§
    T¹»j,  ã                   óÀ   — d Z ddlZddlmc mZ ddlZddlm	Z	m
Z
mZmZmZmZ ddlmZmZ ddlmZmZ  G d„ dej        ¦  «        Zedk    r ej        ¦   «          dS dS )	z¸
Unit tests for 15-Tier Item Affix Matrix (T1 to T15) and Exponential Crafting Currency & Gold Sinks.
Verifies iLvl gating, tier range rolling, gold fee scaling, and high-tier rarity.
é    N)ÚItemSlotÚ
ItemRarityÚ	AffixTypeÚAffixModÚPrimalCurrencyTypeÚCraftingItem)Úget_available_affixesÚCANONICAL_AFFIX_DEFINITIONS)ÚItemCraftingEngineÚcalculate_crafting_gold_feec                   óN   — e Zd Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd	„Z	dd
„Z
dS )ÚTestItemCrafting15TiersÚreturnNc                 ó,   — t          ¦   «         | _        d S ©N)r   Úengine)Úselfs    ú?C:\Projects\FreeExile\tests\unit\test_item_crafting_15_tiers.pyÚsetUpzTestItemCrafting15Tiers.setUp   s   € Ý(Ñ*Ô*ˆŒˆˆó    c           	      óì   — d„ t           D ¦   «         }|                      t          |¦  «        dd¦  «         d„ |D ¦   «         }|                      |t          t	          dd¦  «        ¦  «        d¦  «         dS )	z:Catalog must define T1 through T15 for core stat families.c                 óF   — g | ]}|j                              d ¦  «        ¯|‘ŒS ©Úpref_phys_pct_t)Úmod_idÚ
startswith©Ú.0Úas     r   ú
<listcomp>z[TestItemCrafting15Tiers.test_catalog_contains_15_tiers_for_core_affixes.<locals>.<listcomp>   s.   € ÐiÐiÐi˜aÀ!Ä(×BUÒBUÐVgÑBhÔBhÐi˜ÐiÐiÐir   é   z8Physical damage % must have exactly 15 tiers (T1 to T15)c                 ó   — h | ]	}|j         ’Œ
S © )Útierr   s     r   ú	<setcomp>zZTestItemCrafting15Tiers.test_catalog_contains_15_tiers_for_core_affixes.<locals>.<setcomp>"   s   € Ð.Ð.Ð.˜A�”Ð.Ð.Ð.r   é   é   z!Tiers must span 1 to 15 inclusiveN)r
   ÚassertEqualÚlenÚsetÚrange)r   Úphys_affixesÚtierss      r   Ú/test_catalog_contains_15_tiers_for_core_affixeszGTestItemCrafting15Tiers.test_catalog_contains_15_tiers_for_core_affixes   sy   € àiÐiÕ#>ÐiÑiÔiˆØ×Ò�˜\Ñ*Ô*¨BÐ0jÑkÔkÐkà.Ð. Ð.Ñ.Ô.ˆØ×Ò˜¥¥E¨!¨R¡L¤LÑ 1Ô 1Ð3VÑWÔWÐWÐWÐWr   c                 óª  — t          d„ t          D ¦   «         ¦  «        }t          d„ t          D ¦   «         ¦  «        }|                      |j        d¦  «         |                      |j        d¦  «         |                      |j        |j        ¦  «         |                      |j        |j        ¦  «         |                      |j	        |j	        ¦  «         dS )zKT1 requires high iLvl (85+) and has superior min/max stats compared to T15.c              3   ó0   K  — | ]}|j         d k    ¯|V — ŒdS )Úpref_phys_pct_t1N©r   r   s     r   ú	<genexpr>zeTestItemCrafting15Tiers.test_tier_1_requires_high_item_level_and_has_highest_stats.<locals>.<genexpr>'   s/   è è € Ð[Ð[˜¸A¼HÐHZÒ<ZÐ<Z�!Ð<ZÐ<ZÐ<ZÐ<ZÐ[Ð[r   c              3   ó0   K  — | ]}|j         d k    ¯|V — ŒdS )Úpref_phys_pct_t15Nr2   r   s     r   r3   zeTestItemCrafting15Tiers.test_tier_1_requires_high_item_level_and_has_highest_stats.<locals>.<genexpr>(   s/   è è € Ð]Ð]˜¸Q¼XÐI\Ò=\Ð=\�1Ð=\Ð=\Ð=\Ð=\Ð]Ð]r   éU   r&   N)
