Advertisement
Guest User

civdos barbarian units ai (fix 4)

a guest
Apr 8th, 2020
258
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.47 KB | None | 0 0
  1. #define IM_CITY       1
  2. #define IM_IRRIGATION 2
  3. #define IM_MINE       4
  4.  
  5. #define SQ_OCEAN     10
  6.  
  7. #define UR_DEFENCE    2 //land defence: only musketeers. In theory also militia, phalanx, riflemen and mech. inf.
  8. #define UR_TRANSPORT  5 //sail or frigate (in theory also trireme and transport)
  9.  
  10. #define UD_LAND       0 //land unit
  11. #define UD_FLEET      2 //unit is a boat
  12.  
  13. #define U_DIPLOMAT 0x2A
  14.  
  15. change_x[9] = {0,0,1,1,1,0,-1,-1,-1};
  16. change_y[9] = {0,-1,-1,0,1,1,1,0,-1};
  17.  
  18. check_ZOC(civ,x,y)
  19. {
  20.     res = 0;
  21.     impr = get_improvements(x,y);
  22.     if ((impr & IM_CITY) == 0)
  23.         res = check_ZOC_B(civ,x,y); //check blocking unit. If civ == player_civ - draw it and draw terrain and city in its square.
  24.     else
  25.         res = 0; //unit can always go from and to the city
  26.     return res;
  27. }
  28.  
  29. get_city_area_civ(x,y)
  30. {
  31.     return (current_terrain_value[x][y]&7);
  32.     //returns 0..7 (city civ) for 21 squares of city area
  33.     //but what about other squares?
  34.     //if it's similar to save file (see current terrain value in JCivED), then...
  35.     //8 for +1 radius line around a city area -> returns 0 - it's ok...
  36.     //but if there's no city nearby then current land value can be 0 or 9..15
  37.     //problem here: what about 9..15 land value outside city areas?
  38.     //it will return current_terrain_value[x][y]-8 instead of civ number. But m.b. this is ok...
  39. }
  40.  
  41. barbarian_unit_ai_func(civ, unit_id) //civ == 0
  42. {
  43.     unit = get_unit_type(civ,unit_id); //legion, cavalry, diplomat etc.
  44.     x = get_unit_x(civ,unit_id);
  45.     y = get_unit_y(civ,unit_id);
  46.     if (y < 2 || y > 47)
  47.     {
  48.         unkn_var = disband_unit(param_civ,unit_id); //it returns void! it never returns anything anywhere but here!
  49.         return unkn_var; //?
  50.     }
  51.    
  52.     zoc_here = check_ZOC(civ,x,y); //1 if any adjacent enemy units (not in ocean...). If city - then always 0 (you can always go in and from a city ignoring ZoC...)
  53.     //zone of control in current square. If zoc_here == 1 && zoc_next == 1 -> no go
  54.    
  55.     if (get_unit_role(unit) == UR_TRANSPORT)
  56.     {
  57.         if (next_unit_in_stack != -1) //has passengers
  58.         {
  59.             city = find_closest_city(x,y); //return city id and set global var: gl_distance
  60.             dist_closest_city = gl_distance;
  61.             for (dir = 1; dir < 9; dir++)
  62.             {
  63.                 x2 = normalize(x+change_x[dir]); //the world is round. For example, x = -1 -> x = 79
  64.                 y2 = y+change_y[dir];
  65.                 terr = get_terrain(x2,y2);
  66.                 impr = get_improvements(x2,y2);
  67.                 if (dist_closest_city < 9 && terr != SQ_OCEAN
  68.                 && (impr&IM_CITY) == 0 //there's no city in this square
  69.                 && civ_id_of_unit_in_xy(x2,y2) == -1 //no units by any civ in this square
  70.                 && y2 > 1 && y2 < 48)
  71.                 {
  72.                     if (map_of_explored_terrain[x][y] & (1<<player_civ)) != 0 //square is explored by player civ
  73.                     && get_city_civ(city) == player_civ)
  74.                     {
  75.                         cont1 = get_continent(city_x[city],city_y[city]);
  76.                         cont2 = get_continent(x2,y2);
  77.                         if (cont1 == cont2)
  78.                         {
  79.                             unit_visibility |= (1<<player_civ); //set visibility bit of player civ to 1
  80.                            
  81.                             //fix view position? (if incorrect??) and change view position to x-8,y-6
  82.                            
  83.                             gl_message_type = 3; //Military Advisor:
  84.                             //message about landing...
  85.                         }
  86.                     }
  87.                     unit_visibility |= get_terrain_visibility(x,y);
  88.                     unit_remaining_moves = 0;
  89.                     return 0x75; //'u'->unload
  90.                 }
  91.                 if (civ_id_of_unit_in_xy(x2,y2) > 0) //somebody is next to us and it's not a barbarian
  92.                     return dir; //direction of movement/attack
  93.             } //for: all 8 directions
  94.             if (goto_x != -1) //boat is already in GoTo state
  95.                 return 0;
  96.         } //transport has passengers
  97.         best_city = 0;
  98.         cit_count = 0;
  99.         best_val; //best_val value was undefined?
  100.         do
  101.         {
  102.             if (city_flags[cit_count] != -1) //city exists
  103.             {
  104.                 distance = find_distance(x,y,city_x[cit_count],city_y[cit_count]);
  105.                 city_val = get_city_gold_loot(cit_count); // city_population*civ_treasure/(civ_population+1)
  106.                 city_val = (city_val+50)/(distance+1); //formula for target city
  107.                 if (city_val > best_val)
  108.                 {
  109.                     best_city = cit_count;
  110.                     best_val = city_val;
  111.                 }
  112.             }
  113.             cit_count++;
  114.         }
  115.         while (cit_count < 128);
  116.         if (best_city != 0)
  117.         {
  118.             goto_x = city_x[cit_count];
  119.             goto_y = city_y[cit_count];
  120.             return 0;
  121.         }
  122.         goto LABEL_DISBAND;
  123.     } //unit role: transport
  124.    
  125.     city = find_closest_city(x,y); //it sets global var: gl_distance
  126.     dist_closest_city = gl_distance;
  127.     cit_civ = get_city_civ(city);
  128.     if (dist_closest_city == 0 && (next_unit_in_stack == -1 || get_unit_role(unit) == UR_DEFENCE))
  129.         return 0x66; //'f' -> fortify
  130.        
  131.     x_direction_to_city = -2;
  132.     y_direction_to_city = -2;
  133.     if (game_turn&3 == 0) //every 4th turn
  134.     {
  135.         cont1 = get_continent(x,y);
  136.         cont2 = get_continent(city_x[city], city_y[city]);
  137.         if ((cont1 != cont2) || dist_closest_city > 8)
  138.         {
  139.             goto LABEL_DISBAND;
  140.         }
  141.     }
  142.     if (city != -1) //at least 1 city exists in the world
  143.     {
  144.         cont1 = get_continent(x,y);
  145.         cont2 = get_continent(city_x[city], city_y[city]);
  146.         if (cont1 == cont2
  147.         && (human_civ_bits & (1<<cit_civ)) != 0) //this is a human player's city... human_civ_bits and player_civ are different variables. Human civ bits are bit flags.
  148.         {
  149.             x_direction_to_city = get_sign(city_x[city] - x); //-1 if < 0 0 if 0 +1 if > 0
  150.             y_direction_to_city = get_sign(city_y[city] - y);
  151.         }
  152.     }
  153.     if (cit_civ == civ //barbarian city
  154.     || (civ_cities_total[cit_civ] < 2 && gold[cit_civ] < 100)) //or city owner has only 1 city and less than 100$
  155.     {
  156.         x_direction_to_city = -2;
  157.         y_direction_to_city = -2;
  158.     }
  159.     if (x_direction_to_city != -2)
  160.     {
  161.         //go straight to the city!
  162.         goto_x = city_x[city];
  163.         goto_y = city_y[city];
  164.         goto_dir = moveUnitGoto(civ,unit_id); //returns direction of next move: 1..9 //Unknown9 field in JCivED.
  165.         //moveUnitGoto was disassembled by darkpanda. You can find it somewhere on the forums...
  166.     }
  167.     goto_x = -1; //GoTo off. Barbarian units don't check it anywhere anyway and boat routine never go here, so it's kinda pointless?..
  168.     if (unit == U_DIPLOMAT)
  169.     {
  170.         terr = get_terrain(x,y);
  171.         if (next_unit_in_stack != -1 && terr != SQ_OCEAN && get_unit_type(civ,next_unit_in_stack) != U_DIPLOMAT) //if our diplomat's on land and some other barbarian unit's here and it's not an another diplomat
  172.         {
  173.             return 0x20; //space -> skip turn
  174.         }
  175.        
  176.         if (terr == SQ_OCEAN)
  177.         {
  178.             if (dist_closest_city > 2)
  179.                 goto LABEL_NOT_DIPLOMAT;
  180.         }
  181.         else
  182.         {
  183.             unit_id2 = find_my_closest_unit_id(civ,unit_id,x,y); //set gl_distance
  184.             dist_closest_unit = gl_distance;
  185.             if (dist_closest_unit < 4 && get_unit_type(civ,unit_id2) != U_DIPLOMAT)
  186.             {
  187.                 goto_x = get_unit_x(civ,unit_id2);
  188.                 goto_y = get_unit_y(civ,unit_id2);
  189.                 return 0; //do nothing?
  190.             }
  191.             if ((game_turn&7)+4 > dist_closest_city) //if remainder of dividing game_turn by 8 +4 > dist_closest_city
  192.                 goto LABEL_NOT_DIPLOMAT;
  193.         }
  194.         LABEL_DISBAND:
  195.         disband_unit(civ,unit_id);
  196.     }
  197.     else
  198.     {
  199.         LABEL_NOT_DIPLOMAT:
  200.         best_direction = 0;
  201.         best_val = -999;
  202.         dir = 1;
  203.         while (dir < 9)
  204.         {
  205.             x2 = normalize(x+change_x[dir]);
  206.             y2 = y+change_y[dir];
  207.             terr = get_terrain(x2,y2);
  208.            
  209.             if (((get_unit_domain(unit) == UD_FLEET) == (terr == SQ_OCEAN)) //if boat and in ocean OR not a boat and on land
  210.             && check_if_xy_within_the_map(x2,y2)) //X:0-79,Y:0-49 returns 0 if not
  211.             {
  212.                 unit_id2 = get_unit_id_in_xy(x2,y2); //returns -1 if no units here. Sets gl_unit_civ if some unit is here.
  213.                 if (get_unit_type(civ, unit_id) == U_DIPLOMAT)
  214.                 {
  215.                     curr_val = 0;
  216.                     if (unit_id2 != -1)
  217.                     {
  218.                         if (civ == gl_unit_civ) //it's a barbarian unit
  219.                         {
  220.                             curr_val = 99;
  221.                         }
  222.                         else //it's an enemy unit
  223.                         {
  224.                             curr_val = -99;
  225.                         }
  226.                     }
  227.                     find_closest_city(x2,y2); //set gl_distance
  228.                     dist_closest_city = gl_distance;
  229.                     rand = random(4); //0..3
  230.                     curr_val += dist_closest_city*4+rand+get_terrain_movement_cost(terr); //1 for grassland etc, 2 for hills etc, 3 for mountains
  231.                     LABEL_SET_BEST_VALUE:
  232.                     if (curr_val > best_val)
  233.                     {
  234.                         best_val = curr_val;
  235.                         best_direction = dir;
  236.                     }
  237.                 } //if diplomat
  238.                 else
  239.                 {
  240.                     impr = get_improvements(x2,y2);
  241.                     if ((impr&IM_CITY) == 0) //no city in square
  242.                     || get_city_area_civ(x2,y2) == 0) //or it's a barbarian city
  243.                     {
  244.                         impr = get_improvements(x2,y2); //yep, again...
  245.                         if ((impr&IM_IRRIGATION)==0 && (impr&IM_MINE)==0) //no irrigation and no mines here
  246.                             var_C = 0;
  247.                         else
  248.                             var_C = 6; //do want!
  249.                            
  250.                         if (get_city_area_civ(x2,y2) == 0)
  251.                             var_D = 0;
  252.                         else
  253.                             var_D = 4;  //city area or good terrain - do want!
  254.                             //not too sure if it actually returns non-zero value for good terrain outside of city area...
  255.                            
  256.                         curr_val = var_C+var_D+random(6);
  257.                         if (unit_id2 == -1) //no units in this direction
  258.                         {
  259.                             LABEL_REPEATED_PART:
  260.                             if (zoc_here == 0 //this square is free from enemy adjacent units (not in ocean) or there's a city here
  261.                             || get_unit_domain(unit) != UD_LAND //sea and air units ignore zones of control
  262.                             || unit_id2 != -1 //you can always move to square with other unit of your civ. Or you can attack enemy unit?..
  263.                             || check_ZOC(civ,x2,y2) == 0) //the next square is free from enemy adjacent units
  264.                             {
  265.                                 if (goto_dir == dir) //we are already going in this direction
  266.                                     curr_val += 6;
  267.                                 if (change_x[dir] == x_direction_to_city)
  268.                                     curr_val += 2;
  269.                                 if (change_y[dir] == y_direction_to_city)
  270.                                     curr_val += 2;
  271.                             }
  272.                             goto LABEL_SET_BEST_VALUE;
  273.                         }
  274.                         else //some units in this direciton
  275.                         {
  276.                             if (civ == gl_unit_civ) //it's a barbarian unit
  277.                             {
  278.                                 terr = get_terrain(x,y);
  279.                                 if (terr == SQ_OCEAN)
  280.                                 {
  281.                                     curr_val -= 20;
  282.                                     goto LABEL_REPEATED_PART;
  283.                                 }
  284.                             }
  285.                             else //it's an enemy
  286.                             {
  287.                                 terr = get_terrain(x,y);
  288.                                 if (terr != SQ_OCEAN)
  289.                                 {
  290.                                     if (get_unit_type(gl_unit2) != U_DIPLOMAT)
  291.                                         curr_val += 99;
  292.                                     goto LABEL_REPEATED_PART;
  293.                                 }
  294.                             }
  295.                         }
  296.                     } //no city in x2,y2 or it's a barbarian city
  297.                     else //there's a city in the next square
  298.                     {
  299.                         terr = get_terrain(x,y);
  300.                         if (terr != SQ_OCEAN)
  301.                             return dir; //direction of movement/attack
  302.                     }
  303.                 }
  304.             }
  305.             dir++;
  306.         } //while - check 8 adj. squares...
  307.         impr = get_improvements(x,y);
  308.         if ((impr&IM_CITY) == 0 || next_unit_in_stack != -1 || best_val >= 99)
  309.         {
  310.             goto_dir = best_direction;
  311.             return best_direction; //direction of movement/attack
  312.         }
  313.     } //not diplomat
  314.     return 0x20; //space->skip turn
  315. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement