§
    ïÙÀj.  ã                   ó:  — d Z ddlZddlmZ ddlmZmZmZmZ 	 ddl	m
Z
 ddl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mZmZmZ ddlmZmZ n?# e$ r7 ddl m
Z
 ddl!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mZmZmZ ddl#mZmZ Y nw xY w G d	„ d
¦  «        Z$dS )zÊ
Procedural Monster Generation Engine for FreeExile.
Generates 10,000 deterministic monster variants across 100 levels.
Computes size scaling, ferocity profiles, stats, and modular GPU visual bindings.
é    N)Úreplace)ÚDictÚListÚOptionalÚTuple)ÚFiveElements)	ÚMonsterGenusÚMonsterRankÚAggressionProfileÚMonsterVisualProfileÚProceduralMonsterÚPackAuraTypeÚMonsterPackÚMonsterAffixÚMonsterRuntimeState)ÚCORE_GENUS_SPECSÚSUB_SPECIES_CATALOGÚPREFIX_AFFIXESÚSUFFIX_AFFIXESÚELEMENT_PALETTESÚMODULAR_ATTACHMENTS)Úroll_monster_affixesÚapply_affixes_to_statsc                   óV  — e Zd ZdZdd„Zdededefd„Zdedefd„Zd	ede	e
e
e
e
e
e
f         fd
„Z	 	 	 d dedee         dee         deee                  def
d„Z	 	 d!dededede
de
dedee         deee                  defd„Z	 d"dededee         fd„Zd#dededee         fd„ZdS )$ÚMonsterProceduralEnginezIServer-Authoritative Procedural Monster Generator (Deterministic $O(1)$).ÚreturnNc                 ój   — t          t          ¦  «        | _        t          t          ¦  «        | _        d S )N)Úlistr	   Ú_genus_listr   Ú_element_list)Úselfs    ú?C:\Projects\FreeExile\server\world\monster_procedural_engine.pyÚ__init__z MonsterProceduralEngine.__init__B   s(   € Ý¥Ñ-Ô-ˆÔÝ!¥,Ñ/Ô/ˆÔÐÐó    ÚseedÚsaltc                 óf   — ||dz  z   dz  }||dz	  z  dz  dz  }||dz	  z  dz  dz  }||dz	  z  dz  S )z@Lightweight deterministic integer hashing (splitmix64-inspired).l   ¹yn< l   ÿÿ é   i;Ÿ]© )r!   r%   r&   Úzs       r"   Ú
_hash_seedz"MonsterProceduralEngine._hash_seedF   sW   € à�D˜:Ñ%Ñ%¨Ñ3ˆØ�1˜‘7‰m˜yÑ(¨JÑ6ˆØ�1˜‘7‰m˜yÑ(¨JÑ6ˆØ�Q˜"‘W‘ Ñ+Ð+r$   c                 ó¸   — |                       |d¦  «        dz  }|dk     rt          j        S |dk     rt          j        S |dk     rt          j        S t          j        S )Née   éd   éA   éU   éa   )r+   r
   ÚCOMMONÚMAGICÚRAREÚBOSS)r!   r%   Úvals      r"   Ú_determine_rankz'MonsterProceduralEngine._determine_rankM   sY   € Ø�oŠo˜d CÑ(Ô(¨3Ñ.ˆØ�Š8ˆ8ÝÔ%Ð%Ø�2ŠXˆXÝÔ$Ð$Ø�2ŠXˆXÝÔ#Ð#ÝÔÐr$   Úrankc                 ór   — |t           j        k    rdS |t           j        k    rdS |t           j        k    rdS dS )N)ç      ð?r:   r:   ç        r;   r;   )g      ô?çš™™™™™@gÍÌÌÌÌÌô?g{®Gáz´?ç       @g333333Ó?)gÍÌÌÌÌÌø?ç      @gš™™™™™ù?g333333Ã?g      @g333333ã?)r<   g      (@g333333@g      Ð?g       @ç333333ó?)r
   r2   r3   r4   )r!   r8   s     r"   Ú_calc_rank_modifiersz,MonsterProceduralEngine._calc_rank_modifiersW   sD   € Ø•;Ô%Ò%Ð%Ø1Ð1Ø•[Ô&Ò&Ð&Ø3Ð3Ø•[Ô%Ò%Ð%Ø3Ð3à4Ð4r$   Ú
