From 1bdfbb1f7440385ef4a7a95d9a401015b4b1b926 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sat, 15 Oct 2022 19:03:30 +0300 Subject: [PATCH 24/24] Prevent barbarians from building multiple units of unique type See osdn #44863 Signed-off-by: Marko Lindqvist --- server/animals.c | 2 +- server/barbarian.c | 31 +++++++++++++++++++------------ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/server/animals.c b/server/animals.c index 7de3780b78..bc0f594007 100644 --- a/server/animals.c +++ b/server/animals.c @@ -76,7 +76,7 @@ static void place_animal(struct player *plr, int sqrdist) ptype = animal_for_terrain(tile_terrain(ptile)); - if (ptype != NULL) { + if (ptype != NULL && !utype_player_already_has_this_unique(plr, ptype)) { struct unit *punit; fc_assert_ret(can_exist_at_tile(ptype, ptile)); diff --git a/server/barbarian.c b/server/barbarian.c index 26a3051852..8593153d42 100644 --- a/server/barbarian.c +++ b/server/barbarian.c @@ -292,7 +292,8 @@ bool unleash_barbarians(struct tile *ptile) /* If unit cannot live on this tile, we just don't create one. * Maybe find_a_unit_type() should take tile parameter, so * we could get suitable unit if one exist. */ - if (is_native_tile(punittype, ptile)) { + if (is_native_tile(punittype, ptile) + && !utype_player_already_has_this_unique(barbarians, punittype)) { struct unit *barb_unit; barb_unit = create_unit(barbarians, ptile, punittype, 0, 0, -1); @@ -367,7 +368,8 @@ bool unleash_barbarians(struct tile *ptile) int rdir = random_unchecked_direction(ocean_tiles - checked_count, checked); boat = find_a_unit_type(L_BARBARIAN_BOAT, -1); - if (is_native_tile(boat, dir_tiles[rdir])) { + if (is_native_tile(boat, dir_tiles[rdir]) + && !utype_player_already_has_this_unique(barbarians, boat)) { (void) create_unit(barbarians, dir_tiles[rdir], boat, 0, 0, -1); btile = dir_tiles[rdir]; } @@ -578,24 +580,26 @@ static void try_summon_barbarians(void) } for (i = 0; i < barb_count; i++) { struct unit_type *punittype - = find_a_unit_type(L_BARBARIAN, L_BARBARIAN_TECH); + = find_a_unit_type(L_BARBARIAN, L_BARBARIAN_TECH); /* If unit cannot live on this tile, we just don't create one. * Maybe find_a_unit_type() should take tile parameter, so * we could get suitable unit if one exist. */ - if (is_native_tile(punittype, utile)) { + if (is_native_tile(punittype, utile) + && !utype_player_already_has_this_unique(barbarians, punittype)) { (void) create_unit(barbarians, utile, punittype, 0, 0, -1); really_created++; - log_debug("Created barbarian unit %s",utype_rule_name(punittype)); + log_debug("Created barbarian unit %s", utype_rule_name(punittype)); } } - - if (is_native_tile(leader_type, utile)) { + + if (is_native_tile(leader_type, utile) + && !utype_player_already_has_this_unique(barbarians, leader_type)) { (void) create_unit(barbarians, utile, leader_type, 0, 0, -1); really_created++; } - } else { /* sea raiders - their units will be veteran */ + } else { /* Sea raiders - their units will be veteran */ struct unit *ptrans; struct unit_type *boat; bool miniphase; @@ -618,9 +622,10 @@ static void try_summon_barbarians(void) CALL_PLR_AI_FUNC(phase_begin, barbarians, barbarians, TRUE); } - boat = find_a_unit_type(L_BARBARIAN_BOAT,-1); + boat = find_a_unit_type(L_BARBARIAN_BOAT, -1); if (is_native_tile(boat, utile) + && !utype_player_already_has_this_unique(barbarians, boat) && (is_safe_ocean(utile) || (!utype_has_flag(boat, UTYF_COAST_STRICT) && !utype_has_flag(boat, UTYF_COAST)))) { @@ -635,7 +640,8 @@ static void try_summon_barbarians(void) struct unit_type *barb = find_a_unit_type(L_BARBARIAN_SEA, L_BARBARIAN_SEA_TECH); - if (can_unit_type_transport(boat, utype_class(barb))) { + if (can_unit_type_transport(boat, utype_class(barb)) + && !utype_player_already_has_this_unique(barbarians, barb)) { (void) create_unit_full(barbarians, utile, barb, 0, 0, -1, -1, ptrans); really_created++; @@ -643,7 +649,8 @@ static void try_summon_barbarians(void) } } - if (can_unit_type_transport(boat, utype_class(leader_type))) { + if (can_unit_type_transport(boat, utype_class(leader_type)) + && !utype_player_already_has_this_unique(barbarians, leader_type)) { (void) create_unit_full(barbarians, utile, leader_type, 0, 0, -1, -1, ptrans); really_created++; @@ -661,7 +668,7 @@ static void try_summon_barbarians(void) return; } - /* Is this necessary? create_unit_full already sends unit info. */ + /* Is this necessary? create_unit_full() already sends unit info. */ unit_list_iterate(utile->units, punit2) { send_unit_info(NULL, punit2); } unit_list_iterate_end; -- 2.35.1