Esempio n. 1
0
        private static void ToggleCreatureEvents(NWArea area)
        {
            AreaSpawn areaSpawn   = AreaSpawns[area];
            int       playerCount = NWNXArea.GetNumberOfPlayersInArea(area);

            foreach (var creature in areaSpawn.Creatures)
            {
                if (creature.Spawn.IsValid)
                {
                    bool eventsDisabled = creature.Spawn.GetLocalInt("SPAWN_EVENTS_DISABLED") == TRUE;
                    bool isCreature     = creature.Spawn.IsCreature;

                    if (isCreature)
                    {
                        // Currently disabled, but players are in area. Enable them.
                        if (eventsDisabled && playerCount > 0)
                        {
                            EnableCreatureEvents(creature.SpawnCreature);
                            creature.SpawnCreature.SetLocalInt("SPAWN_EVENTS_DISABLED", FALSE);
                        }
                        // Currently enabled, but players are no longer in area. Disable them.
                        else if (!eventsDisabled && playerCount <= 0)
                        {
                            DisableCreatureEvents(creature.SpawnCreature);
                            creature.SpawnCreature.SetLocalInt("SPAWN_EVENTS_DISABLED", TRUE);
                        }
                    }
                }
            }
        }
Esempio n. 2
0
        private static void CopyAreaSpawns(string originalResref, NWArea copyArea)
        {
            NWArea    originalArea      = NWModule.Get().Areas.Single(x => x.Resref == originalResref && x.GetLocalInt("IS_AREA_INSTANCE") == FALSE);
            AreaSpawn originalAreaSpawn = AreaSpawns[originalArea];

            AreaSpawns.Add(copyArea, originalAreaSpawn);
        }
Esempio n. 3
0
        private static void CopyAreaSpawns(string originalResref, NWArea copyArea)
        {
            NWArea    originalArea  = NWModule.Get().Areas.Single(x => x.Resref == originalResref && x.GetLocalBool("IS_AREA_INSTANCE") == false);
            AreaSpawn copyAreaSpawn = AreaSpawns[originalArea].Clone();

            AreaSpawns.Add(copyArea, copyAreaSpawn);
        }
Esempio n. 4
0
        private static void ProcessSpawns()
        {
            using (new Profiler(nameof(SpawnService) + "." + nameof(ProcessSpawns)))
            {
                foreach (var spawn in AppCache.AreaSpawns)
                {
                    // Check for a valid area - otherwise it causes hangs sometimes when the server shuts down.
                    if (!spawn.Key.IsValid)
                    {
                        continue;
                    }

                    AreaSpawn areaSpawn  = spawn.Value;
                    bool      forceSpawn = !areaSpawn.HasSpawned;

                    foreach (var plc in areaSpawn.Placeables.Where(x => x.Respawns || !x.Respawns && !x.HasSpawnedOnce))
                    {
                        ProcessSpawn(plc, OBJECT_TYPE_PLACEABLE, spawn.Key, forceSpawn);
                    }

                    foreach (var creature in areaSpawn.Creatures.Where(x => x.Respawns || !x.Respawns && !x.HasSpawnedOnce))
                    {
                        ProcessSpawn(creature, OBJECT_TYPE_CREATURE, spawn.Key, forceSpawn);
                    }

                    areaSpawn.SecondsEmpty = 0.0f;
                    areaSpawn.HasSpawned   = true;
                }
            }
        }
