From af5cd5709475118201f4c1a41d470931074005ec Mon Sep 17 00:00:00 2001 From: Vasyl Horbachenko Date: Sun, 4 Nov 2018 04:06:44 +0200 Subject: [PATCH] WIP: display events on the map --- game/game.py | 28 +++----------- resources/ui/aa.png | Bin 229 -> 0 bytes resources/ui/ammo.png | Bin 197 -> 0 bytes resources/ui/cleared.png | Bin 315 -> 0 bytes resources/ui/comms.png | Bin 196 -> 0 bytes resources/ui/factory.png | Bin 220 -> 0 bytes resources/ui/farp.png | Bin 253 -> 0 bytes resources/ui/fob.png | Bin 213 -> 0 bytes resources/ui/fuel.png | Bin 224 -> 0 bytes resources/ui/oil.png | Bin 227 -> 0 bytes resources/ui/power.png | Bin 235 -> 0 bytes resources/ui/target.png | Bin 230 -> 0 bytes resources/ui/warehouse.png | Bin 232 -> 0 bytes theater/start_generator.py | 2 +- ui/overviewcanvas.py | 75 ++++++++++++++++++++++++------------- 15 files changed, 54 insertions(+), 51 deletions(-) delete mode 100644 resources/ui/aa.png delete mode 100644 resources/ui/ammo.png delete mode 100644 resources/ui/cleared.png delete mode 100644 resources/ui/comms.png delete mode 100644 resources/ui/factory.png delete mode 100644 resources/ui/farp.png delete mode 100644 resources/ui/fob.png delete mode 100644 resources/ui/fuel.png delete mode 100644 resources/ui/oil.png delete mode 100644 resources/ui/power.png delete mode 100644 resources/ui/target.png delete mode 100644 resources/ui/warehouse.png diff --git a/game/game.py b/game/game.py index 20b2c004..b99116be 100644 --- a/game/game.py +++ b/game/game.py @@ -100,21 +100,11 @@ class Game: self.enemy = enemy_name def _roll(self, prob, mult): - 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 + if self.settings.version == "dev": + # always generate all events for dev + return 100 + else: + return random.randint(1, 100) <= prob * mult def _generate_player_event(self, event_class, player_cp, enemy_cp): if event_class == NavalInterceptEvent and enemy_cp.radials == LAND: @@ -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) diff --git a/resources/ui/aa.png b/resources/ui/aa.png deleted file mode 100644 index 26ea05c75362ea90f3a35e1a42b4abf1c87b5600..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 229 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Ea{HEjtmSN`?>!lvI6;>1s;*b z3=DjSK$uZf!>a)(C{f}XQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QJXPB%t#~Y|7+0(@_ z#KQk>??uiA10L4R{{`+I7o6jkyxy+4GvJ{9!;9Zyi>{bePp{K`owHAPUZrWlrCSrT zrm%Fhn5<>77YvztpL5U3K!G=3b?P>`^g2CpZm3FstahNVZ9#5s3S-4z1If*@+FO1v U=qS6u3$%{G)78&qol`;+0HTLYZ2$lO diff --git a/resources/ui/ammo.png b/resources/ui/ammo.png deleted file mode 100644 index c2e6ffc089e10b2101a74e992f1bcc9a241a2636..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Ea{HEjtmSN`?>!lvI6;>1s;*b z3=DkxL735kHCP2GC{f}XQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QJXPB%t#~Y}|+0(@_ z#KJ%M$9V@SreO7ap>B=K7c$wLe%$2Xbr4cw6g+rpS%h<(9EYRJhE49K3f>Qrk}onm lOj6R3>Tn6*J)+FU#;`7X$*eT0#LT=By}Z;C1rt3( zJ;P+JIo?1uYdl>XLoEE06IMJ|=4Jf2`hR$bi^=5=FRn*&G;8px-+MFRP3XSAZ!ISH zMlfH+6$Q zDUK~{3k)6R=T>bHQEGfvV&Swg@!V8T2W7>o3v>9~HKZCi7A;SSXPkBUAxA8;fbaer zr>`8?|MQ?xilfD$MT{Ni_TBDPV{*S?`oJ-OS7kw!9mBIav141*3(o`H&EV!lvI6;>1s;*b z3=Dh+K$tP>S|=w^P@=>&q9iy!t)x7$D3zfgF*C13FE6!3!9>qc&oEhQjyF(^lc$Sg zh=qUhkMj;vOu_2;Lfs!S4`|sLnJhTT*TL4oVdOORsL~gEef}=1vmMtMLcFH1afk~m kYC1d>b_w7;qRhs|a6y;T?P|D=63{dTPgg&ebxsLQ02*L4qyPW_ diff --git a/resources/ui/factory.png b/resources/ui/factory.png deleted file mode 100644 index 0d9f3b2d8965d4428efd0e7ba68ac684fbbb8b64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Ea{HEjtmSN`?>!lvI6;>1s;*b z3=Dh+K$tP>S|=w^P@=>&q9iy!t)x7$D3zfgF*C13FE6!3!9>qc&oEhQjyF(El&6bh zh=qUhkMj;vOu_2;Lfsu#8N%JxwC&lma53XKw=@R9GF}I_<&sv+D?~aPVmgdk*gBLt zJPX)jOv`u$GJRZZc^v|Gm~0B-IJBry!RexdN>i4CoS^{&L&KWeEoGlhJO|WtKn?%^ diff --git a/resources/ui/farp.png b/resources/ui/farp.png deleted file mode 100644 index 62fef986fd8e11d05c76d2579dddca7754844fd7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 253 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Ea{HEjtmSN`?>!lvI6;>1s;*b z3=DkxL735kHCP2GC{f}XQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QJXPB%t#~Y}o+SA1` z#KM1X|7pPn1s<2+S)xx9*uxS+H)F51 tN9RO=koWr&F8%$&ZJszmr^mU3QNQc0-|w^9*MZJp@O1TaS?83{1OTb8QOE!Q diff --git a/resources/ui/fob.png b/resources/ui/fob.png deleted file mode 100644 index 27b0ab3345baa69e5680dc1f440b74cccfc2a25f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 213 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Ea{HEjtmSN`?>!lvI6;>1s;*b z3=DkxL735kHCP2GC{f}XQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QJXPB%t#~Y|7*we)^ z#KJ%M$9V@SreO7aq3(?2cu25oqGbZqRO3V3K<9>Vm)| zCKbCFDQ&0g4AU8u78pO^h@5jys>3CK_lPnZ8-us#jVX&2Urz-Z&*16m=d#Wzp$PyC CZ#oVD diff --git a/resources/ui/fuel.png b/resources/ui/fuel.png deleted file mode 100644 index 1324adcbd91b9bc0c49e2dc439aa4fac450f3934..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 224 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Ea{HEjtmSN`?>!lvI6;>1s;*b z3=Dh+L6~vJ#O${~L5ULAh?3y^w370~qEv>0#LT=By}Z;C1rt3(J;P+JIo?1uah@)Y zAr}5~`x-e97;v!6J+*O@yZdX7xoTSl_v!vv(Wor=^YK(o+iT@

