The current Turbine code reads like this, with comments added for my own understanding/clarity:
private bool CanSteamFlow(ref bool insufficient_mass, ref bool insufficient_temperature) { float a1 = 0.0f; float a2 = 0.0f; float a3 = float.PositiveInfinity; this.isInputBlocked = false; for (int index = 0; index < this.master.srcCells.Length; ++index) // for each source cell { int srcCell = this.master.srcCells[index]; float b1 = Grid.Mass[srcCell]; // b1 = source cell mass if (Grid.Element[srcCell].id == this.master.srcElem) // if source cell is steam a1 = Mathf.Max(a1, b1); // a1 = max(a1,b1), get highest source mass float b2 = Grid.Temperature[srcCell]; // b2 = cell temp a2 = Mathf.Max(a2, b2); // a2 = max(a2, b2), get highest source temperature byte num = Grid.ElementIdx[srcCell]; Element element = ElementLoader.elements[(int) num]; if (element.IsLiquid || element.IsSolid) // if source cell is a liquid or solid this.isInputBlocked = true; // input is blocked } this.isOutputBlocked = false; // output is not blocked for (int index = 0; index < this.master.destCells.Length; ++index) // for each destination cell { int destCell = this.master.destCells[index]; float b = Grid.Mass[destCell]; // b = destination cell mass a3 = Mathf.Min(a3, b); // a3 = min(a3, b), get smallest output mass byte num = Grid.ElementIdx[destCell]; Element element = ElementLoader.elements[(int) num]; if (element.IsLiquid || element.IsSolid) // if source cell is a liquid or solid this.isOutputBlocked = true; // output is blocked } insufficient_mass = (double) a1 - (double) a3 < (double) this.master.requiredMassFlowDifferential; // insufficient mass if highest input mass - smallest output mass is less than 3 kg insufficient_temperature = (double) a2 < (double) this.master.minActiveTemperature; // insufficient temperature if highest input temperature is less than 400 K if (!insufficient_mass) return !insufficient_temperature; return false; }
Move "float b2 = Grid.Temperature[srcCell];" above the If statement.
Include "a2 = Mathf.Max(a2, b2);" in the If statement, so that only steam temperatures are considered. In other words, we do not want steam to flow if another gas other than steam is above the minActiveTemperature.
Change the ending If statements "if (!insufficient_mass)" to "if (!this.isInputBlocked && !this.isOutputBlocked && !insufficient_mass)" so that the input blocked and output blocked Boolean are considered.
The only problem that would not be resolved is where a low mass of gas exists above the steam turbine (in the destination cells) and never actually becomes compressed (increases in mass), so a3 always stays small. This is a common exploit (good, bad, otherwise?)
Maybe a way fix to this would be to compare steam separately from other gasses. If steam is present on the output, use the minimum steam mass, otherwise use the minimum non-steam mass.
Add a new variable for steam minimum mass:
float a4 = float.PositiveInfinity;
Make the min function in the destination dependent on destination cell element:
Grid.Element[destCell].id == this.master.srcElem ? a4 = Mathf.Min(a3, b) : a3 = Mathf.Min(a4, b);
And then add another conditional to use either the min steam or min non-steam:
a4 == float.PositiveInfinity ? a3 = a3 : a3 = a4;
The final logic would look like this:
private bool CanSteamFlow(ref bool insufficient_mass, ref bool insufficient_temperature) { float a1 = 0.0f; float a2 = 0.0f; float a3 = float.PositiveInfinity; float a4 = float.PositiveInfinity; this.isInputBlocked = false; for (int index = 0; index < this.master.srcCells.Length; ++index) // for each source cell { int srcCell = this.master.srcCells[index]; float b1 = Grid.Mass[srcCell]; // b1 = source cell mass float b2 = Grid.Temperature[srcCell]; // b2 = cell temp if (Grid.Element[srcCell].id == this.master.srcElem) // if source cell is steam { a1 = Mathf.Max(a1, b1); // a1 = max(a1,b1), get highest source mass a2 = Mathf.Max(a2, b2); // a2 = max(a2, b2), get highest source temperature } byte num = Grid.ElementIdx[srcCell]; Element element = ElementLoader.elements[(int) num]; if (element.IsLiquid || element.IsSolid) // if source cell is a liquid or solid this.isInputBlocked = true; // input is blocked } this.isOutputBlocked = false; // out is not blocked for (int index = 0; index < this.master.destCells.Length; ++index) // for each destination cell { int destCell = this.master.destCells[index]; float b = Grid.Mass[destCell]; // b = destination cell mass Grid.Element[destCell].id == this.master.srcElem ? a4 = Mathf.Min(a4, b) : a3 = Mathf.Min(a3, b); // if destination cell is steam evaluate a4 = min(a4, b) and get smallest steam output mass, otherwise evaluate a3 = min(a3, b) and get smallest non-steam output mass byte num = Grid.ElementIdx[destCell]; Element element = ElementLoader.elements[(int) num]; if (element.IsLiquid || element.IsSolid) // if source cell is a liquid or solid this.isOutputBlocked = true; // output is blocked } a4 == float.PositiveInfinity ? a3 = a3 : a3 = a4; // if no steam (min steam mass is still positive infinity), then use regular non-steam minimum mass a3, otherwise use steam miminum mass a4 insufficient_mass = (double) a1 - (double) a3 < (double) this.master.requiredMassFlowDifferential; // insufficient mass if highest input mass - smallest output mass is less than 3 kg insufficient_temperature = (double) a2 < (double) this.master.minActiveTemperature; // insufficient temperature if highest input temperature is less than 400 K if (!this.isInputBlocked && !this.isOutputBlocked && !insufficient_mass) return !insufficient_temperature; return false; }
Caution, I'm not a C# programmer, so my syntax may be a little off. I also hope posting code snippets is also not against the forum rules. If so, I apologize. Thanks for a great game!
Examine game code and refer to https://forums.kleientertainment.com/forums/topic/98732-the-steam-turbine-everything-you-need-to-know/
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now