Únextr
   ÚassertGreaterEqualÚrequired_ilvlr(   ÚassertGreaterÚmin_valÚmax_valÚ
assertLessÚweight)r   Út1Út15s      r   Ú:test_tier_1_requires_high_item_level_and_has_highest_statszRTestItemCrafting15Tiers.test_tier_1_requires_high_item_level_and_has_highest_stats%   sÄ   € åÐ[Ð[Õ8Ð[Ñ[Ô[Ñ[Ô[ˆÝÐ]Ð]Õ9Ð]Ñ]Ô]Ñ]Ô]ˆà×Ò Ô 0°"Ñ5Ô5Ð5Ø×Ò˜Ô*¨AÑ.Ô.Ð.ð 	×Ò˜2œ: s¤{Ñ3Ô3Ð3Ø×Ò˜2œ: s¤{Ñ3Ô3Ð3ð 	�Š˜œ	 3¤:Ñ.Ô.Ð.Ð.Ð.r   c                 ó   — t          t          j        t          j        d¬¦  «        }d„ |D ¦   «         }|                      d|d¦  «         |                      d|d¦  «         |                      t          d„ |D ¦   «         ¦  «        d	¦  «         d
S )zFAn item with iLvl 15 can only roll low tiers (e.g. T14-T15), never T1.r!   ©Ú
item_levelc                 óP   — h | ]#}|j                              d ¦  «        ¯|j        ’Œ$S r   )r   r   r$   r   s     r   r%   zRTestItemCrafting15Tiers.test_low_ilvl_item_cannot_roll_t1_affix.<locals>.<setcomp>7   s0   € Ð_Ð_Ð_ a¸¼×8KÒ8KÐL]Ñ8^Ô8^Ð_˜1œ6Ð_Ð_Ð_r   r&   ziLvl 15 weapon must not roll T1é   ziLvl 15 weapon must not roll T2c              3   ó"   K  — | ]
}|d k    V — ŒdS )é   Nr#   )r   Úts     r   r3   zRTestItemCrafting15Tiers.test_low_ilvl_item_cannot_roll_t1_affix.<locals>.<genexpr>;   s&   è è € Ð=Ð=¨˜A šGÐ=Ð=Ð=Ð=Ð=Ð=r   z&Only lowest tiers eligible for iLvl 15N)r	   r   Ú	WEAPON_1Hr   ÚPREFIXÚassertNotInÚ
assertTrueÚall)r   Ú	availableÚavailable_tierss      r   Ú'test_low_ilvl_item_cannot_roll_t1_affixz?TestItemCrafting15Tiers.test_low_ilvl_item_cannot_roll_t1_affix4   s”   € å)­(Ô*<½iÔ>NÐ[]Ð^Ñ^Ô^ˆ	Ø_Ð_¨9Ð_Ñ_Ô_ˆà×Ò˜˜OÐ-NÑOÔOÐOØ×Ò˜˜OÐ-NÑOÔOÐOØ�Š�Ð=Ð=¨_Ð=Ñ=Ô=Ñ=Ô=Ð?gÑhÔhÐhÐhÐhr   c                 óf  ‡— t          ddt          j        dt          j        ¬¦  «        }| j                             |t          j        d¬¦  «        }|  	                    |j
        ¦  «         |                      t          |j        j        ¦  «        t          |j        j        ¦  «        z   d¦  «         |j        j        |j        j        z   D ]eŠt!          ˆfd„t"          D ¦   «         d	¦  «        }|r@|                      ‰j        |j        ¦  «         |                      ‰j        |j        ¦  «         Œfd	S )
