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:
mik1893
2016-07-16 11:29:20 +01:00
parent 41ff1efdae
commit 548cd20f11
6 changed files with 198 additions and 50 deletions
@@ -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();
// }
+2 -2
View File
@@ -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 */)