void LightsaberCrystalComponentImplementation::tuneCrystal(CreatureObject* player) {

	if(!player->hasSkill("force_title_jedi_rank_01") || !hasPlayerAsParent(player)) {
		return;
	}

	if ((owner == "")){
		String name = player->getDisplayedName();
		setOwner(name);

		// Color code is lime green.
		String tuneName;
		if (getCustomObjectName().toString().contains("(Exceptional)"))
			tuneName = "\\#00FF00" + postTuneName + " (Exceptional) (tuned)";
		else if (getCustomObjectName().toString().contains("(Legendary)"))
			tuneName = "\\#00FF00" + postTuneName + " (Legendary) (tuned)";
		else
			tuneName = "\\#00FF00" + postTuneName + " (tuned)";

		setCustomObjectName(tuneName, true);
		player->sendSystemMessage("@jedi_spam:crystal_tune_success");
	} else {
		player->sendSystemMessage("This crystal has already been tuned.");
	}
}
int LightsaberCrystalComponentImplementation::handleObjectMenuSelect(CreatureObject* player, byte selectedID) {
	if (selectedID == 128 && player->hasSkill("force_title_jedi_rank_01") && hasPlayerAsParent(player) && ownerID == 0) {
		ManagedReference<SuiMessageBox*> suiMessageBox = new SuiMessageBox(player, SuiWindowType::TUNE_CRYSTAL);

		suiMessageBox->setPromptTitle("@jedi_spam:confirm_tune_title");
		suiMessageBox->setPromptText("@jedi_spam:confirm_tune_prompt");
		suiMessageBox->setCancelButton(true, "Cancel");
		suiMessageBox->setUsingObject(_this.getReferenceUnsafeStaticCast());
		suiMessageBox->setCallback(new LightsaberCrystalTuneSuiCallback(player->getZoneServer()));

		player->getPlayerObject()->addSuiBox(suiMessageBox);
		player->sendMessage(suiMessageBox->generateMessage());
	}

	PlayerObject* ghost = player->getPlayerObject();
	if (ghost != NULL && ghost->isPrivileged()){
		if (selectedID == 130 && getColor() == 31) {
			generateCrystalStats();
		} else if (selectedID == 131 && ownerID != 0) {
			ownerID = 0;

			String tuneName = StringIdManager::instance()->getStringId(objectName.getFullPath().hashCode()).toString();
			if (getCustomObjectName().toString().contains("(Exceptional)"))
				tuneName = tuneName + " (Exceptional)\\#.";
			else if (getCustomObjectName().toString().contains("(Legendary)"))
				tuneName = tuneName + " (Legendary)\\#.";
			else
				tuneName = tuneName + "\\#.";
		}
	}

	return 0;
}
Reference<FactoryCrate*> TangibleObjectImplementation::createFactoryCrate(bool insertSelf) {
	String file;
	uint32 type = getGameObjectType();

	if(type & SceneObjectType::ARMOR)
		file = "object/factory/factory_crate_armor.iff";
	else if(type == SceneObjectType::CHEMICAL || type == SceneObjectType::PHARMACEUTICAL || type == SceneObjectType::PETMEDECINE)
		file = "object/factory/factory_crate_chemicals.iff";
	else if(type & SceneObjectType::CLOTHING)
		file = "object/factory/factory_crate_clothing.iff";
	else if(type == SceneObjectType::ELECTRONICS)
		file = "object/factory/factory_crate_electronics.iff";
	else if(type == SceneObjectType::FOOD || type == SceneObjectType::DRINK)
		file = "object/factory/factory_crate_food.iff";
	else if(type == SceneObjectType::FURNITURE)
		file = "object/factory/factory_crate_furniture.iff";
	else if(type & SceneObjectType::INSTALLATION)
		file = "object/factory/factory_crate_installation.iff";
	else if(type & SceneObjectType::WEAPON)
		file = "object/factory/factory_crate_weapon.iff";
	else
		file = "object/factory/factory_crate_generic_items.iff";

	ObjectManager* objectManager = ObjectManager::instance();

	Reference<FactoryCrate*> crate = (getZoneServer()->createObject(file.hashCode(), 2)).castTo<FactoryCrate*>();

	if (crate == NULL)
		return NULL;

	SharedTangibleObjectTemplate* tanoData = dynamic_cast<SharedTangibleObjectTemplate*>(templateObject.get());

	if (tanoData == NULL)
		return NULL;

	crate->setMaxCapacity(tanoData->getFactoryCrateSize());

	if (insertSelf) {
		crate->transferObject(_this.get(), -1, false);
	} else {

		ManagedReference<TangibleObject*> protoclone = cast<TangibleObject*>( objectManager->cloneObject(_this.get()));

		if (protoclone == NULL)
			return NULL;

		protoclone->setParent(NULL);
		crate->transferObject(protoclone, -1, false);
	}

	crate->setCustomObjectName(getCustomObjectName(), false);

	crate->setUseCount(1);

	return crate;
}
void LightsaberCrystalComponentImplementation::tuneCrystal(CreatureObject* player) {
	if(!player->hasSkill("force_title_jedi_rank_01") || !hasPlayerAsParent(player)) {
		return;
	}

	if (getColor() == 31) {
		ManagedReference<PlayerObject*> ghost = player->getPlayerObject();

		if (ghost == NULL)
			return;

		int tuningCost = 100 + (quality * 75);

		if (ghost->getForcePower() <= tuningCost) {
			player->sendSystemMessage("@jedi_spam:no_force_power");
			return;
		}

		ghost->setForcePower(ghost->getForcePower() - tuningCost);
	}

	if (ownerID == 0) {
		validateCrystalStats();

		ownerID = player->getObjectID();
		ownerName = player->getDisplayedName();

		// Color code is lime green.
		String tuneName = StringIdManager::instance()->getStringId(objectName.getFullPath().hashCode()).toString();
		if (getCustomObjectName().toString().contains("(Exceptional)"))
			tuneName = "\\#00FF00" + tuneName + " (Exceptional) (tuned)\\#.";
		else if (getCustomObjectName().toString().contains("(Legendary)"))
			tuneName = "\\#00FF00" + tuneName + " (Legendary) (tuned)\\#.";
		else
			tuneName = "\\#00FF00" + tuneName + " (tuned)\\#.";

		setCustomObjectName(tuneName, true);
		player->notifyObservers(ObserverEventType::TUNEDCRYSTAL, _this.getReferenceUnsafeStaticCast(), 0);
		player->sendSystemMessage("@jedi_spam:crystal_tune_success");
	}
}
int ContainerImplementation::handleObjectMenuSelect(CreatureObject* player, byte selectedID) {
	if (selectedID == 50) {
		if (checkContainerPermission(player, ContainerPermissions::MOVECONTAINER && getParent().get() != NULL &&
				getParent().get()->checkContainerPermission(player, ContainerPermissions::MOVEOUT))) {

			ManagedReference<SuiInputBox*> inputBox = new SuiInputBox(player, SuiWindowType::OBJECT_NAME, 0x00);

			inputBox->setPromptTitle("@sui:set_name_title");
			inputBox->setPromptText("@sui:set_name_prompt");
			inputBox->setUsingObject(_this.getReferenceUnsafeStaticCast());
			inputBox->setMaxInputSize(255);

			inputBox->setDefaultInput(getCustomObjectName().toString());

			player->getPlayerObject()->addSuiBox(inputBox);
			player->sendMessage(inputBox->generateMessage());

			return 0;
		}

	} else if (selectedID == 69 && player->hasSkill("combat_smuggler_novice")) {
		ManagedReference<Facade*> facade = player->getActiveSession(SessionFacadeType::SLICING);
		ManagedReference<SlicingSession*> session = dynamic_cast<SlicingSession*>(facade.get());

		if (session != NULL) {
			player->sendSystemMessage("@slicing/slicing:already_slicing");
			return 0;
		}

		//Create Session
		session = new SlicingSession(player);
		session->initalizeSlicingMenu(player, _this.getReferenceUnsafeStaticCast());

		return 0;

	}

	return TangibleObjectImplementation::handleObjectMenuSelect(player, selectedID);
}
void PowerupObjectImplementation::updateCraftingValues(CraftingValues* values, bool firstUpdate) {
	/// effect 1-100

	Reference<PowerupTemplate*> pup = cast<PowerupTemplate*>(templateObject.get());
	if(pup == NULL) {
		return;
	}

	if(firstUpdate) {

		String key;
		String value;

		if(pup->hasPrimaryAttribute()) {
			PowerupStat stat = pup->getRandomPrimaryAttribute();
			modifiers.add(stat);

			StringBuffer name;
			name << "A " << stat.getName() << " " << pup->getBaseName();

			setCustomObjectName(name.toString(), true);
		}

		type = pup->getType().toLowerCase();
		uses = 100; // Powerups are always 100 uses

	} else {

		if(pup->hasSecondaryAttribute()) {

			PowerupStat stat = pup->getRandomSecondaryAttribute();

			if(System::random(3) == 1) {
				for(int i = 0; i < modifiers.size(); ++i) {
					if(stat == modifiers.get(i))  {
						return;
					}
				}

				if(modifiers.size() == 1) {
					StringBuffer name;
					name << getCustomObjectName().toString() << " of " << stat.getName();

					setCustomObjectName(name.toString(), true);
				}

				modifiers.add(stat);
			}
		}
	}

	float val = values->getCurrentValue("effect");

	for(int i  = 0; i < modifiers.size(); ++i) {
		PowerupStat* stat = &modifiers.get(i);

		// Primary Stat always increases
		if(i == 0) {
			stat->setValue((val / values->getMaxValue("effect")) * MAXPRIMARY);
			continue;
		}

		// First secondary stat has weird rules
		if(i == 1) {

			/// If there is only 1 secondary stat, it increases as expected
			if(modifiers.size() == 2) {

				stat->setValue((val / values->getMaxValue("effect")) * MAXSECONDARY);
				continue;

			/// If there are more than 1 secondary stat, and the values
			/// is less than 10, the first secondary stat doesn't increase
			} else if(modifiers.size() >= 2 && stat->getValue() < 10) {

				continue;
			}
		}

		/// It seems like we divide the change in values between the
		/// Remaining stats
		float statsLeft = modifiers.size() - i;

		float newValue = (val / values->getMaxValue("effect")) * MAXSECONDARY;
		float valueChange = (newValue - stat->getValue()) / statsLeft;

		stat->setValue(stat->getValue() + valueChange);
	}
}