§
    y¿jÔ#  ã                  ó    — d Z ddlmZ ddlZddl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 ddlmZ ddlmZmZ dd	lmZ  G d
„ d¦  «        ZdS )z÷
FreeExile Monster Loot Drop Generation and Ground Pickup Service.
Manages authoritative item drop generation, spatial ground tracking, and pickup resolution.
Follows Engineering Standards 2026: Soft cap <= 350 lines, Zero-trust server authority.
é    )ÚannotationsN)ÚDictÚListÚOptionalÚTupleÚAnyé   )ÚItemTypeÚ
ItemRarityÚInventoryItem)ÚInventoryService)ÚGroundLootDropÚLootFilterConfig)Úget_default_item_dimensionsc                  óx   — e Zd ZdZd0d1d„Zd2d
„Zd3d„Zd4d„Zd5d„Z	 	 	 	 	 	 	 d6d7d$„Z		 d0d8d*„Z
	 d9d:d.„Z	 d9d;d/„ZdS )<ÚLootDropServicezXAuthoritative service handling ground loot spawns, filter checks, and inventory pickups.NÚinventory_serviceúOptional[InventoryService]ÚreturnÚNonec                ó>   — |pt          ¦   «         | _        i | _        d S ©N)r   r   Ú_ground_drops)Úselfr   s     ú;C:\Projects\FreeExile\server\inventory\loot_drop_service.pyÚ__init__zLootDropService.__init__   s$   € Ø!2Ð!HÕ6FÑ6HÔ6HˆÔØ8:ˆÔÐÐó    Údropr   c                ó$   — || j         |j        <   dS )z'Registers a spawned ground drop entity.N)r   Údrop_id)r   r   s     r   Úregister_ground_dropz$LootDropService.register_ground_drop   s   € à+/ˆÔ˜4œ<Ñ(Ð(Ð(r   r    ÚstrúOptional[GroundLootDrop]c                ó6   — | j                              |¦  «        S )z#Retrieves a ground drop by drop_id.)r   Úget©r   r    s     r   Úget_ground_dropzLootDropService.get_ground_drop   s   € àÔ!×%Ò% gÑ.Ô.Ð.r   úList[GroundLootDrop]c                óH   — d„ | j                              ¦   «         D ¦   «         S )z'Returns all non-collected ground drops.c                ó    — g | ]}|j         °	|‘ŒS © )Úis_collected)Ú.0Úds     r   ú
<listcomp>z;LootDropService.get_active_ground_drops.<locals>.<listcomp>$   s   € ÐMÐMÐM�a¸a¼nÐM�ÐMÐMÐMr   )r   Úvalues)r   s    r   Úget_active_ground_dropsz'LootDropService.get_active_ground_drops"   s%   € àMÐM˜4Ô-×4Ò4Ñ6Ô6ÐMÑMÔMÐMr   Úboolc                ó,   — || j         v r
| j         |= dS dS )z%Deletes a ground drop from the world.TF)r   r&   s     r   Úremove_ground_dropz"LootDropService.remove_ground_drop&   s%   € à�dÔ(Ð(Ð(ØÔ" 7Ð+Ø�4Øˆur   F©ç        r6   ç      ð?Ú
monster_idÚmonster_levelÚintÚis_bossÚdrop_posúTuple[float, float]Úallocation_modeúOptional[Any]Úparty_membersúOptional[List[str]]Úitem_quantity_multÚfloatÚcurrency_quantity_multÚrarity_multc
                ó²  — g }
|\  }}d}|�&t          |d¦  «        r|j        nt          |¦  «        }|                     ¦   «         }|rt	          j        dd¦  «        nt	          j        dd¦  «        }t          dt          t          |t          d|¦  «        z  ¦  «        ¦  «        ¦  «        }|  	                    |||||¦  «        }|
 
                    |¦  «         t          |dz
  ¦  «        D ]Ã}|t	          j        ¦   «         d	z
  d
z  z   }|t	          j        ¦   «         d	z
  d
z  z   }d|	z  }|s%t	          j        ¦   «         t          d|¦  «        k     r/|                      |||||	¦  «        }|
 
                    |¦  «         Œ•|  	                    |d|||¦  «        }|
 
                    |¦  «         ŒÄd„ |pg D ¦   «         }t          j        ¦   «         }t          |
