From 548cd20f11a7776424c11faa3721bd8ea32e323e Mon Sep 17 00:00:00 2001 From: mik1893 Date: Sat, 16 Jul 2016 11:29:20 +0100 Subject: [PATCH] Core/Custom: CrossFaction 2.0 - featuring: - Disable crossfaction on specific map-zones-areas - Fully handled by external class and scripts --- .../sql/db-extra/crossfaction_disable.sql | 5 + .../src/server/plugins/AzthPlgLoader.cpp | 4 +- .../plugins/CrossFaction/CrossFaction.cpp | 149 ++++++++++++++++++ .../plugins/CrossFaction/CrossFaction.h | 40 +++++ .../src/server/plugins/CrossFactionGroup.cpp | 46 ------ src/server/game/Groups/Group.cpp | 4 +- 6 files changed, 198 insertions(+), 50 deletions(-) create mode 100644 modules/azerothshard/data/sql/db-extra/crossfaction_disable.sql create mode 100644 modules/azerothshard/src/server/plugins/CrossFaction/CrossFaction.cpp create mode 100644 modules/azerothshard/src/server/plugins/CrossFaction/CrossFaction.h delete mode 100644 modules/azerothshard/src/server/plugins/CrossFactionGroup.cpp diff --git a/modules/azerothshard/data/sql/db-extra/crossfaction_disable.sql b/modules/azerothshard/data/sql/db-extra/crossfaction_disable.sql new file mode 100644 index 0000000000..7b63d41ada --- /dev/null +++ b/modules/azerothshard/data/sql/db-extra/crossfaction_disable.sql @@ -0,0 +1,5 @@ +DROP TABLE `crossfaction_disable`; +CREATE TABLE `crossfaction_disable` ( + `id` int(10) NOT NULL COMMENT 'could be Map, Zone, Area, depending on type field', + `type` int(10) NOT NULL COMMENT '1 = MAP - 2 = ZONE - 3 = AREA' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/modules/azerothshard/src/server/plugins/AzthPlgLoader.cpp b/modules/azerothshard/src/server/plugins/AzthPlgLoader.cpp index 1d6bbd4028..6520611bb3 100644 --- a/modules/azerothshard/src/server/plugins/AzthPlgLoader.cpp +++ b/modules/azerothshard/src/server/plugins/AzthPlgLoader.cpp @@ -7,7 +7,7 @@ /* This is where custom AzerothShard function scripts declarations should be added. */ // void AddSC_azth_commandscript(); -// void AddSC_CrossFactionGroups(); +void AddSC_CrossFactionGroups(); void AddSC_azth_player_plg(); // void AddSC_Custom_Rates(); // void AddSC_PWS_Transmogrification(); @@ -24,7 +24,7 @@ void AddAzthScripts() sLog->outString("Loading AzerothShard Plugins..."); /* This is where custom AzerothShard scripts should be added. */ // AddSC_azth_commandscript(); -// AddSC_CrossFactionGroups(); + AddSC_CrossFactionGroups(); AddSC_azth_player_plg(); // AddSC_Custom_Rates(); AddSC_npc_1v1arena(); diff --git a/modules/azerothshard/src/server/plugins/CrossFaction/CrossFaction.cpp b/modules/azerothshard/src/server/plugins/CrossFaction/CrossFaction.cpp new file mode 100644 index 0000000000..2bfffa1787 --- /dev/null +++ b/modules/azerothshard/src/server/plugins/CrossFaction/CrossFaction.cpp @@ -0,0 +1,149 @@ +// Copyright (c) 2016 AzerothCore +// Author: mik1893 +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. + +#include "CrossFaction.h" + + +// Crossfaction class functionalities +void CrossFaction::UpdatePlayerTeam(Group* group, uint64 guid, bool reset /* = false */) +{ + Player* player = ObjectAccessor::FindPlayer(guid); + if (player) + { + // if not reset, set the player's race to the group leader race + if (!reset) + if(isMapEnabled(player->GetMapId())) + if (isZoneEnabled(player->GetZoneId())) + if (isAreaEnabled(player->GetAreaId())) + if (group) + if (Player* groupLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID())) + player->setFactionForRace(groupLeader->getRace()); + + // ANY OTHER CASE: just reset it back + player->setFactionForRace(player->getRace()); + } +} + +void CrossFaction::LoadConfig(bool reload) +{ + if (reload) + { + mapDisable.clear(); + zoneDisable.clear(); + areaDisable.clear(); + } + + QueryResult mapResult = ExtraDatabase.PQuery("SELECT id FROM extra.crossfaction_disable where type = 1"); + QueryResult zoneResult = ExtraDatabase.PQuery("SELECT id FROM extra.crossfaction_disable where type = 2"); + QueryResult areaResult = ExtraDatabase.PQuery("SELECT id FROM extra.crossfaction_disable where type = 3"); + + // load in the vector the different types of disable + if (mapResult) + { + do + mapDisable.push_back((*mapResult)[0].GetUInt32()); + while (mapResult->NextRow()); + } + + if (zoneResult) + { + do + zoneDisable.push_back((*zoneResult)[0].GetUInt32()); + while (zoneResult->NextRow()); + } + + if (areaResult) + { + do + areaDisable.push_back((*areaResult)[0].GetUInt32()); + while (areaResult->NextRow()); + } +} + +// ALL THE SCRIPT FUNCTIONS AFTER THIS POINT: GROUPSCRIPT, PLAYERSCRIPT, WORLDSCRIPT +class CrossFactionGroup : public GroupScript +{ +public: + + CrossFactionGroup() : GroupScript("CrossFactionGroup") { } + + void OnAddMember(Group* group, uint64 guid) override + { + sCrossFaction->UpdatePlayerTeam(group, guid); + } + + // This script is called when a member is removed, but after a new leader has been already picked up - so it's valid to update in here. + void OnRemoveMember(Group* group, uint64 guid, RemoveMethod /*method*/, uint64 /*kicker*/, const char* /*reason*/) override + { + sCrossFaction->UpdatePlayerTeam(group, guid, true); + } + + // This script is called at the end of the leader change function - m_leader has already been set, we can use the group already (not the guids) + void OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid) override + { + std::list memberSlots = group->GetMemberSlots(); + for (std::list::iterator membersIterator = memberSlots.begin(); membersIterator != memberSlots.end(); membersIterator++) + sCrossFaction->UpdatePlayerTeam(group, (*membersIterator).guid); + } + + // On disband, reset all the players to their default race + void OnDisband(Group* group) override + { + std::list memberSlots = group->GetMemberSlots(); + for (std::list::iterator membersIterator = memberSlots.begin(); membersIterator != memberSlots.end(); membersIterator++) + sCrossFaction->UpdatePlayerTeam(group, (*membersIterator).guid, true); + } +}; + +class CrossFactionPlayer : public PlayerScript +{ +public: + + CrossFactionPlayer() : PlayerScript("CrossFactionPlayer") { } + + // Called when a player switches to a new zone + void OnUpdateZone(Player* player, uint32 newZone, uint32 newArea) override + { + sCrossFaction->UpdatePlayerTeam(player->GetGroup(), player->GetGUID()); + } + + // Called when a player changes to a new map (after moving to new map) + void OnMapChanged(Player* player) override + { + sCrossFaction->UpdatePlayerTeam(player->GetGroup(), player->GetGUID()); + } + + void OnLogin(Player* player) override + { + sCrossFaction->UpdatePlayerTeam(player->GetGroup(), player->GetGUID()); + } +}; + +class CrossFactionWorld : public WorldScript +{ +public: + CrossFactionWorld() : WorldScript("CrossFactionWorld") { } + + void OnConfigLoad(bool reload) override + { + sCrossFaction->LoadConfig(reload); + } + + void OnStartup() override + { + sCrossFaction->LoadConfig(false); + } +}; + +void AddSC_CrossFactionGroups() +{ + new CrossFactionGroup(); + new CrossFactionPlayer(); + new CrossFactionWorld(); +} + + diff --git a/modules/azerothshard/src/server/plugins/CrossFaction/CrossFaction.h b/modules/azerothshard/src/server/plugins/CrossFaction/CrossFaction.h new file mode 100644 index 0000000000..7315c4e490 --- /dev/null +++ b/modules/azerothshard/src/server/plugins/CrossFaction/CrossFaction.h @@ -0,0 +1,40 @@ +#ifndef CROSSFACTION_H +#define CROSSFACTION_H + +#include "ScriptMgr.h" +#include "Language.h" +#include "Player.h" +#include "ObjectAccessor.h" +#include "Group.h" +#include "Map.h" +#include "Log.h" +#include +#include + +class CrossFaction +{ + public: + + // functions needed to control the + void LoadConfig(bool reload); + void UpdatePlayerTeam(Group* group, uint64 guid, bool reset = false); + + private: + typedef std::vector CrossFactionDisableList; + + // the different disable lists + CrossFactionDisableList mapDisable; + CrossFactionDisableList zoneDisable; + CrossFactionDisableList areaDisable; + + // Check functions + bool isMapEnabled(uint32 mapid) { return std::find(mapDisable.begin(), mapDisable.end(), mapid) == mapDisable.end(); }; + bool isZoneEnabled(uint32 mapid) { return std::find(zoneDisable.begin(), zoneDisable.end(), mapid) == zoneDisable.end(); }; + bool isAreaEnabled(uint32 mapid) { return std::find(areaDisable.begin(), areaDisable.end(), mapid) == areaDisable.end(); }; + +}; + +#define sCrossFaction ACE_Singleton::instance() + + +#endif \ No newline at end of file diff --git a/modules/azerothshard/src/server/plugins/CrossFactionGroup.cpp b/modules/azerothshard/src/server/plugins/CrossFactionGroup.cpp deleted file mode 100644 index 19a80b6865..0000000000 --- a/modules/azerothshard/src/server/plugins/CrossFactionGroup.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "ScriptMgr.h" -#include "Language.h" -#include "Player.h" -#include "ObjectAccessor.h" -#include "Group.h" -#include "Log.h" - -/* [TODO] fix and re-enable */ -// class CrossFactionGroup : public GroupScript { -// public: -// -// CrossFactionGroup() : GroupScript("CrossFactionGroup") { -// } -// -// void OnAddMember(Group* group, ObjectGuid guid) { -// UpdatePlayerTeam(guid); -// } -// -// void OnAfterRemoveMember(Group* group, ObjectGuid guid, RemoveMethod /*method*/, ObjectGuid /*kicker*/, const char* /*reason*/) { -// UpdatePlayerTeam(guid); -// } -// -// void OnAfterChangeLeader(Group* group, ObjectGuid leaderGuid) { -// std::list memberSlots = group->GetMemberSlots(); -// for (std::list::iterator membersIterator = memberSlots.begin(); membersIterator != memberSlots.end(); membersIterator++) -// UpdatePlayerTeam((*membersIterator).guid); -// } -// -// void OnAfterDisband(Group* group) { -// std::list memberSlots = group->GetMemberSlots(); -// for (std::list::iterator membersIterator = memberSlots.begin(); membersIterator != memberSlots.end(); membersIterator++) -// UpdatePlayerTeam((*membersIterator).guid); -// } -// -// private: -// -// void UpdatePlayerTeam(ObjectGuid guid) { -// Player* player = ObjectAccessor::FindConnectedPlayer(guid); -// if (player) -// player->setFactionForRace(player->getRace()); -// } -// }; -// -// void AddSC_CrossFactionGroups() { -// new CrossFactionGroup(); -// } diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 3a3065849f..2fa1c60fc6 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -681,8 +681,6 @@ void Group::ChangeLeader(uint64 newLeaderGuid) if (!newLeader) return; - sScriptMgr->OnGroupChangeLeader(this, newLeaderGuid, m_leaderGuid); - if (!isBGGroup() && !isBFGroup()) { SQLTransaction trans = CharacterDatabase.BeginTransaction(); @@ -707,6 +705,8 @@ void Group::ChangeLeader(uint64 newLeaderGuid) WorldPacket data(SMSG_GROUP_SET_LEADER, m_leaderName.size()+1); data << slot->name; BroadcastPacket(&data, true); + + sScriptMgr->OnGroupChangeLeader(this, newLeaderGuid, m_leaderGuid); // This hook should be executed at the end - Not used anywhere in the original core } void Group::Disband(bool hideDestroy /* = false */)