§
    D½»j}%  ã                  ó|   — d Z ddlmZ ddlZddlmZmZmZmZ ddl	m
Z
mZmZmZmZmZmZmZmZ  G d„ d¦  «        ZdS )a¦  
Core Damage & Defense Calculation Engine for FreeExile (PoE2 Spirit).
Implements:
1. Deterministic Evasion Entropy to eliminate RNG streaks.
2. Non-linear Path of Exile Armour formula DR = Armour / (Armour + 5 * Dmg).
3. Elemental Resistance mitigation with hard caps and penetration.
4. Ward / Energy Shield pool absorption preceding Life depletion.
5. Boss Stagger / Poise accumulation and damage vulnerability window.
é    )ÚannotationsN)ÚDictÚListÚOptionalÚTuple)	ÚAilmentApplicationÚAilmentTypeÚ	BossPhaseÚBossStaggerStateÚCombatHitResultÚCombatantTypeÚDamageChannelÚDamagePacketÚDefenseSheetc                  óp   — e Zd ZdZed d	„¦   «         Zed!d„¦   «         Ze	 	 d"d#d„¦   «         Z	 	 	 d$d%d„ZdS )&ÚDamageCalculatorzFPure mathematical and server-authoritative combat resolution pipeline.ÚaccuracyÚfloatÚevasionÚentropy_poolÚintÚreturnúTuple[bool, int]c                ó4  — |dk    rd|fS t          d| ¦  «        }|t          j        t          d|¦  «        dz  d¦  «        z   }||z  }t          dt          d|¦  «        ¦  «        }|t	          t          |dz  ¦  «        ¦  «        z   }|d	k    rd|d	z
  fS d
|fS )zÚ
        Calculates hit chance using PoE deterministic entropy system.
        Formula: Hit Chance = Accuracy / (Accuracy + (Evasion / 4)^0.8)
        Clamped between 5% and 95% unless evasion is 0 (100% hit).
        ç        Tç      ð?ç      @gš™™™™™é?gffffffî?gš™™™™™©?ç      Y@éd   F)ÚmaxÚmathÚpowÚminr   Úround)r   r   r   ÚaccÚdenominatorÚ
hit_chanceÚclamped_chanceÚnew_entropys           ú8C:\Projects\FreeExile\server\combat\damage_calculator.pyÚroll_accuracy_vs_evasionz)DamageCalculator.roll_accuracy_vs_evasion   s´   € ð �cŠ>ˆ>Ø˜Ð%Ð%å�#�xÑ Ô ˆØ�DœH¥S¨¨gÑ%6Ô%6¸Ñ%<¸cÑBÔBÑBˆØ˜;Ñ&ˆ
Ý˜T¥3 t¨ZÑ#8Ô#8Ñ9Ô9ˆà"¥S­¨~ÀÑ/EÑ)FÔ)FÑ%GÔ%GÑGˆØ˜#ÒÐØ˜ sÑ*Ð*Ð*Ø�kÐ!Ð!ó    ÚarmourÚincoming_physc                óp   — |dk    s| dk    rdS | | d|z  z   z  }t          dt          d|¦  «        ¦  «        S )zš
        PoE Non-Linear Armour Damage Reduction (DR):
        DR = Armour / (Armour + 5.0 * IncomingPhysicalDamage)
        Capped at 90% (0.90).
        r   g      @çÍÌÌÌÌÌì?©r#   r    )r-   r.   Údrs      r*   Úcalculate_armour_mitigationz,DamageCalculator.calculate_armour_mitigation5   sH   € ð ˜CÒÐ 6¨S¢= =Ø�3Ø�v  mÑ 3Ñ3Ñ4ˆÝ�4�˜S "™œÑ&Ô&Ð&r,   ç      è?r   Ú
raw_damageÚ
resistanceÚmax_capÚpenetrationc                óˆ   — | dk    rdS t          ||¦  «        |z
  }t          d|¦  «        }d|z
  }t          d| |z  ¦  «        S )zŸ
        Elemental & Chaos resistance damage resolution:
        Effective Res = min(Resistance, MaxCap) - Penetration
        Floor at -200% (-2.00).
        r   g       Àr   r1   )r5   r6   r7   r8   Úeffective_resÚdamage_multipliers         r*   Úcalculate_resistance_damagez,DamageCalculator.calculate_resistance_damageA   sX   € ð ˜ÒÐØ�3Ý˜J¨Ñ0Ô0°;Ñ>ˆÝ˜E =Ñ1Ô1ˆØ -Ñ/ÐÝ�3˜
