update technique by sect
This commit is contained in:
@@ -13,7 +13,7 @@ from src.classes.tile import Tile
|
||||
from src.classes.region import Region
|
||||
from src.classes.cultivation import CultivationProgress
|
||||
from src.classes.root import Root
|
||||
from src.classes.technique import Technique, get_random_technique_for_avatar
|
||||
from src.classes.technique import Technique, get_random_technique_for_avatar, get_technique_by_sect
|
||||
from src.classes.age import Age
|
||||
from src.classes.event import NULL_EVENT, Event
|
||||
from src.classes.typings import ACTION_NAME, ACTION_PARAMS, ACTION_NAME_PARAMS_PAIRS, ACTION_NAME_PARAMS_PAIR
|
||||
@@ -102,9 +102,11 @@ class Avatar:
|
||||
if not self.personas:
|
||||
self.personas = get_random_compatible_personas(persona_num, avatar=self)
|
||||
|
||||
# 出生即随机赋予功法(与灵根/阵营/条件兼容)
|
||||
# 出生即按宗门分配功法:
|
||||
# - 散修:仅从无宗门功法抽样
|
||||
# - 有宗门:从“无宗门 + 本宗门”集合抽样
|
||||
if self.technique is None:
|
||||
self.technique = get_random_technique_for_avatar(self)
|
||||
self.technique = get_technique_by_sect(self.sect)
|
||||
|
||||
# 若未设定阵营,则依据宗门/无门无派规则设置,避免后续为 None
|
||||
if self.alignment is None:
|
||||
|
||||
@@ -36,6 +36,8 @@ class Sect:
|
||||
male_sect_given_names: list[str]
|
||||
female_sect_given_names: list[str]
|
||||
headquarter: SectHeadQuarter
|
||||
# 本宗关联的功法名称(来自 technique.csv 的 sect 列)
|
||||
technique_names: list[str]
|
||||
# 功法:在technique.csv中配置
|
||||
# TODO:法宝
|
||||
# TODO:宗内等级和称谓
|
||||
@@ -52,12 +54,23 @@ def _load_sects() -> tuple[dict[int, Sect], dict[str, Sect]]:
|
||||
sects_by_name: dict[str, Sect] = {}
|
||||
|
||||
df = game_configs["sect"]
|
||||
# 可能不存在 technique 配表或未添加 sect 列,做容错
|
||||
tech_df = game_configs.get("technique")
|
||||
assets_base = Path("assets/sects")
|
||||
for _, row in df.iterrows():
|
||||
image_path = assets_base / f"{row['name']}.png"
|
||||
male_given_names = _split_names(row["male_sect_given_names"])
|
||||
female_given_names = _split_names(row["female_sect_given_names"])
|
||||
|
||||
# 收集该宗门下配置的功法名称
|
||||
technique_names: list[str] = []
|
||||
if tech_df is not None and "sect" in tech_df.columns:
|
||||
technique_names = [
|
||||
str(tname).strip()
|
||||
for tname in tech_df.loc[tech_df["sect"] == row["name"], "name"].tolist()
|
||||
if str(tname).strip()
|
||||
]
|
||||
|
||||
sect = Sect(
|
||||
id=int(row["id"]),
|
||||
name=str(row["name"]),
|
||||
@@ -73,6 +86,7 @@ def _load_sects() -> tuple[dict[int, Sect], dict[str, Sect]]:
|
||||
desc=str(row.get("headquarter_desc", "")),
|
||||
image=image_path,
|
||||
),
|
||||
technique_names=technique_names,
|
||||
)
|
||||
sects_by_id[sect.id] = sect
|
||||
sects_by_name[sect.name] = sect
|
||||
|
||||
@@ -49,6 +49,8 @@ class Technique:
|
||||
prompt: str
|
||||
weight: float
|
||||
condition: str
|
||||
# 归属宗门名称;None/空表示无宗门要求(散修可修)
|
||||
sect: Optional[str] = None
|
||||
|
||||
def is_allowed_for(self, avatar) -> bool:
|
||||
if not self.condition:
|
||||
@@ -85,6 +87,8 @@ def loads() -> tuple[dict[int, Technique], dict[str, Technique]]:
|
||||
condition = "" if str(cond_val) == "nan" else str(cond_val).strip()
|
||||
weight_val = row.get("weight", 1)
|
||||
weight = float(str(weight_val)) if str(weight_val) != "nan" else 1.0
|
||||
sect_val = row.get("sect", "")
|
||||
sect = None if str(sect_val) == "nan" or str(sect_val).strip() == "" else str(sect_val).strip()
|
||||
t = Technique(
|
||||
id=int(row["id"]),
|
||||
name=name,
|
||||
@@ -93,6 +97,7 @@ def loads() -> tuple[dict[int, Technique], dict[str, Technique]]:
|
||||
prompt=str(row.get("prompt", "")),
|
||||
weight=weight,
|
||||
condition=condition,
|
||||
sect=sect,
|
||||
)
|
||||
techniques_by_id[t.id] = t
|
||||
techniques_by_name[t.name] = t
|
||||
@@ -157,6 +162,35 @@ def get_random_technique_for_avatar(avatar) -> Technique:
|
||||
return random.choices(candidates, weights=weights, k=1)[0]
|
||||
|
||||
|
||||
def get_technique_by_sect(sect) -> Technique:
|
||||
"""
|
||||
简化版:仅按宗门筛选并按权重抽样,不考虑灵根与 condition。
|
||||
- 散修(sect 为 None/空):只从无宗门要求(sect 为空)的功法中抽样;
|
||||
- 有宗门:从“无宗门 + 该宗门”的功法中抽样;
|
||||
若集合为空,则退回全量功法。
|
||||
"""
|
||||
import random
|
||||
|
||||
sect_name: Optional[str] = None
|
||||
if sect is not None:
|
||||
sect_name = getattr(sect, "name", sect)
|
||||
if isinstance(sect_name, str):
|
||||
sect_name = sect_name.strip() or None
|
||||
|
||||
allowed_sects: set[Optional[str]] = {None, ""}
|
||||
if sect_name is not None:
|
||||
allowed_sects.add(sect_name)
|
||||
|
||||
def _in_allowed_sect(t: Technique) -> bool:
|
||||
return (t.sect in allowed_sects) or (t.sect is None) or (t.sect == "")
|
||||
|
||||
candidates: List[Technique] = [t for t in techniques_by_id.values() if _in_allowed_sect(t)]
|
||||
if not candidates:
|
||||
candidates = list(techniques_by_id.values())
|
||||
weights = [max(0.0, t.weight) for t in candidates]
|
||||
return random.choices(candidates, weights=weights, k=1)[0]
|
||||
|
||||
|
||||
def get_grade_bonus(grade: TechniqueGrade) -> float:
|
||||
if grade is TechniqueGrade.UPPER:
|
||||
return 0.10
|
||||
@@ -198,3 +232,18 @@ def get_grade_advantage_bonus(attacker_grade: Optional[TechniqueGrade], defender
|
||||
return bonus
|
||||
|
||||
|
||||
|
||||
# 将功法属性映射为默认的灵根(邪功法不返回)
|
||||
def attribute_to_root(attr: TechniqueAttribute) -> Optional[Root]:
|
||||
mapping: dict[TechniqueAttribute, Root] = {
|
||||
TechniqueAttribute.GOLD: Root.GOLD,
|
||||
TechniqueAttribute.WOOD: Root.WOOD,
|
||||
TechniqueAttribute.WATER: Root.WATER,
|
||||
TechniqueAttribute.FIRE: Root.FIRE,
|
||||
TechniqueAttribute.EARTH: Root.EARTH,
|
||||
TechniqueAttribute.THUNDER: Root.THUNDER,
|
||||
TechniqueAttribute.ICE: Root.ICE,
|
||||
TechniqueAttribute.WIND: Root.WIND,
|
||||
TechniqueAttribute.DARK: Root.DARK,
|
||||
}
|
||||
return mapping.get(attr)
|
||||
|
||||
@@ -26,6 +26,7 @@ from src.classes.sect import sects_by_id
|
||||
from src.classes.alignment import Alignment
|
||||
from src.run.log import get_logger
|
||||
from src.classes.relation import Relation
|
||||
from src.classes.technique import get_technique_by_sect, attribute_to_root
|
||||
|
||||
|
||||
def clamp(value: int, lo: int, hi: int) -> int:
|
||||
@@ -113,6 +114,13 @@ def make_avatars(world: World, count: int = 12, current_month_stamp: MonthStamp
|
||||
# 依据宗门设定阵营(若有宗门则与宗门阵营一致,否则保留默认随机)
|
||||
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())
|
||||
|
||||
@@ -1,33 +1,50 @@
|
||||
id,name,technique_root,grade,prompt,weight,condition
|
||||
,名称,属性,品阶(上中下),提示词,抽样权重,条件
|
||||
1,太乙金光锻体诀,金,下品,运太乙金光淬骨炼筋,金罡护体,刀兵难侵。,1,
|
||||
2,金阳破甲术,金,中品,融金阳之炽与锋,一往破敌,破甲断魄。,1,
|
||||
3,太乙金光经,金,上品,凝太乙金光成罡,身外结铠,破邪辟秽。,1,
|
||||
4,青木长春诀,木,下品,借青木长春之机,涓涓养元,稳固根基。,1,
|
||||
5,碧林长生法,木,中品,汲林海生机,法源不竭,柔而不折。,1,
|
||||
6,太上长生经,木,上品,执太上长生之理,枝叶化护,源远绵长。,1,
|
||||
7,玄冥敛息诀,水,下品,以玄冥静息收摄心神,润物无声。,1,
|
||||
8,玄水化海术,水,中品,以玄水化百川,绵延不绝,攻守随势。,1,
|
||||
9,太玄水灵经,水,上品,驭水灵真意,掌覆沧海,周天轮转。,1,
|
||||
10,南明离火心诀,火,下品,承南明离火之炽,鼓荡心魄,炼魂淬魄。,1,
|
||||
11,赤炎炼真诀,火,中品,以赤炎炼真元,去伪存真,攻势如潮。,1,
|
||||
12,南明离火经,火,上品,承离火至阳,万焰归一,一念焚天。,1,
|
||||
13,厚土镇魄诀,土,下品,以厚土安神定魄,稳如山嶽,不动如山。,1,
|
||||
14,玄黄定岳法,土,中品,以玄黄凝岳势,千钧一力,镇压四方。,1,
|
||||
15,玄黄镇山经,土,上品,执玄黄大道,山河为印,守中制外。,1,
|
||||
16,玄冰凝真诀,冰,下品,以玄冰凝灵,清寒护体,心湖如镜。,1,
|
||||
17,冰魄玄寒法,冰,中品,御玄寒之魄,封江冻海,以静制动。,1,
|
||||
18,太阴玄冰经,冰,上品,执太阴寒意,万里冰封,寒透经脉。,1,
|
||||
19,御风术,风,下品,以清风导息,轻身迅行,形如掠影。,1,
|
||||
20,清风御行法,风,中品,驭风行空,攻守兼备,灵动飘逸。,1,
|
||||
21,太清御风经,风,上品,执太清之风,来去无踪,剑气乘风。,1,
|
||||
22,幽冥潜形术,暗,下品,以幽冥藏形,锋芒尽敛,伺机而动。,1,
|
||||
23,玄夜无相法,暗,中品,夜行无相,出入无痕,摄人心魄。,1,
|
||||
24,幽冥鬼道经,暗,上品,执幽冥鬼道,虚实互转,影灭形生。,1,
|
||||
25,九天淬体雷诀,雷,下品,引九天霆罡击体,筋骨再生,爆发如雷。,1,
|
||||
26,九霄养雷法,雷,中品,引九霄真雷,养气通窍,威势赫然。,1,
|
||||
27,太清神霄经,雷,上品,执神霄正雷,镇压不祥,一念霹雳。,1,
|
||||
28,血神噬魂大法,邪,下品,以血神邪念淬炼,杀伐狠辣,损阴德。,1,avatar.alignment == "邪"
|
||||
29,冥狱吞灵大法,邪,中品,循冥狱之道吞噬灵魄,逆乱阴阳,速成之途。,1,avatar.alignment == "邪"
|
||||
30,太阴噬天魔经,邪,上品,挟太阴极恶之力,噬天吞地,万邪朝宗。,1,avatar.alignment == "邪"
|
||||
id,name,technique_root,grade,prompt,weight,condition,sect
|
||||
,名称,属性,品阶(上中下),提示词,抽样权重,条件,所属宗门
|
||||
1,太乙金光锻体诀,金,下品,运太乙金光淬骨炼筋,金罡护体,刀兵难侵。,1,,
|
||||
2,金阳破甲术,金,中品,融金阳之炽与锋,一往破敌,破甲断魄。,1,,
|
||||
4,青木长春诀,木,下品,借青木长春之机,涓涓养元,稳固根基。,1,,
|
||||
5,碧林长生法,木,中品,汲林海生机,法源不竭,柔而不折。,1,,
|
||||
7,玄冥敛息诀,水,下品,以玄冥静息收摄心神,润物无声。,1,,
|
||||
8,玄水化海术,水,中品,以玄水化百川,绵延不绝,攻守随势。,1,,
|
||||
10,南明离火心诀,火,下品,承南明离火之炽,鼓荡心魄,炼魂淬魄。,1,,
|
||||
11,赤炎炼真诀,火,中品,以赤炎炼真元,去伪存真,攻势如潮。,1,,
|
||||
13,厚土镇魄诀,土,下品,以厚土安神定魄,稳如山嶽,不动如山。,1,,
|
||||
14,玄黄定岳法,土,中品,以玄黄凝岳势,千钧一力,镇压四方。,1,,
|
||||
16,玄冰凝真诀,冰,下品,以玄冰凝灵,清寒护体,心湖如镜。,1,,
|
||||
17,冰魄玄寒法,冰,中品,御玄寒之魄,封江冻海,以静制动。,1,,
|
||||
19,御风术,风,下品,以清风导息,轻身迅行,形如掠影。,1,,
|
||||
20,清风御行法,风,中品,驭风行空,攻守兼备,灵动飘逸。,1,,
|
||||
22,幽冥潜形术,暗,下品,以幽冥藏形,锋芒尽敛,伺机而动。,1,,
|
||||
23,玄夜无相法,暗,中品,夜行无相,出入无痕,摄人心魄。,1,,
|
||||
25,九天淬体雷诀,雷,下品,引九天霆罡击体,筋骨再生,爆发如雷。,1,,
|
||||
26,九霄养雷法,雷,中品,引九霄真雷,养气通窍,威势赫然。,1,,
|
||||
28,血神噬魂大法,邪,下品,以血神邪念淬炼,杀伐狠辣,损阴德。,1,,
|
||||
29,冥狱吞灵大法,邪,中品,循冥狱之道吞噬灵魄,逆乱阴阳,速成之途。,1,,
|
||||
30,明心归一剑典,金,上品,以剑返本归一,明镜止水,一剑断妄。,10,,明心剑宗
|
||||
31,霆光明志剑,雷,上品,以霆光贯剑意,电掣雷行,破虚斩障。,10,,明心剑宗
|
||||
32,离火明心诀,火,上品,以离火照见自心,去蔽存真,剑随心行。,10,,明心剑宗
|
||||
33,御兽玄纲,木,上品,以木灵沟通群兽,血脉契合,驱策如臂。,10,,百兽宗
|
||||
34,蛮荒镇骨体,土,上品,以厚土淬锻筋骨,躯壳如山,血勇不挫。,10,,百兽宗
|
||||
35,血啸狩魂诀,邪,上品,以嗜血啸魄摄魂,狩猎杀伐,越战越猛。,10,,百兽宗
|
||||
36,彻天水镜观,水,上品,以彻天水镜观机,借势化力,先机在握。,10,,水镜宗
|
||||
37,寒漪反斩法,冰,上品,以寒漪回折之势,四两拨千斤,刚柔相济。,10,,水镜宗
|
||||
38,镜花游身步,风,上品,以轻风流转为引,身化水月,进退自如。,10,,水镜宗
|
||||
39,幽冥镇狱经,暗,上品,引幽冥阴煞镇压万灵,寒魄凝骨,万劫不侵。,10,,冥王宗
|
||||
40,冥焰噬神法,邪,上品,以冥焰噬神,逆夺生机,吞灵化魄。,10,,冥王宗
|
||||
41,黄泉引魄步,冰,上品,以玄寒引魄入泉,步步生霜,摄魂夺魄。,10,,冥王宗
|
||||
42,赤狱炼锋诀,火,上品,以赤狱真火炼锋,法器通灵,杀机更盛。,10,,朱勾宗
|
||||
43,魇丝摄魂术,暗,上品,以魇丝无声摄魄,藏形夺命,来去无迹。,10,,朱勾宗
|
||||
44,噬心傀儡经,金,上品,以金罡刻阵,傀儡载魄,攻守如一。,10,,朱勾宗
|
||||
45,双修合和典,水,上品,以清润相济,合气生生,周天圆满。,10,,合欢宗
|
||||
46,魅月摄情术,暗,上品,以魅月摄心,惑而不乱,借情化力。,10,,合欢宗
|
||||
47,绮罗化影步,风,上品,以轻纱化影,形随意转,柔中带锋。,10,,合欢宗
|
||||
48,镇岳定魂经,土,上品,以玄黄定岳势,安神定魄,万邪难侵。,10,,镇魂宗
|
||||
49,霆狱伏邪法,雷,上品,引九霄霆威压邪,刚猛无俦,镇压不返。,10,,镇魂宗
|
||||
50,金章封煞术,金,上品,以金章为印,封煞束灵,斩乱镇邪。,10,,镇魂宗
|
||||
51,幽冥无相诀,暗,上品,隐形无相,出没幽明,摄心夺魄于无声。,10,,幽魂噬影宗
|
||||
52,噬影穿行步,风,上品,以风掠影,穿行缝隙,先至而不留痕。,10,,幽魂噬影宗
|
||||
53,冥狱吞魄经,邪,上品,循幽冥吞魄之道,化敌为养,速成险绝。,10,,幽魂噬影宗
|
||||
54,天罗机巧篇,金,上品,精研机巧阵枢,百变应敌,器术合一。,10,,千帆城
|
||||
55,蓝星定魂阵,土,上品,以厚土定魂为基,阵锁心神,稳如磐石。,10,,千帆城
|
||||
56,飞翼乘风术,风,上品,乘风而行,纵横千里,御器齐驱。,10,,千帆城
|
||||
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 30 and column 108.
|
Reference in New Issue
Block a user