Mercurial > hg > early-roguelike
comparison xrogue/weapons.c @ 142:6b5fbd7c3ece
Merge arogue7 and xrogue trees.
| author | John "Elwin" Edwards |
|---|---|
| date | Tue, 12 May 2015 21:39:39 -0400 |
| parents | ce0cf824c192 |
| children | f54901b9c39b |
comparison
equal
deleted
inserted
replaced
| 132:66b0263af424 | 142:6b5fbd7c3ece |
|---|---|
| 1 /* | |
| 2 weapons.c - Functions for dealing with problems brought about by weapons | |
| 3 | |
| 4 XRogue: Expeditions into the Dungeons of Doom | |
| 5 Copyright (C) 1991 Robert Pietkivitch | |
| 6 All rights reserved. | |
| 7 | |
| 8 Based on "Advanced Rogue" | |
| 9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T | |
| 10 All rights reserved. | |
| 11 | |
| 12 Based on "Rogue: Exploring the Dungeons of Doom" | |
| 13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
| 14 All rights reserved. | |
| 15 | |
| 16 See the file LICENSE.TXT for full copyright and licensing information. | |
| 17 */ | |
| 18 | |
| 19 #include <curses.h> | |
| 20 #include <ctype.h> | |
| 21 #include <string.h> | |
| 22 #include "rogue.h" | |
| 23 | |
| 24 boomerang(ydelta, xdelta, item, tp) | |
| 25 int ydelta, xdelta; | |
| 26 register struct linked_list *item; | |
| 27 register struct thing *tp; | |
| 28 { | |
| 29 register struct object *obj; | |
| 30 struct thing midpoint; | |
| 31 coord oldpos; | |
| 32 | |
| 33 obj = OBJPTR(item); | |
| 34 oldpos = obj->o_pos; | |
| 35 | |
| 36 /* | |
| 37 * make it appear to fly at the target | |
| 38 */ | |
| 39 do_motion(obj, ydelta, xdelta, tp); | |
| 40 hit_monster(unc(obj->o_pos), obj, tp); | |
| 41 | |
| 42 /* | |
| 43 * Now let's make it fly back to the wielder. We need to | |
| 44 * use midpoint to fool do_motion into thinking the action | |
| 45 * starts there. Do_motion only looks at the t_pos field. | |
| 46 */ | |
| 47 midpoint.t_pos = obj->o_pos; /* Simulate a new start position */ | |
| 48 do_motion(obj, -ydelta, -xdelta, &midpoint); | |
| 49 | |
| 50 obj->o_pos = oldpos; | |
| 51 } | |
| 52 | |
| 53 /* | |
| 54 * do the actual motion on the screen done by an object traveling | |
| 55 * across the room. Note that we should not look at any field in | |
| 56 * tp other than t_pos unless we change boomerang(). | |
| 57 */ | |
| 58 | |
| 59 do_motion(obj, ydelta, xdelta, tp) | |
| 60 register struct object *obj; | |
| 61 register int ydelta, xdelta; | |
| 62 register struct thing *tp; | |
| 63 { | |
| 64 | |
| 65 /* | |
| 66 * Come fly with us ... | |
| 67 */ | |
| 68 obj->o_pos = tp->t_pos; | |
| 69 for (;;) { | |
| 70 register int ch; | |
| 71 /* | |
| 72 * Erase the old one | |
| 73 */ | |
| 74 if (!ce(obj->o_pos, tp->t_pos) && | |
| 75 cansee(unc(obj->o_pos)) && | |
| 76 mvwinch(cw, obj->o_pos.y, obj->o_pos.x) != ' ') { | |
| 77 mvwaddch(cw, obj->o_pos.y, obj->o_pos.x, show(obj->o_pos.y, obj->o_pos.x)); | |
| 78 } | |
| 79 /* | |
| 80 * Get the new position | |
| 81 */ | |
| 82 obj->o_pos.y += ydelta; | |
| 83 obj->o_pos.x += xdelta; | |
| 84 if (shoot_ok(ch = winat(obj->o_pos.y, obj->o_pos.x)) && ch != DOOR && !ce(obj->o_pos, hero)) { | |
| 85 /* | |
| 86 * It hasn't hit anything yet, so display it | |
| 87 * If it alright. | |
| 88 */ | |
| 89 if (cansee(unc(obj->o_pos)) && | |
| 90 mvwinch(cw, obj->o_pos.y, obj->o_pos.x) != ' ') { | |
| 91 if (obj->o_type == MISSILE) nofont(cw); | |
| 92 mvwaddch(cw, obj->o_pos.y, obj->o_pos.x, obj->o_type); | |
| 93 newfont(cw); | |
| 94 draw(cw); | |
| 95 } | |
| 96 continue; | |
| 97 } | |
| 98 | |
| 99 /* | |
| 100 * Did we stop because of a monster or the hero? If we did | |
| 101 * not, we want to move our position back one because we could | |
| 102 * not actually make it this far. | |
| 103 */ | |
| 104 if (!isalpha(ch) && | |
| 105 !(obj->o_pos.y == hero.y && obj->o_pos.x == hero.x)) { | |
| 106 obj->o_pos.y -= ydelta; | |
| 107 obj->o_pos.x -= xdelta; | |
| 108 } | |
| 109 | |
| 110 break; | |
| 111 } | |
| 112 } | |
| 113 | |
| 114 | |
| 115 /* | |
| 116 * fall: | |
| 117 * Drop an item someplace around here. | |
| 118 */ | |
| 119 | |
| 120 fall(item, pr) | |
| 121 register struct linked_list *item; | |
| 122 bool pr; | |
| 123 { | |
| 124 register struct object *obj; | |
| 125 register struct room *rp; | |
| 126 register int i; | |
| 127 struct object *tobj; | |
| 128 struct linked_list *titem; | |
| 129 coord *fpos = NULL; | |
| 130 | |
| 131 obj = OBJPTR(item); | |
| 132 /* | |
| 133 * try to drop the item, look up to 3 squares away for now | |
| 134 */ | |
| 135 for (i=1; i<4; i++) { | |
| 136 if ((fpos = fallpos(&obj->o_pos, FALSE, i)) != NULL) | |
| 137 break; | |
| 138 } | |
| 139 | |
| 140 if (fpos != NULL) { | |
| 141 if (obj->o_group) { /* try to add groups together */ | |
| 142 for(titem=lvl_obj; titem!=NULL; titem=next(titem)) { | |
| 143 tobj = OBJPTR(titem); | |
| 144 if (tobj->o_group == obj->o_group && | |
| 145 tobj->o_pos.y == fpos->y && | |
| 146 tobj->o_pos.x == fpos->x) { | |
| 147 tobj->o_count += obj->o_count; | |
| 148 o_discard(item); | |
| 149 return; | |
| 150 } | |
| 151 } | |
| 152 } | |
| 153 mvaddch(fpos->y, fpos->x, obj->o_type); | |
| 154 obj->o_pos = *fpos; | |
| 155 if ((rp = roomin(&hero)) != NULL && | |
| 156 lit_room(rp)) { | |
| 157 light(&hero); | |
| 158 mvwaddch(cw, hero.y, hero.x, PLAYER); | |
| 159 } | |
| 160 attach(lvl_obj, item); | |
| 161 return; | |
| 162 } | |
| 163 if (pr) { | |
| 164 msg("The %s vanishes as it hits the ground.", | |
| 165 weaps[obj->o_which].w_name); | |
| 166 } | |
| 167 o_discard(item); | |
| 168 } | |
| 169 | |
| 170 /* | |
| 171 * Does the missile hit the monster | |
| 172 */ | |
| 173 | |
| 174 hit_monster(y, x, obj, tp) | |
| 175 register int y, x; | |
| 176 struct object *obj; | |
| 177 register struct thing *tp; | |
| 178 { | |
| 179 static coord mp; | |
| 180 | |
| 181 mp.y = y; | |
| 182 mp.x = x; | |
| 183 if (tp == &player) { | |
| 184 /* Make sure there is a monster where it landed */ | |
| 185 if (!isalpha(mvwinch(mw, y, x))) { | |
| 186 return(FALSE); | |
| 187 } | |
| 188 | |
| 189 /* Player hits monster */ | |
| 190 return(fight(&mp, obj, TRUE)); | |
| 191 } else { | |
| 192 if (!ce(mp, hero)) { | |
| 193 /* Monster hits monster */ | |
| 194 return(skirmish(tp, &mp, obj, TRUE)); | |
| 195 } | |
| 196 | |
| 197 /* Monster hits player */ | |
| 198 return(attack(tp, obj, TRUE)); | |
| 199 } | |
| 200 } | |
| 201 | |
| 202 /* | |
| 203 * init_weapon: | |
| 204 * Set up the initial goodies for a weapon | |
| 205 */ | |
| 206 | |
| 207 init_weapon(weap, type) | |
| 208 register struct object *weap; | |
| 209 char type; | |
| 210 { | |
| 211 register struct init_weps *iwp; | |
| 212 | |
| 213 iwp = &weaps[type]; | |
| 214 strcpy(weap->o_damage,iwp->w_dam); | |
| 215 strcpy(weap->o_hurldmg,iwp->w_hrl); | |
| 216 weap->o_launch = iwp->w_launch; | |
| 217 weap->o_flags = iwp->w_flags; | |
| 218 weap->o_weight = iwp->w_wght; | |
| 219 if (weap->o_flags & ISMANY) { | |
| 220 weap->o_count = rnd(8) + 8; | |
| 221 weap->o_group = newgrp(); | |
| 222 } else { | |
| 223 weap->o_count = 1; | |
| 224 } | |
| 225 } | |
| 226 | |
| 227 /* | |
| 228 * missile: | |
| 229 * Fire a missile in a given direction | |
| 230 */ | |
| 231 | |
| 232 missile(ydelta, xdelta, item, tp) | |
| 233 int ydelta, xdelta; | |
| 234 register struct linked_list *item; | |
| 235 register struct thing *tp; | |
| 236 { | |
| 237 register struct object *obj; | |
| 238 register struct linked_list *nitem; | |
| 239 char ch; | |
| 240 | |
| 241 /* | |
| 242 * Get which thing we are hurling | |
| 243 */ | |
| 244 if (item == NULL) { | |
| 245 return; | |
| 246 } | |
| 247 obj = OBJPTR(item); | |
| 248 if (obj->o_type == RELIC && obj->o_which == AXE_AKLAD) { | |
| 249 boomerang(ydelta, xdelta, item, tp); | |
| 250 return; | |
| 251 } | |
| 252 | |
| 253 if (!dropcheck(obj)) return; /* Can we get rid of it? */ | |
| 254 | |
| 255 if(!(obj->o_flags & ISMISL)) { | |
| 256 for(;;) { | |
| 257 msg(terse ? "Really throw? (y or n): " | |
| 258 : "Do you really want to throw %s? (y or n): ", | |
| 259 inv_name(obj, TRUE)); | |
| 260 mpos = 0; | |
| 261 ch = wgetch(cw); | |
| 262 if (ch == 'n' || ch == ESC) { | |
| 263 after = FALSE; | |
| 264 return; | |
| 265 } | |
| 266 if (ch == 'y') | |
| 267 break; | |
| 268 } | |
| 269 } | |
| 270 /* | |
| 271 * Get rid of the thing. If it is a non-multiple item object, or | |
| 272 * if it is the last thing, just drop it. Otherwise, create a new | |
| 273 * item with a count of one. | |
| 274 */ | |
| 275 if (obj->o_count < 2) { | |
| 276 detach(tp->t_pack, item); | |
| 277 if (tp->t_pack == pack) { | |
| 278 inpack--; | |
| 279 } | |
| 280 } | |
| 281 else { | |
| 282 obj->o_count--; | |
| 283 nitem = (struct linked_list *) new_item(sizeof *obj); | |
| 284 obj = OBJPTR(nitem); | |
| 285 *obj = *(OBJPTR(item)); | |
| 286 obj->o_count = 1; | |
| 287 item = nitem; | |
| 288 } | |
| 289 updpack(FALSE, tp); | |
| 290 do_motion(obj, ydelta, xdelta, tp); | |
| 291 /* | |
| 292 * AHA! Here it has hit something. If it is a wall or a door, | |
| 293 * or if it misses (combat) the monster, put it on the floor | |
| 294 */ | |
| 295 if (!hit_monster(unc(obj->o_pos), obj, tp)) { | |
| 296 fall(item, TRUE); | |
| 297 } | |
| 298 else | |
| 299 o_discard(item); | |
| 300 | |
| 301 mvwaddch(cw, hero.y, hero.x, PLAYER); | |
| 302 | |
| 303 } | |
| 304 | |
| 305 /* | |
| 306 * num: | |
| 307 * Figure out the plus number for armor/weapons | |
| 308 */ | |
| 309 | |
| 310 char * | |
| 311 num(n1, n2) | |
| 312 register int n1, n2; | |
| 313 { | |
| 314 static char numbuf[LINELEN/2]; | |
| 315 | |
| 316 if (n1 == 0 && n2 == 0) { | |
| 317 return "+0"; | |
| 318 } | |
| 319 if (n2 == 0) { | |
| 320 sprintf(numbuf, "%s%d", n1 < 0 ? "" : "+", n1); | |
| 321 } else { | |
| 322 sprintf(numbuf, "%s%d, %s%d", n1 < 0 ? "" : "+", n1, n2 < 0 ? "" : "+", n2); | |
| 323 } | |
| 324 return(numbuf); | |
| 325 } | |
| 326 | |
| 327 /* | |
| 328 * wield: | |
| 329 * Pull out a certain weapon | |
| 330 */ | |
| 331 | |
| 332 wield() | |
| 333 { | |
| 334 register struct linked_list *item; | |
| 335 register struct object *obj, *oweapon; | |
| 336 | |
| 337 /* | |
| 338 * It takes 2 movement periods to unwield a weapon and 2 movement | |
| 339 * periods to wield a weapon. | |
| 340 */ | |
| 341 if (player.t_action != C_WIELD) { | |
| 342 player.t_action = C_WIELD; | |
| 343 player.t_using = NULL; /* Make sure this is NULL! */ | |
| 344 if (cur_weapon != NULL) { | |
| 345 player.t_no_move = 2 * movement(&player); | |
| 346 return; | |
| 347 } | |
| 348 } | |
| 349 | |
| 350 if ((oweapon = cur_weapon) != NULL) { | |
| 351 /* At this point we have waited at least 2 units */ | |
| 352 if (!dropcheck(cur_weapon)) { | |
| 353 cur_weapon = oweapon; | |
| 354 player.t_action = A_NIL; | |
| 355 return; | |
| 356 } | |
| 357 if (terse) | |
| 358 addmsg("Was "); | |
| 359 else | |
| 360 addmsg("You were "); | |
| 361 msg("wielding %s", inv_name(oweapon, TRUE)); | |
| 362 } | |
| 363 | |
| 364 /* We we have something picked out? */ | |
| 365 if (player.t_using == NULL) { | |
| 366 /* Now, what does he want to wield? */ | |
| 367 if ((item = get_item(pack, "wield", WIELDABLE, FALSE, FALSE)) == NULL) { | |
