From 9a448542d3e06ea1d8d275e9c7eda33014934a17 Mon Sep 17 00:00:00 2001 From: Dennis Postma Date: Sat, 4 Jan 2025 19:05:54 +0100 Subject: [PATCH] More improvements --- src/events/character/connect.ts | 7 +- src/events/character/delete.ts | 6 +- src/events/character/list.ts | 2 +- src/events/chat/gameMaster/alertCommand.ts | 17 +-- src/events/chat/gameMaster/setTimeCommand.ts | 19 +--- src/events/chat/gameMaster/teleportCommand.ts | 23 ++-- .../chat/gameMaster/toggleFogCommand.ts | 19 +--- .../chat/gameMaster/toggleRainCommand.ts | 19 +--- src/events/chat/message.ts | 3 +- src/events/map/characterMove.ts | 3 + src/events/zone/characterMove.ts | 104 ------------------ 11 files changed, 38 insertions(+), 184 deletions(-) delete mode 100644 src/events/zone/characterMove.ts diff --git a/src/events/character/connect.ts b/src/events/character/connect.ts index 43f1ecb..239e001 100644 --- a/src/events/character/connect.ts +++ b/src/events/character/connect.ts @@ -25,13 +25,16 @@ export default class CharacterConnectEvent extends BaseEvent { return } - const character = await this.characterRepository.getByUserAndId(this.socket.userId!, data.characterId, ['characterType', 'characterHair']) + const character = await this.characterRepository.getByUserAndId(this.socket.userId!, data.characterId) if (!character) { this.emitError('Character not found or does not belong to this user') return } + // Populate character with characterType and characterHair + await this.characterRepository.getEntityManager().populate(character, ['characterType', 'characterHair']) + // Set character id this.socket.characterId = character.id @@ -45,7 +48,7 @@ export default class CharacterConnectEvent extends BaseEvent { callback({ character }) // wait 300 ms, @TODO: Find a better way to do this, race condition - await new Promise((resolve) => setTimeout(resolve, 500)) + await new Promise((resolve) => setTimeout(resolve, 1000)) await TeleportService.teleportCharacter(character.id, { targetMapId: character.map.id, diff --git a/src/events/character/delete.ts b/src/events/character/delete.ts index a077b5a..160bd4c 100644 --- a/src/events/character/delete.ts +++ b/src/events/character/delete.ts @@ -1,7 +1,6 @@ import { BaseEvent } from '#application/base/baseEvent' import { UUID } from '#application/types' import { Character } from '#entities/character' -import { Map } from '#entities/map' import CharacterRepository from '#repositories/characterRepository' type TypePayload = { @@ -19,8 +18,9 @@ export default class CharacterDeleteEvent extends BaseEvent { private async handleEvent(data: TypePayload, callback: (response: TypeResponse) => void): Promise { try { - await (await CharacterRepository.getByUserAndId(this.socket.userId!, data.characterId))?.delete() - const characters: Character[] = await CharacterRepository.getByUserId(this.socket.userId!) + const characterRepository = new CharacterRepository() + await (await characterRepository.getByUserAndId(this.socket.userId!, data.characterId))?.delete() + const characters: Character[] = await characterRepository.getByUserId(this.socket.userId!) this.socket.emit('character:list', characters) } catch (error: any) { diff --git a/src/events/character/list.ts b/src/events/character/list.ts index d3b9699..85ceb13 100644 --- a/src/events/character/list.ts +++ b/src/events/character/list.ts @@ -12,9 +12,9 @@ export default class CharacterListEvent extends BaseEvent { const characterRepository = new CharacterRepository() let characters: Character[] = await characterRepository.getByUserId(this.socket.userId!) + // Populate characters with characterType and characterHair await characterRepository.getEntityManager().populate(characters, ['characterType', 'characterHair']) - console.log(characters) this.socket.emit('character:list', characters) } catch (error: any) { this.logger.error('character:list error', error.message) diff --git a/src/events/chat/gameMaster/alertCommand.ts b/src/events/chat/gameMaster/alertCommand.ts index b8de6fa..dc16413 100644 --- a/src/events/chat/gameMaster/alertCommand.ts +++ b/src/events/chat/gameMaster/alertCommand.ts @@ -13,22 +13,11 @@ export default class AlertCommandEvent extends BaseEvent { private async handleEvent(data: TypePayload, callback: (response: boolean) => void): Promise { try { - if (!ChatService.isCommand(data.message, 'alert')) { - return - } + // Check if command is alert + if (!ChatService.isCommand(data.message, 'alert')) return // Check if character exists - const character = await CharacterRepository.getByUserAndId(this.socket.userId!, this.socket.characterId!) - if (!character) { - this.logger.error('chat:alert_command error', 'Character not found') - return callback(false) - } - - // Check if the user is the GM - if (character.role !== 'gm') { - this.logger.info(`User ${character.id} tried to set time but is not a game master.`) - return callback(false) - } + if (!(await this.isCharacterGM())) return const args = ChatService.getArgs('alert', data.message) diff --git a/src/events/chat/gameMaster/setTimeCommand.ts b/src/events/chat/gameMaster/setTimeCommand.ts index 22e2eb5..b584cbd 100644 --- a/src/events/chat/gameMaster/setTimeCommand.ts +++ b/src/events/chat/gameMaster/setTimeCommand.ts @@ -14,22 +14,11 @@ export default class SetTimeCommand extends BaseEvent { private async handleEvent(data: TypePayload, callback: (response: boolean) => void): Promise { try { - if (!ChatService.isCommand(data.message, 'time')) { - return - } + // Check if command is time + if (!ChatService.isCommand(data.message, 'time')) return - // Check if character exists - const character = await CharacterRepository.getByUserAndId(this.socket.userId!, this.socket.characterId!) - if (!character) { - this.logger.error('chat:alert_command error', 'Character not found') - return - } - - // Check if the user is the GM - if (character.role !== 'gm') { - this.logger.info(`User ${character.id} tried to set time but is not a game master.`) - return - } + // Check if character exists and is GM + if (!(await this.isCharacterGM())) return // Get arguments const args = ChatService.getArgs('time', data.message) diff --git a/src/events/chat/gameMaster/teleportCommand.ts b/src/events/chat/gameMaster/teleportCommand.ts index a0a8714..7963ec0 100644 --- a/src/events/chat/gameMaster/teleportCommand.ts +++ b/src/events/chat/gameMaster/teleportCommand.ts @@ -16,21 +16,15 @@ export default class TeleportCommandEvent extends BaseEvent { private async handleEvent(data: TypePayload, callback: (response: boolean) => void) { try { - const mapCharacter = MapManager.getCharacterById(this.socket.characterId!) - if (!mapCharacter) { - this.logger.error('chat:message error', 'Character not found') - return - } - - const character = mapCharacter.character - - if (character.role !== 'gm') { - this.logger.info(`User ${character.id} tried to set time but is not a game master.`) - return - } - + // Check if command is teleport if (!ChatService.isCommand(data.message, 'teleport')) return + // Check if character exists and is GM + if (!(await this.isCharacterGM())) return + + const character = await this.getCharacter() + if (!character) return + const args = ChatService.getArgs('teleport', data.message) if (!args || args.length === 0 || args.length > 3) { @@ -53,7 +47,8 @@ export default class TeleportCommandEvent extends BaseEvent { return } - const map = await MapRepository.getById(mapId) + const mapRepository = new MapRepository() + const map = await mapRepository.getById(mapId) if (!map) { this.socket.emit('notification', { title: 'Server message', diff --git a/src/events/chat/gameMaster/toggleFogCommand.ts b/src/events/chat/gameMaster/toggleFogCommand.ts index 14bb0d6..d77e306 100644 --- a/src/events/chat/gameMaster/toggleFogCommand.ts +++ b/src/events/chat/gameMaster/toggleFogCommand.ts @@ -14,22 +14,11 @@ export default class ToggleFogCommand extends BaseEvent { private async handleEvent(data: TypePayload, callback: (response: boolean) => void): Promise { try { - if (!ChatService.isCommand(data.message, 'fog')) { - return - } + // Check if command is fog + if (!ChatService.isCommand(data.message, 'fog')) return - // Check if character exists - const character = await CharacterRepository.getByUserAndId(this.socket.userId!, this.socket.characterId!) - if (!character) { - this.logger.error('chat:alert_command error', 'Character not found') - return - } - - // Check if the user is the GM - if (character.role !== 'gm') { - this.logger.info(`User ${character.id} tried to set time but is not a game master.`) - return - } + // Check if character exists and is GM + if (!(await this.isCharacterGM())) return await WeatherManager.toggleFog() } catch (error: any) { diff --git a/src/events/chat/gameMaster/toggleRainCommand.ts b/src/events/chat/gameMaster/toggleRainCommand.ts index c5e40d2..039a7f3 100644 --- a/src/events/chat/gameMaster/toggleRainCommand.ts +++ b/src/events/chat/gameMaster/toggleRainCommand.ts @@ -14,22 +14,11 @@ export default class ToggleRainCommand extends BaseEvent { private async handleEvent(data: TypePayload, callback: (response: boolean) => void): Promise { try { - if (!ChatService.isCommand(data.message, 'rain')) { - return - } + // Check if command is rain + if (!ChatService.isCommand(data.message, 'rain')) return - // Check if character exists - const character = await CharacterRepository.getByUserAndId(this.socket.userId!, this.socket.characterId!) - if (!character) { - this.logger.error('chat:alert_command error', 'Character not found') - return - } - - // Check if the user is the GM - if (character.role !== 'gm') { - this.logger.info(`User ${character.id} tried to set time but is not a game master.`) - return - } + // Check if character exists and is GM + if (!(await this.isCharacterGM())) return await WeatherManager.toggleRain() } catch (error: any) { diff --git a/src/events/chat/message.ts b/src/events/chat/message.ts index 7946032..5659b26 100644 --- a/src/events/chat/message.ts +++ b/src/events/chat/message.ts @@ -26,7 +26,8 @@ export default class ChatMessageEvent extends BaseEvent { const character = mapCharacter.character - const map = await MapRepository.getById(character.map.id) + const mapRepository = new MapRepository() + const map = await mapRepository.getById(character.map.id) if (!map) { this.logger.error('chat:message error', 'Map not found') return callback(false) diff --git a/src/events/map/characterMove.ts b/src/events/map/characterMove.ts index 5402bc4..34d68d0 100644 --- a/src/events/map/characterMove.ts +++ b/src/events/map/characterMove.ts @@ -5,6 +5,7 @@ import MapCharacter from '#models/mapCharacter' import mapEventTileRepository from '#repositories/mapEventTileRepository' import CharacterService from '#services/characterService' import MapEventTileService from '#services/mapEventTileService' +import MapEventTileRepository from '#repositories/mapEventTileRepository' export default class CharacterMove extends BaseEvent { private readonly characterService = CharacterService @@ -50,6 +51,7 @@ export default class CharacterMove extends BaseEvent { const [start, end] = [path[i], path[i + 1]] character.rotation = CharacterService.calculateRotation(start.x, start.y, end.x, end.y) + const mapEventTileRepository = new MapEventTileRepository() const mapEventTile = await mapEventTileRepository.getEventTileByMapIdAndPosition(character.map.id, Math.floor(end.x), Math.floor(end.y)) if (mapEventTile?.type === 'BLOCK') break @@ -86,6 +88,7 @@ export default class CharacterMove extends BaseEvent { return } + // @TODO: Replace with TeleportService if (mapEventTile.teleport) { await this.mapEventTileService.handleTeleport(this.io, this.socket, mapCharacter.character, mapEventTile.teleport) } diff --git a/src/events/zone/characterMove.ts b/src/events/zone/characterMove.ts deleted file mode 100644 index 3266958..0000000 --- a/src/events/zone/characterMove.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { BaseEvent } from '#application/base/baseEvent' -import { ZoneEventTileWithTeleport } from '#application/types' -import ZoneManager from '#managers/zoneManager' -import ZoneCharacter from '#models/zoneCharacter' -import zoneEventTileRepository from '#repositories/zoneEventTileRepository' -import CharacterService from '#services/characterService' -import ZoneEventTileService from '#services/zoneEventTileService' - -export default class CharacterMove extends BaseEvent { - private readonly characterService = CharacterService - private readonly zoneEventTileService = ZoneEventTileService - - public listen(): void { - this.socket.on('zone:character:move', this.handleEvent.bind(this)) - } - - private async handleEvent({ positionX, positionY }: { positionX: number; positionY: number }): Promise { - const zoneCharacter = ZoneManager.getCharacterById(this.socket.characterId!) - if (!zoneCharacter?.character) { - this.logger.error('zone:character:move error: Character not found or not initialized') - 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, 50)) - } - - const path = await this.characterService.calculatePath(zoneCharacter.character, positionX, positionY) - if (!path) { - this.io.in(zoneCharacter.character.zone.id).emit('zone:character:moveError', 'No valid path found') - return - } - - // 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 - - try { - for (let i = 0; i < path.length - 1; i++) { - if (!zoneCharacter.isMoving || zoneCharacter.currentPath !== path) { - return - } - - const [start, end] = [path[i], path[i + 1]] - character.rotation = CharacterService.calculateRotation(start.x, start.y, end.x, end.y) - - const zoneEventTile = await zoneEventTileRepository.getEventTileByZoneIdAndPosition(character.zone.id, Math.floor(end.x), Math.floor(end.y)) - - if (zoneEventTile?.type === 'BLOCK') break - if (zoneEventTile?.type === 'TELEPORT' && zoneEventTile.teleport) { - await this.handleZoneEventTile(zoneEventTile as ZoneEventTileWithTeleport) - break - } - - character.positionX = end.x - character.positionY = end.y - - this.io.in(character.zone.id).emit('zone:character:move', { - characterId: character.id, - positionX: character.positionX, - positionY: character.positionY, - rotation: character.rotation, - isMoving: true - }) - - await this.characterService.applyMovementDelay() - } - } finally { - if (zoneCharacter.isMoving && zoneCharacter.currentPath === path) { - this.finalizeMovement(zoneCharacter) - } - } - } - - private async handleZoneEventTile(zoneEventTile: ZoneEventTileWithTeleport): Promise { - const zoneCharacter = ZoneManager.getCharacterById(this.socket.characterId!) - if (!zoneCharacter) { - this.logger.error('zone:character:move error: Character not found') - return - } - - if (zoneEventTile.teleport) { - await this.zoneEventTileService.handleTeleport(this.io, this.socket, zoneCharacter.character, zoneEventTile.teleport) - } - } - - private finalizeMovement(zoneCharacter: ZoneCharacter): void { - zoneCharacter.isMoving = false - this.io.in(zoneCharacter.character.zone.id).emit('zone:character:move', { - characterId: zoneCharacter.character.id, - positionX: zoneCharacter.character.positionX, - positionY: zoneCharacter.character.positionY, - rotation: zoneCharacter.character.rotation, - isMoving: false - }) - } -}