Implemented #repopclose [distance in units] - Used for development purposes, defaults to 500 units

- Real case use: Large zones with 700 NPC's and you are making fast quick tweaks to nearby NPC's you can refresh just the NPC's around you instead of all in the zone
- This can be quite the time saver
- This command will depop all NPC's and only respawn the NPC's that are 500 units around you or unless you specify otherwise
This commit is contained in:
Akkadius 2015-11-07 13:20:24 -06:00
parent 86f35e45d3
commit d64205124f
7 changed files with 171 additions and 3 deletions

View File

@ -1,5 +1,11 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 11/7/2015 ==
Akkadius: Implemented #repopclose [distance in units] - Used for development purposes, defaults to 500 units
- Real case use: Large zones with 700 NPC's and you are making fast quick tweaks to nearby NPC's you can refresh just the NPC's around you instead of all in the zone
- This can be quite the time saver
- This command will depop all NPC's and only respawn the NPC's that are 500 units around you or unless you specify otherwise
== 11/2/2015 ==
Akkadius: Performance boost (exponential) - Adjusted default idle cast check timers in rules
- Spells:AI_IdleNoSpellMinRecast 500 (Now 6000) 6 seconds

View File

@ -344,6 +344,7 @@ int command_init(void) {
command_add("reloadzonepoints", "- Reload zone points from database", 150, command_reloadzps) ||
command_add("reloadzps", nullptr,0, command_reloadzps) ||
command_add("repop", "[delay] - Repop the zone with optional delay", 100, command_repop) ||
command_add("repopclose", "[distance in units] Repops only NPC's nearby for fast development purposes", 100, command_repopclose) ||
command_add("resetaa", "- Resets a Player's AA in their profile and refunds spent AA's to unspent, may disconnect player.", 200, command_resetaa) ||
command_add("resetaa_timer", "Command to reset AA cooldown timers.", 200, command_resetaa_timer) ||
command_add("revoke", "[charname] [1/0] - Makes charname unable to talk on OOC", 200, command_revoke) ||
@ -3921,9 +3922,11 @@ void command_repop(Client *c, const Seperator *sep)
LinkedListIterator<Spawn2*> iterator(zone->spawn2_list);
iterator.Reset();
while (iterator.MoreElements()) {
std::string query = StringFormat("DELETE FROM respawn_times WHERE id = %lu AND instance_id = %lu",
(unsigned long)iterator.GetData()->GetID(),
(unsigned long)zone->GetInstanceID());
std::string query = StringFormat(
"DELETE FROM respawn_times WHERE id = %lu AND instance_id = %lu",
(unsigned long)iterator.GetData()->GetID(),
(unsigned long)zone->GetInstanceID()
);
auto results = database.QueryDatabase(query);
iterator.Advance();
}
@ -3940,6 +3943,33 @@ void command_repop(Client *c, const Seperator *sep)
zone->Repop(atoi(sep->arg[timearg])*1000);
}
void command_repopclose(Client *c, const Seperator *sep)
{
int repop_distance = 500;
if (sep->arg[1] && strcasecmp(sep->arg[1], "force") == 0) {
LinkedListIterator<Spawn2*> iterator(zone->spawn2_list);
iterator.Reset();
while (iterator.MoreElements()) {
std::string query = StringFormat(
"DELETE FROM respawn_times WHERE id = %lu AND instance_id = %lu",
(unsigned long)iterator.GetData()->GetID(),
(unsigned long)zone->GetInstanceID()
);
auto results = database.QueryDatabase(query);
iterator.Advance();
}
c->Message(0, "Zone depop: Force resetting spawn timers.");
}
if (sep->IsNumber(1)) {
repop_distance = atoi(sep->arg[1]);
}
c->Message(0, "Zone depoped. Repopping NPC's within %i distance units", repop_distance);
zone->RepopClose(c->GetPosition(), repop_distance);
}
void command_spawnstatus(Client *c, const Seperator *sep)
{
if((sep->arg[1][0] == 'e') | (sep->arg[1][0] == 'E'))

View File

@ -187,6 +187,7 @@ void command_myskills(Client *c, const Seperator *sep);
void command_depop(Client *c, const Seperator *sep);
void command_depopzone(Client *c, const Seperator *sep);
void command_repop(Client *c, const Seperator *sep);
void command_repopclose(Client *c, const Seperator *sep);
void command_spawnstatus(Client *c, const Seperator *sep);
void command_nukebuffs(Client *c, const Seperator *sep);
void command_zuwcoords(Client *c, const Seperator *sep);

View File

@ -351,6 +351,112 @@ void Spawn2::DeathReset(bool realdeath)
}
}
bool ZoneDatabase::PopulateZoneSpawnListClose(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, const glm::vec4& client_position, uint32 repop_distance)
{
std::unordered_map<uint32, uint32> spawn_times;
float mob_distance = 0;
timeval tv;
gettimeofday(&tv, nullptr);
/* Bulk Load NPC Types Data into the cache */
database.LoadNPCTypesData(0, true);
std::string spawn_query = StringFormat(
"SELECT "
"respawn_times.id, "
"respawn_times.`start`, "
"respawn_times.duration "
"FROM "
"respawn_times "
"WHERE instance_id = %u",
zone->GetInstanceID()
);
auto results = QueryDatabase(spawn_query);
for (auto row = results.begin(); row != results.end(); ++row) {
uint32 start_duration = atoi(row[1]) > 0 ? atoi(row[1]) : 0;
uint32 end_duration = atoi(row[2]) > 0 ? atoi(row[2]) : 0;
/* Our current time was expired */
if ((start_duration + end_duration) <= tv.tv_sec) {
spawn_times[atoi(row[0])] = 0;
}
/* We still have time left on this timer */
else {
spawn_times[atoi(row[0])] = ((start_duration + end_duration) - tv.tv_sec) * 1000;
}
}
const char *zone_name = database.GetZoneName(zoneid);
std::string query = StringFormat(
"SELECT "
"id, "
"spawngroupID, "
"x, "
"y, "
"z, "
"heading, "
"respawntime, "
"variance, "
"pathgrid, "
"_condition, "
"cond_value, "
"enabled, "
"animation "
"FROM "
"spawn2 "
"WHERE zone = '%s' AND version = %u",
zone_name,
version
);
results = QueryDatabase(query);
if (!results.Success()) {
return false;
}
for (auto row = results.begin(); row != results.end(); ++row) {
uint32 spawn_time_left = 0;
Spawn2* new_spawn = 0;
bool perl_enabled = atoi(row[11]) == 1 ? true : false;
if (spawn_times.count(atoi(row[0])) != 0)
spawn_time_left = spawn_times[atoi(row[0])];
glm::vec4 point;
point.x = atof(row[2]);
point.y = atof(row[3]);
mob_distance = DistanceNoZ(client_position, point);
if (mob_distance > repop_distance)
continue;
new_spawn = new Spawn2( //
atoi(row[0]), // uint32 in_spawn2_id
atoi(row[1]), // uint32 spawngroup_id
atof(row[2]), // float in_x
atof(row[3]), // float in_y
atof(row[4]), // float in_z
atof(row[5]), // float in_heading
atoi(row[6]), // uint32 respawn
atoi(row[7]), // uint32 variance
spawn_time_left, // uint32 timeleft
atoi(row[8]), // uint32 grid
atoi(row[9]), // uint16 in_cond_id
atoi(row[10]), // int16 in_min_value
perl_enabled, // bool in_enabled
(EmuAppearance)atoi(row[12]) // EmuAppearance anim
);
spawn2_list.Insert(new_spawn);
}
return true;
}
bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, uint32 repopdelay) {
std::unordered_map<uint32, uint32> spawn_times;

View File

@ -1445,6 +1445,29 @@ void Zone::ClearNPCTypeCache(int id) {
}
}
void Zone::RepopClose(const glm::vec4& client_position, uint32 repop_distance)
{
if (!Depop())
return;
LinkedListIterator<Spawn2*> iterator(spawn2_list);
iterator.Reset();
while (iterator.MoreElements()) {
iterator.RemoveCurrent();
}
quest_manager.ClearAllTimers();
if (!database.PopulateZoneSpawnListClose(zoneid, spawn2_list, GetInstanceVersion(), client_position, repop_distance))
Log.Out(Logs::General, Logs::None, "Error in Zone::Repop: database.PopulateZoneSpawnList failed");
initgrids_timer.Start();
mod_repop();
}
void Zone::Repop(uint32 delay) {
if(!Depop())

View File

@ -140,6 +140,7 @@ public:
bool Depop(bool StartSpawnTimer = false);
void Repop(uint32 delay = 0);
void RepopClose(const glm::vec4& client_position, uint32 repop_distance);
void ClearNPCTypeCache(int id);
void SpawnStatus(Mob* client);
void ShowEnabledSpawnStatus(Mob* client);

View File

@ -359,6 +359,7 @@ public:
bool LoadSpawnGroups(const char* zone_name, uint16 version, SpawnGroupList* spawn_group_list);
bool LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_group_list);
bool PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, uint32 repopdelay = 0);
bool PopulateZoneSpawnListClose(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, const glm::vec4& client_position, uint32 repop_distance);
Spawn2* LoadSpawn2(LinkedList<Spawn2*> &spawn2_list, uint32 spawn2id, uint32 timeleft);
bool CreateSpawn2(Client *c, uint32 spawngroup, const char* zone, const glm::vec4& position, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value);
void UpdateRespawnTime(uint32 id, uint16 instance_id,uint32 timeleft);