diff options
-rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommand.h | 2 | ||||
-rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommandArgs.h | 2 | ||||
-rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommandTags.h | 3 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_gobject.cpp | 237 |
4 files changed, 65 insertions, 179 deletions
diff --git a/src/server/game/Chat/ChatCommands/ChatCommand.h b/src/server/game/Chat/ChatCommands/ChatCommand.h index dac914485d0..616b4984460 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommand.h +++ b/src/server/game/Chat/ChatCommands/ChatCommand.h @@ -55,7 +55,7 @@ namespace Trinity::Impl::ChatCommands { if constexpr (I < N) { - if (Optional<std::string_view> next = ArgInfo<std::variant_alternative_t<I, V>>::TryConsume(val.template emplace<I>(), args)) + if (Optional<std::string_view> next = SingleConsumer<std::variant_alternative_t<I, V>>::TryConsumeTo(val.template emplace<I>(), args)) return next; else return TryAtIndex<I+1>(val, args); diff --git a/src/server/game/Chat/ChatCommands/ChatCommandArgs.h b/src/server/game/Chat/ChatCommands/ChatCommandArgs.h index aba41baddda..bdd0be0aace 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommandArgs.h +++ b/src/server/game/Chat/ChatCommands/ChatCommandArgs.h @@ -43,7 +43,7 @@ namespace Trinity::Impl::ChatCommands |* *| \****************************************************************************************/ template <typename T, typename = void> -struct ArgInfo { static_assert(!std::is_same_v<T,T>, "Invalid command parameter type - see ChatCommandArgs.h for possible types"); }; +struct ArgInfo { static_assert(Trinity::dependant_false_v<T>, "Invalid command parameter type - see ChatCommandArgs.h for possible types"); }; // catch-all for number types template <typename T> diff --git a/src/server/game/Chat/ChatCommands/ChatCommandTags.h b/src/server/game/Chat/ChatCommands/ChatCommandTags.h index 9255ef18fd3..3c8c778d5ea 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommandTags.h +++ b/src/server/game/Chat/ChatCommands/ChatCommandTags.h @@ -193,6 +193,9 @@ namespace Trinity::ChatCommands return operator*(); } + template <bool C = have_operators> + std::enable_if_t<C, bool> operator!() const { return !**this; } + template <typename T> Variant& operator=(T&& arg) { base::operator=(std::forward<T>(arg)); return *this; } diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index b8af8ea16d0..93dfac2992e 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -50,6 +50,8 @@ bool HandleNpcSpawnGroup(ChatHandler* handler, char const* args); bool HandleNpcDespawnGroup(ChatHandler* handler, char const* args); using namespace Trinity::ChatCommands; +using GameObjectSpawnId = Variant<Hyperlink<gameobject>, ObjectGuid::LowType>; +using GameObjectEntry = Variant<Hyperlink<gameobject_entry>, uint32>; class gobject_commandscript : public CommandScript { public: @@ -88,19 +90,8 @@ public: return commandTable; } - static bool HandleGameObjectActivateCommand(ChatHandler* handler, char const* args) + static bool HandleGameObjectActivateCommand(ChatHandler* handler, GameObjectSpawnId guidLow) { - if (!*args) - return false; - - char* id = handler->extractKeyFromLink((char*)args, "Hgameobject"); - if (!id) - return false; - - ObjectGuid::LowType guidLow = atoull(id); - if (!guidLow) - return false; - GameObject* object = handler->GetObjectFromPlayerMapByDbGuid(guidLow); if (!object) { @@ -121,22 +112,11 @@ public: } //spawn go - static bool HandleGameObjectAddCommand(ChatHandler* handler, char const* args) + static bool HandleGameObjectAddCommand(ChatHandler* handler, GameObjectEntry objectId, Optional<int32> spawnTimeSecs) { - if (!*args) - return false; - - // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r - char* id = handler->extractKeyFromLink((char*)args, "Hgameobject_entry"); - if (!id) - return false; - - uint32 objectId = atoul(id); if (!objectId) return false; - char* spawntimeSecs = strtok(nullptr, " "); - GameObjectTemplate const* objectInfo = sObjectMgr->GetGameObjectTemplate(objectId); if (!objectInfo) { @@ -148,7 +128,7 @@ public: if (objectInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(objectInfo->displayId)) { // report to DB errors log as in loading case - TC_LOG_ERROR("sql.sql", "Gameobject (Entry %u GoType: %u) have invalid displayId (%u), not spawned.", objectId, objectInfo->type, objectInfo->displayId); + TC_LOG_ERROR("sql.sql", "Gameobject (Entry %u GoType: %u) have invalid displayId (%u), not spawned.", *objectId, objectInfo->type, objectInfo->displayId); handler->PSendSysMessage(LANG_GAMEOBJECT_HAVE_INVALID_DATA, objectId); handler->SetSentErrorMessage(true); return false; @@ -163,11 +143,8 @@ public: PhasingHandler::InheritPhaseShift(object, player); - if (spawntimeSecs) - { - int32 value = atoi(spawntimeSecs); - object->SetRespawnTime(value); - } + if (spawnTimeSecs) + object->SetRespawnTime(*spawnTimeSecs); // fill the gameobject data and save to the db object->SaveToDB(map->GetId(), { map->GetDifficultyID() }); @@ -190,24 +167,11 @@ public: } // add go, temp only - static bool HandleGameObjectAddTempCommand(ChatHandler* handler, char const* args) + static bool HandleGameObjectAddTempCommand(ChatHandler* handler, GameObjectEntry objectId, Optional<uint64> spawntime) { - if (!*args) - return false; - - char* id = strtok((char*)args, " "); - if (!id) - return false; - Player* player = handler->GetSession()->GetPlayer(); + Seconds spawntm(spawntime.value_or(300)); - char* spawntime = strtok(nullptr, " "); - Seconds spawntm = 300s; - - if (spawntime) - spawntm = Seconds(atoul(spawntime)); - - uint32 objectId = atoul(id); if (!sObjectMgr->GetGameObjectTemplate(objectId)) { @@ -221,27 +185,22 @@ public: return true; } - static bool HandleGameObjectTargetCommand(ChatHandler* handler, char const* args) + static bool HandleGameObjectTargetCommand(ChatHandler* handler, Optional<Variant<GameObjectEntry, std::string_view>> objectId) { Player* player = handler->GetSession()->GetPlayer(); QueryResult result; GameEventMgr::ActiveEvents const& activeEventsList = sGameEventMgr->GetActiveEventList(); - if (*args) + if (objectId) { - // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r - char* id = handler->extractKeyFromLink((char*)args, "Hgameobject_entry"); - if (!id) - return false; - - uint32 objectId = atoul(id); - - if (objectId) + if (objectId->holds_alternative<GameObjectEntry>()) + { result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, orientation, map, PhaseId, PhaseGroup, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%i' AND id = '%u' ORDER BY order_ ASC LIMIT 1", - player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), objectId); + player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), static_cast<uint32>(objectId->get<GameObjectEntry>())); + } else { - std::string name = id; + std::string name = std::string(objectId->get<std::string_view>()); WorldDatabase.EscapeString(name); result = WorldDatabase.PQuery( "SELECT guid, id, position_x, position_y, position_z, orientation, map, PhaseId, PhaseGroup, (POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ " @@ -341,7 +300,7 @@ public: } //delete object by selection or guid - static bool HandleGameObjectDeleteCommand(ChatHandler* handler, Variant<Hyperlink<gameobject>, ObjectGuid::LowType> spawnId) + static bool HandleGameObjectDeleteCommand(ChatHandler* handler, GameObjectSpawnId spawnId) { if (GameObject* object = handler->GetObjectFromPlayerMapByDbGuid(spawnId)) { @@ -374,14 +333,8 @@ public: } //turn selected object - static bool HandleGameObjectTurnCommand(ChatHandler* handler, char const* args) + static bool HandleGameObjectTurnCommand(ChatHandler* handler, GameObjectSpawnId guidLow, Optional<float> oz, Optional<float> oy, Optional<float> ox) { - // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r - char* id = handler->extractKeyFromLink((char*)args, "Hgameobject"); - if (!id) - return false; - - ObjectGuid::LowType guidLow = atoull(id); if (!guidLow) return false; @@ -393,32 +346,12 @@ public: return false; } - char* orientation = strtok(nullptr, " "); - float oz = 0.f, oy = 0.f, ox = 0.f; - - if (orientation) - { - oz = float(atof(orientation)); - - orientation = strtok(nullptr, " "); - if (orientation) - { - oy = float(atof(orientation)); - orientation = strtok(nullptr, " "); - if (orientation) - ox = float(atof(orientation)); - } - } - else - { - Player* player = handler->GetSession()->GetPlayer(); - oz = player->GetOrientation(); - } + if (!oz) + oz = handler->GetSession()->GetPlayer()->GetOrientation(); Map* map = object->GetMap(); - - object->Relocate(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), oz); - object->SetLocalRotationAngles(oz, oy, ox); + object->Relocate(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), *oz); + object->SetLocalRotationAngles(*oz, oy.value_or(0.0f), ox.value_or(0.0f)); object->SaveToDB(); // Generate a completely new spawn with new guid @@ -436,14 +369,8 @@ public: } //move selected object - static bool HandleGameObjectMoveCommand(ChatHandler* handler, char const* args) + static bool HandleGameObjectMoveCommand(ChatHandler* handler, GameObjectSpawnId guidLow, Optional<std::array<float,3>> xyz) { - // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r - char* id = handler->extractKeyFromLink((char*)args, "Hgameobject"); - if (!id) - return false; - - ObjectGuid::LowType guidLow = atoull(id); if (!guidLow) return false; @@ -455,36 +382,26 @@ public: return false; } - char* toX = strtok(nullptr, " "); - char* toY = strtok(nullptr, " "); - char* toZ = strtok(nullptr, " "); - - float x, y, z; - if (!toX) + Position pos; + if (xyz) { - Player* player = handler->GetSession()->GetPlayer(); - player->GetPosition(x, y, z); - } - else - { - if (!toY || !toZ) - return false; - - x = (float)atof(toX); - y = (float)atof(toY); - z = (float)atof(toZ); - - if (!MapManager::IsValidMapCoord(object->GetMapId(), x, y, z)) + pos = { (*xyz)[0], (*xyz)[1], (*xyz)[2] }; + if (!MapManager::IsValidMapCoord(object->GetMapId(), pos)) { - handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, x, y, object->GetMapId()); + handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, pos.GetPositionX(), pos.GetPositionY(), object->GetMapId()); handler->SetSentErrorMessage(true); return false; } } + else + { + pos = handler->GetSession()->GetPlayer()->GetPosition(); + } Map* map = object->GetMap(); - object->Relocate(x, y, z, object->GetOrientation()); + pos.SetOrientation(object->GetOrientation()); + object->Relocate(pos); // update which cell has this gameobject registered for loading sObjectMgr->RemoveGameobjectFromGrid(object->GetGameObjectData()); @@ -506,14 +423,8 @@ public: } //set phasemask for selected object - static bool HandleGameObjectSetPhaseCommand(ChatHandler* /*handler*/, char const* /*args*/) + static bool HandleGameObjectSetPhaseCommand(ChatHandler* handler, GameObjectSpawnId guidLow, uint32 phaseId) { - /*// number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r - char* id = handler->extractKeyFromLink((char*)args, "Hgameobject"); - if (!id) - return false; - - ObjectGuid::LowType guidLow = atoull(id); if (!guidLow) return false; @@ -525,23 +436,21 @@ public: return false; } - char* phase = strtok (nullptr, " "); - uint32 phaseMask = phase ? atoul(phase) : 0; - if (phaseMask == 0) + if (!phaseId) { handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); return false; } - object->SetPhaseMask(phaseMask, true); - object->SaveToDB();*/ + PhasingHandler::AddPhase(object, phaseId, true); + object->SaveToDB(); return true; } - static bool HandleGameObjectNearCommand(ChatHandler* handler, char const* args) + static bool HandleGameObjectNearCommand(ChatHandler* handler, Optional<float> dist) { - float distance = (!*args) ? 10.0f : (float)(atof(args)); + float distance = dist.value_or(10.0f); uint32 count = 0; Player* player = handler->GetSession()->GetPlayer(); @@ -585,7 +494,7 @@ public: } //show info of gameobject - static bool HandleGameObjectInfoCommand(ChatHandler* handler, char const* args) + static bool HandleGameObjectInfoCommand(ChatHandler* handler, Optional<ExactSequence<'g', 'u', 'i', 'd'>> isGuid, Variant<Hyperlink<gameobject_entry>, Hyperlink<gameobject>, uint32> data) { uint32 entry = 0; uint32 type = 0; @@ -593,37 +502,26 @@ public: std::string name; uint32 lootId = 0; - if (!*args) - return false; - - char* param1 = handler->extractKeyFromLink((char*)args, "Hgameobject_entry"); - if (!param1) - return false; - GameObject* thisGO = nullptr; - GameObjectData const* data = nullptr; + GameObjectData const* spawnData = nullptr; ObjectGuid::LowType spawnId = 0; - if (strcmp(param1, "guid") == 0) + if (isGuid || data.holds_alternative<Hyperlink<gameobject>>()) { - char* tail = strtok(nullptr, ""); - char* cValue = handler->extractKeyFromLink(tail, "Hgameobject"); - if (!cValue) - return false; - spawnId = atoull(cValue); - data = sObjectMgr->GetGameObjectData(spawnId); - if (!data) + spawnId = *data; + spawnData = sObjectMgr->GetGameObjectData(spawnId); + if (!spawnData) { handler->PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, spawnId); handler->SetSentErrorMessage(true); return false; } - entry = data->id; + entry = spawnData->id; thisGO = handler->GetObjectFromPlayerMapByDbGuid(spawnId); } else { - entry = atoul(param1); + entry = *data; } GameObjectTemplate const* gameObjectInfo = sObjectMgr->GetGameObjectTemplate(entry); @@ -658,11 +556,11 @@ public: handler->PSendSysMessage(LANG_GOINFO_ADDON, goOverride->Faction, goOverride->Flags); } - if (data) + if (spawnData) { float yaw, pitch, roll; - data->rotation.toEulerAnglesZYX(yaw, pitch, roll); - handler->PSendSysMessage(LANG_SPAWNINFO_SPAWNID_LOCATION, std::to_string(data->spawnId), data->spawnPoint.GetPositionX(), data->spawnPoint.GetPositionY(), data->spawnPoint.GetPositionZ()); + spawnData->rotation.toEulerAnglesZYX(yaw, pitch, roll); + handler->PSendSysMessage(LANG_SPAWNINFO_SPAWNID_LOCATION, std::to_string(spawnData->spawnId), spawnData->spawnPoint.GetPositionX(), spawnData->spawnPoint.GetPositionY(), spawnData->spawnPoint.GetPositionZ()); handler->PSendSysMessage(LANG_SPAWNINFO_ROTATION, yaw, pitch, roll); } @@ -682,14 +580,8 @@ public: return true; } - static bool HandleGameObjectSetStateCommand(ChatHandler* handler, char const* args) + static bool HandleGameObjectSetStateCommand(ChatHandler* handler, GameObjectSpawnId guidLow, int32 objectType, Optional<int32> objectState) { - // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r - char* id = handler->extractKeyFromLink((char*)args, "Hgameobject"); - if (!id) - return false; - - ObjectGuid::LowType guidLow = atoull(id); if (!guidLow) return false; @@ -701,11 +593,6 @@ public: return false; } - char* type = strtok(nullptr, " "); - if (!type) - return false; - - int32 objectType = atoi(type); if (objectType < 0) { if (objectType == -1) @@ -715,40 +602,36 @@ public: return true; } - char* state = strtok(nullptr, " "); - if (!state) + if (!objectState) return false; - int32 objectState = atoi(state); - switch (objectType) { case 0: - object->SetGoState(GOState(objectState)); + object->SetGoState(GOState(*objectState)); break; case 1: - object->SetGoType(GameobjectTypes(objectState)); + object->SetGoType(GameobjectTypes(*objectState)); break; case 2: - object->SetGoArtKit(objectState); + object->SetGoArtKit(*objectState); break; case 3: - object->SetGoAnimProgress(objectState); + object->SetGoAnimProgress(*objectState); break; case 4: - object->SendCustomAnim(objectState); + object->SendCustomAnim(*objectState); break; case 5: if (objectState < 0 || objectState > GO_DESTRUCTIBLE_REBUILDING) return false; - object->SetDestructibleState(GameObjectDestructibleState(objectState)); + object->SetDestructibleState(GameObjectDestructibleState(*objectState)); break; default: break; } - - handler->PSendSysMessage("Set gobject type %d state %d", objectType, objectState); + handler->PSendSysMessage("Set gobject type %d state %u", objectType, *objectState); return true; } }; |