int CZone::GetWeatherElement() { static uint8 Element[] = { 0, //WEATHER_NONE 0, //WEATHER_SUNSHINE 0, //WEATHER_CLOUDS 0, //WEATHER_FOG 1, //WEATHER_HOT_SPELL 1, //WEATHER_HEAT_WAVE 6, //WEATHER_RAIN 6, //WEATHER_SQUALL 4, //WEATHER_DUST_STORM 4, //WEATHER_SAND_STORM 3, //WEATHER_WIND 3, //WEATHER_GALES 2, //WEATHER_SNOW 2, //WEATHER_BLIZZARDS 5, //WEATHER_THUNDER 5, //WEATHER_THUNDERSTORMS 7, //WEATHER_AURORAS 7, //WEATHER_STELLAR_GLARE 8, //WEATHER_GLOOM 8, //WEATHER_DARKNESS }; return Element[GetWeather()]; }
int main(int argc, char **argv) { // Compute the size of the screen int pixelX = 320; int pixelY = 256; int fontSize = 1; // 0=6x8 1=8x8 GetWeather(); LCD_screen_init(pixelX,pixelY, fontSize); // MODE SET LCD_mode( MODE_OR ); // DISPLAY MODE //LCD_display_mode( DM_TEXT + DM_GRAPHICS ); LCD_display_mode( DM_GRAPHICS ); int i; // Erase graphic screen LCD_set_address_pointer( LCD_getBaseGraphic() ); LCD_auto_write_start(); for (i=0;i<LCD_getGraphicScreenSize();i++) { LCD_auto_write( 0x00 ); } LCD_auto_write_stop(); LCD_set_address_pointer( LCD_getBaseText() ); char buffer[256]; Puts(1,122, "Raspberry Pi LCD - by joaquim.org"); // current date/time based on current system time_t now = time(0); struct tm *tm_struct = localtime(&now); sprintf(buffer,"%02d:%02d",tm_struct->tm_hour, tm_struct->tm_min); WriteText(45, 20, buffer, 2); sprintf(buffer,"%s %d %s %04d",weekday[tm_struct->tm_wday], tm_struct->tm_mday, month[tm_struct->tm_mon], 1900 + tm_struct->tm_year); WriteText(5, 2, buffer, 1); WriteText(5, 50, meteo_ico, 3); WriteText(30, 50, "'", 3); sprintf(buffer,"%s/%s", meteo_min, meteo_max); WriteText(50, 55, buffer, 1); WriteText(85, 49, "*", 3); WriteText(1, 75, meteo_obs, 1); return 0; } // main
void CSector::OnTick(int iPulseCount) { ADDTOCALLSTACK_INTENSIVE("CSector::OnTick"); // CWorld gives OnTick() to all CSectors. EXC_TRY("Tick"); EXC_SET("light change"); // do not tick sectors on maps not supported by server if ( !g_MapList.m_maps[m_map] ) return; // Check for light change before putting the sector to sleep, since in other case the // world light levels will be shitty bool fEnvironChange = false; bool fLightChange = false; bool fSleeping = false; if ( ! ( iPulseCount & 0x7f )) // 30 seconds or so. { // check for local light level change ? BYTE blightprv = m_Env.m_Light; m_Env.m_Light = GetLightCalc( false ); if ( m_Env.m_Light != blightprv ) { fEnvironChange = true; fLightChange = true; } } EXC_SET("sector sleeping?"); size_t clients = m_Chars_Active.HasClients(); if ( clients <= 0 ) // having no clients inside { // Put the sector to sleep if no clients been here in a while. fSleeping = IsSectorSleeping(); if ( fSleeping ) { if ( !g_Cfg.m_iSectorSleepMask ) return; if (( iPulseCount & g_Cfg.m_iSectorSleepMask ) != ( GetIndex() & g_Cfg.m_iSectorSleepMask )) return; } } EXC_SET("sound effects"); // random weather noises and effects. SOUND_TYPE sound = 0; bool fWeatherChange = false; int iRegionPeriodic = 0; if ( ! ( iPulseCount & 0x7f )) // 30 seconds or so. { // Only do this every x minutes or so (TICK_PER_SEC) // check for local weather change ? WEATHER_TYPE weatherprv = m_Env.m_Weather; if ( ! Calc_GetRandVal( 30 )) // change less often { m_Env.m_Weather = GetWeatherCalc(); if ( weatherprv != m_Env.m_Weather ) { fWeatherChange = true; fEnvironChange = true; } } // Random area noises. Only do if clients about. if ( clients > 0 ) { iRegionPeriodic = 2; static const SOUND_TYPE sm_SfxRain[] = { 0x10, 0x11 }; static const SOUND_TYPE sm_SfxWind[] = { 0x14, 0x15, 0x16 }; static const SOUND_TYPE sm_SfxThunder[] = { 0x28, 0x29 , 0x206 }; // Lightning ? // wind, rain, switch ( GetWeather() ) { case WEATHER_CLOUDY: break; case WEATHER_SNOW: if ( ! Calc_GetRandVal(5) ) sound = sm_SfxWind[ Calc_GetRandVal( COUNTOF( sm_SfxWind )) ]; break; case WEATHER_RAIN: { int iVal = Calc_GetRandVal(30); if ( iVal < 5 ) { // Mess up the light levels for a sec.. LightFlash(); sound = sm_SfxThunder[ Calc_GetRandVal( COUNTOF( sm_SfxThunder )) ]; } else if ( iVal < 10 ) sound = sm_SfxRain[ Calc_GetRandVal( COUNTOF( sm_SfxRain )) ]; else if ( iVal < 15 ) sound = sm_SfxWind[ Calc_GetRandVal( COUNTOF( sm_SfxWind )) ]; } break; default: break; } } } // regen all creatures and do AI ProfileTask charactersTask(PROFILE_CHARS); //pChar = STATIC_CAST <CChar*>( m_Chars_Active.GetHead()); CChar * pCharNext = NULL; CChar * pChar = dynamic_cast <CChar*>( m_Chars_Active.GetHead()); for ( ; pChar != NULL; pChar = pCharNext ) { EXC_TRYSUB("TickChar"); pCharNext = pChar->GetNext(); if (( fEnvironChange ) && ( IsTrigUsed(TRIGGER_ENVIRONCHANGE) )) pChar->OnTrigger(CTRIG_EnvironChange, pChar); if ( pChar->IsClient()) { CClient * pClient = pChar->GetClient(); ASSERT( pClient ); if ( sound ) pClient->addSound(sound, pChar); if ( fLightChange && ! pChar->IsStatFlag( STATF_DEAD | STATF_NightSight )) pClient->addLight(); if ( fWeatherChange ) pClient->addWeather(GetWeather()); if ( iRegionPeriodic && pChar->m_pArea ) { if (( iRegionPeriodic == 2 )&&( IsTrigUsed(TRIGGER_REGPERIODIC) )) { pChar->m_pArea->OnRegionTrigger( pChar, RTRIG_REGPERIODIC ); iRegionPeriodic--; } if ( IsTrigUsed(TRIGGER_CLIPERIODIC) ) pChar->m_pArea->OnRegionTrigger( pChar, RTRIG_CLIPERIODIC ); } } // Can only die on your own tick. if ( !pChar->OnTick() ) pChar->Delete(); EXC_CATCHSUB("Sector"); EXC_DEBUGSUB_START; CPointMap pt = GetBasePoint(); g_Log.EventDebug("char 0%lx '%s'\n", static_cast<DWORD>(pChar->GetUID()), pChar->GetName()); g_Log.EventDebug("sector #%d [%d,%d,%d,%d]\n", GetIndex(), pt.m_x, pt.m_y, pt.m_z, pt.m_map); EXC_DEBUGSUB_END; } // decay items on ground = time out spells / gates etc.. etc.. // No need to check these so often ! ProfileTask itemsTask(PROFILE_ITEMS); CItem * pItemNext = NULL; CItem * pItem = dynamic_cast <CItem*>( m_Items_Timer.GetHead()); for ( ; pItem != NULL; pItem = pItemNext ) { EXC_TRYSUB("TickItem"); pItemNext = pItem->GetNext(); EXC_SETSUB("TimerExpired"); if ( pItem->IsTimerExpired() ) { EXC_SETSUB("ItemTick"); if ( !pItem->OnTick() ) { EXC_SETSUB("ItemDelete"); pItem->Delete(); } else { EXC_SETSUB("TimerExpired2"); if ( pItem->IsTimerExpired() ) // forgot to clear the timer.? strange. { EXC_SETSUB("SetTimeout"); pItem->SetTimeout(-1); } } } EXC_SETSUB("UpdateFlags"); pItem->OnTickStatusUpdate(); #ifdef _WIN32 EXC_CATCHSUB("Sector"); EXC_DEBUGSUB_START; CPointMap pt = GetBasePoint(); g_Log.EventError("item 0%lx '%s' [timer=%lld, type=%lld]\n", static_cast<DWORD>(pItem->GetUID()), pItem->GetName(), pItem->GetTimerAdjusted(), static_cast<int>(pItem->GetType())); g_Log.EventError("sector #%d [%d,%d,%d,%d]\n", GetIndex(), pt.m_x, pt.m_y, pt.m_z, pt.m_map); EXC_DEBUGSUB_END; #else } #ifndef _DEBUG catch ( const CGrayError& e )
bool CSector::r_WriteVal( LPCTSTR pszKey, CGString & sVal, CTextConsole * pSrc ) { ADDTOCALLSTACK("CSector::r_WriteVal"); EXC_TRY("WriteVal"); static const CValStr sm_ComplexityTitles[] = { { "HIGH", INT_MIN }, // speech can be very complex if low char count { "MEDIUM", 5 }, { "LOW", 10 }, { NULL, INT_MAX } }; switch ( FindTableHeadSorted( pszKey, sm_szLoadKeys, COUNTOF( sm_szLoadKeys )-1 )) { case SC_CLIENTS: sVal.FormatVal(m_Chars_Active.HasClients()); return true; case SC_COLDCHANCE: sVal.FormatVal( GetColdChance()); return( true ); case SC_COMPLEXITY: if ( pszKey[10] == '.' ) { pszKey += 11; sVal = ( ! strcmpi( pszKey, sm_ComplexityTitles->FindName( GetCharComplexity()))) ? "1" : "0"; return( true ); } sVal.FormatVal( GetCharComplexity()); return( true ); case SC_FLAGS: sVal.FormatHex(m_dwFlags); return( true ); case SC_LIGHT: sVal.FormatVal(GetLight()); return true; case SC_LOCALTIME: sVal = GetLocalGameTime(); return( true ); case SC_LOCALTOD: sVal.FormatVal( GetLocalTime()); return( true ); case SC_NUMBER: sVal.FormatVal(m_index); return( true ); case SC_ISDARK: sVal.FormatVal( IsDark() ); return( true ); case SC_ISNIGHTTIME: { int iMinutes = GetLocalTime(); sVal = ( iMinutes < 7*60 || iMinutes > (9+12)*60 ) ? "1" : "0"; } return( true ); case SC_RAINCHANCE: sVal.FormatVal( GetRainChance()); return( true ); case SC_ITEMCOUNT: sVal.FormatVal(GetItemComplexity()); return true; case SC_SEASON: sVal.FormatVal(static_cast<int>(GetSeason())); return true; case SC_WEATHER: sVal.FormatVal(static_cast<int>(GetWeather())); return true; } EXC_CATCH; EXC_DEBUG_START; EXC_ADD_KEYRET(pSrc); EXC_DEBUG_END; return false; }
BYTE CSector::GetLightCalc( bool fQuickSet ) const { ADDTOCALLSTACK("CSector::GetLightCalc"); // What is the light level default here in this sector. if ( g_Cfg.m_bAllowLightOverride && IsLightOverriden() ) return m_Env.m_Light; if ( IsInDungeon() ) return static_cast<unsigned char>(g_Cfg.m_iLightDungeon); int localtime = GetLocalTime(); if ( !g_Cfg.m_bAllowLightOverride ) { // Normalize time: // convert 0=midnight .. (23*60)+59=midnight // to 0=day .. 12*60=night if ( localtime < 12*60 ) localtime = 12*60 - localtime; else localtime -= 12*60; // 0... y ...lightnight // 0... x ...12*60 int iTargLight = ((localtime * ( g_Cfg.m_iLightNight - g_Cfg.m_iLightDay ))/(12*60) + g_Cfg.m_iLightDay); if ( iTargLight < LIGHT_BRIGHT ) iTargLight = LIGHT_BRIGHT; if ( iTargLight > LIGHT_DARK ) iTargLight = LIGHT_DARK; return static_cast<unsigned char>(iTargLight); } int hour = ( localtime / ( 60)) % 24; bool fNight = ( hour < 6 || hour > 12+8 ); // Is it night or day ? int iTargLight = (fNight) ? g_Cfg.m_iLightNight : g_Cfg.m_iLightDay; // Target light level. // Check for clouds...if it is cloudy, then we don't even need to check for the effects of the moons... if ( GetWeather()) { // Clouds of some sort... if (fNight) iTargLight += ( Calc_GetRandVal( 2 ) + 1 ); // 1-2 light levels darker if cloudy at night else iTargLight += ( Calc_GetRandVal( 4 ) + 1 ); // 1-4 light levels darker if cloudy during the day. } if ( fNight ) { // Factor in the effects of the moons // Trammel unsigned int iTrammelPhase = g_World.GetMoonPhase( false ); // Check to see if Trammel is up here... if ( IsMoonVisible( iTrammelPhase, localtime )) { static const BYTE sm_TrammelPhaseBrightness[] = { 0, // New Moon TRAMMEL_FULL_BRIGHTNESS / 4, // Crescent Moon TRAMMEL_FULL_BRIGHTNESS / 2, // Quarter Moon ( TRAMMEL_FULL_BRIGHTNESS * 3) / 4, // Gibbous Moon TRAMMEL_FULL_BRIGHTNESS, // Full Moon ( TRAMMEL_FULL_BRIGHTNESS * 3) / 4, // Gibbous Moon TRAMMEL_FULL_BRIGHTNESS / 2, // Quarter Moon TRAMMEL_FULL_BRIGHTNESS / 4 // Crescent Moon }; ASSERT( iTrammelPhase < COUNTOF(sm_TrammelPhaseBrightness)); iTargLight -= sm_TrammelPhaseBrightness[iTrammelPhase]; } // Felucca unsigned int iFeluccaPhase = g_World.GetMoonPhase( true ); if ( IsMoonVisible( iFeluccaPhase, localtime )) { static const BYTE sm_FeluccaPhaseBrightness[] = { 0, // New Moon FELUCCA_FULL_BRIGHTNESS / 4, // Crescent Moon FELUCCA_FULL_BRIGHTNESS / 2, // Quarter Moon ( FELUCCA_FULL_BRIGHTNESS * 3) / 4, // Gibbous Moon FELUCCA_FULL_BRIGHTNESS, // Full Moon ( FELUCCA_FULL_BRIGHTNESS * 3) / 4, // Gibbous Moon FELUCCA_FULL_BRIGHTNESS / 2, // Quarter Moon FELUCCA_FULL_BRIGHTNESS / 4 // Crescent Moon }; ASSERT( iFeluccaPhase < COUNTOF(sm_FeluccaPhaseBrightness)); iTargLight -= sm_FeluccaPhaseBrightness[iFeluccaPhase]; } } if ( iTargLight < LIGHT_BRIGHT ) iTargLight = LIGHT_BRIGHT; if ( iTargLight > LIGHT_DARK ) iTargLight = LIGHT_DARK; if ( fQuickSet || m_Env.m_Light == iTargLight ) // Initializing the sector return static_cast<unsigned char>(iTargLight); // Gradual transition to global light level. if ( m_Env.m_Light > iTargLight ) return( m_Env.m_Light - 1 ); else return( m_Env.m_Light + 1 ); }
bool CSector::r_WriteVal( lpctstr pszKey, CSString & sVal, CTextConsole * pSrc ) { ADDTOCALLSTACK("CSector::r_WriteVal"); EXC_TRY("WriteVal"); static const CValStr sm_ComplexityTitles[] = { { "HIGH", INT32_MIN }, // speech can be very complex if low char count { "MEDIUM", 5 }, { "LOW", 10 }, { nullptr, INT32_MAX } }; SC_TYPE key = (SC_TYPE)FindTableHead(pszKey, sm_szLoadKeys, CountOf(sm_szLoadKeys) - 1); switch ( key ) { case SC_CANSLEEP: { pszKey += 8; bool fCheckAdjacents = Exp_GetVal(pszKey); sVal.FormatBVal(CanSleep(fCheckAdjacents)); return true; } case SC_CLIENTS: sVal.FormatSTVal(m_Chars_Active.GetClientsNumber()); return true; case SC_COLDCHANCE: sVal.FormatVal( GetColdChance()); return true; case SC_COMPLEXITY: if ( pszKey[10] == '.' ) { pszKey += 11; sVal = ( ! strcmpi( pszKey, sm_ComplexityTitles->FindName( (int)GetCharComplexity() )) ) ? "1" : "0"; return true; } sVal.FormatSTVal( GetCharComplexity() ); return true; case SC_FLAGS: sVal.FormatHex(m_dwFlags); return true; case SC_LIGHT: sVal.FormatVal(GetLight()); return true; case SC_LOCALTIME: sVal = GetLocalGameTime(); return true; case SC_LOCALTOD: sVal.FormatVal( GetLocalTime()); return true; case SC_NUMBER: sVal.FormatVal(m_index); return true; case SC_ISDARK: sVal.FormatVal( IsDark() ); return true; case SC_ISNIGHTTIME: { int iMinutes = GetLocalTime(); sVal = ( iMinutes < 7*60 || iMinutes > (9+12)*60 ) ? "1" : "0"; } return true; case SC_ISSLEEPING: sVal.FormatVal(IsSleeping()); return true; case SC_RAINCHANCE: sVal.FormatVal( GetRainChance()); return true; case SC_ITEMCOUNT: sVal.FormatSTVal(GetItemComplexity()); return true; case SC_SEASON: sVal.FormatVal((int)GetSeason()); return true; case SC_WEATHER: sVal.FormatVal((int)GetWeather()); return true; } EXC_CATCH; EXC_DEBUG_START; EXC_ADD_KEYRET(pSrc); EXC_DEBUG_END; return false; }
bool CSector::OnTick() { ADDTOCALLSTACK("CSector::OnTick"); /*Ticking sectors from CWorld * Timer is automatically updated at the end with a 30 seconds default delay * Any return before it will threat this CSector as Sleep and will make it * not tick again until a new player enters (WARNING: even if there are * players already inside). */ EXC_TRY("Tick"); // do not tick sectors on maps not supported by server if ( !g_MapList.m_maps[m_map] ) return true; EXC_SET_BLOCK("light change"); // Check for light change before putting the sector to sleep, since in other case the // world light levels will be shitty bool fEnvironChange = false; bool fLightChange = false; // check for local light level change ? byte bLightPrv = m_Env.m_Light; m_Env.m_Light = GetLightCalc( false ); if ( m_Env.m_Light != bLightPrv ) { fEnvironChange = true; fLightChange = true; } EXC_SET_BLOCK("sector sleeping?"); bool fCanSleep = CanSleep(true); int64 iCurTime = CServerTime::GetCurrentTime().GetTimeRaw(); // Put the sector to sleep if no clients been here in a while. if (fCanSleep && (g_Cfg._iSectorSleepDelay > 0)) { if (!IsSleeping()) { GoSleep(); } return true; } EXC_SET_BLOCK("sound effects"); // random weather noises and effects. SOUND_TYPE sound = 0; bool fWeatherChange = false; int iRegionPeriodic = 0; WEATHER_TYPE weatherprv = m_Env.m_Weather; if ( ! Calc_GetRandVal( 30 )) // change less often { m_Env.m_Weather = GetWeatherCalc(); if ( weatherprv != m_Env.m_Weather ) { fWeatherChange = true; fEnvironChange = true; } } // Random area noises. Only do if clients about. if ( GetClientsNumber() > 0 ) { iRegionPeriodic = 2; static const SOUND_TYPE sm_SfxRain[] = { 0x10, 0x11 }; static const SOUND_TYPE sm_SfxWind[] = { 0x14, 0x15, 0x16 }; static const SOUND_TYPE sm_SfxThunder[] = { 0x28, 0x29 , 0x206 }; // Lightning ? // wind, rain, switch ( GetWeather() ) { case WEATHER_CLOUDY: break; case WEATHER_SNOW: if ( ! Calc_GetRandVal(5) ) sound = sm_SfxWind[ Calc_GetRandVal( CountOf( sm_SfxWind )) ]; break; case WEATHER_RAIN: { int iVal = Calc_GetRandVal(30); if ( iVal < 5 ) { // Mess up the light levels for a sec.. LightFlash(); sound = sm_SfxThunder[ Calc_GetRandVal( CountOf( sm_SfxThunder )) ]; } else if ( iVal < 10 ) sound = sm_SfxRain[ Calc_GetRandVal( CountOf( sm_SfxRain )) ]; else if ( iVal < 15 ) sound = sm_SfxWind[ Calc_GetRandVal( CountOf( sm_SfxWind )) ]; } break; default: break; } } // Check environ changes and inform clients of it. ProfileTask charactersTask(PROFILE_CHARS); CChar * pCharNext = nullptr; CChar * pChar = static_cast <CChar*>( m_Chars_Active.GetHead()); for ( ; pChar != nullptr; pChar = pCharNext ) { EXC_TRYSUB("TickChar"); pCharNext = pChar->GetNext(); if (( fEnvironChange ) && ( IsTrigUsed(TRIGGER_ENVIRONCHANGE) )) pChar->OnTrigger(CTRIG_EnvironChange, pChar); if ( pChar->IsClient()) { CClient * pClient = pChar->GetClient(); ASSERT( pClient ); if ( sound ) pClient->addSound(sound, pChar); if ( fLightChange && ! pChar->IsStatFlag( STATF_DEAD | STATF_NIGHTSIGHT )) pClient->addLight(); if ( fWeatherChange ) pClient->addWeather(GetWeather()); if ( iRegionPeriodic && pChar->m_pArea ) { if ( ( iRegionPeriodic == 2 ) && IsTrigUsed(TRIGGER_REGPERIODIC)) { pChar->m_pArea->OnRegionTrigger( pChar, RTRIG_REGPERIODIC ); --iRegionPeriodic; } if ( IsTrigUsed(TRIGGER_CLIPERIODIC) ) pChar->m_pArea->OnRegionTrigger( pChar, RTRIG_CLIPERIODIC ); } } EXC_CATCHSUB("Sector"); EXC_DEBUGSUB_START; CPointMap pt = GetBasePoint(); g_Log.EventDebug("#0 char 0%x '%s'\n", (dword)(pChar->GetUID()), pChar->GetName()); g_Log.EventDebug("#0 sector #%d [%d,%d,%d,%d]\n", GetIndex(), pt.m_x, pt.m_y, pt.m_z, pt.m_map); EXC_DEBUGSUB_END; } ProfileTask overheadTask(PROFILE_OVERHEAD); EXC_SET_BLOCK("check map cache"); if (fCanSleep && m_iMapBlockCacheTime < iCurTime) // Only if the sector can sleep. { // delete the static CServerMapBlock items that have not been used recently. m_iMapBlockCacheTime = CServerTime::GetCurrentTime().GetTimeRaw() + g_Cfg.m_iMapCacheTime ; CheckMapBlockCache(); } EXC_CATCH; SetTimeoutS(30); // Sector is Awake, make it tick after 30 seconds. EXC_DEBUG_START; CPointMap pt = GetBasePoint(); g_Log.EventError("#4 sector #%d [%hd,%hd,%hhd,%hhu]\n", GetIndex(), pt.m_x, pt.m_y, pt.m_z, pt.m_map); EXC_DEBUG_END; return true; }