def objects_under_mouse(self): """Returns list of entities that mouse is hovering over.""" x = self.handler.mouse.cx y = self.handler.mouse.cy names = [] for stairs in self.handler.map_objects['stairs']: if (stairs.x == x and stairs.y == y and self.handler.world.map[x][y].seen): names.append(stairs.name) # Names of mobs for entity in self.handler.map_objects['mobs']: if (entity.x == x and entity.y == y and libt.map_is_in_fov(self.handler.fov_map, entity.x, entity.y)): if entity.state == data.DEAD: names.append(entity.name) else: names.append("{} [{}/{}]".format(entity.name, entity.hp, entity.max_hp)) # Names of items for item in self.handler.map_objects['items']: if (item.x == x and item.y == y and libt.map_is_in_fov(self.handler.fov_map, item.x, item.y)): names.append(item.name) names = ", ".join(names) return names
def sleeping_gas(x, y, radius, duration): path = util.set_full_explore_map(game.current_map) libtcod.dijkstra_compute(path, x, y) for i in range(-radius, radius + 1): for j in range(-radius, radius + 1): if libtcod.dijkstra_get_distance(path, x + i, y + j) <= radius and libtcod.dijkstra_get_distance(path, x + i, y + j) >= 0: game.current_map.tile[x + i][y + j].update({'icon': game.current_map.tile[x + i][y + j]['icon'], 'back_light_color': libtcod.Color(115, 220, 225), 'back_dark_color': libtcod.Color(0, 143, 189), 'lerp': round(libtcod.random_get_float(game.rnd, 0, 1), 1), 'duration': game.turns + duration, 'type': 'sleep_gas'}) for obj in game.current_map.objects: if obj.item is None: if obj.x == x + i and obj.y == y + j: if obj.name == 'player': game.message.new('You are caught in a sleeping cloud!', game.turns) if 'sleep' not in game.player.flags: dice = util.roll_dice(1, 50) if dice > game.player.wisdom + (game.player.karma / 2): game.message.new('You fall asleep!', game.turns, libtcod.Color(0, 143, 189)) game.player.flags.append('sleep') else: if libtcod.map_is_in_fov(game.fov_map, obj.x, obj.y): game.message.new(obj.entity.article.capitalize() + obj.entity.get_name() + ' is caught in a sleeping cloud!', game.turns) if 'sleep' not in obj.entity.flags: dice = util.roll_dice(1, 3) if dice == 3: if libtcod.map_is_in_fov(game.fov_map, obj.x, obj.y): game.message.new(obj.entity.article.capitalize() + obj.entity.get_name() + ' falls asleep!', game.turns) obj.entity.flags.append('sleep')
def render_all(self, target): if target is not None: global color_light_wall global color_light_ground for y in xrange(self.map.height): for x in xrange(self.map.width): visible = libtcod.map_is_in_fov(self.hero.fov_map, x, y) wall = self.map.tiles[x][y].block_sight if visible: if wall: libtcod.console_set_char_background(target, x, y, color_light_wall, libtcod.BKGND_SET) else: libtcod.console_set_char_background(target, x, y, color_light_ground, libtcod.BKGND_SET) self.map.tiles[x][y].explored = True else: if self.map.tiles[x][y].explored: if wall: libtcod.console_set_char_background(target, x, y, color_dark_wall, libtcod.BKGND_SET) else: libtcod.console_set_char_background(target, x, y, color_dark_ground, libtcod.BKGND_SET ) for o in self.npcs: if libtcod.map_is_in_fov(self.hero.fov_map, o.x, o.y): o.draw(target) self.hero.draw(target) libtcod.console_blit(target, 0, 0, SCREEN_WIDE, SCREEN_HIGH, 0, 0, 0)
def cast_fireball(): global fov_map message('Left-click a target tile for the fireball, or right-click to cancel.', libtcod.light_cyan) (x, y) = target_tile() if x is None: return 'cancelled' message('The fireball explodes, burning everything within ' + str(FIREBALL_RADIUS) + ' tiles!', libtcod.orange) for obj in objects: # damage every fighter in range, including the player if obj.distance(x, y) <= FIREBALL_RADIUS and obj.fighter: if libtcod.map_is_in_fov(fov_map, obj.x, obj.y): if obj == player: msg1, msg2 ='', '' else: msg1, msg2 = 'The ', 's' message(msg1 + obj.name.capitalize() + ' get' + msg2 +' burned for ' + str(FIREBALL_DAMAGE) + ' hit points.', libtcod.orange) else: message('You hear a cry of pain') obj.fighter.take_damage(FIREBALL_DAMAGE) render_all() # display code for num in range(3): for x1 in range(x - num, x + num): for y1 in range(y - num, y + num): if not map[x1][y1].block_sight and libtcod.map_is_in_fov(fov_map, x1, y1): libtcod.console_put_char_ex(0, x1, y1, '*', libtcod.dark_orange, libtcod.red) libtcod.console_flush() time.sleep(0.1) time.sleep(0.25)
def refresh(self): tcod_map = self.game.dungeon.tcod_map if self.entity is self.game.player: libtcod.map_compute_fov(tcod_map, self.entity.x, self.entity.y, PLAYER_FOV_RADIUS) else: libtcod.map_compute_fov(tcod_map, self.entity.x, self.entity.y, self.creature.perception) if self.entity is self.game.player: for x in range(len(self.fov_map)): for y in range(len(self.fov_map[0])): self.fov_map[x][y]=int(libtcod.map_is_in_fov(tcod_map, x,y)) else: self.clear() for x in range(self.entity.x-self.creature.perception, self.entity.x+self.creature.perception+1): for y in range(self.entity.y-self.creature.perception, self.entity.y+self.creature.perception+1): fov_num = int(libtcod.map_is_in_fov(tcod_map,x,y)) if fov_num: if (x-self.entity.x==0 or y-self.entity.y==0 or abs(x-self.entity.x)-abs(y-self.entity.y)==0): fov_num += 1 if util.distance(self.entity.x,self.entity.y,x,y)<=self.creature.perception//3: fov_num += 1 try: self.fov_map[x][y] = fov_num except IndexError: pass
def cast_fireball(Game, user): (x,y) = (None, None) target = None target = closest_nonclan(data.TORCH_RADIUS, Game, user) if user is Game.player: #ask the player for a target tile to throw a fireball at message('Left-click a target tile for the fireball. Right-Click or ESC to cancel', Game, libtcod.light_cyan) (x,y) = target_tile(Game) #otherwise this is a mob elif target: if libtcod.map_is_in_fov(user.fighter.fov, target.x, target.y) and target.dungeon_level == user.dungeon_level: (x,y) = (target.x, target.y) if x is None or y is None: if user is Game.player: message('Cancelling fireball', Game, libtcod.red) else: message(user.name + ' cancels Fireball', Game, libtcod.red, False) return data.STATE_CANCELLED else: theDmg = roll_dice([[data.FIREBALL_DAMAGE/2, data.FIREBALL_DAMAGE*2]])[0] #create fireball fov based on x,y coords of target fov_map_fireball = Game.map[Game.dungeon_levelname].fov_map libtcod.map_compute_fov(fov_map_fireball, x, y, data.FIREBALL_RADIUS, data.FOV_LIGHT_WALLS, data.FOV_ALGO) for obj in Game.objects[Game.dungeon_levelname]: #damage all fighters within range if libtcod.map_is_in_fov(fov_map_fireball, obj.x, obj.y) and obj.fighter: message('The fireball explodes', Game, libtcod.orange) message(obj.name + ' is burned for '+ str(theDmg) + ' HP', Game, libtcod.orange) obj.fighter.take_damage(user, theDmg, Game)
def draw_map_panel(): global fov_recompute if fov_recompute: # recompute FOV if needed (the player moved or something) fov_recompute = False libtcod.map_compute_fov(fov_map, player.x, player.y, TORCH_RADIUS, FOV_LIGHT_WALLS, FOV_ALGO) for y in xrange(MAP_HEIGHT): for x in xrange(MAP_WIDTH): visible = libtcod.map_is_in_fov(fov_map, x, y) wall = tile_map[x][y].block_sight if not visible: if tile_map[x][y].explored: if wall: libtcod.console_set_char_background(con, x, y, color_dark_wall, libtcod.BKGND_SET) else: libtcod.console_set_char_background(con, x, y, color_dark_ground, libtcod.BKGND_SET) else: if wall: libtcod.console_set_char_background(con, x, y, color_lit_wall, libtcod.BKGND_SET) else: libtcod.console_set_char_background(con, x, y, color_lit_ground, libtcod.BKGND_SET) tile_map[x][y].explored = True for object in objects: visible = libtcod.map_is_in_fov(fov_map, object.x, object.y) if (visible or (object.always_visible and tile_map[object.x][object.y].explored)) \ and object is not player: object.draw() player.draw()
def is_visible(self): if libtcod.map_is_in_fov(data.fov_map, self.x, self.y): #If it is, check that it's lit. for object in data.current_area.objects: if object.light_map: if libtcod.map_is_in_fov(object.light_map, self.x, self.y): return True return False
def render_local(): global map_, fov_recompute if len(R.map_) > R.MAP_VIEW_WIDTH: cam_x = scrolling_map(you.x, R.MAP_VIEW_WIDTH_HALF + 1, R.MAP_VIEW_WIDTH, R.MAP_WIDTH) else: cam_x = 0 if len(R.map_[0]) > R.MAP_VIEW_HEIGHT: cam_y = scrolling_map(you.y, R.MAP_VIEW_HEIGHT_HALF, R.MAP_VIEW_HEIGHT, R.MAP_HEIGHT) else: cam_y = 0 # cam_x = scrolling_map(you.x, R.MAP_VIEW_WIDTH / 2, R.MAP_VIEW_WIDTH, R.MAP_WIDTH) # cam_y = scrolling_map(you.y, R.MAP_VIEW_HEIGHT / 2, R.MAP_VIEW_HEIGHT, R.MAP_HEIGHT) if fov_recompute: fov_recompute = False libtcod.map_compute_fov(R.locale.floors[you.depth].fov_map, you.x, you.y, 10, True, 0) for sc_y in range(R.MAP_VIEW_HEIGHT): #this refers to the SCREEN position. NOT map. for sc_x in range(R.MAP_VIEW_WIDTH): x = sc_x + cam_x y = sc_y + cam_y if sc_x < len(R.map_) and sc_y < len(R.map_[0]): # and x < len(R.map_) and y < len(R.map_[0]): #if it's within the bounds of the map. tile = R.locale.floors[you.depth].tiles[x][y] visible = libtcod.map_is_in_fov(R.locale.floors[you.depth].fov_map, x, y) if not visible: if tile.explored or debug_mode: libtcod.console_put_char_ex(con, x, y, tile.char, libtcod.dark_green, libtcod.dark_gray) else: libtcod.console_put_char_ex(con, x, y, " ", libtcod.black, libtcod.black) libtcod.console_set_char(con_char, x, y, " ") else: libtcod.console_put_char_ex(con, x, y, tile.char, libtcod.green, libtcod.light_grey) libtcod.console_set_char(con_char, x, y, " ") tile.explored = True else: libtcod.console_put_char_ex(con, x, y, " ", libtcod.black, libtcod.black) for objects in R.locale_obj: #if the tile is explored, then draw the object. if libtcod.map_is_in_fov(R.locale.floors[you.depth].fov_map, objects.x, objects.y): objects.draw(cam_x, cam_y) #if it's explored but out of sight range - draw faded! elif R.locale.floors[you.depth].tiles[objects.x][objects.y].explored == True: objects.draw_faded(cam_x, cam_y) you.draw(cam_x, cam_y) libtcod.console_blit(con, 0, 0, R.MAP_VIEW_WIDTH, R.MAP_VIEW_HEIGHT, 0, 0, 0) libtcod.console_blit(con_char, 0, 0, R.MAP_VIEW_WIDTH, R.MAP_VIEW_HEIGHT, 0, 0, 0, 1.0, 0.0) libtcod.console_blit(inf, 0, 0, R.INFO_BAR_WIDTH, R.SCREEN_HEIGHT, 0, R.MAP_VIEW_WIDTH, 0) libtcod.console_flush()
def draw(self): for n in config.nodes: if libtcod.map_is_in_fov(n.node.fov_map, self.x, self.y): libtcod.console_set_default_foreground(gfx.con, self.color) libtcod.console_put_char(gfx.con, self.x, self.y, self.char, libtcod.BKGND_NONE) if libtcod.map_is_in_fov(config.fov_map, self.x, self.y): #set the color and then draw the character that represents this object at its position libtcod.console_set_default_foreground(gfx.con, self.color) libtcod.console_put_char(gfx.con, self.x, self.y, self.char, libtcod.BKGND_NONE)
def take_turn(self): monster = self.owner if libtcod.map_is_in_fov(fov_map, monster.x, monster.y): if monster.distance_to(player) > 1: monster.move_towards(player) else: monster.character.attack(player) if libtcod.map_is_in_fov(fov_map, monster.x, monster.y): if monster.distance_to(player) > 1: monster.move_towards(player) else: monster.character.attack(player)
def take_damage(self, x, y, damage, source, show=False): self.health -= damage if libtcod.map_is_in_fov(game.fov_map, x, y): game.hp_anim.append({'x': x, 'y': y, 'damage': str(-damage), 'color': libtcod.light_yellow, 'turns': 0, 'icon': self.icon, 'icon_color': libtcod.red}) if source == 'player': if "sleep" in self.flags: if libtcod.map_is_in_fov(game.fov_map, x, y): game.message.new('The ' + self.get_name() + 'woke up.', game.turns) self.flags.remove('sleep') if show: if libtcod.map_is_in_fov(game.fov_map, x, y): game.message.new(self.article.capitalize() + self.get_name() + ' is hit by ' + source + ' for ' + str(damage) + ' pts of damage!', game.turns) elif not self.is_dead(): game.message.new('You hear a scream.', game.turns)
def target_tile(max_range=None): # return the position of a tile left-clicked in player's FOV (optionally # in a range), or (None,None) if right-clicked. message("Use the mouse or the keyboard to select a tile...", tcod.blue) prevcolor = tcod.black mouse_lastx, mouse_lasty = (x, y) = render.prev_mouse_pos while True: # render the screen. this erases the inventory and shows the names of # objects under the mouse. render.render_all() tcod.console_flush() tcod.console_set_char_background( render.con, x, y, prevcolor, tcod.BKGND_SET ) # set last tile's bg color to normal tcod.sys_check_for_event(tcod.EVENT_MOUSE | tcod.EVENT_KEY_PRESS, key, mouse) if mouse.dx or mouse.dy: (mouse_lastx, mouse_lasty) = (x, y) = (mouse.cx, mouse.cy) x = mouse.cx y = mouse.cy x = x + render.camera_x y = y + render.camera_y key_pressed = game.get_key(key) if key_pressed in direction_keys: direction = direction_keys[key_pressed] x += direction[0] y += direction[1] if tcod.map_is_in_fov(terrain.map.fov_map, x, y): prevcolor = tcod.console_get_char_background(render.con, x, y) # for resetting the color later tcod.console_set_char_background(render.con, x, y, tcod.sky, tcod.BKGND_SET) # visualising the target tile else: x, y = game.player.x, game.player.y # if not in fov, reset it to the player coords if mouse.rbutton_pressed or key.vk == tcod.KEY_ESCAPE: tcod.console_set_char_background(render.con, x, y, prevcolor, tcod.BKGND_SET) return (None, None) # cancel if the player right-clicked or pressed Escape # accept the target if the player clicked in FOV, and in case a range # is specified, if it's in that range if ( (mouse.lbutton_pressed or key.vk == tcod.KEY_ENTER) and tcod.map_is_in_fov(terrain.map.fov_map, x, y) and (max_range is None or game.player.distance(x, y) <= max_range) ): tcod.console_set_char_background(render.con, x, y, prevcolor, tcod.BKGND_SET) return (x, y)
def render_all(): """ Renders everything on screen. """ # Set globals. global fov_recompute # Clear root console. roguelib.console_clear(0) # Display mouse location if in FOV. mouse, key = check_for_key_events() if roguelib.map_is_in_fov(fov_map, mouse.cx, mouse.cy): roguelib.console_put_char_ex(0, mouse.cx, mouse.cy, " ", None, eval(SETTING_DATA[b"Mouse Highlight"][b"COLOR"])) # Display objects. for obj in objects: visible = roguelib.map_is_in_fov(fov_map, obj.x, obj.y) # Out of FOV. if not visible: if obj.explored: roguelib.console_set_default_foreground(0, obj.color[1]) roguelib.console_put_char(0, obj.x, obj.y, obj.image, roguelib.BKGND_NONE) # In FOV. else: roguelib.console_set_default_foreground(0, obj.color[0]) roguelib.console_put_char(0, obj.x, obj.y, obj.image, roguelib.BKGND_NONE) obj.explored = True # Recompute FOV if fov_recompute is True. if fov_recompute: fov_recompute = False roguelib.map_compute_fov(fov_map, player.x, player.y, TORCH_RADIUS, FOV_LIGHT_WALLS, FOV_ALGO) # Display player. roguelib.console_set_default_foreground(0, roguelib.white) roguelib.console_put_char(0, player.x, player.y, player.image, roguelib.BKGND_NONE) # Render the gui. render_gui() # Flush the root console. roguelib.console_flush()
def draw(self, camera, map, distance): if libtcod.map_is_in_fov(map.fov_map,self.x,self.y): self.explored = True if self.explored: super(Tile, self).draw(camera, map, distance) if self.actor != None: if libtcod.map_is_in_fov(map.fov_map, self.actor.x, self.actor.y): self.actor.draw(camera, map, distance) return elif self.item != None: self.item.draw(camera, map, distance) return elif self.prop != None: self.prop.draw(camera, map, distance) return
def check_active_effects(): for y in range(game.current_map.map_height): for x in range(game.current_map.map_width): if 'duration' in game.current_map.tile[x][y]: if game.current_map.tile[x][y]['duration'] < game.turns: explored = game.current_map.tile_is_explored(x, y) game.current_map.set_tile_values(game.current_map.tile[x][y]['name'], x, y) if game.current_map.tile_is_invisible(x, y): game.current_map.tile[x][y].pop('invisible', None) if explored: game.current_map.tile[x][y].update({'explored': True}) for obj in game.current_map.objects: if obj.name == 'player': if 'type' in game.current_map.tile[game.char.x][game.char.y]: if game.current_map.tile[game.char.x][game.char.y]['type'] == 'poison_gas': game.message.new('You step into poisonous gas!', game.turns) if 'poison' not in game.player.flags: dice = util.roll_dice(1, 50) if dice > game.player.endurance + (game.player.karma / 2): game.message.new('You are poisoned!', game.turns, libtcod.Color(0, 112, 0)) game.player.flags.append('poison') if game.current_map.tile[game.char.x][game.char.y]['type'] == 'sleep_gas': if 'sleep' not in game.player.flags: game.message.new('You step into sleeping gas!', game.turns) dice = util.roll_dice(1, 50) if dice > game.player.wisdom + (game.player.karma / 2): game.message.new('You fall asleep!', game.turns, libtcod.Color(0, 143, 189)) game.player.flags.append('sleep') elif obj.entity: if 'type' in game.current_map.tile[obj.x][obj.y]: if game.current_map.tile[obj.x][obj.y]['type'] == 'poison_gas': if libtcod.map_is_in_fov(game.fov_map, obj.x, obj.y): game.message.new(obj.entity.article.capitalize() + obj.entity.get_name() + ' step into poisonous gas!', game.turns) if 'poison' not in obj.entity.flags: dice = util.roll_dice(1, 3) if dice == 3: obj.entity.flags.append('poison') if game.current_map.tile[obj.x][obj.y]['type'] == 'sleep_gas': if 'sleep' not in obj.entity.flags: if libtcod.map_is_in_fov(game.fov_map, obj.x, obj.y): game.message.new(obj.entity.article.capitalize() + obj.entity.get_name() + ' step into sleeping gas!', game.turns) dice = util.roll_dice(1, 3) if dice == 3: if libtcod.map_is_in_fov(game.fov_map, obj.x, obj.y): game.message.new(obj.entity.article.capitalize() + obj.entity.get_name() + ' falls asleep!', game.turns) obj.entity.flags.append('sleep')
def draw(self): #only show if it's visible to the player; or it's set to "always visible" and on an explored tile if (libtcod.map_is_in_fov(fov_map, self.x, self.y) or (self.always_visible and map[self.x][self.y].explored)): #set the color and then draw the character that represents this object at its position libtcod.console_set_default_foreground(con, self.color) libtcod.console_put_char(con, self.x, self.y, self.char, libtcod.BKGND_NONE)
def can_see(self, x, y, z): e = self.owner # Break out early if we are not on the same level if not e.z == z: return False lbt.map_compute_fov(self.fov_map, e.x, e.y, 10) return lbt.map_is_in_fov(self.fov_map, x, y)
def render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, mouse, colors, game_state): # Draw all the tiles in the game map if fov_recompute: for y in range(game_map.height): for x in range(game_map.width): visible = libtcod.map_is_in_fov(fov_map, x, y) wall = game_map.tiles[x][y].block_sight if visible: if wall: libtcod.console_set_char_background(con, x, y, colors.get('light_wall'), libtcod.BKGND_SET) else: libtcod.console_set_char_background(con, x, y, colors.get('light_ground'), libtcod.BKGND_SET) game_map.tiles[x][y].explored = True elif game_map.tiles[x][y].explored: if wall: libtcod.console_set_char_background(con, x, y, colors.get('dark_wall'), libtcod.BKGND_SET) else: libtcod.console_set_char_background(con, x, y, colors.get('dark_ground'), libtcod.BKGND_SET) entities_in_render_order = sorted(entities, key=lambda x: x.render_order.value) # Draw all entities in the list for entity in entities_in_render_order: draw_entity(con, entity, fov_map, game_map) libtcod.console_blit(con, 0, 0, screen_width, screen_height, 0, 0, 0) libtcod.console_set_default_background(panel, libtcod.black) libtcod.console_clear(panel) #Print the game messages, one line at a time y = 1 for message in message_log.messages: libtcod.console_set_default_foreground(panel, message.color) libtcod.console_print_ex(panel, message_log.x, y, libtcod.BKGND_NONE, libtcod.LEFT, message.text) y += 1 render_bar(panel, 1, 1, bar_width, 'HP', player.fighter.hp, player.fighter.max_hp, libtcod.light_red, libtcod.darker_red) libtcod.console_print_ex(panel, 1, 3, libtcod.BKGND_NONE, libtcod.LEFT, 'Dungeon level: {0}'.format(game_map.dungeon_level)) libtcod.console_set_default_foreground(panel, libtcod.light_gray) libtcod.console_print_ex(panel, 1, 0, libtcod.BKGND_NONE, libtcod.LEFT, get_names_under_mouse(mouse, entities, fov_map)) libtcod.console_blit(panel, 0, 0, screen_width, panel_height, 0, 0, panel_y) if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY): if game_state == GameStates.SHOW_INVENTORY: inventory_title = 'Press the key next to the item to use it, or Esc to cancel.\n' else: inventory_title = 'Press the key next to an item to drop it, or Esc to cancel.\n' inventory_menu(con, inventory_title, player.inventory, 50, screen_width, screen_height) elif game_state == GameStates.LEVEL_UP: level_up_menu(con, 'Level up! Choose a stat to raise:', player, 40, screen_width, screen_height) elif game_state == GameStates.CHARACTER_SCREEN: character_screen(player, 30, 10, screen_width, screen_height)
def draw(self): #only show if visible to the player if (libtcod.map_is_in_fov(fov_map, self.x, self.y) or (self.always_visible and map[self.x][self.y].explored) or self.name=='room number'): #set the color and then draw the character that represents this object at its position libtcod.console_set_default_foreground(con, self.color) libtcod.console_put_char(con, self.x, self.y, self.char, libtcod.BKGND_NONE)
def take_turn(self): monster = self.owner #simple reciprocal fov by mooching off player's fov_map can_see_player = libtcod.map_is_in_fov(fov_map, monster.x, monster.y) #reset chase timer if monster can see the player if can_see_player: #alert nearby monsters if monster wasn't already alert if self.turns_to_chase_player == 0: message("The " + self.owner.name + " shouts!", libtcod.red) for object in objects: if object != monster and object.distance(monster.x, monster.y) <= SHOUT_RADIUS and object.ai: object.ai.turns_to_chase_player = TURNS_MONSTERS_CHASE_PLAYER_AFTER_LOSING_CONTACT self.turns_to_chase_player = TURNS_MONSTERS_CHASE_PLAYER_AFTER_LOSING_CONTACT #chase the player if the chase timer is nonzero (and decrement timer too) if self.turns_to_chase_player > 0: self.turns_to_chase_player -= 1 #close on distant player if monster.distance_to(player) >= 2: if monster.fighter.ranged and can_see_player: monster.fighter.shoot(player) else: monster.move_astar(player) #kill adjacent, alive player elif player.fighter.hp > 0: monster.fighter.attack(player)
def spawn_monster(self,param=None,add_param=None): ##============================================================================ ##use the console to spawn a monster at the closest node node_distance = 100#set the distance really high so we can get the closest node ##thats also in the fov, incase we have 2 or more nodes in fov for node in self.game.Map.spawn_nodes: if libtcod.map_is_in_fov(self.game.fov_map,node.node.x,node.node.y): distance = self.game.player.distance_to(node.node) if distance < node_distance: node_distance = distance closest_node = node if not param and not add_param:#random mob self.game.objects.append(self.game.build_objects.create_monster(self.game, closest_node.node.x,closest_node.node.y)) if param and not add_param:#specific mob param = param.lower() param = param.replace('-',' ') self.game.objects.append(self.game.build_objects.create_monster(self.game, closest_node.node.x,closest_node.node.y,mob_name=param)) #if param and add_param:#for mob sub-types (not implemented yet) for object in self.game.objects: object.message = self.game.message object.objects = self.game.objects
def take_turn(self): monster = self.owner if libtcod.map_is_in_fov(fov_map, monster.x, monster.y): if monster.distance_to(player) >= 2: monster.move_towards(player.x, player.y) elif player.fighter.hp > 0: monster.fighter.attack(player)
def turn_passed(): # called when a turn has passed, runs the AI for non-player entitites for object in Objects: if object.ai is not None: if libtcod.map_is_in_fov(fov_map, object.xcoord, object.ycoord): object.ai.move() else: object.ai.patrol()
def recalculate(self, level_, initial_location): """ Set this fov to the squares seen from initial_location on level_. level_ - The level on which the field of view is being calculated. initial_location - the viewpoint from which the field of view is being calculated. """ dimensions = level_.dimensions map = level_.sight_map tcod.map_compute_fov(map, initial_location[0], initial_location[1], FOV_RADIUS, True, tcod.FOV_SHADOW) border = set() fov_set = set() dude_set = set() for i in range(initial_location[0] - FOV_RADIUS, initial_location[0] + FOV_RADIUS + 1): for j in range(initial_location[1] - FOV_RADIUS, initial_location[1] + FOV_RADIUS + 1): if tcod.map_is_in_fov(map, i, j): fov_set.add((i, j)) if (i, j) != initial_location and (i, j) in level_.dudeLayer: dude_set.add(level_.dudeLayer[(i, j)]) self.__the_field = fov_set self.dudes = frozenset(dude_set)
def render(): # renders everything to the screen global fov_map, fov_recompute if fov_recompute: #recomputes FOV if needed (player move, etc) fov_recompute = False libtcod.map_compute_fov(fov_map, player.xcoord, player.ycoord, CONFIG.TORCH_RADIUS, CONFIG.FOV_LIGHT_WALLS, CONFIG.FOV_ALGO) # redraws the screen pygame.display.flip() color = BLACK screen.fill(color) # draws objects to the screen for object in Objects: object.draw() for monster in Monsters: if libtcod.map_is_in_fov(fov_map, monster.xcoord, monster.ycoord): monster.draw() player.draw() GUIrender()
def draw(self): if game.fov_recompute: # recompute FOV if needed (the player moved or something) game.fov_recompute = False # yuck, shouldn't need to reference libtcod.map_compute_fov(self.fov_map, self.protagonist.coords[0], self.protagonist.coords[1], C.TORCH_RADIUS, C.FOV_LIGHT_WALLS, C.FOV_ALGORITHM) # go through all tiles, and set their background color according to the FOV for y in range(self.height): for x in range(self.width): visible = libtcod.map_is_in_fov(self.fov_map, x, y) if not C.DEBUG else True wall = self.map[x][y].block_sight if not visible: # if it's not visible right now, the player can only see it if it's explored if self.map[x][y].explored: if wall: libtcod.console_set_char_background(self.console, x, y, C.COLOR_DARK_WALL, libtcod.BKGND_SET) # libtcod.console_put_char_ex(self.console, x, y, 2242, C.COLOR_DARK_WALL, C.COLOR_BACKGROUND) else: libtcod.console_set_char_background(self.console, x, y, C.COLOR_DARK_GROUND, libtcod.BKGND_SET) # libtcod.console_put_char_ex(self.console, x, y, 2242, C.COLOR_DARK_GROUND, C.COLOR_BACKGROUND) else: # it's visible if wall: libtcod.console_set_char_background(self.console, x, y, C.COLOR_LIGHT_WALL, libtcod.BKGND_SET) # libtcod.console_put_char_ex(self.console, x, y, 2242, C.COLOR_LIGHT_WALL, C.COLOR_BACKGROUND) else: libtcod.console_set_char_background(self.console, x, y, C.COLOR_LIGHT_GROUND, libtcod.BKGND_SET) # libtcod.console_put_char_ex(self.console, x, y, 2242, C.COLOR_LIGHT_GROUND, C.COLOR_BACKGROUND) # since it's visible, explore it self.map[x][y].explored = True
def in_fov(x, y): """ Check if given coordinates is within the fov. """ global player global fov_map return True if libtcod.map_is_in_fov(fov_map, x, y) else False
def _draw_fov_using_terrain(player): """ Overly optimized: this code inlines Map.terrain_at(), Map.is_explored(), and ScreenCoords.toWorldCoords() in order to get a 2.5x speedup on large maps. """ libtcod.console_clear(_con) current_map = player.current_map pos = algebra.Location(0, 0) for screen_y in range(min(current_map.height, config.MAP_PANEL_HEIGHT)): pos.set(player.camera_position.x, player.camera_position.y + screen_y) for screen_x in range(min(current_map.width, config.MAP_PANEL_WIDTH)): # pos = ScreenCoords.toWorldCoords(player.camera_position, (screen_x, screen_y)) visible = libtcod.map_is_in_fov(current_map.fov_map, pos.x, pos.y) # terrain = current_map.terrain_at(pos) terrain = map.terrain_types[current_map.terrain[pos.x][pos.y]] if not visible: # if current_map.is_explored(pos): if current_map._explored[pos.x][pos.y]: libtcod.console_set_char_background(_con, screen_x, screen_y, terrain.unseen_color, libtcod.BKGND_SET) else: libtcod.console_set_char_background(_con, screen_x, screen_y, terrain.seen_color, libtcod.BKGND_SET) current_map.explore(pos) pos.x += 1
def take_turn(self,game): self.owner.fighter.ticker.schedule_turn(self.owner.fighter.speed,self.owner) if self.dest and self.owner.distance(self.dest_x,self.dest_y) <= 0: self.dest = False if self.dest and self.owner.distance(self.dest_x,self.dest_y) > 0: self.owner.move_towards(self.dest_x,self.dest_y,game.Map.map,game.objects) if not self.dest: picked = False while not picked: min_x,max_x = self.home_x-self.radius,self.home_x+self.radius min_y,max_y = self.home_y-self.radius,self.home_y+self.radius mx,my = game.Map.MAP_WIDTH,game.Map.MAP_HEIGHT #make sure min and max values are within the boundaries of the map if not min_x <=0 or not min_y <=0 or not max_x >= my or not max_y >= mx: self.dest_x=libtcod.random_get_int(0,min_x+1,max_x-1) self.dest_y=libtcod.random_get_int(0,min_y+1,max_y-1) if not game.Map.map[self.dest_x][self.dest_y].blocked and not self.owner.distance(self.dest_x,self.dest_y) == 0: picked = True self.owner.move_towards(self.dest_x,self.dest_y,game.Map.map,game.objects) if libtcod.map_is_in_fov(game.fov_map, self.owner.x, self.owner.y): self.owner.ai = BasicMonster() self.owner.ai.owner = self.owner
def check_for_stateswap(self): monster = self.owner if not libtcod.map_is_in_fov(self.gldir.fov_map, monster.x, monster.y): self.pass_into(SimpleSearch)
def play_game(player, entities, game_map, message_log, game_state, con, panel, animation_console, constants): fov_recompute = True fov_map = initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN previous_game_state = game_state camera = Camera( x=0, y=0, width=constants['screen_width'], height=constants['screen_height'], map_width=constants['map_width'], map_height=constants['map_height'], ) camera.update(player) targeting_item = None weapon_target = None while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) x_in_camera, y_in_camera = camera.apply(player.x, player.y) if fov_recompute: recompute_fov(fov_map, player.x, player.y, constants['fov_radius'], constants['fov_light_walls'], constants['fov_algorithm']) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], constants['bar_width'], constants['panel_height'], constants['panel_y'], mouse, constants['colors'], game_state, camera) fov_recompute = False libtcod.console_flush() clear_all(con, entities, camera) action = handle_keys(key, game_state) mouse_action = handle_mouse(mouse) move = action.get('move') wait = action.get('wait') pickup = action.get('pickup') show_inventory = action.get('show_inventory') drop_inventory = action.get('drop_inventory') inventory_index = action.get('inventory_index') take_stairs = action.get('take_stairs') level_up = action.get('level_up') show_character_screen = action.get('show_character_screen') targeter = action.get('targeter') fire = action.get('fire') exit = action.get('exit') fullscreen = action.get('fullscreen') left_click = mouse_action.get('left_click') right_click = mouse_action.get('right_click') player_turn_results = [] if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) camera.update(player) fov_recompute = True for entity in entities: if entity != player and entity.x == player.x and entity.y == player.y: see_results = [{ 'message': Message('{0}(이)가 보인다.'.format(entity.name), libtcod.white) }] player_turn_results.extend(see_results) game_state = GameStates.ENEMY_TURN elif wait: game_state = GameStates.ENEMY_TURN elif pickup and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.item and entity.x == player.x and entity.y == player.y: pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message( Message('여기에는 주울 수 있는 것이 없다.', libtcod.yellow)) if targeter: previous_game_state = GameStates.PLAYERS_TURN testfunc() game_state = GameStates.WEAPON_TARGETING if show_inventory: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY if drop_inventory: previous_game_state = game_state game_state = GameStates.DROP_INVENTORY if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len( player.inventory.items): item = player.inventory.items[inventory_index] if game_state == GameStates.SHOW_INVENTORY: player_turn_results.extend( player.inventory.use(item, entities=entities, fov_map=fov_map)) elif game_state == GameStates.DROP_INVENTORY: player_turn_results.extend(player.inventory.drop_item(item)) if take_stairs and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.stairs and entity.x == player.x and entity.y == player.y: entities = game_map.next_floor(player, message_log, constants) fov_map = initialize_fov(game_map) fov_recompute = True camera.update(player) libtcod.console_clear(con) break else: message_log.add_message(Message('여기에는 계단이 없다.', libtcod.yellow)) if level_up: if level_up == 'hp': player.fighter.base_max_hp += 20 player.fighter.hp += 20 elif level_up == 'str': player.fighter.base_power += 1 elif level_up == 'def': player.fighter.base_ += 1 game_state = previous_game_state if show_character_screen: previous_game_state = game_state game_state = GameStates.CHARACTER_SCREEN if game_state == GameStates.CHARACTER_SCREEN: x, y = get_mouse_movement(mouse) get_player_tooltip(animation_console, x, y, mouse, constants['screen_width'], constants['screen_height']) if left_click: game_state = previous_game_state if game_state == GameStates.WEAPON_TARGETING: wx, wy = get_mouse_movement(mouse) get_targeting_radius( con, panel, wx, wy, entities, player, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], constants['bar_width'], constants['panel_height'], constants['panel_y'], mouse, constants['colors'], game_state, camera, left_click, right_click, animation_console) if left_click: weapon_target_x, weapon_target_y = left_click weapon_target_x -= camera.x weapon_target_y -= camera.y if not libtcod.map_is_in_fov(fov_map, weapon_target_x, weapon_target_y): message_log.add_message(Message('시야 밖의 적을 목표로 지정할 수는 없다.')) for entity in entities: if entity.distance( weapon_target_x, weapon_target_y) == 0 and entity.name == 'Player': message_log.add_message( Message('자기 자신을 목표로 지정할 수는 없다.')) elif entity.distance( weapon_target_x, weapon_target_y) == 0 and entity.fighter: player_turn_results.append({'wep_targetted': True}) weapon_target = entity elif right_click: player_turn_results.append({'targeting_cancelled': True}) if fire: #수동으로 타겟을 잡았거나, 자동 발사로 타겟이 잡혔을 때 #원거리 무기 미장비시 if not player.equipment.main_hand: message_log.add_message(Message('발사할 수 있는 것을 장비하고 있지 않다.')) #원거리 무기 장비시 elif player.equipment.main_hand.equippable.ranged_weapon == True: #타겟이 지정되었을 때 if weapon_target is not None: print(weapon_target) message_log.add_message( Message('당신은 {0}을(를) 발사한다! '.format( player.equipment.main_hand.name))) attack_results = player.fighter.attack(weapon_target) player_turn_results.extend(attack_results) if weapon_target.fighter.hp <= 0: weapon_target = None game_state = GameStates.ENEMY_TURN #타겟이 지정되지 않았을 때 자동 발사 else: closest_distance = 10 + 1 for entity in entities: if entity.fighter and libtcod.map_is_in_fov( fov_map, entity.x, entity.y ) and entity.name != 'Player' and entity.blocks == True: distance = player.distance_to(entity) if distance < closest_distance: weapon_target = entity closest_distance = distance #자동 발사 대상 지정 후 발사, 타겟 지정 if weapon_target: message_log.add_message( Message('당신은 {0}을(를) 발사한다! '.format( player.equipment.main_hand.name))) attack_results = player.fighter.attack(weapon_target) player_turn_results.extend(attack_results) if weapon_target.fighter.hp <= 0: weapon_target = None game_state = GameStates.ENEMY_TURN #타겟이 지정되지 않았고 적이 Fov 외에 있을 때 else: message_log.add_message( Message('사격할 수 있는 대상이 보이지 않는다.')) weapon_target = None game_state = GameStates.ENEMY_TURN else: message_log.add_message(Message('발사할 수 있는 것을 장비하고 있지 않다.')) if game_state == GameStates.TARGETING: x, y = get_mouse_movement(mouse) get_targeting_radius( con, panel, x, y, entities, player, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], constants['bar_width'], constants['panel_height'], constants['panel_y'], mouse, constants['colors'], game_state, camera, left_click, right_click, animation_console) if left_click: target_x, target_y = left_click target_x -= camera.x target_y -= camera.y item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map, target_x=target_x, target_y=target_y) player_turn_results.extend(item_use_results) elif right_click: player_turn_results.append({'targeting_cancelled': True}) if exit: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY, GameStates.CHARACTER_SCREEN): game_state = previous_game_state elif game_state == GameStates.LEVEL_UP: level_up_menu(con, 'Level up! Choose a stat to raise:', player, 40, constants['screen_width'], constants['screen_height']) elif game_state == GameStates.CHARACTER_SCREEN: character_screen(player, 30, 10, constants['screen_width'], constants['screen_height']) elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) else: save_game(player, entities, game_map, message_log, game_state) return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') item_added = player_turn_result.get('item_added') item_consumed = player_turn_result.get('consumed') item_dropped = player_turn_result.get('item_dropped') equip = player_turn_result.get('equip') targeting = player_turn_result.get('targeting') targeting_cancelled = player_turn_result.get('targeting_cancelled') wep_targetted = player_turn_result.get('wep_targetted') xp = player_turn_result.get('xp') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: victim_cord_x, victim_cord_y = get_victim_cord(dead_entity) explosion(con, panel, victim_cord_x, victim_cord_y, entities, player, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], mouse, constants['colors'], camera, animation_console) blood_splatter(con, game_map, victim_cord_x, victim_cord_y, constants['colors']) libtcod.console_clear(con) fov_recompute = True message = kill_monster(dead_entity) pass message_log.add_message(message) if item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if item_consumed: game_state = GameStates.ENEMY_TURN if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN if equip: equip_results = player.equipment.toggle_equip(equip) for equip_result in equip_results: equipped = equip_result.get('equipped') dequipped = equip_result.get('dequipped') if equipped: message_log.add_message( Message('{0}(을)를 장비했다.'.format(equipped.name))) if dequipped: message_log.add_message( Message('{0}(을)를 해제했다.'.format(dequipped.name))) game_state = GameStates.ENEMY_TURN if wep_targetted: game_state = previous_game_state message_log.add_message(Message('당신은 목표를 조준한다.')) if targeting: previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message(targeting_item.item.targeting_message) if targeting_cancelled: game_state = previous_game_state message_log.add_message(Message('목표 지정을 취소하였다.')) if xp: leveled_up = player.level.add_xp(xp) message_log.add_message( Message('당신은 {0}의 경험치를 얻었다..'.format(xp))) if leveled_up: message_log.add_message( Message( '레벨 {0}에 도달하였다!'.format(player.level.current_level) + '!', libtcod.yellow)) previous_game_state = game_state game_state = GameStates.LEVEL_UP if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities) for enemy_turn_result in enemy_turn_results: message = enemy_turn_result.get('message') dead_entity = enemy_turn_result.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN
def get_names_under_mouse(mouse, entities, fov_map): (x, y) = (mouse.cx, mouse.cy) names = [entity.name for entity in entities if entity.x == x and entity.y == y and libtcod.map_is_in_fov(fov_map, entity.x, entity.y)] names = ', '.join(names) return names.capitalize()
def information_menu(x, y): for obj in settings.objects: if obj.x == x and obj.y == y and tcod.map_is_in_fov(settings.fov_map, obj.x, obj.y): index = menu(obj.name.capitalize(), ["Here's a bunch of info about this object."], 50) return index
def play_game(player, entities, game_map, message_log, game_state, constants): explosion_radius = 0 explosion_target = [] explosion_shape = [] targeting_item = None lineshot_pts = [] lineshot_clr = '' equip_index = 0 move = '' # get the targeting cursor targeting_cursor = entity.find_entity_by_name(entities, 'TargetingCursor') # build the game map, setting up the fov for the map fov_recompute = True fov_map = fov_functions.initialize_fov(game_map) turn_cnt = 0 game_state = GameStates.PLAYER_TURRET_TURN previous_game_state = game_state turret_find = True active_turrets = [] disabled_turrets = [] entity_turn_order = [] active_enemy_turrets = [] enemy_turret_results = [] death_game_state = '' left_click = [] while True: if DEBUG: turn_cnt += 1 print('*******************************') print('TURN {} {}'.format(turn_cnt, game_state)) player_turn_results = [] found_turrets = False if fov_recompute: fov_functions.recompute_fov(fov_map, player.x, player.y, constants['fov_radius'], constants['fov_light_walls'], constants['fov_algorithm']) # initialize set target mode mindist = 1000 foundtarget = None for ent in entities: if ent.ai and ent.combatship and ent not in [ player, targeting_cursor ] and libtcod.map_is_in_fov(fov_map, ent.x, ent.y): if ent.combatship.targeted: foundtarget = None break else: dist = player.distance_to(ent) if dist < mindist: mindist = dist foundtarget = ent if foundtarget is not None: foundtarget.combatship.targeted = True # player turrets take a turn # for targeting turrets (animated), cycle through the whole animation cycle, come back through for next turret if game_state == GameStates.PLAYER_TURRET_TURN: results = [] # first get all the active turrets if turret_find flag is set if turret_find: for item_entity in player.inventory.items: if item_entity.ai is not None and item_entity not in active_turrets and \ item_entity.item.max_charge_time is not None: # handle charge time here as well. Subtract one if charging, fire if charged if not item_entity.item.charge_time: active_turrets.append(item_entity) else: item_entity.item.charge_time -= 1 found_turrets = True turret_find = False else: for item_entity in player.inventory.items: if item_entity.ai is not None and item_entity not in active_turrets and not item_entity.item.charge_time: active_turrets.append(item_entity) if DEBUG: print( 'DEBUG {} total items is {}, active turrets pre check is {}' .format(player.name, len(player.inventory.items), len(active_turrets))) # remove all the disabled turrets and recharging turrets second time through active_turrets = [ turret for turret in active_turrets if turret not in disabled_turrets ] if DEBUG: print('DEBUG {} has {} remaining turrets'.format( player.name, len(active_turrets))) # now look for a good target, get results if you used the turret and remove it from active turrets if active_turrets and not found_turrets: for ent in entities: if ent.combatship: if ent.combatship.targeted: results = active_turrets[0].ai.take_turn( player, ent, fov_map, game_map, entities) if results: player_turn_results.extend(results) active_turrets.remove(active_turrets[0]) break else: results = [] # with no shots or no active turrets, switch to players turn if not results: # do a pass through to rdy up turrets in case you only fired some of your complement if active_turrets: for item_entity in player.inventory.items: if item_entity.ai is not None and item_entity not in active_turrets and \ item_entity.item.max_charge_time is not None: if item_entity.item.charge_time: item_entity.item.charge_time -= 1 game_state = GameStates.PLAYERS_TURN if not active_turrets: turret_find = True # print to screen for render_functions.render_all to display/refresh render_functions.render_all(entities, player, targeting_cursor, game_map, fov_map, fov_recompute, message_log, constants, game_state, equip_index, left_click, active_turrets, lineshot_pts, lineshot_clr, explosion_shape) # clear all explosion points and one line point each time (with delay) render_functions.clear_all(entities, fov_map) # blocking read input (unless an animation is going on) key = None if game_state not in [ GameStates.EXPLOSION, GameStates.LINESHOT, GameStates.PLAYER_TURRET_TURN, GameStates.ENEMY_TURN, GameStates.ENEMY_TURRET_TURN ]: key = terminal.read() action = input_handlers.handle_keys(key, game_state) move = action.get('move') pickup = action.get('pickup') enter = action.get('enter') goto_equip = action.get('goto_equip') drop_equip = action.get('drop_equip') equip_inc = action.get('menupos') equip_select = action.get('select') set_target = action.get('set_target') exit = action.get('exit') fullscreen = action.get('fullscreen') left_click = action.get('left_click') right_click = action.get('right_click') # move the player and attack if an entity is in the way if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = entity.get_blocking_entities_at_location( entities, destination_x, destination_y) if target: attack_results = player.combatship.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) targeting_cursor.move(dx, dy) fov_recompute = True player.combatship.regen_shields() game_state = GameStates.ENEMY_TURRET_TURN # if you hit g and there is an item under you, add to inventory elif pickup and game_state == GameStates.PLAYERS_TURN: for ent in entities: if ent.item and ent.x == player.x and ent.y == player.y: pickup_results = player.inventory.add_item(ent) player_turn_results.extend(pickup_results) break else: message_log.add_message( Message('There is nothing here to pick up.', 'yellow')) # change modes to show (i) / drop (d) if you hit those keys if goto_equip: previous_game_state = game_state game_state = GameStates.GOTO_EQUIP if drop_equip: previous_game_state = game_state game_state = GameStates.DROP_EQUIP if set_target: message_log.add_message( Message( 'Use the arrow keys and press enter to set an enemy target', 'light cyan')) previous_game_state = game_state game_state = GameStates.SET_TARGET # handle moving around within the inventory if equip_inc is not None and previous_game_state != GameStates.PLAYER_DEAD: equip_index += equip_inc if equip_index < 0: equip_index = 0 elif equip_index >= len(player.inventory.items) - 1: equip_index = len(player.inventory.items) - 1 # hit enter in inventory, use item / drop item and append to player_turn_results if equip_select: item = player.inventory.items[equip_index] if game_state == GameStates.GOTO_EQUIP: player_turn_results.extend( player.inventory.use(item, entities=entities, fov_map=fov_map, inventory_enter_key=True)) elif game_state == GameStates.DROP_EQUIP: player_turn_results.extend(player.inventory.drop_item(item)) # once you finish animating the line, check if there is a turret left to fire # if not, going through the turret turn will rebuild active turrets list for next turn if not lineshot_pts and game_state == GameStates.LINESHOT: game_state = previous_game_state # first time through, build the shape of the explosion # second time through (it's been animated and cleared) if game_state == GameStates.EXPLOSION: if explosion_shape: explosion_shape = [] game_state = previous_game_state else: explosion_shape = Diamond( (explosion_target[0], explosion_target[1]), explosion_radius) explosion_shape.build_diamond() # set target mode: if game_state == GameStates.SET_TARGET: if left_click: target_x, target_y = left_click for ent in entities: if ent.ai and ent.combatship and ent not in [ player, targeting_cursor ]: if ent.x == target_x and ent.y == target_y: ent.combatship.targeted = True else: ent.combatship.targeted = False player_turn_results.append({'set_target': True}) elif right_click: player_turn_results.append({'set_target_cancelled': True}) elif move: dx, dy = move if dx + dy >= 0: move = 1 else: move = -1 for ent in entities: if ent.ai and ent.combatship and ent not in [ player, targeting_cursor ]: if ent.combatship.targeted: ships = [ ent for ent in entities if ent.ai and ent.combatship and ent not in [player, targeting_cursor] and libtcod.map_is_in_fov(fov_map, ent.x, ent.y) ] ent.combatship.targeted = False ind = ships.index(ent) newind = ind + move if newind >= 0 and newind < len(ships): entities[entities.index( ships[newind])].combatship.targeted = True else: if move == 1: entities[entities.index( ships[0])].combatship.targeted = True else: entities[entities.index( ships[-1])].combatship.targeted = True break player_turn_results.append({'move_target': True}) elif enter: player_turn_results.append({'set_target': True}) # targeting mode: # left click from mouse_handler targets entity (without using targeting cursor # right click cancels target mode # move will move around the targeting cursor # enter fires and resets cursor if game_state == GameStates.TARGETING: if left_click: target_x, target_y = left_click hit, blocked, target_x, target_y = \ item_functions.target_with_accuracy(player, target_x, target_y, targeting_item.item.function_kwargs.get('accuracy'), game_map, entities) item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map, target_x=target_x, target_y=target_y, blocked=blocked, hit=hit) player_turn_results.extend(item_use_results) player.combatship.regen_shields() elif right_click: targeting_cursor.render_order = render_functions.RenderOrder.INACTIVE_TARGETING targeting_cursor.x = player.x targeting_cursor.y = player.y player_turn_results.append({'targeting_cancelled': True}) elif move: targeting_cursor.render_order = render_functions.RenderOrder.ACTIVE_TARGETING dx, dy = move targeting_cursor.move(dx, dy) elif enter: render_functions.clear_targeting_line(player, targeting_cursor, fov_map) hit, blocked, target_x, target_y = \ item_functions.target_with_accuracy(player, targeting_cursor.x, targeting_cursor.y, targeting_item.item.function_kwargs.get('accuracy'), game_map, entities) item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map, target_x=target_x, target_y=target_y, blocked=blocked, hit=hit) player_turn_results.extend(item_use_results) targeting_cursor.render_order = render_functions.RenderOrder.INACTIVE_TARGETING targeting_cursor.x = player.x targeting_cursor.y = player.y player.combatship.regen_shields() # hit escape at any point # if in inventory mode, clears the inventory screen and goes back to player state if exit: if game_state in [ GameStates.GOTO_EQUIP, GameStates.DROP_EQUIP, GameStates.SET_TARGET ]: terminal.clear() fov_recompute = True game_state = previous_game_state elif game_state == GameStates.TARGETING: targeting_cursor.render_order = render_functions.RenderOrder.INACTIVE_TARGETING targeting_cursor.x = player.x targeting_cursor.y = player.y player_turn_results.append({'targeting_cancelled': True}) else: data_loaders.save_game(player, entities, game_map, message_log, game_state) return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') autofire = player_turn_result.get('autofire') explosion = player_turn_result.get('explosion') lineshot = player_turn_result.get('lineshot') dead_entity = player_turn_result.get('dead') item_added = player_turn_result.get('item_added') item_dropped = player_turn_result.get('item_dropped') targeting = player_turn_result.get('targeting') toggle_turret = player_turn_result.get('toggle_turret') targeting_cancelled = player_turn_result.get('targeting_cancelled') set_target_result = player_turn_result.get('set_target') set_target_cancelled = player_turn_result.get( 'set_target_cancelled') move_target = player_turn_result.get('move_target') if message: message_log.add_message(message) if autofire: pass if explosion: explosion_radius = explosion[0] explosion_target = explosion[1] game_state = GameStates.EXPLOSION previous_game_state = GameStates.ENEMY_TURRET_TURN if lineshot: lineshot_pts = [ step for step in libtcod.line_iter(player.x, player.y, lineshot.get('pts')[0], lineshot.get('pts')[1]) ] lineshot_clr = lineshot.get('clr') game_state = GameStates.LINESHOT previous_game_state = GameStates.PLAYER_TURRET_TURN if dead_entity: if dead_entity == player: message, game_state = death_functions.kill_player( dead_entity) else: entity_turn_order.remove(dead_entity) message = death_functions.kill_enemy(dead_entity) message_log.add_message(message) if item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURRET_TURN if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURRET_TURN if targeting: terminal.clear() fov_recompute = True previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message(targeting_item.item.targeting_message) if toggle_turret: if toggle_turret in disabled_turrets: toggle_turret.item.targeting = 'auto_on' disabled_turrets.remove(toggle_turret) else: toggle_turret.item.targeting = 'auto_off' disabled_turrets.append(toggle_turret) game_state = GameStates.PLAYERS_TURN if targeting_cancelled: fov_recompute = True game_state = previous_game_state message_log.add_message(Message('Targeting cancelled.')) if set_target_result: game_state = GameStates.PLAYERS_TURN fov_recompute = True if set_target_cancelled: game_state = previous_game_state if move_target: fov_recompute = True if game_state == GameStates.ENEMY_TURN: active_enemy_turrets = [] if entity_turn_order: ent = entity_turn_order[0] entity_turn_order.remove(ent) enemy_turn_results = ent.ai.take_turn(player, fov_map, game_map, entities, constants) for enemy_turn_result in enemy_turn_results: message = enemy_turn_result.get('message') dead_entity = enemy_turn_result.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = death_functions.kill_player( dead_entity) else: entity_turn_order.remove(dead_entity) message = death_functions.kill_enemy(dead_entity) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break elif not entity_turn_order: game_state = GameStates.PLAYER_TURRET_TURN else: game_state = GameStates.ENEMY_TURRET_TURN else: game_state = GameStates.PLAYER_TURRET_TURN if game_state == GameStates.ENEMY_TURRET_TURN: enemy_turret_results = [] dead_entity = '' if entity_turn_order: ent = entity_turn_order[0] if not active_enemy_turrets: for item_entity in ent.inventory.items: if item_entity.ai is not None and item_entity not in active_turrets and \ item_entity.item.max_charge_time is not None: # handle charge time here as well. Subtract one if charging, fire if charged if not item_entity.item.charge_time: active_enemy_turrets.append(item_entity) else: item_entity.item.charge_time -= 1 if DEBUG: print('DEBUG {} {} items, {} with ai'.format( ent.name, len(ent.inventory.items), len([ i for i in ent.inventory.items if i.ai is not None ]))) print('DEBUG {} position {}'.format( ent.name, [ent.x, ent.y])) print('DEBUG {} has {} remaining turrets'.format( ent.name, len(active_enemy_turrets))) if active_enemy_turrets: enemy_turret_results = ent.ai.handle_turret( active_enemy_turrets[0], player, fov_map, game_map, entities, constants) active_enemy_turrets.remove(active_enemy_turrets[0]) for result in enemy_turret_results: if DEBUG and result: print('DEBUG {} turret result {}'.format( ent.name, result)) dead_entity = result.get('dead') lineshot = result.get('lineshot') message = result.get('message') if dead_entity == player and not death_game_state: message, death_game_state = death_functions.kill_player( dead_entity) if lineshot: lineshot_pts = [ step for step in libtcod.line_iter( ent.x, ent.y, lineshot.get('pts')[0], lineshot.get('pts')[1]) ] lineshot_clr = lineshot.get('clr') if DEBUG: print( 'DEBUG {} enemy target lineshot {}'.format( ent.name, lineshot_pts)) game_state = GameStates.LINESHOT if not active_enemy_turrets: previous_game_state = GameStates.ENEMY_TURN else: previous_game_state = GameStates.ENEMY_TURRET_TURN if message: message_log.add_message(message) if death_game_state: previous_game_state = death_game_state # with no shots or no active turrets, switch to players turn if not enemy_turret_results and not dead_entity: # do a pass through to rdy up turrets in case you only fired some of your complement if active_enemy_turrets: for item_entity in ent.inventory.items: if item_entity.ai is not None and item_entity not in active_turrets and \ item_entity.item.max_charge_time is not None: if item_entity.item.charge_time: item_entity.item.charge_time -= 1 game_state = GameStates.ENEMY_TURN else: game_state = GameStates.ENEMY_TURN # build list of enemies if not entity_turn_order: entity_turn_order = [ ent for ent in entities if ent.ai is not None and libtcod.map_is_in_fov(fov_map, ent.x, ent.y) ]
def draw(self): if (libtcod.map_is_in_fov(fov_map, self.x, self.y) or (self.always_visible and map[self.x][self.y].explored)): libtcod.console_set_default_foreground(con, self.color) libtcod.console_put_char(con, self.x, self.y, self.char, libtcod.BKGND_NONE)
def draw_entity(con, entity, fov_map, game_map): if libtcod.map_is_in_fov(fov_map, entity.x, entity.y) or ( entity.stairs and game_map.tiles[entity.x][entity.y].explored): libtcod.console_set_default_foreground(con, entity.color) libtcod.console_put_char(con, entity.x, entity.y, entity.char, libtcod.BKGND_NONE)
def render_all(): global fov_map, color_dark_wall, color_light_wall global color_dark_ground, color_light_ground global fov_recompute if fov_recompute: #recompute FOV if needed (the player moved or something) fov_recompute = False libtcod.map_compute_fov(fov_map, player.x, player.y, TORCH_RADIUS, FOV_LIGHT_WALLS, FOV_ALGO) #go through all tiles, and set their background color according to the FOV for y in range(MAP_HEIGHT): for x in range(MAP_WIDTH): visible = libtcod.map_is_in_fov(fov_map, x, y) wall = map[x][y].block_sight if not visible: #if it's not visible right now, the player can only see it if it's explored if map[x][y].explored: if wall: libtcod.console_set_char_background( con, x, y, color_dark_wall, libtcod.BKGND_SET) # libtcod.console_put_char_ex(con, x, y, '#', libtcod.white, libtcod.dark_blue) else: libtcod.console_set_char_background( con, x, y, color_dark_ground, libtcod.BKGND_SET) else: #it's visible if wall: libtcod.console_set_char_background( con, x, y, color_light_wall, libtcod.BKGND_SET) else: libtcod.console_set_char_background( con, x, y, color_light_ground, libtcod.BKGND_SET) #since it's visible, explore it map[x][y].explored = True #draw all objects in the list, except the player. we want it to #always appear over all other objects! so it's drawn later. for object in objects: if object != player: object.draw() player.draw() #blit the contents of "con" to the root console libtcod.console_blit(con, 0, 0, MAP_WIDTH, MAP_HEIGHT, 0, 0, 0) #prepare to render the GUI panel libtcod.console_set_default_background(panel, libtcod.black) libtcod.console_clear(panel) #print the game messages, one line at a time y = 1 for (line, color) in game_msgs: libtcod.console_set_default_foreground(panel, color) libtcod.console_print_ex(panel, MSG_X, y, libtcod.BKGND_NONE, libtcod.LEFT, line) y += 1 #show the player's stats render_bar(1, 1, BAR_WIDTH, 'HP', player.fighter.hp, player.fighter.max_hp, libtcod.light_red, libtcod.darker_red) libtcod.console_print_ex(panel, 1, 3, libtcod.BKGND_NONE, libtcod.LEFT, 'Dungeon level ' + str(dungeon_level)) #display names of objects under the mouse libtcod.console_set_default_foreground(panel, libtcod.light_gray) libtcod.console_print_ex(panel, 1, 0, libtcod.BKGND_NONE, libtcod.LEFT, get_names_under_mouse()) #blit the contents of "panel" to the root console libtcod.console_blit(panel, 0, 0, SCREEN_WIDTH, PANEL_HEIGHT, 0, 0, PANEL_Y)
def draw(self): #only show if it's visible to the player if libtcod.map_is_in_fov(fov_map, self.x, self.y): #set the color and then draw the character that represents this object at its position libtcod.console_set_default_foreground(con, self.color) libtcod.console_put_char(con, self.x, self.y, self.char, libtcod.BKGND_NONE)
def render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, mouse, colors, game_state): if fov_recompute: for y in range(game_map.height): for x in range(game_map.width): visible = libtcod.map_is_in_fov(fov_map, x, y) wall = game_map.tiles[x][y].block_sight back_col = '' fore_col = '' if visible: if wall: back_col = 'back_light_wall' fore_col = 'fore_light_wall' else: back_col = 'back_light_ground' fore_col = 'fore_light_ground' game_map.tiles[x][y].explored = True elif game_map.tiles[x][y].explored: if wall: back_col = 'back_dark_wall' fore_col = 'fore_dark_wall' else: back_col = 'back_dark_ground' fore_col = 'fore_dark_ground' if back_col and fore_col: libtcod.console_put_char_ex(con, x, y, game_map.tiles[x][y].char, colors.get(fore_col), colors.get(back_col)) # Draw all entities in the list entities_in_render_order = sorted(entities, key=lambda x: x.render_order.value) for entity in entities_in_render_order: draw_entity(con, entity, fov_map, game_map) libtcod.console_blit(con, 0, 0, screen_width, screen_height, 0, 0, 0) libtcod.console_set_default_background(panel, libtcod.black) libtcod.console_clear(panel) # Print the game messages, one line at a time y = 1 for message in message_log.messages: libtcod.console_set_default_foreground(panel, message.color) libtcod.console_print_ex(panel, message_log.x, y, libtcod.BKGND_NONE, libtcod.LEFT, message.text) y += 1 render_bar(panel, 1, 1, bar_width, 'HP', player.fighter.hp, player.fighter.max_hp, libtcod.light_red, libtcod.darker_red) render_bar(panel, 1, 2, bar_width, 'ST', 7, 10, libtcod.light_green, libtcod.darker_green) render_bar(panel, 1, 3, bar_width, 'MP', 7, 10, libtcod.light_blue, libtcod.darker_blue) render_bar(panel, 1, 4, bar_width, 'XP', player.level.current_xp, player.level.experience_to_next_level, libtcod.light_yellow, libtcod.darker_yellow, font_color=libtcod.white) libtcod.console_print_ex( panel, 1, 5, libtcod.BKGND_NONE, libtcod.LEFT, 'Dungeon level: {0}'.format(game_map.dungeon_level)) s = ',' libtcod.console_print_ex( panel, 1, 6, libtcod.BKGND_NONE, libtcod.LEFT, '{0}'.format(s.join(list(player.fighter.conditions.keys())))) libtcod.console_set_default_foreground(panel, libtcod.light_gray) libtcod.console_print_ex(panel, 1, 0, libtcod.BKGND_NONE, libtcod.LEFT, get_names_under_mouse(mouse, entities, fov_map)) libtcod.console_blit(panel, 0, 0, screen_width, panel_height, 0, 0, panel_y) if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY, GameStates.QUICK_USE, GameStates.QUICK_USE_NUMBER): if game_state == GameStates.SHOW_INVENTORY: inventory_title = 'Press the key next to an item to use it, or Esc to cancel.\n' elif game_state == GameStates.DROP_INVENTORY: inventory_title = 'Press the key next to an item to drop it, or Esc to cancel.\n' elif game_state == GameStates.QUICK_USE_NUMBER: inventory_title = 'Press 1-5 to select a quick use slot' elif game_state == GameStates.QUICK_USE: inventory_title = 'Press the key next to an item to assign it to a quickslot' inventory_menu(con, inventory_title, player, 50, screen_width, screen_height) elif game_state == GameStates.LEVEL_UP: level_up_menu(con, 'Level up! Choose a stat to raise:', player, 40, screen_width, screen_height) elif game_state == GameStates.CHARACTER_SCREEN: character_screen(player, 40, 30, screen_width, screen_height) elif game_state == GameStates.EXAMINE_SCREEN: examine_screen(entities, mouse, fov_map, 40, 30, screen_width, screen_height)
def target_tile(actor, max_range=None): """ Return the position of a tile left-clicked in player's FOV (optionally in a range), or (None,None) if right-clicked. """ (key, mouse) = poll() (ox, oy) = (mouse.cx, mouse.cy) using_mouse = False using_keyboard = False (kx, ky) = renderer.ScreenCoords.fromWorldCoords(actor.camera_position, actor.pos) pos = None while True: # Render the screen. This erases the inventory and shows # the names of objects under the mouse. libtcod.console_flush() (key, mouse) = poll() renderer.render_all(actor, (kx, ky)) actor.current_map.fov_needs_recompute = False if (mouse.cx != ox or mouse.cy != oy): using_mouse = True using_keyboard = False (key_pressed, direction, shift) = parse_move(key) if key_pressed: using_keyboard = True if using_mouse: (ox, oy) = (mouse.cx, mouse.cy) using_mouse = False if direction: kx += direction.x ky += direction.y if using_mouse: (kx, ky) = (mouse.cx, mouse.cy) pos = renderer.ScreenCoords.toWorldCoords(actor.camera_position, (kx, ky)) libtcod.console_set_default_background(renderer._overlay, libtcod.black) libtcod.console_clear(renderer._overlay) (ux, uy) = renderer.ScreenCoords.fromWorldCoords(actor.camera_position, actor.pos) libtcod.line_init(ux, uy, kx, ky) nx, ny = libtcod.line_step() while ((not (nx is None)) and nx >= 0 and ny >= 0 and nx < config.MAP_PANEL_WIDTH and ny < config.MAP_PANEL_HEIGHT): libtcod.console_set_char_background(renderer._overlay, nx, ny, libtcod.sepia, libtcod.BKGND_SET) nx, ny = libtcod.line_step() if mouse.rbutton_pressed or key.vk == libtcod.KEY_ESCAPE: libtcod.console_clear(renderer._overlay) return None # Accept the target if the player clicked in FOV # and within the range specified. if ((mouse.lbutton_pressed or key.vk == libtcod.KEY_ENTER) and libtcod.map_is_in_fov(actor.current_map.fov_map, pos.x, pos.y) and (max_range is None or actor.distance(pos) <= max_range)): libtcod.console_clear(renderer._overlay) return pos
def draw(self): if libtcod.map_is_in_fov(fov_map, self.x, self.y): libtcod.console_set_default_foreground(con, self.color) libtcod.console_put_char(con, self.x, self.y, self.char, libtcod.BKGND_NONE)
def check_for_stateswap(self): monster = self.owner if libtcod.map_is_in_fov(self.gldir.fov_map, monster.x, monster.y): self.pass_into(SimpleAttack) if self.ai.timer_since_swap > 7 or (self.owner.x, self.owner.y) == (self.target.x, self.target.y): self.pass_into(SimpleIdle)
def draw(self, fov_map, con): #Draw the character that represents this object, if its in the players field of view if libtcod.map_is_in_fov(fov_map, self.x, self.y): libtcod.console_set_default_foreground(con, self.color) libtcod.console_put_char(con, self.x, self.y, self.char, libtcod.BKGND_NONE)
def render_all(fov_recompute): # main fucntion which draws all objects on the screen every cycle #local renders player = gameconfig.player objects = gameconfig.objects level_map = gameconfig.level_map fov_map = gameconfig.fov_map theme = gameconfig.color_theme if fov_recompute: libtcod.map_compute_fov(fov_map, player.x, player.y, gameconfig.TORCH_RADIUS, gameconfig.FOV_LIGHT_WALLS, gameconfig.FOV_ALGO) # go through all tiles, and set their background color for y in range(gameconfig.MAP_HEIGHT): for x in range(gameconfig.MAP_WIDTH): visible = libtcod.map_is_in_fov(fov_map, x, y) wall = level_map[x][y].block_sight if not visible: if level_map[x][y].explored: if wall: libtcod.console_set_char_background( gameconfig.con, x, y, theme['color_dark_wall'], libtcod.BKGND_SET) else: libtcod.console_set_char_background( gameconfig.con, x, y, theme['color_dark_ground'], libtcod.BKGND_SET) else: if wall: libtcod.console_set_char_background( gameconfig.con, x, y, theme['color_light_wall'], libtcod.BKGND_SET) else: libtcod.console_set_char_background( gameconfig.con, x, y, theme['color_light_ground'], libtcod.BKGND_SET) level_map[x][y].explored = True # draw all objects in the list for obj in objects: if obj != player: if libtcod.map_is_in_fov(fov_map, obj.x, obj.y): draw_object(obj, gameconfig.con) draw_object(player, gameconfig.con) # draw player last #blit the contents of "con" to the root console libtcod.console_blit(gameconfig.con, 0, 0, gameconfig.SCREEN_WIDTH, gameconfig.SCREEN_HEIGHT, 0, 0, 0) # panel libtcod.console_set_default_background(gameconfig.panel, libtcod.black) libtcod.console_clear(gameconfig.panel) # HUD render_hud() render_messages() libtcod.console_blit(gameconfig.panel, 0, 0, gameconfig.SCREEN_WIDTH, gameconfig.PANEL_HEIGHT, 0, 0, gameconfig.PANEL_Y) # clean up libtcod.console_flush() for obj in objects: clear_object(obj, gameconfig.con)
def render_all(): global color_light_wall global color_light_ground global fov_recompute global game_msgs # go through all tiles, and set their background color according to the FOV for y in range(MAP_HEIGHT): for x in range(MAP_WIDTH): visible = libtcod.map_is_in_fov(fov_map, x, y) wall = map[x][y].block_sight if not visible: # if it's not visible right now, the player can only see it if it's explored if map[x][y].explored: # it's out of the player's FOV if wall: libtcod.console_set_char_background( con, x, y, color_dark_wall, libtcod.BKGND_SET) else: libtcod.console_set_char_background( con, x, y, color_dark_ground, libtcod.BKGND_SET) else: # it's visible if wall: libtcod.console_set_char_background( con, x, y, color_light_wall, libtcod.BKGND_SET) else: libtcod.console_set_char_background( con, x, y, color_light_ground, libtcod.BKGND_SET) map[x][y].explored = True # draw all objects in the list for object in objects: object.draw() player.draw() # blit the contents of "con" to the root console libtcod.console_blit(con, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 0) if fov_recompute: # recompute FOV if needed (the player moved or something) fov_recompute = False libtcod.map_compute_fov(fov_map, player.x, player.y, TORCH_RADIUS, FOV_LIGHT_WALLS, FOV_ALGO) # prepare to render the GUI panel libtcod.console_set_default_background(panel, libtcod.black) libtcod.console_clear(panel) # print the game messages, one line at a time y = 1 for (line, color) in game_msgs: libtcod.console_set_default_foreground(panel, color) libtcod.console_print_ex(panel, MSG_X, y, libtcod.BKGND_NONE, libtcod.LEFT, line) y += 1 # show the player's stats render_bar( 1, 1, BAR_WIDTH, "HP", player.fighter.hp, player.fighter.max_hp, libtcod.light_red, libtcod.darker_red, ) # blit the contents of "panel" to the root console libtcod.console_blit(panel, 0, 0, SCREEN_WIDTH, PANEL_HEIGHT, 0, 0, PANEL_Y)
def take_turn(self, target, fov_map, game_map, entities): results = [] monster = self.owner closest_distance = 10 if self.number_of_turns > 0: for entity in entities: if entity.ai and entity.ai != PeacefulMonster and entity != monster and libtcod.map_is_in_fov(fov_map, entity.x, entity.y): distance = monster.distance_to(entity) if distance < closest_distance: target = entity closest_distance = distance if monster.distance_to(target) >= 2: monster.move_astar(target, entities, game_map) elif target.fighter.hp > 0: attack_results = monster.fighter.attack(target) results.extend(attack_results) else: random_x = self.owner.x + randint(0, 2) - 1 random_y = self.owner.y + randint(0, 2) - 1 if random_x != self.owner.x and random_y != self.owner.y: self.owner.move_towards(random_x, random_y, game_map, entities) self.number_of_turns -= 1 else: self.owner.ai = self.previous_ai results.append({'message': Message('The {0} is no longer charmed!'.format(self.owner.name), libtcod.red)}) return results
def render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, mouse, colors): # Draw all the tiles in the game map if fov_recompute: for y in range(game_map.height): for x in range(game_map.width): visible = libtcod.map_is_in_fov(fov_map, x, y) wall = game_map.tiles[x][y].block_sight if visible: if wall: libtcod.console_set_char_background( con, x, y, colors.get('light_wall'), libtcod.BKGND_SET) else: libtcod.console_set_char_background( con, x, y, colors.get('light_ground'), libtcod.BKGND_SET) game_map.tiles[x][y].explored = True elif game_map.tiles[x][y].explored: if wall: libtcod.console_set_char_background( con, x, y, colors.get('dark_wall'), libtcod.BKGND_SET) else: libtcod.console_set_char_background( con, x, y, colors.get('dark_ground'), libtcod.BKGND_SET) # Draw all entities in the list entities_in_render_order = sorted(entities, key=lambda x: x.render_order.value) for entity in entities_in_render_order: draw_entity(con, entity, fov_map) libtcod.console_set_default_foreground(con, libtcod.white) libtcod.console_print_ex( con, 1, screen_height - 2, libtcod.BKGND_NONE, libtcod.LEFT, 'HP: {0:02}/{1:02}'.format(player.fighter.hp, player.fighter.max_hp)) libtcod.console_blit(con, 0, 0, screen_width, screen_height, 0, 0, 0) libtcod.console_set_default_background(panel, libtcod.black) libtcod.console_clear(panel) # Print the game messages, one line at a time y = 1 for message in message_log.messages: libtcod.console_set_default_foreground(panel, message.color) libtcod.console_print_ex(panel, message_log.x, y, libtcod.BKGND_NONE, libtcod.LEFT, message.text) y += 1 render_bar(panel, 1, 1, bar_width, 'HP', player.fighter.hp, player.fighter.max_hp, libtcod.light_red, libtcod.darker_red) libtcod.console_set_default_foreground(panel, libtcod.light_gray) libtcod.console_print_ex(panel, 1, 0, libtcod.BKGND_NONE, libtcod.LEFT, get_names_under_mouse(mouse, entities, fov_map)) libtcod.console_blit(panel, 0, 0, screen_width, panel_height, 0, 0, panel_y)
def render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, mouse, colors, game_state): if fov_recompute: # Draw all the tiles in the game map for y in range(game_map.height): for x in range(game_map.width): visible = libtcod.map_is_in_fov(fov_map, x, y) wall = game_map.tiles[x][y].block_sight if visible: if wall: libtcod.console_set_char_background( con, x, y, colors.get('light_wall'), libtcod.BKGND_SET) else: libtcod.console_set_char_background( con, x, y, colors.get('light_ground'), libtcod.BKGND_SET) game_map.tiles[x][y].explored = True elif game_map.tiles[x][y].explored: if wall: libtcod.console_set_char_background( con, x, y, colors.get('dark_wall'), libtcod.BKGND_SET) else: libtcod.console_set_char_background( con, x, y, colors.get('dark_ground'), libtcod.BKGND_SET) entities_in_render_order = sorted(entities, key=lambda x: x.render_order.value) # Draw all entities in the list for entity in entities_in_render_order: draw_entity(con, entity, fov_map, game_map) libtcod.console_set_default_foreground(con, libtcod.white) libtcod.console_print_ex( con, 1, screen_height - 2, libtcod.BKGND_NONE, libtcod.LEFT, 'HP: {0:02}/{1:02}'.format(player.fighter.hp, player.fighter.max_hp)) libtcod.console_blit(con, 0, 0, screen_width, screen_height, 0, 0, 0) libtcod.console_set_default_background(panel, libtcod.black) libtcod.console_clear(panel) # Print the game messages, one line at a time y = 1 for message in message_log.messages: libtcod.console_set_default_foreground(panel, message.color) libtcod.console_print_ex(panel, message_log.x, y, libtcod.BKGND_NONE, libtcod.LEFT, message.text) y += 1 render_bar(panel, 1, 1, bar_width, 'HP', player.fighter.hp, player.fighter.max_hp, libtcod.light_red, libtcod.darker_red) libtcod.console_print_ex( panel, 1, 3, libtcod.BKGND_NONE, libtcod.LEFT, 'Dungeon level: {0}'.format(game_map.dungeon_level)) libtcod.console_set_default_foreground(panel, libtcod.light_gray) libtcod.console_print_ex(panel, 1, 0, libtcod.BKGND_NONE, libtcod.LEFT, get_names_under_mouse(mouse, entities, fov_map)) libtcod.console_blit(panel, 0, 0, screen_width, panel_height, 0, 0, panel_y) if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY): if game_state == GameStates.SHOW_INVENTORY: inventory_title = 'Press the key next to an item to use it, or Esc to cancel.\n' else: inventory_title = 'Press the key next to an item to drop it, or Esc to cancel.\n' inventory_menu(con, inventory_title, player, 50, screen_width, screen_height) elif game_state == GameStates.LEVEL_UP: level_up_menu(con, 'level up! Choose a stat to raise:', player, 40, screen_width, screen_height) elif game_state == GameStates.CHARACTER_SCREEN: character_screen(player, 30, 10, screen_width, screen_height)
def render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, mouse, colors, game_state): if fov_recompute: # Draw all the tiles in the game map for y in range(game_map.height): for x in range(game_map.width): visible = libtcod.map_is_in_fov(fov_map, x, y) wall = game_map.tiles[x][y].block_sight if visible: if wall: libtcod.console_set_char_background( con, x, y, colors.get('light_wall'), libtcod.BKGND_SET) else: libtcod.console_set_char_background( con, x, y, colors.get('light_ground'), libtcod.BKGND_SET) game_map.tiles[x][y].explored = True elif game_map.tiles[x][y].explored: if wall: libtcod.console_set_char_background( con, x, y, colors.get('dark_wall'), libtcod.BKGND_SET) else: libtcod.console_set_char_background( con, x, y, colors.get('dark_ground'), libtcod.BKGND_SET) entities_in_render_order = sorted(entities, key=lambda x: x.render_order.value) # Draw all entities in the list for entity in entities_in_render_order: draw_entity(con, entity, fov_map, game_map) libtcod.console_set_default_foreground(con, libtcod.white) libtcod.console_print_ex( con, 1, screen_height - 2, libtcod.BKGND_NONE, libtcod.LEFT, "HP: {0:02}/{1:02}".format(player.fighter.hp, player.fighter.max_hp)) ''' Danny code to center player and have window scroll r = 20 libtcod.console_blit(con, player.x - r, player.y - r, 2*r+1, 2*r+1, 0, int(screen_width/2) - r, int(screen_height/2) - r) ''' libtcod.console_blit(con, 0, 0, screen_width, screen_height, 0, 0, 0) libtcod.console_set_default_background(panel, libtcod.black) libtcod.console_clear(panel) y = 1 for message in message_log.messages: libtcod.console_set_default_foreground(panel, message.color) libtcod.console_print_ex(panel, message_log.x, y, libtcod.BKGND_NONE, libtcod.LEFT, message.text) y += 1 render_bar(panel, 1, 1, bar_width, "HP", player.fighter.hp, player.fighter.max_hp, libtcod.light_red, libtcod.darker_red) render_bar(panel, 1, 2, bar_width, "EXP", player.level.current_xp, player.level.experience_to_next_level, libtcod.light_blue, libtcod.darker_blue) libtcod.console_print_ex(panel, 1, 3, libtcod.BKGND_NONE, libtcod.LEFT, "Gold: {0}".format(player.fighter.gold)) if player.inventory.search("Health Talisman") is not None: libtcod.console_print_ex( panel, 1, 4, libtcod.BKGND_NONE, libtcod.LEFT, "Talisman HP: {0}".format(player.fighter.talismanhp)) libtcod.console_print_ex( panel, 1, 5, libtcod.BKGND_NONE, libtcod.LEFT, "Dungeon Level: {0}".format(game_map.dungeon_level)) libtcod.console_set_default_foreground(panel, libtcod.light_gray) libtcod.console_print_ex(panel, 1, 0, libtcod.BKGND_NONE, libtcod.LEFT, get_names_under_mouse(mouse, entities, fov_map)) libtcod.console_blit(panel, 0, 0, screen_width, panel_height, 0, 0, panel_y) if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY): if game_state == GameStates.SHOW_INVENTORY: inventory_title = "Press the key next to an item to use it, or ESC to cancel.\n" else: inventory_title = "Press the key next to an item to drop it, or ESC to cancel.\n" inventory_menu(con, inventory_title, player, 50, screen_width, screen_height) elif game_state == GameStates.SHOW_EQUIPMENT_INVENTORY: equipment_inventory_menu( con, "Press the key next to an item to equip it, or ESC to cancel.\n", player.equipment_inventory, 50, screen_width, screen_height) elif game_state == GameStates.LEVEL_UP: level_up_menu(con, "Level up! Choose a stat to raise:", player, 40, screen_width, screen_height) elif game_state == GameStates.CHARACTER_SCREEN: character_screen(player, 30, 10, screen_width, screen_height) elif game_state == GameStates.SHOW_BAG: bag_title = "Press the key next to the option to open the bag.\n" bag_menu(con, bag_title, player, 50, screen_width, screen_height) elif game_state == GameStates.HELP_MENU: help_menu(player, 30, 10, screen_width, screen_height)
def take_turn(self, target, fov_map, game_map, entities): global npc_target global attacks results = [] monster = self.owner attacks = randint(1,10) closest_distance = 10 for entity in entities: if entity.ai and entity.fighter.is_peaceful == False and entity != monster: npc_target = entity if monster.fighter.is_peaceful == True and npc_target.ai and npc_target.fighter and npc_target.fighter.is_peaceful == False: target = npc_target if monster.distance_to(target) >= 2: if target.fighter.stealthed == 0: monster.move_astar(target, entities, game_map) else: random_x = self.owner.x + randint(0, 2) - 1 random_y = self.owner.y + randint(0, 2) - 1 if random_x != self.owner.x and random_y != self.owner.y: self.owner.move_towards(random_x, random_y, game_map, entities) attacks = randint(1, 10) elif target.fighter.hp > 0: target.fighter.poisoned = 1 target.fighter.poison_timer = 12 poison_results = monster.fighter.poison_attack(target) attack_results = monster.fighter.attack(target) results.extend(attack_results) results.extend(poison_results) attacks = randint(1, 10) else: if libtcod.map_is_in_fov(fov_map, monster.x, monster.y): if monster.distance_to(target) >= 2: if target.fighter.stealthed == 0: monster.move_astar(target, entities, game_map) else: random_x = self.owner.x + randint(0, 2) - 1 random_y = self.owner.y + randint(0, 2) - 1 if random_x != self.owner.x and random_y != self.owner.y: self.owner.move_towards(random_x, random_y, game_map, entities) attacks = randint(1, 10) elif target.fighter.hp > 0 and target.fighter.poisoned == 0 and 8 <= attacks >= 9 <= attacks <= 10: target.fighter.poisoned = 1 target.fighter.poison_timer = 12 poison_results = monster.fighter.poison_attack(target) attack_results = monster.fighter.attack(target) results.extend(attack_results) results.extend(poison_results) attacks = randint(1, 10) elif target.fighter.hp > 0: attack_results = monster.fighter.attack(target) results.extend(attack_results) attacks = randint(1, 10) else: random_x = self.owner.x + randint(0, 2) - 1 random_y = self.owner.y + randint(0, 2) - 1 if random_x != self.owner.x and random_y != self.owner.y: self.owner.move_towards(random_x, random_y, game_map, entities) return results
def take_turn(self, target, fov_map, game_map, entities): global npc_target results = [] monster = self.owner closest_distance = 10 for entity in entities: if entity.ai and entity.fighter.is_peaceful == False and entity != monster: npc_target = entity if monster.fighter.is_peaceful == True and npc_target.ai and npc_target.fighter and npc_target.fighter.is_peaceful == False : distance = monster.distance_to(npc_target) if distance < closest_distance: target = npc_target closest_distance = distance if monster.distance_to(target) >= 2: monster.move_astar(target, entities, game_map) elif target.fighter.hp > 0: attack_results = monster.fighter.attack(target) results.extend(attack_results) else: random_x = self.owner.x + randint(0, 2) - 1 random_y = self.owner.y + randint(0, 2) - 1 if random_x != self.owner.x and random_y != self.owner.y: self.owner.move_towards(random_x, random_y, game_map, entities) else: if monster.fighter.is_peaceful == False and libtcod.map_is_in_fov(fov_map, monster.x, monster.y): if monster.distance_to(target) >= 2: if target.fighter.stealthed == 0: monster.move_astar(target, entities, game_map) else: random_x = self.owner.x + randint(0, 2) - 1 random_y = self.owner.y + randint(0, 2) - 1 if random_x != self.owner.x and random_y != self.owner.y: self.owner.move_towards(random_x, random_y, game_map, entities) elif target.fighter.hp > 0: fighter_component = Fighter(hp=20, defense=2, power=5, xp=100, agility=1, mana=0, base_psyche=0, attack_dice_minimum=2, attack_dice_maximum=6, ac=3, will=3, talk_message='The Bee-Spawn buzzes') ai_component = BasicMonster() food_component = Item(use_function=eat, amount=25, eat_message='That meal tastes like jelly!') monster = Entity(self.owner.x, self.owner.y, 'b', libtcod.white, 'Bee-Spawn', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, ai=ai_component, item=food_component) entities.append(monster) attack_results = monster.fighter.attack(target) results.extend(attack_results) else: random_x = self.owner.x + randint(0, 2) - 1 random_y = self.owner.y + randint(0, 2) - 1 if random_x != self.owner.x and random_y != self.owner.y: self.owner.move_towards(random_x, random_y, game_map, entities) return results
def handle_keys(): #global keys if defn.key.vk == libtcod.KEY_ENTER and defn.key.lalt: #Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif defn.key.vk == libtcod.KEY_ESCAPE: return 'exit' #exit game if defn.game_state == 'playing': #autoplay module if defn.autoplaying != None: #if any hostile monsters are in view, stop autoplaying: for obj in defn.objects: if obj.creature and obj.creature.alignment != 'player' and libtcod.map_is_in_fov( defn.fov_map, obj.x, obj.y): gui.message( 'Seeing enemies, you decide to pay a bit more attention to what you are doing.', libtcod.white) defn.autoplaying = None break #Move. if defn.autoplaying == 'autoexplore': #first check if standing on an item. If so, pick it up. for obj in defn.dungeon[defn.player.x][ defn.player. y].objects: #look for an item in the player's tile if obj.item and len(defn.inventory) < 26: #we have an error where a full inventory will cause the player to remain on the same spot, continually trying to pick up the item. if obj.item.pick_up() == 'cancelled': defn.autoplaying == None return #compute fog of war (FOW) dijkstra map unexplored_tiles = [] for y in range(defn.MAP_HEIGHT): for x in range(defn.MAP_WIDTH): if not defn.dungeon[x][y].explored: unexplored_tiles.append(defn.dungeon[x][y]) #if inventory is not full, compute item map item_tiles = [] if len(defn.inventory) < 26: for obj in defn.objects: if obj.item and defn.dungeon[obj.x][obj.y].explored: item_tiles.append(defn.dungeon[obj.x][obj.y]) #check whether any target squares were found dijkstra_autoexplore_map = djks.Map(unexplored_tiles + item_tiles) dijkstra_autoexplore_map.compute_map() #if there is a next point, move there, otherwise cancel autoplay: if dijkstra_autoexplore_map.array[defn.player.x][ defn.player.y] < 999: destination = dijkstra_autoexplore_map.get_next_step( defn.player.x, defn.player.y) defn.player.creature.try_to_move(destination.x, destination.y) return else: #cancel autoplay; we're done defn.autoplaying = None elif defn.autoplaying == 'autoascend': #go up if standing on the portal if defn.stairs.x == defn.player.x and defn.stairs.y == defn.player.y: dgen.next_level() defn.autoplaying = None return #see if the portal is visible: portals = [] for y in range(defn.MAP_HEIGHT): for x in range(defn.MAP_WIDTH): if defn.stairs in defn.dungeon[x][ y].objects and defn.dungeon[x][y].explored: portals.append(defn.dungeon[x][y]) if portals: dijkstra_autoascend_map = djks.Map(portals) dijkstra_autoascend_map.compute_map() destination = dijkstra_autoascend_map.get_next_step( defn.player.x, defn.player.y) defn.player.creature.try_to_move(destination.x, destination.y) return #cancel autoplay; we're done defn.autoplaying = None else: #no portals found; cancel autoplay gui.message( 'You have no idea where the nearest portal is.', libtcod.white) defn.autoplaying = None else: #stop autoexploring when a key is pressed. defn.autoplaying = None #autofight with tab if defn.key.vk == libtcod.KEY_TAB: enemy_tiles = [] for obj in defn.objects: if obj.creature and obj.creature.alignment != 'player' and libtcod.map_is_in_fov( defn.fov_map, obj.x, obj.y): enemy_tiles.append(defn.dungeon[obj.x][obj.y]) if enemy_tiles: #create dijkstra map and roll towards nearest enemy. dijkstra_autofight_map = djks.Map(enemy_tiles) dijkstra_autofight_map.compute_map() destination = dijkstra_autofight_map.get_next_step( defn.player.x, defn.player.y) defn.player.creature.try_to_move(destination.x, destination.y) return else: gui.message('No enemies in sight!', libtcod.white) #cancel autoplay if any key is pressed if defn.key.vk != libtcod.KEY_NONE: defn.autoplaying = None #movement keys try: (dx0, dx1) = { libtcod.KEY_KP1: (-1, 1), libtcod.KEY_KP2: (0, 1), libtcod.KEY_KP3: (1, 1), libtcod.KEY_KP4: (-1, 0), libtcod.KEY_KP6: (1, 0), libtcod.KEY_KP7: (-1, -1), libtcod.KEY_KP8: (0, -1), libtcod.KEY_KP9: (1, -1) }[defn.key.vk] player_move_or_attack(dx0, dx1) except: if defn.key.vk == libtcod.KEY_KP5: return key_char = chr(defn.key.c) if key_char == ',': #pick up an item for obj in defn.dungeon[defn.player.x][ defn.player. y].objects: #look for an item in the player's tile if obj.item: obj.item.pick_up() return if key_char == '?': gui.msgbox( 'Use the numpad keys to move around. You can mouse-over any object to identify it. The following keys can be used to get more information:' + '\n\nI = examine an item in your inventory' + '\nZ = examine a spell in your spellbook' + '\nc = access information about your character' + '\nx = get information on a nearby object' + '\n\nThe following keys may be used to interact with your environment:' + '\n\nCOMMA = pick up item from current position' + '\ni = use an item from your inventory' + '\nd = drop an item from your inventory' + '\nz = choose a spell from your spellbook to cast' + '\ns = summon an ally from a previous level' + '\n\nTo avoid tedious repetition, you can automate certain tasks:' + '\n\n< = travel to the nearest portal and pass through' + '\no = autoexplore (press any key to stop exploring)' + '\nTAB = move towards/attack nearest enemy' + '\n\nYour objective on each level is to find the exit and ascend to the next level. Enemies will get more dangerous the further you go, so it will be to your advantage to pick up equipment that you find lying around.', 50) if key_char == 'i': #show the inventory; if an item is selected, use it chosen_item = inventory_menu( 'Press the key next to an item to use it, or any other to cancel.\n' ) if chosen_item is not None: if chosen_item.use() != 'cancelled': return if key_char == 'I': #show the inventory; if an item is selected, describe it chosen_item = inventory_menu( 'Press the key next to an item to examine it, or any other to cancel.\n' ) if chosen_item is not None: info = chosen_item.owner info.describe() if key_char == 'z': spellbook = defn.player.spellbook #show the spellbook; if a spell is selected, use it chosen_spell = spellbook_menu( 'Press the key next to a spell to cast it, or any other to cancel.\n' ) if chosen_spell is not None: if defn.player.creature.cast_spell( chosen_spell) != 'cancelled': spellbook.remove(chosen_spell, 1) return if key_char == 'Z': #show the inventory; if an item is selected, describe it chosen_spell = spellbook_menu( 'Press the key next to a spell for more information, or any other to cancel.\n' ) if chosen_spell is not None: chosen_spell.describe() if key_char == 'd': #show the inventory; if an item is selected, drop it chosen_item = inventory_menu( 'Press the key next to an item to drop it, or any other to cancel.\n' ) if chosen_item is not None: chosen_item.drop() chosen_item.owner.send_to_back() return chosen_item = inventory_menu( 'Press the key next to an item to drop it, or any other to cancel.\n' ) if chosen_item is not None: chosen_item.drop() return if key_char == '<': #go up if standing on the portal if defn.stairs.x == defn.player.x and defn.stairs.y == defn.player.y: dgen.next_level() defn.autoplaying = None #head toward portal and then blank input key in preparation for override. defn.autoplaying = 'autoascend' defn.key.vk = libtcod.KEY_NONE if key_char == 'o': #initialize autoexplore and then blank input key in preparation for override. defn.autoplaying = 'autoexplore' defn.key.vk = libtcod.KEY_NONE if key_char == 'c': #show character information #first, compute traits traits_inc = [] appended_traits = [] for trait in defn.player.traits: if trait[0] not in appended_traits: if len(trait) == 2: if trait[0][-1:] == '+': #sum them trait_inc = [ trait[0], data.sum_values_from_list( defn.player.traits, trait[0]) ] else: #find max trait_inc = [ trait[0], data.max_value_from_list( defn.player.traits, trait[0]) ] traits_inc.append(trait_inc) appended_traits.append(trait_inc[0]) else: traits_inc.append(trait) appended_traits.append(trait) traits = '' for trait in traits_inc: if len(trait) == 1: traits += '\n ' + trait[0].capitalize() else: traits += '\n ' + trait[0].capitalize() + str( trait[1]) #next, compute conditions conditions_inc = [] appended_conditions = [] for condition in defn.player.creature.conditions: if condition not in appended_conditions: conditions_inc.append([ condition, data.count_instances_in_list( defn.player.creature.conditions, condition) ]) appended_conditions.append(condition) conditions = '' for condition in conditions_inc: conditions += '\n ' + condition[0].capitalize( ) + ' (' + str(condition[1]) + ')' level_up_xp = defn.LEVEL_UP_BASE + defn.player.properties[ 'level'] * defn.LEVEL_UP_FACTOR gui.msgbox( 'Character Information\n\nLevel: ' + str(defn.player.properties['level']) + '\nExperience: ' + str(defn.player.creature.xp) + '\nExperience to level up: ' + str(level_up_xp) + '\n\nLife: ' + str(defn.player.creature.max_hp) + '\nMana Capacity: ' + str(defn.player.creature.max_mana) + '\n\nAttack: ' + str(defn.player.creature.active_attack.name.capitalize()) + '\n\nTraits:' + traits + '\n\nConditions' + conditions, defn.CHARACTER_SCREEN_WIDTH) if key_char == 'x': #first, select a target object target = None gui.message( 'Click on the object you would like to know more about, or right click to cancel.', libtcod.white) rangemap = defn.fov_map while True: #render the screen. this erases the inventory and shows the names of objects under the mouse. libtcod.console_flush() libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, defn.key, defn.mouse) game.render_all() (x, y) = (defn.mouse.cx, defn.mouse.cy) if defn.mouse.lbutton_pressed and libtcod.map_is_in_fov( defn.fov_map, x, y): for j in range(defn.MAP_HEIGHT): for i in range(defn.MAP_WIDTH): if libtcod.map_is_in_fov(rangemap, i, j): libtcod.console_set_char_background( defn.con, i, j, defn.dungeon[i][j].color, libtcod.BKGND_SET) break if defn.mouse.rbutton_pressed or defn.key.vk == libtcod.KEY_ESCAPE: for j in range(defn.MAP_HEIGHT): for i in range(defn.MAP_WIDTH): if libtcod.map_is_in_fov(rangemap, i, j): libtcod.console_set_char_background( defn.con, i, j, defn.dungeon[i][j].color, libtcod.BKGND_SET) break if x != None: for obj in defn.dungeon[x][y].objects: target = obj #describe the target more fully if it is a creature if target.creature: traits_inc = [] appended_traits = [] for trait in target.traits: if trait[0] not in appended_traits: if len(trait) == 2: if trait[0][-1:] == '+': #sum them trait_inc = [ trait[0], data.sum_values_from_list( target.traits, trait[0]) ] else: #find max trait_inc = [ trait[0], data.max_value_from_list( target.traits, trait[0]) ] traits_inc.append(trait_inc) appended_traits.append(trait_inc[0]) else: traits_inc.append(trait) appended_traits.append(trait) traits = '' for trait in traits_inc: if len(trait) == 1: traits += '\n ' + trait[0].capitalize() else: traits += '\n ' + trait[0].capitalize( ) + str(trait[1]) #next, compute conditions conditions_inc = [] appended_conditions = [] for condition in target.creature.conditions: if condition not in appended_conditions: conditions_inc.append([ condition, data.count_instances_in_list( target.creature.conditions, condition) ]) appended_conditions.append(condition) conditions = '' for condition in conditions_inc: conditions += '\n ' + condition[ 0].capitalize() + ' (' + str( condition[1]) + ')' title = target.title.capitalize() if target.title == target.name: title = title + ', ' + target.properties['name'] #now describe the creature gui.msgbox( title + '\n\nLevel: ' + str(target.properties['level']) + '\n\nAttack: ' + str(target.creature.active_attack.name. capitalize()) + '\n\nTraits:' + traits + '\n\nConditions:' + conditions + '\n\n' + target.properties['description'], defn.CHARACTER_SCREEN_WIDTH) else: target.describe() break #later, can add menu in case of multiple objects if key_char == 's': #summon an ally creature = summoning_menu( 'Press the key next to a creature to select it, or any other to cancel.\n' ) if creature != None: gui.message( 'Left-click on an open tile to summon creature there, or right-click to cancel.', libtcod.light_cyan) x0, x1 = spfn.target_tile(3) if mpop.place_object(creature, [x0, x1]) != 'failed': defn.player.creatures.remove(creature) else: gui.message('There\'s something in the way...', libtcod.light_cyan) #if key_char == 'w': #defn.player.creature.heal(30) #dgen.next_level() #defn.inventory.append(idic.get_item('scroll of animate dead',0,0)) #defn.inventory.append(idic.get_item('scroll of heal',0,0)) #defn.inventory.append(idic.get_item('scroll of minor heal',0,0)) return 'didnt-take-turn'
def render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, mouse, colors, kill_count, game_state, wall_tile, floor_tile): if fov_recompute: for y in range(game_map.height): for x in range(game_map.width): visible = libtcod.map_is_in_fov(fov_map, x, y) wall = game_map.tiles[x][y].block_sight if visible: if wall: libtcod.console_put_char_ex(con, x, y, wall_tile, libtcod.white, libtcod.black) else: libtcod.console_put_char_ex(con, x, y, floor_tile, libtcod.white, libtcod.black) game_map.tiles[x][y].explored = True elif game_map.tiles[x][y].explored: if wall: libtcod.console_put_char_ex(con, x, y, wall_tile, libtcod.grey, libtcod.black) else: libtcod.console_put_char_ex(con, x, y, floor_tile, libtcod.grey, libtcod.black) entities_in_render_order = sorted(entities, key=lambda x: x.render_order.value) for entity in entities_in_render_order: draw_entity(con, entity, fov_map, game_map, floor_tile) libtcod.console_set_default_foreground(con, libtcod.white) # Danny code to center player and have window scroll #r = 20 #libtcod.console_blit(con, player.x - r, player.y - r, 2*r+1, 2*r+1, 0, int(screen_width/2) - r, int(screen_height/2) - r) libtcod.console_blit(con, 0, 0, screen_width, screen_height, 0, 0, 0) libtcod.console_set_default_background(panel, libtcod.black) libtcod.console_clear(panel) y = 1 for message in message_log.messages: libtcod.console_set_default_foreground(panel, message.color) libtcod.console_print_ex(panel, message_log.x, y, libtcod.BKGND_NONE, libtcod.LEFT, message.text) y += 1 # DESCRIPTION NAMES (0) libtcod.console_set_default_foreground(panel, libtcod.light_gray) libtcod.console_print_ex(panel, 1, 0, libtcod.BKGND_NONE, libtcod.LEFT, get_names_under_mouse(mouse, entities, fov_map)) # HP BAR (1) render_bar(panel, 1, 1, bar_width, "HP", player.fighter.hp, player.fighter.max_hp, libtcod.light_red, libtcod.darker_red) # MANA BAR (2) render_bar(panel, 1, 2, bar_width, "MANA", player.fighter.mana, player.fighter.max_mana, libtcod.light_purple, libtcod.darker_purple) # EXP BAR (3) render_bar(panel, 1, 3, bar_width, "EXP", player.level.current_xp, player.level.experience_to_next_level, libtcod.light_blue, libtcod.darker_blue) # HEALTH TALISMAN BAR (4) if player.inventory.search("Health Talisman") is not None: render_bar(panel, 1, 4, bar_width, "Talisman HP", player.fighter.talismanhp, player.fighter.max_hp, libtcod.light_red, libtcod.darker_red) # GOLD COUNTER (5) libtcod.console_print_ex(panel, 1, 5, libtcod.BKGND_NONE, libtcod.LEFT, "Gold: {0}".format(player.fighter.gold)) # DUNGEON LEVEL (6) libtcod.console_print_ex( panel, 1, 6, libtcod.BKGND_NONE, libtcod.LEFT, "Dungeon Level: {0}".format(game_map.dungeon_level)) libtcod.console_blit(panel, 0, 0, screen_width, panel_height, 0, 0, panel_y) # BORDERS #libtcod.console_print_ex(con, 0, screen_height - 8, libtcod.BKGND_NONE, libtcod.LEFT, "*" * screen_width) #libtcod.console_print_ex(con, 0, 0, libtcod.BKGND_NONE, libtcod.LEFT, "*" * screen_width) #for i in range(9, screen_height + 1): #libtcod.console_print_ex(con, 0, screen_height - i, libtcod.BKGND_NONE, libtcod.LEFT, "*") #libtcod.console_print_ex(con, screen_width - 1, screen_height - i, libtcod.BKGND_NONE, libtcod.LEFT, "*") # END BORDERS if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY): if game_state == GameStates.SHOW_INVENTORY: inventory_title = "Press the key next to an item to use it, or ESC to cancel.\n" elif game_state == GameStates.DROP_INVENTORY: inventory_title = "Press the key next to an item to drop it, or ESC to cancel.\n" inventory_menu(con, inventory_title, player, 50, screen_width, screen_height) elif game_state in (GameStates.SHOW_EQUIPMENT_INVENTORY, GameStates.DROP_EQUIPMENT): if game_state == GameStates.SHOW_EQUIPMENT_INVENTORY: inventory_title = "Press the key next to an item to equip it, or ESC to cancel.\n" else: inventory_title = "Press the key next to the equipment to drop it, or ESC to cancel.\n" equipment_inventory_menu(con, inventory_title, player, 50, screen_width, screen_height) elif game_state == GameStates.LEVEL_UP: level_up_menu(con, "Level up! Choose a stat to raise:\n", player, 46, screen_width, screen_height) elif game_state == GameStates.CHARACTER_SCREEN: character_screen(player, 30, 10, screen_width, screen_height, kill_count) elif game_state == GameStates.SHOW_BAG: bag_title = "Press the key next to the option to open the bag.\n" bag_menu(con, bag_title, player, 50, screen_width, screen_height) elif game_state == GameStates.HELP_MENU: help_menu(player, 30, 10, screen_width, screen_height) elif game_state == GameStates.QUIT_MENU: quit_title = "ARE YOU SURE YOU WANT\n TO QUIT THE GAME?\n" quit_menu(con, quit_title, player, 21, screen_width, screen_height) elif game_state == GameStates.DROP_MENU: drop_title = "Which inventory would you like to drop items from?" drop_menu(con, drop_title, player, 50, screen_width, screen_height) elif game_state == GameStates.SELL_MENU: shop_title = "Welcome to the Shop!\nWhat would you like to sell?\n" sell_menu(con, shop_title, player, 50, screen_width, screen_height) elif game_state == GameStates.BUY_MENU: shop_title = "Welcome to the Shop!\nWhat would you like to buy?\n" buy_menu(con, shop_title, player, 50, screen_width, screen_height, game_map.shop_items) elif game_state == GameStates.SELL_EQUIPMENT_MENU: shop_title = "Welcome to the Shop!\nWhat would you like to sell?\n" sell_equipment_menu(con, shop_title, player, 50, screen_width, screen_height) elif game_state == GameStates.BUY_EQUIPMENT_MENU: shop_title = "Welcome to the Shop!\nWhat would you like to buy?\n" buy_equipment_menu(con, shop_title, player, 50, screen_width, screen_height, game_map.shop_equipment_items) elif game_state == GameStates.SHOP_MENU: shop_title = "Welcome to the Shop!\nWhat would you like to do?\n" shop_menu(con, shop_title, player, 50, screen_width, screen_height)
def draw(self): if libtcod.map_is_in_fov(fov_map, self.x, self.y): # Set the color and then draw the character that represents this object at its position. libtcod.console_set_default_foreground(con, self.color) libtcod.console_put_char(con, self.x, self.y, self.char, libtcod.BKGND_NONE)
def render_all(): global color_dark_wall, color_light_wall global color_dark_ground, color_light_ground global fov_recompute if fov_recompute: #recompute FOV if needed (such as player movement or spellcasting or light or something) fov_recompute = True libtcod.map_compute_fov(fov_map, player.x, player.y, TORCH_RADIUS, FOV_LIGHT_WALLS, FOV_ALGO) #Go through tiles, set BG color for y in range(MAP_HEIGHT): for x in range(MAP_WIDTH): visible = libtcod.map_is_in_fov(fov_map, x, y) wall = map[x][y].block_sight if not visible: #Even if it isn't visible it should be "remembered" if map[x][y].explored: #out of player FOV if wall: libtcod.console_set_back(con, x, y, color_dark_wall, libtcod.BKGND_SET) else: libtcod.console_set_back(con, x, y, color_dark_ground, libtcod.BKGND_SET) else: #it is visible if wall: libtcod.console_set_back(con, x, y, color_light_wall, libtcod.BKGND_SET) else: libtcod.console_set_back(con, x, y, color_light_ground, libtcod.BKGND_SET) map[x][y].explored = True #Draw all objects in the object list for object in objects: if object != player: object.draw() player.draw() #Blit the contents of the "con" console to the root console libtcod.console_blit(con, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 0) #prepare to render GUI panels libtcod.console_set_background_color(panel, libtcod.black) libtcod.console_clear(panel) #print the game messages one line at a time y = 1 for (line, color) in game_msgs: libtcod.console_set_foreground_color(panel, color) libtcod.console_print_left(panel, MSG_X, y, libtcod.BKGND_NONE, line) y += 1 #show player's stats render_bar(1, 1, BAR_WIDTH, 'HP', player.combat.hp, player.combat.max_hp, libtcod.light_red, libtcod.darker_red) libtcod.console_print_left(panel, 1, 3, libtcod.BKGND_NONE, 'Dungeon level ' + str(dungeon_level)) #Display names of things under mouse libtcod.console_set_foreground_color(panel, libtcod.light_gray) libtcod.console_print_left(panel, 1, 0, libtcod.BKGND_NONE, get_names_under_mouse()) #blit the contents of the 'panel' to the root console libtcod.console_blit(panel, 0, 0, SCREEN_WIDTH, PANEL_HEIGHT, 0, 0, PANEL_Y)
def draw(self, con, fov_map): con = con if libtcod.map_is_in_fov(fov_map, self.x, self.y): libtcod.console_set_default_foreground(con, self.colour) libtcod.console_put_char(con, int(self.x), int(self.y), self.char, libtcod.BKGND_NONE)
def render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, mouse, colors, kill_count, game_state, wall_tile, floor_tile, grass_tile): if fov_recompute: for y in range(game_map.height): for x in range(game_map.width): visible = libtcod.map_is_in_fov(fov_map, x, y) wall = game_map.tiles[x][y].block_sight if game_map.dungeon_level == 0: if visible: if wall: libtcod.console_put_char_ex(con, x, y, wall_tile, libtcod.white, libtcod.black) else: libtcod.console_put_char_ex(con, x, y, grass_tile, libtcod.white, libtcod.black) game_map.tiles[x][y].explored = True elif game_map.tiles[x][y].explored: if wall: libtcod.console_put_char_ex(con, x, y, wall_tile, libtcod.grey, libtcod.black) else: libtcod.console_put_char_ex(con, x, y, grass_tile, libtcod.grey, libtcod.black) else: if visible: if wall: libtcod.console_put_char_ex(con, x, y, wall_tile, libtcod.white, libtcod.black) else: libtcod.console_put_char_ex(con, x, y, floor_tile, libtcod.white, libtcod.black) game_map.tiles[x][y].explored = True elif game_map.tiles[x][y].explored: if wall: libtcod.console_put_char_ex(con, x, y, wall_tile, libtcod.grey, libtcod.black) else: libtcod.console_put_char_ex(con, x, y, floor_tile, libtcod.grey, libtcod.black) entities_in_render_order = sorted(entities, key=lambda x: x.render_order.value) for entity in entities_in_render_order: draw_entity(con, entity, fov_map, game_map, floor_tile) libtcod.console_set_default_foreground(con, libtcod.black) libtcod.console_blit(con, 0, 0, screen_width, screen_height, 0, 0, 0) libtcod.console_set_default_background(panel, libtcod.black) libtcod.console_clear(panel) y = 1 for message in message_log.messages: libtcod.console_set_default_foreground(panel, message.color) libtcod.console_print_ex(panel, message_log.x, y, libtcod.BKGND_NONE,libtcod.LEFT, message.text) y += 1 # 0 - Description names under mouse # 1 - HP # 2 - Talisman Health # 3 - Mana # 4 - EXP # 5 - Status # 6 - Gold # 7 - Dungeon Level libtcod.console_set_default_foreground(panel, libtcod.light_gray) libtcod.console_print_ex(panel, 0, 0, libtcod.BKGND_NONE, libtcod.LEFT, get_names_under_mouse(mouse, entities, fov_map)) # BORDERS #render_line(panel, 0, 1, screen_width, libtcod.darkest_sky) #render_vert(panel, 20, 2, 1, 7, libtcod.darkest_sky) render_bar(panel, 0, 1, bar_width, "HP", player.fighter.hp, player.fighter.max_hp, libtcod.light_red, libtcod.darker_red) if player.inventory.search("Health Talisman") is not None: render_bar(panel, 0, 2, bar_width, "Talisman HP", player.fighter.talismanhp, player.fighter.max_hp, libtcod.light_red, libtcod.darker_red) render_bar(panel, 0, 3, bar_width, "MANA", player.fighter.mana, player.fighter.max_mana, libtcod.dark_purple, libtcod.darker_purple) render_bar(panel, 0, 4, bar_width, "EXP", player.level.current_xp, player.level.experience_to_next_level, libtcod.light_blue, libtcod.darker_blue) else: render_bar(panel, 0, 2, bar_width, "MANA", player.fighter.mana, player.fighter.max_mana, libtcod.dark_purple, libtcod.darker_purple) render_bar(panel, 0, 3, bar_width, "EXP", player.level.current_xp, player.level.experience_to_next_level, libtcod.light_blue, libtcod.darker_blue) if player.fighter.status is not None: status = player.fighter.status.name libtcod.console_print_ex(panel, 0, 6, libtcod.BKGND_NONE, libtcod.LEFT, "Status: {0}".format(status)) libtcod.console_print_ex(panel, 0, 7, libtcod.BKGND_NONE, libtcod.LEFT, "Gold: {0}".format(player.fighter.gold)) if game_map.dungeon_level == 0: libtcod.console_print_ex(panel, 0, 8, libtcod.BKGND_NONE, libtcod.LEFT, "Village") else: libtcod.console_print_ex(panel, 0, 8, libtcod.BKGND_NONE, libtcod.LEFT, "Dungeon Level: {0}".format(game_map.dungeon_level)) libtcod.console_blit(panel, 0, 0, screen_width, panel_height, 0, 0, panel_y) if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY): if game_state == GameStates.SHOW_INVENTORY: inventory_title = "Press the key next to an item to use it, or ESC to cancel.\n" elif game_state == GameStates.DROP_INVENTORY: inventory_title = "Press the key next to an item to drop it, or ESC to cancel.\n" inventory_menu(con, inventory_title, player, 50, screen_width, screen_height) elif game_state in (GameStates.SHOW_EQUIPMENT_INVENTORY, GameStates.DROP_EQUIPMENT): if game_state == GameStates.SHOW_EQUIPMENT_INVENTORY: inventory_title = "Press the key next to an item to equip it, or ESC to cancel.\n" else: inventory_title = "Press the key next to the equipment to drop it, or ESC to cancel.\n" equipment_inventory_menu(con, inventory_title, player, 50, screen_width, screen_height) elif game_state == GameStates.LEVEL_UP: level_up_menu(con, "Level up! Choose a stat to raise:\n", player, 46, screen_width, screen_height) elif game_state == GameStates.CHARACTER_SCREEN: character_screen(player, 30, 10, screen_width, screen_height, kill_count) elif game_state == GameStates.SHOW_BAG: bag_title = "Press the key next to the option to open the bag.\n" bag_menu(con, bag_title, player, 50, screen_width, screen_height) elif game_state == GameStates.HELP_MENU: help_menu(player, 30, 10, screen_width, screen_height) elif game_state == GameStates.QUIT_MENU: quit_title = "ARE YOU SURE YOU WANT\n TO QUIT THE GAME?\n" quit_menu(con, quit_title, player, 21, screen_width, screen_height) elif game_state == GameStates.DROP_MENU: drop_title = "Which inventory would you like to drop items from?" drop_menu(con, drop_title, player, 50, screen_width, screen_height) elif game_state == GameStates.SELL_MENU: shop_title = "Welcome to the Shop!\nWhat would you like to sell?\n" sell_menu(con, shop_title, player, 50, screen_width, screen_height) elif game_state == GameStates.BUY_MENU: shop_title = "Welcome to the Shop!\nWhat would you like to buy?\n" buy_menu(con, shop_title, player, 50, screen_width, screen_height, game_map.shop_items) elif game_state == GameStates.SELL_EQUIPMENT_MENU: shop_title = "Welcome to the Shop!\nWhat would you like to sell?\n" sell_equipment_menu(con, shop_title, player, 50, screen_width, screen_height) elif game_state == GameStates.BUY_EQUIPMENT_MENU: shop_title = "Welcome to the Shop!\nWhat would you like to buy?\n" buy_equipment_menu(con, shop_title, player, 50, screen_width, screen_height, game_map.shop_equipment_items) elif game_state == GameStates.SHOP_MENU: shop_title = "Welcome to the Shop!\nWhat would you like to do?\n" shop_menu(con, shop_title, player, 50, screen_width, screen_height)
def draw_entity(con, entity, fov_map, colors): if libtcod.map_is_in_fov(fov_map, entity.x, entity.y): libtcod.console_set_default_foreground(con, entity.color) libtcod.console_put_char(con, entity.x, entity.y, entity.char, libtcod.BKGND_NONE)
def draw(self): is_visible = libtcod.map_is_in_fov(FOV_MAP, self.x, self.y) if is_visible: SURFACE_MAIN.blit(self.sprite, (self.x * constants.CELL_WIDTH, self.y * constants.CELL_HEIGHT))