mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Scripts/Commands: Convert argument parsing of gameobject commands
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -192,6 +192,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; }
|
||||
|
||||
|
||||
@@ -48,6 +48,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:
|
||||
@@ -86,19 +88,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 = atoul(id);
|
||||
if (!guidLow)
|
||||
return false;
|
||||
|
||||
GameObject* object = handler->GetObjectFromPlayerMapByDbGuid(guidLow);
|
||||
if (!object)
|
||||
{
|
||||
@@ -119,22 +110,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)
|
||||
{
|
||||
@@ -146,7 +126,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;
|
||||
@@ -165,11 +145,8 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (spawntimeSecs)
|
||||
{
|
||||
int32 value = atoi((char*)spawntimeSecs);
|
||||
object->SetRespawnTime(value);
|
||||
}
|
||||
if (spawnTimeSecs)
|
||||
object->SetRespawnTime(*spawnTimeSecs);
|
||||
|
||||
// fill the gameobject data and save to the db
|
||||
object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMaskForSpawn());
|
||||
@@ -195,25 +172,12 @@ 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();
|
||||
|
||||
char* spawntime = strtok(nullptr, " ");
|
||||
Seconds spawntm = 300s;
|
||||
|
||||
if (spawntime)
|
||||
spawntm = Seconds(atoul(spawntime));
|
||||
Seconds spawntm(spawntime.value_or(300));
|
||||
|
||||
QuaternionData rotation = QuaternionData::fromEulerAnglesZYX(player->GetOrientation(), 0.f, 0.f);
|
||||
uint32 objectId = atoul(id);
|
||||
|
||||
if (!sObjectMgr->GetGameObjectTemplate(objectId))
|
||||
{
|
||||
@@ -227,27 +191,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, phaseMask, (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, phaseMask, (POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ "
|
||||
@@ -346,7 +305,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))
|
||||
{
|
||||
@@ -378,14 +337,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 = atoul(id);
|
||||
if (!guidLow)
|
||||
return false;
|
||||
|
||||
@@ -397,31 +350,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
|
||||
@@ -442,14 +376,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 = atoul(id);
|
||||
if (!guidLow)
|
||||
return false;
|
||||
|
||||
@@ -461,36 +389,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(guidLow, object->GetGameObjectData());
|
||||
@@ -515,14 +433,8 @@ public:
|
||||
}
|
||||
|
||||
//set phasemask for selected object
|
||||
static bool HandleGameObjectSetPhaseCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleGameObjectSetPhaseCommand(ChatHandler* handler, GameObjectSpawnId guidLow, uint32 phaseMask)
|
||||
{
|
||||
// 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 = atoul(id);
|
||||
if (!guidLow)
|
||||
return false;
|
||||
|
||||
@@ -534,9 +446,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
char* phase = strtok (nullptr, " ");
|
||||
uint32 phaseMask = phase ? atoul(phase) : 0;
|
||||
if (phaseMask == 0)
|
||||
if (!phaseMask)
|
||||
{
|
||||
handler->SendSysMessage(LANG_BAD_VALUE);
|
||||
handler->SetSentErrorMessage(true);
|
||||
@@ -548,9 +458,9 @@ public:
|
||||
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();
|
||||
@@ -594,7 +504,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;
|
||||
@@ -602,37 +512,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 = atoul(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);
|
||||
@@ -670,11 +569,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, data->spawnId, data->spawnPoint.GetPositionX(), data->spawnPoint.GetPositionY(), data->spawnPoint.GetPositionZ());
|
||||
spawnData->rotation.toEulerAnglesZYX(yaw, pitch, roll);
|
||||
handler->PSendSysMessage(LANG_SPAWNINFO_SPAWNID_LOCATION, spawnData->spawnId, spawnData->spawnPoint.GetPositionX(), spawnData->spawnPoint.GetPositionY(), spawnData->spawnPoint.GetPositionZ());
|
||||
handler->PSendSysMessage(LANG_SPAWNINFO_ROTATION, yaw, pitch, roll);
|
||||
}
|
||||
|
||||
@@ -694,14 +593,8 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleGameObjectSetStateCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleGameObjectSetStateCommand(ChatHandler* handler, GameObjectSpawnId guidLow, int32 objectType, Optional<uint32> 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 = atoul(id);
|
||||
if (!guidLow)
|
||||
return false;
|
||||
|
||||
@@ -713,11 +606,6 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
char* type = strtok(nullptr, " ");
|
||||
if (!type)
|
||||
return false;
|
||||
|
||||
int32 objectType = atoi(type);
|
||||
if (objectType < 0)
|
||||
{
|
||||
if (objectType == -1)
|
||||
@@ -727,22 +615,19 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
char* state = strtok(nullptr, " ");
|
||||
if (!state)
|
||||
if (!objectState)
|
||||
return false;
|
||||
|
||||
int32 objectState = atoi(state);
|
||||
|
||||
if (objectType < 4)
|
||||
object->SetByteValue(GAMEOBJECT_BYTES_1, objectType, objectState);
|
||||
object->SetByteValue(GAMEOBJECT_BYTES_1, objectType, *objectState);
|
||||
else if (objectType == 4)
|
||||
{
|
||||
WorldPacket data(SMSG_GAMEOBJECT_CUSTOM_ANIM, 8+4);
|
||||
data << object->GetGUID();
|
||||
data << (uint32)(objectState);
|
||||
data << static_cast<uint32>(*objectState);
|
||||
object->SendMessageToSet(&data, true);
|
||||
}
|
||||
handler->PSendSysMessage("Set gobject type %d state %d", objectType, objectState);
|
||||
handler->PSendSysMessage("Set gobject type %d state %u", objectType, *objectState);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user