a
    ¯`i¿T  ã                3   @   sº  d Z ddlmZmZmZmZ ddlZddlZddl	m
Z
 e e¡Zddddd	d
ddœddddddddœddddd	d
ddœddddddddœddddddddœdd d!dd"d#ddœd$d%d&dd'd(ddœd)d*d+dd,d-ddœd.d/d0dd1d2ddœd3d4d5dd6d7ddœd8d9d:d;dd<ddœd=d>d?d;d1d@ddœdAdBdCd;d'dDddœdEdFdGd;dd#ddœdHdIdJd;ddKddœdLdMdNd;d"dOddœdPdQdRd;dSdTddœdUdVdWd;d	dXddœdYdZd[d\dd]ddœd^d_d`d\d'daddœdbdcddd\d	deddœdfdgdhd\didjddœdkdldmd\d"dnddœdodpdqd\ddrddœdsdtdud\dvdwddœdxdydzd{d|d}ddœd~dd€d{d1d�ddœd‚dƒd„d{d,d…ddœd†d‡dˆd{d‰dŠddœd‹dŒd�d{d	d2ddœdŽd�d�d{dd‘ddœd’d“d”d{d•d–ddœd—d˜d™dšdd›dœdœd�dždŸdšd	d dœdœd¡d¢d£dšd'd¤dœdœd¥d¦d§dšd,d¨dœdœd©dªd«dšd1d¬dœdœd­d®d¯dšd"dTdœdœd°d±d²dšdd³dœdœd´dµd¶dšd'd·dœdœd¸d¹dºdšdd»dœdœd¼d½d¾dšd,d¿dœdœdÀdÁdÂdšdidÃdœdœdÄdÅdÆdšd	dÇdœdœg,ZdÈdÉ„ ZdÓeeeeef ee dÊœdËdÌ„Zeeee dÍœdÎdÏ„Zeeeef dÐœdÑdÒ„ZdS )Ôz„
Achievement System

Tracks and unlocks achievements based on player actions.
Includes 40+ achievements across multiple categories.
é    )ÚDictÚAnyÚListÚOptionalN)Úget_database_connectionZfirst_stepszFirst Stepsz Complete the onboarding tutorialZlife_milestoneé   ZgraduationcapF)ÚkeyÚnameÚdescÚcategoryÚrewardÚiconÚhiddenÚfirst_day_schoolzFirst Day of SchoolzStart elementary schoolé
   ZbookÚgraduate_hszHigh School GraduatezGraduate from high schoolÚgraduate_collegezCollege DegreezGraduate from collegeé2   ÚscrollÚgraduate_masterszMaster ScholarzComplete a master's degreeéK   ZbrainÚgraduate_phdzDoctor of Philosophyz
