void MovingObject::updatePositionInCell(uint64 parentId, const glm::vec3& newPosition) { uint64 oldParentId = this->getParentId(); if (oldParentId != parentId) { // We changed cell CellObject* cell = NULL; // Remove us. if (!this->getKnownPlayers()->empty()) { gMessageLib->broadcastContainmentMessage(this,oldParentId,0); } // only remove us from si, if we just entered the building if (oldParentId != 0) { // We are still inside. if ((cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(oldParentId)))) { cell->removeObject(this); } else { LOG(WARNING) << "Error removing " << this->getId() << " from cell " << this->getParentId(); } } else { // remove us from qt // We just entered a building. if (this->getSubZoneId()) { if (std::shared_ptr<QTRegion> region = gWorldManager->getQTRegion(this->getSubZoneId())) { this->setSubZoneId(0); region->mTree->removeObject(this); } } } // put us into new one if (!this->getKnownPlayers()->empty()) { gMessageLib->broadcastContainmentMessage(this,parentId,4); } if ((cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(parentId)))) { cell->addObjectSecure(this); } else { LOG(WARNING) << "Error adding " << this->getId() << " from cell " << this->getParentId(); } // update the player this->setParentId(parentId); } }
void SpatialIndexManager::createInWorld(PlayerObject* player) { //just create in the SI - it will keep track of nearby players this->_AddObject(player); //are we in a cell? otherwise bail out if(player->getParentId() == 0) { return; } CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(player->getParentId())); if(!cell) { assert(false && "cannot cast cell ???? "); return; } BuildingObject* building = dynamic_cast<BuildingObject*>(gWorldManager->getObjectById(cell->getParentId())); if(!building) { assert(false && "cannot cast building ???? "); return; } //we *should* already be registered as known watcher to the building //add the Creature to the cell we are in cell->addObjectSecure(player); //iterate through all the cells and add the player as listener CellObjectList::iterator cellIt = building->getCellList()->begin(); CellObjectList* cell_list = building->getCellList(); std::for_each(cell_list->begin(), cell_list->end(), [player] (CellObject* cell) { gContainerManager->registerPlayerToContainer(cell, player); }); }
void SpatialIndexManager::createInWorld(CreatureObject* creature) { this->_AddObject(creature); //are we in a cell? otherwise bail out if(creature->getParentId() == 0) { return; } CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(creature->getParentId())); if(!cell) { assert(false && "SpatialIndexManager::createInWorld cannot cast cell ???? "); return; } BuildingObject* building = dynamic_cast<BuildingObject*>(gWorldManager->getObjectById(cell->getParentId())); if(!building) { assert(false && "SpatialIndexManager::createInWorld cannot cast building ???? "); return; } //add the Creature to the cell we are in cell->addObjectSecure(creature); }
void CellFactory::handleObjectReady(Object* object,DispatchClient* client) { InLoadingContainer* ilc = _getObject(object->getParentId()); if (! ilc) {//Crashbug fix: http://paste.swganh.org/viewp.php?id=20100627114151-8f7df7f74013af71c0d0b00bc240770d gLogger->log(LogManager::WARNING,"CellFactory::handleObjectReady could not locate ILC for objectParentId:%I64u",object->getParentId()); return; } CellObject* cell = dynamic_cast<CellObject*>(ilc->mObject); gWorldManager->addObject(object,true); switch(object->getType()) { case ObjType_NPC: case ObjType_Creature: { CreatureObject* creature = dynamic_cast<CreatureObject*>(object); if(creature->getCreoGroup() == CreoGroup_Shuttle) gWorldManager->addShuttle(dynamic_cast<Shuttle*>(creature)); } break; case ObjType_Tangible: { PlayerStructureTerminal* terminal = dynamic_cast<PlayerStructureTerminal*>(object); if(terminal) { terminal->setStructure(cell->getParentId()); } } break; case ObjType_Building: case ObjType_Cell: case ObjType_DraftSchematic: case ObjType_Structure: case ObjType_Intangible: case ObjType_Lair: case ObjType_Mission: case ObjType_None: case ObjType_NonPersistant: case ObjType_Player: case ObjType_Region: case ObjType_Waypoint: default: break; } cell->addObjectSecure(object); if(cell->getLoadCount() == cell->getObjects()->size()) { if(!(_removeFromObjectLoadMap(cell->getId()))) gLogger->log(LogManager::DEBUG,"CellFactory: Failed removing object from loadmap"); ilc->mOfCallback->handleObjectReady(cell,ilc->mClient); mILCPool.free(ilc); } }
void ElevatorTerminal::handleObjectMenuSelect(uint8 messageType,Object* srcObject) { PlayerObject* playerObject = dynamic_cast<PlayerObject*>(srcObject); if(!playerObject || !playerObject->isConnected() || playerObject->getSamplingState() || playerObject->isIncapacitated() || playerObject->isDead()) { return; } if(messageType == radId_elevatorUp) { gMessageLib->sendPlayClientEffectObjectMessage(gWorldManager->getClientEffect(mEffectUp),"",playerObject); // remove player from current position, elevators can only be inside CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(playerObject->getParentId())); if(cell) { cell->removeObject(playerObject); } else { gLogger->logMsgF("could not find cell %"PRIu64"",MSG_HIGH,playerObject->getParentId()); } // put him into new one playerObject->mDirection = mDstDirUp; playerObject->mPosition = mDstPosUp; playerObject->setParentId(mDstCellUp); cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(mDstCellUp)); if(cell) { cell->addObjectSecure(playerObject); } else { gLogger->logMsgF("could not find cell %"PRIu64"",MSG_HIGH,mDstCellUp); } gMessageLib->sendDataTransformWithParent(playerObject); } else if(messageType == radId_elevatorDown) { gMessageLib->sendPlayClientEffectObjectMessage(gWorldManager->getClientEffect(mEffectDown),"",playerObject); // remove player from current position, elevators can only be inside CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(playerObject->getParentId())); if(cell) { cell->removeObject(playerObject); } else { gLogger->logMsgF("could not find cell %"PRIu64"",MSG_HIGH,playerObject->getParentId()); } // put him into new one playerObject->mDirection = mDstDirDown; playerObject->mPosition = mDstPosDown; playerObject->setParentId(mDstCellDown); cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(mDstCellDown)); if(cell) { cell->addObjectSecure(playerObject); } else { gLogger->logMsgF("could not find cell %"PRIu64"",MSG_HIGH,mDstCellDown); } gMessageLib->sendDataTransformWithParent(playerObject); } else { gLogger->logMsgF("ElevatorTerminal: Unhandled MenuSelect: %u",MSG_HIGH,messageType); } }
void ObjectController::_handleTransferItemMisc(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties) { //we need to make sure that ONLY equipped items are contained by the player //all other items are contained by the inventory!!!!!!!! PlayerObject* playerObject = dynamic_cast<PlayerObject*>(mObject); Object* itemObject = gWorldManager->getObjectById(targetId); Inventory* inventory = dynamic_cast<Inventory*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory)); BString dataStr; uint64 targetContainerId; uint32 linkType; float x,y,z; CellObject* cell; message->getStringUnicode16(dataStr); if(swscanf(dataStr.getUnicode16(),L"%" WidePRIu64 L" %u %f %f %f",&targetContainerId,&linkType,&x,&y,&z) != 5) { DLOG(info) << "ObjController::_handleTransferItemMisc: Error in parameters"; return; } if (!itemObject) { DLOG(warning) << "ObjController::_handleTransferItemMisc: No Object to transfer :("; return; } TangibleObject* tangible = dynamic_cast<TangibleObject*>(itemObject); if(!tangible) { //no tagible - get out of here DLOG(warning) << "ObjController::_handleTransferItemMisc: No tangible to transfer :("; return; } //get our containers Object* newContainer = gWorldManager->getObjectById(targetContainerId); Object* oldContainer = gWorldManager->getObjectById(tangible->getParentId()); DLOG(info) << "ObjController::_handleTransferItemMisc: parameters"; DLOG(info) << "ObjController::_handleTransferItemMisc: newcontainer : " << targetContainerId; DLOG(info) << "ObjController::_handleTransferItemMisc: oldcontainer : " << tangible->getParentId(); DLOG(info) << "ObjController::_handleTransferItemMisc: linktype : " << linkType; // We may want to transfer other things than items...basically tangibleObjects! // resourcecontainers / factory crates // first check whether its an instrument with persistant copy - thats a special case! Item* item = dynamic_cast<Item*>(itemObject); if (item) { //check if its only temporarily placed if(item->getItemFamily() == ItemFamily_Instrument) { if(item->getPersistantCopy()) { // gMessageLib->sendSystemMessage(playerObject,L"you cannot pick this up"); // You bet, I can! Remove the temp instrument from the world. // Do I have access to this instrument? if (item->getOwner() == playerObject->getId()) { playerObject->getController()->destroyObject(targetId); } return; } } } // A FYI: When we drop items, we use player pos. itemObject->mPosition = glm::vec3(x,y,z); if (!targetContainerId) { DLOG(info) << "ObjController::_handleTransferItemMisc:TargetContainer is 0 :("; //return; } //ok how to tackle this ... : //basically I want to use ObjectContainer as standard access point for item handling! //so far we have different accesses for Objects on the player and for the inventory and for ContainerObjects and for cells ... //lets begin by getting the target Object if(!checkTargetContainer(targetContainerId,itemObject)) { DLOG(info) << "ObjController::_handleTransferItemMisc:TargetContainer is not valid :("; return; } if(!checkContainingContainer(tangible->getParentId(), playerObject->getId())) { DLOG(info) << "ObjController::_handleTransferItemMisc:ContainingContainer is not allowing the transfer :("; return; } // Remove the object from whatever contains it. if(!removeFromContainer(targetContainerId, targetId)) { DLOG(info) << "ObjectController::_handleTransferItemMisc: removeFromContainer failed :( this might be caused by looting a corpse though"; return; } //we need to destroy the old radial ... our item now gets a new one //delete(itemObject->getRadialMenu()); itemObject->ResetRadialMenu(); itemObject->setParentId(targetContainerId); //Now update the registered watchers!! gContainerManager->updateObjectPlayerRegistrations(newContainer, oldContainer, tangible, linkType); //now go and move it to wherever it belongs cell = dynamic_cast<CellObject*>(newContainer); if (cell) { // drop in a cell //special case temp instrument if (item&&item->getItemFamily() == ItemFamily_Instrument) { if (playerObject->getPlacedInstrumentId()) { // We do have a placed instrument. uint32 instrumentType = item->getItemType(); if ((instrumentType == ItemType_Nalargon) || (instrumentType == ItemType_omni_box) || (instrumentType == ItemType_nalargon_max_reebo)) { // We are about to drop the real thing, remove any copied instrument. // item->setOwner(playerObject->getId(); playerObject->getController()->destroyObject(playerObject->getPlacedInstrumentId()); } } } itemObject->mPosition = playerObject->mPosition; //do the db update manually because of the position - unless we get an automated position save in itemObject->setParentId(targetContainerId); ResourceContainer* rc = dynamic_cast<ResourceContainer*>(itemObject); if(rc) mDatabase->executeSqlAsync(0,0,"UPDATE %s.resource_containers SET parent_id ='%I64u', oX='%f', oY='%f', oZ='%f', oW='%f', x='%f', y='%f', z='%f' WHERE id='%I64u'",mDatabase->galaxy(),itemObject->getParentId(), itemObject->mDirection.x, itemObject->mDirection.y, itemObject->mDirection.z, itemObject->mDirection.w, itemObject->mPosition.x, itemObject->mPosition.y, itemObject->mPosition.z, itemObject->getId()); else mDatabase->executeSqlAsync(0,0,"UPDATE %s.items SET parent_id ='%I64u', oX='%f', oY='%f', oZ='%f', oW='%f', x='%f', y='%f', z='%f' WHERE id='%I64u'",mDatabase->galaxy(),itemObject->getParentId(), itemObject->mDirection.x, itemObject->mDirection.y, itemObject->mDirection.z, itemObject->mDirection.w, itemObject->mPosition.x, itemObject->mPosition.y, itemObject->mPosition.z, itemObject->getId()); cell->addObjectSecure(itemObject); gMessageLib->sendDataTransformWithParent053(itemObject); itemObject->updateWorldPosition(); return; } PlayerObject* player = dynamic_cast<PlayerObject*>(newContainer); if(player) { //equip / unequip handles the db side, too if(!player->getEquipManager()->EquipItem(item)) { LOG(warning) << "ObjectController::_handleTransferItemMisc: Error equipping " << item->getId(); //panik!!!!!! } itemObject->setParentIdIncDB(newContainer->getId()); return; } //***************************************************************** //All special cases have been handled - now its just our generic ObjectContainer Type //some other container ... hopper backpack chest inventory etc if(newContainer) { newContainer->addObjectSecure(itemObject); itemObject->setParentIdIncDB(newContainer->getId()); return; } }
bool WorldManager::addObject(Object* object,bool manual) { uint64 key = object->getId(); //make sure objects arnt added several times!!!! if(getObjectById(key)) { gLogger->logMsgF("WorldManager::addObject Object already existant added several times or ID messup ???",MSG_HIGH); return false; } mObjectMap.insert(key,object); // if we want to set the parent manually or the object is from the snapshots and not a building, return if(manual) { return true; } #if defined(_MSC_VER) if(object->getId() < 0x0000000100000000 && object->getType() != ObjType_Building) #else if(object->getId() < 0x0000000100000000LLU && object->getType() != ObjType_Building) #endif { // check if a crafting station - in that case add Item* item = dynamic_cast<Item*> (object); if(item) { if(!(item->getItemFamily() == ItemFamily_CraftingStations)) return true; } else { return true; } } switch(object->getType()) { // player, when a player enters a planet case ObjType_Player: { PlayerObject* player = dynamic_cast<PlayerObject*>(object); gLogger->logMsgF("New Player: %"PRIu64", Total Players on zone : %i",MSG_NORMAL,player->getId(),(getPlayerAccMap())->size() + 1); // insert into the player map mPlayerAccMap.insert(std::make_pair(player->getAccountId(),player)); // insert into cell if(player->getParentId()) { player->setSubZoneId(0); if(CellObject* cell = dynamic_cast<CellObject*>(getObjectById(player->getParentId()))) { cell->addObjectSecure(player); } else { gLogger->logMsgF("WorldManager::addObject: couldn't find cell %"PRIu64"",MSG_HIGH,player->getParentId()); } } // query the rtree for the qt region we are in else { if(QTRegion* region = mSpatialIndex->getQTRegion(player->mPosition.x,player->mPosition.z)) { player->setSubZoneId((uint32)region->getId()); region->mTree->addObject(player); } else { // we should never get here ! gLogger->logMsg("WorldManager::addObject: could not find zone region in map"); return false; } } // initialize initObjectsInRange(player); gMessageLib->sendCreatePlayer(player,player); // add ham to regeneration scheduler player->getHam()->updateRegenRates(); // ERU: Note sure if this is needed here. player->getHam()->checkForRegen(); // onPlayerEntered event, notify scripts string params; params.setLength(sprintf(params.getAnsi(),"%s %s %u",getPlanetNameThis(),player->getFirstName().getAnsi(),static_cast<uint32>(mPlayerAccMap.size()))); mWorldScriptsListener.handleScriptEvent("onPlayerEntered",params); // Start player world position update. Used when player don't get any events from client (player not moving). // addPlayerMovementUpdateTime(player, 1000); } break; case ObjType_Structure: { // HarvesterObject* harvester = dynamic_cast<HarvesterObject*>(object); mStructureList.push_back(object->getId()); mSpatialIndex->InsertPoint(key,object->mPosition.x,object->mPosition.z); } break; case ObjType_Building: { mStructureList.push_back(object->getId()); BuildingObject* building = dynamic_cast<BuildingObject*>(object); mSpatialIndex->InsertRegion(key,building->mPosition.x,building->mPosition.z,building->getWidth(),building->getHeight()); } break; case ObjType_Tangible: { uint64 parentId = object->getParentId(); if(parentId == 0) { mSpatialIndex->InsertPoint(key,object->mPosition.x,object->mPosition.z); } else { CellObject* cell = dynamic_cast<CellObject*>(getObjectById(parentId)); if(cell) cell->addObjectSecure(object); else gLogger->logMsgF("WorldManager::addObject couldn't find cell %"PRIu64"",MSG_NORMAL,parentId); } } break; // TODO: add moving creatures to qtregions case ObjType_NPC: case ObjType_Creature: case ObjType_Lair: { CreatureObject* creature = dynamic_cast<CreatureObject*>(object); if(creature->getCreoGroup() == CreoGroup_Shuttle) mShuttleList.push_back(dynamic_cast<Shuttle*>(creature)); uint64 parentId = creature->getParentId(); if(parentId) { CellObject* cell = dynamic_cast<CellObject*>(getObjectById(parentId)); if(cell) cell->addObjectSecure(creature); else gLogger->logMsgF("WorldManager::addObject: couldn't find cell %"PRIu64"",MSG_HIGH,parentId); } else { switch(creature->getCreoGroup()) { // moving creature, add to QT case CreoGroup_Vehicle : { if(QTRegion* region = mSpatialIndex->getQTRegion(creature->mPosition.x,creature->mPosition.z)) { creature->setSubZoneId((uint32)region->getId()); region->mTree->addObject(creature); } else { gLogger->logMsg("WorldManager::addObject: could not find zone region in map for creature"); return false; } } break; // still creature, add to SI default : { mSpatialIndex->InsertPoint(key,creature->mPosition.x,creature->mPosition.z); } } } } break; case ObjType_Region: { RegionObject* region = dynamic_cast<RegionObject*>(object); mRegionMap.insert(std::make_pair(key,region)); mSpatialIndex->InsertRegion(key,region->mPosition.x,region->mPosition.z,region->getWidth(),region->getHeight()); if(region->getActive()) addActiveRegion(region); } break; case ObjType_Intangible: { gLogger->logMsgF("Object of type ObjType_Intangible UNHANDLED in WorldManager::addObject:",MSG_HIGH); } break; default: { gLogger->logMsgF("Unhandled ObjectType in WorldManager::addObject: PRId32",MSG_HIGH,object->getType()); // Please, when adding new stufff, at least take the time to add a stub for that type. // Better fail always, than have random crashes. assert(false && "WorldManager::addObject Unhandled ObjectType"); } break; } return true; }
void ObjectController::handleDataTransformWithParent(Message* message,bool inRangeUpdate) { // FIXME: for now assume we only get messages from players PlayerObject* player = dynamic_cast<PlayerObject*>(mObject); glm::vec3 pos; glm::quat dir; uint32 inMoveCount; uint32 tickCount; uint64 parentId; float speed; bool updateAll = false; // get tick and move counters tickCount = message->getUint32(); inMoveCount = message->getUint32(); // only process if its in sequence if (player->getInMoveCount() <= inMoveCount) { uint64 oldParentId = player->getParentId(); //uint32 ticks = tickCount - player->getClientTickCount(); // update tick and move counters player->setClientTickCount(tickCount); player->setInMoveCount(inMoveCount); // get new direction, position, parent and speed parentId = message->getUint64(); dir.x = message->getFloat(); dir.y = message->getFloat(); dir.z = message->getFloat(); dir.w = message->getFloat(); pos.x = message->getFloat(); pos.y = message->getFloat(); pos.z = message->getFloat(); speed = message->getFloat(); // gLogger->logMsgF("Position inside = %f, %f, %f",MSG_NORMAL, pos.x, pos.y, pos.z); // gLogger->logMsgF("Direction = %f, %f, %f, %f",MSG_NORMAL, dir.x, dir.y, dir.z, dir.w); // stop entertaining, if we were if(player->getPerformingState() != PlayerPerformance_None && player->getPosture() != CreaturePosture_SkillAnimating) { gEntertainerManager->stopEntertaining(player); } // if we changed cell if (oldParentId != parentId) { CellObject* cell = NULL; // gLogger->logMsgF("We changed cell from (%"PRIu64") to (%"PRIu64")",MSG_NORMAL, oldParentId, parentId); // Remove us from whatever we where in before. // (4 for add and 0 for remove) gMessageLib->broadcastContainmentMessage(player->getId(),oldParentId,0,player); // only remove us from si, if we just entered the building if (oldParentId != 0) { if((cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(oldParentId)))) { cell->removeObject(player); // Done above.. gMessageLib->broadcastContainmentMessage(player->getId(),parentId,4,player); } else { gLogger->logMsgF("Error removing %"PRIu64" from cell(%"PRIu64")",MSG_NORMAL,player->getId(),oldParentId); } } else { updateAll = true; // We just entered the building. // remove us from qt if(player->getSubZoneId()) { if(QTRegion* region = gWorldManager->getQTRegion(player->getSubZoneId())) { player->setSubZoneId(0); region->mTree->removeObject(player); //If our player is mounted lets update his mount aswell if(player->checkIfMounted() && player->getMount()) { player->getMount()->setSubZoneId(0); region->mTree->removeObject(player->getMount()); //Can't ride into a building with a mount! :-p //However, its easy to do so we have handling incase the client is tricked. // the vehicle is the INTANGIBLE Datapad Controller // the *vehicle* itself is the BODY if(Vehicle* datapad_pet = dynamic_cast<Vehicle*>(gWorldManager->getObjectById(player->getMount()->getPetController()))) { datapad_pet->dismountPlayer(); datapad_pet->store(); } } } } } // put us into new one gMessageLib->broadcastContainmentMessage(player->getId(),parentId,4,player); if((cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(parentId)))) { cell->addObjectSecure(player); // Inform tutorial about cell change. if (gWorldConfig->isTutorial()) { player->getTutorial()->setCellId(parentId); // gLogger->logMsgF("handleDataTransformWithParent: Adding %"PRIu64" to cell(%"PRIu64")",MSG_NORMAL,player->getId(),parentId); } } else { gLogger->logMsgF("Error adding %"PRIu64" to cell(%"PRIu64")",MSG_NORMAL,player->getId(),parentId); } } // update the player player->setParentId(parentId); player->mDirection = dir; player->mPosition = pos; player->setCurrentSpeed(speed); // destroy the instanced instrument if out of range if (player->getPlacedInstrumentId()) { if (!gWorldManager->objectsInRange(player->getId(), player->getPlacedInstrumentId(), 5.0)) { if (Item* item = dynamic_cast<Item*>(gWorldManager->getObjectById(player->getPlacedInstrumentId()))) { destroyObject(item->getId()); } } } // Terminate active conversation with npc if to far away (trainers only so far). ActiveConversation* ac = gConversationManager->getActiveConversation(player->getId()); if (ac != NULL) { // We do have a npc conversation going. if (!gWorldManager->objectsInRange(player->getId(), (ac->getNpc())->getId(), 11.0)) { // Terminate conversation, since we are out of range. gMessageLib->sendSystemMessage(player,L"","system_msg","out_of_range"); gConversationManager->stopConversation(player, true); // We will get the current dialog text in a chat bubble, only seen by me. Impressive :) } } if (updateAll) { // Update our world. playerWorldUpdate(true); // Speed up the timed update, if any pending. gWorldManager->addPlayerMovementUpdateTime(player, 250); } else { if (!gWorldConfig->isInstance()) { // send out updates gMessageLib->sendUpdateTransformMessageWithParent(player); } else { // send out position updates to known players in group or self only gMessageLib->sendUpdateTransformMessageWithParent(player, player); } } } }