Neverwinter Nights 2

File information

Last updated

Original upload

Created by

Dann Pigdon

Uploaded by

DannJ

Virus scan

Safe to use

About this mod

Modified nw_c2_default6 script to allow recovery of arrows, bolts, throwing axes, darts or shuriken from corpses

Permissions and credits
The script below is a modified version of the default OnHit creature script in the game (nw_c2_default6). It has a 1 in 3 chance of making a missile (arrow, bolt, dart, shuriken, throwing axe) recoverable from a creature's corpse when it dies.

Currently sling bullets are disabled, since they're more likely to bounce off than get lodged in a creature. Those lines can be uncommented if required (see the switch in the CatchAmmo function).

**Script starts below**

//::///////////////////////////////////////////////
//:: Default On Damaged
//:: NW_C2_DEFAULT6
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
If already fighting then ignore, else determine
combat round
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 16, 2001
//:: Added CatchAmmo function Oct 2012 - DannJ
//:://////////////////////////////////////////////

#include "hench_i0_ai"
#include "ginc_behavior"

void CatchAmmo(object oSelf);
int NoPhysicalDamage();

void main()
{
int iFocused = GetIsFocused();

// Ive been damaged so no longer partially focused
if (iFocused == FOCUSED_PARTIAL)
{
SetLocalInt(OBJECT_SELF, VAR_FOCUSED, FOCUSED_STANDARD); // no longer focused
}
if (iFocused == FOCUSED_FULL)
{
// remain focused
}
else if(GetFleeToExit())
{
// Were supposed to run away, do nothing
}
else if (GetSpawnInCondition(NW_FLAG_SET_WARNINGS))
{
// dont do anything?
}
else
{
object oDamager = GetLastDamager();
if (!GetIsObjectValid(oDamager))
{
// dont do anything, we dont have a valid damager
}
else if (!GetIsFighting(OBJECT_SELF))
{
if ((GetLocalInt(OBJECT_SELF, HENCH_HEAL_SELF_STATE) == HENCH_HEAL_SELF_WAIT) &&
(GetPercentageHPLoss(OBJECT_SELF) 30))
{
// force heal
HenchDetermineCombatRound(OBJECT_INVALID, TRUE);
}
else if (!GetIsObjectValid(GetAttemptedAttackTarget()) && !GetIsObjectValid(GetAttemptedSpellTarget()))
{
// Jug_Debug(GetName(OBJECT_SELF) + " responding to damage");
if (GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL))
{
HenchDetermineSpecialBehavior(oDamager);
}
else
{
HenchDetermineCombatRound(oDamager);
}
}
}
}
if(GetSpawnInCondition(NW_FLAG_DAMAGED_EVENT))
{
SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_DAMAGED));
}

CatchAmmo(OBJECT_SELF);
}

// 1 in 3 chance of ammo or thrown weapon
// recoverable from corpse
void CatchAmmo(object oSelf)
{
int iRnd = d3(1);
if (iRnd > 1) iRnd = 0;

object oAttacker = GetLastDamager(oSelf);
object oWeapon = GetLastWeaponUsed(oAttacker);

if (!GetIsObjectValid(oWeapon)
|| !GetWeaponRanged(oWeapon)
|| NoPhysicalDamage()
|| GetTag(oWeapon) == "returning" ) iRnd = 0;

// check for unlimited ammunition property
int iUnlimit = GetItemHasItemProperty(oWeapon, ITEM_PROPERTY_UNLIMITED_AMMUNITION);
if (iUnlimit == 1) iRnd = 0;

int iType = GetBaseItemType(oWeapon);
int iSlot = 0;
switch (iType)
{
case 6:// crossbow
iSlot = 13;
break;
case 7:// crossbow
iSlot = 13;
break;
case 8:// bow
iSlot = 11;
break;
case 11:// bow
iSlot = 11;
break;
case 31:// dart
iSlot = 4;
break;
case 59:// shuriken
iSlot = 4;
break;
//case 61:// sling
//iSlot = 12;
//break;
case 63:// axe
iSlot = 4;
break;
}//end switch

iSlot = iSlot * iRnd;
if (iSlot > 0)
{
object oItem = GetItemInSlot(iSlot, oAttacker);
string sResRef = GetResRef(oItem);
CreateItemOnObject(sResRef, oSelf, 1);
}
}

// Tests whether any physical damage occured
// If not, most likely from a spell
// Will fail for: Evards tentacles, blade barrier,
// earthquake, Bigbys crushing hand
int NoPhysicalDamage()
{
int iTest = 0;
int iCount = 3;
int iMagic = 0;
float fDmgType;
int iDmg;
while (iCount 12)//add up non-physical damage
{
fDmgType = pow(2.0, IntToFloat(iCount));
iDmg = GetDamageDealtByType(FloatToInt(fDmgType));
if (iDmg 0) iDmg = 0;
iMagic = iMagic + iDmg;
iCount ++;
}//end while

int iPhysical = GetTotalDamageDealt() - iMagic;
if (iPhysical == 0)//no physical damage done
iTest = 1;
return iTest;
}