From 95e1f1150245dc75b77b5c7bca89187d34630875 Mon Sep 17 00:00:00 2001 From: 4thfever Date: Mon, 12 Jan 2026 23:25:53 +0800 Subject: [PATCH] Refactor/history (#25) add multi process history modification --- .../cities/{青云城_0.jpg => city_301_0.jpg} | Bin .../cities/{青云城_0.png => city_301_0.png} | Bin .../cities/{青云城_1.jpg => city_301_1.jpg} | Bin .../cities/{青云城_1.png => city_301_1.png} | Bin .../cities/{青云城_2.jpg => city_301_2.jpg} | Bin .../cities/{青云城_2.png => city_301_2.png} | Bin .../cities/{青云城_3.jpg => city_301_3.jpg} | Bin .../cities/{青云城_3.png => city_301_3.png} | Bin .../cities/{沙月城_0.jpg => city_302_0.jpg} | Bin .../cities/{沙月城_0.png => city_302_0.png} | Bin .../cities/{沙月城_1.jpg => city_302_1.jpg} | Bin .../cities/{沙月城_1.png => city_302_1.png} | Bin .../cities/{沙月城_2.jpg => city_302_2.jpg} | Bin .../cities/{沙月城_2.png => city_302_2.png} | Bin .../cities/{沙月城_3.jpg => city_302_3.jpg} | Bin .../cities/{沙月城_3.png => city_302_3.png} | Bin .../cities/{翠林城_0.jpg => city_303_0.jpg} | Bin .../cities/{翠林城_0.png => city_303_0.png} | Bin .../cities/{翠林城_1.jpg => city_303_1.jpg} | Bin .../cities/{翠林城_1.png => city_303_1.png} | Bin .../cities/{翠林城_2.jpg => city_303_2.jpg} | Bin .../cities/{翠林城_2.png => city_303_2.png} | Bin .../cities/{翠林城_3.jpg => city_303_3.jpg} | Bin .../cities/{翠林城_3.png => city_303_3.png} | Bin .../cities/{沧澜城_0.jpg => city_304_0.jpg} | Bin .../cities/{沧澜城_0.png => city_304_0.png} | Bin .../cities/{沧澜城_1.jpg => city_304_1.jpg} | Bin .../cities/{沧澜城_1.png => city_304_1.png} | Bin .../cities/{沧澜城_2.jpg => city_304_2.jpg} | Bin .../cities/{沧澜城_2.png => city_304_2.png} | Bin .../cities/{沧澜城_3.jpg => city_304_3.jpg} | Bin .../cities/{沧澜城_3.png => city_304_3.png} | Bin .../cities/{揽月城_0.jpg => city_305_0.jpg} | Bin .../cities/{揽月城_0.png => city_305_0.png} | Bin .../cities/{揽月城_1.jpg => city_305_1.jpg} | Bin .../cities/{揽月城_1.png => city_305_1.png} | Bin .../cities/{揽月城_2.jpg => city_305_2.jpg} | Bin .../cities/{揽月城_2.png => city_305_2.png} | Bin .../cities/{揽月城_3.jpg => city_305_3.jpg} | Bin .../cities/{揽月城_3.png => city_305_3.png} | Bin assets/sects/{明心剑宗.png => sect_1.png} | Bin assets/sects/{妙化宗.png => sect_10.png} | Bin assets/sects/{妙化宗_0.png => sect_10_0.png} | Bin assets/sects/{妙化宗_1.png => sect_10_1.png} | Bin assets/sects/{妙化宗_2.png => sect_10_2.png} | Bin assets/sects/{妙化宗_3.png => sect_10_3.png} | Bin assets/sects/{回玄宗.png => sect_11.png} | Bin assets/sects/{回玄宗_0.png => sect_11_0.png} | Bin assets/sects/{回玄宗_1.png => sect_11_1.png} | Bin assets/sects/{回玄宗_2.png => sect_11_2.png} | Bin assets/sects/{回玄宗_3.png => sect_11_3.png} | Bin assets/sects/{不夜城.png => sect_12.png} | Bin assets/sects/{不夜城_0.png => sect_12_0.png} | Bin assets/sects/{不夜城_1.png => sect_12_1.png} | Bin assets/sects/{不夜城_2.png => sect_12_2.png} | Bin assets/sects/{不夜城_3.png => sect_12_3.png} | Bin assets/sects/{天行健宗.png => sect_13.png} | Bin .../sects/{天行健宗_0.png => sect_13_0.png} | Bin .../sects/{天行健宗_1.png => sect_13_1.png} | Bin .../sects/{天行健宗_2.png => sect_13_2.png} | Bin .../sects/{天行健宗_3.png => sect_13_3.png} | Bin assets/sects/{噬魔宗.png => sect_14.png} | Bin assets/sects/{噬魔宗_0.png => sect_14_0.png} | Bin assets/sects/{噬魔宗_1.png => sect_14_1.png} | Bin assets/sects/{噬魔宗_2.png => sect_14_2.png} | Bin assets/sects/{噬魔宗_3.png => sect_14_3.png} | Bin assets/sects/{明心剑宗_0.png => sect_1_0.png} | Bin assets/sects/{明心剑宗_1.png => sect_1_1.png} | Bin assets/sects/{明心剑宗_2.png => sect_1_2.png} | Bin assets/sects/{明心剑宗_3.png => sect_1_3.png} | Bin assets/sects/{百兽宗.png => sect_2.png} | Bin assets/sects/{百兽宗_0.png => sect_2_0.png} | Bin assets/sects/{百兽宗_1.png => sect_2_1.png} | Bin assets/sects/{百兽宗_2.png => sect_2_2.png} | Bin assets/sects/{百兽宗_3.png => sect_2_3.png} | Bin assets/sects/{水镜宗.png => sect_3.png} | Bin assets/sects/{水镜宗_0.png => sect_3_0.png} | Bin assets/sects/{水镜宗_1.png => sect_3_1.png} | Bin assets/sects/{水镜宗_2.png => sect_3_2.png} | Bin assets/sects/{水镜宗_3.png => sect_3_3.png} | Bin assets/sects/{冥王宗.png => sect_4.png} | Bin assets/sects/{冥王宗_0.png => sect_4_0.png} | Bin assets/sects/{冥王宗_1.png => sect_4_1.png} | Bin assets/sects/{冥王宗_2.png => sect_4_2.png} | Bin assets/sects/{冥王宗_3.png => sect_4_3.png} | Bin assets/sects/{朱勾宗.png => sect_5.png} | Bin assets/sects/{朱勾宗_0.png => sect_5_0.png} | Bin assets/sects/{朱勾宗_1.png => sect_5_1.png} | Bin assets/sects/{朱勾宗_2.png => sect_5_2.png} | Bin assets/sects/{朱勾宗_3.png => sect_5_3.png} | Bin assets/sects/{合欢宗.png => sect_6.png} | Bin assets/sects/{合欢宗_0.png => sect_6_0.png} | Bin assets/sects/{合欢宗_1.png => sect_6_1.png} | Bin assets/sects/{合欢宗_2.png => sect_6_2.png} | Bin assets/sects/{合欢宗_3.png => sect_6_3.png} | Bin assets/sects/{镇魂宗.png => sect_7.png} | Bin assets/sects/{镇魂宗_0.png => sect_7_0.png} | Bin assets/sects/{镇魂宗_1.png => sect_7_1.png} | Bin assets/sects/{镇魂宗_2.png => sect_7_2.png} | Bin assets/sects/{镇魂宗_3.png => sect_7_3.png} | Bin assets/sects/{幽魂噬影宗.png => sect_8.png} | Bin .../sects/{幽魂噬影宗_0.png => sect_8_0.png} | Bin .../sects/{幽魂噬影宗_1.png => sect_8_1.png} | Bin .../sects/{幽魂噬影宗_2.png => sect_8_2.png} | Bin .../sects/{幽魂噬影宗_3.png => sect_8_3.png} | Bin assets/sects/{千帆城.png => sect_9.png} | Bin assets/sects/{千帆城_0.png => sect_9_0.png} | Bin assets/sects/{千帆城_1.png => sect_9_1.png} | Bin assets/sects/{千帆城_2.png => sect_9_2.png} | Bin assets/sects/{千帆城_3.png => sect_9_3.png} | Bin src/classes/history.py | 162 +- src/classes/name.py | 104 +- src/classes/region.py | 6 +- src/classes/sect.py | 2 +- src/classes/world.py | 8 + src/run/load_map.py | 1 + src/server/main.py | 29 +- src/sim/load/load_game.py | 5 + src/sim/save/save_game.py | 2 + static/game_configs/city_region.csv | 2 +- static/game_configs/cultivate_region.csv | 18 +- static/game_configs/given_name.csv | 1598 ++++++++--------- static/game_configs/technique.csv | 58 +- static/game_configs/tile_map.csv | 52 +- static/templates/history_influence_item.txt | 40 + ...nfluence.txt => history_influence_map.txt} | 23 +- static/templates/history_influence_sect.txt | 36 + tests/test_history.py | 223 ++- tests/test_item_registry.py | 6 +- tools/map_creator/README_MIGRATION.md | 76 + tools/map_creator/main.py | 196 +- tools/map_creator/templates/index.html | 28 +- tools/map_creator/tile_map.csv | 40 +- tools/migrate_assets_and_map.py | 138 ++ web/src/components/game/MapLayer.vue | 46 +- .../game/composables/useTextures.ts | 26 +- web/src/types/core.ts | 3 +- 137 files changed, 1729 insertions(+), 1199 deletions(-) rename assets/cities/{青云城_0.jpg => city_301_0.jpg} (100%) rename assets/cities/{青云城_0.png => city_301_0.png} (100%) rename assets/cities/{青云城_1.jpg => city_301_1.jpg} (100%) rename assets/cities/{青云城_1.png => city_301_1.png} (100%) rename assets/cities/{青云城_2.jpg => city_301_2.jpg} (100%) rename assets/cities/{青云城_2.png => city_301_2.png} (100%) rename assets/cities/{青云城_3.jpg => city_301_3.jpg} (100%) rename assets/cities/{青云城_3.png => city_301_3.png} (100%) rename assets/cities/{沙月城_0.jpg => city_302_0.jpg} (100%) rename assets/cities/{沙月城_0.png => city_302_0.png} (100%) rename assets/cities/{沙月城_1.jpg => city_302_1.jpg} (100%) rename assets/cities/{沙月城_1.png => city_302_1.png} (100%) rename assets/cities/{沙月城_2.jpg => city_302_2.jpg} (100%) rename assets/cities/{沙月城_2.png => city_302_2.png} (100%) rename assets/cities/{沙月城_3.jpg => city_302_3.jpg} (100%) rename assets/cities/{沙月城_3.png => city_302_3.png} (100%) rename assets/cities/{翠林城_0.jpg => city_303_0.jpg} (100%) rename assets/cities/{翠林城_0.png => city_303_0.png} (100%) rename assets/cities/{翠林城_1.jpg => city_303_1.jpg} (100%) rename assets/cities/{翠林城_1.png => city_303_1.png} (100%) rename assets/cities/{翠林城_2.jpg => city_303_2.jpg} (100%) rename assets/cities/{翠林城_2.png => city_303_2.png} (100%) rename assets/cities/{翠林城_3.jpg => city_303_3.jpg} (100%) rename assets/cities/{翠林城_3.png => city_303_3.png} (100%) rename assets/cities/{沧澜城_0.jpg => city_304_0.jpg} (100%) rename assets/cities/{沧澜城_0.png => city_304_0.png} (100%) rename assets/cities/{沧澜城_1.jpg => city_304_1.jpg} (100%) rename assets/cities/{沧澜城_1.png => city_304_1.png} (100%) rename assets/cities/{沧澜城_2.jpg => city_304_2.jpg} (100%) rename assets/cities/{沧澜城_2.png => city_304_2.png} (100%) rename assets/cities/{沧澜城_3.jpg => city_304_3.jpg} (100%) rename assets/cities/{沧澜城_3.png => city_304_3.png} (100%) rename assets/cities/{揽月城_0.jpg => city_305_0.jpg} (100%) rename assets/cities/{揽月城_0.png => city_305_0.png} (100%) rename assets/cities/{揽月城_1.jpg => city_305_1.jpg} (100%) rename assets/cities/{揽月城_1.png => city_305_1.png} (100%) rename assets/cities/{揽月城_2.jpg => city_305_2.jpg} (100%) rename assets/cities/{揽月城_2.png => city_305_2.png} (100%) rename assets/cities/{揽月城_3.jpg => city_305_3.jpg} (100%) rename assets/cities/{揽月城_3.png => city_305_3.png} (100%) rename assets/sects/{明心剑宗.png => sect_1.png} (100%) rename assets/sects/{妙化宗.png => sect_10.png} (100%) rename assets/sects/{妙化宗_0.png => sect_10_0.png} (100%) rename assets/sects/{妙化宗_1.png => sect_10_1.png} (100%) rename assets/sects/{妙化宗_2.png => sect_10_2.png} (100%) rename assets/sects/{妙化宗_3.png => sect_10_3.png} (100%) rename assets/sects/{回玄宗.png => sect_11.png} (100%) rename assets/sects/{回玄宗_0.png => sect_11_0.png} (100%) rename assets/sects/{回玄宗_1.png => sect_11_1.png} (100%) rename assets/sects/{回玄宗_2.png => sect_11_2.png} (100%) rename assets/sects/{回玄宗_3.png => sect_11_3.png} (100%) rename assets/sects/{不夜城.png => sect_12.png} (100%) rename assets/sects/{不夜城_0.png => sect_12_0.png} (100%) rename assets/sects/{不夜城_1.png => sect_12_1.png} (100%) rename assets/sects/{不夜城_2.png => sect_12_2.png} (100%) rename assets/sects/{不夜城_3.png => sect_12_3.png} (100%) rename assets/sects/{天行健宗.png => sect_13.png} (100%) rename assets/sects/{天行健宗_0.png => sect_13_0.png} (100%) rename assets/sects/{天行健宗_1.png => sect_13_1.png} (100%) rename assets/sects/{天行健宗_2.png => sect_13_2.png} (100%) rename assets/sects/{天行健宗_3.png => sect_13_3.png} (100%) rename assets/sects/{噬魔宗.png => sect_14.png} (100%) rename assets/sects/{噬魔宗_0.png => sect_14_0.png} (100%) rename assets/sects/{噬魔宗_1.png => sect_14_1.png} (100%) rename assets/sects/{噬魔宗_2.png => sect_14_2.png} (100%) rename assets/sects/{噬魔宗_3.png => sect_14_3.png} (100%) rename assets/sects/{明心剑宗_0.png => sect_1_0.png} (100%) rename assets/sects/{明心剑宗_1.png => sect_1_1.png} (100%) rename assets/sects/{明心剑宗_2.png => sect_1_2.png} (100%) rename assets/sects/{明心剑宗_3.png => sect_1_3.png} (100%) rename assets/sects/{百兽宗.png => sect_2.png} (100%) rename assets/sects/{百兽宗_0.png => sect_2_0.png} (100%) rename assets/sects/{百兽宗_1.png => sect_2_1.png} (100%) rename assets/sects/{百兽宗_2.png => sect_2_2.png} (100%) rename assets/sects/{百兽宗_3.png => sect_2_3.png} (100%) rename assets/sects/{水镜宗.png => sect_3.png} (100%) rename assets/sects/{水镜宗_0.png => sect_3_0.png} (100%) rename assets/sects/{水镜宗_1.png => sect_3_1.png} (100%) rename assets/sects/{水镜宗_2.png => sect_3_2.png} (100%) rename assets/sects/{水镜宗_3.png => sect_3_3.png} (100%) rename assets/sects/{冥王宗.png => sect_4.png} (100%) rename assets/sects/{冥王宗_0.png => sect_4_0.png} (100%) rename assets/sects/{冥王宗_1.png => sect_4_1.png} (100%) rename assets/sects/{冥王宗_2.png => sect_4_2.png} (100%) rename assets/sects/{冥王宗_3.png => sect_4_3.png} (100%) rename assets/sects/{朱勾宗.png => sect_5.png} (100%) rename assets/sects/{朱勾宗_0.png => sect_5_0.png} (100%) rename assets/sects/{朱勾宗_1.png => sect_5_1.png} (100%) rename assets/sects/{朱勾宗_2.png => sect_5_2.png} (100%) rename assets/sects/{朱勾宗_3.png => sect_5_3.png} (100%) rename assets/sects/{合欢宗.png => sect_6.png} (100%) rename assets/sects/{合欢宗_0.png => sect_6_0.png} (100%) rename assets/sects/{合欢宗_1.png => sect_6_1.png} (100%) rename assets/sects/{合欢宗_2.png => sect_6_2.png} (100%) rename assets/sects/{合欢宗_3.png => sect_6_3.png} (100%) rename assets/sects/{镇魂宗.png => sect_7.png} (100%) rename assets/sects/{镇魂宗_0.png => sect_7_0.png} (100%) rename assets/sects/{镇魂宗_1.png => sect_7_1.png} (100%) rename assets/sects/{镇魂宗_2.png => sect_7_2.png} (100%) rename assets/sects/{镇魂宗_3.png => sect_7_3.png} (100%) rename assets/sects/{幽魂噬影宗.png => sect_8.png} (100%) rename assets/sects/{幽魂噬影宗_0.png => sect_8_0.png} (100%) rename assets/sects/{幽魂噬影宗_1.png => sect_8_1.png} (100%) rename assets/sects/{幽魂噬影宗_2.png => sect_8_2.png} (100%) rename assets/sects/{幽魂噬影宗_3.png => sect_8_3.png} (100%) rename assets/sects/{千帆城.png => sect_9.png} (100%) rename assets/sects/{千帆城_0.png => sect_9_0.png} (100%) rename assets/sects/{千帆城_1.png => sect_9_1.png} (100%) rename assets/sects/{千帆城_2.png => sect_9_2.png} (100%) rename assets/sects/{千帆城_3.png => sect_9_3.png} (100%) create mode 100644 static/templates/history_influence_item.txt rename static/templates/{history_influence.txt => history_influence_map.txt} (64%) create mode 100644 static/templates/history_influence_sect.txt create mode 100644 tools/map_creator/README_MIGRATION.md create mode 100644 tools/migrate_assets_and_map.py 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 @@
@@ -598,6 +598,31 @@ createApp({ requestAnimationFrame(drawLoop); } + // --- Helper Functions --- + function getRegionPreviewSrc(region) { + const tile = region.bindTile; + const type = region.bindTileType; + + // For sect/city, use first slice (_0) + if (type === 'sect') { + return `/sects/${tile}_0.png`; + } else if (type === 'city') { + // city tiles might have jpg or png, check cityTilesMap + const baseFile = cityTilesMap.value[tile]; + if (baseFile) { + const ext = baseFile.split('.').pop(); + return `/cities/${tile}_0.${ext}`; + } + return `/cities/${tile}_0.png`; + } else { + // For cultivate (cave/ruin) and normal tiles + if (tile === 'cave' || tile === 'ruin') { + return `/tiles/${tile}_0.png`; + } + return `/tiles/${tile}.png`; + } + } + // --- Actions --- async function saveMap() { const payload = { @@ -626,6 +651,7 @@ createApp({ saveMap, hoverX, hoverY, isShiftDown, selectTile, + getRegionPreviewSrc, canvas, container }; } diff --git a/tools/map_creator/tile_map.csv b/tools/map_creator/tile_map.csv index 2d06818..eca05e1 100644 --- a/tools/map_creator/tile_map.csv +++ b/tools/map_creator/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,揽月城_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,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,揽月城_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,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,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,青云城_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,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,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,翠林城_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,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,沙月城_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,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,沙月城_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,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,沧澜城_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,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/tools/migrate_assets_and_map.py b/tools/migrate_assets_and_map.py new file mode 100644 index 0000000..66ff567 --- /dev/null +++ b/tools/migrate_assets_and_map.py @@ -0,0 +1,138 @@ +import os +import csv +import shutil +from pathlib import Path + +# Configs +CONFIG_DIR = Path("static/game_configs") +ASSETS_DIR = Path("assets/sects") +TILE_MAP_PATH = CONFIG_DIR / "tile_map.csv" +SECT_PATH = CONFIG_DIR / "sect.csv" + +def load_sect_mapping(): + """Load sect name -> id mapping""" + mapping = {} + if not SECT_PATH.exists(): + print(f"Error: {SECT_PATH} not found") + return {} + + with open(SECT_PATH, 'r', encoding='utf-8') as f: + reader = csv.reader(f) + header = next(reader) + next(reader) # skip comment + + try: + id_idx = header.index('id') + name_idx = header.index('name') + except ValueError: + print("Error parsing sect.csv header") + return {} + + for row in reader: + if len(row) > max(id_idx, name_idx): + mapping[row[name_idx].strip()] = row[id_idx].strip() + return mapping + +def rename_assets(mapping): + """Rename assets from {name}_{i}.png to sect_{id}_{i}.png""" + print("\n--- Renaming Assets ---") + if not ASSETS_DIR.exists(): + print(f"Assets dir {ASSETS_DIR} not found") + return + + count = 0 + for filename in os.listdir(ASSETS_DIR): + if not filename.endswith(".png"): + continue + + # Parse filename: Name_Index.png + # Handle names with underscores? Assuming names don't have _ for now, or match longest prefix + # Actually standard format seems to be Name_0.png + + name_part = None + index_part = None + + # Try to find a matching sect name + matched_sect = None + for sect_name in mapping.keys(): + if filename.startswith(sect_name + "_"): + # Check if the rest is a number + suffix = filename[len(sect_name)+1:] # remove name and _ + if suffix.replace(".png", "").isdigit(): + matched_sect = sect_name + index_part = suffix.replace(".png", "") + break + + if matched_sect: + sect_id = mapping[matched_sect] + new_name = f"sect_{sect_id}_{index_part}.png" + old_path = ASSETS_DIR / filename + new_path = ASSETS_DIR / new_name + + if old_path != new_path: + print(f"Renaming: {filename} -> {new_name}") + shutil.move(old_path, new_path) + count += 1 + else: + # Maybe it is just Name.png (icon)? + if filename.replace(".png", "") in mapping: + sect_name = filename.replace(".png", "") + sect_id = mapping[sect_name] + new_name = f"sect_{sect_id}.png" # Icon + old_path = ASSETS_DIR / filename + new_path = ASSETS_DIR / new_name + print(f"Renaming Icon: {filename} -> {new_name}") + shutil.move(old_path, new_path) + count += 1 + else: + # check if already renamed + if not filename.startswith("sect_"): + print(f"Skipping unknown file: {filename}") + + print(f"Renamed {count} files.") + +def update_tile_map(mapping): + """Update tile_map.csv replacing Name_Index with sect_{id}_{index}""" + print("\n--- Updating Tile Map ---") + if not TILE_MAP_PATH.exists(): + print(f"{TILE_MAP_PATH} not found") + return + + with open(TILE_MAP_PATH, 'r', encoding='utf-8') as f: + content = f.read() + + new_content = content + count = 0 + + # Sort mapping by key length desc to avoid partial replacements (though names should be distinct) + sorted_sects = sorted(mapping.keys(), key=len, reverse=True) + + for sect_name in sorted_sects: + sect_id = mapping[sect_name] + # Iterate indices 0-3 + for i in range(4): + old_str = f"{sect_name}_{i}" + new_str = f"sect_{sect_id}_{i}" + if old_str in new_content: + new_content = new_content.replace(old_str, new_str) + count += 1 + + if content != new_content: + with open(TILE_MAP_PATH, 'w', encoding='utf-8') as f: + f.write(new_content) + print(f"Updated tile_map.csv (approx {count} replacements)") + else: + print("No changes in tile_map.csv") + +def main(): + mapping = load_sect_mapping() + if not mapping: + print("No mapping loaded") + return + + print(f"Loaded {len(mapping)} sects") + rename_assets(mapping) + update_tile_map(mapping) + +if __name__ == "__main__": + main() diff --git a/web/src/components/game/MapLayer.vue b/web/src/components/game/MapLayer.vue index 1f944ec..cbcaab1 100644 --- a/web/src/components/game/MapLayer.vue +++ b/web/src/components/game/MapLayer.vue @@ -215,27 +215,31 @@ async function renderMap() { async function preloadRegionTextures() { const regions = Array.from(worldStore.regions.values()); - // Sects - const sectNames = Array.from( + // Sects - use sect_id instead of sect_name + const sectIds = Array.from( new Set( regions - .filter(region => region.type === 'sect' && region.sect_name) - .map(region => region.sect_name as string) + .filter(region => region.type === 'sect' && region.sect_id) + .map(region => region.sect_id as number) ) ) - // Cities - const cityNames = Array.from( + // Cities - use city id (convert to number) + const cityIds = Array.from( new Set( regions - .filter(region => region.type === 'city') - .map(region => region.name) + .filter(region => region.type === 'city' && region.id) + .map(region => { + const id = typeof region.id === 'string' ? parseInt(region.id) : region.id + return isNaN(id) ? null : id + }) + .filter(id => id !== null) ) - ) + ) as number[] await Promise.all([ - ...sectNames.map(name => loadSectTexture(name)), - ...cityNames.map(name => loadCityTexture(name)) + ...sectIds.map(id => loadSectTexture(id)), + ...cityIds.map(id => loadCityTexture(id)) ]) } @@ -244,16 +248,18 @@ function renderLargeRegions() { for (const region of regions) { let baseName: string | null = null; - if (region.type === 'city') { - baseName = region.name - } else if (region.type === 'sect' && region.sect_name) { - baseName = region.sect_name - } else if (region.type === 'cultivate') { - if (region.name.includes('遗迹')) { - baseName = 'ruin' - } else if (region.name.includes('洞') || region.name.includes('府') || region.name.includes('秘境') || region.name.includes('宫')) { - baseName = 'cave' + if (region.type === 'city' && region.id) { + // Use city_id instead of city_name (convert to number) + const cityId = typeof region.id === 'string' ? parseInt(region.id) : region.id + if (!isNaN(cityId)) { + baseName = `city_${cityId}` } + } else if (region.type === 'sect' && region.sect_id) { + // Use sect_id instead of sect_name + baseName = `sect_${region.sect_id}` + } else if (region.type === 'cultivate' && region.sub_type) { + // Use sub_type from backend instead of name matching + baseName = region.sub_type // "cave" or "ruin" } if (baseName && mapContainer.value) { diff --git a/web/src/components/game/composables/useTextures.ts b/web/src/components/game/composables/useTextures.ts index 5475032..8a54ea4 100644 --- a/web/src/components/game/composables/useTextures.ts +++ b/web/src/components/game/composables/useTextures.ts @@ -166,21 +166,18 @@ export function useTextures() { } // 动态加载宗门纹理(按需)- 加载4个切片用于渲染 - const loadSectTexture = async (sectName: string) => { + const loadSectTexture = async (sectId: number) => { // 加载4个切片 _0, _1, _2, _3 const slicePromises = [0, 1, 2, 3].map(async (i) => { - const key = `${sectName}_${i}` + const key = `sect_${sectId}_${i}` if (textures.value[key]) return - const url = `/assets/sects/${sectName}_${i}.png` + const url = `/assets/sects/sect_${sectId}_${i}.png` try { const tex = await Assets.load(url) textures.value[key] = tex } catch (e) { - // 尝试 URL 编码后加载 - const encodedUrl = `/assets/sects/${encodeURIComponent(`${sectName}_${i}`)}.png` - const tex = await Assets.load(encodedUrl) - textures.value[key] = tex + console.warn(`Failed to load sect texture: ${url}`, e) } }) @@ -188,29 +185,22 @@ export function useTextures() { } // 动态加载城市纹理(按需)- 加载4个切片用于渲染 - const loadCityTexture = async (cityName: string) => { + const loadCityTexture = async (cityId: number) => { // 加载4个切片 _0, _1, _2, _3 const extensions = ['.jpg', '.png'] const slicePromises = [0, 1, 2, 3].map(async (i) => { - const key = `${cityName}_${i}` + const key = `city_${cityId}_${i}` if (textures.value[key]) return for (const ext of extensions) { - const url = `/assets/cities/${cityName}_${i}${ext}` + const url = `/assets/cities/city_${cityId}_${i}${ext}` try { const tex = await Assets.load(url) textures.value[key] = tex return } catch (e) { - try { - const encodedUrl = `/assets/cities/${encodeURIComponent(`${cityName}_${i}`)}${ext}` - const tex = await Assets.load(encodedUrl) - textures.value[key] = tex - return - } catch (e2) { - // continue - } + console.warn(`Failed to load city texture: ${url}`) } } }) diff --git a/web/src/types/core.ts b/web/src/types/core.ts index fb96cff..347f81a 100644 --- a/web/src/types/core.ts +++ b/web/src/types/core.ts @@ -145,7 +145,8 @@ export type MapMatrix = string[][]; export interface RegionSummary extends EntityBase, Coordinates { type: string; - sect_name?: string; + sect_id?: number; + sub_type?: string; // for cultivate regions: "cave" or "ruin" } export interface RegionDetail extends EntityBase {