Mercurial > hg > early-roguelike
view arogue5/fight.c @ 158:2515e03b2f09
arogue7, xrogue: add 'install' targets to Makefiles.
'make install' and 'make uninstall' should now work as expected.
| author | John "Elwin" Edwards |
|---|---|
| date | Thu, 04 Jun 2015 17:08:40 -0400 |
| parents | 0ed67132cf10 |
| children | 56e748983fa8 |
line wrap: on
line source
/* * All the fighting gets done here * * Advanced Rogue * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T * All rights reserved. * * Based on "Rogue: Exploring the Dungeons of Doom" * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman * All rights reserved. * * See the file LICENSE.TXT for full copyright and licensing information. */ #include "curses.h" #include <ctype.h> #include <string.h> #include "rogue.h" #define CONF_DAMAGE -1 #define PARAL_DAMAGE -2 #define DEST_DAMAGE -3 static const struct matrix att_mat[5] = { /* Base Max_lvl, Factor, Offset, Range */ { 10, 25, 2, 1, 2 }, { 9, 18, 2, 1, 5 }, { 10, 19, 2, 1, 3 }, { 10, 21, 2, 1, 4 }, { 7, 25, 1, 0, 2 } }; /* * fight: * The player attacks the monster. */ fight(mp, weap, thrown) register coord *mp; struct object *weap; bool thrown; { register struct thing *tp; register struct linked_list *item; register bool did_hit = TRUE; bool back_stab = FALSE; /* * Find the monster we want to fight */ if ((item = find_mons(mp->y, mp->x)) == NULL) { return(FALSE); /* must have killed him already */ } tp = THINGPTR(item); /* * Since we are fighting, things are not quiet so no healing takes * place. */ player.t_quiet = 0; tp->t_quiet = 0; /* * if its in the wall, we can't hit it */ if (on(*tp, ISINWALL) && off(player, CANINWALL)) return(FALSE); /* * Let him know it was really a mimic (if it was one). */ if (on(*tp, ISDISGUISE) && (tp->t_type != tp->t_disguise) && off(player, ISBLIND)) { msg("Wait! That's a %s!", monsters[tp->t_index].m_name); turn_off(*tp, ISDISGUISE); did_hit = thrown; } if (on(*tp, CANSURPRISE) && off(player, ISBLIND) && !ISWEARING(R_ALERT)) { msg("Wait! There's a %s!", monsters[tp->t_index].m_name); turn_off(*tp, CANSURPRISE); did_hit = thrown; } /* * if he's a thief and the creature is asleep then he gets a chance * for a backstab */ if (player.t_ctype == C_THIEF && (!on(*tp, ISRUN) || on(*tp, ISHELD) || tp->t_no_move > 0)&& !on(*tp, NOSTAB)) back_stab = TRUE; runto(tp, &hero); if (did_hit) { register const char *mname; did_hit = FALSE; mname = (on(player, ISBLIND)) ? "it" : monsters[tp->t_index].m_name; if (!can_blink(tp) && ( ((weap != NULL) && (weap->o_type == RELIC)) || ((off(*tp, MAGICHIT) || ((weap != NULL) && (weap->o_hplus > 0 || weap->o_dplus > 0)) ) && (off(*tp, BMAGICHIT) || ((weap != NULL) && (weap->o_hplus > 1 || weap->o_dplus > 1)) ) && (off(*tp, CMAGICHIT) || ((weap != NULL) && (weap->o_hplus > 2 || weap->o_dplus > 2)) ) ) ) && roll_em(&player, tp, weap, thrown, cur_weapon, back_stab)) { did_hit = TRUE; if (on(*tp, NOMETAL) && weap != NULL && weap->o_type != RELIC && weap->o_flags & ISMETAL) { sprintf(outstring,"Your %s passes right through the %s!", weaps[weap->o_which].w_name, mname); msg(outstring); } else if (thrown) { tp->t_wasshot = TRUE; thunk(weap, tp, mname); } else hit(weap, tp, NULL, mname, back_stab); /* If the player hit a rust monster, he better have a + weapon */ if (on(*tp, CANRUST) && !thrown && (weap != NULL) && weap->o_type != RELIC && (weap->o_flags & ISMETAL) && !(weap->o_flags & ISPROT) && (weap->o_hplus < 1) && (weap->o_dplus < 1)) { if (rnd(100) < 50) weap->o_hplus--; else weap->o_dplus--; msg(terse ? "Your %s weakens!" : "Your %s appears to be weaker now!", weaps[weap->o_which].w_name); } /* If the player hit something that shrieks, wake the dungeon */ if (on(*tp, CANSHRIEK)) { turn_off(*tp, CANSHRIEK); msg("The %s emits a piercing shriek.", mname); aggravate(); } /* If the player hit something that can surprise, it can't now */ if (on(*tp, CANSURPRISE)) turn_off(*tp, CANSURPRISE); /* * Can the player confuse? */ if (on(player, CANHUH) && !thrown) { msg("Your hands stop glowing red"); msg("The %s appears confused.", mname); turn_on(*tp, ISHUH); turn_off(player, CANHUH); } /* * does the creature explode when hit? */ if (on(*tp, CANEXPLODE)) explode(tp); /* * Merchants just disappear if hit */ if (on(*tp, CANSELL)) { msg("The %s disappears with his wares in a flash.",mname); killed(item, FALSE, FALSE); } else if (tp->t_stats.s_hpt <= 0) killed(item, TRUE, TRUE); /* If the monster is fairly intelligent and about to die, it * may turn tail and run. */ else if ((tp->t_stats.s_hpt < max(10, tp->maxstats.s_hpt/10)) && (rnd(25) < tp->t_stats.s_intel)) { turn_on(*tp, ISFLEE); /* If monster was suffocating, stop it */ if (on(*tp, DIDSUFFOCATE)) { turn_off(*tp, DIDSUFFOCATE); extinguish(suffocate); } /* If monster held us, stop it */ if (on(*tp, DIDHOLD) && (--hold_count == 0)) turn_off(player, ISHELD); turn_off(*tp, DIDHOLD); } } else { if (thrown) bounce(weap, tp, mname); else miss(weap, tp, NULL, mname); } } count = 0; return did_hit; } /* * attack: * The monster attacks the player */ attack(mp, weapon, thrown) register struct thing *mp; register struct object *weapon; bool thrown; { register const char *mname; register bool did_hit = FALSE; register struct object *wielded; /* The wielded weapon */ /* * Since this is an attack, stop running and any healing that was * going on at the time. */ running = FALSE; player.t_quiet = 0; mp->t_quiet = 0; if (on(*mp, ISDISGUISE) && off(player, ISBLIND)) turn_off(*mp, ISDISGUISE); mname = on(player, ISBLIND) ? "it" : monsters[mp->t_index].m_name; /* * Try to find a weapon to wield. Wield_weap will return a * projector if weapon is a projectile (eg. bow for arrow). * If weapon is NULL, it will try to find a suitable weapon. */ wielded = wield_weap(weapon, mp); if (weapon == NULL) weapon = wielded; if (roll_em(mp, &player, weapon, thrown, wielded, FALSE)) { did_hit = TRUE; if (thrown) m_thunk(weapon, mp, mname); else hit(weapon, mp, mname, NULL, FALSE); if (pstats.s_hpt <= 0) death(mp->t_index); /* Bye bye life ... */ /* * suprising monsters appear after they shoot at you */ if (thrown) { if (on(*mp, CANSURPRISE)) turn_off(*mp, CANSURPRISE); } if (!thrown) { /* * If a vampire hits, it may take half your hit points */ if (on(*mp, CANSUCK) && !save(VS_MAGIC, &player, 0)) { if (pstats.s_hpt == 1) death(mp->t_index); else { pstats.s_hpt /= 2; msg("You feel your life force being drawn from you."); } } /* * Stinking monsters make player weaker (to hit) */ if (on(*mp, CANSTINK)) { turn_off(*mp, CANSTINK); if (!save(VS_POISON, &player, 0)) { msg("The stench of the %s sickens you.", mname); if (on(player, HASSTINK)) lengthen(unstink, STINKTIME); else { turn_on(player, HASSTINK); fuse(unstink, 0, STINKTIME, AFTER); } } } /* * Chilling monster reduces strength each time */ if (on(*mp, CANCHILL)) { if (!ISWEARING(R_SUSABILITY) && !save(VS_POISON, &player, 0)) { msg("You cringe at the %s's chilling touch.", mname); chg_str(-1); if (lost_str++ == 0) fuse(res_strength, 0, CHILLTIME, AFTER); else lengthen(res_strength, CHILLTIME); } } /* * itching monsters reduce dexterity (temporarily) */ if (on(*mp, CANITCH) && !save(VS_POISON, &player, 0)) { msg("The claws of the %s scratch you", mname); if(ISWEARING(R_SUSABILITY)) { msg("The scratch has no effect"); } else { turn_on(player, HASITCH); add_dexterity(TRUE); lost_dext++; fuse(un_itch, 0, roll(HEALTIME,SICKTIME), AFTER); } } /* * If a hugging monster hits, it may SQUEEEEEEEZE */ if (on(*mp, CANHUG)) { if (roll(1,20) >= 18 || roll(1,20) >= 18) { msg("The %s squeezes you against itself.", mname); if ((pstats.s_hpt -= roll(2,8)) <= 0) death(mp->t_index); } } /* * If a disease-carrying monster hits, there is a chance the * player will catch the disease */ if (on(*mp, CANDISEASE) && (rnd(pstats.s_const) < mp->t_stats.s_lvl) && off(player, HASDISEASE)) { if (ISWEARING(R_HEALTH)) msg("The wound heals quickly."); else { turn_on(player, HASDISEASE); fuse(cure_disease, 0, roll(HEALTIME,SICKTIME), AFTER); msg(terse ? "You have been diseased." : "You have contracted a disease!"); } } /* * If a rust monster hits, you lose armor */ if (on(*mp, CANRUST)) { if (cur_armor != NULL && cur_armor->o_which != LEATHER && cur_armor->o_which != STUDDED_LEATHER && cur_armor->o_which != PADDED_ARMOR && !(cur_armor->o_flags & ISPROT) && cur_armor->o_ac < pstats.s_arm+1 ) { msg(terse ? "Your armor weakens" : "Your armor appears to be weaker now. Oh my!"); cur_armor->o_ac++; } if (cur_misc[WEAR_BRACERS] != NULL && cur_misc[WEAR_BRACERS]->o_ac > 0 && !(cur_misc[WEAR_BRACERS]->o_flags & ISPROT)) { cur_misc[WEAR_BRACERS]->o_ac--; if (cur_misc[WEAR_BRACERS]->o_ac == 0) { register struct linked_list *item; for (item=pack; item!=NULL; item=next(item)) { if (OBJPTR(item) == cur_misc[WEAR_BRACERS]) { detach(pack, item); o_discard(item); break; } } msg ("Your bracers crumble and fall off!"); cur_misc[WEAR_BRACERS] = NULL; inpack--; } else { msg("Your bracers weaken!"); } } } /* * If can dissolve and hero has leather type armor */ if (on(*mp, CANDISSOLVE) && cur_armor != NULL && (cur_armor->o_which == LEATHER || cur_armor->o_which == STUDDED_LEATHER || cur_armor->o_which == PADDED_ARMOR) && !(cur_armor->o_flags & ISPROT) && cur_armor->o_ac < pstats.s_arm+1) { msg(terse ? "Your armor dissolves" : "Your armor appears to dissolve. Oh my!"); cur_armor->o_ac++; } /* If a surprising monster hit you, you can see it now */ if (on(*mp, CANSURPRISE)) turn_off(*mp, CANSURPRISE); /* * If an infesting monster hits you, you get a parasite or rot */ if (on(*mp, CANINFEST) && rnd(pstats.s_const) < mp->t_stats.s_lvl) { if (ISWEARING(R_HEALTH)) msg("The wound quickly heals.");
