Joining, leaving rooms and teleporting works again + refactor
This commit is contained in:
83
src/services/teleportService.ts
Normal file
83
src/services/teleportService.ts
Normal 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()
|
Reference in New Issue
Block a user