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;
}
Example #2
0
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);
    }
}
Example #3
0
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);
    }
}
Example #4
0
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();
}
Example #9
0
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();
	}
}
Example #11
0
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;
}
Example #14
0
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();
    });
}
Example #15
0
//*********************************************************************
//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);
}
Example #16
0
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;
	}
}
Example #19
0
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());
}
Example #20
0
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;
}
Example #21
0
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());
	}
}
Example #26
0
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());
	}
}
Example #29
0
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;
}