[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