§
    /Áj£(  ã            
       óv  — d Z ddlZddlZddlZej                             dej                             ej                             ej                             e	¦  «        d¦  «        ¦  «        ¦  «         ddl
mZmZmZmZmZmZmZmZmZmZmZmZ  G d„ dej        ¦  «        Zedk    r ej        ¦   «          dS dS )u"  
Unit tests for ChÃ¢n VÃµ Ä�an & Tháº§n Biáº¿n PhÃ¹ (Martial Matrix Engine) in FreeExile.
Verifies:
1. Socketing active martial skills & linking augmenting sigils.
2. Tag compatibility enforcement (cannot link incompatible sigils).
3. PoE2 Trade-Off mechanics (Upside always accompanied by Downside).
4. Character Loadout & Attributes scaling (CÆ°Æ¡ng Thá»ƒ, ThÃ¢n PhÃ¡p, Tháº§n Niá»‡m).
5. Song Binh Tá»± Ä�á»™ng HoÃ¡n Ä�á»•i (Dual Weapon Auto-Swap in 0ms).
6. Recoil damage, resource conversion (Blood Magic), and intrinsic skill restrictions.
é    Nz../../server)ÚMartialMatrixÚ	ChanVoDanÚ
DiBienTaAnÚFiveElementsÚMartialSectÚSkillTagÚWeaponCategoryÚ
WeaponItemÚCharacterLoadoutÚSigilAugmentTypeÚcreate_standard_active_skillsÚcreate_standard_augment_sigilsc                   óP   — e Zd Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zd
„ Zd„ ZdS )ÚTestMartialMatrixc                 ó>  — t          d¬¦  «        | _        t          ¦   «         | _        t	          ¦   «         | _        t          ddt          j        dddddd	d	d
d
dt          ddt          j        ¬¦  «        t          ddt          j        ¬¦  «        ¬¦  «        | _        d S )Né   )Úmax_active_slotsée   u   TiÃªu Nháº¥t Kiáº¿mé<   éP   é(   g     À’@g     À‚@g     @o@é   u   BÃ­ch Thá»§y Kiáº¿m)Ú	weapon_idÚnameÚcategoryé   u   Huyá»�n Thiáº¿t Bá»•ng)Úactor_idr   ÚsectÚ	cuong_theÚ	than_phapÚ	than_niemÚ
current_hpÚmax_hpÚ
current_qiÚmax_qiÚward_barrierÚmax_ward_barrierÚactive_weapon_setÚweapon_set_1Úweapon_set_2)r   Úmatrixr   Úskills_catalogr   Úsigils_catalogr   r   ÚTHANH_PHONGr
   r	   ÚSWORDÚSTAFFÚchar)Úselfs    ú7C:\Projects\FreeExile\tests\unit\test_martial_matrix.pyÚsetUpzTestMartialMatrix.setUp#   s¢   € Ý#°QÐ7Ñ7Ô7ˆŒÝ;Ñ=Ô=ˆÔÝ<Ñ>Ô>ˆÔå$ØØ&ÝÔ(ØØØØØØØØØ"ØÝ#¨aÐ6KÕVdÔVjÐkÑkÔkÝ#¨aÐ6NÕYgÔYmÐnÑnÔnð
