diff --git a/src/models/zoneCharacter.ts b/src/models/zoneCharacter.ts index 43ce094..8705451 100644 --- a/src/models/zoneCharacter.ts +++ b/src/models/zoneCharacter.ts @@ -4,6 +4,7 @@ import prisma from '../utilities/prisma' class ZoneCharacter { public readonly character: Character public isMoving: boolean = false + public currentPath: Array<{ x: number; y: number }> | null = null; constructor(character: Character) { this.character = character diff --git a/src/socketEvents/character/connect.ts b/src/socketEvents/character/connect.ts index f9efd06..6fab1a2 100644 --- a/src/socketEvents/character/connect.ts +++ b/src/socketEvents/character/connect.ts @@ -39,7 +39,7 @@ export default class CharacterConnectEvent { this.socket.characterId = character.id this.socket.emit('character:connect', character) } catch (error) { - this.handleError('Failed to connect character', error) + this.handleError('Failed to connect character', error) // @TODO : Make global error handler } } diff --git a/src/socketEvents/zone/characterMove.ts b/src/socketEvents/zone/characterMove.ts index aa31830..c29ae00 100644 --- a/src/socketEvents/zone/characterMove.ts +++ b/src/socketEvents/zone/characterMove.ts @@ -11,7 +11,6 @@ import ZoneCharacter from '../../models/zoneCharacter' export default class CharacterMove { private readonly characterMoveService = new CharacterMoveService() private readonly zoneEventTileService = new ZoneEventTileService() - private nextPath = new Map() constructor( private readonly io: Server, @@ -29,24 +28,33 @@ export default class CharacterMove { return } + // If already moving, cancel current movement and wait for it to fully stop + if (zoneCharacter.isMoving) { + zoneCharacter.isMoving = false + await new Promise(resolve => setTimeout(resolve, 100)) + } + const path = await this.characterMoveService.calculatePath(zoneCharacter.character, positionX, positionY) if (!path) { this.io.in(zoneCharacter.character.zoneId.toString()).emit('character:moveError', 'No valid path found') return } - if (!zoneCharacter.isMoving) { - zoneCharacter.isMoving = true - await this.moveAlongPath(zoneCharacter, path) - } else { - this.nextPath.set(zoneCharacter.character.id, path) - } + // Start new movement + zoneCharacter.isMoving = true + zoneCharacter.currentPath = path // Add this property to ZoneCharacter class + await this.moveAlongPath(zoneCharacter, path) } private async moveAlongPath(zoneCharacter: ZoneCharacter, path: Array<{ x: number; y: number }>): Promise { const { character } = zoneCharacter for (let i = 0; i < path.length - 1; i++) { + // Exit if movement was cancelled or interrupted + if (!zoneCharacter.isMoving || zoneCharacter.currentPath !== path) { + return + } + const [start, end] = [path[i], path[i + 1]] character.rotation = Rotation.calculate(start.x, start.y, end.x, end.y) @@ -70,11 +78,8 @@ export default class CharacterMove { await this.characterMoveService.applyMovementDelay() } - const nextPath = this.nextPath.get(character.id) - if (nextPath) { - this.nextPath.delete(character.id) - await this.moveAlongPath(zoneCharacter, nextPath) - } else { + // Only finalize if this path wasn't interrupted + if (zoneCharacter.isMoving && zoneCharacter.currentPath === path) { this.finalizeMovement(zoneCharacter) } }