[CF-Devel] PROPOSAL: Luck

Tim Rightnour root at garbled.net
Mon Sep 17 01:35:28 CDT 2001


Included are the patches to make luck work per my proposal.  I have added the
die_roll and random_roll functions to common/player.c, because it wasn't
obvious to me where such procedures would go, and it generally seemed to fit
the concept of the other functions in that file.  I have also modified
spell_util.c as an example of how my code is to be implemented.

In addition.. I am a bit confused as to where to add my function prototypes.  I
would have expected them to live in player.h, but there is the sproto.h, which
seems to be machine generated, and I wasn't sure what to do with that.

Finally, I might like to add two defines to one of the .h files, PREFER_HIGH
and PREFER_LOW, rather than using 1 and 0 for the goodbad argument to the
functions.  I think it would improve code readability significantly (and make
it immediately obvious if a high or low roll is good to coders) but I'm not
sure what the coding style is WRT this.

BTW- you really want diff -C?  diff -u is so much easier to read.

*** common/player.c.orig        Sun Sep 16 13:53:35 2001
--- common/player.c     Sun Sep 16 17:48:11 2001
***************
*** 132,134 ****
--- 132,196 ----
      }
      return skill1;
  }
+ 
+ /*
+  * Roll a random number between min and max.  Uses op to determine luck,
+  * and if goodbad is non-zero, luck increases the roll, if zero, it decreases.
+  * Generally, op should be the player/caster/hitter requesting the roll,
+  * not the recipient (ie, the poor slob getting hit). [garbled 20010916]
+  */
+ 
+ int random_roll(int min, int max, object *op, int goodbad) {
+     int omin, diff, luck;
+ 
+     omin = min;
+     diff = max - min + 1;
+ 
+     if (op->type != PLAYER)
+       return((RANDOM()%diff)+min);
+ 
+     luck = op->stats.luck;
+     if (RANDOM()%20 < MIN(10, abs(luck))) {
+       /* we have a winner */
+       ((luck > 0) ? (luck = 1) : (luck = -1));
+       diff -= luck;
+       ((goodbad) ? (min += luck) : (diff));
+ 
+       return(MAX(omin, MIN(max, (RANDOM()%diff)+min)));
+     }
+     return((RANDOM()%diff)+min);
+ }
+ 
+ /*
+  * Roll a number of dice (2d3, 4d6).  Uses op to determine luck,
+  * If goodbad is non-zero, luck increases the roll, if zero, it decreases.
+  * Generally, op should be the player/caster/hitter requesting the roll,
+  * not the recipient (ie, the poor slob getting hit).
+  * The args are num D size (ie 4d6)  [garbled 20010916]
+  */
+ 
+ int die_roll(int num, int size, object *op, int goodbad) {
+     int min, diff, luck, total, i, gotlucky;
+ 
+     diff = size;
+     min = 1;
+     luck = total = gotlucky = 0;
+ 
+     if (op->type == PLAYER)
+       luck = op->stats.luck;
+ 
+     for (i = 0; i < num; i++) {
+       if (RANDOM()%20 < MIN(10, abs(luck)) && !gotlucky) {
+           /* we have a winner */
+           gotlucky++;
+           ((luck > 0) ? (luck = 1) : (luck = -1));
+           diff -= luck;
+           ((goodbad) ? (min += luck) : (diff));
+           total += MAX(1, MIN(size, (RANDOM()%diff)+min));
+       } else {
+           total += RANDOM()%size+1;
+       }
+     }
+     return(total);
+ }
+ 
*** server/spell_util.c.orig    Sun May 13 14:55:41 2001
--- server/spell_util.c Sun Sep 16 17:41:43 2001
***************
*** 212,218 ****
           *Instead of subtracting 10 from the roll, add in grace (which is
           * negative).  This puts a real limit on things.
           */
