def init_ui(self): self.frame_manager = FrameManager(self) libraries = FrameLibraries(self.width, self.height, self.frame_manager) action_clock = FrameActionClock(self.width, self.height, libraries.height, self.frame_manager) commands = FrameCommands(self.width, self.height, libraries.width, action_clock.height + libraries.height, self.frame_manager) terminal = FramePseudoTerminal( self.width, self.height, action_clock.width, self.height - action_clock.height - libraries.height, self.frame_manager) world_screen_position = Vec2d(action_clock.width, action_clock.height + libraries.height) world_frame = FrameWorld(self.width, self.height, world_screen_position[0], world_screen_position[1], self.frame_manager) world_overlay = FrameActionsOverlay(self.width, self.height, world_screen_position[0], world_screen_position[1], self.frame_manager) self.frame_manager.add_frame(libraries) self.frame_manager.add_frame(world_frame) self.frame_manager.add_frame(world_overlay) self.frame_manager.add_frame(action_clock) self.frame_manager.add_frame(commands) self.frame_manager.add_frame(terminal) # generate an initial set of UI events to set up the UI self.frame_manager.handle_ui_event( UIEvent(UIEventType.ActionQueueMaxActionsChange, {'max_actions': max_actions}))
def init_ui(self): self.frame_manager = FrameManager(self) libraries = FrameLibraries(self.width, self.height, self.frame_manager) action_clock = FrameActionClock(self.width, self.height, libraries.height, self.frame_manager) commands = FrameCommands(self.width, self.height, libraries.width, action_clock.height + libraries.height, self.frame_manager) terminal = FramePseudoTerminal(self.width, self.height, action_clock.width, self.height - action_clock.height - libraries.height, self.frame_manager) world_screen_position = Vec2d(action_clock.width, action_clock.height + libraries.height) world_frame = FrameWorld(self.width, self.height, world_screen_position[0], world_screen_position[1], self.frame_manager) world_overlay = FrameActionsOverlay(self.width, self.height, world_screen_position[0], world_screen_position[1], self.frame_manager) self.frame_manager.add_frame(libraries) self.frame_manager.add_frame(world_frame) self.frame_manager.add_frame(world_overlay) self.frame_manager.add_frame(action_clock) self.frame_manager.add_frame(commands) self.frame_manager.add_frame(terminal) # generate an initial set of UI events to set up the UI self.frame_manager.handle_ui_event(UIEvent(UIEventType.ActionQueueMaxActionsChange, {'max_actions': max_actions}))
class MenuGame(Menu): # init def __init__(self, width, height): Menu.__init__(self, width, height) self.queued_actions_cost_so_far = 0 self.action_history = [] self.flagged_exit = False self.entity_manager = None self.game_state = GameState.TakingInput self.current_input_tree = innates_input_tree player_hardcoded_libraries = [ Library('atk', 'temporary test library', [config.game_functions.master_available_functions[0]]) ] #try and load a save game. if that fails, initialize a baseline entity manager and try to feed in an action history. If both fail, the game simply ends up in a newgame state self.entity_manager = self.try_load_savegame() if not self.entity_manager: #currently hardcoded to test player movement self.entity_manager = EntityManager(self) self.entity_manager.add_entity( Entity([ Attribute(AttributeTag.Player, {'max_actions_per_cycle': max_actions}), Attribute(AttributeTag.Visible), Attribute(AttributeTag.OwnedMemory, {'segments': []}), Attribute(AttributeTag.WorldPosition, {'value': Vec2d(2, 2)}), Attribute(AttributeTag.MaxProgramSize, {'value': 5}), Attribute(AttributeTag.ClockRate, {'value': 2}), Attribute( AttributeTag.DrawInfo, { 'character': 64, 'fore_color': libtcod.Color(157, 205, 255), 'back_color': libtcod.black, 'draw_type': WorldRenderType.Character, 'z_level': 2 }), Attribute(AttributeTag.Libraries, {'value': player_hardcoded_libraries}) ])) #for x in range(10): self.entity_manager.add_entity( Entity([ Attribute(AttributeTag.HostileProgram), Attribute(AttributeTag.Visible), Attribute(AttributeTag.OwnedMemory, {'segments': []}), Attribute( AttributeTag.WorldPosition, {'value': Vec2d(20, 10)} ), #libtcod.random_get_int(0, 5, 45), libtcod.random_get_int(0, 5, 45))}), Attribute(AttributeTag.MaxProgramSize, {'value': 5}), Attribute(AttributeTag.ClockRate, {'value': 2}), Attribute( AttributeTag.DrawInfo, { 'character': 121, 'fore_color': libtcod.Color(255, 0, 0), 'back_color': libtcod.black, 'draw_type': WorldRenderType.Character, 'z_level': 2 }) ])) self.try_load_action_history() else: self.entity_manager.parent_menu = self self.entity_manager.player_id = 1 self.init_ui() def init_ui(self): self.frame_manager = FrameManager(self) libraries = FrameLibraries(self.width, self.height, self.frame_manager) action_clock = FrameActionClock(self.width, self.height, libraries.height, self.frame_manager) commands = FrameCommands(self.width, self.height, libraries.width, action_clock.height + libraries.height, self.frame_manager) terminal = FramePseudoTerminal( self.width, self.height, action_clock.width, self.height - action_clock.height - libraries.height, self.frame_manager) world_screen_position = Vec2d(action_clock.width, action_clock.height + libraries.height) world_frame = FrameWorld(self.width, self.height, world_screen_position[0], world_screen_position[1], self.frame_manager) world_overlay = FrameActionsOverlay(self.width, self.height, world_screen_position[0], world_screen_position[1], self.frame_manager) self.frame_manager.add_frame(libraries) self.frame_manager.add_frame(world_frame) self.frame_manager.add_frame(world_overlay) self.frame_manager.add_frame(action_clock) self.frame_manager.add_frame(commands) self.frame_manager.add_frame(terminal) # generate an initial set of UI events to set up the UI self.frame_manager.handle_ui_event( UIEvent(UIEventType.ActionQueueMaxActionsChange, {'max_actions': max_actions})) # internal state management def reset_input_tree(self): self.current_input_tree = contextual_input_tree def flag_for_exit(self): self.flagged_exit = True def generate_atk_action(self, input): parsed_str = input.split(',') target_position = Vec2d(int(parsed_str[0]), int(parsed_str[1])) self.queue_action( Action(ActionTag.DamagePosition, { 'absolute': target_position, 'attacker_id': 1, 'cost': 4 })) self.reset_input_tree() # save and load def try_load_savegame(self): if not os.path.isfile('world.sav'): return False reloaded_manager = open('world.sav', 'r') return pickle.load(reloaded_manager) def try_load_action_history(self): if not os.path.isfile('action_history.sav'): return False save_file = open('action_history.sav', 'r') action_history = pickle.load(save_file) self.entity_manager.load_action_history(action_history) self.game_state = GameState.Loading return True def save_current_state(self): save_file = open('world.sav', 'w') #remove back-reference, otherwise Bad Things Happen(TM) self.entity_manager.parent_menu = None pickle.dump(self.entity_manager, save_file) self.entity_manager.parent_menu = self def save_action_history(self): save_file = open('action_history.sav', 'w') pickle.dump(self.entity_manager.action_history, save_file) # action management def handle_input_command(self, input_command): if self.game_state == GameState.TakingInput: player_available_libraries = self.entity_manager.get_entity_by_id( self.entity_manager.player_id).get_attribute( AttributeTag.Libraries) #more todo: catch special commands like __# and such properly #generate UI events for library data if input_command in self.current_input_tree: if hasattr(self.current_input_tree[input_command], ('__call__')): self.current_input_tree[input_command](self) elif isinstance(self.current_input_tree[input_command], Action): self.queue_action(self.current_input_tree[input_command]) elif isinstance(self.current_input_tree[input_command], dict): self.current_input_tree = self.current_input_tree[ input_command] #temp/todo: make this not just pull from MenuGame when i start building an actual libraries structure if hasattr(self, input_command + '_init'): init_function = getattr(self, input_command + '_init') if hasattr(init_function, ('__call__')): init_function() # global commands are arguably in a state of limbo, depending on how the implementation rolls, they can stay for now though elif input_command in global_input_tree: if hasattr(global_input_tree[input_command], ('__call__')): global_input_tree[input_command](self) elif isinstance(global_input_tree[input_command], Action): self.queue_action(global_input_tree[input_command]) elif '__#' in self.current_input_tree: self.current_input_tree['__#'](self, input_command) else: self.frame_manager.handle_ui_event( UIEvent(UIEventType.InvalidCommand, {'command': input_command})) def queue_action(self, action): player = self.entity_manager.get_entity_by_id( self.entity_manager.player_id) player_max_actions = player.get_attribute( AttributeTag.Player).data['max_actions_per_cycle'] action_cost = action.data['cost'] if self.queued_actions_cost_so_far + action_cost <= player_max_actions: self.queued_actions_cost_so_far += action_cost #manually attach the player as the target_id for now - this will need to change when options other than movement are implemented action.data['target_id'] = player.id self.entity_manager.queue_action(action) self.frame_manager.handle_ui_event( UIEvent(UIEventType.ActionQueueAdd, {'action': action})) def execute_queued_actions(self): self.game_state = GameState.Executing self.frame_manager.handle_ui_event(UIEvent(UIEventType.InputDisabled)) self.entity_manager.start_execution() print 'beginning queued commands execution' def clear_queued_actions(self): self.entity_manager.queued_actions = [] self.queued_actions_cost_so_far = 0 self.frame_manager.handle_ui_event( UIEvent(UIEventType.ActionQueueClear)) # debug functions def dump_entities(self): for entity in self.entity_manager.entities: print entity def dump_entity_manager_state(self): print self.entity_manager.is_executing print self.entity_manager.update_timer def snapshot_performance(self): self.frame_manager.should_measure = True # update and draw def update(self, delta): self.frame_manager.update(delta) self.entity_manager.update(delta) if self.game_state == GameState.Executing: if not self.entity_manager.is_executing: self.frame_manager.handle_ui_event( UIEvent(UIEventType.InputEnabled)) self.frame_manager.handle_ui_event( UIEvent(UIEventType.ActionQueueClear)) self.game_state = GameState.TakingInput self.queued_actions_cost_so_far = 0 #future possible optimization/redesign: batch out commands to no longer than x MS per tick to allow UI update of a loading screen elif self.game_state == GameState.Loading: for action in self.action_history: self.entity_manager.handle_action( action ) # may need to convert to dumping into entity manager's queue and calling a load action history method self.game_state = GameState.TakingInput if self.flagged_exit: return MenuStatus.Exit return MenuStatus.Okay def draw(self): self.frame_manager.draw() pass
class MenuGame(Menu): # init def __init__(self, width, height): Menu.__init__(self, width, height) self.queued_actions_cost_so_far = 0 self.action_history = [] self.flagged_exit = False self.entity_manager = None self.game_state = GameState.TakingInput self.current_input_tree = innates_input_tree player_hardcoded_libraries = [ Library( 'atk', 'temporary test library', [config.game_functions.master_available_functions[0]] ) ] #try and load a save game. if that fails, initialize a baseline entity manager and try to feed in an action history. If both fail, the game simply ends up in a newgame state self.entity_manager = self.try_load_savegame() if not self.entity_manager: #currently hardcoded to test player movement self.entity_manager = EntityManager(self) self.entity_manager.add_entity(Entity([ Attribute(AttributeTag.Player, {'max_actions_per_cycle': max_actions}), Attribute(AttributeTag.Visible), Attribute(AttributeTag.OwnedMemory, {'segments':[]}), Attribute(AttributeTag.WorldPosition, {'value': Vec2d(2, 2)}), Attribute(AttributeTag.MaxProgramSize, {'value': 5}), Attribute(AttributeTag.ClockRate, {'value': 2}), Attribute(AttributeTag.DrawInfo, {'character': 64, 'fore_color': libtcod.Color(157,205,255), 'back_color': libtcod.black, 'draw_type': WorldRenderType.Character, 'z_level': 2}), Attribute(AttributeTag.Libraries, {'value': player_hardcoded_libraries}) ]) ) #for x in range(10): self.entity_manager.add_entity(Entity([ Attribute(AttributeTag.HostileProgram), Attribute(AttributeTag.Visible), Attribute(AttributeTag.OwnedMemory, {'segments':[]}), Attribute(AttributeTag.WorldPosition, {'value': Vec2d(20, 10)}), #libtcod.random_get_int(0, 5, 45), libtcod.random_get_int(0, 5, 45))}), Attribute(AttributeTag.MaxProgramSize, {'value': 5}), Attribute(AttributeTag.ClockRate, {'value': 2}), Attribute(AttributeTag.DrawInfo, {'character': 121, 'fore_color': libtcod.Color(255,0,0), 'back_color': libtcod.black, 'draw_type': WorldRenderType.Character, 'z_level': 2}) ]) ) self.try_load_action_history() else: self.entity_manager.parent_menu = self self.entity_manager.player_id = 1 self.init_ui() def init_ui(self): self.frame_manager = FrameManager(self) libraries = FrameLibraries(self.width, self.height, self.frame_manager) action_clock = FrameActionClock(self.width, self.height, libraries.height, self.frame_manager) commands = FrameCommands(self.width, self.height, libraries.width, action_clock.height + libraries.height, self.frame_manager) terminal = FramePseudoTerminal(self.width, self.height, action_clock.width, self.height - action_clock.height - libraries.height, self.frame_manager) world_screen_position = Vec2d(action_clock.width, action_clock.height + libraries.height) world_frame = FrameWorld(self.width, self.height, world_screen_position[0], world_screen_position[1], self.frame_manager) world_overlay = FrameActionsOverlay(self.width, self.height, world_screen_position[0], world_screen_position[1], self.frame_manager) self.frame_manager.add_frame(libraries) self.frame_manager.add_frame(world_frame) self.frame_manager.add_frame(world_overlay) self.frame_manager.add_frame(action_clock) self.frame_manager.add_frame(commands) self.frame_manager.add_frame(terminal) # generate an initial set of UI events to set up the UI self.frame_manager.handle_ui_event(UIEvent(UIEventType.ActionQueueMaxActionsChange, {'max_actions': max_actions})) # internal state management def reset_input_tree(self): self.current_input_tree = contextual_input_tree def flag_for_exit(self): self.flagged_exit = True def generate_atk_action(self, input): parsed_str = input.split(',') target_position = Vec2d(int(parsed_str[0]), int(parsed_str[1])) self.queue_action(Action(ActionTag.DamagePosition, {'absolute': target_position, 'attacker_id': 1, 'cost': 4})) self.reset_input_tree() # save and load def try_load_savegame(self): if not os.path.isfile('world.sav'): return False reloaded_manager = open('world.sav', 'r') return pickle.load(reloaded_manager) def try_load_action_history(self): if not os.path.isfile('action_history.sav'): return False save_file = open('action_history.sav', 'r') action_history = pickle.load(save_file) self.entity_manager.load_action_history(action_history) self.game_state = GameState.Loading return True def save_current_state(self): save_file = open('world.sav', 'w') #remove back-reference, otherwise Bad Things Happen(TM) self.entity_manager.parent_menu = None pickle.dump(self.entity_manager, save_file) self.entity_manager.parent_menu = self def save_action_history(self): save_file = open('action_history.sav', 'w') pickle.dump(self.entity_manager.action_history, save_file) # action management def handle_input_command(self, input_command): if self.game_state == GameState.TakingInput: player_available_libraries = self.entity_manager.get_entity_by_id(self.entity_manager.player_id).get_attribute(AttributeTag.Libraries) #more todo: catch special commands like __# and such properly #generate UI events for library data if input_command in self.current_input_tree: if hasattr(self.current_input_tree[input_command], ('__call__')): self.current_input_tree[input_command](self) elif isinstance(self.current_input_tree[input_command], Action): self.queue_action(self.current_input_tree[input_command]) elif isinstance(self.current_input_tree[input_command], dict): self.current_input_tree = self.current_input_tree[input_command] #temp/todo: make this not just pull from MenuGame when i start building an actual libraries structure if hasattr(self, input_command + '_init'): init_function = getattr(self, input_command + '_init') if hasattr(init_function, ('__call__')): init_function() # global commands are arguably in a state of limbo, depending on how the implementation rolls, they can stay for now though elif input_command in global_input_tree: if hasattr(global_input_tree[input_command], ('__call__')): global_input_tree[input_command](self) elif isinstance(global_input_tree[input_command], Action): self.queue_action(global_input_tree[input_command]) elif '__#' in self.current_input_tree: self.current_input_tree['__#'](self, input_command) else: self.frame_manager.handle_ui_event(UIEvent(UIEventType.InvalidCommand, {'command': input_command})) def queue_action(self, action): player = self.entity_manager.get_entity_by_id(self.entity_manager.player_id) player_max_actions = player.get_attribute(AttributeTag.Player).data['max_actions_per_cycle'] action_cost = action.data['cost'] if self.queued_actions_cost_so_far + action_cost <= player_max_actions: self.queued_actions_cost_so_far += action_cost #manually attach the player as the target_id for now - this will need to change when options other than movement are implemented action.data['target_id'] = player.id self.entity_manager.queue_action(action) self.frame_manager.handle_ui_event(UIEvent(UIEventType.ActionQueueAdd, {'action': action})) def execute_queued_actions(self): self.game_state = GameState.Executing self.frame_manager.handle_ui_event(UIEvent(UIEventType.InputDisabled)) self.entity_manager.start_execution() print 'beginning queued commands execution' def clear_queued_actions(self): self.entity_manager.queued_actions = [] self.queued_actions_cost_so_far = 0 self.frame_manager.handle_ui_event(UIEvent(UIEventType.ActionQueueClear)) # debug functions def dump_entities(self): for entity in self.entity_manager.entities: print entity def dump_entity_manager_state(self): print self.entity_manager.is_executing print self.entity_manager.update_timer def snapshot_performance(self): self.frame_manager.should_measure = True # update and draw def update(self, delta): self.frame_manager.update(delta) self.entity_manager.update(delta) if self.game_state == GameState.Executing: if not self.entity_manager.is_executing: self.frame_manager.handle_ui_event(UIEvent(UIEventType.InputEnabled)) self.frame_manager.handle_ui_event(UIEvent(UIEventType.ActionQueueClear)) self.game_state = GameState.TakingInput self.queued_actions_cost_so_far = 0 #future possible optimization/redesign: batch out commands to no longer than x MS per tick to allow UI update of a loading screen elif self.game_state == GameState.Loading: for action in self.action_history: self.entity_manager.handle_action(action) # may need to convert to dumping into entity manager's queue and calling a load action history method self.game_state = GameState.TakingInput if self.flagged_exit: return MenuStatus.Exit return MenuStatus.Okay def draw(self): self.frame_manager.draw() pass