§
    |ÙÀj{H  ã                  óª   — d Z ddl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mZmZmZmZmZmZmZmZmZ ddlmZ g d¢Z G d„ d	¦  «        Zddd„ZdS )a|  
Quest and Milestone Authoritative Engine for FreeExile.
Implements:
1. Normal Quests (Main and Side Quests).
2. Hidden Quests (Triggered by cryptic environmental & combat criteria).
3. High-Tier / Epic Quests (Endgame Bosses, Keystones, Astral Challenges).
4. Milestone Progression and Tiered Rewards with Anti-Double Claim Protection.
5. Zero-Trust Server Authority validation.
é    )ÚannotationsN)ÚDictÚListÚOptionalÚSetÚTupleÚAny)Ú	QuestTypeÚQuestStatusÚObjectiveTypeÚHiddenTriggerTypeÚ
RewardItemÚQuestRewardÚObjectiveStateÚHiddenTriggerÚQuestDefinitionÚPlayerQuestProgressÚMilestoneTier)Ú(register_canonical_quests_and_milestones)ÚQuestEngineÚcreate_default_quest_enginer
   r   r   r   r   r   r   r   r   r   r   c                  ó  — e Zd ZdRd„ZdSd„ZdTd„ZdUd„ZdVd„ZdWd„ZdXd„Z	dYdZd„Z
d[d„Zd\d„Zd]d!„Zd^d#„Z	 dYd_d*„Zd`d-„Z	 dadbd4„Zdadcd7„Zdaddd9„Zded;„Zdfd=„Zdadgd?„ZdhdA„ZdadidB„ZdadidC„ZdadjdE„ZdkdH„ZdldJ„ZdadmdL„ZdndN„ZdodP„ZdpdQ„Z dS )qr   ÚreturnÚNonec                óZ   — i | _         i | _        i | _        i | _        i | _        d | _        d S ©N)Ú_quest_registryÚ_milestone_registryÚ_player_questsÚ_player_milestonesÚ_player_levelsÚ_story_engine©Úselfs    ú2C:\Projects\FreeExile\server\world\quest_engine.pyÚ__init__zQuestEngine.__init__0   s8   € Ø;=ˆÔØ=?ˆÔ àIKˆÔà79ˆÔØ.0ˆÔØ,0ˆÔÐÐó    Ústory_enginer	   c                ó   — || _         d S r   ©r"   )r$   r(   s     r%   Úattach_story_enginezQuestEngine.attach_story_engine:   s   € Ø)ˆÔÐÐr'   úOptional[Any]c                ó   — | j         S r   r*   r#   s    r%   Úget_story_enginezQuestEngine.get_story_engine=   s   € ØÔ!Ð!r'   Ú	quest_defr   c                ó$   — || j         |j        <   d S r   )r   Úquest_id)r$   r/   s     r%   Úregister_questzQuestEngine.register_quest@   s   € Ø3<ˆÔ˜YÔ/Ñ0Ð0Ð0r'   Ú	milestoner   c                ó$   — || j         |j        <   d S r   )r   Úmilestone_id)r$   r3   s     r%   Úregister_milestonezQuestEngine.register_milestoneC   s   € Ø;DˆÔ  Ô!7Ñ8Ð8Ð8r'   r1   ÚstrúOptional[QuestDefinition]c                ó6   — | j                              |¦  «        S r   )r   Úget)r$   r1   s     r%   Úget_quest_definitionz QuestEngine.get_quest_definitionF   s   € ØÔ#×'Ò'¨Ñ1Ô1Ð1r'   r5   úOptional[MilestoneTier]c                ó6   — | j                              |¦  «        S r   )r   r:   )r$   r5   s     r%   Úget_milestonezQuestEngine.get_milestoneI   s   € ØÔ'×+Ò+¨LÑ9Ô9Ð9r'   NÚ	player_idÚplayer_levelúOptional[int]c                ó°   — || j         vr
i | j         |<   || j        vrt          ¦   «         | j        |<   |�|| j        |<   d S || j        vrd| j        |<   d S d S ©Né   )r   r    Úsetr!   )r$   r?   r@   s      r%   Úinitialize_playerzQuestEngine.initialize_playerL   s~   € Ø˜DÔ/Ð/Ð/Ø-/ˆDÔ 	Ñ*Ø˜DÔ3Ð3Ð3Ý14±´ˆDÔ# IÑ.ØÐ#Ø-9ˆDÔ 	Ñ*Ð*Ð*Ø˜dÔ1Ð1Ð1Ø-.ˆDÔ 	Ñ*Ð*Ð*ð 2Ð1r'   úOptional[PlayerQuestProgress]c                ó^   — | j                              |i ¦  «                             |¦  «        S r   )r   r:   )r$   r?   r1   s      r%   Úget_player_questzQuestEngine.get_player_questV   s)   € ØÔ"×&Ò& y°"Ñ5Ô5×9Ò9¸(ÑCÔCÐCr'   úList[PlayerQuestProgress]c                ót   — | j                              |i ¦  «        }d„ |                     ¦   «         D ¦   «         S )Nc                ó<   — g | ]}|j         t          j        k    ¯|‘ŒS © )Ústatusr   ÚIN_PROGRESS)Ú.0Úqs     r%   ú
<listcomp>z1QuestEngine.get_active_quests.<locals>.<listcomp>[   s'   € ÐWÐWÐW�a°1´8½{Ô?VÒ3VÐ3V�Ð3VÐ3VÐ3Vr'   )r   r:   Úvalues)r$   r?   Úplayer_dicts      r%   Úget_active_questszQuestEngine.get_active_questsY   s:   € ØÔ)×-Ò-¨i¸Ñ<Ô<ˆØWÐW˜;×-Ò-Ñ/Ô/ÐWÑWÔWÐWr'   ÚintúList[QuestDefinition]c                ó$  — |                       ||¦  «         g }| j                             |i ¦  «        }| j                             ¦   «         D ]Â}|j        t          j        k    rŒ||j        k     rŒ$|j	        |v r8||j	                 j
        }|t          j        t          j        t          j        fv rŒed}|j        D ]<}|                     |¦  «        }	|	r|	j
        t          j        t          j        fvrd} nŒ=|r|                     |¦  «         ŒÃ|S )z[Returns quests that the player can accept, excluding hidden and in-progress/completed ones.TF)rF   r   r:   r   rS   Ú
