コード例 #1
0
ファイル: NPCManager.cs プロジェクト: Vednix/Custom-Npcs
            /// <summary>
            /// Attempts to spawn the given minion for every player online, where applicable.
            /// </summary>
            /// <param name="spawnRegion"></param>
            /// <param name="minion"></param>
            /// <param name="npcdef"></param>
            /// <param name="attempts"></param>
            private static void SpawnMinion(Rectangle spawnRegion, SpawnMinion minion, CustomNPCDefinition npcdef, int attempts)
            {
                //Loop through players
                foreach (TSPlayer player in TShock.Players)
                {
                    if (player == null || player.Dead || !player.Active || !NPCManager.Chance(minion.Chance))
                    {
                        continue;
                    }

                    //Check if the minions can spawn anywhere, or if we need to check if players see them.
                    if (!CurrentWave.SpawnAnywhere)
                    {
                        Rectangle playerFrame = new Rectangle((int)player.TPlayer.position.X, (int)player.TPlayer.position.Y, player.TPlayer.width, player.TPlayer.height);
                        if (!playerFrame.Intersects(spawnRegion))
                        {
                            continue;
                        }
                    }

                    //Check biomes
                    if (minion.BiomeConditions != BiomeTypes.None)
                    {
                        BiomeTypes biomes = player.GetCurrentBiomes();

                        if ((minion.BiomeConditions & biomes) == 0)
                        {
                            continue;
                        }
                    }

                    int mobid = -1;

                    //Try max attempts times. This gives attempts*50 spawn attempts at random positions.
                    for (int i = 0; mobid == -1 && i < attempts; i++)
                    {
                        mobid = NPCManager.SpawnMobAroundPlayer(player, npcdef);
                    }

                    //Spawning failed :(
                    if (mobid == -1)
                    {
                        continue;
                    }

                    NPCManager.GetCustomNPCByIndex(mobid).isInvasion = true;
                }
            }
