Improved service names, added attack anim. sprite to init.ts, added attackService, added attack event
This commit is contained in:
102
src/services/characterTeleportService.ts
Normal file
102
src/services/characterTeleportService.ts
Normal file
@ -0,0 +1,102 @@
|
||||
import Logger, { LoggerType } from '#application/logger'
|
||||
import { UUID } from '#application/types'
|
||||
import { Character } from '#entities/character'
|
||||
import MapManager from '#managers/mapManager'
|
||||
import SocketManager from '#managers/socketManager'
|
||||
import MapCharacter from '#models/mapCharacter'
|
||||
import MapRepository from '#repositories/mapRepository'
|
||||
|
||||
interface TeleportOptions {
|
||||
targetMapId: UUID
|
||||
targetX: number
|
||||
targetY: number
|
||||
rotation?: number
|
||||
isInitialJoin?: boolean
|
||||
character?: Character
|
||||
}
|
||||
|
||||
class CharacterTeleportService {
|
||||
private readonly logger = Logger.type(LoggerType.GAME)
|
||||
|
||||
public async teleportCharacter(characterId: UUID, options: TeleportOptions): Promise<boolean> {
|
||||
const mapRepository = new MapRepository()
|
||||
const socket = SocketManager.getSocketByCharacterId(characterId)
|
||||
const targetMap = MapManager.getMapById(options.targetMapId)
|
||||
|
||||
if (!socket || !targetMap) {
|
||||
this.logger.error(`Teleport failed - Missing socket or target map for character ${characterId}`)
|
||||
return false
|
||||
}
|
||||
|
||||
if (options.isInitialJoin && !options.character) {
|
||||
this.logger.error('Initial join requires character data')
|
||||
return false
|
||||
}
|
||||
|
||||
const existingCharacter = !options.isInitialJoin && MapManager.getCharacterById(characterId)
|
||||
const mapCharacter = options.isInitialJoin
|
||||
? new MapCharacter(options.character!)
|
||||
: existingCharacter ||
|
||||
(() => {
|
||||
this.logger.error(`Teleport failed - Character ${characterId} not found in MapManager`)
|
||||
return null
|
||||
})()
|
||||
|
||||
if (!mapCharacter) return false
|
||||
|
||||
try {
|
||||
const currentMapId = mapCharacter.character.map?.id
|
||||
const io = SocketManager.getIO()
|
||||
|
||||
// Update character position and map
|
||||
await mapCharacter
|
||||
.getCharacter()
|
||||
.setPositionX(options.targetX)
|
||||
.setPositionY(options.targetY)
|
||||
.setRotation(options.rotation ?? 0)
|
||||
.setMap(targetMap.getMap())
|
||||
.save()
|
||||
|
||||
// If the current map is the target map and we are not joining, send move event
|
||||
if (currentMapId === options.targetMapId && !options.isInitialJoin) {
|
||||
// If the current map is the target map, send move event
|
||||
io.in(currentMapId).emit('map:character:move', {
|
||||
characterId: mapCharacter.character.id,
|
||||
positionX: options.targetX,
|
||||
positionY: options.targetY,
|
||||
rotation: options.rotation ?? 0,
|
||||
isMoving: false
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
// Handle current map cleanup
|
||||
if (currentMapId) {
|
||||
socket.leave(currentMapId)
|
||||
MapManager.removeCharacter(characterId)
|
||||
io.in(currentMapId).emit('map:character:leave', characterId)
|
||||
}
|
||||
|
||||
// Join new map
|
||||
socket.join(options.targetMapId)
|
||||
targetMap.addCharacter(mapCharacter.getCharacter())
|
||||
|
||||
const map = await mapRepository.getById(options.targetMapId)
|
||||
await mapRepository.getEntityManager().populate(map!, mapRepository.POPULATE_TELEPORT as any)
|
||||
|
||||
// Notify clients
|
||||
io.in(options.targetMapId).emit('map:character:join', mapCharacter)
|
||||
socket.emit('map:character:teleport', {
|
||||
mapId: options.targetMapId,
|
||||
characters: targetMap.getCharactersInMap()
|
||||
})
|
||||
|
||||
return true
|
||||
} catch (error) {
|
||||
this.logger.error(`Teleport error for character ${characterId}: ${error}`)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new CharacterTeleportService()
|
Reference in New Issue
Block a user