208 lines
6.0 KiB
JavaScript
Raw Normal View History

2022-08-13 12:40:42 +02:00
import {EventProcessor} from "./EventProcessor.js";
2022-10-06 20:35:28 +02:00
import {Player} from "./Player.js";
2022-08-13 12:40:42 +02:00
export class Game {
#round = 1
2022-10-06 20:35:28 +02:00
#paused = false
2022-08-13 12:40:42 +02:00
#started = false
#options = false
#readyCallback
#endCallback
#hud
2022-10-05 16:09:55 +02:00
#stats
2022-08-13 12:40:42 +02:00
#world
eventProcessor
2022-10-06 20:35:28 +02:00
score = null
alivePlayers = [0, 0]
2022-08-13 12:40:42 +02:00
players = []
2022-10-06 20:35:28 +02:00
playerMe = null
2022-08-13 12:40:42 +02:00
2022-10-05 16:09:55 +02:00
constructor(world, hud, stats) {
2022-08-13 12:40:42 +02:00
this.#world = world
this.#hud = hud
2022-10-05 16:09:55 +02:00
this.#stats = stats
2022-08-13 12:40:42 +02:00
this.eventProcessor = new EventProcessor(this)
}
2022-10-06 20:35:28 +02:00
pause(msg, score, timeMs) {
console.log("Pause: " + msg + " for " + timeMs + "ms")
2022-09-24 19:28:57 +02:00
const game = this
this.players.forEach(function (player) {
2022-10-06 20:35:28 +02:00
if (player.getId() !== game.playerMe.getId()) {
player.get3DObject().visible = true // respawn (show) all beside me
2022-09-24 19:28:57 +02:00
}
})
2022-09-23 18:33:03 +02:00
this.#started = true
2022-08-13 12:40:42 +02:00
this.#paused = true
2022-10-06 20:35:28 +02:00
this.score = score
2022-08-13 12:40:42 +02:00
this.#hud.pause(msg, timeMs)
2022-10-07 15:44:35 +02:00
this.#hud.requestFullScoreBoardUpdate(this.score)
2022-08-13 12:40:42 +02:00
}
unpause() {
this.#paused = false
this.#hud.clearTopMessage()
console.log("Game unpause")
}
end(msg) {
console.log('Game ended')
if (this.#endCallback) {
this.#endCallback(msg)
}
}
roundStart(aliveAttackers, aliveDefenders) {
console.log("Starting round " + this.#round)
2022-10-06 20:35:28 +02:00
this.alivePlayers[0] = aliveDefenders
this.alivePlayers[1] = aliveAttackers
2022-08-13 12:40:42 +02:00
this.#hud.clearAlerts()
this.#hud.roundStart(this.#options.setting.round_time_ms)
}
2022-10-06 20:35:28 +02:00
roundEnd(attackersWins, newRoundNumber, score) {
2022-08-13 12:40:42 +02:00
let winner = attackersWins ? 'Attackers' : 'Defenders'
console.log("Round " + this.#round + " ended. Round wins: " + winner)
2022-10-06 20:35:28 +02:00
this.score = score;
2022-10-05 20:08:33 +02:00
this.#round = newRoundNumber
2022-08-13 12:40:42 +02:00
this.#hud.displayTopMessage(winner + ' wins')
2022-10-07 15:44:35 +02:00
this.#hud.requestFullScoreBoardUpdate(this.score)
2022-08-13 12:40:42 +02:00
}
isPlaying() {
return this.#started
}
onReady(callback) {
this.#readyCallback = callback
}
onEnd(callback) {
this.#endCallback = callback
}
setOptions(options) {
this.#options = options
this.#hud.startWarmup(options.warmupSec * 1000)
const playerId = options.playerId
if (this.players[playerId]) {
throw new Error("My Player is already set!")
}
2022-10-06 20:35:28 +02:00
this.playerMe = new Player(options.player, this.#world.createPlayerMe())
this.players[playerId] = this.playerMe;
2022-08-13 12:40:42 +02:00
if (this.#readyCallback) {
this.#readyCallback(this.#options)
}
}
playerKilled(playerIdDead, playerIdCulprit, wasHeadshot, killItemId) {
2022-10-07 15:44:35 +02:00
const culpritPlayer = this.players[playerIdCulprit];
2022-10-06 20:35:28 +02:00
const deadPlayer = this.players[playerIdDead];
2022-10-07 15:44:35 +02:00
2022-10-06 20:35:28 +02:00
deadPlayer.get3DObject().visible = false
this.alivePlayers[deadPlayer.getTeamIndex()]--
2022-08-13 12:40:42 +02:00
this.#hud.showKill(
2022-10-07 15:44:35 +02:00
culpritPlayer.data,
2022-10-06 20:35:28 +02:00
deadPlayer.data,
2022-08-13 12:40:42 +02:00
wasHeadshot,
2022-10-06 20:35:28 +02:00
this.playerMe.data,
2022-08-13 12:40:42 +02:00
killItemId
)
}
2022-10-06 20:35:28 +02:00
createPlayer(data) {
2022-10-07 15:44:35 +02:00
const player = new Player(data, this.#world.spawnPlayer(data.color, this.playerMe.isAttacker !== data.isAttacker))
2022-10-06 20:35:28 +02:00
if (this.players[data.id]) {
throw new Error('Player already exist with id ' + data.id)
2022-08-13 12:40:42 +02:00
}
2022-10-06 20:35:28 +02:00
this.players[data.id] = player
return player
2022-08-13 12:40:42 +02:00
}
2022-10-05 20:08:33 +02:00
attack() {
// TODO attack feedback (audiovisual)
}
2022-08-13 12:40:42 +02:00
equip(slotId) {
2022-10-06 20:35:28 +02:00
if (!this.playerMe.data.slots[slotId]) {
2022-08-13 12:40:42 +02:00
return false
}
2022-10-06 20:35:28 +02:00
this.playerMe.equip(slotId)
this.#hud.equip(slotId, this.playerMe.data.slots)
2022-08-13 12:40:42 +02:00
return true
}
tick(state) {
const game = this
2022-10-07 15:44:35 +02:00
state.events.forEach(function (event) {
game.eventProcessor.process(event)
})
2022-08-13 12:40:42 +02:00
if (this.#options === false) {
return
}
state.players.forEach(function (playerState) {
let player = game.players[playerState.id]
if (player === undefined) {
2022-10-06 20:35:28 +02:00
player = game.createPlayer(playerState)
2022-08-13 12:40:42 +02:00
}
2022-10-07 15:44:35 +02:00
player.get3DObject().getObjectByName('head').position.y = playerState.heightSight
player.get3DObject().position.set(playerState.position.x, playerState.position.y, -1 * (playerState.position.z))
game.updatePlayerData(player, playerState)
2022-08-13 12:40:42 +02:00
})
this.render()
}
2022-10-07 15:44:35 +02:00
updatePlayerData(player, serverState) {
if (this.playerMe.getId() === serverState.id) { // if me
if (this.playerMe.getEquippedSlotId() !== serverState.item.slot) {
this.equip(serverState.item.slot)
}
}
if (player.data.isAttacker === this.playerMe.data.isAttacker) { // if player on my team
if (player.data.money !== serverState.money) {
this.#hud.updateMyTeamPlayerMoney(player.data, serverState.money)
}
player.updateData(serverState)
} else {
player.data.item = serverState.item
player.data.isAttacker = serverState.isAttacker
this.updateOtherPlayersModels(player.get3DObject(), serverState)
}
}
2022-10-06 20:35:28 +02:00
meIsAlive() {
return this.playerMe.isAlive()
2022-08-13 12:40:42 +02:00
}
2022-10-06 20:35:28 +02:00
updateOtherPlayersModels(playerObject, data) {
2022-08-13 12:40:42 +02:00
playerObject.rotation.y = serverRotationToThreeRadian(data.look.horizontal)
2022-10-07 15:44:35 +02:00
const body = playerObject.getObjectByName('body')
if (body.position.y !== data.heightBody) { // update body height position if changed
// TODO probably keyframe time based animation from userData like body.position = body.userData.animation[data.playerAnimationId]
body.position.y = data.heightBody
}
2022-08-13 12:40:42 +02:00
}
render() {
2022-10-05 16:09:55 +02:00
this.#stats.begin()
2022-10-06 20:35:28 +02:00
if (this.#started) {
this.#hud.updateHud(this.playerMe.data) // TODO check performance and if heavy debounce to every x tick
}
2022-08-13 12:40:42 +02:00
this.#world.render()
2022-10-05 16:09:55 +02:00
this.#stats.end()
2022-08-13 12:40:42 +02:00
}
}