int ContractCrateImplementation::canAddObject(SceneObject* object, int containmentType, String& errorDescription) {
	ManagedReference<CreatureObject*>  player = getParentRecursively(SceneObjectType::PLAYERCREATURE).castTo<CreatureObject*>();

	if (player == NULL)
		return TransferErrorCode::MUSTBEINPLAYERINVENTORY;

	String itemTemplate = object->getObjectTemplate()->getFullTemplateString();

	if (requiredItem != itemTemplate) {
		errorDescription = "@quest/crafting_contract/system_messages:wrong_item";
		return TransferErrorCode::INVALIDTYPE;
	}

	ManagedReference<TangibleObject*> tano = cast<TangibleObject*>(object);

	if (tano == NULL)
		return TransferErrorCode::INVALIDTYPE;

	if (tano->getCraftersName() == "") {
		errorDescription =  "@quest/crafting_contract/system_messages:not_crafted";
		return TransferErrorCode::INVALIDTYPE;
	}

	if (tano->getCraftersName() != player->getFirstName()) {
		errorDescription = "@quest/crafting_contract/system_messages:not_crafter";
		return TransferErrorCode::INVALIDTYPE;
	}

	if (currentAmount == amountNeeded) {
		errorDescription = "@quest/crafting_contract/system_messages:already_complete";
		return TransferErrorCode::INVALIDTYPE;
	}

	return TangibleObjectImplementation::canAddObject(object, containmentType, errorDescription);
}
void PetControlDeviceImplementation::destroyObjectFromWorld(bool sendSelfDestroy) {
	if (petType == PetManager::CREATUREPET) {
		ManagedReference<CreatureObject*> player = cast<CreatureObject*>(getParentRecursively(SceneObjectType::PLAYERCREATURE).get().get());

		if (player != NULL) {
			player->sendSystemMessage("@pet/pet_menu:pet_released"); // You release your pet back into the wild
		}
	}

	IntangibleObjectImplementation::destroyObjectFromWorld(sendSelfDestroy);
}
void GuildTerminalImplementation::fillObjectMenuResponse(ObjectMenuResponse* menuResponse, CreatureObject* player) {
	if (guildObject == NULL) {
		ManagedReference<BuildingObject*> building = cast<BuildingObject*>( getParentRecursively(SceneObjectType::BUILDING).get().get());

		if (building != NULL && building->isOwnerOf(player)) {
			if (!player->isInGuild()) {
				menuResponse->addRadialMenuItem(185, 3, "@guild:menu_create"); //Create Guild
				return;
			}

			//If the owner is already in a guild, and this guild terminal doesn't have a guild assigned yet,
			//then use the owner's guild.
			guildObject = player->getGuildObject();
		} else {
			//They don't have permission to create a guild.
			return;
		}
	}

	uint64 playerID = player->getObjectID();

	//Only members have access.
	if (!guildObject->hasMember(playerID) && !player->getPlayerObject()->isPrivileged())
		return;

	//Guild exists -> display these functions.
	menuResponse->addRadialMenuItem(193, 3, "@guild:menu_guild_management"); //Guild Management
	menuResponse->addRadialMenuItemToRadialID(193, 186, 3, "@guild:menu_info"); //Guild Information
	menuResponse->addRadialMenuItemToRadialID(193, 189, 3, "@guild:menu_enemies"); //Guild Enemies
	if ( guildObject->getGuildLeaderID() == playerID )
	menuResponse->addRadialMenuItemToRadialID(193, 195, 3, "@guild:accept_hall"); // Accept

	if (guildObject->hasDisbandPermission(playerID))
		menuResponse->addRadialMenuItemToRadialID(193, 191, 3, "@guild:menu_disband"); //Disband Guild

	if (guildObject->hasNamePermission(playerID) || player->getPlayerObject()->isPrivileged())
		menuResponse->addRadialMenuItemToRadialID(193, 192, 3, "@guild:menu_namechange"); //Change Guild Name

	menuResponse->addRadialMenuItemToRadialID(193, 68, 3, "@guild:menu_enable_elections"); //Enable/Disable Elections

	menuResponse->addRadialMenuItem(194, 3, "@guild:menu_member_management"); //Member Management
	menuResponse->addRadialMenuItemToRadialID(194, 187, 3, "@guild:menu_members"); //Guild Members

	if (guildObject->getSponsoredPlayerCount() > 0)
		menuResponse->addRadialMenuItemToRadialID(194, 188, 3, "@guild:menu_sponsored"); //Sponsored for Membership

	menuResponse->addRadialMenuItemToRadialID(194, 190, 3, "@guild:menu_sponsor"); //Sponsor for Membership

	if (guildObject->getGuildLeaderID() == playerID || player->getPlayerObject()->isPrivileged())
		menuResponse->addRadialMenuItemToRadialID(194, 69, 3, "@guild:menu_leader_change"); //Transfer PA Leadership

	return;
}
void MissionObjectImplementation::updateMissionLocation() {
	ManagedReference<SceneObject*> player = getParentRecursively(SceneObjectType::PLAYERCREATURE);
	
	ManagedReference<WaypointObject* > waypointToMission = this->waypointToMission;

	if (player != NULL && waypointToMission != NULL) {
		MissionObjectDeltaMessage3* dmiso3 = new MissionObjectDeltaMessage3(_this.get());
		dmiso3->updateWaypoint(waypointToMission);
		dmiso3->close();

		player->sendMessage(dmiso3);
	}
}
void MissionObjectImplementation::setMissionTitle(const String& file, const String& id, bool notifyClient) {
	missionTitle.setStringId(file, id);

	if (!notifyClient)
		return;

	ManagedReference<SceneObject*> player = getParentRecursively(SceneObjectType::PLAYERCREATURE);

	if (player != NULL) {
		MissionObjectDeltaMessage3* delta = new MissionObjectDeltaMessage3(_this.get());
		delta->updateTitleStf(&missionTitle);
		delta->close();

		player->sendMessage(delta);
	}
}
void MissionObjectImplementation::setRefreshCounter(int ctr, bool notifyClient) {
	refreshCounter = ctr;

	if (!notifyClient)
		return;

	ManagedReference<SceneObject*> player = getParentRecursively(SceneObjectType::PLAYERCREATURE);

	if (player != NULL) {
		MissionObjectDeltaMessage3* delta = new MissionObjectDeltaMessage3(_this.get());
		delta->updateRefreshCount(ctr);
		delta->close();

		player->sendMessage(delta);
	}
}
void MissionObjectImplementation::setCreatorName(const String& name, bool notifyClient) {
	creatorName = name;

	if (!notifyClient)
		return;

	ManagedReference<SceneObject*> player = getParentRecursively(SceneObjectType::PLAYERCREATURE);

	if (player != NULL) {
		MissionObjectDeltaMessage3* delta = new MissionObjectDeltaMessage3(_this.get());
		delta->updateCreator();
		delta->close();

		player->sendMessage(delta);
	}
}
void MissionObjectImplementation::setEndPosition(float posX, float posY, const String& planet, bool notifyClient) {
	endPositionX = posX;
	endPositionY = posY;
	endPlanet = planet;

	if (!notifyClient)
		return;

	ManagedReference<SceneObject*> player = getParentRecursively(SceneObjectType::PLAYERCREATURE);

	if (player != NULL) {
		MissionObjectDeltaMessage3* delta = new MissionObjectDeltaMessage3(_this.get());
		delta->updateDestination(posX, posY, endPlanet.hashCode());
		delta->close();

		player->sendMessage(delta);
	}
}
int ContractCrateImplementation::notifyObjectInserted(SceneObject* object) {
	ManagedReference<CreatureObject*> player = getParentRecursively(SceneObjectType::PLAYERCREATURE).castTo<CreatureObject*>();

	if (player == NULL)
		return 0;

	currentAmount++;

	if (currentAmount == amountNeeded) {
		player->sendSystemMessage("@quest/crafting_contract/system_messages:job_complete");
	} else {
		StringIdChatParameter str("@quest/crafting_contract/system_messages:items_remaining");
		str.setDI(amountNeeded - currentAmount);
		player->sendSystemMessage(str);
	}

	return 0;
}
void MissionObjectImplementation::setMissionDifficulty(int diffLevel, int display, int diff, bool notifyClient) {
	difficultyLevel = diffLevel;
	difficultyDisplay = display;
	difficulty = diff;

	if (!notifyClient)
		return;

	ManagedReference<SceneObject*> player = getParentRecursively(SceneObjectType::PLAYERCREATURE);

	if (player != NULL) {
		MissionObjectDeltaMessage3* delta = new MissionObjectDeltaMessage3(_this.get());
		delta->updateDifficultyLevel(difficultyDisplay);
		delta->close();

		player->sendMessage(delta);
	}
}
void MissionObjectImplementation::setTypeCRC(uint32 crc, bool notifyClient) {
	/*if (typeCRC == crc)
		return;*/

	typeCRC = crc;

	if (!notifyClient)
		return;

	ManagedReference<SceneObject*> player = getParentRecursively(SceneObjectType::PLAYERCREATURE);

	if (player != NULL) {
		MissionObjectDeltaMessage3* delta = new MissionObjectDeltaMessage3(_this.get());
		delta->updateTypeCRC(crc);
		delta->close();

		player->sendMessage(delta);
	}
}
void MissionObjectImplementation::setTargetTemplate(SharedObjectTemplate* templateObject, bool notifyClient) {
	if (targetTemplate == templateObject)
		return;

	targetTemplate = templateObject;

	if (!notifyClient)
		return;

	ManagedReference<SceneObject*> player = getParentRecursively(SceneObjectType::PLAYERCREATURE);

	if (player != NULL) {
		MissionObjectDeltaMessage3* delta = new MissionObjectDeltaMessage3(_this.get());
		delta->updateTemplateCRC(targetTemplate->getClientObjectCRC());
		delta->close();

		player->sendMessage(delta);
	}
}
void MissionObjectImplementation::setRewardCredits(int creds, bool notifyClient) {
	if (rewardCredits == creds)
		return;

	rewardCredits = creds;

	if (!notifyClient)
		return;

	ManagedReference<SceneObject*> player = getParentRecursively(SceneObjectType::PLAYERCREATURE);

	if (player != NULL) {
		MissionObjectDeltaMessage3* delta = new MissionObjectDeltaMessage3(_this.get());
		delta->updateRewardCredits(creds);
		delta->close();

		player->sendMessage(delta);
	}
}
bool LightsaberCrystalComponentImplementation::hasPlayerAsParent(CreatureObject* player) {
	ManagedReference<SceneObject*> wearableParent = getParentRecursively(SceneObjectType::WEARABLECONTAINER);
	SceneObject* inventory = player->getSlottedObject("inventory");
	SceneObject* bank = player->getSlottedObject("bank");

	// Check if crystal is inside a wearable container in bank or inventory
	if (wearableParent != NULL) {
		ManagedReference<WearableContainerObject*> wearable = cast<WearableContainerObject*>(wearableParent.get());

		if (wearable != NULL) {
			SceneObject* parentOfWearableParent = wearable->getParent().get();

			if (parentOfWearableParent == inventory || parentOfWearableParent == bank)
				return true;
		}
	} else {
		// Check if crystal is in inventory or bank
		SceneObject* thisParent = getParent().get();

		if (thisParent == inventory || thisParent == bank)
			return true;
	}
	return false;
}
Reference<CreatureObject*> LootkitObjectImplementation::getPlayer() {
    ManagedReference<CreatureObject*> strong = getParentRecursively(SceneObjectType::PLAYERCREATURE).castTo<CreatureObject*>();
    return strong.get();
}
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);
}