diff --git a/zone/client.cpp b/zone/client.cpp index 13ac70be8..4ba0cf9f1 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -6270,6 +6270,11 @@ void Client::AssignToInstance(uint16 instance_id) database.AddClientToInstance(instance_id, CharacterID()); } +void Client::RemoveFromInstance(uint16 instance_id) +{ + database.RemoveClientFromInstance(instance_id, CharacterID()); +} + void Client::SendStatsWindow(Client* client, bool use_window) { // Define the types of page breaks we need diff --git a/zone/client.h b/zone/client.h index 598fc8bce..7dfaee9e8 100644 --- a/zone/client.h +++ b/zone/client.h @@ -584,6 +584,7 @@ public: 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 AssignToInstance(uint16 instance_id); + void RemoveFromInstance(uint16 instance_id); void WhoAll(); bool CheckLoreConflict(const Item_Struct* item); void ChangeLastName(const char* in_lastname); diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index 6e337cc03..cdd5eb6c9 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -2859,14 +2859,49 @@ XS(XS__GetInstanceID) { XSRETURN_UV(id); } +XS(XS__GetCharactersInInstance); +XS(XS__GetCharactersInInstance) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: GetCharactersInInstance(instance_id)"); + dXSTARG; + + Const_char * RETVAL; + uint16 instance_id = (int)SvUV(ST(0)); + std::list charid_list; + std::string charid_string; + + database.GetCharactersInInstance(instance_id, charid_list); + + if (charid_list.size() > 0) + { + charid_string = itoa(charid_list.size()); + charid_string += " player(s) in instance. CharID list: "; + auto iter = charid_list.begin(); + while (iter != charid_list.end()) + { + charid_string += itoa(*iter); + ++iter; + if (iter != charid_list.end()) + charid_string += ", "; + } + RETVAL = charid_string.c_str(); + } + else + RETVAL = "No players in that instance."; + + sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; + XSRETURN(1); +} + XS(XS__AssignToInstance); XS(XS__AssignToInstance) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: AssignToInstance(id)"); + Perl_croak(aTHX_ "Usage: AssignToInstance(instance_id)"); - uint16 id = (int)SvUV(ST(0)); - quest_manager.AssignToInstance(id); + uint16 instance_id = (int)SvUV(ST(0)); + quest_manager.AssignToInstance(instance_id); XSRETURN_EMPTY; } @@ -2875,10 +2910,10 @@ XS(XS__AssignGroupToInstance); XS(XS__AssignGroupToInstance) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: AssignGroupToInstance(id)"); + Perl_croak(aTHX_ "Usage: AssignGroupToInstance(instance_id)"); - uint16 id = (int)SvUV(ST(0)); - quest_manager.AssignGroupToInstance(id); + uint16 instance_id = (int)SvUV(ST(0)); + quest_manager.AssignGroupToInstance(instance_id); XSRETURN_EMPTY; } @@ -2887,10 +2922,34 @@ XS(XS__AssignRaidToInstance); XS(XS__AssignRaidToInstance) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: AssignRaidToInstance(id)"); + Perl_croak(aTHX_ "Usage: AssignRaidToInstance(instance_id)"); - uint16 id = (int)SvUV(ST(0)); - quest_manager.AssignRaidToInstance(id); + uint16 instance_id = (int)SvUV(ST(0)); + quest_manager.AssignRaidToInstance(instance_id); + + XSRETURN_EMPTY; +} + +XS(XS__RemoveFromInstance); +XS(XS__RemoveFromInstance) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: RemoveFromInstance(instance_id)"); + + uint16 instance_id = (int)SvUV(ST(0)); + quest_manager.RemoveFromInstance(instance_id); + + XSRETURN_EMPTY; +} + +XS(XS__RemoveAllFromInstance); +XS(XS__RemoveAllFromInstance) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: RemoveAllFromInstance(instance_id)"); + + uint16 instance_id = (int)SvUV(ST(0)); + quest_manager.RemoveAllFromInstance(instance_id); XSRETURN_EMPTY; } @@ -3628,9 +3687,12 @@ EXTERN_C XS(boot_quest) newXS(strcpy(buf, "CreateInstance"), XS__CreateInstance, file); newXS(strcpy(buf, "DestroyInstance"), XS__DestroyInstance, file); newXS(strcpy(buf, "GetInstanceID"), XS__GetInstanceID, file); + newXS(strcpy(buf, "GetCharactersInInstance"), XS__GetCharactersInInstance, file); newXS(strcpy(buf, "AssignToInstance"), XS__AssignToInstance, file); newXS(strcpy(buf, "AssignGroupToInstance"), XS__AssignGroupToInstance, file); newXS(strcpy(buf, "AssignRaidToInstance"), XS__AssignRaidToInstance, file); + newXS(strcpy(buf, "RemoveFromInstance"), XS__RemoveFromInstance, file); + newXS(strcpy(buf, "RemoveAllFromInstance"), XS__RemoveAllFromInstance, file); newXS(strcpy(buf, "MovePCInstance"), XS__MovePCInstance, file); newXS(strcpy(buf, "FlagInstanceByGroupLeader"), XS__FlagInstanceByGroupLeader, file); newXS(strcpy(buf, "FlagInstanceByRaidLeader"), XS__FlagInstanceByRaidLeader, file); diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index a33e9a8b9..aaaa5899f 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -5337,6 +5337,30 @@ XS(XS_Client_AssignToInstance) XSRETURN_EMPTY; } +XS(XS_Client_RemoveFromInstance); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_RemoveFromInstance) +{ + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Client::RemoveFromInstance(THIS, instance_id)"); + { + Client * THIS; + uint16 instance_id = (uint16)SvUV(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."); + + THIS->RemoveFromInstance(instance_id); + } + XSRETURN_EMPTY; +} + XS(XS_Client_Freeze); XS(XS_Client_Freeze) { diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 7757d0a70..4de816067 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -2545,7 +2545,7 @@ void QuestManager::DestroyInstance(uint16 instance_id) uint16 QuestManager::GetInstanceID(const char *zone, int16 version) { QuestManagerCurrentQuestVars(); - if(initiator) + if (initiator) { return database.GetInstanceID(zone, initiator->CharacterID(), version); } @@ -2555,7 +2555,7 @@ uint16 QuestManager::GetInstanceID(const char *zone, int16 version) void QuestManager::AssignToInstance(uint16 instance_id) { QuestManagerCurrentQuestVars(); - if(initiator) + if (initiator) { database.AddClientToInstance(instance_id, initiator->CharacterID()); } @@ -2564,10 +2564,10 @@ void QuestManager::AssignToInstance(uint16 instance_id) void QuestManager::AssignGroupToInstance(uint16 instance_id) { QuestManagerCurrentQuestVars(); - if(initiator) + if (initiator) { Group *g = initiator->GetGroup(); - if(g) + if (g) { uint32 gid = g->GetID(); database.AssignGroupToInstance(gid, instance_id); @@ -2578,7 +2578,7 @@ void QuestManager::AssignGroupToInstance(uint16 instance_id) void QuestManager::AssignRaidToInstance(uint16 instance_id) { QuestManagerCurrentQuestVars(); - if(initiator) + if (initiator) { Raid *r = initiator->GetRaid(); if(r) @@ -2592,36 +2592,28 @@ void QuestManager::AssignRaidToInstance(uint16 instance_id) void QuestManager::RemoveFromInstance(uint16 instance_id) { QuestManagerCurrentQuestVars(); - if(initiator) { - if(database.RemoveClientFromInstance(instance_id, initiator->CharacterID())) { + if (initiator) + { + if (database.RemoveClientFromInstance(instance_id, initiator->CharacterID())) initiator->Message(MT_Say, "Removed client from instance."); - } else { + else initiator->Message(MT_Say, "Failed to remove client from instance."); - } } } void QuestManager::RemoveAllFromInstance(uint16 instance_id) { QuestManagerCurrentQuestVars(); - if(initiator) { + if (initiator) + { std::list charid_list; - bool removed_all = true; - uint16 fail_count = 0; - database.GetCharactersInInstance(instance_id,charid_list); - auto iter = charid_list.begin(); - while(iter != charid_list.end()) { - if(!database.RemoveClientFromInstance(instance_id, *iter)) { - removed_all = false; - ++fail_count; - } - ++iter; - } - if (removed_all) { + + if (database.RemoveClientsFromInstance(instance_id)) initiator->Message(MT_Say, "Removed all players from instance."); - } else { - // once the expedition system is in, this message it not relevant - initiator->Message(MT_Say, "Failed to remove %i player(s) from instance.", fail_count); + else + { + database.GetCharactersInInstance(instance_id, charid_list); + initiator->Message(MT_Say, "Failed to remove %i player(s) from instance.", charid_list.size()); // once the expedition system is in, this message it not relevant } } }