/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2016, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ * Copyright (C) 1986-2021, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure, Markus Armbruster
*
* Empire is free software: you can redistribute it and/or modify
#include <config.h>
+#include <math.h>
#include "commands.h"
#include "item.h"
+#include "land.h"
#include "optlist.h"
#include "product.h"
+#include "ship.h"
+#include "update.h"
static void prprod(struct sctstr *, double, double, char,
double, double, double, char[], int[], int[], int);
-int
-count_pop(int n)
+static int
+count_pop(void)
{
+ /* FIXME don't duplicate the update's workings, use its code */
int i;
int pop = 0;
- struct sctstr *sp;
+ struct sctstr *sectp;
+ struct shpstr *sp;
+ struct lndstr *lp;
+
+ for (i = 0; (sectp = getsectid(i)); i++) {
+ if (sectp->sct_own == player->cnum) {
+ if (sectp->sct_own == sectp->sct_oldown)
+ pop += sectp->sct_item[I_CIVIL];
+ }
+ }
- for (i = 0; NULL != (sp = getsectid(i)); i++) {
- if (sp->sct_own != n)
- continue;
- if (sp->sct_oldown != n)
- continue;
- pop += sp->sct_item[I_CIVIL];
+ for (i = 0; (sp = getshipp(i)); i++) {
+ if (sp->shp_own == player->cnum)
+ pop += sp->shp_item[I_CIVIL];
+ }
+
+ for (i = 0; (lp = getlandp(i)); i++) {
+ if (lp->lnd_own == player->cnum)
+ pop += lp->lnd_item[I_CIVIL];
}
+
return pop;
}
int
-prod(void)
+c_production(void)
{
struct natstr *natp;
- struct sctstr sect;
+ struct sctstr sect, scratch_sect;
struct nstr_sect nstr;
struct pchrstr *pp;
double p_e;
- double maxr; /* floating version of max */
double prodeff;
- double real; /* floating pt version of act */
- int totpop;
- int material_consume; /* actual production */
+ int totpop = -1;
double cost;
int i;
- int max_consume; /* production w/infinite materials */
int nsect;
- double take;
- double mtake;
- int there;
- int unit_work; /* sum of component amounts */
- int mat_limit, res_limit;
- double worker_limit;
+ double real, maxr;
+ double take, mtake;
i_type it;
- i_type vtype;
unsigned char *resource;
char cmnem[MAXPRCON];
int cuse[MAXPRCON], cmax[MAXPRCON];
if (dchr[sect.sct_type].d_prd < 0)
continue;
pp = &pchr[dchr[sect.sct_type].d_prd];
- vtype = pp->p_type;
if (pp->p_nrndx)
resource = (unsigned char *)§ + pp->p_nrndx;
else
resource = NULL;
- mat_limit = prod_materials_cost(pp, sect.sct_item, &unit_work);
-
/* sector p.e. */
p_e = sect.sct_effic / 100.0;
- if (resource) {
- unit_work++;
+ if (resource)
p_e *= *resource / 100.0;
- }
- if (unit_work == 0)
- unit_work = 1;
-
- worker_limit = sect.sct_avail * p_e / (double)unit_work;
- res_limit = prod_resource_limit(pp, resource);
-
- max_consume = res_limit;
- if (max_consume > worker_limit)
- max_consume = (int)worker_limit;
- material_consume = MIN(max_consume, mat_limit);
prodeff = prod_eff(sect.sct_type, natp->nat_level[pp->p_nlndx]);
- real = (double)material_consume * prodeff;
- maxr = (double)max_consume * prodeff;
- if (vtype != I_NONE) {
- real = MIN(999.0, real);
- maxr = MIN(999.0, maxr);
- if (real < 0.0)
- real = 0.0;
- /* production backlog? */
- there = MIN(ITEM_MAX, sect.sct_item[vtype]);
- real = MIN(real, ITEM_MAX - there);
- }
+ scratch_sect = sect;
+ real = prod_output(&scratch_sect, prodeff);
+
+ scratch_sect = sect;
+ for (i = 0; i < MAXPRCON; ++i)
+ scratch_sect.sct_item[pp->p_ctype[i]] = ITEM_MAX;
+ scratch_sect.sct_item[pp->p_type] = 0;
+ maxr = prod_output(&scratch_sect, prodeff);
if (prodeff != 0) {
take = real / prodeff;
cost = take * pp->p_cost;
if (opt_TECH_POP) {
if (pp->p_level == NAT_TLEV) {
- totpop = count_pop(sect.sct_own);
+ if (totpop < 0)
+ totpop = count_pop();
if (totpop > 50000)
cost *= totpop / 50000.0;
}
if (CANT_HAPPEN(it <= I_NONE || I_MAX < it))
continue;
cmnem[i] = ichr[it].i_mnem;
- cuse[i] = (int)(take * pp->p_camt[i] + 0.5);
- cmax[i] = (int)(mtake * pp->p_camt[i] + 0.5);
+ cuse[i] = (int)ceil(take * pp->p_camt[i]);
+ cmax[i] = (int)ceil(mtake * pp->p_camt[i]);
}
if (pp->p_type != I_NONE)
- mnem = ichr[vtype].i_mnem;
+ mnem = ichr[pp->p_type].i_mnem;
else if (pp->p_level == NAT_TLEV || pp->p_level == NAT_RLEV)
mnem = '.';
else