Return to repo list

heart-of-gold

Tactical RPG written in python, using pygame.
Return to HMagellan.com

commit bed90a4b9717102f5a9d383502e06ddf788ffa24
parent 4ce18f339f53c692a90060cd355af8623766ff77
Author: Erik Letson <hmagellan@hmagellan.com>
Date:   Thu, 12 Nov 2020 21:13:12 -0600

Turn order working! FFX-style turns!

Diffstat:
Mdata/board/testmap1/testmap1.json | 121+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Adata/img/jisella_2.png | 0
Adata/img/jisella_3.png | 0
Adata/img/jisella_4.png | 0
Adata/img/turn_order_tray_1.png | 0
Mdata/json/anims.json | 198+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdata/json/sheets.json | 15+++++++++++++++
Msrc/bus.py | 2++
Msrc/game.py | 6+++++-
Msrc/interface.py | 3++-
Msrc/turn.py | 53+++++++++++++++++++++++++++++------------------------
11 files changed, 369 insertions(+), 29 deletions(-)

diff --git a/data/board/testmap1/testmap1.json b/data/board/testmap1/testmap1.json @@ -59,7 +59,7 @@ "testent2" : { "name" : "Fakella", "type" : "Piece", - "sheet" : "jisella_1", + "sheet" : "jisella_2", "sprite" : [0, 0], "visible" : true, "animation" : "stand_R", @@ -72,7 +72,7 @@ "HP" : 100, "ATK" : 10, "DEF" : 6, - "SPD" : 9, + "SPD" : 3, "ACC" : 7, "INT" : 5, "WIS" : 6, @@ -91,7 +91,7 @@ "HP" : 100, "ATK" : 10, "DEF" : 6, - "SPD" : 9, + "SPD" : 3, "ACC" : 7, "INT" : 5, "WIS" : 6, @@ -112,5 +112,120 @@ "acc2" : null, "acc3" : null } + }, + "testent3" : { + "name" : "OtherName", + "type" : "Piece", + "sheet" : "jisella_4", + "sprite" : [0, 0], + "visible" : true, + "animation" : "stand_R", + "animated" : true, + "passable" : false, + "tile" : [7, 2], + "team" : "Enemy", + "normal_stats" : { + "LVL" : 1, + "HP" : 100, + "ATK" : 10, + "DEF" : 6, + "SPD" : 12, + "ACC" : 7, + "INT" : 5, + "WIS" : 6, + "LUK" : 8, + "INIT" : 6, + "CNTR" : 2, + "GARD" : 1, + "PUSH" : 2, + "MOVE" : 6, + "SKIL" : 3, + "PASS" : 3, + "AFFINITY" : "Water" + }, + "active_stats" : { + "LVL" : 1, + "HP" : 100, + "ATK" : 10, + "DEF" : 6, + "SPD" : 12, + "ACC" : 7, + "INT" : 5, + "WIS" : 6, + "LUK" : 8, + "INIT" : 6, + "CNTR" : 2, + "GARD" : 1, + "PUSH" : 2, + "MOVE" : 6, + "SKIL" : 3, + "PASS" : 3, + "AFFINITY" : "Water" + }, + "equipment" : { + "weapon" : "Basic_Sword_1", + "armor" : "Basic_Armor_1", + "acc1" : null, + "acc2" : null, + "acc3" : null + } + }, + "testent4" : { + "name" : "SomeName", + "type" : "Piece", + "sheet" : "jisella_3", + "sprite" : [0, 0], + "visible" : true, + "animation" : "stand_R", + "animated" : true, + "passable" : false, + "tile" : [0, 9], + "team" : "Enemy", + "normal_stats" : { + "LVL" : 1, + "HP" : 100, + "ATK" : 10, + "DEF" : 6, + "SPD" : 1, + "ACC" : 7, + "INT" : 5, + "WIS" : 6, + "LUK" : 8, + "INIT" : 9, + "CNTR" : 2, + "GARD" : 1, + "PUSH" : 2, + "MOVE" : 6, + "SKIL" : 3, + "PASS" : 3, + "AFFINITY" : "Water" + }, + "active_stats" : { + "LVL" : 1, + "HP" : 100, + "ATK" : 10, + "DEF" : 6, + "SPD" : 1, + "ACC" : 7, + "INT" : 5, + "WIS" : 6, + "LUK" : 8, + "INIT" : 9, + "CNTR" : 2, + "GARD" : 1, + "PUSH" : 2, + "MOVE" : 6, + "SKIL" : 3, + "PASS" : 3, + "AFFINITY" : "Water" + }, + "equipment" : { + "weapon" : "Basic_Sword_1", + "armor" : "Basic_Armor_1", + "acc1" : null, + "acc2" : null, + "acc3" : null + } } } + diff --git a/data/img/jisella_2.png b/data/img/jisella_2.png Binary files differ. diff --git a/data/img/jisella_3.png b/data/img/jisella_3.png Binary files differ. diff --git a/data/img/jisella_4.png b/data/img/jisella_4.png Binary files differ. diff --git a/data/img/turn_order_tray_1.png b/data/img/turn_order_tray_1.png Binary files differ. diff --git a/data/json/anims.json b/data/json/anims.json @@ -65,6 +65,204 @@ { "sprite" : [3, 2], "timer" : 6 } ] }, + "jisella_2" : { + "stand_L" : [ + { "sprite" : [0, 0], "timer" : 4 }, + { "sprite" : [1, 0], "timer" : 4 }, + { "sprite" : [2, 0], "timer" : 4 }, + { "sprite" : [3, 0], "timer" : 4 }, + { "sprite" : [0, 1], "timer" : 4 }, + { "sprite" : [1, 1], "timer" : 4 }, + { "sprite" : [2, 1], "timer" : 4 }, + { "sprite" : [3, 1], "timer" : 4 } + ], + "stand_R" : [ + { "sprite" : [4, 0], "timer" : 4 }, + { "sprite" : [5, 0], "timer" : 4 }, + { "sprite" : [6, 0], "timer" : 4 }, + { "sprite" : [7, 0], "timer" : 4 }, + { "sprite" : [4, 1], "timer" : 4 }, + { "sprite" : [5, 1], "timer" : 4 }, + { "sprite" : [6, 1], "timer" : 4 }, + { "sprite" : [7, 1], "timer" : 4 } + ], + "stand_U" : [ + { "sprite" : [8, 0], "timer" : 4 }, + { "sprite" : [9, 0], "timer" : 4 }, + { "sprite" : [10, 0], "timer" : 4 }, + { "sprite" : [11, 0], "timer" : 4 }, + { "sprite" : [8, 1], "timer" : 4 }, + { "sprite" : [9, 1], "timer" : 4 }, + { "sprite" : [10, 1], "timer" : 4 }, + { "sprite" : [11, 1], "timer" : 4 } + ], + "stand_D" : [ + { "sprite" : [0, 0], "timer" : 4 }, + { "sprite" : [1, 0], "timer" : 4 }, + { "sprite" : [2, 0], "timer" : 4 }, + { "sprite" : [3, 0], "timer" : 4 }, + { "sprite" : [0, 1], "timer" : 4 }, + { "sprite" : [1, 1], "timer" : 4 }, + { "sprite" : [2, 1], "timer" : 4 }, + { "sprite" : [3, 1], "timer" : 4 } + ], + "walk_L" : [ + { "sprite" : [0, 2], "timer" : 6 }, + { "sprite" : [1, 2], "timer" : 6 }, + { "sprite" : [2, 2], "timer" : 6 }, + { "sprite" : [3, 2], "timer" : 6 } + ], + "walk_R" : [ + { "sprite" : [4, 2], "timer" : 6 }, + { "sprite" : [5, 2], "timer" : 6 }, + { "sprite" : [6, 2], "timer" : 6 }, + { "sprite" : [7, 2], "timer" : 6 } + ], + "walk_U" : [ + { "sprite" : [8, 2], "timer" : 6 }, + { "sprite" : [9, 2], "timer" : 6 }, + { "sprite" : [10, 2], "timer" : 6 }, + { "sprite" : [11, 2], "timer" : 6 } + ], + "walk_D" : [ + { "sprite" : [0, 2], "timer" : 6 }, + { "sprite" : [1, 2], "timer" : 6 }, + { "sprite" : [2, 2], "timer" : 6 }, + { "sprite" : [3, 2], "timer" : 6 } + ] + }, + "jisella_3" : { + "stand_L" : [ + { "sprite" : [0, 0], "timer" : 4 }, + { "sprite" : [1, 0], "timer" : 4 }, + { "sprite" : [2, 0], "timer" : 4 }, + { "sprite" : [3, 0], "timer" : 4 }, + { "sprite" : [0, 1], "timer" : 4 }, + { "sprite" : [1, 1], "timer" : 4 }, + { "sprite" : [2, 1], "timer" : 4 }, + { "sprite" : [3, 1], "timer" : 4 } + ], + "stand_R" : [ + { "sprite" : [4, 0], "timer" : 4 }, + { "sprite" : [5, 0], "timer" : 4 }, + { "sprite" : [6, 0], "timer" : 4 }, + { "sprite" : [7, 0], "timer" : 4 }, + { "sprite" : [4, 1], "timer" : 4 }, + { "sprite" : [5, 1], "timer" : 4 }, + { "sprite" : [6, 1], "timer" : 4 }, + { "sprite" : [7, 1], "timer" : 4 } + ], + "stand_U" : [ + { "sprite" : [8, 0], "timer" : 4 }, + { "sprite" : [9, 0], "timer" : 4 }, + { "sprite" : [10, 0], "timer" : 4 }, + { "sprite" : [11, 0], "timer" : 4 }, + { "sprite" : [8, 1], "timer" : 4 }, + { "sprite" : [9, 1], "timer" : 4 }, + { "sprite" : [10, 1], "timer" : 4 }, + { "sprite" : [11, 1], "timer" : 4 } + ], + "stand_D" : [ + { "sprite" : [0, 0], "timer" : 4 }, + { "sprite" : [1, 0], "timer" : 4 }, + { "sprite" : [2, 0], "timer" : 4 }, + { "sprite" : [3, 0], "timer" : 4 }, + { "sprite" : [0, 1], "timer" : 4 }, + { "sprite" : [1, 1], "timer" : 4 }, + { "sprite" : [2, 1], "timer" : 4 }, + { "sprite" : [3, 1], "timer" : 4 } + ], + "walk_L" : [ + { "sprite" : [0, 2], "timer" : 6 }, + { "sprite" : [1, 2], "timer" : 6 }, + { "sprite" : [2, 2], "timer" : 6 }, + { "sprite" : [3, 2], "timer" : 6 } + ], + "walk_R" : [ + { "sprite" : [4, 2], "timer" : 6 }, + { "sprite" : [5, 2], "timer" : 6 }, + { "sprite" : [6, 2], "timer" : 6 }, + { "sprite" : [7, 2], "timer" : 6 } + ], + "walk_U" : [ + { "sprite" : [8, 2], "timer" : 6 }, + { "sprite" : [9, 2], "timer" : 6 }, + { "sprite" : [10, 2], "timer" : 6 }, + { "sprite" : [11, 2], "timer" : 6 } + ], + "walk_D" : [ + { "sprite" : [0, 2], "timer" : 6 }, + { "sprite" : [1, 2], "timer" : 6 }, + { "sprite" : [2, 2], "timer" : 6 }, + { "sprite" : [3, 2], "timer" : 6 } + ] + }, + "jisella_4" : { + "stand_L" : [ + { "sprite" : [0, 0], "timer" : 4 }, + { "sprite" : [1, 0], "timer" : 4 }, + { "sprite" : [2, 0], "timer" : 4 }, + { "sprite" : [3, 0], "timer" : 4 }, + { "sprite" : [0, 1], "timer" : 4 }, + { "sprite" : [1, 1], "timer" : 4 }, + { "sprite" : [2, 1], "timer" : 4 }, + { "sprite" : [3, 1], "timer" : 4 } + ], + "stand_R" : [ + { "sprite" : [4, 0], "timer" : 4 }, + { "sprite" : [5, 0], "timer" : 4 }, + { "sprite" : [6, 0], "timer" : 4 }, + { "sprite" : [7, 0], "timer" : 4 }, + { "sprite" : [4, 1], "timer" : 4 }, + { "sprite" : [5, 1], "timer" : 4 }, + { "sprite" : [6, 1], "timer" : 4 }, + { "sprite" : [7, 1], "timer" : 4 } + ], + "stand_U" : [ + { "sprite" : [8, 0], "timer" : 4 }, + { "sprite" : [9, 0], "timer" : 4 }, + { "sprite" : [10, 0], "timer" : 4 }, + { "sprite" : [11, 0], "timer" : 4 }, + { "sprite" : [8, 1], "timer" : 4 }, + { "sprite" : [9, 1], "timer" : 4 }, + { "sprite" : [10, 1], "timer" : 4 }, + { "sprite" : [11, 1], "timer" : 4 } + ], + "stand_D" : [ + { "sprite" : [0, 0], "timer" : 4 }, + { "sprite" : [1, 0], "timer" : 4 }, + { "sprite" : [2, 0], "timer" : 4 }, + { "sprite" : [3, 0], "timer" : 4 }, + { "sprite" : [0, 1], "timer" : 4 }, + { "sprite" : [1, 1], "timer" : 4 }, + { "sprite" : [2, 1], "timer" : 4 }, + { "sprite" : [3, 1], "timer" : 4 } + ], + "walk_L" : [ + { "sprite" : [0, 2], "timer" : 6 }, + { "sprite" : [1, 2], "timer" : 6 }, + { "sprite" : [2, 2], "timer" : 6 }, + { "sprite" : [3, 2], "timer" : 6 } + ], + "walk_R" : [ + { "sprite" : [4, 2], "timer" : 6 }, + { "sprite" : [5, 2], "timer" : 6 }, + { "sprite" : [6, 2], "timer" : 6 }, + { "sprite" : [7, 2], "timer" : 6 } + ], + "walk_U" : [ + { "sprite" : [8, 2], "timer" : 6 }, + { "sprite" : [9, 2], "timer" : 6 }, + { "sprite" : [10, 2], "timer" : 6 }, + { "sprite" : [11, 2], "timer" : 6 } + ], + "walk_D" : [ + { "sprite" : [0, 2], "timer" : 6 }, + { "sprite" : [1, 2], "timer" : 6 }, + { "sprite" : [2, 2], "timer" : 6 }, + { "sprite" : [3, 2], "timer" : 6 } + ] + }, "cursor1" : { "pulse" : [ { "sprite" : [0, 0], "timer" : 3 }, diff --git a/data/json/sheets.json b/data/json/sheets.json @@ -39,6 +39,21 @@ "dimensions" : [64, 64], "total_sprites" : 72 }, + "jisella_2" : { + "filename" : "jisella_2.png", + "dimensions" : [64, 64], + "total_sprites" : 72 + }, + "jisella_3" : { + "filename" : "jisella_3.png", + "dimensions" : [64, 64], + "total_sprites" : 72 + }, + "jisella_4" : { + "filename" : "jisella_4.png", + "dimensions" : [64, 64], + "total_sprites" : 72 + }, "cursor1" : { "filename" : "cursor1.png", "dimensions" : [64, 64], diff --git a/src/bus.py b/src/bus.py @@ -116,3 +116,5 @@ class ManagerBus(subsystem.GameSubsystem): self.game.scene_manager.current_scene.continue_script() def perform_display_move_range_of_piece(self, piece): self.game.board_manager.display_as_move_range(self.game.piece_manager.get_piece_max_legal_move(self.game.piece_manager.selected_piece)) + def perform_shift_turns(self): + self.game.turn_manager.shift_turns() diff --git a/src/game.py b/src/game.py @@ -1,5 +1,5 @@ import pygame -from . import subsystem, bus, camera, interface, manager, images, sound, board, entity, piece, menu, scene +from . import subsystem, bus, camera, interface, manager, images, sound, board, entity, piece, turn, menu, scene from .constants import * ########### @@ -55,6 +55,7 @@ class Game(object): self.board_manager = board.BoardManager(self, self.manager_bus, "board_manager") self.piece_manager = piece.PieceManager(self, self.manager_bus, "piece_manager") self.scene_manager = scene.SceneManager(self, self.manager_bus, "scene_manager") + self.turn_manager = turn.TurnManager(self, self.manager_bus, "turn_manager") # Setup (This is WIP) self.sheet_manager.load_sheets_from_json("sheets.json") @@ -89,6 +90,8 @@ class Game(object): self.piece_manager.load_pieces_from_file(data) self.piece_manager.load_tile_cursor("cursor1") self.camera.load_camera_surface(self.board_manager.current_board.pixel_dimensions) + # TODO: This maybe shouldn't happen here, probably not ideal in a more complex transition to battle + self.turn_manager.initialize_turns(self.piece_manager.pieces) elif new_mode == STATE_MODES.Still_Scene_Mode: self.control_mode = CTRL_MODES.Still_Scene_Normal self.scene_manager.load_still_scene_from_file(data) @@ -138,6 +141,7 @@ class Game(object): elif self.state_mode == STATE_MODES.Battle_Mode: self.board_manager.update(self.camera.camera_surface) self.piece_manager.update(self.camera.camera_surface) + self.turn_manager.update(self.camera.camera_surface) elif self.state_mode == STATE_MODES.Still_Scene_Mode: self.scene_manager.update(self.camera.camera_surface) diff --git a/src/interface.py b/src/interface.py @@ -90,7 +90,7 @@ class GameInterface(subsystem.GameSubsystem): if self.game.control_mode == CTRL_MODES.Turn_Normal: self.bus.perform_select_piece_with_tile_cursor() sp = self.bus.fetch("piece_manager", "selected_piece") - if sp != None: + if sp != None and sp.taking_turn: self.bus.perform_display_move_range_of_piece(sp) self.game.control_mode = CTRL_MODES.Turn_Select_Move @@ -104,6 +104,7 @@ class GameInterface(subsystem.GameSubsystem): # TODO: Not like this self.game.lose_control(len(to_path) * PIECE_MOVE_DELAY, CTRL_MODES.Turn_Normal) self.bus.perform_load_board_overlay() + self.bus.perform_shift_turns() # Still-scene mode behavior elif self.game.state_mode == STATE_MODES.Still_Scene_Mode: diff --git a/src/turn.py b/src/turn.py @@ -21,10 +21,10 @@ class TurnManager(manager.Manager): info about the current turn in the UI. """ - def __init__(self, game): + def __init__(self, game, bus, name): # Parent initialization - super().__init__(game) + super().__init__(game, bus, name) # Important values self.current_turn = 0 @@ -43,9 +43,9 @@ class TurnManager(manager.Manager): Load up the turns for the first time. """ self.in_play_pieces = pieces - self.shift_turn() + self.shift_turns() - def shift_turn(self): + def shift_turns(self): """ Shift to the next turn. """ @@ -56,50 +56,55 @@ class TurnManager(manager.Manager): # Next, set up the values we need self.current_turn += 1 candidates = [] - np = None + + # If there are any pieces with readiness > 100, go ahead and populate those + # pieces into the candidates (this will skip the following while loop) + for pc in self.in_play_pieces: + if pc.readiness >= 100: + candidates.append(pc) # Generate a list of next turn candidates + # Note that the tick is only iterated here. A tick only occurs when the pieces' + # readiness is increased, so if the while loop is skipped, no ticking takes place while len(candidates) == 0: self.current_tick += 1 for p in self.in_play_pieces: p.readiness += p.active_stats["INIT"] + min(1, (p.active_stats["SPD"] // 3)) if p.readiness >= 100: - candidates.add(p) - - # Sort the candidates by highest readiness, taking the 0th candidate afterward - # as the presumptive next turn piece - candidates.sort(lambda can: can.readiness) - np = candidates[0] + candidates.append(p) - # In the event that more than one piece has equal readiness at the top of the - # list, let the piece with the higest speed go first - for c in candidates: - if c.readiness >= np.readiness and c.active_stats["SPD"] > np.active_stats["SPD"]: - np = c + # Sort the candidates by highest readiness, then (in the event of tied rediness) by + # highest speed + candidates.sort(reverse = True, key = lambda can: (can.readiness, can.active_stats["SPD"])) - # Set np as the current active piece and let it take a turn - self.current_active_piece = np - np.taking_turn = True - np.readiness -= 100 + # Set the 0th candidate as the current active piece and let it take a turn + self.current_active_piece = candidates[0] + self.current_active_piece.taking_turn = True + self.current_active_piece.readiness -= 100 def project_turn_order(self): """ - Make a projection of the assumed turn order. + Make a projection of the upcoming turn order. Fills up a number of entries equal to the turn_depth value (accounting for that many projected turns). """ pt = self.current_tick self.turn_projection = [] + next_turn_candidates = [] rds = { self.in_play_pieces[i] : self.in_play_pieces[i].readiness for i in self.in_play_pieces } - while len(projection) - 1 < self.turn_depth: + while len(self.turn_projection) < self.turn_depth: + pt += 1 for p in rds: rds[p] += p.active_stats["INIT"] + min(1, (p.active_stats["SPD"] // 3)) if rds[p] >= 100: - self.turn_projection.add[p] + next_turn_candidates.append[p] rds[p] -= 100 + next_turn_candidates.sort(reverse = True, key = lambda can: (can.readiness, can.active_stats["SPD"])) + for ntc in next_turn_candidates: + self.turn_projection.append(ntc) - def update_turn_entities(self, surface): + def update_managed(self, surface): """ Update the entities this manager controls. """