コード例 #2
0
ファイル: NPCManager.cs プロジェクト: Vednix/Custom-Npcs
        internal static void SpawnMobsInBiomeAndRegion()
        {
            //loop through all players
            foreach (TSPlayer player in TShock.Players)
            {
                //Check if player exist and is connected
                if (player == null || !player.ConnectionAlive)
                {
                    continue;
                }

                //Log.ConsoleInfo("{0} - Checking spawn for player", player.Name);

                //Check all biome spawns
                BiomeTypes biomes = player.GetCurrentBiomes();
                foreach (BiomeTypes biome in availableBiomes.Where(x => biomes.HasFlag(x)))
                {
                    //Log.ConsoleInfo("{0} - Checking biome for player", biome.ToString());

                    //Get list of mobs that can be spawned in that biome
                    List <Tuple <string, CustomNPCSpawning> > biomeSpawns;
                    if (!Data.BiomeSpawns.TryGetValue(biome, out biomeSpawns))
                    {
                        continue;
                    }

                    foreach (Tuple <string, CustomNPCSpawning> obj in biomeSpawns)
                    {
                        //Log.ConsoleInfo("{0} - Checking mob spawn", obj.Item1);
                        //Check spawn conditions
                        if (!CheckSpawnConditions(obj.Item2.spawnConditions))
                        {
                            //Log.ConsoleInfo("False Conditions");
                            continue;
                        }

                        CustomNPCDefinition customnpc = Data.GetNPCbyID(obj.Item1);

                        if (customnpc.maxSpawns <= -1)
                        {
                            customnpc.currSpawnsVar++;
                        }

                        //Make sure not spawning more then maxSpawns
                        if (customnpc.maxSpawns != -1 && customnpc.currSpawnsVar >= customnpc.maxSpawns)
                        {
                            continue;
                        }


                        //Get the last spawn attempt
                        DateTime lastSpawnAttempt;
                        if (!Data.LastSpawnAttempt.TryGetValue(customnpc.customID, out lastSpawnAttempt))
                        {
                            lastSpawnAttempt = default(DateTime);
                            Data.LastSpawnAttempt[customnpc.customID] = lastSpawnAttempt;
                        }

                        //If not enough time has passed, we skip and go to the next NPC.
                        if ((DateTime.Now - lastSpawnAttempt).TotalSeconds < obj.Item2.spawnRate)
                        {
                            continue;
                        }

                        //Check spawn chance
                        if (!NPCManager.Chance(obj.Item2.spawnChance))
                        {
                            continue;
                        }

                        // Check Player Depth

                        if (player.TileY > obj.Item2.minDepth && player.TileY < obj.Item2.maxDepth || obj.Item2.minDepth == -1 || obj.Item2.maxDepth == -1)
                        {
                            //Check spawn method
                            if (obj.Item2.useTerrariaSpawn)
                            {
                                //All checks completed --> spawn mob
                                int npcid = SpawnMobAroundPlayer(player, customnpc);
                                if (npcid != -1)
                                {
                                    Main.npc[npcid].target = player.Index;
                                    Data.LastSpawnAttempt[customnpc.customID] = DateTime.Now;
                                    customnpc.currSpawnsVar++;
                                }
                            }
                            else
                            {
                                //All checks completed --> spawn mob
                                int spawnX;
                                int spawnY;

                                TShock.Utils.GetRandomClearTileWithInRange(player.TileX, player.TileY, 50, 50, out spawnX, out spawnY);

                                int npcid = SpawnNPCAtLocation((spawnX * 16) + 8, spawnY * 16, customnpc);
                                if (npcid == -1)
                                {
                                    continue;
                                }

                                Data.LastSpawnAttempt[customnpc.customID] = DateTime.Now;
                                Main.npc[npcid].target = player.Index;
                                customnpc.currSpawnsVar++;
                            }
                        }
                    }
                }

                //Then check regions as well
                Rectangle playerRectangle = new Rectangle(player.TileX, player.TileY, player.TPlayer.width, player.TPlayer.height);
                foreach (Region obj in Data.RegionSpawns.Keys.Select(name => TShock.Regions.GetRegionByName(name)).Where(region => region != null && region.InArea(playerRectangle)))
                {
                    List <Tuple <string, CustomNPCSpawning> > regionSpawns;
                    if (!Data.RegionSpawns.TryGetValue(obj.Name, out regionSpawns))
                    {
                        continue;
                    }

                    foreach (Tuple <string, CustomNPCSpawning> obj2 in regionSpawns)
                    {
                        //Invalid spawn conditions
                        if (!CheckSpawnConditions(obj2.Item2.spawnConditions))
                        {
                            continue;
                        }

                        CustomNPCDefinition customnpc = Data.GetNPCbyID(obj2.Item1);

                        //Make sure not spawning more then maxSpawns
                        if (customnpc.maxSpawns != -1 && customnpc.currSpawnsVar >= customnpc.maxSpawns)
                        {
                            continue;
                        }

                        //Get the last spawn attempt
                        DateTime lastSpawnAttempt;
                        if (!Data.LastSpawnAttempt.TryGetValue(customnpc.customID, out lastSpawnAttempt))
                        {
                            lastSpawnAttempt = default(DateTime);
                            Data.LastSpawnAttempt[customnpc.customID] = lastSpawnAttempt;
                        }

                        //If not enough time passed, we skip and go to the next NPC.
                        if ((DateTime.Now - lastSpawnAttempt).TotalSeconds < obj2.Item2.spawnRate)
                        {
                            continue;
                        }

                        Data.LastSpawnAttempt[customnpc.customID] = DateTime.Now;

                        if (!NPCManager.Chance(obj2.Item2.spawnChance))
                        {
                            continue;
                        }

                        // Check Player Depth

                        if (player.TileY > obj2.Item2.minDepth && player.TileY < obj2.Item2.maxDepth || obj2.Item2.minDepth == -1 || obj2.Item2.maxDepth == -1)
                        {
                            var region = TShock.Regions.GetRegionByName(obj2.Item2.spawnRegion);
                            ActiveArenas.Add(region);
                            ActiveArenas.Count();

                            var arenaX = region.Area.X + (region.Area.Width / 2);
                            var arenaY = region.Area.Y + (region.Area.Height / 2);
                            var rangeX = region.Area.Width / 2;
                            var rangeY = region.Area.Height / 2;

                            int spawnX;
                            int spawnY;

                            TShock.Utils.GetRandomClearTileWithInRange(arenaX, arenaY, rangeX, rangeY, out spawnX, out spawnY);

                            int npcid = SpawnNPCAtLocation((spawnX * 16) + 8, spawnY * 16, customnpc);
                            if (npcid == -1)
                            {
                                continue;
                            }


                            Main.npc[npcid].target = player.Index;
                            customnpc.currSpawnsVar++;
                            ActiveArenas.Remove(region);
                            continue;
                        }
                    }
                }
            }
        }
