#ifndef lint
static char *RCSid = "$Header: human.c,v 1.8 89/12/07 20:40:05 mr-frog Exp $";
#endif

/*
 * human.c
 *
 * Update the people in empire; food, plague, etc
 * 
 * from PSL Empire, 1985
 * and Dave Pare, 1986
 */

#include <math.h>
#include "misc.h"
#include "var.h"
#include "sect.h"
#include "nat.h"
#include "item.h"
#include "news.h"
#include "file.h"
#include "xy.h"

/*
 * returns the number who starved, if any.
 */
int
feed_people(vec, etus)
	register int *vec;
	int	etus;
{
#ifndef	NOFOOD
	extern	double eatrate;
	double	food_eaten;
	double	people_left;
	int	starved;

	food_eaten = (etus * eatrate) *
		(vec[I_CIVIL] + vec[I_MILIT] + vec[I_UW]);
	starved = 0;
	if (food_eaten > vec[I_FOOD]) {
		people_left = (vec[I_FOOD] + 0.01) / (food_eaten + 0.01);
		starved = vec[I_CIVIL] + vec[I_MILIT] + vec[I_UW];
		/* only want to starve off at most 1/2 the populace. */
		if (people_left < 0.5)
			people_left = 0.5;
		vec[I_CIVIL] = (int) (vec[I_CIVIL] * people_left);
		vec[I_MILIT] = (int) (vec[I_MILIT] * people_left);
		vec[I_UW] = (int) (vec[I_UW] * people_left);
		starved -= vec[I_CIVIL] + vec[I_MILIT] + vec[I_UW];
		vec[I_FOOD] = 0;
	} else {
		vec[I_FOOD] -= roundavg(food_eaten);
	}
	return starved;
#else
	return 0;
#endif	NOFOOD
}

/*
 * Grow babies, and add to populace.
 * XXX Might think about dropping in a birth
 * rate limitation on countries with high tech
 * production?  Maybe with just high education?
 */
int
grow_people(vec, etus)
	register int *vec;
	int	etus;
{
	extern	double obrate;
	extern	double uwbrate;
	extern	double babyeat;
	int	newciv;
	int	newuw;
	int	new_birth;
	int	new_food;

	newciv = 0;
	newuw = 0;
	if (vec[I_CIVIL] < 999) {
		new_birth = (int) roundavg(obrate * (double)(etus * vec[I_CIVIL]));
#ifdef	NOFOOD
		new_food = (int) (0.5 + 999 / (2.0 * babyeat));
#else
		new_food = (int) (0.5 + vec[I_FOOD] / (2.0 * babyeat));
#endif	NOFOOD
		newciv = new_birth;
		if (newciv > new_food)
			newciv = new_food;
		vec[I_CIVIL] += newciv;
	}
	if (vec[I_CIVIL] > 999)
		vec[I_CIVIL] = 999;
	if (vec[I_UW] < 999) {
		/*
		 * now grow uw's
		 */
		new_birth = (int) roundavg(uwbrate * (double)(etus * vec[I_UW]));
#ifdef	NOFOOD
		new_food = (int) (0.5 + 999 / (2.0 * babyeat));
#else
		new_food = (int) (0.5 + vec[I_FOOD] / (2.0 * babyeat));
#endif	NOFOOD
		newuw = new_birth;
		if (newuw > new_food)
			newuw = new_food;
		vec[I_UW] += newuw;
	}
	if (vec[I_UW] > 999)
		vec[I_UW] = 999;
	/*
	 * subtract the baby eat food and return
	 * # of births.
	 */
#ifndef	NOFOOD
	if (newciv || newuw)
		vec[I_FOOD] -= roundavg((newciv + newuw) * babyeat);
#endif	NOFOOD
	return newciv + newuw;
}

int
infect_people(np, vec, eff, mobil)
	struct	natstr *np;
	register int *vec;
	u_int	eff;
	int	mobil;
{
	double	plg_num;
	double	plg_denom;
	double	plg_chance;

	if (np->nat_level[NAT_TLEV] <= 10.0)
		return 0;
	/*
	 * make plague where there was none before...
	 */
	plg_num = ((vec[I_CIVIL] + vec[I_MILIT] + vec[I_UW]) / 999.0) *
		((vec[I_IRON] + vec[I_OIL]) / 10.0 +
		np->nat_level[NAT_TLEV] + 100.0);
	plg_denom = eff + mobil + 100 + np->nat_level[NAT_RLEV];
	plg_chance = ((plg_num / plg_denom) - 1.0) * 0.01;
	if (chance(plg_chance))
		return PLG_EXPOSED;
	return 0;
}

/*
 * Given the fact that plague exists, kill off
 * people if in plague state DYING.  Increment
 * the plague time.  Return "current" plague
 * stage.  No reports generated here anymore.
 */
int
plague_people(np, vec, cvec, etus)
	struct	natstr *np;
	register int *vec;
	register int *cvec;
	int	etus;
{
	int	stage;
	double	plg_num;
	double	plg_denom;
	double	pct_left;

	cvec[C_PTIME] -= etus;
	stage = cvec[C_PSTAGE];
	switch (stage) {
	case PLG_DYING:
		plg_num = 100.0 * etus;
		plg_denom = (np->nat_level[NAT_RLEV] + 100.0) *
			(vec[C_PTIME] + etus + 1.0);
		pct_left = 1.0 - plg_num / plg_denom;
		if (pct_left < 0.2)
			pct_left = 0.2;
		vec[I_CIVIL] = vec[I_CIVIL] * pct_left;
		vec[I_MILIT] = vec[I_MILIT] * pct_left;
		vec[I_UW] = vec[I_UW] * pct_left;
		break;
	case PLG_INFECT:
	case PLG_INCUBATE:
		break;
	case PLG_EXPOSED:
		cvec[C_PTIME] = 0;
		break;
	default:
		/* bad */
		cvec[C_PTIME] = 0;
		break;
	}
	if (cvec[C_PTIME] <= 0) {
		cvec[C_PSTAGE]--;
		cvec[C_PTIME] = 32 + (random() % 32);
	}
	return stage;
}