quest_typer
   ÚHIDDENÚrequired_levelr1   rN   r   rO   Ú	COMPLETEDÚCLAIMEDÚprerequisite_quest_idsÚappend)
r$   r?   r@   Ú	availablerT   r/   rN   Úprereqs_metÚ	prereq_idÚprereq_progresss
             r%   Úget_available_questsz QuestEngine.get_available_quests]   s2  € à×Ò˜y¨,Ñ7Ô7Ð7Ø+-ˆ	ØÔ)×-Ò-¨i¸Ñ<Ô<ˆàÔ-×4Ò4Ñ6Ô6ð 	,ð 	,ˆIØÔ#¥yÔ'7Ò7Ð7ØØ˜iÔ6Ò6Ð6ØàÔ! [Ð0Ð0Ø$ YÔ%7Ô8Ô?�Ø�kÔ5µ{Ô7LÍkÔNaÐbÐbÐbØàˆKØ&Ô=ð ð �	Ø"-§/¢/°)Ñ"<Ô"<�Ø&ð ¨/Ô*@ÍÔI^Õ`kÔ`sÐHtÐ*tÐ*tØ"'�KØ�Eð +uð ð ,Ø× Ò  Ñ+Ô+Ð+øàÐr'   Úboolc                óB  — |                       ||¦  «         |                      |¦  «        }|r|j        t          j        k    rdS ||j        k     rdS | j        |         }||v r4||         j        }|t          j	        t          j
        t          j        fv rdS |j        D ];}|                     |¦  «        }|r|j        t          j
        t          j        fvr dS Œ<d„ |j        D ¦   «         }	t          ||t          j	        |	t!          j        ¦   «         ¬¦  «        }
