§
    ¡»»jT   ã            
       ó¼  — d Z ddlZddlmc m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 ddlmZmZmZmZmZmZmZmZmZmZ ddlm Z m!Z!m"Z" ddl#m$Z$  G d„ d	ej%        ¦  «        Z&e'd
k    r ej(        ¦   «          dS dS )aQ  
Unit tests for Savage Weapons & Martial Sects System in FreeExile.
Verifies:
1. Weapon catalog loading & coverage across 5 Sects and 5 Primal Clans.
2. Attribute requirements validation (Physique, Agility, Mind).
3. Base damage scaling with Character Attributes.
4. Dual Wielding mechanics (+10% More APS, +15% Block Chance).
5. Two-Handed weapon potency (+50% More Base Damage, extended reach).
6. Shield equipping and Block Chance computation.
7. Sect & Clan Affinity Resonance Bonus.
8. Zero-latency (0ms) Dual Weapon Auto-Swap for skill execution.
9. Weapon implicit affixes application.
é    Nz../../server)ÚFiveElementsÚMartialSectÚWeaponCategory)
ÚWeaponClassÚ	GripStyleÚ
PrimalClanÚWeaponImplicitStatÚWeaponImplicitModÚBaseWeaponTemplateÚEquippedWeaponÚWeaponSetLoadoutÚWeaponScalingResultÚDualWieldBonus)Úget_base_weapon_catalogÚget_weapons_by_sectÚget_weapons_by_clan)ÚWeaponEnginec                   óJ   — 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S )ÚTestWeaponSystemc                 óR   — t          ¦   «         | _        t          ¦   «         | _        d S )N)r   Úcatalogr   Úengine)Úselfs    ú6C:\Projects\FreeExile\tests\unit\test_weapon_system.pyÚsetUpzTestWeaponSystem.setUp'   s   € Ý.Ñ0Ô0ˆŒÝ"‘n”nˆŒˆˆó    c                 óZ  — |                       t          | j        ¦  «        d¦  «         t          D ]9}t	          |¦  «        }|                       t          |¦  «        dd|› d�¦  «         Œ:t
          D ]9}t          |¦  «        }|                       t          |¦  «        dd|› d�¦  «         Œ:dS )	zCCatalog must contain rich weapons covering all 5 sects and 5 clans.é   é   zSect z should have >= 3 weaponsé   zClan z should have >= 2 weaponsN)ÚassertGreaterEqualÚlenr   r   r   r   r   )r   ÚsectÚsect_weaponsÚclanÚclan_weaponss        r   Ú$test_catalog_coverage_and_uniquenessz5TestWeaponSystem.test_catalog_coverage_and_uniqueness+   sÌ   € à×Ò¥ D¤LÑ 1Ô 1°2Ñ6Ô6Ð6õ  ð 	cð 	cˆDÝ.¨tÑ4Ô4ˆLØ×#Ò#¥C¨Ñ$5Ô$5°qÐ:aÀ$Ð:aÐ:aÐ:aÑbÔbÐbÐbõ ð 	cð 	cˆDÝ.¨tÑ4Ô4ˆLØ×#Ò#¥C¨Ñ$5Ô$5°qÐ:aÀ$Ð:aÐ:aÐ:aÑbÔbÐbÐbð	cð 	cr   c                 óð   — | j         d         }ddddœ}|                      | j                             ||¦  «        ¦  «         ddddœ}|                      | j                             ||¦  «        ¦  «         dS )z?Should validate if character meets weapon attribute thresholds.ÚWPN_BLADE_2H_XICH_HUYETr   é2   ©Ú	cuong_theÚ	than_phapÚ	than_nieméx   N)r   ÚassertFalser   Úvalidate_requirementsÚ
