public static void Display_RenderedWorld(object sender, RenderedWorldEventArgs e)
        {
            if (ModEntry.isUnderwater && SwimUtils.IsMapUnderwater(Game1.player.currentLocation.Name))
            {
                if ((ticksUnderwater % 100 / Math.Min(100, Config.BubbleMult)) - bubbleOffset == 0)
                {
                    Game1.playSound("tinyWhip");
                    ModEntry.bubbles.Add(new Vector2(Game1.player.position.X + Game1.random.Next(-24, 25), Game1.player.position.Y - 96));
                    if (ModEntry.bubbles.Count > 100)
                    {
                        ModEntry.bubbles = ModEntry.bubbles.Skip(1).ToList();
                    }
                    bubbleOffset = Game1.random.Next(30 / Math.Min(100, Config.BubbleMult));
                }

                for (int k = 0; k < ModEntry.bubbles.Count; k++)
                {
                    ModEntry.bubbles[k] = new Vector2(ModEntry.bubbles[k].X, ModEntry.bubbles[k].Y - 2);
                }

                foreach (Vector2 v in ModEntry.bubbles)
                {
                    e.SpriteBatch.Draw(bubbleTexture, v + new Vector2((float)Math.Sin(ticksUnderwater / 20f) * 10f - Game1.viewport.X, -Game1.viewport.Y), new Microsoft.Xna.Framework.Rectangle?(new Microsoft.Xna.Framework.Rectangle(132, 20, 8, 8)), new Color(1, 1, 1, 0.5f), 0f, Vector2.Zero, 4f, SpriteEffects.None, 0.001f);
                }
                ticksUnderwater++;
            }
            else
            {
                ticksUnderwater = 0;
            }
        }
        public static void GameLocation_isCollidingPosition_Postfix(GameLocation __instance, ref bool __result, Microsoft.Xna.Framework.Rectangle position, xTile.Dimensions.Rectangle viewport, bool isFarmer, int damagesFarmer, bool glider, Character character, bool pathfinding, bool projectile = false, bool ignoreCharacterRequirement = false)
        {
            try
            {
                IEnumerable <Farmer> farmers = Game1.getAllFarmers();
                if (!farmers.Any())
                {
                    return;
                }
                foreach (Farmer farmer in farmers)
                {
                    if (farmer.currentLocation == null || farmer == null || !Game1.displayFarmer || farmer.position == null)
                    {
                        return;
                    }
                    if (!__result || !isFarmer || !character.Equals(farmer) || !farmer.swimming || ModEntry.swimmerData[farmer.uniqueMultiplayerID].isUnderwater)
                    {
                        return;
                    }

                    Vector2 next = SwimUtils.GetNextTile(farmer);
                    //Monitor.Log($"Checking collide {SwimUtils.doesTileHaveProperty(__instance.map, (int)next.X, (int)next.Y, "Water", "Back") != null}");
                    if ((int)next.X <= 0 || (int)next.Y <= 0 || __instance.Map.Layers[0].LayerWidth <= (int)next.X || __instance.Map.Layers[0].LayerHeight <= (int)next.Y || SwimUtils.doesTileHaveProperty(__instance.map, (int)next.X, (int)next.Y, "Water", "Back") != null)
                    {
                        __result = false;
                    }
                }
            }
            catch (Exception ex)
            {
                Monitor.Log($"Failed in {nameof(GameLocation_isCollidingPosition_Postfix)}:\n{ex}", LogLevel.Error);
            }
        }
 public static void Input_ButtonReleased(object sender, ButtonReleasedEventArgs e)
 {
     if (Game1.player == null)
     {
         ModEntry.myButtonDown = false;
         return;
     }
     SwimUtils.CheckIfMyButtonDown();
 }
Exemple #4
0
 public bool AddContentPack(IContentPack contentPack)
 {
     try
     {
         Monitor.Log($"Reading content pack: {contentPack.Manifest.Name} {contentPack.Manifest.Version} from {contentPack.DirectoryPath}");
         DiveMapData data = contentPack.ReadJsonFile <DiveMapData>("content.json");
         SwimUtils.ReadDiveMapData(data);
         return(true);
     }
     catch
     {
         Monitor.Log($"couldn't read content.json in content pack {contentPack.Manifest.Name}", LogLevel.Warn);
         return(false);
     }
 }
        public static void Display_RenderedHud(object sender, RenderedHudEventArgs e)
        {
            if (Game1.player.currentLocation.Name == "ScubaAbigailCave")
            {
                if (abigailTicks > 0 && abigailTicks < 80000 / 16)
                {
                    SwimUtils.MakeOxygenBar((80000 / 16) - abigailTicks, 80000 / 16);
                }
                e.SpriteBatch.Draw(ModEntry.OxygenBarTexture, new Vector2((int)Math.Round(Game1.viewport.Width * 0.13f), 100), Color.White);
                return;
            }
            int maxOx = SwimUtils.MaxOxygen();

            if (ModEntry.oxygen < maxOx)
            {
                SwimUtils.MakeOxygenBar(ModEntry.oxygen, maxOx);
                e.SpriteBatch.Draw(ModEntry.OxygenBarTexture, new Vector2((int)Math.Round(Game1.viewport.Width * 0.13f), 100), Color.White);
            }
        }
        public static void GameLocation_isCollidingPosition_Postfix(GameLocation __instance, ref bool __result, Microsoft.Xna.Framework.Rectangle position, xTile.Dimensions.Rectangle viewport, bool isFarmer, int damagesFarmer, bool glider, Character character, bool pathfinding, bool projectile = false, bool ignoreCharacterRequirement = false)
        {
            try
            {
                if (__result == false || !isFarmer || !character.Equals(Game1.player) || !Game1.player.swimming || ModEntry.isUnderwater)
                {
                    return;
                }

                Vector2 next = SwimUtils.GetNextTile();
                //Monitor.Log($"Checking collide {SwimUtils.doesTileHaveProperty(__instance.map, (int)next.X, (int)next.Y, "Water", "Back") != null}");
                if ((int)next.X <= 0 || (int)next.Y <= 0 || __instance.Map.Layers[0].LayerWidth <= (int)next.X || __instance.Map.Layers[0].LayerHeight <= (int)next.Y || SwimUtils.doesTileHaveProperty(__instance.map, (int)next.X, (int)next.Y, "Water", "Back") != null)
                {
                    __result = false;
                }
            }
            catch (Exception ex)
            {
                Monitor.Log($"Failed in {nameof(GameLocation_isCollidingPosition_Postfix)}:\n{ex}", LogLevel.Error);
            }
        }
