mirror of
https://gitcode.com/GitHub_Trending/az/azerothcore-wotlk.git
synced 2026-07-11 03:13:10 +00:00
Core/Custom: CrossFaction 2.0 - featuring:
- Disable crossfaction on specific map-zones-areas - Fully handled by external class and scripts
This commit is contained in:
@@ -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;
|
||||
@@ -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();
|
||||
|
||||
@@ -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<Group::MemberSlot> memberSlots = group->GetMemberSlots();
|
||||
for (std::list<Group::MemberSlot>::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<Group::MemberSlot> memberSlots = group->GetMemberSlots();
|
||||
for (std::list<Group::MemberSlot>::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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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 <vector>
|
||||
#include <algorithm>
|
||||
|
||||
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<uint32> 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<CrossFaction, ACE_Null_Mutex>::instance()
|
||||
|
||||
|
||||
#endif
|
||||
@@ -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<Group::MemberSlot> memberSlots = group->GetMemberSlots();
|
||||
// for (std::list<Group::MemberSlot>::iterator membersIterator = memberSlots.begin(); membersIterator != memberSlots.end(); membersIterator++)
|
||||
// UpdatePlayerTeam((*membersIterator).guid);
|
||||
// }
|
||||
//
|
||||
// void OnAfterDisband(Group* group) {
|
||||
// std::list<Group::MemberSlot> memberSlots = group->GetMemberSlots();
|
||||
// for (std::list<Group::MemberSlot>::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();
|
||||
// }
|
||||
@@ -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 */)
|
||||
|
||||
Reference in New Issue
Block a user