This repository has been archived on 2026-05-07. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
instructions-clear/src/ability.js
T
2025-01-17 23:40:33 +09:00

181 lines
4.8 KiB
JavaScript

import Projectile from './projectile.js'
// major damage OR minor self sustain / crowd control
// major support OR minor vision / selfless support / creative
// major control OR minor mobility
export default class Ability {
id = crypto.randomUUID()
name = 'Ability'
castTime = 0
cooldown = 0
damage = 0
moveCancelable = false
radius = 1
range = 0
speed = 1000
#effect = () => {}
get effect() { return this.#effect }
set effect(value) { this.#effect = value }
constructor(options = {}) {
Object.entries(options).forEach(([key, value]) => this[key] = value)
}
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 (collidingEntity == null) { return }
if (collidingEntity.team == (projectile.owner?.team ?? 'unknown')) { return }
collidingEntity.damage(ability.damage)
projectile.despawn()
}
const projectile = new Projectile({
onCollide: straightShotCollision,
owner: caster,
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, cursor) {
const ability = this
const target = caster.closestTargetTo(cursor, ability.range)
if (target == null) { return }
const rangedAttackAfter = function rangedAttackAfter() {
target.damage(ability.damage)
}
const projectile = new Projectile({
after: rangedAttackAfter,
homingTarget: target,
owner: caster,
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, cursor) {
const ability = this
const target = caster.closestTargetTo(cursor, ability.range)
if (target == null) { return }
target.damage(ability.damage)
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,
position: projectile.position.clone(),
radius: ability.radius,
speed: ability.speed,
homingTarget: caster,
})
caster.game?.spawnProjectile(returnProjectile)
}
const projectile = new Projectile({
after: shieldThrowReturn,
owner: caster,
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',
castTime: 0.25,
cooldown: 2,
range: 475,
effect: function blinkEffect(caster, cursor) {
const ability = this
const direction = cursor.clone().sub(caster.position)
const realRange = ability.range + caster.radius
if (direction.length() > realRange) {
direction.normalize().multiplyScalar(realRange)
}
const destination = caster.position.clone().add(direction)
caster.teleport(destination)
caster.cooldown(ability.id)
},
})
static control = new Ability({
id: 'control',
name: 'Control',
castTime: 1,
cooldown: 5,
effect: function controlEffect(caster, cursor) { },
})
}