diff --git a/client.py b/client.py index 9638e84..7e481d3 100755 --- a/client.py +++ b/client.py @@ -1,6 +1,7 @@ import wx import socket from common import * +import glob class ClientVCKO(wx.App): @@ -18,7 +19,7 @@ class ClientVCKO(wx.App): self.game_frame = GameFrame(self) self.last_lobby_state = "" self.last_game_state = "" - self.debug_frame.set_connection_status() + self.game_count = 0 return True def parse_response(self, response): @@ -36,9 +37,11 @@ class ClientVCKO(wx.App): elif full_command[1] == "state": json_response = ' '.join(full_command[2:]) new_lobby_state = json.loads(json_response) - if new_lobby_state != self.lobby: - self.lobby = new_lobby_state - self.lobby_frame.get_lobby_status() + last_dict = new_lobby_state[-1] if new_lobby_state else None + if last_dict and last_dict in new_lobby_state: + new_lobby_state.remove(last_dict) + self.lobby = new_lobby_state + self.game_count = last_dict['game_count'] else: print("Couldn't understand that response") case "game": @@ -50,12 +53,63 @@ class ClientVCKO(wx.App): elif full_command[1] == "state": json_response = ' '.join(full_command[2:]) new_game_state = json.loads(json_response) + with open("game_state.txt", "w") as dump: + dump.write(json.dumps(new_game_state, indent=4)) if new_game_state == self.last_game_state: return self.last_game_state = new_game_state - + self.game_frame.update_board(self.last_game_state) def update_lobby_status(self): return self.in_lobby +class TiledImages(wx.Window): + def __init__(self, parent, image_path, rows=3, cols=3, overlap=10): + super().__init__(parent) + self.image = wx.Image(image_path) + self.rows = rows + self.cols = cols + self.overlap = overlap + self.SetMinSize(wx.Size(self.image.GetWidth() * self.cols - self.overlap, self.image.GetHeight() * self.rows - self.overlap)) + + def OnPaint(self, event): + dc = wx.PaintDC(self) + for row in range(self.rows): + for col in range(self.cols): + x = col * (self.image.GetWidth() - self.overlap) + y = row * (self.image.GetHeight() - self.overlap) + dc.DrawBitmap(wx.Bitmap(self.image), x, y) + + +class MonsterCard(wx.StaticBitmap): + def __init__(self, parent, card_id): + img_path = None + for file in glob.glob(f"images/monster_{card_id:02d}*.jpg"): + img_path = file + break # Stop searching after the first matching file + if not img_path: + raise ValueError(f"No image found for card ID {card_id:02d}") + + self.parent = parent + self.card_id = card_id + self.bitmap = None + + super().__init__(parent, -1) + + self.Bind(wx.EVT_SIZE, self.on_size) + self.update_bitmap() + + def update_bitmap(self): + img_path = glob.glob(f"images/monster_{self.card_id:02d}*.jpg")[0] + img = wx.Image(img_path, wx.BITMAP_TYPE_ANY) + width, height = self.parent.GetSize() + width = int(width * 0.15) # Set the width to 15% of the parent width + height = int(width * img.GetHeight() / img.GetWidth()) # Scale height to maintain aspect ratio + img = img.Scale(width, height, wx.IMAGE_QUALITY_HIGH) + self.bitmap = wx.Bitmap(img) + self.SetBitmap(self.bitmap) + + def on_size(self, event): + self.update_bitmap() + event.Skip() class GameFrame(wx.Frame): @@ -65,37 +119,29 @@ class GameFrame(wx.Frame): self.panel = wx.Panel(self) # Create a static box sizer with padding - vbox = wx.StaticBoxSizer(wx.StaticBox(self.panel, label=""), wx.VERTICAL) - vbox.AddSpacer(10) # Add a bit of padding at the top + self.vbox = wx.StaticBoxSizer(wx.StaticBox(self.panel, label=""), wx.VERTICAL) + self.vbox.AddSpacer(10) # Add a bit of padding at the top + self.monster_grid = wx.BoxSizer(wx.HORIZONTAL) + # Create the game state list box + self.game_state_list = wx.ListCtrl(self.panel, style=wx.LC_REPORT | wx.LC_SINGLE_SEL) + self.vbox.Add(self.game_state_list, proportion=1, flag=wx.EXPAND | wx.ALL, border=10) - # Wrap the list control widget inside a scrolled window - sw = wx.ScrolledWindow(vbox.GetStaticBox(), style=wx.VSCROLL) - sw.SetScrollbars(1, 1, 1, 1) # Show the scrollbars - self.game_state_list = wx.ListCtrl(sw, style=wx.LC_REPORT | wx.LC_SINGLE_SEL) - sw.SetSizer(wx.BoxSizer(wx.VERTICAL)) - sw.GetSizer().Add(self.game_state_list, proportion=1, flag=wx.EXPAND | wx.ALL, border=10) - - vbox.Add(sw, proportion=1, flag=wx.EXPAND | wx.ALL, border=10) # Add the scrolled window to the sizer - - vbox.AddSpacer(10) # Add a bit of padding at the bottom + self.vbox.AddSpacer(10) # Add a bit of padding at the bottom # Set the sizer for the panel - self.panel.SetSizer(vbox) + self.panel.SetSizer(self.vbox) self.SetMinSize(Constants.medium_window_size) self.last_game_state = "" - self.timer_interval = 500 self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.get_game_status, self.timer) - self.timer.Start(self.timer_interval) + self.timer.Start(500) + self.panel.Layout() def get_game_status(self, event=None): if self.app.in_game and connection_check(): self.app.parse_response(send(f"game get_status {self.app.game_id}")) if self.last_game_state == self.app.last_game_state: - if self.timer_interval < 9500: - self.timer_interval += 500 - self.timer.Start(self.timer_interval) # If the current game state is the same as the last one, don't update the list control return pretty_json_str = json.dumps(self.app.last_game_state, indent=4, sort_keys=False) @@ -107,17 +153,34 @@ class GameFrame(wx.Frame): # Save the new game state self.last_game_state = self.app.last_game_state + def update_board(self, game_state): + game = Game(game_state) + monster_ids = [] + for index, monster_stack in enumerate(game.monster_grid): + monster_stack_sizer = wx.BoxSizer(wx.VERTICAL) # Create a vertical sizer for the monster stack + for monster in monster_stack: + if monster['is_accessible']: + card_id = monster['monster_id'] + try: + img_path = glob.glob(f"images/monster_{card_id:02}*.jpg")[0] + except IndexError: + raise ValueError(f"No image found for card ID {card_id:02}") + bitmap = wx.Bitmap(img_path, wx.BITMAP_TYPE_ANY) + card = MonsterCard(self.panel, card_id) + card.SetBitmap(bitmap) + monster_stack_sizer.Add(card, 0, wx.BOTTOM, 10) # Add the card to the monster stack sizer + monster_ids.append(monster['monster_id']) + # Add the monster stack sizer to the monster grid sizer + self.monster_grid.Add(monster_stack_sizer, 0, wx.LEFT | wx.RIGHT, 10) + self.vbox.Add(self.monster_grid, proportion=1, flag=wx.EXPAND | wx.ALL, border=10) + self.panel.Layout() + self.panel.Refresh() + self.Fit() class LobbyFrame(wx.Frame): def __init__(self, app): super().__init__(parent=None, title='VCK Online Lobby', size=Constants.medium_window_size) self.app = app - - self.timer_interval = 500 - self.timer = wx.Timer(self) - self.Bind(wx.EVT_TIMER, self.get_lobby_status, self.timer) - self.timer.Start(self.timer_interval) - self.panel = wx.Panel(self) self.vertical_sizer = wx.BoxSizer(wx.VERTICAL) @@ -125,16 +188,22 @@ class LobbyFrame(wx.Frame): left_panel = wx.Panel(splitter) left_sizer = wx.BoxSizer(wx.VERTICAL) + status_sizer = wx.BoxSizer(wx.HORIZONTAL) text = wx.StaticText(left_panel, label='Enter name:') self.name_field = wx.TextCtrl(left_panel, style=wx.TE_PROCESS_ENTER, value='') + self.connection_status_indicator = wx.StaticText(left_panel, label="Connection Status") submit_button = wx.Button(left_panel, label='Submit') submit_button.Bind(wx.EVT_BUTTON, self.on_submit) self.name_field.Bind(wx.EVT_TEXT_ENTER, self.on_text_enter) + status_sizer.Add(wx.StaticText(left_panel), 0, wx.EXPAND | wx.RIGHT, 5) + status_sizer.Add(self.connection_status_indicator, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5) + status_sizer.Add(wx.StaticText(left_panel), 0, wx.EXPAND | wx.LEFT, 5) left_sizer.Add(text, 0, wx.ALL, 5) left_sizer.Add(self.name_field, 0, wx.EXPAND | wx.ALL, 5) left_sizer.Add(submit_button, 0, wx.ALL | wx.CENTER, 5) + left_sizer.AddStretchSpacer() + left_sizer.Add(status_sizer, 0, wx.ALIGN_LEFT | wx.BOTTOM, 5) left_panel.SetSizer(left_sizer) - self.last_lobby_state = [] self.current_player_index = None @@ -143,15 +212,27 @@ class LobbyFrame(wx.Frame): self.list_ctrl = wx.ListCtrl(right_panel, style=wx.LC_REPORT) self.list_ctrl.InsertColumn(0, "Player Name") self.list_ctrl.InsertColumn(1, "Ready Status", format=wx.LIST_FORMAT_RIGHT) + self.set_connection_status() self.get_lobby_status() + self.set_game_count() + # Create the ready button ready_button = wx.Button(right_panel, label="Ready Up") ready_button.Bind(wx.EVT_BUTTON, self.on_ready_up) - self.list_ctrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.highlight_current_player) - # Add the list control and ready button to the vertical sizer + + # Create the static text + self.active_games_text = wx.StaticText(right_panel, label="Active games: 42069") + + # Add the static text and ready button to a horizontal box sizer + button_sizer = wx.BoxSizer(wx.HORIZONTAL) + button_sizer.Add(self.active_games_text, 0, wx.ALIGN_BOTTOM | wx.LEFT | wx.BOTTOM, 5) + button_sizer.AddStretchSpacer() + button_sizer.Add(ready_button, 0, wx.ALIGN_BOTTOM | wx.RIGHT | wx.BOTTOM, 5) + + # Add the list control and the button sizer to the vertical sizer right_sizer = wx.BoxSizer(wx.VERTICAL) right_sizer.Add(self.list_ctrl, 1, wx.ALL | wx.EXPAND, 5) - right_sizer.Add(ready_button, 0, wx.ALL | wx.CENTER, 5) + right_sizer.Add(button_sizer, 0, wx.EXPAND, 5) right_panel.SetSizer(right_sizer) splitter.SplitVertically(left_panel, right_panel) @@ -167,12 +248,29 @@ class LobbyFrame(wx.Frame): self.Bind(wx.EVT_SIZE, self.on_size) self.Bind(wx.EVT_CLOSE, self.on_close) - self.timer_interval = 500 - self.timer = wx.Timer(self) - self.Bind(wx.EVT_TIMER, self.get_lobby_status, self.timer) - self.timer.Start(self.timer_interval) + self.lobby_check_timer = wx.Timer(self) + self.Bind(wx.EVT_TIMER, self.get_lobby_status, self.lobby_check_timer) + self.lobby_check_timer.Start(1000) + # Create a timer to call the connection_check method every 2 seconds + self.connection_check_timer = wx.Timer(self) + self.Bind(wx.EVT_TIMER, self.set_connection_status, self.connection_check_timer) + self.connection_check_timer.Start(10000) self.Show() + def set_connection_status(self, event=None): + if connection_check(): + self.connection_status_indicator.SetLabel("Connected") + self.connection_status_indicator.SetForegroundColour(Constants.green) + else: + self.connection_status_indicator.SetLabel("Not Connected") + self.connection_status_indicator.SetForegroundColour(Constants.red) + + def set_game_count(self): + try: + self.active_games_text.SetLabel(f"Active games: {self.app.game_count}") + except AttributeError: + print("Can't set game count. Maybe window hasn't loaded yet") + def on_size(self, event): # Calculate the width of each column based on the width of the list control width = self.list_ctrl.GetSize()[0] @@ -209,13 +307,11 @@ class LobbyFrame(wx.Frame): self.name_field.SetValue("") def get_lobby_status(self, event=None): - if connection_check(): + if not self.app.in_game and connection_check(): self.app.parse_response(send(f"lobby get_status {self.app.player_id}")) if self.app.lobby == self.last_lobby_state: # If the current lobby state is the same as the last one, don't update the list control - if self.timer_interval < 9500: - self.timer_interval += 500 - self.timer.Start(self.timer_interval) + self.set_game_count() return self.list_ctrl.DeleteAllItems() for index, player in enumerate(self.app.lobby): @@ -228,6 +324,7 @@ class LobbyFrame(wx.Frame): self.list_ctrl.SetItemState(index, 0, wx.LIST_STATE_SELECTED) # Save the new lobby state self.last_lobby_state = self.app.lobby + self.set_game_count() def highlight_current_player(self, event=None): if self.current_player_index is not None: @@ -251,7 +348,10 @@ class LobbyFrame(wx.Frame): self.Hide() def on_close(self, event): - self.app.parse_response(send(f"lobby leave {self.app.player_id}")) + try: + self.app.parse_response(send(f"lobby leave {self.app.player_id}")) + except ConnectionRefusedError: + print("Server may be down. Exiting anyway.") self.Destroy() @@ -279,11 +379,10 @@ class DebugFrame(wx.Frame): self.vertical_sizer.Add(self.status_sizer, 0, wx.ALIGN_LEFT | wx.BOTTOM, 5) self.panel.SetSizer(self.vertical_sizer) self.SetMinSize(Constants.small_window_size) - self.Show() - # Create a timer to call the connection_check method every 2 seconds self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.set_connection_status, self.timer) self.timer.Start(10000) + self.set_connection_status() def set_connection_status(self, event=None): if connection_check(): diff --git a/common.py b/common.py index bb7f1ba..6699ed7 100755 --- a/common.py +++ b/common.py @@ -443,6 +443,7 @@ class Game: self.exhausted_count = game_state['exhausted_count'] self.effects = game_state['effects'] self.action_required = game_state['action_required'] + self.last_active_time = 0 def roll_phase(self): self.die_one = random.randint(1, 6) @@ -622,6 +623,20 @@ class Game: print(payout) return payout + def owned_monster_attributes(self, player_id): + return_dict = {attr: 0 for attr in Constants.areas + Constants.types} + for player in self.player_list: + if player.player_id == player_id: + for monster in player.owned_monsters: + for area in Constants.areas: + if monster.area == area: + return_dict[area] += 1 + for monster_type in Constants.types: + if monster.monster_type == monster_type: + return_dict[monster_type] += 1 + + return return_dict + def update_payout_for_role(self, role_name, player_id, payout, split_command): role_count = 0 for player in self.player_list: diff --git a/constants.py b/constants.py index b358c7e..dfa4d3c 100644 --- a/constants.py +++ b/constants.py @@ -2,8 +2,8 @@ class Constants: green = (106, 171, 115) red = (219, 92, 92) server_host = '192.168.1.99' - host = "lukesau.com" - # host = "127.0.1.1" + # host = "lukesau.com" + host = "127.0.1.1" port = 8328 text_format = "utf-8" small_window_size = (300, 150) @@ -12,3 +12,5 @@ class Constants: header_size = 512 buffer_size = 4096 encoding = "utf-8" + areas = ['Hills', 'Ruins', 'Forest', 'Valley', 'Mountains'] + types = ['Minion', 'Titan', 'Warden', 'Boss', 'Beast'] diff --git a/image.jpg b/image.jpg new file mode 100644 index 0000000..0a6bd3f Binary files /dev/null and b/image.jpg differ diff --git a/images/citizen_01_cleric.jpg b/images/citizen_01_cleric.jpg new file mode 100644 index 0000000..d5e2453 Binary files /dev/null and b/images/citizen_01_cleric.jpg differ diff --git a/images/citizen_02_merchant.jpg b/images/citizen_02_merchant.jpg new file mode 100644 index 0000000..f0a6ffe Binary files /dev/null and b/images/citizen_02_merchant.jpg differ diff --git a/images/citizen_03_mercenary.jpg b/images/citizen_03_mercenary.jpg new file mode 100644 index 0000000..3ff2930 Binary files /dev/null and b/images/citizen_03_mercenary.jpg differ diff --git a/images/citizen_04_archer.jpg b/images/citizen_04_archer.jpg new file mode 100644 index 0000000..cd98a46 Binary files /dev/null and b/images/citizen_04_archer.jpg differ diff --git a/images/citizen_05_peasant.jpg b/images/citizen_05_peasant.jpg new file mode 100644 index 0000000..cf658db Binary files /dev/null and b/images/citizen_05_peasant.jpg differ diff --git a/images/citizen_06_knight.jpg b/images/citizen_06_knight.jpg new file mode 100644 index 0000000..a878257 Binary files /dev/null and b/images/citizen_06_knight.jpg differ diff --git a/images/citizen_07_rogue.jpg b/images/citizen_07_rogue.jpg new file mode 100644 index 0000000..79ca726 Binary files /dev/null and b/images/citizen_07_rogue.jpg differ diff --git a/images/citizen_08_champion.jpg b/images/citizen_08_champion.jpg new file mode 100644 index 0000000..13a43b3 Binary files /dev/null and b/images/citizen_08_champion.jpg differ diff --git a/images/citizen_09_paladin.jpg b/images/citizen_09_paladin.jpg new file mode 100644 index 0000000..a2d62aa Binary files /dev/null and b/images/citizen_09_paladin.jpg differ diff --git a/images/citizen_10_butcher.jpg b/images/citizen_10_butcher.jpg new file mode 100644 index 0000000..737bd55 Binary files /dev/null and b/images/citizen_10_butcher.jpg differ diff --git a/images/monster_01_goblin.jpg b/images/monster_01_goblin.jpg new file mode 100644 index 0000000..62937e2 Binary files /dev/null and b/images/monster_01_goblin.jpg differ diff --git a/images/monster_02_goblin.jpg b/images/monster_02_goblin.jpg new file mode 100644 index 0000000..62937e2 Binary files /dev/null and b/images/monster_02_goblin.jpg differ diff --git a/images/monster_03_goblin.jpg b/images/monster_03_goblin.jpg new file mode 100644 index 0000000..62937e2 Binary files /dev/null and b/images/monster_03_goblin.jpg differ diff --git a/images/monster_04_goblin_mage.jpg b/images/monster_04_goblin_mage.jpg new file mode 100644 index 0000000..4e299bb Binary files /dev/null and b/images/monster_04_goblin_mage.jpg differ diff --git a/images/monster_05_goblin_bomber.jpg b/images/monster_05_goblin_bomber.jpg new file mode 100644 index 0000000..7e0069a Binary files /dev/null and b/images/monster_05_goblin_bomber.jpg differ diff --git a/images/monster_06_goblin_king.jpg b/images/monster_06_goblin_king.jpg new file mode 100644 index 0000000..c05ff34 Binary files /dev/null and b/images/monster_06_goblin_king.jpg differ diff --git a/images/monster_07_goblin_mage.jpg b/images/monster_07_goblin_mage.jpg new file mode 100644 index 0000000..4e299bb Binary files /dev/null and b/images/monster_07_goblin_mage.jpg differ diff --git a/images/monster_08_skeleton.jpg b/images/monster_08_skeleton.jpg new file mode 100644 index 0000000..5b7fb13 Binary files /dev/null and b/images/monster_08_skeleton.jpg differ diff --git a/images/monster_09_skeleton.jpg b/images/monster_09_skeleton.jpg new file mode 100644 index 0000000..5b7fb13 Binary files /dev/null and b/images/monster_09_skeleton.jpg differ diff --git a/images/monster_10_skeleton.jpg b/images/monster_10_skeleton.jpg new file mode 100644 index 0000000..5b7fb13 Binary files /dev/null and b/images/monster_10_skeleton.jpg differ diff --git a/images/monster_11_flaming_skeleton.jpg b/images/monster_11_flaming_skeleton.jpg new file mode 100644 index 0000000..555f3e4 Binary files /dev/null and b/images/monster_11_flaming_skeleton.jpg differ diff --git a/images/monster_12_flaming_skeleton.jpg b/images/monster_12_flaming_skeleton.jpg new file mode 100644 index 0000000..555f3e4 Binary files /dev/null and b/images/monster_12_flaming_skeleton.jpg differ diff --git a/images/monster_13_death_knight.jpg b/images/monster_13_death_knight.jpg new file mode 100644 index 0000000..7bb6193 Binary files /dev/null and b/images/monster_13_death_knight.jpg differ diff --git a/images/monster_14_skeleton_king.jpg b/images/monster_14_skeleton_king.jpg new file mode 100644 index 0000000..9326302 Binary files /dev/null and b/images/monster_14_skeleton_king.jpg differ diff --git a/images/monster_15_treant.jpg b/images/monster_15_treant.jpg new file mode 100644 index 0000000..00a8aab Binary files /dev/null and b/images/monster_15_treant.jpg differ diff --git a/images/monster_16_treant.jpg b/images/monster_16_treant.jpg new file mode 100644 index 0000000..00a8aab Binary files /dev/null and b/images/monster_16_treant.jpg differ diff --git a/images/monster_17_treant.jpg b/images/monster_17_treant.jpg new file mode 100644 index 0000000..00a8aab Binary files /dev/null and b/images/monster_17_treant.jpg differ diff --git a/images/monster_18_bane_spider.jpg b/images/monster_18_bane_spider.jpg new file mode 100644 index 0000000..41be101 Binary files /dev/null and b/images/monster_18_bane_spider.jpg differ diff --git a/images/monster_19_bane_spider.jpg b/images/monster_19_bane_spider.jpg new file mode 100644 index 0000000..41be101 Binary files /dev/null and b/images/monster_19_bane_spider.jpg differ diff --git a/images/monster_20_ettercap.jpg b/images/monster_20_ettercap.jpg new file mode 100644 index 0000000..e813049 Binary files /dev/null and b/images/monster_20_ettercap.jpg differ diff --git a/images/monster_21_spider_queen.jpg b/images/monster_21_spider_queen.jpg new file mode 100644 index 0000000..ca60f24 Binary files /dev/null and b/images/monster_21_spider_queen.jpg differ diff --git a/images/monster_22_owlbear.jpg b/images/monster_22_owlbear.jpg new file mode 100644 index 0000000..581f673 Binary files /dev/null and b/images/monster_22_owlbear.jpg differ diff --git a/images/monster_23_owlbear.jpg b/images/monster_23_owlbear.jpg new file mode 100644 index 0000000..581f673 Binary files /dev/null and b/images/monster_23_owlbear.jpg differ diff --git a/images/monster_24_owlbear.jpg b/images/monster_24_owlbear.jpg new file mode 100644 index 0000000..581f673 Binary files /dev/null and b/images/monster_24_owlbear.jpg differ diff --git a/images/monster_25_giant.jpg b/images/monster_25_giant.jpg new file mode 100644 index 0000000..8857247 Binary files /dev/null and b/images/monster_25_giant.jpg differ diff --git a/images/monster_26_giant.jpg b/images/monster_26_giant.jpg new file mode 100644 index 0000000..8857247 Binary files /dev/null and b/images/monster_26_giant.jpg differ diff --git a/images/monster_27_satyr_mage.jpg b/images/monster_27_satyr_mage.jpg new file mode 100644 index 0000000..1b4f3ca Binary files /dev/null and b/images/monster_27_satyr_mage.jpg differ diff --git a/images/monster_28_troll.jpg b/images/monster_28_troll.jpg new file mode 100644 index 0000000..ddc5327 Binary files /dev/null and b/images/monster_28_troll.jpg differ diff --git a/images/monster_29_dire_bear.jpg b/images/monster_29_dire_bear.jpg new file mode 100644 index 0000000..ea7fdba Binary files /dev/null and b/images/monster_29_dire_bear.jpg differ diff --git a/images/monster_30_dire_bear.jpg b/images/monster_30_dire_bear.jpg new file mode 100644 index 0000000..ea7fdba Binary files /dev/null and b/images/monster_30_dire_bear.jpg differ diff --git a/images/monster_31_dire_bear.jpg b/images/monster_31_dire_bear.jpg new file mode 100644 index 0000000..ea7fdba Binary files /dev/null and b/images/monster_31_dire_bear.jpg differ diff --git a/images/monster_32_orc_warrior.jpg b/images/monster_32_orc_warrior.jpg new file mode 100644 index 0000000..1938051 Binary files /dev/null and b/images/monster_32_orc_warrior.jpg differ diff --git a/images/monster_33_orc_warrior.jpg b/images/monster_33_orc_warrior.jpg new file mode 100644 index 0000000..1938051 Binary files /dev/null and b/images/monster_33_orc_warrior.jpg differ diff --git a/images/monster_34_orc_batrider.jpg b/images/monster_34_orc_batrider.jpg new file mode 100644 index 0000000..a66ef97 Binary files /dev/null and b/images/monster_34_orc_batrider.jpg differ diff --git a/images/monster_35_orc_chieftain.jpg b/images/monster_35_orc_chieftain.jpg new file mode 100644 index 0000000..c31a24d Binary files /dev/null and b/images/monster_35_orc_chieftain.jpg differ diff --git a/images/agents.jpg b/images/unused/agents.jpg similarity index 100% rename from images/agents.jpg rename to images/unused/agents.jpg diff --git a/images/agents_back.jpg b/images/unused/agents_back.jpg similarity index 100% rename from images/agents_back.jpg rename to images/unused/agents_back.jpg diff --git a/images/citizens_crimson_seas.jpg b/images/unused/citizens_crimson_seas.jpg similarity index 100% rename from images/citizens_crimson_seas.jpg rename to images/unused/citizens_crimson_seas.jpg diff --git a/images/coxswain.jpg b/images/unused/coxswain.jpg similarity index 100% rename from images/coxswain.jpg rename to images/unused/coxswain.jpg diff --git a/images/crimson_seas_mat.jpg b/images/unused/crimson_seas_mat.jpg similarity index 100% rename from images/crimson_seas_mat.jpg rename to images/unused/crimson_seas_mat.jpg diff --git a/images/domains_crimson_seas.jpg b/images/unused/domains_crimson_seas.jpg similarity index 100% rename from images/domains_crimson_seas.jpg rename to images/unused/domains_crimson_seas.jpg diff --git a/images/events.jpg b/images/unused/events.jpg similarity index 100% rename from images/events.jpg rename to images/unused/events.jpg diff --git a/images/gold_tome.jpg b/images/unused/gold_tome.jpg similarity index 100% rename from images/gold_tome.jpg rename to images/unused/gold_tome.jpg diff --git a/images/magic_tome.jpg b/images/unused/magic_tome.jpg similarity index 100% rename from images/magic_tome.jpg rename to images/unused/magic_tome.jpg diff --git a/images/map.png b/images/unused/map.png similarity index 100% rename from images/map.png rename to images/unused/map.png diff --git a/images/monsters_crimson_seas.jpg b/images/unused/monsters_crimson_seas.jpg similarity index 100% rename from images/monsters_crimson_seas.jpg rename to images/unused/monsters_crimson_seas.jpg diff --git a/images/nobles.jpg b/images/unused/nobles.jpg similarity index 100% rename from images/nobles.jpg rename to images/unused/nobles.jpg diff --git a/images/nobles_back.jpg b/images/unused/nobles_back.jpg similarity index 100% rename from images/nobles_back.jpg rename to images/unused/nobles_back.jpg diff --git a/images/relic_back.jpg b/images/unused/relic_back.jpg similarity index 100% rename from images/relic_back.jpg rename to images/unused/relic_back.jpg diff --git a/images/relics.jpg b/images/unused/relics.jpg similarity index 100% rename from images/relics.jpg rename to images/unused/relics.jpg diff --git a/images/strength_tome.jpg b/images/unused/strength_tome.jpg similarity index 100% rename from images/strength_tome.jpg rename to images/unused/strength_tome.jpg diff --git a/images/tome_back.jpg b/images/unused/tome_back.jpg similarity index 100% rename from images/tome_back.jpg rename to images/unused/tome_back.jpg diff --git a/server.py b/server.py index 918b052..9596490 100755 --- a/server.py +++ b/server.py @@ -16,14 +16,18 @@ class ServerVCKO: self.gamers = [] # Start the thread to remove inactive players - self.inactive_player_thread = threading.Thread(target=self.remove_inactive_players, daemon=True) + self.inactive_player_thread = threading.Thread(target=self.remove_inactive, daemon=True) self.inactive_player_thread.start() - def remove_inactive_players(self): + def remove_inactive(self): while True: current_time = time.time() self.lobby = [player for player in self.lobby if current_time - player.last_active_time <= 60] - time.sleep(10) # check for inactive players every 10 seconds + inactive_games = [game_id for game_id, game in self.game_dict.items() if + current_time - game.last_active_time > 180] + for game_id in inactive_games: + del self.game_dict[game_id] + time.sleep(10) def handle_client(self, conn, addr): print(f"Connection from: {addr}") @@ -39,16 +43,6 @@ class ServerVCKO: case "connection_check": connected = False send_data(conn, "received".encode(Constants.encoding)) - case "server": - connected = False - response_dict = { - "threads": threading.active_count(), - "lobby": self.lobby, - "game_count": len(self.game_dict), - "games": self.game_dict - } - lobby_state = json.dumps(response_dict, cls=SummaryEncoder, indent=2) - send_data(conn, lobby_state.encode(Constants.encoding)) case "lobby": connected = False if full_command[1] == "join" and len(full_command) > 2: @@ -134,6 +128,7 @@ class ServerVCKO: message = "game state error: game not found" send_data(conn, message.encode(Constants.encoding)) else: + game.last_active_time = time.time() self.send_game_state(conn, full_command[2]) case _: connected = False @@ -159,7 +154,9 @@ class ServerVCKO: "is_ready": lobby_member.is_ready } lobby_data.append(player_dict) + lobby_data.append({'game_count': len(self.game_dict)}) response = f"lobby state {json.dumps(lobby_data)}" + print(response) send_data(conn, response.encode(Constants.encoding)) def send_game_state(self, conn, game_id): diff --git a/vckonline.py b/vckonline.py index 3d7817d..5a8df03 100755 --- a/vckonline.py +++ b/vckonline.py @@ -9,6 +9,24 @@ try: base1_new_game_state = load_game_data(str(uuid.uuid4()), "base1", player_list) game = Game(base1_new_game_state) game.slay_monster(player1_id, 1, 1, 0) + game.hire_citizen(player1_id, 1, 0, 0) + game.hire_citizen(player1_id, 3, 0, 0) + game.hire_citizen(player1_id, 4, 0, 0) + game.hire_citizen(player1_id, 5, 0, 0) + game.hire_citizen(player1_id, 6, 0, 0) + game.hire_citizen(player1_id, 7, 0, 0) + game.hire_citizen(player1_id, 8, 0, 0) + game.hire_citizen(player1_id, 9, 0, 0) + game.hire_citizen(player1_id, 10, 0, 0) + game.hire_citizen(player2_id, 1, 0, 0) + game.hire_citizen(player2_id, 3, 0, 0) + game.hire_citizen(player2_id, 4, 0, 0) + game.hire_citizen(player2_id, 5, 0, 0) + game.hire_citizen(player2_id, 6, 0, 0) + game.hire_citizen(player2_id, 7, 0, 0) + game.hire_citizen(player2_id, 8, 0, 0) + game.hire_citizen(player2_id, 9, 0, 0) + game.hire_citizen(player2_id, 10, 0, 0) game.harvest_phase() game_json = json.dumps(game, cls=GameObjectEncoder, indent=2)