Complete fighting and squash bugs
This commit is contained in:
parent
04538bae36
commit
860b98f1a9
7 changed files with 127 additions and 31 deletions
53
lib/fight.py
53
lib/fight.py
|
@ -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()
|
56
lib/game.py
56
lib/game.py
|
@ -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
9
lib/item.py
Normal 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
|
|
@ -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í!"
|
|
@ -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!"
|
|
@ -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):
|
||||
|
|
30
lib/save.py
30
lib/save.py
|
@ -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)
|
||||
|
|
Reference in a new issue