Capturing the wounding effect
#1
Posté 10 février 2012 - 07:46
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?
#2
Posté 11 février 2012 - 04:23
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
#3
Posté 11 février 2012 - 04:38
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 .
#4
Posté 11 février 2012 - 06:03
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):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.
/* 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.
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.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.
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).EDIT: I am interested in your EffectIcon(). It is not a standard command. NWNX?
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
#5
Posté 11 février 2012 - 06:37
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.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
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.
#6
Posté 11 février 2012 - 11:23
#7
Posté 11 février 2012 - 04:26
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.WhiZard wrote...
Your easy and hard seem a little odd.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
...
Yes, this looks complex, but it doesn't take too many lines of script either.
Funky
#8
Posté 11 février 2012 - 05:05
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 holderWhiZard wrote...
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.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
#9
Posté 11 février 2012 - 08:52
ShaDoOoW wrote...
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 holderWhiZard wrote...
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.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
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.
#10
Posté 12 février 2012 - 01:42
Funky
#11
Posté 12 février 2012 - 03:00
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
Your response to these were
a) Only high level spells should remove wounding
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.
#12
Posté 12 février 2012 - 05:55
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.
Funky
#13
Posté 12 février 2012 - 01:40
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 .
#14
Posté 12 février 2012 - 02:54
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 .
#15
Posté 12 février 2012 - 05:45
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.
#16
Posté 12 février 2012 - 06:39
pope_leo wrote...
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.
Just curious if you have tested this; moreso because it seems wounding would also require an object parameter (the object that applied the wounding). Should this object die the wounding would typically last at most one more round and then disappear. This latter behavior I will be overriding by keeping the actual creature alive.
#17
Posté 12 février 2012 - 07:37
WhiZard wrote...
pope_leo wrote...
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.
Just curious if you have tested this; moreso because it seems wounding would also require an object parameter (the object that applied the wounding). Should this object die the wounding would typically last at most one more round and then disappear. This latter behavior I will be overriding by keeping the actual creature alive.
I didn't test fully every aspect of it, because ultimately my world was too high magic to make use of it. I can say impact was applied every round and it was negated by any healing/regen effects as expected.
Since the technique here (developed by Acaos so far as I know) is to 'trick' the game engine into treating a visual effect as an effect of a different type, it's just as you'd suspect: the applier/creator is implicity OBJECT_SELF so you could AssignCommand it to any object if you wanted.
Modifié par pope_leo, 12 février 2012 - 07:47 .
#18
Posté 12 février 2012 - 09:30
pope_leo wrote...
WhiZard wrote...
pope_leo wrote...
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.
Just curious if you have tested this; moreso because it seems wounding would also require an object parameter (the object that applied the wounding). Should this object die the wounding would typically last at most one more round and then disappear. This latter behavior I will be overriding by keeping the actual creature alive.
I didn't test fully every aspect of it, because ultimately my world was too high magic to make use of it. I can say impact was applied every round and it was negated by any healing/regen effects as expected.
Since the technique here (developed by Acaos so far as I know) is to 'trick' the game engine into treating a visual effect as an effect of a different type, it's just as you'd suspect: the applier/creator is implicity OBJECT_SELF so you could AssignCommand it to any object if you wanted.
That's interesting, because in the effect I capture I can't change the one initiating the wounding damage with AssignCommand(). Did the applier turn out to be the damager?
#19
Posté 12 février 2012 - 10:09
WhiZard wrote...
pope_leo wrote...
WhiZard wrote...
pope_leo wrote...
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.
Just curious if you have tested this; moreso because it seems wounding would also require an object parameter (the object that applied the wounding). Should this object die the wounding would typically last at most one more round and then disappear. This latter behavior I will be overriding by keeping the actual creature alive.
I didn't test fully every aspect of it, because ultimately my world was too high magic to make use of it. I can say impact was applied every round and it was negated by any healing/regen effects as expected.
Since the technique here (developed by Acaos so far as I know) is to 'trick' the game engine into treating a visual effect as an effect of a different type, it's just as you'd suspect: the applier/creator is implicity OBJECT_SELF so you could AssignCommand it to any object if you wanted.
That's interesting, because in the effect I capture I can't change the one initiating the wounding damage with AssignCommand(). Did the applier turn out to be the damager?
An effects creator is set when the effect is created, application doesn't change that. I was going to mention that but I didn't want to split hairs unnecessarily. If you have a scenario like such:
void func(object pc, effect eff){
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eff, pc);
}
void main()
{
object pc = GetLastUsedBy();
effect eff = EffectWounding(100);
AssignCommand(GetArea(pc), func(pc, eff));
}
The damage will be done by whomever OBJECT_SELF was at the time of effect creation, not application.
There is one caveat to what I said, the effect can't be assigned to any object, it really needs to be a creature. Placeables, Areas, etc, will apply the wounding but do the damage once on impact and then it will end.





Retour en haut






