void Transport::UpdateNPCPositions() { for (CreatureSet::iterator itr = m_NPCPassengerSet.begin(); itr != m_NPCPassengerSet.end(); ++itr) { Creature* npc = *itr; float x, y, z, o; npc->m_movementInfo.t_pos.GetPosition(x, y, z, o); CalculatePassengerPosition(x, y, z, o); GetMap()->CreatureRelocation(npc, x, y, z, o, false); npc->GetTransportHomePosition(x, y, z, o); CalculatePassengerPosition(x, y, z, o); npc->SetHomePosition(x, y, z, o); } for (PlayerSet::iterator itr = m_passengers.begin(); itr != m_passengers.end(); ++itr) { Player* plr = *itr; float x, y, z, o; o = GetOrientation() + plr->m_movementInfo.t_pos.m_orientation; MapManager::NormalizeOrientation(o); x = GetPositionX() + (plr->m_movementInfo.t_pos.m_positionX * cos(GetOrientation()) + plr->m_movementInfo.t_pos.m_positionY * sin(GetOrientation() + M_PI)); y = GetPositionY() + (plr->m_movementInfo.t_pos.m_positionY * cos(GetOrientation()) + plr->m_movementInfo.t_pos.m_positionX * sin(GetOrientation())); z = GetPositionZ() + plr->m_movementInfo.t_pos.m_positionZ; plr->Relocate(x, y, z, o); UpdateData transData; WorldPacket packet; transData.BuildPacket(&packet); plr->SendDirectMessage(&packet); } }
void Transport::UpdatePassengerPositions(PassengerSet& passengers) { for (PassengerSet::iterator itr = passengers.begin(); itr != passengers.end(); ++itr) { WorldObject* passenger = *itr; // transport teleported but passenger not yet (can happen for players) if (passenger->GetMap() != GetMap()) continue; // if passenger is on vehicle we have to assume the vehicle is also on transport // and its the vehicle that will be updating its passengers if (Unit* unit = passenger->ToUnit()) if (unit->GetVehicle()) continue; // Do not use Unit::UpdatePosition here, we don't want to remove auras // as if regular movement occurred float x, y, z, o; passenger->m_movementInfo.transport.pos.GetPosition(x, y, z, o); CalculatePassengerPosition(x, y, z, &o); switch (passenger->GetTypeId()) { case TYPEID_UNIT: { Creature* creature = passenger->ToCreature(); GetMap()->CreatureRelocation(creature, x, y, z, o, false); creature->GetTransportHomePosition(x, y, z, o); CalculatePassengerPosition(x, y, z, &o); creature->SetHomePosition(x, y, z, o); break; } case TYPEID_PLAYER: //relocate only passengers in world and skip any player that might be still logging in/teleporting if (passenger->IsInWorld()) GetMap()->PlayerRelocation(passenger->ToPlayer(), x, y, z, o); break; case TYPEID_GAMEOBJECT: GetMap()->GameObjectRelocation(passenger->ToGameObject(), x, y, z, o, false); passenger->ToGameObject()->RelocateStationaryPosition(x, y, z, o); break; case TYPEID_DYNAMICOBJECT: GetMap()->DynamicObjectRelocation(passenger->ToDynObject(), x, y, z, o); break; case TYPEID_AREATRIGGER: GetMap()->AreaTriggerRelocation(passenger->ToAreaTrigger(), x, y, z, o); break; default: break; } if (Unit* unit = passenger->ToUnit()) if (Vehicle* vehicle = unit->GetVehicleKit()) vehicle->RelocatePassengers(); } }
void Transport::UpdateNPCPositions() { for (CreatureSet::iterator itr = m_NPCPassengerSet.begin(); itr != m_NPCPassengerSet.end(); ++itr) { Creature* npc = *itr; float x, y, z, o; npc->m_movementInfo.t_pos.GetPosition(x, y, z, o); CalculatePassengerPosition(x, y, z, o); GetMap()->CreatureRelocation(npc, x, y, z, o, false); npc->GetTransportHomePosition(x, y, z, o); CalculatePassengerPosition(x, y, z, o); npc->SetHomePosition(x, y, z, o); } }
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; }
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; }
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; }
void Vehicle::RelocatePassengers() { ASSERT(_me->GetMap()); // not sure that absolute position calculation is correct, it must depend on vehicle pitch angle for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr) { if (Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), itr->second.Passenger.Guid)) { ASSERT(passenger->IsInWorld()); float px, py, pz, po; passenger->m_movementInfo.transport.pos.GetPosition(px, py, pz, po); CalculatePassengerPosition(px, py, pz, &po); passenger->UpdatePosition(px, py, pz, po); } } }
GameObject* Transport::CreateGOPassenger(ObjectGuid::LowType guid, GameObjectData const* data) { Map* map = GetMap(); GameObject* go = GameObject::CreateGameObjectFromDB(guid, map, false); if (!go) return nullptr; ASSERT(data); float x = data->posX; float y = data->posY; float z = data->posZ; float o = data->orientation; go->SetTransport(this); go->m_movementInfo.transport.guid = GetGUID(); go->m_movementInfo.transport.pos.Relocate(x, y, z, o); go->m_movementInfo.transport.seat = -1; CalculatePassengerPosition(x, y, z, &o); go->Relocate(x, y, z, o); go->RelocateStationaryPosition(x, y, z, o); if (!go->IsPositionValid()) { TC_LOG_ERROR("entities.transport", "Passenger %s not created. Suggested coordinates aren't valid (X: %f Y: %f)", go->GetGUID().ToString().c_str(), go->GetPositionX(), go->GetPositionY()); delete go; return nullptr; } PhasingHandler::InitDbPhaseShift(go->GetPhaseShift(), data->phaseUseFlags, data->phaseId, data->phaseGroup); PhasingHandler::InitDbVisibleMapId(go->GetPhaseShift(), data->terrainSwapMap); if (!map->AddToMap(go)) { delete go; return nullptr; } _staticPassengers.insert(go); return go; }
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); 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; }
GameObject* Transport::CreateGOPassenger(uint32 guid, GameObjectData const* data) { Map* map = GetMap(); GameObject* go = new GameObject(); if (!go->LoadGameObjectFromDB(guid, map, false)) { delete go; return NULL; } float x = data->posX; float y = data->posY; float z = data->posZ; float o = data->orientation; go->SetTransport(this); go->m_movementInfo.transport.guid = GetGUID(); go->m_movementInfo.transport.pos.Relocate(x, y, z, o); // m_movementInfo.transport.pos.m_positionX = offset go->m_movementInfo.transport.seat = -1; CalculatePassengerPosition(x, y, z, &o); // This method transforms supplied transport offsets into global coordinates offset > worldpos go->Relocate(x, y, z, o); // me->m_positionX = worldpos go->RelocateStationaryPosition(x, y, z, o); // this->gameobject->m_stationaryPosition x=worldpos go->m_updateFlag |= UPDATEFLAG_GO_TRANSPORT_POSITION; if (!go->IsPositionValid()) { TC_LOG_ERROR("entities.transport", "GameObject (guidlow %d, entry %d) not created. Suggested coordinates aren't valid (X: %f Y: %f)", go->GetGUIDLow(), go->GetEntry(), go->GetPositionX(), go->GetPositionY()); delete go; return NULL; } if (!map->AddToMap(go)) { delete go; return NULL; } _staticPassengers.insert(go); return go; }
GameObject* Transport::CreateGOPassenger(ObjectGuid::LowType guid, GameObjectData const* data) { Map* map = GetMap(); GameObject* go = new GameObject(); if (!go->LoadGameObjectFromDB(guid, map, false)) { delete go; return NULL; } ASSERT(data); float x = data->posX; float y = data->posY; float z = data->posZ; float o = data->orientation; go->SetTransport(this); go->m_movementInfo.transport.guid = GetGUID(); go->m_movementInfo.transport.pos.Relocate(x, y, z, o); CalculatePassengerPosition(x, y, z, &o); go->Relocate(x, y, z, o); go->RelocateStationaryPosition(x, y, z, o); if (!go->IsPositionValid()) { TC_LOG_ERROR("entities.transport", "GameObject (guidlow %d, entry %d) not created. Suggested coordinates aren't valid (X: %f Y: %f)", go->GetGUID().GetCounter(), go->GetEntry(), go->GetPositionX(), go->GetPositionY()); delete go; return NULL; } if (!map->AddToMap(go)) { delete go; return NULL; } _staticPassengers.insert(go); return go; }
//! Must be called after m_base::Relocate void Vehicle::RelocatePassengers() { ASSERT(_me->GetMap()); // not sure that absolute position calculation is correct, it must depend on vehicle pitch angle for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr) { if (Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), itr->second.Passenger)) { ASSERT(passenger->IsInWorld()); VehicleSeatEntry const* veSeat = itr->second.SeatInfo; float px = veSeat->m_attachmentOffsetX; float py = veSeat->m_attachmentOffsetY; float pz = veSeat->m_attachmentOffsetZ; float po = 0.0f; //passenger->m_movementInfo.t_pos.GetPosition(px, py, pz, po); CalculatePassengerPosition(px, py, pz, po); passenger->UpdatePosition(px, py, pz, po); } } }
void Vehicle::RelocatePassengers() { ASSERT(_me->GetMap()); std::vector<std::pair<Unit*, Position>> seatRelocation; seatRelocation.reserve(Seats.size()); // not sure that absolute position calculation is correct, it must depend on vehicle pitch angle for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr) { if (Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), itr->second.Passenger.Guid)) { ASSERT(passenger->IsInWorld()); float px, py, pz, po; passenger->m_movementInfo.transport.pos.GetPosition(px, py, pz, po); CalculatePassengerPosition(px, py, pz, &po); seatRelocation.emplace_back(passenger, Position(px, py, pz, po)); } } for (auto const& pair : seatRelocation) pair.first->UpdatePosition(pair.second); }
TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSummonType summonType, SummonPropertiesEntry const* properties /*= NULL*/, uint32 duration /*= 0*/, Unit* summoner /*= NULL*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/) { Map* map = FindMap(); if (!map) return NULL; uint32 mask = UNIT_MASK_SUMMON; if (properties) { switch (properties->Control) { case SUMMON_CATEGORY_PET: mask = UNIT_MASK_GUARDIAN; break; case SUMMON_CATEGORY_PUPPET: mask = UNIT_MASK_PUPPET; break; case SUMMON_CATEGORY_VEHICLE: mask = UNIT_MASK_MINION; break; case SUMMON_CATEGORY_WILD: case SUMMON_CATEGORY_ALLY: case SUMMON_CATEGORY_UNK: { switch (properties->Title) { case SUMMON_TYPE_MINION: case SUMMON_TYPE_GUARDIAN: case SUMMON_TYPE_GUARDIAN2: mask = UNIT_MASK_GUARDIAN; break; case SUMMON_TYPE_TOTEM: case SUMMON_TYPE_LIGHTWELL: mask = UNIT_MASK_TOTEM; break; case SUMMON_TYPE_VEHICLE: case SUMMON_TYPE_VEHICLE2: mask = UNIT_MASK_SUMMON; break; case SUMMON_TYPE_MINIPET: mask = UNIT_MASK_MINION; break; default: if (properties->Flags & 512) // Mirror Image, Summon Gargoyle mask = UNIT_MASK_GUARDIAN; break; } break; } default: return NULL; } } TempSummon* summon = nullptr; switch (mask) { case UNIT_MASK_SUMMON: summon = new TempSummon(properties, summoner, false); break; case UNIT_MASK_GUARDIAN: summon = new Guardian(properties, summoner, false); break; case UNIT_MASK_PUPPET: summon = new Puppet(properties, summoner); break; case UNIT_MASK_TOTEM: summon = new Totem(properties, summoner); break; case UNIT_MASK_MINION: summon = new Minion(properties, summoner, false); break; } float x, y, z, o; pos.GetPosition(x, y, z, o); CalculatePassengerPosition(x, y, z, &o); if (!summon->Create(map->GenerateLowGuid<HighGuid::Creature>(), map, entry, x, y, z, o, nullptr, vehId)) { delete summon; return nullptr; } PhasingHandler::InheritPhaseShift(summon, summoner ? static_cast<WorldObject*>(summoner) : static_cast<WorldObject*>(this)); summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId); summon->SetTransport(this); summon->m_movementInfo.transport.guid = GetGUID(); summon->m_movementInfo.transport.pos.Relocate(pos); summon->Relocate(x, y, z, o); summon->SetHomePosition(x, y, z, o); summon->SetTransportHomePosition(pos); /// @HACK - transport models are not added to map's dynamic LoS calculations /// because the current GameObjectModel cannot be moved without recreating summon->AddUnitState(UNIT_STATE_IGNORE_PATHFINDING); summon->InitStats(duration); if (!map->AddToMap<Creature>(summon)) { delete summon; return nullptr; } _staticPassengers.insert(summon); summon->InitSummon(); summon->SetTempSummonType(summonType); return summon; }
TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSummonType summonType, SummonPropertiesEntry const* properties /*= NULL*/, uint32 duration /*= 0*/, Unit* summoner /*= NULL*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/) { Map* map = FindMap(); if (!map) return NULL; uint32 mask = UNIT_MASK_SUMMON; if (properties) { switch (properties->Category) { case SUMMON_CATEGORY_PET: mask = UNIT_MASK_GUARDIAN; break; case SUMMON_CATEGORY_PUPPET: mask = UNIT_MASK_PUPPET; break; case SUMMON_CATEGORY_VEHICLE: mask = UNIT_MASK_MINION; break; case SUMMON_CATEGORY_WILD: case SUMMON_CATEGORY_ALLY: case SUMMON_CATEGORY_UNK: { switch (properties->Type) { case SUMMON_TYPE_MINION: case SUMMON_TYPE_GUARDIAN: case SUMMON_TYPE_GUARDIAN2: mask = UNIT_MASK_GUARDIAN; break; case SUMMON_TYPE_TOTEM: case SUMMON_TYPE_LIGHTWELL: mask = UNIT_MASK_TOTEM; break; case SUMMON_TYPE_VEHICLE: case SUMMON_TYPE_VEHICLE2: mask = UNIT_MASK_SUMMON; break; case SUMMON_TYPE_MINIPET: mask = UNIT_MASK_MINION; break; default: if (properties->Flags & 512) // Mirror Image, Summon Gargoyle mask = UNIT_MASK_GUARDIAN; break; } break; } default: return NULL; } } uint32 phase = PHASEMASK_NORMAL; uint32 team = 0; if (summoner) { phase = summoner->GetPhaseMask(); if (summoner->GetTypeId() == TYPEID_PLAYER) team = summoner->ToPlayer()->GetTeam(); } TempSummon* summon = NULL; switch (mask) { case UNIT_MASK_SUMMON: summon = new TempSummon(properties, summoner, false); break; case UNIT_MASK_GUARDIAN: summon = new Guardian(properties, summoner, false); break; case UNIT_MASK_PUPPET: summon = new Puppet(properties, summoner); break; case UNIT_MASK_TOTEM: summon = new Totem(properties, summoner); break; case UNIT_MASK_MINION: summon = new Minion(properties, summoner, false); break; } float x, y, z, o; pos.GetPosition(x, y, z, o); CalculatePassengerPosition(x, y, z, &o); if (!summon->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, phase, entry, vehId, team, x, y, z, o)) { delete summon; return NULL; } summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId); summon->SetTransport(this); summon->m_movementInfo.transport.guid = GetGUID(); summon->m_movementInfo.transport.pos.Relocate(pos); summon->Relocate(x, y, z, o); summon->SetHomePosition(x, y, z, o); summon->SetTransportHomePosition(pos); /// @HACK - transport models are not added to map's dynamic LoS calculations /// because the current GameObjectModel cannot be moved without recreating summon->AddUnitState(UNIT_STATE_IGNORE_PATHFINDING); summon->InitStats(duration); if (!map->AddToMap<Creature>(summon)) { delete summon; return NULL; } _staticPassengers.insert(summon); summon->InitSummon(); summon->SetTempSummonType(summonType); return summon; }
bool Vehicle::AddPassenger(Unit* unit, int8 seatId) { /// @Prevent adding passengers when vehicle is uninstalling. (Bad script in OnUninstall/OnRemovePassenger/PassengerBoarded hook.) if (_status == STATUS_UNINSTALLING) { #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_VEHICLES, "Passenger GuidLow: %u, Entry: %u, attempting to board vehicle GuidLow: %u, Entry: %u during uninstall! SeatId: %i", unit->GetGUIDLow(), unit->GetEntry(), _me->GetGUIDLow(), _me->GetEntry(), (int32)seatId); #endif return false; } if (unit->GetVehicle() != this) return false; SeatMap::iterator seat; if (seatId < 0) // no specific seat requirement { for (seat = Seats.begin(); seat != Seats.end(); ++seat) if (seat->second.IsEmpty() && (seat->second.SeatInfo->CanEnterOrExit() || seat->second.SeatInfo->IsUsableByOverride())) break; if (seat == Seats.end()) // no available seat return false; } else { seat = Seats.find(seatId); if (seat == Seats.end()) return false; if (!seat->second.IsEmpty()) { if (Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), seat->second.Passenger.Guid)) passenger->ExitVehicle(); seat->second.Passenger.Guid = 0; } ASSERT(seat->second.IsEmpty()); } #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_VEHICLES, "Unit %s enter vehicle entry %u id %u dbguid %u seat %d", unit->GetName().c_str(), _me->GetEntry(), _vehicleInfo->m_ID, _me->GetGUIDLow(), (int32)seat->first); #endif seat->second.Passenger.Guid = unit->GetGUID(); seat->second.Passenger.IsUnselectable = unit->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); if (seat->second.SeatInfo->CanEnterOrExit()) { ASSERT(_usableSeatNum); --_usableSeatNum; if (!_usableSeatNum) { if (_me->GetTypeId() == TYPEID_PLAYER) _me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE); else _me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); } } if (!_me->IsInWorld() || _me->IsDuringRemoveFromWorld()) return false; // Xinef: moved from unit.cpp, if aura passes seatId == -1 (choose automaticly) we wont get appropriate flags if (unit->GetTypeId() == TYPEID_PLAYER && !(seat->second.SeatInfo->m_flagsB & VEHICLE_SEAT_FLAG_B_KEEP_PET)) unit->ToPlayer()->UnsummonPetTemporaryIfAny(); if (seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_PASSENGER_NOT_SELECTABLE) unit->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); VehicleSeatEntry const* veSeat = seat->second.SeatInfo; unit->m_movementInfo.transport.pos.Relocate(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ); unit->m_movementInfo.transport.time = 0; unit->m_movementInfo.transport.seat = seat->first; unit->m_movementInfo.transport.guid = _me->GetGUID(); // xinef: removed retarded seat->first == 0 check... if (_me->GetTypeId() == TYPEID_UNIT && unit->GetTypeId() == TYPEID_PLAYER && seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL) { try { if (!_me->SetCharmedBy(unit, CHARM_TYPE_VEHICLE)) ASSERT(false); } catch (...) { sLog->outString("ZOMG! CRASH! Try-catch in Unit::SetCharmedBy()!"); sLog->outString("ZOMG! CRASH! Try-catch in Unit::SetCharmedBy(). not null: %u", _me ? 1 : 0); if (!_me) return false; sLog->outString("ZOMG! CRASH! Try-catch in Unit::SetCharmedBy(). Is: %u!", _me->IsInWorld()); sLog->outString("ZOMG! CRASH! Try-catch in Unit::SetCharmedBy(). Is2: %u!", _me->IsDuringRemoveFromWorld()); sLog->outString("ZOMG! CRASH! Try-catch in Unit::SetCharmedBy(). Unit %s!", _me->GetName().c_str()); sLog->outString("ZOMG! CRASH! Try-catch in Unit::SetCharmedBy(). typeid: %u!", _me->GetTypeId()); sLog->outString("ZOMG! CRASH! Try-catch in Unit::SetCharmedBy(). Unit %s, typeid: %u, in world: %u, duringremove: %u has wrong CharmType! Charmer %s, typeid: %u, in world: %u, duringremove: %u.", _me->GetName().c_str(), _me->GetTypeId(), _me->IsInWorld(), _me->IsDuringRemoveFromWorld(), unit->GetName().c_str(), unit->GetTypeId(), unit->IsInWorld(), unit->IsDuringRemoveFromWorld()); return false; } } if (_me->IsInWorld()) { unit->SendClearTarget(); // SMSG_BREAK_TARGET unit->SetControlled(true, UNIT_STATE_ROOT); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures) // also adds MOVEMENTFLAG_ROOT Movement::MoveSplineInit init(unit); init.DisableTransportPathTransformations(); init.MoveTo(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ); // Xinef: did not found anything unique in dbc, maybe missed something if (veSeat->m_ID == 3566 || veSeat->m_ID == 3567 || veSeat->m_ID == 3568 || veSeat->m_ID == 3570) { float x = veSeat->m_attachmentOffsetX, y = veSeat->m_attachmentOffsetY, z = veSeat->m_attachmentOffsetZ, o; CalculatePassengerPosition(x, y, z, &o); init.SetFacing(_me->GetAngle(x, y)); } else init.SetFacing(0.0f); init.SetTransportEnter(); init.Launch(); if (_me->GetTypeId() == TYPEID_UNIT) { if (_me->ToCreature()->IsAIEnabled) _me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, true); } } if (GetBase()->GetTypeId() == TYPEID_UNIT) sScriptMgr->OnAddPassenger(this, unit, seatId); // Remove parachute on vehicle switch unit->RemoveAurasDueToSpell(VEHICLE_SPELL_PARACHUTE); return true; }