"""Fly command for aerial movement across the world.""" from mudlib.commands import CommandDefinition, register from mudlib.commands.movement import DIRECTIONS, send_nearby_message from mudlib.effects import add_effect from mudlib.player import Player from mudlib.render.ansi import BOLD, BRIGHT_WHITE from mudlib.zone import Zone # how far you fly FLY_DISTANCE = 5 # origin cloud gets the base ttl, each step toward destination adds stagger. # trail visibly shrinks from origin toward the player, one tile at a time. CLOUD_TTL = 1.5 CLOUD_STAGGER = 0.4 # seconds between each cloud's expiry # ANSI color for cloud trails CLOUD_COLOR = BOLD + BRIGHT_WHITE async def cmd_fly(player: Player, args: str) -> None: """Toggle flying or move while airborne. fly - toggle flying on/off fly - move 5 tiles in a direction (must be flying) """ direction = args.strip().lower() # no args = toggle flying state if not direction: if player.flying: player.flying = False player.writer.write("You land.\r\n") await player.writer.drain() await send_nearby_message( player, player.x, player.y, f"{player.name} lands.\r\n", ) else: player.flying = True player.writer.write("You fly into the air!\r\n") await player.writer.drain() await send_nearby_message( player, player.x, player.y, f"{player.name} lifts into the air!\r\n", ) return # direction given but not flying if not player.flying: player.writer.write("You aren't flying.\r\n") await player.writer.drain() return delta = DIRECTIONS.get(direction) if delta is None: player.writer.write(f"'{direction}' isn't a direction.\r\n") await player.writer.drain() return zone = player.location assert isinstance(zone, Zone), "Player must be in a zone to fly" dx, dy = delta start_x, start_y = player.x, player.y # lay cloud trail at starting position and each intermediate step. # origin cloud expires first, near-dest cloud lingers longest. # the trail shrinks from behind toward the player over time. for step in range(FLY_DISTANCE): trail_x, trail_y = zone.wrap(start_x + dx * step, start_y + dy * step) ttl = CLOUD_TTL + step * CLOUD_STAGGER add_effect(trail_x, trail_y, "~", CLOUD_COLOR, ttl=ttl) # move player to destination dest_x, dest_y = zone.wrap(start_x + dx * FLY_DISTANCE, start_y + dy * FLY_DISTANCE) player.x = dest_x player.y = dest_y # auto-look at new position from mudlib.commands.look import cmd_look await cmd_look(player, "") register(CommandDefinition("fly", cmd_fly))