Author Topic: Capturing the wounding effect  (Read 500 times)

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Capturing the wounding effect
« on: February 10, 2012, 07:46:57 pm »


               I was recently able to use pseudo-heartbeats to capture an instance of wounding damage being applied, and retaining the wounding effect to apply it at any time later.  Functionally wounding damage can be anywhere from 1 to 5 damage per instance applied (used from the On-MonsterHit wounding type).  Wanting more flexibility I altered iprp_paramtable.2da to use iprp_spellcstr.2da instead of iprp_amount.2da.  (The amount 2da seems only to be called by the monster hit level drain and monster hit wounding).  Now I can achieve wounding damage up to 40 per round per application, that can be given to a creature through pseudo-heartbeat scripts (the amount is significant as wounding does not bypass damage reduction or any damage resistance).

Is there a significant call for generating this effect arbitrarily, especially for single player modules or does NWNX have the multiplayer aspect well covered for creating this effect on its own?
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Capturing the wounding effect
« Reply #1 on: February 11, 2012, 04:23:49 am »


               I don't really understand what it is you're trying to accomplish with this 'capture', and the 2da edits. You can implement persistent wounds of ANY damage amount using pseduoheartbeats, without the need for 2da changes. As you say, wounding doesn't bypass resistance or reduction, so I can see no need for such measures, when you can acheive the same with just a pseduo.

Here's some relevant code:


void ApplyPersistentWound (object oWounded) {
    if (GetIsDead(oWounded)                           ||
        GetLocalInt(oWounded, "PersistentWound") <= 0 ||
        GetHasSpellEffect(HGEFFECT_PERSISTENT_WOUND, oWounded))
        return;

    effect eLink = EffectSpellImmunity(HGSPELL_UNUSED);
    eLink = EffectLinkEffects(eLink, EffectIcon(EFFECT_ICON_WOUNDING));
    eLink = SupernaturalEffect(eLink);
    SetEffectSpellId(eLink, HGEFFECT_PERSISTENT_WOUND);

    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oWounded);
}

void DoPersistentWound (object oWounded, int nAdd=0, string sMessage="", float fInterval=6.0) {
    if (GetPlotFlag(oWounded)) {
        if (nAdd == 0)
            DelayCommand(fInterval, DoPersistentWound(oWounded, 0, "", fInterval));
        return;
    }

    if (GetIsDead(oWounded)) {
        DeleteLocalInt(oWounded, "PersistentWound");
        DeleteLocalInt(oWounded, "PersistentWoundRests");
        return;
    }

    int nRests = GetLocalInt(oWounded, "PersistentWoundRests");
    if (nRests > 0 && GetLocalInt(oWounded, "Rests") >= nRests) {
        DeleteLocalInt(oWounded, "PersistentWound");
        DeleteLocalInt(oWounded, "PersistentWoundRests");
        RemoveEffectsFromSpell(HGEFFECT_PERSISTENT_WOUND, oWounded);
        return;
    }

    if (nAdd > 0) {
        string sRes = GetResRef(GetItemInSlot(INVENTORY_SLOT_BELT, oWounded));
        if (sRes == "abosetbelt001" || sRes == "hivsetbelt001")
            return;

        if (sMessage != "")
            FloatingTextStringOnCreature(sMessage, oWounded, FALSE);

        int nAmount = GetLocalInt(oWounded, "PersistentWound");
        SetLocalInt(oWounded, "PersistentWound", nAmount + nAdd);

        if (nAmount > 0)
            return;

    } else {
        int nAmount = GetLocalInt(oWounded, "PersistentWound");
        SetLocalInt(oWounded, "PersistentWound", nAmount -1);//persistent wounds grow less virulent over time
    }

    object oArea = GetArea(oWounded);

    if (!GetIsObjectValid(oArea)) {
        DelayCommand(fInterval, DoPersistentWound(oWounded, 0, "", fInterval));
        return;
    }

    int nAmount = GetLocalInt(oWounded, "PersistentWound") + nAdd;
    if (nAmount <= 0) {
        DeleteLocalInt(oWounded, "PersistentWound");
        DeleteLocalInt(oWounded, "PersistentWoundRests");
        RemoveEffectsFromSpell(HGEFFECT_PERSISTENT_WOUND, oWounded);
        return;
    }

    if (!GetHasSpellEffect(HGEFFECT_PERSISTENT_WOUND, oWounded))
        AssignCommand(GenCreator(), ApplyPersistentWound(oWounded));

    ApplyDirectDamage(oWounded, nAmount, DAMAGE_TYPE_INTERNAL, DAMAGE_POWER_NORMAL,
        "Persistent Wound", "Your festering wound kills you!");

    if (!GetLocalInt(oWounded, "DirectDamageDeath")) {
        FloatingTextStringOnCreature("Your wound festers!", oWounded, FALSE);
        ApplyVisualToObject(PRCVFX_IMP_REDUCE_ABILITY_SCORE_RED, oWounded);
    } else {
        DeleteLocalInt(oWounded, "PersistentWound");
        DeleteLocalInt(oWounded, "PersistentWoundRests");
    }

    AssignCommand(oArea, DelayCommand(fInterval, DoPersistentWound(oWounded, 0, "", fInterval)));
}
The pseudos fire up again on client enter, if warranted, based on the variables.

