§
    Å¿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	 ddl
mZmZmZ  G d„ d¦  «        ZdS )a7  
Authoritative PoE2-Style Hideout Town Portal Engine with Anti-Exploit Quarantine.

Manages dynamic 2-way town portal links bridging wilderness coordinates
to player hideouts and hubs, 6-portal map device charge tracking,
authoritative boss/secret chamber exploit quarantine, and death penalty portal handling.
é    )ÚannotationsN)ÚAnyÚDictÚOptionalÚTupleÚUnion)ÚPortalQuarantineStatusÚTownPortalLinkÚTownPortalResultc                  óz   — e Zd ZdZd-d„Z	 	 d.d/d„Zd0d„Z	 	 	 	 d1d2d„Zd3d4d „Zd5d"„Z		 d6d7d$„Z
	 d8d9d)„Z	 	 d:d;d,„Zd%S )<ÚTownPortalEnginezIAuthoritative PoE2 2-Way Town Portal Engine with Anti-Exploit Quarantine.ÚreturnÚNonec                óL   — i | _         i | _        i | _        i | _        d| _        d S )Nr   )ÚportalsÚmap_chargesÚboss_activeÚsecret_activeÚ_portal_counter)Úselfs    ú8C:\Projects\FreeExile\server\world\town_portal_engine.pyÚ__init__zTownPortalEngine.__init__   s/   € Ø24ˆŒØ+-ˆÔØ,.ˆÔØ.0ˆÔØ$%ˆÔÐÐó    FÚinstance_idÚstrr   Úboolr   c                ó.   — || j         |<   || j        |<   dS )zPRegister or update active boss combat and secret chamber states for an instance.N)r   r   )r   r   r   r   s       r   Úset_encounter_statez$TownPortalEngine.set_encounter_state   s$   € ð )4ˆÔ˜Ñ%Ø*7ˆÔ˜;Ñ'Ð'Ð'r   Úzone_idúTuple[bool, str]c                ó¤   — | j                              |d¦  «        rdS | j                             |d¦  «        s|                     d¦  «        rdS dS )zLPerform authoritative pre-flight quarantine check against active encounters.F)TuS   QUARANTINE_BOSS_ENGAGED: Cáº¥m má»Ÿ cá»•ng/trá»‘n thoÃ¡t khi Boss Ä‘ang giao tranh!Úzone_secret_)Tue   QUARANTINE_SECRET_CHAMBER: Máº­t tháº¥t Ä‘áº¿m ngÆ°á»£c Ä‘ang kÃ­ch hoáº¡t, khÃ´ng thá»ƒ má»Ÿ cá»•ng!)FÚUNLOCKED)r   Úgetr   Ú
