§
    r»jŽ6  ã                   ó&  — d Z ddlZddlZ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mZmZmZmZmZmZmZ ej        defd„¦   «         Z ej        defd	„¦   «         Z!ej        defd
„¦   «         Z" G d„ d¦  «        Z#dS )uõ  
Unit Test Suite for FreeExile Server-Authoritative NPC, Dialogue & Map-Quest Interconnection System.
Theme: Cá»” VÃ• HOANG DÃƒ & Háº®C Ã�M LÆ¯U Ä�Ã€Y (Grimdark Savage Primal Exile ARPG - 100% PoE2 Spirit).

Validates:
1. Feral NPC registration, spatial indexing, and zone querying.
2. Anti-cheat distance validation (Euclidean threshold gating).
3. Dynamic branching dialogue trees with survival and level gating.
4. Seamless integration with QuestEngine (Talk NPC, Deliver to NPC, quest acceptance, reward claiming).
5. Dynamic NPC dialogue adaptation based on player quest progression.
6. Hidden quest serendipity triggers via dialogue choices / blood offerings.
7. Seamless integration with ZoneEngine (Outcast Camp, Bone-Cliff Chasm, Secret Chambers).
é    N)ÚDictÚAnyÚList)
ÚQuestEngineÚ	QuestTypeÚQuestStatusÚObjectiveTypeÚHiddenTriggerTypeÚObjectiveStateÚ
RewardItemÚQuestRewardÚHiddenTriggerÚQuestDefinition)Ú
ZoneEngineÚZoneTypeÚZoneEnvironment)Ú	NpcEngineÚNpcRoleÚNpcServiceTypeÚNpcDialogueChoiceÚNpcDialogueNodeÚNpcDialogueTreeÚNpcDefinitionÚcreate_canonical_npc_engineÚreturnc                  óü  — t          ¦   «         } |                      t          dddt          j        dg t          ddt          j        dd¬¦  «        gt          d	t          d
dd¦  «        gd¬¦  «        ¬¦  «        ¦  «         |                      t          dddt          j        dg t          ddt          j
        dd¬¦  «        gt          dt          ddd¦  «        gd¬¦  «        ¬¦  «        ¦  «         |                      t          dddt          j        dg t          ddt          j        dd¬¦  «        gt          dt          d d!d¦  «        gd¬¦  «        t          t          j        d"¬#¦  «        ¬$¦	  «	        ¦  «         | S )%NÚquest_intro_doc_cou"   Sinh Tá»“n NÆ¡i Vá»±c TÃ¡ng Kiáº¿muj   TÃ¬m gáº·p LÃ£o Ä�á»™c Cá»‘t táº¡i Vá»±c TÃ¡ng Kiáº¿m Ä‘á»ƒ Ä‘oáº¡t láº¥y thanh tÃ  Ä‘ao máº» sá»‘ng sÃ³t.é   Úobj_talk_doc_cou$   Ä�Ã m Ä‘áº¡o vá»›i LÃ£o Ä�á»™c Cá»‘tÚnpc_doc_co_tan_kiem)Úobjective_idÚdescriptionÚobj_typeÚ	target_idÚtarget_counti,  Úcurrency_primordial_stoneu   Háº¯c SÆ¡ Tháº¡ché   )ÚexpÚspirit_stonesÚmeridian_points)Úquest_idÚtitler"   Ú