zYWhen an affix rolls, the value must fall strictly within [min_val, max_val] of that tier.Úweapon_god_baseu   Huyáº¿t áº¢nh TÃ  Ä�aoéX   ©Ú	item_uuidÚ	base_nameÚslotrD   ÚrarityéPÃ  ©ÚitemÚcurrencyÚplayer_goldr   c              3   ó<   •K  — | ]}|j         ‰j         k    ¯|V — Œd S r   )Úmod_name)r   r   Úmods     €r   r3   zlTestItemCrafting15Tiers.test_high_ilvl_item_rolls_value_strictly_within_chosen_tier_range.<locals>.<genexpr>P   s3   øè è € Ð fÐ f qÈ1Ì:ÐY\ÔYeÒKeÐKe ÐKeÐKeÐKeÐKeÐ fÐ fr   N)r   r   rJ   r   ÚNORMALr   Úapply_primal_currencyr   ÚHAC_SO_THACHrM   Úsuccessr:   r)   r\   ÚprefixesÚsuffixesr7   r
   r8   Úvaluer;   ÚassertLessEqualr<   )r   r\   ÚresÚmatching_defra   s       @r   ÚAtest_high_ilvl_item_rolls_value_strictly_within_chosen_tier_rangezYTestItemCrafting15Tiers.test_high_ilvl_item_rolls_value_strictly_within_chosen_tier_range=   s3  ø€ åØ'Ø.ÝÔ#ØÝÔ$ð
ñ 
ô 
ˆð Œk×/Ò/ØÝ'Ô4Øð 0ñ 
ô 
ˆð
 	�Š˜œÑ$Ô$Ð$Ø×Ò�3˜sœxÔ0Ñ1Ô1µC¸¼Ô8IÑ4JÔ4JÑJÈAÑNÔNÐNà”8Ô$ s¤xÔ'8Ñ8ð 	Fð 	FˆCÝÐ fÐ fÐ fÐ fÕ,GÐ fÑ fÔ fÐhlÑmÔmˆLØð FØ×'Ò'¨¬	°<Ô3GÑHÔHÐHØ×$Ò$ S¤Y°Ô0DÑEÔEÐEøð		Fð 	Fr   c                 ó¦   — t          t          j        d¬¦  «        }t          t          j        d¬¦  «        }|                      ||dz  d¦  «         dS )zJCrafting fee scales with item level to increase gold sink on endgame gear.é   rC   éV   é   z8High iLvl crafting gold fee must be substantially higherN)r   r   ÚHUYET_HON_THACHr:   )r   Úfee_lowÚfee_highs      r   Ú;test_crafting_gold_fee_scales_exponentially_with_item_levelzSTestItemCrafting15Tiers.test_crafting_gold_fee_scales_exponentially_with_item_levelU   sS   € å-Õ.@Ô.PÐ]_Ð`Ñ`Ô`ˆÝ.Õ/AÔ/QÐ^`ÐaÑaÔaˆà×Ò˜8 W¨q¡[Ð2lÑmÔmÐmÐmÐmr   c                 ó  — t          ddt          j        dt          j        ¬¦  «        }| j                             |t          j        d¬¦  «        }|  	                    |j
        ¦  «         |                      d|j        ¦  «         dS )	z@Crafting requires gold fee; fails if player lacks required gold.Úexpensive_baseu   Cá»• Kiáº¿m Tháº§n Mar6   rU   é   r[   ÚINSUFFICIENT_GOLD_FEEN)r   r   rJ   r   ÚRAREr   rc   r   rq   ÚassertFalsere   ÚassertInÚmessage)r   r\   rj   s      r   Ú6test_crafting_rejected_if_player_has_insufficient_goldzNTestItemCrafting15Tiers.test_crafting_rejected_if_player_has_insufficient_gold\   s‰   € åØ&Ø-ÝÔ#ØÝ”?ð