Esempio n. 5
0
        private static void ProcessSpawns()
        {
            using (new Profiler(nameof(SpawnService) + "." + nameof(ProcessSpawns)))
            {
                // On module load, we want to populate all areas with NPCs and disable their AI.
                // The reason for this is because we don't want lag when players enter an area.
                // This'll use more memory but the CPU usage will be very limited as none of the
                // creatures will have scripts assigned.
                bool hasRunOnce = NWModule.Get().GetLocalInt("SPAWN_HAS_RUN_ONCE") == TRUE;

                foreach (var spawn in AreaSpawns)
                {
                    // Check for a valid area - otherwise it causes hangs sometimes when the server shuts down.
                    if (!spawn.Key.IsValid)
                    {
                        continue;
                    }

                    // Ignore empty areas.
                    int playerCount = NWNXArea.GetNumberOfPlayersInArea(spawn.Key);
                    if (playerCount <= 0 && hasRunOnce)
                    {
                        continue;
                    }

                    AreaSpawn areaSpawn  = spawn.Value;
                    bool      forceSpawn = !areaSpawn.HasSpawned;

                    foreach (var plc in areaSpawn.Placeables.Where(x => x.Respawns || !x.Respawns && !x.HasSpawnedOnce))
                    {
                        ProcessSpawn(plc, OBJECT_TYPE_PLACEABLE, spawn.Key, forceSpawn);
                    }

                    foreach (var creature in areaSpawn.Creatures.Where(x => x.Respawns || !x.Respawns && !x.HasSpawnedOnce))
                    {
                        ProcessSpawn(creature, OBJECT_TYPE_CREATURE, spawn.Key, forceSpawn);
                    }

                    areaSpawn.SecondsEmpty = 0.0f;
                    areaSpawn.HasSpawned   = true;

                    // Toggle creature AI now, if this is the first time we're running this process.
                    if (!hasRunOnce)
                    {
                        ToggleCreatureEvents(spawn.Key);
                    }
                }

                NWModule.Get().SetLocalInt("SPAWN_HAS_RUN_ONCE", TRUE);
            }
        }
