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