quest_typeÚrequired_levelÚprerequisite_quest_idsÚ
objectivesÚrewardÚquest_deliver_ancient_wineu   Hiáº¿n Táº¿ Huyáº¿t Tá»­uul   Ä�em Há»—n NguyÃªn Tá»­u dÃ¢ng cho Cuá»“ng NhÃ¢n BÃ£o CÃ¡t táº¡i VÃ´ Ä�á»‹nh BÃ£o CÃ¡t Ä‘á»ƒ má»Ÿ Ä‘Æ°á»�ng.é   Úobj_deliver_wineu4   Giao Há»—n NguyÃªn Tá»­u cho Cuá»“ng NhÃ¢n BÃ£o CÃ¡tÚnpc_sa_mac_du_thaniè  Úcurrency_blood_soul_stoneu   Huyáº¿t Há»“n Tháº¡chÚhidden_ancient_sword_secretu   TÃ n SÃ¡t Di TÃ­ch Cá»• MauW   Ká»³ duyÃªn Ä‘Ã m Ä‘áº¡o vá»›i LÃ£o Ä�á»™c Cá»‘t hÃ© lá»™ há»‘ chÃ´n tÃ n binh Cá»• Ma.Úobj_uncover_secretu   KhÃ¡m phÃ¡ há»‘ chÃ´n tÃ n binhÚloc_ancient_steleiÄ	  Ú currency_blood_reflection_mirroru   Huyáº¿t áº¢nh Cá»• KÃ­nhu8   Ä�Ã m luáº­n bÃ­ máº­t tÃ n sÃ¡t vá»›i LÃ£o Ä�á»™c Cá»‘t)Útrigger_typer"   )	r+   r,   r"   r-   r.   r/   r0   r1   Úhidden_trigger)r   Úregister_questr   r   ÚNORMALr   r	   ÚTALK_NPCr   r   ÚDELIVER_TO_NPCÚHIDDENÚDISCOVER_LOCATIONr   r
   ÚNPC_DIALOGUE_CHOICE)Úengines    ú3C:\Projects\FreeExile\tests\unit\test_npc_system.pyÚquest_enginerF   ,   s   € å‰]Œ]€Fð ×ÒÝØ)Ø6ð EÝ Ô'ØØ#%åØ!2Ø FÝ*Ô3Ø3Ø!"ðñ ô ðõ ØÝ)Ð*EÐGZÐ\]Ñ^Ô^Ð_Ø !ðñ ô ð!	
ñ 	
ô 	
ñô ð ð4 ×ÒÝØ1Ø-ð GÝ Ô'ØØ#%åØ!3Ø VÝ*Ô9Ø2Ø!"ðñ ô ðõ ØÝ)Ð*EÐG^Ð`aÑbÔbÐcØ !ðñ ô ð!	
ñ 	
ô 	
ñô ð ð4 ×ÒÝØ2Ø.ØqÝ Ô'ØØ#%åØ!5Ø AÝ*Ô<Ø1Ø!"ðñ ô ðõ ØÝ)Ð*LÐNhÐjkÑlÔlÐmØ !ðñ ô õ
 )Ý.ÔBØVðñ ô ð+	