Ð%6Ñ6Ñ7Ô7Ð7r,   NÚpacketr   Údefenser   úOptional[int]Úboss_staggerúOptional[BossStaggerState]Ú
force_critúOptional[bool]úTuple[CombatHitResult, int]c                óZ  — |�|n|j         }|j        r=t          dddd|j                             ¦   «         i ddd|j        |j        ¬¦  «        |fS |                      |j        |j	        |¦  «        \  }}||_         |s=t          dddd|j                             ¦   «         i ddd|j        |j        ¬¦  «        |fS |j
        dk    rH|j
        dk    r=t          dddd|j                             ¦   «         i ddd|j        |j        ¬¦  «        |fS dt          d|j        dz  ¦  «        z   }	|j        D ]}
|	|
z  }	Œ|�|n
|j        dk    }|r
|	|j        z  }	|j        r&|j        dk    r|	dt%          d	|j        ¦  «        z
  z  }	i }|j        j        |	z  }|dk    r0|                      |j        |¦  «        }|d|z
  z  |t,          j        <   t,          j        t,          j        t,          j        t,          j        fD ]‘}|j                             |¦  «        |	z  }|dk    rl|j                             |d¦  «        }|j                             |d
¦  «        }|j                              |d¦  «        }|  !                    ||||¦  «        ||<   Œ’tE          | #                    ¦   «         ¦  «        }|j$        }|r|j%        r
||j&        z  }||z  }d}|}|j        dk    r8|j        |k    r|}|xj        |z  c_        d}n|j        }||j        z
  }d|_        t          d|j        |z
  ¦  «        |_        d}d}|rg|j%        s`|j'        }|dk    r#t,          j        |v r|t,          j                 dz  }|xj(        |z  c_(        |j(        |j)        k    rd|_%        d|_*        d}t          ddd||j                             ¦   «         |	z  |tW          |d¦  «        tW          |d¦  «        tW          |d¦  «        tW          |j        d¦  «        tW          |j        d¦  «        tW          |d¦  «        |¬¦  «        |fS )zBExecutes a single damage transaction through all defensive layers.NFTr   )Úis_hitÚ	is_evadedÚ
is_blockedÚis_criticalÚraw_damage_totalÚmitigated_damage_by_channelÚabsorbed_by_wardÚdamage_to_lifeÚfinal_total_damageÚdefender_life_remainingÚdefender_ward_remainingr   gÍÌÌÌÌÌì¿r   r0   r4   gš™™™™™¹?r   é   )rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   Ústagger_inflictedÚboss_staggered_triggered),r   Úis_in_iframer   Údamage_vectorÚ	total_rawÚcurrent_lifeÚcurrent_wardr+   r   Úevasion_ratingÚblock_chancer    Úincreased_damage_pctÚmore_damage_multipliersÚcrit_chanceÚcrit_multiplierÚis_aoeÚaoe_damage_reduction_pctr#   Úphysicalr3   r-   r   ÚPHYSICALÚFIREÚCOLDÚ	LIGHTNINGÚCHAOSÚget_channelÚresistancesÚgetÚmax_resistance_capsÚelemental_penetrationr<   ÚsumÚvaluesÚdamage_taken_multiplierÚis_staggeredÚstagger_damage_amplificationÚstagger_impactÚcurrent_staggerÚmax_stagger_poiseÚstagger_duration_remaining_secr$   )Úselfr=   r>   r   r@   rB   Úcurrent_entropyrF   Únext_entropyÚglobal_multiplierÚ	more_multÚis_critÚmitigated_channelsÚraw_physÚphys_drÚchÚraw_valÚresÚcapÚpenÚtotal_mitigatedÚ
taken_multÚfinal_damageÚabsorbed_wardrM   Ústagger_triggeredÚstagger_applieds                              r*   Úexecute_hitzDamageCalculator.execute_hitT   s&  € ð +7Ð*B˜,˜,ÈÔH\ˆð Ôð 	åØ Ø"Ø$Ø %Ø%+Ô%9×%CÒ%CÑ%EÔ%EØ02Ø%(Ø#&Ø'*Ø,3Ô,@Ø,3Ô,@ðñ ô ð  ðð ð$  $×<Ò<ØŒO˜WÔ3°_ñ 
ô  
Ñˆ�ð  ,ˆÔØð 	åØ Ø"Ø$Ø %Ø%+Ô%9×%CÒ%CÑ%EÔ%EØ02Ø%(Ø#&Ø'*Ø,3Ô,@Ø,3Ô,@ðñ ô ð ðð ð$ Ô #Ò%Ð%¨'Ô*>À#Ò*EÐ*EåØ Ø#Ø#Ø %Ø%+Ô%9×%CÒ%CÑ%EÔ%EØ02Ø%(Ø#&Ø'*Ø,3Ô,@Ø,3Ô,@ðñ ô ð ðð ð$  ¥# e¨VÔ-HÈ5Ñ-PÑ"QÔ"QÑQÐØÔ7ð 	+ð 	+ˆIØ Ñ*ÐÐà *Ð 6�*�*¸VÔ=OÐSVÒ=VˆØð 	8Ø Ô!7Ñ7ÐàŒ=ð 	U˜WÔ=ÀÒCÐCØ #­¨D°'Ô2RÑ(SÔ(SÑ"SÑTÐð :<Ðð Ô'Ô0Ð3DÑDˆØ�cŠ>ˆ>Ø×6Ò6°w´~ÀxÑPÔPˆGØ9AÀSÈ7Á]Ñ9SÐ�}Ô5Ñ6õ !Ô%¥}Ô'9½=Ô;RÕTaÔTgÐhð 	bð 	bˆBØÔ*×6Ò6°rÑ:Ô:Ð=NÑNˆGØ˜Š}ˆ}ØÔ)×-Ò-¨b°#Ñ6Ô6�ØÔ1×5Ò5°b¸$Ñ?Ô?�ØÔ2×6Ò6°r¸3Ñ?Ô?�Ø)-×)IÒ)IÈ'ÐSVÐX[Ð]`Ñ)aÔ)aÐ" 2Ñ&øõ Ð0×7Ò7Ñ9Ô9Ñ:Ô:ˆØÔ4ˆ
Øð 	D˜LÔ5ð 	DØ˜,ÔCÑCˆJà&¨Ñ3ˆð ˆØ%ˆàÔ #Ò%Ð%ØÔ# |Ò3Ð3Ø ,�ØÐ$Ô$¨Ñ4Ð$Ô$Ø!$��à 'Ô 4�Ø!-°Ô0DÑ!D�Ø'*�Ô$å" 3¨Ô(<¸~Ñ(MÑNÔNˆÔð "ÐØˆØð 		) Ô 9ð 		)Ø$Ô3ˆOØ #Ò%Ð%­-Ô*@ÐDVÐ*VÐ*VØ"4µ]Ô5KÔ"LÈtÑ"S�àÐ(Ô(¨OÑ;Ð(Ô(ØÔ+¨|Ô/MÒMÐMØ,0�Ô)Ø>A�Ô;Ø$(Ð!õ ØØØ Ø#Ø!'Ô!5×!?Ò!?Ñ!AÔ!AÐDUÑ!UØ,>Ý!& }°aÑ!8Ô!8Ý$ ^°QÑ7Ô7Ý#(¨°qÑ#9Ô#9Ý(-¨gÔ.BÀAÑ(FÔ(FÝ(-¨gÔ.BÀAÑ(FÔ(FÝ"'¨¸Ñ";Ô";Ø):ðñ ô ð ð!
ð 	
r,   )r   r   r   r   r   r   r   r   )r-   r   r.   r   r   r   )r4   r   )
r5   r   r6   r   r7   r   r8   r   r   r   )NNN)r=   r   r>   r   r   r?   r@   rA   rB   rC   r   rD   )	Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ústaticmethodr+   r3   r<   r‰   © r,   r*   r   r      s°   € € € € € ØPÐPàð"ð "ð "ñ „\ð"ð* ð	'ð 	'ð 	'ñ „\ð	'ð ð Ø ð	8ð 8ð 8ð 8ñ „\ð8ð, '+Ø37Ø%)ð]
ð ]
ð ]
ð ]
ð ]
ð ]
ð ]
r,   r   )r�   Ú
__future__r   r!   Útypingr   r   r   r   Úcombat.combat_typesr   r	   r
   r   r   r   r   r   r   r   r�   r,   r*   ú<module>r“      sú   ððð ð #Ð "Ð "Ð "Ð "Ð "Ø €€€Ø .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .ð
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ðU
ð U
ð U
ð U
ð U
ñ U
ô U
ð U
ð U
ð U
r,   