Mercurial > hg > early-roguelike
comparison urogue/fight.c @ 256:c495a4f288c6
Import UltraRogue from the Roguelike Restoration Project (r1490)
| author | John "Elwin" Edwards |
|---|---|
| date | Tue, 31 Jan 2017 19:56:04 -0500 |
| parents | |
| children | 317166b49d8a |
comparison
equal
deleted
inserted
replaced
| 253:d9badb9c0179 | 256:c495a4f288c6 |
|---|---|
| 1 /* | |
| 2 fight.c - All the fighting gets done here | |
| 3 | |
| 4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom | |
| 5 Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong | |
| 6 All rights reserved. | |
| 7 | |
| 8 Based on "Advanced Rogue" | |
| 9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka | |
| 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 <stdlib.h> | |
| 20 #include <string.h> | |
| 21 #include <ctype.h> | |
| 22 #include "rogue.h" | |
| 23 | |
| 24 /* | |
| 25 * This are the beginning experience levels for all players all further | |
| 26 * experience levels are computed by multiplying by 2 | |
| 27 */ | |
| 28 | |
| 29 static long e_levels[10] = | |
| 30 { | |
| 31 143L, /* Fighter */ | |
| 32 182L, /* Paladin */ | |
| 33 169L, /* Ranger */ | |
| 34 127L, /* Cleric */ | |
| 35 154L, /* Druid */ | |
| 36 185L, /* Magician */ | |
| 37 169L, /* Illusionist */ | |
| 38 112L, /* Thief */ | |
| 39 126L, /* Assasin */ | |
| 40 319L /* Ninja */ | |
| 41 }; | |
| 42 | |
| 43 static struct matrix att_mat[11] = | |
| 44 { | |
| 45 /* Base, Max_lvl, Factor, Offset, Range */ | |
| 46 | |
| 47 { 10, 17, 2, 1, 2 }, /* fi */ | |
| 48 { 10, 17, 2, 1, 2 }, /* pa */ | |
| 49 { 10, 17, 2, 1, 2 }, /* ra */ | |
| 50 { 10, 19, 2, 1, 3 }, /* cl */ | |
| 51 { 10, 19, 2, 1, 3 }, /* dr */ | |
| 52 { 9, 21, 2, 1, 5 }, /* mu */ | |
| 53 { 9, 21, 2, 1, 5 }, /* il */ | |
| 54 { 10, 21, 2, 1, 4 }, /* th */ | |
| 55 { 10, 21, 2, 1, 4 }, /* as */ | |
| 56 { 10, 21, 2, 1, 4 }, /* nj */ | |
| 57 { 7, 25, 1, 0, 2 } /* mn */ | |
| 58 }; | |
| 59 | |
| 60 void | |
| 61 do_fight(coord dir, int tothedeath) | |
| 62 { | |
| 63 int x,y; | |
| 64 | |
| 65 x = dir.x; | |
| 66 y = dir.y; | |
| 67 | |
| 68 if (!tothedeath && pstats.s_hpt < max_stats.s_hpt / 3) | |
| 69 { | |
| 70 msg("That's not wise."); | |
| 71 | |
| 72 after = fighting = FALSE; | |
| 73 return; | |
| 74 } | |
| 75 | |
| 76 if (isalpha(CCHAR(winat(hero.y + y, hero.x + x)))) | |
| 77 { | |
| 78 after = fighting = TRUE; | |
| 79 do_move(y, x); | |
| 80 } | |
| 81 else | |
| 82 { | |
| 83 if (fighting == FALSE) | |
| 84 msg("Nothing there."); | |
| 85 | |
| 86 after = fighting = FALSE; | |
| 87 } | |
| 88 | |
| 89 return; | |
| 90 } | |
| 91 | |
| 92 /* | |
| 93 fight() | |
| 94 The player attacks the monster. | |
| 95 */ | |
| 96 | |
| 97 int | |
| 98 fight(coord *mp, struct object *weap, int thrown) | |
| 99 { | |
| 100 struct thing *tp; | |
| 101 struct linked_list *item; | |
| 102 int did_hit = TRUE; | |
| 103 char *mname; | |
| 104 | |
| 105 /* Find the monster we want to fight */ | |
| 106 | |
| 107 if ((item = find_mons(mp->y, mp->x)) == NULL) | |
| 108 { | |
| 109 debug("Fight what @ %d,%d", mp->y, mp->x); | |
| 110 return 0; | |
| 111 } | |
| 112 | |
| 113 tp = THINGPTR(item); | |
| 114 | |
| 115 mname = (on(player, ISBLIND)) ? "it" : monsters[tp->t_index].m_name; | |
| 116 | |
| 117 /* Since we are fighting, things are not quiet so no healing takes place */ | |
| 118 | |
| 119 player.t_rest_hpt = player.t_rest_pow = 0; | |
| 120 tp->t_rest_hpt = tp->t_rest_pow = 0; | |
| 121 | |
| 122 /* Let him know it was really a mimic (if it was one). */ | |
| 123 | |
| 124 if (off(player, ISBLIND)) | |
| 125 { | |
| 126 if (on(*tp, ISDISGUISE) && (tp->t_type != tp->t_disguise)) | |
| 127 { | |
| 128 msg("Wait! That's a %s!", mname); | |
| 129 turn_off(*tp, ISDISGUISE); | |
| 130 did_hit = thrown; | |
| 131 } | |
| 132 | |
| 133 if (on(*tp, CANSURPRISE)) | |
| 134 { | |
| 135 turn_off(*tp, CANSURPRISE); | |
| 136 if ((player.t_ctype == C_RANGER && rnd(6) != 0) || | |
| 137 (player.t_ctype == C_NINJA && rnd(pstats.s_lvl / 2) | |
| 138 != 0)) | |
| 139 msg("You notice a %s trying to hide!", mname); | |
| 140 else | |
| 141 { | |
| 142 msg("Wait! There's a %s!", mname); | |
| 143 did_hit = thrown; | |
| 144 } | |
| 145 } | |
| 146 } | |
| 147 | |
| 148 /* Protection from Normal Missiles */ | |
| 149 | |
| 150 if (thrown && on(*tp, HASMSHIELD)) | |
| 151 { | |
| 152 msg("The %s slows as it approaches %s.", | |
| 153 weaps[weap->o_which].w_name, mname); | |
| 154 | |
| 155 did_hit = FALSE; | |
| 156 } | |
| 157 | |
| 158 if (did_hit) | |
| 159 { | |
| 160 did_hit = FALSE; | |
| 161 | |
| 162 if (!can_blink(tp) && | |
| 163 (off(*tp, MAGICHIT) || (weap != NULL && | |
| 164 (weap->o_hplus > 0 || weap->o_dplus > 0))) && | |
| 165 (off(*tp, BMAGICHIT) || (weap != NULL && | |
| 166 (weap->o_hplus > 2 || weap->o_dplus > 2))) && | |
| 167 roll_em(&player, tp, weap, thrown, cur_weapon)) | |
| 168 { | |
| 169 did_hit = TRUE; | |
| 170 tp->t_wasshot = TRUE; | |
| 171 | |
| 172 if (thrown) | |
| 173 { | |
| 174 if (weap != NULL && weap->o_type == WEAPON | |
| 175 && weap->o_which == GRENADE) | |
| 176 { | |
| 177 hearmsg("BOOOM!"); | |
| 178 aggravate(); | |
| 179 } | |
| 180 | |
| 181 thunk(weap, mname); | |
| 182 } | |
| 183 else | |
| 184 hit(mname); | |
| 185 | |
| 186 /* hitting a friendly monster is curtains */ | |
| 187 | |
| 188 if (on(*tp, ISFRIENDLY)) | |
| 189 { | |
| 190 turn_off(*tp, ISFRIENDLY); | |
| 191 turn_on(*tp, ISMEAN); | |
| 192 } | |
| 193 | |
| 194 /* Charmed monsters become uncharmed */ | |
| 195 | |
| 196 if (on(*tp, ISCHARMED)) | |
| 197 { | |
| 198 turn_off(*tp, ISCHARMED); | |
| 199 turn_on(*tp, ISMEAN); | |
| 200 } | |
| 201 | |
| 202 /* | |
| 203 * If the player hit a rust monster, he better have a | |
| 204 * + weapon | |
| 205 */ | |
| 206 | |
| 207 if (on(*tp, CANRUST)) | |
| 208 { | |
| 209 if (!thrown && (weap != NULL) && | |
| 210 (weap->o_flags & ISMETAL) && | |
| 211 !(weap->o_flags & ISPROT) && | |
| 212 !(weap->o_flags & ISSILVER) && | |
| 213 (weap->o_hplus < 1) && (weap->o_dplus < 1)) | |
| 214 { | |
| 215 if (rnd(100) < 50) | |
| 216 weap->o_hplus--; | |
| 217 else | |
| 218 weap->o_dplus--; | |
| 219 | |
| 220 msg("Your %s weakens!", weaps[weap->o_which].w_name); | |
| 221 } | |
| 222 else if (!thrown && weap != NULL && (weap->o_flags & ISMETAL)) | |
| 223 msg("The rust vanishes from your %s!", | |
| 224 weaps[weap->o_which].w_name); | |
| 225 } | |
| 226 | |
| 227 /* flammable monsters die from burning weapons */ | |
| 228 | |
| 229 if (thrown && on(*tp, CANBBURN) && | |
| 230 (weap->o_flags & CANBURN) && | |
| 231 !save_throw(VS_WAND, tp)) | |
| 232 { | |
| 233 msg("The %s vanishes in a ball of flame.", | |
| 234 monsters[tp->t_index].m_name); | |
| 235 | |
| 236 tp->t_stats.s_hpt = 0; | |
| 237 } | |
| 238 | |
| 239 /* spores explode and infest hero */ | |
| 240 | |
| 241 if (on(*tp, CANSPORE)) | |
| 242 { | |
| 243 msg("The %s explodes in a cloud of dust.", | |
| 244 monsters[tp->t_index].m_name); | |
| 245 | |
| 246 if (is_wearing(R_HEALTH) || | |
| 247 player.t_ctype == C_PALADIN || | |
| 248 (player.t_ctype == C_NINJA && pstats.s_lvl | |
| 249 > 6) || | |
| 250 thrown && rnd(50) > 0 || | |
| 251 rnd(20) > 0) | |
| 252 { | |
| 253 msg("The dust makes it hard to breath."); | |
| 254 } | |
| 255 else | |
| 256 { | |
| 257 msg("You have contracted a parasitic infestation!"); | |
| 258 | |
| 259 infest_dam++; | |
| 260 turn_on(player, HASINFEST); | |
| 261 } | |
| 262 | |
| 263 tp->t_stats.s_hpt = 0; | |
| 264 } | |
| 265 | |
| 266 /* fireproof monsters laugh at you when burning weapon hits */ | |
| 267 | |
| 268 if (thrown && on(*tp, NOFIRE) && (weap->o_flags & CANBURN)) | |
| 269 msg("The %s laughs as the %s bounces.", | |
| 270 monsters[tp->t_index].m_name, | |
| 271 weaps[weap->o_which].w_name); | |
| 272 | |
| 273 /* sharp weapons have no effect on NOSHARP monsters */ | |
| 274 | |
| 275 if (on(*tp, NOSHARP) && (weap != NULL) && | |
| 276 (weap->o_flags & ISSHARP)) | |
| 277 { | |
| 278 msg("The %s has no effect on the %s!", | |
| 279 weaps[weap->o_which].w_name, | |
| 280 monsters[tp->t_index].m_name); | |
| 281 | |
| 282 fighting = FALSE; | |
| 283 } | |
| 284 | |
| 285 /* metal weapons pass through NOMETAL monsters */ | |
| 286 | |
| 287 if (on(*tp, NOMETAL) && (weap != NULL) && | |
| 288 (weap->o_flags & ISMETAL)) | |
| 289 { | |
| 290 msg("The %s passes through the %s!", | |
| 291 weaps[weap->o_which].w_name, | |
| 292 monsters[tp->t_index].m_name); | |
| 293 | |
| 294 fighting = FALSE; | |
| 295 } | |
| 296 | |
| 297 /* | |
| 298 * If the player hit something that shrieks, wake the | |
| 299 * dungeon | |
| 300 */ | |
| 301 | |
| 302 if (on(*tp, CANSHRIEK)) | |
| 303 { | |
| 304 turn_off(*tp, CANSHRIEK); | |
| 305 | |
| 306 if (on(player, CANHEAR)) | |
| 307 { | |
| 308 msg("You are stunned by the %s's shriek.", mname); | |
| 309 no_command += 4 + rnd(8); | |
| 310 } | |
| 311 else if (off(player, ISDEAF)) | |
| 312 msg("The %s emits a piercing shriek.", mname); | |
| 313 else | |
| 314 msg("The %s seems to be trying to make some noise.", mname); | |
| 315 | |
| 316 aggravate(); | |
| 317 | |
| 318 if (rnd(wizard ? 3 : 39) == 0 && cur_armor | |
| 319 != NULL | |
| 320 && cur_armor->o_which == CRYSTAL_ARMOR) | |
| 321 { | |
| 322 struct linked_list *itm; | |
| 323 struct object *obj; | |
| 324 | |
| 325 for (itm = pack; itm != NULL; itm = next(itm)) | |
| 326 { | |
| 327 obj = OBJPTR(itm); | |
| 328 | |
| 329 if (obj == cur_armor) | |
| 330 break; | |
| 331 } | |
| 332 | |
| 333 if (itm == NULL) | |
| 334 debug("Can't find crystalline armor being worn."); | |
| 335 else | |
| 336 { | |
| 337 msg("Your armor shatters from the shriek."); | |
| 338 cur_armor = NULL; | |
| 339 del_pack(itm); | |
| 340 } | |
| 341 } | |
| 342 } | |
| 343 | |
| 344 /* | |
| 345 * If the player hit something that can surprise, it | |
| 346 * can't now | |
| 347 */ | |
| 348 | |
| 349 if (on(*tp, CANSURPRISE)) | |
| 350 turn_off(*tp, CANSURPRISE); | |
| 351 | |
| 352 /* | |
| 353 * If the player hit something that can summon, it | |
| 354 * will try to | |
| 355 */ | |
| 356 | |
| 357 summon_help(tp, NOFORCE); | |
| 358 | |
| 359 /* Can the player confuse? */ | |
| 360 | |
| 361 if (on(player, CANHUH) && !thrown) | |
| 362 { | |
| 363 seemsg("Your hands stop glowing red!"); | |
| 364 seemsg("The %s appears confused.", mname); | |
| 365 turn_on(*tp, ISHUH); | |
