This commit is contained in:
bridge
2025-10-21 22:53:13 +08:00
parent f7a2e377a1
commit b4fa1c1c76
11 changed files with 185 additions and 11 deletions

View File

@@ -32,6 +32,7 @@ from .help_mortals import HelpMortals
from .talk import Talk
from .devour_mortals import DevourMortals
from .self_heal import SelfHeal
from .catch import Catch
# 注册到 ActionRegistry标注是否为实际可执行动作
register_action(actual=False)(Action)
@@ -60,6 +61,7 @@ register_action(actual=True)(HelpMortals)
register_action(actual=True)(Talk)
register_action(actual=True)(DevourMortals)
register_action(actual=True)(SelfHeal)
register_action(actual=True)(Catch)
__all__ = [
# 基类
@@ -90,6 +92,7 @@ __all__ = [
"Talk",
"DevourMortals",
"SelfHeal",
"Catch",
]

View File

@@ -0,0 +1,75 @@
from __future__ import annotations
import random
from typing import TYPE_CHECKING
from src.classes.action import TimedAction
from src.classes.event import Event
from src.classes.region import NormalRegion
from src.classes.spirit_animal import SpiritAnimal
from src.classes.cultivation import Realm
if TYPE_CHECKING:
from src.classes.animal import Animal
class Catch(TimedAction):
"""
御兽:仅百兽宗弟子可用。
条件:
- 当前处于普通区域,且该区域有动物分布
- 目标动物境界 <= Avatar 境界
结果:
- 按动物境界映射成功率尝试捕捉,成功则成为灵兽(覆盖旧灵兽)。
"""
COMMENT = "尝试驯服一只灵兽,成为自身灵兽"
DOABLES_REQUIREMENTS = "仅百兽宗;在有动物的普通区域;目标动物境界不高于角色"
PARAMS = {}
duration_months = 4
def _get_available_animals(self) -> list[Animal]:
region = self.avatar.tile.region
avatar_realm = self.avatar.cultivation_progress.realm
return [animal for animal in getattr(region, "animals", []) if avatar_realm >= animal.realm]
def _calc_success_rate_by_realm(self, animal_realm: Realm) -> float:
mapping: dict[Realm, float] = {
Realm.Qi_Refinement: 0.8,
Realm.Foundation_Establishment: 0.6,
Realm.Core_Formation: 0.4,
Realm.Nascent_Soul: 0.2,
}
return mapping.get(animal_realm, 0.1)
def _execute(self) -> None:
animals = self._get_available_animals()
if not animals:
return
target = random.choice(animals)
base = self._calc_success_rate_by_realm(target.realm)
extra = float(self.avatar.effects.get("extra_catch_success_rate", 0) or 0)
rate = max(0.0, min(1.0, base + extra))
if random.random() < rate:
# 覆盖为新的灵兽
self.avatar.spirit_animal = SpiritAnimal(name=target.name, realm=target.realm)
def can_start(self) -> bool:
# 仅百兽宗
sect = getattr(self.avatar, "sect", None)
if sect is None or getattr(sect, "name", "") != "百兽宗":
return False
region = self.avatar.tile.region
if not isinstance(region, NormalRegion):
return False
return len(self._get_available_animals()) > 0
def start(self) -> Event:
region = self.avatar.tile.region
return Event(self.world.month_stamp, f"{self.avatar.name}{region.name} 尝试御兽")
def finish(self) -> list[Event]:
return []