ñ 
ô 
ˆð Œk×/Ò/ØÝ'Ô7Øð 0ñ 
ô 
ˆð
 	×Ò˜œÑ%Ô%Ð%Ø�ŠÐ-¨s¬{Ñ;Ô;Ð;Ð;Ð;r   c                 ó’  — t          ddt          j        dt          j        ¬¦  «        }t          d„ t          D ¦   «         ¦  «        }|j                             t          |j
        |j        t          j        d|j        |j        |j        ¬¦  «        ¦  «         | j                             |t$          j        d¬	¦  «        }|                      |j        ¦  «         |j        j        d
         }|                      |j        dd¦  «         |                      |j        |j        ¦  «         |                      |j        |j        ¦  «         dS )u^   Tinh Hoa Huyáº¿t Tháº¡ch (Divine) rerolls values strictly within the existing tier boundaries.Útest_divine_itemu   Cá»‘t KhÃ´ir6   rU   c              3   ó0   K  — | ]}|j         d k    ¯|V — ŒdS )Úpref_life_t1Nr2   r   s     r   r3   zPTestItemCrafting15Tiers.test_divine_rerolls_within_tier_range.<locals>.<genexpr>y   s/   è è € Ð`Ð` ÀQÄXÐQ_ÒE_ÐE_˜1ÐE_ÐE_ÐE_ÐE_Ð`Ð`r   r&   )r   r`   Úmod_typer$   rh   Útier_minÚtier_maxrZ   r[   r   zDivine must preserve TierN)r   r   ÚHELMETr   ry   r7   r
   rf   Úappendr   r   r`   r   rK   r;   r<   r   rc   r   ÚTINH_HOA_HUYET_THACHrM   re   r\   r(   r$   r8   rh   ri   )r   r\   Út1_life_defrj   Údivined_mods        r   Ú%test_divine_rerolls_within_tier_rangez=TestItemCrafting15Tiers.test_divine_rerolls_within_tier_rangeo   sD  € åØ(Ø#Ý”ØÝ”?ð
ñ 
ô 
ˆõ Ð`Ð`Õ&AÐ`Ñ`Ô`Ñ`Ô`ˆØŒ×ÒÝØ"Ô)Ø$Ô-Ý"Ô)ØØ!Ô)Ø$Ô,Ø$Ô,ðñ ô ñ
	
ô 
	
ð 
	
ð Œk×/Ò/ØÝ'Ô<Øð 0ñ 
ô 
ˆð
 	�Š˜œÑ$Ô$Ð$Ø”hÔ'¨Ô*ˆØ×Ò˜Ô)¨1Ð.IÑJÔJÐJØ×Ò Ô 1°;Ô3FÑGÔGÐGØ×Ò˜[Ô.°Ô0CÑDÔDÐDÐDÐDr   )r   N)Ú__name__Ú
__module__Ú__qualname__r   r.   rA   rQ   rl   rt   r}   rŠ   r#   r   r   r   r      sÊ   € € € € € ð+ð +ð +ð +ðXð Xð Xð Xð/ð /ð /ð /ðið ið ið iðFð Fð Fð Fð0nð nð nð nð<ð <ð <ð <ð& Eð  Eð  Eð  Eð  Eð  Er   r   Ú__main__)Ú__doc__ÚbuiltinsÚ@py_builtinsÚ_pytest.assertion.rewriteÚ	assertionÚrewriteÚ
@pytest_arÚunittestÚ server.world.item_crafting_typesr   r   r   r   r   r   Úserver.world.item_affix_catalogr	   r
   Ú!server.world.item_crafting_enginer   r   ÚTestCaser   r‹   Úmainr#   r   r   ú<module>rœ      s8  ððð ð
 € € € € € € € € € € € € €€€€ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ðð ð ð ð ð ð ð ðð ð ð ð ð ð ð ðvEð vEð vEð vEð vE˜hÔ/ñ vEô vEð vEðr ˆzÒÐØ€H„M�O„O€O€O€Oð Ðr   