exclude dead entities from auto-attack target selection
This commit is contained in:
+47
-43
@@ -467,36 +467,50 @@ function connectWebSocket() {
|
|||||||
if (playerId != null) {
|
if (playerId != null) {
|
||||||
const player = state.entities.find((e) => e.id == playerId)
|
const player = state.entities.find((e) => e.id == playerId)
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
for (let abilityIndex = 0; abilityIndex < 7; abilityIndex++) {
|
const playerAbilities = player.abilities
|
||||||
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)}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (player.casting?.ability == ability.id) {
|
let abilitiesHTML = ''
|
||||||
document.getElementById(`ability-${abilityIndex}-cooldown`).style.clipPath = `polygon(50% 0%, 0% 100%, 100% 100%)` // triangle
|
|
||||||
|
let i = 0
|
||||||
|
for (const [abilityKey, _abilityId] of Object.entries(playerAbilities)) {
|
||||||
|
i++
|
||||||
|
const abilityKeyText = abilityKey.toUpperCase()
|
||||||
|
const abilityTemplate = `<div id="ability-${i}" class="ability">${abilityKeyText}<div id="ability-${i}-cooldown" class="cooldown"></div><div id="ability-${i}-cooldown-text" class="cooldown-text"></div></div>`
|
||||||
|
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 {
|
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 = ``
|
let buffs = ``
|
||||||
@@ -577,24 +591,14 @@ window.addEventListener('load', () => {
|
|||||||
websocket.send(JSON.stringify({ action: 'halt', id: playerId }))
|
websocket.send(JSON.stringify({ action: 'halt', id: playerId }))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.code == 'KeyQ') {
|
const alreadyBound = ['A', 'X', 'S', 'H']
|
||||||
websocket.send(JSON.stringify({ action: 'cast', slot: 'q', id: playerId, x, y }))
|
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('').forEach((letter) => {
|
||||||
}
|
if (alreadyBound.includes(letter)) { return }
|
||||||
if (event.code == 'KeyW') {
|
|
||||||
websocket.send(JSON.stringify({ action: 'cast', slot: 'w', id: playerId, x, y }))
|
if (event.code == `Key${letter}`) {
|
||||||
}
|
websocket.send(JSON.stringify({ action: 'cast', slot: letter.toLowerCase(), 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 }))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
+7
-38
@@ -58,12 +58,12 @@
|
|||||||
border-right: none;
|
border-right: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hud {
|
.abilities {
|
||||||
|
display: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
display: flex;
|
|
||||||
inset: auto 0 0 0;
|
inset: auto 0 0 0;
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
@@ -74,6 +74,10 @@
|
|||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.abilities:has(.ability) {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
.ability {
|
.ability {
|
||||||
position: relative;
|
position: relative;
|
||||||
flex: 1 0 0;
|
flex: 1 0 0;
|
||||||
@@ -178,42 +182,7 @@
|
|||||||
<div id="cast_indicator_progress" class="cast-indicator-progress"></div>
|
<div id="cast_indicator_progress" class="cast-indicator-progress"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="hud">
|
<div id="abilities" class="abilities">
|
||||||
<div id="ability-0" class="ability">
|
|
||||||
A
|
|
||||||
<div id="ability-0-cooldown" class="cooldown"></div>
|
|
||||||
<div id="ability-0-cooldown-text" class="cooldown-text"></div>
|
|
||||||
</div>
|
|
||||||
<div id="ability-1" class="ability">
|
|
||||||
Q
|
|
||||||
<div id="ability-1-cooldown" class="cooldown"></div>
|
|
||||||
<div id="ability-1-cooldown-text" class="cooldown-text"></div>
|
|
||||||
</div>
|
|
||||||
<div id="ability-2" class="ability">
|
|
||||||
W
|
|
||||||
<div id="ability-2-cooldown" class="cooldown"></div>
|
|
||||||
<div id="ability-2-cooldown-text" class="cooldown-text"></div>
|
|
||||||
</div>
|
|
||||||
<div id="ability-3" class="ability">
|
|
||||||
E
|
|
||||||
<div id="ability-3-cooldown" class="cooldown"></div>
|
|
||||||
<div id="ability-3-cooldown-text" class="cooldown-text"></div>
|
|
||||||
</div>
|
|
||||||
<div id="ability-4" class="ability">
|
|
||||||
R
|
|
||||||
<div id="ability-4-cooldown" class="cooldown"></div>
|
|
||||||
<div id="ability-4-cooldown-text" class="cooldown-text"></div>
|
|
||||||
</div>
|
|
||||||
<div id="ability-5" class="ability">
|
|
||||||
D
|
|
||||||
<div id="ability-5-cooldown" class="cooldown"></div>
|
|
||||||
<div id="ability-5-cooldown-text" class="cooldown-text"></div>
|
|
||||||
</div>
|
|
||||||
<div id="ability-6" class="ability">
|
|
||||||
F
|
|
||||||
<div id="ability-6-cooldown" class="cooldown"></div>
|
|
||||||
<div id="ability-6-cooldown-text" class="cooldown-text"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="buffs" class="buffs"></div>
|
<div id="buffs" class="buffs"></div>
|
||||||
<script type="module" src="client.js"></script>
|
<script type="module" src="client.js"></script>
|
||||||
|
|||||||
+1
-1
@@ -85,7 +85,7 @@ export default class Ability {
|
|||||||
const entities = projectile.game?.entities ?? []
|
const entities = projectile.game?.entities ?? []
|
||||||
const pos = projectile.position
|
const pos = projectile.position
|
||||||
projectile.despawn()
|
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)
|
const closestDeadTeammate = nearbyDeadTeammates.reduce((e1, e2) => (e1?.distanceTo(pos) ?? Infinity) < e2.distanceTo(pos) ? e1 : e2, null)
|
||||||
if (closestDeadTeammate != null) {
|
if (closestDeadTeammate != null) {
|
||||||
closestDeadTeammate.revive(closestDeadTeammate.maxHealth / 4)
|
closestDeadTeammate.revive(closestDeadTeammate.maxHealth / 4)
|
||||||
|
|||||||
+2
-2
@@ -300,8 +300,8 @@ export default class Entity {
|
|||||||
const entities = this.game?.entities
|
const entities = this.game?.entities
|
||||||
if (entities == null) { return }
|
if (entities == null) { return }
|
||||||
const targetsInRange = targetAllies
|
const targetsInRange = targetAllies
|
||||||
? 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) => 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 }
|
if (targetsInRange.length < 1) { return }
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -41,7 +41,7 @@ export default class Game {
|
|||||||
|
|
||||||
if (options.action == 'attack') { entity.attackAction(new Vector2(options.x, options.y)) }
|
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 == '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 == 'stop') { entity.stopAction() }
|
||||||
if (options.action == 'move') { entity.moveAction(new Vector2(options.x, options.y)) }
|
if (options.action == 'move') { entity.moveAction(new Vector2(options.x, options.y)) }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user