diff --git a/zone/command.cpp b/zone/command.cpp index 6dc06cc3f..761f60a90 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -358,7 +358,7 @@ int command_init(void) command_add("spawn", "[name] [race] [level] [material] [hp] [gender] [class] [priweapon] [secweapon] [merchantid] - Spawn an NPC", AccountStatus::Steward, command_spawn) || command_add("spawneditmass", "Mass editing spawn command", AccountStatus::GMLeadAdmin, command_spawneditmass) || command_add("spawnfix", "- Find targeted NPC in database based on its X/Y/heading and update the database to make it spawn at your current location/heading.", AccountStatus::GMAreas, command_spawnfix) || - command_add("spawnstatus", "- Show respawn timer status", AccountStatus::GMAdmin, command_spawnstatus) || + command_add("spawnstatus", "[All|Disabled|Enabled|Spawn ID] - Show respawn timer status", AccountStatus::GMAdmin, command_spawnstatus) || command_add("spellinfo", "[spellid] - Get detailed info about a spell", AccountStatus::Steward, command_spellinfo) || command_add("stun", "[duration] - Stuns you or your target for duration", AccountStatus::GMAdmin, command_stun) || command_add("summon", "[charname] - Summons your player/npc/corpse target, or charname if specified", AccountStatus::QuestTroupe, command_summon) || diff --git a/zone/gm_commands/spawnstatus.cpp b/zone/gm_commands/spawnstatus.cpp index 9c9307bd8..6c90fb353 100755 --- a/zone/gm_commands/spawnstatus.cpp +++ b/zone/gm_commands/spawnstatus.cpp @@ -2,27 +2,136 @@ void command_spawnstatus(Client *c, const Seperator *sep) { - if ((sep->arg[1][0] == 'e') | (sep->arg[1][0] == 'E')) { - // show only enabled spawns - zone->ShowEnabledSpawnStatus(c); + int arguments = sep->argnum; + if (!arguments) { + c->Message(Chat::White, "Usage: #spawnstatus all - Show all spawn statuses for your current zone"); + c->Message(Chat::White, "Usage: #spawnstatus disabled - Show all disabled spawn statuses for your current zone"); + c->Message(Chat::White, "Usage: #spawnstatus enabled - Show all enabled spawn statuses for your current zone"); + c->Message(Chat::White, "Usage: #spawnstatus [Spawn ID] - Show spawn status by ID for your current zone"); + return; } - else if ((sep->arg[1][0] == 'd') | (sep->arg[1][0] == 'D')) { - // show only disabled spawns - zone->ShowDisabledSpawnStatus(c); + + bool is_all = !strcasecmp(sep->arg[1], "all"); + bool is_disabled = !strcasecmp(sep->arg[1], "disabled"); + bool is_enabled = !strcasecmp(sep->arg[1], "enabled"); + bool is_search = sep->IsNumber(1); + + if ( + !is_all && + !is_disabled && + !is_enabled && + !is_search + ) { + c->Message(Chat::White, "Usage: #spawnstatus all - Show all spawn statuses for your current zone"); + c->Message(Chat::White, "Usage: #spawnstatus disabled - Show all disabled spawn statuses for your current zone"); + c->Message(Chat::White, "Usage: #spawnstatus enabled - Show all enabled spawn statuses for your current zone"); + c->Message(Chat::White, "Usage: #spawnstatus [Spawn ID] - Show spawn status by ID for your current zone"); + return; } - else if ((sep->arg[1][0] == 'a') | (sep->arg[1][0] == 'A')) { - // show all spawn staus with no filters - zone->SpawnStatus(c); + + std::string filter_type; + if (is_disabled) { + filter_type = "Disabled"; + } else if (is_enabled) { + filter_type = "Enabled"; } - else if (sep->IsNumber(1)) { - // show spawn status by spawn2 id - zone->ShowSpawnStatusByID(c, atoi(sep->arg[1])); + + uint32 spawn_id = 0; + if (is_search) { + spawn_id = std::stoul(sep->arg[1]); } - else if (strcmp(sep->arg[1], "help") == 0) { - c->Message(Chat::White, "Usage: #spawnstatus <[a]ll | [d]isabled | [e]nabled | {Spawn2 ID}>"); + + LinkedListIterator iterator(zone->spawn2_list); + iterator.Reset(); + + uint32 filtered_count = 0; + uint32 spawn_count = 0; + uint32 spawn_number = 1; + while (iterator.MoreElements()) { + auto e = iterator.GetData(); + auto time_remaining = e->GetTimer().GetRemainingTime(); + if ( + is_all || + ( + is_disabled && + time_remaining == 0xFFFFFFFF + ) || + ( + is_enabled && + time_remaining != 0xFFFFFFFF + ) || + ( + is_search && + e->GetID() == spawn_id + ) + ) { + c->Message( + Chat::White, + fmt::format( + "Spawn {} | ID: {} Coordinates: {:.2f}, {:.2f}, {:.2f}, {:.2f}", + spawn_number, + e->GetID(), + e->GetX(), + e->GetY(), + e->GetZ(), + e->GetHeading() + ).c_str() + ); + if (time_remaining != 0xFFFFFFFF) { + auto seconds_remaining = (time_remaining / 1000); + c->Message( + Chat::White, + fmt::format( + "Spawn {} | Respawn: {} ({} Second{})", + spawn_number, + ConvertSecondsToTime(seconds_remaining), + seconds_remaining, + seconds_remaining != 1 ? "s" : "" + ).c_str() + ); + } + filtered_count++; + spawn_number++; + } + spawn_count++; + iterator.Advance(); } - else { - zone->SpawnStatus(c); + + if (!spawn_count) { + c->Message(Chat::White, "No spawns were found in this zone."); + return; + } + + if (!is_all && !is_search && !filtered_count) { + c->Message( + Chat::White, + fmt::format( + "No {} spawns were found in this zone.", + filter_type + ).c_str() + ); + return; + } + + if (is_all) { + c->Message( + Chat::White, + fmt::format( + "{} spawn{} listed.", + spawn_count, + spawn_count != 1 ? "s" : "" + ).c_str() + ); + } else { + c->Message( + Chat::White, + fmt::format( + "{} of {} spawn{} listed.", + filtered_count, + spawn_count, + spawn_count != 1 ? "s" : "" + ).c_str() + ); } } diff --git a/zone/spawn2.h b/zone/spawn2.h index 3f8b2e8ee..c6d5d0c46 100644 --- a/zone/spawn2.h +++ b/zone/spawn2.h @@ -67,6 +67,7 @@ public: bool NPCPointerValid() { return (npcthis!=nullptr); } void SetNPCPointer(NPC* n) { npcthis = n; } void SetNPCPointerNull() { npcthis = nullptr; } + Timer GetTimer() { return timer; } void SetTimer(uint32 duration) { timer.Start(duration); } uint32 GetKillCount() { return killcount; } protected: diff --git a/zone/zone.cpp b/zone/zone.cpp index a7876c980..d20be4022 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -2043,102 +2043,6 @@ bool ZoneDatabase::LoadStaticZonePoints(LinkedList *zone_point_list return true; } -void Zone::SpawnStatus(Mob* client) { - LinkedListIterator iterator(spawn2_list); - - uint32 x = 0; - iterator.Reset(); - while(iterator.MoreElements()) - { - if (iterator.GetData()->timer.GetRemainingTime() == 0xFFFFFFFF) - client->Message(Chat::White, " %d: %1.1f, %1.1f, %1.1f: disabled", iterator.GetData()->GetID(), iterator.GetData()->GetX(), iterator.GetData()->GetY(), iterator.GetData()->GetZ()); - else - client->Message(Chat::White, " %d: %1.1f, %1.1f, %1.1f: %1.2f", iterator.GetData()->GetID(), iterator.GetData()->GetX(), iterator.GetData()->GetY(), iterator.GetData()->GetZ(), (float)iterator.GetData()->timer.GetRemainingTime() / 1000); - - x++; - iterator.Advance(); - } - client->Message(Chat::White, "%i spawns listed.", x); -} - -void Zone::ShowEnabledSpawnStatus(Mob* client) -{ - LinkedListIterator iterator(spawn2_list); - int x = 0; - int iEnabledCount = 0; - - iterator.Reset(); - - while(iterator.MoreElements()) - { - if (iterator.GetData()->timer.GetRemainingTime() != 0xFFFFFFFF) - { - client->Message(Chat::White, " %d: %1.1f, %1.1f, %1.1f: %1.2f", iterator.GetData()->GetID(), iterator.GetData()->GetX(), iterator.GetData()->GetY(), iterator.GetData()->GetZ(), (float)iterator.GetData()->timer.GetRemainingTime() / 1000); - iEnabledCount++; - } - - x++; - iterator.Advance(); - } - - client->Message(Chat::White, "%i of %i spawns listed.", iEnabledCount, x); -} - -void Zone::ShowDisabledSpawnStatus(Mob* client) -{ - LinkedListIterator iterator(spawn2_list); - int x = 0; - int iDisabledCount = 0; - - iterator.Reset(); - - while(iterator.MoreElements()) - { - if (iterator.GetData()->timer.GetRemainingTime() == 0xFFFFFFFF) - { - client->Message(Chat::White, " %d: %1.1f, %1.1f, %1.1f: disabled", iterator.GetData()->GetID(), iterator.GetData()->GetX(), iterator.GetData()->GetY(), iterator.GetData()->GetZ()); - iDisabledCount++; - } - - x++; - iterator.Advance(); - } - - client->Message(Chat::White, "%i of %i spawns listed.", iDisabledCount, x); -} - -void Zone::ShowSpawnStatusByID(Mob* client, uint32 spawnid) -{ - LinkedListIterator iterator(spawn2_list); - int x = 0; - int iSpawnIDCount = 0; - - iterator.Reset(); - - while(iterator.MoreElements()) - { - if (iterator.GetData()->GetID() == spawnid) - { - if (iterator.GetData()->timer.GetRemainingTime() == 0xFFFFFFFF) - client->Message(Chat::White, " %d: %1.1f, %1.1f, %1.1f: disabled", iterator.GetData()->GetID(), iterator.GetData()->GetX(), iterator.GetData()->GetY(), iterator.GetData()->GetZ()); - else - client->Message(Chat::White, " %d: %1.1f, %1.1f, %1.1f: %1.2f", iterator.GetData()->GetID(), iterator.GetData()->GetX(), iterator.GetData()->GetY(), iterator.GetData()->GetZ(), (float)iterator.GetData()->timer.GetRemainingTime() / 1000); - - iSpawnIDCount++; - - break; - } - - x++; - iterator.Advance(); - } - - if(iSpawnIDCount > 0) - client->Message(Chat::White, "%i of %i spawns listed.", iSpawnIDCount, x); - else - client->Message(Chat::White, "No matching spawn id was found in this zone."); -} - bool ZoneDatabase::GetDecayTimes(npcDecayTimes_Struct *npcCorpseDecayTimes) { const std::string query = diff --git a/zone/zone.h b/zone/zone.h index 23262778d..3304aa30d 100755 --- a/zone/zone.h +++ b/zone/zone.h @@ -287,11 +287,7 @@ public: void SetStaticZone(bool sz) { staticzone = sz; } void SetTime(uint8 hour, uint8 minute, bool update_world = true); void SetUCSServerAvailable(bool ucss_available, uint32 update_timestamp); - void ShowDisabledSpawnStatus(Mob *client); - void ShowEnabledSpawnStatus(Mob *client); - void ShowSpawnStatusByID(Mob *client, uint32 spawnid); void SpawnConditionChanged(const SpawnCondition &c, int16 old_value); - void SpawnStatus(Mob *client); void StartShutdownTimer(uint32 set_time = (RuleI(Zone, AutoShutdownDelay))); void UpdateQGlobal(uint32 qid, QGlobal newGlobal); void weatherSend(Client *client = nullptr);