¦  «        D ]u\  }}|rD||t!          |¦  «        z           }||_        ||_        |dk    r|j        dz   |_        nd|_        nd|_        d|_        d|_        |                      |¦  «         Œv|
S )z[Generates authentic drops according to monster rank, level, drop tables, and party scaling.ÚFREE_FOR_ALLNÚvalueé   é   r	   é   çš™™™™™¹?g      à?gš™™™™™ù?gÍÌÌÌÌÌÜ?g333333ë?Fc                ó   — g | ]}|¯|‘ŒS r+   r+   )r-   Úms     r   r/   z:LootDropService.generate_monster_drops.<locals>.<listcomp>V   s   € Ð>Ð>Ð>˜a¸AÐ>˜Ð>Ð>Ð>r   ÚSHORTg      @r6   Ú )ÚhasattrrH   r"   ÚupperÚrandomÚrandintÚmaxr:   ÚroundÚ_create_currency_dropÚappendÚrangeÚminÚ_create_gear_dropÚtimeÚ	enumerateÚlenÚallocated_player_idr>   Ú
spawned_atÚallocation_expires_atr!   )r   r8   r9   r;   r<   r>   r@   rB   rD   rE   ÚdropsÚbase_xÚbase_yÚmode_valÚ
base_dropsÚ	num_dropsÚ	curr_dropÚ_Úoffset_xÚoffset_yÚgear_chanceÚ	gear_dropÚ
extra_currÚmembers_listÚnowÚidxr   Úassigned_players                               r   Úgenerate_monster_dropsz&LootDropService.generate_monster_drops-   s„  € ð ')ˆØ!‰ˆ�à!ˆØÐ&Ý07¸ÈÑ0QÔ0QÐk�Ô,Ð,ÕWZÐ[jÑWkÔWkˆHØ—>’>Ñ#Ô#ˆà-4ÐN•V”^ A qÑ)Ô)Ð)½&¼.ÈÈAÑ:NÔ:Nˆ
Ý˜�3�u Zµ#°cÐ;MÑ2NÔ2NÑ%NÑOÔOÑPÔPÑQÔQˆ	ð ×.Ò.¨}¸gÀvÈvÐWmÑnÔnˆ	Ø�Š�YÑÔÐõ �y 1‘}Ñ%Ô%ð 		)ð 		)ˆAØ¥¤¡¤°3Ñ!6¸#Ñ =Ñ=ˆHØ¥¤¡¤°3Ñ!6¸#Ñ =Ñ=ˆHØ Ñ,ˆKØð )�&œ-™/œ/­C°°kÑ,BÔ,BÒBÐBØ ×2Ò2°=À'È8ÐU]Ð_jÑkÔk�	Ø—’˜YÑ'Ô'Ð'Ð'à!×7Ò7¸ÀuÈhÐX`ÐbxÑyÔy�
Ø—’˜ZÑ(Ô(Ð(Ð(ð ?Ð> MÐ$7°RÐ>Ñ>Ô>ˆÝŒi‰kŒkˆÝ" 5Ñ)Ô)ð 	,ð 	,‰IˆC�Øð 1Ø".¨sµS¸Ñ5FÔ5FÑ/FÔ"G�Ø+:�Ô(Ø'/�Ô$Ø˜wÒ&Ð&Ø15´À3Ñ1F�DÔ.Ð.à14�DÔ.Ð.à+-�Ô(Ø'5�Ô$Ø-0�Ô*à×%Ò% dÑ+Ô+Ð+Ð+àˆr   Ú
account_idÚcharacter_idÚfilter_configúOptional[LootFilterConfig]úTuple[bool, str, Optional[int]]c                óô  — |                       |¦  «        }|s	dd|› d�dfS |j        r	dd|› d�dfS t          j        ¦   «         }|                     ||¦  «        p|                     ||¦  «        }|s	dd|› d�dfS |r4|                     |j        ¦  «        sd|_        dd|j        j        › d	�dfS | j         	                    |||j        ¬
¦  «        \  }}	}
|rd|_        dd|j        j        › d|
› �|
fS d|	dfS )z^Authoritatively collects a ground drop into character survival backpack with allocation check.FzGround drop z does not existNz already collectedz is allocated to another playerTzItem z filtered out by loot filter)rt   ru   Úitemz
Picked up z into slot )
r'   r,   r\   Úcan_player_pickupÚevaluate_itemrz   Úfiltered_outÚnamer   Úadd_item_to_inventory)r   rt   ru   r    rv   r   rp   Ú
can_pickupÚsuccessÚmsgÚslots              r   Úpickup_ground_dropz"LootDropService.pickup_ground_dropj   sw  € ð ×#Ò# GÑ,Ô,ˆØð 	HØÐA¨ÐAÐAÐAÀ4ÐGÐGàÔð 	KØÐD¨ÐDÐDÐDÀdÐJÐJõ Œi‰kŒkˆØ×+Ò+¨L¸#Ñ>Ô>ÐiÀ$×BXÒBXÐYcÐehÑBiÔBiˆ
Øð 	XØÐQ¨ÐQÐQÐQÐSWÐWÐWð ð 	U ×!<Ò!<¸T¼YÑ!GÔ!Gð 	UØ $ˆDÔØÐN $¤)¤.ÐNÐNÐNÐPTÐTÐTð "Ô3×IÒIØ!Ø%Ø”ð Jñ 
ô 
Ñˆ��dð ð 	NØ $ˆDÔØÐG d¤i¤nÐGÐGÀÐGÐGÈÐMÐMà�c˜4ÐÐr   ÚwxÚwyÚcurrency_multc                ó  — ddt           j        ddfddt           j        ddfd	d
t           j        ddfddt           j        ddfg}|r/t          j        ¦   «         dk     rddt           j        ddf\  }}}	}
}nt          j        |¦  «        \  }}}	}
}|rt          j        dd¦  «        nt          j        dd¦  «        }t          dt          t          |t          d|¦  «        z  ¦  «        ¦  «        ¦  «        }t          dt          j        ¦   «         j        d d…         › �||t          j        |	ddd|d¬¦
  «
        }t!          dt          j        ¦   «         j        d d…         › �||||
