private void AddModOrGrass(Vector2 location) { // We have 4 kinds of things that a mod can add: // largeterrainfeatures, terrainfeatures, resourceclumps and objects. // To create a truly random order, we shuffle the kind of things (using lambdas in a list), // and then we shuffle the callbacks provided by mods. foreach (var action in DeepWoodsAPI.ToShuffledList(new List <Func <bool> >() { () => { foreach (var modLargeTerrainFeature in DeepWoodsAPI.ToShuffledList(ModEntry.GetAPI().LargeTerrainFeatures)) { if (modLargeTerrainFeature.Item1(deepWoods, location)) { deepWoods.largeTerrainFeatures.Add(modLargeTerrainFeature.Item2()); return(true); } } return(false); }, () => { foreach (var modResourceClump in DeepWoodsAPI.ToShuffledList(ModEntry.GetAPI().ResourceClumps)) { if (modResourceClump.Item1(deepWoods, location)) { deepWoods.resourceClumps.Add(modResourceClump.Item2()); return(true); } } return(false); }, () => { foreach (var modTerrainFeature in DeepWoodsAPI.ToShuffledList(ModEntry.GetAPI().TerrainFeatures)) { if (modTerrainFeature.Item1(deepWoods, location)) { deepWoods.terrainFeatures[location] = modTerrainFeature.Item2(); return(true); } } return(false); }, () => { foreach (var modObject in DeepWoodsAPI.ToShuffledList(ModEntry.GetAPI().Objects)) { if (modObject.Item1(deepWoods, location)) { deepWoods.objects[location] = modObject.Item2(); return(true); } } return(false); } })) { if (action()) { // A mod added something, return return; } } // Mods didn't add anything, add grass deepWoods.terrainFeatures[location] = new LootFreeGrass(GetSeasonGrassType(), this.random.GetRandomValue(1, 3)); }
// Called whenever a player warps, both from and to may be null public static void PlayerWarped(Farmer who, GameLocation rawFrom, GameLocation rawTo) { DeepWoods from = rawFrom as DeepWoods; DeepWoods to = rawTo as DeepWoods; if (from != null && to != null && from.Name == to.Name) { return; } from?.RemovePlayer(who); to?.AddPlayer(who); // everything that follows should only be done if this is the local player if (who != Game1.player) { ModEntry.Log("Player (" + who.UniqueMultiplayerID + ") warped from: " + rawFrom?.Name + ", to: " + rawTo?.Name, LogLevel.Trace); return; } ModEntry.Log("Local Player (" + who.UniqueMultiplayerID + ") warped from: " + rawFrom?.Name + ", to: " + rawTo?.Name, LogLevel.Trace); if (rawTo is Woods woods) { OpenPassageInSecretWoods(woods); } if (from != null && to == null) { // We left the deepwoods, fix lighting DeepWoodsManager.FixLighting(); // Stop music Game1.changeMusicTrack("none"); Game1.updateMusic(); // Workaround for bug where players are warped to [0,0] for some reason if (rawTo is Woods) { who.Position = new Vector2(WOODS_WARP_LOCATION.X * 64, WOODS_WARP_LOCATION.Y * 64); } } if (from != null && to != null && from.Parent == null && to.Parent == from && !lostMessageDisplayedToday && !to.spawnedFromObelisk.Value && ExitDirToEnterDir(CastEnterDirToExitDir(from.EnterDir)) == to.EnterDir) { Game1.addHUDMessage(new HUDMessage(I18N.LostMessage) { noIcon = true }); lostMessageDisplayedToday = true; } if (to != null && to.level.Value >= Settings.Level.MinLevelForWoodsObelisk && !Game1.player.hasOrWillReceiveMail(WOODS_OBELISK_WIZARD_MAIL_ID) && (Game1.player.mailReceived.Contains("hasPickedUpMagicInk") || Game1.player.hasMagicInk)) { Game1.addMailForTomorrow(WOODS_OBELISK_WIZARD_MAIL_ID); } }
private static void OpenPassageInSecretWoods(Woods woods) { // Game isn't running if (!ModEntry.IsDeepWoodsGameRunning) { ModEntry.Log("OpenPassageInSecretWoods: Cancelled, mod not initialized.", LogLevel.Trace); return; } // If warps exist, the map might be patched already, but we can't be 100% sure // So we just use this as an indicator not to print any warnings about stuff already being patched we might encounter further down. var existingWarpLocations = woods.warps.Where(warp => "DeepWoods".Equals(warp.TargetName)).Select(warp => new SimpleCoord(warp.X, warp.Y)); bool possiblyPatchedAlready = existingWarpLocations.Any(); Layer buildingsLayer = woods.map.GetLayer("Buildings"); // Just to be sure if (buildingsLayer == null) { ModEntry.Log("OpenPassageInSecretWoods: Cancelled, invalid map (buildingsLayer is null).", LogLevel.Trace); return; } ModEntry.Log("OpenPassageInSecretWoods:", LogLevel.Trace); TileSheet borderTileSheet = woods.map.TileSheets.First(); int borderTileIndex = 0; int removed = 0; int added = 0; int warpsAdded = 0; foreach (var location in Settings.WoodsPassage.DeleteBuildingTiles) { if (buildingsLayer.Tiles[location.X, location.Y] == null) { if (!possiblyPatchedAlready) { ModEntry.Log($" Can't remove tile from building layer at {location.X}, {location.Y}, there is no tile here! (Custom Woods map? Please modify WoodsPassage settings in the DeepWoods config file for custom Woods maps.)", LogLevel.Trace); } } else { ModEntry.Log($" Removing tile from building layer at {location.X}, {location.Y}.", LogLevel.Trace); buildingsLayer.Tiles[location.X, location.Y] = null; removed++; } } foreach (var location in Settings.WoodsPassage.AddBuildingTiles) { if (buildingsLayer.Tiles[location.X, location.Y] == null) { ModEntry.Log($" Adding tile to building layer at {location.X}, {location.Y}.", LogLevel.Trace); buildingsLayer.Tiles[location.X, location.Y] = new StaticTile(buildingsLayer, borderTileSheet, BlendMode.Alpha, borderTileIndex); added++; } else { if (!possiblyPatchedAlready) { ModEntry.Log($" Can't add tile to building layer at {location.X}, {location.Y}, already have a tile there! (Custom Woods map? Please modify WoodsPassage settings in the DeepWoods config file for custom Woods maps.)", LogLevel.Trace); } } } foreach (var location in Settings.WoodsPassage.WarpLocations) { if (!existingWarpLocations.Contains(location)) { ModEntry.Log($" Adding warp to DeepWoods at {location.X}, {location.Y}.", LogLevel.Trace); woods.warps.Add(new Warp(location.X, location.Y, "DeepWoods", Settings.Map.RootLevelEnterLocation.X, Settings.Map.RootLevelEnterLocation.Y + 1, false)); warpsAdded++; } } if (possiblyPatchedAlready && added == 0 && removed == 0 && warpsAdded == 0) { ModEntry.Log($"OpenPassageInSecretWoods skipped. Map was already patched.", LogLevel.Trace); } else { ModEntry.Log($"OpenPassageInSecretWoods done. (Added {added}/{Settings.WoodsPassage.AddBuildingTiles.Length} tiles, removed {removed}/{Settings.WoodsPassage.DeleteBuildingTiles.Length} tiles, added {warpsAdded}/{Settings.WoodsPassage.WarpLocations.Length} warps.)", LogLevel.Trace); } }
private void DoDeath(GameLocation location, Vector2 tileLocation) { DelayedAction.playSoundAfterDelay("leafrustle", 100, (GameLocation)null); Color color = Color.Green; string currentSeason = Game1.currentSeason; if (!(currentSeason == "spring")) { if (!(currentSeason == "summer")) { if (!(currentSeason == "fall")) { if (currentSeason == "winter") { color = Color.Cyan; } } else { color = Color.IndianRed; } } else { color = Color.ForestGreen; } } else { color = Color.Green; } for (int index1 = 0; index1 <= this.size.Value; ++index1) { for (int index2 = 0; index2 < 12; ++index2) { ModEntry.GetMultiplayer().broadcastSprites(location, new TemporaryAnimatedSprite[1] { new TemporaryAnimatedSprite("LooseSprites\\Cursors", new Rectangle(355, 1200 + (Game1.IsFall ? 16 : (Game1.IsWinter ? -16 : 0)), 16, 16), Utility.getRandomPositionInThisRectangle(this.getBoundingBox(), Game1.random) - new Vector2(0.0f, (float)Game1.random.Next(64)), false, 0.01f, Game1.IsWinter ? Color.Cyan : Color.White) { motion = new Vector2((float)Game1.random.Next(-10, 11) / 10f, (float)-Game1.random.Next(5, 7)), acceleration = new Vector2(0.0f, (float)Game1.random.Next(13, 17) / 100f), accelerationChange = new Vector2(0.0f, -1f / 1000f), scale = 4f, layerDepth = (float)((double)tileLocation.Y * 64.0 / 10000.0), animationLength = 11, totalNumberOfLoops = 99, interval = (float)Game1.random.Next(20, 90), delayBeforeAnimationStart = (index1 + 1) * index2 * 20 } }); if (index2 % 6 == 0) { ModEntry.GetMultiplayer().broadcastSprites(location, new TemporaryAnimatedSprite[1] { new TemporaryAnimatedSprite(50, Utility.getRandomPositionInThisRectangle(this.getBoundingBox(), Game1.random) - new Vector2(32f, (float)Game1.random.Next(32, 64)), color, 8, false, 100f, 0, -1, -1f, -1, 0) }); ModEntry.GetMultiplayer().broadcastSprites(location, new TemporaryAnimatedSprite[1] { new TemporaryAnimatedSprite(12, Utility.getRandomPositionInThisRectangle(this.getBoundingBox(), Game1.random) - new Vector2(32f, (float)Game1.random.Next(32, 64)), Color.White, 8, false, 100f, 0, -1, -1f, -1, 0) }); } } } }
// This method is also called by the patch in DeepWoodsMTNCompatibilityMod. // We return false when we handled this message, so Harmony will cancel the original MTN handler. private static bool InternalProcessIncomingMessage(IncomingMessage msg) { if (msg.MessageType == Settings.Network.DeepWoodsMessageId) { int deepwoodsMessageType = msg.Reader.ReadInt32(); int randId = Game1.random.Next(); ModEntry.Log("InterceptProcessIncomingMessage[" + randId + "], master id: " + Game1.MasterPlayer.UniqueMultiplayerID + ", local id: " + Game1.player.UniqueMultiplayerID + ", msg.FarmerID: " + msg.FarmerID + ", deepwoodsMessageType: " + deepwoodsMessageType, StardewModdingAPI.LogLevel.Debug); Farmer who = Game1.getFarmer(msg.FarmerID); if (who == null || who == Game1.player) { ModEntry.Log(" who is null or local!", StardewModdingAPI.LogLevel.Warn); return(true); // execute original } if (deepwoodsMessageType == NETWORK_MESSAGE_DEEPWOODS_INIT) { ModEntry.Log(" [" + randId + "] deepwoodsMessageType == NETWORK_MESSAGE_DEEPWOODS_INIT", StardewModdingAPI.LogLevel.Debug); if (Game1.IsMasterGame) { // Client requests settings and state, send it: List <string> deepWoodsLevelNames = new List <string>(); foreach (var location in Game1.locations) { if (location is DeepWoods deepWoods) { deepWoodsLevelNames.Add(deepWoods.Name); } } object[] data = new object[deepWoodsLevelNames.Count + 4]; data[0] = NETWORK_MESSAGE_DEEPWOODS_INIT; data[1] = JsonConvert.SerializeObject(Settings); data[2] = JsonConvert.SerializeObject(DeepWoodsState); data[3] = (int)deepWoodsLevelNames.Count; for (int i = 0; i < deepWoodsLevelNames.Count; i++) { data[i + 4] = deepWoodsLevelNames[i]; } ModEntry.Log(" [" + randId + "] Client requests settings and state, deepWoodsLevelNames.Count: " + deepWoodsLevelNames.Count + ", deepWoodsLevelNames: " + String.Join(", ", deepWoodsLevelNames.ToArray()), StardewModdingAPI.LogLevel.Debug); who.queueMessage(Settings.Network.DeepWoodsMessageId, Game1.MasterPlayer, data); } else { // Server sent us settings and state! Settings = JsonConvert.DeserializeObject <DeepWoodsSettings>(msg.Reader.ReadString()); DeepWoodsState = JsonConvert.DeserializeObject <DeepWoodsStateData>(msg.Reader.ReadString()); int numDeepWoodsLevelNames = msg.Reader.ReadInt32(); List <string> deepWoodsLevelNames = new List <string>(); for (int i = 0; i < numDeepWoodsLevelNames; i++) { deepWoodsLevelNames.Add(msg.Reader.ReadString()); } ModEntry.Log(" [" + randId + "] Server sent us settings and state, deepWoodsLevelNames.Count: " + deepWoodsLevelNames.Count + ", deepWoodsLevelNames: " + String.Join(", ", deepWoodsLevelNames.ToArray()), StardewModdingAPI.LogLevel.Debug); ModEntry.DeepWoodsInitServerAnswerReceived(deepWoodsLevelNames); } } else { if (!Game1.IsMasterGame && !ModEntry.IsDeepWoodsGameRunning) { if (ModEntry.HasRequestedInitMessageFromServer) { ModEntry.Log("Got message from server before init message!", StardewModdingAPI.LogLevel.Warn); } else { ModEntry.Log("Got message from server before init message, never sent init message request!", StardewModdingAPI.LogLevel.Warn); } } if (deepwoodsMessageType == NETWORK_MESSAGE_DEEPWOODS_WARP) { ModEntry.Log(" [" + randId + "] deepwoodsMessageType == NETWORK_MESSAGE_DEEPWOODS_WARP", StardewModdingAPI.LogLevel.Debug); DeepWoodsWarpMessageData data = ReadDeepWoodsWarpMessage(msg.Reader); if (Game1.IsMasterGame) { // Client requests that we load and activate a specific DeepWoods level they want to warp into. DeepWoods deepWoods = DeepWoodsManager.AddDeepWoodsFromObelisk(data.Level); // Send message to client telling them we have the level ready. ModEntry.Log(" [" + randId + "] Client requests that we load and activate a specific DeepWoods level they want to warp into: data.Level:" + data.Level, StardewModdingAPI.LogLevel.Debug); who.queueMessage(Settings.Network.DeepWoodsMessageId, Game1.MasterPlayer, new object[] { NETWORK_MESSAGE_DEEPWOODS_WARP, deepWoods.level.Value, deepWoods.Name, new Vector2(deepWoods.enterLocation.Value.X, deepWoods.enterLocation.Value.Y) }); } else { // Server informs us that we can warp now! ModEntry.Log(" [" + randId + "] Server informs us that we can warp now: data.Level:" + data.Level + ", data.Name:" + data.Name, StardewModdingAPI.LogLevel.Debug); DeepWoodsManager.AddBlankDeepWoodsToGameLocations(data.Name); DeepWoodsManager.WarpFarmerIntoDeepWoodsFromServerObelisk(data.Name, data.EnterLocation); } } else if (deepwoodsMessageType == NETWORK_MESSAGE_DEEPWOODS_LEVEL) { ModEntry.Log(" [" + randId + "] deepwoodsMessageType == NETWORK_MESSAGE_DEEPWOODS_LEVEL", StardewModdingAPI.LogLevel.Debug); if (!Game1.IsMasterGame && who == Game1.MasterPlayer) { DeepWoodsState.LowestLevelReached = msg.Reader.ReadInt32(); ModEntry.Log(" [" + randId + "] DeepWoodsState.LowestLevelReached: " + DeepWoodsState.LowestLevelReached, StardewModdingAPI.LogLevel.Debug); } } else if (deepwoodsMessageType == NETWORK_MESSAGE_RCVD_STARDROP_FROM_UNICORN) { ModEntry.Log(" [" + randId + "] deepwoodsMessageType == NETWORK_MESSAGE_RCVD_STARDROP_FROM_UNICORN", StardewModdingAPI.LogLevel.Debug); if (Game1.IsMasterGame) { DeepWoodsState.PlayersWhoGotStardropFromUnicorn.Add(who.UniqueMultiplayerID); } } else if (deepwoodsMessageType == NETWORK_MESSAGE_DEEPWOODS_ADDREMOVE) { ModEntry.Log(" [" + randId + "] deepwoodsMessageType == NETWORK_MESSAGE_DEEPWOODS_ADDREMOVE", StardewModdingAPI.LogLevel.Debug); if (!Game1.IsMasterGame) { bool added = msg.Reader.ReadByte() != 0; string name = msg.Reader.ReadString(); ModEntry.Log(" [" + randId + "] added: " + added + ", name: " + name, StardewModdingAPI.LogLevel.Debug); if (added) { DeepWoodsManager.AddBlankDeepWoodsToGameLocations(name); } else { DeepWoodsManager.RemoveDeepWoodsFromGameLocations(name); } } } else { ModEntry.Log(" [" + randId + "] unknown deepwoodsMessageType: " + deepwoodsMessageType + "!", StardewModdingAPI.LogLevel.Warn); return(true); // execute original } } return(false); // don't execute original } return(true); // execute original }
public override object GetApi() { return(ModEntry.GetAPI()); }
Monster CreateRandomMonster(Vector2 location) { Monster monster = null; if (Game1.isDarkOut() && CanHazMonster(Settings.Monsters.Bat)) { monster = new Bat(new Vector2()); } else if (Game1.isDarkOut() && CanHazMonster(Settings.Monsters.Ghost)) { monster = new Ghost(new Vector2()); } else if (CanHazMonster(Settings.Monsters.BigSlime)) { monster = new BigSlime(new Vector2(), GetSlimeLevel()); } else if (CanHazMonster(Settings.Monsters.Grub)) { monster = new Grub(new Vector2(), true); } else if (CanHazMonster(Settings.Monsters.Fly)) { monster = new Fly(new Vector2(), true); } else if (CanHazMonster(Settings.Monsters.Brute)) { monster = new ShadowBrute(new Vector2()); } else if (CanHazMonster(Settings.Monsters.Golem)) { monster = new RockGolem(new Vector2(), deepWoods.GetCombatLevel()); } else if (CanHazMonster(Settings.Monsters.RockCrab)) { monster = new RockCrab(new Vector2(), GetRockCrabType()); } else if (CanHazMonster(Settings.Monsters.Bug)) { monster = new Bug(new Vector2(), 121); monster.isHardModeMonster.Value = true; } else if (CanHazMonster(Settings.Monsters.ArmoredBug)) { monster = new Bug(new Vector2(), 121); monster.isHardModeMonster.Value = true; } else if (Game1.isDarkOut() && CanHazMonster(Settings.Monsters.PutridGhost)) { monster = new Ghost(new Vector2(), "Putrid Ghost"); } else if (Game1.isDarkOut() && CanHazMonster(Settings.Monsters.DustSprite)) { monster = new DustSpirit(new Vector2()); new Leaper(); } else if (Game1.isDarkOut() && CanHazMonster(Settings.Monsters.Spider)) { monster = new Leaper(new Vector2()); } else { foreach (var modMonster in DeepWoodsAPI.ToShuffledList(ModEntry.GetAPI().Monsters)) { // Item1 is a mod provided function that returns true if the mod wants to spawn a custom monster at this location. // Item2 is a mod provided function that returns the custom monster. if (modMonster.Item1(deepWoods, location)) { monster = modMonster.Item2(); break; } } } // No other monster was selected and no mod provided a monster, default to green slime if (monster == null) { monster = new GreenSlime(new Vector2(), GetSlimeLevel()); } if (!Settings.Monsters.DisableBuffedMonsters && deepWoods.level.Value >= Settings.Level.MinLevelForBuffedMonsters && !this.random.CheckChance(Settings.Monsters.ChanceForUnbuffedMonster)) { BuffMonster(monster); } if (!Settings.Monsters.DisableDangerousMonsters && deepWoods.level.Value >= Settings.Level.MinLevelForDangerousMonsters && !this.random.CheckChance(Settings.Monsters.ChanceForNonDangerousMonster)) { monster.isHardModeMonster.Value = true; } monster.faceDirection(this.random.GetRandomValue(0, 4)); return(monster); }
public static void SendMessage(string messageType, long playerID) { ModEntry.SendMessage(true, messageType, playerID); }
public override void Entry(IModHelper helper) { ModEntry.mod = this; I18N.Init(helper.Translation); RegisterEvents(helper.Events); }
private void Warp(ExitDirection exitDir) { if (Game1.locationRequest == null) { bool warped = false; string targetDeepWoodsName = null; Location?targetLocationWrapper = null; if (level.Value == 1 && exitDir == ExitDirection.TOP) { targetDeepWoodsName = "Woods"; targetLocationWrapper = WOODS_WARP_LOCATION; } else if (GetExit(exitDir) is DeepWoodsExit exit) { targetDeepWoodsName = exit.TargetLocationName; if (exit.TargetLocation.X == 0 && exit.TargetLocation.Y == 0) { if (Game1.getLocationFromName(targetDeepWoodsName) is DeepWoods exitDeepWoods) { exit.TargetLocation = new Location(exitDeepWoods.enterLocation.X, exitDeepWoods.enterLocation.Y); } } targetLocationWrapper = exit.TargetLocation; } else if (CastEnterDirToExitDir(EnterDir) == exitDir) { targetDeepWoodsName = parentName.Value; if (ParentExitLocation.X == 0 && ParentExitLocation.Y == 0) { if (Game1.getLocationFromName(targetDeepWoodsName) is DeepWoods parentDeepWoods) { ParentExitLocation = parentDeepWoods.GetExit(EnterDirToExitDir(EnterDir)).Location; } } targetLocationWrapper = ParentExitLocation; } ModEntry.Log($"Trying to warp from {this.Name}: (ExitDir: {exitDir}, Position: {Game1.player.Position.X}, {Game1.player.Position.Y}, targetDeepWoodsName: {targetDeepWoodsName}, targetLocation: {(targetLocationWrapper?.X ?? -1)}, {(targetLocationWrapper?.Y ?? -1)})", LogLevel.Trace); if (targetLocationWrapper.HasValue && targetDeepWoodsName != null) { Location targetLocation = targetLocationWrapper.Value; if (!(targetLocation.X == 0 && targetLocation.Y == 0)) { if (exitDir == ExitDirection.LEFT) { targetLocation.X += 1; } else if (exitDir == ExitDirection.BOTTOM) { targetLocation.Y += 1; } if (targetDeepWoodsName != "Woods") { DeepWoodsManager.currentWarpRequestName = targetDeepWoodsName; DeepWoodsManager.currentWarpRequestLocation = new Vector2(targetLocation.X * 64, targetLocation.Y * 64); if (!Game1.IsMasterGame) { DeepWoodsManager.AddBlankDeepWoodsToGameLocations(targetDeepWoodsName); } } Game1.warpFarmer(targetDeepWoodsName, targetLocation.X, targetLocation.Y, false); warped = true; } } if (!warped) { ModEntry.Log("Warp from " + this.Name + " failed. (ExitDir: " + exitDir + ")", LogLevel.Warn); } } }
public override void Entry(IModHelper helper) { ModEntry.mod = this; RegisterEvents(helper.Events); }
private void OnModMessageReceived(object sender, ModMessageReceivedEventArgs e) { if (e.FromModID != this.ModManifest.UniqueID) { return; } ModEntry.Log($"[{(Context.IsMainPlayer ? "host" : "farmhand")}] Received {e.Type} from {e.FromPlayerID}.", LogLevel.Trace); switch (e.Type) { // farmhand requested metadata case MessageId.RequestMetadata: if (Context.IsMainPlayer) { // client requests settings and state, send it: InitResponseMessage response = new InitResponseMessage { Settings = DeepWoodsSettings.Settings, State = DeepWoodsSettings.DeepWoodsState, LevelNames = Game1.locations.OfType <DeepWoods>().Select(p => p.Name).ToArray() }; ModEntry.SendMessage(response, MessageId.Metadata, e.FromPlayerID); } break; // host sent metadata case MessageId.Metadata: if (!Context.IsMainPlayer) { InitResponseMessage response = e.ReadAs <InitResponseMessage>(); DeepWoodsSettings.Settings = response.Settings; DeepWoodsSettings.DeepWoodsState = response.State; ModEntry.DeepWoodsInitServerAnswerReceived(response.LevelNames); } break; // farmhand requested that we load and activate a DeepWoods level case MessageId.RequestWarp: if (Context.IsMainPlayer) { // load level int level = e.ReadAs <int>(); DeepWoods deepWoods = DeepWoodsManager.AddDeepWoodsFromObelisk(level); // send response WarpMessage response = new WarpMessage { Level = deepWoods.Level, Name = deepWoods.Name, EnterLocation = new Vector2(deepWoods.enterLocation.Value.X, deepWoods.enterLocation.Value.Y) }; ModEntry.SendMessage(response, MessageId.Warp, e.FromPlayerID); } break; // host loaded area for warp case MessageId.Warp: if (!Context.IsMainPlayer) { WarpMessage data = e.ReadAs <WarpMessage>(); DeepWoodsManager.AddBlankDeepWoodsToGameLocations(data.Name); DeepWoodsManager.WarpFarmerIntoDeepWoodsFromServerObelisk(data.Name, data.EnterLocation); } break; // host sent 'lowest level reached' update case MessageId.SetLowestLevelReached: if (!Context.IsMainPlayer) { DeepWoodsState.LowestLevelReached = e.ReadAs <int>(); } break; // host sent 'received stardrop from unicorn' update case MessageId.SetUnicornStardropReceived: if (Context.IsMainPlayer) { DeepWoodsState.PlayersWhoGotStardropFromUnicorn.Add(e.FromPlayerID); } break; // host added/removed location case MessageId.AddLocation: if (!Context.IsMainPlayer) { string name = e.ReadAs <string>(); DeepWoodsManager.AddBlankDeepWoodsToGameLocations(name); } break; case MessageId.RemoveLocation: if (!Context.IsMainPlayer) { string name = e.ReadAs <string>(); DeepWoodsManager.RemoveDeepWoodsFromGameLocations(name); } break; default: ModEntry.Log(" ignored unknown type.", LogLevel.Trace); break; } }
private void OpenPassageInSecretWoods(Woods woods) { // TODO: Configurable (and moddable!) locations to modify Woods // Game isn't running if (!isDeepWoodsGameRunning) { ModEntry.Log("OpenPassageInSecretWoods: Cancelled, mod not initialized.", LogLevel.Trace); return; } // Already patched if (woods.warps.Where(warp => "DeepWoods".Equals(warp.TargetName)).Any()) { ModEntry.Log("OpenPassageInSecretWoods: Cancelled, map already patched.", LogLevel.Trace); return; } Layer buildingsLayer = woods.map.GetLayer("Buildings"); // Just to be sure if (buildingsLayer == null) { ModEntry.Log("OpenPassageInSecretWoods: Cancelled, invalid map (buildingsLayer is null).", LogLevel.Trace); return; } ModEntry.Log("OpenPassageInSecretWoods:", LogLevel.Trace); TileSheet borderTileSheet = woods.map.TileSheets.First(); int borderTileIndex = 0; int removed = 0; int added = 0; foreach (var location in Settings.WoodsPassage.DeleteBuildingTiles) { if (buildingsLayer.Tiles[location.X, location.Y] == null) { ModEntry.Log($" Can't remove tile from building layer at {location.X}, {location.Y}, there is no tile here! (Custom Woods map? Please modify WoodsPassage settings in the DeepWoods config file for custom Woods maps.)", LogLevel.Trace); } else { ModEntry.Log($" Removing tile from building layer at {location.X}, {location.Y}.", LogLevel.Trace); buildingsLayer.Tiles[location.X, location.Y] = null; removed++; } } foreach (var location in Settings.WoodsPassage.AddBuildingTiles) { if (buildingsLayer.Tiles[location.X, location.Y] == null) { ModEntry.Log($" Adding tile to building layer at {location.X}, {location.Y}.", LogLevel.Trace); buildingsLayer.Tiles[location.X, location.Y] = new StaticTile(buildingsLayer, borderTileSheet, BlendMode.Alpha, borderTileIndex); added++; } else { ModEntry.Log($" Can't add tile to building layer at {location.X}, {location.Y}, already have a tile there! (Custom Woods map? Please modify WoodsPassage settings in the DeepWoods config file for custom Woods maps.)", LogLevel.Trace); } } foreach (var location in Settings.WoodsPassage.WarpLocations) { ModEntry.Log($" Adding warp to DeepWoods at {location.X}, {location.Y}.", LogLevel.Trace); woods.warps.Add(new Warp(location.X, location.Y, "DeepWoods", Settings.Map.RootLevelEnterLocation.X, Settings.Map.RootLevelEnterLocation.Y + 1, false)); } ModEntry.Log($"OpenPassageInSecretWoods done. (Added {added}/{Settings.WoodsPassage.AddBuildingTiles.Length} tiles, removed {removed}/{Settings.WoodsPassage.DeleteBuildingTiles.Length} tiles, added {Settings.WoodsPassage.WarpLocations.Length} warps.)", LogLevel.Trace); }
private void OnReturnedToTitle(object sender, ReturnedToTitleEventArgs args) { ModEntry.Log("GameEvents_AfterReturnToTitle", StardewModdingAPI.LogLevel.Trace); isDeepWoodsGameRunning = false; }