bool MoonScriptCreatureAI::CastSpellInternal(SpellDesc* pSpell, uint32 pCurrentTime) { if( pSpell == NULL) return false; //Do not cast if we are already casting if( IsCasting() ) return false; //We do not cast in special states such as : stunned, feared, silenced, charmed, asleep, confused and if they are not ignored if ( ( ~pSpell->mTargetType.mTargetFilter & TargetFilter_IgnoreSpecialStates ) && _unit->m_special_state & ( UNIT_STATE_STUN | UNIT_STATE_FEAR | UNIT_STATE_SLEEP | UNIT_STATE_SILENCE | UNIT_STATE_CHARM | UNIT_STATE_CONFUSE ) ) return false; //Do not cast if we are in cooldown uint32 CurrentTime = ( pCurrentTime == 0 ) ? (uint32)time(NULL) : pCurrentTime; if( pSpell->mLastCastTime + pSpell->mCooldown > CurrentTime ) return false; //Check range before casting Unit *Target = GetTargetForSpell( pSpell ); if( Target ) { RangeStatusPair Status; if( pSpell->mTargetType.mTargetFilter & TargetFilter_InRangeOnly || ( Status = GetSpellRangeStatusToUnit( Target, pSpell ) ).first == RangeStatus_Ok ) { //Safe-delay if we got special state flag before DelayNextAttack( CalcSpellAttackTime( pSpell ) ); //If we were running to a target, stop because we're in range now PopRunToTargetCache(); //Do emote associated with this spell RandomEmote(pSpell->mEmotes); //Cast spell now if( pSpell->mInfo ) CastSpellOnTarget(Target, pSpell->mTargetType, pSpell->mInfo, ( pSpell->mCastTime == 0 ) ? true : false); else if( pSpell->mSpellFunc ) pSpell->mSpellFunc(pSpell, this, Target, pSpell->mTargetType); else sLog.outDebug("MoonScriptCreatureAI::CastSpellInternal() : Invalid spell!\n"); //Store cast time for cooldown pSpell->mLastCastTime = CurrentTime; return true; } else if( !pSpell->mStrictRange ) //Target is out of range, run to it { PushRunToTargetCache( Target, pSpell, Status ); return false; } } //If we get here, its because the RunToTarget changed type, so its no longer valid, clear it PopRunToTargetCache(); DelayNextAttack(0); //Cancel attack delay return true; //No targets possible? Consider spell casted nonetheless }
bool ArcScriptCreatureAI::CastSpellInternal(SpellDesc* pSpell, uint32 pCurrentTime) { //Do not cast if we are already casting if( IsCasting() ) return false; //Do not cast if we are in cooldown uint32 CurrentTime = ( pCurrentTime == 0 ) ? (uint32)time(NULL) : pCurrentTime; if( pSpell->mLastCastTime + pSpell->mCooldown > CurrentTime ) return false; //Check range before casting Unit* Target = GetTargetForSpell(pSpell); if( Target ) { if( IsUnitInRange(Target, pSpell) ) { //If we were running to a target, stop because we're in range now PopRunToTargetCache(); //Do emote associated with this spell RandomEmote(pSpell->mEmotes); //Cast spell now if( pSpell->mInfo ) CastSpellOnTarget(Target, pSpell->mTargetType, pSpell->mInfo, ( pSpell->mCastTime == 0 ) ? true : false); else if( pSpell->mSpellFunc ) pSpell->mSpellFunc(pSpell, this, Target, pSpell->mTargetType); else sLog.outDebug("ArcScriptCreatureAI::CastSpellInternal() : Invalid spell!\n"); //Store cast time for cooldown pSpell->mLastCastTime = CurrentTime; return true; } else if( !pSpell->mStrictRange ) //Target is out of range, run to it { PushRunToTargetCache(Target, pSpell); return false; } } //If we get here, its because the RunToTarget changed type, so its no longer valid, clear it PopRunToTargetCache(); DelayNextAttack(0); //Cancel attack delay return true; //No targets possible? Consider spell casted nonetheless }