ShaDoOoW wrote...
Dont forget that MM's solution (same as my immunity to dev crit script) has downsides like immunity to any mind-affecting effect, devastating critical hit, death magic etc.
Only if you're worried about the creatures taking >2500 damage between calls of the script, and that's only a worry during the last 25% of the creature's effective health (because otherwise they'd need to take >5000 damage).
And of course it's independent of the health percentage display.
ShaDoOoW wrote...
I was admin of a PW like that (legendary levels above 40, magic gear +9) and we didnt needed such absurd numbers especially if you can balance that with high regeneration, damage immunity or damage resistance
The main problem with damage immunity is that it doesn't play nicely because it's additive. For example, let's say you make a boss with 50% immunity to everything and also give him Elemental Shield. Instead of taking 25% damage from Fire and Cold, he takes 0%. Stuff like that means you need to be careful. Regeneration can also have issues (such as the boss having more hit points the longer the fight goes on) which need to be considerd.
ShaDoOoW wrote...
Again the concept is brilliant, but the method of doing that less so. Also for very massive hit points, 10k hp base is not enought to make proper illusion of the default HP percentage so for a more than 100k hp editing the creature's base hitpoint via the method I suggested would be preferred anyway.
See below regarding method (in response to Funky).
Why do you think 10k isn't enough to make a proper illusion? Unless you take 2500 or more damage between calls of the script, the illusion should be (nearly) perfect.
FunkySwerve wrote...
Was there no way to achieve this via ondamaged?
You could remove main, some of the arguments being passed, and the DelayCommand call and stick the UpdateHP funtion in OnDamage (would take like 5-10 minutes to adjust it, I suspect). However, that does raise additional problems:
1, it won't account for regeneration until you get damaged again (scripted or natural).
2, it won't account for any healing period until you get damaged again, though you could call the UpdateHP function every time a healing spell is cast at the creature or something
3, if you had, say, 10 mages unloading the default IGMS (20 missiles) at a target, that's already calling OnDamaged 200 times in about 3 seconds. You wouldn't want/need to call this function that often, so you'd probably want to use a local int or something to make sure it doesn't fire more often than every 0.5-1.0 seconds or whatever.
In other words, it'd be workable, but requires more effort to set up and I don't know how much of a performance gain it would be (meaning I really have no idea, not that I'm sure they're roughly equal, see below).
FunkySwerve wrote...
That said, I wouldn't use your approach either - it sounds like an immense amount of unnecessary overhead.
Well, admittedly I understand very little of the technical aspects of NWN - you're the expert in that regard. My thought process was to make the "heartbeat" extremely extremely simple to avoid the overhead. The following is all that happens if the creature has NOT taken damage or healing since the previous call.
void UpdateHP(int nPrev, int nMax)
{
int nCurrent = GetCurrentHitPoints(), nMassive;
if (nPrev != nCurrent)
{
}
DelayCommand(0.5, UpdateHP(nCurrent + nMassive, nMax));
}
1. Receive the arguments from the previous call
2. Retrieve the current hit points and set up another int called nMassive (which is 0)
3. Compare one of the arguments to currentHP and since they're equal do nothing
4. Call itself again in 0.5 (or 1.0 or 2.0 or whatever) seconds with equivalent arguments (since nMassive is still 0)
The main problem is that I don't know how expensive function calls are (and how DelayCommand affects that). I assumed they were trivial, but if simply calling the function is a large constant while the work within the function is relatively immaterial, then obviously this approach could be made far more efficient by any of the following:
1, rework it to be put in OnDamaged (and if the extra code within one script is seriously inconsequential compared to having another script running, then maybe you wouldn't even need the cooldown on running Update (though it might still be a good idea)).
2, have it run every, say, 6 seconds out of combat and every 0.5-1.0 seconds in combat. I originally had it set up like this but it means you could go 5.99 seconds without any update if the creature entered combat right after the heartbeat ticked. Not the end of the world, but I wasn't sure how much of a performance improvement it actually was.
3. Check to see whether an enemy is within 50 yards, and if so start running every second. If not, don't run again for 12-18 seconds or whatever.
4. Only run while an enemy is in the area. If no enemies are in the area, then stop running. Start it back up with the OnEnter script for the area if enemies return.
1 and 4 require more work to set up, 2 and 3 have the potential problem of taking a few seconds to kick in. In 3, for example, if an enemy moves from 51 yards to 30 yards in like 5 seconds and starts attacking with a ranged weapon, it could take 13 seconds for the percent/health pool to start updating.
So, yeah, it largely depends on how the engine handles things (and I don't know). Is a separate script running a single line of code far more expensive than an existing script running 20 additional lines of code (obviously the actual operations matter, just as a general principle)? How do psuedo heartbeat functions factor into that?
By default, my script has like 3 main actual operations per heartbeat. If I added a while loop that checked the surrounding area or something, that would greatly increase the number of operations per heartbeat - but it still might be more efficient overall if the heartbeat itself was very expensive (regardless of the code in it). #4 in the list up there seems like it might technically be the best solution (in OnExit, set a local int to 1 that indicates UpdateHP should stop running and then in OnEnter set it to 0 and call UpdateHP to restart the process, so only creatures in an area with enemies would have the heartbeat running), but you'd have to integrate that into every area's OnEnter/OnExit, which might be very complicated for some modules.
Modifié par MagicalMaster, 15 mars 2013 - 08:42 .