budget: Fix treasury tracking

The update simply updates each nation's nat_money as it goes.  Works.
Except it doesn't update when it runs on behalf of budget.  But it
still checks nat_money to determine whether the nation is solvent.
These checks are all broken.  Leads to massive mispredictions when
you'd go broke or solvent during a real update.

Track money unconditionally in nat_budget[].money.  Delay update of
nat_money until prod_nat().  Replace separate money[] by new
nat_budget[].start_money.  Closes bug#235.

Remaining difference between budget and update in the update test:

* #1: budget mispredicts plane #100 gets built (to be fixed)

* #2: budget shows ship, plane and land unit maintenance when broke,
      but update damages them instead (correct)

* #2: sector -14,0 converts, quadrupling its taxes (correct)

* #4 & #5: bank with dust and bars taken over by che (correct)

* #4: plague deaths (correct)

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
This commit is contained in:
Markus Armbruster 2016-06-19 11:32:36 +02:00
parent 058268595f
commit 10789a0365
14 changed files with 78 additions and 99 deletions

View file

@ -114,8 +114,7 @@ enlist(struct natstr *np, short *vec, int etu)
nat_budget[np->nat_cnum].prod[SCT_ENLIST].count += enlisted;
nat_budget[np->nat_cnum].prod[SCT_ENLIST].money -= enlisted * 3;
if (!player->simulation)
np->nat_money -= enlisted * 3;
nat_budget[np->nat_cnum].money -= enlisted * 3;
}
/* Fallout is calculated here. */
@ -258,7 +257,7 @@ produce_sect(struct natstr *np, int etu, struct bp *bp)
do_feed(sp, np, etu, 0);
if (sp->sct_off || np->nat_money < 0) {
if (sp->sct_off || budget->money < 0) {
sp->sct_avail = 0;
bp_set_from_sect(bp, sp);
continue;
@ -268,17 +267,15 @@ produce_sect(struct natstr *np, int etu, struct bp *bp)
cost = etu * dchr[sp->sct_type].d_maint;
budget->bm[BUDG_SCT_MAINT].count++;
budget->bm[BUDG_SCT_MAINT].money -= cost;
if (!player->simulation)
np->nat_money -= cost;
budget->money -= cost;
}
if ((sp->sct_effic < 100 || sp->sct_type != sp->sct_newtype) &&
np->nat_money >= 0) {
budget->money >= 0) {
cost = roundavg(buildeff(sp));
budget->bm[BUDG_SCT_BUILD].count++;
budget->bm[BUDG_SCT_BUILD].money -= cost;
if (!player->simulation)
np->nat_money -= cost;
budget->money -= cost;
}
if (sp->sct_type == SCT_ENLIST && sp->sct_effic >= 60 &&
@ -291,7 +288,7 @@ produce_sect(struct natstr *np, int etu, struct bp *bp)
*/
if (sp->sct_effic >= 60) {
if (np->nat_money >= 0 && dchr[sp->sct_type].d_prd >= 0)
if (budget->money >= 0 && dchr[sp->sct_type].d_prd >= 0)
produce(np, sp);
}