ñ 
ô 
ˆŒ	ˆ	ˆ	ó    c                 óÞ   — | j         d         }| j                             d|¬¦  «        }|                      |¦  «         |                      | j                             d¦  «        |¦  «         dS )z*Test socketing standard skill into slot 0.éé  r   ©Ú
slot_indexÚskillN)r,   r+   Úsocket_active_skillÚ
assertTrueÚassertEqualÚget_active_skill)r2   r:   Úsuccesss      r3   Útest_socket_active_chan_vo_danz0TestMartialMatrix.test_socket_active_chan_vo_dan:   sg   € àÔ# DÔ)ˆØ”+×1Ò1¸QÀeÐ1ÑLÔLˆØ�Š˜Ñ Ô Ð Ø×Ò˜œ×5Ò5°aÑ8Ô8¸%Ñ@Ô@Ð@Ð@Ð@r5   c                 óØ  — | j         d         }| j                             d|¬¦  «         | j        d         }| j                             d|¬¦  «        \  }}|                      |¦  «         |                      d|¦  «         | j        d         }| j                             d|¬¦  «        \  }}|                      |¦  «         |                      t          |j
        ¦  «        d¦  «         dS )	zASigil requiring PROJECTILE must NOT link to a purely MELEE skill.éï  r   r8   éÑ  ©r9   Úsigilu   khÃ´ng tÆ°Æ¡ng thÃ­chiÒ  N)r,   r+   r;   r-   Úlink_sigil_to_skillÚassertFalseÚassertInr<   r=   ÚlenÚlinked_sigils)r2   Úmelee_skillÚprojectile_sigilr?   ÚmsgÚ	aoe_sigilÚsuccess_aoeÚmsg_aoes           r3   Ú"test_tag_compatibility_enforcementz4TestMartialMatrix.test_tag_compatibility_enforcementA   sì   € ð Ô)¨$Ô/ˆØŒ×'Ò'°1¸KÐ'ÑHÔHÐHð  Ô.¨tÔ4ÐØ”{×6Ò6À!ÐK[Ð6Ñ\Ô\‰ˆ�Ø×Ò˜Ñ!Ô!Ð!Ø�ŠÐ-¨sÑ3Ô3Ð3ð Ô'¨Ô-ˆ	Ø#œ{×>Ò>È!ÐS\Ð>Ñ]Ô]Ñˆ�WØ�Š˜Ñ$Ô$Ð$Ø×Ò�˜[Ô6Ñ7Ô7¸Ñ;Ô;Ð;Ð;Ð;r5   c                 ó  — | j         d         }| j                             d|¬¦  «         | j        d         }| j                             d|¬¦  «        \  }}|                      |¦  «         | j                             d¬¦  «        }|                      |¦  «         |                      |d         d¦  «         |  	                    |d	         d
d¬¦  «         |                      |d         d¦  «         |                      |d         d¦  «         dS )u‚   
        PhÃ¢n Quang Ä�a HÃ³a PhÃ¹:
        Upside: +3 projectiles.
        Downside: -35% less damage, +45% energy cost.
        r7   r   r8   rC   rD   ©r9   Úprojectile_counté   Úeffective_damageg     Àf@r   ©ÚplacesÚ
cost_valueéA   Ú	cost_typeu
   CHÃ‚N_KHÃ�N)
r,   r+   r;   r-   rF   r<   Úcompute_modified_skillÚassertIsNotNoner=   ÚassertAlmostEqual©r2   r:   rE   r?   Ú_Ústatss         r3   Útest_multi_projectile_trade_offz1TestMartialMatrix.test_multi_projectile_trade_offS   s  € ð Ô# DÔ)ˆØŒ×'Ò'°1¸EÐ'ÑBÔBÐBàÔ# DÔ)ˆØ”[×4Ò4ÀÈÐ4ÑOÔO‰
ˆ�Ø�Š˜Ñ Ô Ð à”×2Ò2¸aÐ2Ñ@Ô@ˆØ×Ò˜UÑ#Ô#Ð#à×Ò˜Ð1Ô2°AÑ6Ô6Ð6à×Ò˜uÐ%7Ô8¸%ÈÐÑJÔJÐJà×Ò˜˜|Ô,¨bÑ1Ô1Ð1Ø×Ò˜˜{Ô+¨\Ñ:Ô:Ð:Ð:Ð:r5   c                 ó´  — | j         d         }| j                             d|¬¦  «         | j        d         }| j                             d|¬¦  «         | j                             d¬¦  «        }|                      |¦  «         |                      |d         d¦  «         |                      |d	         ¦  «         |  	                    |d
         dd¬¦  «         dS )u¨   
        Huyáº¿t KhÃ­ Quy TÃ´ng PhÃ¹:
        Upside: +25% damage.
        Downside: Converts cost to Life (KhÃ­ Huyáº¿t) and disables Ward Barrier completely.
        ið  r   r8   iÔ  rD   rS   r[   u   KHÃ�_HUYáº¾TÚward_disabledrV   g      y@r   rW   N)
