String WeaponObjectImplementation::repairAttempt(int repairChance) {

	String message = "@error_message:";

	if(repairChance < 25) {
		message += "sys_repair_failed";
		setMaxCondition(1, true);
		setConditionDamage(0, true);
	} else if(repairChance < 50) {
		message += "sys_repair_imperfect";
		setMaxCondition(getMaxCondition() * .65f, true);
		setConditionDamage(0, true);
	} else if(repairChance < 75) {
		setMaxCondition(getMaxCondition() * .80f, true);
		setConditionDamage(0, true);
		message += "sys_repair_slight";
	} else {
		setMaxCondition(getMaxCondition() * .95f, true);
		setConditionDamage(0, true);
		message += "sys_repair_perfect";
	}

	return message;
}
void TangibleObjectImplementation::repair(CreatureObject* player) {

	if(player == NULL || player->getZoneServer() == NULL)
		return;

	if(!isASubChildOf(player))
		return;

	if (getConditionDamage() == 0) {
		player->sendSystemMessage("That item is not in need of repair.");
		return;
	}

	//Condition is unrepairable
	if ((getMaxCondition() - getConditionDamage()) <= 0) {
		StringIdChatParameter cantrepair("error_message", "sys_repair_unrepairable");
		cantrepair.setTT(getDisplayedName());
		player->sendSystemMessage(cantrepair); //%TT's condition is beyond repair even for your skills.
		return;
	}

	SceneObject* inventory = player->getSlottedObject("inventory");
	if(inventory == NULL)
		return;

	ManagedReference<RepairTool*> repairTool = NULL;
	Reference<RepairToolTemplate*> repairTemplate = NULL;

	for(int i = 0; i < inventory->getContainerObjectsSize(); ++i) {
		ManagedReference<SceneObject*> item = inventory->getContainerObject(i);
		if(item->isRepairTool()) {
			repairTemplate = cast<RepairToolTemplate*>(item->getObjectTemplate());

			if (repairTemplate == NULL) {
				error("No RepairToolTemplate for: " + String::valueOf(item->getServerObjectCRC()));
				return;
			}

			if(repairTemplate->getRepairType() & getGameObjectType()) {
				repairTool = cast<RepairTool*>(item.get());
				break;
			}
			repairTemplate = NULL;
		}
	}

	if(repairTool == NULL)
		return;

	/// Luck Roll + Profession Mod(25) + Luck Tapes
	/// + Station Mod - BF

	/// Luck Roll
	int roll = System::random(100);
	int repairChance = roll;

	/// Profession Bonus
	if(player->hasSkill(repairTemplate->getSkill()))
		repairChance += 35;

	/// Get Skill mods
	repairChance += player->getSkillMod(repairTemplate->getSkillMod());
	repairChance += player->getSkillMod("crafting_repair");
	repairChance += player->getSkillMod("force_repair_bonus");

	/// use tool quality to lower chances if bad tool
	float quality = 1.f - (((100.f - repairTool->getQuality()) / 2) / 100.f);
	repairChance *= quality;

	ManagedReference<PlayerManager*> playerMan = player->getZoneServer()->getPlayerManager();

	/// Increase if near station
	if(playerMan->getNearbyCraftingStation(player, repairTemplate->getStationType()) != NULL) {
		repairChance += 15;
	}

	/// Subtract battle fatigue
	repairChance -= (player->getShockWounds() / 2);

	/// Subtract complexity
	repairChance -= (getComplexity() / 3);

	/// 5% random failure
	if(getMaxCondition() < 20 || roll < 5)
		repairChance = 0;

	if(roll > 95)
		repairChance = 100;

	String result = repairAttempt(repairChance);

	Locker locker(repairTool);

	repairTool->destroyObjectFromWorld(true);
	repairTool->destroyObjectFromDatabase(true);

	player->sendSystemMessage(result);
}
void LightsaberCrystalComponentImplementation::validateCrystalStats() {
	ManagedReference<LootManager*> lootManager = getZoneServer()->getLootManager();

	if (lootManager == NULL)
		return;

	CrystalData* crystalData = lootManager->getCrystalData(getObjectTemplate()->getTemplateFileName());

	if (crystalData == NULL) {
		error("Unable to find crystal stats for " + getObjectTemplate()->getTemplateFileName());
		return;
	}

	int minStat = crystalData->getMinHitpoints();
	int maxStat = crystalData->getMaxHitpoints();

	if (getMaxCondition() > maxStat || getMaxCondition() < minStat)
		setMaxCondition(getRandomizedStat(minStat, maxStat, itemLevel));

	if (color == 31) {
		minStat = crystalData->getMinDamage();
		maxStat = crystalData->getMaxDamage();

		if (damage > maxStat || damage < minStat)
			damage = getRandomizedStat(minStat, maxStat, itemLevel);

		minStat = crystalData->getMinHealthSac();
		maxStat = crystalData->getMaxHealthSac();

		if (sacHealth > maxStat || sacHealth < minStat)
			sacHealth = getRandomizedStat(minStat, maxStat, itemLevel);

		minStat = crystalData->getMinActionSac();
		maxStat = crystalData->getMaxActionSac();

		if (sacAction > maxStat || sacAction < minStat)
			sacAction = getRandomizedStat(minStat, maxStat, itemLevel);

		minStat = crystalData->getMinMindSac();
		maxStat = crystalData->getMaxMindSac();

		if (sacMind > maxStat || sacMind < minStat)
			sacMind = getRandomizedStat(minStat, maxStat, itemLevel);

		minStat = crystalData->getMinWoundChance();
		maxStat = crystalData->getMaxWoundChance();

		if (woundChance > maxStat || woundChance < minStat)
			woundChance = getRandomizedStat(minStat, maxStat, itemLevel);

		float minFloatStat = crystalData->getMinForceCost();
		float maxFloatStat = crystalData->getMaxForceCost();

		if (floatForceCost > maxFloatStat || floatForceCost < minFloatStat)
			floatForceCost = getRandomizedStat(minFloatStat, maxFloatStat, itemLevel);

		minFloatStat = crystalData->getMinAttackSpeed();
		maxFloatStat = crystalData->getMaxAttackSpeed();

		if (attackSpeed > maxFloatStat || attackSpeed < minFloatStat)
			attackSpeed = Math::getPrecision(getRandomizedStat(minFloatStat, maxFloatStat, itemLevel), 2);
	}
}