Earn a PhDéd   ZcrownÚget_marriedzHappily Ever AfterzGet marriedé   ZheartÚ
have_childz
New ParentzHave your first childé(   zfigure.2Ú
live_to_50zHalf CenturyzLive to 50 years oldé   ZstarÚlive_to_100zCentury ClubzLive to 100 years oldéÈ   z	star.fillÚ	first_jobzWorking ClasszGet your first jobÚcareerZ	briefcaseÚ	promotionzClimbing the LadderzGet promotedzarrow.upÚbecome_managerzManagement MaterialzBecome a managerzperson.2Ú
become_ceozCorner OfficezBecome a CEOZ	earn_100kzSix FigureszEarn $100,000 in a yearzdollarsign.circleÚearn_1m_lifetimeZMillionairez Earn $1,000,000 in your lifetimeZbanknoteÚearn_10m_lifetimezMulti-Millionairez!Earn $10,000,000 in your lifetimeéú   zbanknote.fillZperfect_performancezEmployee of the YearzAchieve 100% job performanceZtrophyÚmake_first_friendzSocial Butterfly BeginszMake your first friendÚrelationshipÚpersonÚbest_friendzBest Friends ForeverzReach 100 affinity with someonez
heart.fillÚdate_10_peoplezDating AroundzDate 10 different peoplezheart.multipleÚ
first_kissz
First KisszShare your first kissé   zheart.circleÚgolden_anniversaryzGolden AnniversaryzStay married for 50 yearsZsparklesÚfive_childrenz
Big FamilyzHave 5 childrenz
house.fillÚpopularzMr/Ms PopularzHave 10 friendsé#   zperson.3Úfirst_purchasezFirst PurchasezBuy your first itemZ
collectioné   ZbagÚown_25_itemsZ	CollectorzOwn 25 itemszsquare.grid.3x3Úown_50_itemsZHoarderzOwn 50 itemszsquare.grid.4x3Úown_100_itemszUltimate CollectorzOwn 100 itemséP   zsquare.stack.3d.upÚprestige_100zRising StarzReach 100 prestigeÚprestige_500zCelebrity StatuszReach 500 prestigezstar.circleÚmax_prestigezMaximum PrestigezReach 1000 prestigeé–   zstar.circle.fillÚ	die_at_69ZNicezDie at exactly 69 years oldÚsecretzface.smilingTÚfired_3_timeszProfessional QuitterzGet fired 3 timeszxmark.circleÚnever_marryzForever Alonez Complete a life without marryingzperson.fillÚmarry_3_timeszSerial MonogamistzGet married 3 different timeszarrow.triangle.2.circlepathÚdie_poorzBroke at DeathzDie with less than $100zbanknote.slashÚdie_richzDied WealthyzDie with over $1,000,000Zperfect_healthz
Health Nutz$Maintain 100% health for a full yearzheart.text.square.fillZ
workaholicZ
WorkaholiczWork 80+ hours in a weekZ	deskclockZearly_retirementzEarly RetirementzRetire before age 40zbeach.umbrellaÚ
straight_azStraight A StudentzGraduate with a 4.0 GPAza.circle.fillZdropoutzSchool DropoutzDrop out of high schoolzbook.closedZ
no_friendsz	Lone Wolfz'Reach age 30 without making any friendszperson.fill.questionmarkc                  C   sú   d} d}zÒzpt ƒ } |  ¡ }tD ]:}| d|d |d |d |d |d |d |d	 f¡ q|  ¡  t d
ttƒ› d�¡ W nD ty¾ } z,| r–|  	¡  tj
d|› �dd� W Y d}~n
d}~0 0 W |rÎ| ¡  | rö|  ¡  n|rè| ¡  | rô|  ¡  0 dS )z-Insert achievement definitions into database.NaŽ  INSERT INTO achievements
                   (key_name, display_name, description, category, diamond_reward, icon_name, hidden)
                   VALUES (%s, %s, %s, %s, %s, %s, %s) AS new_ach
                   ON DUPLICATE KEY UPDATE
                   display_name=new_ach.display_name,
                   description=new_ach.description,
                   diamond_reward=new_ach.diamond_rewardr   r	   r
   r   r   r   r   zInitialized z achievementsz!Error initializing achievements: T©Úexc_info)r   ÚcursorÚACHIEVEMENT_DEFINITIONSÚexecuteÚcommitÚloggingÚinfoÚlenÚ	ExceptionÚrollbackÚerrorÚclose)ÚconnrH   ZachÚe© rU   ú7/var/www/lichun.app/lichun/ws/retention/achievements.pyÚinitialize_achievementsv   s4    ÿø,
ýrW   )Ú	player_idÚ
event_typeÚ
event_dataÚreturnc              
   C   s®  |du ri }g }d}d}�zp�zêt ƒ }|jdd�}z@| d| f¡ | ¡ }|spg W W W |rb| ¡  |rn| ¡  S W nn tjjjyà } zPdt	|ƒv rÊt
 d¡ g W  Y d}~W W |r¼| ¡  |rÈ| ¡  S ‚ W Y d}~n
