bool ProcessEventId_event_go_focusing_iris(uint32 /*uiEventId*/, Object* pSource, Object* /*pTarget*/, bool /*bIsStart*/) { if (instance_eye_of_eternity* pInstance = (instance_eye_of_eternity*)((Creature*)pSource)->GetInstanceData()) { if (pSource->GetTypeId() != TYPEID_PLAYER) return false; if (pInstance->GetData(TYPE_MALYGOS) == IN_PROGRESS || pInstance->GetData(TYPE_MALYGOS) == DONE) return false; Creature* pMalygos = pInstance->GetSingleCreatureFromStorage(NPC_MALYGOS); Creature* pTrigger = pInstance->GetSingleCreatureFromStorage(NPC_LARGE_TRIGGER); if (!pMalygos || !pTrigger) return false; // Enter combat area - Move to ground point first, then start chasing target float fX, fY, fZ; pTrigger->GetNearPoint(pTrigger, fX, fY, fZ, 0, 30.0f, pTrigger->GetAngle(pMalygos)); pMalygos->GetMotionMaster()->MovePoint(POINT_ID_COMBAT, fX, fY, fZ); pMalygos->AI()->AttackStart((Player*)pSource); return true; } return false; }
static bool HandleNpcAddFormationCommand(ChatHandler* handler, const char* args) { if (!*args) return false; uint32 leaderGUID = (uint32) atoi((char*) args); Creature *pCreature = handler->getSelectedCreature(); if (!pCreature || !pCreature->GetDBTableGUIDLow()) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } uint32 lowguid = pCreature->GetDBTableGUIDLow(); if (pCreature->GetFormation()) { handler->PSendSysMessage( "Selected creature is already member of group %u", pCreature->GetFormation()->GetId()); return false; } if (!lowguid) return false; Player *chr = handler->GetSession()->GetPlayer(); FormationInfo *group_member; group_member = new FormationInfo; group_member->follow_angle = (pCreature->GetAngle(chr) - chr->GetOrientation()) * 180 / M_PI; group_member->follow_dist = sqrtf( pow(chr->GetPositionX() - pCreature->GetPositionX(), int(2)) + pow(chr->GetPositionY() - pCreature->GetPositionY(), int(2))); group_member->leaderGUID = leaderGUID; group_member->groupAI = 0; CreatureGroupMap[lowguid] = group_member; pCreature->SearchFormation(); WorldDatabase.PExecute( "INSERT INTO creature_formations (leaderGUID, memberGUID, dist, angle, groupAI) VALUES ('%u','%u','%f', '%f', '%u')", leaderGUID, lowguid, group_member->follow_dist, group_member->follow_angle, group_member->groupAI); handler->PSendSysMessage( "Creature %u added to formation with leader %u", lowguid, leaderGUID); return true; }
void DoAction(const int32 actionId) { switch (actionId) { case ACTION_OUTRO: { Position pos; if (Creature* pIck = GetIck()) { // TODO: tele on Ick then run some distance. pIck->GetNearPosition(pos, 5.0f, 3.14f); me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), 0.0f); } me->SetVisible(true); Creature* pJainaOrSylvanas = me->GetCreature(*me, pInstance->GetData64(DATA_JAINA_SYLVANAS_1)); if (pJainaOrSylvanas) { Position pos; me->GetNearPosition(pos, 5.0f, 0); pJainaOrSylvanas->NearTeleportTo( pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetAngle(me->GetPositionX(), me->GetPositionY())); } else { if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE) pJainaOrSylvanas = me->SummonCreature( NPC_SYLVANAS_PART1, *me, TEMPSUMMON_MANUAL_DESPAWN); else pJainaOrSylvanas = me->SummonCreature(NPC_JAINA_PART1, *me, TEMPSUMMON_MANUAL_DESPAWN); } if (pJainaOrSylvanas) { pJainaOrSylvanas->SetOrientation( pJainaOrSylvanas->GetAngle(me->GetPositionX(), me->GetPositionY())); me->SetOrientation( me->GetAngle(pJainaOrSylvanas->GetPositionX(), pJainaOrSylvanas->GetPositionY())); uiNpcOutroDialog = pJainaOrSylvanas->GetGUID(); } phase = PHASE_OUTRO; events.Reset(); events.ScheduleEvent(EVENT_OUTRO_1, 1000); break; } } }
static bool HandleNpcAddFormationCommand(ChatHandler* handler, const char* args) { if (!*args) return false; uint32 leaderGUID = (uint32) atoi((char*)args); Creature* creature = handler->getSelectedCreature(); if (!creature || !creature->GetDBTableGUIDLow()) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } uint32 lowguid = creature->GetDBTableGUIDLow(); if (creature->GetFormation()) { handler->PSendSysMessage("Selected creature is already member of group %u", creature->GetFormation()->GetId()); return false; } if (!lowguid) return false; Player* chr = handler->GetSession()->GetPlayer(); FormationInfo* group_member; group_member = new FormationInfo; group_member->follow_angle = (creature->GetAngle(chr) - chr->GetOrientation()) * 180 / M_PI; group_member->follow_dist = sqrtf(pow(chr->GetPositionX() - creature->GetPositionX(), int(2))+pow(chr->GetPositionY() - creature->GetPositionY(), int(2))); group_member->leaderGUID = leaderGUID; group_member->groupAI = 0; CreatureGroupMap[lowguid] = group_member; creature->SearchFormation(); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_CREATURE_FORMATION); stmt->setUInt32(0, leaderGUID); stmt->setUInt32(1, lowguid); stmt->setFloat(2, group_member->follow_dist); stmt->setFloat(3, group_member->follow_angle); stmt->setUInt32(4, uint32(group_member->groupAI)); WorldDatabase.Execute(stmt); handler->PSendSysMessage("Creature %u added to formation with leader %u", lowguid, leaderGUID); return true; }
bool ChargeMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff) { i_nextMoveTime.Update(diff); if(i_nextMoveTime.Passed()) { i_nextMoveTime.Reset(m_pointTime); float angle = creature.GetAngle(m_path[curPoint].x,m_path[curPoint].y); creature.GetMap()->CreatureRelocation(&creature, m_path[curPoint].x, m_path[curPoint].y, m_path[curPoint].z, angle); if(curPoint >= m_end) { creature.clearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE); return false; } ++curPoint; } return true; }
void FilterTargets(std::list<WorldObject*>& targets) { Creature* varos = GetCaster()->ToCreature(); if (!varos) return; if (varos->GetEntry() != NPC_VAROS) return; float orientation = ENSURE_AI(boss_varos::boss_varosAI, varos->AI())->GetCoreEnergizeOrientation(); for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end();) { float angle = varos->GetAngle((*itr)->GetPositionX(), (*itr)->GetPositionY()); float diff = std::fabs(orientation - angle); if (diff > 1.0f) itr = targets.erase(itr); else ++itr; } }
void ChargeMovementGenerator<Creature>::Initialize(Creature &creature) { if (!creature.isAlive()) return; creature.addUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE); if (m_start == m_end) { float dist = creature.GetDistance(m_path[m_end].x, m_path[m_end].y, m_path[m_end].z); float angle = creature.GetAngle(m_path[m_end].x, m_path[m_end].y); bool outdoor = creature.GetTerrain()->IsOutdoors(m_path[m_end].x, m_path[m_end].y, m_path[m_end].z); Coords pos = creature.GetPosition(); float itr = 1; if(m_pointTime > 1000) { while(float(m_pointTime)/(float(dist+itr)/itr) <= 1000 && itr < dist) itr+=0.3f; } else itr = dist; for(float i = 1; i < dist; i+=itr) { m_path.resize(m_path.size()+1); m_path.set(m_end+1, m_path[m_end]); pos.x += cos(angle)*itr; pos.y += sin(angle)*itr; creature.UpdateGroundPositionZ(pos.x, pos.y, pos.z, outdoor ? 10.0f : 3.0f); m_path.set(m_end, pos); ++m_end; } m_pointTime = float(m_pointTime)/float((m_end - m_start) + 1); i_nextMoveTime.Reset(m_pointTime); } }
// Emote Ardonis and Pathaleon void Turn_to_Pathaleons_Image() { Creature* ardonis = Unit::GetCreature(*me, ardonisGUID); Creature* pathaleon = Unit::GetCreature(*me, pathaleonGUID); Player* player = Unit::GetPlayer(*me, PlayerGUID); if (!ardonis || !pathaleon || !player) return; //Calculate the angle to Pathaleon angle_dawnforge = me->GetAngle(pathaleon->GetPositionX(), pathaleon->GetPositionY()); angle_ardonis = ardonis->GetAngle(pathaleon->GetPositionX(), pathaleon->GetPositionY()); //Turn Dawnforge and update me->SetOrientation(angle_dawnforge); me->SendUpdateToPlayer(player); //Turn Ardonis and update ardonis->SetOrientation(angle_ardonis); ardonis->SendUpdateToPlayer(player); //Set them to kneel me->SetStandState(UNIT_STAND_STATE_KNEEL); ardonis->SetStandState(UNIT_STAND_STATE_KNEEL); }
void Transform() { if (m_creature->GetMap()->GetPlayer(m_playerGuid)) { Creature* pDemon = m_creature->SummonCreature(NPC_SIMONE_THE_SEDUCTRESS, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), m_creature->GetAngle(m_creature), TEMPSPAWN_DEAD_DESPAWN, 0); Creature* pPrecious = GetClosestCreatureWithEntry(m_creature, NPC_PRECIOUS, 100.0f); if (pDemon) { if (npc_simone_seductressAI * pSimone = dynamic_cast<npc_simone_seductressAI*> (pDemon->AI())) pSimone->m_simoneGuid = m_creature->GetObjectGuid(); m_creature->SetVisibility(VISIBILITY_OFF); m_creature->ForcedDespawn(); } if (pDemon && pPrecious) { Creature* pPreciousDevourer = m_creature->SummonCreature(NPC_PRECIOUS_THE_DEVOURER, pPrecious->GetPositionX(), pPrecious->GetPositionY(), pPrecious->GetPositionZ(), pPrecious->GetAngle(pPrecious), TEMPSPAWN_DEAD_DESPAWN, 0, true); if (pPreciousDevourer) { if (npc_simone_seductressAI * pSimone = dynamic_cast<npc_simone_seductressAI*> (pDemon->AI())) pSimone->m_preciousGuid = pPreciousDevourer->GetObjectGuid(); if (npc_precious_the_devourerAI * pDevourer = dynamic_cast<npc_precious_the_devourerAI*> (pPreciousDevourer->AI())) pDevourer->m_simoneGuid = pDemon->GetObjectGuid(); } pPrecious->SetVisibility(VISIBILITY_OFF); pPrecious->ForcedDespawn(); } } }
void RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature) { float X, Y, Z, z, nx, ny, nz, ori, dist; creature.GetHomePosition(X, Y, Z, ori); z = creature.GetPositionZ(); Map const* map = creature.GetBaseMap(); // For 2D/3D system selection //bool is_land_ok = creature.canWalk(); //bool is_water_ok = creature.canSwim(); bool is_air_ok = creature.canFly(); for (uint32 i = 0; ; ++i) { const float angle = (float)rand_norm()*static_cast<float>(M_PI*2); const float range = (float)rand_norm()*wander_distance; const float distanceX = range * cos(angle); const float distanceY = range * sin(angle); nx = X + distanceX; ny = Y + distanceY; // prevent invalid coordinates generation Trillium::NormalizeMapCoord(nx); Trillium::NormalizeMapCoord(ny); dist = (nx - X)*(nx - X) + (ny - Y)*(ny - Y); if (i == 5) { nz = Z; break; } if (is_air_ok) // 3D system above ground and above water (flying mode) { const float distanceZ = (float)(rand_norm()) * sqrtf(dist)/2; // Limit height change nz = Z + distanceZ; float tz = map->GetHeight(nx, ny, nz-2.0f, false); // Map check only, vmap needed here but need to alter vmaps checks for height. float wz = map->GetWaterLevel(nx, ny); if (tz >= nz || wz >= nz) continue; // Problem here, we must fly above the ground and water, not under. Let's try on next tick } //else if (is_water_ok) // 3D system under water and above ground (swimming mode) else // 2D only { dist = dist >= 100.0f ? 10.0f : sqrtf(dist); // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE) // The fastest way to get an accurate result 90% of the time. // Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long. nz = map->GetHeight(nx, ny, Z+dist-2.0f, false); // Map check if (fabs(nz-Z)>dist) { nz = map->GetHeight(nx, ny, Z-2.0f, true); // Vmap Horizontal or above if (fabs(nz-Z)>dist) { nz = map->GetHeight(nx, ny, Z+dist-2.0f, true); // Vmap Higher if (fabs(nz-Z)>dist) continue; // let's forget this bad coords where a z cannot be find and retry at next tick } } } break; } Traveller<Creature> traveller(creature); creature.SetOrientation(creature.GetAngle(nx, ny)); i_destinationHolder.SetDestination(traveller, nx, ny, nz); creature.AddUnitState(UNIT_STAT_ROAMING); if (is_air_ok) { i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); } //else if (is_water_ok) // Swimming mode to be done with more than this check else { i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(), 5000+i_destinationHolder.GetTotalTravelTime())); creature.AddUnitMovementFlag(MOVEMENTFLAG_WALKING); } //Call for creature group update if (creature.GetFormation() && creature.GetFormation()->getLeader() == &creature) { creature.GetFormation()->LeaderMoveTo(nx, ny, nz); } }
void RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature) { float respX, respY, respZ, respO, currZ, destX, destY, destZ, wander_distance, travelDistZ; creature.GetRespawnCoord(respX, respY, respZ, &respO, &wander_distance); currZ = creature.GetPositionZ(); TerrainInfo const* map = creature.GetTerrain(); // For 2D/3D system selection //bool is_land_ok = creature.CanWalk(); // not used? //bool is_water_ok = creature.CanSwim(); // not used? bool is_air_ok = creature.CanFly(); const float angle = rand_norm_f() * (M_PI_F*2.0f); const float range = rand_norm_f() * wander_distance; const float distanceX = range * cos(angle); const float distanceY = range * sin(angle); destX = respX + distanceX; destY = respY + distanceY; // prevent invalid coordinates generation MaNGOS::NormalizeMapCoord(destX); MaNGOS::NormalizeMapCoord(destY); travelDistZ = distanceX*distanceX + distanceY*distanceY; if (is_air_ok) // 3D system above ground and above water (flying mode) { // Limit height change const float distanceZ = rand_norm_f() * sqrtf(travelDistZ)/2.0f; destZ = respZ + distanceZ; float levelZ = map->GetWaterOrGroundLevel(destX, destY, destZ-2.0f); // Problem here, we must fly above the ground and water, not under. Let's try on next tick if (levelZ >= destZ) return; } //else if (is_water_ok) // 3D system under water and above ground (swimming mode) else // 2D only { destZ = respZ; if(!map->IsNextZcoordOK(destX, destY, destZ, travelDistZ)) return; // let's forget this bad coords where a z cannot be find and retry at next tick creature.UpdateGroundPositionZ(destX, destY, destZ, travelDistZ); } Traveller<Creature> traveller(creature); creature.SetOrientation(creature.GetAngle(destX, destY)); i_destinationHolder.SetDestination(traveller, destX, destY, destZ); creature.addUnitState(UNIT_STAT_ROAMING_MOVE); if (is_air_ok) { i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7); } //else if (is_water_ok) // Swimming mode to be done with more than this check else { i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(), 10000+i_destinationHolder.GetTotalTravelTime())); creature.AddSplineFlag(SPLINEFLAG_WALKMODE); } }
void RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature) { float X,Y,Z,z,nx,ny,nz,wander_distance,ori,dist; creature.GetRespawnCoord(X, Y, Z, &ori, &wander_distance); z = creature.GetPositionZ(); uint32 mapid=creature.GetMapId(); Map const* map = MapManager::Instance().GetBaseMap(mapid); // For 2D/3D system selection //bool is_land_ok = creature.canWalk(); // not used? //bool is_water_ok = creature.canSwim(); // not used? bool is_air_ok = creature.canFly(); const float angle = rand_norm()*(M_PI*2); const float range = rand_norm()*wander_distance; const float distanceX = range * cos(angle); const float distanceY = range * sin(angle); nx = X + distanceX; ny = Y + distanceY; // prevent invalid coordinates generation MaNGOS::NormalizeMapCoord(nx); MaNGOS::NormalizeMapCoord(ny); dist = distanceX*distanceX + distanceY*distanceY; if (is_air_ok) // 3D system above ground and above water (flying mode) { const float distanceZ = rand_norm() * sqrtf(dist)/2; // Limit height change nz = Z + distanceZ; float tz = map->GetHeight(nx, ny, nz-2.0f, false); // Map check only, vmap needed here but need to alter vmaps checks for height. float wz = map->GetWaterLevel(nx, ny); if (tz >= nz || wz >= nz) return; // Problem here, we must fly above the ground and water, not under. Let's try on next tick } //else if (is_water_ok) // 3D system under water and above ground (swimming mode) else // 2D only { dist = dist>=100.0f ? 10.0f : sqrtf(dist); // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE) // The fastest way to get an accurate result 90% of the time. // Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long. nz = map->GetHeight(nx,ny,Z+dist-2.0f,false); // Map check if (fabs(nz-Z)>dist) { nz = map->GetHeight(nx,ny,Z-2.0f,true); // Vmap Horizontal or above if (fabs(nz-Z)>dist) { nz = map->GetHeight(nx,ny,Z+dist-2.0f,true); // Vmap Higher if (fabs(nz-Z)>dist) return; // let's forget this bad coords where a z cannot be find and retry at next tick } } } Traveller<Creature> traveller(creature); creature.SetOrientation(creature.GetAngle(nx,ny)); i_destinationHolder.SetDestination(traveller, nx, ny, nz); creature.addUnitState(UNIT_STAT_ROAMING); if (is_air_ok) { i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); creature.AddUnitMovementFlag(MONSTER_MOVE_FLY); } //else if (is_water_ok) // Swimming mode to be done with more than this check else { i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(),5000+i_destinationHolder.GetTotalTravelTime())); creature.SetUnitMovementFlags(MONSTER_MOVE_WALK); } }
void RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature) { float respX, respY, respZ, respO, currZ, destX, destY, destZ, wander_distance, travelDistZ; creature.GetRespawnCoord(respX, respY, respZ, &respO, &wander_distance); currZ = creature.GetPositionZ(); TerrainInfo const* map = creature.GetTerrain(); // For 2D/3D system selection //bool is_land_ok = creature.CanWalk(); // not used? //bool is_water_ok = creature.CanSwim(); // not used? bool is_air_ok = creature.CanFly(); const float angle = rand_norm_f() * (M_PI_F*2.0f); const float range = rand_norm_f() * wander_distance; const float distanceX = range * cos(angle); const float distanceY = range * sin(angle); destX = respX + distanceX; destY = respY + distanceY; // prevent invalid coordinates generation MaNGOS::NormalizeMapCoord(destX); MaNGOS::NormalizeMapCoord(destY); travelDistZ = distanceX*distanceX + distanceY*distanceY; if (is_air_ok) // 3D system above ground and above water (flying mode) { // Limit height change const float distanceZ = rand_norm_f() * sqrtf(travelDistZ)/2.0f; destZ = respZ + distanceZ; float levelZ = map->GetWaterOrGroundLevel(destX, destY, destZ-2.0f); // Problem here, we must fly above the ground and water, not under. Let's try on next tick if (levelZ >= destZ) return; } //else if (is_water_ok) // 3D system under water and above ground (swimming mode) else // 2D only { // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE) travelDistZ = travelDistZ >= 100.0f ? 10.0f : sqrtf(travelDistZ); // The fastest way to get an accurate result 90% of the time. // Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long. destZ = map->GetHeight(destX, destY, respZ+travelDistZ-2.0f, false); if (fabs(destZ - respZ) > travelDistZ) // Map check { // Vmap Horizontal or above destZ = map->GetHeight(destX, destY, respZ - 2.0f, true); if (fabs(destZ - respZ) > travelDistZ) { // Vmap Higher destZ = map->GetHeight(destX, destY, respZ+travelDistZ-2.0f, true); // let's forget this bad coords where a z cannot be find and retry at next tick if (fabs(destZ - respZ) > travelDistZ) return; } } } Traveller<Creature> traveller(creature); creature.SetOrientation(creature.GetAngle(destX, destY)); i_destinationHolder.SetDestination(traveller, destX, destY, destZ); creature.addUnitState(UNIT_STAT_ROAMING_MOVE); if (is_air_ok) { i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); creature.AddSplineFlag(SPLINEFLAG_FLYING); } //else if (is_water_ok) // Swimming mode to be done with more than this check else { i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime() + urand(500, 10000)); creature.AddSplineFlag(SPLINEFLAG_WALKMODE); } }
bool EffectAuraDummy_npc_captured_beryl_sorcerer(const Aura* pAura, bool bApply) { if (pAura->GetId() == SPELL_ARCANE_CHAINS_CHANNEL) { if (pAura->GetEffIndex() != EFFECT_INDEX_0 || !bApply) return false; Creature* pCreature = (Creature*)pAura->GetTarget(); Unit* pCaster = pAura->GetCaster(); if (!pCreature || !pCaster || pCaster->GetTypeId() != TYPEID_PLAYER || pCreature->GetEntry() != NPC_CAPTURED_BERYL_SORCERER) return false; // follow the caster ((Player*)pCaster)->KilledMonsterCredit(NPC_CAPTURED_BERYL_SORCERER); pCreature->GetMotionMaster()->MoveFollow(pCaster, pCreature->GetDistance(pCaster), M_PI_F - pCreature->GetAngle(pCaster)); return true; } return false; }
void RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature) { float X,Y,Z,z,nx,ny,nz,wander_distance,ori,dist; creature.GetRespawnCoord(X, Y, Z, &ori, &wander_distance); z = creature.GetPositionZ(); Map const* map = creature.GetBaseMap(); // For 2D/3D system selection //bool is_land_ok = creature.canWalk(); // not used? //bool is_water_ok = creature.canSwim(); // not used? bool is_air_ok = creature.canFly(); const float angle = rand_norm_f()*(M_PI_F*2.0f); const float range = rand_norm_f()*wander_distance; const float distanceX = range * cos(angle); const float distanceY = range * sin(angle); nx = X + distanceX; ny = Y + distanceY; // prevent invalid coordinates generation MaNGOS::NormalizeMapCoord(nx); MaNGOS::NormalizeMapCoord(ny); dist = distanceX*distanceX + distanceY*distanceY; if (is_air_ok) // 3D system above ground and above water (flying mode) { // Limit height change const float distanceZ = rand_norm_f() * sqrtf(dist)/2.0f; nz = Z + distanceZ; float tz = map->GetHeight(nx, ny, nz-2.0f, false); // Map check only, vmap needed here but need to alter vmaps checks for height. float wz = map->GetWaterLevel(nx, ny); // Problem here, we must fly above the ground and water, not under. Let's try on next tick if (tz >= nz || wz >= nz) return; } //else if (is_water_ok) // 3D system under water and above ground (swimming mode) else // 2D only { nz = Z; if (!map->IsNextZcoordOK(nx, ny, nz, dist)) return; // let's forget this bad coords where a z cannot be find and retry at next tick creature.UpdateGroundPositionZ(nx, ny, nz, dist); } Traveller<Creature> traveller(creature); creature.SetOrientation(creature.GetAngle(nx, ny)); i_destinationHolder.SetDestination(traveller, nx, ny, nz); creature.addUnitState(UNIT_STAT_ROAMING_MOVE); if (is_air_ok && !(creature.canWalk() && creature.IsAtGroundLevel(nx, ny, nz))) { i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7); } //else if (is_water_ok) // Swimming mode to be done with more than this check else { i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(), 10000+i_destinationHolder.GetTotalTravelTime())); creature.AddSplineFlag(SPLINEFLAG_WALKMODE); } }
void RandomCircleMovementGenerator<Creature>::fillSplineWayPoints(Creature &creature) { m_splineMap.clear(); float spawnX, spawnY, spawnZ, spawnO, spawnDist, x, y, z; creature.GetRespawnCoord(spawnX, spawnY, spawnZ, &spawnO, &spawnDist); creature.GetPosition(x,y,z); //Add first waypoint /* SplineWayPointInfo *firstwp = new SplineWayPointInfo(); firstwp->x = x; firstwp->y = y; firstwp->z = z; m_splineMap.insert(std::make_pair<uint32, SplineWayPointInfo*>(0, firstwp)); */ //calculate other ones float m_fDistance = creature.GetDistance2d(spawnX, spawnY); float m_fLenght = 2*M_PI_F*m_fDistance; float m_fAngle = (M_PI_F - ((2*M_PI_F) / m_fLenght)) / 2; if (m_bClockWise) m_fAngle += ((2*M_PI_F) / m_fLenght) + creature.GetAngle(spawnX, spawnY); else m_fAngle = creature.GetAngle(spawnX, spawnY) - m_fAngle - ((2*M_PI_F) / m_fLenght); //because it cant be lower than 0 or bigger than 2*PI m_fAngle = (m_fAngle >= 0) ? m_fAngle : 2 * M_PI_F + m_fAngle; m_fAngle = (m_fAngle <= 2*M_PI_F) ? m_fAngle : m_fAngle - 2 * M_PI_F; float creature_speed = creature.GetSpeed(MOVE_FLIGHT) / 2; float lastx = x; float lasty = y; for(uint32 wpId = 0; wpId < 30; ++wpId) { bool canIncerase = true; bool canDecerase = true; if (m_fDistance > spawnDist) canIncerase = false; if (m_fDistance < 1) canDecerase = false; uint8 tmp = urand(0,2); // 0 nothing, 1 incerase, 2 decerase if (tmp == 1 && canIncerase) m_fDistance += 0.5f; else if (tmp == 2 && canDecerase) m_fDistance -= 0.5f; m_fLenght = 2*M_PI_F*m_fDistance; float m_fRotateAngle = ((2*M_PI_F) / m_fLenght); // Moving by half of speed every 500ms if (m_bClockWise) m_fAngle -= m_fRotateAngle; else m_fAngle += m_fRotateAngle; //because it cant be lower than 0 or bigger than 2*PI m_fAngle = (m_fAngle >= 0) ? m_fAngle : 2 * M_PI_F + m_fAngle; m_fAngle = (m_fAngle <= 2*M_PI_F) ? m_fAngle : m_fAngle - 2 * M_PI_F; lastx += cos(m_fAngle)*creature_speed; lasty += sin(m_fAngle)*creature_speed; MaNGOS::NormalizeMapCoord(lastx); MaNGOS::NormalizeMapCoord(lasty); Position *wp = new Position(); wp->x = lastx; wp->y = lasty; wp->z = z; wp->o = m_fAngle; m_splineMap.insert(std::make_pair<uint32, Position*>(wpId, wp)); } i_nextMoveTime.Reset(500); }