コード例 #3
0
ファイル: CustomNPCPlugin.cs プロジェクト: Vednix/Custom-Npcs
        /// <summary>
        /// Checks if any player is within targetable range of the npc, without obstacle and within firing cooldown timer.
        /// </summary>
        private void ProjectileCheck()
        {
            //Loop through all custom npcs currently spawned
            foreach (CustomNPCVars obj in NPCManager.NPCs)
            {
                //Check if they exists and are active
                if (obj == null || obj.isDead || !obj.mainNPC.active)
                {
                    continue;
                }

                //We only want the npcs with custom projectiles
                if (obj.customNPC.customProjectiles == null)
                {
                    continue;
                }

                //Save the current time
                DateTime savedNow = DateTime.Now;

                int k = 0;
                //Loop through all npc projectiles they can fire
                foreach (CustomNPCProjectiles projectile in obj.customNPC.customProjectiles)
                {
                    //Check if projectile last fire time is greater then equal to its next allowed fire time
                    if ((savedNow - obj.lastAttemptedProjectile[k]).TotalMilliseconds >= projectile.projectileFireRate)
                    {
                        //Make sure chance is checked too, don't bother checking if its 100
                        if (projectile.projectileFireChance == 100 || NPCManager.Chance(projectile.projectileFireChance))
                        {
                            TSPlayer target = null;
                            if (projectile.projectileLookForTarget)
                            {
                                //Find a target for it to shoot that isn't dead or disconnected
                                foreach (TSPlayer player in TShock.Players.Where(x => x != null && !x.Dead && x.ConnectionAlive))
                                {
                                    //Check if that target can be shot ie/ no obstacles, or if it if projectile goes through walls ignore this check
                                    if (!projectile.projectileCheckCollision || Collision.CanHit(player.TPlayer.position, player.TPlayer.bodyFrame.Width, player.TPlayer.bodyFrame.Height, obj.mainNPC.position, obj.mainNPC.width, obj.mainNPC.height))
                                    {
                                        //Make sure distance isn't further then what tshock allows
                                        float currDistance = Vector2.DistanceSquared(player.TPlayer.position, obj.mainNPC.frame.Center());

                                        //Distance^2 < 4194304 is the same as Distance < 2048, but faster
                                        if (currDistance < 4194304)
                                        {
                                            //Set the target player
                                            target = player;
                                            //Set npcs target to the player its shooting at
                                            obj.mainNPC.target = player.Index;
                                            //Break since no need to find another target
                                            break;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                target = TShock.Players[obj.mainNPC.target];
                            }

                            //Check if we found a valid target
                            if (target != null)
                            {
                                //All checks completed. Fire projectile
                                FireProjectile(target, obj, projectile);
                                //Set last attempted projectile to now
                                obj.lastAttemptedProjectile[k] = savedNow;
                            }
                        }
                        else
                        {
                            obj.lastAttemptedProjectile[k] = savedNow;
                        }
                    }

                    //Increment Index
                    k++;
                }
            }
        }
コード例 #4
0
        private void InvasionTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (TShock.Utils.ActivePlayers() == 0)
            {
                return;
            }

            int spawnFails     = 0;
            int spawnsThisWave = 0;

            int       spawnX      = Main.spawnTileX - 150;
            int       spawnY      = Main.spawnTileY - 150;
            Rectangle SpawnRegion = new Rectangle(spawnX, spawnY, 300, 300);

            foreach (SpawnMinion minions in CurrentWave.SpawnGroup.SpawnMinions)
            {
                var npcdef = NPCManager.Data.GetNPCbyID(minions.MobID);
                if (npcdef == null)
                {
                    TShock.Log.ConsoleError("[CustomNPC]: Error! The custom mob id \"{0}\" does not exist!", minions.MobID);
                    continue;
                }

                // Check spawn conditions
                if (minions.SpawnConditions != SpawnConditions.None)
                {
                    if (NPCManager.CheckSpawnConditions(minions.SpawnConditions))
                    {
                        continue;
                    }
                }

                foreach (TSPlayer player in TShock.Players)
                {
                    //Skip spawning more NPCs when we have likely hit the server's mob limit.
                    if (spawnFails > 40 && spawnsThisWave >= 150)
                    {
                        continue;
                    }

                    if (player == null || player.Dead || !player.Active || !NPCManager.Chance(minions.Chance))
                    {
                        continue;
                    }
                    Rectangle playerframe = new Rectangle((int)player.TPlayer.position.X, (int)player.TPlayer.position.Y, player.TPlayer.width, player.TPlayer.height);
                    if (!playerframe.Intersects(SpawnRegion))
                    {
                        continue;
                    }

                    if (minions.BiomeConditions != BiomeTypes.None)
                    {
                        BiomeTypes biomes = player.GetCurrentBiomes();

                        if ((minions.BiomeConditions & biomes) == 0)
                        {
                            continue;
                        }
                    }

                    // Prevent multiple bosses from spawning during invasions
                    if (minions.isBoss && NPCManager.AliveCount(minions.MobID) > 0)
                    {
                        continue;
                    }

                    int mobid = -1;
                    //Try max 3 times. Since every try checks 50 positions around the player to spawn the mob,
                    //3 tries means a maximum of 150 spawn attempts.
                    for (int i = 0; mobid == -1 && i < 3; i++)
                    {
                        mobid = NPCManager.SpawnMobAroundPlayer(player, npcdef);
                    }

                    if (mobid == -1)
                    {
                        spawnFails++;
                        continue;
                    }

                    NPCManager.GetCustomNPCByIndex(mobid).isInvasion = true;
                    spawnsThisWave++;
                }
            }

            if (spawnFails > 0)
            {
                TShock.Log.ConsoleInfo("[CustomNPC]: Failed to spawn {0} npcs this wave!", spawnFails);
            }
        }
コード例 #5
0
ファイル: CustomNPCPlugin.cs プロジェクト: Vednix/Custom-Npcs
        private void OnNPCSpawn(NpcSpawnEventArgs args)
        {
            //DEBUG
            TShock.Log.ConsoleInfo("DEBUG [NPCSpawn] NPCIndex {0}", args.NpcId);
            //DEBUG

            //If the id falls outside the possible range, we can return.
            if (args.NpcId < 0 || args.NpcId >= 200)
            {
                return;
            }

            //This NPC is custom and not dead.
            if (NPCManager.NPCs[args.NpcId] != null && !NPCManager.NPCs[args.NpcId].isDead)
            {
                return;
            }

            NPC spawned = Main.npc[args.NpcId];

            foreach (CustomNPCDefinition customnpc in NPCManager.Data.CustomNPCs.Values)
            {
                if (!customnpc.isReplacement || customnpc.ReplacementChance >= 100 || NPCManager.Chance(customnpc.ReplacementChance) || spawned.netID != customnpc.customBase.netID)
                {
                    continue;
                }
                DateTime[] dt = null;
                if (customnpc.customProjectiles != null)
                {
                    dt = Enumerable.Repeat(DateTime.Now, customnpc.customProjectiles.Count).ToArray();
                }
                NPCManager.NPCs[spawned.whoAmI] = new CustomNPCVars(customnpc, dt, spawned);
                NPCManager.Data.ConvertNPCToCustom(spawned.whoAmI, customnpc);

                break;
            }
        }