//::///////////////////////////////////////////////
//:: Magic of Incarnum events
//:: moi_events
//::///////////////////////////////////////////////
/** @file
    Does all MoI content that require event scripting.

    @author Stratovarius
    @date   Created - 2019.12.31
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////

#include "moi_inc_moifunc"
#include "prc_inc_combmove"
#include "pnp_shft_main" // Silly horse system
#include "x0_i0_modes"
#include "inc_addragebonus"

//////////////////////////////////////////////////
/*             Content Functions                */
//////////////////////////////////////////////////

void BloodwarGauntlets(object oMeldshaper, object oItem, int nEvent)
{
	if (GetIsMeldBound(oMeldshaper, MELD_BLOODWAR_GAUNTLETS) != CHAKRA_HANDS) return;
	
	if(nEvent == EVENT_ONPLAYEREQUIPITEM)
    {
		IPSafeAddItemProperty(oItem, ItemPropertyKeen(), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);	       
    }
    // We are called from the OnPlayerUnEquipItem eventhook. Remove OnHitCast: Unique Power from oMeldshaper's weapon
    else if(nEvent == EVENT_ONPLAYERUNEQUIPITEM)
    {
    	RemoveSpecificProperty(oItem, ITEM_PROPERTY_KEEN, -1, -1, 1, "", -1, DURATION_TYPE_TEMPORARY);  
    }	
}

void Bloodtalons(object oMeldshaper, object oItem, object oTarget)
{
	if (GetIsMeldBound(oMeldshaper, MELD_BLOODTALONS) != CHAKRA_TOTEM) return;
    
    if(oItem == GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oMeldshaper) || oItem == GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oMeldshaper)) 
    {
    	// Living creatures only
    	if (PRCGetIsAliveCreature(oTarget))
    	{	
        	effect eDam = EffectDamage(GetEssentiaInvested(oMeldshaper, MELD_BLOODTALONS), DAMAGE_TYPE_BASE_WEAPON);
        	DelayCommand(6.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
        }	
    }// end if - Item is a melee weapon 	
}

void DreadCarapace(object oMeldshaper)
{
	object oLeft  = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oMeldshaper);
	object oRight = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oMeldshaper);
	object oBite  = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oMeldshaper);
	int nEssentia = GetEssentiaInvested(oMeldshaper, MELD_DREAD_CARAPACE);
	
    if (GetIsObjectValid(oLeft)) 
    {
    	IPSafeAddItemProperty(oLeft, ItemPropertyAttackPenalty(nEssentia+1), 6.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
    	IPSafeAddItemProperty(oLeft, ItemPropertyDamageBonus(DAMAGE_TYPE_SLASHING, IPDamageConstant(nEssentia+1)), 6.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
    }	
    if (GetIsObjectValid(oRight)) 
    {
    	IPSafeAddItemProperty(oRight, ItemPropertyAttackPenalty(nEssentia+1), 6.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
    	IPSafeAddItemProperty(oRight, ItemPropertyDamageBonus(DAMAGE_TYPE_SLASHING, IPDamageConstant(nEssentia+1)), 6.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
    }
    if (GetIsObjectValid(oBite)) 
    {
    	IPSafeAddItemProperty(oBite, ItemPropertyAttackPenalty(nEssentia+1), 6.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
    	IPSafeAddItemProperty(oBite, ItemPropertyDamageBonus(DAMAGE_TYPE_SLASHING, IPDamageConstant((nEssentia+1)*2)), 6.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
    }
	
    if (GetIsMeldBound(oMeldshaper, MELD_DREAD_CARAPACE) == CHAKRA_ARMS)
    {
    	if (GetIsObjectValid(oLeft)) IPSafeAddItemProperty(oLeft, ItemPropertyKeen(), 6.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
    	if (GetIsObjectValid(oRight)) IPSafeAddItemProperty(oRight, ItemPropertyKeen(), 6.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
    	if (GetIsObjectValid(oBite)) IPSafeAddItemProperty(oBite, ItemPropertyKeen(), 6.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
    }	
}

void FearsomeMask(object oMeldshaper)
{
	location lTarget = GetLocation(oMeldshaper);
	int nDC = GetMeldshaperDC(oMeldshaper, CLASS_TYPE_SOULBORN, MELD_FEARSOME_MASK);
    object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, FeetToMeters(30.0), lTarget, TRUE, OBJECT_TYPE_CREATURE);
    //Cycle through the targets within the spell shape until an invalid object is captured.
    while (GetIsObjectValid(oTarget))
    {
        if (GetIsEnemy(oMeldshaper, oTarget))
        {
			if(!PRCMySavingThrow(SAVING_THROW_WILL, oTarget, nDC, SAVING_THROW_TYPE_MIND_SPELLS))
				ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectShaken(), oTarget, 60.0);
        }
       //Select the next target within the spell shape.
       oTarget = MyNextObjectInShape(SHAPE_SPHERE, FeetToMeters(30.0), lTarget, TRUE, OBJECT_TYPE_CREATURE);
    }	
}

void GirallonArms(object oMeldshaper)
{
	object oLeft  = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oMeldshaper);
	object oRight = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oMeldshaper);
	int nEssentia = GetEssentiaInvested(oMeldshaper, MELD_GIRALLON_ARMS);
	
    if (GetIsObjectValid(oLeft)) 
    	IPSafeAddItemProperty(oLeft, ItemPropertyEnhancementBonus(nEssentia), 6.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);	
    if (GetIsObjectValid(oRight)) 
    	IPSafeAddItemProperty(oRight, ItemPropertyEnhancementBonus(nEssentia), 6.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
}

void HeartOfFire(object oMeldshaper)
{
	int nEssentia = GetEssentiaInvested(oMeldshaper, MELD_HEART_OF_FIRE);
	//FloatingTextStringOnCreature("Heart of Fire heartbeat", oMeldshaper);
    if (GetIsMeldBound(oMeldshaper, MELD_HEART_OF_FIRE) == CHAKRA_TOTEM)
    {
    	
		object oLeft  = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oMeldshaper);
		object oRight = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oMeldshaper);
		object oBite  = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oMeldshaper);   
		
		int nDamage = EssentiaToD4(nEssentia);
		//FloatingTextStringOnCreature("Heart of Fire heartbeat Damage is "+IntToString(nDamage), oMeldshaper);
    
    	if (GetIsObjectValid(oLeft)) 
    	{
    		//FloatingTextStringOnCreature("Heart of Fire oLeft is "+GetName(oLeft), oMeldshaper);
    		IPSafeAddItemProperty(oLeft, ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, nDamage), 6.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
    		AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, nDamage), oLeft, 6.0);
    		//if (!GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oMeldshaper))) ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(d6(nEssentia), DAMAGE_TYPE_FIRE), oTarget);
    	}	
    	if (GetIsObjectValid(oRight)) 
    	{
    		//FloatingTextStringOnCreature("Heart of Fire oRight is "+GetName(oRight), oMeldshaper);
			IPSafeAddItemProperty(oRight, ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, nDamage), 6.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
			AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, nDamage), oRight, 6.0);
		}	
    	if (GetIsObjectValid(oBite)) 
    	{
    		//FloatingTextStringOnCreature("Heart of Fire oBite is "+GetName(oBite), oMeldshaper);
			IPSafeAddItemProperty(oBite, ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, nDamage), 6.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
			AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, nDamage), oBite, 6.0);
		}	
	}
}

