mirror of
https://github.com/araxiaonline/TrinityCore2.git
synced 2026-06-25 15:59:24 -04:00
*Set pvp flags for units controlled by player.
*Reset pvp flags when unit is uncharmed. *Remove walk flag when unit is charmed. --HG-- branch : trunk
This commit is contained in:
+43
-49
@@ -6176,19 +6176,8 @@ void Player::UpdateArea(uint32 newArea)
|
||||
m_areaUpdateId = newArea;
|
||||
|
||||
AreaTableEntry const* area = GetAreaEntryByAreaID(newArea);
|
||||
|
||||
if(area && (area->flags & AREA_FLAG_ARENA))
|
||||
{
|
||||
if(!isGameMaster())
|
||||
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove ffa flag only if not ffapvp realm
|
||||
// removal in sanctuaries and capitals is handled in zone update
|
||||
if(HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP) && !sWorld.IsFFAPvPRealm())
|
||||
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||
}
|
||||
pvpInfo.inFFAPvPArea = area && (area->flags & AREA_FLAG_ARENA);
|
||||
UpdatePvPState(true);
|
||||
|
||||
UpdateAreaDependentAuras(newArea);
|
||||
}
|
||||
@@ -6241,29 +6230,18 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
|
||||
break;
|
||||
case AREATEAM_NONE:
|
||||
// overwrite for battlegrounds, maybe batter some zone flags but current known not 100% fit to this
|
||||
pvpInfo.inHostileArea = sWorld.IsPvPRealm() || InBattleGround();
|
||||
pvpInfo.inHostileArea = sWorld.IsPvPRealm() || InBattleGround() || (zone->flags & AREA_FLAG_OUTDOOR_PVP);
|
||||
break;
|
||||
default: // 6 in fact
|
||||
pvpInfo.inHostileArea = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(pvpInfo.inHostileArea) // in hostile area
|
||||
{
|
||||
if(!IsPvP() || pvpInfo.endTimer != 0)
|
||||
UpdatePvP(true, true);
|
||||
}
|
||||
else // in friendly area
|
||||
{
|
||||
if(IsPvP() && !HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_IN_PVP) && pvpInfo.endTimer == 0)
|
||||
pvpInfo.endTimer = time(0); // start toggle-off
|
||||
}
|
||||
|
||||
pvpInfo.inNoPvPArea = false;
|
||||
if((zone->flags & AREA_FLAG_SANCTUARY) || zone->mapid == 609) // in sanctuary
|
||||
{
|
||||
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
|
||||
if(sWorld.IsFFAPvPRealm())
|
||||
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||
pvpInfo.inNoPvPArea = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -6275,9 +6253,7 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
|
||||
SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
|
||||
SetRestType(REST_TYPE_IN_CITY);
|
||||
InnEnter(time(0),GetMapId(),0,0,0);
|
||||
|
||||
if(sWorld.IsFFAPvPRealm())
|
||||
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||
pvpInfo.inNoPvPArea = true;
|
||||
}
|
||||
else // anywhere else
|
||||
{
|
||||
@@ -6289,23 +6265,18 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
|
||||
{
|
||||
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
|
||||
SetRestType(REST_TYPE_NO);
|
||||
|
||||
if(sWorld.IsFFAPvPRealm())
|
||||
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||
}
|
||||
}
|
||||
else // not in tavern (leave city then)
|
||||
{
|
||||
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
|
||||
SetRestType(REST_TYPE_NO);
|
||||
|
||||
// Set player to FFA PVP when not in rested environment.
|
||||
if(sWorld.IsFFAPvPRealm())
|
||||
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdatePvPState();
|
||||
|
||||
// remove items with area/map limitations (delete only for alive player to allow back in ghost mode)
|
||||
// if player resurrected at teleport this will be applied in resurrect code
|
||||
if(isAlive())
|
||||
@@ -17819,16 +17790,46 @@ void Player::UpdateHomebindTime(uint32 time)
|
||||
}
|
||||
}
|
||||
|
||||
void Player::UpdatePvPState(bool onlyFFA)
|
||||
{
|
||||
// TODO: should we always synchronize UNIT_FIELD_BYTES_2, 1 of controller and controlled?
|
||||
if(!pvpInfo.inNoPvPArea && !isGameMaster()
|
||||
&& (pvpInfo.inFFAPvPArea || sWorld.IsFFAPvPRealm()))
|
||||
{
|
||||
if(!HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
|
||||
{
|
||||
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||
for(ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
|
||||
(*itr)->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||
}
|
||||
}
|
||||
else if(HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
|
||||
{
|
||||
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||
for(ControlList::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.inHostileArea) // in hostile area
|
||||
{
|
||||
if(!IsPvP() || pvpInfo.endTimer != 0)
|
||||
UpdatePvP(true, true);
|
||||
}
|
||||
else // in friendly area
|
||||
{
|
||||
if(IsPvP() && !HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_IN_PVP) && pvpInfo.endTimer == 0)
|
||||
pvpInfo.endTimer = time(0); // start toggle-off
|
||||
}
|
||||
}
|
||||
|
||||
void Player::UpdatePvP(bool state, bool ovrride)
|
||||
{
|
||||
if(!state || ovrride)
|
||||
{
|
||||
SetPvP(state);
|
||||
if(Pet* pet = GetPet())
|
||||
pet->SetPvP(state);
|
||||
if(Unit* charmed = GetCharm())
|
||||
charmed->SetPvP(state);
|
||||
|
||||
pvpInfo.endTimer = 0;
|
||||
}
|
||||
else
|
||||
@@ -17836,14 +17837,7 @@ void Player::UpdatePvP(bool state, bool ovrride)
|
||||
if(pvpInfo.endTimer != 0)
|
||||
pvpInfo.endTimer = time(NULL);
|
||||
else
|
||||
{
|
||||
SetPvP(state);
|
||||
|
||||
if(Pet* pet = GetPet())
|
||||
pet->SetPvP(state);
|
||||
if(Unit* charmed = GetCharm())
|
||||
charmed->SetPvP(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-1
@@ -213,9 +213,11 @@ struct PlayerInfo
|
||||
|
||||
struct PvPInfo
|
||||
{
|
||||
PvPInfo() : inHostileArea(false), endTimer(0) {}
|
||||
PvPInfo() : inHostileArea(false), inNoPvPArea(false), inFFAPvPArea(false), endTimer(0) {}
|
||||
|
||||
bool inHostileArea;
|
||||
bool inNoPvPArea;
|
||||
bool inFFAPvPArea;
|
||||
time_t endTimer;
|
||||
};
|
||||
|
||||
@@ -1423,6 +1425,13 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
void SendInitialActionButtons() const;
|
||||
|
||||
PvPInfo pvpInfo;
|
||||
void UpdatePvPState(bool onlyFFA = false);
|
||||
void SetPvP(bool state)
|
||||
{
|
||||
Unit::SetPvP(state);
|
||||
for(ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
|
||||
(*itr)->SetPvP(state);
|
||||
}
|
||||
void UpdatePvP(bool state, bool ovrride=false);
|
||||
void UpdateZone(uint32 newZone,uint32 newArea);
|
||||
void UpdateArea(uint32 newArea);
|
||||
|
||||
+29
-6
@@ -8341,10 +8341,10 @@ void Unit::SetMinion(Minion *minion, bool apply)
|
||||
//else if(minion->m_Properties && minion->m_Properties->Type == SUMMON_TYPE_MINIPET)
|
||||
// AddUInt64Value(UNIT_FIELD_CRITTER, minion->GetGUID());
|
||||
|
||||
// FIXME: hack, speed must be set only at follow
|
||||
if(HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
|
||||
minion->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||
// PvP, FFAPvP
|
||||
minion->SetByteValue(UNIT_FIELD_BYTES_2, 1, GetByteValue(UNIT_FIELD_BYTES_2, 1));
|
||||
|
||||
// FIXME: hack, speed must be set only at follow
|
||||
if(GetTypeId() == TYPEID_PLAYER && minion->HasSummonMask(SUMMON_MASK_PET))
|
||||
for(int i = 0; i < MAX_MOVE_TYPE; ++i)
|
||||
minion->SetSpeed(UnitMoveType(i), m_speed_rate[i], true);
|
||||
@@ -8411,13 +8411,24 @@ void Unit::SetCharm(Unit* charm, bool apply)
|
||||
sLog.outCrash("Player %s is trying to charm unit %u, but it already has a charmed unit %u", GetName(), charm->GetEntry(), GetCharmGUID());
|
||||
|
||||
charm->m_ControlledByPlayer = true;
|
||||
// TODO: maybe we can use this flag to check if controlled by player
|
||||
charm->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
|
||||
}
|
||||
else
|
||||
charm->m_ControlledByPlayer = false;
|
||||
|
||||
// PvP, FFAPvP
|
||||
charm->SetByteValue(UNIT_FIELD_BYTES_2, 1, GetByteValue(UNIT_FIELD_BYTES_2, 1));
|
||||
|
||||
if(!charm->AddUInt64Value(UNIT_FIELD_CHARMEDBY, GetGUID()))
|
||||
sLog.outCrash("Unit %u is being charmed, but it already has a charmer %u", charm->GetEntry(), charm->GetCharmerGUID());
|
||||
|
||||
if(charm->HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE))
|
||||
{
|
||||
charm->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
|
||||
charm->SendMovementFlagUpdate();
|
||||
}
|
||||
|
||||
m_Controlled.insert(charm);
|
||||
}
|
||||
else
|
||||
@@ -8428,10 +8439,24 @@ void Unit::SetCharm(Unit* charm, bool apply)
|
||||
sLog.outCrash("Player %s is trying to uncharm unit %u, but it has another charmed unit %u", GetName(), charm->GetEntry(), GetCharmGUID());
|
||||
}
|
||||
|
||||
if(charm->GetTypeId() == TYPEID_PLAYER || IS_PLAYER_GUID(charm->GetOwnerGUID()))
|
||||
if(charm->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
charm->m_ControlledByPlayer = true;
|
||||
charm->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
|
||||
((Player*)charm)->UpdatePvPState();
|
||||
}
|
||||
else if(Player *player = charm->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
{
|
||||
charm->m_ControlledByPlayer = true;
|
||||
charm->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
|
||||
charm->SetByteValue(UNIT_FIELD_BYTES_2, 1, player->GetByteValue(UNIT_FIELD_BYTES_2, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
charm->m_ControlledByPlayer = false;
|
||||
charm->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
|
||||
charm->SetByteValue(UNIT_FIELD_BYTES_2, 1, 0);
|
||||
}
|
||||
|
||||
if(!charm->RemoveUInt64Value(UNIT_FIELD_CHARMEDBY, GetGUID()))
|
||||
sLog.outCrash("Unit %u is being uncharmed, but it has another charmer %u", charm->GetEntry(), charm->GetCharmerGUID());
|
||||
@@ -13389,7 +13414,6 @@ void Unit::SetCharmedOrPossessedBy(Unit* charmer, bool possess)
|
||||
if(GetTypeId() == TYPEID_PLAYER && ((Player*)this)->GetTransport())
|
||||
return;
|
||||
|
||||
RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
|
||||
CastStop();
|
||||
CombatStop(); //TODO: CombatStop(true) may cause crash (interrupt spells)
|
||||
DeleteThreatList();
|
||||
@@ -13414,7 +13438,6 @@ void Unit::SetCharmedOrPossessedBy(Unit* charmer, bool possess)
|
||||
|
||||
// Set charmed
|
||||
setFaction(charmer->getFaction());
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
|
||||
charmer->SetCharm(this, true);
|
||||
|
||||
if(GetTypeId() == TYPEID_UNIT)
|
||||
|
||||
Reference in New Issue
Block a user