From 305980b7f9d4b7e2abea1738f3721a560165e30d Mon Sep 17 00:00:00 2001 From: Thayol Date: Thu, 23 Jan 2025 14:20:14 +0900 Subject: [PATCH] add shield buff property --- public/index.html | 2 ++ src/ability.js | 6 +++--- src/buff.js | 8 ++++++++ src/entity.js | 51 +++++++++++++++++++++++++++++++++-------------- src/level.js | 1 - 5 files changed, 49 insertions(+), 19 deletions(-) diff --git a/public/index.html b/public/index.html index ec296b2..437a48b 100644 --- a/public/index.html +++ b/public/index.html @@ -159,6 +159,7 @@ .buff:hover { overflow: visible; + height: fit-content; z-index: 3; } @@ -167,6 +168,7 @@ padding: 5px; background-color: black; width: fit-content; + min-width: 200px; height: 100%; } diff --git a/src/ability.js b/src/ability.js index ecb00a0..1847b2b 100644 --- a/src/ability.js +++ b/src/ability.js @@ -235,7 +235,7 @@ export default class Ability { const entityId = collidingEntity.id if (!collided.has(entityId)) { - collidingEntity.heal(amount, caster) + collidingEntity.applyBuff(Buff.shieldThrowShield.id, caster.id) collided.add(entityId) } } @@ -252,8 +252,8 @@ export default class Ability { } const shieldThrowSecondAfter = function shieldThrowSecondAfter(projectile, homingTarget) { - caster.heal(amount, caster) - caster.heal(amount, caster) // NOTE: duplicated on purpose + caster.applyBuff(Buff.shieldThrowShield.id, caster.id) + caster.applyBuff(Buff.shieldThrowShield.id, caster.id) // NOTE: duplicated on purpose } const shieldThrowFirstAfter = function shieldThrowFirstAfter(projectile, homingTarget) { diff --git a/src/buff.js b/src/buff.js index baf7607..44ae8a6 100644 --- a/src/buff.js +++ b/src/buff.js @@ -7,6 +7,7 @@ export default class Buff { damageMultiplier = null duration = 0 + shield = null #effect = null @@ -25,4 +26,11 @@ export default class Buff { duration: 4, onHitMultiplier: 3, }) + + static shieldThrowShield = new Buff({ + id: 'shield_throw_shield', + name: 'Shield (of Shield Throw)', + duration: 5, + shield: 200, + }) } diff --git a/src/entity.js b/src/entity.js index 2beca9e..30e859d 100644 --- a/src/entity.js +++ b/src/entity.js @@ -28,21 +28,22 @@ export default class Entity { visionRange = 900 visualRadius = null - #collision = true - #ghostable = true #attacking = false #bbox = new Float32Array(4) #colliders = [] - #entitiesInVision = [] - #projectilesInVision = [] - #pathfindingCooldown = 0 - #pathfindingObstacleLimit = null + #collision = true #dest = null + #entitiesInVision = [] #game = null + #ghostable = true #logic = null #moving = false - #path = [] #noPathfindingUntil = 0 + #path = [] + #pathfindingCooldown = 0 + #pathfindingObstacleLimit = null + #projectilesInVision = [] + #queuedAction = null #spawnPosition = new Vector2() static bbox(x, y, radius) { @@ -177,7 +178,6 @@ export default class Entity { this.moveAction(cursor, true) } - // TODO: buffer skill inputs castAction(slot, cursor, halt = false) { if (this.dead) { return } @@ -267,16 +267,27 @@ export default class Entity { } applyBuff(id, sourceId = null) { + const buff = (this.game?.buffs ?? []).find((it) => it.id, id) + if (buff == null) { return false } + const index = this.buffs.findIndex((it) => it.id == id) const source = sourceId ?? this.id const timestamp = this.game?.currentTick ?? 0 - if (index > -1) { - this.buffs[index].timestamp = timestamp - this.buffs[index].source = source + if (index < 0) { + const entityBuff = { id, source, timestamp } + if (buff.shield != null) { + entityBuff.shield = buff.shield + } + + this.buffs.push(entityBuff) } else { - this.buffs.push({ id, source, timestamp }) + this.buffs[index].timestamp = timestamp + this.buffs[index].source = source + if (buff.shield != null) { + this.buffs[index].shield = (this.buffs[index].shield ?? 0) + buff.shield + } } } @@ -322,7 +333,6 @@ export default class Entity { return entitiesAndTerrains.filter((it) => !it.dead && it.collision && !((this.ghosting && it.ghostable) || (this.ghostable && it.ghosting)) && SATX.bboxCheck(bbox, it.bbox)) } - // TODO: add shielding logic damage(amount, source = null) { if (this.dead) { return } @@ -335,11 +345,22 @@ export default class Entity { } } - const damageMultiplerBuffs = (source?.buffs ?? []).map((it) => it.getBuff).filter((it) => it != null && it.damageMultiplier != null) + const buffs = (source?.buffs ?? []) + const damageMultiplerBuffs = buffs.map((it) => it.getBuff).filter((it) => it != null && it.damageMultiplier != null) const buffPassiveDamageMultiplier = damageMultiplerBuffs.reduce((it) => it.damageMultiplier - 1, 0) const damageMultipler = 1 + buffPassiveDamageMultiplier + customMultipliers - const damage = amount * damageMultipler + let damage = amount * damageMultipler + + if (damage <= 0) { + buffs.filter((it) => it.shield != null && it.shield > 0).forEach((it) => { + if (damage <= 0) { return } + + const shielded = Math.max(0, Math.min(damage, it.shield)) + it.shield -= shielded + damage -= shielded + }) + } this.health = Math.min(Math.max(0, this.health - damage), this.maxHealth) } diff --git a/src/level.js b/src/level.js index 408ff2f..fc65fad 100644 --- a/src/level.js +++ b/src/level.js @@ -26,7 +26,6 @@ export class Dungeon { game.spawnEntity(new Entity(Template.player({ id: '2', spawnPosition: new Vector2(1500, 700), team, dead: true }))) game.spawnEntity(new Entity(Template.basilisk({ id: 'boss', spawnPosition: new Vector2(2200, 750), team: Team.neutral }))) - game.entities.find((it) => it.id == 'boss').damage(9999) game.start() }