view xrogue/fight.c @ 283:d71e5e1f49cf

Fix a few more compiler warnings.
author John "Elwin" Edwards
date Mon, 18 Sep 2017 19:36:14 -0400
parents e1cd27c5464f
children e52a8a7ad4c5
line wrap: on
line source

/*
    fight.c - All the fighting gets done here
    
    XRogue: Expeditions into the Dungeons of Doom
    Copyright (C) 1991 Robert Pietkivitch
    All rights reserved.
    
    Based on "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 <stdlib.h>
#include "rogue.h"

#define CONF_DAMAGE     -1
#define PARAL_DAMAGE    -2
#define DEST_DAMAGE     -3
#define DRAIN_DAMAGE    -4

bool roll_em(struct thing *att_er, struct thing *def_er, struct object *weap, 
             bool hurl, struct object *cur_weapon, bool back_stab);
void hit(struct object *weapon, bool see_att, bool see_def, char *er, char *ee, 
         bool back_stab, bool thrown, bool short_msg);
void miss(struct object *weapon, bool see_att, bool see_def, char *er, char *ee,
          bool thrown, bool short_msg);
int add_dam(short str);
int hung_dam(void);

int killed_chance = 0;  /* cumulative chance for goodies to loose it */

/*
 * returns true if player has a any chance to hit the monster
 */

bool
player_can_hit(struct thing *tp, struct object *weap)
{
    if (off(*tp, CMAGICHIT) && off(*tp, BMAGICHIT) && off(*tp, MAGICHIT))
        return(TRUE);
    if (weap && weap->o_type == RELIC)
        return(TRUE);
    if (on(*tp, CMAGICHIT) && weap && (weap->o_hplus>2 || weap->o_dplus>2))
        return(TRUE);
    if (on(*tp, BMAGICHIT) && weap && (weap->o_hplus>1 || weap->o_dplus>1))
        return(TRUE);
    if (on(*tp,  MAGICHIT) && weap && (weap->o_hplus>0 || weap->o_dplus>0))
        return(TRUE);
    if (player.t_ctype == C_MONK) {
        if (on(*tp, CMAGICHIT) && pstats.s_lvl > 15)
            return(TRUE);
        if (on(*tp, BMAGICHIT) && pstats.s_lvl > 10)
            return(TRUE);
        if (on(*tp,  MAGICHIT) && pstats.s_lvl > 5)
            return(TRUE);
    }
    return(FALSE);
}

/*
 * fight:
 *      The player attacks the monster.
 */

bool
fight(coord *mp, struct object *weap, bool thrown)
{
    register struct thing *tp;
    register struct linked_list *item;
    register bool did_hit = TRUE;
    bool see_def, back_stab = FALSE;
    register char *mname;

    /*
     * 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.  The -1 also tells us that we are in a fight.
     */
    player.t_quiet = -1;
    tp->t_quiet = -1;

    see_def = ((off(*tp, ISINVIS)     || on(player, CANSEE)) &&
               (off(*tp, ISSHADOW)    || on(player, CANSEE)) &&
               (!thrown || cansee(unc(tp->t_pos))));

    mname = see_def ? monster_name(tp) : "something";

    /*
     * if its in the wall, we can't hit it
     */
    if (on(*tp, ISINWALL) && off(player, CANINWALL))
        return(FALSE);

    if (on(*tp, ISSTONE)) {
        killed(item, FALSE, FALSE, FALSE);
        if (see_def) 
            msg("%s shatters into a million pieces!", prname(mname, TRUE));
        count = 0;
        return (TRUE);
    }
    /*
     * 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))
    {
        if (see_def) {
            msg("Wait! That's a %s!", mname);
            turn_off(*tp, ISDISGUISE);
        }
        did_hit = thrown;
    }
    if (on(*tp, CANSURPRISE) && off(player, ISBLIND) && !ISWEARING(R_ALERT)) {
        if (see_def) {
            msg("Wait! There's a %s!", mname);
            turn_off(*tp, CANSURPRISE);
        }
        did_hit = thrown;
    }

    /*
     * if he's a thief or assassin and the creature is asleep then he gets 
     * a chance for a backstab
     */
    if ((player.t_ctype == C_THIEF || player.t_ctype == C_ASSASSIN) &&
        !thrown          &&
        !on(*tp, NOSTAB) &&
        !invisible(tp)   &&
        (!on(*tp, ISRUN) || on(*tp, ISHELD) || tp->t_action == A_FREEZE))
            back_stab = TRUE;

    /*
     * assassins get an assassination chance, if it fails then its normal
     * damage
     */
    if (back_stab && player.t_ctype == C_ASSASSIN) {
        int chance;

        chance = 50 + (pstats.s_lvl - tp->t_stats.s_lvl) * 5;
        if (cur_weapon && (cur_weapon->o_flags & ISPOISON))
            chance += 20;
        if (roll(1,100) > chance || on(*tp, ISUNIQUE))
            back_stab = FALSE;
    }

    runto(tp, &hero);

    /* Let the monster know that the player has missiles! */