extend moveset with attack, halt, stop
This commit is contained in:
+75
-23
@@ -8,7 +8,7 @@ export default class Entity {
|
||||
id = crypto.randomUUID()
|
||||
speed = 400
|
||||
radius = 0
|
||||
health = 1 // TODO: health can go into negatives and can go over maxHealth
|
||||
health = 1
|
||||
maxHealth = 1
|
||||
abilities = [
|
||||
Ability.basicAttack,
|
||||
@@ -21,6 +21,7 @@ export default class Entity {
|
||||
|
||||
cooldowns = {}
|
||||
|
||||
#attack = false
|
||||
#position = new Vector2()
|
||||
#dest = null
|
||||
#game = null
|
||||
@@ -70,6 +71,72 @@ export default class Entity {
|
||||
])
|
||||
}
|
||||
|
||||
attackAction(x, y) {
|
||||
this.moveAction(x, y, true)
|
||||
}
|
||||
|
||||
castAction(slot, x, y, clearDestination = true) {
|
||||
const ability = this.abilities[slot]
|
||||
|
||||
if (this.casting != null) {
|
||||
const abilityBeingCasted = this.casting.ability
|
||||
if (abilityBeingCasted.id == ability.id) {
|
||||
return false
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
if (clearDestination) {
|
||||
this.#dest = null
|
||||
}
|
||||
|
||||
const cursor = new Vector2(x, y)
|
||||
const cooldown = this.game?.secToTick(ability.cooldown) ?? 0
|
||||
const lastCast = this.cooldowns[ability.id]
|
||||
const timestamp = this.game?.currentTick ?? 0
|
||||
if (lastCast != null && lastCast + cooldown > timestamp) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.casting = { ability, cursor, timestamp }
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
haltAction() {
|
||||
this.#dest = null
|
||||
}
|
||||
|
||||
moveAction(x, y, attack = false) {
|
||||
this.#attack = attack
|
||||
if (this.casting != null && (!this.#attack || this.casting.ability.id != this.abilities[0].id)) {
|
||||
this.casting = null
|
||||
}
|
||||
|
||||
this.#dest = SATX.fixCollisions(new Vector2(x, y), this.collidables(), this.radius, this.game?.width, this.game?.height)
|
||||
}
|
||||
|
||||
stopAction() {
|
||||
this.casting = null
|
||||
this.#dest = null
|
||||
this.#attack = false
|
||||
}
|
||||
|
||||
autoAttack() {
|
||||
if (!this.#attack) { return false }
|
||||
|
||||
if (this.game?.entities.some((e) => e.id != this.id && e.position.clone().sub(this.position).length() < this.abilities[0].range)) {
|
||||
const cooldown = this.game?.secToTick(this.abilities[0].cooldown) ?? 0
|
||||
const lastCast = this.cooldowns[this.abilities[0].id]
|
||||
const timestamp = this.game?.currentTick ?? 0
|
||||
if (lastCast != null && lastCast + cooldown > timestamp) { return false }
|
||||
|
||||
const target = this.#dest ?? this.position
|
||||
this.castAction(0, target.x, target.y, false)
|
||||
}
|
||||
}
|
||||
|
||||
cast() {
|
||||
if (this.casting == null) {
|
||||
return false
|
||||
@@ -88,22 +155,6 @@ export default class Entity {
|
||||
return true
|
||||
}
|
||||
|
||||
castAction(slot, x, y) {
|
||||
const ability = this.abilities[slot]
|
||||
const cursor = new Vector2(x, y)
|
||||
const cooldown = this.game?.secToTick(ability.cooldown) ?? 0
|
||||
const lastCast = this.cooldowns[ability.id]
|
||||
const timestamp = this.game?.currentTick ?? 0
|
||||
if (lastCast != null && lastCast + cooldown > timestamp) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.#dest = null
|
||||
this.casting = { ability, cursor, timestamp }
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
collidables() {
|
||||
const entityColliders = (this.game?.entities ?? []).filter((e) => e.id != this.id).map((e) => e.collider)
|
||||
const terrainColliders = (this.game?.terrains ?? []).map((t) => t.colliders).flat()
|
||||
@@ -123,7 +174,7 @@ export default class Entity {
|
||||
this.cooldowns[id] = this.game?.currentTick ?? 0
|
||||
}
|
||||
|
||||
damage(amount, source = null) {
|
||||
damage(amount) {
|
||||
this.health = Math.min(Math.max(0, this.health - amount), this.maxHealth)
|
||||
}
|
||||
|
||||
@@ -131,7 +182,7 @@ export default class Entity {
|
||||
this.game?.despawn(this)
|
||||
}
|
||||
|
||||
heal(amount, source = null) {
|
||||
heal(amount) {
|
||||
this.health = Math.min(Math.max(0, this.health + amount), this.maxHealth)
|
||||
}
|
||||
|
||||
@@ -143,10 +194,6 @@ export default class Entity {
|
||||
return SATX.collideObjects(this.collider, colliders)
|
||||
}
|
||||
|
||||
moveAction(x, y) {
|
||||
this.#dest = SATX.fixCollisions(new Vector2(x, y), this.collidables(), this.radius, this.game?.width, this.game?.height)
|
||||
}
|
||||
|
||||
state() {
|
||||
return {
|
||||
...this,
|
||||
@@ -165,6 +212,8 @@ export default class Entity {
|
||||
// TODO: unset destination on teleports, etc.
|
||||
// TODO: recalculate path on obstructions (currently next waypoint is used)
|
||||
takeStep(distanceTraveled = 0) {
|
||||
if (this.casting != null) { return false }
|
||||
|
||||
const speed = (this.speed / (this.game?.tickBudget ?? 1000)) - distanceTraveled
|
||||
const collidables = this.collidables()
|
||||
if (this.#dest != null) {
|
||||
@@ -213,6 +262,9 @@ export default class Entity {
|
||||
this.cast()
|
||||
this.takeStep()
|
||||
this.fixPosition()
|
||||
this.autoAttack()
|
||||
|
||||
// TODO: proper death and respawn
|
||||
if (this.health <= 0) {
|
||||
if (this.id == '1' || this.id == '2') {
|
||||
this.health = this.maxHealth
|
||||
|
||||
Reference in New Issue
Block a user