ñ 	
ô 	
ñô ð ð: €Mó    c                  ó   — t          ¦   «         S ©N)r   © rG   rE   Úzone_enginerK   …   s   € å‰<Œ<ÐrG   c                  ó   — t          ¦   «         S rI   )r   rJ   rG   rE   Ú
npc_enginerM   Š   s   € å&Ñ(Ô(Ð(rG   c                   ó¢   — e Zd Zdeddfd„Zdeddfd„Zdeddfd„Zdededdfd„Zdededdfd	„Z	dededdfd
„Z
dededdfd„Zdededdfd„ZdS )ÚTestNpcSystemrM   r   Nc                 óò   — |                      d¦  «        }t          |¦  «        dk    sJ ‚d„ |D ¦   «         }d|v sJ ‚d|v sJ ‚d|v sJ ‚|                     dddd¬	¦  «        }t          |¦  «        d
k    sJ ‚dS )uS   Kiá»ƒm tra Ä‘Äƒng kÃ½ NPC hoang dÃ£ vÃ  truy váº¥n danh sÃ¡ch NPC theo báº£n Ä‘á»“.Úzone_boundless_sanctuaryé   c                 ó   — h | ]	}|j         ’Œ
S rJ   )Únpc_id)Ú.0Únpcs     rE   ú	<setcomp>zHTestNpcSystem.test_npc_registration_and_zone_querying.<locals>.<setcomp>•   s   € Ð8Ð8Ð8 #�3”:Ð8Ð8Ð8rG   Únpc_bach_hieu_sinhÚnpc_van_gioi_thuong_nhanÚnpc_thiet_tuong_au_da_tug        ç      I@)Úradiusr   N)Úget_npcs_in_zoneÚlenÚget_nearby_npcs)ÚselfrM   Úsanctuary_npcsÚnpc_idsÚnearbys        rE   Ú'test_npc_registration_and_zone_queryingz5TestNpcSystem.test_npc_registration_and_zone_querying�   s¬   € à#×4Ò4Ð5OÑPÔPˆÝ�>Ñ"Ô" aÒ'Ð'Ð'Ð'à8Ð8¨Ð8Ñ8Ô8ˆØ# wÐ.Ð.Ð.Ð.Ø)¨WÐ4Ð4Ð4Ð4Ø)¨WÐ4Ð4Ð4Ð4ð ×+Ò+Ð,FÈÈSÐY]Ð+Ñ^Ô^ˆÝ�6‰{Œ{˜QŠˆˆˆˆˆrG   c                 ó¸  — |                      d¦  «        }|€J ‚|j        dk    sJ ‚|                     ||j        dz   |j        dz   ¦  «        du sJ ‚|                     ||j        dz   |j        ¦  «        du sJ ‚|                     d	dd
|j        |j        d¬¦  «        \  }}}}|du sJ ‚d|                     ¦   «         v sd|                     ¦   «         v sJ ‚dS dS )uV   Kiá»ƒm tra cÆ¡ cháº¿ Server-Authoritative chá»‘ng gian láº­n tá»�a Ä‘á»™ tÆ°Æ¡ng tÃ¡c.r    Nu   LÃ£o Ä�á»™c Cá»‘tg       @g      ð?Tr[   FÚ	player_01rQ   r   ©Ú	player_idrT   Úzone_idÚplayer_xÚplayer_yÚplayer_levelu   báº£n Ä‘á»“Úzone)Úget_npcÚnameÚvalidate_interaction_distanceÚxÚyÚinteract_with_npcÚlower)r`   rM   rV   ÚsuccessÚmsgÚnodeÚ_s          rE   Ú#test_anticheat_proximity_validationz1TestNpcSystem.test_anticheat_proximity_validationž   s  € à× Ò Ð!6Ñ7Ô7ˆØˆˆˆØŒxÐ.Ò.Ð.Ð.Ð.ð ×7Ò7¸¸S¼UÀS¹[È#Ì%ÐRUÉ+ÑVÔVÐZ^Ð^Ð^Ð^Ð^ð ×7Ò7¸¸S¼UÀT¹\È3Ì5ÑQÔQÐUZÐZÐZÐZÐZð !+× <Ò <Ø!Ø(Ø.Ø”UØ”UØð !=ñ !
ô !
Ñˆ��d˜Að ˜%ÐÐÐÐØ §	¢	¡¤Ð+Ð+¨v¸¿º¹¼Ð/DÐ/DÐ/DÐDÐ+Ð+Ð/DÐ/DrG   c                 ó–  — |                      d¦  «        }|€J ‚|                     d|j        |j        |j        |j        d¬¦  «        \  }}}}|du sJ ‚|€J ‚t          |j        ¦  «        dk    sJ ‚|j        d         }|                     d|j        |j	        |j
        ¬¦  «        \  }}	}
}}|du sJ ‚|
€J ‚|
j	        |j        k    sJ ‚dS )	uK   Kiá»ƒm tra luá»“ng há»™i thoáº¡i phÃ¢n nhÃ¡nh sinh tá»“n vÃ  chuyá»ƒn node.r    Nrf   r   rg   Tr   )rh   rT   Úcurrent_node_idÚ	choice_id)rn   rs   rT   ri   rq   rr   r^   ÚchoicesÚselect_dialogue_choiceÚnode_idr|   Útarget_node_id)r`   rM   rV   ru   rv   Úinitial_noderx   Úfirst_choiceÚokÚ
choice_msgÚ	next_nodeÚserviceÚpayloads                rE   Útest_branching_dialogue_flowz*TestNpcSystem.test_branching_dialogue_flow¶   s  € à× Ò Ð!6Ñ7Ô7ˆØˆˆˆð )3×(DÒ(DØ!Ø”:Ø”KØ”UØ”UØð )Eñ )
ô )
Ñ%ˆ��l Að ˜$ˆˆˆˆØÐ'Ð'Ð'Ý�<Ô'Ñ(Ô(¨1Ò,Ð,Ð,Ð,ð $Ô+¨AÔ.ˆØ6@×6WÒ6WØ!Ø”:Ø(Ô0Ø"Ô,ð	 7Xñ 7
ô 7
Ñ3ˆˆJ˜	 7¨Gð �TˆzˆzˆzˆzØÐ$Ð$Ð$ØÔ  LÔ$?Ò?Ð?Ð?Ð?Ð?Ð?rG   rF   c           	      ó
  — d}|                      |d¬¦  «         |                     |dd¬¦  «        }|du sJ ‚|                     |d¦  «        }|€J ‚|j        d         j        du sJ ‚|                     d	¦  «        }|€J ‚|                     ||j        |j        |j	        |j
        d|¬
