Skip to main content
Glama

Path of Exile 2 Build Optimizer MCP

STUN_CALCULATOR.md14.5 kB
# Path of Exile 2 Stun Calculator ## Overview The Stun Calculator module implements Path of Exile 2's completely redesigned stun system, featuring **Light Stun** (chance-based) and **Heavy Stun** (buildup-based) mechanics. ## Table of Contents - [PoE2 Stun System](#poe2-stun-system) - [Installation](#installation) - [Quick Start](#quick-start) - [Features](#features) - [API Reference](#api-reference) - [Examples](#examples) - [Testing](#testing) ## PoE2 Stun System Path of Exile 2 introduces a dual stun system: ### Light Stun - **Chance-based** interruption on hit - Base formula: `(damage / target_max_life) × 100` - **Minimum threshold**: 15% (below this = 0% chance) - **Damage type bonuses**: Physical damage gets +50% more stun - **Attack type bonuses**: Melee attacks get +50% more stun - **Combined**: Physical melee attacks get 2.25× multiplier (1.5 × 1.5) ### Heavy Stun - **Buildup-based** extended stun (3 seconds) - Meter fills with each hit (same bonuses as Light Stun) - At 100% meter: Heavy Stun triggers - Uses same formula as Light Stun for buildup calculation - Threshold = target's maximum life ### Primed State - Occurs when Heavy Stun meter is 50-99% full - Next hit that would Light Stun triggers **Crushing Blow** - Crushing Blow provides additional effects ## Installation The module is located at: ``` C:\Users\tanki\ClaudesPathOfExile2EnhancementService\src\calculator\stun_calculator.py ``` Import in your code: ```python from src.calculator.stun_calculator import ( StunCalculator, DamageType, AttackType, StunModifiers ) ``` ## Quick Start ### Basic Usage ```python from src.calculator.stun_calculator import StunCalculator, DamageType, AttackType # Create calculator instance calculator = StunCalculator() # Calculate stun for a single hit result = calculator.calculate_complete_stun( damage=1500, target_max_life=6000, damage_type=DamageType.PHYSICAL, attack_type=AttackType.MELEE, entity_id="boss1" ) # Check results print(f"Light Stun Chance: {result.light_stun.final_chance:.1f}%") print(f"Will Stun: {result.light_stun.will_stun}") print(f"Heavy Stun Meter: {result.heavy_stun.meter.buildup_percentage:.1f}%") print(f"State: {result.heavy_stun.meter.state.value}") ``` ### Quick Calculation For rapid calculations: ```python from src.calculator.stun_calculator import quick_stun_calculation result = quick_stun_calculation( damage=1200, target_max_life=6000, is_physical=True, is_melee=True ) print(result) # Formatted output string ``` ## Features ### 1. Light Stun Calculation - Accurate chance calculation with damage/attack type bonuses - Minimum threshold enforcement (15%) - Modifier support (increased, more, threshold changes) - Immunity handling ### 2. Heavy Stun Buildup Tracking - Per-entity meter tracking - Automatic state detection (Normal, Primed, Heavy Stunned) - Hit history recording - Buildup accumulation over multiple hits ### 3. Primed State Detection - Automatic detection at 50-99% meter - Crushing Blow trigger when Light Stun occurs during Primed state - State management ### 4. Modifier System - Increased stun chance (additive) - More stun chance (multiplicative) - Stun threshold modifications - Buildup rate multipliers - Custom minimum thresholds - Immunity flags ### 5. Multi-Entity Tracking - Track unlimited entities simultaneously - Per-entity Heavy Stun meters - Entity management (create, reset, remove) ### 6. Analysis Tools - Calculate hits needed to stun - Meter state inspection - Hit history analysis ## API Reference ### Classes #### `StunCalculator` Main calculator class for all stun calculations. **Methods:** - `calculate_light_stun_chance()` - Calculate Light Stun chance - `calculate_heavy_stun_buildup()` - Calculate Heavy Stun buildup - `calculate_complete_stun()` - Calculate both Light and Heavy stun - `get_heavy_stun_meter()` - Get entity's Heavy Stun meter - `reset_heavy_stun_meter()` - Reset entity's meter - `remove_entity()` - Remove entity from tracking - `get_all_tracked_entities()` - Get list of tracked entities - `calculate_hits_to_stun()` - Calculate theoretical hits needed #### `DamageType` (Enum) ```python PHYSICAL # +50% more stun FIRE COLD LIGHTNING CHAOS ``` #### `AttackType` (Enum) ```python MELEE # +50% more stun RANGED SPELL ``` #### `StunState` (Enum) ```python NORMAL # 0-49% meter PRIMED # 50-99% meter (ready for Crushing Blow) HEAVY_STUNNED # 100%+ meter (Heavy Stun active) ``` #### `StunModifiers` (Dataclass) ```python increased_stun_chance: float = 0.0 # Additive % increase more_stun_chance: float = 1.0 # Multiplicative multiplier increased_stun_threshold: float = 1.0 # Enemy threshold multiplier reduced_stun_threshold: float = 1.0 # Enemy threshold reduction stun_buildup_multiplier: float = 1.0 # Buildup rate multiplier minimum_stun_chance: Optional[float] = None # Custom threshold immune_to_stun: bool = False # Complete immunity ``` ### Result Classes #### `LightStunResult` Contains Light Stun calculation results: - `base_chance` - Base percentage before bonuses - `damage_type_bonus` - Multiplier from damage type - `attack_type_bonus` - Multiplier from attack type - `final_chance` - Final percentage after all modifiers - `will_stun` - Boolean indicating if stun occurs - `damage` - Damage dealt - `target_max_life` - Target's max life #### `HeavyStunResult` Contains Heavy Stun calculation results: - `buildup_added` - Buildup added by this hit - `total_buildup` - Total accumulated buildup - `meter` - HeavyStunMeter object - `triggered_heavy_stun` - Boolean if Heavy Stun triggered - `triggered_crushing_blow` - Boolean if Crushing Blow triggered - `hits_to_heavy_stun` - Estimated hits needed with similar damage #### `HeavyStunMeter` Tracks Heavy Stun buildup state: - `current_buildup` - Current buildup amount - `max_buildup` - Maximum buildup (= target life) - `buildup_percentage` - Percentage filled (0-100+) - `state` - Current StunState - `hits_received` - Number of hits recorded - `hit_history` - List of hit details - Methods: `is_primed()`, `is_heavy_stunned()`, `reset()` ## Examples ### Example 1: Basic Combat ```python calculator = StunCalculator() # Heavy Strike dealing 1500 damage to 6000 life enemy result = calculator.calculate_complete_stun( damage=1500, target_max_life=6000, damage_type=DamageType.PHYSICAL, attack_type=AttackType.MELEE, entity_id="enemy1" ) # Result: # Light Stun: 56.2% chance (STUN!) # Heavy Meter: 56.2% (PRIMED) # Hits to Heavy Stun: 0.78 ``` ### Example 2: Multiple Hits Sequence ```python calculator = StunCalculator() boss_id = "boss1" attacks = [ (1200, "Heavy Strike"), (800, "Follow-up"), (1500, "Critical Hit"), (900, "Normal Attack"), (2000, "Finisher") ] for damage, name in attacks: result = calculator.calculate_complete_stun( damage=damage, target_max_life=10000, damage_type=DamageType.PHYSICAL, attack_type=AttackType.MELEE, entity_id=boss_id ) print(f"{name}: {result.heavy_stun.meter.buildup_percentage:.1f}%") if result.heavy_stun.triggered_heavy_stun: print("HEAVY STUN!") if result.heavy_stun.triggered_crushing_blow: print("CRUSHING BLOW!") ``` ### Example 3: Damage Type Comparison ```python calculator = StunCalculator() damage_types = [DamageType.PHYSICAL, DamageType.FIRE, DamageType.COLD] for dmg_type in damage_types: result = calculator.calculate_complete_stun( damage=1000, target_max_life=5000, damage_type=dmg_type, attack_type=AttackType.MELEE, entity_id=f"test_{dmg_type.value}" ) print(f"{dmg_type.value}: {result.light_stun.final_chance:.1f}% chance") # Output: # physical: 45.0% chance (1.5x bonus) # fire: 30.0% chance (no bonus) # cold: 30.0% chance (no bonus) ``` ### Example 4: Character with Modifiers ```python calculator = StunCalculator() # Stun-focused character build modifiers = StunModifiers( increased_stun_chance=75.0, # +75% from passive tree more_stun_chance=1.4, # 40% more from support gem stun_buildup_multiplier=1.2, # 20% faster buildup reduced_stun_threshold=0.85 # 15% reduced enemy threshold ) result = calculator.calculate_complete_stun( damage=1000, target_max_life=8000, damage_type=DamageType.PHYSICAL, attack_type=AttackType.MELEE, entity_id="boss", modifiers=modifiers ) # Without modifiers: 28.1% chance, 2.56 hits to Heavy Stun # With modifiers: 81.1% chance, 0.03 hits to Heavy Stun (nearly instant!) ``` ### Example 5: Primed State Strategy ```python calculator = StunCalculator() boss_id = "primed_boss" # Hit 1: Get to Primed state (50%) result1 = calculator.calculate_complete_stun( damage=2500, target_max_life=5000, damage_type=DamageType.FIRE, attack_type=AttackType.SPELL, entity_id=boss_id ) meter = calculator.get_heavy_stun_meter(boss_id) if meter.is_primed(): print("Boss is PRIMED! Next stun triggers Crushing Blow!") # Hit 2: Trigger Crushing Blow result2 = calculator.calculate_complete_stun( damage=1000, target_max_life=5000, damage_type=DamageType.FIRE, attack_type=AttackType.SPELL, entity_id=boss_id ) if result2.heavy_stun.triggered_crushing_blow: print("CRUSHING BLOW TRIGGERED!") ``` ### Example 6: Planning Attacks ```python calculator = StunCalculator() # Calculate hits needed for different skills skills = [ (500, "Basic Attack"), (1500, "Heavy Strike"), (2500, "Ultimate") ] for damage, name in skills: hits_light, hits_heavy = calculator.calculate_hits_to_stun( damage_per_hit=damage, target_max_life=10000, damage_type=DamageType.PHYSICAL, attack_type=AttackType.MELEE ) print(f"{name}: {hits_heavy:.2f} hits to Heavy Stun") # Output: # Basic Attack: 8.89 hits to Heavy Stun # Heavy Strike: 2.96 hits to Heavy Stun # Ultimate: 1.78 hits to Heavy Stun ``` ### Example 7: Multiple Enemy Tracking ```python calculator = StunCalculator() enemies = [ ("elite", 8000), ("magic", 3000), ("normal", 1500) ] # Hit all enemies with AoE attack for enemy_id, life in enemies: result = calculator.calculate_complete_stun( damage=1000, target_max_life=life, damage_type=DamageType.PHYSICAL, attack_type=AttackType.MELEE, entity_id=enemy_id ) # Check all tracked entities for entity_id in calculator.get_all_tracked_entities(): meter = calculator.get_heavy_stun_meter(entity_id) print(f"{entity_id}: {meter.buildup_percentage:.1f}% ({meter.state.value})") # Output: # elite: 28.1% (normal) # magic: 75.0% (primed) # normal: 150.0% (heavy_stunned) ``` ## Testing Run the comprehensive test suite: ```bash # Run all tests python -m pytest tests/test_stun_calculator.py -v # Run specific test class python -m pytest tests/test_stun_calculator.py::TestLightStunCalculation -v # Run with coverage python -m pytest tests/test_stun_calculator.py --cov=src.calculator.stun_calculator ``` Test coverage includes: - Light Stun calculations (14 tests) - Heavy Stun buildup (11 tests) - Complete stun integration (3 tests) - Hits-to-stun calculations (3 tests) - Modifier applications (4 tests) - Entity tracking (2 tests) - Edge cases (3 tests) **Total: 42 tests - All passing** ## Formulas Reference ### Light Stun Chance ``` base_chance = (damage / target_max_life) × 100 bonuses = 1.0 if is_physical: bonuses × 1.5 if is_melee: bonuses × 1.5 final_chance = base_chance × bonuses × (1 + increased%) × more_multiplier if final_chance < 15%: final_chance = 0% final_chance = min(final_chance, 100%) ``` ### Heavy Stun Buildup ``` buildup = damage × bonuses × (1 + increased%) × more_multiplier Heavy Stun triggers when: total_buildup >= target_max_life ``` ### Primed State ``` if 50% <= buildup_percentage < 100%: state = PRIMED if state == PRIMED and light_stun_would_occur: trigger_crushing_blow() ``` ### Hits to Stun ``` Light Stun (threshold): hits = 15% / (chance_per_hit%) Heavy Stun: hits = target_max_life / buildup_per_hit ``` ## Performance Notes - O(1) complexity for single stun calculations - O(n) memory for tracking n entities - Hit history stored per entity (can grow large) - Use `reset_heavy_stun_meter()` to clear history - Use `remove_entity()` when entity no longer needed ## Common Patterns ### Pattern 1: Boss Fight Tracking ```python calculator = StunCalculator() boss_id = "raid_boss" def on_hit(damage): result = calculator.calculate_complete_stun( damage=damage, target_max_life=boss_life, damage_type=player_damage_type, attack_type=player_attack_type, entity_id=boss_id, modifiers=player_modifiers ) update_ui(result.heavy_stun.meter) if result.heavy_stun.triggered_heavy_stun: trigger_stun_animation() ``` ### Pattern 2: Clear Dead/Off-Screen Enemies ```python def cleanup_entities(): for entity_id in calculator.get_all_tracked_entities(): if is_entity_dead_or_offscreen(entity_id): calculator.remove_entity(entity_id) ``` ### Pattern 3: Simulate Attack Sequence ```python def plan_rotation(skill_damages, boss_life): calculator = StunCalculator() for i, damage in enumerate(skill_damages): result = calculator.calculate_complete_stun( damage=damage, target_max_life=boss_life, damage_type=DamageType.PHYSICAL, attack_type=AttackType.MELEE, entity_id="simulation" ) print(f"Hit {i+1}: {result.heavy_stun.meter.buildup_percentage:.1f}%") if result.heavy_stun.triggered_heavy_stun: print(f"Heavy Stun on hit {i+1}!") break ``` ## Version History - **1.0.0** (2025-10-22) - Initial release - Complete Light Stun calculation - Complete Heavy Stun buildup tracking - Primed state detection - Crushing Blow mechanics - Modifier system - Multi-entity tracking - Comprehensive test suite (42 tests) - Full documentation and examples ## License Part of Claude's Path of Exile 2 Enhancement Service ## Support For issues, questions, or contributions, refer to the main project repository. --- **Author**: Claude Code **Module**: `src.calculator.stun_calculator` **Last Updated**: 2025-10-22

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/HivemindOverlord/poe2-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server