// To support the decay delay, we will use the HoeDirt.state variable to track how many days the patch has gone without being watered. // For example: 'state == -3' indicates that the tile hasn't been watered in the past 3 days. void HoeDirt_dayUpdate() { // Find: if (crop != null) var dayUpdate = BeginCode(); var begin = AttachLabel(dayUpdate[0]); dayUpdate.Prepend( // if (crop == null Instructions.Ldarg_0(), Instructions.Callvirt_get(typeof(HoeDirt), nameof(HoeDirt.crop)), Instructions.Brtrue(begin), // && state <= 0) { Instructions.Ldarg_0(), Instructions.Ldfld(typeof(HoeDirt), nameof(HoeDirt.state)), Instructions.Call_get(typeof(NetInt), nameof(NetInt.Value)), Instructions.Ldc_I4_0(), Instructions.Bgt(begin), // state--; Instructions.Ldarg_0(), Instructions.Ldfld(typeof(HoeDirt), nameof(HoeDirt.state)), Instructions.Dup(), Instructions.Call_get(typeof(NetInt), nameof(NetInt.Value)), Instructions.Ldc_I4_1(), Instructions.Sub(), Instructions.Call_set(typeof(NetInt), nameof(NetInt.Value)), // return; Instructions.Ret() // } ); }
void HoeDirt_dayUpdate() { // Find: if (crop != null) var dayUpdate = BeginCode(); var begin = AttachLabel(dayUpdate[0]); dayUpdate.Prepend( // if (crop == null Instructions.Ldarg_0(), Instructions.Callvirt_get(typeof(StardewValley.TerrainFeatures.HoeDirt), "crop"), Instructions.Brtrue(begin), // && state <= 0) { Instructions.Ldarg_0(), Instructions.Ldfld(typeof(StardewValley.TerrainFeatures.HoeDirt), "state"), Instructions.Call_get(typeof(Netcode.NetInt), "Value"), Instructions.Ldc_I4_0(), Instructions.Bgt(begin), // state--; Instructions.Ldarg_0(), Instructions.Ldfld(typeof(StardewValley.TerrainFeatures.HoeDirt), "state"), Instructions.Dup(), Instructions.Call_get(typeof(Netcode.NetInt), "Value"), Instructions.Ldc_I4_1(), Instructions.Sub(), Instructions.Call_set(typeof(Netcode.NetInt), "Value"), // return; Instructions.Ret() // } ); }
void Farm_DayUpdate() { var hdv = generator.DeclareLocal(typeof(HoeDirt)); // Inject code to check if soil is sufficiently dried out. var DayUpdate = FindCode( // if (!terrainFeatures[key] is HoeDirt) OpCodes.Ldarg_0, OpCodes.Ldfld, //Instructions.Ldfld(typeof(GameLocation), nameof(GameLocation.terrainFeatures)), OpCodes.Ldloc_S, OpCodes.Callvirt, Instructions.Isinst(typeof(HoeDirt)), OpCodes.Brfalse ); DayUpdate.Replace( // if (terrainFeatures[key] as HoeDirt).state > -ModConfig.DecayConfig.getFarmConfig(dayOfMonth).DryingDelay DayUpdate[0], DayUpdate[1], DayUpdate[2], DayUpdate[3], DayUpdate[4], Instructions.Stloc_S(hdv), Instructions.Ldloc_S(hdv), DayUpdate[5], Instructions.Ldloc_S(hdv), Instructions.Ldfld(typeof(HoeDirt), nameof(HoeDirt.state)), Instructions.Call_get(typeof(NetInt), nameof(NetInt.Value)), Instructions.Call(GetType(), nameof(getConfig)), Instructions.Ldfld(typeof(ModConfig), nameof(ModConfig.EachNight)), Instructions.Ldfld(typeof(ModConfig.DecayConfig), nameof(ModConfig.DecayConfig.Delay)), Instructions.Neg(), Instructions.Bgt((Label)DayUpdate[5].operand) ); DayUpdate = DayUpdate.FindNext( // Game1.random.NextDouble() <= 0.1 Instructions.Ldsfld(typeof(Game1), nameof(Game1.random)), OpCodes.Callvirt, OpCodes.Ldc_R8 ); DayUpdate.Replace( // Game1.random.NextDouble() <= ModConfig.DecayConfig.getFarmConfig(dayOfMonth).DryingRate DayUpdate[0], DayUpdate[1], // Set Decay Rate Instructions.Call(GetType(), nameof(getConfig)), Instructions.Ldfld(typeof(ModConfig), nameof(ModConfig.EachNight)), Instructions.Ldfld(typeof(ModConfig.DecayConfig), nameof(ModConfig.DecayConfig.DryingRate)) ); }
void IslandWest_DayUpdate() { var hdv = generator.DeclareLocal(typeof(HoeDirt)); var DayUpdate = FindCode( // is HoeDirt Instructions.Isinst(typeof(HoeDirt)), // .crop == null Instructions.Callvirt_get(typeof(HoeDirt), nameof(HoeDirt.crop)), OpCodes.Brtrue, // Game1.random.NextDouble() <= 0.1 Instructions.Ldsfld(typeof(Game1), nameof(Game1.random)), OpCodes.Callvirt, OpCodes.Ldc_R8 ); DayUpdate.Replace( DayUpdate[0], // Inject && state <= -delay Instructions.Stloc_S(hdv), Instructions.Ldloc_S(hdv), Instructions.Ldfld(typeof(HoeDirt), nameof(HoeDirt.state)), Instructions.Call_get(typeof(NetInt), nameof(NetInt.Value)), Instructions.Call(GetType(), nameof(getConfig)), Instructions.Ldfld(typeof(ModConfig), nameof(ModConfig.Island)), Instructions.Ldfld(typeof(ModConfig.DecayConfig), nameof(ModConfig.DecayConfig.Delay)), Instructions.Neg(), Instructions.Bgt((Label)DayUpdate[2].operand), Instructions.Ldloc_S(hdv), // Continue with && crop == null DayUpdate[1], DayUpdate[2], DayUpdate[3], DayUpdate[4], // Set Decay Rate Instructions.Call(GetType(), nameof(getConfig)), Instructions.Ldfld(typeof(ModConfig), nameof(ModConfig.Island)), Instructions.Ldfld(typeof(ModConfig.DecayConfig), nameof(ModConfig.DecayConfig.DryingRate)) ); }
void Farm_DayUpdate() { //var crop = GetField("StardewValley.TerrainFeatures.HoeDirt::crop"); //var state = GetField("StardewValley.TerrainFeatures.HoeDirt::state"); var DayUpdate = BeginCode(); var hdv = generator.DeclareLocal(typeof(HoeDirt)); // There are 2 updates. One for normal day transitions and one for the first of the month. for (int i = 0; i < 2; i++) { DayUpdate = DayUpdate.FindNext( Instructions.Isinst(typeof(HoeDirt)), Instructions.Callvirt_get(typeof(HoeDirt), nameof(HoeDirt.crop)), OpCodes.Brtrue, Instructions.Ldsfld(typeof(Game1), nameof(Game1.random)), OpCodes.Callvirt, OpCodes.Ldc_R8 ); // Set Decay Rate DayUpdate[5].operand = (i == 0 ? config.DryDecayRate : config.DryDecayRateFirstOfMonth); int delay = (i == 0 ? config.DecayDelay : config.DecayDelayFirstOfMonth); if (delay > 0) { DayUpdate.Insert(1, // Inject && state <= -delay Instructions.Stloc_S(hdv), Instructions.Ldloc_S(hdv), Instructions.Ldfld(typeof(HoeDirt), nameof(HoeDirt.state)), Instructions.Call_get(typeof(NetInt), nameof(NetInt.Value)), Instructions.Ldc_I4(-delay), Instructions.Bgt((Label)DayUpdate[2].operand), Instructions.Ldloc_S(hdv) // Continue with && crop == null ); } } }