mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-23 19:44:20 +00:00
progress
This commit is contained in:
parent
bc519535a1
commit
1928aaa2f5
8 changed files with 237 additions and 176 deletions
|
@ -1,169 +0,0 @@
|
||||||
from typing import *
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import logging
|
|
||||||
import aiohttp
|
|
||||||
|
|
||||||
from royalnet.backpack import tables as rbt
|
|
||||||
import royalnet.commands as rc
|
|
||||||
import royalnet.utils as ru
|
|
||||||
from sqlalchemy import or_, and_
|
|
||||||
|
|
||||||
from .abstract.linker import LinkerCommand
|
|
||||||
from ..tables import Steam, Brawlhalla, BrawlhallaDuo
|
|
||||||
from ..types import BrawlhallaRank, BrawlhallaMetal, BrawlhallaTier, Updatable
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class BrawlhallaCommand(LinkerCommand):
|
|
||||||
name: str = "brawlhalla"
|
|
||||||
|
|
||||||
aliases = ["bh", "bruhalla", "bruhlalla"]
|
|
||||||
|
|
||||||
description: str = "Visualizza le tue statistiche di Brawlhalla."
|
|
||||||
|
|
||||||
syntax: str = ""
|
|
||||||
|
|
||||||
def token(self):
|
|
||||||
return self.config['brawlhalla']['token']
|
|
||||||
|
|
||||||
async def get_updatables_of_user(self, session, user: rbt.User) -> List[Brawlhalla]:
|
|
||||||
return user.steam
|
|
||||||
|
|
||||||
async def get_updatables(self, session) -> List[Brawlhalla]:
|
|
||||||
return await ru.asyncify(session.query(self.alchemy.get(Steam)).all)
|
|
||||||
|
|
||||||
async def create(self,
|
|
||||||
session,
|
|
||||||
user: rbt.User,
|
|
||||||
args: rc.CommandArgs,
|
|
||||||
data: Optional[rc.CommandData] = None) -> Optional[Brawlhalla]:
|
|
||||||
raise rc.InvalidInputError("Brawlhalla accounts are automatically linked from Steam.")
|
|
||||||
|
|
||||||
async def update(self, session, obj, change: Callable[[str, Any], Awaitable[None]]):
|
|
||||||
BrawlhallaT = self.alchemy.get(Brawlhalla)
|
|
||||||
DuoT = self.alchemy.get(BrawlhallaDuo)
|
|
||||||
log.info(f"Updating: {obj}")
|
|
||||||
async with aiohttp.ClientSession() as hcs:
|
|
||||||
bh: Brawlhalla = obj.brawlhalla
|
|
||||||
if bh is None:
|
|
||||||
log.debug(f"Checking if player has an account...")
|
|
||||||
async with hcs.get(f"https://api.brawlhalla.com/search?steamid={obj.steamid.as_64}&api_key={self.token()}") as response:
|
|
||||||
if response.status != 200:
|
|
||||||
raise rc.ExternalError(f"Brawlhalla API /search returned {response.status}!")
|
|
||||||
j = await response.json()
|
|
||||||
if j == {} or j == []:
|
|
||||||
log.debug("No account found.")
|
|
||||||
return
|
|
||||||
bh = BrawlhallaT(
|
|
||||||
steam=obj,
|
|
||||||
brawlhalla_id=j["brawlhalla_id"],
|
|
||||||
name=j["name"]
|
|
||||||
)
|
|
||||||
session.add(bh)
|
|
||||||
session.flush()
|
|
||||||
|
|
||||||
async with hcs.get(f"https://api.brawlhalla.com/player/{bh.brawlhalla_id}/ranked?api_key={self.token()}") as response:
|
|
||||||
if response.status != 200:
|
|
||||||
raise rc.ExternalError(f"Brawlhalla API /ranked returned {response.status}!")
|
|
||||||
j = await response.json()
|
|
||||||
if j == {} or j == []:
|
|
||||||
log.debug("No ranked info found.")
|
|
||||||
else:
|
|
||||||
await self._change(session=session, obj=bh, attribute="rating_1v1", new=j["rating"])
|
|
||||||
metal_name, tier_name = j["tier"].split(" ", 1)
|
|
||||||
metal = BrawlhallaMetal[metal_name.upper()]
|
|
||||||
tier = BrawlhallaTier(int(tier_name))
|
|
||||||
rank = BrawlhallaRank(metal=metal, tier=tier)
|
|
||||||
await self._change(session=session, obj=bh, attribute="rank_1v1", new=rank)
|
|
||||||
|
|
||||||
for jduo in j.get("2v2", []):
|
|
||||||
bhduo: Optional[BrawlhallaDuo] = await ru.asyncify(
|
|
||||||
session.query(DuoT)
|
|
||||||
.filter(
|
|
||||||
or_(
|
|
||||||
and_(
|
|
||||||
DuoT.id_one == jduo["brawlhalla_id_one"],
|
|
||||||
DuoT.id_two == jduo["brawlhalla_id_two"]
|
|
||||||
),
|
|
||||||
and_(
|
|
||||||
DuoT.id_one == jduo["brawlhalla_id_two"],
|
|
||||||
DuoT.id_two == jduo["brawlhalla_id_one"]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.one_or_none
|
|
||||||
)
|
|
||||||
if bhduo is None:
|
|
||||||
if bh.brawlhalla_id == jduo["brawlhalla_id_one"]:
|
|
||||||
otherbh: Optional[Brawlhalla] = await ru.asyncify(
|
|
||||||
session.query(BrawlhallaT).get, jduo["brawlhalla_id_two"]
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
otherbh: Optional[Brawlhalla] = await ru.asyncify(
|
|
||||||
session.query(BrawlhallaT).get, jduo["brawlhalla_id_one"]
|
|
||||||
)
|
|
||||||
if otherbh is None:
|
|
||||||
continue
|
|
||||||
bhduo = DuoT(
|
|
||||||
one=bh,
|
|
||||||
two=otherbh,
|
|
||||||
)
|
|
||||||
|
|
||||||
session.add(bhduo)
|
|
||||||
await self._change(session=session, obj=bhduo, attribute="rating_2v2", new=jduo["rating"])
|
|
||||||
metal_name, tier_name = jduo["tier"].split(" ", 1)
|
|
||||||
metal = BrawlhallaMetal[metal_name.upper()]
|
|
||||||
tier = BrawlhallaTier(int(tier_name))
|
|
||||||
rank = BrawlhallaRank(metal=metal, tier=tier)
|
|
||||||
await self._change(session=session, obj=bhduo, attribute="rank_2v2", new=rank)
|
|
||||||
|
|
||||||
async def on_increase(self, session, obj: Union[Brawlhalla, BrawlhallaDuo], attribute: str, old: Any, new: Any) -> None:
|
|
||||||
if attribute == "rank_1v1":
|
|
||||||
await self.notify(f"📈 [b]{obj.steam.user}[/b] è salito a [b]{new}[/b] ({obj.rating_1v1} MMR) in 1v1 su Brawlhalla! Congratulazioni!")
|
|
||||||
elif attribute == "rank_2v2":
|
|
||||||
await self.notify(f"📈 [b]{obj.one.steam.user}[/b] e [b]{obj.two.steam.user}[/b] sono saliti a [b]{new}[/b] ({obj.rating_2v2} MMR) in 2v2 su Brawlhalla! Congratulazioni!")
|
|
||||||
|
|
||||||
async def on_unchanged(self, session, obj: Union[Brawlhalla, BrawlhallaDuo], attribute: str, old: Any, new: Any) -> None:
|
|
||||||
pass
|
|
||||||
|
|
||||||
async def on_decrease(self, session, obj: Union[Brawlhalla, BrawlhallaDuo], attribute: str, old: Any, new: Any) -> None:
|
|
||||||
if attribute == "rank_1v1":
|
|
||||||
await self.notify(f"📉 [b]{obj.steam.user}[/b] è sceso a [b]{new}[/b] ({obj.rating_1v1} MMR) in 1v1 su Brawlhalla.")
|
|
||||||
elif attribute == "rank_2v2":
|
|
||||||
await self.notify(f"📉 [b]{obj.one.steam.user}[/b] e [b]{obj.two.steam.user}[/b] sono scesi a [b]{new}[/b] ({obj.rating_2v2} MMR) in 2v2 su Brawlhalla.")
|
|
||||||
|
|
||||||
async def on_first(self, session, obj: Union[Brawlhalla, BrawlhallaDuo], attribute: str, old: None, new: Any) -> None:
|
|
||||||
if attribute == "rank_1v1":
|
|
||||||
await self.notify(f"🌟 [b]{obj.steam.user}[/b] si è classificato a [b]{new}[/b] ({obj.rating_1v1} MMR) in 1v1 su Brawlhalla!")
|
|
||||||
elif attribute == "rank_2v2":
|
|
||||||
await self.notify(f"🌟 [b]{obj.one.steam.user}[/b] e [b]{obj.two.steam.user}[/b] si sono classificati a [b]{new}[/b] ({obj.rating_2v2} MMR) in 2v2 su Brawlhalla!")
|
|
||||||
|
|
||||||
async def on_reset(self, session, obj: Union[Brawlhalla, BrawlhallaDuo], attribute: str, old: Any, new: None) -> None:
|
|
||||||
if attribute == "rank_1v1":
|
|
||||||
await self.notify(f"⬜️ [b]{obj.steam.user}[/b] non ha più un rank su Brawlhalla.")
|
|
||||||
elif attribute == "rank_2v2":
|
|
||||||
await self.notify(f"⬜️ [b]{obj.one.steam.user}[/b] e [b]{obj.two.steam.user}[/b] non hanno più un rank su Brawlhalla.")
|
|
||||||
|
|
||||||
def describe(self, obj: Steam) -> str:
|
|
||||||
bh = obj.brawlhalla
|
|
||||||
|
|
||||||
string = [f"ℹ️ [b]{bh.name}[/b]", ""]
|
|
||||||
|
|
||||||
if bh.rank_1v1:
|
|
||||||
string.append("👤 [b]1v1[/b]")
|
|
||||||
string.append(f"[b]{bh.rank_1v1}[/b] ({bh.rating_1v1} MMR)")
|
|
||||||
string.append("")
|
|
||||||
|
|
||||||
if len(bh.duos) != 0:
|
|
||||||
string.append(f"👥 [b]2v2[/b]")
|
|
||||||
|
|
||||||
for duo in sorted(bh.duos, key=lambda d: -d.rating_2v2):
|
|
||||||
other = duo.other(bh)
|
|
||||||
string.append(f"Con [b]{other.steam.user}[/b]: [b]{duo.rank_2v2}[/b] ({duo.rating_2v2} MMR)")
|
|
||||||
|
|
||||||
if len(bh.duos) != 0:
|
|
||||||
string.append("")
|
|
||||||
|
|
||||||
return "\n".join(string)
|
|
|
@ -2,6 +2,7 @@ from typing import *
|
||||||
import royalnet.commands as rc
|
import royalnet.commands as rc
|
||||||
import royalnet.utils as ru
|
import royalnet.utils as ru
|
||||||
import royalspells as rs
|
import royalspells as rs
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
class SpellCommand(rc.Command):
|
class SpellCommand(rc.Command):
|
||||||
|
@ -27,6 +28,14 @@ class SpellCommand(rc.Command):
|
||||||
rows.append(f"Multiattacco: [b]×{dmg.repeat}[/b]")
|
rows.append(f"Multiattacco: [b]×{dmg.repeat}[/b]")
|
||||||
rows.append("")
|
rows.append("")
|
||||||
|
|
||||||
|
# Halloween 2020
|
||||||
|
possible_dmg = (dmg.dice_number * dmg.dice_type + dmg.constant) * dmg.repeat
|
||||||
|
if possible_dmg >= 250:
|
||||||
|
async with data.session_acm() as session:
|
||||||
|
author = await data.find_author(session=session, required=False)
|
||||||
|
if author is not None and author.halloween2020 is not None:
|
||||||
|
author.halloween2020.i = datetime.datetime.now()
|
||||||
|
|
||||||
if spell.healing_component:
|
if spell.healing_component:
|
||||||
heal: rs.HealingComponent = spell.healing_component
|
heal: rs.HealingComponent = spell.healing_component
|
||||||
constant_str: str = f"{heal.constant:+d}" if heal.constant != 0 else ""
|
constant_str: str = f"{heal.constant:+d}" if heal.constant != 0 else ""
|
||||||
|
|
54
royalpack/commands/trionfireali.py
Normal file
54
royalpack/commands/trionfireali.py
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
from typing import *
|
||||||
|
import logging
|
||||||
|
import aiohttp
|
||||||
|
import royalnet.commands as rc
|
||||||
|
import royalnet.utils as ru
|
||||||
|
from royalnet.backpack import tables as rbt
|
||||||
|
from .abstract.linker import LinkerCommand
|
||||||
|
|
||||||
|
from ..tables import Steam, Dota
|
||||||
|
from ..types import DotaRank
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class TrionfirealiCommand(LinkerCommand):
|
||||||
|
name: str = "trionfireali"
|
||||||
|
|
||||||
|
description: str = "Visualizza il tuo pr⊕gress⊕ nei Tri⊕nfi Reali!"
|
||||||
|
|
||||||
|
syntax: str = ""
|
||||||
|
|
||||||
|
def describe(self, obj: Steam) -> str:
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
async def get_updatables_of_user(self, session, user: rbt.User) -> List[Dota]:
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
async def get_updatables(self, session) -> List[Dota]:
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
async def create(self,
|
||||||
|
session,
|
||||||
|
user: rbt.User,
|
||||||
|
args: rc.CommandArgs,
|
||||||
|
data: Optional[rc.CommandData] = None) -> Optional[Dota]:
|
||||||
|
raise rc.InvalidInputError("Trionfi Reali accounts are automatically linked from Steam.")
|
||||||
|
|
||||||
|
async def update(self, session, obj: Steam, change: Callable[[str, Any], Awaitable[None]]):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
async def on_increase(self, session, obj: Dota, attribute: str, old: Any, new: Any) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def on_unchanged(self, session, obj: Dota, attribute: str, old: Any, new: Any) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def on_decrease(self, session, obj: Dota, attribute: str, old: Any, new: Any) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def on_first(self, session, obj: Dota, attribute: str, old: None, new: Any) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def on_reset(self, session, obj: Dota, attribute: str, old: Any, new: None) -> None:
|
||||||
|
pass
|
|
@ -42,6 +42,5 @@ class ApiUserRygStar(rca.ApiStar):
|
||||||
"leagueoflegends": [leagueoflegends.json() for leagueoflegends in user.leagueoflegends],
|
"leagueoflegends": [leagueoflegends.json() for leagueoflegends in user.leagueoflegends],
|
||||||
"osu": [osu.json() for osu in user.osu],
|
"osu": [osu.json() for osu in user.osu],
|
||||||
"trivia": user.trivia_score.json() if user.trivia_score is not None else None,
|
"trivia": user.trivia_score.json() if user.trivia_score is not None else None,
|
||||||
"halloween2020": user.halloween2020.json() if user.halloween2020 is not None else None,
|
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -23,5 +23,4 @@ class ApiUserRygListStar(rca.ApiStar):
|
||||||
"leagueoflegends": [leagueoflegends.json() for leagueoflegends in user.leagueoflegends],
|
"leagueoflegends": [leagueoflegends.json() for leagueoflegends in user.leagueoflegends],
|
||||||
"osu": [osu.json() for osu in user.osu],
|
"osu": [osu.json() for osu in user.osu],
|
||||||
"trivia": user.trivia_score.json() if user.trivia_score is not None else None,
|
"trivia": user.trivia_score.json() if user.trivia_score is not None else None,
|
||||||
"halloween2020": user.halloween2020.json() if user.halloween2020 is not None else None,
|
|
||||||
} for user in users if "member" in user.roles]
|
} for user in users if "member" in user.roles]
|
||||||
|
|
|
@ -7,12 +7,12 @@ class Halloween2020:
|
||||||
__tablename__ = "halloween2020"
|
__tablename__ = "halloween2020"
|
||||||
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
def user_id(self):
|
def _steamid(self):
|
||||||
return Column(Integer, ForeignKey("users.uid"), primary_key=True)
|
return Column(BigInteger, ForeignKey("steam._steamid"), primary_key=True)
|
||||||
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
def user(self):
|
def steam(self):
|
||||||
return relationship("User", backref=backref("halloween2020", uselist=False))
|
return relationship("Steam", backref=backref("halloween2020", uselist=False))
|
||||||
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
def zero(self):
|
def zero(self):
|
||||||
|
|
|
@ -76,7 +76,8 @@ class Steam:
|
||||||
"most_played_game_forever": self.most_played_game_forever,
|
"most_played_game_forever": self.most_played_game_forever,
|
||||||
|
|
||||||
"dota": self.dota.json() if self.dota is not None else None,
|
"dota": self.dota.json() if self.dota is not None else None,
|
||||||
"brawlhalla": self.brawlhalla.json() if self.brawlhalla is not None else None
|
"brawlhalla": self.brawlhalla.json() if self.brawlhalla is not None else None,
|
||||||
|
"halloween2020": self.halloween2020.json() if self.halloween2020 is not None else None,
|
||||||
}
|
}
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|
168
royalpack/types/halloween2020tarots.py
Normal file
168
royalpack/types/halloween2020tarots.py
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
from typing import *
|
||||||
|
|
||||||
|
|
||||||
|
class Halloween2020Tarot:
|
||||||
|
def __init__(self,
|
||||||
|
variable: str,
|
||||||
|
title: str,
|
||||||
|
roman: str,
|
||||||
|
name: str,
|
||||||
|
objective: str,
|
||||||
|
puzzle: str,
|
||||||
|
check: Optional[Callable[..., Awaitable[...]]]):
|
||||||
|
self.variable: str = variable
|
||||||
|
self.title: str = title
|
||||||
|
self.roman: str = roman
|
||||||
|
self.name: str = name
|
||||||
|
self.objective: str = objective
|
||||||
|
self.puzzle: str = puzzle
|
||||||
|
self.check: Optional[Callable[..., Awaitable[...]]] = check
|
||||||
|
|
||||||
|
|
||||||
|
halloween2020tarots = (
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="zero",
|
||||||
|
title="o",
|
||||||
|
roman="0",
|
||||||
|
name="Il Folle",
|
||||||
|
objective="Partecipa ai Trionfi Reali.",
|
||||||
|
puzzle="Scopri nuovi indizi ottenendo dei Trionfi!",
|
||||||
|
check=None,
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="i",
|
||||||
|
title="i",
|
||||||
|
roman="I",
|
||||||
|
name="Il Mago",
|
||||||
|
objective="Trova una magia che possa fare almeno 250 danni.",
|
||||||
|
puzzle="L'ultimo giorno del decimo mese...",
|
||||||
|
check=None,
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="ii",
|
||||||
|
title="ii",
|
||||||
|
roman="II",
|
||||||
|
name="La Papessa",
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="iii",
|
||||||
|
title="iii",
|
||||||
|
roman="III",
|
||||||
|
name="L'Imperatrice",
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="iv",
|
||||||
|
title="iv",
|
||||||
|
roman="IV",
|
||||||
|
name="L'Imperatore",
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="v",
|
||||||
|
title="v",
|
||||||
|
roman="V",
|
||||||
|
name="Il Papa",
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="vi",
|
||||||
|
title="vi",
|
||||||
|
roman="VI",
|
||||||
|
name="Gli Amanti",
|
||||||
|
objective="Completa [url=https://store.steampowered.com/app/698780]Doki Doki "
|
||||||
|
"Literature Club[/url].",
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="vii",
|
||||||
|
title="vii",
|
||||||
|
roman="VII",
|
||||||
|
name="Il Carro",
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="viii",
|
||||||
|
title="viii",
|
||||||
|
roman="VIII",
|
||||||
|
name="La Giustizia",
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="ix",
|
||||||
|
title="ix",
|
||||||
|
roman="IX",
|
||||||
|
name="L'Eremita",
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="x",
|
||||||
|
title="x",
|
||||||
|
roman="X",
|
||||||
|
name="La Fortuna",
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="xi",
|
||||||
|
title="xi",
|
||||||
|
roman="XI",
|
||||||
|
name="La Forza",
|
||||||
|
objective="Gioca 3 partite Ranked 1v1 su "
|
||||||
|
"[url=https://steamcommunity.com/id/steffo1999/stats/appid/291550/achievements]Brawlhalla[/url]."
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="xii",
|
||||||
|
title="xii",
|
||||||
|
roman="XII",
|
||||||
|
name="L'Appeso",
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="xiii",
|
||||||
|
title="xiii",
|
||||||
|
roman="XIII",
|
||||||
|
name="La Morte",
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="xiv",
|
||||||
|
title="xiv",
|
||||||
|
roman="XIV",
|
||||||
|
name="La Temperanza",
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="xv",
|
||||||
|
title="xv",
|
||||||
|
roman="XV",
|
||||||
|
name="Il Diavolo",
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="xvi",
|
||||||
|
title="xvi",
|
||||||
|
roman="XVI",
|
||||||
|
name="La Torre",
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="xvii",
|
||||||
|
title="xvii",
|
||||||
|
roman="XVII",
|
||||||
|
name="Le Stelle",
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="xviii",
|
||||||
|
title="xviii",
|
||||||
|
roman="XVIII",
|
||||||
|
name="La Luna",
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="xix",
|
||||||
|
title="xix",
|
||||||
|
roman="XIX",
|
||||||
|
name="Il Sole",
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="xx",
|
||||||
|
title="xx",
|
||||||
|
roman="XX",
|
||||||
|
name="Il Giudizio",
|
||||||
|
),
|
||||||
|
Halloween2020Tarot(
|
||||||
|
variable="xxi",
|
||||||
|
title="xxi",
|
||||||
|
roman="XII",
|
||||||
|
name="Il Mondo",
|
||||||
|
objective="Risolvi il mistero dei Trionfi Reali.",
|
||||||
|
puzzle="""44°35'45.0"N 11°02'58.9"E""",
|
||||||
|
check=None,
|
||||||
|
),
|
||||||
|
)
|
Loading…
Reference in a new issue