forked from Jaysyn/PRC8
Added Vow of Poverty, Jaebrin, Hobgoblin Warsoul & Forsaker fixes (thanks PRC5 & @Fencas). Added iprp_matcost.2da for new materials. Updated PRC8 Tester module. Cohorts updated to support 8 classes. Fixed ranged disarm w/ Fighter. Updated release archive.
740 lines
38 KiB
Plaintext
740 lines
38 KiB
Plaintext
//::///////////////////////////////////////////////
|
|
//:: 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 JaebrinHB(object oMeldshaper)
|
|
{
|
|
object oBite = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oMeldshaper);
|
|
|
|
if (GetIsObjectValid(oBite))
|
|
{
|
|
// Add eventhook to the bite
|
|
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 JaebrinOnHit(object oMeldshaper, object oItem, object oTarget)
|
|
{
|
|
if (GetRacialType(oMeldshaper) != RACIAL_TYPE_JAEBRIN) return;
|
|
|
|
if(oItem == GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oMeldshaper))
|
|
{
|
|
int nDC = 10 + GetHitDice(oMeldshaper)/2 + GetAbilityModifier(ABILITY_CONSTITUTION);
|
|
if(!PRCMySavingThrow(SAVING_THROW_WILL, oTarget, nDC))
|
|
{
|
|
effect eEssence = EffectSavingThrowDecrease(SAVING_THROW_WILL, 4);
|
|
eEssence = EffectLinkEffects(eEssence, EffectVisualEffect(VFX_DUR_MIND_AFFECTING_NEGATIVE));
|
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEssence, oTarget, RoundsToSeconds(10));
|
|
}
|
|
}// 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);
|
|
}
|
|
WorgPeltOnHit(oMeldshaper, oItem, oTarget);
|
|
JaebrinOnHit(oMeldshaper, oItem, oTarget);
|
|
}// 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 (GetRacialType(oMeldshaper) == RACIAL_TYPE_JAEBRIN) JaebrinHB(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);
|
|
}
|
|
} |