Esempio n. 6
0
        private static void InitializeAreaSpawns(NWArea area)
        {
            var areaSpawn = new AreaSpawn();

            // Check for manually placed spawns
            NWObject obj = GetFirstObjectInArea(area.Object);

            while (obj.IsValid)
            {
                bool isSpawn = obj.ObjectType == OBJECT_TYPE_WAYPOINT && obj.GetLocalInt("IS_SPAWN") == TRUE;

                if (isSpawn)
                {
                    int    spawnType       = obj.GetLocalInt("SPAWN_TYPE");
                    int    objectType      = spawnType == 0 || spawnType == OBJECT_TYPE_CREATURE ? OBJECT_TYPE_CREATURE : spawnType;
                    int    spawnTableID    = obj.GetLocalInt("SPAWN_TABLE_ID");
                    int    npcGroupID      = obj.GetLocalInt("SPAWN_NPC_GROUP_ID");
                    string behaviourScript = obj.GetLocalString("SPAWN_BEHAVIOUR_SCRIPT");
                    if (string.IsNullOrWhiteSpace(behaviourScript))
                    {
                        behaviourScript = obj.GetLocalString("SPAWN_BEHAVIOUR");
                    }

                    string  spawnResref = obj.GetLocalString("SPAWN_RESREF");
                    float   respawnTime = obj.GetLocalFloat("SPAWN_RESPAWN_SECONDS");
                    string  spawnRule   = obj.GetLocalString("SPAWN_RULE");
                    int     deathVFXID  = obj.GetLocalInt("SPAWN_DEATH_VFX");
                    AIFlags aiFlags     = (AIFlags)obj.GetLocalInt("SPAWN_AI_FLAGS");
                    bool    useResref   = true;

                    // No resref specified but a table was, look in the database for a random record.
                    if (string.IsNullOrWhiteSpace(spawnResref) && spawnTableID > 0)
                    {
                        // Pick a random record.
                        var spawnObjects = DataService.SpawnObject.GetAllBySpawnTableID(spawnTableID).ToList();
                        int count        = spawnObjects.Count;
                        int index        = count <= 0 ? 0 : RandomService.Random(count);
                        var dbSpawn      = spawnObjects[index];

                        if (dbSpawn != null)
                        {
                            spawnResref = dbSpawn.Resref;
                            useResref   = false;

                            if (dbSpawn.NPCGroupID != null && dbSpawn.NPCGroupID > 0)
                            {
                                npcGroupID = Convert.ToInt32(dbSpawn.NPCGroupID);
                            }

                            if (!string.IsNullOrWhiteSpace(dbSpawn.BehaviourScript))
                            {
                                behaviourScript = dbSpawn.BehaviourScript;
                            }

                            if (!string.IsNullOrWhiteSpace(dbSpawn.SpawnRule))
                            {
                                spawnRule = dbSpawn.SpawnRule;
                            }

                            if (deathVFXID <= 0)
                            {
                                deathVFXID = dbSpawn.DeathVFXID;
                            }

                            if (aiFlags == AIFlags.None)
                            {
                                aiFlags = dbSpawn.AIFlags;
                            }
                        }
                    }

                    // If we found a resref, spawn the object and add it to the cache.
                    if (!string.IsNullOrWhiteSpace(spawnResref))
                    {
                        // Delay the creation so that the iteration through the area doesn't get thrown off by new entries.
                        Location location   = obj.Location;
                        bool     isInstance = area.IsInstance;

                        ObjectSpawn newSpawn;
                        if (useResref)
                        {
                            newSpawn = new ObjectSpawn(location, true, spawnResref, respawnTime);
                        }
                        else
                        {
                            newSpawn = new ObjectSpawn(location, true, spawnTableID, respawnTime);
                        }

                        if (npcGroupID > 0)
                        {
                            newSpawn.NPCGroupID = npcGroupID;
                        }

                        if (deathVFXID > 0)
                        {
                            newSpawn.DeathVFXID = deathVFXID;
                        }

                        if (!string.IsNullOrWhiteSpace(behaviourScript))
                        {
                            newSpawn.BehaviourScript = behaviourScript;
                        }

                        if (!string.IsNullOrWhiteSpace(spawnRule))
                        {
                            newSpawn.SpawnRule = spawnRule;
                        }

                        if (aiFlags == AIFlags.None)
                        {
                            newSpawn.AIFlags = aiFlags;
                        }

                        // Instance spawns are one-shot.
                        if (isInstance)
                        {
                            newSpawn.Respawns = false;
                        }

                        if (objectType == OBJECT_TYPE_CREATURE)
                        {
                            areaSpawn.Creatures.Add(newSpawn);
                        }
                        else if (objectType == OBJECT_TYPE_PLACEABLE)
                        {
                            areaSpawn.Placeables.Add(newSpawn);
                        }
                    }
                }

                obj = GetNextObjectInArea(area.Object);
            }

            AreaSpawns.Add(area, areaSpawn);

            DelayCommand(1.0f, () =>
            {
                SpawnResources(area, areaSpawn);
            });
        }
