rendered paste bodyIndex: game/GameObject.cpp
===================================================================
--- game/GameObject.cpp (revision 5648)
+++ game/GameObject.cpp (working copy)
@@ -195,6 +195,13 @@
return;
}
+ if (GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP)
+ {
+ Unit* owner = GetOwner();
+ if (!owner || owner->isInCombat())
+ m_cooldownTime = time(NULL) + GetGOInfo()->trap._data6[1];
+ }
+
m_lootState = GO_READY; // for other GOis same switched without delay to GO_READY
// NO BREAK
case GO_READY:
Index: game/Spell.cpp
===================================================================
--- game/Spell.cpp (revision 5648)
+++ game/Spell.cpp (working copy)
@@ -323,7 +323,7 @@
m_triggeredByAuraSpell = NULL;
m_autoRepeat = false;
- if( m_spellInfo->AttributesEx2 == 0x000020 ) //Auto Shot & Shoot
+ if( m_spellInfo->AttributesEx2 == 0x000020 && !triggered) //Auto Shot & Shoot
m_autoRepeat = true;
m_casttime = 0; // setup to correct value in Spell::prepare, don't must be used before.
@@ -333,7 +333,7 @@
m_meleeSpell = false;
- m_rangedShoot = ((m_spellInfo->Attributes & 18) == 18);
+ m_rangedShoot = (m_spellInfo->Attributes & 2);
if( m_spellInfo->StartRecoveryTime == 0 && !m_autoRepeat && !m_rangedShoot )
{
for (int i = 0; i < 3; i++)
@@ -1734,6 +1734,14 @@
// calculate cast time (calculated after first CanCast check to prevent charge counting for first CanCast fail)
m_casttime = GetSpellCastTime(sCastTimesStore.LookupEntry(m_spellInfo->CastingTimeIndex));
+ if (m_rangedShoot && !m_IsTriggeredSpell)
+ {
+ m_casttime = int32(m_casttime*m_caster->m_modAttackSpeedPct[RANGED_ATTACK]);
+
+ if (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT)
+ m_casttime += 500;
+ }
+
if(Player* modOwner = m_caster->GetSpellModOwner())
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_CASTING_TIME, m_casttime,this);
@@ -1750,10 +1758,6 @@
m_caster->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
}
- // do first cast of autorepeat spell with recovery time delay (like after any autocast)
- if(IsAutoRepeat())
- m_spellState = SPELL_STATE_FINISHED;
-
if(m_IsTriggeredSpell)
cast(true);
else
@@ -1887,6 +1891,20 @@
UpdatePointers(); // pointers can be invalidate at triggered spell casting
}
+ if (IsMeleeAttackResetSpell())
+ {
+ if ( m_rangedShoot )
+ {
+ m_caster->resetAttackTimer(RANGED_ATTACK);
+ }
+ else
+ {
+ m_caster->resetAttackTimer(BASE_ATTACK);
+ if(m_caster->haveOffhandWeapon())
+ m_caster->resetAttackTimer(OFF_ATTACK);
+ }
+ }
+
// Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
if (m_spellInfo->speed > 0.0f)
{
@@ -2183,7 +2201,9 @@
cancel();
// don't cancel for melee, autorepeat and instant spells
else if(!m_meleeSpell && !m_autoRepeat && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT))
+ {
cancel();
+ }
}
switch(m_spellState)
@@ -2198,7 +2218,7 @@
m_timer -= difftime;
}
- if(m_timer == 0 && !m_meleeSpell)
+ if(m_timer == 0 && !m_meleeSpell && !m_autoRepeat)
cast();
} break;
case SPELL_STATE_CASTING:
@@ -2324,12 +2344,20 @@
}
}
- if (IsMeleeAttackResetSpell())
- {
- m_caster->resetAttackTimer(BASE_ATTACK);
- if(m_caster->haveOffhandWeapon())
- m_caster->resetAttackTimer(OFF_ATTACK);
- }
+ // Bestial Wrath: Try to find Beast Within
+ if (m_spellInfo->Id == 19574)
+ {
+ Unit::AuraList const& BWDummy = m_caster->GetAurasByType(SPELL_AURA_DUMMY);
+ for(Unit::AuraList::const_iterator i = BWDummy.begin(); i != BWDummy.end(); ++i)
+ {
+ // Beast Within
+ if ((*i)->GetSpellProto()->Id == 34692)
+ {
+ m_caster->CastSpell(m_caster,34471,true,NULL,(*i));
+ break;
+ }
+ }
+ }
// Clear combo at finish state
if(m_caster->GetTypeId() == TYPEID_PLAYER)
@@ -3724,11 +3752,11 @@
case SPELL_AURA_MOD_FEAR:
return SPELL_FAILED_FLEEING;
case SPELL_AURA_MOD_SILENCE:
- if((GetSpellSchoolMask(m_spellInfo) & SPELL_SCHOOL_MASK_NORMAL)==0)
+ if(m_spellInfo->DmgClass==SPELL_DAMAGE_CLASS_MAGIC)
return SPELL_FAILED_SILENCED;
break;
case SPELL_AURA_MOD_PACIFY:
- if(GetSpellSchoolMask(m_spellInfo) & SPELL_SCHOOL_MASK_NORMAL)
+ if(m_spellInfo->DmgClass==SPELL_DAMAGE_CLASS_MELEE||m_spellInfo->DmgClass==SPELL_DAMAGE_CLASS_RANGED)
return SPELL_FAILED_PACIFIED;
break;
}
Index: game/SpellAuras.cpp
===================================================================
--- game/SpellAuras.cpp (revision 5648)
+++ game/SpellAuras.cpp (working copy)
@@ -2995,9 +2995,33 @@
{
uint32 mechanic = 1 << m_modifier.m_miscvalue;
- //immune movement impairement and loss of control
- if(GetId()==42292)
- mechanic=0x9967da6;
+ // Manualy set
+ switch(GetId())
+ {
+ //immune movement impairement and loss of control
+ case 42292:
+ mechanic=0x9967da6;
+ break;
+ case 34471:
+ case 19574:
+ mechanic=0x41066CA6;
+ // need to also add immunities due to this spell
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_CHARM,apply);
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_FEAR,apply);
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_POLYMORPH,apply);
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_CONFUSED,apply);
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_BANISH,apply);
+ //m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,30,apply); // 2.4 SAP
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_ROOT,apply);
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_SLEEP,apply);
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_SNARE,apply);
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_KNOCKOUT,apply);
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_FREEZE,apply);
+ m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_HORROR,apply);
+ break;
+ default:
+ break;
+ }
if(apply)
{
Index: game/Unit.cpp
===================================================================
--- game/Unit.cpp (revision 5648)
+++ game/Unit.cpp (working copy)
@@ -1339,6 +1339,9 @@
if( spellProto->Effect[effect_idx]==SPELL_EFFECT_PERSISTENT_AREA_AURA &&
SpellHitResult(pVictim,spellProto,false)!=SPELL_MISS_NONE)
return;
+
+ if (pVictim->IsImmunedToSpellDamage(spellProto,false))
+ return;
uint32 absorb=0;
uint32 resist=0;
@@ -1398,6 +1401,9 @@
SpellHitResult(pVictim,spellProto,false)!=SPELL_MISS_NONE)
return;
+ if (pVictim->IsImmunedToSpellDamage(spellProto,false))
+ return;
+
uint32 absorb=0;
uint32 resist=0;
CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
@@ -1570,6 +1576,9 @@
SpellHitResult(pVictim,spellProto,false)!=SPELL_MISS_NONE)
return;
+ if (pVictim->IsImmunedToSpell(spellProto,false))
+ return;
+
// ignore non positive values (can be result apply spellmods to aura damage
uint32 pdamage = mod->m_amount > 0 ? mod->m_amount : 0;
@@ -1674,6 +1683,10 @@
}
case SPELL_AURA_POWER_BURN_MANA:
{
+
+ if (pVictim->IsImmunedToSpell(spellProto,false))
+ return;
+
int32 pdamage = mod->m_amount > 0 ? mod->m_amount : 0;
Powers powerType = Powers(mod->m_miscvalue);
@@ -3389,94 +3402,65 @@
void Unit::_UpdateAutoRepeatSpell()
{
- if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() == SPELL_STATE_FINISHED)
- {
- //Auto Shot & Shoot
- if( m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->AttributesEx2 == 0x000020 && GetTypeId() == TYPEID_PLAYER )
- {
- // Auto Shot don't require ranged weapon cooldown at first cast, wand shoot does, so the 'FINISHED' state
- if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Category == 351)
- {
- // Shoot
- resetAttackTimer( RANGED_ATTACK );
- }
- else
- {
- // Auto Shoot
- if (m_AutoRepeatFirstCast)
- {
- // first cast only with recovery time (not less)
- if (getAttackTimer( RANGED_ATTACK ) < m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->RecoveryTime)
- setAttackTimer( RANGED_ATTACK, m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->RecoveryTime);
- m_AutoRepeatFirstCast = false;
- }
- else
- {
- // second or further casts
- resetAttackTimer( RANGED_ATTACK );
- }
- }
- }
- else
- {
- setAttackTimer( RANGED_ATTACK, m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->RecoveryTime);
- }
+ if ( m_AutoRepeatFirstCast )
+ {
+ if ( getAttackTimer(RANGED_ATTACK) < m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->GetCastTime() )
+ setAttackTimer(RANGED_ATTACK,m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->GetCastTime());
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->setState(SPELL_STATE_IDLE);
- }
- else if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() == SPELL_STATE_IDLE && isAttackReady(RANGED_ATTACK) )
+ m_AutoRepeatFirstCast = false;
+ return;
+ }
+
+ if (isAttackReady(RANGED_ATTACK))
{
- // check if we can cast
- if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CanCast(true) == 0)
+ if(!IsNonMeleeSpellCasted(false,false,true))
{
- // check movement in player case
if(GetTypeId() == TYPEID_PLAYER && ((Player*)this)->isMoving())
{
// cancel wand shooting
if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Category == 351)
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
// ELSE delay auto-repeat ranged weapon until player movement stop
+ // this will setup 0.5s cast time
+ setAttackTimer(RANGED_ATTACK,m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->GetCastTime());
+ return;
}
- else
- // recheck range and req. items (ammo and gun, etc)
- if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CheckRange(true) == 0 && m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CheckItems() == 0 )
- {
- // check, if we are casting melee spell (it blocks autorepeat)
- if ( ! (m_currentSpells[CURRENT_MELEE_SPELL] &&
- (m_currentSpells[CURRENT_MELEE_SPELL]->getState() != SPELL_STATE_FINISHED) &&
- (m_currentSpells[CURRENT_MELEE_SPELL]->getState() != SPELL_STATE_DELAYED)) )
- {
- // check, if we are casting something else, if no then run autorepeat spell
- if (!IsNonMeleeSpellCasted(false, false, true))
- {
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->setState(SPELL_STATE_PREPARING);
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->ReSetTimer();
- }
- }
- }
- else
- {
+
+ // Check if able to cast
+ if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CheckRange(true) != 0 ||
+ m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CheckItems() != 0 ||
+ m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CanCast(true) != 0)
+ {
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
- }
- }
- else
- {
- InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
- }
- }
- else if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() == SPELL_STATE_PREPARING)
- {
- // check, if some other incomplete spell exists (including melee) or ranged attack is not ready
- if ( m_currentSpells[CURRENT_MELEE_SPELL] ||
- m_currentSpells[CURRENT_GENERIC_SPELL] ||
- m_currentSpells[CURRENT_CHANNELED_SPELL] ||
- !isAttackReady(RANGED_ATTACK) )
- {
- // some other spell is here or ranged attack is not ready, break us to idle state
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->finish(false);
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->setState(SPELL_STATE_IDLE);
- }
- }
+ return;
+ }
+
+ // we want to shoot
+ Spell* spell = new Spell(this, m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo, true, 0);
+ spell->prepare(&(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_targets));
+ // all went good, reset attack
+ resetAttackTimer(RANGED_ATTACK);
+ }
+ // Attack Ready, but something prevents us from castubg
+ else
+ {
+ // this will setup 0.5s cast time
+ setAttackTimer(RANGED_ATTACK,m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->GetCastTime());
+ }
+ }
+ // Ranged Attack not ready yet
+ else
+ {
+ // moving, cancel wand shoot
+ if ( GetTypeId() == TYPEID_PLAYER && ((Player*)this)->isMoving() )
+ {
+ if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Category == 351)
+ InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
+
+ if ( getAttackTimer(RANGED_ATTACK) < m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->GetCastTime() )
+ setAttackTimer(RANGED_ATTACK,m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->GetCastTime());
+ }
+ }
}
void Unit::SetCurrentCastedSpell( Spell * pSpell )
@@ -6571,6 +6555,7 @@
InterruptSpell(CURRENT_MELEE_SPELL);
+
if( GetTypeId()==TYPEID_UNIT )
{
// reset call assistance
@@ -7549,7 +7534,7 @@
if(itr->type == spellInfo->Dispel)
return true;
- if( !(spellInfo->AttributesEx & 0x10000)) // unaffected by school immunity
+ if(!(spellInfo->AttributesEx & 0x10000) && spellInfo->Id != 42292) // unaffected by school immunity
{
// not have spells with charges currently
SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];