aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/CharacterHandler.cpp2
-rw-r--r--src/game/MiscHandler.cpp2
-rw-r--r--src/game/Player.cpp23
-rw-r--r--src/game/Player.h14
-rw-r--r--src/game/Spell.cpp16
-rw-r--r--src/game/SpellMgr.h15
-rw-r--r--src/game/Unit.cpp49
-rw-r--r--src/shared/revision_nr.h2
8 files changed, 74 insertions, 49 deletions
diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp
index f7c1fe5090a..5d091d55b1c 100644
--- a/src/game/CharacterHandler.cpp
+++ b/src/game/CharacterHandler.cpp
@@ -825,7 +825,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
// Set FFA PvP for non GM in non-rest mode
if(sWorld.IsFFAPvPRealm() && !pCurrChar->isGameMaster() && !pCurrChar->HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_RESTING) )
- pCurrChar->SetFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ pCurrChar->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
if(pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP))
pCurrChar->SetContestedPvP();
diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp
index b6b224a2d6a..2107d792c7d 100644
--- a/src/game/MiscHandler.cpp
+++ b/src/game/MiscHandler.cpp
@@ -818,7 +818,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
GetPlayer()->SetRestType(REST_TYPE_IN_TAVERN);
if(sWorld.IsFFAPvPRealm())
- GetPlayer()->RemoveFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ GetPlayer()->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
return;
}
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 3a42e4ea80b..c9866fc554d 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -2071,7 +2071,7 @@ void Player::SetGameMaster(bool on)
setFaction(35);
SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM);
- RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP);
+ RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
ResetContestedPvP();
getHostilRefManager().setOnlineOfflineState(false);
@@ -2085,7 +2085,7 @@ void Player::SetGameMaster(bool on)
// restore FFA PvP Server state
if(sWorld.IsFFAPvPRealm())
- SetFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
// restore FFA PvP area state, remove not allowed for GM mounts
UpdateArea(m_areaUpdateId);
@@ -2464,9 +2464,10 @@ void Player::InitStatsForLevel(bool reapplyMods)
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE ); // must be set
// cleanup player flags (will be re-applied if need at aura load), to avoid have ghost flag without ghost aura, for example.
- RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK | PLAYER_FLAGS_DND | PLAYER_FLAGS_GM | PLAYER_FLAGS_GHOST | PLAYER_FLAGS_FFA_PVP);
+ RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK | PLAYER_FLAGS_DND | PLAYER_FLAGS_GM | PLAYER_FLAGS_GHOST);
SetByteValue(UNIT_FIELD_BYTES_1, 2, 0x00); // one form stealth modified bytes
+ RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP | UNIT_BYTE2_FLAG_SANCTUARY);
// restore if need some important flags
SetUInt32Value(PLAYER_FIELD_BYTES2, 0 ); // flags empty by default
@@ -3107,6 +3108,8 @@ void Player::removeSpell(uint32 spell_id, bool disabled)
for(SpellLearnSpellMap::const_iterator itr2 = spell_begin; itr2 != spell_end; ++itr2)
removeSpell(itr2->second.spell, disabled);
+
+ // TODO: recast if need lesser ranks spell for passive with IsPassiveSpellStackableWithRanks
}
void Player::RemoveArenaSpellCooldowns()
@@ -6341,14 +6344,14 @@ void Player::UpdateArea(uint32 newArea)
if(area && (area->flags & AREA_FLAG_ARENA))
{
if(!isGameMaster())
- SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP);
+ 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(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP) && !sWorld.IsFFAPvPRealm())
- RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP);
+ 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);
}
UpdateAreaDependentAuras(newArea);
@@ -6412,7 +6415,7 @@ void Player::UpdateZone(uint32 newZone)
{
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
if(sWorld.IsFFAPvPRealm())
- RemoveFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
}
else
{
@@ -6426,7 +6429,7 @@ void Player::UpdateZone(uint32 newZone)
InnEnter(time(0),GetMapId(),0,0,0);
if(sWorld.IsFFAPvPRealm())
- RemoveFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
}
else // anywhere else
{
@@ -6440,7 +6443,7 @@ void Player::UpdateZone(uint32 newZone)
SetRestType(REST_TYPE_NO);
if(sWorld.IsFFAPvPRealm())
- SetFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
}
}
else // not in tavern (leave city then)
@@ -6450,7 +6453,7 @@ void Player::UpdateZone(uint32 newZone)
// Set player to FFA PVP when not in rested environment.
if(sWorld.IsFFAPvPRealm())
- SetFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);
+ SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
}
}
}
diff --git a/src/game/Player.h b/src/game/Player.h
index 88883bfd666..e1be1e6db97 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -420,16 +420,18 @@ enum PlayerFlags
PLAYER_FLAGS_GM = 0x00000008,
PLAYER_FLAGS_GHOST = 0x00000010,
PLAYER_FLAGS_RESTING = 0x00000020,
- PLAYER_FLAGS_FFA_PVP = 0x00000080,
+ PLAYER_FLAGS_UNK7 = 0x00000040,
+ PLAYER_FLAGS_UNK8 = 0x00000080, // pre-3.0.3 PLAYER_FLAGS_FFA_PVP flag for FFA PVP state
PLAYER_FLAGS_CONTESTED_PVP = 0x00000100, // Player has been involved in a PvP combat and will be attacked by contested guards
PLAYER_FLAGS_IN_PVP = 0x00000200,
PLAYER_FLAGS_HIDE_HELM = 0x00000400,
PLAYER_FLAGS_HIDE_CLOAK = 0x00000800,
- PLAYER_FLAGS_UNK1 = 0x00001000, // played long time
- PLAYER_FLAGS_UNK2 = 0x00002000, // played too long time
- PLAYER_FLAGS_UNK3 = 0x00008000, // strange visual effect (2.0.1), looks like PLAYER_FLAGS_GHOST flag
- PLAYER_FLAGS_UNK4 = 0x00010000, // pre-3.0.3 PLAYER_FLAGS_SANCTUARY flag for player entered sanctuary
- PLAYER_FLAGS_UNK5 = 0x00020000, // taxi benchmark mode (on/off) (2.0.1)
+ PLAYER_FLAGS_UNK13 = 0x00001000, // played long time
+ PLAYER_FLAGS_UNK14 = 0x00002000, // played too long time
+ PLAYER_FLAGS_UNK15 = 0x00004000,
+ PLAYER_FLAGS_UNK16 = 0x00008000, // strange visual effect (2.0.1), looks like PLAYER_FLAGS_GHOST flag
+ PLAYER_FLAGS_UNK17 = 0x00010000, // pre-3.0.3 PLAYER_FLAGS_SANCTUARY flag for player entered sanctuary
+ PLAYER_FLAGS_UNK18 = 0x00020000, // taxi benchmark mode (on/off) (2.0.1)
PLAYER_FLAGS_PVP_TIMER = 0x00040000, // 3.0.2, pvp timer active (after you disable pvp manually)
};
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index e31d9f06b07..1267d2b28aa 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -353,11 +353,8 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
m_glyphIndex = 0;
m_triggeredByAuraSpell = NULL;
- //Auto Shot & Shoot
- if( m_spellInfo->AttributesEx2 == 0x000020 && !triggered )
- m_autoRepeat = true;
- else
- m_autoRepeat = false;
+ //Auto Shot & Shoot (wand)
+ m_autoRepeat = IsAutoRepeatRangedSpell(m_spellInfo);
m_runesState = 0;
m_powerCost = 0; // setup to correct value in Spell::prepare, don't must be used before.
@@ -670,7 +667,8 @@ void Spell::prepareDataForTriggerSystem()
m_procAttacker = PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL;
m_procVictim = PROC_FLAG_TAKEN_POSITIVE_SPELL;
}
- else if (m_spellInfo->Id != SPELL_ID_AUTOSHOT) // Wands
+ // Wands
+ else if (IsAutoRepeatRangedSpell(m_spellInfo) && m_spellInfo->Id != SPELL_ID_AUTOSHOT)
{
m_procAttacker = PROC_FLAG_SUCCESSFUL_RANGED_SPELL_HIT;
m_procVictim = PROC_FLAG_TAKEN_RANGED_SPELL_HIT;
@@ -1984,7 +1982,7 @@ void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura)
m_caster->m_Events.AddEvent(Event, m_caster->m_Events.CalculateTime(1));
//Prevent casting at cast another spell (ServerSide check)
- if(m_caster->IsNonMeleeSpellCasted(false, true) && m_cast_count)
+ if(m_caster->IsNonMeleeSpellCasted(false, true, true) && m_cast_count)
{
SendCastResult(SPELL_FAILED_SPELL_IN_PROGRESS);
finish(false);
@@ -2417,7 +2415,7 @@ void Spell::SendSpellCooldown()
// shoot spells used equipped item cooldown values already assigned in GetAttackTime(RANGED_ATTACK)
// prevent 0 cooldowns set by another way
- if (rec <= 0 && catrec <= 0 && (cat == 76 || m_spellInfo->Id != SPELL_ID_AUTOSHOT))
+ if (rec <= 0 && catrec <= 0 && (cat == 76 || IsAutoRepeatRangedSpell(m_spellInfo) && m_spellInfo->Id != SPELL_ID_AUTOSHOT))
rec = _player->GetAttackTime(RANGED_ATTACK);
// Now we have cooldown data (if found any), time to apply mods
@@ -2455,7 +2453,7 @@ void Spell::SendSpellCooldown()
if(*i_scset == m_spellInfo->Id) // skip main spell, already handled above
continue;
- _player->AddSpellCooldown(m_spellInfo->Id, m_CastItem ? m_CastItem->GetEntry() : 0, catrecTime);
+ _player->AddSpellCooldown(*i_scset, m_CastItem ? m_CastItem->GetEntry() : 0, catrecTime);
}
}
}
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index bca8abd1c33..04c952005e0 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -352,6 +352,15 @@ bool IsSingleFromSpellSpecificPerCaster(uint32 spellSpec1, uint32 spellSpec2);
bool IsSingleFromSpellSpecificPerTarget(uint32 spellSpec1, uint32 spellSpec2);
bool IsPassiveSpell(uint32 spellId);
+inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto)
+{
+ if(!IsPassiveSpell(spellProto->Id))
+ return false;
+
+ return !IsSpellHaveEffect(spellProto,SPELL_EFFECT_APPLY_AURA);
+}
+
+
inline bool IsDeathPersistentSpell(SpellEntry const *spellInfo)
{
switch(spellInfo->Id)
@@ -418,6 +427,12 @@ inline bool isSpellBreakStealth(SpellEntry const* spellInfo)
return !(spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_BREAK_STEALTH);
}
+inline bool IsAutoRepeatRangedSpell(SpellEntry const* spellInfo)
+{
+ return (spellInfo->Attributes & SPELL_ATTR_RANGED) && (spellInfo->AttributesEx2 == 0x000020 /*autorepeat*/);
+}
+
+
uint8 GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32 form);
inline bool IsChanneledSpell(SpellEntry const* spellInfo)
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 56284ca5f6b..5526e3a7002 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -72,20 +72,6 @@ static bool isNonTriggerAura[TOTAL_AURAS];
// Prepare lists
static bool procPrepared = InitTriggerAuraData();
-bool IsPassiveStackableSpell( uint32 spellId )
-{
- if(!IsPassiveSpell(spellId))
- return false;
-
- SpellEntry const* spellProto = sSpellStore.LookupEntry(spellId);
- if(!spellProto)
- return false;
- if (spellProto->procFlags)
- return false;
-
- return true;
-}
-
Unit::Unit()
: WorldObject(), i_motionMaster(this), m_ThreatManager(this), m_HostilRefManager(this)
, m_IsInNotifyList(false), m_Notified(false)
@@ -2293,6 +2279,12 @@ bool Unit::isSpellBlocked(Unit *pVictim, SpellEntry const *spellProto, WeaponAtt
return false;
}
*/
+
+ // Check creatures flags_extra for disable block
+ if(pVictim->GetTypeId()==TYPEID_UNIT &&
+ ((Creature*)pVictim)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_BLOCK )
+ return false;
+
float blockChance = GetUnitBlockChance();
blockChance += (GetWeaponSkillValue(attackType) - pVictim->GetMaxSkillValueForLevel() )*0.04;
if (roll_chance_f(blockChance))
@@ -2387,7 +2379,13 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell)
// Can`t parry
canParry = false;
}
-
+ // Check creatures flags_extra for disable parry
+ if(pVictim->GetTypeId()==TYPEID_UNIT)
+ {
+ uint32 flagEx = ((Creature*)pVictim)->GetCreatureInfo()->flags_extra;
+ if( flagEx & CREATURE_FLAG_EXTRA_NO_PARRY )
+ canParry = false;
+ }
// Ignore combat result aura
AuraList const& ignore = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT);
for(AuraList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
@@ -3410,9 +3408,8 @@ bool Unit::AddAura(Aura *Aur)
}
}
- // passive auras stack with all (except passive spell proc auras)
- if ((!Aur->IsPassive() || !IsPassiveStackableSpell(Aur->GetId())) &&
- !(Aur->GetId() == 20584 || Aur->GetId() == 8326))
+ // passive auras not stacable with other ranks
+ if (!IsPassiveSpellStackableWithRanks(aurSpellInfo))
{
if (!RemoveNoStackAurasDueToAura(Aur))
{
@@ -3516,6 +3513,14 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
return false;
uint32 spellId = Aur->GetId();
+
+ // passive spell special case (only non stackable with ranks)
+ if(IsPassiveSpell(spellId))
+ {
+ if(IsPassiveSpellStackableWithRanks(spellProto))
+ return true;
+ }
+
uint32 effIndex = Aur->GetEffIndex();
SpellSpecific spellId_spec = GetSpellSpecific(spellId);
@@ -3534,9 +3539,11 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
uint32 i_spellId = i_spellProto->Id;
+ // early checks that spellId is passive non stackable spell
if(IsPassiveSpell(i_spellId))
{
- if(IsPassiveStackableSpell(i_spellId))
+ // passive non-stackable spells not stackable only for same caster
+ if(Aur->GetCasterGUID()!=i->second->GetCasterGUID())
continue;
// passive non-stackable spells not stackable only with another rank of same spell
@@ -6443,7 +6450,7 @@ bool Unit::IsHostileTo(Unit const* unit) const
return false;
// PvP FFA state
- if(pTester->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP) && pTarget->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP))
+ if(pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP) && pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
return true;
//= PvP states
@@ -6552,7 +6559,7 @@ bool Unit::IsFriendlyTo(Unit const* unit) const
return true;
// PvP FFA state
- if(pTester->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP) && pTarget->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP))
+ if(pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP) && pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
return false;
//= PvP states
diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h
index b46aded8736..49149eb004a 100644
--- a/src/shared/revision_nr.h
+++ b/src/shared/revision_nr.h
@@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
- #define REVISION_NR "6989"
+ #define REVISION_NR "6995"
#endif // __REVISION_NR_H__