Mercurial > hg > early-roguelike
view urogue/daemons.c @ 279:d3968e9cb98d
Use C stdio functions for score files and save files.
Switching from Unix file descriptor operations to C standard FILE*
functions will reduce portability problems.
| author | John "Elwin" Edwards |
|---|---|
| date | Fri, 15 Sep 2017 19:57:54 -0400 |
| parents | c4b12d2d1dcd |
| children |
line wrap: on
line source
/* daemons.c - All the daemon and fuse functions are in here UltraRogue: The Ultimate Adventure in the Dungeons of Doom Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong All rights reserved. Based on "Advanced Rogue" Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka All rights reserved. Based on "Rogue: Exploring the Dungeons of Doom" Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman All rights reserved. See the file LICENSE.TXT for full copyright and licensing information. */ #include "rogue.h" /* doctor() A healing daemon that restors spell and hit points after rest */ void doctor(daemon_arg *who) { struct thing *tp = who->thingptr; long ohp; /* turn off ISFLEE? */ struct stats *curp; /* current stats pointer */ struct stats *maxp; /* max stats pointer */ int turns_quiet, new_points; curp = &(tp->t_stats); maxp = &(tp->maxstats); if (on(*tp, ISINWALL)) { tp->t_rest_hpt = 0; return; } /* Check for regenerating spell points first */ doctor_spell_points(tp); if (curp->s_hpt == maxp->s_hpt) { tp->t_rest_hpt = 0; return; } tp->t_rest_hpt++; switch (tp->t_ctype) { case C_MAGICIAN: case C_ILLUSION: turns_quiet = 24 - curp->s_lvl; new_points = curp->s_lvl / 2 - 4; break; case C_THIEF: case C_ASSASIN: case C_NINJA: turns_quiet = 16 - curp->s_lvl; new_points = curp->s_lvl / 2 - 1; break; case C_CLERIC: case C_DRUID: turns_quiet = 16 - curp->s_lvl; new_points = curp->s_lvl / 2 - 2; break; case C_FIGHTER: case C_RANGER: case C_PALADIN: turns_quiet = 8 - curp->s_lvl / 2; new_points = curp->s_lvl / 2 - 1; break; case C_MONSTER: turns_quiet = 16 - curp->s_lvl; new_points = curp->s_lvl / 2 - 6; break; default: debug("What a strange character you are!"); return; } ohp = curp->s_hpt; if (off(*tp, HASDISEASE)) { if (curp->s_lvl < 8) { if (tp->t_rest_hpt > turns_quiet) curp->s_hpt++; } else if (tp->t_rest_hpt >= 15) curp->s_hpt += rnd(new_points) + 1; } if (tp == &player) { if (curp->s_lvl > 10) turns_quiet = 2; else turns_quiet = rnd(turns_quiet / 6) + 1; if (is_wearing(R_REGEN)) curp->s_hpt += ring_value(R_REGEN); } if (on(*tp, ISREGEN)) curp->s_hpt += curp->s_lvl / 5 + 1; if (ohp != curp->s_hpt) { if (curp->s_hpt >= maxp->s_hpt) { curp->s_hpt = maxp->s_hpt; if (off(*tp, WASTURNED) && on(*tp, ISFLEE) && tp != &player) { turn_off(*tp, ISFLEE); tp->t_oldpos = tp->t_pos; /* Start our trek over */ } } tp->t_rest_hpt = 0; } return; } /* doctor_spell_points() A healing daemon that restors spell points */ void doctor_spell_points(struct thing *tp) { int turns_quiet, new_points; struct stats *curp; /* current stats pointer */ struct stats *maxp; /* max stats pointer */ int opower; /* current power */ curp = &(tp->t_stats); maxp = &(tp->maxstats); opower = curp->s_power; /* The right ring will let you regenerate while wearing bad armor */ if (off(*tp, CANCAST) || ((tp == &player) && (cur_armor && wear_ok(tp, cur_armor, NOMESSAGE) == FALSE) && !(is_wearing(R_WIZARD) || is_wearing(R_PIETY)))) { tp->t_rest_pow = 0; return; } tp->t_rest_pow++; switch (tp->t_ctype) { case C_MAGICIAN: case C_ILLUSION: turns_quiet = 18 - curp->s_lvl / 2; new_points = curp->s_lvl / 2; break; case C_CLERIC: case C_DRUID: turns_quiet = 24 - curp->s_lvl; new_points = curp->s_lvl / 2 - 2; break; case C_THIEF: case C_ASSASIN: case C_NINJA: turns_quiet = 32 - curp->s_lvl; new_points = curp->s_lvl / 3 - 3; break; case C_FIGHTER: case C_RANGER: case C_PALADIN: turns_quiet = 32 - curp->s_lvl; new_points = curp->s_lvl / 3 - 4; break; case C_MONSTER: turns_quiet = 24 - curp->s_lvl; new_points = curp->s_lvl - 6; break; default: return; } if (curp->s_lvl < 8) { if (tp->t_rest_pow > turns_quiet) curp->s_power++; } else if (tp->t_rest_pow >= 15) curp->s_power += rnd(new_points) + 1; if (tp == &player && (is_wearing(R_WIZARD) || is_wearing(R_PIETY))) curp->s_power += ring_value(R_WIZARD) + ring_value(R_PIETY); curp->s_power = min(max(0, curp->s_power), maxp->s_power); if (curp->s_power != opower) tp->t_rest_pow = 0; return; } /* rollwand() called to roll to see if a wandering monster starts up */ void rollwand(daemon_arg *arg) { NOOP(arg); if ((rnd(6) == 0) && (player.t_ctype != C_THIEF || (rnd(30) >= pstats.s_dext))) { wanderer(); kill_daemon(DAEMON_ROLLWAND); light_fuse(FUSE_SWANDER, 0, WANDERTIME, BEFORE); } return; } /* stomach() digest the hero's food */ void stomach(daemon_arg *arg) { int oldfood, old_hunger; int amount; int power_scale; NOOP(arg); old_hunger = hungry_state; if (food_left <= 0) { /* the hero is fainting */ if (no_command || rnd(100) > 20) return; no_command = rnd(8) + 4; running = FALSE; count = 0; hungry_state = F_FAINT; feed_me(hungry_state); } else { oldfood = food_left; amount = ring_eat(LEFT_1) + ring_eat(LEFT_2) + ring_eat(LEFT_3) + ring_eat(LEFT_4) + ring_eat(RIGHT_1) + ring_eat(RIGHT_2) + ring_eat(RIGHT_3) + ring_eat(RIGHT_4) + foodlev; if (on(player, SUPEREAT)) /* artifact or regeneration munchies */ amount *= 2; if (on(player, POWEREAT)) /* Used an artifact power */ { amount += 40; turn_off(player, POWEREAT); } power_scale = (on(player, POWERDEXT) + on(player, POWERSTR) + on(player, POWERWISDOM) + on(player, POWERINTEL) + on(player, POWERCONST) + 1); food_left -= amount * power_scale; if (food_left < MORETIME && oldfood >= MORETIME) { hungry_state = F_WEAK; running = FALSE; feed_me(hungry_state); } else if (food_left < 2 * MORETIME && oldfood >= 2 * MORETIME) { hungry_state = F_HUNGRY; running = FALSE; feed_me(hungry_state); } } if (old_hunger != hungry_state) updpack(); wghtchk(NULL); } /* runners() Make all the running monsters move. with monsters now fighting each other, this routine have been enhanced and may need more work yet */ void runners(daemon_arg *arg) { struct linked_list *item; struct thing *tp; NOOP(arg); for (item = mlist; item != NULL; item = next_mons) { curr_mons = item; next_mons = next(curr_mons); tp = THINGPTR(item); if (on(*tp, ISHELD) && rnd(tp->t_stats.s_str + tp->t_stats.s_lvl) > 10 + rnd(50)) { turn_off(*tp, ISHELD); turn_off(*tp, ISDISGUISE); turn_on(*tp, ISRUN); tp->t_ischasing = TRUE; tp->t_chasee = &player; tp->t_horde = NULL; if (tp->t_stats.s_hpt < rnd(tp->maxstats.s_hpt)) turn_on(*tp, ISFLEE); if (cansee(tp->t_pos.y, tp->t_pos.x)) msg("The %s breaks free!", monsters[tp->t_index].m_name); } if (off(*tp, ISHELD) && on(*tp, ISRUN)) { int flee = FALSE; flee = on(*tp, ISFLEE) || ( (tp->t_chasee == &player) && on(player, ISINWALL) && off(*tp, CANINWALL) && off(*tp, ISFAMILIAR) ); if (off(*tp, ISSLOW) || tp->t_turn) { daemon_arg targ; targ.thingptr = tp; doctor(&targ); do_chase(tp, flee); } if (curr_mons && (on(*tp, ISHASTE) || ((on(*tp, CANFLY) || on(*tp, ISFAST)) && DISTANCE(hero, tp->t_pos) >= 4))) { daemon_arg targ; targ.thingptr = tp; doctor(&targ); do_chase(tp, flee); } if (curr_mons) { tp->t_turn ^= TRUE; tp->t_wasshot ^= FALSE; /* Not shot anymore */ } } } curr_mons = next_mons = NULL; return; } /* swander() called when it is time to start rolling for wandering monsters */ fuse swander(fuse_arg *arg) { NOOP(arg); start_daemon(DAEMON_ROLLWAND, 0, BEFORE); return; } /* unconfuse release the poor player from his confusion */ fuse unconfuse(fuse_arg *arg) { NOOP(arg); turn_off(player, ISHUH); msg("You feel less confused now.");
