Exemple #1
0
CSector::CSector() : CTimedObject(PROFILE_SECTORS)
{
	m_ListenItems = 0;

	m_RainChance = 0;		// 0 to 100%
	m_ColdChance = 0;		// Will be snow if rain chance success.
	SetDefaultWeatherChance();

	m_dwFlags = 0;
	m_fSaveParity = false;
    GoSleep();    // Every sector is sleeping at start, they only awake when any player enter (this eases the load at startup).
}
Exemple #2
0
static msg_t AppThread(void *arg) {
    (void)arg;
    chRegSetThreadName("App");
#ifdef TRAIN_MODE
    uint32_t counter;
#else
    int16_t bestResult;
    int16_t result = 0;
    uint32_t tmpCode = 0;
    uint32_t newCode = 0;
    Status_t tmpStatus = stIdle;
    uint32_t SignCodeNumb = 999999;
    int32_t SignTimeoutCounter = 0;
#endif

    while(1) {
        chThdSleepMilliseconds(9);
        if(!App.Enabled) continue;  // Do nothing

        // ==== Read accelerations ====
        bool AllOperational = true;
        for(uint8_t i = 0; i < ACC_CNT; i++) {
            Acc[i].ReadAccelerations();
            if(Acc[i].IsOperational) {
//                Uart.Printf("%u %d %d %d; ", i, Acc[i].a[0], Acc[i].a[1], Acc[i].a[2]);
                // Copy accelerations to vector. Also, filter is applied here, and acceleration change is checked.
                Process.AddAcc(i, &Acc[i].a[0]);
#ifndef TRAIN_MODE
                // Prepare to compare
                bestResult = 9999;
                newCode = SignCodeNumb;
                // *** Iterate all subsigns ***
                chSysLock();// Do not switch to other thread
                for(uint8_t j = 0; j < SUBSIGN_CNT; j++) {
                    // Check if similar
                    result = Process.IsSimilar(Subsign[j], hyperRadius[j]);
                    if(result > -1) {
                        // Seems like similar
                        tmpCode = (SignCodeNumb * 100) % 1000000 + j;
                        tmpStatus = Analyze(tmpCode);
                        if((tmpStatus != stIdle) and (result < bestResult)) {
                            newCode = tmpCode;
                            App.Status = tmpStatus;
                            bestResult = result;
                            Process.CurrentSubsign = j;
                            SignTimeoutCounter = INITIAL_COUNTDOWN; // Reset timeout counter
                            Uart.Printf("%d\r\n", j);
                        } // if
                    } // if result > -1
                } // for
                chSysUnlock();
                SignCodeNumb = newCode;
#endif
            } // if operational
            else {
                Uart.Printf("Acc %u fail\r", i);
                // Try to rise from dead
                Acc[i].Init();
                if(!Acc[i].IsOperational) {
                    AllOperational = false;
                    chThdSleepMilliseconds(450);
                }
            }
        } // for i

        // Handle status depending on accelerometers state
        if(!AllOperational) App.Status = stAccFail;
        else if(App.Status == stAccFail) App.Status = stIdle; // All operational

        if(App.Status != stAccFail) {
            // Signal that 'first after power-on' measurement completed
            FirstTime = false;

            // ==== Check if time to sleep ====
            SleepTimeoutCounter--;
            if(SleepTimeoutCounter < 0) {
                SleepTimeoutCounter = 0;
//                Uart.Printf("Zzz\r");
#if defined SLEEP_ENABLED && !defined TRAIN_MODE
                GoSleep();
#endif
            }
#ifndef TRAIN_MODE
            // ==== Check if sign timed out ====
            SignTimeoutCounter--;
            if(SignTimeoutCounter < 0) {
                SignTimeoutCounter = 0;
                App.Status = stIdle;    // Reset indication
                SignCodeNumb = (SignCodeNumb * 100) % 1000000 + 99;
            }
#endif
        } // if not failure
#ifdef TRAIN_MODE
        counter++;
        if(counter >= 10) {
            counter=0;
//            Process.PrintVect();
            for(uint8_t i = 0; i < 21; i++) Uart.Printf("%d,", Process.AccVector[i]);
            Uart.Printf("\r\n");
        }
#endif
    } // while 1
        return 0;
    }
Exemple #3
0
bool CSector::r_Verb( CScript & s, CTextConsole * pSrc )
{
	ADDTOCALLSTACK("CSector::r_Verb");
	EXC_TRY("Verb");
	ASSERT(pSrc);
	int index = FindTableSorted( s.GetKey(), sm_szVerbKeys, CountOf(sm_szVerbKeys)-1 );
	switch (index)
	{
		case SEV_ALLCHARS:		// "ALLCHARS"
			v_AllChars( s, pSrc );
			break;
		case SEV_ALLCHARSIDLE:	// "ALLCHARSIDLE"
			v_AllCharsIdle( s, pSrc );
			break;
		case SEV_ALLCLIENTS:	// "ALLCLIENTS"
			v_AllClients( s, pSrc );
			break;
		case SEV_ALLITEMS:		// "ALLITEMS"
			v_AllItems( s, pSrc );
			break;
        case SEV_AWAKE:
            if (!IsSleeping())
            {
                break;
            }
            GoAwake();
            break;
		case SEV_DRY:	// "DRY"
			SetWeather( WEATHER_DRY );
			break;
		case SEV_LIGHT:
			if ( g_Cfg.m_bAllowLightOverride )
				SetLight( (s.HasArgs()) ? s.GetArgVal() : -1 );
			else
				g_Log.EventWarn("AllowLightOverride flag is disabled in sphere.ini, so sector's LIGHT property wasn't set\n");
			break;
		case SEV_RAIN:
			SetWeather(s.HasArgs() ? static_cast<WEATHER_TYPE>(s.GetArgVal()) : WEATHER_RAIN);
			break;
		case SEV_RESPAWN:
			( toupper( s.GetArgRaw()[0] ) == 'A' ) ? g_World.RespawnDeadNPCs() : RespawnDeadNPCs();
			break;
		case SEV_RESTOCK:	// x
			// set restock time of all vendors in World, set the respawn time of all spawns in World.
			( toupper( s.GetArgRaw()[0] ) == 'A' ) ? g_World.Restock() : Restock();
			break;
		case SEV_SEASON:
			SetSeason(static_cast<SEASON_TYPE>(s.GetArgVal()));
			break;
        case SEV_SLEEP:
            {
                if (IsSleeping())
                {
                    break;
                }
                if (!s.HasArgs())// with no args it will check if it can sleep before, to avoid possible problems.
                {
                    if (!CanSleep(true))
                    {
                        break;
                    }
                }
                GoSleep();
            }
            break;
		case SEV_SNOW:
			SetWeather( WEATHER_SNOW );
			break;
		default:
			return( CScriptObj::r_Verb( s, pSrc ));
	}
	return true;
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_SCRIPTSRC;
	EXC_DEBUG_END;
	return false;
}
Exemple #4
0
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;
}