Funky
               
               

               
            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Capturing the wounding effect
« Reply #2 on: February 11, 2012, 04:38:19 am »


               There is a distinction between wounding and direct damage per round.  Wounding is removed by any healing whatsoever.  Also wounding can respect the highest of the physical damage resistances while direct damage is bound to the damage type selected.

As far as the 2da edit, there is another reason.  ItemPropertyOnMonsterHitProperties()  does not function for wounding in general.  This is because it ignores the second argument (where you set the wounding amount) and regards it as 10 making the effect unable to be applied.  A 2da edit can allow 10 to be a valid parameter and thus allow one to script in this item property which before couldn't be scripted in.


EDIT: I am interested in your EffectIcon().  It is not a standard command.  NWNX?
               
               

               


                     Modifié par WhiZard, 11 février 2012 - 04:44 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Capturing the wounding effect
« Reply #3 on: February 11, 2012, 06:03:32 am »


               

WhiZard wrote...

There is a distinction between wounding and direct damage per round.  Wounding is removed by any healing whatsoever.  Also wounding can respect the highest of the physical damage resistances while direct damage is bound to the damage type selected.

You can easily code both of those. We restrict healing of persistent wounds to casterlevel 41+, on HG, so that you CAN'T simply do away with it via a healing potion or the like(what follows is an excerpt from our compilation of positive energy/neg energy healing compilation spellscript, hgs_gen_posneg):

                /* Heal can heal persistent wounds at CL41+ */
                if (si.id == SPELL_HEAL) {
                    if (GetLocalInt(si.target, "PersistentWound")) {
                        if (si.clevel > 40) {
                            DeleteLocalInt(si.target, "PersistentWound");
                            RemoveEffectsFromSpell(HGEFFECT_PERSISTENT_WOUND, si.target);

                            FloatingTextStringOnCreature("Your wound closes!", si.target, FALSE);
                        } else
                            FloatingTextStringOnCreature("The Heal spell was too weak to close the wound!", si.target, FALSE);
                    }
                }

Coded pseudos are inevitably going to be more flexible than the bioware wounding effect, though it IS sort of cool that you captured it.

As far as the 2da edit, there is another reason.  ItemPropertyOnMonsterHitProperties()  does not function for wounding in general.  This is because it ignores the second argument (where you set the wounding amount) and regards it as 10 making the effect unable to be applied.  A 2da edit can allow 10 to be a valid parameter and thus allow one to script in this item property which before couldn't be scripted in.

My point was more general - namely, that the use of the pseudo makes 2da edits completely unnecessary, because they can do all that wounding does and more. Frankly, I'd prefer a wounding effect that totally ignored resistances altogether, but that's a little trickier.

EDIT: I am interested in your EffectIcon().  It is not a standard command.  NWNX?

That's one of ours - it requires a custom client exe to see effect icons over the 255 limit (we added one for knockdown). That just allows application of icons where the engine wouldn't handle it otherwise (as with our custom-hacked movement alteration, which displays a Slowed icon without actually using a Slow effect).

I should also probably point out that the RemoveEffectsFromSpell function above is looking for a spell id set via nwnx function, but you don't need SetEffectSpellID to code persistent wounds with pseudos - or any nwnx functions, for that matter.

I still don't understand what advantage going to all this trouble to get the bioware wounding effect confers, if any.

Funky
               
               

               
            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Capturing the wounding effect
« Reply #4 on: February 11, 2012, 06:37:53 am »


               

FunkySwerve wrote...
You can easily code both of those.
...
I still don't understand what advantage going to all this trouble to get the bioware wounding effect confers, if any.

Funky

Your easy and hard seem a little odd.  The exact replication of removing the effect from any healing (even item property regeneration) is a bear especially in the middle of combat, but you don't seem too interested in exact replication.

