public static Vector2 GetGroupStoragePower(string location, PipeGroup group, GridType type) { var chargeKey = type == GridType.water ? "aedenthorn.UtilityGrid/waterCharge" : "aedenthorn.UtilityGrid/electricCharge"; Vector2 power = Vector2.Zero; foreach (var v in utilitySystemDict[location][type].objects.Keys.ToArray()) { if (!group.pipes.Contains(v)) { continue; } var obj = utilitySystemDict[location][type].objects[v]; var objW = obj.WorldObject; var objT = obj.Template; var capacity = type == GridType.water ? objT.waterChargeCapacity : objT.electricChargeCapacity; if (capacity == 0) { continue; } float charge = 0; if (objW.modData.TryGetValue(chargeKey, out string chargeString)) { float.TryParse(chargeString, NumberStyles.Float, CultureInfo.InvariantCulture, out charge); } power.X += Math.Min(charge, type == GridType.water ? objT.waterDischargeRate : objT.electricDischargeRate); power.Y -= Math.Min(capacity - charge, type == GridType.water ? objT.waterChargeRate : objT.electricChargeRate); } return(power); // X is providable, Y is receivable }
public static Vector2 GetGroupPower(string location, PipeGroup group, GridType type) { Vector2 power = Vector2.Zero; foreach (var tile in group.pipes) { if (!utilitySystemDict[location][type].objects.TryGetValue(tile, out UtilityObjectInstance obj)) { continue; } var objT = obj.Template; if (type == GridType.water && objT.electric < 0) { Vector2 ePower = GetTileElectricPower(location, tile); if (ePower.X == 0 || ePower.X + ePower.Y < 0) // unpowered { continue; } } power += GetPowerVector(location, obj, type == GridType.water ? objT.water : objT.electric); } foreach (var func in powerFuctionList) { power += func(location, (int)type, group.pipes); } foreach (var v in utilitySystemDict[location][type].objects.Keys.ToArray()) { if (group.pipes.Contains(v)) { utilitySystemDict[location][type].objects[v].CurrentPowerVector = power; } } return(power); }
public static void RemakeGroups(string location, GridType gridType) { if (!utilitySystemDict.ContainsKey(location)) { utilitySystemDict[location] = new Dictionary <GridType, UtilitySystem>(); } Dictionary <Vector2, GridPipe> pipeDict = new Dictionary <Vector2, GridPipe>(utilitySystemDict[location][gridType].pipes); List <PipeGroup> groupList = utilitySystemDict[location][gridType].groups; groupList.Clear(); while (pipeDict.Count > 0) { var tile = pipeDict.Keys.ToArray()[0]; var group = new PipeGroup { pipes = new List <Vector2>() { tile } }; //SMonitor.Log($"Creating new group; power: {group.input}"); pipeDict.Remove(tile); AddTilesToGroup(location, tile, ref group, pipeDict, gridType); groupList.Add(group); } AddObjectsToGrid(location, gridType); EventHandler <KeyValuePair <GameLocation, int> > handler = refreshEventHandler; if (handler != null) { GameLocation gl = Game1.getLocationFromName(location); if (gl == null) { gl = Game1.getLocationFromName(location, true); if (gl == null) { return; } } KeyValuePair <GameLocation, int> e = new KeyValuePair <GameLocation, int>(gl, (int)gridType); handler(context, e); } }
public static void AddTilesToGroup(string location, Vector2 tile, ref PipeGroup group, Dictionary <Vector2, GridPipe> pipeDict, GridType gridType) { Vector2[] adjecents = new Vector2[] { tile + new Vector2(0, 1), tile + new Vector2(1, 0), tile + new Vector2(-1, 0), tile + new Vector2(0, -1) }; foreach (var a in adjecents) { if (group.pipes.Contains(a) || !pipeDict.ContainsKey(a)) { continue; } if (PipesAreJoined(location, tile, a, gridType)) { group.pipes.Add(a); pipeDict.Remove(a); //SMonitor.Log($"Adding pipe to group; {group.pipes.Count} pipes in group; total power: {group.input}"); AddTilesToGroup(location, a, ref group, pipeDict, gridType); } } }
public static void ChangeStorageObjects(string location, PipeGroup group, GridType type, float hours) { var netPower = group.powerVector.X + group.powerVector.Y; if (group.storageVector.X + netPower < 0) // not enough stored power { return; } GameLocation gl = Game1.getLocationFromName(location, false); if (gl == null) { gl = Game1.getLocationFromName(location, true); if (gl == null) { SMonitor.Log($"Invalid game location {location}", StardewModdingAPI.LogLevel.Error); return; } } var chargeKey = type == GridType.water ? "aedenthorn.UtilityGrid/waterCharge" : "aedenthorn.UtilityGrid/electricCharge"; var changeObjects = new Dictionary <Vector2, float>(); foreach (var v in utilitySystemDict[location][type].objects.Keys.ToArray()) { if (!group.pipes.Contains(v)) { continue; } var obj = utilitySystemDict[location][type].objects[v]; var objW = obj.WorldObject; var objT = obj.Template; var capacity = type == GridType.water ? objT.waterChargeCapacity : objT.electricChargeCapacity; if (capacity == 0) { continue; } float charge = 0; if (obj.WorldObject.modData.TryGetValue(chargeKey, out string chargeString)) { float.TryParse(chargeString, NumberStyles.Float, CultureInfo.InvariantCulture, out charge); } if (type == GridType.water && hours > 0 && objT.fillWaterFromRain && gl.IsOutdoors && Game1.netWorldState.Value.GetWeatherForLocation(gl.GetLocationContext()).isRaining.Value) { charge = Math.Min(charge + objT.waterChargeRate * hours, objT.waterChargeCapacity); objW.modData[chargeKey] = charge + ""; } if (netPower != 0) { if (netPower > 0) { changeObjects.Add(v, Math.Min(capacity - charge, type == GridType.water ? objT.waterChargeRate : objT.electricChargeRate)); } else { changeObjects.Add(v, Math.Min(charge, type == GridType.water ? objT.waterDischargeRate : objT.electricDischargeRate)); } } } // change charges while (changeObjects != null && changeObjects.Count > 0 && netPower != 0) { var eachPower = netPower / changeObjects.Count; foreach (var v in changeObjects.Keys.ToArray()) { var obj = utilitySystemDict[location][type].objects[v].WorldObject; var objT = utilitySystemDict[location][type].objects[v].Template; float currentCharge = 0; float diff = changeObjects[v]; if (obj.modData.TryGetValue(chargeKey, out string chargeString)) { float.TryParse(chargeString, NumberStyles.Float, CultureInfo.InvariantCulture, out currentCharge); } if (eachPower > 0) { var capacity = type == GridType.water ? objT.waterChargeCapacity : objT.electricChargeCapacity; var add = Math.Min(capacity - currentCharge, Math.Min(diff, eachPower)); if (hours > 0) { SMonitor.Log($"adding {add * hours} {type} energy to {obj.Name} at {v}"); obj.modData[chargeKey] = Math.Min(capacity, currentCharge + add * hours) + ""; } changeObjects[v] -= add; if (add != eachPower) { changeObjects.Remove(v); } } else { float subtract = Math.Min(currentCharge, Math.Min(diff, -eachPower)); if (hours > 0) { SMonitor.Log($"subtracting {subtract * hours} {type} energy from {obj.Name} at {v}"); obj.modData[chargeKey] = Math.Max(0, currentCharge - subtract * hours) + ""; } changeObjects[v] -= subtract; if (subtract != -eachPower) { changeObjects.Remove(v); } } } } }