<8?dmIcxo=fnz z@4F$ysMWCQLI#JUg8fMk7W>7DEea0O`)oTOC~|xYI+*UJ5OPEGRmYu3m+RARJEYzP P+Qi`L>gTe~DWM4f50*&~ diff --git a/resources/ui/oil.png b/resources/ui/oil.png deleted file mode 100644 index 548cdbab160fb4cece27c36bac2d90517e0edd27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 227 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Ea{HEjtmSN`?>!lvI6;>1s;*b z3=Dh+K$tP>S|=w^P@=>&q9iy!t)x7$D3zfgF*C13FE6!3!9>qc&oEhQjyF(EqNj^v zh=u>sUPitK1s>+_N&j97*YxU{tz617b5_g(hx{Xg?{{p=T^}U0WrNs!lvI6;>1s;*b z3=DkxL735kHCP2GC{f}XQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QJXPB%t#~Y|7)6>N< z#KM1Se>Z1?0S~Kj;r9}j0#LT=By}Z;C1rt3( zJ;P+JIo?1u;hrvzAr}5idl>nE*17Kfe^%yT<_4wK{8?{v<30r}l&D$qhl}Te{&t2t zzgv5(pB=RF->7%!pKyorH3xC=7z4W*NwF<|?JbhzencMpo^X+a-M#7qUm$Cj{9Of) Tgu7WlD;PXo{an^LB{Ts58yZQ* diff --git a/resources/ui/warehouse.png b/resources/ui/warehouse.png deleted file mode 100644 index fa7a38e1e015ad19b97889d5e2f458f83c5c380d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 232 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Ea{HEjtmSN`?>!lvI6;>1s;*b z3=DkxL735kHCP2GC{f}XQ4*Y=R#Ki=l*&+$n3-3imzP?iV4`QJXPB%t#~Y|7&C|s( z#KQk*??v7Q0}hv&r#9|tUu@ZQIpT|s<%EboMwOZR1^Oox@9)@`yZ%#m1Lx!IbxSH^ zmG(I}-D0~UdB|J3M~X9e68GA<5eY($%l+M%i}WPI9?7ukd|=|3w%Fh(r)%EAJ`eVn XE(i1;C7a9z+Q{JP>gTe~DWM4fy4y+s diff --git a/theater/start_generator.py b/theater/start_generator.py index 2c4d9c87..d14a6e63 100644 --- a/theater/start_generator.py +++ b/theater/start_generator.py @@ -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) diff --git a/ui/overviewcanvas.py b/ui/overviewcanvas.py index 98bc781c..66248f3b 100644 --- a/ui/overviewcanvas.py +++ b/ui/overviewcanvas.py @@ -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):