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_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 */
extern struct budget nat_budget[MAXNOC];
extern int money[MAXNOC];
extern int pops[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 int total_work(int, int, int, int, int, int);
/* 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 tax(struct sctstr *, int, int *, int *, int *);
extern void upd_slmilcosts(int, natid);
extern int bank_income(struct sctstr *, int);
extern void pay_reserve(struct natstr *, int);
/* produce.c */
extern int produce(struct natstr *, struct sctstr *, int *);
extern int prod_materials_cost(struct pchrstr *, short[], int *);

View file

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

View file

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

View file

@ -51,7 +51,7 @@ prepare_sects(int etu)
{
struct sctstr *sp;
struct natstr *np;
int n, civ_tax, uw_tax, mil_pay;
int n, civ_tax, uw_tax;
memset(levels, 0, sizeof(levels));
@ -95,20 +95,24 @@ prepare_sects(int etu)
do_plague(sp, etu);
populace(sp, etu);
np = getnatp(sp->sct_own);
tax(sp, etu, &pops[sp->sct_own], &civ_tax, &uw_tax, &mil_pay);
np->nat_money += civ_tax + uw_tax + mil_pay;
tax(sp, etu, &pops[sp->sct_own], &civ_tax, &uw_tax);
np->nat_money += civ_tax + uw_tax;
if (sp->sct_type == SCT_BANK)
np->nat_money += bank_income(sp, etu);
}
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
tax(struct sctstr *sp, int etu, int *pop, int *civ_tax,
int *uw_tax, int *mil_pay)
tax(struct sctstr *sp, int etu, int *pop, int *civ_tax, int *uw_tax)
{
struct budget *budget = &nat_budget[sp->sct_own];
int mil_pay;
*civ_tax = (int)(0.5 + sp->sct_item[I_CIVIL] * sp->sct_effic *
etu * money_civ / 100);
/*
@ -118,7 +122,10 @@ tax(struct sctstr *sp, int etu, int *pop, int *civ_tax,
*civ_tax = *civ_tax / 4;
*uw_tax = (int)(0.5 + sp->sct_item[I_UW] * sp->sct_effic *
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
@ -127,13 +134,12 @@ tax(struct sctstr *sp, int etu, int *pop, int *civ_tax,
*pop += sp->sct_item[I_CIVIL];
}
int
upd_slmilcosts(natid n, int etu)
void
upd_slmilcosts(int etu, natid n)
{
struct shpstr *sp;
struct lndstr *lp;
int mil, i;
int mil_pay;
mil = 0;
@ -149,8 +155,8 @@ upd_slmilcosts(natid n, int etu)
mil += lp->lnd_item[I_MILIT];
}
mil_pay = mil * etu * money_mil;
return mil_pay;
nat_budget[n].mil.count += mil;
nat_budget[n].mil.money += mil * etu * money_mil;
}
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);
}
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
| BUG: military payroll slightly low, both #mil and $
| BUG: military payroll slightly low
| BUG: expenses ignore going broke
| TODO is it accurate?
production *

View file

@ -41,7 +41,7 @@
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 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 Income from taxes 26911 civs, 9007 uws +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 Sector building 26 sectors 209
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 Income from taxes 6800 civs, 4000 uws +1076
Play#2 output Play#2 1 Income from bars 400 bars +2865
@ -279,7 +279,7 @@
Play#3 input budget
Play#3 command budget
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 Income from taxes 16549 civs, 150 uws +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 Ship maintenance 10 ships 300
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 Income from taxes 23604 civs, 4100 uws +212
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 Unit maintenance 3 units 90
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 Income from taxes 4000 civs, 0 uws +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 Ship maintenance 3 ships 70
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 Income from taxes 4000 civs, 0 uws +1750
Play#7 output Play#7 1 Total income.......................................................+1750