1 /* 2 * File with various monster functions in it 3 * 4 * monsters.c 1.4 (A.I. Design) 12/14/84 5 */ 6 7 #include "rogue.h" 8 #include "curses.h" 9 10 /* 11 * List of monsters in rough order of vorpalness 12 */ 13 14 static char *lvl_mons = "K BHISOR LCA NYTWFP GMXVJD"; 15 static char *wand_mons = "KEBHISORZ CAQ YTW PUGM VJ "; 16 17 /* 18 * randmonster: 19 * Pick a monster to show up. The lower the level, 20 * the meaner the monster. 21 */ 22 randmonster(wander) 23 bool wander; 24 { 25 register int d; 26 register char *mons; 27 28 mons = wander ? wand_mons : lvl_mons; 29 do { 30 int r10 = rnd(5) + rnd(6); 31 32 d = level + (r10 - 5); 33 if (d < 1) 34 d = rnd(5) + 1; 35 if (d > 26) 36 d = rnd(5) + 22; 37 } while (mons[--d] == ' '); 38 return mons[d]; 39 } 40 41 /* 42 * new_monster: 43 * Pick a new monster and add it to the list 44 */ 45 new_monster(tp, type, cp) 46 THING *tp; 47 byte type; 48 coord *cp; 49 { 50 register struct monster *mp; 51 register int lev_add; 52 53 if ((lev_add = level - AMULETLEVEL) < 0) 54 lev_add = 0; 55 attach(mlist, tp); 56 tp->t_type = type; 57 tp->t_disguise = type; 58 bcopy(tp->t_pos,*cp); 59 tp->t_oldch = '@'; 60 tp->t_room = roomin(cp); 61 mp = &monsters[tp->t_type-'A']; 62 tp->t_stats.s_lvl = mp->m_stats.s_lvl + lev_add; 63 tp->t_stats.s_maxhp = tp->t_stats.s_hpt = roll(tp->t_stats.s_lvl, 8); 64 tp->t_stats.s_arm = mp->m_stats.s_arm - lev_add; 65 tp->t_stats.s_dmg = mp->m_stats.s_dmg; 66 tp->t_stats.s_str = mp->m_stats.s_str; 67 tp->t_stats.s_exp = mp->m_stats.s_exp + lev_add * 10 + exp_add(tp); 68 tp->t_flags = mp->m_flags; 69 tp->t_turn = TRUE; 70 tp->t_pack = NULL; 71 if (ISWEARING(R_AGGR)) 72 start_run(cp); 73 if (type == 'F') 74 tp->t_stats.s_dmg = f_damage; 75 if (type == 'X') 76 switch (rnd(level > 25 ? 9 : 8)) { 77 when 0: tp->t_disguise = GOLD; 78 when 1: tp->t_disguise = POTION; 79 when 2: tp->t_disguise = SCROLL; 80 when 3: tp->t_disguise = STAIRS; 81 when 4: tp->t_disguise = WEAPON; 82 when 5: tp->t_disguise = ARMOR; 83 when 6: tp->t_disguise = RING; 84 when 7: tp->t_disguise = STICK; 85 when 8: tp->t_disguise = AMULET; 86 } 87 } 88 89 /* 90 * f_restor(): restor initial damage string for flytraps 91 */ 92 f_restor() 93 { 94 register struct monster *mp = &monsters['F'-'A']; 95 96 fung_hit = 0; 97 strcpy(f_damage, mp->m_stats.s_dmg); 98 } 99 100 /* 101 * expadd: 102 * Experience to add for this monster's level/hit points 103 */ 104 exp_add(tp) 105 register THING *tp; 106 { 107 register int mod; 108 109 if (tp->t_stats.s_lvl == 1) 110 mod = tp->t_stats.s_maxhp / 8; 111 else 112 mod = tp->t_stats.s_maxhp / 6; 113 if (tp->t_stats.s_lvl > 9) 114 mod *= 20; 115 else if (tp->t_stats.s_lvl > 6) 116 mod *= 4; 117 return mod; 118 } 119 120 /* 121 * wanderer: 122 * Create a new wandering monster and aim it at the player 123 */ 124 wanderer() 125 { 126 int i; 127 register struct room *rp; 128 register THING *tp; 129 coord cp; 130 131 /* 132 * can we allocate a new monster 133 */ 134 if ((tp = new_item()) == NULL) 135 return; 136 do { 137 i = rnd_room(); 138 if ((rp = &rooms[i]) == proom) 139 continue; 140 rnd_pos(rp, &cp); 141 } while (!(rp != proom && step_ok(winat(cp.y, cp.x)))); 142 new_monster(tp, randmonster(TRUE), &cp); 143 #ifdef TEST 144 if (bailout && me()) 145 msg("wanderer bailout"); 146 #endif TEST 147 #ifdef WIZARD 148 if (wizard) 149 msg("started a wandering %s", monsters[tp->t_type-'A'].m_name); 150 #endif 151 start_run(&tp->t_pos); 152 } 153 154 /* 155 * wake_monster: 156 * What to do when the hero steps next to a monster 157 */ 158 THING * 159 wake_monster(y, x) 160 int y, x; 161 { 162 register THING *tp; 163 register struct room *rp; 164 register byte ch; 165 register int dst; 166 167 if ((tp = moat(y, x)) == NULL) 168 return tp; 169 ch = tp->t_type; 170 /* 171 * Every time he sees mean monster, it might start chasing him 172 */ 173 if (!on(*tp, ISRUN) && rnd(3) != 0 && on(*tp, ISMEAN) && !on(*tp, ISHELD) 174 && !ISWEARING(R_STEALTH)) 175 { 176 tp->t_dest = &hero; 177 tp->t_flags |= ISRUN; 178 } 179 if (ch == 'M' && !on(player, ISBLIND) && !on(*tp, ISFOUND) 180 && !on(*tp, ISCANC) && on(*tp, ISRUN)) 181 { 182 rp = proom; 183 dst = DISTANCE(y, x, hero.y, hero.x); 184 if ((rp != NULL && !(rp->r_flags & ISDARK)) || dst < LAMPDIST) { 185 tp->t_flags |= ISFOUND; 186 if (!save(VS_MAGIC)) { 187 if (on(player, ISHUH)) 188 lengthen(unconfuse, rnd(20) + HUHDURATION); 189 else 190 fuse(unconfuse, 0, rnd(20) + HUHDURATION); 191 player.t_flags |= ISHUH; 192 msg("the medusa's gaze has confused you"); 193 } 194 } 195 } 196 /* 197 * Let greedy ones guard gold 198 */ 199 if (on(*tp, ISGREED) && !on(*tp, ISRUN)) { 200 tp->t_flags = tp->t_flags | ISRUN; 201 if (proom->r_goldval) 202 tp->t_dest = &proom->r_gold; 203 else 204 tp->t_dest = &hero; 205 } 206 return tp; 207 } 208 209 /* 210 * give_pack: 211 * Give a pack to a monster if it deserves one 212 */ 213 give_pack(tp) 214 THING *tp; 215 { 216 /* 217 * check if we can allocate a new item 218 */ 219 if (total < MAXITEMS && rnd(100) < monsters[tp->t_type-'A'].m_carry) 220 attach(tp->t_pack, new_thing()); 221 } 222 223 /* 224 * pick_mons: 225 * Choose a sort of monster for the enemy of a vorpally enchanted weapon 226 */ 227 228 pick_mons() 229 { 230 register char *cp = lvl_mons + strlen(lvl_mons); 231 232 while (--cp >= lvl_mons && rnd(10)) 233 ; 234 if (cp < lvl_mons) 235 return 'M'; 236 return *cp; 237 } 238 239 240 /* 241 * moat(x,y) 242 * returns pointer to monster at coordinate 243 * if no monster there return NULL 244 */ 245 246 THING * 247 moat(my,mx) 248 int my, mx; 249 { 250 register THING *tp; 251 252 for (tp = mlist ; tp != NULL ; tp = next(tp)) 253 if (tp->t_pos.x == mx && tp->t_pos.y == my) 254 return(tp); 255 return(NULL); 256 } 257 ÿ