forked from noxious/server
154 lines
4.6 KiB
TypeScript
154 lines
4.6 KiB
TypeScript
import { Character, Zone } from '@prisma/client'
|
|
import ZoneRepository from '../repositories/zoneRepository'
|
|
import ZoneService from '../services/zoneService'
|
|
import zoneRepository from '../repositories/zoneRepository'
|
|
import logger from '../utilities/logger'
|
|
|
|
type TLoadedZone = {
|
|
zone: Zone
|
|
characters: Character[]
|
|
grid: number[][]
|
|
}
|
|
|
|
class ZoneManager {
|
|
private loadedZones: TLoadedZone[] = []
|
|
|
|
// Method to initialize zoneEditor manager
|
|
public async boot() {
|
|
if (!(await ZoneRepository.getById(1))) {
|
|
const zoneService = new ZoneService()
|
|
await zoneService.createDemoZone()
|
|
}
|
|
|
|
const zones = await ZoneRepository.getAll()
|
|
|
|
for (const zone of zones) {
|
|
await this.loadZone(zone)
|
|
}
|
|
|
|
logger.info('Zone manager loaded')
|
|
}
|
|
|
|
// Method to handle individual zoneEditor loading
|
|
public async loadZone(zone: Zone) {
|
|
const grid = await this.getGrid(zone.id) // Create the grid for the zoneEditor
|
|
this.loadedZones.push({
|
|
zone,
|
|
characters: [],
|
|
grid
|
|
})
|
|
logger.info(`Zone ID ${zone.id} loaded`)
|
|
}
|
|
|
|
// Method to handle individual zoneEditor unloading
|
|
public unloadZone(zoneId: number) {
|
|
this.loadedZones = this.loadedZones.filter((loadedZone) => {
|
|
return loadedZone.zone.id !== zoneId
|
|
})
|
|
logger.info(`Zone ID ${zoneId} unloaded`)
|
|
}
|
|
|
|
// Getter for loaded zones
|
|
public getLoadedZones(): TLoadedZone[] {
|
|
return this.loadedZones
|
|
}
|
|
|
|
// Check if position is walkable
|
|
private isPositionWalkable(zoneId: number, x: number, y: number): boolean {
|
|
const loadedZone = this.loadedZones.find((lz) => lz.zone.id === zoneId)
|
|
if (!loadedZone) {
|
|
console.log(`Zone ${zoneId} not found in loadedZones`)
|
|
return false
|
|
}
|
|
if (!loadedZone.grid) {
|
|
console.log(`Grid for zone ${zoneId} is undefined`)
|
|
return false
|
|
}
|
|
if (!loadedZone.grid[y]) {
|
|
console.log(`Row ${y} in grid for zone ${zoneId} is undefined`)
|
|
return false
|
|
}
|
|
return loadedZone.grid[y][x] === 0
|
|
}
|
|
|
|
public addCharacterToZone(zoneId: number, character: Character) {
|
|
console.log(`Adding character ${character.id} to zone ${zoneId}`)
|
|
console.log(`Character position: x=${character.positionX}, y=${character.positionY}`)
|
|
|
|
const loadedZone = this.loadedZones.find((loadedZone) => {
|
|
return loadedZone.zone.id === zoneId
|
|
})
|
|
|
|
if (!loadedZone) {
|
|
console.log(`Zone ${zoneId} not found in loadedZones`)
|
|
return
|
|
}
|
|
|
|
if (this.isPositionWalkable(zoneId, character.positionX, character.positionY)) {
|
|
loadedZone.characters.push(character)
|
|
console.log(`Character ${character.id} added to zone ${zoneId}`)
|
|
} else {
|
|
// set position to 0,0 if not walkable
|
|
console.log(`Position (${character.positionX}, ${character.positionY}) is not walkable in zone ${zoneId}`)
|
|
character.positionX = 0
|
|
character.positionY = 0
|
|
loadedZone.characters.push(character)
|
|
}
|
|
}
|
|
|
|
public removeCharacterFromZone(zoneId: number, character: Character) {
|
|
const loadedZone = this.loadedZones.find((loadedZone) => {
|
|
return loadedZone.zone.id === zoneId
|
|
})
|
|
if (loadedZone) {
|
|
loadedZone.characters = loadedZone.characters.filter((loadedCharacter) => {
|
|
return loadedCharacter.id !== character.id
|
|
})
|
|
}
|
|
}
|
|
|
|
public updateCharacterInZone(zoneId: number, character: Character) {
|
|
const loadedZone = this.loadedZones.find((loadedZone) => {
|
|
return loadedZone.zone.id === zoneId
|
|
})
|
|
if (loadedZone) {
|
|
const characterIndex = loadedZone.characters.findIndex((loadedCharacter) => {
|
|
return loadedCharacter.id === character.id
|
|
})
|
|
if (characterIndex !== -1) {
|
|
loadedZone.characters[characterIndex] = character
|
|
}
|
|
}
|
|
}
|
|
|
|
public getCharactersInZone(zoneId: number): Character[] {
|
|
const loadedZone = this.loadedZones.find((loadedZone) => {
|
|
return loadedZone.zone.id === zoneId
|
|
})
|
|
return loadedZone ? loadedZone.characters : []
|
|
}
|
|
|
|
public async getGrid(zoneId: number): Promise<number[][]> {
|
|
const zone = this.loadedZones.find((z) => z.zone.id === zoneId)
|
|
if (zone) return zone.grid
|
|
|
|
const loadedZone = await ZoneRepository.getById(zoneId)
|
|
if (!loadedZone) return []
|
|
|
|
let grid: number[][] = Array.from({ length: loadedZone.height }, () => Array.from({ length: loadedZone.width }, () => 0))
|
|
|
|
const eventTiles = await zoneRepository.getEventTiles(zoneId)
|
|
|
|
// Set the grid values based on the event tiles, these are strings
|
|
eventTiles.forEach((eventTile) => {
|
|
if (eventTile.type === 'BLOCK') {
|
|
grid[eventTile.positionY][eventTile.positionX] = 1
|
|
}
|
|
})
|
|
|
|
return grid
|
|
}
|
|
}
|
|
|
|
export default new ZoneManager()
|