Skip to content

Commit 21119d8

Browse files
committed
Major update to factorio 2.0: base game (non SA)
1 parent ef44a9c commit 21119d8

30 files changed

+15718
-7548
lines changed

Foreman/Controls/EditRecipePanel.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ private void UpdateBeaconInfo()
414414

415415
BeaconEnergyLabel.Text = nodeData.SelectedBeacon == null ? "0J" : GraphicsStuff.DoubleToEnergy(nodeData.GetBeaconEnergyConsumption(), "W");
416416
BeaconModuleCountLabel.Text = nodeData.SelectedBeacon == null ? "0" : nodeData.SelectedBeacon.ModuleSlots.ToString();
417-
BeaconEfficiencyLabel.Text = nodeData.SelectedBeacon == null ? "0%" : nodeData.SelectedBeacon.BeaconEffectivity.ToString("P0");
417+
BeaconEfficiencyLabel.Text = nodeData.SelectedBeacon == null ? "0%" : nodeData.SelectedBeacon.GetBeaconEffectivity(nodeData.SelectedBeacon.Owner.DefaultQuality, nodeData.BeaconCount).ToString("P0"); //QUALITY UPDATE REQUIRED
418418
TotalBeaconsLabel.Text = nodeData.GetTotalBeacons().ToString();
419419
TotalBeaconEnergyLabel.Text = nodeData.SelectedBeacon == null ? "0J" : GraphicsStuff.DoubleToEnergy(nodeData.GetTotalBeaconElectricalConsumption(), "W");
420420
}

Foreman/DataCache/DataCache.cs

+376-160
Large diffs are not rendered by default.

Foreman/DataCache/DataTypes/Assembler.cs

+24-1
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,41 @@ namespace Foreman
77
public interface Assembler : EntityObjectBase
88
{
99
IReadOnlyCollection<Recipe> Recipes { get; }
10+
double BaseSpeedBonus { get; }
1011
double BaseProductivityBonus { get; }
12+
double BaseConsumptionBonus { get; }
13+
double BasePollutionBonus { get; }
14+
double BaseQualityBonus { get; }
15+
16+
bool AllowBeacons { get; }
17+
bool AllowModules { get; }
1118
}
1219

