Saving throws (revisited)

From: The Merciless Lord of Everything (serces@mud.dk)
Date: 11/27/00


So there..

After having had some serious thought and some serious discussions with
Imms we've deviced a better (In our opinion) Saving throw system.

The general idea was to make a system that didn't rely on static Arrays to
work, we didn't quite overcome that one, but at least we made it a bit
more simple :). The system looks at Level of victim and level of attacker
and calculates it's saving throw from there, and then adds/subtracts a
type-modifier, returning the ending result. Also, we've cut down on the
saving throw types from 5 to 3 (but that is fortunately changeable :)

First add this in structs.h after con_app_type:
struct save_modifier_type {
   byte physical;
   byte staff;
   byte magic;
};

then in Class.c (or wherever you'd like the definition of the modifiers to
be):
struct save_modifier_type save_modifier[] = {
/*   Physical   Staff  Magic  */
  {   20,        -10,     -20  }, /* Wizard */
  {   10,          0,     -10  }, /* Cleric */
  {   20,          0,     -20  }, /* Thief */
  {  -15,          5,      15  }, /* Warrior */
  {    0,          0,       0  }, /* Unknown */
};

In magic.c you need to declare the above struct
extern struct save_modifier_type save_modifier[];

int calc_saving_throw(struct char_data *ch, struct char_data *victim, int
save_type)
{
  float base_save = 0;
  float saving_throw = 0;
  float mod = 0;
  if (GET_LEVEL(ch) >= LVL_IMMORT) {
/* Gods have all the fun! :) */
    return(1);
  }
  if (!IS_NPC(victim)) {
    switch (save_type) {
      case SAVE_MAGIC:
        mod = save_modifier[(int)GET_CLASS(victim)].magic;
      break;
      case SAVE_PHYSICAL:
        mod = save_modifier[(int)GET_CLASS(victim)].physical;
      break;
      case SAVE_STAFF:
      break;
      default:
        log("SYSERR: Called saving_throws with an unknown save_type (%d)",
save_type);
        return (99);
      break;
    }
  } else {
/*
 * NPC's get their saving throw from Knights..
 */
    mod = save_modifier[CLASS_WARRIOR].staff;
  }

  base_save = (100 - (GET_LEVEL(victim) - GET_LEVEL(ch))) / 2;
  saving_throw = base_save + ((mod / 100) * base_save);

  return MIN(100,(int)saving_throw);
}

And now remove all the saving throws (Those majestic arrays) :).

Still in magic.c, you need to change mag_savingthrow so that it looks like
this:

int mag_savingthrow(struct char_data * ch, struct char_data * victim, int
type)
{
  int save;

  save = calc_saving_throw(ch,victim,type);
  save += GET_SAVE(ch, type);

  /* throwing a 0 is always a failure */
  if (MAX(1, save) < number(0, 99))
    return TRUE;
  else
    return FALSE;
}


And now it's a matter of finding all the places where mag_saving throw is
called and change them.

NB: I've noted that in more recent versions of Circle, the saving throws
are no longer in magic.c, but in class.c, but of course I don't need to
tell you this.

Also, stock circle carries 5 Savingthrow types instead of these 3. I felt
that a change from 5 to 3 would make things more simple.

Magic means  anything that cannot be measured as either Staff or Physical.
Staff is when someone uses a staff against someone.
Physical, All skills can be considered physical (more or less), also
spells like poison.

of course, if you feel like you need all 5 you just expand the function...


Have fun! :)

/S



               Speak softly and carry a cellular phone.

--
   +---------------------------------------------------------------+
   | FAQ: http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html |
   | Archives: http://post.queensu.ca/listserv/wwwarch/circle.html |
   +---------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 04/11/01 PDT