diff --git a/common/servertalk.h b/common/servertalk.h index 5337b6b1d..687abf2d7 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -179,13 +179,15 @@ #define ServerOP_CZMessagePlayer 0x4008 #define ServerOP_ReloadWorld 0x4009 -#define ServerOP_QSPlayerLogTrades 0x4010 -#define ServerOP_QSPlayerLogHandins 0x4011 -#define ServerOP_QSPlayerLogNPCKills 0x4012 -#define ServerOP_QSPlayerLogDeletes 0x4013 -#define ServerOP_QSPlayerLogMoves 0x4014 +#define ServerOP_QSPlayerLogTrades 0x4010 +#define ServerOP_QSPlayerLogHandins 0x4011 +#define ServerOP_QSPlayerLogNPCKills 0x4012 +#define ServerOP_QSPlayerLogDeletes 0x4013 +#define ServerOP_QSPlayerLogMoves 0x4014 #define ServerOP_QSPlayerLogMerchantTransactions 0x4015 -#define ServerOP_QSSendQuery 0x4016 +#define ServerOP_QSSendQuery 0x4016 +#define ServerOP_CZSignalNPC 0x4017 +#define ServerOP_CZSetEntityVariableByNPCTypeID 0x4018 /* Query Serv Generic Packet Flag/Type Enumeration */ enum { QSG_LFGuild = 0 }; @@ -1092,6 +1094,11 @@ struct CZClientSignal_Struct { uint32 data; }; +struct CZNPCSignal_Struct { + uint32 npctype_id; + uint32 data; +}; + struct CZClientSignalByName_Struct { char Name[64]; uint32 data; @@ -1233,6 +1240,12 @@ struct CZMessagePlayer_Struct { char Message[512]; }; +struct CZSetEntVarByNPCTypeID_Struct { + uint32 npctype_id; + char id[256]; + char m_var[256]; +}; + struct ReloadWorld_Struct{ uint32 Option; }; diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index c740ff3bc..c05962816 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -1266,7 +1266,9 @@ bool ZoneServer::Process() { break; } case ServerOP_CZSignalClientByName: - case ServerOP_CZMessagePlayer: + case ServerOP_CZMessagePlayer: + case ServerOP_CZSignalNPC: + case ServerOP_CZSetEntityVariableByNPCTypeID: case ServerOP_CZSignalClient: { zoneserver_list.SendPacket(pack); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 755309ef6..59d43591e 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -9435,7 +9435,7 @@ void Client::CompleteConnect() { if (buffs[j1].spellid >(uint32)SPDAT_RECORDS) continue; - const SPDat_Spell_Struct &spell = spells[buffs[j1].spellid]; + const SPDat_Spell_Struct &spell = spells[buffs[j1].spellid]; for (int x1 = 0; x1 < EFFECT_COUNT; x1++) { switch (spell.effectid[x1]) { diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index 5adbdedbd..6e337cc03 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -3402,6 +3402,41 @@ XS(XS__qs_player_event) XSRETURN_EMPTY; } +XS(XS__crosszonesetentityvariablebynpctypeid); +XS(XS__crosszonesetentityvariablebynpctypeid) +{ + dXSARGS; + + if (items != 3) + Perl_croak(aTHX_ "Usage: crosszonesetentityvariablebynpctypeid(npctype_id, id, m_var)"); + + if (items == 3) { + uint32 npctype_id = (uint32)SvIV(ST(0)); + const char *id = (const char *)SvPV_nolen(ST(1)); + const char *m_var = (const char *)SvPV_nolen(ST(2)); + quest_manager.CrossZoneSetEntityVariableByNPCTypeID(npctype_id, id, m_var); + } + + XSRETURN_EMPTY; +} + +XS(XS__crosszonesignalnpcbynpctypeid); +XS(XS__crosszonesignalnpcbynpctypeid) +{ + dXSARGS; + + if (items != 2) + Perl_croak(aTHX_ "Usage: crosszonesignalnpcbynpctypeid(npctype_id, data)"); + + if (items == 2) { + uint32 npctype_id = (uint32)SvIV(ST(0)); + uint32 data = (uint32)SvIV(ST(1)); + quest_manager.CrossZoneSignalNPCByNPCTypeID(npctype_id, data); + } + + XSRETURN_EMPTY; +} + /* This is the callback perl will look for to setup the quest package's XSUBs @@ -3624,7 +3659,9 @@ EXTERN_C XS(boot_quest) newXS(strcpy(buf, "disablerecipe"), XS__disablerecipe, file); newXS(strcpy(buf, "clear_npctype_cache"), XS__clear_npctype_cache, file); newXS(strcpy(buf, "qs_send_query"), XS__qs_send_query, file); - newXS(strcpy(buf, "qs_player_event"), XS__qs_player_event, file); + newXS(strcpy(buf, "qs_player_event"), XS__qs_player_event, file); + newXS(strcpy(buf, "crosszonesetentityvariablebynpctypeid"), XS__crosszonesetentityvariablebynpctypeid, file); + newXS(strcpy(buf, "crosszonesignalnpcbynpctypeid"), XS__crosszonesignalnpcbynpctypeid, file); XSRETURN_YES; } diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index 72e2865c9..03da3bc35 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -5072,6 +5072,35 @@ XS(XS_Client_UpdateTaskActivity) XSRETURN_EMPTY; } +XS(XS_Client_GetTaskActivityDoneCount); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Client_GetTaskActivityDoneCount) +{ + dXSARGS; + if (items != 3) + Perl_croak(aTHX_ "Usage: Client::GetTaskActivityDoneCount(THIS, TaskID, ActivityID)"); + { + Client * THIS; + int RETVAL; + int TaskID = (int)SvIV(ST(1)); + int ActivityID = (int)SvIV(ST(2)); + dXSTARG; + + 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."); + + + RETVAL = THIS->GetTaskActivityDoneCountFromTaskID(TaskID, ActivityID); + XSprePUSH; PUSHi((IV)RETVAL); + } + XSRETURN(1); +} + XS(XS_Client_AssignTask); /* prototype to pass -Wmissing-prototypes */ XS(XS_Client_AssignTask) { @@ -6199,6 +6228,7 @@ XS(boot_Client) newXSproto(strcpy(buf, "IsTaskCompleted"), XS_Client_IsTaskCompleted, file, "$$"); newXSproto(strcpy(buf, "IsTaskActive"), XS_Client_IsTaskActive, file, "$$"); newXSproto(strcpy(buf, "IsTaskActivityActive"), XS_Client_IsTaskActivityActive, file, "$$$"); + newXSproto(strcpy(buf, "GetTaskActivityDoneCount"), XS_Client_GetTaskActivityDoneCount, file, "$$$"); newXSproto(strcpy(buf, "GetCorpseCount"), XS_Client_GetCorpseCount, file, "$"); newXSproto(strcpy(buf, "GetCorpseID"), XS_Client_GetCorpseID, file, "$$"); newXSproto(strcpy(buf, "GetCorpseItemAt"), XS_Client_GetCorpseItemAt, file, "$$$"); diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index e86e4d601..e779a5aa7 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -2951,6 +2951,15 @@ const char* QuestManager::GetZoneLongName(const char *zone) { return ln.c_str(); } +void QuestManager::CrossZoneSignalNPCByNPCTypeID(uint32 npctype_id, uint32 data){ + ServerPacket* pack = new ServerPacket(ServerOP_CZSignalNPC, sizeof(CZNPCSignal_Struct)); + CZNPCSignal_Struct* CZSN = (CZNPCSignal_Struct*)pack->pBuffer; + CZSN->npctype_id = npctype_id; + CZSN->data = data; + worldserver.SendPacket(pack); + safe_delete(pack); +} + void QuestManager::CrossZoneSignalPlayerByCharID(int charid, uint32 data){ ServerPacket* pack = new ServerPacket(ServerOP_CZSignalClient, sizeof(CZClientSignal_Struct)); CZClientSignal_Struct* CZSC = (CZClientSignal_Struct*) pack->pBuffer; @@ -2968,7 +2977,7 @@ void QuestManager::CrossZoneSignalPlayerByName(const char *CharName, uint32 data CZSC->data = data; worldserver.SendPacket(pack); safe_delete(pack); -} +} void QuestManager::CrossZoneMessagePlayerByName(uint32 Type, const char *CharName, const char *Message){ uint32 message_len = strlen(CharName) + 1; @@ -2978,6 +2987,18 @@ void QuestManager::CrossZoneMessagePlayerByName(uint32 Type, const char *CharNam CZSC->Type = Type; strn0cpy(CZSC->CharName, CharName, 64); strn0cpy(CZSC->Message, Message, 512); + worldserver.SendPacket(pack); + safe_delete(pack); +} + +void QuestManager::CrossZoneSetEntityVariableByNPCTypeID(uint32 npctype_id, const char *id, const char *m_var){ + uint32 message_len = strlen(id) + 1; + uint32 message_len2 = strlen(m_var) + 1; + ServerPacket* pack = new ServerPacket(ServerOP_CZSetEntityVariableByNPCTypeID, sizeof(CZSetEntVarByNPCTypeID_Struct) + message_len + message_len2); + CZSetEntVarByNPCTypeID_Struct* CZSNBYNID = (CZSetEntVarByNPCTypeID_Struct*)pack->pBuffer; + CZSNBYNID->npctype_id = npctype_id; + strn0cpy(CZSNBYNID->id, id, 256); + strn0cpy(CZSNBYNID->m_var, m_var, 256); worldserver.SendPacket(pack); safe_delete(pack); } diff --git a/zone/questmgr.h b/zone/questmgr.h index 89a0eca78..2d1184942 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -239,8 +239,10 @@ public: uint16 CreateDoor( const char* model, float x, float y, float z, float heading, uint8 opentype, uint16 size); int32 GetZoneID(const char *zone); const char *GetZoneLongName(const char *zone); - void CrossZoneSignalPlayerByCharID(int charid, uint32 data); + void CrossZoneSignalPlayerByCharID(int charid, uint32 data); + void CrossZoneSignalNPCByNPCTypeID(uint32 npctype_id, uint32 data); void CrossZoneSignalPlayerByName(const char *CharName, uint32 data); + void CrossZoneSetEntityVariableByNPCTypeID(uint32 npctype_id, const char *id, const char *m_var); void CrossZoneMessagePlayerByName(uint32 Type, const char *CharName, const char *Message); bool EnableRecipe(uint32 recipe_id); bool DisableRecipe(uint32 recipe_id); diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 152ed4f0d..92d34ff71 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -1777,6 +1777,24 @@ void WorldServer::Process() { break; } + case ServerOP_CZSetEntityVariableByNPCTypeID: + { + CZSetEntVarByNPCTypeID_Struct* CZM = (CZSetEntVarByNPCTypeID_Struct*)pack->pBuffer; + NPC* n = entity_list.GetNPCByNPCTypeID(CZM->npctype_id); + if (n != 0) { + n->SetEntityVariable(CZM->id, CZM->m_var); + } + break; + } + case ServerOP_CZSignalNPC: + { + CZNPCSignal_Struct* CZCN = (CZNPCSignal_Struct*)pack->pBuffer; + NPC* n = entity_list.GetNPCByNPCTypeID(CZCN->npctype_id); + if (n != 0) { + n->SignalNPC(CZCN->data); + } + break; + } case ServerOP_CZSignalClient: { CZClientSignal_Struct* CZCS = (CZClientSignal_Struct*) pack->pBuffer;