public static void AddBoss(IPandaBoss m) { lock (_bossList) { _bossList.Add(m); } }
private static IPandaBoss GetMonsterType() { IPandaBoss t = null; lock (_bossList) { var rand = _boss; while (rand == _boss) { rand = Random.Next(0, _bossList.Count); } t = _bossList[rand]; _boss = rand; } return(t); }
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 static bool CaclulateZombie(Banner banner, Colony colony, NPCType typeToSpawn, int RecycleFrequency = 1, float maxSpawnWalkDistance = 500f, IPandaBoss boss = null) { Path path; if (RecycleFrequency > 1 && MonsterSpawner.PathCache.TryGetPath(RecycleFrequency, banner.KeyLocation, maxSpawnWalkDistance, out path)) { SpawnPandaZombie(typeToSpawn, path, colony, boss); return(true); } Vector3Int positionFinal; switch (MonsterSpawner.TryGetSpawnLocation(banner, maxSpawnWalkDistance, out positionFinal)) { case MonsterSpawner.ESpawnResult.Success: if (AIManager.ZombiePathFinder.TryFindPath(positionFinal, banner.KeyLocation, out path, 2000000000) == EPathFindingResult.Success) { if (RecycleFrequency > 1) { MonsterSpawner.PathCache.AddCopy(path); } SpawnPandaZombie(typeToSpawn, path, colony, boss); return(true); } colony.OnZombieSpawn(false); return(false); case MonsterSpawner.ESpawnResult.NotLoaded: case MonsterSpawner.ESpawnResult.Impossible: colony.OnZombieSpawn(true); return(true); case MonsterSpawner.ESpawnResult.Fail: colony.OnZombieSpawn(false); return(true); default: return(false); } }
public bool SpawnForBanner(Banner banner, IDifficultySetting difficulty, Colony colony, float cooldown, IPandaBoss boss) { int recycleFrequency = MonsterSpawner.GetPathRecycleFrequency(1f / cooldown); NPCType zombieTypeToSpawn = difficulty.GetZombieTypeToSpawn(colony); float maxPathDistance = difficulty.GetMaxPathDistance(colony, zombieTypeToSpawn, banner.SafeRadius); return(CaclulateZombie(banner, colony, zombieTypeToSpawn, recycleFrequency, maxPathDistance)); }
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(); } } } } }