a
    w^iÆ;  ã                   @   sè   d Z ddlZddlZddlmZ ddlZddlmZmZm	Z	m
Z
mZmZmZmZmZmZmZmZmZmZmZmZmZ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% ddl&m'Z' ddl(m(Z( e )e*¡Z+dd	„ Z,ddd„Z-dS )aI  
Game Loop Manager

This module contains the core game simulation loop and iteration utilities.
It handles:
- Main game loop (initLifeSim): Processes each game tick, updates player state,
  checks events, and manages time progression
- Game iteration (iterateGames): Loads and processes all active games for
  offline simulation
é    N)Údate)ÚsaveGameAsyncÚloadGameAsyncÚ	loadGamesÚ	updateAgeÚhandleDeathÚgetPeakEnergyÚupdateDeathChanceÚget_dailyPlanÚ
get_seasonÚgetIntradayActivityÚparseLocationsÚparseOneTimeEventsÚ	updateBioÚmessageFunctionÚhandleUpdatesÚhandleFinancesÚhandleMoodsÚhandleEducationÚ	handleJobÚhandleRelationshipsÚhandleHabitChangesÚ
set_avatarÚsendRandomCharacterMessageÚcheckTutorialEventsÚcheckDayEventsÚcheckDilemmas)ÚBatchedUpdateÚsendEventMessageÚsendUserInfoÚsendDict)Úget_applicable_events)Úconfigc                  Ã   s®   ddl } | j}tƒ }|rªt|ƒdkrª|D ]€}| |d ¡}|du sL|jdkr(t|d ƒI dH }|jjdkr(t	d|jj
 d |jj d t|jƒ d ƒ td|ƒI dH  q(dS )	zõ
    Iterate through all saved games and process one tick for disconnected players.

    This function loads all games from the database and runs offline simulation
    for players who are disconnected. Used for background game progression.
    r   NÚdisconnectedÚaliveziterating game Ú ÚminF)ÚappÚplayerRecordsr   ÚlenÚgetÚ
connectionr   ÚcÚstatusÚprintÚ	firstnameÚlastnameÚstrÚminuteOfHourÚinitLifeSim)r'   r(   ZgamesZgameÚcached_playerZ	foundGame© r5   ú7/var/www/lichun.app/lichun/ws/game_loop/loop_manager.pyÚiterateGames#   s    .r7   Fc                 Ã   s
  ddl m} ddl}|j}| r,| jdkr,dS d}|r:|}n| | j¡}| jd7  _|j|j dksj|�
r|jdkr~|j	dks„|�
r|j
j	d	krªt|ƒ t|ƒI dH  dS | jd7  _t|jƒd
 t|jƒ |_|jdkrâd|_|jdk�	rªtƒ }| d|j¡ | d|j¡ | d|j¡ | d|j¡ | d|j
j¡ | d|j
j¡ | d|j
j¡ | d|j
j¡ | d|j
j¡ | d|j
j¡ | d|j
j¡ | d|j
j¡ | d|j
j¡ | d|j
j¡ | d|j
j¡ | d|j
j ¡ | d|j¡ | !¡ }d|_"| jd7  _t#|ƒ}|j$dk�r:t%| |ƒI dH  |jdk�rúd|_|j&dk�r`d|_&n| j&d7  _&|j'd k�r‚d|_'n| j'd7  _'t (td!ddƒ )¡ |j& d ¡ *d"¡|_t+|j ,d#¡d ƒ|_-t.|j-ƒ|_/t|jƒ|_t|jƒd$ |_g d%¢|j'd  |_d&|j& |_0|j&d'k�r.d(|j0 |_0|j&d' |_1|j&d'k �rRd(|j& |_1|j&d&k�rr|j&d'k �rrd)|_2nd|_2t3|ƒI dH  dd*l4m5}	 |j6D ]`}
|
jd+k�r¶|	|
|d,ƒ n@|
jd-k�rÐ|	|
|d.ƒ n&|
jd/k �rê|	|
|d0ƒ n|	|
|d1ƒ �q˜|j'dk�r0|jdk�r0t7dt8|j6ƒƒD ]h}t9|j6| ƒ t:||j6| ƒ t;|j6| ƒ t<||j6| ƒ t=||j6| ƒ t>|j6| ƒ|j6| _?�q"t9|j
ƒ t:||j
ƒ t=||j
ƒ t<||j
ƒ t;|j
ƒ t@||j
ƒ t>|j
ƒ|j
_?dd2l4mA} |jBD ]}||ƒ �qðt|ƒI dH  tCd3ƒ tC|jDƒ tE|| ƒI dH  |jdk�rpd|_FtG|j
ƒ |j
 j|j
jd4k �rfdnd7  _|j
jHdk�r¨|j
jI�r¨|j
jI J¡ d5 |_"tE|| ƒI dH  |j
jHdk�r&|j
jHd dk�r&|j
 jKd7  _KtL|j
