Mi2dRPGamEng/resources/logic/abilities.py

45 lines
1.8 KiB
Python

from __future__ import annotations
from engine.character import Character
from engine.world import TimeWarpZone, World
DEFAULT_RADIUS = 3.0
DEFAULT_SPEED_FACTOR = 0.3 # 30% normal speed inside the sphere
DEFAULT_DURATION = 5.0 # seconds
def cast_time_warp_sphere(
caster: Character,
world: World,
now: float,
center: tuple[float, float, float] | None = None,
radius: float = DEFAULT_RADIUS,
speed_factor: float = DEFAULT_SPEED_FACTOR,
duration: float = DEFAULT_DURATION,
whitelist: set[str] | None = None,
) -> TimeWarpZone:
"""Sample ability: everything inside the sphere (except the caster and `whitelist`, e.g.
allies) moves at `speed_factor` of normal for `duration` seconds. Size, speed factor,
whitelist, and time are all just arguments - this is deliberately not tied to being cast
from a character ability vs. an item; see grants_ability on ItemDef and resources/logic/
actions.py::activate_hand for the item attachment point, and Character.can_perform_ability
for gating a direct character-ability trigger the same way leap/melee/ranged already are.
Note: only entity *movement* speed is actually slowed (see World.speed_multiplier_at) -
this engine resolves shots as instant hit-scans with no travel-time to slow.
"""
assert caster.position is not None
if center is None:
center = (caster.position.x, caster.position.y, caster.position.z)
immune = set(whitelist) if whitelist is not None else set()
immune.add(caster.entity_id)
zone = TimeWarpZone(
map_id=caster.position.map_id,
center=center,
radius=radius,
speed_factor=speed_factor,
expires_at=now + duration,
immune_entity_ids=immune,
)
world.time_warp_zones.append(zone)
return zone