Further file organization
Further file organization
This commit is contained in:
177
nwn/nwnprc/trunk/scripts/prc_tw_rend.nss
Normal file
177
nwn/nwnprc/trunk/scripts/prc_tw_rend.nss
Normal file
@@ -0,0 +1,177 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Two-Weapon Rend
|
||||
//:: prc_tw_rend
|
||||
//:://////////////////////////////////////////////
|
||||
/** @file
|
||||
TWO-WEAPON REND [EPIC]
|
||||
Prerequisites: Dex 15, base attack bonus +9,
|
||||
Improved Two-Weapon Fighting, Two-Weapon Fighting.
|
||||
|
||||
Benefit: If the character hits an opponent with a
|
||||
weapon in each hand in the same round, he or she
|
||||
may automatically rend the opponent. This deals
|
||||
additional damage equal to the base damage of the
|
||||
smaller weapon (if both weapons are of same size,
|
||||
the weapon in main hand is used) plus 1 1/2 times
|
||||
the character<65>s Strength modifier. Base weapon
|
||||
damage includes an enhancement bonus on damage,
|
||||
if any.
|
||||
The character can only rend once per round,
|
||||
regardless of how many successful attacks he or
|
||||
she makes.
|
||||
|
||||
@author Ornedan
|
||||
@date Created - 2006.07.05
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "prc_alterations"
|
||||
|
||||
const string REND_FIRST_MAINHAND_HIT_PREFIX = "PRC_TWRend_MainHandHitBy_";
|
||||
const string REND_FIRST_OFFHAND_HIT_PREFIX = "PRC_TWRend_OffHandHitBy_";
|
||||
const string REND_LOCK = "PRC_TWRend_Used";
|
||||
|
||||
void main()
|
||||
{
|
||||
object oPC, oItem;
|
||||
int nEvent = GetRunningEvent();
|
||||
|
||||
if(DEBUG) DoDebug("prc_tw_rend running, event: " + IntToString(nEvent));
|
||||
|
||||
// We're being called from the OnHit eventhook, so deal the damage
|
||||
if(nEvent == EVENT_ITEM_ONHIT)
|
||||
{
|
||||
oPC = OBJECT_SELF;
|
||||
oItem = GetSpellCastItem();
|
||||
object oTarget = PRCGetSpellTargetObject();
|
||||
if(DEBUG) DoDebug("prc_tw_rend: OnHit:\n"
|
||||
+ "oPC = " + DebugObject2Str(oPC) + "\n"
|
||||
+ "oItem = " + DebugObject2Str(oItem) + "\n"
|
||||
+ "oTarget = " + DebugObject2Str(oTarget) + "\n"
|
||||
);
|
||||
|
||||
// Only run if called by a melee weapon and rend hasn't already been used for this round
|
||||
if(IPGetIsMeleeWeapon(oItem) && !GetLocalInt(oPC, REND_LOCK))
|
||||
{
|
||||
string sPCOID = ObjectToString(oPC);
|
||||
|
||||
// Determine if the weapon is the mainhand one or the offhand one
|
||||
int bIsMainHand = oItem == GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
||||
|
||||
// Determine if the other hand has hit
|
||||
int bBothHandsHit;
|
||||
if(bIsMainHand)
|
||||
bBothHandsHit = GetLocalInt(oTarget, REND_FIRST_OFFHAND_HIT_PREFIX + sPCOID);
|
||||
else
|
||||
bBothHandsHit = GetLocalInt(oTarget, REND_FIRST_MAINHAND_HIT_PREFIX + sPCOID);
|
||||
|
||||
if(DEBUG) DoDebug("prc_tw_rend: OnHit: bBothHandsHit = " + DebugBool2String(bBothHandsHit));
|
||||
|
||||
// If both hands did hit, run the rending code
|
||||
if(bBothHandsHit)
|
||||
{
|
||||
// Get the equipped weapons
|
||||
object oRightHand = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
||||
object oLeftHand = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC);
|
||||
|
||||
// Make sure both are valid before continuing. If the PC is changing their loadout mid-battle,
|
||||
// they are not going to be able to rend things at the same time.
|
||||
if(!GetIsObjectValid(oRightHand) || !GetIsObjectValid(oLeftHand))
|
||||
{
|
||||
if(DEBUG) DoDebug("prc_tw_rend: OnHit: One of the weapons was not present:\n"
|
||||
+ "oRightHand = " + DebugObject2Str(oRightHand) + "\n"
|
||||
+ "oLeftHand = " + DebugObject2Str(oLeftHand) + "\n"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine which is smaller, preferring the right hand in case of equal size
|
||||
int nRightSize = StringToInt(Get2DACache("baseitems", "WeaponSize", GetBaseItemType(oRightHand)));
|
||||
int nLeftSize = StringToInt(Get2DACache("baseitems", "WeaponSize", GetBaseItemType(oLeftHand)));
|
||||
object oSmaller = nRightSize >= nLeftSize ? oRightHand : oLeftHand;
|
||||
int nSmaller = GetBaseItemType(oSmaller);
|
||||
|
||||
// Determine dice to roll
|
||||
int nDieSize = StringToInt(Get2DACache("baseitems", "DieToRoll", nSmaller));
|
||||
int nNumDice = StringToInt(Get2DACache("baseitems", "NumDice", nSmaller));
|
||||
|
||||
// Determine damage bonus from enhancement
|
||||
int nBonus = 0;
|
||||
itemproperty ipTest = GetFirstItemProperty(oSmaller);
|
||||
while(GetIsItemPropertyValid(ipTest))
|
||||
{
|
||||
// Get the highest enhancement bonus property on the item
|
||||
if(GetItemPropertyType(ipTest) == ITEM_PROPERTY_ENHANCEMENT_BONUS)
|
||||
nBonus = max(nBonus, GetItemPropertyCostTableValue(ipTest));
|
||||
|
||||
ipTest = GetNextItemProperty(oSmaller);
|
||||
}
|
||||
|
||||
// Add STR modifier to damage bonus
|
||||
nBonus += FloatToInt(1.5f * GetAbilityModifier(ABILITY_STRENGTH, oPC));
|
||||
|
||||
// Start with bonus and add damage rolls
|
||||
int nDamage = nBonus;
|
||||
for(; nNumDice > 0; nNumDice--)
|
||||
nDamage += Random(nDieSize) + 1;
|
||||
|
||||
// Apply effects. Damage type is slashing, since it seems most appropriate
|
||||
effect eLink = EffectDamage(nDamage, DAMAGE_TYPE_SLASHING);
|
||||
eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_COM_BLOOD_CRT_RED));
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink, oTarget);
|
||||
|
||||
// Do some feedback
|
||||
// * PCName rends TargetName *
|
||||
FloatingTextStringOnCreature("* " + GetName(oPC) + " " + GetStringByStrRef(0x01000000 + 51197) + " " + GetName(oTarget) + " *",
|
||||
oPC,
|
||||
TRUE);
|
||||
|
||||
// Set the feat used for this round, queue lock variable deletion
|
||||
SetLocalInt(oPC, REND_LOCK, TRUE);
|
||||
DelayCommand(6.0f, DeleteLocalInt(oPC, REND_LOCK));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just a single hit in so far, set marker local and queue it's deletion
|
||||
string sVar = (bIsMainHand ? REND_FIRST_MAINHAND_HIT_PREFIX : REND_FIRST_OFFHAND_HIT_PREFIX) + sPCOID;
|
||||
SetLocalInt(oTarget, sVar, TRUE);
|
||||
DelayCommand(6.0f, DeleteLocalInt(oTarget, sVar));
|
||||
}
|
||||
}// end if - Item is a melee weapon and Two-Weapon Rend hasn't already been used up for the round
|
||||
}// end if - Running OnHit event
|
||||
// We are called from the OnPlayerEquipItem eventhook. Add OnHitCast: Unique Power to oPC's weapon
|
||||
else if(nEvent == EVENT_ONPLAYEREQUIPITEM)
|
||||
{
|
||||
oPC = GetItemLastEquippedBy();
|
||||
oItem = GetItemLastEquipped();
|
||||
if(DEBUG) DoDebug("prc_tw_rend - OnEquip");
|
||||
|
||||
// Only applies to melee weapons
|
||||
if(IPGetIsMeleeWeapon(oItem))
|
||||
{
|
||||
// Add eventhook to the item
|
||||
AddEventScript(oItem, EVENT_ITEM_ONHIT, "prc_tw_rend", TRUE, FALSE);
|
||||
|
||||
// Add the OnHitCastSpell: Unique needed to trigger the event
|
||||
IPSafeAddItemProperty(oItem, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 99999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
}
|
||||
}
|
||||
// We are called from the OnPlayerUnEquipItem eventhook. Remove OnHitCast: Unique Power from oPC's weapon
|
||||
else if(nEvent == EVENT_ONPLAYERUNEQUIPITEM)
|
||||
{
|
||||
oPC = GetItemLastUnequippedBy();
|
||||
oItem = GetItemLastUnequipped();
|
||||
if(DEBUG) DoDebug("prc_tw_rend - OnUnEquip");
|
||||
|
||||
// Only applies to melee weapons
|
||||
if(IPGetIsMeleeWeapon(oItem))
|
||||
{
|
||||
// Add eventhook to the item
|
||||
RemoveEventScript(oItem, EVENT_ITEM_ONHIT, "prc_tw_rend", TRUE, FALSE);
|
||||
|
||||
// Remove the temporary OnHitCastSpell: Unique
|
||||
RemoveSpecificProperty(oItem, ITEM_PROPERTY_ONHITCASTSPELL, IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 0, 1, "", 1, DURATION_TYPE_TEMPORARY);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user