Example #1
0
        private void beforeSave(object sender, EventArgs args)
        {
            Log.info("Before save, use vanilla farms...");

            foreach (var entry in Data.FarmTypes)
            {
                GameLocation loc = Game1.getLocationFromName(entry.Key);
                if (loc.GetType() == typeof(CustomFarm))
                {
                    Log.debug("Putting vanilla farm over " + entry.Key + "=" + entry.Value);
                    var  farm    = loc as CustomFarm;
                    Farm newFarm = new Farm(Helper.Content.Load <xTile.Map>("Maps\\Farm", ContentSource.GameContent), loc.name);
                    CustomFarm.swapFarms(farm, newFarm);
                    Game1.locations.Remove(farm);
                    Game1.locations.Add(newFarm);
                }
            }
        }
        public static object SafeDeSerialize(XmlReader reader, GameLocation location)
        {
            Type baseType   = typeof(GameLocation);
            Type customType = location.GetType();

            bool IsUnsafe = location is BuildableGameLocation || location is IAnimalLocation || location is DecoratableLocation;

            // No need to fix types from the base game.
            if (!IsUnsafe || object.ReferenceEquals(customType.Assembly, baseType.Assembly))
            {
                return(SaveGame.locationSerializer.Deserialize(reader));
            }

            var           xmlOverrides = new XmlAttributeOverrides();
            XmlSerializer serializer   = new XmlSerializer(customType, xmlOverrides, ExtraTypes, null, null);

            return(serializer.Deserialize(reader));
        }
