budget: Fix military count (but not yet their pay)

When we add up military payroll, we discard fractions.  Payroll is
therefore lower than it should be, but I'm not fixing that now.  The
number of military budget reports is actually computed from payroll,
and therefore also low.

The obvious way to fix that would be adding another out parameter to
tax() and upd_slmilcosts().  However, budget and the update track cost
and count of numerous things (sector products, unit maintenance and
building, ...), and it's time for a common way to do that.

Create struct budget_item for tracking cost and count, and struct
budget nat_budget[MAXNOC] for tracking a nation's budget.  Track only
military for now; more to follow.

This fixes the military count.  The cost of military remains low,
because we discard fractions exactly as before.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
This commit is contained in:
Markus Armbruster 2016-06-18 14:57:45 +02:00
parent 35d2671c71
commit bb495cac60
6 changed files with 75 additions and 47 deletions

View file

@ -43,7 +43,19 @@
#define SCT_MAINT (SCT_TYPE_MAX + 2) #define SCT_MAINT (SCT_TYPE_MAX + 2)
#define SCT_BUDG_MAX SCT_MAINT #define SCT_BUDG_MAX SCT_MAINT
struct budg_item {
int money; /* money delta */
int count; /* #things making/consuming the money */
};
/* A nation's budget for an update */
struct budget {
/* military payroll */
struct budg_item mil;
};
/* main.c */ /* main.c */
extern struct budget nat_budget[MAXNOC];
extern int money[MAXNOC]; extern int money[MAXNOC];
extern int pops[MAXNOC]; extern int pops[MAXNOC];
extern int sea_money[MAXNOC]; extern int sea_money[MAXNOC];
@ -103,10 +115,11 @@ extern int prod_plane(int, int, struct bp *, int);
extern void populace(struct sctstr *, int); extern void populace(struct sctstr *, int);
extern int total_work(int, int, int, int, int, int); extern int total_work(int, int, int, int, int, int);
/* prepare.c */ /* prepare.c */
extern void tax(struct sctstr *, int, int *, int *, int *, int *);
extern int upd_slmilcosts(natid, int);
extern void prepare_sects(int); extern void prepare_sects(int);
extern void tax(struct sctstr *, int, int *, int *, int *);
extern void upd_slmilcosts(int, natid);
extern int bank_income(struct sctstr *, int); extern int bank_income(struct sctstr *, int);
extern void pay_reserve(struct natstr *, int);
/* produce.c */ /* produce.c */
extern int produce(struct natstr *, struct sctstr *, int *); extern int produce(struct natstr *, struct sctstr *, int *);
extern int prod_materials_cost(struct pchrstr *, short[], int *); extern int prod_materials_cost(struct pchrstr *, short[], int *);

View file