As for getting the effect it really isn't that hard.  I can easily put up a script that can capture it typically within the first 15 seconds of the module.  OnMonsterHit wounding doesn't have a saving throw which helps catch it.  As far as storage you only need to persistently update about once every 60 seconds until certain creatures that might use it start having a non-zero AI level, in which case you can transfer an instance to the creature's pseudo heart beat that updates every round.  The key detail to remember is that the creature that cause the wounding MUST be kept alive (the original wounding effect can be safely removed), thus a separate "test" area is ideal. In addition, any time you wish to apply the wounding, simply update the original creature's name to match the creature which is applying the wounding and the target gets a nice line indicating that they were dealt damage by a name matching the creature they are fighting.  Yes, this looks complex, but it doesn't take too many lines of script either.
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Capturing the wounding effect
« Reply #5 on: February 11, 2012, 11:23:56 am »


               NWNX (nwnx_effects linux, nwnx_funcs win) should be able to generate this effect from scratch. However if you do not use NWNX yet from any reasons, there is nothing wrong on your current method, though it could be also captured in OnDamaged event.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Capturing the wounding effect
« Reply #6 on: February 11, 2012, 04:26:44 pm »


               

WhiZard wrote...

FunkySwerve wrote...
You can easily code both of those.
...
I still don't understand what advantage going to all this trouble to get the bioware wounding effect confers, if any.

Funky

Your easy and hard seem a little odd.
...
Yes, this looks complex, but it doesn't take too many lines of script either.

Complex, no. Unnecessarily convoluted, yes. I'm not sure what you think is 'hard' about what I'm suggesting - the bare minimum is a pseudo, which you're already using, and a Get/Set/Delete of a variable. Don't be confused by the frills we've added, like floaty text, different healing methods, and the like. If script line count is your measure of choice for complexity, I'm pretty sure my way is less complex. The difference lies in your going to some difficulty to capture an effect instead of simply using EffectDamage. I could understand this, maybe, if wounding were treated differently from other damage, as it should be - but it isn't.

Funky
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Capturing the wounding effect
« Reply #7 on: February 11, 2012, 05:05:12 pm »


               

WhiZard wrote...

FunkySwerve wrote...
You can easily code both of those.
...
I still don't understand what advantage going to all this trouble to get the bioware wounding effect confers, if any.

Funky

Your easy and hard seem a little odd.  The exact replication of removing the effect from any healing (even item property regeneration) is a bear especially in the middle of combat, but you don't seem too interested in exact replication.

You could use effect tracking method (showed in here: http://social.biowar...2/index/9115176) to properly replicate the remove of this effect via healer's kit etc. and use your own pseudo-hb to add any ammount of damage (probably magical) to damage effect holder
               
               

               
            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Capturing the wounding effect
« Reply #8 on: February 11, 2012, 08:52:19 pm »


               

ShaDoOoW wrote...

WhiZard wrote...

FunkySwerve wrote...
You can easily code both of those.
...
I still don't understand what advantage going to all this trouble to get the bioware wounding effect confers, if any.

Funky

Your easy and hard seem a little odd.  The exact replication of removing the effect from any healing (even item property regeneration) is a bear especially in the middle of combat, but you don't seem too interested in exact replication.

You could use effect tracking method (showed in here: http://social.biowar...2/index/9115176) to properly replicate the remove of this effect via healer's kit etc. and use your own pseudo-hb to add any ammount of damage (probably magical) to damage effect holder


The difficulty lies in catching when healing occurs rather than removing the effect.  Even with 60 psuedo heartbeats a round you may still not have the accuracy to catch most of the vampiric regeneration healing while you are being dealt damage.  Even if you could increase the frequency of the pseudoheartbeats to the point where you could non-redundantly use GetDamageDealtByType(), there are other ways of increasing hit points than just healing (e.g. constitution increase, leveling up).  It isn't just catching one aspect for exact replication.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Capturing the wounding effect
« Reply #9 on: February 12, 2012, 01:42:21 am »


               You lost me again. I thought you were just using the pseudos to capture the initial effect, and maybe pass it along on a slow iteration. Now it sounds like you're saying you need a ton of iterations per round just to deal with the unique disadvantages of wounding versus normal damage. I'm really not trying to be down on you, I just utterly fail to see the point, other than the sort of dorky-in-a-good-way cool factor of being able to grab the effect. Pseduos are not terribly cheap in terms of overhead, either...maybe I'm just missing something.

Funky
               
               

               
            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Capturing the wounding effect
« Reply #10 on: February 12, 2012, 03:00:56 am »


               

FunkySwerve wrote...

You lost me again. I thought you were just using the pseudos to capture the initial effect, and maybe pass it along on a slow iteration. Now it sounds like you're saying you need a ton of iterations per round just to deal with the unique disadvantages of wounding versus normal damage. I'm really not trying to be down on you, I just utterly fail to see the point, other than the sort of dorky-in-a-good-way cool factor of being able to grab the effect. Pseduos are not terribly cheap in terms of overhead, either...maybe I'm just missing something.

Funky


I was just using psuedos to capture the initial effect and pass it along by slow iteration.

You seem to find this worthless saying you could replicate the process with just psuedos.  I presented that using just psuedos (and not the wounding effect) would be more difficult than capturing the wounding effect, as you would need to capture the healing events in order to tell you to stop applying damage.

On the whole I listed two aspects of wounding that were difficult to replicate without the effect
a) Removal of the effect by any healing
'B)' Using of highest physical damage resistance

Your response to these were
a) Only high level spells should remove wounding
'B)' Damage reduction and resistance should not be considered for wounding damage

