Creature* Transport::AddNPCPassenger(uint32 entry, float x, float y, float z, float o, uint32 anim) { Map* map = GetMap(); //make it world object so it will not be unloaded with grid auto const creature = new Creature(true); if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, GetPhaseMask(), entry, 0, GetGOInfo()->faction, 0, 0, 0, 0)) { delete creature; return nullptr; } creature->SetTransport(this); creature->m_movementInfo.t_pos.Relocate(x, y, z, o); if (anim) creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, anim); creature->Relocate( GetPositionX() + (x * std::cos(GetOrientation()) + y * std::sin(GetOrientation() + float(M_PI))), GetPositionY() + (y * std::cos(GetOrientation()) + x * std::sin(GetOrientation())), z + GetPositionZ(), o + GetOrientation()); creature->SetHomePosition(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation()); creature->SetTransportHomePosition(creature->m_movementInfo.t_pos); if (!creature->IsPositionValid()) { TC_LOG_ERROR("entities.transport", "Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)", creature->GetGUIDLow(), creature->GetEntry(), creature->GetPositionX(), creature->GetPositionY()); delete creature; return nullptr; } map->AddToMap(creature); m_NPCPassengerSet.insert(creature); creature->setActive(true); sScriptMgr->OnAddCreaturePassenger(this, creature); return creature; }
bool Vehicle::LoadFromDB(uint32 guid, Map *map) { CreatureData const* data = objmgr.GetCreatureData(guid); if(!data) { sLog.outErrorDb("Creature (GUID: %u) not found in table `creature`, can't load. ",guid); return false; } uint32 id = 0; if(const CreatureInfo *cInfo = objmgr.GetCreatureTemplate(data->id)) id = cInfo->VehicleId; if(!id || !sVehicleStore.LookupEntry(id)) return false; m_DBTableGuid = guid; if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_VEHICLE); uint16 team = 0; if(!Create(guid,map,data->phaseMask,data->id,id,team,data->posX,data->posY,data->posZ,data->orientation,data)) return false; //We should set first home position, because then AI calls home movement SetHomePosition(data->posX,data->posY,data->posZ,data->orientation); m_respawnradius = data->spawndist; m_respawnDelay = data->spawntimesecs; m_isDeadByDefault = data->is_dead; m_deathState = m_isDeadByDefault ? DEAD : ALIVE; m_respawnTime = objmgr.GetCreatureRespawnTime(m_DBTableGuid,GetInstanceId()); if(m_respawnTime > time(NULL)) // not ready to respawn { m_deathState = DEAD; if(canFly()) { float tz = GetMap()->GetHeight(data->posX,data->posY,data->posZ,false); if(data->posZ - tz > 0.1) Relocate(data->posX,data->posY,tz); } } else if(m_respawnTime) // respawn time set but expired { m_respawnTime = 0; objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0); } uint32 curhealth = data->curhealth; if(curhealth) { curhealth = uint32(curhealth*_GetHealthMod(GetCreatureInfo()->rank)); if(curhealth < 1) curhealth = 1; } SetHealth(m_deathState == ALIVE ? curhealth : 0); SetPower(POWER_MANA,data->curmana); // checked at creature_template loading m_defaultMovementType = MovementGeneratorType(data->movementType); m_creatureData = data; return true; }