display buffs in the client
This commit is contained in:
+21
-2
@@ -247,7 +247,7 @@ function connectWebSocket() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(state)
|
// console.log(state)
|
||||||
|
|
||||||
if (state.width != null && state.height != null && (ground.geometry.attributes.width != state.width || ground.geometry.attributes.height != state.height)) {
|
if (state.width != null && state.height != null && (ground.geometry.attributes.width != state.width || ground.geometry.attributes.height != state.height)) {
|
||||||
ground.geometry = new THREE.PlaneGeometry(state.width / 100, state.height / 100)
|
ground.geometry = new THREE.PlaneGeometry(state.width / 100, state.height / 100)
|
||||||
@@ -294,6 +294,14 @@ function connectWebSocket() {
|
|||||||
teamMarker.layers.set(1)
|
teamMarker.layers.set(1)
|
||||||
entity.add(teamMarker)
|
entity.add(teamMarker)
|
||||||
|
|
||||||
|
const buffMaterial = new THREE.MeshToonMaterial({ color: 0xffff00, transparent: true, opacity: 0.4 })
|
||||||
|
const buffMarker = new THREE.Mesh(new THREE.CylinderGeometry((e.visualRadius + 10) / 100, (e.visualRadius + 10) / 100, 1), buffMaterial)
|
||||||
|
const buffMarkerSize = 400
|
||||||
|
buffMarker.scale.y = e.height / buffMarkerSize
|
||||||
|
buffMarker.layers.set(1)
|
||||||
|
buffMarker.visible = false
|
||||||
|
entity.add(buffMarker)
|
||||||
|
|
||||||
if (e.id == playerId) {
|
if (e.id == playerId) {
|
||||||
const rangeMaterial = teamMaterials['range']
|
const rangeMaterial = teamMaterials['range']
|
||||||
const rangeSize = (state.abilities.find((it) => it.id == e.abilities?.a)?.range ?? 0) + e.radius
|
const rangeSize = (state.abilities.find((it) => it.id == e.abilities?.a)?.range ?? 0) + e.radius
|
||||||
@@ -308,6 +316,8 @@ function connectWebSocket() {
|
|||||||
entities[e.id] = entity
|
entities[e.id] = entity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entity.children.at(2).visible = e.buffs.some((it) => it.id == 'exposed') // TODO: only works for Exposed now
|
||||||
|
|
||||||
entity.userData.flaggedForRemoval = false
|
entity.userData.flaggedForRemoval = false
|
||||||
positionTweens[entity.id] = new Tween(entity.position).to({ x: e.position.x / 100, y: e.position.y / 100, z: e.height / 100 }, tweenDuration).start()
|
positionTweens[entity.id] = new Tween(entity.position).to({ x: e.position.x / 100, y: e.position.y / 100, z: e.height / 100 }, tweenDuration).start()
|
||||||
|
|
||||||
@@ -422,6 +432,15 @@ function connectWebSocket() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let buffs = ``
|
||||||
|
player.buffs.forEach((b) => {
|
||||||
|
buffs += `<div class="buff"><div class="buff-body">${state.buffs.find((it) => it.id == b.id).name}</div></div>`
|
||||||
|
})
|
||||||
|
|
||||||
|
if (document.getElementById('buffs').innerHTML != buffs) {
|
||||||
|
document.getElementById('buffs').innerHTML = buffs
|
||||||
|
}
|
||||||
|
|
||||||
let castIndicatorDisplay = 'none'
|
let castIndicatorDisplay = 'none'
|
||||||
if (player.casting != null) {
|
if (player.casting != null) {
|
||||||
castIndicatorDisplay = 'block'
|
castIndicatorDisplay = 'block'
|
||||||
@@ -441,7 +460,7 @@ function connectWebSocket() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// document.getElementById('state').innerHTML = JSON.stringify(stateUpdates, null, 2)
|
document.getElementById('state').innerHTML = JSON.stringify(stateUpdates, null, 2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -132,6 +132,38 @@
|
|||||||
height: 20px;
|
height: 20px;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.buffs {
|
||||||
|
position: fixed;
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
inset: auto 0 120px calc(50vw - 165px);
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buff {
|
||||||
|
flex: 1 0 0;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
background-color: black;
|
||||||
|
/* border: 1px solid gray; */
|
||||||
|
border-right: 1px solid gray;
|
||||||
|
color: white;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buff:hover {
|
||||||
|
overflow: visible;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buff-body {
|
||||||
|
border: 1px solid gray;
|
||||||
|
padding: 5px;
|
||||||
|
background-color: black;
|
||||||
|
width: fit-content;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -168,6 +200,7 @@
|
|||||||
<div id="ability-3-cooldown-text" class="cooldown-text"></div>
|
<div id="ability-3-cooldown-text" class="cooldown-text"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="buffs" class="buffs"></div>
|
||||||
<script type="module" src="client.js"></script>
|
<script type="module" src="client.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+4
-4
@@ -42,7 +42,7 @@ export default class Ability {
|
|||||||
if (collidingEntity == null) { return }
|
if (collidingEntity == null) { return }
|
||||||
if (collidingEntity.team == (projectile.owner?.team ?? 'unknown')) { return }
|
if (collidingEntity.team == (projectile.owner?.team ?? 'unknown')) { return }
|
||||||
|
|
||||||
collidingEntity.damage(ability.damage)
|
collidingEntity.damage(ability.damage, caster)
|
||||||
projectile.despawn()
|
projectile.despawn()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ export default class Ability {
|
|||||||
if (target == null) { return }
|
if (target == null) { return }
|
||||||
|
|
||||||
const rangedAttackAfter = function rangedAttackAfter() {
|
const rangedAttackAfter = function rangedAttackAfter() {
|
||||||
target.damage(ability.damage)
|
target.damage(ability.damage, caster)
|
||||||
}
|
}
|
||||||
|
|
||||||
const projectile = new Projectile({
|
const projectile = new Projectile({
|
||||||
@@ -108,7 +108,7 @@ export default class Ability {
|
|||||||
const target = caster.game?.entities.find((it) => it.id == targetId)
|
const target = caster.game?.entities.find((it) => it.id == targetId)
|
||||||
if (target == null) { return }
|
if (target == null) { return }
|
||||||
|
|
||||||
target.damage(ability.damage)
|
target.damage(ability.damage, caster)
|
||||||
caster.cooldown(ability.id)
|
caster.cooldown(ability.id)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -185,7 +185,7 @@ export default class Ability {
|
|||||||
if (collidingEntity == null) { return }
|
if (collidingEntity == null) { return }
|
||||||
if (collidingEntity.team == (projectile.owner?.team ?? 'unknown')) { return }
|
if (collidingEntity.team == (projectile.owner?.team ?? 'unknown')) { return }
|
||||||
|
|
||||||
collidingEntity.applyBuff(Buff.exposed.id)
|
collidingEntity.applyBuff(Buff.exposed.id, caster.id)
|
||||||
projectile.despawn()
|
projectile.despawn()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+22
-11
@@ -153,14 +153,17 @@ export default class Entity {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
applyBuff(id) {
|
applyBuff(id, sourceId = null) {
|
||||||
const index = this.buffs.findIndex((it) => it.id == id)
|
const index = this.buffs.findIndex((it) => it.id == id)
|
||||||
|
const source = sourceId ?? this.id
|
||||||
const timestamp = this.game?.currentTick ?? 0
|
const timestamp = this.game?.currentTick ?? 0
|
||||||
|
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
this.buffs[index].timestamp = timestamp
|
this.buffs[index].timestamp = timestamp
|
||||||
|
this.buffs[index].source = source
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.buffs.push({ id, timestamp })
|
this.buffs.push({ id, source, timestamp })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,12 +194,15 @@ export default class Entity {
|
|||||||
.reduce((e1, e2) => (e1?.distanceTo(cursor) ?? Infinity) < e2.distanceTo(cursor) ? e1 : e2, null)
|
.reduce((e1, e2) => (e1?.distanceTo(cursor) ?? Infinity) < e2.distanceTo(cursor) ? e1 : e2, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
damage(amount) {
|
damage(amount, source = null) {
|
||||||
let damage = amount
|
let damage = amount
|
||||||
if (this.hasBuff(Buff.exposed.id)) {
|
if (this.hasBuff(Buff.exposed.id)) {
|
||||||
damage *= 3 // TODO: move to buff, make generic
|
const buff = this.getBuff(Buff.exposed.id)
|
||||||
|
if (buff.source == source.id) {
|
||||||
|
damage *= 3 // TODO: move to Buff class to make generic
|
||||||
this.removeBuff(Buff.exposed.id)
|
this.removeBuff(Buff.exposed.id)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.health = Math.min(Math.max(0, this.health - damage), this.maxHealth)
|
this.health = Math.min(Math.max(0, this.health - damage), this.maxHealth)
|
||||||
}
|
}
|
||||||
@@ -209,6 +215,16 @@ export default class Entity {
|
|||||||
return this.position.distanceTo(cursor)
|
return this.position.distanceTo(cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getBuff(id) {
|
||||||
|
const entityBuff = this.buffs.find((it) => it.id == id)
|
||||||
|
if (entityBuff == null) { return }
|
||||||
|
|
||||||
|
const buffDefinition = this.game?.buffs.find((it) => it.id == entityBuff.id)
|
||||||
|
if (buffDefinition == null) { return }
|
||||||
|
|
||||||
|
return { ...buffDefinition, ...entityBuff }
|
||||||
|
}
|
||||||
|
|
||||||
hasBuff(id) {
|
hasBuff(id) {
|
||||||
return this.buffs.some((it) => it.id == id)
|
return this.buffs.some((it) => it.id == id)
|
||||||
}
|
}
|
||||||
@@ -405,13 +421,8 @@ export default class Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#tickBuff(index) {
|
#tickBuff(index) {
|
||||||
const entityBuff = this.buffs[index]
|
if (this.buffs[index] == null) { return }
|
||||||
if (entityBuff == null) { return }
|
const buff = this.getBuff(this.buffs[index].id)
|
||||||
|
|
||||||
const buffDefinition = this.game?.buffs.find((it) => it.id == entityBuff.id)
|
|
||||||
if (buffDefinition == null) { return }
|
|
||||||
|
|
||||||
const buff = { ...buffDefinition, ...entityBuff }
|
|
||||||
const duration = this.game?.secToTick(buff.duration) ?? 0
|
const duration = this.game?.secToTick(buff.duration) ?? 0
|
||||||
const currentTick = this.game?.currentTick ?? 0
|
const currentTick = this.game?.currentTick ?? 0
|
||||||
|
|
||||||
|
|||||||
+9
-9
@@ -121,17 +121,17 @@ function laneScenario() {
|
|||||||
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: true, route: redRoute })))
|
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: true, route: redRoute })))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// game.logic = gameLogic
|
game.logic = gameLogic
|
||||||
|
|
||||||
player2.teleport(new Vector2(100, 100))
|
// player2.teleport(new Vector2(100, 100))
|
||||||
player2.logic = function patrolLogic() {
|
// player2.logic = function patrolLogic() {
|
||||||
const entity = this
|
// const entity = this
|
||||||
if (entity.position.x < 100) { entity.memory.patrolReverse = false }
|
// if (entity.position.x < 100) { entity.memory.patrolReverse = false }
|
||||||
if (entity.position.x > 1900) { entity.memory.patrolReverse = true }
|
// if (entity.position.x > 1900) { entity.memory.patrolReverse = true }
|
||||||
const goal = entity.memory.patrolReverse ? new Vector2(50, 100) : new Vector2(1950, 100)
|
// const goal = entity.memory.patrolReverse ? new Vector2(50, 100) : new Vector2(1950, 100)
|
||||||
|
|
||||||
entity.moveAction(goal)
|
// entity.moveAction(goal)
|
||||||
}
|
// }
|
||||||
|
|
||||||
// player1.abilities[0] = 'melee_attack'
|
// player1.abilities[0] = 'melee_attack'
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user