From 0e6858f566e78c88dfda3321bf4195b31a7bf9fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maty=C3=A1=C5=A1=20Caras?= Date: Fri, 4 Feb 2022 19:35:38 +0100 Subject: [PATCH] WIP saves and languages --- README.md | 2 +- __main__.py | 2 +- example.yml | 1 + lib/game.py | 98 +++++++++++++++++++++++++++++++++++++++---------- lib/lang/cz.yml | 1 + lib/lang/en.yml | 1 + lib/save.py | 23 ++++++++++++ 7 files changed, 106 insertions(+), 22 deletions(-) create mode 100644 lib/lang/cz.yml create mode 100644 lib/lang/en.yml create mode 100644 lib/save.py diff --git a/README.md b/README.md index dfd60ef..f9cc3e1 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # texty -An extremely simple text-adventure game engine(?) +An extremely simple text-adventure game ~~engine(?)~~ player ## What is this? I was bored diff --git a/__main__.py b/__main__.py index 0087c17..1ba0016 100644 --- a/__main__.py +++ b/__main__.py @@ -11,7 +11,7 @@ def main(): # TODO: Maybe a menu for available text games? game = load(argv[1]) if(game is None): exit(1) - game.print_text() + game.main_menu() if __name__ == "__main__": main() \ No newline at end of file diff --git a/example.yml b/example.yml index 54540d0..80932f4 100644 --- a/example.yml +++ b/example.yml @@ -1,5 +1,6 @@ meta: # make sure every key is in lowercase name: "My Text Adventure" # Game name + id: "examplegame" # An original game ID (please try to be original) creator: "hernik" # Your name as a creator game: # here goes all the game logic diff --git a/lib/game.py b/lib/game.py index d0b766f..400b7e5 100644 --- a/lib/game.py +++ b/lib/game.py @@ -2,21 +2,80 @@ import yaml from yaml.loader import SafeLoader from colorama import Fore, Back, Style import re +from .save import SaveManager from .ascii import AsciiAnimation from time import sleep -from os import system +from os import system, path, mkdir -class Game: +class Game: # the game class keeps information about the loaded game def __init__(self,data:dict): self.name = data["meta"]["name"] self.author = data["meta"]["creator"] self.current = "start" self.nodes = {} self.inventory = [] + self.save = SaveManager() + self.id = data["meta"]["id"] for k in data["game"]: self.nodes.update({k:data["game"][k]}) - def make_selection(self) -> int: + 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") + 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() + else: + print("Quitting") + exit() + + def settings_menu(self): # displays the settings menu + print("Settings") + 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() + pass + + def make_selection(self, length=0) -> int: # this method makes sure a valid selection is made and returns the selection as a number + l = length # sets the length + if(l == 0): # if no length was set, we get it from nodes + l = len(self.nodes[self.current]["actions"]) y = False selection = 0 # TODO: Check for "has_item" @@ -31,10 +90,7 @@ class Game: y = True return selection - def print_text(self): - ''' - Used to print out the current prompt with the options - ''' + def print_text(self): # Prints out the current prompt animated = re.search(r"(?!{).+(?=})",self.nodes[self.current]["text"]) # find the animated text if(animated != None): self.print_animated(animated.group(0)) @@ -51,14 +107,10 @@ class Game: # add item to inventory self.inventory.append(self.nodes[self.current]["add_inventory"]) self.current = self.nodes[self.current]["actions"][sel] + self.save.currentPrompt = self.nodes[self.current]["actions"][sel] # save the current prompt self.print_text() - def print_animated(self,animid): - ''' - Used to print out animated text, - currently only prints out the first occurence of an animated text - (in curly braces) - ''' + def print_animated(self,animid): # prinst the first found occurence of an ascii animation animation = AsciiAnimation() animation.load_ascii(animid) for frame in animation.frames: @@ -67,22 +119,28 @@ class Game: sleep(animation.speed) print() - - def parse_colors(self,text:str) -> str: - ''' - Used to convert color codes in string to colors from the colorama lib - ''' + def parse_colors(self,text:str) -> str: # Converts color codes into terminal colors 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 newText += Fore.RESET # reset color at the end of the text return newText -def load(file_path): - '''Loads the game from a YAML file to a Game class''' +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" try: with open(file_path) as f: data = yaml.load(f,Loader=SafeLoader) g = Game(data) + g.lang = lang return g except Exception as e: print(f"{Back.RED}{Fore.WHITE}An exception has occured while loading the game from the YAML file:{Fore.RESET}{Back.RESET}") diff --git a/lib/lang/cz.yml b/lib/lang/cz.yml new file mode 100644 index 0000000..2b55f13 --- /dev/null +++ b/lib/lang/cz.yml @@ -0,0 +1 @@ +TODO: "todo" \ No newline at end of file diff --git a/lib/lang/en.yml b/lib/lang/en.yml new file mode 100644 index 0000000..2b55f13 --- /dev/null +++ b/lib/lang/en.yml @@ -0,0 +1 @@ +TODO: "todo" \ No newline at end of file diff --git a/lib/save.py b/lib/save.py new file mode 100644 index 0000000..2732a32 --- /dev/null +++ b/lib/save.py @@ -0,0 +1,23 @@ +from os import path +import yaml + +class SaveManager: # manages save and configuration files + def __init__(self): + self.id = "" + self.currentPrompt = "" + self.lang = "" + self.inventory = [] + + 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"] + return True + return False + + def save(self): + data = {"id":self.id,"currentPrompt":self.currentPrompt,"inventory":self.inventory,"lang":self.lang} + with open(f"./saves/{self.id}.yml",mode="w",encoding="utf-8") as f: + yaml.dump(data,f) \ No newline at end of file