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 {