#ifndef lint
static char *RCSid = "$Header: /usr/brule/guest/empire/empire/emprcs/lib/update/plane.c,v 2.6 1995/10/24 04:34:49 empire Exp $";
#endif

/*
 * plane.c
 *
 * do "production" for planes -- make more efficient,
 * charge for military, etc.
 *
 * Dave Pare, 1986
 */

#include "misc.h"
#include "var.h"
#include "sect.h"
#include "plane.h"
#include "ship.h"
#include "nat.h"
#include "file.h"
#include "optlist.h"
#include "budg.h"

#ifndef MIN
#define MIN(x,y)        ((x) > (y) ? (y) : (x))
#endif

extern int update_pending;

int
prod_plane(etus,natnum,bp,buildem)
int	etus;
int	natnum;
int     *bp;
int	buildem; /* Build = 1, maintain =0 */
{
	extern	double money_mil;
	extern	double money_plane;
	extern	int plane_grow_scale;
	extern	long money[MAXNOC];
	extern	long air_money[MAXNOC];
	register struct plnstr *pp;
	register struct plchrstr *plp;
	struct	natstr *np;
	float	leftp, buildp;
	int	left, build;
	int	lcm,hcm,lcm_needed,hcm_needed;
	int	mil,mil_needed;
	int	svec[I_MAX+1];
	int     mvec[I_MAX+1];
	int	n, k=0;
	struct	shpstr *shp;
	struct	plchrstr *desc;
	struct  sctstr *sp;
	int	delta;
	int	mult;
	int	cost;
	int	eff;
	int	avail;
	int	w_p_eff;
	int	used;
	int     start_money, onship=0;

	for (n=0; pp = getplanep(n); n++) {
		if (pp->pln_own == 0)
			continue;
		if (pp->pln_own != natnum)
			continue;
		if (pp->pln_effic < PLANE_MINEFF) {
			pp->pln_own = 0;
			continue;
		}
		onship = 0;
		shp = (struct shpstr *)0;
		plp = &plchr[pp->pln_type];
		if (pp->pln_ship >= 0) {
			if (pp->pln_effic >= 80)
				continue;
			onship = 1;
			shp = getshipp(pp->pln_ship);
			if (shp == 0 || shp->shp_own != pp->pln_own) {
				/* nplane is unsigned... */
				if (shp->shp_nplane > 0)
					shp->shp_nplane --;
				pp->pln_own = 0;
				continue;
			}
		}
		np = getnatp(pp->pln_own);
		desc = &plchr[pp->pln_type];
		sp = getsectp(pp->pln_x, pp->pln_y);
		getvec(VT_ITEM, svec, (s_char *)sp, EF_SECTOR);
		mult=1;
		if (np->nat_level[NAT_TLEV] < pp->pln_tech * 0.85)
			mult = 2;

		if (buildem == 0) {
#ifdef  ORBIT
			if ((update_pending) && 
			    (plp->pl_flags & P_O) &&
			    (pp->pln_flags & PLN_LAUNCHED) &&
			    !(plp->pl_flags & P_M) &&
			    !(pp->pln_flags & PLN_SYNCHRONOUS))
				move_sat(pp);
#endif  /* ORBIT */
		/* flight pay is 5x the pay received by other military */
			start_money = np->nat_money;
			cost = -(mult * etus *
				 dmin(0.0, desc->pl_cost * money_plane));
			if ((np->nat_priorities[PRI_PMAINT] == 0 ||
			    np->nat_money < cost) && update_pending) {
				if ((eff = pp->pln_effic - etus/5) < PLANE_MINEFF) {
					wu(0, pp->pln_own,
					   "%s lost to lack of maintenance\n",
					   prplane(pp));
					pp->pln_own = 0;
					continue;
				}
				wu(0, pp->pln_own,
				   "%s lost %d%% to lack of maintenance\n",
				   prplane(pp), pp->pln_effic - eff);
				pp->pln_effic = eff;
			} else {
				np->nat_money -= cost;
			}
			
			np->nat_money += (etus * plp->pl_crew * money_mil * 5);

			air_money[pp->pln_own] += np->nat_money - start_money;
			k++;
			if (!update_pending)
			   np->nat_money = start_money;
			if ((pp->pln_flags & PLN_LAUNCHED) == PLN_LAUNCHED)
				continue;
		}else{
			if (sp->sct_off)
				continue;
			if (np->nat_priorities[PRI_PBUILD] == 0 ||
			    np->nat_money < 0)
				continue;

			start_money = np->nat_money;
			left = 100 - pp->pln_effic;
			if (left <= 0)
				continue;

			if (update_pending)
			  avail = sp->sct_avail * 100;
			else
			  avail = gt_bg_nmbr(bp, sp, I_MAX+1) * 100;

			if (pp->pln_ship >= 0) {
				int     vec[I_MAX+1];
				shp = getshipp(pp->pln_ship);
				getvec(VT_ITEM, vec, (s_char *)shp, EF_SHIP);
				avail += (etus * vec[I_MILIT]/2);
			}
			w_p_eff = 20 + (desc->pl_lcm + 2 * desc->pl_hcm);
			delta = roundavg((double)avail/w_p_eff);
			if (delta <= 0)
				continue;
			if (delta > etus*plane_grow_scale)
				delta = etus*plane_grow_scale;
			if (delta > left)
				delta = left;

			/* delta is the max amount we can grow */

        		left = 100 - pp->pln_effic;
			if (left > delta)
				left = delta;

        		leftp = ((float)left/100.0);
			bzero(mvec, sizeof(mvec));
        		mvec[I_MILIT] = mil_needed = 
                                     ldround((double)(plp->pl_crew * leftp),1);
        		mvec[I_LCM] = lcm_needed = 
                                     ldround((double)(plp->pl_lcm * leftp),1);
        		mvec[I_HCM] = hcm_needed = 
                                     ldround((double)(plp->pl_hcm * leftp),1);

			get_materials(sp, bp, mvec, 0);
 
        		if (mvec[I_MILIT]>=mil_needed)
                		buildp=leftp;
        		else
                		buildp=((float)mvec[I_MILIT]/(float)plp->pl_crew);
	
        		if (mvec[I_LCM] < lcm_needed)
                		buildp = MIN(buildp,((float)mvec[I_LCM]/
					(float)plp->pl_lcm));

        		if (mvec[I_HCM] < hcm_needed)
                		buildp = MIN(buildp,((float)mvec[I_HCM]/
					(float)plp->pl_hcm));

			build=ldround((double)(buildp*100.0),1);
			bzero(mvec, sizeof(mvec));
        		mvec[I_MILIT] = mil_needed = 
                                     roundavg((double)(plp->pl_crew * buildp));
        		mvec[I_LCM] = lcm_needed = 
                                     roundavg((double)(plp->pl_lcm * buildp));
        		mvec[I_HCM] = hcm_needed = 
                                     roundavg((double)(plp->pl_hcm * buildp));

			get_materials(sp, bp, mvec, 1);

			if (onship) build = delta;
			used = build * w_p_eff;

			/*
		 	 * I didn't use roundavg here, because I want to
			 * penalize the player with a large number of planes.
		 	 */
			if (update_pending)
			  avail = (sp->sct_avail * 100 - used) / 100;
			else
			  avail = (gt_bg_nmbr(bp,sp,I_MAX+1) *100 -used) / 100;

			if (avail < 0)
				avail = 0;
			if (update_pending)
			  sp->sct_avail = avail;
			else
			  pt_bg_nmbr(bp,sp,I_MAX+1,avail);

			if (sp->sct_type != SCT_AIRPT)
				build /= 3;
			if (onship){
				if ((pp->pln_effic + build) > 80)
					build = 80- pp ->pln_effic;
			}
			np->nat_money -= roundavg(mult * build *
				desc->pl_cost / 100.0);
			air_money[pp->pln_own] += np->nat_money - start_money;
			
			if (update_pending)
			  pp->pln_effic += (s_char)build;
			else
			  np->nat_money = start_money;
			k++;
		}
	}
	return k;
}




