New method for events + TP work
This commit is contained in:
66
src/services/character/characterMoveService.ts
Normal file
66
src/services/character/characterMoveService.ts
Normal file
@ -0,0 +1,66 @@
|
||||
import { ExtendedCharacter } from '../../utilities/types'
|
||||
import { AStar } from '../../utilities/character/aStar'
|
||||
import ZoneManager from '../../managers/zoneManager'
|
||||
import prisma from '../../utilities/prisma'
|
||||
import Rotation from '../../utilities/character/rotation'
|
||||
|
||||
export class CharacterMoveService {
|
||||
private moveTokens: Map<number, symbol> = new Map()
|
||||
|
||||
public async updatePosition(character: ExtendedCharacter, position: { x: number; y: number }, newZoneId?: number): Promise<void> {
|
||||
const oldZoneId = character.zoneId
|
||||
|
||||
Object.assign(character, {
|
||||
positionX: position.x,
|
||||
positionY: position.y,
|
||||
rotation: Rotation.calculate(character.positionX, character.positionY, position.x, position.y),
|
||||
zoneId: newZoneId || character.zoneId
|
||||
})
|
||||
|
||||
if (newZoneId && newZoneId !== oldZoneId) {
|
||||
ZoneManager.removeCharacterFromZone(oldZoneId, character)
|
||||
ZoneManager.addCharacterToZone(newZoneId, character)
|
||||
} else {
|
||||
ZoneManager.updateCharacterInZone(character.zoneId, character)
|
||||
}
|
||||
|
||||
await prisma.character.update({
|
||||
where: { id: character.id },
|
||||
data: {
|
||||
positionX: position.x,
|
||||
positionY: position.y,
|
||||
rotation: character.rotation,
|
||||
zoneId: character.zoneId
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
public async calculatePath(character: ExtendedCharacter, targetX: number, targetY: number): Promise<Array<{ x: number; y: number }> | null> {
|
||||
const grid = await ZoneManager.getGrid(character.zoneId)
|
||||
if (!grid?.length) {
|
||||
console.error('character:move error', 'Grid not found or empty')
|
||||
return null
|
||||
}
|
||||
|
||||
const start = { x: Math.floor(character.positionX), y: Math.floor(character.positionY) }
|
||||
const end = { x: Math.floor(targetX), y: Math.floor(targetY) }
|
||||
|
||||
return AStar.findPath(start, end, grid)
|
||||
}
|
||||
|
||||
public startMovement(characterId: number): void {
|
||||
this.moveTokens.set(characterId, Symbol('moveToken'))
|
||||
}
|
||||
|
||||
public stopMovement(characterId: number): void {
|
||||
this.moveTokens.delete(characterId)
|
||||
}
|
||||
|
||||
public isMoving(characterId: number): boolean {
|
||||
return this.moveTokens.has(characterId)
|
||||
}
|
||||
|
||||
public async applyMovementDelay(): Promise<void> {
|
||||
await new Promise((resolve) => setTimeout(resolve, 250)) // 50ms delay between steps
|
||||
}
|
||||
}
|
17
src/services/character/movementValidator.ts
Normal file
17
src/services/character/movementValidator.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { ExtendedCharacter } from '../../utilities/types'
|
||||
import ZoneManager from '../../managers/zoneManager'
|
||||
|
||||
export class MovementValidator {
|
||||
public async isValidMove(character: ExtendedCharacter, position: { x: number; y: number }): Promise<boolean> {
|
||||
const grid = await ZoneManager.getGrid(character.zoneId)
|
||||
if (!grid?.length) return false
|
||||
|
||||
return !this.isObstacle(position, grid)
|
||||
}
|
||||
|
||||
private isObstacle({ x, y }: { x: number; y: number }, grid: number[][]): boolean {
|
||||
const gridX = Math.floor(x)
|
||||
const gridY = Math.floor(y)
|
||||
return grid[gridY]?.[gridX] === 1 || grid[gridY]?.[Math.ceil(x)] === 1 || grid[Math.ceil(y)]?.[gridX] === 1 || grid[Math.ceil(y)]?.[Math.ceil(x)] === 1
|
||||
}
|
||||
}
|
37
src/services/character/teleportService.ts
Normal file
37
src/services/character/teleportService.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import { ExtendedCharacter, TSocket } from '../../utilities/types'
|
||||
import prisma from '../../utilities/prisma'
|
||||
import ZoneRepository from '../../repositories/zoneRepository'
|
||||
import ZoneManager from '../../managers/zoneManager'
|
||||
|
||||
export class TeleportService {
|
||||
public async checkForTeleport(character: ExtendedCharacter, position: { x: number; y: number }): Promise<any | null> {
|
||||
return prisma.zoneEventTile.findFirst({
|
||||
where: {
|
||||
zoneId: character.zoneId,
|
||||
type: 'TELEPORT',
|
||||
positionX: Math.floor(position.x),
|
||||
positionY: Math.floor(position.y)
|
||||
},
|
||||
include: { teleport: true }
|
||||
})
|
||||
}
|
||||
|
||||
public async handleTeleport(socket: TSocket, character: ExtendedCharacter, teleport: any): Promise<void> {
|
||||
if (teleport.toZoneId === character.zoneId) return
|
||||
|
||||
const zone = await ZoneRepository.getById(teleport.toZoneId)
|
||||
if (!zone) return
|
||||
|
||||
character.zoneId = teleport.toZoneId
|
||||
character.positionX = teleport.toPositionX
|
||||
character.positionY = teleport.toPositionY
|
||||
|
||||
socket.leave(character.zoneId.toString())
|
||||
socket.join(teleport.toZoneId.toString())
|
||||
|
||||
socket.emit('zone:teleport', {
|
||||
zone,
|
||||
characters: ZoneManager.getCharactersInZone(zone.id)
|
||||
})
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user