WIP: display events on the map

This commit is contained in:
Vasyl Horbachenko 2018-11-04 04:06:44 +02:00
parent 8f85101cec
commit af5cd57094
15 changed files with 54 additions and 51 deletions

View File

@ -100,22 +100,12 @@ class Game:
self.enemy = enemy_name
def _roll(self, prob, mult):
if self.settings.version == "dev":
# always generate all events for dev
return 100
else:
return random.randint(1, 100) <= prob * mult
def _generate_globalinterceptions(self):
global_count = len([x for x in self.theater.player_points() if x.is_global])
for from_cp in [x for x in self.theater.player_points() if x.is_global]:
probability_base = max(PLAYER_INTERCEPT_GLOBAL_PROBABILITY_BASE / global_count, 1)
probability = probability_base * math.log(len(self.theater.player_points()) + 1, PLAYER_INTERCEPT_GLOBAL_PROBABILITY_LOG)
if self._roll(probability, from_cp.base.strength):
to_cp = random.choice([x for x in self.theater.enemy_points() if x not in self.theater.conflicts()])
self.events.append(InterceptEvent(attacker_name=self.player,
defender_name=self.enemy,
from_cp=from_cp,
to_cp=to_cp,
game=self))
break
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
@ -173,20 +163,12 @@ class Game:
def _generate_events(self):
for player_cp, enemy_cp in self.theater.conflicts(True):
if enemy_cp.is_global:
continue
for event_class, (player_probability, enemy_probability) in EVENT_PROBABILITIES.items():
if event_class in [FrontlineAttackEvent, FrontlinePatrolEvent, InfantryTransportEvent]:
# skip events requiring frontline
if not Conflict.has_frontline_between(player_cp, enemy_cp):
continue
if player_cp.is_global:
# skip events requiring ground CP
if event_class not in [InterceptEvent, StrikeEvent, NavalInterceptEvent]:
continue
if player_probability == 100 or self._roll(player_probability, player_cp.base.strength):
self._generate_player_event(event_class, player_cp, enemy_cp)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 B

View File

@ -72,7 +72,7 @@ def generate_groundobjects(theater: ConflictTheater):
return None
group_id = 0
for cp in theater.enemy_points():
for cp in theater.controlpoints:
for _ in range(0, random.randrange(2, 4)):
available_categories = list(tpls) + ["aa", "aa"]
tpl_category = random.choice(available_categories)

View File

