Example #1
0
        /// <summary>
        /// Allows the user to pop extra mushrooms before they're ready,
        /// and pop root mushrooms without extras.
        /// Author's note: The mushrooms are never ready.
        /// </summary>
        /// <returns>Whether to continue with base behaviour.</returns>
        public override bool performUseAction(GameLocation location)
        {
            Log.D($"performUseAction at {Game1.currentLocation?.Name} {TileLocation.ToString()}",
                  ModEntry.Instance.Config.DebugMode);

            return(PopByAction());
        }
Example #2
0
        private void Initialise()
        {
            Log.D($"Initialise propagator at {TileLocation.ToString()}",
                  ModEntry.Instance.Config.DebugMode);

            Name             = ModValues.PropagatorInternalName;
            ParentSheetIndex = ModValues.PropagatorIndex;
            DisplayName      = loadDisplayName();

            var strArray1 = ModValues.ObjectData.Split('/');

            price.Value     = Convert.ToInt32(strArray1[1]);
            edibility.Value = Convert.ToInt32(strArray1[2]);
            var strArray2 = strArray1[3].Split(' ');

            type.Value = strArray2[0];
            if (strArray2.Length > 1)
            {
                Category = Convert.ToInt32(strArray2[1]);
            }
            setOutdoors.Value = Convert.ToBoolean(strArray1[5]);
            setIndoors.Value  = Convert.ToBoolean(strArray1[6]);
            fragility.Value   = Convert.ToInt32(strArray1[7]);
            isLamp.Value      = strArray1.Length > 8 && strArray1[8].Equals("true");

            canBeSetDown.Value = true;
            bigCraftable.Value = true;
            initializeLightSource(TileLocation);

            boundingBox.Value = new Rectangle((int)TileLocation.X * 64, (int)TileLocation.Y * 64, 64, 64);
        }
Example #3
0
        public void PopExtraHeldMushrooms(bool giveNothing)
        {
            Log.D($"PopExtraHeldMushrooms at {Game1.currentLocation?.Name} {TileLocation.ToString()}",
                  ModEntry.Instance.Config.DebugMode);

            // Incorporate Gatherer's skill effects for bonus production
            var popQuantity = heldObject.Value.Stack;

            if (Game1.player.professions.Contains(Farmer.gatherer) &&
                new Random().Next(5) == 0)
            {
                popQuantity += 1;
            }

            var popQuality = Game1.player.professions.Contains(Farmer.botanist) ? 4 : SourceMushroomQuality;
            var popObject  = new Object(SourceMushroomIndex, 1, false, -1, popQuality);

            // Create mushroom item drops in the world from the machine
            if (!giveNothing)
            {
                for (var i = 0; i < popQuantity; ++i)
                {
                    Game1.createItemDebris(popObject.getOne(),
                                           new Vector2(TileLocation.X * 64 + 32, TileLocation.Y * 64 + 32), -1);
                }
            }

            // Clear the extra mushroom data
            heldObject.Value = null;
        }
Example #4
0
 public bool PopByAction()
 {
     Log.D($"PopByAction at {Game1.currentLocation?.Name} {TileLocation.ToString()}",
           ModEntry.Instance.Config.DebugMode);
     if (SourceMushroomIndex > 0)
     {
         PopExposedMushroom(false);
         return(true);
     }
     return(false);
 }
Example #5
0
        /// <summary>
        /// Adds an instance of the given item to be used as a source mushroom by the machine,
        /// and resets all growth and harvest variables.
        /// </summary>
        /// <param name="dropIn">Some instance of an object, hopefully a mushroom.</param>
        public void PutSourceMushroom(Item dropIn)
        {
            ModEntry.GetMushroomGrowthRate(dropIn as Object, out RateToMature);
            ModEntry.GetMushroomMaximumQuantity(dropIn as Object, out MaximumStack);
            SourceMushroomName      = dropIn.Name;
            SourceMushroomIndex     = dropIn.ParentSheetIndex;
            SourceMushroomQuality   = (dropIn as Object).Quality;
            DaysToMature            = 0;
            minutesUntilReady.Value = 999999;

            Log.D($"PutSourceMushroom(item: [{dropIn.ParentSheetIndex}] {dropIn.Name} Q{(dropIn as Object).Quality}), stack to {MaximumStack}" +
                  $" at {Game1.currentLocation?.Name} {TileLocation.ToString()}",
                  ModEntry.Instance.Config.DebugMode);
        }
