private static void After_DustSpirit_behaviorAtGameTick(DustSpirit __instance, ref bool ___runningAwayFromFarmer, ref bool ___chargingFarmer) { if (IsLovedMonster(__instance)) { ___runningAwayFromFarmer = false; ___chargingFarmer = false; __instance.controller = null; } }
private static void DustSpirit_behaviorAtGameTick_Postfix(DustSpirit __instance, ref bool ___runningAwayFromFarmer, ref bool ___chargingFarmer) { if (__instance.Health <= 0 || Config.MonstersIgnorePlayer) { ___runningAwayFromFarmer = false; ___chargingFarmer = false; __instance.controller = null; } }
private void DustBoss(int x, int y) { DustSpirit dust = new DustSpirit(new Vector2(x, y), true) { Health = (mineLevel == 1) ? 400 : ((mineLevel / 2) * 400), speed = 6, ExperienceGained = 40, DamageToFarmer = (Config.difficulty > 5) ? (int)(mineLevel / 2 * difficulty) : ((mineLevel == 1) ? 12 : ((mineLevel / 2) * 12)), isGlowing = true, glowingTransparency = 0.0f }; dust.jitteriness.Value = (Double)100.0; Game1.mine.tryToAddMonster((Monster)dust, x, y); _bossHpEvents.Add((Monster)dust, new Action(BossLevel10Die)); }
public static DustSpirit CreateFriendlyLivingMushroom(Vector2 vector) { var monster = new DustSpirit(vector, false); monster.DamageToFarmer = 0; monster.Speed /= 2; monster.farmerPassesThrough = true; monster.coinsToDrop.Value = 0; monster.objectsToDrop.Clear(); monster.objectsToDrop.Add(MushroomRancher.redMushroomId); string dangerous_texture_name = monster.Sprite.textureName.Value + "_dangerous"; if (Game1.content.Load <Texture2D>(dangerous_texture_name) != null) { monster.Sprite.LoadTexture(dangerous_texture_name); } return(monster); }
public static bool BehaviorAtGameTick_LivingMushroom(DustSpirit __instance, ref bool ___chargingFarmer, ref bool ___seenFarmer) { try { if (___seenFarmer && __instance.currentLocation is SlimeHutch) { var farmer = Utility.isThereAFarmerWithinDistance(__instance.getStandingPosition() / 64f, 3, __instance.currentLocation); if (farmer == null) { ___chargingFarmer = false; __instance.controller = null; } } return(true); } catch (Exception e) { mod.ErrorLog("There was an exception in a patch", e); return(true); } }
/// <summary>Generates a monster and places it on the specified map and tile.</summary> /// <param name="monsterType">The monster type's name and an optional dictionary of monster-specific settings.</param> /// <param name="location">The GameLocation where the monster should be spawned.</param> /// <param name="tile">The x/y coordinates of the tile where the monster should be spawned.</param> /// <param name="areaID">The UniqueAreaID of the related SpawnArea. Required for log messages.</param> /// <returns>Returns the monster's ID value, or null if the spawn process failed.</returns> public static int?SpawnMonster(MonsterType monsterType, GameLocation location, Vector2 tile, string areaID = "") { Monster monster = null; //an instatiated monster, to be spawned into the world later Color?color = null; //the monster's color (used by specific monster types) if (monsterType.Settings != null) //if settings were provided { if (monsterType.Settings.ContainsKey("Color")) //if this setting was provided { string[] colorText = ((string)monsterType.Settings["Color"]).Trim().Split(' '); //split the setting string into strings for each number List <int> colorNumbers = new List <int>(); foreach (string text in colorText) //for each string { int num = Convert.ToInt32(text); //convert it to a number if (num < 0) { num = 0; } //minimum 0 else if (num > 255) { num = 255; } //maximum 255 colorNumbers.Add(num); //add it to the list } //convert strings into RGBA values int r = Convert.ToInt32(colorNumbers[0]); int g = Convert.ToInt32(colorNumbers[1]); int b = Convert.ToInt32(colorNumbers[2]); int a; if (colorNumbers.Count > 3) //if the setting included an "A" value { a = Convert.ToInt32(colorNumbers[3]); } else //if the setting did not include an "A" value { a = 255; //default to no transparency } color = new Color(r, g, b, a); //set the color } else if (monsterType.Settings.ContainsKey("MinColor") && monsterType.Settings.ContainsKey("MaxColor")) //if color wasn't provided, but mincolor & maxcolor were { string[] minColorText = ((string)monsterType.Settings["MinColor"]).Trim().Split(' '); //split the setting string into strings for each number List <int> minColorNumbers = new List <int>(); foreach (string text in minColorText) //for each string { int num = Convert.ToInt32(text); //convert it to a number if (num < 0) { num = 0; } //minimum 0 else if (num > 255) { num = 255; } //maximum 255 minColorNumbers.Add(num); //add it to the list } string[] maxColorText = ((string)monsterType.Settings["MaxColor"]).Trim().Split(' '); //split the setting string into strings for each number List <int> maxColorNumbers = new List <int>(); foreach (string text in maxColorText) //for each string { int num = Convert.ToInt32(text); //convert it to a number if (num < 0) { num = 0; } //minimum 0 else if (num > 255) { num = 255; } //maximum 255 maxColorNumbers.Add(num); //convert to number } for (int x = 0; x < minColorNumbers.Count && x < maxColorNumbers.Count; x++) //for each pair of values { if (minColorNumbers[x] > maxColorNumbers[x]) //if min > max { //swap min and max int temp = minColorNumbers[x]; minColorNumbers[x] = maxColorNumbers[x]; maxColorNumbers[x] = temp; } } //pick random RGBA values between min and max int r = RNG.Next(minColorNumbers[0], maxColorNumbers[0] + 1); int g = RNG.Next(minColorNumbers[1], maxColorNumbers[1] + 1); int b = RNG.Next(minColorNumbers[2], maxColorNumbers[2] + 1); int a; if (minColorNumbers.Count > 3 && maxColorNumbers.Count > 3) //if both settings included an "A" value { a = RNG.Next(minColorNumbers[3], maxColorNumbers[3] + 1); } else //if one/both of the settings did not include an "A" value { a = 255; //default to no transparency } color = new Color(r, g, b, a); //set the color } } bool seesPlayers = false; //whether the monster automatically "sees" players at spawn (handled differently by some monster types) if (monsterType.Settings != null) //if settings were provided { if (monsterType.Settings.ContainsKey("SeesPlayersAtSpawn")) //if this setting was provided { seesPlayers = (bool)monsterType.Settings["SeesPlayersAtSpawn"]; //use the provided setting } } //create a new monster based on the provided name & apply type-specific settings switch (monsterType.MonsterName.ToLower()) //avoid most casing issues by making this lower-case { case "bat": monster = new BatFTM(tile, 0); break; case "frostbat": case "frost bat": monster = new BatFTM(tile, 40); break; case "lavabat": case "lava bat": monster = new BatFTM(tile, 80); break; case "iridiumbat": case "iridium bat": monster = new BatFTM(tile, 171); break; case "doll": case "curseddoll": case "cursed doll": monster = new BatFTM(tile, -666); break; case "skull": case "hauntedskull": case "haunted skull": monster = new BatFTM(tile, 77377); break; case "bigslime": case "big slime": case "biggreenslime": case "big green slime": monster = new BigSlimeFTM(tile, 0); if (color.HasValue) //if color was provided { ((BigSlimeFTM)monster).c.Value = color.Value; //set its color after creation } if (seesPlayers) //if the "SeesPlayersAtSpawn" setting is true { monster.IsWalkingTowardPlayer = true; } break; case "bigblueslime": case "big blue slime": case "bigfrostjelly": case "big frost jelly": monster = new BigSlimeFTM(tile, 40); if (color.HasValue) //if color was provided { ((BigSlimeFTM)monster).c.Value = color.Value; //set its color after creation } if (seesPlayers) //if the "SeesPlayersAtSpawn" setting is true { monster.IsWalkingTowardPlayer = true; } break; case "bigredslime": case "big red slime": case "bigredsludge": case "big red sludge": monster = new BigSlimeFTM(tile, 80); if (color.HasValue) //if color was provided { ((BigSlimeFTM)monster).c.Value = color.Value; //set its color after creation } if (seesPlayers) //if the "SeesPlayersAtSpawn" setting is true { monster.IsWalkingTowardPlayer = true; } break; case "bigpurpleslime": case "big purple slime": case "bigpurplesludge": case "big purple sludge": monster = new BigSlimeFTM(tile, 121); if (color.HasValue) //if color was provided { ((BigSlimeFTM)monster).c.Value = color.Value; //set its color after creation } if (seesPlayers) //if the "SeesPlayersAtSpawn" setting is true { monster.IsWalkingTowardPlayer = true; } break; case "bug": monster = new Bug(tile, 0); break; case "armoredbug": case "armored bug": monster = new Bug(tile, 121); break; case "dino": case "dinomonster": case "dino monster": case "pepper": case "pepperrex": case "pepper rex": case "rex": monster = new DinoMonster(tile); break; case "duggy": monster = new DuggyFTM(tile); break; case "dust": case "sprite": case "dustsprite": case "dust sprite": case "spirit": case "dustspirit": case "dust spirit": monster = new DustSpirit(tile); break; case "ghost": monster = new GhostFTM(tile); break; case "carbonghost": case "carbon ghost": monster = new GhostFTM(tile, "Carbon Ghost"); break; case "slime": case "greenslime": case "green slime": monster = new GreenSlime(tile, 0); if (color.HasValue) //if color was also provided { ((GreenSlime)monster).color.Value = color.Value; //set its color after creation } break; case "blueslime": case "blue slime": case "frostjelly": case "frost jelly": monster = new GreenSlime(tile, 40); if (color.HasValue) //if color was also provided { ((GreenSlime)monster).color.Value = color.Value; //set its color after creation } break; case "redslime": case "red slime": case "redsludge": case "red sludge": monster = new GreenSlime(tile, 80); if (color.HasValue) //if color was also provided { ((GreenSlime)monster).color.Value = color.Value; //set its color after creation } break; case "purpleslime": case "purple slime": case "purplesludge": case "purple sludge": monster = new GreenSlime(tile, 121); if (color.HasValue) //if color was also provided { ((GreenSlime)monster).color.Value = color.Value; //set its color after creation } break; case "grub": case "cavegrub": case "cave grub": monster = new GrubFTM(tile, false); break; case "fly": case "cavefly": case "cave fly": monster = new FlyFTM(tile, false); break; case "mutantgrub": case "mutant grub": monster = new GrubFTM(tile, true); break; case "mutantfly": case "mutant fly": monster = new FlyFTM(tile, true); break; case "metalhead": case "metal head": monster = new MetalHead(tile, 0); if (color.HasValue) //if color was provided { ((MetalHead)monster).c.Value = color.Value; //set its color after creation } break; case "mummy": monster = new MummyFTM(tile); break; case "rockcrab": case "rock crab": monster = new RockCrab(tile); break; case "lavacrab": case "lava crab": monster = new LavaCrab(tile); break; case "iridiumcrab": case "iridium crab": monster = new RockCrab(tile, "Iridium Crab"); break; case "rockgolem": case "rock golem": case "stonegolem": case "stone golem": monster = new RockGolemFTM(tile); break; case "wildernessgolem": case "wilderness golem": monster = new RockGolemFTM(tile, Game1.player.CombatLevel); break; case "serpent": monster = new SerpentFTM(tile); break; case "brute": case "shadowbrute": case "shadow brute": monster = new ShadowBrute(tile); break; case "shaman": case "shadowshaman": case "shadow shaman": monster = new ShadowShaman(tile); break; case "skeleton": monster = new Skeleton(tile); if (seesPlayers) //if the "SeesPlayersAtSpawn" setting is true { IReflectedField <bool> spottedPlayer = Helper.Reflection.GetField <bool>(monster, "spottedPlayer"); //try to access this skeleton's private "spottedPlayer" field spottedPlayer.SetValue(true); monster.IsWalkingTowardPlayer = true; } break; case "squid": case "kid": case "squidkid": case "squid kid": monster = new SquidKidFTM(tile); break; default: //if the name doesn't match any directly known monster types Type externalType = GetTypeFromName(monsterType.MonsterName, typeof(Monster)); //find a monster subclass with a matching name monster = (Monster)Activator.CreateInstance(externalType, tile); //create a monster with the Vector2 constructor break; } if (monster == null) { Monitor.Log($"The monster to be spawned (\"{monsterType.MonsterName}\") doesn't match any known monster types. Make sure that name isn't misspelled in your config file.", LogLevel.Info); return(null); } int?ID = MonsterTracker.AddMonster(monster); //generate an ID for this monster if (!ID.HasValue) { Monitor.Log("A new monster ID could not be generated. This is may be due to coding issue; please report it to this mod's developer. This monster won't be spawned.", LogLevel.Warn); return(null); } monster.id = ID.Value; //assign the ID to this monster monster.MaxHealth = monster.Health; //some monster types set Health on creation and expect MaxHealth to be updated like this ApplyMonsterSettings(monster, monsterType.Settings, areaID); //adjust the monster based on any other provided optional settings //spawn the completed monster at the target location Monitor.VerboseLog($"Spawning monster. Type: {monsterType.MonsterName}. Location: {tile.X},{tile.Y} ({location.Name})."); monster.currentLocation = location; monster.setTileLocation(tile); location.addCharacter(monster); return(monster.id); }
private Monster GetMonster(int x, Vector2 loc) { Monster m; switch (x) { case 0: m = new DustSpirit(loc); break; case 1: m = new Grub(loc); break; case 2: m = new Skeleton(loc); break; case 3: m = new RockCrab(loc); break; case 4: m = new Ghost(loc); break; case 5: m = new GreenSlime(loc); break; case 6: m = new RockGolem(loc); break; case 7: m = new ShadowBrute(loc); break; case 8: int y = rand.Next(1, 6); //m = new Monster(); if (y == 1) { m = new RockCrab(loc, "Iridium Crab"); } else if (y == 2) { m = new Ghost(loc, "Carbon Ghost"); } else if (y == 3) { m = new LavaCrab(loc); } //else if (y == 4) //m = new Bat(loc, Math.Max(Game1.player.CombatLevel * 5, 50)); else if (y == 4) { m = new GreenSlime(loc, Math.Max(Game1.player.CombatLevel * 5, 50)); } else if (y == 5) { m = new BigSlime(loc, Math.Max(Game1.player.CombatLevel * 5, 50)); } else { m = new Mummy(loc); } break; default: m = new Monster(); break; } return(m); }
/********* ** Private methods *********/ private void SpawnEntity(string command, string[] args) { //We need a world to spawn monsters in, duh if (Context.IsWorldReady) { // Determine if we have arguments if (args.Length > 0) { //Set defaults NPC entity = null; int xTile = Game1.player.getTileX(); int yTile = Game1.player.getTileY(); int amount = 1; //Ensure provided coordinatees are actually coordinates try { //Determine X tile if (args.Length >= 2) { if (!args[1].Equals("~")) { xTile = int.Parse(args[1]); } } //Determine Y tile if (args.Length >= 3) { if (!args[1].Equals("~")) { yTile = int.Parse(args[2]); } } } catch (Exception) { Monitor.Log("Arguments 1 and 2 must be coordinates or '~' to use the Farmer's coordinates! Make sure you don't add any brackets!"); return; } try { if (args.Length >= 4) { amount = int.Parse(args[3]); if (amount < 1) { throw new Exception(); } } } catch (Exception) { Monitor.Log("Argument 3 must be an amount larger than 0!"); return; } Vector2 pos = new Vector2(xTile, yTile); for (int i = 0; i < amount; i++) { // Determine the monster to spawn switch (args[0]) { case "greenSlime": entity = new GreenSlime(pos, 0); break; case "blueSlime": entity = new GreenSlime(pos, 40); break; case "redSlime": entity = new GreenSlime(pos, 80); break; case "purpleSlime": entity = new GreenSlime(pos, 121); break; case "yellowSlime": entity = new GreenSlime(pos, new Color(255, 255, 50)); break; case "blackSlime": Random r = new Random(); entity = new GreenSlime(pos, new Color(40 + r.Next(10), 40 + r.Next(10), 40 + r.Next(10))); break; case "bat": entity = new Bat(pos); break; //minelevel: 0 - 40 - 80 - 171 -> type case "frostBat": entity = new Bat(pos, 40); break; case "lavaBat": entity = new Bat(pos, 80); break; case "iridiumBat": entity = new Bat(pos, 171); break; case "bug": entity = new Bug(pos, 0); break; //available areatypes: 121 -> armored case "armoredBug": entity = new Bug(pos, 121); break; case "fly": entity = new Fly(pos); break; //hard -> mutant case "mutantFly": entity = new Fly(pos, true); break; case "ghost": entity = new Ghost(pos); break; //name -> carbon ghost case "carbonGhost": entity = new Ghost(pos, "Carbon Ghost"); break; case "grub": entity = new Grub(pos); break; //hard -> mutant case "mutantGrub": entity = new Grub(pos, true); break; case "rockCrab": entity = new RockCrab(pos); break; //name -> iridium crab case "lavaCrab": entity = new LavaCrab(pos); break; case "iridiumCrab": entity = new RockCrab(pos, "Iridium Crab"); break; case "metalHead": entity = new MetalHead(pos, 80); break; //mineareas: 0, 40, 80 - seems to only spawn at 80+ case "rockGolem": entity = new RockGolem(pos); break; //mineareas: 0, 40, 80 - changes health and damage; difficultymod: case "wildernessGolem": entity = new RockGolem(pos, 5); break; case "mummy": entity = new Mummy(pos); break; case "serpent": entity = new Serpent(pos); break; case "shadowBrute": entity = new ShadowBrute(pos); break; case "shadowShaman": entity = new ShadowShaman(pos); break; case "skeleton": entity = new Skeleton(pos); break; case "squidKid": entity = new SquidKid(pos); break; case "duggy": entity = new Duggy(pos); break; case "dustSpirit": entity = new DustSpirit(pos); break; } if (entity != null) { entity.currentLocation = Game1.currentLocation; entity.setTileLocation(new Vector2(xTile, yTile)); Game1.currentLocation.addCharacter(entity); } else { Monitor.Log($"{args[0]} not found! Type monster_list to view a list of available monsters to spawn!"); return; } } Monitor.Log($"{amount} {entity.Name} added at {entity.currentLocation.Name} {entity.getTileX()},{entity.getTileY()}", LogLevel.Info); } else { Monitor.Log("Usage: monster_spawn <name> [posX] [posY] [amount]\n\nUses Farmer's coordinates if none or '~' was given."); } } else { Monitor.Log("Load a save first!"); } }
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); }