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 } 190