Having looked at your implentation (designed around wounds festering over many rests) it looks like you are trying to replicate the disease apsect of weapons penetrating the body, than the perfuse bleeding that does not clot.

As far as damage reduction/resistance, these are in part given to creatures whose hide is tough enough, or who lack of bodily fluids altogether, to prevent any perfuse form of bleeding.  Thus one would not expect a wraith to bleed.  As far as PC usage, the feats and spells by and large seem to line up in this regard.  Monk 20 (where in DnD the monk becomes an outsider) provides DR reflecting a change in body.  Ghostly and ethereal visage allow the body to be different.  Depletable forms of DR like stoneskin will slowly be overcome by the perfuse bleeding.

As far as how DnD should implement things, or whether it should step back a few editions where aging and ailments were more of a concern, and didn't have fights where heros regularly suffered so many bodily ruptures and detortions that it would take a miracle to recover, that is a reasonable concern insofar as getting the game to return to reality.

When one is perfusely bleeding, they obviously will not survive the night, which is one reason why wounding prevents resting.  Whether or not minor regeneration should be able to clot bleeding may be another concern.  But on  the whole it looks like you are focusing more on the infectous end then on the perfuse bleeding end.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Capturing the wounding effect
« Reply #11 on: February 12, 2012, 05:55:55 am »


               

WhiZard wrote...

You seem to find this worthless saying you could replicate the process with just psuedos.  I presented that using just psuedos (and not the wounding effect) would be more difficult than capturing the wounding effect, as you would need to capture the healing events in order to tell you to stop applying damage.


Ahh, that's what I was missing, thanks. We actually go out of our way to avoid that behavior on HG, but that's obviously going to vary widely based on server power level, etc. If that's why you're doing it, it makes perfect sense. Sorry for being dense. '<img'>

Funky
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Capturing the wounding effect
« Reply #12 on: February 12, 2012, 01:40:12 pm »


               I still don't understand.

What I suggested is using both methods:
- using OnDamaged/pseudo-hb to capture wounding effect that has not yet been captured
- remove orignal effect and apply it again with VFX linked into it or with different subtype to mark this effect as captured (i suspect the subtype is magical)
- run new pseudohb with this effect where you can apply damage of any ammount as long as the effect is present on PC
               
               

               


                     Modifié par ShaDoOoW, 12 février 2012 - 01:40 .
                     
                  


            

Legacy_leo_x

  • Sr. Member
  • ****
  • Posts: 403
  • Karma: +0/-0
Capturing the wounding effect
« Reply #13 on: February 12, 2012, 02:54:54 pm »


               Probably won't be of much help to you, but using Acaos' nwnx_structs on the linux side creating the wounding effect for arbitrary damage amounts is pretty simple:

effect EffectWounding (int nAmount) {
    effect eEff = EffectVisualEffect(nAmount);

    SetEffectTrueType(eEff, EFFECT_TRUETYPE_WOUNDING);
    return eEff;
}

nwnx_funcs for windows would probably let you do the same.
               
               

               


                     Modifié par pope_leo, 12 février 2012 - 03:01 .
                     
                  


            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Capturing the wounding effect
« Reply #14 on: February 12, 2012, 05:45:12 pm »


               

ShaDoOoW wrote...

I still don't understand.

What I suggested is using both methods:
- using OnDamaged/pseudo-hb to capture wounding effect that has not yet been captured
- remove orignal effect and apply it again with VFX linked into it or with different subtype to mark this effect as captured (i suspect the subtype is magical)
- run new pseudohb with this effect where you can apply damage of any ammount as long as the effect is present on PC


Wounding (once applied) doesn't run on a scripted pseudo heartbeat.  It applies the specified damage once each round and is removed instantaneously by any healing.  I don't understand how you would change a parameter of the effect.