mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-02-01 01:53:47 +00:00
feat(Core/PvP): Set 30 sec timer before turn off FFA PvP flag. (#5090)
This commit is contained in:
@@ -1617,6 +1617,7 @@ void Player::Update(uint32 p_time)
|
|||||||
time_t now = time(nullptr);
|
time_t now = time(nullptr);
|
||||||
|
|
||||||
UpdatePvPFlag(now);
|
UpdatePvPFlag(now);
|
||||||
|
UpdateFFAPvPFlag(now);
|
||||||
|
|
||||||
UpdateContestedPvP(p_time);
|
UpdateContestedPvP(p_time);
|
||||||
|
|
||||||
@@ -7730,28 +7731,8 @@ void Player::UpdateArea(uint32 newArea)
|
|||||||
m_areaUpdateId = newArea;
|
m_areaUpdateId = newArea;
|
||||||
|
|
||||||
AreaTableEntry const* area = sAreaTableStore.LookupEntry(newArea);
|
AreaTableEntry const* area = sAreaTableStore.LookupEntry(newArea);
|
||||||
bool oldFFAPvPArea = pvpInfo.IsInFFAPvPArea;
|
|
||||||
pvpInfo.IsInFFAPvPArea = area && (area->flags & AREA_FLAG_ARENA);
|
pvpInfo.IsInFFAPvPArea = area && (area->flags & AREA_FLAG_ARENA);
|
||||||
UpdatePvPState(true);
|
UpdateFFAPvPState(false);
|
||||||
|
|
||||||
// xinef: check if we were in ffa arena and we left
|
|
||||||
if (oldFFAPvPArea && !pvpInfo.IsInFFAPvPArea)
|
|
||||||
{
|
|
||||||
// xinef: iterate attackers
|
|
||||||
AttackerSet toRemove;
|
|
||||||
AttackerSet const& attackers = getAttackers();
|
|
||||||
for (AttackerSet::const_iterator itr = attackers.begin(); itr != attackers.end(); ++itr)
|
|
||||||
if (!(*itr)->IsValidAttackTarget(this))
|
|
||||||
toRemove.insert(*itr);
|
|
||||||
|
|
||||||
for (AttackerSet::const_iterator itr = toRemove.begin(); itr != toRemove.end(); ++itr)
|
|
||||||
(*itr)->AttackStop();
|
|
||||||
|
|
||||||
// xinef: remove our own victim
|
|
||||||
if (Unit* victim = GetVictim())
|
|
||||||
if (!IsValidAttackTarget(victim))
|
|
||||||
AttackStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateAreaDependentAuras(newArea);
|
UpdateAreaDependentAuras(newArea);
|
||||||
|
|
||||||
@@ -21158,18 +21139,50 @@ void Player::UpdatePvPFlag(time_t currTime)
|
|||||||
{
|
{
|
||||||
if (!IsPvP())
|
if (!IsPvP())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (pvpInfo.EndTimer == 0 || pvpInfo.IsHostile)
|
if (pvpInfo.EndTimer == 0 || pvpInfo.IsHostile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (currTime < (pvpInfo.EndTimer + 300 + 5))
|
if (currTime < (pvpInfo.EndTimer + 300 + 5))
|
||||||
{
|
{
|
||||||
if (currTime > (pvpInfo.EndTimer + 4) && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER))
|
if (currTime > (pvpInfo.EndTimer + 4) && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER))
|
||||||
SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER);
|
SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdatePvP(false);
|
UpdatePvP(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::UpdateFFAPvPFlag(time_t currTime)
|
||||||
|
{
|
||||||
|
if (!IsFFAPvP() || sWorld->IsFFAPvPRealm() || !pvpInfo.FFAPvPEndTimer || currTime < pvpInfo.FFAPvPEndTimer + 30)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pvpInfo.FFAPvPEndTimer = time_t(0);
|
||||||
|
|
||||||
|
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||||
|
for (ControlSet::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
|
||||||
|
(*itr)->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||||
|
|
||||||
|
// xinef: iterate attackers
|
||||||
|
AttackerSet toRemove;
|
||||||
|
AttackerSet const& attackers = getAttackers();
|
||||||
|
for (AttackerSet::const_iterator itr = attackers.begin(); itr != attackers.end(); ++itr)
|
||||||
|
if (!(*itr)->IsValidAttackTarget(this))
|
||||||
|
toRemove.insert(*itr);
|
||||||
|
|
||||||
|
for (AttackerSet::const_iterator itr = toRemove.begin(); itr != toRemove.end(); ++itr)
|
||||||
|
(*itr)->AttackStop();
|
||||||
|
|
||||||
|
// xinef: remove our own victim
|
||||||
|
if (Unit* victim = GetVictim())
|
||||||
|
if (!IsValidAttackTarget(victim))
|
||||||
|
AttackStop();
|
||||||
|
}
|
||||||
|
|
||||||
void Player::UpdateDuelFlag(time_t currTime)
|
void Player::UpdateDuelFlag(time_t currTime)
|
||||||
{
|
{
|
||||||
if (!duel || duel->startTimer == 0 || currTime < duel->startTimer + 3)
|
if (!duel || duel->startTimer == 0 || currTime < duel->startTimer + 3)
|
||||||
@@ -22747,29 +22760,9 @@ void Player::UpdateHomebindTime(uint32 time)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::UpdatePvPState(bool onlyFFA)
|
void Player::UpdatePvPState()
|
||||||
{
|
{
|
||||||
// TODO: should we always synchronize UNIT_FIELD_BYTES_2, 1 of controller and controlled?
|
UpdateFFAPvPState();
|
||||||
// no, we shouldn't, those are checked for affecting player by client
|
|
||||||
if (!pvpInfo.IsInNoPvPArea && !IsGameMaster()
|
|
||||||
&& (pvpInfo.IsInFFAPvPArea || sWorld->IsFFAPvPRealm()))
|
|
||||||
{
|
|
||||||
if (!IsFFAPvP())
|
|
||||||
{
|
|
||||||
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
|
||||||
for (ControlSet::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
|
|
||||||
(*itr)->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (IsFFAPvP())
|
|
||||||
{
|
|
||||||
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
|
||||||
for (ControlSet::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
|
|
||||||
(*itr)->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onlyFFA)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (pvpInfo.IsHostile) // in hostile area
|
if (pvpInfo.IsHostile) // in hostile area
|
||||||
{
|
{
|
||||||
@@ -22783,6 +22776,63 @@ void Player::UpdatePvPState(bool onlyFFA)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::UpdateFFAPvPState(bool reset /*= true*/)
|
||||||
|
{
|
||||||
|
// TODO: should we always synchronize UNIT_FIELD_BYTES_2, 1 of controller and controlled?
|
||||||
|
// no, we shouldn't, those are checked for affecting player by client
|
||||||
|
if (!pvpInfo.IsInNoPvPArea && !IsGameMaster() && (pvpInfo.IsInFFAPvPArea || sWorld->IsFFAPvPRealm()))
|
||||||
|
{
|
||||||
|
if (!IsFFAPvP())
|
||||||
|
{
|
||||||
|
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||||
|
for (ControlSet::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
|
||||||
|
(*itr)->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pvpInfo.IsInFFAPvPArea)
|
||||||
|
{
|
||||||
|
pvpInfo.FFAPvPEndTimer = time_t(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (IsFFAPvP())
|
||||||
|
{
|
||||||
|
if ((pvpInfo.IsInNoPvPArea || IsGameMaster()) || reset || !pvpInfo.EndTimer)
|
||||||
|
{
|
||||||
|
pvpInfo.FFAPvPEndTimer = time_t(0);
|
||||||
|
|
||||||
|
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||||
|
for (ControlSet::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
|
||||||
|
(*itr)->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||||
|
|
||||||
|
// xinef: iterate attackers
|
||||||
|
AttackerSet toRemove;
|
||||||
|
AttackerSet const& attackers = getAttackers();
|
||||||
|
for (AttackerSet::const_iterator itr = attackers.begin(); itr != attackers.end(); ++itr)
|
||||||
|
if (!(*itr)->IsValidAttackTarget(this))
|
||||||
|
toRemove.insert(*itr);
|
||||||
|
|
||||||
|
for (AttackerSet::const_iterator itr = toRemove.begin(); itr != toRemove.end(); ++itr)
|
||||||
|
(*itr)->AttackStop();
|
||||||
|
|
||||||
|
// xinef: remove our own victim
|
||||||
|
if (Unit* victim = GetVictim())
|
||||||
|
if (!IsValidAttackTarget(victim))
|
||||||
|
AttackStop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Not in FFA PvP Area
|
||||||
|
// Not FFA PvP realm
|
||||||
|
// Not FFA PvP timer already set
|
||||||
|
// Being recently in PvP combat
|
||||||
|
if (!pvpInfo.IsInFFAPvPArea && !sWorld->IsFFAPvPRealm() && !pvpInfo.FFAPvPEndTimer)
|
||||||
|
{
|
||||||
|
pvpInfo.FFAPvPEndTimer = sWorld->GetGameTime() + sWorld->getIntConfig(CONFIG_FFA_PVP_TIMER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Player::UpdatePvP(bool state, bool _override)
|
void Player::UpdatePvP(bool state, bool _override)
|
||||||
{
|
{
|
||||||
if (!state || _override)
|
if (!state || _override)
|
||||||
@@ -22795,6 +22845,7 @@ void Player::UpdatePvP(bool state, bool _override)
|
|||||||
pvpInfo.EndTimer = time(nullptr);
|
pvpInfo.EndTimer = time(nullptr);
|
||||||
SetPvP(state);
|
SetPvP(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER);
|
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -309,7 +309,8 @@ struct PvPInfo
|
|||||||
bool IsInHostileArea{false}; ///> Marks if player is in an area which forces PvP flag
|
bool IsInHostileArea{false}; ///> Marks if player is in an area which forces PvP flag
|
||||||
bool IsInNoPvPArea{false}; ///> Marks if player is in a sanctuary or friendly capital city
|
bool IsInNoPvPArea{false}; ///> Marks if player is in a sanctuary or friendly capital city
|
||||||
bool IsInFFAPvPArea{false}; ///> Marks if player is in an FFAPvP area (such as Gurubashi Arena)
|
bool IsInFFAPvPArea{false}; ///> Marks if player is in an FFAPvP area (such as Gurubashi Arena)
|
||||||
time_t EndTimer{0}; ///> Time when player unflags himself for PvP (flag removed after 5 minutes)
|
time_t EndTimer{0}; ///> Time when player unflags himself for PvP (flag removed after 5 minutes)
|
||||||
|
time_t FFAPvPEndTimer{0}; ///> Time when player unflags himself for FFA PvP (flag removed after 30 sec)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DuelInfo
|
struct DuelInfo
|
||||||
@@ -1843,7 +1844,8 @@ public:
|
|||||||
bool IsActionButtonDataValid(uint8 button, uint32 action, uint8 type);
|
bool IsActionButtonDataValid(uint8 button, uint32 action, uint8 type);
|
||||||
|
|
||||||
PvPInfo pvpInfo;
|
PvPInfo pvpInfo;
|
||||||
void UpdatePvPState(bool onlyFFA = false);
|
void UpdatePvPState();
|
||||||
|
void UpdateFFAPvPState(bool reset = true);
|
||||||
void SetPvP(bool state)
|
void SetPvP(bool state)
|
||||||
{
|
{
|
||||||
Unit::SetPvP(state);
|
Unit::SetPvP(state);
|
||||||
@@ -1864,6 +1866,7 @@ public:
|
|||||||
|
|
||||||
void UpdateAfkReport(time_t currTime);
|
void UpdateAfkReport(time_t currTime);
|
||||||
void UpdatePvPFlag(time_t currTime);
|
void UpdatePvPFlag(time_t currTime);
|
||||||
|
void UpdateFFAPvPFlag(time_t currTime);
|
||||||
void UpdateContestedPvP(uint32 currTime);
|
void UpdateContestedPvP(uint32 currTime);
|
||||||
void SetContestedPvPTimer(uint32 newTime) {m_contestedPvPTimer = newTime;}
|
void SetContestedPvPTimer(uint32 newTime) {m_contestedPvPTimer = newTime;}
|
||||||
void ResetContestedPvP()
|
void ResetContestedPvP()
|
||||||
|
|||||||
@@ -378,6 +378,7 @@ enum WorldIntConfigs
|
|||||||
CONFIG_TOGGLE_XP_COST,
|
CONFIG_TOGGLE_XP_COST,
|
||||||
CONFIG_NPC_EVADE_IF_NOT_REACHABLE,
|
CONFIG_NPC_EVADE_IF_NOT_REACHABLE,
|
||||||
CONFIG_NPC_REGEN_TIME_IF_NOT_REACHABLE_IN_RAID,
|
CONFIG_NPC_REGEN_TIME_IF_NOT_REACHABLE_IN_RAID,
|
||||||
|
CONFIG_FFA_PVP_TIMER,
|
||||||
INT_CONFIG_VALUE_COUNT
|
INT_CONFIG_VALUE_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1240,6 +1240,8 @@ void World::LoadConfigSettings(bool reload)
|
|||||||
m_int_configs[CONFIG_ITEMDELETE_QUALITY] = sConfigMgr->GetOption<int32>("ItemDelete.Quality", 3);
|
m_int_configs[CONFIG_ITEMDELETE_QUALITY] = sConfigMgr->GetOption<int32>("ItemDelete.Quality", 3);
|
||||||
m_int_configs[CONFIG_ITEMDELETE_ITEM_LEVEL] = sConfigMgr->GetOption<int32>("ItemDelete.ItemLevel", 80);
|
m_int_configs[CONFIG_ITEMDELETE_ITEM_LEVEL] = sConfigMgr->GetOption<int32>("ItemDelete.ItemLevel", 80);
|
||||||
|
|
||||||
|
m_int_configs[CONFIG_FFA_PVP_TIMER] = sConfigMgr->GetOption<int32>("FFAPvPTimer", 30);
|
||||||
|
|
||||||
///- Read the "Data" directory from the config file
|
///- Read the "Data" directory from the config file
|
||||||
std::string dataPath = sConfigMgr->GetOption<std::string>("DataDir", "./");
|
std::string dataPath = sConfigMgr->GetOption<std::string>("DataDir", "./");
|
||||||
if (dataPath.empty() || (dataPath.at(dataPath.length() - 1) != '/' && dataPath.at(dataPath.length() - 1) != '\\'))
|
if (dataPath.empty() || (dataPath.at(dataPath.length() - 1) != '/' && dataPath.at(dataPath.length() - 1) != '\\'))
|
||||||
|
|||||||
@@ -3680,6 +3680,13 @@ ICC.Buff.Alliance = 73828
|
|||||||
|
|
||||||
Item.SetItemTradeable = 1
|
Item.SetItemTradeable = 1
|
||||||
|
|
||||||
|
#
|
||||||
|
# FFAPvPTimer
|
||||||
|
# Description: Specify time offset when player unset FFAPvP flag when leaving FFAPvP area. (e.g. Gurubashi Arena)
|
||||||
|
# Default: 30 sec
|
||||||
|
|
||||||
|
FFAPvPTimer = 30
|
||||||
|
|
||||||
#
|
#
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user