@ -42,8 +42,8 @@
#include "product.h" #include "product.h"
#include "update.h" #include "update.h"
static void calc_all(int (*p_sect)[2], int *taxes, int *Ncivs, static struct budget *calc_all(int (*p_sect)[2], int *taxes, int *Ncivs,
int *Nuws, int *bars, int *Nbars, int *mil, int *Nuws, int *bars, int *Nbars,
int *ships, int *sbuild, int *nsbuild, int *smaint, int *ships, int *sbuild, int *nsbuild, int *smaint,
int *units, int *lbuild, int *nlbuild, int *lmaint, int *units, int *lbuild, int *nlbuild, int *lmaint,
int *planes, int *pbuild, int *npbuild, int *pmaint); int *planes, int *pbuild, int *npbuild, int *pmaint);
@ -54,26 +54,24 @@ budg(void)
{ {
int i; int i;
int p_sect[SCT_BUDG_MAX+1][2]; int p_sect[SCT_BUDG_MAX+1][2];
int taxes, Ncivs, Nuws, bars, Nbars, mil; int taxes, Ncivs, Nuws, bars, Nbars;
int ships, sbuild, nsbuild, smaint; int ships, sbuild, nsbuild, smaint;
int units, lbuild, nlbuild, lmaint; int units, lbuild, nlbuild, lmaint;
int planes, pbuild, npbuild, pmaint; int planes, pbuild, npbuild, pmaint;
int n, etu; struct budget *budget;
int income, expenses; int income, expenses;
struct natstr *np; struct natstr *np;
char buf[1024]; char buf[1024];
char in[80]; char in[80];
etu = etu_per_update;
np = getnatp(player->cnum); np = getnatp(player->cnum);
player->simulation = 1; player->simulation = 1;
calc_all(p_sect, budget = calc_all(p_sect,
&taxes, &Ncivs, &Nuws, &bars, &Nbars, &mil, &taxes, &Ncivs, &Nuws, &bars, &Nbars,
&ships, &sbuild, &nsbuild, &smaint, &ships, &sbuild, &nsbuild, &smaint,
&units, &lbuild, &nlbuild, &lmaint, &units, &lbuild, &nlbuild, &lmaint,
&planes, &pbuild, &npbuild, &pmaint); &planes, &pbuild, &npbuild, &pmaint);
player->simulation = 0; player->simulation = 0;
income = taxes + bars; income = taxes + bars;
@ -142,12 +140,14 @@ budg(void)
buf, p_sect[SCT_MAINT][1]); buf, p_sect[SCT_MAINT][1]);
expenses += p_sect[SCT_MAINT][1]; expenses += p_sect[SCT_MAINT][1];
} }
if (mil) { if (budget->mil.money) {
n = (mil - np->nat_reserve * money_res * etu) / (etu * money_mil); snprintf(buf, sizeof(buf), "%d mil, %d res",
sprintf(in, "%d mil, %d res", n, np->nat_reserve); budget->mil.count, np->nat_reserve);
pr("Military payroll\t\t%-32s%8d\n", in, -mil); pr("Military payroll\t\t%-32s%8d\n",
expenses -= mil; buf, -budget->mil.money);
expenses -= budget->mil.money;
} }
pr("Total expenses%s\n", dotsprintf(buf, "%58d", expenses)); pr("Total expenses%s\n", dotsprintf(buf, "%58d", expenses));
if (taxes) { if (taxes) {
sprintf(in, "%d civ%s, %d uw%s", sprintf(in, "%d civ%s, %d uw%s",
@ -171,22 +171,24 @@ budg(void)
return RET_OK; return RET_OK;
} }
static void static struct budget *
calc_all(int p_sect[][2], calc_all(int p_sect[][2],
int *taxes, int *Ncivs, int *Nuws, int *bars, int *Nbars, int *mil, int *taxes, int *Ncivs, int *Nuws, int *bars, int *Nbars,
int *ships, int *sbuild, int *nsbuild, int *smaint, int *ships, int *sbuild, int *nsbuild, int *smaint,
int *units, int *lbuild, int *nlbuild, int *lmaint, int *units, int *lbuild, int *nlbuild, int *lmaint,
int *planes, int *pbuild, int *npbuild, int *pmaint) int *planes, int *pbuild, int *npbuild, int *pmaint)
{ {
struct budget *budget = &nat_budget[player->cnum];
struct natstr *np; struct natstr *np;
struct bp *bp; struct bp *bp;
int pop = 0; int pop = 0;
int n, civ_tax, uw_tax, mil_pay; int n, civ_tax, uw_tax;
struct sctstr *sp; struct sctstr *sp;
int etu = etu_per_update; int etu = etu_per_update;
memset(nat_budget, 0, sizeof(nat_budget));
memset(p_sect, 0, sizeof(**p_sect) * (SCT_BUDG_MAX+1) * 2); memset(p_sect, 0, sizeof(**p_sect) * (SCT_BUDG_MAX+1) * 2);
*taxes = *Ncivs = *Nuws = *bars = *Nbars = *mil = 0; *taxes = *Ncivs = *Nuws = *bars = *Nbars = 0;
*ships = *sbuild = *nsbuild = *smaint = 0; *ships = *sbuild = *nsbuild = *smaint = 0;
*units = *lbuild = *nlbuild = *lmaint = 0; *units = *lbuild = *nlbuild = *lmaint = 0;
*planes = *pbuild = *npbuild = *pmaint = 0; *planes = *pbuild = *npbuild = *pmaint = 0;
@ -197,11 +199,10 @@ calc_all(int p_sect[][2],
bp_set_from_sect(bp, sp); bp_set_from_sect(bp, sp);
if (sp->sct_own == player->cnum) { if (sp->sct_own == player->cnum) {
sp->sct_updated = 0; sp->sct_updated = 0;
tax(sp, etu, &pop, &civ_tax, &uw_tax, &mil_pay); tax(sp, etu, &pop, &civ_tax, &uw_tax);
*Ncivs += sp->sct_item[I_CIVIL]; *Ncivs += sp->sct_item[I_CIVIL];
*Nuws += sp->sct_item[I_UW]; *Nuws += sp->sct_item[I_UW];
*taxes += civ_tax + uw_tax; *taxes += civ_tax + uw_tax;
*mil += mil_pay;
if (sp->sct_type == SCT_BANK) { if (sp->sct_type == SCT_BANK) {
*bars += bank_income(sp, etu); *bars += bank_income(sp, etu);
*Nbars += sp->sct_item[I_BAR]; *Nbars += sp->sct_item[I_BAR];
@ -209,9 +210,8 @@ calc_all(int p_sect[][2],
} }
} }
tpops[player->cnum] = pop; tpops[player->cnum] = pop;
*mil += (int)(np->nat_reserve * money_res * etu); upd_slmilcosts(etu, player->cnum);
pay_reserve(np, etu);
*mil += upd_slmilcosts(np->nat_cnum, etu);
/* Maintain ships */ /* Maintain ships */
sea_money[player->cnum] = 0; sea_money[player->cnum] = 0;
@ -250,6 +250,7 @@ calc_all(int p_sect[][2],
lnd_money[player->cnum] = 0; lnd_money[player->cnum] = 0;
free(bp); free(bp);
return budget;
} }
static char * static char *

View file

@ -46,6 +46,7 @@
#include "unit.h" #include "unit.h"
#include "update.h" #include "update.h"
struct budget nat_budget[MAXNOC];
int money[MAXNOC]; int money[MAXNOC];
int pops[MAXNOC]; int pops[MAXNOC];
int sea_money[MAXNOC]; int sea_money[MAXNOC];
@ -86,6 +87,7 @@ update_main(void)
* sector production routine (for producing education, * sector production routine (for producing education,
* happiness, and printing out the state of the nation) * happiness, and printing out the state of the nation)
*/ */
memset(nat_budget, 0, sizeof(nat_budget));
memset(pops, 0, sizeof(pops)); memset(pops, 0, sizeof(pops));
memset(air_money, 0, sizeof(air_money)); memset(air_money, 0, sizeof(air_money));
memset(sea_money, 0, sizeof(sea_money)); memset(sea_money, 0, sizeof(sea_money));
@ -111,7 +113,6 @@ update_main(void)
if (np->nat_stat == STAT_SANCT) { if (np->nat_stat == STAT_SANCT) {
continue; continue;
} }
np->nat_money += (int)(np->nat_reserve * money_res * etu);
/* maintain units */ /* maintain units */
prod_ship(etu, i, NULL, 0); prod_ship(etu, i, NULL, 0);

View file

@ -51,7 +51,7 @@ prepare_sects(int etu)
{ {
struct sctstr *sp; struct sctstr *sp;
struct natstr *np; struct natstr *np;
int n, civ_tax, uw_tax, mil_pay; int n, civ_tax, uw_tax;
memset(levels, 0, sizeof(levels)); memset(levels, 0, sizeof(levels));
@ -95,20 +95,24 @@ prepare_sects(int etu)
do_plague(sp, etu); do_plague(sp, etu);
populace(sp, etu); populace(sp, etu);
np = getnatp(sp->sct_own); np = getnatp(sp->sct_own);
tax(sp, etu, &pops[sp->sct_own], &civ_tax, &uw_tax, &mil_pay); tax(sp, etu, &pops[sp->sct_own], &civ_tax, &uw_tax);
np->nat_money += civ_tax + uw_tax + mil_pay; np->nat_money += civ_tax + uw_tax;
if (sp->sct_type == SCT_BANK) if (sp->sct_type == SCT_BANK)
np->nat_money += bank_income(sp, etu); np->nat_money += bank_income(sp, etu);
} }
for (n = 0; NULL != (np = getnatp(n)); n++) { for (n = 0; NULL != (np = getnatp(n)); n++) {
np->nat_money += upd_slmilcosts(np->nat_cnum, etu); upd_slmilcosts(etu, np->nat_cnum);
pay_reserve(np, etu);
np->nat_money += nat_budget[n].mil.money;
} }
} }
void void
tax(struct sctstr *sp, int etu, int *pop, int *civ_tax, tax(struct sctstr *sp, int etu, int *pop, int *civ_tax, int *uw_tax)
int *uw_tax, int *mil_pay)
{ {
struct budget *budget = &nat_budget[sp->sct_own];
int mil_pay;
*civ_tax = (int)(0.5 + sp->sct_item[I_CIVIL] * sp->sct_effic * *civ_tax = (int)(0.5 + sp->sct_item[I_CIVIL] * sp->sct_effic *
etu * money_civ / 100); etu * money_civ / 100);
/* /*
@ -118,7 +122,10 @@ tax(struct sctstr *sp, int etu, int *pop, int *civ_tax,
*civ_tax = *civ_tax / 4; *civ_tax = *civ_tax / 4;
*uw_tax = (int)(0.5 + sp->sct_item[I_UW] * sp->sct_effic * *uw_tax = (int)(0.5 + sp->sct_item[I_UW] * sp->sct_effic *
etu * money_uw / 100); etu * money_uw / 100);
*mil_pay = sp->sct_item[I_MILIT] * etu * money_mil;
mil_pay = sp->sct_item[I_MILIT] * etu * money_mil;
budget->mil.count += sp->sct_item[I_MILIT];
budget->mil.money += mil_pay;
/* /*
* only non-captured civs add to census for nation * only non-captured civs add to census for nation
@ -127,13 +134,12 @@ tax(struct sctstr *sp, int etu, int *pop, int *civ_tax,
*pop += sp->sct_item[I_CIVIL]; *pop += sp->sct_item[I_CIVIL];
} }
int void
upd_slmilcosts(natid n, int etu) upd_slmilcosts(int etu, natid n)
{ {
struct shpstr *sp; struct shpstr *sp;
struct lndstr *lp; struct lndstr *lp;
int mil, i; int mil, i;
int mil_pay;
mil = 0; mil = 0;
@ -149,8 +155,8 @@ upd_slmilcosts(natid n, int etu)
mil += lp->lnd_item[I_MILIT]; mil += lp->lnd_item[I_MILIT];
} }
mil_pay = mil * etu * money_mil; nat_budget[n].mil.count += mil;
return mil_pay; nat_budget[n].mil.money += mil * etu * money_mil;
} }
int int
@ -158,3 +164,10 @@ bank_income(struct sctstr *sp, int etu)
{ {
return (int)(sp->sct_item[I_BAR] * etu * bankint * sp->sct_effic / 100); return (int)(sp->sct_item[I_BAR] * etu * bankint * sp->sct_effic / 100);
} }
void
pay_reserve(struct natstr *np, int etu)
{
nat_budget[np->nat_cnum].mil.money
+= (int)(np->nat_reserve * money_res * etu);
}

View file

@ -1,5 +1,5 @@
budget budget
| BUG: military payroll slightly low, both #mil and $ | BUG: military payroll slightly low
| BUG: expenses ignore going broke | BUG: expenses ignore going broke
| TODO is it accurate? | TODO is it accurate?
production * production *

View file

@ -41,7 +41,7 @@
Play#1 output Play#1 1 Unit maintenance 16 units 510 Play#1 output Play#1 1 Unit maintenance 16 units 510
Play#1 output Play#1 1 Sector building 40 sectors 774 Play#1 output Play#1 1 Sector building 40 sectors 774
Play#1 output Play#1 1 Sector maintenance 2 sectors 120 Play#1 output Play#1 1 Sector maintenance 2 sectors 120
Play#1 output Play#1 1 Military payroll 1155 mil, 0 res 5777 Play#1 output Play#1 1 Military payroll 1164 mil, 0 res 5777
Play#1 output Play#1 1 Total expenses.....................................................24647 Play#1 output Play#1 1 Total expenses.....................................................24647
Play#1 output Play#1 1 Income from taxes 26911 civs, 9007 uws +12625 Play#1 output Play#1 1 Income from taxes 26911 civs, 9007 uws +12625
Play#1 output Play#1 1 Total income......................................................+12625 Play#1 output Play#1 1 Total income......................................................+12625
@ -234,7 +234,7 @@
Play#2 output Play#2 1 Unit maintenance 3 units 90 Play#2 output Play#2 1 Unit maintenance 3 units 90
Play#2 output Play#2 1 Sector building 26 sectors 209 Play#2 output Play#2 1 Sector building 26 sectors 209
Play#2 output Play#2 1 Sector maintenance 5 sectors 300 Play#2 output Play#2 1 Sector maintenance 5 sectors 300
Play#2 output Play#2 1 Military payroll 1898 mil, 1000 res 9994 Play#2 output Play#2 1 Military payroll 1900 mil, 1000 res 9994
Play#2 output Play#2 1 Total expenses.....................................................12390 Play#2 output Play#2 1 Total expenses.....................................................12390
Play#2 output Play#2 1 Income from taxes 6800 civs, 4000 uws +1076 Play#2 output Play#2 1 Income from taxes 6800 civs, 4000 uws +1076
Play#2 output Play#2 1 Income from bars 400 bars +2865 Play#2 output Play#2 1 Income from bars 400 bars +2865
@ -279,7 +279,7 @@
Play#3 input budget Play#3 input budget
Play#3 command budget Play#3 command budget
Play#3 output Play#3 1 Sector Type Production Cost Play#3 output Play#3 1 Sector Type Production Cost
Play#3 output Play#3 1 Military payroll 169 mil, 0 res 848 Play#3 output Play#3 1 Military payroll 170 mil, 0 res 848
Play#3 output Play#3 1 Total expenses.......................................................848 Play#3 output Play#3 1 Total expenses.......................................................848
Play#3 output Play#3 1 Income from taxes 16549 civs, 150 uws +5540 Play#3 output Play#3 1 Income from taxes 16549 civs, 150 uws +5540
Play#3 output Play#3 1 Total income.......................................................+5540 Play#3 output Play#3 1 Total income.......................................................+5540
@ -320,7 +320,7 @@
Play#4 output Play#4 1 bank 4 bars 40 Play#4 output Play#4 1 bank 4 bars 40
Play#4 output Play#4 1 Ship maintenance 10 ships 300 Play#4 output Play#4 1 Ship maintenance 10 ships 300
Play#4 output Play#4 1 Unit maintenance 10 units 600 Play#4 output Play#4 1 Unit maintenance 10 units 600
Play#4 output Play#4 1 Military payroll 1110 mil, 0 res 5552 Play#4 output Play#4 1 Military payroll 1111 mil, 0 res 5552
Play#4 output Play#4 1 Total expenses......................................................6492 Play#4 output Play#4 1 Total expenses......................................................6492
Play#4 output Play#4 1 Income from taxes 23604 civs, 4100 uws +212 Play#4 output Play#4 1 Income from taxes 23604 civs, 4100 uws +212
Play#4 output Play#4 1 Income from bars 100 bars +1500 Play#4 output Play#4 1 Income from bars 100 bars +1500
@ -393,7 +393,7 @@
Play#6 output Play#6 1 Plane maintenance 3 planes 147 Play#6 output Play#6 1 Plane maintenance 3 planes 147
Play#6 output Play#6 1 Unit maintenance 3 units 90 Play#6 output Play#6 1 Unit maintenance 3 units 90
Play#6 output Play#6 1 Sector maintenance 1 sector 60 Play#6 output Play#6 1 Sector maintenance 1 sector 60
Play#6 output Play#6 1 Military payroll 166 mil, 0 res 831 Play#6 output Play#6 1 Military payroll 168 mil, 0 res 831
Play#6 output Play#6 1 Total expenses......................................................1668 Play#6 output Play#6 1 Total expenses......................................................1668
Play#6 output Play#6 1 Income from taxes 4000 civs, 0 uws +1750 Play#6 output Play#6 1 Income from taxes 4000 civs, 0 uws +1750
Play#6 output Play#6 1 Total income.......................................................+1750 Play#6 output Play#6 1 Total income.......................................................+1750
@ -424,7 +424,7 @@
Play#7 output Play#7 1 Sector Type Production Cost Play#7 output Play#7 1 Sector Type Production Cost
Play#7 output Play#7 1 Ship maintenance 3 ships 70 Play#7 output Play#7 1 Ship maintenance 3 ships 70
Play#7 output Play#7 1 Sector maintenance 1 sector 60 Play#7 output Play#7 1 Sector maintenance 1 sector 60
Play#7 output Play#7 1 Military payroll 158 mil, 0 res 792 Play#7 output Play#7 1 Military payroll 160 mil, 0 res 792
Play#7 output Play#7 1 Total expenses.......................................................922 Play#7 output Play#7 1 Total expenses.......................................................922
Play#7 output Play#7 1 Income from taxes 4000 civs, 0 uws +1750 Play#7 output Play#7 1 Income from taxes 4000 civs, 0 uws +1750
Play#7 output Play#7 1 Total income.......................................................+1750 Play#7 output Play#7 1 Total income.......................................................+1750