Silly mistake on my part. Should have seen that. That's why its good to have a few extra eyes on these things. I'm going to chalk it up to midnight coding.....(Good excuse there, Poet).
Well anyway I checked through the script for similar mistakes and I didn't spot any. And like I wrote in my comments I knew there was a more elegant way to do this, and thank you for showing me elegance.
I tested it with the changes you made... same result. This time instead of vaunting my laurels like a fool I'm just going to paste the whole ude script.
////////////////////////////////////////////////////////////////////////////////
//TMP - tmp_ww_ude, user-defined script for werewolves //
////////////////////////////////////////////////////////////////////////////////
#include "x2_i0_spells"
// This function is called from the on damaged (1006) UDE when permanent damage
// equals or exceeds the WWs maximum hitpoints.
void KillWW( object oWW = OBJECT_SELF )
{
SetImmortal( oWW, FALSE );
ApplyEffectToObject( DURATION_TYPE_INSTANT, EffectDeath(), oWW );
}
int IsSilver(object oItem)
{
int iCostVal = 0;
int bFound = FALSE;
itemproperty ipTest = GetFirstItemProperty(oItem);
while ( (GetIsItemPropertyValid(ipTest)) && (!bFound) )
{
if (GetItemPropertyType(ipTest)==ITEM_PROPERTY_MATERIAL)
{
bFound = TRUE; // shouldn't have more than 1 material property
iCostVal = GetItemPropertyCostTableValue(ipTest);
// check for silver, alchemical silver, or silver dragon hide (== claw or tooth)
if ( (iCostVal == 13) || (iCostVal == 14) || (iCostVal == 29) )
{
return TRUE;
}
}
ipTest = GetNextItemProperty(oItem);
}
return FALSE;
}
int CalculateWWDamage()
{
int iSilverDamage, iDamage, iTemp, iSilver;
object oAttacker = GetLastAttacker();
object oWeapon = GetLastWeaponUsed(oAttacker);
//No matter what, if the weapon itself is silver, it will cause damage.
if(IsSilver(oWeapon)) {
iSilver = TRUE;
} else if (!GetMeleeWeapon(oWeapon)) {
/*For ranged weapons. Checks to ensure whatever ranged weapon type is equipped the
corresponding equipped ammunition is checked to see if it is silver. Don't want silver bullets
being able to be true for arrows after all. Probably a more elegent way to handle this,
but for now I just want it to work.*/
//Checks equipped weapon whether to see if not melee
object oAmmo;
int iWeaponType = GetBaseItemType(oWeapon);
if ( iWeaponType == BASE_ITEM_HEAVYCROSSBOW || iWeaponType == BASE_ITEM_LIGHTCROSSBOW ) {
oAmmo = GetItemInSlot(INVENTORY_SLOT_BOLTS, oAttacker);
} else if (iWeaponType == BASE_ITEM_LONGBOW || iWeaponType == BASE_ITEM_SHORTBOW ) {
oAmmo = GetItemInSlot(INVENTORY_SLOT_ARROWS, oAttacker);
} else if ( iWeaponType == BASE_ITEM_SLING ) {
oAmmo = GetItemInSlot(INVENTORY_SLOT_BULLETS, oAttacker);
}
iSilver = IsSilver(oAmmo);
}
// Damage recieved from Silver Weapon
if (iSilver == TRUE) {
iSilverDamage = GetTotalDamageDealt();
if( iSilverDamage > 0 )
SetLocalInt( OBJECT_SELF, "bSilver", TRUE );
else
{
iSilverDamage = 0;
SetLocalInt( OBJECT_SELF, "bSilver", FALSE );
}
}
// Get the most recent damage (all types combined)
iDamage = GetTotalDamageDealt();
// Calculate the new permanent damage from silver and then add it to
// the existing permenant damage.
iTemp = iSilverDamage;
// If the WW took permanent damage while unconscious it will be killed.
if( iTemp > 0 && GetLocalInt( OBJECT_SELF, "WW_unconscious" ))
KillWW();
SetLocalInt( OBJECT_SELF, "WW_PermDamage", GetLocalInt( OBJECT_SELF, "WW_PermDamage" ) + iTemp );
// Calculate the new temporary damage and then add it to the existing temporary
// damage.
// iTemp still holds the new permanent damage
iTemp = iDamage - iTemp;
SetLocalInt( OBJECT_SELF, "WW_TempDamage", GetLocalInt( OBJECT_SELF, "WW_TempDamage" ) + iTemp );
return iDamage;
}
// Regenerate temporary damage
void HealWW()
{
int iHeal, iPermDamage, iTempDamage, iMaxHPs = GetMaxHitPoints();
effect eHeal;
iTempDamage = GetLocalInt ( OBJECT_SELF, "WW_TempDamage" );
iPermDamage = GetLocalInt ( OBJECT_SELF, "WW_PermDamage" );
// Reduce temporary damage by the lesser of five hitpoints or the WW's
// temporary damage.
iHeal = ( iTempDamage < 5 ) ? iTempDamage : 5;
iTempDamage -= iHeal;
SetLocalInt( OBJECT_SELF, "WW_TempDamage", iTempDamage );
// Only heal if the regeneration places the WW into positive hitpoints.
if(( iTempDamage + iPermDamage ) < iMaxHPs )
{
eHeal = EffectHeal( iHeal );
ApplyEffectToObject( DURATION_TYPE_INSTANT , eHeal, OBJECT_SELF );
}
}
void main()
{
int iSum, iPermDamage, iTempDamage, iMaxHPs = GetMaxHitPoints();
float fDuration;
switch ( GetUserDefinedEventNumber () )
{
case EVENT_HEARTBEAT:
iTempDamage = GetLocalInt ( OBJECT_SELF, "WW_TempDamage" );
// Use iPermDamage as a temporary variable that holds the sum of
// temporary and permanent damage
iSum = iTempDamage + GetLocalInt( OBJECT_SELF, "WW_PermDamage" );
if( iSum == 0 )
return;
if( iSum < iMaxHPs && GetLocalInt( OBJECT_SELF, "WW_unconscious" ))
{
// Return the WW to consciousness as it has regenerated to
// positive hitpoints.
SetCommandable( TRUE, OBJECT_SELF );
// Force the WW up off the ground as DetermineCombatRound()
// won't unless it has an attack target.
ActionForceMoveToLocation( GetLocation( OBJECT_SELF ));
SetLocalInt( OBJECT_SELF, "WW_unconscious", FALSE );
DelayCommand( 0.5, DetermineCombatRound() );
}
if( iTempDamage > 0 )
{
HealWW();
}
break;
case EVENT_DAMAGED:
// Sort new damage into permanent and temporary damage.
if( CalculateWWDamage() )
{
iTempDamage = GetLocalInt ( OBJECT_SELF, "WW_TempDamage" );
iPermDamage = GetLocalInt( OBJECT_SELF, "WW_PermDamage" );
iSum = iTempDamage + iPermDamage;
if( iPermDamage >= iMaxHPs )
{
// Permanent damage has reached or exceeded the WW's maximum
// hitpoints so kill the WW.
KillWW();
}
else if( iSum >= iMaxHPs )
{
// Force the WW to lie down unconcious until it regenerates to
// positive hitpoints.
// Play the dead animation for the time it will take to regenerate from the
// current hitpoints to positive hitpoints.
// At 5 hitpoints/round with a 6 second round this is 1.2 seconds per HP.
fDuration = ( 2.0 * IntToFloat( iSum - iMaxHPs ));
SetCommandable( TRUE, OBJECT_SELF );
ClearAllActions();
PlayAnimation( ANIMATION_LOOPING_DEAD_FRONT, 1.0, fDuration );
SetLocalInt( OBJECT_SELF, "WW_unconscious", TRUE );
DelayCommand( 0.05, SetCommandable( FALSE, OBJECT_SELF ));
}
}
break;
}
}
Also thank you everyone for taking time to look this over and give me a hand.