]> git.pond.sub.org Git - empserver/blob - src/lib/commands/budg.c
budget: Track taxes in nat_budget[]
[empserver] / src / lib / commands / budg.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2016, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                Ken Stevens, Steve McClure, Markus Armbruster
5  *
6  *  Empire is free software: you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation, either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  *  ---
20  *
21  *  See files README, COPYING and CREDITS in the root of the source
22  *  tree for related information and legal notices.  It is expected
23  *  that future projects/authors will amend these files as needed.
24  *
25  *  ---
26  *
27  *  budg.c: Calculate production levels, prioritize
28  *
29  *  Known contributors to this file:
30  *     Thomas Ruschak, 1992
31  *     Ville Virrankoski, 1995
32  *     Steve McClure, 1997-2000
33  *     Markus Armbruster, 2004-2016
34  */
35
36 #include <config.h>
37
38 #include <ctype.h>
39 #include "commands.h"
40 #include "item.h"
41 #include "optlist.h"
42 #include "product.h"
43 #include "update.h"
44
45 static struct budget *calc_all(int *bars, int *Nbars);
46 static char *dotsprintf(char *buf, char *format, int data);
47
48 int
49 budg(void)
50 {
51     static struct {
52         char *activity;
53         char *object;
54     } bm_name[] = {
55         { "Ship building", "ship" },
56         { "Ship maintenance", "ship" },
57         { "Plane building", "plane" },
58         { "Plane maintenance", "plane" },
59         { "Unit building", "unit" },
60         { "Unit maintenance", "unit" },
61         { "Sector building", "sector" },
62         { "Sector maintenance", "sector" }
63     };
64     int i;
65     int bars, Nbars;
66     struct budget *budget;
67     int income, expenses, taxes;
68     struct natstr *np;
69     char buf[1024];
70     char in[80];
71
72     np = getnatp(player->cnum);
73
74     player->simulation = 1;
75     budget = calc_all(&bars, &Nbars);
76     player->simulation = 0;
77
78     income = bars;
79     expenses = 0;
80     pr("Sector Type\t\t\tProduction\t\t\t    Cost\n");
81     for (i = 0; i <= SCT_TYPE_MAX; i++) {
82         if (!budget->prod[i].money)
83             continue;
84         pr("%-17s\t\t", dchr[i].d_name);
85         if (i == SCT_ENLIST)
86             pr("%d mil    \t", budget->prod[i].count);
87         else if (dchr[i].d_prd >= 0)
88             pr("%d %-7s\t", budget->prod[i].count,
89                pchr[dchr[i].d_prd].p_sname);
90         else
91             pr("\t\t");
92         pr("\t\t%8d\n", -budget->prod[i].money);
93         expenses -= budget->prod[i].money;
94     }
95
96     for (i = 0; i <= BUDG_BLD_MAX; i++) {
97         if (!budget->bm[i].money)
98             continue;
99         snprintf(buf, sizeof(buf), "%d %s%s",
100                  budget->bm[i].count, bm_name[i].object,
101                  splur(budget->bm[i].count));
102         pr("%-20s\t\t%-16s\t\t%8d\n",
103            bm_name[i].activity, buf, -budget->bm[i].money);
104         expenses -= budget->bm[i].money;
105     }
106
107     if (budget->mil.money) {
108         snprintf(buf, sizeof(buf), "%d mil, %d res",
109                  budget->mil.count, np->nat_reserve);
110         pr("Military payroll\t\t%-32s%8d\n",
111            buf, -budget->mil.money);
112         expenses -= budget->mil.money;
113     }
114
115     pr("Total expenses%s\n", dotsprintf(buf, "%58d", expenses));
116     taxes = budget->civ.money + budget->uw.money;
117     if (taxes) {
118         snprintf(buf, sizeof(buf), "%d civ%s, %d uw%s",
119                  budget->civ.count, splur(budget->civ.count),
120                  budget->uw.count, splur(budget->uw.count));
121         pr("Income from taxes\t\t%-32s%+8d\n", buf, taxes);
122         income += taxes;
123     }
124     if (bars) {
125         sprintf(in, "%d bar%s", Nbars, splur(Nbars));
126         pr("Income from bars\t\t%-32s%+8d\n", in, bars);
127     }
128     pr("Total income%s\n", dotsprintf(buf, "%+60d", income));
129     pr("Balance forward\t\t\t\t\t\t      %10d\n", np->nat_money);
130     pr("Estimated delta\t\t\t\t\t\t      %+10d\n", income - expenses);
131     pr("Estimated new treasury%s\n",
132        dotsprintf(buf, "%50d", np->nat_money + income - expenses));
133     if (np->nat_money + income - expenses < 0 && !player->god) {
134         pr("After processsing sectors, you will be broke!\n");
135         pr("Sectors will not produce, distribute, or deliver!\n\n");
136     }
137
138     return RET_OK;
139 }
140
141 static struct budget *
142 calc_all(int *bars, int *Nbars)
143 {
144     struct budget *budget = &nat_budget[player->cnum];
145     struct natstr *np;
146     struct bp *bp;
147     int pop = 0;
148     int n;
149     struct sctstr *sp;
150     int etu = etu_per_update;
151
152     memset(nat_budget, 0, sizeof(nat_budget));
153     *bars = *Nbars = 0;
154
155     np = getnatp(player->cnum);
156     bp = bp_alloc();
157     for (n = 0; NULL != (sp = getsectid(n)); n++) {
158         bp_set_from_sect(bp, sp);
159         if (sp->sct_own == player->cnum) {
160             sp->sct_updated = 0;
161             tax(sp, etu, &pop);
162             if (sp->sct_type == SCT_BANK) {
163                 *bars += bank_income(sp, etu);
164                 *Nbars += sp->sct_item[I_BAR];
165             }
166         }
167     }
168     tpops[player->cnum] = pop;
169     upd_slmilcosts(etu, player->cnum);
170     pay_reserve(np, etu);
171
172     /* Maintain ships, planes and land units */
173     prod_ship(etu, player->cnum, bp, 0);
174     prod_plane(etu, player->cnum, bp, 0);
175     prod_land(etu, player->cnum, bp, 0);
176
177     /* Produce */
178     produce_sect(np, etu, bp);
179
180     /* Build ships, planes and land units */
181     prod_ship(etu, player->cnum, bp, 1);
182     prod_plane(etu, player->cnum, bp, 1);
183     prod_land(etu, player->cnum, bp, 1);
184
185     free(bp);
186     return budget;
187 }
188
189 static char *
190 dotsprintf(char *buf, char *format, int data)
191 {
192     sprintf(buf, format, data);
193     return memset(buf, '.', strspn(buf, " "));
194 }