diff --git a/zone/client.h b/zone/client.h index 4253e6643..3d3f0ad5c 100644 --- a/zone/client.h +++ b/zone/client.h @@ -633,6 +633,9 @@ public: void MovePC(uint32 zoneID, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited); void MovePC(float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited); void MovePC(uint32 zoneID, uint32 instanceID, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited); + void MoveZone(const char *zone_short_name); + void MoveZoneGroup(const char *zone_short_name); + void MoveZoneRaid(const char *zone_short_name); void SendToGuildHall(); void AssignToInstance(uint16 instance_id); void RemoveFromInstance(uint16 instance_id); diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 5898215f3..006e38b1f 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -325,6 +325,21 @@ void Lua_Client::MovePCInstance(int zone, int instance, float x, float y, float self->MovePC(zone, instance, x, y, z, heading); } +void Lua_Client::MoveZone(const char *zone_short_name) { + Lua_Safe_Call_Void(); + self->MoveZone(zone_short_name); +} + +void Lua_Client::MoveZoneGroup(const char *zone_short_name) { + Lua_Safe_Call_Void(); + self->MoveZoneGroup(zone_short_name); +} + +void Lua_Client::MoveZoneRaid(const char *zone_short_name) { + Lua_Safe_Call_Void(); + self->MoveZoneRaid(zone_short_name); +} + void Lua_Client::ChangeLastName(const char *in) { Lua_Safe_Call_Void(); self->ChangeLastName(in); @@ -1648,6 +1663,9 @@ luabind::scope lua_register_client() { .def("SetSecondaryWeaponOrnamentation", (void(Lua_Client::*)(uint32))&Lua_Client::SetSecondaryWeaponOrnamentation) .def("MovePC", (void(Lua_Client::*)(int,float,float,float,float))&Lua_Client::MovePC) .def("MovePCInstance", (void(Lua_Client::*)(int,int,float,float,float,float))&Lua_Client::MovePCInstance) + .def("MoveZone", (void(Lua_Client::*)(const char*))&Lua_Client::MoveZone) + .def("MoveZoneGroup", (void(Lua_Client::*)(const char*))&Lua_Client::MoveZoneGroup) + .def("MoveZoneRaid", (void(Lua_Client::*)(const char*))&Lua_Client::MoveZoneRaid) .def("ChangeLastName", (void(Lua_Client::*)(const char *in))&Lua_Client::ChangeLastName) .def("GetFactionLevel", (int(Lua_Client::*)(uint32,uint32,uint32,uint32,uint32,uint32,Lua_NPC))&Lua_Client::GetFactionLevel) .def("SetFactionLevel", (void(Lua_Client::*)(uint32,uint32,int,int,int))&Lua_Client::SetFactionLevel) diff --git a/zone/lua_client.h b/zone/lua_client.h index 600b594f2..49b49130f 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -91,6 +91,9 @@ public: uint32 GetBindZoneID(int index); void MovePC(int zone, float x, float y, float z, float heading); void MovePCInstance(int zone, int instance, float x, float y, float z, float heading); + void MoveZone(const char *zone_short_name); + void MoveZoneGroup(const char *zone_short_name); + void MoveZoneRaid(const char *zone_short_name); void ChangeLastName(const char *in); int GetFactionLevel(uint32 char_id, uint32 npc_id, uint32 race, uint32 class_, uint32 deity, uint32 faction, Lua_NPC npc); void SetFactionLevel(uint32 char_id, uint32 npc_id, int char_class, int char_race, int char_deity); diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index ff17e041c..17e610078 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -1319,6 +1319,132 @@ XS(XS_Client_MovePCInstance) { XSRETURN_EMPTY; } +XS(XS_Client_MoveZone); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_MoveZone) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::MoveZone(THIS, string zone_short_name)"); + { + Client *THIS; + const char *zone_short_name = (const char *) SvPV_nolen(ST(1)); + + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + if (THIS->IsClient()) { + THIS->MoveZone(zone_short_name); + } else { + if (THIS->IsMerc()) { + LogDebug("[CLIENT] Perl(XS_Client_MoveZone) attempted to process a type Merc reference"); + } +#ifdef BOTS + else if (THIS->IsBot()) { + LogDebug("[CLIENT] Perl(XS_Client_MoveZone) attempted to process a type Bot reference"); + } +#endif + else if (THIS->IsNPC()) { + LogDebug("[CLIENT] Perl(XS_Client_MoveZone) attempted to process a type NPC reference"); + } + else { + LogDebug("[CLIENT] Perl(XS_Client_MoveZone) attempted to process an Unknown type reference"); + } + + Perl_croak(aTHX_ "THIS is not of type Client"); + } + + } + XSRETURN_EMPTY; +} + +XS(XS_Client_MoveZoneGroup); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_MoveZoneGroup) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::MoveZoneGroup(THIS, string zone_short_name)"); + { + Client *THIS; + const char *zone_short_name = (const char *) SvPV_nolen(ST(1)); + + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + if (THIS->IsClient()) { + THIS->MoveZoneGroup(zone_short_name); + } else { + if (THIS->IsMerc()) { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneGroup) attempted to process a type Merc reference"); + } +#ifdef BOTS + else if (THIS->IsBot()) { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneGroup) attempted to process a type Bot reference"); + } +#endif + else if (THIS->IsNPC()) { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneGroup) attempted to process a type NPC reference"); + } + else { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneGroup) attempted to process an Unknown type reference"); + } + + Perl_croak(aTHX_ "THIS is not of type Client"); + } + + } + XSRETURN_EMPTY; +} + +XS(XS_Client_MoveZoneRaid); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_MoveZoneRaid) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::MoveZoneRaid(THIS, string zone_short_name)"); + { + Client *THIS; + const char *zone_short_name = (const char *) SvPV_nolen(ST(1)); + + if (sv_derived_from(ST(0), "Client")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(Client *, tmp); + } else + Perl_croak(aTHX_ "THIS is not of type Client"); + if (THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + if (THIS->IsClient()) { + THIS->MoveZoneRaid(zone_short_name); + } else { + if (THIS->IsMerc()) { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneRaid) attempted to process a type Merc reference"); + } +#ifdef BOTS + else if (THIS->IsBot()) { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneRaid) attempted to process a type Bot reference"); + } +#endif + else if (THIS->IsNPC()) { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneRaid) attempted to process a type NPC reference"); + } + else { + LogDebug("[CLIENT] Perl(XS_Client_MoveZoneRaid) attempted to process an Unknown type reference"); + } + + Perl_croak(aTHX_ "THIS is not of type Client"); + } + + } + XSRETURN_EMPTY; +} + XS(XS_Client_ChangeLastName); /* prototype to pass -Wmissing-prototypes */ XS(XS_Client_ChangeLastName) { dXSARGS; @@ -6537,6 +6663,9 @@ XS(boot_Client) { newXSproto(strcpy(buf, "MemSpell"), XS_Client_MemSpell, file, "$$$;$"); newXSproto(strcpy(buf, "MovePC"), XS_Client_MovePC, file, "$$$$$$"); newXSproto(strcpy(buf, "MovePCInstance"), XS_Client_MovePCInstance, file, "$$$$$$$"); + newXSproto(strcpy(buf, "MoveZone"), XS_Client_MoveZone, file, "$$"); + newXSproto(strcpy(buf, "MoveZoneGroup"), XS_Client_MoveZoneGroup, file, "$$"); + newXSproto(strcpy(buf, "MoveZoneRaid"), XS_Client_MoveZoneRaid, file, "$$"); newXSproto(strcpy(buf, "NPCSpawn"), XS_Client_NPCSpawn, file, "$$$;$"); newXSproto(strcpy(buf, "NukeItem"), XS_Client_NukeItem, file, "$$;$"); newXSproto(strcpy(buf, "OpenLFGuildWindow"), XS_Client_OpenLFGuildWindow, file, "$"); diff --git a/zone/zoning.cpp b/zone/zoning.cpp index 7a04cfeae..a22d5e250 100644 --- a/zone/zoning.cpp +++ b/zone/zoning.cpp @@ -418,6 +418,48 @@ void Client::MovePC(uint32 zoneID, uint32 instanceID, float x, float y, float z, ProcessMovePC(zoneID, instanceID, x, y, z, heading, ignorerestrictions, zm); } +void Client::MoveZone(const char *zone_short_name) { + auto pack = new ServerPacket(ServerOP_ZoneToZoneRequest, sizeof(ZoneToZone_Struct)); + ZoneToZone_Struct* ztz = (ZoneToZone_Struct*) pack->pBuffer; + ztz->response = 0; + ztz->current_zone_id = zone->GetZoneID(); + ztz->current_instance_id = zone->GetInstanceID(); + ztz->requested_zone_id = database.GetZoneID(zone_short_name); + ztz->admin = Admin(); + strcpy(ztz->name, GetName()); + ztz->guild_id = GuildID(); + ztz->ignorerestrictions = 3; + worldserver.SendPacket(pack); + safe_delete(pack); +} + +void Client::MoveZoneGroup(const char *zone_short_name) { + if (!GetGroup()) { + MoveZone(zone_short_name); + } else { + auto client_group = GetGroup(); + for (int member_index = 0; member_index < MAX_GROUP_MEMBERS; member_index++) { + if (client_group->members[member_index] && client_group->members[member_index]->IsClient()) { + auto group_member = client_group->members[member_index]->CastToClient(); + group_member->MoveZone(zone_short_name); + } + } + } +} + +void Client::MoveZoneRaid(const char *zone_short_name) { + if (!GetRaid()) { + MoveZone(zone_short_name); + } else { + auto client_raid = GetRaid(); + for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) { + if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) { + auto raid_member = client_raid->members[member_index].member->CastToClient(); + raid_member->MoveZone(zone_short_name); + } + } + } +} void Client::ProcessMovePC(uint32 zoneID, uint32 instance_id, float x, float y, float z, float heading, uint8 ignorerestrictions, ZoneMode zm) {