You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fabula/app.py

158 lines
9.6 KiB

import asyncio
from discord_webhook import DiscordEmbed
from urwid import MainLoop, AsyncioEventLoop, set_encoding
from embedgen import WebhookExecutor, simple_character_field
from model import Character
from enums import CharacterType, Visibility, CombatSide
from ui import LogUI, CharactersUI, ClocksUI, FabulaUI, MainUI
class FabulaApp(object):
def __init__(self, wrapper: FabulaUI, clocks: ClocksUI, characters: CharactersUI,
log: LogUI, webhook: WebhookExecutor):
self.wrapper = wrapper
self.clocks = clocks
self.characters = characters
self.log = log
self.log.add_message("this is a log message")
self.log.add_message("this is a second log message with some **bolded** text")
self.log.move_divider()
self.log.add_message("this is the newest message, since the last log was sent")
prandia = Character(name="Prandia", hp=53, max_hp=65, mp=55, max_mp=55, ip=6, max_ip=6, max_turns=1,
turns_left=0, sp=3, statuses=frozenset(("Delicious", "Dazed")), affinities=tuple(),
access_key='1', visibility=Visibility.ShowEvenIfKO, mdf=7, df=11, dr=0,
character_type=CharacterType.PlayerCharacter, side=CombatSide.Heroes,
color="34eb89", player_discord_id="579932273558945792", player_name="Fak",
thumbnail="https://media.discordapp.net/attachments/989315969920929862/1058455278221271120/"
+ "342px-Bluhen_Epic_Quest_Square.png")
self.characters.add_character(prandia)
selia = Character(name="Sélia", hp=12, max_hp=50, mp=55, max_mp=55, ip=0, max_ip=0, max_turns=1,
turns_left=1, sp=None, statuses=frozenset(["Enraged"]), affinities=tuple(),
access_key='2', visibility=Visibility.ShowAll, mdf=7, df=11, dr=0,
character_type=CharacterType.NonPlayerCharacter, side=CombatSide.Heroes,
color=None, thumbnail=None, player_discord_id=None, player_name=None)
self.characters.add_character(selia)
prandia_voraphilia = Character(name="Prandia's Voraphilia Resistance", hp=0, max_hp=1, mp=1, max_mp=1, ip=0,
max_ip=0,
max_turns=1, turns_left=1, sp=None, statuses=frozenset(), affinities=tuple(),
access_key='',
character_type=CharacterType.NonPlayerCharacter, side=CombatSide.Heroes,
visibility=Visibility.Hide, mdf=7, df=11, dr=0, color="34eb89",
thumbnail=None, player_discord_id=None, player_name=None)
self.characters.add_character(prandia_voraphilia)
vacana = Character(name="Hungry Vacana", hp=53, max_hp=53, mp=55, max_mp=55, ip=6, max_ip=6, max_turns=2,
turns_left=1, sp=3, statuses=frozenset(["Transformed"]), affinities=tuple(), access_key='A',
visibility=Visibility.MaskStats, mdf=7, df=11, dr=0,
character_type=CharacterType.PlayerCharacter, side=CombatSide.Villains,
player_name="Nan", player_discord_id="158766486725328897", color="a50ecf",
thumbnail="https://images-ext-1.discordapp.net/external/"
+ "bMwLWSrrCyGiqgJ14icQjXXllStzsKbQ-htrANQdSJA/"
+ "https/cdn.picrew.me/shareImg/org/202211/1561797_pzHTS4JJ.png")
self.characters.add_character(vacana)
flow = Character(name="Hungry Flow", hp=69, max_hp=120, mp=55, max_mp=55, ip=0, max_ip=0, max_turns=2,
turns_left=2, sp=3, statuses=frozenset(), affinities=tuple(), access_key='B',
visibility=Visibility.MaskName, mdf=7, df=11, dr=0,
character_type=CharacterType.NonPlayerCharacter, side=CombatSide.Villains, player_name=None,
player_discord_id=None, color="0073ff", thumbnail=None)
self.characters.add_character(flow)
vacana_hunger = Character(name="Vacana's Hunger", hp=27, max_hp=60, mp=1, max_mp=1, ip=0, max_ip=0, max_turns=2,
turns_left=0, sp=None, statuses=frozenset(), affinities=tuple(), access_key='',
visibility=Visibility.Hide, mdf=7, df=11, dr=0,
character_type=CharacterType.NonPlayerCharacter, side=CombatSide.Villains,
color="a50ecf",
thumbnail=None, player_name=None, player_discord_id=None, )
self.characters.add_character(vacana_hunger)
self.clocks.update_session(1, 2, 7)
self.webhook = webhook
self.character_list = (prandia, selia, prandia_voraphilia, vacana, flow, vacana_hunger)
self.event_loop = None
self.loop = None
@classmethod
def new(cls, webhook_url: str):
clocks = ClocksUI()
characters = CharactersUI()
log = LogUI()
main = MainUI(clocks, characters, log)
wrapper = FabulaUI(main)
webhook = WebhookExecutor(url=webhook_url)
return cls(wrapper=wrapper, clocks=clocks, characters=characters,
log=log, webhook=webhook)
def keypress(self, key):
if key == "l":
self.log.add_message("Another log message, eh? Sure, I can hook you up with **one of those.** Here I go!")
def run(self):
set_encoding("UTF-8")
self.event_loop = asyncio.new_event_loop()
self.loop = MainLoop(
widget=self.wrapper,
unhandled_input=self.keypress,
event_loop=AsyncioEventLoop(loop=self.event_loop),
palette=[
(None, "light gray", "default", "default"),
("FrameTitle", "white,bold", "default", "bold"),
("LogBold", "white,bold", "default", "bold"),
("LogFocused", "white,bold", "default", "bold"),
("LogUnfocused", "light cyan", "default", "default"),
("ClockName", "white,bold", "default", "bold"),
("ClockFocused", "white,bold", "default", "bold"),
("ClockUnfocused", "light green", "default", "default"),
("ClockBarEdge", 'yellow,bold', 'default', 'bold'),
("ClockBarFilled", 'yellow', 'default', 'default'),
("ClockBarEmpty", 'light gray', 'default', 'default'),
("ClockCurrent", 'light green,bold', 'default', 'bold'),
("ClockDivider", 'white', 'default', 'default'),
("ClockMax", 'dark green', 'default', 'default'),
("RoundLabel", 'light gray', 'default', 'default'),
("RoundNumber", 'white,bold', 'default', 'bold'),
("FabulaLabel", 'light gray', 'default', 'default'),
("FabulaNumber", 'white,bold', 'default', 'bold'),
("UltimaLabel", 'light gray', 'default', 'default'),
("UltimaNumber", 'white,bold', 'default', 'bold'),
("CharacterUnfocused", 'light red', 'default', 'default'),
("CharacterFocused", 'white,bold', 'default', 'bold'),
("CharacterPlayer", 'light green,bold', 'default', 'bold'),
("CharacterAlly", 'light cyan,bold', 'default', 'bold'),
("CharacterEnemy", 'light red,bold', 'default', 'bold'),
("CharacterEnemyPlayer", 'yellow,bold', 'default', 'bold'),
("CharacterUnknown", 'light gray,bold', 'default', 'bold'),
("TurnDisabled", 'dark gray', 'default', 'default'),
("TurnAvailable", 'light green,bold', 'default', 'bold'),
("TurnActed", 'light gray', 'default', 'default'),
("HPFull", 'light green,bold', 'default', 'bold'),
("HPScratched", 'light green', 'default', 'default'),
("HPWounded", 'white', 'default', 'default'),
("HPCrisis", 'yellow', 'default', 'default'),
("HPPeril", 'light red', 'default', 'default'),
("HPDown", 'dark red,bold', 'default', 'bold'),
("HPLabel", 'light gray', 'default', 'default'),
("HPMax", 'light gray', 'default', 'default'),
("MPLabel", 'light gray', 'default', 'default'),
("MPValue", 'light cyan', 'default', 'default'),
("MPMax", 'light gray', 'default', 'default'),
("FPLabel", 'light gray', 'default', 'default'),
("UPLabel", 'light gray', 'default', 'default'),
("FPValue", 'yellow', 'default', 'default'),
("UPValue", 'yellow', 'default', 'default'),
("IPLabel", 'light gray', 'default', 'default'),
("IPValue", 'light magenta', 'default', 'default'),
("IPMax", 'light gray', 'default', 'default'),
("StatusKO", 'light red,bold', 'default', 'bold,standout'),
("StatusCrisis", 'yellow,bold', 'default', 'bold'),
("Statuses", 'white', 'default', 'default'),
])
self.loop.screen.set_terminal_properties(
colors=2 ** 24,
has_underline=True,
bright_is_bold=False,
)
embed = DiscordEmbed()
for header, field in [simple_character_field(character) for character in self.character_list]:
embed.add_embed_field(name=header, value=field, inline=False)
self.loop.run()
self.loop = None
self.event_loop = None