mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-23 19:44:20 +00:00
yes
This commit is contained in:
parent
d3beadef16
commit
5220201434
14 changed files with 216 additions and 26 deletions
52
.idea/codeStyles/Project.xml
Normal file
52
.idea/codeStyles/Project.xml
Normal 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
11
.idea/dataSources.xml
Normal 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
9
.idea/discord.xml
Normal 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>
|
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
Normal 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
8
.idea/modules.xml
Normal 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
6
.idea/vcs.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -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)
|
||||||
|
active_character = await get_active_character(data)
|
||||||
|
|
||||||
|
# Display the active character
|
||||||
if identifier is None:
|
if identifier is None:
|
||||||
# Display the active character
|
if active_character is None:
|
||||||
if author.dnd_active_character is None:
|
await data.reply("ℹ️ You haven't activated any character in this chat.")
|
||||||
await data.reply("ℹ️ You have no active characters.")
|
|
||||||
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]!")
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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}>"
|
||||||
|
|
|
@ -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"]
|
||||||
|
|
45
rpgpack/utils/getactivechar.py
Normal file
45
rpgpack/utils/getactivechar.py
Normal 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
|
Loading…
Reference in a new issue