Example #6
0
        /// <summary>
        /// Overrides the usual hit-with-tool behaviour to change the requirements
        /// and allow for popping held mushrooms at different stages.
        /// </summary>
        /// <returns>Whether or not to continue with base behaviour.</returns>
        public override bool performToolAction(Tool t, GameLocation location)
        {
            Log.D($"performToolAction at {Game1.currentLocation?.Name} {TileLocation.ToString()}",
                  ModEntry.Instance.Config.DebugMode);

            // Ignore usages that wouldn't trigger actions for other machines
            if (t == null || !t.isHeavyHitter() || t is StardewValley.Tools.MeleeWeapon)
            {
                return(base.performToolAction(t, location));
            }

            location.playSound("woodWhack");
            return(PopByTool());
        }
Example #7
0
        /// <summary>
        /// Behaviours for tool actions to uproot the machine itself.
        /// </summary>
        public void PopMachine()
        {
            Log.D($"PopMachine at {Game1.currentLocation?.Name} {TileLocation.ToString()}",
                  ModEntry.Instance.Config.DebugMode);
            var key = Game1.player.GetToolLocation() / 64f;

            key.X = (int)key.X;
            key.Y = (int)key.Y;
            var toolLocation   = Game1.player.GetToolLocation();
            var x              = (double)boundingBox.Center.X;
            var y              = (double)boundingBox.Center.Y;
            var playerPosition = new Vector2((float)x, (float)y);

            Game1.currentLocation.debris.Add(new Debris(
                                                 new Propagator(TileLocation), toolLocation, playerPosition));
            Game1.currentLocation.Objects.Remove(key);
        }
Example #8
0
        public bool PopByTool()
        {
            Log.D($"PopByTool at {Game1.currentLocation?.Name} {TileLocation.ToString()}",
                  ModEntry.Instance.Config.DebugMode);

            if (SourceMushroomIndex > 0)
            {
                // Extract any held mushrooms from machine
                PopExposedMushroom(true);
            }
            else
            {
                // Extract machine from location
                PopMachine();
            }
            return(false);
        }
Example #9
0
        /// <summary>
        /// Pops the extra mushrooms in the 'heldItem' slot if they exist, otherwise pops the source mushroom and resets to 'empty'.
        /// </summary>
        /// <param name="forceRemoveSource">
        /// Whether or not to pop the source mushroom in addition to any extra mushrooms, leaving the machine considered 'empty'.
        /// </param>
        public void PopExposedMushroom(bool forceRemoveSource)
        {
            Log.D($"PopExposedMushroom(forceRemoveSource: {forceRemoveSource})"
                  + $" (item: [{SourceMushroomIndex}] {SourceMushroomName} Q{SourceMushroomQuality})" +
                  $" at {Game1.currentLocation?.Name} {TileLocation.ToString()}",
                  ModEntry.Instance.Config.DebugMode);

            Game1.playSound("harvest");
            var popSource = forceRemoveSource || heldObject.Value == null;

            // Pop the extra mushrooms, leaving the source mushroom to continue producing
            if (heldObject.Value != null)
            {
                PopExtraHeldMushrooms(giveNothing: false);
                minutesUntilReady.Value = 999999;
            }

            // Pop the source mushroom, resetting the machine to default
            if (popSource)
            {
                Log.D("PopExposed source",
                      ModEntry.Instance.Config.DebugMode);
                Game1.createItemDebris(new Object(SourceMushroomIndex, 1)
                {
                    Quality = SourceMushroomQuality
                },
                                       new Vector2(TileLocation.X * 64 + 32, TileLocation.Y * 64 + 32), -1);
                MaximumStack            = 1;
                SourceMushroomName      = null;
                SourceMushroomIndex     = 0;
                SourceMushroomQuality   = 0;
                minutesUntilReady.Value = -1;
            }

            // Reset growing and harvesting info
            readyForHarvest.Value = false;
            DaysToMature          = 0;
        }
Example #10
0
        /// <summary>
        /// Override method for any player cursor passive or active interactions with the machine.
        /// Permits triggering behaviours to pop mushrooms before they're ready with the action hotkey.
        /// </summary>
        /// <param name="who">Farmer interacting with the machine.</param>
        /// <param name="justCheckingForActivity">Whether the cursor hovered or clicked.</param>
        /// <returns>Whether to continue with base method.</returns>
        public override bool checkForAction(Farmer who, bool justCheckingForActivity = false)
        {
            if (!justCheckingForActivity)
            {
                Log.D($"checkForAction at {Game1.currentLocation?.Name} {TileLocation.ToString()}",
                      ModEntry.Instance.Config.DebugMode);
            }

            if (!justCheckingForActivity && who != null &&
                who.currentLocation.isObjectAtTile(who.getTileX(), who.getTileY() - 1) &&
                who.currentLocation.isObjectAtTile(who.getTileX(), who.getTileY() + 1) &&
                who.currentLocation.isObjectAtTile(who.getTileX() + 1, who.getTileY()) &&
                who.currentLocation.isObjectAtTile(who.getTileX() - 1, who.getTileY()) &&
                !who.currentLocation.getObjectAtTile(who.getTileX(), who.getTileY() - 1).isPassable() &&
                !who.currentLocation.getObjectAtTile(who.getTileX(), who.getTileY() + 1).isPassable() &&
                !who.currentLocation.getObjectAtTile(who.getTileX() - 1, who.getTileY()).isPassable() &&
                !who.currentLocation.getObjectAtTile(who.getTileX() + 1, who.getTileY()).isPassable())
            {
                performToolAction(null, who.currentLocation);
            }

            return(justCheckingForActivity || base.checkForAction(who, justCheckingForActivity));
        }
