diff --git a/public/client.js b/public/client.js
index 6aff89e..861dd8d 100644
--- a/public/client.js
+++ b/public/client.js
@@ -467,36 +467,50 @@ function connectWebSocket() {
if (playerId != null) {
const player = state.entities.find((e) => e.id == playerId)
if (player != null) {
- for (let abilityIndex = 0; abilityIndex < 7; abilityIndex++) {
- const abilityKey = ['a', 'q', 'w', 'e', 'r', 'd', 'f'][abilityIndex]
- if (player.abilities[abilityKey] != null) {
- const abilityId = player.abilities[abilityKey]
- const ability = state.abilities.find((it) => it.id == abilityId)
- const lastCast = player.cooldowns[ability.id] ?? -Infinity
- const cooldownDuration = (ability.cooldown * state.tickRate) ?? 0
- const remainingCooldown = (lastCast + cooldownDuration) - state.currentTick
- let cssPercentage = '100%'
- let text = ''
- if (remainingCooldown > 0) {
- const cooldownPercentage = 1 - (remainingCooldown / cooldownDuration)
- cssPercentage = `${Math.round(100 * cooldownPercentage)}%`
- if (remainingCooldown / state.tickRate <= 5) {
- text = `${(Math.round(10 * remainingCooldown / state.tickRate) / 10).toFixed(1)}`
- }
- else {
- text = `${Math.round(remainingCooldown / state.tickRate)}`
- }
- }
+ const playerAbilities = player.abilities
- if (player.casting?.ability == ability.id) {
- document.getElementById(`ability-${abilityIndex}-cooldown`).style.clipPath = `polygon(50% 0%, 0% 100%, 100% 100%)` // triangle
+ let abilitiesHTML = ''
+
+ let i = 0
+ for (const [abilityKey, _abilityId] of Object.entries(playerAbilities)) {
+ i++
+ const abilityKeyText = abilityKey.toUpperCase()
+ const abilityTemplate = `
`
+ abilitiesHTML += abilityTemplate
+ }
+
+ if (document.getElementById(`abilities`).innerHTML != abilitiesHTML) {
+ document.getElementById(`abilities`).innerHTML = abilitiesHTML
+ }
+
+ let abilityIndex = 0
+ for (const [_abilityKey, abilityId] of Object.entries(playerAbilities)) {
+ abilityIndex++
+ const ability = state.abilities.find((it) => it.id == abilityId)
+ const lastCast = player.cooldowns[ability.id] ?? -Infinity
+ const cooldownDuration = (ability.cooldown * state.tickRate) ?? 0
+ const remainingCooldown = (lastCast + cooldownDuration) - state.currentTick
+ let cssPercentage = '100%'
+ let text = ''
+ if (remainingCooldown > 0) {
+ const cooldownPercentage = 1 - (remainingCooldown / cooldownDuration)
+ cssPercentage = `${Math.round(100 * cooldownPercentage)}%`
+ if (remainingCooldown / state.tickRate <= 5) {
+ text = `${(Math.round(10 * remainingCooldown / state.tickRate) / 10).toFixed(1)}`
}
else {
- document.getElementById(`ability-${abilityIndex}-cooldown`).style.clipPath = `polygon(0 ${cssPercentage}, 100% ${cssPercentage}, 100% 100%, 0 100%)`
+ text = `${Math.round(remainingCooldown / state.tickRate)}`
}
-
- document.getElementById(`ability-${abilityIndex}-cooldown-text`).innerHTML = text
}
+
+ if (player.casting?.ability == ability.id) {
+ document.getElementById(`ability-${abilityIndex}-cooldown`).style.clipPath = `polygon(50% 0%, 0% 100%, 100% 100%)` // triangle
+ }
+ else {
+ document.getElementById(`ability-${abilityIndex}-cooldown`).style.clipPath = `polygon(0 ${cssPercentage}, 100% ${cssPercentage}, 100% 100%, 0 100%)`
+ }
+
+ document.getElementById(`ability-${abilityIndex}-cooldown-text`).innerHTML = text
}
let buffs = ``
@@ -577,24 +591,14 @@ window.addEventListener('load', () => {
websocket.send(JSON.stringify({ action: 'halt', id: playerId }))
}
- if (event.code == 'KeyQ') {
- websocket.send(JSON.stringify({ action: 'cast', slot: 'q', id: playerId, x, y }))
- }
- if (event.code == 'KeyW') {
- websocket.send(JSON.stringify({ action: 'cast', slot: 'w', id: playerId, x, y }))
- }
- if (event.code == 'KeyE') {
- websocket.send(JSON.stringify({ action: 'cast', slot: 'e', id: playerId, x, y }))
- }
- if (event.code == 'KeyR') {
- websocket.send(JSON.stringify({ action: 'cast', slot: 'r', id: playerId, x, y }))
- }
- if (event.code == 'KeyD') {
- websocket.send(JSON.stringify({ action: 'cast', slot: 'd', id: playerId, x, y }))
- }
- if (event.code == 'KeyF') {
- websocket.send(JSON.stringify({ action: 'cast', slot: 'f', id: playerId, x, y }))
- }
+ const alreadyBound = ['A', 'X', 'S', 'H']
+ const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('').forEach((letter) => {
+ if (alreadyBound.includes(letter)) { return }
+
+ if (event.code == `Key${letter}`) {
+ websocket.send(JSON.stringify({ action: 'cast', slot: letter.toLowerCase(), id: playerId, x, y }))
+ }
+ })
}
})
diff --git a/public/index.html b/public/index.html
index 8883ce4..ec296b2 100644
--- a/public/index.html
+++ b/public/index.html
@@ -58,12 +58,12 @@
border-right: none;
}
- .hud {
+ .abilities {
+ display: none;
position: fixed;
gap: 10px;
padding: 15px;
padding-bottom: 10px;
- display: flex;
inset: auto 0 0 0;
width: fit-content;
margin: auto;
@@ -74,6 +74,10 @@
border-bottom: none;
}
+ .abilities:has(.ability) {
+ display: flex;
+ }
+
.ability {
position: relative;
flex: 1 0 0;
@@ -178,42 +182,7 @@
-
-
-
-
-
-
-
-
+
diff --git a/src/ability.js b/src/ability.js
index 4687ce5..ecb00a0 100644
--- a/src/ability.js
+++ b/src/ability.js
@@ -85,7 +85,7 @@ export default class Ability {
const entities = projectile.game?.entities ?? []
const pos = projectile.position
projectile.despawn()
- const nearbyDeadTeammates = entities.filter((it) => it.dead && it.team == team)
+ const nearbyDeadTeammates = entities.filter((it) => it.dead && it.team == team && it.distanceTo(pos) <= ability.radius)
const closestDeadTeammate = nearbyDeadTeammates.reduce((e1, e2) => (e1?.distanceTo(pos) ?? Infinity) < e2.distanceTo(pos) ? e1 : e2, null)
if (closestDeadTeammate != null) {
closestDeadTeammate.revive(closestDeadTeammate.maxHealth / 4)
diff --git a/src/entity.js b/src/entity.js
index 6a61030..a6dc525 100644
--- a/src/entity.js
+++ b/src/entity.js
@@ -300,8 +300,8 @@ export default class Entity {
const entities = this.game?.entities
if (entities == null) { return }
const targetsInRange = targetAllies
- ? entities.filter((it) => this.team == it.team && it.distanceTo(cursor) <= range + this.radius + it.radius)
- : entities.filter((it) => this.team != it.team && it.distanceTo(cursor) <= range + this.radius + it.radius)
+ ? entities.filter((it) => !it.dead && this.team == it.team && it.distanceTo(cursor) <= range + this.radius + it.radius)
+ : entities.filter((it) => !it.dead && this.team != it.team && it.distanceTo(cursor) <= range + this.radius + it.radius)
if (targetsInRange.length < 1) { return }
diff --git a/src/game.js b/src/game.js
index 393decd..b8aa223 100644
--- a/src/game.js
+++ b/src/game.js
@@ -41,7 +41,7 @@ export default class Game {
if (options.action == 'attack') { entity.attackAction(new Vector2(options.x, options.y)) }
if (options.action == 'cast') { entity.castAction(options.slot, new Vector2(options.x, options.y)) }
- if (options.action == 'halt') { entity.haltAction(), delay }
+ if (options.action == 'halt') { entity.haltAction() }
if (options.action == 'stop') { entity.stopAction() }
if (options.action == 'move') { entity.moveAction(new Vector2(options.x, options.y)) }
}