d}~0 0 | d| f¡ | ¡ }|dk�r| t| d	||ƒ¡ �n|d
k�r| dd¡}	d|	 ¡ v �rz| t| d||ƒ¡ | dd¡dk�r | t| d||ƒ¡ n†d|	 ¡ v �s–d|	 ¡ v �r¬| t| d||ƒ¡ nTd|	 ¡ v �rÐ| t| d||ƒ¡ n0d|	 ¡ v �sìd|	 ¡ v �r0| t| d||ƒ¡ �n,|dk�r:|�r0|d dk�r0| t| d||ƒ¡ �nö|dk�r´| t| d||ƒ¡ | d d¡ ¡ }
d!|
v �rˆ| t| d"||ƒ¡ n(d#|
v �sœd$|
v �r0| t| d%||ƒ¡ �n||d&k�rú| t| d'||ƒ¡ |�r0|d( �r0| t| d)||ƒ¡ �n6|d*k�rZ|�r.|d+ dk�r.| t| d,||ƒ¡ n(|�r0|d+ d-k�r0| t| d.||ƒ¡ �nÖ|d/k�r|| t| d/||ƒ¡ �n´|d0k�rø| d1|d1 ¡}|d2k�r¶| t| d3||ƒ¡ n>|d4k�rÖ| t| d5||ƒ¡ n|d6k�r0| t| d7||ƒ¡ �n8|d8k�r¶|d9 d6k �r&| t| d:||ƒ¡ n"|d9 d;k�rH| t| d<||ƒ¡ |�r0|d( �sl| t| d=||ƒ¡ |d> d;k�r�| t| d?||ƒ¡ n"|d> d@k�r0| t| dA||ƒ¡ �nz|dBk�r|�rê|dC dk�rê| t| dD||ƒ¡ n(|�r0|dC dEk�r0| t| dF||ƒ¡ �n|dGk�rÈ| dH| f¡ | ¡ }|�rD|dI nd}|dk�rh| t| dJ||ƒ¡ n^|dKk�rˆ| t| dL||ƒ¡ n>|d2k�r¨| t| dM||ƒ¡ n|d6k�r0| t| dN||ƒ¡ nh|dOk�rþ| dPd¡}|d6k�r0| t| dQ||ƒ¡ n2|dRk�r0|�r0|dS dTk�r0| t| dU||ƒ¡ |dV d6k�rR| t| dW||ƒ¡ |dV dXk�rt| t| dY||ƒ¡ |dV dZk�r–| t| d[||ƒ¡ |�r¾|d\ dEk�r¾| t| d]||ƒ¡ |�ræ|d^ d2k�ræ| t| d_||ƒ¡ |W W |�rú| ¡  |�r| ¡  S  t�yj } zHtjd`| › da|› �ddb� g W  Y d}~W |�rR| ¡  |�r`| ¡  S d}~0 0 W |�r|| ¡  |�rª| ¡  n|�rš| ¡  |�r¨| ¡  0 dS )ca  
    Check if any achievements should be unlocked based on event.

    Args:
        player_id: The player's ID
        event_type: Type of event that occurred
        event_data: Additional event data

    Returns:
        List of unlocked achievements
    NT©Ú
dictionaryz®SELECT age, money, diamonds, prestige, health, happiness,
                          educationLevel, occupation, occupationSalary
                   FROM players WHERE id = %sZ42S02zDPlayers table not found - achievements disabled until migration runsz4SELECT * FROM player_statistics WHERE player_id = %sZstart_schoolr   ZgraduateÚlevelÚ Úhigh_schoolr   Úgpar   g      @rE   ÚcollegeZ
universityr   Zmasterr   ZphdZ	doctorater   Zget_jobZ	job_counté   r!   r#   ÚtitleÚmanagerr$   Zceozchief executiver%   Úmarriager   Zever_marriedrB   Zbirth_childZchildren_countr   r5   r1   r.   ÚbirthdayÚager   r   éE   r>   r   r   ZdeathÚmoneyrC   i@B rD   rA   Zlifetime_earningsr&   i€–˜ r'   Zmake_friendZfriends_countr)   r   r2   Zpurchase_itemzWSELECT COUNT(DISTINCT item_id) as item_count FROM player_inventory WHERE player_id = %sÚ
item_countr4   r   r6   r7   r8   Zaffinity_milestoneÚaffinityr,   ÚfiredZtimes_firedé   r@   Úprestiger:   iô  r;   iè  r<   Zpeople_datedr-   Zyears_marriedr0   z'Error checking achievements for player ú: rF   )r   rH   rJ   ÚfetchonerR   ÚmysqlÚ	connectorÚerrorsÚProgrammingErrorÚstrÚloggerÚwarningÚextendÚcheck_and_unlockÚgetÚlowerrO   rL   rQ   )rX   rY   rZ   ÚunlockedrS   rH   ÚplayerrT   Ústatsr^   rd   rh   Úresultrk   rl   rU   rU   rV   Úcheck_achievements›   s4   ü € ê
 € îþ















