Commit | Line | Data |
---|---|---|
15637ed4 RG |
1 | /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ |
2 | /* hack.wizard.c - version 1.0.3 */ | |
3 | ||
4 | /* wizard code - inspired by rogue code from Merlyn Leroy (digi-g!brian) */ | |
5 | ||
6 | #include "hack.h" | |
7 | extern struct permonst pm_wizard; | |
8 | extern struct monst *makemon(); | |
9 | ||
10 | #define WIZSHOT 6 /* one chance in WIZSHOT that wizard will try magic */ | |
11 | #define BOLT_LIM 8 /* from this distance D and 1 will try to hit you */ | |
12 | ||
13 | char wizapp[] = "@DNPTUVXcemntx"; | |
14 | ||
15 | /* If he has found the Amulet, make the wizard appear after some time */ | |
16 | amulet(){ | |
17 | register struct obj *otmp; | |
18 | register struct monst *mtmp; | |
19 | ||
20 | if(!flags.made_amulet || !flags.no_of_wizards) | |
21 | return; | |
22 | /* find wizard, and wake him if necessary */ | |
23 | for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) | |
24 | if(mtmp->data->mlet == '1' && mtmp->msleep && !rn2(40)) | |
25 | for(otmp = invent; otmp; otmp = otmp->nobj) | |
26 | if(otmp->olet == AMULET_SYM && !otmp->spe) { | |
27 | mtmp->msleep = 0; | |
28 | if(dist(mtmp->mx,mtmp->my) > 2) | |
29 | pline( | |
30 | "You get the creepy feeling that somebody noticed your taking the Amulet." | |
31 | ); | |
32 | return; | |
33 | } | |
34 | } | |
35 | ||
36 | wiz_hit(mtmp) | |
37 | register struct monst *mtmp; | |
38 | { | |
39 | /* if we have stolen or found the amulet, we disappear */ | |
40 | if(mtmp->minvent && mtmp->minvent->olet == AMULET_SYM && | |
41 | mtmp->minvent->spe == 0) { | |
42 | /* vanish -- very primitive */ | |
43 | fall_down(mtmp); | |
44 | return(1); | |
45 | } | |
46 | ||
47 | /* if it is lying around someplace, we teleport to it */ | |
48 | if(!carrying(AMULET_OF_YENDOR)) { | |
49 | register struct obj *otmp; | |
50 | ||
51 | for(otmp = fobj; otmp; otmp = otmp->nobj) | |
52 | if(otmp->olet == AMULET_SYM && !otmp->spe) { | |
53 | if((u.ux != otmp->ox || u.uy != otmp->oy) && | |
54 | !m_at(otmp->ox, otmp->oy)) { | |
55 | ||
56 | /* teleport to it and pick it up */ | |
57 | mtmp->mx = otmp->ox; | |
58 | mtmp->my = otmp->oy; | |
59 | freeobj(otmp); | |
60 | mpickobj(mtmp, otmp); | |
61 | pmon(mtmp); | |
62 | return(0); | |
63 | } | |
64 | goto hithim; | |
65 | } | |
66 | return(0); /* we don't know where it is */ | |
67 | } | |
68 | hithim: | |
69 | if(rn2(2)) { /* hit - perhaps steal */ | |
70 | ||
71 | /* if hit 1/20 chance of stealing amulet & vanish | |
72 | - amulet is on level 26 again. */ | |
73 | if(hitu(mtmp, d(mtmp->data->damn,mtmp->data->damd)) | |
74 | && !rn2(20) && stealamulet(mtmp)) | |
75 | ; | |
76 | } | |
77 | else | |
78 | inrange(mtmp); /* try magic */ | |
79 | return(0); | |
80 | } | |
81 | ||
82 | inrange(mtmp) | |
83 | register struct monst *mtmp; | |
84 | { | |
85 | register schar tx,ty; | |
86 | ||
87 | /* do nothing if cancelled (but make '1' say something) */ | |
88 | if(mtmp->data->mlet != '1' && mtmp->mcan) | |
89 | return; | |
90 | ||
91 | /* spit fire only when both in a room or both in a corridor */ | |
92 | if(inroom(u.ux,u.uy) != inroom(mtmp->mx,mtmp->my)) return; | |
93 | tx = u.ux - mtmp->mx; | |
94 | ty = u.uy - mtmp->my; | |
95 | if((!tx && abs(ty) < BOLT_LIM) || (!ty && abs(tx) < BOLT_LIM) | |
96 | || (abs(tx) == abs(ty) && abs(tx) < BOLT_LIM)){ | |
97 | switch(mtmp->data->mlet) { | |
98 | case 'D': | |
99 | /* spit fire in the direction of @ (not nec. hitting) */ | |
100 | buzz(-1,mtmp->mx,mtmp->my,sgn(tx),sgn(ty)); | |
101 | break; | |
102 | case '1': | |
103 | if(rn2(WIZSHOT)) break; | |
104 | /* if you zapped wizard with wand of cancellation, | |
105 | he has to shake off the effects before he can throw | |
106 | spells successfully. 1/2 the time they fail anyway */ | |
107 | if(mtmp->mcan || rn2(2)) { | |
108 | if(canseemon(mtmp)) | |
109 | pline("%s makes a gesture, then curses.", | |
110 | Monnam(mtmp)); | |
111 | else | |
112 | pline("You hear mumbled cursing."); | |
113 | if(!rn2(3)) { | |
114 | mtmp->mspeed = 0; | |
115 | mtmp->minvis = 0; | |
116 | } | |
117 | if(!rn2(3)) | |
118 | mtmp->mcan = 0; | |
119 | } else { | |
120 | if(canseemon(mtmp)){ | |
121 | if(!rn2(6) && !Invis) { | |
122 | pline("%s hypnotizes you.", Monnam(mtmp)); | |
123 | nomul(rn2(3) + 3); | |
124 | break; | |
125 | } else | |
126 | pline("%s chants an incantation.", | |
127 | Monnam(mtmp)); | |
128 | } else | |
129 | pline("You hear a mumbled incantation."); | |
130 | switch(rn2(Invis ? 5 : 6)) { | |
131 | case 0: | |
132 | /* create a nasty monster from a deep level */ | |
133 | /* (for the moment, 'nasty' is not implemented) */ | |
134 | (void) makemon((struct permonst *)0, u.ux, u.uy); | |
135 | break; | |
136 | case 1: | |
137 | pline("\"Destroy the thief, my pets!\""); | |
138 | aggravate(); /* aggravate all the monsters */ | |
139 | /* fall into next case */ | |
140 | case 2: | |
141 | if (flags.no_of_wizards == 1 && rnd(5) == 0) | |
142 | /* if only 1 wizard, clone himself */ | |
143 | clonewiz(mtmp); | |
144 | break; | |
145 | case 3: | |
146 | if(mtmp->mspeed == MSLOW) | |
147 | mtmp->mspeed = 0; | |
148 | else | |
149 | mtmp->mspeed = MFAST; | |
150 | break; | |
151 | case 4: | |
152 | mtmp->minvis = 1; | |
153 | break; | |
154 | case 5: | |
155 | /* Only if not Invisible */ | |
156 | pline("You hear a clap of thunder!"); | |
157 | /* shoot a bolt of fire or cold, or a sleep ray */ | |
158 | buzz(-rnd(3),mtmp->mx,mtmp->my,sgn(tx),sgn(ty)); | |
159 | break; | |
160 | } | |
161 | } | |
162 | } | |
163 | if(u.uhp < 1) done_in_by(mtmp); | |
164 | } | |
165 | } | |
166 | ||
167 | aggravate() | |
168 | { | |
169 | register struct monst *mtmp; | |
170 | ||
171 | for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { | |
172 | mtmp->msleep = 0; | |
173 | if(mtmp->mfroz && !rn2(5)) | |
174 | mtmp->mfroz = 0; | |
175 | } | |
176 | } | |
177 | ||
178 | clonewiz(mtmp) | |
179 | register struct monst *mtmp; | |
180 | { | |
181 | register struct monst *mtmp2; | |
182 | ||
183 | if(mtmp2 = makemon(PM_WIZARD, mtmp->mx, mtmp->my)) { | |
184 | flags.no_of_wizards = 2; | |
185 | unpmon(mtmp2); | |
186 | mtmp2->mappearance = wizapp[rn2(sizeof(wizapp)-1)]; | |
187 | pmon(mtmp); | |
188 | } | |
189 | } |