[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