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);
            }
        }
Example #5
0
        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();
                        }
                    }
                }
            }
        }
Example #7
0
        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();
                        }
                    }
                }
            }
        }