public static void SpawnPandaZombie(NPCType typeToSpawn, Path path, Colony colony, IPandaBoss boss) { var monster = new Zombie(typeToSpawn, path, colony.Owner); if (boss != null) { if (boss.ZombieHPBonus != 0) { var fi = monster .GetType().GetField("health", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance); fi.SetValue(monster, (float)fi.GetValue(monster) + boss.ZombieHPBonus); } } if (colony.FollowerCount > Configuration.GetorDefault("MinColonistsCountForBosses", 15)) { var fi = monster .GetType().GetField("health", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance); fi.SetValue(monster, (float)fi.GetValue(monster) + colony.FollowerCount * .05f); } ModLoader.TriggerCallbacks <IMonster>(ModLoader.EModCallbackType.OnMonsterSpawned, monster); MonsterTracker.Add(monster); colony.OnZombieSpawn(true); }
public void SpawnZombie(NPCType typeToSpawn, Path path, Colony colony, bool notifyColonyForSiegeMode = true) { IMonster monster = new Zombie(typeToSpawn, path, colony); ModLoader.Callbacks.OnMonsterSpawned.Invoke(monster); MonsterTracker.Add(monster); if (notifyColonyForSiegeMode) { colony.OnZombieSpawn(true); } }
public void RegisterMonsterSpawnedElsewhere(IMonster monster, bool notifyColonyForSiegeMode = true) { ThreadManager.AssertIsMainThread(); ModLoader.Callbacks.OnMonsterSpawned.Invoke(monster); MonsterTracker.Add(monster); Colony goalColony = monster.OriginalGoal; if (goalColony != null) { IColonyDifficultySetting difficulty = goalColony.DifficultySetting; float cooldown = difficulty.GetZombieSpawnCooldown(goalColony); NextZombieSpawnTimes[goalColony] = Extensions.GetValueOrDefault(NextZombieSpawnTimes, goalColony, ServerTime.SecondsSinceStart) + cooldown; if (notifyColonyForSiegeMode) { goalColony.OnZombieSpawn(true); } } }
public static void OnUpdate() { if (!World.Initialized) { return; } while (_spawnQueue.Count > 0) { var pandaZombie = _spawnQueue.Dequeue(); var cs = ColonyState.GetColonyState(pandaZombie.OriginalGoal); ModLoader.Callbacks.OnMonsterSpawned.Invoke(pandaZombie); MonsterTracker.Add(pandaZombie); cs.ColonyRef.OnZombieSpawn(true); } if (_updateTime < Time.SecondsSinceStartDouble) { ServerManager.PathingManager.QueueAction(_pandaPathing); _updateTime = Time.SecondsSinceStartDouble + Pipliz.Random.NextDouble(30, 45); } }
public static void SpawnZombie(Colony colony, Banner bannerGoal, NPCType typeToSpawn) { float maxSpawnWalkDistance = 500f; if (TimeCycle.ShouldSpawnMonsters && typeToSpawn.TryGetSettings(out NPCTypeMonsterSettings nPCTypeMonsterSettings)) { maxSpawnWalkDistance = TimeCycle.NightLengthLeftInRealSeconds * (nPCTypeMonsterSettings.movementSpeed * 0.85f) + (float)bannerGoal.SafeRadius; } switch (TryGetSpawnLocation(bannerGoal, maxSpawnWalkDistance, out Vector3Int start)) { case MonsterSpawner.ESpawnResult.Success: { Path path; if (AIManager.ZombiePathFinder.TryFindPath(start, bannerGoal.KeyLocation, out path, 2000000000) == EPathFindingResult.Success) { IMonster monster = new Zombie(typeToSpawn, path, bannerGoal.Owner); ModLoader.TriggerCallbacks <IMonster>(ModLoader.EModCallbackType.OnMonsterSpawned, monster); MonsterTracker.Add(monster); colony.OnZombieSpawn(true); } else { colony.OnZombieSpawn(false); } break; } case MonsterSpawner.ESpawnResult.NotLoaded: colony.OnZombieSpawn(true); break; case MonsterSpawner.ESpawnResult.Fail: colony.OnZombieSpawn(false); break; } }
public static void OnUpdate() { if (!World.Initialized) { return; } var secondsSinceStartDouble = Time.SecondsSinceStartDouble; if (World.Initialized) { if (!TimeCycle.IsDay && !BossActive && _nextBossUpdateTime <= secondsSinceStartDouble) { BossActive = true; var bossType = GetMonsterType(); if (bossType != null) { _monsterManager.CurrentPandaBoss = bossType; ServerManager.PathingManager.QueueAction(_monsterManager); _justQueued = secondsSinceStartDouble + 5; if (Players.CountConnected != 0) { APILogger.Log(ChatColor.yellow, $"Boss Active! Boss is: {bossType.name}"); } } else { BossActive = false; GetNextBossSpawnTime(); } } if (BossActive && _justQueued < secondsSinceStartDouble) { var turnOffBoss = true; if (_pandaBossesSpawnQueue.Count > 0) { var pandaboss = _pandaBossesSpawnQueue.Dequeue(); var cs = ColonyState.GetColonyState(pandaboss.OriginalGoal); BossSpawned?.Invoke(MonsterTracker.MonsterSpawner, new BossSpawnedEvent(cs, pandaboss)); ModLoader.Callbacks.OnMonsterSpawned.Invoke(pandaboss); MonsterTracker.Add(pandaboss); cs.ColonyRef.OnZombieSpawn(true); cs.FaiedBossSpawns = 0; PandaChat.Send(cs, _localizationHelper, $"[{pandaboss.name}] {pandaboss.AnnouncementText}", ChatColor.red); if (!string.IsNullOrEmpty(pandaboss.AnnouncementAudio)) { cs.ColonyRef.ForEachOwner(o => AudioManager.SendAudio(o.Position, pandaboss.AnnouncementAudio)); } } foreach (var colony in ServerManager.ColonyTracker.ColoniesByID.Values) { var bannerGoal = colony.Banners.FirstOrDefault(); var cs = ColonyState.GetColonyState(colony); if (bannerGoal != null && cs.BossesEnabled && cs.ColonyRef.OwnerIsOnline()) { if (SpawnedBosses.ContainsKey(cs) && SpawnedBosses[cs].IsValid && SpawnedBosses[cs].CurrentHealth > 0) { if (colony.TemporaryData.GetAsOrDefault("BossIndicator", 0) < Time.SecondsSinceStartInt) { Indicator.SendIconIndicatorNear(new Vector3Int(SpawnedBosses[cs].Position), SpawnedBosses[cs].ID, new IndicatorState(1, ItemId.GetItemId(GameInitializer.NAMESPACE + ".Poisoned").Id, false, false)); colony.TemporaryData.SetAs("BossIndicator", Time.SecondsSinceStartInt + 1); } turnOffBoss = false; } } if (turnOffBoss) { if (Players.CountConnected != 0 && SpawnedBosses.Count != 0) { APILogger.Log(ChatColor.yellow, $"All bosses cleared!"); var boss = SpawnedBosses.FirstOrDefault().Value; PandaChat.SendToAll($"[{boss.name}] {boss.DeathText}", _localizationHelper, ChatColor.red); } BossActive = false; SpawnedBosses.Clear(); GetNextBossSpawnTime(); } } } } }
public static void OnUpdate() { if (!World.Initialized || AIManager.IsBusy()) { return; } var secondsSinceStartDouble = Time.SecondsSinceStartDouble; if (_nextUpdateTime < secondsSinceStartDouble) { IMonster m = null; foreach (var monster in GetAllMonsters()) { if (m == null || Vector3.Distance(monster.Value.Position, m.Position) > 15 && Random.NextBool()) { m = monster.Value; ServerManager.SendAudio(monster.Value.Position, GameLoader.NAMESPACE + ".ZombieAudio"); } } _nextUpdateTime = secondsSinceStartDouble + 5; } IPandaBoss bossType = null; if (World.Initialized && !AIManager.IsBusy()) { if (!BossActive && _nextBossUpdateTime <= secondsSinceStartDouble) { BossActive = true; bossType = GetMonsterType(); if (Players.CountConnected != 0) { PandaLogger.Log(ChatColor.yellow, $"Boss Active! Boss is: {bossType.Name}"); } } if (BossActive) { var turnOffBoss = true; var worldSettings = ServerManager.WorldSettings; Dictionary <PlayerState, List <Banner> > banners = new Dictionary <PlayerState, List <Banner> >(); var spawnBanners = new List <Banner>(); for (var i = 0; i < BannerTracker.GetCount(); i++) { if (BannerTracker.TryGetAtIndex(i, out var newBanner)) { var bps = PlayerState.GetPlayerState(newBanner.Owner); if (!banners.ContainsKey(bps)) { banners.Add(bps, new List <Banner>()); } banners[bps].Add(newBanner); } } foreach (var bkvp in banners) { if (bkvp.Value.Count > 1) { var next = Pipliz.Random.Next(bkvp.Value.Count); spawnBanners.Add(bkvp.Value[next]); } else if (bkvp.Value.Count == 1) { spawnBanners.Add(bkvp.Value[0]); } } foreach (var bannerGoal in spawnBanners) { var ps = PlayerState.GetPlayerState(bannerGoal.Owner); var colony = Colony.Get(ps.Player); if (ps.BossesEnabled && ps.Player.IsConnected && colony.FollowerCount > Configuration.GetorDefault("MinColonistsCountForBosses", 15)) { if (bossType != null && !_spawnedBosses.ContainsKey(ps)) { Vector3Int positionFinal; switch (MonsterSpawner.TryGetSpawnLocation(bannerGoal, 500f, out positionFinal)) { case MonsterSpawner.ESpawnResult.Success: if (AIManager.ZombiePathFinder.TryFindPath(positionFinal, bannerGoal.KeyLocation, out var path, 2000000000) == EPathFindingResult.Success) { var pandaboss = bossType.GetNewBoss(path, ps.Player); _spawnedBosses.Add(ps, pandaboss); BossSpawned?.Invoke(MonsterTracker.MonsterSpawner, new BossSpawnedEvent(ps, pandaboss)); ModLoader.TriggerCallbacks <IMonster>(ModLoader.EModCallbackType.OnMonsterSpawned, pandaboss); MonsterTracker.Add(pandaboss); colony.OnZombieSpawn(true); ps.FaiedBossSpawns = 0; PandaChat.Send(ps.Player, $"[{pandaboss.Name}] {pandaboss.AnnouncementText}", ChatColor.red); if (!string.IsNullOrEmpty(pandaboss.AnnouncementAudio)) { ServerManager.SendAudio(ps.Player.Position, pandaboss.AnnouncementAudio); } } break; case MonsterSpawner.ESpawnResult.NotLoaded: case MonsterSpawner.ESpawnResult.Impossible: colony.OnZombieSpawn(true); break; case MonsterSpawner.ESpawnResult.Fail: CantSpawnBoss(ps, colony); break; } if (_spawnedBosses.ContainsKey(ps) && _spawnedBosses[ps].IsValid && _spawnedBosses[ps].CurrentHealth > 0) { if (ps.Player.GetTempValues(true).GetOrDefault("BossIndicator", 0) < Time.SecondsSinceStartInt) { Indicator.SendIconIndicatorNear(new Vector3Int(_spawnedBosses[ps].Position), _spawnedBosses[ps].ID, new IndicatorState(1, GameLoader.Poisoned_Icon, false, false)); ps.Player.GetTempValues(true) .Set("BossIndicator", Time.SecondsSinceStartInt + 1); } turnOffBoss = false; } } } if (turnOffBoss) { if (Players.CountConnected != 0 && _spawnedBosses.Count != 0) { PandaLogger.Log(ChatColor.yellow, $"All bosses cleared!"); var boss = _spawnedBosses.FirstOrDefault().Value; PandaChat.SendToAll($"[{boss.Name}] {boss.DeathText}", ChatColor.red); } BossActive = false; _spawnedBosses.Clear(); GetNextBossSpawnTime(); } } } } }