startswith)r   r   r   s      r   Úcheck_quarantine_lockz&TownPortalEngine.check_quarantine_lock)   sh   € àÔ×Ò ¨UÑ3Ô3ð 	oØnÐnàÔ×!Ò! +¨uÑ5Ô5ð 	A¸×9KÒ9KÈNÑ9[Ô9[ð 	Að Að  Aà Ð r   Úinst_1ç        Úzone_player_hideoutÚ	player_idÚinstance_id_or_wxúUnion[str, float]ÚwxÚfloatÚwyÚhub_zoneÚkwargsr   r   c                ó¶  — t          |t          t          f¦  «        r|}t          |¦  «        }	d}
n-t          |¦  «        }
t          |¦  «        }	t          |¦  «        }|                      ||
¦  «        \  }}|rt          d|d¦  «        S | j                             ¦   «         D ]0}|j        |k    r#|j	        rt                               |dd¦  «         Œ1| xj        dz  c_        d|› dt          t          j        ¦   «         dz  ¦  «        › d| j        › �}t          ||||	||d	d	t          j        ¦   «         d
|
¬¦  «        }|| j        |<   t          d
d|¦  «        S )zNRequest creation of a 2-way town portal linking wilderness coordinates to hub.r'   FNÚ	is_activeé   Útp_Ú_iè  r(   T)Ú	portal_idÚowner_idÚwilderness_zone_idÚwilderness_xÚwilderness_yÚhub_zone_idÚhub_xÚhub_yÚ
created_atr3   r   ÚSUCCESS)Ú
isinstanceÚintr.   r   r&   r   r   Úvaluesr8   r3   ÚobjectÚ__setattr__r   Útimer
   )r   r*   r   r+   r-   r/   r0   r1   Ú	actual_wyÚ	actual_wxÚactual_instance_idÚ	is_lockedÚerrÚexisting_portalr7   Úportals                   r   Úrequest_town_portalz$TownPortalEngine.request_town_portal3   s„  € õ Ð'­#­u¨Ñ6Ô6ð 	"ØˆIÝÐ/Ñ0Ô0ˆIØ!)ÐÐå!$Ð%6Ñ!7Ô!7ÐÝ˜b™	œ	ˆIÝ˜b™	œ	ˆIð ×3Ò3°GÐ=OÑPÔP‰ˆ	�3Øð 	6Ý# E¨3°Ñ5Ô5Ð5ð  $œ|×2Ò2Ñ4Ô4ð 	Hð 	HˆOØÔ'¨9Ò4Ð4¸Ô9RÐ4Ý×"Ò" ?°KÀÑGÔGÐGøàÐÔ Ñ!ÐÔØV˜)ÐVÐV¥c­$¬)©+¬+¸Ñ*<Ñ&=Ô&=ÐVÐVÀÔ@TÐVÐVˆ	ÝØØØ&Ø"Ø"Ø ØØÝ”y‘{”{ØØ*ð
ñ 
ô 
ˆð #)ˆŒ�YÑÝ  i°Ñ;Ô;Ð;r   é   Úinitial_chargesrB   c                ó6   — t          d|¦  «        | j        |<   dS )zFInitialize 6 portal charges for an Endgame Astral Map Device instance.r   N)Úmaxr   )r   r   rP   s      r   Úregister_astral_map_devicez+TownPortalEngine.register_astral_map_deviced   s   € å(+¨A¨Ñ(?Ô(?ˆÔ˜Ñ%Ð%Ð%r   úTuple[bool, str, int]c                óp   — | j                              |d¦  «        }|dk    rdS |dz
  }|| j         |<   dd|fS )zLTraverse into an Endgame Map instance, atomically consuming 1 portal charge.r   )FuR   MAP_SEALED: Háº¿t lÆ°á»£t cá»•ng (0/6). Báº£n Ä‘á»“ Ä‘Ã£ phong tá»�a vÄ©nh viá»…n!r   r4   TÚENTER_SUCCESS)r   r$   )r   r   ÚchargesÚnew_chargess       r   Úenter_map_portalz!TownPortalEngine.enter_map_portalh   sL   € àÔ"×&Ò& {°AÑ6Ô6ˆØ�aŠ<ˆ<ØqÐqà ‘kˆØ(3ˆÔ˜Ñ%Ø�_ kÐ1Ð1r   Úis_map_instancec                óZ  — |rQ| j                              |d¦  «        }|dk    r|dz
  | j         |<   | j                              |d¦  «        }dd|› d�fS d}| j                             ¦   «         D ]5}|j        |k    r(|j        r!t                               |dd¦  «         |dz  }Œ6dd|› d	�fS )
