1 #include "house_evolution.h"
2
3 #include "building/house.h"
4 #include "building/model.h"
5 #include "building/monument.h"
6 #include "city/houses.h"
7 #include "city/resource.h"
8 #include "core/calc.h"
9 #include "core/time.h"
10 #include "game/resource.h"
11 #include "game/time.h"
12 #include "game/undo.h"
13 #include "map/building.h"
14 #include "map/grid.h"
15 #include "map/routing_terrain.h"
16 #include "map/tiles.h"
17
18 #define DEVOLVE_DELAY 2
19 #define DEVOLVE_DELAY_WITH_VENUS 20
20
21 typedef enum {
22 EVOLVE = 1,
23 NONE = 0,
24 DEVOLVE = -1
25 } evolve_status;
26
27 static int active_devolve_delay;
28
check_evolve_desirability(building * house,int bonus)29 static int check_evolve_desirability(building *house, int bonus)
30 {
31 int level = house->subtype.house_level;
32 level -= bonus;
33 level = calc_bound(level, HOUSE_MIN, HOUSE_MAX);
34 const model_house *model = model_get_house(level);
35 int evolve_des = model->evolve_desirability;
36 if (level >= HOUSE_LUXURY_PALACE) {
37 evolve_des = 1000;
38 }
39 int current_des = house->desirability;
40 int status;
41 if (current_des <= model->devolve_desirability) {
42 status = DEVOLVE;
43 } else if (current_des >= evolve_des) {
44 status = EVOLVE;
45 } else {
46 status = NONE;
47 }
48 house->data.house.evolve_text_id = status; // BUG? -1 in an unsigned char?
49 return status;
50 }
51
has_required_goods_and_services(building * house,int for_upgrade,int with_bonus,house_demands * demands)52 static int has_required_goods_and_services(building *house, int for_upgrade, int with_bonus, house_demands *demands)
53 {
54 int level = house->subtype.house_level;
55 if (for_upgrade) {
56 ++level;
57 }
58 if (with_bonus) {
59 --level;
60 }
61 level = calc_bound(level, HOUSE_MIN, HOUSE_MAX);
62 const model_house *model = model_get_house(level);
63 // water
64 int water = model->water;
65 if (!house->has_water_access) {
66 if (water >= 2) {
67 ++demands->missing.fountain;
68 return 0;
69 }
70 if (water == 1 && !house->has_well_access) {
71 ++demands->missing.well;
72 return 0;
73 }
74 }
75 // entertainment
76 int entertainment = model->entertainment;
77 if (house->data.house.entertainment < entertainment) {
78 if (house->data.house.entertainment) {
79 ++demands->missing.more_entertainment;
80 } else {
81 ++demands->missing.entertainment;
82 }
83 return 0;
84 }
85 // education
86 int education = model->education;
87 if (house->data.house.education < education) {
88 if (house->data.house.education) {
89 ++demands->missing.more_education;
90 } else {
91 ++demands->missing.education;
92 }
93 return 0;
94 }
95 if (education == 2) {
96 ++demands->requiring.school;
97 ++demands->requiring.library;
98 } else if (education == 1) {
99 ++demands->requiring.school;
100 }
101 // religion
102 int religion = model->religion;
103 if (house->data.house.num_gods < religion) {
104 if (religion == 1) {
105 ++demands->missing.religion;
106 return 0;
107 } else if (religion == 2) {
108 ++demands->missing.second_religion;
109 return 0;
110 } else if (religion == 3) {
111 ++demands->missing.third_religion;
112 return 0;
113 }
114 } else if (religion > 0) {
115 ++demands->requiring.religion;
116 }
117 // barber
118 int barber = model->barber;
119 if (house->data.house.barber < barber) {
120 ++demands->missing.barber;
121 return 0;
122 }
123 if (barber == 1) {
124 ++demands->requiring.barber;
125 }
126 // bathhouse
127 int bathhouse = model->bathhouse;
128 if (house->data.house.bathhouse < bathhouse) {
129 ++demands->missing.bathhouse;
130 return 0;
131 }
132 if (bathhouse == 1) {
133 ++demands->requiring.bathhouse;
134 }
135 // health
136 int health = model->health;
137 if (house->data.house.health < health) {
138 if (health < 2) {
139 ++demands->missing.clinic;
140 } else {
141 ++demands->missing.hospital;
142 }
143 return 0;
144 }
145 if (health >= 1) {
146 ++demands->requiring.clinic;
147 }
148 // food types
149 int foodtypes_required = model->food_types;
150 int foodtypes_available = 0;
151 for (int i = INVENTORY_MIN_FOOD; i < INVENTORY_MAX_FOOD; i++) {
152 if (house->data.house.inventory[i]) {
153 foodtypes_available++;
154 }
155 }
156 if (foodtypes_available < foodtypes_required) {
157 ++demands->missing.food;
158 return 0;
159 }
160 // goods
161 if (house->data.house.inventory[INVENTORY_POTTERY] < model->pottery) {
162 return 0;
163 }
164 if (house->data.house.inventory[INVENTORY_OIL] < model->oil) {
165 return 0;
166 }
167 if (house->data.house.inventory[INVENTORY_FURNITURE] < model->furniture) {
168 return 0;
169 }
170 int wine = model->wine;
171 if (wine && house->data.house.inventory[INVENTORY_WINE] <= 0) {
172 return 0;
173 }
174 if (wine > 1 && !city_resource_multiple_wine_available()) {
175 ++demands->missing.second_wine;
176 return 0;
177 }
178 return 1;
179 }
180
check_requirements(building * house,house_demands * demands)181 static int check_requirements(building *house, house_demands *demands)
182 {
183 int bonus = 0;
184 if (building_monument_pantheon_module_is_active(PANTHEON_MODULE_2_HOUSING_EVOLUTION) && house->house_pantheon_access) {
185 bonus++;
186 }
187 int status = check_evolve_desirability(house, bonus);
188 if (!has_required_goods_and_services(house, 0, bonus, demands)) {
189 status = DEVOLVE;
190 } else if (status == EVOLVE) {
191 status = has_required_goods_and_services(house, 1, bonus, demands);
192 }
193 return status;
194 }
195
has_devolve_delay(building * house,evolve_status status)196 static int has_devolve_delay(building *house, evolve_status status)
197 {
198 if (status == DEVOLVE && house->data.house.devolve_delay < active_devolve_delay) {
199 house->data.house.devolve_delay++;
200 return 1;
201 } else {
202 house->data.house.devolve_delay = 0;
203 return 0;
204 }
205 }
206
evolve_small_tent(building * house,house_demands * demands)207 static int evolve_small_tent(building *house, house_demands *demands)
208 {
209 if (house->house_population > 0) {
210 building_house_merge(house);
211 evolve_status status = check_requirements(house, demands);
212 if (status == EVOLVE) {
213 building_house_change_to(house, BUILDING_HOUSE_LARGE_TENT);
214 }
215 }
216 return 0;
217 }
218
evolve_large_tent(building * house,house_demands * demands)219 static int evolve_large_tent(building *house, house_demands *demands)
220 {
221 if (house->house_population > 0) {
222 building_house_merge(house);
223 evolve_status status = check_requirements(house, demands);
224 if (!has_devolve_delay(house, status)) {
225 if (status == EVOLVE) {
226 building_house_change_to(house, BUILDING_HOUSE_SMALL_SHACK);
227 } else if (status == DEVOLVE) {
228 building_house_change_to(house, BUILDING_HOUSE_SMALL_TENT);
229 }
230 }
231 }
232 return 0;
233 }
234
evolve_small_shack(building * house,house_demands * demands)235 static int evolve_small_shack(building *house, house_demands *demands)
236 {
237 building_house_merge(house);
238 int status = check_requirements(house, demands);
239 if (!has_devolve_delay(house, status)) {
240 if (status == EVOLVE) {
241 building_house_change_to(house, BUILDING_HOUSE_LARGE_SHACK);
242 } else if (status == DEVOLVE) {
243 building_house_change_to(house, BUILDING_HOUSE_LARGE_TENT);
244 }
245 }
246 return 0;
247 }
248
evolve_large_shack(building * house,house_demands * demands)249 static int evolve_large_shack(building *house, house_demands *demands)
250 {
251 building_house_merge(house);
252 int status = check_requirements(house, demands);
253 if (!has_devolve_delay(house, status)) {
254 if (status == EVOLVE) {
255 building_house_change_to(house, BUILDING_HOUSE_SMALL_HOVEL);
256 } else if (status == DEVOLVE) {
257 building_house_change_to(house, BUILDING_HOUSE_SMALL_SHACK);
258 }
259 }
260 return 0;
261 }
262
evolve_small_hovel(building * house,house_demands * demands)263 static int evolve_small_hovel(building *house, house_demands *demands)
264 {
265 building_house_merge(house);
266 int status = check_requirements(house, demands);
267 if (!has_devolve_delay(house, status)) {
268 if (status == EVOLVE) {
269 building_house_change_to(house, BUILDING_HOUSE_LARGE_HOVEL);
270 } else if (status == DEVOLVE) {
271 building_house_change_to(house, BUILDING_HOUSE_LARGE_SHACK);
272 }
273 }
274 return 0;
275 }
276
evolve_large_hovel(building * house,house_demands * demands)277 static int evolve_large_hovel(building *house, house_demands *demands)
278 {
279 building_house_merge(house);
280 int status = check_requirements(house, demands);
281 if (!has_devolve_delay(house, status)) {
282 if (status == EVOLVE) {
283 building_house_change_to(house, BUILDING_HOUSE_SMALL_CASA);
284 } else if (status == DEVOLVE) {
285 building_house_change_to(house, BUILDING_HOUSE_SMALL_HOVEL);
286 }
287 }
288 return 0;
289 }
290
evolve_small_casa(building * house,house_demands * demands)291 static int evolve_small_casa(building *house, house_demands *demands)
292 {
293 building_house_merge(house);
294 int status = check_requirements(house, demands);
295 if (!has_devolve_delay(house, status)) {
296 if (status == EVOLVE) {
297 building_house_change_to(house, BUILDING_HOUSE_LARGE_CASA);
298 } else if (status == DEVOLVE) {
299 building_house_change_to(house, BUILDING_HOUSE_LARGE_HOVEL);
300 }
301 }
302 return 0;
303 }
304
evolve_large_casa(building * house,house_demands * demands)305 static int evolve_large_casa(building *house, house_demands *demands)
306 {
307 building_house_merge(house);
308 int status = check_requirements(house, demands);
309 if (!has_devolve_delay(house, status)) {
310 if (status == EVOLVE) {
311 building_house_change_to(house, BUILDING_HOUSE_SMALL_INSULA);
312 } else if (status == DEVOLVE) {
313 building_house_change_to(house, BUILDING_HOUSE_SMALL_CASA);
314 }
315 }
316 return 0;
317 }
318
evolve_small_insula(building * house,house_demands * demands)319 static int evolve_small_insula(building *house, house_demands *demands)
320 {
321 building_house_merge(house);
322 int status = check_requirements(house, demands);
323 if (!has_devolve_delay(house, status)) {
324 if (status == EVOLVE) {
325 building_house_change_to(house, BUILDING_HOUSE_MEDIUM_INSULA);
326 } else if (status == DEVOLVE) {
327 building_house_change_to(house, BUILDING_HOUSE_LARGE_CASA);
328 }
329 }
330 return 0;
331 }
332
evolve_medium_insula(building * house,house_demands * demands)333 static int evolve_medium_insula(building *house, house_demands *demands)
334 {
335 building_house_merge(house);
336 int status = check_requirements(house, demands);
337 if (!has_devolve_delay(house, status)) {
338 if (status == EVOLVE) {
339 if (building_house_can_expand(house, 4)) {
340 game_undo_disable();
341 house->house_is_merged = 0;
342 building_house_expand_to_large_insula(house);
343 map_tiles_update_all_gardens();
344 return 1;
345 }
346 } else if (status == DEVOLVE) {
347 building_house_change_to(house, BUILDING_HOUSE_SMALL_INSULA);
348 }
349 }
350 return 0;
351 }
352
evolve_large_insula(building * house,house_demands * demands)353 static int evolve_large_insula(building *house, house_demands *demands)
354 {
355 int status = check_requirements(house, demands);
356 if (!has_devolve_delay(house, status)) {
357 if (status == EVOLVE) {
358 building_house_change_to(house, BUILDING_HOUSE_GRAND_INSULA);
359 } else if (status == DEVOLVE) {
360 game_undo_disable();
361 building_house_devolve_from_large_insula(house);
362 }
363 }
364 return 0;
365 }
366
evolve_grand_insula(building * house,house_demands * demands)367 static int evolve_grand_insula(building *house, house_demands *demands)
368 {
369 int status = check_requirements(house, demands);
370 if (!has_devolve_delay(house, status)) {
371 if (status == EVOLVE) {
372 building_house_change_to(house, BUILDING_HOUSE_SMALL_VILLA);
373 } else if (status == DEVOLVE) {
374 building_house_change_to(house, BUILDING_HOUSE_LARGE_INSULA);
375 }
376 }
377 return 0;
378 }
379
evolve_small_villa(building * house,house_demands * demands)380 static int evolve_small_villa(building *house, house_demands *demands)
381 {
382 int status = check_requirements(house, demands);
383 if (!has_devolve_delay(house, status)) {
384 if (status == EVOLVE) {
385 building_house_change_to(house, BUILDING_HOUSE_MEDIUM_VILLA);
386 } else if (status == DEVOLVE) {
387 building_house_change_to(house, BUILDING_HOUSE_GRAND_INSULA);
388 }
389 }
390 return 0;
391 }
392
evolve_medium_villa(building * house,house_demands * demands)393 static int evolve_medium_villa(building *house, house_demands *demands)
394 {
395 int status = check_requirements(house, demands);
396 if (!has_devolve_delay(house, status)) {
397 if (status == EVOLVE) {
398 if (building_house_can_expand(house, 9)) {
399 game_undo_disable();
400 building_house_expand_to_large_villa(house);
401 map_tiles_update_all_gardens();
402 return 1;
403 }
404 } else if (status == DEVOLVE) {
405 building_house_change_to(house, BUILDING_HOUSE_SMALL_VILLA);
406 }
407 }
408 return 0;
409 }
410
evolve_large_villa(building * house,house_demands * demands)411 static int evolve_large_villa(building *house, house_demands *demands)
412 {
413 int status = check_requirements(house, demands);
414 if (!has_devolve_delay(house, status)) {
415 if (status == EVOLVE) {
416 building_house_change_to(house, BUILDING_HOUSE_GRAND_VILLA);
417 } else if (status == DEVOLVE) {
418 game_undo_disable();
419 building_house_devolve_from_large_villa(house);
420 }
421 }
422 return 0;
423 }
424
evolve_grand_villa(building * house,house_demands * demands)425 static int evolve_grand_villa(building *house, house_demands *demands)
426 {
427 int status = check_requirements(house, demands);
428 if (!has_devolve_delay(house, status)) {
429 if (status == EVOLVE) {
430 building_house_change_to(house, BUILDING_HOUSE_SMALL_PALACE);
431 } else if (status == DEVOLVE) {
432 building_house_change_to(house, BUILDING_HOUSE_LARGE_VILLA);
433 }
434 }
435 return 0;
436 }
437
evolve_small_palace(building * house,house_demands * demands)438 static int evolve_small_palace(building *house, house_demands *demands)
439 {
440 int status = check_requirements(house, demands);
441 if (!has_devolve_delay(house, status)) {
442 if (status == EVOLVE) {
443 building_house_change_to(house, BUILDING_HOUSE_MEDIUM_PALACE);
444 } else if (status == DEVOLVE) {
445 building_house_change_to(house, BUILDING_HOUSE_GRAND_VILLA);
446 }
447 }
448 return 0;
449 }
450
evolve_medium_palace(building * house,house_demands * demands)451 static int evolve_medium_palace(building *house, house_demands *demands)
452 {
453 int status = check_requirements(house, demands);
454 if (!has_devolve_delay(house, status)) {
455 if (status == EVOLVE) {
456 if (building_house_can_expand(house, 16)) {
457 game_undo_disable();
458 building_house_expand_to_large_palace(house);
459 map_tiles_update_all_gardens();
460 return 1;
461 }
462 } else if (status == DEVOLVE) {
463 building_house_change_to(house, BUILDING_HOUSE_SMALL_PALACE);
464 }
465 }
466 return 0;
467 }
468
evolve_large_palace(building * house,house_demands * demands)469 static int evolve_large_palace(building *house, house_demands *demands)
470 {
471 int status = check_requirements(house, demands);
472 if (!has_devolve_delay(house, status)) {
473 if (status == EVOLVE) {
474 building_house_change_to(house, BUILDING_HOUSE_LUXURY_PALACE);
475 } else if (status == DEVOLVE) {
476 game_undo_disable();
477 building_house_devolve_from_large_palace(house);
478 }
479 }
480 return 0;
481 }
482
evolve_luxury_palace(building * house,house_demands * demands)483 static int evolve_luxury_palace(building *house, house_demands *demands)
484 {
485 int bonus = (int) (building_monument_pantheon_module_is_active(PANTHEON_MODULE_2_HOUSING_EVOLUTION) && house->house_pantheon_access);
486 int status = check_evolve_desirability(house, bonus);
487 if (!has_required_goods_and_services(house, 0, bonus, demands)) {
488 status = DEVOLVE;
489 }
490 if (!has_devolve_delay(house, status) && status == DEVOLVE) {
491 building_house_change_to(house, BUILDING_HOUSE_LARGE_PALACE);
492 }
493 return 0;
494 }
495
consume_resource(building * b,int inventory,int amount)496 static void consume_resource(building *b, int inventory, int amount)
497 {
498 if (amount > 0) {
499 if (amount > b->data.house.inventory[inventory]) {
500 b->data.house.inventory[inventory] = 0;
501 } else {
502 b->data.house.inventory[inventory] -= amount;
503 }
504 }
505 }
506
consume_resources(building * b)507 static void consume_resources(building *b)
508 {
509 int consumption_reduction[INVENTORY_MAX] = { 0 };
510
511 // mercury module 1 - pottery and furniture reduced by 20%
512 if (building_monument_gt_module_is_active(MERCURY_MODULE_1_POTTERY_FURN)) {
513 consumption_reduction[INVENTORY_POTTERY] += 20;
514 consumption_reduction[INVENTORY_FURNITURE] += 20;
515 }
516 // mercury module 2 - oil and wine reduced by 20%
517 if (b->data.house.temple_mercury && building_monument_gt_module_is_active(MERCURY_MODULE_2_OIL_WINE)) {
518 consumption_reduction[INVENTORY_WINE] += 20;
519 consumption_reduction[INVENTORY_OIL] += 20;
520 }
521 // mars module 2 - all goods reduced by 10%
522 if (b->data.house.temple_mars && building_monument_gt_module_is_active(MARS_MODULE_2_ALL_GOODS)) {
523 consumption_reduction[INVENTORY_WINE] += 10;
524 consumption_reduction[INVENTORY_OIL] += 10;
525 consumption_reduction[INVENTORY_POTTERY] += 10;
526 consumption_reduction[INVENTORY_FURNITURE] += 10;
527 }
528
529 for (inventory_type inventory = INVENTORY_MIN_GOOD; inventory < INVENTORY_MAX_GOOD; inventory++) {
530 if (!consumption_reduction[inventory] ||
531 (game_time_total_months() % (100 / consumption_reduction[inventory]))) {
532 consume_resource(b, inventory, model_house_uses_inventory(b->subtype.house_level, inventory));
533 }
534 }
535 }
536
537 static int (*evolve_callback[])(building *, house_demands *) = {
538 evolve_small_tent, evolve_large_tent, evolve_small_shack, evolve_large_shack,
539 evolve_small_hovel, evolve_large_hovel, evolve_small_casa, evolve_large_casa,
540 evolve_small_insula, evolve_medium_insula, evolve_large_insula, evolve_grand_insula,
541 evolve_small_villa, evolve_medium_villa, evolve_large_villa, evolve_grand_villa,
542 evolve_small_palace, evolve_medium_palace, evolve_large_palace, evolve_luxury_palace
543 };
544
building_house_process_evolve_and_consume_goods(void)545 void building_house_process_evolve_and_consume_goods(void)
546 {
547 city_houses_reset_demands();
548 house_demands *demands = city_houses_demands();
549 int has_expanded = 0;
550
551 if (building_monument_working(BUILDING_GRAND_TEMPLE_VENUS)) {
552 active_devolve_delay = DEVOLVE_DELAY_WITH_VENUS;
553 } else {
554 active_devolve_delay = DEVOLVE_DELAY;
555 }
556
557 time_millis last_update = time_get_millis();
558
559 for (building_type type = BUILDING_HOUSE_VACANT_LOT; type <= BUILDING_HOUSE_LUXURY_PALACE; type++) {
560 building *next_of_type = 0; // evolve_callback changes the building type
561 for (building *b = building_first_of_type(type); b; b = next_of_type) {
562 next_of_type = b->next_of_type;
563 if (b->state != BUILDING_STATE_IN_USE || b->last_update == last_update) {
564 continue;
565 }
566 building_house_check_for_corruption(b);
567 has_expanded |= evolve_callback[b->type - BUILDING_HOUSE_VACANT_LOT](b, demands);
568 if (game_time_day() == 0 || game_time_day() == 7) {
569 consume_resources(b);
570 }
571 b->last_update = last_update;
572 }
573 }
574 if (has_expanded) {
575 map_routing_update_land();
576 }
577 }
578
building_house_determine_evolve_text(building * house,int worst_desirability_building)579 void building_house_determine_evolve_text(building *house, int worst_desirability_building)
580 {
581 int level = house->subtype.house_level;
582 if (building_monument_pantheon_module_is_active(PANTHEON_MODULE_2_HOUSING_EVOLUTION) && house->house_pantheon_access) {
583 level--;
584 }
585 level = calc_bound(level, HOUSE_MIN, HOUSE_MAX);
586
587 // this house will devolve soon because...
588
589 const model_house *model = model_get_house(level);
590 // desirability
591 if (house->desirability <= model->devolve_desirability) {
592 house->data.house.evolve_text_id = 0;
593 return;
594 }
595 // water
596 int water = model->water;
597 if (water == 1 && !house->has_water_access && !house->has_well_access) {
598 house->data.house.evolve_text_id = 1;
599 return;
600 }
601 if (water == 2 && !house->has_water_access) {
602 house->data.house.evolve_text_id = 2;
603 return;
604 }
605 // entertainment
606 int entertainment = model->entertainment;
607 if (house->data.house.entertainment < entertainment) {
608 if (!house->data.house.entertainment) {
609 house->data.house.evolve_text_id = 3;
610 } else if (entertainment < 10) {
611 house->data.house.evolve_text_id = 4;
612 } else if (entertainment < 25) {
613 house->data.house.evolve_text_id = 5;
614 } else if (entertainment < 50) {
615 house->data.house.evolve_text_id = 6;
616 } else if (entertainment < 80) {
617 house->data.house.evolve_text_id = 7;
618 } else {
619 house->data.house.evolve_text_id = 8;
620 }
621 return;
622 }
623 // food types
624 int foodtypes_required = model->food_types;
625 int foodtypes_available = 0;
626 for (int i = INVENTORY_MIN_FOOD; i < INVENTORY_MAX_FOOD; i++) {
627 if (house->data.house.inventory[i]) {
628 foodtypes_available++;
629 }
630 }
631 if (foodtypes_available < foodtypes_required) {
632 if (foodtypes_required == 1) {
633 house->data.house.evolve_text_id = 9;
634 return;
635 } else if (foodtypes_required == 2) {
636 house->data.house.evolve_text_id = 10;
637 return;
638 } else if (foodtypes_required == 3) {
639 house->data.house.evolve_text_id = 11;
640 return;
641 }
642 }
643 // education
644 int education = model->education;
645 if (house->data.house.education < education) {
646 if (education == 1) {
647 house->data.house.evolve_text_id = 14;
648 return;
649 } else if (education == 2) {
650 if (house->data.house.school) {
651 house->data.house.evolve_text_id = 15;
652 return;
653 } else if (house->data.house.library) {
654 house->data.house.evolve_text_id = 16;
655 return;
656 }
657 } else if (education == 3) {
658 house->data.house.evolve_text_id = 17;
659 return;
660 }
661 }
662 // bathhouse
663 if (house->data.house.bathhouse < model->bathhouse) {
664 house->data.house.evolve_text_id = 18;
665 return;
666 }
667 // pottery
668 if (house->data.house.inventory[INVENTORY_POTTERY] < model->pottery) {
669 house->data.house.evolve_text_id = 19;
670 return;
671 }
672 // religion
673 int religion = model->religion;
674 if (house->data.house.num_gods < religion) {
675 if (religion == 1) {
676 house->data.house.evolve_text_id = 20;
677 return;
678 } else if (religion == 2) {
679 house->data.house.evolve_text_id = 21;
680 return;
681 } else if (religion == 3) {
682 house->data.house.evolve_text_id = 22;
683 return;
684 }
685 }
686 // barber
687 if (house->data.house.barber < model->barber) {
688 house->data.house.evolve_text_id = 23;
689 return;
690 }
691 // health
692 int health = model->health;
693 if (house->data.house.health < health) {
694 if (health == 1) {
695 house->data.house.evolve_text_id = 24;
696 } else if (house->data.house.clinic) {
697 house->data.house.evolve_text_id = 25;
698 } else {
699 house->data.house.evolve_text_id = 26;
700 }
701 return;
702 }
703 // oil
704 if (house->data.house.inventory[INVENTORY_OIL] < model->oil) {
705 house->data.house.evolve_text_id = 27;
706 return;
707 }
708 // furniture
709 if (house->data.house.inventory[INVENTORY_FURNITURE] < model->furniture) {
710 house->data.house.evolve_text_id = 28;
711 return;
712 }
713 // wine
714 int wine = model->wine;
715 if (house->data.house.inventory[INVENTORY_WINE] < wine) {
716 house->data.house.evolve_text_id = 29;
717 return;
718 }
719 if (wine > 1 && !city_resource_multiple_wine_available()) {
720 house->data.house.evolve_text_id = 65;
721 return;
722 }
723 if (level >= HOUSE_LUXURY_PALACE) { // max level!
724 house->data.house.evolve_text_id = 60;
725 return;
726 }
727
728 // this house will evolve if ...
729
730 // desirability
731 if (house->desirability < model->evolve_desirability) {
732 if (worst_desirability_building) {
733 house->data.house.evolve_text_id = 62;
734 } else {
735 house->data.house.evolve_text_id = 30;
736 }
737 return;
738 }
739 model = model_get_house(++level);
740 // water
741 water = model->water;
742 if (water == 1 && !house->has_water_access && !house->has_well_access) {
743 house->data.house.evolve_text_id = 31;
744 return;
745 }
746 if (water == 2 && !house->has_water_access) {
747 house->data.house.evolve_text_id = 32;
748 return;
749 }
750 // entertainment
751 entertainment = model->entertainment;
752 if (house->data.house.entertainment < entertainment) {
753 if (!house->data.house.entertainment) {
754 house->data.house.evolve_text_id = 33;
755 } else if (entertainment < 10) {
756 house->data.house.evolve_text_id = 34;
757 } else if (entertainment < 25) {
758 house->data.house.evolve_text_id = 35;
759 } else if (entertainment < 50) {
760 house->data.house.evolve_text_id = 36;
761 } else if (entertainment < 80) {
762 house->data.house.evolve_text_id = 37;
763 } else {
764 house->data.house.evolve_text_id = 38;
765 }
766 return;
767 }
768 // food types
769 foodtypes_required = model->food_types;
770 if (foodtypes_available < foodtypes_required) {
771 if (foodtypes_required == 1) {
772 house->data.house.evolve_text_id = 39;
773 return;
774 } else if (foodtypes_required == 2) {
775 house->data.house.evolve_text_id = 40;
776 return;
777 } else if (foodtypes_required == 3) {
778 house->data.house.evolve_text_id = 41;
779 return;
780 }
781 }
782 // education
783 education = model->education;
784 if (house->data.house.education < education) {
785 if (education == 1) {
786 house->data.house.evolve_text_id = 44;
787 return;
788 } else if (education == 2) {
789 if (house->data.house.school) {
790 house->data.house.evolve_text_id = 45;
791 return;
792 } else if (house->data.house.library) {
793 house->data.house.evolve_text_id = 46;
794 return;
795 }
796 } else if (education == 3) {
797 house->data.house.evolve_text_id = 47;
798 return;
799 }
800 }
801 // bathhouse
802 if (house->data.house.bathhouse < model->bathhouse) {
803 house->data.house.evolve_text_id = 48;
804 return;
805 }
806 // pottery
807 if (house->data.house.inventory[INVENTORY_POTTERY] < model->pottery) {
808 house->data.house.evolve_text_id = 49;
809 return;
810 }
811 // religion
812 religion = model->religion;
813 if (house->data.house.num_gods < religion) {
814 if (religion == 1) {
815 house->data.house.evolve_text_id = 50;
816 return;
817 } else if (religion == 2) {
818 house->data.house.evolve_text_id = 51;
819 return;
820 } else if (religion == 3) {
821 house->data.house.evolve_text_id = 52;
822 return;
823 }
824 }
825 // barber
826 if (house->data.house.barber < model->barber) {
827 house->data.house.evolve_text_id = 53;
828 return;
829 }
830 // health
831 health = model->health;
832 if (house->data.house.health < health) {
833 if (health == 1) {
834 house->data.house.evolve_text_id = 54;
835 } else if (house->data.house.clinic) {
836 house->data.house.evolve_text_id = 55;
837 } else {
838 house->data.house.evolve_text_id = 56;
839 }
840 return;
841 }
842 // oil
843 if (house->data.house.inventory[INVENTORY_OIL] < model->oil) {
844 house->data.house.evolve_text_id = 57;
845 return;
846 }
847 // furniture
848 if (house->data.house.inventory[INVENTORY_FURNITURE] < model->furniture) {
849 house->data.house.evolve_text_id = 58;
850 return;
851 }
852 // wine
853 wine = model->wine;
854 if (house->data.house.inventory[INVENTORY_WINE] < wine) {
855 house->data.house.evolve_text_id = 59;
856 return;
857 }
858 if (wine > 1 && !city_resource_multiple_wine_available()) {
859 house->data.house.evolve_text_id = 66;
860 return;
861 }
862 // house is evolving
863 house->data.house.evolve_text_id = 61;
864 if (house->data.house.no_space_to_expand == 1) {
865 // house would like to evolve but can't
866 house->data.house.evolve_text_id = 64;
867 }
868 }
869
building_house_determine_worst_desirability_building(const building * house)870 int building_house_determine_worst_desirability_building(const building *house)
871 {
872 int lowest_desirability = 0;
873 int lowest_building_id = 0;
874 int x_min, y_min, x_max, y_max;
875 map_grid_get_area(house->x, house->y, 1, 6, &x_min, &y_min, &x_max, &y_max);
876
877 for (int y = y_min; y <= y_max; y++) {
878 for (int x = x_min; x <= x_max; x++) {
879 int building_id = map_building_at(map_grid_offset(x, y));
880 if (building_id <= 0) {
881 continue;
882 }
883 building *b = building_get(building_id);
884 if (b->state != BUILDING_STATE_IN_USE || building_id == house->id) {
885 continue;
886 }
887 if (!b->house_size || b->type < house->type) {
888 int des = model_get_building(b->type)->desirability_value;
889 if (des < 0) {
890 // simplified desirability calculation
891 int step_size = model_get_building(b->type)->desirability_step_size;
892 int range = model_get_building(b->type)->desirability_range;
893 int dist = calc_maximum_distance(x, y, house->x, house->y);
894 if (dist <= range) {
895 while (--dist > 1) {
896 des += step_size;
897 }
898 if (des < lowest_desirability) {
899 lowest_desirability = des;
900 lowest_building_id = building_id;
901 }
902 }
903 }
904 }
905 }
906 }
907 return lowest_building_id;
908 }
909