Mercurial > hg > early-roguelike
comparison urogue/daemons.c @ 256:c495a4f288c6
Import UltraRogue from the Roguelike Restoration Project (r1490)
| author | John "Elwin" Edwards |
|---|---|
| date | Tue, 31 Jan 2017 19:56:04 -0500 |
| parents | |
| children | c4b12d2d1dcd |
comparison
equal
deleted
inserted
replaced
| 253:d9badb9c0179 | 256:c495a4f288c6 |
|---|---|
| 1 /* | |
| 2 daemons.c - All the daemon and fuse functions are in here | |
| 3 | |
| 4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom | |
| 5 Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong | |
| 6 All rights reserved. | |
| 7 | |
| 8 Based on "Advanced Rogue" | |
| 9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka | |
| 10 All rights reserved. | |
| 11 | |
| 12 Based on "Rogue: Exploring the Dungeons of Doom" | |
| 13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
| 14 All rights reserved. | |
| 15 | |
| 16 See the file LICENSE.TXT for full copyright and licensing information. | |
| 17 */ | |
| 18 | |
| 19 #include "rogue.h" | |
| 20 | |
| 21 /* | |
| 22 doctor() | |
| 23 A healing daemon that restors spell and hit points after rest | |
| 24 */ | |
| 25 | |
| 26 void | |
| 27 doctor(daemon_arg *who) | |
| 28 { | |
| 29 struct thing *tp = who->thingptr; | |
| 30 long ohp; /* turn off ISFLEE? */ | |
| 31 struct stats *curp; /* current stats pointer */ | |
| 32 struct stats *maxp; /* max stats pointer */ | |
| 33 int turns_quiet, new_points; | |
| 34 | |
| 35 curp = &(tp->t_stats); | |
| 36 maxp = &(tp->maxstats); | |
| 37 | |
| 38 if (on(*tp, ISINWALL)) | |
| 39 { | |
| 40 tp->t_rest_hpt = 0; | |
| 41 return; | |
| 42 } | |
| 43 | |
| 44 /* Check for regenerating spell points first */ | |
| 45 | |
| 46 doctor_spell_points(tp); | |
| 47 | |
| 48 if (curp->s_hpt == maxp->s_hpt) | |
| 49 { | |
| 50 tp->t_rest_hpt = 0; | |
| 51 return; | |
| 52 } | |
| 53 | |
| 54 tp->t_rest_hpt++; | |
| 55 | |
| 56 switch (tp->t_ctype) | |
| 57 { | |
| 58 case C_MAGICIAN: | |
| 59 case C_ILLUSION: | |
| 60 turns_quiet = 24 - curp->s_lvl; | |
| 61 new_points = curp->s_lvl / 2 - 4; | |
| 62 break; | |
| 63 | |
| 64 case C_THIEF: | |
| 65 case C_ASSASIN: | |
| 66 case C_NINJA: | |
| 67 turns_quiet = 16 - curp->s_lvl; | |
| 68 new_points = curp->s_lvl / 2 - 1; | |
| 69 break; | |
| 70 | |
| 71 case C_CLERIC: | |
| 72 case C_DRUID: | |
| 73 turns_quiet = 16 - curp->s_lvl; | |
| 74 new_points = curp->s_lvl / 2 - 2; | |
| 75 break; | |
| 76 | |
| 77 case C_FIGHTER: | |
| 78 case C_RANGER: | |
| 79 case C_PALADIN: | |
| 80 turns_quiet = 8 - curp->s_lvl / 2; | |
| 81 new_points = curp->s_lvl / 2 - 1; | |
| 82 break; | |
| 83 | |
| 84 case C_MONSTER: | |
| 85 turns_quiet = 16 - curp->s_lvl; | |
| 86 new_points = curp->s_lvl / 2 - 6; | |
| 87 break; | |
| 88 | |
| 89 default: | |
| 90 debug("What a strange character you are!"); | |
| 91 return; | |
| 92 } | |
| 93 | |
| 94 ohp = curp->s_hpt; | |
| 95 | |
| 96 if (off(*tp, HASDISEASE)) | |
| 97 { | |
| 98 if (curp->s_lvl < 8) | |
| 99 { | |
| 100 if (tp->t_rest_hpt > turns_quiet) | |
| 101 curp->s_hpt++; | |
| 102 } | |
| 103 else if (tp->t_rest_hpt >= 15) | |
| 104 curp->s_hpt += rnd(new_points) + 1; | |
| 105 } | |
| 106 | |
| 107 if (tp == &player) | |
| 108 { | |
| 109 if (curp->s_lvl > 10) | |
| 110 turns_quiet = 2; | |
| 111 else | |
| 112 turns_quiet = rnd(turns_quiet / 6) + 1; | |
| 113 | |
| 114 if (is_wearing(R_REGEN)) | |
| 115 curp->s_hpt += ring_value(R_REGEN); | |
| 116 } | |
| 117 | |
| 118 if (on(*tp, ISREGEN)) | |
| 119 curp->s_hpt += curp->s_lvl / 5 + 1; | |
| 120 | |
| 121 if (ohp != curp->s_hpt) | |
| 122 { | |
| 123 if (curp->s_hpt >= maxp->s_hpt) | |
| 124 { | |
| 125 curp->s_hpt = maxp->s_hpt; | |
| 126 | |
| 127 if (off(*tp, WASTURNED) && on(*tp, ISFLEE) | |
| 128 && tp != &player) | |
| 129 { | |
| 130 turn_off(*tp, ISFLEE); | |
| 131 tp->t_oldpos = tp->t_pos; | |
| 132 /* Start our trek over */ | |
| 133 } | |
| 134 } | |
| 135 tp->t_rest_hpt = 0; | |
| 136 } | |
| 137 | |
| 138 return; | |
| 139 } | |
| 140 | |
| 141 | |
| 142 /* | |
| 143 doctor_spell_points() | |
| 144 A healing daemon that restors spell points | |
| 145 */ | |
| 146 | |
| 147 void | |
| 148 doctor_spell_points(struct thing *tp) | |
| 149 { | |
| 150 int turns_quiet, new_points; | |
| 151 struct stats *curp; /* current stats pointer */ | |
| 152 struct stats *maxp; /* max stats pointer */ | |
| 153 int opower; /* current power */ | |
| 154 | |
| 155 curp = &(tp->t_stats); | |
| 156 maxp = &(tp->maxstats); | |
| 157 opower = curp->s_power; | |
| 158 | |
| 159 /* The right ring will let you regenerate while wearing bad armor */ | |
| 160 | |
| 161 if (off(*tp, CANCAST) || | |
| 162 ((tp == &player) && | |
| 163 (cur_armor && wear_ok(tp, cur_armor, NOMESSAGE) == FALSE) && | |
| 164 !(is_wearing(R_WIZARD) || is_wearing(R_PIETY)))) | |
| 165 { | |
| 166 tp->t_rest_pow = 0; | |
| 167 return; | |
| 168 } | |
| 169 | |
| 170 tp->t_rest_pow++; | |
| 171 | |
| 172 switch (tp->t_ctype) | |
| 173 { | |
| 174 case C_MAGICIAN: | |
| 175 case C_ILLUSION: | |
| 176 turns_quiet = 18 - curp->s_lvl / 2; | |
| 177 new_points = curp->s_lvl / 2; | |
| 178 break; | |
| 179 case C_CLERIC: | |
| 180 case C_DRUID: | |
| 181 turns_quiet = 24 - curp->s_lvl; | |
| 182 new_points = curp->s_lvl / 2 - 2; | |
| 183 break; | |
| 184 case C_THIEF: | |
| 185 case C_ASSASIN: | |
| 186 case C_NINJA: | |
| 187 turns_quiet = 32 - curp->s_lvl; | |
| 188 new_points = curp->s_lvl / 3 - 3; | |
| 189 break; | |
| 190 case C_FIGHTER: | |
| 191 case C_RANGER: | |
| 192 case C_PALADIN: | |
| 193 turns_quiet = 32 - curp->s_lvl; | |
| 194 new_points = curp->s_lvl / 3 - 4; | |
| 195 break; | |
| 196 case C_MONSTER: | |
| 197 turns_quiet = 24 - curp->s_lvl; | |
| 198 new_points = curp->s_lvl - 6; | |
| 199 break; | |
| 200 default: | |
| 201 return; | |
| 202 } | |
| 203 | |
| 204 if (curp->s_lvl < 8) | |
| 205 { | |
| 206 if (tp->t_rest_pow > turns_quiet) | |
| 207 curp->s_power++; | |
| 208 } | |
| 209 else if (tp->t_rest_pow >= 15) | |
| 210 curp->s_power += rnd(new_points) + 1; | |
| 211 | |
| 212 if (tp == &player && (is_wearing(R_WIZARD) || is_wearing(R_PIETY))) | |
| 213 curp->s_power += ring_value(R_WIZARD) + ring_value(R_PIETY); | |
| 214 | |
| 215 curp->s_power = min(max(0, curp->s_power), maxp->s_power); | |
| 216 | |
| 217 if (curp->s_power != opower) | |
| 218 tp->t_rest_pow = 0; | |
| 219 | |
| 220 return; | |
| 221 } | |
| 222 | |
| 223 /* | |
| 224 rollwand() | |
| 225 called to roll to see if a wandering monster starts up | |
| 226 */ | |
| 227 | |
| 228 daemon | |
| 229 rollwand(daemon_arg *arg) | |
| 230 { | |
| 231 NOOP(arg); | |
| 232 | |
| 233 if ((rnd(6) == 0) && (player.t_ctype != C_THIEF || | |
| 234 (rnd(30) >= pstats.s_dext))) | |
| 235 { | |
| 236 wanderer(); | |
| 237 kill_daemon(DAEMON_ROLLWAND); | |
| 238 light_fuse(FUSE_SWANDER, 0, WANDERTIME, BEFORE); | |
| 239 } | |
| 240 | |
| 241 return; | |
| 242 } | |
| 243 | |
| 244 /* | |
| 245 stomach() | |
| 246 digest the hero's food | |
| 247 */ | |
| 248 | |
| 249 daemon | |
| 250 stomach(daemon_arg *arg) | |
| 251 { | |
| 252 int oldfood, old_hunger; | |
| 253 int amount; | |
| 254 int power_scale; | |
| 255 | |
| 256 NOOP(arg); | |
| 257 | |
| 258 old_hunger = hungry_state; | |
| 259 | |
| 260 if (food_left <= 0) | |
| 261 { | |
| 262 /* the hero is fainting */ | |
| 263 | |
| 264 if (no_command || rnd(100) > 20) | |
| 265 return; | |
| 266 | |
| 267 no_command = rnd(8) + 4; | |
| 268 running = FALSE; | |
| 269 count = 0; | |
| 270 hungry_state = F_FAINT; | |
| 271 feed_me(hungry_state); | |
| 272 } | |
| 273 else | |
| 274 { | |
| 275 oldfood = food_left; | |
| 276 | |
| 277 amount = ring_eat(LEFT_1) + ring_eat(LEFT_2) + | |
| 278 ring_eat(LEFT_3) + ring_eat(LEFT_4) + | |
| 279 ring_eat(RIGHT_1) + ring_eat(RIGHT_2) + | |
| 280 ring_eat(RIGHT_3) + ring_eat(RIGHT_4) + | |
| 281 foodlev; | |
| 282 | |
| 283 if (on(player, SUPEREAT)) /* artifact or regeneration munchies */ | |
| 284 amount *= 2; | |
| 285 | |
| 286 if (on(player, POWEREAT)) /* Used an artifact power */ | |
| 287 { | |
| 288 amount += 40; | |
| 289 turn_off(player, POWEREAT); | |
| 290 } | |
| 291 | |
| 292 power_scale = (on(player, POWERDEXT) + on(player, POWERSTR) + | |
| 293 on(player, POWERWISDOM) + on(player, POWERINTEL) + | |
| 294 on(player, POWERCONST) + 1); | |
| 295 | |
| 296 food_left -= amount * power_scale; | |
| 297 | |
| 298 if (food_left < MORETIME && oldfood >= MORETIME) | |
| 299 { | |
| 300 hungry_state = F_WEAK; | |
| 301 running = FALSE; | |
| 302 feed_me(hungry_state); | |
| 303 } | |
| 304 else if (food_left < 2 * MORETIME && oldfood >= 2 * MORETIME) | |
| 305 { | |
| 306 hungry_state = F_HUNGRY; | |
| 307 running = FALSE; | |
| 308 feed_me(hungry_state); | |
| 309 } | |
| 310 } | |
| 311 | |
| 312 if (old_hunger != hungry_state) | |
| 313 updpack(); | |
| 314 | |
| 315 wghtchk(NULL); | |
| 316 } | |
| 317 | |
| 318 | |
| 319 /* | |
| 320 runners() | |
| 321 Make all the running monsters move. with monsters now fighting | |
| 322 each other, this routine have been enhanced and may need more work yet | |
| 323 */ | |
| 324 | |
| 325 daemon | |
| 326 runners(daemon_arg *arg) | |
| 327 { | |
| 328 struct linked_list *item; | |
| 329 struct thing *tp; | |
| 330 | |
| 331 NOOP(arg); | |
| 332 | |
| 333 for (item = mlist; item != NULL; item = next_mons) | |
| 334 { | |
| 335 curr_mons = item; | |
| 336 next_mons = next(curr_mons); | |
| 337 tp = THINGPTR(item); | |
| 338 | |
| 339 if (on(*tp, ISHELD) && rnd(tp->t_stats.s_str + | |
| 340 tp->t_stats.s_lvl) > 10 + rnd(50)) | |
| 341 { | |
| 342 turn_off(*tp, ISHELD); | |
| 343 turn_off(*tp, ISDISGUISE); | |
| 344 turn_on(*tp, ISRUN); | |
| 345 tp->t_ischasing = TRUE; | |
| 346 tp->t_chasee = &player; | |
| 347 tp->t_horde = NULL; | |
| 348 | |
| 349 if (tp->t_stats.s_hpt < rnd(tp->maxstats.s_hpt)) | |
| 350 turn_on(*tp, ISFLEE); | |
| 351 | |
| 352 if (cansee(tp->t_pos.y, tp->t_pos.x)) | |
| 353 msg("The %s breaks free!", monsters[tp->t_index].m_name); | |
| 354 } | |
| 355 | |
| 356 if (off(*tp, ISHELD) && on(*tp, ISRUN)) | |
| 357 { | |
| 358 int flee = FALSE; | |
| 359 | |
| 360 flee = on(*tp, ISFLEE) || | |
| 361 ( (tp->t_chasee == &player) && | |
| 362 on(player, ISINWALL) && | |
| 363 off(*tp, CANINWALL) && off(*tp, ISFAMILIAR) ); | |
| 364 | |
| 365 if (off(*tp, ISSLOW) || tp->t_turn) | |
| 366 { | |
| 367 daemon_arg targ; | |
| 368 | |
| 369 targ.thingptr = tp; | |
| 370 doctor(&targ); | |
| 371 do_chase(tp, flee); | |
| 372 } | |
| 373 | |
| 374 if (curr_mons && (on(*tp, ISHASTE) || | |
| 375 ((on(*tp, CANFLY) || on(*tp, ISFAST)) && | |
| 376 DISTANCE(hero, tp->t_pos) >= 4))) | |
| 377 { | |
