forked from noxious/server
Fixes for teleporting between zones
This commit is contained in:
parent
22bf43b14d
commit
358aa795e4
@ -20,7 +20,7 @@ interface IResponse {
|
|||||||
* @param io
|
* @param io
|
||||||
*/
|
*/
|
||||||
export default function (socket: TSocket, io: Server) {
|
export default function (socket: TSocket, io: Server) {
|
||||||
socket.on('zone:characterJoin', async (data: IPayload, callback: (response: IResponse) => void) => {
|
socket.on('zone:character:join', async (data: IPayload, callback: (response: IResponse) => void) => {
|
||||||
try {
|
try {
|
||||||
console.log(`---User ${socket.character?.id} has requested zone.`)
|
console.log(`---User ${socket.character?.id} has requested zone.`)
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ export default function (socket: TSocket, io: Server) {
|
|||||||
socket.join(zone.id.toString())
|
socket.join(zone.id.toString())
|
||||||
|
|
||||||
// let other clients know of new character
|
// let other clients know of new character
|
||||||
io.to(zone.id.toString()).emit('zone:characterJoin', socket.character)
|
io.to(zone.id.toString()).emit('zone:character:join', socket.character)
|
||||||
|
|
||||||
// add character to zone manager
|
// add character to zone manager
|
||||||
ZoneManager.addCharacterToZone(zone.id, socket.character as Character)
|
ZoneManager.addCharacterToZone(zone.id, socket.character as Character)
|
||||||
|
@ -10,7 +10,7 @@ import { Character, Zone } from '@prisma/client'
|
|||||||
* @param io
|
* @param io
|
||||||
*/
|
*/
|
||||||
export default function (socket: TSocket, io: Server) {
|
export default function (socket: TSocket, io: Server) {
|
||||||
socket.on('zone:characterLeave', async () => {
|
socket.on('zone:character:leave', async () => {
|
||||||
console.log(`---Socket ${socket.character?.id} has leaved zone.`)
|
console.log(`---Socket ${socket.character?.id} has leaved zone.`)
|
||||||
|
|
||||||
if (!socket.character) {
|
if (!socket.character) {
|
||||||
|
@ -9,7 +9,7 @@ import Rotation from '../../utilities/character/rotation'
|
|||||||
import logger from '../../utilities/logger'
|
import logger from '../../utilities/logger'
|
||||||
|
|
||||||
type ZoneEventTileWithTeleport = ZoneEventTile & {
|
type ZoneEventTileWithTeleport = ZoneEventTile & {
|
||||||
teleport: ZoneEventTileTeleport | null
|
teleport: ZoneEventTileTeleport
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class CharacterMoveEvent {
|
export default class CharacterMoveEvent {
|
||||||
@ -62,25 +62,36 @@ export default class CharacterMoveEvent {
|
|||||||
const zoneEventTile = await prisma.zoneEventTile.findFirst({
|
const zoneEventTile = await prisma.zoneEventTile.findFirst({
|
||||||
where: {
|
where: {
|
||||||
zoneId: character.zoneId,
|
zoneId: character.zoneId,
|
||||||
type: 'TELEPORT',
|
|
||||||
positionX: Math.floor(end.x),
|
positionX: Math.floor(end.x),
|
||||||
positionY: Math.floor(end.y)
|
positionY: Math.floor(end.y)
|
||||||
},
|
}
|
||||||
include: { teleport: true }
|
});
|
||||||
}) as ZoneEventTileWithTeleport | null
|
|
||||||
|
|
||||||
if (zoneEventTile) {
|
if (zoneEventTile) {
|
||||||
await this.handleZoneEventTile(zoneEventTile)
|
if (zoneEventTile.type === 'BLOCK') {
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.characterMoveService.updatePosition(character, end)
|
if (zoneEventTile.type === 'TELEPORT') {
|
||||||
this.io.in(character.zoneId.toString()).emit('character:move', character)
|
const teleportTile = await prisma.zoneEventTile.findFirst({
|
||||||
|
where: { id: zoneEventTile.id },
|
||||||
|
include: { teleport: true }
|
||||||
|
}) as ZoneEventTileWithTeleport;
|
||||||
|
|
||||||
await this.characterMoveService.applyMovementDelay()
|
if (teleportTile) {
|
||||||
|
await this.handleZoneEventTile(teleportTile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.finalizeMovement(character)
|
await this.characterMoveService.updatePosition(character, end);
|
||||||
|
this.io.in(character.zoneId.toString()).emit('character:move', character);
|
||||||
|
|
||||||
|
await this.characterMoveService.applyMovementDelay();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.finalizeMovement(character);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async handleZoneEventTile(zoneEventTile: ZoneEventTileWithTeleport): Promise<void> {
|
private async handleZoneEventTile(zoneEventTile: ZoneEventTileWithTeleport): Promise<void> {
|
||||||
|
@ -148,6 +148,33 @@ class ZoneManager {
|
|||||||
|
|
||||||
return grid
|
return grid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async moveCharacterBetweenZones(oldZoneId: number, newZoneId: number, character: Character): Promise<void> {
|
||||||
|
// Find the old and new zones
|
||||||
|
const oldZone = this.loadedZones.find(zone => zone.zone.id === oldZoneId);
|
||||||
|
const newZone = this.loadedZones.find(zone => zone.zone.id === newZoneId);
|
||||||
|
|
||||||
|
if (!oldZone || !newZone) {
|
||||||
|
logger.error(`Unable to move character ${character.id}: zones not found`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove character from old zone
|
||||||
|
oldZone.characters = oldZone.characters.filter(c => c.id !== character.id);
|
||||||
|
|
||||||
|
// Check if the new position is walkable
|
||||||
|
if (this.isPositionWalkable(newZoneId, character.positionX, character.positionY)) {
|
||||||
|
newZone.characters.push(character);
|
||||||
|
} else {
|
||||||
|
// Set position to 0,0 if not walkable
|
||||||
|
logger.warn(`Position (${character.positionX}, ${character.positionY}) is not walkable in zone ${newZoneId}. Moving character to (0,0).`);
|
||||||
|
character.positionX = 0;
|
||||||
|
character.positionY = 0;
|
||||||
|
newZone.characters.push(character);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(`Character ${character.id} moved from zone ${oldZoneId} to zone ${newZoneId}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new ZoneManager()
|
export default new ZoneManager()
|
||||||
|
@ -7,29 +7,44 @@ import { Server } from 'socket.io'
|
|||||||
|
|
||||||
export class ZoneEventTileService {
|
export class ZoneEventTileService {
|
||||||
public async handleTeleport(io: Server, socket: TSocket, character: ExtendedCharacter, teleport: ZoneEventTileTeleport): Promise<void> {
|
public async handleTeleport(io: Server, socket: TSocket, character: ExtendedCharacter, teleport: ZoneEventTileTeleport): Promise<void> {
|
||||||
if (teleport.toZoneId === character.zoneId) return
|
if (teleport.toZoneId === character.zoneId) return;
|
||||||
|
|
||||||
const zone = await ZoneRepository.getById(teleport.toZoneId)
|
const zone = await ZoneRepository.getById(teleport.toZoneId);
|
||||||
if (!zone) return
|
if (!zone) return;
|
||||||
|
|
||||||
const oldZoneId = character.zoneId
|
const oldZoneId = character.zoneId;
|
||||||
const newZoneId = teleport.toZoneId
|
const newZoneId = teleport.toZoneId;
|
||||||
|
|
||||||
character.zoneId = teleport.toZoneId
|
// Update character in database
|
||||||
character.positionX = teleport.toPositionX
|
await prisma.character.update({
|
||||||
character.positionY = teleport.toPositionY
|
where: { id: character.id },
|
||||||
|
data: {
|
||||||
|
zoneId: newZoneId,
|
||||||
|
positionX: teleport.toPositionX,
|
||||||
|
positionY: teleport.toPositionY
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
socket.leave(character.zoneId.toString())
|
// Update local character object
|
||||||
socket.join(teleport.toZoneId.toString())
|
character.zoneId = newZoneId;
|
||||||
|
character.positionX = teleport.toPositionX;
|
||||||
|
character.positionY = teleport.toPositionY;
|
||||||
|
|
||||||
io.to(oldZoneId.toString()).emit('zone:character:leave', character);
|
// Atomic operation in ZoneManager
|
||||||
|
await ZoneManager.moveCharacterBetweenZones(oldZoneId, newZoneId, character as Character);
|
||||||
|
|
||||||
|
// Emit events
|
||||||
|
io.to(oldZoneId.toString()).emit('zone:character:leave', character.id);
|
||||||
io.to(newZoneId.toString()).emit('zone:character:join', character);
|
io.to(newZoneId.toString()).emit('zone:character:join', character);
|
||||||
ZoneManager.removeCharacterFromZone(oldZoneId, character as Character);
|
|
||||||
ZoneManager.addCharacterToZone(newZoneId, character as Character);
|
|
||||||
|
|
||||||
|
// Update socket rooms
|
||||||
|
socket.leave(oldZoneId.toString());
|
||||||
|
socket.join(newZoneId.toString());
|
||||||
|
|
||||||
|
// Send teleport information to the client
|
||||||
socket.emit('zone:teleport', {
|
socket.emit('zone:teleport', {
|
||||||
zone,
|
zone,
|
||||||
characters: ZoneManager.getCharactersInZone(zone.id)
|
characters: ZoneManager.getCharactersInZone(zone.id)
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user