blacktrigram 0.7.39 → 0.7.41
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 +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KoreanTechniques.js","names":[],"sources":["../../../src/systems/trigram/KoreanTechniques.ts"],"sourcesContent":["import { PlayerArchetype } from \"../../types\";\nimport { TrigramStance } from \"../../types/common\";\nimport { PlayerState } from \"../player\";\nimport { PLAYER_ARCHETYPES_DATA } from \"../types\";\nimport { KoreanTechnique } from \"../vitalpoint\";\nimport {\n DARK_OPS_ARCHETYPE_BONUSES,\n DARK_OPS_TECHNIQUES,\n TRIGRAM_TECHNIQUES,\n} from \"./techniques/index\";\n\n/**\n * Korean martial arts techniques system\n */\nexport class KoreanTechniquesSystem {\n /**\n * Get available techniques for a trigram stance\n */\n static getAvailableTechniques(\n stance: TrigramStance\n ): readonly KoreanTechnique[] {\n return (TRIGRAM_TECHNIQUES[stance] as readonly KoreanTechnique[]) || [];\n }\n\n /**\n * Get Dark Ops techniques (암흑작전부대 기술)\n * Specialized techniques for 암살자 (Amsalja) archetype\n */\n static getDarkOpsTechniques(): readonly KoreanTechnique[] {\n return DARK_OPS_TECHNIQUES;\n }\n\n /**\n * Get all available techniques including Dark Ops\n */\n static getAllAvailableTechniques(\n stance: TrigramStance,\n archetype?: PlayerArchetype\n ): readonly KoreanTechnique[] {\n const stanceTechniques = this.getAvailableTechniques(stance);\n\n // Add Dark Ops techniques for 암살자 (Amsalja) archetype\n if (archetype === PlayerArchetype.AMSALJA) {\n const darkOpsTechniques = DARK_OPS_TECHNIQUES.filter(\n (tech) => tech.stance === stance\n );\n return [...stanceTechniques, ...darkOpsTechniques];\n }\n\n return stanceTechniques;\n }\n\n /**\n * Get primary technique for stance\n */\n static getPrimaryTechnique(stance: TrigramStance): KoreanTechnique | null {\n const techniques = this.getAvailableTechniques(stance);\n return techniques[0] ?? null;\n }\n\n /**\n * Check if player can execute technique\n */\n static canExecuteTechnique(\n player: PlayerState,\n technique: KoreanTechnique\n ): boolean {\n return (\n player.ki >= technique.kiCost &&\n player.stamina >= technique.staminaCost &&\n player.currentStance === technique.stance\n );\n }\n\n /**\n * Get technique effectiveness against target stance\n */\n static getTechniqueEffectiveness(\n attackerStance: TrigramStance,\n defenderStance: TrigramStance\n ): number {\n return (\n TECHNIQUE_EFFECTIVENESS_MATRIX[attackerStance]?.[defenderStance] ?? 1.0\n );\n }\n\n /**\n * Get all techniques\n */\n static getAllTechniques(): KoreanTechnique[] {\n // Fix: Convert readonly array to mutable array using spread operator\n const stanceTechniques = Object.values(TRIGRAM_TECHNIQUES).flat();\n const darkOpsTechniques = [...DARK_OPS_TECHNIQUES];\n return [...stanceTechniques, ...darkOpsTechniques] as KoreanTechnique[];\n }\n\n static getTechniquesByArchetype(\n archetype: PlayerArchetype\n ): readonly KoreanTechnique[] {\n const allTechniques = this.getAllTechniques();\n\n // Filter techniques based on archetype preferences\n const archetypeData = PLAYER_ARCHETYPES_DATA[archetype]; // Fix: Now properly imported\n const favoredStances = archetypeData.favoredStances || [];\n\n // Filter by favored stances (excludes Dark Ops techniques initially)\n const filteredTechniques = allTechniques.filter((technique) => {\n // Exclude Dark Ops from initial filtering\n if (technique.id.startsWith(\"darkops_\")) {\n return false;\n }\n return favoredStances.includes(technique.stance);\n });\n\n // Add Dark Ops techniques for 암살자 (Amsalja) only\n if (archetype === PlayerArchetype.AMSALJA) {\n return [...filteredTechniques, ...DARK_OPS_TECHNIQUES];\n }\n\n return filteredTechniques;\n }\n\n static getTechniqueById(id: string): KoreanTechnique | undefined {\n const allTechniques = this.getAllTechniques();\n return allTechniques.find((technique) => technique.id === id);\n }\n\n /**\n * Check if technique is a Dark Ops technique\n */\n static isDarkOpsTechnique(techniqueId: string): boolean {\n return DARK_OPS_TECHNIQUES.some((tech) => tech.id === techniqueId);\n }\n\n /**\n * Get Dark Ops archetype effectiveness multiplier\n * Uses DARK_OPS_ARCHETYPE_BONUSES from techniques.ts\n */\n static getDarkOpsArchetypeBonus(archetype: PlayerArchetype): number {\n return DARK_OPS_ARCHETYPE_BONUSES[archetype] || 1.0;\n }\n\n /**\n * Get night operations bonus (simulated)\n * In a full game, this would use actual game time\n */\n static getNightOperationsBonus(): number {\n // Simulate night time for now (in real game, use game clock)\n // Night: 00:00-06:00, 18:00-23:59 = 1.25x\n // Day: 06:00-18:00 = 1.0x\n const hour = new Date().getHours();\n if (hour >= 0 && hour < 6) return 1.25; // Night\n if (hour >= 18 && hour < 24) return 1.25; // Night\n if (hour >= 5 && hour < 7) return 1.15; // Twilight\n if (hour >= 17 && hour < 19) return 1.15; // Twilight\n return 1.0; // Day\n }\n}\n\n// Export functions for backwards compatibility\nexport function getTechniquesByStance(\n stance: TrigramStance\n): KoreanTechnique[] {\n // Fix: Convert readonly array to mutable array\n return [\n ...((TRIGRAM_TECHNIQUES[stance] as unknown as KoreanTechnique[]) || []),\n ];\n}\n\n// Export TRIGRAM_TECHNIQUES for tests\nexport { DARK_OPS_TECHNIQUES, TRIGRAM_TECHNIQUES } from \"./techniques/index\";\n\n// Export Dark Ops constants\nexport {\n DARK_OPS_ARCHETYPE_BONUSES,\n DARK_OPS_NIGHT_BONUS,\n DARK_OPS_SPECIAL_EFFECTS,\n DARK_OPS_UNITS,\n} from \"./techniques/index\";\n\n// Export technique effectiveness matrix\nexport const TECHNIQUE_EFFECTIVENESS_MATRIX: Record<\n TrigramStance,\n Partial<Record<TrigramStance, number>>\n> = {\n [TrigramStance.GEON]: {\n [TrigramStance.GON]: 1.2,\n [TrigramStance.SON]: 0.8,\n },\n [TrigramStance.TAE]: {\n [TrigramStance.JIN]: 1.2,\n [TrigramStance.GAN]: 0.8,\n },\n [TrigramStance.LI]: {\n [TrigramStance.GAM]: 1.2,\n [TrigramStance.TAE]: 0.8,\n },\n [TrigramStance.JIN]: {\n [TrigramStance.SON]: 1.2,\n [TrigramStance.GEON]: 0.8,\n },\n [TrigramStance.SON]: {\n [TrigramStance.GON]: 1.2,\n [TrigramStance.LI]: 0.8,\n },\n [TrigramStance.GAM]: {\n [TrigramStance.LI]: 1.2,\n [TrigramStance.JIN]: 0.8,\n },\n [TrigramStance.GAN]: {\n [TrigramStance.TAE]: 1.2,\n [TrigramStance.GAM]: 0.8,\n },\n [TrigramStance.GON]: {\n [TrigramStance.GEON]: 1.2,\n [TrigramStance.SON]: 0.8,\n },\n};\n"],"mappings":";;;;;;;;AAcA,IAAa,yBAAb,MAAoC;;;;CAIlC,OAAO,uBACL,QAC4B;
|
|
1
|
+
{"version":3,"file":"KoreanTechniques.js","names":[],"sources":["../../../src/systems/trigram/KoreanTechniques.ts"],"sourcesContent":["import { PlayerArchetype } from \"../../types\";\nimport { TrigramStance } from \"../../types/common\";\nimport { PlayerState } from \"../player\";\nimport { PLAYER_ARCHETYPES_DATA } from \"../types\";\nimport { KoreanTechnique } from \"../vitalpoint\";\nimport {\n DARK_OPS_ARCHETYPE_BONUSES,\n DARK_OPS_TECHNIQUES,\n TRIGRAM_TECHNIQUES,\n} from \"./techniques/index\";\n\n/**\n * Korean martial arts techniques system\n */\nexport class KoreanTechniquesSystem {\n /**\n * Get available techniques for a trigram stance\n */\n static getAvailableTechniques(\n stance: TrigramStance\n ): readonly KoreanTechnique[] {\n return (TRIGRAM_TECHNIQUES[stance] as readonly KoreanTechnique[]) || [];\n }\n\n /**\n * Get Dark Ops techniques (암흑작전부대 기술)\n * Specialized techniques for 암살자 (Amsalja) archetype\n */\n static getDarkOpsTechniques(): readonly KoreanTechnique[] {\n return DARK_OPS_TECHNIQUES;\n }\n\n /**\n * Get all available techniques including Dark Ops\n */\n static getAllAvailableTechniques(\n stance: TrigramStance,\n archetype?: PlayerArchetype\n ): readonly KoreanTechnique[] {\n const stanceTechniques = this.getAvailableTechniques(stance);\n\n // Add Dark Ops techniques for 암살자 (Amsalja) archetype\n if (archetype === PlayerArchetype.AMSALJA) {\n const darkOpsTechniques = DARK_OPS_TECHNIQUES.filter(\n (tech) => tech.stance === stance\n );\n return [...stanceTechniques, ...darkOpsTechniques];\n }\n\n return stanceTechniques;\n }\n\n /**\n * Get primary technique for stance\n */\n static getPrimaryTechnique(stance: TrigramStance): KoreanTechnique | null {\n const techniques = this.getAvailableTechniques(stance);\n return techniques[0] ?? null;\n }\n\n /**\n * Check if player can execute technique\n */\n static canExecuteTechnique(\n player: PlayerState,\n technique: KoreanTechnique\n ): boolean {\n return (\n player.ki >= technique.kiCost &&\n player.stamina >= technique.staminaCost &&\n player.currentStance === technique.stance\n );\n }\n\n /**\n * Get technique effectiveness against target stance\n */\n static getTechniqueEffectiveness(\n attackerStance: TrigramStance,\n defenderStance: TrigramStance\n ): number {\n return (\n TECHNIQUE_EFFECTIVENESS_MATRIX[attackerStance]?.[defenderStance] ?? 1.0\n );\n }\n\n /**\n * Get all techniques\n */\n static getAllTechniques(): KoreanTechnique[] {\n // Fix: Convert readonly array to mutable array using spread operator\n const stanceTechniques = Object.values(TRIGRAM_TECHNIQUES).flat();\n const darkOpsTechniques = [...DARK_OPS_TECHNIQUES];\n return [...stanceTechniques, ...darkOpsTechniques] as KoreanTechnique[];\n }\n\n static getTechniquesByArchetype(\n archetype: PlayerArchetype\n ): readonly KoreanTechnique[] {\n const allTechniques = this.getAllTechniques();\n\n // Filter techniques based on archetype preferences\n const archetypeData = PLAYER_ARCHETYPES_DATA[archetype]; // Fix: Now properly imported\n const favoredStances = archetypeData.favoredStances || [];\n\n // Filter by favored stances (excludes Dark Ops techniques initially)\n const filteredTechniques = allTechniques.filter((technique) => {\n // Exclude Dark Ops from initial filtering\n if (technique.id.startsWith(\"darkops_\")) {\n return false;\n }\n return favoredStances.includes(technique.stance);\n });\n\n // Add Dark Ops techniques for 암살자 (Amsalja) only\n if (archetype === PlayerArchetype.AMSALJA) {\n return [...filteredTechniques, ...DARK_OPS_TECHNIQUES];\n }\n\n return filteredTechniques;\n }\n\n static getTechniqueById(id: string): KoreanTechnique | undefined {\n const allTechniques = this.getAllTechniques();\n return allTechniques.find((technique) => technique.id === id);\n }\n\n /**\n * Check if technique is a Dark Ops technique\n */\n static isDarkOpsTechnique(techniqueId: string): boolean {\n return DARK_OPS_TECHNIQUES.some((tech) => tech.id === techniqueId);\n }\n\n /**\n * Get Dark Ops archetype effectiveness multiplier\n * Uses DARK_OPS_ARCHETYPE_BONUSES from techniques.ts\n */\n static getDarkOpsArchetypeBonus(archetype: PlayerArchetype): number {\n return DARK_OPS_ARCHETYPE_BONUSES[archetype] || 1.0;\n }\n\n /**\n * Get night operations bonus (simulated)\n * In a full game, this would use actual game time\n */\n static getNightOperationsBonus(): number {\n // Simulate night time for now (in real game, use game clock)\n // Night: 00:00-06:00, 18:00-23:59 = 1.25x\n // Day: 06:00-18:00 = 1.0x\n const hour = new Date().getHours();\n if (hour >= 0 && hour < 6) return 1.25; // Night\n if (hour >= 18 && hour < 24) return 1.25; // Night\n if (hour >= 5 && hour < 7) return 1.15; // Twilight\n if (hour >= 17 && hour < 19) return 1.15; // Twilight\n return 1.0; // Day\n }\n}\n\n// Export functions for backwards compatibility\nexport function getTechniquesByStance(\n stance: TrigramStance\n): KoreanTechnique[] {\n // Fix: Convert readonly array to mutable array\n return [\n ...((TRIGRAM_TECHNIQUES[stance] as unknown as KoreanTechnique[]) || []),\n ];\n}\n\n// Export TRIGRAM_TECHNIQUES for tests\nexport { DARK_OPS_TECHNIQUES, TRIGRAM_TECHNIQUES } from \"./techniques/index\";\n\n// Export Dark Ops constants\nexport {\n DARK_OPS_ARCHETYPE_BONUSES,\n DARK_OPS_NIGHT_BONUS,\n DARK_OPS_SPECIAL_EFFECTS,\n DARK_OPS_UNITS,\n} from \"./techniques/index\";\n\n// Export technique effectiveness matrix\nexport const TECHNIQUE_EFFECTIVENESS_MATRIX: Record<\n TrigramStance,\n Partial<Record<TrigramStance, number>>\n> = {\n [TrigramStance.GEON]: {\n [TrigramStance.GON]: 1.2,\n [TrigramStance.SON]: 0.8,\n },\n [TrigramStance.TAE]: {\n [TrigramStance.JIN]: 1.2,\n [TrigramStance.GAN]: 0.8,\n },\n [TrigramStance.LI]: {\n [TrigramStance.GAM]: 1.2,\n [TrigramStance.TAE]: 0.8,\n },\n [TrigramStance.JIN]: {\n [TrigramStance.SON]: 1.2,\n [TrigramStance.GEON]: 0.8,\n },\n [TrigramStance.SON]: {\n [TrigramStance.GON]: 1.2,\n [TrigramStance.LI]: 0.8,\n },\n [TrigramStance.GAM]: {\n [TrigramStance.LI]: 1.2,\n [TrigramStance.JIN]: 0.8,\n },\n [TrigramStance.GAN]: {\n [TrigramStance.TAE]: 1.2,\n [TrigramStance.GAM]: 0.8,\n },\n [TrigramStance.GON]: {\n [TrigramStance.GEON]: 1.2,\n [TrigramStance.SON]: 0.8,\n },\n};\n"],"mappings":";;;;;;;;AAcA,IAAa,yBAAb,MAAoC;;;;CAIlC,OAAO,uBACL,QAC4B;EAC5B,OAAQ,mBAAmB,WAA0C,EAAE;;;;;;CAOzE,OAAO,uBAAmD;EACxD,OAAO;;;;;CAMT,OAAO,0BACL,QACA,WAC4B;EAC5B,MAAM,mBAAmB,KAAK,uBAAuB,OAAO;EAG5D,IAAI,cAAc,gBAAgB,SAAS;GACzC,MAAM,oBAAoB,oBAAoB,QAC3C,SAAS,KAAK,WAAW,OAC3B;GACD,OAAO,CAAC,GAAG,kBAAkB,GAAG,kBAAkB;;EAGpD,OAAO;;;;;CAMT,OAAO,oBAAoB,QAA+C;EAExE,OADmB,KAAK,uBAAuB,OACxC,CAAW,MAAM;;;;;CAM1B,OAAO,oBACL,QACA,WACS;EACT,OACE,OAAO,MAAM,UAAU,UACvB,OAAO,WAAW,UAAU,eAC5B,OAAO,kBAAkB,UAAU;;;;;CAOvC,OAAO,0BACL,gBACA,gBACQ;EACR,OACE,+BAA+B,kBAAkB,mBAAmB;;;;;CAOxE,OAAO,mBAAsC;EAE3C,MAAM,mBAAmB,OAAO,OAAO,mBAAmB,CAAC,MAAM;EACjE,MAAM,oBAAoB,CAAC,GAAG,oBAAoB;EAClD,OAAO,CAAC,GAAG,kBAAkB,GAAG,kBAAkB;;CAGpD,OAAO,yBACL,WAC4B;EAC5B,MAAM,gBAAgB,KAAK,kBAAkB;EAI7C,MAAM,iBADgB,uBAAuB,WACR,kBAAkB,EAAE;EAGzD,MAAM,qBAAqB,cAAc,QAAQ,cAAc;GAE7D,IAAI,UAAU,GAAG,WAAW,WAAW,EACrC,OAAO;GAET,OAAO,eAAe,SAAS,UAAU,OAAO;IAChD;EAGF,IAAI,cAAc,gBAAgB,SAChC,OAAO,CAAC,GAAG,oBAAoB,GAAG,oBAAoB;EAGxD,OAAO;;CAGT,OAAO,iBAAiB,IAAyC;EAE/D,OADsB,KAAK,kBACpB,CAAc,MAAM,cAAc,UAAU,OAAO,GAAG;;;;;CAM/D,OAAO,mBAAmB,aAA8B;EACtD,OAAO,oBAAoB,MAAM,SAAS,KAAK,OAAO,YAAY;;;;;;CAOpE,OAAO,yBAAyB,WAAoC;EAClE,OAAO,2BAA2B,cAAc;;;;;;CAOlD,OAAO,0BAAkC;EAIvC,MAAM,wBAAO,IAAI,MAAM,EAAC,UAAU;EAClC,IAAI,QAAQ,KAAK,OAAO,GAAG,OAAO;EAClC,IAAI,QAAQ,MAAM,OAAO,IAAI,OAAO;EACpC,IAAI,QAAQ,KAAK,OAAO,GAAG,OAAO;EAClC,IAAI,QAAQ,MAAM,OAAO,IAAI,OAAO;EACpC,OAAO;;;AAKX,SAAgB,sBACd,QACmB;CAEnB,OAAO,CACL,GAAK,mBAAmB,WAA4C,EAAE,CACvE;;AAeH,IAAa,iCAGT;EACD,cAAc,OAAO;GACnB,cAAc,MAAM;GACpB,cAAc,MAAM;EACtB;EACA,cAAc,MAAM;GAClB,cAAc,MAAM;GACpB,cAAc,MAAM;EACtB;EACA,cAAc,KAAK;GACjB,cAAc,MAAM;GACpB,cAAc,MAAM;EACtB;EACA,cAAc,MAAM;GAClB,cAAc,MAAM;GACpB,cAAc,OAAO;EACvB;EACA,cAAc,MAAM;GAClB,cAAc,MAAM;GACpB,cAAc,KAAK;EACrB;EACA,cAAc,MAAM;GAClB,cAAc,KAAK;GACnB,cAAc,MAAM;EACtB;EACA,cAAc,MAAM;GAClB,cAAc,MAAM;GACpB,cAAc,MAAM;EACtB;EACA,cAAc,MAAM;GAClB,cAAc,OAAO;GACrB,cAAc,MAAM;EACtB;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StanceManager.js","names":[],"sources":["../../../src/systems/trigram/StanceManager.ts"],"sourcesContent":["import { TrigramStance } from \"../../types/common\";\nimport { PlayerState } from \"../player\";\nimport { PLAYER_ARCHETYPES_DATA } from \"../types\";\nimport { TrigramCalculator } from \"./TrigramCalculator\";\nimport { StanceLaterality, TrigramTransitionCost } from \"./types\";\n\nexport interface StanceChangeResult {\n readonly success: boolean;\n readonly updatedPlayer: PlayerState;\n readonly cost: TrigramTransitionCost;\n readonly laterality?: StanceLaterality;\n readonly message?: string;\n}\n\n/**\n * Manager for trigram stance changes and laterality state\n * \n * **Korean**: 자세 관리자\n * \n * Manages both trigram stance selection (8 stances) and laterality (left/right).\n * Supports authentic Korean martial arts stance configurations with:\n * - 8 trigram stances (☰–☷)\n * - 2 laterality options (left/right foot forward)\n * - 16 total stance configurations\n * \n * Laterality transitions take 400ms (24 frames @ 60fps) and cost 2 stamina.\n */\nexport class StanceManager {\n private readonly minTransitionInterval = 500;\n private readonly lateralityTransitionTime = 400; // 400ms for stance side switch\n private currentStance?: TrigramStance;\n private currentLaterality: StanceLaterality = \"right\"; // Default: right foot forward\n\n constructor() {\n // No initialization needed\n }\n\n /**\n * Get the current stance\n * \n * @returns Current trigram stance or undefined if not set\n * @korean 현재자세가져오기\n */\n public getCurrent(): TrigramStance | undefined {\n return this.currentStance;\n }\n\n /**\n * Get the current stance laterality (left or right foot forward)\n * \n * **Korean**: 현재 측면성\n * \n * @returns Current laterality (\"left\" or \"right\")\n * @korean 현재측면성가져오기\n */\n public getCurrentLaterality(): StanceLaterality {\n return this.currentLaterality;\n }\n\n /**\n * Switch stance side (left ↔ right) without changing trigram stance\n * \n * **Korean**: 자세 측면 전환\n * \n * Mirrors the current guard position from left to right or vice versa.\n * Takes 400ms (24 frames @ 60fps) and costs 2 stamina.\n * \n * Korean terminology:\n * - 왼발서기 (Oenbal Seogi): Left foot forward\n * - 오른발서기 (Oreun Bal Seogi): Right foot forward\n * \n * @param player - Current player state\n * @param currentLaterality - Current laterality to toggle from\n * @returns Result with updated laterality\n * @korean 측면전환\n */\n public switchStanceSide(player: PlayerState, currentLaterality: StanceLaterality): StanceChangeResult {\n const lateralityCost: TrigramTransitionCost = {\n ki: 0,\n stamina: 2,\n timeMilliseconds: this.lateralityTransitionTime,\n };\n\n // Check if player has enough stamina\n if (player.stamina < lateralityCost.stamina) {\n return {\n success: false,\n updatedPlayer: player,\n cost: lateralityCost,\n laterality: currentLaterality,\n message: \"Insufficient stamina to switch stance side\",\n };\n }\n\n // Check cooldown\n const timeSinceLastChange = Date.now() - (player.lastStanceChangeTime || 0);\n if (timeSinceLastChange < this.minTransitionInterval) {\n return {\n success: false,\n updatedPlayer: player,\n cost: lateralityCost,\n laterality: currentLaterality,\n message: \"Stance side switch on cooldown\",\n };\n }\n\n // Switch laterality (toggle from current)\n const newLaterality: StanceLaterality = \n currentLaterality === \"left\" ? \"right\" : \"left\";\n this.currentLaterality = newLaterality;\n\n // Apply stamina cost and update timestamp\n const updatedPlayer: PlayerState = {\n ...player,\n stamina: Math.max(0, player.stamina - lateralityCost.stamina),\n lastStanceChangeTime: Date.now(),\n };\n\n return {\n success: true,\n updatedPlayer,\n cost: lateralityCost,\n laterality: newLaterality,\n };\n }\n\n /**\n * Attempt to change stance\n * \n * @param player - Current player state\n * @param newStance - Target trigram stance\n * @returns Result with success status and updated player\n * @korean 자세변경\n */\n changeStance(\n player: PlayerState,\n newStance: TrigramStance\n ): StanceChangeResult {\n const cost = this.getStanceTransitionCost(\n player.currentStance,\n newStance,\n player\n );\n\n // Check if transition is possible\n if (!this.canChangeStance(player, newStance)) {\n return {\n success: false,\n updatedPlayer: player,\n cost,\n laterality: this.currentLaterality,\n message:\n \"Cannot change stance - insufficient resources or cooldown active\",\n };\n }\n\n // Same stance - no cost, but update laterality info\n if (player.currentStance === newStance) {\n this.currentStance = newStance;\n return {\n success: true,\n updatedPlayer: {\n ...player,\n lastStanceChangeTime: Date.now(),\n },\n cost: { ki: 0, stamina: 0, timeMilliseconds: 0 },\n laterality: this.currentLaterality,\n };\n }\n\n // Apply stance change\n const updatedPlayer: PlayerState = {\n ...player,\n currentStance: newStance,\n ki: Math.max(0, player.ki - cost.ki),\n stamina: Math.max(0, player.stamina - cost.stamina),\n lastStanceChangeTime: Date.now(),\n };\n this.currentStance = newStance;\n\n return {\n success: true,\n updatedPlayer,\n cost,\n laterality: this.currentLaterality,\n };\n }\n\n /**\n * Check if player can change to the specified stance\n */\n canChangeStance(player: PlayerState, newStance: TrigramStance): boolean {\n const cost = this.getStanceTransitionCost(\n player.currentStance,\n newStance,\n player\n );\n\n // Check resources\n if (player.ki < cost.ki || player.stamina < cost.stamina) {\n return false;\n }\n\n // Check cooldown\n const timeSinceLastChange = Date.now() - (player.lastStanceChangeTime || 0);\n if (timeSinceLastChange < this.minTransitionInterval) {\n return false;\n }\n\n // Check if player is stunned or incapacitated\n if (player.isStunned || player.consciousness < 50) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Calculate the cost of transitioning between stances\n */\n getStanceTransitionCost(\n fromStance: TrigramStance,\n toStance: TrigramStance,\n player: PlayerState\n ): TrigramTransitionCost {\n if (fromStance === toStance) {\n return { ki: 0, stamina: 0, timeMilliseconds: 0 };\n }\n\n const baseCost = { ki: 10, stamina: 15, timeMilliseconds: 500 };\n const difficulty = TrigramCalculator.calculateTransitionDifficulty(\n fromStance,\n toStance\n );\n const difficultyMultiplier = 1 + difficulty;\n\n // Apply archetype modifiers\n const archetypeData = PLAYER_ARCHETYPES_DATA[player.archetype];\n const favoredStances = archetypeData.favoredStances || [];\n const archetypeModifier = favoredStances.includes(toStance) ? 0.8 : 1.0;\n\n return {\n ki: Math.floor(baseCost.ki * difficultyMultiplier * archetypeModifier),\n stamina: Math.floor(\n baseCost.stamina * difficultyMultiplier * archetypeModifier\n ),\n timeMilliseconds: Math.floor(\n baseCost.timeMilliseconds * difficultyMultiplier\n ),\n };\n }\n\n /**\n * Get optimal stance recommendation\n */\n getOptimalStance(player: PlayerState, opponent?: PlayerState): TrigramStance {\n if (opponent) {\n // Get counter stance against opponent\n return TrigramCalculator.getCounterStance(opponent.currentStance);\n }\n\n // Default to archetype preferred stance\n const archetypeData = PLAYER_ARCHETYPES_DATA[player.archetype];\n const favoredStances = archetypeData.favoredStances || [];\n\n return favoredStances.length > 0 ? favoredStances[0] : TrigramStance.GEON; // Fix: Use enum value\n }\n\n /**\n * Get all valid transitions from current stance\n */\n getValidTransitions(player: PlayerState): TrigramStance[] {\n return Object.values(TrigramStance).filter(\n (\n stance // Fix: Use enum values\n ) => this.canChangeStance(player, stance)\n );\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"StanceManager.js","names":[],"sources":["../../../src/systems/trigram/StanceManager.ts"],"sourcesContent":["import { TrigramStance } from \"../../types/common\";\nimport { PlayerState } from \"../player\";\nimport { PLAYER_ARCHETYPES_DATA } from \"../types\";\nimport { TrigramCalculator } from \"./TrigramCalculator\";\nimport { StanceLaterality, TrigramTransitionCost } from \"./types\";\n\nexport interface StanceChangeResult {\n readonly success: boolean;\n readonly updatedPlayer: PlayerState;\n readonly cost: TrigramTransitionCost;\n readonly laterality?: StanceLaterality;\n readonly message?: string;\n}\n\n/**\n * Manager for trigram stance changes and laterality state\n * \n * **Korean**: 자세 관리자\n * \n * Manages both trigram stance selection (8 stances) and laterality (left/right).\n * Supports authentic Korean martial arts stance configurations with:\n * - 8 trigram stances (☰–☷)\n * - 2 laterality options (left/right foot forward)\n * - 16 total stance configurations\n * \n * Laterality transitions take 400ms (24 frames @ 60fps) and cost 2 stamina.\n */\nexport class StanceManager {\n private readonly minTransitionInterval = 500;\n private readonly lateralityTransitionTime = 400; // 400ms for stance side switch\n private currentStance?: TrigramStance;\n private currentLaterality: StanceLaterality = \"right\"; // Default: right foot forward\n\n constructor() {\n // No initialization needed\n }\n\n /**\n * Get the current stance\n * \n * @returns Current trigram stance or undefined if not set\n * @korean 현재자세가져오기\n */\n public getCurrent(): TrigramStance | undefined {\n return this.currentStance;\n }\n\n /**\n * Get the current stance laterality (left or right foot forward)\n * \n * **Korean**: 현재 측면성\n * \n * @returns Current laterality (\"left\" or \"right\")\n * @korean 현재측면성가져오기\n */\n public getCurrentLaterality(): StanceLaterality {\n return this.currentLaterality;\n }\n\n /**\n * Switch stance side (left ↔ right) without changing trigram stance\n * \n * **Korean**: 자세 측면 전환\n * \n * Mirrors the current guard position from left to right or vice versa.\n * Takes 400ms (24 frames @ 60fps) and costs 2 stamina.\n * \n * Korean terminology:\n * - 왼발서기 (Oenbal Seogi): Left foot forward\n * - 오른발서기 (Oreun Bal Seogi): Right foot forward\n * \n * @param player - Current player state\n * @param currentLaterality - Current laterality to toggle from\n * @returns Result with updated laterality\n * @korean 측면전환\n */\n public switchStanceSide(player: PlayerState, currentLaterality: StanceLaterality): StanceChangeResult {\n const lateralityCost: TrigramTransitionCost = {\n ki: 0,\n stamina: 2,\n timeMilliseconds: this.lateralityTransitionTime,\n };\n\n // Check if player has enough stamina\n if (player.stamina < lateralityCost.stamina) {\n return {\n success: false,\n updatedPlayer: player,\n cost: lateralityCost,\n laterality: currentLaterality,\n message: \"Insufficient stamina to switch stance side\",\n };\n }\n\n // Check cooldown\n const timeSinceLastChange = Date.now() - (player.lastStanceChangeTime || 0);\n if (timeSinceLastChange < this.minTransitionInterval) {\n return {\n success: false,\n updatedPlayer: player,\n cost: lateralityCost,\n laterality: currentLaterality,\n message: \"Stance side switch on cooldown\",\n };\n }\n\n // Switch laterality (toggle from current)\n const newLaterality: StanceLaterality = \n currentLaterality === \"left\" ? \"right\" : \"left\";\n this.currentLaterality = newLaterality;\n\n // Apply stamina cost and update timestamp\n const updatedPlayer: PlayerState = {\n ...player,\n stamina: Math.max(0, player.stamina - lateralityCost.stamina),\n lastStanceChangeTime: Date.now(),\n };\n\n return {\n success: true,\n updatedPlayer,\n cost: lateralityCost,\n laterality: newLaterality,\n };\n }\n\n /**\n * Attempt to change stance\n * \n * @param player - Current player state\n * @param newStance - Target trigram stance\n * @returns Result with success status and updated player\n * @korean 자세변경\n */\n changeStance(\n player: PlayerState,\n newStance: TrigramStance\n ): StanceChangeResult {\n const cost = this.getStanceTransitionCost(\n player.currentStance,\n newStance,\n player\n );\n\n // Check if transition is possible\n if (!this.canChangeStance(player, newStance)) {\n return {\n success: false,\n updatedPlayer: player,\n cost,\n laterality: this.currentLaterality,\n message:\n \"Cannot change stance - insufficient resources or cooldown active\",\n };\n }\n\n // Same stance - no cost, but update laterality info\n if (player.currentStance === newStance) {\n this.currentStance = newStance;\n return {\n success: true,\n updatedPlayer: {\n ...player,\n lastStanceChangeTime: Date.now(),\n },\n cost: { ki: 0, stamina: 0, timeMilliseconds: 0 },\n laterality: this.currentLaterality,\n };\n }\n\n // Apply stance change\n const updatedPlayer: PlayerState = {\n ...player,\n currentStance: newStance,\n ki: Math.max(0, player.ki - cost.ki),\n stamina: Math.max(0, player.stamina - cost.stamina),\n lastStanceChangeTime: Date.now(),\n };\n this.currentStance = newStance;\n\n return {\n success: true,\n updatedPlayer,\n cost,\n laterality: this.currentLaterality,\n };\n }\n\n /**\n * Check if player can change to the specified stance\n */\n canChangeStance(player: PlayerState, newStance: TrigramStance): boolean {\n const cost = this.getStanceTransitionCost(\n player.currentStance,\n newStance,\n player\n );\n\n // Check resources\n if (player.ki < cost.ki || player.stamina < cost.stamina) {\n return false;\n }\n\n // Check cooldown\n const timeSinceLastChange = Date.now() - (player.lastStanceChangeTime || 0);\n if (timeSinceLastChange < this.minTransitionInterval) {\n return false;\n }\n\n // Check if player is stunned or incapacitated\n if (player.isStunned || player.consciousness < 50) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Calculate the cost of transitioning between stances\n */\n getStanceTransitionCost(\n fromStance: TrigramStance,\n toStance: TrigramStance,\n player: PlayerState\n ): TrigramTransitionCost {\n if (fromStance === toStance) {\n return { ki: 0, stamina: 0, timeMilliseconds: 0 };\n }\n\n const baseCost = { ki: 10, stamina: 15, timeMilliseconds: 500 };\n const difficulty = TrigramCalculator.calculateTransitionDifficulty(\n fromStance,\n toStance\n );\n const difficultyMultiplier = 1 + difficulty;\n\n // Apply archetype modifiers\n const archetypeData = PLAYER_ARCHETYPES_DATA[player.archetype];\n const favoredStances = archetypeData.favoredStances || [];\n const archetypeModifier = favoredStances.includes(toStance) ? 0.8 : 1.0;\n\n return {\n ki: Math.floor(baseCost.ki * difficultyMultiplier * archetypeModifier),\n stamina: Math.floor(\n baseCost.stamina * difficultyMultiplier * archetypeModifier\n ),\n timeMilliseconds: Math.floor(\n baseCost.timeMilliseconds * difficultyMultiplier\n ),\n };\n }\n\n /**\n * Get optimal stance recommendation\n */\n getOptimalStance(player: PlayerState, opponent?: PlayerState): TrigramStance {\n if (opponent) {\n // Get counter stance against opponent\n return TrigramCalculator.getCounterStance(opponent.currentStance);\n }\n\n // Default to archetype preferred stance\n const archetypeData = PLAYER_ARCHETYPES_DATA[player.archetype];\n const favoredStances = archetypeData.favoredStances || [];\n\n return favoredStances.length > 0 ? favoredStances[0] : TrigramStance.GEON; // Fix: Use enum value\n }\n\n /**\n * Get all valid transitions from current stance\n */\n getValidTransitions(player: PlayerState): TrigramStance[] {\n return Object.values(TrigramStance).filter(\n (\n stance // Fix: Use enum values\n ) => this.canChangeStance(player, stance)\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransitionCalculator.js","names":[],"sources":["../../../src/systems/trigram/TransitionCalculator.ts"],"sourcesContent":["import { TrigramStance } from \"../../types\";\nimport { TrigramStance as TrigramStanceEnum } from \"../../types/common\";\nimport {\n calculateStanceDistance,\n determineTransitionType,\n getStanceTransition,\n type StanceTransitionType,\n} from \"../animation/core/AnimationTransitions\";\nimport { PlayerState } from \"../player\";\nimport { TrigramTransitionCost, TrigramTransitionRule } from \"./types\";\n\n/**\n * Calculator for trigram stance transition costs and validation\n *\n * **Korean**: 자세 전환 계산기\n *\n * Calculates costs, paths, and validation for transitions between trigram stances.\n * Integrates with the animation system's stance transition matrix.\n *\n * @category Trigram System\n * @korean 자세전환계산기\n */\nexport class TransitionCalculator {\n private calculateBaseCost(\n from: TrigramStance,\n to: TrigramStance\n ): TrigramTransitionCost {\n if (from === to) {\n return { ki: 0, stamina: 0, timeMilliseconds: 0 };\n }\n\n return { ki: 10, stamina: 15, timeMilliseconds: 500 };\n }\n\n generateTransitionRule(\n from: TrigramStance,\n to: TrigramStance\n ): TrigramTransitionRule {\n const cost = this.calculateBaseCost(from, to);\n\n return {\n from,\n to,\n cost,\n effectiveness: 1.0, // Fix: Add missing effectiveness property\n conditions: [],\n description: {\n korean: `${from}에서 ${to}로 전환`,\n english: `Transition from ${from} to ${to}`,\n },\n };\n }\n\n /**\n * Calculate the cost of transitioning between stances\n *\n * **Korean**: 자세 전환 비용 계산\n *\n * Calculates ki, stamina, and time costs based on stance distance.\n * Uses animation system's transition configurations for accurate timing.\n *\n * @param from - Source stance\n * @param to - Target stance\n * @returns Transition cost breakdown\n *\n * @korean 자세전환비용계산\n */\n static calculateCost(\n from: TrigramStance,\n to: TrigramStance\n ): TrigramTransitionCost {\n if (from === to) {\n return { ki: 0, stamina: 0, timeMilliseconds: 0 };\n }\n\n // Get transition from animation system for accurate timing\n const transition = getStanceTransition(from, to);\n const timeMs = transition?.duration ?? 600;\n\n const baseCost = { ki: 15, stamina: 10, timeMilliseconds: timeMs };\n const modifier = this.getAdjacencyModifier(from, to);\n\n return {\n ki: Math.floor(baseCost.ki * modifier),\n stamina: Math.floor(baseCost.stamina * modifier),\n timeMilliseconds: timeMs, // Use actual transition duration\n };\n }\n\n /**\n * Check if a transition is valid for a player\n */\n static canTransition(\n from: TrigramStance,\n to: TrigramStance,\n player: PlayerState\n ): boolean {\n const cost = this.calculateCost(from, to);\n return player.ki >= cost.ki && player.stamina >= cost.stamina;\n }\n\n /**\n * Check if transition is valid based on player state\n */\n static isTransitionValid(\n from: TrigramStance,\n to: TrigramStance,\n player: PlayerState\n ): boolean {\n return this.canTransition(from, to, player);\n }\n\n /**\n * Get Ki cost for transition\n */\n static getKiCost(\n from: TrigramStance,\n to: TrigramStance,\n _player: PlayerState\n ): number {\n return this.calculateCost(from, to).ki;\n }\n\n /**\n * Get Stamina cost for transition\n */\n static getStaminaCost(\n from: TrigramStance,\n to: TrigramStance,\n _player: PlayerState\n ): number {\n return this.calculateCost(from, to).stamina;\n }\n\n /**\n * Get transition time\n */\n static getTransitionTime(\n from: TrigramStance,\n to: TrigramStance,\n _player: PlayerState\n ): number {\n return this.calculateCost(from, to).timeMilliseconds; // Fix property name\n }\n\n /**\n * Get adjacency modifier for stance transitions\n *\n * **Korean**: 인접도 수정자\n *\n * Uses the animation system's distance calculation for consistency.\n * Adjacent stances (distance 1) get 0.7x cost, others get 1.0x cost.\n *\n * @param from - Source stance\n * @param to - Target stance\n * @returns Cost modifier (0.7 for adjacent, 1.0 for distant)\n *\n * @korean 인접도수정자\n */\n private static getAdjacencyModifier(\n from: TrigramStance,\n to: TrigramStance\n ): number {\n const distance = calculateStanceDistance(from, to);\n\n // Adjacent stances (distance 1) have reduced cost\n if (distance === 1) return 0.7;\n\n // Near-adjacent (distance 2) have slightly reduced cost\n if (distance === 2) return 0.85;\n\n // Distant/opposite stances have full cost\n return 1.0;\n }\n\n /**\n * Get the shortest transition path between stances\n *\n * **Korean**: 최단 전환 경로\n *\n * For direct transitions, returns [from, to].\n * For indirect transitions, may include intermediate stances for smoother animation.\n *\n * @param from - Source stance\n * @param to - Target stance\n * @returns Array of stances in transition path\n *\n * @example\n * ```typescript\n * // Adjacent stances - direct path\n * getTransitionPath(TrigramStance.GEON, TrigramStance.TAE);\n * // Returns: [\"geon\", \"tae\"]\n *\n * // Opposite stances - may use intermediate\n * getTransitionPath(TrigramStance.GEON, TrigramStance.GON);\n * // Returns: [\"geon\", \"gon\"] (direct is shortest even though opposite)\n * ```\n *\n * @korean 최단전환경로\n */\n static getTransitionPath(\n from: TrigramStance,\n to: TrigramStance\n ): TrigramStance[] {\n if (from === to) return [from];\n\n // For all transitions, direct path is used\n // The animation system handles the complexity with keyframes\n return [from, to];\n }\n\n /**\n * Get transition type for a stance change\n *\n * **Korean**: 전환 유형 가져오기\n *\n * Determines if transition is direct (adjacent), indirect (opposite), or self.\n *\n * @param from - Source stance\n * @param to - Target stance\n * @returns Transition type classification\n *\n * @korean 전환유형가져오기\n */\n static getTransitionType(\n from: TrigramStance,\n to: TrigramStance\n ): StanceTransitionType {\n return determineTransitionType(from, to);\n }\n\n /**\n * Calculate stance distance around the wheel\n *\n * **Korean**: 자세 거리 계산\n *\n * Returns the number of steps between stances on the octagonal wheel.\n *\n * @param from - Source stance\n * @param to - Target stance\n * @returns Distance (0-4)\n *\n * @korean 자세거리계산\n */\n static getStanceDistance(from: TrigramStance, to: TrigramStance): number {\n return calculateStanceDistance(from, to);\n }\n\n /**\n * Calculate total cost for a transition path\n */\n static calculatePathCost(path: TrigramStance[]): TrigramTransitionCost {\n if (path.length <= 1) {\n return { ki: 0, stamina: 0, timeMilliseconds: 0 }; // Fix: Use timeMilliseconds\n }\n\n const totalCost = { ki: 0, stamina: 0, timeMilliseconds: 0 };\n\n for (let i = 0; i < path.length - 1; i++) {\n const stepCost = this.calculateCost(path[i], path[i + 1]);\n totalCost.ki += stepCost.ki;\n totalCost.stamina += stepCost.stamina;\n totalCost.timeMilliseconds += stepCost.timeMilliseconds;\n }\n\n return totalCost;\n }\n\n /**\n * Get all valid transitions from a stance\n */\n static getValidTransitions(\n from: TrigramStance,\n player: PlayerState\n ): TrigramTransitionRule[] {\n const transitions: TrigramTransitionRule[] = [];\n\n for (const to of Object.values(TrigramStanceEnum)) {\n if (this.isTransitionValid(from, to, player)) {\n const cost = this.calculateCost(from, to);\n\n transitions.push({\n from,\n to,\n cost,\n effectiveness: 1.0, // Add missing property\n conditions: [],\n description: {\n korean: `${from}에서 ${to}로`,\n english: `From ${from} to ${to}`,\n },\n });\n }\n }\n\n return transitions;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TransitionCalculator.js","names":[],"sources":["../../../src/systems/trigram/TransitionCalculator.ts"],"sourcesContent":["import { TrigramStance } from \"../../types\";\nimport { TrigramStance as TrigramStanceEnum } from \"../../types/common\";\nimport {\n calculateStanceDistance,\n determineTransitionType,\n getStanceTransition,\n type StanceTransitionType,\n} from \"../animation/core/AnimationTransitions\";\nimport { PlayerState } from \"../player\";\nimport { TrigramTransitionCost, TrigramTransitionRule } from \"./types\";\n\n/**\n * Calculator for trigram stance transition costs and validation\n *\n * **Korean**: 자세 전환 계산기\n *\n * Calculates costs, paths, and validation for transitions between trigram stances.\n * Integrates with the animation system's stance transition matrix.\n *\n * @category Trigram System\n * @korean 자세전환계산기\n */\nexport class TransitionCalculator {\n private calculateBaseCost(\n from: TrigramStance,\n to: TrigramStance\n ): TrigramTransitionCost {\n if (from === to) {\n return { ki: 0, stamina: 0, timeMilliseconds: 0 };\n }\n\n return { ki: 10, stamina: 15, timeMilliseconds: 500 };\n }\n\n generateTransitionRule(\n from: TrigramStance,\n to: TrigramStance\n ): TrigramTransitionRule {\n const cost = this.calculateBaseCost(from, to);\n\n return {\n from,\n to,\n cost,\n effectiveness: 1.0, // Fix: Add missing effectiveness property\n conditions: [],\n description: {\n korean: `${from}에서 ${to}로 전환`,\n english: `Transition from ${from} to ${to}`,\n },\n };\n }\n\n /**\n * Calculate the cost of transitioning between stances\n *\n * **Korean**: 자세 전환 비용 계산\n *\n * Calculates ki, stamina, and time costs based on stance distance.\n * Uses animation system's transition configurations for accurate timing.\n *\n * @param from - Source stance\n * @param to - Target stance\n * @returns Transition cost breakdown\n *\n * @korean 자세전환비용계산\n */\n static calculateCost(\n from: TrigramStance,\n to: TrigramStance\n ): TrigramTransitionCost {\n if (from === to) {\n return { ki: 0, stamina: 0, timeMilliseconds: 0 };\n }\n\n // Get transition from animation system for accurate timing\n const transition = getStanceTransition(from, to);\n const timeMs = transition?.duration ?? 600;\n\n const baseCost = { ki: 15, stamina: 10, timeMilliseconds: timeMs };\n const modifier = this.getAdjacencyModifier(from, to);\n\n return {\n ki: Math.floor(baseCost.ki * modifier),\n stamina: Math.floor(baseCost.stamina * modifier),\n timeMilliseconds: timeMs, // Use actual transition duration\n };\n }\n\n /**\n * Check if a transition is valid for a player\n */\n static canTransition(\n from: TrigramStance,\n to: TrigramStance,\n player: PlayerState\n ): boolean {\n const cost = this.calculateCost(from, to);\n return player.ki >= cost.ki && player.stamina >= cost.stamina;\n }\n\n /**\n * Check if transition is valid based on player state\n */\n static isTransitionValid(\n from: TrigramStance,\n to: TrigramStance,\n player: PlayerState\n ): boolean {\n return this.canTransition(from, to, player);\n }\n\n /**\n * Get Ki cost for transition\n */\n static getKiCost(\n from: TrigramStance,\n to: TrigramStance,\n _player: PlayerState\n ): number {\n return this.calculateCost(from, to).ki;\n }\n\n /**\n * Get Stamina cost for transition\n */\n static getStaminaCost(\n from: TrigramStance,\n to: TrigramStance,\n _player: PlayerState\n ): number {\n return this.calculateCost(from, to).stamina;\n }\n\n /**\n * Get transition time\n */\n static getTransitionTime(\n from: TrigramStance,\n to: TrigramStance,\n _player: PlayerState\n ): number {\n return this.calculateCost(from, to).timeMilliseconds; // Fix property name\n }\n\n /**\n * Get adjacency modifier for stance transitions\n *\n * **Korean**: 인접도 수정자\n *\n * Uses the animation system's distance calculation for consistency.\n * Adjacent stances (distance 1) get 0.7x cost, others get 1.0x cost.\n *\n * @param from - Source stance\n * @param to - Target stance\n * @returns Cost modifier (0.7 for adjacent, 1.0 for distant)\n *\n * @korean 인접도수정자\n */\n private static getAdjacencyModifier(\n from: TrigramStance,\n to: TrigramStance\n ): number {\n const distance = calculateStanceDistance(from, to);\n\n // Adjacent stances (distance 1) have reduced cost\n if (distance === 1) return 0.7;\n\n // Near-adjacent (distance 2) have slightly reduced cost\n if (distance === 2) return 0.85;\n\n // Distant/opposite stances have full cost\n return 1.0;\n }\n\n /**\n * Get the shortest transition path between stances\n *\n * **Korean**: 최단 전환 경로\n *\n * For direct transitions, returns [from, to].\n * For indirect transitions, may include intermediate stances for smoother animation.\n *\n * @param from - Source stance\n * @param to - Target stance\n * @returns Array of stances in transition path\n *\n * @example\n * ```typescript\n * // Adjacent stances - direct path\n * getTransitionPath(TrigramStance.GEON, TrigramStance.TAE);\n * // Returns: [\"geon\", \"tae\"]\n *\n * // Opposite stances - may use intermediate\n * getTransitionPath(TrigramStance.GEON, TrigramStance.GON);\n * // Returns: [\"geon\", \"gon\"] (direct is shortest even though opposite)\n * ```\n *\n * @korean 최단전환경로\n */\n static getTransitionPath(\n from: TrigramStance,\n to: TrigramStance\n ): TrigramStance[] {\n if (from === to) return [from];\n\n // For all transitions, direct path is used\n // The animation system handles the complexity with keyframes\n return [from, to];\n }\n\n /**\n * Get transition type for a stance change\n *\n * **Korean**: 전환 유형 가져오기\n *\n * Determines if transition is direct (adjacent), indirect (opposite), or self.\n *\n * @param from - Source stance\n * @param to - Target stance\n * @returns Transition type classification\n *\n * @korean 전환유형가져오기\n */\n static getTransitionType(\n from: TrigramStance,\n to: TrigramStance\n ): StanceTransitionType {\n return determineTransitionType(from, to);\n }\n\n /**\n * Calculate stance distance around the wheel\n *\n * **Korean**: 자세 거리 계산\n *\n * Returns the number of steps between stances on the octagonal wheel.\n *\n * @param from - Source stance\n * @param to - Target stance\n * @returns Distance (0-4)\n *\n * @korean 자세거리계산\n */\n static getStanceDistance(from: TrigramStance, to: TrigramStance): number {\n return calculateStanceDistance(from, to);\n }\n\n /**\n * Calculate total cost for a transition path\n */\n static calculatePathCost(path: TrigramStance[]): TrigramTransitionCost {\n if (path.length <= 1) {\n return { ki: 0, stamina: 0, timeMilliseconds: 0 }; // Fix: Use timeMilliseconds\n }\n\n const totalCost = { ki: 0, stamina: 0, timeMilliseconds: 0 };\n\n for (let i = 0; i < path.length - 1; i++) {\n const stepCost = this.calculateCost(path[i], path[i + 1]);\n totalCost.ki += stepCost.ki;\n totalCost.stamina += stepCost.stamina;\n totalCost.timeMilliseconds += stepCost.timeMilliseconds;\n }\n\n return totalCost;\n }\n\n /**\n * Get all valid transitions from a stance\n */\n static getValidTransitions(\n from: TrigramStance,\n player: PlayerState\n ): TrigramTransitionRule[] {\n const transitions: TrigramTransitionRule[] = [];\n\n for (const to of Object.values(TrigramStanceEnum)) {\n if (this.isTransitionValid(from, to, player)) {\n const cost = this.calculateCost(from, to);\n\n transitions.push({\n from,\n to,\n cost,\n effectiveness: 1.0, // Add missing property\n conditions: [],\n description: {\n korean: `${from}에서 ${to}로`,\n english: `From ${from} to ${to}`,\n },\n });\n }\n }\n\n return transitions;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TrigramCalculator.js","names":[],"sources":["../../../src/systems/trigram/TrigramCalculator.ts"],"sourcesContent":["import { TrigramStance } from \"../../types/common\";\nimport { StanceLaterality } from \"./types\";\n\n/**\n * Enhanced stance effectiveness matrix for Korean martial arts\n * Based on traditional I-Ching trigram relationships\n */\nconst STANCE_EFFECTIVENESS_MATRIX: Record<\n TrigramStance,\n Partial<Record<TrigramStance, number>>\n> = {\n [TrigramStance.GEON]: { [TrigramStance.GON]: 1.2, [TrigramStance.SON]: 0.8 },\n [TrigramStance.GON]: { [TrigramStance.GEON]: 0.8, [TrigramStance.GAM]: 1.2 },\n [TrigramStance.TAE]: { [TrigramStance.JIN]: 1.2, [TrigramStance.GAN]: 0.8 },\n [TrigramStance.JIN]: { [TrigramStance.TAE]: 0.8, [TrigramStance.SON]: 1.2 },\n [TrigramStance.LI]: { [TrigramStance.GAM]: 0.8, [TrigramStance.TAE]: 0.8 },\n [TrigramStance.GAM]: {\n // water extinguishes fire:\n [TrigramStance.LI]: 1.2,\n [TrigramStance.GON]: 0.8,\n },\n [TrigramStance.SON]: { [TrigramStance.GEON]: 1.2, [TrigramStance.JIN]: 0.8 },\n [TrigramStance.GAN]: { [TrigramStance.TAE]: 1.2, [TrigramStance.LI]: 0.8 },\n};\n\nexport class TrigramCalculator {\n /**\n * Calculate effectiveness of one stance against another\n */\n calculateStanceEffectiveness(\n attackerStance: TrigramStance,\n defenderStance: TrigramStance\n ): number {\n if (attackerStance === defenderStance) {\n return 1.0; // Neutral when same stance\n }\n\n const effectiveness =\n STANCE_EFFECTIVENESS_MATRIX[attackerStance]?.[defenderStance];\n return effectiveness ?? 1.0; // Default to neutral if no specific relationship\n }\n\n /**\n * Get the optimal counter stance for a given stance\n */\n getCounterStance(targetStance: TrigramStance): TrigramStance {\n let bestCounter = TrigramStance.GEON;\n let bestEffectiveness = 0;\n\n // Find stance with highest effectiveness against target\n for (const stance of Object.values(TrigramStance)) {\n const effectiveness = this.calculateStanceEffectiveness(\n stance,\n targetStance\n );\n if (effectiveness > bestEffectiveness) {\n bestEffectiveness = effectiveness;\n bestCounter = stance;\n }\n }\n\n return bestCounter;\n }\n\n /**\n * Calculate transition difficulty between stances\n */\n calculateTransitionDifficulty(\n fromStance: TrigramStance,\n toStance: TrigramStance\n ): number {\n if (fromStance === toStance) return 0;\n\n // Base difficulty for any transition\n const baseDifficulty = 0.5;\n\n // Get stance order for adjacency calculation\n const stanceOrder = Object.values(TrigramStance);\n const fromIndex = stanceOrder.indexOf(fromStance);\n const toIndex = stanceOrder.indexOf(toStance);\n\n if (fromIndex === -1 || toIndex === -1) {\n return 1.0; // Unknown stances, high difficulty\n }\n\n // Calculate distance (adjacent stances are easier)\n const distance = Math.min(\n Math.abs(toIndex - fromIndex),\n stanceOrder.length - Math.abs(toIndex - fromIndex)\n );\n\n // Normalize distance to 0-1 range and add base difficulty\n const normalizedDistance = distance / (stanceOrder.length / 2);\n return baseDifficulty + normalizedDistance * 0.5;\n }\n\n /**\n * Calculate stance effectiveness between attacker and defender\n */\n static calculateStanceEffectiveness(\n attackerStance: TrigramStance,\n defenderStance: TrigramStance\n ): number {\n // Use the effectiveness matrix from constants\n const effectiveness =\n STANCE_EFFECTIVENESS_MATRIX[attackerStance]?.[defenderStance];\n return effectiveness ?? 1.0; // Default neutral effectiveness\n }\n\n /**\n * Get optimal counter stance against opponent stance\n */\n static getCounterStance(opponentStance: TrigramStance): TrigramStance {\n // Find the stance that has highest effectiveness against opponent\n const stances = Object.values(TrigramStance);\n let bestCounter = TrigramStance.GEON;\n let bestEffectiveness = 0;\n\n stances.forEach((stance) => {\n const effectiveness = this.calculateStanceEffectiveness(\n stance,\n opponentStance\n );\n if (effectiveness > bestEffectiveness) {\n bestEffectiveness = effectiveness;\n bestCounter = stance;\n }\n });\n\n return bestCounter;\n }\n\n /**\n * Calculate difficulty of transitioning between stances\n */\n static calculateTransitionDifficulty(\n fromStance: TrigramStance,\n toStance: TrigramStance\n ): number {\n if (fromStance === toStance) {\n return 0; // No transition needed\n }\n\n // Base difficulty for any transition\n const baseDifficulty = 0.5;\n\n // Get stance order for adjacency calculation\n const stanceOrder = Object.values(TrigramStance);\n const fromIndex = stanceOrder.indexOf(fromStance);\n const toIndex = stanceOrder.indexOf(toStance);\n\n if (fromIndex === -1 || toIndex === -1) {\n return 1.0; // Unknown stances, high difficulty\n }\n\n // Calculate distance (adjacent stances are easier)\n const distance = Math.min(\n Math.abs(toIndex - fromIndex),\n stanceOrder.length - Math.abs(toIndex - fromIndex)\n );\n\n // Normalize distance to 0-1 range and add base difficulty\n const normalizedDistance = distance / (stanceOrder.length / 2);\n return baseDifficulty + normalizedDistance * 0.5;\n }\n\n /**\n * Calculate laterality modifier based on stance matching.\n * \n * In Korean martial arts, matched stances (both fighters in same laterality)\n * create tactical advantages for mid-level attacks as centerlines are more exposed.\n * Mismatched stances (opposite laterality) provide defensive advantages as lead guards\n * naturally protect the centerline.\n * \n * @param attackerLaterality - Attacker's stance laterality (left or right)\n * @param defenderLaterality - Defender's stance laterality (left or right)\n * @param attackLevel - Attack level: \"high\", \"mid\", or \"low\"\n * @returns Damage multiplier (1.0 = neutral, >1.0 = advantage, <1.0 = disadvantage)\n * \n * @example\n * ```typescript\n * // Matched stances: attacker gains mid-level advantage\n * const modifier = TrigramCalculator.calculateLateralityModifier(\"left\", \"left\", \"mid\");\n * // Returns 1.15 (+15% effectiveness)\n * \n * // Mismatched stances: defender's guard protects centerline\n * const modifier = TrigramCalculator.calculateLateralityModifier(\"left\", \"right\", \"mid\");\n * // Returns 0.90 (-10% effectiveness)\n * ```\n * \n * @public\n * @korean 측면성수정자계산\n */\n static calculateLateralityModifier(\n attackerLaterality: StanceLaterality,\n defenderLaterality: StanceLaterality,\n attackLevel: \"high\" | \"mid\" | \"low\" = \"mid\"\n ): number {\n const isMatched = attackerLaterality === defenderLaterality;\n\n // Laterality primarily affects mid-level attacks (centerline attacks)\n if (attackLevel === \"mid\") {\n // Matched stances: Open centerline = offensive advantage\n // Mismatched stances: Protected centerline = defensive advantage\n return isMatched ? 1.15 : 0.90;\n }\n\n // High and low attacks less affected by laterality\n // Slight tactical variation still exists\n if (attackLevel === \"high\") {\n return isMatched ? 1.05 : 0.98;\n }\n\n if (attackLevel === \"low\") {\n return isMatched ? 1.03 : 0.99;\n }\n\n // Default neutral\n return 1.0;\n }\n} // end of class\n\nexport { STANCE_EFFECTIVENESS_MATRIX };\n"],"mappings":";;;;;;AAOA,IAAM,8BAGF;EACD,cAAc,OAAO;GAAG,cAAc,MAAM;GAAM,cAAc,MAAM;EAAK;EAC3E,cAAc,MAAM;GAAG,cAAc,OAAO;GAAM,cAAc,MAAM;EAAK;EAC3E,cAAc,MAAM;GAAG,cAAc,MAAM;GAAM,cAAc,MAAM;EAAK;EAC1E,cAAc,MAAM;GAAG,cAAc,MAAM;GAAM,cAAc,MAAM;EAAK;EAC1E,cAAc,KAAK;GAAG,cAAc,MAAM;GAAM,cAAc,MAAM;EAAK;EACzE,cAAc,MAAM;GAElB,cAAc,KAAK;GACnB,cAAc,MAAM;EACtB;EACA,cAAc,MAAM;GAAG,cAAc,OAAO;GAAM,cAAc,MAAM;EAAK;EAC3E,cAAc,MAAM;GAAG,cAAc,MAAM;GAAM,cAAc,KAAK;EAAK;CAC3E;AAED,IAAa,oBAAb,MAA+B;;;;CAI7B,6BACE,gBACA,gBACQ;
|
|
1
|
+
{"version":3,"file":"TrigramCalculator.js","names":[],"sources":["../../../src/systems/trigram/TrigramCalculator.ts"],"sourcesContent":["import { TrigramStance } from \"../../types/common\";\nimport { StanceLaterality } from \"./types\";\n\n/**\n * Enhanced stance effectiveness matrix for Korean martial arts\n * Based on traditional I-Ching trigram relationships\n */\nconst STANCE_EFFECTIVENESS_MATRIX: Record<\n TrigramStance,\n Partial<Record<TrigramStance, number>>\n> = {\n [TrigramStance.GEON]: { [TrigramStance.GON]: 1.2, [TrigramStance.SON]: 0.8 },\n [TrigramStance.GON]: { [TrigramStance.GEON]: 0.8, [TrigramStance.GAM]: 1.2 },\n [TrigramStance.TAE]: { [TrigramStance.JIN]: 1.2, [TrigramStance.GAN]: 0.8 },\n [TrigramStance.JIN]: { [TrigramStance.TAE]: 0.8, [TrigramStance.SON]: 1.2 },\n [TrigramStance.LI]: { [TrigramStance.GAM]: 0.8, [TrigramStance.TAE]: 0.8 },\n [TrigramStance.GAM]: {\n // water extinguishes fire:\n [TrigramStance.LI]: 1.2,\n [TrigramStance.GON]: 0.8,\n },\n [TrigramStance.SON]: { [TrigramStance.GEON]: 1.2, [TrigramStance.JIN]: 0.8 },\n [TrigramStance.GAN]: { [TrigramStance.TAE]: 1.2, [TrigramStance.LI]: 0.8 },\n};\n\nexport class TrigramCalculator {\n /**\n * Calculate effectiveness of one stance against another\n */\n calculateStanceEffectiveness(\n attackerStance: TrigramStance,\n defenderStance: TrigramStance\n ): number {\n if (attackerStance === defenderStance) {\n return 1.0; // Neutral when same stance\n }\n\n const effectiveness =\n STANCE_EFFECTIVENESS_MATRIX[attackerStance]?.[defenderStance];\n return effectiveness ?? 1.0; // Default to neutral if no specific relationship\n }\n\n /**\n * Get the optimal counter stance for a given stance\n */\n getCounterStance(targetStance: TrigramStance): TrigramStance {\n let bestCounter = TrigramStance.GEON;\n let bestEffectiveness = 0;\n\n // Find stance with highest effectiveness against target\n for (const stance of Object.values(TrigramStance)) {\n const effectiveness = this.calculateStanceEffectiveness(\n stance,\n targetStance\n );\n if (effectiveness > bestEffectiveness) {\n bestEffectiveness = effectiveness;\n bestCounter = stance;\n }\n }\n\n return bestCounter;\n }\n\n /**\n * Calculate transition difficulty between stances\n */\n calculateTransitionDifficulty(\n fromStance: TrigramStance,\n toStance: TrigramStance\n ): number {\n if (fromStance === toStance) return 0;\n\n // Base difficulty for any transition\n const baseDifficulty = 0.5;\n\n // Get stance order for adjacency calculation\n const stanceOrder = Object.values(TrigramStance);\n const fromIndex = stanceOrder.indexOf(fromStance);\n const toIndex = stanceOrder.indexOf(toStance);\n\n if (fromIndex === -1 || toIndex === -1) {\n return 1.0; // Unknown stances, high difficulty\n }\n\n // Calculate distance (adjacent stances are easier)\n const distance = Math.min(\n Math.abs(toIndex - fromIndex),\n stanceOrder.length - Math.abs(toIndex - fromIndex)\n );\n\n // Normalize distance to 0-1 range and add base difficulty\n const normalizedDistance = distance / (stanceOrder.length / 2);\n return baseDifficulty + normalizedDistance * 0.5;\n }\n\n /**\n * Calculate stance effectiveness between attacker and defender\n */\n static calculateStanceEffectiveness(\n attackerStance: TrigramStance,\n defenderStance: TrigramStance\n ): number {\n // Use the effectiveness matrix from constants\n const effectiveness =\n STANCE_EFFECTIVENESS_MATRIX[attackerStance]?.[defenderStance];\n return effectiveness ?? 1.0; // Default neutral effectiveness\n }\n\n /**\n * Get optimal counter stance against opponent stance\n */\n static getCounterStance(opponentStance: TrigramStance): TrigramStance {\n // Find the stance that has highest effectiveness against opponent\n const stances = Object.values(TrigramStance);\n let bestCounter = TrigramStance.GEON;\n let bestEffectiveness = 0;\n\n stances.forEach((stance) => {\n const effectiveness = this.calculateStanceEffectiveness(\n stance,\n opponentStance\n );\n if (effectiveness > bestEffectiveness) {\n bestEffectiveness = effectiveness;\n bestCounter = stance;\n }\n });\n\n return bestCounter;\n }\n\n /**\n * Calculate difficulty of transitioning between stances\n */\n static calculateTransitionDifficulty(\n fromStance: TrigramStance,\n toStance: TrigramStance\n ): number {\n if (fromStance === toStance) {\n return 0; // No transition needed\n }\n\n // Base difficulty for any transition\n const baseDifficulty = 0.5;\n\n // Get stance order for adjacency calculation\n const stanceOrder = Object.values(TrigramStance);\n const fromIndex = stanceOrder.indexOf(fromStance);\n const toIndex = stanceOrder.indexOf(toStance);\n\n if (fromIndex === -1 || toIndex === -1) {\n return 1.0; // Unknown stances, high difficulty\n }\n\n // Calculate distance (adjacent stances are easier)\n const distance = Math.min(\n Math.abs(toIndex - fromIndex),\n stanceOrder.length - Math.abs(toIndex - fromIndex)\n );\n\n // Normalize distance to 0-1 range and add base difficulty\n const normalizedDistance = distance / (stanceOrder.length / 2);\n return baseDifficulty + normalizedDistance * 0.5;\n }\n\n /**\n * Calculate laterality modifier based on stance matching.\n * \n * In Korean martial arts, matched stances (both fighters in same laterality)\n * create tactical advantages for mid-level attacks as centerlines are more exposed.\n * Mismatched stances (opposite laterality) provide defensive advantages as lead guards\n * naturally protect the centerline.\n * \n * @param attackerLaterality - Attacker's stance laterality (left or right)\n * @param defenderLaterality - Defender's stance laterality (left or right)\n * @param attackLevel - Attack level: \"high\", \"mid\", or \"low\"\n * @returns Damage multiplier (1.0 = neutral, >1.0 = advantage, <1.0 = disadvantage)\n * \n * @example\n * ```typescript\n * // Matched stances: attacker gains mid-level advantage\n * const modifier = TrigramCalculator.calculateLateralityModifier(\"left\", \"left\", \"mid\");\n * // Returns 1.15 (+15% effectiveness)\n * \n * // Mismatched stances: defender's guard protects centerline\n * const modifier = TrigramCalculator.calculateLateralityModifier(\"left\", \"right\", \"mid\");\n * // Returns 0.90 (-10% effectiveness)\n * ```\n * \n * @public\n * @korean 측면성수정자계산\n */\n static calculateLateralityModifier(\n attackerLaterality: StanceLaterality,\n defenderLaterality: StanceLaterality,\n attackLevel: \"high\" | \"mid\" | \"low\" = \"mid\"\n ): number {\n const isMatched = attackerLaterality === defenderLaterality;\n\n // Laterality primarily affects mid-level attacks (centerline attacks)\n if (attackLevel === \"mid\") {\n // Matched stances: Open centerline = offensive advantage\n // Mismatched stances: Protected centerline = defensive advantage\n return isMatched ? 1.15 : 0.90;\n }\n\n // High and low attacks less affected by laterality\n // Slight tactical variation still exists\n if (attackLevel === \"high\") {\n return isMatched ? 1.05 : 0.98;\n }\n\n if (attackLevel === \"low\") {\n return isMatched ? 1.03 : 0.99;\n }\n\n // Default neutral\n return 1.0;\n }\n} // end of class\n\nexport { STANCE_EFFECTIVENESS_MATRIX };\n"],"mappings":";;;;;;AAOA,IAAM,8BAGF;EACD,cAAc,OAAO;GAAG,cAAc,MAAM;GAAM,cAAc,MAAM;EAAK;EAC3E,cAAc,MAAM;GAAG,cAAc,OAAO;GAAM,cAAc,MAAM;EAAK;EAC3E,cAAc,MAAM;GAAG,cAAc,MAAM;GAAM,cAAc,MAAM;EAAK;EAC1E,cAAc,MAAM;GAAG,cAAc,MAAM;GAAM,cAAc,MAAM;EAAK;EAC1E,cAAc,KAAK;GAAG,cAAc,MAAM;GAAM,cAAc,MAAM;EAAK;EACzE,cAAc,MAAM;GAElB,cAAc,KAAK;GACnB,cAAc,MAAM;EACtB;EACA,cAAc,MAAM;GAAG,cAAc,OAAO;GAAM,cAAc,MAAM;EAAK;EAC3E,cAAc,MAAM;GAAG,cAAc,MAAM;GAAM,cAAc,KAAK;EAAK;CAC3E;AAED,IAAa,oBAAb,MAA+B;;;;CAI7B,6BACE,gBACA,gBACQ;EACR,IAAI,mBAAmB,gBACrB,OAAO;EAKT,OADE,4BAA4B,kBAAkB,mBACxB;;;;;CAM1B,iBAAiB,cAA4C;EAC3D,IAAI,cAAc,cAAc;EAChC,IAAI,oBAAoB;EAGxB,KAAK,MAAM,UAAU,OAAO,OAAO,cAAc,EAAE;GACjD,MAAM,gBAAgB,KAAK,6BACzB,QACA,aACD;GACD,IAAI,gBAAgB,mBAAmB;IACrC,oBAAoB;IACpB,cAAc;;;EAIlB,OAAO;;;;;CAMT,8BACE,YACA,UACQ;EACR,IAAI,eAAe,UAAU,OAAO;EAGpC,MAAM,iBAAiB;EAGvB,MAAM,cAAc,OAAO,OAAO,cAAc;EAChD,MAAM,YAAY,YAAY,QAAQ,WAAW;EACjD,MAAM,UAAU,YAAY,QAAQ,SAAS;EAE7C,IAAI,cAAc,MAAM,YAAY,IAClC,OAAO;EAWT,OAAO,iBAPU,KAAK,IACpB,KAAK,IAAI,UAAU,UAAU,EAC7B,YAAY,SAAS,KAAK,IAAI,UAAU,UAAU,CAIzB,IAAY,YAAY,SAAS,KACf;;;;;CAM/C,OAAO,6BACL,gBACA,gBACQ;EAIR,OADE,4BAA4B,kBAAkB,mBACxB;;;;;CAM1B,OAAO,iBAAiB,gBAA8C;EAEpE,MAAM,UAAU,OAAO,OAAO,cAAc;EAC5C,IAAI,cAAc,cAAc;EAChC,IAAI,oBAAoB;EAExB,QAAQ,SAAS,WAAW;GAC1B,MAAM,gBAAgB,KAAK,6BACzB,QACA,eACD;GACD,IAAI,gBAAgB,mBAAmB;IACrC,oBAAoB;IACpB,cAAc;;IAEhB;EAEF,OAAO;;;;;CAMT,OAAO,8BACL,YACA,UACQ;EACR,IAAI,eAAe,UACjB,OAAO;EAIT,MAAM,iBAAiB;EAGvB,MAAM,cAAc,OAAO,OAAO,cAAc;EAChD,MAAM,YAAY,YAAY,QAAQ,WAAW;EACjD,MAAM,UAAU,YAAY,QAAQ,SAAS;EAE7C,IAAI,cAAc,MAAM,YAAY,IAClC,OAAO;EAWT,OAAO,iBAPU,KAAK,IACpB,KAAK,IAAI,UAAU,UAAU,EAC7B,YAAY,SAAS,KAAK,IAAI,UAAU,UAAU,CAIzB,IAAY,YAAY,SAAS,KACf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8B/C,OAAO,4BACL,oBACA,oBACA,cAAsC,OAC9B;EACR,MAAM,YAAY,uBAAuB;EAGzC,IAAI,gBAAgB,OAGlB,OAAO,YAAY,OAAO;EAK5B,IAAI,gBAAgB,QAClB,OAAO,YAAY,OAAO;EAG5B,IAAI,gBAAgB,OAClB,OAAO,YAAY,OAAO;EAI5B,OAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DarkOpsTechniques.js","names":[],"sources":["../../../../src/systems/trigram/techniques/DarkOpsTechniques.ts"],"sourcesContent":["/**\n * 🌑 Dark Ops Techniques (암흑작전 기술)\n * Silent Incapacitation & Tactical Assassination\n *\n * Special operations techniques designed for the 암살자 (Amsalja) archetype.\n * Based on 5 specialized Korean Dark Ops units with focus on silent takedowns,\n * nerve disruption, and rapid incapacitation.\n *\n * Philosophy: \"그림자처럼 움직이고 바람처럼 사라져라\"\n * Move like shadow, vanish like wind\n *\n * @module DarkOpsTechniques\n */\n\nimport type { KoreanTechnique } from \"@/systems/vitalpoint\";\nimport {\n CombatAttackType,\n DamageType,\n PlayerArchetype,\n TrigramStance,\n} from \"../../../types/common\";\nimport { AnimationType } from \"../../animation\";\n\n// =====================================================\n// DARK OPS UNIT DEFINITIONS\n// =====================================================\n\n/**\n * Dark Ops unit specializations (암흑작전 부대 특화)\n */\nexport const DARK_OPS_UNITS = {\n DARK_OPERATIONS: \"암흑작전부대\", // Dark Operations Unit - Silent Infiltration\n SHADOW_COMMANDO: \"암흑특공대\", // Shadow Commando Brigade - Demolition Tactics\n NIGHTFALL_SQUADRON: \"심야작전부대\", // Nightfall Squadron - Night Operations\n BLACK_OPS_TASK_FORCE: \"블랙옵스부대\", // Black Ops Task Force - Cyber-Enhanced\n DEEP_SEA_UNIT: \"심해침투부대\", // Deep Sea Unit - Amphibious Combat\n} as const;\n\n// =====================================================\n// DARK OPS TECHNIQUES\n// =====================================================\n\n/**\n * Dark Ops techniques array - Silent incapacitation and tactical assassination\n * Designed for 암살자 (Amsalja) archetype with +30% effectiveness bonus\n *\n * Animation speeds are calibrated for stealth and precision:\n * - Silent: 0.8-0.9 (slow, controlled movements)\n * - Normal: 1.0 (standard techniques)\n * - Rapid: 1.1-1.2 (quick incapacitation)\n */\nexport const DARK_OPS_TECHNIQUES: readonly KoreanTechnique[] = [\n // ===== 암흑작전부대 (Dark Operations Unit) - Silent Infiltration =====\n {\n id: \"darkops_silent_carotid\",\n name: {\n korean: \"은밀 경동맥 차단\",\n english: \"Silent Carotid Strike\",\n romanized: \"Eunmil Gyeongdongmaek Chadan\",\n },\n koreanName: \"은밀 경동맥 차단\",\n englishName: \"Silent Carotid Strike\",\n romanized: \"Eunmil Gyeongdongmaek Chadan\",\n description: {\n korean:\n \"경동맥을 압박하여 소리 없이 실신시킴. 3초 내 무의식 유발. 암흑작전부대의 침투 기술.\",\n english:\n \"Silent carotid compression causing unconsciousness within 3 seconds. Dark Operations Unit infiltration technique.\",\n },\n stance: TrigramStance.GAM,\n type: CombatAttackType.PRESSURE_POINT,\n damageType: DamageType.PRESSURE,\n damage: 28,\n kiCost: 30,\n staminaCost: 25,\n accuracy: 0.92,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 840,\n recoveryTime: 1400,\n critChance: 0.25,\n critMultiplier: 2.0,\n effects: [],\n // Animation: Silent choking motion\n animationType: AnimationType.GRAPPLE,\n animationSpeed: 0.65,\n animationCategory: \"grapple\", // Type: shared category\n animationId: \"darkops_silent_carotid\", // ID: unique 1-1 mapping\n },\n {\n id: \"darkops_nerve_paralysis\",\n name: {\n korean: \"신경마비타격\",\n english: \"Nerve Paralysis Strike\",\n romanized: \"Singyeong Mabi Tagyeok\",\n },\n koreanName: \"신경마비타격\",\n englishName: \"Nerve Paralysis Strike\",\n romanized: \"Singyeong Mabi Tagyeok\",\n description: {\n korean: \"신경총을 정밀 타격하여 사지 마비 유발. 블랙옵스 기술 강화.\",\n english:\n \"Precise nerve cluster strike causing limb paralysis. Black Ops tech-enhanced technique.\",\n },\n stance: TrigramStance.LI,\n type: CombatAttackType.NERVE_STRIKE,\n damageType: DamageType.NERVE,\n damage: 26,\n kiCost: 25,\n staminaCost: 20,\n accuracy: 0.95,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.95,\n },\n executionTime: 700,\n recoveryTime: 1260,\n critChance: 0.3,\n critMultiplier: 2.2,\n effects: [],\n // Animation: Precision nerve strike\n animationType: AnimationType.JAB,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_nerve_paralysis\", // ID: unique 1-1 mapping\n },\n\n // ===== 암흑특공대 (Shadow Commando Brigade) - Demolition Tactics =====\n {\n id: \"darkops_liver_disruption\",\n name: {\n korean: \"간 타격\",\n english: \"Liver Disruption Strike\",\n romanized: \"Gan Tagyeok\",\n },\n koreanName: \"간 타격\",\n englishName: \"Liver Disruption Strike\",\n romanized: \"Gan Tagyeok\",\n description: {\n korean:\n \"간을 강타하여 내부 출혈과 급격한 체력 소진 유발. 암흑특공대 폭파 전술.\",\n english:\n \"Powerful liver strike causing internal trauma and rapid stamina drain. Shadow Commando explosive tactic.\",\n },\n stance: TrigramStance.JIN,\n type: CombatAttackType.STRIKE,\n damageType: DamageType.INTERNAL,\n damage: 35,\n kiCost: 28,\n staminaCost: 30,\n accuracy: 0.85,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 979,\n recoveryTime: 1540,\n critChance: 0.22,\n critMultiplier: 2.1,\n effects: [],\n // Animation: Powerful body hook\n animationType: AnimationType.HOOK,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_liver_disruption\", // ID: unique 1-1 mapping\n },\n {\n id: \"darkops_kidney_strike\",\n name: {\n korean: \"신장충격\",\n english: \"Kidney Shock\",\n romanized: \"Sinjang Chunggyeok\",\n },\n koreanName: \"신장충격\",\n englishName: \"Kidney Shock\",\n romanized: \"Sinjang Chunggyeok\",\n description: {\n korean:\n \"신장을 타격하여 극심한 고통과 일시적 마비 유발. 폭발적 힘의 암흑특공대 기술.\",\n english:\n \"Kidney strike causing severe pain and temporary paralysis. Shadow Commando explosive force technique.\",\n },\n stance: TrigramStance.JIN,\n type: CombatAttackType.STRIKE,\n damageType: DamageType.INTERNAL,\n damage: 33,\n kiCost: 26,\n staminaCost: 28,\n accuracy: 0.82,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 909,\n recoveryTime: 1470,\n critChance: 0.2,\n critMultiplier: 2.0,\n effects: [],\n // Animation: Short hook to kidney\n animationType: AnimationType.HOOK,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_kidney_strike\", // ID: unique 1-1 mapping\n },\n\n // ===== 심야작전부대 (Nightfall Squadron) - Night Operations =====\n {\n id: \"darkops_throat_strike\",\n name: {\n korean: \"후두차단\",\n english: \"Throat Disruption\",\n romanized: \"Hudu Chadan\",\n },\n koreanName: \"후두차단\",\n englishName: \"Throat Disruption\",\n romanized: \"Hudu Chadan\",\n description: {\n korean:\n \"후두를 타격하여 호흡 곤란과 발성 불가 유발. 심야작전부대의 무음 제압술.\",\n english:\n \"Throat strike causing breathing difficulty and voice loss. Nightfall Squadron silent suppression technique.\",\n },\n stance: TrigramStance.SON,\n type: CombatAttackType.STRIKE,\n damageType: DamageType.PRESSURE,\n damage: 30,\n kiCost: 24,\n staminaCost: 22,\n accuracy: 0.88,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.95,\n },\n executionTime: 770,\n recoveryTime: 1330,\n critChance: 0.24,\n critMultiplier: 2.1,\n effects: [],\n // Animation: Throat strike\n animationType: AnimationType.JAB,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_throat_strike\", // ID: unique 1-1 mapping\n },\n {\n id: \"darkops_solar_plexus_paralyze\",\n name: {\n korean: \"명치마비\",\n english: \"Solar Plexus Paralysis\",\n romanized: \"Myeongchi Mabi\",\n },\n koreanName: \"명치마비\",\n englishName: \"Solar Plexus Paralysis\",\n romanized: \"Myeongchi Mabi\",\n description: {\n korean:\n \"명치를 정밀 타격하여 횡격막 마비와 호흡 정지. 심야작전부대 야간 전술.\",\n english:\n \"Precise solar plexus strike causing diaphragm paralysis and breath cessation. Nightfall Squadron night tactic.\",\n },\n stance: TrigramStance.LI,\n type: CombatAttackType.THRUST,\n damageType: DamageType.NERVE,\n damage: 32,\n kiCost: 28,\n staminaCost: 24,\n accuracy: 0.9,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.95,\n },\n executionTime: 840,\n recoveryTime: 1400,\n critChance: 0.26,\n critMultiplier: 2.2,\n effects: [],\n // Animation: Precision thrust\n animationType: AnimationType.JAB,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_solar_plexus_paralyze\", // ID: unique 1-1 mapping\n },\n\n // ===== 블랙옵스부대 (Black Ops Task Force) - Cyber-Enhanced Combat =====\n {\n id: \"darkops_brachial_plexus_strike\",\n name: {\n korean: \"상완신경타격\",\n english: \"Brachial Plexus Strike\",\n romanized: \"Sangwan Singyeong Tagyeok\",\n },\n koreanName: \"상완신경타격\",\n englishName: \"Brachial Plexus Strike\",\n romanized: \"Sangwan Singyeong Tagyeok\",\n description: {\n korean:\n \"상완 신경총을 타격하여 팔 전체 마비. 블랙옵스 사이버 분석 기반 정밀 타격.\",\n english:\n \"Brachial plexus strike causing complete arm paralysis. Black Ops cyber-analysis precision targeting.\",\n },\n stance: TrigramStance.LI,\n type: CombatAttackType.NERVE_STRIKE,\n damageType: DamageType.NERVE,\n damage: 28,\n kiCost: 26,\n staminaCost: 20,\n accuracy: 0.94,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.95,\n },\n executionTime: 770,\n recoveryTime: 1260,\n critChance: 0.28,\n critMultiplier: 2.3,\n effects: [],\n // Animation: Arm strike\n animationType: AnimationType.JAB,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_brachial_plexus_strike\", // ID: unique 1-1 mapping\n },\n {\n id: \"darkops_femoral_nerve_strike\",\n name: {\n korean: \"대퇴신경타격\",\n english: \"Femoral Nerve Strike\",\n romanized: \"Daetoe Singyeong Tagyeok\",\n },\n koreanName: \"대퇴신경타격\",\n englishName: \"Femoral Nerve Strike\",\n romanized: \"Daetoe Singyeong Tagyeok\",\n description: {\n korean: \"대퇴 신경을 타격하여 다리 이동 불가. 블랙옵스 디지털 표적 지정.\",\n english:\n \"Femoral nerve strike disabling leg mobility. Black Ops digital targeting system.\",\n },\n stance: TrigramStance.LI,\n type: CombatAttackType.KICK,\n damageType: DamageType.NERVE,\n damage: 30,\n kiCost: 24,\n staminaCost: 26,\n accuracy: 0.9,\n reachConfig: {\n bodyPart: \"leg\",\n techniqueType: \"kick\",\n baseExtension: 0.95,\n },\n executionTime: 840,\n recoveryTime: 1400,\n critChance: 0.24,\n critMultiplier: 2.1,\n effects: [],\n // Animation: Low kick to thigh\n animationType: AnimationType.LOW_KICK,\n animationSpeed: 0.75,\n animationCategory: \"kick\", // Type: shared category\n animationId: \"darkops_femoral_nerve_strike\", // ID: unique 1-1 mapping\n },\n\n // ===== 심해침투부대 (Deep Sea Unit) - Amphibious Combat =====\n {\n id: \"darkops_rear_choke\",\n name: {\n korean: \"후방목졸임\",\n english: \"Rear Naked Choke\",\n romanized: \"Hubang Mokjorim\",\n },\n koreanName: \"후방목졸임\",\n englishName: \"Rear Naked Choke\",\n romanized: \"Hubang Mokjorim\",\n description: {\n korean:\n \"후방에서 목을 조여 혈류 차단과 의식 상실. 심해침투부대 수중 전투 기술.\",\n english:\n \"Rear choke cutting blood flow and causing unconsciousness. Deep Sea Unit underwater combat technique.\",\n },\n stance: TrigramStance.GAM,\n type: CombatAttackType.GRAPPLE,\n damageType: DamageType.PRESSURE,\n damage: 34,\n kiCost: 30,\n staminaCost: 32,\n accuracy: 0.86,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 1120,\n recoveryTime: 1680,\n critChance: 0.22,\n critMultiplier: 2.0,\n effects: [],\n // Animation: Rear choke hold\n animationType: AnimationType.GRAPPLE,\n animationSpeed: 0.7,\n animationCategory: \"grapple\", // Type: shared category\n animationId: \"darkops_rear_choke\", // ID: unique 1-1 mapping\n },\n {\n id: \"darkops_spinal_strike\",\n name: {\n korean: \"척추타격\",\n english: \"Spinal Column Strike\",\n romanized: \"Cheokchu Tagyeok\",\n },\n koreanName: \"척추타격\",\n englishName: \"Spinal Column Strike\",\n romanized: \"Cheokchu Tagyeok\",\n description: {\n korean:\n \"척추를 타격하여 전신 마비와 의식 상실. 심해침투부대 치명적 기술.\",\n english:\n \"Spinal column strike causing full-body paralysis and unconsciousness. Deep Sea Unit lethal technique.\",\n },\n stance: TrigramStance.GEON,\n type: CombatAttackType.STRIKE,\n damageType: DamageType.NERVE,\n damage: 40,\n kiCost: 35,\n staminaCost: 35,\n accuracy: 0.78,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.95,\n },\n executionTime: 1050,\n recoveryTime: 1610,\n critChance: 0.3,\n critMultiplier: 2.5,\n effects: [],\n // Animation: Powerful back strike\n animationType: AnimationType.CROSS,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_spinal_strike\", // ID: unique 1-1 mapping\n },\n\n // ===== Additional Dark Ops Techniques - Mixed Units =====\n {\n id: \"darkops_jaw_dislocation\",\n name: {\n korean: \"턱탈구\",\n english: \"Jaw Dislocation\",\n romanized: \"Teok Talgu\",\n },\n koreanName: \"턱탈구\",\n englishName: \"Jaw Dislocation\",\n romanized: \"Teok Talgu\",\n description: {\n korean: \"턱을 비틀어 탈구시키고 의식 혼미. 암흑작전부대 신속 무력화.\",\n english:\n \"Twisting jaw causing dislocation and disorientation. Dark Operations rapid incapacitation.\",\n },\n stance: TrigramStance.TAE,\n type: CombatAttackType.GRAPPLE,\n damageType: DamageType.JOINT,\n damage: 30,\n kiCost: 22,\n staminaCost: 24,\n accuracy: 0.88,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.65,\n },\n executionTime: 840,\n recoveryTime: 1400,\n critChance: 0.24,\n critMultiplier: 2.0,\n effects: [],\n // Animation: Jaw manipulation (grapple-based dislocation)\n animationType: AnimationType.GRAPPLE,\n animationSpeed: 0.7,\n animationCategory: \"grapple\", // Type: shared category\n animationId: \"darkops_jaw_dislocation\", // ID: unique 1-1 mapping\n },\n {\n id: \"darkops_temple_strike\",\n name: {\n korean: \"관자놀이급타\",\n english: \"Temple Knockout Strike\",\n romanized: \"Gwanja-nori Geubta\",\n },\n koreanName: \"관자놀이급타\",\n englishName: \"Temple Knockout Strike\",\n romanized: \"Gwanja-nori Geubta\",\n description: {\n korean: \"관자놀이를 정확히 타격하여 즉시 의식 상실. 블랙옵스 치명 타격.\",\n english:\n \"Precise temple strike causing immediate unconsciousness. Black Ops lethal targeting.\",\n },\n stance: TrigramStance.LI,\n type: CombatAttackType.STRIKE,\n damageType: DamageType.BLUNT,\n damage: 38,\n kiCost: 32,\n staminaCost: 28,\n accuracy: 0.92,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 770,\n recoveryTime: 1330,\n critChance: 0.32,\n critMultiplier: 2.4,\n effects: [],\n // Animation: Temple strike\n animationType: AnimationType.HOOK,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_temple_strike\", // ID: unique 1-1 mapping\n },\n {\n id: \"darkops_achilles_sever\",\n name: {\n korean: \"아킬레스절단\",\n english: \"Achilles Tendon Sever\",\n romanized: \"Akilles Jeoldan\",\n },\n koreanName: \"아킬레스절단\",\n englishName: \"Achilles Tendon Sever\",\n romanized: \"Akilles Jeoldan\",\n description: {\n korean: \"아킬레스건을 공격하여 이동 불가. 암흑특공대 무력화 기술.\",\n english:\n \"Achilles tendon strike disabling mobility. Shadow Commando incapacitation technique.\",\n },\n stance: TrigramStance.GON,\n type: CombatAttackType.KICK,\n damageType: DamageType.CRUSHING,\n damage: 32,\n kiCost: 26,\n staminaCost: 28,\n accuracy: 0.84,\n reachConfig: {\n bodyPart: \"leg\",\n techniqueType: \"kick\",\n baseExtension: 0.95,\n },\n executionTime: 909,\n recoveryTime: 1470,\n critChance: 0.26,\n critMultiplier: 2.2,\n effects: [],\n // Animation: Low cutting kick\n animationType: AnimationType.LOW_KICK,\n animationSpeed: 0.75,\n animationCategory: \"kick\", // Type: shared category\n animationId: \"darkops_achilles_sever\", // ID: unique 1-1 mapping\n },\n {\n id: \"darkops_ear_strike\",\n name: {\n korean: \"귓바퀴타격\",\n english: \"Ear Box Strike\",\n romanized: \"Gwitbakwi Tagyeok\",\n },\n koreanName: \"귓바퀴타격\",\n englishName: \"Ear Box Strike\",\n romanized: \"Gwitbakwi Tagyeok\",\n description: {\n korean:\n \"양쪽 귀를 동시 타격하여 고막 파열과 평형 상실. 심야작전부대 방향 감각 교란.\",\n english:\n \"Simultaneous ear strikes rupturing eardrums and disrupting balance. Nightfall Squadron disorientation tactic.\",\n },\n stance: TrigramStance.SON,\n type: CombatAttackType.STRIKE,\n damageType: DamageType.BLUNT,\n damage: 28,\n kiCost: 24,\n staminaCost: 22,\n accuracy: 0.86,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 700,\n recoveryTime: 1260,\n critChance: 0.22,\n critMultiplier: 2.0,\n effects: [],\n // Animation: Double palm strike\n animationType: AnimationType.PALM_STRIKE,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_ear_strike\", // ID: unique 1-1 mapping\n },\n {\n id: \"darkops_eye_gouge\",\n name: {\n korean: \"안구공격\",\n english: \"Eye Strike\",\n romanized: \"Angu Gonggyeok\",\n },\n koreanName: \"안구공격\",\n englishName: \"Eye Strike\",\n romanized: \"Angu Gonggyeok\",\n description: {\n korean:\n \"눈을 정밀 공격하여 시각 상실과 전투 무력화. 암살자 특화 치명 기술.\",\n english:\n \"Precise eye strike causing vision loss and combat incapacitation. Assassin specialty lethal technique.\",\n },\n stance: TrigramStance.LI,\n type: CombatAttackType.THRUST,\n damageType: DamageType.PIERCING,\n damage: 36,\n kiCost: 30,\n staminaCost: 26,\n accuracy: 0.9,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.95,\n },\n executionTime: 700,\n recoveryTime: 1260,\n critChance: 0.3,\n critMultiplier: 2.4,\n effects: [],\n // Animation: Precision finger thrust\n animationType: AnimationType.JAB,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_eye_gouge\", // ID: unique 1-1 mapping\n },\n] as const;\n\n// =====================================================\n// DARK OPS CONFIGURATION\n// =====================================================\n\n/**\n * Dark Ops archetype bonus configuration\n * 암살자 (Amsalja) gets +30% effectiveness with all Dark Ops techniques\n */\nexport const DARK_OPS_ARCHETYPE_BONUSES: Record<PlayerArchetype, number> = {\n [PlayerArchetype.AMSALJA]: 1.3, // +30% for Shadow Assassin archetype\n [PlayerArchetype.JEONGBO_YOWON]: 1.15, // +15% for Intelligence Operative\n [PlayerArchetype.HACKER]: 1.1, // +10% for Cyber Warrior (tech synergy)\n [PlayerArchetype.MUSA]: 0.85, // -15% for Traditional Warrior (dishonorable)\n [PlayerArchetype.JOJIK_POKRYEOKBAE]: 1.05, // +5% for Organized Crime (ruthless)\n} as const;\n\n/**\n * Dark Ops night operations bonus\n * Time-of-day effectiveness multiplier (simulated)\n */\nexport const DARK_OPS_NIGHT_BONUS = {\n night: 1.25, // +25% at night (00:00 - 06:00, 18:00 - 23:59)\n day: 1.0, // Normal during day (06:00 - 18:00)\n twilight: 1.15, // +15% during twilight (05:00 - 07:00, 17:00 - 19:00)\n} as const;\n\n/**\n * Dark Ops special effects configuration\n */\nexport const DARK_OPS_SPECIAL_EFFECTS = {\n silent: {\n korean: \"무음 공격\",\n english: \"Silent Attack\",\n description: {\n korean: \"적에게 경보를 발생시키지 않음\",\n english: \"Does not alert enemies\",\n },\n noAlert: true,\n },\n paralysis: {\n korean: \"마비\",\n english: \"Paralysis\",\n description: {\n korean: \"일시적 또는 영구적 사지 마비\",\n english: \"Temporary or permanent limb paralysis\",\n },\n duration: 3000, // 3 seconds\n },\n unconsciousness: {\n korean: \"의식 상실\",\n english: \"Unconsciousness\",\n description: {\n korean: \"즉시 의식을 잃음\",\n english: \"Immediate loss of consciousness\",\n },\n duration: 5000, // 5 seconds\n },\n breathingDifficulty: {\n korean: \"호흡 곤란\",\n english: \"Breathing Difficulty\",\n description: {\n korean: \"호흡 재생 -75%\",\n english: \"Breathing regen -75%\",\n },\n staminaRegenPenalty: -0.75,\n duration: 5000, // 5 seconds\n },\n disorientation: {\n korean: \"방향 감각 상실\",\n english: \"Disorientation\",\n description: {\n korean: \"정확도 -50%\",\n english: \"Accuracy -50%\",\n },\n accuracyPenalty: -0.5,\n duration: 4000, // 4 seconds\n },\n} as const;\n\n// =====================================================\n// HELPER FUNCTIONS\n// =====================================================\n\n/**\n * Get Dark Ops techniques count\n */\nexport const DARK_OPS_TECHNIQUE_COUNT = DARK_OPS_TECHNIQUES.length;\n\n/**\n * Get Dark Ops technique by ID\n */\nexport function getDarkOpsTechniqueById(\n id: string,\n): KoreanTechnique | undefined {\n return DARK_OPS_TECHNIQUES.find((t) => t.id === id);\n}\n\n/**\n * Get all Dark Ops techniques for a specific unit\n */\nexport function getDarkOpsTechniquesByUnit(\n unitType: keyof typeof DARK_OPS_UNITS,\n): readonly KoreanTechnique[] {\n // Map technique IDs to units based on prefix patterns\n const unitPrefixMap: Record<string, string[]> = {\n DARK_OPERATIONS: [\"darkops_silent_carotid\", \"darkops_jaw_dislocation\"],\n SHADOW_COMMANDO: [\n \"darkops_liver_disruption\",\n \"darkops_kidney_strike\",\n \"darkops_achilles_sever\",\n ],\n NIGHTFALL_SQUADRON: [\n \"darkops_throat_strike\",\n \"darkops_solar_plexus_paralyze\",\n \"darkops_ear_strike\",\n ],\n BLACK_OPS_TASK_FORCE: [\n \"darkops_nerve_paralysis\",\n \"darkops_brachial_plexus_strike\",\n \"darkops_femoral_nerve_strike\",\n \"darkops_temple_strike\",\n ],\n DEEP_SEA_UNIT: [\"darkops_rear_choke\", \"darkops_spinal_strike\"],\n };\n\n const techniqueIds = unitPrefixMap[unitType] ?? [];\n return DARK_OPS_TECHNIQUES.filter((t) => techniqueIds.includes(t.id));\n}\n\n/**\n * Get archetype effectiveness multiplier for Dark Ops\n */\nexport function getDarkOpsArchetypeBonus(archetype: PlayerArchetype): number {\n return DARK_OPS_ARCHETYPE_BONUSES[archetype] ?? 1.0;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DarkOpsTechniques.js","names":[],"sources":["../../../../src/systems/trigram/techniques/DarkOpsTechniques.ts"],"sourcesContent":["/**\n * 🌑 Dark Ops Techniques (암흑작전 기술)\n * Silent Incapacitation & Tactical Assassination\n *\n * Special operations techniques designed for the 암살자 (Amsalja) archetype.\n * Based on 5 specialized Korean Dark Ops units with focus on silent takedowns,\n * nerve disruption, and rapid incapacitation.\n *\n * Philosophy: \"그림자처럼 움직이고 바람처럼 사라져라\"\n * Move like shadow, vanish like wind\n *\n * @module DarkOpsTechniques\n */\n\nimport type { KoreanTechnique } from \"@/systems/vitalpoint\";\nimport {\n CombatAttackType,\n DamageType,\n PlayerArchetype,\n TrigramStance,\n} from \"../../../types/common\";\nimport { AnimationType } from \"../../animation\";\n\n// =====================================================\n// DARK OPS UNIT DEFINITIONS\n// =====================================================\n\n/**\n * Dark Ops unit specializations (암흑작전 부대 특화)\n */\nexport const DARK_OPS_UNITS = {\n DARK_OPERATIONS: \"암흑작전부대\", // Dark Operations Unit - Silent Infiltration\n SHADOW_COMMANDO: \"암흑특공대\", // Shadow Commando Brigade - Demolition Tactics\n NIGHTFALL_SQUADRON: \"심야작전부대\", // Nightfall Squadron - Night Operations\n BLACK_OPS_TASK_FORCE: \"블랙옵스부대\", // Black Ops Task Force - Cyber-Enhanced\n DEEP_SEA_UNIT: \"심해침투부대\", // Deep Sea Unit - Amphibious Combat\n} as const;\n\n// =====================================================\n// DARK OPS TECHNIQUES\n// =====================================================\n\n/**\n * Dark Ops techniques array - Silent incapacitation and tactical assassination\n * Designed for 암살자 (Amsalja) archetype with +30% effectiveness bonus\n *\n * Animation speeds are calibrated for stealth and precision:\n * - Silent: 0.8-0.9 (slow, controlled movements)\n * - Normal: 1.0 (standard techniques)\n * - Rapid: 1.1-1.2 (quick incapacitation)\n */\nexport const DARK_OPS_TECHNIQUES: readonly KoreanTechnique[] = [\n // ===== 암흑작전부대 (Dark Operations Unit) - Silent Infiltration =====\n {\n id: \"darkops_silent_carotid\",\n name: {\n korean: \"은밀 경동맥 차단\",\n english: \"Silent Carotid Strike\",\n romanized: \"Eunmil Gyeongdongmaek Chadan\",\n },\n koreanName: \"은밀 경동맥 차단\",\n englishName: \"Silent Carotid Strike\",\n romanized: \"Eunmil Gyeongdongmaek Chadan\",\n description: {\n korean:\n \"경동맥을 압박하여 소리 없이 실신시킴. 3초 내 무의식 유발. 암흑작전부대의 침투 기술.\",\n english:\n \"Silent carotid compression causing unconsciousness within 3 seconds. Dark Operations Unit infiltration technique.\",\n },\n stance: TrigramStance.GAM,\n type: CombatAttackType.PRESSURE_POINT,\n damageType: DamageType.PRESSURE,\n damage: 28,\n kiCost: 30,\n staminaCost: 25,\n accuracy: 0.92,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 840,\n recoveryTime: 1400,\n critChance: 0.25,\n critMultiplier: 2.0,\n effects: [],\n // Animation: Silent choking motion\n animationType: AnimationType.GRAPPLE,\n animationSpeed: 0.65,\n animationCategory: \"grapple\", // Type: shared category\n animationId: \"darkops_silent_carotid\", // ID: unique 1-1 mapping\n },\n {\n id: \"darkops_nerve_paralysis\",\n name: {\n korean: \"신경마비타격\",\n english: \"Nerve Paralysis Strike\",\n romanized: \"Singyeong Mabi Tagyeok\",\n },\n koreanName: \"신경마비타격\",\n englishName: \"Nerve Paralysis Strike\",\n romanized: \"Singyeong Mabi Tagyeok\",\n description: {\n korean: \"신경총을 정밀 타격하여 사지 마비 유발. 블랙옵스 기술 강화.\",\n english:\n \"Precise nerve cluster strike causing limb paralysis. Black Ops tech-enhanced technique.\",\n },\n stance: TrigramStance.LI,\n type: CombatAttackType.NERVE_STRIKE,\n damageType: DamageType.NERVE,\n damage: 26,\n kiCost: 25,\n staminaCost: 20,\n accuracy: 0.95,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.95,\n },\n executionTime: 700,\n recoveryTime: 1260,\n critChance: 0.3,\n critMultiplier: 2.2,\n effects: [],\n // Animation: Precision nerve strike\n animationType: AnimationType.JAB,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_nerve_paralysis\", // ID: unique 1-1 mapping\n },\n\n // ===== 암흑특공대 (Shadow Commando Brigade) - Demolition Tactics =====\n {\n id: \"darkops_liver_disruption\",\n name: {\n korean: \"간 타격\",\n english: \"Liver Disruption Strike\",\n romanized: \"Gan Tagyeok\",\n },\n koreanName: \"간 타격\",\n englishName: \"Liver Disruption Strike\",\n romanized: \"Gan Tagyeok\",\n description: {\n korean:\n \"간을 강타하여 내부 출혈과 급격한 체력 소진 유발. 암흑특공대 폭파 전술.\",\n english:\n \"Powerful liver strike causing internal trauma and rapid stamina drain. Shadow Commando explosive tactic.\",\n },\n stance: TrigramStance.JIN,\n type: CombatAttackType.STRIKE,\n damageType: DamageType.INTERNAL,\n damage: 35,\n kiCost: 28,\n staminaCost: 30,\n accuracy: 0.85,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 979,\n recoveryTime: 1540,\n critChance: 0.22,\n critMultiplier: 2.1,\n effects: [],\n // Animation: Powerful body hook\n animationType: AnimationType.HOOK,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_liver_disruption\", // ID: unique 1-1 mapping\n },\n {\n id: \"darkops_kidney_strike\",\n name: {\n korean: \"신장충격\",\n english: \"Kidney Shock\",\n romanized: \"Sinjang Chunggyeok\",\n },\n koreanName: \"신장충격\",\n englishName: \"Kidney Shock\",\n romanized: \"Sinjang Chunggyeok\",\n description: {\n korean:\n \"신장을 타격하여 극심한 고통과 일시적 마비 유발. 폭발적 힘의 암흑특공대 기술.\",\n english:\n \"Kidney strike causing severe pain and temporary paralysis. Shadow Commando explosive force technique.\",\n },\n stance: TrigramStance.JIN,\n type: CombatAttackType.STRIKE,\n damageType: DamageType.INTERNAL,\n damage: 33,\n kiCost: 26,\n staminaCost: 28,\n accuracy: 0.82,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 909,\n recoveryTime: 1470,\n critChance: 0.2,\n critMultiplier: 2.0,\n effects: [],\n // Animation: Short hook to kidney\n animationType: AnimationType.HOOK,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_kidney_strike\", // ID: unique 1-1 mapping\n },\n\n // ===== 심야작전부대 (Nightfall Squadron) - Night Operations =====\n {\n id: \"darkops_throat_strike\",\n name: {\n korean: \"후두차단\",\n english: \"Throat Disruption\",\n romanized: \"Hudu Chadan\",\n },\n koreanName: \"후두차단\",\n englishName: \"Throat Disruption\",\n romanized: \"Hudu Chadan\",\n description: {\n korean:\n \"후두를 타격하여 호흡 곤란과 발성 불가 유발. 심야작전부대의 무음 제압술.\",\n english:\n \"Throat strike causing breathing difficulty and voice loss. Nightfall Squadron silent suppression technique.\",\n },\n stance: TrigramStance.SON,\n type: CombatAttackType.STRIKE,\n damageType: DamageType.PRESSURE,\n damage: 30,\n kiCost: 24,\n staminaCost: 22,\n accuracy: 0.88,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.95,\n },\n executionTime: 770,\n recoveryTime: 1330,\n critChance: 0.24,\n critMultiplier: 2.1,\n effects: [],\n // Animation: Throat strike\n animationType: AnimationType.JAB,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_throat_strike\", // ID: unique 1-1 mapping\n },\n {\n id: \"darkops_solar_plexus_paralyze\",\n name: {\n korean: \"명치마비\",\n english: \"Solar Plexus Paralysis\",\n romanized: \"Myeongchi Mabi\",\n },\n koreanName: \"명치마비\",\n englishName: \"Solar Plexus Paralysis\",\n romanized: \"Myeongchi Mabi\",\n description: {\n korean:\n \"명치를 정밀 타격하여 횡격막 마비와 호흡 정지. 심야작전부대 야간 전술.\",\n english:\n \"Precise solar plexus strike causing diaphragm paralysis and breath cessation. Nightfall Squadron night tactic.\",\n },\n stance: TrigramStance.LI,\n type: CombatAttackType.THRUST,\n damageType: DamageType.NERVE,\n damage: 32,\n kiCost: 28,\n staminaCost: 24,\n accuracy: 0.9,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.95,\n },\n executionTime: 840,\n recoveryTime: 1400,\n critChance: 0.26,\n critMultiplier: 2.2,\n effects: [],\n // Animation: Precision thrust\n animationType: AnimationType.JAB,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_solar_plexus_paralyze\", // ID: unique 1-1 mapping\n },\n\n // ===== 블랙옵스부대 (Black Ops Task Force) - Cyber-Enhanced Combat =====\n {\n id: \"darkops_brachial_plexus_strike\",\n name: {\n korean: \"상완신경타격\",\n english: \"Brachial Plexus Strike\",\n romanized: \"Sangwan Singyeong Tagyeok\",\n },\n koreanName: \"상완신경타격\",\n englishName: \"Brachial Plexus Strike\",\n romanized: \"Sangwan Singyeong Tagyeok\",\n description: {\n korean:\n \"상완 신경총을 타격하여 팔 전체 마비. 블랙옵스 사이버 분석 기반 정밀 타격.\",\n english:\n \"Brachial plexus strike causing complete arm paralysis. Black Ops cyber-analysis precision targeting.\",\n },\n stance: TrigramStance.LI,\n type: CombatAttackType.NERVE_STRIKE,\n damageType: DamageType.NERVE,\n damage: 28,\n kiCost: 26,\n staminaCost: 20,\n accuracy: 0.94,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.95,\n },\n executionTime: 770,\n recoveryTime: 1260,\n critChance: 0.28,\n critMultiplier: 2.3,\n effects: [],\n // Animation: Arm strike\n animationType: AnimationType.JAB,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_brachial_plexus_strike\", // ID: unique 1-1 mapping\n },\n {\n id: \"darkops_femoral_nerve_strike\",\n name: {\n korean: \"대퇴신경타격\",\n english: \"Femoral Nerve Strike\",\n romanized: \"Daetoe Singyeong Tagyeok\",\n },\n koreanName: \"대퇴신경타격\",\n englishName: \"Femoral Nerve Strike\",\n romanized: \"Daetoe Singyeong Tagyeok\",\n description: {\n korean: \"대퇴 신경을 타격하여 다리 이동 불가. 블랙옵스 디지털 표적 지정.\",\n english:\n \"Femoral nerve strike disabling leg mobility. Black Ops digital targeting system.\",\n },\n stance: TrigramStance.LI,\n type: CombatAttackType.KICK,\n damageType: DamageType.NERVE,\n damage: 30,\n kiCost: 24,\n staminaCost: 26,\n accuracy: 0.9,\n reachConfig: {\n bodyPart: \"leg\",\n techniqueType: \"kick\",\n baseExtension: 0.95,\n },\n executionTime: 840,\n recoveryTime: 1400,\n critChance: 0.24,\n critMultiplier: 2.1,\n effects: [],\n // Animation: Low kick to thigh\n animationType: AnimationType.LOW_KICK,\n animationSpeed: 0.75,\n animationCategory: \"kick\", // Type: shared category\n animationId: \"darkops_femoral_nerve_strike\", // ID: unique 1-1 mapping\n },\n\n // ===== 심해침투부대 (Deep Sea Unit) - Amphibious Combat =====\n {\n id: \"darkops_rear_choke\",\n name: {\n korean: \"후방목졸임\",\n english: \"Rear Naked Choke\",\n romanized: \"Hubang Mokjorim\",\n },\n koreanName: \"후방목졸임\",\n englishName: \"Rear Naked Choke\",\n romanized: \"Hubang Mokjorim\",\n description: {\n korean:\n \"후방에서 목을 조여 혈류 차단과 의식 상실. 심해침투부대 수중 전투 기술.\",\n english:\n \"Rear choke cutting blood flow and causing unconsciousness. Deep Sea Unit underwater combat technique.\",\n },\n stance: TrigramStance.GAM,\n type: CombatAttackType.GRAPPLE,\n damageType: DamageType.PRESSURE,\n damage: 34,\n kiCost: 30,\n staminaCost: 32,\n accuracy: 0.86,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 1120,\n recoveryTime: 1680,\n critChance: 0.22,\n critMultiplier: 2.0,\n effects: [],\n // Animation: Rear choke hold\n animationType: AnimationType.GRAPPLE,\n animationSpeed: 0.7,\n animationCategory: \"grapple\", // Type: shared category\n animationId: \"darkops_rear_choke\", // ID: unique 1-1 mapping\n },\n {\n id: \"darkops_spinal_strike\",\n name: {\n korean: \"척추타격\",\n english: \"Spinal Column Strike\",\n romanized: \"Cheokchu Tagyeok\",\n },\n koreanName: \"척추타격\",\n englishName: \"Spinal Column Strike\",\n romanized: \"Cheokchu Tagyeok\",\n description: {\n korean:\n \"척추를 타격하여 전신 마비와 의식 상실. 심해침투부대 치명적 기술.\",\n english:\n \"Spinal column strike causing full-body paralysis and unconsciousness. Deep Sea Unit lethal technique.\",\n },\n stance: TrigramStance.GEON,\n type: CombatAttackType.STRIKE,\n damageType: DamageType.NERVE,\n damage: 40,\n kiCost: 35,\n staminaCost: 35,\n accuracy: 0.78,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.95,\n },\n executionTime: 1050,\n recoveryTime: 1610,\n critChance: 0.3,\n critMultiplier: 2.5,\n effects: [],\n // Animation: Powerful back strike\n animationType: AnimationType.CROSS,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_spinal_strike\", // ID: unique 1-1 mapping\n },\n\n // ===== Additional Dark Ops Techniques - Mixed Units =====\n {\n id: \"darkops_jaw_dislocation\",\n name: {\n korean: \"턱탈구\",\n english: \"Jaw Dislocation\",\n romanized: \"Teok Talgu\",\n },\n koreanName: \"턱탈구\",\n englishName: \"Jaw Dislocation\",\n romanized: \"Teok Talgu\",\n description: {\n korean: \"턱을 비틀어 탈구시키고 의식 혼미. 암흑작전부대 신속 무력화.\",\n english:\n \"Twisting jaw causing dislocation and disorientation. Dark Operations rapid incapacitation.\",\n },\n stance: TrigramStance.TAE,\n type: CombatAttackType.GRAPPLE,\n damageType: DamageType.JOINT,\n damage: 30,\n kiCost: 22,\n staminaCost: 24,\n accuracy: 0.88,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.65,\n },\n executionTime: 840,\n recoveryTime: 1400,\n critChance: 0.24,\n critMultiplier: 2.0,\n effects: [],\n // Animation: Jaw manipulation (grapple-based dislocation)\n animationType: AnimationType.GRAPPLE,\n animationSpeed: 0.7,\n animationCategory: \"grapple\", // Type: shared category\n animationId: \"darkops_jaw_dislocation\", // ID: unique 1-1 mapping\n },\n {\n id: \"darkops_temple_strike\",\n name: {\n korean: \"관자놀이급타\",\n english: \"Temple Knockout Strike\",\n romanized: \"Gwanja-nori Geubta\",\n },\n koreanName: \"관자놀이급타\",\n englishName: \"Temple Knockout Strike\",\n romanized: \"Gwanja-nori Geubta\",\n description: {\n korean: \"관자놀이를 정확히 타격하여 즉시 의식 상실. 블랙옵스 치명 타격.\",\n english:\n \"Precise temple strike causing immediate unconsciousness. Black Ops lethal targeting.\",\n },\n stance: TrigramStance.LI,\n type: CombatAttackType.STRIKE,\n damageType: DamageType.BLUNT,\n damage: 38,\n kiCost: 32,\n staminaCost: 28,\n accuracy: 0.92,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 770,\n recoveryTime: 1330,\n critChance: 0.32,\n critMultiplier: 2.4,\n effects: [],\n // Animation: Temple strike\n animationType: AnimationType.HOOK,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_temple_strike\", // ID: unique 1-1 mapping\n },\n {\n id: \"darkops_achilles_sever\",\n name: {\n korean: \"아킬레스절단\",\n english: \"Achilles Tendon Sever\",\n romanized: \"Akilles Jeoldan\",\n },\n koreanName: \"아킬레스절단\",\n englishName: \"Achilles Tendon Sever\",\n romanized: \"Akilles Jeoldan\",\n description: {\n korean: \"아킬레스건을 공격하여 이동 불가. 암흑특공대 무력화 기술.\",\n english:\n \"Achilles tendon strike disabling mobility. Shadow Commando incapacitation technique.\",\n },\n stance: TrigramStance.GON,\n type: CombatAttackType.KICK,\n damageType: DamageType.CRUSHING,\n damage: 32,\n kiCost: 26,\n staminaCost: 28,\n accuracy: 0.84,\n reachConfig: {\n bodyPart: \"leg\",\n techniqueType: \"kick\",\n baseExtension: 0.95,\n },\n executionTime: 909,\n recoveryTime: 1470,\n critChance: 0.26,\n critMultiplier: 2.2,\n effects: [],\n // Animation: Low cutting kick\n animationType: AnimationType.LOW_KICK,\n animationSpeed: 0.75,\n animationCategory: \"kick\", // Type: shared category\n animationId: \"darkops_achilles_sever\", // ID: unique 1-1 mapping\n },\n {\n id: \"darkops_ear_strike\",\n name: {\n korean: \"귓바퀴타격\",\n english: \"Ear Box Strike\",\n romanized: \"Gwitbakwi Tagyeok\",\n },\n koreanName: \"귓바퀴타격\",\n englishName: \"Ear Box Strike\",\n romanized: \"Gwitbakwi Tagyeok\",\n description: {\n korean:\n \"양쪽 귀를 동시 타격하여 고막 파열과 평형 상실. 심야작전부대 방향 감각 교란.\",\n english:\n \"Simultaneous ear strikes rupturing eardrums and disrupting balance. Nightfall Squadron disorientation tactic.\",\n },\n stance: TrigramStance.SON,\n type: CombatAttackType.STRIKE,\n damageType: DamageType.BLUNT,\n damage: 28,\n kiCost: 24,\n staminaCost: 22,\n accuracy: 0.86,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 700,\n recoveryTime: 1260,\n critChance: 0.22,\n critMultiplier: 2.0,\n effects: [],\n // Animation: Double palm strike\n animationType: AnimationType.PALM_STRIKE,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_ear_strike\", // ID: unique 1-1 mapping\n },\n {\n id: \"darkops_eye_gouge\",\n name: {\n korean: \"안구공격\",\n english: \"Eye Strike\",\n romanized: \"Angu Gonggyeok\",\n },\n koreanName: \"안구공격\",\n englishName: \"Eye Strike\",\n romanized: \"Angu Gonggyeok\",\n description: {\n korean:\n \"눈을 정밀 공격하여 시각 상실과 전투 무력화. 암살자 특화 치명 기술.\",\n english:\n \"Precise eye strike causing vision loss and combat incapacitation. Assassin specialty lethal technique.\",\n },\n stance: TrigramStance.LI,\n type: CombatAttackType.THRUST,\n damageType: DamageType.PIERCING,\n damage: 36,\n kiCost: 30,\n staminaCost: 26,\n accuracy: 0.9,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.95,\n },\n executionTime: 700,\n recoveryTime: 1260,\n critChance: 0.3,\n critMultiplier: 2.4,\n effects: [],\n // Animation: Precision finger thrust\n animationType: AnimationType.JAB,\n animationSpeed: 0.75,\n animationCategory: \"strike\", // Type: shared category\n animationId: \"darkops_eye_gouge\", // ID: unique 1-1 mapping\n },\n] as const;\n\n// =====================================================\n// DARK OPS CONFIGURATION\n// =====================================================\n\n/**\n * Dark Ops archetype bonus configuration\n * 암살자 (Amsalja) gets +30% effectiveness with all Dark Ops techniques\n */\nexport const DARK_OPS_ARCHETYPE_BONUSES: Record<PlayerArchetype, number> = {\n [PlayerArchetype.AMSALJA]: 1.3, // +30% for Shadow Assassin archetype\n [PlayerArchetype.JEONGBO_YOWON]: 1.15, // +15% for Intelligence Operative\n [PlayerArchetype.HACKER]: 1.1, // +10% for Cyber Warrior (tech synergy)\n [PlayerArchetype.MUSA]: 0.85, // -15% for Traditional Warrior (dishonorable)\n [PlayerArchetype.JOJIK_POKRYEOKBAE]: 1.05, // +5% for Organized Crime (ruthless)\n} as const;\n\n/**\n * Dark Ops night operations bonus\n * Time-of-day effectiveness multiplier (simulated)\n */\nexport const DARK_OPS_NIGHT_BONUS = {\n night: 1.25, // +25% at night (00:00 - 06:00, 18:00 - 23:59)\n day: 1.0, // Normal during day (06:00 - 18:00)\n twilight: 1.15, // +15% during twilight (05:00 - 07:00, 17:00 - 19:00)\n} as const;\n\n/**\n * Dark Ops special effects configuration\n */\nexport const DARK_OPS_SPECIAL_EFFECTS = {\n silent: {\n korean: \"무음 공격\",\n english: \"Silent Attack\",\n description: {\n korean: \"적에게 경보를 발생시키지 않음\",\n english: \"Does not alert enemies\",\n },\n noAlert: true,\n },\n paralysis: {\n korean: \"마비\",\n english: \"Paralysis\",\n description: {\n korean: \"일시적 또는 영구적 사지 마비\",\n english: \"Temporary or permanent limb paralysis\",\n },\n duration: 3000, // 3 seconds\n },\n unconsciousness: {\n korean: \"의식 상실\",\n english: \"Unconsciousness\",\n description: {\n korean: \"즉시 의식을 잃음\",\n english: \"Immediate loss of consciousness\",\n },\n duration: 5000, // 5 seconds\n },\n breathingDifficulty: {\n korean: \"호흡 곤란\",\n english: \"Breathing Difficulty\",\n description: {\n korean: \"호흡 재생 -75%\",\n english: \"Breathing regen -75%\",\n },\n staminaRegenPenalty: -0.75,\n duration: 5000, // 5 seconds\n },\n disorientation: {\n korean: \"방향 감각 상실\",\n english: \"Disorientation\",\n description: {\n korean: \"정확도 -50%\",\n english: \"Accuracy -50%\",\n },\n accuracyPenalty: -0.5,\n duration: 4000, // 4 seconds\n },\n} as const;\n\n// =====================================================\n// HELPER FUNCTIONS\n// =====================================================\n\n/**\n * Get Dark Ops techniques count\n */\nexport const DARK_OPS_TECHNIQUE_COUNT = DARK_OPS_TECHNIQUES.length;\n\n/**\n * Get Dark Ops technique by ID\n */\nexport function getDarkOpsTechniqueById(\n id: string,\n): KoreanTechnique | undefined {\n return DARK_OPS_TECHNIQUES.find((t) => t.id === id);\n}\n\n/**\n * Get all Dark Ops techniques for a specific unit\n */\nexport function getDarkOpsTechniquesByUnit(\n unitType: keyof typeof DARK_OPS_UNITS,\n): readonly KoreanTechnique[] {\n // Map technique IDs to units based on prefix patterns\n const unitPrefixMap: Record<string, string[]> = {\n DARK_OPERATIONS: [\"darkops_silent_carotid\", \"darkops_jaw_dislocation\"],\n SHADOW_COMMANDO: [\n \"darkops_liver_disruption\",\n \"darkops_kidney_strike\",\n \"darkops_achilles_sever\",\n ],\n NIGHTFALL_SQUADRON: [\n \"darkops_throat_strike\",\n \"darkops_solar_plexus_paralyze\",\n \"darkops_ear_strike\",\n ],\n BLACK_OPS_TASK_FORCE: [\n \"darkops_nerve_paralysis\",\n \"darkops_brachial_plexus_strike\",\n \"darkops_femoral_nerve_strike\",\n \"darkops_temple_strike\",\n ],\n DEEP_SEA_UNIT: [\"darkops_rear_choke\", \"darkops_spinal_strike\"],\n };\n\n const techniqueIds = unitPrefixMap[unitType] ?? [];\n return DARK_OPS_TECHNIQUES.filter((t) => techniqueIds.includes(t.id));\n}\n\n/**\n * Get archetype effectiveness multiplier for Dark Ops\n */\nexport function getDarkOpsArchetypeBonus(archetype: PlayerArchetype): number {\n return DARK_OPS_ARCHETYPE_BONUSES[archetype] ?? 1.0;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GamTechniques.js","names":[],"sources":["../../../../src/systems/trigram/techniques/GamTechniques.ts"],"sourcesContent":["/**\n * ☵ 감 (GAM) - Water Stance Techniques\n * 수류반격 - Adaptive Flow (Hapkido Redirect & Counter)\n *\n * The Water stance (감괘) embodies adaptation and redirection.\n * Based on Hapkido (합기도) principles of using opponent's force\n * against them, flowing around attacks like water around rocks.\n *\n * Philosophy: \"물처럼 흘러 적의 힘을 이용하라\"\n * Flow like water and use the enemy's force\n *\n * @module GamTechniques\n */\n\nimport type { TrigramStanceTechnique } from \"@/systems/vitalpoint\";\nimport {\n CombatAttackType,\n DamageType,\n TrigramStance,\n} from \"../../../types/common\";\nimport { AnimationType } from \"../../animation\";\n\n/**\n * GAM stance techniques - Water / Adaptive Flow\n * Hapkido redirect and counter techniques\n *\n * Technique characteristics:\n * - Counter-attack focus\n * - Force redirection\n * - Flowing defense-to-offense\n * - Throws using opponent's momentum\n *\n * Animation speeds are calibrated for flowing responses:\n * - Reactive: 1.1-1.2 (quick counters)\n * - Normal: 1.0 (standard redirects)\n * - Controlled: 0.9 (throwing techniques)\n */\nexport const GAM_TECHNIQUES: readonly TrigramStanceTechnique[] = [\n // ============= Primary Technique =============\n {\n id: \"gam_water_counter\",\n name: {\n korean: \"수류반격\",\n english: \"Water Counter\",\n romanized: \"suryu_bangyeok\",\n },\n koreanName: \"수류반격\",\n englishName: \"Water Counter\",\n romanized: \"suryu_bangyeok\",\n description: {\n korean: \"물의 흐름으로 적의 공격을 받아넘기는 반격\",\n english: \"Counter-attack that flows like water\",\n },\n stance: TrigramStance.GAM,\n type: CombatAttackType.COUNTER_ATTACK,\n damageType: DamageType.BLUNT,\n damage: 32,\n kiCost: 20,\n staminaCost: 12,\n accuracy: 0.85,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 1.05,\n },\n executionTime: 840,\n recoveryTime: 1260,\n critChance: 0.18,\n critMultiplier: 1.7,\n effects: [],\n // Combo metadata - Flowing counter starter\n comboWindow: 200,\n comboPriority: 1, // Starter - initiates counter flow\n pressureStacks: 2,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"counter\", // Type: shared category\n animationId: \"gam_water_counter\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Flowing counter-attack (matches TechniqueAnimationMapping)\n animationType: AnimationType.WATER_COUNTER,\n animationSpeed: 0.75,\n category: \"medium\",\n range: \"medium\",\n speed: 1.0,\n },\n\n // ============= Throwing Techniques =============\n {\n id: \"gam_redirect_throw\",\n name: {\n korean: \"유도던지기\",\n english: \"Redirect Throw\",\n romanized: \"yudo-deonjigi\",\n },\n koreanName: \"유도던지기\",\n englishName: \"Redirect Throw\",\n romanized: \"yudo-deonjigi\",\n description: {\n korean: \"합기도 방향전환으로 상대의 힘을 이용해 던짐\",\n english: \"Hapkido redirect using opponent's force for throw\",\n },\n stance: TrigramStance.GAM,\n type: CombatAttackType.THROW,\n damageType: DamageType.BLUNT,\n damage: 30,\n kiCost: 18,\n staminaCost: 24,\n accuracy: 0.82,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.7,\n },\n executionTime: 1190,\n recoveryTime: 1680,\n critChance: 0.16,\n critMultiplier: 1.8,\n effects: [],\n // Combo metadata - Force redirection throw\n comboWindow: 200,\n comboPriority: 2, // Mid-chain - momentum redirection\n pressureStacks: 2,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"throw\", // Type: shared category\n animationId: \"gam_redirect_throw\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Redirect throw motion\n animationType: AnimationType.GAM_REDIRECT_THROW,\n animationSpeed: 0.7,\n category: \"medium\",\n range: \"short\",\n speed: 0.9,\n },\n {\n id: \"gam_hip_throw\",\n name: {\n korean: \"허리던지기\",\n english: \"Hip Throw\",\n romanized: \"heori-deonjigi\",\n },\n koreanName: \"허리던지기\",\n englishName: \"Hip Throw\",\n romanized: \"heori-deonjigi\",\n description: {\n korean: \"합기도 허리 던지기로 상대를 제압\",\n english: \"Hapkido hip throw for control\",\n },\n stance: TrigramStance.GAM,\n type: CombatAttackType.THROW,\n damageType: DamageType.BLUNT,\n damage: 34,\n kiCost: 22,\n staminaCost: 28,\n accuracy: 0.8,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.7,\n },\n executionTime: 1260,\n recoveryTime: 1819,\n critChance: 0.2,\n critMultiplier: 1.9,\n effects: [],\n // Combo metadata - Control throw finisher\n comboWindow: 200,\n comboPriority: 3, // Finisher - dominant position throw\n pressureStacks: 3,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"throw\", // Type: shared category\n animationId: \"gam_hip_throw\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Hip throw motion\n animationType: AnimationType.GAM_HIP_THROW,\n animationSpeed: 0.65,\n category: \"medium\",\n range: \"short\",\n speed: 0.85,\n },\n\n // ============= Blocking & Parry Techniques =============\n {\n id: \"gam_flowing_block\",\n name: {\n korean: \"유수막기\",\n english: \"Flowing Block\",\n romanized: \"yusu-makgi\",\n },\n koreanName: \"유수막기\",\n englishName: \"Flowing Block\",\n romanized: \"yusu-makgi\",\n description: {\n korean: \"물의 흐름처럼 부드럽게 막고 반격\",\n english: \"Soft flowing block leading to counter\",\n },\n stance: TrigramStance.GAM,\n type: CombatAttackType.BLOCK,\n damageType: DamageType.BLUNT,\n damage: 20,\n kiCost: 10,\n staminaCost: 14,\n accuracy: 0.92,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 560,\n recoveryTime: 979,\n critChance: 0.08,\n critMultiplier: 1.3,\n effects: [],\n // Combo metadata - Defensive flow starter\n comboWindow: 200,\n comboPriority: 1, // Starter - soft defensive entry\n pressureStacks: 1,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"defensive\", // Type: shared category\n animationId: \"gam_flowing_block\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Soft blocking motion\n animationType: AnimationType.BLOCK,\n animationSpeed: 0.75,\n category: \"light\",\n range: \"short\",\n speed: 1.0,\n },\n {\n id: \"gam_circular_parry\",\n name: {\n korean: \"원형받기\",\n english: \"Circular Parry\",\n romanized: \"wonhyeong-batgi\",\n },\n koreanName: \"원형받기\",\n englishName: \"Circular Parry\",\n romanized: \"wonhyeong-batgi\",\n description: {\n korean: \"합기도 원형 움직임으로 공격을 무력화\",\n english: \"Hapkido circular motion neutralizing attack\",\n },\n stance: TrigramStance.GAM,\n type: CombatAttackType.COUNTER_ATTACK,\n damageType: DamageType.PRESSURE,\n damage: 24,\n kiCost: 14,\n staminaCost: 18,\n accuracy: 0.88,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 1.05,\n },\n executionTime: 770,\n recoveryTime: 1190,\n critChance: 0.12,\n critMultiplier: 1.5,\n effects: [],\n // Combo metadata - Neutralizing redirect\n comboWindow: 200,\n comboPriority: 2, // Mid-chain - circular neutralization\n pressureStacks: 2,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"defensive\", // Type: shared category\n animationId: \"gam_circular_parry\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Circular parry motion\n animationType: AnimationType.GAM_CIRCULAR_PARRY,\n animationSpeed: 0.75,\n category: \"medium\",\n range: \"medium\",\n speed: 1.0,\n },\n\n // ============= Joint Control Counter =============\n {\n id: \"gam_wrist_twist_counter\",\n name: {\n korean: \"손목비틀기반격\",\n english: \"Wrist Twist Counter\",\n romanized: \"sonmok-biteulgi-bangyeok\",\n },\n koreanName: \"손목비틀기반격\",\n englishName: \"Wrist Twist Counter\",\n romanized: \"sonmok-biteulgi-bangyeok\",\n description: {\n korean: \"공격을 받아 손목을 비틀어 반격\",\n english: \"Counter by catching and twisting wrist\",\n },\n stance: TrigramStance.GAM,\n type: CombatAttackType.COUNTER_ATTACK,\n damageType: DamageType.JOINT,\n damage: 28,\n kiCost: 16,\n staminaCost: 20,\n accuracy: 0.90,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.65,\n },\n executionTime: 979,\n recoveryTime: 1400,\n critChance: 0.25,\n critMultiplier: 2.2,\n effects: [],\n // Combo metadata - Joint control counter finisher\n comboWindow: 200,\n comboPriority: 3, // Finisher - vital point joint lock\n pressureStacks: 3,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"joint_lock\", // Type: shared category\n animationId: \"gam_wrist_twist_counter\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Wrist control transition\n animationType: AnimationType.GAM_WRIST_TWIST_COUNTER,\n animationSpeed: 0.75,\n category: \"special\",\n range: \"short\",\n speed: 1.0,\n },\n] as const;\n\n/**\n * Get GAM techniques count\n */\nexport const GAM_TECHNIQUE_COUNT = GAM_TECHNIQUES.length;\n\n/**\n * Get GAM technique by ID\n */\nexport function getGamTechniqueById(id: string): TrigramStanceTechnique | undefined {\n return GAM_TECHNIQUES.find((t) => t.id === id);\n}\n\n/**\n * Get all GAM techniques by attack type\n */\nexport function getGamTechniquesByType(\n type: CombatAttackType\n): readonly TrigramStanceTechnique[] {\n return GAM_TECHNIQUES.filter((t) => t.type === type);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"GamTechniques.js","names":[],"sources":["../../../../src/systems/trigram/techniques/GamTechniques.ts"],"sourcesContent":["/**\n * ☵ 감 (GAM) - Water Stance Techniques\n * 수류반격 - Adaptive Flow (Hapkido Redirect & Counter)\n *\n * The Water stance (감괘) embodies adaptation and redirection.\n * Based on Hapkido (합기도) principles of using opponent's force\n * against them, flowing around attacks like water around rocks.\n *\n * Philosophy: \"물처럼 흘러 적의 힘을 이용하라\"\n * Flow like water and use the enemy's force\n *\n * @module GamTechniques\n */\n\nimport type { TrigramStanceTechnique } from \"@/systems/vitalpoint\";\nimport {\n CombatAttackType,\n DamageType,\n TrigramStance,\n} from \"../../../types/common\";\nimport { AnimationType } from \"../../animation\";\n\n/**\n * GAM stance techniques - Water / Adaptive Flow\n * Hapkido redirect and counter techniques\n *\n * Technique characteristics:\n * - Counter-attack focus\n * - Force redirection\n * - Flowing defense-to-offense\n * - Throws using opponent's momentum\n *\n * Animation speeds are calibrated for flowing responses:\n * - Reactive: 1.1-1.2 (quick counters)\n * - Normal: 1.0 (standard redirects)\n * - Controlled: 0.9 (throwing techniques)\n */\nexport const GAM_TECHNIQUES: readonly TrigramStanceTechnique[] = [\n // ============= Primary Technique =============\n {\n id: \"gam_water_counter\",\n name: {\n korean: \"수류반격\",\n english: \"Water Counter\",\n romanized: \"suryu_bangyeok\",\n },\n koreanName: \"수류반격\",\n englishName: \"Water Counter\",\n romanized: \"suryu_bangyeok\",\n description: {\n korean: \"물의 흐름으로 적의 공격을 받아넘기는 반격\",\n english: \"Counter-attack that flows like water\",\n },\n stance: TrigramStance.GAM,\n type: CombatAttackType.COUNTER_ATTACK,\n damageType: DamageType.BLUNT,\n damage: 32,\n kiCost: 20,\n staminaCost: 12,\n accuracy: 0.85,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 1.05,\n },\n executionTime: 840,\n recoveryTime: 1260,\n critChance: 0.18,\n critMultiplier: 1.7,\n effects: [],\n // Combo metadata - Flowing counter starter\n comboWindow: 200,\n comboPriority: 1, // Starter - initiates counter flow\n pressureStacks: 2,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"counter\", // Type: shared category\n animationId: \"gam_water_counter\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Flowing counter-attack (matches TechniqueAnimationMapping)\n animationType: AnimationType.WATER_COUNTER,\n animationSpeed: 0.75,\n category: \"medium\",\n range: \"medium\",\n speed: 1.0,\n },\n\n // ============= Throwing Techniques =============\n {\n id: \"gam_redirect_throw\",\n name: {\n korean: \"유도던지기\",\n english: \"Redirect Throw\",\n romanized: \"yudo-deonjigi\",\n },\n koreanName: \"유도던지기\",\n englishName: \"Redirect Throw\",\n romanized: \"yudo-deonjigi\",\n description: {\n korean: \"합기도 방향전환으로 상대의 힘을 이용해 던짐\",\n english: \"Hapkido redirect using opponent's force for throw\",\n },\n stance: TrigramStance.GAM,\n type: CombatAttackType.THROW,\n damageType: DamageType.BLUNT,\n damage: 30,\n kiCost: 18,\n staminaCost: 24,\n accuracy: 0.82,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.7,\n },\n executionTime: 1190,\n recoveryTime: 1680,\n critChance: 0.16,\n critMultiplier: 1.8,\n effects: [],\n // Combo metadata - Force redirection throw\n comboWindow: 200,\n comboPriority: 2, // Mid-chain - momentum redirection\n pressureStacks: 2,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"throw\", // Type: shared category\n animationId: \"gam_redirect_throw\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Redirect throw motion\n animationType: AnimationType.GAM_REDIRECT_THROW,\n animationSpeed: 0.7,\n category: \"medium\",\n range: \"short\",\n speed: 0.9,\n },\n {\n id: \"gam_hip_throw\",\n name: {\n korean: \"허리던지기\",\n english: \"Hip Throw\",\n romanized: \"heori-deonjigi\",\n },\n koreanName: \"허리던지기\",\n englishName: \"Hip Throw\",\n romanized: \"heori-deonjigi\",\n description: {\n korean: \"합기도 허리 던지기로 상대를 제압\",\n english: \"Hapkido hip throw for control\",\n },\n stance: TrigramStance.GAM,\n type: CombatAttackType.THROW,\n damageType: DamageType.BLUNT,\n damage: 34,\n kiCost: 22,\n staminaCost: 28,\n accuracy: 0.8,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.7,\n },\n executionTime: 1260,\n recoveryTime: 1819,\n critChance: 0.2,\n critMultiplier: 1.9,\n effects: [],\n // Combo metadata - Control throw finisher\n comboWindow: 200,\n comboPriority: 3, // Finisher - dominant position throw\n pressureStacks: 3,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"throw\", // Type: shared category\n animationId: \"gam_hip_throw\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Hip throw motion\n animationType: AnimationType.GAM_HIP_THROW,\n animationSpeed: 0.65,\n category: \"medium\",\n range: \"short\",\n speed: 0.85,\n },\n\n // ============= Blocking & Parry Techniques =============\n {\n id: \"gam_flowing_block\",\n name: {\n korean: \"유수막기\",\n english: \"Flowing Block\",\n romanized: \"yusu-makgi\",\n },\n koreanName: \"유수막기\",\n englishName: \"Flowing Block\",\n romanized: \"yusu-makgi\",\n description: {\n korean: \"물의 흐름처럼 부드럽게 막고 반격\",\n english: \"Soft flowing block leading to counter\",\n },\n stance: TrigramStance.GAM,\n type: CombatAttackType.BLOCK,\n damageType: DamageType.BLUNT,\n damage: 20,\n kiCost: 10,\n staminaCost: 14,\n accuracy: 0.92,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 560,\n recoveryTime: 979,\n critChance: 0.08,\n critMultiplier: 1.3,\n effects: [],\n // Combo metadata - Defensive flow starter\n comboWindow: 200,\n comboPriority: 1, // Starter - soft defensive entry\n pressureStacks: 1,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"defensive\", // Type: shared category\n animationId: \"gam_flowing_block\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Soft blocking motion\n animationType: AnimationType.BLOCK,\n animationSpeed: 0.75,\n category: \"light\",\n range: \"short\",\n speed: 1.0,\n },\n {\n id: \"gam_circular_parry\",\n name: {\n korean: \"원형받기\",\n english: \"Circular Parry\",\n romanized: \"wonhyeong-batgi\",\n },\n koreanName: \"원형받기\",\n englishName: \"Circular Parry\",\n romanized: \"wonhyeong-batgi\",\n description: {\n korean: \"합기도 원형 움직임으로 공격을 무력화\",\n english: \"Hapkido circular motion neutralizing attack\",\n },\n stance: TrigramStance.GAM,\n type: CombatAttackType.COUNTER_ATTACK,\n damageType: DamageType.PRESSURE,\n damage: 24,\n kiCost: 14,\n staminaCost: 18,\n accuracy: 0.88,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 1.05,\n },\n executionTime: 770,\n recoveryTime: 1190,\n critChance: 0.12,\n critMultiplier: 1.5,\n effects: [],\n // Combo metadata - Neutralizing redirect\n comboWindow: 200,\n comboPriority: 2, // Mid-chain - circular neutralization\n pressureStacks: 2,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"defensive\", // Type: shared category\n animationId: \"gam_circular_parry\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Circular parry motion\n animationType: AnimationType.GAM_CIRCULAR_PARRY,\n animationSpeed: 0.75,\n category: \"medium\",\n range: \"medium\",\n speed: 1.0,\n },\n\n // ============= Joint Control Counter =============\n {\n id: \"gam_wrist_twist_counter\",\n name: {\n korean: \"손목비틀기반격\",\n english: \"Wrist Twist Counter\",\n romanized: \"sonmok-biteulgi-bangyeok\",\n },\n koreanName: \"손목비틀기반격\",\n englishName: \"Wrist Twist Counter\",\n romanized: \"sonmok-biteulgi-bangyeok\",\n description: {\n korean: \"공격을 받아 손목을 비틀어 반격\",\n english: \"Counter by catching and twisting wrist\",\n },\n stance: TrigramStance.GAM,\n type: CombatAttackType.COUNTER_ATTACK,\n damageType: DamageType.JOINT,\n damage: 28,\n kiCost: 16,\n staminaCost: 20,\n accuracy: 0.90,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.65,\n },\n executionTime: 979,\n recoveryTime: 1400,\n critChance: 0.25,\n critMultiplier: 2.2,\n effects: [],\n // Combo metadata - Joint control counter finisher\n comboWindow: 200,\n comboPriority: 3, // Finisher - vital point joint lock\n pressureStacks: 3,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"joint_lock\", // Type: shared category\n animationId: \"gam_wrist_twist_counter\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Wrist control transition\n animationType: AnimationType.GAM_WRIST_TWIST_COUNTER,\n animationSpeed: 0.75,\n category: \"special\",\n range: \"short\",\n speed: 1.0,\n },\n] as const;\n\n/**\n * Get GAM techniques count\n */\nexport const GAM_TECHNIQUE_COUNT = GAM_TECHNIQUES.length;\n\n/**\n * Get GAM technique by ID\n */\nexport function getGamTechniqueById(id: string): TrigramStanceTechnique | undefined {\n return GAM_TECHNIQUES.find((t) => t.id === id);\n}\n\n/**\n * Get all GAM techniques by attack type\n */\nexport function getGamTechniquesByType(\n type: CombatAttackType\n): readonly TrigramStanceTechnique[] {\n return GAM_TECHNIQUES.filter((t) => t.type === type);\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GanTechniques.js","names":[],"sources":["../../../../src/systems/trigram/techniques/GanTechniques.ts"],"sourcesContent":["/**\n * ☶ 간 (GAN) - Mountain Stance Techniques\n * 반석방어 - Immovable Defense (Hapkido Defensive Mastery)\n *\n * The Mountain stance (간괘) embodies immovable defense and patient counter.\n * Based on Hapkido (합기도) defensive principles - rooted and unshakeable\n * like a mountain, waiting for the perfect moment to counter.\n *\n * Philosophy: \"산처럼 굳건히 서서 때를 기다려라\"\n * Stand firm like a mountain and wait for the moment\n *\n * **ENHANCED DEFENSIVE MECHANICS:**\n * - Block timing windows (blockWindow): 200-350ms for precise defense\n * - Perfect block windows (perfectBlockWindow): 60-100ms for optimal timing\n * - Damage reduction (damageReduction): 50-75% damage reduction on successful blocks\n * - Stability bonuses (stabilityBonus): 120-180% fortitude increase\n * - Rooting effects (rootingEffect): Ground connection for immovable stance\n * - Optimized execution times: 250-800ms for defensive reactions\n *\n * All 6 techniques now include defensive properties for:\n * - Immovable defense visualization\n * - Block timing indicators\n * - Damage absorption feedback\n * - Mountain/earth-themed effects\n *\n * @module GanTechniques\n */\n\nimport type { TrigramStanceTechnique } from \"@/systems/vitalpoint\";\nimport {\n CombatAttackType,\n DamageType,\n TrigramStance,\n} from \"../../../types/common\";\nimport { AnimationType } from \"../../animation\";\n\n/**\n * GAN stance techniques - Mountain / Immovable Defense\n * Hapkido defensive mastery and patient counters\n *\n * Technique characteristics:\n * - Superior blocking capability\n * - Rooted defensive stances\n * - Devastating counter-attacks\n * - Control through position\n *\n * Animation speeds are calibrated for defensive timing:\n * - Quick defense: 1.1-1.2 (rapid blocks)\n * - Normal: 1.0 (standard defense)\n * - Powerful counter: 0.9-1.0 (deliberate strikes)\n */\nexport const GAN_TECHNIQUES: readonly TrigramStanceTechnique[] = [\n // ============= Primary Technique =============\n {\n id: \"gan_rock_defense\",\n name: {\n korean: \"반석방어\",\n english: \"Rock Defense\",\n romanized: \"banseok_bangeo\",\n },\n koreanName: \"반석방어\",\n englishName: \"Rock Defense\",\n romanized: \"banseok_bangeo\",\n description: {\n korean: \"바위처럼 견고한 방어 자세\",\n english: \"Solid defense like a rock\",\n },\n stance: TrigramStance.GAN,\n type: CombatAttackType.BLOCK,\n damageType: DamageType.BLUNT,\n damage: 15,\n kiCost: 5,\n staminaCost: 8,\n accuracy: 0.95,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 420,\n recoveryTime: 700,\n critChance: 0.02,\n critMultiplier: 1.0,\n effects: [],\n // Combo metadata - Solid defensive base\n comboWindow: 250,\n comboPriority: 1, // Starter - establishes defensive position\n pressureStacks: 1,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"defensive\", // Type: shared category\n animationId: \"gan_rock_defense\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Solid blocking stance\n animationType: AnimationType.GAN_ROCK_DEFENSE_BLOCK,\n animationSpeed: 0.75,\n category: \"light\",\n range: \"short\",\n speed: 1.2,\n // Defensive mechanics for immovable defense\n blockWindow: 300, // 300ms block timing window\n perfectBlockWindow: 80, // 80ms perfect block window\n damageReduction: 0.65, // 65% damage reduction\n stabilityBonus: 1.3, // 130% stability increase\n rootingEffect: true, // Creates rooting ground connection\n },\n\n // ============= Defensive Stance Techniques =============\n {\n id: \"gan_immovable_stance\",\n name: {\n korean: \"부동자세\",\n english: \"Immovable Stance\",\n romanized: \"budong-jase\",\n },\n koreanName: \"부동자세\",\n englishName: \"Immovable Stance\",\n romanized: \"budong-jase\",\n description: {\n korean: \"산처럼 움직이지 않는 견고한 방어 자세\",\n english: \"Immovable defensive stance like a mountain\",\n },\n stance: TrigramStance.GAN,\n type: CombatAttackType.BLOCK,\n damageType: DamageType.BLUNT,\n damage: 12,\n kiCost: 8,\n staminaCost: 10,\n accuracy: 0.98,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 350,\n recoveryTime: 630,\n critChance: 0.04,\n critMultiplier: 1.1,\n effects: [],\n // Combo metadata - Rooted defense stance\n comboWindow: 250,\n comboPriority: 1, // Starter - immovable foundation\n pressureStacks: 1,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"stance\", // Type: shared category\n animationId: \"gan_immovable_stance\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Rooted defensive stance\n animationType: AnimationType.GAN_IMMOVABLE_STANCE,\n animationSpeed: 0.75,\n category: \"light\",\n range: \"short\",\n speed: 1.0,\n // Defensive mechanics for maximum stability\n blockWindow: 350, // 350ms block timing window (longer for stance)\n perfectBlockWindow: 100, // 100ms perfect block window\n damageReduction: 0.75, // 75% damage reduction (highest)\n stabilityBonus: 1.8, // 180% stability increase (maximum)\n rootingEffect: true, // Deep rooting ground connection\n },\n {\n id: \"gan_iron_block\",\n name: {\n korean: \"철벽막기\",\n english: \"Iron Wall Block\",\n romanized: \"cheolbyeok-makgi\",\n },\n koreanName: \"철벽막기\",\n englishName: \"Iron Wall Block\",\n romanized: \"cheolbyeok-makgi\",\n description: {\n korean: \"합기도 강력한 막기로 공격을 완전히 차단\",\n english: \"Hapkido powerful block completely stopping attack\",\n },\n stance: TrigramStance.GAN,\n type: CombatAttackType.BLOCK,\n damageType: DamageType.BLUNT,\n damage: 20,\n kiCost: 12,\n staminaCost: 14,\n accuracy: 0.94,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 1.05,\n },\n executionTime: 560,\n recoveryTime: 909,\n critChance: 0.06,\n critMultiplier: 1.2,\n effects: [],\n // Combo metadata - Powerful blocking technique\n comboWindow: 250,\n comboPriority: 1, // Starter - wall defense\n pressureStacks: 1,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"defensive\", // Type: shared category\n animationId: \"gan_iron_block\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Powerful blocking motion (matches TechniqueAnimationMapping)\n animationType: AnimationType.IRON_BLOCK,\n animationSpeed: 0.65,\n category: \"light\",\n range: \"medium\",\n speed: 0.85,\n // Defensive mechanics for powerful block\n blockWindow: 280, // 280ms block timing window\n perfectBlockWindow: 70, // 70ms perfect block window (tight)\n damageReduction: 0.7, // 70% damage reduction\n stabilityBonus: 1.5, // 150% stability increase\n rootingEffect: true, // Strong rooting effect\n },\n\n // ============= Counter-Attack Techniques =============\n {\n id: \"gan_counter_strike\",\n name: {\n korean: \"반격타\",\n english: \"Counter Strike\",\n romanized: \"bangyeok-ta\",\n },\n koreanName: \"반격타\",\n englishName: \"Counter Strike\",\n romanized: \"bangyeok-ta\",\n description: {\n korean: \"방어 후 즉시 가하는 강력한 반격\",\n english: \"Powerful counter strike immediately after defense\",\n },\n stance: TrigramStance.GAN,\n type: CombatAttackType.COUNTER_ATTACK,\n damageType: DamageType.BLUNT,\n damage: 30,\n kiCost: 16,\n staminaCost: 20,\n accuracy: 0.92,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 1.05,\n },\n executionTime: 840,\n recoveryTime: 1330,\n critChance: 0.26,\n critMultiplier: 2.2,\n effects: [],\n // Combo metadata - Devastating counter strike\n comboWindow: 250,\n comboPriority: 3, // Finisher - powerful counter blow\n pressureStacks: 3,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"counter\", // Type: shared category\n animationId: \"gan_counter_strike\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Powerful counter attack\n animationType: AnimationType.GAN_COUNTER_STRIKE,\n animationSpeed: 0.75,\n category: \"special\",\n range: \"medium\",\n speed: 1.0,\n // Defensive mechanics for counter timing\n blockWindow: 200, // 200ms block window (tight for counter)\n perfectBlockWindow: 60, // 60ms perfect block window (very tight)\n damageReduction: 0.5, // 50% damage reduction (counter-focused)\n stabilityBonus: 1.2, // 120% stability during counter setup\n rootingEffect: false, // No rooting for counter mobility\n },\n {\n id: \"gan_reversal_technique\",\n name: {\n korean: \"역기술\",\n english: \"Reversal Technique\",\n romanized: \"yeok-gisul\",\n },\n koreanName: \"역기술\",\n englishName: \"Reversal Technique\",\n romanized: \"yeok-gisul\",\n description: {\n korean: \"상대의 공격을 받아 역으로 제압\",\n english: \"Receiving attack and reversing into control\",\n },\n stance: TrigramStance.GAN,\n type: CombatAttackType.COUNTER_ATTACK,\n damageType: DamageType.JOINT,\n damage: 28,\n kiCost: 18,\n staminaCost: 22,\n accuracy: 0.84,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 1120,\n recoveryTime: 1680,\n critChance: 0.18,\n critMultiplier: 1.8,\n effects: [],\n // Combo metadata - Control reversal technique\n comboWindow: 250,\n comboPriority: 2, // Mid-chain - defensive reversal\n pressureStacks: 2,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"counter\", // Type: shared category\n animationId: \"gan_reversal_technique\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Reversal motion\n animationType: AnimationType.GAN_REVERSAL_TECHNIQUE,\n animationSpeed: 0.7,\n category: \"medium\",\n range: \"short\",\n speed: 0.9,\n // Defensive mechanics for reversal\n blockWindow: 250, // 250ms block window for reversal setup\n perfectBlockWindow: 75, // 75ms perfect reversal window\n damageReduction: 0.55, // 55% damage reduction during reversal\n stabilityBonus: 1.4, // 140% stability for control\n rootingEffect: true, // Rooting for reversal control\n },\n\n // ============= Grappling Control =============\n {\n id: \"gan_mountain_stance_lock\",\n name: {\n korean: \"산세고정\",\n english: \"Mountain Stance Lock\",\n romanized: \"sanse-gojeong\",\n },\n koreanName: \"산세고정\",\n englishName: \"Mountain Stance Lock\",\n romanized: \"sanse-gojeong\",\n description: {\n korean: \"합기도 방어 자세에서 상대를 고정하고 제압\",\n english: \"Hapkido defensive position locking and controlling opponent\",\n },\n stance: TrigramStance.GAN,\n type: CombatAttackType.GRAPPLE,\n damageType: DamageType.JOINT,\n damage: 24,\n kiCost: 14,\n staminaCost: 18,\n accuracy: 0.86,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 1050,\n recoveryTime: 1540,\n critChance: 0.14,\n critMultiplier: 1.6,\n effects: [],\n // Combo metadata - Immobilizing lock\n comboWindow: 250,\n comboPriority: 2, // Mid-chain - position control\n pressureStacks: 2,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"grapple\", // Type: shared category\n animationId: \"gan_mountain_stance_lock\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Standing control position\n animationType: AnimationType.GAN_MOUNTAIN_STANCE_LOCK,\n animationSpeed: 0.7,\n category: \"medium\",\n range: \"short\",\n speed: 0.9,\n // Defensive mechanics for grapple control\n blockWindow: 220, // 220ms block window during grapple setup\n perfectBlockWindow: 65, // 65ms perfect grapple window\n damageReduction: 0.6, // 60% damage reduction (grappling focus)\n stabilityBonus: 1.6, // 160% stability for grapple control\n rootingEffect: true, // Strong rooting for grapple lock\n },\n] as const;\n\n/**\n * Get GAN techniques count\n */\nexport const GAN_TECHNIQUE_COUNT = GAN_TECHNIQUES.length;\n\n/**\n * Get GAN technique by ID\n */\nexport function getGanTechniqueById(id: string): TrigramStanceTechnique | undefined {\n return GAN_TECHNIQUES.find((t) => t.id === id);\n}\n\n/**\n * Get all GAN techniques by attack type\n */\nexport function getGanTechniquesByType(\n type: CombatAttackType\n): readonly TrigramStanceTechnique[] {\n return GAN_TECHNIQUES.filter((t) => t.type === type);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"GanTechniques.js","names":[],"sources":["../../../../src/systems/trigram/techniques/GanTechniques.ts"],"sourcesContent":["/**\n * ☶ 간 (GAN) - Mountain Stance Techniques\n * 반석방어 - Immovable Defense (Hapkido Defensive Mastery)\n *\n * The Mountain stance (간괘) embodies immovable defense and patient counter.\n * Based on Hapkido (합기도) defensive principles - rooted and unshakeable\n * like a mountain, waiting for the perfect moment to counter.\n *\n * Philosophy: \"산처럼 굳건히 서서 때를 기다려라\"\n * Stand firm like a mountain and wait for the moment\n *\n * **ENHANCED DEFENSIVE MECHANICS:**\n * - Block timing windows (blockWindow): 200-350ms for precise defense\n * - Perfect block windows (perfectBlockWindow): 60-100ms for optimal timing\n * - Damage reduction (damageReduction): 50-75% damage reduction on successful blocks\n * - Stability bonuses (stabilityBonus): 120-180% fortitude increase\n * - Rooting effects (rootingEffect): Ground connection for immovable stance\n * - Optimized execution times: 250-800ms for defensive reactions\n *\n * All 6 techniques now include defensive properties for:\n * - Immovable defense visualization\n * - Block timing indicators\n * - Damage absorption feedback\n * - Mountain/earth-themed effects\n *\n * @module GanTechniques\n */\n\nimport type { TrigramStanceTechnique } from \"@/systems/vitalpoint\";\nimport {\n CombatAttackType,\n DamageType,\n TrigramStance,\n} from \"../../../types/common\";\nimport { AnimationType } from \"../../animation\";\n\n/**\n * GAN stance techniques - Mountain / Immovable Defense\n * Hapkido defensive mastery and patient counters\n *\n * Technique characteristics:\n * - Superior blocking capability\n * - Rooted defensive stances\n * - Devastating counter-attacks\n * - Control through position\n *\n * Animation speeds are calibrated for defensive timing:\n * - Quick defense: 1.1-1.2 (rapid blocks)\n * - Normal: 1.0 (standard defense)\n * - Powerful counter: 0.9-1.0 (deliberate strikes)\n */\nexport const GAN_TECHNIQUES: readonly TrigramStanceTechnique[] = [\n // ============= Primary Technique =============\n {\n id: \"gan_rock_defense\",\n name: {\n korean: \"반석방어\",\n english: \"Rock Defense\",\n romanized: \"banseok_bangeo\",\n },\n koreanName: \"반석방어\",\n englishName: \"Rock Defense\",\n romanized: \"banseok_bangeo\",\n description: {\n korean: \"바위처럼 견고한 방어 자세\",\n english: \"Solid defense like a rock\",\n },\n stance: TrigramStance.GAN,\n type: CombatAttackType.BLOCK,\n damageType: DamageType.BLUNT,\n damage: 15,\n kiCost: 5,\n staminaCost: 8,\n accuracy: 0.95,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 420,\n recoveryTime: 700,\n critChance: 0.02,\n critMultiplier: 1.0,\n effects: [],\n // Combo metadata - Solid defensive base\n comboWindow: 250,\n comboPriority: 1, // Starter - establishes defensive position\n pressureStacks: 1,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"defensive\", // Type: shared category\n animationId: \"gan_rock_defense\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Solid blocking stance\n animationType: AnimationType.GAN_ROCK_DEFENSE_BLOCK,\n animationSpeed: 0.75,\n category: \"light\",\n range: \"short\",\n speed: 1.2,\n // Defensive mechanics for immovable defense\n blockWindow: 300, // 300ms block timing window\n perfectBlockWindow: 80, // 80ms perfect block window\n damageReduction: 0.65, // 65% damage reduction\n stabilityBonus: 1.3, // 130% stability increase\n rootingEffect: true, // Creates rooting ground connection\n },\n\n // ============= Defensive Stance Techniques =============\n {\n id: \"gan_immovable_stance\",\n name: {\n korean: \"부동자세\",\n english: \"Immovable Stance\",\n romanized: \"budong-jase\",\n },\n koreanName: \"부동자세\",\n englishName: \"Immovable Stance\",\n romanized: \"budong-jase\",\n description: {\n korean: \"산처럼 움직이지 않는 견고한 방어 자세\",\n english: \"Immovable defensive stance like a mountain\",\n },\n stance: TrigramStance.GAN,\n type: CombatAttackType.BLOCK,\n damageType: DamageType.BLUNT,\n damage: 12,\n kiCost: 8,\n staminaCost: 10,\n accuracy: 0.98,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 350,\n recoveryTime: 630,\n critChance: 0.04,\n critMultiplier: 1.1,\n effects: [],\n // Combo metadata - Rooted defense stance\n comboWindow: 250,\n comboPriority: 1, // Starter - immovable foundation\n pressureStacks: 1,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"stance\", // Type: shared category\n animationId: \"gan_immovable_stance\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Rooted defensive stance\n animationType: AnimationType.GAN_IMMOVABLE_STANCE,\n animationSpeed: 0.75,\n category: \"light\",\n range: \"short\",\n speed: 1.0,\n // Defensive mechanics for maximum stability\n blockWindow: 350, // 350ms block timing window (longer for stance)\n perfectBlockWindow: 100, // 100ms perfect block window\n damageReduction: 0.75, // 75% damage reduction (highest)\n stabilityBonus: 1.8, // 180% stability increase (maximum)\n rootingEffect: true, // Deep rooting ground connection\n },\n {\n id: \"gan_iron_block\",\n name: {\n korean: \"철벽막기\",\n english: \"Iron Wall Block\",\n romanized: \"cheolbyeok-makgi\",\n },\n koreanName: \"철벽막기\",\n englishName: \"Iron Wall Block\",\n romanized: \"cheolbyeok-makgi\",\n description: {\n korean: \"합기도 강력한 막기로 공격을 완전히 차단\",\n english: \"Hapkido powerful block completely stopping attack\",\n },\n stance: TrigramStance.GAN,\n type: CombatAttackType.BLOCK,\n damageType: DamageType.BLUNT,\n damage: 20,\n kiCost: 12,\n staminaCost: 14,\n accuracy: 0.94,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 1.05,\n },\n executionTime: 560,\n recoveryTime: 909,\n critChance: 0.06,\n critMultiplier: 1.2,\n effects: [],\n // Combo metadata - Powerful blocking technique\n comboWindow: 250,\n comboPriority: 1, // Starter - wall defense\n pressureStacks: 1,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"defensive\", // Type: shared category\n animationId: \"gan_iron_block\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Powerful blocking motion (matches TechniqueAnimationMapping)\n animationType: AnimationType.IRON_BLOCK,\n animationSpeed: 0.65,\n category: \"light\",\n range: \"medium\",\n speed: 0.85,\n // Defensive mechanics for powerful block\n blockWindow: 280, // 280ms block timing window\n perfectBlockWindow: 70, // 70ms perfect block window (tight)\n damageReduction: 0.7, // 70% damage reduction\n stabilityBonus: 1.5, // 150% stability increase\n rootingEffect: true, // Strong rooting effect\n },\n\n // ============= Counter-Attack Techniques =============\n {\n id: \"gan_counter_strike\",\n name: {\n korean: \"반격타\",\n english: \"Counter Strike\",\n romanized: \"bangyeok-ta\",\n },\n koreanName: \"반격타\",\n englishName: \"Counter Strike\",\n romanized: \"bangyeok-ta\",\n description: {\n korean: \"방어 후 즉시 가하는 강력한 반격\",\n english: \"Powerful counter strike immediately after defense\",\n },\n stance: TrigramStance.GAN,\n type: CombatAttackType.COUNTER_ATTACK,\n damageType: DamageType.BLUNT,\n damage: 30,\n kiCost: 16,\n staminaCost: 20,\n accuracy: 0.92,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 1.05,\n },\n executionTime: 840,\n recoveryTime: 1330,\n critChance: 0.26,\n critMultiplier: 2.2,\n effects: [],\n // Combo metadata - Devastating counter strike\n comboWindow: 250,\n comboPriority: 3, // Finisher - powerful counter blow\n pressureStacks: 3,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"counter\", // Type: shared category\n animationId: \"gan_counter_strike\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Powerful counter attack\n animationType: AnimationType.GAN_COUNTER_STRIKE,\n animationSpeed: 0.75,\n category: \"special\",\n range: \"medium\",\n speed: 1.0,\n // Defensive mechanics for counter timing\n blockWindow: 200, // 200ms block window (tight for counter)\n perfectBlockWindow: 60, // 60ms perfect block window (very tight)\n damageReduction: 0.5, // 50% damage reduction (counter-focused)\n stabilityBonus: 1.2, // 120% stability during counter setup\n rootingEffect: false, // No rooting for counter mobility\n },\n {\n id: \"gan_reversal_technique\",\n name: {\n korean: \"역기술\",\n english: \"Reversal Technique\",\n romanized: \"yeok-gisul\",\n },\n koreanName: \"역기술\",\n englishName: \"Reversal Technique\",\n romanized: \"yeok-gisul\",\n description: {\n korean: \"상대의 공격을 받아 역으로 제압\",\n english: \"Receiving attack and reversing into control\",\n },\n stance: TrigramStance.GAN,\n type: CombatAttackType.COUNTER_ATTACK,\n damageType: DamageType.JOINT,\n damage: 28,\n kiCost: 18,\n staminaCost: 22,\n accuracy: 0.84,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 1120,\n recoveryTime: 1680,\n critChance: 0.18,\n critMultiplier: 1.8,\n effects: [],\n // Combo metadata - Control reversal technique\n comboWindow: 250,\n comboPriority: 2, // Mid-chain - defensive reversal\n pressureStacks: 2,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"counter\", // Type: shared category\n animationId: \"gan_reversal_technique\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Reversal motion\n animationType: AnimationType.GAN_REVERSAL_TECHNIQUE,\n animationSpeed: 0.7,\n category: \"medium\",\n range: \"short\",\n speed: 0.9,\n // Defensive mechanics for reversal\n blockWindow: 250, // 250ms block window for reversal setup\n perfectBlockWindow: 75, // 75ms perfect reversal window\n damageReduction: 0.55, // 55% damage reduction during reversal\n stabilityBonus: 1.4, // 140% stability for control\n rootingEffect: true, // Rooting for reversal control\n },\n\n // ============= Grappling Control =============\n {\n id: \"gan_mountain_stance_lock\",\n name: {\n korean: \"산세고정\",\n english: \"Mountain Stance Lock\",\n romanized: \"sanse-gojeong\",\n },\n koreanName: \"산세고정\",\n englishName: \"Mountain Stance Lock\",\n romanized: \"sanse-gojeong\",\n description: {\n korean: \"합기도 방어 자세에서 상대를 고정하고 제압\",\n english: \"Hapkido defensive position locking and controlling opponent\",\n },\n stance: TrigramStance.GAN,\n type: CombatAttackType.GRAPPLE,\n damageType: DamageType.JOINT,\n damage: 24,\n kiCost: 14,\n staminaCost: 18,\n accuracy: 0.86,\n reachConfig: {\n bodyPart: \"arm\",\n techniqueType: \"punch\",\n baseExtension: 0.9,\n },\n executionTime: 1050,\n recoveryTime: 1540,\n critChance: 0.14,\n critMultiplier: 1.6,\n effects: [],\n // Combo metadata - Immobilizing lock\n comboWindow: 250,\n comboPriority: 2, // Mid-chain - position control\n pressureStacks: 2,\n // NEW ARCHITECTURE: Separate type (category) from ID (unique)\n animationCategory: \"grapple\", // Type: shared category\n animationId: \"gan_mountain_stance_lock\", // ID: unique 1-1 mapping\n // Legacy field for backward compatibility\n // Animation: Standing control position\n animationType: AnimationType.GAN_MOUNTAIN_STANCE_LOCK,\n animationSpeed: 0.7,\n category: \"medium\",\n range: \"short\",\n speed: 0.9,\n // Defensive mechanics for grapple control\n blockWindow: 220, // 220ms block window during grapple setup\n perfectBlockWindow: 65, // 65ms perfect grapple window\n damageReduction: 0.6, // 60% damage reduction (grappling focus)\n stabilityBonus: 1.6, // 160% stability for grapple control\n rootingEffect: true, // Strong rooting for grapple lock\n },\n] as const;\n\n/**\n * Get GAN techniques count\n */\nexport const GAN_TECHNIQUE_COUNT = GAN_TECHNIQUES.length;\n\n/**\n * Get GAN technique by ID\n */\nexport function getGanTechniqueById(id: string): TrigramStanceTechnique | undefined {\n return GAN_TECHNIQUES.find((t) => t.id === id);\n}\n\n/**\n * Get all GAN techniques by attack type\n */\nexport function getGanTechniquesByType(\n type: CombatAttackType\n): readonly TrigramStanceTechnique[] {\n return GAN_TECHNIQUES.filter((t) => t.type === type);\n}\n"],"mappings":"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"}
|