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 { | |