Complete fighting and squash bugs

This commit is contained in:
Matyáš Caras 2022-05-04 10:16:30 +02:00 committed by GitHub
parent 04538bae36
commit 860b98f1a9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 127 additions and 31 deletions

View file

@ -1,16 +1,16 @@
import math
from lib.menu import MenuManager
from .ascii import *
from colorama import Fore
import keyboard
from random import randrange
class FightHandler:
def __init__(self,message:str,name:str,hp:int,defense:int,attacks:dict,lang:dict,eq:dict,img:str="") -> None:
def __init__(self,message:str,name:str,hp:int,defense:int,attacks:dict,lang:dict,eq:dict,inv:list,img:str="") -> None:
self.selected = 0
keyboard.add_hotkey("up",self.up)
keyboard.add_hotkey("down",self.down)
keyboard.add_hotkey("enter",self.attack)
self.rebind()
self.name = name
self.max = hp # starting ENEMY HP
self.hp = self.max # current ENEMY HP
@ -21,6 +21,7 @@ class FightHandler:
self.lang = lang
self.message = message
self.equipped = eq
self.inventory = inv
self.show()
def up(self):
@ -40,6 +41,7 @@ class FightHandler:
self.show()
def show(self):
system("cls||clear")
p = math.trunc(self.hp/self.max*10)
h = "🟥"*p
if str(p).endswith(".5"):
@ -57,6 +59,39 @@ class FightHandler:
else:
print(f" {selection}")
def make_selection(self) -> None:
if self.selected == 0:
self.attack()
elif self.selected == 1:
self.defend()
elif self.selected == 2:
self.show_inventory()
def rebind(self):
keyboard.remove_all_hotkeys()
keyboard.add_hotkey("up",self.up)
keyboard.add_hotkey("down",self.down)
keyboard.add_hotkey("enter",self.make_selection)
def show_inventory(self): # Basically `Game` show_inventory
system("cls||clear")
if len(self.inventory) == 0:
FightMenu([self.lang["return"]],f" {self.lang['inside_inv']} \n")
else:
s = ""
for i,item in enumerate(self.inventory):
if type(item) is not str:
if(i == len(self.inventory)): # last item
s += f"- {item.name}"
else:
s += f"- {item.name}\n"
else:
if(i == len(self.inventory)): # last item
s += f"- {item}"
else:
s += f"- {item}\n"
FightMenu([self.lang["return"]],f" {self.lang['inside_inv']} \n{s}")
def attack(self):
p = randrange(len(self.attacks))
name = list(self.attacks[p].keys())[0]
@ -70,3 +105,13 @@ class FightHandler:
def defend(self):
self.message = self.lang["defended"]
class FightMenu(MenuManager):
def __init__(self,selections:list,additional:str):
self.selected = 0 # current selection
self.selections = selections # available selections
self.additional = additional # additional text to display above the menu
keyboard.add_hotkey("up",self.up)
keyboard.add_hotkey("down",self.down)
keyboard.add_hotkey("enter",self.make_selection)
self.show_menu()

View file

@ -2,6 +2,7 @@ import yaml
from yaml.loader import SafeLoader
from colorama import Fore, Back
import re
from lib.item import Item
from lib.menu import HasItemDialogue, MenuManager
from .save import SaveManager
@ -11,14 +12,15 @@ from time import sleep
from os import system
class Game: # the game class keeps information about the loaded game
def __init__(self,data:dict):
def __init__(self,data:dict,lang):
self.name = data["meta"]["name"] # Game name
self.author = data["meta"]["creator"] # Game creator
self.current = "start" # Current prompt
self.nodes = {} # All nodes
self.inventory = [] # Player's inventory
self.id = data["meta"]["id"] # Game ID
self.save = SaveManager(self.id) # saving
self.lang = lang # Language strings
self.save = SaveManager(self.id,self.lang) # saving
self.equipped = {"weapon":None,"armor":None} # Items equipped by player
self.enemies = {} # Enemies
if "equippable" in data["meta"].keys():
@ -134,10 +136,27 @@ class Game: # the game class keeps information about the loaded game
elif "fight" in self.nodes[self.current].keys():
# Initiate a fight
enemy = self.enemies[self.nodes[self.current]["fight"]] # TODO: Complete after fight actions
s = FightHandler(self.nodes[self.current]["text"],enemy["name"],enemy["hp"],enemy["def"],enemy["attacks"],self.lang,self.equipped)
while s.hp > 0:
s.show()
m = FightHandler(self.nodes[self.current]["text"],enemy["name"],enemy["hp"],enemy["def"],enemy["attacks"],self.lang,self.equipped,self.inventory)
input()
while m.hp > 0 and m.my > 0:
m.show()
m.rebind() # rebind due to MenuManager in show_inventory
input()
system("cls||clear")
keyboard.remove_all_hotkeys()
if m.hp < 1:
# Enemy defeated
print(self.lang["defeated"].replace("$enemy",enemy["name"]))
sleep(5)
self.current = self.nodes[self.current]["actions"][0] # move to the first action
self.print_text()
return
else:
# Player defeated
print(self.lang["defeat"].replace("$enemy",enemy["name"]))
sleep(5)
self.print_text()
return
else:
m = MenuManager(actions_desc,self.parse_colors(self.nodes[self.current]["text"]))
sel = m.selected
@ -161,10 +180,16 @@ class Game: # the game class keeps information about the loaded game
else:
s = ""
for i,item in enumerate(self.inventory):
if(i == len(self.inventory)): # last item
s += f"- {item}"
if type(item) is Item:
if(i == len(self.inventory)): # last item
s += f"- {item.name}"
else:
s += f"- {item.name}\n"
else:
s += f"- {item}\n"
if(i == len(self.inventory)): # last item
s += f"- {item}"
else:
s += f"- {item}\n"
MenuManager([self.lang["return"]],f" {self.lang['inside_inv']} \n{s}")
self.print_text()
@ -183,20 +208,9 @@ def load(file_path,lang): # starts to load the game from YAML
try:
with open(file_path) as f:
data = yaml.load(f,Loader=SafeLoader)
g = Game(data)
g.lang = lang
g = Game(data,lang)
return g
except Exception as e:
print(f"{Back.RED}{Fore.WHITE}ERROR{Fore.RESET}{Back.RESET}")
print(e)
return None
class Item:
def __init__(self,name:str,attack:int = 0,defense:int = 0) -> None:
self.name = name
if attack == 0 and defense > 0:
self.type = "armor"
else:
self.type = "weapon"
self.attack = attack
self.defense = defense
return None

