fix pool filtering exclude welfare and limited from regular, remove pull embed, single process
This commit is contained in:
1 parent
55824e8a5a
commit
6dbd8f09ca
2 files changed
+23
-44
No files matched your search
+17
-11
@@ -63,8 +63,6 @@ def wiki_portrait_url(student: dict) -> str:
|
|||||||
def schale_portrait_url(student_id: int) -> str:
|
def schale_portrait_url(student_id: int) -> str:
|
||||||
"""Full-body sprite URL (fallback if wiki portrait is unavailable)."""
|
"""Full-body sprite URL (fallback if wiki portrait is unavailable)."""
|
||||||
return f"{SCHALE_PORTRAIT}/{student_id}.webp"
|
return f"{SCHALE_PORTRAIT}/{student_id}.webp"
|
||||||
PORTRAIT_BASE = "https://raw.githubusercontent.com/SchaleDB/SchaleDB/main/images/student/portrait"
|
|
||||||
ICON_BASE = "https://raw.githubusercontent.com/SchaleDB/SchaleDB/main/images/student/icon"
|
|
||||||
|
|
||||||
|
|
||||||
class StudentDB:
|
class StudentDB:
|
||||||
@@ -83,36 +81,44 @@ class StudentDB:
|
|||||||
with open(BUNDLED_DB, "r", encoding="utf-8") as f:
|
with open(BUNDLED_DB, "r", encoding="utf-8") as f:
|
||||||
self.students = json.load(f)
|
self.students = json.load(f)
|
||||||
|
|
||||||
|
excluded = 0
|
||||||
for s in self.students:
|
for s in self.students:
|
||||||
sid = s["Id"]
|
sid = s["Id"]
|
||||||
name = s["Name"].lower()
|
name = s["Name"].lower()
|
||||||
rarity = s["StarGrade"]
|
rarity = s["StarGrade"]
|
||||||
|
limit = s.get("IsLimited") or 0
|
||||||
|
|
||||||
self.by_id[sid] = s
|
self.by_id[sid] = s
|
||||||
self.by_name[name] = s
|
self.by_name[name] = s
|
||||||
|
|
||||||
|
# Exclude welfare/event characters (IsLimited >= 2) from pullable pool
|
||||||
|
if limit >= 2:
|
||||||
|
excluded += 1
|
||||||
|
continue
|
||||||
|
|
||||||
if rarity in self.by_rarity:
|
if rarity in self.by_rarity:
|
||||||
self.by_rarity[rarity].append(s)
|
self.by_rarity[rarity].append(s)
|
||||||
|
|
||||||
self._loaded = True
|
self._loaded = True
|
||||||
log.info(
|
log.info(
|
||||||
"Loaded %d students (1*: %d, 2*: %d, 3*: %d)",
|
"Loaded %d students (1*: %d, 2*: %d, 3*: %d) — %d welfare excluded",
|
||||||
len(self.students),
|
len(self.students),
|
||||||
len(self.by_rarity[1]),
|
len(self.by_rarity[1]),
|
||||||
len(self.by_rarity[2]),
|
len(self.by_rarity[2]),
|
||||||
len(self.by_rarity[3]),
|
len(self.by_rarity[3]),
|
||||||
|
excluded,
|
||||||
)
|
)
|
||||||
|
|
||||||
def get(self, student_id: int) -> Optional[dict]:
|
def random_by_rarity(self, rarity: int, exclude_limited: bool = False) -> dict:
|
||||||
return self.by_id.get(student_id)
|
"""Pick a random student of the given base rarity.
|
||||||
|
|
||||||
def get_by_name(self, name: str) -> Optional[dict]:
|
If exclude_limited is True, only returns standard-pool characters
|
||||||
return self.by_name.get(name.lower())
|
(IsLimited == 0). Used by Regular Recruitment to exclude banner-only units.
|
||||||
|
"""
|
||||||
def random_by_rarity(self, rarity: int) -> dict:
|
|
||||||
"""Pick a random student of the given base rarity (1, 2, or 3)."""
|
|
||||||
pool = self.by_rarity.get(rarity, [])
|
pool = self.by_rarity.get(rarity, [])
|
||||||
|
if exclude_limited:
|
||||||
|
pool = [s for s in pool if (s.get("IsLimited") or 0) == 0]
|
||||||
if not pool:
|
if not pool:
|
||||||
# Fallback: any student
|
|
||||||
pool = self.students
|
pool = self.students
|
||||||
return random.choice(pool)
|
return random.choice(pool)
|
||||||
|
|
||||||
|
|||||||
+6
-33
@@ -230,6 +230,9 @@ class BlueArchiveGacha(commands.Cog):
|
|||||||
# "Opening envelope" teaser
|
# "Opening envelope" teaser
|
||||||
teaser = await ctx.reply("Opening recruitment envelope" + ("s..." if count > 1 else "..."))
|
teaser = await ctx.reply("Opening recruitment envelope" + ("s..." if count > 1 else "..."))
|
||||||
|
|
||||||
|
# Determine pool scope: regular banner excludes limiteds
|
||||||
|
is_regular = (banner_id is None or banner_id == "regular")
|
||||||
|
|
||||||
# Perform pulls
|
# Perform pulls
|
||||||
pulls = []
|
pulls = []
|
||||||
for i in range(count):
|
for i in range(count):
|
||||||
@@ -239,7 +242,7 @@ class BlueArchiveGacha(commands.Cog):
|
|||||||
r = PULL10_RATES
|
r = PULL10_RATES
|
||||||
|
|
||||||
rarity = roll_rarity(r)
|
rarity = roll_rarity(r)
|
||||||
student = db.random_by_rarity(rarity)
|
student = db.random_by_rarity(rarity, exclude_limited=is_regular)
|
||||||
|
|
||||||
# Check for rate-up weighting (simplified: 30% chance to hit rate-up if 3★)
|
# Check for rate-up weighting (simplified: 30% chance to hit rate-up if 3★)
|
||||||
if banner and rarity == 3 and banner.get("rateups"):
|
if banner and rarity == 3 and banner.get("rateups"):
|
||||||
@@ -267,43 +270,13 @@ class BlueArchiveGacha(commands.Cog):
|
|||||||
async with ctx.typing():
|
async with ctx.typing():
|
||||||
img_bytes = await render_pull(pulls, banner_name, spark)
|
img_bytes = await render_pull(pulls, banner_name, spark)
|
||||||
|
|
||||||
# Build summary embed
|
# Send image only — the picture says it all
|
||||||
rarity_counts = {3: 0, 2: 0, 1: 0}
|
|
||||||
for p in pulls:
|
|
||||||
rarity_counts[p["StarGrade"]] += 1
|
|
||||||
|
|
||||||
summary_lines = [f"{p['StarGrade']}★ {p['Name']}" for p in pulls]
|
|
||||||
summary_text = "\n".join(summary_lines)
|
|
||||||
|
|
||||||
best = max(pulls, key=lambda p: p["StarGrade"])
|
|
||||||
embed = discord.Embed(
|
|
||||||
title=f"{count}x Recruitment Result",
|
|
||||||
description=summary_text,
|
|
||||||
color={
|
|
||||||
3: 0xF0C040,
|
|
||||||
2: 0xB478DC,
|
|
||||||
1: 0x64A0DC,
|
|
||||||
}.get(best["StarGrade"], 0x5BA0D0),
|
|
||||||
)
|
|
||||||
embed.add_field(
|
|
||||||
name="Summary",
|
|
||||||
value=f"3★: {rarity_counts[3]} | 2★: {rarity_counts[2]} | 1★: {rarity_counts[1]}",
|
|
||||||
)
|
|
||||||
embed.add_field(name="Banner", value=banner_name, inline=False)
|
|
||||||
embed.add_field(
|
|
||||||
name="Recruitment Points",
|
|
||||||
value=f"{spark}/{SPARK_TARGET} {'-- Spark Ready!' if spark >= SPARK_TARGET else ''}",
|
|
||||||
)
|
|
||||||
embed.set_footer(text=f"Top pull: {best['StarGrade']}★ {best['Name']} ({best.get('School', '')})")
|
|
||||||
|
|
||||||
# Send image and embed
|
|
||||||
file = discord.File(img_bytes, filename="gacha_result.png")
|
file = discord.File(img_bytes, filename="gacha_result.png")
|
||||||
embed.set_image(url="attachment://gacha_result.png")
|
|
||||||
try:
|
try:
|
||||||
await teaser.delete()
|
await teaser.delete()
|
||||||
except (discord.NotFound, discord.Forbidden):
|
except (discord.NotFound, discord.Forbidden):
|
||||||
pass
|
pass
|
||||||
await ctx.reply(file=file, embed=embed)
|
await ctx.reply(file=file)
|
||||||
|
|
||||||
@commands.command(name="spark")
|
@commands.command(name="spark")
|
||||||
async def spark(self, ctx: commands.Context, *, character_name: str = "") -> None:
|
async def spark(self, ctx: commands.Context, *, character_name: str = "") -> None:
|
||||||
|
|||||||
Reference in new issue
Block a user