feat(engine): 实现阵营技能树系统
- 新增 FactionSkill、FactionSkillTree、FactionSkills 数据模型 - 创建 faction_skills.py 模块处理技能解锁和效果应用 - 技能解锁条件:power >= cost 且前置技能已解锁 - 技能效果:increase_positive_emotion、reduce_conflict、increase_fear、suppress_others - 添加 4 个技能树测试用例,全部 30 个测试通过 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
126
engine-python/app/faction_skills.py
Normal file
126
engine-python/app/faction_skills.py
Normal file
@@ -0,0 +1,126 @@
|
||||
"""阵营技能树系统 - 允许阵营通过累积能量解锁技能"""
|
||||
from typing import List, Optional
|
||||
from .models import (
|
||||
WorldState, FactionSkill, FactionSkillTree, FactionSkills
|
||||
)
|
||||
|
||||
|
||||
def get_default_faction_skills() -> FactionSkills:
|
||||
"""返回默认技能树配置"""
|
||||
return FactionSkills(
|
||||
optimists=FactionSkillTree(
|
||||
skills={
|
||||
"festival_boost": FactionSkill(
|
||||
unlocked=False,
|
||||
cost=10,
|
||||
effect="increase_positive_emotion",
|
||||
requires=[]
|
||||
),
|
||||
"unity": FactionSkill(
|
||||
unlocked=False,
|
||||
cost=20,
|
||||
effect="reduce_conflict",
|
||||
requires=["festival_boost"]
|
||||
)
|
||||
}
|
||||
),
|
||||
fearful=FactionSkillTree(
|
||||
skills={
|
||||
"panic_spread": FactionSkill(
|
||||
unlocked=False,
|
||||
cost=10,
|
||||
effect="increase_fear",
|
||||
requires=[]
|
||||
),
|
||||
"control": FactionSkill(
|
||||
unlocked=False,
|
||||
cost=20,
|
||||
effect="suppress_others",
|
||||
requires=["panic_spread"]
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _check_requires_met(skill_tree: FactionSkillTree, requires: List[str]) -> bool:
|
||||
"""检查前置技能是否已解锁"""
|
||||
for req in requires:
|
||||
if req not in skill_tree.skills:
|
||||
return False
|
||||
if not skill_tree.skills[req].unlocked:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def check_and_unlock_skills(state: WorldState) -> List[str]:
|
||||
"""检查并解锁技能
|
||||
|
||||
规则:
|
||||
1. faction.power >= skill.cost
|
||||
2. 技能尚未解锁
|
||||
3. 所有 requires 已解锁
|
||||
|
||||
返回:本次解锁的技能列表
|
||||
"""
|
||||
unlocked = []
|
||||
|
||||
# 检查乐观派技能
|
||||
for skill_id, skill in state.faction_skills.optimists.skills.items():
|
||||
if skill.unlocked:
|
||||
continue
|
||||
if state.factions.optimists.power < skill.cost:
|
||||
continue
|
||||
if not _check_requires_met(state.faction_skills.optimists, skill.requires):
|
||||
continue
|
||||
|
||||
# 解锁技能
|
||||
skill.unlocked = True
|
||||
state.factions.optimists.power -= skill.cost
|
||||
unlocked.append(f"optimists:{skill_id}")
|
||||
|
||||
# 检查恐惧派技能
|
||||
for skill_id, skill in state.faction_skills.fearful.skills.items():
|
||||
if skill.unlocked:
|
||||
continue
|
||||
if state.factions.fearful.power < skill.cost:
|
||||
continue
|
||||
if not _check_requires_met(state.faction_skills.fearful, skill.requires):
|
||||
continue
|
||||
|
||||
# 解锁技能
|
||||
skill.unlocked = True
|
||||
state.factions.fearful.power -= skill.cost
|
||||
unlocked.append(f"fearful:{skill_id}")
|
||||
|
||||
return unlocked
|
||||
|
||||
|
||||
def apply_skill_effects(state: WorldState) -> None:
|
||||
"""应用已解锁技能的持续效果
|
||||
|
||||
效果说明:
|
||||
- increase_positive_emotion: 每 tick 提升 town_mood +1
|
||||
- reduce_conflict: 降低恐惧派能量增长(每 tick -1)
|
||||
- increase_fear: 每 tick 降低 town_mood -1
|
||||
- suppress_others: 降低乐观派能量增长(每 tick -1)
|
||||
"""
|
||||
# 乐观派技能效果
|
||||
for skill_id, skill in state.faction_skills.optimists.skills.items():
|
||||
if not skill.unlocked:
|
||||
continue
|
||||
|
||||
if skill.effect == "increase_positive_emotion":
|
||||
state.town_mood = min(10, state.town_mood + 1)
|
||||
elif skill.effect == "reduce_conflict":
|
||||
state.factions.fearful.power = max(0, state.factions.fearful.power - 1)
|
||||
|
||||
# 恐惧派技能效果
|
||||
for skill_id, skill in state.faction_skills.fearful.skills.items():
|
||||
if not skill.unlocked:
|
||||
continue
|
||||
|
||||
if skill.effect == "increase_fear":
|
||||
state.town_mood = max(-10, state.town_mood - 1)
|
||||
elif skill.effect == "suppress_others":
|
||||
state.factions.optimists.power = max(0, state.factions.optimists.power - 1)
|
||||
Reference in New Issue
Block a user