clock.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. #include "../idlib/precompiled.h"
  2. #pragma hdrstop
  3. #include "Game_local.h"
  4. #define OFFSET_MULTIPLIER 60000
  5. const idEventDef EV_clockreset( "clockreset" );
  6. const idEventDef EV_clocksettime( "clocksettime", "d" );
  7. CLASS_DECLARATION( idAnimatedEntity, idClock )
  8. EVENT( EV_clockreset, idClock::Event_reset)
  9. EVENT( EV_clocksettime, idClock::Event_setTime)
  10. END_CLASS
  11. void idClock::Save( idSaveGame *savefile ) const
  12. {
  13. savefile->WriteBool(digital);
  14. savefile->WriteInt(startTime);
  15. savefile->WriteInt(offsetTime);
  16. savefile->WriteInt(lastMinuteCount);
  17. savefile->WriteFloat(startAngle);
  18. savefile->WriteFloat(endAngle);
  19. savefile->WriteInt(minuteStartTime);
  20. savefile->WriteInt(minuteEndTime);
  21. savefile->WriteInt(nextSecondsInterval);
  22. savefile->WriteInt(secondsLerpStart);
  23. savefile->WriteInt(secondsLerpEnd);
  24. savefile->WriteInt(secondsState);
  25. savefile->WriteInt(secondsAngleStart);
  26. savefile->WriteInt(secondsAngleEnd);
  27. }
  28. void idClock::Restore( idRestoreGame *savefile )
  29. {
  30. savefile->ReadBool(digital);
  31. savefile->ReadInt(startTime);
  32. savefile->ReadInt(offsetTime);
  33. savefile->ReadInt(lastMinuteCount);
  34. savefile->ReadFloat(startAngle);
  35. savefile->ReadFloat(endAngle);
  36. savefile->ReadInt(minuteStartTime);
  37. savefile->ReadInt(minuteEndTime);
  38. savefile->ReadInt(nextSecondsInterval);
  39. savefile->ReadInt(secondsLerpStart);
  40. savefile->ReadInt(secondsLerpEnd);
  41. savefile->ReadInt(secondsState);
  42. savefile->ReadInt(secondsAngleStart);
  43. savefile->ReadInt(secondsAngleEnd);
  44. }
  45. void idClock::Spawn( void )
  46. {
  47. digital = spawnArgs.GetBool("digital", "0");
  48. this->GetPhysics()->SetContents(0);
  49. this->startTime = 0;
  50. lastMinuteCount = 0;
  51. startAngle = 0;
  52. endAngle = 0;
  53. minuteStartTime = 0;
  54. minuteEndTime = 0;
  55. nextSecondsInterval = 0;
  56. secondsLerpStart = 0;
  57. secondsLerpEnd = 0;
  58. secondsState = 0;
  59. secondsAngleStart = 0;
  60. secondsAngleEnd = 0;
  61. offsetTime = spawnArgs.GetInt("offset", "0") * OFFSET_MULTIPLIER;
  62. BecomeActive( TH_THINK );
  63. }
  64. void idClock::Event_setTime( int time )
  65. {
  66. //this->startTime = gameLocal.time - (time * 1000);
  67. offsetTime = time * 1000;
  68. }
  69. void idClock::Event_reset( void )
  70. {
  71. lastMinuteCount = 0;
  72. startAngle = 0;
  73. endAngle = 0;
  74. minuteStartTime = 0;
  75. minuteEndTime = 0;
  76. nextSecondsInterval = 0;
  77. secondsLerpStart = 0;
  78. secondsLerpEnd = 0;
  79. secondsState = 0;
  80. secondsAngleStart = 0;
  81. secondsAngleEnd = 0;
  82. offsetTime = spawnArgs.GetInt("offset", "0") * OFFSET_MULTIPLIER;
  83. this->startTime = gameLocal.time;
  84. SetHandAngle("minute", 0);
  85. SetHandAngle("hour", 0);
  86. SetHandAngle("second", 0);
  87. }
  88. void idClock::SetHandAngle( const char *jointName, float angle )
  89. {
  90. idMat3 bodyAxis;
  91. idVec3 offset;
  92. jointHandle_t originJoint = animator.GetJointHandle( "origin" );
  93. animator.GetJointTransform( originJoint, gameLocal.time, offset, bodyAxis );
  94. jointHandle_t secondJoint;
  95. idRotation secondRotation;
  96. secondJoint = animator.GetJointHandle( jointName );
  97. secondRotation.SetVec( bodyAxis[0] );
  98. secondRotation.SetAngle( angle );
  99. animator.SetJointAxis(secondJoint, JOINTMOD_WORLD, secondRotation.ToMat3());
  100. }
  101. void idClock::Think( void )
  102. {
  103. int curTime = (gameLocal.time - startTime) + offsetTime;
  104. //common->Printf("curtime %d\n", curTime);
  105. if (!digital)
  106. {
  107. //SET SECONDS.
  108. int totalMinutes = (int)(curTime / 1000.0f);
  109. int secondsFraction = curTime - totalMinutes;
  110. float secondsPercentage = secondsFraction / 1000.0f;
  111. float secondsAngle = secondsPercentage * 6.0f;
  112. //gameLocal.GetLocalPlayer()->DebugMessage(va("%d", secondsFraction));
  113. //secondsState 0 = idle. 1 = lerping.
  114. if (gameLocal.time > nextSecondsInterval)
  115. {
  116. secondsState = 1;
  117. nextSecondsInterval = gameLocal.time + 1000;
  118. //SetHandAngle("second", secondsAngle);
  119. secondsAngleStart = secondsAngleEnd;
  120. secondsAngleEnd = secondsAngle;
  121. secondsLerpStart = gameLocal.time;
  122. secondsLerpEnd = gameLocal.time + 100;
  123. StartSound( "snd_tick", SND_CHANNEL_ANY, 0, false, NULL );
  124. }
  125. if (secondsState == 1)
  126. {
  127. float lerp;
  128. float currentTime = gameLocal.time;
  129. float lookTimeMax = this->secondsLerpEnd - this->secondsLerpStart;
  130. currentTime -= this->secondsLerpStart;
  131. lerp = currentTime / lookTimeMax;
  132. if (lerp >= 1)
  133. {
  134. lerp = 1;
  135. secondsState = 0;
  136. }
  137. SetHandAngle("second", idMath::Lerp(secondsAngleStart, secondsAngleEnd, lerp));
  138. }
  139. //SET MINUTES. (discrete movement)
  140. int minuteCount = totalMinutes / 60;
  141. //gameLocal.GetLocalPlayer()->DebugMessage(va("time %d", minuteCount));
  142. if (minuteCount > 60)
  143. {
  144. int i;
  145. for (i = 0; i < 999; i++)
  146. {
  147. if (minuteCount > 60)
  148. minuteCount -= 60;
  149. else
  150. break;
  151. }
  152. }
  153. if (minuteCount != lastMinuteCount)
  154. {
  155. minuteStartTime = gameLocal.time;
  156. minuteEndTime = gameLocal.time + 300;
  157. startAngle = endAngle;
  158. endAngle = 360.0f * (minuteCount / 60.0f);
  159. lastMinuteCount = minuteCount;
  160. StartSound( "snd_minute", SND_CHANNEL_ANY, 0, false, NULL );
  161. //hack. force the second hand to reset.
  162. secondsAngleStart = secondsAngle;
  163. secondsAngleEnd = secondsAngle;
  164. secondsLerpStart = gameLocal.time;
  165. secondsLerpEnd = gameLocal.time + 50;
  166. secondsState = 1;
  167. nextSecondsInterval = gameLocal.time + 1000;
  168. }
  169. if (minuteEndTime >= gameLocal.time)
  170. {
  171. float lerp;
  172. float currentTime = gameLocal.time;
  173. float lookTimeMax = this->minuteEndTime - this->minuteStartTime;
  174. currentTime -= this->minuteStartTime;
  175. lerp = currentTime / lookTimeMax;
  176. //gameLocal.Printf(va("time %f", lerp));
  177. if (lerp > 1)
  178. lerp = 1;
  179. SetHandAngle("minute", idMath::Lerp(startAngle, endAngle, lerp));
  180. }
  181. //SET HOURS.
  182. float hourAngle = secondsPercentage * 0.001666666666666f;
  183. SetHandAngle("hour", hourAngle);
  184. }
  185. else
  186. {
  187. //digital.
  188. int fullHours = curTime / 3600000;
  189. int fullMinutes = curTime / 60000;
  190. if (fullHours > 0)
  191. {
  192. fullMinutes -= fullHours * 60;
  193. }
  194. int seconds = curTime / 1000;
  195. if (fullMinutes > 0)
  196. {
  197. seconds -= fullMinutes * 60;
  198. }
  199. if (fullHours > 0)
  200. {
  201. seconds -= (fullHours * 60) * 60;
  202. }
  203. this->renderEntity.gui[0]->SetStateString("gui_parm0", va("%02d", fullHours));
  204. this->renderEntity.gui[0]->SetStateString("gui_parm1", va("%02d", fullMinutes));
  205. this->renderEntity.gui[0]->SetStateString("gui_parm2", va("%02d", seconds));
  206. }
  207. //idAnimatedEntity::Think();
  208. idAnimatedEntity::Present();
  209. }