Mercurial > hg > early-roguelike
comparison arogue7/misc.c @ 125:adfa37e67084
Import Advanced Rogue 7.7 from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Fri, 08 May 2015 15:24:40 -0400 |
parents | |
children | b786053d2f37 |
comparison
equal
deleted
inserted
replaced
124:d10fc4a065ac | 125:adfa37e67084 |
---|---|
1 /* | |
2 * misc.c - routines dealing specifically with miscellaneous magic | |
3 * | |
4 * Advanced Rogue | |
5 * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T | |
6 * All rights reserved. | |
7 * | |
8 * Based on "Rogue: Exploring the Dungeons of Doom" | |
9 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
10 * All rights reserved. | |
11 * | |
12 * See the file LICENSE.TXT for full copyright and licensing information. | |
13 */ | |
14 | |
15 #include "curses.h" | |
16 #include <ctype.h> | |
17 #include "rogue.h" | |
18 #ifdef PC7300 | |
19 #include "menu.h" | |
20 #endif | |
21 | |
22 /* | |
23 * routines dealing specifically with miscellaneous magic | |
24 */ | |
25 | |
26 /* | |
27 * changeclass: | |
28 * Change the player's class to the specified one. | |
29 */ | |
30 | |
31 changeclass(newclass) | |
32 int newclass; | |
33 { | |
34 if (newclass == player.t_ctype) { | |
35 msg("You feel more skillful."); | |
36 raise_level(); | |
37 } | |
38 else { | |
39 /* | |
40 * reset his class and then use check_level to reset hit | |
41 * points and the right level for his exp pts | |
42 * drop exp pts by 10% | |
43 */ | |
44 long save; | |
45 | |
46 msg("You feel like a whole new person!"); | |
47 | |
48 /* | |
49 * if he becomes a thief he has to have leather armor | |
50 */ | |
51 if ((newclass == C_THIEF || newclass == C_ASSASIN) && | |
52 cur_armor != NULL && | |
53 cur_armor->o_which != LEATHER && | |
54 cur_armor->o_which != STUDDED_LEATHER ) | |
55 cur_armor->o_which = STUDDED_LEATHER; | |
56 /* | |
57 * if he becomes a monk he can't wear armor | |
58 */ | |
59 if (newclass == C_MONK && cur_armor != NULL) { | |
60 cur_armor->o_ac = armors[cur_armor->o_which].a_class - | |
61 cur_armor->o_ac; | |
62 cur_armor->o_type = MM; | |
63 cur_armor->o_which = MM_PROTECT; | |
64 cur_armor->o_flags &= ~(ISPROT | ISKNOW | ISMETAL); | |
65 cur_misc[WEAR_CLOAK] = cur_armor; | |
66 cur_armor = NULL; | |
67 } | |
68 /* | |
69 * if he used to be a spell caster of some sort, kill the fuse | |
70 */ | |
71 if (player.t_ctype == C_MAGICIAN || player.t_ctype == C_RANGER) | |
72 extinguish(spell_recovery); | |
73 if (player.t_ctype == C_DRUID || player.t_ctype == C_RANGER) | |
74 extinguish(chant_recovery); | |
75 if ((player.t_ctype == C_CLERIC || player.t_ctype == C_PALADIN) && | |
76 !cur_relic[HEIL_ANKH]) | |
77 extinguish(prayer_recovery); | |
78 /* | |
79 * if he becomes a spell caster of some kind, give him a fuse | |
80 */ | |
81 if (newclass == C_MAGICIAN || newclass == C_RANGER) | |
82 fuse(spell_recovery, 0, SPELLTIME, AFTER); | |
83 if (newclass == C_DRUID || newclass == C_RANGER) | |
84 fuse(chant_recovery, 0, SPELLTIME, AFTER); | |
85 if ((newclass==C_CLERIC || newclass==C_PALADIN) && !cur_misc[HEIL_ANKH]) | |
86 fuse(prayer_recovery, 0, SPELLTIME, AFTER); | |
87 /* | |
88 * if he's changing from a fighter then may have to change | |
89 * his sword since only fighter can use two-handed | |
90 * and bastard swords | |
91 */ | |
92 if ((player.t_ctype == C_FIGHTER || | |
93 player.t_ctype == C_RANGER || | |
94 player.t_ctype == C_PALADIN) && | |
95 cur_weapon != NULL && | |
96 cur_weapon->o_type == WEAPON && | |
97 (cur_weapon->o_which== BASWORD || | |
98 cur_weapon->o_which== TWOSWORD ) && | |
99 !(newclass == C_FIGHTER || | |
100 newclass == C_RANGER || | |
101 newclass == C_PALADIN) && | |
102 !(newclass == C_ASSASIN && | |
103 cur_weapon->o_which == BASWORD)) | |
104 cur_weapon->o_which = SWORD; | |
105 | |
106 /* | |
107 * if he was a thief then take out the trap_look() daemon | |
108 */ | |
109 if (player.t_ctype == C_THIEF || | |
110 player.t_ctype == C_MONK || | |
111 player.t_ctype == C_ASSASIN) | |
112 kill_daemon(trap_look); | |
113 | |
114 /* | |
115 * if he becomes a thief then add the trap_look() daemon | |
116 */ | |
117 if (newclass == C_THIEF || newclass == C_ASSASIN || newclass == C_MONK) | |
118 daemon(trap_look, 0, AFTER); | |
119 char_type = player.t_ctype = newclass; | |
120 save = pstats.s_hpt; | |
121 max_stats.s_hpt = pstats.s_hpt = 0; | |
122 max_stats.s_lvl = pstats.s_lvl = 0; | |
123 max_stats.s_lvladj = pstats.s_lvladj = 0; | |
124 max_stats.s_exp = pstats.s_exp -= pstats.s_exp/10; | |
125 check_level(); | |
126 if (pstats.s_hpt > save) /* don't add to current hits */ | |
127 pstats.s_hpt = save; | |
128 } | |
129 } | |
130 | |
131 /* | |
132 * Use the relic that our monster is wielding. | |
133 */ | |
134 m_use_relic(monster) | |
135 register struct thing *monster; | |
136 { | |
137 register struct object *obj; | |
138 | |
139 /* Make sure we really have it */ | |
140 if (monster->t_using) obj = OBJPTR(monster->t_using); | |
141 else { | |
142 debug("Relic not set!"); | |
143 monster->t_action = A_NIL; | |
144 return; | |
145 } | |
146 | |
147 /* Now let's see what we're using */ | |
148 if (obj->o_type == RELIC) switch (obj->o_which) { | |
149 case MING_STAFF: { | |
150 static struct object missile = { | |
151 MISSILE, {0,0}, "", 0, "", "0d4 " , NULL, 0, WS_MISSILE, 100, 1 | |
152 }; | |
153 | |
154 debug("Firing Ming's staff"); | |
155 sprintf(missile.o_hurldmg, "%dd4", monster->t_stats.s_lvl); | |
156 do_motion(&missile, | |
157 monster->t_newpos.y, monster->t_newpos.x, monster); | |
158 hit_monster(unc(missile.o_pos), &missile, monster); | |
159 monster->t_artifact = monster->t_artifact * 4 / 5; | |
160 } | |
161 when EMORI_CLOAK: | |
162 debug("stunning with Emori's cloak"); | |
163 do_zap(monster, obj, &monster->t_newpos, WS_PARALYZE, NULL); | |
164 obj->o_charges = 0; | |
165 | |
166 when ASMO_ROD: { | |
167 char *name; | |
168 | |
169 switch (rnd(3)) { /* Select a function */ | |
170 case 0: name = "lightning bolt"; | |
171 when 1: name = "flame"; | |
172 otherwise: name = "ice"; | |
173 } | |
174 shoot_bolt( monster, | |
175 monster->t_pos, | |
176 monster->t_newpos, | |
177 FALSE, | |
178 monster->t_index, | |
179 name, | |
180 roll(monster->t_stats.s_lvl,6)); | |
181 monster->t_artifact /= 2; | |
182 } | |
183 when BRIAN_MANDOLIN: | |
184 /* Make sure the defendant is still around */ | |
185 if (DISTANCE(monster->t_pos.y, monster->t_pos.x, | |
186 hero.y, hero.x) < 25) { | |
187 if (!save(VS_MAGIC, &player, -4) && | |
188 !ISWEARING(R_ALERT)) { | |
189 msg("Some beautiful music enthralls you."); | |
190 player.t_no_move += movement(&player) * FREEZETIME; | |
191 player.t_action = A_FREEZE; | |
192 monster->t_artifact = monster->t_artifact * 2 / 3; | |
193 } | |
194 else { | |
195 msg("You wince at a sour note."); | |
196 monster->t_artifact /= 3; | |
197 } | |
198 } | |
199 when GERYON_HORN: | |
200 /* Make sure the defendant is still around */ | |
201 if (DISTANCE(monster->t_pos.y, monster->t_pos.x, | |
202 hero.y, hero.x) < 25) { | |
203 if (!ISWEARING(R_HEROISM) && | |
204 !save(VS_MAGIC, &player, -4)) { | |
205 turn_on(player, ISFLEE); | |
206 player.t_dest = &monster->t_pos; | |
207 msg("A shrill blast terrifies you."); | |
208 monster->t_artifact = monster->t_artifact * 3 / 4; | |
209 } | |
210 else { | |
211 msg("A shrill blast sends chills up your spine."); | |
212 monster->t_artifact /= 3; | |
213 } | |
214 } | |
215 | |
216 otherwise: | |
217 /* Unknown RELIC! */ | |
218 debug("Unknown wielded relic %d", obj->o_which); | |
219 } | |
220 else debug("Declared relic is %d", obj->o_type); | |
221 | |
222 turn_off(*monster, CANSURPRISE); | |
223 /* Reset the monsters actions */ | |
224 monster->t_action = A_NIL; | |
225 monster->t_using = NULL; | |
226 } | |
227 | |
228 /* | |
229 * add something to the contents of something else | |
230 */ | |
231 put_contents(bag, item) | |
232 register struct object *bag; /* the holder of the items */ | |
233 register struct linked_list *item; /* the item to put inside */ | |
234 { | |
235 register struct linked_list *titem; | |
236 register struct object *tobj; | |
237 | |
238 bag->o_ac++; | |
239 tobj = OBJPTR(item); | |
240 for (titem = bag->contents; titem != NULL; titem = next(titem)) { | |
241 if ((OBJPTR(titem))->o_which == tobj->o_which) | |
242 break; | |
243 } | |
244 if (titem == NULL) { /* if not a duplicate put at beginning */ | |
245 attach(bag->contents, item); | |
246 } | |
247 else { | |
248 item->l_prev = titem; | |
249 item->l_next = titem->l_next; | |
250 if (next(titem) != NULL) | |
251 (titem->l_next)->l_prev = item; | |
252 titem->l_next = item; | |
253 } | |
254 } | |
255 | |
256 /* | |
257 * remove something from something else | |
258 */ | |
259 take_contents(bag, item) | |
260 register struct object *bag; /* the holder of the items */ | |
261 register struct linked_list *item; | |
262 { | |
263 | |
264 if (bag->o_ac <= 0) { | |
265 msg("Nothing to take out"); | |
266 return; | |
267 } | |
268 bag->o_ac--; | |
269 detach(bag->contents, item); | |
270 if (!add_pack(item, FALSE, NULL)) | |
271 put_contents(bag, item); | |
272 } | |
273 | |
274 | |
275 do_bag(item) | |
276 register struct linked_list *item; | |
277 { | |
278 | |
279 register struct linked_list *titem; | |
280 register struct object *obj, *tobj; | |
281 bool doit = TRUE; | |
282 | |
283 obj = OBJPTR(item); | |
284 while (doit) { | |
285 msg("What do you want to do? (* for a list): "); | |
286 mpos = 0; | |
287 switch (readchar()) { | |
288 case EOF: | |
289 case ESCAPE: | |
290 msg (""); | |
291 doit = FALSE; | |
292 when '1': | |
293 inventory(obj->contents, ALL); | |
294 | |
295 when '2': | |
296 if (obj->o_ac >= MAXCONTENTS) { | |
297 msg("the %s is full", m_magic[obj->o_which].mi_name); | |
298 break; | |
299 } | |
300 switch (obj->o_which) { | |
301 case MM_BEAKER: | |
302 titem = get_item(pack, "put in", POTION, FALSE, FALSE); | |
303 when MM_BOOK: | |
304 titem = get_item(pack, "put in", SCROLL, FALSE, FALSE); | |
305 } | |
306 if (titem == NULL) | |
307 break; | |
308 detach(pack, titem); | |
309 inpack--; | |
310 put_contents(obj, titem); | |
311 | |
312 when '3': | |
313 titem = get_item(obj->contents,"take out",ALL,FALSE,FALSE); | |
314 if (titem == NULL) | |
315 break; | |
316 take_contents(obj, titem); | |
317 | |
318 when '4': | |
319 switch (obj->o_which) { | |
320 case MM_BEAKER: | |
321 titem = get_item(obj->contents,"quaff",ALL,FALSE,FALSE); | |
322 if (titem == NULL) | |
323 break; | |
324 tobj = OBJPTR(titem); | |
325 obj->o_ac--; | |
326 detach(obj->contents, titem); | |
327 quaff(tobj->o_which, | |
328 tobj->o_kind, | |
329 tobj->o_flags, | |
330 TRUE); | |
331 if (p_know[tobj->o_which] && p_guess[tobj->o_which]) | |
332 { | |
333 free(p_guess[tobj->o_which]); | |
334 p_guess[tobj->o_which] = NULL; | |
335 } | |
336 else if (!p_know[tobj->o_which] && | |
337 askme && | |
338 (tobj->o_flags & ISKNOW) == 0 && | |
339 (tobj->o_flags & ISPOST) == 0 && | |
340 p_guess[tobj->o_which] == NULL) { | |
341 nameitem(titem, FALSE); | |
342 } | |
343 o_discard(titem); | |
344 when MM_BOOK: | |
345 if (on(player, ISBLIND)) { | |
346 msg("You can't see to read anything"); | |
347 break; | |
348 } | |
349 titem = get_item(obj->contents,"read",ALL,FALSE,FALSE); | |
350 if (titem == NULL) | |
351 break; | |
352 tobj = OBJPTR(titem); | |
353 obj->o_ac--; | |
354 detach(obj->contents, titem); | |
355 read_scroll(tobj->o_which, | |
356 tobj->o_flags & (ISCURSED|ISBLESSED), | |
357 TRUE); | |
358 if (s_know[tobj->o_which] && s_guess[tobj->o_which]) | |
359 { | |
360 free(s_guess[tobj->o_which]); | |
361 s_guess[tobj->o_which] = NULL; | |
362 } | |
363 else if (!s_know[tobj->o_which] && | |
364 askme && | |
365 (tobj->o_flags & ISKNOW) == 0 && | |
366 (tobj->o_flags & ISPOST) == 0 && | |
367 s_guess[tobj->o_which] == NULL) { | |
368 nameitem(titem, FALSE); | |
369 } | |