|
||<   dS )z=Validates prerequisites and activates a quest for the player.Fc                ó   — i | ]
}|j         |“ŒS rM   ©Úobjective_id©rP   Úobjs     r%   ú
<dictcomp>z,QuestEngine.accept_quest.<locals>.<dictcomp>�   s   € ÐIÐIÐI¨S�3Ô# SÐIÐIÐIr'   ©r?   r1   rN   Ú
objectivesÚ
started_atT)rF   r;   rY   r
   rZ   r[   r   rN   r   rO   r\   r]   r^   r:   rn   r   Útime)r$   r?   r1   r@   r/   rT   rN   rb   rc   Úobj_mapÚprogresss              r%   Úaccept_questzQuestEngine.accept_questz   sG  € à×Ò˜y¨,Ñ7Ô7Ð7Ø×-Ò-¨hÑ7Ô7ˆ	Øð 	˜IÔ0µIÔ4DÒDÐDØ�5à˜)Ô2Ò2Ð2Ø�5àÔ)¨)Ô4ˆØ�{Ð"Ð"Ø  Ô*Ô1ˆFØ�+Ô1µ;Ô3HÍ+ÔJ]Ð^Ð^Ð^Ø�uà"Ô9ð 	ð 	ˆIØ)Ÿošo¨iÑ8Ô8ˆOØ"ð  oÔ&<Å[ÔEZÕ\gÔ\oÐDpÐ&pÐ&pØ�u�uð 'qð JÐI°IÔ4HÐIÑIÔIˆÝ&ØØÝÔ*ØÝ”y‘{”{ð
ñ 
ô 
ˆð !)ˆ�HÑØˆtr'   Útrigger_typer   ÚcontextúOptional[Dict[str, Any]]ÚkwargsúOptional[str]c           	     ó  — |                       |¦  «         | j        |         }| j                             |d¦  «        }t	          |pi ¦  «        }|                     |¦  «         |}| j                             ¦   «         D �]}|j        t          j
        k    rŒ|j        r|j        j        |k    rŒ1||j        k     rŒ=|j        |v r8||j                 j        }	|	t           j        t           j        t           j        fv rŒ~|j        }