Exemple #7
0
        public static void Display_RenderedHud(object sender, RenderedHudEventArgs e)
        {
            if (Game1.player.currentLocation.Name == "ScubaAbigailCave")
            {
                if (abigailTicks > 0 && abigailTicks < 30 * 5)
                {
                    e.SpriteBatch.Draw(Game1.mouseCursors, new Vector2(Game1.viewport.Width, Game1.viewport.Height) / 2 - new Vector2(78, 31) / 2, new Rectangle?(new Rectangle(353, 1649, 78, 31)), new Color(255, 255, 255, abigailTicks > 30 * 3 ? (int)Math.Round(255 * (abigailTicks - 90) / 60f) : 255), 0f, Vector2.Zero, 3f, SpriteEffects.None, 0.99f);
                }
                if (abigailTicks > 0 && abigailTicks < 80000 / 16)
                {
                    SwimUtils.MakeOxygenBar((80000 / 16) - abigailTicks, 80000 / 16);
                }
                e.SpriteBatch.Draw(ModEntry.OxygenBarTexture, new Vector2((int)Math.Round(Game1.viewport.Width * 0.13f), 100), Color.White);
                return;
            }
            int maxOx = SwimUtils.MaxOxygen();

            if (ModEntry.oxygen < maxOx)
            {
                SwimUtils.MakeOxygenBar(ModEntry.oxygen, maxOx);
                e.SpriteBatch.Draw(ModEntry.OxygenBarTexture, new Vector2((int)Math.Round(Game1.viewport.Width * 0.13f), 100), Color.White);
            }
        }
        public static void RemoveWaterTiles(GameLocation l)
        {
            if (l == null || l.map == null)
            {
                return;
            }
            Map    map     = l.map;
            string mapName = l.Name;

            for (int x = 0; x < map.Layers[0].LayerWidth; x++)
            {
                for (int y = 0; y < map.Layers[0].LayerHeight; y++)
                {
                    if (SwimUtils.doesTileHaveProperty(map, x, y, "Water", "Back") != null)
                    {
                        Tile tile = map.GetLayer("Back").PickTile(new Location(x, y) * Game1.tileSize, Game1.viewport.Size);
                        if (tile != null)
                        {
                            tile.TileIndexProperties.Remove("Water");
                        }
                    }
                }
            }
        }
        public static void SwitchToLandTiles(GameLocation location)
        {
            string mapName = location.Name;

            Map map = location.Map;

            for (int x = 0; x < map.Layers[0].LayerWidth; x++)
            {
                for (int y = 0; y < map.Layers[0].LayerHeight; y++)
                {
                    if (SwimUtils.doesTileHaveProperty(map, x, y, "Water", "Back") != null)
                    {
                        Tile tile = map.GetLayer("Back").PickTile(new Location(x, y) * Game1.tileSize, Game1.viewport.Size);
                        if (tile != null)
                        {
                            if (tile.TileIndexProperties.ContainsKey("Passable"))
                            {
                                tile.TileIndexProperties["Passable"] = "F";
                            }
                        }
                        tile = map.GetLayer("Buildings").PickTile(new Location(x, y) * Game1.tileSize, Game1.viewport.Size);
                        if (tile != null)
                        {
                            if (tile.TileIndexProperties.ContainsKey("Passable"))
                            {
                                tile.TileIndexProperties["Passable"] = "F";
                            }
                            else
                            {
                                tile.TileIndexProperties.Add("Passable", "F");
                            }
                        }
                    }
                }
            }
        }
Exemple #10
0
        public override void Entry(IModHelper helper)
        {
            config = Helper.ReadConfig <ModConfig>();
            if (!config.EnableMod)
            {
                return;
            }

            SMonitor = Monitor;

            myRand = new Random();

            SwimPatches.Initialize(Monitor, helper, config);
            SwimDialog.Initialize(Monitor, helper, config);
            SwimMaps.Initialize(Monitor, helper, config);
            SwimHelperEvents.Initialize(Monitor, helper, config);
            SwimUtils.Initialize(Monitor, helper, config);

            helper.Events.GameLoop.UpdateTicked   += SwimHelperEvents.GameLoop_UpdateTicked;
            helper.Events.Input.ButtonPressed     += SwimHelperEvents.Input_ButtonPressed;
            helper.Events.Input.ButtonReleased    += SwimHelperEvents.Input_ButtonReleased;
            helper.Events.GameLoop.DayStarted     += SwimHelperEvents.GameLoop_DayStarted;
            helper.Events.GameLoop.GameLaunched   += SwimHelperEvents.GameLoop_GameLaunched;
            helper.Events.GameLoop.SaveLoaded     += SwimHelperEvents.GameLoop_SaveLoaded;
            helper.Events.Display.RenderedHud     += SwimHelperEvents.Display_RenderedHud;
            helper.Events.Display.RenderedWorld   += SwimHelperEvents.Display_RenderedWorld;
            helper.Events.Player.InventoryChanged += SwimHelperEvents.Player_InventoryChanged;
            helper.Events.Player.Warped           += SwimHelperEvents.Player_Warped;

            var harmony = HarmonyInstance.Create(this.ModManifest.UniqueID);

            harmony.Patch(
                original: AccessTools.Method(typeof(FarmerRenderer), nameof(FarmerRenderer.draw), new Type[] { typeof(SpriteBatch), typeof(FarmerSprite.AnimationFrame), typeof(int), typeof(Rectangle), typeof(Vector2), typeof(Vector2), typeof(float), typeof(int), typeof(Color), typeof(float), typeof(float), typeof(Farmer) }),
                prefix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.FarmerRenderer_draw_Prefix)),
                postfix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.FarmerRenderer_draw_Postfix))
                );
            harmony.Patch(
                original: AccessTools.Method(typeof(FarmerSprite), "checkForFootstep"),
                prefix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.FarmerSprite_checkForFootstep_Prefix))
                );
            harmony.Patch(
                original: AccessTools.Method(typeof(GameLocation), nameof(GameLocation.startEvent)),
                postfix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.GameLocation_StartEvent_Postfix))
                );
            harmony.Patch(
                original: AccessTools.Method(typeof(Event), nameof(Event.exitEvent)),
                postfix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.Event_exitEvent_Postfix))
                );

            harmony.Patch(
                original: AccessTools.Method(typeof(Farmer), "updateCommon"),
                prefix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.Farmer_updateCommon_Prefix)),
                postfix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.Farmer_updateCommon_Postfix)),
                transpiler: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.Farmer_updateCommon_Transpiler))
                );

            harmony.Patch(
                original: AccessTools.Method(typeof(Farmer), nameof(Farmer.setRunning)),
                prefix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.Farmer_setRunning_Prefix)),
                postfix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.Farmer_setRunning_Postfix))
                );

            harmony.Patch(
                original: AccessTools.Method(typeof(Farmer), nameof(Farmer.changeIntoSwimsuit)),
                postfix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.Farmer_changeIntoSwimsuit_Postfix))
                );

            harmony.Patch(
                original: AccessTools.Method(typeof(Toolbar), nameof(Toolbar.draw), new Type[] { typeof(SpriteBatch) }),
                prefix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.Toolbar_draw_Prefix))
                );

            /*
             *
             * harmony.Patch(
             * original: AccessTools.Method(typeof(Wand), nameof(Wand.DoFunction)),
             * transpiler: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.Wand_DoFunction_Transpiler))
             * );
             *
             */

            harmony.Patch(
                original: AccessTools.Method(typeof(GameLocation), nameof(GameLocation.draw)),
                prefix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.GameLocation_draw_Prefix))
                );

            harmony.Patch(
                original: AccessTools.Method(typeof(GameLocation), nameof(GameLocation.UpdateWhenCurrentLocation)),
                postfix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.GameLocation_UpdateWhenCurrentLocation_Postfix))
                );

            harmony.Patch(
                original: AccessTools.Method(typeof(GameLocation), nameof(GameLocation.resetForPlayerEntry)),
                prefix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.GameLocation_resetForPlayerEntry_Prefix))
                );

            harmony.Patch(
                original: AccessTools.Method(typeof(GameLocation), nameof(GameLocation.isCollidingPosition), new Type[] { typeof(Rectangle), typeof(xTile.Dimensions.Rectangle), typeof(bool), typeof(int), typeof(bool), typeof(Character) }),
                prefix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.GameLocation_isCollidingPosition_Prefix))
                );

            harmony.Patch(
                original: AccessTools.Method(typeof(GameLocation), nameof(GameLocation.performTouchAction)),
                prefix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.GameLocation_performTouchAction_Prefix))
                );

            harmony.Patch(
                original: AccessTools.Method(typeof(GameLocation), nameof(GameLocation.checkAction)),
                prefix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.GameLocation_checkAction_Prefix))
                );

            harmony.Patch(
                original: AccessTools.Method(typeof(GameLocation), nameof(GameLocation.isCollidingPosition), new Type[] { typeof(Rectangle), typeof(xTile.Dimensions.Rectangle), typeof(bool), typeof(int), typeof(bool), typeof(Character), typeof(bool), typeof(bool), typeof(bool) }),
                postfix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.GameLocation_isCollidingPosition_Postfix))
                );

            harmony.Patch(
                original: AccessTools.Method(typeof(GameLocation), nameof(GameLocation.sinkDebris)),
                postfix: new HarmonyMethod(typeof(SwimPatches), nameof(SwimPatches.GameLocation_sinkDebris_Postfix))
                );
        }
