Skip to content

Commit aece7cd

Browse files
committed
2 parents 7524eac + cf997d8 commit aece7cd

File tree

1 file changed

+351
-0
lines changed

1 file changed

+351
-0
lines changed

source/interface.py

+351
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,351 @@
1+
import os
2+
import platform
3+
import psycopg2
4+
from colorama import Fore, Style, init
5+
from create_character import Character
6+
from queries.query import get_subregions_character, list_all_characters, list_npcs_subregion, list_item_inventory, list_enemys_subregion, get_enemy_info, get_civilian_info
7+
from utils import debug
8+
from combat import Combate, verificar_percepcao, Inimigo
9+
import time
10+
11+
# Initialize colorama
12+
init()
13+
14+
# Clean the terminal screen
15+
def clear_screen():
16+
if platform.system() == "Windows":
17+
os.system("cls")
18+
else:
19+
os.system("clear")
20+
21+
def show_title():
22+
print("")
23+
print(" ██╗ ██╗███╗ ██╗██╗███╗ ███╗ █████╗ ███╗ ██╗ ██████╗███████╗██████╗ ")
24+
print(" ██║ ██║████╗ ██║██║████╗ ████║██╔══██╗████╗ ██║██╔════╝██╔════╝██╔══██╗")
25+
print(" ██║ ██║██╔██╗ ██║██║██╔████╔██║███████║██╔██╗ ██║██║ █████╗ ██████╔╝")
26+
print(" ██║ ██║██║╚██╗██║██║██║╚██╔╝██║██╔══██║██║╚██╗██║██║ ██╔══╝ ██╔══██╗")
27+
print(" ╚██████╔╝██║ ╚████║██║██║ ╚═╝ ██║██║ ██║██║ ╚████║╚██████╗███████╗██║ ██║")
28+
print(" ╚═════╝ ╚═╝ ╚═══╝╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝╚══════╝╚═╝ ╚═╝")
29+
print("")
30+
31+
# Show initial menu of the game and return option chosen.
32+
def show_menu() -> str:
33+
def ask():
34+
return input("Escolha uma opção: ").lower()
35+
36+
print(Style.BRIGHT + Fore.YELLOW + "\n--- Bem-vindo ao Unimancer! ---" + Style.RESET_ALL)
37+
print("criar: criar um novo personagem;")
38+
print("listar: Liste os personagens existentes")
39+
print("sair: sair do jogo.")
40+
41+
option = ask()
42+
while option not in ["criar", "sair", "listar"]:
43+
print("Opção inválida!")
44+
option = ask()
45+
return option
46+
47+
# Display player header information
48+
def header(character):
49+
clear_screen()
50+
print(f"=== {character.nome} === vida: {character.vida}/{character.vida_maxima} "
51+
f"energia arcana: {character.energia_arcana}/{character.energia_arcana_maxima} "
52+
f"moedas: {character.moedas} xp: {character.xp}/{character.xp_total} ===")
53+
54+
# Display player inventory
55+
def inventory(character, conn):
56+
clear_screen()
57+
print(f"Inventário de === {character.nome} ===")
58+
print("-" * 40)
59+
60+
items = list_item_inventory(conn, character.id)
61+
62+
if not items:
63+
print("O inventário está vazio.")
64+
else:
65+
for item in items:
66+
nome, descricao, qtd = item
67+
print(f"- {nome} ({descricao}) - {qtd}")
68+
69+
print("-" * 40)
70+
71+
def list_spells(conn, character_id):
72+
with conn.cursor() as cur:
73+
cur.execute("""
74+
SELECT feitico.descricao, feitico.energia_arcana
75+
FROM inventario
76+
JOIN feitico_aprendido ON inventario.id = feitico_aprendido.inventario_id
77+
JOIN feitico ON feitico_aprendido.feitico_id = feitico.id
78+
WHERE inventario.personagem_id = %s;
79+
""", (character_id,))
80+
81+
spells = cur.fetchall()
82+
83+
clear_screen()
84+
print(Style.BRIGHT + Fore.CYAN + f"\n--- Feitiços Disponíveis ---\n" + Style.RESET_ALL)
85+
86+
if not spells:
87+
print(Fore.RED + "Nenhum feitiço aprendido." + Style.RESET_ALL)
88+
else:
89+
for descricao, custo in spells:
90+
print(Fore.CYAN + f" Custo de energia: {custo}" + Style.RESET_ALL)
91+
print(f" {descricao}")
92+
print("-" * 40)
93+
94+
input("\nPressione Enter para continuar...")
95+
96+
97+
def show_enemies(conn, character):
98+
enemys = list_enemys_subregion(conn, character.sub_regiao_id)
99+
if enemys:
100+
print(Fore.YELLOW + "\n--- Inimigos na Região ---" + Style.RESET_ALL)
101+
for idx, enemy in enumerate(enemys, start=1):
102+
enemy_id, enemy_name, enemy_descricao, *_ = enemy
103+
print(f"{idx}. {enemy_name} - {enemy_descricao}")
104+
else:
105+
print(Fore.GREEN + "Nenhum inimigo nesta sub-região." + Style.RESET_ALL)
106+
return enemys
107+
108+
109+
# Show available subregions and handle navigation
110+
def display_subregion_info(conn, character):
111+
print(Fore.CYAN + "\n ----- Descrição -------" + Style.RESET_ALL)
112+
rg = get_subregion_description(conn, character)
113+
print(f"{rg[0][1]} - {rg[0][0]}")
114+
115+
print(Fore.YELLOW + "\n--- Locais Disponíveis ---" + Style.RESET_ALL)
116+
subregions = get_subregions_character(conn, character.sub_regiao_id)
117+
if subregions:
118+
for idx, (destino, direcao, situacao) in enumerate(subregions, start=1):
119+
print(f"{idx}. {destino} ({direcao}) - Situação: {situacao}")
120+
else:
121+
print("Nenhum local disponível.")
122+
123+
return subregions
124+
125+
def display_enemies(conn, character, check):
126+
enemys = list_enemys_subregion(conn, character.sub_regiao_id)
127+
if enemys and check:
128+
print(Fore.YELLOW + "\n--- Verificando Percepção dos Inimigos ---" + Style.RESET_ALL)
129+
time.sleep(1)
130+
print(Style.BRIGHT + Fore.YELLOW + "." + Style.RESET_ALL)
131+
time.sleep(1)
132+
print(Style.BRIGHT + Fore.YELLOW + "." + Style.RESET_ALL)
133+
time.sleep(1)
134+
print(Style.BRIGHT + Fore.YELLOW + "." + Style.RESET_ALL)
135+
time.sleep(1)
136+
137+
138+
for enemy in enemys:
139+
enemy_id, enemy_name, *_ = enemy
140+
enemy_info = get_enemy_info(conn, enemy_id)
141+
inimigo_instanciado = Inimigo(*enemy_info)
142+
inimigo_percebeu = verificar_percepcao(character, [inimigo_instanciado])
143+
144+
if inimigo_percebeu:
145+
inimigo_percebeu = (
146+
inimigo_percebeu.nome,
147+
inimigo_percebeu.id,
148+
inimigo_percebeu.armazenamento_id,
149+
inimigo_percebeu.descricao,
150+
inimigo_percebeu.elemento,
151+
inimigo_percebeu.vida,
152+
inimigo_percebeu.vida_maxima,
153+
inimigo_percebeu.xp_obtido,
154+
inimigo_percebeu.inteligencia,
155+
inimigo_percebeu.moedas_obtidas,
156+
inimigo_percebeu.conhecimento_arcano,
157+
inimigo_percebeu.energia_arcana_maxima
158+
)
159+
combate = Combate(character, inimigo_percebeu, conn)
160+
combate.iniciar()
161+
clear_screen()
162+
display_subregion_info(conn, character)
163+
show_enemies(conn, character)
164+
if character.vida <= 0:
165+
print(Fore.RED + "Você foi derrotado no combate..." + Style.RESET_ALL)
166+
return
167+
return enemys
168+
169+
def display_npcs(conn, character):
170+
print(Fore.YELLOW + "\n--- Personagens ---" + Style.RESET_ALL)
171+
npcs = list_npcs_subregion(conn, character.sub_regiao_id)
172+
if npcs:
173+
for npc in npcs:
174+
nome, tipo = npc
175+
print(f"{nome} - ({tipo})")
176+
else:
177+
print("Nenhum personagem encontrado.")
178+
179+
return npcs
180+
181+
def display_npc_info(npc_nome, npc_tipo, conn):
182+
descricao = get_civilian_info(conn, npc_nome)
183+
print(Fore.CYAN + "\n--- Ficha do Personagem ---" + Style.RESET_ALL)
184+
print(Fore.GREEN + f"Nome: {descricao['nome']}" + Style.RESET_ALL)
185+
print(Fore.GREEN + f"Descrição: {descricao['descricao']}" + Style.RESET_ALL)
186+
print(Fore.MAGENTA + "\n.." + Style.RESET_ALL)
187+
time.sleep(1)
188+
189+
if npc_tipo == "Quester":
190+
get_quest(npc_nome)
191+
input("Pressione Enter para continuar...")
192+
else:
193+
print(Fore.RED + f"{npc_nome} não tem nada a dizer." + Style.RESET_ALL)
194+
print(Fore.MAGENTA + "Pressione 0 para voltar ao menu." + Style.RESET_ALL)
195+
input()
196+
197+
def handle_player_choice(conn, character, subregions, npcs, enemys):
198+
try:
199+
choice_interaction = input("\nO que você deseja fazer agora?\n0-Voltar\n1-Continuar caminhando\n2-Interagir com um personagem\n3-Lutar: \n")
200+
201+
if choice_interaction == "0":
202+
return False
203+
204+
elif choice_interaction == "1": # change current location
205+
if subregions:
206+
choice = int(input("\nEscolha uma direção: "))
207+
if 1 <= choice <= len(subregions):
208+
destino, direcao, situacao = subregions[choice - 1]
209+
if situacao == "Passável":
210+
print(f"\nVocê se moveu para: {destino} ({direcao}).")
211+
character.sub_regiao_id = fetch_subregion_id_by_name(destino, conn)
212+
else:
213+
print("\nEssa passagem está bloqueada!")
214+
else:
215+
print("\nOpção inválida!")
216+
else:
217+
print("Nenhuma sub-região para navegar.")
218+
219+
navigate(conn, character)
220+
221+
elif choice_interaction == "2": # Interact with npcs
222+
npcs = list_npcs_subregion(conn, character.sub_regiao_id)
223+
if npcs:
224+
npc_choice = int(input("Escolha um personagem (número): "))
225+
if 1 <= npc_choice <= len(npcs):
226+
npc_nome, npc_tipo = npcs[npc_choice - 1]
227+
display_npc_info(npc_nome, npc_tipo, conn)
228+
else:
229+
print("\nOpção inválida!")
230+
else:
231+
print("Nenhum NPC disponível para interação.")
232+
233+
elif choice_interaction == "3": # Fight with an enemy
234+
if enemys:
235+
result = int(input("Escolha um inimigo: "))
236+
if result != 0 and 1 <= result <= len(enemys):
237+
enemy_id = enemys[result - 1][0]
238+
enemy_info = get_enemy_info(conn, enemy_id)
239+
combate = Combate(character, enemy_info, conn)
240+
combate.iniciar()
241+
else:
242+
print("\nOpção inválida!")
243+
else:
244+
print("Nenhum inimigo disponível para combate.")
245+
246+
else:
247+
print("\nOpção inválida!")
248+
return True
249+
250+
except ValueError:
251+
print("\nEntrada inválida! Escolha um número correspondente ou '0'.")
252+
return True
253+
254+
def navigate(conn, character):
255+
check = 1
256+
while True:
257+
clear_screen()
258+
subregions = display_subregion_info(conn, character)
259+
show_enemies(conn, character)
260+
enemys = display_enemies(conn, character, check)
261+
check = 0
262+
npcs = display_npcs(conn, character)
263+
264+
if not handle_player_choice(conn, character, subregions, npcs, enemys):
265+
break
266+
267+
# Function to change actual subregion
268+
def fetch_subregion_id_by_name(name, conn):
269+
with conn.cursor() as cur:
270+
cur.execute("SELECT DISTINCT id FROM sub_regiao WHERE nome = %s", (name,))
271+
result = cur.fetchone()
272+
return result[0] if result else None
273+
274+
# Function to get subregion description
275+
def get_subregion_description(conn, character):
276+
try:
277+
with conn.cursor() as cur:
278+
cur.execute(f"SELECT descricao, nome FROM sub_regiao WHERE id = {character.sub_regiao_id}")
279+
result = cur.fetchall()
280+
return result
281+
except psycopg2.Error as e:
282+
print(f"Erro ao obter descrição da sub-região: {e}")
283+
conn.rollback()
284+
return "Erro ao acessar a descrição."
285+
286+
def get_quest(npc_nome):
287+
print(f"Você recebeu uma missão de {npc_nome}.")
288+
# Adicione mais lógica conforme necessário
289+
290+
# Main game loop
291+
def game_loop(conn):
292+
ok = False
293+
while(ok == False):
294+
clear_screen()
295+
show_title()
296+
option = show_menu()
297+
characters = list_all_characters(conn)
298+
299+
if option == "sair":
300+
print("Saindo do jogo...")
301+
return
302+
303+
elif option == "listar":
304+
if not characters:
305+
clear_screen()
306+
print(Fore.RED + "Nenhum personagem encontrado" + Style.RESET_ALL)
307+
input("\nPressione Enter para continuar...")
308+
ok = False
309+
else:
310+
for idx, character in enumerate(characters, start=1):
311+
print(f"\n Personagem: {idx}, ID: {character[0]}, nome: {character[1]}, elemento: {character[2]}")
312+
313+
personagem_id = input("Escolha um personagem (id): ")
314+
character = Character(conn, personagem_id)
315+
debug(f"Personagem {character.nome} selecionado com sucesso!")
316+
ok = True
317+
318+
elif option == "criar":
319+
character = Character(conn)
320+
character.add_database()
321+
character.define_initial_spells(conn)
322+
character.add_initial_items(conn)
323+
debug(f"Personagem {character.nome} criado com sucesso!")
324+
ok = True
325+
326+
while True:
327+
show_title()
328+
clear_screen()
329+
print(Fore.CYAN + "\n--- Menu Principal ---" + Style.RESET_ALL)
330+
print("1. Navegar")
331+
print("2. Ver status do personagem")
332+
print("3. Ver Inventário")
333+
print("4. Ver feitiços")
334+
print("5. Sair")
335+
336+
option = input("Escolha uma opção: ").lower()
337+
if option == "1":
338+
navigate(conn, character)
339+
elif option == "2":
340+
header(character)
341+
input("\nPressione Enter para continuar...")
342+
elif option == "3":
343+
inventory(character, conn)
344+
input("\nPressione Enter para continuar...")
345+
elif option == "4":
346+
list_spells(conn, character.id)
347+
elif option == "5":
348+
print("Saindo do jogo...")
349+
break
350+
else:
351+
print("Opção inválida!")

0 commit comments

Comments
 (0)