/// <summary>Generates a large object and places it on the specified map and tile.</summary> /// <param name="index">The parent sheet index (a.k.a. object ID) of the object type to spawn.</param> /// <param name="location">The GameLocation where the large object should be spawned.</param> /// <param name="tile">The x/y coordinates of the tile where the ore should be spawned.</param> public static bool SpawnLargeObject(int index, GameLocation location, Vector2 tile) { Monitor.VerboseLog($"Spawning large object. ID: {index}. Location: {tile.X},{tile.Y} ({location.Name})."); ResourceClump clump; if (index == 190 || index == 254 || index == 276) //if this should be a GiantCrop { clump = new GiantCrop(index, tile); } else //if this should be a ResourceClump { clump = new ResourceClump(index, 2, 2, tile); } if (location is Farm farm) { farm.resourceClumps.Add(clump); //spawn the specified resource clump } else if (location is MineShaft mine) { mine.resourceClumps.Add(clump); //spawn the specified resource clump } else //if this is not a farm or mine, which generally means it lacks a "resourceClumps" list { location.largeTerrainFeatures.Add(new LargeResourceClump(clump)); //spawn a wrapped version of the specified resource clump } return(true); }
static void Prefix(ref ResourceClump __instance, Tool t, int damage, Vector2 tileLocation, GameLocation location) { if (t is Axe && t.UpgradeLevel == 5 && (__instance.parentSheetIndex.Value == 600 || __instance.parentSheetIndex.Value == 602)) { __instance.health.Value = 0; } }
private static void ResourceClumpPostfix(ResourceClump __instance) { var instanceName = $"{AlternativeTextureModel.TextureType.ResourceClump}_{GetResourceClumpName(__instance)}"; var instanceSeasonName = $"{instanceName}_{Game1.GetSeasonForLocation(__instance.currentLocation)}"; if (AlternativeTextures.textureManager.DoesObjectHaveAlternativeTexture(instanceName) && AlternativeTextures.textureManager.DoesObjectHaveAlternativeTexture(instanceSeasonName)) { var result = Game1.random.Next(2) > 0 ? AssignModData(__instance, instanceSeasonName, true) : AssignModData(__instance, instanceName, false); return; } else { if (AlternativeTextures.textureManager.DoesObjectHaveAlternativeTexture(instanceName)) { AssignModData(__instance, instanceName, false); return; } if (AlternativeTextures.textureManager.DoesObjectHaveAlternativeTexture(instanceSeasonName)) { AssignModData(__instance, instanceSeasonName, true); return; } } AssignDefaultModData(__instance, instanceSeasonName, true); }
private static bool DrawPrefix(ResourceClump __instance, float ___shakeTimer, SpriteBatch spriteBatch, Vector2 tileLocation) { if (__instance.modData.ContainsKey("AlternativeTextureName")) { var textureModel = AlternativeTextures.textureManager.GetSpecificTextureModel(__instance.modData["AlternativeTextureName"]); if (textureModel is null) { return(true); } var textureVariation = Int32.Parse(__instance.modData["AlternativeTextureVariation"]); if (textureVariation == -1 || AlternativeTextures.modConfig.IsTextureVariationDisabled(textureModel.GetId(), textureVariation)) { return(true); } Vector2 position = __instance.tile.Value * 64f; if (___shakeTimer > 0f) { position.X += (float)Math.Sin(Math.PI * 2.0 / (double)___shakeTimer) * 4f; } var textureOffset = textureModel.GetTextureOffset(textureVariation); Rectangle sourceRect = new Rectangle(0, textureOffset, 32, 32); spriteBatch.Draw(textureModel.GetTexture(textureVariation), Game1.GlobalToLocal(Game1.viewport, position), sourceRect, Color.White, 0f, Vector2.Zero, 4f, SpriteEffects.None, (__instance.tile.Y + 1f) * 64f / 10000f + __instance.tile.X / 100000f); return(false); } return(true); }
static ValMap ToMap(ResourceClump clump) { if (clump == null) { return(null); } var result = new ValMap(); result.map[_type] = new ValString("Clump"); string name; switch (clump.parentSheetIndex.Value) { case ResourceClump.boulderIndex: name = "Boulder"; break; case ResourceClump.hollowLogIndex: name = "Hollow Log"; break; case ResourceClump.meteoriteIndex: name = "Meteorite"; break; case ResourceClump.mineRock1Index: case ResourceClump.mineRock2Index: case ResourceClump.mineRock3Index: case ResourceClump.mineRock4Index: name = "Mine Rock"; break; case ResourceClump.stumpIndex: name = "Stump"; break; default: name = "#" + clump.parentSheetIndex.Value; break; } result.map[_name] = new ValString(name); result.map[_health] = new ValNumber(clump.health.Value); return(result); }
/// <summary>Get the resource clump which covers a given tile, if any.</summary> /// <param name="location">The location to check.</param> /// <param name="tile">The tile to check.</param> /// <param name="player">The current player.</param> /// <param name="applyTool">Applies a tool to the resource clump.</param> protected ResourceClump GetResourceClumpCoveringTile(GameLocation location, Vector2 tile, Farmer player, out Func <Tool, bool> applyTool) { Rectangle tileArea = this.GetAbsoluteTileArea(tile); // normal resource clumps foreach (ResourceClump clump in this.GetNormalResourceClumps(location)) { if (clump.getBoundingBox(clump.tile.Value).Intersects(tileArea)) { applyTool = tool => this.UseToolOnTile(tool, tile, player, location); return(clump); } } // FarmTypeManager resource clumps if (this.HasFarmTypeManager) { foreach (LargeTerrainFeature feature in location.largeTerrainFeatures) { if (feature.GetType().FullName == "FarmTypeManager.LargeResourceClump" && feature.getBoundingBox(feature.tilePosition.Value).Intersects(tileArea)) { ResourceClump clump = this.Reflection.GetField <Netcode.NetRef <ResourceClump> >(feature, "Clump").GetValue().Value; applyTool = tool => feature.performToolAction(tool, 0, tile, location); return(clump); } } } applyTool = null; return(null); }
private bool CheckIfTileBelongToResourceClump(int ResourceClumpIndex, Vector2 tile) { TerrainFeature check; if (Game1.currentLocation.terrainFeatures.TryGetValue(tile, out check)) { if (check is ResourceClump) { ResourceClump RC = (ResourceClump)check; if (RC.parentSheetIndex == ResourceClumpIndex) { return(true); } } } Vector2 tileToLeft = new Vector2(tile.X - 1, tile.Y); if (Game1.currentLocation.terrainFeatures.TryGetValue(tileToLeft, out check)) { if (check is ResourceClump) { ResourceClump RC = (ResourceClump)check; if (RC.parentSheetIndex == ResourceClumpIndex) { return(true); } } } Vector2 tileToTopLeft = new Vector2(tile.X - 1, tile.Y - 1); if (Game1.currentLocation.terrainFeatures.TryGetValue(tileToTopLeft, out check)) { if (check is ResourceClump) { ResourceClump RC = (ResourceClump)check; if (RC.parentSheetIndex == ResourceClumpIndex) { return(true); } } } Vector2 tileToTop = new Vector2(tile.X, tile.Y - 1); if (Game1.currentLocation.terrainFeatures.TryGetValue(tileToTop, out check)) { if (check is ResourceClump) { ResourceClump RC = (ResourceClump)check; if (RC.parentSheetIndex == ResourceClumpIndex) { return(true); } } } return(false); }
public override bool Apply(Vector2 tile, SObject tileObj, TerrainFeature tileFeature, SFarmer who, Tool tool, Item item, GameLocation location) { if (this.Config.CutDebris && tileObj?.Name == "Stone") { return(this.UseToolOnTile(tool, tile)); } if (tileFeature is HoeDirt dirt) { if (this.Config.ClearDirt && dirt.crop == null) { return(this.UseToolOnTile(tool, tile)); } if (this.Config.CutDeadCrops && dirt.crop.dead) { return(this.UseToolOnTile(tool, tile)); } } if (this.Config.ClearBouldersAndMeteor) { ResourceClump rc = this.ResourceClumpCoveringTile(location, tile); if (rc != null && this.ResourceUpgradeNeeded.ContainsKey(rc.parentSheetIndex) && tool.upgradeLevel >= this.ResourceUpgradeNeeded[rc.parentSheetIndex]) { this.UseToolOnTile(tool, tile); } } return(false); }
public static bool DoDamage_Prefix(ref MeleeWeapon __instance, GameLocation location, int x, int y, int facingDirection, int power, Farmer who) { // Add functionality to be able to damage resource clumps with mattocks. if (__instance is Mattock mattock) { if (who.IsLocalPlayer) { Vector2 tileLocation3 = Vector2.Zero; Vector2 tileLocation2 = Vector2.Zero; Rectangle areaOfEffect = __instance.getAreaOfEffect(x, y, facingDirection, ref tileLocation3, ref tileLocation2, who.GetBoundingBox(), who.FarmerSprite.currentAnimationIndex); foreach (Vector2 v in Utility.removeDuplicates(Utility.getListOfTileLocationsForBordersOfNonTileRectangle(areaOfEffect))) { ResourceClump[] clumpCopy = new ResourceClump[location.resourceClumps.Count]; location.resourceClumps.CopyTo(clumpCopy, 0); foreach (ResourceClump resourceClump in clumpCopy) { if (mattock.struckFeatures.Contains(resourceClump)) { continue; } if (resourceClump.occupiesTile((int)v.X, (int)v.Y)) { Tool standinTool = null; switch (resourceClump.parentSheetIndex.Get()) { // Stumps case 600: case 602: standinTool = mattock.asAxe(); break; // Boulders case 622: case 672: case 752: case 754: case 756: case 758: standinTool = mattock.asPickaxe(); break; } if (standinTool != null) { mattock.struckFeatures.Add(resourceClump); if (resourceClump.performToolAction(standinTool, 1, resourceClump.tile.Get(), location)) { location.resourceClumps.Remove(resourceClump); } } } } } } } return(true); }
private static void SeasonUpdatePostfix(ResourceClump __instance, bool onLoad) { if (__instance.modData.ContainsKey("AlternativeTextureName") && __instance.modData.ContainsKey("AlternativeTextureSeason") && !String.IsNullOrEmpty(__instance.modData["AlternativeTextureSeason"])) { __instance.modData["AlternativeTextureSeason"] = Game1.GetSeasonForLocation(__instance.currentLocation); __instance.modData["AlternativeTextureName"] = String.Concat(__instance.modData["AlternativeTextureOwner"], ".", $"{AlternativeTextureModel.TextureType.ResourceClump}_{GetResourceClumpName(__instance)}_{__instance.modData["AlternativeTextureSeason"]}"); } }
public Forest(Map map, string name) : base(map, name) { this.marniesLivestock = new List <FarmAnimal>(); this.marniesLivestock.Add(new FarmAnimal("Dairy Cow", MultiplayerUtility.getNewID(), -1L)); this.marniesLivestock.Add(new FarmAnimal("Dairy Cow", MultiplayerUtility.getNewID(), -1L)); this.marniesLivestock[0].position = new Vector2((float)(98 * Game1.tileSize), (float)(20 * Game1.tileSize)); this.marniesLivestock[1].position = new Vector2((float)(101 * Game1.tileSize), (float)(20 * Game1.tileSize)); this.log = new ResourceClump(602, 2, 2, new Vector2(1f, 6f)); }
public Forest(string map, string name) : base(map, name) { marniesLivestock.Add(new FarmAnimal("Dairy Cow", Game1.multiplayer.getNewID(), -1L)); marniesLivestock.Add(new FarmAnimal("Dairy Cow", Game1.multiplayer.getNewID(), -1L)); marniesLivestock[0].Position = new Vector2(6272f, 1280f); marniesLivestock[1].Position = new Vector2(6464f, 1280f); log = new ResourceClump(602, 2, 2, new Vector2(1f, 6f)); }
public CustomResourceClump(ResourceClump rc) : base(rc.parentSheetIndex.Value, rc.width.Value, rc.height.Value, rc.currentTileLocation) { parentSheetIndex.Value = rc.parentSheetIndex.Value; width.Value = rc.width.Value; height.Value = rc.height.Value; currentTileLocation = rc.currentTileLocation; health.Value = rc.health.Value; }
/// <summary>Apply the tool to the given tile.</summary> /// <param name="tile">The tile to modify.</param> /// <param name="tileObj">The object on the tile.</param> /// <param name="tileFeature">The feature on the tile.</param> /// <param name="player">The current player.</param> /// <param name="tool">The tool selected by the player (if any).</param> /// <param name="item">The item selected by the player (if any).</param> /// <param name="location">The current location.</param> public override bool Apply(Vector2 tile, SObject tileObj, TerrainFeature tileFeature, SFarmer player, Tool tool, Item item, GameLocation location) { // break stones if (this.Config.ClearDebris && tileObj?.Name == "Stone") { return(this.UseToolOnTile(tool, tile)); } // break flooring & paths if (this.Config.ClearFlooring && tileFeature is Flooring) { return(this.UseToolOnTile(tool, tile)); } // break objects if (this.Config.ClearObjects && tileObj != null) { return(this.UseToolOnTile(tool, tile)); } // clear twigs & weeds if (this.Config.ClearWeeds && this.IsWeed(tileObj)) { return(this.UseToolOnTile(tool, tile)); } // handle dirt if (tileFeature is HoeDirt dirt) { // clear tilled dirt if (this.Config.ClearDirt && dirt.crop == null) { return(this.UseToolOnTile(tool, tile)); } // clear dead crops if (this.Config.ClearDeadCrops && dirt.crop != null && dirt.crop.dead.Value) { return(this.UseToolOnTile(tool, tile)); } } // clear boulders / meteorites // This needs to check if the axe upgrade level is high enough first, to avoid spamming // 'need to upgrade your tool' messages. Based on ResourceClump.performToolAction. if (this.Config.ClearBouldersAndMeteorites) { ResourceClump clump = this.GetResourceClumpCoveringTile(location, tile); if (clump != null && (!this.ResourceUpgradeLevelsNeeded.TryGetValue(clump.parentSheetIndex.Value, out int requiredUpgradeLevel) || tool.UpgradeLevel >= requiredUpgradeLevel)) { return(this.UseToolOnTile(tool, tile)); } } return(false); }
private static bool IsResourceClumpBoulderAt(ResourceClump resourceClump, int x, int y) { return(resourceClump.occupiesTile(x, y) && (resourceClump.parentSheetIndex.Value == ResourceClump.meteoriteIndex || resourceClump.parentSheetIndex.Value == ResourceClump.boulderIndex || resourceClump.parentSheetIndex.Value == ResourceClump.mineRock1Index || resourceClump.parentSheetIndex.Value == ResourceClump.mineRock2Index || resourceClump.parentSheetIndex.Value == ResourceClump.mineRock3Index || resourceClump.parentSheetIndex.Value == ResourceClump.mineRock4Index)); }
public static bool performToolAction(ref ResourceClump __instance, ref Tool t, ref int damage, ref Vector2 tileLocation, ref GameLocation location) { if (__instance.parentSheetIndex.Value == 622) { monitor.Log("Found a Meteor."); return(false); } return(true); }
/// <summary>Apply the tool to the given tile.</summary> /// <param name="tile">The tile to modify.</param> /// <param name="tileObj">The object on the tile.</param> /// <param name="tileFeature">The feature on the tile.</param> /// <param name="player">The current player.</param> /// <param name="tool">The tool selected by the player (if any).</param> /// <param name="item">The item selected by the player (if any).</param> /// <param name="location">The current location.</param> public override bool Apply(Vector2 tile, SObject tileObj, TerrainFeature tileFeature, SFarmer player, Tool tool, Item item, GameLocation location) { // clear twigs & weeds if (this.Config.ClearDebris && (tileObj?.Name == "Twig" || tileObj?.Name.ToLower().Contains("weed") == true)) { return(this.UseToolOnTile(tool, tile)); } // check terrain feature switch (tileFeature) { // cut non-fruit tree case Tree tree: if (tree.tapped ? this.Config.CutTappedTrees : this.Config.CutTrees) { return(this.UseToolOnTile(tool, tile)); } break; // cut fruit tree case FruitTree _: if (this.Config.CutFruitTrees) { return(this.UseToolOnTile(tool, tile)); } break; // clear crops case HoeDirt dirt when dirt.crop != null: if (this.Config.ClearDeadCrops && dirt.crop.dead) { return(this.UseToolOnTile(tool, tile)); } if (this.Config.ClearLiveCrops && !dirt.crop.dead) { return(this.UseToolOnTile(tool, tile)); } break; } // clear stumps // This needs to check if the axe upgrade level is high enough first, to avoid spamming // 'need to upgrade your tool' messages. Based on ResourceClump.performToolAction. if (this.Config.ClearDebris) { ResourceClump clump = this.GetResourceClumpCoveringTile(location, tile); if (clump != null && this.ResourceUpgradeLevelsNeeded.ContainsKey(clump.parentSheetIndex) && tool.upgradeLevel >= this.ResourceUpgradeLevelsNeeded[clump.parentSheetIndex]) { this.UseToolOnTile(tool, tile); } } return(false); }
public override bool performToolAction(Tool t, int tileX, int tileY) { if (log != null && log.getBoundingBox(log.tile).Contains(tileX * 64, tileY * 64)) { if (log.performToolAction(t, 1, log.tile, this)) { log = null; } return(true); } return(base.performToolAction(t, tileX, tileY)); }
public override bool performToolAction(Tool t, int tileX, int tileY) { if (this.log == null || !this.log.getBoundingBox(this.log.tile).Contains(tileX * Game1.tileSize, tileY * Game1.tileSize)) { return(base.performToolAction(t, tileX, tileY)); } if (this.log.performToolAction(t, 1, this.log.tile, (GameLocation)null)) { this.log = (ResourceClump)null; } return(true); }
private void ClearResourceClump(IList <ResourceClump> input, Vector2 tile) { for (int i = 0; i < input.Count; i++) { ResourceClump RC = input[i]; if (RC.tile.Value == tile) { input.RemoveAt(i); i--; } } }
public override bool performToolAction(Tool t, int tileX, int tileY) { if (this.log != null && this.log.getBoundingBox(this.log.tile).Contains(tileX * Game1.tileSize, tileY * Game1.tileSize)) { if (this.log.performToolAction(t, 1, this.log.tile, null)) { this.log = null; } return(true); } return(base.performToolAction(t, tileX, tileY)); }
/// <summary>Apply the tool to the given tile.</summary> /// <param name="tile">The tile to modify.</param> /// <param name="tileObj">The object on the tile.</param> /// <param name="tileFeature">The feature on the tile.</param> /// <param name="player">The current player.</param> /// <param name="tool">The tool selected by the player (if any).</param> /// <param name="item">The item selected by the player (if any).</param> /// <param name="location">The current location.</param> public override bool Apply(Vector2 tile, SObject tileObj, TerrainFeature tileFeature, SFarmer player, Tool tool, Item item, GameLocation location) { // break stones if (tileObj?.Name == "Stone") { return(this.UseToolOnTile(tool, tile)); } // break flooring & paths if (tileFeature is Flooring) { return(this.BreakFlooring && this.UseToolOnTile(tool, tile)); } // handle dirt if (tileFeature is HoeDirt dirt) { // clear tilled dirt if (dirt.crop == null) { return(this.ClearDirt && this.UseToolOnTile(tool, tile)); } // clear dead crops if (dirt.crop?.dead == true) { return(this.UseToolOnTile(tool, tile)); } } // clear boulders / meteorites // This needs to check if the axe upgrade level is high enough first, to avoid spamming // 'need to upgrade your tool' messages. Based on ResourceClump.performToolAction. { Rectangle tileArea = this.GetAbsoluteTileArea(tile); ResourceClump stump = ( from clump in this.GetResourceClumps(location) where clump.getBoundingBox(clump.tile).Intersects(tileArea) && this.ResourceUpgradeLevelsNeeded.ContainsKey(clump.parentSheetIndex) && tool.upgradeLevel >= this.ResourceUpgradeLevelsNeeded[clump.parentSheetIndex] select clump ) .FirstOrDefault(); if (stump != null) { this.UseToolOnTile(tool, tile); } } return(false); }
static void ClearResourceClump(IList <ResourceClump> input, Vector2 RCLocation) { for (int i = 0; i < input.Count; i++) { ResourceClump RC = input[i]; if (RC.tile.Value == RCLocation) { input.RemoveAt(i); i--; } } }
public static bool BreakStump(Player player, Rectangle bb, ResourceClump clump) { if (CanBreakBigObject(player, bb, clump)) { clump.health = 0; clump.performToolAction(player.CurrentTool, 1, clump.tile, player.currentLocation); return(true); } else { return(false); } }
public static void ResourceClump_performToolAction_Postfix(ResourceClump __instance, Tool t) { if (__instance.health.Value <= 0f) { if (__instance.parentSheetIndex.Value is 672 or 752 or 754 or 756 or 758) { if (t is not null && t.getLastFarmerToUse() is not null) { t.getLastFarmerToUse().stats.BouldersCracked++; } } } }
private void onClumpRemoved(ResourceClump value) { if (value.parentSheetIndex == ResourceClump.meteoriteIndex) { Random r = new Random((int)value.tile.X * 1000 + (int)value.tile.Y); Game1.createMultipleObjectDebris(StardewValley.Object.stone, (int)value.tile.X, (int)value.tile.Y, 75 + r.Next(175)); Game1.createMultipleObjectDebris(StardewValley.Object.coal, (int)value.tile.X, (int)value.tile.Y, 20 + r.Next(55)); Game1.createMultipleObjectDebris(StardewValley.Object.iridium, (int)value.tile.X, (int)value.tile.Y, 50 + r.Next(100)); Game1.createMultipleObjectDebris(535, (int)value.tile.X, (int)value.tile.Y, 7 + r.Next(15)); Game1.createMultipleObjectDebris(536, (int)value.tile.X, (int)value.tile.Y, 7 + r.Next(15)); Game1.createMultipleObjectDebris(537, (int)value.tile.X, (int)value.tile.Y, 7 + r.Next(15)); Game1.createMultipleObjectDebris(749, (int)value.tile.X, (int)value.tile.Y, 3 + r.Next(9)); } }
/// <summary>Apply the tool to the given tile.</summary> /// <param name="tile">The tile to modify.</param> /// <param name="tileObj">The object on the tile.</param> /// <param name="tileFeature">The feature on the tile.</param> /// <param name="player">The current player.</param> /// <param name="tool">The tool selected by the player (if any).</param> /// <param name="item">The item selected by the player (if any).</param> /// <param name="location">The current location.</param> public override bool Apply(Vector2 tile, SObject tileObj, TerrainFeature tileFeature, SFarmer player, Tool tool, Item item, GameLocation location) { // clear twigs if (tileObj?.Name == "Twig") { return(this.UseToolOnTile(tool, tile)); } // cut non-fruit tree if (tileFeature is Tree) { return(this.CutTrees && this.UseToolOnTile(tool, tile)); } // cut fruit tree if (tileFeature is FruitTree) { return(this.CutFruitTrees && this.UseToolOnTile(tool, tile)); } // clear crops if (tileFeature is HoeDirt dirt && dirt.crop != null && (dirt.crop.dead || this.ClearCrops)) { return(this.UseToolOnTile(tool, tile)); } // clear stumps // This needs to check if the axe upgrade level is high enough first, to avoid spamming // 'need to upgrade your tool' messages. Based on ResourceClump.performToolAction. { Rectangle tileArea = this.GetAbsoluteTileArea(tile); ResourceClump stump = ( from clump in this.GetResourceClumps(location) where clump.getBoundingBox(clump.tile).Intersects(tileArea) && this.ResourceUpgradeLevelsNeeded.ContainsKey(clump.parentSheetIndex) && tool.upgradeLevel >= this.ResourceUpgradeLevelsNeeded[clump.parentSheetIndex] select clump ) .FirstOrDefault(); if (stump != null) { this.UseToolOnTile(tool, tile); } } return(false); }
public static void Prefix(ResourceClump __instance, Tool t) { if (t.UpgradeLevel != 6) // Mythicite { return; } int[] axeIds = new int[] { 600, 602 }; int[] pickaxeIds = new int[] { 622, 672, 752, 754, 756, 758 }; if (t is Axe && axeIds.Contains(__instance.parentSheetIndex.Value) || t is Pickaxe && pickaxeIds.Contains(__instance.parentSheetIndex.Value)) { __instance.health.Value = 0; } }
public static bool performToolAction(ref ResourceClump __instance, ref Tool t, ref int damage, ref Vector2 tileLocation, ref GameLocation location) { ResourceClump rc = __instance; //Start checking ParentSheetIndexes for the ResourceClumps if (rc.health.Value > 0.0) { return(true); } if (rc.parentSheetIndex.Value == 600) { } //Everything else failed. The original Method runs. return(true); }
public static bool performToolAction_Prefix(ref ResourceClump __instance, Tool t, int damage, Vector2 tileLocation, GameLocation location, ref bool __result) { // Gotta have the original method available for mattock stand-ins. if (performToolActionOriginal == null) { return(true); } // If the tool is a mattock and this object is one that requires a specific type of tool that is supported, // run the function with a stand-in tool instead. if (t is Mattock mattock && !mattock.struckFeatures.Contains(__instance)) { switch (__instance.parentSheetIndex.Get()) { case 600: // Stump case 602: // Log { // Treat the mattock as an axe for stumps. Axe standinAxe = mattock.asAxe(); mattock.struckFeatures.Add(__instance); __result = (bool)performToolActionOriginal.Invoke(__instance, new object[] { __instance, standinAxe, damage, tileLocation, location }); return(false); } case 622: // Iridium meteorite case 672: // Boulder 1 case 752: // Boulder 2 case 754: // Boulder 3 case 756: // Icy Boulder 1 case 758: // Icy Boulder 2 { // Treat the mattock as a pickaxe for boulders. Pickaxe standinPickaxe = mattock.asPickaxe(); mattock.struckFeatures.Add(__instance); //standinPickaxe.DoFunction(location, (int)(__instance.currentTileLocation.X * 64), (int)(__instance.currentTileLocation.Y * 64), 1, Game1.player); __result = (bool)performToolActionOriginal.Invoke(__instance, new object[] { __instance, standinPickaxe, damage, tileLocation, location }); return(false); } } } // Otherwise, just do the default functionality. return(true); }