import { Server } from 'socket.io' import { TSocket, ExtendedCharacter } from '../../utilities/types' import { CharacterMoveService } from '../../services/character/characterMoveService' import { TeleportService } from '../../services/character/teleportService' import { MovementValidator } from '../../services/character/movementValidator' import { SocketEmitter } from '../../utilities/socketEmitter' export default class CharacterMoveEvent { private characterMoveService: CharacterMoveService private teleportService: TeleportService private movementValidator: MovementValidator private socketEmitter: SocketEmitter constructor( private readonly io: Server, private readonly socket: TSocket ) { this.characterMoveService = new CharacterMoveService() this.teleportService = new TeleportService() this.movementValidator = new MovementValidator() this.socketEmitter = new SocketEmitter(io, socket) } public listen(): void { this.socket.on('character:initMove', this.handleCharacterMove.bind(this)) } private async handleCharacterMove({ positionX, positionY }: { positionX: number; positionY: number }): Promise { const { character } = this.socket if (!character) { console.error('character:move error', 'Character not found') return } const path = await this.characterMoveService.calculatePath(character, positionX, positionY) if (!path) { this.socketEmitter.emitMoveError('No valid path found') return } await this.moveAlongPath(character, path) } private async moveAlongPath(character: ExtendedCharacter, path: Array<{ x: number; y: number }>): Promise { for (const position of path) { if (!(await this.movementValidator.isValidMove(character, position))) { break } const teleport = await this.teleportService.checkForTeleport(character, position) if (teleport) { await this.characterMoveService.updatePosition(character, position, teleport.toZoneId) await this.teleportService.handleTeleport(this.socket, character, teleport) break } await this.characterMoveService.updatePosition(character, position) this.socketEmitter.emitCharacterMove(character) await this.characterMoveService.applyMovementDelay() } this.finalizeMovement(character) } private finalizeMovement(character: ExtendedCharacter): void { character.isMoving = false this.socketEmitter.emitCharacterMove(character) } }