/// <summary> /// Before a save, simulate any lightning the previous night should have had safely. /// </summary> private void BeforeSave(object sender, EventArgs e) { if (this.previousDayRNGInfo == null) { return; } //Fix Game1.wasRainingYesterday Game1.wasRainingYesterday = Game1.wasRainingYesterday || this.previousDayRNGInfo.isLightning; int num = (2400 - this.previousDayRNGInfo.time) / 100; this.Monitor.Log($"Running overnight lightning {num} times.", LogLevel.Trace); for (int i = 0; i < num; i++) { if (SDVLightningMimic.GetSDVLightningStrikePositionAt(this.previousDayRNGInfo, out KeyValuePair <Vector2, TerrainFeature> item)) { this.SaveFeature(item.Key, item.Value); this.Monitor.Log($"{item.Value.GetType().Name} at {item.Key} will be hit next.", LogLevel.Trace); } SDVLightningMimic.CauseVanillaStrike(this.previousDayRNGInfo); this.RestoreLocationAndIgnoreErrors(Game1.getFarm(), this.featuresBeforeTheyWereHit); } this.previousDayRNGInfo = null; }
public override string Parse(string[] args) { string result = "Okay, lightning strikes today will be at:"; for (int i = 600; i < 2400; i = SafeLightningMod.GetNextTime(i)) { if (SDVLightningMimic.GetSDVLightningStrikePositionAt(new LightningStrikeRNGInfo(i), out KeyValuePair <Vector2, TerrainFeature>?feature)) { result += $"\nLightning strike: {i} at {feature.Value.Key} on {feature.Value.Value.GetType().Name}."; } } return(result); }
/// <summary> /// When told that another mod will cause a lightning strike, save the state of that <see cref="TerrainFeature" /> so /// it can be restored. /// </summary> /// <param name="position">The position that will be hit</param> /// <param name="effects">Whether visual/sound effects should be created</param> private void ModWantsToStrikeLightningAt(Vector2 position, bool effects) { if (!Context.IsWorldReady) { return; } if (Game1.getFarm().terrainFeatures.TryGetValue(position, out TerrainFeature feature)) { this.SaveFeature(position, feature); this.modForcedRestore = true; } SDVLightningMimic.StrikeLightningSafelyAt(this.Monitor, position, effects); }
/// <summary> /// Handles the next update tick. Restores any affected <see cref="TerrainFeature"/>s and saves <see cref="TerrainFeature"/>s to be hit in the next ten minutes. /// </summary> private void UpdateTick(object sender, EventArgs e) { if (!Context.IsWorldReady) { return; } if ((savedFeaturesAt != -1 && savedFeaturesAt != Game1.timeOfDay) || modForcedRestore) { RestoreLocationAndIgnoreErrors(Game1.getFarm(), featuresBeforeTheyWereHit); if (modForcedRestore) { modForcedRestore = false; } if (savedFeaturesAt != -1) { savedFeaturesAt = -1; } } //Lightning protection works by saving features right before lightning hits them, i.e. right before the game's ten minute update. //Unfortunately, there is no reliable way to determine when the current tick is the last tick before the ten minute update. //We use a margin based on the game's original code to save features. The margin is large enough to be compatible with mods that speed up //time up to ten in game minutes == 1 real life second, but save more than necessary for the default ten minute length. if (Game1.gameTimeInterval >= 7000 + Game1.currentLocation.getExtraMillisecondsPerInGameMinuteForThisLocation() - margin) { if (SDVLightningMimic.GetSDVLightningStrikePositionAt(new LightningStrikeRNGInfo(true), out KeyValuePair <Vector2, TerrainFeature>?item)) { SaveFeature(item.Value.Key, item.Value.Value); } savedFeaturesAt = Game1.timeOfDay; } if (Game1.newDay) { PrepareForOvernightLightning(); } lastTimeOfDay = Game1.timeOfDay; }