Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding barracks fort priority #1063

Merged
merged 13 commits into from
Apr 17, 2024
88 changes: 80 additions & 8 deletions src/building/barracks.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ int building_get_barracks_for_weapon(int x, int y, int resource, int road_networ
if (b->resources[RESOURCE_WEAPONS] >= MAX_WEAPONS_BARRACKS) {
continue;
}
if (!b->accept_delivery) {
continue;
}
int dist = calc_maximum_distance(b->x, b->y, x, y);
dist += 8 * b->resources[RESOURCE_WEAPONS];
if (dist < min_dist) {
Expand All @@ -50,7 +53,8 @@ int building_get_barracks_for_weapon(int x, int y, int resource, int road_networ
building *monument = building_first_of_type(BUILDING_GRAND_TEMPLE_MARS);
if (monument && monument->monument.phase == MONUMENT_FINISHED &&
is_valid_destination(monument, road_network_id) &&
(monument->resources[RESOURCE_WEAPONS] < MAX_WEAPONS_BARRACKS)) {
(monument->resources[RESOURCE_WEAPONS] < MAX_WEAPONS_BARRACKS) &&
monument->accept_delivery) {
int dist = calc_maximum_distance(monument->x, monument->y, x, y);
dist += 8 * monument->resources[RESOURCE_WEAPONS];
if (dist < min_dist) {
Expand Down Expand Up @@ -79,6 +83,29 @@ static int get_closest_legion_needing_soldiers(const building *barracks)
int recruit_type = LEGION_RECRUIT_NONE;
int min_formation_id = 0;
int min_distance = INFINITE;

int priority_recruitment = barracks->subtype.barracks_priority;
int requiered_recruitment = recruit_type;

switch (priority_recruitment) {
case PRIORITY_FORT:
requiered_recruitment = LEGION_RECRUIT_LEGIONARY;
break;
case PRIORITY_FORT_JAVELIN:
requiered_recruitment = LEGION_RECRUIT_JAVELIN;
break;
case PRIORITY_FORT_MOUNTED:
requiered_recruitment = LEGION_RECRUIT_MOUNTED;
break;
case PRIORITY_FORT_AUXILIA_INFANTRY:
requiered_recruitment = LEGION_RECRUIT_INFANTRY;
break;
case PRIORITY_FORT_AUXILIA_ARCHERY:
default:
break;
}

// find by recruitment priority
for (int i = 1; i < formation_count(); i++) {
formation *m = formation_get(i);
if (!m->in_use || !m->is_legion) {
Expand All @@ -92,13 +119,41 @@ static int get_closest_legion_needing_soldiers(const building *barracks)
}
building *fort = building_get(m->building_id);
int dist = calc_maximum_distance(barracks->x, barracks->y, fort->x, fort->y);
if (m->legion_recruit_type > recruit_type ||
(m->legion_recruit_type == recruit_type && dist < min_distance)) {

// find closest one
if (m->legion_recruit_type == requiered_recruitment || (m->legion_recruit_type == recruit_type && dist < min_distance)) {
recruit_type = m->legion_recruit_type;
min_formation_id = m->id;
min_distance = dist;
min_formation_id = m->id;
}
}

// find default
if (!min_formation_id) {
for (int i = 1; i < formation_count(); i++) {
formation *m = formation_get(i);
if (!m->in_use || !m->is_legion) {
continue;
}
if (m->in_distant_battle || m->legion_recruit_type == LEGION_RECRUIT_NONE) {
continue;
}
if (m->legion_recruit_type == LEGION_RECRUIT_LEGIONARY && barracks->resources[RESOURCE_WEAPONS] <= 0) {
continue;
}
building *fort = building_get(m->building_id);
int dist = calc_maximum_distance(barracks->x, barracks->y, fort->x, fort->y);

// find closest one
if (m->legion_recruit_type > recruit_type || (m->legion_recruit_type == recruit_type && dist < min_distance)) {
recruit_type = m->legion_recruit_type;
min_distance = dist;
min_formation_id = m->id;
}
}
}


return min_formation_id;
}

Expand Down Expand Up @@ -170,11 +225,20 @@ static building *get_unmanned_tower_of_type(building_type type, building *barrac

building *building_barracks_get_unmanned_tower(building *barracks, map_point *road)
{
building *tower = get_unmanned_tower_of_type(BUILDING_TOWER, barracks, road);
int first_priority = BUILDING_TOWER;
int second_priority = BUILDING_WATCHTOWER;

// invert priority
if (barracks->subtype.barracks_priority == PRIORITY_WATCHTOWER) {
first_priority = BUILDING_WATCHTOWER;
second_priority = BUILDING_TOWER;
}

building *tower = get_unmanned_tower_of_type(first_priority, barracks, road);
if (tower) {
return tower;
}
tower = get_unmanned_tower_of_type(BUILDING_WATCHTOWER, barracks, road);
tower = get_unmanned_tower_of_type(second_priority, barracks, road);
return tower;
}

Expand All @@ -198,9 +262,17 @@ int building_barracks_create_tower_sentry(building *barracks, int x, int y)
return 1;
}

void building_barracks_toggle_priority(building *barracks)
void building_barracks_set_priority(building *barracks, int priority)
{
// TODO remove when archery available
if (priority != 4) {
barracks->subtype.barracks_priority = priority;
}
}

void building_barracks_toggle_delivery(building *barracks)
{
barracks->subtype.barracks_priority = 1 - barracks->subtype.barracks_priority;
barracks->accept_delivery = barracks->accept_delivery ? 0 : 1;
}

int building_barracks_get_priority(building *barracks)
Expand Down
13 changes: 10 additions & 3 deletions src/building/barracks.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,21 @@ building *building_barracks_get_unmanned_tower(building *barracks, map_point *ro

int building_barracks_create_tower_sentry(building *barracks, int x, int y);

void building_barracks_toggle_priority(building* barracks);
void building_barracks_set_priority(building* barracks, int priority);

void building_barracks_toggle_delivery(building* barracks);

int building_barracks_get_priority(building* barracks);


typedef enum {
PRIORITY_TOWER = 0,
PRIORITY_FORT = 1,
PRIORITY_FORT = 0,
PRIORITY_FORT_JAVELIN = 1,
PRIORITY_FORT_MOUNTED = 2,
PRIORITY_FORT_AUXILIA_INFANTRY = 3,
PRIORITY_FORT_AUXILIA_ARCHERY = 4,
PRIORITY_TOWER = 5,
PRIORITY_WATCHTOWER = 6,
} barracks_priority;

#endif // BUILDING_BARRACKS_H
1 change: 1 addition & 0 deletions src/building/building.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ typedef struct building {
unsigned char fumigation_direction;
short resources[RESOURCE_MAX];
unsigned char accepted_goods[RESOURCE_MAX];
unsigned char accept_delivery;
} building;

building *building_get(int id);
Expand Down
7 changes: 7 additions & 0 deletions src/building/construction_building.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,9 @@ static void add_to_map(int type, building *b, int size, int orientation, int wat
case BUILDING_PANTHEON:
map_tiles_update_area_roads(b->x, b->y, 9);
building_monument_set_phase(b, MONUMENT_START);
if (type == BUILDING_GRAND_TEMPLE_MARS) {
b->accept_delivery = 1;
}
break;
case BUILDING_MESS_HALL:
b->data.market.is_mess_hall = 1;
Expand Down Expand Up @@ -295,6 +298,10 @@ static void add_to_map(int type, building *b, int size, int orientation, int wat
case BUILDING_SHRINE_VENUS:
b->subtype.orientation = building_rotation_get_rotation();
add_building(b);
break;
case BUILDING_BARRACKS:
b->accept_delivery = 1;
add_building(b);
break;

}
Expand Down
10 changes: 9 additions & 1 deletion src/building/figure.c
Original file line number Diff line number Diff line change
Expand Up @@ -1130,7 +1130,11 @@ static void spawn_figure_grand_temple_mars(building *b)
b->figure_spawn_delay = 0;
map_has_road_access(b->x, b->y, b->size, &road);
switch (b->subtype.barracks_priority) {
case PRIORITY_FORT:
case PRIORITY_FORT:
case PRIORITY_FORT_JAVELIN:
case PRIORITY_FORT_MOUNTED:
case PRIORITY_FORT_AUXILIA_INFANTRY:
case PRIORITY_FORT_AUXILIA_ARCHERY:
if (!building_barracks_create_soldier(b, road.x, road.y)) {
building_barracks_create_tower_sentry(b, road.x, road.y);
}
Expand Down Expand Up @@ -1570,6 +1574,10 @@ static void spawn_figure_barracks(building *b)
map_has_road_access(b->x, b->y, b->size, &road);
switch (b->subtype.barracks_priority) {
case PRIORITY_FORT:
case PRIORITY_FORT_JAVELIN:
case PRIORITY_FORT_MOUNTED:
case PRIORITY_FORT_AUXILIA_INFANTRY:
case PRIORITY_FORT_AUXILIA_ARCHERY:
if (!building_barracks_create_soldier(b, road.x, road.y)) {
building_barracks_create_tower_sentry(b, road.x, road.y);
}
Expand Down
6 changes: 6 additions & 0 deletions src/building/state.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ void building_state_save_to_buffer(buffer *buf, const building *b)
buffer_write_u8(buf, b->accepted_goods[i]);
}

buffer_write_u8(buf, b->accept_delivery);

// New building state code should always be added at the end to preserve savegame retrocompatibility
// Also, don't forget to update BUILDING_STATE_CURRENT_BUFFER_SIZE and if possible, add a new macro like
// BUILDING_STATE_NEW_FEATURE_BUFFER_SIZE with the full building state buffer size including all added features
Expand Down Expand Up @@ -600,6 +602,10 @@ void building_state_load_from_buffer(buffer *buf, building *b, int building_buf_
}
}

if (building_buf_size > BUILDING_STATE_DELIVERY) {
b->accept_delivery = buffer_read_u8(buf);
}

// Update resource requirement changes on monuments
if (building_monument_is_monument(b) && b->monument.phase != MONUMENT_FINISHED) {
for (resource_type resource = 0; resource < RESOURCE_MAX; resource++) {
Expand Down
1 change: 1 addition & 0 deletions src/building/state.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define BUILDING_STATE_WITHOUT_RESOURCES (BUILDING_STATE_SICKNESS - RESOURCE_MAX_LEGACY) // 126 (plus variable resource size)
#define BUILDING_STATE_DYNAMIC_RESOURCES (BUILDING_STATE_WITHOUT_RESOURCES + BUILDING_STATE_NONSTATIC_RESOURCE_SIZE)
#define BUILDING_STATE_CURRENT_BUFFER_SIZE (BUILDING_STATE_DYNAMIC_RESOURCES + 8)
#define BUILDING_STATE_DELIVERY (BUILDING_STATE_CURRENT_BUFFER_SIZE + 1)

void building_state_save_to_buffer(buffer *buf, const building *b);

Expand Down
3 changes: 2 additions & 1 deletion src/figure/formation.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ enum {
LEGION_RECRUIT_MOUNTED = 1,
LEGION_RECRUIT_JAVELIN = 2,
LEGION_RECRUIT_LEGIONARY = 3,
LEGION_RECRUIT_INFANTRY = 4
LEGION_RECRUIT_INFANTRY = 4,
LEGION_RECRUIT_ARCHERY = 5
};

typedef enum {
Expand Down
12 changes: 12 additions & 0 deletions src/translation/english.c
Original file line number Diff line number Diff line change
Expand Up @@ -1416,6 +1416,18 @@ static translation_string all_strings[] = {
{TR_EDITOR_CAESAR_SALARY, "Caesar's salary"},
{TR_CITY_MESSAGE_TEXT_CARAVANSERAI_COMPLETE, "The caravanserai is completed. New commercial horizons are emerging. Caravans from all over the world are eager to come and trade in your city."},
{TR_CONFIG_SHOW_DESIRABILITY_RANGE, "Show desirability when building mausoleums and nymphaeums"},
{TR_WINDOW_BARRACKS_PRIORITY, "Recruitment Priority:"},
{TR_WINDOW_BARRACKS_FORTS, "Forts"},
{TR_WINDOW_BARRACKS_TOWERS, "Towers"},
{TR_TOOLTIP_BARRACKS_PRIORITY_FORT, "Prioritize Legionary training"},
{TR_TOOLTIP_BARRACKS_PRIORITY_JAVELIN, "Prioritize Javelin training"},
{TR_TOOLTIP_BARRACKS_PRIORITY_MOUNTED, "Prioritize Cavalery training"},
{TR_TOOLTIP_BARRACKS_PRIORITY_AUXINF, "Prioritize Infantryman training"},
{TR_TOOLTIP_BARRACKS_PRIORITY_AUXARCH, "Prioritize Archer training"},
{TR_TOOLTIP_BARRACKS_PRIORITY_TOWER, "Prioritize Towers delivery"},
{TR_TOOLTIP_BARRACKS_PRIORITY_WATCHTOWER, "Prioritize Watchtowers delivery"},
{TR_TOOLTIP_BUTTON_REJECT_DELIVERY, "Stopping weapons delivery from Armory"},
{TR_TOOLTIP_BUTTON_ACCEPT_DELIVERY, "Allowing weapons delivery from Armory"},
};

void translation_english(const translation_string **strings, int *num_strings)
Expand Down
14 changes: 13 additions & 1 deletion src/translation/french.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ static translation_string all_strings[] = {
{TR_BUILDING_PANTHEON_DESC_MODULE_1, "Pantheum Ara Maxima"},
{TR_BUILDING_PANTHEON_DESC_MODULE_2, "Pantheum Roma Aeterna"},
{TR_BUILDING_GRAND_TEMPLE_MENU, "Temple monumental"},
{TR_BUILDING_WORK_CAMP, "Camp de travail"},
{TR_BUILDING_WORK_CAMP, "Chantier de construction"},
{TR_BUILDING_WORK_CAMP_DESC, "Les ouvriers se rassemblent ici pour transporter les matériaux vers les chantiers de construction."},
{TR_BUILDING_DEPOT, "Dépôt de charrettes"},
{TR_BUILDING_CAT_DEPOT, "Dépôt de chat(rrettes)"},
Expand Down Expand Up @@ -1409,6 +1409,18 @@ static translation_string all_strings[] = {
{TR_EDITOR_CAESAR_SALARY, "Salaire de Caesar"},
{TR_CITY_MESSAGE_TEXT_CARAVANSERAI_COMPLETE, "Le caravanserail est achevé. De nouveaux horizons commerciaux se profilent. Les caravanes des quatre coins du monde sont enthousiastes à l'idée de venir commercer dans votre cité."},
{TR_CONFIG_SHOW_DESIRABILITY_RANGE , "Voir l'attrait des mausolées et des nymphées lors du placement"},
{TR_WINDOW_BARRACKS_PRIORITY, "Priorité de recrutement:"},
{TR_WINDOW_BARRACKS_FORTS, "Forts"},
{TR_WINDOW_BARRACKS_TOWERS, "Tours"},
{TR_TOOLTIP_BARRACKS_PRIORITY_FORT, "Prioriser la formation des Légionnaires"},
{TR_TOOLTIP_BARRACKS_PRIORITY_JAVELIN, "Prioriser la formation des Javelines"},
{TR_TOOLTIP_BARRACKS_PRIORITY_MOUNTED, "Prioriser la formation des Cavaliers"},
{TR_TOOLTIP_BARRACKS_PRIORITY_AUXINF, "Prioriser la formation des Fantassins"},
{TR_TOOLTIP_BARRACKS_PRIORITY_AUXARCH, "Prioriser la formation des Archers"},
{TR_TOOLTIP_BARRACKS_PRIORITY_TOWER, "Prioriser la livraison des Tours"},
{TR_TOOLTIP_BARRACKS_PRIORITY_WATCHTOWER, "Prioriser la livraison des Tours de guet"},
{TR_TOOLTIP_BUTTON_REJECT_DELIVERY, "Refuser la livraison d'armes par les Armureries"},
{TR_TOOLTIP_BUTTON_ACCEPT_DELIVERY, "Accepter la livraison d'armes par les Armureries"},
};

void translation_french(const translation_string **strings, int *num_strings)
Expand Down
12 changes: 12 additions & 0 deletions src/translation/translation.h
Original file line number Diff line number Diff line change
Expand Up @@ -1410,6 +1410,18 @@ typedef enum {
TR_EDITOR_CAESAR_SALARY,
TR_CITY_MESSAGE_TEXT_CARAVANSERAI_COMPLETE,
TR_CONFIG_SHOW_DESIRABILITY_RANGE,
TR_WINDOW_BARRACKS_PRIORITY,
TR_WINDOW_BARRACKS_FORTS,
TR_WINDOW_BARRACKS_TOWERS,
TR_TOOLTIP_BARRACKS_PRIORITY_FORT,
TR_TOOLTIP_BARRACKS_PRIORITY_JAVELIN,
TR_TOOLTIP_BARRACKS_PRIORITY_MOUNTED,
TR_TOOLTIP_BARRACKS_PRIORITY_AUXINF,
TR_TOOLTIP_BARRACKS_PRIORITY_AUXARCH,
TR_TOOLTIP_BARRACKS_PRIORITY_TOWER,
TR_TOOLTIP_BARRACKS_PRIORITY_WATCHTOWER,
TR_TOOLTIP_BUTTON_REJECT_DELIVERY,
TR_TOOLTIP_BUTTON_ACCEPT_DELIVERY,
TRANSLATION_MAX_KEY
} translation_key;

Expand Down
17 changes: 10 additions & 7 deletions src/window/building/culture.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ void window_building_draw_amphitheater(building_info_context *c)
} else {
lang_text_draw(71, 9, c->x_offset + 32, c->y_offset + 234, FONT_NORMAL_BROWN);
}
window_building_draw_description_at(c, BLOCK_SIZE * c->height_blocks - 80, 71, 1);
window_building_draw_description_at(c, BLOCK_SIZE * c->height_blocks - 90, 71, 1);
}

static void draw_entertainment_school(building_info_context *c, const char *sound_file, int group_id)
Expand Down Expand Up @@ -589,7 +589,7 @@ static void draw_grand_temple_mars_military(building_info_context *c)
{
int y = 60;
data.building_id = c->building_id;
image_draw(resource_get_data(RESOURCE_WEAPONS)->image.icon, c->x_offset + 24, c->y_offset + y - 5,
image_draw(resource_get_data(RESOURCE_WEAPONS)->image.icon, c->x_offset + 25, c->y_offset + y - 5,
COLOR_MASK_NONE, SCALE_NONE);
building *b = building_get(c->building_id);
if (b->resources[RESOURCE_WEAPONS] < 1) {
Expand All @@ -598,9 +598,11 @@ static void draw_grand_temple_mars_military(building_info_context *c)
lang_text_draw_amount(8, 10, b->resources[RESOURCE_WEAPONS], c->x_offset + 52, c->y_offset + y, FONT_NORMAL_BLACK);
}

lang_text_draw(50, 21, c->x_offset + 236, c->y_offset + y, FONT_NORMAL_BLACK); // "Priority"
lang_text_draw(91, 0, c->x_offset + 326, c->y_offset + y, FONT_NORMAL_BLACK); // "Tower"
lang_text_draw(89, 0, c->x_offset + 326, c->y_offset + y + 20, FONT_NORMAL_BLACK); // "Fort"
lang_text_draw(CUSTOM_TRANSLATION, TR_WINDOW_BARRACKS_PRIORITY, c->x_offset + 25, c->y_offset + 88, FONT_NORMAL_BLACK); // "Priority"

inner_panel_draw(c->x_offset + 16, c->y_offset + 108, c->width_blocks - 2, 5);
lang_text_draw(CUSTOM_TRANSLATION, TR_WINDOW_BARRACKS_FORTS, c->x_offset + 50, c->y_offset + 113, FONT_NORMAL_BROWN); // "Forts"
lang_text_draw(CUSTOM_TRANSLATION, TR_WINDOW_BARRACKS_TOWERS, c->x_offset + 327, c->y_offset + 113, FONT_NORMAL_BROWN); // "Towers"
}

static void draw_temple(building_info_context *c, const char *sound_file, int group_id)
Expand Down Expand Up @@ -752,7 +754,8 @@ void window_building_draw_grand_temple_foreground(building_info_context *c)
16 * (c->width_blocks - 10), FONT_NORMAL_BLACK, 0);
}
if (b->type == BUILDING_GRAND_TEMPLE_MARS) {
window_building_draw_priority_buttons(c->x_offset + 285, c->y_offset + 55);
window_building_draw_priority_buttons(c->x_offset + 50, c->y_offset + 133, b->id);
window_building_draw_delivery_buttons(c->x_offset + 408, c->y_offset + 40, b->id);
}
}

Expand Down Expand Up @@ -799,7 +802,7 @@ void window_building_draw_grand_temple_mars(building_info_context *c)
draw_grand_temple(c, "wavs/temple_war.wav", TR_BUILDING_GRAND_TEMPLE_MARS_DESC,
TR_BUILDING_GRAND_TEMPLE_MARS_BONUS_DESC,
assets_get_image_id("UI", "Mars L Banner"),
TR_BUILDING_MARS_TEMPLE_QUOTE, GOD_MARS, 50);
TR_BUILDING_MARS_TEMPLE_QUOTE, GOD_MARS, 150);
}

void window_building_draw_grand_temple_venus(building_info_context *c)
Expand Down
Loading
Loading