Author Topic: Kill it with silver!  (Read 414 times)

Legacy_The Mad Poet

  • Hero Member
  • *****
  • Posts: 715
  • Karma: +0/-0
Kill it with silver!
« on: June 01, 2015, 12:10:14 am »


               

I've been working on a script to require my players to kill Werewolves with silver weapons. At first I was going to try and make it that werewolves had DR+3/10, and make silver weapons have Enh vs Shapechangers +3, that way it made it exceedingly difficult to kill them without it. Then one of my players made the suggestion of adapting those classic troll regeneration scripts... and I thought... ZOUNDS! What an idea!


 


So I've gone about doing just that. Hacking and beating the script editor until I came up with something that ALMOST works.


 


I'm stuck.



 


 


//Function called when WW is to be killed.

void KillWW( object oWW = OBJECT_SELF )

{

SetImmortal( oWW, FALSE );

ApplyEffectToObject( DURATION_TYPE_INSTANT, EffectDeath(), oWW );

}


//TMP - Makes silver weapon damage apply permenantly, other damage is temporary

int CalculateWWDamage()

{

int iSilverDamage, iDamage, iTemp, iSilver;

object oAttacker = GetLastAttacker();

object oWeapon = GetLastWeaponUsed(oAttacker);

itemproperty ipSilver = ItemPropertyMaterial(13);


if (IPGetItemHasProperty(oWeapon, ipSilver, -1, TRUE) == TRUE)

{iSilver == TRUE;}

else

{iSilver == FALSE;}


// Damage recieved from Silver Weapon

if (iSilver == TRUE) { iSilverDamage = GetTotalDamageDealt(); }


// Get the most recent damage (all types combined)

iDamage = GetTotalDamageDealt();


//Get the amount of Silver Damage and add it to 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 );

}

}

 


Those are the functions I've built and cobbled together out of two different troll scripts and my sanity.


 



 


 


void main()

{

int nUser = GetUserDefinedEventNumber();

int iSum, iPermDamage, iTempDamage, iMaxHPs = GetMaxHitPoints();

float fDuration;


if(nUser == EVENT_HEARTBEAT ) //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();

}

}

else if(nUser == EVENT_PERCEIVE) // PERCEIVE

{


}

else if(nUser == EVENT_END_COMBAT_ROUND) // END OF COMBAT

{


}

else if(nUser == EVENT_DIALOGUE) // ON DIALOGUE

{


}

else if(nUser == EVENT_ATTACKED) // ATTACKED

{


}

else if(nUser == EVENT_DAMAGED) // 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 ));

}

}

}

else if(nUser == 1007) // DEATH - do not use for critical code, does not fire reliably all the time

{


}

else if(nUser == EVENT_DISTURBED) // DISTURBED

{


}

else if (nUser == EVENT_USER_DEFINED_PRESPAWN)

{

SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT);

}

}

And that is my UD script.


 


This is what happens. Player can run up and start beating the werewolf senseless and it happily falls over unconscious waiting to heal up. However when struck with a silver weapon it acts like nothing happened.


 


I'm not sure if I'm calculating Temp and Permenant damage wrong.


 


It could also be that I am getting the itemproperty for Material (silver) incorrectly.


 


I dunno chaps.


 


Anyone care to give me a happy hand?



               
               

               
            

Legacy_MrZork

  • Hero Member
  • *****
  • Posts: 1643
  • Karma: +0/-0
Kill it with silver!
« Reply #1 on: June 02, 2015, 05:22:36 am »


               

First, make sure that the part of the code that tests whether the weapon is silver is working. If I were doing it, I would do that test with something like the following (not tested)



int bIsSilver(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;
    }

Essentially, you want to test both that the item has the item property for material and test that its material is silver, which should be the cost table value.


 


Second, double check that the silver weapons will eventually kill the target creature when enough damage is done, even if the target's on-screen damage indicator is showing "Uninjured". I mention this because: I didn't test your script, but if it is based on some of the "real troll" scripts, that is a common issue. That is, the script does the right thing and kills the creature when it has taken enough of the "right" type of damage, but it doesn't show that damage in the creature's damage indicator. Because of that, it's easy to assume that the creature is taking no damage from the weapons that are supposed to be able to hurt him. Obviously, a PC in that situation might give up, but if enough damage is done, the creature will die. (To me, that is a significant flaw in the system, but I think it is popular anyway.)



               
               

               
            

Legacy_The Mad Poet

  • Hero Member
  • *****
  • Posts: 715
  • Karma: +0/-0
Kill it with silver!
« Reply #2 on: June 03, 2015, 02:44:00 pm »


               

Alright, I'm going to try your suggestions and see what I can cobble together. Thank you, and I'll let you know the results when I'm done.



               
               

               
            

Legacy_The Mad Poet

  • Hero Member
  • *****
  • Posts: 715
  • Karma: +0/-0
Kill it with silver!
« Reply #3 on: June 30, 2015, 06:28:45 pm »


               

Alright, I've managed to get this script working almost perfectly except for one problem.


 


How can I get data from recently fired ammunition?


 


I have a gun, and I have bullets. The bullets themselves are silver, and not the gun. As of right now I can kill it with silver if I have a silver gun, but not a silver bullet. I've looked and I can't seem to find a function to pull data off the item property of ammunition that was recently fired.



               
               

               
            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
Kill it with silver!
« Reply #4 on: June 30, 2015, 06:57:41 pm »


               

Surely you should be able to get the attacker, then get the item in the ammunition slot?


This however raises the question of :


Does the item in that slot get consumed before the onDamaged event fires.


If so - it means that the last bullet/bolt could end up being OBJECT_INVALID when the event runs.



               
               

               
            

Legacy_The Mad Poet

  • Hero Member
  • *****
  • Posts: 715
  • Karma: +0/-0
Kill it with silver!
« Reply #5 on: June 30, 2015, 07:03:01 pm »


               

Ah... good idea. 


 


I'll have to try. If that error does come up do you know anyway to just suppress it? I mean they're going to realize the next shot they are out of ammo anyway...



               
               

               
            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Kill it with silver!
« Reply #6 on: June 30, 2015, 10:40:38 pm »


               

If so - it means that the last bullet/bolt could end up being OBJECT_INVALID when the event runs.



 


This is the case.  No real solution for it other than having the last shot not be considered silver.


               
               

               
            

Legacy_meaglyn

  • Hero Member
  • *****
  • Posts: 1451
  • Karma: +0/-0
Kill it with silver!
« Reply #7 on: July 01, 2015, 01:31:14 am »


               

Well, you could set a variable like last_ammo_tag or something onequip of ammo. Then keep a special chest with a single item of any special ammo types. You can then get that and check the properties. That sort of assumes you know up front what the ammos are and don't let people make new ones.


 


An alternative would be to set a variable like last_ammo_silver to TRUE onequip if the ammo equipped is silver. Just be sure to clear it anytime any other ammo is equipped.  You could use your property detection code in the onequipped check.


 


There are probably other ways to work around it...



               
               

               
            

Legacy_The Mad Poet

  • Hero Member
  • *****
  • Posts: 715
  • Karma: +0/-0
Kill it with silver!
« Reply #8 on: July 01, 2015, 06:46:24 am »


               

 


Well, you could set a variable like last_ammo_tag or something onequip of ammo. Then keep a special chest with a single item of any special ammo types. You can then get that and check the properties. That sort of assumes you know up front what the ammos are and don't let people make new ones.


 


An alternative would be to set a variable like last_ammo_silver to TRUE onequip if the ammo equipped is silver. Just be sure to clear it anytime any other ammo is equipped.  You could use your property detection code in the onequipped check.


 


There are probably other ways to work around it...



 


A good suggestion, and if I can't accomplish this in one script I'll give it a shot.


 


So far this is what I've done with the suggestions provided... just a snippet, as the rest of the code seems fine because melee weapons work perfect. I've tried three different ways now, and I've tried having messages sent to me when silver weapons cause damage, doesn't work for ranged seemingly.