monster_idÚtarget_levelÚforced_rankÚallowed_genusc                 ó
  — |dk     rd}|�|n&t          dt          d|dz
  dz  dz   ¦  «        ¦  «        }|r|n| j        }|                      |d¦  «        t	          |¦  «        z  }||         }t
          |         \  }	}
}}}t          |         }||                      |d¦  «        t	          |¦  «        z           \  }}t          |                      |d¦  «        t	          t          ¦  «        z           \  }}}}t          |                      |d¦  «        t	          t          ¦  «        z           \  }}| j	        |                      |d¦  «        t	          | j	        ¦  «        z           }|�|n|  
                    |¦  «        }|                      |¦  «        \  }}}}}}|d	z  }t          |d
d|dz  z  z   z  |z  d¦  «        }t          d|z  d¦  «        } t          dt          dd|dz  z  z   |z   d¦  «        ¦  «        }!t          dd|dz  z  z   |z   d¦  «        }"t          dd|d
z  z  z   |z   d¦  «        }#t          dt          dd|dz  z  z
  ¦  «        ¦  «        }$t          dt          dd|d
z  z  z
  ¦  «        ¦  «        }%t          dt          dd
|z  z   d¦  «        ¦  «        }&d|dk    rdnd z   |d!k    rdnd z   |t          j        k    rdnd z   }'t!          |!|"t          |"dz  d¦  «        |#|$|%|&|'¬"¦  «        }(t"          |         \  })}*}+|t          j        k    rd n%|t          j        k    rdn|t          j        k    rdnd},g }-t+          |,¦  «        D ]V}.|                      |d#|.z   ¦  «        t	          t,          ¦  «        z  }/t,          |/         }0|0|-vr|-                     |0¦  «         ŒWt1          || |)t          d|+|t          j        k    rdnd$z   z  d¦  «        |-|+¬%¦  «        }1|dk    rd&n
dd'|z  z   d(z  }2|dk    rd)n
dd*|z  z   d+z  }3t          |
|3z  |z  |z  d¦  «        }4t          ||2z  |z  |z  d¦  «        }5t          |4d'z  d¦  «        }6|› d,|› d-|› �}7t3          |||¬.¦  «        }8|8rt5          |4|5|6|8¦  «        \  }4}5}6t7          dCi d/|“d0|“d1|7“d2|“d3|“d4|“d5|“d6|“d7|“d8|4“d9|5“d:|6“d;|(“d<|1“d=t          |d>z  |z  ¦  «        “d?t          d@t          d|dAz  |t          j        k    rdnd z   ¦  «        ¦  «        “dB|8“ŽS )Dz=Generates a single deterministic monster by ID (1 .. 10,000).é   Nr.   é   é   é%   é/   é;   g      Y@gš™™™™™é?g      à?g      è?é   r:   gš™™™™™É?gš™™™™™á?g333333ë?é   g      @g      .@gÍÌÌÌÌÌì?r<   r>   é´   i  iÜ  i^  iÄ	  iÐ  gš™™™™™¹?é   r   éF   )Úferocity_indexÚaggro_radius_metersÚleash_radius_metersÚmovement_speedÚattack_windup_msÚattack_cooldown_msÚflocking_cohesionÚ
combo_hitséG   r;   )Ú
base_scaleÚcollision_radiusÚelemental_tint_hexÚemissive_glow_intensityÚattachment_idsÚpalette_lut_indexg{®GázÔ?g¸…ëQ¸¾?gÍÌÌÌÌÌü?gÍÌÌÌÌÌä?g
×£p=
Ç?gÍÌÌÌÌÌ @ú u    Â· )Úlevelr8   r%   rA   ra   ÚnameÚgenusÚsub_species_codeÚelementr8   ÚprefixÚsuffixÚmax_hpÚbase_damageÚarmorÚ
aggressionÚvisualÚexperience_rewardé   Ú	loot_tierr(   é   Úaffixesr)   )ÚminÚmaxr   r+   Úlenr   r   r   r   r    r7   r@   ÚroundÚintr
   r5   r   r   r2   r3   r4   Úranger   Úappendr   r   r   r   )9r!   rA   rB   rC   rD   ra   Ú
