优化出门历练,更加沉浸
This commit is contained in:
@@ -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]:
|
||||
|
||||
Reference in New Issue
Block a user