1 /* 2 * Functions for dealing with problems brought about by weapons 3 * 4 * weapons.c 1.4 (AI Design) 12/22/84 5 */ 6 7 #include "rogue.h" 8 #include "curses.h" 9 10 #define NONE 100 11 12 static struct init_weps { 13 char *iw_dam; /* Damage when wielded */ 14 char *iw_hrl; /* Damage when thrown */ 15 char iw_launch; /* Launching weapon */ 16 int iw_flags; /* Miscellaneous flags */ 17 } init_dam[MAXWEAPONS] = { 18 "2d4", "1d3", NONE, 0, /* Mace */ 19 "3d4", "1d2", NONE, 0, /* Long sword */ 20 "1d1", "1d1", NONE, 0, /* Bow */ 21 "1d1", "2d3", BOW, ISMANY|ISMISL, /* Arrow */ 22 "1d6", "1d4", NONE, ISMISL, /* Dagger */ 23 "4d4", "1d2", NONE, 0, /* 2h sword */ 24 "1d1", "1d3", NONE, ISMANY|ISMISL, /* Dart */ 25 "1d1", "1d1", NONE, 0, /* Crossbow */ 26 "1d2", "2d5", CROSSBOW, ISMANY|ISMISL, /* Crossbow bolt */ 27 "2d3", "1d6", NONE, ISMISL /* Spear */ 28 }; 29 30 /* 31 * missile: 32 * Fire a missile in a given direction 33 */ 34 missile(ydelta, xdelta) 35 int ydelta, xdelta; 36 { 37 register THING *obj, *nitem; 38 39 /* 40 * Get which thing we are hurling 41 */ 42 if ((obj = get_item("throw", WEAPON)) == NULL) 43 return; 44 if (!can_drop(obj) || is_current(obj)) 45 return; 46 /* 47 * Get rid of the thing. If it is a non-multiple item object, or 48 * if it is the last thing, just drop it. Otherwise, create a new 49 * item with a count of one. 50 */ 51 hack: 52 if (obj->o_count < 2) { 53 detach(pack, obj); 54 inpack--; 55 } else { 56 /* 57 * here is a quick hack to check if we can get a new item 58 */ 59 if ((nitem = new_item()) == NULL) { 60 obj->o_count = 1; 61 msg("something in your pack explodes!!!"); 62 goto hack; 63 } 64 obj->o_count--; 65 if (obj->o_group == 0) 66 inpack--; 67 bcopy(*nitem,*obj); 68 nitem->o_count = 1; 69 obj = nitem; 70 } 71 do_motion(obj, ydelta, xdelta); 72 /* 73 * AHA! Here it has hit something. If it is a wall or a door, 74 * or if it misses (combat) the monster, put it on the floor 75 */ 76 if (moat(obj->o_pos.y, obj->o_pos.x) == NULL 77 || !hit_monster(unc(obj->o_pos), obj)) 78 fall(obj, TRUE); 79 } 80 81 /* 82 * do_motion: 83 * Do the actual motion on the screen done by an object traveling 84 * across the room 85 */ 86 do_motion(obj, ydelta, xdelta) 87 THING *obj; 88 register int ydelta, xdelta; 89 { 90 register byte under = '@'; 91 92 /* 93 * Come fly with us ... 94 */ 95 bcopy(obj->o_pos,hero); 96 for (;;) { 97 register int ch; 98 99 /* 100 * Erase the old one 101 */ 102 if (under != '@' && !ce(obj->o_pos, hero) && cansee(unc(obj->o_pos))) 103 mvaddch(obj->o_pos.y, obj->o_pos.x, under); 104 /* 105 * Get the new position 106 */ 107 obj->o_pos.y += ydelta; 108 obj->o_pos.x += xdelta; 109 110 if (step_ok(ch = winat(obj->o_pos.y, obj->o_pos.x)) && ch != DOOR) { 111 /* 112 * It hasn't hit anything yet, so display it 113 * If it alright. 114 */ 115 if (cansee(unc(obj->o_pos))) { 116 under = chat(obj->o_pos.y, obj->o_pos.x); 117 mvaddch(obj->o_pos.y, obj->o_pos.x, obj->o_type); 118 tick_pause(); 119 } else 120 under = '@'; 121 continue; 122 } 123 break; 124 } 125 } 126 127 char * 128 short_name(obj) 129 THING *obj; 130 { 131 switch (obj->o_type) { 132 case WEAPON: return w_names[obj->o_which]; 133 case ARMOR: return a_names[obj->o_which]; 134 case FOOD: return "food"; 135 case POTION: 136 case SCROLL: 137 case AMULET: 138 case STICK: 139 case RING: 140 return index(inv_name(obj, TRUE), ' ') + 1; 141 default: 142 return "bizzare thing"; 143 } 144 } 145 146 /* 147 * fall: 148 * Drop an item someplace around here. 149 */ 150 fall(obj, pr) 151 THING *obj; 152 bool pr; 153 { 154 static coord fpos; 155 register int index; 156 157 switch (fallpos(obj, &fpos)) 158 { 159 case 1: 160 index = INDEX(fpos.y, fpos.x); 161 _level[index] = obj->o_type; 162 bcopy(obj->o_pos,fpos); 163 if (cansee(fpos.y, fpos.x)) 164 { 165 if ((flat(obj->o_pos.y, obj->o_pos.x) & F_PASS) || 166 (flat(obj->o_pos.y, obj->o_pos.x) & F_MAZE)) 167 standout(); 168 mvaddch(fpos.y, fpos.x, obj->o_type); 169 standend(); 170 if (moat(fpos.y,fpos.x) != NULL) 171 moat(fpos.y,fpos.x)->t_oldch = obj->o_type; 172 } 173 attach(lvl_obj, obj); 174 return; 175 case 2: 176 pr = 0; 177 } 178 if (pr) 179 msg("the %s vanishes%s.", short_name(obj), 180 noterse(" as it hits the ground")); 181 discard(obj); 182 } 183 184 /* 185 * init_weapon: 186 * Set up the initial goodies for a weapon 187 */ 188 init_weapon(weap, type) 189 register THING *weap; 190 byte type; 191 { 192 register struct init_weps *iwp; 193 194 iwp = &init_dam[type]; 195 weap->o_damage = iwp->iw_dam; 196 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 = group++; 203 } 204 else 205 weap->o_count = 1; 206 } 207 208 /* 209 * hit_monster: 210 * Does the missile hit the monster? 211 */ 212 hit_monster(y, x, obj) 213 register int y, x; 214 THING *obj; 215 { 216 static coord mp; 217 register THING *mo; 218 219 if (mo = moat(y, x)) { 220 mp.y = y; 221 mp.x = x; 222 return fight(&mp, mo->t_type, obj, TRUE); 223 } 224 return FALSE; 225 } 226 227 /* 228 * num: 229 * Figure out the plus number for armor/weapons 230 */ 231 char * 232 num(n1, n2, type) 233 register int n1, n2; 234 register char type; 235 { 236 static char numbuf[10]; 237 238 sprintf(numbuf, "%s%d", n1 < 0 ? "" : "+", n1); 239 if (type == WEAPON) 240 sprintf(&numbuf[strlen(numbuf)], ",%s%d", n2 < 0 ? "" : "+", n2); 241 return numbuf; 242 } 243 244 /* 245 * wield: 246 * Pull out a certain weapon 247 */ 248 wield() 249 { 250 register THING *obj, *oweapon; 251 register char *sp; 252 253 oweapon = cur_weapon; 254 if (!can_drop(cur_weapon)) 255 { 256 cur_weapon = oweapon; 257 return; 258 } 259 cur_weapon = oweapon; 260 if ((obj = get_item("wield", WEAPON)) == NULL) 261 { 262 bad: 263 after = FALSE; 264 return; 265 } 266 267 if (obj->o_type == ARMOR) 268 { 269 msg("you can't wield armor"); 270 goto bad; 271 } 272 if (is_current(obj)) 273 goto bad; 274 275 sp = inv_name(obj, TRUE); 276 cur_weapon = obj; 277 ifterse2("now wielding %s (%c)","you are now wielding %s (%c)", sp, pack_char(obj)); 278 } 279 280 /* 281 * fallpos: 282 * Pick a random position around the given (y, x) coordinates 283 */ 284 fallpos(obj, newpos) 285 register coord *newpos; 286 THING *obj; 287 { 288 register int y, x, cnt = 0, ch; 289 THING *onfloor; 290 291 for (y = obj->o_pos.y - 1; y <= obj->o_pos.y + 1; y++) 292 for (x = obj->o_pos.x - 1; x <= obj->o_pos.x + 1; x++) { 293 /* 294 * check to make certain the spot is empty, if it is, 295 * put the object there, set it in the level list 296 * and re-draw the room if he can see it 297 */ 298 if ((y == hero.y && x == hero.x) || offmap(y,x)) 299 continue; 300 if ((ch = chat(y, x)) == FLOOR || ch == PASSAGE) { 301 if (rnd(++cnt) == 0) { 302 newpos->y = y; 303 newpos->x = x; 304 } 305 continue; 306 } 307 if (step_ok(ch) 308 && (onfloor = find_obj(y, x)) 309 && onfloor->o_type == obj->o_type 310 && onfloor->o_group 311 && onfloor->o_group == obj->o_group) 312 { 313 onfloor->o_count += obj->o_count; 314 return 2; 315 } 316 } 317 return(cnt != 0); 318 } 319 320 tick_pause() 321 { 322 register int otick; 323 extern int tick; 324 325 otick = tick; 326 while (otick == tick) 327 ; 328 } 329 ÿ