view arogue7/encumb.c @ 238:e1cd27c5464f

arogue7, xrogue: improve the handling of the arguments to fuses. fuse() now expects a pointer as the argument to a fuse function. If this is one of the functions that takes int, fuse() follows the pointer and stores that value in the f_list slot, in the integer field of the argument union. When the fuse goes off, do_fuses() recognizes the function and passes it the integer field instead of the pointer. This has the disadvantage of hard-coding the functions that require int in daemon.c, but since the int is copied into f_list, it no longer has to be in static or global memory, which simplifies several files.
author John "Elwin" Edwards
date Fri, 11 Mar 2016 17:40:00 -0500
parents f9ef86cf22b2
children
line wrap: on
line source

/*
 * encumb.c  -  Stuff to do with encumberence
 *
 * Advanced Rogue
 * Copyright (C) 1984, 1985, 1986 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.
 */

/*
 * Stuff to do with encumberence
 *
 */

#include "curses.h"
#include "rogue.h"

int packweight(struct thing *tp);

/*
 * updpack:
 *	Update his pack weight and adjust fooduse accordingly
 */
void
updpack(int getmax, struct thing *tp)
{

	reg int topcarry, curcarry;

	if (getmax)
	    tp->t_stats.s_carry = totalenc(tp);	/* get total encumb */
	curcarry = packweight(tp);		/* get pack weight */

	/* Only update food use for the player (for now) */
	if (tp == &player) {
	    topcarry = tp->t_stats.s_carry / 5;	/* 20% of total carry */
	    if(curcarry > 4 * topcarry) {
		if(rnd(100) < 80)
		    foodlev = 3;			/* > 80% of pack */
	    } else if(curcarry > 3 * topcarry) {
		if(rnd(100) < 60)
		    foodlev = 2;			/* > 60% of pack */
	    } else
		foodlev = 1;			/* <= 60% of pack */
	}
	tp->t_stats.s_pack = curcarry;		/* update pack weight */
}


/*
 * packweight:
 *	Get the total weight of the hero's pack
 */
int
packweight(struct thing *tp)
{
	reg struct object *obj;
	reg struct linked_list *pc;
	reg int weight;

	weight = 0;
	for (pc = tp->t_pack ; pc != NULL ; pc = next(pc)) {
	    obj = OBJPTR(pc);
	    weight += itemweight(obj);
	}
	if (weight < 0)		/* in case of amulet */
	     weight = 0;

	/* If this is the player, is he wearing a ring of carrying? */
	if (tp == &player && ISWEARING(R_CARRY)) {
	    register int temp, i;

	    temp = 0;
	    for (i=0; i<NUM_FINGERS; i++) {
		if (cur_ring[i]->o_which == R_CARRY) {
		    if (cur_ring[i]->o_flags & ISCURSED) temp--;
		    else temp++;
		}
	    }
	    weight -= (temp * weight) / 4;
	}

	return(weight);
}


/*
 * itemweight:
 *	Get the weight of an object
 */
int
itemweight(struct object *wh)
{
	reg int weight;
	reg int ac;

	weight = wh->o_weight;		/* get base weight */
	switch(wh->o_type) {
	    case ARMOR:
		/*
		 * subtract 10% for each enchantment
		 * this will add weight for negative items
		 */
		ac = armors[wh->o_which].a_class - wh->o_ac;
		weight = ((weight*10) - (weight*ac)) / 10;
		if (weight < 0) weight = 0;
	    when WEAPON:
		if ((wh->o_hplus + wh->o_dplus) > 0)
			weight /= 2;
	}
	if(wh->o_flags & ISCURSED)
		weight += weight / 5;	/* 20% more for cursed */
        weight *= wh->o_count;
	return(weight);
}


/*
 * playenc:
 *	Get hero's carrying ability above norm
 */
int
playenc(struct thing *tp)
{
	register int strength;

	if (tp == &player) strength = str_compute();
	else strength = tp->t_stats.s_str;

	return ((strength-8)*50);
}


/*
 * totalenc:
 *	Get total weight that the hero can carry
 */
int
totalenc(struct thing *tp)
{
	reg int wtotal;

	wtotal = NORMENCB + playenc(tp);
	if (tp == &player) switch(hungry_state) {
		case F_SATIATED:
		case F_OKAY:
		case F_HUNGRY:	;			/* no change */
		when F_WEAK:	wtotal -= wtotal / 10;	/* 10% off weak */
		when F_FAINT:	wtotal /= 2;		/* 50% off faint */
	}
	return(wtotal);
}



/*
 * whgtchk:
 *	See if the hero can carry his pack
 */

void
wghtchk(void)
{
	reg int dropchk, err = TRUE;
	reg char ch;

	inwhgt = TRUE;
	if (pstats.s_pack > pstats.s_carry) {
	    ch = CCHAR( mvwinch(stdscr, hero.y, hero.x) );
	    if((ch != FLOOR && ch != PASSAGE)) {
		extinguish(wghtchk);
		fuse(wghtchk, NULL, 1, AFTER);
		inwhgt = FALSE;
		return;
	    }
	    extinguish(wghtchk);
	    msg("Your pack is too heavy for you");
	    do {
		dropchk = drop(NULL);
		if(dropchk == 0) {
		    mpos = 0;
		    msg("You must drop something");
		}
		if(dropchk == TRUE)
		    err = FALSE;
	    } while(err);
	}
	inwhgt = FALSE;
}


/*
 * hitweight:
 *	Gets the fighting ability according to current weight
 * 	This returns a  +1 hit for light pack weight
 * 			 0 hit for medium pack weight
 *			-1 hit for heavy pack weight
 */

int
hitweight(void)
{
	return(2 - foodlev);
}