§
    o½»j  ã                  óæ   — d Z ddlmZ ddlmZm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 ddlmZ ddlmZ ddlmZ  ed	¬
¦  «         G d„ d¦  «        ¦   «         Z G d„ d¦  «        ZdS )z¥
Server-Authoritative Combat Engine for FreeExile.
Coordinates Combat Entities, Hit Resolution, Boss Stagger Recovery,
Status Ailments, and Five Elements Interplay.
é    )Úannotations)Ú	dataclassÚfield)ÚDictÚListÚOptionalÚTuple)	ÚAilmentApplicationÚAilmentTypeÚ	BossPhaseÚBossStaggerStateÚCombatHitResultÚCombatantTypeÚDamageChannelÚDamagePacketÚDefenseSheet)ÚDamageCalculator)ÚMonsterScalingEngine)ÚFiveElementsT)Úslotsc                  ó¸   — e Zd ZU dZded<   ded<   ded<   ded<   d	ed
<   ded<   dZded<   dZded<   dZded<   dZded<    e	e
¬¦  «        Zded<   dZded<   dS )ÚCombatEntityz<Runtime combat representation of a player, monster, or boss.ÚintÚ	entity_idÚstrÚnamer   Úcombatant_typeÚlevelr   Úelementr   ÚdefenseNzOptional[BossStaggerState]Úboss_staggerzOptional[BossPhase]Ú
boss_phaser   Úlast_evasion_timestamp_mséú   Úevasion_iframe_duration_ms)Údefault_factoryzList[AilmentApplication]Úactive_ailmentsÚlast_hit_received_timestamp_ms)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú__annotations__r!   r"   r#   r%   r   Úlistr'   r(   © ó    ú4C:\Projects\FreeExile\server\combat\combat_engine.pyr   r      sÍ   € € € € € € àFÐFØ€N€N�NØ€I€I�IØ!Ð!Ð!Ñ!Ø€J€J�JØÐÐÑØÐÐÑØ/3€LÐ3Ð3Ð3Ñ3Ø&*€JÐ*Ð*Ð*Ñ*Ø%&ÐÐ&Ð&Ð&Ñ&Ø&)ÐÐ)Ð)Ð)Ñ)Ø05°ÀdÐ0KÑ0KÔ0K€OÐKÐKÐKÑKØ*+Ð"Ð+Ð+Ð+Ñ+Ð+Ð+r0   r   c            
      ó¾   — e Zd 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d„Zdd„Zdd„Zdd„Zdd„ZdS )ÚCombatEnginezECentral authority executing combat ticks, attacks, and state updates.ÚreturnÚNonec                ó`   — i | _         t          ¦   «         | _        t          ¦   «         | _        d S ©N)Úentitiesr   Ú
calculatorr   Úscaling)Úselfs    r1   Ú__init__zCombatEngine.__init__8   s'   € Ø13ˆŒÝ*Ñ,Ô,ˆŒÝ+Ñ-Ô-ˆŒˆˆr0   Úentityr   c                ó$   — || j         |j        <   d S r7   )r8   r   )r;   r=   s     r1   Úregister_entityzCombatEngine.register_entity=   s   € Ø*0ˆŒ�fÔ&Ñ'Ð'Ð'r0   r   r   úOptional[CombatEntity]c                ó6   — | j                              |¦  «        S r7   )r8   Úget)r;   r   s     r1   Ú
get_entityzCombatEngine.get_entity@   s   € ØŒ}× Ò  Ñ+Ô+Ð+r0   Úcurrent_timestamp_msÚboolc                óP   — | j                              |¦  «        }|sdS ||_        dS )uC   Triggers Huyá»…n áº¢nh Bá»™ (0.25s i-frame invulnerability window).FT)r8   rB   r#   )r;   r   rD   r=   s       r1   Útrigger_phantom_evasionz$CombatEngine.trigger_phantom_evasionC   s1   € à”×"Ò" 9Ñ-Ô-ˆØð 	Ø�5Ø+?ˆÔ(Øˆtr0   Úattacker_idÚdefender_idÚpacketr   úOptional[CombatHitResult]c                óª  — | j                              |¦  «        }| j                              |¦  «        }|r|sdS ||j        z
  }d|cxk    o
|j        k    nc |j        _        | j                             |j        ¦  «        |j        k    r|j         	                    d¦  «         | j
                             ||j        |j        j        |j        ¬¦  «        \  }}	|	|j        _        |j        re||_        |j        t"          j        k    rI| j                             |j        j        |j        j        ¬¦  «        }
|
|j        k    r|
|_        |
|_        |S )z7Processes an outgoing attack against a defender entity.Nr   g      ô?)rJ   r    Úentropy_poolr!   )Ú
current_hpÚmax_hp)r8   rB   r#   r%   r    Úis_in_iframeÚELEMENT_OVERCOMINGr   Úmore_damage_multipliersÚappendr9   Úexecute_hitrM   r!   Úis_hitr(   r   r   ÚBOSSr:   Úevaluate_boss_phaseÚcurrent_lifeÚmax_lifer"   Úboss_phase_transition)r;   rH   rI   rJ   rD   ÚattackerÚdefenderÚelapsedÚresultÚnext_entropyÚ	new_phases              r1   Úprocess_attackzCombatEngine.process_attackK   sv  € ð ”=×$Ò$ [Ñ1Ô1ˆØ”=×$Ò$ [Ñ1Ô1ˆØð 	˜xð 	Ø�4ð '¨Ô)KÑKˆØ()¨WÐ([Ð([Ò([Ð([¸Ô8[Ò([Ð([Ð([Ð([ˆÔÔ%ð Ô"×&Ò& xÔ'7Ñ8Ô8¸HÔ<LÒLÐLØÔ*×1Ò1°$Ñ7Ô7Ð7ð  $œ×:Ò:ØØÔ$Ø!Ô)Ô6Ø!Ô.ð	  ;ñ  
ô  
Ñˆ�ð )5ˆÔÔ%àŒ=ð 	=Ø6JˆHÔ3ð Ô&­-Ô*<Ò<Ð<Ø œL×<Ò<Ø'Ô/Ô<Ø#Ô+Ô4ð =ñ ô �	ð  Ô 3Ò3Ð3Ø*3�HÔ'Ø3<�FÔ0àˆr0   Ú	delta_secÚfloatc                óÞ  — | j                              ¦   «         D �]Q}|j        r×|j        j        rJ|j        xj        |z  c_        |j        j        dk    r$d|j        _        d|j        _        d|j        _        n�|j        j        dk    r|j        xj        |z  c_        ||j        z
  dz  }|dk    rI|j        j        dk    r9|j        j        dz  |z  }t          d|j        j        |z
  ¦  «        |j        _        ||j        z
  dz  }|dk    r]|j
        j        |j
        j        k     rC|j
        j        dz  |z  }t          |j
        j        |j
        j        |z   ¦  «        |j
        _        �ŒSd	S )
z5Periodic server loop update (called at 30Hz or 60Hz).g        Fg       @g     @�@g      @gš™™™™™¹?g      @gš™™™™™É?N)r8   Úvaluesr!   Úis_staggeredÚstagger_duration_remaining_secÚstagger_cooldown_remaining_secr(   Úcurrent_staggerÚmax_stagger_poiseÚmaxr    Úcurrent_wardÚmax_wardÚmin)r;   rb   rD   r=   Útime_since_hitÚdecayÚrecharge_rates          r1   Úupdate_tickzCombatEngine.update_tickx   sŒ  € à”m×*Ò*Ñ,Ô,ð 	xñ 	xˆFàÔ"ð tØÔ&Ô3ð tØÔ'ÐFÔFÈ)ÑSÐFÔFØÔ*ÔIÈSÒPÐPØ;@˜Ô+Ô8ØMP˜Ô+ÔJØMP˜Ô+ÔJøàÔ*ÔIÈCÒOÐOØÔ+ÐJÔJÈiÑWÐJÔJà&:¸VÔ=bÑ&bÐflÑ%l�NØ%¨Ò,Ð,°Ô1DÔ1TÐWZÒ1ZÐ1ZØ &Ô 3Ô EÈÑ LÈyÑ X˜Ý>AÀ#ÀvÔGZÔGjÐmrÑGrÑ>sÔ>s˜Ô+Ô;ð 3°VÔ5ZÑZÐ^dÑdˆNØ Ò$Ð$¨¬Ô)DÀvÄ~ÔG^Ò)^Ð)^Ø &¤Ô 7¸$Ñ >ÀÑ J�Ý.1°&´.Ô2IÈ6Ì>ÔKfÐivÑKvÑ.wÔ.w�”Ô+ùð-	xð 	xr0   N)r4   r5   )r=   r   r4   r5   )r   r   r4   r@   )r   r   rD   r   r4   rE   )
rH   r   rI   r   rJ   r   rD   r   r4   rK   )rb   rc   rD   r   r4   r5   )r)   r*   r+   r,   r   ÚKIMÚMOCÚTHOÚTHUYÚHOArQ   r<   r?   rC   rG   ra   rr   r/   r0   r1   r3   r3   ,   sÚ   € € € € € ØOÐOð 	Ô˜,Ô*ØÔ˜,Ô*ØÔ˜,Ô+ØÔ˜<Ô+ØÔ˜,Ô*ðÐð.ð .ð .ð .ð
1ð 1ð 1ð 1ð,ð ,ð ,ð ,ðð ð ð ð+ð +ð +ð +ðZxð xð xð xð xð xr0   r3   N)r,   Ú
__future__r   Údataclassesr   r   Útypingr   r   r   r	   Úcombat.combat_typesr
   r   r   r   r   r   r   r   r   Úcombat.damage_calculatorr   Úcombat.monster_scalingr   Úworld.martial_matrixr   r   r3   r/   r0   r1   ú<module>r      s�  ððð ð #Ð "Ð "Ð "Ð "Ð "Ø (Ð (Ð (Ð (Ð (Ð (Ð (Ð (Ø .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .ð
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 6Ð 5Ð 5Ð 5Ð 5Ð 5Ø 7Ð 7Ð 7Ð 7Ð 7Ð 7Ø -Ð -Ð -Ð -Ð -Ð -ð €�ÐÑÔð,ð ,ð ,ð ,ð ,ñ ,ô ,ñ Ôð,ð dxð dxð dxð dxð dxñ dxô dxð dxð dxð dxr0   