ƒ|j
_M|j
jI J¡ d6 t|j
jKƒ d7 |_"t|ƒI dH  tE|| ƒI dH  |j
jMd4 tN N¡ d4 k�sN|j
jKd8k�rˆd	|j
_	|j
jI J¡ d9 t|j
jKƒ d: |_"tE|| ƒI dH  tO|d;ƒ }�rà|j$dk�rÄ|jP |jQ¡ t%| |ƒI dH  n|j$d<k�ràt%| |ƒI dH  tR||j
ƒ|_
|jd=k�r|j
j |d< t7dt8|j6ƒƒD ]X}|j6| j	d>k�rV|j6| jSdk�rV|j6| jSd? |j6| _StR||j6| ƒ|j6|< �qtT||j
ƒ|_
t7dt8|j6ƒƒD ]}tT||j6| ƒ|j6|< �qŽtU|ƒ}tV|ƒ tW|ƒ}|jX�rt8|jXƒdk�r|jX Yd¡|_"|jD Z|j"¡ t%| t[d@|j"|d)ƒƒI dH  dA|_"|j\�r8tE|| ƒI dH  d|_\|jt]j^k �	r^t_|d;ƒ }�r |j$dk�r‚|jP |jQ¡ t%| |ƒI dH  n|j$d<k�	r^t%| |ƒI dH  n¾t`|ƒ}|D ]°}zh|dB |d;ƒ}|�	r|j$dk�rò|jP |jQ¡ t%| |ƒI dH  n|j$d<k�	rt%| |ƒI dH  W  �	q^W n@ ta�	yX } z&tb cdC|dD › dE|› �¡ W Y d}~n
d}~0 0 �q¬td|ƒ }�	r|t%| |ƒI dH  te||| ƒ}|�	rÎ|i k�	rÎtf| |ƒI dH  n$|jd=k�	rÎtf| dF|jdGœƒI dH  |�
rdH|_gdI|_|jh jid7  _itCdJt|jhjiƒ dK ƒ t|ƒI dH  dS dS )LuP  
    Main game simulation loop - processes one game tick.

    This function handles all game logic updates including:
    - Time progression (minutes â†’ hours â†’ days)
    - Character stat updates (energy, hunger, mood, money)
    - Event checking and triggering
    - Daily/weekly/hourly tick processing
    - Location and activity updates
    - Client synchronization

    Args:
        websocket: The WebSocket connection (or False for offline processing)
        oneTimePlayer: Optional player object for one-time offline updates

    Returns:
        False to indicate completion
    r   )Úcall_event_handlerNÚDUMMY_USER_IDFé   ÚactiveÚcreatingÚdeadú:é<   r   Ú	hourOfDayr2   ÚweekDayTextÚenergyÚ
calcEnergyÚmoneyÚdiamondsÚprestigeÚstressÚ	happinessÚ
occupationÚlocationÚ	schedulesÚintraDayMessageÚ	dailyPlanÚ	gameSpeedÚmessageEventé   im  é   iæ  z%m-%dÚ-z:00)ÚSundayÚMondayÚTuesdayÚ	WednesdayÚThursdayÚFridayÚSaturdayé˜   éô   éy   T)Úset_mood_stateéF   ZstressedéP   Zgreaté   ÚbadÚneutral)Údecay_messaging_modifierszweekly tickéd   z/ is starting their life, full of opportunities.z is z years old.éx   z has died at the age of z years.ÚcheckÚquestionEventé
   r$   é   ÚqueueÚ ÚfunczError in event Úidz: Úu)Útyper2   r#   Úinactivezoffline for z minutes, saving game)jÚevent_handlersr8   r'   r(   ÚuserIDr*   ÚticksrN   Ú
controllerr-   r,   r   r   r2   r1   r@   Útimer   Úaddr   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   Úto_dictÚmessager   ro   r   Ú	dayOfYearÚ	dayOfWeekÚfromordinalÚ	toordinalÚstrftimeÚintÚsplitÚmonthOfYearr   ÚseasonÚdaysUntilSchoolEndsÚdaysSinceSchoolStartedÚsummerVacationr   Úmessaging_styler]   ÚrÚranger)   r   r   r   r   r   r   Úimager   rc   ÚrelDatar.   Ú
messageLogr   ÚdayEventr   ÚageDaysr/   Ú
capitalizeÚageYearsr	   ÚdeathChanceÚrandomr   Úeventsrm   r
   Úfamiliarityr   r   r   r   ÚmessageQueueÚpopÚappendr   ÚupdateClientr"   ÚSPEED_QUESTION_PAUSEr   r!   Ú	ExceptionÚloggerÚerrorr   r   r    r+   ÚofflineStatsÚminutesOffline)Ú	websocketZoneTimePlayerr8   r'   r(   ÚplayerÚbatchÚupdateObjectÚresultr]   Ú	characterÚirc   ÚrelZapplicable_eventsÚ
event_infoÚer5   r5   r6   r3   <   sd   
(





" "("$4r3   )F).Ú__doc__Úasyncior�   Údatetimer   ÚloggingÚ	functionsr   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   Úserver.websocket_messagingr   r   r   r    Úevent_registryr!   r"   Ú	getLoggerÚ__name__r™   r7   r3   r5   r5   r5   r6   Ú<module>   s   p	
