diff --git a/changelog.md b/changelog.md index eeab1c4c..ebd79e24 100644 --- a/changelog.md +++ b/changelog.md @@ -2,7 +2,8 @@ ##Features/Improvements : * **[Units/Factions]** Added P-47D-30 for factions allies_1944 -* **[Mission Generator]** CAP flights have been slightly reworked +* **[Units/Factions]** Replaced S3-B Tanker by KC130 for most factions +* **[Mission Generator]** AI Flight generator has been reworked * **[Mission Generator]** Add PP points for JF-17 on STRIKE missions * **[Mission Generator]** Add ST point for F-14B on STRIKE missions * **[Mission Generator]** Flights with client slots will never be delayed @@ -18,12 +19,13 @@ ##Fixed issues : * **[Mission Generator]** When playing as RED the activation trigger would not be properly generated -* **[Mission Generator]** Changed "strike" payload for Su-24M -* **[Mission Generator]** Changed "strike" payload for JF-17 +* **[Mission Generator]** Changed "strike" payload for Su-24M that was innefective +* **[Mission Generator]** Changed "strike" payload for JF-17 to use LS-6 bombs instead of GBU * **[Mission Generator]** FW-190A8 is now properly considered as a flyable * **[Maps/Campaign]** Now using Vasiani airport instead of Soganlung in North Caucasus campaign (More parking slots) * **[Info Panel]** Message displayed on base capture event stated that the ennemy captured an airbase, while it was the player who captured it. * **[Map]** Graphical glitch on map when one building of an objective was destroyed, but not the others +* **[Map]** Change power station template. (Buildings could end up superposed). #2.0 RC 6 diff --git a/game/db.py b/game/db.py index 100824cf..ca143278 100644 --- a/game/db.py +++ b/game/db.py @@ -1033,14 +1033,6 @@ def _validate_db(): assert unit_type not in total_set, "{} is duplicate for task {}".format(unit_type, t) total_set.add(unit_type) - # check country allegiance - for unit_type in total_set: - did_find = False - for country_units_list in FACTIONS.values(): - if unit_type in country_units_list["units"]: - did_find = True - print("WARN : {} not in country list".format(unit_type)) - # check prices for unit_type in total_set: assert unit_type in PRICES, "{} not in prices".format(unit_type) diff --git a/game/event/event.py b/game/event/event.py index 96ae6fef..28a53011 100644 --- a/game/event/event.py +++ b/game/event/event.py @@ -216,28 +216,27 @@ class Event: id = int(captured.split("||")[0]) new_owner_coalition = int(captured.split("||")[1]) + captured_cps = [] for cp in self.game.theater.controlpoints: if cp.id == id: - pname = "" if cp.captured and new_owner_coalition != coalition: cp.captured = False - info = Information(cp.name + " lost !", - "We took control of " + cp.name + "! Great job !", - self.game.turn) - self.game.informations.append(info) - pname = self.game.enemy_name - elif not(cp.captured) and new_owner_coalition == coalition: - cp.captured = True info = Information(cp.name + " captured !", "The ennemy took control of " + cp.name + "\nShame on us !", self.game.turn) self.game.informations.append(info) + pname = self.game.enemy_name + captured_cps.append(cp) + elif not(cp.captured) and new_owner_coalition == coalition: + cp.captured = True + info = Information(cp.name + " lost !", "We took control of " + cp.name + "! Great job !", self.game.turn) + self.game.informations.append(info) pname = self.game.player_name + captured_cps.append(cp) else: continue cp.base.aircraft = {} cp.base.armor = {} - cp.base.aa = {} airbase_def_id = 0 for g in cp.ground_objects: @@ -246,6 +245,10 @@ class Event: generate_airbase_defense_group(airbase_def_id, g, pname, self.game, cp) airbase_def_id = airbase_def_id + 1 + for cp in captured_cps: + logging.info("Will run redeploy for " + cp.name) + self.redeploy_units(cp) + except Exception as e: print(e) @@ -324,6 +327,47 @@ class Event: def skip(self): pass + def redeploy_units(self, cp): + """" + Auto redeploy units to newly captured base + """ + + ally_connected_cps = [ocp for ocp in cp.connected_points if cp.captured == ocp.captured] + enemy_connected_cps = [ocp for ocp in cp.connected_points if cp.captured != ocp.captured] + + # If the newly captured cp does not have enemy connected cp, + # then it is not necessary to redeploy frontline units there. + if len(enemy_connected_cps) == 0: + return + else: + # From each ally cp, send reinforcements + for ally_cp in ally_connected_cps: + total_units_redeployed = 0 + own_enemy_cp = [ocp for ocp in ally_cp.connected_points if ally_cp.captured != ocp.captured] + + moved_units = {} + + # If the connected base, does not have any more enemy cp connected. + # Or if it is not the opponent redeploying forces there (enemy AI will never redeploy all their forces at once) + if len(own_enemy_cp) > 0 or not cp.captured: + for frontline_unit, count in ally_cp.base.armor.items(): + moved_units[frontline_unit] = int(count/2) + total_units_redeployed = total_units_redeployed + int(count/2) + else: # So if the old base, does not have any more enemy cp connected, or if it is an enemy base + for frontline_unit, count in ally_cp.base.armor.items(): + moved_units[frontline_unit] = count + total_units_redeployed = total_units_redeployed + count + + cp.base.commision_units(moved_units) + ally_cp.base.commit_losses(moved_units) + + if total_units_redeployed > 0: + info = Information("Units redeployed", "", self.game.turn) + info.text = str(total_units_redeployed) + " have been redeployed from " + ally_cp.name + " to " + cp.name + self.game.informations.append(info) + logging.info(info.text) + + class UnitsDeliveryEvent(Event): informational = True diff --git a/game/game_stats.py b/game/game_stats.py index 48f735ce..2690d861 100644 --- a/game/game_stats.py +++ b/game/game_stats.py @@ -47,11 +47,9 @@ class GameStats: for cp in game.theater.controlpoints: if cp.captured: turn_data.allied_units.aircraft_count += sum(cp.base.aircraft.values()) - turn_data.allied_units.sam_count += sum(cp.base.aa.values()) turn_data.allied_units.vehicles_count += sum(cp.base.armor.values()) else: turn_data.enemy_units.aircraft_count += sum(cp.base.aircraft.values()) - turn_data.enemy_units.sam_count += sum(cp.base.aa.values()) turn_data.enemy_units.vehicles_count += sum(cp.base.armor.values()) self.data_per_turn.append(turn_data) diff --git a/theater/base.py b/theater/base.py index 0c01b7d4..b294dd38 100644 --- a/theater/base.py +++ b/theater/base.py @@ -120,34 +120,13 @@ class Base: target_dict[unit_type] = target_dict.get(unit_type, 0) + unit_count def commit_losses(self, units_lost: typing.Dict[typing.Any, int]): - # advanced SAM sites have multiple units - this code was not at all set up to handle that - # to avoid having to restructure a bunch of upstream code, we track total destroyed units and - # use that to determine if a site was destroyed - # this can be thought of as the enemy re-distributing parts of SAM sites to keep as many - # operational as possible (pulling specific units from ...storage... to bring them back online - # if non-letal damage was done) - # in the future, I may add more depth to this (e.g. a base having a certain number of spares and tracking - # the number of pieces of each site), but for now this is what we get - sams_destroyed = {} - # we count complex SAM sites at the end - don't double count - aa_skip = [ - AirDefence.SAM_SA_6_Kub_LN_2P25, - AirDefence.SAM_SA_3_S_125_LN_5P73, - AirDefence.SAM_SA_11_Buk_LN_9A310M1 - ] + for unit_type, count in units_lost.items(): - if unit_type in db.SAM_CONVERT or unit_type in db.SAM_CONVERT['except']: - # unit is part of an advanced SAM site, which means it will fail the below check - try: - sams_destroyed[unit_type] += 1 - except KeyError: - sams_destroyed[unit_type] = 1 + if unit_type in self.aircraft: target_array = self.aircraft elif unit_type in self.armor: target_array = self.armor - elif unit_type in self.aa and unit_type not in aa_skip: - target_array = self.aa else: print("Base didn't find event type {}".format(unit_type)) continue @@ -160,22 +139,6 @@ class Base: if target_array[unit_type] == 0: del target_array[unit_type] - # now that we have a complete picture of the SAM sites destroyed, determine if any were destroyed - for sam_site, count in sams_destroyed.items(): - dead_count = aaa.num_sam_dead(sam_site, count) - try: - modified_sam_site = db.SAM_CONVERT[sam_site] - except KeyError: - modified_sam_site = db.SAM_CONVERT[sam_site]['except'] - - if modified_sam_site in self.aa: - self.aa[modified_sam_site] = max( - self.aa[modified_sam_site] - dead_count, - 0 - ) - if self.aa[modified_sam_site] == 0: - del self.aa[modified_sam_site] - def affect_strength(self, amount): self.strength += amount if self.strength > BASE_MAX_STRENGTH: