diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 60849c1ae..63f59f73b 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4367,7 +4367,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { safe_delete(outapp); /* Update the boat's position on the server, without sending an update */ - cmob->GMMove(ppu->x_pos, ppu->y_pos, ppu->z_pos, EQ12toFloat(ppu->heading), false); + cmob->GMMove(ppu->x_pos, ppu->y_pos, ppu->z_pos, EQ12toFloat(ppu->heading)); return; } else { diff --git a/zone/command.cpp b/zone/command.cpp index 41aa2a1a7..375674bd6 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -361,7 +361,7 @@ int command_init(void) 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) || + command_add("summon", "[Character Name] - Summons your corpse, NPC, or player target, or by character name if specified", AccountStatus::QuestTroupe, command_summon) || command_add("summonburiedplayercorpse", "- Summons the target's oldest buried corpse, if any exist.", AccountStatus::GMAdmin, command_summonburiedplayercorpse) || command_add("summonitem", "[itemid] [charges] - Summon an item onto your cursor. Charges are optional.", AccountStatus::GMMgmt, command_summonitem) || command_add("suspend", "[name] [days] [reason] - Suspend by character name and for specificed number of days", AccountStatus::GMLeadAdmin, command_suspend) || diff --git a/zone/gm_commands/summon.cpp b/zone/gm_commands/summon.cpp index 586217112..eb496c2ab 100755 --- a/zone/gm_commands/summon.cpp +++ b/zone/gm_commands/summon.cpp @@ -7,82 +7,79 @@ extern WorldServer worldserver; void command_summon(Client *c, const Seperator *sep) { - Mob *t; + int arguments = sep->argnum; + if (!arguments && !c->GetTarget()) { + c->Message(Chat::White, "Usage: #summon - Summon your target, if you have one, to your position"); + c->Message(Chat::White, "Usage: #summon [Character Name] - Summon a character by name to your position"); + c->Message(Chat::White, "Note: You may also summon your target if you have one."); + return; + } - if (sep->arg[1][0] != 0) // arg specified - { - Client *client = entity_list.GetClientByName(sep->arg[1]); - if (client != 0) { // found player in zone - t = client->CastToMob(); - } - else { - if (!worldserver.Connected()) { - c->Message(Chat::White, "Error: World server disconnected."); - } - else { // player is in another zone - //Taking this command out until we test the factor of 8 in ServerOP_ZonePlayer - //c->Message(Chat::White, "Summoning player from another zone not yet implemented."); - //return; + Mob* target; - auto pack = new ServerPacket(ServerOP_ZonePlayer, sizeof(ServerZonePlayer_Struct)); - ServerZonePlayer_Struct *szp = (ServerZonePlayer_Struct *) pack->pBuffer; - strcpy(szp->adminname, c->GetName()); - szp->adminrank = c->Admin(); - szp->ignorerestrictions = 2; - strcpy(szp->name, sep->arg[1]); - strcpy(szp->zone, zone->GetShortName()); - szp->x_pos = c->GetX(); // May need to add a factor of 8 in here.. - szp->y_pos = c->GetY(); - szp->z_pos = c->GetZ(); - szp->instance_id = zone->GetInstanceID(); - worldserver.SendPacket(pack); - safe_delete(pack); - } + if (arguments == 1) { + std::string character_name = sep->arg[1]; + auto character_id = database.GetCharacterID(character_name.c_str()); + if (!character_id) { + c->Message( + Chat::White, + fmt::format( + "Character '{}' does not exist.", + character_name + ).c_str() + ); return; } + + auto search_client = entity_list.GetClientByName(character_name.c_str()); + if (search_client) { + target = search_client->CastToMob(); + } else { + if (!worldserver.Connected()) { + c->Message(Chat::White, "World server is currently disconnected."); + return; + } + + auto pack = new ServerPacket(ServerOP_ZonePlayer, sizeof(ServerZonePlayer_Struct)); + auto szp = (ServerZonePlayer_Struct *) pack->pBuffer; + strn0cpy(szp->adminname, c->GetName(), sizeof(szp->adminname)); + szp->adminrank = c->Admin(); + szp->ignorerestrictions = 2; + strn0cpy(szp->name, character_name.c_str(), sizeof(szp->name)); + strn0cpy(szp->zone, zone->GetShortName(), sizeof(szp->zone)); + szp->x_pos = c->GetX(); + szp->y_pos = c->GetY(); + szp->z_pos = c->GetZ(); + szp->instance_id = zone->GetInstanceID(); + worldserver.SendPacket(pack); + safe_delete(pack); + return; + } + } else if (c->GetTarget()) { + target = c->GetTarget(); } - else if (c->GetTarget()) { // have target - t = c->GetTarget(); - } - else { - c->Message(Chat::White, "Usage: #summon [charname] Either target or charname is required"); + + if (c == target) { + c->Message(Chat::White, "You cannot summon yourself."); return; } + + c->Message( + Chat::White, + fmt::format( + "Summoning {} ({}) to {:.2f}, {:.2f}, {:.2f} in {} ({}).", + target->GetCleanName(), + target->GetID(), + c->GetX(), + c->GetY(), + c->GetZ(), + zone->GetLongName(), + zone->GetZoneID() + ).c_str() + ); - if (!t) { - return; - } - - if (t->IsNPC()) { // npc target - c->Message( - Chat::White, - "Summoning NPC %s to %1.1f, %1.1f, %1.1f", - t->GetName(), - c->GetX(), - c->GetY(), - c->GetZ()); - t->CastToNPC()->GMMove(c->GetX(), c->GetY(), c->GetZ(), c->GetHeading()); - t->CastToNPC()->SaveGuardSpot(glm::vec4(0.0f)); - } - else if (t->IsCorpse()) { // corpse target - c->Message( - Chat::White, - "Summoning corpse %s to %1.1f, %1.1f, %1.1f", - t->GetName(), - c->GetX(), - c->GetY(), - c->GetZ()); - t->CastToCorpse()->GMMove(c->GetX(), c->GetY(), c->GetZ(), c->GetHeading()); - } - else if (t->IsClient()) { - c->Message( - Chat::White, - "Summoning player %s to %1.1f, %1.1f, %1.1f", - t->GetName(), - c->GetX(), - c->GetY(), - c->GetZ()); - t->CastToClient()->MovePC( + if (target->IsClient()) { + target->CastToClient()->MovePC( zone->GetZoneID(), zone->GetInstanceID(), c->GetX(), @@ -92,6 +89,13 @@ void command_summon(Client *c, const Seperator *sep) 2, GMSummon ); + return; + } + + target->GMMove(c->GetPosition()); + + if (target->IsNPC()) { + target->CastToNPC()->SaveGuardSpot(glm::vec4(0.0f)); } } diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 72ae13cad..fa3a03c9d 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -287,11 +287,6 @@ void Lua_Mob::GMMove(double x, double y, double z, double heading) { self->GMMove(static_cast(x), static_cast(y), static_cast(z), static_cast(heading)); } -void Lua_Mob::GMMove(double x, double y, double z, double heading, bool send_update) { - Lua_Safe_Call_Void(); - self->GMMove(static_cast(x), static_cast(y), static_cast(z), static_cast(heading), send_update); -} - void Lua_Mob::TryMoveAlong(float distance, float angle) { Lua_Safe_Call_Void(); self->TryMoveAlong(distance, angle); @@ -2605,7 +2600,6 @@ luabind::scope lua_register_mob() { .def("FindType", (bool(Lua_Mob::*)(int,bool,int))&Lua_Mob::FindType) .def("GMMove", (void(Lua_Mob::*)(double,double,double))&Lua_Mob::GMMove) .def("GMMove", (void(Lua_Mob::*)(double,double,double,double))&Lua_Mob::GMMove) - .def("GMMove", (void(Lua_Mob::*)(double,double,double,double,bool))&Lua_Mob::GMMove) .def("GetAA", (int(Lua_Mob::*)(int))&Lua_Mob::GetAA) .def("GetAABonuses", &Lua_Mob::GetAABonuses) .def("GetAAByAAID", (int(Lua_Mob::*)(int))&Lua_Mob::GetAAByAAID) diff --git a/zone/lua_mob.h b/zone/lua_mob.h index 17b0dc4fb..604b6c52d 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -79,7 +79,6 @@ public: void RandomizeFeatures(bool send_illusion, bool save_variables); void GMMove(double x, double y, double z); void GMMove(double x, double y, double z, double heading); - void GMMove(double x, double y, double z, double heading, bool send_update); void TryMoveAlong(float distance, float heading); void TryMoveAlong(float distance, float heading, bool send); bool HasProcs(); diff --git a/zone/mob.cpp b/zone/mob.cpp index c1f8d670c..8e0d70c99 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2433,7 +2433,7 @@ void Mob::ShowBuffList(Client* client) { } } -void Mob::GMMove(float x, float y, float z, float heading, bool SendUpdate) { +void Mob::GMMove(float x, float y, float z, float heading) { m_Position.x = x; m_Position.y = y; m_Position.z = z; @@ -2445,6 +2445,18 @@ void Mob::GMMove(float x, float y, float z, float heading, bool SendUpdate) { } } +void Mob::GMMove(const glm::vec4 &position) { + m_Position.x = position.x; + m_Position.y = position.y; + m_Position.z = position.z; + SetHeading(position.w); + mMovementManager->SendCommandToClients(this, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny); + + if (IsNPC()) { + CastToNPC()->SaveGuardSpot(position); + } +} + void Mob::SendIllusionPacket( uint16 in_race, uint8 in_gender, diff --git a/zone/mob.h b/zone/mob.h index 00b8c1be6..0e44c29bb 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -655,7 +655,8 @@ public: float GetMovespeed() const { return IsRunning() ? GetRunspeed() : GetWalkspeed(); } bool IsRunning() const { return m_is_running; } void SetRunning(bool val) { m_is_running = val; } - virtual void GMMove(float x, float y, float z, float heading = 0.01, bool SendUpdate = true); + virtual void GMMove(float x, float y, float z, float heading = 0.01); + virtual void GMMove(const glm::vec4 &position); void SetDelta(const glm::vec4& delta); void MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct* spu); void MakeSpawnUpdate(PlayerPositionUpdateServer_Struct* spu); diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 18a5f9c28..1c8f65e47 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -625,41 +625,52 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } case ServerOP_ZonePlayer: { ServerZonePlayer_Struct* szp = (ServerZonePlayer_Struct*)pack->pBuffer; - Client* client = entity_list.GetClientByName(szp->name); - // printf("Zoning %s to %s(%u) - %u\n", client != nullptr ? client->GetCleanName() : "Unknown", szp->zone, ZoneID(szp->zone), szp->instance_id); + auto client = entity_list.GetClientByName(szp->name); if (client) { - if (strcasecmp(szp->adminname, szp->name) == 0) - client->Message(Chat::White, "Zoning to: %s", szp->zone); - else if (client->GetAnon() == 1 && client->Admin() > szp->adminrank) + if (!strcasecmp(szp->adminname, szp->name)) { + client->Message( + Chat::White, + fmt::format( + "Zoning to {} ({}).", + ZoneLongName( + ZoneID(szp->zone) + ), + ZoneID(szp->zone) + ).c_str() + ); + } else if (client->GetAnon() == 1 && client->Admin() > szp->adminrank) { break; - else { + } else { + std::string name = str_tolower(szp->name); + name[0] = toupper(name[0]); + SendEmoteMessage( szp->adminname, 0, Chat::White, fmt::format( - "Summoning {} to {} at {:.2f}, {:.2f}, {:.2f}", - szp->name, - szp->zone, + "Summoning {} to {:.2f}, {:.2f}, {:.2f} in {} ({}).", + name, szp->x_pos, szp->y_pos, - szp->z_pos + szp->z_pos, + ZoneLongName( + ZoneID(szp->zone) + ), + ZoneID(szp->zone) ).c_str() ); } + if (!szp->instance_id) { client->MovePC(ZoneID(szp->zone), szp->instance_id, szp->x_pos, szp->y_pos, szp->z_pos, client->GetHeading(), szp->ignorerestrictions, GMSummon); - } - else { - if (database.GetInstanceID(client->CharacterID(), ZoneID(szp->zone)) == 0) { - client->AssignToInstance(szp->instance_id); - client->MovePC(ZoneID(szp->zone), szp->instance_id, szp->x_pos, szp->y_pos, szp->z_pos, client->GetHeading(), szp->ignorerestrictions, GMSummon); - } - else { + } else { + if (database.GetInstanceID(client->CharacterID(), ZoneID(szp->zone))) { client->RemoveFromInstance(database.GetInstanceID(client->CharacterID(), ZoneID(szp->zone))); - client->AssignToInstance(szp->instance_id); - client->MovePC(ZoneID(szp->zone), szp->instance_id, szp->x_pos, szp->y_pos, szp->z_pos, client->GetHeading(), szp->ignorerestrictions, GMSummon); } + + client->AssignToInstance(szp->instance_id); + client->MovePC(ZoneID(szp->zone), szp->instance_id, szp->x_pos, szp->y_pos, szp->z_pos, client->GetHeading(), szp->ignorerestrictions, GMSummon); } } break;