From acb112b318fdfcb07ca7c9ac7d6c586173e73d0a Mon Sep 17 00:00:00 2001 From: liuwei Date: Mon, 24 Nov 2025 17:21:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=87=BA=E9=97=A8=E5=8E=86?= =?UTF-8?q?=E7=BB=83=EF=BC=8C=E6=9B=B4=E5=8A=A0=E6=B2=89=E6=B5=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/xiuxian/main.py | 203 ++++++++++++++++++++++++++++++---------- 1 file changed, 153 insertions(+), 50 deletions(-) diff --git a/plugins/xiuxian/main.py b/plugins/xiuxian/main.py index ee21e32..25cbd56 100644 --- a/plugins/xiuxian/main.py +++ b/plugins/xiuxian/main.py @@ -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]: