Work on fighting
This commit is contained in:
parent
f0eae367b1
commit
04538bae36
6 changed files with 71 additions and 12 deletions
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
|
@ -9,7 +9,7 @@
|
||||||
"type": "python",
|
"type": "python",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceFolder}/__main__.py",
|
"program": "${workspaceFolder}/__main__.py",
|
||||||
"console": "externalTerminal",
|
"console": "integratedTerminal",
|
||||||
"justMyCode": true,
|
"justMyCode": true,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,6 +9,18 @@ meta: # make sure every key is in lowercase
|
||||||
- chainmail:
|
- chainmail:
|
||||||
def: 2
|
def: 2
|
||||||
starter: true
|
starter: true
|
||||||
|
enemies:
|
||||||
|
- john:
|
||||||
|
name: "John"
|
||||||
|
hp: 20
|
||||||
|
def: 1
|
||||||
|
attacks:
|
||||||
|
- slash:
|
||||||
|
atk: 2
|
||||||
|
name: "Slash"
|
||||||
|
- boom:
|
||||||
|
atk: 1
|
||||||
|
name: "Boom"
|
||||||
|
|
||||||
game: # here goes all the game logic
|
game: # here goes all the game logic
|
||||||
start: # the starting point always HAS to be named "start" (lowercase), the order and name of the rest does not matter
|
start: # the starting point always HAS to be named "start" (lowercase), the order and name of the rest does not matter
|
||||||
|
@ -51,5 +63,20 @@ game: # here goes all the game logic
|
||||||
- leave
|
- leave
|
||||||
leave:
|
leave:
|
||||||
description: "Leave"
|
description: "Leave"
|
||||||
text: "You decide to leave."
|
text: "You decide to leave. But John Doe blocks your way!"
|
||||||
|
fight: john
|
||||||
|
actions:
|
||||||
|
- af
|
||||||
|
af:
|
||||||
|
description: "Continue"
|
||||||
|
text: "&cJohn&r: I'm really sorry for attacking you, I don't know what I was doing!"
|
||||||
|
actions:
|
||||||
|
- idc
|
||||||
|
- ok
|
||||||
|
idc:
|
||||||
|
description: "Leave silently"
|
||||||
|
text: "You decide to turn around and leave without saying a word."
|
||||||
|
ok:
|
||||||
|
description: "Accept apology"
|
||||||
|
text: "&cJohn&r: Oh, thank you, kind sir!"
|
||||||
|
|
||||||
|
|
27
lib/fight.py
27
lib/fight.py
|
@ -1,26 +1,27 @@
|
||||||
import math
|
import math
|
||||||
|
|
||||||
from lib.game import Item
|
|
||||||
from .ascii import *
|
from .ascii import *
|
||||||
from colorama import Fore
|
from colorama import Fore
|
||||||
import keyboard
|
import keyboard
|
||||||
from random import randrange
|
from random import randrange
|
||||||
|
|
||||||
class FightHandler:
|
class FightHandler:
|
||||||
def __init__(self,message:str,name:str,hp:int,attacks:dict,lang:dict,eq:Item,img:str="") -> None:
|
def __init__(self,message:str,name:str,hp:int,defense:int,attacks:dict,lang:dict,eq:dict,img:str="") -> None:
|
||||||
self.selected = 0
|
self.selected = 0
|
||||||
keyboard.add_hotkey("up",self.up)
|
keyboard.add_hotkey("up",self.up)
|
||||||
keyboard.add_hotkey("down",self.down)
|
keyboard.add_hotkey("down",self.down)
|
||||||
keyboard.add_hotkey("enter",self.attack)
|
keyboard.add_hotkey("enter",self.attack)
|
||||||
self.name = name
|
self.name = name
|
||||||
self.max = hp # starting HP
|
self.max = hp # starting ENEMY HP
|
||||||
self.hp = self.max # current HP
|
self.hp = self.max # current ENEMY HP
|
||||||
|
self.enemyDef = defense # ENEMY DEF
|
||||||
|
self.my = 30 # starting PLAYER HP TODO: maybe make this a variable
|
||||||
self.attacks = attacks
|
self.attacks = attacks
|
||||||
self.img = img
|
self.img = img
|
||||||
self.lang = lang
|
self.lang = lang
|
||||||
self.message = message
|
self.message = message
|
||||||
self.equipped = eq
|
self.equipped = eq
|
||||||
input()
|
self.show()
|
||||||
|
|
||||||
def up(self):
|
def up(self):
|
||||||
if self.selected == 0:
|
if self.selected == 0:
|
||||||
|
@ -51,11 +52,21 @@ class FightHandler:
|
||||||
anim.play()
|
anim.play()
|
||||||
s = [self.lang["attack"],self.lang["defend"],self.lang["inventory"]]
|
s = [self.lang["attack"],self.lang["defend"],self.lang["inventory"]]
|
||||||
for selection in s:
|
for selection in s:
|
||||||
if(self.selected == self.selections.index(selection)):
|
if(self.selected == s.index(selection)):
|
||||||
print(f"{Fore.RED}⚔{Fore.RESET} {selection}")
|
print(f"{Fore.RED}⚔{Fore.RESET} {selection}")
|
||||||
else:
|
else:
|
||||||
print(f" {selection}")
|
print(f" {selection}")
|
||||||
|
|
||||||
def attack(self):
|
def attack(self):
|
||||||
self.hp -= self.attacks[randrange(len(self.attacks))][atk].
|
p = randrange(len(self.attacks))
|
||||||
input()
|
name = list(self.attacks[p].keys())[0]
|
||||||
|
enemyAtk = self.attacks[p][name]["atk"]
|
||||||
|
enemyDef = self.enemyDef
|
||||||
|
playerAtk = self.equipped["weapon"].attack
|
||||||
|
playerDef = self.equipped["armor"].defense
|
||||||
|
self.hp -= playerAtk - enemyDef # enemy takes damage
|
||||||
|
self.my -= enemyAtk - playerDef # player takes damage
|
||||||
|
self.message = f"{self.lang['enemydmg'].replace('$atk',str(playerAtk - enemyDef)).replace('$name',self.name)}\n{self.lang['playerdmg'].replace('$atk',str(enemyAtk - playerDef)).replace('$name',self.attacks[p][name]['name'])}"
|
||||||
|
|
||||||
|
def defend(self):
|
||||||
|
self.message = self.lang["defended"]
|
||||||
|
|
16
lib/game.py
16
lib/game.py
|
@ -6,6 +6,7 @@ import re
|
||||||
from lib.menu import HasItemDialogue, MenuManager
|
from lib.menu import HasItemDialogue, MenuManager
|
||||||
from .save import SaveManager
|
from .save import SaveManager
|
||||||
from .ascii import AsciiAnimation
|
from .ascii import AsciiAnimation
|
||||||
|
from .fight import *
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from os import system
|
from os import system
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@ class Game: # the game class keeps information about the loaded game
|
||||||
self.id = data["meta"]["id"] # Game ID
|
self.id = data["meta"]["id"] # Game ID
|
||||||
self.save = SaveManager(self.id) # saving
|
self.save = SaveManager(self.id) # saving
|
||||||
self.equipped = {"weapon":None,"armor":None} # Items equipped by player
|
self.equipped = {"weapon":None,"armor":None} # Items equipped by player
|
||||||
|
self.enemies = {} # Enemies
|
||||||
if "equippable" in data["meta"].keys():
|
if "equippable" in data["meta"].keys():
|
||||||
self.equippable = [] # Items that can be equipped by player
|
self.equippable = [] # Items that can be equipped by player
|
||||||
for item in data["meta"]["equippable"]:
|
for item in data["meta"]["equippable"]:
|
||||||
|
@ -34,7 +36,11 @@ class Game: # the game class keeps information about the loaded game
|
||||||
i = next((x for x in self.equippable if x.name == list(item.keys())[0]))
|
i = next((x for x in self.equippable if x.name == list(item.keys())[0]))
|
||||||
self.inventory.append(i)
|
self.inventory.append(i)
|
||||||
self.equipped[i.type] = i
|
self.equipped[i.type] = i
|
||||||
|
if "enemies" in data["meta"].keys():
|
||||||
|
# Load enemies
|
||||||
|
for en in data["meta"]["enemies"]:
|
||||||
|
name = list(en.keys())[0]
|
||||||
|
self.enemies[name] = {"name":en["name"],"hp":en["hp"],"attacks":en["attacks"],"def":en["def"]}
|
||||||
for k in data["game"]:
|
for k in data["game"]:
|
||||||
self.nodes.update({k:data["game"][k]})
|
self.nodes.update({k:data["game"][k]})
|
||||||
|
|
||||||
|
@ -120,12 +126,18 @@ class Game: # the game class keeps information about the loaded game
|
||||||
need_item.extend([None, None])
|
need_item.extend([None, None])
|
||||||
# we need to check if user has item
|
# we need to check if user has item
|
||||||
m = HasItemDialogue(actions_desc,self.parse_colors(self.nodes[self.current]["text"]),self.inventory,need_item)
|
m = HasItemDialogue(actions_desc,self.parse_colors(self.nodes[self.current]["text"]),self.inventory,need_item)
|
||||||
# TODO: Remove item from inventory after using it?
|
|
||||||
while need_item[m.selected] != None and all(element not in self.inventory for element in need_item[m.selected]): # until user selects an available prompt, re-prompt again
|
while need_item[m.selected] != None and all(element not in self.inventory for element in need_item[m.selected]): # until user selects an available prompt, re-prompt again
|
||||||
m = HasItemDialogue(actions_desc,self.parse_colors(self.nodes[self.current]["text"]),self.inventory,need_item)
|
m = HasItemDialogue(actions_desc,self.parse_colors(self.nodes[self.current]["text"]),self.inventory,need_item)
|
||||||
if m.selected <= len(actions_desc)-3 and "has_item" in self.nodes[self.nodes[self.current]["actions"][m.selected]].keys():
|
if m.selected <= len(actions_desc)-3 and "has_item" in self.nodes[self.nodes[self.current]["actions"][m.selected]].keys():
|
||||||
for item in need_item[m.selected]:
|
for item in need_item[m.selected]:
|
||||||
self.inventory.remove(item)
|
self.inventory.remove(item)
|
||||||
|
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()
|
||||||
|
input()
|
||||||
else:
|
else:
|
||||||
m = MenuManager(actions_desc,self.parse_colors(self.nodes[self.current]["text"]))
|
m = MenuManager(actions_desc,self.parse_colors(self.nodes[self.current]["text"]))
|
||||||
sel = m.selected
|
sel = m.selected
|
||||||
|
|
|
@ -24,5 +24,11 @@ selection: 'Vyberte zadáním čísla:'
|
||||||
not_number: 'Nezadali jste číslo'
|
not_number: 'Nezadali jste číslo'
|
||||||
invalid: 'Neplatný výběr'
|
invalid: 'Neplatný výběr'
|
||||||
|
|
||||||
|
attack: "Útočit"
|
||||||
|
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."
|
||||||
|
|
||||||
error_loading: 'Při načítání YAML souboru nastala chyba:'
|
error_loading: 'Při načítání YAML souboru nastala chyba:'
|
||||||
no_action: 'Chyba: žádná akce "$action" nenalezena v souboru hry'
|
no_action: 'Chyba: žádná akce "$action" nenalezena v souboru hry'
|
||||||
|
|
|
@ -26,6 +26,9 @@ invalid: 'Invalid selection'
|
||||||
|
|
||||||
attack: "Attack"
|
attack: "Attack"
|
||||||
defend: "Defend"
|
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."
|
||||||
|
|
||||||
error_loading: 'An exception has occured while loading the game from the YAML file'
|
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.'
|
Reference in a new issue