comparison xrogue/misc.c @ 142:6b5fbd7c3ece

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