Micropolis
budget.cpp
Go to the documentation of this file.
1/* budget.cpp
2 *
3 * Micropolis, Unix Version. This game was released for the Unix platform
4 * in or about 1990 and has been modified for inclusion in the One Laptop
5 * Per Child program. Copyright (C) 1989 - 2007 Electronic Arts Inc. If
6 * you need assistance with this program, you may contact:
7 * http://wiki.laptop.org/go/Micropolis or email micropolis@laptop.org.
8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or (at
12 * your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details. You should have received a
18 * copy of the GNU General Public License along with this program. If
19 * not, see <http://www.gnu.org/licenses/>.
20 *
21 * ADDITIONAL TERMS per GNU GPL Section 7
22 *
23 * No trademark or publicity rights are granted. This license does NOT
24 * give you any right, title or interest in the trademark SimCity or any
25 * other Electronic Arts trademark. You may not distribute any
26 * modification of this program using the trademark SimCity or claim any
27 * affliation or association with Electronic Arts Inc. or its employees.
28 *
29 * Any propagation or conveyance of this program must include this
30 * copyright notice and these terms.
31 *
32 * If you convey this program (or any modifications of it) and assume
33 * contractual liability for the program to recipients of it, you agree
34 * to indemnify Electronic Arts for any liability that those contractual
35 * assumptions impose on Electronic Arts.
36 *
37 * You may not misrepresent the origins of this program; modified
38 * versions of the program must be marked as such and not identified as
39 * the original program.
40 *
41 * This disclaimer supplements the one included in the General Public
42 * License. TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, THIS
43 * PROGRAM IS PROVIDED TO YOU "AS IS," WITH ALL FAULTS, WITHOUT WARRANTY
44 * OF ANY KIND, AND YOUR USE IS AT YOUR SOLE RISK. THE ENTIRE RISK OF
45 * SATISFACTORY QUALITY AND PERFORMANCE RESIDES WITH YOU. ELECTRONIC ARTS
46 * DISCLAIMS ANY AND ALL EXPRESS, IMPLIED OR STATUTORY WARRANTIES,
47 * INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY, SATISFACTORY QUALITY,
48 * FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT OF THIRD PARTY
49 * RIGHTS, AND WARRANTIES (IF ANY) ARISING FROM A COURSE OF DEALING,
50 * USAGE, OR TRADE PRACTICE. ELECTRONIC ARTS DOES NOT WARRANT AGAINST
51 * INTERFERENCE WITH YOUR ENJOYMENT OF THE PROGRAM; THAT THE PROGRAM WILL
52 * MEET YOUR REQUIREMENTS; THAT OPERATION OF THE PROGRAM WILL BE
53 * UNINTERRUPTED OR ERROR-FREE, OR THAT THE PROGRAM WILL BE COMPATIBLE
54 * WITH THIRD PARTY SOFTWARE OR THAT ANY ERRORS IN THE PROGRAM WILL BE
55 * CORRECTED. NO ORAL OR WRITTEN ADVICE PROVIDED BY ELECTRONIC ARTS OR
56 * ANY AUTHORIZED REPRESENTATIVE SHALL CREATE A WARRANTY. SOME
57 * JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF OR LIMITATIONS ON IMPLIED
58 * WARRANTIES OR THE LIMITATIONS ON THE APPLICABLE STATUTORY RIGHTS OF A
59 * CONSUMER, SO SOME OR ALL OF THE ABOVE EXCLUSIONS AND LIMITATIONS MAY
60 * NOT APPLY TO YOU.
61 */
62
77
78
79#include "micropolis.h"
80
81
83
84
85void Micropolis::initFundingLevel()
86{
87 firePercent = 1.0;
88 fireValue = 0;
89 policePercent = 1.0;
90 policeValue = 0;
91 roadPercent = 1.0;
92 roadValue = 0;
94}
95
98{
99 doBudgetNow(false);
100}
101
102
105{
106 doBudgetNow(true);
107}
108
109
116void Micropolis::doBudgetNow(bool fromMenu)
117{
118 Quad fireInt = (int)(fireFund * firePercent);
119 Quad policeInt = (int)(policeFund * policePercent);
120 Quad roadInt = (int)(roadFund * roadPercent);
121
122 Quad total = fireInt + policeInt + roadInt;
123
124 Quad yumDuckets = taxFund + totalFunds;
125
126 if (yumDuckets > total) {
127
128 // Enough yumDuckets to fully fund fire, police and road.
129
130 fireValue = fireInt;
131 policeValue = policeInt;
132 roadValue = roadInt;
133
136
137 } else if (total > 0) {
138
139 assert(yumDuckets <= total);
140
141 // Not enough yumDuckets to fund everything.
142 // First spend on roads, then on fire, then on police.
143
144 if (yumDuckets > roadInt) {
145
146 // Enough yumDuckets to fully fund roads.
147
148 roadValue = roadInt;
149 yumDuckets -= roadInt;
150
151 if (yumDuckets > fireInt) {
152
153 // Enough yumDuckets to fully fund fire.
154
155 fireValue = fireInt;
156 yumDuckets -= fireInt;
157
158 if (yumDuckets > policeInt) {
159
160 // Enough yumDuckets to fully fund police.
161 // Hey what are we doing here? Should never get here.
162 // We tested for yumDuckets > total above
163 // (where total = fireInt + policeInt + roadInt),
164 // so this should never happen.
165
166 policeValue = policeInt;
167 yumDuckets -= policeInt;
168
169 } else {
170
171 // Fuly funded roads and fire.
172 // Partially fund police.
173
174 policeValue = yumDuckets;
175
176 if (yumDuckets > 0) {
177
178 // Scale back police percentage to available cash.
179
180 policePercent = ((float)yumDuckets) / ((float)policeFund);
181
182 } else {
183
184 // Exactly nothing left, so scale back police percentage to zero.
185
186 policePercent = 0.0;
187
188 }
189
190 }
191
192 } else {
193
194 // Not enough yumDuckets to fully fund fire.
195
196 fireValue = yumDuckets;
197
198 // No police after funding roads and fire.
199
200 policeValue = 0;
201 policePercent = 0.0;
202
203 if (yumDuckets > 0) {
204
205 // Scale back fire percentage to available cash.
206
208 ((float)yumDuckets) / ((float)fireFund);
209
210 } else {
211
212 // Exactly nothing left, so scale back fire percentage to zero.
213
214 firePercent = 0.0;
215
216 }
217
218 }
219
220 } else {
221
222 // Not enough yumDuckets to fully fund roads.
223
224 roadValue = yumDuckets;
225
226 // No fire or police after funding roads.
227
228 fireValue = 0;
229 policeValue = 0;
230 firePercent = 0.0;
231 policePercent = 0.0;
232
233 if (yumDuckets > 0) {
234
235 // Scale back road percentage to available cash.
236
237 roadPercent = ((float)yumDuckets) / ((float)roadFund);
238
239 } else {
240
241 // Exactly nothing left, so scale back road percentage to zero.
242
243 roadPercent = 0.0;
244
245 }
246
247 }
248
249 } else {
250
251 assert(yumDuckets == total);
252 assert(total == 0);
253
254 // Zero funding, so no values but full percentages.
255
256 fireValue = 0;
257 policeValue = 0;
258 roadValue = 0;
259 firePercent = 1.0;
260 policePercent = 1.0;
261 roadPercent = 1.0;
262
263 }
264
265noMoney:
266
267 if (!autoBudget || fromMenu) {
268
269 // FIXME: This might have blocked on the Mac, but now it's asynchronous.
270 // Make sure the stuff we do just afterwards is intended to be done immediately
271 // and is not supposed to wait until after the budget dialog is dismissed.
272 // Otherwise don't do it after this and arrange for it to happen when the
273 // modal budget dialog is dismissed.
274 showBudgetWindowAndStartWaiting();
275
276 // FIXME: Only do this AFTER the budget window is accepted.
277
278 if (!fromMenu) {
279
283
284 total = fireSpend + policeSpend + roadSpend;
285
286 Quad moreDough = (Quad)(taxFund - total);
287 spend(-moreDough);
288
289 }
290
291 mustDrawBudget = 1;
292 doUpdateHeads();
293
294 } else { /* autoBudget & !fromMenu */
295
296 // FIXME: Not sure yumDuckets is the right value here. It gets the
297 // amount spent subtracted from it above in some cases, but not if
298 // we are fully funded. I think we want to use the original value
299 // of yumDuckets, which is taxFund + totalFunds.
300
301 if (yumDuckets > total) {
302
303 Quad moreDough = (Quad)(taxFund - total);
304 spend(-moreDough);
305
309
310 mustDrawBudget = 1;
311 doUpdateHeads();
312
313 } else {
314
315 setAutoBudget(false); /* force autobudget */
316 mustUpdateOptions = true;
318 goto noMoney;
319
320 }
321
322 }
323
324}
325
326
328{
331
332 if (mustDrawBudget) {
333 callback->updateBudget(this, callbackVal);
334 mustDrawBudget = 0;
335 }
336}
337
338
339void Micropolis::showBudgetWindowAndStartWaiting()
340{
341 callback->showBudgetAndWait(this, callbackVal);
342}
343
344
345void Micropolis::setCityTax(short tax)
346{
347 cityTax = tax;
348 callback->updateTaxRate(this, callbackVal, cityTax);
349}
350
351
float firePercent
int mustDrawBudget
Callback * callback
Definition micropolis.h:955
Quad policeValue
void updateBudget()
Definition budget.cpp:327
float roadPercent
bool mustUpdateOptions
Options displayed at user need updating.
void doBudgetFromMenu()
Definition budget.cpp:104
void sendMessage(short Mnum, short x=NOWHERE, short y=NOWHERE, bool picture=false, bool important=false)
Definition message.cpp:390
bool autoBudget
Quad policeSpend
void spend(int dollars)
void doBudgetNow(bool fromMenu)
Definition budget.cpp:116
Quad policeFund
short cityTax
float policePercent
Quad totalFunds
Funds of the player.
void doBudget()
Definition budget.cpp:97
void setAutoBudget(bool value)
Header file for Micropolis game engine.
static const int NOWHERE
Definition micropolis.h:233
@ MESSAGE_NO_MONEY
YOUR CITY HAS GONE BROKE!
Definition text.h:141