diff --git a/__init__.py b/__init__.py index 8efa047b..a098a56c 100755 --- a/__init__.py +++ b/__init__.py @@ -43,7 +43,7 @@ def is_version_compatible(save_version): if current_version_components == save_version_components: return True - if save_version == "1.4_rc1": + if save_version in ["1.4_rc1", "1.4_rc2", "1.4_rc3"]: return False if current_version_components[:2] == save_version_components[:2]: diff --git a/game/game.py b/game/game.py index c73f519c..ba54dc8d 100644 --- a/game/game.py +++ b/game/game.py @@ -58,14 +58,14 @@ EVENT_PROBABILITIES = { InfantryTransportEvent: [25, 0], # events conditionally present; for both enemy and player - BaseAttackEvent: [100, 15], + BaseAttackEvent: [100, 5], # events randomly present; for both enemy and player - InterceptEvent: [25, 15], - NavalInterceptEvent: [25, 15], + InterceptEvent: [25, 5], + NavalInterceptEvent: [25, 5], # events randomly present; only for the enemy - InsurgentAttackEvent: [0, 10], + InsurgentAttackEvent: [0, 4], } # amount of strength player bases recover for the turn @@ -116,10 +116,62 @@ class Game: game=self)) break - def _generate_events(self): - enemy_cap_generated = False - enemy_generated_types = [] + def _generate_player_event(self, event_class, player_cp, enemy_cp): + if event_class == NavalInterceptEvent and enemy_cp.radials == LAND: + # skip naval events for non-coastal CPs + return + if event_class == BaseAttackEvent and enemy_cp.base.strength > PLAYER_BASEATTACK_THRESHOLD: + # skip base attack events for CPs yet too strong + return + + if event_class == StrikeEvent and not enemy_cp.ground_objects: + # skip strikes in case of no targets + return + + self.events.append(event_class(self.player, self.enemy, player_cp, enemy_cp, self)) + + def _generate_enemy_event(self, event_class, player_cp, enemy_cp): + if event_class in [type(x) for x in self.events if not self.is_player_attack(x)]: + # skip already generated enemy event types + return + + if player_cp in self.ignored_cps: + # skip attacks against ignored CPs (for example just captured ones) + return + + if enemy_cp.base.total_planes == 0: + # skip event if there's no planes on the base + return + + if player_cp.is_global: + # skip carriers + return + + if event_class == NavalInterceptEvent: + if player_cp.radials == LAND: + # skip naval events for non-coastal CPs + return + elif event_class == StrikeEvent: + if not player_cp.ground_objects: + # skip strikes if there's no ground objects + return + elif event_class == BaseAttackEvent: + if BaseAttackEvent in [type(x) for x in self.events]: + # skip base attack event if there's another one going on + return + + if enemy_cp.base.total_armor == 0: + # skip base attack if there's no armor + return + + if player_cp.base.strength > PLAYER_BASEATTACK_THRESHOLD: + # skip base attack if strength is too high + return + + self.events.append(event_class(self.enemy, self.player, enemy_cp, player_cp, self)) + + def _generate_events(self): for player_cp, enemy_cp in self.theater.conflicts(True): if enemy_cp.is_global: continue @@ -136,54 +188,10 @@ class Game: continue if player_probability == 100 or self._roll(player_probability, player_cp.base.strength): - if event_class == NavalInterceptEvent and enemy_cp.radials == LAND: - # skip naval events for non-coastal CPs - pass - else: - if event_class == BaseAttackEvent and enemy_cp.base.strength > PLAYER_BASEATTACK_THRESHOLD: - # skip base attack events for CPs yet too strong - pass - else: - if event_class == StrikeEvent and not enemy_cp.ground_objects: - # skip strikes in case of no targets - pass - else: - # finally append the event - self.events.append(event_class(self.player, self.enemy, player_cp, enemy_cp, self)) - elif enemy_probability == 100 or self._roll(enemy_probability, enemy_cp.base.strength): - if event_class in enemy_generated_types: - # skip already generated event types - continue + self._generate_player_event(event_class, player_cp, enemy_cp) - if player_cp in self.ignored_cps: - # skip attacks against ignored CPs (for example just captured ones) - continue - - if enemy_cp.base.total_planes == 0: - # skip event if there's no planes on the base - continue - - if event_class == NavalInterceptEvent: - if player_cp.radials == LAND: - # skip naval events for non-coastal CPs - continue - elif event_class == StrikeEvent: - if not player_cp.ground_objects: - # skip strikes if there's no ground objects - continue - elif event_class == BaseAttackEvent: - if enemy_cap_generated: - # skip base attack event if there's another one going on - continue - if enemy_cp.base.total_armor == 0: - # skip base attack if there's no armor - continue - - enemy_cap_generated = True - - # finally append the event - enemy_generated_types.append(event_class) - self.events.append(event_class(self.enemy, self.player, enemy_cp, player_cp, self)) + if enemy_probability == 100 or self._roll(enemy_probability, enemy_cp.base.strength): + self._generate_enemy_event(event_class, player_cp, enemy_cp) def commision_unit_types(self, cp: ControlPoint, for_task: Task) -> typing.Collection[UnitType]: importance_factor = (cp.importance - IMPORTANCE_LOW) / (IMPORTANCE_HIGH - IMPORTANCE_LOW) diff --git a/theater/caucasus.py b/theater/caucasus.py index ca5bb3f6..cf1b98d1 100644 --- a/theater/caucasus.py +++ b/theater/caucasus.py @@ -11,8 +11,8 @@ from .base import * class CaucasusTheater(ConflictTheater): terrain = caucasus.Caucasus() overview_image = "caumap.gif" - reference_points = {(-317948.32727306, 635639.37385346): (282.5, 319), - (-355692.3067714, 617269.96285781): (269, 352), } + reference_points = {(-317948.32727306, 635639.37385346): (278.5, 319), + (-355692.3067714, 617269.96285781): (263, 352), } landmap = load_landmap("resources\\caulandmap.p") daytime_map = { "dawn": (6, 9), diff --git a/ui/mainmenu.py b/ui/mainmenu.py index dd828da1..9117e9b6 100644 --- a/ui/mainmenu.py +++ b/ui/mainmenu.py @@ -20,8 +20,8 @@ class MainMenu(Menu): self.upd.update() self.frame = self.window.right_pane - self.frame.columnconfigure(0, weight=1) - self.frame.rowconfigure(0, weight=1) + self.frame.rowconfigure(0, weight=0) + self.frame.rowconfigure(1, weight=1) def display(self): persistency.save_game(self.game) @@ -32,27 +32,29 @@ class MainMenu(Menu): # Header : header = Frame(self.frame, **STYLES["header"]) Button(header, text="Configuration", command=self.configuration_menu, **STYLES["btn-primary"]).grid(column=0, row=0, sticky=NW) - Label(header, text="Budget: {}m (+{}m)".format(self.game.budget, self.game.budget_reward_amount), **STYLES["strong"]).grid(column=1, row=0, sticky=NSEW, padx=50) + Label(header, text="Budget: {}m (+{}m)".format(self.game.budget, self.game.budget_reward_amount), **STYLES["strong"]).grid(column=1, row=0, sticky=N+EW, padx=50) Button(header, text="Pass turn", command=self.pass_turn, **STYLES["btn-primary"]).grid(column=2, row=0, sticky=NE) - header.grid(column=0, columnspan=99, row=0, sticky=N+EW) + header.grid(column=0, row=0, sticky=N+EW) + content = Frame(self.frame, **STYLES["body"]) + content.grid(column=0, row=1, sticky=NSEW) column = 0 row = 0 def label(text): nonlocal row, body frame = LabelFrame(body, **STYLES["label-frame"]) - frame.grid(row=row, sticky=NSEW, columnspan=2) + frame.grid(row=row, sticky=N+EW, columnspan=2) Label(frame, text=text, **STYLES["widget"]).grid(row=row, sticky=NS) row += 1 def event_button(event): nonlocal row, body frame = LabelFrame(body, **STYLES["label-frame"]) - frame.grid(row=row, sticky=NSEW) + frame.grid(row=row, sticky=N+EW) Message(frame, text="{}".format( event - ), aspect=1600, **STYLES["widget"]).grid(column=0, row=0, sticky=NSEW) + ), aspect=1600, **STYLES["widget"]).grid(column=0, row=0, sticky=N+EW) Button(body, text=">", command=self.start_event(event), **STYLES["btn-primary"]).grid(column=1, row=row, sticky=E) row += 1 @@ -83,7 +85,7 @@ class MainMenu(Menu): new_departure = event.from_cp.name if new_departure != departure: - body = LabelFrame(self.frame, **STYLES["body"]) + body = Frame(content, **STYLES["body"]) body.grid(column=column, row=1, sticky=N+EW) row = 0 column += 1 diff --git a/ui/overviewcanvas.py b/ui/overviewcanvas.py index ff88a217..ae5d1495 100644 --- a/ui/overviewcanvas.py +++ b/ui/overviewcanvas.py @@ -67,6 +67,14 @@ class OverviewCanvas: self.canvas.create_image((self.image.width()/2, self.image.height()/2), image=self.image) for cp in self.game.theater.controlpoints: + for ground_object in cp.ground_objects: + x, y = self.transform_point(ground_object.position) + self.canvas.create_text(x, + y, + text=".", + fill="black" if ground_object.is_dead else self._enemy_color(), + font=("Helvetica", 18)) + coords = self.transform_point(cp.position) for connected_cp in cp.connected_points: connected_coords = self.transform_point(connected_cp.position)