|t#          j        ¦   «         ¬¦  «        S )NÚcurr_blood_soul_gemu   Huyáº¿t Há»“n Tháº¡chú#29b6f6éZ   Úcurr_chaos_stoneu   Há»—n NguyÃªn Tháº¡chú#fbbf24é‚   Úcurr_nether_bone_nailu   U Minh Cá»‘t Ä�inhz#f59e0béx   Úcurr_primal_bone_sealu   Cá»• Cá»‘t áº¤néŒ   g333333Ã?Úcurr_void_mirror_shardu   Máº£nh KÃ­nh ThÃ¡i HÆ°z#818cf8éÜ   rI   é   r	   rL   Údrop_é
   iˆ  ©
Ú	item_uuidÚitem_idr~   Ú	item_typeÚrarityÚ
item_levelÚwidthÚheightÚstack_countÚ	max_stackÚgd_©r    rz   Úworld_xÚworld_yÚ
beam_colorÚbeam_heightr`   )r   Ú	LINH_PHAMÚCUC_PHAMrS   Ú
THAN_THOAIÚchoicerT   rU   r:   rV   r   ÚuuidÚuuid4Úhexr
   ÚCURRENCYr   r\   )r   r9   r;   r…   r†   r‡   Ú
currenciesÚc_idÚc_namerœ   ÚcolorÚbeam_hÚ
base_countÚcountrz   s                  r   rW   z%LootDropService._create_currency_drop“   s§  € ð #Ð$;½ZÔ=QÐS\Ð^`ÐaØÐ!8½*Ô:MÈyÐZ]Ð^Ø$Ð&:½JÔ<OÐQZÐ\_Ð`Ø$Ð&7½Ô9LÈiÐY\Ð]ð	
ˆ
ð ð 	L•v”}‘”¨Ò-Ð-à(Ð*BÅJÔDYÐ[dÐfið3Ñ/ˆD�&˜& %¨¨õ 39´-À
Ñ2KÔ2KÑ/ˆD�&˜& %¨à-4ÐN•V”^ A qÑ)Ô)Ð)½&¼.ÈÈAÑ:NÔ:Nˆ
Ý�A•s�5 ­c°#°}Ñ.EÔ.EÑ!EÑFÔFÑGÔGÑHÔHˆÝØ5�dœj™lœlÔ.¨s°¨sÔ3Ð5Ð5ØØÝÔ'ØØØØØØð
ñ 
ô 
ˆõ Ø0�$œ*™,œ,Ô*¨2¨A¨2Ô.Ð0Ð0ØØØØØÝ”y‘{”{ð
ñ 
ô 
ð 	
r   c                óÖ  — ddt           j        ddfddt           j        ddfddt           j        d	d
fddt           j        dd
fddt           j        ddfddt           j        ddfg}t          j        |¦  «        \  }}}	}
}t          dd|z  ¦  «        }|st          j        ¦   «         |k     rt          j        nt          j        }|t          j        k    rdnd}|t          j        k    rdnd}t          dt          j        ¦   «         j        d d…         › �|||	|||
|d	d	¬¦
  «
        }t          dt          j        ¦   «         j        d d…         › �|||||t          j        ¦   «         ¬¦  «        S )NÚwpn_infernal_bladeu   XÃ­ch Diá»…m Tráº£m MÃ£ Ä�aorK   é   Úwpn_bone_bowu   TÃ­ch Cá»‘t Ma Há»“n CungÚwpn_azure_swordu   Thanh Phong Cá»• Kiáº¿mr	   rI   Úarm_yaksha_armoru   Dáº¡ Xoa Huyáº¿t GiÃ¡pÚarm_crane_helmu   Linh Háº¡c QuanÚarm_cloud_bootsu   Huyá»…n áº¢nh BÃ¡o ThÃ¢n HÃ ig      è?g333333Ó?r�   rŠ   é–   r‹   Úgear_r—   r˜   r¢   r•   r£   )r
   ÚWEAPONÚARMORrS   r«   rZ   r   r©   r¨   r   r¬   r­   r®   r   r\   )r   r9   r;   r…   r†   rE   Úgear_templatesÚg_idÚg_nameÚg_typeÚwÚhÚcuc_pham_chancerœ   r³   r´   rz   s                    r   r[   z!LootDropService._create_gear_drop»   s‘  € ð "Ð#AÅ8Ä?ÐTUÐWXÐYØÐ8½(¼/È1ÈaÐPØÐ 9½8¼?ÈAÈqÐQØÐ!9½8¼>È1ÈaÐPØÐ0µ(´.À!ÀQÐGØÐ ?ÅÄÐQRÐTUÐVð
ˆõ &,¤]°>Ñ%BÔ%BÑ"ˆˆf�f˜a Ý˜d C¨+Ñ$5Ñ6Ô6ˆØ(/Ðnµ6´=±?´?À_Ò3TÐ3T•Ô$Ð$ÕZdÔZnˆØ#¥zÔ':Ò:Ð:�	�	À	ˆØ¥*Ô"5Ò5Ð5��¸2ˆåØ5�dœj™lœlÔ.¨s°¨sÔ3Ð5Ð5ØØØØØ$ØØØØð
ñ 
ô 
ˆõ Ø0�$œ*™,œ,Ô*¨2¨A¨2Ô.Ð0Ð0ØØØØØÝ”y‘{”{ð
ñ 
ô 
ð 	
r   r   )r   r   r   r   )r   r   r   r   )r    r"   r   r#   )r   r(   )r    r"   r   r2   )Fr5   NNr7   r7   r7   )r8   r"   r9   r:   r;   r2   r<   r=   r>   r?   r@   rA   rB   rC   rD   rC   rE   rC   r   r(   )
rt   r"   ru   r"   r    r"   rv   rw   r   rx   )r7   )r9   r:   r;   r2   r…   rC   r†   rC   r‡   rC   r   r   )r9   r:   r;   r2   r…   rC   r†   rC   rE   rC   r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r!   r'   r1   r4   rs   r„   rW   r[   r+   r   r   r   r      s  € € € € € ØbÐbð;ð ;ð ;ð ;ð ;ð0ð 0ð 0ð 0ð/ð /ð /ð /ðNð Nð Nð Nðð ð ð ð Ø(2Ø)-Ø-1Ø$'Ø(+Ø ð;ð ;ð ;ð ;ð ;ðD 59ð% ð % ð % ð % ð % ðT _bð&
ð &
ð &
ð &
ð &
ðR ]`ð%
ð %
ð %
ð %
ð %
ð %
ð %
r   r   )rÍ   Ú
__future__r   rS   r\   r¬   Útypingr   r   r   r   r   Úinventory_typesr
   r   r   r   r   Úloot_filter_typesr   r   Úspatial_grid_typesr   r   r+   r   r   ú<module>rÓ      sþ   ððð ð #Ð "Ð "Ð "Ð "Ð "Ø €€€Ø €€€Ø €€€Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3à @Ð @Ð @Ð @Ð @Ð @Ð @Ð @Ð @Ð @Ø /Ð /Ð /Ð /Ð /Ð /Ø ?Ð ?Ð ?Ð ?Ð ?Ð ?Ð ?Ð ?Ø ;Ð ;Ð ;Ð ;Ð ;Ð ;ðM
ð M
ð M
ð M
ð M
ñ M
ô M
ð M
ð M
ð M
r   