-
Notifications
You must be signed in to change notification settings - Fork 0
/
render_functions.py
140 lines (107 loc) · 6.67 KB
/
render_functions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import tcod as libtcod
from enum import Enum, auto
from game_states import GameStates
from menus import inventory_menu, entity_description, level_up_menu, character_screen, message_box, role_menu
from fov_functions import recompute_fov
import math
class RenderOrder(Enum):
STAIRS = auto()
CORPSE = auto()
ITEM = auto()
ACTOR = auto()
def render_bar(panel, x, y, total_width, name, value, maximum, bar_color, back_color):
bar_width = int(float(value) / maximum * total_width)
libtcod.console_set_default_background(panel, back_color)
libtcod.console_rect(panel, x, y, total_width, 1, False, libtcod.BKGND_SCREEN)
libtcod.console_set_default_background(panel, bar_color)
if bar_width > 0:
libtcod.console_rect(panel, x, y, bar_width, 1, False, libtcod.BKGND_SCREEN)
libtcod.console_set_default_foreground(panel, libtcod.white)
libtcod.console_print_ex(panel, int(x + total_width / 2), y, libtcod.BKGND_NONE, libtcod.CENTER, '{0}: {1}/{2}'.format(name, value, maximum))
def render_all(con, panel, mouse, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, colors, game_state, description_list, description_index, cursor_radius, target_fov_map, fov_map_no_walls):
# 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, game_map)
libtcod.console_blit(con, 0, 0, screen_width, screen_height, 0, 0, 0)
draw_cursor(mouse, cursor_radius, game_state, target_fov_map, fov_map_no_walls, screen_width, screen_height)
#clear info 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 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_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.'
else:
inventory_title = 'Press the key next to an item to drop it, or Esc to cancel.'
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, screen_width, screen_height)
elif len(description_list) > 0:
entity_description(con, description_list, description_index, 50, screen_width, screen_height)
def clear_all(con, entities):
for entity in entities:
clear_entity(con, entity)
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) or (entity.item 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 clear_entity(con, entity):
# erase the character that represents this object
libtcod.console_put_char(con, entity.x, entity.y, ' ', libtcod.BKGND_NONE)
def draw_cursor(mouse, cursor_radius, game_state, target_fov_map, fov_map_no_walls, screen_width, screen_height):
#Checks to see that the item we are using has no radius so that we dont waste time computing a target reticule
if cursor_radius == 1 or cursor_radius == None:
cursor = libtcod.console_new(1, 1)
libtcod.console_set_default_foreground(cursor, libtcod.white)
cursor.draw_rect(0, 0, 1, 1, 0, bg=libtcod.white)
libtcod.console_blit(cursor, 0, 0, 1, 1, 0, mouse.cx, mouse.cy, 1.0, 0.7)
# If we have a radius greater than one then draw a circle with a radius of cursor_radius. Game state needs to be targetting, this makes it so when we cancel targetting our cursor goes back to normal
elif game_state == GameStates.TARGETING:
#I needed to add a buffer to the screen width otherwise the targeting reticule would wrap to the otehr side of the screen when it was on the left side.
cursor = libtcod.console.Console(screen_width + 20, screen_height)
libtcod.console_set_default_background(cursor, [245, 245, 245])
libtcod.console_set_key_color(cursor, [245, 245, 245])
cursor.draw_rect(0,0, screen_width, screen_height,0,bg=[245, 245, 245])
#Compute FOV from the cursors perspective. This makes it so walls etc. will block our reticule from showing green
recompute_fov(target_fov_map, mouse.cx, mouse.cy, cursor_radius, light_walls=False, algorithm=libtcod.FOV_RESTRICTIVE)
#Check all coords within the target radius from our cursors
for x in range(mouse.cx - cursor_radius, mouse.cx + cursor_radius + 1):
for y in range(mouse.cy - cursor_radius, mouse.cy + cursor_radius + 1):
if math.sqrt((x - mouse.cx) ** 2 + (y - mouse.cy) ** 2) <= cursor_radius:
#This FOV is computer from the player perspective, but with walls not lighting. This makes it so that if our cursors is on a wall the reticule will be red.
if not libtcod.map_is_in_fov(fov_map_no_walls, x, y):
cursor.draw_rect(x,y,1,1,0,bg=libtcod.red)
#Check FOV of the cursors so that walls will block our reticule. If coordinate is in FOV we color it green.
elif libtcod.map_is_in_fov(target_fov_map, x, y):
cursor.draw_rect(x,y,1,1,0,bg=libtcod.light_green)
else:
cursor.draw_rect(x,y,1,1,0,bg=libtcod.red)
libtcod.console_blit(cursor, 0, 0, 0, 0, 0,0, 0, 0, 0.4)