r,   r+   r;   r-   rF   r\   r]   r=   r<   r^   )r2   r:   rE   ra   s       r3   Ú6test_blood_magic_resource_conversion_and_ward_disabledzHTestMartialMatrix.test_blood_magic_resource_conversion_and_ward_disabledk   sÙ   € ð Ô# DÔ)ˆØŒ×'Ò'°1¸EÐ'ÑBÔBÐBàÔ# DÔ)ˆØŒ×'Ò'°1¸EÐ'ÑBÔBÐBà”×2Ò2¸aÐ2Ñ@Ô@ˆØ×Ò˜UÑ#Ô#Ð#Ø×Ò˜˜{Ô+¨^Ñ<Ô<Ð<Ø�Š˜˜oÔ.Ñ/Ô/Ð/à×Ò˜uÐ%7Ô8¸%ÈÐÑJÔJÐJÐJÐJr5   c                 óª  — | j         d         }| j                             d|¬¦  «         | j        d         }| j                             d|¬¦  «        \  }}|                      |¦  «         | j                             d¬¦  «        }|                      |¦  «         |                      |d         d¦  «         |                      |d	         d
¦  «         dS )u›   
        Tháº¥t ThÆ°Æ¡ng Ä�oáº¡t Má»‡nh PhÃ¹:
        Upside: +120% Crit Multiplier, +15% damage.
        Downside: 12% Recoil damage onto caster.
        r7   r   r8   iØ  rD   rS   Úrecoil_damage_percentg¸…ëQ¸¾?Úcrit_multipliergš™™™™™@N)	r,   r+   r;   r-   rF   r<   r\   r]   r=   r_   s         r3   Ú%test_seven_fists_martyr_recoil_damagez7TestMartialMatrix.test_seven_fists_martyr_recoil_damage~   sÓ   € ð Ô# DÔ)ˆØŒ×'Ò'°1¸EÐ'ÑBÔBÐBàÔ# DÔ)ˆØ”[×4Ò4ÀÈÐ4ÑOÔO‰
ˆ�Ø�Š˜Ñ Ô Ð à”×2Ò2¸aÐ2Ñ@Ô@ˆØ×Ò˜UÑ#Ô#Ð#Ø×Ò˜Ð6Ô7¸Ñ>Ô>Ð>à×Ò˜Ð0Ô1°4Ñ8Ô8Ð8Ð8Ð8r5   c                 ó¬  — | j         d         }| j                             d|¬¦  «         | j        d         }| j                             d|¬¦  «        \  }}|                      |¦  «         | j                             d¬¦  «        }|                      |¦  «         |                      |d         ¦  «         |                      |d         d	d
¬¦  «         dS )u‰   
        Kháº¯c CÆ°Æ¡ng Liá»‡t KhÃ­ PhÃ¹:
        Upside: +50% Physical damage.
        Downside: Disables all elemental damage.
        iñ  é   r8   iÙ  rD   rS   Úelemental_disabledrV   g      n@r   rW   N)	r,   r+   r;   r-   rF   r<   r\   r]   r^   r_   s         r3   Ú%test_pure_physical_disables_elementalz7TestMartialMatrix.test_pure_physical_disables_elemental‘   sÔ   € ð Ô# DÔ)ˆØŒ×'Ò'°1¸EÐ'ÑBÔBÐBàÔ# DÔ)ˆØ”[×4Ò4ÀÈÐ4ÑOÔO‰