9
lib/item.py Normal file
View file

@ -0,0 +1,9 @@
class Item:
def __init__(self,name:str,attack:int = 0,defense:int = 0) -> None:
self.name = name
if attack == 0 and defense > 0:
self.type = "armor"
else:
self.type = "weapon"
self.attack = attack
self.defense = defense

View file

@ -29,6 +29,9 @@ defend: "Bránit se"
enemydmg: "$name dostal zásah za $atk bodů!"
playerdmg: "Nepřítel použil $name a poškodil tě za $atk bodů."
defended: "Rozhodneš se bránit a nedostal jsi tak žádný zásah."
defeated: "Porazil jsi $enemy."
defeat: "$enemy tě zabil. Budeš to muset zkusit znovu."
error_loading: 'Při načítání YAML souboru nastala chyba:'
no_action: 'Chyba: žádná akce "$action" nenalezena v souboru hry'
no_comp: "VAROVÁNÍ: Tato uložená hra je pro starší verzi enginu a nemusí být kompatibilní!"

View file

@ -29,6 +29,9 @@ defend: "Defend"
enemydmg: "$name took $atk damage!"
playerdmg: "The enemy used $name to damage you by $atk"
defended: "You decide to defend yourself and take no damage."
defeated: "You have defeated $enemy."
defeat: "$enemy has slain you. You'll have to try again."
error_loading: 'An exception has occured while loading the game from the YAML file'
no_action: 'Error: No action "$action" found in the game file.'
no_action: 'Error: No action "$action" found in the game file.'
no_comp: "WARNING: This save is for an older version of the engine and may not be compatible!"

View file

@ -15,7 +15,7 @@ class MenuManager:
self.show_menu()
input()
def make_selection(self) -> int:
def make_selection(self) -> None:
keyboard.remove_all_hotkeys()
def up(self):

View file

@ -1,22 +1,44 @@
from os import path
from time import sleep
from os import path, system
import yaml
from lib.game import Item
class SaveManager: # manages save and configuration files
def __init__(self,gid:str):
def __init__(self,gid:str,lang):
self.id = gid # game ID
self.currentPrompt = "" # Current prompt
self.inventory = [] # Items in inventory
self.version = 1
self.lang = lang
def load(self):
if(path.exists(f"./saves/{self.id}.yml")):
with open(f"./saves/{self.id}.yml",encoding="utf-8") as f:
data = yaml.load(f,Loader=yaml.SafeLoader)
self.currentPrompt = data["currentPrompt"]
self.inventory = data["inventory"]
if(data["version"] < self.version):
system("cls||clear")
print(self.lang["no_comp"])
sleep(5)
inv = []
for item in data["inventory"]:
if type(item) is str:
inv.append(item)
else:
# Item class
inv.append(Item(item["name"],item["atk"],item["def"]))
return True
return False
def save(self):
data = {"id":self.id,"currentPrompt":self.currentPrompt,"inventory":self.inventory}
inv = []
for item in self.inventory:
if type(item) is str:
inv.append(item)
else:
# Item class
inv.append({"name":item.name,"atk":item.attack,"def":item.defense})
data = {"id":self.id,"currentPrompt":self.currentPrompt,"inventory":self.inventory,"version":1}
with open(f"./saves/{self.id}.yml",mode="w",encoding="utf-8") as f:
yaml.dump(data,f)