From 9496f77c17e70520ed850be835487635298ec4c0 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sat, 15 Oct 2022 18:54:39 +0300 Subject: [PATCH 41/41] Prevent barbarians from building multiple units of unique type See osdn #44863 Signed-off-by: Marko Lindqvist --- server/animals.c | 2 +- server/barbarian.c | 27 +++++++++++++++++---------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/server/animals.c b/server/animals.c index 35bd939ec0..6a8a587066 100644 --- a/server/animals.c +++ b/server/animals.c @@ -78,7 +78,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(&(wld.map), ptype, ptile)); diff --git a/server/barbarian.c b/server/barbarian.c index 74c97f4539..bbe2b66997 100644 --- a/server/barbarian.c +++ b/server/barbarian.c @@ -313,7 +313,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); @@ -388,7 +389,8 @@ bool unleash_barbarians(struct tile *ptile) int rdir = random_unchecked_direction(ocean_tiles - checked_count, checked); candidate = find_a_unit_type(L_BARBARIAN_BOAT, L_BARBARIAN_BOAT_TECH); - if (is_native_tile(candidate, dir_tiles[rdir])) { + if (is_native_tile(candidate, dir_tiles[rdir]) + && !utype_player_already_has_this_unique(barbarians, candidate)) { boat = create_unit(barbarians, dir_tiles[rdir], candidate, 0, 0, -1); } @@ -617,24 +619,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; @@ -660,6 +664,7 @@ static void try_summon_barbarians(void) boat = find_a_unit_type(L_BARBARIAN_BOAT, L_BARBARIAN_BOAT_TECH); if (is_native_tile(boat, utile) + && !utype_player_already_has_this_unique(barbarians, boat) && (is_safe_ocean(&(wld.map), utile) || (!utype_has_flag(boat, UTYF_COAST_STRICT) && !utype_has_flag(boat, UTYF_COAST)))) { @@ -674,7 +679,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++; @@ -682,7 +688,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++; @@ -700,7 +707,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