private void CheckForSkillUpdates(Netcode.NetArray <int, Netcode.NetInt> newExp) { for (int skillIndex = 0; skillIndex < newExp.Length; skillIndex++) { int diff = newExp[skillIndex] - lastExp[skillIndex]; if (diff != 0) { HandleSkillGain(skillIndex, diff, newExp[skillIndex]); lastExp[skillIndex] = newExp[skillIndex]; } } }
/// <summary> /// Update the player's addedSpeed value based on existing buffs and the player's total level /// </summary> private void UpdatePlayerSpeed() { // Grab farmer to reduce typing Farmer player = Game1.player; // Calculate the "base" buff from our player's total level (5-50) // At total level 0, we should have no extra buff, but at 50 we should max out int totalLevel = player.FarmingLevel + player.MiningLevel + player.FishingLevel + player.ForagingLevel + player.CombatLevel; float baseBuff = this.speedScale * totalLevel / 50; float addedSpeed = baseBuff; // Calculate multiplier for existing buffs and horse. If player is going 2x speed, buffs should too float mult = (baseBuff + 5) / 5; // Check applied speed buff (private field) Netcode.NetArray <int, Netcode.NetInt> appliedBuffs = this.Helper.Reflection.GetField <Netcode.NetArray <int, Netcode.NetInt> >(player, "appliedBuffs").GetValue(); int appliedSpeedBuff = appliedBuffs[9]; // Add it to our sum, scaled by the multplier addedSpeed += appliedSpeedBuff * mult; // Check horse state, and add it based on our multiplier if (player.isRidingHorse()) { addedSpeed += 5 * mult; this.lastWasRiding = true; } else { this.lastWasRiding = false; } // Decide what to set (don't add speed if walking) int addedSpeedToUse; if (player.running || player.isRidingHorse()) { addedSpeedToUse = (int)addedSpeed; this.wasWalking = false; } else { addedSpeedToUse = appliedSpeedBuff; this.wasWalking = true; } player.addedSpeed = addedSpeedToUse; this.lastAddedSpeed = addedSpeedToUse; }
//this was almost entirely stolen from spacechase0 with very little contribution on my part. internal static void HandleToolTransmute(Tool tool) { int alchemyLevel = (EquivalentExchange.IsShiftKeyPressed() ? 0 : Alchemy.GetToolTransmuteRadius()); int toolLevel = tool.UpgradeLevel; //set last user to dodge a null pointer var toolPlayerFieldReflector = tool.GetType().GetField("lastUser", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); toolPlayerFieldReflector.SetValue(tool, Game1.player); Point hitLocation = GetMouseHitLocation(); GameLocation location = Game1.player.currentLocation; bool performedAction = false; //getting this out of the way, helps with easily determining tool types bool isScythe = tool is MeleeWeapon && tool.Name.ToLower().Contains("scythe"); bool isAxe = tool is StardewValley.Tools.Axe; bool isPickaxe = tool is StardewValley.Tools.Pickaxe; bool isHoe = tool is StardewValley.Tools.Hoe; bool isWateringCan = tool is StardewValley.Tools.WateringCan; for (int xOffset = -alchemyLevel; xOffset <= alchemyLevel; xOffset++) { for (int yOffset = -alchemyLevel; yOffset <= alchemyLevel; yOffset++) { if (!isScythe) { if (!IsCapableOfWithstandingToolTransmuteCost(Game1.player, 2F)) { return; } } Vector2 offsetPosition = new Vector2(xOffset + hitLocation.X, yOffset + hitLocation.Y); if (location.objects.ContainsKey(offsetPosition)) { if (isAxe || isScythe || isPickaxe || isHoe) { var snapshotPlayerExperience = Game1.player.experiencePoints; performedAction = DoToolFunction(location, Game1.player, tool, (int)offsetPosition.X, (int)offsetPosition.Y); RestorePlayerExperience(snapshotPlayerExperience); if (performedAction && !isScythe) { HandleToolTransmuteConsequence(2F); } } } else if (location.terrainFeatures.ContainsKey(offsetPosition)) { //a terrain feature, rather than a tool check, might respond to the tool TerrainFeature terrainFeature = location.terrainFeatures[offsetPosition]; //don't break stumps unless the player is in precision mode. if (terrainFeature is Tree && isAxe && (!(terrainFeature as Tree).stump || EquivalentExchange.IsShiftKeyPressed())) { Netcode.NetArray <int, Netcode.NetInt> snapshotPlayerExperience = Game1.player.experiencePoints; //trees get removed automatically performedAction = DoToolFunction(location, Game1.player, tool, (int)offsetPosition.X, (int)offsetPosition.Y); RestorePlayerExperience(snapshotPlayerExperience); if (performedAction) { HandleToolTransmuteConsequence(2F); } } else if (terrainFeature is Grass && location is Farm && isScythe) { int oldHay = (location as Farm).piecesOfHay; var snapshotPlayerExperience = Game1.player.experiencePoints; if (terrainFeature.performToolAction(tool, 0, offsetPosition, location)) { location.terrainFeatures.Remove(offsetPosition); //HandleToolTransmuteConsequence(); Scythe transmute is special and doesn't cost anything, but you don't get experience. performedAction = true; } RestorePlayerExperience(snapshotPlayerExperience); //hay get! spawn the sprite animation for acquisition of hay if (oldHay < (location as Farm).piecesOfHay) { SpawnHayAnimationSprite(location, offsetPosition, Game1.player); } } else if (terrainFeature is HoeDirt && isWateringCan && (tool as WateringCan).WaterLeft > 0) { //state of 0 is unwatered. if ((terrainFeature as HoeDirt).state != 1) { var snapshotPlayerExperience = Game1.player.experiencePoints; terrainFeature.performToolAction(tool, 0, offsetPosition, location); RestorePlayerExperience(snapshotPlayerExperience); (tool as WateringCan).WaterLeft = (tool as WateringCan).WaterLeft - 1; SpawnWateringCanAnimationSprite(location, offsetPosition); HandleToolTransmuteConsequence(2F); performedAction = true; } } else if (isPickaxe && terrainFeature is HoeDirt) { var snapshotPlayerExperience = Game1.player.experiencePoints; performedAction = DoToolFunction(location, Game1.player, tool, (int)offsetPosition.X, (int)offsetPosition.Y); RestorePlayerExperience(snapshotPlayerExperience); if (performedAction) { HandleToolTransmuteConsequence(2F); } } } else if ((isPickaxe || isAxe)) { ICollection <ResourceClump> largeResourceClusters = null; if (location is Farm) { largeResourceClusters = (NetCollection <ResourceClump>)location.GetType().GetField("resourceClumps", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).GetValue(location); } else if (location is MineShaft) { largeResourceClusters = (NetObjectList <ResourceClump>)location.GetType().GetField("resourceClumps", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).GetValue(location); } else if (location is Woods) { largeResourceClusters = (location as Woods).stumps; } DoLargeResourceClusterAction(largeResourceClusters, tool, offsetPosition, performedAction); } else if (isHoe) { var snapshotPlayerExperience = Game1.player.experiencePoints; performedAction = DoToolFunction(location, Game1.player, tool, (int)offsetPosition.X, (int)offsetPosition.Y); RestorePlayerExperience(snapshotPlayerExperience); if (performedAction) { HandleToolTransmuteConsequence(2F); } } } } if (performedAction) { SoundUtil.PlayMagickySound(); } }