[crossfire] Curse bug
Mark Wedel
mwedel at sonic.net
Sun Dec 3 00:11:24 CST 2006
Nicolas Weeger (Laposte) wrote:
> Reading fix_object (former fix_player), it seems to be there's a big mess
> waiting to happen (or already happened?) :)
>
> Basically, fix_object resets many many things, including all special flags
> (see in dark, stealth, ...), resistances, ...
> This means all those custom values will simply disappear whenever a monster
> will drink a potion, be hit by a curse or a disease, things like that :)
> Of course fix_object works fine when called with a player, but will horribly
> alter things for a customized monster.
>
> I can see a few possible fixes:
> * fix fix_object so it handles things correctly
It's unclear how one can simply fix fix_object(), because as you describe,
there are lots of values modified, so you basically need to know what those are
(fix_object has to start with some baseline of what the initial values are
supposed to be).
> * don't call fix_object except when absolutely required. Recode eg curse to
> simply decrease wc, and restore it later when the force expires. Of course
> it's a mess with other things modifying wc
Yes - especially if the monster has already been modified so some attributes
are near maximums.
Eg, if a creature has fire_resistance 100, anything that adds fire resistance
won't have any effect. But if a player cast a fire resistance spell on the
monster, when that spells ends, the monster still needs to have fire resistance
100 (you can't take away the resistance the spell would give).
There may be osme other cases like that - the way the bonuses stack, max/worse
bonuses (if wc is -120, nothing can improve it further, but if the monster
unequips it, his wc should still be wc -120 if that is what the map set it to, etc).
Plus, it means you have places all in the code to handle this. I suppose the
right approach would be to have a function for applying/unapplying these force
objects to the monster, but there are so many odd cases.
> * we could store all modified values so fix_object knows what to search for.
> An overkill solution is to temporarily create an artifact for each customized
> monster, and free it when monster diseappears.
Do you mean artifact or archetype? I'd think archetype would be easier - you
could update op->arch with the new archetype (but really, you just chare about
op->arch.clone). You could even store away the original archetype is
op->arch.clone->arch
This might be one of the simplest things to do - fix_player() really wouldn't
need to be modified, because it already looks at op->arch for the initial
starting values. What would need to be modified is the load code (to know when
to create a new archtype) and the save code (need to go back to
op->arch.clone->arch to get the differences, since the load code would go back
to the original archetype for starting values).
There is still a little complication - take this situation:
Have modified monster, including say wc.
Spell is cast on monster, modifying its wc
Player leaves map, and map gets swapped out, so wc needs to be saved.
You probably don't want to save the wc as modified by the spell, because then
when the map is swapped back in, we no longer know what the original (modified)
value is.
You need to save the wc as specified in the original map (op->clone), and then
when loaded back in, know to call fix_player() to get values back to normal
(spell effect would be saved in the inventory, so doing this should get the same
value back that was there before it was swapped out).
That doesn't sound very complicated, but there are some values where you
always want to save the op-> values and not the op->arch values (hp, sp, grace)
- I'm not sure if there are any others - everything else I think could be
derived from the temporary archetype values.
One other complication is this:
Standard orc on a map
orc equips some armor
map is swapped out - orc now has different AC
So in this case, you once again want to do the same thing above - save the
orcs original values and mark it to re-run fix_player() at load. Otherwise, it
looks like a modified value, and you don't want to create an archetype from that.
The extra memory for the archetypes isn't likely to be that big a deal -
crossfire as it is right now doesn't use a whole lot of memory given how much
memory modern systems have, and if limited to modified monsters, that is a
pretty low impact.
One other method that could be used to fix the problem:
For modified monsters, instead of modifying the values and saving those values
on the map, instead create a permanent force object with the modified values (or
more likely, the values necessarily to modify the standard archetype to get the
modified values). In this way, when fix_player() is called, it finds this
archetype, and everything works out.
That would require a lot of maps to be updated. Ideally, the editor would be
modified so that this is invisible to the map designer - the problem here is
that it means that the editor would have to have a lot of smarts (know how those
values are calculated, etc). And if the method of calculation ever changes, or
new things added, then that probably breaks that change.
I think temporary archetype is really the best way to go.
More information about the crossfire
mailing list