void ConfusedMovementGenerator<T>::Initialize(T &unit) { const float wander_distance = 11; float x, y, z; x = unit.GetPositionX(); y = unit.GetPositionY(); z = unit.GetPositionZ(); Map const* map = unit.GetBaseMap(); i_nextMove = 1; bool is_water_ok, is_land_ok; _InitSpecific(unit, is_water_ok, is_land_ok); for (uint8 idx = 0; idx <= MAX_CONF_WAYPOINTS; ++idx) { float wanderX = x + wander_distance * (float) rand_norm() - wander_distance / 2; float wanderY = y + wander_distance * (float) rand_norm() - wander_distance / 2; Trinity::NormalizeMapCoord(wanderX); Trinity::NormalizeMapCoord(wanderY); float new_z = map->GetHeight(wanderX, wanderY, z, true); if (new_z > INVALID_HEIGHT && unit.IsWithinLOS(wanderX, wanderY, new_z)) { // Don't move in water if we're not already in // Don't move on land if we're not already on it either bool is_water_now = map->IsInWater(x, y, z); bool is_water_next = map->IsInWater(wanderX, wanderY, new_z); if ((is_water_now && !is_water_next && !is_land_ok) || (!is_water_now && is_water_next && !is_water_ok)) { i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx - 1][0] : x; // Back to previous location i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx - 1][1] : y; i_waypoints[idx][2] = idx > 0 ? i_waypoints[idx - 1][2] : z; continue; } // Taken from FleeingMovementGenerator if (!(new_z - z) || wander_distance / fabs(new_z - z) > 1.0f) { i_waypoints[idx][0] = wanderX; i_waypoints[idx][1] = wanderY; i_waypoints[idx][2] = new_z; continue; } } else // Back to previous location { i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx - 1][0] : x; i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx - 1][1] : y; i_waypoints[idx][2] = idx > 0 ? i_waypoints[idx - 1][2] : z; continue; } } unit.SetUInt64Value(UNIT_FIELD_TARGET, 0); unit.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); unit.CastStop(); unit.StopMoving(); unit.RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); unit.AddUnitState(UNIT_STAT_CONFUSED); }
void GetRandomPointInCircle(float max_rad, float &x, float &y) { float ang = 2*M_PI * rand_norm(); float rad = max_rad * sqrt(rand_norm()); x = rad * cos(ang); y = rad * sin(ang); }
// uniformly distribute on the circle static Position GetRandomPositionOnCircle(Position const& center, float radius) { double angle = rand_norm() * 2.0 * M_PI; double relDistance = rand_norm() + rand_norm(); if (relDistance > 1) relDistance = 1 - relDistance; return Position(center.GetPositionX() + std::sin(angle)*relDistance*radius, center.GetPositionY() + std::cos(angle)*relDistance*radius, center.GetPositionZ()); }
void SummonConservator() { float x = (rand_norm() * 30.0f) - 15.0f; float y = (rand_norm() * 30.0f) - 15.0f; Creature *add = DoSpawnCreature(CR_ANCIENT_CONSERVATOR, x, y, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 2000); Unit *target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); if(add && target) add->AddThreat(target, 1.0f); }
void ConfusedMovementGenerator<T>::Initialize(T &unit) { const float wander_distance = 11; float x,y,z; x = unit.GetPositionX(); y = unit.GetPositionY(); z = unit.GetPositionZ(); Map const* map = unit.GetBaseMap(); i_nextMove = 1; bool is_water_ok, is_land_ok; _InitSpecific(unit, is_water_ok, is_land_ok); VMAP::IVMapManager *vMaps = VMAP::VMapFactory::createOrGetVMapManager(); for (uint8 idx = 0; idx <= MAX_CONF_WAYPOINTS; ++idx) { const bool isInLoS = vMaps->isInLineOfSight(unit.GetMapId(), x, y, z + 2.0f, i_waypoints[idx][0], i_waypoints[idx][1], z + 2.0f); if (isInLoS) { const float wanderX = wander_distance*rand_norm() - wander_distance/2; const float wanderY = wander_distance*rand_norm() - wander_distance/2; i_waypoints[idx][0] = x + wanderX; i_waypoints[idx][1] = y + wanderY; } else { i_waypoints[idx][0] = x; i_waypoints[idx][1] = y; } // prevent invalid coordinates generation Quad::NormalizeMapCoord(i_waypoints[idx][0]); Quad::NormalizeMapCoord(i_waypoints[idx][1]); bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1],z); // if generated wrong path just ignore if ((is_water && !is_water_ok) || (!is_water && !is_land_ok)) { i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x; i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y; } unit.UpdateGroundPositionZ(i_waypoints[idx][0],i_waypoints[idx][1],z); i_waypoints[idx][2] = z; } unit.SetUInt64Value(UNIT_FIELD_TARGET, 0); unit.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); unit.CastStop(); unit.StopMoving(); unit.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); unit.addUnitState(UNIT_STAT_CONFUSED); }
void ConfusedMovementGenerator<T>::Initialize(T &unit) { unit.StopMoving(); float const wander_distance = 2; float x = unit.GetPositionX(); float y = unit.GetPositionY(); float z = unit.GetPositionZ(); Map const* map = unit.GetBaseMap(); i_nextMove = 1; bool is_water_ok, is_land_ok; _InitSpecific(unit, is_water_ok, is_land_ok); for (uint8 idx = 0; idx < MAX_CONF_WAYPOINTS + 1; ++idx) { float wanderX = x + (wander_distance * (float)rand_norm() - wander_distance/2); float wanderY = y + (wander_distance * (float)rand_norm() - wander_distance/2); // prevent invalid coordinates generation WoWSource::NormalizeMapCoord(wanderX); WoWSource::NormalizeMapCoord(wanderY); if (unit.IsWithinLOS(wanderX, wanderY, z)) { bool is_water = map->IsInWater(wanderX, wanderY, z); if ((is_water && !is_water_ok) || (!is_water && !is_land_ok)) { //! Cannot use coordinates outside our InhabitType. Use the current or previous position. wanderX = idx > 0 ? i_waypoints[idx-1][0] : x; wanderY = idx > 0 ? i_waypoints[idx-1][1] : y; } } else { //! Trying to access path outside line of sight. Skip this by using the current or previous position. wanderX = idx > 0 ? i_waypoints[idx-1][0] : x; wanderY = idx > 0 ? i_waypoints[idx-1][1] : y; } unit.UpdateAllowedPositionZ(wanderX, wanderY, z); //! Positions are fine - apply them to this waypoint i_waypoints[idx][0] = wanderX; i_waypoints[idx][1] = wanderY; i_waypoints[idx][2] = z; } unit.StopMoving(); unit.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); unit.AddUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); }
bool ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff) { if (unit.HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED)) return true; if (i_nextMoveTime.Passed()) { // currently moving, update location unit.AddUnitState(UNIT_STATE_CONFUSED_MOVE); if (unit.movespline->Finalized()) i_nextMoveTime.Reset(urand(800, 1500)); /* { i_nextMove = urand(1, MAX_CONF_WAYPOINTS); i_nextMoveTime.Reset(urand(0, 1500-1)); // TODO: check the minimum reset time, should be probably higher }*/ } else { // waiting for next move i_nextMoveTime.Update(diff); if (i_nextMoveTime.Passed()) { // start moving unit.AddUnitState(UNIT_STATE_CONFUSED_MOVE); // ASSERT( i_nextMove <= MAX_CONF_WAYPOINTS ); // float x = i_waypoints[i_nextMove][0]; // float y = i_waypoints[i_nextMove][1]; // float z = i_waypoints[i_nextMove][2]; float x = i_x + 10.0f * ((float)rand_norm() - 0.5f); float y = i_y + 10.0f * ((float)rand_norm() - 0.5f); float z = i_z; unit.UpdateAllowedPositionZ(x, y, z); PathFinderMovementGenerator path(&unit); path.setPathLengthLimit(30.0f); path.calculate(x, y, z); if (path.getPathType() & PATHFIND_NOPATH) { i_nextMoveTime.Reset(urand(800, 1000)); return true; } Movement::MoveSplineInit init(unit); // init.MoveTo(x, y, z); init.MovebyPath(path.getPath()); init.SetWalk(true); init.Launch(); } } return true; }
bool ConfusedMovementGenerator<T>::Update(T* unit, uint32 diff) { if (unit->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED)) return true; if (i_nextMoveTime.Passed()) { // currently moving, update location unit->AddUnitState(UNIT_STATE_CONFUSED_MOVE); if (unit->movespline->Finalized()) i_nextMoveTime.Reset(urand(800, 1500)); } else { // waiting for next move i_nextMoveTime.Update(diff); if (i_nextMoveTime.Passed()) { // start moving unit->AddUnitState(UNIT_STATE_CONFUSED_MOVE); float x = i_x + (4.0f * (float)rand_norm() - 2.0f); float y = i_y + (4.0f * (float)rand_norm() - 2.0f); Trinity::NormalizeMapCoord(x); Trinity::NormalizeMapCoord(y); float z = unit->GetBaseMap()->GetHeight(unit->GetPhaseMask(), x, y, 10.0f, true); if (z <= INVALID_HEIGHT || fabs(i_z - z) > 10.0f || !unit->IsWithinLOS(x, y, z)) { i_nextMoveTime.Reset(100); return true; } PathGenerator path(unit); path.SetPathLengthLimit(20.0f); bool result = path.CalculatePath(x, y, z); if (!result || (path.GetPathType() & PATHFIND_NOPATH)) { i_nextMoveTime.Reset(100); // short reset return true; } Movement::MoveSplineInit init(unit); init.MovebyPath(path.GetPath()); init.SetWalk(true); init.Launch(); } } return true; }
void UpdateAI(uint32 diff) { if( !UpdateVictim() ) return; events.Update(diff); if( me->HasUnitState(UNIT_STATE_CASTING) ) return; DoMeleeAttackIfReady(); switch( events.GetEvent() ) { case 0: break; case EVENT_MAGIC_PULL: { Talk(SAY_PULL); //me->MonsterTextEmote(TEXT_MAGIC_PULL, 0, true); me->CastSpell(me, SPELL_MAGIC_PULL, false); events.RepeatEvent(urand(15000,25000)); events.ScheduleEvent(EVENT_SUMMON_x4, 1500); } break; case EVENT_THUNDERING_STOMP: { Talk(SAY_STOMP); me->CastSpell(me, SPELL_THUNDERING_STOMP, false); events.RepeatEvent(urand(10000,20000)); } break; case EVENT_SUMMON: { for( uint8 i=0; i<2; ++i ) { float angle = rand_norm()*2*M_PI; me->SummonCreature(NPC_UNSTABLE_SPHERE, me->GetPositionX() + 5.0f*cos(angle), me->GetPositionY() + 5.0f*sin(angle), me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 18000); } events.RepeatEvent(2000); } break; case EVENT_SUMMON_x4: for( uint8 i=0; i<4; ++i ) { float angle = rand_norm()*2*M_PI; me->SummonCreature(NPC_UNSTABLE_SPHERE, me->GetPositionX() + 5.0f*cos(angle), me->GetPositionY() + 5.0f*sin(angle), me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 18000); } events.PopEvent(); break; } }
void RandomMovementGenerator<Creature>::Initialize(Creature &creature) { float x,y,z,z2, wander_distance; creature.GetRespawnCoord(x, y, z); creature.GetRespawnDist(wander_distance); uint32 mapid=creature.GetMapId(); Map* map = MapManager::Instance().GetMap(mapid, &creature); // Initialization is done in bulk. Don’t use vamps for that (4. parameter = false). It is too costly when entering a new map grid z2 = map->GetHeight(x,y,z, false); if( fabs( z2 - z ) < 5 ) z = z2; i_nextMove = 1; i_waypoints[0][0] = x; i_waypoints[0][1] = y; i_waypoints[0][2] = z; bool is_water_ok = creature.isCanSwimOrFly(); bool is_land_ok = creature.isCanWalkOrFly(); for(unsigned int idx=1; idx < MAX_RAND_WAYPOINTS+1; ++idx) { const float angle = 2*M_PI*rand_norm(); const float range = wander_distance*rand_norm(); i_waypoints[idx][0] = x+ range * cos(angle); i_waypoints[idx][1] = y+ range * sin(angle); // prevent invalid coordinates generation MaNGOS::NormalizeMapCoord(i_waypoints[idx][0]); MaNGOS::NormalizeMapCoord(i_waypoints[idx][1]); bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1],z); // if generated wrong path just ignore if( is_water && !is_water_ok || !is_water && !is_land_ok ) { i_waypoints[idx][0] = i_waypoints[idx-1][0]; i_waypoints[idx][1] = i_waypoints[idx-1][1]; i_waypoints[idx][2] = i_waypoints[idx-1][2]; continue; } // Initialization is done in bulk. Don’t use vamps for that (4. parameter = false). It is too costly when entering a new map grid z2 = map->GetHeight(i_waypoints[idx][0],i_waypoints[idx][1],z, false); if( fabs( z2 - z ) < 5 ) z = z2; i_waypoints[idx][2] = z; } i_nextMoveTime.Reset(urand(0, 10000-1)); // TODO: check the lower bound (it is probably too small) creature.StopMoving(); }
bool ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff) { if (unit.HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED)) return true; if (i_nextMoveTime.Passed()) { // currently moving, update location unit.AddUnitState(UNIT_STATE_CONFUSED_MOVE); if (unit.movespline->Finalized()) i_nextMoveTime.Reset(100); // short reset } else { // waiting for next move i_nextMoveTime.Update(diff); if (i_nextMoveTime.Passed()) { // start moving unit.AddUnitState(UNIT_STATE_CONFUSED_MOVE); float x = i_x + 4.0f*((float)rand_norm() - 0.5f); float y = i_y + 4.0f*((float)rand_norm() - 0.5f); float z = i_z; Trinity::NormalizeMapCoord(x); Trinity::NormalizeMapCoord(y); unit.UpdateAllowedPositionZ(x, y, z); if (z <= INVALID_HEIGHT) i_z = unit.GetBaseMap()->GetHeight(unit.GetPhaseMask(), x, y, MAX_HEIGHT) + 2.0f; PathFinderMovementGenerator path(&unit); path.setPathLengthLimit(20.0f); path.setUseStrightPath(false); if (!unit.IsWithinLOS(x, y, z) || !path.calculate(x, y, z) || (path.getPathType() & PATHFIND_NOPATH)) { i_nextMoveTime.Reset(100); return true; } Movement::MoveSplineInit init(unit); init.MovebyPath(path.getPath()); init.SetWalk(true); init.Launch(); } } return true; }
void SummonLashers() { int i; float x,y; for(i=0; i<10; ++i) { x = (rand_norm() * 30.0f) - 15.0f; y = (rand_norm() * 30.0f) - 15.0f; Creature *lasher = DoSpawnCreature(CR_DETONATING_LASHER, x, y, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 2000); Unit *target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); if(lasher && target) lasher->AddThreat(target, 1.0f); } }
void UpdateAI(uint32 diff) { if (!UpdateVictim()) return; events.Update(diff); if( me->HasUnitState(UNIT_STATE_CASTING) ) return; switch( events.GetEvent() ) { case 0: break; case EVENT_SPELL_SHADOWBOLT: me->CastSpell(me->GetVictim(), SPELL_SHADOWBOLT, false); events.RepeatEvent(urand(4000,5000)); break; case EVENT_FROST_TOMB: if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true) ) if( !target->HasAura(SPELL_FROST_TOMB_AURA) ) { Talk(SAY_FROST_TOMB_EMOTE, target); Talk(SAY_FROST_TOMB); me->CastSpell(target, SPELL_FROST_TOMB, false); events.RepeatEvent(15000); break; } events.RepeatEvent(1000); break; case EVENT_SUMMON_SKELETONS: Talk(SAY_SUMMON_SKELETONS); for (uint8 i = 0; i < 5; ++i) { float dist = rand_norm()*4+3.0f; float angle = rand_norm()*2*M_PI; if( Creature* c = me->SummonCreature(NPC_SKELETON, 156.2f+cos(angle)*dist, 259.1f+sin(angle)*dist, 42.9f, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000) ) if( Unit* target = c->SelectNearestTarget(250.0f) ) { c->AddThreat(target, 5.0f); DoZoneInCombat(c); } } events.PopEvent(); break; } DoMeleeAttackIfReady(); }
molten_flameAI(Creature *c) : NullCreatureAI(c) { float x, y, z; me->CastSpell(me,SPELL_MOLTEN_FLAME,true); me->GetNearPoint(me, x, y, z, 1.0f, 50.0f, float(M_PI*2*rand_norm())); me->GetMotionMaster()->MovePoint(0, x, y, z); }
void ReceiveEmote(Player* player, uint32 emote) { if (emote == TEXTEMOTE_KISS) { alreadykissed = true; if(urand(0,3) == 0) { DoCast(me,SPELL_TRANSFORM,true); me->MonsterSay(SAY_FREED,LANG_UNIVERSAL,player->GetGUID()); me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); }else { if (!player->HasAura(SPELL_WARTS_B_GONE)) { //FIXME me->CastSpell(player,SPELL_WARTS); }else player->RemoveAurasDueToSpell(SPELL_WARTS_B_GONE); me->CastSpell(me,SPELL_FROG_LOVE,true); me->GetMotionMaster()->MoveFollow(player,1,float(rand_norm()*2*M_PI)); } me->DespawnOrUnsummon(15000); } }
void UpdateAI(const uint32 uiDiff) { if (!UpdateVictim()) return; if (uiChargeTimer <= uiDiff) { chargeing = true; float x,y,z; me->GetNearPoint(me, x, y, z, 1.0f, 15.0f, float(2 * M_PI * rand_norm())); me->GetMotionMaster()->MovePoint(1,x,y,z); uiChargeTimer = 15*IN_MILLISECONDS; } else uiChargeTimer -= uiDiff; if (uiShieldBreakerTimer <= uiDiff) { DoCastVictim(SPELL_SHIELD_BREAKER); uiShieldBreakerTimer = 10*IN_MILLISECONDS; } else uiShieldBreakerTimer -= uiDiff; if (me->isAttackReady()) { DoCast(me->getVictim(), SPELL_PLAYER_THRUST, true); me->resetAttackTimer(); } if (Player* player = Player::GetPlayer(*me,guidAttacker)) if (!player->HasAura(SPELL_AURA_TOURNAMENT_MOUNT)) EnterEvadeMode(); }
void RandomMovementGenerator<Creature>::DoInitialize(Creature* creature) { if (!creature->IsAlive()) return; if (!_wanderDistance) _wanderDistance = creature->GetRespawnRadius(); _nextMoveTime.Reset(creature->GetDBTableGUIDLow() && creature->GetRespawnRadius() == _wanderDistance ? urand(1, 5000) : 0); _wanderDistance = std::max((creature->GetRespawnRadius() == _wanderDistance && creature->GetInstanceId() == 0) ? (creature->CanFly() ? MIN_WANDER_DISTANCE_AIR : MIN_WANDER_DISTANCE_GROUND) : 0.0f, _wanderDistance); if (G3D::fuzzyEq(_initialPosition.GetExactDist2d(0.0f, 0.0f), 0.0f)) { _initialPosition.Relocate(creature); _destinationPoints.clear(); for (uint8 i = 0; i < RANDOM_POINTS_NUMBER; ++i) { float angle = (M_PI*2.0f/(float)RANDOM_POINTS_NUMBER)*i; float factor = 0.5f + rand_norm()*0.5f; _destinationPoints.push_back(G3D::Vector3(_initialPosition.GetPositionX() + _wanderDistance*cos(angle)*factor, _initialPosition.GetPositionY() + _wanderDistance*sin(angle)*factor, _initialPosition.GetPositionZ())); } } if (!_pathGenerator) _pathGenerator = new PathGenerator(creature); creature->AddUnitState(UNIT_STATE_ROAMING | UNIT_STATE_ROAMING_MOVE); }
void Reset() { me->SetReactState(REACT_PASSIVE); if (Creature* XT002 = me->GetCreature(*me, _instance->GetData64(TYPE_XT002))) me->GetMotionMaster()->MoveFollow(XT002, 1, float(2*M_PI*rand_norm())); }
void InitializeAI() { if (me->isDead() || !me->GetOwner()) return; Reset(); switch (urand(0, 3)) { case 0: _mountModel = 6471; break; case 1: _mountModel = 6473; break; case 2: _mountModel = 6469; break; default: _mountModel = 6472; break; } me->SetDisplayId(trollmodel[urand(0, 39)]); if (Player* player = me->GetOwner()->ToPlayer()) me->GetMotionMaster()->MoveFollow(player, 5.0f, float(rand_norm() + 1.0f) * M_PI / 3.0f * 4.0f); }
void SetRandomEnchantVisual(Player* player, Item* item) { if (!player || !item) return; const ItemTemplate* temp = item->GetTemplate(); if (temp->Class != ITEM_CLASS_WEAPON) return; if (temp->SubClass == ITEM_SUBCLASS_WEAPON_BOW || temp->SubClass == ITEM_SUBCLASS_WEAPON_GUN || temp->SubClass == ITEM_SUBCLASS_WEAPON_obsolete || temp->SubClass == ITEM_SUBCLASS_WEAPON_FIST || temp->SubClass == ITEM_SUBCLASS_WEAPON_THROWN || temp->SubClass == ITEM_SUBCLASS_WEAPON_SPEAR || temp->SubClass == ITEM_SUBCLASS_WEAPON_CROSSBOW || temp->SubClass == ITEM_SUBCLASS_WEAPON_WAND || temp->SubClass == ITEM_SUBCLASS_WEAPON_FISHING_POLE) return; if (rand_norm() >= CHANCE) return; uint32 enchant = ItemEnchants[urand(0, ItemEnchants_size)]; uint32 iguid = item->GetGUIDLow(); CharacterDatabase.PExecute("REPLACE INTO custom_item_enchant_visuals (iguid, display) VALUES (%u, %u)", iguid, enchant); ItemStore[player->GetGUIDLow()][iguid] = enchant; player->SaveToDB(); player->SetVisibleItemSlot(EQUIPMENT_SLOT_MAINHAND, player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND)); player->SetVisibleItemSlot(EQUIPMENT_SLOT_OFFHAND, player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND)); }
Position GetRandomPositionAround(Creature* anubarak) { static float DISTANCE_MIN = 10.0f; static float DISTANCE_MAX = 30.0f; double angle = rand_norm() * 2.0 * M_PI; return { anubarak->GetPositionX() + (float)(frand(DISTANCE_MIN, DISTANCE_MAX)*std::sin(angle)), anubarak->GetPositionY() + (float)(frand(DISTANCE_MIN, DISTANCE_MAX)*std::cos(angle)), anubarak->GetPositionZ() }; }
void UpdateAI(uint32 diff) { if (working) { if (timer <= diff) { timer = 3000; if (fixingGUID) { if (Creature* c = ObjectAccessor::GetCreature(*me, fixingGUID)) if (me->GetExactDist2dSq(c) <= 25.0f) { if( me->GetUInt32Value(UNIT_NPC_EMOTESTATE) != EMOTE_STATE_WORK ) me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_WORK); if (fabs(me->GetOrientation()-me->GetAngle(c)) > M_PI/4) me->SetFacingToObject(c); c->AI()->SetData(2, 0); if (c->AI()->GetData(2)) fixingGUID = 0; } } if (!fixingGUID) { Creature* razorscale = NULL; if( uint64 rsGUID = pInstance->GetData64(TYPE_RAZORSCALE) ) razorscale = ObjectAccessor::GetCreature(*me, rsGUID); if( !razorscale || !razorscale->IsInCombat() ) { Reset(); me->GetMotionMaster()->MoveTargetedHome(); return; } for( int i=0; i<4; ++i ) if( uint64 fs_GUID = pInstance->GetData64(DATA_HARPOON_FIRE_STATE_1 + i) ) if( Creature* fs = ObjectAccessor::GetCreature(*me, fs_GUID) ) if (!fs->AI()->GetData(2)) { float a = rand_norm()*M_PI; me->GetMotionMaster()->MovePoint(0, fs->GetPositionX()+3.0f*cos(a), fs->GetPositionY()+3.0f*sin(a), fs->GetPositionZ()); fixingGUID = fs->GetGUID(); return; } Reset(); // all harpoons repaired me->GetMotionMaster()->MoveTargetedHome(); } } else timer -= diff; } else if (me->GetUInt32Value(UNIT_NPC_EMOTESTATE) == EMOTE_STATE_WORK) me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STAND); }
void Reset() { me->SetStandState(UNIT_STAND_STATE_SUBMERGED); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); summons.DespawnAll(); for( uint8 i=0; i<10; ++i ) { float angle = rand_norm()*2*M_PI; float dist = rand_norm()*40.0f; if( Creature* c = me->SummonCreature(NPC_SCARAB, AnubLocs[0].GetPositionX()+cos(angle)*dist, AnubLocs[0].GetPositionY()+sin(angle)*dist, AnubLocs[0].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000) ) { c->setFaction(31); c->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); c->GetMotionMaster()->MoveRandom(15.0f); } } }
void InitializeAI() { float x, y, z; me->GetNearPoint(me, x, y, z, 1, 100, M_PI*2*rand_norm()); me->GetMotionMaster()->MovePoint(0, x, y, z); me->SetVisibility(VISIBILITY_OFF); me->CastSpell(me,SPELL_MOLTEN_FLAME,true); }
void InitializeAI() override { float x, y, z; me->GetNearPoint(me, x, y, z, 1, 100, float(M_PI*2*rand_norm())); me->GetMotionMaster()->MovePoint(0, x, y, z); me->SetVisible(false); me->CastSpell(me, SPELL_MOLTEN_FLAME, true); }
bool ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff) { if (unit.HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED)) return true; if (i_nextMoveTime.Passed()) { // currently moving, update location unit.AddUnitState(UNIT_STATE_CONFUSED_MOVE); if (unit.movespline->Finalized()) i_nextMoveTime.Reset(urand(800, 1500)); } else { // waiting for next move i_nextMoveTime.Update(diff); if (i_nextMoveTime.Passed()) { // start moving unit.AddUnitState(UNIT_STATE_CONFUSED_MOVE); float x = i_x + 10.0f*((float)rand_norm() - 0.5f); float y = i_y + 10.0f*((float)rand_norm() - 0.5f); float z = i_z; unit.UpdateAllowedPositionZ(x, y, z); PathFinderMovementGenerator path(&unit); path.setPathLengthLimit(30.0f); path.calculate(x, y, z); if (path.getPathType() & PATHFIND_NOPATH) { i_nextMoveTime.Reset(urand(800, 1000)); return true; } Movement::MoveSplineInit init(unit); init.MovebyPath(path.getPath()); init.SetWalk(true); init.Launch(); } } return true; }
void InitializeAI() { CombatAI::InitializeAI(); ((Minion*)me)->SetFollowAngle(rand_norm()*2*M_PI); // Heroism / Bloodlust immunity me->ApplySpellImmune(0, IMMUNITY_ID, 32182, true); me->ApplySpellImmune(0, IMMUNITY_ID, 2825, true); }
void JustSummoned(Creature* cr) { if (cr->GetEntry() == NPC_SANCTUM_SENTRY) cr->GetMotionMaster()->MoveFollow(me, 6, rand_norm()*2*3.14f); else cr->SetInCombatWithZone(); summons.Summon(cr); }
void UpdateAI(uint32 diff) { if (!UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; switch (events.ExecuteEvent()) { case EVENT_ORMOROK_HEALTH: if (me->HealthBelowPct(26)) { me->CastSpell(me, SPELL_FRENZY, true); Talk(EMOTE_FRENZY); break; } events.ScheduleEvent(EVENT_ORMOROK_HEALTH, 1000); break; case EVENT_ORMOROK_TRAMPLE: me->CastSpell(me, SPELL_TRAMPLE, false); events.ScheduleEvent(EVENT_ORMOROK_TRAMPLE, 10000); break; case EVENT_ORMOROK_SPELL_REFLECTION: Talk(SAY_REFLECT); me->CastSpell(me, SPELL_SPELL_REFLECTION, false); events.ScheduleEvent(EVENT_ORMOROK_SPELL_REFLECTION, 30000); break; case EVENT_ORMOROK_SUMMON: if (Unit* target = SelectTarget(SELECT_TARGET_FARTHEST, 0, 50.0f, true)) me->CastSpell(target, SPELL_SUMMON_CRYSTALLINE_TANGLER, true); events.ScheduleEvent(EVENT_ORMOROK_SUMMON, 17000); break; case EVENT_ORMOROK_CRYSTAL_SPIKES: Talk(SAY_CRYSTAL_SPIKES); me->CastSpell(me, SPELL_CRYSTAL_SPIKES, false); _spikesCount = 0; events.ScheduleEvent(EVENT_ORMOROK_SUMMON_SPIKES, 300); events.ScheduleEvent(EVENT_ORMOROK_CRYSTAL_SPIKES, 20000); break; case EVENT_ORMOROK_SUMMON_SPIKES: if (++_spikesCount > 9) break; for (uint8 i = 0; i < 4; ++i) { float o = rand_norm()*2.0f*M_PI; float x = me->GetPositionX()+5.0f*_spikesCount*cos(o); float y = me->GetPositionY()+5.0f*_spikesCount*sin(o); me->SummonCreature(NPC_CRYSTAL_SPIKE, x, y, me->GetMap()->GetHeight(x, y, me->GetPositionZ()+5.0f), 0, TEMPSUMMON_TIMED_DESPAWN, 7000); } events.ScheduleEvent(EVENT_ORMOROK_SUMMON_SPIKES, 200); break; } DoMeleeAttackIfReady(); }
void ChooseDirection() { float angle = rand_norm() * 2.0f * 3.1416f; dstX = ROOM_CENTER_X + ROOM_RADIUS * sinf(angle); dstY = ROOM_CENTER_Y + ROOM_RADIUS * cosf(angle); dstZ = 394.5f; me->GetMotionMaster()->MovePoint(0, dstX, dstY, dstZ); }