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