bool ZoneImplementation::objectIsValidPlanetaryMapPerformanceLocation(SceneObject* object) { BuildingObject* building = object->asBuildingObject(); if (building == NULL) { return false; } bool hasPerformanceLocationCategory = false; PlanetMapCategory* planetMapCategory = object->getPlanetMapCategory(); if (planetMapCategory != NULL) { String category = planetMapCategory->getName(); if (category == "cantina" || category == "hotel") { hasPerformanceLocationCategory = true; } } if (!hasPerformanceLocationCategory) { planetMapCategory = object->getPlanetMapSubCategory(); if (planetMapCategory != NULL) { String subCategory = planetMapCategory->getName(); if (subCategory == "guild_theater") { hasPerformanceLocationCategory = true; } } } if (hasPerformanceLocationCategory) { if (building->isPublicStructure()) { return true; } } return false; }
void BuildingFactory::handleObjectReady(Object* object,DispatchClient* client) { InLoadingContainer* ilc = _getObject(object->getParentId()); if (! ilc) {//ILC sanity check... gLogger->log(LogManager::WARNING,"BuildingFactory::handleObjectReady could not locate ILC for objectParentId:%I64u",object->getParentId()); return; } BuildingObject* building = dynamic_cast<BuildingObject*>(ilc->mObject); //this happens on load so no reason to update players gWorldManager->addObject(object,true); building->addCell(dynamic_cast<CellObject*>(object)); if(building->getLoadCount() == (building->getCellList())->size()) { if(!(_removeFromObjectLoadMap(building->getId()))) gLogger->log(LogManager::DEBUG,"BuildingFactory: Failed removing object from loadmap"); ilc->mOfCallback->handleObjectReady(building,ilc->mClient); mILCPool.free(ilc); } }
void BuildingFactory::handleObjectReady(Object* object,DispatchClient* client) { InLoadingContainer* ilc = _getObject(object->getParentId()); if (! ilc) {//ILC sanity check... LOG(warning) << "Could not locate InLoadingContainer for object parent [" << object->getParentId() << "]"; return; } BuildingObject* building = dynamic_cast<BuildingObject*>(ilc->mObject); //this happens on load so no reason to update players gWorldManager->addObject(object,true); building->addCell(dynamic_cast<CellObject*>(object)); //LOG(info) << "BuildingFactory::handleObjectReady -> building load cell " << object->getId() << "for " << building->getId(); //LOG(info) << "loadcount : " << building->getLoadCount() << " : count : " << building->getCellList()->size(); if(building->getLoadCount() == (building->getCellList())->size()) { //LOG(info) << "BuildingFactory::handleObjectReady -> building loadcount done for " << building->getId(); if(!(_removeFromObjectLoadMap(building->getId()))) LOG(warning) << "Failed removing object from loadmap"; ilc->mOfCallback->handleObjectReady(building,ilc->mClient); mILCPool.free(ilc); } }
void StructureManager::setSign(StructureObject* structure, CreatureObject* player, String signSuiItem ){ if( !structure->isBuildingObject() ) return; // Check building template has shop signs configured Reference<SharedBuildingObjectTemplate*> buildingTemplate = dynamic_cast<SharedBuildingObjectTemplate*>(structure->getObjectTemplate()); if( buildingTemplate == NULL ){ player->sendSystemMessage( "ERROR: Unable to get structure template" ); return; } if( buildingTemplate->getShopSignsSize() == 0 ){ player->sendSystemMessage( "This building does not have any signs configured" ); return; } BuildingObject* building = cast<BuildingObject*>(structure); if( building == NULL ) return; // Find matching sign in the template and change sign for( int i=0; i < buildingTemplate->getShopSignsSize(); i++){ SignTemplate* signTemplate = buildingTemplate->getShopSign(i); if( signTemplate->getSuiItem() == signSuiItem ){ building->changeSign( signTemplate ); return; } } }
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); }); }
int PlaceStructureSessionImplementation::completeSession() { if (constructionBarricade != NULL) constructionBarricade->destroyObjectFromWorld(true); String serverTemplatePath = deedObject->getGeneratedObjectTemplate(); StructureManager* structureManager = StructureManager::instance(); ManagedReference<StructureObject*> structureObject = structureManager->placeStructure(creatureObject, serverTemplatePath, positionX, positionY, directionAngle); removeTemporaryNoBuildZone(); if (structureObject == NULL) { ManagedReference<SceneObject*> inventory = creatureObject->getSlottedObject("inventory"); if (inventory != NULL) inventory->transferObject(deedObject, -1, true); return cancelSession(); } structureObject->setDeedObjectID(deedObject->getObjectID()); deedObject->notifyStructurePlaced(creatureObject, structureObject); ManagedReference<PlayerObject*> ghost = creatureObject->getPlayerObject(); if (ghost != NULL) { ghost->addOwnedStructure(structureObject); //Create Waypoint ManagedReference<WaypointObject*> waypointObject = ( zone->getZoneServer()->createObject(String("object/waypoint/world_waypoint_blue.iff").hashCode(), 1)).castTo<WaypointObject*>(); waypointObject->setCustomObjectName(structureObject->getDisplayedName(), false); waypointObject->setActive(true); waypointObject->setPosition(positionX, 0, positionY); waypointObject->setPlanetCRC(zone->getZoneCRC()); ghost->addWaypoint(waypointObject, false, true); //Create an email. ManagedReference<ChatManager*> chatManager = zone->getZoneServer()->getChatManager(); if (chatManager != NULL) { UnicodeString subject = "@player_structure:construction_complete_subject"; StringIdChatParameter emailBody("@player_structure:construction_complete"); emailBody.setTO(structureObject->getObjectName()); emailBody.setDI(ghost->getLotsRemaining()); chatManager->sendMail("@player_structure:construction_complete_sender", subject, emailBody, creatureObject->getFirstName(), waypointObject); } if (structureObject->isBuildingObject() && !structureObject->isGCWBase()) { BuildingObject* building = cast<BuildingObject*>(structureObject.get()); building->setCustomObjectName(creatureObject->getFirstName() + "'s House", true); //Set the house sign. } } return cancelSession(); //Canceling the session just removes the session from the player's map. }
Reference<SceneObject*> PlanetManagerImplementation::loadSnapshotObject(WorldSnapshotNode* node, WorldSnapshotIff* wsiff, int& totalObjects) { uint64 objectID = node->getObjectID(); String templateName = wsiff->getObjectTemplateName(node->getNameID()); ZoneServer* zoneServer = server->getZoneServer(); Reference<SceneObject*> object = zoneServer->getObject(objectID); ++totalObjects; if (ConfigManager::instance()->isProgressMonitorActivated()) printf("\r\tLoading snapshot objects: [%d] / [?]\t", totalObjects); //Object already exists, exit. if (object != NULL) return NULL; Reference<SceneObject*> parentObject = zoneServer->getObject(node->getParentID()); String serverTemplate = templateName.replaceFirst("shared_", ""); Vector3 position = node->getPosition(); object = zoneServer->createClientObject(serverTemplate.hashCode(), objectID); object->initializePosition(position.getX(), position.getZ(), position.getY()); object->setDirection(node->getDirection()); if (parentObject != NULL && parentObject->isBuildingObject() && object->isCellObject()) { CellObject* cell = cast<CellObject*>(object.get()); BuildingObject* building = cast<BuildingObject*>(parentObject.get()); building->addCell(cell, node->getCellID()); } if (parentObject != NULL) parentObject->transferObject(object, -1); else if (node->getParentID() != 0) error("parent id " + String::valueOf(node->getParentID())); if (parentObject == NULL) { //object->insertToZone(zone); Locker clocker(object); zone->transferObject(object, -1, true); } //Load child nodes for (int i = 0; i < node->getNodeCount(); ++i) { WorldSnapshotNode* childNode = node->getNode(i); if (childNode == NULL) continue; loadSnapshotObject(childNode, wsiff, totalObjects); } //object->createChildObjects(); return object; }
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(); }
BuildingObject* BuildingFactory::_createBuilding(DatabaseResult* result) { BuildingObject* buildingObject = new BuildingObject(); uint64 count = result->getRowCount(); result->GetNextRow(mBuildingBinding,buildingObject); buildingObject->setLoadState(LoadState_Loaded); buildingObject->setPlayerStructureFamily(PlayerStructure_TreBuilding); return buildingObject; }
void PlanetManagerImplementation::loadPlanetObjects(LuaObject* luaObject) { if (!luaObject->isValidTable()) return; for (int i = 1; i <= luaObject->getTableSize(); ++i) { lua_State* L = luaObject->getLuaState(); lua_rawgeti(L, -1, i); LuaObject planetObject(L); String templateFile = planetObject.getStringField("templateFile"); ManagedReference<SceneObject*> obj = ObjectManager::instance()->createObject(templateFile.hashCode(), 0, ""); if (obj != NULL) { Locker objLocker(obj); float x = planetObject.getFloatField("x"); float y = planetObject.getFloatField("y"); float z = planetObject.getFloatField("z"); float ox = planetObject.getFloatField("ox"); float oy = planetObject.getFloatField("oy"); float oz = planetObject.getFloatField("oz"); float ow = planetObject.getFloatField("ow"); uint64 parentID = planetObject.getLongField("parent"); if (obj->isBuildingObject()) { BuildingObject* building = obj->asBuildingObject(); building->createCellObjects(); } obj->initializePosition(x, z, y); obj->setDirection(ow, ox, oy, oz); ManagedReference<SceneObject*> parent = zone->getZoneServer()->getObject(parentID); if (parent != NULL) parent->transferObject(obj, -1, true); else zone->transferObject(obj, -1, true); obj->createChildObjects(); } planetObject.pop(); } }
BuildingObject* BuildingFactory::_createBuilding(swganh::database::DatabaseResult* result) { if (!result->getRowCount()) { return nullptr; } BuildingObject* buildingObject = new BuildingObject(); result->getNextRow(mBuildingBinding,buildingObject); //buildingObject->SetTemplate(buildingObject->mModel.getAnsi()); buildingObject->setLoadState(LoadState_Loaded); buildingObject->setPlayerStructureFamily(PlayerStructure_TreBuilding); gObjectManager->LoadSlotsForObject(buildingObject); return buildingObject; }
int CellObjectImplementation::canAddObject(SceneObject* object, int containmentType, String& errorDescription) { ManagedReference<SceneObject*> strongParent = getParent().get(); if (strongParent != NULL && strongParent->isBuildingObject()) { BuildingObject* building = strongParent->asBuildingObject(); int count = 1; if (object->isVendor()) count = 0; else if (object->isContainerObject()) count += object->getCountableObjectsRecursive(); if (building->getCurrentNumberOfPlayerItems() + count > building->getMaximumNumberOfPlayerItems()) { errorDescription = "@container_error_message:container13"; return TransferErrorCode::TOOMANYITEMSINHOUSE; } } return SceneObjectImplementation::canAddObject(object, containmentType, errorDescription); }
bool CellObjectImplementation::transferObject(SceneObject* object, int containmentType, bool notifyClient, bool allowOverflow) { //Locker locker(_this); Zone* zone = getZone(); Locker* locker = NULL; if (zone != NULL) { // locker = new Locker(zone); } bool ret = false; ManagedReference<SceneObject*> oldParent = object->getParent(); try { ret = SceneObjectImplementation::transferObject(object, containmentType, notifyClient, allowOverflow); if (zone != NULL && object->isTangibleObject()) { TangibleObject* tano = cast<TangibleObject*>(object); zone->updateActiveAreas(tano); } } catch (...) { } if (oldParent == NULL) { BuildingObject* building = cast<BuildingObject*>(parent.get().get()); CreatureObject* creo = cast<CreatureObject*>(object); if (building != NULL && creo != NULL) building->onEnter(creo); } if (locker != NULL) delete locker; return ret; }
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(); }); }
//********************************************************************* //a simple Object can only be in the grid *or* in the cell //it can be equipped however by a creature / player void SpatialIndexManager::RemoveObjectFromWorld(Object *removeObject) { DLOG(info) << "SpatialIndexManager::RemoveObjectFromWorld:: Object : " << removeObject->getId(); //were in a container - get us out if(removeObject->getParentId()) { Object* container = gWorldManager->getObjectById(removeObject->getParentId()); if(container) { if(CreatureObject* owner = dynamic_cast<CreatureObject*>(container)) { // remove from creatures slotmap owner->getEquipManager()->removeEquippedObject(removeObject); // send out the new equiplist gMessageLib->sendEquippedListUpdate_InRange(owner); } //update the world on our changes gContainerManager->destroyObjectToRegisteredPlayers(container,removeObject->getId()); //remove the object out of the container container->removeObject(removeObject); } //no need to remove a tangible(!) from the grid if it was in a cell return; } //if we are a building we need to prepare for destruction BuildingObject* building = dynamic_cast<BuildingObject*>(removeObject); if(building) { building->prepareDestruction(); } //remove it out of the grid _RemoveObjectFromGrid(removeObject); }
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); }); }
int ContainerImplementation::canAddObject(SceneObject* object, int containmentType, String& errorDescription) { // if (locked) // return TransferErrorCode::CONTAINERLOCKED; if ((object->isIntangibleObject() && getContainerType() != 3) || (getContainerType() == 3 && !object->isIntangibleObject())) { errorDescription = "@container_error_message:container07"; // You cannot put that kind of item in that kind of container. return TransferErrorCode::INVALIDTYPE; } if (containmentType == -1) { if ((gameObjectType == SceneObjectType::WEARABLECONTAINER && object->getGameObjectType() == SceneObjectType::WEARABLECONTAINER)) { errorDescription = "@container_error_message:container12"; // This item is too bulky to fit inside this container. return TransferErrorCode::CANTNESTOBJECT; } if (object->isContainerObject() && getArrangementDescriptorSize() == 0) { errorDescription = "@container_error_message:container12"; // This item is too bulky to fit inside this container. return TransferErrorCode::CANTNESTOBJECT; } // Find out how much room we need int objectSize; if (object->isContainerObject()) objectSize = object->getContainerObjectsSize() + 1; else objectSize = 1; // Return if there's not enough room in the container if (getContainerVolumeLimit() < getCountableObjectsRecursive() + objectSize) { errorDescription = "@container_error_message:container03"; // This container is full. return TransferErrorCode::CONTAINERFULL; } ManagedReference<SceneObject*> wearableParent = getParentRecursively(SceneObjectType::WEARABLECONTAINER); ManagedReference<SceneObject*> playerParent = getParentRecursively(SceneObjectType::PLAYERCREATURE); // If there's a wearable container parent, return if it doesn't have enough room if (wearableParent != NULL) { if (wearableParent->getContainerVolumeLimit() < wearableParent->getCountableObjectsRecursive() + objectSize) { errorDescription = "@container_error_message:container03"; // This container is full. return TransferErrorCode::CONTAINERFULL; } // It has room. Check if it's not equipped and on a player. ManagedReference<WearableContainerObject*> wearable = cast<WearableContainerObject*>(wearableParent.get()); if (!wearable->isEquipped() && playerParent != NULL) { SceneObject* inventory = playerParent->getSlottedObject("inventory"); SceneObject* bank = playerParent->getSlottedObject("bank"); SceneObject* parentOfWearableParent = wearable->getParent().get(); // Return if it's in a player inventory which doesn't have room if (parentOfWearableParent == inventory) { if (inventory->getContainerVolumeLimit() < inventory->getCountableObjectsRecursive() + objectSize) { errorDescription = "@error_message:inv_full"; // Your inventory is full. return TransferErrorCode::CONTAINERFULL; } // Return if it's in a player bank that doesn't have room } else if (parentOfWearableParent == bank) { if (bank->getContainerVolumeLimit() < bank->getCountableObjectsRecursive() + objectSize) { errorDescription = "@container_error_message:container03"; // This container is full. return TransferErrorCode::CONTAINERFULL; } } } } else { // There's no parent that's a wearable container. Check if this is if (gameObjectType == SceneObjectType::WEARABLECONTAINER) { WearableContainerObject* pack = cast<WearableContainerObject*>(_this.getReferenceUnsafeStaticCast()); if (pack != NULL && !pack->isEquipped()) { // This is a wearable container, and it's not equipped. if (playerParent != NULL ) { SceneObject* inventory = playerParent->getSlottedObject("inventory"); SceneObject* bank = playerParent->getSlottedObject("bank"); SceneObject* thisParent = getParent().get(); // Return if the container is in a player inventory without room if (thisParent == inventory) { if (inventory->getContainerVolumeLimit() < inventory->getCountableObjectsRecursive() + objectSize) { errorDescription = "@error_message:inv_full"; // Your inventory is full. return TransferErrorCode::CONTAINERFULL; } // Return if it's in a player bank that doesn't have room } else if (thisParent == bank) { if (bank->getContainerVolumeLimit() < bank->getCountableObjectsRecursive() + objectSize) { errorDescription = "@container_error_message:container03"; // This container is full. return TransferErrorCode::CONTAINERFULL; } } } } } else { // This is a non-wearable container. if (playerParent != NULL ) { SceneObject* inventory = playerParent->getSlottedObject("inventory"); SceneObject* bank = playerParent->getSlottedObject("bank"); SceneObject* thisParent = getParent().get(); // Return if the container is in a player inventory without room if (thisParent == inventory) { if (inventory->getContainerVolumeLimit() < inventory->getCountableObjectsRecursive() + objectSize) { errorDescription = "@error_message:inv_full"; // Your inventory is full. return TransferErrorCode::CONTAINERFULL; } // Return if it's in a player bank that doesn't have room } else if (thisParent == bank) { if (bank->getContainerVolumeLimit() < bank->getCountableObjectsRecursive() + objectSize) { errorDescription = "@container_error_message:container03"; // This container is full. return TransferErrorCode::CONTAINERFULL; } } } } } // Check if the container is in a building or factory ingredient hopper if (playerParent == NULL) { ManagedReference<SceneObject*> rootParent = getRootParent(); if (rootParent != NULL) { if (rootParent->isBuildingObject()) { BuildingObject* building = rootParent.castTo<BuildingObject*>(); if (!building->isStaticBuilding() && (building->getCurrentNumberOfPlayerItems() + objectSize > building->getMaximumNumberOfPlayerItems())) { errorDescription = "@container_error_message:container13"; // This house has too many items in it return TransferErrorCode::TOOMANYITEMSINHOUSE; } } else if (rootParent->isFactory()) { FactoryObject* factory = rootParent.castTo<FactoryObject*>(); SceneObject* hopper = factory->getSlottedObject("ingredient_hopper"); if (hopper->getContainerVolumeLimit() < hopper->getCountableObjectsRecursive() + objectSize) { errorDescription = "@container_error_message:container03"; // This container is full. return TransferErrorCode::CONTAINERFULL; } } } } ManagedReference<SceneObject*> myParent = getParent(); ManagedReference<SceneObject*> otherParent = object->getParent(); if (myParent != NULL && otherParent != NULL) { if (otherParent->isCreatureObject()) { AiAgent* ai = dynamic_cast<AiAgent*>(otherParent.get()); if (ai != NULL) { SceneObject* creatureInventory = ai->getSlottedObject("inventory"); if (creatureInventory != NULL) { uint64 lootOwnerID = creatureInventory->getContainerPermissions()->getOwnerID(); if (lootOwnerID != myParent->getObjectID()) { errorDescription = "@group:no_loot_permission"; return TransferErrorCode::NOLOOTPERMISSION; } } } } } } return TangibleObjectImplementation::canAddObject(object, containmentType, errorDescription); }
void BuildingController::handleMessage (int message, float value, const MessageQueue::Data* data, uint32 flags) { BuildingObject * owner = dynamic_cast<BuildingObject *>(getOwner()); NOT_NULL(owner); switch (message) { case CM_addAllowed: { const MessageQueueGenericValueType<std::string> * const msg = safe_cast<const MessageQueueGenericValueType<std::string> *>(data); if(msg) { owner->addAllowed(msg->getValue()); } } break; case CM_removeAllowed: { const MessageQueueGenericValueType<std::string> * const msg = safe_cast<const MessageQueueGenericValueType<std::string> *>(data); if(msg) { owner->removeAllowed(msg->getValue()); } } break; case CM_addBanned: { const MessageQueueGenericValueType<std::string> * const msg = safe_cast<const MessageQueueGenericValueType<std::string> *>(data); if(msg) { owner->addBanned(msg->getValue()); } } break; case CM_removeBanned: { const MessageQueueGenericValueType<std::string> * const msg = safe_cast<const MessageQueueGenericValueType<std::string> *>(data); if(msg) { owner->removeBanned(msg->getValue()); } } break; case CM_setBuildingIsPublic: { MessageQueueGenericValueType<bool> const *msg = safe_cast<MessageQueueGenericValueType<bool> const *>(data); if (msg) owner->setIsPublic(msg->getValue()); } break; case CM_setBuildingCityId: { MessageQueueGenericValueType<int> const *msg = safe_cast<MessageQueueGenericValueType<int> const *>(data); if (msg) owner->setCityId(msg->getValue()); } break; default: TangibleController::handleMessage(message, value, data, flags); break; } }
void StructureManager::reportStructureStatus(CreatureObject* creature, StructureObject* structure) { ManagedReference<PlayerObject*> ghost = creature->getPlayerObject(); if (ghost == NULL) return; //Close the window if it is already open. ghost->closeSuiWindowType(SuiWindowType::STRUCTURE_STATUS); ManagedReference<SuiListBox*> status = new SuiListBox(creature, SuiWindowType::STRUCTURE_STATUS); status->setPromptTitle("@player_structure:structure_status_t"); //Structure Status status->setPromptText( "@player_structure:structure_name_prompt " + structure->getDisplayedName()); //Structure Name: status->setUsingObject(structure); status->setOkButton(true, "@refresh"); status->setCancelButton(true, "@cancel"); status->setCallback(new StructureStatusSuiCallback(server)); ManagedReference<SceneObject*> ownerObject = server->getObject( structure->getOwnerObjectID()); if (ownerObject != NULL && ownerObject->isCreatureObject()) { CreatureObject* owner = cast<CreatureObject*>(ownerObject.get()); status->addMenuItem( "@player_structure:owner_prompt " + owner->getFirstName()); } uint64 declaredOidResidence = ghost->getDeclaredResidence(); ManagedReference<BuildingObject*> declaredResidence = server->getObject(declaredOidResidence).castTo<BuildingObject*>(); if (declaredResidence == structure) { status->addMenuItem("@player_structure:declared_residency"); //You have declared your residency here. } if (structure->isPrivateStructure() && !structure->isCivicStructure()) { status->addMenuItem("@player_structure:structure_private"); //This structure is private } else { status->addMenuItem("@player_structure:structure_public"); //This structure is public } status->addMenuItem( "@player_structure:condition_prompt " + String::valueOf(structure->getDecayPercentage()) + "%"); if (!structure->isCivicStructure()) { // property tax float propertytax = 0.f; if(!structure->isCivicStructure() && structure->getCityRegion() != NULL){ ManagedReference<CityRegion*> city = structure->getCityRegion().get(); if(city != NULL){ propertytax = city->getPropertyTax()/ 100.f * structure->getMaintenanceRate(); status->addMenuItem( "@city/city:property_tax_prompt : " + String::valueOf(ceil(propertytax)) + " cr/hr"); } } // maintenance float secsRemainingMaint = 0.f; if( structure->getSurplusMaintenance() > 0 ){ float totalrate = (float)structure->getMaintenanceRate() + propertytax; secsRemainingMaint = ((float)structure->getSurplusMaintenance() / totalrate)*3600; } status->addMenuItem( "@player_structure:maintenance_pool_prompt " + String::valueOf( (int) floor( (float) structure->getSurplusMaintenance())) + " " + getTimeString( (uint32)secsRemainingMaint ) ); status->addMenuItem( "@player_structure:maintenance_rate_prompt " + String::valueOf(structure->getMaintenanceRate()) + " cr/hr"); status->addMenuItem( "@player_structure:maintenance_mods_prompt " + structure->getMaintenanceMods()); } if (structure->isInstallationObject() && !structure->isGeneratorObject() && !structure->isCivicStructure()) { InstallationObject* installation = cast<InstallationObject*>(structure); float secsRemainingPower = 0.f; if( installation->getSurplusPower() > 0 ){ secsRemainingPower = ((float)installation->getSurplusPower() / (float)installation->getBasePowerRate())*3600; } status->addMenuItem( "@player_structure:power_reserve_prompt " + String::valueOf( (int) installation->getSurplusPower()) + " " + getTimeString( (uint32)secsRemainingPower ) ); status->addMenuItem( "@player_structure:power_consumption_prompt " + String::valueOf( (int) installation->getBasePowerRate()) + " @player_structure:units_per_hour"); } if (structure->isBuildingObject()) { BuildingObject* building = cast<BuildingObject*>(structure); status->addMenuItem( "@player_structure:items_in_building_prompt " + String::valueOf( building->getCurrentNumberOfPlayerItems())); //Number of Items in Building: } ghost->addSuiBox(status); creature->sendMessage(status->generateMessage()); }
StructureObject* StructureManager::placeStructure(CreatureObject* creature, const String& structureTemplatePath, float x, float y, int angle, int persistenceLevel) { ManagedReference<Zone*> zone = creature->getZone(); if (zone == NULL) return NULL; TerrainManager* terrainManager = zone->getPlanetManager()->getTerrainManager(); SharedStructureObjectTemplate* serverTemplate = dynamic_cast<SharedStructureObjectTemplate*>(templateManager->getTemplate( structureTemplatePath.hashCode())); if (serverTemplate == NULL) { info("server template is null"); return NULL; } float z = zone->getHeight(x, y); float floraRadius = serverTemplate->getClearFloraRadius(); bool snapToTerrain = serverTemplate->getSnapToTerrain(); Reference<StructureFootprint*> structureFootprint = serverTemplate->getStructureFootprint(); float w0 = -5; //Along the x axis. float l0 = -5; //Along the y axis. float l1 = 5; float w1 = 5; float zIncreaseWhenNoAvailableFootprint = 0.f; //TODO: remove this when it has been verified that all buildings have astructure footprint. if (structureFootprint != NULL) { //If the angle is odd, then swap them. getStructureFootprint(serverTemplate, angle, l0, w0, l1, w1); } else { if (!serverTemplate->isCampStructureTemplate()) warning( "Structure with template '" + structureTemplatePath + "' has no structure footprint."); zIncreaseWhenNoAvailableFootprint = 5.f; } if (floraRadius > 0 && !snapToTerrain) z = terrainManager->getHighestHeight(x + w0, y + l0, x + w1, y + l1, 1) + zIncreaseWhenNoAvailableFootprint; String strDatabase = "playerstructures"; bool bIsFactionBuilding = (serverTemplate->getGameObjectType() == SceneObjectType::FACTIONBUILDING); if (bIsFactionBuilding || serverTemplate->getGameObjectType() == SceneObjectType::TURRET) { strDatabase = "playerstructures"; } ManagedReference<SceneObject*> obj = ObjectManager::instance()->createObject( structureTemplatePath.hashCode(), persistenceLevel, strDatabase); if (obj == NULL || !obj->isStructureObject()) { if (obj != NULL) obj->destroyObjectFromDatabase(true); error( "Failed to create structure with template: " + structureTemplatePath); return NULL; } StructureObject* structureObject = cast<StructureObject*>(obj.get()); structureObject->setOwnerObjectID(creature->getObjectID()); structureObject->grantPermission("ADMIN", creature->getFirstName()); structureObject->setOwnerName(creature->getFirstName()); if(structureObject->isTurret() || structureObject->isMinefield()){ structureObject->setFaction(creature->getFaction()); } BuildingObject* buildingObject = NULL; if (structureObject->isBuildingObject()) { buildingObject = cast<BuildingObject*>(structureObject); if (buildingObject != NULL) buildingObject->createCellObjects(); } structureObject->setPublicStructure(serverTemplate->isPublicStructure()); structureObject->initializePosition(x, z, y); structureObject->rotate(angle); //structureObject->insertToZone(zone); zone->transferObject(structureObject, -1, true); structureObject->createChildObjects(); structureObject->notifyStructurePlaced(creature); return structureObject; }
void ObjectController::destroyObject(uint64 objectId) { PlayerObject* playerObject = dynamic_cast<PlayerObject*>(mObject); Datapad* datapad = playerObject->getDataPad(); Object* object = gWorldManager->getObjectById(objectId); //could be a schematic! ManufacturingSchematic* schem = datapad->getManufacturingSchematicById(objectId); if(schem != NULL) { //delete schematic datapad->removeManufacturingSchematic(objectId); //delete schematic object gObjectFactory->deleteObjectFromDB(schem); gMessageLib->sendDestroyObject(objectId,playerObject); return; } // could be a waypoint if(object == NULL) { object = datapad->getWaypointById(objectId); } // or something else if(object == NULL) { gLogger->log(LogManager::DEBUG,"ObjController::destroyObject: could not find object %"PRIu64"",objectId); return; } // waypoint if(object->getType() == ObjType_Waypoint) { // update our datapad if(!(datapad->removeWaypoint(objectId))) { gLogger->log(LogManager::DEBUG,"ObjController::handleDestroyObject: Error removing Waypoint from datapad %"PRIu64"",objectId); } gMessageLib->sendUpdateWaypoint(dynamic_cast<WaypointObject*>(object),ObjectUpdateDelete,playerObject); // delete from db gObjectFactory->deleteObjectFromDB(object); delete(object); } //Inangible Objects if(object->getType() == ObjType_Intangible) { //update the datapad if(!(datapad->removeData(objectId))) { gLogger->log(LogManager::DEBUG,"ObjController::handleDestroyObject: Error removing Data from datapad %"PRIu64"",objectId); } if(VehicleController* vehicle = dynamic_cast<VehicleController*>(object)) { vehicle->Store(); } gObjectFactory->deleteObjectFromDB(object); gMessageLib->sendDestroyObject(objectId,playerObject); delete(object); } // tangible else if(object->getType() == ObjType_Tangible) { TangibleObject* tangibleObject = dynamic_cast<TangibleObject*>(object); BuildingObject* building = dynamic_cast<BuildingObject*>(tangibleObject->getObjectMainParent(tangibleObject)); if(building) { if(!building->hasAdminRights(playerObject->getId())) { return; } } if(tangibleObject->getParentId() == 0) { return; } Inventory* inventory = dynamic_cast<Inventory*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory)); // items if(Item* item = dynamic_cast<Item*>(tangibleObject)) { // handle any family specifics switch(item->getItemFamily()) { case ItemFamily_CraftingTools: _handleDestroyCraftingTool(dynamic_cast<CraftingTool*>(item)); break; case ItemFamily_Instrument: _handleDestroyInstrument(item); break; default: break; } // update the equiplist, if its an equipable item CreatureObject* creature = dynamic_cast<CreatureObject*>(gWorldManager->getObjectById(item->getParentId())); if(creature) { // remove from creatures slotmap creature->getEquipManager()->removeEquippedObject(object); //unequip it object->setParentId(inventory->getId()); gMessageLib->sendContainmentMessage_InRange(object->getId(),inventory->getId(),0xffffffff,creature); // send out the new equiplist gMessageLib->sendEquippedListUpdate_InRange(creature); } } //tangible includes items and resourcecontainers if(tangibleObject) { //if(tangible->getObjectMainParent(object) != inventory->getId()) if(tangibleObject->getKnownPlayers()->size()) { //this automatically destroys the object for the players in its vicinity tangibleObject->destroyKnownObjects(); } else { // destroy it for the player gMessageLib->sendDestroyObject(objectId,playerObject); } } // reset pending ui callbacks playerObject->resetUICallbacks(object); // delete from db CAVE :: mark if its an Object saved in the db!!!! // temporary placed instruments are not saved in the db gObjectFactory->deleteObjectFromDB(object); //it might be in a cell or in a container or in the inventory :) ObjectContainer* oc = dynamic_cast<ObjectContainer*>(gWorldManager->getObjectById(object->getParentId())); if(oc) { oc->deleteObject(object); } else { gWorldManager->destroyObject(object); } } }
void CityRegionImplementation::notifyExit(SceneObject* object) { //pre: no 2 different city regions should ever overlap, only 2 Regions of the same city region if (object->isTangibleObject()) { TangibleObject* tano = cast<TangibleObject*>(object); ManagedReference<Region*> activeRegion = tano->getActiveRegion().castTo<Region*>(); if (activeRegion != NULL) { ManagedReference<CityRegion*> city = activeRegion->getCityRegion(); object->setCityRegion(city); if (city == _this.getReferenceUnsafeStaticCast()) // if its the same city we wait till the object exits the last region return; } else { object->setCityRegion(NULL); } } else { object->setCityRegion(NULL); } if (object->isBazaarTerminal() || object->isVendor()) { if (object->isBazaarTerminal()) bazaars.drop(object->getObjectID()); AuctionTerminalDataComponent* terminalData = NULL; DataObjectComponentReference* data = object->getDataObjectComponent(); if(data != NULL && data->get() != NULL && data->get()->isAuctionTerminalData()) terminalData = cast<AuctionTerminalDataComponent*>(data->get()); if(terminalData != NULL) terminalData->updateUID(); } if (object->isPlayerCreature()) currentPlayers.decrement(); if (isClientRegion()) return; if (object->isCreatureObject()) { CreatureObject* creature = cast<CreatureObject*>(object); StringIdChatParameter params("city/city", "city_leave_city"); //You have left %TO. params.setTO(getRegionName()); creature->sendSystemMessage(params); removeSpecializationModifiers(creature); } if (object->isStructureObject()) { float x = object->getWorldPositionX(); float y = object->getWorldPositionY(); StructureObject* structure = cast<StructureObject*>(object); Locker slocker(&structureListMutex); if (structure->isBuildingObject()) { BuildingObject* building = cast<BuildingObject*>(object); uint64 ownerID = structure->getOwnerObjectID(); ZoneServer* zoneServer = building->getZoneServer(); if (zoneServer != NULL) { ManagedReference<CreatureObject*> owner = zoneServer->getObject(ownerID).castTo<CreatureObject*>(); if(owner != NULL && owner->isPlayerCreature() && building->isResidence() && isCitizen(ownerID)) { CityManager* cityManager = zoneServer->getCityManager(); cityManager->unregisterCitizen(_this.getReferenceUnsafeStaticCast(), owner); } } } completeStructureList.drop(structure->getObjectID()); if (structure->isCivicStructure()) { removeStructure(structure); } else if (structure->isCommercialStructure()) { removeCommercialStructure(structure); } } if (object->isDecoration() && object->getParent().get() == NULL) { removeDecoration(object); } }
void CityRegionImplementation::notifyEnter(SceneObject* object) { if (object->getCityRegion().get() != _this.getReferenceUnsafeStaticCast() && object->isPlayerCreature()) currentPlayers.increment(); object->setCityRegion(_this.getReferenceUnsafeStaticCast()); if (object->isBazaarTerminal() || object->isVendor()) { if (object->isBazaarTerminal()) bazaars.put(object->getObjectID(), cast<TangibleObject*>(object)); AuctionTerminalDataComponent* terminalData = NULL; DataObjectComponentReference* data = object->getDataObjectComponent(); if(data != NULL && data->get() != NULL && data->get()->isAuctionTerminalData()) terminalData = cast<AuctionTerminalDataComponent*>(data->get()); if(terminalData != NULL) terminalData->updateUID(); } if (isClientRegion()) return; if (object->isCreatureObject()) { CreatureObject* creature = cast<CreatureObject*>(object); StringIdChatParameter params("city/city", "city_enter_city"); //You have entered %TT (%TO). params.setTT(getRegionName()); UnicodeString strRank = StringIdManager::instance()->getStringId(String("@city/city:rank" + String::valueOf(cityRank)).hashCode()); if (citySpecialization.isEmpty()) { params.setTO(strRank); } else { UnicodeString citySpec = StringIdManager::instance()->getStringId(citySpecialization.hashCode()); params.setTO(strRank + ", " + citySpec); } creature->sendSystemMessage(params); applySpecializationModifiers(creature); } if (object->isStructureObject()) { StructureObject* structure = cast<StructureObject*>(object); CityManager* cityManager = getZone()->getZoneServer()->getCityManager(); Locker slocker(&structureListMutex); if (isLoaded() && !completeStructureList.contains(structure->getObjectID()) && structure->getBaseMaintenanceRate() > 0) { cityManager->sendAddStructureMails(_this.getReferenceUnsafeStaticCast(), structure); } if (structure->isBuildingObject()) { BuildingObject* building = cast<BuildingObject*>(object); uint64 ownerID = structure->getOwnerObjectID(); ManagedReference<CreatureObject*> owner = zone->getZoneServer()->getObject(ownerID).castTo<CreatureObject*>(); if(owner != NULL && owner->isPlayerCreature() && building->isResidence() && !isCitizen(ownerID)) { cityManager->registerCitizen(_this.getReferenceUnsafeStaticCast(), owner); } } completeStructureList.put(structure->getObjectID()); if (structure->isCivicStructure() && !structure->isDecoration()) { addStructure(structure); } else if (structure->isCommercialStructure()) { addCommercialStructure(structure); } if (registered) { zone->registerObjectWithPlanetaryMap(structure); } } if (object->isDecoration() && object->getParent().get() == NULL) { addDecoration(object); } if (registered && cityMissionTerminals.contains(object)) { zone->registerObjectWithPlanetaryMap(object); } if (!registered && citySkillTrainers.contains(object)) { zone->unregisterObjectWithPlanetaryMap(object); } }
void StructureMaintenanceTask::run() { ManagedReference<StructureObject*> strongRef = structureObject.get(); if (strongRef == NULL) return; ZoneServer* zoneServer = strongRef->getZoneServer(); if (zoneServer != NULL && zoneServer->isServerLoading()) { schedule(1000); return; } ManagedReference<CreatureObject*> owner = strongRef->getOwnerCreatureObject(); if (owner == NULL || !owner->isPlayerCreature()) { info("Player structure has NULL owner, destroying.", true); StructureManager::instance()->destroyStructure(strongRef); return; } ManagedReference<PlayerObject*> ghost = owner->getPlayerObject(); if (ghost == NULL) { info("Player structure has NULL owner ghost, destroying.", true); StructureManager::instance()->destroyStructure(strongRef); return; } if (!ghost->isOwnedStructure(strongRef)) { info("Removing orphaned structure.", true); StructureManager::instance()->destroyStructure(strongRef); return; } if (strongRef->getSurplusMaintenance() > 0) { //Incorrect scheduling, reschedule. Locker locker(strongRef); strongRef->scheduleMaintenanceExpirationEvent(); return; } Locker _ownerLock(owner); Locker _lock(strongRef, owner); //Structure is out of maintenance. Start the decaying process... strongRef->updateStructureStatus(); //Calculate one week of maintenance +- any existing maintenance/decay. int oneWeekMaintenance = 7 * 24 * strongRef->getMaintenanceRate() - strongRef->getSurplusMaintenance(); // add city tax to the week maintenance ManagedReference<CityRegion*> city = strongRef->getCityRegion(); if(strongRef->isBuildingObject() && city != NULL){ oneWeekMaintenance += city->getPropertyTax() / 100.0f * oneWeekMaintenance; } //Check if owner got money in the bank and structure not decaying. if (owner->getBankCredits() >= oneWeekMaintenance) { //Withdraw 1 week maintenance from owner bank account and add to the structure //maintenance pool. strongRef->payMaintenance(oneWeekMaintenance, owner, false); //Send email notification to owner. sendMailMaintenanceWithdrawnFromBank(owner, strongRef); //Reschedule task in 1 week. strongRef->scheduleMaintenanceExpirationEvent(); } else { //Start decay process. //Notify owner about decay. sendMailDecay(owner, strongRef); if (!strongRef->isDecayed()) { //Reschedule task in 1 day. reschedule(oneDayTime); } else { if (strongRef->isBuildingObject() && !shouldBuildingBeDestroyed(strongRef)) { BuildingObject* building = strongRef.castTo<BuildingObject*>(); //Building is condemned since it has decayed. sendMailCondemned(owner, strongRef); strongRef->info("Structure decayed, it is now condemned."); building->updateSignName(true); } else { strongRef->info("Structure decayed, destroying it."); StructureManager::instance()->destroyStructure(strongRef); } } } }
void WorldManager::destroyObject(Object* object) { switch(object->getType()) { case ObjType_Player: { //destroys knownObjects in the destructor PlayerObject* player = dynamic_cast<PlayerObject*>(object); // moved most of the code to the players destructor // onPlayerLeft event, notify scripts string params; params.setLength(sprintf(params.getAnsi(),"%s %s %u",getPlanetNameThis(),player->getFirstName().getAnsi(),static_cast<uint32>(mPlayerAccMap.size()))); mWorldScriptsListener.handleScriptEvent("onPlayerLeft",params); // gLogger->logMsg("WorldManager::destroyObject: Player Client set to NULL"); delete player->getClient(); player->setClient(NULL); player->setConnectionState(PlayerConnState_Destroying); } break; case ObjType_NPC: case ObjType_Creature: { CreatureObject* creature = dynamic_cast<CreatureObject*>(object); // remove any timers we got running removeCreatureHamToProcess(creature->getHam()->getTaskId()); // remove from cell / SI if (!object->getParentId()) { // Not all objects-creatures of this type are points. if(creature->getSubZoneId()) { if(QTRegion* region = getQTRegion(creature->getSubZoneId())) { creature->setSubZoneId(0); region->mTree->removeObject(creature); } } else { mSpatialIndex->RemovePoint(object->getId(),object->mPosition.x,object->mPosition.z); } } else { if(CellObject* cell = dynamic_cast<CellObject*>(getObjectById(object->getParentId()))) { cell->removeObject(object); } else { //gLogger->logMsgF("WorldManager::destroyObject: couldn't find cell %"PRIu64"",MSG_HIGH,object->getParentId()); } } // destroy known objects object->destroyKnownObjects(); // if its a shuttle, remove it from the shuttle list if(creature->getCreoGroup() == CreoGroup_Shuttle) { ShuttleList::iterator shuttleIt = mShuttleList.begin(); while(shuttleIt != mShuttleList.end()) { if((*shuttleIt)->getId() == creature->getId()) { mShuttleList.erase(shuttleIt); break; } ++shuttleIt; } } } break; case ObjType_Structure: { // cave what do we do with player cities ?? // then the parent Id should be the region object. shouldnt it???? if(object->getSubZoneId()) { if(QTRegion* region = getQTRegion(object->getSubZoneId())) { object->setSubZoneId(0); region->mTree->removeObject(object); } } else { mSpatialIndex->RemovePoint(object->getId(),object->mPosition.x,object->mPosition.z); } object->destroyKnownObjects(); //remove it out of the worldmanagers structurelist now that it is deleted ObjectIDList::iterator itStruct = mStructureList.begin(); while(itStruct != mStructureList.end()) { if((*itStruct)==object->getId()) itStruct = mStructureList.erase(itStruct); else itStruct++; } } break; case ObjType_Building: { BuildingObject* building = dynamic_cast<BuildingObject*>(object); if(building) { if(object->getSubZoneId()) { if(QTRegion* region = getQTRegion(object->getSubZoneId())) { object->setSubZoneId(0); region->mTree->removeObject(object); } } else { //mSpatialIndex->InsertRegion(key,building->mPosition.x,building->mPosition.z,building->getWidth(),building->getHeight()); mSpatialIndex->RemoveRegion(object->getId(),object->mPosition.x-building->getWidth(),object->mPosition.z-building->getHeight(),object->mPosition.x+building->getWidth(),object->mPosition.z+building->getHeight()); } //remove it out of the worldmanagers structurelist now that it is deleted ObjectIDList::iterator itStruct = mStructureList.begin(); while(itStruct != mStructureList.end()) { if((*itStruct)==object->getId()) itStruct = mStructureList.erase(itStruct); else itStruct++; } } else gLogger->logMsgF("WorldManager::destroyObject: nearly did not remove: %"PRIu64"s knownObjectList",MSG_HIGH,object->getId()); object->destroyKnownObjects(); } break; case ObjType_Cell: { //a cell shouldnt have knownobjects ... -that should be checked to make sure it is true object->destroyKnownObjects(); } break; case ObjType_Tangible: { if(TangibleObject* tangible = dynamic_cast<TangibleObject*>(object)) { uint64 parentId = tangible->getParentId(); if(parentId == 0) { mSpatialIndex->RemovePoint(tangible->getId(),tangible->mPosition.x,tangible->mPosition.z); } else { if(CellObject* cell = dynamic_cast<CellObject*>(getObjectById(parentId))) { cell->removeObject(object); } else { // Well, Tangible can have more kind of parents than just cells or SI. For example players or Inventory. // the tangible is owned by its containing object (please note exeption of inventory / player with equipped stuff) // however we should leave the object link in the worldmanagers Objectmap and only store references in the object // we will have great trouble finding items otherwise //gLogger->logMsgF("WorldManager::destroyObject couldn't find cell %"PRIu64"",MSG_NORMAL,parentId); } } } else { gLogger->logMsgF("WorldManager::destroyObject: error removing : %"PRIu64"",MSG_HIGH,object->getId()); } // destroy known objects object->destroyKnownObjects(); } break; case ObjType_Region: { RegionMap::iterator it = mRegionMap.find(object->getId()); if(it != mRegionMap.end()) { mRegionMap.erase(it); } else { gLogger->logMsgF("Worldmanager::destroyObject: Could not find region %"PRIu64"",MSG_NORMAL,object->getId()); } //camp regions are in here, too QTRegionMap::iterator itQ = mQTRegionMap.find(static_cast<uint32>(object->getId())); if(itQ != mQTRegionMap.end()) { mQTRegionMap.erase(itQ); gLogger->logMsgF("Worldmanager::destroyObject: qt region %"PRIu64"",MSG_HIGH,object->getId()); } object->destroyKnownObjects(); } break; case ObjType_Intangible: { gLogger->logMsgF("Object of type ObjType_Intangible almost UNHANDLED in WorldManager::destroyObject:",MSG_HIGH); // intangibles are controllers / pets in the datapad // they are NOT in the world //we really shouldnt have any of thoose object->destroyKnownObjects(); } break; default: { gLogger->logMsgF("Unhandled ObjectType in WorldManager::destroyObject: %u",MSG_HIGH,(uint32)(object->getType())); // Please, when adding new stufff, at least take the time to add a stub for that type. // Better fail always, than have random crashes. assert(false && "WorldManager::destroyObject Unhandled ObjectType"); } break; } object->destroyKnownObjects(); // finally delete it ObjectMap::iterator objMapIt = mObjectMap.find(object->getId()); if(objMapIt != mObjectMap.end()) { mObjectMap.erase(objMapIt); } else { gLogger->logMsgF("WorldManager::destroyObject: error removing from objectmap: %"PRIu64"",MSG_HIGH,object->getId()); } }
void CreatureObject::die() { mIncapCount = 0; mCurrentIncapTime = 0; mFirstIncapTime = 0; // gLogger->logMsg("CreatureObject::die I'm dead"); gMessageLib->sendIncapTimerUpdate(this); if(PlayerObject* player = dynamic_cast<PlayerObject*>(this)) { gMessageLib->sendSystemMessage(player,L"","base_player","victim_dead"); player->disableAutoAttack(); } mPosture = CreaturePosture_Dead; // reset ham regeneration mHam.updateRegenRates(); gWorldManager->removeCreatureHamToProcess(mHam.getTaskId()); mHam.setTaskId(0); updateMovementProperties(); // clear states mState = 0; gMessageLib->sendPostureAndStateUpdate(this); if(PlayerObject* player = dynamic_cast<PlayerObject*>(this)) { gMessageLib->sendUpdateMovementProperties(player); gMessageLib->sendSelfPostureUpdate(player); // update duel lists PlayerList::iterator duelIt = player->getDuelList()->begin(); while(duelIt != player->getDuelList()->end()) { if((*duelIt)->checkDuelList(player)) { PlayerObject* duelPlayer = (*duelIt); duelPlayer->removeFromDuelList(player); gMessageLib->sendUpdatePvpStatus(player,duelPlayer); gMessageLib->sendUpdatePvpStatus(duelPlayer,player); } ++duelIt; } player->getDuelList()->clear(); // update defender lists ObjectIDList::iterator defenderIt = mDefenders.begin(); while (defenderIt != mDefenders.end()) { if (CreatureObject* defenderCreature = dynamic_cast<CreatureObject*>(gWorldManager->getObjectById((*defenderIt)))) { defenderCreature->removeDefenderAndUpdateList(this->getId()); if (PlayerObject* defenderPlayer = dynamic_cast<PlayerObject*>(defenderCreature)) { gMessageLib->sendUpdatePvpStatus(this,defenderPlayer); // gMessageLib->sendDefenderUpdate(defenderPlayer,0,0,this->getId()); } // Defender not hostile to me any more. gMessageLib->sendUpdatePvpStatus(defenderCreature, player); // if no more defenders, clear combat state if (!defenderCreature->getDefenders()->size()) { defenderCreature->toggleStateOff((CreatureState)(CreatureState_Combat + CreatureState_CombatAttitudeNormal)); gMessageLib->sendStateUpdate(defenderCreature); } } // If we remove self from all defenders, then we should remove all defenders from self. Remember, we are dead. defenderIt = mDefenders.erase(defenderIt); } // bring up the clone selection window ObjectSet inRangeBuildings; BStringVector buildingNames; std::vector<BuildingObject*> buildings; BuildingObject* nearestBuilding = NULL; BuildingObject* preDesignatedBuilding = NULL; // Search for cloning facilities. gWorldManager->getSI()->getObjectsInRange(this,&inRangeBuildings,ObjType_Building,8192); ObjectSet::iterator buildingIt = inRangeBuildings.begin(); while (buildingIt != inRangeBuildings.end()) { BuildingObject* building = dynamic_cast<BuildingObject*>(*buildingIt); if (building) { // Do we have any personal clone location? if (building->getId() == player->getPreDesignatedCloningFacilityId()) { // gLogger->logMsg("Found a pre-designated cloning facility"); preDesignatedBuilding = building; } if (building->getBuildingFamily() == BuildingFamily_Cloning_Facility) { // gLogger->logMsg("Found a cloning facility"); // TODO: This code is not working as intended if player dies inside, since buildings use world coordinates and players inside have cell coordinates. // Tranformation is needed before the correct distance can be calculated. if(!nearestBuilding || (nearestBuilding != building && (glm::distance(mPosition, building->mPosition) < glm::distance(mPosition, nearestBuilding->mPosition)))) { nearestBuilding = building; } } } ++buildingIt; } if (nearestBuilding) { if (nearestBuilding->getSpawnPoints()->size()) { // buildingNames.push_back(nearestBuilding->getRandomSpawnPoint()->mName.getAnsi()); // buildingNames.push_back("Closest Cloning Facility"); buildingNames.push_back("@base_player:revive_closest"); buildings.push_back(nearestBuilding); // Save nearest building in case we need to clone when reviev times out. player->saveNearestCloningFacility(nearestBuilding); } } if (preDesignatedBuilding) { if (preDesignatedBuilding->getSpawnPoints()->size()) { // buildingNames.push_back("Pre-Designated Facility"); buildingNames.push_back("@base_player:revive_bind"); buildings.push_back(preDesignatedBuilding); } } if (buildings.size()) { // Set up revive timer in case of user don't clone. gWorldManager->addPlayerObjectForTimedCloning(player->getId(), 10 * 60 * 1000); // TODO: Don't use hardcoded value. gUIManager->createNewCloneSelectListBox(player,"cloneSelect","Select Clone Destination","Select clone destination",buildingNames,buildings,player); } else { gLogger->logMsg("No cloning facility available\n"); } } else // if(CreatureObject* creature = dynamic_cast<CreatureObject*>(this)) { // gMessageLib->sendUpdateMovementProperties(player); // gMessageLib->sendSelfPostureUpdate(player); // Who killed me // this->prepareCustomRadialMenu(this,0); // // update defender lists ObjectIDList::iterator defenderIt = mDefenders.begin(); while(defenderIt != mDefenders.end()) { // This may be optimized, but rigth now THIS code does the job. this->makePeaceWithDefender(*defenderIt); defenderIt = mDefenders.begin(); } // I'm dead. De-spawn after "loot-timer" has expired, if any. // 3-5 min. uint64 timeBeforeDeletion = (180 + (gRandom->getRand() % (int32)120)) * 1000; if (this->getCreoGroup() == CreoGroup_AttackableObject) { // timeBeforeDeletion = 2 * 1000; // Almost NOW! timeBeforeDeletion = 500; // Play the death-animation, if any. if (AttackableStaticNpc* staticNpc = dynamic_cast<AttackableStaticNpc*>(this)) { staticNpc->playDeathAnimation(); } } else if (this->getCreoGroup() == CreoGroup_Creature) { if (AttackableCreature* creature = dynamic_cast<AttackableCreature*>(this)) { creature->unequipWeapon(); // Give XP to the one(s) attacking me. // creature->updateAttackersXp(); } } if (NPCObject* npc = dynamic_cast<NPCObject*>(this)) { // Give XP to the one(s) attacking me. npc->updateAttackersXp(); } // Put this creature in the pool of delayed destruction. gWorldManager->addCreatureObjectForTimedDeletion(this->getId(), timeBeforeDeletion); // this->killEvent(); } }
bool WorldManager::addObject(Object* object,bool manual) { uint64 key = object->getId(); //make sure objects arnt added several times!!!! if(getObjectById(key)) { gLogger->logMsgF("WorldManager::addObject Object already existant added several times or ID messup ???",MSG_HIGH); return false; } mObjectMap.insert(key,object); // if we want to set the parent manually or the object is from the snapshots and not a building, return if(manual) { return true; } #if defined(_MSC_VER) if(object->getId() < 0x0000000100000000 && object->getType() != ObjType_Building) #else if(object->getId() < 0x0000000100000000LLU && object->getType() != ObjType_Building) #endif { // check if a crafting station - in that case add Item* item = dynamic_cast<Item*> (object); if(item) { if(!(item->getItemFamily() == ItemFamily_CraftingStations)) return true; } else { return true; } } switch(object->getType()) { // player, when a player enters a planet case ObjType_Player: { PlayerObject* player = dynamic_cast<PlayerObject*>(object); gLogger->logMsgF("New Player: %"PRIu64", Total Players on zone : %i",MSG_NORMAL,player->getId(),(getPlayerAccMap())->size() + 1); // insert into the player map mPlayerAccMap.insert(std::make_pair(player->getAccountId(),player)); // insert into cell if(player->getParentId()) { player->setSubZoneId(0); if(CellObject* cell = dynamic_cast<CellObject*>(getObjectById(player->getParentId()))) { cell->addObjectSecure(player); } else { gLogger->logMsgF("WorldManager::addObject: couldn't find cell %"PRIu64"",MSG_HIGH,player->getParentId()); } } // query the rtree for the qt region we are in else { if(QTRegion* region = mSpatialIndex->getQTRegion(player->mPosition.x,player->mPosition.z)) { player->setSubZoneId((uint32)region->getId()); region->mTree->addObject(player); } else { // we should never get here ! gLogger->logMsg("WorldManager::addObject: could not find zone region in map"); return false; } } // initialize initObjectsInRange(player); gMessageLib->sendCreatePlayer(player,player); // add ham to regeneration scheduler player->getHam()->updateRegenRates(); // ERU: Note sure if this is needed here. player->getHam()->checkForRegen(); // onPlayerEntered event, notify scripts string params; params.setLength(sprintf(params.getAnsi(),"%s %s %u",getPlanetNameThis(),player->getFirstName().getAnsi(),static_cast<uint32>(mPlayerAccMap.size()))); mWorldScriptsListener.handleScriptEvent("onPlayerEntered",params); // Start player world position update. Used when player don't get any events from client (player not moving). // addPlayerMovementUpdateTime(player, 1000); } break; case ObjType_Structure: { // HarvesterObject* harvester = dynamic_cast<HarvesterObject*>(object); mStructureList.push_back(object->getId()); mSpatialIndex->InsertPoint(key,object->mPosition.x,object->mPosition.z); } break; case ObjType_Building: { mStructureList.push_back(object->getId()); BuildingObject* building = dynamic_cast<BuildingObject*>(object); mSpatialIndex->InsertRegion(key,building->mPosition.x,building->mPosition.z,building->getWidth(),building->getHeight()); } break; case ObjType_Tangible: { uint64 parentId = object->getParentId(); if(parentId == 0) { mSpatialIndex->InsertPoint(key,object->mPosition.x,object->mPosition.z); } else { CellObject* cell = dynamic_cast<CellObject*>(getObjectById(parentId)); if(cell) cell->addObjectSecure(object); else gLogger->logMsgF("WorldManager::addObject couldn't find cell %"PRIu64"",MSG_NORMAL,parentId); } } break; // TODO: add moving creatures to qtregions case ObjType_NPC: case ObjType_Creature: case ObjType_Lair: { CreatureObject* creature = dynamic_cast<CreatureObject*>(object); if(creature->getCreoGroup() == CreoGroup_Shuttle) mShuttleList.push_back(dynamic_cast<Shuttle*>(creature)); uint64 parentId = creature->getParentId(); if(parentId) { CellObject* cell = dynamic_cast<CellObject*>(getObjectById(parentId)); if(cell) cell->addObjectSecure(creature); else gLogger->logMsgF("WorldManager::addObject: couldn't find cell %"PRIu64"",MSG_HIGH,parentId); } else { switch(creature->getCreoGroup()) { // moving creature, add to QT case CreoGroup_Vehicle : { if(QTRegion* region = mSpatialIndex->getQTRegion(creature->mPosition.x,creature->mPosition.z)) { creature->setSubZoneId((uint32)region->getId()); region->mTree->addObject(creature); } else { gLogger->logMsg("WorldManager::addObject: could not find zone region in map for creature"); return false; } } break; // still creature, add to SI default : { mSpatialIndex->InsertPoint(key,creature->mPosition.x,creature->mPosition.z); } } } } break; case ObjType_Region: { RegionObject* region = dynamic_cast<RegionObject*>(object); mRegionMap.insert(std::make_pair(key,region)); mSpatialIndex->InsertRegion(key,region->mPosition.x,region->mPosition.z,region->getWidth(),region->getHeight()); if(region->getActive()) addActiveRegion(region); } break; case ObjType_Intangible: { gLogger->logMsgF("Object of type ObjType_Intangible UNHANDLED in WorldManager::addObject:",MSG_HIGH); } break; default: { gLogger->logMsgF("Unhandled ObjectType in WorldManager::addObject: PRId32",MSG_HIGH,object->getType()); // Please, when adding new stufff, at least take the time to add a stub for that type. // Better fail always, than have random crashes. assert(false && "WorldManager::addObject Unhandled ObjectType"); } break; } return true; }
void SceneObjectImplementation::createChildObjects() { if (getZone() == NULL) return; ZoneServer* zoneServer = getZone()->getZoneServer(); bool client = isStaticObject(); for (int i = 0; i < templateObject->getChildObjectsSize(); ++i) { ChildObject* child = templateObject->getChildObject(i); if (child == NULL) continue; ManagedReference<SceneObject*> obj = NULL; if (client) obj = zoneServer->createObject(child->getTemplateFile().hashCode(), "clientobjects", getPersistenceLevel()); else obj = zoneServer->createObject(child->getTemplateFile().hashCode(), getPersistenceLevel()); if (obj == NULL) continue; Locker objLocker(obj, asSceneObject()); Vector3 childPosition = child->getPosition(); childObjects.put(obj); obj->initializePosition(childPosition.getX(), childPosition.getZ(), childPosition.getY()); obj->setDirection(child->getDirection()); if (isBuildingObject() && child->getCellId() >= 0) { BuildingObject* buildingObject = asBuildingObject(); int totalCells = buildingObject->getTotalCellNumber(); try { if (totalCells >= child->getCellId()) { ManagedReference<CellObject*> cellObject = buildingObject->getCell(child->getCellId()); if (cellObject != NULL) { if (!cellObject->transferObject(obj, child->getContainmentType(), true)) { obj->destroyObjectFromDatabase(true); continue; } //cellObject->broadcastObject(obj, false); } else { error("NULL CELL OBJECT"); obj->destroyObjectFromDatabase(true); continue; } } } catch (Exception& e) { error("unreported exception caught in void SceneObjectImplementation::createChildObjects()!"); e.printStackTrace(); } } else { //Create the object outdoors in relation to its parent. Vector3 position; if (obj->isActiveArea()) position = getWorldPosition(); else position = getPosition(); float angle = direction.getRadians(); float x = (Math::cos(angle) * childPosition.getX()) + (childPosition.getY() * Math::sin(angle)); float y = (Math::cos(angle) * childPosition.getY()) - (childPosition.getX() * Math::sin(angle)); x += position.getX(); y += position.getY(); float z = position.getZ() + childPosition.getZ(); float degrees = direction.getDegrees(); Quaternion dir = child->getDirection(); obj->initializePosition(x, z, y); obj->setDirection(dir.rotate(Vector3(0, 1, 0), degrees)); if (obj->isBuildingObject()) { BuildingObject* building = obj->asBuildingObject(); if (building != NULL) { building->createCellObjects(); } } if (!getZone()->transferObject(obj, -1, false)) { obj->destroyObjectFromDatabase(true); continue; } } //childObjects.put(obj); ContainerPermissions* permissions = obj->getContainerPermissions(); permissions->setOwner(getObjectID()); permissions->setInheritPermissionsFromParent(false); permissions->setDefaultDenyPermission(ContainerPermissions::MOVECONTAINER); permissions->setDenyPermission("owner", ContainerPermissions::MOVECONTAINER); obj->initializeChildObject(asSceneObject()); } }
void BuildingFactory::handleDatabaseJobComplete(void* ref,DatabaseResult* result) { QueryContainerBase* asyncContainer = reinterpret_cast<QueryContainerBase*>(ref); switch(asyncContainer->mQueryType) { case BFQuery_MainData: { BuildingObject* building = _createBuilding(result); QueryContainerBase* asContainer; // if its a cloning facility, query its spawn points if(building->getBuildingFamily() == BuildingFamily_Cloning_Facility) { asContainer = new(mQueryContainerPool.ordered_malloc()) QueryContainerBase(asyncContainer->mOfCallback,BFQuery_CloneData,asyncContainer->mClient); asContainer->mObject = building; mDatabase->ExecuteSqlAsync(this,asContainer,"SELECT spawn_clone.parentId,spawn_clone.oX,spawn_clone.oY,spawn_clone.oZ,spawn_clone.oW," "spawn_clone.cell_x,spawn_clone.cell_y,spawn_clone.cell_z,spawn_clone.city " "FROM spawn_clone " "INNER JOIN cells ON spawn_clone.parentid = cells.id " "INNER JOIN buildings ON cells.parent_id = buildings.id " "WHERE buildings.id = %"PRIu64";",building->getId()); } else { asContainer = new(mQueryContainerPool.ordered_malloc()) QueryContainerBase(asyncContainer->mOfCallback,BFQuery_Cells,asyncContainer->mClient); asContainer->mObject = building; mDatabase->ExecuteSqlAsync(this,asContainer,"SELECT id FROM cells WHERE parent_id = %"PRIu64";",building->getId()); } } break; case BFQuery_CloneData: { BuildingObject* building = dynamic_cast<BuildingObject*>(asyncContainer->mObject); uint64 spawnCount = result->getRowCount(); if(!spawnCount) { gLogger->log(LogManager::DEBUG,"BuildingFactory: Cloning facility %"PRIu64" has no spawn points",building->getId()); } for(uint64 i = 0; i < spawnCount; i++) { SpawnPoint* spawnPoint = new SpawnPoint(); result->GetNextRow(mSpawnBinding,spawnPoint); building->addSpawnPoint(spawnPoint); } // load cells QueryContainerBase* asContainer = new(mQueryContainerPool.ordered_malloc()) QueryContainerBase(asyncContainer->mOfCallback,BFQuery_Cells,asyncContainer->mClient); asContainer->mObject = building; mDatabase->ExecuteSqlAsync(this,asContainer,"SELECT id FROM cells WHERE parent_id = %"PRIu64";",building->getId()); } break; case BFQuery_Cells: { BuildingObject* building = dynamic_cast<BuildingObject*>(asyncContainer->mObject); uint32 cellCount; uint64 cellId; DataBinding* cellBinding = mDatabase->CreateDataBinding(1); cellBinding->addField(DFT_int64,0,8); // store us for later lookup mObjectLoadMap.insert(std::make_pair(building->getId(),new(mILCPool.ordered_malloc()) InLoadingContainer(building,asyncContainer->mOfCallback,asyncContainer->mClient))); cellCount = static_cast<uint32>(result->getRowCount()); building->setLoadCount(cellCount); for(uint32 j = 0; j < cellCount; j++) { result->GetNextRow(cellBinding,&cellId); mCellFactory->requestObject(this,cellId,0,0,asyncContainer->mClient); } mDatabase->DestroyDataBinding(cellBinding); } break; default: break; } mQueryContainerPool.free(asyncContainer); }
float CollisionManager::getWorldFloorCollision(float x, float y, Zone* zone, bool testWater) { SortedVector<ManagedReference<QuadTreeEntry*> > closeObjects; zone->getInRangeObjects(x, y, 128, &closeObjects, true); PlanetManager* planetManager = zone->getPlanetManager(); if (planetManager == NULL) return 0.f; float height = 0; TerrainManager* terrainManager = planetManager->getTerrainManager(); //need to include exclude affectors in the terrain calcs height = terrainManager->getHeight(x, y); Vector3 rayStart(x, 16384.f, y); Vector3 rayEnd(x, -16384.f, y); Triangle* triangle = NULL; if (testWater) { float waterHeight; if (terrainManager->getWaterHeight(x, y, waterHeight)) if (waterHeight > height) height = waterHeight; } float intersectionDistance; for (int i = 0; i < closeObjects.size(); ++i) { BuildingObject* building = dynamic_cast<BuildingObject*>(closeObjects.get(i).get()); if (building == NULL) continue; //building->getObjectTemplate()->get SharedObjectTemplate* templateObject = building->getObjectTemplate(); if (templateObject == NULL) continue; PortalLayout* portalLayout = templateObject->getPortalLayout(); if (portalLayout == NULL) continue; if (portalLayout->getFloorMeshNumber() == 0) continue; //find nearest entrance FloorMesh* exteriorFloorMesh = portalLayout->getFloorMesh(0); // get outside layout AABBTree* aabbTree = exteriorFloorMesh->getAABBTree(); if (aabbTree == NULL) continue; Ray ray = convertToModelSpace(rayStart, rayEnd, building); if (aabbTree->intersects(ray, 16384 * 2, intersectionDistance, triangle, true)) { float floorHeight = 16384 - intersectionDistance; if (floorHeight > height) height = floorHeight; } } return height; }