þ






öú
ýr�   )rX   Úachievement_keyr[   c              
   C   s(  zÞ|  d|f¡ | ¡ }|s2t d|› �¡ g W S |  d| |d f¡ | ¡ }|rXg W S |  d| |d |d f¡ ddlm} || d	|› �|d
 ƒ | ¡  t d| › d|› �¡ |d |d |d |d |d |d
 dœgW S  t�y" } z*tj	d|› d|› �dd� g W  Y d}~S d}~0 0 dS )ar  
    Check if player has unlocked achievement. If not yet unlocked, unlock it.

    Args:
        player_id: The player's ID
        achievement_key: Achievement key name
        cursor: Database cursor (for efficiency)
        conn: Database connection (for commit)

    Returns:
        List containing the achievement dict if newly unlocked, empty list otherwise
    z.SELECT * FROM achievements WHERE key_name = %szAchievement not found: zqSELECT * FROM player_achievements
               WHERE player_id = %s AND achievement_id = %s AND unlocked = TRUEÚidzçINSERT INTO player_achievements
               (player_id, achievement_id, progress, unlocked, unlock_date)
               VALUES (%s, %s, %s, TRUE, NOW())
               ON DUPLICATE KEY UPDATE unlocked = TRUE, unlock_date = NOW()Zprogress_maxr   )Úaward_diamondsZachievement_Zdiamond_rewardzPlayer z unlocked achievement: Zkey_nameZdisplay_nameÚdescriptionZ	icon_name)rƒ   r   r	   r…   r   r   zError unlocking achievement rp   TrF   N)
rJ   rq   rL   rx   Zmonetization.diamond_economyr„   rK   rM   rO   rQ   )rX   r‚   rH   rS   ZachievementZ
player_achr„   rT   rU   rU   rV   rz   X  sD    þ
ýû	ú
	rz   )rX   r[   c              
   C   s@  d}d}�zz†t ƒ }|jdd�}| d| f¡ | ¡ }| d| f¡ | ¡ }||ttƒt|ƒtt|ƒttƒ d ƒdœW W |r†| ¡  |r’| ¡  S  t� yü } zPt	j
d| › d	|› �dd
� g g ddddœW  Y d}~W |ræ| ¡  |rò| ¡  S d}~0 0 W |�r| ¡  |�r<| ¡  n|�r,| ¡  |�r:| ¡  0 dS )z­
    Get all achievements and player's progress.

    Args:
        player_id: The player's ID

    Returns:
        Dict with 'unlocked' and 'locked' achievement lists
    NTr\   zîSELECT a.*, pa.unlock_date
               FROM achievements a
               JOIN player_achievements pa ON a.id = pa.achievement_id
               WHERE pa.player_id = %s AND pa.unlocked = TRUE
               ORDER BY pa.unlock_date DESCa8  SELECT a.*
               FROM achievements a
               WHERE a.id NOT IN (
                   SELECT achievement_id FROM player_achievements
                   WHERE player_id = %s AND unlocked = TRUE
               )
               AND a.hidden = FALSE
               ORDER BY a.category, a.diamond_rewardr   )r}   ÚlockedZtotal_countZunlocked_countZprogress_percentz&Error getting achievements for player rp   rF   r   )r   rH   rJ   ÚfetchallrN   rI   ÚintrR   rO   rL   rQ   )rX   rS   rH   r}   r†   rT   rU   rU   rV   Úget_player_achievements›  sT    
ú÷ûðú
ýr‰   )N)Ú__doc__Útypingr   r   r   r   rL   Zmysql.connector.errorsrr   Údatabaser   Ú	getLoggerÚ__name__rw   rI   rW   rˆ   rv   r�   rz   r‰   rU   rU   rU   rV   Ú<module>   s  
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ e%" >C