void HeartOfFireOnHit(object oMeldshaper, object oTarget)
{
	int nEssentia = GetEssentiaInvested(oMeldshaper, MELD_HEART_OF_FIRE);
	object oRight = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget);
    if (!GetIsObjectValid(oRight)) // If they don't have a weapon in their right hand and hit us, it was a natural attack
		ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(d6(nEssentia), DAMAGE_TYPE_FIRE), oTarget);
}

void _DoPush(object oTarget, object oMeldshaper)
{
        // Calculate how far the creature gets pushed
        float fDistance = FeetToMeters(50.0f);
        // Determine if they hit a wall on the way
        location lTrueSpeaker  = GetLocation(oMeldshaper);
        location lTargetOrigin = GetLocation(oTarget);
        vector vAngle          = AngleToVector(GetRelativeAngleBetweenLocations(lTrueSpeaker, lTargetOrigin));
        vector vTargetOrigin   = GetPosition(oTarget);
        vector vTarget         = vTargetOrigin + (vAngle * fDistance);
        
        if(!LineOfSightVector(vTargetOrigin, vTarget))
        {
                // Hit a wall, binary search for the wall
                float fEpsilon    = 1.0f;          // Search precision
                float fLowerBound = 0.0f;          // The lower search bound, initialise to 0
                float fUpperBound = fDistance;     // The upper search bound, initialise to the initial distance
                fDistance         = fDistance / 2; // The search position, set to middle of the range
                
                do
                {
                        // Create test vector for this iteration
                        vTarget = vTargetOrigin + (vAngle * fDistance);
                        
                        // Determine which bound to move.
                        if(LineOfSightVector(vTargetOrigin, vTarget))
                        fLowerBound = fDistance;
                        else
                        fUpperBound = fDistance;
                        
                        // Get the new middle point
                        fDistance = (fUpperBound + fLowerBound) / 2;
                }
                while(fabs(fUpperBound - fLowerBound) > fEpsilon);
        }
        
        // Create the final target vector
        vTarget = vTargetOrigin + (vAngle * fDistance);
        
        // Move the target
        location lTargetDestination = Location(GetArea(oTarget), vTarget, GetFacing(oTarget));
        AssignCommand(oTarget, ClearAllActions(TRUE));
        AssignCommand(oTarget, JumpToLocation(lTargetDestination));
}

void LammasuRepulsion(object oMeldshaper)
{
    location lTarget = GetLocation(oMeldshaper);
    object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, FeetToMeters(30.0), lTarget, FALSE, OBJECT_TYPE_CREATURE);
    {
        if(GetAssociateType(oTarget) == ASSOCIATE_TYPE_SUMMONED)
        {
	        _DoPush(oTarget, oMeldshaper);
        }
        //Get next target.
        oTarget = MyNextObjectInShape(SHAPE_SPHERE, FeetToMeters(30.0), lTarget, FALSE, OBJECT_TYPE_CREATURE);
    }
}

void LammasuAllies(object oMeldshaper)
{
    location lTarget   = GetLocation(oMeldshaper);
	int nEssentia      = GetEssentiaInvested(oMeldshaper, MELD_LAMMASU_MANTLE);
    effect eLink       = EffectACIncrease(2, AC_DEFLECTION_BONUS);
    
    if (nEssentia) eLink = EffectLinkEffects(eLink, EffectSavingThrowIncrease(SAVING_THROW_ALL, nEssentia));
    
    object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, FeetToMeters(10.0), lTarget, FALSE, OBJECT_TYPE_CREATURE);
    {
        if(GetIsFriend(oMeldshaper, oTarget))
        {
	        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(VersusAlignmentEffect(eLink, ALIGNMENT_ALL, ALIGNMENT_EVIL)), oTarget, 6.0);
        }
        //Get next target.
        oTarget = MyNextObjectInShape(SHAPE_SPHERE, FeetToMeters(10.0), lTarget, FALSE, OBJECT_TYPE_CREATURE);
    }
}