|t(          j        k    rS|                     d¦  «        }|                     dd¦  «        }|
j        r||
j        k    rŒÓ|
j        �||
j        k    rŒæ�nÅ|t(          j        k    r~|                     d¦  «        }|                     d¦  «        p)|                     d¦  «        p|                     d¦  «        }|
j        r||
j        k    r�Œ`|
j        r||
j        k    r�Œt�n7|t(          j        k    r*|                     d¦  «        }|
j        r||
j        k    r�Œ¯ný|t(          j        k    r|                     d	d
¦  «        s�ŒØnÔ|t(          j        k    rO|
j        r |                     d¦  «        |
j        k    r�Œ|
j        r |                     d¦  «        |
j        k    r�Œ7nu|t(          j        k    re|                     d¦  «        p|                     d¦  «        }|
j        r||
j        k    r�Œ†|
j        r |                     d¦  «        |
j        k    r�Œ­d„ |j        D ¦   «         }t?          ||j        t           j        |tA          j         ¦   «         ¬¦  «        }|||j        <   |j        c S dS )zLEvaluates cryptic environmental and combat triggers to unlock hidden quests.rD   ÚzoneÚ
hp_percentg      ð?NÚitem_idÚrequired_item_idÚoffered_itemÚelement_streakFc                ó   — i | ]
}|j         |“ŒS rM   rh   rj   s     r%   rl   z4QuestEngine.trigger_hidden_quest.<locals>.<dictcomp>à   s   € ÐMÐMÐM°�sÔ'¨ÐMÐMÐMr'   rm   )!rF   r   r!   r:   ÚdictÚupdater   rS   rY   r
   rZ   Úhidden_triggerrt   r[   r1   rN   r   rO   r\   r]   r   ÚEVASION_NEAR_DEATHÚrequired_zoneÚrequired_hp_percentÚRELIC_OFFERINGr}   ÚSECRET_ALTAR_INTERACTIONÚFIVE_ELEMENTS_STREAKÚNPC_DIALOGUE_CHOICEÚNPC_GIFT_OFFERINGrn   r   rp   )r$   r?   rt   ru   rw   rT   r@   Úmerged_contextr/   rN   Útriggerrz   r{   r|   rq   rr   s                   r%   Útrigger_hidden_questz QuestEngine.trigger_hidden_questš   s©  € ð 	×Ò˜yÑ)Ô)Ð)ØÔ)¨)Ô4ˆØÔ*×.Ò.¨y¸!Ñ<Ô<ˆå˜g˜m¨Ñ,Ô,ˆØ×Ò˜fÑ%Ô%Ð%Ø ˆàÔ-×4Ò4Ñ6Ô6ð ?	&ñ ?	&ˆIØÔ#¥yÔ'7Ò7Ð7ØàÔ+ð ¨yÔ/GÔ/TÐXdÒ/dÐ/dØà˜iÔ6Ò6Ð6ØàÔ! [Ð0Ð0Ø$ YÔ%7Ô8Ô?�Ø�kÔ5µ{Ô7LÍkÔNaÐbÐbÐbØàÔ.ˆGØÕ0ÔCÒCÐCØ—{’{ 6Ñ*Ô*�Ø$Ÿ[š[¨°sÑ;Ô;�
ØÔ(ð ¨T°WÔ5JÒ-JÐ-JØØÔ.Ð:¸zÈGÔLgÒ?gÐ?gØùàÕ!2Ô!AÒAÐAØ—{’{ 6Ñ*Ô*�Ø!Ÿ+š+ iÑ0Ô0Ðr°G·K²KÐ@RÑ4SÔ4SÐrÐW^×WbÒWbÐcqÑWrÔWr�ØÔ(ð ¨T°WÔ5JÒ-JÐ-JÙØÔ+ð °¸7Ô;SÒ0SÐ0SÙùàÕ!2Ô!KÒKÐKØ—{’{ 6Ñ*Ô*�ØÔ(ð ¨T°WÔ5JÒ-JÐ-JÙøàÕ!2Ô!GÒGÐGØ—{’{Ð#3°UÑ;Ô;ð Ùðð Õ!2Ô!FÒFÐFØÔ(ð ¨W¯[ª[¸Ñ-@Ô-@ÀGÔDYÒ-YÐ-YÙØÔ+ð °·²¸IÑ0FÔ0FÈ'ÔJbÒ0bÐ0bÙøàÕ!2Ô!DÒDÐDØ!Ÿ+š+ iÑ0Ô0ÐO°G·K²KÀÑ4OÔ4O�ØÔ+ð °¸7Ô;SÒ0SÐ0SÙØÔ(ð ¨W¯[ª[¸Ñ-@Ô-@ÀGÔDYÒ-YÐ-YÙàMÐM¸	Ô8LÐMÑMÔMˆGÝ*Ø#Ø"Ô+Ý"Ô.Ø"Ýœ9™;œ;ðñ ô ˆHð /7ˆK˜	Ô*Ñ+ØÔ%Ð%Ð%Ð%àˆtr'   Ú
obj_targetÚinput_targetc                ó†   ‡— ||k    rdS |dk    r1d}|                      ¦   «         Št          ˆfd„|D ¦   «         ¦  «        S dS )NTÚmob_trash_bone_hound)ÚbatÚhoundu   cáº©uu   dÆ¡iu	   khÃ´ lÃ¢uÚskeletonÚraptorÚ	hellhoundÚmob_starter_batÚmob_starter_houndÚmob_starter_skeletonÚmob_corrupted_raptorÚmob_feral_hellhoundÚmob_skeleton_warriorc              3  ó    •K  — | ]}|‰v V — Œ	d S r   rM   )rP   ÚtokÚlows     €r%   ú	<genexpr>z/QuestEngine._is_target_match.<locals>.<genexpr>÷   s'   øè è € Ð<Ð< c�s˜c�zÐ<Ð<Ð<Ð<Ð<Ð<r'   F)ÚlowerÚany)r$   r�   r�   Ústarter_tokensr    s       @r%   Ú_is_target_matchzQuestEngine._is_target_matchí   sa   ø€ Ø˜Ò%Ð%Ø�4ØÐ/Ò/Ð/ðˆNð
 ×$Ò$Ñ&Ô&ˆCÝÐ<Ð<Ð<Ð<¨^Ð<Ñ<Ô<Ñ<Ô<Ð<Øˆur'   rD   Úobj_typer   Ú	target_idÚamountú	List[str]c                ó  — g }| j                              |i ¦  «        }|                     ¦   «         D �]R}|j        t          j        k    rŒd}|j                             ¦   «         D ]\  }	}
|
j        |k    ro|  	                    |
j
        |¦  «        rT|
j        sM|t          j        k    r|
                     |¦  «        |j        |	<   n|
                     |¦  «        |j        |	<   d}Œ€|rœt!          d„ |j                             ¦   «         D ¦   «         ¦  «        }|rPt          j        |_        t%          j        ¦   «         |_        | j        r | j                             ||j        ¦  «         |                     |j        ¦  «         �ŒT|S )zRInternal helper to increment progress on matching objectives across active quests.FTc              3  ó$   K  — | ]}|j         V — Œd S r   )Úis_completed)rP   Úos     r%   r¡   z1QuestEngine._update_objectives.<locals>.<genexpr>  s$   è è € ÐZÐZ°!˜qœ~ÐZÐZÐZÐZÐZÐZr'   )r   r:   rS   rN   r   rO   rn   Úitemsr¦   r¥   r§   r¬   r   ÚCLEAR_FOG_PERCENTÚwith_gauge_valueÚwith_incrementÚallr\   rp   Úcompleted_atr"   Úon_quest_completedr1   r_   )r$   r?   r¦   r§   r¨   Úupdated_quest_idsrT   Úquest_progressÚquest_updatedÚobj_idrk   Úall_dones               r%   Ú_update_objectiveszQuestEngine._update_objectivesú   s•  € ð (*ÐØÔ)×-Ò-¨i¸Ñ<Ô<ˆà)×0Ò0Ñ2Ô2ð 	Bñ 	BˆNØÔ$­Ô(?Ò?Ð?Øà!ˆMØ-Ô8×>Ò>Ñ@Ô@ð -ð -‘�˜Ø”< 8Ò+Ð+°×0EÒ0EÀcÄmÐU^Ñ0_Ô0_Ð+ØÔ+ð -Ø#¥}Ô'FÒFÐFØ@C×@TÒ@TÐU[Ñ@\Ô@\˜NÔ5°fÑ=Ð=à@C×@RÒ@RÐSYÑ@ZÔ@Z˜NÔ5°fÑ=Ø(,˜øàð BÝÐZÐZ°~Ô7P×7WÒ7WÑ7YÔ7YÐZÑZÔZÑZÔZ�Øð bÝ,7Ô,A�NÔ)Ý26´)±+´+�NÔ/ØÔ)ð bØÔ*×=Ò=¸iÈÔI`ÑaÔaÐaØ!×(Ò(¨Ô)@ÑAÔAÐAùà Ð r'   Ú
monster_idÚcountc                óF   — |                       |t          j        ||¦  «        S r   )rº   r   ÚKILL_MONSTER)r$   r?   r»   r¼   s       r%   Úrecord_killzQuestEngine.record_kill  s    € Ø×&Ò& yµ-Ô2LÈjÐZ_Ñ`Ô`Ð`r'   r|   c                óF   — |                       |t          j        ||¦  «        S r   )rº   r   Ú
CRAFT_ITEM)r$   r?   r|   r¼   s       r%   Úrecord_craftzQuestEngine.record_craft!  s    € Ø×&Ò& yµ-Ô2JÈGÐUZÑ[Ô[Ð[r'   Úlocation_idc                óF   — |                       |t          j        |d¦  «        S rC   )rº   r   ÚDISCOVER_LOCATION)r$   r?   rÃ   s      r%   Úrecord_discoveryzQuestEngine.record_discovery$  ó!   € Ø×&Ò& yµ-Ô2QÐS^Ð`aÑbÔbÐbr'   Úacupoint_idc                óF   — |                       |t          j        |d¦  «        S rC   )rº   r   ÚACTIVATE_MERIDIAN)r$   r?   rÈ   s      r%   Úrecord_meridian_unlockz"QuestEngine.record_meridian_unlock'  rÇ   r'   Ú
action_keyc                óF   — |                       |t          j        ||¦  «        S r   )rº   r   ÚPERFORM_ACTION)r$   r?   rÌ   r¼   s       r%   Úrecord_actionzQuestEngine.record_action*  s!   € Ø×&Ò& yµ-Ô2NÐPZÐ\aÑbÔbÐbr'   Únpc_idc                óF   — |                       |t          j        |d¦  «        S rC   )rº   r   ÚTALK_NPC)r$   r?   rÐ   s      r%   Úrecord_talk_npczQuestEngine.record_talk_npc-  s    € Ø×&Ò& yµ-Ô2HÈ&ÐRSÑTÔTÐTr'   c                óF   — |                       |t          j        ||¦  «        S r   )rº   r   ÚDELIVER_TO_NPC©r$   r?   rÐ   r¼   s       r%   Úrecord_deliver_npczQuestEngine.record_deliver_npc0  s!   € Ø×&Ò& yµ-Ô2NÐPVÐX]Ñ^Ô^Ð^r'   c                ó0   — |                       |||¦  «        S r   )r×   rÖ   s       r%   Úrecord_deliver_to_npcz!QuestEngine.record_deliver_to_npc3  s   € Ø×&Ò& y°&¸%Ñ@Ô@Ð@r'   Útarget_room_idc                óF   — |                       |t          j        ||¦  «        S r   )rº   r   ÚEXPLORE_MAP_ROOMS)r$   r?   rÚ   r¼   s       r%   Úrecord_room_explorationz#QuestEngine.record_room_exploration6  s!   € Ø×&Ò& yµ-Ô2QÐSaÐchÑiÔiÐir'   Úzone_or_map_idÚpercentc                óF   — |                       |t          j        ||¦  «        S r   )rº   r   r¯   )r$   r?   rÞ   rß   s       r%   Úrecord_fog_clearancez QuestEngine.record_fog_clearance9  s!   € Ø×&Ò& yµ-Ô2QÐSaÐcjÑkÔkÐkr'   Úgate_target_idc                óF   — |                       |t          j        |d¦  «        S rC   )rº   r   ÚBREACH_BOSS_GATE)r$   r?   râ   s      r%   Úrecord_boss_gate_breachz#QuestEngine.record_boss_gate_breach<  s!   € Ø×&Ò& yµ-Ô2PÐR`ÐbcÑdÔdÐdr'   Úobstacle_target_idc                óF   — |                       |t          j        ||¦  «        S r   )rº   r   ÚDESTROY_OBSTACLES)r$   r?   ræ   r¼   s       r%   Úrecord_obstacle_destructionz'QuestEngine.record_obstacle_destruction?  s!   € Ø×&Ò& yµ-Ô2QÐSeÐglÑmÔmÐmr'   ú'Tuple[bool, Optional[QuestReward], str]c                ó°  — |                       |¦  «         | j        |         }|                     |¦  «        }|sdS |j        t          j        k    rdS |j        t          j        k    rdS |                      |¦  «        }|sdS t          j        |_        t          j        ¦   «         |_	        | j
        r| j
                             ||¦  «         d|j        dfS )zPClaims reward for completed quest. Guarantees idempotency and anti-double claim.)FNuC   Nhiá»‡m vá»¥ khÃ´ng tá»“n táº¡i trong tiáº¿n trÃ¬nh ngÆ°á»�i chÆ¡i!)FNu=   Pháº§n thÆ°á»Ÿng nhiá»‡m vá»¥ nÃ y Ä‘Ã£ nháº­n trÆ°á»›c Ä‘Ã³!)FNu,   Nhiá»‡m vá»¥ chÆ°a hoÃ n thÃ nh má»¥c tiÃªu!)FNu/   KhÃ´ng tÃ¬m tháº¥y Ä‘á»‹nh nghÄ©a nhiá»‡m vá»¥!Tu+   Nháº­n thÆ°á»Ÿng nhiá»‡m vá»¥ thÃ nh cÃ´ng!)rF   r   r:   rN   r   r]   r\   r;   rp   Ú
