def start_dialogue(self, command: LaytonLib.gds.GDSCommand, exec_dialogue=True): dialogue_id = command.params[0] dialogue_gds = self.event_data.get_text(dialogue_id) Debug.log(f"Dialogue: {dialogue_gds.params[4]}", self) # If we are executing the dialogue if exec_dialogue: self.dialogue.reset_all() self.show_dialogue() self.dialogue.text_left_to_do = dialogue_gds.params[4] self.dialogue.replace_substitutions() self.dialogue.voice_line = self.next_voice else: # Reset the voice so that the next dialogue that is executed doesn't play it self.next_voice = -1 # If there is a character talking if dialogue_gds.params[0] != 0: self.dialogue.character_talking = self.characters[ dialogue_gds.params[0]] if exec_dialogue: self.dialogue.init_char_name() if dialogue_gds.params[1] != "NONE": # Set animation by name self.dialogue.character_talking.set_tag(dialogue_gds.params[1]) # Update positions and etc self.dialogue.character_talking.update_() else: self.dialogue.character_talking = None self.dialogue.char_name.kill()
def tick(self): self._delta_time = self.pygame_clock.tick(self.fps_cap) / 1000.0 self.events = pygame.event.get() self.input_manager.update_events(self.events) if self.log_fps: Debug.log(f"FPS: { 1 / self._delta_time }", self)
def gds_to_images(self, gds: LaytonLib.gds.GDSScript): transform_list = { 0x2: "fade_in_both.png", 0x3: "fade_out_both.png", 0x4: "dialogue.png", 0x21: "load_bg_btm.png", 0x22: "load_bg_top.png", 0x2a: "chr_show.png", 0x2b: "chr_hide.png", 0x2c: "chr_visible.png", 0x30: "chr_slot.png", 0x32: "fade_btm_in.png", 0x33: "fade_btm_out.png", 0x31: "wait.png", 0x37: "bg_alpha.png", 0x3f: "chr_anim.png", 0x5c: "voice.png", 0x5d: "sad_sfx.png", 0x6a: "bg_shake.png", 0x87: "fade_out_top_timed.png", 0x88: "fade_in_top_timed.png", } result = [] commands_to_del = [] for command in gds.commands: # type: LaytonLib.gds.GDSCommand if command.command not in transform_list.keys(): commands_to_del.append(command) continue result.append(transform_list[command.command]) for command in commands_to_del: Debug.log_warning( f"Removed command {command}. This event shouldn't be saved.", self) gds.commands.remove(command) return result
def get_joystick_axis(self, joy_number, axis): if joy_number < 0 or joy_number >= self.joystick_manager.joystick_count: Debug.log_error( "Requested joystick_axis from joystick {}, out of range". format(joy_number), self) return 0 if axis not in self.joystick_axis[joy_number].keys(): return 0 return self.joystick_axis[joy_number][axis]
def get_joystick_button(self, joy_number, button): if joy_number < 0 or joy_number >= self.joystick_manager.joystick_count: Debug.log_error( "Requested joystick_axis from joystick {}, out of range". format(joy_number), self) return False if button not in self.joystick_dict[joy_number].keys(): return False return self.joystick_dict[joy_number][button]
def change_to_file(self, file_path): Debug.log(f"Changing to file: {file_path}", self) if file_path.endswith(".arc"): try: load_bg(file_path, self.preview_sprite) except: load_animation(file_path, self.preview_sprite) self.preview_sprite.scale_by_factor([2, 2]) self.preview_sprite.add(self.preview_group)
def get_joystick_button_up(self, joy_number, button): if joy_number < 0 or joy_number >= self.joystick_manager.joystick_count: Debug.log_error( "Requested joystick_button from joystick {}, out of range". format(joy_number), self) return False if button not in self.joystick_dict[joy_number].keys( ) or button not in self.joystick_updated[joy_number]: return False is_button_down = self.joystick_dict[joy_number][button] return not is_button_down
def update_events(self, events): self.key_grab_id = None self.mouse_grab_id = None self.last_events = events self.key_updated = [] self.mouse_updated = [] self.quit = False for joy_number in self.joystick_updated.keys(): self.joystick_updated[joy_number] = [] for event in events: if event.type == pygame.KEYDOWN: key = event.key self.key_down_dict[key] = True self.key_updated.append(key) elif event.type == pygame.KEYUP: key = event.key self.key_down_dict[key] = False self.key_updated.append(key) elif event.type == pygame.MOUSEBUTTONDOWN: button = event.button self.mouse_down_dict[button] = True self.mouse_updated.append(button) elif event.type == pygame.MOUSEBUTTONUP: button = event.button self.mouse_down_dict[button] = False self.mouse_updated.append(button) elif event.type == pygame.JOYBUTTONDOWN: button = event.button joy_id = event.joy if joy_id not in self.joystick_manager.joy_order: Debug.log_warning("Joy {} event, but not in joy_order", "Input Manager") continue joy_number = self.joystick_manager.joy_order.index(joy_id) self.joystick_dict[joy_number][button] = True self.joystick_updated[joy_number].append(button) elif event.type == pygame.JOYBUTTONUP: button = event.button joy_id = event.joy if joy_id not in self.joystick_manager.joy_order: Debug.log_warning("Joy {} event, but not in joy_order", "Input Manager") continue joy_number = self.joystick_manager.joy_order.index(joy_id) self.joystick_dict[joy_number][button] = False self.joystick_updated[joy_number].append(button) elif event.type == pygame.JOYAXISMOTION: joy_id = event.joy axis = event.axis if joy_id not in self.joystick_manager.joy_order: Debug.log_warning("Joy {} event, but not in joy_order", "Input Manager") continue joy_number = self.joystick_manager.joy_order.index(joy_id) if axis not in self.joystick_axis[joy_number].keys(): self.joystick_axis[joy_number][axis] = 0 self.joystick_axis[joy_number][axis] = event.value elif event.type == pygame.QUIT: self.quit = True
def __init__(self, screen_size=None, full_screen=True, log_fps=False, fps_limit=60, name="Default Name"): if not GameManager.__inited: pygame.init() pygame.mixer.init() self.running = True if not screen_size: Debug.log_error("Screen size not specified", "GameManager") self.running = False return GameManager.__inited = True flags = pygame.HWSURFACE | pygame.DOUBLEBUF if full_screen: flags = flags | pygame.FULLSCREEN Screen.new_screen(screen_size, flags, name=name) self._delta_time = 1 self.time_scale = 1 self.pygame_clock = pygame.time.Clock() # type: pygame self.pygame_clock.tick() self.log_fps = log_fps self.input_manager = Input() random.seed(time.time()) self.fps_cap = fps_limit self.events = []
def run_gds_command(self, run_until_command=-1): auto_progress = run_until_command == -1 # Should we play commands if not auto_progress: Debug.log_debug(f"Event running until command {run_until_command}", self) self.top_fader.max_fade = 180 self.bottom_fader.max_fade = 180 else: self.top_fader.max_fade = 255 self.bottom_fader.max_fade = 255 while True: should_return = False # Should we return and stop playing commands? if self.current_gds_command >= len( self.event_data.event_gds.commands): break next_command: LaytonLib.gds.GDSCommand = self.event_data.event_gds.commands[ self.current_gds_command] self.current_gds_command += 1 # Have we completed run_until_command? run_until_command_completed = (self.current_gds_command > run_until_command) if next_command.command == 0x2: # Both screens fade in Debug.log("Fading in both screens", self) self.top_fader.fade_in(auto_progress, not run_until_command_completed) self.bottom_fader.fade_in(False, not run_until_command_completed) should_return = True elif next_command.command == 0x3: # Both screens fade out Debug.log("Fading out both screens", self) self.top_fader.fade_out(auto_progress, not run_until_command_completed) self.bottom_fader.fade_out(False, not run_until_command_completed) should_return = True elif next_command.command == 0x4: # Dialogue Debug.log(f"Starting dialogue {next_command.params[0]}", self) self.start_dialogue(next_command, exec_dialogue=run_until_command_completed) should_return = True elif next_command.command == 0x21: # Set BG Bottom path = ".".join(next_command.params[0].split(".") [:-1]) + ".arc" # Change extension Debug.log(f"Loading BG on bottom {path}", self) load_bg("data_lt2/bg/" + path, self.bottom_bg) self.back_translucent.image.set_alpha(0) self.back_translucent.dirty = 1 elif next_command.command == 0x22: # Set BG Top path = ".".join(next_command.params[0].split(".") [:-1]) + ".arc" # Change extension Debug.log(f"Loading BG on top {path}", self) load_bg("data_lt2/bg/" + path, self.top_bg) elif next_command.command == 0x2a: # Show character Debug.log(f"Showing character {next_command.params[0]}", self) char_id = self.char_order[next_command.params[0]] self.characters[char_id].show() elif next_command.command == 0x2b: # Hide character Debug.log(f"Hiding character {next_command.params[0]}", self) char_id = self.char_order[next_command.params[0]] self.characters[char_id].hide() elif next_command.command == 0x2C: # Set character visibility Debug.log( f"Setting character {next_command.params[0]} visibility " f"to {next_command.params[1] > 0}", self) char_id = self.char_order[next_command.params[0]] if next_command.params[1] > 0: self.characters[char_id].show() else: self.characters[char_id].hide() elif next_command.command == 0x30: # Set character slot Debug.log( f"Setting character {next_command.params[0]} slot to {next_command.params[1]}", self) char_id = self.char_order[next_command.params[0]] char: EventCharacter = self.characters[char_id] char.slot = next_command.params[1] char.update_() elif next_command.command == 0x32: # Bottom fade in Debug.log(f"Fading bottom in", self) self.bottom_fader.fade_in(auto_progress, not run_until_command_completed) should_return = True elif next_command.command == 0x33: # Bottom fade out Debug.log("Fading bottom out", self) self.bottom_fader.fade_out(auto_progress, not run_until_command_completed) should_return = True elif next_command.command == 0x31: # Wait frames if run_until_command_completed: self.wait(next_command.params[0]) Debug.log(f"Waiting {self.wait_timer}", self) should_return = True elif next_command.command == 0x37: # Set BG Opacity Debug.log(f"Setting BG opacity to {next_command.params[3]}", self) self.back_translucent.image.set_alpha(next_command.params[3]) self.back_translucent.dirty = 1 elif next_command.command == 0x3f: # Set character animation Debug.log( f"Setting character {next_command.params[0]} animation to {next_command.params[1]}", self) self.characters[next_command.params[0]].set_tag( next_command.params[1]) self.characters[next_command.params[0]].update_() elif next_command.command == 0x5c: # Set voice line for next command Debug.log(f"Playing voice line {next_command.params[0]}", self) self.next_voice = next_command.params[0] elif next_command.command == 0x5d: # Play SFX Debug.log(f"Playing SAD SFX {next_command.params[0]}", self) if run_until_command_completed: sfx_path = f"data_lt2/stream/ST_{str(next_command.params[0]).zfill(3)}.SAD" sfx = load_effect(sfx_path) self.sound_player.start_sound(sfx) elif next_command.command == 0x5e: # Play SFX Sequenced (NOT IMPLEMENTED) Debug.log(f"SFX Sequenced {next_command.params}", self) elif next_command.command == 0x6a: # Shake bottom screen Debug.log(f"Shaking screen bottom", self) if run_until_command_completed: self.bottom_bg.shake() elif next_command.command == 0x87: # Fade out top timed Debug.log(f"Fading out top in {next_command.params[0]} frames", self) self.top_fader.fade_out(run_until_command == -1, not run_until_command_completed) self.top_fader.current_time = next_command.params[ 0] / ORIGINAL_FPS should_return = True elif next_command.command == 0x88: # Fade in top timed Debug.log(f"Fading in top in {next_command.params[0]} frames", self) self.top_fader.fade_in(run_until_command == -1, not run_until_command_completed) self.top_fader.current_time = next_command.params[ 0] / ORIGINAL_FPS should_return = True else: Debug.log(f"Unknown dialogue {next_command}", self) # If we have completed run_until_command and we are auto_progressing to next command if run_until_command_completed and not auto_progress: return # If we should return and we are auto_progressing to next command if should_return and auto_progress: return Debug.log("Event execution finished", self)
def change_to_folder(self, folder_path): Debug.log(f"Changing to folder: {folder_path}", self) self.open_folder(folder_path + "/")