Untitled
unknown
python
3 months ago
12 kB
8
Indexable
ATTEMPT_VALUES = [1, 2, 3, 4, 5, 6]
ATTEMPT_WEIGHTS = [2, 12, 15, 12, 8, 7]
MAX_PASSES = 10
MAX_BALLS = 10
FAIL_TEXT = [
"Le Pokémon se débat !",
"La Pokéball a rebondit !",
"Il esquive la balle !",
"La Pokéball s'ouvre !",
"Ça y était presque !",
"Il veut te résister !",
"La cible a ésquiver !"
]
UI = {
"caught": "<:caught:1379044694922760282>",
"uncaught": "<:uncaught:1379044710437617674>",
"waiting": "<a:waiting:1379500515343470613>",
"success": "<a:success:1379500529171955722>",
"random": "<a:random:1379500466945130597>",
"fled": "<a:fled:1379500541037514833>",
"shiny": "<a:shiny:1377962995552096388>"
}
db = lambda c: SlashMongo("inventory", c)
items = db("items")
daycare = db("daycare")
pokedex = db("emojis")
daily = db("daily")
icons = db("ressource")
class PokeCatch(View):
def __init__(self, user_id):
self.user_id = user_id
self.filter = {"user_id": str(user_id)}
self.passes = MAX_PASSES
self.balls = MAX_BALLS
self.captured = 0
self.tries = 0
self.ended = False
self.evo_rdy = False
# -- INIT --
async def initialize(self):
data = await icons.find({})
self.icon = dict((e["type"], e["icon"]) for e in data)
self.anim = dict((e["type"], e["animated"]) for e in data)
self.choices = await pokedex.find({})
self.weights = await self.get_rarity_weights()
async def get_rarity_weights(self):
data = await daily.find_one(self.filter) or {}
badges = data.get("user_badges", [])
boost = min(1 + 0.02 * len(badges), 1.3)
return list(
p["weight"] * boost
if p["weight"] <= 0.3 else p["weight"]
for p in self.choices
)
# -- ENCOUNTER --
def get_catch_rate(self):
chance = (self.pkmn["weight"] ** 1.2) * 0.5
chance += min((self.tries - 1) * 0.03, 0.1)
return max(0.05, min(chance, 0.35))
async def pick_pokemon(self):
self.pkmn, = pyrandom.choices(
self.choices, weights=self.weights, k=1
)
self.max_tries, = pyrandom.choices(
ATTEMPT_VALUES, weights=ATTEMPT_WEIGHTS, k=1
)
self.tries = 0
self.p_id = self.pkmn["item_numb"]
self.p_name = self.pkmn["emoji_name"]
self.p_emoji = f"<a:{self.p_name}:{self.pkmn['emoji_id']}>"
async def start_encounter(self, i):
await self.respond(i, UI["random"], components=False)
await sleep(0.4)
await self.pick_pokemon()
embed = await self.encounter_embed()
await self.respond(i, self.render_pkmn(), embed)
# -- UI HELPERS --
async def respond(self, i, content, embed=None, components=True):
respond_interaction(
i,
content,
embed=embed,
components=self if components else None
)
def try_bonus(self):
if self.ended:
return ""
r = pyrandom.random()
if r < 0.04:
self.balls += 1
return "\n\n🎁 Cadeau Bonus : **+1 Pokéball** !"
if r < 0.08:
self.passes += 1
return "\n\n🎁 Cadeau Bonus : **+1 Passe** !"
return ""
def embed(self, text, color=0x248046):
return Message(description=text, color=color)
def render_pkmn(self):
emoji = self.anim.get(self.pkmn["types"][0], "🌲")
return f"{emoji} {self.p_emoji} {emoji}"
def get_types(self, types):
return " ".join(
f"{self.icon.get(t,'')} {t}"
for t in types
)
def xp_bar(self, current, total, size=10):
if not total:
return "▱" * size
filled = round(current / total * size)
return "▰" * filled + "▱" * (size - filled)
def get_rarity(self):
w = self.pkmn["weight"]
if w >= 0.5: return "Commun"
if w >= 0.4: return "Peu commun"
if w >= 0.2: return "Rare"
if w >= 0.1: return "Très Rare"
return "Légendaire"
async def is_caught(self):
item = await items.find_one({
"item_numb": self.p_id,
**self.filter
})
return UI["caught"] if item else UI["uncaught"]
def check_end_of_hunt(self):
if self.passes <= 0 or self.balls <= 0:
self.ended = True
# -- EMBEDS --
async def encounter_embed(self):
status = await self.is_caught()
types = self.get_types(self.pkmn['types'])
return self.embed(
"-# 🌿 Nouveau Pokémon sauvage !\n\n"
f"🔹*N°{self.p_id} :* {status} **{self.p_name}**\n"
f"🔹*Types :* {types}\n"
f"🔹*Rareté :* {self.get_rarity()}"
)
async def result_embed(self):
name = f"**{self.p_name}** {self.p_emoji}"
if self.caught:
text = f"Et Hop !\n{name} a été capturé ✨"
text += await self.update_challenge()
text += await self.add_daycare_xp()
content, color = UI["success"], 0xFFAC32
else:
text = f"Oh Non...\nLe {name} s'enfuit ! 😔"
content, color = UI["fled"], 0xFF0000
text += self.bonus
if self.ended:
text += (
f"\n\n⏰ Fin de la chasse.\n"
f"🏆 Pokémon capturés : **{self.captured}**"
)
return self.embed(text, color), content
# -- CAPTURE FLOW --
async def throw_ball(self, i):
roll = pyrandom.random()
chance = self.get_catch_rate()
self.caught = roll < chance
delta = chance - roll
delay = (
3.5 if self.caught
else 2.6 if delta > -0.06
else 1.6
)
embed = self.embed(
f"{i.user.mention}\n"
"lance une **Poké Ball** !",
0x0094FF
)
await self.respond(i, UI["waiting"], embed, False)
await sleep(delay)
async def failed_try(self, i):
embed = self.embed(
f"❌ **Échec** de la capture...\n"
f"{pyrandom.choice(FAIL_TEXT)}",
0xFF0000
)
await self.respond(i, self.render_pkmn(), embed)
async def end_capture(self, i):
if self.caught:
await items.update_one(
{"item_numb": self.p_id, **self.filter},
{"$inc": {"count": 1}},
upsert=True
)
self.check_end_of_hunt()
self.bonus = self.try_bonus()
embed, content = await self.result_embed()
self.update_btns(lock_capture=True)
await self.respond(i, content, embed)
if self.ended and not self.evo_rdy:
self.stop()
# -- BUTTONS --
async def verify(self, i):
if i.user.id != self.user_id:
return False
await defer(i, action="update")
return True
def update_btns(self, lock_capture=False):
show_evo = self.ended and self.evo_rdy
self.update_component(
"ball",
label=f"Poké Balls ({self.balls})",
hidden=show_evo,
is_disabled=lock_capture
)
self.update_component(
"skip",
label=f"Passes ({self.passes})",
hidden=show_evo,
is_disabled=self.passes <= 0 or self.ended
)
self.update_component(
"evo",
hidden=not show_evo
)
@button(label=f"Poké Balls ({MAX_BALLS})", style="success", custom_id="ball")
async def capture(self, i, b):
if not await self.verify(i):
return
self.tries += 1
self.balls -= 1
self.update_btns()
await self.throw_ball(i)
if self.caught:
self.captured += 1
return await self.end_capture(i)
if self.tries >= self.max_tries or self.balls <= 0:
return await self.end_capture(i)
await self.failed_try(i)
@button(label=f"Passes ({MAX_PASSES})", style="primary", custom_id="skip")
async def skip(self, i, b):
if not await self.verify(i):
return
self.passes -= 1
self.update_btns()
await self.start_encounter(i)
@button(label="✨ Évolution", style="success", hidden=True, custom_id="evo")
async def evolve(self, i, b):
if not await self.verify(i):
return
await self.animate_evolution(i, self.evo_data, self.evo)
self.stop()
# -- DAYCARE --
async def add_daycare_xp(self):
data = await daycare.find_one(self.filter)
if not data:
return ""
gain = pyrandom.randint(10, 20)
total = data["xp"] + gain
required = data["xp_required"]
await daycare.update_one(
self.filter, {"$inc": {"xp": gain}}
)
if total >= required:
self.evo_rdy = True
self.evo_data = data
await self.pick_evolved(data)
return (
"\n\n🆙 Ton "
f"**{data['emoji_name']}** gagne **{gain} XP**\n"
f"{self.xp_bar(total, required)} "
f"({min(total, required)}/{required})"
)
async def pick_evolved(self, data):
await daycare.delete_one(self.filter)
self.evo = await pokedex.find_one({
"item_numb": pyrandom.choice(data["evolution_numb"])
})
await items.update_one(
{"item_numb": self.evo["item_numb"], **self.filter},
{"$inc": {"count": 1}},
upsert=True
)
async def animate_evolution(self, i, data, evo):
old = data['emoji_name']
new = evo['emoji_name']
glow = UI["shiny"]
frames = [
f"{glow}<a:{old}:{data['emoji_id']}>{glow}",
f"{glow}<a:{new}:{evo['emoji_id']}>{glow}"
]
async def animate(index, _):
is_final = index == 5
desc = (
f"Ton **{old}** évolue en...\n# {new} ! 🎉"
if is_final else
f"Quoi ??\nTon **{old}** évolue !"
)
content = frames[index % 2]
embed = self.embed(desc, color=0xFFAC32)
await self.respond(i, content, embed, False)
await sleep(0.35)
loop(6, animate)
# -- CHALLENGE --
async def update_challenge(self):
data = await daily.find_one(self.filter) or {}
ch = data.get("challenge")
if not ch:
return ""
badge = ch["current_badge"]
goal = ch["capture_goal"]
count = ch["count"]
if badge not in self.pkmn["types"] or count >= goal:
return ""
await daily.update_one(
self.filter, {"$inc": {"challenge.count": 1}}
)
count += 1
badge_str = self.get_types([badge])
if count >= goal:
return f"\n\n🎯 Défi **{badge_str}** terminé !"
return f"\n\n🎯 Défi **{badge_str}** : {count}/{goal}"
view = PokeCatch(user.id)
await view.initialize()
await view.start_encounter(interaction)
if await view.wait(scope=scope, timeout=60) == "timeout":
await view.respond(interaction, "⏳ Timeout...", components=False)
view.stop()Editor is loading...
Leave a Comment