//TMP - Makes silver weapon damage apply permenantly, other damage is temporary
int CalculateWWDamage()
{
    int iSilverDamage, iDamage, iTemp, iSilver;
    object oAttacker = GetLastAttacker();
    object oWeapon = GetLastWeaponUsed(oAttacker);
    int iWeaponType = GetBaseItemType(oWeapon);
    object oBolts = GetItemInSlot(INVENTORY_SLOT_BOLTS, oAttacker);
    object oArrows = GetItemInSlot(INVENTORY_SLOT_ARROWS, oAttacker);
    object oBullets = GetItemInSlot(INVENTORY_SLOT_BULLETS, oAttacker);
    int nSilver = IsSilver(oWeapon);
    int nSilverBolt = IsSilver(oBolts);
    int nSilverArrow = IsSilver(oArrows);
    int nSilverBullet = IsSilver(oBullets);
    int nMelee = GetMeleeWeapon(oWeapon);

    //No matter what, if the weapon itself is silver, it will cause damage.
    if(nSilver == TRUE )
        {
          iSilver == TRUE;
        }

    /*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.*/

    //TMP - Not currently working, @%#&
    if(nMelee == FALSE) //Checks equipped weapon whether to see if not melee
        {
          if ( iWeaponType == BASE_ITEM_HEAVYCROSSBOW || iWeaponType == BASE_ITEM_LIGHTCROSSBOW )
            {
                if (nSilverBolt == TRUE)
                    {iSilver == TRUE;}
            }
          if ( iWeaponType == BASE_ITEM_LONGBOW || iWeaponType == BASE_ITEM_SHORTBOW )
            {
                if (nSilverArrow == TRUE)
                    {iSilver == TRUE;}
            }
          if ( iWeaponType == BASE_ITEM_SLING )
            {
                if (nSilverBullet == TRUE)
                    {iSilver == TRUE;}
            }
         }


               
               

               
            

Legacy_meaglyn

  • Hero Member
  • *****
  • Posts: 1451
  • Karma: +0/-0
Kill it with silver!
« Reply #9 on: July 01, 2015, 02:00:34 pm »


               

I'm not sure that the rest of the script is working completely correctly. You are not assiging TRUE to iSilver you are doing a comparison equals. Remove the extra "=" sign in all of those cases.  Since you are also doing that for the initial case, when nSilver is set I question that the rest of the script is actually doing what you think it is. 


 


As an aside, you might want to refactor the code so that it does not do work it does not need to. For example:



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);
      }

This is the same code except that I don't call GetItemInSlot until we know it's needed and only call isSilver once for the ammo and only if we need to. At the end of the snippet iSilver is either set or not just as before (well ... as before with the comparisons changed to assigments '<img'>)



               
               

               
            

Legacy_The Mad Poet

  • Hero Member
  • *****
  • Posts: 715
  • Karma: +0/-0
Kill it with silver!
« Reply #10 on: July 01, 2015, 07:04:53 pm »


               

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. 



               
               

               
            

Legacy_meaglyn

  • Hero Member
  • *****
  • Posts: 1451
  • Karma: +0/-0
Kill it with silver!
« Reply #11 on: July 01, 2015, 07:42:56 pm »


               

Based on what you had before I'm not sure how it was working with melee weapons as you were never setting iSilver to TRUE. But that said, you may want to add some sendmessages to print what you got for oAmmo for example. Check that the baseitem type is what you think and that it's going through the code paths you expect.  You might also add a check at the top of isSilver to return FALSE if oItem is not valid.  You'll get there anyway but it's cleaner.   



               
               

               
            

Legacy_meaglyn

  • Hero Member
  • *****
  • Posts: 1451
  • Karma: +0/-0
Kill it with silver!
« Reply #12 on: July 03, 2015, 01:59:00 am »


               

Did I misread your post? It looks like  you are saying it still didn't work for you. This script works just fine for me. Both for ranged and melee. If it's really not working for you with ranged make sure you are actually getting the silver property on the ammo.



               
               

               
            

Legacy_The Mad Poet

  • Hero Member
  • *****
  • Posts: 715
  • Karma: +0/-0
Kill it with silver!
« Reply #13 on: July 14, 2015, 05:17:51 pm »


               

After a bit more testing I've managed to get it working. I appreciate everyones help!