diff --git a/src/core/types/missile.ts b/src/core/types/missile.ts index 4517a9d..6d2b28c 100644 --- a/src/core/types/missile.ts +++ b/src/core/types/missile.ts @@ -37,7 +37,7 @@ export class Missile implements Destroyable { head = this } - public static launch( + public static launch( config: Readonly<{ art: string scale?: number @@ -51,7 +51,8 @@ export class Missile implements Destroyable { }>, source: Unit | Vec2, target: Unit | Vec2, - onArrival: (missile: Missile, success: boolean) => void + onArrival: (missile: Missile, success: boolean, ...parameters: T) => void, + ...parameters: T ): Missile { let offsetX = config.sourceOffset?.x ?? 0 let offsetY = config.sourceOffset?.y ?? 0 @@ -166,7 +167,7 @@ export class Missile implements Destroyable { visualPositionArcY = currentVisualTargetY visualPositionArcZ = currentVisualTargetZ retarget = false - safeCall(onArrival, this, true) + safeCall(onArrival, this, true, ...parameters) return !retarget } diff --git a/src/engine/behaviour/ability.ts b/src/engine/behaviour/ability.ts index 0d9d1b0..6112462 100644 --- a/src/engine/behaviour/ability.ts +++ b/src/engine/behaviour/ability.ts @@ -10,11 +10,15 @@ import { Effect, EffectParameters } from "../../core/types/effect" import { AREA_EFFECT_MODEL_PATHS_ABILITY_STRING_ARRAY_FIELD, EFFECT_MODEL_PATHS_ABILITY_STRING_ARRAY_FIELD, + MISSILE_ARC_ABILITY_FLOAT_FIELD, + MISSILE_MODEL_PATHS_ABILITY_STRING_ARRAY_FIELD, + MISSILE_SPEED_ABILITY_INTEGER_FIELD, SPECIAL_EFFECT_ATTACHMENT_POINT_STRING_FIELD, SPECIAL_EFFECT_MODEL_PATHS_ABILITY_STRING_ARRAY_FIELD, } from "../standard/fields/ability" import { AbilityDependentValue, resolveCurrentAbilityDependentValue } from "../object-field/ability" import { Timer } from "../../core/types/timer" +import { Missile } from "../../core/types/missile" const createBehaviorFunctionsByAbilityTypeId = new LuaMap< AbilityTypeId, @@ -26,9 +30,23 @@ export type AbilityBehaviorConstructor = new ( ...args: Args ) => AbilityBehavior +const invokeOnMissileArrival = ( + _missile: Missile, + success: boolean, + abilityBehavior: AbilityBehavior<{ periodicActionParameters: T }>, + ...parameters: T +): void => { + if (success) { + abilityBehavior.onMissileArrival(...parameters) + } +} + export abstract class AbilityBehavior< - PeriodicActionParameters extends any[] = any[] -> extends Behavior { + Parameters extends { + periodicActionParameters?: any[] + missileParameters?: any[] + } = {} +> extends Behavior> { public constructor(ability: Ability) { super(ability) } @@ -99,6 +117,51 @@ export abstract class AbilityBehavior< } } + private static MissileLaunchConfig = class { + public constructor(private readonly abilityBehavior: AbilityBehavior) {} + + public get art(): string { + return MISSILE_MODEL_PATHS_ABILITY_STRING_ARRAY_FIELD.getValue( + this.abilityBehavior.ability, + 0 + ) + } + + public get arc(): number { + return MISSILE_ARC_ABILITY_FLOAT_FIELD.getValue(this.abilityBehavior.ability) + } + + public get speed(): number { + return MISSILE_SPEED_ABILITY_INTEGER_FIELD.getValue(this.abilityBehavior.ability) + } + } + + private get missileLaunchConfig(): InstanceType { + const missileLaunchConfig = new AbilityBehavior.MissileLaunchConfig(this) + rawset(this as any, "missileLaunchConfig", missileLaunchConfig) + return missileLaunchConfig + } + + protected launchMissile( + source: Unit, + target: Unit, + ...parameters: NonNullable + ): void { + Missile.launch( + this.missileLaunchConfig, + source, + target, + invokeOnMissileArrival, + this, + ...parameters + ) + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + public onMissileArrival(...parameters: NonNullable): void { + // no-op + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars public onUnitGainAbility(_unit: Unit): void { // no-op diff --git a/src/engine/standard/fields/ability.ts b/src/engine/standard/fields/ability.ts index bfa2cd8..2fe846d 100644 --- a/src/engine/standard/fields/ability.ts +++ b/src/engine/standard/fields/ability.ts @@ -59,7 +59,7 @@ export const ITEM_ABILITY_ABILITY_BOOLEAN_FIELD = AbilityBooleanField.create(fou export const CHECK_DEPENDENCIES_ABILITY_BOOLEAN_FIELD = AbilityBooleanField.create(fourCC("achd")) -export const ARF_MISSILE_ARC_ABILITY_FLOAT_FIELD = AbilityFloatField.create(fourCC("amac")) +export const MISSILE_ARC_ABILITY_FLOAT_FIELD = AbilityFloatField.create(fourCC("amac")) export const NAME_ABILITY_STRING_FIELD = AbilityStringField.create(fourCC("anam"))