Пример #1
0
 public static int GetToolTransmuteRadius()
 {
     if (EquivalentExchange.IsShiftKeyPressed())
     {
         return(0);
     }
     return(Util.GetAlchemyPowerLevel(EquivalentExchange.AlchemyLevel) - 1);
 }
Пример #2
0
        //handles all the things.
        public override void Entry(IModHelper helper)
        {
            //set the static instance variable. is this an oxymoron?
            instance = this;

            //preserve this entry method's helper class because it's.. helpful.
            instance.eeHelper = helper;

            //read the config file, poached from horse whistles, get the configured keys and settings
            Config = helper.ReadConfig <ConfigurationModel>();

            //add handler for the "transmute/copy" button.
            ControlEvents.KeyPressed += ControlEvents_KeyPressed;

            //exclusively to figure out if ctrl or shift have been let go of.
            ControlEvents.KeyReleased += ControlEvents_KeyReleased;

            //wire up the library scraping function to occur on save-loading to defer recipe scraping until all mods are loaded, optimistically.
            SaveEvents.AfterLoad += SaveEvents_AfterLoad;

            //we need this to save our alchemists['] data
            SaveEvents.BeforeSave += SaveEvents_BeforeSave;

            //set texture files in memory, they're tiny things.
            DrawingUtil.HandleTextureCaching();

            //trying something completely different from a patched event hook...
            //gonna try using this to detect the night event heuristically.
            GameEvents.UpdateTick += GameEvents_UpdateTick;

            //wire up the PreRenderHUD event so I can display info bubbles when needed
            GraphicsEvents.OnPreRenderHudEvent += GraphicsEvents_OnPreRenderHudEvent;

            //check for experience bars mod: if it's here we draw hud elements for the new alchemy skill
            CheckForExperienceBarsMod();
            if (hasExperienceBarsMod)
            {
                GraphicsEvents.OnPostRenderHudEvent += GraphicsEvents_OnPostRenderHudEvent;
            }

            //check for all professions mod: if it's here we run a wireup to give the player all skills professions at the right time (or after), when present.
            CheckForAllProfessionsMod();
            if (hasAllProfessionsMod)
            {
                LocationEvents.CurrentLocationChanged += LocationEvents_CurrentLocationChanged;;
            }

            //add a debug option to give yourself experience
            Helper.ConsoleCommands.Add("player_givealchemyexp", "player_givealchemyexp <amount>", GiveAlchemyExperience);

            //post render event for skills menu
            GraphicsEvents.OnPostRenderGuiEvent += DrawAfterGUI;

            //check for chase's skills
            checkForLuck();
            checkForCooking();
        }
        //handles all the things.
        public override void Entry(IModHelper helper)
        {
            //set the static instance variable. is this an oxymoron?
            instance = this;

            //read the config file, poached from horse whistles, get the configured keys and settings
            Config = helper.ReadConfig <ConfigurationModel>();

            //add handler for the "transmute/copy" button.
            ControlEvents.KeyPressed += ControlEvents_KeyPressed;

            //exclusively to figure out if ctrl or shift have been let go of.
            ControlEvents.KeyReleased += ControlEvents_KeyReleased;

            //wire up the library scraping function to occur on save-loading to defer recipe scraping until all mods are loaded, optimistically.
            SaveEvents.AfterLoad += SaveEvents_AfterLoad;

            //we need this to save our alchemists['] data
            SaveEvents.BeforeSave += SaveEvents_BeforeSave;

            //set texture files in memory, they're tiny things.
            DrawingUtil.HandleTextureCaching();

            //handles high resolution update ticks, like regeneration and held keys.
            GameEvents.UpdateTick += GameEvents_UpdateTick;

            //wire up the PreRenderHUD event so I can display info bubbles when needed
            GraphicsEvents.OnPreRenderHudEvent += GraphicsEvents_OnPreRenderHudEvent;

            // handles end of night event requirements like alchemy energy being restored and level ups.
            SpaceEvents.ShowNightEndMenus += SpaceEvents_ShowNightEndMenus;

            // stuff we have to do for multiplayer now, handles client join events to cascade data to the non-hosts.
            SpaceEvents.ServerGotClient += SpaceEvents_ServerGotClient;

            // handle looking out for the slime gift to the wizard that gates the alchemy content
            SpaceEvents.AfterGiftGiven += SpaceEvents_AfterGiftGiven;

            Networking.RegisterMessageHandler(MSG_DATA, OnDataMessage);
            Networking.RegisterMessageHandler(MSG_EXPERIENCE, OnExpMessage);
            Networking.RegisterMessageHandler(MSG_LEVEL, OnLevelMessage);
            Networking.RegisterMessageHandler(MSG_CURRENT_ENERGY, OnCurrentEnergyMessage);
            Networking.RegisterMessageHandler(MSG_MAX_ENERGY, OnMaxEnergyMessage);
            Networking.RegisterMessageHandler(MSG_TOTAL_VALUE_TRANSMUTED, OnTransmutedValueMessage);
            Networking.RegisterMessageHandler(MSG_REGEN_TICK, OnRegenTick);
            Networking.RegisterMessageHandler(MSG_IS_SLIME_GIVEN_TO_WIZARD, OnSlimeGivenToWizardMessage);

            Skills.RegisterSkill(skill = new AlchemySkill());
        }
