Mercurial > hg > early-roguelike
comparison rogue3/monsters.c @ 0:527e2150eaf0
Import Rogue 3.6 from the Roguelike Restoration Project (r1490)
| author | edwarj4 |
|---|---|
| date | Tue, 13 Oct 2009 13:33:34 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:527e2150eaf0 |
|---|---|
| 1 /* | |
| 2 * File with various monster functions in it | |
| 3 * | |
| 4 * @(#)monsters.c 3.18 (Berkeley) 6/15/81 | |
| 5 * | |
| 6 * Rogue: Exploring the Dungeons of Doom | |
| 7 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
| 8 * All rights reserved. | |
| 9 * | |
| 10 * See the file LICENSE.TXT for full copyright and licensing information. | |
| 11 */ | |
| 12 | |
| 13 #include "curses.h" | |
| 14 #include "rogue.h" | |
| 15 #include <string.h> | |
| 16 #include <ctype.h> | |
| 17 | |
| 18 /* | |
| 19 * List of monsters in rough order of vorpalness | |
| 20 */ | |
| 21 char lvl_mons[27] = "KJBSHEAOZGLCRQNYTWFIXUMVDP"; | |
| 22 char wand_mons[27] = "KJBSH AOZG CRQ Y W IXU V "; | |
| 23 | |
| 24 /* | |
| 25 * randmonster: | |
| 26 * Pick a monster to show up. The lower the level, | |
| 27 * the meaner the monster. | |
| 28 */ | |
| 29 | |
| 30 int | |
| 31 randmonster(int wander) | |
| 32 { | |
| 33 int d; | |
| 34 char *mons; | |
| 35 | |
| 36 mons = wander ? wand_mons : lvl_mons; | |
| 37 do | |
| 38 { | |
| 39 d = level + (rnd(10) - 5); | |
| 40 if (d < 1) | |
| 41 d = rnd(5) + 1; | |
| 42 if (d > 26) | |
| 43 d = rnd(5) + 22; | |
| 44 } while (mons[--d] == ' '); | |
| 45 return mons[d]; | |
| 46 } | |
| 47 | |
| 48 /* | |
| 49 * new_monster: | |
| 50 * Pick a new monster and add it to the list | |
| 51 */ | |
| 52 | |
| 53 void | |
| 54 new_monster(struct linked_list *item, int type, coord *cp) | |
| 55 { | |
| 56 struct thing *tp; | |
| 57 struct monster *mp; | |
| 58 | |
| 59 attach(mlist, item); | |
| 60 tp = (struct thing *) ldata(item); | |
| 61 tp->t_type = type; | |
| 62 tp->t_pos = *cp; | |
| 63 tp->t_oldch = mvwinch(cw, cp->y, cp->x); | |
| 64 mvwaddch(mw, cp->y, cp->x, tp->t_type); | |
| 65 mp = &monsters[tp->t_type-'A']; | |
| 66 tp->t_stats.s_hpt = roll(mp->m_stats.s_lvl, 8); | |
| 67 tp->t_stats.s_lvl = mp->m_stats.s_lvl; | |
| 68 tp->t_stats.s_arm = mp->m_stats.s_arm; | |
| 69 strcpy(tp->t_stats.s_dmg,mp->m_stats.s_dmg); | |
| 70 tp->t_stats.s_exp = mp->m_stats.s_exp; | |
| 71 tp->t_stats.s_str.st_str = 10; | |
| 72 tp->t_flags = mp->m_flags; | |
| 73 tp->t_turn = TRUE; | |
| 74 tp->t_pack = NULL; | |
| 75 if (ISWEARING(R_AGGR)) | |
| 76 runto(cp, &hero); | |
| 77 if (type == 'M') | |
| 78 { | |
| 79 int mch = 0; | |
| 80 | |
| 81 if (tp->t_pack != NULL) | |
| 82 mch = ((struct object *) ldata(tp->t_pack))->o_type; | |
| 83 else | |
| 84 switch (rnd(level > 25 ? 9 : 8)) | |
| 85 { | |
| 86 case 0: mch = GOLD; | |
| 87 when 1: mch = POTION; | |
| 88 when 2: mch = SCROLL; | |
| 89 when 3: mch = STAIRS; | |
| 90 when 4: mch = WEAPON; | |
| 91 when 5: mch = ARMOR; | |
| 92 when 6: mch = RING; | |
| 93 when 7: mch = STICK; | |
| 94 when 8: mch = AMULET; | |
| 95 } | |
| 96 tp->t_disguise = mch; | |
| 97 } | |
| 98 } | |
| 99 | |
| 100 /* | |
| 101 * wanderer: | |
| 102 * A wandering monster has awakened and is headed for the player | |
| 103 */ | |
| 104 | |
| 105 void | |
| 106 wanderer() | |
| 107 { | |
| 108 int i, ch; | |
| 109 struct room *rp, *hr = roomin(&hero); | |
| 110 struct linked_list *item; | |
| 111 struct thing *tp; | |
| 112 coord cp; | |
| 113 | |
| 114 item = new_item(sizeof *tp); | |
| 115 do | |
| 116 { | |
| 117 i = rnd_room(); | |
| 118 if ((rp = &rooms[i]) == hr) | |
| 119 continue; | |
| 120 rnd_pos(rp, &cp); | |
| 121 if ((ch = mvwinch(stdscr, cp.y, cp.x)) == ERR) | |
| 122 { | |
| 123 debug("Routine wanderer: mvwinch failed to %d,%d", cp.y, cp.x); | |
| 124 if (wizard) | |
| 125 wait_for(cw,'\n'); | |
| 126 return; | |
| 127 } | |
| 128 } until(hr != rp && step_ok(ch)); | |
| 129 new_monster(item, randmonster(TRUE), &cp); | |
| 130 tp = (struct thing *) ldata(item); | |
| 131 tp->t_flags |= ISRUN; | |
| 132 tp->t_pos = cp; | |
| 133 tp->t_dest = &hero; | |
| 134 if (wizard) | |
| 135 msg("Started a wandering %s", monsters[tp->t_type-'A'].m_name); | |
| 136 } | |
| 137 | |
| 138 /* | |
| 139 * what to do when the hero steps next to a monster | |
| 140 */ | |
| 141 struct linked_list * | |
| 142 wake_monster(int y, int x) | |
| 143 { | |
| 144 struct thing *tp; | |
| 145 struct linked_list *it; | |
| 146 struct room *rp; | |
| 147 int ch; | |
| 148 | |
| 149 if ((it = find_mons(y, x)) == NULL) | |
| 150 { | |
| 151 fatal("Can't find monster in wake"); | |
| 152 return NULL; | |
| 153 } | |
| 154 | |
| 155 tp = (struct thing *) ldata(it); | |
| 156 ch = tp->t_type; | |
| 157 /* | |
| 158 * Every time he sees mean monster, it might start chasing him | |
| 159 */ | |
| 160 if (rnd(100) > 33 && on(*tp, ISMEAN) && off(*tp, ISHELD) | |
| 161 && !ISWEARING(R_STEALTH)) | |
| 162 { | |
| 163 tp->t_dest = &hero; | |
| 164 tp->t_flags |= ISRUN; | |
| 165 } | |
| 166 if (ch == 'U' && off(player, ISBLIND)) | |
| 167 { | |
| 168 rp = roomin(&hero); | |
| 169 if ((rp != NULL && !(rp->r_flags&ISDARK)) | |
| 170 || DISTANCE(y, x, hero.y, hero.x) < 3) | |
| 171 { | |
| 172 if (off(*tp, ISFOUND) && !save(VS_MAGIC)) | |
| 173 { | |
| 174 msg("The umber hulk's gaze has confused you."); | |
| 175 if (on(player, ISHUH)) | |
| 176 lengthen(unconfuse, rnd(20)+HUHDURATION); | |
| 177 else | |
| 178 fuse(unconfuse, 0, rnd(20)+HUHDURATION, AFTER); | |
| 179 player.t_flags |= ISHUH; | |
| 180 } | |
| 181 tp->t_flags |= ISFOUND; | |
| 182 } | |
| 183 } | |
| 184 /* | |
| 185 * Hide invisible monsters | |
| 186 */ | |
| 187 if (on(*tp, ISINVIS) && off(player, CANSEE)) | |
| 188 ch = mvwinch(stdscr, y, x); | |
| 189 /* | |
| 190 * Let greedy ones guard gold | |
| 191 */ | |
| 192 if (on(*tp, ISGREED) && off(*tp, ISRUN)) | |
| 193 { | |
| 194 rp = roomin(&hero); | |
| 195 | |
| 196 if (rp != NULL && rp->r_goldval) | |
| 197 { | |
| 198 tp->t_dest = &rp->r_gold; | |
| 199 tp->t_flags |= ISRUN; | |
| 200 } | |
| 201 } | |
| 202 | |
| 203 return it; | |
| 204 } | |
| 205 | |
| 206 void | |
| 207 genocide() | |
| 208 { | |
| 209 struct linked_list *ip; | |
| 210 struct thing *mp; | |
| 211 int c; | |
| 212 int i; | |
| 213 struct linked_list *nip; | |
| 214 | |
| 215 addmsg("Which monster"); | |
| 216 if (!terse) | |
| 217 addmsg(" do you wish to wipe out"); | |
| 218 msg("? "); | |
| 219 while (!isalpha(c = readchar(cw))) | |
| 220 if (c == ESCAPE) | |
| 221 return; | |
| 222 else | |
| 223 { | |
| 224 mpos = 0; | |
| 225 msg("Please specify a letter between 'A' and 'Z'"); | |
| 226 } | |
| 227 if (islower(c)) | |
| 228 c = toupper(c); | |
| 229 for (ip = mlist; ip; ip = nip) | |
| 230 { | |
| 231 mp = (struct thing *) ldata(ip); | |
| 232 nip = next(ip); | |
| 233 if (mp->t_type == c) | |
| 234 remove_monster(&mp->t_pos, ip); | |
| 235 } | |
| 236 for (i = 0; i < 26; i++) | |
| 237 if (lvl_mons[i] == c) | |
| 238 { | |
| 239 lvl_mons[i] = ' '; | |
| 240 wand_mons[i] = ' '; | |
| 241 break; | |
| 242 } | |
| 243 } |
