1
0
forked from noxious/server
noxious_server/src/managers/zoneManager.ts

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()