public static void ShakeNettles(CustomBush bush) { string variety = (string)bush.Variety; if (variety == ModEntry.BushNameNettle) { DelayedAction.playSoundAfterDelay("leafrustle", 100); Game1.player.takeDamage( damage: Math.Max(1, int.Parse(ModEntry.ItemDefinitions["NettlesDamage"][0]) - Game1.player.resilience), overrideParry: true, damager: null); if (Game1.player.health < 1) { Game1.player.health = 1; } Buff existingBuff = Game1.buffsDisplay.otherBuffs .FirstOrDefault(b => b.source == variety); if (existingBuff is null) { Game1.buffsDisplay.addOtherBuff(new Buff( 0, 0, 0, 0, 0, 0, 0, 0, 0, speed: -1, 0, 0, minutesDuration: 10, source: variety, displaySource: ModEntry.Instance.Helper.Translation.Get("buff.nettles.inspect"))); } else { existingBuff.millisecondsDuration = 6000; } } }
internal static void TrySpawnNettles() { // Only master player should make changes to the world if (Game1.MasterPlayer.UniqueMultiplayerID != Game1.player.UniqueMultiplayerID) { return; } // Attempt to place a wild nettle as forage around other weeds bool spawnNettlesToday = Game1.currentSeason == "summer" || ((Game1.currentSeason == "spring" || Game1.currentSeason == "fall") && Game1.dayOfMonth % 3 == 1); if (ModEntry.NettlesEnabled && spawnNettlesToday) { foreach (string l in ModEntry.ItemDefinitions["NettlesLocations"]) { if (Game1.random.NextDouble() > float.Parse(ModEntry.ItemDefinitions["NettlesDailyChancePerLocation"][0])) { // Skip the location if we didn't succeed the roll to add nettles Log.D($"Did not add nettles to {l}.", ModEntry.Instance.Config.DebugMode); continue; } // Spawn a random number of nettles between some upper and lower bounds, reduced by the number of nettles already in this location GameLocation location = Game1.getLocationFromName(l); int nettlesToAdd = Game1.random.Next(int.Parse(ModEntry.ItemDefinitions["NettlesAddedRange"][0]), int.Parse(ModEntry.ItemDefinitions["NettlesAddedRange"][1])); int nettlesAlreadyInLocation = location.Objects.Values.Count(o => o.Name.ToLower().EndsWith("nettles")); nettlesToAdd -= nettlesAlreadyInLocation; int nettlesAdded = 0; List <Vector2> shuffledWeedsTiles = location.Objects.Keys.Where( tile => location.Objects.TryGetValue(tile, out StardewValley.Object o) && o.Name == "Weeds").ToList(); Utility.Shuffle(Game1.random, shuffledWeedsTiles); foreach (Vector2 tile in shuffledWeedsTiles) { if (nettlesAdded >= nettlesToAdd) { // Move to the next location if this location's quota is met break; } Vector2 nearbyTile = Utility.getRandomAdjacentOpenTile(tile, location); if (nearbyTile == Vector2.Zero) { // Skip weeds without any free spaces to spawn nettles upon continue; } // Spawn nettles around other weeds CustomBush nettleBush = new CustomBush(tile: nearbyTile, location: location, variety: BushVariety.Nettle); location.largeTerrainFeatures.Add(nettleBush); ++nettlesAdded; Log.D($"Adding to {nearbyTile}...", ModEntry.Instance.Config.DebugMode); } Log.D($"Added {nettlesAdded} nettles to {l}.", ModEntry.Instance.Config.DebugMode); } } }
internal BushToolUsedEventArgs(CustomBush bush, Tool tool, int explosion, Vector2 tileLocation, GameLocation location) { this.Bush = bush; this.Tool = tool; this.Explosion = explosion; this.TileLocation = tileLocation; this.Location = location; }
public static void ShakeBehaviour(CustomBush bush, Vector2 tileLocation) { if (bush.Variety == BushVariety.Redberry) { for (int i = 0; i < bush.HeldItemQuantity; ++i) { Game1.createObjectDebris(bush.HeldItemId, (int)tileLocation.X, (int)tileLocation.Y); } } }
/* HarmonyPatch behaviours */ public static bool InBloomBehaviour(CustomBush bush, string season, int dayOfMonth) { if (bush.Variety == BushVariety.Nettle) { return(false); } bool inSeason = dayOfMonth >= 22 && (!season.Equals("winter") || bush.greenhouseBush.Value); return(bush.IsMature && inSeason); }
public static void SpawnNettles(bool force = false) { foreach (string l in ModEntry.ItemDefinitions["NettlesLocations"]) { if (!force && Game1.random.NextDouble() > float.Parse(ModEntry.ItemDefinitions["NettlesDailyChancePerLocation"][0])) { // Skip the location if we didn't succeed the roll to add nettles Log.D($"Did not add nettles to {l}.", ModEntry.Config.DebugMode); continue; } // Spawn a random number of nettles between some upper and lower bounds, reduced by the number of nettles already in this location GameLocation location = Game1.getLocationFromName(l); int nettlesToAdd = Game1.random.Next(int.Parse(ModEntry.ItemDefinitions["NettlesAddedRange"][0]), int.Parse(ModEntry.ItemDefinitions["NettlesAddedRange"][1])); int nettlesAlreadyInLocation = force ? 0 : location.largeTerrainFeatures.Count( ltf => ltf is CustomBush cb && (string)cb.Variety == ModEntry.BushNameNettle); nettlesToAdd -= nettlesAlreadyInLocation; int nettlesAdded = 0; List <Vector2> shuffledWeedsTiles = location.Objects.Keys .Where(tile => location.Objects.TryGetValue(tile, out StardewValley.Object o) && o.Name == "Weeds") .ToList(); Utility.Shuffle(Game1.random, shuffledWeedsTiles); foreach (Vector2 tile in shuffledWeedsTiles) { if (nettlesAdded >= nettlesToAdd) { // Move to the next location if this location's quota is met break; } Vector2 nearbyTile = Utility.getRandomAdjacentOpenTile(tile, location); if (nearbyTile == Vector2.Zero) { // Skip weeds without any free spaces to spawn nettles upon continue; } // Spawn nettles around other weeds CustomBush nettleBush = new CustomBush( tile: nearbyTile, location: location, variety: ModEntry.BushNameNettle); location.largeTerrainFeatures.Add(nettleBush); ++nettlesAdded; Log.D($"Adding to {nearbyTile}...", force || ModEntry.Config.DebugMode); } Log.D($"Added {nettlesAdded} nettles to {l}.", force || ModEntry.Config.DebugMode); } }
internal static void InvokeOnBushToolUsed(CustomBush bush, Tool tool, int explosion, Vector2 tileLocation, GameLocation location) { if (BushToolUsed == null) { return; } BushToolUsed.Invoke( sender: null, e: new BushToolUsedEventArgs(bush: bush, tool: tool, explosion: explosion, tileLocation: tileLocation, location: location)); }
internal static void InvokeOnBushShaken(CustomBush bush) { if (BushShaken == null) { return; } BushShaken.Invoke( sender: null, e: new BushShakenEventArgs(bush: bush)); }
public static bool IsDestroyableBehaviour(CustomBush bush) { return(true); }
public static int GetEffectiveSizeBehaviour(CustomBush bush) { return(bush.EffectiveSize); }
internal BushShakenEventArgs(CustomBush bush) { this.Bush = bush; }