// ============================== DURATION/PROBABILITY ===============================
    // -----------------------------------------------------------------------------------
    // UCE_Harvesting_CanBoost
    // -----------------------------------------------------------------------------------
    public bool UCE_Harvesting_CanBoost()
    {
        UCE_HarvestingProfessionRequirement requiredProfession = getRequiredHarvestingProfession();
        UCE_HarvestingProfession profession = getHarvestingProfession(requiredProfession);

        if (profession.template.optionalTools.Length <= 0) return false;

        bool bValid = false;

        foreach (UCE_HarvestingTool tool in profession.template.optionalTools)
        {
            if (
                (!tool.equippedItem && InventoryCount(new Item(tool.requiredItem)) >= 1) ||
                (tool.equippedItem && UCE_checkHasEquipment(tool.requiredItem))
                )
            {
                bValid = true;
            }
            else
            {
                bValid = false;
            }
        }

        return bValid;
    }
    // -----------------------------------------------------------------------------------
    // getHarvestingProfession
    // Returns the required profession of the player, that the player is capable of using
    // -----------------------------------------------------------------------------------
    public UCE_HarvestingProfession getHarvestingProfession(UCE_HarvestingProfessionRequirement tmpl)
    {
        if (HasHarvestingProfessionLevel(tmpl.template, tmpl.level))
        {
            int id = UCE_Professions.FindIndex(x => x.templateName == tmpl.template.name);
            return UCE_Professions[id];
        }

        return new UCE_HarvestingProfession();
    }
    // -----------------------------------------------------------------------------------
    // UCE_HarvestingProbability
    // -----------------------------------------------------------------------------------
    public float UCE_HarvestingProbability(bool boost)
    {
        float proba = 0f;

        UCE_HarvestingProfessionRequirement requiredProfession = getRequiredHarvestingProfession();
        UCE_HarvestingProfession            profession         = getHarvestingProfession(requiredProfession);

        // -- Modificator: Profession Skill

        proba = profession.template.baseHarvestChance;

        // -- Modificator: Node Level vs. Skill Level

        if (profession.level > requiredProfession.level)
        {
            proba += (profession.level - requiredProfession.level) * profession.template.probabilityPerSkillLevel;
        }

        // -- Modificator: Required Tools

        foreach (UCE_HarvestingTool tool in profession.template.tools)
        {
            if ((!tool.equippedItem && InventoryCount(new Item(tool.requiredItem)) >= 1) || (tool.equippedItem && UCE_checkHasEquipment(tool.requiredItem)))
            {
                proba += tool.modifyProbability;
                if (!profession.template.requiresAllTools)
                {
                    break;
                }
            }
        }

        // -- Modificator: Optional Tools

        if (boost)
        {
            foreach (UCE_HarvestingTool tool in profession.template.optionalTools)
            {
                if ((!tool.equippedItem && InventoryCount(new Item(tool.requiredItem)) >= 1) || (tool.equippedItem && UCE_checkHasEquipment(tool.requiredItem)))
                {
                    proba += tool.modifyProbability;
                    break;
                }
            }
        }

        return(proba);
    }
    // -----------------------------------------------------------------------------------
    // UCE_HarvestingDuration
    // -----------------------------------------------------------------------------------
    public float UCE_HarvestingDuration(bool boost)
    {
        float duration = 0f;
        int   level    = 0;

        UCE_HarvestingProfessionRequirement requiredProfession = getRequiredHarvestingProfession();
        UCE_HarvestingProfession            profession         = getHarvestingProfession(requiredProfession);

        duration = UCE_selectedResourceNode.harvestDuration;

        // -- Modificator: Skill

        duration += level * profession.template.durationPerSkillLevel;

        // -- Modificator: Required Tools

        foreach (UCE_HarvestingTool tool in profession.template.tools)
        {
            if ((!tool.equippedItem && InventoryCount(new Item(tool.requiredItem)) >= 1) || (tool.equippedItem && UCE_checkHasEquipment(tool.requiredItem)))
            {
                duration += tool.modifyDuration;
                if (!profession.template.requiresAllTools)
                {
                    break;
                }
            }
        }

        // -- Modificator: Optional Tools

        if (boost)
        {
            foreach (UCE_HarvestingTool tool in profession.template.optionalTools)
            {
                if ((!tool.equippedItem && InventoryCount(new Item(tool.requiredItem)) >= 1) || (tool.equippedItem && UCE_checkHasEquipment(tool.requiredItem)))
                {
                    duration += tool.modifyDuration;
                    break;
                }
            }
        }

        return(duration);
    }
    // -----------------------------------------------------------------------------------
    // UCE_HarvestingExperience
    // -----------------------------------------------------------------------------------
    public int UCE_HarvestingExperience(bool boost)
    {
        int exp = 0;

        UCE_HarvestingProfessionRequirement requiredProfession = getRequiredHarvestingProfession();
        UCE_HarvestingProfession            profession         = getHarvestingProfession(requiredProfession);

        // -- Modificator: Resource Node

        exp = UnityEngine.Random.Range(UCE_selectedResourceNode.ProfessionExperienceRewardMin, UCE_selectedResourceNode.ProfessionExperienceRewardMax);

        // -- Modificator: Required Tools

        foreach (UCE_HarvestingTool tool in profession.template.tools)
        {
            if ((!tool.equippedItem && InventoryCount(new Item(tool.requiredItem)) >= 1) || (tool.equippedItem && UCE_checkHasEquipment(tool.requiredItem)))
            {
                exp += UnityEngine.Random.Range(tool.modifyExperienceMin, tool.modifyExperienceMax);
                if (!profession.template.requiresAllTools)
                {
                    break;
                }
            }
        }

        // -- Modificator: Optional Tools

        if (boost)
        {
            foreach (UCE_HarvestingTool tool in profession.template.optionalTools)
            {
                if ((!tool.equippedItem && InventoryCount(new Item(tool.requiredItem)) >= 1) || (tool.equippedItem && UCE_checkHasEquipment(tool.requiredItem)))
                {
                    exp += UnityEngine.Random.Range(tool.modifyExperienceMin, tool.modifyExperienceMax);
                    break;
                }
            }
        }

        return(exp);
    }
    public void Cmd_UCE_FinishHarvest()
    {
        if (UCE_HarvestingValidation())
        {
            UCE_removeTask();
            UCE_stopTimer();

            UCE_HarvestingResult harvestingResult = UCE_HarvestingResult.None;

            // --------------------------------------------------------------------------- Experience

            UCE_HarvestingProfessionRequirement requiredProfession = getRequiredHarvestingProfession();
            UCE_HarvestingProfession profession = getHarvestingProfession(requiredProfession);

            harvestBooster = UCE_Harvesting_CanBoost();

            float harvestChance = UCE_HarvestingProbability(harvestBooster);
            float harvestCritChance = UCE_HarvestingCriticalProbability(harvestBooster);
            int nodeLevel = requiredProfession.level;
            int oldLevel = profession.level;
            int exp = UCE_HarvestingExperience(harvestBooster);
            profession.experience += exp;

            SetHarvestingProfession(profession);

            if (exp > 0)
                UCE_TargetAddMessage(exp.ToString() + " " + profession.template.name + " " + UCE_selectedResourceNode.experienceMessage);

        #if _iMMOTOOLS
            if (oldLevel < profession.level)
                UCE_ShowPopup(UCE_selectedResourceNode.levelUpMessage + profession.templateName + " [L" + profession.level + "]");
        #endif

            // --------------------------------------------------------------------------- Skill Check

            if (UnityEngine.Random.value <= harvestChance)
            {
                harvestingResult = UCE_HarvestingResult.Success;

                if (UnityEngine.Random.value <= harvestCritChance)
                    harvestingResult = UCE_HarvestingResult.CriticalSuccess;
            }
            else
            {
                harvestingResult = UCE_HarvestingResult.Failure;
            }

            // --------------------------------------------------------------------------- Deplete other Costs (mana etc.)

            mana -= UCE_selectedResourceNode.manaCost;

            // --------------------------------------------------------------------------- Check Tool breakage

            foreach (UCE_HarvestingTool tool in profession.template.tools)
            {
                if ((!tool.equippedItem && InventoryCount(new Item(tool.requiredItem)) >= 1) || (tool.equippedItem && UCE_checkHasEquipment(tool.requiredItem)))
                {
                    if (UnityEngine.Random.value <= tool.toolDestroyChance)
                    {
                        if (tool.equippedItem)
                            UCE_removeEquipment(tool.requiredItem);
                        else
                            InventoryRemove(new Item(tool.requiredItem), 1);
                        UCE_TargetAddMessage(UCE_selectedResourceNode.breakMessage);
                    }
                }
            }

            if (harvestBooster)
            {
                foreach (UCE_HarvestingTool tool in profession.template.optionalTools)
                {
                    if ((!tool.equippedItem && InventoryCount(new Item(tool.requiredItem)) >= 1) || (tool.equippedItem && UCE_checkHasEquipment(tool.requiredItem)))
                    {
                        if (UnityEngine.Random.value <= tool.toolDestroyChance)
                        {
                            if (tool.equippedItem)
                                UCE_removeEquipment(tool.requiredItem);
                            else
                                InventoryRemove(new Item(tool.requiredItem), 1);
                            UCE_TargetAddMessage(UCE_selectedResourceNode.boosterMessage);
                        }
                    }
                }
            }

            // --------------------------------------------------------------------------- Resources

            if (harvestingResult != UCE_HarvestingResult.Failure)
            {
                if (harvestingResult == UCE_HarvestingResult.CriticalSuccess)
                {
                    UCE_selectedResourceNode.OnCritical();
                    UCE_TargetAddMessage(UCE_selectedResourceNode.criticalSuccessMessage);
                }
                else
                {
                    UCE_TargetAddMessage(UCE_selectedResourceNode.successMessage);
                }

                Target_UCE_finishResourceNodeAccess(connectionToClient);

                UCE_selectedResourceNode.OnHarvested();
                UCE_selectedResourceNode.OnDepleted();

        #if _iMMOHARVESTING && _iMMOQUESTS
                UCE_IncreaseHarvestNodeCounterFor(profession.template);
        #endif
            }
            else
            {
                UCE_ShowPrompt(UCE_selectedResourceNode.failedMessage);
            }

            // --------------------------------------------------------------------------- Cleanup

            //UCE_cancelHarvesting();
            harvestBooster = false;
        }
    }