From 25c3d3803f2a1993a6c451842f71bec824efd76b Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 27 Jun 2020 18:37:43 -0400 Subject: [PATCH] Add cross-zone task assign methods to Perl/Lua. --- common/servertalk.h | 32 +++++++++++++++++ world/zoneserver.cpp | 4 +++ zone/embparser_api.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++ zone/lua_general.cpp | 40 +++++++++++++++++++++ zone/questmgr.cpp | 56 +++++++++++++++++++++++++++++ zone/questmgr.h | 4 +++ zone/tasks.cpp | 11 ++---- zone/worldserver.cpp | 43 +++++++++++++++++++++++ 8 files changed, 262 insertions(+), 8 deletions(-) diff --git a/common/servertalk.h b/common/servertalk.h index e08dbf35d..3e947a281 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -207,6 +207,10 @@ #define ServerOP_CZSetEntityVariableByGroupID 0x4022 #define ServerOP_CZSetEntityVariableByRaidID 0x4023 #define ServerOP_CZSetEntityVariableByGuildID 0x4024 +#define ServerOP_CZTaskAssign 0x4025 +#define ServerOP_CZTaskAssignGroup 0x4026 +#define ServerOP_CZTaskAssignRaid 0x4027 +#define ServerOP_CZTaskAssignGuild 0x4028 /** * QueryServer @@ -1171,6 +1175,34 @@ struct Server_Speech_Struct { char message[0]; }; +struct CZTaskAssign_Struct { + uint16 npc_entity_id; + int character_id; + uint32 task_id; + bool enforce_level_requirement; +}; + +struct CZTaskAssignGroup_Struct { + uint16 npc_entity_id; + int group_id; + uint32 task_id; + bool enforce_level_requirement; +}; + +struct CZTaskAssignRaid_Struct { + uint16 npc_entity_id; + int raid_id; + uint32 task_id; + bool enforce_level_requirement; +}; + +struct CZTaskAssignGuild_Struct { + uint16 npc_entity_id; + int guild_id; + uint32 task_id; + bool enforce_level_requirement; +}; + struct CZClientSignal_Struct { int charid; uint32 data; diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index 282c5f6be..9ccd1de81 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -1251,6 +1251,10 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { case ServerOP_CZSetEntityVariableByGroupID: case ServerOP_CZSetEntityVariableByRaidID: case ServerOP_CZSetEntityVariableByGuildID: + case ServerOP_CZTaskAssign: + case ServerOP_CZTaskAssignGroup: + case ServerOP_CZTaskAssignRaid: + case ServerOP_CZTaskAssignGuild: case ServerOP_WWMarquee: case ServerOP_DepopAllPlayersCorpses: case ServerOP_DepopPlayerCorpse: diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index f95730eb0..d057085bd 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -3715,6 +3715,82 @@ XS(XS__GetTimeSeconds) { XSRETURN_UV(seconds); } +XS(XS__crosszoneassigntaskbycharid); +XS(XS__crosszoneassigntaskbycharid) { + dXSARGS; + if (items < 2 || items > 3) + Perl_croak(aTHX_ "Usage: quest::crosszoneassigntaskbycharid(int character_id, uint32 task_id, [bool enforce_level_requirement = false])"); + { + int character_id = (int) SvIV(ST(0)); + uint32 task_id = (uint32) SvIV(ST(1)); + bool enforce_level_requirement = false; + + if (items == 3) { + enforce_level_requirement = (bool) SvTRUE(ST(2)); + } + + quest_manager.CrossZoneAssignTaskByCharID(character_id, task_id, enforce_level_requirement); + } + + XSRETURN_EMPTY; +} + +XS(XS__crosszoneassigntaskbygroupid); +XS(XS__crosszoneassigntaskbygroupid) { + dXSARGS; + if (items < 2 || items > 3) + Perl_croak(aTHX_ "Usage: quest::crosszoneassigntaskbygroupid(int group_id, uint32 task_id, [bool enforce_level_requirement = false])"); + { + int group_id = (int) SvIV(ST(0)); + uint32 task_id = (uint32) SvIV(ST(1)); + bool enforce_level_requirement = false; + + if (items == 3) { + enforce_level_requirement = (bool) SvTRUE(ST(2)); + } + + quest_manager.CrossZoneAssignTaskByGroupID(group_id, task_id, enforce_level_requirement); + } + XSRETURN_EMPTY; +} + +XS(XS__crosszoneassigntaskbyraidid); +XS(XS__crosszoneassigntaskbyraidid) { + dXSARGS; + if (items < 2 || items > 3) + Perl_croak(aTHX_ "Usage: quest::crosszoneassigntaskbyraidid(int raid_id, uint32 task_id, [bool enforce_level_requirement = false])");\ + { + int raid_id = (int) SvIV(ST(0)); + uint32 task_id = (uint32) SvIV(ST(1)); + bool enforce_level_requirement = false; + + if (items == 3) { + enforce_level_requirement = (bool) SvTRUE(ST(2)); + } + + quest_manager.CrossZoneAssignTaskByRaidID(raid_id, task_id, enforce_level_requirement); + } + XSRETURN_EMPTY; +} + +XS(XS__crosszoneassigntaskbyguildid); +XS(XS__crosszoneassigntaskbyguildid) { + dXSARGS; + if (items < 2 || items > 3) + Perl_croak(aTHX_ "Usage: quest::crosszoneassigntaskbyguildid(int guild_id, uint32 task_id, [bool enforce_level_requirement = false])"); + { + int guild_id = (int) SvIV(ST(0)); + uint32 task_id = (uint32) SvIV(ST(1)); + bool enforce_level_requirement = false; + + if (items == 3) { + enforce_level_requirement = (bool) SvTRUE(ST(2)); + } + quest_manager.CrossZoneAssignTaskByGuildID(guild_id, task_id, enforce_level_requirement); + } + XSRETURN_EMPTY; +} + XS(XS__crosszonesignalclientbycharid); XS(XS__crosszonesignalclientbycharid) { dXSARGS; @@ -4340,6 +4416,10 @@ EXTERN_C XS(boot_quest) { newXS(strcpy(buf, "creategroundobject"), XS__CreateGroundObject, file); newXS(strcpy(buf, "creategroundobjectfrommodel"), XS__CreateGroundObjectFromModel, file); newXS(strcpy(buf, "createguild"), XS__createguild, file); + newXS(strcpy(buf, "crosszoneassigntaskbycharid"), XS__crosszoneassigntaskbycharid, file); + newXS(strcpy(buf, "crosszoneassigntaskbygroupid"), XS__crosszoneassigntaskbygroupid, file); + newXS(strcpy(buf, "crosszoneassigntaskbyraidid"), XS__crosszoneassigntaskbyraidid, file); + newXS(strcpy(buf, "crosszoneassigntaskbyguildid"), XS__crosszoneassigntaskbyguildid, file); newXS(strcpy(buf, "crosszonemessageplayerbyname"), XS__crosszonemessageplayerbyname, file); newXS(strcpy(buf, "crosszonemessageplayerbygroupid"), XS__crosszonemessageplayerbygroupid, file); newXS(strcpy(buf, "crosszonemessageplayerbyraidid"), XS__crosszonemessageplayerbyraidid, file); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index b7b9ca6bb..0082cb829 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -1022,6 +1022,38 @@ void lua_send_mail(const char *to, const char *from, const char *subject, const quest_manager.SendMail(to, from, subject, message); } +void lua_cross_zone_assign_task_by_char_id(int character_id, uint32 task_id) { + quest_manager.CrossZoneAssignTaskByCharID(character_id, task_id); +} + +void lua_cross_zone_assign_task_by_char_id(int character_id, uint32 task_id, bool enforce_level_requirement) { + quest_manager.CrossZoneAssignTaskByCharID(character_id, task_id, enforce_level_requirement); +} + +void lua_cross_zone_assign_task_by_group_id(int group_id, uint32 task_id) { + quest_manager.CrossZoneAssignTaskByGroupID(group_id, task_id); +} + +void lua_cross_zone_assign_task_by_group_id(int group_id, uint32 task_id, bool enforce_level_requirement) { + quest_manager.CrossZoneAssignTaskByGroupID(group_id, task_id, enforce_level_requirement); +} + +void lua_cross_zone_assign_task_by_raid_id(int raid_id, uint32 task_id) { + quest_manager.CrossZoneAssignTaskByRaidID(raid_id, task_id); +} + +void lua_cross_zone_assign_task_by_raid_id(int raid_id, uint32 task_id, bool enforce_level_requirement) { + quest_manager.CrossZoneAssignTaskByRaidID(raid_id, task_id, enforce_level_requirement); +} + +void lua_cross_zone_assign_task_by_guild_id(int guild_id, uint32 task_id) { + quest_manager.CrossZoneAssignTaskByGuildID(guild_id, task_id); +} + +void lua_cross_zone_assign_task_by_guild_id(int guild_id, uint32 task_id, bool enforce_level_requirement) { + quest_manager.CrossZoneAssignTaskByGuildID(guild_id, task_id, enforce_level_requirement); +} + void lua_cross_zone_signal_client_by_char_id(uint32 player_id, int signal) { quest_manager.CrossZoneSignalPlayerByCharID(player_id, signal); } @@ -1874,6 +1906,14 @@ luabind::scope lua_register_general() { luabind::def("wear_change", &lua_wear_change), luabind::def("voice_tell", &lua_voice_tell), luabind::def("send_mail", &lua_send_mail), + luabind::def("cross_zone_assign_task_by_char_id", (void(*)(int,uint32))&lua_cross_zone_assign_task_by_char_id), + luabind::def("cross_zone_assign_task_by_char_id", (void(*)(int,uint32,bool))&lua_cross_zone_assign_task_by_char_id), + luabind::def("cross_zone_assign_task_by_group_id", (void(*)(int,uint32))&lua_cross_zone_assign_task_by_group_id), + luabind::def("cross_zone_assign_task_by_group_id", (void(*)(int,uint32,bool))&lua_cross_zone_assign_task_by_group_id), + luabind::def("cross_zone_assign_task_by_raid_id", (void(*)(int,uint32))&lua_cross_zone_assign_task_by_raid_id), + luabind::def("cross_zone_assign_task_by_raid_id", (void(*)(int,uint32,bool))&lua_cross_zone_assign_task_by_raid_id), + luabind::def("cross_zone_assign_task_by_guild_id", (void(*)(int,uint32))&lua_cross_zone_assign_task_by_guild_id), + luabind::def("cross_zone_assign_task_by_guild_id", (void(*)(int,uint32,bool))&lua_cross_zone_assign_task_by_guild_id), luabind::def("cross_zone_signal_client_by_char_id", &lua_cross_zone_signal_client_by_char_id), luabind::def("cross_zone_signal_client_by_group_id", &lua_cross_zone_signal_client_by_group_id), luabind::def("cross_zone_signal_client_by_raid_id", &lua_cross_zone_signal_client_by_raid_id), diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 969fab6eb..38d6b9539 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -3193,6 +3193,62 @@ const char* QuestManager::GetZoneLongName(const char *zone) { return ln.c_str(); } +void QuestManager::CrossZoneAssignTaskByCharID(int character_id, uint32 task_id, bool enforce_level_requirement) { + QuestManagerCurrentQuestVars(); + if (RuleB(TaskSystem, EnableTaskSystem) && initiator && owner) { + auto pack = new ServerPacket(ServerOP_CZTaskAssign, sizeof(CZTaskAssign_Struct)); + CZTaskAssign_Struct* CZTA = (CZTaskAssign_Struct*)pack->pBuffer; + CZTA->npc_entity_id = owner->GetID(); + CZTA->character_id = character_id; + CZTA->task_id = task_id; + CZTA->enforce_level_requirement = enforce_level_requirement; + worldserver.SendPacket(pack); + safe_delete(pack); + } +} + +void QuestManager::CrossZoneAssignTaskByGroupID(int group_id, uint32 task_id, bool enforce_level_requirement) { + QuestManagerCurrentQuestVars(); + if (RuleB(TaskSystem, EnableTaskSystem) && initiator && owner) { + auto pack = new ServerPacket(ServerOP_CZTaskAssignGroup, sizeof(CZTaskAssignGroup_Struct)); + CZTaskAssignGroup_Struct* CZTA = (CZTaskAssignGroup_Struct*)pack->pBuffer; + CZTA->npc_entity_id = owner->GetID(); + CZTA->group_id = group_id; + CZTA->task_id = task_id; + CZTA->enforce_level_requirement = enforce_level_requirement; + worldserver.SendPacket(pack); + safe_delete(pack); + } +} + +void QuestManager::CrossZoneAssignTaskByRaidID(int raid_id, uint32 task_id, bool enforce_level_requirement) { + QuestManagerCurrentQuestVars(); + if (RuleB(TaskSystem, EnableTaskSystem) && initiator && owner) { + auto pack = new ServerPacket(ServerOP_CZTaskAssignRaid, sizeof(CZTaskAssignRaid_Struct)); + CZTaskAssignRaid_Struct* CZTA = (CZTaskAssignRaid_Struct*) pack->pBuffer; + CZTA->npc_entity_id = owner->GetID(); + CZTA->raid_id = raid_id; + CZTA->task_id = task_id; + CZTA->enforce_level_requirement = enforce_level_requirement; + worldserver.SendPacket(pack); + safe_delete(pack); + } +} + +void QuestManager::CrossZoneAssignTaskByGuildID(int guild_id, uint32 task_id, bool enforce_level_requirement) { + QuestManagerCurrentQuestVars(); + if (RuleB(TaskSystem, EnableTaskSystem) && initiator && owner) { + auto pack = new ServerPacket(ServerOP_CZTaskAssignGuild, sizeof(CZTaskAssignGuild_Struct)); + CZTaskAssignGuild_Struct* CZTA = (CZTaskAssignGuild_Struct*) pack->pBuffer; + CZTA->npc_entity_id = owner->GetID(); + CZTA->guild_id = guild_id; + CZTA->task_id = task_id; + CZTA->enforce_level_requirement = enforce_level_requirement; + worldserver.SendPacket(pack); + safe_delete(pack); + } +} + void QuestManager::CrossZoneSignalNPCByNPCTypeID(uint32 npctype_id, uint32 data){ auto pack = new ServerPacket(ServerOP_CZSignalNPC, sizeof(CZNPCSignal_Struct)); CZNPCSignal_Struct* CZSN = (CZNPCSignal_Struct*)pack->pBuffer; diff --git a/zone/questmgr.h b/zone/questmgr.h index fb27ca002..917962ade 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -278,6 +278,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 CrossZoneAssignTaskByCharID(int character_id, uint32 task_id, bool enforce_level_requirement = false); + void CrossZoneAssignTaskByGroupID(int group_id, uint32 task_id, bool enforce_level_requirement = false); + void CrossZoneAssignTaskByRaidID(int raid_id, uint32 task_id, bool enforce_level_requirement = false); + void CrossZoneAssignTaskByGuildID(int guild_id, uint32 task_id, bool enforce_level_requirement = false); void CrossZoneSignalPlayerByCharID(int charid, uint32 data); void CrossZoneSignalPlayerByGroupID(int group_id, uint32 data); void CrossZoneSignalPlayerByRaidID(int raid_id, uint32 data); diff --git a/zone/tasks.cpp b/zone/tasks.cpp index a2c601aa3..141359d81 100644 --- a/zone/tasks.cpp +++ b/zone/tasks.cpp @@ -3308,18 +3308,13 @@ void ClientTaskState::AcceptNewTask(Client *c, int TaskID, int NPCID, bool enfor taskmanager->SendSingleActiveTaskToClient(c, *active_slot, false, true); c->Message(Chat::White, "You have been assigned the task '%s'.", taskmanager->Tasks[TaskID]->Title.c_str()); - + taskmanager->SaveClientState(c, this); std::string buf = std::to_string(TaskID); NPC *npc = entity_list.GetID(NPCID)->CastToNPC(); - if(!npc) { - c->Message(Chat::Yellow, "Task Giver ID is %i", NPCID); - c->Message(Chat::Red, "Unable to find NPC to send EVENT_TASKACCEPTED to. Report this bug."); - return; + if(npc) { + parse->EventNPC(EVENT_TASK_ACCEPTED, npc, c, buf.c_str(), 0); } - - taskmanager->SaveClientState(c, this); - parse->EventNPC(EVENT_TASK_ACCEPTED, npc, c, buf.c_str(), 0); } void ClientTaskState::ProcessTaskProximities(Client *c, float X, float Y, float Z) { diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index dfc9c447a..24d1bb7fb 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -2041,6 +2041,49 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } break; } + case ServerOP_CZTaskAssign: + { + CZTaskAssign_Struct* CZTA = (CZTaskAssign_Struct*)pack->pBuffer; + auto client_list = entity_list.GetClientList(); + Client* client = entity_list.GetClientByCharID(CZTA->character_id); + if (client != 0) { + client->AssignTask(CZTA->task_id, CZTA->npc_entity_id, CZTA->enforce_level_requirement); + } + break; + } + case ServerOP_CZTaskAssignGroup: + { + CZTaskAssignGroup_Struct* CZTA = (CZTaskAssignGroup_Struct*)pack->pBuffer; + auto client_list = entity_list.GetClientList(); + for (auto client : client_list) { + if (client.second->GetGroup() && client.second->GetGroup()->GetID() == CZTA->group_id) { + client.second->AssignTask(CZTA->task_id, CZTA->npc_entity_id, CZTA->enforce_level_requirement); + } + } + break; + } + case ServerOP_CZTaskAssignRaid: + { + CZTaskAssignRaid_Struct* CZTA = (CZTaskAssignRaid_Struct*)pack->pBuffer; + auto client_list = entity_list.GetClientList(); + for (auto client : client_list) { + if (client.second->GetRaid() && client.second->GetRaid()->GetID() == CZTA->raid_id) { + client.second->AssignTask(CZTA->task_id, CZTA->npc_entity_id, CZTA->enforce_level_requirement); + } + } + break; + } + case ServerOP_CZTaskAssignGuild: + { + CZTaskAssignGuild_Struct* CZTA = (CZTaskAssignGuild_Struct*)pack->pBuffer; + auto client_list = entity_list.GetClientList(); + for (auto client : client_list) { + if (client.second->GuildID() > 0 && client.second->GuildID() == CZTA->guild_id) { + client.second->AssignTask(CZTA->task_id, CZTA->npc_entity_id, CZTA->enforce_level_requirement); + } + } + break; + } case ServerOP_WWMarquee: { WWMarquee_Struct* WWMS = (WWMarquee_Struct*)pack->pBuffer;