@ -32,6 +32,8 @@ class OverviewCanvas:
HEIGHT = 600
started = None
ground_assets_icons = None # type: typing.Dict[str, pygame.Surface]
event_icons = None # type: typing.Dict[typing.Type, pygame.Surface]
selected_event_info = None # type: typing.Tuple[Event, typing.Tuple[int, int]]
frontline_vector_cache = None # type: typing.Dict[str, typing.Tuple[Point, int, int]]
@ -54,7 +56,7 @@ class OverviewCanvas:
pygame.font.init()
self.font: pygame.font.SysFont = pygame.font.SysFont("arial", 15)
self.fontsmall: pygame.font.SysFont = pygame.font.SysFont("arial", 10)
self.icons = {}
self.ground_assets_icons = {}
# Frontline are too heavy on performance to compute in realtime, so keep them in a cache
self.frontline_vector_cache = {}
@ -144,14 +146,23 @@ class OverviewCanvas:
self.screen.fill(pygame.Color(*self.BLACK))
# Load icons resources
self.icons = {}
self.icons["target"] = pygame.image.load(os.path.join("resources", "ui", "target.png"))
self.icons["cleared"] = pygame.image.load(os.path.join("resources", "ui", "cleared.png"))
self.ground_assets_icons = {}
self.ground_assets_icons["target"] = pygame.image.load(os.path.join("resources", "ui", "ground_assets", "target.png"))
self.ground_assets_icons["cleared"] = pygame.image.load(os.path.join("resources", "ui", "ground_assets", "cleared.png"))
for category in CATEGORY_MAP.keys():
try:
self.icons[category] = pygame.image.load(os.path.join("resources", "ui", category + ".png"))
except:
print("Couldn't load icon for : " + category)
self.ground_assets_icons[category] = pygame.image.load(os.path.join("resources", "ui", "ground_assets", category + ".png"))
self.event_icons = {}
for category, image in {BaseAttackEvent: "capture",
FrontlinePatrolEvent: "attack",
FrontlineAttackEvent: "attack",
InfantryTransportEvent: "infantry",
InsurgentAttackEvent: "insurgent_attack",
InterceptEvent: "air_intercept",
NavalInterceptEvent: "naval_intercept",
StrikeEvent: "strike"}.items():
self.event_icons[category] = pygame.image.load(os.path.join("resources", "ui", "events", image + ".png"))
# Load the map image
self.map = pygame.image.load(os.path.join("resources", self.game.theater.overview_image)).convert()
@ -409,12 +420,12 @@ class OverviewCanvas:
rect = pygame.Rect(x, y, 16, 16)
if ground_object.is_dead:
surface.blit(self.icons["cleared"], (x, y))
surface.blit(self.ground_assets_icons["cleared"], (x, y))
else:
if ground_object.category in self.icons.keys():
icon = self.icons[ground_object.category]
if ground_object.category in self.ground_assets_icons.keys():
icon = self.ground_assets_icons[ground_object.category]
else:
icon = self.icons["target"]
icon = self.ground_assets_icons["target"]
surface.blit(icon, (x, y))
if rect.collidepoint(*mouse_pos):
@ -425,36 +436,46 @@ class OverviewCanvas:
surface.blit(lb, (pos[0] + 18, pos[1]))
def draw_events(self, surface: pygame.Surface, mouse_pos, mouse_down):
location_point_counters = {}
def _location_to_point(location: Point) -> typing.Tuple[int, int]:
nonlocal location_point_counters
key = str(location.x) + str(location.y)
occupied_rects = [pygame.Rect(*self._transform_point(x.position), 32, 32) for x in self.game.theater.controlpoints]
def _location_to_rect(location: Point) -> pygame.Rect:
nonlocal occupied_rects
point = self._transform_point(location)
point = point[0], point[1] + location_point_counters.get(key, 0) * 40
rect = pygame.Rect(*point, 32, 32)
i = 0
for occupied_rect in occupied_rects:
if rect.colliderect(occupied_rect):
i += 1
if i % 2:
rect.y = occupied_rect.y + occupied_rect.height + 3
else:
rect.x = occupied_rect.x + occupied_rect.width + 3
location_point_counters[key] = location_point_counters.get(key, 0) + 1
return point
occupied_rects.append(rect)
return rect
label_to_draw = None
for event in self.game.events:
location = event.location
if isinstance(event, FrontlinePatrolEvent) or isinstance(event, FrontlineAttackEvent):
location = self._frontline_center(event.from_cp, event.to_cp)
point = _location_to_point(location)
rect = pygame.Rect(*point, 30, 30)
pygame.draw.rect(surface, self.BLACK, rect)
rect = _location_to_rect(location)
pygame.draw.rect(surface, self.RED, rect)
self.surface.blit(self.event_icons[event.__class__], rect.topleft)
if rect.collidepoint(*mouse_pos) or self.selected_event_info == (event, point):
line = self.font.render(str(event), self.ANTIALIASING, self.WHITE, self.BLACK)
surface.blit(line, rect.center)
if rect.collidepoint(*mouse_pos) or self.selected_event_info == (event, rect.center):
if not label_to_draw:
label_to_draw = self.font.render(str(event), self.ANTIALIASING, self.WHITE, self.BLACK), rect.center
if rect.collidepoint(*mouse_pos):
if mouse_down[0]:
self.selected_event_info = event, point
self.selected_event_info = event, rect.center
mouse_down[0] = False
if label_to_draw:
surface.blit(*label_to_draw)
return mouse_down
def _selected_cp(self, cp):