!         if( (RANDOM()%op->stats.Wis) +op->stats.grace -
                 
10*SP_level_spellpoint_cost(op,caster,type)/op->stats.maxgrace >0) {
  #ifdef MULTIPLE_GODS
                          new_draw_info_format(NDI_UNIQUE, 0,op, 
--- 212,218 ----
           *Instead of subtracting 10 from the roll, add in grace (which is
           * negative).  This puts a real limit on things.
           */
!         if(random_roll(0, op->stats.Wis, op, 1) + op->stats.grace -
                 
10*SP_level_spellpoint_cost(op,caster,type)/op->stats.maxgrace >0) {
  #ifdef MULTIPLE_GODS
                          new_draw_info_format(NDI_UNIQUE, 0,op, 
***************
*** 311,320 ****
      return 0;
    }
    if(item == spellNormal && op->type==PLAYER&&s->cleric&&
!         /*     RANDOM()%100< s->level*2 - op->level +
cleric_chance[op->stats.Wis]-
!                               op->stats.luck*3) {*/
!         RANDOM()%100 < s->level/(float)MAX(1,op->level) *
cleric_chance[op->stats.Wis]-
!         op->stats.luck*3) {
      play_sound_player_only(op->contr, SOUND_FUMBLE_SPELL,0,0);
      new_draw_info(NDI_UNIQUE, 0,op,"You fumble the spell.");
  #ifdef CASTING_TIME
--- 311,319 ----
      return 0;
    }
    if(item == spellNormal && op->type==PLAYER&&s->cleric&&
!         random_roll(0, 99, op, 1) < s->level/(float)MAX(1,op->level) *
!         cleric_chance[op->stats.Wis]) {
! 
      play_sound_player_only(op->contr, SOUND_FUMBLE_SPELL,0,0);
      new_draw_info(NDI_UNIQUE, 0,op,"You fumble the spell.");
  #ifdef CASTING_TIME
***************
*** 327,340 ****
    }
  #ifdef SPELL_ENCUMBRANCE
    if(item == spellNormal && op->type==PLAYER && (!s->cleric) ) {
!     int failure = (RANDOM()%200) - op->contr->encumbrance +op->level
-s->level +35;
  
      if( failure < 0) {
        new_draw_info(NDI_UNIQUE, 0,op,"You bungle the spell because you have
too much heavy equipment in use.");
  #ifdef SPELL_FAILURE_EFFECTS
          spell_failure(op,failure,SP_level_spellpoint_cost(op,caster,type));
  #endif
!       return RANDOM()%(SP_level_spellpoint_cost(op,caster,type)+ 1);
        }
     }
  #endif /*SPELL_ENCUMBRANCE*/
--- 326,339 ----
    }
  #ifdef SPELL_ENCUMBRANCE
    if(item == spellNormal && op->type==PLAYER && (!s->cleric) ) {
!     int failure = random_roll(0, 199, op, 0) - op->contr->encumbrance
+op->level -s->level +35;
  
      if( failure < 0) {
        new_draw_info(NDI_UNIQUE, 0,op,"You bungle the spell because you have
too much heavy equipment in use.");
  #ifdef SPELL_FAILURE_EFFECTS
          spell_failure(op,failure,SP_level_spellpoint_cost(op,caster,type));
  #endif
!       return(random_roll(1, SP_level_spellpoint_cost(op,caster,type), op, 0));
        }
     }
  #endif /*SPELL_ENCUMBRANCE*/
***************
*** 608,642 ****
      success = fire_arch(op,caster,dir,spellarch[type],type,!ability);
      break;
    case SP_METEOR_SWARM: {
-     int n;
-     n=RANDOM()%3 + RANDOM()%3 + RANDOM()%3 +3 +
-       SP_level_strength_adjust(op,caster, type);
      success = 1;
!     fire_swarm(op,caster,dir,spellarch[type],SP_METEOR,n,0);
      break;
    }
    case SP_BULLET_SWARM: {
-     int n;
-     n=RANDOM()%3 + RANDOM()%3 + RANDOM()%3 +3 +
-       SP_level_strength_adjust(op,caster, type);
      success = 1;
!     fire_swarm(op,caster,dir,spellarch[type],SP_BULLET,n,1);
      break;
    }
    case SP_BULLET_STORM: {
-     int n;
-     n=RANDOM()%3 + RANDOM()%3 + RANDOM()%3 +3 +
-       SP_level_strength_adjust(op,caster, type);
      success = 1;
!     fire_swarm(op,caster,dir,spellarch[type],SP_LARGE_BULLET,n,1);
      break;
    }
    case SP_CAUSE_MANY: {
-     int n;
-     n=RANDOM()%3 + RANDOM()%3 + RANDOM()%3 +3 +
-       SP_level_strength_adjust(op,caster, type);
      success = 1;
!     fire_swarm(op,caster,dir,spellarch[type],SP_CAUSE_HEAVY,n,1);
      break;
    }
    case SP_METEOR:
--- 607,633 ----
      success = fire_arch(op,caster,dir,spellarch[type],type,!ability);
      break;
    case SP_METEOR_SWARM: {
      success = 1;
!     fire_swarm(op, caster, dir, spellarch[type], SP_METEOR,
!       die_roll(3, 3, op, 1) + SP_level_strength_adjust(op,caster, type), 0);
      break;
    }
    case SP_BULLET_SWARM: {
      success = 1;
!     fire_swarm(op, caster, dir, spellarch[type], SP_BULLET,
!       die_roll(3, 3, op, 1) + SP_level_strength_adjust(op,caster, type), 0);
      break;
    }
    case SP_BULLET_STORM: {
      success = 1;
!     fire_swarm(op, caster, dir, spellarch[type], SP_LARGE_BULLET,
!       die_roll(3, 3, op, 1) + SP_level_strength_adjust(op,caster, type), 0);
      break;
    }
    case SP_CAUSE_MANY: {
      success = 1;
!     fire_swarm(op, caster, dir, spellarch[type], SP_CAUSE_HEAVY,
!       die_roll(3, 3, op, 1) + SP_level_strength_adjust(op,caster, type), 0);
      break;
    }
    case SP_METEOR:
***************
*** 2259,2265 ****
    insert_ob_in_ob(new_aura, op);
    return 1;
  }
!           
  /*  look_up_spell_by_name:  peterm
      this function attempts to find the spell spname in spells[].
      if it doesn't exist, or if the op cannot cast that spname,
--- 2250,2256 ----
    insert_ob_in_ob(new_aura, op);
    return 1;
  }
! 
  /*  look_up_spell_by_name:  peterm
      this function attempts to find the spell spname in spells[].
      if it doesn't exist, or if the op cannot cast that spname,


---
Tim Rightnour <
     
     root at garbled.net
     
     >
NetBSD: Free multi-architecture OS 
     
     http://www.netbsd.org/
     
     
NetBSD supported hardware database: 
     
     http://mail-index.netbsd.org/cgi-bin/hw.cgi
     
     
    


More information about the crossfire mailing list