This repository has been archived on 2022-12-03. You can view files and clone it, but cannot push or open issues or pull requests.
texty/lib/game.py

162 lines
6.4 KiB
Python
Raw Normal View History

2021-11-02 17:40:54 +01:00
import yaml
from yaml.loader import SafeLoader
from colorama import Fore, Back, Style
2022-01-25 17:16:07 +01:00
import re
2022-02-04 19:35:38 +01:00
from .save import SaveManager
2022-01-26 09:23:30 +01:00
from .ascii import AsciiAnimation
2022-01-25 17:16:07 +01:00
from time import sleep
2022-02-04 19:35:38 +01:00
from os import system, path, mkdir
2021-11-02 17:40:54 +01:00
2022-02-04 19:35:38 +01:00
class Game: # the game class keeps information about the loaded game
2021-11-26 22:13:30 +01:00
def __init__(self,data:dict):
self.name = data["meta"]["name"]
self.author = data["meta"]["creator"]
2021-11-02 17:40:54 +01:00
self.current = "start"
self.nodes = {}
2022-01-26 16:07:31 +01:00
self.inventory = []
2022-02-04 19:35:38 +01:00
self.save = SaveManager()
self.id = data["meta"]["id"]
2021-11-26 22:13:30 +01:00
for k in data["game"]:
self.nodes.update({k:data["game"][k]})
2021-11-02 17:40:54 +01:00
2022-02-04 19:35:38 +01:00
def main_menu(self): # displays the main menu
l = self.save.load()
if not l:
# New game
print(self.name)
print(f"A game by {self.author}")
print("")
print("1 - Start")
print("2 - Options")
print("0 - Quit")
2022-02-23 19:28:50 +01:00
selection = self.make_selection(3)
system("cls||clear")
if(selection == 1): # start new game
self.print_text()
elif(selection == 2):
self.settings_menu()
elif(selection == 0):
print("Quitting")
exit()
2022-02-04 19:35:38 +01:00
else: # Display continue
print(self.name)
print(f"A game by {self.author}")
print("")
print("1 - Continue")
print("2 - New game")
print("3 - Options")
print("0 - Quit")
selection = self.make_selection(3)
system("cls||clear")
if(selection == 1):
self.current = self.save.currentPrompt
self.inventory = self.save.inventory
self.print_text()
elif(selection == 2):
self.print_text()
2022-02-23 19:28:50 +01:00
elif(selection == 3):
self.settings_menu()
elif(selection == 0):
2022-02-04 19:35:38 +01:00
print("Quitting")
exit()
def settings_menu(self): # displays the settings menu
2022-02-27 12:02:46 +01:00
print("Options")
2022-02-04 19:35:38 +01:00
print("")
print("1 - Language")
print("0 - Back")
selection = self.make_selection(1)
if(selection == 1):
print("Language")
print("")
print("1 - English")
print("2 - Czech")
print("0 - Back")
selection = self.make_selection(2)
system("cls||clear")
if(selection == 1):
with open("./saves/lang","w") as f:
f.write("en")
elif(selection == 2):
with open("./saves/lang","w") as f:
f.write("cz")
self.settings_menu()
2022-02-23 19:28:50 +01:00
else:
self.main_menu()
2022-02-04 19:35:38 +01:00
def make_selection(self, length=0) -> int: # this method makes sure a valid selection is made and returns the selection as a number
2022-02-27 12:02:46 +01:00
# TODO: replace with selection by keyboard(?)
2022-02-04 19:35:38 +01:00
l = length # sets the length
if(l == 0): # if no length was set, we get it from nodes
2022-02-23 19:28:50 +01:00
l = len(self.nodes[self.current]["actions"])-1
2022-01-26 16:07:31 +01:00
y = False
selection = 0
# TODO: Check for "has_item"
2022-02-23 19:28:50 +01:00
while y == False: # while the selection is not correct
2022-01-26 16:07:31 +01:00
try:
2022-02-23 19:28:50 +01:00
selection = int(input("Make a selection (number): ")) # ask for selection
except ValueError: # handle wrong input type
2022-01-26 16:07:31 +01:00
print("Not a number selection")
2022-02-23 19:28:50 +01:00
if(selection > l or selection < 0): # if the number is bigger than the length or smaller than 0, print error
2022-01-26 16:07:31 +01:00
print("Invalid selection")
else:
2022-02-23 19:28:50 +01:00
y = True # else return the selection
2022-01-26 16:07:31 +01:00
return selection
2021-11-02 17:40:54 +01:00
2022-02-04 19:35:38 +01:00
def print_text(self): # Prints out the current prompt
2022-02-23 19:28:50 +01:00
system("cls||clear")
2022-01-25 17:16:07 +01:00
animated = re.search(r"(?!{).+(?=})",self.nodes[self.current]["text"]) # find the animated text
if(animated != None):
self.print_animated(animated.group(0))
2022-01-25 17:30:09 +01:00
self.nodes[self.current]["text"] = self.nodes[self.current]["text"].replace("{"+animated.group(0)+"}","") # remove the animated text from the text prompt
2021-12-16 10:12:00 +01:00
print(self.parse_colors(self.nodes[self.current]["text"]))
2021-11-02 17:40:54 +01:00
print("")
ostring = ""
2021-11-26 22:13:30 +01:00
if("actions" in self.nodes[self.current].keys()):
for i,option in enumerate(self.nodes[self.current]["actions"]):
ostring+=f"{i} - {self.nodes[option]['description']}\n"
print(ostring)
2022-01-26 16:07:31 +01:00
sel = self.make_selection()
2022-02-23 19:28:50 +01:00
if "add_item" in self.nodes[self.current]: # if there is an add_inventory key in the node,
2022-01-26 16:07:31 +01:00
# add item to inventory
self.inventory.append(self.nodes[self.current]["add_inventory"])
self.current = self.nodes[self.current]["actions"][sel]
2022-02-23 19:28:50 +01:00
self.save.currentPrompt = self.current # save the current prompt
2022-01-25 17:16:07 +01:00
self.print_text()
2022-02-04 19:35:38 +01:00
def print_animated(self,animid): # prinst the first found occurence of an ascii animation
2022-01-26 09:23:30 +01:00
animation = AsciiAnimation()
animation.load_ascii(animid)
2022-01-26 09:25:24 +01:00
for frame in animation.frames:
2022-01-25 17:30:09 +01:00
system("cls||clear")
2022-01-25 17:16:07 +01:00
print(frame)
2022-01-26 09:25:24 +01:00
sleep(animation.speed)
2022-01-25 17:30:09 +01:00
print()
2022-01-25 17:16:07 +01:00
2022-02-04 19:35:38 +01:00
def parse_colors(self,text:str) -> str: # Converts color codes into terminal colors
2021-12-02 11:20:39 +01:00
newText = text.replace("&b",Fore.CYAN).replace("&c",Fore.RED).replace("&e", Fore.YELLOW).replace("&a",Fore.GREEN).replace("&9",Fore.BLUE).replace("&r",Fore.RESET).replace("&f",Fore.WHITE).replace("&5",Fore.MAGENTA).replace("\n",Fore.RESET + "\n") # replace color codes and newlines with colorama
2021-11-26 22:13:30 +01:00
newText += Fore.RESET # reset color at the end of the text
return newText
2021-11-02 17:40:54 +01:00
2022-02-04 19:35:38 +01:00
def load(file_path): # starts to load the game from YAML
lang = "en"
if not (path.exists("./saves/lang")):
mkdir("./saves")
with open("./saves/lang","w") as f:
f.write("en")
else:
with open("./saves/lang","r") as f:
lang = f.read()
if lang == "cz":
lang = "cz"
2021-11-26 22:13:30 +01:00
try:
with open(file_path) as f:
data = yaml.load(f,Loader=SafeLoader)
g = Game(data)
2022-02-04 19:35:38 +01:00
g.lang = lang
2021-11-26 22:13:30 +01:00
return g
except Exception as e:
2021-12-16 10:12:00 +01:00
print(f"{Back.RED}{Fore.WHITE}An exception has occured while loading the game from the YAML file:{Fore.RESET}{Back.RESET}")
2021-11-26 22:13:30 +01:00
print(e)
2022-01-26 09:23:30 +01:00
return None