void MantleOfFlameOnHit(object oMeldshaper, object oTarget)
{
	if (GetDistanceBetween(oMeldshaper, oTarget) <= FeetToMeters(10.0f))
	{
		int nEssentia = GetEssentiaInvested(oMeldshaper, MELD_MANTLE_OF_FLAME);
		ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(d6(nEssentia+1), DAMAGE_TYPE_FIRE), oTarget);
	}	
}

void PhaseCloak(object oMeldshaper)
{
    // Check to see if the WP is valid
    string sWPTag = "PhaseCloakWP_" + GetName(oMeldshaper);
    object oTestWP = GetWaypointByTag(sWPTag);
    if (!GetIsObjectValid(oTestWP))
    {
        // Create waypoint for the movement
        CreateObject(OBJECT_TYPE_WAYPOINT, "nw_waypoint001", GetLocation(oMeldshaper), FALSE, sWPTag);
    }
    else // We have a test waypoint, now to check the distance
    {
        // Distance moved in the last round
        float fDist = GetDistanceBetween(oMeldshaper, oTestWP);
        // Distance needed to move
        float fCheck = FeetToMeters(5.0);

        // Now clean up the WP and create a new one for next round's check
        DestroyObject(oTestWP);
        CreateObject(OBJECT_TYPE_WAYPOINT, "nw_waypoint001", GetLocation(oMeldshaper), FALSE, sWPTag);

        // Moved the distance
        if (fDist >= fCheck)
        {
			SetIncorporeal(oMeldshaper, 3.0, 1);
        }
    }
}

void PlanarWard(object oMeldshaper, object oTarget)
{
	if (MyPRCGetRacialType(oTarget) != RACIAL_TYPE_OUTSIDER || GetLocalInt(oTarget, "PlanarWardImmune")) return; // Outsiders only past this point
	
	int nDC = GetMeldshaperDC(oMeldshaper, CLASS_TYPE_INCARNATE, MELD_PLANAR_WARD) + GetMeldshaperLevel(oMeldshaper, CLASS_TYPE_INCARNATE, MELD_PLANAR_WARD) - GetHitDice(oTarget);
	
	if(!PRCMySavingThrow(SAVING_THROW_WILL, oTarget, nDC, SAVING_THROW_TYPE_NONE))
		ApplyEffectToObject(DURATION_TYPE_INSTANT, SupernaturalEffect(EffectDeath(TRUE)), oTarget);
	else
		SetLocalInt(oTarget, "PlanarWardImmune", TRUE);
}

void RageClaws(object oMeldshaper)
{
	effect eLink = EffectLinkEffects(EffectAttackIncrease(2), EffectDamageIncrease(DAMAGE_BONUS_2, DAMAGE_TYPE_BASE_WEAPON));
		   eLink = EffectLinkEffects(eLink, EffectSavingThrowIncrease(SAVING_THROW_FORT, 2));
		   
	if (GetHitDice(oMeldshaper) >= GetCurrentHitPoints(oMeldshaper))
		ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(eLink), oMeldshaper, 6.0);
}

void RidingBracers(object oMeldshaper)
{
    if (PRCHorseGetIsMounted(oMeldshaper))
    {	
		if(GetIsMeldBound(oMeldshaper, MELD_RIDING_BRACERS) == CHAKRA_ARMS)
			ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(EffectLinkEffects(EffectACIncrease(2, AC_DODGE_BONUS), EffectDamageIncrease(DAMAGE_BONUS_2, DAMAGE_TYPE_BASE_WEAPON))), oMeldshaper, 6.0);
		
		if(GetIsMeldBound(oMeldshaper, MELD_RIDING_BRACERS) == CHAKRA_TOTEM)
			IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_FEAT_EVASION), 6.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
	}	
}

void TotemAvatar(object oMeldshaper)
{
	int nDamageBonus;
	if (GetIsMeldBound(oMeldshaper, MELD_TOTEM_AVATAR) == CHAKRA_SHOULDERS)
		nDamageBonus += 2;
	
	if (GetIsMeldBound(oMeldshaper, MELD_TOTEM_AVATAR) == CHAKRA_TOTEM) 
		nDamageBonus += GetEssentiaInvested(oMeldshaper, MELD_TOTEM_AVATAR);


	object oRight = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oMeldshaper);
    if (!GetIsObjectValid(oRight)) // If they don't have a weapon in their right hand, it was a natural attack
		ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectDamageIncrease(IPGetDamageBonusConstantFromNumber(nDamageBonus), DAMAGE_TYPE_BASE_WEAPON), oMeldshaper, 6.0);
}

void WorgPeltHB(object oMeldshaper)
{
	object oLeft  = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oMeldshaper);
	object oBite  = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oMeldshaper);
	
	if (GetIsObjectValid(oLeft))
    {       
        // Add eventhook to the armor
        IPSafeAddItemProperty(oLeft, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 6.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
        AddEventScript(oLeft, EVENT_ITEM_ONHIT, "moi_events", TRUE, FALSE);
    }  	
	if (GetIsObjectValid(oBite))
    {       
        // Add eventhook to the armor
        IPSafeAddItemProperty(oBite, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 6.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
        AddEventScript(oBite, EVENT_ITEM_ONHIT, "moi_events", TRUE, FALSE);
    } 	
}

void WorgPeltOnHit(object oMeldshaper, object oItem, object oTarget)
{
	if (GetIsMeldBound(oMeldshaper, MELD_WORG_PELT) != CHAKRA_HANDS) return;
    
    if(oItem == GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oMeldshaper) || oItem == GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oMeldshaper)) 
    {
		DoTrip(oMeldshaper, oTarget, 0, FALSE, FALSE, TRUE);
    }// end if - Item is a melee weapon 	
}