zSApply PoE2 death penalty: wilderness closes portal; map instance consumes 1 charge.r   r4   Tu&   MAP_DEATH_CONSUMED_PORTAL: CÃ²n láº¡i u    lÆ°á»£tr3   FÚWILDERNESS_DEATH_CLOSED_Ú_PORTALS)r   r$   r   rC   r8   r3   rD   rE   )	r   r*   r   r   rZ   rW   Ú	remainingÚclosedÚps	            r   Úon_player_deathz TownPortalEngine.on_player_deathr   sß   € ð ð 	VØÔ&×*Ò*¨;¸Ñ:Ô:ˆGØ˜Š{ˆ{Ø07¸!±�Ô  Ñ-ØÔ(×,Ò,¨[¸!Ñ<Ô<ˆIØÐUÀ)ÐUÐUÐUÐUÐUð ˆØ”×$Ò$Ñ&Ô&ð 	ð 	ˆAØŒz˜YÒ&Ð&¨1¬;Ð&Ý×"Ò" 1 k°5Ñ9Ô9Ð9Ø˜!‘�øØÐ@°Ð@Ð@Ð@Ð@Ð@r   Nr7   Úparty_serviceúOptional[Any]c                ó  — | j                              |¦  «        }|sdS |j        sdS |j        |k    rdS |rJt	          |di ¦  «        }|                     |j        ¦  «        }|                     |¦  «        }|r||k    rdS dS )zQVerify whether player is the owner or an authorized party member to enter portal.)Fu;   PORTAL_NOT_FOUND: Cá»•ng dá»‹ch chuyá»ƒn khÃ´ng tá»“n táº¡i)Fu3   PORTAL_INACTIVE: Cá»•ng dá»‹ch chuyá»ƒn Ä‘Ã£ Ä‘Ã³ng)TÚAUTHORIZED_OWNERÚplayer_party_map)TÚAUTHORIZED_PARTY_MEMBER)FuW   PORTAL_UNAUTHORIZED: Chá»‰ chá»§ nhÃ¢n hoáº·c Ä‘á»“ng Ä‘á»™i má»›i cÃ³ thá»ƒ qua cá»•ng)r   r$   r3   r8   Úgetattr)r   r*   r7   rb   rM   Ú	party_mapÚowner_party_idÚplayer_party_ids           r   Úcan_traverse_portalz$TownPortalEngine.can_traverse_portal‰   s©   € ð ”×!Ò! )Ñ,Ô,ˆØð 	XØWÐWàÔð 	PØOÐOàŒ?˜iÒ'Ð'Ø+Ð+àð 	7Ý Ð/AÀ2ÑFÔFˆIØ&Ÿ]š]¨6¬?Ñ;Ô;ˆNØ'Ÿmšm¨IÑ6Ô6ˆOØð 7 .°OÒ"CÐ"CØ6Ð6àoÐor   Ú	is_returnú4Tuple[bool, str, Optional[Tuple[str, float, float]]]c                ó¾   — |                       |||¦  «        \  }}|sd|dfS | j        |         }|sdd|j        |j        |j        ffS dd|j        |j        |j        ffS )zDTraverse a 2-way town portal and return destination (zone_id, x, y).FNTÚTRAVERSED_TO_HUBÚTRAVERSED_TO_WILDERNESS)rl   r   r<   r=   r>   r9   r:   r;   )r   r*   r7   rb   rm   ÚokÚreasonrM   s           r   Útraverse_town_portalz%TownPortalEngine.traverse_town_portal£   sˆ   € ð ×-Ò-¨i¸ÀMÑRÔR‰
ˆˆFØð 	'Ø˜& $Ð&Ð&à”˜iÔ(ˆØð 	^àÐ+¨fÔ.@À&Ä,ÐPVÔP\Ð-]Ð]Ð]ð Ð.°Ô1JÈFÔL_ÐagÔatÐ0uÐuÐur   )r   r   )FF)r   r   r   r   r   r   r   r   )r   r   r   r   r   r    )r'   r(   r(   r)   )r*   r   r   r   r+   r,   r-   r.   r/   r.   r0   r   r1   r   r   r   )rO   )r   r   rP   rB   r   r   )r   r   r   rT   )F)
r*   r   r   r   r   r   rZ   r   r   r    )N)r*   r   r7   r   rb   rc   r   r    )NF)
r*   r   r7   r   rb   rc   rm   r   r   rn   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r&   rN   rS   rY   ra   rl   rt   © r   r   r   r      s+  € € € € € ØSÐSð&ð &ð &ð &ð "Ø#ð	8ð 8ð 8ð 8ð 8ð!ð !ð !ð !ð 08ØØØ-ð/<ð /<ð /<ð /<ð /<ðb@ð @ð @ð @ð @ð2ð 2ð 2ð 2ð !&ðAð Að Að Að Að6 (,ð	pð pð pð pð pð< (,Øðvð vð vð vð vð vð vr   r   )rx   Ú
__future__r   rF   Útypingr   r   r   r   r   Úserver.world.town_portal_typesr	   r
   r   r   ry   r   r   ú<module>r}      sÎ   ððð ð #Ð "Ð "Ð "Ð "Ð "à €€€Ø 4Ð 4Ð 4Ð 4Ð 4Ð 4Ð 4Ð 4Ð 4Ð 4Ð 4Ð 4Ð 4Ð 4ðð ð ð ð ð ð ð ð ð ð`vð `vð `vð `vð `vñ `vô `vð `vð `vð `vr   