Пример #4
0
        public static bool HandleTransmuteEvent(Item heldItem, int actualValue)
        {
            // if the recipes list doesn't contain the item you're holding, you can't transmute that.
            var recipes = EquivalentExchange.GetTransmutationFormulas();

            // sorted recipe list
            var validRecipes = recipes.GetRecipesForOutput(heldItem.parentSheetIndex);

            if (validRecipes.Count == 0)
            {
                return(true);
            }

            // use more sorting magic to find a potential recipe from the player's inventory
            // prioritize the recipes by their input costs (cheapest inputs are prioritized by the function GetRecipesForOutput)
            var optimalRecipe = validRecipes.FindBestRecipe(Game1.player);

            // something has stopped us from finding a valid recipe. The player either doesn't have the necessary items
            // or doesn't have the energy to do the transmutation.
            if (optimalRecipe == null)
            {
                return(true);
            }

            var breakRepeaterLoop = false;

            Alchemy.HandleAlchemyEnergyDeduction(optimalRecipe.GetEnergyCost(), false);

            if (optimalRecipe.GetEnergyCost() > EquivalentExchange.CurrentEnergy)
            {
                breakRepeaterLoop = true;
            }

            Alchemy.IncreaseTotalTransmuteValue((int)Math.Floor(Math.Max(1D, optimalRecipe.GetEnergyCost())));

            Util.TakeItemFromPlayer(optimalRecipe.InputId, optimalRecipe.GetInputCost(), Game1.player);

            Item spawnedItem = heldItem.getOne();

            spawnedItem.Stack = optimalRecipe.GetOutputQuantity();

            Util.GiveItemToPlayer((StardewValley.Object)spawnedItem, Game1.player);

            SoundUtil.PlayMagickySound();

            return(breakRepeaterLoop);
        }
Пример #5
0
        //handles draining energy/stamina on successful transmute
        public static void HandleAlchemyEnergyDeduction(double energyCost, bool isForcedStaminaDrain)
        {
            double remainingStaminaCost = energyCost;

            // if the stamina drain is "forced" it means you can't pay for this transaction with energy
            // the *entire* cost goes to stamina.
            if (!isForcedStaminaDrain)
            {
                //if you have any alkahestry energy, it will try to use as much as it can
                double alkahestryCost = (double)Math.Min(EquivalentExchange.CurrentEnergy, energyCost);

                //and deduct that from whatever stamina cost might be left over (which may be all of it)
                remainingStaminaCost -= alkahestryCost;

                Alchemy.ReduceAlkahestryEnergy(alkahestryCost);
            }
            Game1.player.Stamina -= (float)remainingStaminaCost;
            EquivalentExchange.AddAlchemyExperience((int)Math.Floor(Math.Max(energyCost, 1D)));
        }
