Dungeon mode
This commit is contained in:
parent
d729c8dcbb
commit
6dc6bc5db8
|
@ -0,0 +1,25 @@
|
|||
import { game } from "../game"
|
||||
import { levelState } from "./levelState"
|
||||
|
||||
export class dungeonData{
|
||||
entranceId : string
|
||||
rooms : levelState[] = []
|
||||
playerCount : number = 0
|
||||
|
||||
constructor(id:string) {
|
||||
this.entranceId = id
|
||||
}
|
||||
|
||||
getRoom(roomId : string, create : boolean){
|
||||
let room = this.rooms.find(r=>r.id == roomId)
|
||||
|
||||
if(room == null && create){
|
||||
room = new levelState(roomId, -1)
|
||||
room.isDungeon = true
|
||||
this.rooms.push(room)
|
||||
game.lobbyState.rooms.push(room)
|
||||
}
|
||||
|
||||
return room
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
export class enemyDamageInfo{
|
||||
sourceId : number
|
||||
targetId : number
|
||||
sourceId : number //player/enemy
|
||||
targetId : number //player/enemy
|
||||
targetName : string //physics objects
|
||||
relativePosition : number[]
|
||||
damage : number
|
||||
knockback : number
|
||||
|
|
|
@ -1,11 +1,78 @@
|
|||
import { enemyData } from "./enemyData";
|
||||
import { physicsObject } from "./physicsObject";
|
||||
import { playerData } from "./playerData";
|
||||
import { userData } from "./userData";
|
||||
|
||||
export class levelState{
|
||||
id : string
|
||||
seed : number = -1
|
||||
hostId : number = -1
|
||||
enemies : enemyData[] = [];
|
||||
objects : physicsObject[] = [];
|
||||
completed : boolean = false
|
||||
isDungeon : boolean = false
|
||||
enemies : enemyData[] = []
|
||||
objects : physicsObject[] = []
|
||||
players : playerData[] = []
|
||||
|
||||
getRandomInt(max) {
|
||||
return Math.floor(Math.random() * max);
|
||||
}
|
||||
|
||||
constructor(id, hostId){
|
||||
this.id = id
|
||||
this.hostId = hostId
|
||||
this.seed = this.getRandomInt(1000000)
|
||||
this.completed = false
|
||||
}
|
||||
|
||||
copyLight() {
|
||||
let level : any = {}
|
||||
level.id = this.id
|
||||
level.seed = this.seed
|
||||
level.hostId = this.hostId
|
||||
level.completed = this.completed
|
||||
level.enemies = this.enemies
|
||||
level.objects = this.objects
|
||||
level.players = this.players.map(pl=>pl.copyLight())
|
||||
return level
|
||||
}
|
||||
|
||||
isHostValid(){
|
||||
if(this.hostId == -1) return false
|
||||
if(this.players.length == 0) return false
|
||||
|
||||
let playerIdx = this.players.findIndex(p=>p.id==this.hostId)
|
||||
if(playerIdx == -1) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
addPlayer(player : playerData) : boolean{
|
||||
let playerIdx = this.players.findIndex(p=>p.id==player.id)
|
||||
if(playerIdx != -1) return false
|
||||
|
||||
this.players.push(player)
|
||||
|
||||
if(this.hostId == -1){
|
||||
this.hostId = this.players[0].id
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
removePlayer(id) : boolean{
|
||||
let playerIdx = this.players.findIndex(p=>p.id==id)
|
||||
if(playerIdx == -1) return false
|
||||
|
||||
this.players.splice(playerIdx,1)
|
||||
|
||||
if(this.hostId == id){
|
||||
if(this.players.length > 0){
|
||||
this.hostId = this.players[0].id
|
||||
}
|
||||
else{
|
||||
this.hostId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import { playerData } from "../Classes/playerData";
|
||||
import { dungeonData } from "./dungeonData";
|
||||
import { levelState } from "./levelState";
|
||||
import { userData } from "./userData";
|
||||
|
||||
|
@ -6,6 +7,7 @@ export class lobbyState{
|
|||
users : userData[] = [];
|
||||
players : playerData[] = [];
|
||||
rooms : levelState[] = []
|
||||
dungeons : dungeonData[] = []
|
||||
|
||||
copyLight(){
|
||||
let lobby = Object.assign({}, this);
|
||||
|
@ -15,6 +17,7 @@ export class lobbyState{
|
|||
lobby.players.push(this.players[i].copyLight());
|
||||
}
|
||||
lobby.rooms = this.rooms
|
||||
lobby.dungeons = this.dungeons
|
||||
return lobby
|
||||
}
|
||||
|
||||
|
@ -39,11 +42,112 @@ export class lobbyState{
|
|||
|
||||
idx = this.players.findIndex(u=>u.id == id)
|
||||
if(idx != -1){
|
||||
let player = this.players[idx]
|
||||
this.players.splice(idx, 1)
|
||||
this.roomExit(player.room, player)
|
||||
}
|
||||
}
|
||||
|
||||
findPlayer(id: number){
|
||||
return this.players.find(p=>p.id == id)
|
||||
}
|
||||
|
||||
getDungeonRoot(name){
|
||||
let split = name.split("_")
|
||||
return split[0] + "_" + split[1] + "_0_0"
|
||||
}
|
||||
|
||||
getDungeon(id : string, create : boolean){
|
||||
let dungeon = this.dungeons.find(r=>r.entranceId == id)
|
||||
if(dungeon == null && create){
|
||||
dungeon = new dungeonData(id)
|
||||
this.dungeons.push(dungeon)
|
||||
}
|
||||
return dungeon
|
||||
}
|
||||
|
||||
getRoom(id: string, create : boolean){
|
||||
let room = this.rooms.find(r=>r.id == id)
|
||||
if(room == null && create){
|
||||
room = new levelState(id, -1)
|
||||
this.rooms.push(room)
|
||||
}
|
||||
return room
|
||||
}
|
||||
|
||||
createRoom(id : string, host : number){
|
||||
let room = new levelState(id, host)
|
||||
this.rooms.push(room)
|
||||
return room
|
||||
}
|
||||
|
||||
roomEnter(targetRoom : levelState, player: playerData){
|
||||
if(!targetRoom.isDungeon){
|
||||
let room = this.getRoom(targetRoom.id, true)
|
||||
|
||||
room.addPlayer(player)
|
||||
|
||||
return room
|
||||
}
|
||||
else{
|
||||
let dungeon = this.getDungeon(this.getDungeonRoot(targetRoom.id), true);
|
||||
|
||||
let room = dungeon.getRoom(targetRoom.id, true)
|
||||
|
||||
if(room.addPlayer(player)){
|
||||
dungeon.playerCount += 1;
|
||||
}
|
||||
|
||||
return room
|
||||
}
|
||||
}
|
||||
|
||||
roomComplete(roomId: string){
|
||||
let room = this.getRoom(roomId, false)
|
||||
if(room != null){
|
||||
room.completed = true
|
||||
return room
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
roomExit(roomId : string, player: playerData){
|
||||
let room = this.getRoom(roomId, false)
|
||||
if(room != null){
|
||||
|
||||
if(room.removePlayer(player.id)){
|
||||
if(room.isDungeon){
|
||||
let dungeon = this.getDungeon(this.getDungeonRoot(roomId), false)
|
||||
dungeon.playerCount -= 1;
|
||||
this.tryRemoveDungeon(room.id)
|
||||
}
|
||||
else if(room.hostId == -1){
|
||||
let roomIdx = this.rooms.indexOf(room)
|
||||
this.rooms.splice(roomIdx, 1)
|
||||
}
|
||||
}
|
||||
|
||||
return room
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
tryRemoveDungeon(roomId : string){
|
||||
let dungeonIdx = this.dungeons.findIndex(r=>r.entranceId == this.getDungeonRoot(roomId))
|
||||
|
||||
if(dungeonIdx == -1) return false
|
||||
|
||||
let dungeon = this.dungeons[dungeonIdx]
|
||||
if(dungeon.playerCount == 0){
|
||||
this.dungeons.splice(dungeonIdx, 1)
|
||||
dungeon.rooms.forEach(room=>{
|
||||
let roomIdx = this.rooms.findIndex(r=>r.id == room.id)
|
||||
this.rooms.splice(roomIdx, 1)
|
||||
})
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
|
@ -1,8 +1,16 @@
|
|||
export class physicsObject{
|
||||
name : string
|
||||
templateId : number
|
||||
//array of floats [3]
|
||||
kinematic : boolean
|
||||
position : number[] = [0,0,0]
|
||||
rotation : number[] = [0,0,0]
|
||||
velocity : number[] = [0,0,0]
|
||||
angularVelocity : number[] = [0,0,0]
|
||||
|
||||
static copyLight(o: physicsObject) {
|
||||
let pObject = Object.assign({}, o)
|
||||
|
||||
return pObject
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
import { game } from "../game";
|
||||
import { enemyDamageInfo } from "./enemyDamageInfo";
|
||||
import { physicsObject } from "./physicsObject";
|
||||
import { playerInventory } from "./playerInventory";
|
||||
|
@ -15,8 +14,8 @@ export class playerData{
|
|||
copyLight(){
|
||||
let player : any = {}
|
||||
player.id = this.id
|
||||
player.room = this.room
|
||||
player.rigidbody = this.rigidbody
|
||||
//player.room = this.room
|
||||
player.rigidbody = physicsObject.copyLight(this.rigidbody)
|
||||
player.damageInfo = this.damageInfo
|
||||
return player
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
import { levelState } from "./levelState"
|
||||
|
||||
export class roomChangeData{
|
||||
previousRoom : string
|
||||
targetRoom : levelState
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
import { levelState } from "./levelState"
|
||||
import { playerData } from "./playerData"
|
||||
|
||||
export class roomChangeResponse{
|
||||
player : playerData
|
||||
newRoom : levelState
|
||||
previousRoom : levelState
|
||||
}
|
|
@ -1,10 +1,8 @@
|
|||
import { game } from "../game";
|
||||
|
||||
export function projectile(socket, data){
|
||||
if(!socket.hasOwnProperty("user")) return;
|
||||
|
||||
let buff = Buffer.from(data, 'base64');
|
||||
//let data1 = JSON.parse();
|
||||
|
||||
game.socketIO.emit('level/projectile', buff.toString('utf-8'))
|
||||
socket.to(socket.player.room).emit('level/projectile', buff.toString('utf-8'))
|
||||
}
|
|
@ -10,9 +10,7 @@ export function update(socket, data){
|
|||
|
||||
let room = game.lobbyState.rooms.find(l=>l.id == data1.id)
|
||||
if (room == null){
|
||||
room = new levelState()
|
||||
room.id = data1.id
|
||||
game.lobbyState.rooms.push(room)
|
||||
return
|
||||
}
|
||||
|
||||
let player = socket.player
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
import { game } from "../game";
|
||||
|
||||
export function clearRoom(socket, data){
|
||||
if(!socket.hasOwnProperty("player")) return;
|
||||
|
||||
let buff = Buffer.from(data, 'base64');
|
||||
let data1 : string = JSON.parse(buff.toString('utf-8'));
|
||||
|
||||
let room = game.lobbyState.roomComplete(data1)
|
||||
game.socketIO.emit("lobby/cleared", JSON.stringify(room))
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import { roomChangeData as roomChangeRequest } from "../Classes/roomChangeRequest";
|
||||
import { roomChangeResponse } from "../Classes/roomChangeResponse";
|
||||
import { game } from "../game";
|
||||
|
||||
export function enter(socket, data){
|
||||
if(!socket.hasOwnProperty("player")) return;
|
||||
|
||||
let buff = Buffer.from(data, 'base64');
|
||||
let data1 : roomChangeRequest = JSON.parse(buff.toString('utf-8'));
|
||||
|
||||
socket.join(data1.targetRoom.id)
|
||||
let newRoom = game.lobbyState.roomEnter(data1.targetRoom, socket.player)
|
||||
socket.player.room = newRoom.id
|
||||
|
||||
socket.leave(data1.previousRoom)
|
||||
let oldRoom = game.lobbyState.roomExit(data1.previousRoom, socket.player)
|
||||
|
||||
let data2 = new roomChangeResponse()
|
||||
data2.player = socket.player.copyLight()
|
||||
data2.newRoom = newRoom.copyLight()
|
||||
data2.previousRoom = oldRoom.copyLight()
|
||||
|
||||
game.socketIO.emit("lobby/entered", JSON.stringify(data2))
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { levelState } from "../Classes/levelState";
|
||||
import { lobbyMessage } from "../Classes/lobbyMessage";
|
||||
import { lobbyState } from "../Classes/lobbyState";
|
||||
import { playerData } from "../Classes/playerData";
|
||||
import { userData } from "../Classes/userData";
|
||||
import { game } from "../game";
|
||||
|
@ -13,9 +13,29 @@ export function playerJoin(socket, data){
|
|||
socket.player.characterId = data1.characterId
|
||||
game.lobbyState.addUser(socket.user, socket.player)
|
||||
|
||||
let newLobbyState : lobbyState = Object.assign({}, game.lobbyState);
|
||||
newLobbyState.users = newLobbyState.users.map(u=> userData.makeSafe(u))
|
||||
let newUser = {users:[userData.makeSafe(socket.user)], players:[socket.player], rooms:[]};
|
||||
let existingUsers = {users:game.lobbyState.users.map(u=> userData.makeSafe(u)), players:[], rooms:[]}
|
||||
|
||||
game.lobbyState.players.forEach(player=>{
|
||||
if(player.id == socket.player.id){
|
||||
existingUsers.players.push(player)
|
||||
}
|
||||
else{
|
||||
let newPlayer = Object.assign({}, player);
|
||||
delete(newPlayer.inventory)
|
||||
existingUsers.players.push(newPlayer)
|
||||
}
|
||||
})
|
||||
|
||||
let room = game.lobbyState.roomEnter(new levelState("0_0", -1), socket.player)
|
||||
existingUsers.rooms = game.lobbyState.rooms
|
||||
socket.join("0_0")
|
||||
|
||||
//send only player to all existing players
|
||||
socket.broadcast.emit("lobby/playerJoin", JSON.stringify(newUser));
|
||||
|
||||
//send all users to player (including player)
|
||||
socket.emit("lobby/playerJoin", JSON.stringify(existingUsers))
|
||||
|
||||
game.socketIO.emit("lobby/playerJoin", JSON.stringify(newLobbyState))
|
||||
game.addMessage(new lobbyMessage(socket.user.login + " joined"))
|
||||
}
|
|
@ -9,10 +9,10 @@ export function playerUpdate(socket, data){
|
|||
let player : playerData = socket.player
|
||||
if(player == null){
|
||||
console.log("Error! Player not spawned!")
|
||||
return
|
||||
}
|
||||
else{
|
||||
player.room = data1.room
|
||||
player.rigidbody = data1.rigidbody
|
||||
player.damageInfo = player.damageInfo.concat(data1.damageInfo)
|
||||
}
|
||||
|
||||
player.room = data1.room
|
||||
player.rigidbody = data1.rigidbody
|
||||
player.damageInfo = player.damageInfo.concat(data1.damageInfo)
|
||||
}
|
|
@ -1,9 +1,19 @@
|
|||
import { clearRoom } from "./_clearRoom";
|
||||
import { enter } from "./_enter";
|
||||
import { loadoutChanged } from "./_loadoutChanged";
|
||||
import { message } from "./_message";
|
||||
import { playerJoin } from "./_playerJoin";
|
||||
import { playerUpdate } from "./_playerUpdate";
|
||||
|
||||
export function registerLobbyCallbacks(socket){
|
||||
socket.on('lobby/enter', (data) => {
|
||||
enter(socket, data)
|
||||
});
|
||||
|
||||
socket.on('lobby/cleared', (data) => {
|
||||
clearRoom(socket, data)
|
||||
});
|
||||
|
||||
socket.on('lobby/playerJoin', (data) => {
|
||||
playerJoin(socket, data)
|
||||
});
|
||||
|
|
63
index.ts
63
index.ts
|
@ -6,7 +6,8 @@ import { registerItemCallbacks } from "./Items/itemSocket";
|
|||
import { registerLobbyCallbacks } from "./Lobby/lobbySocket";
|
||||
import { registerAccountCallbacks } from "./Account/accountSocket";
|
||||
import { registerLevelCallbacks } from "./Level/levelSocket";
|
||||
import { levelState } from "./Classes/levelState";
|
||||
import { physicsObject } from "./Classes/physicsObject";
|
||||
import { enemyData } from "./Classes/enemyData";
|
||||
|
||||
const express = require("express");
|
||||
const app = express();
|
||||
|
@ -54,50 +55,14 @@ io.on('connection', (socket) => {
|
|||
});
|
||||
|
||||
//Send player updates to everyone
|
||||
setInterval(() => {
|
||||
setInterval(async () => {
|
||||
let userCount = game.lobbyState.players.length
|
||||
if(userCount > 0){
|
||||
game.lobbyState.players.forEach(p=>{
|
||||
let room = game.lobbyState.rooms.find(r=>r.id == p.room)
|
||||
if (room == null){
|
||||
room = new levelState()
|
||||
room.id = p.room
|
||||
game.lobbyState.rooms.push(room)
|
||||
console.log("Added room " + room.id)
|
||||
}
|
||||
})
|
||||
let removeRooms = []
|
||||
for (let i = 0; i < game.lobbyState.rooms.length; i++){
|
||||
let room = game.lobbyState.rooms[i]
|
||||
game.lobbyState.rooms.forEach(room=>{
|
||||
let roomData = room.copyLight()
|
||||
|
||||
//assign host to a room if there isn't one
|
||||
if(room.hostId == -1){
|
||||
let hostPlayer = game.lobbyState.players.find(p=>p.room == room.id)
|
||||
if(hostPlayer != null){
|
||||
room.hostId = hostPlayer.id
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//verify if host is still in the room
|
||||
let hostPlayer = game.lobbyState.players.find(p=>p.id == room.hostId)
|
||||
if(hostPlayer == null || hostPlayer.room != room.id){
|
||||
//if they aren't, find another
|
||||
hostPlayer = game.lobbyState.players.find(p=>p.room == room.id)
|
||||
if(hostPlayer != null){
|
||||
room.hostId = hostPlayer.id
|
||||
}
|
||||
else{
|
||||
room.hostId = -1
|
||||
removeRooms.push(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
for(let i = removeRooms.length - 1; i >= 0; i--){
|
||||
console.log("no players in room " + game.lobbyState.rooms[removeRooms[i]] + ". removing.")
|
||||
game.lobbyState.rooms.splice(removeRooms[i],1);
|
||||
}
|
||||
io.emit('lobby/update', JSON.stringify(game.lobbyState.copyLight()))
|
||||
io.in(room.id).emit('lobby/update', JSON.stringify(roomData))
|
||||
})
|
||||
game.playersDB.forEach(p=>{
|
||||
p.damageInfo = []
|
||||
})
|
||||
|
@ -105,7 +70,19 @@ setInterval(() => {
|
|||
}, 1000/30)
|
||||
|
||||
setInterval(() => {
|
||||
console.log("Players: " + game.lobbyState.players.length + ", users: " + game.lobbyState.users.length + ", rooms: " + game.lobbyState.rooms.length);
|
||||
let lobbyState = game.lobbyState
|
||||
console.log("Players:")
|
||||
for(let i = 0; i < lobbyState.players.length; i++){
|
||||
console.log(lobbyState.players[i].id + " " + lobbyState.players[i].room)
|
||||
}
|
||||
console.log("Rooms:")
|
||||
for(let i = 0; i < lobbyState.rooms.length; i++){
|
||||
console.log(lobbyState.rooms[i].id + " " + lobbyState.rooms[i].hostId)
|
||||
}
|
||||
console.log("Dungeon:")
|
||||
for(let i = 0; i < lobbyState.dungeons.length; i++){
|
||||
console.log(lobbyState.dungeons[i].entranceId + " " + lobbyState.dungeons[i].playerCount)
|
||||
}
|
||||
}, 60 * 1000)
|
||||
|
||||
process.on('SIGINT', function () {
|
||||
|
|
Loading…
Reference in New Issue