// scripts does not take care about MoveInLineOfSight loops // MoveInLineOfSight can be called inside another MoveInLineOfSight and cause stack overflow void CreatureAI::MoveInLineOfSight_Safe(Unit *who) { if (m_MoveInLineOfSight_locked == true) return; m_MoveInLineOfSight_locked = true; MoveInLineOfSight(who); m_MoveInLineOfSight_locked = false; }
// scripts does not take care about MoveInLineOfSight loops // MoveInLineOfSight can be called inside another MoveInLineOfSight and cause stack overflow void CreatureAI::MoveInLineOfSight_Safe(Unit* who) { if (Player* player = who->ToPlayer()) if (player->isGameMaster()) return; if (m_MoveInLineOfSight_locked == true) return; m_MoveInLineOfSight_locked = true; MoveInLineOfSight(who); m_MoveInLineOfSight_locked = false; }
void NpcDarkNucleusAI::UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (_targetAuraCheck <= diff) { _targetAuraCheck = 1000; if (Unit* victim = me->getVictim()) if (me->GetDistance(victim) < 15.0f && !victim->HasAura(SPELL_SHADOW_RESONANCE_RESIST, me->GetGUID())) { DoCast(victim, SPELL_SHADOW_RESONANCE_RESIST); me->ClearUnitState(UNIT_STATE_CASTING); } else MoveInLineOfSight(me->getVictim()); } else _targetAuraCheck -= diff; }
void GuardAI::UpdateAI(const uint32 diff) { // update i_victimGuid if i_creature.getVictim() !=0 and changed if(i_creature.getVictim()) i_victimGuid = i_creature.getVictim()->GetGUID(); // i_creature.getVictim() can't be used for check in case stop fighting, i_creature.getVictim() clearóâ at Unit death etc. if( i_victimGuid ) { if( _needToStop() ) { DEBUG_LOG("Guard AI stoped attacking [guid=%u]", i_creature.GetGUIDLow()); _stopAttack(); // i_victimGuid == 0 && i_creature.getVictim() == NULL now } assert((i_victimGuid != 0) == (i_creature.getVictim() != NULL) && "i_victimGuid and i_creature.getVictim() not synchronized."); switch( i_state ) { case STATE_LOOK_AT_VICTIM: { if( i_creature.getVictim() && IsVisible(i_creature.getVictim()) ) { DEBUG_LOG("Victim %u re-enters creature's aggro radius fater stop attacking", i_creature.getVictim()->GetGUIDLow()); i_state = STATE_NORMAL; i_creature->MovementExpired(); break; // move on // back to the cat and mice game if you move back in range } i_tracker.Update(diff); if( i_tracker.Passed() ) { DEBUG_LOG("Creature running back home [guid=%u]", i_creature.GetGUIDLow()); static_cast<TargetedMovementGenerator *>(i_creature->top())->TargetedHome(i_creature); i_state = STATE_NORMAL; } /*else if( !i_creature.canReachWithAttack( i_pVictim )) { float dx = i_pVictim->GetPositionX() - i_creature.GetPositionX(); float dy = i_pVictim->GetPositionY() - i_creature.GetPositionY(); float orientation = (float)atan2((double)dy, (double)dx); i_creature.Relocate(i_pVictim->GetPositionX(), i_pVictim->GetPositionY(), i_pVictim->GetPositionZ(), orientation); }*/ break; } case STATE_NORMAL: { if( i_creature.IsStopped() ) { if( i_creature.isAttackReady() ) { Unit* newtarget = i_creature.SelectHostilTarget(); if(newtarget) AttackStart(newtarget); if(!i_creature.getVictim() || !i_creature.canReachWithAttack(i_creature.getVictim())) return; i_creature.AttackerStateUpdate(i_creature.getVictim()); i_creature.resetAttackTimer(); if ( !i_creature.getVictim() ) return; if( _needToStop() ) _stopAttack(); } } break; } default: break; } } else { std::list<Unit*> unitlist; MapManager::Instance().GetMap(i_creature.GetMapId())->GetUnitList(i_creature.GetPositionX(), i_creature.GetPositionY(),unitlist); for(std::list<Unit*>::iterator iter=unitlist.begin();iter!=unitlist.end();iter++) { if((*iter) && (*iter)->isAlive() && !(*iter)->isInFlight() && IsVisible( *iter ) ) { MoveInLineOfSight(*iter); } } } }
void IsSummonedBy(Unit* owner) { MoveInLineOfSight(owner); }