Пример #6
0
        public static void CleanDeprecatedProfessions()
        {
            foreach (var deprecatedProfession in DeprecatedProfessionIntegers)
            {
                if (EquivalentExchange.HasProfession(deprecatedProfession))
                {
                    Game1.player.professions.Remove(deprecatedProfession);
                    switch (deprecatedProfession)
                    {
                    case OldShaperId:
                        Game1.player.professions.Add(AlchemySkill.ProfessionShaper.GetVanillaId());
                        break;

                    case OldSageId:
                        Game1.player.professions.Add(AlchemySkill.ProfessionSage.GetVanillaId());
                        break;

                    case OldTransmuterId:
                        Game1.player.professions.Add(AlchemySkill.ProfessionTransmuter.GetVanillaId());
                        break;

                    case OldAdeptId:
                        Game1.player.professions.Add(AlchemySkill.ProfessionAdept.GetVanillaId());
                        break;

                    case OldAurumancerId:
                        Game1.player.professions.Add(AlchemySkill.ProfessionAurumancer.GetVanillaId());
                        break;

                    case OldConduitId:
                        Game1.player.professions.Add(AlchemySkill.ProfessionConduit.GetVanillaId());
                        break;
                    }
                }
            }
        }
Пример #7
0
        private static bool DoToolFunction(GameLocation location, StardewValley.Farmer who, Tool tool, int x, int y)
        {
            bool    performedAction = false;
            Vector2 index           = new Vector2(x, y);
            Vector2 vector2         = new Vector2((float)(x + 0.5), (float)(y + 0.5));

            if (tool is MeleeWeapon && tool.Name.ToLower().Contains("scythe"))
            {
                var snapshotPlayerExperience = Game1.player.experiencePoints;
                if (location.objects[index] != null)
                {
                    StardewValley.Object hitObject = location.objects[index];
                    if (hitObject.name.Contains("Weed") && hitObject.performToolAction(tool, location))
                    {
                        if (hitObject.type == "Crafting" && hitObject.fragility != 2)
                        {
                            location.debris.Add(new Debris(hitObject.bigCraftable ? -hitObject.parentSheetIndex : hitObject.parentSheetIndex, index, index));
                        }
                        hitObject.performRemoveAction(index, location);
                        location.objects.Remove(index);
                        performedAction = true;
                    }
                }
                else if (location.terrainFeatures.ContainsKey(index) && location.terrainFeatures[index].performToolAction(tool, 0, index, (GameLocation)null))
                {
                    location.terrainFeatures.Remove(index);
                    performedAction = true;
                }
                RestorePlayerExperience(snapshotPlayerExperience);
            }
            else if (tool is Axe)
            {
                var       snapshotPlayerExperience = Game1.player.experiencePoints;
                Rectangle rectangle = new Rectangle(x * Game1.tileSize, y * Game1.tileSize, Game1.tileSize, Game1.tileSize);
                location.performToolAction(tool, x, y);
                if (location.terrainFeatures.ContainsKey(index) && location.terrainFeatures[index].performToolAction(tool, 0, index, (GameLocation)null))
                {
                    location.terrainFeatures.Remove(index);
                    performedAction = true;
                }
                Rectangle boundingBox;
                if (location.largeTerrainFeatures != null)
                {
                    for (int index2 = location.largeTerrainFeatures.Count - 1; index2 >= 0; --index2)
                    {
                        boundingBox = location.largeTerrainFeatures[index2].getBoundingBox();
                        if (boundingBox.Intersects(rectangle) && location.largeTerrainFeatures[index2].performToolAction(tool, 0, index, (GameLocation)null))
                        {
                            location.largeTerrainFeatures.RemoveAt(index2);
                        }
                    }
                }
                if (location.terrainFeatures.ContainsKey(index) && location.terrainFeatures[index] is Tree)
                {
                    if (!(location.terrainFeatures[index] as Tree).stump || EquivalentExchange.IsShiftKeyPressed())
                    {
                        performedAction = true;
                    }
                }
                if (!location.Objects.ContainsKey(index) || location.Objects[index].Type == null || !location.Objects[index].performToolAction(tool, location))
                {
                    return(performedAction);
                }
                if (location.Objects[index].type.Equals("Crafting") && location.Objects[index].fragility != 2)
                {
                    var    debris1     = location.debris;
                    int    objectIndex = location.Objects[index].bigCraftable ? -location.Objects[index].ParentSheetIndex : location.Objects[index].ParentSheetIndex;
                    Debris debris2     = new Debris(objectIndex, index, index);
                    debris1.Add(debris2);
                }
                location.Objects[index].performRemoveAction(index, location);
                location.Objects.Remove(index);
                performedAction = true;
                RestorePlayerExperience(snapshotPlayerExperience);
            }
            else if (tool is Pickaxe)
            {
                var snapshotPlayerExperience = Game1.player.experiencePoints;
                int power = who.toolPower;
                if (location.performToolAction(tool, x, y))
                {
                    return(true);
                }
                StardewValley.Object objectHit = (StardewValley.Object)null;
                location.Objects.TryGetValue(index, out objectHit);
                if (objectHit == null)
                {
                    if (location.terrainFeatures.ContainsKey(index) && location.terrainFeatures[index].performToolAction(tool, 0, index, (GameLocation)null))
                    {
                        location.terrainFeatures.Remove(index);
                        performedAction = true;
                    }
                }

                if (objectHit != null)
                {
                    if (objectHit.Name.Equals("Stone"))
                    {
                        Game1.playSound("hammer");
                        if (objectHit.minutesUntilReady > 0)
                        {
                            int num3 = Math.Max(1, tool.upgradeLevel + 1);
                            objectHit.minutesUntilReady.Set(objectHit.minutesUntilReady - num3);
                            objectHit.shakeTimer = 200;
                            if (objectHit.minutesUntilReady > 0)
                            {
                                Game1.createRadialDebris(Game1.currentLocation, 14, x, y, Game1.random.Next(2, 5), false, -1, false, -1);
                                return(performedAction);
                            }
                        }
                        if (objectHit.ParentSheetIndex < 200 && !Game1.objectInformation.ContainsKey(objectHit.ParentSheetIndex + 1))
                        {
                            location.TemporarySprites.Add(new TemporaryAnimatedSprite(objectHit.ParentSheetIndex + 1, 300f, 1, 2, new Vector2((float)(x) * Game1.tileSize, (float)(y) * Game1.tileSize), true, objectHit.flipped)
                            {
                                alphaFade = 0.01f
                            });
                        }
                        else
                        {
                            location.TemporarySprites.Add(new TemporaryAnimatedSprite(47, new Vector2((float)(x * Game1.tileSize), (float)(y * Game1.tileSize)), Color.Gray, 10, false, 80f, 0, -1, -1f, -1, 0));
                        }
                        Game1.createRadialDebris(location, 14, x, y, Game1.random.Next(2, 5), false, -1, false, -1);
                        location.TemporarySprites.Add(new TemporaryAnimatedSprite(46, new Vector2((float)(x * Game1.tileSize), (float)(y * Game1.tileSize)), Color.White, 10, false, 80f, 0, -1, -1f, -1, 0)
                        {
                            motion       = new Vector2(0.0f, -0.6f),
                            acceleration = new Vector2(0.0f, 1f / 500f),
                            alphaFade    = 0.015f
                        });
                        if (!location.Name.StartsWith("UndergroundMine"))
                        {
                            if (objectHit.parentSheetIndex == 343 || objectHit.parentSheetIndex == 450)
                            {
                                Random random = new Random((int)Game1.stats.DaysPlayed + (int)Game1.uniqueIDForThisGame / 2 + x * 2000 + y);
                                if (random.NextDouble() < 0.035 && Game1.stats.DaysPlayed > 1U)
                                {
                                    Game1.createObjectDebris(535 + (Game1.stats.DaysPlayed <= 60U || random.NextDouble() >= 0.2 ? (Game1.stats.DaysPlayed <= 120U || random.NextDouble() >= 0.2 ? 0 : 2) : 1), x, y, tool.getLastFarmerToUse().uniqueMultiplayerID);
                                }
                                if (random.NextDouble() < 0.035 * (who.professions.Contains(21) ? 2.0 : 1.0) && Game1.stats.DaysPlayed > 1U)
                                {
                                    Game1.createObjectDebris(382, x, y, tool.getLastFarmerToUse().uniqueMultiplayerID);
                                }
                                if (random.NextDouble() < 0.01 && Game1.stats.DaysPlayed > 1U)
                                {
                                    Game1.createObjectDebris(390, x, y, tool.getLastFarmerToUse().uniqueMultiplayerID);
                                }
                            }
                            location.breakStone(objectHit.parentSheetIndex, x, y, who, new Random((int)Game1.stats.DaysPlayed + (int)Game1.uniqueIDForThisGame / 2 + x * 4000 + y));
                        }
                        else
                        {
                            Game1.mine.checkStoneForItems(objectHit.ParentSheetIndex, x, y, who);
                        }
                        if (objectHit.minutesUntilReady > 0)
                        {
                            return(performedAction);
                        }
                        location.Objects.Remove(index);
                        Game1.playSound("stoneCrack");
                        performedAction = true;
                    }
                    else
                    {
                        if (!objectHit.performToolAction(tool, location))
                        {
                            return(performedAction);
                        }
                        objectHit.performRemoveAction(index, location);
                        if (objectHit.type.Equals("Crafting") && objectHit.fragility != 2)
                        {
                            var       debris1      = Game1.currentLocation.debris;
                            int       objectIndex  = objectHit.bigCraftable ? -objectHit.ParentSheetIndex : objectHit.ParentSheetIndex;
                            Vector2   toolLocation = who.GetToolLocation(false);
                            Rectangle boundingBox  = who.GetBoundingBox();
                            double    x1           = (double)boundingBox.Center.X;
                            boundingBox = who.GetBoundingBox();
                            double  y1             = (double)boundingBox.Center.Y;
                            Vector2 playerPosition = new Vector2((float)x1, (float)y1);
                            Debris  debris2        = new Debris(objectIndex, toolLocation, playerPosition);
                            debris1.Add(debris2);
                        }
                        Game1.currentLocation.Objects.Remove(index);
                        performedAction = true;
                    }
                    RestorePlayerExperience(snapshotPlayerExperience);
                }
                else
                {
                    Game1.playSound("woodyHit");
                    if (location.doesTileHaveProperty(x, y, "Diggable", "Back") == null)
                    {
                        return(false);
                    }
                    location.TemporarySprites.Add(new TemporaryAnimatedSprite(12, new Vector2((float)(x * Game1.tileSize), (float)(y * Game1.tileSize)), Color.White, 8, false, 80f, 0, -1, -1f, -1, 0)
                    {
                        alphaFade = 0.015f
                    });
                }
            }
            else if (tool is Hoe)
            {
                var snapshotPlayerExperience = Game1.player.experiencePoints;
                if (location.terrainFeatures.ContainsKey(index))
                {
                    if (location.terrainFeatures[index].performToolAction(tool, 0, index, (GameLocation)null))
                    {
                        location.terrainFeatures.Remove(index);
                        performedAction = true;
                    }
                }
                else
                {
                    if (location.objects.ContainsKey(index) && location.Objects[index].performToolAction(tool, location))
                    {
                        if (location.Objects[index].type.Equals("Crafting") && location.Objects[index].fragility != 2)
                        {
                            var     debris1      = location.debris;
                            int     objectIndex  = location.Objects[index].bigCraftable ? -location.Objects[index].ParentSheetIndex : location.Objects[index].ParentSheetIndex;
                            Vector2 toolLocation = who.GetToolLocation(false);
                            Microsoft.Xna.Framework.Rectangle boundingBox = who.GetBoundingBox();
                            double x1 = (double)boundingBox.Center.X;
                            boundingBox = who.GetBoundingBox();
                            double  y1             = (double)boundingBox.Center.Y;
                            Vector2 playerPosition = new Vector2((float)x1, (float)y1);
                            Debris  debris2        = new Debris(objectIndex, toolLocation, playerPosition);
                            debris1.Add(debris2);
                        }
                        location.Objects[index].performRemoveAction(index, location);
                        location.Objects.Remove(index);
                        performedAction = true;
                    }
                    if (location.doesTileHaveProperty((int)index.X, (int)index.Y, "Diggable", "Back") != null)
                    {
                        if (location.Name.Equals("UndergroundMine") && !location.isTileOccupied(index, ""))
                        {
                            location.terrainFeatures.Add(index, (TerrainFeature) new HoeDirt());
                            performedAction = true;
                            Game1.removeSquareDebrisFromTile((int)index.X, (int)index.Y);
                            location.checkForBuriedItem((int)index.X, (int)index.Y, false, false);
                            location.temporarySprites.Add(new TemporaryAnimatedSprite(12, new Vector2(vector2.X * (float)Game1.tileSize, vector2.Y * (float)Game1.tileSize), Color.White, 8, Game1.random.NextDouble() < 0.5, 50f, 0, -1, -1f, -1, 0));
                        }
                        else if (!location.isTileOccupied(index, "") && location.isTilePassable(new xTile.Dimensions.Location((int)index.X, (int)index.Y), Game1.viewport))
                        {
                            location.makeHoeDirt(index);
                            performedAction = true;
                            Game1.removeSquareDebrisFromTile((int)index.X, (int)index.Y);
                            location.temporarySprites.Add(new TemporaryAnimatedSprite(12, new Vector2(index.X * (float)Game1.tileSize, index.Y * (float)Game1.tileSize), Color.White, 8, Game1.random.NextDouble() < 0.5, 50f, 0, -1, -1f, -1, 0));
                            location.checkForBuriedItem((int)index.X, (int)index.Y, false, false);
                        }
                    }
                }
                RestorePlayerExperience(snapshotPlayerExperience);
            }
            return(performedAction);
        }