¦  «        \  }}}}|du sJ ‚|                     |d¦  «        }	|	€J ‚|	j        d         j        du sJ ‚|	j        t          j        k    sJ ‚dS )uC   Kiá»ƒm tra NPC cáº­p nháº­t má»¥c tiÃªu TALK_NPC trong QuestEngine.Úplayer_swordsmanr   ©rl   r   TNr   Fr    ©rh   rT   ri   rj   rk   rl   rF   )Úinitialize_playerÚaccept_questÚget_player_questr0   Úis_completedrn   rs   rT   ri   rq   rr   Ústatusr   Ú	COMPLETED)
r`   rM   rF   rh   ÚacceptedÚprog_beforerV   ru   rx   Ú
prog_afters
             rE   Ú)test_npc_quest_interaction_talk_objectivez7TestNpcSystem.test_npc_quest_interaction_talk_objectiveÔ   s\  € ð 'ˆ	Ø×&Ò& y¸qÐ&ÑAÔAÐAð  ×,Ò,¨YÐ8LÐ[\Ð,Ñ]Ô]ˆØ˜4ÐÐÐÐà"×3Ò3°IÐ?SÑTÔTˆØÐ&Ð&Ð&ØÔ%Ð&7Ô8ÔEÈÐNÐNÐNÐNð × Ò Ð!6Ñ7Ô7ˆØˆˆˆà%×7Ò7ØØ”:Ø”KØ”UØ”UØØ%ð 8ñ 
ô 
Ñˆ��A�qð ˜$ˆˆˆˆð "×2Ò2°9Ð>RÑSÔSˆ
ØÐ%Ð%Ð%ØÔ$Ð%6Ô7ÔDÈÐLÐLÐLÐLØÔ ¥KÔ$9Ò9Ð9Ð9Ð9Ð9Ð9rG   c                 ót  — d}|                      |d¬¦  «         |                     |dd¬¦  «         |                     d¦  «        }|€J ‚|j        dk    sJ ‚|                     ||j        dd	|¬
¦  «        \  }}}|du sJ ‚d|v sJ ‚|                     |d¦  «        }|€J ‚|j        t          j	        k    sJ ‚dS )ue   Kiá»ƒm tra NPC tiáº¿p nháº­n váº­t pháº©m hiáº¿n táº¿ (DELIVER_TO_NPC) vÃ  hoÃ n thÃ nh nhiá»‡m vá»¥.Úplayer_travellerr3   r‹   r2   r5   Nõ   Cuá»“ng NhÃ¢n BÃ£o CÃ¡tÚitem_hon_nguyen_tuur   )rh   rT   Úitem_idÚcountrF   T)
r�   rŽ   rn   ro   Údeliver_item_to_npcrT   r�   r‘   r   r’   )	r`   rM   rF   rh   rV   rƒ   rv   Úupdated_questsÚprogresss	            rE   Ú%test_npc_quest_deliver_item_objectivez3TestNpcSystem.test_npc_quest_deliver_item_objectiveø   s  € ð 'ˆ	Ø×&Ò& y¸qÐ&ÑAÔAÐAØ×!Ò! )Ð-IÐXYÐ!ÑZÔZÐZà× Ò Ð!5Ñ6Ô6ˆØˆˆˆØŒxÐ4Ò4Ð4Ð4Ð4ð #-×"@Ò"@ØØ”:Ø)ØØ%ð #Añ #
ô #
ÑˆˆC�ð �TˆzˆzˆzˆzØ+¨~Ð=Ð=Ð=Ð=à×0Ò0°Ð<XÑYÔYˆØÐ#Ð#Ð#ØŒ¥+Ô"7Ò7Ð7Ð7Ð7Ð7Ð7rG   c           	      ó’  — d}|                      d¦  «        }|€J ‚|                     ||j        |j        |j        |j        d|¬¦  «        \  }}}}|€J ‚d|j        v sJ ‚|                     |dd¬¦  «         |                     ||j        |j        |j        |j        d|¬¦  «        \  }}}}|€J ‚d	|j        v sd
|j        v sJ ‚dS dS )us   Kiá»ƒm tra há»™i thoáº¡i cá»§a NPC tá»± Ä‘á»™ng biáº¿n chuyá»ƒn theo tráº¡ng thÃ¡i tiáº¿n Ä‘á»™ cá»§a nhiá»‡m vá»¥.Úplayer_adaptiver    Nr   rŒ   Únode_doc_co_intror   r‹   Ú	completedÚintro)rn   rs   rT   ri   rq   rr   r   rŽ   )r`   rM   rF   rh   rV   rx   Únode_initialÚnode_inprogresss           rE   Ú/test_npc_adaptive_dialogue_based_on_quest_statez=TestNpcSystem.test_npc_adaptive_dialogue_based_on_quest_state  s%  € ð &ˆ	Ø× Ò Ð!6Ñ7Ô7ˆØˆˆˆð !+× <Ò <ØØ”:Ø”KØ”UØ”UØØ%ð !=ñ !
ô !
Ñˆˆ1ˆl˜Að Ð'Ð'Ð'Ø" lÔ&:Ð:Ð:Ð:Ð:ð 	×!Ò! )Ð-AÐPQÐ!ÑRÔRÐRØ#-×#?Ò#?ØØ”:Ø”KØ”UØ”UØØ%ð $@ñ $
ô $
Ñ ˆˆ1ˆo˜qð Ð*Ð*Ð*Ø˜oÔ5Ð5Ð5¸ÀOÔD[Ð9[Ð9[Ð9[Ð[Ð5Ð5Ð9[Ð9[rG   c                 óô   — d}|                      d¦  «        }|€J ‚|                     ||j        dd|¬¦  «        \  }}}}}	|du sJ ‚|                     |d¦  «        }
|
€J ‚|
j        t
          j        k    sJ ‚dS )	ul   Kiá»ƒm tra kÃ­ch hoáº¡t ká»³ ngá»™ áº©n (Hidden Quest) qua Ä‘á»‘i thoáº¡i tÃ n sÃ¡t vá»›i LÃ£o Ä�á»™c Cá»‘t.Úplayer_destinyr    NÚnode_doc_co_martial_talkÚ#choice_inquire_ancient_sword_secret)rh   rT   r{   r|   rF   Tr7   )rn   r~   rT   r�   r‘   r   ÚIN_PROGRESS)r`   rM   rF   rh   rV   rƒ   rv   rw   r†   r‡   Úhidden_progs              rE   Ú4test_hidden_quest_serendipity_trigger_via_npc_choicezBTestNpcSystem.test_hidden_quest_serendipity_trigger_via_npc_choice6  s¯   € ð %ˆ	Ø× Ò Ð!6Ñ7Ô7ˆØˆˆˆð +5×*KÒ*KØØ”:Ø6Ø;Ø%ð +Lñ +