genus_poolÚ	genus_idxrc   Ú	base_nameÚbase_hpÚbase_dmgrZ   Únative_elemÚsub_listÚsub_codeÚ	sub_titleÚprefix_titleÚp_hp_modÚ	p_dmg_modÚ_Úsuffix_titlere   r8   Úrank_scale_mÚ	rank_hp_mÚ
rank_dmg_mÚrank_fero_bÚrank_aggro_bÚ
rank_spd_bÚ	lvl_ratioÚfinal_scaleÚcollision_rÚferocityÚaggro_radiusÚmovement_spdÚ	windup_msÚcooldown_msÚcohesionrX   rk   Útint_hexÚglow_hexÚlut_idxÚnum_attachmentsÚselected_attachmentsÚiÚatt_idxÚatt_idrl   Úlvl_dmg_multÚlvl_hp_multrh   Úbase_dmg_valÚ	armor_valÚ	full_namerq   s9                                                            r"   Úgenerate_monsterz(MonsterProceduralEngine.generate_monstera   sX  € ð ˜Š>ˆ>ØˆJà ,Ð 8��½cÀ#ÅsÈ1ÐPZÐ]^ÑP^ÐcfÑOfÐjkÑNkÑGlÔGlÑ>mÔ>mˆØ&3ÐI�]�]¸Ô9Iˆ
Ø—O’O J°Ñ3Ô3µc¸*±o´oÑEˆ	Ø˜9Ô%ˆÝ@PÐQVÔ@WÑ=ˆ	�7˜H j°+õ ' uÔ-ˆØ& t§¢°zÀ2Ñ'FÔ'FÍÈXÉÌÑ'VÔWÑˆ�)Ý/=¸d¿oºoÈjÐZ\Ñ>]Ô>]Õ`cÕdrÑ`sÔ`sÑ>sÔ/tÑ,ˆ�h 	¨1Ý(¨¯ª¸ÀRÑ)HÔ)HÍ3Í~ÑK^ÔK^Ñ)^Ô_‰ˆ�að Ô$ T§_¢_°ZÀÑ%DÔ%DÅsÈ4ÔK]ÑG^ÔG^Ñ%^Ô_ˆØ)Ð5ˆ{ˆ{¸4×;OÒ;OÐPZÑ;[Ô;[ˆØUY×UnÒUnÐosÑUtÔUtÑRˆ�i ¨[¸,È
ð ˜E‘Mˆ	Ý˜J¨$°¸ÀdÑ9JÑ1KÑ*KÑLÈ|Ñ[Ð]^Ñ_Ô_ˆÝ˜D ;Ñ.°Ñ2Ô2ˆõ �s�E $¨°¸dÑ1BÑ)CÑ"CÀkÑ"QÐSTÑUÔUÑVÔVˆÝ˜S 4¨9¸Ñ+<Ñ#=Ñ=ÀÑLÈaÑPÔPˆÝ˜S 3¨)°tÑ*;Ñ#<Ñ<¸zÑIÈ1ÑMÔMˆÝ˜�S ¨°	¸TÑ0AÑ(BÑ!BÑCÔCÑDÔDˆ	Ý˜#�s 4¨$°)¸tÑ2CÑ*DÑ#DÑEÔEÑFÔFˆÝ�s�E #¨¨i©Ñ"7¸Ñ;Ô;Ñ<Ô<ˆØ˜u¨š{˜{˜!˜!°Ñ2¸5ÀBº;¸;°a°aÈAÑNÐW[Õ_jÔ_oÒWoÐWoÐRSÐRSÐuvÑwˆ
å&Ø#Ø ,Ý % l°SÑ&8¸!Ñ <Ô <Ø'Ø&Ø*Ø&Ø!ð	
ñ 	
ô 	
ˆ
õ '7°wÔ&?Ñ#ˆ�(˜GØ#¥{Ô'9Ò9Ð9˜!˜!ÀTÍ[ÔM^ÒE^ÐE^ÀÀÐjnÕr}ô  sCò  kCð  kCÐefÐefð  IJˆØ*,ÐÝ�Ñ'Ô'ð 	4ð 	4ˆAØ—o’o j°"°q±&Ñ9Ô9½CÕ@SÑ<TÔ<TÑTˆGÝ(¨Ô1ˆFØÐ1Ð1Ð1Ø$×+Ò+¨FÑ3Ô3Ð3øå%Ø"Ø(Ø'Ý$)¨#°À4Í;ÔK]ÒC]ÐC]¸C¸CÐcfÑ1gÑ*hÐjkÑ$lÔ$lØ/Ø%ð
ñ 
ô 
ˆð  %¨šz˜z�t�t°°t¸e±|Ñ1CÈÑ0KˆØ# qšj˜j�d�d°°d¸U±lÑ0BÀsÑ/JˆÝ�w Ñ,¨yÑ8¸8ÑCÀQÑGÔGˆÝ˜X¨Ñ4°zÑAÀIÑMÈqÑQÔQˆÝ˜& 4™-¨Ñ+Ô+ˆ	Ø#ÐCÐC iÐCÐC°\ÐCÐCˆ	õ '¨U¸ÀJÐOÑOÔOˆØð 	oÝ.DÀVÈ\Ð[dÐfmÑ.nÔ.nÑ+ˆF�L )å ð 
ð 
ð 
Ø!�zð
à�%ð
ð �ð
ð �%ð	
ð
 &˜Xð
ð �Gð
ð �ð
ð  �<ð
ð  �<ð
ð �6ð
ð %˜ð
ð �)ð
ð "�zð
ð �6ð
õ " %¨"¡*¨yÑ"8Ñ9Ô9Ð9ð
õ  ˜"�c ! e¨q¡j¸$Å+ÔBTÒ:TÐ:T°Q°QÐZ[Ñ%\Ñ]Ô]Ñ^Ô^Ð^ð!
ð" �Gð#
ð 	
r$   Úpack_idÚzone_idra   Úcenter_xÚcenter_yÚminion_countc	                 ó
  — |                       |d¦  «        dz  dz   }	|                      |	|t          j        |¬¦  «        }
t	          t
          ¦  «        }||                       |d¦  «        t          |¦  «        z           }t          |t          j        |                       |d¦  «        ¦  «        }t          |
|d|t          j        |¬¦  «        }
|�|nd
|                       |d¦  «        dz  z   }g }t          |¦  «        D ]q}|                       |d|z   ¦  «        dz  dz   }|                      ||t          j
        |¬¦  «        }t          ||d|
j        ¬¦  «        }|                     |¦  «         Œrt          |||
|||¦  «        S )zq
        Generates a coordinated monster pack with a Rare pack leader and radial minions (1.2m to 3.2m).
        ié  i(#  iè  )rB   rC   rD   iÒ  iÉ	  T)r¤   Úis_pack_leaderÚleader_aurar8   rq   NrM   i»  é   i¤  F)r¤   rª   Úpack_leader_id)r+   r£   r
   r4   r   r   rt   r   r   rw   r2   rA   rx   r   )r!   r¤   r¥   ra   r¦   r§   r%   r¨   rD   Ú	leader_idÚleaderÚ	aura_listÚchosen_auraÚleader_affixesÚcountÚminionsr›   Úm_idÚms                      r"   Úgenerate_packz%MonsterProceduralEngine.generate_packÊ   s¬  € ð —_’_ T¨4Ñ0Ô0°4Ñ7¸4Ñ?ˆ	Ø×&Ò&ØØÝ#Ô(Ø'ð	 'ñ 
ô 
ˆõ �Ñ&Ô&ˆ	Ø §¢°°dÑ ;Ô ;½cÀ)¹n¼nÑ LÔMˆÝ-¨eµ[Ô5EÀtÇÂÐW[Ð]aÑGbÔGbÑcÔcˆÝØØØØ#ÝÔ!Ø"ð
ñ 
ô 
ˆð !-Ð 8��¸aÀ4Ç?Â?ÐSWÐY]ÑC^ÔC^ÐabÑCbÑ>cˆØ+-ˆå�u‘”ð 	ð 	ˆAØ—O’O D¨$°©(Ñ3Ô3°dÑ:¸dÑBˆDØ×%Ò%ØØ"Ý'Ô.Ø+ð	 &ñ ô ˆAõ ØØØ$Ø%Ô0ð	ñ ô ˆAð �NŠN˜1ÑÔÐÐå˜7 G¨V°W¸hÈÑQÔQÐQr$   é90  Úpackc                 ó  — g }t          |j        |j        |j        |j        |j        |j        j        |j        d|j        j        |j        j        ¬¦
  «
        }|                     |¦  «         t          |j
        ¦  «        }t          |j
        ¦  «        D ]ï\  }}dt          j        z  |z  t          d|¦  «        z  |                      |d|z   ¦  «        dz  dz  z   }d|                      |d	|z   ¦  «        d
z  dz  z   }	|j        |	t          j        |¦  «        z  z   }
|j        |	t          j        |¦  «        z  z   }t          ||
||
||j        |j        d|j        j        |j        ¬¦
  «
        }|                     |¦  «         Œð|S )zKInstantiates runtime states with radial positioning around the pack leader.T)
ÚmonsterÚ	current_xÚ	current_yÚspawn_xÚspawn_yÚ
current_hpr¤   rª   r«   rq   r=   rF   i�  r.   g{®Gázt?r?   iv  éÈ   g{®Gáz„?F)
r»   r¼   r½   r¾   r¿   rÀ   r¤   rª   r­   rq   )r   r¯   r¦   r§   rh   r¤   r«   rq   rx   rt   r´   Ú	enumerateÚmathÚpirs   r+   ÚcosÚsinrA   )r!   r¹   r%   ÚstatesÚ	leader_str³   r›   ÚminionÚangleÚdistÚm_xÚm_yÚm_sts                r"   Úcreate_pack_runtime_statesz2MonsterProceduralEngine.create_pack_runtime_states   sŠ  € ð -/ˆÝ'Ø”KØ”mØ”mØ”MØ”MØ”{Ô)Ø”LØØœÔ/Ø”KÔ'ð
ñ 
ô 
ˆ	ð 	�Š�iÑ Ô Ð å�D”LÑ!Ô!ˆÝ" 4¤<Ñ0Ô0ð 	 ð 	 ‰IˆAˆvØ�4œ7‘] QÑ&­#¨a°©-¬-Ñ7¸4¿?º?È4ÐQUÐXYÑQYÑ;ZÔ;ZÐ]`Ñ;`ÐdiÑ:iÑiˆEØ˜$Ÿ/š/¨$°°q±Ñ9Ô9¸CÑ?À4ÑGÑGˆDØ”- $­¬°%©¬Ñ"8Ñ8ˆCØ”- $­¬°%©¬Ñ"8Ñ8ˆCÝ&ØØØØØØ!œ=ØœØ$Ø#œ{Ô5Øœðñ ô ˆDð �MŠM˜$ÑÔÐÐØˆr$   rF   é'  Ústart_idr³   c                 óB   ‡ — ˆ fd„t          |||z   ¦  «        D ¦   «         S )z*Generates a batch of monsters efficiently.c                 ó:   •— g | ]}‰                      |¦  «        ‘ŒS r)   )r£   )Ú.0Úmidr!   s     €r"   ú
<listcomp>z:MonsterProceduralEngine.generate_batch.<locals>.<listcomp>,  s'   ø€ ÐXÐXÐX¨s�×%Ò% cÑ*Ô*ÐXÐXÐXr$   )rw   )r!   rÑ   r³   s   `  r"   Úgenerate_batchz&MonsterProceduralEngine.generate_batch*  s-   ø€ àXÐXÐXÐXµe¸HÀhÐQVÑFVÑ6WÔ6WÐXÑXÔXÐXr$   )r   N)NNN)NN)r¸   )rF   rÐ   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r#   rv   r+   r
   r7   ÚtupleÚfloatr@   r   r   r	   r   r£   Ústrr   r·   r   rÏ   r×   r)   r$   r"   r   r   ?   s7  € € € € € ØSÐSð0ð 0ð 0ð 0ð,˜sð ,¨#ð ,°#ð ,ð ,ð ,ð ,ð  Cð  ¨Kð  ð  ð  ð  ð5¨ð 5¸¸uÀeÈUÐTYÐ[`ÐbgÐ?gÔ9hð 5ð 5ð 5ð 5ð '+Ø-1Ø6:ðg
