1 #include "resource.h"
2
3 #include "building/building.h"
4 #include "building/count.h"
5 #include "building/industry.h"
6 #include "building/model.h"
7 #include "building/monument.h"
8 #include "city/data_private.h"
9 #include "city/message.h"
10 #include "city/military.h"
11 #include "city/trade.h"
12 #include "city/trade_policy.h"
13 #include "core/calc.h"
14 #include "empire/city.h"
15 #include "figure/figure.h"
16 #include "figure/formation.h"
17 #include "game/difficulty.h"
18 #include "game/tutorial.h"
19 #include "map/road_access.h"
20 #include "scenario/building.h"
21 #include "scenario/property.h"
22
23 #include <math.h>
24
25 static struct {
26 resource_list resource_list;
27 resource_list food_list;
28 } available;
29
30 static struct {
31 resource_list resource_list;
32 resource_list food_list;
33 } potential;
34
city_resource_count_food_on_granaries(resource_type food)35 int city_resource_count_food_on_granaries(resource_type food)
36 {
37 return city_data.resource.granary_food_stored[food];
38 }
39
city_resource_count(resource_type resource)40 int city_resource_count(resource_type resource)
41 {
42 return city_data.resource.stored_in_warehouses[resource];
43 }
44
city_resource_get_amount_including_granaries(int resource,int amount,int * checked_granaries)45 int city_resource_get_amount_including_granaries(int resource, int amount, int *checked_granaries)
46 {
47 if (checked_granaries) {
48 *checked_granaries = 0;
49 }
50 int amount_stored = city_data.resource.stored_in_warehouses[resource];
51 if (amount_stored < amount && resource_is_food(resource)) {
52 amount_stored += city_data.resource.granary_food_stored[resource] / 100;
53 if (checked_granaries) {
54 *checked_granaries = 1;
55 }
56 }
57 return amount_stored;
58 }
59
city_resource_get_available(void)60 const resource_list *city_resource_get_available(void)
61 {
62 return &available.resource_list;
63 }
64
city_resource_get_available_foods(void)65 const resource_list *city_resource_get_available_foods(void)
66 {
67 return &available.food_list;
68 }
69
city_resource_get_potential(void)70 const resource_list *city_resource_get_potential(void)
71 {
72 return &potential.resource_list;
73 }
74
city_resource_get_potential_foods(void)75 const resource_list *city_resource_get_potential_foods(void)
76 {
77 return &potential.food_list;
78 }
79
city_resource_multiple_wine_available(void)80 int city_resource_multiple_wine_available(void)
81 {
82 return city_data.resource.wine_types_available >= 2;
83 }
84
city_resource_food_types_available(void)85 int city_resource_food_types_available(void)
86 {
87 return city_data.resource.food_types_available;
88 }
89
city_resource_food_stored(void)90 int city_resource_food_stored(void)
91 {
92 return city_data.resource.granary_total_stored;
93 }
94
city_resource_food_needed(void)95 int city_resource_food_needed(void)
96 {
97 return city_data.resource.food_needed_per_month;
98 }
99
city_resource_food_supply_months(void)100 int city_resource_food_supply_months(void)
101 {
102 return city_data.resource.food_supply_months;
103 }
104
city_resource_food_percentage_produced(void)105 int city_resource_food_percentage_produced(void)
106 {
107 return calc_percentage(city_data.resource.food_produced_last_month, city_data.resource.food_consumed_last_month);
108 }
109
city_resource_operating_granaries(void)110 int city_resource_operating_granaries(void)
111 {
112 return city_data.resource.granaries.operating;
113 }
114
city_resource_last_used_warehouse(void)115 int city_resource_last_used_warehouse(void)
116 {
117 return city_data.resource.last_used_warehouse;
118 }
119
city_resource_set_last_used_warehouse(int warehouse_id)120 void city_resource_set_last_used_warehouse(int warehouse_id)
121 {
122 city_data.resource.last_used_warehouse = warehouse_id;
123 }
124
city_resource_trade_status(resource_type resource)125 resource_trade_status city_resource_trade_status(resource_type resource)
126 {
127 return city_data.resource.trade_status[resource];
128 }
129
city_resource_cycle_trade_status(resource_type resource,resource_trade_status status)130 void city_resource_cycle_trade_status(resource_type resource, resource_trade_status status)
131 {
132 if (status == TRADE_STATUS_IMPORT && !empire_can_import_resource(resource)) {
133 city_data.resource.trade_status[resource] &= ~TRADE_STATUS_IMPORT;
134 return;
135 }
136 if (status == TRADE_STATUS_EXPORT && !empire_can_export_resource(resource)) {
137 city_data.resource.trade_status[resource] &= ~TRADE_STATUS_EXPORT;
138 return;
139 }
140 city_data.resource.trade_status[resource] ^= status;
141
142 if (city_data.resource.trade_status[resource] & TRADE_STATUS_EXPORT) {
143 city_data.resource.stockpiled[resource] = 0;
144 }
145 }
146
city_resource_import_over(resource_type resource)147 int city_resource_import_over(resource_type resource)
148 {
149 return city_data.resource.import_over[resource];
150 }
151
city_resource_change_import_over(resource_type resource,int change)152 void city_resource_change_import_over(resource_type resource, int change)
153 {
154 city_data.resource.import_over[resource] = calc_bound(city_data.resource.import_over[resource] + change, 0, 100);
155 }
156
city_resource_export_over(resource_type resource)157 int city_resource_export_over(resource_type resource)
158 {
159 return city_data.resource.export_over[resource];
160 }
161
city_resource_change_export_over(resource_type resource,int change)162 void city_resource_change_export_over(resource_type resource, int change)
163 {
164 city_data.resource.export_over[resource] = calc_bound(city_data.resource.export_over[resource] + change, 0, 100);
165 }
166
city_resource_is_stockpiled(resource_type resource)167 int city_resource_is_stockpiled(resource_type resource)
168 {
169 return city_data.resource.stockpiled[resource];
170 }
171
city_resource_toggle_stockpiled(resource_type resource)172 void city_resource_toggle_stockpiled(resource_type resource)
173 {
174 if (city_data.resource.stockpiled[resource]) {
175 city_data.resource.stockpiled[resource] = 0;
176 city_data.resource.trade_status[resource] |= city_data.resource.export_status_before_stockpiling[resource];
177 } else {
178 city_data.resource.stockpiled[resource] = 1;
179 city_data.resource.export_status_before_stockpiling[resource] = city_data.resource.trade_status[resource] & TRADE_STATUS_EXPORT;
180 city_data.resource.trade_status[resource] &= ~TRADE_STATUS_EXPORT;
181 }
182 }
183
city_resource_is_mothballed(resource_type resource)184 int city_resource_is_mothballed(resource_type resource)
185 {
186 return city_data.resource.mothballed[resource];
187 }
188
city_resource_toggle_mothballed(resource_type resource)189 void city_resource_toggle_mothballed(resource_type resource)
190 {
191 city_data.resource.mothballed[resource] = city_data.resource.mothballed[resource] ? 0 : 1;
192 }
193
city_resource_has_workshop_with_room(int workshop_type)194 int city_resource_has_workshop_with_room(int workshop_type)
195 {
196 return city_data.resource.space_in_workshops[workshop_type] > 0;
197 }
198
city_resource_add_produced_to_granary(int amount)199 void city_resource_add_produced_to_granary(int amount)
200 {
201 city_data.resource.food_produced_this_month += amount;
202 }
203
city_resource_add_to_granary(resource_type food,int amount)204 void city_resource_add_to_granary(resource_type food, int amount)
205 {
206 city_data.resource.granary_food_stored[food] += amount;
207 }
208
city_resource_remove_from_granary(resource_type food,int amount)209 void city_resource_remove_from_granary(resource_type food, int amount)
210 {
211 city_data.resource.granary_food_stored[food] -= amount;
212 }
213
city_resource_add_to_warehouse(resource_type resource,int amount)214 void city_resource_add_to_warehouse(resource_type resource, int amount)
215 {
216 city_data.resource.space_in_warehouses[resource] -= amount;
217 city_data.resource.stored_in_warehouses[resource] += amount;
218 }
219
city_resource_remove_from_warehouse(resource_type resource,int amount)220 void city_resource_remove_from_warehouse(resource_type resource, int amount)
221 {
222 city_data.resource.space_in_warehouses[resource] += amount;
223 city_data.resource.stored_in_warehouses[resource] -= amount;
224 }
225
city_resource_calculate_warehouse_stocks(void)226 void city_resource_calculate_warehouse_stocks(void)
227 {
228 for (int i = 0; i < RESOURCE_MAX; i++) {
229 city_data.resource.space_in_warehouses[i] = 0;
230 city_data.resource.stored_in_warehouses[i] = 0;
231 }
232 for (building *b = building_first_of_type(BUILDING_WAREHOUSE); b; b = b->next_of_type) {
233 if (b->state == BUILDING_STATE_IN_USE) {
234 b->has_road_access = 0;
235 if (map_has_road_access_rotation(b->subtype.orientation, b->x, b->y, b->size, 0)) {
236 b->has_road_access = 1;
237 } else if (map_has_road_access_rotation(b->subtype.orientation, b->x, b->y, 3, 0)) {
238 b->has_road_access = 2;
239 }
240 }
241 }
242 for (building *b = building_first_of_type(BUILDING_WAREHOUSE_SPACE); b; b = b->next_of_type) {
243 if (b->state != BUILDING_STATE_IN_USE) {
244 continue;
245 }
246 building *warehouse = building_main(b);
247 if (warehouse->state != BUILDING_STATE_IN_USE || warehouse->type != BUILDING_WAREHOUSE) {
248 continue;
249 }
250 if (warehouse->has_road_access) {
251 b->has_road_access = warehouse->has_road_access;
252 if (b->subtype.warehouse_resource_id) {
253 int loads = b->loads_stored;
254 int resource = b->subtype.warehouse_resource_id;
255 city_data.resource.stored_in_warehouses[resource] += loads;
256 city_data.resource.space_in_warehouses[resource] += 4 - loads;
257 } else {
258 city_data.resource.space_in_warehouses[RESOURCE_NONE] += 4;
259 }
260 }
261 }
262 }
263
city_resource_determine_available(void)264 void city_resource_determine_available(void)
265 {
266 for (int i = 0; i < RESOURCE_MAX; i++) {
267 available.resource_list.items[i] = 0;
268 available.food_list.items[i] = 0;
269 potential.resource_list.items[i] = 0;
270 potential.food_list.items[i] = 0;
271 }
272 available.resource_list.size = 0;
273 available.food_list.size = 0;
274 potential.resource_list.size = 0;
275 potential.food_list.size = 0;
276
277 for (int i = RESOURCE_MIN; i < RESOURCE_MAX; i++) {
278 if (empire_can_produce_resource(i) || empire_can_import_resource(i) ||
279 (i == RESOURCE_MEAT && scenario_building_allowed(BUILDING_WHARF))) {
280 available.resource_list.items[available.resource_list.size++] = i;
281 potential.resource_list.items[potential.resource_list.size++] = i;
282 } else if (empire_can_produce_resource_potentially(i) || empire_can_import_resource_potentially(i)) {
283 potential.resource_list.items[potential.resource_list.size++] = i;
284 }
285 }
286 for (int i = RESOURCE_MIN_FOOD; i < RESOURCE_MAX_FOOD; i++) {
287 if (i == RESOURCE_OLIVES || i == RESOURCE_VINES) {
288 continue;
289 }
290 if (empire_can_produce_resource(i) || empire_can_import_resource(i) ||
291 (i == RESOURCE_MEAT && scenario_building_allowed(BUILDING_WHARF))) {
292 available.food_list.items[available.food_list.size++] = i;
293 potential.food_list.items[potential.food_list.size++] = i;
294 } else if (empire_can_produce_resource_potentially(i) || empire_can_import_resource_potentially(i)) {
295 potential.food_list.items[potential.food_list.size++] = i;
296 }
297 }
298 }
299
city_resource_ceres_temple_food(void)300 int city_resource_ceres_temple_food(void)
301 {
302 // locally produced
303 for (int i = RESOURCE_MIN_FOOD; i < RESOURCE_MAX_FOOD; i++) {
304 if (i == RESOURCE_OLIVES || i == RESOURCE_VINES) {
305 continue;
306 }
307 if (can_produce_resource(i)) {
308 return i;
309 }
310 }
311
312 // imported, if no food is locally produced
313 for (int i = RESOURCE_MIN_FOOD; i < RESOURCE_MAX_FOOD; i++) {
314 if (i == RESOURCE_OLIVES || i == RESOURCE_VINES) {
315 continue;
316 }
317 if (empire_can_import_resource_potentially(i)) {
318 return i;
319 }
320 }
321
322 return RESOURCE_NONE;
323 }
324
calculate_available_food(void)325 static void calculate_available_food(void)
326 {
327 for (int i = 0; i < RESOURCE_MAX_FOOD; i++) {
328 city_data.resource.granary_food_stored[i] = 0;
329 }
330 city_data.resource.granary_total_stored = 0;
331 city_data.resource.food_types_available = 0;
332 city_data.resource.food_supply_months = 0;
333 city_data.resource.granaries.operating = 0;
334 city_data.resource.granaries.understaffed = 0;
335 city_data.resource.granaries.not_operating = 0;
336 city_data.resource.granaries.not_operating_with_food = 0;
337 for (building *b = building_first_of_type(BUILDING_GRANARY); b; b = b->next_of_type) {
338 if (b->state != BUILDING_STATE_IN_USE) {
339 continue;
340 }
341 b->has_road_access = 0;
342 if (map_has_road_access_granary(b->x, b->y, 0)) {
343 b->has_road_access = 1;
344 int pct_workers = calc_percentage(
345 b->num_workers, model_get_building(b->type)->laborers);
346 if (pct_workers < 100) {
347 city_data.resource.granaries.understaffed++;
348 }
349 int amount_stored = 0;
350 for (int r = RESOURCE_MIN_FOOD; r < RESOURCE_MAX_FOOD; r++) {
351 amount_stored += b->data.granary.resource_stored[r];
352 }
353 if (pct_workers < 50) {
354 city_data.resource.granaries.not_operating++;
355 if (amount_stored > 0) {
356 city_data.resource.granaries.not_operating_with_food++;
357 }
358 } else {
359 city_data.resource.granaries.operating++;
360 for (int r = 0; r < RESOURCE_MAX_FOOD; r++) {
361 city_data.resource.granary_food_stored[r] += b->data.granary.resource_stored[r];
362 }
363 if (amount_stored > 400) {
364 tutorial_on_filled_granary();
365 }
366 }
367 }
368 }
369 for (int i = RESOURCE_MIN_FOOD; i < RESOURCE_MAX_FOOD; i++) {
370 if (city_data.resource.granary_food_stored[i]) {
371 city_data.resource.granary_total_stored += city_data.resource.granary_food_stored[i];
372 city_data.resource.food_types_available++;
373 }
374 }
375 city_data.resource.food_needed_per_month =
376 calc_adjust_with_percentage(city_data.population.population, 50);
377 if (city_data.resource.food_needed_per_month > 0) {
378 city_data.resource.food_supply_months =
379 city_data.resource.granary_total_stored / city_data.resource.food_needed_per_month;
380 } else {
381 city_data.resource.food_supply_months =
382 city_data.resource.granary_total_stored > 0 ? 1 : 0;
383 }
384 if (scenario_property_rome_supplies_wheat()) {
385 city_data.resource.food_types_available = 1;
386 city_data.resource.food_supply_months = 12;
387 }
388 }
389
city_resource_calculate_food_stocks_and_supply_wheat(void)390 void city_resource_calculate_food_stocks_and_supply_wheat(void)
391 {
392 calculate_available_food();
393 if (scenario_property_rome_supplies_wheat()) {
394 building_type supplied_buildings[] = { BUILDING_MARKET, BUILDING_MESS_HALL };
395 for (int i = 0; i < 2; i++) {
396 building_type type = supplied_buildings[i];
397 for (building *b = building_first_of_type(type); b; b = b->next_of_type) {
398 if (b->state == BUILDING_STATE_IN_USE) {
399 b->data.market.inventory[INVENTORY_WHEAT] = 200;
400 }
401 }
402 }
403 }
404 }
405
city_resource_calculate_workshop_stocks(void)406 void city_resource_calculate_workshop_stocks(void)
407 {
408 for (int i = 0; i < 6; i++) {
409 city_data.resource.stored_in_workshops[i] = 0;
410 city_data.resource.space_in_workshops[i] = 0;
411 }
412 for (building_type type = BUILDING_WINE_WORKSHOP; type <= BUILDING_POTTERY_WORKSHOP; type++) {
413 for (building *b = building_first_of_type(type); b; b = b->next_of_type) {
414 if (b->state != BUILDING_STATE_IN_USE) {
415 continue;
416 }
417 b->has_road_access = 0;
418 if (map_has_road_access(b->x, b->y, b->size, 0)) {
419 b->has_road_access = 1;
420 int room = 2 - b->loads_stored;
421 if (room < 0) {
422 room = 0;
423 }
424 int workshop_resource = b->subtype.workshop_type;
425 city_data.resource.space_in_workshops[workshop_resource] += room;
426 city_data.resource.stored_in_workshops[workshop_resource] += b->loads_stored;
427 }
428 }
429 }
430 }
431
house_consume_food(void)432 static int house_consume_food(void)
433 {
434 int total_consumed = 0;
435 int ceres_module = (building_monument_gt_module_is_active(CERES_MODULE_1_REDUCE_FOOD));
436 for (building_type type = BUILDING_HOUSE_SMALL_TENT; type <= BUILDING_HOUSE_LUXURY_PALACE; type++) {
437 for (building *b = building_first_of_type(type); b; b = b->next_of_type) {
438 if (b->state != BUILDING_STATE_IN_USE || !b->house_size) {
439 continue;
440 }
441 int num_types = model_get_house(b->subtype.house_level)->food_types;
442 int amount_per_type;
443 if (ceres_module && b->data.house.temple_ceres) {
444 amount_per_type = calc_adjust_with_percentage(b->house_population, 40);
445 } else {
446 amount_per_type = calc_adjust_with_percentage(b->house_population, 50);
447 }
448 int foodtypes_available = 0;
449 for (int i = INVENTORY_MIN_FOOD; i < INVENTORY_MAX_FOOD; i++) {
450 if (b->data.house.inventory[i]) {
451 foodtypes_available++;
452 }
453 }
454 if (foodtypes_available) {
455 amount_per_type /= foodtypes_available;
456 }
457
458 b->data.house.num_foods = 0;
459 if (scenario_property_rome_supplies_wheat()) {
460 city_data.resource.food_types_eaten = 1;
461 city_data.resource.food_types_available = 1;
462 b->data.house.inventory[INVENTORY_WHEAT] = amount_per_type;
463 b->data.house.num_foods = 1;
464 } else if (num_types > 0) {
465 for (int t = INVENTORY_MIN_FOOD; t < INVENTORY_MAX_FOOD; t++) {
466 if (b->data.house.inventory[t] >= amount_per_type) {
467 b->data.house.inventory[t] -= amount_per_type;
468 b->data.house.num_foods++;
469 total_consumed += amount_per_type;
470 } else if (b->data.house.inventory[t]) {
471 // has food but not enough
472 b->data.house.inventory[t] = 0;
473 b->data.house.num_foods++;
474 total_consumed += amount_per_type;
475 }
476 if (b->data.house.num_foods > city_data.resource.food_types_eaten) {
477 city_data.resource.food_types_eaten = b->data.house.num_foods;
478 }
479 }
480 }
481 }
482 }
483 return total_consumed;
484 }
485
mess_hall_consume_food(void)486 static int mess_hall_consume_food(void)
487 {
488 int total_consumed = 0;
489 building *b = building_first_of_type(BUILDING_MESS_HALL);
490 if (!b || b->state != BUILDING_STATE_IN_USE) {
491 return 0;
492 };
493 int food_required = city_military_total_soldiers_in_city() *
494 difficulty_adjust_soldier_food_consumption(FOOD_PER_SOLDIER_MONTHLY);
495 int num_foods = 0;
496 int total_food_in_mess_hall = 0;
497 int proportionate_amount = 0;
498 int amount_for_type = 0;
499
500 for (int i = INVENTORY_MIN_FOOD; i < INVENTORY_MAX_FOOD; ++i) {
501 total_food_in_mess_hall += b->data.market.inventory[i];
502 }
503
504 city_data.mess_hall.total_food = total_food_in_mess_hall;
505 if (!food_required) {
506 return 0;
507 }
508
509 if (total_food_in_mess_hall > 0) {
510 for (int i = INVENTORY_MIN_FOOD; i < INVENTORY_MAX_FOOD; ++i) {
511 proportionate_amount = food_required * b->data.market.inventory[i] / total_food_in_mess_hall;
512 if (proportionate_amount > 0) {
513 amount_for_type = calc_bound((int) ceil(proportionate_amount), 0, b->data.market.inventory[i]);
514 b->data.market.inventory[i] -= amount_for_type;
515 ++num_foods;
516 }
517 }
518 }
519
520 if (food_required > total_food_in_mess_hall) {
521 city_data.mess_hall.food_percentage_missing_this_month = 100 -
522 calc_percentage(total_food_in_mess_hall, food_required);
523 total_consumed += total_food_in_mess_hall;
524 city_data.mess_hall.total_food = 0;
525 } else {
526 city_data.mess_hall.food_percentage_missing_this_month = 0;
527 total_consumed += food_required;
528 city_data.mess_hall.total_food -= food_required;
529 }
530
531 city_data.mess_hall.food_types = num_foods;
532
533 return total_consumed;
534 }
535
caravanserai_consume_food(void)536 static int caravanserai_consume_food(void)
537 {
538 if (!building_monument_working(BUILDING_CARAVANSERAI)) {
539 return 0;
540 }
541 int food_required = trade_caravan_count() * FOOD_PER_TRADER_MONTHLY;
542
543 trade_policy policy = city_trade_policy_get(LAND_TRADE_POLICY);
544
545 if (policy == TRADE_POLICY_3) { // consume 20% more
546 food_required = calc_adjust_with_percentage(food_required, 100 + POLICY_3_MALUS_PERCENT);
547 }
548
549 int total_consumed = 0;
550 building *b = building_first_of_type(BUILDING_CARAVANSERAI);
551 if (!b) {
552 return 0;
553 }
554
555 int total_food_in_caravanserai = 0;
556 int proportionate_amount = 0;
557 int amount_for_type = 0;
558
559 for (int i = INVENTORY_MIN_FOOD; i < INVENTORY_MAX_FOOD; ++i) {
560 total_food_in_caravanserai += b->data.market.inventory[i];
561 }
562
563 city_data.caravanserai.total_food = total_food_in_caravanserai;
564
565
566 if (!food_required || !total_food_in_caravanserai) {
567 return 0;
568 }
569
570 for (int i = INVENTORY_MIN_FOOD; i < INVENTORY_MAX_FOOD; ++i) {
571 proportionate_amount = food_required * b->data.market.inventory[i] / total_food_in_caravanserai;
572 if (proportionate_amount > 0) {
573 amount_for_type = calc_bound(proportionate_amount, 0, b->data.market.inventory[i]);
574 b->data.market.inventory[i] -= amount_for_type;
575 }
576 }
577
578 if (food_required > total_food_in_caravanserai) {
579 total_consumed += total_food_in_caravanserai;
580 city_data.caravanserai.total_food = 0;
581 } else {
582 total_consumed += food_required;
583 city_data.caravanserai.total_food -= food_required;
584 }
585
586 return total_consumed;
587 }
588
city_resource_consume_food(void)589 void city_resource_consume_food(void)
590 {
591 calculate_available_food();
592 city_data.resource.food_types_eaten = 0;
593
594 int total_consumed = house_consume_food() + mess_hall_consume_food() + caravanserai_consume_food();
595
596 if (city_military_total_soldiers_in_city() > 0 && !city_data.building.mess_hall_building_id &&
597 !city_data.mess_hall.missing_mess_hall_warning_shown) {
598 city_data.mess_hall.food_percentage_missing_this_month = 100;
599 city_message_post(1, MESSAGE_SOLDIERS_STARVING_NO_MESS_HALL, 0, 0);
600 city_data.mess_hall.missing_mess_hall_warning_shown = 1;
601 } else if (city_military_total_soldiers_in_city() > 0 && city_data.mess_hall.food_stress_cumulative > 50 &&
602 !city_data.mess_hall.mess_hall_warning_shown) {
603 city_message_post(1, MESSAGE_SOLDIERS_STARVING, 0, 0);
604 city_data.mess_hall.mess_hall_warning_shown = 1;
605 }
606
607 city_data.mess_hall.food_stress_cumulative = ((city_data.mess_hall.food_percentage_missing_this_month +
608 city_data.mess_hall.food_stress_cumulative) / 2);
609 if (city_data.mess_hall.food_stress_cumulative < 20) {
610 city_data.mess_hall.mess_hall_warning_shown = 0;
611 }
612
613 if (city_data.mess_hall.food_stress_cumulative > 100) {
614 city_data.mess_hall.food_stress_cumulative = 100;
615 }
616
617 city_data.resource.food_consumed_last_month = total_consumed;
618 city_data.resource.food_produced_last_month = city_data.resource.food_produced_this_month;
619 city_data.resource.food_produced_this_month = 0;
620 }
621