ô +
Ñ'ˆˆC��w ð �Tˆzˆzˆzˆzð #×3Ò3°IÐ?\Ñ]Ô]ˆØÐ&Ð&Ð&ØÔ!¥[Ô%<Ò<Ð<Ð<Ð<Ð<Ð<rG   rK   c                 ó  — |                      d¦  «        }|€J ‚|j        t          j        k    sJ ‚|                     d¦  «        }|€J ‚|j        dk    sJ ‚|j        dk    sJ ‚|j        t          j        j        k    sJ ‚dS )uf   Kiá»ƒm tra liÃªn káº¿t NPC vá»›i ZoneEngine vÃ  Ä‘iá»�u kiá»‡n mÃ´i trÆ°á»�ng khÃ­ tÆ°á»£ng bÃ£o cÃ¡t.Úzone_boundless_sandstormNr5   r™   )	Úget_zone_definitionÚenvironmentr   Ú	SANDSTORMrn   ro   ri   Úrequired_environmentÚvalue)r`   rM   rK   Úsandstorm_zoneÚ
npc_hermits        rE   Ú6test_map_zone_integration_and_environmental_conditionszDTestNpcSystem.test_map_zone_integration_and_environmental_conditionsM  s¤   € ð
 %×8Ò8Ð9SÑTÔTˆØÐ)Ð)Ð)ØÔ)­_Ô-FÒFÐFÐFÐFà×'Ò'Ð(<Ñ=Ô=ˆ
ØÐ%Ð%Ð%ØŒÐ";Ò;Ð;Ð;Ð;ØÔ!Ð%?Ò?Ð?Ð?Ð?ØÔ.µ/Ô2KÔ2QÒQÐQÐQÐQÐQÐQrG   )Ú__name__Ú
__module__Ú__qualname__r   rd   ry   rˆ   r   r–   r    r¨   r¯   r   r¹   rJ   rG   rE   rO   rO   �   su  € € € € € ðÀ)ð ÐPTð ð ð ð ðE¸ið EÈDð Eð Eð Eð Eð0@°yð @ÀTð @ð @ð @ð @ð<":Ø#ð":Ø3>ð":à	ð":ð ":ð ":ð ":ðH8Ø#ð8Ø3>ð8à	ð8ð 8ð 8ð 8ð6!\Ø#ð!\Ø3>ð!\à	ð!\ð !\ð !\ð !\ðF=Ø#ð=Ø3>ð=à	ð=ð =ð =ð =ð.RØ#ðRØ2<ðRà	ðRð Rð Rð Rð Rð RrG   rO   )$Ú__doc__ÚpytestÚtimeÚtypingr   r   r   Úserver.world.quest_enginer   r   r   r	   r
   r   r   r   r   r   Úserver.world.zone_enginer   r   r   Úserver.world.npc_enginer   r   r   r   r   r   r   r   ÚfixturerF   rK   rM   rO   rJ   rG   rE   ú<module>rÅ      s  ððð ð €€€Ø €€€Ø "Ð "Ð "Ð "Ð "Ð "Ð "Ð "Ð "Ð "ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð KÐ JÐ JÐ JÐ JÐ JÐ JÐ JÐ JÐ Jð	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð „ðU�kð Uð Uð Uñ „ðUðp „ð�Zð ð ð ñ „ðð „ð)�Ið )ð )ð )ñ „ð)ðKRð KRð KRð KRð KRñ KRô KRð KRð KRð KRrG   