update battle
This commit is contained in:
@@ -10,6 +10,10 @@ class Battle(InstantAction):
|
|||||||
COMMENT = "与目标进行对战,判定胜负"
|
COMMENT = "与目标进行对战,判定胜负"
|
||||||
DOABLES_REQUIREMENTS = "任何时候都可以执行"
|
DOABLES_REQUIREMENTS = "任何时候都可以执行"
|
||||||
PARAMS = {"avatar_name": "AvatarName"}
|
PARAMS = {"avatar_name": "AvatarName"}
|
||||||
|
# 提供用于故事生成的提示词:不出现血量/伤害等数值描述
|
||||||
|
STORY_PROMPT: str | None = (
|
||||||
|
"不要出现具体血量、伤害点数或任何数值表达。"
|
||||||
|
)
|
||||||
|
|
||||||
def _get_target(self, avatar_name: str):
|
def _get_target(self, avatar_name: str):
|
||||||
for v in self.world.avatar_manager.avatars.values():
|
for v in self.world.avatar_manager.avatars.values():
|
||||||
@@ -57,7 +61,7 @@ class Battle(InstantAction):
|
|||||||
target = self._get_target(avatar_name)
|
target = self._get_target(avatar_name)
|
||||||
avatar_infos = StoryTeller.build_avatar_infos(self.avatar, target)
|
avatar_infos = StoryTeller.build_avatar_infos(self.avatar, target)
|
||||||
start_text = getattr(self, "_start_event_content", "") or result_event.content
|
start_text = getattr(self, "_start_event_content", "") or result_event.content
|
||||||
story = StoryTeller.tell_story(avatar_infos, start_text, result_event.content)
|
story = StoryTeller.tell_story(avatar_infos, start_text, result_event.content, self.STORY_PROMPT)
|
||||||
story_event = Event(self.world.month_stamp, story)
|
story_event = Event(self.world.month_stamp, story)
|
||||||
return [result_event, story_event]
|
return [result_event, story_event]
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ from src.classes.alignment import Alignment
|
|||||||
from src.utils.params import filter_kwargs_for_callable
|
from src.utils.params import filter_kwargs_for_callable
|
||||||
from src.classes.sect import Sect
|
from src.classes.sect import Sect
|
||||||
from src.classes.appearance import Appearance, get_random_appearance
|
from src.classes.appearance import Appearance, get_random_appearance
|
||||||
|
from src.classes.battle import get_base_strength
|
||||||
|
|
||||||
persona_num = CONFIG.avatar.persona_num
|
persona_num = CONFIG.avatar.persona_num
|
||||||
|
|
||||||
@@ -476,6 +477,7 @@ class Avatar:
|
|||||||
f"境界: {str(self.cultivation_progress)}",
|
f"境界: {str(self.cultivation_progress)}",
|
||||||
f"HP: {self.hp}",
|
f"HP: {self.hp}",
|
||||||
f"MP: {self.mp}",
|
f"MP: {self.mp}",
|
||||||
|
f"战斗力: {int(get_base_strength(self))}",
|
||||||
]
|
]
|
||||||
lines.append(f"宗门: {self.get_sect_str()}")
|
lines.append(f"宗门: {self.get_sect_str()}")
|
||||||
from src.classes.root import format_root_cn
|
from src.classes.root import format_root_cn
|
||||||
|
|||||||
@@ -26,29 +26,29 @@ _MIN_RATIO: float = 1.05 # 最小相对优势比,确保赢
|
|||||||
_PAIR_BIAS: float = 1.1 # 成对偏置:让败者再多一点、赢家再少一点
|
_PAIR_BIAS: float = 1.1 # 成对偏置:让败者再多一点、赢家再少一点
|
||||||
|
|
||||||
|
|
||||||
def _combat_strength_vs(opponent: "Avatar", self_avatar: "Avatar") -> float:
|
def get_base_strength(self_avatar: "Avatar") -> float:
|
||||||
"""
|
"""
|
||||||
计算对某个对手的有效战斗力:
|
基础战斗力:与对手无关。
|
||||||
= 10×ln(1+修为等级) + 品阶点数(0/3/6) + 克制点数(若克制则+3)
|
= 10×ln(1+修为等级) + 品阶点数(0/3/6)
|
||||||
说明:
|
|
||||||
- 修为使用总等级(1..120)并做对数缩放,避免过大;
|
|
||||||
- 品阶加点为线性,避免与修为重复放大;
|
|
||||||
- 克制只在“对某个对手”时生效,因此放在此函数处理。
|
|
||||||
"""
|
"""
|
||||||
level = max(1, self_avatar.cultivation_progress.level)
|
level = max(1, self_avatar.cultivation_progress.level)
|
||||||
strength_from_level = _STRENGTH_LOG_SCALE * math.log1p(level)
|
strength_from_level = _STRENGTH_LOG_SCALE * math.log1p(level)
|
||||||
|
|
||||||
grade_points = 0.0
|
grade_points = 0.0
|
||||||
if self_avatar.technique is not None:
|
if self_avatar.technique is not None:
|
||||||
grade_points = _GRADE_POINTS.get(self_avatar.technique.grade, 0.0)
|
grade_points = _GRADE_POINTS.get(self_avatar.technique.grade, 0.0)
|
||||||
|
return strength_from_level + grade_points
|
||||||
|
|
||||||
|
|
||||||
|
def _combat_strength_vs(opponent: "Avatar", self_avatar: "Avatar") -> float:
|
||||||
|
"""
|
||||||
|
相对战斗力:= 基础战斗力 + 克制点数(若克制则+3)
|
||||||
|
"""
|
||||||
|
base = get_base_strength(self_avatar)
|
||||||
suppression_points = 0.0
|
suppression_points = 0.0
|
||||||
if self_avatar.technique is not None and opponent.technique is not None:
|
if self_avatar.technique is not None and opponent.technique is not None:
|
||||||
# 仅需“是否克制”的布尔,不引入倍率。
|
|
||||||
if get_suppression_bonus(self_avatar.technique.attribute, opponent.technique.attribute) > 0.0:
|
if get_suppression_bonus(self_avatar.technique.attribute, opponent.technique.attribute) > 0.0:
|
||||||
suppression_points = _SUPPRESSION_POINTS
|
suppression_points = _SUPPRESSION_POINTS
|
||||||
|
return base + suppression_points
|
||||||
return strength_from_level + grade_points + suppression_points
|
|
||||||
|
|
||||||
|
|
||||||
def _strength_diff(attacker: "Avatar", defender: "Avatar") -> float:
|
def _strength_diff(attacker: "Avatar", defender: "Avatar") -> float:
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class Attack(MutualAction):
|
|||||||
DOABLES_REQUIREMENTS = "与目标处于同一区域"
|
DOABLES_REQUIREMENTS = "与目标处于同一区域"
|
||||||
PARAMS = {"target_avatar": "AvatarName"}
|
PARAMS = {"target_avatar": "AvatarName"}
|
||||||
FEEDBACK_ACTIONS = ["Escape", "Battle"]
|
FEEDBACK_ACTIONS = ["Escape", "Battle"]
|
||||||
story_prompt: str = ""
|
STORY_PROMPT: str = ""
|
||||||
|
|
||||||
def _settle_feedback(self, target_avatar: "Avatar", feedback_name: str) -> None:
|
def _settle_feedback(self, target_avatar: "Avatar", feedback_name: str) -> None:
|
||||||
fb = str(feedback_name).strip()
|
fb = str(feedback_name).strip()
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class Conversation(MutualAction):
|
|||||||
DOABLES_REQUIREMENTS = "与目标处于同一区域"
|
DOABLES_REQUIREMENTS = "与目标处于同一区域"
|
||||||
PARAMS = {"target_avatar": "AvatarName"}
|
PARAMS = {"target_avatar": "AvatarName"}
|
||||||
FEEDBACK_ACTIONS: list[str] = ["Talk", "Reject"]
|
FEEDBACK_ACTIONS: list[str] = ["Talk", "Reject"]
|
||||||
story_prompt: str = ""
|
STORY_PROMPT: str = ""
|
||||||
|
|
||||||
def _get_template_path(self) -> Path:
|
def _get_template_path(self) -> Path:
|
||||||
# 使用 talk.txt 模板,以获取是否接受与对话内容
|
# 使用 talk.txt 模板,以获取是否接受与对话内容
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class DriveAway(MutualAction):
|
|||||||
DOABLES_REQUIREMENTS = "与目标处于同一区域"
|
DOABLES_REQUIREMENTS = "与目标处于同一区域"
|
||||||
PARAMS = {"target_avatar": "AvatarName"}
|
PARAMS = {"target_avatar": "AvatarName"}
|
||||||
FEEDBACK_ACTIONS = ["MoveAwayFromRegion", "Battle"]
|
FEEDBACK_ACTIONS = ["MoveAwayFromRegion", "Battle"]
|
||||||
story_prompt: str = ""
|
STORY_PROMPT: str = ""
|
||||||
|
|
||||||
def _settle_feedback(self, target_avatar: "Avatar", feedback_name: str) -> None:
|
def _settle_feedback(self, target_avatar: "Avatar", feedback_name: str) -> None:
|
||||||
fb = str(feedback_name).strip()
|
fb = str(feedback_name).strip()
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class DualCultivation(MutualAction):
|
|||||||
PARAMS = {"target_avatar": "AvatarName"}
|
PARAMS = {"target_avatar": "AvatarName"}
|
||||||
FEEDBACK_ACTIONS = ["Accept", "Reject"]
|
FEEDBACK_ACTIONS = ["Accept", "Reject"]
|
||||||
# 提供用于故事生成的提示词,供 StoryTeller 模板参考
|
# 提供用于故事生成的提示词,供 StoryTeller 模板参考
|
||||||
story_prompt: str | None = "两位修士在双修过程中情愫暗生,以含蓄、雅致的文字描绘一段暧昧而不露骨的双修体验,体现彼此性格、境界差异与甜蜜的恋爱时光。"
|
STORY_PROMPT: str | None = "两位修士在双修过程中情愫暗生,以含蓄、雅致的文字描绘一段暧昧而不露骨的双修体验,体现彼此性格、境界差异与甜蜜的恋爱时光。不要体现经验的数值。"
|
||||||
|
|
||||||
def _get_template_path(self) -> Path:
|
def _get_template_path(self) -> Path:
|
||||||
# 复用 mutual_action 模板,仅需返回 Accept/Reject
|
# 复用 mutual_action 模板,仅需返回 Accept/Reject
|
||||||
@@ -104,7 +104,7 @@ class DualCultivation(MutualAction):
|
|||||||
# 生成恋爱/双修小故事:使用通用故事模板
|
# 生成恋爱/双修小故事:使用通用故事模板
|
||||||
avatar_infos = StoryTeller.build_avatar_infos(self.avatar, target)
|
avatar_infos = StoryTeller.build_avatar_infos(self.avatar, target)
|
||||||
start_text = self._start_event_content or result_event.content
|
start_text = self._start_event_content or result_event.content
|
||||||
story = StoryTeller.tell_story(avatar_infos, start_text, result_event.content, self.story_prompt)
|
story = StoryTeller.tell_story(avatar_infos, start_text, result_event.content, self.STORY_PROMPT)
|
||||||
story_event = Event(self.world.month_stamp, story)
|
story_event = Event(self.world.month_stamp, story)
|
||||||
events.append(story_event)
|
events.append(story_event)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class MutualAction(DefineAction, LLMAction, TargetingMixin):
|
|||||||
"Battle": "战斗",
|
"Battle": "战斗",
|
||||||
}
|
}
|
||||||
# 若该互动动作可能生成小故事,可在子类中覆盖该提示词
|
# 若该互动动作可能生成小故事,可在子类中覆盖该提示词
|
||||||
story_prompt: str | None = None
|
STORY_PROMPT: str | None = None
|
||||||
|
|
||||||
def _get_template_path(self) -> Path:
|
def _get_template_path(self) -> Path:
|
||||||
return CONFIG.paths.templates / "mutual_action.txt"
|
return CONFIG.paths.templates / "mutual_action.txt"
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class StoryTeller:
|
|||||||
return infos
|
return infos
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def tell_story(avatar_infos: Dict[str, dict], event: str, res: str, story_prompt: str = "") -> str:
|
def tell_story(avatar_infos: Dict[str, dict], event: str, res: str, STORY_PROMPT: str = "") -> str:
|
||||||
"""
|
"""
|
||||||
基于 `static/templates/story.txt` 模板生成小故事。
|
基于 `static/templates/story.txt` 模板生成小故事。
|
||||||
始终使用 fast 模式以提升速度。
|
始终使用 fast 模式以提升速度。
|
||||||
@@ -54,7 +54,7 @@ class StoryTeller:
|
|||||||
"event": event,
|
"event": event,
|
||||||
"res": res,
|
"res": res,
|
||||||
"style": random.choice(story_styles),
|
"style": random.choice(story_styles),
|
||||||
"story_prompt": story_prompt or "",
|
"STORY_PROMPT": STORY_PROMPT or "",
|
||||||
}
|
}
|
||||||
data = get_prompt_and_call_llm(template_path, infos, mode="fast")
|
data = get_prompt_and_call_llm(template_path, infos, mode="fast")
|
||||||
story = data["story"].strip()
|
story = data["story"].strip()
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ ai:
|
|||||||
max_decide_num: 4
|
max_decide_num: 4
|
||||||
|
|
||||||
game:
|
game:
|
||||||
init_npc_num: 9
|
init_npc_num: 2
|
||||||
sect_num: 2 # init_npc_num大于sect_num时,会随机选择sect_num个宗门
|
sect_num: 2 # init_npc_num大于sect_num时,会随机选择sect_num个宗门
|
||||||
npc_birth_rate_per_month: 0.001
|
npc_birth_rate_per_month: 0.001
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ id,name,exclusion_ids,desc,weight,condition
|
|||||||
9,沉思,2,你总是会深思熟虑,思考问题比较有哲理。,1,
|
9,沉思,2,你总是会深思熟虑,思考问题比较有哲理。,1,
|
||||||
10,惜命,4;24;25,你总是会珍惜自己的生命,不会轻易冒险。,1,
|
10,惜命,4;24;25,你总是会珍惜自己的生命,不会轻易冒险。,1,
|
||||||
11,友爱,13;14;15;12;24;25,你重视同伴与和谐,乐于助人,倾向通过协作与沟通化解矛盾。,1,
|
11,友爱,13;14;15;12;24;25,你重视同伴与和谐,乐于助人,倾向通过协作与沟通化解矛盾。,1,
|
||||||
12,复仇,11;14,你绝不轻易放下仇怨,为了复仇愿意付出代价与时间。你必须立刻进行复仇行动。,1,
|
12,复仇,11;14,你绝不轻易放下仇怨,为了复仇愿意付出代价与时间。你必须立刻进行复仇行动。,1000,
|
||||||
13,孤僻,11,你喜欢独处,避免与人深交,更信赖自己的判断与行动。,1,
|
13,孤僻,11,你喜欢独处,避免与人深交,更信赖自己的判断与行动。,1,
|
||||||
14,淡漠,11;12;15;24;25,你情感克制,对外界冷静疏离,不轻易被他人或事件影响。,1,
|
14,淡漠,11;12;15;24;25,你情感克制,对外界冷静疏离,不轻易被他人或事件影响。,1,
|
||||||
15,好斗,11;14;10;17,你直面冲突,偏好以力量与对抗解决问题,越挫越勇。,1,
|
15,好斗,11;14;10;17,你直面冲突,偏好以力量与对抗解决问题,越挫越勇。,1,
|
||||||
@@ -25,7 +25,7 @@ id,name,exclusion_ids,desc,weight,condition
|
|||||||
23,热情,13;14;22,你待人友好、积极回应,倾向用鼓励与赞美拉近距离;你更愿意主动展开善意的交流,乐于合作与分享,1,
|
23,热情,13;14;22,你待人友好、积极回应,倾向用鼓励与赞美拉近距离;你更愿意主动展开善意的交流,乐于合作与分享,1,
|
||||||
24,极端正义,20;25,你对邪恶深恶痛绝,对正义的理想抱有近乎偏执的追求。,1,avatar.alignment == "正"
|
24,极端正义,20;25,你对邪恶深恶痛绝,对正义的理想抱有近乎偏执的追求。,1,avatar.alignment == "正"
|
||||||
25,极端邪恶,20;24,你推崇权力与恐惧,为达目的不择手段,对善良嗤之以鼻。,1,avatar.alignment == "邪"
|
25,极端邪恶,20;24,你推崇权力与恐惧,为达目的不择手段,对善良嗤之以鼻。,1,avatar.alignment == "邪"
|
||||||
26,开放,27,你对待和他人结为道侣或者双修比较随意,1000,
|
26,开放,27,你对待和他人结为道侣或者双修比较随意,1,
|
||||||
27,腼腆,26,你对待和他人结为道侣或者双修比较谨慎,1,
|
27,腼腆,26,你对待和他人结为道侣或者双修比较谨慎,1,
|
||||||
28,舔狗,13;14;22;27,你对异性中外貌出众者格外友善,倾向主动接近、帮助与合作。,1,
|
28,舔狗,13;14;22;27,你对异性中外貌出众者格外友善,倾向主动接近、帮助与合作。,1,
|
||||||
29,嫉妒,11;23,你对在修为、外貌或财富等方面远超于你的人容易产生敌意,更倾向对其冷淡、挑衅或打压。,1,
|
29,嫉妒,11;23,你对在修为、外貌或财富等方面远超于你的人容易产生敌意,更倾向对其冷淡、挑衅或打压。,1,
|
||||||
|
|||||||
|
Can't render this file because it contains an unexpected character in line 26 and column 121.
|
Reference in New Issue
Block a user