claimed_atr"   r´   Úreward)r$   r?   r1   rT   r¶   r/   s         r%   Úclaim_quest_rewardzQuestEngine.claim_quest_rewardB  sâ   € à×Ò˜yÑ)Ô)Ð)ØÔ)¨)Ô4ˆØ$Ÿš¨Ñ2Ô2ˆàð 	fØeÐeØÔ ¥KÔ$7Ò7Ð7Ø_Ð_ØÔ ¥KÔ$9Ò9Ð9ØNÐNà×-Ò-¨hÑ7Ô7ˆ	Øð 	RØQÐQå +Ô 3ˆÔÝ$(¤I¡K¤KˆÔ!ØÔð 	GØÔ×1Ò1°)¸XÑFÔFÐFØ�YÔ%Ð'TÐTÐTr'   úDict[str, Any]c                ó¶  — |                       |¦  «         | j                             |i ¦  «        }| j                             |t	          ¦   «         ¦  «        }d}d}d}|                     ¦   «         D ]v\  }}|j        t          j        t          j	        fv rR|  
                    |¦  «        }	|	sŒ<|dz  }|	j        t          j        k    r|dz  }Œ\|	j        t          j        k    r|dz  }Œwg }
| j                             ¦   «         D ]@\  }}||v rŒ
||j        k    r+||j        k    r ||j        k    r|
                     |¦  «         ŒA||||t)          |¦  «        |
