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 }|rt|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rt| t|I dH  dS | jd7  _t|jd
 t|j |_|jdkrd|_|jdk	rt }|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rd|_|j&dkr`d|_&n| j&d7  _&|j'd krd|_'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 ]}|| qt|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
jIJ d5 |_"tE|| I dH  |j
jHdkr&|j
jHd dkr&|j
 jKd7  _KtL|j
|j
_M|j
jIJ d6 t|j
jK d7 |_"t|I dH  tE|| I dH  |j
jMd4 tNN d4 ksN|j
jKd8krd	|j
_	|j
jIJ 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rt%| |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|< qtU|}tV| tW|}|jXrt8|jXdkr|jXYd|_"|jDZ|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  nt`|}|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&tbcdC|dD  dE|  W Y d}~n
d}~0 0 qtd| }	r|t%| |I dH  te||| }|	r|i k	rtf| |I dH  n$|jd=k	rtf| 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_stateF   ZstressedP   Zgreat   badneutral)decay_messaging_modifierszweekly tickd   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	
