void EventPerkMenuComponent::fillObjectMenuResponse(SceneObject* sceneObject, ObjectMenuResponse* menuResponse, CreatureObject* player) {
	TangibleObjectMenuComponent::fillObjectMenuResponse(sceneObject, menuResponse, player);

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

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

	EventPerkDeed* deed = data->getDeed();

	if (deed == NULL) {
		player->sendSystemMessage("Error: deed is NULL.");
		return;
	}

	ManagedReference<CreatureObject*> owner = deed->getOwner().get();

	if (owner == player) {
		menuResponse->addRadialMenuItem(132, 3, "@event_perk:mnu_show_exp_time"); // Show Expiration Time
		menuResponse->addRadialMenuItem(128, 3, "@event_perk:mnu_redeed"); // Reclaim Rental Deed

		menuResponse->addRadialMenuItem(51, 1, "@event_perk:mnu_rotate"); // Rotate
		menuResponse->addRadialMenuItemToRadialID(51, 52, 3, "@event_perk:mnu_rot_left"); // Rotate Left
		menuResponse->addRadialMenuItemToRadialID(51, 53, 3, "@event_perk:mnu_rot_right"); // Rotate Right
	}
}
int EventPerkMenuComponent::handleObjectMenuSelect(SceneObject* sceneObject, CreatureObject* player, byte selectedID) {
	EventPerkDataComponent* data = cast<EventPerkDataComponent*>(sceneObject->getDataObjectComponent()->get());

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

	EventPerkDeed* deed = data->getDeed();

	if (deed == NULL) {
		player->sendSystemMessage("Error: deed is NULL.");
		return 1;
	}

	ManagedReference<CreatureObject*> owner = deed->getOwner().get();

	if (owner != player) {
		return TangibleObjectMenuComponent::handleObjectMenuSelect(sceneObject, player, selectedID);
	}

	if (selectedID == 132) {
		Time currentTime;
		uint32 timeDelta = currentTime.getMiliTime() - deed->getPurchaseTime()->getMiliTime();
		uint32 minutes = (EventPerkDeedTemplate::TIME_TO_LIVE - timeDelta) / 60000;

		StringIdChatParameter params("event_perk", "show_exp_time"); // This rental will expire in approximately %DI minutes.
		params.setDI(minutes);
		player->sendSystemMessage(params);
		return 0;
	} else if (selectedID == 128) {
		ManagedReference<SceneObject*> inventory = player->getSlottedObject("inventory");
		PlayerObject* ghost = player->getPlayerObject();

		if (inventory == NULL || inventory->isContainerFull()) {
			player->sendSystemMessage("@event_perk:redeed_failed"); // The rental could not be re-deeded.
			return 1;
		}

		if (ghost == NULL || ghost->getEventPerkCount() > 5) {
			player->sendSystemMessage("@event_perk:redeed_too_many_deeds"); // You have too many rental deeds in your possession and cannot redeed this rental.
			return 1;
		}

		deed->sendTo(player, true);
		inventory->transferObject(deed, -1, true);
		deed->setGenerated(false);
		sceneObject->destroyObjectFromWorld(true);

		player->sendSystemMessage("@event_perk:redeed_success"); // Your Rental has been removed and the deed reclaimed.
		return 0;
	}

	return TangibleObjectMenuComponent::handleObjectMenuSelect(sceneObject, player, selectedID);
}
CreatureObject* ScavengerDroidImplementation::getDeedOwner() {
	EventPerkDataComponent* gameData = cast<EventPerkDataComponent*>(getDataObjectComponent()->get());

	if (gameData == NULL) {
		return NULL;
	}

	ManagedReference<EventPerkDeed*> deed = gameData->getDeed();

	if (deed == NULL) {
		return NULL;
	}

	ManagedReference<CreatureObject*> owner = deed->getOwner().get();

	return owner;
}
int ScavengerDroidImplementation::handleObjectMenuSelect(CreatureObject* player, byte selectedID) {
	ManagedReference<CreatureObject*> perkOwner = getDeedOwner();

	bool isOwner = perkOwner != NULL && player == perkOwner;


	if (gameStatus == GAMESETUP && isOwner) {
		if (selectedID == 132) {
			sendSetupInstructionsSUI(player);
		} else if (selectedID == 133) {
			sendItemListSUI(player);
		} else if (selectedID == 134) {
			player->sendSystemMessage("@event_perk:scavenger_list_reset_msg");
			clearItemList();
		} else if (selectedID == 135) {
			startGame(player);
		}
	} else if (gameStatus == GAMESTARTED) {
		if (selectedID == 132) {
			sendGameInstructionsSUI(player);
		} else if (selectedID == 133) {
			sendItemListSUI(player);
		} else if (selectedID == 136) {
			StringIdChatParameter msg("event_perk", "scavenger_show_current_leader");

			ManagedReference<CreatureObject*> curWinner = currentWinner.get();

			if (curWinner == NULL)
				msg.setTO("Nobody");
			else
				msg.setTO(curWinner->getDisplayedName());
			player->sendSystemMessage(msg);
		}
	} else if (gameStatus == GAMEENDED) {
		if (selectedID == 136) {
			StringIdChatParameter msg("event_perk", "scavenger_show_leader");

			ManagedReference<CreatureObject*> curWinner = currentWinner.get();

			int timeMins = (gameEndTime.getMiliTime() - gameStartTime.getMiliTime()) / 60000;

			if (curWinner != NULL)
				msg.setTO(curWinner->getDisplayedName());
			else
				msg.setTO("Unknown");

			msg.setDI(timeMins);
			player->sendSystemMessage(msg);
		}
	}

	if (selectedID == 137 && (isOwner || (player->getPlayerObject() != NULL && player->getPlayerObject()->isPrivileged()))) {
		EventPerkDataComponent* data = cast<EventPerkDataComponent*>(getDataObjectComponent()->get());

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

		EventPerkDeed* deed = data->getDeed();

		if (deed == NULL) {
			player->sendSystemMessage("Error: deed is NULL.");
			return 1;
		}

		Time currentTime;
		uint32 timeDelta = currentTime.getMiliTime() - deed->getPurchaseTime()->getMiliTime();
		uint32 minutes = (EventPerkDeedTemplate::TIME_TO_LIVE - timeDelta) / 60000;

		StringIdChatParameter params("event_perk", "show_exp_time"); // This rental will expire in approximately %DI minutes.
		params.setDI(minutes);
		player->sendSystemMessage(params);
		return 0;
	}

	return 0;
}
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);
}