add treasures
This commit is contained in:
@@ -19,6 +19,9 @@ class Move(DefineAction, ChunkActionMixin):
|
||||
world = self.world
|
||||
# 基于境界的移动步长:曼哈顿限制,优先斜向
|
||||
step = getattr(self.avatar, "move_step_length", 1)
|
||||
# 附加移动步长加成
|
||||
extra_raw = self.avatar.effects.get("extra_move_step", 0)
|
||||
step += int(extra_raw or 0)
|
||||
clamped_dx, clamped_dy = clamp_manhattan_with_diagonal_priority(delta_x, delta_y, step)
|
||||
|
||||
new_x = self.avatar.pos_x + clamped_dx
|
||||
|
||||
@@ -23,6 +23,7 @@ from src.classes.effect import _merge_effects
|
||||
from src.classes.alignment import Alignment
|
||||
from src.classes.persona import Persona, personas_by_id, get_random_compatible_personas
|
||||
from src.classes.item import Item
|
||||
from src.classes.treasure import Treasure
|
||||
from src.classes.magic_stone import MagicStone
|
||||
from src.classes.hp_and_mp import HP, MP, HP_MAX_BY_REALM, MP_MAX_BY_REALM
|
||||
from src.utils.id_generator import get_avatar_id
|
||||
@@ -88,6 +89,8 @@ class Avatar:
|
||||
sect: Sect | None = None
|
||||
# 外貌(1~10级),创建时随机生成
|
||||
appearance: Appearance = field(default_factory=get_random_appearance)
|
||||
# 装备的法宝(仅一个)
|
||||
treasure: Optional[Treasure] = None
|
||||
# 当月/当步新设动作标记:在 commit_next_plan 设为 True,首次 tick_action 后清为 False
|
||||
_new_action_set_this_step: bool = False
|
||||
# 不缓存 effects;实时从宗门与功法合并
|
||||
@@ -136,6 +139,9 @@ class Avatar:
|
||||
merged = _merge_effects(merged, self.technique.effects)
|
||||
# 来自灵根
|
||||
merged = _merge_effects(merged, self.root.effects)
|
||||
# 来自法宝
|
||||
if self.treasure is not None:
|
||||
merged = _merge_effects(merged, self.treasure.effects)
|
||||
return merged
|
||||
|
||||
|
||||
@@ -172,6 +178,12 @@ class Avatar:
|
||||
items_info = ",".join([f"{item.get_info()}x{quantity}" for item, quantity in self.items.items()]) if self.items else "无"
|
||||
appearance_info = self.appearance.get_info()
|
||||
|
||||
# 法宝信息:detailed 使用 get_detailed_info;简略使用 get_info
|
||||
if self.treasure is not None:
|
||||
treasures_info = self.treasure.get_detailed_info() if detailed else self.treasure.get_info()
|
||||
else:
|
||||
treasures_info = "无"
|
||||
|
||||
return {
|
||||
"id": self.id,
|
||||
"名字": self.name,
|
||||
@@ -190,6 +202,7 @@ class Avatar:
|
||||
"个性": personas_info,
|
||||
"物品": items_info,
|
||||
"外貌": appearance_info,
|
||||
"法宝": treasures_info,
|
||||
}
|
||||
|
||||
def __str__(self) -> str:
|
||||
@@ -579,7 +592,8 @@ class Avatar:
|
||||
relation = self.get_relation(other_avatar)
|
||||
relation_str = str(relation)
|
||||
sect_str = other_avatar.sect.name if other_avatar.sect is not None else "散修"
|
||||
return f"{other_avatar.name},境界:{other_avatar.cultivation_progress.get_info()},关系:{relation_str},阵营:{other_avatar.alignment},宗门:{sect_str},外貌:{other_avatar.appearance.get_info()}"
|
||||
tr_str = other_avatar.treasure.get_info() if other_avatar.treasure is not None else "无"
|
||||
return f"{other_avatar.name},境界:{other_avatar.cultivation_progress.get_info()},关系:{relation_str},阵营:{other_avatar.alignment},宗门:{sect_str},法宝:{tr_str},外貌:{other_avatar.appearance.get_info()}"
|
||||
|
||||
def update_time_effect(self) -> None:
|
||||
"""
|
||||
@@ -597,28 +611,4 @@ class Avatar:
|
||||
"""
|
||||
return self.cultivation_progress.get_move_step()
|
||||
|
||||
def get_new_avatar_from_ordinary(world: World, current_month_stamp: MonthStamp, name: str, age: Age):
|
||||
"""
|
||||
从凡人中来的新修士
|
||||
这代表其境界为最低
|
||||
"""
|
||||
# 生成短ID,替代UUID4
|
||||
avatar_id = get_avatar_id()
|
||||
|
||||
birth_month_stamp = current_month_stamp - age.age * 12 + random.randint(0, 11) # 在出生年内随机选择月份
|
||||
cultivation_progress = CultivationProgress(0)
|
||||
pos_x = random.randint(0, world.map.width - 1)
|
||||
pos_y = random.randint(0, world.map.height - 1)
|
||||
gender = random.choice(list(Gender))
|
||||
|
||||
return Avatar(
|
||||
world=world,
|
||||
name=name,
|
||||
id=avatar_id,
|
||||
birth_month_stamp=MonthStamp(birth_month_stamp),
|
||||
age=age,
|
||||
gender=gender,
|
||||
cultivation_progress=cultivation_progress,
|
||||
pos_x=pos_x,
|
||||
pos_y=pos_y,
|
||||
)
|
||||
|
||||
|
||||
@@ -38,7 +38,10 @@ def get_base_strength(self_avatar: "Avatar") -> float:
|
||||
grade_points = 0.0
|
||||
if self_avatar.technique is not None:
|
||||
grade_points = _GRADE_POINTS.get(self_avatar.technique.grade, 0.0)
|
||||
return strength_from_level + grade_points
|
||||
# 来自效果的额外战斗力点数(例如法宝带来的被动加成)
|
||||
extra_raw = self_avatar.effects.get("extra_battle_strength_points", 0)
|
||||
extra_points = float(extra_raw or 0.0)
|
||||
return strength_from_level + grade_points + extra_points
|
||||
|
||||
|
||||
def _combat_strength_vs(opponent: "Avatar", self_avatar: "Avatar") -> float:
|
||||
|
||||
@@ -85,6 +85,10 @@ class DualCultivation(MutualAction):
|
||||
jitter = random.uniform(-0.2, 0.2)
|
||||
factor = max(3.0, min(5.0, factor + jitter))
|
||||
exp_gain = int(base * factor)
|
||||
# 附加“双修经验提升”效果(如法宝)
|
||||
extra_raw = initiator.effects.get("extra_dual_cultivation_exp", 0)
|
||||
extra = int(extra_raw or 0)
|
||||
exp_gain += extra
|
||||
initiator.cultivation_progress.add_exp(exp_gain)
|
||||
self._dual_exp_gain = exp_gain
|
||||
|
||||
|
||||
@@ -28,7 +28,10 @@ def get_avatar_observation_radius(avatar: "Avatar") -> int:
|
||||
"""
|
||||
获取角色的感知半径。
|
||||
"""
|
||||
return get_observation_radius_by_realm(avatar.cultivation_progress.realm)
|
||||
base = get_observation_radius_by_realm(avatar.cultivation_progress.realm)
|
||||
extra_raw = avatar.effects.get("extra_observation_radius", 0)
|
||||
extra = int(extra_raw or 0)
|
||||
return max(1, base + extra)
|
||||
|
||||
|
||||
def is_within_observation(initiator: "Avatar", other: "Avatar") -> bool:
|
||||
|
||||
78
src/classes/treasure.py
Normal file
78
src/classes/treasure.py
Normal file
@@ -0,0 +1,78 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Optional, Dict
|
||||
|
||||
from src.utils.df import game_configs
|
||||
from src.classes.effect import load_effect_from_str
|
||||
from src.classes.sect import Sect, sects_by_id
|
||||
|
||||
|
||||
@dataclass
|
||||
class Treasure:
|
||||
"""
|
||||
法宝:配置驱动,暂不挂接到 Avatar。
|
||||
字段与 static/game_configs/treasure.csv 对应:
|
||||
- sect_id:对应宗门ID(见 sect.csv);允许为空表示无特定宗门归属
|
||||
- effects:解析为 dict,用于未来与 Avatar.effects 合并
|
||||
"""
|
||||
id: int
|
||||
name: str
|
||||
sect_id: Optional[int]
|
||||
desc: str
|
||||
effects: dict[str, object] = field(default_factory=dict)
|
||||
sect: Optional[Sect] = None
|
||||
|
||||
def get_info(self) -> str:
|
||||
return self.name
|
||||
|
||||
def get_detailed_info(self) -> str:
|
||||
sect_name = self.sect.name if self.sect is not None else "散修可用"
|
||||
return f"{self.name}(宗门:{sect_name}){self.desc}"
|
||||
|
||||
|
||||
def _load_treasures() -> tuple[Dict[int, Treasure], Dict[str, Treasure], Dict[int, Treasure]]:
|
||||
"""从配表加载 treasure 数据。
|
||||
返回:(按ID、按名称、按宗门ID 的映射)。
|
||||
若同一宗门配置多个法宝,按首次出现保留(每门至多一个)。
|
||||
"""
|
||||
treasures_by_id: Dict[int, Treasure] = {}
|
||||
treasures_by_name: Dict[str, Treasure] = {}
|
||||
treasures_by_sect_id: Dict[int, Treasure] = {}
|
||||
|
||||
df = game_configs.get("treasure")
|
||||
if df is None:
|
||||
return treasures_by_id, treasures_by_name, treasures_by_sect_id
|
||||
|
||||
for _, row in df.iterrows():
|
||||
raw_sect = row.get("sect_id")
|
||||
sect_id: Optional[int] = None
|
||||
if raw_sect is not None and str(raw_sect).strip() and str(raw_sect).strip() != "nan":
|
||||
sect_id = int(float(raw_sect))
|
||||
|
||||
effects = load_effect_from_str(row.get("effects", ""))
|
||||
|
||||
sect_obj: Optional[Sect] = sects_by_id.get(int(sect_id)) if sect_id is not None else None
|
||||
|
||||
t = Treasure(
|
||||
id=int(row["id"]),
|
||||
name=str(row["name"]),
|
||||
sect_id=sect_id,
|
||||
desc=str(row.get("desc", "")),
|
||||
effects=effects,
|
||||
sect=sect_obj,
|
||||
)
|
||||
|
||||
treasures_by_id[t.id] = t
|
||||
treasures_by_name[t.name] = t
|
||||
if t.sect_id is not None and t.sect_id not in treasures_by_sect_id:
|
||||
treasures_by_sect_id[t.sect_id] = t
|
||||
|
||||
return treasures_by_id, treasures_by_name, treasures_by_sect_id
|
||||
|
||||
|
||||
treasures_by_id, treasures_by_name, treasures_by_sect_id = _load_treasures()
|
||||
|
||||
|
||||
for name, treasure in treasures_by_name.items():
|
||||
print(name, treasure.sect.name)
|
||||
@@ -10,6 +10,7 @@ sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))
|
||||
# 依赖项目内部模块
|
||||
from src.front.front import Front
|
||||
from src.sim.simulator import Simulator
|
||||
from src.sim.new_avatar import make_avatars
|
||||
from src.classes.world import World
|
||||
from src.classes.map import Map
|
||||
from src.classes.tile import TileType
|
||||
@@ -68,94 +69,12 @@ def sample_existed_sects(all_sects: Sequence, needed_sects: int) -> list:
|
||||
return result
|
||||
|
||||
def make_avatars(world: World, count: int = 12, current_month_stamp: MonthStamp = MonthStamp(100 * 12), existed_sects: Optional[List] = None) -> dict[str, Avatar]:
|
||||
avatars: dict[str, Avatar] = {}
|
||||
width, height = world.map.width, world.map.height
|
||||
# 依据配置决定宗门人数占比:当 init_npc_num > sect_num 时启用宗门逻辑
|
||||
num_total = int(count)
|
||||
use_sects = bool(existed_sects)
|
||||
# 约 2/3 为宗门弟子,1/3 为散修
|
||||
sect_member_target = int(num_total * 2 / 3) if use_sects else 0
|
||||
# 本局启用的宗门(已在上方确定)
|
||||
# 在地图上添加本局宗门总部
|
||||
# 迁移到 src/sim/new_avatar.py
|
||||
from src.sim.new_avatar import make_avatars as _new_make
|
||||
# 在地图上添加本局宗门总部(保持原行为)
|
||||
if existed_sects:
|
||||
add_sect_headquarters(world.map, existed_sects)
|
||||
# 统计将要分配的宗门成员数量(用于均分)
|
||||
sect_member_count = 0
|
||||
sect_member_counts_by_id: dict[int, int] = {s.id: 0 for s in existed_sects} if existed_sects else {}
|
||||
|
||||
for i in range(count):
|
||||
# 随机生成年龄,范围从16到60岁
|
||||
age_years = random.randint(16, 60)
|
||||
# 根据当前时间戳和年龄计算出生时间戳
|
||||
birth_month_stamp = current_month_stamp - age_years * 12 + random.randint(0, 11) # 在出生年内随机选择月份
|
||||
gender = random_gender()
|
||||
# 分配宗门或散修
|
||||
assigned_sect = None
|
||||
if use_sects and sect_member_count < sect_member_target and existed_sects:
|
||||
# 均分到各宗门:选择当前成员最少的宗门,若并列则随机
|
||||
min_count = min(sect_member_counts_by_id.values()) if sect_member_counts_by_id else 0
|
||||
candidates = [s for s in existed_sects if sect_member_counts_by_id.get(s.id, 0) == min_count]
|
||||
assigned_sect = random.choice(candidates)
|
||||
sect_member_counts_by_id[assigned_sect.id] = sect_member_counts_by_id.get(assigned_sect.id, 0) + 1
|
||||
sect_member_count += 1
|
||||
# 根据宗门生成姓名
|
||||
name = get_random_name_for_sect(gender, assigned_sect)
|
||||
|
||||
# 随机生成level,范围从0到120(对应四个大境界)
|
||||
level = random.randint(0, 120)
|
||||
cultivation_progress = CultivationProgress(level)
|
||||
|
||||
# 创建Age实例,传入年龄与当前境界
|
||||
age = Age(age_years, cultivation_progress.realm)
|
||||
|
||||
# 找一个非海域的出生点
|
||||
for _ in range(200):
|
||||
x = random.randint(0, width - 1)
|
||||
y = random.randint(0, height - 1)
|
||||
t = world.map.get_tile(x, y)
|
||||
if t.type not in (TileType.WATER, TileType.SEA, TileType.MOUNTAIN, TileType.VOLCANO, TileType.SWAMP, TileType.CAVE, TileType.RUINS):
|
||||
break
|
||||
else:
|
||||
x, y = random.randint(0, width - 1), random.randint(0, height - 1)
|
||||
|
||||
avatar = Avatar(
|
||||
world=world,
|
||||
name=name,
|
||||
id=get_avatar_id(),
|
||||
birth_month_stamp=MonthStamp(birth_month_stamp),
|
||||
age=age,
|
||||
gender=gender,
|
||||
cultivation_progress=cultivation_progress,
|
||||
pos_x=x,
|
||||
pos_y=y,
|
||||
root=random.choice(list(Root)), # 随机选择灵根
|
||||
sect=assigned_sect,
|
||||
)
|
||||
avatar.tile = world.map.get_tile(x, y)
|
||||
# 依据宗门设定阵营(若有宗门则与宗门阵营一致,否则保留默认随机)
|
||||
if assigned_sect is not None:
|
||||
avatar.alignment = assigned_sect.alignment
|
||||
# 宗门弟子:按宗门功法随机
|
||||
t = get_technique_by_sect(assigned_sect)
|
||||
avatar.technique = t
|
||||
# 将灵根改为功法对应灵根(邪功法不变)
|
||||
mapped_root = attribute_to_root(avatar.technique.attribute)
|
||||
if mapped_root is not None:
|
||||
avatar.root = mapped_root
|
||||
avatars[avatar.id] = avatar
|
||||
# # —— 为演示添加少量示例关系 ——
|
||||
avatar_list = list(avatars.values())
|
||||
if len(avatar_list) >= 2:
|
||||
avatar_list[0].set_relation(avatar_list[1], Relation.ENEMY)
|
||||
if len(avatar_list) >= 4:
|
||||
avatar_list[2].set_relation(avatar_list[3], Relation.FRIEND)
|
||||
if len(avatar_list) >= 6:
|
||||
# 师徒(有向):第5位是师傅,第6位是徒弟
|
||||
avatar_list[4].set_relation(avatar_list[5], Relation.MASTER)
|
||||
if len(avatar_list) >= 8:
|
||||
# 道侣
|
||||
avatar_list[6].set_relation(avatar_list[7], Relation.LOVERS)
|
||||
return avatars
|
||||
return _new_make(world, count=count, current_month_stamp=current_month_stamp, existed_sects=existed_sects)
|
||||
|
||||
|
||||
async def main():
|
||||
|
||||
137
src/sim/new_avatar.py
Normal file
137
src/sim/new_avatar.py
Normal file
@@ -0,0 +1,137 @@
|
||||
import random
|
||||
from typing import List, Optional, Dict
|
||||
|
||||
from src.classes.world import World
|
||||
from src.classes.map import Map
|
||||
from src.classes.tile import TileType
|
||||
from src.classes.avatar import Avatar, Gender
|
||||
from src.classes.calendar import MonthStamp
|
||||
from src.classes.cultivation import CultivationProgress
|
||||
from src.classes.root import Root
|
||||
from src.classes.age import Age
|
||||
from src.utils.names import get_random_name_for_sect
|
||||
from src.utils.id_generator import get_avatar_id
|
||||
from src.classes.sect import Sect
|
||||
from src.classes.alignment import Alignment
|
||||
from src.classes.relation import Relation
|
||||
from src.classes.technique import get_technique_by_sect, attribute_to_root
|
||||
from src.classes.treasure import treasures_by_sect_id
|
||||
|
||||
|
||||
def random_gender() -> Gender:
|
||||
return Gender.MALE if random.random() < 0.5 else Gender.FEMALE
|
||||
|
||||
|
||||
def get_new_avatar_from_ordinary(world: World, current_month_stamp: MonthStamp, name: str, age: Age) -> Avatar:
|
||||
"""
|
||||
从凡人中来的新修士:最低境界、随机位置,不分配宗门/法宝。
|
||||
"""
|
||||
avatar_id = get_avatar_id()
|
||||
birth_month_stamp = current_month_stamp - age.age * 12 + random.randint(0, 11)
|
||||
cultivation_progress = CultivationProgress(0)
|
||||
pos_x = random.randint(0, world.map.width - 1)
|
||||
pos_y = random.randint(0, world.map.height - 1)
|
||||
gender = random.choice(list(Gender))
|
||||
return Avatar(
|
||||
world=world,
|
||||
name=name,
|
||||
id=avatar_id,
|
||||
birth_month_stamp=MonthStamp(birth_month_stamp),
|
||||
age=age,
|
||||
gender=gender,
|
||||
cultivation_progress=cultivation_progress,
|
||||
pos_x=pos_x,
|
||||
pos_y=pos_y,
|
||||
)
|
||||
|
||||
|
||||
def make_avatars(
|
||||
world: World,
|
||||
count: int = 12,
|
||||
current_month_stamp: MonthStamp = MonthStamp(100 * 12),
|
||||
existed_sects: Optional[List[Sect]] = None,
|
||||
) -> dict[str, Avatar]:
|
||||
avatars: dict[str, Avatar] = {}
|
||||
width, height = world.map.width, world.map.height
|
||||
|
||||
num_total = int(count)
|
||||
use_sects = bool(existed_sects)
|
||||
# 约 2/3 为宗门弟子,1/3 为散修
|
||||
sect_member_target = int(num_total * 2 / 3) if use_sects else 0
|
||||
|
||||
# 统计将要分配的宗门成员数量(用于均分)
|
||||
sect_member_count = 0
|
||||
sect_member_counts_by_id: dict[int, int] = {s.id: 0 for s in existed_sects} if existed_sects else {}
|
||||
|
||||
# 本局中“已给出宗门法宝”的标记,确保每个宗门最多一件且仅首次分配
|
||||
sect_treasure_assigned: Dict[int, bool] = {}
|
||||
|
||||
for i in range(count):
|
||||
age_years = random.randint(16, 60)
|
||||
birth_month_stamp = current_month_stamp - age_years * 12 + random.randint(0, 11)
|
||||
gender = random_gender()
|
||||
|
||||
# 分配宗门或散修
|
||||
assigned_sect: Optional[Sect] = None
|
||||
if use_sects and sect_member_count < sect_member_target and existed_sects:
|
||||
min_count = min(sect_member_counts_by_id.values()) if sect_member_counts_by_id else 0
|
||||
candidates = [s for s in existed_sects if sect_member_counts_by_id.get(s.id, 0) == min_count]
|
||||
assigned_sect = random.choice(candidates)
|
||||
sect_member_counts_by_id[assigned_sect.id] = sect_member_counts_by_id.get(assigned_sect.id, 0) + 1
|
||||
sect_member_count += 1
|
||||
|
||||
name = get_random_name_for_sect(gender, assigned_sect)
|
||||
|
||||
level = random.randint(0, 120)
|
||||
cultivation_progress = CultivationProgress(level)
|
||||
age = Age(age_years, cultivation_progress.realm)
|
||||
|
||||
# 出生点:
|
||||
x, y = random.randint(0, width - 1), random.randint(0, height - 1)
|
||||
|
||||
avatar = Avatar(
|
||||
world=world,
|
||||
name=name,
|
||||
id=get_avatar_id(),
|
||||
birth_month_stamp=MonthStamp(birth_month_stamp),
|
||||
age=age,
|
||||
gender=gender,
|
||||
cultivation_progress=cultivation_progress,
|
||||
pos_x=x,
|
||||
pos_y=y,
|
||||
root=random.choice(list(Root)),
|
||||
sect=assigned_sect,
|
||||
)
|
||||
|
||||
avatar.tile = world.map.get_tile(x, y)
|
||||
|
||||
if assigned_sect is not None:
|
||||
avatar.alignment = assigned_sect.alignment
|
||||
avatar.technique = get_technique_by_sect(assigned_sect)
|
||||
|
||||
# 若该宗门有法宝,且本局尚未分配过,则给该宗门第一个生成的弟子分配法宝
|
||||
treasure = treasures_by_sect_id.get(assigned_sect.id)
|
||||
if treasure is not None and not sect_treasure_assigned.get(assigned_sect.id, False):
|
||||
avatar.treasure = treasure
|
||||
sect_treasure_assigned[assigned_sect.id] = True
|
||||
|
||||
mapped_root = attribute_to_root(avatar.technique.attribute)
|
||||
if mapped_root is not None:
|
||||
avatar.root = mapped_root
|
||||
|
||||
avatars[avatar.id] = avatar
|
||||
|
||||
# 简单关系样例
|
||||
avatar_list = list(avatars.values())
|
||||
if len(avatar_list) >= 2:
|
||||
avatar_list[0].set_relation(avatar_list[1], Relation.ENEMY)
|
||||
if len(avatar_list) >= 4:
|
||||
avatar_list[2].set_relation(avatar_list[3], Relation.FRIEND)
|
||||
if len(avatar_list) >= 6:
|
||||
avatar_list[4].set_relation(avatar_list[5], Relation.MASTER)
|
||||
if len(avatar_list) >= 8:
|
||||
avatar_list[6].set_relation(avatar_list[7], Relation.LOVERS)
|
||||
|
||||
return avatars
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import random
|
||||
|
||||
from src.classes.calendar import Month, Year, MonthStamp
|
||||
from src.classes.avatar import Avatar, get_new_avatar_from_ordinary, Gender
|
||||
from src.classes.avatar import Avatar, Gender
|
||||
from src.sim.new_avatar import get_new_avatar_from_ordinary
|
||||
from src.classes.age import Age
|
||||
from src.classes.cultivation import Realm
|
||||
from src.classes.world import World
|
||||
|
||||
12
static/game_configs/treasure.csv
Normal file
12
static/game_configs/treasure.csv
Normal file
@@ -0,0 +1,12 @@
|
||||
id,name,sect_id,desc,effects
|
||||
,名称,所属宗门ID(见sect.csv),描述/提示词,效果键值对(不含花括号),例:"extra_move_step":1
|
||||
1,本命剑匣,1,以心御剑,匣启如霆,剑意随心破万法.,"extra_battle_strength_points": 3
|
||||
2,灵舟,9,小舟承灵气,御风渡海,千里一瞬.,"extra_move_step": 1
|
||||
3,千里镜,3,澄澈如镜,观千里之外,洞察先机.,"extra_observation_radius": 2
|
||||
4,镇魂钟,7,钟鸣摄魄,定魂镇邪,护心安魂.,"extra_battle_strength_points": 3; "extra_observation_radius": 1
|
||||
5,聚灵阵盘,5,刻阵成盘,聚纳灵机,修行事半功倍.,"extra_cultivate_exp": 50
|
||||
6,万魂幡,4,幡起万魂啾啾,阴风过境。(效果留空,后续配置),
|
||||
7,万欲同心结,6,情意同心,双修之道相互映照,修为更精进.,"extra_dual_cultivation_exp": 100
|
||||
8,影遁披风,8,融身影界,来去无踪,伏击出其不意.,"extra_move_step": 1; "extra_observation_radius": 1
|
||||
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 99.
|
Reference in New Issue
Block a user