public static void EvaluateBanners() { if (!GameLoader.WorldLoaded) { return; } _bannerCounts.Clear(); var banners = BannerTracker.GetCount(); if (banners > 0) { for (var i = 0; i < banners; i++) { if (BannerTracker.TryGetAtIndex(i, out var banner)) { if (!_bannerCounts.ContainsKey(banner.Owner)) { _bannerCounts.Add(banner.Owner, 1); } else { _bannerCounts[banner.Owner]++; } } } } foreach (var p in _bannerCounts) { var ps = PlayerState.GetPlayerState(p.Key); if (ps == null) { continue; } var numberOfBanners = p.Key.GetTempValues(true) .GetOrDefault(PandaResearch.GetLevelKey(PandaResearch.Settlement), 0) + 1; var inv = Inventory.GetInventory(p.Key); var sockBanner = Stockpile.GetStockPile(p.Key).AmountContained(BuiltinBlocks.Banner); var inventoryBanners = 0; if (inv != null) { foreach (var item in inv.Items) { if (item.Type == BuiltinBlocks.Banner) { inventoryBanners = item.Amount; } } } var totalBanners = p.Value + sockBanner + inventoryBanners; #if Debug PandaLogger.Log($"Number of research banners: {numberOfBanners}"); PandaLogger.Log($"Number of banners: {p.Value}"); PandaLogger.Log($"Number of stockpile banners: {sockBanner}"); PandaLogger.Log($"Number of Inventory banners: {inventoryBanners}"); PandaLogger.Log($"Total banners: {totalBanners}"); PandaLogger.Log($"Add Banner: {totalBanners < numberOfBanners}"); #endif if (totalBanners < numberOfBanners) { if (!Inventory.GetInventory(p.Key).TryAdd(BuiltinBlocks.Banner)) { Stockpile.GetStockPile(p.Key).Add(BuiltinBlocks.Banner); } } } }
public void CalculateColoniesThatRequireMonsters() { int bannerCount = BannerTracker.GetCount(); coloniesRequiringZombies.Clear(); for (int i = 0; i < bannerCount; i++) { Banner banner; if (!BannerTracker.TryGetAtIndex(i, out banner) || !banner.KeyLocation.IsValid) { continue; } Colony colony = Colony.Get(banner.Owner); if (colony.FollowerCount == 0) { colony.OnZombieSpawn(true); continue; } var ps = PlayerState.GetPlayerState(banner.Owner); IDifficultySetting difficultyColony = colony.Owner.DifficultySetting; if (!MonsterManager.BossActive) { if (!ps.MonstersEnabled || !difficultyColony.ShouldSpawnZombies(colony)) { colony.OnZombieSpawn(true); continue; } } double nextZombieSpawnTime = NextZombieSpawnTimes.GetValueOrDefault(colony, 0.0); if (nextZombieSpawnTime > Pipliz.Time.SecondsSinceStartDoubleThisFrame) { continue; } if (colony.InSiegeMode) { if (Pipliz.Time.SecondsSinceStartDoubleThisFrame - colony.LastSiegeModeSpawn < siegeModeCooldown) { continue; } else { colony.LastSiegeModeSpawn = Pipliz.Time.SecondsSinceStartDoubleThisFrame; } } // lagging behind, or no cooldown set: teleport to current time if (Pipliz.Time.SecondsSinceStartDoubleThisFrame - nextZombieSpawnTime > MONSTERS_DELAY_THRESHOLD_SECONDS) { NextZombieSpawnTimes[colony] = Pipliz.Time.SecondsSinceStartDoubleThisFrame; } coloniesRequiringZombies.Add(TupleStruct.Create(colony, banner)); } }
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(); } } } } }