untangle abilities
This commit is contained in:
+177
-205
@@ -29,131 +29,6 @@ export default class Ability {
|
||||
|
||||
static get noEffect() { return function noEffect() {} }
|
||||
|
||||
static straightShot = new Ability({
|
||||
id: 'straight_shot',
|
||||
name: 'Straight Shot',
|
||||
castTime: 0.25,
|
||||
cooldown: 1,
|
||||
damage: 83,
|
||||
radius: 60,
|
||||
range: 1200,
|
||||
visualRadius: 20,
|
||||
speed: 2000,
|
||||
effect: function straightShotEffect(caster, cursor) {
|
||||
const ability = this
|
||||
const straightShotCollision = function straightShotCollision(projectile, collidingEntity) {
|
||||
if (projectile.game == null) { return }
|
||||
if (collidingEntity == null) { return }
|
||||
if (collidingEntity.id == caster.id) { return }
|
||||
if (collidingEntity.team == (caster.team ?? 'unknown')) { return }
|
||||
|
||||
collidingEntity.damage(ability.damage, caster)
|
||||
projectile.despawn()
|
||||
}
|
||||
|
||||
const projectile = new Projectile({
|
||||
onCollide: straightShotCollision,
|
||||
owner: caster.id,
|
||||
position: caster.position.clone(),
|
||||
radius: ability.radius,
|
||||
speed: ability.speed,
|
||||
visualRadius: ability.visualRadius,
|
||||
})
|
||||
|
||||
projectile.destination = caster.position.clone().add(cursor.clone().sub(caster.position).normalize().multiplyScalar(ability.range + caster.radius))
|
||||
caster.game?.spawnProjectile(projectile)
|
||||
caster.cooldown(ability.id)
|
||||
},
|
||||
})
|
||||
|
||||
static rangedAttack = new Ability({
|
||||
id: 'ranged_attack',
|
||||
name: 'Ranged Attack',
|
||||
castTime: (1.6 * 0.18839),
|
||||
cooldown: 1.6,
|
||||
damage: 60,
|
||||
moveCancelable: true,
|
||||
radius: 5,
|
||||
range: 500,
|
||||
speed: 2000,
|
||||
effect: function rangedAttackEffect(caster, targetId) {
|
||||
const ability = this
|
||||
const target = caster.game?.entities.find((it) => it.id == targetId)
|
||||
if (target == null) { return }
|
||||
|
||||
const rangedAttackAfter = function rangedAttackAfter() {
|
||||
target.damage(ability.damage, caster)
|
||||
}
|
||||
|
||||
const projectile = new Projectile({
|
||||
after: rangedAttackAfter,
|
||||
homingTarget: target,
|
||||
owner: caster.id,
|
||||
position: caster.position.clone(),
|
||||
radius: ability.radius,
|
||||
speed: ability.speed,
|
||||
})
|
||||
|
||||
caster.game?.spawnProjectile(projectile)
|
||||
caster.cooldown(ability.id)
|
||||
},
|
||||
})
|
||||
|
||||
static meleeAttack = new Ability({
|
||||
id: 'melee_attack',
|
||||
name: 'Melee Attack',
|
||||
castTime: (1.4 * 0.22),
|
||||
cooldown: 1.4,
|
||||
moveCancelable: true,
|
||||
damage: 60,
|
||||
radius: 5,
|
||||
range: 100,
|
||||
effect: function meleeAttackEffect(caster, targetId) {
|
||||
const ability = this
|
||||
const target = caster.game?.entities.find((it) => it.id == targetId)
|
||||
if (target == null) { return }
|
||||
|
||||
target.damage(ability.damage, caster)
|
||||
caster.cooldown(ability.id)
|
||||
},
|
||||
})
|
||||
|
||||
static shieldThrow = new Ability({
|
||||
id: 'shield_throw',
|
||||
name: 'Shield Throw',
|
||||
castTime: 0.25,
|
||||
cooldown: 5,
|
||||
radius: 110,
|
||||
range: 1025,
|
||||
speed: 2400,
|
||||
effect: function shieldThrowEffect(caster, cursor) {
|
||||
const ability = this
|
||||
const shieldThrowReturn = function shieldThrowReturn(projectile, homingTarget) {
|
||||
const returnProjectile = new Projectile({
|
||||
owner: caster.id,
|
||||
position: projectile.position.clone(),
|
||||
radius: ability.radius,
|
||||
speed: ability.speed,
|
||||
homingTarget: caster,
|
||||
})
|
||||
|
||||
caster.game?.spawnProjectile(returnProjectile)
|
||||
}
|
||||
|
||||
const projectile = new Projectile({
|
||||
after: shieldThrowReturn,
|
||||
owner: caster.id,
|
||||
position: caster.position.clone(),
|
||||
radius: ability.radius,
|
||||
speed: ability.speed,
|
||||
})
|
||||
|
||||
projectile.destination = caster.position.clone().add(cursor.clone().sub(caster.position).normalize().multiplyScalar(ability.range + caster.radius))
|
||||
caster.game?.spawnProjectile(projectile)
|
||||
caster.cooldown(ability.id)
|
||||
},
|
||||
})
|
||||
|
||||
static blink = new Ability({
|
||||
id: 'blink',
|
||||
name: 'Blink',
|
||||
@@ -174,92 +49,13 @@ export default class Ability {
|
||||
},
|
||||
})
|
||||
|
||||
static expose = new Ability({
|
||||
id: 'expose',
|
||||
name: 'Expose',
|
||||
castTime: 0.25,
|
||||
cooldown: 6,
|
||||
radius: 80,
|
||||
range: 1200,
|
||||
speed: 1700,
|
||||
visualRadius: 50,
|
||||
effect: function exposeEffect(caster, cursor) {
|
||||
const ability = this
|
||||
const exposeCollision = function exposeCollision(projectile, collidingEntity) {
|
||||
if (projectile.game == null) { return }
|
||||
if (collidingEntity == null) { return }
|
||||
if (collidingEntity.team == caster.id) { return }
|
||||
if (collidingEntity.team == (caster.team ?? 'unknown')) { return }
|
||||
|
||||
collidingEntity.applyBuff(Buff.exposed.id, caster.id)
|
||||
projectile.despawn()
|
||||
}
|
||||
|
||||
const projectile = new Projectile({
|
||||
onCollide: exposeCollision,
|
||||
owner: caster.id,
|
||||
position: caster.position.clone(),
|
||||
radius: ability.radius,
|
||||
speed: ability.speed,
|
||||
visualRadius: ability.visualRadius,
|
||||
})
|
||||
|
||||
projectile.destination = caster.position.clone().add(cursor.clone().sub(caster.position).normalize().multiplyScalar(ability.range + caster.radius))
|
||||
caster.game?.spawnProjectile(projectile)
|
||||
caster.cooldown(ability.id)
|
||||
},
|
||||
})
|
||||
|
||||
static control = new Ability({
|
||||
id: 'control',
|
||||
name: 'Control',
|
||||
castTime: 1,
|
||||
cooldown: 5,
|
||||
effect: function controlEffect(caster, cursor) { },
|
||||
})
|
||||
|
||||
static castingVision = new Ability({
|
||||
id: 'casting_vision',
|
||||
name: 'Casting Vision',
|
||||
radius: 300,
|
||||
duration: 2,
|
||||
effect: function castingVisionEffect(caster, cursor) {
|
||||
const ability = this
|
||||
|
||||
const currentTick = caster.game?.currentTick ?? 0
|
||||
const duration = caster.game?.secToTick(ability.duration) ?? 0
|
||||
const despawnAfter = currentTick + duration
|
||||
|
||||
const castingVisionLogic = function castingVisionLogic(projectile) {
|
||||
const currentTick = projectile.game?.currentTick ?? 0
|
||||
if (currentTick > despawnAfter) {
|
||||
projectile.despawn()
|
||||
}
|
||||
}
|
||||
|
||||
const projectile = new Projectile({
|
||||
logic: castingVisionLogic,
|
||||
owner: caster.id,
|
||||
position: cursor.clone(),
|
||||
visionRange: ability.radius,
|
||||
})
|
||||
|
||||
caster.game?.spawnProjectile(projectile)
|
||||
},
|
||||
})
|
||||
|
||||
static circleOfResurrectionChannel = new Ability({
|
||||
id: 'channel:circle_of_resurrection',
|
||||
name: 'Channeling: Circle of Resurrection',
|
||||
castTime: 3,
|
||||
})
|
||||
|
||||
static circleOfResurrection = new Ability({
|
||||
id: 'circle_of_resurrection',
|
||||
name: 'Circle of Resurrection',
|
||||
castTime: 0.5,
|
||||
cooldown: 100,
|
||||
duration: 3,
|
||||
moveCancelable: true,
|
||||
radius: 300,
|
||||
range: 300,
|
||||
effect: function circleOfResurrectionEffect(caster, cursor) {
|
||||
@@ -312,4 +108,180 @@ export default class Ability {
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
static circleOfResurrectionChannel = new Ability({
|
||||
id: 'channel:circle_of_resurrection',
|
||||
name: 'Channeling: Circle of Resurrection',
|
||||
castTime: 3,
|
||||
moveCancelable: true,
|
||||
})
|
||||
|
||||
static control = new Ability({
|
||||
id: 'control',
|
||||
name: 'Control',
|
||||
castTime: 1,
|
||||
cooldown: 5,
|
||||
effect: function controlEffect(caster, cursor) { },
|
||||
})
|
||||
|
||||
static expose = new Ability({
|
||||
id: 'expose',
|
||||
name: 'Expose',
|
||||
castTime: 0.25,
|
||||
cooldown: 6,
|
||||
radius: 80,
|
||||
range: 1200,
|
||||
speed: 1700,
|
||||
visualRadius: 50,
|
||||
effect: function exposeEffect(caster, cursor) {
|
||||
const ability = this
|
||||
const exposeCollision = function exposeCollision(projectile, collidingEntity) {
|
||||
if (projectile.game == null) { return }
|
||||
if (collidingEntity == null) { return }
|
||||
if (collidingEntity.team == caster.id) { return }
|
||||
if (collidingEntity.team == (caster.team ?? 'unknown')) { return }
|
||||
|
||||
collidingEntity.applyBuff(Buff.exposed.id, caster.id)
|
||||
projectile.despawn()
|
||||
}
|
||||
|
||||
const projectile = new Projectile({
|
||||
onCollide: exposeCollision,
|
||||
owner: caster.id,
|
||||
position: caster.position.clone(),
|
||||
radius: ability.radius,
|
||||
speed: ability.speed,
|
||||
visualRadius: ability.visualRadius,
|
||||
})
|
||||
|
||||
projectile.destination = caster.position.clone().add(cursor.clone().sub(caster.position).normalize().multiplyScalar(ability.range + caster.radius))
|
||||
caster.game?.spawnProjectile(projectile)
|
||||
caster.cooldown(ability.id)
|
||||
},
|
||||
})
|
||||
|
||||
static meleeAttack = new Ability({
|
||||
id: 'melee_attack',
|
||||
name: 'Melee Attack',
|
||||
castTime: (1.4 * 0.22),
|
||||
cooldown: 1.4,
|
||||
moveCancelable: true,
|
||||
damage: 60,
|
||||
radius: 5,
|
||||
range: 100,
|
||||
effect: function meleeAttackEffect(caster, targetId) {
|
||||
const ability = this
|
||||
const target = caster.game?.entities.find((it) => it.id == targetId)
|
||||
if (target == null) { return }
|
||||
|
||||
target.damage(ability.damage, caster)
|
||||
caster.cooldown(ability.id)
|
||||
},
|
||||
})
|
||||
|
||||
static rangedAttack = new Ability({
|
||||
id: 'ranged_attack',
|
||||
name: 'Ranged Attack',
|
||||
castTime: (1.6 * 0.18839),
|
||||
cooldown: 1.6,
|
||||
damage: 60,
|
||||
moveCancelable: true,
|
||||
radius: 5,
|
||||
range: 500,
|
||||
speed: 2000,
|
||||
effect: function rangedAttackEffect(caster, targetId) {
|
||||
const ability = this
|
||||
const target = caster.game?.entities.find((it) => it.id == targetId)
|
||||
if (target == null) { return }
|
||||
|
||||
const rangedAttackAfter = function rangedAttackAfter() {
|
||||
target.damage(ability.damage, caster)
|
||||
}
|
||||
|
||||
const projectile = new Projectile({
|
||||
after: rangedAttackAfter,
|
||||
homingTarget: target,
|
||||
owner: caster.id,
|
||||
position: caster.position.clone(),
|
||||
radius: ability.radius,
|
||||
speed: ability.speed,
|
||||
})
|
||||
|
||||
caster.game?.spawnProjectile(projectile)
|
||||
caster.cooldown(ability.id)
|
||||
},
|
||||
})
|
||||
|
||||
static shieldThrow = new Ability({
|
||||
id: 'shield_throw',
|
||||
name: 'Shield Throw',
|
||||
castTime: 0.25,
|
||||
cooldown: 5,
|
||||
radius: 110,
|
||||
range: 1025,
|
||||
speed: 2400,
|
||||
effect: function shieldThrowEffect(caster, cursor) {
|
||||
const ability = this
|
||||
const shieldThrowReturn = function shieldThrowReturn(projectile, homingTarget) {
|
||||
const returnProjectile = new Projectile({
|
||||
owner: caster.id,
|
||||
position: projectile.position.clone(),
|
||||
radius: ability.radius,
|
||||
speed: ability.speed,
|
||||
homingTarget: caster,
|
||||
})
|
||||
|
||||
caster.game?.spawnProjectile(returnProjectile)
|
||||
}
|
||||
|
||||
const projectile = new Projectile({
|
||||
after: shieldThrowReturn,
|
||||
owner: caster.id,
|
||||
position: caster.position.clone(),
|
||||
radius: ability.radius,
|
||||
speed: ability.speed,
|
||||
})
|
||||
|
||||
projectile.destination = caster.position.clone().add(cursor.clone().sub(caster.position).normalize().multiplyScalar(ability.range + caster.radius))
|
||||
caster.game?.spawnProjectile(projectile)
|
||||
caster.cooldown(ability.id)
|
||||
},
|
||||
})
|
||||
|
||||
static straightShot = new Ability({
|
||||
id: 'straight_shot',
|
||||
name: 'Straight Shot',
|
||||
castTime: 0.25,
|
||||
cooldown: 1,
|
||||
damage: 83,
|
||||
radius: 60,
|
||||
range: 1200,
|
||||
visualRadius: 20,
|
||||
speed: 2000,
|
||||
effect: function straightShotEffect(caster, cursor) {
|
||||
const ability = this
|
||||
const straightShotCollision = function straightShotCollision(projectile, collidingEntity) {
|
||||
if (projectile.game == null) { return }
|
||||
if (collidingEntity == null) { return }
|
||||
if (collidingEntity.id == caster.id) { return }
|
||||
if (collidingEntity.team == (caster.team ?? 'unknown')) { return }
|
||||
|
||||
collidingEntity.damage(ability.damage, caster)
|
||||
projectile.despawn()
|
||||
}
|
||||
|
||||
const projectile = new Projectile({
|
||||
onCollide: straightShotCollision,
|
||||
owner: caster.id,
|
||||
position: caster.position.clone(),
|
||||
radius: ability.radius,
|
||||
speed: ability.speed,
|
||||
visualRadius: ability.visualRadius,
|
||||
})
|
||||
|
||||
projectile.destination = caster.position.clone().add(cursor.clone().sub(caster.position).normalize().multiplyScalar(ability.range + caster.radius))
|
||||
caster.game?.spawnProjectile(projectile)
|
||||
caster.cooldown(ability.id)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
+25
-4
@@ -1,7 +1,7 @@
|
||||
import { Vector2 } from 'three'
|
||||
import Ability from './ability.js'
|
||||
import Buff from './buff.js'
|
||||
import Pathfind from './pathfind.js'
|
||||
import Projectile from './projectile.js'
|
||||
import SAT from 'sat'
|
||||
import SATX from './satx.js'
|
||||
import Team from './team.js'
|
||||
@@ -184,7 +184,7 @@ export default class Entity {
|
||||
if (ability == null) { return }
|
||||
|
||||
if (this.casting != null) {
|
||||
const abilityBeingCasted = this.game?.abilities.filter((it) => it.id == this.casting.ability)
|
||||
const abilityBeingCasted = this.game?.abilities.find((it) => it.id == this.casting.ability)
|
||||
if (abilityBeingCasted != null && abilityBeingCasted.id == ability.id) {
|
||||
return false
|
||||
}
|
||||
@@ -229,7 +229,7 @@ export default class Entity {
|
||||
moveAction(cursor, attack = false) {
|
||||
if (this.dead) { return }
|
||||
|
||||
if (this.casting != null && this.game?.abilities.filter((it) => it.id == this.casting.ability)?.moveCancelable) {
|
||||
if (this.casting != null && this.game?.abilities.find((it) => it.id == this.casting.ability)?.moveCancelable) {
|
||||
if (!attack && !(this.casting != null && this.casting.ability == this.abilities[0])) {
|
||||
this.casting = null
|
||||
}
|
||||
@@ -637,7 +637,28 @@ export default class Entity {
|
||||
|
||||
const enemiesNearby = (this.game?.entities ?? []).some((it) => !it.dead && it.team == enemyTeam && it.distanceTo(this.position) <= (it.visionRange + this.radius))
|
||||
if (enemiesNearby) {
|
||||
Ability.castingVision.effect(this, this.position)
|
||||
const radius = 300
|
||||
const duration = this.game?.secToTick(2) ?? 0
|
||||
if (duration <= 0) { return }
|
||||
|
||||
const currentTick = this.game?.currentTick ?? 0
|
||||
const despawnAfter = currentTick + duration
|
||||
|
||||
const castingVisionLogic = function castingVisionLogic(projectile) {
|
||||
const currentTick = projectile.game?.currentTick ?? 0
|
||||
if (currentTick > despawnAfter) {
|
||||
projectile.despawn()
|
||||
}
|
||||
}
|
||||
|
||||
const projectile = new Projectile({
|
||||
logic: castingVisionLogic,
|
||||
owner: this.id,
|
||||
position: this.position.clone(),
|
||||
visionRange: radius,
|
||||
})
|
||||
|
||||
this.game?.spawnProjectile(projectile)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user