优化层级逻辑
This commit is contained in:
@@ -65,60 +65,28 @@ items = [
|
||||
"聚灵符:材料:100"
|
||||
]
|
||||
|
||||
# 双轨制突破参数:丹药路径与强行路径
|
||||
# pill_threshold:丹药突破修为需求;pill_item:消耗的丹药名;pill_success:成功率
|
||||
# force_threshold:强行突破修为需求;force_success:成功率;force_next_realm:成功后的境界
|
||||
[Xiuxian.breakthrough]
|
||||
pill_threshold = 5000
|
||||
pill_item = "筑基丹"
|
||||
pill_success = 0.4
|
||||
force_threshold = 20000
|
||||
force_success = 0.1
|
||||
force_next_realm = "筑基2层"
|
||||
# 统一的境界配置:定义所有境界的层级提升和突破规则
|
||||
# 格式:境界名称 = "每层修为阈值,境界分值,突破丹药名,丹药突破成功率,强行突破成功率,强行突破倍率"
|
||||
# 突破修为要求自动计算 = 9层 × 每层阈值(达到10层所需修为)
|
||||
# 强行突破修为要求 = 突破修为要求 × 强行突破倍率
|
||||
# 注意:TOML中中文键名需要用引号
|
||||
[Xiuxian.realms]
|
||||
# 格式:境界名 = "每层阈值,境界分值,突破丹药,丹药成功率,强行成功率,强行倍率"
|
||||
# 注意:每层阈值用于计算层级提升(1-10层),突破要求自动计算为 9×每层阈值
|
||||
"炼气" = "1000,10,筑基丹,0.4,0.1,2.0"
|
||||
"筑基" = "5000,20,金元丹,0.2,0.05,2.0"
|
||||
"金丹" = "50000,30,结婴丹,0.15,0.03,2.0"
|
||||
"元婴" = "200000,40,化神丹,0.1,0.02,2.0"
|
||||
"化神" = "1000000,50,合体丹,0.08,0.01,2.0"
|
||||
"合体" = "5000000,60,大乘丹,0.05,0.005,2.0"
|
||||
"大乘" = "10000000,70,渡劫丹,0.03,0.003,2.0"
|
||||
"渡劫" = "50000000,80,飞升丹,0.02,0.001,2.0"
|
||||
"真仙" = "0,100,,0,0,0" # 真仙为最高境界,无法再突破
|
||||
|
||||
[Xiuxian.leaderboard]
|
||||
# 排行榜键(Redis Sorted Set)。默认使用修为分数,也支持按境界分值映射。
|
||||
key = "xiuxian:zset:leaderboard:cultivation"
|
||||
realm_key = "xiuxian:zset:leaderboard:realm"
|
||||
|
||||
[Xiuxian.realm_score]
|
||||
# 境界分值映射:用于 realm 排行榜(基础值 + 层数),真仙为固定高分
|
||||
stages = [
|
||||
"凡人:0",
|
||||
"炼气:10",
|
||||
"筑基:20",
|
||||
"金丹:30",
|
||||
"元婴:40",
|
||||
"化神:50",
|
||||
"合体:60",
|
||||
"大乘:70",
|
||||
"渡劫:80",
|
||||
"真仙:100"
|
||||
]
|
||||
|
||||
[Xiuxian.layer_up]
|
||||
# 每提升一层的修为阈值(简化规则):按当前境界前缀应用固定阈值
|
||||
thresholds = [
|
||||
"炼气:1000",
|
||||
"筑基:5000",
|
||||
"金丹:50000",
|
||||
"元婴:200000",
|
||||
"化神:1000000",
|
||||
"合体:5000000",
|
||||
"大乘:10000000",
|
||||
"渡劫:50000000"
|
||||
]
|
||||
|
||||
[Xiuxian.breakthrough_stages]
|
||||
# 瓶颈突破定义:当前境界(10层):路径:修为消耗:成功率:目标境界
|
||||
# 注意:突破修为要求应该与达到10层所需修为一致或略高
|
||||
# 炼气10层需要9000修为(9×1000),所以突破要求应该≥9000
|
||||
# 筑基10层需要45000修为(9×5000),所以突破要求应该≥45000
|
||||
paths = [
|
||||
"炼气10层:pill:9000:0.4:筑基1层", # 修复:从5000改为9000,与达到10层所需修为一致
|
||||
"炼气10层:hard:18000:0.1:筑基2层", # 修复:从20000改为18000(2倍)
|
||||
"筑基10层:pill:45000:0.2:金丹1层", # 修复:从50000改为45000,与达到10层所需修为一致
|
||||
"筑基10层:hard:90000:0.05:金丹2层" # 修复:从200000改为90000(2倍)
|
||||
]
|
||||
[Xiuxian.points_exchange]
|
||||
point_to_stone_rate = 10
|
||||
point_to_stone_rate = 10
|
||||
|
||||
@@ -290,49 +290,90 @@ class XiuxianPlugin(MessagePluginInterface):
|
||||
pts_cfg = cfg.get("points_exchange", {})
|
||||
self.point_to_stone_rate = int(pts_cfg.get("point_to_stone_rate", 10))
|
||||
|
||||
bt_cfg = cfg.get("breakthrough", {})
|
||||
self.bt_pill_threshold = int(bt_cfg.get("pill_threshold", 5000))
|
||||
self.bt_pill_item = bt_cfg.get("pill_item", "筑基丹")
|
||||
self.bt_pill_success = float(bt_cfg.get("pill_success", 0.4))
|
||||
self.bt_force_threshold = int(bt_cfg.get("force_threshold", 20000))
|
||||
self.bt_force_success = float(bt_cfg.get("force_success", 0.1))
|
||||
self.bt_force_next = bt_cfg.get("force_next_realm", "筑基2层")
|
||||
|
||||
# 解析境界分值与层级提升阈值
|
||||
realm_score_cfg = self._config.get("Xiuxian", {}).get("realm_score", {})
|
||||
self.realm_score_map = {}
|
||||
for s in realm_score_cfg.get("stages", []):
|
||||
# 统一解析境界配置:每层阈值、境界分值、突破规则
|
||||
realms_cfg = self._config.get("Xiuxian", {}).get("realms", {})
|
||||
if not realms_cfg:
|
||||
self.LOG.warning("未找到境界配置 [Xiuxian.realms],使用默认配置")
|
||||
# 提供默认配置作为后备
|
||||
realms_cfg = {
|
||||
"炼气": "1000,10,筑基丹,0.4,0.1,2.0",
|
||||
"筑基": "5000,20,金元丹,0.2,0.05,2.0",
|
||||
"金丹": "50000,30,结婴丹,0.15,0.03,2.0",
|
||||
"元婴": "200000,40,化神丹,0.1,0.02,2.0",
|
||||
"化神": "1000000,50,合体丹,0.08,0.01,2.0",
|
||||
"合体": "5000000,60,大乘丹,0.05,0.005,2.0",
|
||||
"大乘": "10000000,70,渡劫丹,0.03,0.003,2.0",
|
||||
"渡劫": "50000000,80,飞升丹,0.02,0.001,2.0",
|
||||
"真仙": "0,100,,0,0,0"
|
||||
}
|
||||
|
||||
self.realm_score_map = {} # 境界分值映射
|
||||
self.layer_threshold_map = {} # 每层修为阈值
|
||||
self.break_config = {} # 突破配置:{境界10层: {pill: {...}, hard: {...}}}
|
||||
|
||||
# 境界顺序(用于计算下一个境界)
|
||||
realm_order = ["炼气", "筑基", "金丹", "元婴", "化神", "合体", "大乘", "渡劫", "真仙"]
|
||||
|
||||
self.LOG.info(f"开始解析境界配置,共{len(realms_cfg)}个境界")
|
||||
for realm_name, config_str in realms_cfg.items():
|
||||
try:
|
||||
n, v = s.split(":")
|
||||
self.realm_score_map[n] = int(v)
|
||||
# 解析配置:每层阈值,境界分值,突破丹药,丹药成功率,强行成功率,强行倍率
|
||||
parts = config_str.split(",")
|
||||
if len(parts) < 6:
|
||||
self.LOG.warning(f"境界配置格式错误: {realm_name}={config_str}")
|
||||
continue
|
||||
|
||||
layer_threshold = int(parts[0].strip())
|
||||
realm_score = int(parts[1].strip())
|
||||
pill_item = parts[2].strip() if parts[2].strip() else None
|
||||
pill_rate = float(parts[3].strip()) if parts[3].strip() else 0.0
|
||||
hard_rate = float(parts[4].strip()) if parts[4].strip() else 0.0
|
||||
hard_multiplier = float(parts[5].strip()) if parts[5].strip() else 2.0
|
||||
|
||||
# 存储层级阈值和境界分值
|
||||
self.layer_threshold_map[realm_name] = layer_threshold
|
||||
self.realm_score_map[realm_name] = realm_score
|
||||
|
||||
# 计算突破要求:达到10层需要9层×每层阈值
|
||||
breakthrough_cost = 9 * layer_threshold
|
||||
hard_breakthrough_cost = int(breakthrough_cost * hard_multiplier)
|
||||
|
||||
# 计算下一个境界
|
||||
next_realm = None
|
||||
if realm_name != "真仙":
|
||||
try:
|
||||
current_idx = realm_order.index(realm_name)
|
||||
if current_idx + 1 < len(realm_order):
|
||||
next_realm = realm_order[current_idx + 1]
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# 构建突破配置
|
||||
if next_realm and layer_threshold > 0:
|
||||
stage_key = f"{realm_name}10层"
|
||||
self.break_config[stage_key] = {}
|
||||
|
||||
# 丹药突破路径
|
||||
if pill_item and pill_rate > 0:
|
||||
self.break_config[stage_key]["pill"] = {
|
||||
"cost": breakthrough_cost,
|
||||
"rate": pill_rate,
|
||||
"target": f"{next_realm}1层",
|
||||
"item": pill_item
|
||||
}
|
||||
|
||||
# 强行突破路径
|
||||
if hard_rate > 0:
|
||||
self.break_config[stage_key]["hard"] = {
|
||||
"cost": hard_breakthrough_cost,
|
||||
"rate": hard_rate,
|
||||
"target": f"{next_realm}2层"
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
self.LOG.warning(f"解析境界分值配置失败: {s}, 错误: {e}")
|
||||
|
||||
layer_up_cfg = self._config.get("Xiuxian", {}).get("layer_up", {})
|
||||
self.layer_threshold_map = {}
|
||||
for s in layer_up_cfg.get("thresholds", []):
|
||||
try:
|
||||
n, v = s.split(":")
|
||||
self.layer_threshold_map[n] = int(v)
|
||||
except Exception as e:
|
||||
self.LOG.warning(f"解析层级阈值配置失败: {s}, 错误: {e}")
|
||||
|
||||
# 解析突破阶段配置
|
||||
stage_cfg = self._config.get("Xiuxian", {}).get("breakthrough_stages", {})
|
||||
self.break_config = {}
|
||||
for p in stage_cfg.get("paths", []):
|
||||
try:
|
||||
cur, path, cost, rate, target = p.split(":")
|
||||
if cur not in self.break_config:
|
||||
self.break_config[cur] = {}
|
||||
self.break_config[cur][path] = {
|
||||
"cost": int(cost),
|
||||
"rate": float(rate),
|
||||
"target": target
|
||||
}
|
||||
except Exception as e:
|
||||
self.LOG.warning(f"解析突破阶段配置失败: {p}, 错误: {e}")
|
||||
|
||||
self.LOG.warning(f"解析境界配置失败: {realm_name}={config_str}, 错误: {e}")
|
||||
|
||||
self.LOG.info(f"境界配置解析完成:层级阈值{len(self.layer_threshold_map)}个,突破配置{len(self.break_config)}个")
|
||||
self.LOG.info(f"[{self.name}] 插件初始化完成,指令:{self._commands}")
|
||||
return True
|
||||
|
||||
@@ -937,23 +978,6 @@ class XiuxianPlugin(MessagePluginInterface):
|
||||
return False, "未注册"
|
||||
player = self._check_status_update(player)
|
||||
points = int(player.get("cultivation_points", 0))
|
||||
# 优化:从数据库读取最新的背包数据,确保数据准确性
|
||||
pill_item_count = 0
|
||||
if self.xdb:
|
||||
try:
|
||||
items = self.xdb.get_inventory(sender)
|
||||
for item in items:
|
||||
if item["name"] == self.bt_pill_item:
|
||||
pill_item_count = item["quantity"]
|
||||
break
|
||||
except Exception as e:
|
||||
logger.warning(f"读取背包数据失败: {e}, user_id={sender}")
|
||||
# 降级到使用内存中的inventory
|
||||
inv = player.get("inventory") or {}
|
||||
pill_item_count = inv.get(self.bt_pill_item, 0)
|
||||
else:
|
||||
inv = player.get("inventory") or {}
|
||||
pill_item_count = inv.get(self.bt_pill_item, 0)
|
||||
|
||||
# 读取当前瓶颈配置
|
||||
cur_realm = player.get("realm", "炼气1层")
|
||||
@@ -977,24 +1001,51 @@ class XiuxianPlugin(MessagePluginInterface):
|
||||
if self.revoke:
|
||||
self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 5)
|
||||
return False, "未配置"
|
||||
|
||||
# 从配置中获取丹药名称
|
||||
pill_item_name = pill_conf.get("item")
|
||||
if not pill_item_name:
|
||||
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, 5)
|
||||
return False, "丹药未配置"
|
||||
|
||||
# 优化:从数据库读取最新的背包数据,确保数据准确性
|
||||
pill_item_count = 0
|
||||
if self.xdb:
|
||||
try:
|
||||
items = self.xdb.get_inventory(sender)
|
||||
for item in items:
|
||||
if item["name"] == pill_item_name:
|
||||
pill_item_count = item["quantity"]
|
||||
break
|
||||
except Exception as e:
|
||||
logger.warning(f"读取背包数据失败: {e}, user_id={sender}")
|
||||
# 降级到使用内存中的inventory
|
||||
inv = player.get("inventory") or {}
|
||||
pill_item_count = inv.get(pill_item_name, 0)
|
||||
else:
|
||||
inv = player.get("inventory") or {}
|
||||
pill_item_count = inv.get(pill_item_name, 0)
|
||||
|
||||
if points < pill_conf["cost"]:
|
||||
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, 5)
|
||||
return False, "修为不足"
|
||||
if pill_item_count <= 0:
|
||||
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, f"缺少丹药:{self.bt_pill_item}", sender)
|
||||
client_msg_id, create_time, new_msg_id = await bot.send_text_message(roomid or sender, f"缺少丹药:{pill_item_name}", sender)
|
||||
if self.revoke:
|
||||
self.revoke.add_message_to_revoke((roomid if roomid else sender), client_msg_id, create_time, new_msg_id, 5)
|
||||
return False, "缺少丹药"
|
||||
# 更新内存中的inventory(用于缓存)
|
||||
inv = player.get("inventory") or {}
|
||||
inv[self.bt_pill_item] = pill_item_count - 1
|
||||
inv[pill_item_name] = pill_item_count - 1
|
||||
player["inventory"] = inv
|
||||
player["cultivation_points"] = points - pill_conf["cost"]
|
||||
if self.xdb:
|
||||
try:
|
||||
self.xdb.remove_item(sender, self.bt_pill_item, 1)
|
||||
self.xdb.remove_item(sender, pill_item_name, 1)
|
||||
self.xdb.update_player_fields(sender, {"cultivation_points": player["cultivation_points"]})
|
||||
self.redis_db.invalidate_player(sender, player.get("group_id", ""))
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user