Ejemplo n.º 1
0
	//-----------------------------------------------------------------------
	void EditorOperation::execute() 
	{
        if ( getScene() )
        {
            TerrainManager* terrain = getScene()->getTerrainManager();
            if ( terrain )
            {
                Ogre::Rect rect = BrushSystem::getInstance().getActiveRect();
                UInt chunkCount = terrain->getTerrainChunkCount();

                for (UInt i=0;i<chunkCount; i++)
                {
                    TerrainChunk* chunk = terrain->getTerrainChunkByIndex(i);
                    
                    if ( chunk )
                    {
                        Ogre::Rect chunkRect = rect.intersect( chunk->getBoundingRect() );

                        if ( chunkRect.isNull() == false )
                        {
                            execute( chunk, chunkRect );
                        }
                    }
                }
            }
        }
	}
Ejemplo n.º 2
0
void RenderManager::AddTerrainToRenderer(TerrainManager &t)
{
	terrain = SetupVAO(t.GetTerrainMesh());
	terrainSize = t.GetTerrainMesh().GetSize();
	terrainManager = &t;
	water = SetupVAO(t.GetWaterMesh());
}
float ZoneImplementation::getHeight(float x, float y) {
	if (planetManager != NULL) {
		TerrainManager* manager = planetManager->getTerrainManager();

		if (manager != NULL)
			return manager->getHeight(x, y);
	}

	return 0;
}
Vector3 MissionObjectiveImplementation::getEndPosition() {
	ManagedReference<MissionObject* > mission = this->mission.get();

	Vector3 missionEndPoint;

	missionEndPoint.setX(mission->getEndPositionX());
	missionEndPoint.setY(mission->getEndPositionY());
	TerrainManager* terrain = getPlayerOwner().get()->getZone()->getPlanetManager()->getTerrainManager();
	missionEndPoint.setZ(terrain->getHeight(missionEndPoint.getX(), missionEndPoint.getY()));

	return missionEndPoint;
}
Vector3 ReconMissionObjectiveImplementation::getEndPosition() {
	ManagedReference<MissionObject* > mission = this->mission.get();

	Vector3 missionEndPoint;

	missionEndPoint.setX(mission->getStartPositionX());
	missionEndPoint.setY(mission->getStartPositionY());

	Zone* zone =  getPlayerOwner().get()->getZone();

	if (zone != NULL) {
		TerrainManager* terrain = zone->getPlanetManager()->getTerrainManager();
		missionEndPoint.setZ(terrain->getHeight(missionEndPoint.getX(), missionEndPoint.getY()));
	}

	return missionEndPoint;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
int main(int argc, char** argv)
{
	if (argc == 3 && strncmp(argv[1], "--convert", 9) == 0)
	{
		Configuration* config = new IniConfig(argv[2]);
		Heightmap* map = new Heightmap(config->getFloatValue("terrain","spacing"));
		if (map->loadFromImage(config->getValue("terrain","heightmap").c_str()))
		{
			std::cout << "Generating Terrain.." << std::endl;
			TerrainGenerator(map, config->getIntValue("terrain","chunksize"), config->getValue("out","filename").c_str());
			std::cout << "..done" << std::endl;
			std::cout.flush();
		}
		else
			std::cout << "Generation failed." << std::endl;
		return 0;
	}
	if (argc == 4 && strncmp(argv[1], "--load", 6) == 0)
	{
		int id = atoi(argv[3]);
		TerrainFileReader* reader = new TerrainFileReader();
		reader->openFile(argv[2]);

		TerrainChunk* tc = reader->readId(id);
		if (tc == NULL || tc->getInfo()->getQuadId() != id)
		{
			std::cout << "Got ID" << tc->getInfo()->getQuadId()
					<< " instead of " << id << std::endl;
			return 1;
		}
		else
		{
			std::cout << "Successfully got Terrainchunk " << id << std::endl;
			std::cout << "Spacing of Heightmap is "
					<< tc->getHeightmap()->getSpacing() << " where origin is "
					<< tc->getOrigin().x << "," << tc->getOrigin().y << " and center at "
					<< tc->getCenter().x << "," << tc->getCenter().y << std::endl;
		}
		reader->closeFile();
		delete tc;
		delete reader;
	}
	if (argc != 2 || strncmp(argv[1], "--run", 5) != 0)
	{
		std::cout << "Usage of '" << argv[0] << "'" <<std::endl;
		std::cout << "\nAvailable Parameter:"
				<< "\n\t--convert terrain.desc"
				<< "\n\t--load terrain.terr chunkid(=0)"
				<< "\n\t--run" << std::endl;
		return 1;
	}

	int width, height;
	Configuration * win_config = new IniConfig("config.ini");
	WindowHints* hints = new WindowHints();
	hints->Fullscreen = win_config->getBooleanValue("Window","fullscreen");
	hints->Width = win_config->getIntValue("Window","width");
	hints->Height = win_config->getIntValue("Window","height");
	GraphicsSystem* GSystem = new GraphicsSystem(GraphicsSystem::PROFILE_GL3,
			hints);
	if (GSystem->isError())
		return -1;
	GraphicsContext* grctx = GSystem->getGraphicsContext();
	Window* win = GSystem->getWindow();
	TextureManager* tmgr = new TextureManager(grctx);
	ModelLoader* mmgr = new ModelLoader(grctx, tmgr);
	TerrainManager* terrmgr = new TerrainManager(grctx);
	Model* mdl, *mdl2;
	Camera* cam = new Camera();
	win->getSize(&width, &height);
	cam->setScreen(width,height);
	cam->setupLens(65.0f, 1.0f, 1000.0f);

	if ((mdl = mmgr->loadAsset("Resources/Models/ant01.ms3d")) == NULL)
		std::cerr << "Could not load Model" << std::endl;
	if ((mdl2 = mmgr->loadAsset("Resources/Models/dwarf1.ms3d")) == NULL)
		std::cerr << "Could not load Model" << std::endl;
	ModelAnimationController mdlanictrl(mdl), mdlanictrl2(mdl2);
	mdlanictrl.addAnimation("idle", 52, 67, 0.25f, true);
	mdlanictrl.addAnimation("die", 30, 49, 0.25f, false);
	mdlanictrl2.addAnimation("begin_walk", 1, 2, 0.25f, false, "walk");
	mdlanictrl2.addAnimation("walk", 2, 14, 0.25f, true);
	mdlanictrl2.addAnimation("jump", 28, 40, 0.5f, false, "begin_walk");
	mdlanictrl2.addAnimation("idle", 292, 325, 0.25f, false, "idle2");
	mdlanictrl2.addAnimation("idle2", 327, 360, 0.25f, true);
	mdlanictrl2.addAnimation("die", 230, 251, 0.25f, false);
	std::cout << "Using DesktopMode: " << width << "x" << height << std::endl;
	win->setTitle("Xng?! -> Yeah!");

	Shader* sh = grctx->createShader();
	if (!sh->loadFromFile("Shader/Animation.vs", "Shader/Animation.fs"))
		return 1;

	Shader* tsh = grctx->createShader();
	if (!tsh->loadFromFile("Shader/Terrain.vs", "Shader/Terrain.fs"))
			return 1;

	Timer* t = new Timer();
	double frames = 0;

	grctx->setClearColor(glm::vec4(1.0f, 0.5f, 0.25f, 1.0f));
	t->start();

	Terrain* terr = terrmgr->loadAsset("Resources/terrain/terrain.terr");
	terr->setDetail(0.05f,cam);

	glm::mat4 mdlm = glm::scale(
			glm::translate(glm::mat4(1.0f), glm::vec3(5.0f, -5.0f, -20.0f)),
			glm::vec3(0.5f));
	glm::mat4 mdlm2 = glm::scale(
			glm::translate(glm::mat4(1.0f), glm::vec3(-5.0f, -5.0f, -20.0f)),
			glm::vec3(0.18f));
	mdlm = glm::rotate(mdlm, 180.0f, glm::vec3(0.0f, 1.0f, 0.0f));
	mdlm2 = glm::rotate(mdlm2, 180.0f, glm::vec3(0.0f, 1.0f, 0.0f));
	glm::vec3 cam_pos = glm::vec3(0.0f,0.0f,0.0f);
	glm::quat cam_orient = glm::quat();
	float speed = 0.0f;

	float deltaTime = 0;
	float second = t->getMilli();
	float lastTime = second;

	while (win->isOpen())
	{
		second = t->getMilli();
		deltaTime = second - lastTime;
		lastTime = second;
		if (glfwGetKey(GLFW_KEY_ESC))
			break;
		if (glfwGetKey(GLFW_KEY_SPACE))
			mdlanictrl2.setActiveAnimation("jump");
		if (glfwGetKey('W'))
			mdlanictrl2.setActiveAnimation("begin_walk");
		if (glfwGetKey('S'))
			mdlanictrl2.setActiveAnimation("idle");
		if (glfwGetKey('F'))
			mdlanictrl.setActiveAnimation("die");
		if (glfwGetKey('G'))
			mdlanictrl2.setActiveAnimation("die");
		if (glfwGetKey('A'))
			mdlm2 = glm::rotate(mdlm2, -0.3f, glm::vec3(0.0f, 1.0f, 0.0f));
		if (glfwGetKey('D'))
			mdlm2 = glm::rotate(mdlm2, 0.3f, glm::vec3(0.0f, 1.0f, 0.0f));
		if( glfwGetKey(GLFW_KEY_LSHIFT) || glfwGetKey(GLFW_KEY_RSHIFT))
			speed = 1.0f;
		else speed = 0.1f;
		if (glfwGetKey('I'))
			cam_pos += glm::cross(cam->getUpVector(),cam->getRightVector()) * speed * deltaTime;
		if (glfwGetKey('K'))
			cam_pos -= glm::cross(cam->getUpVector(),cam->getRightVector()) * speed * deltaTime;
		if (glfwGetKey('J'))
			cam_pos -= cam->getRightVector() * speed * deltaTime;
		if (glfwGetKey('L'))
			cam_pos += cam->getRightVector() * speed * deltaTime;
		if (glfwGetKey('O'))
			cam_pos += cam->getUpVector() * speed * deltaTime;
		if (glfwGetKey('P'))
			cam_pos -= cam->getUpVector() * speed * deltaTime;
		if(glfwGetKey(GLFW_KEY_LEFT))
			cam_orient = glm::rotate(cam_orient,speed * deltaTime,glm::vec3(0.0f,1.0f,0.0f));
		if(glfwGetKey(GLFW_KEY_RIGHT))
			cam_orient =glm::rotate(cam_orient,-speed * deltaTime,glm::vec3(0.0f,1.0f,0.0f));
		if(glfwGetKey(GLFW_KEY_UP))
			cam_orient = glm::rotate(cam_orient,speed * deltaTime,glm::vec3(1.0f,0.0f,0.0f));
		if(glfwGetKey(GLFW_KEY_DOWN))
			cam_orient = glm::rotate(cam_orient,-speed * deltaTime,glm::vec3(1.0f,0.0f,0.0f));
		cam_pos.y = terr->getHeightAt(cam_pos.x,cam_pos.z) + 5;
		cam->setPosition(cam_pos);
		cam->setOrientation(cam_orient);
		mdlanictrl.update(deltaTime);
		mdlanictrl2.update(deltaTime);
		grctx->clearDisplay();
		grctx->setShader(sh);

		grctx->setProjectionMatrix(cam->getLens());
		grctx->setViewMatrix(cam->getView());
		grctx->setModelMatrix(&mdlm);
		for (int i = 0; i < mdl->getNumMeshes(); i++)
		{
			grctx->setMesh(mdl->getMesh(i));
			grctx->setMaterial(mdl->getMaterial(mdl->getMesh(i)->getMaterialId()));
			grctx->setBoneTransformation(mdlanictrl.getBoneTransformation(), mdlanictrl.getNumBones());

			grctx->draw();
		}

		grctx->setModelMatrix(&mdlm2);
		for (int i = 0; i < mdl2->getNumMeshes(); i++)
		{
			grctx->setMesh(mdl2->getMesh(i));
			grctx->setMaterial(mdl2->getMaterial(mdl2->getMesh(i)->getMaterialId()));
			grctx->setBoneTransformation(mdlanictrl2.getBoneTransformation(), mdlanictrl2.getNumBones());
			grctx->draw();
		}

		grctx->setShader(tsh);
		grctx->setProjectionMatrix(cam->getLens());
		grctx->setViewMatrix(cam->getView());
		terr->selectNodes(cam);

		grctx->swapBuffers();
		frames++;
	}
	t->end();

	delete sh;

	mmgr->removeAsset("Resources/Models/dwarf1.ms3d");
	mmgr->removeAsset("Resources/Models/ant01.ms3d");
	std::cout << "TpF: " << t->getLastMilli() / frames << " mspf was " << frames
			<< " Frames in " << t->getLastMilli() << "ms or "
			<< frames / t->getLastSecond() << "fps" << std::endl;
	delete mmgr;
	delete tmgr;
	delete t;
	delete GSystem;

	return 0;
}
bool CollisionManager::checkShipCollision(ShipObject* ship, const Vector3& targetPosition, Vector3& collisionPoint) {
	Zone* zone = ship->getZone();

	if (zone == NULL)
		return false;

	TerrainManager* terrainManager = zone->getPlanetManager()->getTerrainManager();

	if (terrainManager->getProceduralTerrainAppearance() != NULL) {
		float height = terrainManager->getHeight(targetPosition.getX(), targetPosition.getY());

		float waterHeight = -16368.f;

		if (terrainManager->getWaterHeight(targetPosition.getY(), targetPosition.getY(), waterHeight))
			height = MAX(waterHeight, height);

		if (height > targetPosition.getZ()) {
			collisionPoint = targetPosition;
			collisionPoint.setZ(height);
			//ship->info("colliding with terrain", true);
			return true;
		}
	}

	Vector3 rayOrigin = ship->getWorldPosition();

	rayOrigin.set(rayOrigin.getX(), rayOrigin.getY(), rayOrigin.getZ());

	Vector3 rayEnd;
	rayEnd.set(targetPosition.getX(), targetPosition.getY(), targetPosition.getZ());

	float dist = rayEnd.distanceTo(rayOrigin);
	float intersectionDistance;
	Triangle* triangle = NULL;

	SortedVector<ManagedReference<QuadTreeEntry*> > objects(512, 512);
	zone->getInRangeObjects(targetPosition.getX(), targetPosition.getY(), 512, &objects, true);

	for (int i = 0; i < objects.size(); ++i) {
		AABBTree* aabbTree = NULL;

		SceneObject* scno = cast<SceneObject*>(objects.get(i).get());

		try {
			aabbTree = getAABBTree(scno, -1);

			if (aabbTree == NULL)
				continue;

		} catch (Exception& e) {
			aabbTree = NULL;
		} catch (...) {
			throw;
		}

		if (aabbTree != NULL) {
			//moving ray to model space

			try {
				Ray ray = convertToModelSpace(rayOrigin, rayEnd, scno);

				//structure->info("checking ray with building dir" + String::valueOf(structure->getDirectionAngle()), true);

				if (aabbTree->intersects(ray, dist, intersectionDistance, triangle, true)) {

					//rayOrigin.set(rayOrigin.getX(), rayOrigin.getY(), rayOrigin.getZ());
					Vector3 direction = rayEnd - rayOrigin;
					direction.normalize();
					//intersectionDistance -= 0.5f;

					collisionPoint.set(rayOrigin.getX() + (direction.getX() * intersectionDistance), rayOrigin.getY() + (direction.getY() * intersectionDistance), rayOrigin.getZ() + (direction.getZ() * intersectionDistance));
					//ship->info("colliding with building", true);

					return true;
				}
			} catch (Exception& e) {
				ship->error(e.getMessage());
			} catch (...) {
				throw;
			}


		}
	}

	return false;
}
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;
}
Ejemplo n.º 10
0
	TerrainCache::lru_value_t run(const float& k, const float& k2) {
		float height = terrainData->getUnCachedHeight(k , k2);

		return std::make_pair(new HeightQuadTreeEntry(k, k2), height);
	}
int EventPerkDeedImplementation::handleObjectMenuSelect(CreatureObject* player, byte selectedID) {

	if (selectedID == 20) {
		if (generated) {
			return 1;
		}

		Zone* zone = player->getZone();

		if (zone == NULL) {
			return 1;
		}

		PlanetManager* planetManager = zone->getPlanetManager();
		if (planetManager == NULL) {
			return 1;
		}

		EventPerkDeedTemplate* deedTemplate = cast<EventPerkDeedTemplate*>(getObjectTemplate());
		if (deedTemplate == NULL) {
			return 1;
		}

		if (zone->getZoneName().contains("space_")) {
			player->sendSystemMessage("@event_perk:not_in_space"); // You may not deploy a Rental in space. Return to the ground first.
			return 1;
		}

		if (!deedTemplate->isAllowedZone(zone->getZoneName())) {
			player->sendSystemMessage("@event_perk:not_on_this_planet"); // You cannot deploy this rental on this planet. Examine the deed to determine the intended planet for this rental.
			return 1;
		}

		if (!isASubChildOf(player)) {
			player->sendSystemMessage("@event_perk:from_inventory_only"); // This rental must be in your inventory in order to be deployed.
			return 1;
		}

		if (player->getParent() != NULL) {
			player->sendSystemMessage("@event_perk:not_inside"); // You cannot deploy a Rental indoors. You must move outside.
			return 1;
		}

		if (player->isInCombat()) {
			player->sendSystemMessage("@event_perk:not_in_combat"); // You cannot deploy a Rental while in combat.
			return 1;
		}

		if (player->isSwimming()) {
			player->sendSystemMessage("@event_perk:not_while_swimming"); // You cannot deploy a Rental while swimming.
			return 1;
		}

		ManagedReference<CityRegion*> city = player->getCityRegion().get();

		if (city != NULL) {
			if (city->isClientRegion()) {
				player->sendSystemMessage("@event_perk:not_in_municipal_zone"); // You may not place a Rental in a municipal zone.
				return 1;
			}

			if (city->isZoningEnabled() && !city->hasZoningRights(player->getObjectID())) {
				player->sendSystemMessage("@event_perk:no_zoning_rights"); // You must have zoning rights to place a Rental in this city.
				return 1;
			}
		}

		int x = player->getWorldPositionX();
		int y = player->getWorldPositionY();
		int nearbyPerks = 0;

		TerrainManager* terrainManager = planetManager->getTerrainManager();
		if ( terrainManager == NULL || terrainManager->getHighestHeightDifference(x - 10, y - 10, x + 10, y + 10) > 15.0) {
			player->sendSystemMessage("@event_perk:bad_area"); // This rental could not be deployed due to the surrounding terrain. Please move to another area and try again.
			return 1;
		}

		SortedVector<ManagedReference<QuadTreeEntry* > >* closeObjects = player->getCloseObjects();

		if (closeObjects == NULL) {
			error("Player has NULL closeObjectsVector in EventPerkDeedImplementation::handleObjectMenuSelect");
			return 1;
		}

		for (int i = 0; i < closeObjects->size(); ++i) {
			SceneObject* obj = cast<SceneObject*>(closeObjects->get(i).get());

			if (obj == NULL) {
				continue;
			}

			SharedObjectTemplate* objectTemplate = obj->getObjectTemplate();
			if (objectTemplate == NULL) {
				continue;
			}

			float radius = objectTemplate->getNoBuildRadius();

			if (obj->isLairObject() && player->isInRange(obj, radius)) {
				player->sendSystemMessage("@event_perk:too_close_lair"); // You cannot place a Rental this close to a lair.
				return 1;
			}

			if (obj->isCampStructure() && player->isInRange(obj, radius)) {
				player->sendSystemMessage("@event_perk:too_close_camp"); // You cannot place a Rental this close to a camp.
				return 1;
			}

			if (radius > 0 && player->isInRange(obj, radius)) {
				player->sendSystemMessage("@event_perk:too_close_something"); // You are too close to an object to deploy your Rental here. Move away from it.
				return 1;
			}

			if (objectTemplate->isSharedStructureObjectTemplate()) {
				if (StructureManager::instance()->isInStructureFootprint(cast<StructureObject*>(obj), x, y, 0)) {
					player->sendSystemMessage("@event_perk:too_close_building"); // You may not place a Rental this close to a building.
					return 1;
				}
			}

			if (obj->isEventPerk() && player->isInRange(obj, 32) && ++nearbyPerks > 2) {
				player->sendSystemMessage("@event_perk:too_many_perks"); // There are too many Rentals already deployed in this area. Please move to another location.
				return 1;
			}
		}

		SortedVector<ManagedReference<ActiveArea* > > activeAreas;
		zone->getInRangeActiveAreas(x, y, &activeAreas, true);

		for (int i = 0; i < activeAreas.size(); ++i) {
			ActiveArea* area = activeAreas.get(i);

			if (area->isNoBuildArea()) {
				player->sendSystemMessage("@event_perk:too_close_something"); // You are too close to an object to deploy your Rental here. Move away from it.
				return 1;
			}
		}

		if (planetManager->isInRangeWithPoi(x, y, 150)) {
			player->sendSystemMessage("@event_perk:too_close_something"); // You are too close to an object to deploy your Rental here. Move away from it.
			return 1;
		}

		if (perkType != EventPerkDeedTemplate::STATIC) {
			player->sendSystemMessage("This type of event perk deed is not functional yet.");
			return 1;
		}

		ManagedReference<TangibleObject*> object = generatedObject.get();

		if (object == NULL) {
			object = (server->getZoneServer()->createObject(generatedObjectTemplate.hashCode(), "playerstructures", 1)).castTo<TangibleObject*>();

			if (object == NULL) {
				player->sendSystemMessage("Error generating object. Wrong generatedObjectTemplate or is not a tangible object.");
				return 1;
			}

			generatedObject = object;
		}

		EventPerkDataComponent* data = cast<EventPerkDataComponent*>(object->getDataObjectComponent()->get());

		if (data == NULL) {
			player->sendSystemMessage("Error: no dataObjectComponent.");
			object->destroyObjectFromDatabase();
			return 1;
		}

		data->setDeed(_this.get());

		object->initializePosition(player->getPositionX(), player->getPositionZ(), player->getPositionY());
		object->setDirection(Math::deg2rad(player->getDirectionAngle()));
		zone->transferObject(object, -1, true);

		generated = true;
		destroyObjectFromWorld(true);

		return 0;
	}

	return DeedImplementation::handleObjectMenuSelect(player, selectedID);
}