#ifndef lint
static char *RCSid = "$Header: /usr/brule/guest/empire/empire/emprcs/lib/update/prepare.c,v 2.8 1995/10/11 03:05:54 empire Exp $";
#endif

/*
 * prepare.c
 *
 * perform preliminary updates of the sect
 * does pop growth/starvation, and mil payment,
 * reserve payment, and cap payments
 *
 * Does this for all countries at once
 * 
 * Modified from code
 * from PSL Empire, 1985
 * and Dave Pare, 1986
 *
 * by Thomas Ruschak, 1992
 */

#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"
#ifdef	FALLOUT
#include "path.h"
#endif	/* FALLOUT */
#include "optlist.h"
#include "budg.h"

extern	float levels[MAXNOC][4];

void prep_update();

prepare_sects(etu, bp)
	int	etu;
        int     *bp;
{
	extern	long pops[];
	register struct sctstr *sp;
	struct	natstr *np;
	int	n;

	bzero((s_char *)levels, sizeof(levels));

	for (n=0; sp = getsectid(n); n++) {
		sp->sct_updated = 0;
		fill_update_array(bp, sp);

#ifdef	FALLOUT
	        do_fallout(sp,etu);
#endif	/* FALLOUT */

		if (sp->sct_type == SCT_WATER)
			continue;
		np = getnatp(sp->sct_own);

#ifdef DEBUG
                if (np->nat_stat & STAT_SANCT)
		   logerror("Prepare.c: country in sanctuary skipped production");
#endif  /* DEBUG */

                if (!(np->nat_stat & STAT_SANCT)){
  	 	  guerrilla(sp);
		  prep_update(sp, etu, np, &pops[sp->sct_own]);
		}

	}
}

/*
 * update the individual sector
 *
 */
void
prep_update(sp, etus, np, pop)
	register struct sctstr *sp;
	register int etus;
	register struct natstr *np;
	long	*pop;
{
	extern	double populace();
	extern	double eatrate;
	extern	double bankint;
	int	vec[I_MAX+1];
	int	cvec[I_MAX+1];
	int	people;
	int	work;
	int	n;
	int	starved;
	int	needed;

	if (getvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR) <= 0)
		return;
	if (getvec(VT_COND, cvec, (s_char *)sp, EF_SECTOR) <= 0)
		bzero(cvec,sizeof(cvec));

	/* If everybody is dead, the sector reverts to unowned. 
	 * This is also checked at the end of the production in
	 * they all starved or were plagued off.
	 */
	if (vec[I_CIVIL] == 0 && vec[I_MILIT] == 0 &&
		!has_units(sp->sct_x,sp->sct_y,sp->sct_own)) {
		sp->sct_own = 0;
		sp->sct_oldown = 0;
		return;
	}
	/* grow people & stuff */
	work = roundavg((etus * populace(np, sp, vec, etus)) / 100.0);

	people = vec[I_CIVIL] + vec[I_MILIT] + vec[I_UW];
	if (sp->sct_type != SCT_SANCT) {
		if (opt_NOFOOD == 0) {
			if (vec[I_FOOD] < 1 + etus * people * eatrate) {
				/* need to grow "emergency rations" */ 
				work -= growfood(sp, vec, work, etus);
			}
			if ((vec[I_FOOD] < 1 + etus * people * eatrate) &&
			    (sp->sct_own == sp->sct_oldown)){

				/* steal food from warehouses, headquarters,
				   supply ships in port, or supply units */
				int	curfood, needed;

				/* first take food out of sector, so that 
				   supply_commod won't find it there & 
				   duplicate it */

				curfood=vec[I_FOOD];
				vec[I_FOOD]=0;
				needed = ldround((double)(1+etus*people*eatrate),1);
				needed -= curfood;
				putvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR);

				/* Now, find some food */
				curfood += supply_commod(sp->sct_own,sp->sct_x,
							 sp->sct_y,I_FOOD,needed);

				/* Now, put it back in sector */
				getvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR);
				vec[I_FOOD]=curfood;
				putvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR);
			}
		}
		starved = feed_people(vec, etus, &needed);
		if (starved > 0 && sp->sct_own) {
			/* don't report POGO starvation */
			wu(0, sp->sct_own, "%d starved in %s.\n", starved,
				xyas(sp->sct_x, sp->sct_y, sp->sct_own));
			if (starved > 25)
				nreport(sp->sct_own, N_DIE_FAMINE, 0, 1);
		}
		if (starved > 0)
			starvation(sp);
		else {
			if (sp->sct_work < 100)
				sp->sct_work += 8 + (random() % 15);
			if (sp->sct_work > 100)
				sp->sct_work = 100;
			grow_people(sp, etus, np, vec);
		}
	} else
		sp->sct_work = 100;
	if (cvec[C_PSTAGE] == 0) {
		cvec[C_PSTAGE] = infect_people(np, vec, sp->sct_effic,
			(int)sp->sct_mobil);
		cvec[C_PTIME] = 0;
	} else {
		n = plague_people(np, vec, cvec, etus);
		switch (n) {
		case PLG_DYING:
			wu(0, sp->sct_own, "PLAGUE deaths reported in %s.\n",
				ownxy(sp));
			nreport(sp->sct_own, N_DIE_PLAGUE, 0, 1);
			break;
		case PLG_INFECT:
			wu(0, sp->sct_own, "%s battling PLAGUE\n", ownxy(sp));
			break;
		case PLG_INCUBATE:
			/* plage has moved into "infectious" stage */
			if (n != cvec[C_PSTAGE]) {
				wu(0, sp->sct_own,
					"Outbreak of PLAGUE in %s!\n",
					ownxy(sp));
				nreport(sp->sct_own, N_OUT_PLAGUE, 0, 1);
			}
			break;
		case PLG_EXPOSED:
		default:
			break;
		}
	}
	if (vec[I_CIVIL] == 0 && vec[I_MILIT] == 0 &&
		!has_units(sp->sct_x,sp->sct_y,sp->sct_own)) {
		sp->sct_own = 0;
		sp->sct_oldown = 0;
	}
	/*
	 * only non-captured civs add to census for nation
	 */
	if (sp->sct_oldown == sp->sct_own)
		*pop += vec[I_CIVIL];

	if (sp->sct_effic > 60 && sp->sct_type == SCT_CAPIT)
		np->nat_money -= etus;

	if (sp->sct_type == SCT_BANK)
		np->nat_money += vec[I_BAR] * etus * bankint
			* sp->sct_effic / 100;

	putvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR);
	putvec(VT_COND, cvec, (s_char *)sp, EF_SECTOR);
}
