Vector<WorldCoordinates>* PathFinderManager::findPathFromCellToCell(const WorldCoordinates& pointA, const WorldCoordinates& pointB) { CellObject* ourCell = pointA.getCell(); CellObject* targetCell = pointB.getCell(); if (ourCell != targetCell) return findPathFromCellToDifferentCell(pointA, pointB); int ourCellID = ourCell->getCellNumber(); ManagedReference<BuildingObject*> building = cast<BuildingObject*>( ourCell->getParent().get().get()); SharedObjectTemplate* templateObject = building->getObjectTemplate(); if (templateObject == NULL) return NULL; PortalLayout* portalLayout = templateObject->getPortalLayout(); if (portalLayout == NULL) return NULL; FloorMesh* floorMesh1 = portalLayout->getFloorMesh(ourCellID); PathGraph* pathGraph1 = floorMesh1->getPathGraph(); Vector<WorldCoordinates>* path = new Vector<WorldCoordinates>(5, 1); path->add(pointA); // adding source //info("same cell... trying to calculate triangle path", true); Vector<Triangle*>* trianglePath = NULL; //info("searching floorMesh for cellID " + String::valueOf(ourCellID), true); int res = getFloorPath(pointA.getPoint(), pointB.getPoint(), floorMesh1, trianglePath); if (res == -1) { //points in the same triangle path->add(pointB); return path; } if (trianglePath == NULL) { // returning NULL, no path found //error("path NULL"); delete path; return findPathFromCellToDifferentCell(pointA, pointB); } else { //info("path found", true); addTriangleNodeEdges(pointA.getPoint(), pointB.getPoint(), trianglePath, path, ourCell); delete trianglePath; path->add(pointB); //adding destination return path; } return path; }
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); }); }
//********************************************************************* //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(); } }
bool CollisionManager::checkLineOfSightInParentCell(SceneObject* object, Vector3& endPoint) { ManagedReference<SceneObject*> parent = object->getParent(); if (parent == NULL || !parent->isCellObject()) return true; CellObject* cell = cast<CellObject*>( parent.get()); SharedObjectTemplate* objectTemplate = parent->getRootParent().get()->getObjectTemplate(); PortalLayout* portalLayout = objectTemplate->getPortalLayout(); MeshAppearanceTemplate* appearanceMesh = NULL; if (portalLayout == NULL) return true; try { appearanceMesh = portalLayout->getMeshAppearanceTemplate(cell->getCellNumber()); } catch (Exception& e) { return true; } if (appearanceMesh == NULL) { //info("null appearance mesh "); return true; } AABBTree* aabbTree = appearanceMesh->getAABBTree(); if (aabbTree == NULL) return true; //switching Y<->Z, adding 0.1 to account floor Vector3 startPoint = object->getPosition(); startPoint.set(startPoint.getX(), startPoint.getY(), startPoint.getZ() + 0.1f); endPoint.set(endPoint.getX(), endPoint.getY(), endPoint.getZ() + 0.1f); Vector3 dir = endPoint - startPoint; dir.normalize(); float distance = endPoint.distanceTo(startPoint); float intersectionDistance; Ray ray(startPoint, dir); Triangle* triangle = NULL; //nothing in the middle if (aabbTree->intersects(ray, distance, intersectionDistance, triangle, true)) return false; Ray ray2(endPoint, Vector3(0, -1, 0)); //check if we are in the cell with dir (0, -1, 0) if (!aabbTree->intersects(ray2, 64000.f, intersectionDistance, triangle, true)) return false; return true; }
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); } }
int ZoneImplementation::getInRangeObjects(float x, float y, float range, SortedVector<ManagedReference<QuadTreeEntry*> >* objects, bool readLockZone) { //Locker locker(_this.getReferenceUnsafeStaticCast()); bool readlock = readLockZone && !_this.getReferenceUnsafeStaticCast()->isLockedByCurrentThread(); Vector<ManagedReference<QuadTreeEntry*> > buildingObjects; // _this.getReferenceUnsafeStaticCast()->rlock(readlock); try { _this.getReferenceUnsafeStaticCast()->rlock(readlock); quadTree->inRange(x, y, range, *objects); _this.getReferenceUnsafeStaticCast()->runlock(readlock); } catch (...) { _this.getReferenceUnsafeStaticCast()->runlock(readlock); } for (int i = 0; i < objects->size(); ++i) { SceneObject* sceneObject = cast<SceneObject*>(objects->get(i).get()); BuildingObject* building = dynamic_cast<BuildingObject*>(sceneObject); if (building != NULL) { for (int j = 1; j <= building->getMapCellSize(); ++j) { CellObject* cell = building->getCell(j); if (cell != NULL) { try { ReadLocker rlocker(cell->getContainerLock()); for (int h = 0; h < cell->getContainerObjectsSize(); ++h) { ManagedReference<SceneObject*> obj = cell->getContainerObject(h); if (obj != NULL) buildingObjects.add(obj.get()); } } catch (...) { } } } } else if (sceneObject != NULL && (sceneObject->isVehicleObject() || sceneObject->isMount())) { ManagedReference<SceneObject*> rider = sceneObject->getSlottedObject("rider"); if (rider != NULL) buildingObjects.add(rider.get()); } } //_this.getReferenceUnsafeStaticCast()->runlock(readlock); for (int i = 0; i < buildingObjects.size(); ++i) objects->put(buildingObjects.get(i)); return objects->size(); }
//====================================================================================================================== // // create building // bool MessageLib::sendCreateBuilding(BuildingObject* buildingObject,PlayerObject* playerObject) { if(!_checkPlayer(playerObject)) return(false); bool publicBuilding = true; //test buildings on house basis here //perhaps move to on cell basis sometime ? if(HouseObject* house = dynamic_cast<HouseObject*>(buildingObject)) { house->checkCellPermission(playerObject); publicBuilding = buildingObject->getPublic(); } sendCreateObjectByCRC(buildingObject,playerObject,false); sendBaselinesBUIO_3(buildingObject,playerObject); sendBaselinesBUIO_6(buildingObject,playerObject); uint64 buildingId = buildingObject->getId(); CellObjectList* cellList = buildingObject->getCellList(); CellObjectList::iterator cellIt = cellList->begin(); uint64 cellCount = cellList->size(); while(cellIt != cellList->end()) { CellObject* cell = (*cellIt); uint64 cellId = cell->getId(); uint64 count = buildingObject->getMinCellId()-1; sendCreateObjectByCRC(cell,playerObject,false); sendContainmentMessage(cellId,buildingId,0xffffffff,playerObject); //cell ids are id based for tutorial cells! if(cell->getId() <= 2203318222975) { sendBaselinesSCLT_3(cell,cellId - buildingId,playerObject); } else { sendBaselinesSCLT_3(cell,cellId - count,playerObject); } sendBaselinesSCLT_6(cell,playerObject); sendUpdateCellPermissionMessage(cell,publicBuilding,playerObject); //cellpermissions get checked by datatransform sendEndBaselines(cellId,playerObject); ++cellIt; } sendEndBaselines(buildingId,playerObject); return(true); }
CellObject* CellFactory::_createCell(DatabaseResult* result) { CellObject* cellObject = new CellObject(); cellObject->setCapacity(500); uint64 count = result->getRowCount(); result->GetNextRow(mCellBinding,(void*)cellObject); return cellObject; }
//============================================================================================================ // 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; }
CellObject* CellFactory::_createCell(DatabaseResult* result) { if (!result->getRowCount()) { return nullptr; } CellObject* cellObject = new CellObject(); cellObject->setCapacity(500); result->getNextRow(mCellBinding,(void*)cellObject); //cells are added to the worldmanager in the buildingFactory!! return cellObject; }
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; } }
CellObject* CellFactory::_createCell(swganh::database::DatabaseResult* result) { if (!result->getRowCount()) { return nullptr; } CellObject* cell = new CellObject(); cell->setCapacity(500); cell->object_type_ = SWG_CELL; gObjectManager->LoadSlotsForObject(cell); result->getNextRow(mCellBinding,(void*)cell); auto permissions_objects_ = gObjectManager->GetPermissionsMap(); cell->SetPermissions(permissions_objects_.find(swganh::object::WORLD_CELL_PERMISSION)->second.get());//CREATURE_PERMISSION //cells are added to the worldmanager in the buildingFactory!! return cell; }
//================================================================================ // //the cells send an updated permission to the specified player // void BuildingObject::updateCellPermissions(PlayerObject* player, bool access) { //iterate through all the cells //place players inside the world this->ViewObjects(nullptr, 1, false, [&](Object* object){ if(object->getObjectType() == SWG_CELL) { CellObject* cell = dynamic_cast<CellObject*>(object); gMessageLib->sendUpdateCellPermissionMessage(cell,access,player); //are we inside the cell ? if((player->getParentId() == cell->getId()) && (!access)) { //were no longer allowed to be inside .... //so get going //TODO find outside position (sign position for example??) to place the player glm::vec3 playerPosition = player->mPosition; glm::vec3 playerWorldPosition = player->getWorldPosition(); glm::vec3 position; glm::vec3 playerNewPosition; position.x = (0 - playerPosition.x) - 5; position.z = (0 - playerPosition.z) - 2; position.y = mPosition.y + 50; position.x += playerWorldPosition.x; //position.y += player->getWorldPosition.x; position.z += playerWorldPosition.z; player->updatePosition(0,position); } } }); }
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 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 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 ObjectFactory::deleteObjectFromDB(Object* object) { int8 sql[256]; switch(object->getType()) { case ObjType_Tangible: { TangibleObject* tangibleObject = dynamic_cast<TangibleObject*>(object); switch(tangibleObject->getTangibleGroup()) { case TanGroup_Item: { Item* item = dynamic_cast<Item*>(object); if(item->getItemType() == ItemFamily_ManufacturingSchematic) { ManufacturingSchematic* schem = dynamic_cast<ManufacturingSchematic*> (object); //first associated item sprintf(sql,"DELETE FROM items WHERE id = %"PRIu64"",schem->getItem()->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); sprintf(sql,"DELETE FROM item_attributes WHERE item_id = %"PRIu64"",schem->getItem()->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); } ObjectIDList* objectList = item->getObjects(); ObjectIDList::iterator objIt = objectList->begin(); while(objIt != objectList->end()) { Object* object = gWorldManager->getObjectById((*objIt)); deleteObjectFromDB(object); ++objIt; } sprintf(sql,"DELETE FROM items WHERE id = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); sprintf(sql,"DELETE FROM item_attributes WHERE item_id = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); } break; case TanGroup_ResourceContainer: { sprintf(sql,"DELETE FROM resource_containers WHERE id = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); } break; case TanGroup_Terminal: { sprintf(sql,"DELETE FROM terminals WHERE id = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); } break; default:break; } } break; case ObjType_Intangible: { IntangibleObject* itno = dynamic_cast<IntangibleObject*>(object); switch(itno->getItnoGroup()) { case ItnoGroup_Vehicle: { sprintf(sql,"DELETE FROM vehicle_cutomization WHERE vehicles_id = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); sprintf(sql,"DELETE FROM vehicle_attributes WHERE vehicles_id = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); sprintf(sql,"DELETE FROM vehicles WHERE id = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); } break; default: break; } } break; case ObjType_Cell: { CellObject* cell = dynamic_cast<CellObject*>(object); ObjectIDList* cellObjects = cell->getObjects(); ObjectIDList::iterator objIt = cellObjects->begin(); while(objIt != cellObjects->end()) { Object* childObject = gWorldManager->getObjectById((*objIt)); if(PlayerObject* player = dynamic_cast<PlayerObject*>(childObject)) { //place the player in the world and db - do *NOT* delete him :P //player->setParentId(0,0xffffffff,player->getKnownPlayers(),true); } else if(CreatureObject* pet = dynamic_cast<CreatureObject*>(childObject)) { //place the player in the world and db - do *NOT* delete him :P //pet->setParentId(0,0xffffffff,pet->getKnownPlayers(),true); } else { deleteObjectFromDB(childObject); } ++objIt; sprintf(sql,"UPDATE characters SET parent_id = 0 WHERE parent_id = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); } sprintf(sql,"DELETE FROM cells WHERE id = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); } break; case ObjType_Building: { //only delete when a playerbuilding HouseObject* house = dynamic_cast<HouseObject*>(object); if(!house) { //no player building return; } CellObjectList* cellList = house->getCellList(); CellObjectList::iterator cellIt = cellList->begin(); while(cellIt != cellList->end()) { CellObject* cell = (*cellIt); deleteObjectFromDB(cell); //remove items in the building from world and db ++cellIt; } sprintf(sql,"DELETE FROM houses WHERE ID = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); //sprintf(sql,"DELETE FROM terminals WHERE ID = %"PRIu64"",object->getId()); //mDatabase->ExecuteSqlAsync(NULL,NULL,sql); sprintf(sql,"DELETE FROM structures WHERE ID = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); //Admin / Hopper Lists sprintf(sql,"DELETE FROM structure_admin_data WHERE StructureID = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); //update attributes cave redeed vs destroy sprintf(sql,"DELETE FROM structure_attributes WHERE Structure_id = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); } break; case ObjType_Structure: { //Harvester sprintf(sql,"DELETE FROM structures WHERE ID = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); sprintf(sql,"DELETE FROM harvesters WHERE ID = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); sprintf(sql,"DELETE FROM factories WHERE ID = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); //Admin / Hopper Lists sprintf(sql,"DELETE FROM structure_admin_data WHERE StructureID = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); //update attributes cave redeed vs destroy sprintf(sql,"DELETE FROM structure_attributes WHERE Structure_id = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); //update hopper contents sprintf(sql,"DELETE FROM harvester_resources WHERE ID = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); } break; case ObjType_Waypoint: { sprintf(sql,"DELETE FROM waypoints WHERE waypoint_id = %"PRIu64"",object->getId()); mDatabase->ExecuteSqlAsync(NULL,NULL,sql); } break; default:break; } }
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); } }
Vector<WorldCoordinates>* PathFinderManager::findPathFromCellToWorld(const WorldCoordinates& pointA, const WorldCoordinates& pointB, Zone *zone) { Vector<WorldCoordinates>* path = new Vector<WorldCoordinates>(5, 1); if (path == NULL) return NULL; path->add(pointA); CellObject* ourCell = pointA.getCell(); ManagedReference<BuildingObject*> building = cast<BuildingObject*>( ourCell->getParent().get().get()); int ourCellID = ourCell->getCellNumber(); SharedObjectTemplate* templateObject = ourCell->getParent().get()->getObjectTemplate(); if (templateObject == NULL) { delete path; return NULL; } PortalLayout* portalLayout = templateObject->getPortalLayout(); if (portalLayout == NULL) { delete path; return NULL; } FloorMesh* sourceFloorMesh = portalLayout->getFloorMesh(ourCellID); if (sourceFloorMesh == NULL) { delete path; return NULL; } PathGraph* sourcePathGraph = sourceFloorMesh->getPathGraph(); if (sourcePathGraph == NULL) { delete path; return NULL; } FloorMesh* exteriorFloorMesh = portalLayout->getFloorMesh(0); if (exteriorFloorMesh == NULL) { delete path; return NULL; } PathGraph* exteriorPathGraph = exteriorFloorMesh->getPathGraph(); if (exteriorPathGraph == NULL) { delete path; return NULL; } // we need to move world position into model space Vector3 transformedPosition = transformToModelSpace(pointB.getPoint(), building); //find exit node in our cell //PathNode* exitNode = sourcePathGraph->findNearestNode(pointA.getPoint()); TriangleNode* nearestTargetNodeTriangle = CollisionManager::getTriangle(pointA.getPoint(), sourceFloorMesh); if (nearestTargetNodeTriangle == NULL) { delete path; return NULL; } PathNode* exitNode = CollisionManager::findNearestPathNode(nearestTargetNodeTriangle, sourceFloorMesh, transformedPosition);//targetPathGraph->findNearestNode(pointB.getPoint()); if (exitNode == NULL) { delete path; return NULL; } //find exterior node PathNode* exteriorNode = exteriorPathGraph->findNearestGlobalNode(transformedPosition); if (exteriorNode == NULL) { delete path; return NULL; } //find path to the exit Vector<PathNode*>* exitPath = portalLayout->getPath(exitNode, exteriorNode); if (exitPath == NULL) { error("exitPath == NULL"); delete path; return NULL; } //find triangle path to exitNode Vector<Triangle*>* trianglePath = NULL; int res = getFloorPath(pointA.getPoint(), exitNode->getPosition(), sourceFloorMesh, trianglePath); if (res != -1 && trianglePath != NULL) addTriangleNodeEdges(pointA.getPoint(), exitNode->getPosition(), trianglePath, path, ourCell); if (trianglePath != NULL) delete trianglePath; path->add(WorldCoordinates(exitNode->getPosition(), ourCell)); //populate cell traversing for (int i = 0; i < exitPath->size(); ++i) { PathNode* pathNode = exitPath->get(i); PathGraph* pathGraph = pathNode->getPathGraph(); FloorMesh* floorMesh = pathGraph->getFloorMesh(); int cellID = floorMesh->getCellID(); if (cellID == 0) { // we are outside WorldCoordinates coord(pathNode->getPosition(), ourCell); path->add(WorldCoordinates(coord.getWorldPosition(), NULL)); } else { // we are inside the building CellObject* pathCell = building->getCell(cellID); path->add(WorldCoordinates(pathNode->getPosition(), pathCell)); } } delete exitPath; exitPath = NULL; if (path->size()) { Vector<WorldCoordinates>* newPath = findPathFromWorldToWorld(path->get(path->size()-1), pointB, zone); if (newPath) { path->addAll(*newPath); delete newPath; } } else path->add(pointB); return path; }
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; }
void CellFactory::handleDatabaseJobComplete(void* ref,swganh::database::DatabaseResult* result) { QueryContainerBase* asyncContainer = reinterpret_cast<QueryContainerBase*>(ref); switch(asyncContainer->mQueryType) { case CellFQuery_MainData: { CellObject* cell = _createCell(result); uint64 cellId = cell->getId(); QueryContainerBase* asContainer = new(mQueryContainerPool.ordered_malloc()) QueryContainerBase(asyncContainer->mOfCallback,CellFQuery_Objects,asyncContainer->mClient); asContainer->mObject = cell; mDatabase->executeSqlAsync(this,asContainer,"(SELECT \'terminals\',id FROM %s.terminals WHERE parent_id = %"PRIu64")" " UNION (SELECT \'ticket_collectors\',id FROM %s.ticket_collectors WHERE (parent_id=%"PRIu64"))" " UNION (SELECT \'persistent_npcs\',id FROM %s.persistent_npcs WHERE parentId=%"PRIu64")" " UNION (SELECT \'shuttles\',id FROM %s.shuttles WHERE parentId=%"PRIu64")" " UNION (SELECT \'items\',id FROM %s.items WHERE parent_id=%"PRIu64")" " UNION (SELECT \'resource_containers\',id FROM %s.resource_containers WHERE parent_id=%"PRIu64")", mDatabase->galaxy(),cellId, mDatabase->galaxy(),cellId, mDatabase->galaxy(),cellId, mDatabase->galaxy(),cellId, mDatabase->galaxy(),cellId, mDatabase->galaxy(),cellId); } break; case CellFQuery_Objects: { CellObject* cell = dynamic_cast<CellObject*>(asyncContainer->mObject); Type1_QueryContainer queryContainer; swganh::database::DataBinding* binding = mDatabase->createDataBinding(2); binding->addField(swganh::database::DFT_bstring,offsetof(Type1_QueryContainer,mString),64,0); binding->addField(swganh::database::DFT_uint64,offsetof(Type1_QueryContainer,mId),8,1); uint64 count = result->getRowCount(); if(count > 0) { // store us for later lookup mObjectLoadMap.insert(std::make_pair(cell->getId(),new(mILCPool.ordered_malloc()) InLoadingContainer(cell,asyncContainer->mOfCallback,asyncContainer->mClient))); cell->setLoadCount(static_cast<uint32>(count)); for(uint32 i = 0; i < count; i++) { result->getNextRow(binding,&queryContainer); if(strcmp(queryContainer.mString.getAnsi(),"terminals") == 0) gObjectFactory->requestObject(ObjType_Tangible,TanGroup_Terminal,0,this,queryContainer.mId,asyncContainer->mClient); else if(strcmp(queryContainer.mString.getAnsi(),"ticket_collectors") == 0) gObjectFactory->requestObject(ObjType_Tangible,TanGroup_TicketCollector,0,this,queryContainer.mId,asyncContainer->mClient); else if(strcmp(queryContainer.mString.getAnsi(),"persistent_npcs") == 0) gObjectFactory->requestObject(ObjType_NPC,CreoGroup_PersistentNpc,0,this,queryContainer.mId,asyncContainer->mClient); else if(strcmp(queryContainer.mString.getAnsi(),"shuttles") == 0) gObjectFactory->requestObject(ObjType_Creature,CreoGroup_Shuttle,0,this,queryContainer.mId,asyncContainer->mClient); else if(strcmp(queryContainer.mString.getAnsi(),"items") == 0) gObjectFactory->requestObject(ObjType_Tangible,TanGroup_Item,0,this,queryContainer.mId,asyncContainer->mClient); else if(strcmp(queryContainer.mString.getAnsi(),"resource_containers") == 0) gObjectFactory->requestObject(ObjType_Tangible,TanGroup_ResourceContainer,0,this,queryContainer.mId,asyncContainer->mClient); } } else asyncContainer->mOfCallback->handleObjectReady(cell,asyncContainer->mClient); mDatabase->destroyDataBinding(binding); } break; default: break; } mQueryContainerPool.free(asyncContainer); }
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(); }
Vector<WorldCoordinates>* PathFinderManager::findPathFromCellToDifferentCell(const WorldCoordinates& pointA, const WorldCoordinates& pointB) { //info ("findPathFromCellToDifferentCell", true); CellObject* ourCell = pointA.getCell(); CellObject* targetCell = pointB.getCell(); int ourCellID = ourCell->getCellNumber(); int targetCellID = targetCell->getCellNumber(); ManagedReference<BuildingObject*> building1 = cast<BuildingObject*>( ourCell->getParent().get().get()); ManagedReference<BuildingObject*> building2 = cast<BuildingObject*>( targetCell->getParent().get().get()); if (building1 != building2) // TODO: implement path finding between 2 buildings return NULL; SharedObjectTemplate* templateObject = building1->getObjectTemplate(); if (templateObject == NULL) return NULL; PortalLayout* portalLayout = templateObject->getPortalLayout(); if (portalLayout == NULL) return NULL; FloorMesh* floorMesh1 = portalLayout->getFloorMesh(ourCellID); FloorMesh* floorMesh2 = portalLayout->getFloorMesh(targetCellID); if (floorMesh2->getCellID() != targetCellID) error("floorMes2 cellID != targetCellID"); //info("targetCellID:" + String::valueOf(targetCellID), true); PathGraph* pathGraph1 = floorMesh1->getPathGraph(); PathGraph* pathGraph2 = floorMesh2->getPathGraph(); Vector<WorldCoordinates>* path = new Vector<WorldCoordinates>(5, 1); path->add(pointA); // adding source //PathNode* source = pathGraph1->findNearestNode(pointA.getPoint()); TriangleNode* nearestSourceNodeTriangle = CollisionManager::getTriangle(pointA.getPoint(), floorMesh1); if (nearestSourceNodeTriangle == NULL) { delete path; return NULL; } PathNode* source = CollisionManager::findNearestPathNode(nearestSourceNodeTriangle, floorMesh1, pointB.getPoint());//targetPathGraph->findNearestNode(pointB.getPoint()); if (source == NULL) { delete path; return NULL; } //PathNode* target = pathGraph2->findNearestNode(pointB.getPoint()); TriangleNode* nearestTargetNodeTriangle = CollisionManager::getTriangle(pointB.getPoint(), floorMesh2); if (nearestTargetNodeTriangle == NULL) { delete path; return NULL; } PathNode* target = CollisionManager::findNearestPathNode(nearestTargetNodeTriangle, floorMesh2, pointB.getPoint());//targetPathGraph->findNearestNode(pointB.getPoint()); if (target == NULL) { delete path; return NULL; } Vector<PathNode*>* nodes = portalLayout->getPath(source, target); if (nodes == NULL) { StringBuffer str; str << "Could not find path from node: " << source->getID() << " to node: " << target->getID() << " in building: " << templateObject->getFullTemplateString(); log(str.toString()); delete path; return NULL; } // FIXME (dannuic): Sometimes nodes only have one entry.... why? if (nodes->size() == 1) { error("Only one node"); delete path; return NULL; } // path from our position to path node Vector<Triangle*>* trianglePath = NULL; int res = getFloorPath(pointA.getPoint(), nodes->get(1)->getPosition(), floorMesh1, trianglePath); if (res != -1 && trianglePath != NULL) addTriangleNodeEdges(pointA.getPoint(), nodes->get(1)->getPosition(), trianglePath, path, ourCell); if (trianglePath != NULL) { delete trianglePath; trianglePath = NULL; } path->add(WorldCoordinates(source->getPosition(), ourCell)); //traversing cells for (int i = 1; i < nodes->size(); ++i) { PathNode* pathNode = nodes->get(i); PathGraph* pathGraph = pathNode->getPathGraph(); FloorMesh* floorMesh = pathGraph->getFloorMesh(); int cellID = floorMesh->getCellID(); if (cellID == 0) { //info("cellID == 0", true); WorldCoordinates coord(pathNode->getPosition(), ourCell); path->add(WorldCoordinates(coord.getWorldPosition(), NULL)); } else { CellObject* pathCell = building1->getCell(cellID); WorldCoordinates coord(pathNode->getPosition(), pathCell); path->add(coord); //info("cellID:" + String::valueOf(cellID), true); if (i == nodes->size() - 1) { if (pathNode != target) { StringBuffer msg; msg << "pathNode != target pathNode: " << pathNode->getID() << " target:" << target->getID(); error(msg.toString()); } if (pathCell != targetCell) { error("final cell not target cell"); } } } } delete nodes; nodes = NULL; // path from cell entrance to destination point trianglePath = NULL; res = getFloorPath(path->get(path->size() - 1).getPoint(), pointB.getPoint(), floorMesh2, trianglePath); if (res != -1 && trianglePath != NULL) addTriangleNodeEdges(path->get(path->size() - 1).getPoint(), pointB.getPoint(), trianglePath, path, targetCell); if (trianglePath != NULL) delete trianglePath; path->add(pointB); return path; }
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); } }
bool ObjectController::removeFromContainer(uint64 targetContainerId, uint64 targetId) { PlayerObject* playerObject = dynamic_cast<PlayerObject*>(mObject); Object* itemObject = gWorldManager->getObjectById(targetId); Inventory* inventory = dynamic_cast<Inventory*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory)); TangibleObject* targetContainer = dynamic_cast<TangibleObject*>(gWorldManager->getObjectById(targetContainerId)); TangibleObject* tangible = dynamic_cast<TangibleObject*>(itemObject); Item* item = dynamic_cast<Item*>(itemObject); // its us if (tangible->getParentId() == playerObject->getId()) { // unequip it return playerObject->getEquipManager()->unEquipItem(itemObject); } //the containerObject is the container used in the tutorial or some random dungeon container Container* container = dynamic_cast<Container*>(gWorldManager->getObjectById(tangible->getParentId())); if (container) { container->removeObject(itemObject); //gContainerManager->destroyObjectToRegisteredPlayers(container, tangible->getId()); if (gWorldConfig->isTutorial()) { playerObject->getTutorial()->transferedItemFromContainer(targetId, tangible->getParentId()); // If object is owned by player (private owned for instancing), we remove the owner from the object. // what is this used for ??? if (itemObject->getPrivateOwner() == playerObject->getId()) { itemObject->setPrivateOwner(0); } } return true; } //creature inventories are a special case - their items are temporary!!! we cannot loot them directly CreatureObject* unknownCreature; Inventory* creatureInventory; if (itemObject->getParentId() && (unknownCreature = dynamic_cast<CreatureObject*>(gWorldManager->getObjectById(itemObject->getParentId() - INVENTORY_OFFSET))) && (creatureInventory = dynamic_cast<Inventory*>(unknownCreature->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory))) && (creatureInventory->getId() == itemObject->getParentId()) && (creatureInventory->getId() != inventory->getId())) { if(!creatureInventory->removeObject(itemObject)) { LOG(warning) << "ObjectController::removeFromContainer: Internal Error could not remove " << itemObject->getId() << " from creature inventory " << creatureInventory->getId(); return false; } // we destroy the item in this case as its a temporary!! // we do not want to clog the db with unlooted items gContainerManager->destroyObjectToRegisteredPlayers(creatureInventory, tangible->getId()); ObjectIDList* invObjList = creatureInventory->getObjects(); if (invObjList->size() == 0) { // Put this creature in the pool of delayed destruction and remove the corpse from scene. gWorldManager->addCreatureObjectForTimedDeletion(creatureInventory->getParentId(), LootedCorpseTimeout); } if (gWorldConfig->isTutorial()) { // TODO: Update tutorial about the loot. playerObject->getTutorial()->transferedItemFromContainer(targetId, creatureInventory->getId()); } //bail out here and request the item over the db - as the item in the NPC has a temporary id and we dont want that in the db // This ensure that we do not use/store any of the temp id's in the database. gObjectFactory->requestNewDefaultItem(inventory, item->getItemFamily(), item->getItemType(), inventory->getId(), 99, glm::vec3(), ""); return false; } //cells are NOT tangibles - thei are static Objects CellObject* cell; if(cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(itemObject->getParentId()))) { // Stop playing if we pick up the (permanently placed) instrument we are playing if (item && (item->getItemFamily() == ItemFamily_Instrument)) { uint32 instrumentType = item->getItemType(); if ((instrumentType == ItemType_Nalargon) || (instrumentType == ItemType_omni_box) || (instrumentType == ItemType_nalargon_max_reebo)) { // It's a placeable original instrument. // Are we targeting the instrument we actually play on? if (playerObject->getActiveInstrumentId() == item->getId()) { gEntertainerManager->stopEntertaining(playerObject); } } } //we *cannot* remove static tangibles like the structureterminal!!!! if(tangible->getStatic()) { return false; } // Remove object from cell. cell->removeObject(itemObject); return true; } //some other container ... hopper backpack chest etc TangibleObject* containingContainer = dynamic_cast<TangibleObject*>(gWorldManager->getObjectById(tangible->getParentId())); if(containingContainer && containingContainer->removeObject(itemObject)) { return true; } return false; }
//====================================================================================================================== // // 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 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; } }
//====================================================================================================================== // // 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(); }
//====================================================================================================================== // // 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(); }