assertTrue)r   Ú	blade_wpnÚ	low_statsÚqualified_statss       r   Ú!test_attribute_requirements_checkz2TestWeaponSystem.test_attribute_requirements_check9   sƒ   € ð ”LÐ!:Ô;ˆ	ð #%°2ÀBÐGÐGˆ	Ø×Ò˜œ×:Ò:¸9ÀiÑPÔPÑQÔQÐQð ),¸"È2ÐNÐNˆØ�Š˜œ×9Ò9¸)À_ÑUÔUÑVÔVÐVÐVÐVr   c                 ór  — | j         d         }t          |d¬¦  «        }ddddœ}| j                             ||t          j        ¦  «        }ddddœ}| j                             ||t          j        ¦  «        }|                      |j        |j        ¦  «         |                      |j        |j        ¦  «         dS )z@Attributes must scale physical and elemental damage accordingly.ÚWPN_SWORD_1H_COT_KIEMr   )ÚtemplateÚqualityr*   r+   é–   N)	r   r   r   Úcalculate_weapon_damager   Ú
ONE_HANDEDÚassertGreaterÚeffective_dpsÚfinal_crit_chance)r   ÚswordÚequippedÚ
base_statsÚbase_resÚhigh_agi_statsÚhigh_ress          r   Ú#test_damage_scaling_with_attributesz4TestWeaponSystem.test_damage_scaling_with_attributesF   sº   € à”Ð4Ô5ˆÝ!¨5¸"Ð=Ñ=Ô=ˆð $&°BÀRÐHÐHˆ
Ø”;×6Ò6°xÀÍYÔMaÑbÔbˆð (*¸È"ÐMÐMˆØ”;×6Ò6°xÀÕQZÔQeÑfÔfˆà×Ò˜8Ô1°8Ô3IÑJÔJÐJØ×Ò˜8Ô5°xÔ7QÑRÔRÐRÐRÐRr   c                 óš  — t          | j        d         ¬¦  «        }t          | j        d         ¬¦  «        }ddddœ}| j                             ||t          j        ¦  «        }| j                             ||t          j        |¬¦  «        }|                      |j        |j        d	z  d
¬¦  «         |                      |j	        d¦  «         dS )zDDual wielding granting +10% More Attack Speed and +15% Block Chance.r8   ©r9   ÚWPN_SWORD_1H_THANH_PHONGé<   éP   é(   r+   )Úoffhand_weapongš™™™™™ñ?r    )Úplacesg333333Ã?N)
r   r   r   r<   r   r=   ÚassertAlmostEqualÚeffective_attack_speedr!   Úbonus_block_chance)r   Ú
sword_mainÚ
dagger_offÚstatsÚ
single_resÚdual_ress         r   Útest_dual_wielding_mechanicz,TestWeaponSystem.test_dual_wielding_mechanicV   sÒ   € å#¨T¬\Ð:QÔ-RÐSÑSÔSˆ
Ý#¨T¬\Ð:TÔ-UÐVÑVÔVˆ
Ø ¨rÀÐCÐCˆð ”[×8Ò8¸ÀUÍIÔL`ÑaÔaˆ
ð ”;×6Ò6Ø˜�yÔ3ÀJð 7ñ 
ô 
ˆð 	×Ò˜xÔ>À
Ô@aÐdhÑ@hÐqrÐÑsÔsÐsØ×Ò Ô ;¸TÑBÔBÐBÐBÐBr   c                 ó4  — t          | j        d         ¬¦  «        }ddddœ}| j                             ||t          j        ¦  «        }|                      |j        ¦  «         |                      |j	        d¦  «         |                      |j
        d¦  «         d	S )
z?Two-Handed weapon grants +50% More Base Damage and wider reach.ÚWPN_CLUB_2H_HUYEN_THIETrI   éd   rM   é   r+   g       @gÍÌÌÌÌÌô?N)r   r   r   r<   r   Ú
TWO_HANDEDr2   Úis_two_handedr!   Úweapon_reach_metersÚstun_potency_multiplier)r   Úclub_2hrU   Úres_2hs       r   Útest_two_handed_heavy_potencyz.TestWeaponSystem.test_two_handed_heavy_potencyg   s’   € å ¨$¬,Ð7PÔ*QÐRÑRÔRˆØ!°ÀÐDÐDˆà”×4Ò4°W¸eÅYÔEYÑZÔZˆØ�Š˜Ô,Ñ-Ô-Ð-Ø×Ò Ô :¸CÑ@Ô@Ð@Ø×Ò Ô >ÀÑDÔDÐDÐDÐDr   c                 óv  — t          | j        d         ¬¦  «        }t          | j        d         ¬¦  «        }ddddœ}t          ||¬¦  «        }| j                             ||¦  «        }|                      |j        ¦  «         |                      |j        d	¦  «         |  	                    |j
        d
¦  «         dS )zAShield in offhand must grant block chance and armor/ward barrier.r8   rI   ÚWPN_SHIELD_HAC_BI_THUANrL   r*   r\   r+   )ÚmainhandÚoffhandg      Ð?r   N)r   r   r   r   Úevaluate_loadoutr2   Ú
has_shieldr!   Útotal_block_chancer>   Úbonus_armor)r   Úmain_weaponÚshieldrU   ÚloadoutÚeval_ress         r   Útest_shield_equipping_and_blockz0TestWeaponSystem.test_shield_equipping_and_blockq   s·   € å$¨d¬lÐ;RÔ.SÐTÑTÔTˆÝ¨¬Ð6OÔ)PÐQÑQÔQˆØ ¨rÀÐCÐCˆå"¨KÀÐHÑHÔHˆØ”;×/Ò/°¸Ñ?Ô?ˆà�Š˜Ô+Ñ,Ô,Ð,Ø×Ò Ô ;¸TÑBÔBÐBØ×Ò˜8Ô/°Ñ3Ô3Ð3Ð3Ð3r   c                 ó@  — | j         d         }t          |¬¦  «        }| j                             |t          j        t          j        ¬¦  «        }|                      |j	        d¦  «         |  
                    |j        ¦  «         |  
                    |j        ¦  «         | j                             |t          j        t          j        ¬¦  «        }|                      |j        ¦  «         |                      |j        ¦  «         |                      |j	        d¦  «         dS )z>Matching Sect and Clan grants thematic bonus damage and stats.rJ   rI   )Ú	char_sectÚ	char_clanç      ð?gffffffò?N)r   r   r   Úget_affinity_resonancer   ÚKIM_CANGr   ÚCRIMSON_BLOODÚassertEqualÚtotal_damage_multiplierr0   Úhas_sect_resonanceÚhas_clan_resonanceÚTHANH_PHONGÚGALE_PHANTOMr2   r>   )r   rA   rB   Úno_resÚfull_ress        r   Ú%test_sect_and_clan_affinity_resonancez6TestWeaponSystem.test_sect_and_clan_affinity_resonance~   s	  € à”Ð7Ô8ˆÝ!¨5Ð1Ñ1Ô1ˆð ”×3Ò3Ø¥Ô 4Å
Ô@Xð 4ñ 
ô 
ˆð 	×Ò˜Ô7¸Ñ=Ô=Ð=Ø×Ò˜Ô2Ñ3Ô3Ð3Ø×Ò˜Ô2Ñ3Ô3Ð3ð ”;×5Ò5Ø¥Ô 7Å:ÔCZð 6ñ 
ô 
ˆð 	�Š˜Ô3Ñ4Ô4Ð4Ø�Š˜Ô3Ñ4Ô4Ð4Ø×Ò˜8Ô;¸TÑBÔBÐBÐBÐBr   c                 ó|  — t          t          | j        d         ¬¦  «        ¬¦  «        }t          t          | j        d         ¬¦  «        ¬¦  «        }| j                             d||t
          j        ¬¦  «        }|                      |j        ¦  «         |  	                    |j
        d¦  «         |  	                    |j        j        j        t          j        ¦  «         | j                             d||t
          j        ¬¦  «        }|                      |j        ¦  «         |  	                    |j
        d¦  «         dS )	z5Auto-swap finds matching weapon set instantly in 0ms.r8   rI   )rf   ÚWPN_BOW_2H_COT_TIENé   )Úcurrent_active_setÚweapon_set_1Úweapon_set_2Úrequired_categoryr    N)r   r   r   r   Úresolve_auto_swapr   ÚPROJECTILE_WEAPONr2   Úswappedrx   Únew_active_setÚselected_weaponr9   Úweapon_classr   Ú
RANGED_BOWÚSWORD)r   Ú	sword_setÚbow_setÚswap_resultÚ	swap_backs        r   Útest_zero_latency_auto_swapz,TestWeaponSystem.test_zero_latency_auto_swap“   s:  € å$Ý#¨T¬\Ð:QÔ-RÐSÑSÔSð
ñ 
ô 
ˆ	õ #Ý#¨T¬\Ð:OÔ-PÐQÑQÔQð
ñ 
ô 
ˆð
 ”k×3Ò3Ø Ø"Ø Ý,Ô>ð	 4ñ 
ô 
ˆð 	�Š˜Ô+Ñ,Ô,Ð,Ø×Ò˜Ô3°QÑ7Ô7Ð7Ø×Ò˜Ô4Ô=ÔJÍKÔLbÑcÔcÐcð ”K×1Ò1Ø Ø"Ø Ý,Ô2ð	 2ñ 
ô 
ˆ	ð 	�Š˜	Ô)Ñ*Ô*Ð*Ø×Ò˜Ô1°1Ñ5Ô5Ð5Ð5Ð5r   c                 óè   — | j         d         }|                      |j        ¦  «         |                      |j        j        t
          j        ¦  «         |                      |j        j        d¦  «         dS )zCEach weapon base template must carry an appropriate implicit affix.r‚   rt   N)	r   ÚassertIsNotNoneÚimplicit_modrx   Ústatr	   ÚADDITIONAL_PIERCEr!   Úvalue)r   Úbows     r   Ú"test_weapon_implicit_affix_appliedz3TestWeaponSystem.test_weapon_implicit_affix_applied²   sh   € àŒlÐ0Ô1ˆØ×Ò˜SÔ-Ñ.Ô.Ð.Ø×Ò˜Ô)Ô.Õ0BÔ0TÑUÔUÐUØ×Ò Ô 0Ô 6¸Ñ<Ô<Ð<Ð<Ð<r   N)Ú__name__Ú
__module__Ú__qualname__r   r'   r6   rG   rX   rc   rp   r€   r”   rœ   © r   r   r   r   &   s¼   € € € € € ð%ð %ð %ðcð cð cðWð Wð WðSð Sð Sð Cð Cð Cð"Eð Eð Eð4ð 4ð 4ðCð Cð Cð*6ð 6ð 6ð>=ð =ð =ð =ð =r   r   Ú__main__))Ú__doc__ÚbuiltinsÚ@py_builtinsÚ_pytest.assertion.rewriteÚ	assertionÚrewriteÚ
@pytest_arÚunittestÚsysÚosÚpathÚinsertÚabspathÚjoinÚdirnameÚ__file__Úserver.world.martial_typesr   r   r   Úserver.world.weapon_typesr   r   r   r	   r
   r   r   r   r   r   Úserver.world.weapon_catalogr   r   r   Úserver.world.weapon_enginer   ÚTestCaser   r�   Úmainr    r   r   ú<module>r¸      s­  ððð ð € € € € € € € € € € € € €€€€Ø 
€
€
€
Ø 	€	€	€	à „‡‚��2”7—?’? 2¤7§<¢<°´·²ÀÑ0IÔ0IÈ>Ñ#ZÔ#ZÑ[Ô[Ñ \Ô \Ð \à PÐ PÐ PÐ PÐ PÐ PÐ PÐ PÐ PÐ Pðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð jÐ iÐ iÐ iÐ iÐ iÐ iÐ iÐ iÐ iØ 3Ð 3Ð 3Ð 3Ð 3Ð 3ðQ=ð Q=ð Q=ð Q=ð Q=�xÔ(ñ Q=ô Q=ð Q=ðh ˆzÒÐØ€H„M�O„O€O€O€Oð Ðr   