void CobaltExpertise(object oMeldshaper)
{
    // Only applies when using expertise
    if(GetModeActive(ACTION_MODE_EXPERTISE) || GetActionMode(oMeldshaper, ACTION_MODE_EXPERTISE) || GetLastAttackMode(oMeldshaper) == COMBAT_MODE_EXPERTISE ||
       GetModeActive(ACTION_MODE_IMPROVED_EXPERTISE) || GetActionMode(oMeldshaper, ACTION_MODE_IMPROVED_EXPERTISE) || GetLastAttackMode(oMeldshaper) == COMBAT_MODE_IMPROVED_EXPERTISE)
    {
       ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectACIncrease(GetEssentiaInvestedFeat(oMeldshaper, FEAT_COBALT_EXPERTISE)), oMeldshaper, 6.0);
    }
}

void CobaltPower(object oMeldshaper)
{
    // Only applies when using expertise
    if(GetModeActive(ACTION_MODE_POWER_ATTACK) || GetActionMode(oMeldshaper, ACTION_MODE_POWER_ATTACK) || GetLastAttackMode(oMeldshaper) == COMBAT_MODE_POWER_ATTACK ||
       GetModeActive(ACTION_MODE_IMPROVED_POWER_ATTACK) || GetActionMode(oMeldshaper, ACTION_MODE_IMPROVED_POWER_ATTACK) || GetLastAttackMode(oMeldshaper) == COMBAT_MODE_IMPROVED_POWER_ATTACK)
    {
    	int nDamageType = GetDamageTypeOfWeapon(INVENTORY_SLOT_RIGHTHAND, oMeldshaper);
       	ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectDamageIncrease(IPGetDamageBonusConstantFromNumber(GetEssentiaInvestedFeat(oMeldshaper, FEAT_COBALT_POWER)), nDamageType), oMeldshaper, 6.0);
    }
}

void MidnightDodge(object oMeldshaper)
{
   ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectACIncrease(GetEssentiaInvestedFeat(oMeldshaper, FEAT_MIDNIGHT_DODGE)), oMeldshaper, 6.0);
}

void IncandescentAura(object oMeldshaper)
{
    int nEssentia      = GetEssentiaInvested(oMeldshaper, MELD_INCANDESCENT_AURA);

    if (nEssentia) 
    {
    	location lTarget = GetLocation(oMeldshaper);
    	// Use the function to get the closest creature as a target
    	object oAreaTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lTarget, TRUE, OBJECT_TYPE_CREATURE);
    	while(GetIsObjectValid(oAreaTarget))
    	{
    	    if(oAreaTarget != oMeldshaper && // Not you
    	       GetIsInMeleeRange(oMeldshaper, oAreaTarget) && // They must be in melee range
    	       GetIsEnemy(oAreaTarget, oMeldshaper)) // Only enemies
    	    {
    	    	int nDamage = d6(nEssentia);
    	    	int nDC = 10 + nEssentia + GetAbilityModifier(ABILITY_CHARISMA, oMeldshaper);
    	    	if(PRCMySavingThrow(SAVING_THROW_WILL, oAreaTarget, nDC, SAVING_THROW_TYPE_NONE))
    	    		nDamage /= 2;
    	        ApplyEffectToObject(DURATION_TYPE_INSTANT, SupernaturalEffect(EffectDamage(nDamage, DAMAGE_TYPE_POSITIVE)), oAreaTarget);
    	    }
    	//Select the next target within the spell shape.
    	oAreaTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lTarget, TRUE, OBJECT_TYPE_CREATURE);
    	}	
    }  
}   

void NecroVestmentsAura(object oMeldshaper)
{
   	int nClass = GetMeldShapedClass(oMeldshaper, MELD_NECROCARNUM_VESTMENTS);
	int nDC = GetMeldshaperDC(oMeldshaper, nClass, MELD_NECROCARNUM_VESTMENTS); 
    	location lTarget = GetLocation(oMeldshaper);
    	// Use the function to get the closest creature as a target
    	object oAreaTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_SMALL, lTarget, TRUE, OBJECT_TYPE_CREATURE);
    	while(GetIsObjectValid(oAreaTarget))
    	{
    	    if(oAreaTarget != oMeldshaper && // Not you
    	       GetIsInMeleeRange(oMeldshaper, oAreaTarget) && // They must be in melee range
    	       GetIsEnemy(oAreaTarget, oMeldshaper)) // Only enemies
    	    {
    	    	int nDamage = d6();
    	    	if(!PRCMySavingThrow(SAVING_THROW_FORT, oAreaTarget, nDC, SAVING_THROW_TYPE_COLD))
    	    		ApplyEffectToObject(DURATION_TYPE_INSTANT, SupernaturalEffect(EffectDamage(nDamage, DAMAGE_TYPE_COLD)), oAreaTarget);
    	    }
    	//Select the next target within the spell shape.
    	oAreaTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_SMALL, lTarget, TRUE, OBJECT_TYPE_CREATURE);
    	}	
} 

