def check_interactable_space(self): """Checks to see if any Npc objects around the player are interactable. It then populates a menu of possible actions. :param: None :rtype: Bool :returns: True if there is an Npc to interact with. """ collision_dict = self.player.get_collision_map(self) player_tile_pos = nearest(self.player.tile_pos) collisions = self.player.collision_check(player_tile_pos, collision_dict, self.collision_lines_map) if not collisions: pass else: for direction in collisions: if self.player.facing == direction: if direction == "up": tile = (player_tile_pos[0], player_tile_pos[1] - 1) elif direction == "down": tile = (player_tile_pos[0], player_tile_pos[1] + 1) elif direction == "left": tile = (player_tile_pos[0] - 1, player_tile_pos[1]) elif direction == "right": tile = (player_tile_pos[0] + 1, player_tile_pos[1]) for npc in self.npcs.values(): tile_pos = (int(round(npc.tile_pos[0])), int(round(npc.tile_pos[1]))) if tile_pos == tile: logger.info("Opening interaction menu!") self.client.push_state("InteractionMenu") return True else: continue
def get_collision_map(self): """ Return dictionary for collision testing Returns a dictionary where keys are (x, y) tile tuples and the values are tiles or NPCs. # NOTE: This will not respect map changes to collisions after the map has been loaded! :rtype: dict :returns: A dictionary of collision tiles """ # TODO: overlapping tiles/objects by returning a list collision_dict = dict() # Get all the NPCs' tile positions for npc in self.get_all_entities(): pos = nearest(npc.tile_pos) collision_dict[pos] = {"entity": npc} # tile layout takes precedence collision_dict.update(self.collision_map) return collision_dict
def get_state(self, session): """Prepares a dictionary of the npc to be saved to a file :param tuxemon.core.session.Session session: :rtype: Dictionary :returns: Dictionary containing all the information about the npc """ state = { 'current_map': session.client.get_map_name(), 'facing': self.facing, 'game_variables': self.game_variables, 'inventory': encode_inventory(self.inventory), 'monsters': encode_monsters(self.monsters), 'player_name': self.name, 'monster_boxes': dict(), 'item_boxes': dict(), 'tile_pos': nearest(self.tile_pos), } for key, value in self.monster_boxes.items(): state['monster_boxes'][key] = encode_monsters(value) for key, value in self.item_boxes.items(): state['item_boxes'][key] = encode_inventory(value) return state
def get_state(self, session): """Prepares a dictionary of the npc to be saved to a file :param tuxemon.core.session.Session session: :rtype: Dictionary :returns: Dictionary containing all the information about the npc """ return { 'current_map': session.client.get_map_name(), 'facing': self.facing, 'game_variables': self.game_variables, 'inventory': encode_inventory(self.inventory), 'monsters': encode_monsters(self.monsters), 'player_name': self.name, 'storage': { 'items': encode_inventory(self.storage['items']), 'monsters': encode_monsters(self.storage['monsters']), }, 'tile_pos': nearest(self.tile_pos), }
def map_drawing(self, surface): """Draws the map tiles in a layered order. :param: None :rtype: None :returns: None """ # TODO: move all drawing into a "WorldView" widget # interlace player sprites with tiles surfaces. # eventually, maybe use pygame sprites or something similar world_surfaces = list() # temporary if self.current_map.renderer is None: self.current_map.initialize_renderer() # get player coords to center map cx, cy = nearest(self.project(self.player.tile_pos)) # offset center point for player sprite cx += prepare.TILE_SIZE[0] // 2 cy += prepare.TILE_SIZE[1] // 2 # center the map on center of player sprite # must center map before getting sprite coordinates self.current_map.renderer.center((cx, cy)) # get npc surfaces/sprites for npc in self.npcs: world_surfaces.extend(self.npcs[npc].get_sprites(self.current_map.sprite_layer)) # get map_animations for anim_data in self.map_animations.values(): anim = anim_data['animation'] if not anim.isFinished() and anim.visibility: frame = (anim.getCurrentFrame(), anim_data["position"], anim_data['layer']) world_surfaces.append(frame) # position the surfaces correctly # pyscroll expects surfaces in screen coords, so they are # converted from world to screen coords here screen_surfaces = list() for frame in world_surfaces: s, c, l = frame # project to pixel/screen coords c = self.get_pos_from_tilepos(c) # TODO: better handling of tall sprites # handle tall sprites h = s.get_height() if h > prepare.TILE_SIZE[1]: # offset for center and image height c = nearest((c[0], c[1] - h // 2)) screen_surfaces.append((s, c, l)) # draw the map and sprites self.rect = self.current_map.renderer.draw(surface, surface.get_rect(), screen_surfaces) # If we want to draw the collision map for debug purposes if prepare.CONFIG.collision_map: self.debug_drawing(surface)