Exemple #11
0
        /// <summary>Edit a matched asset.</summary>
        /// <param name="asset">A helper which encapsulates metadata about an asset and enables changes to it.</param>
        public void Edit <T>(IAssetData asset)
        {
            Monitor.Log("Editing asset: " + asset.AssetName);

            string mapName = asset.AssetName.Replace("Maps/", "").Replace("Maps\\", "");

            if (false && changeLocations.ContainsKey(mapName))
            {
                IAssetDataForMap map = asset.AsMap();
                for (int x = 0; x < map.Data.Layers[0].LayerWidth; x++)
                {
                    for (int y = 0; y < map.Data.Layers[0].LayerHeight; y++)
                    {
                        if (SwimUtils.doesTileHaveProperty(map.Data, x, y, "Water", "Back") != null)
                        {
                            Tile tile = map.Data.GetLayer("Back").PickTile(new Location(x, y) * Game1.tileSize, Game1.viewport.Size);
                            if (tile != null && (((mapName == "Beach" || mapName == "UnderwaterBeach") && x > 58 && x < 61 && y > 11 && y < 15) || mapName != "Beach"))
                            {
                                if (tile.TileIndexProperties.ContainsKey("Passable"))
                                {
                                    tile.TileIndexProperties.Remove("Passable");
                                }
                            }
                            tile = map.Data.GetLayer("Front").PickTile(new Location(x, y) * Game1.tileSize, Game1.viewport.Size);
                            if (tile != null)
                            {
                                if (tile.TileIndexProperties.ContainsKey("Passable"))
                                {
                                    //tile.TileIndexProperties.Remove("Passable");
                                }
                            }
                            if (map.Data.GetLayer("AlwaysFront") != null)
                            {
                                tile = map.Data.GetLayer("AlwaysFront").PickTile(new Location(x, y) * Game1.tileSize, Game1.viewport.Size);
                                if (tile != null)
                                {
                                    if (tile.TileIndexProperties.ContainsKey("Passable"))
                                    {
                                        //tile.TileIndexProperties.Remove("Passable");
                                    }
                                }
                            }
                            tile = map.Data.GetLayer("Buildings").PickTile(new Location(x, y) * Game1.tileSize, Game1.viewport.Size);
                            if (tile != null)
                            {
                                if (
                                    ((mapName == "Beach" || mapName == "UnderwaterBeach") && x > 58 && x < 61 && y > 11 && y < 15) ||
                                    (mapName != "Beach" && mapName != "UnderwaterBeach" &&
                                     ((tile.TileIndex > 1292 && tile.TileIndex < 1297) || (tile.TileIndex > 1317 && tile.TileIndex < 1322) ||
                                      (tile.TileIndex % 25 > 17 && tile.TileIndex / 25 < 53 && tile.TileIndex / 25 > 48) ||
                                      (tile.TileIndex % 25 > 1 && tile.TileIndex % 25 < 7 && tile.TileIndex / 25 < 53 && tile.TileIndex / 25 > 48) ||
                                      (tile.TileIndex % 25 > 11 && tile.TileIndex / 25 < 51 && tile.TileIndex / 25 > 48) ||
                                      (tile.TileIndex % 25 > 10 && tile.TileIndex % 25 < 14 && tile.TileIndex / 25 < 49 && tile.TileIndex / 25 > 46) ||
                                      tile.TileIndex == 734 || tile.TileIndex == 759 ||
                                      tile.TileIndex == 628 || tile.TileIndex == 629 ||
                                      (mapName == "Forest" && x == 119 && ((y > 42 && y < 48) || (y > 104 && y < 119)))

                                     )
                                    )
                                    )
                                {
                                    if (tile.TileIndexProperties.ContainsKey("Passable"))
                                    {
                                        tile.TileIndexProperties["Passable"] = "T";
                                    }
                                    else
                                    {
                                        tile.TileIndexProperties.Add("Passable", "T");
                                    }
                                }
                                else if (mapName == "Beach" && tile.TileIndex == 76)
                                {
                                    if (x > 58 && x < 61 && y > 11 && y < 15)
                                    {
                                        Game1.getLocationFromName(mapName).removeTile(x, y, "Buildings");
                                    }
                                    if (tile.TileIndexProperties.ContainsKey("Passable"))
                                    {
                                        tile.TileIndexProperties.Remove("Passable");
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        public static void GameLocation_sinkDebris_Postfix(GameLocation __instance, bool __result, Debris debris, Vector2 chunkTile, Vector2 chunkPosition)
        {
            try
            {
                if (__result == false || !Game1.IsMasterGame || !SwimUtils.DebrisIsAnItem(debris))
                {
                    return;
                }

                if (ModEntry.diveMaps.ContainsKey(__instance.Name) && ModEntry.diveMaps[__instance.Name].DiveLocations.Count > 0)
                {
                    Point    pos = new Point((int)chunkTile.X, (int)chunkTile.Y);
                    Location loc = new Location(pos.X, pos.Y);

                    DiveMap      dm           = ModEntry.diveMaps[__instance.Name];
                    DiveLocation diveLocation = null;
                    foreach (DiveLocation dl in dm.DiveLocations)
                    {
                        if (dl.GetRectangle().X == -1 || dl.GetRectangle().Contains(loc))
                        {
                            diveLocation = dl;
                            break;
                        }
                    }

                    if (diveLocation == null)
                    {
                        Monitor.Log($"sink debris: No dive destination for this point on this map");
                        return;
                    }

                    if (Game1.getLocationFromName(diveLocation.OtherMapName) == null)
                    {
                        Monitor.Log($"sink debris: Can't find destination map named {diveLocation.OtherMapName}", LogLevel.Warn);
                        return;
                    }


                    foreach (Chunk chunk in debris.Chunks)
                    {
                        if (chunk.position == chunkPosition)
                        {
                            Monitor.Log($"sink debris: creating copy of debris {debris.debrisType} chunk {chunk.debrisType} item {debris.item != null} on {diveLocation.OtherMapName}");

                            if (debris.debrisType != Debris.DebrisType.ARCHAEOLOGY && debris.debrisType != Debris.DebrisType.OBJECT && chunk.debrisType % 2 != 0)
                            {
                                Monitor.Log($"sink debris: non-item debris");
                                break;
                            }

                            Debris  newDebris;
                            Vector2 newTile = diveLocation.OtherMapPos == null ? chunkTile : new Vector2(diveLocation.OtherMapPos.X, diveLocation.OtherMapPos.Y);
                            Vector2 newPos  = new Vector2(newTile.X * Game1.tileSize, newTile.Y * Game1.tileSize);
                            if (debris.item != null)
                            {
                                newDebris = Game1.createItemDebris(debris.item, newPos, Game1.random.Next(4));
                                Game1.getLocationFromName(diveLocation.OtherMapName).debris.Add(newDebris);
                            }
                            else
                            {
                                Game1.createItemDebris(new StardewValley.Object(chunk.debrisType, 1), newPos, Game1.random.Next(4), Game1.getLocationFromName(diveLocation.OtherMapName));
                            }
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Monitor.Log($"Failed in {nameof(GameLocation_sinkDebris_Postfix)}:\n{ex}", LogLevel.Error);
            }
        }
        public static void Input_ButtonPressed(object sender, ButtonPressedEventArgs e)
        {
            if (Game1.player == null || Game1.player.currentLocation == null)
            {
                ModEntry.myButtonDown = false;
                return;
            }

            if (false && e.Button == SButton.Q)
            {
                SwimUtils.SeaMonsterSay("The quick brown fox jumped over the slow lazy dog.");
            }

            if (Game1.activeClickableMenu != null && Game1.player.currentLocation.Name == "ScubaCrystalCave" && Game1.player.currentLocation.lastQuestionKey.StartsWith("SwimMod_Mariner_"))
            {
                IClickableMenu menu = Game1.activeClickableMenu;
                if (menu == null || menu.GetType() != typeof(DialogueBox))
                {
                    return;
                }
                int             resp  = (int)typeof(DialogueBox).GetField("selectedResponse", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(menu);
                List <Response> resps = (List <Response>) typeof(DialogueBox).GetField("responses", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(menu);

                if (resp < 0 || resps == null || resp >= resps.Count || resps[resp] == null)
                {
                    return;
                }
                Game1.player.currentLocation.lastQuestionKey = "";

                SwimDialog.OldMarinerDialogue(resps[resp].responseKey);
                return;
            }

            if (false && e.Button == SButton.Q)
            {
                var v1 = Game1.game1;
                return;
                //Game1.player.currentLocation.overlayObjects[Game1.player.getTileLocation() + new Vector2(0, 1)] = new Chest(0, new List<Item>() { Helper.Input.IsDown(SButton.LeftShift) ? (Item)(new StardewValley.Object(434, 1)) : (new Hat(ModEntry.scubaMaskID)) }, Game1.player.getTileLocation() + new Vector2(0, 1), false, 0);
            }

            if (e.Button == Config.DiveKey && ModEntry.diveMaps.ContainsKey(Game1.player.currentLocation.Name) && ModEntry.diveMaps[Game1.player.currentLocation.Name].DiveLocations.Count > 0)
            {
                Point    pos = Game1.player.getTileLocationPoint();
                Location loc = new Location(pos.X, pos.Y);

                if (!SwimUtils.IsInWater())
                {
                    return;
                }

                DiveMap      dm           = ModEntry.diveMaps[Game1.player.currentLocation.Name];
                DiveLocation diveLocation = null;
                foreach (DiveLocation dl in dm.DiveLocations)
                {
                    if (dl.GetRectangle().X == -1 || dl.GetRectangle().Contains(loc))
                    {
                        diveLocation = dl;
                        break;
                    }
                }

                if (diveLocation == null)
                {
                    Monitor.Log($"No dive destination for this point on this map", LogLevel.Debug);
                    return;
                }

                if (Game1.getLocationFromName(diveLocation.OtherMapName) == null)
                {
                    Monitor.Log($"Can't find destination map named {diveLocation.OtherMapName}", LogLevel.Warn);
                    return;
                }

                Monitor.Log($"warping to {diveLocation.OtherMapName}", LogLevel.Debug);
                SwimUtils.DiveTo(diveLocation);
                return;
            }

            if (e.Button == Config.SwimKey && (!Game1.player.swimming || !Config.ReadyToSwim) && !isJumping)
            {
                Config.ReadyToSwim = !Config.ReadyToSwim;
                Helper.WriteConfig <ModConfig>(Config);
                Monitor.Log($"Ready to swim: {Config.ReadyToSwim}");
                return;
            }

            if (e.Button == Config.SwimSuitKey)
            {
                Config.SwimSuitAlways = !Config.SwimSuitAlways;
                Helper.WriteConfig <ModConfig>(Config);
                if (!Game1.player.swimming)
                {
                    if (!Config.SwimSuitAlways)
                    {
                        Game1.player.changeOutOfSwimSuit();
                    }
                    else
                    {
                        Game1.player.changeIntoSwimsuit();
                    }
                }
                return;
            }
        }
 public static void GameLoop_DayStarted(object sender, DayStartedEventArgs e)
 {
     foreach (KeyValuePair <string, DiveMap> kvp in ModEntry.diveMaps)
     {
         GameLocation location = Game1.getLocationFromName(kvp.Key);
         if (location == null)
         {
             Monitor.Log($"GameLocation {kvp.Key} not found in day started loop");
             continue;
         }
         if (kvp.Value.Features.Contains("OceanTreasure") || kvp.Value.Features.Contains("OceanResources") || kvp.Value.Features.Contains("Minerals"))
         {
             Monitor.Log($"Clearing overlay objects from GameLocation {location.Name} ");
             location.overlayObjects.Clear();
         }
         if (kvp.Value.Features.Contains("OceanTreasure"))
         {
             Monitor.Log($"Adding ocean treasure to GameLocation {location.Name} ");
             SwimMaps.AddOceanTreasure(location);
         }
         if (kvp.Value.Features.Contains("OceanResources"))
         {
             Monitor.Log($"Adding ocean forage to GameLocation {location.Name} ");
             SwimMaps.AddOceanForage(location);
         }
         if (kvp.Value.Features.Contains("Minerals"))
         {
             Monitor.Log($"Adding minerals to GameLocation {location.Name} ");
             SwimMaps.AddMinerals(location);
         }
         if (kvp.Value.Features.Contains("SmolFishies") || kvp.Value.Features.Contains("BigFishies") || kvp.Value.Features.Contains("Crabs"))
         {
             Monitor.Log($"Clearing characters from GameLocation {location.Name} ");
             location.characters.Clear();
         }
         if (kvp.Value.Features.Contains("SmolFishies"))
         {
             Monitor.Log($"Adding smol fishies to GameLocation {location.Name} ");
             SwimMaps.AddFishies(location);
         }
         if (kvp.Value.Features.Contains("BigFishies"))
         {
             Monitor.Log($"Adding big fishies to GameLocation {location.Name} ");
             SwimMaps.AddFishies(location, false);
         }
         if (kvp.Value.Features.Contains("Crabs"))
         {
             Monitor.Log($"Adding crabs to GameLocation {location.Name} ");
             SwimMaps.AddCrabs(location);
         }
         if (kvp.Value.Features.Contains("WaterTiles"))
         {
             Monitor.Log($"Adding water tiles to GameLocation {location.Name} ");
             SwimMaps.AddWaterTiles(location);
         }
         if (kvp.Value.Features.Contains("Underwater"))
         {
             Monitor.Log($"Removing water tiles from GameLocation {location.Name} ");
             SwimMaps.RemoveWaterTiles(location);
         }
     }
     if (Game1.getLocationFromName("ScubaCave") != null && !Game1.player.mailReceived.Contains("ScubaMask"))
     {
         SwimMaps.AddScubaChest(Game1.getLocationFromName("ScubaCave"), new Vector2(10, 14), "ScubaMask");
     }
     ModEntry.marinerQuestionsWrongToday = false;
     ModEntry.oxygen = SwimUtils.MaxOxygen();
 }
        public static void GameLoop_SaveLoaded(object sender, SaveLoadedEventArgs e)
        {
            // load scuba gear ids

            if (ModEntry.JsonAssets != null)
            {
                ModEntry.scubaMaskID = ModEntry.JsonAssets.GetHatId("Scuba Mask");
                ModEntry.scubaTankID = ModEntry.JsonAssets.GetClothingId("Scuba Tank");

                if (ModEntry.scubaMaskID == -1)
                {
                    Monitor.Log("Can't get ID for Swim mod item #1. Some functionality will be lost.");
                }
                else
                {
                    Monitor.Log(string.Format("Swim mod item #1 ID is {0}.", ModEntry.scubaMaskID));
                }

                if (ModEntry.scubaTankID == -1)
                {
                    Monitor.Log("Can't get ID for Swim mod item #2. Some functionality will be lost.");
                }
                else
                {
                    Monitor.Log(string.Format("Swim mod item #2 ID is {0}.", ModEntry.scubaTankID));
                }

                try
                {
                    ModEntry.scubaFinsID = Helper.Content.Load <Dictionary <int, string> >(@"Data/Boots", ContentSource.GameContent).First(x => x.Value.StartsWith("Scuba Fins")).Key;
                }
                catch
                {
                    Monitor.Log("Can't get ID for Swim mod item #3. Some functionality will be lost.");
                }
                if (ModEntry.scubaFinsID != -1)
                {
                    Monitor.Log(string.Format("Swim mod item #3 ID is {0}.", ModEntry.scubaFinsID));
                    if (Game1.player.boots != null && Game1.player.boots.Value != null && Game1.player.boots.Value.Name == "Scuba Fins" && Game1.player.boots.Value.parentSheetIndex != ModEntry.scubaFinsID)
                    {
                        Game1.player.boots.Value = new Boots(ModEntry.scubaFinsID);
                    }
                }
            }

            // load dive maps

            foreach (IContentPack contentPack in Helper.ContentPacks.GetOwned())
            {
                try
                {
                    Monitor.Log($"Reading content pack: {contentPack.Manifest.Name} {contentPack.Manifest.Version} from {contentPack.DirectoryPath}");
                    DiveMapData data = contentPack.ReadJsonFile <DiveMapData>("content.json");
                    SwimUtils.ReadDiveMapData(data);
                }
                catch
                {
                    Monitor.Log($"couldn't read content.json in content pack {contentPack.Manifest.Name}", LogLevel.Warn);
                }
            }

            Monitor.Log($"Reading content pack from assets/swim-map-content.json");

            try
            {
                DiveMapData myData = Helper.Data.ReadJsonFile <DiveMapData>("assets/swim-map-content.json");
                SwimUtils.ReadDiveMapData(myData);
            }
            catch (Exception ex)
            {
                Monitor.Log($"assets/swim-map-content.json file read error. Exception: {ex}", LogLevel.Warn);
            }

            if (!SwimUtils.IsWearingScubaGear() && Config.SwimSuitAlways)
            {
                Game1.player.changeIntoSwimsuit();
            }

            bubbleTexture = Helper.Content.Load <Texture2D>("LooseSprites/temporary_sprites_1", ContentSource.GameContent);
        }
Exemple #16
0
        public static void AddMinerals(GameLocation l)
        {
            List <Vector2> spots = new List <Vector2>();

            for (int x = 0; x < l.map.Layers[0].LayerWidth; x++)
            {
                for (int y = 0; y < l.map.Layers[0].LayerHeight; y++)
                {
                    Tile tile = l.map.GetLayer("Back").PickTile(new Location(x, y) * Game1.tileSize, Game1.viewport.Size);
                    if (tile != null && l.map.GetLayer("Buildings").PickTile(new Location(x, y) * Game1.tileSize, Game1.viewport.Size) == null && l.map.GetLayer("Front").PickTile(new Location(x, y) * Game1.tileSize, Game1.viewport.Size) == null)
                    {
                        spots.Add(new Vector2(x, y));
                    }
                }
            }
            int n = spots.Count;

            while (n > 1)
            {
                n--;
                int k     = Game1.random.Next(n + 1);
                var value = spots[k];
                spots[k] = spots[n];
                spots[n] = value;
            }

            int            mineralNo    = (int)Math.Round(Game1.random.Next(Config.MineralPerThousandMin, Config.MineralPerThousandMax) / 1000f * spots.Count);
            List <Vector2> mineralSpots = spots.Take(mineralNo).ToList();

            foreach (Vector2 tile in mineralSpots)
            {
                double chance = Game1.random.NextDouble();

                if (chance < 0.2 && !l.map.GetLayer("Back").Tiles[(int)tile.X, (int)tile.Y].Properties.ContainsKey("Treasure") && !l.map.GetLayer("Back").Tiles[(int)tile.X, (int)tile.Y].Properties.ContainsKey("Diggable"))
                {
                    l.map.GetLayer("Back").Tiles[(int)tile.X, (int)tile.Y].TileIndex = 1299;
                    l.map.GetLayer("Back").Tiles[(int)tile.X, (int)tile.Y].Properties.Add("Treasure", new PropertyValue("Object " + SwimUtils.CheckForBuriedItem(Game1.player)));
                    l.map.GetLayer("Back").Tiles[(int)tile.X, (int)tile.Y].Properties.Add("Diggable", new PropertyValue("T"));
                }
                else if (chance < 0.4)
                {
                    l.overlayObjects[tile] = new StardewValley.Object(tile, 751, "Stone", true, false, false, false)
                    {
                        MinutesUntilReady = 2
                    };
                }
                else if (chance < 0.5)
                {
                    l.overlayObjects[tile] = new StardewValley.Object(tile, 290, "Stone", true, false, false, false)
                    {
                        MinutesUntilReady = 4
                    };
                }
                else if (chance < 0.55)
                {
                    l.overlayObjects[tile] = new StardewValley.Object(tile, 764, "Stone", true, false, false, false)
                    {
                        MinutesUntilReady = 8
                    };
                }
                else if (chance < 0.56)
                {
                    l.overlayObjects[tile] = new StardewValley.Object(tile, 765, "Stone", true, false, false, false)
                    {
                        MinutesUntilReady = 16
                    };
                }
                else if (chance < 0.65)
                {
                    l.overlayObjects[tile] = new StardewValley.Object(tile, 80, "Stone", true, true, false, true);
                }
                else if (chance < 0.74)
                {
                    l.overlayObjects[tile] = new StardewValley.Object(tile, 82, "Stone", true, true, false, true);
                }
                else if (chance < 0.83)
                {
                    l.overlayObjects[tile] = new StardewValley.Object(tile, 84, "Stone", true, true, false, true);
                }
                else if (chance < 0.90)
                {
                    l.overlayObjects[tile] = new StardewValley.Object(tile, 86, "Stone", true, true, false, true);
                }
                else
                {
                    int[] gems     = { 4, 6, 8, 10, 12, 14, 40 };
                    int   whichGem = gems[Game1.random.Next(gems.Length)];
                    l.overlayObjects[tile] = new StardewValley.Object(tile, whichGem, "Stone", true, false, false, false)
                    {
                        MinutesUntilReady = 5
                    };
                }
            }
        }
        public static void GameLoop_UpdateTicked(object sender, UpdateTickedEventArgs e)
        {
            if (Game1.player.currentLocation == null || Game1.player == null || !Game1.displayFarmer || Game1.player.position == null)
            {
                return;
            }

            ModEntry.isUnderwater = SwimUtils.IsMapUnderwater(Game1.player.currentLocation.Name);

            if (Game1.player.currentLocation.Name == "ScubaAbigailCave")
            {
                AbigailCaveTick();
            }

            if (Game1.activeClickableMenu == null)
            {
                if (ModEntry.isUnderwater)
                {
                    if (ModEntry.oxygen >= 0)
                    {
                        if (!SwimUtils.IsWearingScubaGear())
                        {
                            ModEntry.oxygen--;
                        }
                        else
                        {
                            if (ModEntry.oxygen < SwimUtils.MaxOxygen())
                            {
                                ModEntry.oxygen++;
                            }
                            if (ModEntry.oxygen < SwimUtils.MaxOxygen())
                            {
                                ModEntry.oxygen++;
                            }
                        }
                    }
                    if (ModEntry.oxygen < 0 && !surfacing)
                    {
                        surfacing = true;
                        Game1.playSound("pullItemFromWater");
                        DiveLocation diveLocation = ModEntry.diveMaps[Game1.player.currentLocation.Name].DiveLocations.Last();
                        SwimUtils.DiveTo(diveLocation);
                    }
                }
                else
                {
                    surfacing = false;
                    if (ModEntry.oxygen < SwimUtils.MaxOxygen())
                    {
                        ModEntry.oxygen++;
                    }
                    if (ModEntry.oxygen < SwimUtils.MaxOxygen())
                    {
                        ModEntry.oxygen++;
                    }
                }
            }

            if (SwimUtils.IsWearingScubaGear())
            {
                ticksWearingScubaGear++;
                if (Config.BreatheSound && breatheEffect != null && (lastBreatheSound == 0 || ticksWearingScubaGear - lastBreatheSound > 6000 / 16))
                {
                    Monitor.Log("Playing breathe sound");
                    lastBreatheSound = ticksWearingScubaGear;
                    breatheEffect.Play(0.5f * Game1.options.soundVolumeLevel, 0f, 0f);
                }
            }
            else
            {
                if (breatheEffect != null && lastBreatheSound != 0)
                {
                    breatheEffect.Dispose();
                    LoadBreatheSound();
                }
                lastBreatheSound      = 0;
                ticksWearingScubaGear = 0;
            }

            if (isJumping)
            {
                float difx      = endJumpLoc.X - startJumpLoc.X;
                float dify      = endJumpLoc.Y - startJumpLoc.Y;
                float completed = Game1.player.freezePause / (float)Config.JumpTimeInMilliseconds;
                if (Game1.player.freezePause <= 0)
                {
                    Game1.player.position.Value = endJumpLoc;
                    isJumping = false;
                    if (ModEntry.willSwim)
                    {
                        Game1.player.currentLocation.playSound("waterSlosh", NetAudio.SoundContext.Default);
                        Game1.player.swimming.Value = true;
                    }
                    else
                    {
                        if (!Config.SwimSuitAlways)
                        {
                            Game1.player.changeOutOfSwimSuit();
                        }
                    }
                    return;
                }
                Game1.player.position.Value = new Vector2(endJumpLoc.X - (difx * completed), endJumpLoc.Y - (dify * completed) - (float)Math.Sin(completed * Math.PI) * 64);
                return;
            }

            // only if ready to swim from here on!

            if (!Config.ReadyToSwim || !Context.IsPlayerFree)
            {
                return;
            }

            if (Game1.player.swimming)
            {
                if (!SwimUtils.IsInWater() && !isJumping)
                {
                    Monitor.Log("Swimming out of water");
                    ModEntry.willSwim        = false;
                    Game1.player.freezePause = Config.JumpTimeInMilliseconds;
                    Game1.player.currentLocation.playSound("dwop", NetAudio.SoundContext.Default);
                    Game1.player.currentLocation.playSound("waterSlosh", NetAudio.SoundContext.Default);
                    isJumping    = true;
                    startJumpLoc = Game1.player.position.Value;
                    endJumpLoc   = Game1.player.position.Value;

                    Game1.player.swimming.Value = false;
                    if (Game1.player.bathingClothes && !Config.SwimSuitAlways)
                    {
                        Game1.player.changeOutOfSwimSuit();
                    }
                }

                DiveMap dm      = null;
                Point   edgePos = Game1.player.getTileLocationPoint();

                if (ModEntry.diveMaps.ContainsKey(Game1.player.currentLocation.Name))
                {
                    dm = ModEntry.diveMaps[Game1.player.currentLocation.Name];
                }

                if (Game1.player.position.Y > Game1.viewport.Y + Game1.viewport.Height - 16)
                {
                    Game1.player.position.Value = new Vector2(Game1.player.position.X, Game1.viewport.Y + Game1.viewport.Height - 17);
                    if (dm != null)
                    {
                        EdgeWarp edge = dm.EdgeWarps.Find((x) => x.ThisMapEdge == "Bottom" && x.FirstTile <= edgePos.X && x.LastTile >= edgePos.X);
                        if (edge != null)
                        {
                            Point pos = SwimUtils.GetEdgeWarpDestination(edgePos.X, edge);
                            if (pos != Point.Zero)
                            {
                                Monitor.Log("warping south");
                                Game1.warpFarmer(edge.OtherMapName, pos.X, pos.Y, false);
                            }
                        }
                    }
                }
                else if (Game1.player.position.Y < Game1.viewport.Y - 16)
                {
                    Game1.player.position.Value = new Vector2(Game1.player.position.X, Game1.viewport.Y - 15);

                    if (dm != null)
                    {
                        EdgeWarp edge = dm.EdgeWarps.Find((x) => x.ThisMapEdge == "Top" && x.FirstTile <= edgePos.X && x.LastTile >= edgePos.X);
                        if (edge != null)
                        {
                            Point pos = SwimUtils.GetEdgeWarpDestination(edgePos.X, edge);
                            if (pos != Point.Zero)
                            {
                                Monitor.Log("warping north");
                                Game1.warpFarmer(edge.OtherMapName, pos.X, pos.Y, false);
                            }
                        }
                    }
                }
                else if (Game1.player.position.X > Game1.viewport.X + Game1.viewport.Width - 32)
                {
                    Game1.player.position.Value = new Vector2(Game1.viewport.X + Game1.viewport.Width - 33, Game1.player.position.Y);

                    if (dm != null)
                    {
                        EdgeWarp edge = dm.EdgeWarps.Find((x) => x.ThisMapEdge == "Right" && x.FirstTile <= edgePos.Y && x.LastTile >= edgePos.Y);
                        if (edge != null)
                        {
                            Point pos = SwimUtils.GetEdgeWarpDestination(edgePos.Y, edge);
                            if (pos != Point.Zero)
                            {
                                Monitor.Log("warping east");
                                Game1.warpFarmer(edge.OtherMapName, pos.X, pos.Y, false);
                            }
                        }
                    }

                    if (Game1.player.currentLocation.Name == "Forest")
                    {
                        if (Game1.player.position.Y / 64 > 74)
                        {
                            Game1.warpFarmer("Beach", 0, 13, false);
                        }
                        else
                        {
                            Game1.warpFarmer("Town", 0, 100, false);
                        }
                    }
                }
                else if (Game1.player.position.X < Game1.viewport.X - 32)
                {
                    Game1.player.position.Value = new Vector2(Game1.viewport.X - 31, Game1.player.position.Y);

                    if (dm != null)
                    {
                        EdgeWarp edge = dm.EdgeWarps.Find((x) => x.ThisMapEdge == "Left" && x.FirstTile <= edgePos.X && x.LastTile >= edgePos.X);
                        if (edge != null)
                        {
                            Point pos = SwimUtils.GetEdgeWarpDestination(edgePos.Y, edge);
                            if (pos != Point.Zero)
                            {
                                Monitor.Log("warping west");
                                Game1.warpFarmer(edge.OtherMapName, pos.X, pos.Y, false);
                            }
                        }
                    }

                    if (Game1.player.currentLocation.Name == "Town")
                    {
                        Game1.warpFarmer("Forest", 119, 43, false);
                    }
                    else if (Game1.player.currentLocation.Name == "Beach")
                    {
                        Game1.warpFarmer("Forest", 119, 111, false);
                    }
                }

                if (Game1.player.bathingClothes && SwimUtils.IsWearingScubaGear() && !Config.SwimSuitAlways)
                {
                    Game1.player.changeOutOfSwimSuit();
                }
                else if (!Game1.player.bathingClothes && (!SwimUtils.IsWearingScubaGear() || Config.SwimSuitAlways))
                {
                    Game1.player.changeIntoSwimsuit();
                }

                if (Game1.player.boots.Value != null && ModEntry.scubaFinsID != -1 && Game1.player.boots.Value.indexInTileSheet == ModEntry.scubaFinsID)
                {
                    int  buffId = 42883167;
                    Buff buff   = Game1.buffsDisplay.otherBuffs.FirstOrDefault((Buff p) => p.which == buffId);
                    if (buff == null)
                    {
                        BuffsDisplay buffsDisplay = Game1.buffsDisplay;
                        Buff         buff2        = new Buff(0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, "Scuba Fins", Helper.Translation.Get("scuba-fins"));
                        buff2.which = buffId;
                        buff        = buff2;
                        buffsDisplay.addOtherBuff(buff2);
                    }
                    buff.millisecondsDuration = 50;
                }
            }
            else
            {
                if (SwimUtils.IsInWater() && !isJumping)
                {
                    Monitor.Log("In water not swimming");

                    ModEntry.willSwim        = true;
                    Game1.player.freezePause = Config.JumpTimeInMilliseconds;
                    Game1.player.currentLocation.playSound("dwop", NetAudio.SoundContext.Default);
                    isJumping    = true;
                    startJumpLoc = Game1.player.position.Value;
                    endJumpLoc   = Game1.player.position.Value;


                    Game1.player.swimming.Value = true;
                    if (!Game1.player.bathingClothes && !SwimUtils.IsWearingScubaGear())
                    {
                        Game1.player.changeIntoSwimsuit();
                    }
                }
            }

            SwimUtils.CheckIfMyButtonDown();

            if (!ModEntry.myButtonDown || Game1.player.millisecondsPlayed - lastJump < 250 || SwimUtils.IsMapUnderwater(Game1.player.currentLocation.Name))
            {
                return;
            }

            if (Helper.Input.IsDown(SButton.MouseLeft) && !Game1.player.swimming && (Game1.player.CurrentTool is WateringCan || Game1.player.CurrentTool is FishingRod))
            {
                return;
            }


            List <Vector2> tiles        = SwimUtils.GetTilesInDirection(5);
            Vector2        jumpLocation = Vector2.Zero;

            double distance    = -1;
            int    maxDistance = 0;

            switch (Game1.player.FacingDirection)
            {
            case 0:
                distance    = Math.Abs(Game1.player.position.Y - tiles.Last().Y *Game1.tileSize);
                maxDistance = 72;
                break;

            case 2:
                distance    = Math.Abs(Game1.player.position.Y - tiles.Last().Y *Game1.tileSize);
                maxDistance = 48;
                break;

            case 1:
            case 3:
                distance    = Math.Abs(Game1.player.position.X - tiles.Last().X *Game1.tileSize);
                maxDistance = 65;
                break;
            }
            if (Helper.Input.IsDown(SButton.MouseLeft))
            {
                try
                {
                    int  xTile = (Game1.viewport.X + Game1.getOldMouseX()) / 64;
                    int  yTile = (Game1.viewport.Y + Game1.getOldMouseY()) / 64;
                    bool water = Game1.player.currentLocation.waterTiles[xTile, yTile];
                    if (Game1.player.swimming != water)
                    {
                        distance = -1;
                    }
                }
                catch
                {
                }
            }
            //Monitor.Log("Distance: " + distance);

            bool nextToLand = Game1.player.swimming && !Game1.player.currentLocation.isTilePassable(new Location((int)tiles.Last().X, (int)tiles.Last().Y), Game1.viewport) && !SwimUtils.IsWaterTile(tiles[tiles.Count - 2]) && distance < maxDistance;

            bool nextToWater = false;

            try
            {
                nextToWater = !Game1.player.swimming &&
                              !SwimUtils.IsTilePassable(Game1.player.currentLocation, new Location((int)tiles.Last().X, (int)tiles.Last().Y), Game1.viewport) &&
                              (Game1.player.currentLocation.waterTiles[(int)tiles.Last().X, (int)tiles.Last().Y] ||
                               SwimUtils.IsWaterTile(tiles[tiles.Count - 2])) &&
                              distance < maxDistance;
            }
            catch
            {
                //Monitor.Log($"exception trying to get next to water: {ex}");
            }

            //Monitor.Log($"next passable {Game1.player.currentLocation.isTilePassable(new Location((int)tiles.Last().X, (int)tiles.Last().Y), Game1.viewport)} next to land: {nextToLand}, next to water: {nextToWater}");


            if (Helper.Input.IsDown(Config.SwimKey) || nextToLand || nextToWater)
            {
                //Monitor.Log("okay to jump");
                for (int i = 0; i < tiles.Count; i++)
                {
                    Vector2 tileV      = tiles[i];
                    bool    isWater    = false;
                    bool    isPassable = false;
                    try
                    {
                        Tile tile = Game1.player.currentLocation.map.GetLayer("Buildings").PickTile(new Location((int)tileV.X * Game1.tileSize, (int)tileV.Y * Game1.tileSize), Game1.viewport.Size);
                        isWater    = SwimUtils.IsWaterTile(tileV);
                        isPassable = (nextToLand && !isWater && SwimUtils.IsTilePassable(Game1.player.currentLocation, new Location((int)tileV.X, (int)tileV.Y), Game1.viewport)) || (nextToWater && isWater && (tile == null || tile.TileIndex == 76));
                        //Monitor.Log($"Trying {tileV} is passable {isPassable} isWater {isWater}");
                        if (!SwimUtils.IsTilePassable(Game1.player.currentLocation, new Location((int)tileV.X, (int)tileV.Y), Game1.viewport) && !isWater && nextToLand)
                        {
                            //Monitor.Log($"Nixing {tileV}");
                            jumpLocation = Vector2.Zero;
                        }
                    }
                    catch (Exception ex)
                    {
                        Monitor.Log("" + ex);
                    }
                    if (nextToLand && !isWater && isPassable)
                    {
                        Monitor.Log($"Jumping to {tileV}");
                        jumpLocation = tileV;
                    }

                    if (nextToWater && isWater && isPassable)
                    {
                        Monitor.Log($"Jumping to {tileV}");
                        jumpLocation = tileV;
                    }
                }
            }

            if (jumpLocation != Vector2.Zero)
            {
                lastJump = Game1.player.millisecondsPlayed;
                //Monitor.Log("got swim location");
                if (Game1.player.swimming)
                {
                    ModEntry.willSwim           = false;
                    Game1.player.swimming.Value = false;
                    Game1.player.freezePause    = Config.JumpTimeInMilliseconds;
                    Game1.player.currentLocation.playSound("dwop", NetAudio.SoundContext.Default);
                    Game1.player.currentLocation.playSound("waterSlosh", NetAudio.SoundContext.Default);
                }
                else
                {
                    ModEntry.willSwim = true;
                    if (!SwimUtils.IsWearingScubaGear())
                    {
                        Game1.player.changeIntoSwimsuit();
                    }

                    Game1.player.freezePause = Config.JumpTimeInMilliseconds;
                    Game1.player.currentLocation.playSound("dwop", NetAudio.SoundContext.Default);
                }
                isJumping    = true;
                startJumpLoc = Game1.player.position.Value;
                endJumpLoc   = new Vector2(jumpLocation.X * Game1.tileSize, jumpLocation.Y * Game1.tileSize);
            }
        }