§
    	�Áj€4  ã                   ól  — d Z ddlmZmZmZmZmZmZmZ ddl	m
Z
mZ erddlmZ n	 ddlmZ n# e$ r	 ddlmZ Y nw xY we
 G d„ d¦  «        ¦   «         Ze
 G d„ d¦  «        ¦   «         Ze
 G d	„ d
¦  «        ¦   «         Z	 ddlmZmZmZmZmZ n# e$ r ddlmZmZmZmZmZ Y nw xY w G d„ d¦  «        ZdS )u  
Server-Authoritative Combat Engine & Five Elements System for FreeExile.
Calculates elemental interactions (NgÅ© HÃ nh TÆ°Æ¡ng Kháº¯c), resistance mitigation,
critical strikes, and enforces Huyá»…n áº¢nh Bá»™ (Phantom Evasion) 0.25s i-frame invulnerability.
é    )ÚAnyÚCallableÚDictÚListÚOptionalÚTupleÚTYPE_CHECKING)Ú	dataclassÚfield)ÚFiveElementsc                   ó~  — e Zd ZU eed<   eed<   eed<   dZeed<   dZ	eed<   dZ
eed<   d	Zeed
<   dZeed<    ee¬¦  «        Zeeef         ed<   dZeed<   dZeed<   dZeed<   dZeed<   dZee         ed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed <   d!Zeed"<    ee¬¦  «        Zeeef         ed#<   dS )$ÚCombatActorÚactor_idÚnameÚelementg     @�@Ú
current_hpÚmax_hpç      I@Úbase_attackgš™™™™™©?Úcrit_chanceg      ø?Úcrit_multiplier)Údefault_factoryÚresistancesiüÿÿÚlast_evasion_timestamp_mséú   Úevasion_iframe_duration_msFÚ	is_playeré   ÚlevelNÚ	player_idÚSWORDÚweapon_set_1ÚPROJECTILE_WEAPONÚweapon_set_2Úactive_weapon_setg      Y@Úcurrent_energyÚ
max_energyr   Úanimation_locked_until_msÚ	cooldowns) Ú__name__Ú
__module__Ú__qualname__ÚintÚ__annotations__Ústrr   r   Úfloatr   r   r   r   r   Údictr   r   r   r   r   Úboolr   r    r   r"   r   r$   r%   r&   r'   r(   r)   © ó    ú3C:\Projects\FreeExile\server\world\combat_engine.pyr   r      s�  € € € € € € à€M€M�MØ
€I€I�IØÐÐÑØ€J�ÐÐÑØ€FˆEÐÐÑØ€K�ÐÐÑØ€K�ÐÐÑØ €O�UÐ Ð Ñ Ø-2¨UÀ4Ð-HÑ-HÔ-H€K��l EÐ)Ô*ÐHÐHÑHØ%*Ð˜sÐ*Ð*Ñ*Ø&)Ð Ð)Ð)Ñ)Ø€IˆtÐÐÑØ€Eˆ3€N€N�NØ#€Iˆx˜Œ}Ð#Ð#Ñ#à€L�#ÐÐÑØ+€L�#Ð+Ð+Ñ+ØÐ�sÐÐÑØ!€N�EÐ!Ð!Ñ!Ø€J�ÐÐÑØ%&Ð˜sÐ&Ð&Ñ&Ø % °dÐ ;Ñ ;Ô ;€Iˆt�C˜�HŒ~Ð;Ð;Ñ;Ð;Ð;r4   r   c                   ód   — e Zd ZU eed<   eed<   eed<   eed<   eed<   eed<   eed<   dZeed	<   d
S )ÚDamageEventResultÚattacker_idÚdefender_idÚ
raw_damageÚfinal_damageÚis_criticalÚ	is_evadedr   FÚis_fatalN)	r*   r+   r,   r-   r.   r0   r2   r   r>   r3   r4   r5   r7   r7   -   ss   € € € € € € àÐÐÑØÐÐÑØÐÐÑØÐÐÑØÐÐÑØ€O€O�OØÐÐÑØ€HˆdÐÐÑÐÐr4   r7   c                   ó¤   — e Zd ZU eed<   eed<   eed<   ee         ed<   dZee         ed<   dZ	eed<   d	Z
eed
<   dZeed<   dZeed<   dZeed<   dS )ÚSkillCastResultÚsuccessÚskill_idr8   Ú	target_idNÚdamage_resultr   Úprojectilesç        Úenergy_consumedFÚswapped_weaponÚnew_weapon_setÚ Úerror_reason)r*   r+   r,   r2   r.   r-   r   rD   r7   rE   rG   r0   rH   rI   rK   r/   r3   r4   r5   r@   r@   9   s¦   € € € € € € à€M€M�MØ€M€M�MØÐÐÑØ˜Œ}ÐÐÑØ15€M�8Ð-Ô.Ð5Ð5Ñ5Ø€K�ÐÐÑØ €O�UÐ Ð Ñ Ø €N�DÐ Ð Ñ Ø€N�CÐÐÑØ€L�#ÐÐÑÐÐr4   r@   )Úextract_weapon_categoryÚweapon_matchesÚparse_elementÚresolve_skill_dataÚresolve_sigil_datac                   ó”  — e Zd Zej        ej        ej        ej        ej        ej        ej        ej        ej        ej        iZ	d#d„Z
deeeeegdf                  ddfd„Zdeddfd„Zdeddfd	„Zd
ededefd„Zd
ededefd„Zd
edefd„Zdededededee         deeef         fd„Zdee         dee         dedededededee         fd„Z	 d$dedededededee         defd„Zdededeeef         fd„Zdedee ef         de!e         dedeeeef         f
d „Z"	 	 d%deded!ee         dedee!e                  dede#fd"„Z$dS )&ÚCombatEngineÚreturnNc                 ó"   — i | _         d | _        d S ©N)ÚactorsÚon_fatal_damage)Úselfs    r5   Ú__init__zCombatEngine.__init__d   s   € Ø.0ˆŒØhlˆÔÐÐr4   Úcallbackc                 ó   — || _         dS )z=Sets an optional observer callback triggered on fatal damage.N)rW   )rX   rZ   s     r5   Úset_fatal_damage_hookz"CombatEngine.set_fatal_damage_hookh   s   € ð  (ˆÔÐÐr4   Úservicec                 ól   ‡— dt           dt          dt          ddfˆfd„}|                      |¦  «         dS )zOAttaches a LevelProgressionService instance via an automated fatal damage hook.ÚresÚatkÚdfnrS   Nc                 ó‚  •— t          |dd¦  «        s^t          |dd¦  «        rMt          |dd ¦  «        pt          |j        ¦  «        }‰                     |t          |dd¦  «        ¬¦  «         d S t          |dd¦  «        r=t          |dd ¦  «        pt          |j        ¦  «        }‰                     |¬¦  «         d S d S )Nr   Fr    r   r   )r    Úmonster_level)r    )Úgetattrr/   r   Úaward_monster_expÚapply_death_penalty)r_   r`   ra   Úpidr]   s       €r5   Ú_hookz6CombatEngine.attach_progression_service.<locals>._hookp   sÓ   ø€ Ý˜3 ¨UÑ3Ô3ð ;½ÀÀ[ÐRWÑ8XÔ8Xð ;Ý˜c ;°Ñ5Ô5ÐJ½¸S¼\Ñ9JÔ9J�Ø×)Ò)°CÅwÈsÐT[Ð]^ÑG_ÔG_Ð)Ñ`Ô`Ð`Ð`Ð`Ý˜˜k¨5Ñ1Ô1ð ;Ý˜c ;°Ñ5Ô5ÐJ½¸S¼\Ñ9JÔ9J�Ø×+Ò+°cÐ+Ñ:Ô:Ð:Ð:Ð:ð;ð ;r4   )r7   r   r\   )rX   r]   rh   s    ` r5   Úattach_progression_servicez'CombatEngine.attach_progression_servicen   s[   ø€ ð	;Õ(ð 	;­{ð 	;Åð 	;ÐQUð 	;ð 	;ð 	;ð 	;ð 	;ð 	;ð 	×"Ò" 5Ñ)Ô)Ð)Ð)Ð)r4   Úactorc                 ó$   — || j         |j        <   d S rU   )rV   r   )rX   rj   s     r5   Úregister_actorzCombatEngine.register_actorz   s   € Ø&+ˆŒ�E”NÑ#Ð#Ð#r4   r   Útimestamp_msc                 ó^   — | j                              |¦  «        }|sdS ||_        d|_        dS )uQ   Triggers Huyá»…n áº¢nh Bá»™, canceling animation lock and granting 250ms i-frame.Fr   T)rV   Úgetr   r(   ©rX   r   rm   rj   s       r5   Útrigger_phantom_evasionz$CombatEngine.trigger_phantom_evasion}   s7   € à”—’ Ñ)Ô)ˆØð 	Ø�5Ø*6ˆÔ'Ø*+ˆÔ'Øˆtr4   c                 óT   — | j                              |¦  «        }|sdS ||j        k     S )z=Checks if the actor is currently locked in a skill animation.F)rV   ro   r(   rp   s       r5   Úis_animation_lockedz CombatEngine.is_animation_locked†   s0   € à”—’ Ñ)Ô)ˆØð 	Ø�5Ø˜eÔ=Ò=Ð=r4   c                 ót   — | j                              |¦  «        }|sdS |j        dk    rdnd|_        |j        S )z9Manually swaps active weapon set between Set 1 and Set 2.r   é   )rV   ro   r%   )rX   r   rj   s      r5   Úswap_weapon_setzCombatEngine.swap_weapon_set�   sD   € à”—’ Ñ)Ô)ˆØð 	Ø�1Ø',Ô'>À!Ò'CÐ'C ! !ÈˆÔØÔ&Ð&r4   ÚattackerÚdefenderr:   Údamage_elementÚ
force_critc                 ó   — | j                              |¦  «        |j        k    rdnd}|j                             |d¦  «        }t	          dt          d|¦  «        ¦  «        }||z  d|z
  z  }	|�|nd}
|
r
|	|j        z  }	t          d|	¦  «        |
fS )zPCalculates elemental overcoming, resistance mitigation, and critical multiplier.g      ô?ç      ð?rF   g      è?g      à¿NF)ÚELEMENT_OVERCOMINGro   r   r   ÚminÚmaxr   )rX   rw   rx   r:   ry   rz   Ú	elem_multr_   Úeffective_resÚ	mitigatedÚis_crits              r5   Ú_calculate_mitigated_damagez(CombatEngine._calculate_mitigated_damage•   s§   € ð !Ô3×7Ò7¸ÑGÔGÈ8ÔK[Ò[Ð[�D�DÐadˆ	ØÔ"×&Ò& ~°sÑ;Ô;ˆÝ˜D¥# e¨S¡/¤/Ñ2Ô2ˆØ Ñ*¨c°MÑ.AÑBˆ	Ø *Ð 6�*�*¸EˆØð 	2Ø˜Ô1Ñ1ˆIÝ�3˜	Ñ"Ô" GÐ+Ð+r4   r8   r9   Úcurrent_timestamp_msc           
      óº   — |r|st          |||ddd|d¦  «        S |j        dk    r5||j        z
  }d|cxk    r|j        k    rn nt          |||ddd|d¦  «        S dS )zJHandles missing actors or evasion i-frames without full combat resolution.rF   Fr   TN)r7   r   r   )	rX   rw   rx   r8   r9   r:   ry   r…   Úelapseds	            r5   Ú_check_special_damage_casesz(CombatEngine._check_special_damage_cases§   s¤   € ð ð 	˜xð 	Ý$Ø˜[¨*°c¸5À%ÈÐY^ñô ð ð Ô-°Ò2Ð2Ø*¨XÔ-OÑOˆGØ�GÐBÐBÒBÐB˜xÔBÒBÐBÐBÐBÐBÝ(Ø ¨j¸#¸uÀdÈNÐ\añô ð ð ˆtr4   c           
      óÞ  — | j                              |¦  «        }| j                              |¦  «        }|                      |||||||¦  «        }	|	�|	S |�|€J ‚|                      |||||¦  «        \  }
}|j        dk    }t          d|j        |
z
  ¦  «        }||_        |o|dk    }t          |||t          |
d¦  «        |d||¬¦  «        }|r| j        �|                      |||¦  «         |S )NrF   ru   F)r8   r9   r:   r;   r<   r=   r   r>   )	rV   ro   rˆ   r„   r   r   r7   ÚroundrW   )rX   r8   r9   r:   ry   r…   rz   rw   rx   Úspecialr;   rƒ   Ú	was_aliveÚnew_hpr>   Úresults                   r5   Úcalculate_damagezCombatEngine.calculate_damage¾   s3  € ð ”;—?’? ;Ñ/Ô/ˆØ”;—?’? ;Ñ/Ô/ˆà×2Ò2Ø�h ¨[¸*ÀnÐVjñ
ô 
ˆð ÐØˆNØÐ#¨Ð(<Ð(<Ð<à $× @Ò @Ø�h 
¨N¸Jñ!
ô !
Ñˆ�gð Ô(¨3Ò.ˆ	Ý�S˜(Ô-°Ñ<Ñ=Ô=ˆØ$ˆÔØÐ0 &¨C¢-ˆå"Ø#Ø#Ø!Ý˜|¨QÑ/Ô/ØØØ"Øð	
ñ 	
ô 	
ˆð ð 	=˜Ô,Ð8Ø× Ò  ¨°8Ñ<Ô<Ð<àˆr4   Ú
req_weaponc                 ó2  — |�(t          |¦  «        dk    st          |dd¦  «        dk    rdS |j        dk    r|j        n|j        }t          ||¦  «        rdS |j        dk    r|j        n|j        }t          ||¦  «        r|j        dk    rdnd|_        dS d	S )
zGValidates weapon compatibility and auto-swaps if alternate weapon fits.NÚANYÚvaluerJ   )FTr   ru   )TT)FF)r/   rd   r%   r"   r$   rM   )rX   rw   r�   Ú
cur_weaponÚ
alt_weapons        r5   Ú_resolve_weapon_for_castz%CombatEngine._resolve_weapon_for_casté   sÁ   € ð Ð¥ Z¡¤°EÒ!9Ð!9½WÀZÐQXÐZ\Ñ=]Ô=]ÐafÒ=fÐ=fØ�;Ø.6Ô.HÈAÒ.MÐ.M�XÔ*Ð*ÐS[ÔShˆ
Ý˜* jÑ1Ô1ð 	Ø�;Ø.6Ô.HÈAÒ.MÐ.M�XÔ*Ð*ÐS[ÔShˆ
Ý˜* jÑ1Ô1ð 	Ø.6Ô.HÈAÒ.MÐ.M¨¨ÐSTˆHÔ&Ø�:Øˆ|r4   rB   Ú
skill_dataÚlinked_sigil_idsÚskill_dbc                 ó   — t          |                     dd¦  «        ¦  «        }t          |                     dd¦  «        ¦  «        }t          |                     dd¦  «        ¦  «        }|D ]´}|r,t          |d¦  «        r|                     ||¦  «        \  }	}
|	sŒ0t          ||¦  «        }|rr|t          |                     dd¦  «        ¦  «        z  }|t          |                     d	d
¦  «        ¦  «        z  }|t          |                     dd¦  «        ¦  «        z  }Œµt          d|¦  «        t          d|¦  «        t          d|¦  «        fS )zMCalculates combined damage, projectiles, and energy cost from support sigils.Úbase_damagerF   Úbase_projectile_countr   Úenergy_costÚvalidate_gem_linkÚdamage_multiplierr|   Úprojectile_bonusr   Úenergy_cost_multiplier)r0   ro   r-   Úhasattrrž   rP   r   )rX   rB   r—   r˜   r™   Ú
eff_damageÚeff_projÚeff_costÚsigil_idÚvalidÚ_Úsigils               r5   Ú_calculate_sigil_modifiersz'CombatEngine._calculate_sigil_modifiersø   sL  € õ ˜:Ÿ>š>¨-¸Ñ=Ô=Ñ>Ô>ˆ
Ý�z—~’~Ð&=¸qÑAÔAÑBÔBˆÝ˜Ÿš¨°sÑ;Ô;Ñ<Ô<ˆØ(ð 		Lð 		LˆHØð �G HÐ.AÑBÔBð Ø#×5Ò5°hÀÑIÔI‘��qØð ØÝ& x°Ñ:Ô:ˆEØð LØ�e E§I¢IÐ.AÀ3Ñ$GÔ$GÑHÔHÑH�
Ø�C §	¢	Ð*<¸aÑ @Ô @ÑAÔAÑA�Ø�E %§)¢)Ð,DÀcÑ"JÔ"JÑKÔKÑK�øÝ�3˜
Ñ#Ô#¥S¨¨HÑ%5Ô%5µs¸3ÀÑ7IÔ7IÐIÐIr4   rC   c                 óˆ  — | j                              |¦  «        }|st          d|||d¬¦  «        S |                      ||¦  «        rt          d|||d¬¦  «        S t	          ||¦  «        }|st          d|||d¬¦  «        S |j                             |d¦  «        }	||	k     rt          d|||d¬¦  «        S |                     d¦  «        }
|                      ||
¦  «        \  }}|st          d|||d|j        d	¬
¦  «        S |                      |||pg |¦  «        \  }}}|j	        |k     rt          d|||||j        d¬
¦  «        S t          d|j	        |z
  ¦  «        |_	        |t          |                     dd¦  «        ¦  «        z   |j        |<   |t          |                     dd¦  «        ¦  «        z   |_        d}|�Z|dk    rTt          |                     dt          j        ¦  «        ¦  «        }||j        dz  z  }|                      |||||¬¦  «        }t          d|||||t%          |d¦  «        ||j        ¬¦	  «	        S )z?Executes a server-authoritative skill cast with PoE2 mechanics.FÚATTACKER_NOT_FOUND)rK   ÚANIMATION_LOCKEDÚSKILL_NOT_FOUNDr   ÚCOOLDOWN_ACTIVEÚweapon_requirementÚWEAPON_INCOMPATIBLE)rH   rI   rK   ÚINSUFFICIENT_ENERGYrF   Úcooldown_msÚanimation_lock_msNr   r   )r8   r9   r:   ry   r…   Tru   )	rA   rB   r8   rC   rD   rE   rG   rH   rI   )rV   ro   r@   rs   rO   r)   r–   r%   rª   r&   r   r-   r(   rN   r   ÚKIMr   r�   rŠ   )rX   r8   rB   rC   rm   r˜   r™   rw   r—   Úcooldown_untilr�   ÚswappedÚswap_okr£   r¤   r¥   Ú
damage_resÚelemÚraw_dmgs                      r5   Úexecute_skill_castzCombatEngine.execute_skill_cast  sº  € ð ”;—?’? ;Ñ/Ô/ˆØð 	oÝ" 5¨(°KÀÐYmÐnÑnÔnÐnà×#Ò# K°Ñ>Ô>ð 	mÝ" 5¨(°KÀÐYkÐlÑlÔlÐlå'¨°(Ñ;Ô;ˆ
Øð 	lÝ" 5¨(°KÀÐYjÐkÑkÔkÐkà!Ô+×/Ò/°¸!Ñ<Ô<ˆØ˜.Ò(Ð(Ý" 5¨(°KÀÐYjÐkÑkÔkÐkà—^’^Ð$8Ñ9Ô9ˆ
Ø×8Ò8¸À:ÑNÔNÑˆ�Øð 	Ý"Ø�x ¨iØ$°XÔ5OØ2ðñ ô ð ð *.×)HÒ)HØ�jÐ"2Ð"8°b¸(ñ*
ô *
Ñ&ˆ
�H˜hð Ô" XÒ-Ð-Ý"Ø�x ¨iØ&°xÔ7QØ2ðñ ô ð õ #& c¨8Ô+BÀXÑ+MÑ"NÔ"NˆÔØ'3µc¸*¿.º.ÈÐXYÑ:ZÔ:ZÑ6[Ô6[Ñ'[ˆÔ˜8Ñ$Ø-9½CÀ
ÇÂÐObÐdeÑ@fÔ@fÑ<gÔ<gÑ-gˆÔ*àˆ
ØÐ  Z°!¢^ ^Ý  §¢°	½<Ô;KÑ!LÔ!LÑMÔMˆDØ  HÔ$8¸4Ñ$?Ñ@ˆGØ×.Ò.Ø'Ø%Ø"Ø#Ø%1ð /ñ ô ˆJõ ØØØ#ØØ$Ø Ý! (¨AÑ.Ô.Ø"Ø#Ô5ð

ñ 

ô 

ð 
	
r4   )rS   NrU   )NN)%r*   r+   r,   r   rµ   ÚMOCÚTHOÚTHUYÚHOAr}   rY   r   r   r7   r   r\   r   ri   rl   r-   r2   rq   rs   rv   r0   Útupler„   rˆ   r�   r   r–   r   r/   r   rª   r@   r¼   r3   r4   r5   rR   rR   Y   s¯  € € € € € ð 	Ô˜,Ô*ØÔ˜,Ô*ØÔ˜,Ô+ØÔ˜<Ô+ØÔ˜,Ô*ðÐðmð mð mð mð(Ø  Ð+<¸kÈ;Ð*WÐY]Ð*]Ô!^Ô_ð(à	ð(ð (ð (ð (ð
*°#ð 
*¸$ð 
*ð 
*ð 
*ð 
*ð, Kð ,°Dð ,ð ,ð ,ð ,ð°ð À3ð È4ð ð ð ð ð>¨Cð >¸sð >Àtð >ð >ð >ð >ð'¨ð '°ð 'ð 'ð 'ð 'ð,àð,ð ð,ð ð	,ð
 %ð,ð ˜T”Nð,ð 
ˆu�dˆ{Ô	ð,ð ,ð ,ð ,ð$à˜;Ô'ðð ˜;Ô'ðð ð	ð
 ðð ðð %ðð "ðð 
Ð#Ô	$ðð ð ð ð< &*ð)ð )àð)ð ð)ð ð	)ð
 %ð)ð "ð)ð ˜T”Nð)ð 
ð)ð )ð )ð )ðVØ#ðØ14ðà	ˆt�TˆzÔ	ðð ð ð ðJàðJð ˜˜c˜”NðJð ˜sœ)ð	Jð
 ðJð 
ˆu�c˜5Ð Ô	!ðJð Jð Jð Jð: 15ØðG
ð G
àðG
ð ðG
ð ˜C”=ð	G
ð
 ðG
ð # 4¨¤9Ô-ðG
ð ðG
ð 
ðG
ð G
ð G
ð G
ð G
ð G
r4   rR   N)Ú__doc__Útypingr   r   r   r   r   r   r	   Údataclassesr
   r   Úserver.world.martial_matrixr   ÚImportErrorÚworld.martial_matrixr   r7   r@   Ú!server.world.combat_skill_helpersrL   rM   rN   rO   rP   Úworld.combat_skill_helpersrR   r3   r4   r5   ú<module>rÊ      s_  ððð ð MÐ LÐ LÐ LÐ LÐ LÐ LÐ LÐ LÐ LÐ LÐ LÐ LÐ LÐ LÐ LÐ LÐ LØ (Ð (Ð (Ð (Ð (Ð (Ð (Ð (àð 6Ø8Ð8Ð8Ð8Ð8Ð8Ð8ð6Ø<Ð<Ð<Ð<Ð<Ð<Ð<øØð 6ð 6ð 6Ø5Ð5Ð5Ð5Ð5Ð5Ð5Ð5ð6øøøð ð<ð <ð <ð <ð <ñ <ô <ñ „ð<ð2 ðð ð ð ð ñ ô ñ „ðð ð
ð 
ð 
ð 
ð 
ñ 
ô 
ñ „ð
ððð ð ð ð ð ð ð ð ð ð ð ð ð ð øð ð ð ð ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ðøøøð}
ð }
ð }
ð }
ð }
ñ }
ô }
ð }
ð }
ð }
s   §. ®<»<Á?B ÂB$Â#B$