diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7a73a41 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/Account/accountSocket.ts b/Account/accountSocket.ts index 4e6eb4c..5bef066 100644 --- a/Account/accountSocket.ts +++ b/Account/accountSocket.ts @@ -5,7 +5,7 @@ import { users } from "./users"; import { players } from "../Player/players"; export function registerAccountCallbacks(socket){ - function emitLogin(user : userData, player:playerData, registered:boolean = false){ + function emitLogin(user : userData | null, player:playerData, registered:boolean = false){ if(user != null){ socket.emit("account/login", JSON.stringify(new loginResponse(true, user, player))); socket.user = user @@ -46,6 +46,9 @@ export function registerAccountCallbacks(socket){ let player = null if(result != null){ player = players.readPlayer(result.id) + if(player == null){ + player = players.createPlayer(result.id) + } } emitLogin(result, player); diff --git a/Classes/itemData.ts b/Classes/itemData.ts index 69e7d3c..0c79ad0 100644 --- a/Classes/itemData.ts +++ b/Classes/itemData.ts @@ -1,9 +1,57 @@ -import { enums } from "./enums" +import { game } from "../game" export class itemData{ - name : string - id : number - rarity: number - itemType : number - stats = {} + name : string + id : number + templateId : number + rarity : number + count : number = 1 + stats : Stat[] = [] + + static fromPersistentData(data : persistentItemData){ + let item = new itemData() + + item.name = data.name; + item.id = ++game.itemCount; + item.templateId = data.id; + item.rarity = Math.floor(Math.random()*data.rarityMax); + item.count = 1; + + return item + } + + static copy(data : itemData){ + let item = new itemData() + + item.name = data.name; + item.id = data.id; + item.templateId = data.templateId; + item.rarity = data.rarity + item.count = data.count + data.stats.forEach(stat=>item.stats.push(stat)) + + return item + } } + +export class persistentItemData{ + name: string + id: number + itemType: number + description: string + rarityMin: number + rarityMax: number + maxCount: number + tags: number[] = [] + stats: Stat[] = [] + + constructor(init?: Partial) { + Object.assign(this, init); + } +} + +export interface Stat { + Key: number + Value: number +} + \ No newline at end of file diff --git a/Classes/itemGenerated.ts b/Classes/itemGenerated.ts index dec0bb8..fc2b877 100644 --- a/Classes/itemGenerated.ts +++ b/Classes/itemGenerated.ts @@ -2,5 +2,5 @@ import { itemData } from "./itemData" export class itemGenerated{ instanceId: number - item: itemData + item: itemData | null } \ No newline at end of file diff --git a/Classes/lobbyState.ts b/Classes/lobbyState.ts index b06824f..d1ba91b 100644 --- a/Classes/lobbyState.ts +++ b/Classes/lobbyState.ts @@ -13,7 +13,7 @@ export class lobbyState{ lobby.players = [] lobby.users = [] for (let i = 0; i < this.players.length; i++) { - lobby.players.push(playerData.copyLight(this.players[i])); + lobby.players.push(this.players[i].copyLight()); } return lobby } diff --git a/Classes/playerData.ts b/Classes/playerData.ts index fda06a2..2e1889b 100644 --- a/Classes/playerData.ts +++ b/Classes/playerData.ts @@ -3,14 +3,42 @@ import { playerInventory } from "./playerInventory"; export class playerData{ id : number + level : number = 1 characterId : number inventory : playerInventory = new playerInventory() rigidbody : physicsObject = new physicsObject() - static copyLight(data : playerData){ + copyLight(){ let player : any = {} - player.id = data.id - player.rigidbody = data.rigidbody + player.id = this.id + player.rigidbody = this.rigidbody return player } + + getItemById(id : number){ + let item = this.inventory.items.find(i=>i.id == id) + return item + } + + validateEquipment(){ + if(this.inventory.weapon != -1){ + if(this.getItemById(this.inventory.weapon) == null){ + this.inventory.weapon == -1; + } + } + if(this.inventory.equipment[0] != -1){ + if(this.getItemById(this.inventory.equipment[0]) == null){ + this.inventory.equipment[0] == -1; + } + } + if(this.inventory.equipment[1] != -1){ + if(this.getItemById(this.inventory.equipment[1]) == null){ + this.inventory.equipment[1] == -1; + } + } + } + + constructor(init?: Partial) { + Object.assign(this, init); + } } \ No newline at end of file diff --git a/Classes/playerInventory.ts b/Classes/playerInventory.ts index 81300da..839a909 100644 --- a/Classes/playerInventory.ts +++ b/Classes/playerInventory.ts @@ -4,16 +4,4 @@ export class playerInventory{ weapon : number = -1 equipment : number[] = [-1,-1] items : itemData[] = [] - - static validate(inv : playerInventory){ - if(inv.equipment[0] == inv.weapon){ - inv.equipment[0] = -1 - } - if(inv.equipment[1] == inv.weapon){ - inv.equipment[1] = -1 - } - if(inv.equipment[1] == inv.equipment[0]){ - inv.equipment[1] = -1 - } - } } \ No newline at end of file diff --git a/Items/itemGeneration.ts b/Items/itemGeneration.ts index e619057..80ab3a6 100644 --- a/Items/itemGeneration.ts +++ b/Items/itemGeneration.ts @@ -1,38 +1,20 @@ -import { enums } from "../Classes/enums"; -import { itemData } from "../Classes/itemData"; +import { itemData, persistentItemData } from "../Classes/itemData"; import {game} from "../game"; -let consumableNames = ["soda", "bread"] -let currencyNames = ["stick", "rock", "leaf", "coin"] -let equipmentNames = ["umbrella", "sock", "bag"] -let miscNames = ["book", "envelope"] +function getRandom(arr){ + return arr[Math.floor(Math.random()*arr.length)] +} -export function generateItem(itemType : number){ - let item = new itemData() - item.id = ++game.itemCount; - item.itemType = itemType - item.rarity = Math.floor(Math.random()*100) - switch(itemType){ - case enums.itemType.undefined:{ - item.name = miscNames[Math.floor(Math.random()*miscNames.length)]; +export function generateItemByType(itemType : number){ + let items = game.itemsDB.filter(i=>i.itemType == itemType) - break - } - case enums.itemType.consumable:{ - item.name = consumableNames[Math.floor(Math.random()*consumableNames.length)]; - - break - } - case enums.itemType.currency:{ - item.name = currencyNames[Math.floor(Math.random()*currencyNames.length)]; - - break - } - case enums.itemType.equipment:{ - item.name = equipmentNames[Math.floor(Math.random()*equipmentNames.length)]; - - break - } + if(items.length == 0){ + console.log("Error, can't generate item type " + itemType) + return null + } + else{ + let itemTemplate : persistentItemData = getRandom(items) + let item = itemData.fromPersistentData(itemTemplate) + return item } - return item } \ No newline at end of file diff --git a/Items/itemSocket.ts b/Items/itemSocket.ts index 51b1c44..b2ff033 100644 --- a/Items/itemSocket.ts +++ b/Items/itemSocket.ts @@ -1,9 +1,8 @@ import { itemData } from "../Classes/itemData"; import { itemGenerated } from "../Classes/itemGenerated"; -import { generateItem } from "./itemGeneration"; +import { generateItemByType } from "./itemGeneration"; import { itemRequest } from "../Classes/itemRequest"; import { lobbyMessage } from "../Classes/lobbyMessage"; -import { userData } from "../Classes/userData"; import { game } from "../game"; import { playerData } from "../Classes/playerData"; @@ -16,21 +15,60 @@ export function registerItemCallbacks(socket){ let player : playerData = socket.player if(player != null){ - let message = socket.user.login + " picked up " - if(data1.rarity >= 95){ - message += "" + data1.name + " (epic)" + + let inventory = player.inventory + let template = game.getItemTemplate(data1.templateId) + let items = inventory.items.filter(i=>i.templateId == data1.templateId) + let totalAdded = 0 + + if(data1.count > template.maxCount) + { + console.log("ERROR ERROR ITEM ERROR") + return; } - else if(data1.rarity >= 75){ - message += "" + data1.name + " (rare)" + + items.forEach(item=>{ + var maxAmount = Math.min(template.maxCount - item.count, data1.count - totalAdded); + + if (maxAmount > 0) + { + item.count += maxAmount; + totalAdded += maxAmount; + } + }) + + if(totalAdded < data1.count) + { + let maxAmount = data1.count - totalAdded + let itemCopy = itemData.copy(data1); + itemCopy.count = maxAmount; + totalAdded += maxAmount; + inventory.items.push(itemCopy); } - else if(data1.rarity >= 60){ - message += "" + data1.name + " (uncommon)" + + if (totalAdded == data1.count) + { + if(data1.rarity >= 75){ + let message = socket.user.login + " picked up " + if(data1.rarity >= 95){ + message += "" + data1.name + " (epic)" + } + else if(data1.rarity >= 75){ + message += "" + data1.name + " (rare)" + } + else if(data1.rarity >= 60){ + message += "" + data1.name + " (uncommon)" + } + else + message += data1.name; + + game.addMessage(new lobbyMessage(message)) + } } else - message += data1.name; - - player.inventory.items.push(data1) - game.addMessage(new lobbyMessage(message)) + { + console.log("ERROR ERROR ITEM ERROR") + } } }); @@ -40,7 +78,7 @@ export function registerItemCallbacks(socket){ let buff = Buffer.from(data, 'base64'); let data1 = Number(buff.toString('utf-8')); - let player : playerData = socket.user.playerData + let player : playerData = socket.player let item = player.inventory.items.findIndex(i=>i.id == data1); if(item == -1){ console.log("Error! Item " + item + " not found!") @@ -56,7 +94,7 @@ export function registerItemCallbacks(socket){ let response = new itemGenerated() response.instanceId = data1.instanceId - response.item = generateItem(data1.itemType) + response.item = generateItemByType(data1.itemType) socket.emit("item/generated", JSON.stringify(response)) }); diff --git a/Items/items.ts b/Items/items.ts new file mode 100644 index 0000000..c7db48f --- /dev/null +++ b/Items/items.ts @@ -0,0 +1,20 @@ +import { persistentItemData } from "../Classes/itemData"; +import { game } from "../game"; + +const fs = require('fs'); + +export function loadItems(){ + fs.mkdirSync(`Database/Items/`, { recursive: true }) + fs.readdir(`Database/Items/`, (err, files) => { + files.forEach(file => { + fs.readFile(`Database/Items/${file}`, (err, data) => { + if (err) throw err; + let data1 = JSON.parse(data); + data1.forEach(item => { + let item1 = new persistentItemData(item) + game.itemsDB.push(item1) + }); + }); + }); + }); +} \ No newline at end of file diff --git a/Lobby/lobbySocket.ts b/Lobby/lobbySocket.ts index a2c7678..6dd66fc 100644 --- a/Lobby/lobbySocket.ts +++ b/Lobby/lobbySocket.ts @@ -46,9 +46,10 @@ export function registerLobbyCallbacks(socket){ let buff = Buffer.from(data, 'base64'); let data1 : playerData = JSON.parse(buff.toString('utf-8')); - let player = game.lobbyState.findPlayer(socket.user.id) - player.inventory = data1.inventory - playerInventory.validate(player.inventory) + let player : playerData = socket.player + player.inventory.weapon = data1.inventory.weapon + player.inventory.equipment = data1.inventory.equipment + player.validateEquipment() game.socketIO.emit("lobby/loadoutChanged", JSON.stringify(player)) }); diff --git a/Player/players.ts b/Player/players.ts index ce91fdd..7ae5803 100644 --- a/Player/players.ts +++ b/Player/players.ts @@ -1,5 +1,4 @@ import { game } from "../game"; -import { userData } from "../Classes/userData"; import { playerData } from "../Classes/playerData"; const fs = require('fs'); @@ -34,13 +33,14 @@ export class players{ files.forEach(file => { fs.readFile(`Database/Players/${file}`, (err, data) => { if (err) throw err; - let player : playerData = JSON.parse(data); + let player : playerData = new playerData(JSON.parse(data)); game.playersDB.push(player); player.inventory.items.forEach(i=>{ if(i.id > game.itemCount){ game.itemCount = i.id } }) + player.validateEquipment() console.log(`Loaded pl ${player.id}`); }); }); diff --git a/game.ts b/game.ts index a9a920e..952d262 100644 --- a/game.ts +++ b/game.ts @@ -2,6 +2,7 @@ import { userData } from "./Classes/userData"; import { lobbyMessage } from "./Classes/lobbyMessage"; import { lobbyState } from "./Classes/lobbyState"; import { playerData } from "./Classes/playerData"; +import { persistentItemData } from "./Classes/itemData"; const fs = require('fs'); export class game{ @@ -10,6 +11,7 @@ export class game{ static itemCount : number = 0 static accountsDB : userData[] = [] static playersDB : playerData[] = [] + static itemsDB : persistentItemData[] = [] /** Key: socket ID*/ static lobbyState : lobbyState = new lobbyState() @@ -25,4 +27,13 @@ export class game{ game.messages.unshift(message) game.socketIO.emit('lobby/messages', JSON.stringify(game.messages)) } + + static getItemTemplate(templateId){ + let item = this.itemsDB.find(i=>i.id == templateId) + if (item == null){ + console.log("Error, item " + templateId + " not found") + return null + } + return item + } } \ No newline at end of file diff --git a/index.ts b/index.ts index b7c1499..fe0001b 100644 --- a/index.ts +++ b/index.ts @@ -1,10 +1,10 @@ -import { registerAccountCallbacks } from "./Account/accountSocket"; -import { users } from "./Account/users"; -import { registerLobbyCallbacks } from "./Lobby/lobbySocket"; -import { playerData } from "./Classes/playerData"; import { game } from "./game"; -import { registerItemCallbacks } from "./Items/itemSocket"; +import { users } from "./Account/users"; +import { loadItems } from "./Items/items"; import { players } from "./Player/players"; +import { registerItemCallbacks } from "./Items/itemSocket"; +import { registerLobbyCallbacks } from "./Lobby/lobbySocket"; +import { registerAccountCallbacks } from "./Account/accountSocket"; const express = require("express"); const app = express(); @@ -24,6 +24,7 @@ const io = require("socket.io")(server, { users.loadUsers(); players.loadPlayers(); +loadItems() io.on('connection', (socket) => { console.log("Got connection!");