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; }
static bool HandleWpShowCommand(ChatHandler* handler, const char* args) { if (!*args) return false; // first arg: on, off, first, last char* show_str = strtok((char*)args, " "); if (!show_str) return false; // second arg: GUID (optional, if a creature is selected) char* guid_str = strtok((char*)NULL, " "); uint32 pathid = 0; Creature* target = handler->getSelectedCreature(); // Did player provide a PathID? if (!guid_str) { // No PathID provided // -> Player must have selected a creature if (!target) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } pathid = target->GetWaypointPath(); } else { // PathID provided // Warn if player also selected a creature // -> Creature selection is ignored <- if (target) handler->SendSysMessage(LANG_WAYPOINT_CREATSELECTED); pathid = atoi((char*)guid_str); } std::string show = show_str; //handler->PSendSysMessage("wpshow - show: %s", show); // Show info for the selected waypoint if (show == "info") { // Check if the user did specify a visual waypoint if (!target || target->GetEntry() != VISUAL_WAYPOINT) { handler->PSendSysMessage(LANG_WAYPOINT_VP_SELECT); handler->SetSentErrorMessage(true); return false; } PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_ALL_BY_WPGUID); stmt->setUInt32(0, target->GetGUIDLow()); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { handler->SendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM); return true; } handler->SendSysMessage("|cff00ffffDEBUG: wp show info:|r"); do { Field* fields = result->Fetch(); pathid = fields[0].GetUInt32(); uint32 point = fields[1].GetUInt32(); uint32 delay = fields[2].GetUInt32(); uint32 flag = fields[3].GetUInt32(); uint32 ev_id = fields[4].GetUInt32(); uint32 ev_chance = fields[5].GetUInt32(); handler->PSendSysMessage("|cff00ff00Show info: for current point: |r|cff00ffff%u|r|cff00ff00, Path ID: |r|cff00ffff%u|r", point, pathid); handler->PSendSysMessage("|cff00ff00Show info: delay: |r|cff00ffff%u|r", delay); handler->PSendSysMessage("|cff00ff00Show info: Move flag: |r|cff00ffff%u|r", flag); handler->PSendSysMessage("|cff00ff00Show info: Waypoint event: |r|cff00ffff%u|r", ev_id); handler->PSendSysMessage("|cff00ff00Show info: Event chance: |r|cff00ffff%u|r", ev_chance); } while (result->NextRow()); return true; } if (show == "on") { PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_POS_BY_ID); stmt->setUInt32(0, pathid); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { handler->SendSysMessage("|cffff33ffPath no found.|r"); handler->SetSentErrorMessage(true); return false; } handler->PSendSysMessage("|cff00ff00DEBUG: wp on, PathID: |cff00ffff%u|r", pathid); // Delete all visuals for this NPC stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_WPGUID_BY_ID); stmt->setUInt32(0, pathid); PreparedQueryResult result2 = WorldDatabase.Query(stmt); if (result2) { bool hasError = false; do { Field* fields = result2->Fetch(); uint32 wpguid = fields[0].GetUInt32(); Creature* creature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpguid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); if (!creature) { handler->PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid); hasError = true; PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE); stmt->setUInt32(0, wpguid); WorldDatabase.Execute(stmt); } else { creature->CombatStop(); creature->DeleteFromDB(); creature->AddObjectToRemoveList(); } } while (result2->NextRow()); if (hasError) { handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR1); handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR2); handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR3); } } do { Field* fields = result->Fetch(); uint32 point = fields[0].GetUInt32(); float x = fields[1].GetFloat(); float y = fields[2].GetFloat(); float z = fields[3].GetFloat(); uint32 id = VISUAL_WAYPOINT; Player* chr = handler->GetSession()->GetPlayer(); Map* map = chr->GetMap(); float o = chr->GetOrientation(); Creature* wcreature = new Creature(); if (!wcreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMask(), id, 0, 0, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete wcreature; return false; } // Set "wpguid" column to the visual waypoint PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_WPGUID); stmt->setInt32(0, int32(wcreature->GetGUIDLow())); stmt->setUInt32(1, pathid); stmt->setUInt32(2, point); WorldDatabase.Execute(stmt); wcreature->CopyPhaseFrom(chr); wcreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); if (!wcreature->LoadCreatureFromDB(wcreature->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete wcreature; return false; } if (target) { wcreature->SetDisplayId(target->GetDisplayId()); wcreature->SetObjectScale(0.5f); wcreature->SetLevel(std::min<uint32>(point, STRONG_MAX_LEVEL)); } } while (result->NextRow()); handler->SendSysMessage("|cff00ff00Showing the current creature's path.|r"); return true; } if (show == "first") { handler->PSendSysMessage("|cff00ff00DEBUG: wp first, GUID: %u|r", pathid); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_POS_FIRST_BY_ID); stmt->setUInt32(0, pathid); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUND, pathid); handler->SetSentErrorMessage(true); return false; } Field* fields = result->Fetch(); float x = fields[0].GetFloat(); float y = fields[1].GetFloat(); float z = fields[2].GetFloat(); uint32 id = VISUAL_WAYPOINT; Player* chr = handler->GetSession()->GetPlayer(); float o = chr->GetOrientation(); Map* map = chr->GetMap(); Creature* creature = new Creature(); if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMask(), id, 0, 0, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete creature; return false; } creature->CopyPhaseFrom(chr); creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete creature; return false; } if (target) { creature->SetDisplayId(target->GetDisplayId()); creature->SetObjectScale(0.5f); } return true; } if (show == "last") { handler->PSendSysMessage("|cff00ff00DEBUG: wp last, PathID: |r|cff00ffff%u|r", pathid); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_POS_LAST_BY_ID); stmt->setUInt32(0, pathid); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, pathid); handler->SetSentErrorMessage(true); return false; } Field* fields = result->Fetch(); float x = fields[0].GetFloat(); float y = fields[1].GetFloat(); float z = fields[2].GetFloat(); float o = fields[3].GetFloat(); uint32 id = VISUAL_WAYPOINT; Player* chr = handler->GetSession()->GetPlayer(); Map* map = chr->GetMap(); Creature* creature = new Creature(); if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMask(), id, 0, 0, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); delete creature; return false; } creature->CopyPhaseFrom(chr); creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); delete creature; return false; } if (target) { creature->SetDisplayId(target->GetDisplayId()); creature->SetObjectScale(0.5f); } return true; } if (show == "off") { PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_BY_ID); stmt->setUInt32(0, 1); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { handler->SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND); handler->SetSentErrorMessage(true); return false; } bool hasError = false; do { Field* fields = result->Fetch(); uint32 guid = fields[0].GetUInt32(); Creature* creature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(guid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); if (!creature) { handler->PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid); hasError = true; PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE); stmt->setUInt32(0, guid); WorldDatabase.Execute(stmt); } else { creature->CombatStop(); creature->DeleteFromDB(); creature->AddObjectToRemoveList(); } } while (result->NextRow()); // set "wpguid" column to "empty" - no visual waypoint spawned stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_ALL_WPGUID); WorldDatabase.Execute(stmt); //WorldDatabase.PExecute("UPDATE creature_movement SET wpguid = '0' WHERE wpguid <> '0'"); if (hasError) { handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR1); handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR2); handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR3); } handler->SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED); return true; } handler->PSendSysMessage("|cffff33ffDEBUG: wpshow - no valid command found|r"); return true; }