Example #3
0
        /// <summary>Raised before the game creates a new save file or saves.</summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event arguments.</param>
        private void OnSaving(object sender, EventArgs e)
        {
            Log.info("Before save, use vanilla farms...");

            foreach (var entry in Data.FarmTypes)
            {
                GameLocation loc = Game1.getLocationFromName(entry.Key);
                if (loc.GetType() == typeof(CustomFarm))
                {
                    Log.debug($"Putting vanilla farm over {entry.Key}={entry.Value}");
                    var  farm    = loc as CustomFarm;
                    Farm newFarm = new Farm("Maps\\Farm", loc.Name);
                    CustomFarm.swapFarms(farm, newFarm);
                    Game1.locations.Remove(farm);
                    Game1.locations.Add(newFarm);
                }
            }

            Helper.Data.WriteSaveData("custom-farm-types", Data);
        }
        public override IActiveEffect onCast(Farmer player, int level, int targetX, int targetY)
        {
            level   += 1;
            targetX /= Game1.tileSize;
            targetY /= Game1.tileSize;
            Vector2 target = new Vector2(targetX, targetY);

            Tool dummyAxe  = new Axe(); dummyAxe.UpgradeLevel = level;
            Tool dummyPick = new Pickaxe(); dummyPick.UpgradeLevel = level;

            Mod.instance.Helper.Reflection.GetField <Farmer>(dummyAxe, "lastUser").SetValue(player);
            Mod.instance.Helper.Reflection.GetField <Farmer>(dummyPick, "lastUser").SetValue(player);

            GameLocation loc = player.currentLocation;

            for (int ix = targetX - level; ix <= targetX + level; ++ix)
            {
                for (int iy = targetY - level; iy <= targetY + level; ++iy)
                {
                    if (player.getCurrentMana() <= 0)
                    {
                        return(null);
                    }

                    Vector2 pos = new Vector2(ix, iy);

                    if (loc.objects.ContainsKey(pos))
                    {
                        var obj = loc.objects[pos];
                        if (obj.performToolAction(dummyAxe, loc))
                        {
                            if (obj.Type == "Crafting" && obj.Fragility != 2)
                            {
                                loc.debris.Add(new Debris(obj.bigCraftable.Value ? -obj.ParentSheetIndex : obj.ParentSheetIndex, pos, pos));
                            }
                            obj.performRemoveAction(pos, loc);
                            loc.objects.Remove(pos);
                            player.addMana(-3);
                            player.AddCustomSkillExperience(Magic.Skill, 1);
                        }
                        else
                        {
                            var oldStam = player.stamina;
                            dummyPick.DoFunction(loc, ix * Game1.tileSize, iy * Game1.tileSize, 0, player);
                            player.stamina = oldStam;
                            player.addMana(-3);
                            player.AddCustomSkillExperience(Magic.Skill, 1);
                        }
                    }

                    // Trees
                    if (level >= 2)
                    {
                        if (loc.terrainFeatures.ContainsKey(pos) && !(loc.terrainFeatures[pos] is HoeDirt))
                        {
                            TerrainFeature tf = loc.terrainFeatures[pos];
                            if (tf is Tree)
                            {
                                player.addMana(-3);
                            }
                            if (tf.performToolAction(dummyAxe, 0, pos, loc) || tf is Grass || (tf is Tree && tf.performToolAction(dummyAxe, 0, pos, loc)))
                            {
                                if (tf is Tree)
                                {
                                    player.AddCustomSkillExperience(Magic.Skill, 5);
                                }
                                loc.terrainFeatures.Remove(pos);
                            }
                            if (tf is Grass && loc is Farm)
                            {
                                (loc as Farm).tryToAddHay(1);
                                Game1.playSound("swordswipe");
                                loc.temporarySprites.Add(new TemporaryAnimatedSprite(28, pos * (float)Game1.tileSize + new Vector2((float)Game1.random.Next(-Game1.pixelZoom * 4, Game1.pixelZoom * 4), (float)Game1.random.Next(-Game1.pixelZoom * 4, Game1.pixelZoom * 4)), Color.Green, 8, Game1.random.NextDouble() < 0.5, (float)Game1.random.Next(60, 100), 0, -1, -1f, -1, 0));
                                loc.temporarySprites.Add(new TemporaryAnimatedSprite(Game1.objectSpriteSheetName, Game1.getSourceRectForStandardTileSheet(Game1.objectSpriteSheet, 178, 16, 16), 750f, 1, 0, player.position - new Vector2(0.0f, (float)(Game1.tileSize * 2)), false, false, player.position.Y / 10000f, 0.005f, Color.White, (float)Game1.pixelZoom, -0.005f, 0.0f, 0.0f, false)
                                {
                                    motion     = { Y = -1f },
                                    layerDepth = (float)(1.0 - (double)Game1.random.Next(100) / 10000.0),
                                    delayBeforeAnimationStart = Game1.random.Next(350)
                                });
                            }
                        }
                    }

                    if (level >= 3)
                    {
                        ICollection <ResourceClump> clumps = (NetCollection <ResourceClump>)loc.GetType().GetField("resourceClumps", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).GetValue(loc);
                        if (loc is Woods)
                        {
                            clumps = (loc as Woods).stumps;
                        }
                        if (clumps != null)
                        {
                            foreach (var rc in clumps)
                            {
                                if (new Rectangle((int)rc.tile.X, (int)rc.tile.Y, rc.width.Value, rc.height.Value).Contains(ix, iy))
                                {
                                    player.addMana(-3);
                                    if (rc.performToolAction(dummyAxe, 1, pos, loc) || rc.performToolAction(dummyPick, 1, pos, loc))
                                    {
                                        clumps.Remove(rc);
                                        player.AddCustomSkillExperience(Magic.Skill, 10);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            return(null);
        }
Example #5
0
        public static void TrySpousesKiss()
        {
            GameLocation location = Game1.currentLocation;

            if (location == null || !ReferenceEquals(location.GetType(), typeof(FarmHouse)))
            {
                return;
            }

            Farmer owner = (location as FarmHouse).owner;

            lastKissTime++;

            if (location == null || location.characters == null)
            {
                return;
            }

            List <NPC> list = location.characters.ToList();

            Misc.ShuffleList(ref list);

            foreach (NPC npc1 in list)
            {
                if (!owner.friendshipData.ContainsKey(npc1.Name))
                {
                    continue;
                }

                if (!ModEntry.config.RoommateRomance && owner.friendshipData[npc1.Name].RoommateMarriage)
                {
                    continue;
                }


                foreach (NPC npc2 in list)
                {
                    if (!owner.friendshipData.ContainsKey(npc2.Name))
                    {
                        continue;
                    }

                    if (npc1.Name == npc2.Name || (!ModEntry.config.RoommateRomance && owner.friendshipData[npc2.Name].RoommateMarriage))
                    {
                        continue;
                    }

                    if (lastKissTime >= ModEntry.config.MinSpouseKissInterval)
                    {
                        kissingSpouses.Clear();
                    }


                    float distance = Vector2.Distance(npc1.position, npc2.position);
                    if (
                        npc1.getSpouse() != null && npc2.getSpouse() != null &&
                        npc1.getSpouse().Name == npc2.getSpouse().Name &&
                        distance < ModEntry.config.MaxDistanceToKiss &&
                        !kissingSpouses.Contains(npc1.Name) &&
                        !kissingSpouses.Contains(npc2.Name) &&
                        owner.getFriendshipHeartLevelForNPC(npc1.Name) >= ModEntry.config.MinHeartsForKiss &&
                        owner.getFriendshipHeartLevelForNPC(npc2.Name) >= ModEntry.config.MinHeartsForKiss &&
                        lastKissTime > ModEntry.config.MinSpouseKissInterval &&
                        ModEntry.myRand.NextDouble() < ModEntry.config.SpouseKissChance &&
                        (!ModEntry.config.PreventRelativesFromKissing || !Misc.AreSpousesRelated(npc1.Name, npc2.Name))
                        )
                    {
                        kissingSpouses.Add(npc1.Name);
                        kissingSpouses.Add(npc2.Name);
                        ModEntry.PMonitor.Log("spouses kissing");
                        lastKissTime = 0;
                        Vector2 npc1pos  = npc1.position;
                        Vector2 npc2pos  = npc2.position;
                        int     npc1face = npc1.facingDirection;
                        int     npc2face = npc1.facingDirection;
                        Vector2 midpoint = new Vector2((npc1.position.X + npc2.position.X) / 2, (npc1.position.Y + npc2.position.Y) / 2);
                        PerformKiss(npc1, midpoint, npc2.Name);
                        PerformKiss(npc2, midpoint, npc1.Name);
                        DelayedAction action = new DelayedAction(1000);
                        var           t      = Task.Run(async delegate
                        {
                            await Task.Delay(TimeSpan.FromSeconds(1));
                            npc1.position.Value  = npc1pos;
                            npc2.position.Value  = npc2pos;
                            npc1.FacingDirection = npc1face;
                            npc2.FacingDirection = npc2face;
                            return;
                        });
                    }
                }
            }
        }
Example #6
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();
            }
        }
Example #7
0
        private GameLocation Serialize(Dictionary <string, Tuple <bool, InstanceState> > data, GameLocation location, bool building = false)
        {
            string guid   = Guid.NewGuid().ToString();
            var    output = new GameLocation();

#pragma warning disable AvoidNetField // Avoid Netcode types when possible
            output.name.Value = guid;
#pragma warning restore AvoidNetField // Avoid Netcode types when possible
            data.Add(building ? guid : location.Name, new Tuple <bool, InstanceState>(building, new InstanceState(location.GetType().AssemblyQualifiedName, JToken.FromObject(location, Serializer))));
            return(output);
        }
 public static bool Prefix(GameLocation location, Item item, int x, int y, Farmer f, ref bool __result)
 {
     if (!Config.EnableMod || item is not Object || !(item as Object).bigCraftable.Value || item.ParentSheetIndex != 62 || !typeof(DecoratableLocation).IsAssignableFrom(location.GetType()) || !(location as DecoratableLocation).isTileOnWall(x / 64, y / 64) || !Utility.isWithinTileWithLeeway(x, y, item, f))
     {
         return(true);
     }
     SMonitor.Log($"Placing planter on wall");
     __result = true;
     return(false);
 }
Example #9
0
 public static GameLocation GetOriginLocation(GameLocation location)
 {
     return(!(location is IHookedLocation) ? location : CopyData(location, location.GetType().BaseType));
 }
Example #10
0
 public static bool Prefix(GameLocation location, Item item, int x, int y, Farmer f, ref bool __result)
 {
     if (!Config.EnableMod || item is not TV || item.Name.Contains("Budget") || item.Name.Contains("Floor") || !typeof(DecoratableLocation).IsAssignableFrom(location.GetType()) || !(location as DecoratableLocation).isTileOnWall(x / 64, y / 64) || (location as DecoratableLocation).isTileOnWall(x / 64, y / 64 + 1) || !Utility.isWithinTileWithLeeway(x, y, item, f))
     {
         return(true);
     }
     __result = true;
     return(false);
 }
Example #11
0
 public static bool Prefix(Furniture __instance, GameLocation location, int x, int y, ref int __result)
 {
     if (!Config.EnableMod || __instance is not TV || __instance.Name.Contains("Budget") || __instance.Name.Contains("Floor") || !typeof(DecoratableLocation).IsAssignableFrom(location.GetType()) || !(location as DecoratableLocation).isTileOnWall((int)x / 64, (int)y / 64) || (location as DecoratableLocation).isTileOnWall(x / 64, y / 64 + 1))
     {
         return(true);
     }
     __instance.TileLocation = new Vector2(x / 64, y / 64);
     __result = 0;
     return(false);
 }
Example #12
0
 public static bool Prefix(Furniture __instance, GameLocation l, Vector2 tile, ref bool __result)
 {
     if (!Config.EnableMod || __instance is not TV || __instance.Name.Contains("Budget") || __instance.Name.Contains("Floor") || !typeof(DecoratableLocation).IsAssignableFrom(l.GetType()) || !(l as DecoratableLocation).isTileOnWall((int)tile.X, (int)tile.Y) || (l as DecoratableLocation).isTileOnWall((int)tile.X, (int)tile.Y + 1))
     {
         return(true);
     }
     __result = true;
     return(false);
 }