dœS )zJCalculates completed quests statistics and identifies eligible milestones.r   rD   )r?   Útotal_completedÚhidden_completedÚhigh_tier_completedÚclaimed_milestonesÚeligible_milestones)rF   r   r:   r    rE   r®   rN   r   r\   r]   r;   rY   r
   rZ   Ú	HIGH_TIERr   Úrequired_total_completedÚrequired_hidden_completedÚrequired_high_tier_completedr_   Úlist)r$   r?   rT   rô   rñ   rò   ró   Úq_idÚq_progr/   rõ   Úms_idÚmss                r%   Úget_player_milestone_statusz'QuestEngine.get_player_milestone_statusY  s™  € à×Ò˜yÑ)Ô)Ð)ØÔ)×-Ò-¨i¸Ñ<Ô<ˆØ!Ô4×8Ò8¸ÅCÁEÄEÑJÔJÐàˆØÐØÐà'×-Ò-Ñ/Ô/ð 		-ð 		-‰LˆD�&ØŒ}¥Ô!6½Ô8KÐ LÐLÐLØ ×5Ò5°dÑ;Ô;�	Ø ð ØØ 1Ñ$�ØÔ'­9Ô+;Ò;Ð;Ø$¨Ñ)Ð$Ð$ØÔ)­YÔ-@Ò@Ð@Ø'¨1Ñ,Ð'øà)+ÐØÔ1×7Ò7Ñ9Ô9ð 	2ð 	2‰IˆE�2ØÐ*Ð*Ð*Øà 2Ô#>Ò>Ð>Ø$¨Ô(DÒDÐDØ'¨2Ô+JÒJÐJà#×*Ò*¨5Ñ1Ô1Ð1øð #Ø.Ø 0Ø#6Ý"&Ð'9Ñ":Ô":Ø#6ð
