Making a placeable resistant to certain types of damages

So I want to make a tree placeable invulnerable to bludgeoning or piercing damage. In fact, it would only be able to be hurt by slashing damage (it’s a tree you chop for wood). How do I go ahead about it?

Something along the lines of
If (DAMAGE_TYPE_SLASHING==FALSE) then turn invulnerability on…otherwise invulnerability is off

I can’t find the right functions… can anyone help?

-Val

  1. Make placeable usable but plot, so it can be attacked
  2. In OnDamaged handler get last weapon with GetLastWeaponUsed(GetLastAttacker())
  3. Check base type of the weapon to see if it deals slashing damage
  4. If it does, drop plot flag, do an EffectDamage, re-apply plot flag

EDIT: it might be actually better to check the weapon / drop plot flag in OnPhysicallyAttacked, then re-apply plot flag in OnDamage. This should avoid the “you can’t damage blah blah” message being shown to confuse the player.

2 Likes

NWShacker’s method will work. You could also apply the following effect to the tree placeable:

    effect eDR=EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_PIERCING, 100),EffectDamageImmunityIncrease(DAMAGE_TYPE_BLUDGEONING, 100));
    eDR=EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_ACID, 100), eDR);
    eDR=EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_COLD, 100), eDR);
    eDR=EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_DIVINE, 100), eDR);
    eDR=EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_ELECTRICAL, 100), eDR);
    eDR=EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_FIRE, 100), eDR);
    eDR=EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_MAGICAL, 100), eDR);
    eDR=EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_NEGATIVE, 100), eDR);
    eDR=EffectLinkEffects(EffectDamageImmunityIncrease(DAMAGE_TYPE_SONIC, 100), eDR);
    eDR=ExtraordinaryEffect(eDR);
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDR, OBJECT_SELF);

This covers everything other than positive and slashing, I don’t think positive will do any damage unless the target is undead. The problem with this approach is that placeables don’t have spawn scripts so you would likely have to have another event to apply this effect to the tree (I would probably use the on enter script for the area, with a run once check).

2 Likes

Yeah, damage immunity approach is more economic (script-wise too), though my suggestion can be used to filter a specific weapon, i.e. when you need a big axe rather than a puny short sword.

It hurts everybody just like any other type.

EDIT BELOW THIS LINE

Now that I thought about this once more, to make a placeable damageable only by a specific item (like a hatchet), one can combine @Wendigo211’s approach with OnHitCastSpell property (override x2_s3_onhitcast) on the item to temporarily remove a certain immunity (i.e. slashing) which gets restored in OnDamage handler…

…Or of you only care for bludgeoning / piercing protection (when other damage sources are OK), you can set placeable’s hardness in toolset to 250, set it to 0 in x2_s3_onhitcast, then return to 250 in OnDamage or via DelayCommand with 0.01 delay.

Does it really work? I tried applying damage immunity effect to doors and it didn’t. But it is true I haven’t tested it on placeable…

I tested it by putting it on the on damage event for a tree placeable before posting. The tree took damage from the first hit, but then all the damage for the subsequent hits was absorbed. Granted that’s not the event you want to use to apply the effect, but it was good enough for a quick and dirty test.

It works fine with doors.

What I posted works too. Strange enough OnHitCastSpell property script does not fire at all when target is plot, which is unfortunate since it is called after hit is registered but before damage is done calculated.

The set plot idea is actually great and it works, problem is that it sends out a message at the first hit “Your weapon is ineffective” which can be confusing to players, and only after that hit it stops sending the msg (because the flag is removed). I’m trying to think of a way to get around it. If you have a solution I’d love to hear it

By the way I went with a specific weapon (woodcutter’s axe for tree placeables)

If you went for a specific weapon, try this from my post above:

Give the axe an On Hit Cast Spell → Unique Power property in toolset, then check its (and GetAttackTarget’s / GetSpellTargetObject’s - both shoud work) tag in x2_s3_onhitcast. Or, per @Wendigo211’s answer, give the tree a 100% bludgeoning & piercing immunity (though it affects all weapons).

Seems a bit too complicated. I tried something that seemed easier to be by using the onclick event handle for the tree to check if the clicker is equipped with a woodcutter’s axe. However, GetItemInSlot only applies for “object_self”! Isn’t there a way for a placeable to know what the PC has equipped in “INVENTORY_SLOT_RIGHTHAND” if the PC just clicks it?

Not exactly. GetItemInSlot has an object parameter whose default is “OBJECT_SELF”. To say, if you do not specify an object when you call this function, it will default to using whomever is OBJECT_SELF within the calling script.

To get the item in oPC’s right hand slot, pass oPC as GetItemInSlot’s second parameter.

    object oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);

You can see what the parameters of the functions are in the lower part of the script editor, if you’re working within the toolset.

Oops!
I assumed that it’s automatically object_self because I got an error before, but I don’t seem to be getting it anymore so go figure!

But thanks for the detailed explanation, though yes I’ve been working a lot with the “Help” tab in the editor; I just misinterpreted the error. You’re great! :slight_smile:

1 Like

OK, put this oneliner as tree’s OnPhysicalAttacked handler. Note that it appears the change is actually commited on combat round end, so expect some weirdness when switching weapons.

void main()
{
    SetPlotFlag(OBJECT_SELF, "MY_WEAPON_TAG" ==
        GetTag(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, GetLastAttacker())));
}

I was wrong about OnHitCastSpell - it seems to fire only if target is physically damaged.

1 Like