class CalculateMode(Mode): keymap = { action.move: False, action.quit: False, action.zoom: False, action.show_help: False, } def enter(self): self.mouse.hide() self.mouse.relative() self.mouse.track() self.shot_sim_overlay = GenericMenu( title='Calculating shot...', frame_color=(0, 0, 0, 0.4), title_pos=(0, 0, -0.2), ) self.add_task(self.run_simulation, 'run_simulation', taskChain='simulation') self.task_action('escape', action.quit, True) self.task_action('mouse1', action.zoom, True) self.task_action('mouse1-up', action.zoom, False) self.task_action('a', action.aim, True) self.task_action('v', action.move, True) self.task_action('v-up', action.move, False) self.task_action('h', action.show_help, True) self.add_task(self.calculate_view_task, 'calculate_view_task') def exit(self): self.remove_task('calculate_view_task') self.shot_sim_overlay.hide() def calculate_view_task(self, task): if not 'run_simulation' in self.tasks: # simulation calculation is finished self.change_mode('shot', enter_kwargs=dict(init_animations=True)) elif self.keymap[action.zoom]: self.zoom_camera_calculate() elif self.keymap[action.move]: self.move_camera_calculate() else: if task.time > ani.rotate_downtime: # Prevents shot follow through from moving camera self.rotate_camera_calculate() else: # Update mouse positions so there is not a big jump self.mouse.touch() if task.time > 0.25: self.shot_sim_overlay.show() return task.cont def run_simulation(self, task): """Run a pool simulation""" self.shots.active.simulate(continuize=False, quiet=False) self.game.process_shot(self.shots.active) self.remove_task('run_simulation') return task.done def zoom_camera_calculate(self): with self.mouse: s = -self.mouse.get_dy() * ani.zoom_sensitivity self.player_cam.node.setPos( pt.autils.multiply_cw(self.player_cam.node.getPos(), 1 - s)) def move_camera_calculate(self): with self.mouse: dxp, dyp = self.mouse.get_dx(), self.mouse.get_dy() h = self.player_cam.focus.getH() * np.pi / 180 + np.pi / 2 dx = dxp * np.cos(h) - dyp * np.sin(h) dy = dxp * np.sin(h) + dyp * np.cos(h) self.player_cam.focus.setX(self.player_cam.focus.getX() + dx * ani.move_sensitivity) self.player_cam.focus.setY(self.player_cam.focus.getY() + dy * ani.move_sensitivity) def rotate_camera_calculate(self): fx, fy = ani.rotate_sensitivity_x, ani.rotate_sensitivity_y with self.mouse: alpha_x = self.player_cam.focus.getH() - fx * self.mouse.get_dx() alpha_y = max( min(0, self.player_cam.focus.getR() + fy * self.mouse.get_dy()), -90) self.player_cam.focus.setH(alpha_x) # Move view laterally self.player_cam.focus.setR(alpha_y) # Move view vertically
class ShotViewer(Interface): is_game = False def __init__(self, *args, **kwargs): Interface.__init__(self, *args, **kwargs) self.create_standby_screen() self.create_instructions() self.create_title('') self.stop() def create_title(self, title): self.title_node = OnscreenText( text = title, pos = (-1.55, -0.93), scale = ani.menu_text_scale*0.7, fg = (1,1,1,1), align = TextNode.ALeft, parent = aspect2d, ) self.title_node.hide() def create_instructions(self): self.instructions = OnscreenText( text = "Press <escape> to exit", pos = (-1.55, 0.93), scale = ani.menu_text_scale*0.7, fg = (1,1,1,1), align = TextNode.ALeft, parent = aspect2d, ) self.instructions.hide() def create_standby_screen(self): self.standby_screen = GenericMenu(frame_color=(0.3,0.3,0.3,1)) self.standby_screen.add_image(ani.logo_paths['default'], pos=(0,0,0), scale=(0.5, 1, 0.44)) text = OnscreenText( text = 'GUI standing by...', style = 1, fg = (1, 1, 1, 1), parent = self.standby_screen.titleMenu, align = TextNode.ALeft, pos = (-1.55,0.93), scale = 0.8*ani.menu_text_scale, ) def show(self, shot_or_shots=None, title=''): if shot_or_shots is None: # No passed shots. This is ok if self.shots has already been defined, but will complain # otherwise if not len(self.shots): raise ConfigError("ShotViewer.show :: No shots passed and no shots set.") else: # Create a new SystemCollection based on type of shot_or_shots if issubclass(type(shot_or_shots), System): self.shots = SystemCollection() self.shots.append(shot_or_shots) elif issubclass(type(shot_or_shots), SystemCollection): self.shots = shot_or_shots if self.shots.active is None: self.shots.set_active(0) self.standby_screen.hide() self.instructions.show() self.create_title(title) self.title_node.show() self.init_help_page() self.help_hint.hide() self.mouse = Mouse() self.init_system_nodes() self.init_hud() params = dict( init_animations = True, single_instance = True, ) self.change_mode('shot', enter_kwargs=params) self.player_cam.load_state('last_scene', ok_if_not_exists=True) self.taskMgr.run() def stop(self): self.standby_screen.show() self.instructions.hide() self.title_node.hide() base.graphicsEngine.renderFrame() base.graphicsEngine.renderFrame() self.taskMgr.stop() def finalizeExit(self): self.stop()
class CamLoadMode(Mode): keymap = { action.quit: False, action.cam_load: True, } def enter(self): if self.last_mode == 'aim': self.last_mode = 'view' self.mouse.show() self.mouse.absolute() self.mouse.track() self.selection = None self.task_action('escape', action.quit, True) self.task_action('2', action.cam_load, True) self.task_action('2-up', action.cam_load, False) self.render_camera_load_buttons() self.add_task(self.cam_load_task, 'cam_load_task') def render_camera_load_buttons(self): self.cam_load_slots = GenericMenu( title="Release key with moused hovered over desired save slot", frame_color=(0, 0, 0, 0.2), title_pos=(0, 0, 0.45), ) pos = -1.2 for slot in range(1, 10): exists = True if f'save_{slot}' in self.player_cam.states else False button = self.cam_load_slots.add_button( text=(f'{slot}', f'{slot}', 'load' if exists else 'empty', f'{slot}'), command=lambda: None, scale=0.1, text_scale=0.6, frameSize=(-1.2, 1.2, -1.2, 1.2), frameColor=(0.3, 0.6, 0.6, 1.0) if exists else (0.8, 0.8, 0.8, 1.0), ) button.setPos((pos, 0, 0.25)) button.bind(DGG.WITHIN, self.update_load_selection, extraArgs=[slot]) button.bind(DGG.WITHOUT, self.update_load_selection, extraArgs=[None]) pos += 0.3 self.cam_load_slots.show() def update_load_selection(self, state, coords): self.selection = state def exit(self): if self.selection: self.player_cam.load_state(name=f'save_{self.selection}', ok_if_not_exists=True) self.remove_task('cam_load_task') self.mouse.touch() self.cam_load_slots.hide() def cam_load_task(self, task): if not self.keymap[action.cam_load]: enter_kwargs = dict( load_prev_cam=True) if self.last_mode == 'aim' else {} self.change_mode(self.last_mode, enter_kwargs=enter_kwargs) return task.cont