fix graph merge loss of rates
parent
e1f442308e
commit
b0f49eb814
|
|
@ -7,396 +7,397 @@ import satisfactory.items.type.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class Database {
|
public class Database {
|
||||||
// dirty!
|
|
||||||
private static final Collection<Item> items = new HashSet<>();
|
private static final Collection<Item> items = new HashSet<>();
|
||||||
public static final Map<Item, Recipe> preferences = new HashMap<>();
|
public static final Map<Item, Recipe> preferences = new HashMap<>();
|
||||||
|
|
||||||
// Items & recipes
|
// Items & recipes
|
||||||
public static final Item IronOre = new Ore("Iron Ore");
|
public static final Item IronOre = new Ore("Iron Ore");
|
||||||
public static final Item IronIngot = new Ingot("Iron Ingot", new Recipe(2, IronOre, 1));
|
public static final Item IronIngot = new Ingot("Iron Ingot", new Recipe(2, IronOre, 1));
|
||||||
public static final Item CopperOre = new Ore("Copper Ore");
|
public static final Item CopperOre = new Ore("Copper Ore");
|
||||||
public static final Item CopperIngot = new Ingot("Copper Ingot", new Recipe(2, CopperOre, 1));
|
public static final Item CopperIngot = new Ingot("Copper Ingot", new Recipe(2, CopperOre, 1));
|
||||||
public static final Item Coal = new Ore("Coal");
|
public static final Item Coal = new Ore("Coal");
|
||||||
public static final Item SteelIngot = new Ingot("Steel Ingot");
|
public static final Item SteelIngot = new Ingot("Steel Ingot");
|
||||||
public static final Item CateriumOre = new Ore("Caterium Ore");
|
public static final Item CateriumOre = new Ore("Caterium Ore");
|
||||||
public static final Item CateriumIngot = new Ingot("Caterium Ingot", new Recipe(4, CateriumOre, 3));
|
public static final Item CateriumIngot = new Ingot("Caterium Ingot", new Recipe(4, CateriumOre, 3));
|
||||||
public static final Item IronPlate = new Part("Iron Plate");
|
public static final Item IronPlate = new Part("Iron Plate");
|
||||||
public static final Item IronRod = new Part("IronRod", new Recipe(4, IronIngot, 1));
|
public static final Item IronRod = new Part("Iron Rod", new Recipe(4, IronIngot, 1));
|
||||||
public static final Item Screw = new Part("Screw");
|
public static final Item Screw = new Part("Screw");
|
||||||
public static final Item ReinforcedIronPlate = new Part("Reinforced Iron Plate");
|
public static final Item ReinforcedIronPlate = new Part("Reinforced Iron Plate");
|
||||||
public static final Item ModularFrame = new Part("Modular Frame");
|
public static final Item ModularFrame = new Part("Modular Frame");
|
||||||
public static final Item SteelBeam = new Part("Steel Beam", new Recipe(4, SteelIngot, 4));
|
public static final Item SteelBeam = new Part("Steel Beam", new Recipe(4, SteelIngot, 4));
|
||||||
public static final Item SteelPipe = new Part("Steel Pipe");
|
public static final Item SteelPipe = new Part("Steel Pipe");
|
||||||
public static final Item Limestone = new Ore("Limestone");
|
public static final Item Limestone = new Ore("Limestone");
|
||||||
public static final Item Concrete = new Part("Concrete", new Recipe(4, Limestone, 3));
|
public static final Item Concrete = new Part("Concrete", new Recipe(4, Limestone, 3));
|
||||||
public static final Item EncasedIndustrialBeam = new Part("Encased Industrial Beam");
|
public static final Item EncasedIndustrialBeam = new Part("Encased Industrial Beam");
|
||||||
public static final Item HeavyModularFrame = new Part("HeavyModularFrame");
|
public static final Item HeavyModularFrame = new Part("Heavy Modular Frame");
|
||||||
public static final Item CopperSheet = new Part("CopperSheet", new Recipe(6, CopperIngot, 2));
|
public static final Item CopperSheet = new Part("Copper Sheet", new Recipe(6, CopperIngot, 2));
|
||||||
public static final Item Wire = new Part("Wire");
|
public static final Item Wire = new Part("Wire");
|
||||||
public static final Item Cable = new Part("Cable", new Recipe(2, Wire, 2));
|
public static final Item Cable = new Part("Cable", new Recipe(2, Wire, 2));
|
||||||
public static final Item Quickwire = new Part("Quickwire");
|
public static final Item Quickwire = new Part("Quickwire");
|
||||||
public static final Item CircuitBoard = new Part("CircuitBoard");
|
public static final Item CircuitBoard = new Part("Circuit Board");
|
||||||
public static final Item AILimiter = new Part("A.I. Limiter");
|
public static final Item AILimiter = new Part("A.I. Limiter");
|
||||||
public static final Item HighSpeedConnector = new Part("High-Speed Connector");
|
public static final Item HighSpeedConnector = new Part("High-Speed Connector");
|
||||||
public static final Item Biomass = new Part("Biomass");
|
public static final Item Biomass = new Part("Biomass");
|
||||||
public static final Item SolidBiofuel = new Part("Solid Biofuel");
|
public static final Item SolidBiofuel = new Part("Solid Biofuel");
|
||||||
public static final Item Mycelia = new Pickup("Mycelia");
|
public static final Item Mycelia = new Pickup("Mycelia");
|
||||||
public static final Item Leaves = new Pickup("Leaves");
|
public static final Item Leaves = new Pickup("Leaves");
|
||||||
public static final Item Wood = new Pickup("Wood");
|
public static final Item Wood = new Pickup("Wood");
|
||||||
public static final Item AlienCarapace = new Pickup("Alien Carapace");
|
public static final Item AlienCarapace = new Pickup("Alien Carapace");
|
||||||
public static final Item AlienOrgans = new Pickup("Alien Organs");
|
public static final Item AlienOrgans = new Pickup("Alien Organs");
|
||||||
public static final Item Fabric = new Part("Fabric");
|
public static final Item Fabric = new Part("Fabric");
|
||||||
public static final Item Rotor = new Part("Rotor");
|
public static final Item Rotor = new Part("Rotor");
|
||||||
public static final Item Stator = new Part("Stator");
|
public static final Item Stator = new Part("Stator");
|
||||||
public static final Item Motor = new Part("Motor");
|
public static final Item Motor = new Part("Motor");
|
||||||
public static final Item GreenPowerSlug = new Pickup("Green Power Slug");
|
public static final Item GreenPowerSlug = new Pickup("Green Power Slug");
|
||||||
public static final Item YellowPowerSlug = new Pickup("Yellow Power Slug");
|
public static final Item YellowPowerSlug = new Pickup("Yellow Power Slug");
|
||||||
public static final Item PurplePowerSlug = new Pickup("Purple Power Slug");
|
public static final Item PurplePowerSlug = new Pickup("Purple Power Slug");
|
||||||
public static final Item PowerShard = new Pickup("PowerShard");
|
public static final Item PowerShard = new Pickup("PowerShard");
|
||||||
public static final Item Sulfur = new Ore("Sulfur");
|
public static final Item Sulfur = new Ore("Sulfur");
|
||||||
public static final Item BlackPowder = new Part("Black powder");
|
public static final Item BlackPowder = new Part("Black powder");
|
||||||
public static final Item SpikedRebar = new Part("SpikedRebar", new Recipe(4, IronRod, 1));
|
public static final Item SpikedRebar = new Part("Spiked Rebar", new Recipe(4, IronRod, 1));
|
||||||
public static final Item FlowerPetals = new Pickup("Flower Petals");
|
public static final Item FlowerPetals = new Pickup("Flower Petals");
|
||||||
public static final Item ColorCatridge = new Part("Color Catridge");
|
public static final Item ColorCatridge = new Part("Color Catridge");
|
||||||
public static final Item Beacon = new Tool("Beacon");
|
public static final Item Beacon = new Tool("Beacon");
|
||||||
public static final Item Rubber = new Part("Rubber");
|
public static final Item Rubber = new Part("Rubber");
|
||||||
public static final Item RifleCatridge = new Part("RifleCatridge");
|
public static final Item RifleCatridge = new Part("Rifle Catridge");
|
||||||
public static final Item GasFilter = new Tool("Gas Filter");
|
public static final Item GasFilter = new Tool("Gas Filter");
|
||||||
public static final Item Plastic = new Part("Plastic");
|
public static final Item Plastic = new Part("Plastic");
|
||||||
public static final Item Computer = new Part("Computer");
|
public static final Item Computer = new Part("Computer");
|
||||||
public static final Item SuperComputer = new Part("SuperComputer");
|
public static final Item SuperComputer = new Part("Super Computer");
|
||||||
public static final Item EmptyCanister = new Part("Empty Canister");
|
public static final Item EmptyCanister = new Part("Empty Canister");
|
||||||
public static final Item ModularEngine = new Part("Modular Engine");
|
public static final Item ModularEngine = new Part("Modular Engine");
|
||||||
public static final Item AdaptiveControlUnit = new Part("Adaptive Control Unit");
|
public static final Item AdaptiveControlUnit = new Part("Adaptive Control Unit");
|
||||||
public static final Item SmartPlating = new Part("Smart Plating");
|
public static final Item SmartPlating = new Part("Smart Plating");
|
||||||
public static final Item AutomatedWiring = new Part("Automated Wiring");
|
public static final Item AutomatedWiring = new Part("Automated Wiring");
|
||||||
public static final Item VersatileFrameWork = new Part("Versatile Framework");
|
public static final Item VersatileFrameWork = new Part("Versatile Framework");
|
||||||
public static final Item Nobelisk = new Part("Nobelisk");
|
public static final Item Nobelisk = new Part("Nobelisk");
|
||||||
public static final Item Water = new RawFluid("Water");
|
public static final Item Water = new RawFluid("Water");
|
||||||
public static final Item CrudeOil = new RawFluid("Crude Oil");
|
public static final Item CrudeOil = new RawFluid("Crude Oil");
|
||||||
public static final Item HeavyOilResidue = new ProcessedFluid("Heavy Oil Residue");
|
public static final Item HeavyOilResidue = new ProcessedFluid("Heavy Oil Residue");
|
||||||
public static final Item Fuel = new ProcessedFluid("Fuel");
|
public static final Item Fuel = new ProcessedFluid("Fuel");
|
||||||
public static final Item LiquidBiofuel = new ProcessedFluid("Liquid Biofuel");
|
public static final Item LiquidBiofuel = new ProcessedFluid("Liquid Biofuel");
|
||||||
public static final Item PetroleumCoke = new Part("Petroleum Coke");
|
public static final Item PetroleumCoke = new Part("Petroleum Coke");
|
||||||
public static final Item PolymerResin = new Part("Polymer Resin");
|
public static final Item PolymerResin = new Part("Polymer Resin");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
{
|
{
|
||||||
Set<Item> ores = new HashSet<>(Arrays.asList(IronOre, Coal, Limestone, CopperOre, CateriumOre, Sulfur));
|
Set<Item> ores = new HashSet<>(Arrays.asList(IronOre, Coal, Limestone, CopperOre, CateriumOre, Sulfur));
|
||||||
for (Item ore : ores) {
|
for (Item ore : ores) {
|
||||||
Recipe mk1 = new Recipe(1, "Miner MK 1", false);
|
Recipe mk1 = new Recipe(1, "Miner MK 1", false);
|
||||||
ore.add(mk1, 1);
|
ore.add(mk1, 1);
|
||||||
Recipe mk2 = new Recipe(1, "Miner MK2", false);
|
Recipe mk2 = new Recipe(1, "Miner MK2", false);
|
||||||
ore.add(mk2, 2);
|
ore.add(mk2, 2);
|
||||||
}
|
ore.setPreference(mk2);
|
||||||
|
}
|
||||||
|
|
||||||
Set<Item> rawFluids = new HashSet<>(Arrays.asList(CrudeOil, Water));
|
Set<Item> rawFluids = new HashSet<>(Arrays.asList(CrudeOil, Water));
|
||||||
// no common well yet
|
// no common well yet
|
||||||
CrudeOil.add(new Recipe(1, "Oil extracting thingy", false), 2);
|
CrudeOil.add(new Recipe(1, "Oil extracting thingy", false), 2);
|
||||||
Water.add(new Recipe(1, "water pump thingy", false), 2);
|
Water.add(new Recipe(1, "water pump thingy", false), 2);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Steel Ingot
|
// Steel Ingot
|
||||||
Recipe recipe = new Recipe(4);
|
Recipe recipe = new Recipe(4);
|
||||||
recipe.addInput(IronOre, 3);
|
recipe.addInput(IronOre, 3);
|
||||||
recipe.addInput(Coal, 3);
|
recipe.addInput(Coal, 3);
|
||||||
SteelIngot.add(recipe, 3);
|
SteelIngot.add(recipe, 3);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Iron Plate
|
// Iron Plate
|
||||||
Recipe recipe = new Recipe(6, IronIngot, 3);
|
Recipe recipe = new Recipe(6, IronIngot, 3);
|
||||||
IronPlate.add(recipe, 2);
|
IronPlate.add(recipe, 2);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Screw
|
// Screw
|
||||||
Screw.add(new Recipe(6, IronRod, 1), 4);
|
Screw.add(new Recipe(6, IronRod, 1), 4);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Reinforced Iron Plate
|
// Reinforced Iron Plate
|
||||||
Recipe recipe = new Recipe(12);
|
Recipe recipe = new Recipe(12);
|
||||||
recipe.addInput(IronPlate, 6);
|
recipe.addInput(IronPlate, 6);
|
||||||
recipe.addInput(Screw, 12);
|
recipe.addInput(Screw, 12);
|
||||||
ReinforcedIronPlate.add(recipe);
|
ReinforcedIronPlate.add(recipe);
|
||||||
Recipe bolted = new Recipe(12, "Bolted Iron Plate", false);
|
Recipe bolted = new Recipe(12, "Bolted Iron Plate", false);
|
||||||
bolted.addInput(IronPlate, 18);
|
bolted.addInput(IronPlate, 18);
|
||||||
bolted.addInput(Screw, 50);
|
bolted.addInput(Screw, 50);
|
||||||
ReinforcedIronPlate.add(bolted, 3);
|
ReinforcedIronPlate.add(bolted, 3);
|
||||||
|
|
||||||
ReinforcedIronPlate.setPreference(recipe);
|
ReinforcedIronPlate.setPreference(recipe);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Modular Frame
|
// Modular Frame
|
||||||
Recipe recipe = new Recipe(60);
|
Recipe recipe = new Recipe(60);
|
||||||
recipe.addInput(ReinforcedIronPlate, 3);
|
recipe.addInput(ReinforcedIronPlate, 3);
|
||||||
recipe.addInput(IronRod, 12);
|
recipe.addInput(IronRod, 12);
|
||||||
ModularFrame.add(recipe, 2);
|
ModularFrame.add(recipe, 2);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Steel Pipe
|
// Steel Pipe
|
||||||
Recipe recipe = new Recipe(6);
|
Recipe recipe = new Recipe(6);
|
||||||
recipe.addInput(SteelIngot, 3);
|
recipe.addInput(SteelIngot, 3);
|
||||||
SteelPipe.add(recipe, 2);
|
SteelPipe.add(recipe, 2);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Encased Industrial Beam
|
// Encased Industrial Beam
|
||||||
Recipe recipe = new Recipe(10);
|
Recipe recipe = new Recipe(10);
|
||||||
recipe.addInput(SteelBeam, 4);
|
recipe.addInput(SteelBeam, 4);
|
||||||
recipe.addInput(Concrete, 5);
|
recipe.addInput(Concrete, 5);
|
||||||
EncasedIndustrialBeam.add(recipe);
|
EncasedIndustrialBeam.add(recipe);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Heavy Modular Frame
|
// Heavy Modular Frame
|
||||||
Recipe recipe = new Recipe(30);
|
Recipe recipe = new Recipe(30);
|
||||||
recipe.addInput(ModularFrame, 5);
|
recipe.addInput(ModularFrame, 5);
|
||||||
recipe.addInput(SteelPipe, 15);
|
recipe.addInput(SteelPipe, 15);
|
||||||
recipe.addInput(EncasedIndustrialBeam, 5);
|
recipe.addInput(EncasedIndustrialBeam, 5);
|
||||||
recipe.addInput(Screw, 100);
|
recipe.addInput(Screw, 100);
|
||||||
HeavyModularFrame.add(recipe);
|
HeavyModularFrame.add(recipe);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Wire
|
// Wire
|
||||||
Wire.add(new Recipe(4, CopperIngot, 1), 2);
|
Wire.add(new Recipe(4, CopperIngot, 1), 2);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Quickwire
|
// Quickwire
|
||||||
Quickwire.add(new Recipe(5, CateriumIngot, 1), 5);
|
Quickwire.add(new Recipe(5, CateriumIngot, 1), 5);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Circuit Board
|
// Circuit Board
|
||||||
Recipe recipe = new Recipe(8);
|
Recipe recipe = new Recipe(8);
|
||||||
recipe.addInput(CopperSheet, 2);
|
recipe.addInput(CopperSheet, 2);
|
||||||
recipe.addInput(Plastic, 4);
|
recipe.addInput(Plastic, 4);
|
||||||
CircuitBoard.add(recipe);
|
CircuitBoard.add(recipe);
|
||||||
}
|
// TODO: alternative
|
||||||
{
|
}
|
||||||
// A.I. Limiter
|
{
|
||||||
Recipe recipe = new Recipe(12);
|
// A.I. Limiter
|
||||||
recipe.addInput(CopperSheet, 5);
|
Recipe recipe = new Recipe(12);
|
||||||
recipe.addInput(Quickwire, 20);
|
recipe.addInput(CopperSheet, 5);
|
||||||
AILimiter.add(recipe);
|
recipe.addInput(Quickwire, 20);
|
||||||
}
|
AILimiter.add(recipe);
|
||||||
{
|
}
|
||||||
// High Speed Connector
|
{
|
||||||
Recipe recipe = new Recipe(16);
|
// High Speed Connector
|
||||||
recipe.addInput(Quickwire, 56);
|
Recipe recipe = new Recipe(16);
|
||||||
recipe.addInput(Cable, 10);
|
recipe.addInput(Quickwire, 56);
|
||||||
recipe.addInput(CircuitBoard, 1);
|
recipe.addInput(Cable, 10);
|
||||||
HighSpeedConnector.add(recipe);
|
recipe.addInput(CircuitBoard, 1);
|
||||||
}
|
HighSpeedConnector.add(recipe);
|
||||||
{
|
}
|
||||||
// Biomass
|
{
|
||||||
Biomass.add(new Recipe(5, Leaves, 10), 5);
|
// Biomass
|
||||||
Biomass.add(new Recipe(4, Wood, 4), 20);
|
Biomass.add(new Recipe(5, Leaves, 10), 5);
|
||||||
Biomass.add(new Recipe(4, Mycelia, 10), 10);
|
Biomass.add(new Recipe(4, Wood, 4), 20);
|
||||||
Biomass.add(new Recipe(4, AlienCarapace, 1), 100);
|
Biomass.add(new Recipe(4, Mycelia, 10), 10);
|
||||||
Biomass.add(new Recipe(8, AlienOrgans, 1), 200);
|
Biomass.add(new Recipe(4, AlienCarapace, 1), 100);
|
||||||
}
|
Biomass.add(new Recipe(8, AlienOrgans, 1), 200);
|
||||||
{
|
}
|
||||||
// Fabric
|
{
|
||||||
Recipe recipe = new Recipe(4);
|
// Fabric
|
||||||
recipe.addInput(Mycelia);
|
Recipe recipe = new Recipe(4);
|
||||||
recipe.addInput(Biomass, 5);
|
recipe.addInput(Mycelia);
|
||||||
Fabric.add(recipe);
|
recipe.addInput(Biomass, 5);
|
||||||
}
|
Fabric.add(recipe);
|
||||||
{
|
}
|
||||||
// Solid Biofuel
|
{
|
||||||
SolidBiofuel.add(new Recipe(4, Biomass, 8), 4);
|
// Solid Biofuel
|
||||||
}
|
SolidBiofuel.add(new Recipe(4, Biomass, 8), 4);
|
||||||
{
|
}
|
||||||
// Rotator
|
{
|
||||||
Recipe recipe = new Recipe(15);
|
// Rotator
|
||||||
recipe.addInput(IronRod, 5);
|
Recipe recipe = new Recipe(15);
|
||||||
recipe.addInput(Screw, 25);
|
recipe.addInput(IronRod, 5);
|
||||||
Rotor.add(recipe);
|
recipe.addInput(Screw, 25);
|
||||||
}
|
Rotor.add(recipe);
|
||||||
{
|
}
|
||||||
// Stator
|
{
|
||||||
Recipe recipe = new Recipe(12);
|
// Stator
|
||||||
recipe.addInput(SteelPipe, 3);
|
Recipe recipe = new Recipe(12);
|
||||||
recipe.addInput(Wire, 8);
|
recipe.addInput(SteelPipe, 3);
|
||||||
Stator.add(recipe);
|
recipe.addInput(Wire, 8);
|
||||||
}
|
Stator.add(recipe);
|
||||||
{
|
}
|
||||||
// Motor
|
{
|
||||||
Recipe recipe = new Recipe(12);
|
// Motor
|
||||||
recipe.addInput(Rotor, 2);
|
Recipe recipe = new Recipe(12);
|
||||||
recipe.addInput(Stator, 2);
|
recipe.addInput(Rotor, 2);
|
||||||
Motor.add(recipe);
|
recipe.addInput(Stator, 2);
|
||||||
}
|
Motor.add(recipe);
|
||||||
{
|
}
|
||||||
// Power Shard
|
{
|
||||||
PowerShard.add(new Recipe(8, GreenPowerSlug, 1));
|
// Power Shard
|
||||||
PowerShard.add(new Recipe(12, YellowPowerSlug, 1), 2);
|
PowerShard.add(new Recipe(8, GreenPowerSlug, 1));
|
||||||
PowerShard.add(new Recipe(24, PurplePowerSlug, 1), 5);
|
PowerShard.add(new Recipe(12, YellowPowerSlug, 1), 2);
|
||||||
}
|
PowerShard.add(new Recipe(24, PurplePowerSlug, 1), 5);
|
||||||
{
|
}
|
||||||
// Black Powder
|
{
|
||||||
Recipe recipe = new Recipe(8);
|
// Black Powder
|
||||||
recipe.addInput(Coal);
|
Recipe recipe = new Recipe(8);
|
||||||
recipe.addInput(Sulfur, 2);
|
recipe.addInput(Coal);
|
||||||
BlackPowder.add(recipe);
|
recipe.addInput(Sulfur, 2);
|
||||||
}
|
BlackPowder.add(recipe);
|
||||||
{
|
}
|
||||||
// Color Catridge
|
{
|
||||||
ColorCatridge.add(new Recipe(8, FlowerPetals, 5), 10);
|
// Color Catridge
|
||||||
}
|
ColorCatridge.add(new Recipe(8, FlowerPetals, 5), 10);
|
||||||
{
|
}
|
||||||
// Rifle Catridge
|
{
|
||||||
Recipe recipe = new Recipe(20);
|
// Rifle Catridge
|
||||||
recipe.addInput(Beacon, 1);
|
Recipe recipe = new Recipe(20);
|
||||||
recipe.addInput(SteelPipe, 10);
|
recipe.addInput(Beacon, 1);
|
||||||
recipe.addInput(BlackPowder, 10);
|
recipe.addInput(SteelPipe, 10);
|
||||||
recipe.addInput(Rubber, 10);
|
recipe.addInput(BlackPowder, 10);
|
||||||
RifleCatridge.add(recipe, 5);
|
recipe.addInput(Rubber, 10);
|
||||||
}
|
RifleCatridge.add(recipe, 5);
|
||||||
{
|
}
|
||||||
// Gas Filter
|
{
|
||||||
Recipe recipe = new Recipe(8);
|
// Gas Filter
|
||||||
recipe.addInput(Coal, 5);
|
Recipe recipe = new Recipe(8);
|
||||||
recipe.addInput(Rubber, 2);
|
recipe.addInput(Coal, 5);
|
||||||
recipe.addInput(Fabric, 2);
|
recipe.addInput(Rubber, 2);
|
||||||
GasFilter.add(recipe);
|
recipe.addInput(Fabric, 2);
|
||||||
}
|
GasFilter.add(recipe);
|
||||||
{
|
}
|
||||||
// Computer
|
{
|
||||||
Recipe recipe = new Recipe(24);
|
// Computer
|
||||||
recipe.addInput(CircuitBoard, 10);
|
Recipe recipe = new Recipe(24);
|
||||||
recipe.addInput(Cable, 9);
|
recipe.addInput(CircuitBoard, 10);
|
||||||
recipe.addInput(Plastic, 18);
|
recipe.addInput(Cable, 9);
|
||||||
recipe.addInput(Screw, 52);
|
recipe.addInput(Plastic, 18);
|
||||||
Computer.add(recipe);
|
recipe.addInput(Screw, 52);
|
||||||
Recipe alternative = new Recipe(16, "Caterium Computer", false);
|
Computer.add(recipe);
|
||||||
alternative.addInput(CircuitBoard, 7);
|
Recipe alternative = new Recipe(16, "Caterium Computer", false);
|
||||||
alternative.addInput(Quickwire, 28);
|
alternative.addInput(CircuitBoard, 7);
|
||||||
alternative.addInput(Rubber, 12);
|
alternative.addInput(Quickwire, 28);
|
||||||
Computer.add(alternative);
|
alternative.addInput(Rubber, 12);
|
||||||
|
Computer.add(alternative);
|
||||||
|
|
||||||
Computer.setPreference(recipe);
|
Computer.setPreference(recipe);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Super Computer
|
// Super Computer
|
||||||
Recipe recipe = new Recipe(32);
|
Recipe recipe = new Recipe(32);
|
||||||
recipe.addInput(Computer, 2);
|
recipe.addInput(Computer, 2);
|
||||||
recipe.addInput(AILimiter, 2);
|
recipe.addInput(AILimiter, 2);
|
||||||
recipe.addInput(HighSpeedConnector, 3);
|
recipe.addInput(HighSpeedConnector, 3);
|
||||||
recipe.addInput(Plastic, 28);
|
recipe.addInput(Plastic, 28);
|
||||||
SuperComputer.add(recipe);
|
SuperComputer.add(recipe);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Empty Canister
|
// Empty Canister
|
||||||
EmptyCanister.add(new Recipe(4, Plastic, 2), 4);
|
EmptyCanister.add(new Recipe(4, Plastic, 2), 4);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Beacon
|
// Beacon
|
||||||
Recipe recipe = new Recipe(8);
|
Recipe recipe = new Recipe(8);
|
||||||
recipe.addInput(IronPlate, 3);
|
recipe.addInput(IronPlate, 3);
|
||||||
recipe.addInput(IronRod);
|
recipe.addInput(IronRod);
|
||||||
recipe.addInput(Wire, 15);
|
recipe.addInput(Wire, 15);
|
||||||
recipe.addInput(Cable, 2);
|
recipe.addInput(Cable, 2);
|
||||||
Beacon.add(recipe);
|
Beacon.add(recipe);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Modular Engine
|
// Modular Engine
|
||||||
Recipe recipe = new Recipe(60, false);
|
Recipe recipe = new Recipe(60, false);
|
||||||
recipe.addInput(Motor, 2);
|
recipe.addInput(Motor, 2);
|
||||||
recipe.addInput(Rubber, 15);
|
recipe.addInput(Rubber, 15);
|
||||||
recipe.addInput(SmartPlating, 2);
|
recipe.addInput(SmartPlating, 2);
|
||||||
ModularEngine.add(recipe);
|
ModularEngine.add(recipe);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Adaptive Control Unit
|
// Adaptive Control Unit
|
||||||
Recipe recipe = new Recipe(120, false);
|
Recipe recipe = new Recipe(120, false);
|
||||||
recipe.addInput(AutomatedWiring, 15);
|
recipe.addInput(AutomatedWiring, 15);
|
||||||
recipe.addInput(CircuitBoard, 10);
|
recipe.addInput(CircuitBoard, 10);
|
||||||
recipe.addInput(HeavyModularFrame, 2);
|
recipe.addInput(HeavyModularFrame, 2);
|
||||||
recipe.addInput(Computer, 2);
|
recipe.addInput(Computer, 2);
|
||||||
AdaptiveControlUnit.add(recipe, 2);
|
AdaptiveControlUnit.add(recipe, 2);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Nobelisk
|
// Nobelisk
|
||||||
Recipe recipe = new Recipe(20, false);
|
Recipe recipe = new Recipe(20, false);
|
||||||
recipe.addInput(BlackPowder, 5);
|
recipe.addInput(BlackPowder, 5);
|
||||||
recipe.addInput(SteelPipe, 10);
|
recipe.addInput(SteelPipe, 10);
|
||||||
Nobelisk.add(recipe);
|
Nobelisk.add(recipe);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Smart Plating
|
// Smart Plating
|
||||||
Recipe recipe = new Recipe(30, false);
|
Recipe recipe = new Recipe(30, false);
|
||||||
recipe.addInput(ReinforcedIronPlate);
|
recipe.addInput(ReinforcedIronPlate);
|
||||||
recipe.addInput(Rotor);
|
recipe.addInput(Rotor);
|
||||||
SmartPlating.add(recipe);
|
SmartPlating.add(recipe);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Automated Wiring
|
// Automated Wiring
|
||||||
Recipe recipe = new Recipe(24, false);
|
Recipe recipe = new Recipe(24, false);
|
||||||
recipe.addInput(Stator);
|
recipe.addInput(Stator);
|
||||||
recipe.addInput(Cable, 20);
|
recipe.addInput(Cable, 20);
|
||||||
AutomatedWiring.add(recipe);
|
AutomatedWiring.add(recipe);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Versatile Framework
|
// Versatile Framework
|
||||||
Recipe recipe = new Recipe(24, false);
|
Recipe recipe = new Recipe(24, false);
|
||||||
recipe.addInput(ModularFrame);
|
recipe.addInput(ModularFrame);
|
||||||
recipe.addInput(SteelBeam, 12);
|
recipe.addInput(SteelBeam, 12);
|
||||||
VersatileFrameWork.add(recipe, 2);
|
VersatileFrameWork.add(recipe, 2);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Fuel
|
// Fuel
|
||||||
Recipe residualFuel = new Recipe(6, "Residual Fuel", false);
|
Recipe residualFuel = new Recipe(6, "Residual Fuel", false);
|
||||||
residualFuel.addInput(HeavyOilResidue, 6);
|
residualFuel.addInput(HeavyOilResidue, 6);
|
||||||
Fuel.add(residualFuel, 4);
|
Fuel.add(residualFuel, 4);
|
||||||
Recipe recipe = new Recipe(6, false);
|
Recipe recipe = new Recipe(6, false);
|
||||||
recipe.addInput(CrudeOil, 6);
|
recipe.addInput(CrudeOil, 6);
|
||||||
recipe.addOutput(PolymerResin, 3);
|
recipe.addOutput(PolymerResin, 3);
|
||||||
Fuel.add(recipe, 4);
|
Fuel.add(recipe, 4);
|
||||||
|
|
||||||
Fuel.setPreference(recipe);
|
Fuel.setPreference(recipe);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Liquid Biofuel
|
// Liquid Biofuel
|
||||||
Recipe recipe = new Recipe(4, false);
|
Recipe recipe = new Recipe(4, false);
|
||||||
recipe.addInput(SolidBiofuel, 6);
|
recipe.addInput(SolidBiofuel, 6);
|
||||||
recipe.addInput(Water, 3);
|
recipe.addInput(Water, 3);
|
||||||
LiquidBiofuel.add(recipe, 4);
|
LiquidBiofuel.add(recipe, 4);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Plastic
|
// Plastic
|
||||||
Recipe recipe = new Recipe(6, false);
|
Recipe recipe = new Recipe(6, false);
|
||||||
recipe.addInput(CrudeOil, 3);
|
recipe.addInput(CrudeOil, 3);
|
||||||
recipe.addOutput(HeavyOilResidue, 1);
|
recipe.addOutput(HeavyOilResidue, 1);
|
||||||
Plastic.add(recipe, 2);
|
Plastic.add(recipe, 2);
|
||||||
Recipe residualPlastic = new Recipe(6, "Residual Plastic", false);
|
Recipe residualPlastic = new Recipe(6, "Residual Plastic", false);
|
||||||
residualPlastic.addInput(PolymerResin, 6);
|
residualPlastic.addInput(PolymerResin, 6);
|
||||||
residualPlastic.addInput(Water, 2);
|
residualPlastic.addInput(Water, 2);
|
||||||
Plastic.add(residualPlastic, 2);
|
Plastic.add(residualPlastic, 2);
|
||||||
|
|
||||||
Plastic.setPreference(recipe);
|
Plastic.setPreference(recipe);
|
||||||
|
|
||||||
HeavyOilResidue.add(recipe);
|
HeavyOilResidue.add(recipe);
|
||||||
HeavyOilResidue.setPreference(recipe);
|
HeavyOilResidue.setPreference(recipe);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Rubber
|
// Rubber
|
||||||
Recipe recipe = new Recipe(6, false);
|
Recipe recipe = new Recipe(6, false);
|
||||||
recipe.addInput(CrudeOil, 3);
|
recipe.addInput(CrudeOil, 3);
|
||||||
recipe.addOutput(HeavyOilResidue, 2);
|
recipe.addOutput(HeavyOilResidue, 2);
|
||||||
Rubber.add(recipe, 2);
|
Rubber.add(recipe, 2);
|
||||||
Recipe residualRubber = new Recipe(6, "Residual Rubber", false);
|
Recipe residualRubber = new Recipe(6, "Residual Rubber", false);
|
||||||
residualRubber.addInput(PolymerResin, 6);
|
residualRubber.addInput(PolymerResin, 6);
|
||||||
residualRubber.addInput(Water, 4);
|
residualRubber.addInput(Water, 4);
|
||||||
Rubber.add(residualRubber, 2);
|
Rubber.add(residualRubber, 2);
|
||||||
|
|
||||||
Rubber.setPreference(recipe);
|
Rubber.setPreference(recipe);
|
||||||
|
|
||||||
HeavyOilResidue.add(recipe);
|
HeavyOilResidue.add(recipe);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Petroleum Coke
|
// Petroleum Coke
|
||||||
Recipe recipe = new Recipe(6, false);
|
Recipe recipe = new Recipe(6, false);
|
||||||
recipe.addInput(HeavyOilResidue, 4);
|
recipe.addInput(HeavyOilResidue, 4);
|
||||||
PetroleumCoke.add(recipe, 12);
|
PetroleumCoke.add(recipe, 12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void add(Item i) {
|
public static void add(Item i) {
|
||||||
items.add(i);
|
items.add(i);
|
||||||
|
|
|
||||||
|
|
@ -67,28 +67,30 @@ public class Test {
|
||||||
System.out.println("\nSUM_reif");
|
System.out.println("\nSUM_reif");
|
||||||
Database.ReinforcedIronPlate.getRecipe().sum(Database.ReinforcedIronPlate, 100);
|
Database.ReinforcedIronPlate.getRecipe().sum(Database.ReinforcedIronPlate, 100);
|
||||||
System.out.println("\nSUM_screw");
|
System.out.println("\nSUM_screw");
|
||||||
Graph<Item, ProductionEdge> screws100 = Database.Screw.getRecipe().sum(Database.Screw, 100);
|
Graph<Item, ProductionEdge> screws100 = Database.Screw.getRecipe().sum(Database.Screw, 100).getProduction();
|
||||||
Graph<Item, ProductionEdge> computers100 = Database.Computer.getRecipe().sum(Database.Computer, 100);
|
Graph<Item, ProductionEdge> computers100 = Database.Computer.getRecipe().sum(Database.Computer, 100).getProduction();
|
||||||
|
|
||||||
plot2(screws100, "screw_sum");
|
plot2(screws100, "screw_sum");
|
||||||
System.out.println("\nSUM_ACU");
|
System.out.println("\nSUM_ACU");
|
||||||
plot2(Database.AdaptiveControlUnit.getRecipe().sum(Database.AdaptiveControlUnit, 1), "acu4");
|
plot2(Database.AdaptiveControlUnit.getRecipe().sum(Database.AdaptiveControlUnit, 1).getProduction(), "acu4");
|
||||||
|
|
||||||
|
|
||||||
plot2(Utils.merge(screws100, computers100), "merged");
|
//plot2(SumResult.merge(screws100, computers100), "merged");
|
||||||
|
|
||||||
System.out.println("\n\nPHASE 3");
|
System.out.println("\n\nPHASE 3");
|
||||||
Graph<Item, ProductionEdge> phase3;
|
Graph<Item, ProductionEdge> phase3;
|
||||||
//phase3 = Utils.sum(Database.VersatileFrameWork, 2500);
|
//phase3 = Utils.sum(Database.VersatileFrameWork, 2500);
|
||||||
//phase3 = Utils.merge(phase3, Utils.sum(Database.ModularEngine,500));
|
//phase3 = Utils.merge(phase3, Utils.sum(Database.ModularEngine,500));
|
||||||
phase3 = Utils.sum(Database.ModularEngine,5);
|
//phase3 = SumResult.sum(Database.ModularEngine,5);
|
||||||
phase3 = Utils.merge(phase3, Utils.sum(Database.AdaptiveControlUnit, 1));
|
//phase3 = SumResult.merge(phase3, SumResult.sum(Database.AdaptiveControlUnit, 1));
|
||||||
|
|
||||||
|
phase3 = SumResult.sum(new Production(Database.ModularEngine,5), new Production(Database.AdaptiveControlUnit,1)).getProduction();
|
||||||
|
|
||||||
plot2(phase3, "phase3");
|
plot2(phase3, "phase3");
|
||||||
System.out.println("\nrubber");
|
System.out.println("\nrubber");
|
||||||
plot2(Utils.sum(Database.Rubber, 75),"rubber");
|
plot2(SumResult.sum(Database.Rubber, 75),"rubber");
|
||||||
System.out.println("\ntest");
|
System.out.println("\ntest");
|
||||||
Utils.sum(Database.Plastic, 4);
|
SumResult.sum(Database.Plastic, 4);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import org.jgrapht.traverse.DepthFirstIterator;
|
||||||
import org.jgrapht.traverse.GraphIterator;
|
import org.jgrapht.traverse.GraphIterator;
|
||||||
import satisfactory.items.Item;
|
import satisfactory.items.Item;
|
||||||
import satisfactory.items.ProductionEdge;
|
import satisfactory.items.ProductionEdge;
|
||||||
|
import satisfactory.items.SumResult;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
@ -23,112 +24,83 @@ import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class Utils {
|
public class Utils {
|
||||||
public static Map<Item, Integer> getRawOnly(Map<Item, Integer> totals) {
|
public static Map<Item, Integer> getRawOnly(Map<Item, Integer> totals) {
|
||||||
Map<Item, Integer> raws = new HashMap<>();
|
Map<Item, Integer> raws = new HashMap<>();
|
||||||
for (Item item : totals.keySet().stream().filter(Item::isRaw).collect(Collectors.toList())) {
|
for (Item item : totals.keySet().stream().filter(Item::isRaw).collect(Collectors.toList())) {
|
||||||
raws.put(item, totals.get(item));
|
raws.put(item, totals.get(item));
|
||||||
}
|
}
|
||||||
return raws;
|
return raws;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <E extends Number> Map<String, E> shorten(Map<Item, E> totals) {
|
public static <E extends Number> Map<String, E> shorten(Map<Item, E> totals) {
|
||||||
Map<String, E> shortend = new HashMap<>();
|
Map<String, E> shortend = new HashMap<>();
|
||||||
totals.forEach((item, e) -> shortend.put(item.getName(), e));
|
totals.forEach((item, e) -> shortend.put(item.getName(), e));
|
||||||
return shortend;
|
return shortend;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String dotID(Item item) {
|
public static String dotID(Item item) {
|
||||||
String name = item.getName() + "_" + item.sum + "__" + (String.valueOf(item.getProductionRate()).replace(".", "_"));
|
String name = item.getName() + "_" + item.sum + "__" + (String.valueOf(item.getProductionRate()).replace(".", "_"));
|
||||||
name = name.replace(" ", "").replace(".", "");
|
name = name.replace(" ", "").replace(".", "");
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void fixSums(Item target, Graph<Item, DefaultWeightedEdge> graph) {
|
public static void fixSums(Item target, Graph<Item, DefaultWeightedEdge> graph) {
|
||||||
System.err.println(target);
|
System.err.println(target);
|
||||||
EdgeReversedGraph<Item, DefaultWeightedEdge> inverse = new EdgeReversedGraph<>(graph);
|
EdgeReversedGraph<Item, DefaultWeightedEdge> inverse = new EdgeReversedGraph<>(graph);
|
||||||
|
|
||||||
GraphIterator<Item, DefaultWeightedEdge> iterator = new DepthFirstIterator<>(inverse, target);
|
GraphIterator<Item, DefaultWeightedEdge> iterator = new DepthFirstIterator<>(inverse, target);
|
||||||
iterator.addTraversalListener(new TraversalListener<Item, DefaultWeightedEdge>() {
|
iterator.addTraversalListener(new TraversalListener<Item, DefaultWeightedEdge>() {
|
||||||
@Override
|
@Override
|
||||||
public void connectedComponentFinished(ConnectedComponentTraversalEvent e) {
|
public void connectedComponentFinished(ConnectedComponentTraversalEvent e) {
|
||||||
System.out.println("\tconnectedComponentFinished: " + e);
|
System.out.println("\tconnectedComponentFinished: " + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void connectedComponentStarted(ConnectedComponentTraversalEvent e) {
|
public void connectedComponentStarted(ConnectedComponentTraversalEvent e) {
|
||||||
System.out.println("\tconnectedComponentStarted: " + e);
|
System.out.println("\tconnectedComponentStarted: " + e);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void edgeTraversed(EdgeTraversalEvent<DefaultWeightedEdge> e) {
|
public void edgeTraversed(EdgeTraversalEvent<DefaultWeightedEdge> e) {
|
||||||
System.out.println("\tedgeTraversed: " + e + "---> " + e.getEdge());
|
System.out.println("\tedgeTraversed: " + e + "---> " + e.getEdge());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void vertexTraversed(VertexTraversalEvent<Item> e) {
|
public void vertexTraversed(VertexTraversalEvent<Item> e) {
|
||||||
System.out.println("\tvertexTraversed: " + e + "---> " + e.getVertex().getName());
|
System.out.println("\tvertexTraversed: " + e + "---> " + e.getVertex().getName());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void vertexFinished(VertexTraversalEvent<Item> e) {
|
public void vertexFinished(VertexTraversalEvent<Item> e) {
|
||||||
System.out.println("\tvertexFinished: " + e);
|
System.out.println("\tvertexFinished: " + e);
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
Item i = iterator.next();
|
Item i = iterator.next();
|
||||||
System.out.println(i.getName());
|
System.out.println(i.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Graph<Item, ProductionEdge> merge(Graph<Item, ProductionEdge> graph0, Graph<Item, ProductionEdge> graph1) {
|
public static void plot2(Graph<Item, ProductionEdge> sum, String filename) {
|
||||||
Graph<Item, ProductionEdge> result = new DefaultDirectedWeightedGraph<>(ProductionEdge.class);
|
DOTExporter<Item, ProductionEdge> de = new DOTExporter<>(Item::ID);
|
||||||
|
de.setEdgeAttributeProvider(productionEdge -> {
|
||||||
|
Map<String, Attribute> m = new HashMap<>();
|
||||||
|
m.put("label", DefaultAttribute.createAttribute(productionEdge.label()));
|
||||||
|
return m;
|
||||||
|
});
|
||||||
|
de.setVertexAttributeProvider(item -> {
|
||||||
|
Map<String, Attribute> m = new HashMap<>();
|
||||||
|
if (item.isRaw()) {
|
||||||
|
m.put("peripheries", DefaultAttribute.createAttribute(2));
|
||||||
|
}
|
||||||
|
m.put("label", DefaultAttribute.createAttribute(item.getName()));
|
||||||
|
return m;
|
||||||
|
});
|
||||||
|
de.exportGraph(sum, new File(filename + ".dot"));
|
||||||
|
}
|
||||||
|
|
||||||
graph0.vertexSet().forEach(result::addVertex);
|
|
||||||
graph0.edgeSet().forEach(productionEdge -> result.addEdge(graph0.getEdgeSource(productionEdge), graph0.getEdgeTarget(productionEdge), productionEdge));
|
|
||||||
|
|
||||||
graph1.vertexSet().forEach(result::addVertex);
|
|
||||||
graph1.edgeSet().forEach(productionEdge -> {
|
|
||||||
List<ProductionEdge> collect = result.edgeSet().stream().filter(productionEdge1 -> productionEdge1.hasTarget(productionEdge.getTarget())).collect(Collectors.toList());
|
|
||||||
collect.forEach(edge -> {
|
|
||||||
Item src = result.getEdgeSource(edge);
|
|
||||||
Item target = result.getEdgeTarget(edge);
|
|
||||||
Item target2 = graph1.getEdgeTarget(productionEdge);
|
|
||||||
if (target != target2) {
|
|
||||||
result.addEdge(src, target2, productionEdge);
|
|
||||||
} else {
|
|
||||||
result.removeEdge(edge);
|
|
||||||
result.addEdge(src, target, edge);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (collect.isEmpty()) {
|
|
||||||
result.addEdge(graph1.getEdgeSource(productionEdge), graph1.getEdgeTarget(productionEdge), productionEdge);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Graph<Item, ProductionEdge> sum(Item item, int amount) {
|
|
||||||
return item.getRecipe().sum(item,amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void plot2(Graph<Item, ProductionEdge> sum, String filename) {
|
|
||||||
DOTExporter<Item,ProductionEdge> de = new DOTExporter<>(Item::ID);
|
|
||||||
de.setEdgeAttributeProvider(productionEdge -> {
|
|
||||||
Map<String, Attribute> m = new HashMap<>();
|
|
||||||
m.put("label", DefaultAttribute.createAttribute(productionEdge.label()));
|
|
||||||
return m;
|
|
||||||
});
|
|
||||||
de.setVertexAttributeProvider(item -> {
|
|
||||||
Map<String,Attribute> m = new HashMap<>();
|
|
||||||
if (item.isRaw()) {
|
|
||||||
m.put("peripheries", DefaultAttribute.createAttribute(2));
|
|
||||||
}
|
|
||||||
return m;
|
|
||||||
});
|
|
||||||
de.exportGraph(sum, new File(filename+".dot"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package satisfactory.items;
|
||||||
|
|
||||||
|
public class Production {
|
||||||
|
private final Item item;
|
||||||
|
private final int amount;
|
||||||
|
|
||||||
|
public Production(Item item, int amount) {
|
||||||
|
this.item = item;
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item getItem() {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,62 +3,77 @@ package satisfactory.items;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class ProductionEdge {
|
public class ProductionEdge {
|
||||||
private Item source;
|
private final Item source;
|
||||||
private double totalRequired;
|
private final Item target;
|
||||||
private double instances;
|
private double totalRequired;
|
||||||
|
private double instances;
|
||||||
|
|
||||||
public ProductionEdge(Item source,double totalRequired, double productionRate) {
|
public ProductionEdge(Item source, Item target, double totalRequired, double productionRate) {
|
||||||
this.source=source;
|
this.source = source;
|
||||||
this.totalRequired = totalRequired;
|
this.target = target;
|
||||||
this.instances = productionRate;
|
this.totalRequired = totalRequired;
|
||||||
}
|
this.instances = productionRate;
|
||||||
public String label(){
|
}
|
||||||
//return "(" + totalRequired + "||" + instances + ")";
|
|
||||||
return "(%.2f||%.2f)".formatted(totalRequired,instances);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getTotalRequired() {
|
public String label() {
|
||||||
return totalRequired;
|
//return "(" + totalRequired + "||" + instances + ")";
|
||||||
}
|
return "(%.2f||%.2f)".formatted(totalRequired, instances);
|
||||||
|
}
|
||||||
|
|
||||||
public void setTotalRequired(double totalRequired) {
|
public void merge(ProductionEdge other) {
|
||||||
this.totalRequired = totalRequired;
|
if (source.equals(other.getSource())) {
|
||||||
}
|
totalRequired += other.getTotalRequired();
|
||||||
|
instances += other.getInstances();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public double getInstances() {
|
public double getTotalRequired() {
|
||||||
return instances;
|
return totalRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInstances(double instances) {
|
public void setTotalRequired(double totalRequired) {
|
||||||
this.instances = instances;
|
this.totalRequired = totalRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasTarget(Item t){
|
public double getInstances() {
|
||||||
return source.equals(t);
|
return instances;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setInstances(double instances) {
|
||||||
public boolean equals(Object o) {
|
this.instances = instances;
|
||||||
if (this == o) return true;
|
}
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
ProductionEdge that = (ProductionEdge) o;
|
|
||||||
return Double.compare(that.totalRequired, totalRequired) == 0 && instances == that.instances && Objects.equals(source, that.source);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public boolean hasSource(Item t) {
|
||||||
public int hashCode() {
|
return source.equals(t);
|
||||||
return Objects.hash(source, totalRequired, instances);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public boolean equals(Object o) {
|
||||||
return "ProductionEdge{" +
|
if (this == o) return true;
|
||||||
"totalRequired=" + totalRequired +
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
", instances=" + instances +
|
ProductionEdge that = (ProductionEdge) o;
|
||||||
'}';
|
return Objects.equals(source, that.source) && Objects.equals(target, that.target);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Item getTarget() {
|
@Override
|
||||||
return source;
|
public int hashCode() {
|
||||||
}
|
return Objects.hash(source, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ProductionEdge{" +
|
||||||
|
"source=" + source.getName() +
|
||||||
|
", totalRequired=" + totalRequired +
|
||||||
|
", instances=" + instances +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item getSource() {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item getTarget() {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,239 +1,240 @@
|
||||||
package satisfactory.items;
|
package satisfactory.items;
|
||||||
|
|
||||||
import satisfactory.items.requirements.RateAccumulator;
|
|
||||||
import satisfactory.items.requirements.TotalAccumulator;
|
|
||||||
import org.jgrapht.Graph;
|
import org.jgrapht.Graph;
|
||||||
import org.jgrapht.Graphs;
|
import org.jgrapht.Graphs;
|
||||||
import org.jgrapht.graph.DefaultDirectedWeightedGraph;
|
import org.jgrapht.graph.DefaultDirectedWeightedGraph;
|
||||||
import org.jgrapht.graph.DefaultWeightedEdge;
|
import org.jgrapht.graph.DefaultWeightedEdge;
|
||||||
|
import satisfactory.items.requirements.RateAccumulator;
|
||||||
|
import satisfactory.items.requirements.TotalAccumulator;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class Recipe {
|
public class Recipe {
|
||||||
private final Map<Item, Integer> inputs;
|
private final Map<Item, Integer> inputs;
|
||||||
private final Map<Item, Integer> outputs;
|
private final Map<Item, Integer> outputs;
|
||||||
private boolean isHandCraftable = true;
|
private boolean isHandCraftable = true;
|
||||||
private String name;
|
private String name;
|
||||||
private final int duration;
|
private final int duration;
|
||||||
|
|
||||||
public Recipe(int duration) {
|
public Recipe(int duration) {
|
||||||
inputs = new HashMap<>();
|
inputs = new HashMap<>();
|
||||||
outputs = new HashMap<>();
|
outputs = new HashMap<>();
|
||||||
this.duration = duration;
|
this.duration = duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Recipe(int duration, boolean isHandCraftable) {
|
public Recipe(int duration, boolean isHandCraftable) {
|
||||||
this(duration);
|
this(duration);
|
||||||
this.isHandCraftable = isHandCraftable;
|
this.isHandCraftable = isHandCraftable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Recipe(int duration, Item item, int input) {
|
public Recipe(int duration, Item item, int input) {
|
||||||
this(duration);
|
this(duration);
|
||||||
addInput(item, input);
|
addInput(item, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Recipe(int duration, Map<Item, Integer> inputs, Map<Item, Integer> outputs) {
|
public Recipe(int duration, Map<Item, Integer> inputs, Map<Item, Integer> outputs) {
|
||||||
this.duration = duration;
|
this.duration = duration;
|
||||||
this.inputs = inputs;
|
this.inputs = inputs;
|
||||||
this.outputs = outputs;
|
this.outputs = outputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Recipe(int duration, String name, boolean isHandCraftable) {
|
public Recipe(int duration, String name, boolean isHandCraftable) {
|
||||||
this(duration);
|
this(duration);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.isHandCraftable = isHandCraftable;
|
this.isHandCraftable = isHandCraftable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<String, Integer> getInputs(Map<Item, Integer> values) {
|
public static Map<String, Integer> getInputs(Map<Item, Integer> values) {
|
||||||
Map<String, Integer> names = new HashMap<>();
|
Map<String, Integer> names = new HashMap<>();
|
||||||
for (Item item : values.keySet()) {
|
for (Item item : values.keySet()) {
|
||||||
names.put(item.getName(), values.get(item));
|
names.put(item.getName(), values.get(item));
|
||||||
}
|
}
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addInput(Item item, int amount) {
|
public void addInput(Item item, int amount) {
|
||||||
inputs.put(item, amount);
|
inputs.put(item, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Recipe{" +
|
return "Recipe{" +
|
||||||
"inputs=" + inputs +
|
"inputs=" + inputs +
|
||||||
", outputs=" + formatIO(outputs) +
|
", outputs=" + formatIO(outputs) +
|
||||||
", isHandCraftable=" + isHandCraftable +
|
", isHandCraftable=" + isHandCraftable +
|
||||||
", name='" + name + '\'' +
|
", name='" + name + '\'' +
|
||||||
", duration=" + duration +
|
", duration=" + duration +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addInput(Item input) {
|
public void addInput(Item input) {
|
||||||
addInput(input, 1);
|
addInput(input, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addOutput(Item item, int amount) {
|
public void addOutput(Item item, int amount) {
|
||||||
this.outputs.put(item, amount);
|
this.outputs.put(item, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkOutput(Item item, int amount) {
|
public void checkOutput(Item item, int amount) {
|
||||||
if (!(outputs.containsKey(item) && outputs.get(item) == amount)) {
|
if (!(outputs.containsKey(item) && outputs.get(item) == amount)) {
|
||||||
outputs.put(item, amount);
|
outputs.put(item, amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String formatIO(Map<Item, Integer> map) {
|
private String formatIO(Map<Item, Integer> map) {
|
||||||
StringBuilder sb = new StringBuilder("{");
|
StringBuilder sb = new StringBuilder("{");
|
||||||
map.forEach((item, integer) -> sb.append(item.getName()).append(": ").append(integer).append(", "));
|
map.forEach((item, integer) -> sb.append(item.getName()).append(": ").append(integer).append(", "));
|
||||||
return sb.append("}").toString();
|
return sb.append("}").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Item, Integer> getTotalRequirements() {
|
public Map<Item, Integer> getTotalRequirements() {
|
||||||
return new TotalAccumulator(inputs).accumulate();
|
return new TotalAccumulator(inputs).accumulate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getProductionRate(Item item) {
|
public float getProductionRate(Item item) {
|
||||||
float production = outputs.get(item);
|
float production = outputs.get(item);
|
||||||
return (float) (production / (duration / 60.0));
|
return (float) (production / (duration / 60.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Item, Float> getRequirementRates(Item item) {
|
public Map<Item, Float> getRequirementRates(Item item) {
|
||||||
float rate = getProductionRate(item);
|
float rate = getProductionRate(item);
|
||||||
return new RateAccumulator(this, item).accumulate();
|
return new RateAccumulator(this, item).accumulate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Item, Integer> getInputs() {
|
public Map<Item, Integer> getInputs() {
|
||||||
return inputs;
|
return inputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Graph<Item, DefaultWeightedEdge> buildGraph(Item target) {
|
public Graph<Item, DefaultWeightedEdge> buildGraph(Item target) {
|
||||||
Graph<Item, DefaultWeightedEdge> graph = new DefaultDirectedWeightedGraph<>(DefaultWeightedEdge.class);
|
Graph<Item, DefaultWeightedEdge> graph = new DefaultDirectedWeightedGraph<>(DefaultWeightedEdge.class);
|
||||||
graph.addVertex(target);
|
graph.addVertex(target);
|
||||||
target.sum += 1;
|
target.sum += 1;
|
||||||
Map<Item, Integer> output = outputs.entrySet().stream()
|
Map<Item, Integer> output = outputs.entrySet().stream()
|
||||||
.filter(itemIntegerEntry -> itemIntegerEntry.getKey() != target)
|
.filter(itemIntegerEntry -> itemIntegerEntry.getKey() != target)
|
||||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||||
output.forEach((item, integer) -> {
|
output.forEach((item, integer) -> {
|
||||||
graph.addVertex(item);
|
graph.addVertex(item);
|
||||||
graph.addEdge(target, item);
|
graph.addEdge(target, item);
|
||||||
graph.setEdgeWeight(target, item, integer);
|
graph.setEdgeWeight(target, item, integer);
|
||||||
});
|
});
|
||||||
inputs.forEach((item, integer) -> {
|
inputs.forEach((item, integer) -> {
|
||||||
graph.addVertex(item);
|
graph.addVertex(item);
|
||||||
graph.addEdge(item, target);
|
graph.addEdge(item, target);
|
||||||
graph.setEdgeWeight(item, target, integer);
|
graph.setEdgeWeight(item, target, integer);
|
||||||
|
|
||||||
Recipe recipe = item.getRecipe();
|
Recipe recipe = item.getRecipe();
|
||||||
if (recipe != null) {
|
if (recipe != null) {
|
||||||
Graph<Item, DefaultWeightedEdge> g = recipe.buildGraph(item);
|
Graph<Item, DefaultWeightedEdge> g = recipe.buildGraph(item);
|
||||||
Graphs.addGraph(graph, g);
|
Graphs.addGraph(graph, g);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return graph;
|
return graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
private float getLoad(Item target, float amount) {
|
private float getLoad(Item target, float amount) {
|
||||||
return getUsage(target, amount) * duration;
|
return getUsage(target, amount) * duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
private float getUsage(Item target, float amount) {
|
private float getUsage(Item target, float amount) {
|
||||||
return amount / outputs.get(target);
|
return amount / outputs.get(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Graph<Item, DefaultWeightedEdge> buildGraph(Item target, float amountPerSecond) {
|
public Graph<Item, DefaultWeightedEdge> buildGraph(Item target, float amountPerSecond) {
|
||||||
Graph<Item, DefaultWeightedEdge> graph = new DefaultDirectedWeightedGraph<>(DefaultWeightedEdge.class);
|
Graph<Item, DefaultWeightedEdge> graph = new DefaultDirectedWeightedGraph<>(DefaultWeightedEdge.class);
|
||||||
graph.addVertex(target);
|
graph.addVertex(target);
|
||||||
target.sum += 1;
|
target.sum += 1;
|
||||||
float load = getLoad(target, amountPerSecond);
|
float load = getLoad(target, amountPerSecond);
|
||||||
// byproducts
|
// byproducts
|
||||||
Map<Item, Integer> output = outputs.entrySet().stream()
|
Map<Item, Integer> output = outputs.entrySet().stream()
|
||||||
.filter(itemIntegerEntry -> itemIntegerEntry.getKey() != target)
|
.filter(itemIntegerEntry -> itemIntegerEntry.getKey() != target)
|
||||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||||
output.forEach((item, integer) -> {
|
output.forEach((item, integer) -> {
|
||||||
graph.addVertex(item);
|
graph.addVertex(item);
|
||||||
graph.addEdge(target, item);
|
graph.addEdge(target, item);
|
||||||
graph.setEdgeWeight(target, item, integer * load);
|
graph.setEdgeWeight(target, item, integer * load);
|
||||||
});
|
});
|
||||||
// inputs
|
// inputs
|
||||||
inputs.forEach((item, integer) -> {
|
inputs.forEach((item, integer) -> {
|
||||||
graph.addVertex(item);
|
graph.addVertex(item);
|
||||||
graph.addEdge(item, target);
|
graph.addEdge(item, target);
|
||||||
float rate = (amountPerSecond / outputs.get(target)) / integer;
|
float rate = (amountPerSecond / outputs.get(target)) / integer;
|
||||||
graph.setEdgeWeight(item, target, rate);
|
graph.setEdgeWeight(item, target, rate);
|
||||||
|
|
||||||
Recipe recipe = item.getRecipe();
|
Recipe recipe = item.getRecipe();
|
||||||
if (recipe != null) {
|
if (recipe != null) {
|
||||||
Graph<Item, DefaultWeightedEdge> g = recipe.buildGraph(item, rate);
|
Graph<Item, DefaultWeightedEdge> g = recipe.buildGraph(item, rate);
|
||||||
Graphs.addGraph(graph, g);
|
Graphs.addGraph(graph, g);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return graph;
|
return graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private double processesNeeded(Item target, double n) {
|
private double processesNeeded(Item target, double n) {
|
||||||
Recipe r = target.getRecipe();
|
Recipe r = target.getRecipe();
|
||||||
return n / r.getProductionRate(target);
|
return n / r.getProductionRate(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Graph<Item, ProductionEdge> sum(Item target, int prodPerMinute) {
|
public SumResult sum(Item target, int prodPerMinute) {
|
||||||
Graph<Item, DefaultWeightedEdge> buildGraph = buildGraph(target);
|
Graph<Item, DefaultWeightedEdge> buildGraph = buildGraph(target);
|
||||||
Graph<Item, ProductionEdge> production = new DefaultDirectedWeightedGraph<>(ProductionEdge.class);
|
Graph<Item, ProductionEdge> production = new DefaultDirectedWeightedGraph<>(ProductionEdge.class);
|
||||||
Map<Item, Double> map = new HashMap<>();
|
Map<Item, Double> map = new HashMap<>();
|
||||||
Queue<Item> queue = new LinkedList<>();
|
Queue<Item> queue = new LinkedList<>();
|
||||||
queue.add(target);
|
queue.add(target);
|
||||||
map.put(target, (double) prodPerMinute);
|
map.put(target, (double) prodPerMinute);
|
||||||
production.addVertex(target);
|
production.addVertex(target);
|
||||||
production.addEdge(target, target, new ProductionEdge(target, prodPerMinute, processesNeeded(target, prodPerMinute)));
|
production.addEdge(target, target, new ProductionEdge(target, target, prodPerMinute, processesNeeded(target, prodPerMinute)));
|
||||||
while (!queue.isEmpty()) {
|
while (!queue.isEmpty()) {
|
||||||
Item item = queue.remove();
|
Item item = queue.remove();
|
||||||
// next satisfactory.items
|
// next items
|
||||||
buildGraph.incomingEdgesOf(item)
|
buildGraph.incomingEdgesOf(item)
|
||||||
.stream()
|
.stream()
|
||||||
.map(buildGraph::getEdgeSource)
|
.map(buildGraph::getEdgeSource)
|
||||||
.forEach(queue::add);
|
.forEach(queue::add);
|
||||||
// *this* item
|
// *this* item
|
||||||
double sum = 0;
|
double sum = 0;
|
||||||
Set<Item> byProducts = new HashSet<>();
|
Set<Item> byProducts = new HashSet<>();
|
||||||
for (DefaultWeightedEdge edge : buildGraph.outgoingEdgesOf(item)) {
|
for (DefaultWeightedEdge edge : buildGraph.outgoingEdgesOf(item)) {
|
||||||
Item product = buildGraph.getEdgeTarget(edge);
|
Item product = buildGraph.getEdgeTarget(edge);
|
||||||
Double productWantedPerMinute = map.get(product);
|
Double productWantedPerMinute = map.get(product);
|
||||||
if (item.getRecipe().outputs.containsKey(product)){
|
if (item.getRecipe().outputs.containsKey(product)) {
|
||||||
// product is by-product, no forward dependency
|
// product is by-product, no forward dependency
|
||||||
byProducts.add(product);
|
byProducts.add(product);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (productWantedPerMinute == null) {
|
if (productWantedPerMinute == null) {
|
||||||
sum = 0;
|
sum = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
double amountNeeded = buildGraph.getEdgeWeight(edge);
|
double amountNeeded = buildGraph.getEdgeWeight(edge);
|
||||||
int productPerProcess = product.getRecipe().outputs.get(product);
|
int productPerProcess = product.getRecipe().outputs.get(product);
|
||||||
double requiredProcesRuns = productWantedPerMinute / productPerProcess;
|
double requiredProcesRuns = productWantedPerMinute / productPerProcess;
|
||||||
double requiredInput = amountNeeded * requiredProcesRuns;
|
double requiredInput = amountNeeded * requiredProcesRuns;
|
||||||
sum += requiredInput;
|
sum += requiredInput;
|
||||||
|
|
||||||
|
production.addVertex(item);
|
||||||
|
production.addEdge(item, product, new ProductionEdge(item, product, requiredInput, processesNeeded(item, requiredInput)));
|
||||||
|
}
|
||||||
|
if (!map.containsKey(item) && sum > 0) {
|
||||||
|
map.put(item, sum);
|
||||||
|
}
|
||||||
|
if (!byProducts.isEmpty()) {
|
||||||
|
byProducts.forEach(item1 -> {
|
||||||
|
production.addVertex(item1);
|
||||||
|
// TODO: calculate produced amount
|
||||||
|
production.addEdge(item, item1, new ProductionEdge(item, item1, 0, 0));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
map.forEach((item, aDouble) -> {
|
||||||
|
System.out.println(item.getName() + ": " + aDouble);
|
||||||
|
});
|
||||||
|
return new SumResult(production, map);
|
||||||
|
}
|
||||||
|
|
||||||
production.addVertex(item);
|
|
||||||
production.addEdge(item, product, new ProductionEdge(item, requiredInput, processesNeeded(item, requiredInput)));
|
|
||||||
}
|
|
||||||
if (!map.containsKey(item) && sum > 0) {
|
|
||||||
map.put(item, sum);
|
|
||||||
}
|
|
||||||
if (!byProducts.isEmpty()) {
|
|
||||||
byProducts.forEach(item1 -> {
|
|
||||||
production.addVertex(item1);
|
|
||||||
// TODO: calculate produced amount
|
|
||||||
production.addEdge(item, item1, new ProductionEdge(item, 0,0));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
map.forEach((item, aDouble) -> {
|
|
||||||
System.out.println(item.getName() + ": " + aDouble);
|
|
||||||
});
|
|
||||||
return production;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
package satisfactory.items;
|
||||||
|
|
||||||
|
import org.jgrapht.Graph;
|
||||||
|
import org.jgrapht.graph.DefaultDirectedWeightedGraph;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class SumResult {
|
||||||
|
private final Graph<Item, ProductionEdge> production;
|
||||||
|
private final Map<Item, Double> map;
|
||||||
|
|
||||||
|
public SumResult(Graph<Item, ProductionEdge> production, Map<Item, Double> map) {
|
||||||
|
this.production = production;
|
||||||
|
this.map = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SumResult() {
|
||||||
|
production = new DefaultDirectedWeightedGraph<>(ProductionEdge.class);
|
||||||
|
map = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Graph<Item, ProductionEdge> getProduction() {
|
||||||
|
return production;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Item, Double> getMap() {
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SumResult merge(SumResult other){
|
||||||
|
HashMap<Item, Double> map = new HashMap<>();
|
||||||
|
this.map.forEach(map::put);
|
||||||
|
other.map.forEach((item, aDouble) -> map.merge(item,aDouble,Double::sum));
|
||||||
|
return new SumResult(merge(production, other.getProduction()), map);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Graph<Item, ProductionEdge> sum(Item item, int amount) {
|
||||||
|
return item.getRecipe().sum(item, amount).getProduction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SumResult sum(Production... productions) {
|
||||||
|
return Arrays.stream(productions)
|
||||||
|
.map(prod -> prod.getItem().getRecipe().sum(prod.getItem(), prod.getAmount()))
|
||||||
|
.reduce(SumResult::merge).orElse(new SumResult());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Graph<Item, ProductionEdge> merge(Graph<Item, ProductionEdge> graph0, Graph<Item, ProductionEdge> graph1) {
|
||||||
|
// ToDo: test!
|
||||||
|
Graph<Item, ProductionEdge> result = new DefaultDirectedWeightedGraph<>(ProductionEdge.class);
|
||||||
|
|
||||||
|
graph0.vertexSet().forEach(result::addVertex);
|
||||||
|
graph0.edgeSet().forEach(productionEdge -> result.addEdge(graph0.getEdgeSource(productionEdge), graph0.getEdgeTarget(productionEdge), productionEdge));
|
||||||
|
|
||||||
|
graph1.vertexSet().forEach(result::addVertex);
|
||||||
|
graph1.edgeSet().forEach(productionEdge -> {
|
||||||
|
List<ProductionEdge> collect = result.edgeSet().stream()
|
||||||
|
.filter(productionEdge1 -> productionEdge1.hasSource(productionEdge.getSource()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
collect.forEach(edge -> {
|
||||||
|
Item src = result.getEdgeSource(edge);
|
||||||
|
Item target = result.getEdgeTarget(edge);
|
||||||
|
Item target2 = graph1.getEdgeTarget(productionEdge);
|
||||||
|
if (target != target2) {
|
||||||
|
result.addEdge(src, target2, productionEdge);
|
||||||
|
} else {
|
||||||
|
/*result.removeEdge(edge);
|
||||||
|
result.addEdge(src, target, edge);*/
|
||||||
|
edge.merge(productionEdge);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (collect.isEmpty()) {
|
||||||
|
result.addEdge(graph1.getEdgeSource(productionEdge), graph1.getEdgeTarget(productionEdge), productionEdge);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,27 +1,28 @@
|
||||||
package satisfactory.items;
|
package satisfactory.items;
|
||||||
|
|
||||||
|
import org.jgrapht.Graph;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import satisfactory.Database;
|
||||||
|
import satisfactory.Utils;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import satisfactory.Database;
|
|
||||||
|
|
||||||
class ItemTest {
|
class ItemTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void productionScrews() {
|
void productionScrews() {
|
||||||
Map<Item, Double> production = Database.Screw.production(100);
|
Map<Item, Double> production = Database.Screw.production(100);
|
||||||
assertEquals(100, production.get(Database.Screw), "Screws (output)");
|
assertEquals(100, production.get(Database.Screw), "Screws (output)");
|
||||||
assertEquals(25, production.get(Database.IronRod), "IronRod");
|
assertEquals(25, production.get(Database.IronRod), "IronRod");
|
||||||
assertEquals(25, production.get(Database.IronIngot), "IronIngot");
|
assertEquals(25, production.get(Database.IronIngot), "IronIngot");
|
||||||
assertEquals(25, production.get(Database.IronOre), "IronOre");
|
assertEquals(25, production.get(Database.IronOre), "IronOre");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void productionScrews2() {
|
void productionScrews2() {
|
||||||
/*Map<Item, Double> production = Database.Screw.getRecipe().sum(Database.Screw, 100);
|
/*Map<Item, Double> production = Database.Screw.getRecipe().sum(Database.Screw, 100);
|
||||||
assertEquals(100, production.get(Database.Screw), "Screws (output)");
|
assertEquals(100, production.get(Database.Screw), "Screws (output)");
|
||||||
assertEquals(25, production.get(Database.IronRod), "IronRod");
|
assertEquals(25, production.get(Database.IronRod), "IronRod");
|
||||||
|
|
@ -29,23 +30,71 @@ class ItemTest {
|
||||||
assertEquals(25, production.get(Database.IronOre), "IronOre");
|
assertEquals(25, production.get(Database.IronOre), "IronOre");
|
||||||
|
|
||||||
*/
|
*/
|
||||||
fail("TODO: migrate");
|
fail("TODO: migrate");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void productionReinforcedIronPlates() {
|
void productionReinforcedIronPlates() {
|
||||||
Map<Item, Double> production = Database.ReinforcedIronPlate.production(100);
|
Map<Item, Double> production = Database.ReinforcedIronPlate.production(100);
|
||||||
assertEquals(100, production.get(Database.ReinforcedIronPlate), "output");
|
assertEquals(100, production.get(Database.ReinforcedIronPlate), "output");
|
||||||
assertEquals(1200, production.get(Database.Screw), "Screws");
|
assertEquals(1200, production.get(Database.Screw), "Screws");
|
||||||
assertEquals(300, production.get(Database.IronRod), "IronRod");
|
assertEquals(300, production.get(Database.IronRod), "IronRod");
|
||||||
assertEquals(1200, production.get(Database.IronIngot), "IronIngot");
|
assertEquals(1200, production.get(Database.IronIngot), "IronIngot");
|
||||||
assertEquals(1200, production.get(Database.IronOre), "IronOre");
|
assertEquals(1200, production.get(Database.IronOre), "IronOre");
|
||||||
assertEquals(600, production.get(Database.IronPlate), "IronPlate");
|
assertEquals(600, production.get(Database.IronPlate), "IronPlate");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testScrewProd(){
|
void testScrewProd() {
|
||||||
float productionRate = Database.Screw.getRecipe().getProductionRate(Database.Screw);
|
float productionRate = Database.Screw.getRecipe().getProductionRate(Database.Screw);
|
||||||
assertEquals(40, productionRate);
|
assertEquals(40, productionRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPhase3_ME_ACU() {
|
||||||
|
// references
|
||||||
|
Map<Item, Double> ref = new HashMap<>();
|
||||||
|
ref.put(Database.CircuitBoard, 15.0);
|
||||||
|
ref.put(Database.Computer, 1.0);
|
||||||
|
ref.put(Database.Limestone,75.0);
|
||||||
|
ref.put(Database.Concrete,25.0);
|
||||||
|
ref.put(Database.SteelBeam,20.0);
|
||||||
|
ref.put(Database.EncasedIndustrialBeam, 5.0);
|
||||||
|
ref.put(Database.ModularFrame,5.0);
|
||||||
|
ref.put(Database.HeavyModularFrame,1.0);
|
||||||
|
ref.put(Database.Plastic, 78.0);
|
||||||
|
ref.put(Database.CopperSheet, 30.0);
|
||||||
|
ref.put(Database.Coal,226.25);
|
||||||
|
ref.put(Database.Cable,159.0);
|
||||||
|
ref.put(Database.CopperOre,329.0);
|
||||||
|
ref.put(Database.AutomatedWiring, 7.5);
|
||||||
|
ref.put(Database.AdaptiveControlUnit, 1.0);
|
||||||
|
ref.put(Database.CrudeOil, 229.5);
|
||||||
|
ref.put(Database.ReinforcedIronPlate, 17.5);
|
||||||
|
ref.put(Database.CopperIngot, 329.0);
|
||||||
|
ref.put(Database.SteelIngot, 226.25);
|
||||||
|
ref.put(Database.IronPlate, 105.0);
|
||||||
|
ref.put(Database.SmartPlating, 10.0);
|
||||||
|
//ref.put(Database.HeavyOilResidue, 114.0); // TODO: implement calculation
|
||||||
|
ref.put(Database.Rubber, 75.0);
|
||||||
|
ref.put(Database.Wire, 538.0);
|
||||||
|
ref.put(Database.SteelPipe, 97.5);
|
||||||
|
ref.put(Database.Stator, 27.5);
|
||||||
|
ref.put(Database.Screw, 1112.0);
|
||||||
|
ref.put(Database.IronOre, 841.75);
|
||||||
|
ref.put(Database.IronIngot, 615.5);
|
||||||
|
ref.put(Database.IronRod, 458.0);
|
||||||
|
ref.put(Database.Rotor, 30.0);
|
||||||
|
ref.put(Database.Motor, 10.0);
|
||||||
|
ref.put(Database.ModularEngine, 5.0);
|
||||||
|
|
||||||
|
// calculate
|
||||||
|
Map<Item, Double> calculations = SumResult.sum(new Production(Database.ModularEngine, 5), new Production(Database.AdaptiveControlUnit, 1)).getMap();
|
||||||
|
|
||||||
|
// assert
|
||||||
|
ref.forEach((item, amount) -> {
|
||||||
|
assertTrue(calculations.containsKey(item), "exists? " + item.getName());
|
||||||
|
assertEquals(amount, calculations.get(item), 0.01, item.getName());
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue