All files / blacktrigram/src/systems/vitalpoint HitDetection.ts

8.75% Statements 7/80
100% Branches 0/0
0% Functions 0/2
8.75% Lines 7/80

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106      1x 1x     1x       1x                                                                                             1x                                                                                       1x   1x  
import type { Position } from "../../types/common";
import { VitalPoint, VitalPointEffect, VitalPointHitResult } from "./types";
// Fix: Import both EffectIntensity type and enum from the correct location
import { VitalPointEffectType, VitalPointSeverity } from "../../types/common";
import { EffectIntensity, EffectType } from "../effects";
import { StatusEffect } from "../types";
 
export class HitDetection {
  /**
   * Convert VitalPointEffect to StatusEffect with required properties
   */
  private static convertVitalPointEffectToStatusEffect(
    vitalPointEffect: VitalPointEffect,
    vitalPointId: string
  ): StatusEffect {
    const currentTime = Date.now();
 
    // Fix: Use EffectType from effects.ts (string literals)
    const typeMapping: Record<VitalPointEffectType, EffectType> = {
      [VitalPointEffectType.UNCONSCIOUSNESS]: "stun",
      [VitalPointEffectType.BREATHLESSNESS]: "stamina_drain",
      [VitalPointEffectType.PAIN]: "weakened",
      [VitalPointEffectType.PARALYSIS]: "paralysis",
      [VitalPointEffectType.STUN]: "stun",
      [VitalPointEffectType.WEAKNESS]: "weakened",
      [VitalPointEffectType.DISORIENTATION]: "confusion",
      [VitalPointEffectType.BLOOD_FLOW_RESTRICTION]: "bleed",
      [VitalPointEffectType.NERVE_DISRUPTION]: "paralysis",
      [VitalPointEffectType.ORGAN_DISRUPTION]: "vulnerability",
    };
 
    // Fix: Use the correct EffectIntensity enum values from enums.ts
    const intensityMapping: Record<EffectIntensity, EffectIntensity> = {
      [EffectIntensity.WEAK]: EffectIntensity.WEAK,
      [EffectIntensity.MINOR]: EffectIntensity.MINOR,
      [EffectIntensity.LOW]: EffectIntensity.LOW,
      [EffectIntensity.MEDIUM]: EffectIntensity.MEDIUM,
      [EffectIntensity.MODERATE]: EffectIntensity.MODERATE,
      [EffectIntensity.HIGH]: EffectIntensity.HIGH,
      [EffectIntensity.SEVERE]: EffectIntensity.SEVERE,
      [EffectIntensity.CRITICAL]: EffectIntensity.CRITICAL,
      [EffectIntensity.EXTREME]: EffectIntensity.EXTREME,
    };
 
    return {
      id: `${vitalPointEffect.id}_${currentTime}`,
      type: typeMapping[vitalPointEffect.type] || "weakened",
      intensity:
        intensityMapping[vitalPointEffect.intensity] || EffectIntensity.MEDIUM,
      duration: vitalPointEffect.duration,
      description: vitalPointEffect.description,
      stackable: vitalPointEffect.stackable,
      source: vitalPointId,
      startTime: currentTime,
      endTime: currentTime + vitalPointEffect.duration,
    };
  }
 
  processVitalPointHit(
    vitalPoint: VitalPoint,
    hitPosition: Position,
    force: number
  ): VitalPointHitResult {
    // Calculate hit accuracy
    const distance = Math.sqrt(
      Math.pow(hitPosition.x - vitalPoint.position.x, 2) +
        Math.pow(hitPosition.y - vitalPoint.position.y, 2)
    );
 
    // Fix: Provide default values for potentially undefined properties
    const radius = vitalPoint.radius ?? 10; // Default radius
    const requiredForce = vitalPoint.requiredForce ?? 50; // Default force requirement
 
    const isHit = distance <= radius;
 
    if (!isHit) {
      return {
        hit: false,
        damage: 0,
        effects: [],
        severity: VitalPointSeverity.MINOR,
      };
    }
 
    // Calculate damage
    const baseDamage = vitalPoint.baseDamage || 15;
    const forceMultiplier = Math.min(force / requiredForce, 2.0);
    const damage = Math.floor(baseDamage * forceMultiplier);
 
    // Convert VitalPointEffect array to StatusEffect array
    const effects = vitalPoint.effects.map((effect) =>
      HitDetection.convertVitalPointEffectToStatusEffect(effect, vitalPoint.id)
    );
 
    return {
      hit: true,
      vitalPoint,
      damage,
      effects,
      severity: vitalPoint.severity,
    };
  }
}
 
export default HitDetection;