优化出门历练,更加沉浸

This commit is contained in:
liuwei
2025-11-24 17:21:12 +08:00
parent 9d4737860a
commit acb112b318

View File

@@ -776,6 +776,10 @@ class XiuxianPlugin(MessagePluginInterface):
duration_hours = max(0.0, min(duration_hours, float(self.max_cultivate_hours)))
mult = self._yield_multiplier(player.get("realm", "炼气1层"))
rate = self.base_rate_per_hour * float(player.get("spirit_root_mult", 1.0)) * mult
cbn = float(player.get("cultivate_bonus_next", 0.0) or 0.0)
if cbn > 0:
rate = rate * (1.0 + cbn)
player["cultivate_bonus_next"] = 0.0
gain = int(duration_hours * rate)
player["cultivation_points"] = int(player.get("cultivation_points", 0)) + gain
player["status"] = "Unstable_Qi"
@@ -814,9 +818,25 @@ class XiuxianPlugin(MessagePluginInterface):
return False, "灵石不足"
player["spirit_stone"] = stones - qty
bonus = float(player.get("gather_bonus", 0.0))
debuff = float(player.get("gather_debuff", 0.0) or 0.0)
gd_until = player.get("gather_debuff_until")
if gd_until:
try:
u = datetime.fromisoformat(gd_until)
if u and u.tzinfo is None:
u = u.replace(tzinfo=timezone.utc)
if not u or datetime.now(timezone.utc) >= u:
debuff = 0.0
player["gather_debuff"] = 0.0
player["gather_debuff_until"] = None
except Exception:
debuff = 0.0
player["gather_debuff"] = 0.0
player["gather_debuff_until"] = None
base_gain = qty * 10
mult = self._yield_multiplier(player.get("realm", "炼气1层"))
gain = int(base_gain * (1.0 + bonus) * mult)
factor = max(0.1, 1.0 + bonus + debuff)
gain = int(base_gain * factor * mult)
player["cultivation_points"] = int(player.get("cultivation_points", 0)) + gain
if bonus > 0:
player["gather_bonus"] = 0.0
@@ -1125,60 +1145,138 @@ class XiuxianPlugin(MessagePluginInterface):
self._rate_set_global(sender, "出门历练")
prefix, layer = self._parse_realm(player.get("realm", "炼气1层"))
rs = self.realm_score_map.get(prefix, 0)
realm_mult = 1.0 + (float(rs) / 100.0)
layer_bonus = 1.0 + (max(0, (layer or 1) - 1) * 0.02)
d = realm_mult * layer_bonus
jack_p = min(0.05 * d, 0.25)
succ_p = min(0.45 * d, 0.8)
back_p = max(0.10 / d, 0.02)
r = random.random()
stones_gain = 0
mult = self._yield_multiplier(player.get("realm", "炼气1层"))
orig_stones = int(player.get("spirit_stone", 0))
stones = orig_stones
mats_gain: Dict[str, int] = {}
if r < jack_p:
stones_gain = int(random.uniform(100, 500) * d)
n = random.randint(2, 3)
tiers = ["T3", "T2"] if rs >= 40 else ["T2", "T1"]
for _ in range(n):
tier = tiers[0] if random.random() < 0.6 else tiers[1]
pool = self.materials_by_tier.get(tier, [])
if not pool:
continue
name = random.choice(pool)
mats_gain[name] = mats_gain.get(name, 0) + 1
elif r < jack_p + succ_p:
stones_gain = int(random.uniform(20, 80) * d)
n = random.randint(1, 2)
tiers = ["T2", "T1"]
for _ in range(n):
tier = tiers[0] if random.random() < min(0.3 * d, 0.7) else tiers[1]
pool = self.materials_by_tier.get(tier, [])
if not pool:
continue
name = random.choice(pool)
mats_gain[name] = mats_gain.get(name, 0) + 1
elif r < jack_p + succ_p + back_p:
player["status"] = "Injured"
player["status_until"] = (datetime.now(timezone.utc) + timedelta(minutes=30)).isoformat()
self._save_player(player)
self._rate_set_global(sender, "出门历练")
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, "❌ 历练失利灵气倒灌受伤30分钟", sender)
if self.revoke:
self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 10)
return False, "历练失败"
else:
self._rate_set_global(sender, "出门历练")
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, "⚠️ 此番行走天地,空手而归", sender)
if self.revoke:
self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 10)
return True, "历练无所得"
player["spirit_stone"] = int(player.get("spirit_stone", 0)) + stones_gain
cult_gain = 0
final_status = "Expedition"
final_until = player.get("status_until")
events = [
"洞府遗址",
"古老传承",
"天材地宝",
"大妖横行",
"魔头埋伏",
"天劫试炼",
"禁地余威",
"灵脉枯竭",
"灵潮涌动",
]
weights = [
30 + rs,
20 + rs,
25 + max(rs - 10, 0),
25,
20,
15 + max(rs - 20, 0),
15,
10,
10 + rs,
]
count = 1
if prefix in ("筑基", "金丹"):
count = 2
elif prefix in ("元婴", "化神", "合体", "大乘", "渡劫", "真仙"):
count = random.choice([2, 3])
happened = []
for _ in range(count):
idx = random.choices(range(len(events)), weights=weights, k=1)[0]
name = events[idx]
happened.append(name)
if name == "洞府遗址":
stones += int(random.uniform(80, 200) * mult)
n = random.randint(2, 4)
tiers = ["T3", "T2"] if rs >= 40 else ["T2", "T1"]
for _m in range(n):
tier = tiers[0] if random.random() < 0.5 else tiers[1]
pool = self.materials_by_tier.get(tier, [])
if pool:
mk = random.choice(pool)
mats_gain[mk] = mats_gain.get(mk, 0) + 1
if random.random() < 0.25:
final_status = "Unstable_Qi"
final_until = (datetime.now(timezone.utc) + timedelta(minutes=20)).isoformat()
elif name == "古老传承":
gain = int(random.uniform(100, 500) * mult)
cult_gain += gain
player["cultivate_bonus_next"] = float(player.get("cultivate_bonus_next", 0.0) or 0.0) + 0.1
elif name == "天材地宝":
stones += int(random.uniform(30, 80) * mult)
n = random.randint(1, 3)
tiers = ["T2", "T1"]
for _m in range(n):
tier = tiers[0] if random.random() < min(0.3 * mult, 0.7) else tiers[1]
pool = self.materials_by_tier.get(tier, [])
if pool:
mk = random.choice(pool)
mats_gain[mk] = mats_gain.get(mk, 0) + 1
if rs >= 50 and random.random() < 0.3:
pool = self.materials_by_tier.get("T3", [])
if pool:
mk = random.choice(pool)
mats_gain[mk] = mats_gain.get(mk, 0) + 1
elif name == "大妖横行":
p = min(0.5 + rs / 200.0, 0.8)
if random.random() < p:
gain = int(max(0, stones) * random.uniform(0.2, 0.5))
stones += gain
n = random.randint(2, 5)
pool = self.materials_by_tier.get("T2", [])
for _m in range(n):
if pool:
mk = random.choice(pool)
mats_gain[mk] = mats_gain.get(mk, 0) + 1
if rs >= 50 and random.random() < 0.2:
pool3 = self.materials_by_tier.get("T3", [])
if pool3:
mk = random.choice(pool3)
mats_gain[mk] = mats_gain.get(mk, 0) + 1
else:
loss = int(max(0, stones) * random.uniform(0.1, 0.3))
stones = max(0, stones - loss)
final_status = "Injured"
final_until = (datetime.now(timezone.utc) + timedelta(minutes=30)).isoformat()
elif name == "魔头埋伏":
loss = int(max(0, stones) * random.uniform(0.2, 0.4))
stones = max(0, stones - loss)
if random.random() < 0.3:
inv = player.get("inventory") or {}
keys = [k for k, v in inv.items() if int(v) > 0]
if keys:
rk = random.choice(keys)
inv[rk] = max(0, int(inv.get(rk, 0)) - 1)
player["inventory"] = inv
player["gather_debuff"] = -random.uniform(0.1, 0.2)
player["gather_debuff_until"] = (datetime.now(timezone.utc) + timedelta(minutes=30)).isoformat()
elif name == "天劫试炼":
if rs >= 40 and random.random() < 0.4:
gain = int(random.uniform(200, 800) * mult)
cult_gain += gain
else:
final_status = "Injured"
final_until = (datetime.now(timezone.utc) + timedelta(minutes=30)).isoformat()
elif name == "禁地余威":
final_status = "Unstable_Qi"
final_until = (datetime.now(timezone.utc) + timedelta(minutes=random.randint(20, 30))).isoformat()
elif name == "灵脉枯竭":
pass
elif name == "灵潮涌动":
player["gather_bonus"] = float(player.get("gather_bonus", 0.0) or 0.0) + 0.2
player["spirit_stone"] = stones
if cult_gain > 0:
player["cultivation_points"] = int(player.get("cultivation_points", 0)) + cult_gain
self.redis_db.leaderboard_add(sender, float(player["cultivation_points"]))
inv = player.get("inventory") or {}
for k, v in mats_gain.items():
inv[k] = int(inv.get(k, 0)) + v
player["inventory"] = inv
if final_status in ("Injured", "Unstable_Qi"):
player["status"] = final_status
player["status_until"] = final_until
if self.xdb:
try:
self.xdb.update_player_fields(sender, player.get("group_id", ""), {"spirit_stone": player["spirit_stone"]})
self.xdb.update_player_fields(sender, player.get("group_id", ""), {"spirit_stone": player["spirit_stone"], "cultivation_points": player.get("cultivation_points", 0), "status": player.get("status"), "status_until": player.get("status_until")})
for k, v in mats_gain.items():
self.xdb.add_item(sender, k, "材料", v)
except Exception:
@@ -1186,9 +1284,14 @@ class XiuxianPlugin(MessagePluginInterface):
self._save_player(player)
self._rate_set_global(sender, "出门历练")
mats_text = ", ".join([f"{k}×{v}" for k, v in mats_gain.items()]) if mats_gain else ""
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, f"✅ 行走四方所得:灵石{stones_gain},材料:{mats_text}", sender)
total_stones_delta = player["spirit_stone"] - orig_stones
if cult_gain > 0:
msg = f"✅ 行走四方所得:灵石{total_stones_delta},修为{cult_gain},材料:{mats_text}\n遭遇:{''.join(happened)}"
else:
msg = f"✅ 行走四方所得:灵石{total_stones_delta},材料:{mats_text}\n遭遇:{''.join(happened)}"
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, msg, sender)
if self.revoke:
self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 10)
self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 90)
return True, "历练成功"
async def _cmd_use(self, bot: WechatAPIClient, sender: str, roomid: str, content: str) -> Tuple[bool, str]: