def __init__(self, name, bases, dct): if self.name is None: host = p3d.ConfigVariableString('pstats-host', 'localhost').value port = p3d.ConfigVariableInt('pstats-port', 5185).value if not self.client.connect(host, port): if p3d.ConfigVariableBool('pstats-required', False).value: raise ConnectionError(f'failed to connect: {host}:{port}') else: self._trunk.setdefault(self.name, _PStatBranch(self))
def rebuild_menu(self, newitems, heading): self._left_edge = -self.showbase.get_aspect_ratio() + self.edge_inset common_kwargs = { 'parent': self.root, 'text_scale': self.text_scale, 'relief': DGG.FLAT, 'frameSize': [ -0.05, self.button_width - 0.05, -0.05, self.button_height - 0.05 ], } has_heading = bool(heading) if has_heading: self.heading = DirectLabel(pos=(self._left_edge, 0, self.menu_start), text=heading.upper(), text_align=p3d.TextNode.ACenter, text_fg=self.text_active_color, text_pos=(-0.05 + self.button_width / 2, 0), **common_kwargs) for button in self.menu_buttons: button.remove_node() self.menu_buttons = self.build_buttons(newitems, has_heading, common_kwargs) cursor_hidden = p3d.ConfigVariableBool('cursor-hidden') if not cursor_hidden: for idx, button in enumerate(self.menu_buttons): def menu_hover(bid, _event): messenger.send('menu-hover', [bid]) button.bind(DGG.WITHIN, menu_hover, [idx]) def menu_click(_event): messenger.send('menu-click') button.bind(DGG.B1CLICK, menu_click) if newitems: self.update_selection(0)
def replace_texture(self, model, texture, stage=TS_MODULATE, minfilter = FT_MIPMAP, magfilter = FT_LINEAR): '''Replace the texture on a model ''' new_tex=self.loader.load_texture(texture) new_tex.set_minfilter(FT_MIPMAP) new_tex.set_magfilter(FT_LINEAR) if p3d.ConfigVariableBool('framebuffer-srgb').get_value() and stage==TS_MODULATE: tex_format=new_tex.get_format() if tex_format == F_RGB: new_tex.set_format(F_SRGB) elif tex_format == F_RGBA: new_tex.set_format(F_SRGBA) for tex_stage in model.find_all_texture_stages(): if model.find_texture(tex_stage): if tex_stage.get_mode() == stage: model.set_texture(tex_stage, new_tex, 1)
def __init__(self, multisamples=0, srgb_color=False, show_window=False): """Construct a Renderer. Keyword Arguments: multisamples {bool} -- antialiasing multisamples: 0 (disabled), 2, 4, etc. (default: {0}) srgb_color {bool} -- enable sRGB recoloring (default: False) show_window {bool} -- open a window (default: False) """ self._multisamples = multisamples self._srgb_color = srgb_color self._show_window = show_window p3d.ConfigVariableBool('allow-incomplete-render').set_value(False) self._engine = p3d.GraphicsEngine.get_global_ptr() self._pipe = p3d.GraphicsPipeSelection.get_global_ptr( ).make_default_pipe() self._buffer_size = None self._buffer = None self._region = None self._depth_tex = None self._color_tex = None
class EngineAnalysis(object): """ Management object for engine analysis and reporting """ collectors = {} collecting = core.ConfigVariableBool('collect-stats', __debug__).value @classmethod def get_client(cls): """ Retrieves the global pstats client object """ return core.PStatClient.get_global_pstats() @classmethod def get_collecting(cls): """ Retrieves the collecting state """ return cls.collecting @classmethod def set_collecting(cls, state): """ Sets the collecting state """ cls.collecting = state @classmethod def connect(cls, hostname='', port=-1): """ Connects to a PStats Server instance """ if core.PStatClient.is_connected(): return False return core.PStatClient.connect(hostname, port) @classmethod def disconnect(cls, hostname, port): """ Disconnected from a PStats Server instance """ if not core.PStatClient.is_connected(): return False core.PStatClient.disconnect() return True @classmethod def add_collector(cls, collector_name, collector_instance): """ Adds a new collector instance to the collection """ if collector_name in cls.collectors: return False cls.collectors[collector_name] = collector_instance return True @classmethod def get_collector(cls, collector_name): """ Retrieves a collector instance. Otherwise returns a new collector if one does not already exist """ if collector_name in cls.collectors: return cls.collectors[collector_name] else: collector = StatCollector(collector_name) cls.collectors[collector_name] = collector return collector
def __init__(self): super().__init__() # Background Image bgnode.generate(self.root_node, 'arena') bgnode.generate(self.root_node, 'arena', True) # Background Music self.play_bg_music('the_last_encounter') # Arena self.arena = Arena(self.root_node, 10, 10) self.selected_tile = (0, 0) self.move_range_tiles = [] self.ability_range_tiles = [] self.player = base.blackboard['player'] # Player Combatants self.player_combatants = [ Combatant(mon, self.root_node) for mon in self.player.monsters ] random_placement = p3d.ConfigVariableBool( 'mercury-random-combat-placement', True).get_value() possible_positions = [(x, y) for x in range(2) for y in range(self.arena.sizey - 1)] if random_placement: placements = random.sample(possible_positions, len(self.player_combatants)) else: placements = possible_positions for combatant, placement in zip(self.player_combatants, placements): self.move_combatant_to_tile(combatant, placement, True) combatant.set_h(90) self.starting_tile_position = (0, 0) # Enemy Combatants default_combat_type = p3d.ConfigVariableString( 'mercury-default-combat-type', 'skirmish') self.combat_type = base.blackboard.get('combat_type', default_combat_type) if self.combat_type == 'tournament': num_enemies = {1: 3, 2: 5, 3: 8}.get(self.player.rank, 8) else: num_enemies = len(self.player_combatants) self.enemy_combatants = [ Combatant(Monster.gen_random(f'combatant{i}', 1), self.root_node) for i in range(num_enemies) ] possible_positions = [ (x, y) for x in range(self.arena.sizex - 1, self.arena.sizex - 3, -1) for y in range(self.arena.sizey - 1) ] placements = random.sample(possible_positions, len(self.enemy_combatants)) for combatant, placement in zip(self.enemy_combatants, placements): self.move_combatant_to_tile(combatant, placement, True) combatant.set_h(-90) # Setup Lighting arena_world_center = self.arena.tile_coord_to_world(self.arena.center) CommonLighting(self.root_node, arena_world_center) # Setup Camera base.camera.set_pos(-15, -15, 15) lookat_offset = p3d.LVector3(-3, -3, 0) base.camera.look_at( self.arena.tile_coord_to_world(self.arena.center) + lookat_offset) # Setup UI self.load_ui('combat') # Setup AI self.aicontroller = AiController(self.arena, self, self.root_node) # Set initial input state self.input_state = 'END_TURN'
def __init__(self): ShowBase.__init__(self) pman.shim.init(self) base.enable_particles() gdb = gamedb.get_instance() # Render pipeline self.set_background_color((0, 0, 0, 1)) self.render.set_antialias(p3d.AntialiasAttrib.MAuto) self.render_pipeline = simplepbr.init( max_lights=4, msaa_samples=p3d.ConfigVariableInt('msaa-samples', 4).get_value(), enable_shadows=p3d.ConfigVariableBool('enable-shadows', True).get_value(), exposure=5, ) # Controls self.event_mapper = eventmapper.EventMapper() self.disable_mouse() self.accept('quit', sys.exit) self.accept('toggle-buffer-viewer', self.bufferViewer.toggleEnable) self.accept('toggle-oobe', self.oobe) self.accept('save-screenshot', self.screenshot) # Global storage self.blackboard = {} default_save = p3d.ConfigVariableString('mercury-default-save', '').get_value() if default_save: saveloc = os.path.join( pathutils.get_saves_dir(), default_save, ) if not saveloc.endswith('.sav'): saveloc += '.sav' if os.path.exists(saveloc): with open(saveloc) as savefile: self.blackboard['player'] = PlayerData.load(savefile) default_monster_id = p3d.ConfigVariableString( 'mercury-default-monster', '').get_value() if default_monster_id: default_monster = Monster(gdb['monsters'][default_monster_id]) else: default_form = p3d.ConfigVariableString('mercury-default-form', 'mine').get_value() default_monster = Monster.make_new('player_monster', form_id=default_form) if 'player' not in self.blackboard: self.blackboard['player'] = PlayerData() self.blackboard['player'].monsters = [default_monster] # UI default_font = self.loader.load_font('fonts/BalooThambi2-Medium.ttf', pixelsPerUnit=90) p3d.TextNode.set_default_font(default_font) # Game states initial_state = p3d.ConfigVariableString('mercury-initial-state', 'Title').get_value() self.gman = gamestates.StateManager(initial_state) def update_state(task): self.gman.update() return task.cont self.taskMgr.add(update_state, 'GameState Update') # Get volume levels from config self.musicManager.set_volume( p3d.ConfigVariableDouble('audio-music-volume', 1.0).get_value()) self.sfxManagerList[0].set_volume( p3d.ConfigVariableDouble('audio-sfx-volume', 1.0).get_value())
def __init__(self): super().__init__() gdb = gamedb.get_instance() self.player = base.blackboard['player'] self.monster_selection = 0 self.monster_actors = [] self.monsters_root = self.root_node.attach_new_node('monsters') # Setup lighting self.lights_root = self.root_node.attach_new_node('light root') self.lighting = CommonLighting(self.lights_root, calc_shadow_bounds=False) self.lights_root.set_h(45) # Pre-load all monster models forms = gdb['forms'].values() self.load_monster_models(forms) # Load and display the player monster models self.load_monster_models() # Setup plane to catch shadows if p3d.ConfigVariableBool('enable-shadows').get_value(): shadow_catcher = p3d.CardMaker('shadow_catcher').generate() shadow_catcher = self.root_node.attach_new_node(shadow_catcher) shadow_catcher.set_p(-90) shadow_catcher.set_scale(30) shadow_catcher.set_pos(-15, -15, 0) shadow_catcher.flatten_strong() shadow_catcher.set_transparency(p3d.TransparencyAttrib.M_alpha) shadow_catcher.set_shader( p3d.Shader.make(p3d.Shader.SL_GLSL, SHADOW_CATCH_V, SHADOW_CATCH_F)) # Setup backgrounds self.background_textures = { 'base': ( base.loader.load_texture('backgrounds/ranchbg.png'), base.loader.load_texture('backgrounds/ranchfg.png'), ), 'foundry': ( base.loader.load_texture('backgrounds/marketbg.png'), base.loader.load_texture('backgrounds/marketfg.png'), ), } for tex in (i for texs in self.background_textures.values() for i in texs): if tex.get_num_components() == 4: tex.set_format(p3d.Texture.F_srgb_alpha) else: tex.set_format(p3d.Texture.F_srgb) self.background_image = bgnode.generate(self.root_node) self.foreground_image = bgnode.generate(self.root_node, foreground=True) self.foreground_image.set_transparency(p3d.TransparencyAttrib.M_alpha) # Setup Background Music self.play_bg_music('woodland_fantasy') # Setup Camera base.camera.set_pos(0, -5, 6) base.camera.look_at(0, 0, 1) # UI self.message = "" self.message_modal = False self.load_ui('workshop') # Set initial input state if self.player.monsters: self.input_state = 'MAIN' else: self.input_state = 'FOUNDRY'
def __init__(self): super().__init__(self) # MSAA just for making thinkgs look good self.render.set_antialias(p3d.AntialiasAttrib.M_multisample) # ShaderTerrainMesh used for terrain self.terrain_node = p3d.ShaderTerrainMesh() heightfield = self.loader.load_texture( '../../models/texture/terrain/terrain_height.png') self.terrain_node.heightfield = heightfield # self.terrain_node.target_triangle_width = 10.0 self.terrain_node.generate() self.terrain = self.render.attach_new_node(self.terrain_node) self.terrain.set_scale(512, 512, 100) self.terrain.set_pos(-256, -256, -30) self.terrain.set_shader( p3d.Shader.load(GLSL, 'shaders/terrain_v.glsl', 'shaders/terrain_f.glsl'), 1) # load terrain textures grass = self.loader.load_texture( '../../models/texture/terrain/grass_c.png', minfilter=FT_MIPMAP, magfilter=FT_LINEAR) rock = self.loader.load_texture( '../../models/texture/terrain/rock_c.png', minfilter=FT_MIPMAP, magfilter=FT_LINEAR) snow = self.loader.load_texture( '../../models/texture/terrain/snow_c.png', minfilter=FT_MIPMAP, magfilter=FT_LINEAR) attribute = self.loader.load_texture( '../../models/texture/terrain/terrain_atr.png') # make sure textures are sRGB if p3d.ConfigVariableBool('framebuffer-srgb').get_value(): grass.set_format(F_SRGB) rock.set_format(F_SRGB) snow.set_format(F_SRGB) attribute.set_format(F_SRGB) self.terrain.set_shader_input('grass_map', grass) self.terrain.set_shader_input('rock_map', rock) self.terrain.set_shader_input('snow_map', snow) self.terrain.set_shader_input('attribute_map', attribute) self.terrain.set_shader_input('camera', self.camera) # make the grass map more gpu friendly: grass_map = p3d.PNMImage() grass_map.read('../../models/texture/terrain/terrain_grass.png') grass_list = [] x_size = grass_map.get_read_x_size() y_size = grass_map.get_read_y_size() for x in range(x_size): for y in range(y_size): if grass_map.get_bright(x, y) > 0.5: # terrain_node.uv_to_world() will give as the position of the grass # but we need to flip the y because OpenGL UVs... # we also want to add a bit of random to avoid 'grass grid' uv_x = x / x_size uv_y = 1.0 - y / y_size uv_x += random.uniform(-0.001, 0.001) uv_y += random.uniform(-0.001, 0.001) uv_x = max(0.0, min(1.0, uv_x)) uv_y = max(0.0, min(1.0, uv_y)) grass_list.append(self.terrain_node.uv_to_world( uv_x, uv_y)) # pack the grass_list into a buffer_texture grass_buf_tex = p3d.Texture('texbuffer') grass_buf_tex.setup_buffer_texture( len(grass_list) + 1, p3d.Texture.T_float, p3d.Texture.F_rgb32, p3d.GeomEnums.UH_static) image = memoryview(grass_buf_tex.modify_ram_image()) for i, pos in enumerate(grass_list): off = i * 12 image[off:off + 12] = struct.pack('fff', pos[0], pos[1], pos[2]) # load the grass model grass_model = self.loader.load_model('../../models/grass') # fix texture for srgb if p3d.ConfigVariableBool('framebuffer-srgb').get_value(): for tex_stage in grass_model.find_all_texture_stages(): tex = grass_model.find_texture(tex_stage) if tex: tex.set_format(F_SRGBA) grass_model.set_texture(tex_stage, tex, 1) grass_model.set_shader( p3d.Shader.load(GLSL, 'shaders/grass_v.glsl', 'shaders/grass_f.glsl'), 1) grass_model.set_shader_input('grass_buf_tex', grass_buf_tex) grass_model.set_shader_input('clip_distance', 125.0) grass_model.set_instance_count(len(grass_list)) grass_model.reparent_to(self.render) # alpha testing will be done in the shader grass_model.set_transparency(p3d.TransparencyAttrib.M_none, 1) # set the bounds so it stays visible grass_model.node().set_bounds( p3d.BoundingBox((0, 0, 0), max(grass_list, key=itemgetter(1)))) grass_model.node().set_final(1) #make skybox self.sky_box = self.loader.load_model('../../models//box') self.sky_box.reparent_to(self.render) self.sky_box.set_scale(10) self.sky_box.set_shader( p3d.Shader.load(GLSL, 'shaders/skybox_v.glsl', 'shaders/skybox_f.glsl'), 1) self.sky_box.set_shader_input('blur', 0.0) self.sky_box.set_bin('background', 100) self.sky_box.set_depth_test(False) self.sky_box.set_depth_write(False) self.render.set_shader_input("camera", self.cam) self.render.set_shader_input( 'env_map', self.loader.load_texture( '../../models/texture/cubemap/qwantani.txo')) #add a task to update the skybox self.taskMgr.add(self.update, 'update')