Mercurial > hg > early-roguelike
comparison rogue5/weapons.c @ 33:f502bf60e6e4
Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
| author | elwin |
|---|---|
| date | Mon, 24 May 2010 20:10:59 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 32:2dcd75e6a736 | 33:f502bf60e6e4 |
|---|---|
| 1 /* | |
| 2 * Functions for dealing with problems brought about by weapons | |
| 3 * | |
| 4 * @(#)weapons.c 4.34 (Berkeley) 02/05/99 | |
| 5 * | |
| 6 * Rogue: Exploring the Dungeons of Doom | |
| 7 * Copyright (C) 1980-1983, 1985, 1999 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 <string.h> | |
| 15 #include <ctype.h> | |
| 16 #include "rogue.h" | |
| 17 | |
| 18 #define NO_WEAPON -1 | |
| 19 | |
| 20 static const struct init_weaps { | |
| 21 char *iw_dam; /* Damage when wielded */ | |
| 22 char *iw_hrl; /* Damage when thrown */ | |
| 23 int iw_launch; /* Launching weapon */ | |
| 24 int iw_flags; /* Miscellaneous flags */ | |
| 25 } init_dam[MAXWEAPONS] = { | |
| 26 { "2x4", "1x3", NO_WEAPON, 0, }, /* Mace */ | |
| 27 { "3x4", "1x2", NO_WEAPON, 0, }, /* Long sword */ | |
| 28 { "1x1", "1x1", NO_WEAPON, 0, }, /* Bow */ | |
| 29 { "1x1", "2x3", BOW, ISMANY|ISMISL, }, /* Arrow */ | |
| 30 { "1x6", "1x4", NO_WEAPON, ISMISL|ISMISL, }, /* Dagger */ | |
| 31 { "4x4", "1x2", NO_WEAPON, 0, }, /* 2h sword */ | |
| 32 { "1x1", "1x3", NO_WEAPON, ISMANY|ISMISL, }, /* Dart */ | |
| 33 { "1x2", "2x4", NO_WEAPON, ISMANY|ISMISL, }, /* Shuriken */ | |
| 34 { "2x3", "1x6", NO_WEAPON, ISMISL, }, /* Spear */ | |
| 35 }; | |
| 36 | |
| 37 /* | |
| 38 * missile: | |
| 39 * Fire a missile in a given direction | |
| 40 */ | |
| 41 | |
| 42 void | |
| 43 missile(int ydelta, int xdelta) | |
| 44 { | |
| 45 THING *obj; | |
| 46 | |
| 47 /* | |
| 48 * Get which thing we are hurling | |
| 49 */ | |
| 50 if ((obj = get_item("throw", WEAPON)) == NULL) | |
| 51 return; | |
| 52 if (!dropcheck(obj) || is_current(obj)) | |
| 53 return; | |
| 54 obj = leave_pack(obj, TRUE, FALSE); | |
| 55 do_motion(obj, ydelta, xdelta); | |
| 56 /* | |
| 57 * AHA! Here it has hit something. If it is a wall or a door, | |
| 58 * or if it misses (combat) the monster, put it on the floor | |
| 59 */ | |
| 60 if (moat(obj->o_pos.y, obj->o_pos.x) == NULL || | |
| 61 !hit_monster(unc(obj->o_pos), obj)) | |
| 62 fall(obj, TRUE); | |
| 63 } | |
| 64 | |
| 65 /* | |
| 66 * do_motion: | |
| 67 * Do the actual motion on the screen done by an object traveling | |
| 68 * across the room | |
| 69 */ | |
| 70 | |
| 71 void | |
| 72 do_motion(THING *obj, int ydelta, int xdelta) | |
| 73 { | |
| 74 int ch; | |
| 75 | |
| 76 /* | |
| 77 * Come fly with us ... | |
| 78 */ | |
| 79 obj->o_pos = hero; | |
| 80 for (;;) | |
| 81 { | |
| 82 /* | |
| 83 * Erase the old one | |
| 84 */ | |
| 85 if (!ce(obj->o_pos, hero) && cansee(unc(obj->o_pos)) && !terse) | |
| 86 { | |
| 87 ch = chat(obj->o_pos.y, obj->o_pos.x); | |
| 88 if (ch == FLOOR && !show_floor()) | |
| 89 ch = ' '; | |
| 90 mvaddch(obj->o_pos.y, obj->o_pos.x, ch); | |
| 91 } | |
| 92 /* | |
| 93 * Get the new position | |
| 94 */ | |
| 95 obj->o_pos.y += ydelta; | |
| 96 obj->o_pos.x += xdelta; | |
| 97 if (step_ok(ch = winat(obj->o_pos.y, obj->o_pos.x)) && ch != DOOR) | |
| 98 { | |
| 99 /* | |
| 100 * It hasn't hit anything yet, so display it | |
| 101 * If it alright. | |
| 102 */ | |
| 103 if (cansee(unc(obj->o_pos)) && !terse) | |
| 104 { | |
| 105 mvaddch(obj->o_pos.y, obj->o_pos.x, obj->o_type); | |
| 106 refresh(); | |
| 107 } | |
| 108 continue; | |
| 109 } | |
| 110 break; | |
| 111 } | |
| 112 } | |
| 113 | |
| 114 /* | |
| 115 * fall: | |
| 116 * Drop an item someplace around here. | |
| 117 */ | |
| 118 | |
| 119 void | |
| 120 fall(THING *obj, int pr) | |
| 121 { | |
| 122 PLACE *pp; | |
| 123 coord fpos; | |
| 124 | |
| 125 if (fallpos(&obj->o_pos, &fpos)) | |
| 126 { | |
| 127 pp = INDEX(fpos.y, fpos.x); | |
| 128 pp->p_ch = obj->o_type; | |
| 129 obj->o_pos = fpos; | |
| 130 if (cansee(fpos.y, fpos.x)) | |
| 131 { | |
| 132 if (pp->p_monst != NULL) | |
| 133 pp->p_monst->t_oldch = obj->o_type; | |
| 134 else | |
| 135 mvaddch(fpos.y, fpos.x, obj->o_type); | |
| 136 } | |
| 137 attach(lvl_obj, obj); | |
| 138 return; | |
| 139 } | |
| 140 if (pr) | |
| 141 { | |
| 142 if (has_hit) | |
| 143 { | |
| 144 endmsg(); | |
| 145 has_hit = FALSE; | |
| 146 } | |
| 147 msg("the %s vanishes as it hits the ground", | |
| 148 weap_info[obj->o_which].oi_name); | |
| 149 } | |
| 150 discard(obj); | |
| 151 } | |
| 152 | |
| 153 /* | |
| 154 * init_weapon: | |
| 155 * Set up the initial goodies for a weapon | |
| 156 */ | |
| 157 | |
| 158 void | |
| 159 init_weapon(THING *weap, int which) | |
| 160 { | |
| 161 const struct init_weaps *iwp; | |
| 162 | |
| 163 weap->o_type = WEAPON; | |
| 164 weap->o_which = which; | |
| 165 iwp = &init_dam[which]; | |
| 166 strncpy(weap->o_damage, iwp->iw_dam, sizeof(weap->o_damage)); | |
| 167 strncpy(weap->o_hurldmg,iwp->iw_hrl, sizeof(weap->o_hurldmg)); | |
| 168 weap->o_launch = iwp->iw_launch; | |
| 169 weap->o_flags = iwp->iw_flags; | |
| 170 weap->o_hplus = 0; | |
| 171 weap->o_dplus = 0; | |
| 172 if (which == DAGGER) | |
| 173 { | |
| 174 weap->o_count = rnd(4) + 2; | |
| 175 weap->o_group = group++; | |
| 176 } | |
| 177 else if (weap->o_flags & ISMANY) | |
| 178 { | |
| 179 weap->o_count = rnd(8) + 8; | |
| 180 weap->o_group = group++; | |
| 181 } | |
| 182 else | |
| 183 { | |
| 184 weap->o_count = 1; | |
| 185 weap->o_group = 0; | |
| 186 } | |
| 187 } | |
| 188 | |
| 189 /* | |
| 190 * hit_monster: | |
| 191 * Does the missile hit the monster? | |
| 192 */ | |
| 193 int | |
| 194 hit_monster(int y, int x, const THING *obj) | |
| 195 { | |
| 196 coord mp; | |
| 197 | |
| 198 mp.y = y; | |
| 199 mp.x = x; | |
| 200 return fight(&mp, obj, TRUE); | |
| 201 } | |
| 202 | |
| 203 /* | |
| 204 * num: | |
| 205 * Figure out the plus number for armor/weapons | |
| 206 */ | |
| 207 const char * | |
| 208 num(int n1, int n2, int type) | |
| 209 { | |
| 210 static char numbuf[10]; | |
| 211 | |
| 212 sprintf(numbuf, n1 < 0 ? "%d" : "+%d", n1); | |
| 213 if (type == WEAPON) | |
| 214 sprintf(&numbuf[strlen(numbuf)], n2 < 0 ? ",%d" : ",+%d", n2); | |
| 215 return numbuf; | |
| 216 } | |
| 217 | |
| 218 /* | |
| 219 * wield: | |
| 220 * Pull out a certain weapon | |
| 221 */ | |
| 222 | |
| 223 void | |
| 224 wield(void) | |
| 225 { | |
| 226 THING *obj, *oweapon; | |
| 227 char *sp; | |
| 228 | |
| 229 oweapon = cur_weapon; | |
| 230 if (!dropcheck(cur_weapon)) | |
| 231 { | |
| 232 cur_weapon = oweapon; | |
| 233 return; | |
| 234 } | |
| 235 cur_weapon = oweapon; | |
| 236 if ((obj = get_item("wield", WEAPON)) == NULL) | |
| 237 { | |
| 238 bad: | |
| 239 after = FALSE; | |
| 240 return; | |
| 241 } | |
| 242 | |
| 243 if (obj->o_type == ARMOR) | |
| 244 { | |
| 245 msg("you can't wield armor"); | |
| 246 goto bad; | |
| 247 } | |
| 248 if (is_current(obj)) | |
| 249 goto bad; | |
| 250 | |
| 251 sp = inv_name(obj, TRUE); | |
| 252 cur_weapon = obj; | |
| 253 if (!terse) | |
| 254 addmsg("you are now "); | |
| 255 msg("wielding %s (%c)", sp, obj->o_packch); | |
| 256 } | |
| 257 | |
| 258 /* | |
| 259 * fallpos: | |
| 260 * Pick a random position around the give (y, x) coordinates | |
| 261 */ | |
| 262 int | |
| 263 fallpos(const coord *pos, coord *newpos) | |
| 264 { | |
| 265 int y, x, cnt, ch; | |
| 266 | |
| 267 cnt = 0; | |
| 268 for (y = pos->y - 1; y <= pos->y + 1; y++) | |
| 269 for (x = pos->x - 1; x <= pos->x + 1; x++) | |
| 270 { | |
| 271 /* | |
| 272 * check to make certain the spot is empty, if it is, | |
| 273 * put the object there, set it in the level list | |
| 274 * and re-draw the room if he can see it | |
| 275 */ | |
| 276 if (y == hero.y && x == hero.x) | |
| 277 continue; | |
| 278 if (((ch = chat(y, x)) == FLOOR || ch == PASSAGE) | |
| 279 && rnd(++cnt) == 0) | |
| 280 { | |
| 281 newpos->y = y; | |
| 282 newpos->x = x; | |
| 283 } | |
| 284 } | |
| 285 return (cnt != 0); | |
| 286 } |