Esempio n. 7
0
        private static void SpawnResources(NWArea area, AreaSpawn areaSpawn)
        {
            var dbArea = DataService.Area.GetByResref(area.Resref);

            if (dbArea.ResourceSpawnTableID <= 0 ||
                !dbArea.AutoSpawnResources)
            {
                return;
            }
            var possibleSpawns = DataService.SpawnObject.GetAllBySpawnTableID(dbArea.ResourceSpawnTableID).ToList();

            // 1024 size = 32x32
            // 256  size = 16x16
            // 64   size = 8x8
            int size = area.Width * area.Height;

            int maxSpawns = 0;

            if (size <= 12)
            {
                maxSpawns = 2;
            }
            else if (size <= 32)
            {
                maxSpawns = 6;
            }
            else if (size <= 64)
            {
                maxSpawns = 10;
            }
            else if (size <= 256)
            {
                maxSpawns = 25;
            }
            else if (size <= 512)
            {
                maxSpawns = 40;
            }
            else if (size <= 1024)
            {
                maxSpawns = 50;
            }

            int[] weights = new int[possibleSpawns.Count()];
            for (int x = 0; x < possibleSpawns.Count(); x++)
            {
                weights[x] = possibleSpawns.ElementAt(x).Weight;
            }

            for (int x = 1; x <= maxSpawns; x++)
            {
                int         index    = RandomService.GetRandomWeightedIndex(weights);
                var         dbSpawn  = possibleSpawns.ElementAt(index);
                Location    location = GetRandomSpawnPoint(area);
                NWPlaceable plc      = (CreateObject(OBJECT_TYPE_PLACEABLE, dbSpawn.Resref, location));
                ObjectSpawn spawn    = new ObjectSpawn(location, false, dbArea.ResourceSpawnTableID, 600.0f);
                spawn.Spawn = plc;

                ObjectVisibilityService.ApplyVisibilityForObject(plc);

                if (dbSpawn.NPCGroupID != null && dbSpawn.NPCGroupID > 0)
                {
                    plc.SetLocalInt("NPC_GROUP", Convert.ToInt32(dbSpawn.NPCGroupID));
                    spawn.NPCGroupID = Convert.ToInt32(dbSpawn.NPCGroupID);
                }

                if (!string.IsNullOrWhiteSpace(dbSpawn.BehaviourScript) &&
                    string.IsNullOrWhiteSpace(plc.GetLocalString("BEHAVIOUR")))
                {
                    plc.SetLocalString("BEHAVIOUR", dbSpawn.BehaviourScript);
                    spawn.BehaviourScript = dbSpawn.BehaviourScript;
                }

                if (!string.IsNullOrWhiteSpace(dbSpawn.SpawnRule))
                {
                    var rule = GetSpawnRule(dbSpawn.SpawnRule);
                    rule.Run(plc);
                }

                areaSpawn.Placeables.Add(spawn);
            }
        }
Esempio n. 8
0
        public void Run(object[] args)
        {
            var spawns = _cache.AreaSpawns;

            foreach (var spawn in spawns)
            {
                // Check for a valid area - otherwise it causes hangs sometimes when the server shuts down.
                if (!spawn.Key.IsValid)
                {
                    continue;
                }

                AreaSpawn areaSpawn = spawn.Value;
                int       pcsInArea = NWModule.Get().Players.Count(x => x.Area.Equals(spawn.Key));

                // No players in area. Process the despawner.
                if (pcsInArea <= 0 && areaSpawn.HasSpawned)
                {
                    areaSpawn.SecondsEmpty += _processor.ProcessingTickInterval;

                    if (areaSpawn.SecondsEmpty >= 1200) // 20 minutes have passed with no players in the area.
                    {
                        areaSpawn.SecondsEmpty = 0.0f;
                        areaSpawn.HasSpawned   = false;

                        foreach (var plc in areaSpawn.Placeables)
                        {
                            if (plc.Spawn.IsValid)
                            {
                                plc.Spawn.Destroy();
                            }
                        }

                        foreach (var creature in areaSpawn.Creatures)
                        {
                            if (creature.Spawn.IsValid)
                            {
                                creature.Spawn.Destroy();
                            }
                        }
                    }
                }
                // Players in the area
                else if (pcsInArea > 0)
                {
                    bool forceSpawn = !areaSpawn.HasSpawned;

                    foreach (var plc in areaSpawn.Placeables.Where(x => x.Respawns || !x.Respawns && !x.HasSpawnedOnce))
                    {
                        ProcessSpawn(plc, OBJECT_TYPE_PLACEABLE, spawn.Key, forceSpawn);
                    }

                    foreach (var creature in areaSpawn.Creatures.Where(x => x.Respawns || !x.Respawns && !x.HasSpawnedOnce))
                    {
                        ProcessSpawn(creature, OBJECT_TYPE_CREATURE, spawn.Key, forceSpawn);
                    }

                    areaSpawn.SecondsEmpty = 0.0f;
                    areaSpawn.HasSpawned   = true;
                }
            }
        }