diff --git a/assets/cities/青云城_0.jpg b/assets/cities/city_301_0.jpg
similarity index 100%
rename from assets/cities/青云城_0.jpg
rename to assets/cities/city_301_0.jpg
diff --git a/assets/cities/青云城_0.png b/assets/cities/city_301_0.png
similarity index 100%
rename from assets/cities/青云城_0.png
rename to assets/cities/city_301_0.png
diff --git a/assets/cities/青云城_1.jpg b/assets/cities/city_301_1.jpg
similarity index 100%
rename from assets/cities/青云城_1.jpg
rename to assets/cities/city_301_1.jpg
diff --git a/assets/cities/青云城_1.png b/assets/cities/city_301_1.png
similarity index 100%
rename from assets/cities/青云城_1.png
rename to assets/cities/city_301_1.png
diff --git a/assets/cities/青云城_2.jpg b/assets/cities/city_301_2.jpg
similarity index 100%
rename from assets/cities/青云城_2.jpg
rename to assets/cities/city_301_2.jpg
diff --git a/assets/cities/青云城_2.png b/assets/cities/city_301_2.png
similarity index 100%
rename from assets/cities/青云城_2.png
rename to assets/cities/city_301_2.png
diff --git a/assets/cities/青云城_3.jpg b/assets/cities/city_301_3.jpg
similarity index 100%
rename from assets/cities/青云城_3.jpg
rename to assets/cities/city_301_3.jpg
diff --git a/assets/cities/青云城_3.png b/assets/cities/city_301_3.png
similarity index 100%
rename from assets/cities/青云城_3.png
rename to assets/cities/city_301_3.png
diff --git a/assets/cities/沙月城_0.jpg b/assets/cities/city_302_0.jpg
similarity index 100%
rename from assets/cities/沙月城_0.jpg
rename to assets/cities/city_302_0.jpg
diff --git a/assets/cities/沙月城_0.png b/assets/cities/city_302_0.png
similarity index 100%
rename from assets/cities/沙月城_0.png
rename to assets/cities/city_302_0.png
diff --git a/assets/cities/沙月城_1.jpg b/assets/cities/city_302_1.jpg
similarity index 100%
rename from assets/cities/沙月城_1.jpg
rename to assets/cities/city_302_1.jpg
diff --git a/assets/cities/沙月城_1.png b/assets/cities/city_302_1.png
similarity index 100%
rename from assets/cities/沙月城_1.png
rename to assets/cities/city_302_1.png
diff --git a/assets/cities/沙月城_2.jpg b/assets/cities/city_302_2.jpg
similarity index 100%
rename from assets/cities/沙月城_2.jpg
rename to assets/cities/city_302_2.jpg
diff --git a/assets/cities/沙月城_2.png b/assets/cities/city_302_2.png
similarity index 100%
rename from assets/cities/沙月城_2.png
rename to assets/cities/city_302_2.png
diff --git a/assets/cities/沙月城_3.jpg b/assets/cities/city_302_3.jpg
similarity index 100%
rename from assets/cities/沙月城_3.jpg
rename to assets/cities/city_302_3.jpg
diff --git a/assets/cities/沙月城_3.png b/assets/cities/city_302_3.png
similarity index 100%
rename from assets/cities/沙月城_3.png
rename to assets/cities/city_302_3.png
diff --git a/assets/cities/翠林城_0.jpg b/assets/cities/city_303_0.jpg
similarity index 100%
rename from assets/cities/翠林城_0.jpg
rename to assets/cities/city_303_0.jpg
diff --git a/assets/cities/翠林城_0.png b/assets/cities/city_303_0.png
similarity index 100%
rename from assets/cities/翠林城_0.png
rename to assets/cities/city_303_0.png
diff --git a/assets/cities/翠林城_1.jpg b/assets/cities/city_303_1.jpg
similarity index 100%
rename from assets/cities/翠林城_1.jpg
rename to assets/cities/city_303_1.jpg
diff --git a/assets/cities/翠林城_1.png b/assets/cities/city_303_1.png
similarity index 100%
rename from assets/cities/翠林城_1.png
rename to assets/cities/city_303_1.png
diff --git a/assets/cities/翠林城_2.jpg b/assets/cities/city_303_2.jpg
similarity index 100%
rename from assets/cities/翠林城_2.jpg
rename to assets/cities/city_303_2.jpg
diff --git a/assets/cities/翠林城_2.png b/assets/cities/city_303_2.png
similarity index 100%
rename from assets/cities/翠林城_2.png
rename to assets/cities/city_303_2.png
diff --git a/assets/cities/翠林城_3.jpg b/assets/cities/city_303_3.jpg
similarity index 100%
rename from assets/cities/翠林城_3.jpg
rename to assets/cities/city_303_3.jpg
diff --git a/assets/cities/翠林城_3.png b/assets/cities/city_303_3.png
similarity index 100%
rename from assets/cities/翠林城_3.png
rename to assets/cities/city_303_3.png
diff --git a/assets/cities/沧澜城_0.jpg b/assets/cities/city_304_0.jpg
similarity index 100%
rename from assets/cities/沧澜城_0.jpg
rename to assets/cities/city_304_0.jpg
diff --git a/assets/cities/沧澜城_0.png b/assets/cities/city_304_0.png
similarity index 100%
rename from assets/cities/沧澜城_0.png
rename to assets/cities/city_304_0.png
diff --git a/assets/cities/沧澜城_1.jpg b/assets/cities/city_304_1.jpg
similarity index 100%
rename from assets/cities/沧澜城_1.jpg
rename to assets/cities/city_304_1.jpg
diff --git a/assets/cities/沧澜城_1.png b/assets/cities/city_304_1.png
similarity index 100%
rename from assets/cities/沧澜城_1.png
rename to assets/cities/city_304_1.png
diff --git a/assets/cities/沧澜城_2.jpg b/assets/cities/city_304_2.jpg
similarity index 100%
rename from assets/cities/沧澜城_2.jpg
rename to assets/cities/city_304_2.jpg
diff --git a/assets/cities/沧澜城_2.png b/assets/cities/city_304_2.png
similarity index 100%
rename from assets/cities/沧澜城_2.png
rename to assets/cities/city_304_2.png
diff --git a/assets/cities/沧澜城_3.jpg b/assets/cities/city_304_3.jpg
similarity index 100%
rename from assets/cities/沧澜城_3.jpg
rename to assets/cities/city_304_3.jpg
diff --git a/assets/cities/沧澜城_3.png b/assets/cities/city_304_3.png
similarity index 100%
rename from assets/cities/沧澜城_3.png
rename to assets/cities/city_304_3.png
diff --git a/assets/cities/揽月城_0.jpg b/assets/cities/city_305_0.jpg
similarity index 100%
rename from assets/cities/揽月城_0.jpg
rename to assets/cities/city_305_0.jpg
diff --git a/assets/cities/揽月城_0.png b/assets/cities/city_305_0.png
similarity index 100%
rename from assets/cities/揽月城_0.png
rename to assets/cities/city_305_0.png
diff --git a/assets/cities/揽月城_1.jpg b/assets/cities/city_305_1.jpg
similarity index 100%
rename from assets/cities/揽月城_1.jpg
rename to assets/cities/city_305_1.jpg
diff --git a/assets/cities/揽月城_1.png b/assets/cities/city_305_1.png
similarity index 100%
rename from assets/cities/揽月城_1.png
rename to assets/cities/city_305_1.png
diff --git a/assets/cities/揽月城_2.jpg b/assets/cities/city_305_2.jpg
similarity index 100%
rename from assets/cities/揽月城_2.jpg
rename to assets/cities/city_305_2.jpg
diff --git a/assets/cities/揽月城_2.png b/assets/cities/city_305_2.png
similarity index 100%
rename from assets/cities/揽月城_2.png
rename to assets/cities/city_305_2.png
diff --git a/assets/cities/揽月城_3.jpg b/assets/cities/city_305_3.jpg
similarity index 100%
rename from assets/cities/揽月城_3.jpg
rename to assets/cities/city_305_3.jpg
diff --git a/assets/cities/揽月城_3.png b/assets/cities/city_305_3.png
similarity index 100%
rename from assets/cities/揽月城_3.png
rename to assets/cities/city_305_3.png
diff --git a/assets/sects/明心剑宗.png b/assets/sects/sect_1.png
similarity index 100%
rename from assets/sects/明心剑宗.png
rename to assets/sects/sect_1.png
diff --git a/assets/sects/妙化宗.png b/assets/sects/sect_10.png
similarity index 100%
rename from assets/sects/妙化宗.png
rename to assets/sects/sect_10.png
diff --git a/assets/sects/妙化宗_0.png b/assets/sects/sect_10_0.png
similarity index 100%
rename from assets/sects/妙化宗_0.png
rename to assets/sects/sect_10_0.png
diff --git a/assets/sects/妙化宗_1.png b/assets/sects/sect_10_1.png
similarity index 100%
rename from assets/sects/妙化宗_1.png
rename to assets/sects/sect_10_1.png
diff --git a/assets/sects/妙化宗_2.png b/assets/sects/sect_10_2.png
similarity index 100%
rename from assets/sects/妙化宗_2.png
rename to assets/sects/sect_10_2.png
diff --git a/assets/sects/妙化宗_3.png b/assets/sects/sect_10_3.png
similarity index 100%
rename from assets/sects/妙化宗_3.png
rename to assets/sects/sect_10_3.png
diff --git a/assets/sects/回玄宗.png b/assets/sects/sect_11.png
similarity index 100%
rename from assets/sects/回玄宗.png
rename to assets/sects/sect_11.png
diff --git a/assets/sects/回玄宗_0.png b/assets/sects/sect_11_0.png
similarity index 100%
rename from assets/sects/回玄宗_0.png
rename to assets/sects/sect_11_0.png
diff --git a/assets/sects/回玄宗_1.png b/assets/sects/sect_11_1.png
similarity index 100%
rename from assets/sects/回玄宗_1.png
rename to assets/sects/sect_11_1.png
diff --git a/assets/sects/回玄宗_2.png b/assets/sects/sect_11_2.png
similarity index 100%
rename from assets/sects/回玄宗_2.png
rename to assets/sects/sect_11_2.png
diff --git a/assets/sects/回玄宗_3.png b/assets/sects/sect_11_3.png
similarity index 100%
rename from assets/sects/回玄宗_3.png
rename to assets/sects/sect_11_3.png
diff --git a/assets/sects/不夜城.png b/assets/sects/sect_12.png
similarity index 100%
rename from assets/sects/不夜城.png
rename to assets/sects/sect_12.png
diff --git a/assets/sects/不夜城_0.png b/assets/sects/sect_12_0.png
similarity index 100%
rename from assets/sects/不夜城_0.png
rename to assets/sects/sect_12_0.png
diff --git a/assets/sects/不夜城_1.png b/assets/sects/sect_12_1.png
similarity index 100%
rename from assets/sects/不夜城_1.png
rename to assets/sects/sect_12_1.png
diff --git a/assets/sects/不夜城_2.png b/assets/sects/sect_12_2.png
similarity index 100%
rename from assets/sects/不夜城_2.png
rename to assets/sects/sect_12_2.png
diff --git a/assets/sects/不夜城_3.png b/assets/sects/sect_12_3.png
similarity index 100%
rename from assets/sects/不夜城_3.png
rename to assets/sects/sect_12_3.png
diff --git a/assets/sects/天行健宗.png b/assets/sects/sect_13.png
similarity index 100%
rename from assets/sects/天行健宗.png
rename to assets/sects/sect_13.png
diff --git a/assets/sects/天行健宗_0.png b/assets/sects/sect_13_0.png
similarity index 100%
rename from assets/sects/天行健宗_0.png
rename to assets/sects/sect_13_0.png
diff --git a/assets/sects/天行健宗_1.png b/assets/sects/sect_13_1.png
similarity index 100%
rename from assets/sects/天行健宗_1.png
rename to assets/sects/sect_13_1.png
diff --git a/assets/sects/天行健宗_2.png b/assets/sects/sect_13_2.png
similarity index 100%
rename from assets/sects/天行健宗_2.png
rename to assets/sects/sect_13_2.png
diff --git a/assets/sects/天行健宗_3.png b/assets/sects/sect_13_3.png
similarity index 100%
rename from assets/sects/天行健宗_3.png
rename to assets/sects/sect_13_3.png
diff --git a/assets/sects/噬魔宗.png b/assets/sects/sect_14.png
similarity index 100%
rename from assets/sects/噬魔宗.png
rename to assets/sects/sect_14.png
diff --git a/assets/sects/噬魔宗_0.png b/assets/sects/sect_14_0.png
similarity index 100%
rename from assets/sects/噬魔宗_0.png
rename to assets/sects/sect_14_0.png
diff --git a/assets/sects/噬魔宗_1.png b/assets/sects/sect_14_1.png
similarity index 100%
rename from assets/sects/噬魔宗_1.png
rename to assets/sects/sect_14_1.png
diff --git a/assets/sects/噬魔宗_2.png b/assets/sects/sect_14_2.png
similarity index 100%
rename from assets/sects/噬魔宗_2.png
rename to assets/sects/sect_14_2.png
diff --git a/assets/sects/噬魔宗_3.png b/assets/sects/sect_14_3.png
similarity index 100%
rename from assets/sects/噬魔宗_3.png
rename to assets/sects/sect_14_3.png
diff --git a/assets/sects/明心剑宗_0.png b/assets/sects/sect_1_0.png
similarity index 100%
rename from assets/sects/明心剑宗_0.png
rename to assets/sects/sect_1_0.png
diff --git a/assets/sects/明心剑宗_1.png b/assets/sects/sect_1_1.png
similarity index 100%
rename from assets/sects/明心剑宗_1.png
rename to assets/sects/sect_1_1.png
diff --git a/assets/sects/明心剑宗_2.png b/assets/sects/sect_1_2.png
similarity index 100%
rename from assets/sects/明心剑宗_2.png
rename to assets/sects/sect_1_2.png
diff --git a/assets/sects/明心剑宗_3.png b/assets/sects/sect_1_3.png
similarity index 100%
rename from assets/sects/明心剑宗_3.png
rename to assets/sects/sect_1_3.png
diff --git a/assets/sects/百兽宗.png b/assets/sects/sect_2.png
similarity index 100%
rename from assets/sects/百兽宗.png
rename to assets/sects/sect_2.png
diff --git a/assets/sects/百兽宗_0.png b/assets/sects/sect_2_0.png
similarity index 100%
rename from assets/sects/百兽宗_0.png
rename to assets/sects/sect_2_0.png
diff --git a/assets/sects/百兽宗_1.png b/assets/sects/sect_2_1.png
similarity index 100%
rename from assets/sects/百兽宗_1.png
rename to assets/sects/sect_2_1.png
diff --git a/assets/sects/百兽宗_2.png b/assets/sects/sect_2_2.png
similarity index 100%
rename from assets/sects/百兽宗_2.png
rename to assets/sects/sect_2_2.png
diff --git a/assets/sects/百兽宗_3.png b/assets/sects/sect_2_3.png
similarity index 100%
rename from assets/sects/百兽宗_3.png
rename to assets/sects/sect_2_3.png
diff --git a/assets/sects/水镜宗.png b/assets/sects/sect_3.png
similarity index 100%
rename from assets/sects/水镜宗.png
rename to assets/sects/sect_3.png
diff --git a/assets/sects/水镜宗_0.png b/assets/sects/sect_3_0.png
similarity index 100%
rename from assets/sects/水镜宗_0.png
rename to assets/sects/sect_3_0.png
diff --git a/assets/sects/水镜宗_1.png b/assets/sects/sect_3_1.png
similarity index 100%
rename from assets/sects/水镜宗_1.png
rename to assets/sects/sect_3_1.png
diff --git a/assets/sects/水镜宗_2.png b/assets/sects/sect_3_2.png
similarity index 100%
rename from assets/sects/水镜宗_2.png
rename to assets/sects/sect_3_2.png
diff --git a/assets/sects/水镜宗_3.png b/assets/sects/sect_3_3.png
similarity index 100%
rename from assets/sects/水镜宗_3.png
rename to assets/sects/sect_3_3.png
diff --git a/assets/sects/冥王宗.png b/assets/sects/sect_4.png
similarity index 100%
rename from assets/sects/冥王宗.png
rename to assets/sects/sect_4.png
diff --git a/assets/sects/冥王宗_0.png b/assets/sects/sect_4_0.png
similarity index 100%
rename from assets/sects/冥王宗_0.png
rename to assets/sects/sect_4_0.png
diff --git a/assets/sects/冥王宗_1.png b/assets/sects/sect_4_1.png
similarity index 100%
rename from assets/sects/冥王宗_1.png
rename to assets/sects/sect_4_1.png
diff --git a/assets/sects/冥王宗_2.png b/assets/sects/sect_4_2.png
similarity index 100%
rename from assets/sects/冥王宗_2.png
rename to assets/sects/sect_4_2.png
diff --git a/assets/sects/冥王宗_3.png b/assets/sects/sect_4_3.png
similarity index 100%
rename from assets/sects/冥王宗_3.png
rename to assets/sects/sect_4_3.png
diff --git a/assets/sects/朱勾宗.png b/assets/sects/sect_5.png
similarity index 100%
rename from assets/sects/朱勾宗.png
rename to assets/sects/sect_5.png
diff --git a/assets/sects/朱勾宗_0.png b/assets/sects/sect_5_0.png
similarity index 100%
rename from assets/sects/朱勾宗_0.png
rename to assets/sects/sect_5_0.png
diff --git a/assets/sects/朱勾宗_1.png b/assets/sects/sect_5_1.png
similarity index 100%
rename from assets/sects/朱勾宗_1.png
rename to assets/sects/sect_5_1.png
diff --git a/assets/sects/朱勾宗_2.png b/assets/sects/sect_5_2.png
similarity index 100%
rename from assets/sects/朱勾宗_2.png
rename to assets/sects/sect_5_2.png
diff --git a/assets/sects/朱勾宗_3.png b/assets/sects/sect_5_3.png
similarity index 100%
rename from assets/sects/朱勾宗_3.png
rename to assets/sects/sect_5_3.png
diff --git a/assets/sects/合欢宗.png b/assets/sects/sect_6.png
similarity index 100%
rename from assets/sects/合欢宗.png
rename to assets/sects/sect_6.png
diff --git a/assets/sects/合欢宗_0.png b/assets/sects/sect_6_0.png
similarity index 100%
rename from assets/sects/合欢宗_0.png
rename to assets/sects/sect_6_0.png
diff --git a/assets/sects/合欢宗_1.png b/assets/sects/sect_6_1.png
similarity index 100%
rename from assets/sects/合欢宗_1.png
rename to assets/sects/sect_6_1.png
diff --git a/assets/sects/合欢宗_2.png b/assets/sects/sect_6_2.png
similarity index 100%
rename from assets/sects/合欢宗_2.png
rename to assets/sects/sect_6_2.png
diff --git a/assets/sects/合欢宗_3.png b/assets/sects/sect_6_3.png
similarity index 100%
rename from assets/sects/合欢宗_3.png
rename to assets/sects/sect_6_3.png
diff --git a/assets/sects/镇魂宗.png b/assets/sects/sect_7.png
similarity index 100%
rename from assets/sects/镇魂宗.png
rename to assets/sects/sect_7.png
diff --git a/assets/sects/镇魂宗_0.png b/assets/sects/sect_7_0.png
similarity index 100%
rename from assets/sects/镇魂宗_0.png
rename to assets/sects/sect_7_0.png
diff --git a/assets/sects/镇魂宗_1.png b/assets/sects/sect_7_1.png
similarity index 100%
rename from assets/sects/镇魂宗_1.png
rename to assets/sects/sect_7_1.png
diff --git a/assets/sects/镇魂宗_2.png b/assets/sects/sect_7_2.png
similarity index 100%
rename from assets/sects/镇魂宗_2.png
rename to assets/sects/sect_7_2.png
diff --git a/assets/sects/镇魂宗_3.png b/assets/sects/sect_7_3.png
similarity index 100%
rename from assets/sects/镇魂宗_3.png
rename to assets/sects/sect_7_3.png
diff --git a/assets/sects/幽魂噬影宗.png b/assets/sects/sect_8.png
similarity index 100%
rename from assets/sects/幽魂噬影宗.png
rename to assets/sects/sect_8.png
diff --git a/assets/sects/幽魂噬影宗_0.png b/assets/sects/sect_8_0.png
similarity index 100%
rename from assets/sects/幽魂噬影宗_0.png
rename to assets/sects/sect_8_0.png
diff --git a/assets/sects/幽魂噬影宗_1.png b/assets/sects/sect_8_1.png
similarity index 100%
rename from assets/sects/幽魂噬影宗_1.png
rename to assets/sects/sect_8_1.png
diff --git a/assets/sects/幽魂噬影宗_2.png b/assets/sects/sect_8_2.png
similarity index 100%
rename from assets/sects/幽魂噬影宗_2.png
rename to assets/sects/sect_8_2.png
diff --git a/assets/sects/幽魂噬影宗_3.png b/assets/sects/sect_8_3.png
similarity index 100%
rename from assets/sects/幽魂噬影宗_3.png
rename to assets/sects/sect_8_3.png
diff --git a/assets/sects/千帆城.png b/assets/sects/sect_9.png
similarity index 100%
rename from assets/sects/千帆城.png
rename to assets/sects/sect_9.png
diff --git a/assets/sects/千帆城_0.png b/assets/sects/sect_9_0.png
similarity index 100%
rename from assets/sects/千帆城_0.png
rename to assets/sects/sect_9_0.png
diff --git a/assets/sects/千帆城_1.png b/assets/sects/sect_9_1.png
similarity index 100%
rename from assets/sects/千帆城_1.png
rename to assets/sects/sect_9_1.png
diff --git a/assets/sects/千帆城_2.png b/assets/sects/sect_9_2.png
similarity index 100%
rename from assets/sects/千帆城_2.png
rename to assets/sects/sect_9_2.png
diff --git a/assets/sects/千帆城_3.png b/assets/sects/sect_9_3.png
similarity index 100%
rename from assets/sects/千帆城_3.png
rename to assets/sects/sect_9_3.png
diff --git a/src/classes/history.py b/src/classes/history.py
index e4c969f..5c0bfc4 100644
--- a/src/classes/history.py
+++ b/src/classes/history.py
@@ -1,12 +1,13 @@
import asyncio
-import json
-from pathlib import Path
-from typing import Dict, Any, Optional, TYPE_CHECKING
import logging
+from dataclasses import dataclass
+from pathlib import Path
+from typing import Dict, Any, Optional, Callable, TYPE_CHECKING, Coroutine
from src.classes.item_registry import ItemRegistry
from src.classes.technique import techniques_by_id, techniques_by_name
from src.classes.weapon import weapons_by_name
+from src.classes.sect import sects_by_id, sects_by_name
from src.utils.llm.client import call_llm_with_task_name
from src.run.log import get_logger
@@ -17,48 +18,93 @@ class HistoryManager:
"""
历史管理器
在游戏开局时,根据历史文本一次性修改世界中的对象数据。
+ 支持并发调用 LLM 分别处理不同领域的数据(地图、宗门、物品)。
"""
def __init__(self, world: "World"):
self.world = world
- # 配置目录路径
self.config_dir = Path("static/game_configs")
self.logger = get_logger().logger
async def apply_history_influence(self, history_text: str):
"""
- 核心方法:读取 CSV -> LLM 分析 -> 更新内存对象
+ 核心方法:读取 CSV -> 并发 LLM 分析 -> 更新内存对象
"""
- # 1. 准备 Prompt 参数:直接读取 CSV 原始内容
- infos = {
- "world_info": str(self.world.static_info) if self.world else "",
- "history_str": history_text,
- "city_regions": self._read_csv("city_region.csv"),
- "normal_regions": self._read_csv("normal_region.csv"),
- "cultivate_regions": self._read_csv("cultivate_region.csv"),
- "sect_regions": self._read_csv("sect_region.csv"),
- "techniques": self._read_csv("technique.csv"),
- "weapons": self._read_csv("weapon.csv"),
- "auxiliarys": self._read_csv("auxiliary.csv"),
- }
+ self.logger.info("[History] 正在根据历史推演世界变化 (并发模式)...")
+
+ world_info = str(self.world.static_info) if self.world else ""
+
+ # 1. 构建并发任务
+ tasks = []
- # 2. 调用 LLM
- self.logger.info("[History] 正在根据历史推演世界变化...")
+ # Task 1: Map (Regions)
+ tasks.append(self._create_task(
+ task_suffix="map",
+ template="static/templates/history_influence_map.txt",
+ infos={
+ "world_info": world_info,
+ "history_str": history_text,
+ "city_regions": self._read_csv("city_region.csv"),
+ "normal_regions": self._read_csv("normal_region.csv"),
+ "cultivate_regions": self._read_csv("cultivate_region.csv"),
+ },
+ handler=self._apply_map_changes
+ ))
+
+ # Task 2: Sects & Sect Regions
+ tasks.append(self._create_task(
+ task_suffix="sect",
+ template="static/templates/history_influence_sect.txt",
+ infos={
+ "world_info": world_info,
+ "history_str": history_text,
+ "sects": self._read_csv("sect.csv"),
+ "sect_regions": self._read_csv("sect_region.csv"),
+ },
+ handler=self._apply_sect_changes
+ ))
+
+ # Task 3: Items (Techniques, Weapons, Auxiliarys)
+ tasks.append(self._create_task(
+ task_suffix="item",
+ template="static/templates/history_influence_item.txt",
+ infos={
+ "world_info": world_info,
+ "history_str": history_text,
+ "techniques": self._read_csv("technique.csv"),
+ "weapons": self._read_csv("weapon.csv"),
+ "auxiliarys": self._read_csv("auxiliary.csv"),
+ },
+ handler=self._apply_item_changes
+ ))
+
+ # 2. 并发执行并等待所有结果
+ await asyncio.gather(*tasks)
+ self.logger.info("[History] 历史推演完成")
+
+ async def _create_task(
+ self,
+ task_suffix: str,
+ template: str,
+ infos: Dict[str, Any],
+ handler: Callable[[Dict[str, Any]], None]
+ ):
+ """
+ 创建一个执行单元:调用 LLM -> 处理回调
+ """
+ task_name = f"history_influence_{task_suffix}"
try:
result = await call_llm_with_task_name(
- task_name="history_influence",
- template_path="static/templates/history_influence.txt",
+ task_name=task_name,
+ template_path=template,
infos=infos,
- max_retries=3 # 增加重试次数,确保 JSON 格式正确
+ max_retries=3
)
+ if result:
+ handler(result)
+ else:
+ self.logger.info(f"[History] {task_name} 返回为空,未进行修改")
except Exception as e:
- self.logger.error(f"[History] LLM 调用或解析失败: {e}")
- return
-
- # 3. 应用变更到内存对象
- if result:
- self._apply_changes(result)
- else:
- self.logger.info("[History] LLM 返回为空,未进行任何修改")
+ self.logger.error(f"[History] {task_name} 任务失败: {e}")
def _read_csv(self, filename: str) -> str:
"""读取 CSV 文件原始内容"""
@@ -72,21 +118,53 @@ class HistoryManager:
self.logger.error(f"[History] 读取文件 {filename} 失败: {e}")
return ""
- def _apply_changes(self, result: Dict[str, Any]):
- """分发并应用变更"""
-
- # 3.1 区域变更
+ # --- Handlers ---
+
+ def _apply_map_changes(self, result: Dict[str, Any]):
+ """处理地图区域变更"""
self._update_regions(result.get("city_regions_change", {}))
self._update_regions(result.get("normal_regions_change", {}))
self._update_regions(result.get("cultivate_regions_change", {}))
+
+ def _apply_sect_changes(self, result: Dict[str, Any]):
+ """处理宗门及宗门驻地变更"""
+ # 1. 宗门驻地 (从 Map 任务移过来)
self._update_regions(result.get("sect_regions_change", {}))
-
- # 3.2 功法变更
+
+ # 2. 宗门本体
+ changes = result.get("sects_change", {})
+ if not changes: return
+
+ count = 0
+ for sid_str, data in changes.items():
+ try:
+ sid = int(sid_str)
+ sect = sects_by_id.get(sid)
+ if sect:
+ old_name = sect.name
+ self._update_obj_attrs(sect, data)
+
+ # 同步 sects_by_name 索引
+ if sect.name != old_name:
+ if old_name in sects_by_name:
+ del sects_by_name[old_name]
+ sects_by_name[sect.name] = sect
+
+ self.logger.info(f"[History] 宗门变更 - ID: {sid}, Name: {sect.name}, Desc: {sect.desc}")
+ count += 1
+ except Exception as e:
+ self.logger.error(f"[History] 宗门更新失败 - ID: {sid_str}, Error: {e}")
+ continue
+ if count > 0:
+ self.logger.info(f"[History] 更新了 {count} 个宗门")
+
+ def _apply_item_changes(self, result: Dict[str, Any]):
+ """处理物品/功法变更"""
self._update_techniques(result.get("techniques_change", {}))
-
- # 3.3 装备变更
self._update_items(result.get("weapons_change", {}), weapons_by_name)
- self._update_items(result.get("auxiliarys_change", {}), None) # 辅助装备可能没有全局 name 索引
+ self._update_items(result.get("auxiliarys_change", {}), None)
+
+ # --- Update Logic ---
def _update_regions(self, changes: Dict[str, Any]):
"""更新区域 (Map.regions)"""
@@ -96,7 +174,6 @@ class HistoryManager:
for rid_str, data in changes.items():
try:
rid = int(rid_str)
- # 从 World.Map 获取区域
if self.world and self.world.map:
region = self.world.map.regions.get(rid)
if region:
@@ -122,7 +199,6 @@ class HistoryManager:
old_name = tech.name
self._update_obj_attrs(tech, data)
- # 同步 techniques_by_name 索引
if tech.name != old_name:
if old_name in techniques_by_name:
del techniques_by_name[old_name]
@@ -149,7 +225,6 @@ class HistoryManager:
old_name = item.name
self._update_obj_attrs(item, data)
- # 同步可选的 name 索引 (如 weapons_by_name)
if by_name_index is not None and item.name != old_name:
if old_name in by_name_index:
del by_name_index[old_name]
@@ -172,7 +247,4 @@ class HistoryManager:
if __name__ == "__main__":
# 模拟运行
- history_str = "上古时期..."
- # 注意:这里直接运行可能会报错,因为需要 World 对象
- # 这里只是为了保留文件结构的完整性
pass
diff --git a/src/classes/name.py b/src/classes/name.py
index ead3b15..29192d3 100644
--- a/src/classes/name.py
+++ b/src/classes/name.py
@@ -1,8 +1,8 @@
import random
-from typing import Optional
+from typing import Optional, Union
from dataclasses import dataclass
-from src.utils.df import game_configs, get_str
+from src.utils.df import game_configs, get_str, get_int
from src.classes.avatar import Gender
@@ -17,7 +17,7 @@ class GivenName:
"""名字"""
name: str
gender: Gender
- sect: Optional[str]
+ sect: Optional[int]
class NameManager:
@@ -34,14 +34,14 @@ class NameManager:
Gender.MALE: [],
Gender.FEMALE: []
}
- # 按宗门和性别分类的名字 {宗门名: {Gender: [名字列表]}}
- self.sect_given_names: dict[str, dict[Gender, list[str]]] = {}
+ # 按宗门和性别分类的名字 {宗门ID: {Gender: [名字列表]}}
+ self.sect_given_names: dict[int, dict[Gender, list[str]]] = {}
self._load_names()
def _load_names(self):
"""从CSV加载姓名数据"""
- # 加载姓氏
+ # 加载姓氏 (保留使用 name 引用)
last_name_df = game_configs["last_name"]
for row in last_name_df:
name = get_str(row, "last_name")
@@ -54,87 +54,63 @@ class NameManager:
else:
self.common_last_names.append(name)
- # 加载名字
+ # 加载名字 (使用 sect_id 引用)
given_name_df = game_configs["given_name"]
for row in given_name_df:
name = get_str(row, "given_name")
gender_str = get_str(row, "gender")
gender = Gender.MALE if gender_str == "男" else Gender.FEMALE
- sect = get_str(row, "sect")
+ # 尝试读取 sect_id,兼容旧的 sect 列(虽然已经被迁移脚本改了)
+ sect_id = get_int(row, "sect_id")
- if sect:
- if sect not in self.sect_given_names:
- self.sect_given_names[sect] = {Gender.MALE: [], Gender.FEMALE: []}
- self.sect_given_names[sect][gender].append(name)
+ if sect_id > 0:
+ if sect_id not in self.sect_given_names:
+ self.sect_given_names[sect_id] = {Gender.MALE: [], Gender.FEMALE: []}
+ self.sect_given_names[sect_id][gender].append(name)
else:
self.common_given_names[gender].append(name)
def get_random_last_name(self, sect_name: Optional[str] = None) -> str:
"""
获取随机姓氏
-
- Args:
- sect_name: 宗门名称,如果为None则从散修姓氏中选择
-
- Returns:
- 姓氏字符串
"""
if sect_name and sect_name in self.sect_last_names:
return random.choice(self.sect_last_names[sect_name])
return random.choice(self.common_last_names)
- def get_random_given_name(self, gender: Gender, sect_name: Optional[str] = None) -> str:
+ def get_random_given_name(self, gender: Gender, sect_id: Optional[int] = None) -> str:
"""
获取随机名字
-
- Args:
- gender: 性别
- sect_name: 宗门名称,如果为None则从散修名字中选择
-
- Returns:
- 名字字符串
"""
- if sect_name and sect_name in self.sect_given_names:
- sect_names = self.sect_given_names[sect_name][gender]
+ if sect_id and sect_id in self.sect_given_names:
+ sect_names = self.sect_given_names[sect_id][gender]
if sect_names:
return random.choice(sect_names)
return random.choice(self.common_given_names[gender])
- def get_random_full_name(self, gender: Gender, sect_name: Optional[str] = None) -> str:
+ def get_random_full_name(self, gender: Gender, sect_name: Optional[str] = None, sect_id: Optional[int] = None) -> str:
"""
获取随机全名
-
- Args:
- gender: 性别
- sect_name: 宗门名称,如果为None则为散修
-
- Returns:
- 完整姓名
"""
last_name = self.get_random_last_name(sect_name)
- given_name = self.get_random_given_name(gender, sect_name)
+ given_name = self.get_random_given_name(gender, sect_id)
return last_name + given_name
def get_random_full_name_with_surname(
self,
gender: Gender,
surname: str,
- sect_name: Optional[str] = None
+ sect_id: Optional[int] = None
) -> str:
"""
使用指定姓氏生成随机全名
-
- Args:
- gender: 性别
- surname: 指定的姓氏
- sect_name: 宗门名称,如果为None则为散修
-
- Returns:
- 完整姓名
"""
if not surname:
- return self.get_random_full_name(gender, sect_name)
- given_name = self.get_random_given_name(gender, sect_name)
+ # 如果没有提供姓氏,回退到随机全名(这里假设没有 sect_name 传进来,因为这个函数签名里没有)
+ # 为了严谨,这里只能生成随机名
+ return self.get_random_full_name(gender, None, sect_id)
+
+ given_name = self.get_random_given_name(gender, sect_id)
return surname + given_name
@@ -142,35 +118,23 @@ class NameManager:
_name_manager = NameManager()
-def get_random_name(gender: Gender, sect_name: Optional[str] = None) -> str:
+def get_random_name(gender: Gender, sect_name: Optional[str] = None, sect_id: Optional[int] = None) -> str:
"""获取随机全名"""
- return _name_manager.get_random_full_name(gender, sect_name)
+ return _name_manager.get_random_full_name(gender, sect_name, sect_id)
def get_random_name_for_sect(gender: Gender, sect) -> str:
"""
基于宗门生成姓名(兼容旧接口)
-
- Args:
- gender: 性别
- sect: Sect对象或None
-
- Returns:
- 完整姓名
"""
sect_name = sect.name if sect is not None else None
- return _name_manager.get_random_full_name(gender, sect_name)
+ sect_id = sect.id if sect is not None else None
+ return _name_manager.get_random_full_name(gender, sect_name, sect_id)
def pick_surname_for_sect(sect) -> str:
"""
从宗门常见姓或全局库中挑选一个姓氏(兼容旧接口)
-
- Args:
- sect: Sect对象或None
-
- Returns:
- 姓氏
"""
sect_name = sect.name if sect is not None else None
return _name_manager.get_random_last_name(sect_name)
@@ -183,14 +147,6 @@ def get_random_name_with_surname(
) -> str:
"""
使用指定姓氏生成随机全名(兼容旧接口)
-
- Args:
- gender: 性别
- surname: 指定的姓氏
- sect: Sect对象或None
-
- Returns:
- 完整姓名
"""
- sect_name = sect.name if sect is not None else None
- return _name_manager.get_random_full_name_with_surname(gender, surname, sect_name)
+ sect_id = sect.id if sect is not None else None
+ return _name_manager.get_random_full_name_with_surname(gender, surname, sect_id)
diff --git a/src/classes/region.py b/src/classes/region.py
index 8db4ed8..4d549fc 100644
--- a/src/classes/region.py
+++ b/src/classes/region.py
@@ -170,9 +170,10 @@ class NormalRegion(Region):
@dataclass(eq=False)
class CultivateRegion(Region):
- """修炼区域"""
+ """修炼区域(洞府/遗迹)"""
essence_type: EssenceType = EssenceType.GOLD # 默认值避免 dataclass 继承错误
essence_density: int = 0
+ sub_type: str = "cave" # "cave" 或 "ruin"
essence: Essence = field(init=False)
# 洞府主人:默认为空(无主)
@@ -195,11 +196,12 @@ class CultivateRegion(Region):
def get_structured_info(self) -> dict:
info = super().get_structured_info()
- info["type_name"] = "修炼区域"
+ info["type_name"] = "洞府" if self.sub_type == "cave" else "遗迹"
info["essence"] = {
"type": str(self.essence_type),
"density": self.essence_density
}
+ info["sub_type"] = self.sub_type
if self.host_avatar:
info["host"] = {
diff --git a/src/classes/sect.py b/src/classes/sect.py
index 1355959..9e89893 100644
--- a/src/classes/sect.py
+++ b/src/classes/sect.py
@@ -200,7 +200,7 @@ def _load_sects() -> tuple[dict[int, Sect], dict[str, Sect]]:
technique_names = [
get_str(t, "name")
for t in tech_df
- if get_str(t, "sect") == name and get_str(t, "name")
+ if get_int(t, "sect_id") == sid and get_str(t, "name")
]
weight = get_float(row, "weight", 1.0)
diff --git a/src/classes/world.py b/src/classes/world.py
index 6059531..bc6449d 100644
--- a/src/classes/world.py
+++ b/src/classes/world.py
@@ -26,6 +26,8 @@ class World():
phenomenon_start_year: int = 0
# 出世物品流通管理器
circulation: CirculationManager = field(default_factory=CirculationManager)
+ # 世界历史文本
+ history: str = ""
def get_info(self, detailed: bool = False, avatar: Optional["Avatar"] = None) -> dict:
"""
@@ -47,6 +49,10 @@ class World():
def get_observable_avatars(self, avatar: "Avatar"):
return self.avatar_manager.get_observable_avatars(avatar)
+ def set_history(self, history_text: str):
+ """设置世界历史文本"""
+ self.history = history_text
+
@property
def static_info(self) -> dict:
desc = {
@@ -65,6 +71,8 @@ class World():
"装备与丹药": "通过兵器、辅助装备、丹药等装备,可以获得额外的属性加成,获得或小或大的增益。拥有好的装备或者服用好的丹药,能获得很大好处。",
"购物": "在城市区域可以购买练气级别丹药、兵器。购买丹药后会立刻服用强化自身。购买兵器可以帮自己切换兵器类型为顺手的类型。",
}
+ if self.history:
+ desc["历史"] = self.history
return desc
@classmethod
diff --git a/src/run/load_map.py b/src/run/load_map.py
index b660129..081cd50 100644
--- a/src/run/load_map.py
+++ b/src/run/load_map.py
@@ -104,6 +104,7 @@ def _load_and_assign_regions(game_map: Map, region_coords: dict[int, list[tuple[
elif type_tag == "cultivate":
params["essence_type"] = EssenceType.from_str(get_str(row, "root_type"))
params["essence_density"] = get_int(row, "root_density")
+ params["sub_type"] = get_str(row, "sub_type") or "cave"
elif type_tag == "city":
sell_ids_str = get_str(row, "sell_item_ids")
if sell_ids_str:
diff --git a/src/server/main.py b/src/server/main.py
index 8059f7b..f601ada 100644
--- a/src/server/main.py
+++ b/src/server/main.py
@@ -343,6 +343,7 @@ async def init_game_async():
update_init_progress(2, "processing_history")
world_history = getattr(CONFIG.game, "world_history", "")
if world_history and world_history.strip():
+ world.set_history(world_history)
print(f"正在根据历史背景重塑世界: {world_history[:50]}...")
try:
history_mgr = HistoryManager(world)
@@ -856,18 +857,22 @@ def get_map():
if hasattr(r, 'get_region_type'):
rtype = r.get_region_type()
- region_dict = {
- "id": r.id,
- "name": r.name,
- "type": rtype,
- "x": r.center_loc[0],
- "y": r.center_loc[1]
- }
- # 如果是宗门区域,额外传递 sect_name 用于前端加载图片
- if hasattr(r, 'sect_name'):
- region_dict["sect_name"] = r.sect_name
-
- regions_data.append(region_dict)
+ region_dict = {
+ "id": r.id,
+ "name": r.name,
+ "type": rtype,
+ "x": r.center_loc[0],
+ "y": r.center_loc[1]
+ }
+ # 如果是宗门区域,传递 sect_id 用于前端加载图片资源
+ if hasattr(r, 'sect_id'):
+ region_dict["sect_id"] = r.sect_id
+
+ # 如果是修炼区域(洞府/遗迹),传递 sub_type
+ if hasattr(r, 'sub_type'):
+ region_dict["sub_type"] = r.sub_type
+
+ regions_data.append(region_dict)
return {
"width": w,
diff --git a/src/sim/load/load_game.py b/src/sim/load/load_game.py
index 21a4fa5..63e4f78 100644
--- a/src/sim/load/load_game.py
+++ b/src/sim/load/load_game.py
@@ -108,6 +108,11 @@ def load_game(save_path: Optional[Path] = None) -> Tuple["World", "Simulator", L
events_db_path=events_db_path,
)
+ # 恢复世界历史
+ history = world_data.get("history", "")
+ if history:
+ world.set_history(history)
+
# 重建天地灵机
from src.classes.celestial_phenomenon import celestial_phenomena_by_id
phenomenon_id = world_data.get("current_phenomenon_id")
diff --git a/src/sim/save/save_game.py b/src/sim/save/save_game.py
index 6524f54..381960c 100644
--- a/src/sim/save/save_game.py
+++ b/src/sim/save/save_game.py
@@ -122,6 +122,8 @@ def save_game(
"cultivate_regions_hosts": cultivate_regions_hosts,
# 出世物品流转
"circulation": world.circulation.to_save_dict(),
+ # 世界历史
+ "history": world.history,
}
# 保存所有Avatar(第一阶段:不含relations)
diff --git a/static/game_configs/city_region.csv b/static/game_configs/city_region.csv
index 7876d2b..ec1d3e2 100644
--- a/static/game_configs/city_region.csv
+++ b/static/game_configs/city_region.csv
@@ -1,7 +1,7 @@
id,name,desc,sell_item_ids
ID必须以3开头,,,
301,青云城,繁华都市,人烟稠密,商贾云集。此地是交易天材地宝、寻找机缘的重要场所。,"[3001, 3005]"
-302,沙月城,沙漠绿洲中的贸易重镇,各路商队在此集结,是修士补给和交流的重要据点。,"[3009, 3013]"
+302,沙州城,沙漠绿洲中的贸易重镇,各路商队在此集结,是修士补给和交流的重要据点。,"[3009, 3013]"
303,翠林城,森林深处的修仙重镇,众多修士在此栖居,是修炼和炼宝的理想之地。,"[1001, 1002, 1003]"
304,沧澜城,坐落于大河入海口的三角洲,百川归海,水运昌隆,是水系修士往来最为频繁的宝地。,"[1004, 1005, 1006]"
305,揽月城,屹立于连绵群山之巅,终年云雾缭绕,灵气纯净,是苦修之士感悟天道的绝佳场所。,"[1007, 1008, 1009]"
diff --git a/static/game_configs/cultivate_region.csv b/static/game_configs/cultivate_region.csv
index 92e3631..b7c3edb 100644
--- a/static/game_configs/cultivate_region.csv
+++ b/static/game_configs/cultivate_region.csv
@@ -1,9 +1,9 @@
-id,name,desc,root_type,root_density
-ID必须以2开头,,,,
-201,太白金府,青峰山脉深处的金行洞府,金精气凝,刀剑鸣音不绝,乃金系修士的最高圣地。,金,10
-202,青木洞天,青云林海中的木行洞府,生机盎然,灵药遍地,乃木系修士的最高圣地。,木,10
-203,玄水秘境,无边碧海深处的水行洞府,碧波万里,水精凝神,乃水系修士的最高圣地。,水,10
-204,离火洞府,炎狱火山旁的火行洞府,烈焰冲天,真火精纯,乃火系修士的最高圣地。,火,10
-205,厚土玄宫,青峰山脉的土行洞府,厚德载物,山岳共鸣,乃土系修士的最高圣地。,土,10
-206,古越遗迹,雨林深处的上古遗迹,古藤缠绕,木行灵气与金行灵气交融。蕴藏古老功法与灵药配方。,木,8
-207,沧海遗迹,沉没在海中的远古文明遗迹,水行灵气浓郁,潮汐间偶有宝物现世。,水,9
+id,name,desc,sub_type,root_type,root_density
+ID必须以2开头,,,,,
+201,太白金府,青峰山脉深处的金行洞府,金精气凝,刀剑鸣音不绝,乃金系修士的最高圣地。,cave,金,10
+202,青木洞天,青云林海中的木行洞府,生机盎然,灵药遍地,乃木系修士的最高圣地。,cave,木,10
+203,玄水秘境,无边碧海深处的水行洞府,碧波万里,水精凝神,乃水系修士的最高圣地。,cave,水,10
+204,离火洞府,炎狱火山旁的火行洞府,烈焰冲天,真火精纯,乃火系修士的最高圣地。,cave,火,10
+205,厚土玄宫,青峰山脉的土行洞府,厚德载物,山岳共鸣,乃土系修士的最高圣地。,cave,土,10
+206,古越遗迹,雨林深处的上古遗迹,古藤缠绕,木行灵气与金行灵气交融。蕴藏古老功法与灵药配方。,ruin,木,8
+207,沧海遗迹,沉没在海中的远古文明遗迹,水行灵气浓郁,潮汐间偶有宝物现世。,ruin,水,9
diff --git a/static/game_configs/given_name.csv b/static/game_configs/given_name.csv
index 07a7652..12a96bf 100644
--- a/static/game_configs/given_name.csv
+++ b/static/game_configs/given_name.csv
@@ -1,5 +1,5 @@
-given_name,gender,sect,cond
-名字,性别(男/女),宗门名称(空=散修通用),条件(暂不用)
+given_name,gender,sect_id,cond
+名字,性别(男/女),宗门ID(空=散修),条件(暂不用)
逍遥,男,,
无极,男,,
天行,男,,
@@ -200,802 +200,802 @@ given_name,gender,sect,cond
初晴,女,,
寒烟,女,,
月珑,女,,
-澄川,男,明心剑宗,
-宏石,男,明心剑宗,
-磐岳,男,明心剑宗,
-霆岱,男,明心剑宗,
-寂岚,男,明心剑宗,
-久安,男,明心剑宗,
-宸秋,男,明心剑宗,
-烁离,男,明心剑宗,
-沧岳,男,明心剑宗,
-砺锋,男,明心剑宗,
-炎洲,男,明心剑宗,
-远歌,男,明心剑宗,
-采微,女,明心剑宗,
-霏岚,女,明心剑宗,
-韶华,女,明心剑宗,
-绮澜,女,明心剑宗,
-珠影,女,明心剑宗,
-远岫,女,明心剑宗,
-若水,女,明心剑宗,
-凝香,女,明心剑宗,
-雪瑶,女,明心剑宗,
-南絮,女,明心剑宗,
-轻萝,女,明心剑宗,
-宛竹,女,明心剑宗,
-驼王,男,百兽宗,
-飞熊,男,百兽宗,
-虎魄,男,百兽宗,
-狼行,男,百兽宗,
-熊罡,男,百兽宗,
-白猿,男,百兽宗,
-石坚,男,百兽宗,
-山岚,男,百兽宗,
-青鬃,男,百兽宗,
-玄爪,男,百兽宗,
-金瞳,男,百兽宗,
-裂爪,男,百兽宗,
-破角,男,百兽宗,
-狂鬃,男,百兽宗,
-赤鬣,男,百兽宗,
-苍隼,男,百兽宗,
-啸风,男,百兽宗,
-裂岩,男,百兽宗,
-狐绮,女,百兽宗,
-白貂,女,百兽宗,
-青翎,女,百兽宗,
-雪牙,女,百兽宗,
-赤羽,女,百兽宗,
-玄狸,女,百兽宗,
-灵爪,女,百兽宗,
-月狐,女,百兽宗,
-银鳞,女,百兽宗,
-霜蹄,女,百兽宗,
-云貉,女,百兽宗,
-绒尾,女,百兽宗,
-锦狐,女,百兽宗,
-轻蹄,女,百兽宗,
-涟光,男,水镜宗,
-沧浪,男,水镜宗,
-泽远,男,水镜宗,
-浩川,男,水镜宗,
-泊舟,男,水镜宗,
-涓石,男,水镜宗,
-溪原,男,水镜宗,
-涵舟,男,水镜宗,
-泠曜,男,水镜宗,
-漪岑,男,水镜宗,
-淞岳,男,水镜宗,
-涔雨,男,水镜宗,
-漫霖,女,水镜宗,
-洛漪,女,水镜宗,
-潋月,女,水镜宗,
-涵烟,女,水镜宗,
-沁波,女,水镜宗,
-翠波,女,水镜宗,
-漫葭,女,水镜宗,
-汀兰,女,水镜宗,
-潭歌,女,水镜宗,
-涓玥,女,水镜宗,
-澧宁,女,水镜宗,
-潇然,女,水镜宗,
-血燎,男,冥王宗,
-焚魄,男,冥王宗,
-灰灭,男,冥王宗,
-殁川,男,冥王宗,
-绝尘,男,冥王宗,
-厌离,男,冥王宗,
-朔寒,男,冥王宗,
-邪风,男,冥王宗,
-归墟,男,冥王宗,
-朽骨,男,冥王宗,
-朔月,男,冥王宗,
-止戈,男,冥王宗,
-寒绫,女,冥王宗,
-霜瑶,女,冥王宗,
-凄歌,女,冥王宗,
-素鸢,女,冥王宗,
-祭宁,女,冥王宗,
-黛魂,女,冥王宗,
-夙梦,女,冥王宗,
-绫雪,女,冥王宗,
-凛珑,女,冥王宗,
-霁月,女,冥王宗,
-旷音,女,冥王宗,
-凝岚,女,冥王宗,
-暗阑,男,朱勾宗,
-机括,男,朱勾宗,
-鬼匣,男,朱勾宗,
-夜禁,男,朱勾宗,
-幻锁,男,朱勾宗,
-残锋,男,朱勾宗,
-暗弦,男,朱勾宗,
-影栅,男,朱勾宗,
-幽钩,男,朱勾宗,
-断线,男,朱勾宗,
-潜匿,男,朱勾宗,
-迷踪,男,朱勾宗,
-玄簪,女,朱勾宗,
-霜绡,女,朱勾宗,
-纤罗,女,朱勾宗,
-碎玉,女,朱勾宗,
-影裳,女,朱勾宗,
-轻弦,女,朱勾宗,
-凝黛,女,朱勾宗,
-凝烟,女,朱勾宗,
-冷珥,女,朱勾宗,
-素纱,女,朱勾宗,
-凛钗,女,朱勾宗,
-寒袖,女,朱勾宗,
-流烟,男,合欢宗,
-迟夜,男,合欢宗,
-长陌,男,合欢宗,
-归舟,男,合欢宗,
-暮成,男,合欢宗,
-远辞,男,合欢宗,
-行止,男,合欢宗,
-轻寒,男,合欢宗,
-沉香,男,合欢宗,
-野鹤,男,合欢宗,
-乘风,男,合欢宗,
-婉心,女,合欢宗,
-轻柔,女,合欢宗,
-疏影,女,合欢宗,
-如梦,女,合欢宗,
-绮念,女,合欢宗,
-惜香,女,合欢宗,
-慕雪,女,合欢宗,
-倾城,女,合欢宗,
-绯烟,女,合欢宗,
-晚晴,女,合欢宗,
-素袖,女,合欢宗,
-霁眉,女,合欢宗,
-绸缪,女,合欢宗,
-静妍,女,合欢宗,
-安魄,男,镇魂宗,
-靖川,男,镇魂宗,
-霁阳,男,镇魂宗,
-季衡,男,镇魂宗,
-砺甲,男,镇魂宗,
-烁锋,男,镇魂宗,
-昊戈,男,镇魂宗,
-祁光,男,镇魂宗,
-漠石,男,镇魂宗,
-启封,男,镇魂宗,
-殷策,男,镇魂宗,
-定魄,男,镇魂宗,
-清宁,女,镇魂宗,
-素铃,女,镇魂宗,
-靖霜,女,镇魂宗,
-澄心,女,镇魂宗,
-霁雪,女,镇魂宗,
-安祈,女,镇魂宗,
-净月,女,镇魂宗,
-宁枝,女,镇魂宗,
-祷绫,女,镇魂宗,
-明槐,女,镇魂宗,
-采霁,女,镇魂宗,
-定寒,女,镇魂宗,
-噬影,男,幽魂噬影宗,
-无藏,男,幽魂噬影宗,
-绝响,男,幽魂噬影宗,
-断痕,男,幽魂噬影宗,
-影渊,男,幽魂噬影宗,
-暗行,男,幽魂噬影宗,
-潜踪,男,幽魂噬影宗,
-魄隐,男,幽魂噬影宗,
-迷雾,男,幽魂噬影宗,
-空蝉,男,幽魂噬影宗,
-断念,男,幽魂噬影宗,
-裂隙,男,幽魂噬影宗,
-影绫,女,幽魂噬影宗,
-暗萝,女,幽魂噬影宗,
-霜绡,女,幽魂噬影宗,
-素鹭,女,幽魂噬影宗,
-玄绮,女,幽魂噬影宗,
-凝灯,女,幽魂噬影宗,
-绫岚,女,幽魂噬影宗,
-凛铃,女,幽魂噬影宗,
-朔华,女,幽魂噬影宗,
-漠音,女,幽魂噬影宗,
-宵岑,女,幽魂噬影宗,
-泠歌,女,幽魂噬影宗,
-持衡,男,千帆城,
-清评,男,千帆城,
-问价,男,千帆城,
-立契,男,千帆城,
-通衡,男,千帆城,
-问道,男,千帆城,
-理市,男,千帆城,
-衡准,男,千帆城,
-守约,男,千帆城,
-筑匠,男,千帆城,
-铸衡,男,千帆城,
-估算,男,千帆城,
-素蓝,女,千帆城,
-明衡,女,千帆城,
-巧心,女,千帆城,
-青帆,女,千帆城,
-绫舟,女,千帆城,
-观星,女,千帆城,
-衡绫,女,千帆城,
-星槎,女,千帆城,
-织霓,女,千帆城,
-采绫,女,千帆城,
-芸巧,女,千帆城,
-霁行,女,千帆城,
-砚秋,女,千帆城,
-镶玑,女,千帆城,
-绘蓝,女,千帆城,
-银梭,女,千帆城,
-珩心,女,千帆城,
-凌虚,男,明心剑宗,
-剑尘,男,明心剑宗,
-浩然,男,明心剑宗,
-长风,男,明心剑宗,
-问天,男,明心剑宗,
-断岳,男,明心剑宗,
-流云,男,明心剑宗,
-守心,男,明心剑宗,
-剑鸣,男,明心剑宗,
-天锋,男,明心剑宗,
-傲雪,男,明心剑宗,
-寒松,男,明心剑宗,
-抱朴,男,明心剑宗,
-归真,男,明心剑宗,
-绝云,男,明心剑宗,
-破妄,男,明心剑宗,
-承天,男,明心剑宗,
-御空,男,明心剑宗,
-凌绝,男,明心剑宗,
-剑痴,男,明心剑宗,
-独行,男,明心剑宗,
-苍松,男,明心剑宗,
-劲节,男,明心剑宗,
-问剑,男,明心剑宗,
-亦云,男,明心剑宗,
-止水,男,明心剑宗,
-寒锋,男,明心剑宗,
-孤剑,男,明心剑宗,
-凌霜,男,明心剑宗,
-彻空,男,明心剑宗,
-绝尘,男,明心剑宗,
-一剑,男,明心剑宗,
-洗墨,男,明心剑宗,
-藏锋,男,明心剑宗,
-折梅,男,明心剑宗,
-负剑,男,明心剑宗,
-听风,男,明心剑宗,
-观海,男,明心剑宗,
-问心,男,明心剑宗,
-求道,男,明心剑宗,
-寒梅,女,明心剑宗,
-剑舞,女,明心剑宗,
-清涟,女,明心剑宗,
-云舒,女,明心剑宗,
-听雨,女,明心剑宗,
-若云,女,明心剑宗,
-灵韵,女,明心剑宗,
-问心,女,明心剑宗,
-霜雪,女,明心剑宗,
-傲梅,女,明心剑宗,
-清心,女,明心剑宗,
-凌波,女,明心剑宗,
-芷若,女,明心剑宗,
-怀柔,女,明心剑宗,
-听剑,女,明心剑宗,
-舞剑,女,明心剑宗,
-凝剑,女,明心剑宗,
-冰清,女,明心剑宗,
-玉洁,女,明心剑宗,
-晓月,女,明心剑宗,
-寒霜,女,明心剑宗,
-凌烟,女,明心剑宗,
-梦剑,女,明心剑宗,
-亦柔,女,明心剑宗,
-芷兰,女,明心剑宗,
-清微,女,明心剑宗,
-寒香,女,明心剑宗,
-剑兰,女,明心剑宗,
-傲霜,女,明心剑宗,
-凌月,女,明心剑宗,
-拂雪,女,明心剑宗,
-挽剑,女,明心剑宗,
-青丝,女,明心剑宗,
-若雪,女,明心剑宗,
-含烟,女,明心剑宗,
-如冰,女,明心剑宗,
-傲竹,女,明心剑宗,
-清影,女,明心剑宗,
-绝尘,女,明心剑宗,
-心剑,女,明心剑宗,
-狂狮,男,百兽宗,
-龙牙,男,百兽宗,
-蛮牛,男,百兽宗,
-鹰眼,男,百兽宗,
-血狼,男,百兽宗,
-震山,男,百兽宗,
-铁臂,男,百兽宗,
-獠牙,男,百兽宗,
-虎啸,男,百兽宗,
-豹奔,男,百兽宗,
-熊力,男,百兽宗,
-猿啼,男,百兽宗,
-狼顾,男,百兽宗,
-鹰扬,男,百兽宗,
-狮吼,男,百兽宗,
-狂战,男,百兽宗,
-兽心,男,百兽宗,
-怒涛,男,百兽宗,
-裂地,男,百兽宗,
-碎岩,男,百兽宗,
-霸天,男,百兽宗,
-狂蟒,男,百兽宗,
-犀角,男,百兽宗,
-鳄牙,男,百兽宗,
-鹏飞,男,百兽宗,
-贪狼,男,百兽宗,
-破军,男,百兽宗,
-七杀,男,百兽宗,
-暴熊,男,百兽宗,
-毒牙,男,百兽宗,
-狂骨,男,百兽宗,
-荒咬,男,百兽宗,
-灵蛇,女,百兽宗,
-雀羽,女,百兽宗,
-鹿鸣,女,百兽宗,
-猫影,女,百兽宗,
-蜂刺,女,百兽宗,
-蝶衣,女,百兽宗,
-燕舞,女,百兽宗,
-狐灵,女,百兽宗,
-白鹭,女,百兽宗,
-青鸾,女,百兽宗,
-朱雀,女,百兽宗,
-银狐,女,百兽宗,
-灵猫,女,百兽宗,
-锦鲤,女,百兽宗,
-翠鸟,女,百兽宗,
-灵犀,女,百兽宗,
-幼鹿,女,百兽宗,
-飞燕,女,百兽宗,
-灵鹤,女,百兽宗,
-丹顶,女,百兽宗,
-锦翎,女,百兽宗,
-翠羽,女,百兽宗,
-斑斓,女,百兽宗,
-啸月,女,百兽宗,
-灵狐,女,百兽宗,
-媚猫,女,百兽宗,
-蛇舞,女,百兽宗,
-蛛儿,女,百兽宗,
-蝎娘,女,百兽宗,
-彩蝶,女,百兽宗,
-金蚕,女,百兽宗,
-玉蝉,女,百兽宗,
-灵贝,女,百兽宗,
-鲛珠,女,百兽宗,
-澜沧,男,水镜宗,
-镜明,男,水镜宗,
-寒潭,男,水镜宗,
-深蓝,男,水镜宗,
-听潮,男,水镜宗,
-无涯,男,水镜宗,
-冰封,男,水镜宗,
-流水,男,水镜宗,
-瀚海,男,水镜宗,
-渊默,男,水镜宗,
-沉渊,男,水镜宗,
-浮光,男,水镜宗,
-掠影,男,水镜宗,
-镜花,男,水镜宗,
-水月,男,水镜宗,
-寒江,男,水镜宗,
-孤帆,男,水镜宗,
-远影,男,水镜宗,
-碧波,男,水镜宗,
-涟漪,男,水镜宗,
-清流,男,水镜宗,
-激浪,男,水镜宗,
-惊涛,男,水镜宗,
-骇浪,男,水镜宗,
-冰棱,男,水镜宗,
-霜冻,男,水镜宗,
-雪飘,男,水镜宗,
-雾锁,男,水镜宗,
-云深,男,水镜宗,
-潜龙,男,水镜宗,
-深渊,男,水镜宗,
-海阔,男,水镜宗,
-天青,男,水镜宗,
-雨歇,男,水镜宗,
-潮生,男,水镜宗,
-汐落,男,水镜宗,
-冰河,男,水镜宗,
-雪峰,男,水镜宗,
-寒露,男,水镜宗,
-涟漪,女,水镜宗,
-水月,女,水镜宗,
-雾纱,女,水镜宗,
-冰洁,女,水镜宗,
-露珠,女,水镜宗,
-海悦,女,水镜宗,
-清溪,女,水镜宗,
-雨霏,女,水镜宗,
-浣纱,女,水镜宗,
-采莲,女,水镜宗,
-弄潮,女,水镜宗,
-踏浪,女,水镜宗,
-潜游,女,水镜宗,
-浮水,女,水镜宗,
-镜心,女,水镜宗,
-水灵,女,水镜宗,
-冰魄,女,水镜宗,
-雪魂,女,水镜宗,
-霜儿,女,水镜宗,
-露儿,女,水镜宗,
-雨儿,女,水镜宗,
-云儿,女,水镜宗,
-雾儿,女,水镜宗,
-烟儿,女,水镜宗,
-渺儿,女,水镜宗,
-淼儿,女,水镜宗,
-湘君,女,水镜宗,
-湘妃,女,水镜宗,
-洛神,女,水镜宗,
-宓妃,女,水镜宗,
-冰心,女,水镜宗,
-雪儿,女,水镜宗,
-海兰,女,水镜宗,
-江月,女,水镜宗,
-湖光,女,水镜宗,
-溪月,女,水镜宗,
-泉韵,女,水镜宗,
-雨荷,女,水镜宗,
-露华,女,水镜宗,
-霜月,女,水镜宗,
-枯骨,男,冥王宗,
-厉魂,男,冥王宗,
-血煞,男,冥王宗,
-无常,男,冥王宗,
-丧钟,男,冥王宗,
-墓碑,男,冥王宗,
-鬼火,男,冥王宗,
-修罗,男,冥王宗,
-阎罗,男,冥王宗,
-判官,男,冥王宗,
-勾魂,男,冥王宗,
-摄魄,男,冥王宗,
-阴阳,男,冥王宗,
-生死,男,冥王宗,
-轮回,男,冥王宗,
-奈何,男,冥王宗,
-忘川,男,冥王宗,
-黄泉,男,冥王宗,
-碧落,男,冥王宗,
-幽冥,男,冥王宗,
-罗刹,男,冥王宗,
-夜叉,男,冥王宗,
-魍魉,男,冥王宗,
-魑魅,男,冥王宗,
-饕餮,男,冥王宗,
-灰烬,男,冥王宗,
-残魂,男,冥王宗,
-断魄,男,冥王宗,
-绝命,男,冥王宗,
-追魂,男,冥王宗,
-索命,男,冥王宗,
-无赦,男,冥王宗,
-天罚,男,冥王宗,
-地藏,男,冥王宗,
-幽兰,女,冥王宗,
-鬼姬,女,冥王宗,
-彼岸,女,冥王宗,
-忘川,女,冥王宗,
-孟婆,女,冥王宗,
-阴灵,女,冥王宗,
-骨香,女,冥王宗,
-血蔷,女,冥王宗,
-艳鬼,女,冥王宗,
-倩女,女,冥王宗,
-幽魂,女,冥王宗,
-离魂,女,冥王宗,
-索命,女,冥王宗,
-追魂,女,冥王宗,
-夺魄,女,冥王宗,
-迷魂,女,冥王宗,
-阴后,女,冥王宗,
-鬼母,女,冥王宗,
-骨女,女,冥王宗,
-阴风,女,冥王宗,
-愁云,女,冥王宗,
-冥烛,女,冥王宗,
-灵幡,女,冥王宗,
-魂铃,女,冥王宗,
-尸香,女,冥王宗,
-血魅,女,冥王宗,
-骨姬,女,冥王宗,
-阴月,女,冥王宗,
-鬼魅,女,冥王宗,
-绝弦,男,朱勾宗,
-影杀,男,朱勾宗,
-天机,男,朱勾宗,
-鬼手,男,朱勾宗,
-连环,男,朱勾宗,
-破甲,男,朱勾宗,
-透骨,男,朱勾宗,
-索命,男,朱勾宗,
-无影,男,朱勾宗,
-追风,男,朱勾宗,
-夺命,男,朱勾宗,
-穿心,男,朱勾宗,
-封喉,男,朱勾宗,
-见血,男,朱勾宗,
-必杀,男,朱勾宗,
-绝杀,男,朱勾宗,
-瞬杀,男,朱勾宗,
-偃师,男,朱勾宗,
-神机,男,朱勾宗,
-妙算,男,朱勾宗,
-鬼谷,男,朱勾宗,
-千机,男,朱勾宗,
-百炼,男,朱勾宗,
-神工,男,朱勾宗,
-天工,男,朱勾宗,
-巧夺,男,朱勾宗,
-夺天,男,朱勾宗,
-造化,男,朱勾宗,
-钉魂,男,朱勾宗,
-裂石,男,朱勾宗,
-穿云,男,朱勾宗,
-破风,男,朱勾宗,
-惊雷,男,朱勾宗,
-霹雳,男,朱勾宗,
-雷火,男,朱勾宗,
-暗雷,男,朱勾宗,
-伏击,男,朱勾宗,
-毒刺,女,朱勾宗,
-隐娘,女,朱勾宗,
-罗网,女,朱勾宗,
-千机,女,朱勾宗,
-袖箭,女,朱勾宗,
-丝雨,女,朱勾宗,
-暗香,女,朱勾宗,
-诡丝,女,朱勾宗,
-毒牙,女,朱勾宗,
-蛇蝎,女,朱勾宗,
-罂粟,女,朱勾宗,
-曼陀,女,朱勾宗,
-见血,女,朱勾宗,
-含沙,女,朱勾宗,
-射影,女,朱勾宗,
-梨花,女,朱勾宗,
-散花,女,朱勾宗,
-飞针,女,朱勾宗,
-织萝,女,朱勾宗,
-蛛网,女,朱勾宗,
-缠绵,女,朱勾宗,
-缚灵,女,朱勾宗,
-困兽,女,朱勾宗,
-锁心,女,朱勾宗,
-封印,女,朱勾宗,
-无影,女,朱勾宗,
-无踪,女,朱勾宗,
-无声,女,朱勾宗,
-无息,女,朱勾宗,
-夺魂,女,朱勾宗,
-摄魄,女,朱勾宗,
-迷香,女,朱勾宗,
-软筋,女,朱勾宗,
-断肠,女,朱勾宗,
-绝情,女,朱勾宗,
-惜花,男,合欢宗,
-醉月,男,合欢宗,
-多情,男,合欢宗,
-寻芳,男,合欢宗,
-风流,男,合欢宗,
-玉郎,男,合欢宗,
-春生,男,合欢宗,
-梦回,男,合欢宗,
-痴情,男,合欢宗,
-绝情,男,合欢宗,
-留情,男,合欢宗,
-钟情,男,合欢宗,
-朝露,男,合欢宗,
-晚霞,男,合欢宗,
-彩云,男,合欢宗,
-追月,男,合欢宗,
-摘星,男,合欢宗,
-弄玉,男,合欢宗,
-吹箫,男,合欢宗,
-抚琴,男,合欢宗,
-听曲,男,合欢宗,
-赏舞,男,合欢宗,
-品茗,男,合欢宗,
-怜香,男,合欢宗,
-惜玉,男,合欢宗,
-护花,男,合欢宗,
-风月,男,合欢宗,
-逍遥,男,合欢宗,
-媚儿,女,合欢宗,
-倾国,女,合欢宗,
-含羞,女,合欢宗,
-醉颜,女,合欢宗,
-红豆,女,合欢宗,
-相思,女,合欢宗,
-花魁,女,合欢宗,
-怜月,女,合欢宗,
-羞花,女,合欢宗,
-闭月,女,合欢宗,
-沉鱼,女,合欢宗,
-落雁,女,合欢宗,
-绝色,女,合欢宗,
-天香,女,合欢宗,
-国色,女,合欢宗,
-妖娆,女,合欢宗,
-妩媚,女,合欢宗,
-动人,女,合欢宗,
-春心,女,合欢宗,
-芳心,女,合欢宗,
-痴心,女,合欢宗,
-冰心,女,合欢宗,
-如幻,女,合欢宗,
-如诗,女,合欢宗,
-如画,女,合欢宗,
-佳人,女,合欢宗,
-红颜,女,合欢宗,
-绝代,女,合欢宗,
-风华,女,合欢宗,
-镇山,男,镇魂宗,
-伏魔,男,镇魂宗,
-铁壁,男,镇魂宗,
-金刚,男,镇魂宗,
-定海,男,镇魂宗,
-卫道,男,镇魂宗,
-正阳,男,镇魂宗,
-不坏,男,镇魂宗,
-磐石,男,镇魂宗,
-泰山,男,镇魂宗,
-不动,男,镇魂宗,
-如山,男,镇魂宗,
-巍峨,男,镇魂宗,
-雄伟,男,镇魂宗,
-壮观,男,镇魂宗,
-肃穆,男,镇魂宗,
-庄严,男,镇魂宗,
-威武,男,镇魂宗,
-凛然,男,镇魂宗,
-浩大,男,镇魂宗,
-宏大,男,镇魂宗,
-宽广,男,镇魂宗,
-博大,男,镇魂宗,
-精深,男,镇魂宗,
-厚德,男,镇魂宗,
-载物,男,镇魂宗,
-坤元,男,镇魂宗,
-乾元,男,镇魂宗,
-护法,男,镇魂宗,
-伽蓝,男,镇魂宗,
-韦驮,男,镇魂宗,
-天王,男,镇魂宗,
-力士,男,镇魂宗,
-罗汉,男,镇魂宗,
-尊者,男,镇魂宗,
-行者,男,镇魂宗,
-觉者,男,镇魂宗,
-智者,男,镇魂宗,
-守灵,女,镇魂宗,
-安魂,女,镇魂宗,
-净世,女,镇魂宗,
-慈航,女,镇魂宗,
-宝相,女,镇魂宗,
-金铃,女,镇魂宗,
-定心,女,镇魂宗,
-圣洁,女,镇魂宗,
-梵音,女,镇魂宗,
-禅心,女,镇魂宗,
-净土,女,镇魂宗,
-莲花,女,镇魂宗,
-菩提,女,镇魂宗,
-般若,女,镇魂宗,
-智慧,女,镇魂宗,
-圆满,女,镇魂宗,
-妙法,女,镇魂宗,
-真如,女,镇魂宗,
-法性,女,镇魂宗,
-佛性,女,镇魂宗,
-觉悟,女,镇魂宗,
-涅槃,女,镇魂宗,
-寂灭,女,镇魂宗,
-无为,女,镇魂宗,
-虚影,男,幽魂噬影宗,
-吞天,男,幽魂噬影宗,
-绝影,男,幽魂噬影宗,
-无声,男,幽魂噬影宗,
-夜行,男,幽魂噬影宗,
-莫测,男,幽魂噬影宗,
-幻灭,男,幽魂噬影宗,
-空无,男,幽魂噬影宗,
-虚空,男,幽魂噬影宗,
-无极,男,幽魂噬影宗,
-暗夜,男,幽魂噬影宗,
-潜行,男,幽魂噬影宗,
-伏击,男,幽魂噬影宗,
-瞬移,男,幽魂噬影宗,
-影遁,男,幽魂噬影宗,
-鬼步,男,幽魂噬影宗,
-魔踪,男,幽魂噬影宗,
-邪影,男,幽魂噬影宗,
-冥空,男,幽魂噬影宗,
-无妄,男,幽魂噬影宗,
-无相,男,幽魂噬影宗,
-魅影,女,幽魂噬影宗,
-夜魅,女,幽魂噬影宗,
-无形,女,幽魂噬影宗,
-幻音,女,幽魂噬影宗,
-幽梦,女,幽魂噬影宗,
-影舞,女,幽魂噬影宗,
-黑纱,女,幽魂噬影宗,
-虚灵,女,幽魂噬影宗,
-梦魇,女,幽魂噬影宗,
-梦魔,女,幽魂噬影宗,
-梦幻,女,幽魂噬影宗,
-泡影,女,幽魂噬影宗,
-镜花,女,幽魂噬影宗,
-海市,女,幽魂噬影宗,
-蜃楼,女,幽魂噬影宗,
-空花,女,幽魂噬影宗,
-迷离,女,幽魂噬影宗,
-恍惚,女,幽魂噬影宗,
-幽暗,女,幽魂噬影宗,
-晦涩,女,幽魂噬影宗,
-朦胧,女,幽魂噬影宗,
-隐约,女,幽魂噬影宗,
-飘渺,女,幽魂噬影宗,
-迷踪,女,幽魂噬影宗,
-幻影,女,幽魂噬影宗,
-宝通,男,千帆城,
-远航,男,千帆城,
-达观,男,千帆城,
-通达,男,千帆城,
-宏图,男,千帆城,
-伟业,男,千帆城,
-汇通,男,千帆城,
-天下,男,千帆城,
-金山,男,千帆城,
-银海,男,千帆城,
-聚宝,男,千帆城,
-珠儿,女,千帆城,
-玉润,女,千帆城,
-锦绣,女,千帆城,
-宝珠,女,千帆城,
-盈盈,女,千帆城,
-瑞彩,女,千帆城,
-金玉,女,千帆城,
-琳琅,女,千帆城,
-玛瑙,女,千帆城,
-翡翠,女,千帆城,
-琉璃,女,千帆城,
-琥珀,女,千帆城,
-珊瑚,女,千帆城,
-玳瑁,女,千帆城,
-珍珠,女,千帆城,
-宝石,女,千帆城,
-钻石,女,千帆城,
-水晶,女,千帆城,
-黄金,女,千帆城,
-白银,女,千帆城,
-丰盈,女,千帆城,
-彩霞,女,千帆城,
-云锦,女,千帆城,
-天孙,女,千帆城,
-织女,女,千帆城,
-巧手,女,千帆城,
-金枝,女,千帆城,
-玉叶,女,千帆城,
-闺秀,女,千帆城,
-风范,女,千帆城,
+澄川,男,1,
+宏石,男,1,
+磐岳,男,1,
+霆岱,男,1,
+寂岚,男,1,
+久安,男,1,
+宸秋,男,1,
+烁离,男,1,
+沧岳,男,1,
+砺锋,男,1,
+炎洲,男,1,
+远歌,男,1,
+采微,女,1,
+霏岚,女,1,
+韶华,女,1,
+绮澜,女,1,
+珠影,女,1,
+远岫,女,1,
+若水,女,1,
+凝香,女,1,
+雪瑶,女,1,
+南絮,女,1,
+轻萝,女,1,
+宛竹,女,1,
+驼王,男,2,
+飞熊,男,2,
+虎魄,男,2,
+狼行,男,2,
+熊罡,男,2,
+白猿,男,2,
+石坚,男,2,
+山岚,男,2,
+青鬃,男,2,
+玄爪,男,2,
+金瞳,男,2,
+裂爪,男,2,
+破角,男,2,
+狂鬃,男,2,
+赤鬣,男,2,
+苍隼,男,2,
+啸风,男,2,
+裂岩,男,2,
+狐绮,女,2,
+白貂,女,2,
+青翎,女,2,
+雪牙,女,2,
+赤羽,女,2,
+玄狸,女,2,
+灵爪,女,2,
+月狐,女,2,
+银鳞,女,2,
+霜蹄,女,2,
+云貉,女,2,
+绒尾,女,2,
+锦狐,女,2,
+轻蹄,女,2,
+涟光,男,3,
+沧浪,男,3,
+泽远,男,3,
+浩川,男,3,
+泊舟,男,3,
+涓石,男,3,
+溪原,男,3,
+涵舟,男,3,
+泠曜,男,3,
+漪岑,男,3,
+淞岳,男,3,
+涔雨,男,3,
+漫霖,女,3,
+洛漪,女,3,
+潋月,女,3,
+涵烟,女,3,
+沁波,女,3,
+翠波,女,3,
+漫葭,女,3,
+汀兰,女,3,
+潭歌,女,3,
+涓玥,女,3,
+澧宁,女,3,
+潇然,女,3,
+血燎,男,4,
+焚魄,男,4,
+灰灭,男,4,
+殁川,男,4,
+绝尘,男,4,
+厌离,男,4,
+朔寒,男,4,
+邪风,男,4,
+归墟,男,4,
+朽骨,男,4,
+朔月,男,4,
+止戈,男,4,
+寒绫,女,4,
+霜瑶,女,4,
+凄歌,女,4,
+素鸢,女,4,
+祭宁,女,4,
+黛魂,女,4,
+夙梦,女,4,
+绫雪,女,4,
+凛珑,女,4,
+霁月,女,4,
+旷音,女,4,
+凝岚,女,4,
+暗阑,男,5,
+机括,男,5,
+鬼匣,男,5,
+夜禁,男,5,
+幻锁,男,5,
+残锋,男,5,
+暗弦,男,5,
+影栅,男,5,
+幽钩,男,5,
+断线,男,5,
+潜匿,男,5,
+迷踪,男,5,
+玄簪,女,5,
+霜绡,女,5,
+纤罗,女,5,
+碎玉,女,5,
+影裳,女,5,
+轻弦,女,5,
+凝黛,女,5,
+凝烟,女,5,
+冷珥,女,5,
+素纱,女,5,
+凛钗,女,5,
+寒袖,女,5,
+流烟,男,6,
+迟夜,男,6,
+长陌,男,6,
+归舟,男,6,
+暮成,男,6,
+远辞,男,6,
+行止,男,6,
+轻寒,男,6,
+沉香,男,6,
+野鹤,男,6,
+乘风,男,6,
+婉心,女,6,
+轻柔,女,6,
+疏影,女,6,
+如梦,女,6,
+绮念,女,6,
+惜香,女,6,
+慕雪,女,6,
+倾城,女,6,
+绯烟,女,6,
+晚晴,女,6,
+素袖,女,6,
+霁眉,女,6,
+绸缪,女,6,
+静妍,女,6,
+安魄,男,7,
+靖川,男,7,
+霁阳,男,7,
+季衡,男,7,
+砺甲,男,7,
+烁锋,男,7,
+昊戈,男,7,
+祁光,男,7,
+漠石,男,7,
+启封,男,7,
+殷策,男,7,
+定魄,男,7,
+清宁,女,7,
+素铃,女,7,
+靖霜,女,7,
+澄心,女,7,
+霁雪,女,7,
+安祈,女,7,
+净月,女,7,
+宁枝,女,7,
+祷绫,女,7,
+明槐,女,7,
+采霁,女,7,
+定寒,女,7,
+噬影,男,8,
+无藏,男,8,
+绝响,男,8,
+断痕,男,8,
+影渊,男,8,
+暗行,男,8,
+潜踪,男,8,
+魄隐,男,8,
+迷雾,男,8,
+空蝉,男,8,
+断念,男,8,
+裂隙,男,8,
+影绫,女,8,
+暗萝,女,8,
+霜绡,女,8,
+素鹭,女,8,
+玄绮,女,8,
+凝灯,女,8,
+绫岚,女,8,
+凛铃,女,8,
+朔华,女,8,
+漠音,女,8,
+宵岑,女,8,
+泠歌,女,8,
+持衡,男,9,
+清评,男,9,
+问价,男,9,
+立契,男,9,
+通衡,男,9,
+问道,男,9,
+理市,男,9,
+衡准,男,9,
+守约,男,9,
+筑匠,男,9,
+铸衡,男,9,
+估算,男,9,
+素蓝,女,9,
+明衡,女,9,
+巧心,女,9,
+青帆,女,9,
+绫舟,女,9,
+观星,女,9,
+衡绫,女,9,
+星槎,女,9,
+织霓,女,9,
+采绫,女,9,
+芸巧,女,9,
+霁行,女,9,
+砚秋,女,9,
+镶玑,女,9,
+绘蓝,女,9,
+银梭,女,9,
+珩心,女,9,
+凌虚,男,1,
+剑尘,男,1,
+浩然,男,1,
+长风,男,1,
+问天,男,1,
+断岳,男,1,
+流云,男,1,
+守心,男,1,
+剑鸣,男,1,
+天锋,男,1,
+傲雪,男,1,
+寒松,男,1,
+抱朴,男,1,
+归真,男,1,
+绝云,男,1,
+破妄,男,1,
+承天,男,1,
+御空,男,1,
+凌绝,男,1,
+剑痴,男,1,
+独行,男,1,
+苍松,男,1,
+劲节,男,1,
+问剑,男,1,
+亦云,男,1,
+止水,男,1,
+寒锋,男,1,
+孤剑,男,1,
+凌霜,男,1,
+彻空,男,1,
+绝尘,男,1,
+一剑,男,1,
+洗墨,男,1,
+藏锋,男,1,
+折梅,男,1,
+负剑,男,1,
+听风,男,1,
+观海,男,1,
+问心,男,1,
+求道,男,1,
+寒梅,女,1,
+剑舞,女,1,
+清涟,女,1,
+云舒,女,1,
+听雨,女,1,
+若云,女,1,
+灵韵,女,1,
+问心,女,1,
+霜雪,女,1,
+傲梅,女,1,
+清心,女,1,
+凌波,女,1,
+芷若,女,1,
+怀柔,女,1,
+听剑,女,1,
+舞剑,女,1,
+凝剑,女,1,
+冰清,女,1,
+玉洁,女,1,
+晓月,女,1,
+寒霜,女,1,
+凌烟,女,1,
+梦剑,女,1,
+亦柔,女,1,
+芷兰,女,1,
+清微,女,1,
+寒香,女,1,
+剑兰,女,1,
+傲霜,女,1,
+凌月,女,1,
+拂雪,女,1,
+挽剑,女,1,
+青丝,女,1,
+若雪,女,1,
+含烟,女,1,
+如冰,女,1,
+傲竹,女,1,
+清影,女,1,
+绝尘,女,1,
+心剑,女,1,
+狂狮,男,2,
+龙牙,男,2,
+蛮牛,男,2,
+鹰眼,男,2,
+血狼,男,2,
+震山,男,2,
+铁臂,男,2,
+獠牙,男,2,
+虎啸,男,2,
+豹奔,男,2,
+熊力,男,2,
+猿啼,男,2,
+狼顾,男,2,
+鹰扬,男,2,
+狮吼,男,2,
+狂战,男,2,
+兽心,男,2,
+怒涛,男,2,
+裂地,男,2,
+碎岩,男,2,
+霸天,男,2,
+狂蟒,男,2,
+犀角,男,2,
+鳄牙,男,2,
+鹏飞,男,2,
+贪狼,男,2,
+破军,男,2,
+七杀,男,2,
+暴熊,男,2,
+毒牙,男,2,
+狂骨,男,2,
+荒咬,男,2,
+灵蛇,女,2,
+雀羽,女,2,
+鹿鸣,女,2,
+猫影,女,2,
+蜂刺,女,2,
+蝶衣,女,2,
+燕舞,女,2,
+狐灵,女,2,
+白鹭,女,2,
+青鸾,女,2,
+朱雀,女,2,
+银狐,女,2,
+灵猫,女,2,
+锦鲤,女,2,
+翠鸟,女,2,
+灵犀,女,2,
+幼鹿,女,2,
+飞燕,女,2,
+灵鹤,女,2,
+丹顶,女,2,
+锦翎,女,2,
+翠羽,女,2,
+斑斓,女,2,
+啸月,女,2,
+灵狐,女,2,
+媚猫,女,2,
+蛇舞,女,2,
+蛛儿,女,2,
+蝎娘,女,2,
+彩蝶,女,2,
+金蚕,女,2,
+玉蝉,女,2,
+灵贝,女,2,
+鲛珠,女,2,
+澜沧,男,3,
+镜明,男,3,
+寒潭,男,3,
+深蓝,男,3,
+听潮,男,3,
+无涯,男,3,
+冰封,男,3,
+流水,男,3,
+瀚海,男,3,
+渊默,男,3,
+沉渊,男,3,
+浮光,男,3,
+掠影,男,3,
+镜花,男,3,
+水月,男,3,
+寒江,男,3,
+孤帆,男,3,
+远影,男,3,
+碧波,男,3,
+涟漪,男,3,
+清流,男,3,
+激浪,男,3,
+惊涛,男,3,
+骇浪,男,3,
+冰棱,男,3,
+霜冻,男,3,
+雪飘,男,3,
+雾锁,男,3,
+云深,男,3,
+潜龙,男,3,
+深渊,男,3,
+海阔,男,3,
+天青,男,3,
+雨歇,男,3,
+潮生,男,3,
+汐落,男,3,
+冰河,男,3,
+雪峰,男,3,
+寒露,男,3,
+涟漪,女,3,
+水月,女,3,
+雾纱,女,3,
+冰洁,女,3,
+露珠,女,3,
+海悦,女,3,
+清溪,女,3,
+雨霏,女,3,
+浣纱,女,3,
+采莲,女,3,
+弄潮,女,3,
+踏浪,女,3,
+潜游,女,3,
+浮水,女,3,
+镜心,女,3,
+水灵,女,3,
+冰魄,女,3,
+雪魂,女,3,
+霜儿,女,3,
+露儿,女,3,
+雨儿,女,3,
+云儿,女,3,
+雾儿,女,3,
+烟儿,女,3,
+渺儿,女,3,
+淼儿,女,3,
+湘君,女,3,
+湘妃,女,3,
+洛神,女,3,
+宓妃,女,3,
+冰心,女,3,
+雪儿,女,3,
+海兰,女,3,
+江月,女,3,
+湖光,女,3,
+溪月,女,3,
+泉韵,女,3,
+雨荷,女,3,
+露华,女,3,
+霜月,女,3,
+枯骨,男,4,
+厉魂,男,4,
+血煞,男,4,
+无常,男,4,
+丧钟,男,4,
+墓碑,男,4,
+鬼火,男,4,
+修罗,男,4,
+阎罗,男,4,
+判官,男,4,
+勾魂,男,4,
+摄魄,男,4,
+阴阳,男,4,
+生死,男,4,
+轮回,男,4,
+奈何,男,4,
+忘川,男,4,
+黄泉,男,4,
+碧落,男,4,
+幽冥,男,4,
+罗刹,男,4,
+夜叉,男,4,
+魍魉,男,4,
+魑魅,男,4,
+饕餮,男,4,
+灰烬,男,4,
+残魂,男,4,
+断魄,男,4,
+绝命,男,4,
+追魂,男,4,
+索命,男,4,
+无赦,男,4,
+天罚,男,4,
+地藏,男,4,
+幽兰,女,4,
+鬼姬,女,4,
+彼岸,女,4,
+忘川,女,4,
+孟婆,女,4,
+阴灵,女,4,
+骨香,女,4,
+血蔷,女,4,
+艳鬼,女,4,
+倩女,女,4,
+幽魂,女,4,
+离魂,女,4,
+索命,女,4,
+追魂,女,4,
+夺魄,女,4,
+迷魂,女,4,
+阴后,女,4,
+鬼母,女,4,
+骨女,女,4,
+阴风,女,4,
+愁云,女,4,
+冥烛,女,4,
+灵幡,女,4,
+魂铃,女,4,
+尸香,女,4,
+血魅,女,4,
+骨姬,女,4,
+阴月,女,4,
+鬼魅,女,4,
+绝弦,男,5,
+影杀,男,5,
+天机,男,5,
+鬼手,男,5,
+连环,男,5,
+破甲,男,5,
+透骨,男,5,
+索命,男,5,
+无影,男,5,
+追风,男,5,
+夺命,男,5,
+穿心,男,5,
+封喉,男,5,
+见血,男,5,
+必杀,男,5,
+绝杀,男,5,
+瞬杀,男,5,
+偃师,男,5,
+神机,男,5,
+妙算,男,5,
+鬼谷,男,5,
+千机,男,5,
+百炼,男,5,
+神工,男,5,
+天工,男,5,
+巧夺,男,5,
+夺天,男,5,
+造化,男,5,
+钉魂,男,5,
+裂石,男,5,
+穿云,男,5,
+破风,男,5,
+惊雷,男,5,
+霹雳,男,5,
+雷火,男,5,
+暗雷,男,5,
+伏击,男,5,
+毒刺,女,5,
+隐娘,女,5,
+罗网,女,5,
+千机,女,5,
+袖箭,女,5,
+丝雨,女,5,
+暗香,女,5,
+诡丝,女,5,
+毒牙,女,5,
+蛇蝎,女,5,
+罂粟,女,5,
+曼陀,女,5,
+见血,女,5,
+含沙,女,5,
+射影,女,5,
+梨花,女,5,
+散花,女,5,
+飞针,女,5,
+织萝,女,5,
+蛛网,女,5,
+缠绵,女,5,
+缚灵,女,5,
+困兽,女,5,
+锁心,女,5,
+封印,女,5,
+无影,女,5,
+无踪,女,5,
+无声,女,5,
+无息,女,5,
+夺魂,女,5,
+摄魄,女,5,
+迷香,女,5,
+软筋,女,5,
+断肠,女,5,
+绝情,女,5,
+惜花,男,6,
+醉月,男,6,
+多情,男,6,
+寻芳,男,6,
+风流,男,6,
+玉郎,男,6,
+春生,男,6,
+梦回,男,6,
+痴情,男,6,
+绝情,男,6,
+留情,男,6,
+钟情,男,6,
+朝露,男,6,
+晚霞,男,6,
+彩云,男,6,
+追月,男,6,
+摘星,男,6,
+弄玉,男,6,
+吹箫,男,6,
+抚琴,男,6,
+听曲,男,6,
+赏舞,男,6,
+品茗,男,6,
+怜香,男,6,
+惜玉,男,6,
+护花,男,6,
+风月,男,6,
+逍遥,男,6,
+媚儿,女,6,
+倾国,女,6,
+含羞,女,6,
+醉颜,女,6,
+红豆,女,6,
+相思,女,6,
+花魁,女,6,
+怜月,女,6,
+羞花,女,6,
+闭月,女,6,
+沉鱼,女,6,
+落雁,女,6,
+绝色,女,6,
+天香,女,6,
+国色,女,6,
+妖娆,女,6,
+妩媚,女,6,
+动人,女,6,
+春心,女,6,
+芳心,女,6,
+痴心,女,6,
+冰心,女,6,
+如幻,女,6,
+如诗,女,6,
+如画,女,6,
+佳人,女,6,
+红颜,女,6,
+绝代,女,6,
+风华,女,6,
+镇山,男,7,
+伏魔,男,7,
+铁壁,男,7,
+金刚,男,7,
+定海,男,7,
+卫道,男,7,
+正阳,男,7,
+不坏,男,7,
+磐石,男,7,
+泰山,男,7,
+不动,男,7,
+如山,男,7,
+巍峨,男,7,
+雄伟,男,7,
+壮观,男,7,
+肃穆,男,7,
+庄严,男,7,
+威武,男,7,
+凛然,男,7,
+浩大,男,7,
+宏大,男,7,
+宽广,男,7,
+博大,男,7,
+精深,男,7,
+厚德,男,7,
+载物,男,7,
+坤元,男,7,
+乾元,男,7,
+护法,男,7,
+伽蓝,男,7,
+韦驮,男,7,
+天王,男,7,
+力士,男,7,
+罗汉,男,7,
+尊者,男,7,
+行者,男,7,
+觉者,男,7,
+智者,男,7,
+守灵,女,7,
+安魂,女,7,
+净世,女,7,
+慈航,女,7,
+宝相,女,7,
+金铃,女,7,
+定心,女,7,
+圣洁,女,7,
+梵音,女,7,
+禅心,女,7,
+净土,女,7,
+莲花,女,7,
+菩提,女,7,
+般若,女,7,
+智慧,女,7,
+圆满,女,7,
+妙法,女,7,
+真如,女,7,
+法性,女,7,
+佛性,女,7,
+觉悟,女,7,
+涅槃,女,7,
+寂灭,女,7,
+无为,女,7,
+虚影,男,8,
+吞天,男,8,
+绝影,男,8,
+无声,男,8,
+夜行,男,8,
+莫测,男,8,
+幻灭,男,8,
+空无,男,8,
+虚空,男,8,
+无极,男,8,
+暗夜,男,8,
+潜行,男,8,
+伏击,男,8,
+瞬移,男,8,
+影遁,男,8,
+鬼步,男,8,
+魔踪,男,8,
+邪影,男,8,
+冥空,男,8,
+无妄,男,8,
+无相,男,8,
+魅影,女,8,
+夜魅,女,8,
+无形,女,8,
+幻音,女,8,
+幽梦,女,8,
+影舞,女,8,
+黑纱,女,8,
+虚灵,女,8,
+梦魇,女,8,
+梦魔,女,8,
+梦幻,女,8,
+泡影,女,8,
+镜花,女,8,
+海市,女,8,
+蜃楼,女,8,
+空花,女,8,
+迷离,女,8,
+恍惚,女,8,
+幽暗,女,8,
+晦涩,女,8,
+朦胧,女,8,
+隐约,女,8,
+飘渺,女,8,
+迷踪,女,8,
+幻影,女,8,
+宝通,男,9,
+远航,男,9,
+达观,男,9,
+通达,男,9,
+宏图,男,9,
+伟业,男,9,
+汇通,男,9,
+天下,男,9,
+金山,男,9,
+银海,男,9,
+聚宝,男,9,
+珠儿,女,9,
+玉润,女,9,
+锦绣,女,9,
+宝珠,女,9,
+盈盈,女,9,
+瑞彩,女,9,
+金玉,女,9,
+琳琅,女,9,
+玛瑙,女,9,
+翡翠,女,9,
+琉璃,女,9,
+琥珀,女,9,
+珊瑚,女,9,
+玳瑁,女,9,
+珍珠,女,9,
+宝石,女,9,
+钻石,女,9,
+水晶,女,9,
+黄金,女,9,
+白银,女,9,
+丰盈,女,9,
+彩霞,女,9,
+云锦,女,9,
+天孙,女,9,
+织女,女,9,
+巧手,女,9,
+金枝,女,9,
+玉叶,女,9,
+闺秀,女,9,
+风范,女,9,
天,男,,
玄,男,,
道,男,,
@@ -1115,4 +1115,4 @@ given_name,gender,sect,cond
娴,女,,
淑,女,,
惠,女,,
-珍,女,,
\ No newline at end of file
+珍,女,,
diff --git a/static/game_configs/technique.csv b/static/game_configs/technique.csv
index 79f248b..a36194a 100644
--- a/static/game_configs/technique.csv
+++ b/static/game_configs/technique.csv
@@ -1,5 +1,5 @@
-id,name,technique_root,grade,desc,weight,condition,sect,effects
-,名称,属性,品阶(上中下),描述/提示词,抽样权重,条件,所属宗门,JSON形式(支持宽松格式,见effects.py说明)
+id,name,technique_root,grade,desc,weight,condition,sect_id,effects
+,名称,属性,品阶(上中下),描述/提示词,抽样权重,条件,宗门ID(空=散修),JSON形式(支持宽松格式,见effects.py说明)
1,金刚不坏体,金,下品,少林七十二绝技之一,浑身坚若金刚,刀枪不入。,1,,,
2,金钟罩,金,中品,运气成钟,护持周身,反震外力。,1,,,"{""extra_battle_strength_points"": 3}"
4,长春功,木,下品,养生延年,气息绵长,凡人修仙的基础功法。,1,,,
@@ -20,30 +20,30 @@ id,name,technique_root,grade,desc,weight,condition,sect,effects
26,五雷正法,雷,中品,役使五行之雷,刚猛霸道,无坚不摧。,1,,,"{""extra_battle_strength_points"": 3}"
28,燃血大法,邪,下品,燃烧精血,短暂爆发实力,事后虚弱。,1,,,"{extra_breakthrough_success_rate: -0.1, extra_cultivate_exp: 50, extra_battle_strength_points: 2}"
29,吸星大法,邪,中品,吸取他人内力为己用,霸道异常,常有反噬。,1,,,"{""extra_breakthrough_success_rate"": -0.1, ""extra_cultivate_exp"": 50, ""extra_battle_strength_points"": 3}"
-30,草字剑诀,金,上品,一株草斩尽日月星辰,完美世界三大剑诀之一。,10,,明心剑宗,"{""extra_battle_strength_points"": 6}"
-31,神剑御雷真诀,雷,上品,九天玄刹,化为神雷。煌煌天威,以剑引之。,10,,明心剑宗,"{""extra_battle_strength_points"": 6}"
-32,大河剑意,火,上品,君不见黄河之水天上来,奔流到海不复回。,10,,明心剑宗,"{""extra_battle_strength_points"": 6}"
-33,青帝长生诀,木,上品,青帝所创,木系至高功法,生生不息,枯木逢春。,10,,百兽宗,"{""extra_battle_strength_points"": 5, ""extra_refine_success_rate"": 0.1}"
-34,神象镇狱劲,土,上品,以气引神,以神成象,举手投足,镇压地狱。,10,,百兽宗,"{""extra_battle_strength_points"": 6}"
-35,鲲鹏宝术,邪,上品,入海为鲲,扶摇为鹏。阴阳变化,极速与吞噬。,10,,百兽宗,"{""extra_breakthrough_success_rate"": -0.1, ""extra_cultivate_exp"": 50, ""extra_battle_strength_points"": 6, ""extra_move_step"": 1}"
-36,虚空经,水,上品,以无限虚空证道,掌控空间,先天立于不败。,10,,水镜宗,"{""extra_battle_strength_points"": 6}"
-37,太上忘情录,冰,上品,太上忘情,非无情,乃忘情。至公至正,威力无穷。,10,,水镜宗,"{""extra_battle_strength_points"": 6}"
-38,逍遥游,风,上品,乘天地之正,而御六气之辩,以游无穷。,10,,水镜宗,"{""extra_battle_strength_points"": 6, ""extra_move_step"": 1}"
-39,吞天魔功,暗,上品,狠人大帝所创,吞噬万千体质,铸就混沌体。,10,,冥王宗,"{""extra_battle_strength_points"": 6}"
-40,天魔策,邪,上品,魔门至高宝典,包罗万象,直指破碎虚空。,10,,冥王宗,"{""extra_breakthrough_success_rate"": -0.1, ""extra_cultivate_exp"": 50, ""extra_battle_strength_points"": 6}"
-41,冥河真经,冰,上品,血海不枯,冥河不死。演化四亿八千万血神子。,10,,冥王宗,"{""extra_battle_strength_points"": 6}"
-42,焚诀,火,上品,通过吞噬异火进化功法,潜力无限,号令万火。,10,,朱勾宗,"{""extra_battle_strength_points"": 6, ""extra_cast_success_rate"": 0.1, ""extra_refine_success_rate"": 0.1}"
-43,道心种魔大法,暗,上品,以他人为炉鼎,种魔种,夺天地造化。,10,,朱勾宗,"{""extra_battle_strength_points"": 6}"
-44,大衍决,金,上品,专修神识,能分心多用,操控万千傀儡。,10,,朱勾宗,"{""extra_battle_strength_points"": 6}"
-45,大乐赋,水,上品,阴阳大道,极乐飞升。双修之至高法门。,10,,合欢宗,"{""extra_battle_strength_points"": 6}"
-46,天魔舞,暗,上品,域外天魔之舞,勾魂摄魄,乱人心智。,10,,合欢宗,"{""extra_battle_strength_points"": 6}"
-47,凌波微步,风,上品,体迅飞凫,飘忽若神,罗袜生尘。,10,,合欢宗,"{""extra_battle_strength_points"": 6, ""extra_escape_success_rate"": 0.2}"
-48,过去弥陀经,土,上品,神魂不灭,超脱彼岸。修成过去二竖,万劫不磨。,10,,镇魂宗,"{""extra_battle_strength_points"": 6}"
-49,神霄雷法,雷,上品,道家雷法正宗,役使神霄天雷,诛邪灭魔。,10,,镇魂宗,"{""extra_battle_strength_points"": 6}"
-50,九字真言,金,上品,临兵斗者皆阵列前行。道家无上咒法。,10,,镇魂宗,"{""extra_battle_strength_points"": 6}"
-51,幽冥鬼爪,暗,上品,阴损毒辣,专破内家真气,触之即死。,10,,幽魂噬影宗,"{""extra_battle_strength_points"": 6}"
-52,三千雷动,风,上品,身化雷霆,瞬息千里,残影重重。,10,,幽魂噬影宗,"{""extra_battle_strength_points"": 6}"
-53,血神经,邪,上品,人皮为纸,鲜血为墨。修炼者必先剥皮噬血。,10,,幽魂噬影宗,"{""extra_breakthrough_success_rate"": -0.1, ""extra_cultivate_exp"": 50, ""extra_battle_strength_points"": 6}"
-54,神机百炼,金,上品,炼器极致,化腐朽为神奇,万物皆可为兵。,10,,千帆城,"{""extra_battle_strength_points"": 4, ""extra_cast_success_rate"": 0.2}"
-55,周天星斗大阵,土,上品,引周天星力,演化宇宙洪荒,攻防一体。,10,,千帆城,"{""extra_battle_strength_points"": 6}"
-56,纵地金光,风,上品,阐教绝学,化作一道金光,瞬息万里。,10,,千帆城,"{""extra_battle_strength_points"": 6, ""extra_move_step"": 2}"
+30,草字剑诀,金,上品,一株草斩尽日月星辰,完美世界三大剑诀之一。,10,,1,"{""extra_battle_strength_points"": 6}"
+31,神剑御雷真诀,雷,上品,九天玄刹,化为神雷。煌煌天威,以剑引之。,10,,1,"{""extra_battle_strength_points"": 6}"
+32,大河剑意,火,上品,君不见黄河之水天上来,奔流到海不复回。,10,,1,"{""extra_battle_strength_points"": 6}"
+33,青帝长生诀,木,上品,青帝所创,木系至高功法,生生不息,枯木逢春。,10,,2,"{""extra_battle_strength_points"": 5, ""extra_refine_success_rate"": 0.1}"
+34,神象镇狱劲,土,上品,以气引神,以神成象,举手投足,镇压地狱。,10,,2,"{""extra_battle_strength_points"": 6}"
+35,鲲鹏宝术,邪,上品,入海为鲲,扶摇为鹏。阴阳变化,极速与吞噬。,10,,2,"{""extra_breakthrough_success_rate"": -0.1, ""extra_cultivate_exp"": 50, ""extra_battle_strength_points"": 6, ""extra_move_step"": 1}"
+36,虚空经,水,上品,以无限虚空证道,掌控空间,先天立于不败。,10,,3,"{""extra_battle_strength_points"": 6}"
+37,太上忘情录,冰,上品,太上忘情,非无情,乃忘情。至公至正,威力无穷。,10,,3,"{""extra_battle_strength_points"": 6}"
+38,逍遥游,风,上品,乘天地之正,而御六气之辩,以游无穷。,10,,3,"{""extra_battle_strength_points"": 6, ""extra_move_step"": 1}"
+39,吞天魔功,暗,上品,狠人大帝所创,吞噬万千体质,铸就混沌体。,10,,4,"{""extra_battle_strength_points"": 6}"
+40,天魔策,邪,上品,魔门至高宝典,包罗万象,直指破碎虚空。,10,,4,"{""extra_breakthrough_success_rate"": -0.1, ""extra_cultivate_exp"": 50, ""extra_battle_strength_points"": 6}"
+41,冥河真经,冰,上品,血海不枯,冥河不死。演化四亿八千万血神子。,10,,4,"{""extra_battle_strength_points"": 6}"
+42,焚诀,火,上品,通过吞噬异火进化功法,潜力无限,号令万火。,10,,5,"{""extra_battle_strength_points"": 6, ""extra_cast_success_rate"": 0.1, ""extra_refine_success_rate"": 0.1}"
+43,道心种魔大法,暗,上品,以他人为炉鼎,种魔种,夺天地造化。,10,,5,"{""extra_battle_strength_points"": 6}"
+44,大衍决,金,上品,专修神识,能分心多用,操控万千傀儡。,10,,5,"{""extra_battle_strength_points"": 6}"
+45,大乐赋,水,上品,阴阳大道,极乐飞升。双修之至高法门。,10,,6,"{""extra_battle_strength_points"": 6}"
+46,天魔舞,暗,上品,域外天魔之舞,勾魂摄魄,乱人心智。,10,,6,"{""extra_battle_strength_points"": 6}"
+47,凌波微步,风,上品,体迅飞凫,飘忽若神,罗袜生尘。,10,,6,"{""extra_battle_strength_points"": 6, ""extra_escape_success_rate"": 0.2}"
+48,过去弥陀经,土,上品,神魂不灭,超脱彼岸。修成过去二竖,万劫不磨。,10,,7,"{""extra_battle_strength_points"": 6}"
+49,神霄雷法,雷,上品,道家雷法正宗,役使神霄天雷,诛邪灭魔。,10,,7,"{""extra_battle_strength_points"": 6}"
+50,九字真言,金,上品,临兵斗者皆阵列前行。道家无上咒法。,10,,7,"{""extra_battle_strength_points"": 6}"
+51,幽冥鬼爪,暗,上品,阴损毒辣,专破内家真气,触之即死。,10,,8,"{""extra_battle_strength_points"": 6}"
+52,三千雷动,风,上品,身化雷霆,瞬息千里,残影重重。,10,,8,"{""extra_battle_strength_points"": 6}"
+53,血神经,邪,上品,人皮为纸,鲜血为墨。修炼者必先剥皮噬血。,10,,8,"{""extra_breakthrough_success_rate"": -0.1, ""extra_cultivate_exp"": 50, ""extra_battle_strength_points"": 6}"
+54,神机百炼,金,上品,炼器极致,化腐朽为神奇,万物皆可为兵。,10,,9,"{""extra_battle_strength_points"": 4, ""extra_cast_success_rate"": 0.2}"
+55,周天星斗大阵,土,上品,引周天星力,演化宇宙洪荒,攻防一体。,10,,9,"{""extra_battle_strength_points"": 6}"
+56,纵地金光,风,上品,阐教绝学,化作一道金光,瞬息万里。,10,,9,"{""extra_battle_strength_points"": 6, ""extra_move_step"": 2}"
diff --git a/static/game_configs/tile_map.csv b/static/game_configs/tile_map.csv
index 2d06818..8547412 100644
--- a/static/game_configs/tile_map.csv
+++ b/static/game_configs/tile_map.csv
@@ -4,47 +4,47 @@ desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,des
desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,snow_mountain,snow_mountain,snow_mountain,snow_mountain,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,tundra,tundra,tundra,tundra,tundra,tundra,tundra,tundra,tundra,volcano,volcano,volcano,volcano,volcano,volcano,volcano,volcano,plain,plain,plain,plain,water,water,plain,plain,plain,plain,plain,plain
desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,tundra,tundra,tundra,tundra,tundra,tundra,tundra,tundra,tundra,tundra,volcano,volcano,volcano,volcano,volcano,volcano,volcano,volcano,volcano,volcano,plain,plain,plain,water,water,water,plain,plain,plain,plain,plain
desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,snow_mountain,snow_mountain,snow_mountain,snow_mountain,plain,plain,plain,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,tundra,tundra,tundra,tundra,tundra,tundra,tundra,tundra,tundra,tundra,tundra,tundra,volcano,volcano,volcano,volcano,volcano,volcano,volcano,volcano,volcano,volcano,plain,plain,plain,plain,water,water,plain,plain,plain,plain,plain
-desert,desert,desert,desert,desert,desert,desert,desert,desert,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,plain,不夜城_0,不夜城_1,glacier,plain,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,tundra,tundra,tundra,tundra,tundra,tundra,water,tundra,tundra,plain,mountain,mountain,tundra,tundra,tundra,volcano,volcano,volcano,volcano,volcano,volcano,volcano,volcano,volcano,volcano,plain,plain,plain,plain,water,water,water,plain,plain,plain,plain
-desert,desert,desert,desert,desert,desert,desert,desert,desert,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,不夜城_2,不夜城_3,plain,plain,glacier,plain,plain,plain,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,plain,tundra,tundra,plain,plain,water,water,water,tundra,plain,mountain,mountain,mountain,plain,tundra,tundra,volcano,volcano,volcano,volcano,volcano,volcano,volcano,volcano,volcano,plain,plain,plain,plain,plain,plain,water,sea,plain,plain,plain,plain
-desert,desert,desert,desert,desert,desert,desert,desert,snow_mountain,snow_mountain,揽月城_0,揽月城_1,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,plain,plain,plain,plain,plain,plain,plain,plain,glacier,glacier,glacier,glacier,妙化宗_0,妙化宗_1,plain,plain,plain,plain,water,water,plain,plain,mountain,mountain,mountain,mountain,mountain,天行健宗_0,天行健宗_1,plain,plain,plain,volcano,volcano,volcano,volcano,volcano,volcano,plain,plain,冥王宗_0,冥王宗_1,plain,plain,sea,sea,sea,镇魂宗_0,镇魂宗_1,sea,sea
-desert,desert,desert,desert,desert,desert,desert,desert,snow_mountain,snow_mountain,揽月城_2,揽月城_3,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,妙化宗_2,妙化宗_3,plain,plain,plain,water,water,plain,plain,plain,mountain,mountain,mountain,mountain,mountain,天行健宗_2,天行健宗_3,plain,plain,plain,water,water,volcano,volcano,volcano,plain,plain,plain,冥王宗_2,冥王宗_3,plain,sea,sea,sea,sea,镇魂宗_2,镇魂宗_3,sea,sea
+desert,desert,desert,desert,desert,desert,desert,desert,desert,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,plain,sect_12_0,sect_12_1,glacier,plain,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,tundra,tundra,tundra,tundra,tundra,tundra,water,tundra,tundra,plain,mountain,mountain,tundra,tundra,tundra,volcano,volcano,volcano,volcano,volcano,volcano,volcano,volcano,volcano,volcano,plain,plain,plain,plain,water,water,water,plain,plain,plain,plain
+desert,desert,desert,desert,desert,desert,desert,desert,desert,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,sect_12_2,sect_12_3,plain,plain,glacier,plain,plain,plain,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,glacier,plain,tundra,tundra,plain,plain,water,water,water,tundra,plain,mountain,mountain,mountain,plain,tundra,tundra,volcano,volcano,volcano,volcano,volcano,volcano,volcano,volcano,volcano,plain,plain,plain,plain,plain,plain,water,sea,plain,plain,plain,plain
+desert,desert,desert,desert,desert,desert,desert,desert,snow_mountain,snow_mountain,city_305_0,city_305_1,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,plain,plain,plain,plain,plain,plain,plain,plain,glacier,glacier,glacier,glacier,sect_10_0,sect_10_1,plain,plain,plain,plain,water,water,plain,plain,mountain,mountain,mountain,mountain,mountain,sect_13_0,sect_13_1,plain,plain,plain,volcano,volcano,volcano,volcano,volcano,volcano,plain,plain,sect_4_0,sect_4_1,plain,plain,sea,sea,sea,sect_7_0,sect_7_1,sea,sea
+desert,desert,desert,desert,desert,desert,desert,desert,snow_mountain,snow_mountain,city_305_2,city_305_3,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,sect_10_2,sect_10_3,plain,plain,plain,water,water,plain,plain,plain,mountain,mountain,mountain,mountain,mountain,sect_13_2,sect_13_3,plain,plain,plain,water,water,volcano,volcano,volcano,plain,plain,plain,sect_4_2,sect_4_3,plain,sea,sea,sea,sea,sect_7_2,sect_7_3,sea,sea
desert,desert,desert,desert,desert,desert,desert,gobi,gobi,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,plain,plain,plain,plain,plain,plain,plain,plain,plain,water,water,water,water,plain,plain,plain,plain,plain,mountain,mountain,mountain,mountain,mountain,plain,plain,plain,plain,plain,water,water,water,plain,plain,water,water,water,water,sea,sea,sea,sea,sea,sea,sea,sea,sea
desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,plain,plain,plain,plain,plain,plain,plain,plain,water,water,water,plain,bamboo,bamboo,bamboo,bamboo,bamboo,plain,plain,mountain,mountain,mountain,mountain,mountain,plain,plain,plain,plain,plain,plain,water,water,water,water,water,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,plain,plain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,snow_mountain,water,water,water,water,water,water,water,water,plain,water,water,plain,plain,plain,bamboo,bamboo,bamboo,bamboo,bamboo,bamboo,plain,mountain,mountain,mountain,mountain,mountain,mountain,plain,plain,plain,plain,plain,plain,plain,plain,water,water,water,sea,island,sea,sea,sea,sea,sea,sea,sea,sea,sea
desert,desert,desert,desert,desert,desert,desert,gobi,gobi,desert,gobi,gobi,gobi,plain,plain,plain,plain,plain,snow_mountain,snow_mountain,plain,water,water,water,water,water,water,water,water,water,water,plain,plain,plain,plain,bamboo,bamboo,bamboo,bamboo,bamboo,bamboo,plain,mountain,mountain,mountain,mountain,mountain,mountain,plain,plain,farm,farm,farm,farm,farm,farm,farm,water,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
desert,desert,desert,desert,desert,desert,desert,gobi,desert,desert,gobi,gobi,gobi,gobi,plain,plain,cave_0,cave_1,plain,plain,grassland,grassland,grassland,grassland,grassland,grassland,plain,plain,water,water,water,plain,plain,plain,plain,bamboo,bamboo,bamboo,bamboo,bamboo,plain,plain,plain,mountain,mountain,mountain,mountain,mountain,plain,plain,farm,farm,farm,farm,farm,farm,farm,water,water,sea,sea,sea,sea,sea,sea,sea,sea,island,sea,sea
-desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,plain,cave_2,cave_3,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,water,water,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,朱勾宗_0,朱勾宗_1,mountain,mountain,mountain,mountain,mountain,mountain,plain,farm,farm,farm,farm,farm,farm,farm,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,island,island,sea
-desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,plain,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,water,water,water,forest,forest,plain,plain,plain,plain,plain,plain,plain,朱勾宗_2,朱勾宗_3,mountain,mountain,mountain,mountain,mountain,mountain,plain,farm,farm,farm,farm,farm,farm,farm,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,water,water,water,forest,forest,forest,plain,青云城_0,青云城_1,plain,plain,plain,plain,plain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,farm,farm,farm,farm,farm,farm,farm,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,water,water,forest,forest,forest,forest,青云城_2,青云城_3,plain,plain,plain,plain,plain,mountain,mountain,mountain,plain,mountain,mountain,mountain,farm,farm,farm,farm,farm,farm,farm,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,plain,cave_2,cave_3,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,water,water,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,sect_5_0,sect_5_1,mountain,mountain,mountain,mountain,mountain,mountain,plain,farm,farm,farm,farm,farm,farm,farm,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,island,island,sea
+desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,plain,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,water,water,water,forest,forest,plain,plain,plain,plain,plain,plain,plain,sect_5_2,sect_5_3,mountain,mountain,mountain,mountain,mountain,mountain,plain,farm,farm,farm,farm,farm,farm,farm,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,water,water,water,forest,forest,forest,plain,city_301_0,city_301_1,plain,plain,plain,plain,plain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,farm,farm,farm,farm,farm,farm,farm,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,water,water,forest,forest,forest,forest,city_301_2,city_301_3,plain,plain,plain,plain,plain,mountain,mountain,mountain,plain,mountain,mountain,mountain,farm,farm,farm,farm,farm,farm,farm,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,water,water,forest,forest,forest,forest,forest,forest,plain,plain,plain,plain,plain,mountain,mountain,mountain,mountain,plain,mountain,mountain,mountain,plain,plain,plain,plain,plain,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,plain,water,forest,forest,forest,forest,forest,forest,forest,plain,plain,cave_0,cave_1,plain,mountain,mountain,mountain,plain,plain,mountain,mountain,plain,plain,plain,plain,plain,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,plain,plain,water,water,forest,forest,forest,forest,forest,forest,forest,forest,cave_2,cave_3,plain,mountain,mountain,mountain,mountain,plain,plain,mountain,mountain,plain,plain,plain,plain,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,噬魔宗_0,噬魔宗_1,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,幽魂噬影宗_0,幽魂噬影宗_1,water,water,forest,forest,forest,forest,forest,forest,forest,forest,forest,forest,plain,plain,mountain,mountain,mountain,mountain,plain,plain,mountain,mountain,plain,plain,plain,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,噬魔宗_2,噬魔宗_3,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,幽魂噬影宗_2,幽魂噬影宗_3,plain,water,water,forest,forest,forest,forest,forest,forest,forest,forest,forest,forest,forest,mountain,mountain,mountain,mountain,mountain,plain,plain,plain,plain,plain,plain,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,plain,plain,water,water,water,forest,forest,forest,forest,forest,forest,forest,forest,forest,forest,plain,mountain,mountain,mountain,mountain,mountain,plain,plain,plain,明心剑宗_0,明心剑宗_1,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,plain,plain,water,water,water,plain,forest,forest,forest,forest,forest,forest,forest,forest,forest,plain,plain,mountain,mountain,mountain,mountain,plain,plain,明心剑宗_2,明心剑宗_3,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,plain,plain,water,water,water,plain,plain,翠林城_0,翠林城_1,forest,forest,forest,forest,forest,forest,forest,plain,plain,mountain,mountain,mountain,plain,plain,plain,sea,sea,sea,sea,ruin_0,ruin_1,sea,sea,sea,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,plain,plain,water,water,water,water,翠林城_2,翠林城_3,forest,forest,forest,forest,forest,forest,plain,plain,plain,plain,mountain,mountain,plain,plain,plain,sea,sea,sea,sea,ruin_2,ruin_3,sea,sea,sea,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,sect_14_0,sect_14_1,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,sect_8_0,sect_8_1,water,water,forest,forest,forest,forest,forest,forest,forest,forest,forest,forest,plain,plain,mountain,mountain,mountain,mountain,plain,plain,mountain,mountain,plain,plain,plain,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,sect_14_2,sect_14_3,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,sect_8_2,sect_8_3,plain,water,water,forest,forest,forest,forest,forest,forest,forest,forest,forest,forest,forest,mountain,mountain,mountain,mountain,mountain,plain,plain,plain,plain,plain,plain,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,plain,plain,water,water,water,forest,forest,forest,forest,forest,forest,forest,forest,forest,forest,plain,mountain,mountain,mountain,mountain,mountain,plain,plain,plain,sect_1_0,sect_1_1,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,plain,plain,water,water,water,plain,forest,forest,forest,forest,forest,forest,forest,forest,forest,plain,plain,mountain,mountain,mountain,mountain,plain,plain,sect_1_2,sect_1_3,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,plain,plain,water,water,water,plain,plain,city_303_0,city_303_1,forest,forest,forest,forest,forest,forest,forest,plain,plain,mountain,mountain,mountain,plain,plain,plain,sea,sea,sea,sea,ruin_0,ruin_1,sea,sea,sea,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,plain,plain,water,water,water,water,city_303_2,city_303_3,forest,forest,forest,forest,forest,forest,plain,plain,plain,plain,mountain,mountain,plain,plain,plain,sea,sea,sea,sea,ruin_2,ruin_3,sea,sea,sea,sea,sea,sea,sea,sea
desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,plain,plain,plain,water,water,water,water,water,plain,plain,plain,plain,forest,forest,plain,cave_0,cave_1,plain,plain,mountain,mountain,plain,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,island,sea,sea
desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,plain,plain,plain,water,water,water,water,water,water,water,water,plain,plain,plain,cave_2,cave_3,plain,plain,plain,mountain,mountain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,grassland,grassland,grassland,grassland,grassland,grassland,grassland,grassland,plain,plain,plain,plain,plain,plain,water,water,water,water,water,water,water,water,water,water,water,water,water,water,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,沙月城_0,沙月城_1,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,plain,grassland,grassland,grassland,grassland,grassland,grassland,plain,plain,plain,plain,plain,plain,水镜宗_0,水镜宗_1,plain,plain,water,water,water,water,water,water,water,water,water,water,water,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,沙月城_2,沙月城_3,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,plain,plain,plain,grassland,plain,grassland,grassland,grassland,plain,plain,plain,plain,plain,水镜宗_2,水镜宗_3,plain,plain,plain,plain,water,water,water,water,water,water,water,water,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,plain,plain,plain,plain,plain,plain,plain,plain,grassland,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,water,water,water,water,water,water,沧澜城_0,沧澜城_1,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,water,water,water,water,water,沧澜城_2,沧澜城_3,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,plain,plain,plain,回玄宗_0,回玄宗_1,plain,plain,plain,mountain,mountain,mountain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,water,water,water,water,water,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,plain,plain,回玄宗_2,回玄宗_3,plain,mountain,mountain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,water,water,water,water,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,island,island,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,rainforest,rainforest,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,plain,plain,mountain,mountain,mountain,mountain,mountain,plain,mountain,mountain,mountain,plain,plain,plain,plain,plain,mountain,mountain,plain,plain,plain,plain,plain,plain,plain,千帆城_0,千帆城_1,plain,water,water,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,island,island,island,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,desert,desert,rainforest,rainforest,rainforest,rainforest,gobi,gobi,gobi,gobi,gobi,gobi,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,plain,mountain,plain,mountain,mountain,mountain,mountain,plain,plain,plain,plain,plain,千帆城_2,千帆城_3,plain,plain,water,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,island,island,island,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,city_302_0,city_302_1,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,plain,grassland,grassland,grassland,grassland,grassland,grassland,plain,plain,plain,plain,plain,plain,sect_3_0,sect_3_1,plain,plain,water,water,water,water,water,water,water,water,water,water,water,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,city_302_2,city_302_3,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,plain,plain,plain,grassland,plain,grassland,grassland,grassland,plain,plain,plain,plain,plain,sect_3_2,sect_3_3,plain,plain,plain,plain,water,water,water,water,water,water,water,water,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,plain,plain,plain,plain,plain,plain,plain,plain,grassland,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,water,water,water,water,water,water,city_304_0,city_304_1,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,water,water,water,water,water,city_304_2,city_304_3,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,plain,plain,plain,sect_11_0,sect_11_1,plain,plain,plain,mountain,mountain,mountain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,water,water,water,water,water,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,plain,plain,sect_11_2,sect_11_3,plain,mountain,mountain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,plain,water,water,water,water,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,island,island,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,desert,desert,desert,rainforest,rainforest,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,gobi,plain,plain,mountain,mountain,mountain,mountain,mountain,plain,mountain,mountain,mountain,plain,plain,plain,plain,plain,mountain,mountain,plain,plain,plain,plain,plain,plain,plain,sect_9_0,sect_9_1,plain,water,water,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,island,island,island,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,desert,desert,rainforest,rainforest,rainforest,rainforest,gobi,gobi,gobi,gobi,gobi,gobi,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,plain,mountain,plain,mountain,mountain,mountain,mountain,plain,plain,plain,plain,plain,sect_9_2,sect_9_3,plain,plain,water,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,island,island,island,sea,sea,sea,sea,sea
desert,desert,desert,desert,desert,desert,desert,desert,desert,rainforest,rainforest,rainforest,rainforest,rainforest,gobi,gobi,gobi,gobi,plain,plain,plain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,plain,plain,plain,water,sea,sea,sea,sea,sea,sea,sea,sea,sea,island,island,island,island,sea,sea,sea,sea
desert,desert,desert,desert,desert,desert,desert,desert,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,gobi,gobi,plain,plain,plain,plain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,plain,plain,plain,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,island,island,island,sea,sea,sea,sea,sea
desert,desert,desert,desert,desert,desert,desert,desert,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,plain,plain,plain,plain,plain,plain,plain,plain,mountain,plain,mountain,mountain,mountain,plain,plain,plain,swamp,plain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,mountain,plain,plain,plain,plain,plain,plain,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,百兽宗_0,百兽宗_1,rainforest,rainforest,rainforest,plain,rainforest,plain,plain,plain,plain,plain,plain,plain,plain,swamp,swamp,swamp,swamp,swamp,plain,plain,plain,plain,plain,cave_0,cave_1,mountain,mountain,mountain,plain,plain,plain,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,mountain,mountain,mountain,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,百兽宗_2,百兽宗_3,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,plain,plain,plain,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,plain,cave_2,cave_3,plain,plain,plain,plain,plain,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,island,sea
+desert,desert,desert,desert,desert,desert,desert,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,sect_2_0,sect_2_1,rainforest,rainforest,rainforest,plain,rainforest,plain,plain,plain,plain,plain,plain,plain,plain,swamp,swamp,swamp,swamp,swamp,plain,plain,plain,plain,plain,cave_0,cave_1,mountain,mountain,mountain,plain,plain,plain,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,mountain,mountain,mountain,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,sect_2_2,sect_2_3,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,plain,plain,plain,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,plain,cave_2,cave_3,plain,plain,plain,plain,plain,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,island,sea
desert,desert,desert,desert,desert,desert,desert,mountain,mountain,mountain,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,plain,plain,plain,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,plain,plain,plain,plain,plain,plain,plain,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
desert,desert,desert,desert,desert,desert,desert,desert,mountain,mountain,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,plain,plain,plain,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,desert,mountain,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,plain,plain,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,合欢宗_0,合欢宗_1,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
-desert,desert,desert,desert,desert,desert,desert,mountain,mountain,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,ruin_0,ruin_1,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,合欢宗_2,合欢宗_3,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,desert,mountain,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,plain,plain,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sect_6_0,sect_6_1,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
+desert,desert,desert,desert,desert,desert,desert,mountain,mountain,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,ruin_0,ruin_1,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sect_6_2,sect_6_3,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
desert,desert,desert,desert,desert,desert,desert,mountain,mountain,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,ruin_2,ruin_3,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,swamp,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
desert,desert,desert,desert,desert,desert,desert,mountain,mountain,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,rainforest,swamp,swamp,swamp,swamp,swamp,swamp,swamp,plain,plain,swamp,plain,sea,sea,sea,sea,sea,sea,sea,sea,sea,island,island,sea,sea,sea,sea,island,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea,sea
diff --git a/static/templates/history_influence_item.txt b/static/templates/history_influence_item.txt
new file mode 100644
index 0000000..128af6e
--- /dev/null
+++ b/static/templates/history_influence_item.txt
@@ -0,0 +1,40 @@
+你是一个仙侠世界的创作者,我会给你一个原始的世界背景,以及一段历史。
+你需要基于世界背景,根据这段历史,修改这个世界中存在的功法、兵器、辅助装备信息。
+
+世界背景:
+{world_info}
+
+历史文本:
+{history_str}
+
+功法信息:
+{techniques}
+
+兵器信息:
+{weapons}
+
+辅助装备信息:
+{auxiliarys}
+
+基于以上信息,分析,并返回修改意见。
+
+返回JSON格式:
+{{
+ "thinking": "分析应该有怎么样的修改",
+ "techniques_change":
+ {{
+ "id": {{ //原来的id
+ "name": str // 新的名字
+ "desc": desc // 新的desc
+ }}
+ }},
+ "weapons_change": {{}} // dict, 结构同上
+ "auxiliarys_change": {{}} // dict, 结构同上
+}}
+
+要求:
+1. thinking是你的思考过程,要详细分析
+2. 要参考history的内容进行修改,言之有理。
+3. history的文本内容多,就多修改点,少的话就少修改点
+4. 某项没有修改的话,就返回空字典{{}}
+5. 要修改的项,只返回name和desc,不返回别的key
diff --git a/static/templates/history_influence.txt b/static/templates/history_influence_map.txt
similarity index 64%
rename from static/templates/history_influence.txt
rename to static/templates/history_influence_map.txt
index 49c9382..f1af868 100644
--- a/static/templates/history_influence.txt
+++ b/static/templates/history_influence_map.txt
@@ -1,5 +1,5 @@
你是一个仙侠世界的创作者,我会给你一个原始的世界背景,以及一段历史。
-你需要基于世界背景,根据这段历史,修改这个世界中存在的部分功法、兵器、辅助装备、区域信息。
+你需要基于世界背景,根据这段历史,修改这个世界中存在的区域信息(包括城市、普通区域、修炼区域)。
世界背景:
{world_info}
@@ -16,18 +16,6 @@
修炼区域信息:
{cultivate_regions}
-宗门区域信息:
-{sect_regions}
-
-功法信息:
-{techniques}
-
-兵器信息:
-{weapons}
-
-辅助装备信息:
-{auxiliarys}
-
基于以上信息,分析,并返回修改意见。
返回JSON格式:
@@ -41,17 +29,12 @@
}}
}},
"normal_regions_change": {{}} // dict, 结构同上
- "cultivate_regions_change": {{}} // dict, 结构同上
- "sect_regions_change": {{}} // dict, 结构同上
- "techniques_change": {{}} // dict, 结构同上
- "weapons_change": {{}} // dict, 结构同上
- "auxiliarys_change": {{}} // dict, 结构同上
+ "cultivate_regions_change": {{}} // dict, 结构同上
}}
要求:
1. thinking是你的思考过程,要详细分析
-2. 要参考history的内容进行修改,言之有理,比如。
+2. 要参考history的内容进行修改,言之有理。
3. history的文本内容多,就多修改点,少的话就少修改点
4. 某项没有修改的话,就返回空字典{{}}
5. 要修改的项,只返回name和desc,不返回别的key
-
diff --git a/static/templates/history_influence_sect.txt b/static/templates/history_influence_sect.txt
new file mode 100644
index 0000000..c36a1ab
--- /dev/null
+++ b/static/templates/history_influence_sect.txt
@@ -0,0 +1,36 @@
+你是一个仙侠世界的创作者,我会给你一个原始的世界背景,以及一段历史。
+你需要基于世界背景,根据这段历史,修改这个世界中存在的宗门信息,以及宗门对应的驻地信息。
+
+世界背景:
+{world_info}
+
+历史文本:
+{history_str}
+
+宗门信息:
+{sects}
+
+宗门区域信息:
+{sect_regions}
+
+基于以上信息,分析,并返回修改意见。
+
+返回JSON格式:
+{{
+ "thinking": "分析应该有怎么样的修改",
+ "sects_change":
+ {{
+ "id": {{ //原来的id
+ "name": str // 新的名字
+ "desc": desc // 新的desc
+ }}
+ }},
+ "sect_regions_change": {{}} // dict, 结构同上,针对宗门区域
+}}
+
+要求:
+1. thinking是你的思考过程,要详细分析
+2. 要参考history的内容进行修改,言之有理。
+3. history的文本内容多,就多修改点,少的话就少修改点
+4. 某项没有修改的话,就返回空字典{{}}
+5. 要修改的项,只返回name和desc,不返回别的key
diff --git a/tests/test_history.py b/tests/test_history.py
index 5c833fe..3a1b7f8 100644
--- a/tests/test_history.py
+++ b/tests/test_history.py
@@ -1,17 +1,40 @@
import pytest
from unittest.mock import MagicMock, AsyncMock, patch
+from pathlib import Path
from src.classes.history import HistoryManager
-from src.classes.region import CityRegion, NormalRegion, CultivateRegion
+from src.classes.region import CityRegion, NormalRegion, CultivateRegion, Region
+from src.classes.sect_region import SectRegion
from src.classes.technique import Technique, TechniqueAttribute, TechniqueGrade
from src.classes.weapon import Weapon, WeaponType
from src.classes.auxiliary import Auxiliary
from src.classes.cultivation import Realm
from src.classes.item_registry import ItemRegistry
+from src.classes.sect import Sect, SectHeadQuarter
+from src.classes.alignment import Alignment
# 假设这些全局字典在模块层级
from src.classes import technique as technique_module
from src.classes import weapon as weapon_module
-# auxiliary 模块没有导出全局字典,所以这里不需要特别处理它的全局字典,只需要处理 ItemRegistry
+from src.classes import sect as sect_module
+
+def test_world_set_history(base_world):
+ """测试 world.set_history 方法和 static_info 中的历史显示"""
+ # 初始状态:无历史
+ assert base_world.history == ""
+ static_info = base_world.static_info
+ assert "历史" not in static_info
+
+ # 设置历史
+ history_text = "这是一段测试历史文本:修仙界曾发生大战,许多宗门覆灭。"
+ base_world.set_history(history_text)
+
+ # 验证历史已设置
+ assert base_world.history == history_text
+
+ # 验证 static_info 包含历史
+ static_info = base_world.static_info
+ assert "历史" in static_info
+ assert static_info["历史"] == history_text
@pytest.mark.asyncio
async def test_history_influence(base_world):
@@ -21,14 +44,28 @@ async def test_history_influence(base_world):
city_region = CityRegion(id=1, name="OldCity", desc="Old Desc")
normal_region = NormalRegion(id=2, name="OldWild", desc="Old Wild Desc")
cult_region = CultivateRegion(id=3, name="OldCave", desc="Old Cave Desc")
+ # 假设 ID 4 是宗门驻地在地图上的区域对象
+ sect_region_obj = SectRegion(id=4, name="OldSectHQ", desc="Old Sect HQ Desc", sect_name="OldSect", sect_id=1)
base_world.map.regions = {
1: city_region,
2: normal_region,
- 3: cult_region
+ 3: cult_region,
+ 4: sect_region_obj
}
- # 2. Techniques
+ # 2. Sects
+ sect = Sect(
+ id=1,
+ name="OldSect",
+ desc="Old Sect Desc",
+ member_act_style="Old Style",
+ alignment=Alignment.RIGHTEOUS,
+ headquarter=SectHeadQuarter(name="OldHQ", desc="Old HQ Desc", image=None),
+ technique_names=[]
+ )
+
+ # 3. Techniques
tech = Technique(
id=101,
name="OldTech",
@@ -39,7 +76,7 @@ async def test_history_influence(base_world):
condition=""
)
- # 3. Weapons & Auxiliaries
+ # 4. Weapons & Auxiliaries
weapon = Weapon(
id=201,
name="OldSword",
@@ -55,53 +92,66 @@ async def test_history_influence(base_world):
)
# --- Patch Global Registries ---
- # 使用 patch.dict 来隔离对全局字典的修改
with patch.dict(technique_module.techniques_by_id, {101: tech}, clear=True), \
patch.dict(technique_module.techniques_by_name, {"OldTech": tech}, clear=True), \
patch.dict(weapon_module.weapons_by_name, {"OldSword": weapon}, clear=True), \
- patch.object(ItemRegistry, "_items_by_id", {201: weapon, 301: aux}): # ItemRegistry 是类属性
+ patch.dict(sect_module.sects_by_id, {1: sect}, clear=True), \
+ patch.dict(sect_module.sects_by_name, {"OldSect": sect}, clear=True), \
+ patch.object(ItemRegistry, "_items_by_id", {201: weapon, 301: aux}):
- # --- Prepare LLM Mock Response ---
- mock_response = {
- "city_regions_change": {
- "1": {"name": "NewCity", "desc": "New Desc"}
- },
- "normal_regions_change": {
- "2": {"name": "NewWild", "desc": "New Wild Desc"}
- },
- "cultivate_regions_change": {
- "3": {"name": "NewCave", "desc": "New Cave Desc"}
- },
- "techniques_change": {
- "101": {"name": "NewTech", "desc": "New Tech Desc"}
- },
- "weapons_change": {
- "201": {"name": "NewSword", "desc": "New Sword Desc"}
- },
- "auxiliarys_change": {
- "301": {"name": "NewOrb", "desc": "New Orb Desc"}
- }
+ # --- Prepare LLM Mock Responses ---
+ # Map Task Response
+ map_response = {
+ "city_regions_change": {"1": {"name": "NewCity", "desc": "New Desc"}},
+ "normal_regions_change": {"2": {"name": "NewWild", "desc": "New Wild Desc"}},
+ "cultivate_regions_change": {"3": {"name": "NewCave", "desc": "New Cave Desc"}}
}
+
+ # Sect Task Response
+ sect_response = {
+ "sects_change": {"1": {"name": "NewSect", "desc": "New Sect Desc"}},
+ "sect_regions_change": {"4": {"name": "NewSectHQ", "desc": "New Sect HQ Desc"}}
+ }
+
+ # Item Task Response
+ item_response = {
+ "techniques_change": {"101": {"name": "NewTech", "desc": "New Tech Desc"}},
+ "weapons_change": {"201": {"name": "NewSword", "desc": "New Sword Desc"}},
+ "auxiliarys_change": {"301": {"name": "NewOrb", "desc": "New Orb Desc"}}
+ }
+
+ def side_effect(**kwargs):
+ task_name = kwargs.get("task_name")
+ if task_name == "history_influence_map":
+ return map_response
+ elif task_name == "history_influence_sect":
+ return sect_response
+ elif task_name == "history_influence_item":
+ return item_response
+ return {}
# --- Instantiate Manager & Mock Internal Methods ---
manager = HistoryManager(base_world)
-
- # Mock _read_csv to return dummy string
manager._read_csv = MagicMock(return_value="dummy,csv,content")
# Mock call_llm_with_task_name
with patch("src.classes.history.call_llm_with_task_name", new_callable=AsyncMock) as mock_llm:
- mock_llm.return_value = mock_response
+ mock_llm.side_effect = side_effect
# --- Execute ---
- await manager.apply_history_influence("Some history text")
+ history_text = "Some history text"
+ await manager.apply_history_influence(history_text)
# --- Assertions ---
- # 1. LLM Called
- mock_llm.assert_called_once()
+ # 0. World history 未自动设置(需要外部调用 set_history)
+ # 注意:apply_history_influence 只应用影响,不设置 history 属性
+ # history 属性应该在调用前由外部设置
- # 2. Regions Updated
+ # 1. LLM Called 3 times
+ assert mock_llm.call_count == 3
+
+ # 2. Map Regions Updated
assert city_region.name == "NewCity"
assert city_region.desc == "New Desc"
assert normal_region.name == "NewWild"
@@ -109,21 +159,120 @@ async def test_history_influence(base_world):
assert cult_region.name == "NewCave"
assert cult_region.desc == "New Cave Desc"
- # 3. Technique Updated & Index Synced
+ # 3. Sect & Sect Region Updated
+ assert sect.name == "NewSect"
+ assert sect.desc == "New Sect Desc"
+ assert sect_region_obj.name == "NewSectHQ" # 地图上的对象被更新
+ assert sect_region_obj.desc == "New Sect HQ Desc"
+
+ # 4. Sect Index Synced
+ assert "NewSect" in sect_module.sects_by_name
+ assert "OldSect" not in sect_module.sects_by_name
+ assert sect_module.sects_by_name["NewSect"] == sect
+
+ # 5. Technique Updated & Index Synced
assert tech.name == "NewTech"
assert tech.desc == "New Tech Desc"
assert "NewTech" in technique_module.techniques_by_name
assert "OldTech" not in technique_module.techniques_by_name
assert technique_module.techniques_by_name["NewTech"] == tech
- # 4. Weapon Updated & Index Synced
+ # 6. Weapon Updated & Index Synced
assert weapon.name == "NewSword"
assert weapon.desc == "New Sword Desc"
assert "NewSword" in weapon_module.weapons_by_name
assert "OldSword" not in weapon_module.weapons_by_name
assert weapon_module.weapons_by_name["NewSword"] == weapon
- # 5. Auxiliary Updated
+ # 7. Auxiliary Updated
assert aux.name == "NewOrb"
assert aux.desc == "New Orb Desc"
+@pytest.mark.asyncio
+async def test_history_workflow_integration(base_world):
+ """测试完整的历史工作流程:设置历史 -> 应用影响"""
+ # 准备测试数据
+ city_region = CityRegion(id=1, name="测试城", desc="旧描述")
+ base_world.map.regions = {1: city_region}
+
+ # 模拟初始化时的完整流程
+ history_text = "这片大陆曾经历过灵气复苏,修仙宗门林立。"
+
+ # 1. 先设置 history(模拟 init_game_async 中的调用)
+ base_world.set_history(history_text)
+ assert base_world.history == history_text
+
+ # 2. 验证 static_info 中包含历史
+ static_info = base_world.static_info
+ assert "历史" in static_info
+ assert static_info["历史"] == history_text
+
+ # 3. 应用历史影响(模拟 HistoryManager.apply_history_influence)
+ manager = HistoryManager(base_world)
+ manager._read_csv = MagicMock(return_value="dummy,csv,content")
+
+ map_response = {
+ "city_regions_change": {"1": {"name": "灵气城", "desc": "充满灵气的城市"}},
+ }
+
+ def side_effect(**kwargs):
+ task_name = kwargs.get("task_name")
+ if task_name == "history_influence_map":
+ return map_response
+ return {}
+
+ with patch("src.classes.history.call_llm_with_task_name", new_callable=AsyncMock) as mock_llm:
+ mock_llm.side_effect = side_effect
+
+ await manager.apply_history_influence(history_text)
+
+ # 4. 验证影响已应用
+ assert city_region.name == "灵气城"
+ assert city_region.desc == "充满灵气的城市"
+
+ # 5. 验证 history 仍然保留
+ assert base_world.history == history_text
+
+ # 6. 验证 static_info 中仍包含历史
+ static_info = base_world.static_info
+ assert "历史" in static_info
+ assert static_info["历史"] == history_text
+
+def test_history_persistence_in_save_load(base_world, tmp_path):
+ """测试 history 在保存和加载时的持久化"""
+ from src.sim.save.save_game import save_game
+ from src.sim.load.load_game import load_game
+ from src.sim.simulator import Simulator
+
+ # 设置历史
+ history_text = "修仙界的远古历史:曾有强者飞升,留下诸多传承。"
+ base_world.set_history(history_text)
+
+ # 创建模拟器和宗门列表
+ simulator = Simulator(base_world)
+ existed_sects = []
+
+ # 保存游戏
+ save_path = tmp_path / "test_history_save.json"
+ success, _ = save_game(base_world, simulator, existed_sects, save_path)
+ assert success, "保存游戏应该成功"
+
+ # 验证保存文件中包含历史
+ import json
+ with open(save_path, "r", encoding="utf-8") as f:
+ save_data = json.load(f)
+
+ world_data = save_data.get("world", {})
+ assert "history" in world_data, "保存数据应该包含 history 字段"
+ assert world_data["history"] == history_text, "保存的历史文本应该正确"
+
+ # 加载游戏
+ loaded_world, loaded_sim, loaded_sects = load_game(save_path)
+
+ # 验证历史被正确恢复
+ assert loaded_world.history == history_text, "加载的世界应该包含历史"
+
+ # 验证 static_info 中包含历史
+ static_info = loaded_world.static_info
+ assert "历史" in static_info, "加载后的 static_info 应该包含历史"
+ assert static_info["历史"] == history_text, "加载后的历史文本应该正确"
diff --git a/tests/test_item_registry.py b/tests/test_item_registry.py
index 6fa8a43..eb8179f 100644
--- a/tests/test_item_registry.py
+++ b/tests/test_item_registry.py
@@ -102,6 +102,9 @@ def test_store_init_mixed_ids_and_names(mock_item_data):
original_registry = ItemRegistry._items_by_id.copy()
ItemRegistry._items_by_id.clear()
+ from src.classes.weapon import weapons_by_name
+ original_weapons_by_name = weapons_by_name.copy()
+
try:
# We need `resolve_query` to work for names, which relies on
# weapons_by_name etc. populated in conftest or manually here.
@@ -119,7 +122,6 @@ def test_store_init_mixed_ids_and_names(mock_item_data):
# We need to mock `src.utils.resolution.resolve_query` or make `resolve_query` find it.
# Ideally, `StoreMixin` uses `resolve_query` for strings.
- from src.classes.weapon import weapons_by_name
weapons_by_name[weapon.name] = weapon
shop = MockShop()
@@ -133,6 +135,8 @@ def test_store_init_mixed_ids_and_names(mock_item_data):
finally:
ItemRegistry._items_by_id = original_registry
+ weapons_by_name.clear()
+ weapons_by_name.update(original_weapons_by_name)
# --- Test Item Instantiation ---
diff --git a/tools/map_creator/README_MIGRATION.md b/tools/map_creator/README_MIGRATION.md
new file mode 100644
index 0000000..dbc7b81
--- /dev/null
+++ b/tools/map_creator/README_MIGRATION.md
@@ -0,0 +1,76 @@
+# Map Creator ID Migration
+
+## 修改说明
+
+已将地图编辑器从基于名称的配置迁移到基于 ID 的配置,以匹配主项目的修改。
+
+### 主要修改
+
+#### 1. 后端 (main.py)
+
+**区域-地形映射表 (REGION_TILE_MAP)**
+- 从名称映射改为 ID 映射
+- 示例:
+ ```python
+ # 旧:
+ "青云城": {"t": "青云城", "type": "city"}
+
+ # 新:
+ 301: {"t": "city_301", "type": "city"}
+ ```
+
+**get_default_tile 函数**
+- 新增参数:`sect_id`, `sub_type`
+- 支持根据 ID 生成 tile 名称:
+ - 宗门:`sect_{sect_id}` (如 `sect_1`)
+ - 城市:`city_{region_id}` (如 `city_301`)
+ - 修炼区域:根据 `sub_type` 返回 `cave` 或 `ruin`
+
+**资源文件扫描**
+- 宗门:从 `sect_1_0.png` 等切片提取基础名称 `sect_1`
+- 城市:从 `city_301_0.png` 等切片提取基础名称 `city_301`
+
+**CSV 解析**
+- 新增 `sub_type_col` 参数,用于读取 `cultivate_region.csv` 的 `sub_type` 列
+
+#### 2. 前端 (templates/index.html)
+
+**预览图片显示**
+- 添加 `getRegionPreviewSrc` 函数,根据区域类型动态生成预览图片路径
+- 支持:
+ - 宗门:`/sects/sect_1_0.png`
+ - 城市:`/cities/city_301_0.png` (支持 jpg/png)
+ - 修炼区域:`/tiles/cave_0.png` 或 `/tiles/ruin_0.png`
+
+### 兼容性
+
+**资源文件命名要求**:
+- 宗门图片:`assets/sects/sect_{id}_{0-3}.png`
+- 城市图片:`assets/cities/city_{id}_{0-3}.{png|jpg}`
+- 修炼区域:`assets/tiles/{cave|ruin}_{0-3}.png`
+
+**CSV 文件要求**:
+- `sect_region.csv`: 必须包含 `sect_id` 列(第3列,索引为3)
+- `cultivate_region.csv`: 必须包含 `sub_type` 列(第3列,索引为3)
+
+### 使用方法
+
+1. 确保资源文件已按新的命名规则重命名
+2. 确保 CSV 文件包含必要的列
+3. 运行地图编辑器:
+ ```bash
+ python tools/map_creator/main.py
+ ```
+4. 访问 http://127.0.0.1:5000
+
+### 示例数据
+
+**宗门区域**:
+- ID: 401, sect_id: 1 → 绑定 tile: `sect_1`
+
+**城市区域**:
+- ID: 301, name: "青云城" → 绑定 tile: `city_301`
+
+**修炼区域**:
+- ID: 201, name: "太白金府", sub_type: "cave" → 绑定 tile: `cave`
+- ID: 206, name: "古越遗迹", sub_type: "ruin" → 绑定 tile: `ruin`
diff --git a/tools/map_creator/main.py b/tools/map_creator/main.py
index 3f4ac8a..d546d69 100644
--- a/tools/map_creator/main.py
+++ b/tools/map_creator/main.py
@@ -33,76 +33,84 @@ def serve_city_image(filename):
return send_from_directory(os.path.join(ASSETS_DIR, "cities"), filename)
# 显式定义的区域-地形映射表
-# Key: 区域名称, Value: {"t": tile_name, "type": "tile" | "sect" | "city"}
+# Key: 区域ID (int), Value: {"t": tile_name, "type": "tile" | "sect" | "city"}
REGION_TILE_MAP = {
- # --- 普通区域 (Normal Regions) ---
- "平原地带": {"t": "plain", "type": "tile"},
- "西域流沙": {"t": "desert", "type": "tile"},
- "南疆蛮荒": {"t": "rainforest", "type": "tile"},
- "极北冰原": {"t": "glacier", "type": "tile"},
- "无边碧海": {"t": "sea", "type": "tile"},
- "天河奔流": {"t": "water", "type": "tile"},
- "青峰山脉": {"t": "mountain", "type": "tile"},
- "万丈雪峰": {"t": "snow_mountain", "type": "tile"},
- "碧野千里": {"t": "grassland", "type": "tile"},
- "青云林海": {"t": "forest", "type": "tile"},
- "炎狱火山": {"t": "volcano", "type": "tile"},
- "沃土良田": {"t": "farm", "type": "tile"},
- "幽冥毒泽": {"t": "swamp", "type": "tile"},
- "十万大山": {"t": "mountain", "type": "tile"},
- "紫竹幽境": {"t": "bamboo", "type": "tile"},
- "凛霜荒原": {"t": "tundra", "type": "tile"},
- "碎星戈壁": {"t": "gobi", "type": "tile"},
- "蓬莱遗岛": {"t": "island", "type": "tile"},
+ # --- 城市区域 (City Regions) - 使用 ID ---
+ 301: {"t": "city_301", "type": "city"}, # 青云城
+ 302: {"t": "city_302", "type": "city"}, # 沙月城
+ 303: {"t": "city_303", "type": "city"}, # 翠林城
+ 304: {"t": "city_304", "type": "city"}, # 沧澜城
+ 305: {"t": "city_305", "type": "city"}, # 揽月城
- # --- 城市区域 (City Regions) ---
- "青云城": {"t": "青云城", "type": "city"},
- "沙月城": {"t": "沙月城", "type": "city"},
- "翠林城": {"t": "翠林城", "type": "city"},
- "揽月城": {"t": "揽月城", "type": "city"},
- "沧澜城": {"t": "沧澜城", "type": "city"},
-
- # --- 洞府遗迹 (Cultivate Regions) ---
- "太白金府": {"t": "cave", "type": "tile"},
- "青木洞天": {"t": "cave", "type": "tile"},
- "玄水秘境": {"t": "cave", "type": "tile"},
- "离火洞府": {"t": "cave", "type": "tile"},
- "厚土玄宫": {"t": "cave", "type": "tile"},
- "古越遗迹": {"t": "ruin", "type": "tile"},
- "沧海遗迹": {"t": "ruin", "type": "tile"},
+ # --- 洞府遗迹 (Cultivate Regions) - 使用 sub_type ---
+ 201: {"t": "cave", "type": "tile"}, # 太白金府
+ 202: {"t": "cave", "type": "tile"}, # 青木洞天
+ 203: {"t": "cave", "type": "tile"}, # 玄水秘境
+ 204: {"t": "cave", "type": "tile"}, # 离火洞府
+ 205: {"t": "cave", "type": "tile"}, # 厚土玄宫
+ 206: {"t": "ruin", "type": "tile"}, # 古越遗迹
+ 207: {"t": "ruin", "type": "tile"}, # 沧海遗迹
}
-def get_default_tile(name, type_tag, all_tiles, all_sect_tiles, all_city_tiles):
- """根据区域名称和类型查找默认 Tile"""
-
- # 1. 查表 (精确匹配)
- if name in REGION_TILE_MAP:
- return REGION_TILE_MAP[name]
-
- # 2. 宗门:尝试匹配 Sect 图片
- if type_tag == 'sect':
- # 尝试直接匹配宗门名
- if name in all_sect_tiles:
- return {"t": name, "type": "sect"}
- # 尝试部分匹配
- for t in all_sect_tiles:
- if t in name or name in t:
- return {"t": t, "type": "sect"}
- return {"t": "mountain", "type": "tile"} # 默认建在山上
+# 普通区域名称映射(用于后备查找)
+NORMAL_REGION_NAME_MAP = {
+ "平原地带": "plain",
+ "西域流沙": "desert",
+ "南疆蛮荒": "rainforest",
+ "极北冰原": "glacier",
+ "无边碧海": "sea",
+ "天河奔流": "water",
+ "青峰山脉": "mountain",
+ "万丈雪峰": "snow_mountain",
+ "碧野千里": "grassland",
+ "青云林海": "forest",
+ "炎狱火山": "volcano",
+ "沃土良田": "farm",
+ "幽冥毒泽": "swamp",
+ "十万大山": "mountain",
+ "紫竹幽境": "bamboo",
+ "凛霜荒原": "tundra",
+ "碎星戈壁": "gobi",
+ "蓬莱遗岛": "island",
+}
- # 3. 城市
+def get_default_tile(region_id, name, type_tag, sect_id=None, sub_type=None):
+ """根据区域ID和类型查找默认 Tile
+
+ Args:
+ region_id: 区域ID
+ name: 区域名称(用于后备查找)
+ type_tag: 区域类型 (normal/sect/city/cultivate)
+ sect_id: 宗门ID(仅 sect 类型)
+ sub_type: 子类型(仅 cultivate 类型:cave/ruin)
+ """
+
+ # 1. 优先使用 ID 查表
+ if region_id in REGION_TILE_MAP:
+ return REGION_TILE_MAP[region_id]
+
+ # 2. 宗门:使用 sect_id 生成 tile 名称
+ if type_tag == 'sect' and sect_id is not None:
+ return {"t": f"sect_{sect_id}", "type": "sect"}
+
+ # 3. 城市:使用 region_id 生成 tile 名称
if type_tag == 'city':
- if name in all_city_tiles:
- return {"t": name, "type": "city"}
- return {"t": "city", "type": "tile"}
-
- # 4. 包含特定关键词的兜底逻辑 (针对未在表中的新区域)
- name_lower = name.lower()
- if '洞' in name_lower or '府' in name_lower or '秘境' in name_lower:
+ return {"t": f"city_{region_id}", "type": "city"}
+
+ # 4. 修炼区域:使用 sub_type
+ if type_tag == 'cultivate':
+ if sub_type in ['cave', 'ruin']:
+ return {"t": sub_type, "type": "tile"}
+ # 兜底:根据名称推断
+ if '遗迹' in name:
+ return {"t": "ruin", "type": "tile"}
return {"t": "cave", "type": "tile"}
- if '遗迹' in name_lower:
- return {"t": "ruin", "type": "tile"}
-
+
+ # 5. 普通区域:尝试名称映射
+ if type_tag == 'normal' and name in NORMAL_REGION_NAME_MAP:
+ tile_name = NORMAL_REGION_NAME_MAP[name]
+ return {"t": tile_name, "type": "tile"}
+
# 默认
return {"t": "plain", "type": "tile"}
@@ -116,25 +124,43 @@ def init_data():
tiles = [os.path.splitext(os.path.basename(f))[0] for f in tile_files if not os.path.splitext(os.path.basename(f))[0][-2:] in ['_0', '_1', '_2', '_3']]
tiles.sort()
- # 2. 获取所有 Sect 图片名称
+ # 2. 获取所有 Sect 图片名称 (sect_1, sect_2, ...)
sect_files = glob.glob(os.path.join(ASSETS_DIR, "sects", "*.png"))
- sect_tiles = [os.path.splitext(os.path.basename(f))[0] for f in sect_files if not os.path.splitext(os.path.basename(f))[0][-2:] in ['_0', '_1', '_2', '_3']]
- sect_tiles.sort()
+ sect_tiles_set = set()
+ for f in sect_files:
+ name = os.path.splitext(os.path.basename(f))[0]
+ # Extract base name from slices: sect_1_0 -> sect_1
+ if name.startswith('sect_') and '_' in name[5:]:
+ # Split by underscore and take first two parts
+ parts = name.split('_')
+ if len(parts) >= 3: # sect_1_0
+ base_name = f"{parts[0]}_{parts[1]}" # sect_1
+ sect_tiles_set.add(base_name)
+ sect_tiles = sorted(list(sect_tiles_set))
- # 3. 获取所有 City 图片名称 (保留扩展名映射)
+ # 3. 获取所有 City 图片名称 (city_301, city_302, ...)
city_files = glob.glob(os.path.join(ASSETS_DIR, "cities", "*.*"))
# 过滤非图片
city_files = [f for f in city_files if f.lower().endswith(('.png', '.jpg', '.jpeg'))]
- city_tiles_map = {} # name -> filename
- city_tiles = []
+ city_tiles_map = {} # base_name -> extension (for first slice)
+ city_tiles_set = set()
for f in city_files:
- name = os.path.splitext(os.path.basename(f))[0]
- if name[-2:] in ['_0', '_1', '_2', '_3']: continue
- filename = os.path.basename(f)
- city_tiles.append(name)
- city_tiles_map[name] = filename
- city_tiles.sort()
+ basename = os.path.basename(f)
+ name = os.path.splitext(basename)[0]
+ ext = os.path.splitext(basename)[1]
+
+ # Extract base name from slices: city_301_0 -> city_301
+ if name.startswith('city_') and '_' in name[5:]:
+ parts = name.split('_')
+ if len(parts) >= 3: # city_301_0
+ base_name = f"{parts[0]}_{parts[1]}" # city_301
+ city_tiles_set.add(base_name)
+ # Store extension for the first slice
+ if base_name not in city_tiles_map:
+ city_tiles_map[base_name] = f"{base_name}_0{ext}"
+
+ city_tiles = sorted(list(city_tiles_set))
# 4. 读取 sect.csv 建立 sect_id -> sect_name 映射
sect_id_to_name = {}
@@ -156,7 +182,7 @@ def init_data():
# 5. 读取 Region 配置
regions = []
- def parse_csv(filename, id_col, name_col, type_tag, sect_id_col=None):
+ def parse_csv(filename, id_col, name_col, type_tag, sect_id_col=None, sub_type_col=None):
path = os.path.join(CONFIG_DIR, filename)
if not os.path.exists(path):
print(f"Warning: {path} not found")
@@ -177,17 +203,21 @@ def init_data():
color_hash = hash(f"{type_tag}_{r_id}") & 0xFFFFFF
color = f"#{color_hash:06x}"
- # 对于 sect 类型,使用 sect_id 查找对应的宗门名称
- bind_name = name
+ # 获取 sect_id (用于宗门)
+ sect_id = None
if type_tag == 'sect' and sect_id_col is not None and len(row) > sect_id_col:
try:
- sid = int(row[sect_id_col])
- bind_name = sect_id_to_name.get(sid, name)
+ sect_id = int(row[sect_id_col])
except ValueError:
pass
+ # 获取 sub_type (用于修炼区域)
+ sub_type = None
+ if type_tag == 'cultivate' and sub_type_col is not None and len(row) > sub_type_col:
+ sub_type = row[sub_type_col].strip()
+
# 计算默认绑定 Tile
- bind_info = get_default_tile(bind_name, type_tag, tiles, sect_tiles, city_tiles)
+ bind_info = get_default_tile(r_id, name, type_tag, sect_id=sect_id, sub_type=sub_type)
regions.append({
"id": r_id,
@@ -206,8 +236,8 @@ def init_data():
parse_csv("normal_region.csv", 0, 1, "normal")
# sect_region.csv: id=0, name=1, sect_id=3
parse_csv("sect_region.csv", 0, 1, "sect", sect_id_col=3)
- # cultivate_region.csv: id=0, name=1
- parse_csv("cultivate_region.csv", 0, 1, "cultivate")
+ # cultivate_region.csv: id=0, name=1, sub_type=3 (在 desc 后面)
+ parse_csv("cultivate_region.csv", 0, 1, "cultivate", sub_type_col=3)
# city_region.csv: id=0, name=1
parse_csv("city_region.csv", 0, 1, "city")
diff --git a/tools/map_creator/templates/index.html b/tools/map_creator/templates/index.html
index 5f56f61..1fb84fb 100644
--- a/tools/map_creator/templates/index.html
+++ b/tools/map_creator/templates/index.html
@@ -140,7 +140,7 @@