This commit is contained in:
Dennis Postma 2024-08-22 20:00:37 +02:00
parent ff7664bae0
commit c4b50ec811
16 changed files with 97 additions and 80 deletions

View File

@ -25,8 +25,8 @@ CREATE TABLE `SpriteAction` (
`spriteId` VARCHAR(191) NOT NULL,
`action` VARCHAR(191) NOT NULL,
`sprites` JSON NULL,
`origin_x` DECIMAL(65, 30) NOT NULL DEFAULT 0,
`origin_y` DECIMAL(65, 30) NOT NULL DEFAULT 0,
`originX` DECIMAL(65, 30) NOT NULL DEFAULT 0,
`originY` DECIMAL(65, 30) NOT NULL DEFAULT 0,
`isAnimated` BOOLEAN NOT NULL DEFAULT false,
`isLooping` BOOLEAN NOT NULL DEFAULT false,
`frameWidth` INTEGER NOT NULL DEFAULT 0,
@ -69,8 +69,8 @@ CREATE TABLE `Character` (
`level` INTEGER NOT NULL DEFAULT 1,
`experience` INTEGER NOT NULL DEFAULT 0,
`role` VARCHAR(191) NOT NULL DEFAULT 'player',
`position_x` INTEGER NOT NULL DEFAULT 0,
`position_y` INTEGER NOT NULL DEFAULT 0,
`positionX` INTEGER NOT NULL DEFAULT 0,
`positionY` INTEGER NOT NULL DEFAULT 0,
`rotation` INTEGER NOT NULL DEFAULT 0,
`zoneId` INTEGER NOT NULL DEFAULT 1,
`characterTypeId` INTEGER NULL,
@ -105,8 +105,8 @@ CREATE TABLE `Object` (
`id` VARCHAR(191) NOT NULL,
`name` VARCHAR(191) NOT NULL,
`tags` JSON NULL,
`origin_x` DECIMAL(65, 30) NOT NULL DEFAULT 0,
`origin_y` DECIMAL(65, 30) NOT NULL DEFAULT 0,
`originX` DECIMAL(65, 30) NOT NULL DEFAULT 0,
`originY` DECIMAL(65, 30) NOT NULL DEFAULT 0,
`isAnimated` BOOLEAN NOT NULL DEFAULT false,
`frameSpeed` INTEGER NOT NULL DEFAULT 0,
`frameWidth` INTEGER NOT NULL DEFAULT 0,
@ -149,8 +149,8 @@ CREATE TABLE `ZoneObject` (
`zoneId` INTEGER NOT NULL,
`objectId` VARCHAR(191) NOT NULL,
`depth` INTEGER NOT NULL DEFAULT 0,
`position_x` INTEGER NOT NULL DEFAULT 0,
`position_y` INTEGER NOT NULL DEFAULT 0,
`positionX` INTEGER NOT NULL DEFAULT 0,
`positionY` INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
@ -160,21 +160,21 @@ CREATE TABLE `ZoneEventTile` (
`id` VARCHAR(191) NOT NULL,
`zoneId` INTEGER NOT NULL,
`type` ENUM('BLOCK', 'TELEPORT', 'NPC', 'ITEM') NOT NULL,
`position_x` INTEGER NOT NULL,
`position_y` INTEGER NOT NULL,
`teleportId` VARCHAR(191) NULL,
`positionX` INTEGER NOT NULL,
`positionY` INTEGER NOT NULL,
UNIQUE INDEX `ZoneEventTile_teleportId_key`(`teleportId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `ZoneEventTileTeleport` (
`id` VARCHAR(191) NOT NULL,
`zoneEventTileId` VARCHAR(191) NOT NULL,
`toZoneId` INTEGER NOT NULL,
`toPosition_x` INTEGER NOT NULL,
`toPosition_y` INTEGER NOT NULL,
`toPositionX` INTEGER NOT NULL,
`toPositionY` INTEGER NOT NULL,
UNIQUE INDEX `ZoneEventTileTeleport_zoneEventTileId_key`(`zoneEventTileId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
@ -215,7 +215,7 @@ ALTER TABLE `ZoneObject` ADD CONSTRAINT `ZoneObject_objectId_fkey` FOREIGN KEY (
ALTER TABLE `ZoneEventTile` ADD CONSTRAINT `ZoneEventTile_zoneId_fkey` FOREIGN KEY (`zoneId`) REFERENCES `Zone`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `ZoneEventTile` ADD CONSTRAINT `ZoneEventTile_teleportId_fkey` FOREIGN KEY (`teleportId`) REFERENCES `ZoneEventTileTeleport`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE `ZoneEventTileTeleport` ADD CONSTRAINT `ZoneEventTileTeleport_zoneEventTileId_fkey` FOREIGN KEY (`zoneEventTileId`) REFERENCES `ZoneEventTile`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `ZoneEventTileTeleport` ADD CONSTRAINT `ZoneEventTileTeleport_toZoneId_fkey` FOREIGN KEY (`toZoneId`) REFERENCES `Zone`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -13,8 +13,8 @@ model SpriteAction {
sprite Sprite @relation(fields: [spriteId], references: [id], onDelete: Cascade)
action String
sprites Json?
origin_x Decimal @default(0)
origin_y Decimal @default(0)
originX Decimal @default(0)
originY Decimal @default(0)
isAnimated Boolean @default(false)
isLooping Boolean @default(false)
frameWidth Int @default(0)

View File

@ -40,8 +40,8 @@ model Character {
level Int @default(1)
experience Int @default(0)
role String @default("player")
position_x Int @default(0)
position_y Int @default(0)
positionX Int @default(0)
positionY Int @default(0)
rotation Int @default(0)
zoneId Int @default(1)
zone Zone @relation(fields: [zoneId], references: [id], onDelete: Cascade)

View File

@ -10,8 +10,8 @@ model Object {
id String @id @default(uuid())
name String
tags Json?
origin_x Decimal @default(0)
origin_y Decimal @default(0)
originX Decimal @default(0)
originY Decimal @default(0)
isAnimated Boolean @default(false)
frameSpeed Int @default(0)
frameWidth Int @default(0)
@ -48,14 +48,14 @@ model Zone {
}
model ZoneObject {
id String @id @default(uuid())
zoneId Int
zone Zone @relation(fields: [zoneId], references: [id], onDelete: Cascade)
objectId String
object Object @relation(fields: [objectId], references: [id], onDelete: Cascade)
depth Int @default(0)
position_x Int @default(0)
position_y Int @default(0)
id String @id @default(uuid())
zoneId Int
zone Zone @relation(fields: [zoneId], references: [id], onDelete: Cascade)
objectId String
object Object @relation(fields: [objectId], references: [id], onDelete: Cascade)
depth Int @default(0)
positionX Int @default(0)
positionY Int @default(0)
}
enum ZoneEventTileType {
@ -66,21 +66,21 @@ enum ZoneEventTileType {
}
model ZoneEventTile {
id String @id @default(uuid())
zoneId Int
zone Zone @relation(fields: [zoneId], references: [id], onDelete: Cascade)
type ZoneEventTileType
position_x Int
position_y Int
teleportId String? @unique
teleport ZoneEventTileTeleport? @relation("ZoneEventTileTeleport", fields: [teleportId], references: [id])
id String @id @default(uuid())
zoneId Int
zone Zone @relation(fields: [zoneId], references: [id], onDelete: Cascade)
type ZoneEventTileType
positionX Int
positionY Int
teleport ZoneEventTileTeleport?
}
model ZoneEventTileTeleport {
id String @id @default(uuid())
zoneEventTile ZoneEventTile? @relation("ZoneEventTileTeleport")
toZoneId Int
toZone Zone @relation(fields: [toZoneId], references: [id], onDelete: Cascade)
toPosition_x Int
toPosition_y Int
id String @id @default(uuid())
zoneEventTileId String @unique
zoneEventTile ZoneEventTile @relation(fields: [zoneEventTileId], references: [id], onDelete: Cascade)
toZoneId Int
toZone Zone @relation(fields: [toZoneId], references: [id], onDelete: Cascade)
toPositionX Int
toPositionY Int
}

View File

@ -30,7 +30,7 @@ export default function (socket: TSocket, io: Server) {
const character: Character = await prisma.character.create({
data: {
name: data.name,
userId: user_id,
userId: user_id
// characterTypeId: 1 // @TODO set to chosen character type
}
})

View File

@ -8,7 +8,7 @@ import Rotation from '../../utilities/player/rotation'
const moveTokens = new Map<number, symbol>()
export default function setupCharacterMove(socket: TSocket, io: Server) {
socket.on('character:move', async ({ position_x, position_y }: { position_x: number; position_y: number }) => {
socket.on('character:move', async ({ positionX, positionY }: { positionX: number; positionY: number }) => {
const { character } = socket
if (!character) return console.error('character:move error', 'Character not found')
@ -16,8 +16,8 @@ export default function setupCharacterMove(socket: TSocket, io: Server) {
const grid = await ZoneManager.getGrid(character.zoneId)
if (!grid?.length) return console.error('character:move error', 'Grid not found or empty')
const start = { x: Math.floor(character.position_x), y: Math.floor(character.position_y) }
const end = { x: Math.floor(position_x), y: Math.floor(position_y) }
const start = { x: Math.floor(character.positionX), y: Math.floor(character.positionY) }
const end = { x: Math.floor(positionX), y: Math.floor(positionY) }
if (isObstacle(end, grid)) return socket.emit('character:moveError', 'Destination is an obstacle')
@ -80,17 +80,14 @@ const interpolatePosition = (start: { x: number; y: number }, end: { x: number;
const isObstacle = ({ x, y }: { x: number; y: number }, grid: number[][]) => {
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
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
}
async function updateCharacter(character: ExtendedCharacter, { x, y }: { x: number; y: number }, rotation: number) {
Object.assign(character, { position_x: x, position_y: y, rotation })
Object.assign(character, { positionX: x, positionY: y, rotation })
ZoneManager.updateCharacterInZone(character.zoneId, character)
await prisma.character.update({
where: { id: character.id },
data: { position_x: x, position_y: y, rotation }
data: { positionX: x, positionY: y, rotation }
})
}

View File

@ -6,8 +6,8 @@ type Payload = {
id: string
name: string
tags: string[]
origin_x: number
origin_y: number
originX: number
originY: number
isAnimated: boolean
frameSpeed: number
frameWidth: number
@ -33,8 +33,8 @@ export default function (socket: TSocket, io: Server) {
data: {
name: data.name,
tags: data.tags,
origin_x: data.origin_x,
origin_y: data.origin_y,
originX: data.originX,
originY: data.originY,
isAnimated: data.isAnimated,
frameSpeed: data.frameSpeed,
frameWidth: data.frameWidth,

View File

@ -32,8 +32,8 @@ export default function (socket: TSocket, io: Server) {
data: {
name: key,
tags: [],
origin_x: 0,
origin_y: 0
originX: 0,
originY: 0
}
})

View File

@ -98,11 +98,11 @@ async function updateDatabase(id: string, name: string, processedActions: Proces
name,
spriteActions: {
deleteMany: { spriteId: id },
create: processedActions.map(({ action, sprites, origin_x, origin_y, isAnimated, isLooping, frameWidth, frameHeight, frameSpeed }) => ({
create: processedActions.map(({ action, sprites, originX, originY, isAnimated, isLooping, frameWidth, frameHeight, frameSpeed }) => ({
action,
sprites,
origin_x,
origin_y,
originX,
originY,
isAnimated,
isLooping,
frameWidth,

View File

@ -1,7 +1,7 @@
import { Server } from 'socket.io'
import { TSocket } from '../../../utilities/types'
import ZoneRepository from '../../../repositories/zoneRepository'
import { ZoneEventTile, ZoneObject } from '@prisma/client'
import { ZoneEventTile, ZoneEventTileType, ZoneObject } from '@prisma/client'
import prisma from '../../../utilities/prisma'
import zoneManager from '../../../managers/zoneManager'
@ -12,7 +12,16 @@ interface IPayload {
height: number
tiles: string[][]
pvp: boolean
zoneEventTiles: ZoneEventTile[]
zoneEventTiles: {
type: ZoneEventTileType
positionX: number
positionY: number
teleport?: {
toZoneId: number
toPositionX: number
toPositionY: number
}
}[]
zoneObjects: ZoneObject[]
}
@ -62,8 +71,19 @@ export default function (socket: TSocket, io: Server) {
// Save new zone event tiles
create: data.zoneEventTiles.map((zoneEventTile) => ({
type: zoneEventTile.type,
position_x: zoneEventTile.position_x,
position_y: zoneEventTile.position_y
positionX: zoneEventTile.positionX,
positionY: zoneEventTile.positionY,
...(zoneEventTile.type === 'TELEPORT' && zoneEventTile.teleport
? {
teleport: {
create: {
toZoneId: zoneEventTile.teleport.toZoneId,
toPositionX: zoneEventTile.teleport.toPositionX,
toPositionY: zoneEventTile.teleport.toPositionY
}
}
}
: {})
}))
},
zoneObjects: {
@ -74,8 +94,8 @@ export default function (socket: TSocket, io: Server) {
create: data.zoneObjects.map((zoneObject) => ({
objectId: zoneObject.objectId,
depth: zoneObject.depth,
position_x: zoneObject.position_x,
position_y: zoneObject.position_y
positionX: zoneObject.positionX,
positionY: zoneObject.positionY
}))
}
}

View File

@ -63,7 +63,7 @@ class ZoneManager {
const loadedZone = this.loadedZones.find((loadedZone) => {
return loadedZone.zone.id === zoneId
})
if (loadedZone && this.isPositionWalkable(zoneId, character.position_x, character.position_y)) {
if (loadedZone && this.isPositionWalkable(zoneId, character.positionX, character.positionY)) {
loadedZone.characters.push(character)
}
}
@ -114,7 +114,7 @@ class ZoneManager {
// Set the grid values based on the event tiles, these are strings
eventTiles.forEach((eventTile) => {
if (eventTile.type === 'BLOCK') {
grid[eventTile.position_y][eventTile.position_x] = 1
grid[eventTile.positionY][eventTile.positionX] = 1
}
})

View File

@ -66,15 +66,15 @@ class CharacterRepository {
}
}
async updatePosition(id: number, position_x: number, position_y: number): Promise<Character | null> {
async updatePosition(id: number, positionX: number, positionY: number): Promise<Character | null> {
try {
return await prisma.character.update({
where: {
id: id
},
data: {
position_x,
position_y
positionX,
positionY
}
})
} catch (error: any) {

View File

@ -29,7 +29,8 @@ class ZoneRepository {
include: {
zoneEventTiles: {
include: {
zone: true
zone: true,
teleport: true
}
},
zoneObjects: {

View File

@ -15,7 +15,6 @@ import { Authentication } from './middleware/authentication'
import { Dirent } from 'node:fs'
import logger from './utilities/logger'
export class Server {
private readonly app: Application
private readonly http: HTTPServer
@ -104,4 +103,4 @@ export class Server {
const server = new Server()
server.start()
console.log('Server started')
console.log('Server started')

View File

@ -12,9 +12,9 @@ const logger = pino({
formatters: {
level: (label) => {
return { level: label.toUpperCase() }
},
}
},
timestamp: pino.stdTimeFunctions.isoTime
})
export default logger
export default logger

View File

@ -4,9 +4,9 @@ export type Node = Position & { parent?: Node; g: number; h: number; f: number }
export class AStar {
private static readonly DIRECTIONS = [
{ x: 0, y: -1 }, // Up
{ x: 0, y: 1 }, // Down
{ x: 0, y: 1 }, // Down
{ x: -1, y: 0 }, // Left
{ x: 1, y: 0 }, // Right
{ x: 1, y: 0 }, // Right
{ x: -1, y: -1 },
{ x: -1, y: 1 },
{ x: 1, y: -1 },