void SpatialIndexManager::initObjectsInRange(PlayerObject* player) { uint64_t player_id = player->getParentId(); if (player_id == 0) { return; } Object* tmp = gWorldManager->getObjectById(player_id); if (tmp->getType() != ObjType_Cell) { return; } CellObject* cell = static_cast<CellObject*>(tmp); tmp = gWorldManager->getObjectById(cell->getParentId()); if (tmp->getType() != ObjType_Building) { return; } BuildingObject* building = static_cast<BuildingObject*>(tmp); ObjectList children = building->getAllCellChilds(); std::for_each(children.begin(), children.end(), [this, player] (Object* cell_child) { if (cell_child->getType() != ObjType_Tangible) { return; } sendCreateObject(cell_child, player, true); }); }
//============================================================================================================ // the idea is that the container holding our new item might be held by a container, too // should this happen, we need to find the main container to determin what kind of creates to send to our player/s // we will iterate through the parentObjects until the parent is either a player (item has been equipped) or in the inventory or ) // or a cell or a factory uint64 SpatialIndexManager::getObjectMainParent(Object* object) { uint64 parentID = object->getParentId(); // hack ourselves a player - it is not possible to get an inventory otherwise because // inventories are not part of the WorldObjectMap ... which really gets cumbersom (resolved with newest trunc) PlayerObject* player = dynamic_cast<PlayerObject*>(gWorldManager->getObjectById(parentID-1)); if(!player) { // the backpack might have been equipped ? // this way we have of course a player directly PlayerObject* player = dynamic_cast<PlayerObject*>(gWorldManager->getObjectById(parentID)); if(!player) { CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(parentID)); if(!cell) { CellObject* cell = dynamic_cast<CellObject*>(object); if(cell) { return parentID; } FactoryObject* factory = dynamic_cast<FactoryObject*>(gWorldManager->getObjectById(parentID)); if(!factory) { Object* ob = dynamic_cast<Object*>(gWorldManager->getObjectById(parentID)); if(!ob) { return 0; } parentID = getObjectMainParent(ob); } } else { //return the house return cell->getParentId(); } } } else { //its in the inventory return parentID; //Inventory is parent ID +1 - we cannot find inventories in the worldObjectMap but we can find players there //so we have to go this way //before changing this we need to settle the dispute what objects are part of the world objectmap and need to discuss objectownership //Eru is right in saying that we cant have two object owners (well we can but obviously we shouldnt) } return parentID; }
//====================================================================================================================== // // rotates an item // void ObjectController::HandleRotateFurniture_( uint64 targetId, Message* message, ObjectControllerCmdProperties* cmdProperties) { CreatureObject* creature = dynamic_cast<CreatureObject*>(mObject); PlayerObject* player = creature->GetGhost(); if (!player) { assert(false && "ObjectController::HandleRotateFurniture_ Player not found"); return; } // Verify that there was a target passed. if (!targetId) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "rotate_what"), player); return; } Object* object = gWorldManager->getObjectById(targetId); if(!object) { assert(false && "ObjectController::HandleRotateFurniture_ item not found"); return; } // Verify that the item and player are in the same structure. CellObject* playerCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(player->getParentId())); if(!playerCell) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "rotate_what"), player); return; } uint64 playerStructure = playerCell->getParentId(); CellObject* objectCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(object->getParentId())); if(!objectCell) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "rotate_what"), player); return; } uint64 objectStructure = objectCell->getParentId(); if (objectStructure != playerStructure) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "rotate_what"), player); return; } // Verify that the player has appropriate rights on this structure. if (playerCell) { if (BuildingObject* building = dynamic_cast<BuildingObject*>(gWorldManager->getObjectById(playerCell->getParentId()))) { if (!building->getAdminData().check_admin(player->getId())) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "admin_move_only"), player); return; } } else { assert(false && "ObjectController::HandleRotateFurniture_ no structure"); return; } } else { //were just outside?? return; } // Read the message out of the packet. BString tmp; message->getStringUnicode16(tmp); // If the string has no length the message is ill-formatted, send the // proper format to the client. if (!tmp.getLength()) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "format_rotatefurniture_degrees"), player); return; } // Convert the string to an ansi string for ease with the regex. tmp.convert(BSTRType_ANSI); std::string input_string(tmp.getAnsi()); static const regex pattern("(right|left) ([0-9]+)"); smatch result; regex_search(input_string, result, pattern); // If the pattern doesn't match all elements then send the proper format // to the client. if (result.length() < 2) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "format_rotatefurniture_degrees"), player); return; } // Gather the results of the pattern for validation and use. std::string direction(result[1]); float degrees = boost::lexical_cast<float>(result[2]); // If the the specified amount is not within the valid range notify the client. if (degrees < 1.0f || degrees > 180.0f) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "rotate_params"), player); return; } // Rotate by the necessary amount. if (direction.compare("left") == 0) { object->rotateLeft(degrees); } else { object->rotateRight(degrees); } // Update the world with the changes. gMessageLib->sendDataTransformWithParent053(object); object->updateWorldPosition(); }
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 LOG(warning) << "Could not locate InLoadingContainer for object parent id [" << 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; } auto permissions_objects_ = gObjectManager->GetPermissionsMap(); object->SetPermissions(permissions_objects_.find(swganh::object::DEFAULT_PERMISSION)->second.get());//CREATURE_PERMISSION gObjectManager->LoadSlotsForObject(object); cell->InitializeObject(object); cell->incLoad(); //LOG(info) << "cellFactory::handleObjectReady -> cell load stuff" << object->getId() << "for " << cell->getId(); //LOG(info) << "loadcount : " << cell->getLoadCount() << " : count : " << cell->getLoad(); if(cell->getLoadCount() == cell->getLoad()) { //LOG(info) << "cellFactory::handleObjectReady -> cell done " << cell->getId(); if(!(_removeFromObjectLoadMap(cell->getId()))) LOG(warning) << "Failed removing object from loadmap"; ilc->mOfCallback->handleObjectReady(cell,ilc->mClient); mILCPool.free(ilc); } }
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); } }
//====================================================================================================================== // // moves an item // void ObjectController::HandleItemMoveDown_( uint64 targetId, Message* message, ObjectControllerCmdProperties* cmdProperties) { PlayerObject* player = dynamic_cast<PlayerObject*>(mObject); if (!player) { assert(false && "ObjectController::HandleItemMoveDown_ Player not found"); return; } // Verify that there was a target passed. if (!targetId) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "move_what"), player); return; } Object* object = gWorldManager->getObjectById(targetId); if(!object) { assert(false && "ObjectController::HandleItemMoveDown_ item not found"); return; } // Verify that the item and player are in the same structure. // Verify that the item and player are in the same structure. CellObject* playerCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(player->getParentId())); if(!playerCell) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "move_what"), player); return; } uint64 playerStructure = playerCell->getParentId(); CellObject* objectCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(object->getParentId())); if(!objectCell) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "move_what"), player); return; } uint64 objectStructure = objectCell->getParentId(); if (objectStructure != playerStructure) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "move_what"), player); return; } // Verify that the player has appropriate rights on this structure. if (playerCell) { if (BuildingObject* building = dynamic_cast<BuildingObject*>(gWorldManager->getObjectById(playerCell->getParentId()))) { if (!building->hasAdminRights(player->getId())) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "admin_move_only"), player); return; } } else { assert(false && "ObjectController::HandleItemMoveDown_ no structure"); return; } } else { //were just outside?? return; } object->mPosition.y -= MOVE_INCREMENT; gMessageLib->sendDataTransformWithParent053(object); object->updateWorldPosition(); }
void ObjectController::handleObjectMenuRequest(Message* message) { //for ever item where we request a radial the client starts by displaying a radial on his own and additionally sends a //objectMenuRequest to the server //The server then either just resends the radial as send by the client or adds / modifies options on his own //this is why sometimes when lag is involved it takes some time for all options to display PlayerObject* playerObject = dynamic_cast<PlayerObject*>(mObject); message->getUint32(); // unknown uint64 requestedObjectId = message->getUint64(); message->getUint64(); // player id again ? Object* requestedObject = gWorldManager->getObjectById(requestedObjectId); uint32 itemCount = message->getUint32(); BString extendedDescription; MenuItemList menuItemList; MenuItem* menuItem; for(uint32 i = 0; i < itemCount; i++) { menuItem = new(MenuItem); menuItem->sItem = message->getUint8(); // item nr menuItem->sSubMenu = message->getUint8(); // submenu flag menuItem->sIdentifier = message->getUint8(); // item identifier menuItem->sOption = message->getUint8(); // extended option message->getStringUnicode16(extendedDescription); menuItemList.push_back(menuItem); } uint8 responseNr = message->getUint8(); if(!requestedObject) { if(playerObject->isConnected()) gMessageLib->sendEmptyObjectMenuResponse(requestedObjectId,playerObject,responseNr,menuItemList); //the list is cleared and items are destroyed in the message lib //for the default response return; } requestedObject->setMenuList(&menuItemList); //are we an item dropped in a structure awaiting to be moved or picked u`p? //just implement this virtual function for items as we need just one central point instead //of the same code over and over for all items CellObject* itemCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(requestedObject->getParentId())); Item* item = dynamic_cast<Item*>(requestedObject); ResourceContainer* rC = dynamic_cast<ResourceContainer*>(requestedObject); TangibleObject* tO = dynamic_cast<TangibleObject*>(requestedObject); //only display that menu when *we* and the item are in the same structure if((rC || item) && itemCell && (!tO->getStatic())) { CellObject* playerCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(playerObject->getParentId())); if(playerCell && (playerCell->getParentId() == itemCell->getParentId())) { PlayerStructure* pS = dynamic_cast<PlayerStructure*>(gWorldManager->getObjectById(playerCell->getParentId())); if(pS) requestedObject->prepareCustomRadialMenuInCell(playerObject,static_cast<uint8>(itemCount)); } } /* if(rc && requestedObject->getParentId()) { if(CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(requestedObject->getParentId()))) { requestedObject->prepareCustomRadialMenuInCell(playerObject,static_cast<uint8>(itemCount)); } } */ //delete the radials after every use or provide every object with set rules when to delete it ? if(!requestedObject->getRadialMenu()) requestedObject->prepareCustomRadialMenu(playerObject,static_cast<uint8>(itemCount)); if (requestedObject->getRadialMenu()) { if(playerObject->isConnected()) { gMessageLib->sendObjectMenuResponse(requestedObject,playerObject,responseNr); } //they only reset if the objects virtual function does it //by default it stays requestedObject->ResetRadialMenu(); //the radial menu is supposed to be an intelligent pointer deleting itself when no reference is left //however during runtime the item always references the radialmenu that was generated for it on the first call. //when the circumstances of the item change we need to delete the pointer and thus force it to generate a new radial } else { // putting this for static objects/objects that are not known by the server yet // send a default menu,so client stops flooding us with requests //empty might just mean that the clients radial is sufficient if(playerObject->isConnected()) gMessageLib->sendEmptyObjectMenuResponse(requestedObjectId,playerObject,responseNr,menuItemList); //the list is cleared and items are destroyes in the message lib //for the default response } //we need to clear that if the messagelib wont clear it //still want to use it for the player radials at some point for(MenuItemList::iterator it=menuItemList.begin(); it != menuItemList.end(); it++) delete (*it); menuItemList.clear(); }
void WorldManager::initObjectsInRange(PlayerObject* playerObject) { float viewingRange = _GetMessageHeapLoadViewingRange(); //if we are in a playerbuilding create the playerbuilding first //otherwise our items will not show when they are created before the cell if(CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(playerObject->getParentId()))) { if(HouseObject* playerHouse = dynamic_cast<HouseObject*>(gWorldManager->getObjectById(cell->getParentId()))) { //gLogger->logMsgF("create playerbuilding",MSG_HIGH); gMessageLib->sendCreateObject(playerHouse,playerObject); playerHouse->addKnownObjectSafe(playerObject); playerObject->addKnownObjectSafe(playerHouse); } } // we still query for players here, cause they are found through the buildings and arent kept in a qtree ObjectSet inRangeObjects; mSpatialIndex->getObjectsInRange(playerObject,&inRangeObjects,(ObjType_Player | ObjType_Tangible | ObjType_NPC | ObjType_Creature | ObjType_Building | ObjType_Structure ),viewingRange); // query the according qtree, if we are in one if(playerObject->getSubZoneId()) { if(QTRegion* region = getQTRegion(playerObject->getSubZoneId())) { Anh_Math::Rectangle qRect; if(!playerObject->getParentId()) { qRect = Anh_Math::Rectangle(playerObject->mPosition.x - viewingRange,playerObject->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2); } else { CellObject* cell = dynamic_cast<CellObject*>(getObjectById(playerObject->getParentId())); if(BuildingObject* house = dynamic_cast<BuildingObject*>(getObjectById(cell->getParentId()))) { qRect = Anh_Math::Rectangle(house->mPosition.x - viewingRange,house->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2); } } region->mTree->getObjectsInRange(playerObject,&inRangeObjects,ObjType_Player,&qRect); } } // iterate through the results ObjectSet::iterator it = inRangeObjects.begin(); while(it != inRangeObjects.end()) { Object* object = (*it); // send create for the type of object if (object->getPrivateOwner()) //what is this about ?? does it concern instances ???? { if (object->isOwnedBy(playerObject)) { gMessageLib->sendCreateObject(object,playerObject); object->addKnownObjectSafe(playerObject); playerObject->addKnownObjectSafe(object); } } else { gMessageLib->sendCreateObject(object,playerObject); object->addKnownObjectSafe(playerObject); playerObject->addKnownObjectSafe(object); } ++it; } }
//********************************************************************* //a Player or creature is ALWAYS in the grid and possibly in a cell void SpatialIndexManager::RemoveObjectFromWorld(PlayerObject *removePlayer) { DLOG(info) << "SpatialIndexManager::RemoveObjectFromWorld:: Player : " << removePlayer->getId(); //remove us from the grid _RemoveObjectFromGrid(removePlayer); //remove us out of the cell if(removePlayer->getParentId() == 0) { return; } CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(removePlayer->getParentId())); if(cell) { //unregister from the building and all its cells if(BuildingObject* building = dynamic_cast<BuildingObject*>(gWorldManager->getObjectById(cell->getParentId()))) { gContainerManager->unRegisterPlayerFromBuilding(building,removePlayer); } cell->removeObject(removePlayer); } else { DLOG(info) << "SpatialIndexManager::RemoveObjectFromWorld (player): couldn't find cell " << removePlayer->getParentId(); } }
void BuildingObject::prepareDestruction() { //iterate through all the registered watchers //place players inside into the world and unregister the content //add an option to delete those players we send to ... gContainerManager->sendToRegisteredPlayers(this, [=] (PlayerObject* player) { gSpatialIndexManager->removeStructureItemsForPlayer(player,this); //is the player inside ??? or was he merely still watching?? CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(player->getParentId())); if (!cell) { //we have no interest in bystanders return; } BuildingObject* building = dynamic_cast<BuildingObject*>(gWorldManager->getObjectById(cell->getParentId())); if (!building || building->getId() != this->getId()) { return; } //No need to update the SI here as we only leave the cell player->updatePosition(0, player->getWorldPosition()); player->setParentIdIncDB(0); cell->RemoveObject(this, player); gMessageLib->broadcastContainmentMessage(player, 0, 0xffffffff); }); //remove items in the building from the world CellObjectList* cell_list = getCellList(); std::for_each(cell_list->begin(), cell_list->end(), [] (CellObject* cell) { cell->prepareDestruction(); }); }
void WorldManager::initPlayersInRange(Object* object,PlayerObject* player) { // we still query for players here, cause they are found through the buildings and arent kept in a qtree ObjectSet inRangeObjects; mSpatialIndex->getObjectsInRange(object,&inRangeObjects,(ObjType_Player),gWorldConfig->getPlayerViewingRange()); // query the according qtree, if we are in one if(object->getSubZoneId()) { if(QTRegion* region = getQTRegion(object->getSubZoneId())) { float viewingRange = _GetMessageHeapLoadViewingRange(); //float viewingRange = (float)gWorldConfig->getPlayerViewingRange(); Anh_Math::Rectangle qRect; if(!object->getParentId()) { qRect = Anh_Math::Rectangle(object->mPosition.x - viewingRange,object->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2); } else { CellObject* cell = dynamic_cast<CellObject*>(getObjectById(object->getParentId())); BuildingObject* building = dynamic_cast<BuildingObject*>(getObjectById(cell->getParentId())); qRect = Anh_Math::Rectangle(building->mPosition.x - viewingRange,building->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2); } region->mTree->getObjectsInRange(object,&inRangeObjects,ObjType_Player,&qRect); } } // iterate through the results ObjectSet::iterator it = inRangeObjects.begin(); while(it != inRangeObjects.end()) { PlayerObject* pObject = dynamic_cast<PlayerObject*>(*it); if(pObject) { if(pObject != player) { gMessageLib->sendCreateObject(object,pObject); pObject->addKnownObjectSafe(object); object->addKnownObjectSafe(pObject); } } ++it; } }
bool ObjectController::_updateInRangeObjectsInside() { PlayerObject* player = dynamic_cast<PlayerObject*>(mObject); CellObject* playerCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(player->getParentId())); // make sure we got a cell if (!playerCell) { gLogger->logMsgF("Error getting cell %"PRIu64" for %"PRIu64" type %u",MSG_NORMAL,player->getParentId(),player->getId(),player->getType()); return true; // We are done, nothing we can do... } // We may wan't to limit the amount of messages sent in one session. uint32 updatedObjects = 0; const uint32 objectSendLimit = 50; //what do we do if the object has been deleted in the meantime? //TODO while ((mObjectSetIt != mInRangeObjects.end()) && (updatedObjects < objectSendLimit)) { // Object* object = (*mObjectSetIt); // Needed since object may be invalid due to the multi-session approach of this function. Object* object = dynamic_cast<Object*>(*mObjectSetIt); // Create objects that are in the same building as we are OR outside near the building. if ((object) && (!player->checkKnownObjects(object))) { bool validObject = true; // Assume it's an object we shall add. // Object inside a building ? if (object->getParentId()) { validObject = false; // Yes, get the objects cell. CellObject* objectCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(object->getParentId())); if (objectCell) { // Are we in the same building? if (objectCell->getParentId() == playerCell->getParentId()) { // We are in the same building as the object. validObject = true; } } else { gLogger->logMsgF("Error getting cell %"PRIu64" for %"PRIu64" type %u",MSG_NORMAL,object->getParentId(),object->getId(),object->getType()); } } if (validObject) { // send the according create for the type of object #if defined(_MSC_VER) if (object->getId() > 0x0000000100000000) #else if (object->getId() > 0x0000000100000000LLU) #endif { //if its an instance and per chance *our* instance if (object->getPrivateOwner()&&object->isOwnedBy(player)) { gMessageLib->sendCreateObject(object,player); player->addKnownObjectSafe(object); object->addKnownObjectSafe(player); updatedObjects++; } else { //if(!player->checkKnownObjects(object)) //{ gMessageLib->sendCreateObject(object,player); player->addKnownObjectSafe(object); object->addKnownObjectSafe(player); updatedObjects++; //} } } } } ++mObjectSetIt; } return (mObjectSetIt == mInRangeObjects.end()); }
//========================================================================================= // // Find the objects observed/known objects when inside // void ObjectController::_findInRangeObjectsInside(bool updateAll) { PlayerObject* player = dynamic_cast<PlayerObject*>(mObject); float viewingRange = _GetMessageHeapLoadViewingRange(); CellObject* playerCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(player->getParentId())); // Make Set ready, mInRangeObjects.clear(); // Init the iterator. mObjectSetIt = mInRangeObjects.begin(); // make sure we got a cell if (!playerCell) { gLogger->logMsg("ERROR: No playerCell."); return; } Object* object = gWorldManager->getObjectById(playerCell->getParentId()); //BuildingObject* building = dynamic_cast<BuildingObject*>(object); BuildingObject* building = dynamic_cast<BuildingObject*>(object); // make sure we got a building if (!building) { gLogger->logMsg("ERROR: No building."); return; } // mInRangeObjectIndex = 0; if (updateAll) { // This is good to use when entering a building. mSI->getObjectsInRange(player,&mInRangeObjects,(ObjType_Player | ObjType_Tangible | ObjType_NPC | ObjType_Creature | ObjType_Building | ObjType_Structure),viewingRange); // query the qtree based on the buildings world position if (QTRegion* region = mSI->getQTRegion(building->mPosition.x,building->mPosition.z)) { Anh_Math::Rectangle qRect = Anh_Math::Rectangle(building->mPosition.x - viewingRange,building->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2); // We need to find moving creatures outside... region->mTree->getObjectsInRange(player,&mInRangeObjects,ObjType_Player | ObjType_NPC | ObjType_Creature, &qRect); } } else { // This is good to use when running around inside a building. // We need to see player or creatures spawning inside. // Added ObjType_Tangible because Tutorial spawns ObjType_Tangible in a way we don't normally do. // If we need more speed in normal cases, just add a test for Tutorial and de-select ObjType_Tangible if not active. mSI->getObjectsInRange(player,&mInRangeObjects,(ObjType_Tangible | ObjType_Player | ObjType_Creature | ObjType_NPC),viewingRange); // query the qtree based on the buildings world position if (QTRegion* region = mSI->getQTRegion(building->mPosition.x,building->mPosition.z)) { Anh_Math::Rectangle qRect = Anh_Math::Rectangle(building->mPosition.x - viewingRange,building->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2); // We need to find moving creatures outside... region->mTree->getObjectsInRange(player,&mInRangeObjects,ObjType_Player | ObjType_NPC | ObjType_Creature,&qRect); } } // Update the iterator to start of Set. mObjectSetIt = mInRangeObjects.begin(); }
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); }
bool HandleMoveFurniture( Object* object, Object* target, Message* message, ObjectControllerCmdProperties* cmdProperties) { PlayerObject* player = dynamic_cast<PlayerObject*>(object); if (!player) { assert(false && "ObjectController::HandleItemMoveDown_ Player not found"); return false; } // Verify that there was a target passed. if (!target) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "move_what"), player); return false; } if(!target) { assert(false && "ObjectController::HandleItemMoveDown_ item not found"); return false; } // Verify that the item and player are in the same structure. CellObject* playerCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(player->getParentId())); if(!playerCell) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "move_what"), player); return false; } uint64 playerStructure = playerCell->getParentId(); CellObject* objectCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(object->getParentId())); if(!objectCell) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "move_what"), player); return false; } uint64 objectStructure = objectCell->getParentId(); if (objectStructure != playerStructure) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "move_what"), player); return false; } // Verify that the player has appropriate rights on this structure. if (playerCell) { if (BuildingObject* building = dynamic_cast<BuildingObject*>(gWorldManager->getObjectById(playerCell->getParentId()))) { if (!building->getAdminData().check_admin(player->getId())) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "admin_move_only"), player); return false; } } else { assert(false && "ObjectController::HandleItemMoveDown_ no structure"); return false; } } else { //were just outside ?? return false; } // Read the message out of the packet. BString tmp; message->getStringUnicode16(tmp); // If the string has no length the message is ill-formatted, send the // proper format to the client. if (!tmp.getLength()) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "format_movefurniture_distance"), player); return false; } // Convert the string to an ansi string for ease with the regex. tmp.convert(BSTRType_ANSI); std::string input_string(tmp.getAnsi()); static const regex pattern("(forward|back|up|down) ([0-9]+)"); smatch result; regex_search(input_string, result, pattern); // If the pattern doesn't match all elements then send the proper format // to the client. if (result.length() < 2) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "format_movefurniture_distance"), player); return false; } // Gather the results of the pattern for validation and use. std::string direction(result[1]); float distance = boost::lexical_cast<float>(result[2]); // If the the specified amount is not within the valid range notify the client. if ((distance < 1.0f) || (distance > 500.0f)) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "movefurniture_params"), player); return false; } // Move object an MOVE_INCREMENT times by the amount and direction specified. if (direction == "forward") { target->move(player->mDirection, distance * MOVE_INCREMENT); } else if (direction == "back") { target->move(player->mDirection, -distance * MOVE_INCREMENT); } else if (direction == "up") { target->mPosition.y += distance * MOVE_INCREMENT; } else if (direction == "down") { target->mPosition.y -= distance * MOVE_INCREMENT; } // Update the world with the changes. gMessageLib->sendDataTransformWithParent053(target); target->updateWorldPosition(); return true; }
//====================================================================================================================== // // rotates an item 90d to right // void ObjectController::HandleItemRotateRight_( uint64 targetId, Message* message, ObjectControllerCmdProperties* cmdProperties) { CreatureObject* creature = dynamic_cast<CreatureObject*>(mObject); PlayerObject* player = creature->GetGhost(); if (!player) { assert(false && "ObjectController::HandleItemRotateRight_ Player not found"); return; } // Verify that there was a target passed. if (!targetId) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "rotate_what"), player); return; } Object* object = gWorldManager->getObjectById(targetId); if(!object) { assert(false && "ObjectController::HandleItemRotateRight_ item not found"); return; } // Verify that the item and player are in the same structure. // Verify that the item and player are in the same structure. CellObject* playerCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(player->getParentId())); if(!playerCell) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "rotate_what"), player); return; } uint64 playerStructure = playerCell->getParentId(); CellObject* objectCell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(object->getParentId())); if(!objectCell) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "rotate_what"), player); return; } uint64 objectStructure = objectCell->getParentId(); if (objectStructure != playerStructure) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "rotate_what"), player); return; } // Verify that the player has appropriate rights on this structure. if (playerCell) { if (BuildingObject* building = dynamic_cast<BuildingObject*>(gWorldManager->getObjectById(playerCell->getParentId()))) { if (!building->getAdminData().check_admin(player->getId())) { gMessageLib->SendSystemMessage(::common::OutOfBand("player_structure", "admin_move_only"), player); return; } } else { assert(false && "ObjectController::HandleItemRotateRight_ no structure"); return; } } else { //were just outside return; } // Rotate the object 90 degree's to the right object->rotateRight(ROTATE_INCREMENT); gMessageLib->sendDataTransformWithParent053(object); object->updateWorldPosition(); }
void WorldManager::createObjectinWorld(Object* object) { float viewingRange = _GetMessageHeapLoadViewingRange(); ObjectSet inRangeObjects; mSpatialIndex->getObjectsInRange(object,&inRangeObjects,(ObjType_Player),viewingRange); // query the according qtree, if we are in one if(object->getSubZoneId()) { if(QTRegion* region = getQTRegion(object->getSubZoneId())) { Anh_Math::Rectangle qRect; if(!object->getParentId()) { qRect = Anh_Math::Rectangle(object->mPosition.x - viewingRange,object->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2); } else { CellObject* cell = dynamic_cast<CellObject*>(getObjectById(object->getParentId())); if(BuildingObject* house = dynamic_cast<BuildingObject*>(getObjectById(cell->getParentId()))) { qRect = Anh_Math::Rectangle(house->mPosition.x - viewingRange,house->mPosition.z - viewingRange,viewingRange * 2,viewingRange * 2); } } region->mTree->getObjectsInRange(object,&inRangeObjects,ObjType_Player,&qRect); } } // iterate through the results ObjectSet::iterator it = inRangeObjects.begin(); while(it != inRangeObjects.end()) { PlayerObject* player = dynamic_cast<PlayerObject*> (*it); if(player) { // send create for the type of object if (object->getPrivateOwner()) //what is this about ?? does it concern instances ???? { if (object->isOwnedBy(player)) { gMessageLib->sendCreateObject(object,player); object->addKnownObjectSafe(player); player->addKnownObjectSafe(object); } } else { gMessageLib->sendCreateObject(object,player); object->addKnownObjectSafe(player); player->addKnownObjectSafe(object); } } ++it; } }