ad catch
This commit is contained in:
@@ -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",
|
||||
]
|
||||
|
||||
|
||||
|
||||
75
src/classes/action/catch.py
Normal file
75
src/classes/action/catch.py
Normal 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 []
|
||||
|
||||
|
||||
Reference in New Issue
Block a user