ˆ�Ø�Š˜Ñ Ô Ð à”×2Ò2¸aÐ2Ñ@Ô@ˆØ×Ò˜UÑ#Ô#Ð#Ø�Š˜Ð2Ô3Ñ4Ô4Ð4Ø×Ò˜uÐ%7Ô8¸,ÈqÐÑQÔQÐQÐQÐQr5   c                 óò  — | j         d         }| j                             d|¬¦  «         | j                             dd¬¦  «        }| j                             d| j        ¬¦  «        }|                      |¦  «         |                      |¦  «         |                      |d         |d         ¦  «         |                      |d         |d         ¦  «         |                      |d         |d         ¦  «         dS )	zÈ
        Character attributes scaling:
        cuong_the=60 -> +12% Melee damage.
        than_phap=80 -> +12% cast speed, +8% crit chance.
        than_niem=40 -> +8% elemental/spell damage.
        rB   rU   r8   N)r9   Ú	characterrV   Úcrit_chanceÚcast_time_ms)r,   r+   r;   r\   r1   r]   ÚassertGreaterÚassertLessEqual)r2   r:   Ústats_unscaledÚstats_scaleds       r3   Ú!test_character_attributes_scalingz3TestMartialMatrix.test_character_attributes_scaling£   s÷   € ð Ô# DÔ)ˆØŒ×'Ò'°1¸EÐ'ÑBÔBÐBàœ×;Ò;ÀqÐTXÐ;ÑYÔYˆØ”{×9Ò9ÀQÐRVÔR[Ð9Ñ\Ô\ˆà×Ò˜^Ñ,Ô,Ð,Ø×Ò˜\Ñ*Ô*Ð*ð 	×Ò˜<Ð(:Ô;¸^ÐL^Ô=_Ñ`Ô`Ð`à×Ò˜<¨Ô6¸À}Ô8UÑVÔVÐVà×Ò˜\¨.Ô9¸>È.Ô;YÑZÔZÐZÐZÐZr5   c                 ój  — | j         d         }|                      | j        j        d¦  «         | j                             | j        |¦  «        \  }}}|                      |¦  «         |                      |d¦  «         |                      | j        j        d¦  «         |                      d|¦  «         dS )u¸   
        Character has Sword in Set 1, Staff in Set 2. Active is Set 1.
        Casting Staff skill (BÄƒng PhÃ¡ch HÃ n Quang Tráº­n) should automatically swap to Set 2 in 0ms!
        éí  r   r   u.   Tá»± Ä‘á»™ng hoÃ¡n Ä‘á»•i sang Bá»™ VÅ© KhÃ­ 2N)r,   r=   r1   r(   r+   Úresolve_weapon_swapr<   rH   )r2   Ústaff_skillr?   Únew_setrM   s        r3   Ú'test_song_binh_auto_weapon_swap_successz9TestMartialMatrix.test_song_binh_auto_weapon_swap_successº   sª   € ð
 Ô)¨$Ô/ˆØ×Ò˜œÔ4°aÑ8Ô8Ð8à $¤× ?Ò ?ÀÄ	È;Ñ WÔ WÑˆ�˜#Ø�Š˜Ñ Ô Ð Ø×Ò˜ !Ñ$Ô$Ð$Ø×Ò˜œÔ4°aÑ8Ô8Ð8Ø�ŠÐFÈÑLÔLÐLÐLÐLr5   c                 ó¾   — | j         d         }| j                             | j        |¦  «        \  }}}|                      |¦  «         |                      d|¦  «         dS )uŠ   
        Character has Sword and Staff.
        Casting Blade skill (Liá»‡t Há»�a ToÃ n Phong Tráº£m - Requires BLADE) must fail.
        rB   u$   Ä‘á»�u khÃ´ng thá»�a mÃ£n yÃªu cáº§uN)r,   r+   ry   r1   rG   rH   )r2   Úblade_skillr?   Ú
