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