Mercurial > hg > early-roguelike
comparison rogue3/weapons.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 | 84651832f967 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:527e2150eaf0 |
|---|---|
| 1 /* | |
| 2 * Functions for dealing with problems brought about by weapons | |
| 3 * | |
| 4 * @(#)weapons.c 3.17 (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 <ctype.h> | |
| 15 #include <string.h> | |
| 16 #include "rogue.h" | |
| 17 | |
| 18 #define NONE 100 | |
| 19 | |
| 20 char *w_names[MAXWEAPONS] = { | |
| 21 "mace", | |
| 22 "long sword", | |
| 23 "int bow", | |
| 24 "arrow", | |
| 25 "dagger", | |
| 26 "rock", | |
| 27 "two handed sword", | |
| 28 "sling", | |
| 29 "dart", | |
| 30 "crossbow", | |
| 31 "crossbow bolt", | |
| 32 "spear", | |
| 33 }; | |
| 34 | |
| 35 static struct init_weps { | |
| 36 char *iw_dam; | |
| 37 char *iw_hrl; | |
| 38 int iw_launch; | |
| 39 int iw_flags; | |
| 40 } init_dam[MAXWEAPONS] = { | |
| 41 "2d4", "1d3", NONE, 0, /* Mace */ | |
| 42 "1d10", "1d2", NONE,0, /* Long sword */ | |
| 43 "1d1", "1d1", NONE, 0, /* Bow */ | |
| 44 "1d1", "1d6", BOW, ISMANY|ISMISL, /* Arrow */ | |
| 45 "1d6", "1d4", NONE, ISMISL, /* Dagger */ | |
| 46 "1d2", "1d4", SLING,ISMANY|ISMISL, /* Rock */ | |
| 47 "3d6", "1d2", NONE, 0, /* 2h sword */ | |
| 48 "0d0", "0d0", NONE, 0, /* Sling */ | |
| 49 "1d1", "1d3", NONE, ISMANY|ISMISL, /* Dart */ | |
| 50 "1d1", "1d1", NONE, 0, /* Crossbow */ | |
| 51 "1d2", "1d10", CROSSBOW, ISMANY|ISMISL,/* Crossbow bolt */ | |
| 52 "1d8", "1d6", NONE, ISMISL, /* Spear */ | |
| 53 }; | |
| 54 | |
| 55 /* | |
| 56 * missile: | |
| 57 * Fire a missile in a given direction | |
| 58 */ | |
| 59 | |
| 60 void | |
| 61 missile(int ydelta, int xdelta) | |
| 62 { | |
| 63 struct object *obj; | |
| 64 struct linked_list *item, *nitem; | |
| 65 | |
| 66 /* | |
| 67 * Get which thing we are hurling | |
| 68 */ | |
| 69 if ((item = get_item("throw", WEAPON)) == NULL) | |
| 70 return; | |
| 71 obj = (struct object *) ldata(item); | |
| 72 if (!dropcheck(obj) || is_current(obj)) | |
| 73 return; | |
| 74 /* | |
| 75 * Get rid of the thing. If it is a non-multiple item object, or | |
| 76 * if it is the last thing, just drop it. Otherwise, create a new | |
| 77 * item with a count of one. | |
| 78 */ | |
| 79 if (obj->o_count < 2) | |
| 80 { | |
| 81 detach(pack, item); | |
| 82 inpack--; | |
| 83 } | |
| 84 else | |
| 85 { | |
| 86 obj->o_count--; | |
| 87 if (obj->o_group == 0) | |
| 88 inpack--; | |
| 89 nitem = (struct linked_list *) new_item(sizeof *obj); | |
| 90 obj = (struct object *) ldata(nitem); | |
| 91 *obj = *((struct object *) ldata(item)); | |
| 92 obj->o_count = 1; | |
| 93 item = nitem; | |
| 94 } | |
| 95 do_motion(obj, ydelta, xdelta); | |
| 96 /* | |
| 97 * AHA! Here it has hit something. If it is a wall or a door, | |
| 98 * or if it misses (combat) the mosnter, put it on the floor | |
| 99 */ | |
| 100 if (!isupper(mvwinch(mw, obj->o_pos.y, obj->o_pos.x)) | |
| 101 || !hit_monster(unc(obj->o_pos), obj)) | |
| 102 fall(item, TRUE); | |
| 103 mvwaddch(cw, hero.y, hero.x, PLAYER); | |
| 104 } | |
| 105 | |
| 106 /* | |
| 107 * do the actual motion on the screen done by an object traveling | |
| 108 * across the room | |
| 109 */ | |
| 110 void | |
| 111 do_motion(struct object *obj, int ydelta, int xdelta) | |
| 112 { | |
| 113 /* | |
| 114 * Come fly with us ... | |
| 115 */ | |
| 116 obj->o_pos = hero; | |
| 117 for (;;) | |
| 118 { | |
| 119 int ch; | |
| 120 | |
| 121 /* | |
| 122 * Erase the old one | |
| 123 */ | |
| 124 if (!ce(obj->o_pos, hero) && cansee(unc(obj->o_pos)) && | |
| 125 mvwinch(cw, obj->o_pos.y, obj->o_pos.x) != ' ') | |
| 126 mvwaddch(cw, obj->o_pos.y, obj->o_pos.x, | |
| 127 show(obj->o_pos.y, obj->o_pos.x)); | |
| 128 /* | |
| 129 * Get the new position | |
| 130 */ | |
| 131 obj->o_pos.y += ydelta; | |
| 132 obj->o_pos.x += xdelta; | |
| 133 if (step_ok(ch = winat(obj->o_pos.y, obj->o_pos.x)) && ch != DOOR) | |
| 134 { | |
| 135 /* | |
| 136 * It hasn't hit anything yet, so display it | |
| 137 * If it alright. | |
| 138 */ | |
| 139 if (cansee(unc(obj->o_pos)) && | |
| 140 mvwinch(cw, obj->o_pos.y, obj->o_pos.x) != ' ') | |
| 141 { | |
| 142 mvwaddch(cw, obj->o_pos.y, obj->o_pos.x, obj->o_type); | |
| 143 draw(cw); | |
| 144 } | |
| 145 continue; | |
| 146 } | |
| 147 break; | |
| 148 } | |
| 149 } | |
| 150 | |
| 151 /* | |
| 152 * fall: | |
| 153 * Drop an item someplace around here. | |
| 154 */ | |
| 155 | |
| 156 void | |
| 157 fall(struct linked_list *item, int pr) | |
| 158 { | |
| 159 struct object *obj; | |
| 160 struct room *rp; | |
| 161 static coord fpos; | |
| 162 | |
| 163 obj = (struct object *) ldata(item); | |
| 164 if (fallpos(&obj->o_pos, &fpos, TRUE)) | |
| 165 { | |
| 166 mvaddch(fpos.y, fpos.x, obj->o_type); | |
| 167 obj->o_pos = fpos; | |
| 168 if ((rp = roomin(&hero)) != NULL && !(rp->r_flags & ISDARK)) | |
| 169 { | |
| 170 light(&hero); | |
| 171 mvwaddch(cw, hero.y, hero.x, PLAYER); | |
| 172 } | |
| 173 attach(lvl_obj, item); | |
| 174 return; | |
| 175 } | |
| 176 if (pr) | |
| 177 if (obj->o_type == WEAPON) /* BUGFUX: Identification trick */ | |
| 178 msg("Your %s vanishes as it hits the ground.", w_names[obj->o_which]); | |
| 179 else | |
| 180 msg("%s vanishes as it hits the ground.", inv_name(obj,TRUE)); | |
| 181 discard(item); | |
| 182 } | |
| 183 | |
| 184 /* | |
| 185 * init_weapon: | |
| 186 * Set up the initial goodies for a weapon | |
| 187 */ | |
| 188 | |
| 189 void | |
| 190 init_weapon(struct object *weap, int type) | |
| 191 { | |
| 192 struct init_weps *iwp; | |
| 193 | |
| 194 iwp = &init_dam[type]; | |
| 195 strcpy(weap->o_damage,iwp->iw_dam); | |
| 196 strcpy(weap->o_hurldmg,iwp->iw_hrl); | |
| 197 weap->o_launch = iwp->iw_launch; | |
| 198 weap->o_flags = iwp->iw_flags; | |
| 199 if (weap->o_flags & ISMANY) | |
| 200 { | |
| 201 weap->o_count = rnd(8) + 8; | |
| 202 weap->o_group = newgrp(); | |
| 203 } | |
| 204 else | |
| 205 weap->o_count = 1; | |
| 206 } | |
| 207 | |
| 208 /* | |
| 209 * Does the missile hit the monster | |
| 210 */ | |
| 211 | |
| 212 int | |
| 213 hit_monster(int y, int x, struct object *obj) | |
| 214 { | |
| 215 static coord mp; | |
| 216 | |
| 217 mp.y = y; | |
| 218 mp.x = x; | |
| 219 return fight(&mp, winat(y, x), obj, TRUE); | |
| 220 } | |
| 221 | |
| 222 /* | |
| 223 * num: | |
| 224 * Figure out the plus number for armor/weapons | |
| 225 */ | |
| 226 | |
| 227 char * | |
| 228 num(int n1, int n2) | |
| 229 { | |
| 230 static char numbuf[80]; | |
| 231 | |
| 232 if (n1 == 0 && n2 == 0) | |
| 233 return "+0"; | |
| 234 if (n2 == 0) | |
| 235 sprintf(numbuf, "%s%d", n1 < 0 ? "" : "+", n1); | |
| 236 else | |
| 237 sprintf(numbuf, "%s%d,%s%d", | |
| 238 n1 < 0 ? "" : "+", n1, n2 < 0 ? "" : "+", n2); | |
| 239 return numbuf; | |
| 240 } | |
| 241 | |
| 242 /* | |
| 243 * wield: | |
| 244 * Pull out a certain weapon | |
| 245 */ | |
| 246 | |
| 247 void | |
| 248 wield() | |
| 249 { | |
| 250 struct linked_list *item; | |
| 251 struct object *obj, *oweapon; | |
| 252 | |
| 253 oweapon = cur_weapon; | |
| 254 if (!dropcheck(cur_weapon)) | |
| 255 { | |
| 256 cur_weapon = oweapon; | |
| 257 return; | |
| 258 } | |
| 259 cur_weapon = oweapon; | |
| 260 if ((item = get_item("wield", WEAPON)) == NULL) | |
| 261 { | |
| 262 bad: | |
| 263 after = FALSE; | |
| 264 return; | |
| 265 } | |
| 266 | |
| 267 obj = (struct object *) ldata(item); | |
| 268 if (obj->o_type == ARMOR) | |
| 269 { | |
| 270 msg("You can't wield armor"); | |
| 271 goto bad; | |
| 272 } | |
| 273 if (is_current(obj)) | |
| 274 goto bad; | |
| 275 | |
| 276 if (terse) | |
| 277 addmsg("W"); | |
| 278 else | |
| 279 addmsg("You are now w"); | |
| 280 msg("ielding %s", inv_name(obj, TRUE)); | |
| 281 cur_weapon = obj; | |
| 282 } | |
| 283 | |
| 284 /* | |
| 285 * pick a random position around the give (y, x) coordinates | |
| 286 */ | |
| 287 int | |
| 288 fallpos(coord *pos, coord *newpos, int passages) | |
| 289 { | |
| 290 int y, x, cnt, ch; | |
| 291 | |
| 292 cnt = 0; | |
| 293 for (y = pos->y - 1; y <= pos->y + 1; y++) | |
| 294 for (x = pos->x - 1; x <= pos->x + 1; x++) | |
| 295 { | |
| 296 /* | |
| 297 * check to make certain the spot is empty, if it is, | |
| 298 * put the object there, set it in the level list | |
| 299 * and re-draw the room if he can see it | |
| 300 */ | |
| 301 if (y == hero.y && x == hero.x) | |
| 302 continue; | |
| 303 if (((ch = winat(y, x)) == FLOOR || (passages && ch == PASSAGE)) | |
| 304 && rnd(++cnt) == 0) | |
| 305 { | |
| 306 newpos->y = y; | |
| 307 newpos->x = x; | |
| 308 } | |
| 309 } | |
| 310 return (cnt != 0); | |
| 311 } |