ð g
àðg
ð ˜s”mðg
ð ˜kÔ*ð	g
ð
    \Ô 2Ô3ðg
ð 
ðg
ð g
ð g
ð g
ðb '+Ø6:ð4Rð 4Ràð4Rð ð4Rð ð	4Rð
 ð4Rð ð4Rð ð4Rð ˜s”mð4Rð    \Ô 2Ô3ð4Rð 
ð4Rð 4Rð 4Rð 4Rðr ð(ð (àð(ð ð(ð 
Ð!Ô	"ð	(ð (ð (ð (ðTYð Y sð Y°sð YÀtÐL]ÔG^ð Yð Yð Yð Yð Yð Yr$   r   )%rÛ   rÃ   Údataclassesr   Útypingr   r   r   r   Úserver.world.martial_matrixr   Úserver.world.monster_typesr	   r
   r   r   r   r   r   r   r   Ú&server.world.monster_archetype_catalogr   r   r   r   r   r   Ú"server.world.monster_affix_catalogr   r   ÚImportErrorÚworld.martial_matrixÚworld.monster_typesÚworld.monster_archetype_catalogÚworld.monster_affix_catalogr   r)   r$   r"   ú<module>rê      s·  ððð ð €€€Ø Ð Ð Ð Ð Ð Ø .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .ð1Ø8Ð8Ð8Ð8Ð8Ð8ð
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ðð ð ð ð ð ð ð ð øð ð ð ð Ø1Ð1Ð1Ð1Ð1Ð1ð
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ðð ð ð ð ð ð ð ð ð ð+øøøð8mYð mYð mYð mYð mYñ mYô mYð mYð mYð mYs   š4A Á9BÂ
B