displaystatus.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. enum DSLevels
  2. {
  3. NORMAL = 0,//no bit, default
  4. WARNING = 1,//first bit
  5. CRITICAL = 2,//second bit
  6. BLINKING = 3,//first + second bit
  7. EXTRA = 4,//third bit
  8. }
  9. enum DSLevelsTemp
  10. {
  11. NORMAL = 0,//no bit, default
  12. WARNING_MINUS = 1,//
  13. CRITICAL_MINUS = 2,//
  14. BLINKING_MINUS = 3,//
  15. WARNING_PLUS = 4,//
  16. CRITICAL_PLUS = 5,//
  17. BLINKING_PLUS = 6,//
  18. }
  19. class VirtualHud
  20. {
  21. const int NUMBER_OF_MASKS = 2;//how many INT numbers we need to accommodate all elements
  22. ref array<int> m_LastSentArray;
  23. //ref map<int, ref DisplayElement> m_Elements;
  24. const int NUMBER_OF_ELEMENTS = eDisplayElements.COUNT;
  25. ref DisplayElementBase m_Elements[NUMBER_OF_ELEMENTS];
  26. Mission mission;
  27. Hud m_Hud;
  28. int m_LastTick;
  29. PlayerBase m_Player;
  30. string m_System = "VirtualHud";
  31. ref array<ref Param> rpcParams;
  32. void VirtualHud(PlayerBase player)
  33. {
  34. m_Player = player;
  35. m_LastTick = 0;
  36. RegisterElement(new BadgeStuffed(m_Player));
  37. RegisterElement(new BadgeWet(m_Player));
  38. RegisterElement(new BadgeSick(m_Player));
  39. RegisterElement(new BadgePills(m_Player));
  40. RegisterElement(new BadgePoisoned(m_Player));
  41. RegisterElement(new BadgeFracture(m_Player));
  42. RegisterElement(new TendencyHealth(m_Player));
  43. RegisterElement(new TendencyBlood(m_Player));
  44. RegisterElement(new TendencyTemperature(m_Player));
  45. RegisterElement(new TendencyHunger(m_Player));
  46. RegisterElement(new TendencyThirst(m_Player));
  47. RegisterElement(new TendencyBacteria(m_Player));
  48. RegisterElement(new BadgeHeartbeat(m_Player));
  49. RegisterElement(new BadgeLegs(m_Player));
  50. RegisterElement(new ElementStance(m_Player));// client only
  51. RegisterElement(new BadgeBleeding(m_Player));// client only
  52. mission = GetGame().GetMission();
  53. if ( mission )
  54. {
  55. m_Hud = mission.GetHud();
  56. }
  57. //UpdateStatus();
  58. }
  59. void OnScheduledTick()
  60. {
  61. if ( GetGame().IsServer() )
  62. {
  63. if (GetGame().GetTime() > (m_LastTick + VIRTUAL_HUD_UPDATE_INTERVAL))
  64. {
  65. SendRPC();
  66. m_LastTick = GetGame().GetTime();
  67. }
  68. }
  69. if ( !GetGame().IsDedicatedServer() )
  70. {
  71. ImmediateUpdate();
  72. //DisplayPresence();
  73. }
  74. }
  75. void RegisterElement(DisplayElementBase element)
  76. {
  77. int id = element.GetType();
  78. m_Elements[id] = element;
  79. //Log("adding element:"+id.ToString());
  80. }
  81. DisplayElementBase GetElement(eDisplayElements element_id)
  82. {
  83. if ( element_id < 0 || element_id >= NUMBER_OF_ELEMENTS )
  84. {
  85. return null;
  86. }
  87. return m_Elements[element_id];
  88. }
  89. //this will serialize all elements and 'compresses' them into integer(s) through bit shifting, these integers are placed into an array
  90. void SerializeElements(ref array<int> mask_array)
  91. {
  92. int offset = 0;
  93. int mask = 0;
  94. for (int i = 0; i < NUMBER_OF_ELEMENTS; i++)
  95. {
  96. if ( GetElement(i) && !GetElement(i).IsClientOnly() )
  97. {
  98. if ( (GetElement(i).GetNumberOfBits() + offset) > BIT_INT_SIZE )
  99. {
  100. mask_array.Insert(mask);
  101. offset = 0;
  102. mask = 0;
  103. }
  104. mask = mask | (GetElement(i).GetValue() << offset);
  105. offset = offset + GetElement(i).GetNumberOfBits();
  106. }
  107. }
  108. mask_array.Insert(mask);
  109. }
  110. void DeserializeElements(ref array<int> mask_array)//extracts elements from mask
  111. {
  112. int maskArrayIndex = 0;
  113. int offset = 0;
  114. int mask = 0;
  115. for (int i = 0; i < NUMBER_OF_ELEMENTS;i++)
  116. {
  117. if ( GetElement(i) && !GetElement(i).IsClientOnly() )
  118. {
  119. //Log("entity> " + ToString(GetElement(i)) );
  120. if (offset + GetElement(i).GetNumberOfBits() > BIT_INT_SIZE)
  121. {
  122. maskArrayIndex++;
  123. offset = 0;
  124. }
  125. mask = mask_array.Get(maskArrayIndex);
  126. int value = BitToDec( mask, offset, GetElement(i).GetCompareMask() );
  127. offset = offset + GetElement(i).GetNumberOfBits();
  128. GetElement(i).SetValue( value );
  129. }
  130. }
  131. }
  132. int BitToDec(int mask, int index, int compareMask)
  133. {
  134. int value = mask & (compareMask << index);
  135. value = value >> index;
  136. return value;
  137. }
  138. void PrintElements()
  139. {
  140. for (int i = 0; i < NUMBER_OF_ELEMENTS; i++)
  141. {
  142. PrintString(i.ToString() +": "+ GetElement(i).m_Value.ToString() );
  143. }
  144. }
  145. void SendRPC()
  146. {
  147. array<int> mask_array = new array<int>;
  148. SerializeElements(mask_array);
  149. if ( !m_LastSentArray || !AreArraysSame(m_LastSentArray, mask_array) )
  150. {
  151. ScriptRPC rpc = new ScriptRPC();
  152. rpc.Write(mask_array);
  153. rpc.Send(m_Player, ERPCs.RPC_SYNC_DISPLAY_STATUS, false, m_Player.GetIdentity());
  154. m_LastSentArray = mask_array;
  155. }
  156. }
  157. bool AreArraysSame( notnull array<int> array_a, notnull array<int> array_b )
  158. {
  159. if ( array_a.Count() != array_b.Count() ) return false;
  160. for (int i = 0; i <array_a.Count(); i++)
  161. {
  162. if ( array_a.Get(i) != array_b.Get(i) )
  163. {
  164. return false;
  165. }
  166. }
  167. return true;
  168. }
  169. void ImmediateUpdate()
  170. {
  171. for (int i = 0; i < NUMBER_OF_ELEMENTS;i++)
  172. {
  173. DisplayElementBase element = GetElement(i);
  174. if ( element && element.IsClientOnly() && element.IsValueChanged() )
  175. element.UpdateHUD();
  176. }
  177. }
  178. void UpdateStatus()
  179. {
  180. //Log("UpdateStatus called for entity: "+ToString(m_Player));
  181. for (int i = 0; i < NUMBER_OF_ELEMENTS; i++)
  182. {
  183. DisplayElementBase element = GetElement(i);
  184. if ( element && !element.IsClientOnly() && element.IsValueChanged() )
  185. {
  186. element.UpdateHUD();
  187. }
  188. }
  189. }
  190. void OnRPC(ParamsReadContext ctx)//on Client
  191. {
  192. //Log("OnRPC called");
  193. array<int> mask_array = new array<int>;
  194. ctx.Read(mask_array);
  195. DeserializeElements(mask_array);
  196. UpdateStatus();
  197. }
  198. void Debug()
  199. {
  200. Log("debug");
  201. PluginPlayerStatus m_ModulePlayerStatus = PluginPlayerStatus.Cast(GetPlugin(PluginPlayerStatus));
  202. m_ModulePlayerStatus.DisplayTendency(NTFKEY_HUNGRY, 2);
  203. }
  204. }