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