Пример #8
0
        //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();
            }
        }
Пример #9
0
 public static void IncreaseTotalTransmuteValue(int transmuteValue)
 {
     EquivalentExchange.AddTotalValueTransmuted(transmuteValue);
 }
Пример #10
0
        public static void HandleLiquidateEvent(Item heldItem, int actualValue)
        {
            //if the player is holding only one item, don't let them transmute it to money unless they're holding shift.
            if (heldItem.Stack == 1 && !EquivalentExchange.IsShiftKeyPressed())
            {
                return;
            }

            //placeholder for determining if the transmute occurs, so it knows to play a sound.
            bool didTransmuteOccur = false;

            //placeholder for determining if the transmute rebounds, so it knows to play a different sound.
            bool didTransmuteFail = false;

            //if the transmute did fail, this preserves the damage so we can apply it in one cycle, otherwise batches look weird af
            int reboundDamageTaken = 0;

            //needed for some profession effects
            bool isItemWorthLessThanOnePercentOfMoney = (Game1.player.money * 0.01F > actualValue);

            //stamina cost is overridden for conduits if money is > 100x the item's value.
            double staminaCost = (isItemWorthLessThanOnePercentOfMoney && Game1.player.professions.Contains(Professions.Conduit)) ? 0D : Alchemy.GetStaminaCostForTransmutation(actualValue);

            //if the player lacks the stamina to execute a transmute, abort
            if (Game1.player.Stamina <= staminaCost)
            {
                return;
            }

            //if we fail this check, it's because a rebound would kill the player.
            //if the rebound chance is zero, this check will automatically pass.
            if (!Alchemy.CanSurviveRebound(actualValue, isItemWorthLessThanOnePercentOfMoney, true))
            {
                return;
            }

            //if we fail this check, transmutation will fail this cycle.
            //this is our "rebound check"
            if (Alchemy.DidPlayerFailReboundCheck(isItemWorthLessThanOnePercentOfMoney, true))
            {
                reboundDamageTaken += Alchemy.GetReboundDamage(actualValue);
                didTransmuteFail    = true;
            }

            //the conduit profession makes it so that the transmutation succeeds anyway, after taking damage.
            if (Game1.player.professions.Contains((int)Professions.Sage) || !didTransmuteFail)
            {
                //if we reached this point transmutation will succeed
                didTransmuteOccur = true;

                Alchemy.HandleStaminaDeduction(staminaCost, false);

                //we floor the math here because we don't want weirdly divergent values based on stack count - the rate is fixed regardless of quantity
                //this occurs at the expense of rounding - liquidation is lossy.
                int liquidationValue = (int)Math.Floor(Alchemy.GetLiquidationValuePercentage() * actualValue);

                int totalValue = liquidationValue;

                Game1.player.Money += totalValue;

                Game1.player.reduceActiveItemByOne();

                //the percentage of experience you get is increased by the lossiness of the transmute
                //as you increase in levels, this amount diminishes to a minimum of 1.
                double experienceValueCoefficient = 1D - Alchemy.GetLiquidationValuePercentage();
                int    experienceValue            = (int)Math.Floor(Math.Sqrt(experienceValueCoefficient * actualValue / 10 + 1));

                Alchemy.AddAlchemyExperience(experienceValue);

                //a transmute (at least one) happened, play the cash money sound
                if (didTransmuteOccur && !didTransmuteFail)
                {
                    SoundUtil.PlayMoneySound();
                }
            }

            //a rebound occurred, apply the damage and also play the ouchy sound.
            if (didTransmuteFail)
            {
                Alchemy.TakeDamageFromRebound(reboundDamageTaken);
                SoundUtil.PlayReboundSound();
            }
        }