Joining, leaving rooms and teleporting works again + refactor

This commit is contained in:
2025-01-01 04:46:00 +01:00
parent 30b2028bd8
commit 495e9f192e
5 changed files with 175 additions and 97 deletions

View File

@ -0,0 +1,83 @@
import { Character } from '#entities/character'
import ZoneManager from '#managers/zoneManager'
import SocketManager from '#managers/socketManager'
import Logger, { LoggerType } from '#application/logger'
import ZoneCharacter from '#models/zoneCharacter'
interface TeleportOptions {
targetZoneId: number
targetX: number
targetY: number
rotation?: number
isInitialJoin?: boolean
character?: Character
}
class TeleportService {
private readonly logger = Logger.type(LoggerType.GAME)
public async teleportCharacter(characterId: number, options: TeleportOptions): Promise<boolean> {
const { targetZoneId, targetX, targetY, rotation = 0, isInitialJoin = false, character } = options
const socket = SocketManager.getSocketByCharacterId(characterId)
const targetZone = ZoneManager.getZoneById(targetZoneId)
if (!socket || !targetZone) {
this.logger.error(`Teleport failed - Missing socket or target zone for character ${characterId}`)
return false
}
if (isInitialJoin && !character) {
this.logger.error('Initial join requires character data')
return false
}
const existingCharacter = !isInitialJoin && ZoneManager.getCharacterById(characterId)
const zoneCharacter = isInitialJoin
? new ZoneCharacter(character!)
: existingCharacter || (() => {
this.logger.error(`Teleport failed - Character ${characterId} not found in ZoneManager`)
return null
})()
if (!zoneCharacter) return false
try {
const currentZoneId = zoneCharacter.character.zone?.id
const io = SocketManager.getIO()
// Handle current zone cleanup
if (currentZoneId) {
socket.leave(currentZoneId.toString())
ZoneManager.removeCharacter(characterId)
io.in(currentZoneId.toString()).emit('zone:character:leave', characterId)
}
// Update character position and zone
await zoneCharacter.character
.setPositionX(targetX)
.setPositionY(targetY)
.setRotation(rotation)
.setZone(targetZone.getZone())
.update()
// Join new zone
socket.join(targetZoneId.toString())
targetZone.addCharacter(zoneCharacter.character)
// Notify clients
io.in(targetZoneId.toString()).emit('zone:character:join', zoneCharacter)
socket.emit('zone:character:teleport', {
zone: targetZone.getZone(),
characters: targetZone.getCharactersInZone()
})
return true
} catch (error) {
this.logger.error(`Teleport error for character ${characterId}: ${error}`)
return false
}
}
}
export default new TeleportService()