mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
display strike objectives on map; minor fixes
This commit is contained in:
parent
ff08888385
commit
ce43be0d67
@ -43,7 +43,7 @@ def is_version_compatible(save_version):
|
|||||||
if current_version_components == save_version_components:
|
if current_version_components == save_version_components:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if save_version == "1.4_rc1":
|
if save_version in ["1.4_rc1", "1.4_rc2", "1.4_rc3"]:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if current_version_components[:2] == save_version_components[:2]:
|
if current_version_components[:2] == save_version_components[:2]:
|
||||||
|
|||||||
116
game/game.py
116
game/game.py
@ -58,14 +58,14 @@ EVENT_PROBABILITIES = {
|
|||||||
InfantryTransportEvent: [25, 0],
|
InfantryTransportEvent: [25, 0],
|
||||||
|
|
||||||
# events conditionally present; for both enemy and player
|
# events conditionally present; for both enemy and player
|
||||||
BaseAttackEvent: [100, 15],
|
BaseAttackEvent: [100, 5],
|
||||||
|
|
||||||
# events randomly present; for both enemy and player
|
# events randomly present; for both enemy and player
|
||||||
InterceptEvent: [25, 15],
|
InterceptEvent: [25, 5],
|
||||||
NavalInterceptEvent: [25, 15],
|
NavalInterceptEvent: [25, 5],
|
||||||
|
|
||||||
# events randomly present; only for the enemy
|
# events randomly present; only for the enemy
|
||||||
InsurgentAttackEvent: [0, 10],
|
InsurgentAttackEvent: [0, 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
# amount of strength player bases recover for the turn
|
# amount of strength player bases recover for the turn
|
||||||
@ -116,10 +116,62 @@ class Game:
|
|||||||
game=self))
|
game=self))
|
||||||
break
|
break
|
||||||
|
|
||||||
def _generate_events(self):
|
def _generate_player_event(self, event_class, player_cp, enemy_cp):
|
||||||
enemy_cap_generated = False
|
if event_class == NavalInterceptEvent and enemy_cp.radials == LAND:
|
||||||
enemy_generated_types = []
|
# 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):
|
for player_cp, enemy_cp in self.theater.conflicts(True):
|
||||||
if enemy_cp.is_global:
|
if enemy_cp.is_global:
|
||||||
continue
|
continue
|
||||||
@ -136,54 +188,10 @@ class Game:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if player_probability == 100 or self._roll(player_probability, player_cp.base.strength):
|
if player_probability == 100 or self._roll(player_probability, player_cp.base.strength):
|
||||||
if event_class == NavalInterceptEvent and enemy_cp.radials == LAND:
|
self._generate_player_event(event_class, player_cp, enemy_cp)
|
||||||
# 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
|
|
||||||
|
|
||||||
if player_cp in self.ignored_cps:
|
if enemy_probability == 100 or self._roll(enemy_probability, enemy_cp.base.strength):
|
||||||
# skip attacks against ignored CPs (for example just captured ones)
|
self._generate_enemy_event(event_class, player_cp, enemy_cp)
|
||||||
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))
|
|
||||||
|
|
||||||
def commision_unit_types(self, cp: ControlPoint, for_task: Task) -> typing.Collection[UnitType]:
|
def commision_unit_types(self, cp: ControlPoint, for_task: Task) -> typing.Collection[UnitType]:
|
||||||
importance_factor = (cp.importance - IMPORTANCE_LOW) / (IMPORTANCE_HIGH - IMPORTANCE_LOW)
|
importance_factor = (cp.importance - IMPORTANCE_LOW) / (IMPORTANCE_HIGH - IMPORTANCE_LOW)
|
||||||
|
|||||||
@ -11,8 +11,8 @@ from .base import *
|
|||||||
class CaucasusTheater(ConflictTheater):
|
class CaucasusTheater(ConflictTheater):
|
||||||
terrain = caucasus.Caucasus()
|
terrain = caucasus.Caucasus()
|
||||||
overview_image = "caumap.gif"
|
overview_image = "caumap.gif"
|
||||||
reference_points = {(-317948.32727306, 635639.37385346): (282.5, 319),
|
reference_points = {(-317948.32727306, 635639.37385346): (278.5, 319),
|
||||||
(-355692.3067714, 617269.96285781): (269, 352), }
|
(-355692.3067714, 617269.96285781): (263, 352), }
|
||||||
landmap = load_landmap("resources\\caulandmap.p")
|
landmap = load_landmap("resources\\caulandmap.p")
|
||||||
daytime_map = {
|
daytime_map = {
|
||||||
"dawn": (6, 9),
|
"dawn": (6, 9),
|
||||||
|
|||||||
@ -20,8 +20,8 @@ class MainMenu(Menu):
|
|||||||
self.upd.update()
|
self.upd.update()
|
||||||
|
|
||||||
self.frame = self.window.right_pane
|
self.frame = self.window.right_pane
|
||||||
self.frame.columnconfigure(0, weight=1)
|
self.frame.rowconfigure(0, weight=0)
|
||||||
self.frame.rowconfigure(0, weight=1)
|
self.frame.rowconfigure(1, weight=1)
|
||||||
|
|
||||||
def display(self):
|
def display(self):
|
||||||
persistency.save_game(self.game)
|
persistency.save_game(self.game)
|
||||||
@ -32,27 +32,29 @@ class MainMenu(Menu):
|
|||||||
# Header :
|
# Header :
|
||||||
header = Frame(self.frame, **STYLES["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)
|
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)
|
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
|
column = 0
|
||||||
row = 0
|
row = 0
|
||||||
|
|
||||||
def label(text):
|
def label(text):
|
||||||
nonlocal row, body
|
nonlocal row, body
|
||||||
frame = LabelFrame(body, **STYLES["label-frame"])
|
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)
|
Label(frame, text=text, **STYLES["widget"]).grid(row=row, sticky=NS)
|
||||||
row += 1
|
row += 1
|
||||||
|
|
||||||
def event_button(event):
|
def event_button(event):
|
||||||
nonlocal row, body
|
nonlocal row, body
|
||||||
frame = LabelFrame(body, **STYLES["label-frame"])
|
frame = LabelFrame(body, **STYLES["label-frame"])
|
||||||
frame.grid(row=row, sticky=NSEW)
|
frame.grid(row=row, sticky=N+EW)
|
||||||
Message(frame, text="{}".format(
|
Message(frame, text="{}".format(
|
||||||
event
|
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)
|
Button(body, text=">", command=self.start_event(event), **STYLES["btn-primary"]).grid(column=1, row=row, sticky=E)
|
||||||
row += 1
|
row += 1
|
||||||
|
|
||||||
@ -83,7 +85,7 @@ class MainMenu(Menu):
|
|||||||
new_departure = event.from_cp.name
|
new_departure = event.from_cp.name
|
||||||
|
|
||||||
if new_departure != departure:
|
if new_departure != departure:
|
||||||
body = LabelFrame(self.frame, **STYLES["body"])
|
body = Frame(content, **STYLES["body"])
|
||||||
body.grid(column=column, row=1, sticky=N+EW)
|
body.grid(column=column, row=1, sticky=N+EW)
|
||||||
row = 0
|
row = 0
|
||||||
column += 1
|
column += 1
|
||||||
|
|||||||
@ -67,6 +67,14 @@ class OverviewCanvas:
|
|||||||
self.canvas.create_image((self.image.width()/2, self.image.height()/2), image=self.image)
|
self.canvas.create_image((self.image.width()/2, self.image.height()/2), image=self.image)
|
||||||
|
|
||||||
for cp in self.game.theater.controlpoints:
|
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)
|
coords = self.transform_point(cp.position)
|
||||||
for connected_cp in cp.connected_points:
|
for connected_cp in cp.connected_points:
|
||||||
connected_coords = self.transform_point(connected_cp.position)
|
connected_coords = self.transform_point(connected_cp.position)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user