· 5 years ago · Jun 05, 2020, 06:08 PM
1//CIVDOS: AI CITY BUILDING LOGIC (pseudocode) v 1.2
2
3//problem: sometimes there's DX register in code but I have no idea what it contains at the moment!
4//maybe in such cases it used for some sort of randomization?
5//Well, then I have no idea how to restore original behavior for such cases!
6
7//DX is set in following places within this function
8//(ignoring what can happens with DX: 1) before this function started and 2) in functions called from this function):
9
10//1ade:06d4 MOV DX,word ptr [BX + CITIES_BUILDINGS2]
11//...
12//1ade:06f3 AND DX,word ptr [BP + local_cit_buildings2]
13//1ade:06f7 OR DX,AX (1) check if city already has this building
14//...
15//1ade:0b9d MOV DL,0x4 (2) used for calcuation of def_un_desire (for var_a)
16//...
17//1ade:0d2f MOV DX,0x1
18//1ade:0d32 MOV CL,byte ptr [HUMAN_CIV_MAIN_1]
19//1ade:0d36 d3 e2 SHL DX,CL (3) in code for SS structural curr_desire
20//...
21//1ade:10a6 MOV DX,CX (4) see var_des
22
23
24//per-continent strategies (same numbers as unit roles)
25#define P_SETTLE 0
26#define P_ATTACK 1
27#define P_DEFEND 2
28#define P_TRANSPORT 5
29
30//unit roles
31#define UR_SETTLER 0
32#define UR_ATTACK 1
33#define UR_DEFENCE 2
34#define UR_SEA_ATTACK 3
35#define UR_TRANSPORT 5
36
37//unit domain
38#define UD_LAND 0
39#define UD_AIR 1
40#define UD_FLEET 2
41
42//types of units
43#define U_SETTLERS 0
44#define U_MILITIA 1
45#define U_FIGHTER 14
46#define U_BOMBER 15
47#define U_NUCLEAR 25
48#define U_DIPLOMAT 26
49
50//city improvements (bit flags)
51#define BB_PALACE 0x1
52#define BB_BARRACKS 0x2
53#define BB_GRANARY 0x4
54#define BB_MARKETPLACE 0x10
55#define BB_LIBRARY 0x20
56#define BB_FACTORY 0x4000
57#define BB_MFG_PLANT 0x8000
58#define BB_POWER_PLANT 0x4 //second word
59#define BB_HYDRO_PLANT 0x8
60#define BB_NUCLEAR_PLANT 0x10
61
62//city improvements (palace is 1)
63#define B_MARKETPLACE 5
64#define B_LIBRARY 6
65#define B_COURTHOUSE 7
66#define B_BANK 10
67#define B_UNIVERSITY 12
68#define B_FACTORY 15
69#define B_POWER_PLANT 19
70#define B_HYDRO_PLANT 20
71#define B_NUCLEAR_PLANT 21
72
73//wonders of the world (Pyramids is 1)
74#define W_HOOVER_DAM 15
75#define W_MANHATTAN_PROJECT 17
76#define W_APOLLO_PROGRAM 19
77
78//civilization advances
79#define T_NUCLEAR_FISSION 0x1b
80#define T_EXPLOSIVES 0x38
81
82//governments
83#define G_DESPOTISM 1
84
85//start sequence: 55 8b ec 81 ec 4a 01 57 56...
86//start address: 0xd9a1 in unpacked civ.exe (ver .05 en)
87
88FUN_prod_menu_and_ai_prod_selection(u8 civ, u8 city_id)
89{
90 //1ade:0421
91 current_list = 0; //2 - city improvements
92 advisers_drawn = 0;
93
94 FUN_city_count_everything(city_id,-1); //darkpanda: CityProcess
95 //it calculates various variables for city_id city
96 //this function also can draw city screen, but it doesn't do it here ('cause -1 param)
97
98 LAB_CREATE_LIST:
99
100 //omitted: create string: "What should we build in City Name?"
101
102 list_entries = 1; //total menu items to select
103 list_prod[0] = 0;
104 if (current_list != 2)
105 {
106 for (counter = 0; counter < 28; counter++)
107 {
108 if (check_tech(civ,unit_tech[counter]))
109 {
110 if (check_tech(civ,unit_obsolete_tech[counter]) == 0)
111 {
112 if (city_flags[city_id]&0x2
113 || unit_domain[counter] != UD_FLEET)
114 {
115 if (counter == U_NUCLEAR)
116 {
117 if (wonder_city[W_MANHATTAN_PROJECT] == -1)
118 continue;
119 if (check_tech(civ,T_NUCLEAR_FISSION) == 0)
120 continue;
121 }
122
123 //omitted: add to string unit string: i.e. "Militia (5 turns, A/D/M:1/1/1)"
124
125 list_prod[list_entries] = counter;
126 list_entries++;
127 }
128 }
129 }
130 }
131 }
132
133 //1ade:05f4
134 list_entries_units = list_entries;
135 string_pos_units = get_string_length(current_string);
136 hoover_dam_eff = 0;
137 if (check_wonder_eff(civ,W_HOOVER_DAM))
138 {
139 if (get_continent(city_x[wonder_city[W_HOOVER_DAM]],city_y[wonder_city[W_HOOVER_DAM]]) ==
140 get_continent(city_x[city_id],city_y[city_id])
141 {
142 hoover_dam_eff = 1;
143 }
144 }
145
146 //1ade:066b
147 if ((debug_flag&0x4)!=0) //you can change debug flags is .SVE using JCivED
148 {
149 for (counter = 1; counter <= 24; counter++)
150 {
151 if (counter > 21) //SS parts
152 {
153 if (wonder_city[W_APOLLO_PROGRAM] == -1)
154 continue;
155 if ((spaceship_flags&(1<<civ))==0) //civ already launched SS
156 continue;
157 }
158
159 if (check_tech(civ,city_improvement_tech[counter] == 0)
160 continue;
161
162 //1ade:06c8 city already has this improvement: I rewrote it pretty loosely...
163 if (counter-1 < 16)
164 {
165 if ((city_buildings1[city_id]&(1<<(counter-1))) != 0)
166 continue;
167 }
168 else
169 {
170 if ((city_buildings2[city_id]&(1<<(counter-1-16))) != 0)
171 continue;
172 }
173
174 //1ade:06fb
175 if (counter == B_FACTORY)
176 {
177 if (city_buildings1[city_id]&BB_MFG_PLANT)
178 {
179 continue;
180 }
181 }
182 if (counter == B_BANK)
183 {
184 if ((city_buildings1[city_id]&BB_MARKETPLACE)==0)
185 {
186 if (check_tech(civ,city_improvement_tech[B_MARKETPLACE]))
187 continue;
188 }
189 }
190 if (counter == B_UNIVERSITY)
191 {
192 if ((city_buildings1[city_id]&BB_LIBRARY)==0)
193 {
194 if (check_tech(civ,city_improvement_tech[B_LIBRARY]))
195 continue;
196 }
197 }
198 if (counter == B_HYDRO_PLANT)
199 {
200 if ((city_flags[city_id]&0x80)==0) //city doesn't have hydropower
201 continue;
202 }
203 if (counter == B_POWER_PLANT)
204 {
205 if ((city_buildings1[city_id]&BB_FACTORY)==0)
206 continue;
207 }
208 if (counter == B_POWER_PLANT
209 || counter == B_HYDRO_PLANT
210 || counter == B_NUCLEAR_PLANT)
211 {
212 if (hoover_dam_eff)
213 continue;
214 if ((city_buildings2[city_id]&BB_POWER_PLANT) != 0
215 || (city_buildings2[city_id]&BB_HYDRO_PLANT) != 0
216 || (city_buildings2[city_id]&BB_NUCLEAR_PLANT) != 0)
217 continue;
218 }
219
220 //omitted: add city improvement string, i.e. "Barracks (20 turns)"
221
222 list_prod[list_entries] = -counter; //1 -> -1 is palace 2 -> -2 is barracks etc.
223 list_entries++;
224 }
225 }
226
227 //1ade:082f
228 for (counter = 25; counter <= 45; counter++)
229 {
230 if (check_tech(civ,city_improvement_tech[counter])==0)
231 continue;
232 if (wonder_city[counter-24] == -1 //wonder was never built
233 || wonder_city[counter-24] == 127) //wonder was destroyed
234 continue;
235 if (check_tech(civ,wonder_tech_obsolete[counter-24])
236 {
237 //omitted: add "*" to string
238 }
239
240 //omitted: add wonder string, i.e. "Pyramids (100 turns)"
241
242 list_prod[list_entries] = -counter;
243 list_entries++;
244 }
245
246 //1ade:08dd
247 if (civ == player_civ)
248 {
249 if ((city_flags[city_id]&0x10)==0) //not autobuild
250 {
251 if (list_entries >= 30)
252 {
253 if (current_list == 0)
254 {
255 current_list = 1;
256 goto LAB_CREATE_LIST; //repeat everything? why?..
257 }
258
259 //omitted: replace part of "current_string" after "string_pos_units" with string "More..." (1)
260
261 list_prod[list_entries_units] = 99; //flag to switch to the next list
262 }
263 }
264 }
265
266 if (current_list == 2)
267 {
268 //omitted: add string "More..." (2)
269
270 list_prod[list_entries] = 98; //flag to switch to previous list
271 }
272 //end of: list creation (position -> what to build) and creation of text for this list--------------------------------------------------------------
273
274 //1ade:094f
275 cont = get_continent(city_x[city_id],city_y[city_id]);
276 cont_pol = continent_policy[civ][cont];
277 pol = 0;
278 if (cont_pol == P_ATTACK
279 || cont_pol == P_DEFEND)
280 {
281 pol = 1;
282 }
283 if (gl_ai_handicap != 0 //'human player dominance': 1st place in civ powergraph, > 4 cities and 0 nuclear bombs, and turn > 200
284 && cont_pol == P_TRANSPORT)
285 {
286 pol = 1;
287 }
288
289 if (government[civ] <= G_DESPOTISM)
290 {
291 settlers_food = 1;
292 }
293 else
294 settlers_food = 2;
295 s16 res_food = city_food_prod-settlers_food*settler_counter-2*city_size[city_id]; //city_food_prod is a global var
296
297 //1ade:09dd
298 counter = 0;
299 do //types of units
300 {
301 stack_fee6[counter] = 1; //modifer: it's 1 for every unit type, so it's possible to just use '1' instead?
302 unit_counter_on_continent[counter] = 0; //stack -0x44
303 counter++;
304 }
305 while (counter < 28);
306
307 //1ade:0a01
308 local_civ_un_counter = civ_unit_counter[civ]; //old, normal value (without settlers and nuclears)
309 civ_unit_counter[civ] = 0;
310
311 city_count = 0;
312 do //all cities
313 {
314 cit_cont = get_continent(city_x[city_count],city_y[city_count]);
315 if (city_flags[city_count] != -1 //a city exists
316 && city_civ[city_count] == civ //it's belong to us
317 && cit_cont == cont) //a city is on the same continent as our city
318 {
319 if (city_production[city_count] >= 0) //unit in production
320 {
321 if (city_count != city_id) //not our city itself
322 {
323 unit_in_prod_on_cont[city_production[city_count]]++; //local array
324 }
325 }
326 for (i = 0; i < 2; i++) //special fields for unit storage...
327 {
328 alt_un = city_alt_unit_field[city_count][i]
329 if (alt_un != 0xFF)
330 {
331 civ_units_counter[civ]++; //global array
332 unit_counter_on_continent[alt_un&0x3F]++; //local array
333 }
334 }
335 }
336 city_count++;
337 }
338 while (city_count < 128);
339
340 //1ade:0ab2
341 counter = 0;
342 do //all units
343 {
344 if (unit_type[counter] != -1) //unit exists
345 {
346 civ_units_counter[civ]++;
347 un_cont = get_continent(unit_x[counter], unit_y[counter]);
348 if (un_cont == cont)
349 {
350 unit_counter_on_continent[unit_type[counter]]++;
351 }
352 }
353 }
354 while (counter < 128);
355
356 //1ade:0b0b
357 if (civ_units_counter[civ] == 0)
358 {
359 if (civ != player_civ)
360 {
361 if (government[civ] <= G_DESPOTISM)
362 {
363 return 1; //militia
364 }
365 }
366 }
367
368 //1ade:0b2c
369 if (civ == 0) //barbarians
370 {
371 if (first_discoverer_civ[T_EXPLOSIVES] != 0) //explosives was discovered by somebody before...
372 {
373 return 7; //knights
374 }
375 return 3; //legion
376 }
377
378 //1ade:0b4a
379 def_un_desire = 0;
380 counter = find_unit_id_in_xy(city_x[city_id],city_y[city_id]);
381 if (counter != -1) //there's some unit in the city
382 {
383 def_units = count_units_of_this_type_in_stack(counter,civ,UR_DEFENCE);
384 var_a = city_size[city_id]/4+pol; //pol can be 0 or 1 //DL is set here. See use of undefined DX later...
385 if (var_a > def_units)
386 def_un_desire = 1; //we need more def units...
387 }
388 else
389 {
390 def_un_desire = 2; //we NEED def unit!!
391 }
392
393 //1ade:0baf
394 best_unit_desire = 999; //the less is better
395 best_bldng_desire = 999;
396 best_desire = 999;
397 best_unit_production = -1;
398 best_bldng_production = -1; //stack -0x4a
399 counter = 1;
400
401 //1ade:0f57
402 for (counter = 0; counter < list_entries; counter++)
403 {
404 prod_type = list_prod[counter];
405
406 if (prod_type >= 0 //unit, not city improvement
407 && prod_type < U_DIPLOMAT) //but not diplomat or caravan
408 {
409 if (prod_type == U_CARRIER)
410 {
411 continue; //AI never builds carriers...
412 }
413
414 if (prod_type == U_SETTLERS)
415 {
416 settl_food = 2;
417 if (government[civ] <= G_DESPOTISM)
418 settl_food = 1;
419 if (settl_food >= res_food) //city produces not enough food to support new settler...
420 {
421 if (units_per_type[civ][U_SETTLERS] != 0
422 || unit_in_prod_on_cont[U_SETTLERS] > 1)
423 {
424 continue;
425 }
426 }
427 }
428
429 //1ade:0fd2
430 if (prod_type == U_MILITIA)
431 {
432 if (government[civ] > G_DESPOTISM) //AI never builds militias if its govt's not Despotism...
433 {
434 continue;
435 }
436 }
437
438 if (prod_type == U_NUCLEAR)
439 {
440 if (units_per_type[civ][U_NUCLEAR] >= 4 //AI never builds nukes if it already has 4 of them
441 || units_in_production[civ][U_NUCLEAR] >= 2) //or if >= 2 nukes in production
442 {
443 continue;
444 }
445 }
446
447 //1ade:1009
448 if (prod_type == U_FIGHTER)
449 {
450 if (units_per_type[civ][prod_type]+units_in_production[civ][prod_type] >=
451 (units_per_type[player_civ][U_BOMBER]-DX)>>1) //what's in DX?! probably it used here for some randomization?..
452 //if there's some unit in the city: mb last time DX was changed to: 4 (DL)?
453 //in decompiled chunk DX was ignored (0)
454 {
455 continue;
456 }
457 if ((diplomacy_status[civ][player_civ]&2) != 0) //peace with player
458 {
459 continue;
460 }
461 }
462
463 //1ade:1054
464 if (unit_domain[prod_type] == UD_LAND)
465 {
466 curr_desire = (stack_fee6[prod_type]<<1)+unit_counter_on_continent[prod_type]; //stack_fee6[prod_type] is always 1
467 //more units of this type (esp. in production) -> less desire to build another one
468 }
469 else
470 {
471 if (defence_per_continent[civ][cont] < 8) //not enough defence on continent -> don't build any boats or aircraft...
472 {
473 continue;
474 }
475
476 var_des = (units_in_production[civ][prod_type]<<1)+units_per_type[civ][prod_type]; //var_des: DX -> CX
477 //more units of this type (esp. in production) -> less desire to build another one
478 curr_desire = var_des*defence_per_continent[civ][cont]/(civ_unit_counter[civ]+1); //AX*CX
479 //strange... more defence on continent -> less desire to build non-land unit?..
480 //more units in total -> more desire to build non-land unit...
481 }
482
483 if (def_un_desire != 0)
484 {
485 if (unit_role[prod_type] != UR_DEFENCE) //we want to build defence units ONLY...
486 {
487 continue;
488 }
489
490 curr_desire = 2/def_un_desire; //the less is better
491 }
492
493 if (unit_role[prod_type] != UR_DEFENCE && unit_role[prod_type] != UR_SETTLER)
494 {
495 curr_desire = (curr_desire<<1); //if it's not a defender or settler, we need it less...
496 if (cont_pol != unit_role[prod_type]) //unit role is not our continent role...
497 {
498 curr_desire = (curr_desire<<1); //we need it less...
499 }
500 }
501
502 //1ade:1113
503 if (unit_role[prod_type] == UR_TRANSPORT)
504 {
505 if (cont_pol != P_TRANSPORT) //AI doesn't build any transports if continent role is not 'transport'
506 continue;
507 curr_desire = ((3*curr_desire-DX)>>1); //DX: should be var_des (last time when DX was changed)
508 //but if def. on continent < 8, then wtf can be in DX...
509 }
510
511 //1ade:113c
512 if (prod_type == U_SETTLERS)
513 {
514 granary_factor = 6; //CX->AX
515 if ((city_buildings1[city_id]&BB_GRANARY)!=0) //city has a granary
516 granary_factor = 4; //we want to build settlers more
517 granary_factor -= get_leader_civilized_attitude(civ,civ_0_or_1_same_color[civ]); //+1->-1 for civilized, -1->+1 for militaristic
518 //civilized leaders want to build settlers more... BUT 'expansionism' attitude is not matter here...
519 }
520 else
521 granary_factor = 10; //AX
522
523 granary_factor *= (unit_shield_rows_cost[prod_type]+2); //AX
524 granary_factor *= curr_desire; //AX->CX
525
526 unit_coolness = (unit_attack[prod_type]+unit_defence[prod_type])*(unit_tot_moves[prod_type]+1);
527 //btw, strange code in unit_coolness calculation: MOV DI, DX ... MOV DX, DI - but DI and DX are not used anywhere in between, so it's useless?..
528 granary_factor /= unit_coolness; //we want to build strongest and fastest units...
529 curr_desire = granary_factor;
530
531 //1ade:11a8
532 if (unit_role[prod_type] == UR_SEA_ATTACK)
533 {
534 if (cont_pol != P_SETTLE)
535 {
536 curr_desire *= 4; //we want it much less (we need military units or transports!)
537 }
538 else
539 {
540 curr_desire *= 2; //we want it less
541 }
542 }
543
544 if (unit_domain[prod_type] == UD_AIR)
545 {
546 curr_desire = (curr_desire<<1);
547 }
548
549 //1ade:11d9
550 if (civ_unit_counter[civ] > 120) //too many units...
551 {
552 curr_desire = (curr_desire<<2);
553 }
554
555 if (cont_pol == P_SETTLE)
556 {
557 //continent policy is not attack/defend or transport -> so we don't units THIS much...
558 if (city_tot_shields <= city_supp_units)
559 //so, if there's too many supported units (in comparison with city shield production)...
560 {
561 curr_desire = (curr_desire<<1); //we want to build another unit less...
562 }
563 }
564
565 if (civ_has_contact_or_peace_with_somebody == 0) //i.e. no contacts with other civs...
566 //if diplomacy flags 'contact' or 'peace' is not 0 with some other civ at the beginning of civ turn => then it's 1
567 {
568 curr_desire = (curr_desire<<1);
569 }
570
571 //1ade:1206
572 if (curr_desire < best_desire) //better
573 {
574 best_common_production = counter; // Stack[-0x146]
575 best_desire = curr_desire;
576 }
577 } //normal unit
578 else //city improvements, diplomat, caravan
579 {
580 //1ade:0f79
581 curr_desire = 999;
582 building_pol = 0;
583 temp_var_ax = -prod_type; //city improvement number... -1 palace->1, -2 barracks->2 etc. diplomat: -26, caravan: -27, //NEG AX
584 temp_var_ax += 27; // SUB AX, -27 //palace: 28 nuclear plant: 48 SS structural: 49
585 //diplomat: 1, caravan: 0
586 if (temp_var_ax <= 49) //caravan, diplomat or any city improvement, except SS component, SS module and wonders
587 {
588 //ADD AX,AX //2 bytes per entry...
589 //XCHG AX,BX //AX <-> BX for what purpose?..
590 //JMP word ptr CS:[BX + 0xe71] //what the heck?
591 //maybe "switch" in original code?
592
593 //JUMP TABLE:
594
595 //0xe71 caravan (0):
596 //jmp 0x0d5a
597
598 //0xe73 diplomat (1):
599 //jmp 0x0dcd
600
601 //0e75-0ea9 mil. units, not used (2-28):
602 //jmp 0x0ed5
603
604 //0xeab barracks (29):
605 //jmp 0x0c31
606
607 //0xead granary (30):
608 //jmp 0x0c40
609
610 //0x0eaf temple (31):
611 //jmp 0x0bcf
612
613 //0x0eb1 marketplace (32):
614 //jmp 0x0c7d
615
616 //0x0eb3 libarary (33):
617 //jmp 0x0ca9
618
619 //0x0eb5 courthouse (34):
620 //jmp 0x0bea
621
622 //0x0eb7 city walls (35):
623 //jmp 0x0ccb
624
625 //0x0eb9 aqueduct (36):
626 //jmp 0x0cf8
627
628 //0x0ebb bank (37):
629 //jmp 0x0ca9 //same as library
630
631 //0x0ebd cathedral (38):
632 //jmp 0x0bfb
633
634 //0x0ebf university (39):
635 //jmp 0x0cb8
636
637 //0x0ec1 mass transit (40):
638 //jmp 0x0ed5 //same as units
639
640 //0x0ec3 colosseum (41):
641 //jmp 0x0c16
642
643 //0x0ec5 factory (42):
644 //jmp 0x0c51
645
646 //0x0ec7 mfg plant (43):
647 //jmp 0x0c69
648
649 //0x0ec9 sdi defence (44):
650 //jmp 0x0ed5 //same as units and mass transit
651
652 //0x0ecb rec. center (45):
653 //jmp 0x0c69 //same as mfg plant
654
655 //0x0ecd power plant (46):
656 //jmp 0x0c5e
657
658 //0x0ecf hydro plant (47):
659 //jmp 0x0c51 //same as factory
660
661 //0x0ed1 nuclear plant (48):
662 //jmp 0x0c69 //same as mfg plant and rec. center
663
664 //0x0ed3 ss structural (49):
665 //jmp 0x0d27
666
667 //for some reason -2 for stack addresses here...
668 //stack 0xfece: -132 -> -134 building_pol
669 //stack 0xfecc: -134 -> -136 curr_bldng_desire
670 //stack 0x8: 8 -> 6 city_id
671 //stack -0x2 -> -4 res_food
672 //stack 6 -> 4 civ
673 //stack -0x4a -> -0x4c counter
674 switch (temp_var_ax)
675 {
676 case 31: //temple 0x0bcf
677 if ((city_flags[city_id]&1) != 0) //city disorder
678 curr_desire = -4; //stack 0xfecc
679 break;
680
681 case 34: //courthouse 0x0bea
682 curr_desire = -((city_corruption<<1)-12);
683 break;
684
685 case 38: //cathedral 0x0bfb
686 if ((city_flags[city_id]&1) != 0) //city disorder
687 curr_desire = -2;
688 break;
689
690 case 41: //colosseum 0x0c16
691 if ((city_flags[city_id]&1) != 0) //city disorder
692 curr_desire = -1;
693 break;
694
695 case 29: //barracks 0x0c31
696 curr_desire = 5;
697 building_pol = 1; //stack 0xfece
698 break;
699
700 case 30: //granary 0x0c40
701 if (city_tot_shields >= 3)
702 curr_desire = 4;
703 else
704 curr_desire = 8;
705 break;
706
707 case 42: //factory
708 case 47: //hydro plant 0x0c51
709 curr_desire = -(((city_tot_shields-DX)>>1)-13); //what's in DX?!
710 break;
711
712 case 46: //power plant 0x0c5e
713 curr_desire = -(city_tot_shields/5-12);
714 break;
715
716 case 43: //mfg plant
717 case 45: //rec center
718 case 48: //nuclear plant 0x0c69
719 AX = city_tot_shields;
720 //have no idea what in DX at the moment. M.b. some sort of randomization here...
721 XOR AX, DX
722 SUB AX, DX
723 AX = AX>>3;
724 XOR AX, DX
725 SUB AX, DX
726 curr_desire = -(AX-12);
727 break;
728
729 case 32: //marketplace 0x0c7d
730 curr_desire = -(((city_tot_trade-DX)>>1)-10); //what in DX?!
731 if ((city_flags[city_id]&1) != 0) //city disorder
732 {
733 curr_desire = -3;
734 }
735 break;
736
737 case 33: //library
738 case 37: //bank 0x0ca9
739 curr_desire = -(city_tot_trade/3-10);
740
741 break;
742
743 case 39: //university 0x0cb8
744 AX = city_tot_trade;
745 //have no idea what in DX at the moment. M.b. some sort of randomization here...
746 XOR AX, DX
747 SUB AX, DX
748 AX = AX>>2;
749 XOR AX, DX
750 SUB AX, DX
751 curr_desire = -(AX-10);
752 break;
753
754 case 35: //city walls 0x0ccb
755 curr_desire = -(city_size[city_id]/2-10);
756 if (city_buildings1[city_id]&BB_PALACE)
757 curr_desire = 4;
758 break;
759
760 case 36: //aqueduct 0x0cf8
761 AX = 10-((res_food-DX)>>1); //res_food: stack -0x2 what is in DX?!
762 if (AX <= city_size[city_id])
763 {
764 curr_desire = -(city_size[city_id]+((res_food-DX)>>1)-14);
765 }
766 break;
767
768 case 49: //SS structural 0x0d27
769 AX = 1<<civ;
770 DX = 1<<player_civ; //DX used
771 AX += DX;
772 if ((spaceship_flags&AX)==0) //Our spaceship not launched AND human spaceship not launched too.
773 {
774 if (spaceship_flags&(1<<8)) //score completed: post game (&0x100)
775 {
776 curr_desire = 2; //but why AI want it _more_ in this case?..
777 }
778 else
779 {
780 curr_desire = 4;
781 }
782 }
783 break;
784
785 case 0: //caravan 0x0d5a
786 if (trade_cities[city_id][2] == -1)
787 {
788 curr_desire = -(((city_tot_trade-DX)>>1)-10); //I have no idea what's in DX at the moment...
789 if (trade_cities[city_id][0] != -1)
790 {
791 curr_desire += 2;
792 }
793 if (trade_cities[city_id][1] != -1)
794 {
795 curr_desire += 2;
796 }
797 if (curr_desire < 3)
798 {
799 curr_desire = 3;
800 }
801 }
802 if (player_civ == civ)
803 {
804 if (city_flags[city_id]&0x10) //auto build
805 {
806 curr_desire = 999; //human player should NOT build caravans in autobuild!
807 }
808 }
809 break;
810
811 case 1: //diplomat 0xdcd
812 if (player_civ != 0) //human doesn't play for Barbarians...
813 {
814 if ((unknown_array_civ_x_civ[civ][player_civ]&2)==0) //always?..
815 //array: 2 bytes per civ, civ x civ = 2*8*8 = 128 bytes total
816 //2nd byte is 0xfd, if in the past there was sneak attack by human player on AI or sneak attack by AI on the human player
817 //but 1st byte never changes and it's always 0 (if it does not change in overlays...)
818 {
819 if (units_in_production[civ][diplomat] <= 0)
820 {
821 counter = random(5); //random block of 16 tech (bit flags, 16*5 = 80 tech max per civ)
822 if ((player_civ_near_me&(1<<civ))!=0)
823 //it's 1, if human player has > 1 cities on some of our AI civ continents
824 //and AI civ defence on this continent is not 0
825 //and there can be some other conditions - it's set in big routine which determines AI policy, it's pretty complicated...
826 {
827 di_var = tech_list[civ][counter];
828 ax_var = tech_list[player_civ][counter];
829 ax_var |= di_var;
830 if (ax_var != dx_var) //player civ has some new techs in this 16 tech chunk...
831 {
832 ax_var = number_of_tech[civ]-number_of_tech[player_civ]+10;
833 curr_desire = normalize_minmax(ax_var,5,10);
834 }
835 }
836 }
837 }
838 }
839 break;
840
841 case 40: //mass transit
842 case 44: //sdi defence
843 default: //2..28 - military units (not used)
844 //do nothing
845 }
846 }
847
848 //1ade:0ed5
849 if (curr_desire >= 400)
850 {
851 curr_desire = 0x3fff; //whut?
852 }
853 else
854 {
855 if (cont_pol != building_pol) //building_pol usually 0, 1 (attack) for barracks
856 {
857 base_des = 14; //we need attack/defence units or transports, so we don't want to build city improvements...
858 }
859 else
860 base_des = 10;
861
862 curr_desire *= base_des;
863 curr_desire = 3*curr_desire/(get_leader_civilized_attitude(civ,civ_0_or_1_same_color[civ])+3);
864 // /4 if civilized -> want to build city improvements
865 // /2 if militaristic -> don't want to build city improvements
866 // /3 otherwise
867 }
868
869 //1ade:0f22
870 if ((city_buildings1[city_id]&BB_BARRACKS)!=0) //if city has barracks...
871 {
872 AX = curr_desire;
873 //what is in DX?! some randomization here or wtf?..
874 XOR AX,DX
875 SUB AX,DX
876 AX = AX>>2;
877 XOR AX,DX
878 SUB AX,DX
879 //why?..
880 curr_desire += AX;
881 }
882
883 if (curr_desire < best_desire) //better
884 {
885 best_common_production = counter;
886 best_desire = curr_desire;
887 }
888 }
889
890 if (unit_type_b < 0 //city improvement
891 || unit_type_b >= U_DIPLOMAT) //diplomat or caravan
892 {
893 if (curr_desire < best_bldng_desire)
894 {
895 best_bldng_desire = curr_desire;
896 best_bldng_production = counter;
897 }
898 }
899 else //normal unit
900 {
901 if (curr_desire < best_unit_desire)
902 {
903 best_unit_desire = curr_desire;
904 best_unit_production = counter;
905 }
906 }
907 } //loop: select best production
908
909 //1ade:1268
910 civ_unit_counter[civ] = local_civ_un_counter; //restore previous value (without settlers and nuclear bombs)
911 if ((human_civs_bits&(1<<civ)) == 0) //ai
912 {
913 if (city_production[city] == -1) //palace
914 {
915 return -1; //continue palace construction?..
916 }
917 return list_prod[best_common_production];
918 }
919
920 //1ade:12a5
921 if ((city_flags[city]&x0x10)!=0) //AUTO
922 {
923 if (best_bldng_production != -1 //some new buildings was selected for AUTO
924 && best_bldng_desire <= 500) //and desire to build it is high enough...
925 {
926 return list_prod[best_bldng_production];
927 }
928 else
929 return 99; //flag: no good new production for AUTO was found. Do not change production. Go to city screen, if needed...
930 }
931
932 //1ade:12cd
933 if ((game_settings&0x1)!=0) //instant advice
934 {
935 if (advisers_drawn == 0)
936 {
937 if (best_unit_production != -1) //military advisor
938 {
939 glob_0xaa[16] = 2; //?? m.b. total number of lists/messages??
940 if (list_prod[best_unit_production] > 0) //unit
941 {
942 //omitted: use name from units name list...
943 }
944 else
945 {
946 //omitted: use name from city improvements name list - never happens
947 }
948
949 //omitted: create string for military advisor message (using produce.txt)
950
951 help_message_on_screen_flag = 1;
952
953 draw_message_B(current_string,8,160); //draw military advisor advice
954 }
955
956 if (best_bldng_production != -1) //domestic advisor
957 {
958 curr_desire = list_prod[best_bldng_production];
959 if (list_prod[best_bldng_production] > 0) //unit: diplomat or caravan
960 {
961 //omitted: use name from units name list...
962 }
963 else
964 {
965 //omitted: use name from city improvements name list...
966 }
967
968 //omitted: create string for domestic advisor message (using produce.txt)
969
970 draw_message_B(current_string,164,160); //draw domestic advisor advice
971 }
972 advisers_drawn = 1;
973 glob_0xaa[16] = 1; //??
974
975 goto LAB_CREATE_LIST;
976 }
977 } //instant advice
978
979 //1ade:1438
980 if (list_entries > 20 || current_list != 0)
981 {
982 glob_0xaa[16] = 2; //??
983 }
984
985 //1ade:144e
986 menu_on_screen_flag = 1;
987 SI = draw_message_B(current_string,80,8); //draw menu (what you can build) in X: 80 Y: 8
988 current_desire = stack_de[SI]; //stack -0xde, never used elsewhere... should be selected menu item?
989 if (current_desire == 99) //go to the next list...
990 {
991 current_list = 2; //city improvements
992 goto LAB_CREATE_LIST;
993 }
994 if (current_desire == 98) //go to previous list...
995 {
996 current_list = 1; //units
997 goto LAB_CREATE_LIST;
998 }
999 glob_0xaa[16] = 1; //??
1000
1001 //1ade:148c
1002 if (civilopedia_help_flag != 0)
1003 {
1004 FUN_black_screen_mb();
1005 FUN_clear_screen_mb_B(); //some_graph_driver_func_1(0,0,200,320,0,0,glob_0xaa);
1006 cpedia_from_city_screen_flag = 1;
1007 if (current_desire >= 0) //unit
1008 {
1009 cpedia_type = 2;
1010 }
1011 else //city improvement
1012 {
1013 cpedia_type = 1;
1014 current_desire = -current_desire; //city improvements have negative values
1015 }
1016 overlay_08_2A06(current_desire,cpedia_type); //civilopedia help
1017 clear_all_screen_mb(); //some_graph_driver_func_2(0,0,glob_0xaa,200,320,unkn_graph_var) - clear screen?
1018 update_screen_mb();
1019 to_other_screen_from_city_screen_flag = 1;
1020 goto LAB_CREATE_LIST;
1021 }
1022
1023 return current_desire;
1024}