mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Work in progress : features restored.
This commit is contained in:
parent
90bdcec7ff
commit
7d70862e72
Binary file not shown.
|
Before Width: | Height: | Size: 424 KiB After Width: | Height: | Size: 276 KiB |
@ -4,6 +4,7 @@ from tkinter import *
|
|||||||
|
|
||||||
from tkinter.ttk import *
|
from tkinter.ttk import *
|
||||||
|
|
||||||
|
from ui.styles import STYLES
|
||||||
from ui.window import *
|
from ui.window import *
|
||||||
import pygame, platform
|
import pygame, platform
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
@ -16,60 +17,93 @@ from theater.conflicttheater import *
|
|||||||
class OverviewCanvas:
|
class OverviewCanvas:
|
||||||
mainmenu = None # type: ui.mainmenu.MainMenu
|
mainmenu = None # type: ui.mainmenu.MainMenu
|
||||||
|
|
||||||
RED = (255,125,125)
|
RED = (255, 125, 125)
|
||||||
BLUE = (164,164,255)
|
BLUE = (164, 164, 255)
|
||||||
|
WHITE = (255, 255, 255)
|
||||||
|
BLACK = (0, 0, 0)
|
||||||
|
|
||||||
def __init__(self, frame: Frame, parent, game: Game):
|
def __init__(self, frame: Frame, parent, game: Game):
|
||||||
|
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.game = game
|
self.game = game
|
||||||
self.screen = None
|
self.screen = None
|
||||||
print(pygame.font.get_fonts())
|
|
||||||
|
|
||||||
# Pygame objects
|
# Pygame objects
|
||||||
self.map = None
|
self.map = None
|
||||||
self.surface = None
|
self.surface: pygame.Surface = None
|
||||||
self.thread = None
|
self.thread:Thread = None
|
||||||
self.clock = pygame.time.Clock();
|
self.clock = pygame.time.Clock()
|
||||||
pygame.font.init();
|
pygame.font.init()
|
||||||
self.font = pygame.font.SysFont("arial", 18)
|
self.font = pygame.font.SysFont("arial", 15)
|
||||||
|
self.fontsmall = pygame.font.SysFont("arial", 10)
|
||||||
|
|
||||||
|
self.rects = []
|
||||||
|
|
||||||
# Map state
|
# Map state
|
||||||
self.zoom = 10
|
self.zoom = 1
|
||||||
self.scroll = [0, 0]
|
self.scroll = [0, 0]
|
||||||
|
|
||||||
self.exited = False
|
self.exited = False
|
||||||
|
|
||||||
# self.image = PhotoImage(file=os.path.join("resources", game.theater.overview_image))
|
# Display options
|
||||||
# self.canvas = Canvas(frame, width=self.image.width(), height=self.image.height())
|
self.display_ground_targets = BooleanVar(value=True)
|
||||||
# self.canvas.grid(column=0, row=0, sticky=NSEW)
|
self.display_forces = BooleanVar(value=True)
|
||||||
|
self.display_bases = BooleanVar(value=True)
|
||||||
|
self.display_road = BooleanVar(value=True)
|
||||||
|
|
||||||
# TODO : dirty :(
|
# TODO : dirty :(
|
||||||
parent.window.tk.protocol("<WM_DELETE_WINDOW>", self.on_close)
|
parent.window.tk.protocol("<WM_DELETE_WINDOW>", self.on_close)
|
||||||
|
|
||||||
self.embed = Frame(frame, width=800, height=600) # creates embed frame for pygame window
|
self.wrapper = Frame(frame, **STYLES["frame-wrapper"])
|
||||||
|
self.wrapper.grid(column=0, row=0, sticky=NSEW) # Adds grid
|
||||||
|
self.wrapper.pack(side=LEFT) # packs window to the left
|
||||||
|
|
||||||
|
self.embed = Frame(self.wrapper, width=1200, height=600) # creates embed frame for pygame window
|
||||||
self.embed.grid(column=0, row=0, sticky=NSEW) # Adds grid
|
self.embed.grid(column=0, row=0, sticky=NSEW) # Adds grid
|
||||||
self.embed.pack(side=LEFT) # packs window to the left
|
|
||||||
|
self.options = Frame(self.wrapper, **STYLES["frame-wrapper"])
|
||||||
|
self.options.grid(column=0,row=1, sticky=SW)
|
||||||
|
self.build_map_options_panel()
|
||||||
|
|
||||||
self.init_sdl_layer()
|
self.init_sdl_layer()
|
||||||
self.init_sdl_thread()
|
self.init_sdl_thread()
|
||||||
|
|
||||||
|
def build_map_options_panel(self):
|
||||||
|
col = 0
|
||||||
|
Label(self.options, text="Ground targets", **STYLES["widget"]).grid(row=0, column=col, sticky=W)
|
||||||
|
Checkbutton(self.options, variable=self.display_ground_targets, **STYLES["radiobutton"]).grid(row=0, column=col + 1, sticky=E)
|
||||||
|
Separator(self.options, orient=VERTICAL).grid(row=0, column=col + 2, sticky=NS)
|
||||||
|
col += 3
|
||||||
|
Label(self.options, text="Forces", **STYLES["widget"]).grid(row=0, column=col, sticky=W)
|
||||||
|
Checkbutton(self.options, variable=self.display_forces, **STYLES["radiobutton"]).grid(row=0, column=col + 1, sticky=E)
|
||||||
|
Separator(self.options, orient=VERTICAL).grid(row=0, column=col + 2, sticky=NS)
|
||||||
|
col += 3
|
||||||
|
Label(self.options, text="Bases", **STYLES["widget"]).grid(row=0, column=col, sticky=W)
|
||||||
|
Checkbutton(self.options, variable=self.display_bases, **STYLES["radiobutton"]).grid(row=0, column=col + 1, sticky=E)
|
||||||
|
Separator(self.options, orient=VERTICAL).grid(row=0, column=col + 2, sticky=NS)
|
||||||
|
col += 4
|
||||||
|
Label(self.options, text="Roads", **STYLES["widget"]).grid(row=0, column=col, sticky=W)
|
||||||
|
Checkbutton(self.options, variable=self.display_road, **STYLES["radiobutton"]).grid(row=0, column=col + 1, sticky=E)
|
||||||
|
Separator(self.options, orient=VERTICAL).grid(row=0, column=col + 2, sticky=NS)
|
||||||
|
|
||||||
def on_close(self):
|
def on_close(self):
|
||||||
print("on_close")
|
print("on_close")
|
||||||
|
|
||||||
self.exited = True
|
self.exited = True
|
||||||
if self.thread is not None:
|
if self.thread is not None:
|
||||||
self.thread.join()
|
self.thread.join()
|
||||||
|
|
||||||
def init_sdl_layer(self):
|
def init_sdl_layer(self):
|
||||||
os.environ['SDL_WINDOWID'] = str(self.embed.winfo_id())
|
os.environ['SDL_WINDOWID'] = str(self.embed.winfo_id())
|
||||||
#if platform.system == "Windows":
|
if platform.system == "Windows":
|
||||||
# os.environ['SDL_VIDEODRIVER'] = 'windib'
|
os.environ['SDL_VIDEODRIVER'] = 'windib'
|
||||||
|
|
||||||
self.screen = pygame.display.set_mode((800, 600), pygame.DOUBLEBUF|pygame.HWSURFACE)
|
self.screen = pygame.display.set_mode((1200, 600), pygame.DOUBLEBUF | pygame.HWSURFACE)
|
||||||
self.screen.fill(pygame.Color(0, 128, 128))
|
self.screen.fill(pygame.Color(0, 128, 128))
|
||||||
self.screen.set_alpha(None)
|
self.screen.set_alpha(None)
|
||||||
|
|
||||||
|
self.icon_tg = pygame.image.load(os.path.join("resources", "ui", "target.png"))
|
||||||
|
self.icon_sam = pygame.image.load(os.path.join("resources", "ui", "sam.png"))
|
||||||
|
self.icon_clr = pygame.image.load(os.path.join("resources", "ui", "cleared.png"))
|
||||||
|
|
||||||
self.map = pygame.image.load(os.path.join("resources", self.game.theater.overview_image)).convert()
|
self.map = pygame.image.load(os.path.join("resources", self.game.theater.overview_image)).convert()
|
||||||
self.surface = pygame.Surface((self.map.get_width(), self.map.get_height()))
|
self.surface = pygame.Surface((self.map.get_width(), self.map.get_height()))
|
||||||
|
|
||||||
@ -85,7 +119,8 @@ class OverviewCanvas:
|
|||||||
self.thread.start()
|
self.thread.start()
|
||||||
|
|
||||||
def sdl_thread(self):
|
def sdl_thread(self):
|
||||||
redraw_required = True
|
self.redraw_required = True
|
||||||
|
bg = pygame.Color(0, 64, 64)
|
||||||
while not self.exited:
|
while not self.exited:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -95,123 +130,156 @@ class OverviewCanvas:
|
|||||||
|
|
||||||
self.clock.tick(60)
|
self.clock.tick(60)
|
||||||
|
|
||||||
if(redraw_required):
|
|
||||||
# Fill
|
|
||||||
self.screen.fill(pygame.Color(0, 128, 128))
|
|
||||||
|
|
||||||
# Surface
|
|
||||||
self.draw_map(self.surface);
|
|
||||||
|
|
||||||
# Scaling
|
|
||||||
scaled = pygame.transform.scale(self.surface, (int(self.surface.get_width() * self.zoom), int(self.surface.get_height() * self.zoom)))
|
|
||||||
self.screen.blit(scaled, self.scroll)
|
|
||||||
|
|
||||||
pygame.display.flip()
|
|
||||||
|
|
||||||
redraw_required = False
|
|
||||||
|
|
||||||
right_down = False
|
right_down = False
|
||||||
for event in pygame.event.get():
|
left_down = False
|
||||||
if event.type == pygame.MOUSEBUTTONDOWN:
|
|
||||||
|
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.MOUSEMOTION:
|
||||||
|
self.redraw_required = True
|
||||||
|
elif event.type == pygame.MOUSEBUTTONDOWN:
|
||||||
# Scroll wheel
|
# Scroll wheel
|
||||||
if event.button == 4:
|
if event.button == 4:
|
||||||
self.zoom += 0.25
|
self.zoom += 0.25
|
||||||
redraw_required = True
|
self.redraw_required = True
|
||||||
elif event.button == 5:
|
elif event.button == 5:
|
||||||
self.zoom -= 0.25
|
self.zoom -= 0.25
|
||||||
redraw_required = True
|
self.redraw_required = True
|
||||||
|
|
||||||
if event.button == 3:
|
if event.button == 3:
|
||||||
right_down = True
|
right_down = True
|
||||||
pygame.mouse.get_rel()
|
pygame.mouse.get_rel()
|
||||||
|
if event.button == 1:
|
||||||
|
left_down = True
|
||||||
|
self.redraw_required = True
|
||||||
|
|
||||||
# If Right click pressed
|
# If Right click pressed
|
||||||
if pygame.mouse.get_pressed()[2] == 1 and not right_down:
|
if pygame.mouse.get_pressed()[2] == 1 and not right_down:
|
||||||
scr = pygame.mouse.get_rel()
|
scr = pygame.mouse.get_rel()
|
||||||
self.scroll[0] += scr[0]
|
self.scroll[0] += scr[0]
|
||||||
self.scroll[1] += scr[1]
|
self.scroll[1] += scr[1]
|
||||||
redraw_required = True
|
self.redraw_required = True
|
||||||
|
|
||||||
if (self.zoom <= 1):
|
if self.zoom <= 0.5:
|
||||||
self.zoom = 1
|
self.zoom = 0.5
|
||||||
elif (self.zoom > 20):
|
elif self.zoom > 10:
|
||||||
self.zoom = 20
|
self.zoom = 10
|
||||||
|
|
||||||
def draw_map(self, surface: pygame.Surface):
|
if (self.redraw_required):
|
||||||
|
# Fill
|
||||||
|
self.screen.fill(bg)
|
||||||
|
|
||||||
self.surface.blit(self.map, (0,0))
|
# Surface
|
||||||
|
cursor_pos = pygame.mouse.get_pos()
|
||||||
|
cursor_pos = (
|
||||||
|
(cursor_pos[0] - self.scroll[0]) / self.zoom, (cursor_pos[1] - self.scroll[1]) / self.zoom)
|
||||||
|
self.draw_map(self.surface, cursor_pos, (left_down, right_down));
|
||||||
|
|
||||||
|
# Scaling
|
||||||
|
# scaled = pygame.transform.scale(self.surface, (int(self.surface.get_width() * self.zoom), int(self.surface.get_height() * self.zoom)))
|
||||||
|
self.screen.blit(self.surface, self.scroll)
|
||||||
|
|
||||||
|
pygame.display.flip()
|
||||||
|
|
||||||
|
self.redraw_required = False
|
||||||
|
|
||||||
|
def draw_map(self, surface: pygame.Surface, mouse_pos: (int, int), mouse_down: (bool, bool)):
|
||||||
|
|
||||||
|
self.surface.blit(self.map, (0, 0))
|
||||||
|
|
||||||
|
pygame.draw.rect(surface, (255, 0, 255), (mouse_pos[0], mouse_pos[1], 5, 5), 2)
|
||||||
|
|
||||||
for cp in self.game.theater.controlpoints:
|
for cp in self.game.theater.controlpoints:
|
||||||
|
|
||||||
for ground_object in cp.ground_objects:
|
if self.display_ground_targets.get():
|
||||||
x, y = self.transform_point(ground_object.position)
|
if cp.captured:
|
||||||
label = self.font.render(ground_object.name_abbrev, False, (0,0,0) if ground_object.is_dead else self._enemy_color())
|
|
||||||
surface.blit(label, (x,y))
|
|
||||||
|
|
||||||
coords = self.transform_point(cp.position)
|
|
||||||
for connected_cp in cp.connected_points:
|
|
||||||
connected_coords = self.transform_point(connected_cp.position)
|
|
||||||
if connected_cp.captured != cp.captured:
|
|
||||||
color = self._enemy_color()
|
|
||||||
elif connected_cp.captured and cp.captured:
|
|
||||||
color = self._player_color()
|
color = self._player_color()
|
||||||
else:
|
else:
|
||||||
color = (0,0,0)
|
color = self._enemy_color()
|
||||||
|
for ground_object in cp.ground_objects:
|
||||||
|
self.draw_ground_object(ground_object, surface, color, mouse_pos)
|
||||||
|
|
||||||
pygame.draw.line(surface, color, coords, connected_coords, 4)
|
if self.display_road.get():
|
||||||
#self.canvas.create_line((coords[0], coords[1], connected_coords[0], connected_coords[1]), width=2, fill=color)
|
coords = self.transform_point(cp.position)
|
||||||
|
for connected_cp in cp.connected_points:
|
||||||
|
connected_coords = self.transform_point(connected_cp.position)
|
||||||
|
if connected_cp.captured != cp.captured:
|
||||||
|
color = self._enemy_color()
|
||||||
|
elif connected_cp.captured and cp.captured:
|
||||||
|
color = self._player_color()
|
||||||
|
else:
|
||||||
|
color = self.BLACK
|
||||||
|
|
||||||
if cp.captured and not connected_cp.captured and Conflict.has_frontline_between(cp, connected_cp):
|
pygame.draw.line(surface, color, coords, connected_coords, 4)
|
||||||
frontline = Conflict.frontline_vector(cp, connected_cp, self.game.theater)
|
# self.canvas.create_line((coords[0], coords[1], connected_coords[0], connected_coords[1]), width=2, fill=color)
|
||||||
if not frontline:
|
|
||||||
continue
|
|
||||||
|
|
||||||
frontline_pos, heading, distance = frontline
|
if cp.captured and not connected_cp.captured and Conflict.has_frontline_between(cp, connected_cp):
|
||||||
if distance < 10000:
|
frontline = Conflict.frontline_vector(cp, connected_cp, self.game.theater)
|
||||||
frontline_pos = frontline_pos.point_from_heading(heading + 180, 5000)
|
if not frontline:
|
||||||
distance = 10000
|
continue
|
||||||
|
|
||||||
start_coords = self.transform_point(frontline_pos, treshold=10)
|
frontline_pos, heading, distance = frontline
|
||||||
end_coords = self.transform_point(frontline_pos.point_from_heading(heading, distance), treshold=60)
|
if distance < 10000:
|
||||||
|
frontline_pos = frontline_pos.point_from_heading(heading + 180, 5000)
|
||||||
|
distance = 10000
|
||||||
|
|
||||||
#self.canvas.create_line((*start_coords, *end_coords), width=2, fill=color)
|
start_coords = self.transform_point(frontline_pos, treshold=10)
|
||||||
pygame.draw.line(surface, color, start_coords, end_coords, 4)
|
end_coords = self.transform_point(frontline_pos.point_from_heading(heading, distance), treshold=60)
|
||||||
|
|
||||||
for cp in self.game.theater.controlpoints:
|
# self.canvas.create_line((*start_coords, *end_coords), width=2, fill=color)
|
||||||
coords = self.transform_point(cp.position)
|
pygame.draw.line(surface, color, start_coords, end_coords, 4)
|
||||||
radius = 12 * math.pow(cp.importance, 1)
|
|
||||||
radius_m = radius * cp.base.strength - 2;
|
|
||||||
|
|
||||||
if cp.captured:
|
if self.display_bases.get():
|
||||||
color = self._player_color()
|
for cp in self.game.theater.controlpoints:
|
||||||
|
coords = self.transform_point(cp.position)
|
||||||
|
radius = 12 * math.pow(cp.importance, 1)
|
||||||
|
radius_m = radius * cp.base.strength - 2;
|
||||||
|
|
||||||
|
if cp.captured:
|
||||||
|
color = self._player_color()
|
||||||
|
else:
|
||||||
|
color = self._enemy_color()
|
||||||
|
|
||||||
|
pygame.draw.circle(surface, self.BLACK, (int(coords[0]), int(coords[1])), int(radius))
|
||||||
|
pygame.draw.circle(surface, color, (int(coords[0]), int(coords[1])), int(radius_m))
|
||||||
|
|
||||||
|
label = self.font.render(cp.name, False, (225, 225, 225), self.BLACK)
|
||||||
|
labelHover = self.font.render(cp.name, False, (255, 255, 255), (128, 186, 128))
|
||||||
|
labelClick = self.font.render(cp.name, False, (255, 255, 255), (122, 122, 255))
|
||||||
|
|
||||||
|
rect = pygame.Rect(coords[0] - label.get_width() / 2 + 1, coords[1] + 1, label.get_width(),
|
||||||
|
label.get_height())
|
||||||
|
if rect.collidepoint(mouse_pos):
|
||||||
|
if (mouse_down[0]):
|
||||||
|
surface.blit(labelClick, (coords[0] - label.get_width() / 2 + 1, coords[1] + 1))
|
||||||
|
self.parent.go_cp(cp)
|
||||||
|
else:
|
||||||
|
surface.blit(labelHover, (coords[0] - label.get_width() / 2 + 1, coords[1] + 1))
|
||||||
|
else:
|
||||||
|
surface.blit(label, (coords[0] - label.get_width() / 2 + 1, coords[1] + 1))
|
||||||
|
|
||||||
|
if self.display_forces.get():
|
||||||
|
units_title = " {} / {} / {} ".format(cp.base.total_planes, cp.base.total_armor, cp.base.total_aa)
|
||||||
|
label2 = self.fontsmall.render(units_title, False, color, (30, 30, 30))
|
||||||
|
surface.blit(label2, (coords[0] - label2.get_width() / 2, coords[1] + label.get_height() + 1))
|
||||||
|
|
||||||
|
def draw_ground_object(self, ground_object: TheaterGroundObject, surface: pygame.Surface, color, mouse_pos):
|
||||||
|
x, y = self.transform_point(ground_object.position)
|
||||||
|
rect = pygame.Rect(x, y, 16, 16)
|
||||||
|
|
||||||
|
if ground_object.is_dead:
|
||||||
|
surface.blit(self.icon_clr, (x, y))
|
||||||
|
else:
|
||||||
|
if ground_object.name_abbrev == "AA":
|
||||||
|
surface.blit(self.icon_sam, (x, y))
|
||||||
else:
|
else:
|
||||||
color = self._enemy_color()
|
surface.blit(self.icon_tg, (x, y))
|
||||||
|
|
||||||
pygame.draw.circle(surface, (0,0,0), (int(coords[0]), int(coords[1])), int(radius))
|
if rect.collidepoint(mouse_pos):
|
||||||
pygame.draw.circle(surface, color, (int(coords[0]), int(coords[1])), int(radius_m))
|
self.draw_ground_object_info(ground_object, (x, y), color, surface);
|
||||||
|
|
||||||
#self.canvas.tag_bind(cp_id, "<Button-1>", self.display(cp))
|
|
||||||
#self.create_cp_title((coords[0] + arc_size/4, coords[1] + arc_size/4), cp)
|
|
||||||
|
|
||||||
units_title = "{}/{}/{}".format(cp.base.total_planes, cp.base.total_armor, cp.base.total_aa)
|
|
||||||
|
|
||||||
label = self.font.render(cp.name, False, color, (0,0,0))
|
|
||||||
surface.blit(label, (coords[0]-label.get_width()/2, coords[1]))
|
|
||||||
|
|
||||||
#self.canvas.create_text(coords[0]+1, coords[1] - arc_size / 1.5 +1, text=units_title, font=("Helvetica", 8), fill=color)
|
|
||||||
#self.canvas.create_text(coords[0], coords[1] - arc_size / 1.5, text=units_title, font=("Helvetica", 8), fill="white")
|
|
||||||
|
|
||||||
#id = self.canvas.create_text(coords[0], coords[1], text=title, font=font)
|
|
||||||
|
|
||||||
|
|
||||||
"""cp_id = self.canvas.create_arc((coords[0] - arc_size/2, coords[1] - arc_size/2),
|
|
||||||
(coords[0] + arc_size/2, coords[1] + arc_size/2),
|
|
||||||
fill=color,
|
|
||||||
style=PIESLICE,
|
|
||||||
start=start,
|
|
||||||
extent=extent)"""
|
|
||||||
|
|
||||||
|
def draw_ground_object_info(self, ground_object: TheaterGroundObject, pos, color, surface: pygame.Surface):
|
||||||
|
lb = self.font.render("Type : " + ground_object.name_abbrev, False, color, self.BLACK);
|
||||||
|
surface.blit(lb, (pos[0] + 18, pos[1]))
|
||||||
|
|
||||||
def transform_point(self, p: Point, treshold=30) -> (int, int):
|
def transform_point(self, p: Point, treshold=30) -> (int, int):
|
||||||
point_a = list(self.game.theater.reference_points.keys())[0]
|
point_a = list(self.game.theater.reference_points.keys())[0]
|
||||||
@ -238,16 +306,6 @@ class OverviewCanvas:
|
|||||||
|
|
||||||
return X > treshold and X or treshold, Y > treshold and Y or treshold
|
return X > treshold and X or treshold, Y > treshold and Y or treshold
|
||||||
|
|
||||||
def create_cp_title(self, coords, cp: ControlPoint):
|
|
||||||
title = cp.name
|
|
||||||
font = ("Helvetica", 10)
|
|
||||||
|
|
||||||
id = self.canvas.create_text(coords[0], coords[1], text=title, font=font)
|
|
||||||
self.canvas.tag_bind(id, "<Button-1>", self.display(cp))
|
|
||||||
|
|
||||||
id = self.canvas.create_text(coords[0] + 1, coords[1] + 1, text=title, fill='white', font=font)
|
|
||||||
self.canvas.tag_bind(id, "<Button-1>", self.display(cp))
|
|
||||||
|
|
||||||
def _player_color(self):
|
def _player_color(self):
|
||||||
return self.game.player == "USA" and self.BLUE or self.RED
|
return self.game.player == "USA" and self.BLUE or self.RED
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user