Example #11
0
        /// <summary>
        /// Overrides usual use-with-item behaviours to limit the set to working in
        /// specific locations with specific items, as well as other funky behaviour.
        /// </summary>
        /// <param name="dropIn">Our candidate item.</param>
        /// <param name="probe">Base game check for determining outcomes without consequences.</param>
        /// <param name="who">Farmer using the machine.</param>
        /// <returns>
        /// Whether the dropIn object is appropriate for this machine in this context.
        /// </returns>
        public override bool performObjectDropInAction(Item dropIn, bool probe, Farmer who)
        {
            if (!probe)
            {
                Log.D($"performObjectDropInAction(dropIn:{dropIn?.Name ?? "null"}) at {Game1.currentLocation?.Name} {TileLocation.ToString()}",
                      ModEntry.Instance.Config.DebugMode);
            }

            // Ignore usages with inappropriate items
            if (dropIn == null)
            {
                return(false);
            }

            // Extract held mushrooms prematurely
            if (!probe && SourceMushroomIndex > 0)
            {
                if (heldObject.Value != null)
                {
                    // Get a copy of the root mushroom
                    PopExposedMushroom(false);
                }
                else if (!ModEntry.Instance.Config.OnlyToolsCanRemoveRootMushrooms)
                {
                    // Remove the root mushroom if it hasn't settled overnight
                    PopExposedMushroom(true);
                }
            }

            // Determine if being used in an appropriate location
            if (!probe && who != null)
            {
                var flag = (who.currentLocation is Cellar && ModEntry.Instance.Config.WorksInCellar) ||
                           (who.currentLocation is FarmCave && ModEntry.Instance.Config.WorksInFarmCave) ||
                           (who.currentLocation is BuildableGameLocation && ModEntry.Instance.Config.WorksInBuildings) ||
                           (who.currentLocation is FarmHouse && ModEntry.Instance.Config.WorksInFarmHouse) ||
                           (who.currentLocation.IsGreenhouse && ModEntry.Instance.Config.WorksInGreenhouse) ||
                           (who.currentLocation.IsOutdoors && ModEntry.Instance.Config.WorksOutdoors);

                if (!flag)
                {
                    // Ignore bad machine locations
                    Game1.showRedMessage(ModEntry.Instance.i18n.Get("error.location"));
                    return(false);
                }
            }

            // Ignore Truffles
            if (!probe && dropIn.ParentSheetIndex.Equals(430))
            {
                Game1.showRedMessage(ModEntry.Instance.i18n.Get("error.truffle"));
                return(false);
            }

            if (!(dropIn is Object o) || !ModEntry.IsValidMushroom(o))
            {
                if (!probe)
                {
                    Log.D($"Invalid mushroom: [{dropIn.ParentSheetIndex}] {dropIn.Name}",
                          ModEntry.Instance.Config.DebugMode);
                }
                return(false);
            }

            if (probe)
            {
                return(true);
            }

            // Accept the deposited item as the new source mushroom
            PutSourceMushroom(dropIn);
            who?.currentLocation.playSound("Ship");
            return(true);
        }
Example #12
0
        /// <summary>
        /// Perform all start-of-day checks for the Propagator to handle held object events.
        /// </summary>
        internal void DayUpdate()
        {
            Log.D($"DayUpdate (item: [{SourceMushroomIndex}] {SourceMushroomName} Q{SourceMushroomQuality} at {Game1.currentLocation?.Name} {TileLocation.ToString()}",
                  ModEntry.Instance.Config.DebugMode);

            // Indexing inconsistencies with JA/CFR
            ParentSheetIndex = ModValues.PropagatorIndex;

            // Grow mushrooms overnight
            if (SourceMushroomIndex > 0)
            {
                GrowHeldMushroom();
            }
        }