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 }