active_setrM   s        r3   Ú1test_song_binh_weapon_swap_incompatible_rejectionzCTestMartialMatrix.test_song_binh_weapon_swap_incompatible_rejectionÈ   s`   € ð
 Ô)¨$Ô/ˆØ#'¤;×#BÒ#BÀ4Ä9ÈkÑ#ZÔ#ZÑ ˆ�˜SØ×Ò˜Ñ!Ô!Ð!Ø�ŠÐ<¸cÑBÔBÐBÐBÐBr5   c                 ó´  — | j         d         }| j                             d|¬¦  «         | j                             d¬¦  «        }|                      |d         d¦  «         |                      |d         d¦  «         |                      |d	         d
¦  «         | j         d         }| j                             d|¬¦  «         | j                             d¬¦  «        }|                      |d         d¦  «         | j         d         }| j                             d|¬¦  «         | j                             d¬¦  «        }|                      |d         ¦  «         dS )u<  
        Verify inherent skill trade-offs:
        1. U Minh Huyáº¿t Ä�á»™c ChÃ¢m has 0 direct damage, dot_multiplier=1.5, speed_penalty=20%.
        2. BÄƒng PhÃ¡ch HÃ n Quang Tráº­n cannot crit (cannot_crit=True).
        3. Kim Cang Báº¥t Hoáº¡i Thá»ƒ immobilizes caster (immobilized_during_effect=True).
        ië  r   r8   rS   rV   g        Údot_multiplierg      ø?Úspeed_penalty_percentgš™™™™™É?rx   r   rp   iò  r   Úimmobilized_during_effectN)r,   r+   r;   r\   r=   r<   )r2   Úpoison_skillÚstats_poisonÚfreeze_skillÚstats_freezeÚfortress_skillÚstats_fortresss          r3   Útest_intrinsic_skill_trade_offsz1TestMartialMatrix.test_intrinsic_skill_trade_offsÒ   sU  € ð Ô*¨4Ô0ˆØŒ×'Ò'°1¸LÐ'ÑIÔIÐIØ”{×9Ò9ÀQÐ9ÑGÔGˆØ×Ò˜Ð&8Ô9¸3Ñ?Ô?Ð?Ø×Ò˜Ð&6Ô7¸Ñ>Ô>Ð>Ø×Ò˜Ð&=Ô>ÀÑEÔEÐEð Ô*¨4Ô0ˆØŒ×'Ò'°1¸LÐ'ÑIÔIÐIØ”{×9Ò9ÀQÐ9ÑGÔGˆØ×Ò˜ mÔ4°cÑ:Ô:Ð:ð Ô,¨TÔ2ˆØŒ×'Ò'°1¸NÐ'ÑKÔKÐKØœ×;Ò;ÀqÐ;ÑIÔIˆØ�Š˜Ð'BÔCÑDÔDÐDÐDÐDr5   N)Ú__name__Ú
__module__Ú__qualname__r4   r@   rQ   rb   re   ri   rm   rv   r|   r€   r‹   © r5   r3   r   r   "   sÐ   € € € € € ð
ð 
ð 
ð.Að Að Að<ð <ð <ð$;ð ;ð ;ð0Kð Kð Kð&9ð 9ð 9ð&Rð Rð Rð$[ð [ð [ð.Mð Mð MðCð Cð CðEð Eð Eð Eð Er5   r   Ú__main__)Ú__doc__ÚunittestÚsysÚosÚpathÚinsertÚabspathÚjoinÚdirnameÚ__file__Úworld.martial_matrixr   r   r   r   r   r   r	   r
   r   r   r   r   ÚTestCaser   rŒ   Úmainr�   r5   r3   ú<module>rž      s^  ðð	ð 	ð €€€Ø 
€
€
€
Ø 	€	€	€	à „‡‚��2”7—?’? 2¤7§<¢<°´·²ÀÑ0IÔ0IÈ>Ñ#ZÔ#ZÑ[Ô[Ñ \Ô \Ð \ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð IEð IEð IEð IEð IE˜Ô)ñ IEô IEð IEðX ˆzÒÐØ€H„M�O„O€O€O€Oð Ðr5   