1320
internal class AssemblerPrototype : EntityObjectBasePrototype, Assembler
1421
{
1522
public IReadOnlyCollection<Recipe> Recipes { get { return recipes; } }
16-
public double BaseProductivityBonus { get; set; }
23+
public double BaseSpeedBonus { get; set; }
24+
public double BaseProductivityBonus { get; set; }
25+
public double BaseConsumptionBonus { get; set; }
26+
public double BasePollutionBonus { get; set; }
27+
public double BaseQualityBonus { get; set; }
28+
29+
public bool AllowBeacons { get; internal set; }
30+
public bool AllowModules { get; internal set; }
1731

1832
internal HashSet<RecipePrototype> recipes { get; private set; }
1933

2034
public AssemblerPrototype(DataCache dCache, string name, string friendlyName, EntityType type, EnergySource source, bool isMissing = false) : base(dCache, name, friendlyName, type, source, isMissing)
2135
{
36+
BaseSpeedBonus = 0;
37+
BaseProductivityBonus = 0;
38+
BaseConsumptionBonus = 0;
39+
BasePollutionBonus = 0;
40+
BaseQualityBonus = 0;
41+
42+
AllowBeacons = false; //assumed to be default? no info in LUA
43+
AllowModules = false; //assumed to be default? no info in LUA
44+
2245
recipes = new HashSet<RecipePrototype>();
2346
}
2447

Foreman/DataCache/DataTypes/Beacon.cs

+38-3
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,53 @@
11

2+
using System;
3+
using System.Collections.Generic;
4+
25
namespace Foreman
36
{
7+
48
public interface Beacon : EntityObjectBase
59
{
6-
double BeaconEffectivity { get; }
10+
double GetBeaconEffectivity(Quality quality, double beaconCount);
711
}
812

913
internal class BeaconPrototype : EntityObjectBasePrototype, Beacon
1014
{
11-
public double BeaconEffectivity { get; set; }
15+
16+
public double GetBeaconEffectivity(Quality quality, double beaconCount)
17+
{
18+
if (beaconCount <= 0)
19+
return 0;
20+
if(beaconCount > 999)
21+
beaconCount = 999;
22+
23+
int baseCount = (int)Math.Truncate(beaconCount);
24+
double remainder = beaconCount - baseCount;
25+
26+
double lowerBeaconEffectivity = baseCount * GetBeaconEffectivityBase(quality, baseCount);
27+
double upperBeaconEffectivity = (baseCount + 1) * GetBeaconEffectivityBase(quality, baseCount + 1);
28+
29+
return (((1 - remainder) * lowerBeaconEffectivity) + (remainder * upperBeaconEffectivity)) / beaconCount;
30+
//just to explain - we need to calculate the 'average' beacon effectivity for a beacon count of (for example) 1.6:
31+
//this means that for every 10 assemblers you have 6 with 2 beacons and 4 with 1 beacon. So calculate the total bonus and divide it by beaconCount.
32+
//therefore 10 assemblers with beacon count of 1.6 will produce exactly the same amount as 6 assemblers with 2 beacons + 4 assemblers with 1 beacon
33+
}
34+
35+
private double GetBeaconEffectivityBase(Quality quality, int beaconCount)
36+
{
37+
return profile[beaconCount] * (DistributionEffectivity + (quality.Level * DistributionEffectivityQualityBoost));
38+
}
39+
40+
internal double DistributionEffectivity { get; set; }
41+
internal double DistributionEffectivityQualityBoost { get; set; }
42+
43+
internal double[] profile { get; private set; } //off by 1 from factorio (or more akin same index as LUA starts from 0) ==> profile[x] is the multiplier for x beacons (so profile[0] is multiplier for 0 beacons...)
1244

1345
public BeaconPrototype(DataCache dCache, string name, string friendlyName, EnergySource source, bool isMissing = false) : base(dCache, name, friendlyName, EntityType.Beacon, source, isMissing)
1446
{
15-
BeaconEffectivity = 0.5f;
47+
profile = new double[1000];
48+
for(int i = 1; i < profile.Length; i++) { profile[i] = 0.5f; }
49+
DistributionEffectivity = 0.5f;
50+
DistributionEffectivityQualityBoost = 0f;
1651
}
1752

1853
public override string ToString() { return string.Format("Beacon: {0}", Name); }

Foreman/DataCache/DataTypes/EntityObjectBase.cs

+33-21
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public interface EntityObjectBase : DataObjectBase
1717
IReadOnlyCollection<Module> Modules { get; }
1818
IReadOnlyCollection<Item> Fuels { get; }
1919
IReadOnlyCollection<Item> AssociatedItems { get; }
20+
IReadOnlyDictionary<string, double> Pollution { get; }
2021

2122
EntityType EntityType { get; }
2223
string GetEntityTypeName(bool plural);
@@ -25,19 +26,19 @@ public interface EntityObjectBase : DataObjectBase
2526
bool IsTemperatureFluidBurner { get; }
2627
fRange FluidFuelTemperatureRange { get; }
2728

28-
double GetBaseFuelConsumptionRate(Item fuel, double temperature = double.NaN);
29+
double GetBaseFuelConsumptionRate(Item fuel, Quality quality, double temperature = double.NaN);
2930

3031
bool IsMissing { get; }
3132

32-
double Speed { get; }
33+
double GetSpeed(Quality quality);
3334

3435
int ModuleSlots { get; }
3536

36-
double EnergyDrain { get; }
37-
double EnergyConsumption { get; }
38-
double EnergyProduction { get; }
37+
double GetEnergyDrain();
38+
double GetEnergyConsumption(Quality quality);
39+
double GetEnergyProduction(Quality quality);
40+
3941
double ConsumptionEffectivity { get; }
40-
double Pollution { get; }
4142

4243
//steam generators
4344
double OperationTemperature { get; }
@@ -53,10 +54,12 @@ internal class EntityObjectBasePrototype : DataObjectBasePrototype, EntityObject
5354
public IReadOnlyCollection<Module> Modules { get { return modules; } }
5455
public IReadOnlyCollection<Item> Fuels { get { return fuels; } }
5556
public IReadOnlyCollection<Item> AssociatedItems { get { return associatedItems; } }
57+
public IReadOnlyDictionary<string, double> Pollution { get { return pollution; } }
5658

5759
internal HashSet<ModulePrototype> modules { get; private set; }
5860
internal HashSet<ItemPrototype> fuels { get; private set; }
5961
internal List<ItemPrototype> associatedItems { get; private set; } //should honestly only be 1, but knowing modders....
62+
internal Dictionary<string, double> pollution { get; private set; }
6063

6164
public EntityType EntityType { get; private set; }
6265
public EnergySource EnergySource { get; internal set; }
@@ -65,56 +68,65 @@ internal class EntityObjectBasePrototype : DataObjectBasePrototype, EntityObject
6568
public bool IsTemperatureFluidBurner { get; set; }
6669
public fRange FluidFuelTemperatureRange { get; set; }
6770

68-
private double speed;
69-
public double Speed { get { return speed; } internal set { speed = value == 0 ? 0.001 : value; } }
71+
internal Dictionary<Quality, double> speed { get; private set; }
72+
internal Dictionary<Quality, double> energyConsumption { get; private set; }
73+
internal Dictionary<Quality, double> energyProduction { get; private set; }
74+
75+
public double GetSpeed(Quality quality) { return speed.ContainsKey(quality)? (speed[quality] > 0 ? speed[quality] : 1) : 1; }
7076

7177
public int ModuleSlots { get; internal set; }
7278
public double NeighbourBonus { get; internal set; }
7379

74-
public double EnergyDrain { get; internal set; } //per second
75-
public double EnergyConsumption { get; internal set; }
76-
public double EnergyProduction { get; internal set; }
80+
internal double energyDrain;
81+
public double GetEnergyDrain() { return energyDrain; }
82+
public double GetEnergyConsumption(Quality quality)
83+
{
84+
if(this is BeaconPrototype)
85+
return quality.BeaconPowerMultiplier * (energyConsumption.ContainsKey(quality) ? energyConsumption[quality] : 1000);
86+
else
87+
return energyConsumption.ContainsKey(quality)? energyConsumption[quality] : 1000;
88+
}
89+
public double GetEnergyProduction(Quality quality) { return energyConsumption.ContainsKey(quality)? energyProduction[quality] : 0; }
90+
7791
public double ConsumptionEffectivity { get; internal set; }
7892
public double OperationTemperature { get; internal set; }
7993

80-
public double Pollution { get; internal set; }
81-
8294
public EntityObjectBasePrototype(DataCache dCache, string name, string friendlyName, EntityType type, EnergySource source, bool isMissing) : base(dCache, name, friendlyName, "-")
8395
{
8496
availableOverride = false;
8597

8698
modules = new HashSet<ModulePrototype>();
8799
fuels = new HashSet<ItemPrototype>();
88100
associatedItems = new List<ItemPrototype>();
101+
pollution = new Dictionary<string, double>();
102+
103+
speed = new Dictionary<Quality, double>();
104+
energyConsumption = new Dictionary<Quality, double>();
105+
energyProduction = new Dictionary<Quality, double>();
89106

90107
IsMissing = isMissing;
91108
EntityType = type;
92109
EnergySource = source;
93110

94111
//just some base defaults -> helps prevent overflow errors during solving if the assembler is a missing entity
95-
Speed = 1f;
96112
ModuleSlots = 0;
97113
NeighbourBonus = 0;
98-
EnergyDrain = 0; //passive use (pretty much electricity only)
99-
EnergyConsumption = 1000; //default value to prevent issues with missing objects
100-
EnergyProduction = 0;
101114
ConsumptionEffectivity = 1f;
102115
OperationTemperature = double.MaxValue;
103116
FluidFuelTemperatureRange = new fRange(double.MinValue, double.MaxValue);
104117

105-
Pollution = 0;
106118
}
107119

108-
public double GetBaseFuelConsumptionRate(Item fuel, double temperature = double.NaN)
120+
public double GetBaseFuelConsumptionRate(Item fuel, Quality quality, double temperature = double.NaN)
109121
{
110122
if ((EnergySource != EnergySource.Burner && EnergySource != EnergySource.FluidBurner && EnergySource != EnergySource.Heat))
111123
Trace.Fail(string.Format("Cant ask for fuel consumption rate on a non-burner! {0}", this));
112124
else if (!fuels.Contains(fuel))
113125
Trace.Fail(string.Format("Invalid fuel! {0} for entity {1}", fuel, this));
114126
else if (!IsTemperatureFluidBurner)
115-
return EnergyConsumption / (fuel.FuelValue * ConsumptionEffectivity);
127+
return GetEnergyConsumption(quality) / (fuel.FuelValue * ConsumptionEffectivity);
116128
else if (!double.IsNaN(temperature) && (fuel is Fluid fluidFuel) && (temperature > fluidFuel.DefaultTemperature) && (fluidFuel.SpecificHeatCapacity > 0)) //temperature burn of liquid
117-
return EnergyConsumption / ((temperature - fluidFuel.DefaultTemperature) * fluidFuel.SpecificHeatCapacity * ConsumptionEffectivity);
129+
return GetEnergyConsumption(quality) / ((temperature - fluidFuel.DefaultTemperature) * fluidFuel.SpecificHeatCapacity * ConsumptionEffectivity);
118130
return 0.01; // we cant have a 0 consumption rate as that would mess with the solver.
119131
}
120132

Foreman/DataCache/DataTypes/Fluid.cs

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ public interface Fluid : Item
1111
bool IsTemperatureDependent { get; }
1212
double DefaultTemperature { get; }
1313
double SpecificHeatCapacity { get; }
14+
double GasTemperature { get; }
15+
double MaxTemperature { get; }
1416

1517
string GetTemperatureRangeFriendlyName(fRange tempRange);
1618
string GetTemperatureFriendlyName(double temperature);
@@ -21,12 +23,16 @@ public class FluidPrototype : ItemPrototype, Fluid
2123
public bool IsTemperatureDependent { get; internal set; } //true if not all recipes can accept each other (ex: fluid produced in R1 is at 10*c, and is required to be at 20+*c as ingredient at R2)
2224
public double DefaultTemperature { get; internal set; }
2325
public double SpecificHeatCapacity { get; internal set; }
26+
public double GasTemperature { get; internal set; }
27+
public double MaxTemperature { get; internal set; }
2428

2529
public FluidPrototype(DataCache dCache, string name, string friendlyName, SubgroupPrototype subgroup, string order, bool isMissing = false) : base(dCache, name, friendlyName, subgroup, order, isMissing)
2630
{
2731
IsTemperatureDependent = false;
2832
DefaultTemperature = 0;
2933
SpecificHeatCapacity = 0;
34+
GasTemperature = 0;
35+
MaxTemperature = 0;
3036
}
3137

3238
public string GetTemperatureRangeFriendlyName(fRange tempRange)

Foreman/DataCache/DataTypes/Item.cs

+22
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,22 @@ public interface Item : DataObjectBase
1717

1818
int StackSize { get; }
1919

20+
double Weight { get; }
21+
double IngredientToWeightCoefficient { get; }
2022
double FuelValue { get; }
2123
double PollutionMultiplier { get; }
24+
2225
Item BurnResult { get; }
26+
Item PlantResult { get; }
27+
Item SpoilResult { get; }
28+
2329
Item FuelOrigin { get; }
30+
Item PlantOrigin { get; }
31+
Item SpoilOrigin { get; }
32+
2433
IReadOnlyCollection<EntityObjectBase> FuelsEntities { get; }
34+
35+
//spoil ticks are ignored - its assumed that if there is a plant/spoil result then the ticks are at least low enough to make it viable on a world basis
2536
}
2637

2738
public class ItemPrototype : DataObjectBasePrototype, Item
@@ -36,10 +47,19 @@ public class ItemPrototype : DataObjectBasePrototype, Item
3647

3748
public int StackSize { get; set; }
3849

50+
public double Weight { get; set; }
51+
public double IngredientToWeightCoefficient { get; set; }
3952
public double FuelValue { get; internal set; }
4053
public double PollutionMultiplier { get; internal set; }
54+
4155
public Item BurnResult { get; internal set; }
56+
public Item PlantResult { get; internal set; }
57+
public Item SpoilResult { get; internal set; }
58+
4259
public Item FuelOrigin { get; internal set; }
60+
public Item PlantOrigin { get; internal set; }
61+
public Item SpoilOrigin { get; internal set; }
62+
4363
public IReadOnlyCollection<EntityObjectBase> FuelsEntities { get { return fuelsEntities; } }
4464

4565
internal SubgroupPrototype mySubgroup;
@@ -61,6 +81,8 @@ public ItemPrototype(DataCache dCache, string name, string friendlyName, Subgrou
6181
consumptionTechnologies = new HashSet<TechnologyPrototype>();
6282
fuelsEntities = new HashSet<EntityObjectBasePrototype>();
6383

84+
Weight = 0.01f;
85+
IngredientToWeightCoefficient = 1f;
6486
FuelValue = 1f; //useful for preventing overlow issues when using missing items / non-fuel items (loading with wrong mods / importing from alt mod group can cause this)
6587
PollutionMultiplier = 1f;
6688
IsMissing = isMissing;

Foreman/DataCache/DataTypes/Module.cs

+14-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ public interface Module : DataObjectBase
1818
double ProductivityBonus { get; }
1919
double ConsumptionBonus { get; }
2020
double PollutionBonus { get; }
21+
double QualityBonus { get; }
22+
23+
string Category { get; }
2124

2225
int Tier { get; }
2326

@@ -32,10 +35,13 @@ public class ModulePrototype : DataObjectBasePrototype, Module
3235
public IReadOnlyCollection<Recipe> AvailableRecipes { get; private set; }
3336
public Item AssociatedItem { get { return Owner.Items[Name]; } }
3437

35-
public double SpeedBonus { get; set; }
36-
public double ProductivityBonus { get; set; }
37-
public double ConsumptionBonus { get; set; }
38-
public double PollutionBonus { get; set; }
38+
public double SpeedBonus { get; internal set; }
39+
public double ProductivityBonus { get; internal set; }
40+
public double ConsumptionBonus { get; internal set; }
41+
public double PollutionBonus { get; internal set; }
42+
public double QualityBonus { get; internal set; }
43+
44+
public string Category { get; internal set; }
3945

4046
public int Tier { get; set; }
4147

@@ -55,6 +61,10 @@ public ModulePrototype(DataCache dCache, string name, string friendlyName, bool
5561
ProductivityBonus = 0;
5662
ConsumptionBonus = 0;
5763
PollutionBonus = 0;
64+
QualityBonus = 0;
65+
66+
Category = "";
67+
5868
recipes = new HashSet<RecipePrototype>();
5969
assemblers = new HashSet<AssemblerPrototype>();
6070
beacons = new HashSet<BeaconPrototype>();
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using System.Collections.Generic;
2+
using System.Diagnostics;
3+
using System.Drawing;
4+
using System.Linq;
5+
6+
namespace Foreman
7+
{
8+
public interface Quality : DataObjectBase
9+
{
10+
Quality NextQuality { get; }
11+
Quality PrevQuality { get; }
12+
double NextProbability { get; }
13+
14+
int Level { get; }
15+
double BeaconPowerMultiplier { get; }
16+
double MiningDrillResourceDrainMultiplier { get; }
17+
18+
}
19+
20+
public class QualityPrototype : DataObjectBasePrototype, Quality
21+
{
22+
public Quality NextQuality { get; internal set; }
23+
public Quality PrevQuality { get; internal set; }
24+
public double NextProbability { get; set; }
25+
26+
public int Level { get; set; }
27+
public double BeaconPowerMultiplier { get; set; }
28+
public double MiningDrillResourceDrainMultiplier { get; set; }
29+
30+
public QualityPrototype(DataCache dCache, string name, string friendlyName, string order) : base(dCache, name, friendlyName, order)
31+
{
32+
Enabled = true;
33+
34+
Level = 0;
35+
BeaconPowerMultiplier = 1;
36+
MiningDrillResourceDrainMultiplier = 1;
37+
}
38+
39+
public override string ToString() { return string.Format("Quality T{0}: {1}", Level, Name); }
40+
}
41+
}

0 commit comments

Comments
 (0)