123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- #include "../idlib/precompiled.h"
- #pragma hdrstop
- #include "Game_local.h"
- #define OFFSET_MULTIPLIER 60000
- const idEventDef EV_clockreset( "clockreset" );
- const idEventDef EV_clocksettime( "clocksettime", "d" );
- CLASS_DECLARATION( idAnimatedEntity, idClock )
- EVENT( EV_clockreset, idClock::Event_reset)
- EVENT( EV_clocksettime, idClock::Event_setTime)
-
- END_CLASS
- void idClock::Save( idSaveGame *savefile ) const
- {
- savefile->WriteBool(digital);
- savefile->WriteInt(startTime);
- savefile->WriteInt(offsetTime);
- savefile->WriteInt(lastMinuteCount);
- savefile->WriteFloat(startAngle);
- savefile->WriteFloat(endAngle);
- savefile->WriteInt(minuteStartTime);
- savefile->WriteInt(minuteEndTime);
- savefile->WriteInt(nextSecondsInterval);
- savefile->WriteInt(secondsLerpStart);
- savefile->WriteInt(secondsLerpEnd);
- savefile->WriteInt(secondsState);
- savefile->WriteInt(secondsAngleStart);
- savefile->WriteInt(secondsAngleEnd);
- }
- void idClock::Restore( idRestoreGame *savefile )
- {
- savefile->ReadBool(digital);
- savefile->ReadInt(startTime);
- savefile->ReadInt(offsetTime);
- savefile->ReadInt(lastMinuteCount);
- savefile->ReadFloat(startAngle);
- savefile->ReadFloat(endAngle);
- savefile->ReadInt(minuteStartTime);
- savefile->ReadInt(minuteEndTime);
- savefile->ReadInt(nextSecondsInterval);
- savefile->ReadInt(secondsLerpStart);
- savefile->ReadInt(secondsLerpEnd);
- savefile->ReadInt(secondsState);
- savefile->ReadInt(secondsAngleStart);
- savefile->ReadInt(secondsAngleEnd);
- }
- void idClock::Spawn( void )
- {
- digital = spawnArgs.GetBool("digital", "0");
- this->GetPhysics()->SetContents(0);
-
- this->startTime = 0;
- lastMinuteCount = 0;
- startAngle = 0;
- endAngle = 0;
- minuteStartTime = 0;
- minuteEndTime = 0;
- nextSecondsInterval = 0;
- secondsLerpStart = 0;
- secondsLerpEnd = 0;
- secondsState = 0;
- secondsAngleStart = 0;
- secondsAngleEnd = 0;
- offsetTime = spawnArgs.GetInt("offset", "0") * OFFSET_MULTIPLIER;
- BecomeActive( TH_THINK );
- }
- void idClock::Event_setTime( int time )
- {
- //this->startTime = gameLocal.time - (time * 1000);
- offsetTime = time * 1000;
- }
- void idClock::Event_reset( void )
- {
- lastMinuteCount = 0;
- startAngle = 0;
- endAngle = 0;
- minuteStartTime = 0;
- minuteEndTime = 0;
- nextSecondsInterval = 0;
- secondsLerpStart = 0;
- secondsLerpEnd = 0;
- secondsState = 0;
- secondsAngleStart = 0;
- secondsAngleEnd = 0;
- offsetTime = spawnArgs.GetInt("offset", "0") * OFFSET_MULTIPLIER;
- this->startTime = gameLocal.time;
- SetHandAngle("minute", 0);
- SetHandAngle("hour", 0);
- SetHandAngle("second", 0);
- }
- void idClock::SetHandAngle( const char *jointName, float angle )
- {
- idMat3 bodyAxis;
- idVec3 offset;
- jointHandle_t originJoint = animator.GetJointHandle( "origin" );
- animator.GetJointTransform( originJoint, gameLocal.time, offset, bodyAxis );
- jointHandle_t secondJoint;
- idRotation secondRotation;
- secondJoint = animator.GetJointHandle( jointName );
- secondRotation.SetVec( bodyAxis[0] );
- secondRotation.SetAngle( angle );
- animator.SetJointAxis(secondJoint, JOINTMOD_WORLD, secondRotation.ToMat3());
- }
- void idClock::Think( void )
- {
- int curTime = (gameLocal.time - startTime) + offsetTime;
- //common->Printf("curtime %d\n", curTime);
- if (!digital)
- {
- //SET SECONDS.
- int totalMinutes = (int)(curTime / 1000.0f);
- int secondsFraction = curTime - totalMinutes;
- float secondsPercentage = secondsFraction / 1000.0f;
- float secondsAngle = secondsPercentage * 6.0f;
- //gameLocal.GetLocalPlayer()->DebugMessage(va("%d", secondsFraction));
- //secondsState 0 = idle. 1 = lerping.
- if (gameLocal.time > nextSecondsInterval)
- {
- secondsState = 1;
- nextSecondsInterval = gameLocal.time + 1000;
- //SetHandAngle("second", secondsAngle);
- secondsAngleStart = secondsAngleEnd;
- secondsAngleEnd = secondsAngle;
-
- secondsLerpStart = gameLocal.time;
- secondsLerpEnd = gameLocal.time + 100;
-
- StartSound( "snd_tick", SND_CHANNEL_ANY, 0, false, NULL );
- }
- if (secondsState == 1)
- {
- float lerp;
- float currentTime = gameLocal.time;
- float lookTimeMax = this->secondsLerpEnd - this->secondsLerpStart;
- currentTime -= this->secondsLerpStart;
- lerp = currentTime / lookTimeMax;
- if (lerp >= 1)
- {
- lerp = 1;
- secondsState = 0;
- }
- SetHandAngle("second", idMath::Lerp(secondsAngleStart, secondsAngleEnd, lerp));
- }
-
-
-
-
- //SET MINUTES. (discrete movement)
- int minuteCount = totalMinutes / 60;
- //gameLocal.GetLocalPlayer()->DebugMessage(va("time %d", minuteCount));
- if (minuteCount > 60)
- {
- int i;
- for (i = 0; i < 999; i++)
- {
- if (minuteCount > 60)
- minuteCount -= 60;
- else
- break;
- }
- }
- if (minuteCount != lastMinuteCount)
- {
- minuteStartTime = gameLocal.time;
- minuteEndTime = gameLocal.time + 300;
- startAngle = endAngle;
- endAngle = 360.0f * (minuteCount / 60.0f);
- lastMinuteCount = minuteCount;
- StartSound( "snd_minute", SND_CHANNEL_ANY, 0, false, NULL );
- //hack. force the second hand to reset.
- secondsAngleStart = secondsAngle;
- secondsAngleEnd = secondsAngle;
-
- secondsLerpStart = gameLocal.time;
- secondsLerpEnd = gameLocal.time + 50;
- secondsState = 1;
- nextSecondsInterval = gameLocal.time + 1000;
- }
- if (minuteEndTime >= gameLocal.time)
- {
- float lerp;
- float currentTime = gameLocal.time;
- float lookTimeMax = this->minuteEndTime - this->minuteStartTime;
- currentTime -= this->minuteStartTime;
- lerp = currentTime / lookTimeMax;
- //gameLocal.Printf(va("time %f", lerp));
- if (lerp > 1)
- lerp = 1;
- SetHandAngle("minute", idMath::Lerp(startAngle, endAngle, lerp));
- }
- //SET HOURS.
- float hourAngle = secondsPercentage * 0.001666666666666f;
- SetHandAngle("hour", hourAngle);
- }
- else
- {
- //digital.
- int fullHours = curTime / 3600000;
- int fullMinutes = curTime / 60000;
- if (fullHours > 0)
- {
- fullMinutes -= fullHours * 60;
- }
- int seconds = curTime / 1000;
- if (fullMinutes > 0)
- {
- seconds -= fullMinutes * 60;
- }
- if (fullHours > 0)
- {
- seconds -= (fullHours * 60) * 60;
- }
- this->renderEntity.gui[0]->SetStateString("gui_parm0", va("%02d", fullHours));
- this->renderEntity.gui[0]->SetStateString("gui_parm1", va("%02d", fullMinutes));
- this->renderEntity.gui[0]->SetStateString("gui_parm2", va("%02d", seconds));
- }
-
- //idAnimatedEntity::Think();
- idAnimatedEntity::Present();
- }
|