Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define IM_CITY 1
- #define IM_IRRIGATION 2
- #define IM_MINE 4
- #define SQ_OCEAN 10
- #define UR_DEFENCE 2 //land defence: only musketeers. In theory also militia, phalanx, riflemen and mech. inf.
- #define UR_TRANSPORT 5 //sail or frigate (in theory also trireme and transport)
- #define UD_LAND 0 //land unit
- #define UD_FLEET 2 //unit is a boat
- #define U_DIPLOMAT 0x2A
- change_x[9] = {0,0,1,1,1,0,-1,-1,-1};
- change_y[9] = {0,-1,-1,0,1,1,1,0,-1};
- check_ZOC(civ,x,y)
- {
- res = 0;
- impr = get_improvements(x,y);
- if ((impr & IM_CITY) == 0)
- res = check_ZOC_B(civ,x,y); //check blocking unit. If civ == player_civ - draw it and draw terrain and city in its square.
- else
- res = 0; //unit can always go from and to the city
- return res;
- }
- get_city_area_civ(x,y)
- {
- return (current_terrain_value[x][y]&7);
- //returns 0..7 (city civ) for 21 squares of city area
- //but what about other squares?
- //if it's similar to save file (see current terrain value in JCivED), then...
- //8 for +1 radius line around a city area -> returns 0 - it's ok...
- //but if there's no city nearby then current land value can be 0 or 9..15
- //problem here: what about 9..15 land value outside city areas?
- //it will return current_terrain_value[x][y]-8 instead of civ number. But m.b. this is ok...
- }
- barbarian_unit_ai_func(civ, unit_id) //civ == 0
- {
- unit = get_unit_type(civ,unit_id); //legion, cavalry, diplomat etc.
- x = get_unit_x(civ,unit_id);
- y = get_unit_y(civ,unit_id);
- if (y < 2 || y > 47)
- {
- unkn_var = disband_unit(param_civ,unit_id); //it returns void! it never returns anything anywhere but here!
- return unkn_var; //?
- }
- 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...)
- //zone of control in current square. If zoc_here == 1 && zoc_next == 1 -> no go
- if (get_unit_role(unit) == UR_TRANSPORT)
- {
- if (next_unit_in_stack != -1) //has passengers
- {
- city = find_closest_city(x,y); //return city id and set global var: gl_distance
- dist_closest_city = gl_distance;
- for (dir = 1; dir < 9; dir++)
- {
- x2 = normalize(x+change_x[dir]); //the world is round. For example, x = -1 -> x = 79
- y2 = y+change_y[dir];
- terr = get_terrain(x2,y2);
- impr = get_improvements(x2,y2);
- if (dist_closest_city < 9 && terr != SQ_OCEAN
- && (impr&IM_CITY) == 0 //there's no city in this square
- && civ_id_of_unit_in_xy(x2,y2) == -1 //no units by any civ in this square
- && y2 > 1 && y2 < 48)
- {
- if (map_of_explored_terrain[x][y] & (1<<player_civ)) != 0 //square is explored by player civ
- && get_city_civ(city) == player_civ)
- {
- cont1 = get_continent(city_x[city],city_y[city]);
- cont2 = get_continent(x2,y2);
- if (cont1 == cont2)
- {
- unit_visibility |= (1<<player_civ); //set visibility bit of player civ to 1
- //fix view position? (if incorrect??) and change view position to x-8,y-6
- gl_message_type = 3; //Military Advisor:
- //message about landing...
- }
- }
- unit_visibility |= get_terrain_visibility(x,y);
- unit_remaining_moves = 0;
- return 0x75; //'u'->unload
- }
- if (civ_id_of_unit_in_xy(x2,y2) > 0) //somebody is next to us and it's not a barbarian
- return dir; //direction of movement/attack
- } //for: all 8 directions
- if (goto_x != -1) //boat is already in GoTo state
- return 0;
- } //transport has passengers
- best_city = 0;
- cit_count = 0;
- best_val; //best_val value was undefined?
- do
- {
- if (city_flags[cit_count] != -1) //city exists
- {
- distance = find_distance(x,y,city_x[cit_count],city_y[cit_count]);
- city_val = get_city_gold_loot(cit_count); // city_population*civ_treasure/(civ_population+1)
- city_val = (city_val+50)/(distance+1); //formula for target city
- if (city_val > best_val)
- {
- best_city = cit_count;
- best_val = city_val;
- }
- }
- cit_count++;
- }
- while (cit_count < 128);
- if (best_city != 0)
- {
- goto_x = city_x[cit_count];
- goto_y = city_y[cit_count];
- return 0;
- }
- goto LABEL_DISBAND;
- } //unit role: transport
- city = find_closest_city(x,y); //it sets global var: gl_distance
- dist_closest_city = gl_distance;
- cit_civ = get_city_civ(city);
- if (dist_closest_city == 0 && (next_unit_in_stack == -1 || get_unit_role(unit) == UR_DEFENCE))
- return 0x66; //'f' -> fortify
- x_direction_to_city = -2;
- y_direction_to_city = -2;
- if (game_turn&3 == 0) //every 4th turn
- {
- cont1 = get_continent(x,y);
- cont2 = get_continent(city_x[city], city_y[city]);
- if ((cont1 != cont2) || dist_closest_city > 8)
- {
- goto LABEL_DISBAND;
- }
- }
- if (city != -1) //at least 1 city exists in the world
- {
- cont1 = get_continent(x,y);
- cont2 = get_continent(city_x[city], city_y[city]);
- if (cont1 == cont2
- && (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.
- {
- x_direction_to_city = get_sign(city_x[city] - x); //-1 if < 0 0 if 0 +1 if > 0
- y_direction_to_city = get_sign(city_y[city] - y);
- }
- }
- if (cit_civ == civ //barbarian city
- || (civ_cities_total[cit_civ] < 2 && gold[cit_civ] < 100)) //or city owner has only 1 city and less than 100$
- {
- x_direction_to_city = -2;
- y_direction_to_city = -2;
- }
- if (x_direction_to_city != -2)
- {
- //go straight to the city!
- goto_x = city_x[city];
- goto_y = city_y[city];
- goto_dir = moveUnitGoto(civ,unit_id); //returns direction of next move: 1..9 //Unknown9 field in JCivED.
- //moveUnitGoto was disassembled by darkpanda. You can find it somewhere on the forums...
- }
- goto_x = -1; //GoTo off. Barbarian units don't check it anywhere anyway and boat routine never go here, so it's kinda pointless?..
- if (unit == U_DIPLOMAT)
- {
- terr = get_terrain(x,y);
- 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
- {
- return 0x20; //space -> skip turn
- }
- if (terr == SQ_OCEAN)
- {
- if (dist_closest_city > 2)
- goto LABEL_NOT_DIPLOMAT;
- }
- else
- {
- unit_id2 = find_my_closest_unit_id(civ,unit_id,x,y); //set gl_distance
- dist_closest_unit = gl_distance;
- if (dist_closest_unit < 4 && get_unit_type(civ,unit_id2) != U_DIPLOMAT)
- {
- goto_x = get_unit_x(civ,unit_id2);
- goto_y = get_unit_y(civ,unit_id2);
- return 0; //do nothing?
- }
- if ((game_turn&7)+4 > dist_closest_city) //if remainder of dividing game_turn by 8 +4 > dist_closest_city
- goto LABEL_NOT_DIPLOMAT;
- }
- LABEL_DISBAND:
- disband_unit(civ,unit_id);
- }
- else
- {
- LABEL_NOT_DIPLOMAT:
- best_direction = 0;
- best_val = -999;
- dir = 1;
- while (dir < 9)
- {
- x2 = normalize(x+change_x[dir]);
- y2 = y+change_y[dir];
- terr = get_terrain(x2,y2);
- if (((get_unit_domain(unit) == UD_FLEET) == (terr == SQ_OCEAN)) //if boat and in ocean OR not a boat and on land
- && check_if_xy_within_the_map(x2,y2)) //X:0-79,Y:0-49 returns 0 if not
- {
- unit_id2 = get_unit_id_in_xy(x2,y2); //returns -1 if no units here. Sets gl_unit_civ if some unit is here.
- if (get_unit_type(civ, unit_id) == U_DIPLOMAT)
- {
- curr_val = 0;
- if (unit_id2 != -1)
- {
- if (civ == gl_unit_civ) //it's a barbarian unit
- {
- curr_val = 99;
- }
- else //it's an enemy unit
- {
- curr_val = -99;
- }
- }
- find_closest_city(x2,y2); //set gl_distance
- dist_closest_city = gl_distance;
- rand = random(4); //0..3
- curr_val += dist_closest_city*4+rand+get_terrain_movement_cost(terr); //1 for grassland etc, 2 for hills etc, 3 for mountains
- LABEL_SET_BEST_VALUE:
- if (curr_val > best_val)
- {
- best_val = curr_val;
- best_direction = dir;
- }
- } //if diplomat
- else
- {
- impr = get_improvements(x2,y2);
- if ((impr&IM_CITY) == 0) //no city in square
- || get_city_area_civ(x2,y2) == 0) //or it's a barbarian city
- {
- impr = get_improvements(x2,y2); //yep, again...
- if ((impr&IM_IRRIGATION)==0 && (impr&IM_MINE)==0) //no irrigation and no mines here
- var_C = 0;
- else
- var_C = 6; //do want!
- if (get_city_area_civ(x2,y2) == 0)
- var_D = 0;
- else
- var_D = 4; //city area or good terrain - do want!
- //not too sure if it actually returns non-zero value for good terrain outside of city area...
- curr_val = var_C+var_D+random(6);
- if (unit_id2 == -1) //no units in this direction
- {
- LABEL_REPEATED_PART:
- if (zoc_here == 0 //this square is free from enemy adjacent units (not in ocean) or there's a city here
- || get_unit_domain(unit) != UD_LAND //sea and air units ignore zones of control
- || unit_id2 != -1 //you can always move to square with other unit of your civ. Or you can attack enemy unit?..
- || check_ZOC(civ,x2,y2) == 0) //the next square is free from enemy adjacent units
- {
- if (goto_dir == dir) //we are already going in this direction
- curr_val += 6;
- if (change_x[dir] == x_direction_to_city)
- curr_val += 2;
- if (change_y[dir] == y_direction_to_city)
- curr_val += 2;
- }
- goto LABEL_SET_BEST_VALUE;
- }
- else //some units in this direciton
- {
- if (civ == gl_unit_civ) //it's a barbarian unit
- {
- terr = get_terrain(x,y);
- if (terr == SQ_OCEAN)
- {
- curr_val -= 20;
- goto LABEL_REPEATED_PART;
- }
- }
- else //it's an enemy
- {
- terr = get_terrain(x,y);
- if (terr != SQ_OCEAN)
- {
- if (get_unit_type(gl_unit2) != U_DIPLOMAT)
- curr_val += 99;
- goto LABEL_REPEATED_PART;
- }
- }
- }
- } //no city in x2,y2 or it's a barbarian city
- else //there's a city in the next square
- {
- terr = get_terrain(x,y);
- if (terr != SQ_OCEAN)
- return dir; //direction of movement/attack
- }
- }
- }
- dir++;
- } //while - check 8 adj. squares...
- impr = get_improvements(x,y);
- if ((impr&IM_CITY) == 0 || next_unit_in_stack != -1 || best_val >= 99)
- {
- goto_dir = best_direction;
- return best_direction; //direction of movement/attack
- }
- } //not diplomat
- return 0x20; //space->skip turn
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement