1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-23 19:44:20 +00:00
This commit is contained in:
Steffo 2020-02-18 14:48:21 +01:00
parent d3beadef16
commit 5220201434
14 changed files with 216 additions and 26 deletions

View file

@ -0,0 +1,52 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<DBN-PSQL>
<case-options enabled="true">
<option name="KEYWORD_CASE" value="lower" />
<option name="FUNCTION_CASE" value="lower" />
<option name="PARAMETER_CASE" value="lower" />
<option name="DATATYPE_CASE" value="lower" />
<option name="OBJECT_CASE" value="preserve" />
</case-options>
<formatting-settings enabled="false" />
</DBN-PSQL>
<DBN-SQL>
<case-options enabled="true">
<option name="KEYWORD_CASE" value="lower" />
<option name="FUNCTION_CASE" value="lower" />
<option name="PARAMETER_CASE" value="lower" />
<option name="DATATYPE_CASE" value="lower" />
<option name="OBJECT_CASE" value="preserve" />
</case-options>
<formatting-settings enabled="false">
<option name="STATEMENT_SPACING" value="one_line" />
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" />
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" />
</formatting-settings>
</DBN-SQL>
<DBN-PSQL>
<case-options enabled="true">
<option name="KEYWORD_CASE" value="lower" />
<option name="FUNCTION_CASE" value="lower" />
<option name="PARAMETER_CASE" value="lower" />
<option name="DATATYPE_CASE" value="lower" />
<option name="OBJECT_CASE" value="preserve" />
</case-options>
<formatting-settings enabled="false" />
</DBN-PSQL>
<DBN-SQL>
<case-options enabled="true">
<option name="KEYWORD_CASE" value="lower" />
<option name="FUNCTION_CASE" value="lower" />
<option name="PARAMETER_CASE" value="lower" />
<option name="DATATYPE_CASE" value="lower" />
<option name="OBJECT_CASE" value="preserve" />
</case-options>
<formatting-settings enabled="false">
<option name="STATEMENT_SPACING" value="one_line" />
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" />
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" />
</formatting-settings>
</DBN-SQL>
</code_scheme>
</component>

11
.idea/dataSources.xml Normal file
View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="royalnet@combo.steffo.eu" uuid="e1643839-41cb-4186-bf58-6d375d1420c8">
<driver-ref>postgresql</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
<jdbc-url>jdbc:postgresql://combo.steffo.eu:5432/royalnet</jdbc-url>
</data-source>
</component>
</project>

9
.idea/discord.xml Normal file
View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="true" />
</component>
<component name="ProjectNotificationSettings">
<option name="askShowProject" value="false" />
</component>
</project>

View file

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

8
.idea/modules.xml Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/rpgpack.iml" filepath="$PROJECT_DIR$/.idea/rpgpack.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View file

@ -1,6 +1,8 @@
from royalnet.commands import * from royalnet.commands import *
from royalnet.utils import asyncify from royalnet.utils import asyncify
from ..tables import DndCharacter, DndActiveCharacter from ..tables import DndCharacter, DndActiveCharacter
from ..utils import get_active_character, get_interface_data
import pickle
class DndactiveCommand(Command): class DndactiveCommand(Command):
@ -15,17 +17,20 @@ class DndactiveCommand(Command):
async def run(self, args: CommandArgs, data: CommandData) -> None: async def run(self, args: CommandArgs, data: CommandData) -> None:
identifier = args.optional(0) identifier = args.optional(0)
author = await data.get_author(error_if_none=True) author = await data.get_author(error_if_none=True)
if identifier is None: active_character = await get_active_character(data)
# Display the active character # Display the active character
if author.dnd_active_character is None: if identifier is None:
await data.reply(" You have no active characters.") if active_character is None:
await data.reply(" You haven't activated any character in this chat.")
else: else:
await data.reply(f" You currently active character is [b]{author.dnd_active_character}[/b].") await data.reply(f" Your active character for this chat is [b]{active_character.character}[/b].")
return return
# Find the character by name
try: try:
identifier = int(identifier) identifier = int(identifier)
except ValueError: except ValueError:
# Find the character by name
chars = await asyncify(data.session.query(self.alchemy.get(DndCharacter)).filter_by(name=identifier).all) chars = await asyncify(data.session.query(self.alchemy.get(DndCharacter)).filter_by(name=identifier).all)
if len(chars) >= 2: if len(chars) >= 2:
char_string = "\n".join([f"[c]{char.character_id}[/c] (LV {char.level}) by {char.creator})" for char in chars]) char_string = "\n".join([f"[c]{char.character_id}[/c] (LV {char.level}) by {char.creator})" for char in chars])
@ -43,12 +48,16 @@ class DndactiveCommand(Command):
if char is None: if char is None:
raise CommandError("No character found.") raise CommandError("No character found.")
# Check if the player already has an active character # Check if the player already has an active character
if author.dnd_active_character is None: if active_character is None:
# Create a new active character # Create a new active character
achar = self.alchemy.get(DndActiveCharacter)(character=char, user=author) achar = self.alchemy.get(DndActiveCharacter)(
character=char,
user=author,
interface_name=self.interface.name,
interface_data=pickle.dumps(get_interface_data(data)))
data.session.add(achar) data.session.add(achar)
else: else:
# Change the active character # Change the active character
author.dnd_active_character.character = char active_character.character = char
await data.session_commit() await data.session_commit()
await data.reply(f"✅ Active character set to [b]{char}[/b]!") await data.reply(f"✅ Active character set to [b]{char}[/b]!")

View file

@ -2,6 +2,7 @@ import re
from royalnet.commands import * from royalnet.commands import *
from .dndnew import DndnewCommand from .dndnew import DndnewCommand
from ..tables import DndCharacter from ..tables import DndCharacter
from ..utils import get_active_character
class DndeditCommand(DndnewCommand): class DndeditCommand(DndnewCommand):
@ -18,11 +19,10 @@ class DndeditCommand(DndnewCommand):
await data.reply(self._syntax()) await data.reply(self._syntax())
return return
author = await data.get_author(error_if_none=True) active_character = await get_active_character(data)
if author.dnd_active_character is None: if active_character is None:
raise CommandError("You don't have an active character.") raise CommandError("You don't have an active character.")
char = active_character.character
char: DndCharacter = author.dnd_active_character.character
arguments = self._parse(character_sheet) arguments = self._parse(character_sheet)
for key in arguments: for key in arguments:

View file

@ -1,5 +1,6 @@
from royalnet.commands import * from royalnet.commands import *
from ..tables import DndCharacter, DndActiveCharacter from ..tables import DndCharacter, DndActiveCharacter
from ..utils import get_active_character
class DndinfoCommand(Command): class DndinfoCommand(Command):
@ -13,6 +14,10 @@ class DndinfoCommand(Command):
async def run(self, args: CommandArgs, data: CommandData) -> None: async def run(self, args: CommandArgs, data: CommandData) -> None:
author = await data.get_author(error_if_none=True) author = await data.get_author(error_if_none=True)
if author.dnd_active_character is None:
active_character = await get_active_character(data)
char = active_character.character
if char is None:
raise CommandError("You don't have an active character.") raise CommandError("You don't have an active character.")
await data.reply(author.dnd_active_character.character.character_sheet()) await data.reply(char.character_sheet())

View file

@ -2,6 +2,7 @@ import random
import math import math
from royalnet.commands import * from royalnet.commands import *
from ..tables import DndCharacter from ..tables import DndCharacter
from ..utils import get_active_character
class DndrollCommand(Command): class DndrollCommand(Command):
@ -73,14 +74,14 @@ class DndrollCommand(Command):
"ste": "stealth", "ste": "stealth",
"nas": "stealth", "nas": "stealth",
"sur": "survival", "sur": "survival",
"sop": "sopravvivenza", "sop": "survival",
} }
async def run(self, args: CommandArgs, data: CommandData) -> None: async def run(self, args: CommandArgs, data: CommandData) -> None:
author = await data.get_author(error_if_none=True) active_character = await get_active_character(data)
if author.dnd_active_character is None: if active_character is None:
raise CommandError("You don't have an active character.") raise CommandError("You don't have an active character.")
char: DndCharacter = author.dnd_active_character.character char = active_character.character
first = args[0] first = args[0]
second = args.optional(1) second = args.optional(1)

View file

@ -50,7 +50,7 @@ class DndspellCommand(Command):
@staticmethod @staticmethod
def _parse_spell(spell: dict) -> str: def _parse_spell(spell: dict) -> str:
string = ['✨ [b]{spell["name"]}[/b]\n'] string = [f'✨ [b]{spell["name"]}[/b]\n']
# Source (manual, page) # Source (manual, page)
if "source" in spell: if "source" in spell:
@ -61,10 +61,18 @@ class DndspellCommand(Command):
string.append("\n") string.append("\n")
# Level # Level
if spell["level"] == 0: string.append({
string.append(f'[b]Cantrip[/b]\n') 0: "0⃣ [b]Cantrip[/b]\n",
else: 1: "1⃣ [b]1st[/b] level\n",
string.append(f'[b]{ordinalformat(spell["level"])}[/b] level\n') 2: "2⃣ [b]2nd[/b] level\n",
3: "3⃣ [b]3rd[/b] level\n",
4: "4⃣ [b]4th[/b] level\n",
5: "5⃣ [b]5th[/b] level\n",
6: "6⃣ [b]6th[/b] level\n",
7: "7⃣ [b]7th[/b] level\n",
8: "8⃣ [b]8th[/b] level\n",
9: "9⃣ [b]9th[/b] level\n",
}[spell["level"]])
# School # School
string.append({ string.append({
@ -78,6 +86,7 @@ class DndspellCommand(Command):
"P": "Psionic", "P": "Psionic",
"T": "Transmutation", "T": "Transmutation",
}[spell["school"]]) }[spell["school"]])
string.append("\n\n")
# Cast time # Cast time
for time in spell.get("time", []): for time in spell.get("time", []):
@ -98,9 +107,29 @@ class DndspellCommand(Command):
string.append("Range: ♾ [b]Unlimited[/b]\n") string.append("Range: ♾ [b]Unlimited[/b]\n")
else: else:
string.append(f'Range: 🏹 [b]{spell["range"]["distance"]["amount"]}' string.append(f'Range: 🏹 [b]{spell["range"]["distance"]["amount"]}'
f' {spell["range"]["distance"]["type"]}[/b] ({spell["range"]["type"]})\n') f' {spell["range"]["distance"]["type"]}[/b] (point)\n')
elif range["type"] == "radius":
string.append(f'Range: ⭕️ [b]{spell["range"]["distance"]["amount"]}'
f' {spell["range"]["distance"]["type"]}[/b] (radius)\n')
elif range["type"] == "sphere":
string.append(f'Range: 🌕 [b]{spell["range"]["distance"]["amount"]}'
f' {spell["range"]["distance"]["type"]}[/b] (sphere)\n')
elif range["type"] == "cone":
string.append(f'Range: 🍦 [b]{spell["range"]["distance"]["amount"]}'
f' {spell["range"]["distance"]["type"]}[/b] (cone)\n')
elif range["type"] == "line":
string.append(f'Range: [b]{spell["range"]["distance"]["amount"]}'
f' {spell["range"]["distance"]["type"]}[/b] (line)\n')
elif range["type"] == "hemisphere":
string.append(f'Range: 🌗 [b]{spell["range"]["distance"]["amount"]}'
f' {spell["range"]["distance"]["type"]}[/b] (hemisphere)\n')
elif range["type"] == "cube":
string.append(f'Range: ⬜️ [b]{spell["range"]["distance"]["amount"]}'
f' {spell["range"]["distance"]["type"]}[/b] (cube)\n')
elif range["type"] == "special": elif range["type"] == "special":
string.append("Range: ⭐️ Special") string.append("Range: ⭐️ Special")
else:
string.append('Range: ⚠️[b]UNKNOWN[/b]')
# Components # Components
components = spell.get("components") components = spell.get("components")

View file

@ -20,7 +20,15 @@ class DndActiveCharacter:
@declared_attr @declared_attr
def user(self): def user(self):
return relationship("User", foreign_keys=self.user_id, backref=backref("dnd_active_character", uselist=False)) return relationship("User", foreign_keys=self.user_id, backref=backref("dnd_active_characters"))
@declared_attr
def interface_name(self):
return Column(String)
@declared_attr
def interface_data(self):
return Column(LargeBinary)
def __repr__(self): def __repr__(self):
return f"<{self.__class__.__qualname__} for {self.user_id}: {self.character_id}>" return f"<{self.__class__.__qualname__} for {self.user_id}: {self.character_id}>"

View file

@ -1,4 +1,5 @@
from .dndproficiencytype import DndProficiencyType 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
__all__ = ["DndProficiencyType", "parse_5etools_entry"] __all__ = ["DndProficiencyType", "parse_5etools_entry", "get_active_character", "get_interface_data"]

View file

@ -0,0 +1,45 @@
from typing import *
from ..tables import DndActiveCharacter
import royalnet.utils as ru
import royalnet.commands as rc
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]:
interface = data._interface
alchemy = interface.alchemy
user = await data.get_author(error_if_none=True)
idata = get_interface_data(data)
DndAcChT = alchemy.get(DndActiveCharacter)
active_characters: List[DndActiveCharacter] = await ru.asyncify(
data.session
.query(DndAcChT)
.filter_by(interface_name=interface.name, user=user)
.all
)
for active_character in active_characters:
if interface.name == "telegram":
# interface_data is chat id
chat_id = pickle.loads(active_character.interface_data)
if chat_id == idata:
return active_character
elif interface.name == "discord":
# interface_data is channel id
chat_id = pickle.loads(active_character.interface_data)
if chat_id == idata:
return active_character
else:
raise rc.UnsupportedError("This interface isn't supported yet.")
return None