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]);