mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-27 13:34:28 +00:00
Add Active Battles
This commit is contained in:
parent
0fdba9aca0
commit
fb8d5fddb5
20 changed files with 160 additions and 32 deletions
|
@ -11,6 +11,7 @@ from .dndspell import DndspellCommand
|
||||||
from .testhealth import TesthealthCommand
|
from .testhealth import TesthealthCommand
|
||||||
from .testfaction import TestfactionCommand
|
from .testfaction import TestfactionCommand
|
||||||
from .dndnewbattle import DndnewbattleCommand
|
from .dndnewbattle import DndnewbattleCommand
|
||||||
|
from .dndactivebattle import DndactivebattleCommand
|
||||||
|
|
||||||
# Enter the commands of your Pack here!
|
# Enter the commands of your Pack here!
|
||||||
available_commands = [
|
available_commands = [
|
||||||
|
@ -25,6 +26,8 @@ available_commands = [
|
||||||
DndspellCommand,
|
DndspellCommand,
|
||||||
TesthealthCommand,
|
TesthealthCommand,
|
||||||
TestfactionCommand,
|
TestfactionCommand,
|
||||||
|
DndnewbattleCommand,
|
||||||
|
DndactivebattleCommand,
|
||||||
]
|
]
|
||||||
|
|
||||||
# Don't change this, it should automatically generate __all__
|
# Don't change this, it should automatically generate __all__
|
||||||
|
|
65
rpgpack/commands/dndactivebattle.py
Normal file
65
rpgpack/commands/dndactivebattle.py
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
from royalnet.commands import *
|
||||||
|
from royalnet.utils import asyncify
|
||||||
|
from ..tables import DndCharacter, DndActiveBattle, DndBattle
|
||||||
|
from ..utils import get_active_battle, get_interface_data
|
||||||
|
import pickle
|
||||||
|
|
||||||
|
|
||||||
|
class DndactivebattleCommand(Command):
|
||||||
|
name: str = "dndactivebattle"
|
||||||
|
|
||||||
|
description: str = "Set a D&D battle as active."
|
||||||
|
|
||||||
|
aliases = ["dab", "dndab", "activebattle", "dactivebattle"]
|
||||||
|
|
||||||
|
syntax = "{name|id}"
|
||||||
|
|
||||||
|
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||||
|
BattleT = self.alchemy.get(DndBattle)
|
||||||
|
ABattleT = self.alchemy.get(DndActiveBattle)
|
||||||
|
|
||||||
|
identifier = args.joined()
|
||||||
|
active_battle = await get_active_battle(data)
|
||||||
|
|
||||||
|
# Display the active character
|
||||||
|
if identifier == "":
|
||||||
|
if active_battle is None:
|
||||||
|
await data.reply("ℹ️ No battles have ever been activated in this chat.")
|
||||||
|
else:
|
||||||
|
await data.reply(active_battle.battle.create_message())
|
||||||
|
return
|
||||||
|
|
||||||
|
# Find the battle
|
||||||
|
try:
|
||||||
|
identifier = int(identifier)
|
||||||
|
except ValueError:
|
||||||
|
# Find the battle by name
|
||||||
|
battles = await asyncify(data.session.query(BattleT).filter_by(name=identifier).all)
|
||||||
|
if len(battles) >= 2:
|
||||||
|
char_string = "\n".join([f"[c]{battle.id}[/c]" for battle in battles])
|
||||||
|
raise CommandError(f"Multiple battles share the name [b]{identifier}[/b], "
|
||||||
|
f"please activate one of them by using their id:\n{char_string}")
|
||||||
|
elif len(battles) == 1:
|
||||||
|
battle = battles[0]
|
||||||
|
else:
|
||||||
|
battle = None
|
||||||
|
else:
|
||||||
|
# Find the battle by id
|
||||||
|
battle = await asyncify(data.session.query(BattleT)
|
||||||
|
.filter_by(id=identifier)
|
||||||
|
.one_or_none)
|
||||||
|
if battle is None:
|
||||||
|
raise CommandError("No such battle found.")
|
||||||
|
# Check if the player already has an active character
|
||||||
|
if active_battle is None:
|
||||||
|
# Create a new active battle
|
||||||
|
active_battle = ABattleT(
|
||||||
|
battle=battle,
|
||||||
|
interface_name=self.interface.name,
|
||||||
|
interface_data=pickle.dumps(get_interface_data(data)))
|
||||||
|
data.session.add(active_battle)
|
||||||
|
else:
|
||||||
|
# Change the active character
|
||||||
|
active_battle.battle = battle
|
||||||
|
await data.session_commit()
|
||||||
|
await data.reply(f"⚔️ [b]{battle}[/b]! Roll initiative!")
|
|
@ -56,24 +56,26 @@ class DnditemCommand(Command):
|
||||||
# Type
|
# Type
|
||||||
item_type = item.get("type")
|
item_type = item.get("type")
|
||||||
if item_type:
|
if item_type:
|
||||||
string.append(f"Type: [b]{item_type}[/b]")
|
string.append(f"Type: [b]{item_type}[/b]\n")
|
||||||
|
|
||||||
# Value
|
# Value
|
||||||
item_value = item.get("value")
|
item_value = item.get("value")
|
||||||
if item_value:
|
if item_value:
|
||||||
string.append(f"Value: [b]{item_value}[/b]")
|
string.append(f"Value: [b]{item_value}[/b]\n")
|
||||||
|
|
||||||
# Weight
|
# Weight
|
||||||
item_weight = item.get("weight")
|
item_weight = item.get("weight")
|
||||||
if item_weight:
|
if item_weight:
|
||||||
string.append(f"Value: [b]{item_weight}[/b]")
|
string.append(f"Value: [b]{item_weight}[/b]\n")
|
||||||
|
|
||||||
# Rarity
|
# Rarity
|
||||||
item_rarity = item.get("rarity")
|
item_rarity = item.get("rarity")
|
||||||
if item_rarity:
|
if item_rarity:
|
||||||
string.append(f"Rarity: [b]{item_rarity}[/b]")
|
string.append(f"Rarity: [b]{item_rarity}[/b]\n")
|
||||||
else:
|
else:
|
||||||
string.append(f"Rarity: [b]Mundane[/b]")
|
string.append(f"Rarity: [b]Mundane[/b]\n")
|
||||||
|
|
||||||
|
string.append("\n")
|
||||||
|
|
||||||
# Text entries
|
# Text entries
|
||||||
for entry in item.get("entries", []):
|
for entry in item.get("entries", []):
|
||||||
|
|
|
@ -2,7 +2,7 @@ import re
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
from royalnet.commands import *
|
from royalnet.commands import *
|
||||||
from ..tables import DndCharacter
|
from ..tables import DndCharacter
|
||||||
from ..utils import DndProficiencyType
|
from ..types import DndProficiencyType
|
||||||
|
|
||||||
|
|
||||||
class DndnewCommand(Command):
|
class DndnewCommand(Command):
|
||||||
|
@ -66,4 +66,4 @@ class DndnewCommand(Command):
|
||||||
raise CommandError(f"Mandatory parameter '{param_name}' is missing.")
|
raise CommandError(f"Mandatory parameter '{param_name}' is missing.")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
await data.reply(f"✅ Character [b]{character.name}[/b] created!")
|
await data.reply(f"✅ Character [b]{character.name}[/b] (ID: {character.character_id}) created!")
|
||||||
|
|
|
@ -26,4 +26,4 @@ class DndnewbattleCommand(rc.Command):
|
||||||
data.session.add(battle)
|
data.session.add(battle)
|
||||||
await data.session_commit()
|
await data.session_commit()
|
||||||
|
|
||||||
await data.reply(f"✅ Battaglia [b]{battle.name}[/b] creata!")
|
await data.reply(f"✅ Battle [b]{battle.name}[/b] (ID: {battle.id}) created!")
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from typing import *
|
from typing import *
|
||||||
import royalnet
|
import royalnet
|
||||||
import royalnet.commands as rc
|
import royalnet.commands as rc
|
||||||
from ..utils import Faction
|
from ..types import Faction
|
||||||
|
|
||||||
|
|
||||||
class TestfactionCommand(rc.Command):
|
class TestfactionCommand(rc.Command):
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from typing import *
|
from typing import *
|
||||||
import royalnet
|
import royalnet
|
||||||
import royalnet.commands as rc
|
import royalnet.commands as rc
|
||||||
from ..utils import Health
|
from ..types import Health
|
||||||
|
|
||||||
|
|
||||||
class TesthealthCommand(rc.Command):
|
class TesthealthCommand(rc.Command):
|
||||||
|
|
|
@ -3,6 +3,7 @@ from .dndactivecharacters import DndActiveCharacter
|
||||||
from .dndcharacters import DndCharacter
|
from .dndcharacters import DndCharacter
|
||||||
from .dndbattle import DndBattle
|
from .dndbattle import DndBattle
|
||||||
from .dndbattleunit import DndBattleUnit
|
from .dndbattleunit import DndBattleUnit
|
||||||
|
from .dndactivebattle import DndActiveBattle
|
||||||
|
|
||||||
# Enter the tables of your Pack here!
|
# Enter the tables of your Pack here!
|
||||||
available_tables = [
|
available_tables = [
|
||||||
|
@ -10,6 +11,7 @@ available_tables = [
|
||||||
DndCharacter,
|
DndCharacter,
|
||||||
DndBattle,
|
DndBattle,
|
||||||
DndBattleUnit,
|
DndBattleUnit,
|
||||||
|
DndActiveBattle,
|
||||||
]
|
]
|
||||||
|
|
||||||
# Don't change this, it should automatically generate __all__
|
# Don't change this, it should automatically generate __all__
|
||||||
|
|
|
@ -12,7 +12,7 @@ class DndActiveBattle:
|
||||||
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
def battle(self):
|
def battle(self):
|
||||||
return relationship("DndCharacter", foreign_keys=self.battle_id, backref="active_in")
|
return relationship("DndBattle", foreign_keys=self.battle_id, backref=backref("activated_in"))
|
||||||
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
def interface_name(self):
|
def interface_name(self):
|
||||||
|
|
|
@ -17,3 +17,15 @@ class DndBattle:
|
||||||
@declared_attr
|
@declared_attr
|
||||||
def description(self):
|
def description(self):
|
||||||
return Column(String, nullable=False)
|
return Column(String, nullable=False)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<{self.__class__.__qualname__} {self.name}>"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.name}"
|
||||||
|
|
||||||
|
def create_message(self):
|
||||||
|
string = []
|
||||||
|
string.append(f"⚔️ [b]{self.name}[/b]\n")
|
||||||
|
string.append(f"{self.description}\n")
|
||||||
|
return "".join(string)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from sqlalchemy.orm import *
|
from sqlalchemy.orm import *
|
||||||
from sqlalchemy.ext.declarative import declared_attr
|
from sqlalchemy.ext.declarative import declared_attr
|
||||||
from ..utils import Health, Faction
|
from ..types import Health, Faction
|
||||||
|
|
||||||
|
|
||||||
class DndBattleUnit:
|
class DndBattleUnit:
|
||||||
|
@ -17,7 +17,7 @@ class DndBattleUnit:
|
||||||
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
def battle(self):
|
def battle(self):
|
||||||
return relationship("DndBattle", backref="units")
|
return relationship("DndBattle", foreign_keys=self.battle_id, backref="units")
|
||||||
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
def initiative(self):
|
def initiative(self):
|
||||||
|
|
|
@ -2,7 +2,7 @@ import math
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from sqlalchemy.orm import *
|
from sqlalchemy.orm import *
|
||||||
from sqlalchemy.ext.declarative import *
|
from sqlalchemy.ext.declarative import *
|
||||||
from ..utils import DndProficiencyType
|
from ..types import DndProficiencyType
|
||||||
|
|
||||||
|
|
||||||
class DndCharacter:
|
class DndCharacter:
|
||||||
|
|
8
rpgpack/types/__init__.py
Normal file
8
rpgpack/types/__init__.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
from .dndproficiencytype import DndProficiencyType
|
||||||
|
from .faction import Faction
|
||||||
|
from .health import Health
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Faction",
|
||||||
|
"Health",
|
||||||
|
]
|
|
@ -1,6 +1,7 @@
|
||||||
import enum
|
import enum
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: Rename this. It will break the whole database.
|
||||||
class DndProficiencyType(enum.Enum):
|
class DndProficiencyType(enum.Enum):
|
||||||
NONE = 0
|
NONE = 0
|
||||||
HALF_PROFICIENCY = 0.5
|
HALF_PROFICIENCY = 0.5
|
|
@ -1,14 +1,11 @@
|
||||||
from .dndproficiencytype import DndProficiencyType
|
|
||||||
from .parse5etoolsentry import parse_5etools_entry
|
from .parse5etoolsentry import parse_5etools_entry
|
||||||
from .getactivechar import get_active_character, get_interface_data
|
from .getinterfacedata import get_interface_data
|
||||||
from .faction import Faction
|
from .getactivechar import get_active_character
|
||||||
from .health import Health
|
from .getactivebattle import get_active_battle
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"DndProficiencyType",
|
|
||||||
"parse_5etools_entry",
|
"parse_5etools_entry",
|
||||||
"get_active_character",
|
|
||||||
"get_interface_data",
|
"get_interface_data",
|
||||||
"Faction",
|
"get_active_character",
|
||||||
"Health",
|
"get_active_battle",
|
||||||
]
|
]
|
||||||
|
|
36
rpgpack/utils/getactivebattle.py
Normal file
36
rpgpack/utils/getactivebattle.py
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
from typing import *
|
||||||
|
from ..tables import DndActiveBattle
|
||||||
|
from ..utils import get_interface_data
|
||||||
|
import royalnet.utils as ru
|
||||||
|
import royalnet.commands as rc
|
||||||
|
import pickle
|
||||||
|
|
||||||
|
|
||||||
|
async def get_active_battle(data: rc.CommandData) -> Optional[DndActiveBattle]:
|
||||||
|
interface = data._interface
|
||||||
|
alchemy = interface.alchemy
|
||||||
|
idata = get_interface_data(data)
|
||||||
|
|
||||||
|
DndAcBaT = alchemy.get(DndActiveBattle)
|
||||||
|
active_battles: List[DndActiveBattle] = await ru.asyncify(
|
||||||
|
data.session
|
||||||
|
.query(DndAcBaT)
|
||||||
|
.filter_by(interface_name=interface.name)
|
||||||
|
.all
|
||||||
|
)
|
||||||
|
|
||||||
|
for active_battle in active_battles:
|
||||||
|
if interface.name == "telegram":
|
||||||
|
# interface_data is chat id
|
||||||
|
chat_id = pickle.loads(active_battle.interface_data)
|
||||||
|
if chat_id == idata:
|
||||||
|
return active_battle
|
||||||
|
elif interface.name == "discord":
|
||||||
|
# interface_data is channel id
|
||||||
|
chat_id = pickle.loads(active_battle.interface_data)
|
||||||
|
if chat_id == idata:
|
||||||
|
return active_battle
|
||||||
|
else:
|
||||||
|
raise rc.UnsupportedError("This interface isn't supported yet.")
|
||||||
|
|
||||||
|
return None
|
|
@ -1,19 +1,11 @@
|
||||||
from typing import *
|
from typing import *
|
||||||
from ..tables import DndActiveCharacter
|
from ..tables import DndActiveCharacter
|
||||||
|
from ..utils import get_interface_data
|
||||||
import royalnet.utils as ru
|
import royalnet.utils as ru
|
||||||
import royalnet.commands as rc
|
import royalnet.commands as rc
|
||||||
import pickle
|
import pickle
|
||||||
|
|
||||||
|
|
||||||
def get_interface_data(data: rc.CommandData):
|
|
||||||
if data._interface.name == "telegram":
|
|
||||||
return data.message.chat.id
|
|
||||||
elif data._interface.name == "discord":
|
|
||||||
return data.message.channel.id
|
|
||||||
else:
|
|
||||||
raise rc.UnsupportedError("This interface isn't supported yet.")
|
|
||||||
|
|
||||||
|
|
||||||
async def get_active_character(data: rc.CommandData) -> Optional[DndActiveCharacter]:
|
async def get_active_character(data: rc.CommandData) -> Optional[DndActiveCharacter]:
|
||||||
interface = data._interface
|
interface = data._interface
|
||||||
alchemy = interface.alchemy
|
alchemy = interface.alchemy
|
||||||
|
|
10
rpgpack/utils/getinterfacedata.py
Normal file
10
rpgpack/utils/getinterfacedata.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import royalnet.commands as rc
|
||||||
|
|
||||||
|
|
||||||
|
def get_interface_data(data: rc.CommandData):
|
||||||
|
if data._interface.name == "telegram":
|
||||||
|
return data.message.chat.id
|
||||||
|
elif data._interface.name == "discord":
|
||||||
|
return data.message.channel.id
|
||||||
|
else:
|
||||||
|
raise rc.UnsupportedError("This interface isn't supported yet.")
|
Loading…
Reference in a new issue