void NecrocarnumWeaponHands(object oMeldshaper, object oTarget, object oItem)
{
	if (PRCGetIsAliveCreature(oTarget) && (d20() >= GetWeaponCriticalRange(oMeldshaper, oItem) || GetLocalInt(oTarget, "PRCCombat_CriticalHit")))
	{
		int nEssentia      = GetEssentiaInvested(oMeldshaper, MELD_NECROCARNUM_WEAPON);
    	SetTemporaryEssentia(oMeldshaper, nEssentia);
    	DelayCommand(60.0, SetTemporaryEssentia(oMeldshaper, nEssentia*-1)); 
    }	
}

//////////////////////////////////////////////////
/*       Void Main and Event Triggers           */
//////////////////////////////////////////////////

void main()
{
    int nEvent = GetRunningEvent();
    if(DEBUG) DoDebug("moi_events running, event: " + IntToString(nEvent));

    // Get the PC. This is event-dependent
    object oMeldshaper;
    switch(nEvent)
    {
        case EVENT_ITEM_ONHIT:          oMeldshaper = OBJECT_SELF;               break;
        case EVENT_ONPLAYEREQUIPITEM:   oMeldshaper = GetItemLastEquippedBy();   break;
        case EVENT_ONPLAYERUNEQUIPITEM: oMeldshaper = GetItemLastUnequippedBy(); break;
        case EVENT_ONHEARTBEAT:         oMeldshaper = OBJECT_SELF;               break;
        case EVENT_ONPLAYERREST_FINISHED:   oMeldshaper = GetLastBeingRested();      break;

        default:
            oMeldshaper = OBJECT_SELF;
    }

    object oItem;

    // We aren't being called from any event, instead from EvalPRCFeats
    if(nEvent == FALSE)
    {
        // Hook in the events
        if(DEBUG) DoDebug("moi_events: Adding eventhooks");
        AddEventScript(oMeldshaper, EVENT_ONPLAYEREQUIPITEM,     "moi_events", TRUE, FALSE);
        AddEventScript(oMeldshaper, EVENT_ONPLAYERUNEQUIPITEM,   "moi_events", TRUE, FALSE);
        AddEventScript(oMeldshaper, EVENT_ONHEARTBEAT,           "moi_events", TRUE, FALSE);
        AddEventScript(oMeldshaper, EVENT_ONPLAYERREST_FINISHED, "moi_events", TRUE, FALSE); 
        object oSkin = GetPCSkin(oMeldshaper);
        
        // Benefits from the Open Chakra feats
        if(GetHasFeat(FEAT_OPEN_LEAST_CHAKRA_CROWN     , oMeldshaper)) SetCompositeBonus(oSkin, "OpenChakraCrown", 1, ITEM_PROPERTY_SAVING_THROW_BONUS_SPECIFIC, IP_CONST_SAVEBASETYPE_WILL);
        if(GetHasFeat(FEAT_OPEN_LEAST_CHAKRA_FEET      , oMeldshaper)) 
        {
        	SetCompositeBonus(oSkin, "OpenChakraFeet_B", 1, ITEM_PROPERTY_SKILL_BONUS, SKILL_BALANCE);
        	SetCompositeBonus(oSkin, "OpenChakraFeet_M", 1, ITEM_PROPERTY_SKILL_BONUS, SKILL_MOVE_SILENTLY);
        }
        if(GetHasFeat(FEAT_OPEN_LEAST_CHAKRA_HANDS     , oMeldshaper)) 
        {
        	SetCompositeBonus(oSkin, "OpenChakraHands_C", 1, ITEM_PROPERTY_SKILL_BONUS, SKILL_CLIMB);
        	SetCompositeBonus(oSkin, "OpenChakraHands_J", 1, ITEM_PROPERTY_SKILL_BONUS, SKILL_JUMP);
        }        
        if(GetHasFeat(FEAT_OPEN_LESSER_CHAKRA_BROW     , oMeldshaper)) 
        {
        	SetCompositeBonus(oSkin, "OpenChakraBrow_E", 1, ITEM_PROPERTY_SKILL_BONUS, SKILL_SEARCH);
        	SetCompositeBonus(oSkin, "OpenChakraBrow_P", 1, ITEM_PROPERTY_SKILL_BONUS, SKILL_SPOT);
        }
        if(GetHasFeat(FEAT_OPEN_LESSER_CHAKRA_SHOULDERS, oMeldshaper)) SetCompositeBonus(oSkin, "OpenChakraShoulders", 1, ITEM_PROPERTY_SAVING_THROW_BONUS_SPECIFIC, IP_CONST_SAVEBASETYPE_REFLEX);
        if(GetHasFeat(FEAT_OPEN_GREATER_CHAKRA_THROAT  , oMeldshaper)) 
        {
        	SetCompositeBonus(oSkin, "OpenChakraThroat_B", 1, ITEM_PROPERTY_SKILL_BONUS, SKILL_BLUFF);
        	SetCompositeBonus(oSkin, "OpenChakraThroat_P", 1, ITEM_PROPERTY_SKILL_BONUS, SKILL_PERSUADE);
        }        
        if(GetHasFeat(FEAT_OPEN_GREATER_CHAKRA_WAIST   , oMeldshaper)) SetCompositeBonus(oSkin, "OpenChakraWaist", 1, ITEM_PROPERTY_SAVING_THROW_BONUS_SPECIFIC, IP_CONST_SAVEBASETYPE_FORTITUDE);
    }
    else if(nEvent == EVENT_ITEM_ONHIT)
    {
        oItem          = GetSpellCastItem();
        object oTarget = PRCGetSpellTargetObject();
        if(DEBUG) DoDebug("moi_events: OnHit:\n"
                        + "oMeldshaper = " + DebugObject2Str(oMeldshaper) + "\n"
                        + "oItem = " + DebugObject2Str(oItem) + "\n"
                        + "oTarget = " + DebugObject2Str(oTarget) + "\n"
                          );
        // Blood
        Bloodtalons(oMeldshaper, oItem, oTarget); 
        // Only applies to armours
        if(GetBaseItemType(oItem) == BASE_ITEM_ARMOR)
        {
            if (GetIsMeldBound(oMeldshaper, MELD_HEART_OF_FIRE) == CHAKRA_WAIST)    
                HeartOfFireOnHit(oMeldshaper, oTarget); 
            if (GetHasSpellEffect(MELD_MANTLE_OF_FLAME, oMeldshaper))
				MantleOfFlameOnHit(oMeldshaper, oTarget);
            if (GetIsMeldBound(oMeldshaper, MELD_PLANAR_WARD) == CHAKRA_THROAT)    
                PlanarWard(oMeldshaper, oTarget); 
        }
        // Melee weapon checks
        if(IPGetIsMeleeWeapon(oItem))
        {         
        	if (GetIsMeldBound(oMeldshaper, MELD_NECROCARNUM_WEAPON) == CHAKRA_HANDS) NecrocarnumWeaponHands(oMeldshaper, oTarget, oItem);
		}                          
    }// end if - Running OnHit event
    else if(nEvent == EVENT_ONPLAYEREQUIPITEM)
    {
        oMeldshaper   = GetItemLastEquippedBy();
        oItem = GetItemLastEquipped();
        if(DEBUG) DoDebug("moi_events - OnEquip\n"
                        + "oMeldshaper = " + DebugObject2Str(oMeldshaper) + "\n"
                        + "oItem = " + DebugObject2Str(oItem) + "\n"
                          );                  
        // Armor checks
        if(GetBaseItemType(oItem) == BASE_ITEM_ARMOR)
        {
            if (GetIsMeldBound(oMeldshaper, MELD_HEART_OF_FIRE) == CHAKRA_WAIST ||
                GetHasSpellEffect(MELD_MANTLE_OF_FLAME, oMeldshaper) ||
                GetIsMeldBound(oMeldshaper, MELD_PLANAR_WARD) == CHAKRA_THROAT )
            {       
                // Add eventhook to the armor
                IPSafeAddItemProperty(oItem, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
                AddEventScript(oItem, EVENT_ITEM_ONHIT, "moi_events", TRUE, FALSE);
            }           
        } 
        // Melee weapon checks
        if(IPGetIsMeleeWeapon(oItem))
        {        
        	int nBonus = IPGetWeaponEnhancementBonus(oItem);

            if (GetHasSpellEffect(MELD_INCARNATE_AVATAR, oMeldshaper))
        	{
        		int nEssentia = GetEssentiaInvested(oMeldshaper, MELD_INCARNATE_AVATAR);
        		if (GetAlignmentLawChaos(oMeldshaper) == ALIGNMENT_LAWFUL)
        			IPSafeAddItemProperty(oItem, ItemPropertyAttackBonus(nEssentia), 9999.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);
        		if (GetAlignmentGoodEvil(oMeldshaper) == ALIGNMENT_EVIL)
        			IPSafeAddItemProperty(oItem, ItemPropertyDamageBonus(DamageTypeToIPConst(GetWeaponDamageType(oItem)), IPDamageConstant((nEssentia*2) + nBonus)), 9999.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);        				
        	}
        	if (GetHasSpellEffect(MELD_NECROCARNUM_WEAPON, oMeldshaper))
        	{
       			IPSafeAddItemProperty(oItem, ItemPropertyAttackBonus(3), 9999.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);        	
       			IPSafeAddItemProperty(oItem, ItemPropertyAttackPenalty(3), 9999.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);        	
       			if (GetIsMeldBound(oMeldshaper, MELD_NECROCARNUM_WEAPON) == CHAKRA_HANDS)
       			{
                	// Add eventhook to the armor
                	IPSafeAddItemProperty(oItem, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
                	AddEventScript(oItem, EVENT_ITEM_ONHIT, "moi_events", TRUE, FALSE);       			
       			}
       		}	
    		if (GetIsMeldBound(oMeldshaper, MELD_MAULING_GAUNTLETS) == CHAKRA_ARMS)
				IPSafeAddItemProperty(oItem, ItemPropertyKeen(), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);        	
        }
        // Ranged weapon checks
        if(GetWeaponRanged(oItem))
        {        
        	if (GetHasSpellEffect(MELD_INCARNATE_AVATAR, oMeldshaper))
        	{
        		int nEssentia = GetEssentiaInvested(oMeldshaper, MELD_INCARNATE_AVATAR);
        		if (GetAlignmentLawChaos(oMeldshaper) == ALIGNMENT_CHAOTIC)
        			IPSafeAddItemProperty(oItem, ItemPropertyAttackBonus(nEssentia), 9999.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);      				
        	}
        	if (GetHasSpellEffect(MELD_SIGHTING_GLOVES, oMeldshaper))
        	{
        		int nDamageType = IP_CONST_DAMAGETYPE_PIERCING;
        		int nEssentia = GetEssentiaInvested(oMeldshaper, MELD_SIGHTING_GLOVES);
        		
                IPSafeAddItemProperty(oItem, ItemPropertyDamageBonus(nDamageType, IPDamageConstant(nEssentia+1)), 9999.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);     	
        	}        	
        }
        // Shields only
        if(GetIsShield(oItem))
        {
        	if (GetIsMeldBound(oMeldshaper, MELD_LANDSHARK_BOOTS) == CHAKRA_TOTEM)
        		ForceUnequip(oMeldshaper, oItem, INVENTORY_SLOT_LEFTHAND);
        }
        // Ammo checks
        if (GetBaseItemType(oItem) == BASE_ITEM_ARROW ||
            GetBaseItemType(oItem) == BASE_ITEM_BOLT ||
            GetBaseItemType(oItem) == BASE_ITEM_BULLET) 
        {
        	if (GetHasSpellEffect(MELD_SIGHTING_GLOVES, oMeldshaper))
        	{
        		int nDamageType = IP_CONST_DAMAGETYPE_PIERCING;
        		int nEssentia = GetEssentiaInvested(oMeldshaper, MELD_SIGHTING_GLOVES);
        		if (GetBaseItemType(oItem) == BASE_ITEM_BULLET) nDamageType = IP_CONST_DAMAGETYPE_BLUDGEONING;
        		
                IPSafeAddItemProperty(oItem, ItemPropertyDamageBonus(nDamageType, IPDamageConstant(nEssentia+1)), 9999.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE);     	
        	}
        }
    }
    // We are called from the OnPlayerUnEquipItem eventhook. Remove OnHitCast: Unique Power from oMeldshaper's weapon
    else if(nEvent == EVENT_ONPLAYERUNEQUIPITEM)
    {
        oMeldshaper   = GetItemLastUnequippedBy();
        oItem = GetItemLastUnequipped();
        if(DEBUG) DoDebug("moi_events - OnUnEquip\n"
                        + "oMeldshaper = " + DebugObject2Str(oMeldshaper) + "\n"
                        + "oItem = " + DebugObject2Str(oItem) + "\n"
                          );
                          
        if (GetTag(oItem) == "moi_incarnatewpn")  
        	ForceEquip(oMeldshaper, oItem, INVENTORY_SLOT_RIGHTHAND); // No unequipping this weapon
        // Only applies to armours
        if(GetBaseItemType(oItem) == BASE_ITEM_ARMOR)
        {
            // Remove the temporary OnHitCastSpell: Unique
            RemoveEventScript(oItem, EVENT_ITEM_ONHIT, "moi_events", TRUE, FALSE);       
            RemoveSpecificProperty(oItem, ITEM_PROPERTY_ONHITCASTSPELL, IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 0, 1, "", 1, DURATION_TYPE_TEMPORARY);
        } 
        // Melee weapon
        if(IPGetIsMeleeWeapon(oItem))
        {
            // Remove the attack bonus
            RemoveSpecificProperty(oItem, ITEM_PROPERTY_ATTACK_BONUS, -1, -1, 1, "", -1, DURATION_TYPE_TEMPORARY);
            RemoveSpecificProperty(oItem, ITEM_PROPERTY_DECREASED_ATTACK_MODIFIER, -1, -1, 1, "", -1, DURATION_TYPE_TEMPORARY);
            RemoveSpecificProperty(oItem, ITEM_PROPERTY_DAMAGE_BONUS, -1, -1, 1, "", -1, DURATION_TYPE_TEMPORARY);
            RemoveSpecificProperty(oItem, ITEM_PROPERTY_KEEN, -1, -1, 1, "", -1, DURATION_TYPE_TEMPORARY);
            // Remove the temporary OnHitCastSpell: Unique
            RemoveEventScript(oItem, EVENT_ITEM_ONHIT, "moi_events", TRUE, FALSE);       
            RemoveSpecificProperty(oItem, ITEM_PROPERTY_ONHITCASTSPELL, IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 0, 1, "", 1, DURATION_TYPE_TEMPORARY);            
        }  
        // Melee weapon
        if(GetWeaponRanged(oItem))
        {
            // Remove the attack bonus
            RemoveSpecificProperty(oItem, ITEM_PROPERTY_ATTACK_BONUS, -1, -1, 1, "", -1, DURATION_TYPE_TEMPORARY);
            RemoveSpecificProperty(oItem, ITEM_PROPERTY_DAMAGE_BONUS, -1, -1, 1, "", -1, DURATION_TYPE_TEMPORARY);
        } 
        // Ammo checks
        if (GetBaseItemType(oItem) == BASE_ITEM_ARROW ||
            GetBaseItemType(oItem) == BASE_ITEM_BOLT ||
            GetBaseItemType(oItem) == BASE_ITEM_BULLET) 
        {
			RemoveSpecificProperty(oItem, ITEM_PROPERTY_DAMAGE_BONUS, -1, -1, 1, "", -1, DURATION_TYPE_TEMPORARY);
        }        
    }
    else if(nEvent == EVENT_ONHEARTBEAT)
    {
		if (GetIsMeldShaped(oMeldshaper, MELD_DREAD_CARAPACE, CLASS_TYPE_TOTEMIST)) DreadCarapace(oMeldshaper);
		if (GetIsMeldBound(oMeldshaper, MELD_FEARSOME_MASK) == CHAKRA_BROW) FearsomeMask(oMeldshaper);
		//if (GetIsMeldBound(oMeldshaper, MELD_GIRALLON_ARMS) == CHAKRA_TOTEM) GirallonArms(oMeldshaper);
		if (GetHasSpellEffect(MELD_HEART_OF_FIRE, oMeldshaper)) HeartOfFire(oMeldshaper);
        /*if (GetHasSpellEffect(MELD_INCARNATE_AVATAR, oMeldshaper))
        {
        	int nEssentia = GetEssentiaInvested(oMeldshaper, MELD_INCARNATE_AVATAR);
        	if (GetAlignmentGoodEvil(oMeldshaper) == ALIGNMENT_GOOD)
        		ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectACIncrease(nEssentia), oMeldshaper, 6.0);     				
        }*/		
        // If you have the meld bound to the correct Chakra and there's nothing in your weapon hand
        if (GetIsMeldBound(oMeldshaper, MELD_KRUTHIK_CLAWS) == CHAKRA_HANDS && !GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oMeldshaper))) 
        	IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_FEAT_WEAPON_FINESSE), 6.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
        if (GetIsMeldBound(oMeldshaper, MELD_LAMMASU_MANTLE) == CHAKRA_SHOULDERS) LammasuRepulsion(oMeldshaper);	
        if (GetIsMeldBound(oMeldshaper, MELD_LAMMASU_MANTLE) == CHAKRA_ARMS) LammasuAllies(oMeldshaper);
        if (GetIsMeldBound(oMeldshaper, MELD_MAULING_GAUNTLETS) == CHAKRA_HANDS && !GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oMeldshaper)))
        	ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectDamageIncrease(IPGetDamageBonusConstantFromNumber(GetEssentiaInvested(oMeldshaper, MELD_MAULING_GAUNTLETS)*2), DAMAGE_TYPE_BASE_WEAPON), oMeldshaper, 6.0);
        if (GetIsMeldBound(oMeldshaper, MELD_PHASE_CLOAK) == CHAKRA_SHOULDERS) PhaseCloak(oMeldshaper);
        if (GetIsMeldBound(oMeldshaper, MELD_RAGECLAWS) == CHAKRA_HANDS) RageClaws(oMeldshaper);
        if (GetIsMeldBound(oMeldshaper, MELD_RIDING_BRACERS) == CHAKRA_ARMS || GetIsMeldBound(oMeldshaper, MELD_RIDING_BRACERS) == CHAKRA_TOTEM) RidingBracers(oMeldshaper);
        if (GetIsMeldBound(oMeldshaper, MELD_TOTEM_AVATAR) == CHAKRA_SHOULDERS || GetIsMeldBound(oMeldshaper, MELD_TOTEM_AVATAR) == CHAKRA_TOTEM) TotemAvatar(oMeldshaper);
        if (GetIsMeldBound(oMeldshaper, MELD_WORG_PELT) == CHAKRA_HANDS) WorgPeltHB(oMeldshaper);
        if (GetEssentiaInvestedFeat(oMeldshaper, FEAT_COBALT_EXPERTISE)) CobaltExpertise(oMeldshaper);
        //if (GetEssentiaInvestedFeat(oMeldshaper, FEAT_COBALT_POWER)) CobaltPower(oMeldshaper); Commented out so it doesn't work with Bioware PA any more.
        if (GetEssentiaInvestedFeat(oMeldshaper, FEAT_MIDNIGHT_DODGE)) MidnightDodge(oMeldshaper);
    	if (GetEssentiaInvested(oMeldshaper, MELD_INCANDESCENT_AURA)) IncandescentAura(oMeldshaper);
    	if (GetIsMeldBound(oMeldshaper, MELD_NECROCARNUM_VESTMENTS) == CHAKRA_WAIST) NecroVestmentsAura(oMeldshaper);
    	if (GetHasSpellEffect(MELD_NECROCARNUM_CIRCLET, oMeldshaper)) ActionCastSpellOnSelf(SPELL_DETECT_UNDEAD);
    	if (GetLevelByClass(CLASS_TYPE_NECROCARNATE, oMeldshaper)) // This tells the PRC whether to check for a necrocarnate on NPC death or not. Only allows 1 necrocarnate at a time
    	{
    		SetLocalObject(GetModule(), "Necrocarnate", oMeldshaper);
    		//DelayCommand(5.99, DeleteLocalObject(GetModule(), "Necrocarnate"));
    		/*int nEssentia = GetLocalInt(oMeldshaper, "EssentiaTrap");
    		if (nEssentia)
    		{
				SetTemporaryEssentia(oMeldshaper, nEssentia);
    			DelayCommand(6.0, SetTemporaryEssentia(oMeldshaper, nEssentia * -1));
    			FloatingTextStringOnCreature("Essentia trapped "+IntToString(nEssentia)+" temporary essentia for one round", oMeldshaper, FALSE);
    		}	*/
    		DeleteLocalInt(oMeldshaper, "EssentiaTrap");
    	}
    }   
    else if(nEvent == EVENT_ONPLAYERREST_FINISHED)    
    {
    	if (GetLevelByClass(CLASS_TYPE_INCANDESCENT_CHAMPION, oMeldshaper) || GetHasFeat(FEAT_INVEST_ESSENTIA_CONV, oMeldshaper)) ClearMeldShapes(oMeldshaper);
    	if (GetHasFeat(FEAT_HEART_INCARNUM, oMeldshaper)) ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectTemporaryHitpoints(GetTotalEssentia(oMeldshaper)), oMeldshaper, 9999.0);
    	if (GetHasFeat(FEAT_INCARNUM_FORTIFIED_BODY, oMeldshaper)) ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectTemporaryHitpoints(GetIncarnumFeats(oMeldshaper)*2), oMeldshaper, 9999.0);
    	while (GetHasFeat(FEAT_NECROCARNATE_HARVEST, oMeldshaper)) DecrementRemainingFeatUses(oMeldshaper, FEAT_NECROCARNATE_HARVEST);
    	if(GetHasFeat(FEAT_OPEN_HEART_CHAKRA, oMeldshaper)) ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectTemporaryHitpoints(GetHitDice(oMeldshaper)/2), oMeldshaper, 9999.0);
    	if(GetHasFeat(FEAT_OPEN_SOUL_CHAKRA, oMeldshaper)) ActionCastSpellOnSelf(MELD_OPEN_SOUL_CHAKRA);
    }     
}