ð 
ð 	
r'   c                óH  — |                       |¦  «         |                      |¦  «        }|sdS | j        |         }||v rdS |                      |¦  «        }||d         vrdS |                     |¦  «         | j        r| j                             ||¦  «         d|j        dfS )zNClaims reward for a qualified milestone tier. Guarantees anti-double claiming.)FNu5   KhÃ´ng tÃ¬m tháº¥y thÃ´ng tin má»‘c pháº§n thÆ°á»Ÿng!)FNu6   Má»‘c pháº§n thÆ°á»Ÿng nÃ y Ä‘Ã£ nháº­n trÆ°á»›c Ä‘Ã³!rõ   )FNu<   ChÆ°a Ä‘áº¡t Ä‘iá»�u kiá»‡n má»‘c hoÃ n thÃ nh nhiá»‡m vá»¥!Tu+   Nháº­n pháº§n thÆ°á»Ÿng má»‘c thÃ nh cÃ´ng!)rF   r>   r    rÿ   Úaddr"   r´   rí   )r$   r?   r5   r3   Úclaimed_setrN   s         r%   Úclaim_milestone_rewardz"QuestEngine.claim_milestone_reward‚  sÊ   € ð 	×Ò˜yÑ)Ô)Ð)Ø×&Ò& |Ñ4Ô4ˆ	Øð 	XØWÐWàÔ-¨iÔ8ˆØ˜;Ð&Ð&ØXÐXà×1Ò1°)Ñ<Ô<ˆØ˜vÐ&;Ô<Ð<Ð<Ø^Ð^à�Š˜Ñ%Ô%Ð%ØÔð 	KØÔ×1Ò1°)¸\ÑJÔJÐJØ�YÔ%Ð'TÐTÐTr'   )r   r   )r(   r	   r   r   )r   r,   )r/   r   r   r   )r3   r   r   r   )r1   r7   r   r8   )r5   r7   r   r<   r   )r?   r7   r@   rA   r   r   )r?   r7   r1   r7   r   rG   )r?   r7   r   rJ   )r?   r7   r@   rV   r   rW   )r?   r7   r1   r7   r@   rV   r   re   )
r?   r7   rt   r   ru   rv   rw   r	   r   rx   )r�   r7   r�   r7   r   re   )rD   )
r?   r7   r¦   r   r§   r7   r¨   rV   r   r©   )r?   r7   r»   r7   r¼   rV   r   r©   )r?   r7   r|   r7   r¼   rV   r   r©   )r?   r7   rÃ   r7   r   r©   )r?   r7   rÈ   r7   r   r©   )r?   r7   rÌ   r7   r¼   rV   r   r©   )r?   r7   rÐ   r7   r   r©   )r?   r7   rÐ   r7   r¼   rV   r   r©   )r?   r7   rÚ   r7   r¼   rV   r   r©   )r?   r7   rÞ   r7   rß   rV   r   r©   )r?   r7   râ   r7   r   r©   )r?   r7   ræ   r7   r¼   rV   r   r©   )r?   r7   r1   r7   r   rê   )r?   r7   r   rï   )r?   r7   r5   r7   r   rê   )!Ú__name__Ú
__module__Ú__qualname__r&   r+   r.   r2   r6   r;   r>   rF   rI   rU   rd   rs   rŽ   r¥   rº   r¿   rÂ   rÆ   rË   rÏ   rÓ   r×   rÙ   rÝ   rá   rå   ré   rî   rÿ   r  rM   r'   r%   r   r   /   sþ  € € € € € ð1ð 1ð 1ð 1ð*ð *ð *ð *ð"ð "ð "ð "ð=ð =ð =ð =ðEð Eð Eð Eð2ð 2ð 2ð 2ð:ð :ð :ð :ð/ð /ð /ð /ð /ðDð Dð Dð DðXð Xð Xð Xðð ð ð ð:ð ð ð ðH -1ð	Qð Qð Qð Qð Qðfð ð ð ð$ ð"!ð "!ð "!ð "!ð "!ðHað að að að að\ð \ð \ð \ð \ðcð cð cð cðcð cð cð cðcð cð cð cð cðUð Uð Uð Uð_ð _ð _ð _ð _ðAð Að Að Að Aðjð jð jð jð jðlð lð lð lðeð eð eð eðnð nð nð nð nðUð Uð Uð Uð.'
ð '
ð '
ð '
ðRUð Uð Uð Uð Uð Ur'   r   TÚattach_storylinere   r   c                ó²   — t          ¦   «         }t          |¦  «         | r7	 ddlm}  |¦   «         }|                     |¦  «         n# t
          $ r Y nw xY w|S )zXFactory creating a QuestEngine populated with canonical FreeExile quests and milestones.r   )Úcreate_default_storyline_engine)r   r   Úserver.world.storyline_enginer	  r+   Ú	Exception)r  Úenginer	  r(   s       r%   r   r   ™  s‚   € å‰]Œ]€FÝ,¨VÑ4Ô4Ð4Øð ð	ØUÐUÐUÐUÐUÐUØ:Ð:Ñ<Ô<ˆLØ×&Ò& |Ñ4Ô4Ð4Ð4øÝð 	ð 	ð 	ØˆDð	øøøà€Ms   ¡%A Á
AÁA)T)r  re   r   r   )Ú__doc__Ú
__future__r   rp   Útypingr   r   r   r   r   r	   Úserver.world.quest_typesr
   r   r   r   r   r   r   r   r   r   r   Úserver.world.quest_catalogr   Ú__all__r   r   rM   r'   r%   ú<module>r     s`  ððð ð #Ð "Ð "Ð "Ð "Ð "Ø €€€Ø 8Ð 8Ð 8Ð 8Ð 8Ð 8Ð 8Ð 8Ð 8Ð 8Ð 8Ð 8Ð 8Ð 8Ð 8Ð 8ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð PÐ OÐ OÐ OÐ OÐ Oðð ð €ð"gUð gUð gUð gUð gUñ gUô gUð gUðTð ð ð ð ð ð r'   