blacktrigram 0.7.39 → 0.7.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/App2.js.map +1 -1
- package/lib/audio/AudioAssetLoader.js.map +1 -1
- package/lib/audio/AudioAssetRegistry.js.map +1 -1
- package/lib/audio/AudioCache.js.map +1 -1
- package/lib/audio/AudioManager.js.map +1 -1
- package/lib/audio/AudioMonitor.js.map +1 -1
- package/lib/audio/AudioPool.js.map +1 -1
- package/lib/audio/AudioProvider.js.map +1 -1
- package/lib/audio/AudioUtils.js.map +1 -1
- package/lib/audio/BoneImpactAudioMap.js.map +1 -1
- package/lib/audio/VariantSelector.js.map +1 -1
- package/lib/audio/types.js.map +1 -1
- package/lib/components/screens/combat/CombatScreen3D.js.map +1 -1
- package/lib/components/screens/combat/components/controls/CombatButtons.js.map +1 -1
- package/lib/components/screens/combat/components/controls/CombatControlsPanel.js.map +1 -1
- package/lib/components/screens/combat/components/controls/ControlsGuide.js.map +1 -1
- package/lib/components/screens/combat/components/controls/KeyboardHints.js.map +1 -1
- package/lib/components/screens/combat/components/controls/PauseMenu.js.map +1 -1
- package/lib/components/screens/combat/components/controls/PauseMenuButton.js.map +1 -1
- package/lib/components/screens/combat/components/controls/QuickSettings.js.map +1 -1
- package/lib/components/screens/combat/components/effects/BloodDecals3D.js.map +1 -1
- package/lib/components/screens/combat/components/effects/BloodLossOverlayHtml.js.map +1 -1
- package/lib/components/screens/combat/components/effects/BloodParticles3D.js.map +1 -1
- package/lib/components/screens/combat/components/effects/BloodViscosity3D.js.map +1 -1
- package/lib/components/screens/combat/components/effects/CombatParticleEffects3D.js.map +1 -1
- package/lib/components/screens/combat/components/effects/ConsciousnessBlur.js.map +1 -1
- package/lib/components/screens/combat/components/effects/InternalDamage3D.js.map +1 -1
- package/lib/components/screens/combat/components/effects/PainVignette.js.map +1 -1
- package/lib/components/screens/combat/components/effects/ParticleAudio3D.js.map +1 -1
- package/lib/components/screens/combat/components/effects/TraumaOverlay3D.js.map +1 -1
- package/lib/components/screens/combat/components/feedback/MatchCountdown.js.map +1 -1
- package/lib/components/screens/combat/components/feedback/RoundAnnouncementOverlayHtml.js.map +1 -1
- package/lib/components/screens/combat/components/feedback/RoundDisplayStatus.js.map +1 -1
- package/lib/components/screens/combat/components/feedback/RoundStartAnnouncementOverlayHtml.js.map +1 -1
- package/lib/components/screens/combat/components/hud/CombatBottomHUD.js.map +1 -1
- package/lib/components/screens/combat/components/hud/CombatLeftHUD.js.map +1 -1
- package/lib/components/screens/combat/components/hud/CombatPortraitStatusStrip.js.map +1 -1
- package/lib/components/screens/combat/components/hud/CombatRightHUD.js.map +1 -1
- package/lib/components/screens/combat/components/hud/CombatTopHUD.js.map +1 -1
- package/lib/components/screens/combat/components/hud/DifficultyIndicator.js.map +1 -1
- package/lib/components/screens/combat/components/hud/FPSMonitor.js.map +1 -1
- package/lib/components/screens/combat/components/hud/MobileControlsWrapper.js.map +1 -1
- package/lib/components/screens/combat/components/hud/PlayerStateOverlayHtml.js.map +1 -1
- package/lib/components/screens/combat/components/indicators/BalanceIndicator.js.map +1 -1
- package/lib/components/screens/combat/components/indicators/InputBufferDisplay.js.map +1 -1
- package/lib/components/screens/combat/components/indicators/StaminaWarning.js.map +1 -1
- package/lib/components/screens/combat/components/indicators/TechniqueNameDisplay.js.map +1 -1
- package/lib/components/screens/combat/helpers/AnimationUpdater.js.map +1 -1
- package/lib/components/screens/combat/helpers/combatHelpers.js.map +1 -1
- package/lib/components/screens/combat/hooks/useAICombat.js.map +1 -1
- package/lib/components/screens/combat/hooks/useCombatActions.js.map +1 -1
- package/lib/components/screens/combat/hooks/useCombatAttackMovement.js.map +1 -1
- package/lib/components/screens/combat/hooks/useCombatAudio.js.map +1 -1
- package/lib/components/screens/combat/hooks/useCombatLayout.js.map +1 -1
- package/lib/components/screens/combat/hooks/useCombatState.js.map +1 -1
- package/lib/components/screens/controls/ControlsScreen3D.js.map +1 -1
- package/lib/components/screens/controls/components/ControlBindingsOverlayHtml.js.map +1 -1
- package/lib/components/screens/controls/components/ControlCategoryTabsOverlayHtml.js.map +1 -1
- package/lib/components/screens/controls/components/GamepadVisualization3D.js.map +1 -1
- package/lib/components/screens/controls/components/InteractiveControlDemoOverlayHtml.js.map +1 -1
- package/lib/components/screens/controls/components/Key3D.js.map +1 -1
- package/lib/components/screens/controls/components/VisualKeyboard3D.js.map +1 -1
- package/lib/components/screens/controls/constants/ControlsConstants.js.map +1 -1
- package/lib/components/screens/controls/hooks/useControlsState.js.map +1 -1
- package/lib/components/screens/endscreen/EndScreen3D.js.map +1 -1
- package/lib/components/screens/endscreen/components/DefeatAnimation3D.js.map +1 -1
- package/lib/components/screens/endscreen/components/MatchStatisticsDisplayOverlayHtml.js.map +1 -1
- package/lib/components/screens/endscreen/components/NavigationButtonsOverlayHtml.js.map +1 -1
- package/lib/components/screens/endscreen/components/PerformanceBreakdownOverlayHtml.js.map +1 -1
- package/lib/components/screens/endscreen/components/PerformanceRatingOverlayHtml.js.map +1 -1
- package/lib/components/screens/endscreen/components/VictoryAnimation3D.js.map +1 -1
- package/lib/components/screens/endscreen/components/WinnerDisplayOverlayHtml.js.map +1 -1
- package/lib/components/screens/intro/IntroScreen3D.js +1 -1
- package/lib/components/screens/intro/IntroScreen3D.js.map +1 -1
- package/lib/components/screens/intro/components/AbilityListOverlayHtml.js.map +1 -1
- package/lib/components/screens/intro/components/ArchetypeCardGridOverlayHtml.js.map +1 -1
- package/lib/components/screens/intro/components/ArchetypeCardOverlayHtml.js.map +1 -1
- package/lib/components/screens/intro/components/ArchetypeDisplayOverlayHtml.js.map +1 -1
- package/lib/components/screens/intro/components/EnhancedArchetypeDisplayOverlayHtml.js.map +1 -1
- package/lib/components/screens/intro/components/MenuButtonsOverlayHtml.js.map +1 -1
- package/lib/components/screens/intro/components/MenuSectionOverlayHtml.js.map +1 -1
- package/lib/components/screens/intro/components/StatBarOverlayHtml.js.map +1 -1
- package/lib/components/screens/philosophy/PhilosophyScreen3D.js.map +1 -1
- package/lib/components/screens/training/TrainingScreen3D.js.map +1 -1
- package/lib/components/screens/training/components/AnatomyControlsOverlayHtml.js.map +1 -1
- package/lib/components/screens/training/components/AnatomyOverlay3D.js.map +1 -1
- package/lib/components/screens/training/components/FootPlacementMarkers3D.js.map +1 -1
- package/lib/components/screens/training/components/FootworkDrillsOverlayHtml.js.map +1 -1
- package/lib/components/screens/training/components/HitFeedbackEffect3D.js.map +1 -1
- package/lib/components/screens/training/components/TrainingButtonsOverlayHtml.js.map +1 -1
- package/lib/components/screens/training/components/TrainingControlsOverlayHtml.js.map +1 -1
- package/lib/components/screens/training/components/TrainingDummy3D.js.map +1 -1
- package/lib/components/screens/training/components/TrainingFeedbackOverlayHtml.js.map +1 -1
- package/lib/components/screens/training/components/TrainingModeSelectorOverlayHtml.js.map +1 -1
- package/lib/components/screens/training/components/TrainingStatsOverlayHtml.js.map +1 -1
- package/lib/components/screens/training/components/VitalPointMarker3D.js.map +1 -1
- package/lib/components/screens/training/components/VitalPointTrainingOverlayHtml.js.map +1 -1
- package/lib/components/screens/training/components/hud/TrainingBottomHUD.js.map +1 -1
- package/lib/components/screens/training/components/hud/TrainingLeftHUD.js.map +1 -1
- package/lib/components/screens/training/components/hud/TrainingRightHUD.js.map +1 -1
- package/lib/components/screens/training/components/hud/TrainingTopHUD.js.map +1 -1
- package/lib/components/screens/training/hooks/useAttackMovement.js.map +1 -1
- package/lib/components/screens/training/hooks/useTrainingActions.js.map +1 -1
- package/lib/components/screens/training/hooks/useTrainingLayout.js.map +1 -1
- package/lib/components/screens/training/hooks/useTrainingState.js.map +1 -1
- package/lib/components/shared/base/BaseButton.js.map +1 -1
- package/lib/components/shared/base/BaseButtonOverlayHtml.js.map +1 -1
- package/lib/components/shared/base/BasePanel.js.map +1 -1
- package/lib/components/shared/base/BaseText.js.map +1 -1
- package/lib/components/shared/base/useKoreanTheme.js.map +1 -1
- package/lib/components/shared/debug/PerformanceDebugOverlayHtml.js.map +1 -1
- package/lib/components/shared/mobile/ActionButtons.js.map +1 -1
- package/lib/components/shared/mobile/GestureRecognizerPure.js.map +1 -1
- package/lib/components/shared/mobile/HapticController.js.map +1 -1
- package/lib/components/shared/mobile/MobileControlsPure.js.map +1 -1
- package/lib/components/shared/mobile/StanceWheelPure.js.map +1 -1
- package/lib/components/shared/mobile/TouchOptimizer.js.map +1 -1
- package/lib/components/shared/mobile/VirtualDPad.js.map +1 -1
- package/lib/components/shared/three/anatomy/BodySurface.js.map +1 -1
- package/lib/components/shared/three/anatomy/BoneAttachedMuscles.js.map +1 -1
- package/lib/components/shared/three/anatomy/BoneClothing.js.map +1 -1
- package/lib/components/shared/three/anatomy/BoneRenderer.js.map +1 -1
- package/lib/components/shared/three/anatomy/Face3D.js.map +1 -1
- package/lib/components/shared/three/anatomy/Foot3D.js.map +1 -1
- package/lib/components/shared/three/anatomy/Hand3D.js.map +1 -1
- package/lib/components/shared/three/effects/ActionFeedback.js.map +1 -1
- package/lib/components/shared/three/effects/DamageNumbers.js.map +1 -1
- package/lib/components/shared/three/effects/HitEffects3D.js.map +1 -1
- package/lib/components/shared/three/effects/PlayerStateIndicators.js.map +1 -1
- package/lib/components/shared/three/effects/StanceSymbol3D.js.map +1 -1
- package/lib/components/shared/three/effects/StanceTransitionEffect.js.map +1 -1
- package/lib/components/shared/three/effects/VitalPointMarkers3D.js.map +1 -1
- package/lib/components/shared/three/indicators/ElementalColorSystem.js.map +1 -1
- package/lib/components/shared/three/indicators/GuardIndicator.js.map +1 -1
- package/lib/components/shared/three/indicators/HapticFeedback.js.map +1 -1
- package/lib/components/shared/three/indicators/StanceChangeIndicator.js.map +1 -1
- package/lib/components/shared/three/models/Player3DWithTransitions.js.map +1 -1
- package/lib/components/shared/three/models/SkeletalPlayer3D.js.map +1 -1
- package/lib/components/shared/three/optimization/AdaptiveQuality.js.map +1 -1
- package/lib/components/shared/three/scene/AtmosphericParticles3D.js.map +1 -1
- package/lib/components/shared/three/scene/BackgroundScene3D.js.map +1 -1
- package/lib/components/shared/three/scene/CombatArena3D.js.map +1 -1
- package/lib/components/shared/three/scene/KoreanSignage3D.js.map +1 -1
- package/lib/components/shared/three/ui/ArchetypeCard.js.map +1 -1
- package/lib/components/shared/three/ui/BodyPartHealthDisplay.js.map +1 -1
- package/lib/components/shared/three/ui/BreathingIndicator2.js.map +1 -1
- package/lib/components/shared/three/ui/CombatReadinessBar.js.map +1 -1
- package/lib/components/shared/three/ui/ComboCounter.js.map +1 -1
- package/lib/components/shared/three/ui/HealthBar.js.map +1 -1
- package/lib/components/shared/three/ui/KoreanButton.js.map +1 -1
- package/lib/components/shared/three/ui/KoreanPanel.js.map +1 -1
- package/lib/components/shared/three/ui/KoreanText.js.map +1 -1
- package/lib/components/shared/three/ui/MenuList.js.map +1 -1
- package/lib/components/shared/three/ui/PlayerHUD.js.map +1 -1
- package/lib/components/shared/three/ui/ProgressBar.js.map +1 -1
- package/lib/components/shared/three/ui/SpeedIndicatorHUD.js.map +1 -1
- package/lib/components/shared/three/ui/StaminaBar.js.map +1 -1
- package/lib/components/shared/three/ui/TechniqueBar.js.map +1 -1
- package/lib/components/shared/three/ui/TechniqueCard.js.map +1 -1
- package/lib/components/shared/three/ui/VitalPointOverlayControlsHtml.js.map +1 -1
- package/lib/components/shared/ui/BackButton.js.map +1 -1
- package/lib/components/shared/ui/BaseHUDContainer.js.map +1 -1
- package/lib/components/shared/ui/CombatTimer.js.map +1 -1
- package/lib/components/shared/ui/ErrorModal.js.map +1 -1
- package/lib/components/shared/ui/LoadingState.js.map +1 -1
- package/lib/components/shared/ui/SplashScreen.js +2 -2
- package/lib/components/shared/ui/SplashScreen.js.map +1 -1
- package/lib/components/shared/ui/VitalPointOverlayControlsPure.js.map +1 -1
- package/lib/components/shared/ui/VolumeControl.js.map +1 -1
- package/lib/components/shared/ui/shared/ConfirmDialog.js.map +1 -1
- package/lib/components/ui/combat/BalanceIndicatorOverlayHtml.js.map +1 -1
- package/lib/constants/bodyDimensions.js.map +1 -1
- package/lib/constants/bodyRenderingConstants.js.map +1 -1
- package/lib/data/archetypeClothing.js.map +1 -1
- package/lib/data/archetypePhysicalAttributes.js.map +1 -1
- package/lib/data/techniqueMappings.js.map +1 -1
- package/lib/data/techniques.js.map +1 -1
- package/lib/hooks/useActionFeedback.js.map +1 -1
- package/lib/hooks/useBalanceAnimations.js.map +1 -1
- package/lib/hooks/useCombatTimer.js.map +1 -1
- package/lib/hooks/useDebounce.js.map +1 -1
- package/lib/hooks/useHUDLayout.js.map +1 -1
- package/lib/hooks/useHandPoseTransitions.js.map +1 -1
- package/lib/hooks/useKeyboardControls.js.map +1 -1
- package/lib/hooks/useMatchCountdown.js.map +1 -1
- package/lib/hooks/useMuscleActivation.js.map +1 -1
- package/lib/hooks/usePauseMenu.js.map +1 -1
- package/lib/hooks/usePlayerAnimation.js.map +1 -1
- package/lib/hooks/useResponsiveLayout.js.map +1 -1
- package/lib/hooks/useRoundTransition.js.map +1 -1
- package/lib/hooks/useSkeletalAnimation.js.map +1 -1
- package/lib/hooks/useTechniqueSelection.js.map +1 -1
- package/lib/hooks/useThrottle.js.map +1 -1
- package/lib/hooks/useTouchControls.js.map +1 -1
- package/lib/hooks/useWebGLContextLossHandler.js.map +1 -1
- package/lib/hooks/useWindowSize.js.map +1 -1
- package/lib/systems/CombatSystem.js.map +1 -1
- package/lib/systems/EffectCalculator.js.map +1 -1
- package/lib/systems/LayoutSystem.js.map +1 -1
- package/lib/systems/PlayerEffectManager.js.map +1 -1
- package/lib/systems/ResponsiveScaling.js.map +1 -1
- package/lib/systems/TrigramSystem.js.map +1 -1
- package/lib/systems/VitalPointSystem.js.map +1 -1
- package/lib/systems/ai/AIPersonality.js.map +1 -1
- package/lib/systems/ai/AdaptiveDifficulty.js.map +1 -1
- package/lib/systems/ai/ArchetypeEnforcer.js.map +1 -1
- package/lib/systems/ai/ComboSystem.js.map +1 -1
- package/lib/systems/ai/DecisionTree.js.map +1 -1
- package/lib/systems/ai/TrainingAI.js.map +1 -1
- package/lib/systems/ai/types.js.map +1 -1
- package/lib/systems/animation/builders/AnimationBuilder.js.map +1 -1
- package/lib/systems/animation/builders/HandPoseApplicator.js.map +1 -1
- package/lib/systems/animation/builders/HandPoses.js.map +1 -1
- package/lib/systems/animation/builders/KeyframeConfig.js.map +1 -1
- package/lib/systems/animation/builders/KeyframeInterpolation.js +3 -90
- package/lib/systems/animation/builders/KeyframeInterpolation.js.map +1 -1
- package/lib/systems/animation/builders/KickPhaseApplicator.js.map +1 -1
- package/lib/systems/animation/builders/KoreanGuardPositions.js.map +1 -1
- package/lib/systems/animation/builders/MartialArtsAnimationBuilder.js.map +1 -1
- package/lib/systems/animation/builders/MartialArtsConstants.js.map +1 -1
- package/lib/systems/animation/builders/MartialPoseApplicator.js.map +1 -1
- package/lib/systems/animation/builders/PunchPhaseApplicator.js.map +1 -1
- package/lib/systems/animation/builders/SkeletonRig.js.map +1 -1
- package/lib/systems/animation/builders/TrigramGuardApplicator.js.map +1 -1
- package/lib/systems/animation/catalogs/DefensiveAnimations.js.map +1 -1
- package/lib/systems/animation/catalogs/FootworkSkeletalAnimations.js.map +1 -1
- package/lib/systems/animation/catalogs/RecoveryAnimations.js.map +1 -1
- package/lib/systems/animation/catalogs/StanceAnimations.js.map +1 -1
- package/lib/systems/animation/catalogs/StanceAttackAnimations.js.map +1 -1
- package/lib/systems/animation/catalogs/StanceGuardPoses.js.map +1 -1
- package/lib/systems/animation/catalogs/StanceIdleAnimations.js.map +1 -1
- package/lib/systems/animation/catalogs/StanceLocomotionAnimations.js.map +1 -1
- package/lib/systems/animation/catalogs/StepSkeletalAnimations.js.map +1 -1
- package/lib/systems/animation/core/AnimationHitTiming.js.map +1 -1
- package/lib/systems/animation/core/AnimationOptimizations.js.map +1 -1
- package/lib/systems/animation/core/AnimationPriority.js.map +1 -1
- package/lib/systems/animation/core/AnimationRegistry.js.map +1 -1
- package/lib/systems/animation/core/AnimationStateMachine.js.map +1 -1
- package/lib/systems/animation/core/AnimationTransitions.js.map +1 -1
- package/lib/systems/animation/core/LateralityTransform.js.map +1 -1
- package/lib/systems/animation/core/RecoveryPhaseEnhancer.js.map +1 -1
- package/lib/systems/animation/core/TechniqueAnimationMapper.js.map +1 -1
- package/lib/systems/animation/core/TechniqueAnimationMapping.js.map +1 -1
- package/lib/systems/animation/core/types.js.map +1 -1
- package/lib/systems/animation/systems/AdvancedJointMovements.js.map +1 -1
- package/lib/systems/animation/systems/BodyFacingSystem.js.map +1 -1
- package/lib/systems/animation/systems/FacialExpressions.js.map +1 -1
- package/lib/systems/animation/systems/FallAnimations.js.map +1 -1
- package/lib/systems/animation/systems/MuscleActivation.js.map +1 -1
- package/lib/systems/bodypart/BodyPartDamageIntegration.js.map +1 -1
- package/lib/systems/bodypart/BodyPartHealthSystem.js.map +1 -1
- package/lib/systems/bodypart/BodyPartPositionMapping.js.map +1 -1
- package/lib/systems/bodypart/CombatInjuryIntegration.js.map +1 -1
- package/lib/systems/bodypart/InjuryIntegration.js.map +1 -1
- package/lib/systems/bodypart/InjuryTracker.js.map +1 -1
- package/lib/systems/bodypart/MovementPenaltySystem.js.map +1 -1
- package/lib/systems/bodypart/PlayerInjuryTrackingManager.js.map +1 -1
- package/lib/systems/bodypart/types.js.map +1 -1
- package/lib/systems/breathing/BreathingDisruptionSystem.js.map +1 -1
- package/lib/systems/breathing/feedback.js.map +1 -1
- package/lib/systems/breathing/integration.js.map +1 -1
- package/lib/systems/combat/BalanceSystem.js.map +1 -1
- package/lib/systems/combat/BreakingStatusEffects.js.map +1 -1
- package/lib/systems/combat/CombatStateSystem.js.map +1 -1
- package/lib/systems/combat/ConsciousnessSystem.js.map +1 -1
- package/lib/systems/combat/FallIntegration.js.map +1 -1
- package/lib/systems/combat/GrappleSystem.js.map +1 -1
- package/lib/systems/combat/LimbExposureSystem.js.map +1 -1
- package/lib/systems/combat/PainResponseSystem.js.map +1 -1
- package/lib/systems/combat/TrainingCombatSystem.js.map +1 -1
- package/lib/systems/combat/painConsciousnessUtils.js.map +1 -1
- package/lib/systems/combat/typeGuards.js.map +1 -1
- package/lib/systems/effects.js.map +1 -1
- package/lib/systems/game.js.map +1 -1
- package/lib/systems/movement/InjuryMovementModifier.js.map +1 -1
- package/lib/systems/movement/helpers/AccelerationUpdater.js.map +1 -1
- package/lib/systems/movement/helpers/accelerationUtils.js.map +1 -1
- package/lib/systems/movement/integration.js.map +1 -1
- package/lib/systems/physics/AttackMovementPhysics.js.map +1 -1
- package/lib/systems/physics/CollisionDetection.js.map +1 -1
- package/lib/systems/physics/CoordinateMapper.js.map +1 -1
- package/lib/systems/physics/KnockbackPhysics.js.map +1 -1
- package/lib/systems/physics/MovementPhysics.js.map +1 -1
- package/lib/systems/physics/PhysicalReachCalculator.js.map +1 -1
- package/lib/systems/physics/SpeedModifierSystem.js.map +1 -1
- package/lib/systems/trigram/KoreanCulture.js.map +1 -1
- package/lib/systems/trigram/KoreanTechniques.js.map +1 -1
- package/lib/systems/trigram/StanceManager.js.map +1 -1
- package/lib/systems/trigram/TransitionCalculator.js.map +1 -1
- package/lib/systems/trigram/TrigramCalculator.js.map +1 -1
- package/lib/systems/trigram/techniques/DarkOpsTechniques.js.map +1 -1
- package/lib/systems/trigram/techniques/GamTechniques.js.map +1 -1
- package/lib/systems/trigram/techniques/GanTechniques.js.map +1 -1
- package/lib/systems/trigram/techniques/GonTechniques.js.map +1 -1
- package/lib/systems/trigram/techniques/SonTechniques.js.map +1 -1
- package/lib/systems/trigram/techniques/TechniqueConfig.js.map +1 -1
- package/lib/systems/trigram/techniques/index.js.map +1 -1
- package/lib/systems/trigram/types/GonTechniqueExtensions.js.map +1 -1
- package/lib/systems/trigram/types.js.map +1 -1
- package/lib/systems/types.js.map +1 -1
- package/lib/systems/vitalpoint/DamageCalculator.js.map +1 -1
- package/lib/systems/vitalpoint/HitDetection.js.map +1 -1
- package/lib/systems/vitalpoint/KoreanAnatomy.js.map +1 -1
- package/lib/systems/vitalpoint/KoreanVitalPoints.js.map +1 -1
- package/lib/systems/vitalpoint/MeridianVitalPointMapping.js.map +1 -1
- package/lib/types/AccessibilityTypes.js.map +1 -1
- package/lib/types/PhysicsTypes.js.map +1 -1
- package/lib/types/common.js.map +1 -1
- package/lib/types/constants/colors.js.map +1 -1
- package/lib/types/constants/designSystem.js.map +1 -1
- package/lib/types/constants/layout.js.map +1 -1
- package/lib/types/constants/performance.js.map +1 -1
- package/lib/types/constants/typography.js.map +1 -1
- package/lib/types/facial.js.map +1 -1
- package/lib/types/hand-animation.js.map +1 -1
- package/lib/types/injury.js.map +1 -1
- package/lib/types/physics.js.map +1 -1
- package/lib/types/skeletal.js.map +1 -1
- package/lib/types/techniqueId.js.map +1 -1
- package/lib/utils/accessibility.js.map +1 -1
- package/lib/utils/arenaWorldDimensions.js.map +1 -1
- package/lib/utils/assetConfig.js.map +1 -1
- package/lib/utils/characterScaling.js.map +1 -1
- package/lib/utils/colorHelpers.js.map +1 -1
- package/lib/utils/colorUtils.js.map +1 -1
- package/lib/utils/combatReadiness.js.map +1 -1
- package/lib/utils/controlMapping.js.map +1 -1
- package/lib/utils/deviceDetection.js.map +1 -1
- package/lib/utils/effectUtils.js.map +1 -1
- package/lib/utils/fabricTextures.js.map +1 -1
- package/lib/utils/hapticFeedback.js.map +1 -1
- package/lib/utils/haptics.js.map +1 -1
- package/lib/utils/htmlOverlayHelpers.js.map +1 -1
- package/lib/utils/inputSystem.js.map +1 -1
- package/lib/utils/koreanThemeHelpers.js.map +1 -1
- package/lib/utils/math.js.map +1 -1
- package/lib/utils/mobileLayoutHelpers.js.map +1 -1
- package/lib/utils/mobileUIUtils.js.map +1 -1
- package/lib/utils/performance/PerformanceMonitor.js.map +1 -1
- package/lib/utils/performance/PerformanceOverlay3D.js.map +1 -1
- package/lib/utils/performance/usePerformanceMonitor.js.map +1 -1
- package/lib/utils/performanceOptimization.js.map +1 -1
- package/lib/utils/player3DHelpers.js.map +1 -1
- package/lib/utils/playerUtils.js.map +1 -1
- package/lib/utils/responsiveLayout.js.map +1 -1
- package/lib/utils/responsiveLayoutHelpers.js.map +1 -1
- package/lib/utils/responsiveOrientationConstants.js.map +1 -1
- package/lib/utils/safeAreaUtils.js.map +1 -1
- package/lib/utils/sharedPhysicsConfig.js.map +1 -1
- package/lib/utils/skeletonScaling.js.map +1 -1
- package/lib/utils/stanceHelpers.js.map +1 -1
- package/lib/utils/threeObjectPool.js.map +1 -1
- package/lib/utils/visualEffects.js.map +1 -1
- package/package.json +5 -5
package/lib/systems/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../src/systems/types.ts"],"sourcesContent":["/**\n * Type definitions for systems types\n * Auto-generated by type migration script\n */\n\n// System imports from shared types - avoid circular dependencies\nimport { AudioSystemInterface, SoundEffectId } from \"@/audio\";\nimport type {\n EffectIntensity,\n EnvironmentalEffectType,\n HitEffectType,\n ParticleType,\n} from \"@/systems/effects\";\nimport { KOREAN_COLORS } from \"@/types\";\nimport {\n KoreanText,\n PlayerArchetype,\n Position,\n TrigramStance,\n} from \"@/types/common\";\n\nexport interface AnimationConfig {\n readonly name: string;\n readonly frames: readonly AnimationFrame[];\n readonly loop?: boolean;\n readonly speed?: number;\n}\n\nexport interface CombatSystemConfig {\n readonly damageMultiplier: number;\n readonly criticalChance: number;\n}\n\nexport interface TrigramSystemConfig {\n readonly transitionSpeed: number;\n readonly energyCost: number;\n}\n\nexport interface AISystemConfig {\n readonly difficulty: \"easy\" | \"medium\" | \"hard\" | \"expert\";\n readonly reactionTime: number;\n}\n\nexport interface VitalPointSystemConfig {\n readonly precisionRequired: number;\n readonly damageMultipliers: Record<string, number>;\n readonly effectDurations: Record<string, number>;\n}\n\n// Deprecated placeholder type - use unknown for generic texture representation\n\ntype Texture = unknown;\n\n// Vital point effect\n// Player archetype data\nexport interface PlayerArchetypeData {\n readonly id: string;\n readonly name: KoreanText;\n readonly description: KoreanText;\n readonly baseHealth: number;\n readonly baseKi: number;\n readonly baseStamina: number;\n readonly coreStance: TrigramStance;\n readonly theme: {\n primary: number;\n secondary: number;\n };\n readonly colors: {\n primary: number;\n secondary: number;\n };\n readonly stats: {\n attackPower: number;\n defense: number;\n speed: number;\n technique: number;\n };\n readonly favoredStances: readonly TrigramStance[];\n readonly specialAbilities: readonly string[];\n readonly philosophy: KoreanText;\n}\n\nexport interface AnimationState {\n readonly currentAnimationName?: string;\n readonly currentFrameIndex: number;\n readonly isPlaying: boolean;\n readonly elapsedTimeInFrame: number;\n}\n\nexport interface CollisionData {\n readonly entityA: EntityId;\n readonly entityB: EntityId;\n readonly normal: Velocity;\n readonly penetration: number;\n}\n\nexport interface PhysicsEntityConfig {\n readonly position: Position;\n readonly velocity?: Velocity;\n readonly mass?: number;\n readonly friction?: number;\n readonly restitution?: number;\n readonly shape:\n | { type: \"circle\"; radius: number }\n | { type: \"rectangle\"; width: number; height: number };\n readonly isStatic?: boolean;\n}\n\nexport interface PhysicsEntityState {\n readonly position: Position;\n readonly velocity: Velocity;\n readonly acceleration?: Velocity;\n readonly angularVelocity?: number;\n}\n\n// @deprecated Use Three.js rendering instead\nexport interface RenderableConfig {\n readonly zOrder?: number;\n readonly visible?: boolean;\n readonly alpha?: number;\n readonly parent?: EntityId | \"stage\";\n}\n\nexport interface StatusEffect {\n readonly id: string;\n readonly type: string;\n readonly intensity: EffectIntensity;\n readonly duration: number;\n readonly description: KoreanText;\n readonly stackable: boolean;\n readonly source: string;\n readonly startTime: number;\n readonly endTime: number;\n}\n\nexport interface HitEffect {\n readonly id: string;\n readonly type: HitEffectType;\n readonly attackerId: string;\n readonly defenderId: string;\n readonly timestamp: number;\n readonly duration: number;\n readonly position?: Position;\n readonly velocity?: { x: number; y: number };\n readonly color?: number;\n readonly size?: number;\n readonly alpha?: number;\n readonly lifespan?: number;\n readonly text?: string | KoreanText;\n readonly damageAmount?: number;\n readonly vitalPointId?: string;\n readonly statusEffect?: StatusEffect;\n readonly yOffset?: number;\n readonly intensity: number;\n readonly startTime: number;\n}\n\nexport interface ParticleEffect {\n readonly id: string;\n readonly type: ParticleType;\n readonly position: Position;\n readonly velocity: { x: number; y: number };\n readonly acceleration?: { x: number; y: number };\n readonly color: number;\n readonly size: number;\n readonly lifetime: number;\n readonly fadeOut?: boolean;\n readonly gravity?: number;\n}\n\nexport interface EnvironmentalEffect {\n readonly id: string;\n readonly type: EnvironmentalEffectType;\n readonly affectedArea: {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n };\n readonly effects: {\n readonly visibilityModifier?: number;\n readonly accuracyModifier?: number;\n readonly movementModifier?: number;\n readonly damageModifier?: number;\n };\n readonly duration: number;\n}\n\nexport interface VisualEffect {\n readonly id: string;\n readonly type: string;\n readonly duration: number;\n readonly intensity: number;\n readonly position?: Position;\n readonly color?: number;\n}\n\nexport interface EffectSystem {\n readonly effects: readonly VisualEffect[];\n readonly addEffect: (effect: VisualEffect) => void;\n readonly removeEffect: (id: string) => void;\n readonly updateEffects: (deltaTime: number) => void;\n}\n\nexport interface DisplayHitEffect extends HitEffect {\n readonly opacity: number;\n readonly scale: number;\n readonly startTime: number;\n readonly displayAlpha: number;\n readonly displayY: number;\n readonly displaySize: number;\n}\n\nexport interface InputSystemInterface {\n registerAction: (action: string, callback: () => void) => void;\n unregisterAction: (action: string) => void;\n clearActions: () => void;\n isActionActive: (action: string) => boolean;\n}\n\nexport interface AnimationSystemInterface {\n playAnimation: (entityId: EntityId, animationName: string) => void;\n stopAnimation: (entityId: EntityId, animationName?: string) => void;\n getCurrentFrame: (entityId: EntityId) => AnimationFrame | undefined;\n addAnimation: (config: AnimationConfig) => void;\n getAnimationState: (entityId: EntityId) => AnimationState | undefined;\n}\n\nexport interface PhysicsSystemInterface {\n addEntity: (entityId: EntityId, config: PhysicsEntityConfig) => void;\n removeEntity: (entityId: EntityId) => void;\n update: (deltaTime: number) => void;\n getEntityState: (entityId: EntityId) => PhysicsEntityState | undefined;\n checkCollision: (\n entityIdA: EntityId,\n entityIdB: EntityId,\n ) => CollisionData | null;\n applyForce: (entityId: EntityId, force: Velocity) => void;\n}\n\n// @deprecated Use Three.js rendering instead\nexport interface RenderingSystemInterface {\n addRenderable: (entityId: EntityId, config: RenderableConfig) => void;\n removeRenderable: (entityId: EntityId) => void;\n updateRenderable: (\n entityId: EntityId,\n updates: Partial<RenderableConfig>,\n ) => void;\n render: () => void;\n}\n\nexport interface SystemEvent {\n readonly type: string;\n readonly timestamp: number;\n readonly source: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Event data varies by event type\n readonly data: Record<string, any>;\n}\n\nexport interface EventBusInterface {\n publish: (event: SystemEvent) => void;\n subscribe: (\n eventType: string,\n callback: (event: SystemEvent) => void,\n ) => void;\n unsubscribe: (\n eventType: string,\n callback: (event: SystemEvent) => void,\n ) => void;\n}\n\n// Define system interfaces without importing (to avoid circular deps)\n// These interfaces use `any` to avoid circular dependency issues between\n// systems (combat, vital point, trigram) that reference each other's types.\n// Proper typing would require extracting shared types to a separate module.\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport interface CombatSystemInterface {\n calculateDamage: (\n technique: any,\n attacker: any,\n defender: any,\n hitResult: any,\n ) => {\n baseDamage: number;\n modifierDamage: number;\n totalDamage: number;\n effectsApplied: readonly StatusEffect[];\n finalDefenderState?: any;\n };\n resolveAttack: (\n attacker: any,\n defender: any,\n technique: any,\n targetedVitalPointId?: string,\n ) => any;\n applyCombatResult: (\n result: any,\n attacker: any,\n defender: any,\n ) => { updatedAttacker: any; updatedDefender: any };\n getAvailableTechniques: (player: any) => readonly any[];\n}\n\nexport interface VitalPointSystemInterface {\n processHit: (\n targetPosition: Position,\n technique: any,\n baseDamage: number,\n attackerArchetype: any,\n targetDimensions: { width: number; height: number },\n targetedVitalPointId?: string | null,\n ) => any;\n calculateHit: (\n technique: any,\n targetVitalPointId: string | null,\n accuracyRoll: number,\n attackerPosition: Position,\n defenderPosition: Position,\n defenderStance: any,\n ) => any;\n applyVitalPointEffects: (\n player: any,\n vitalPoint: any,\n intensityMultiplier?: number,\n ) => any;\n}\n\nexport interface TrigramSystemInterface {\n getTechniqueForStance: (stance: any, archetype?: any) => any | undefined;\n calculateStanceEffectiveness: (\n attackerStance: any,\n defenderStance: any,\n technique?: any,\n ) => number;\n isValidTransition: (from: any, to: any) => boolean;\n getTransitionCost: (\n from: any,\n to: any,\n player?: any,\n ) => { ki: number; stamina: number; timeMs: number };\n recommendStance: (player: any, opponent?: any) => any;\n}\n\nexport interface GameSystemManager {\n readonly combatSystem: CombatSystemInterface;\n readonly vitalPointSystem: VitalPointSystemInterface;\n readonly trigramSystem: TrigramSystemInterface;\n readonly inputSystem: InputSystemInterface;\n readonly audioSystem: AudioSystemInterface;\n readonly animationSystem?: AnimationSystemInterface;\n /* eslint-enable @typescript-eslint/no-explicit-any */\n readonly physicsSystem?: PhysicsSystemInterface;\n readonly renderingSystem?: RenderingSystemInterface;\n readonly eventBus: EventBusInterface;\n initializeAll: () => Promise<void>;\n updateAll: (deltaTime: number) => void;\n}\n\nexport interface SystemConfig {\n readonly debugMode?: boolean;\n readonly performanceMonitoring?: boolean;\n}\n\nexport interface GameSystemState {\n readonly combat: CombatSystemConfig;\n readonly trigram: TrigramSystemConfig;\n readonly vitalPoint: VitalPointSystemConfig;\n readonly ai: AISystemConfig;\n}\n\nexport interface SystemPerformance {\n readonly fps: number;\n readonly memoryUsage: number;\n readonly renderTime: number;\n readonly updateTime: number;\n}\n\n// Fix: Add missing type definitions\nexport type Timestamp = number;\nexport type EntityId = string;\nexport interface Velocity {\n readonly x: number;\n readonly y: number;\n}\n\n// Configuration for the VitalPointSystem\n// Result from VitalPointSystem's hit calculation - unified with anatomy.ts version\n// Combat system interface\n// Vital point system interface\n// Trigram system interface\n// Input system interface\n// Gamepad state\nexport interface GamepadState {\n readonly id: string;\n readonly axes: readonly number[];\n readonly buttons: readonly { pressed: boolean; value: number }[];\n}\n\n// Three.js uses built-in animation systems\n// @deprecated Use Three.js animation system instead\nexport interface AnimationFrame {\n readonly texture: Texture;\n readonly duration: number;\n}\n\n// @deprecated Use Three.js animation system instead\nexport interface AnimationState {\n readonly currentAnimationName?: string;\n readonly currentFrameIndex: number;\n readonly isPlaying: boolean;\n readonly elapsedTimeInFrame: number;\n}\n\n// Physics system interface\n// Physics entity configuration\nexport interface PhysicsEntityConfig {\n readonly position: Position;\n readonly velocity?: Velocity;\n readonly mass?: number;\n readonly friction?: number;\n readonly restitution?: number; // Bounciness\n readonly shape:\n | { type: \"circle\"; radius: number }\n | { type: \"rectangle\"; width: number; height: number };\n readonly isStatic?: boolean; // Cannot be moved by forces // Added\n}\n\n// Added PhysicsEntityState and CollisionData for PhysicsSystemInterface\nexport interface PhysicsEntityState {\n readonly position: Position;\n readonly velocity: Velocity;\n readonly acceleration?: Velocity;\n readonly angularVelocity?: number;\n}\n\nexport interface CollisionData {\n readonly entityA: EntityId;\n readonly entityB: EntityId;\n readonly normal: Velocity; // Collision normal vector\n readonly penetration: number; // How much they are overlapping\n}\n\n// Rendering system interface (deprecated - use Three.js rendering)\n\n// Game system manager\n// System event base type\n// Event bus interface for system communication\n// General system configuration\n// System-specific types for Korean martial arts combat\n\n// Combat system interfaces\nexport interface CombatSystemConfig {\n readonly damageMultiplier: number;\n readonly criticalChance: number;\n readonly blockEffectiveness: number;\n readonly staminaDrainRate: number;\n}\n\n// Trigram system interfaces\nexport interface TrigramSystemConfig {\n readonly transitionSpeed: number;\n readonly energyCost: number;\n readonly effectivenessMatrix: Record<\n TrigramStance,\n Record<TrigramStance, number>\n >;\n}\n\n// Vital point system interfaces\n// AI system interfaces\nexport interface AISystemConfig {\n readonly difficulty: \"easy\" | \"medium\" | \"hard\" | \"expert\";\n readonly reactionTime: number;\n readonly aggressiveness: number;\n readonly adaptability: number;\n}\n\n// Player archetype data\nexport const PLAYER_ARCHETYPES_DATA: Record<\n PlayerArchetype,\n PlayerArchetypeData\n> = {\n [PlayerArchetype.MUSA]: {\n id: \"musa\",\n name: { korean: \"무사 (Musa)\", english: \"Traditional Warrior\" },\n description: {\n korean: \"전통 무사의 길\",\n english: \"Path of the traditional warrior\",\n },\n baseHealth: 120,\n baseKi: 100,\n baseStamina: 110,\n coreStance: TrigramStance.GEON,\n theme: {\n primary: KOREAN_COLORS.TRIGRAM_GEON_PRIMARY,\n secondary: KOREAN_COLORS.KOREAN_RED,\n },\n colors: {\n primary: KOREAN_COLORS.TRIGRAM_GEON_PRIMARY,\n secondary: KOREAN_COLORS.KOREAN_RED,\n },\n stats: {\n attackPower: 85,\n defense: 90,\n speed: 70,\n technique: 80,\n },\n favoredStances: [TrigramStance.GEON, TrigramStance.GAN],\n specialAbilities: [\"Honor Strike\", \"Defensive Mastery\"],\n philosophy: {\n korean: \"명예와 정의의 길\",\n english: \"The way of honor and justice\",\n },\n },\n\n [PlayerArchetype.AMSALJA]: {\n id: \"amsalja\",\n name: { korean: \"암살자 (Amsalja)\", english: \"Shadow Assassin\" },\n description: {\n korean: \"그림자 속의 효율성\",\n english: \"Efficiency from the shadows\",\n },\n baseHealth: 80,\n baseKi: 120,\n baseStamina: 100,\n coreStance: TrigramStance.SON,\n theme: {\n primary: KOREAN_COLORS.TRIGRAM_SON_PRIMARY,\n secondary: KOREAN_COLORS.UI_BACKGROUND_DARK,\n },\n colors: {\n primary: KOREAN_COLORS.TRIGRAM_SON_PRIMARY,\n secondary: KOREAN_COLORS.UI_BACKGROUND_DARK,\n },\n stats: {\n attackPower: 95,\n defense: 60,\n speed: 95,\n technique: 90,\n },\n favoredStances: [TrigramStance.SON, TrigramStance.GAM],\n specialAbilities: [\"Shadow Strike\", \"Vital Point Mastery\"],\n philosophy: {\n korean: \"침묵과 정확성의 도\",\n english: \"The way of silence and precision\",\n },\n },\n\n [PlayerArchetype.HACKER]: {\n id: \"hacker\",\n name: { korean: \"해커 (Hacker)\", english: \"Cyber Warrior\" },\n description: {\n korean: \"정보를 통한 힘\",\n english: \"Power through information\",\n },\n baseHealth: 90,\n baseKi: 130,\n baseStamina: 80,\n coreStance: TrigramStance.LI,\n theme: {\n primary: KOREAN_COLORS.PRIMARY_CYAN,\n secondary: KOREAN_COLORS.TRIGRAM_LI_PRIMARY,\n },\n colors: {\n primary: KOREAN_COLORS.PRIMARY_CYAN,\n secondary: KOREAN_COLORS.TRIGRAM_LI_PRIMARY,\n },\n stats: {\n attackPower: 75,\n defense: 70,\n speed: 85,\n technique: 95,\n },\n favoredStances: [TrigramStance.LI, TrigramStance.JIN],\n specialAbilities: [\"System Override\", \"Digital Precision\"],\n philosophy: {\n korean: \"지식과 기술의 융합\",\n english: \"The fusion of knowledge and technology\",\n },\n },\n\n [PlayerArchetype.JEONGBO_YOWON]: {\n id: \"jeongbo_yowon\",\n name: {\n korean: \"정보요원 (Jeongbo Yowon)\",\n english: \"Intelligence Operative\",\n },\n description: {\n korean: \"관찰을 통한 지식\",\n english: \"Knowledge through observation\",\n },\n baseHealth: 100,\n baseKi: 110,\n baseStamina: 100,\n coreStance: TrigramStance.TAE,\n theme: {\n primary: KOREAN_COLORS.TRIGRAM_TAE_PRIMARY,\n secondary: KOREAN_COLORS.UI_STEEL_GRAY,\n },\n colors: {\n primary: KOREAN_COLORS.TRIGRAM_TAE_PRIMARY,\n secondary: KOREAN_COLORS.UI_STEEL_GRAY,\n },\n stats: {\n attackPower: 80,\n defense: 85,\n speed: 80,\n technique: 85,\n },\n favoredStances: [TrigramStance.TAE, TrigramStance.GAN],\n specialAbilities: [\"Intel Gathering\", \"Adaptive Combat\"],\n philosophy: {\n korean: \"적응과 전략의 예술\",\n english: \"The art of adaptation and strategy\",\n },\n },\n\n [PlayerArchetype.JOJIK_POKRYEOKBAE]: {\n id: \"jojik_pokryeokbae\",\n name: {\n korean: \"조직폭력배 (Jojik Pokryeokbae)\",\n english: \"Organized Crime\",\n },\n description: {\n korean: \"무자비함을 통한 생존\",\n english: \"Survival through ruthlessness\",\n },\n baseHealth: 110,\n baseKi: 90,\n baseStamina: 120,\n coreStance: TrigramStance.JIN,\n theme: {\n primary: KOREAN_COLORS.TRIGRAM_JIN_PRIMARY,\n secondary: KOREAN_COLORS.NEGATIVE_RED,\n },\n colors: {\n primary: KOREAN_COLORS.TRIGRAM_JIN_PRIMARY,\n secondary: KOREAN_COLORS.NEGATIVE_RED,\n },\n stats: {\n attackPower: 90,\n defense: 75,\n speed: 75,\n technique: 70,\n },\n favoredStances: [TrigramStance.JIN, TrigramStance.GON],\n specialAbilities: [\"Brutal Force\", \"Street Fighting\"],\n philosophy: {\n korean: \"강함과 의지의 길\",\n english: \"The way of strength and will\",\n },\n },\n} as const;\n\n// Base player stats\nexport const BASE_PLAYER_STATS = {\n HEALTH: 100,\n KI: 100,\n STAMINA: 100,\n ATTACK_POWER: 75,\n DEFENSE: 75,\n SPEED: 75,\n TECHNIQUE: 75,\n} as const;\n\n// Combat configuration\nexport const COMBAT_CONFIG = {\n MAX_HEALTH: 100,\n MAX_KI: 100,\n MAX_STAMINA: 100,\n MAX_BALANCE: 100,\n MAX_CONSCIOUSNESS: 100,\n\n // Damage multipliers - vital points more impactful for Korean martial arts realism\n CRITICAL_HIT_MULTIPLIER: 2.0,\n VITAL_POINT_MULTIPLIER: 2.5, // Increased from 1.5 for more realistic vital point impact\n COUNTER_ATTACK_MULTIPLIER: 1.3,\n\n // Status thresholds\n LOW_HEALTH_THRESHOLD: 25,\n CRITICAL_HEALTH_THRESHOLD: 10,\n UNCONSCIOUS_THRESHOLD: 0,\n STAMINA_EXHAUSTED_THRESHOLD: 0,\n\n // Recovery rates (per second) - increased for 3-minute round sustainability\n STAMINA_RECOVERY_RATE: 15, // Increased from 10 for sustained combat\n KI_RECOVERY_RATE: 8, // Increased from 5 for more technique usage\n BALANCE_RECOVERY_RATE: 15,\n CONSCIOUSNESS_RECOVERY_RATE: 2,\n\n // Combat timing (milliseconds)\n TECHNIQUE_COOLDOWN: 500,\n STANCE_CHANGE_COOLDOWN: 200,\n BLOCK_DURATION: 300,\n RECOVERY_TIME: 400,\n} as const;\n\n// Enhanced damage calculation constants\nexport const ENHANCED_DAMAGE_CONSTANTS = {\n BASE_DAMAGE: 10,\n CRITICAL_MULTIPLIER: 2.0,\n VITAL_POINT_MULTIPLIER: 2.5, // Increased from 1.5 for Korean martial arts vital point realism\n ARMOR_REDUCTION: 0.1,\n STANCE_DEFENSE_BONUS: 0.2,\n BALANCE_IMPACT_MULTIPLIER: 0.3,\n CONSCIOUSNESS_THRESHOLD: 30,\n PAIN_THRESHOLD: 80,\n\n // New damage factors\n TECHNIQUE_POWER_MODIFIER: 0.2,\n ARCHETYPE_BONUS: 0.15,\n COMBO_MULTIPLIER: 1.2,\n PERFECT_TIMING_BONUS: 0.3,\n BASE_CRIT_CHANCE: 0.1, // Added: Base critical hit chance (e.g., 10%)\n} as const;\n\n// Combat system constants for Korean martial arts\n\nexport const COMBAT_CONSTANTS = {\n // Damage calculation\n BASE_DAMAGE: 10,\n CRITICAL_MULTIPLIER: 2.0,\n VITAL_POINT_MULTIPLIER: 2.5, // Increased from 1.5 for Korean martial arts vital point realism\n\n // Status thresholds\n LOW_HEALTH_THRESHOLD: 30,\n CRITICAL_HEALTH_THRESHOLD: 15,\n EXHAUSTED_STAMINA_THRESHOLD: 20,\n\n // Recovery rates (per second) - increased for 3-minute round sustainability\n STAMINA_RECOVERY_RATE: 15, // Increased from 5 for sustained combat\n KI_RECOVERY_RATE: 8, // Increased from 3 for more technique usage\n CONSCIOUSNESS_RECOVERY_RATE: 2,\n\n // Combat timing\n ATTACK_COOLDOWN: 500, // milliseconds\n STANCE_CHANGE_COOLDOWN: 300,\n BLOCK_WINDOW: 200,\n\n // Balance and momentum\n BALANCE_RECOVERY_RATE: 10,\n MOMENTUM_DECAY_RATE: 5,\n\n // Pain and status effects\n PAIN_DECAY_RATE: 3,\n STATUS_EFFECT_DURATION: 3000,\n} as const;\n\n// Combat controls mapping - Enhanced with realistic combat focus\nexport const COMBAT_CONTROLS = {\n // Trigram stance system (1-8 keys) with authentic Korean martial arts techniques\n stanceControls: {\n \"1\": {\n stance: \"geon\" as TrigramStance,\n korean: \"건\",\n english: \"Heaven\",\n symbol: \"☰\",\n technique: {\n korean: \"천둥벽력\",\n english: \"Thunder Strike\",\n },\n combatFocus: {\n korean: \"골격타격\",\n english: \"Bone-striking force\",\n },\n combatEffects: {\n korean: \"골절, 구조적 손상\",\n english: \"Fractures, structural damage\",\n },\n description: {\n korean: \"하늘의 힘으로 적의 뼈를 부수는 강력한 타격\",\n english:\n \"Powerful strikes that shatter enemy bones with heaven's force\",\n },\n },\n \"2\": {\n stance: \"tae\" as TrigramStance,\n korean: \"태\",\n english: \"Lake\",\n symbol: \"☱\",\n technique: {\n korean: \"유수연타\",\n english: \"Flowing Strike\",\n },\n combatFocus: {\n korean: \"관절조작\",\n english: \"Joint manipulation\",\n },\n combatEffects: {\n korean: \"탈구, 이동력 상실\",\n english: \"Dislocations, mobility loss\",\n },\n description: {\n korean: \"호수처럼 부드럽게 흘러 관절을 조작하는 기법\",\n english: \"Techniques that flow like water to manipulate joints\",\n },\n },\n \"3\": {\n stance: \"li\" as TrigramStance,\n korean: \"리\",\n english: \"Fire\",\n symbol: \"☲\",\n technique: {\n korean: \"화염지창\",\n english: \"Fire Spear\",\n },\n combatFocus: {\n korean: \"정밀신경타격\",\n english: \"Precise nerve strikes\",\n },\n combatEffects: {\n korean: \"일시마비, 감각상실\",\n english: \"Temporary paralysis, numbness\",\n },\n description: {\n korean: \"불꽃같은 정확성으로 신경계를 공격하는 치명적 기법\",\n english:\n \"Deadly techniques targeting the nervous system with fire-like precision\",\n },\n },\n \"4\": {\n stance: \"jin\" as TrigramStance,\n korean: \"진\",\n english: \"Thunder\",\n symbol: \"☳\",\n technique: {\n korean: \"벽력일섬\",\n english: \"Lightning Strike\",\n },\n combatFocus: {\n korean: \"기절기법\",\n english: \"Stunning techniques\",\n },\n combatEffects: {\n korean: \"방향감각상실, 의식잃음\",\n english: \"Disorientation, knockouts\",\n },\n description: {\n korean: \"번개처럼 빠른 충격으로 적의 의식을 차단\",\n english: \"Lightning-fast shocks that disrupt enemy consciousness\",\n },\n },\n \"5\": {\n stance: \"son\" as TrigramStance,\n korean: \"손\",\n english: \"Wind\",\n symbol: \"☴\",\n technique: {\n korean: \"선풍연격\",\n english: \"Whirlwind Combo\",\n },\n combatFocus: {\n korean: \"지속압박\",\n english: \"Continuous pressure\",\n },\n combatEffects: {\n korean: \"점진적 무력화\",\n english: \"Gradual incapacitation\",\n },\n description: {\n korean: \"바람처럼 끊임없는 연타로 적을 서서히 무력화\",\n english:\n \"Relentless wind-like strikes that gradually overwhelm the enemy\",\n },\n },\n \"6\": {\n stance: \"gam\" as TrigramStance,\n korean: \"감\",\n english: \"Water\",\n symbol: \"☵\",\n technique: {\n korean: \"수류반격\",\n english: \"Water Counter\",\n },\n combatFocus: {\n korean: \"혈류차단\",\n english: \"Blood flow restriction\",\n },\n combatEffects: {\n korean: \"순환장애\",\n english: \"Circulation disruption\",\n },\n description: {\n korean: \"물의 흐름을 끊듯 혈액순환을 차단하는 위험한 기법\",\n english:\n \"Dangerous techniques that disrupt blood circulation like stopping water flow\",\n },\n },\n \"7\": {\n stance: \"gan\" as TrigramStance,\n korean: \"간\",\n english: \"Mountain\",\n symbol: \"☶\",\n technique: {\n korean: \"반석방어\",\n english: \"Mountain Defense\",\n },\n combatFocus: {\n korean: \"방어반격\",\n english: \"Defensive counters\",\n },\n combatEffects: {\n korean: \"반격, 차단\",\n english: \"Counter-attacks, blocks\",\n },\n description: {\n korean: \"산처럼 견고한 방어에서 나오는 강력한 반격\",\n english: \"Powerful counters emerging from mountain-solid defense\",\n },\n },\n \"8\": {\n stance: \"gon\" as TrigramStance,\n korean: \"곤\",\n english: \"Earth\",\n symbol: \"☷\",\n technique: {\n korean: \"대지포옹\",\n english: \"Earth's Embrace\",\n },\n combatFocus: {\n korean: \"지면기법\",\n english: \"Ground techniques\",\n },\n combatEffects: {\n korean: \"투척, 넘어뜨리기\",\n english: \"Throws, takedowns\",\n },\n description: {\n korean: \"대지의 힘으로 적을 땅에 내동댕이치는 투척술\",\n english:\n \"Throwing techniques that slam enemies to the ground with earth's power\",\n },\n },\n },\n\n // Movement controls with combat context\n movement: {\n WASD: {\n korean: \"전술적 이동과 발놀림\",\n english: \"Tactical positioning and footwork\",\n },\n ArrowKeys: {\n korean: \"대체 이동 시스템\",\n english: \"Alternative movement system\",\n },\n },\n\n // Combat actions with realistic descriptions\n combat: {\n SPACE: {\n korean: \"현재 자세의 기법 실행\",\n english: \"Execute current stance technique\",\n },\n SHIFT: {\n korean: \"방어 자세/차단 위치\",\n english: \"Defensive guard/block position\",\n },\n CTRL: {\n korean: \"정밀 급소 타격 모드\",\n english: \"Precision vital point targeting mode\",\n },\n TAB: {\n korean: \"무술 원형 순환\",\n english: \"Cycle through martial archetypes\",\n },\n },\n\n // System controls\n system: {\n ESC: {\n korean: \"일시정지 메뉴 / 인트로로 돌아가기\",\n english: \"Pause menu / Return to intro\",\n },\n F1: {\n korean: \"도움말 / 조작법 가이드\",\n english: \"Help / Controls guide\",\n },\n M: {\n korean: \"음소거 / 오디오 설정\",\n english: \"Mute / Audio settings\",\n },\n },\n} as const;\n\n// Damage types\nexport const DAMAGE_TYPES = {\n PHYSICAL: \"physical\",\n ENERGY: \"energy\",\n VITAL_POINT: \"vital_point\",\n PSYCHOLOGICAL: \"psychological\",\n} as const;\n\n// Combat phases\nexport const COMBAT_PHASES = {\n PREPARATION: \"preparation\",\n ENGAGEMENT: \"engagement\",\n EXECUTION: \"execution\",\n RECOVERY: \"recovery\",\n RESOLUTION: \"resolution\",\n} as const;\n\n// Combat audio mapping\nexport const COMBAT_AUDIO_MAP: Record<string, SoundEffectId> = {\n light_attack: \"attack_light\",\n medium_attack: \"attack_medium\",\n heavy_attack: \"attack_heavy\",\n critical_attack: \"attack_critical\",\n\n light_hit: \"hit_light\",\n medium_hit: \"hit_medium\",\n heavy_hit: \"hit_heavy\",\n critical_hit: \"critical_hit\",\n\n block: \"block_success\",\n guard_break: \"block_break\",\n miss: \"miss\",\n\n stance_change: \"stance_change\",\n technique: \"technique_execute\",\n\n match_start: \"match_start\",\n combat_end: \"combat_end\",\n victory: \"victory\",\n defeat: \"defeat\",\n\n guard: \"guard\",\n} as const;\n\n// Combat state transitions\nexport const COMBAT_STATE_MACHINE = {\n idle: {\n canTransitionTo: [\"attacking\", \"defending\", \"moving\", \"stunned\"],\n duration: Infinity,\n },\n attacking: {\n canTransitionTo: [\"idle\", \"recovering\", \"stunned\"],\n duration: 500,\n },\n defending: {\n canTransitionTo: [\"idle\", \"attacking\", \"stunned\"],\n duration: 300,\n },\n moving: {\n canTransitionTo: [\"idle\", \"attacking\", \"defending\"],\n duration: 200,\n },\n stunned: {\n canTransitionTo: [\"idle\"],\n duration: 1000,\n },\n recovering: {\n canTransitionTo: [\"idle\"],\n duration: 400,\n },\n unconscious: {\n canTransitionTo: [\"idle\"],\n duration: 5000,\n },\n} as const;\n\n// Training-specific combat constants\nexport const TRAINING_COMBAT_SETTINGS = {\n techniqueCooldown: 500,\n perfectStrikeThreshold: 0.7,\n maxTrainingSession: 300000, // 5 minutes\n kiRegenerationRate: 2,\n staminaRegenerationRate: 1.5,\n} as const;\n\n// Combat state transitions for training mode\nexport const TRAINING_STATE_MACHINE = {\n practicing: {\n canTransitionTo: [\"idle\", \"executing\", \"recovering\"],\n duration: Infinity,\n },\n executing: {\n canTransitionTo: [\"practicing\", \"idle\"],\n duration: 800,\n },\n recovering: {\n canTransitionTo: [\"practicing\", \"idle\"],\n duration: 300,\n },\n} as const;\n\n// Technique execution results\nexport const TECHNIQUE_RESULTS = {\n SUCCESS: \"success\",\n BLOCKED: \"blocked\",\n MISSED: \"missed\",\n COUNTERED: \"countered\",\n INTERRUPTED: \"interrupted\",\n} as const;\n\n// Combat effectiveness modifiers\nexport const EFFECTIVENESS_MODIFIERS = {\n stance_advantage: 1.2,\n stance_disadvantage: 0.8,\n counter_attack: 1.5,\n perfect_timing: 1.3,\n off_balance: 0.7,\n fatigued: 0.6,\n focused: 1.1,\n} as const;\n\n// Combat resource costs\nexport const RESOURCE_COSTS = {\n KI: {\n BASIC_TECHNIQUE: 5,\n ADVANCED_TECHNIQUE: 10,\n SPECIAL_TECHNIQUE: 15,\n ULTIMATE_TECHNIQUE: 25,\n },\n STAMINA: {\n BASIC_ATTACK: 8,\n HEAVY_ATTACK: 15,\n BLOCK: 5,\n DODGE: 10,\n STANCE_CHANGE: 12,\n },\n} as const;\n\n// Hit detection constants\nexport const HIT_DETECTION = {\n PRECISION_THRESHOLD: 0.8,\n VITAL_POINT_THRESHOLD: 0.9,\n BASE_ACCURACY: 0.7,\n MAX_ACCURACY: 0.95,\n\n // Hit boxes\n PLAYER_HITBOX_WIDTH: 60,\n PLAYER_HITBOX_HEIGHT: 180,\n VITAL_POINT_RADIUS: 15,\n} as const;\n\n// Status effect durations\nexport const STATUS_DURATIONS = {\n STUN: 1500,\n POISON: 5000,\n BURN: 3000,\n BLEED: 4000,\n WEAKNESS: 6000,\n STRENGTH_BUFF: 8000,\n} as const;\n\nexport interface CombatControlsConfig {\n readonly stanceControls: Record<\n string,\n { stance: string; korean: string; technique: string }\n >;\n readonly movement: Record<string, string>;\n readonly combat: Record<string, string>;\n readonly system: Record<string, string>;\n}\n\n// Key mapping for easier lookup\nexport const KEYBOARD_MAPPING = {\n // Stance keys\n STANCE_1: \"1\",\n STANCE_2: \"2\",\n STANCE_3: \"3\",\n STANCE_4: \"4\",\n STANCE_5: \"5\",\n STANCE_6: \"6\",\n STANCE_7: \"7\",\n STANCE_8: \"8\",\n\n // Combat actions\n EXECUTE_TECHNIQUE: \" \", // Space\n BLOCK: \"Shift\",\n TARGET_MODE: \"Control\",\n ARCHETYPE_CYCLE: \"Tab\",\n\n // Movement\n MOVE_UP: \"w\",\n MOVE_DOWN: \"s\",\n MOVE_LEFT: \"a\",\n MOVE_RIGHT: \"d\",\n\n // System\n PAUSE: \"Escape\",\n HELP: \"F1\",\n MUTE: \"m\",\n} as const;\n\n/**\n * Get the stance associated with a given key.\n *\n * @param key - The key to lookup.\n * @returns The corresponding stance, or null if not found.\n */\nexport function getStanceFromKey(key: string): TrigramStance | null {\n const stanceMap: Record<string, TrigramStance> = {\n \"1\": TrigramStance.GEON,\n \"2\": TrigramStance.TAE,\n \"3\": TrigramStance.LI,\n \"4\": TrigramStance.JIN,\n \"5\": TrigramStance.SON,\n \"6\": TrigramStance.GAM,\n \"7\": TrigramStance.GAN,\n \"8\": TrigramStance.GON,\n };\n return stanceMap[key] ?? null;\n}\n\nexport interface CombatControlsConfig {\n readonly stanceControls: Record<\n string,\n { stance: string; korean: string; technique: string }\n >;\n readonly movement: Record<string, string>;\n readonly combat: Record<string, string>;\n readonly system: Record<string, string>;\n}\n\n// Input handling types\nexport interface InputEvent {\n readonly type: \"keydown\" | \"keyup\" | \"pointerdown\" | \"pointerup\";\n readonly key?: string;\n readonly position?: { x: number; y: number };\n readonly timestamp: number;\n}\n\nexport interface CombatInput {\n readonly player: number;\n readonly action: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Combat input data varies by action type\n readonly data?: any;\n}\n\n// Gesture types\nexport interface Gesture {\n readonly type: \"tap\" | \"hold\" | \"swipe\" | \"combo\";\n readonly duration?: number;\n readonly direction?: \"up\" | \"down\" | \"left\" | \"right\";\n readonly sequence?: string[];\n}\n\nexport const DEFAULT_GAME_SPEED = 1.0;\n\n/**\n * Core game configuration constants for Black Trigram\n */\n\n// Game configuration\nexport const GAME_CONFIG = {\n // Canvas dimensions\n CANVAS_WIDTH: 1200,\n CANVAS_HEIGHT: 800,\n TARGET_FPS: 60,\n MIN_FPS: 30,\n\n // Combat settings\n ROUND_DURATION: 180, // seconds\n MAX_ROUNDS: 3,\n KO_THRESHOLD: 0,\n\n // Player settings\n BASE_HEALTH: 100,\n BASE_KI: 100,\n BASE_STAMINA: 100,\n\n // Player positions\n PLAYER_START_POS_X_1: 300,\n PLAYER_START_POS_X_2: 900,\n PLAYER_START_POS_Y: 400,\n\n // Physics\n GRAVITY: 9.8,\n FRICTION: 0.85,\n\n // UI settings\n UI_PADDING: 20,\n BUTTON_HEIGHT: 50,\n\n // Audio settings\n MASTER_VOLUME: 1.0,\n MUSIC_VOLUME: 0.7,\n SFX_VOLUME: 0.8,\n\n // Debug settings\n DEBUG_MODE: false,\n SHOW_HITBOXES: false,\n SHOW_VITAL_POINTS: false,\n} as const;\n\n// Add missing player colors\nexport const PLAYER_COLORS = {\n PLAYER_1_COLOR: 0x0099ff, // Blue\n PLAYER_2_COLOR: 0xff9900, // Orange\n} as const;\n\n// Difficulty settings\nexport const DIFFICULTY_SETTINGS = {\n BEGINNER: {\n AI_REACTION_TIME: 800,\n DAMAGE_MULTIPLIER: 0.7,\n TECHNIQUE_SUCCESS_RATE: 0.6,\n },\n INTERMEDIATE: {\n AI_REACTION_TIME: 600,\n DAMAGE_MULTIPLIER: 1.0,\n TECHNIQUE_SUCCESS_RATE: 0.8,\n },\n EXPERT: {\n AI_REACTION_TIME: 400,\n DAMAGE_MULTIPLIER: 1.3,\n TECHNIQUE_SUCCESS_RATE: 0.9,\n },\n MASTER: {\n AI_REACTION_TIME: 200,\n DAMAGE_MULTIPLIER: 1.5,\n TECHNIQUE_SUCCESS_RATE: 0.95,\n },\n} as const;\n\n// Game phases\nexport const GAME_PHASES = {\n INTRO: \"intro\",\n TRAINING: \"training\",\n COMBAT: \"combat\",\n VICTORY: \"victory\",\n DEFEAT: \"defeat\",\n} as const;\n\n// Game version and metadata\nexport const GAME_METADATA = {\n VERSION: \"1.0.0\",\n BUILD: \"2024.1\",\n TITLE: \"흑괘 (Black Trigram)\",\n SUBTITLE: \"Korean Martial Arts Combat Simulator\",\n DEVELOPER: \"Black Trigram Team\",\n COPYRIGHT: \"© 2024 Black Trigram\",\n} as const;\n\n// Performance thresholds\nexport const PERFORMANCE_THRESHOLDS = {\n TARGET_FPS: 60,\n MIN_FPS: 30,\n FRAME_TIME_WARNING: 20, // ms\n MEMORY_WARNING: 100, // MB\n GARBAGE_COLLECTION_THRESHOLD: 50, // MB\n} as const;\n\n// Combat timing constants\nexport const COMBAT_TIMING = {\n ATTACK_WINDOW: 500, // ms\n DEFENSE_WINDOW: 300, // ms\n RECOVERY_TIME: 200, // ms\n COUNTER_WINDOW: 150, // ms\n} as const;\n\n// Damage calculation constants\nexport const DAMAGE_CONSTANTS = {\n BASE_DAMAGE: 10,\n CRITICAL_MULTIPLIER: 2.0,\n VITAL_POINT_MULTIPLIER: 1.5,\n ARMOR_REDUCTION: 0.1,\n STANCE_DEFENSE_BONUS: 0.2,\n BALANCE_IMPACT_MULTIPLIER: 0.3,\n CONSCIOUSNESS_THRESHOLD: 30,\n PAIN_THRESHOLD: 80,\n BASE_CRIT_CHANCE: 0.1, // Added: Base critical hit chance (e.g., 10%)\n TECHNIQUE_ACCURACY_MODIFIER: 1.0, // Added\n STANCE_EFFECTIVENESS_RANGE: { MIN: 0.5, MAX: 1.5 }, // Added\n PERFECT_TIMING_BONUS: 0.3, // Added\n} as const;\n\n// Animation timings\nexport const ANIMATION_TIMINGS = {\n STANCE_TRANSITION: 300,\n TECHNIQUE_STARTUP: 150,\n TECHNIQUE_ACTIVE: 100,\n TECHNIQUE_RECOVERY: 250,\n HIT_STUN: 200,\n BLOCK_STUN: 100,\n KNOCKDOWN_RECOVERY: 1000,\n} as const;\n\n// UI Layout constants\nexport const UI_LAYOUT = {\n HUD_HEIGHT: 80,\n CONTROLS_HEIGHT: 120,\n SIDEBAR_WIDTH: 200,\n MARGIN: 20,\n BUTTON_HEIGHT: 50,\n BUTTON_WIDTH: 150,\n} as const;\n\n// Audio volume defaults\nexport const AUDIO_DEFAULTS = {\n MASTER_VOLUME: 0.7,\n SFX_VOLUME: 0.8,\n MUSIC_VOLUME: 0.5,\n AMBIENT_VOLUME: 0.3,\n} as const;\n\n// Calculated constants based on GAME_CONFIG\nexport const HALF_CANVAS_WIDTH = GAME_CONFIG.CANVAS_WIDTH / 2;\nexport const HALF_CANVAS_HEIGHT = GAME_CONFIG.CANVAS_HEIGHT / 2;\nexport const CANVAS_ASPECT_RATIO =\n GAME_CONFIG.CANVAS_WIDTH / GAME_CONFIG.CANVAS_HEIGHT;\nexport const FRAME_TIME = 1000 / GAME_CONFIG.TARGET_FPS;\nexport const TICK_RATE = GAME_CONFIG.TARGET_FPS;\n\n// Player distance calculations\nexport const PLAYER_DISTANCE =\n GAME_CONFIG.PLAYER_START_POS_X_2 - GAME_CONFIG.PLAYER_START_POS_X_1;\nexport const CENTER_POSITION_X =\n (GAME_CONFIG.PLAYER_START_POS_X_1 + GAME_CONFIG.PLAYER_START_POS_X_2) / 2;\n\n// Combat ranges\nexport const COMBAT_RANGES = {\n MELEE_RANGE: 80,\n CLOSE_RANGE: 120,\n MEDIUM_RANGE: 200,\n LONG_RANGE: 300,\n MAX_RANGE: PLAYER_DISTANCE,\n} as const;\n\n// Game state constants\nexport const GAME_STATES = {\n LOADING: \"loading\",\n MENU: \"menu\",\n CHARACTER_SELECT: \"character_select\",\n TRAINING: \"training\",\n COMBAT: \"combat\",\n PAUSED: \"paused\",\n GAME_OVER: \"game_over\",\n} as const;\n\n// Input constants\nexport const INPUT_CONSTANTS = {\n DOUBLE_TAP_TIME: 300, // ms\n HOLD_THRESHOLD: 500, // ms\n GESTURE_TIMEOUT: 1000, // ms\n COMBO_TIMEOUT: 2000, // ms\n} as const;\n\n// Visual effect constants\nexport const VISUAL_EFFECTS = {\n HIT_FLASH_DURATION: 100,\n SCREEN_SHAKE_INTENSITY: 5,\n PARTICLE_LIFETIME: 1000,\n GLOW_PULSE_SPEED: 2,\n STANCE_GLOW_OPACITY: 0.3,\n} as const;\n\n// Training mode constants\nexport const TRAINING_CONFIG = {\n DUMMY_HEALTH: 1000,\n AUTO_RESET_TIME: 5000, // ms\n SHOW_FRAME_DATA: true,\n SHOW_HITBOXES: true,\n INFINITE_KI: true,\n INFINITE_STAMINA: true,\n} as const;\n\n// Game mode configurations\nexport const GAME_MODE_CONFIG = {\n VERSUS: {\n allowPause: true,\n timeLimit: 180,\n rounds: 3,\n enableAI: false,\n },\n TRAINING: {\n allowPause: true,\n timeLimit: null,\n rounds: 1,\n enableAI: true,\n infiniteResources: true,\n },\n PRACTICE: {\n allowPause: true,\n timeLimit: null,\n rounds: 1,\n enableAI: false,\n infiniteResources: true,\n },\n} as const;\n\n// Performance settings\nexport const PERFORMANCE_CONFIG = {\n MAX_PARTICLES: 100,\n MAX_SOUND_SOURCES: 16,\n TEXTURE_QUALITY: \"high\",\n ENABLE_SHADOWS: true,\n ENABLE_POST_PROCESSING: true,\n} as const;\n\n// Korean martial arts specific settings\nexport const MARTIAL_ARTS_CONFIG = {\n VITAL_POINTS_COUNT: 70,\n TRIGRAM_STANCES_COUNT: 8,\n PLAYER_ARCHETYPES_COUNT: 5,\n\n // Combat timing\n ATTACK_WINDOW: 500, // milliseconds\n COUNTER_WINDOW: 300,\n BLOCK_WINDOW: 200,\n\n // Stance transition\n MIN_STANCE_CHANGE_INTERVAL: 500,\n STANCE_CHANGE_COST_BASE: 10,\n\n // Damage calculations\n BASE_DAMAGE_MULTIPLIER: 1.0,\n CRITICAL_HIT_MULTIPLIER: 1.5,\n VITAL_POINT_MULTIPLIER: 2.5, // Increased from 2.0 for impactful vital point strikes\n} as const;\n\nexport default GAME_CONFIG;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../src/systems/types.ts"],"sourcesContent":["/**\n * Type definitions for systems types\n * Auto-generated by type migration script\n */\n\n// System imports from shared types - avoid circular dependencies\nimport { AudioSystemInterface, SoundEffectId } from \"@/audio\";\nimport type {\n EffectIntensity,\n EnvironmentalEffectType,\n HitEffectType,\n ParticleType,\n} from \"@/systems/effects\";\nimport { KOREAN_COLORS } from \"@/types\";\nimport {\n KoreanText,\n PlayerArchetype,\n Position,\n TrigramStance,\n} from \"@/types/common\";\n\nexport interface AnimationConfig {\n readonly name: string;\n readonly frames: readonly AnimationFrame[];\n readonly loop?: boolean;\n readonly speed?: number;\n}\n\nexport interface CombatSystemConfig {\n readonly damageMultiplier: number;\n readonly criticalChance: number;\n}\n\nexport interface TrigramSystemConfig {\n readonly transitionSpeed: number;\n readonly energyCost: number;\n}\n\nexport interface AISystemConfig {\n readonly difficulty: \"easy\" | \"medium\" | \"hard\" | \"expert\";\n readonly reactionTime: number;\n}\n\nexport interface VitalPointSystemConfig {\n readonly precisionRequired: number;\n readonly damageMultipliers: Record<string, number>;\n readonly effectDurations: Record<string, number>;\n}\n\n// Deprecated placeholder type - use unknown for generic texture representation\n\ntype Texture = unknown;\n\n// Vital point effect\n// Player archetype data\nexport interface PlayerArchetypeData {\n readonly id: string;\n readonly name: KoreanText;\n readonly description: KoreanText;\n readonly baseHealth: number;\n readonly baseKi: number;\n readonly baseStamina: number;\n readonly coreStance: TrigramStance;\n readonly theme: {\n primary: number;\n secondary: number;\n };\n readonly colors: {\n primary: number;\n secondary: number;\n };\n readonly stats: {\n attackPower: number;\n defense: number;\n speed: number;\n technique: number;\n };\n readonly favoredStances: readonly TrigramStance[];\n readonly specialAbilities: readonly string[];\n readonly philosophy: KoreanText;\n}\n\nexport interface AnimationState {\n readonly currentAnimationName?: string;\n readonly currentFrameIndex: number;\n readonly isPlaying: boolean;\n readonly elapsedTimeInFrame: number;\n}\n\nexport interface CollisionData {\n readonly entityA: EntityId;\n readonly entityB: EntityId;\n readonly normal: Velocity;\n readonly penetration: number;\n}\n\nexport interface PhysicsEntityConfig {\n readonly position: Position;\n readonly velocity?: Velocity;\n readonly mass?: number;\n readonly friction?: number;\n readonly restitution?: number;\n readonly shape:\n | { type: \"circle\"; radius: number }\n | { type: \"rectangle\"; width: number; height: number };\n readonly isStatic?: boolean;\n}\n\nexport interface PhysicsEntityState {\n readonly position: Position;\n readonly velocity: Velocity;\n readonly acceleration?: Velocity;\n readonly angularVelocity?: number;\n}\n\n// @deprecated Use Three.js rendering instead\nexport interface RenderableConfig {\n readonly zOrder?: number;\n readonly visible?: boolean;\n readonly alpha?: number;\n readonly parent?: EntityId | \"stage\";\n}\n\nexport interface StatusEffect {\n readonly id: string;\n readonly type: string;\n readonly intensity: EffectIntensity;\n readonly duration: number;\n readonly description: KoreanText;\n readonly stackable: boolean;\n readonly source: string;\n readonly startTime: number;\n readonly endTime: number;\n}\n\nexport interface HitEffect {\n readonly id: string;\n readonly type: HitEffectType;\n readonly attackerId: string;\n readonly defenderId: string;\n readonly timestamp: number;\n readonly duration: number;\n readonly position?: Position;\n readonly velocity?: { x: number; y: number };\n readonly color?: number;\n readonly size?: number;\n readonly alpha?: number;\n readonly lifespan?: number;\n readonly text?: string | KoreanText;\n readonly damageAmount?: number;\n readonly vitalPointId?: string;\n readonly statusEffect?: StatusEffect;\n readonly yOffset?: number;\n readonly intensity: number;\n readonly startTime: number;\n}\n\nexport interface ParticleEffect {\n readonly id: string;\n readonly type: ParticleType;\n readonly position: Position;\n readonly velocity: { x: number; y: number };\n readonly acceleration?: { x: number; y: number };\n readonly color: number;\n readonly size: number;\n readonly lifetime: number;\n readonly fadeOut?: boolean;\n readonly gravity?: number;\n}\n\nexport interface EnvironmentalEffect {\n readonly id: string;\n readonly type: EnvironmentalEffectType;\n readonly affectedArea: {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n };\n readonly effects: {\n readonly visibilityModifier?: number;\n readonly accuracyModifier?: number;\n readonly movementModifier?: number;\n readonly damageModifier?: number;\n };\n readonly duration: number;\n}\n\nexport interface VisualEffect {\n readonly id: string;\n readonly type: string;\n readonly duration: number;\n readonly intensity: number;\n readonly position?: Position;\n readonly color?: number;\n}\n\nexport interface EffectSystem {\n readonly effects: readonly VisualEffect[];\n readonly addEffect: (effect: VisualEffect) => void;\n readonly removeEffect: (id: string) => void;\n readonly updateEffects: (deltaTime: number) => void;\n}\n\nexport interface DisplayHitEffect extends HitEffect {\n readonly opacity: number;\n readonly scale: number;\n readonly startTime: number;\n readonly displayAlpha: number;\n readonly displayY: number;\n readonly displaySize: number;\n}\n\nexport interface InputSystemInterface {\n registerAction: (action: string, callback: () => void) => void;\n unregisterAction: (action: string) => void;\n clearActions: () => void;\n isActionActive: (action: string) => boolean;\n}\n\nexport interface AnimationSystemInterface {\n playAnimation: (entityId: EntityId, animationName: string) => void;\n stopAnimation: (entityId: EntityId, animationName?: string) => void;\n getCurrentFrame: (entityId: EntityId) => AnimationFrame | undefined;\n addAnimation: (config: AnimationConfig) => void;\n getAnimationState: (entityId: EntityId) => AnimationState | undefined;\n}\n\nexport interface PhysicsSystemInterface {\n addEntity: (entityId: EntityId, config: PhysicsEntityConfig) => void;\n removeEntity: (entityId: EntityId) => void;\n update: (deltaTime: number) => void;\n getEntityState: (entityId: EntityId) => PhysicsEntityState | undefined;\n checkCollision: (\n entityIdA: EntityId,\n entityIdB: EntityId,\n ) => CollisionData | null;\n applyForce: (entityId: EntityId, force: Velocity) => void;\n}\n\n// @deprecated Use Three.js rendering instead\nexport interface RenderingSystemInterface {\n addRenderable: (entityId: EntityId, config: RenderableConfig) => void;\n removeRenderable: (entityId: EntityId) => void;\n updateRenderable: (\n entityId: EntityId,\n updates: Partial<RenderableConfig>,\n ) => void;\n render: () => void;\n}\n\nexport interface SystemEvent {\n readonly type: string;\n readonly timestamp: number;\n readonly source: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Event data varies by event type\n readonly data: Record<string, any>;\n}\n\nexport interface EventBusInterface {\n publish: (event: SystemEvent) => void;\n subscribe: (\n eventType: string,\n callback: (event: SystemEvent) => void,\n ) => void;\n unsubscribe: (\n eventType: string,\n callback: (event: SystemEvent) => void,\n ) => void;\n}\n\n// Define system interfaces without importing (to avoid circular deps)\n// These interfaces use `any` to avoid circular dependency issues between\n// systems (combat, vital point, trigram) that reference each other's types.\n// Proper typing would require extracting shared types to a separate module.\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport interface CombatSystemInterface {\n calculateDamage: (\n technique: any,\n attacker: any,\n defender: any,\n hitResult: any,\n ) => {\n baseDamage: number;\n modifierDamage: number;\n totalDamage: number;\n effectsApplied: readonly StatusEffect[];\n finalDefenderState?: any;\n };\n resolveAttack: (\n attacker: any,\n defender: any,\n technique: any,\n targetedVitalPointId?: string,\n ) => any;\n applyCombatResult: (\n result: any,\n attacker: any,\n defender: any,\n ) => { updatedAttacker: any; updatedDefender: any };\n getAvailableTechniques: (player: any) => readonly any[];\n}\n\nexport interface VitalPointSystemInterface {\n processHit: (\n targetPosition: Position,\n technique: any,\n baseDamage: number,\n attackerArchetype: any,\n targetDimensions: { width: number; height: number },\n targetedVitalPointId?: string | null,\n ) => any;\n calculateHit: (\n technique: any,\n targetVitalPointId: string | null,\n accuracyRoll: number,\n attackerPosition: Position,\n defenderPosition: Position,\n defenderStance: any,\n ) => any;\n applyVitalPointEffects: (\n player: any,\n vitalPoint: any,\n intensityMultiplier?: number,\n ) => any;\n}\n\nexport interface TrigramSystemInterface {\n getTechniqueForStance: (stance: any, archetype?: any) => any | undefined;\n calculateStanceEffectiveness: (\n attackerStance: any,\n defenderStance: any,\n technique?: any,\n ) => number;\n isValidTransition: (from: any, to: any) => boolean;\n getTransitionCost: (\n from: any,\n to: any,\n player?: any,\n ) => { ki: number; stamina: number; timeMs: number };\n recommendStance: (player: any, opponent?: any) => any;\n}\n\nexport interface GameSystemManager {\n readonly combatSystem: CombatSystemInterface;\n readonly vitalPointSystem: VitalPointSystemInterface;\n readonly trigramSystem: TrigramSystemInterface;\n readonly inputSystem: InputSystemInterface;\n readonly audioSystem: AudioSystemInterface;\n readonly animationSystem?: AnimationSystemInterface;\n /* eslint-enable @typescript-eslint/no-explicit-any */\n readonly physicsSystem?: PhysicsSystemInterface;\n readonly renderingSystem?: RenderingSystemInterface;\n readonly eventBus: EventBusInterface;\n initializeAll: () => Promise<void>;\n updateAll: (deltaTime: number) => void;\n}\n\nexport interface SystemConfig {\n readonly debugMode?: boolean;\n readonly performanceMonitoring?: boolean;\n}\n\nexport interface GameSystemState {\n readonly combat: CombatSystemConfig;\n readonly trigram: TrigramSystemConfig;\n readonly vitalPoint: VitalPointSystemConfig;\n readonly ai: AISystemConfig;\n}\n\nexport interface SystemPerformance {\n readonly fps: number;\n readonly memoryUsage: number;\n readonly renderTime: number;\n readonly updateTime: number;\n}\n\n// Fix: Add missing type definitions\nexport type Timestamp = number;\nexport type EntityId = string;\nexport interface Velocity {\n readonly x: number;\n readonly y: number;\n}\n\n// Configuration for the VitalPointSystem\n// Result from VitalPointSystem's hit calculation - unified with anatomy.ts version\n// Combat system interface\n// Vital point system interface\n// Trigram system interface\n// Input system interface\n// Gamepad state\nexport interface GamepadState {\n readonly id: string;\n readonly axes: readonly number[];\n readonly buttons: readonly { pressed: boolean; value: number }[];\n}\n\n// Three.js uses built-in animation systems\n// @deprecated Use Three.js animation system instead\nexport interface AnimationFrame {\n readonly texture: Texture;\n readonly duration: number;\n}\n\n// @deprecated Use Three.js animation system instead\nexport interface AnimationState {\n readonly currentAnimationName?: string;\n readonly currentFrameIndex: number;\n readonly isPlaying: boolean;\n readonly elapsedTimeInFrame: number;\n}\n\n// Physics system interface\n// Physics entity configuration\nexport interface PhysicsEntityConfig {\n readonly position: Position;\n readonly velocity?: Velocity;\n readonly mass?: number;\n readonly friction?: number;\n readonly restitution?: number; // Bounciness\n readonly shape:\n | { type: \"circle\"; radius: number }\n | { type: \"rectangle\"; width: number; height: number };\n readonly isStatic?: boolean; // Cannot be moved by forces // Added\n}\n\n// Added PhysicsEntityState and CollisionData for PhysicsSystemInterface\nexport interface PhysicsEntityState {\n readonly position: Position;\n readonly velocity: Velocity;\n readonly acceleration?: Velocity;\n readonly angularVelocity?: number;\n}\n\nexport interface CollisionData {\n readonly entityA: EntityId;\n readonly entityB: EntityId;\n readonly normal: Velocity; // Collision normal vector\n readonly penetration: number; // How much they are overlapping\n}\n\n// Rendering system interface (deprecated - use Three.js rendering)\n\n// Game system manager\n// System event base type\n// Event bus interface for system communication\n// General system configuration\n// System-specific types for Korean martial arts combat\n\n// Combat system interfaces\nexport interface CombatSystemConfig {\n readonly damageMultiplier: number;\n readonly criticalChance: number;\n readonly blockEffectiveness: number;\n readonly staminaDrainRate: number;\n}\n\n// Trigram system interfaces\nexport interface TrigramSystemConfig {\n readonly transitionSpeed: number;\n readonly energyCost: number;\n readonly effectivenessMatrix: Record<\n TrigramStance,\n Record<TrigramStance, number>\n >;\n}\n\n// Vital point system interfaces\n// AI system interfaces\nexport interface AISystemConfig {\n readonly difficulty: \"easy\" | \"medium\" | \"hard\" | \"expert\";\n readonly reactionTime: number;\n readonly aggressiveness: number;\n readonly adaptability: number;\n}\n\n// Player archetype data\nexport const PLAYER_ARCHETYPES_DATA: Record<\n PlayerArchetype,\n PlayerArchetypeData\n> = {\n [PlayerArchetype.MUSA]: {\n id: \"musa\",\n name: { korean: \"무사 (Musa)\", english: \"Traditional Warrior\" },\n description: {\n korean: \"전통 무사의 길\",\n english: \"Path of the traditional warrior\",\n },\n baseHealth: 120,\n baseKi: 100,\n baseStamina: 110,\n coreStance: TrigramStance.GEON,\n theme: {\n primary: KOREAN_COLORS.TRIGRAM_GEON_PRIMARY,\n secondary: KOREAN_COLORS.KOREAN_RED,\n },\n colors: {\n primary: KOREAN_COLORS.TRIGRAM_GEON_PRIMARY,\n secondary: KOREAN_COLORS.KOREAN_RED,\n },\n stats: {\n attackPower: 85,\n defense: 90,\n speed: 70,\n technique: 80,\n },\n favoredStances: [TrigramStance.GEON, TrigramStance.GAN],\n specialAbilities: [\"Honor Strike\", \"Defensive Mastery\"],\n philosophy: {\n korean: \"명예와 정의의 길\",\n english: \"The way of honor and justice\",\n },\n },\n\n [PlayerArchetype.AMSALJA]: {\n id: \"amsalja\",\n name: { korean: \"암살자 (Amsalja)\", english: \"Shadow Assassin\" },\n description: {\n korean: \"그림자 속의 효율성\",\n english: \"Efficiency from the shadows\",\n },\n baseHealth: 80,\n baseKi: 120,\n baseStamina: 100,\n coreStance: TrigramStance.SON,\n theme: {\n primary: KOREAN_COLORS.TRIGRAM_SON_PRIMARY,\n secondary: KOREAN_COLORS.UI_BACKGROUND_DARK,\n },\n colors: {\n primary: KOREAN_COLORS.TRIGRAM_SON_PRIMARY,\n secondary: KOREAN_COLORS.UI_BACKGROUND_DARK,\n },\n stats: {\n attackPower: 95,\n defense: 60,\n speed: 95,\n technique: 90,\n },\n favoredStances: [TrigramStance.SON, TrigramStance.GAM],\n specialAbilities: [\"Shadow Strike\", \"Vital Point Mastery\"],\n philosophy: {\n korean: \"침묵과 정확성의 도\",\n english: \"The way of silence and precision\",\n },\n },\n\n [PlayerArchetype.HACKER]: {\n id: \"hacker\",\n name: { korean: \"해커 (Hacker)\", english: \"Cyber Warrior\" },\n description: {\n korean: \"정보를 통한 힘\",\n english: \"Power through information\",\n },\n baseHealth: 90,\n baseKi: 130,\n baseStamina: 80,\n coreStance: TrigramStance.LI,\n theme: {\n primary: KOREAN_COLORS.PRIMARY_CYAN,\n secondary: KOREAN_COLORS.TRIGRAM_LI_PRIMARY,\n },\n colors: {\n primary: KOREAN_COLORS.PRIMARY_CYAN,\n secondary: KOREAN_COLORS.TRIGRAM_LI_PRIMARY,\n },\n stats: {\n attackPower: 75,\n defense: 70,\n speed: 85,\n technique: 95,\n },\n favoredStances: [TrigramStance.LI, TrigramStance.JIN],\n specialAbilities: [\"System Override\", \"Digital Precision\"],\n philosophy: {\n korean: \"지식과 기술의 융합\",\n english: \"The fusion of knowledge and technology\",\n },\n },\n\n [PlayerArchetype.JEONGBO_YOWON]: {\n id: \"jeongbo_yowon\",\n name: {\n korean: \"정보요원 (Jeongbo Yowon)\",\n english: \"Intelligence Operative\",\n },\n description: {\n korean: \"관찰을 통한 지식\",\n english: \"Knowledge through observation\",\n },\n baseHealth: 100,\n baseKi: 110,\n baseStamina: 100,\n coreStance: TrigramStance.TAE,\n theme: {\n primary: KOREAN_COLORS.TRIGRAM_TAE_PRIMARY,\n secondary: KOREAN_COLORS.UI_STEEL_GRAY,\n },\n colors: {\n primary: KOREAN_COLORS.TRIGRAM_TAE_PRIMARY,\n secondary: KOREAN_COLORS.UI_STEEL_GRAY,\n },\n stats: {\n attackPower: 80,\n defense: 85,\n speed: 80,\n technique: 85,\n },\n favoredStances: [TrigramStance.TAE, TrigramStance.GAN],\n specialAbilities: [\"Intel Gathering\", \"Adaptive Combat\"],\n philosophy: {\n korean: \"적응과 전략의 예술\",\n english: \"The art of adaptation and strategy\",\n },\n },\n\n [PlayerArchetype.JOJIK_POKRYEOKBAE]: {\n id: \"jojik_pokryeokbae\",\n name: {\n korean: \"조직폭력배 (Jojik Pokryeokbae)\",\n english: \"Organized Crime\",\n },\n description: {\n korean: \"무자비함을 통한 생존\",\n english: \"Survival through ruthlessness\",\n },\n baseHealth: 110,\n baseKi: 90,\n baseStamina: 120,\n coreStance: TrigramStance.JIN,\n theme: {\n primary: KOREAN_COLORS.TRIGRAM_JIN_PRIMARY,\n secondary: KOREAN_COLORS.NEGATIVE_RED,\n },\n colors: {\n primary: KOREAN_COLORS.TRIGRAM_JIN_PRIMARY,\n secondary: KOREAN_COLORS.NEGATIVE_RED,\n },\n stats: {\n attackPower: 90,\n defense: 75,\n speed: 75,\n technique: 70,\n },\n favoredStances: [TrigramStance.JIN, TrigramStance.GON],\n specialAbilities: [\"Brutal Force\", \"Street Fighting\"],\n philosophy: {\n korean: \"강함과 의지의 길\",\n english: \"The way of strength and will\",\n },\n },\n} as const;\n\n// Base player stats\nexport const BASE_PLAYER_STATS = {\n HEALTH: 100,\n KI: 100,\n STAMINA: 100,\n ATTACK_POWER: 75,\n DEFENSE: 75,\n SPEED: 75,\n TECHNIQUE: 75,\n} as const;\n\n// Combat configuration\nexport const COMBAT_CONFIG = {\n MAX_HEALTH: 100,\n MAX_KI: 100,\n MAX_STAMINA: 100,\n MAX_BALANCE: 100,\n MAX_CONSCIOUSNESS: 100,\n\n // Damage multipliers - vital points more impactful for Korean martial arts realism\n CRITICAL_HIT_MULTIPLIER: 2.0,\n VITAL_POINT_MULTIPLIER: 2.5, // Increased from 1.5 for more realistic vital point impact\n COUNTER_ATTACK_MULTIPLIER: 1.3,\n\n // Status thresholds\n LOW_HEALTH_THRESHOLD: 25,\n CRITICAL_HEALTH_THRESHOLD: 10,\n UNCONSCIOUS_THRESHOLD: 0,\n STAMINA_EXHAUSTED_THRESHOLD: 0,\n\n // Recovery rates (per second) - increased for 3-minute round sustainability\n STAMINA_RECOVERY_RATE: 15, // Increased from 10 for sustained combat\n KI_RECOVERY_RATE: 8, // Increased from 5 for more technique usage\n BALANCE_RECOVERY_RATE: 15,\n CONSCIOUSNESS_RECOVERY_RATE: 2,\n\n // Combat timing (milliseconds)\n TECHNIQUE_COOLDOWN: 500,\n STANCE_CHANGE_COOLDOWN: 200,\n BLOCK_DURATION: 300,\n RECOVERY_TIME: 400,\n} as const;\n\n// Enhanced damage calculation constants\nexport const ENHANCED_DAMAGE_CONSTANTS = {\n BASE_DAMAGE: 10,\n CRITICAL_MULTIPLIER: 2.0,\n VITAL_POINT_MULTIPLIER: 2.5, // Increased from 1.5 for Korean martial arts vital point realism\n ARMOR_REDUCTION: 0.1,\n STANCE_DEFENSE_BONUS: 0.2,\n BALANCE_IMPACT_MULTIPLIER: 0.3,\n CONSCIOUSNESS_THRESHOLD: 30,\n PAIN_THRESHOLD: 80,\n\n // New damage factors\n TECHNIQUE_POWER_MODIFIER: 0.2,\n ARCHETYPE_BONUS: 0.15,\n COMBO_MULTIPLIER: 1.2,\n PERFECT_TIMING_BONUS: 0.3,\n BASE_CRIT_CHANCE: 0.1, // Added: Base critical hit chance (e.g., 10%)\n} as const;\n\n// Combat system constants for Korean martial arts\n\nexport const COMBAT_CONSTANTS = {\n // Damage calculation\n BASE_DAMAGE: 10,\n CRITICAL_MULTIPLIER: 2.0,\n VITAL_POINT_MULTIPLIER: 2.5, // Increased from 1.5 for Korean martial arts vital point realism\n\n // Status thresholds\n LOW_HEALTH_THRESHOLD: 30,\n CRITICAL_HEALTH_THRESHOLD: 15,\n EXHAUSTED_STAMINA_THRESHOLD: 20,\n\n // Recovery rates (per second) - increased for 3-minute round sustainability\n STAMINA_RECOVERY_RATE: 15, // Increased from 5 for sustained combat\n KI_RECOVERY_RATE: 8, // Increased from 3 for more technique usage\n CONSCIOUSNESS_RECOVERY_RATE: 2,\n\n // Combat timing\n ATTACK_COOLDOWN: 500, // milliseconds\n STANCE_CHANGE_COOLDOWN: 300,\n BLOCK_WINDOW: 200,\n\n // Balance and momentum\n BALANCE_RECOVERY_RATE: 10,\n MOMENTUM_DECAY_RATE: 5,\n\n // Pain and status effects\n PAIN_DECAY_RATE: 3,\n STATUS_EFFECT_DURATION: 3000,\n} as const;\n\n// Combat controls mapping - Enhanced with realistic combat focus\nexport const COMBAT_CONTROLS = {\n // Trigram stance system (1-8 keys) with authentic Korean martial arts techniques\n stanceControls: {\n \"1\": {\n stance: \"geon\" as TrigramStance,\n korean: \"건\",\n english: \"Heaven\",\n symbol: \"☰\",\n technique: {\n korean: \"천둥벽력\",\n english: \"Thunder Strike\",\n },\n combatFocus: {\n korean: \"골격타격\",\n english: \"Bone-striking force\",\n },\n combatEffects: {\n korean: \"골절, 구조적 손상\",\n english: \"Fractures, structural damage\",\n },\n description: {\n korean: \"하늘의 힘으로 적의 뼈를 부수는 강력한 타격\",\n english:\n \"Powerful strikes that shatter enemy bones with heaven's force\",\n },\n },\n \"2\": {\n stance: \"tae\" as TrigramStance,\n korean: \"태\",\n english: \"Lake\",\n symbol: \"☱\",\n technique: {\n korean: \"유수연타\",\n english: \"Flowing Strike\",\n },\n combatFocus: {\n korean: \"관절조작\",\n english: \"Joint manipulation\",\n },\n combatEffects: {\n korean: \"탈구, 이동력 상실\",\n english: \"Dislocations, mobility loss\",\n },\n description: {\n korean: \"호수처럼 부드럽게 흘러 관절을 조작하는 기법\",\n english: \"Techniques that flow like water to manipulate joints\",\n },\n },\n \"3\": {\n stance: \"li\" as TrigramStance,\n korean: \"리\",\n english: \"Fire\",\n symbol: \"☲\",\n technique: {\n korean: \"화염지창\",\n english: \"Fire Spear\",\n },\n combatFocus: {\n korean: \"정밀신경타격\",\n english: \"Precise nerve strikes\",\n },\n combatEffects: {\n korean: \"일시마비, 감각상실\",\n english: \"Temporary paralysis, numbness\",\n },\n description: {\n korean: \"불꽃같은 정확성으로 신경계를 공격하는 치명적 기법\",\n english:\n \"Deadly techniques targeting the nervous system with fire-like precision\",\n },\n },\n \"4\": {\n stance: \"jin\" as TrigramStance,\n korean: \"진\",\n english: \"Thunder\",\n symbol: \"☳\",\n technique: {\n korean: \"벽력일섬\",\n english: \"Lightning Strike\",\n },\n combatFocus: {\n korean: \"기절기법\",\n english: \"Stunning techniques\",\n },\n combatEffects: {\n korean: \"방향감각상실, 의식잃음\",\n english: \"Disorientation, knockouts\",\n },\n description: {\n korean: \"번개처럼 빠른 충격으로 적의 의식을 차단\",\n english: \"Lightning-fast shocks that disrupt enemy consciousness\",\n },\n },\n \"5\": {\n stance: \"son\" as TrigramStance,\n korean: \"손\",\n english: \"Wind\",\n symbol: \"☴\",\n technique: {\n korean: \"선풍연격\",\n english: \"Whirlwind Combo\",\n },\n combatFocus: {\n korean: \"지속압박\",\n english: \"Continuous pressure\",\n },\n combatEffects: {\n korean: \"점진적 무력화\",\n english: \"Gradual incapacitation\",\n },\n description: {\n korean: \"바람처럼 끊임없는 연타로 적을 서서히 무력화\",\n english:\n \"Relentless wind-like strikes that gradually overwhelm the enemy\",\n },\n },\n \"6\": {\n stance: \"gam\" as TrigramStance,\n korean: \"감\",\n english: \"Water\",\n symbol: \"☵\",\n technique: {\n korean: \"수류반격\",\n english: \"Water Counter\",\n },\n combatFocus: {\n korean: \"혈류차단\",\n english: \"Blood flow restriction\",\n },\n combatEffects: {\n korean: \"순환장애\",\n english: \"Circulation disruption\",\n },\n description: {\n korean: \"물의 흐름을 끊듯 혈액순환을 차단하는 위험한 기법\",\n english:\n \"Dangerous techniques that disrupt blood circulation like stopping water flow\",\n },\n },\n \"7\": {\n stance: \"gan\" as TrigramStance,\n korean: \"간\",\n english: \"Mountain\",\n symbol: \"☶\",\n technique: {\n korean: \"반석방어\",\n english: \"Mountain Defense\",\n },\n combatFocus: {\n korean: \"방어반격\",\n english: \"Defensive counters\",\n },\n combatEffects: {\n korean: \"반격, 차단\",\n english: \"Counter-attacks, blocks\",\n },\n description: {\n korean: \"산처럼 견고한 방어에서 나오는 강력한 반격\",\n english: \"Powerful counters emerging from mountain-solid defense\",\n },\n },\n \"8\": {\n stance: \"gon\" as TrigramStance,\n korean: \"곤\",\n english: \"Earth\",\n symbol: \"☷\",\n technique: {\n korean: \"대지포옹\",\n english: \"Earth's Embrace\",\n },\n combatFocus: {\n korean: \"지면기법\",\n english: \"Ground techniques\",\n },\n combatEffects: {\n korean: \"투척, 넘어뜨리기\",\n english: \"Throws, takedowns\",\n },\n description: {\n korean: \"대지의 힘으로 적을 땅에 내동댕이치는 투척술\",\n english:\n \"Throwing techniques that slam enemies to the ground with earth's power\",\n },\n },\n },\n\n // Movement controls with combat context\n movement: {\n WASD: {\n korean: \"전술적 이동과 발놀림\",\n english: \"Tactical positioning and footwork\",\n },\n ArrowKeys: {\n korean: \"대체 이동 시스템\",\n english: \"Alternative movement system\",\n },\n },\n\n // Combat actions with realistic descriptions\n combat: {\n SPACE: {\n korean: \"현재 자세의 기법 실행\",\n english: \"Execute current stance technique\",\n },\n SHIFT: {\n korean: \"방어 자세/차단 위치\",\n english: \"Defensive guard/block position\",\n },\n CTRL: {\n korean: \"정밀 급소 타격 모드\",\n english: \"Precision vital point targeting mode\",\n },\n TAB: {\n korean: \"무술 원형 순환\",\n english: \"Cycle through martial archetypes\",\n },\n },\n\n // System controls\n system: {\n ESC: {\n korean: \"일시정지 메뉴 / 인트로로 돌아가기\",\n english: \"Pause menu / Return to intro\",\n },\n F1: {\n korean: \"도움말 / 조작법 가이드\",\n english: \"Help / Controls guide\",\n },\n M: {\n korean: \"음소거 / 오디오 설정\",\n english: \"Mute / Audio settings\",\n },\n },\n} as const;\n\n// Damage types\nexport const DAMAGE_TYPES = {\n PHYSICAL: \"physical\",\n ENERGY: \"energy\",\n VITAL_POINT: \"vital_point\",\n PSYCHOLOGICAL: \"psychological\",\n} as const;\n\n// Combat phases\nexport const COMBAT_PHASES = {\n PREPARATION: \"preparation\",\n ENGAGEMENT: \"engagement\",\n EXECUTION: \"execution\",\n RECOVERY: \"recovery\",\n RESOLUTION: \"resolution\",\n} as const;\n\n// Combat audio mapping\nexport const COMBAT_AUDIO_MAP: Record<string, SoundEffectId> = {\n light_attack: \"attack_light\",\n medium_attack: \"attack_medium\",\n heavy_attack: \"attack_heavy\",\n critical_attack: \"attack_critical\",\n\n light_hit: \"hit_light\",\n medium_hit: \"hit_medium\",\n heavy_hit: \"hit_heavy\",\n critical_hit: \"critical_hit\",\n\n block: \"block_success\",\n guard_break: \"block_break\",\n miss: \"miss\",\n\n stance_change: \"stance_change\",\n technique: \"technique_execute\",\n\n match_start: \"match_start\",\n combat_end: \"combat_end\",\n victory: \"victory\",\n defeat: \"defeat\",\n\n guard: \"guard\",\n} as const;\n\n// Combat state transitions\nexport const COMBAT_STATE_MACHINE = {\n idle: {\n canTransitionTo: [\"attacking\", \"defending\", \"moving\", \"stunned\"],\n duration: Infinity,\n },\n attacking: {\n canTransitionTo: [\"idle\", \"recovering\", \"stunned\"],\n duration: 500,\n },\n defending: {\n canTransitionTo: [\"idle\", \"attacking\", \"stunned\"],\n duration: 300,\n },\n moving: {\n canTransitionTo: [\"idle\", \"attacking\", \"defending\"],\n duration: 200,\n },\n stunned: {\n canTransitionTo: [\"idle\"],\n duration: 1000,\n },\n recovering: {\n canTransitionTo: [\"idle\"],\n duration: 400,\n },\n unconscious: {\n canTransitionTo: [\"idle\"],\n duration: 5000,\n },\n} as const;\n\n// Training-specific combat constants\nexport const TRAINING_COMBAT_SETTINGS = {\n techniqueCooldown: 500,\n perfectStrikeThreshold: 0.7,\n maxTrainingSession: 300000, // 5 minutes\n kiRegenerationRate: 2,\n staminaRegenerationRate: 1.5,\n} as const;\n\n// Combat state transitions for training mode\nexport const TRAINING_STATE_MACHINE = {\n practicing: {\n canTransitionTo: [\"idle\", \"executing\", \"recovering\"],\n duration: Infinity,\n },\n executing: {\n canTransitionTo: [\"practicing\", \"idle\"],\n duration: 800,\n },\n recovering: {\n canTransitionTo: [\"practicing\", \"idle\"],\n duration: 300,\n },\n} as const;\n\n// Technique execution results\nexport const TECHNIQUE_RESULTS = {\n SUCCESS: \"success\",\n BLOCKED: \"blocked\",\n MISSED: \"missed\",\n COUNTERED: \"countered\",\n INTERRUPTED: \"interrupted\",\n} as const;\n\n// Combat effectiveness modifiers\nexport const EFFECTIVENESS_MODIFIERS = {\n stance_advantage: 1.2,\n stance_disadvantage: 0.8,\n counter_attack: 1.5,\n perfect_timing: 1.3,\n off_balance: 0.7,\n fatigued: 0.6,\n focused: 1.1,\n} as const;\n\n// Combat resource costs\nexport const RESOURCE_COSTS = {\n KI: {\n BASIC_TECHNIQUE: 5,\n ADVANCED_TECHNIQUE: 10,\n SPECIAL_TECHNIQUE: 15,\n ULTIMATE_TECHNIQUE: 25,\n },\n STAMINA: {\n BASIC_ATTACK: 8,\n HEAVY_ATTACK: 15,\n BLOCK: 5,\n DODGE: 10,\n STANCE_CHANGE: 12,\n },\n} as const;\n\n// Hit detection constants\nexport const HIT_DETECTION = {\n PRECISION_THRESHOLD: 0.8,\n VITAL_POINT_THRESHOLD: 0.9,\n BASE_ACCURACY: 0.7,\n MAX_ACCURACY: 0.95,\n\n // Hit boxes\n PLAYER_HITBOX_WIDTH: 60,\n PLAYER_HITBOX_HEIGHT: 180,\n VITAL_POINT_RADIUS: 15,\n} as const;\n\n// Status effect durations\nexport const STATUS_DURATIONS = {\n STUN: 1500,\n POISON: 5000,\n BURN: 3000,\n BLEED: 4000,\n WEAKNESS: 6000,\n STRENGTH_BUFF: 8000,\n} as const;\n\nexport interface CombatControlsConfig {\n readonly stanceControls: Record<\n string,\n { stance: string; korean: string; technique: string }\n >;\n readonly movement: Record<string, string>;\n readonly combat: Record<string, string>;\n readonly system: Record<string, string>;\n}\n\n// Key mapping for easier lookup\nexport const KEYBOARD_MAPPING = {\n // Stance keys\n STANCE_1: \"1\",\n STANCE_2: \"2\",\n STANCE_3: \"3\",\n STANCE_4: \"4\",\n STANCE_5: \"5\",\n STANCE_6: \"6\",\n STANCE_7: \"7\",\n STANCE_8: \"8\",\n\n // Combat actions\n EXECUTE_TECHNIQUE: \" \", // Space\n BLOCK: \"Shift\",\n TARGET_MODE: \"Control\",\n ARCHETYPE_CYCLE: \"Tab\",\n\n // Movement\n MOVE_UP: \"w\",\n MOVE_DOWN: \"s\",\n MOVE_LEFT: \"a\",\n MOVE_RIGHT: \"d\",\n\n // System\n PAUSE: \"Escape\",\n HELP: \"F1\",\n MUTE: \"m\",\n} as const;\n\n/**\n * Get the stance associated with a given key.\n *\n * @param key - The key to lookup.\n * @returns The corresponding stance, or null if not found.\n */\nexport function getStanceFromKey(key: string): TrigramStance | null {\n const stanceMap: Record<string, TrigramStance> = {\n \"1\": TrigramStance.GEON,\n \"2\": TrigramStance.TAE,\n \"3\": TrigramStance.LI,\n \"4\": TrigramStance.JIN,\n \"5\": TrigramStance.SON,\n \"6\": TrigramStance.GAM,\n \"7\": TrigramStance.GAN,\n \"8\": TrigramStance.GON,\n };\n return stanceMap[key] ?? null;\n}\n\nexport interface CombatControlsConfig {\n readonly stanceControls: Record<\n string,\n { stance: string; korean: string; technique: string }\n >;\n readonly movement: Record<string, string>;\n readonly combat: Record<string, string>;\n readonly system: Record<string, string>;\n}\n\n// Input handling types\nexport interface InputEvent {\n readonly type: \"keydown\" | \"keyup\" | \"pointerdown\" | \"pointerup\";\n readonly key?: string;\n readonly position?: { x: number; y: number };\n readonly timestamp: number;\n}\n\nexport interface CombatInput {\n readonly player: number;\n readonly action: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Combat input data varies by action type\n readonly data?: any;\n}\n\n// Gesture types\nexport interface Gesture {\n readonly type: \"tap\" | \"hold\" | \"swipe\" | \"combo\";\n readonly duration?: number;\n readonly direction?: \"up\" | \"down\" | \"left\" | \"right\";\n readonly sequence?: string[];\n}\n\nexport const DEFAULT_GAME_SPEED = 1.0;\n\n/**\n * Core game configuration constants for Black Trigram\n */\n\n// Game configuration\nexport const GAME_CONFIG = {\n // Canvas dimensions\n CANVAS_WIDTH: 1200,\n CANVAS_HEIGHT: 800,\n TARGET_FPS: 60,\n MIN_FPS: 30,\n\n // Combat settings\n ROUND_DURATION: 180, // seconds\n MAX_ROUNDS: 3,\n KO_THRESHOLD: 0,\n\n // Player settings\n BASE_HEALTH: 100,\n BASE_KI: 100,\n BASE_STAMINA: 100,\n\n // Player positions\n PLAYER_START_POS_X_1: 300,\n PLAYER_START_POS_X_2: 900,\n PLAYER_START_POS_Y: 400,\n\n // Physics\n GRAVITY: 9.8,\n FRICTION: 0.85,\n\n // UI settings\n UI_PADDING: 20,\n BUTTON_HEIGHT: 50,\n\n // Audio settings\n MASTER_VOLUME: 1.0,\n MUSIC_VOLUME: 0.7,\n SFX_VOLUME: 0.8,\n\n // Debug settings\n DEBUG_MODE: false,\n SHOW_HITBOXES: false,\n SHOW_VITAL_POINTS: false,\n} as const;\n\n// Add missing player colors\nexport const PLAYER_COLORS = {\n PLAYER_1_COLOR: 0x0099ff, // Blue\n PLAYER_2_COLOR: 0xff9900, // Orange\n} as const;\n\n// Difficulty settings\nexport const DIFFICULTY_SETTINGS = {\n BEGINNER: {\n AI_REACTION_TIME: 800,\n DAMAGE_MULTIPLIER: 0.7,\n TECHNIQUE_SUCCESS_RATE: 0.6,\n },\n INTERMEDIATE: {\n AI_REACTION_TIME: 600,\n DAMAGE_MULTIPLIER: 1.0,\n TECHNIQUE_SUCCESS_RATE: 0.8,\n },\n EXPERT: {\n AI_REACTION_TIME: 400,\n DAMAGE_MULTIPLIER: 1.3,\n TECHNIQUE_SUCCESS_RATE: 0.9,\n },\n MASTER: {\n AI_REACTION_TIME: 200,\n DAMAGE_MULTIPLIER: 1.5,\n TECHNIQUE_SUCCESS_RATE: 0.95,\n },\n} as const;\n\n// Game phases\nexport const GAME_PHASES = {\n INTRO: \"intro\",\n TRAINING: \"training\",\n COMBAT: \"combat\",\n VICTORY: \"victory\",\n DEFEAT: \"defeat\",\n} as const;\n\n// Game version and metadata\nexport const GAME_METADATA = {\n VERSION: \"1.0.0\",\n BUILD: \"2024.1\",\n TITLE: \"흑괘 (Black Trigram)\",\n SUBTITLE: \"Korean Martial Arts Combat Simulator\",\n DEVELOPER: \"Black Trigram Team\",\n COPYRIGHT: \"© 2024 Black Trigram\",\n} as const;\n\n// Performance thresholds\nexport const PERFORMANCE_THRESHOLDS = {\n TARGET_FPS: 60,\n MIN_FPS: 30,\n FRAME_TIME_WARNING: 20, // ms\n MEMORY_WARNING: 100, // MB\n GARBAGE_COLLECTION_THRESHOLD: 50, // MB\n} as const;\n\n// Combat timing constants\nexport const COMBAT_TIMING = {\n ATTACK_WINDOW: 500, // ms\n DEFENSE_WINDOW: 300, // ms\n RECOVERY_TIME: 200, // ms\n COUNTER_WINDOW: 150, // ms\n} as const;\n\n// Damage calculation constants\nexport const DAMAGE_CONSTANTS = {\n BASE_DAMAGE: 10,\n CRITICAL_MULTIPLIER: 2.0,\n VITAL_POINT_MULTIPLIER: 1.5,\n ARMOR_REDUCTION: 0.1,\n STANCE_DEFENSE_BONUS: 0.2,\n BALANCE_IMPACT_MULTIPLIER: 0.3,\n CONSCIOUSNESS_THRESHOLD: 30,\n PAIN_THRESHOLD: 80,\n BASE_CRIT_CHANCE: 0.1, // Added: Base critical hit chance (e.g., 10%)\n TECHNIQUE_ACCURACY_MODIFIER: 1.0, // Added\n STANCE_EFFECTIVENESS_RANGE: { MIN: 0.5, MAX: 1.5 }, // Added\n PERFECT_TIMING_BONUS: 0.3, // Added\n} as const;\n\n// Animation timings\nexport const ANIMATION_TIMINGS = {\n STANCE_TRANSITION: 300,\n TECHNIQUE_STARTUP: 150,\n TECHNIQUE_ACTIVE: 100,\n TECHNIQUE_RECOVERY: 250,\n HIT_STUN: 200,\n BLOCK_STUN: 100,\n KNOCKDOWN_RECOVERY: 1000,\n} as const;\n\n// UI Layout constants\nexport const UI_LAYOUT = {\n HUD_HEIGHT: 80,\n CONTROLS_HEIGHT: 120,\n SIDEBAR_WIDTH: 200,\n MARGIN: 20,\n BUTTON_HEIGHT: 50,\n BUTTON_WIDTH: 150,\n} as const;\n\n// Audio volume defaults\nexport const AUDIO_DEFAULTS = {\n MASTER_VOLUME: 0.7,\n SFX_VOLUME: 0.8,\n MUSIC_VOLUME: 0.5,\n AMBIENT_VOLUME: 0.3,\n} as const;\n\n// Calculated constants based on GAME_CONFIG\nexport const HALF_CANVAS_WIDTH = GAME_CONFIG.CANVAS_WIDTH / 2;\nexport const HALF_CANVAS_HEIGHT = GAME_CONFIG.CANVAS_HEIGHT / 2;\nexport const CANVAS_ASPECT_RATIO =\n GAME_CONFIG.CANVAS_WIDTH / GAME_CONFIG.CANVAS_HEIGHT;\nexport const FRAME_TIME = 1000 / GAME_CONFIG.TARGET_FPS;\nexport const TICK_RATE = GAME_CONFIG.TARGET_FPS;\n\n// Player distance calculations\nexport const PLAYER_DISTANCE =\n GAME_CONFIG.PLAYER_START_POS_X_2 - GAME_CONFIG.PLAYER_START_POS_X_1;\nexport const CENTER_POSITION_X =\n (GAME_CONFIG.PLAYER_START_POS_X_1 + GAME_CONFIG.PLAYER_START_POS_X_2) / 2;\n\n// Combat ranges\nexport const COMBAT_RANGES = {\n MELEE_RANGE: 80,\n CLOSE_RANGE: 120,\n MEDIUM_RANGE: 200,\n LONG_RANGE: 300,\n MAX_RANGE: PLAYER_DISTANCE,\n} as const;\n\n// Game state constants\nexport const GAME_STATES = {\n LOADING: \"loading\",\n MENU: \"menu\",\n CHARACTER_SELECT: \"character_select\",\n TRAINING: \"training\",\n COMBAT: \"combat\",\n PAUSED: \"paused\",\n GAME_OVER: \"game_over\",\n} as const;\n\n// Input constants\nexport const INPUT_CONSTANTS = {\n DOUBLE_TAP_TIME: 300, // ms\n HOLD_THRESHOLD: 500, // ms\n GESTURE_TIMEOUT: 1000, // ms\n COMBO_TIMEOUT: 2000, // ms\n} as const;\n\n// Visual effect constants\nexport const VISUAL_EFFECTS = {\n HIT_FLASH_DURATION: 100,\n SCREEN_SHAKE_INTENSITY: 5,\n PARTICLE_LIFETIME: 1000,\n GLOW_PULSE_SPEED: 2,\n STANCE_GLOW_OPACITY: 0.3,\n} as const;\n\n// Training mode constants\nexport const TRAINING_CONFIG = {\n DUMMY_HEALTH: 1000,\n AUTO_RESET_TIME: 5000, // ms\n SHOW_FRAME_DATA: true,\n SHOW_HITBOXES: true,\n INFINITE_KI: true,\n INFINITE_STAMINA: true,\n} as const;\n\n// Game mode configurations\nexport const GAME_MODE_CONFIG = {\n VERSUS: {\n allowPause: true,\n timeLimit: 180,\n rounds: 3,\n enableAI: false,\n },\n TRAINING: {\n allowPause: true,\n timeLimit: null,\n rounds: 1,\n enableAI: true,\n infiniteResources: true,\n },\n PRACTICE: {\n allowPause: true,\n timeLimit: null,\n rounds: 1,\n enableAI: false,\n infiniteResources: true,\n },\n} as const;\n\n// Performance settings\nexport const PERFORMANCE_CONFIG = {\n MAX_PARTICLES: 100,\n MAX_SOUND_SOURCES: 16,\n TEXTURE_QUALITY: \"high\",\n ENABLE_SHADOWS: true,\n ENABLE_POST_PROCESSING: true,\n} as const;\n\n// Korean martial arts specific settings\nexport const MARTIAL_ARTS_CONFIG = {\n VITAL_POINTS_COUNT: 70,\n TRIGRAM_STANCES_COUNT: 8,\n PLAYER_ARCHETYPES_COUNT: 5,\n\n // Combat timing\n ATTACK_WINDOW: 500, // milliseconds\n COUNTER_WINDOW: 300,\n BLOCK_WINDOW: 200,\n\n // Stance transition\n MIN_STANCE_CHANGE_INTERVAL: 500,\n STANCE_CHANGE_COST_BASE: 10,\n\n // Damage calculations\n BASE_DAMAGE_MULTIPLIER: 1.0,\n CRITICAL_HIT_MULTIPLIER: 1.5,\n VITAL_POINT_MULTIPLIER: 2.5, // Increased from 2.0 for impactful vital point strikes\n} as const;\n\nexport default GAME_CONFIG;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DamageCalculator.js","names":[],"sources":["../../../src/systems/vitalpoint/DamageCalculator.ts"],"sourcesContent":["import {\n PlayerArchetype,\n TrigramStance,\n VitalPointSeverity,\n} from \"../../types/common\";\nimport {\n calculateHipRotationPowerModifier,\n calculateKickPowerFromHipRotation,\n type HipRotationState,\n type KickType,\n} from \"../animation\";\nimport { PlayerState } from \"../player\";\nimport { TrigramCalculator } from \"../trigram/TrigramCalculator\";\nimport { asExtendedGonTechnique } from \"../trigram/types/GonTechniqueExtensions\";\nimport { StatusEffect } from \"../types\";\nimport { calculateMeridianFlow } from \"./KoreanAnatomy\";\nimport { getMeridiansForVitalPoint } from \"./MeridianVitalPointMapping\";\nimport {\n DamageResult,\n KoreanTechnique,\n VitalPoint,\n VitalPointHitResult,\n} from \"./types\";\n\nexport class DamageCalculator {\n /**\n * Vital point severity damage multipliers\n */\n private static readonly SEVERITY_MULTIPLIERS: Record<\n VitalPointSeverity,\n number\n > = {\n [VitalPointSeverity.MINOR]: 1.2,\n [VitalPointSeverity.MODERATE]: 1.5,\n [VitalPointSeverity.MAJOR]: 2.0,\n [VitalPointSeverity.CRITICAL]: 2.5,\n [VitalPointSeverity.LETHAL]: 3.0,\n };\n\n /**\n * Accuracy bonus scaling constants\n * Maps 0.0-1.0 accuracy to 0.8x-1.2x multiplier\n */\n private static readonly ACCURACY_MIN_MULTIPLIER = 0.8;\n private static readonly ACCURACY_RANGE = 0.4; // Range from min to max (1.2 - 0.8)\n\n /**\n * Calculate vital point damage with proper archetype bonuses\n */\n static calculateVitalPointDamage(\n vitalPoint: VitalPoint,\n baseDamage: number,\n attacker: PlayerState,\n accuracy: number,\n ): DamageResult {\n const effects: StatusEffect[] = [];\n\n // Fix: Use static method call instead of this\n const archetypeModifier = DamageCalculator.getArchetypeModifier(\n attacker.archetype,\n );\n const techniqueEffectiveness = accuracy;\n\n const finalDamage = Math.max(\n 1,\n (vitalPoint.baseDamage ?? vitalPoint.damage?.min ?? baseDamage) *\n archetypeModifier *\n techniqueEffectiveness,\n );\n\n // Create status effects from vital point\n vitalPoint.effects.forEach((effect) => {\n const statusEffect: StatusEffect = {\n id: `${effect.id}_${Date.now()}`,\n type: \"weakened\", // Map to valid EffectType\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- EffectIntensity type mapping from vital point effect\n intensity: \"moderate\" as any,\n duration: effect.duration,\n description: effect.description,\n stackable: effect.stackable,\n source: vitalPoint.id,\n startTime: Date.now(),\n endTime: Date.now() + effect.duration,\n };\n effects.push(statusEffect);\n });\n\n return {\n damage: finalDamage,\n effects,\n isCritical: accuracy > 0.9,\n isVitalPoint: true,\n };\n }\n\n /**\n * Fix: Add missing getArchetypeModifier method\n */\n static getArchetypeModifier(archetype: PlayerArchetype): number {\n switch (archetype) {\n case PlayerArchetype.MUSA:\n return 1.2; // Traditional warrior - strong base damage\n case PlayerArchetype.AMSALJA:\n return 1.5; // Assassin - high damage modifier\n case PlayerArchetype.HACKER:\n return 1.1; // Cyber warrior - precision over power\n case PlayerArchetype.JEONGBO_YOWON:\n return 1.1; // Intelligence operative - strategic damage\n case PlayerArchetype.JOJIK_POKRYEOKBAE:\n return 1.3; // Organized crime - brutal effectiveness\n default:\n return 1.0;\n }\n }\n\n /**\n * Calculate technique damage with vital point consideration\n */\n static calculateTechniqueDamage(\n technique: KoreanTechnique,\n attacker: PlayerState,\n vitalPoint: VitalPoint | null,\n accuracy: number,\n ): DamageResult {\n // Fix: Remove unused baseDamage variable and use technique.damage directly\n const effects: StatusEffect[] = [];\n const archetypeModifier = DamageCalculator.getArchetypeModifier(\n attacker.archetype,\n );\n\n let finalDamage = (technique.damage ?? 15) * archetypeModifier * accuracy;\n\n // Apply vital point multiplier if hitting a vital point\n if (vitalPoint) {\n finalDamage *=\n (vitalPoint.baseDamage ?? vitalPoint.damage?.min ?? 10) / 10;\n\n // Add vital point effects\n vitalPoint.effects.forEach((effect) => {\n const statusEffect: StatusEffect = {\n id: `${effect.id}_${Date.now()}`,\n type: \"weakened\",\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- EffectIntensity type mapping from vital point effect\n intensity: \"moderate\" as any,\n duration: effect.duration,\n description: effect.description,\n stackable: effect.stackable,\n source: vitalPoint.id,\n startTime: Date.now(),\n endTime: Date.now() + effect.duration,\n };\n effects.push(statusEffect);\n });\n }\n\n return {\n damage: Math.max(1, Math.floor(finalDamage)),\n effects,\n isCritical: accuracy > 0.8,\n isVitalPoint: !!vitalPoint,\n };\n }\n\n /**\n * Calculate damage reduction from defense\n */\n static calculateDamageReduction(\n incomingDamage: number,\n defenderDefense: number,\n isBlocking: boolean = false,\n ): number {\n const blockMultiplier = isBlocking ? 0.5 : 1.0;\n const defenseReduction = Math.min(0.8, defenderDefense / 200); // Max 80% reduction\n\n return Math.max(\n 1,\n incomingDamage * (1 - defenseReduction) * blockMultiplier,\n );\n }\n\n /**\n * Calculate critical hit chance\n */\n static calculateCriticalChance(\n baseCritChance: number,\n attacker: PlayerState,\n technique: KoreanTechnique,\n ): number {\n const archetypeBonus =\n DamageCalculator.getArchetypeModifier(attacker.archetype) * 0.1;\n const techniqueBonus = (technique.critChance || 0.1) * 0.5;\n\n return Math.min(0.95, baseCritChance + archetypeBonus + techniqueBonus);\n }\n\n /**\n * Calculate comprehensive vital point damage with all modifiers.\n *\n * **Korean**: 종합 급소 피해 계산 (Comprehensive Vital Point Damage Calculation)\n *\n * Integrates all damage modifiers including:\n * - Base damage from attacker strength and technique power\n * - Stance effectiveness (攻克关系)\n * - Vital point severity multipliers (1.5x-3.0x)\n * - Accuracy bonus (0.8x-1.2x)\n * - Meridian flow bonus (1.0x-1.3x at peak hours)\n * - Time-of-day bonus (+20% for Dark Ops techniques at night)\n * - Archetype-specific bonuses\n * - Hip rotation power modifier (1.0x-1.3x for strikes with full rotation)\n * - Critical hit multiplier (2x when accuracy > 0.9)\n * - Damage variance (±10% randomness)\n * - Defense reduction\n *\n * ## Damage Formula\n *\n * ```typescript\n * finalDamage =\n * baseDamage ×\n * stanceEffectiveness ×\n * vitalPointMultiplier ×\n * accuracyBonus ×\n * meridianBonus ×\n * timeBonus ×\n * archetypeBonus ×\n * hipRotationModifier ×\n * criticalMultiplier ×\n * variance ×\n * defenseReduction\n * ```\n *\n * @param attacker - Attacking player state\n * @param defender - Defending player state\n * @param technique - Korean martial arts technique being used\n * @param vitalPointHit - Result of vital point hit detection\n * @param currentHour - Current hour of day (0-23) for meridian flow\n * @param meridianStates - Current meridian disruption states (0=blocked, 1=normal)\n * @param hipRotationAngle - Hip rotation angle in radians (optional, defaults to 0)\n * @param kickHipState - Hip rotation state for kicks (optional, for kick-specific power)\n * @returns Comprehensive damage result with all modifiers applied\n *\n * @example\n * ```typescript\n * const result = DamageCalculator.calculateEnhancedVitalPointDamage(\n * attackerState,\n * defenderState,\n * technique,\n * vitalPointHitResult,\n * 2, // 2 AM - liver meridian peak\n * { liver: 1.0, gallbladder: 0.8 }\n * );\n * console.log(`Final damage: ${result.damage}`);\n * console.log(`Critical hit: ${result.isCritical}`);\n * ```\n *\n * @public\n * @korean 종합급소피해계산\n */\n static calculateEnhancedVitalPointDamage(\n attacker: PlayerState,\n defender: PlayerState,\n technique: KoreanTechnique,\n vitalPointHit: VitalPointHitResult,\n currentHour: number,\n meridianStates: Record<string, number>,\n hipRotationAngle: number = 0,\n kickHipState?: HipRotationState,\n ): DamageResult {\n // 1. Base damage from technique\n const attackerStrength = attacker.attackPower || 50;\n const techniquePower = technique.damage || 15;\n const baseDamage = attackerStrength * (techniquePower / 10);\n\n // 2. Stance effectiveness (攻克关系)\n const stanceEffectiveness = TrigramCalculator.calculateStanceEffectiveness(\n attacker.currentStance,\n defender.currentStance,\n );\n\n // 3. Vital point severity multiplier\n const vitalPointMultiplier = vitalPointHit.vitalPointHit\n ? (DamageCalculator.SEVERITY_MULTIPLIERS[vitalPointHit.severity] ?? 1)\n : 1;\n\n // 4. Accuracy bonus (better aim = more damage)\n // Maps 0.0-1.0 accuracy to 0.8x-1.2x multiplier\n const accuracy = vitalPointHit.accuracy ?? 0.5;\n const accuracyBonus =\n DamageCalculator.ACCURACY_MIN_MULTIPLIER +\n accuracy * DamageCalculator.ACCURACY_RANGE;\n\n // 5. Meridian flow bonus\n const meridianBonus = DamageCalculator.calculateMeridianDamageBonus(\n vitalPointHit.vitalPointHit?.id ?? \"\",\n currentHour,\n meridianStates,\n );\n\n // 6. Time-of-day bonus (Dark Ops techniques at night)\n const timeBonus = DamageCalculator.calculateTimeBonus(\n technique,\n currentHour,\n );\n\n // 7. Archetype-specific bonus\n const archetypeBonus = DamageCalculator.getArchetypeDamageBonus(\n attacker.archetype,\n technique,\n vitalPointHit.vitalPointHit,\n );\n\n // 8. Hip rotation power modifier (허리회전 파워 보너스)\n // Determine technique type for appropriate modifier calculation\n let hipRotationModifier = 1.0;\n\n // Check if this is a kick technique and we have kick-specific hip state\n const techniqueName =\n technique.name?.english || technique.englishName || \"\";\n const isKickTechnique =\n technique.type === \"kick\" || techniqueName.toLowerCase().includes(\"kick\");\n\n if (kickHipState && isKickTechnique) {\n // Use advanced kick-specific hip rotation calculation (up to 40% bonus)\n const kickType = DamageCalculator.determineKickType(techniqueName);\n hipRotationModifier = calculateKickPowerFromHipRotation(\n kickHipState,\n kickType,\n );\n } else if (hipRotationAngle !== 0) {\n // Use general hip rotation for strikes/throws/joints (up to 30% bonus)\n const techniqueType: \"strike\" | \"throw\" | \"joint\" =\n technique.type === \"throw\"\n ? \"throw\"\n : technique.type === \"joint_lock\"\n ? \"joint\"\n : \"strike\";\n hipRotationModifier = calculateHipRotationPowerModifier(\n hipRotationAngle,\n techniqueType,\n );\n }\n\n // 9. Critical hit (accuracy > 0.9)\n const criticalMultiplier = accuracy > 0.9 ? 2.0 : 1.0;\n const isCritical = accuracy > 0.9;\n\n // 10. Calculate total damage before defense\n let totalDamage =\n baseDamage *\n stanceEffectiveness *\n vitalPointMultiplier *\n accuracyBonus *\n meridianBonus *\n timeBonus *\n archetypeBonus *\n hipRotationModifier *\n criticalMultiplier;\n\n // 11. Add damage variance (±10%)\n const variance = 0.9 + Math.random() * 0.2; // 0.9 to 1.1\n totalDamage *= variance;\n\n // 12. Apply defense reduction using existing method for consistency\n const defenderDefense = defender.defense || 0;\n const finalDamage = DamageCalculator.calculateDamageReduction(\n totalDamage,\n defenderDefense,\n false,\n );\n\n // 13. Combine effects from vital point hit\n const effects = vitalPointHit.effects || [];\n\n return {\n damage: Math.max(1, finalDamage), // Minimum 1 damage\n effects,\n isCritical,\n isVitalPoint: !!vitalPointHit.vitalPointHit,\n };\n }\n\n /**\n * Determine kick type from technique name for hip rotation power calculation\n *\n * @param techniqueName - Name of the technique\n * @returns Kick type for hip rotation calculation\n *\n * @private\n * @korean 차기유형결정\n */\n private static determineKickType(techniqueName: string): KickType {\n const name = techniqueName.toLowerCase();\n\n if (\n name.includes(\"front\") ||\n name.includes(\"앞차기\") ||\n name.includes(\"snap\")\n ) {\n return \"front\";\n } else if (\n name.includes(\"roundhouse\") ||\n name.includes(\"돌려차기\") ||\n name.includes(\"round\")\n ) {\n return \"roundhouse\";\n } else if (\n name.includes(\"side\") ||\n name.includes(\"옆차기\") ||\n name.includes(\"lateral\")\n ) {\n return \"side\";\n } else if (name.includes(\"hook\") || name.includes(\"후려차기\")) {\n return \"hook\";\n } else if (\n name.includes(\"axe\") ||\n name.includes(\"내려차기\") ||\n name.includes(\"downward\")\n ) {\n return \"axe\";\n }\n\n // Default to front kick for unknown kick types\n return \"front\";\n }\n\n /**\n * Calculate meridian flow damage bonus based on time of day.\n *\n * **Korean**: 경락 유효성 피해 보너스 계산\n *\n * Calculates bonus damage when striking vital points during their peak\n * meridian flow hours. Peak flow provides +30% damage bonus.\n *\n * @param vitalPointId - ID of the vital point being struck\n * @param currentHour - Current hour of day (0-23)\n * @param meridianStates - Current meridian disruption states\n * @returns Damage multiplier (1.0-1.3)\n *\n * @private\n * @korean 경락유효성피해보너스계산\n */\n private static calculateMeridianDamageBonus(\n vitalPointId: string,\n currentHour: number,\n meridianStates: Record<string, number>,\n ): number {\n if (!vitalPointId) return 1;\n\n const relatedMeridians = getMeridiansForVitalPoint(vitalPointId);\n let maxBonus = 1.0;\n\n for (const meridianId of relatedMeridians) {\n const flow = calculateMeridianFlow(meridianId, currentHour);\n const state = meridianStates[meridianId] ?? 1.0;\n\n // Peak flow (>0.9) with normal state gives +30% bonus\n // flow ranges from 0.7 to 1.3, state from 0 (blocked) to 1 (normal)\n const effectiveFlow = flow * state;\n if (effectiveFlow > 0.9) {\n // Bonus scales linearly from 1.0 (no bonus) at effectiveFlow = 0.9\n // to 1.3 (maximum 30% bonus) at effectiveFlow = 1.3:\n // bonus = 1.0 + ((effectiveFlow - 0.9) / 0.4) * 0.3\n const bonus = 1.0 + ((effectiveFlow - 0.9) / 0.4) * 0.3;\n maxBonus = Math.max(maxBonus, Math.min(1.3, bonus));\n }\n }\n\n return maxBonus;\n }\n\n /**\n * Calculate time-of-day bonus for Dark Ops techniques.\n *\n * **Korean**: 시간대 보너스 계산\n *\n * Dark Ops techniques gain +20% damage at night (20:00-05:59)\n * to reflect tactical advantage of darkness.\n *\n * @param technique - Technique being used\n * @param currentHour - Current hour of day (0-23)\n * @returns Time bonus multiplier (1.0 or 1.2)\n *\n * @private\n * @korean 시간대보너스계산\n */\n private static calculateTimeBonus(\n technique: KoreanTechnique,\n currentHour: number,\n ): number {\n // Dark Ops techniques get +20% at night (20:00-05:59)\n // Check if technique has dark_ops or stealth in its ID or type\n const isDarkOpsTechnique =\n technique.id.includes(\"dark_ops\") ||\n technique.id.includes(\"stealth\") ||\n technique.id.includes(\"shadow\") ||\n technique.id.includes(\"night\");\n\n if (isDarkOpsTechnique) {\n // Night hours: 20:00 through 05:59 (6 AM is considered daylight)\n if (currentHour >= 20 || currentHour < 6) {\n return 1.2;\n }\n }\n return 1.0;\n }\n\n /**\n * Get archetype-specific damage bonus for technique and vital point.\n *\n * **Korean**: 원형 특화 피해 보너스\n *\n * Each archetype has specialized bonuses for different techniques\n * and vital point categories:\n *\n * - **무사 (Musa)**: +20% with 건 (Geon) stance techniques\n * - **암살자 (Amsalja)**: +30% on neurological vital points\n * - **해커 (Hacker)**: +15% baseline precision bonus\n * - **정보요원 (Jeongbo)**: +25% on vascular vital points\n * - **조직폭력배 (Jojik)**: +20% on dirty/ruthless techniques\n *\n * @param archetype - Attacker's archetype\n * @param technique - Technique being used\n * @param vitalPoint - Vital point being struck (optional)\n * @returns Archetype damage multiplier (1.0-1.5)\n *\n * @private\n * @korean 원형특화피해보너스\n */\n private static getArchetypeDamageBonus(\n archetype: PlayerArchetype,\n technique: KoreanTechnique,\n vitalPoint?: VitalPoint,\n ): number {\n // Base archetype modifier\n let bonus = DamageCalculator.getArchetypeModifier(archetype);\n\n // Additional bonuses based on technique-archetype synergy\n switch (archetype) {\n case PlayerArchetype.MUSA:\n // Musa gets bonus with Geon (Heaven) stance techniques\n if (technique.stance === TrigramStance.GEON) {\n bonus *= 1.2;\n }\n break;\n\n case PlayerArchetype.AMSALJA:\n // Assassin gets bonus on neurological vital points\n if (vitalPoint?.category === \"neurological\") {\n bonus *= 1.3;\n }\n break;\n\n case PlayerArchetype.HACKER:\n // Hacker gets consistent precision bonus\n bonus *= 1.15;\n break;\n\n case PlayerArchetype.JEONGBO_YOWON:\n // Intelligence operative gets bonus on vascular targets\n if (vitalPoint?.category === \"vascular\") {\n bonus *= 1.25;\n }\n break;\n\n case PlayerArchetype.JOJIK_POKRYEOKBAE:\n // Organized crime gets bonus on ruthless techniques\n // Check for keywords in technique ID\n if (\n technique.id.includes(\"ruthless\") ||\n technique.id.includes(\"brutal\") ||\n technique.id.includes(\"dirty\")\n ) {\n bonus *= 1.2;\n }\n break;\n }\n\n // Cap maximum bonus at 1.5x\n return Math.min(1.5, bonus);\n }\n\n /**\n * Calculate throw/takedown impact damage with ground multiplier.\n *\n * **Korean**: 던지기 충격 피해 계산 (Throw Impact Damage Calculation)\n *\n * Applies groundImpactMultiplier from Gon (Earth) techniques when opponent\n * hits the ground after a throw or takedown. Integrates with base damage\n * calculation to provide authentic Ssireum/Hapkido throw mechanics.\n *\n * **Formula**:\n * ```\n * impactDamage = baseDamage × groundImpactMultiplier × strengthModifier\n * ```\n *\n * **Ground Impact Multiplier Ranges**:\n * - 1.0-1.2: Low impact (controlled takedowns)\n * - 1.3-1.5: Medium impact (standard throws)\n * - 1.6-1.8: High impact (power throws)\n * - 1.9-2.0: Maximum impact (slams like 대지강타)\n *\n * @param technique - Korean martial arts technique (checks for ExtendedGonTechnique)\n * @param baseDamage - Base damage before ground impact modifier\n * @param attackerStrength - Attacker's strength stat for scaling\n * @param options - Optional configuration for damage calculation\n * @param options.applyVariance - Whether to apply random ±5% variance (default: true)\n * @returns Enhanced damage result with ground impact applied\n *\n * @example\n * ```typescript\n * const throwDamage = DamageCalculator.calculateThrowImpactDamage(\n * ssireumThrowTechnique, // groundImpactMultiplier: 1.7\n * 50, // base damage\n * 80 // attacker strength\n * );\n * // Result: ~85 damage (50 × 1.7 × 1.0) with ±5% variance\n *\n * // For deterministic testing:\n * const testDamage = DamageCalculator.calculateThrowImpactDamage(\n * technique, 50, 80, { applyVariance: false }\n * );\n * ```\n *\n * @public\n * @korean 던지기충격피해계산\n */\n static calculateThrowImpactDamage(\n technique: KoreanTechnique,\n baseDamage: number,\n attackerStrength: number = 50,\n options: { applyVariance?: boolean } = {},\n ): DamageResult {\n const { applyVariance = true } = options;\n // Check if technique has Gon-specific ground impact metadata\n // Use helper function for safe type casting\n const gonTechnique = asExtendedGonTechnique(technique);\n if (!gonTechnique) {\n // Non-Gon technique: return base damage without ground multiplier\n return {\n damage: Math.max(1, baseDamage),\n effects: [],\n isCritical: false,\n isVitalPoint: false,\n };\n }\n\n // Extract ground impact multiplier from validated Gon technique\n const groundMultiplier = gonTechnique.groundImpactMultiplier;\n\n // Calculate strength modifier (50 = baseline, scales ±20%)\n // Stronger attackers create more impact, weaker create less\n const strengthModifier = 0.8 + (attackerStrength / 250);\n\n // Apply ground impact multiplier with strength scaling\n let impactDamage = baseDamage * groundMultiplier * strengthModifier;\n\n // Add small damage variance (±5%) for realistic impact variation\n // Can be disabled for deterministic testing\n if (applyVariance) {\n const variance = 0.95 + Math.random() * 0.1; // 0.95 to 1.05\n impactDamage *= variance;\n }\n\n // Earth connection healing (대지는 모든 것을 품고 키운다)\n // Supportive healing is applied separately by calling system\n // This method focuses on damage calculation only\n\n return {\n damage: Math.max(1, Math.floor(impactDamage)),\n effects: [],\n isCritical: impactDamage > baseDamage * 1.5, // High impact = critical\n isVitalPoint: false,\n };\n }\n\n /**\n * Calculate earth's supportive healing from Gon technique.\n *\n * **Korean**: 대지 치유 계산 (Earth Healing Calculation)\n *\n * Implements Korean martial arts philosophy:\n * \"대지는 모든 것을 품고 키운다\" (The earth embraces and nurtures all things)\n *\n * Gon techniques restore HP to the attacker after successful execution\n * based on their connection with earth energy. Traditional techniques\n * like Ssireum throws provide stronger healing due to cultural authenticity.\n *\n * **Healing Formula**:\n * ```\n * healingAmount = supportiveHealing × (1 + earthAffinityBonus)\n * ```\n *\n * **Supportive Healing Ranges**:\n * - 0-2: Minimal earth connection (aggressive techniques)\n * - 3-4: Moderate earth connection (standard Ssireum)\n * - 5-6: Strong earth connection (traditional, sacrifice throws)\n * - 7-10: RESERVED for meditation/healing techniques\n *\n * @param technique - Korean martial arts technique (checks for ExtendedGonTechnique)\n * @param earthAffinityBonus - Player's earth affinity stat modifier (0.0-1.0)\n * @returns HP healing amount (0 if not a Gon technique)\n *\n * @example\n * ```typescript\n * const healing = DamageCalculator.calculateEarthHealing(\n * ssireumThrowTechnique, // supportiveHealing: 5\n * 0.3 // 30% earth affinity bonus\n * );\n * // Result: 6.5 HP restored (5 × 1.3)\n * ```\n *\n * @public\n * @korean 대지치유계산\n */\n static calculateEarthHealing(\n technique: KoreanTechnique,\n earthAffinityBonus: number = 0,\n ): number {\n // Use helper function for safe type casting\n const gonTechnique = asExtendedGonTechnique(technique);\n if (!gonTechnique) {\n return 0; // Non-Gon technique: no earth healing\n }\n\n const baseHealing = gonTechnique.supportiveHealing;\n\n // Apply earth affinity bonus (typically 0-100% bonus)\n const affinityMultiplier = 1 + Math.max(0, Math.min(1, earthAffinityBonus));\n\n // Calculate final healing with bonus\n const healingAmount = baseHealing * affinityMultiplier;\n\n // Return rounded healing value (minimum 0)\n return Math.max(0, Math.floor(healingAmount));\n }\n}\n\nexport default DamageCalculator;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DamageCalculator.js","names":[],"sources":["../../../src/systems/vitalpoint/DamageCalculator.ts"],"sourcesContent":["import {\n PlayerArchetype,\n TrigramStance,\n VitalPointSeverity,\n} from \"../../types/common\";\nimport {\n calculateHipRotationPowerModifier,\n calculateKickPowerFromHipRotation,\n type HipRotationState,\n type KickType,\n} from \"../animation\";\nimport { PlayerState } from \"../player\";\nimport { TrigramCalculator } from \"../trigram/TrigramCalculator\";\nimport { asExtendedGonTechnique } from \"../trigram/types/GonTechniqueExtensions\";\nimport { StatusEffect } from \"../types\";\nimport { calculateMeridianFlow } from \"./KoreanAnatomy\";\nimport { getMeridiansForVitalPoint } from \"./MeridianVitalPointMapping\";\nimport {\n DamageResult,\n KoreanTechnique,\n VitalPoint,\n VitalPointHitResult,\n} from \"./types\";\n\nexport class DamageCalculator {\n /**\n * Vital point severity damage multipliers\n */\n private static readonly SEVERITY_MULTIPLIERS: Record<\n VitalPointSeverity,\n number\n > = {\n [VitalPointSeverity.MINOR]: 1.2,\n [VitalPointSeverity.MODERATE]: 1.5,\n [VitalPointSeverity.MAJOR]: 2.0,\n [VitalPointSeverity.CRITICAL]: 2.5,\n [VitalPointSeverity.LETHAL]: 3.0,\n };\n\n /**\n * Accuracy bonus scaling constants\n * Maps 0.0-1.0 accuracy to 0.8x-1.2x multiplier\n */\n private static readonly ACCURACY_MIN_MULTIPLIER = 0.8;\n private static readonly ACCURACY_RANGE = 0.4; // Range from min to max (1.2 - 0.8)\n\n /**\n * Calculate vital point damage with proper archetype bonuses\n */\n static calculateVitalPointDamage(\n vitalPoint: VitalPoint,\n baseDamage: number,\n attacker: PlayerState,\n accuracy: number,\n ): DamageResult {\n const effects: StatusEffect[] = [];\n\n // Fix: Use static method call instead of this\n const archetypeModifier = DamageCalculator.getArchetypeModifier(\n attacker.archetype,\n );\n const techniqueEffectiveness = accuracy;\n\n const finalDamage = Math.max(\n 1,\n (vitalPoint.baseDamage ?? vitalPoint.damage?.min ?? baseDamage) *\n archetypeModifier *\n techniqueEffectiveness,\n );\n\n // Create status effects from vital point\n vitalPoint.effects.forEach((effect) => {\n const statusEffect: StatusEffect = {\n id: `${effect.id}_${Date.now()}`,\n type: \"weakened\", // Map to valid EffectType\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- EffectIntensity type mapping from vital point effect\n intensity: \"moderate\" as any,\n duration: effect.duration,\n description: effect.description,\n stackable: effect.stackable,\n source: vitalPoint.id,\n startTime: Date.now(),\n endTime: Date.now() + effect.duration,\n };\n effects.push(statusEffect);\n });\n\n return {\n damage: finalDamage,\n effects,\n isCritical: accuracy > 0.9,\n isVitalPoint: true,\n };\n }\n\n /**\n * Fix: Add missing getArchetypeModifier method\n */\n static getArchetypeModifier(archetype: PlayerArchetype): number {\n switch (archetype) {\n case PlayerArchetype.MUSA:\n return 1.2; // Traditional warrior - strong base damage\n case PlayerArchetype.AMSALJA:\n return 1.5; // Assassin - high damage modifier\n case PlayerArchetype.HACKER:\n return 1.1; // Cyber warrior - precision over power\n case PlayerArchetype.JEONGBO_YOWON:\n return 1.1; // Intelligence operative - strategic damage\n case PlayerArchetype.JOJIK_POKRYEOKBAE:\n return 1.3; // Organized crime - brutal effectiveness\n default:\n return 1.0;\n }\n }\n\n /**\n * Calculate technique damage with vital point consideration\n */\n static calculateTechniqueDamage(\n technique: KoreanTechnique,\n attacker: PlayerState,\n vitalPoint: VitalPoint | null,\n accuracy: number,\n ): DamageResult {\n // Fix: Remove unused baseDamage variable and use technique.damage directly\n const effects: StatusEffect[] = [];\n const archetypeModifier = DamageCalculator.getArchetypeModifier(\n attacker.archetype,\n );\n\n let finalDamage = (technique.damage ?? 15) * archetypeModifier * accuracy;\n\n // Apply vital point multiplier if hitting a vital point\n if (vitalPoint) {\n finalDamage *=\n (vitalPoint.baseDamage ?? vitalPoint.damage?.min ?? 10) / 10;\n\n // Add vital point effects\n vitalPoint.effects.forEach((effect) => {\n const statusEffect: StatusEffect = {\n id: `${effect.id}_${Date.now()}`,\n type: \"weakened\",\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- EffectIntensity type mapping from vital point effect\n intensity: \"moderate\" as any,\n duration: effect.duration,\n description: effect.description,\n stackable: effect.stackable,\n source: vitalPoint.id,\n startTime: Date.now(),\n endTime: Date.now() + effect.duration,\n };\n effects.push(statusEffect);\n });\n }\n\n return {\n damage: Math.max(1, Math.floor(finalDamage)),\n effects,\n isCritical: accuracy > 0.8,\n isVitalPoint: !!vitalPoint,\n };\n }\n\n /**\n * Calculate damage reduction from defense\n */\n static calculateDamageReduction(\n incomingDamage: number,\n defenderDefense: number,\n isBlocking: boolean = false,\n ): number {\n const blockMultiplier = isBlocking ? 0.5 : 1.0;\n const defenseReduction = Math.min(0.8, defenderDefense / 200); // Max 80% reduction\n\n return Math.max(\n 1,\n incomingDamage * (1 - defenseReduction) * blockMultiplier,\n );\n }\n\n /**\n * Calculate critical hit chance\n */\n static calculateCriticalChance(\n baseCritChance: number,\n attacker: PlayerState,\n technique: KoreanTechnique,\n ): number {\n const archetypeBonus =\n DamageCalculator.getArchetypeModifier(attacker.archetype) * 0.1;\n const techniqueBonus = (technique.critChance || 0.1) * 0.5;\n\n return Math.min(0.95, baseCritChance + archetypeBonus + techniqueBonus);\n }\n\n /**\n * Calculate comprehensive vital point damage with all modifiers.\n *\n * **Korean**: 종합 급소 피해 계산 (Comprehensive Vital Point Damage Calculation)\n *\n * Integrates all damage modifiers including:\n * - Base damage from attacker strength and technique power\n * - Stance effectiveness (攻克关系)\n * - Vital point severity multipliers (1.5x-3.0x)\n * - Accuracy bonus (0.8x-1.2x)\n * - Meridian flow bonus (1.0x-1.3x at peak hours)\n * - Time-of-day bonus (+20% for Dark Ops techniques at night)\n * - Archetype-specific bonuses\n * - Hip rotation power modifier (1.0x-1.3x for strikes with full rotation)\n * - Critical hit multiplier (2x when accuracy > 0.9)\n * - Damage variance (±10% randomness)\n * - Defense reduction\n *\n * ## Damage Formula\n *\n * ```typescript\n * finalDamage =\n * baseDamage ×\n * stanceEffectiveness ×\n * vitalPointMultiplier ×\n * accuracyBonus ×\n * meridianBonus ×\n * timeBonus ×\n * archetypeBonus ×\n * hipRotationModifier ×\n * criticalMultiplier ×\n * variance ×\n * defenseReduction\n * ```\n *\n * @param attacker - Attacking player state\n * @param defender - Defending player state\n * @param technique - Korean martial arts technique being used\n * @param vitalPointHit - Result of vital point hit detection\n * @param currentHour - Current hour of day (0-23) for meridian flow\n * @param meridianStates - Current meridian disruption states (0=blocked, 1=normal)\n * @param hipRotationAngle - Hip rotation angle in radians (optional, defaults to 0)\n * @param kickHipState - Hip rotation state for kicks (optional, for kick-specific power)\n * @returns Comprehensive damage result with all modifiers applied\n *\n * @example\n * ```typescript\n * const result = DamageCalculator.calculateEnhancedVitalPointDamage(\n * attackerState,\n * defenderState,\n * technique,\n * vitalPointHitResult,\n * 2, // 2 AM - liver meridian peak\n * { liver: 1.0, gallbladder: 0.8 }\n * );\n * console.log(`Final damage: ${result.damage}`);\n * console.log(`Critical hit: ${result.isCritical}`);\n * ```\n *\n * @public\n * @korean 종합급소피해계산\n */\n static calculateEnhancedVitalPointDamage(\n attacker: PlayerState,\n defender: PlayerState,\n technique: KoreanTechnique,\n vitalPointHit: VitalPointHitResult,\n currentHour: number,\n meridianStates: Record<string, number>,\n hipRotationAngle: number = 0,\n kickHipState?: HipRotationState,\n ): DamageResult {\n // 1. Base damage from technique\n const attackerStrength = attacker.attackPower || 50;\n const techniquePower = technique.damage || 15;\n const baseDamage = attackerStrength * (techniquePower / 10);\n\n // 2. Stance effectiveness (攻克关系)\n const stanceEffectiveness = TrigramCalculator.calculateStanceEffectiveness(\n attacker.currentStance,\n defender.currentStance,\n );\n\n // 3. Vital point severity multiplier\n const vitalPointMultiplier = vitalPointHit.vitalPointHit\n ? (DamageCalculator.SEVERITY_MULTIPLIERS[vitalPointHit.severity] ?? 1)\n : 1;\n\n // 4. Accuracy bonus (better aim = more damage)\n // Maps 0.0-1.0 accuracy to 0.8x-1.2x multiplier\n const accuracy = vitalPointHit.accuracy ?? 0.5;\n const accuracyBonus =\n DamageCalculator.ACCURACY_MIN_MULTIPLIER +\n accuracy * DamageCalculator.ACCURACY_RANGE;\n\n // 5. Meridian flow bonus\n const meridianBonus = DamageCalculator.calculateMeridianDamageBonus(\n vitalPointHit.vitalPointHit?.id ?? \"\",\n currentHour,\n meridianStates,\n );\n\n // 6. Time-of-day bonus (Dark Ops techniques at night)\n const timeBonus = DamageCalculator.calculateTimeBonus(\n technique,\n currentHour,\n );\n\n // 7. Archetype-specific bonus\n const archetypeBonus = DamageCalculator.getArchetypeDamageBonus(\n attacker.archetype,\n technique,\n vitalPointHit.vitalPointHit,\n );\n\n // 8. Hip rotation power modifier (허리회전 파워 보너스)\n // Determine technique type for appropriate modifier calculation\n let hipRotationModifier = 1.0;\n\n // Check if this is a kick technique and we have kick-specific hip state\n const techniqueName =\n technique.name?.english || technique.englishName || \"\";\n const isKickTechnique =\n technique.type === \"kick\" || techniqueName.toLowerCase().includes(\"kick\");\n\n if (kickHipState && isKickTechnique) {\n // Use advanced kick-specific hip rotation calculation (up to 40% bonus)\n const kickType = DamageCalculator.determineKickType(techniqueName);\n hipRotationModifier = calculateKickPowerFromHipRotation(\n kickHipState,\n kickType,\n );\n } else if (hipRotationAngle !== 0) {\n // Use general hip rotation for strikes/throws/joints (up to 30% bonus)\n const techniqueType: \"strike\" | \"throw\" | \"joint\" =\n technique.type === \"throw\"\n ? \"throw\"\n : technique.type === \"joint_lock\"\n ? \"joint\"\n : \"strike\";\n hipRotationModifier = calculateHipRotationPowerModifier(\n hipRotationAngle,\n techniqueType,\n );\n }\n\n // 9. Critical hit (accuracy > 0.9)\n const criticalMultiplier = accuracy > 0.9 ? 2.0 : 1.0;\n const isCritical = accuracy > 0.9;\n\n // 10. Calculate total damage before defense\n let totalDamage =\n baseDamage *\n stanceEffectiveness *\n vitalPointMultiplier *\n accuracyBonus *\n meridianBonus *\n timeBonus *\n archetypeBonus *\n hipRotationModifier *\n criticalMultiplier;\n\n // 11. Add damage variance (±10%)\n const variance = 0.9 + Math.random() * 0.2; // 0.9 to 1.1\n totalDamage *= variance;\n\n // 12. Apply defense reduction using existing method for consistency\n const defenderDefense = defender.defense || 0;\n const finalDamage = DamageCalculator.calculateDamageReduction(\n totalDamage,\n defenderDefense,\n false,\n );\n\n // 13. Combine effects from vital point hit\n const effects = vitalPointHit.effects || [];\n\n return {\n damage: Math.max(1, finalDamage), // Minimum 1 damage\n effects,\n isCritical,\n isVitalPoint: !!vitalPointHit.vitalPointHit,\n };\n }\n\n /**\n * Determine kick type from technique name for hip rotation power calculation\n *\n * @param techniqueName - Name of the technique\n * @returns Kick type for hip rotation calculation\n *\n * @private\n * @korean 차기유형결정\n */\n private static determineKickType(techniqueName: string): KickType {\n const name = techniqueName.toLowerCase();\n\n if (\n name.includes(\"front\") ||\n name.includes(\"앞차기\") ||\n name.includes(\"snap\")\n ) {\n return \"front\";\n } else if (\n name.includes(\"roundhouse\") ||\n name.includes(\"돌려차기\") ||\n name.includes(\"round\")\n ) {\n return \"roundhouse\";\n } else if (\n name.includes(\"side\") ||\n name.includes(\"옆차기\") ||\n name.includes(\"lateral\")\n ) {\n return \"side\";\n } else if (name.includes(\"hook\") || name.includes(\"후려차기\")) {\n return \"hook\";\n } else if (\n name.includes(\"axe\") ||\n name.includes(\"내려차기\") ||\n name.includes(\"downward\")\n ) {\n return \"axe\";\n }\n\n // Default to front kick for unknown kick types\n return \"front\";\n }\n\n /**\n * Calculate meridian flow damage bonus based on time of day.\n *\n * **Korean**: 경락 유효성 피해 보너스 계산\n *\n * Calculates bonus damage when striking vital points during their peak\n * meridian flow hours. Peak flow provides +30% damage bonus.\n *\n * @param vitalPointId - ID of the vital point being struck\n * @param currentHour - Current hour of day (0-23)\n * @param meridianStates - Current meridian disruption states\n * @returns Damage multiplier (1.0-1.3)\n *\n * @private\n * @korean 경락유효성피해보너스계산\n */\n private static calculateMeridianDamageBonus(\n vitalPointId: string,\n currentHour: number,\n meridianStates: Record<string, number>,\n ): number {\n if (!vitalPointId) return 1;\n\n const relatedMeridians = getMeridiansForVitalPoint(vitalPointId);\n let maxBonus = 1.0;\n\n for (const meridianId of relatedMeridians) {\n const flow = calculateMeridianFlow(meridianId, currentHour);\n const state = meridianStates[meridianId] ?? 1.0;\n\n // Peak flow (>0.9) with normal state gives +30% bonus\n // flow ranges from 0.7 to 1.3, state from 0 (blocked) to 1 (normal)\n const effectiveFlow = flow * state;\n if (effectiveFlow > 0.9) {\n // Bonus scales linearly from 1.0 (no bonus) at effectiveFlow = 0.9\n // to 1.3 (maximum 30% bonus) at effectiveFlow = 1.3:\n // bonus = 1.0 + ((effectiveFlow - 0.9) / 0.4) * 0.3\n const bonus = 1.0 + ((effectiveFlow - 0.9) / 0.4) * 0.3;\n maxBonus = Math.max(maxBonus, Math.min(1.3, bonus));\n }\n }\n\n return maxBonus;\n }\n\n /**\n * Calculate time-of-day bonus for Dark Ops techniques.\n *\n * **Korean**: 시간대 보너스 계산\n *\n * Dark Ops techniques gain +20% damage at night (20:00-05:59)\n * to reflect tactical advantage of darkness.\n *\n * @param technique - Technique being used\n * @param currentHour - Current hour of day (0-23)\n * @returns Time bonus multiplier (1.0 or 1.2)\n *\n * @private\n * @korean 시간대보너스계산\n */\n private static calculateTimeBonus(\n technique: KoreanTechnique,\n currentHour: number,\n ): number {\n // Dark Ops techniques get +20% at night (20:00-05:59)\n // Check if technique has dark_ops or stealth in its ID or type\n const isDarkOpsTechnique =\n technique.id.includes(\"dark_ops\") ||\n technique.id.includes(\"stealth\") ||\n technique.id.includes(\"shadow\") ||\n technique.id.includes(\"night\");\n\n if (isDarkOpsTechnique) {\n // Night hours: 20:00 through 05:59 (6 AM is considered daylight)\n if (currentHour >= 20 || currentHour < 6) {\n return 1.2;\n }\n }\n return 1.0;\n }\n\n /**\n * Get archetype-specific damage bonus for technique and vital point.\n *\n * **Korean**: 원형 특화 피해 보너스\n *\n * Each archetype has specialized bonuses for different techniques\n * and vital point categories:\n *\n * - **무사 (Musa)**: +20% with 건 (Geon) stance techniques\n * - **암살자 (Amsalja)**: +30% on neurological vital points\n * - **해커 (Hacker)**: +15% baseline precision bonus\n * - **정보요원 (Jeongbo)**: +25% on vascular vital points\n * - **조직폭력배 (Jojik)**: +20% on dirty/ruthless techniques\n *\n * @param archetype - Attacker's archetype\n * @param technique - Technique being used\n * @param vitalPoint - Vital point being struck (optional)\n * @returns Archetype damage multiplier (1.0-1.5)\n *\n * @private\n * @korean 원형특화피해보너스\n */\n private static getArchetypeDamageBonus(\n archetype: PlayerArchetype,\n technique: KoreanTechnique,\n vitalPoint?: VitalPoint,\n ): number {\n // Base archetype modifier\n let bonus = DamageCalculator.getArchetypeModifier(archetype);\n\n // Additional bonuses based on technique-archetype synergy\n switch (archetype) {\n case PlayerArchetype.MUSA:\n // Musa gets bonus with Geon (Heaven) stance techniques\n if (technique.stance === TrigramStance.GEON) {\n bonus *= 1.2;\n }\n break;\n\n case PlayerArchetype.AMSALJA:\n // Assassin gets bonus on neurological vital points\n if (vitalPoint?.category === \"neurological\") {\n bonus *= 1.3;\n }\n break;\n\n case PlayerArchetype.HACKER:\n // Hacker gets consistent precision bonus\n bonus *= 1.15;\n break;\n\n case PlayerArchetype.JEONGBO_YOWON:\n // Intelligence operative gets bonus on vascular targets\n if (vitalPoint?.category === \"vascular\") {\n bonus *= 1.25;\n }\n break;\n\n case PlayerArchetype.JOJIK_POKRYEOKBAE:\n // Organized crime gets bonus on ruthless techniques\n // Check for keywords in technique ID\n if (\n technique.id.includes(\"ruthless\") ||\n technique.id.includes(\"brutal\") ||\n technique.id.includes(\"dirty\")\n ) {\n bonus *= 1.2;\n }\n break;\n }\n\n // Cap maximum bonus at 1.5x\n return Math.min(1.5, bonus);\n }\n\n /**\n * Calculate throw/takedown impact damage with ground multiplier.\n *\n * **Korean**: 던지기 충격 피해 계산 (Throw Impact Damage Calculation)\n *\n * Applies groundImpactMultiplier from Gon (Earth) techniques when opponent\n * hits the ground after a throw or takedown. Integrates with base damage\n * calculation to provide authentic Ssireum/Hapkido throw mechanics.\n *\n * **Formula**:\n * ```\n * impactDamage = baseDamage × groundImpactMultiplier × strengthModifier\n * ```\n *\n * **Ground Impact Multiplier Ranges**:\n * - 1.0-1.2: Low impact (controlled takedowns)\n * - 1.3-1.5: Medium impact (standard throws)\n * - 1.6-1.8: High impact (power throws)\n * - 1.9-2.0: Maximum impact (slams like 대지강타)\n *\n * @param technique - Korean martial arts technique (checks for ExtendedGonTechnique)\n * @param baseDamage - Base damage before ground impact modifier\n * @param attackerStrength - Attacker's strength stat for scaling\n * @param options - Optional configuration for damage calculation\n * @param options.applyVariance - Whether to apply random ±5% variance (default: true)\n * @returns Enhanced damage result with ground impact applied\n *\n * @example\n * ```typescript\n * const throwDamage = DamageCalculator.calculateThrowImpactDamage(\n * ssireumThrowTechnique, // groundImpactMultiplier: 1.7\n * 50, // base damage\n * 80 // attacker strength\n * );\n * // Result: ~85 damage (50 × 1.7 × 1.0) with ±5% variance\n *\n * // For deterministic testing:\n * const testDamage = DamageCalculator.calculateThrowImpactDamage(\n * technique, 50, 80, { applyVariance: false }\n * );\n * ```\n *\n * @public\n * @korean 던지기충격피해계산\n */\n static calculateThrowImpactDamage(\n technique: KoreanTechnique,\n baseDamage: number,\n attackerStrength: number = 50,\n options: { applyVariance?: boolean } = {},\n ): DamageResult {\n const { applyVariance = true } = options;\n // Check if technique has Gon-specific ground impact metadata\n // Use helper function for safe type casting\n const gonTechnique = asExtendedGonTechnique(technique);\n if (!gonTechnique) {\n // Non-Gon technique: return base damage without ground multiplier\n return {\n damage: Math.max(1, baseDamage),\n effects: [],\n isCritical: false,\n isVitalPoint: false,\n };\n }\n\n // Extract ground impact multiplier from validated Gon technique\n const groundMultiplier = gonTechnique.groundImpactMultiplier;\n\n // Calculate strength modifier (50 = baseline, scales ±20%)\n // Stronger attackers create more impact, weaker create less\n const strengthModifier = 0.8 + (attackerStrength / 250);\n\n // Apply ground impact multiplier with strength scaling\n let impactDamage = baseDamage * groundMultiplier * strengthModifier;\n\n // Add small damage variance (±5%) for realistic impact variation\n // Can be disabled for deterministic testing\n if (applyVariance) {\n const variance = 0.95 + Math.random() * 0.1; // 0.95 to 1.05\n impactDamage *= variance;\n }\n\n // Earth connection healing (대지는 모든 것을 품고 키운다)\n // Supportive healing is applied separately by calling system\n // This method focuses on damage calculation only\n\n return {\n damage: Math.max(1, Math.floor(impactDamage)),\n effects: [],\n isCritical: impactDamage > baseDamage * 1.5, // High impact = critical\n isVitalPoint: false,\n };\n }\n\n /**\n * Calculate earth's supportive healing from Gon technique.\n *\n * **Korean**: 대지 치유 계산 (Earth Healing Calculation)\n *\n * Implements Korean martial arts philosophy:\n * \"대지는 모든 것을 품고 키운다\" (The earth embraces and nurtures all things)\n *\n * Gon techniques restore HP to the attacker after successful execution\n * based on their connection with earth energy. Traditional techniques\n * like Ssireum throws provide stronger healing due to cultural authenticity.\n *\n * **Healing Formula**:\n * ```\n * healingAmount = supportiveHealing × (1 + earthAffinityBonus)\n * ```\n *\n * **Supportive Healing Ranges**:\n * - 0-2: Minimal earth connection (aggressive techniques)\n * - 3-4: Moderate earth connection (standard Ssireum)\n * - 5-6: Strong earth connection (traditional, sacrifice throws)\n * - 7-10: RESERVED for meditation/healing techniques\n *\n * @param technique - Korean martial arts technique (checks for ExtendedGonTechnique)\n * @param earthAffinityBonus - Player's earth affinity stat modifier (0.0-1.0)\n * @returns HP healing amount (0 if not a Gon technique)\n *\n * @example\n * ```typescript\n * const healing = DamageCalculator.calculateEarthHealing(\n * ssireumThrowTechnique, // supportiveHealing: 5\n * 0.3 // 30% earth affinity bonus\n * );\n * // Result: 6.5 HP restored (5 × 1.3)\n * ```\n *\n * @public\n * @korean 대지치유계산\n */\n static calculateEarthHealing(\n technique: KoreanTechnique,\n earthAffinityBonus: number = 0,\n ): number {\n // Use helper function for safe type casting\n const gonTechnique = asExtendedGonTechnique(technique);\n if (!gonTechnique) {\n return 0; // Non-Gon technique: no earth healing\n }\n\n const baseHealing = gonTechnique.supportiveHealing;\n\n // Apply earth affinity bonus (typically 0-100% bonus)\n const affinityMultiplier = 1 + Math.max(0, Math.min(1, earthAffinityBonus));\n\n // Calculate final healing with bonus\n const healingAmount = baseHealing * affinityMultiplier;\n\n // Return rounded healing value (minimum 0)\n return Math.max(0, Math.floor(healingAmount));\n }\n}\n\nexport default DamageCalculator;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HitDetection.js","names":[],"sources":["../../../src/systems/vitalpoint/HitDetection.ts"],"sourcesContent":["import type { Position } from \"../../types/common\";\nimport { VitalPoint, VitalPointEffect, VitalPointHitResult } from \"./types\";\n// Fix: Import both EffectIntensity type and enum from the correct location\nimport { VitalPointEffectType, VitalPointSeverity } from \"../../types/common\";\nimport { EffectIntensity, EffectType } from \"../effects\";\nimport { StatusEffect } from \"../types\";\n\nexport class HitDetection {\n /**\n * Convert VitalPointEffect to StatusEffect with required properties\n */\n private static convertVitalPointEffectToStatusEffect(\n vitalPointEffect: VitalPointEffect,\n vitalPointId: string\n ): StatusEffect {\n const currentTime = Date.now();\n\n // Fix: Use EffectType from effects.ts (string literals)\n const typeMapping: Record<VitalPointEffectType, EffectType> = {\n [VitalPointEffectType.UNCONSCIOUSNESS]: \"stun\",\n [VitalPointEffectType.BREATHLESSNESS]: \"stamina_drain\",\n [VitalPointEffectType.PAIN]: \"weakened\",\n [VitalPointEffectType.PARALYSIS]: \"paralysis\",\n [VitalPointEffectType.STUN]: \"stun\",\n [VitalPointEffectType.WEAKNESS]: \"weakened\",\n [VitalPointEffectType.DISORIENTATION]: \"confusion\",\n [VitalPointEffectType.BLOOD_FLOW_RESTRICTION]: \"bleed\",\n [VitalPointEffectType.NERVE_DISRUPTION]: \"paralysis\",\n [VitalPointEffectType.ORGAN_DISRUPTION]: \"vulnerability\",\n };\n\n // Fix: Use the correct EffectIntensity enum values from enums.ts\n const intensityMapping: Record<EffectIntensity, EffectIntensity> = {\n [EffectIntensity.WEAK]: EffectIntensity.WEAK,\n [EffectIntensity.MINOR]: EffectIntensity.MINOR,\n [EffectIntensity.LOW]: EffectIntensity.LOW,\n [EffectIntensity.MEDIUM]: EffectIntensity.MEDIUM,\n [EffectIntensity.MODERATE]: EffectIntensity.MODERATE,\n [EffectIntensity.HIGH]: EffectIntensity.HIGH,\n [EffectIntensity.SEVERE]: EffectIntensity.SEVERE,\n [EffectIntensity.CRITICAL]: EffectIntensity.CRITICAL,\n [EffectIntensity.EXTREME]: EffectIntensity.EXTREME,\n };\n\n return {\n id: `${vitalPointEffect.id}_${currentTime}`,\n type: typeMapping[vitalPointEffect.type] || \"weakened\",\n intensity:\n intensityMapping[vitalPointEffect.intensity] || EffectIntensity.MEDIUM,\n duration: vitalPointEffect.duration,\n description: vitalPointEffect.description,\n stackable: vitalPointEffect.stackable,\n source: vitalPointId,\n startTime: currentTime,\n endTime: currentTime + vitalPointEffect.duration,\n };\n }\n\n processVitalPointHit(\n vitalPoint: VitalPoint,\n hitPosition: Position,\n force: number\n ): VitalPointHitResult {\n // Calculate hit accuracy\n const distance = Math.sqrt(\n Math.pow(hitPosition.x - vitalPoint.position.x, 2) +\n Math.pow(hitPosition.y - vitalPoint.position.y, 2)\n );\n\n // Fix: Provide default values for potentially undefined properties\n const radius = vitalPoint.radius ?? 10; // Default radius\n const requiredForce = vitalPoint.requiredForce ?? 50; // Default force requirement\n\n const isHit = distance <= radius;\n\n if (!isHit) {\n return {\n hit: false,\n damage: 0,\n effects: [],\n severity: VitalPointSeverity.MINOR,\n };\n }\n\n // Calculate damage\n const baseDamage = vitalPoint.baseDamage ?? 15;\n const forceMultiplier = Math.min(force / requiredForce, 2.0);\n const damage = Math.floor(baseDamage * forceMultiplier);\n\n // Convert VitalPointEffect array to StatusEffect array\n const effects = vitalPoint.effects.map((effect) =>\n HitDetection.convertVitalPointEffectToStatusEffect(effect, vitalPoint.id)\n );\n\n return {\n hit: true,\n vitalPoint,\n damage,\n effects,\n severity: vitalPoint.severity,\n };\n }\n}\n\nexport default HitDetection;\n"],"mappings":";;;AAOA,IAAa,eAAb,MAAa,aAAa;;;;CAIxB,OAAe,sCACb,kBACA,cACc;EACd,MAAM,cAAc,KAAK,KAAK;EAG9B,MAAM,cAAwD;IAC3D,qBAAqB,kBAAkB;IACvC,qBAAqB,iBAAiB;IACtC,qBAAqB,OAAO;IAC5B,qBAAqB,YAAY;IACjC,qBAAqB,OAAO;IAC5B,qBAAqB,WAAW;IAChC,qBAAqB,iBAAiB;IACtC,qBAAqB,yBAAyB;IAC9C,qBAAqB,mBAAmB;IACxC,qBAAqB,mBAAmB;GAC1C;EAGD,MAAM,mBAA6D;IAChE,gBAAgB,OAAO,gBAAgB;IACvC,gBAAgB,QAAQ,gBAAgB;IACxC,gBAAgB,MAAM,gBAAgB;IACtC,gBAAgB,SAAS,gBAAgB;IACzC,gBAAgB,WAAW,gBAAgB;IAC3C,gBAAgB,OAAO,gBAAgB;IACvC,gBAAgB,SAAS,gBAAgB;IACzC,gBAAgB,WAAW,gBAAgB;IAC3C,gBAAgB,UAAU,gBAAgB;GAC5C;
|
|
1
|
+
{"version":3,"file":"HitDetection.js","names":[],"sources":["../../../src/systems/vitalpoint/HitDetection.ts"],"sourcesContent":["import type { Position } from \"../../types/common\";\nimport { VitalPoint, VitalPointEffect, VitalPointHitResult } from \"./types\";\n// Fix: Import both EffectIntensity type and enum from the correct location\nimport { VitalPointEffectType, VitalPointSeverity } from \"../../types/common\";\nimport { EffectIntensity, EffectType } from \"../effects\";\nimport { StatusEffect } from \"../types\";\n\nexport class HitDetection {\n /**\n * Convert VitalPointEffect to StatusEffect with required properties\n */\n private static convertVitalPointEffectToStatusEffect(\n vitalPointEffect: VitalPointEffect,\n vitalPointId: string\n ): StatusEffect {\n const currentTime = Date.now();\n\n // Fix: Use EffectType from effects.ts (string literals)\n const typeMapping: Record<VitalPointEffectType, EffectType> = {\n [VitalPointEffectType.UNCONSCIOUSNESS]: \"stun\",\n [VitalPointEffectType.BREATHLESSNESS]: \"stamina_drain\",\n [VitalPointEffectType.PAIN]: \"weakened\",\n [VitalPointEffectType.PARALYSIS]: \"paralysis\",\n [VitalPointEffectType.STUN]: \"stun\",\n [VitalPointEffectType.WEAKNESS]: \"weakened\",\n [VitalPointEffectType.DISORIENTATION]: \"confusion\",\n [VitalPointEffectType.BLOOD_FLOW_RESTRICTION]: \"bleed\",\n [VitalPointEffectType.NERVE_DISRUPTION]: \"paralysis\",\n [VitalPointEffectType.ORGAN_DISRUPTION]: \"vulnerability\",\n };\n\n // Fix: Use the correct EffectIntensity enum values from enums.ts\n const intensityMapping: Record<EffectIntensity, EffectIntensity> = {\n [EffectIntensity.WEAK]: EffectIntensity.WEAK,\n [EffectIntensity.MINOR]: EffectIntensity.MINOR,\n [EffectIntensity.LOW]: EffectIntensity.LOW,\n [EffectIntensity.MEDIUM]: EffectIntensity.MEDIUM,\n [EffectIntensity.MODERATE]: EffectIntensity.MODERATE,\n [EffectIntensity.HIGH]: EffectIntensity.HIGH,\n [EffectIntensity.SEVERE]: EffectIntensity.SEVERE,\n [EffectIntensity.CRITICAL]: EffectIntensity.CRITICAL,\n [EffectIntensity.EXTREME]: EffectIntensity.EXTREME,\n };\n\n return {\n id: `${vitalPointEffect.id}_${currentTime}`,\n type: typeMapping[vitalPointEffect.type] || \"weakened\",\n intensity:\n intensityMapping[vitalPointEffect.intensity] || EffectIntensity.MEDIUM,\n duration: vitalPointEffect.duration,\n description: vitalPointEffect.description,\n stackable: vitalPointEffect.stackable,\n source: vitalPointId,\n startTime: currentTime,\n endTime: currentTime + vitalPointEffect.duration,\n };\n }\n\n processVitalPointHit(\n vitalPoint: VitalPoint,\n hitPosition: Position,\n force: number\n ): VitalPointHitResult {\n // Calculate hit accuracy\n const distance = Math.sqrt(\n Math.pow(hitPosition.x - vitalPoint.position.x, 2) +\n Math.pow(hitPosition.y - vitalPoint.position.y, 2)\n );\n\n // Fix: Provide default values for potentially undefined properties\n const radius = vitalPoint.radius ?? 10; // Default radius\n const requiredForce = vitalPoint.requiredForce ?? 50; // Default force requirement\n\n const isHit = distance <= radius;\n\n if (!isHit) {\n return {\n hit: false,\n damage: 0,\n effects: [],\n severity: VitalPointSeverity.MINOR,\n };\n }\n\n // Calculate damage\n const baseDamage = vitalPoint.baseDamage ?? 15;\n const forceMultiplier = Math.min(force / requiredForce, 2.0);\n const damage = Math.floor(baseDamage * forceMultiplier);\n\n // Convert VitalPointEffect array to StatusEffect array\n const effects = vitalPoint.effects.map((effect) =>\n HitDetection.convertVitalPointEffectToStatusEffect(effect, vitalPoint.id)\n );\n\n return {\n hit: true,\n vitalPoint,\n damage,\n effects,\n severity: vitalPoint.severity,\n };\n }\n}\n\nexport default HitDetection;\n"],"mappings":";;;AAOA,IAAa,eAAb,MAAa,aAAa;;;;CAIxB,OAAe,sCACb,kBACA,cACc;EACd,MAAM,cAAc,KAAK,KAAK;EAG9B,MAAM,cAAwD;IAC3D,qBAAqB,kBAAkB;IACvC,qBAAqB,iBAAiB;IACtC,qBAAqB,OAAO;IAC5B,qBAAqB,YAAY;IACjC,qBAAqB,OAAO;IAC5B,qBAAqB,WAAW;IAChC,qBAAqB,iBAAiB;IACtC,qBAAqB,yBAAyB;IAC9C,qBAAqB,mBAAmB;IACxC,qBAAqB,mBAAmB;GAC1C;EAGD,MAAM,mBAA6D;IAChE,gBAAgB,OAAO,gBAAgB;IACvC,gBAAgB,QAAQ,gBAAgB;IACxC,gBAAgB,MAAM,gBAAgB;IACtC,gBAAgB,SAAS,gBAAgB;IACzC,gBAAgB,WAAW,gBAAgB;IAC3C,gBAAgB,OAAO,gBAAgB;IACvC,gBAAgB,SAAS,gBAAgB;IACzC,gBAAgB,WAAW,gBAAgB;IAC3C,gBAAgB,UAAU,gBAAgB;GAC5C;EAED,OAAO;GACL,IAAI,GAAG,iBAAiB,GAAG,GAAG;GAC9B,MAAM,YAAY,iBAAiB,SAAS;GAC5C,WACE,iBAAiB,iBAAiB,cAAc,gBAAgB;GAClE,UAAU,iBAAiB;GAC3B,aAAa,iBAAiB;GAC9B,WAAW,iBAAiB;GAC5B,QAAQ;GACR,WAAW;GACX,SAAS,cAAc,iBAAiB;GACzC;;CAGH,qBACE,YACA,aACA,OACqB;EAErB,MAAM,WAAW,KAAK,KACpB,KAAK,IAAI,YAAY,IAAI,WAAW,SAAS,GAAG,EAAE,GAChD,KAAK,IAAI,YAAY,IAAI,WAAW,SAAS,GAAG,EAAE,CACrD;EAGD,MAAM,SAAS,WAAW,UAAU;EACpC,MAAM,gBAAgB,WAAW,iBAAiB;EAIlD,IAAI,EAFU,YAAY,SAGxB,OAAO;GACL,KAAK;GACL,QAAQ;GACR,SAAS,EAAE;GACX,UAAU,mBAAmB;GAC9B;EAIH,MAAM,aAAa,WAAW,cAAc;EAC5C,MAAM,kBAAkB,KAAK,IAAI,QAAQ,eAAe,EAAI;EAQ5D,OAAO;GACL,KAAK;GACL;GACA,QAVa,KAAK,MAAM,aAAa,gBAUrC;GACA,SARc,WAAW,QAAQ,KAAK,WACtC,aAAa,sCAAsC,QAAQ,WAAW,GAAG,CAOzE;GACA,UAAU,WAAW;GACtB"}
|