
    Ii                        S r SSKJr  SSKJr  SSKJr  SSKJr  \(       a  SSK	J
r
  SSKJr  SS	 jr\ " S
 S\5      5       rg)aR  
Leveling System for Pirates of the Lost Seas.

Handles XP gain, level-ups, and skill unlock detection.
Skill unlock levels are defined on each skill class - this system reads from them.

This class inherits from DataClassJSONMixin to ensure serializability.
The game object is NEVER stored - it is only passed as a parameter to methods.
    )annotations)	dataclass)TYPE_CHECKING)DataClassJSONMixin   )PiratesGame)Skillc                    U S-  $ )z.Get the XP required to reach a specific level.    )levels    <c:\Users\dbart\PlayPalace11\server\games\pirates\leveling.pyget_xp_for_levelr      s    2:    c                      \ rS rSr% SrS\S'   SrS\S'   SrS\S'   SS	 jrSS
 jr	SS jr
SS jrSS jrSS jrSS jr  S           SS jjrSS jrSrg)LevelingSystem   a*  
Manages a player's experience and level progression.

Tied to a specific player via user_id.
Skill unlock levels are read from the skill singletons in skills.py.

The game object is NEVER stored - it is only passed as a parameter to methods.
This ensures the leveling system remains serializable.
struser_idr   intr   xpc                L    [        U R                  S-   5      U R                  -
  $ )z&Get XP needed to reach the next level.r   r   r   r   selfs    r   get_xp_to_next_level#LevelingSystem.get_xp_to_next_level+   s    

Q/$''99r   c                    [        U R                  5      n[        U R                  S-   5      nU R                  U-
  nX!-
  nX44$ )z,Get current XP and XP needed for next level.r   r   )r   current_level_xpnext_level_xpprogressneededs        r   get_xp_progressLevelingSystem.get_xp_progress/   sC    +DJJ7(a877--1r   c                L    U R                   [        U R                  S-   5      :  $ )z.Check if the player has enough XP to level up.r   )r   r   r   r   s    r   can_level_upLevelingSystem.can_level_up7   s    ww*4::>:::r   c                t    SSK Jn  U Vs/ s H   o"R                  U R                  ::  d  M  UPM"     sn$ s  snf )z6Get list of skills unlocked at or below current level.r   
ALL_SKILLSskillsr*   required_levelr   r   r*   skills      r   get_unlocked_skills"LevelingSystem.get_unlocked_skills;   s,    &#-T:%1E1E1S:TTT   55c                t    SSK Jn  U Vs/ s H   o"R                  U R                  :  d  M  UPM"     sn$ s  snf )z$Get list of skills not yet unlocked.r   r)   r+   r.   s      r   get_locked_skills LevelingSystem.get_locked_skillsA   s,    &#-S:%1E1E

1R:SSSr2   c                d    U R                  5       nU(       d  g[        US S9nUR                  U4$ )zAGet the next skill unlock (level, skill) or None if all unlocked.Nc                    U R                   $ N)r-   )ss    r   <lambda>6LevelingSystem.get_next_skill_unlock.<locals>.<lambda>N   s
    q/?/?r   )key)r4   minr-   )r   locked
next_skills      r   get_next_skill_unlock$LevelingSystem.get_next_skill_unlockG   s6    '') %?@
((*44r   c                `    SSK Jn  U Vs/ s H  o3R                  U:X  d  M  UPM     sn$ s  snf )z2Get skills that unlock exactly at the given level.r   r)   )r,   r*   r-   )r   r   r*   r/   s       r   get_skills_at_level"LevelingSystem.get_skills_at_levelQ   s(    &#-O:%1E1E1N:OOOs   ++c                   XE-  n[        X6-  5      nU =R                  U-  sl        UR                  SUS9  UR                  U R                  5      nU(       d  / $ U R
                  n	/ n
U R                  5       (       aX  U =R
                  S-  sl        U R                  U R
                  5      nU
R                  U5        U R                  5       (       a  MX  U R
                  U	:  a  UR                  SSS9  U R
                  U	-
  nUR                  U5      nUS:X  a>  U(       a  UR                  SU R
                  SS	9  UR                  S
X R
                  US9  O@U(       a  UR                  SUU R
                  SS9  UR                  SUUU R
                  US9  U
(       aB  SR                  S U
 5       5      nU(       a  UR                  SUSS9  UR                  SUUUS9  U
$ )a  
Give XP to this leveling system and process level ups.

Args:
    game: The game instance for announcements
    player_name: Name of the player for announcements
    base_xp: Base XP amount to give
    golden_moon_multiplier: Multiplier from golden moon (default 1.0)
    global_multiplier: Global XP multiplier from game options (default 1.0)

Returns:
    List of newly unlocked skills
zpirates-xp-gained)r   r   zgame_pig/win.oggP   )volumezpirates-level-up-youtable)r   bufferzpirates-level-up)playerr   excludezpirates-level-up-multiple-you)levelsr   rI   zpirates-level-up-multiple)rJ   rL   r   rK   z, c              3  8   #    U  H  oR                   v   M     g 7fr8   )name).0r/   s     r   	<genexpr>)LevelingSystem.give_xp.<locals>.<genexpr>   s     'Pu

s   zpirates-skills-unlocked-you)r,   rI   zpirates-skills-unlocked)rJ   r,   rK   )r   r   broadcast_lget_player_by_idr   r   r&   rC   extend
play_soundget_userspeak_ljoin)r   gameplayer_namebase_xpgolden_moon_multiplierglobal_multipliertotal_multiplier	xp_gainedrJ   starting_levelskills_unlockednewly_unlockedlevels_gaineduserskill_namess                  r   give_xpLevelingSystem.give_xpW   s   * 2E23	9 	,; &&t||4I )+!!JJ!OJ "55djjAN"">2 !! ::&OO.rO: JJ7M==(D!LL!7tzzRYLZ  &{**V\ !  LL7,"jj&	 !    /&(**" !  "ii'P'PPLL5*& ! 
   -&&"	 !  r   c                4    U R                   UR                  :  $ )z=Check if a specific skill is unlocked based on current level.)r   r-   )r   r/   s     r   has_skill_unlocked!LevelingSystem.has_skill_unlocked   s    zzU1111r   r   N)returnr   )rk   ztuple[int, int])rk   bool)rk   list['Skill'])rk   ztuple[int, 'Skill'] | None)r   r   rk   rm   )      ?rn   )rY   z'PiratesGame'rZ   r   r[   r   r\   floatr]   ro   rk   rm   )r/   z'Skill'rk   rl   )__name__
__module____qualname____firstlineno____doc____annotations__r   r   r   r#   r&   r0   r4   r@   rC   rf   ri   __static_attributes__r   r   r   r   r      s     LE3NBK: ;UT5P ),#&XX X 	X
 !&X !X 
Xt2r   r   N)r   r   rk   r   )rt   
__future__r   dataclassesr   typingr   mashumaro.mixins.jsonr   rY   r   r,   r	   r   r   r   r   r   <module>r{      sE    # !   4!
 W2' W2 W2r   