bool OnTrigger(Player* player, AreaTriggerEntry const* /* trigger */) { if (player->GetQuestStatus(QUEST_THE_LONESOME_WATCHER) != QUEST_STATUS_INCOMPLETE) return false; Creature* stormforgedMonitor = Creature::GetCreature(*player, stormforgedMonitorGUID); if (stormforgedMonitor) return false; Creature* stormforgedEradictor = Creature::GetCreature(*player, stormforgedEradictorGUID); if (stormforgedEradictor) return false; stormforgedMonitor = player->SummonCreature(NPC_STORMFORGED_MONITOR, stormforgedMonitorPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); if (stormforgedMonitor) { stormforgedMonitorGUID = stormforgedMonitor->GetGUID(); stormforgedMonitor->SetWalk(false); /// The npc would search an alternative way to get to the last waypoint without this unit state. stormforgedMonitor->AddUnitState(UNIT_STATE_IGNORE_PATHFINDING); stormforgedMonitor->GetMotionMaster()->MovePath(NPC_STORMFORGED_MONITOR * 100, false); } stormforgedEradictor = player->SummonCreature(NPC_STORMFORGED_ERADICTOR, stormforgedEradictorPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); if (stormforgedEradictor) { stormforgedEradictorGUID = stormforgedEradictor->GetGUID(); stormforgedEradictor->GetMotionMaster()->MovePath(NPC_STORMFORGED_ERADICTOR * 100, false); } return true; }
void FollowMovementGenerator<Creature>::Initialize(Creature& owner) { owner.AddUnitState(UNIT_STATE_FOLLOW); // _MOVE set in _SetTargetLocation after required checks _updateSpeed(owner); _setTargetLocation(owner, true); m_evadeTimer = urand(4000, 8000); }
void HomeMovementGenerator<Creature>::Initialize(Creature & owner) { float x, y, z; owner.GetHomePosition(x, y, z, ori); owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); owner.AddUnitState(UNIT_STAT_EVADE); _setTargetLocation(owner); }
void ChaseMovementGenerator<Creature>::Initialize(Creature& owner) { owner.SetWalk(false); // Chase movement is running owner.AddUnitState(UNIT_STATE_CHASE); // _MOVE set in _SetTargetLocation after required checks _setTargetLocation(owner, true); m_evadeTimer = urand(4000, 8000); }
Creature* Transport::CreateNPCPassenger(uint32 guid, CreatureData const* data) { Map* map = GetMap(); Creature* creature = new Creature(); if (!creature->LoadCreatureFromDB(guid, map, false)) { delete creature; return NULL; } float x = data->posX; float y = data->posY; float z = data->posZ; float o = data->orientation; creature->SetTransport(this); creature->m_movementInfo.transport.guid = GetGUID(); creature->m_movementInfo.transport.pos.Relocate(x, y, z, o); // m_movementInfo.transport.pos.m_positionX x=offset CalculatePassengerPosition(x, y, z, &o); // This method transforms supplied transport offsets into global coordinates offset > worldpos creature->m_movementInfo.transport.seat = -1; GetMap()->CreatureRelocation(creature, x, y, z, o, false); creature->Relocate(x, y, z, o); // me->m_positionX x=worldpos creature->SetHomePosition(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation()); creature->SetTransportHomePosition(creature->m_movementInfo.transport.pos); /// @HACK - transport models are not added to map's dynamic LoS calculations /// because the current GameObjectModel cannot be moved without recreating creature->AddUnitState(UNIT_STATE_IGNORE_PATHFINDING); if (!creature->IsPositionValid()) { TC_LOG_ERROR("entities.transport", "Creature (guidlow %d, entry %d) not created. Suggested coordinates aren't valid (X: %f Y: %f)", creature->GetGUIDLow(), creature->GetEntry(), creature->GetPositionX(), creature->GetPositionY()); delete creature; return NULL; } if (!data->phaseIds.empty()) { for (uint16 ph : data->phaseIds) creature->SetInPhase(ph, false, true); } else creature->CopyPhaseFrom(this); if (!map->AddToMap(creature)) { delete creature; return NULL; } _staticPassengers.insert(creature); sScriptMgr->OnAddCreaturePassenger(this, creature); return creature; }
Creature* Transport::CreateNPCPassenger(ObjectGuid::LowType guid, CreatureData const* data) { Map* map = GetMap(); Creature* creature = new Creature(); if (!creature->LoadCreatureFromDB(guid, map, false)) { delete creature; return NULL; } ASSERT(data); float x = data->posX; float y = data->posY; float z = data->posZ; float o = data->orientation; creature->SetTransport(this); creature->m_movementInfo.transport.guid = GetGUID(); creature->m_movementInfo.transport.pos.Relocate(x, y, z, o); CalculatePassengerPosition(x, y, z, &o); creature->Relocate(x, y, z, o); creature->SetHomePosition(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation()); creature->SetTransportHomePosition(creature->m_movementInfo.transport.pos); /// @HACK - transport models are not added to map's dynamic LoS calculations /// because the current GameObjectModel cannot be moved without recreating creature->AddUnitState(UNIT_STATE_IGNORE_PATHFINDING); if (!creature->IsPositionValid()) { TC_LOG_ERROR("entities.transport", "Passenger %s not created. Suggested coordinates aren't valid (X: %f Y: %f)", creature->GetGUID().ToString().c_str(), creature->GetPositionX(), creature->GetPositionY()); delete creature; return NULL; } if (data->phaseid) creature->SetInPhase(data->phaseid, false, true); else if (data->phaseGroup) for (auto phase : sDB2Manager.GetPhasesForGroup(data->phaseGroup)) creature->SetInPhase(phase, false, true); else creature->CopyPhaseFrom(this); if (!map->AddToMap(creature)) { delete creature; return NULL; } _staticPassengers.insert(creature); sScriptMgr->OnAddCreaturePassenger(this, creature); return creature; }
void RandomMovementGenerator<Creature>::Initialize(Creature& creature) { if (!creature.IsAlive()) return; if (!wander_distance) wander_distance = creature.GetRespawnRadius(); creature.AddUnitState(UNIT_STATE_ROAMING); _setRandomLocation(creature); }
void RandomMovementGenerator<Creature>::Initialize(Creature &creature) { if (!creature.isAlive()) return; if (!_wanderDistance) _wanderDistance = creature.GetRespawnRadius(); creature.AddUnitState(UNIT_STATE_ROAMING | UNIT_STATE_ROAMING_MOVE); SetRandomLocation(creature); }
void RandomMovementGenerator<Creature>::Initialize(Creature &creature) { if (!creature.isAlive()) return; if (!wander_distance) wander_distance = creature.GetRespawnRadius(); creature.AddUnitState(UNIT_STATE_ROAMING); i_nextMoveTime.Reset(urand(1000, 5000)); }
void WaypointMovementGenerator<Creature>::InitTraveller(Creature &unit, const WaypointData &node) { node.run ? unit.RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING): unit.AddUnitMovementFlag(MOVEMENTFLAG_WALKING); unit.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); unit.SetUInt32Value(UNIT_FIELD_BYTES_1, 0); // TODO: make this part of waypoint node, so that creature can walk when desired? if (unit.canFly()) unit.SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02); unit.AddUnitState(UNIT_STAT_ROAMING); }
bool WaypointMovementGenerator<Creature>::StartMove(Creature &creature) { if (!i_path || i_path->empty()) return false; if (Stopped()) return true; if (m_isArrivalDone) { if ((i_currentNode == i_path->size() - 1) && !repeating) // If that's our last waypoint { creature.SetHomePosition(i_path->at(i_currentNode)->x, i_path->at(i_currentNode)->y, i_path->at(i_currentNode)->z, creature.GetOrientation()); creature.GetMotionMaster()->Initialize(); return false; } i_currentNode = (i_currentNode+1) % i_path->size(); } WaypointData const* node = i_path->at(i_currentNode); if (!node) return false; m_isArrivalDone = false; creature.AddUnitState(UNIT_STATE_ROAMING_MOVE); Movement::MoveSplineInit init(creature); init.MoveTo(node->x, node->y, node->z); //! Accepts angles such as 0.00001 and -0.00001, 0 must be ignored, default value in waypoint table if (node->orientation && node->delay) init.SetFacing(node->orientation); init.SetWalk(!node->run); init.Launch(); //Call for creature group update if (creature.GetFormation() && creature.GetFormation()->getLeader() == &creature) { creature.SetWalk(!node->run); creature.GetFormation()->LeaderMoveTo(node->x, node->y, node->z); } return true; }
Creature* Transport::CreateNPCPassenger(ObjectGuid::LowType guid, CreatureData const* data) { Map* map = GetMap(); Creature* creature = Creature::CreateCreatureFromDB(guid, map, false); if (!creature) return nullptr; ASSERT(data); float x = data->posX; float y = data->posY; float z = data->posZ; float o = data->orientation; creature->SetTransport(this); creature->m_movementInfo.transport.guid = GetGUID(); creature->m_movementInfo.transport.pos.Relocate(x, y, z, o); creature->m_movementInfo.transport.seat = -1; CalculatePassengerPosition(x, y, z, &o); creature->Relocate(x, y, z, o); creature->SetHomePosition(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation()); creature->SetTransportHomePosition(creature->m_movementInfo.transport.pos); /// @HACK - transport models are not added to map's dynamic LoS calculations /// because the current GameObjectModel cannot be moved without recreating creature->AddUnitState(UNIT_STATE_IGNORE_PATHFINDING); if (!creature->IsPositionValid()) { TC_LOG_ERROR("entities.transport", "Passenger %s not created. Suggested coordinates aren't valid (X: %f Y: %f)", creature->GetGUID().ToString().c_str(), creature->GetPositionX(), creature->GetPositionY()); delete creature; return nullptr; } PhasingHandler::InitDbPhaseShift(creature->GetPhaseShift(), data->phaseUseFlags, data->phaseId, data->phaseGroup); PhasingHandler::InitDbVisibleMapId(creature->GetPhaseShift(), data->terrainSwapMap); if (!map->AddToMap(creature)) { delete creature; return nullptr; } _staticPassengers.insert(creature); sScriptMgr->OnAddCreaturePassenger(this, creature); return creature; }
void SpawnAdds() { Creature* pCreature = NULL; for (uint8 i = 0; i < 4; ++i) { pCreature = me->SummonCreature(SpiritInfo[i].entry, SpiritInfo[i].x, SpiritInfo[i].y, SpiritInfo[i].z, SpiritInfo[i].orient, TEMPSUMMON_DEAD_DESPAWN, 0); if (pCreature) { pCreature->CastSpell(pCreature, SPELL_SPIRIT_AURA, true); pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); pCreature->AddUnitState(UNIT_STATE_STUNNED); SpiritGUID[i] = pCreature->GetGUID(); } } }
Creature* Transport::CreateNPCPassenger(uint32 guid, CreatureData const* data) { Map* map = GetMap(); Creature* creature = new Creature(); if (!creature->LoadCreatureFromDB(guid, map, false)) { delete creature; return NULL; } float x = data->posX; float y = data->posY; float z = data->posZ; float o = data->orientation; creature->SetTransport(this); creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); creature->m_movementInfo.transport.guid = GetGUID(); creature->m_movementInfo.transport.pos.Relocate(x, y, z, o); CalculatePassengerPosition(x, y, z, &o); creature->Relocate(x, y, z, o); creature->SetHomePosition(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation()); creature->SetTransportHomePosition(creature->m_movementInfo.transport.pos); /// @HACK - transport models are not added to map's dynamic LoS calculations /// because the current GameObjectModel cannot be moved without recreating creature->AddUnitState(UNIT_STATE_IGNORE_PATHFINDING); if (!creature->IsPositionValid()) { TC_LOG_ERROR(LOG_FILTER_TRANSPORTS, "Creature (guidlow %d, entry %d) not created. Suggested coordinates aren't valid (X: %f Y: %f)",creature->GetGUIDLow(),creature->GetEntry(),creature->GetPositionX(),creature->GetPositionY()); delete creature; return NULL; } if (!map->AddToMap(creature)) { delete creature; return NULL; } _staticPassengers.insert(creature); sScriptMgr->OnAddCreaturePassenger(this, creature); return creature; }
bool WaypointMovementGenerator<Creature>::StartMove(Creature &creature) { if (!i_path || i_path->empty()) return false; if (Stopped()) return true; const WaypointData *node = i_path->at(i_currentNode); if (m_isArrivalDone) { if ((i_currentNode == i_path->size() - 1) && !repeating) // If that's our last waypoint { creature.SetHomePosition(node->x, node->y, node->z, creature.GetOrientation()); creature.GetMotionMaster()->Initialize(); return false; } i_currentNode = (i_currentNode+1) % i_path->size(); } m_isArrivalDone = false; creature.AddUnitState(UNIT_STAT_ROAMING_MOVE); Movement::MoveSplineInit init(creature); init.MoveTo(node->x, node->y, node->z); if (node->orientation != 100 && node->delay != 0) init.SetFacing(node->orientation); init.SetWalk(!node->run); init.Launch(); //Call for creature group update if (creature.GetFormation() && creature.GetFormation()->getLeader() == &creature) creature.GetFormation()->LeaderMoveTo(node->x, node->y, node->z); return true; }
bool RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 diff) { if (creature.HasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED)) { i_nextMoveTime.Update(i_nextMoveTime.GetExpiry()); // Expire the timer creature.ClearUnitState(UNIT_STAT_ROAMING); return true; } i_nextMoveTime.Update(diff); if (i_destinationHolder.HasArrived() && !creature.IsStopped() && !creature.canFly()) creature.ClearUnitState(UNIT_STAT_ROAMING | UNIT_STAT_MOVE); if (!i_destinationHolder.HasArrived() && creature.IsStopped()) creature.AddUnitState(UNIT_STAT_ROAMING); CreatureTraveller traveller(creature); if (i_destinationHolder.UpdateTraveller(traveller, diff, true)) { if (i_nextMoveTime.Passed()) { if (irand(0, RUNNING_CHANCE_RANDOMMV) > 0) creature.AddUnitMovementFlag(MOVEMENTFLAG_WALKING); _setRandomLocation(creature); } else if (creature.isPet() && creature.GetOwner() && !creature.IsWithinDist(creature.GetOwner(), PET_FOLLOW_DIST+2.5f)) { creature.RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); _setRandomLocation(creature); } } return true; }
void ChaseMovementGenerator<Creature>::Initialize(Creature &owner) { owner.SetWalk(false); owner.AddUnitState(UNIT_STATE_CHASE|UNIT_STATE_CHASE_MOVE); _setTargetLocation(owner); }
void RandomMovementGenerator<Creature>::_setRandomLocation(Creature& creature) { if (creature.HasUnitState(UNIT_STATE_CASTING) && !creature.CanMoveDuringChannel()) { creature.CastStop(); return; } float X, Y, Z, nx, ny, nz, ori, dist; creature.GetHomePosition(X, Y, Z, ori); 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(); 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 Oregon::NormalizeMapCoord(nx); Oregon::NormalizeMapCoord(ny); dist = (nx - X) * (nx - X) + (ny - Y) * (ny - Y); if (is_air_ok) // 3D system above ground and above water (flying mode) { // Limit height change const float distanceZ = rand_norm() * 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 { 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); if (fabs(nz - Z) > dist) // Map check { nz = map->GetHeight(nx, ny, Z - 2.0f, true); // Vmap Horizontal or above if (fabs(nz - Z) > dist) { // Vmap Higher nz = map->GetHeight(nx, ny, Z + dist - 2.0f, true); // let's forget this bad coords where a z cannot be find and retry at next tick if (fabs(nz - Z) > dist) return; } } } if (is_air_ok) i_nextMoveTime.Reset(0); else { if (roll_chance_i(MOVEMENT_RANDOM_MMGEN_CHANCE_NO_BREAK)) i_nextMoveTime.Reset(urand(5000, 10000)); else i_nextMoveTime.Reset(urand(50, 400)); } creature.AddUnitState(UNIT_STATE_ROAMING); Movement::MoveSplineInit init(creature); init.MoveTo(nx, ny, nz, true); if (creature.IsPet() && creature.GetOwner() && !creature.IsWithinDist(creature.GetOwner(), PET_FOLLOW_DIST + 2.5f)) init.SetWalk(false); else init.SetWalk(true); init.Launch(); if (roll_chance_i(MOVEMENT_RANDOM_MMGEN_CHANCE_NO_BREAK)) i_nextMoveTime.Reset(50); else i_nextMoveTime.Reset(urand(1500, 10000)); // Keep a short wait time }
void HomeMovementGenerator<Creature>::Initialize(Creature & owner) { owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); owner.AddUnitState(UNIT_STATE_EVADE); _setTargetLocation(owner); }
void WaypointMovementGenerator<Creature>::Reset(Creature &creature) { creature.AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); StartMoveNow(creature); }
void WaypointMovementGenerator<Creature>::Initialize(Creature &creature) { LoadPath(creature); creature.AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); }
void RandomMovementGenerator<Creature>::SetRandomLocation(Creature &creature) { float respX, respY, respZ, respO, currZ, destX, destY, destZ, travelDistZ; creature.GetHomePosition(respX, respY, respZ, respO); currZ = creature.GetPositionZ(); Map const* map = creature.GetBaseMap(); // For 2D/3D system selection bool isAirOk = creature.canFly(); const float angle = float(rand_norm()) * static_cast<float>(M_PI*2.0f); const float range = float(rand_norm()) * _wanderDistance; const float distanceX = range * cos(angle); const float distanceY = range * sin(angle); destX = respX + distanceX; destY = respY + distanceY; // prevent invalid coordinates generation Trinity::NormalizeMapCoord(destX); Trinity::NormalizeMapCoord(destY); travelDistZ = distanceX*distanceX + distanceY*distanceY; if (isAirOk) // 3D system above ground and above water (flying mode) { // Limit height change const float distanceZ = float(rand_norm()) * 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 // 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; } } } if (isAirOk) _nextMoveTime.Reset(0); else _nextMoveTime.Reset(urand(500, 10000)); creature.AddUnitState(UNIT_STATE_ROAMING_MOVE); Movement::MoveSplineInit init(creature); init.MoveTo(destX, destY, destZ); init.SetWalk(true); init.Launch(); //Call for creature group update if (creature.GetFormation() && creature.GetFormation()->getLeader() == &creature) creature.GetFormation()->LeaderMoveTo(destX, destY, destZ); }
void HomeMovementGenerator<Creature>::Initialize(Creature & owner) { owner.AddUnitState(UNIT_STATE_EVADE); _setTargetLocation(owner); }
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 FollowMovementGenerator<Creature>::Initialize(Creature &owner) { owner.AddUnitState(UNIT_STATE_FOLLOW|UNIT_STATE_FOLLOW_MOVE); _updateSpeed(owner); _setTargetLocation(owner); }