Guest User

Untitled

a guest
Jul 4th, 2024
9
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 382.48 KB | None | 0 0
  1. sreV product dayz ugc version 154 prefix JM\CF\Scripts 1_Core\CommunityFramework\CF_Byte.c £­»dë 1_Core\CommunityFramework\CF_Cast.c ÖNb¿ 1_Core\CommunityFramework\CF_Encoding.c £­»d  1_Core\CommunityFramework\CF_Operations.c ÖNb{ 1_Core\CommunityFramework\CF_PackedByte.c ÖNb± 1_Core\CommunityFramework\CF_SeekOrigin.c ÖNb3 1_Core\CommunityFramework\CF_String.c ÖNbâ 1_Core\CommunityFramework\CF_Uint.c ÖNb² 1_Core\CommunityFramework\EventArgs\CF_EventArgs.c ÖNbš 1_Core\CommunityFramework\EventArgs\CF_EventTimeArgs.c ÖNbw 1_Core\CommunityFramework\EventArgs\CF_EventUpdateArgs.c ÖNb– 1_Core\CommunityFramework\Files\CF_Directory.c ÖNbú 1_Core\CommunityFramework\Files\CF_File.c ÖNb 1_Core\CommunityFramework\Files\CF_Path.c £­»d 1_Core\CommunityFramework\IO\CF_Base16Stream.c ÖNbæ 1_Core\CommunityFramework\IO\CF_Base64Stream.c ÖNbª 1_Core\CommunityFramework\IO\CF_BinaryReader.c 'åc 1_Core\CommunityFramework\IO\CF_BinaryWriter.c £­»dŒ
  2. 1_Core\CommunityFramework\IO\CF_FileStream.c ÖNb‰
  3. 1_Core\CommunityFramework\IO\CF_IO.c 'åcÀ 1_Core\CommunityFramework\IO\CF_SerializerStream.c ÖNbË 1_Core\CommunityFramework\IO\CF_Stream.c ÖNb¯ 1_Core\CommunityFramework\IO\CF_StringStream.c £­»dþ 1_Core\CommunityFramework\IO\CF_TextReader.c ÖNb- 1_Core\CommunityFramework\IO\CF_TextWriter.c £­»d• 1_Core\CommunityFramework\Logging\CF_Log.c 'åc 1_Core\CommunityFramework\Logging\CF_LogLevel.c ÖNb_ 1_Core\CommunityFramework\Logging\CF_Trace.c 'åc- 1_Core\CommunityFramework\Module\CF_ModuleCore.c ÖNbf 1_Core\CommunityFramework\Module\CF_ModuleCoreEvent.c ÖNbÛ 1_Core\CommunityFramework\Module\CF_ModuleCoreManager.c .ÖNbØ 1_Core\CommunityFramework\Module\CF_Modules.c ÖNb= 1_Core\CommunityFramework\Module\CF_RegisterModule.c ÖNbw 1_Core\CommunityFramework\proto\EnMath.c ÖNbø 1_Core\CommunityFramework\TypeConverter\CF_RegisterTypeConverter.c ÖNb 1_Core\CommunityFramework\TypeConverter\CF_TypeConverter.c .ÖNb
  4. 1_Core\CommunityFramework\TypeConverter\CF_TypeConverterBase.c ÖNb1
  5. 1_Core\CommunityFramework\TypeConverter\CF_TypeConverterT.c ÖNbç 2_GameLib\CommunityFramework\Cryptography\CF_SHA256.c ÖNb 2_GameLib\CommunityFramework\EventHandler\Attributes\CF_EventSubscriber.c ¥DÒd¤ 2_GameLib\CommunityFramework\EventHandler\Attributes\CF_MultiEventSubscriber.c £­»d 2_GameLib\CommunityFramework\EventHandler\CF_EventHandler.c ¼GÒd¼ 2_GameLib\CommunityFramework\LifecycleEvents\CF_LifecycleEvents.c Âp¿d 3_Game\CommunityFramework\Collections\Stack.c ÖNb) 3_Game\CommunityFramework\CommunityFramework.c .ÖNb¬ 3_Game\CommunityFramework\Config\ConfigArray.c ÖNb 3_Game\CommunityFramework\Config\ConfigArrayParam.c ÖNb¦ 3_Game\CommunityFramework\Config\ConfigArrayParamArray.c 'åc‹ 3_Game\CommunityFramework\Config\ConfigArrayParamFloat.c ÖNb= 3_Game\CommunityFramework\Config\ConfigArrayParamInt.c ÖNb- 3_Game\CommunityFramework\Config\ConfigArrayParamLong.c ÖNb2 3_Game\CommunityFramework\Config\ConfigArrayParamText.c ÖNb; 3_Game\CommunityFramework\Config\ConfigClass.c ÖNbv 3_Game\CommunityFramework\Config\ConfigEntry.c ÖNb¾ 3_Game\CommunityFramework\Config\ConfigFile.c ÖNbO 3_Game\CommunityFramework\Config\ConfigReader.c 'åc¨ 3_Game\CommunityFramework\Config\ConfigValue.c ÖNb‘ 3_Game\CommunityFramework\Config\ConfigValueFloat.c ÖNb- 3_Game\CommunityFramework\Config\ConfigValueInt.c ÖNb 3_Game\CommunityFramework\Config\ConfigValueLong.c ÖNb" 3_Game\CommunityFramework\Config\ConfigValueText.c ÖNb+ 3_Game\CommunityFramework\Config\ConfigValueTypes.c ÖNbW 3_Game\CommunityFramework\Credits\CreditsLoader.c 3ɾd 3_Game\CommunityFramework\EventArgs\CF_EventChatArgs.c ÖNb" 3_Game\CommunityFramework\EventArgs\CF_EventLoginArgs.c ÖNb² 3_Game\CommunityFramework\EventArgs\CF_EventRPCArgs.c ÖNbw 3_Game\CommunityFramework\ExpressionVM\CF_Expression.c £­»d 3_Game\CommunityFramework\ExpressionVM\CF_ExpressionCompileToken.c ÖNbZ 3_Game\CommunityFramework\ExpressionVM\CF_ExpressionFunction.c £­»dc 3_Game\CommunityFramework\ExpressionVM\CF_ExpressionInstruction.c ÖNbÏ 3_Game\CommunityFramework\ExpressionVM\CF_ExpressionStackDebug.c ÖNbg 3_Game\CommunityFramework\ExpressionVM\CF_ExpressionTests.c ÖNbK 3_Game\CommunityFramework\ExpressionVM\CF_ExpressionVM.c £­»d  3_Game\CommunityFramework\ExpressionVM\CF_MathExpression.c ÖNbÖ 3_Game\CommunityFramework\ExpressionVM\CF_SQFExpression.c ÖNbx 3_Game\CommunityFramework\ExpressionVM\DayZGame.c ÖNb» 3_Game\CommunityFramework\Game\DayZGame.c “(åcÁ 3_Game\CommunityFramework\InputBindings\CF_InputBinding.c ÖNbD 3_Game\CommunityFramework\InputBindings\CF_InputBindings.c .ÖNb¯
  6. 3_Game\CommunityFramework\LifecycleEvents\DayZGame.c ×EÒdˆ 3_Game\CommunityFramework\Mods\ModInput.c ÖNbM 3_Game\CommunityFramework\Mods\ModLoader.c 'åc¨ 3_Game\CommunityFramework\Mods\ModStructure.c ÖNb 3_Game\CommunityFramework\ModStorage\CF_ModStorage.c .ÖNb’ 3_Game\CommunityFramework\ModStorage\CF_ModStorageMap.c ÖNbq 3_Game\CommunityFramework\ModStorage\CF_ModStorageModule.c .ÖNb
  7. 3_Game\CommunityFramework\ModStorage\CF_ModStorageTest.c ÖNbM 3_Game\CommunityFramework\Module\CF_ModuleConstructor.c £­»dÏ 3_Game\CommunityFramework\Module\CF_ModuleGame.c .ÖNbF 3_Game\CommunityFramework\Module\CF_ModuleGameEvent.c .ÖNb' 3_Game\CommunityFramework\Module\CF_ModuleGameManager.c .ÖNb 3_Game\CommunityFramework\Module\Deprecated\JMModuleManagerBase.c £­»d
  8. 3_Game\CommunityFramework\Network\CF_NetworkedVariables.c ÖNb  3_Game\CommunityFramework\Network\CF_NetworkVariable.c ÖNb 3_Game\CommunityFramework\Notification\NotificationRuntimeData.c ÖNbý 3_Game\CommunityFramework\Notification\NotificationSystem.c £­»d` 3_Game\CommunityFramework\ObjectManager\ObjectManager.c 'åcÊ. 3_Game\CommunityFramework\RPC\RPCManager.c £­»dw 3_Game\CommunityFramework\TypeConverter\CF_TypeConverterConstructor.c £­»d 3_Game\CommunityFramework\TypeConverter\Converters\CF_TypeConverterBool.c ÖNbÒ 3_Game\CommunityFramework\TypeConverter\Converters\CF_TypeConverterClass.c ÖNb 3_Game\CommunityFramework\TypeConverter\Converters\CF_TypeConverterDate.c ÖNbF 3_Game\CommunityFramework\TypeConverter\Converters\CF_TypeConverterExpression.c ÖNbõ 3_Game\CommunityFramework\TypeConverter\Converters\CF_TypeConverterFile.c ÖNb 3_Game\CommunityFramework\TypeConverter\Converters\CF_TypeConverterFloat.c ÖNbÎ 3_Game\CommunityFramework\TypeConverter\Converters\CF_TypeConverterInt.c ÖNbÀ 3_Game\CommunityFramework\TypeConverter\Converters\CF_TypeConverterLocaliser.c ÖNbñ 3_Game\CommunityFramework\TypeConverter\Converters\CF_TypeConverterManaged.c ÖNbó 3_Game\CommunityFramework\TypeConverter\Converters\CF_TypeConverterString.c ÖNb 3_Game\CommunityFramework\TypeConverter\Converters\CF_TypeConverterVector.c ÖNbp 3_Game\CommunityFramework\Utils\CF_Date.c £­»d½. 3_Game\CommunityFramework\Utils\CF_Localiser.c ÖNbY 3_Game\CommunityFramework\XML\CF_XML.c ÖNb³ 3_Game\CommunityFramework\XML\CF_XML_Attribute.c ÖNbñ 3_Game\CommunityFramework\XML\CF_XML_Callback.c ÖNbÔ 3_Game\CommunityFramework\XML\CF_XML_Document.c ÖNbd 3_Game\CommunityFramework\XML\CF_XML_Element.c 'åc´ 3_Game\CommunityFramework\XML\CF_XML_Reader.c £­»dÍ 3_Game\CommunityFramework\XML\CF_XML_Tag.c 'åc* 4_World\CommunityFramework\Classes\JMAnimRegister.c ÖNb 4_World\CommunityFramework\Entities\AdvancedCommunication.c .ÖNb1 4_World\CommunityFramework\Entities\AnimalBase.c .ÖNb 4_World\CommunityFramework\Entities\BuildingBase.c .ÖNb 4_World\CommunityFramework\Entities\CarScript.c .ÖNb 4_World\CommunityFramework\Entities\DayZPlayerImplement.c .ÖNb- 4_World\CommunityFramework\Entities\HelicopterScript.c .ÖNb' 4_World\CommunityFramework\Entities\ItemBase.c .ÖNbÜ 4_World\CommunityFramework\Entities\ManBase\DayZPlayerCameras.c ÖNb˜ 4_World\CommunityFramework\Entities\ZombieBase.c .ÖNb 4_World\CommunityFramework\EventArgs\CF_EventPlayerArgs.c ÖNbJ 4_World\CommunityFramework\ModStorage\CF_ModStorageBase.c ÖNb¤ 4_World\CommunityFramework\ModStorage\CF_ModStorageObject.c 'åcƒ 4_World\CommunityFramework\ModStorage\modstorage_prepare.c .ÖNbÅ 4_World\CommunityFramework\Module\CF_ModuleWorld.c ÖNb´ 4_World\CommunityFramework\Module\CF_ModuleWorldEvent.c ÖNbÛ 4_World\CommunityFramework\Module\CF_ModuleWorldManager.c .ÖNbþ 4_World\CommunityFramework\Module\Deprecated\JMModuleBase.c £­»d§ 4_World\CommunityFramework\Module\Deprecated\JMModuleBinding.c ÖNb 4_World\CommunityFramework\Module\Deprecated\JMModuleConstructorBase.c ÖNbŒ 4_World\CommunityFramework\Module\Deprecated\JMModuleManager.c £­»d 4_World\CommunityFramework\Surfaces\CF_Surface.c ¤­»d˜ 4_World\CommunityFramework\Surfaces\CF_VehicleSurface.c ¤­»dá 4_World\CommunityFramework\Weapons\CF_WeaponStableState.c .ÖNbP 4_World\CommunityFramework\Weapons\Weapon_Base.c .ÖNbˆ 4_World\CommunityFramework\Weapons\WeaponFSM.c .ÖNb4 4_World\CommunityFramework\Weapons\WeaponStableState.c ÖNbà 5_Mission\CommunityFramework\GUI\Keybindings\KeybindingElement.c ÖNbÍ 5_Mission\CommunityFramework\GUI\Keybindings\KeybindingsGroup.c ÖNb‹ 5_Mission\CommunityFramework\LifecycleEvents\MissionBase.c kHÒd— 5_Mission\CommunityFramework\Mission\MissionBase.c ÖNb 5_Mission\CommunityFramework\Mission\MissionGameplay.c .ÖNb 5_Mission\CommunityFramework\Mission\MissionServer.c s;Þbh 5_Mission\CommunityFramework\Module\JMModuleConstructor.c ÖNbz config.bin òHÒd^ Editor\Plugins\CommunityFramework\BuildMod.c ÖNbh Editor\Plugins\CommunityFramework\DayZProjectManager.c ÖNbÄ Editor\Plugins\CommunityFramework\LaunchClient.c ÖNb, Editor\Plugins\CommunityFramework\LaunchLocalMP.c ÖNbR Editor\Plugins\CommunityFramework\LaunchOffline.c ÖNb? Editor\Plugins\CommunityFramework\LaunchServer.c ÖNb, Editor\Plugins\CommunityFramework\OpenLogs.c ÖNb Editor\Plugins\CommunityFramework\PluginErrorMessage.c ÖNbÓ /*
  9. Byte Type Definition
  10. -- This is a byte datatype definition for EnScript
  11.  
  12. Author: Lystic, Jacob_Mango
  13.  
  14. When working with bytes. It is necessary to use 'CF_Byte::Clamp()' to ensure the value remains 8 bit when modifying.
  15. */
  16.  
  17. typedef int CF_Byte;
  18. class CF_Byte : CF_Uint
  19. {
  20. CF_Byte Clamp()
  21. {
  22. CF_Byte oldByte = value;
  23. value = value & 255;
  24. return value;
  25. }
  26.  
  27. void Set(int index, int v)
  28. {
  29. // set and clamp
  30. value = v & 255;
  31. }
  32.  
  33. int Get(int index)
  34. {
  35. return value;
  36. }
  37.  
  38. static CF_Byte Set(int value)
  39. {
  40. // set and clamp
  41. CF_Byte byte = value & 255;
  42. return byte;
  43. }
  44.  
  45. static CF_Byte Set(string char)
  46. {
  47. CF_Byte byte = char.Get(0).ToAscii() & 255;
  48. return byte;
  49. }
  50.  
  51. string ToHex()
  52. {
  53. int ascii = value & 255;
  54.  
  55. int n0 = Math.Floor(ascii / 16);
  56. int n1 = ascii % 16;
  57.  
  58. return CF_Encoding.BASE_16[n0] + CF_Encoding.BASE_16[n1];
  59. }
  60.  
  61. override CF_Uint XOR(CF_Uint y)
  62. {
  63. CF_Byte b = super.XOR(y) & 255;
  64. return b;
  65. }
  66. };
  67. class CF_Cast<Class U, Class V>
  68. {
  69. static V Reinterpret(U src)
  70. {
  71. U src_arr[1];
  72. src_arr[0] = src;
  73. V dst_arr[1];
  74.  
  75. copyarray(dst_arr, src_arr);
  76.  
  77. return dst_arr[0];
  78. }
  79. };
  80. class CF_Encoding
  81. {
  82. static const string BASE_16[16] = {
  83. "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"
  84. };
  85.  
  86. static const string BASE_64[64] = {
  87. "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P",
  88. "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f",
  89. "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
  90. "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/",
  91. };
  92.  
  93. static int Find(string[] data, int count, string match)
  94. {
  95. for (int i = 0; i < count; i++)
  96. {
  97. if (data[i] == match) return i;
  98. }
  99.  
  100. return -1;
  101. }
  102.  
  103. static string FindGet(string[] data, int count, string match)
  104. {
  105. for (int i = 0; i < count; i++)
  106. {
  107. if (data[i] == match) return data[i];
  108. }
  109.  
  110. return data[0];
  111. }
  112.  
  113. static CF_Byte GetByte(string char)
  114. {
  115. return CF_Byte.Set(char);
  116. }
  117.  
  118. static array<CF_Byte> GetBytes(string str)
  119. {
  120. array<CF_Byte> bytes = new array<CF_Byte>();
  121. for (int i = 0; i < str.Length(); i++)
  122. {
  123. bytes.Insert(CF_Byte.Set(str[i]));
  124. }
  125. return bytes;
  126. }
  127.  
  128. static string ToHex(array<CF_Byte> bytes)
  129. {
  130. string str = "";
  131. for (int i = 0; i < bytes.Count(); i++)
  132. {
  133. str += bytes[i].ToHex();
  134. }
  135. return str;
  136. }
  137.  
  138. static array<CF_Byte> FromHex(string str)
  139. {
  140. if (str.Length() % 2 != 0)
  141. {
  142. Error("Invalid string length");
  143. return null;
  144. }
  145.  
  146. array<CF_Byte> bytes = new array<CF_Byte>();
  147.  
  148. for (int i = 0; i < str.Length() / 2; i++)
  149. {
  150. int n0 = Find(BASE_16, 16, str[i * 2 + 0]) * 16;
  151. int n1 = Find(BASE_16, 16, str[i * 2 + 1]);
  152.  
  153. if (n0 < 0 || n1 < 0)
  154. {
  155. Error("Invalid character, expect valid base-16, got \"" + str[i * 2 + 0] + str[i * 2 + 1] + "\"");
  156. return null;
  157. }
  158.  
  159. CF_Byte byte = n0 + n1;
  160. bytes.Insert(byte);
  161. }
  162.  
  163. return bytes;
  164. }
  165.  
  166. static string ToBase64(array<CF_Byte> bytes)
  167. {
  168. string str = "";
  169. for (int i = 0; i < bytes.Count(); i++)
  170. {
  171. str += bytes[i].ToHex();
  172. }
  173. return str;
  174. }
  175.  
  176. static bool IsWhitespace(string char)
  177. {
  178. return IsWhitespace(CF_Byte.Set(char));
  179. }
  180.  
  181. /**
  182. * @brief Returns true if the input byte as in any character below decimal 32.
  183. * Helpful table https://commons.wikimedia.org/wiki/File:ASCII-Table-wide.svg
  184. */
  185. static bool IsWhitespace(CF_Byte byte)
  186. {
  187. if (byte <= 32) return true;
  188.  
  189. return false;
  190. }
  191.  
  192. static bool IsAlphanumeric(string char)
  193. {
  194. return IsAlphanumeric(CF_Byte.Set(char));
  195. }
  196.  
  197. static bool IsAlphanumeric(CF_Byte byte)
  198. {
  199. if (byte >= 48 && byte <= 57) return true;
  200. if (byte > 90) byte -= 32;
  201. if (byte >= 65 && byte <= 90) return true;
  202.  
  203. return false;
  204. }
  205.  
  206. static bool IsAlpha(string char)
  207. {
  208. return IsAlpha(CF_Byte.Set(char));
  209. }
  210.  
  211. static bool IsAlpha(CF_Byte byte)
  212. {
  213. if (byte > 90) byte -= 32;
  214. if (byte >= 65 && byte <= 90) return true;
  215.  
  216. return false;
  217. }
  218.  
  219. static bool IsNumeric(string char)
  220. {
  221. return IsNumeric(CF_Byte.Set(char));
  222. }
  223.  
  224. static bool IsNumeric(CF_Byte byte)
  225. {
  226. if (byte >= 48 && byte <= 57) return true;
  227.  
  228. return false;
  229. }
  230.  
  231. static bool IsLine(string char)
  232. {
  233. return IsNumeric(CF_Byte.Set(char));
  234. }
  235.  
  236. static bool IsLine(CF_Byte byte)
  237. {
  238. if (byte >= 10 && byte <= 15) return true;
  239.  
  240. return false;
  241. }
  242.  
  243. static bool StringToBool(string str)
  244. {
  245. str.ToLower();
  246. str.Trim();
  247. if (str == "true") return true;
  248. if (str == "false") return false;
  249. return str.ToInt();
  250. }
  251. };
  252. static int CF_XOR(int x, int y)
  253. {
  254. int a = (x | y);
  255. int b = ~x;
  256. int c = ~y;
  257. int d = (b | c);
  258. return (a & d);
  259. }
  260. /**
  261. * Storing bytes in a forward doubly linked list.
  262. * This gives both fast reading and an unlimited size of bytes
  263. */
  264. class CF_PackedByte
  265. {
  266. ref CF_PackedByte m_Next;
  267. CF_PackedByte m_Prev;
  268.  
  269. CF_Byte m_Value;
  270.  
  271. CF_PackedByte SerializerWrite(Serializer ctx, int length, inout int index)
  272. {
  273. CF_PackedByte byte = this;
  274.  
  275. int b0;
  276. int b1;
  277. int b2;
  278. int b3;
  279.  
  280. if (byte)
  281. {
  282. b0 = byte.m_Value;
  283. byte = byte.m_Next;
  284.  
  285. index++;
  286. }
  287.  
  288. if (byte)
  289. {
  290. b1 = byte.m_Value;
  291. byte = byte.m_Next;
  292.  
  293. index++;
  294. }
  295.  
  296. if (byte)
  297. {
  298. b2 = byte.m_Value;
  299. byte = byte.m_Next;
  300.  
  301. index++;
  302. }
  303.  
  304. if (byte)
  305. {
  306. b3 = byte.m_Value;
  307. byte = byte.m_Next;
  308.  
  309. index++;
  310. }
  311.  
  312. ctx.Write(((b3 & 0x000000FF) << 24) + ((b2 & 0x000000FF) << 16) + ((b1 & 0x000000FF) << 8) + (b0 & 0x000000FF));
  313.  
  314. return byte;
  315. }
  316.  
  317. CF_PackedByte SerializerRead(Serializer ctx, int length, inout int index)
  318. {
  319. CF_PackedByte byte = this;
  320.  
  321. int value;
  322.  
  323. ctx.Read(value);
  324.  
  325. int b3 = (value >> 24) & 0x000000FF;
  326. int b2 = (value >> 16) & 0x000000FF;
  327. int b1 = (value >> 8 ) & 0x000000FF;
  328. int b0 = (value ) & 0x000000FF;
  329.  
  330. if (index < length)
  331. {
  332. index++;
  333.  
  334. // set and clamp
  335. byte.m_Value = b0 & 255;
  336.  
  337. byte.m_Next = new CF_PackedByte();
  338. byte.m_Next.m_Prev = byte;
  339. byte = byte.m_Next;
  340. }
  341.  
  342. if (index < length)
  343. {
  344. index++;
  345.  
  346. // set and clamp
  347. byte.m_Value = b1 & 255;
  348.  
  349. byte.m_Next = new CF_PackedByte();
  350. byte.m_Next.m_Prev = byte;
  351. byte = byte.m_Next;
  352. }
  353.  
  354. if (index < length)
  355. {
  356. index++;
  357.  
  358. byte.m_Value = b2 & 255;
  359.  
  360. byte.m_Next = new CF_PackedByte();
  361. byte.m_Next.m_Prev = byte;
  362. byte = byte.m_Next;
  363. }
  364.  
  365. if (index < length)
  366. {
  367. index++;
  368.  
  369. byte.m_Value = b3 & 255;
  370.  
  371. byte.m_Next = new CF_PackedByte();
  372. byte.m_Next.m_Prev = byte;
  373. byte = byte.m_Next;
  374. }
  375.  
  376. return byte;
  377. }
  378. };
  379. enum CF_SeekOrigin
  380. {
  381. SET,
  382. CURRENT,
  383. END
  384. };
  385. typedef string CF_String;
  386. class CF_String : string
  387. {
  388. /**
  389. * @brief Returns the number of times the specified character exists in the string
  390. *
  391. * @param char The character that will be matched
  392. *
  393. * @code
  394. * CF_String str = "Hello, World!";
  395. * int count = str.CountCharacter("l");
  396. * Print(count);
  397. * >> '3'
  398. * @endcode
  399. */
  400. int CountCharacter(CF_String char)
  401. {
  402. int count = 0;
  403. int length = value.Length();
  404. for (int index = 0; index < length; index++)
  405. {
  406. count += value.Substring(index, 1) == char;
  407. }
  408. return count;
  409. }
  410.  
  411. /**
  412. * @brief Returns the number of times the specified character exists in the string
  413. *
  414. * @param char The character that will be matched
  415. * @param[out] firstOccurrence The index of the first character
  416. *
  417. * @code
  418. * CF_String str = "Hello, World!";
  419. * int index;
  420. * int count = str.CountCharacter("l", index);
  421. * Print(count);
  422. * Print(index);
  423. * >> '3'
  424. * >> '2'
  425. * @endcode
  426. */
  427. int CountCharacter(CF_String char, out int firstOccurrence )
  428. {
  429. int count = 0;
  430. firstOccurrence = -1;
  431.  
  432. int length = value.Length();
  433. for (int index = 0; index < length; index++)
  434. {
  435. count += value.Substring(index, 1) == char;
  436.  
  437. if (count == 1 && firstOccurrence == -1)
  438. {
  439. firstOccurrence = index;
  440. }
  441. }
  442.  
  443. return count;
  444. }
  445.  
  446. /**
  447. * @brief Finds last 'sample' in 'str'. Returns -1 when not found
  448. *
  449. * @param sample Finding string
  450. * @return Returns position where sample starts, or -1 when sample not found
  451. *
  452. * @code
  453. * CF_String str = "Hello, World!";
  454. * Print(str.CF_LastIndexOf("l"));
  455. * >> 10
  456. * @endcode
  457. */
  458. int CF_LastIndexOf(CF_String sample)
  459. {
  460. int sampleLength = sample.Length();
  461. int length = value.Length();
  462. int start = length - sampleLength;
  463. if (start <= 0)
  464. {
  465. return -1;
  466. }
  467.  
  468. for (int index = start - 1; index >= 0; index--)
  469. {
  470. if (value.Substring(index, sampleLength) == sample)
  471. {
  472. return index;
  473. }
  474. }
  475.  
  476. return -1;
  477. }
  478.  
  479. /**
  480. * @brief Fills the string with the specified character at the start so the string matches the length.
  481. * Does nothing if string is equal to or exceeds the specifiying length.
  482. *
  483. * @param length The total string length
  484. * @param padChar The character that will be padded
  485. *
  486. * @code
  487. * CF_String str = "55";
  488. * Print(str.PadStringFront(4, "0"));
  489. * >> '0055'
  490. * @endcode
  491. */
  492. string PadStringFront(int length, CF_String padChar)
  493. {
  494. string newString = value;
  495. length = newString.Length() - length;
  496.  
  497. if (length > 0)
  498. {
  499. for (int index = 0; index < length; index++)
  500. {
  501. newString = padChar + newString;
  502. }
  503. }
  504.  
  505. return newString;
  506. }
  507.  
  508. /**
  509. * @brief Fills the string with the specified character at the end so the string matches the length.
  510. * Does nothing if string is equal to or exceeds the specifiying length.
  511. *
  512. * @param length The total string length
  513. * @param padChar The character that will be padded
  514. *
  515. * @code
  516. * CF_String str = "55";
  517. * Print(str.PadStringBack(4, "0"));
  518. * >> '5500'
  519. * @endcode
  520. */
  521. string PadStringBack(int length, CF_String padChar)
  522. {
  523. string newString = value;
  524. length = newString.Length() - length;
  525.  
  526. if (length > 0)
  527. {
  528. for (int index = 0; index < length; index++)
  529. {
  530. newString += padChar;
  531. }
  532. }
  533.  
  534. return newString;
  535. }
  536.  
  537. /**
  538. * @brief Replaces the string of length at the index with the splice.
  539. *
  540. * @param start The index at which to start changing the string
  541. * @param padChar The string the content will be replaced with
  542. *
  543. * @code
  544. * CF_String str = "How is you?";
  545. * Print(str.SpliceString(4, "be"));
  546. * >> 'How be you?'
  547. * @endcode
  548. */
  549. string SpliceString(int start, CF_String splice)
  550. {
  551. int middle = start + splice.Length();
  552. int end = value.Length();
  553. string a = value.Substring(0, start);
  554. string b = splice;
  555. if (middle >= end)
  556. {
  557. return a + b;
  558. }
  559.  
  560. string c = value.Substring(middle, end - middle);
  561. return a + b + c;
  562. }
  563.  
  564. /**
  565. * @brief Replaces the string of length at the index with the splice. New string does not have to match the length.
  566. *
  567. * @param start The index at which to start changing the string
  568. * @param length The length of characters to be removed
  569. * @param padChar The string the content will be replaced with
  570. *
  571. * @code
  572. * CF_String str = "How are you?";
  573. * Print(str.SpliceString(4, 3, "is"));
  574. * >> 'How is you?'
  575. * @endcode
  576. */
  577. string SpliceString(int start, int length, CF_String splice)
  578. {
  579. int middle = start + length;
  580. int end = value.Length();
  581. string a = value.Substring(0, start);
  582. string b = splice;
  583. if (middle >= end)
  584. {
  585. return a + b;
  586. }
  587.  
  588. string c = value.Substring(middle, end - middle);
  589. return a + b + c;
  590. }
  591.  
  592. /**
  593. * @brief Checks to see if the two string matches
  594. *
  595. * @param a The first string to be checked
  596. * @param b The second string to be checked
  597. *
  598. * @code
  599. * CF_String a = "How are you?";
  600. * CF_String b = "how are you?";
  601. *
  602. * Print(CF_String.Equals(a, b));
  603. * >> false
  604. *
  605. * b = "How are you?";
  606. * Print(CF_String.Equals(a, b));
  607. * >> true
  608. * @endcode
  609. */
  610. static bool Equals(string a, string b)
  611. {
  612. return a == b;
  613. }
  614.  
  615.  
  616. /**
  617. * @brief Checks to see if the two string matches, ignoring their case
  618. *
  619. * @param a The first string to be checked
  620. * @param b The second string to be checked
  621. *
  622. * @code
  623. * CF_String a = "How are you?";
  624. * CF_String b = "how are you?";
  625. *
  626. * Print(CF_String.EqualsIgnoreCase(a, b));
  627. * >> true
  628. *
  629. * b = "How are you?";
  630. * Print(CF_String.EqualsIgnoreCase(a, b));
  631. * >> true
  632. * @endcode
  633. */
  634. static bool EqualsIgnoreCase(string a, string b)
  635. {
  636. a.ToLower();
  637. b.ToLower();
  638.  
  639. return a == b;
  640. }
  641.  
  642. /**
  643. * @brief Reverses the string
  644. *
  645. * @code
  646. * CF_String a = "How are you?";
  647. * CF_String b = a.Reverse();
  648. *
  649. * Print(a);
  650. * >> "How are you?"
  651. * Print(b);
  652. * >> "?uoy era woH"
  653. *
  654. * @endcode
  655. */
  656. string Reverse()
  657. {
  658. string result;
  659.  
  660. int index = value.Length() - 1;
  661. while (index >= 0)
  662. {
  663. result += value.Substring(index, 1);
  664.  
  665. index--;
  666. }
  667.  
  668. return result;
  669. }
  670. };
  671. /*
  672. Uint Type Definition
  673. -- This is a CF_Uint datatype definition for EnScript
  674.  
  675. Author: Lystic, Jacob_Mango
  676.  
  677. When working with uints, Right Shift operations need to be handled by the ShiftRight method.
  678. */
  679.  
  680. typedef int CF_Uint;
  681. class CF_Uint : int
  682. {
  683. CF_Uint Add(CF_Uint b)
  684. {
  685. CF_Uint a = value;
  686. CF_Uint carry = a & b;
  687. CF_Uint result = a.XOR(b);
  688. while (carry)
  689. {
  690. CF_Uint shiftedcarry = carry << 1;
  691. carry = result & shiftedcarry;
  692. result = result.XOR(shiftedcarry);
  693. }
  694. return result;
  695. }
  696.  
  697. bool IsGt(CF_Uint b)
  698. {
  699. CF_Uint a = value;
  700.  
  701. CF_Uint ltb = ~a & b;
  702. CF_Uint gtb = a & ~b;
  703. ltb |= ltb.ShiftRight(1);
  704. ltb |= ltb.ShiftRight(2);
  705. ltb |= ltb.ShiftRight(4);
  706. ltb |= ltb.ShiftRight(8);
  707. ltb |= ltb.ShiftRight(16);
  708. CF_Uint isGt = gtb & ~ltb;
  709. return (isGt != 0); //non-zero if A > B
  710. }
  711.  
  712. bool IsLt(CF_Uint b)
  713. {
  714. return !b.IsGt(value);
  715. }
  716.  
  717. CF_Uint ShiftLeft(int amount)
  718. {
  719. return value << amount;
  720. }
  721.  
  722. CF_Uint ShiftRight(int amount)
  723. {
  724. if (amount <= 0) return value;
  725.  
  726. CF_Uint new_value = (value >> 1) & 0x7FFFFFFF; //strip the sign bit away (making it 0)
  727. CF_Uint extra_shifts = amount - 1;
  728. if (extra_shifts > 0) new_value = (new_value >> extra_shifts);
  729.  
  730. return new_value;
  731. }
  732.  
  733. //--- unsigned bitwise operations
  734.  
  735. static CF_Uint RotateLeft(CF_Uint a, CF_Uint b)
  736. {
  737. CF_Uint y = (a << b);
  738. CF_Uint x = (32 - b);
  739. CF_Uint z = a.ShiftRight(x);
  740. return (y | z);
  741. }
  742.  
  743. static CF_Uint RotateRight(CF_Uint a, CF_Uint b)
  744. {
  745. CF_Uint y = a.ShiftRight(b);
  746. CF_Uint x = (32 - b);
  747. CF_Uint z = (a << x);
  748. return (y | z);
  749. }
  750.  
  751. static CF_Uint CH(CF_Uint x, CF_Uint y, CF_Uint z)
  752. {
  753. CF_Uint a = (x & y);
  754. CF_Uint b = ~x;
  755. CF_Uint c = (b & z);
  756. return a.XOR(c); // a XOR c
  757. }
  758.  
  759. static CF_Uint MAJ(CF_Uint x, CF_Uint y, CF_Uint z)
  760. {
  761. CF_Uint a = x & y;
  762. CF_Uint b = x & z;
  763. CF_Uint c = y & z;
  764. return a.XOR(b.XOR(c))); //a XOR b XOR c (left-right associativity)
  765. }
  766.  
  767. static CF_Uint EP0(CF_Uint x)
  768. {
  769. CF_Uint a = CF_Uint.RotateRight(x, 2);
  770. CF_Uint b = CF_Uint.RotateRight(x, 13);
  771. CF_Uint c = CF_Uint.RotateRight(x, 22);
  772. return a.XOR(b.XOR(c))); //a XOR b XOR c
  773. }
  774.  
  775. static CF_Uint EP1(CF_Uint x)
  776. {
  777. CF_Uint a = CF_Uint.RotateRight(x, 6);
  778. CF_Uint b = CF_Uint.RotateRight(x, 11);
  779. CF_Uint c = CF_Uint.RotateRight(x, 25);
  780. return a.XOR(b.XOR(c))); //a XOR b XOR c
  781. }
  782.  
  783. static CF_Uint SIG0(CF_Uint x)
  784. {
  785. CF_Uint a = CF_Uint.RotateRight(x, 7);
  786. CF_Uint b = CF_Uint.RotateRight(x, 18);
  787. CF_Uint c = x.ShiftRight(3);
  788. return a.XOR(b.XOR(c))); //a XOR b XOR c
  789. }
  790.  
  791. static CF_Uint SIG1(CF_Uint x)
  792. {
  793. CF_Uint a = CF_Uint.RotateRight(x, 17);
  794. CF_Uint b = CF_Uint.RotateRight(x, 19);
  795. CF_Uint c = x.ShiftRight(10);
  796. return a.XOR(b.XOR(c))); //a XOR b XOR c
  797. }
  798.  
  799. CF_Uint XOR(CF_Uint y)
  800. {
  801. CF_Uint x = value;
  802. int a = (x | y);
  803. int b = ~x;
  804. int c = ~y;
  805. int d = (b | c);
  806. return (a & d);
  807. }
  808. };
  809. class CF_EventArgs
  810. {
  811. static const CF_EventArgs Empty = NULL;
  812.  
  813. override string GetDebugName()
  814. {
  815. return "[" + ClassName() + "]";
  816. }
  817. };
  818. class CF_EventTimeArgs : CF_EventArgs
  819. {
  820. int Time;
  821.  
  822. void CF_EventTimeArgs(int time)
  823. {
  824. Time = time;
  825. }
  826. };
  827. class CF_EventUpdateArgs : CF_EventArgs
  828. {
  829. float DeltaTime;
  830.  
  831. void CF_EventUpdateArgs(float deltaTime = 0)
  832. {
  833. DeltaTime = deltaTime;
  834. }
  835. };
  836. class CF_Directory
  837. {
  838. /**
  839. * @param pattern The search pattern
  840. * @param [inout] files An array where the list of files will be written to
  841. * @param flags If it should be looked in directories or .pak files, or both
  842. *
  843. * @return If any files were found that matched the pattern
  844. */
  845. static bool GetFiles(string pattern, inout array<ref CF_File> files, FindFileFlags flags = 2)
  846. {
  847. #ifdef CF_TRACE_ENABLED
  848. auto trace = CF_Trace_3("CF_Directory", "GetFiles").Add(pattern).Add(files).Add(flags);
  849. #endif
  850.  
  851. if (!files)
  852. {
  853. files = new array<ref CF_File>();
  854. }
  855.  
  856. pattern.Replace("\\", CF_Path.DIRECTORY_SEPARATOR);
  857.  
  858. string fileName;
  859. FileAttr fileAttr;
  860. FindFileHandle handle = FindFile(pattern, fileName, fileAttr, flags);
  861. if (!handle)
  862. {
  863. return false;
  864. }
  865.  
  866. string folder = CF_Path.GetDirectoryName(pattern);
  867.  
  868. CF_File file;
  869. while (true)
  870. {
  871. file = new CF_File();
  872.  
  873. file._SetFileName(fileName);
  874. file._SetFolder(folder);
  875. file._SetAttributes(fileAttr);
  876.  
  877. files.Insert(file);
  878.  
  879. if (!FindNextFile(handle, fileName, fileAttr))
  880. {
  881. break;
  882. }
  883. }
  884.  
  885. CloseFindFile(handle);
  886.  
  887. return true;
  888. }
  889.  
  890. /**
  891. * @brief Creates all directories and subdirectories in the specified path unless they already exist.
  892. *
  893. * @param directory The directory to create.
  894. *
  895. * @return If the directories could be created
  896. */
  897. static bool CreateDirectory(string directory)
  898. {
  899. array<string> directories();
  900. string path = directory;
  901.  
  902. string previousPath = "";
  903. while (true)
  904. {
  905. previousPath = path;
  906. if (FileExist(previousPath))
  907. {
  908. break;
  909. }
  910.  
  911. path = CF_Path.GetDirectoryName(path);
  912. if (previousPath == path)
  913. {
  914. path = previousPath;
  915. break;
  916. }
  917.  
  918. if (previousPath[previousPath.Length() - 1] == CF_Path.FILESYSTEM_IDENTIFIER)
  919. {
  920. return false;
  921. }
  922.  
  923. directory = CF_Path.GetFileNameEx(previousPath, path);
  924. directory = directory.Substring(0, directory.Length() - 1);
  925.  
  926. directories.Insert(directory);
  927. }
  928.  
  929. for (int i = directories.Count() - 1; i >= 0; i--)
  930. {
  931. path = path + directories[i] + CF_Path.DIRECTORY_SEPARATOR;
  932.  
  933. if (!MakeDirectory(path))
  934. {
  935. return false;
  936. }
  937. }
  938.  
  939. return true;
  940. }
  941. };
  942. class CF_File : Managed
  943. {
  944. protected string m_Directory;
  945. protected string m_FileName;
  946. protected string m_Extension;
  947.  
  948. protected bool m_IsDirectory;
  949. protected bool m_IsHidden;
  950. protected bool m_IsReadOnly;
  951. protected bool m_IsValid;
  952.  
  953. /**
  954. * @brief Constructor
  955. *
  956. * @param path No operation perform if path is empty string
  957. */
  958. void CF_File(string path = "")
  959. {
  960. m_IsValid = true;
  961.  
  962. // Default constructor
  963. if (path == string.Empty)
  964. {
  965. return;
  966. }
  967.  
  968. string fileName;
  969. FileAttr fileAttr;
  970. FindFileHandle handle = FindFile(path, fileName, fileAttr, FindFileFlags.ALL);
  971. if (!handle)
  972. {
  973. return;
  974. }
  975.  
  976. _SetFolder(CF_Path.GetDirectoryName(path));
  977. _SetFileName(fileName);
  978. _SetAttributes(fileAttr);
  979.  
  980. CloseFindFile(handle);
  981. }
  982.  
  983. bool IsDirectory()
  984. {
  985. return m_IsDirectory;
  986. }
  987.  
  988. bool IsHidden()
  989. {
  990. return m_IsHidden;
  991. }
  992.  
  993. bool IsReadOnly()
  994. {
  995. return m_IsReadOnly;
  996. }
  997.  
  998. bool IsValid()
  999. {
  1000. return m_IsValid;
  1001. }
  1002.  
  1003. /**
  1004. * @brief Returns the path, including file name and extension if they exist
  1005. */
  1006. string GetFullPath()
  1007. {
  1008. return m_Directory + m_FileName + m_Extension;
  1009. }
  1010.  
  1011. /**
  1012. * @brief Returns the file name and extension
  1013. */
  1014. string GetFileName()
  1015. {
  1016. return m_FileName + m_Extension;
  1017. }
  1018.  
  1019. /**
  1020. * @brief Returns the file name without the extension
  1021. */
  1022. string GetFileNameWithoutExtension()
  1023. {
  1024. return m_FileName;
  1025. }
  1026.  
  1027. /**
  1028. * @brief Returns the extension (including the period ".")
  1029. */
  1030. string GetExtension()
  1031. {
  1032. return m_Extension;
  1033. }
  1034.  
  1035. /**
  1036. * @brief Returns the full path of the parent folder
  1037. */
  1038. string GetDirectory()
  1039. {
  1040. return m_Directory;
  1041. }
  1042.  
  1043. /**
  1044. * @brief Creates and opens a new instance of a FileStream for the current file
  1045. *
  1046. * @param mode Sets the file mode the stream will be opened in
  1047. *
  1048. * @return new instance of CF_FileStream
  1049. */
  1050. CF_Stream CreateStream(FileMode mode)
  1051. {
  1052. #ifdef CF_TRACE_ENABLED
  1053. auto trace = CF_Trace_1(this, "CreateStream").Add(mode);
  1054. #endif
  1055.  
  1056. if (!IsValid())
  1057. {
  1058. return null;
  1059. }
  1060.  
  1061. return new CF_FileStream(GetFullPath(), mode);
  1062. }
  1063.  
  1064. /**
  1065. * @brief Deletes the current file
  1066. *
  1067. * @return true if the operation was successful
  1068. */
  1069. bool Delete()
  1070. {
  1071. #ifdef CF_TRACE_ENABLED
  1072. auto trace = CF_Trace_0(this, "Delete");
  1073. #endif
  1074.  
  1075. if (!IsValid())
  1076. {
  1077. return false;
  1078. }
  1079.  
  1080. return DeleteFile(GetFullPath());
  1081. }
  1082.  
  1083. /**
  1084. * @brief Renames the current file (copy to new name, then delete original)
  1085. *
  1086. * @param name The new name of the file
  1087. *
  1088. * @return true if the operation was successful
  1089. */
  1090. bool Rename(string name)
  1091. {
  1092. #ifdef CF_TRACE_ENABLED
  1093. auto trace = CF_Trace_1(this, "Rename").Add(name);
  1094. #endif
  1095.  
  1096. if (!IsValid())
  1097. {
  1098. return false;
  1099. }
  1100.  
  1101. // Check if the file already exists at the destination
  1102. if (FileExist(m_Directory + name))
  1103. {
  1104. return false;
  1105. }
  1106.  
  1107. // Copy file to new name
  1108. if (!CopyFile(GetFullPath(), m_Directory + name))
  1109. {
  1110. return false;
  1111. }
  1112.  
  1113. // Delete old file
  1114. bool success = DeleteFile(GetFullPath());
  1115. if (!success)
  1116. {
  1117. CF_Log.Warn("Failed to delete original file in rename for file \"%1\"", GetFullPath());
  1118. }
  1119.  
  1120. _SetFileName(name);
  1121.  
  1122. return true;
  1123. }
  1124.  
  1125. /**
  1126. * @brief Moves the file to the new path (copy to folder, then delete original)
  1127. *
  1128. * @param path The new path
  1129. *
  1130. * @return true if the operation was successful
  1131. */
  1132. bool Move(string path)
  1133. {
  1134. #ifdef CF_TRACE_ENABLED
  1135. auto trace = CF_Trace_1(this, "Move").Add(path);
  1136. #endif
  1137.  
  1138. if (!IsValid())
  1139. {
  1140. return false;
  1141. }
  1142.  
  1143. string folder = CF_Path.GetDirectoryName(path);
  1144. string name = CF_Path.GetFileNameEx(path, folder);
  1145.  
  1146. // File isn't being renamed in move
  1147. if (name == string.Empty)
  1148. {
  1149. name = GetFileName();
  1150. }
  1151.  
  1152. // Check if the file already exists at the destination
  1153. if (FileExist(folder + name))
  1154. {
  1155. return false;
  1156. }
  1157.  
  1158. if (!CopyFile(GetFullPath(), folder + name))
  1159. {
  1160. return false;
  1161. }
  1162.  
  1163. // Delete old file
  1164. bool success = DeleteFile(GetFullPath());
  1165. if (!success)
  1166. {
  1167. CF_Log.Warn("Failed to delete original file in move for file \"%1\"", GetFullPath());
  1168. }
  1169.  
  1170. _SetFolder(folder);
  1171. _SetFileName(name);
  1172.  
  1173. return true;
  1174. }
  1175.  
  1176. /**
  1177. * @brief Copies the file to the new path
  1178. *
  1179. * @param path The new path
  1180. *
  1181. * @return true if the operation was successful
  1182. */
  1183. bool Copy(string path)
  1184. {
  1185. #ifdef CF_TRACE_ENABLED
  1186. auto trace = CF_Trace_1(this, "Move").Add(path);
  1187. #endif
  1188.  
  1189. if (!IsValid())
  1190. {
  1191. return false;
  1192. }
  1193.  
  1194. string folder = CF_Path.GetDirectoryName(path);
  1195. string name = CF_Path.GetFileNameEx(path, folder);
  1196.  
  1197. // File isn't being renamed in move
  1198. if (name == string.Empty)
  1199. {
  1200. name = GetFileName();
  1201. }
  1202.  
  1203. // Check if the file already exists at the destination
  1204. if (FileExist(folder + name))
  1205. {
  1206. CF_Log.Warn("The file already exists at \"%1\".", folder + name);
  1207. return false;
  1208. }
  1209.  
  1210. if (!CopyFile(GetFullPath(), folder + name))
  1211. {
  1212. CF_Log.Warn("Failed to copy file to \"%1\".", folder + name);
  1213. return false;
  1214. }
  1215.  
  1216. return true;
  1217. }
  1218.  
  1219. /**
  1220. * @brief Copies the file to the new path, returning the instance of the file
  1221. *
  1222. * @param path The new path
  1223. * @param [out] newFile Outputs the new instance of the file
  1224. *
  1225. * @return true if the operation was successful
  1226. */
  1227. bool Copy(string path, out CF_File newFile)
  1228. {
  1229. #ifdef CF_TRACE_ENABLED
  1230. auto trace = CF_Trace_1(this, "Copy").Add(path);
  1231. #endif
  1232.  
  1233. if (!IsValid())
  1234. {
  1235. return false;
  1236. }
  1237.  
  1238. string folder = CF_Path.GetDirectoryName(path);
  1239. string name = CF_Path.GetFileNameEx(path, folder);
  1240.  
  1241. // File isn't being renamed in move
  1242. if (name == string.Empty)
  1243. {
  1244. name = GetFileName();
  1245. }
  1246.  
  1247. // Check if the file already exists at the destination
  1248. if (FileExist(folder + name))
  1249. {
  1250. CF_Log.Warn("The file already exists at \"%1\".", folder + name);
  1251. return false;
  1252. }
  1253.  
  1254. if (!CopyFile(GetFullPath(), folder + name))
  1255. {
  1256. CF_Log.Warn("Failed to copy file to \"%1\".", folder + name);
  1257. return false;
  1258. }
  1259.  
  1260. newFile = new CF_File(path);
  1261.  
  1262. return true;
  1263. }
  1264.  
  1265. override string GetDebugName()
  1266. {
  1267. return "{path=\"" + GetFullPath() + "\", filename=\"" + GetFileName() + "\", directory=" + m_IsDirectory.ToString() + ", hidden=" + m_IsHidden.ToString() + ", readonly=" + m_IsReadOnly.ToString() + ", valid=" + m_IsValid.ToString() + "}";
  1268. }
  1269.  
  1270. void _SetFolder(string folder)
  1271. {
  1272. m_Directory = folder;
  1273. }
  1274.  
  1275. void _SetFileName(CF_String fileName)
  1276. {
  1277. int index = fileName.CF_LastIndexOf(".");
  1278. if (index == -1)
  1279. {
  1280. m_FileName = fileName;
  1281. m_Extension = "";
  1282. return;
  1283. }
  1284.  
  1285. m_Extension = fileName.Substring(index, fileName.Length() - index);
  1286. m_FileName = fileName.Substring(0, fileName.Length() - m_Extension.Length());
  1287. }
  1288.  
  1289. void _SetAttributes(FileAttr fileAttr)
  1290. {
  1291. m_IsDirectory = (fileAttr & FileAttr.DIRECTORY) != 0;
  1292. m_IsHidden = (fileAttr & FileAttr.HIDDEN) != 0;
  1293. m_IsReadOnly = (fileAttr & FileAttr.READONLY) != 0;
  1294. m_IsValid = (fileAttr & FileAttr.INVALID) != 0;
  1295. }
  1296. };
  1297. class CF_Path
  1298. {
  1299. static string DIRECTORY_SEPARATOR = "/";
  1300. static string ALT_DIRECTORY_SEPARATOR = "\\";
  1301. static string FILESYSTEM_IDENTIFIER = ":";
  1302.  
  1303. static autoptr array<string> DIRECTORY_CHECKS = { DIRECTORY_SEPARATOR, ALT_DIRECTORY_SEPARATOR, FILESYSTEM_IDENTIFIER };
  1304.  
  1305. /**
  1306. * @brief Returns the directory information for the specified path.
  1307. *
  1308. * @param path The path of a file or directory.
  1309. *
  1310. * @return Directory information for path. Returns an empty string if path does not contain directory information.
  1311. */
  1312. static string GetDirectoryName(CF_String path)
  1313. {
  1314. path.Replace(CF_Path.ALT_DIRECTORY_SEPARATOR, CF_Path.DIRECTORY_SEPARATOR);
  1315.  
  1316. int index = path.CF_LastIndexOf(CF_Path.DIRECTORY_SEPARATOR);
  1317. if (index != -1)
  1318. {
  1319. return path.Substring(0, index) + CF_Path.DIRECTORY_SEPARATOR;
  1320. }
  1321.  
  1322. index = path.CF_LastIndexOf(CF_Path.FILESYSTEM_IDENTIFIER);
  1323. if (index != -1)
  1324. {
  1325. return path.Substring(0, index) + CF_Path.FILESYSTEM_IDENTIFIER;
  1326. }
  1327.  
  1328. return string.Empty;
  1329. }
  1330.  
  1331. /**
  1332. * @brief Returns the file name and extension of the specified path string.
  1333. *
  1334. * @param path The path string from which to obtain the file name and extension.
  1335. *
  1336. * @return The characters after the last directory separator character in path. If the last character of path is a directory or volume separator character, this method returns an empty string.
  1337. */
  1338. static string GetFileName(string path)
  1339. {
  1340. return GetFileNameEx(path, GetDirectoryName(path));
  1341. }
  1342.  
  1343. /**
  1344. * @brief Returns the file name and extension of the specified path string.
  1345. *
  1346. * @param path The path string from which to obtain the file name and extension.
  1347. *
  1348. * @return The characters after the last directory separator character in path. If the last character of path is a directory or volume separator character, this method returns an empty string.
  1349. */
  1350. static string GetFileNameEx(string path, string folder)
  1351. {
  1352. int start = folder.Length();
  1353. int end = path.Length() - folder.Length();
  1354. if (end <= 0)
  1355. {
  1356. return string.Empty;
  1357. }
  1358.  
  1359. if (DIRECTORY_CHECKS.Find(path[end]) != -1)
  1360. {
  1361. return string.Empty;
  1362. }
  1363.  
  1364. return path.Substring(start, end);
  1365. }
  1366.  
  1367. /**
  1368. * @brief Returns the file name of the specified path string.
  1369. *
  1370. * @param path The path string from which to obtain the file name.
  1371. *
  1372. * @return The characters after the last directory separator character in path. If the last character of path is a directory or volume separator character, this method returns an empty string.
  1373. */
  1374. static string GetFileNameWithoutExtension(string path)
  1375. {
  1376. return GetFileNameWithoutExtensionEx(path, GetDirectoryName(path));
  1377. }
  1378.  
  1379. /**
  1380. * @brief Returns the file name of the specified path string.
  1381. *
  1382. * @param path The path string from which to obtain the file name.
  1383. *
  1384. * @return The characters after the last directory separator character in path. If the last character of path is a directory or volume separator character, this method returns an empty string.
  1385. */
  1386. static string GetFileNameWithoutExtensionEx(string path, string folder)
  1387. {
  1388. int start = folder.Length();
  1389. int end = path.Length() - folder.Length();
  1390. if (end <= 0)
  1391. {
  1392. return string.Empty;
  1393. }
  1394.  
  1395. if (DIRECTORY_CHECKS.Find(path[end]) != -1)
  1396. {
  1397. return string.Empty;
  1398. }
  1399.  
  1400. CF_String fileName = path.Substring(start, end);
  1401.  
  1402. int index = fileName.CF_LastIndexOf(".");
  1403. if (index != -1)
  1404. {
  1405. fileName = fileName.Substring(0, index);
  1406. }
  1407.  
  1408. return fileName;
  1409. }
  1410.  
  1411. /**
  1412. * @brief Returns the extension (including the period ".") of the specified path string.
  1413. *
  1414. * @param path The path string from which to get the extension.
  1415. *
  1416. * @return The path string from which to get the extension. If path does not have extension information, this method returns an empty string.
  1417. */
  1418. static string GetExtension(CF_String path)
  1419. {
  1420. int index = path.CF_LastIndexOf(".");
  1421. if (index == -1)
  1422. {
  1423. return string.Empty;
  1424. }
  1425.  
  1426. return path.Substring(index, path.Length() - index);
  1427. }
  1428. };
  1429. typedef CF_Base16Stream CF_HexStream;
  1430.  
  1431. class CF_Base16Stream : CF_Stream
  1432. {
  1433. protected string m_String;
  1434.  
  1435. protected bool m_Dirty;
  1436.  
  1437. void CF_Base16Stream(string str = "")
  1438. {
  1439. Decode(str);
  1440. }
  1441.  
  1442. override void Append(CF_Byte byte = 0)
  1443. {
  1444. super.Append(byte);
  1445.  
  1446. m_Dirty = true;
  1447. }
  1448.  
  1449. override void AppendCurrent(CF_Byte byte = 0)
  1450. {
  1451. super.AppendCurrent(byte);
  1452.  
  1453. m_Dirty = true;
  1454. }
  1455.  
  1456. override void SetOrigin(int index, int value, CF_SeekOrigin origin)
  1457. {
  1458. super.SetOrigin(index, value, origin);
  1459.  
  1460. m_Dirty = true;
  1461. }
  1462.  
  1463. override void Set(int index, int value)
  1464. {
  1465. super.Set(index, value);
  1466.  
  1467. m_Dirty = true;
  1468. }
  1469.  
  1470. override void Resize(int size)
  1471. {
  1472. super.Resize(size);
  1473.  
  1474. m_Dirty = true;
  1475. }
  1476.  
  1477. void Decode(string str)
  1478. {
  1479. if (m_String != str)
  1480. {
  1481. m_String = str;
  1482.  
  1483. for (int i = 0; i < m_String.Length() / 2; i++)
  1484. {
  1485. int n0 = CF_Encoding.Find(CF_Encoding.BASE_16, 16, m_String[i * 2 + 0]) * 16;
  1486. int n1 = CF_Encoding.Find(CF_Encoding.BASE_16, 16, m_String[i * 2 + 1]) * 16;
  1487.  
  1488. if (n0 < 0 || n1 < 0)
  1489. {
  1490. Error("Invalid character, expect valid base-16, got \"" + m_String[i * 2 + 0] + m_String[i * 2 + 1] + "\"");
  1491. return;
  1492. }
  1493.  
  1494. Append(n0 + n1);
  1495. }
  1496. }
  1497.  
  1498. Seek(0, CF_SeekOrigin.SET);
  1499. }
  1500.  
  1501. string Encode()
  1502. {
  1503. UpdateDirty();
  1504.  
  1505. return m_String;
  1506. }
  1507.  
  1508. protected void UpdateDirty()
  1509. {
  1510. if (!m_Dirty) return;
  1511.  
  1512. m_String = "";
  1513.  
  1514. int oldPosition = m_Position;
  1515. CF_PackedByte oldCurrent = m_Current;
  1516.  
  1517. m_Position = 0;
  1518. m_Current = m_Head;
  1519.  
  1520. while (m_Current)
  1521. {
  1522. m_String += m_Current.m_Value.ToHex();
  1523.  
  1524. m_Current = m_Current.m_Next;
  1525. }
  1526.  
  1527. m_Position = oldPosition;
  1528. m_Current = oldCurrent;
  1529.  
  1530. m_Dirty = false;
  1531. }
  1532. };
  1533. class CF_Base64Stream : CF_Stream
  1534. {
  1535. static const string s_Padding[3] = { "", "=", "==" };
  1536.  
  1537. protected string m_String;
  1538.  
  1539. protected bool m_Dirty;
  1540.  
  1541. void CF_Base64Stream(string str = "")
  1542. {
  1543. Decode(str);
  1544. }
  1545.  
  1546. override void Append(CF_Byte byte = 0)
  1547. {
  1548. super.Append(byte);
  1549.  
  1550. m_Dirty = true;
  1551. }
  1552.  
  1553. override void AppendCurrent(CF_Byte byte = 0)
  1554. {
  1555. super.AppendCurrent(byte);
  1556.  
  1557. m_Dirty = true;
  1558. }
  1559.  
  1560. override void SetOrigin(int index, int value, CF_SeekOrigin origin)
  1561. {
  1562. super.SetOrigin(index, value, origin);
  1563.  
  1564. m_Dirty = true;
  1565. }
  1566.  
  1567. override void Set(int index, int value)
  1568. {
  1569. super.Set(index, value);
  1570.  
  1571. m_Dirty = true;
  1572. }
  1573.  
  1574. override void Resize(int size)
  1575. {
  1576. super.Resize(size);
  1577.  
  1578. m_Dirty = true;
  1579. }
  1580.  
  1581. void Decode(string str)
  1582. {
  1583. if (m_String != str)
  1584. {
  1585. m_String = str;
  1586.  
  1587. int padding = 0;
  1588. int i = 0;
  1589.  
  1590. while (i < m_String.Length())
  1591. {
  1592. int value;
  1593.  
  1594. for (int j = 0; j < 4; j++)
  1595. {
  1596. int n = CF_Encoding.Find(CF_Encoding.BASE_64, 64, m_String.Substring(i, 1));
  1597. i++;
  1598. if (n == -1)
  1599. {
  1600. padding++;
  1601. continue;
  1602. }
  1603.  
  1604. value += n << ((18 - j * 6));
  1605. }
  1606.  
  1607. Append((value >> 16 ) & 255);
  1608. Append((value >> 8 ) & 255);
  1609. Append((value ) & 255);
  1610. }
  1611.  
  1612. Resize(m_Size - padding);
  1613. }
  1614.  
  1615. Seek(0, CF_SeekOrigin.SET);
  1616. }
  1617.  
  1618. string Encode()
  1619. {
  1620. UpdateDirty();
  1621.  
  1622. return m_String;
  1623. }
  1624.  
  1625. protected void UpdateDirty()
  1626. {
  1627. if (!m_Dirty) return;
  1628.  
  1629. m_String = "";
  1630.  
  1631. int oldPosition = m_Position;
  1632. CF_PackedByte oldCurrent = m_Current;
  1633.  
  1634. m_Position = 0;
  1635. m_Current = m_Head;
  1636.  
  1637. while (m_Current)
  1638. {
  1639. CF_Uint value = 0;
  1640.  
  1641. value = value.Add(m_Current.m_Value << 16);
  1642. m_Current = m_Current.m_Next;
  1643.  
  1644. if (m_Current)
  1645. {
  1646. value = value.Add(m_Current.m_Value << 8);
  1647. m_Current = m_Current.m_Next;
  1648. }
  1649.  
  1650. if (m_Current)
  1651. {
  1652. value = value.Add(m_Current.m_Value);
  1653. m_Current = m_Current.m_Next;
  1654. }
  1655.  
  1656. m_String += CF_Encoding.BASE_64[value.ShiftRight(18) & 63];
  1657. m_String += CF_Encoding.BASE_64[value.ShiftRight(12) & 63];
  1658. m_String += CF_Encoding.BASE_64[value.ShiftRight(6) & 63];
  1659. m_String += CF_Encoding.BASE_64[value & 63];
  1660. }
  1661.  
  1662. int pad = 3 - (m_Size % 3);
  1663. m_String = m_String.Substring(0, m_String.Length() - pad) + s_Padding[pad];
  1664.  
  1665. m_Position = oldPosition;
  1666. m_Current = oldCurrent;
  1667.  
  1668. m_Dirty = false;
  1669. }
  1670. };
  1671. class CF_BinaryReader : CF_IO
  1672. {
  1673. override bool IsRead()
  1674. {
  1675. return true;
  1676. }
  1677.  
  1678. override bool IsWrite()
  1679. {
  1680. return false;
  1681. }
  1682.  
  1683. override CF_Byte ReadByte()
  1684. {
  1685. return m_Stream.Next();
  1686. }
  1687.  
  1688. override array<CF_Byte> ReadBytes(int count)
  1689. {
  1690. array<CF_Byte> bytes = {};
  1691. ReadBytes(count, bytes);
  1692.  
  1693. return bytes;
  1694. }
  1695.  
  1696. override void ReadBytes(int count, inout array<CF_Byte> bytes)
  1697. {
  1698. bytes.Reserve(count);
  1699. for (int i = 0; i < count; i++)
  1700. {
  1701. CF_Byte byte = m_Stream.Next();
  1702. bytes.Insert(byte);
  1703. }
  1704. }
  1705.  
  1706. override string ReadChar()
  1707. {
  1708. int byte = m_Stream.Next();
  1709. return byte.AsciiToString();
  1710. }
  1711.  
  1712. override bool ReadBool()
  1713. {
  1714. return m_Stream.Next() != 0;
  1715. }
  1716.  
  1717. override int ReadShort()
  1718. {
  1719. int b0 = m_Stream.Next();
  1720. int b1 = m_Stream.Next();
  1721.  
  1722. return ((b1 & 0x000000FF) << 8) + (b0);
  1723. }
  1724.  
  1725. override int ReadInt()
  1726. {
  1727. int b0 = m_Stream.Next();
  1728. int b1 = m_Stream.Next();
  1729. int b2 = m_Stream.Next();
  1730. int b3 = m_Stream.Next();
  1731.  
  1732. return ((b3 & 0x000000FF) << 24) + ((b2 & 0x000000FF) << 16) + ((b1 & 0x000000FF) << 8) + (b0);
  1733. }
  1734.  
  1735. override float ReadFloat()
  1736. {
  1737. int b0 = m_Stream.Next();
  1738. int b1 = m_Stream.Next();
  1739. int b2 = m_Stream.Next();
  1740. int b3 = m_Stream.Next();
  1741.  
  1742. int src[1];
  1743. src[0] = ((b3 & 0x000000FF) << 24) + ((b2 & 0x000000FF) << 16) + ((b1 & 0x000000FF) << 8) + (b0);
  1744. float dst[1];
  1745.  
  1746. copyarray(dst, src);
  1747.  
  1748. return dst[0];
  1749. }
  1750.  
  1751. override vector ReadVector()
  1752. {
  1753. int b3;
  1754. int b2;
  1755. int b1;
  1756. int b0;
  1757.  
  1758. int src[3];
  1759. vector dst;
  1760.  
  1761. b0 = m_Stream.Next();
  1762. b1 = m_Stream.Next();
  1763. b2 = m_Stream.Next();
  1764. b3 = m_Stream.Next();
  1765. src[0] = ((b3 & 0x000000FF) << 24) + ((b2 & 0x000000FF) << 16) + ((b1 & 0x000000FF) << 8) + (b0);
  1766.  
  1767. b0 = m_Stream.Next();
  1768. b1 = m_Stream.Next();
  1769. b2 = m_Stream.Next();
  1770. b3 = m_Stream.Next();
  1771. src[1] = ((b3 & 0x000000FF) << 24) + ((b2 & 0x000000FF) << 16) + ((b1 & 0x000000FF) << 8) + (b0);
  1772.  
  1773. b0 = m_Stream.Next();
  1774. b1 = m_Stream.Next();
  1775. b2 = m_Stream.Next();
  1776. b3 = m_Stream.Next();
  1777. src[2] = ((b3 & 0x000000FF) << 24) + ((b2 & 0x000000FF) << 16) + ((b1 & 0x000000FF) << 8) + (b0);
  1778.  
  1779. copyarray(dst, src);
  1780.  
  1781. return dst;
  1782. }
  1783.  
  1784. override string ReadString()
  1785. {
  1786. int b0 = m_Stream.Next();
  1787. int b1 = m_Stream.Next();
  1788. int b2 = m_Stream.Next();
  1789. int b3 = m_Stream.Next();
  1790.  
  1791. int length = ((b3 & 0x000000FF) << 24) + ((b2 & 0x000000FF) << 16) + ((b1 & 0x000000FF) << 8) + (b0);
  1792.  
  1793. string str;
  1794.  
  1795. for (int index = 0; index < length; index++)
  1796. {
  1797. str += m_Stream.Next().AsciiToString();
  1798. }
  1799.  
  1800. return str;
  1801. }
  1802.  
  1803. override string ReadCString()
  1804. {
  1805. string str;
  1806.  
  1807. int c = m_Stream.Next();
  1808. while (c != 0)
  1809. {
  1810. str += c.AsciiToString();
  1811. c = m_Stream.Next();
  1812. }
  1813.  
  1814. return str;
  1815. }
  1816. };
  1817. class CF_BinaryWriter : CF_IO
  1818. {
  1819. override bool IsRead()
  1820. {
  1821. return false;
  1822. }
  1823.  
  1824. override bool IsWrite()
  1825. {
  1826. return true;
  1827. }
  1828.  
  1829. override void WriteByte(CF_Byte value)
  1830. {
  1831. m_Stream.AppendCurrent(value);
  1832. }
  1833.  
  1834. override void WriteBytes(array<CF_Byte> bytes)
  1835. {
  1836. for (int i = 0; i < bytes.Count(); i++)
  1837. {
  1838. WriteByte(bytes[i]);
  1839. }
  1840. }
  1841.  
  1842. override void WriteChar(string value)
  1843. {
  1844. m_Stream.AppendCurrent(value.ToAscii());
  1845. }
  1846.  
  1847. override void WriteBool(bool value)
  1848. {
  1849. m_Stream.AppendCurrent(value != 0);
  1850. }
  1851.  
  1852. override void WriteShort(int value)
  1853. {
  1854. m_Stream.AppendCurrent((value ) & 0x000000FF);
  1855. m_Stream.AppendCurrent((value >> 8 ) & 0x000000FF);
  1856. }
  1857.  
  1858. override void WriteInt(int value)
  1859. {
  1860. m_Stream.AppendCurrent((value ) & 0x000000FF);
  1861. m_Stream.AppendCurrent((value >> 8 ) & 0x000000FF);
  1862. m_Stream.AppendCurrent((value >> 16) & 0x000000FF);
  1863. m_Stream.AppendCurrent((value >> 24) & 0x000000FF);
  1864. }
  1865.  
  1866. override void WriteFloat(float value)
  1867. {
  1868. float src[1] = { value };
  1869. int dst[1];
  1870. copyarray(dst, src);
  1871.  
  1872. m_Stream.AppendCurrent((dst[0] ) & 0x000000FF);
  1873. m_Stream.AppendCurrent((dst[0] >> 8 ) & 0x000000FF);
  1874. m_Stream.AppendCurrent((dst[0] >> 16) & 0x000000FF);
  1875. m_Stream.AppendCurrent((dst[0] >> 24) & 0x000000FF);
  1876. }
  1877.  
  1878. override void WriteVector(vector value)
  1879. {
  1880. int dst[3];
  1881. copyarray(dst, value);
  1882.  
  1883. int a = dst[0];
  1884. int b = dst[1];
  1885. int c = dst[2];
  1886.  
  1887. m_Stream.AppendCurrent((a ) & 0x000000FF);
  1888. m_Stream.AppendCurrent((a >> 8 ) & 0x000000FF);
  1889. m_Stream.AppendCurrent((a >> 16) & 0x000000FF);
  1890. m_Stream.AppendCurrent((a >> 24) & 0x000000FF);
  1891.  
  1892. m_Stream.AppendCurrent((b ) & 0x000000FF);
  1893. m_Stream.AppendCurrent((b >> 8 ) & 0x000000FF);
  1894. m_Stream.AppendCurrent((b >> 16) & 0x000000FF);
  1895. m_Stream.AppendCurrent((b >> 24) & 0x000000FF);
  1896.  
  1897. m_Stream.AppendCurrent((c ) & 0x000000FF);
  1898. m_Stream.AppendCurrent((c >> 8 ) & 0x000000FF);
  1899. m_Stream.AppendCurrent((c >> 16) & 0x000000FF);
  1900. m_Stream.AppendCurrent((c >> 24) & 0x000000FF);
  1901. }
  1902.  
  1903. override void WriteString(string value)
  1904. {
  1905. int length = value.Length();
  1906. m_Stream.AppendCurrent((length ) & 0x000000FF);
  1907. m_Stream.AppendCurrent((length >> 8 ) & 0x000000FF);
  1908. m_Stream.AppendCurrent((length >> 16) & 0x000000FF);
  1909. m_Stream.AppendCurrent((length >> 24) & 0x000000FF);
  1910.  
  1911. for (int i = 0; i < value.Length(); i++)
  1912. {
  1913. m_Stream.AppendCurrent(value.Get(i).ToAscii());
  1914. }
  1915. }
  1916.  
  1917. override void WriteCString(string value)
  1918. {
  1919. for (int i = 0; i < value.Length(); i++)
  1920. {
  1921. m_Stream.AppendCurrent(value.Get(i).ToAscii());
  1922. }
  1923.  
  1924. m_Stream.AppendCurrent(0);
  1925. }
  1926. };
  1927. class CF_FileStream : CF_Stream
  1928. {
  1929. string m_Path;
  1930. FileMode m_Mode;
  1931.  
  1932. FileHandle m_FileHandle;
  1933.  
  1934. protected bool m_Dirty;
  1935. protected int m_NonZeroCount;
  1936. protected int m_NonZeroes[4];
  1937.  
  1938. void CF_FileStream(string path, FileMode mode)
  1939. {
  1940. m_Path = path;
  1941. m_Mode = mode;
  1942.  
  1943. m_FileHandle = OpenFile(m_Path, m_Mode);
  1944.  
  1945. m_IsOpen = m_FileHandle != 0;
  1946.  
  1947. ReadData(false);
  1948. }
  1949.  
  1950. void MarkDirty()
  1951. {
  1952. m_Dirty = true;
  1953. }
  1954.  
  1955. override void Append(CF_Byte byte = 0)
  1956. {
  1957. super.Append(byte);
  1958.  
  1959. m_Dirty = true;
  1960. }
  1961.  
  1962. override void AppendCurrent(CF_Byte byte = 0)
  1963. {
  1964. super.AppendCurrent(byte);
  1965.  
  1966. m_Dirty = true;
  1967. }
  1968.  
  1969. override void SetOrigin(int index, int value, CF_SeekOrigin origin)
  1970. {
  1971. super.SetOrigin(index, value, origin);
  1972.  
  1973. m_Dirty = true;
  1974. }
  1975.  
  1976. override void Set(int index, int value)
  1977. {
  1978. super.Set(index, value);
  1979.  
  1980. m_Dirty = true;
  1981. }
  1982.  
  1983. override void Resize(int size)
  1984. {
  1985. super.Resize(size);
  1986.  
  1987. m_Dirty = true;
  1988. }
  1989.  
  1990. override bool IsValid()
  1991. {
  1992. return m_FileHandle != 0;
  1993. }
  1994.  
  1995. void ReadData(bool reopen = true)
  1996. {
  1997. if (reopen)
  1998. {
  1999. if (m_FileHandle != 0) CloseFile(m_FileHandle);
  2000.  
  2001. m_FileHandle = OpenFile(m_Path, m_Mode);
  2002. }
  2003.  
  2004. if (m_FileHandle == 0) return;
  2005.  
  2006. if (m_Mode != FileMode.READ) return;
  2007.  
  2008. Resize(0);
  2009.  
  2010. bool readData[1];
  2011. while (ReadFile(m_FileHandle, readData, 1) > 0)
  2012. {
  2013. Append(readData[0] & 0x000000FF);
  2014. }
  2015.  
  2016. Seek(0, CF_SeekOrigin.SET);
  2017. }
  2018.  
  2019. override void Flush()
  2020. {
  2021. if (m_Mode == FileMode.READ) return;
  2022.  
  2023. UpdateDirty();
  2024.  
  2025. FileSerializer serializer = new FileSerializer();
  2026.  
  2027. if (m_FileHandle != 0)
  2028. {
  2029. CloseFile(m_FileHandle);
  2030. }
  2031.  
  2032. if (!serializer.Open(m_Path, FileMode.APPEND)) return;
  2033.  
  2034. int oldPosition = m_Position;
  2035. CF_PackedByte oldCurrent = m_Current;
  2036.  
  2037. m_Position = 0;
  2038. m_Current = m_Head;
  2039.  
  2040. int zero = 0;
  2041. while (m_Current)
  2042. {
  2043. if (zero < m_NonZeroCount && m_NonZeroes[zero] == m_Position)
  2044. {
  2045. zero++;
  2046.  
  2047. serializer.Close();
  2048. m_FileHandle = OpenFile(m_Path, FileMode.APPEND);
  2049.  
  2050. FPrint(m_FileHandle, Next_AsInt().AsciiToString());
  2051.  
  2052. CloseFile(m_FileHandle);
  2053. serializer.Open(m_Path, FileMode.APPEND);
  2054.  
  2055. continue;
  2056. }
  2057.  
  2058. m_Current = m_Current.SerializerWrite(serializer, m_Size, m_Position);
  2059. }
  2060.  
  2061. serializer.Close();
  2062. m_FileHandle = OpenFile(m_Path, FileMode.APPEND);
  2063.  
  2064. m_Position = oldPosition;
  2065. m_Current = oldCurrent;
  2066. }
  2067.  
  2068. override void Close()
  2069. {
  2070. super.Close();
  2071.  
  2072. if (!IsValid())
  2073. return;
  2074.  
  2075. CloseFile(m_FileHandle);
  2076. }
  2077.  
  2078. protected int Next_AsInt()
  2079. {
  2080. int value;
  2081. if (m_Current)
  2082. {
  2083. value = m_Current.m_Value;
  2084. m_Current = m_Current.m_Next;
  2085. m_Position++;
  2086. }
  2087.  
  2088. return value;
  2089. }
  2090.  
  2091. protected void UpdateDirty()
  2092. {
  2093. if (!m_Dirty) return;
  2094.  
  2095. int oldPosition = m_Position;
  2096. CF_PackedByte oldCurrent = m_Current;
  2097.  
  2098. m_Position = 0;
  2099. m_Current = m_Head;
  2100.  
  2101. int needed = m_Size % 4;
  2102. int lastZero = 0;
  2103.  
  2104. m_NonZeroCount = 0;
  2105.  
  2106. for (int index = 0; index < m_Size; index++)
  2107. {
  2108. if (m_NonZeroCount >= needed) break;
  2109.  
  2110. if (Next() == 0) continue;
  2111.  
  2112. // The value is at the start of a block of 4 bytes
  2113. if (((index - lastZero) % 4) == 0)
  2114. {
  2115. m_NonZeroes[m_NonZeroCount] = index;
  2116. m_NonZeroCount++;
  2117.  
  2118. lastZero = index + 1;
  2119. }
  2120. }
  2121.  
  2122. m_Position = oldPosition;
  2123. m_Current = oldCurrent;
  2124.  
  2125. m_Dirty = false;
  2126. }
  2127. };
  2128. class CF_IO : Managed
  2129. {
  2130. ref CF_Stream m_Stream;
  2131.  
  2132. void CF_IO(CF_Stream stream = null)
  2133. {
  2134. m_Stream = stream;
  2135. }
  2136.  
  2137. void SetStream(CF_Stream stream)
  2138. {
  2139. m_Stream = stream;
  2140. }
  2141.  
  2142. bool IsValid()
  2143. {
  2144. if (!m_Stream) return false;
  2145.  
  2146. return m_Stream.IsValid();
  2147. }
  2148.  
  2149. bool IsRead()
  2150. {
  2151. return false;
  2152. }
  2153.  
  2154. bool IsWrite()
  2155. {
  2156. return false;
  2157. }
  2158.  
  2159. /**
  2160. * Write a byte
  2161. */
  2162. void WriteByte(CF_Byte value)
  2163. {
  2164. CF_Log.Error("Not implemented.");
  2165. }
  2166.  
  2167. /**
  2168. * Write an array of bytes
  2169. */
  2170. void WriteBytes(array<CF_Byte> bytes)
  2171. {
  2172. CF_Log.Error("Not implemented.");
  2173. }
  2174.  
  2175. /**
  2176. * Write an ascii character
  2177. */
  2178. void WriteChar(string value)
  2179. {
  2180. CF_Log.Error("Not implemented.");
  2181. }
  2182.  
  2183. /**
  2184. * Write a bool
  2185. */
  2186. void WriteBool(bool value)
  2187. {
  2188. CF_Log.Error("Not implemented.");
  2189. }
  2190.  
  2191. /**
  2192. * Write a short int
  2193. */
  2194. void WriteShort(int value)
  2195. {
  2196. CF_Log.Error("Not implemented.");
  2197. }
  2198.  
  2199. /**
  2200. * Write an int
  2201. */
  2202. void WriteInt(int value)
  2203. {
  2204. CF_Log.Error("Not implemented.");
  2205. }
  2206.  
  2207. /**
  2208. * Write a float
  2209. */
  2210. void WriteFloat(float value)
  2211. {
  2212. CF_Log.Error("Not implemented.");
  2213. }
  2214.  
  2215. /**
  2216. * Write a vector
  2217. */
  2218. void WriteVector(vector value)
  2219. {
  2220. CF_Log.Error("Not implemented.");
  2221. }
  2222.  
  2223. /**
  2224. * Write a string
  2225. */
  2226. void WriteString(string value)
  2227. {
  2228. CF_Log.Error("Not implemented.");
  2229. }
  2230.  
  2231. /**
  2232. * Write a string line
  2233. */
  2234. void WriteLine(string value)
  2235. {
  2236. CF_Log.Error("Not implemented.");
  2237. }
  2238.  
  2239. /**
  2240. * Write a null terminated string
  2241. */
  2242. void WriteCString(string value)
  2243. {
  2244. CF_Log.Error("Not implemented.");
  2245. }
  2246.  
  2247. /**
  2248. * ReadByte a byte
  2249. */
  2250. CF_Byte ReadByte()
  2251. {
  2252. CF_Log.Error("Not implemented.");
  2253. return 0;
  2254. }
  2255.  
  2256. /**
  2257. * ReadByte an array of byte
  2258. */
  2259. array<CF_Byte> ReadBytes(int count)
  2260. {
  2261. CF_Log.Error("Not implemented.");
  2262. return null;
  2263. }
  2264.  
  2265. /**
  2266. * ReadByte an array of byte
  2267. */
  2268. void ReadBytes(int count, inout array<CF_Byte> bytes)
  2269. {
  2270. CF_Log.Error("Not implemented.");
  2271. }
  2272.  
  2273. /**
  2274. * ReadChar an ascii character
  2275. */
  2276. string ReadChar()
  2277. {
  2278. CF_Log.Error("Not implemented.");
  2279. return "";
  2280. }
  2281.  
  2282. /**
  2283. * ReadBool a bool
  2284. */
  2285. bool ReadBool()
  2286. {
  2287. CF_Log.Error("Not implemented.");
  2288. return false;
  2289. }
  2290.  
  2291. /**
  2292. * Read a short int
  2293. */
  2294. int ReadShort()
  2295. {
  2296. CF_Log.Error("Not implemented.");
  2297. return 0;
  2298. }
  2299.  
  2300. /**
  2301. * ReadInt a int
  2302. */
  2303. int ReadInt()
  2304. {
  2305. CF_Log.Error("Not implemented.");
  2306. return 0;
  2307. }
  2308.  
  2309. /**
  2310. * ReadFloat a float
  2311. */
  2312. float ReadFloat()
  2313. {
  2314. CF_Log.Error("Not implemented.");
  2315. return 0;
  2316. }
  2317.  
  2318. /**
  2319. * ReadVector a vector
  2320. */
  2321. vector ReadVector()
  2322. {
  2323. CF_Log.Error("Not implemented.");
  2324. return "0 0 0";
  2325. }
  2326.  
  2327. /**
  2328. * ReadString a string
  2329. */
  2330. string ReadString()
  2331. {
  2332. CF_Log.Error("Not implemented.");
  2333. return "";
  2334. }
  2335.  
  2336. /**
  2337. * ReadLine a line ended with '\n'
  2338. */
  2339. string ReadLine()
  2340. {
  2341. CF_Log.Error("Not implemented.");
  2342. return "";
  2343. }
  2344.  
  2345. /**
  2346. * ReadByte a null terminated string
  2347. */
  2348. string ReadCString()
  2349. {
  2350. CF_Log.Error("Not implemented.");
  2351. return "";
  2352. }
  2353.  
  2354. bool EOF()
  2355. {
  2356. if (!m_Stream) return true;
  2357.  
  2358. return m_Stream.m_Position >= m_Stream.m_Size;
  2359. }
  2360.  
  2361. int Position()
  2362. {
  2363. if (!m_Stream) return 0;
  2364.  
  2365. return m_Stream.m_Position;
  2366. }
  2367.  
  2368. int Length()
  2369. {
  2370. if (!m_Stream) return 0;
  2371.  
  2372. return m_Stream.m_Size;
  2373. }
  2374.  
  2375. void Seek(int num, CF_SeekOrigin origin = CF_SeekOrigin.CURRENT)
  2376. {
  2377. if (!m_Stream) return;
  2378.  
  2379. m_Stream.Seek(num, origin);
  2380. }
  2381.  
  2382. void Close()
  2383. {
  2384. m_Stream.Close();
  2385. m_Stream = null;
  2386. }
  2387.  
  2388. override string GetDebugName()
  2389. {
  2390. string str = "[" + ClassName() + "] ";
  2391.  
  2392. if (m_Stream) str += m_Stream.GetDebugName();
  2393. else str += "NULL";
  2394.  
  2395. return str;
  2396. }
  2397. };
  2398. class CF_SerializerStream : CF_Stream
  2399. {
  2400. Serializer m_Serializer;
  2401.  
  2402. void CF_SerializerStream(Serializer serializer)
  2403. {
  2404. m_Serializer = serializer;
  2405. }
  2406.  
  2407. override bool IsValid()
  2408. {
  2409. return m_Serializer != null;
  2410. }
  2411. };
  2412.  
  2413. class CF_SerializerReadStream : CF_SerializerStream
  2414. {
  2415. void CF_SerializerReadStream(Serializer serializer)
  2416. {
  2417. m_Serializer.Read(m_Size);
  2418.  
  2419. if (m_Size > 0)
  2420. {
  2421. m_Head = new CF_PackedByte();
  2422. m_Tail = m_Head;
  2423.  
  2424. m_Position = 0;
  2425. m_Current = m_Head;
  2426.  
  2427. while (m_Position < m_Size)
  2428. {
  2429. m_Current = m_Current.SerializerRead(m_Serializer, m_Size, m_Position);
  2430. }
  2431.  
  2432. m_Tail = m_Current;
  2433. }
  2434.  
  2435. m_Position = 0;
  2436. m_Current = m_Head;
  2437. }
  2438. };
  2439.  
  2440. class CF_SerializerWriteStream : CF_SerializerStream
  2441. {
  2442. bool m_Flushed;
  2443.  
  2444. override void Flush()
  2445. {
  2446. if (m_Flushed) return;
  2447. m_Flushed = true;
  2448.  
  2449. m_Serializer.Write(m_Size);
  2450.  
  2451. int oldPosition = m_Position;
  2452. CF_PackedByte oldCurrent = m_Current;
  2453.  
  2454. m_Position = 0;
  2455. m_Current = m_Head;
  2456.  
  2457. while (m_Position < m_Size)
  2458. {
  2459. m_Current = m_Current.SerializerWrite(m_Serializer, m_Size, m_Position);
  2460. }
  2461.  
  2462. m_Position = oldPosition;
  2463. m_Current = oldCurrent;
  2464. }
  2465. };
  2466. class CF_Stream
  2467. {
  2468. ref CF_PackedByte m_Head;
  2469. CF_PackedByte m_Tail;
  2470.  
  2471. CF_PackedByte m_Current;
  2472.  
  2473. int m_Size;
  2474. int m_Position;
  2475.  
  2476. bool m_IsOpen;
  2477.  
  2478. void ~CF_Stream()
  2479. {
  2480. #ifdef CF_TRACE_ENABLED
  2481. auto trace = CF_Trace_0(this, "~CF_Stream");
  2482. #endif
  2483.  
  2484. Close();
  2485. }
  2486.  
  2487. bool IsValid()
  2488. {
  2489. return m_IsOpen;
  2490. }
  2491.  
  2492. void Append(CF_Byte byte = 0)
  2493. {
  2494. CF_PackedByte pByte = new CF_PackedByte();
  2495. pByte.m_Value = byte;
  2496.  
  2497. if (!m_Tail)
  2498. {
  2499. m_Head = pByte;
  2500. m_Tail = pByte;
  2501. m_Size = 1;
  2502. }
  2503. else
  2504. {
  2505. pByte.m_Prev = m_Tail;
  2506. m_Tail.m_Next = pByte;
  2507. m_Tail = pByte;
  2508. m_Size++;
  2509. }
  2510.  
  2511. m_Position = m_Size - 1;
  2512.  
  2513. m_Current = pByte;
  2514. }
  2515.  
  2516. void AppendCurrent(CF_Byte byte = 0)
  2517. {
  2518. if (!m_Tail || m_Tail == m_Head || (m_Tail && m_Tail == m_Current))
  2519. {
  2520. Append(byte);
  2521. return;
  2522. }
  2523.  
  2524. CF_PackedByte pByte = new CF_PackedByte();
  2525. pByte.m_Value = byte;
  2526.  
  2527. if (m_Current)
  2528. {
  2529. pByte.m_Next = m_Current.m_Next;
  2530. m_Current.m_Next = pByte;
  2531.  
  2532. pByte.m_Prev = m_Current;
  2533.  
  2534. if (pByte.m_Next != null) pByte.m_Next.m_Prev = pByte;
  2535.  
  2536. m_Position++;
  2537. }
  2538. else
  2539. {
  2540. pByte.m_Next = m_Head;
  2541. m_Head.m_Prev = pByte;
  2542. m_Head = pByte;
  2543.  
  2544. m_Position = 0;
  2545. }
  2546.  
  2547. m_Size++;
  2548.  
  2549. m_Current = pByte;
  2550. }
  2551.  
  2552. void Resize(int size)
  2553. {
  2554. if (m_Size == size) return;
  2555.  
  2556. CF_PackedByte byte = m_Head;
  2557. for (int i = 0; i < size; i++)
  2558. {
  2559. byte = byte.m_Next;
  2560. }
  2561.  
  2562. if (m_Size < size)
  2563. {
  2564. for (i = m_Size; i < size; i++)
  2565. {
  2566. Append();
  2567. }
  2568. }
  2569. else
  2570. {
  2571. byte.m_Next = null;
  2572. m_Tail = byte;
  2573.  
  2574. if (m_Position >= size - 1)
  2575. {
  2576. m_Current = m_Tail;
  2577. m_Position = size - 1;
  2578. }
  2579. }
  2580.  
  2581. m_Size = size;
  2582. }
  2583.  
  2584. int Length()
  2585. {
  2586. return m_Size;
  2587. }
  2588.  
  2589. CF_Byte Get(int index, CF_SeekOrigin origin)
  2590. {
  2591. Seek(index, origin);
  2592. if (!m_Current) return 0;
  2593. return m_Current.m_Value;
  2594. }
  2595.  
  2596. CF_Byte Get(int index)
  2597. {
  2598. Seek(index, CF_SeekOrigin.SET);
  2599. if (!m_Current) return 0;
  2600. return m_Current.m_Value;
  2601. }
  2602.  
  2603. void SetOrigin(int index, int value, CF_SeekOrigin origin)
  2604. {
  2605. Seek(index, origin);
  2606.  
  2607. m_Current.m_Value = value;
  2608. }
  2609.  
  2610. void Set(int index, int value)
  2611. {
  2612. Seek(index, CF_SeekOrigin.SET);
  2613.  
  2614. m_Current.m_Value = value;
  2615. }
  2616.  
  2617. CF_Byte Next()
  2618. {
  2619. if (!m_Current)
  2620. {
  2621. m_Position = 0;
  2622. m_Current = m_Head;
  2623.  
  2624. return 0;
  2625. }
  2626.  
  2627. CF_Byte value = m_Current.m_Value;
  2628.  
  2629. m_Current = m_Current.m_Next;
  2630. m_Position++;
  2631.  
  2632. if (!m_Current)
  2633. {
  2634. m_Position = m_Size;
  2635. m_Current = null;
  2636. }
  2637.  
  2638. return value;
  2639. }
  2640.  
  2641. CF_Byte Previous()
  2642. {
  2643. if (!m_Current)
  2644. {
  2645. m_Position = m_Size - 1;
  2646. m_Current = m_Tail;
  2647.  
  2648. return 0;
  2649. }
  2650.  
  2651. CF_Byte value = m_Current.m_Value;
  2652.  
  2653. m_Current = m_Current.m_Prev;
  2654. m_Position--;
  2655.  
  2656. if (!m_Current)
  2657. {
  2658. m_Position = 0;
  2659. m_Current = m_Head;
  2660. }
  2661.  
  2662. return value;
  2663. }
  2664.  
  2665. void Next(CF_Byte value)
  2666. {
  2667. AppendCurrent(value);
  2668. }
  2669.  
  2670. Param2<CF_PackedByte, int> GetCurrent()
  2671. {
  2672. return new Param2<CF_PackedByte, int>(m_Current, m_Position);
  2673. }
  2674.  
  2675. void GetCurrent(inout Param2<CF_PackedByte, int> tuple)
  2676. {
  2677. tuple = new Param2<CF_PackedByte, int>(m_Current, m_Position);
  2678. }
  2679.  
  2680. void SetCurrent(Param2<CF_PackedByte, int> tuple)
  2681. {
  2682. m_Current = tuple.param1;
  2683. m_Position = tuple.param2;
  2684. }
  2685.  
  2686. void SetPositionAtStart()
  2687. {
  2688. m_Current = null;
  2689. m_Position = -1;
  2690. }
  2691.  
  2692. void SetPositionAtEnd()
  2693. {
  2694. m_Current = m_Tail;
  2695. m_Position = m_Size - 1;
  2696. }
  2697.  
  2698. void Seek(int num, CF_SeekOrigin origin = CF_SeekOrigin.CURRENT)
  2699. {
  2700. int newPosition;
  2701.  
  2702. switch (origin)
  2703. {
  2704. case CF_SeekOrigin.SET:
  2705. newPosition = num;
  2706.  
  2707. m_Position = 0;
  2708. m_Current = m_Head;
  2709. break;
  2710. case CF_SeekOrigin.CURRENT:
  2711. newPosition = m_Position + num;
  2712. break;
  2713. case CF_SeekOrigin.END:
  2714. newPosition = m_Size - num;
  2715.  
  2716. m_Position = m_Size - 1;
  2717. m_Current = m_Tail;
  2718. break;
  2719. }
  2720.  
  2721. if (newPosition < 0)
  2722. {
  2723. m_Position = -1;
  2724. m_Current = null;
  2725. return;
  2726. }
  2727. else if (newPosition >= m_Size)
  2728. {
  2729. m_Position = m_Size - 1;
  2730. m_Current = m_Tail;
  2731. return;
  2732. }
  2733.  
  2734. int i;
  2735. if (newPosition > m_Position)
  2736. {
  2737. i = m_Position;
  2738. while (i < newPosition)
  2739. {
  2740. m_Current = m_Current.m_Next;
  2741. i++;
  2742. }
  2743. }
  2744. else if (newPosition < m_Position)
  2745. {
  2746. i = m_Position;
  2747. while (i > newPosition)
  2748. {
  2749. m_Current = m_Current.m_Prev;
  2750. i--;
  2751. }
  2752. }
  2753.  
  2754. m_Position = newPosition;
  2755. }
  2756.  
  2757. void CopyTo(CF_Stream dest)
  2758. {
  2759. CF_PackedByte byte = m_Head;
  2760. while (byte)
  2761. {
  2762. dest.Append(byte.m_Value);
  2763. byte = byte.m_Next;
  2764. }
  2765. }
  2766.  
  2767. void CopyTo(CF_Stream dest, int size)
  2768. {
  2769. CF_PackedByte byte = m_Head;
  2770.  
  2771. int index = 0;
  2772. while (byte && index < size)
  2773. {
  2774. dest.Append(byte.m_Value);
  2775. byte = byte.m_Next;
  2776. index++;
  2777. }
  2778. }
  2779.  
  2780. void CopyCurrentTo(CF_Stream dest)
  2781. {
  2782. CF_PackedByte byte = m_Current;
  2783.  
  2784. while (byte)
  2785. {
  2786. dest.Append(byte.m_Value);
  2787. byte = byte.m_Next;
  2788. }
  2789. }
  2790.  
  2791. void CopyCurrentTo(CF_Stream dest, int size)
  2792. {
  2793. CF_PackedByte byte = m_Current;
  2794.  
  2795. int index = 0;
  2796. while (byte && index < size)
  2797. {
  2798. dest.Append(byte.m_Value);
  2799. byte = byte.m_Next;
  2800. index++;
  2801. }
  2802. }
  2803.  
  2804. void Flush()
  2805. {
  2806.  
  2807. }
  2808.  
  2809. void Close()
  2810. {
  2811. if (!m_IsOpen)
  2812. return;
  2813.  
  2814. Flush();
  2815.  
  2816. m_IsOpen = true;
  2817. }
  2818.  
  2819. override string GetDebugName()
  2820. {
  2821. string str = "[" + m_Size + "] 0x";
  2822.  
  2823. int oldPosition = m_Position;
  2824. CF_PackedByte oldCurrent = m_Current;
  2825.  
  2826. m_Position = 0;
  2827. m_Current = m_Head;
  2828.  
  2829. while (m_Current)
  2830. {
  2831. str += m_Current.m_Value.ToHex();
  2832.  
  2833. m_Current = m_Current.m_Next;
  2834. }
  2835.  
  2836. m_Position = oldPosition;
  2837. m_Current = oldCurrent;
  2838.  
  2839. return str;
  2840. }
  2841. };
  2842. class CF_StringStream : CF_Stream
  2843. {
  2844. protected string m_String;
  2845.  
  2846. protected bool m_Dirty;
  2847.  
  2848. void CF_StringStream(string str = "")
  2849. {
  2850. m_String = str;
  2851. for (int i = 0; i < str.Length(); i++)
  2852. {
  2853. Append(str.Get(i).ToAscii());
  2854. }
  2855.  
  2856. Seek(0, CF_SeekOrigin.SET);
  2857. }
  2858.  
  2859. override void Append(CF_Byte byte = 0)
  2860. {
  2861. if (byte == 0)
  2862. {
  2863. CF_Log.Error("Attempted writing null byte in CF_StringStream.");
  2864. return;
  2865. }
  2866.  
  2867. super.Append(byte);
  2868.  
  2869. m_Dirty = true;
  2870. }
  2871.  
  2872. override void AppendCurrent(CF_Byte byte = 0)
  2873. {
  2874. if (byte == 0)
  2875. {
  2876. CF_Log.Error("Attempted writing null byte in CF_StringStream.");
  2877. return;
  2878. }
  2879.  
  2880. super.AppendCurrent(byte);
  2881.  
  2882. m_Dirty = true;
  2883. }
  2884.  
  2885. override void SetOrigin(int index, int value, CF_SeekOrigin origin)
  2886. {
  2887. if (value == 0)
  2888. {
  2889. CF_Log.Error("Attempted writing null byte in CF_StringStream.");
  2890. return;
  2891. }
  2892.  
  2893. super.SetOrigin(index, value, origin);
  2894.  
  2895. m_Dirty = true;
  2896. }
  2897.  
  2898. override void Set(int index, int value)
  2899. {
  2900. if (value == 0)
  2901. {
  2902. CF_Log.Error("Attempted writing null byte in CF_StringStream.");
  2903. return;
  2904. }
  2905.  
  2906. super.Set(index, value);
  2907.  
  2908. m_Dirty = true;
  2909. }
  2910.  
  2911. override void Resize(int size)
  2912. {
  2913. super.Resize(size);
  2914.  
  2915. m_Dirty = true;
  2916. }
  2917.  
  2918. override string GetDebugName()
  2919. {
  2920. UpdateDirty();
  2921.  
  2922. return m_String;
  2923. }
  2924.  
  2925. protected void UpdateDirty()
  2926. {
  2927. if (!m_Dirty) return;
  2928.  
  2929. m_String = "";
  2930.  
  2931. int oldPosition = m_Position;
  2932. CF_PackedByte oldCurrent = m_Current;
  2933.  
  2934. m_Position = 0;
  2935. m_Current = m_Head;
  2936.  
  2937. while (m_Current)
  2938. {
  2939. int byte = m_Current.m_Value;
  2940. m_String += byte.AsciiToString();
  2941.  
  2942. m_Current = m_Current.m_Next;
  2943. }
  2944.  
  2945. m_Position = oldPosition;
  2946. m_Current = oldCurrent;
  2947.  
  2948. m_Dirty = false;
  2949. }
  2950. };
  2951. class CF_TextReader : CF_IO
  2952. {
  2953. override bool IsRead()
  2954. {
  2955. return true;
  2956. }
  2957.  
  2958. override bool IsWrite()
  2959. {
  2960. return false;
  2961. }
  2962.  
  2963. override CF_Byte ReadByte()
  2964. {
  2965. return m_Stream.Next();
  2966. }
  2967.  
  2968. override string ReadChar()
  2969. {
  2970. int byte = m_Stream.Next();
  2971. return byte.AsciiToString();
  2972. }
  2973.  
  2974. override bool ReadBool()
  2975. {
  2976. Param2<CF_PackedByte, int> position;
  2977. m_Stream.GetCurrent(position);
  2978.  
  2979. string str = ReadWord();
  2980. if (str == "true")
  2981. return true;
  2982.  
  2983. if (str == "false")
  2984. return false;
  2985.  
  2986. m_Stream.SetCurrent(position);
  2987. return false;
  2988. }
  2989.  
  2990. override int ReadInt()
  2991. {
  2992. string str;
  2993.  
  2994. int byte = ReadByte();
  2995. while (!CF_Encoding.IsWhitespace(byte) && CF_Encoding.IsNumeric(byte) && !EOF())
  2996. {
  2997. str += byte.AsciiToString();
  2998. byte = ReadByte();
  2999. }
  3000.  
  3001. return str.ToInt();
  3002. }
  3003.  
  3004. override float ReadFloat()
  3005. {
  3006. string str;
  3007.  
  3008. int byte = ReadByte();
  3009. bool decimal = false;
  3010. while (!CF_Encoding.IsWhitespace(byte) && (CF_Encoding.IsNumeric(byte) || (!decimal && byte == 46)) && !EOF())
  3011. {
  3012. str += byte.AsciiToString();
  3013. byte = ReadByte();
  3014. }
  3015.  
  3016. return str.ToFloat();
  3017. }
  3018.  
  3019. override vector ReadVector()
  3020. {
  3021. Param2<CF_PackedByte, int> position;
  3022. m_Stream.GetCurrent(position);
  3023.  
  3024. vector vec;
  3025.  
  3026. vec[0] = ReadFloat();
  3027.  
  3028. if (ReadByte() != 44)
  3029. {
  3030. m_Stream.SetCurrent(position);
  3031. return vector.Zero;
  3032. }
  3033.  
  3034. ReadWhitespace();
  3035. vec[1] = ReadFloat();
  3036.  
  3037. if (ReadByte() != 44)
  3038. {
  3039. m_Stream.SetCurrent(position);
  3040. return vector.Zero;
  3041. }
  3042.  
  3043. ReadWhitespace();
  3044. vec[2] = ReadFloat();
  3045.  
  3046. return vec;
  3047. }
  3048.  
  3049. override string ReadLine()
  3050. {
  3051. string str;
  3052.  
  3053. int byte = ReadByte();
  3054. while (!CF_Encoding.IsLine(byte) && !EOF())
  3055. {
  3056. str += byte.AsciiToString();
  3057. byte = ReadByte();
  3058. }
  3059.  
  3060. return str;
  3061. }
  3062.  
  3063. string ReadWord()
  3064. {
  3065. string str;
  3066.  
  3067. int byte = m_Stream.Next();
  3068. while (!CF_Encoding.IsWhitespace(byte) && CF_Encoding.IsAlphanumeric(byte) && !EOF())
  3069. {
  3070. str += byte.AsciiToString();
  3071. byte = m_Stream.Next();
  3072. }
  3073.  
  3074. m_Stream.Previous();
  3075.  
  3076. return str;
  3077. }
  3078.  
  3079. string ReadWhitespace()
  3080. {
  3081. string str;
  3082.  
  3083. int byte = ReadByte();
  3084. while (CF_Encoding.IsWhitespace(byte) && !EOF())
  3085. {
  3086. str += byte.AsciiToString();
  3087. byte = ReadByte();
  3088. }
  3089.  
  3090. m_Stream.Previous();
  3091.  
  3092. return str;
  3093. }
  3094. };
  3095. class CF_TextWriter : CF_IO
  3096. {
  3097. override bool IsRead()
  3098. {
  3099. return false;
  3100. }
  3101.  
  3102. override bool IsWrite()
  3103. {
  3104. return true;
  3105. }
  3106.  
  3107. override void WriteByte(CF_Byte value)
  3108. {
  3109. m_Stream.AppendCurrent(value);
  3110. }
  3111.  
  3112. override void WriteChar(string value)
  3113. {
  3114. WriteByte(value.ToAscii());
  3115. }
  3116.  
  3117. override void WriteBool(bool value)
  3118. {
  3119. WriteString(value.ToString());
  3120. }
  3121.  
  3122. override void WriteInt(int value)
  3123. {
  3124. WriteString(value.ToString());
  3125. }
  3126.  
  3127. override void WriteFloat(float value)
  3128. {
  3129. WriteString(value.ToString());
  3130. }
  3131.  
  3132. override void WriteVector(vector value)
  3133. {
  3134. WriteString(value.ToString());
  3135. }
  3136.  
  3137. override void WriteLine(string value)
  3138. {
  3139. for (int i = 0; i < value.Length(); i++)
  3140. {
  3141. WriteChar(value[i]);
  3142. }
  3143. WriteChar("\n");
  3144. }
  3145.  
  3146. override void WriteString(string value)
  3147. {
  3148. for (int i = 0; i < value.Length(); i++)
  3149. {
  3150. WriteChar(value[i]);
  3151. }
  3152. }
  3153. };
  3154. class CF_Log
  3155. {
  3156. #ifdef CF_TRACE_ENABLED
  3157. static int Level = CF_LogLevel.TRACE;
  3158. #else
  3159. static int Level = CF_LogLevel.ERROR;
  3160. #endif
  3161.  
  3162. static bool IsLogging(CF_LogLevel level)
  3163. {
  3164. return level >= Level;
  3165. }
  3166.  
  3167. /**
  3168. * @brief Logs that contain the most detailed messages. These messages should never be enabled in a production environment.
  3169. */
  3170. static void Trace(string message, string param1 = "", string param2 = "", string param3 = "", string param4 = "", string param5 = "", string param6 = "", string param7 = "", string param8 = "", string param9 = "")
  3171. {
  3172. if (Level > CF_LogLevel.TRACE) return;
  3173.  
  3174. PrintFormat("[TRACE]\t%1", string.Format(message, param1, param2, param3, param4, param5, param6, param7, param8, param9));
  3175. }
  3176.  
  3177. /**
  3178. * @brief Logs that should primarily contain information useful for debugging.
  3179. */
  3180. static void Debug(string message, string param1 = "", string param2 = "", string param3 = "", string param4 = "", string param5 = "", string param6 = "", string param7 = "", string param8 = "", string param9 = "")
  3181. {
  3182. if (Level > CF_LogLevel.DEBUG) return;
  3183.  
  3184. PrintFormat("[DEBUG]\t%1", string.Format(message, param1, param2, param3, param4, param5, param6, param7, param8, param9));
  3185. }
  3186.  
  3187. /**
  3188. * @brief Logs that output information that may be relevant to the user.
  3189. */
  3190. static void Info(string message, string param1 = "", string param2 = "", string param3 = "", string param4 = "", string param5 = "", string param6 = "", string param7 = "", string param8 = "", string param9 = "")
  3191. {
  3192. if (Level > CF_LogLevel.INFO) return;
  3193.  
  3194. PrintFormat("[INFO]\t%1", string.Format(message, param1, param2, param3, param4, param5, param6, param7, param8, param9));
  3195. }
  3196.  
  3197. /**
  3198. * @brief Logs that highlight an abnormal action, but does not cause the user to notice anything different.
  3199. */
  3200. static void Warn(string message, string param1 = "", string param2 = "", string param3 = "", string param4 = "", string param5 = "", string param6 = "", string param7 = "", string param8 = "", string param9 = "")
  3201. {
  3202. if (Level > CF_LogLevel.WARNING) return;
  3203.  
  3204. PrintFormat("[WARNING]\t%1", string.Format(message, param1, param2, param3, param4, param5, param6, param7, param8, param9));
  3205. }
  3206.  
  3207. /**
  3208. * @brief Logs that highlight when the current flow of execution is stopped due to a failure. This should indicate if the current activity has a failure and will not result in the game shutting down. Produces a stack trace.
  3209. */
  3210. static void Error(string message, string param1 = "", string param2 = "", string param3 = "", string param4 = "", string param5 = "", string param6 = "", string param7 = "", string param8 = "", string param9 = "")
  3211. {
  3212. if (Level > CF_LogLevel.ERROR) return;
  3213.  
  3214. PrintFormat("[ERROR]\t%1", string.Format(message, param1, param2, param3, param4, param5, param6, param7, param8, param9));
  3215.  
  3216. string dump = "";
  3217. DumpStackString(dump);
  3218. array<string> outputs = new array<string>();
  3219. dump.Split("\n", outputs);
  3220.  
  3221. for (int i = 1; i < outputs.Count(); i++)
  3222. {
  3223. Print("\t" + outputs[i]);
  3224. }
  3225. }
  3226.  
  3227. /**
  3228. * @brief Logs that describe an unrecoverable event and will most likely lead to the shutdown of the game. Produces a stack trace.
  3229. */
  3230. static void Critical(string message, string param1 = "", string param2 = "", string param3 = "", string param4 = "", string param5 = "", string param6 = "", string param7 = "", string param8 = "", string param9 = "")
  3231. {
  3232. if (Level > CF_LogLevel.CRITICAL) return;
  3233.  
  3234. PrintFormat("[CRITICAL]\t%1", string.Format(message, param1, param2, param3, param4, param5, param6, param7, param8, param9));
  3235.  
  3236. string dump = "";
  3237. DumpStackString(dump);
  3238. array<string> outputs = new array<string>();
  3239. dump.Split("\n", outputs);
  3240.  
  3241. for (int i = 1; i < outputs.Count(); i++)
  3242. {
  3243. Print("\t" + outputs[i]);
  3244. }
  3245. }
  3246. };
  3247. enum CF_LogLevel
  3248. {
  3249. TRACE = 0,
  3250. DEBUG,
  3251. INFO,
  3252. WARNING,
  3253. ERROR,
  3254. CRITICAL,
  3255. NONE,
  3256. };
  3257. class CF_Trace : Managed
  3258. {
  3259. // Global counter for the trace depth
  3260. static string s_TraceDepth;
  3261.  
  3262. protected string m_InstanceName;
  3263. protected string m_StackName;
  3264.  
  3265. protected int m_Ticks;
  3266.  
  3267. protected int m_Count;
  3268.  
  3269. protected int m_Index;
  3270. protected string m_Strings[10];
  3271. protected bool m_Flushed;
  3272. protected bool m_DoLog;
  3273.  
  3274. static string Depth()
  3275. {
  3276. return s_TraceDepth;
  3277. }
  3278.  
  3279. static string FormatInstance(Class instance)
  3280. {
  3281. if (!instance)
  3282. {
  3283. return "null";
  3284. }
  3285.  
  3286. string instanceName;
  3287. //g_Script.CallFunction(instance, "GetDebugNameNative", instanceName, null);
  3288. //if (instanceName == string.Empty)
  3289. //{
  3290. instanceName = "" + instance;
  3291. //}
  3292.  
  3293. return instanceName;
  3294. }
  3295.  
  3296. static string FormatStack(string instance, string stack)
  3297. {
  3298. string res;
  3299. res = instance;
  3300. if (stack != string.Empty) res = instance + "::" + stack;
  3301. return res;
  3302. }
  3303.  
  3304. void CF_Trace(string instanceName, string stackName, int count, bool doLog)
  3305. {
  3306. m_DoLog = doLog;
  3307.  
  3308. m_InstanceName = instanceName;
  3309.  
  3310. string dump = "";
  3311. DumpStackString(dump);
  3312. array<string> outputs = new array<string>();
  3313. dump.Split("\n", outputs);
  3314. m_StackName = outputs[2];
  3315. m_StackName = m_StackName.Substring(0, m_StackName.IndexOf("("));
  3316.  
  3317. if (stackName != string.Empty)
  3318. {
  3319. m_StackName = m_StackName + "_" + stackName;
  3320. }
  3321.  
  3322. m_Count = count;
  3323.  
  3324. if (m_Count == 0) Output();
  3325. }
  3326.  
  3327. void ~CF_Trace()
  3328. {
  3329. if (!m_DoLog || !m_Flushed) return;
  3330.  
  3331. s_TraceDepth = s_TraceDepth.Substring(0, s_TraceDepth.Length() - 1);
  3332.  
  3333. m_Ticks = TickCount(m_Ticks);
  3334.  
  3335. CF_Log.Trace("%1-%2 Time: %3ms", Depth(), FormatStack(m_InstanceName, m_StackName), (m_Ticks / 10000.0).ToString());
  3336. }
  3337.  
  3338. bool IsLogged()
  3339. {
  3340. return m_DoLog;
  3341. }
  3342.  
  3343. void Output()
  3344. {
  3345. if (!m_DoLog || m_Flushed) return;
  3346. m_Flushed = true;
  3347.  
  3348. string params;
  3349. for (int i = 0; i < m_Count - 1; i++)
  3350. {
  3351. params += m_Strings[i] + ", ";
  3352. }
  3353.  
  3354. if (m_Count > 0) params += m_Strings[m_Count - 1];
  3355.  
  3356. CF_Log.Trace("%1+%2 (%3)", Depth(), FormatStack(m_InstanceName, m_StackName), params);
  3357.  
  3358. s_TraceDepth += " ";
  3359.  
  3360. m_Ticks = TickCount(0);
  3361. }
  3362.  
  3363. CF_Trace Add(bool value)
  3364. {
  3365. m_Strings[m_Index] = value.ToString();
  3366. m_Index++;
  3367.  
  3368. if (m_Index < m_Count || m_Count == -1) return this;
  3369.  
  3370. Output();
  3371.  
  3372. return this;
  3373. }
  3374.  
  3375. CF_Trace Add(int value)
  3376. {
  3377. m_Strings[m_Index] = value.ToString();
  3378. m_Index++;
  3379.  
  3380. if (m_Index < m_Count || m_Count == -1) return this;
  3381.  
  3382. Output();
  3383.  
  3384. return this;
  3385. }
  3386.  
  3387. CF_Trace Add(float value)
  3388. {
  3389. m_Strings[m_Index] = value.ToString();
  3390. m_Index++;
  3391.  
  3392. if (m_Index < m_Count || m_Count == -1) return this;
  3393.  
  3394. Output();
  3395.  
  3396. return this;
  3397. }
  3398.  
  3399. CF_Trace Add(vector value)
  3400. {
  3401. m_Strings[m_Index] = value.ToString();
  3402. m_Index++;
  3403.  
  3404. if (m_Index < m_Count || m_Count == -1) return this;
  3405.  
  3406. Output();
  3407.  
  3408. return this;
  3409. }
  3410.  
  3411. CF_Trace Add(string value)
  3412. {
  3413. m_Strings[m_Index] = "\"" + value + "\"";
  3414. m_Index++;
  3415.  
  3416. if (m_Index < m_Count || m_Count == -1) return this;
  3417.  
  3418. Output();
  3419.  
  3420. return this;
  3421. }
  3422.  
  3423. CF_Trace Add(typename value)
  3424. {
  3425. m_Strings[m_Index] = value.ToString();
  3426. m_Index++;
  3427.  
  3428. if (m_Index < m_Count || m_Count == -1) return this;
  3429.  
  3430. Output();
  3431.  
  3432. return this;
  3433. }
  3434.  
  3435. CF_Trace Add(Class value)
  3436. {
  3437. string val = "" + value;
  3438.  
  3439. if (value) val = "\"" + value.GetDebugName() + "\"";
  3440.  
  3441. m_Strings[m_Index] = val;
  3442. m_Index++;
  3443.  
  3444. if (m_Index < m_Count || m_Count == -1) return this;
  3445.  
  3446. Output();
  3447.  
  3448. return this;
  3449. }
  3450.  
  3451. CF_Trace Add(int value, typename type)
  3452. {
  3453. return Add(typename.EnumToString(type, value));
  3454. }
  3455.  
  3456. CF_Trace Add(int value, array<string> values)
  3457. {
  3458. string vName = "INVALID";
  3459. if (value >= 0 && value < values.Count())
  3460. {
  3461. vName = values[value];
  3462. }
  3463.  
  3464. return Add(vName);
  3465. }
  3466. };
  3467.  
  3468. static CF_Trace CF_Trace_Instance(Class instance)
  3469. {
  3470. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), string.Empty, 0, true);
  3471. return trace;
  3472. }
  3473.  
  3474. static CF_Trace CF_Trace_0(Class instance, string stackName = string.Empty)
  3475. {
  3476. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 0, true);
  3477. return trace;
  3478. }
  3479.  
  3480. static CF_Trace CF_Trace_1(Class instance, string stackName = string.Empty)
  3481. {
  3482. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 1, true);
  3483. return trace;
  3484. }
  3485.  
  3486. static CF_Trace CF_Trace_2(Class instance, string stackName = string.Empty)
  3487. {
  3488. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 2, true);
  3489. return trace;
  3490. }
  3491.  
  3492. static CF_Trace CF_Trace_3(Class instance, string stackName = string.Empty)
  3493. {
  3494. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 3, true);
  3495. return trace;
  3496. }
  3497.  
  3498. static CF_Trace CF_Trace_4(Class instance, string stackName = string.Empty)
  3499. {
  3500. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 4, true);
  3501. return trace;
  3502. }
  3503.  
  3504. static CF_Trace CF_Trace_5(Class instance, string stackName = string.Empty)
  3505. {
  3506. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 5, true);
  3507. return trace;
  3508. }
  3509.  
  3510. static CF_Trace CF_Trace_6(Class instance, string stackName = string.Empty)
  3511. {
  3512. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 6, true);
  3513. return trace;
  3514. }
  3515.  
  3516. static CF_Trace CF_Trace_7(Class instance, string stackName = string.Empty)
  3517. {
  3518. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 7, true);
  3519. return trace;
  3520. }
  3521.  
  3522. static CF_Trace CF_Trace_8(Class instance, string stackName = string.Empty)
  3523. {
  3524. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 8, true);
  3525. return trace;
  3526. }
  3527.  
  3528. static CF_Trace CF_Trace_9(Class instance, string stackName = string.Empty)
  3529. {
  3530. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 9, true);
  3531. return trace;
  3532. }
  3533.  
  3534. static CF_Trace CF_Trace_0(string instance = string.Empty, string stackName = string.Empty)
  3535. {
  3536. auto trace = new CF_Trace(instance, stackName, 0, true);
  3537. return trace;
  3538. }
  3539.  
  3540. static CF_Trace CF_Trace_1(string instance = string.Empty, string stackName = string.Empty)
  3541. {
  3542. auto trace = new CF_Trace(instance, stackName, 1, true);
  3543. return trace;
  3544. }
  3545.  
  3546. static CF_Trace CF_Trace_2(string instance = string.Empty, string stackName = string.Empty)
  3547. {
  3548. auto trace = new CF_Trace(instance, stackName, 2, true);
  3549. return trace;
  3550. }
  3551.  
  3552. static CF_Trace CF_Trace_3(string instance = string.Empty, string stackName = string.Empty)
  3553. {
  3554. auto trace = new CF_Trace(instance, stackName, 3, true);
  3555. return trace;
  3556. }
  3557.  
  3558. static CF_Trace CF_Trace_4(string instance = string.Empty, string stackName = string.Empty)
  3559. {
  3560. auto trace = new CF_Trace(instance, stackName, 4, true);
  3561. return trace;
  3562. }
  3563.  
  3564. static CF_Trace CF_Trace_5(string instance = string.Empty, string stackName = string.Empty)
  3565. {
  3566. auto trace = new CF_Trace(instance, stackName, 5, true);
  3567. return trace;
  3568. }
  3569.  
  3570. static CF_Trace CF_Trace_6(string instance = string.Empty, string stackName = string.Empty)
  3571. {
  3572. auto trace = new CF_Trace(instance, stackName, 6, true);
  3573. return trace;
  3574. }
  3575.  
  3576. static CF_Trace CF_Trace_7(string instance = string.Empty, string stackName = string.Empty)
  3577. {
  3578. auto trace = new CF_Trace(instance, stackName, 7, true);
  3579. return trace;
  3580. }
  3581.  
  3582. static CF_Trace CF_Trace_8(string instance = string.Empty, string stackName = string.Empty)
  3583. {
  3584. auto trace = new CF_Trace(instance, stackName, 8, true);
  3585. return trace;
  3586. }
  3587.  
  3588. static CF_Trace CF_Trace_9(string instance = string.Empty, string stackName = string.Empty)
  3589. {
  3590. auto trace = new CF_Trace(instance, stackName, 9, true);
  3591. return trace;
  3592. }
  3593.  
  3594. static CF_Trace CF_Trace_Instance(bool doLog, Class instance)
  3595. {
  3596. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), string.Empty, 0, doLog);
  3597. return trace;
  3598. }
  3599.  
  3600. static CF_Trace CF_Trace_0(bool doLog, Class instance, string stackName = string.Empty)
  3601. {
  3602. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 0, doLog);
  3603. return trace;
  3604. }
  3605.  
  3606. static CF_Trace CF_Trace_1(bool doLog, Class instance, string stackName = string.Empty)
  3607. {
  3608. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 1, doLog);
  3609. return trace;
  3610. }
  3611.  
  3612. static CF_Trace CF_Trace_2(bool doLog, Class instance, string stackName = string.Empty)
  3613. {
  3614. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 2, doLog);
  3615. return trace;
  3616. }
  3617.  
  3618. static CF_Trace CF_Trace_3(bool doLog, Class instance, string stackName = string.Empty)
  3619. {
  3620. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 3, doLog);
  3621. return trace;
  3622. }
  3623.  
  3624. static CF_Trace CF_Trace_4(bool doLog, Class instance, string stackName = string.Empty)
  3625. {
  3626. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 4, doLog);
  3627. return trace;
  3628. }
  3629.  
  3630. static CF_Trace CF_Trace_5(bool doLog, Class instance, string stackName = string.Empty)
  3631. {
  3632. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 5, doLog);
  3633. return trace;
  3634. }
  3635.  
  3636. static CF_Trace CF_Trace_6(bool doLog, Class instance, string stackName = string.Empty)
  3637. {
  3638. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 6, doLog);
  3639. return trace;
  3640. }
  3641.  
  3642. static CF_Trace CF_Trace_7(bool doLog, Class instance, string stackName = string.Empty)
  3643. {
  3644. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 7, doLog);
  3645. return trace;
  3646. }
  3647.  
  3648. static CF_Trace CF_Trace_8(bool doLog, Class instance, string stackName = string.Empty)
  3649. {
  3650. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 8, doLog);
  3651. return trace;
  3652. }
  3653.  
  3654. static CF_Trace CF_Trace_9(bool doLog, Class instance, string stackName = string.Empty)
  3655. {
  3656. auto trace = new CF_Trace(CF_Trace.FormatInstance(instance), stackName, 9, doLog);
  3657. return trace;
  3658. }
  3659.  
  3660. static CF_Trace CF_Trace_0(bool doLog, string instance = string.Empty, string stackName = string.Empty)
  3661. {
  3662. auto trace = new CF_Trace(instance, stackName, 0, doLog);
  3663. return trace;
  3664. }
  3665.  
  3666. static CF_Trace CF_Trace_1(bool doLog, string instance = string.Empty, string stackName = string.Empty)
  3667. {
  3668. auto trace = new CF_Trace(instance, stackName, 1, doLog);
  3669. return trace;
  3670. }
  3671.  
  3672. static CF_Trace CF_Trace_2(bool doLog, string instance = string.Empty, string stackName = string.Empty)
  3673. {
  3674. auto trace = new CF_Trace(instance, stackName, 2, doLog);
  3675. return trace;
  3676. }
  3677.  
  3678. static CF_Trace CF_Trace_3(bool doLog, string instance = string.Empty, string stackName = string.Empty)
  3679. {
  3680. auto trace = new CF_Trace(instance, stackName, 3, doLog);
  3681. return trace;
  3682. }
  3683.  
  3684. static CF_Trace CF_Trace_4(bool doLog, string instance = string.Empty, string stackName = string.Empty)
  3685. {
  3686. auto trace = new CF_Trace(instance, stackName, 4, doLog);
  3687. return trace;
  3688. }
  3689.  
  3690. static CF_Trace CF_Trace_5(bool doLog, string instance = string.Empty, string stackName = string.Empty)
  3691. {
  3692. auto trace = new CF_Trace(instance, stackName, 5, doLog);
  3693. return trace;
  3694. }
  3695.  
  3696. static CF_Trace CF_Trace_6(bool doLog, string instance = string.Empty, string stackName = string.Empty)
  3697. {
  3698. auto trace = new CF_Trace(instance, stackName, 6, doLog);
  3699. return trace;
  3700. }
  3701.  
  3702. static CF_Trace CF_Trace_7(bool doLog, string instance = string.Empty, string stackName = string.Empty)
  3703. {
  3704. auto trace = new CF_Trace(instance, stackName, 7, doLog);
  3705. return trace;
  3706. }
  3707.  
  3708. static CF_Trace CF_Trace_8(bool doLog, string instance = string.Empty, string stackName = string.Empty)
  3709. {
  3710. auto trace = new CF_Trace(instance, stackName, 8, doLog);
  3711. return trace;
  3712. }
  3713.  
  3714. static CF_Trace CF_Trace_9(bool doLog, string instance = string.Empty, string stackName = string.Empty)
  3715. {
  3716. auto trace = new CF_Trace(instance, stackName, 9, doLog);
  3717. return trace;
  3718. }
  3719. class CF_ModuleCore : Managed
  3720. {
  3721. static bool s_PreventInput = false;
  3722.  
  3723. int m_CF_GameFlag;
  3724.  
  3725. void CF_ModuleCore()
  3726. {
  3727. #ifdef CF_TRACE_ENABLED
  3728. auto trace = CF_Trace_0(this, "CF_ModuleCore");
  3729. #endif
  3730. }
  3731.  
  3732. void ~CF_ModuleCore()
  3733. {
  3734. #ifdef CF_TRACE_ENABLED
  3735. auto trace = CF_Trace_0(this, "~CF_ModuleCore");
  3736. #endif
  3737. }
  3738.  
  3739. bool IsServer()
  3740. {
  3741. return true;
  3742. }
  3743.  
  3744. bool IsClient()
  3745. {
  3746. return true;
  3747. }
  3748.  
  3749. typename GetType()
  3750. {
  3751. return Type();
  3752. }
  3753.  
  3754. // Permanent Event
  3755.  
  3756. void Init()
  3757. {
  3758. OnInit();
  3759. }
  3760.  
  3761. void OnInit()
  3762. {
  3763. }
  3764.  
  3765. // Event Registration
  3766.  
  3767. void EnableUpdate()
  3768. {
  3769. CF_ModuleCoreManager.s_Update.Add(this);
  3770. }
  3771.  
  3772. void EnableMissionStart()
  3773. {
  3774. CF_ModuleCoreManager.s_MissionStart.Add(this);
  3775. }
  3776.  
  3777. void EnableMissionFinish()
  3778. {
  3779. CF_ModuleCoreManager.s_MissionFinish.Add(this);
  3780. }
  3781.  
  3782. void EnableMissionLoaded()
  3783. {
  3784. CF_ModuleCoreManager.s_MissionLoaded.Add(this);
  3785. }
  3786.  
  3787. void EnableSettingsChanged()
  3788. {
  3789. CF_ModuleCoreManager.s_SettingsChanged.Add(this);
  3790. }
  3791.  
  3792. void EnablePermissionsChanged()
  3793. {
  3794. CF_ModuleCoreManager.s_PermissionsChanged.Add(this);
  3795. }
  3796.  
  3797. void EnableWorldCleanup()
  3798. {
  3799. CF_ModuleCoreManager.s_WorldCleanup.Add(this);
  3800. }
  3801.  
  3802. void EnableMPSessionStart()
  3803. {
  3804. CF_ModuleCoreManager.s_MPSessionStart.Add(this);
  3805. }
  3806.  
  3807. void EnableMPSessionPlayerReady()
  3808. {
  3809. CF_ModuleCoreManager.s_MPSessionPlayerReady.Add(this);
  3810. }
  3811.  
  3812. void EnableMPSessionFail()
  3813. {
  3814. CF_ModuleCoreManager.s_MPSessionFail.Add(this);
  3815. }
  3816.  
  3817. void EnableMPSessionEnd()
  3818. {
  3819. CF_ModuleCoreManager.s_MPSessionEnd.Add(this);
  3820. }
  3821.  
  3822. void EnableMPConnectAbort()
  3823. {
  3824. CF_ModuleCoreManager.s_MPConnectAbort.Add(this);
  3825. }
  3826.  
  3827. void EnableMPConnectionLost()
  3828. {
  3829. CF_ModuleCoreManager.s_MPConnectionLost.Add(this);
  3830. }
  3831.  
  3832. void EnableRespawn()
  3833. {
  3834. CF_ModuleCoreManager.s_Respawn.Add(this);
  3835. }
  3836.  
  3837. void EnableLoginTime()
  3838. {
  3839. CF_ModuleCoreManager.s_LoginTime.Add(this);
  3840. }
  3841.  
  3842. void EnableLoginStatus()
  3843. {
  3844. CF_ModuleCoreManager.s_LoginStatus.Add(this);
  3845. }
  3846.  
  3847. void EnableLogout()
  3848. {
  3849. CF_ModuleCoreManager.s_Logout.Add(this);
  3850. }
  3851.  
  3852. void EnableChat()
  3853. {
  3854. CF_ModuleCoreManager.s_Chat.Add(this);
  3855. }
  3856.  
  3857. // Events
  3858.  
  3859. void OnMissionStart(Class sender, CF_EventArgs args);
  3860.  
  3861. void OnMissionFinish(Class sender, CF_EventArgs args);
  3862.  
  3863. void OnMissionLoaded(Class sender, CF_EventArgs args);
  3864.  
  3865. void OnUpdate(Class sender, CF_EventArgs args);
  3866.  
  3867. void OnSettingsChanged(Class sender, CF_EventArgs args);
  3868.  
  3869. void OnPermissionsChanged(Class sender, CF_EventArgs args);
  3870.  
  3871. /**
  3872. * @brief See: WorldCleaupEventTypeID
  3873. */
  3874. void OnWorldCleanup(Class sender, CF_EventArgs args);
  3875.  
  3876. /**
  3877. * @brief See: MPSessionStartEventTypeID
  3878. */
  3879. void OnMPSessionStart(Class sender, CF_EventArgs args);
  3880.  
  3881. /**
  3882. * @brief See: MPSessionPlayerReadyEventTypeID
  3883. */
  3884. void OnMPSessionPlayerReady(Class sender, CF_EventArgs args);
  3885.  
  3886. /**
  3887. * @brief See: MPSessionFailEventTypeID
  3888. */
  3889. void OnMPSessionFail(Class sender, CF_EventArgs args);
  3890.  
  3891. /**
  3892. * @brief See: MPSessionEndEventTypeID
  3893. */
  3894. void OnMPSessionEnd(Class sender, CF_EventArgs args);
  3895.  
  3896. /**
  3897. * @brief See: ConnectingAbortEventTypeID
  3898. */
  3899. void OnMPConnectAbort(Class sender, CF_EventArgs args);
  3900.  
  3901. /**
  3902. * @brief See: MPConnectionLostEventTypeID
  3903. */
  3904. void OnMPConnectionLost(Class sender, CF_EventArgs args);
  3905.  
  3906. /**
  3907. * @brief See: RespawnEventTypeID
  3908. */
  3909. void OnRespawn(Class sender, CF_EventArgs args);
  3910.  
  3911. /**
  3912. * @brief See: LoginTimeEventTypeID
  3913. */
  3914. void OnLoginTime(Class sender, CF_EventArgs args);
  3915.  
  3916. /**
  3917. * @brief See: LoginStatusEventTypeID
  3918. */
  3919. void OnLoginStatus(Class sender, CF_EventArgs args);
  3920.  
  3921. /**
  3922. * @brief See: LogoutEventTypeID
  3923. */
  3924. void OnLogout(Class sender, CF_EventArgs args);
  3925.  
  3926. /**
  3927. * @brief See: ChatMessageEventTypeID
  3928. */
  3929. void OnChat(Class sender, CF_EventArgs args);
  3930.  
  3931. // FALLBACKS
  3932.  
  3933. void Error_Deprecated(string oldFunc, string newFunc)
  3934. {
  3935. CF_Log.Info(ClassName() + "::" + oldFunc + " is deprecated. Use " + ClassName() + "::" + newFunc + " instead.");
  3936. }
  3937.  
  3938. void Error_Removed(string oldFunc)
  3939. {
  3940. CF_Log.Info(ClassName() + "::" + oldFunc + " is deprecated and has no replacement.");
  3941. }
  3942. };
  3943. class CF_ModuleCoreEvent
  3944. {
  3945. ref CF_ModuleCore m_Value;
  3946.  
  3947. ref CF_ModuleCoreEvent m_Next;
  3948.  
  3949. void CF_ModuleCoreEvent(CF_ModuleCore module = null)
  3950. {
  3951. m_Value = module;
  3952. }
  3953.  
  3954. void Add(CF_ModuleCore module)
  3955. {
  3956. CF_ModuleCoreEvent newEvent = new CF_ModuleCoreEvent(module);
  3957.  
  3958. CF_ModuleCoreEvent current = this;
  3959. CF_ModuleCoreEvent next = m_Next;
  3960. while (current && next)
  3961. {
  3962. if (current.m_Value == module || next.m_Value == module)
  3963. {
  3964. return;
  3965. }
  3966.  
  3967. current = next;
  3968. next = next.m_Next;
  3969. }
  3970.  
  3971. current.m_Next = newEvent;
  3972. }
  3973.  
  3974. void OnMissionStart(Class sender, CF_EventArgs args)
  3975. {
  3976. CF_ModuleCoreEvent evt = this.m_Next;
  3977. while (evt)
  3978. {
  3979. CF_ModuleCore module = evt.m_Value;
  3980.  
  3981. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  3982. {
  3983. module.OnMissionStart(sender, args);
  3984. }
  3985.  
  3986. evt = evt.m_Next;
  3987. }
  3988. }
  3989.  
  3990. void OnMissionFinish(Class sender, CF_EventArgs args)
  3991. {
  3992. CF_ModuleCoreEvent evt = this.m_Next;
  3993. while (evt)
  3994. {
  3995. CF_ModuleCore module = evt.m_Value;
  3996.  
  3997. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  3998. {
  3999. module.OnMissionFinish(sender, args);
  4000. }
  4001.  
  4002. evt = evt.m_Next;
  4003. }
  4004. }
  4005.  
  4006. void OnMissionLoaded(Class sender, CF_EventArgs args)
  4007. {
  4008. CF_ModuleCoreEvent evt = this.m_Next;
  4009. while (evt)
  4010. {
  4011. CF_ModuleCore module = evt.m_Value;
  4012.  
  4013. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  4014. {
  4015. module.OnMissionLoaded(sender, args);
  4016. }
  4017.  
  4018. evt = evt.m_Next;
  4019. }
  4020. }
  4021.  
  4022. void OnUpdate(Class sender, CF_EventArgs args)
  4023. {
  4024. CF_ModuleCoreEvent evt = this.m_Next;
  4025. while (evt)
  4026. {
  4027. CF_ModuleCore module = evt.m_Value;
  4028.  
  4029. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  4030. {
  4031. module.OnUpdate(sender, args);
  4032. }
  4033.  
  4034. evt = evt.m_Next;
  4035. }
  4036. }
  4037.  
  4038. void OnSettingsChanged(Class sender, CF_EventArgs args)
  4039. {
  4040. CF_ModuleCoreEvent evt = this.m_Next;
  4041. while (evt)
  4042. {
  4043. CF_ModuleCore module = evt.m_Value;
  4044.  
  4045. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  4046. {
  4047. module.OnSettingsChanged(sender, args);
  4048. }
  4049.  
  4050. evt = evt.m_Next;
  4051. }
  4052. }
  4053.  
  4054. void OnPermissionsChanged(Class sender, CF_EventArgs args)
  4055. {
  4056. CF_ModuleCoreEvent evt = this.m_Next;
  4057. while (evt)
  4058. {
  4059. CF_ModuleCore module = evt.m_Value;
  4060.  
  4061. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  4062. {
  4063. module.OnPermissionsChanged(sender, args);
  4064. }
  4065.  
  4066. evt = evt.m_Next;
  4067. }
  4068. }
  4069.  
  4070. void OnWorldCleanup(Class sender, CF_EventArgs args)
  4071. {
  4072. CF_ModuleCoreEvent evt = this.m_Next;
  4073. while (evt)
  4074. {
  4075. CF_ModuleCore module = evt.m_Value;
  4076.  
  4077. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  4078. {
  4079. module.OnWorldCleanup(sender, args);
  4080. }
  4081.  
  4082. evt = evt.m_Next;
  4083. }
  4084. }
  4085.  
  4086. void OnMPSessionStart(Class sender, CF_EventArgs args)
  4087. {
  4088. CF_ModuleCoreEvent evt = this.m_Next;
  4089. while (evt)
  4090. {
  4091. CF_ModuleCore module = evt.m_Value;
  4092.  
  4093. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  4094. {
  4095. module.OnMPSessionStart(sender, args);
  4096. }
  4097.  
  4098. evt = evt.m_Next;
  4099. }
  4100. }
  4101.  
  4102. void OnMPSessionPlayerReady(Class sender, CF_EventArgs args)
  4103. {
  4104. CF_ModuleCoreEvent evt = this.m_Next;
  4105. while (evt)
  4106. {
  4107. CF_ModuleCore module = evt.m_Value;
  4108.  
  4109. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  4110. {
  4111. module.OnMPSessionPlayerReady(sender, args);
  4112. }
  4113.  
  4114. evt = evt.m_Next;
  4115. }
  4116. }
  4117.  
  4118. void OnMPSessionFail(Class sender, CF_EventArgs args)
  4119. {
  4120. CF_ModuleCoreEvent evt = this.m_Next;
  4121. while (evt)
  4122. {
  4123. CF_ModuleCore module = evt.m_Value;
  4124.  
  4125. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  4126. {
  4127. module.OnMPSessionFail(sender, args);
  4128. }
  4129.  
  4130. evt = evt.m_Next;
  4131. }
  4132. }
  4133.  
  4134. void OnMPSessionEnd(Class sender, CF_EventArgs args)
  4135. {
  4136. CF_ModuleCoreEvent evt = this.m_Next;
  4137. while (evt)
  4138. {
  4139. CF_ModuleCore module = evt.m_Value;
  4140.  
  4141. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  4142. {
  4143. module.OnMPSessionEnd(sender, args);
  4144. }
  4145.  
  4146. evt = evt.m_Next;
  4147. }
  4148. }
  4149.  
  4150. void OnMPConnectAbort(Class sender, CF_EventArgs args)
  4151. {
  4152. CF_ModuleCoreEvent evt = this.m_Next;
  4153. while (evt)
  4154. {
  4155. CF_ModuleCore module = evt.m_Value;
  4156.  
  4157. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  4158. {
  4159. module.OnMPConnectAbort(sender, args);
  4160. }
  4161.  
  4162. evt = evt.m_Next;
  4163. }
  4164. }
  4165.  
  4166. void OnMPConnectionLost(Class sender, CF_EventArgs args)
  4167. {
  4168. CF_ModuleCoreEvent evt = this.m_Next;
  4169. while (evt)
  4170. {
  4171. CF_ModuleCore module = evt.m_Value;
  4172.  
  4173. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  4174. {
  4175. module.OnMPConnectionLost(sender, args);
  4176. }
  4177.  
  4178. evt = evt.m_Next;
  4179. }
  4180. }
  4181.  
  4182. void OnRespawn(Class sender, CF_EventArgs args)
  4183. {
  4184. CF_ModuleCoreEvent evt = this.m_Next;
  4185. while (evt)
  4186. {
  4187. CF_ModuleCore module = evt.m_Value;
  4188.  
  4189. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  4190. {
  4191. module.OnRespawn(sender, args);
  4192. }
  4193.  
  4194. evt = evt.m_Next;
  4195. }
  4196. }
  4197.  
  4198. void OnLoginTime(Class sender, CF_EventArgs args)
  4199. {
  4200. CF_ModuleCoreEvent evt = this.m_Next;
  4201. while (evt)
  4202. {
  4203. CF_ModuleCore module = evt.m_Value;
  4204.  
  4205. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  4206. {
  4207. module.OnLoginTime(sender, args);
  4208. }
  4209.  
  4210. evt = evt.m_Next;
  4211. }
  4212. }
  4213.  
  4214. void OnLoginStatus(Class sender, CF_EventArgs args)
  4215. {
  4216. CF_ModuleCoreEvent evt = this.m_Next;
  4217. while (evt)
  4218. {
  4219. CF_ModuleCore module = evt.m_Value;
  4220.  
  4221. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  4222. {
  4223. module.OnLoginStatus(sender, args);
  4224. }
  4225.  
  4226. evt = evt.m_Next;
  4227. }
  4228. }
  4229.  
  4230. void OnLogout(Class sender, CF_EventArgs args)
  4231. {
  4232. CF_ModuleCoreEvent evt = this.m_Next;
  4233. while (evt)
  4234. {
  4235. CF_ModuleCore module = evt.m_Value;
  4236.  
  4237. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  4238. {
  4239. module.OnLogout(sender, args);
  4240. }
  4241.  
  4242. evt = evt.m_Next;
  4243. }
  4244. }
  4245.  
  4246. void OnChat(Class sender, CF_EventArgs args)
  4247. {
  4248. CF_ModuleCoreEvent evt = this.m_Next;
  4249. while (evt)
  4250. {
  4251. CF_ModuleCore module = evt.m_Value;
  4252.  
  4253. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  4254. {
  4255. module.OnChat(sender, args);
  4256. }
  4257.  
  4258. evt = evt.m_Next;
  4259. }
  4260. }
  4261. };
  4262. static autoptr CF_ModuleCoreManager g_CF_Module_Manager;
  4263.  
  4264. class CF_ModuleCoreManager
  4265. {
  4266. static autoptr array<string> s_ModuleNames = new array<string>();
  4267.  
  4268. static autoptr map<typename, CF_ModuleCore> s_ModulesMap = new map<typename, CF_ModuleCore>();
  4269. static autoptr array<autoptr CF_ModuleCore> s_Modules = new array<autoptr CF_ModuleCore>();
  4270.  
  4271. static bool s_IsCreated;
  4272.  
  4273. static autoptr CF_ModuleCoreEvent s_MissionStart = new CF_ModuleCoreEvent();
  4274. static autoptr CF_ModuleCoreEvent s_MissionFinish = new CF_ModuleCoreEvent();
  4275. static autoptr CF_ModuleCoreEvent s_MissionLoaded = new CF_ModuleCoreEvent();
  4276. static autoptr CF_ModuleCoreEvent s_Update = new CF_ModuleCoreEvent();
  4277. static autoptr CF_ModuleCoreEvent s_SettingsChanged = new CF_ModuleCoreEvent();
  4278. static autoptr CF_ModuleCoreEvent s_PermissionsChanged = new CF_ModuleCoreEvent();
  4279. static autoptr CF_ModuleCoreEvent s_WorldCleanup = new CF_ModuleCoreEvent();
  4280. static autoptr CF_ModuleCoreEvent s_MPSessionStart = new CF_ModuleCoreEvent();
  4281. static autoptr CF_ModuleCoreEvent s_MPSessionPlayerReady = new CF_ModuleCoreEvent();
  4282. static autoptr CF_ModuleCoreEvent s_MPSessionFail = new CF_ModuleCoreEvent();
  4283. static autoptr CF_ModuleCoreEvent s_MPSessionEnd = new CF_ModuleCoreEvent();
  4284. static autoptr CF_ModuleCoreEvent s_MPConnectAbort = new CF_ModuleCoreEvent();
  4285. static autoptr CF_ModuleCoreEvent s_MPConnectionLost = new CF_ModuleCoreEvent();
  4286. static autoptr CF_ModuleCoreEvent s_Respawn = new CF_ModuleCoreEvent();
  4287. static autoptr CF_ModuleCoreEvent s_LoginTime = new CF_ModuleCoreEvent();
  4288. static autoptr CF_ModuleCoreEvent s_LoginStatus = new CF_ModuleCoreEvent();
  4289. static autoptr CF_ModuleCoreEvent s_Logout = new CF_ModuleCoreEvent();
  4290. static autoptr CF_ModuleCoreEvent s_Chat = new CF_ModuleCoreEvent();
  4291.  
  4292. static int s_GameFlag;
  4293.  
  4294. static void _OnCreate()
  4295. {
  4296. #ifdef CF_TRACE_ENABLED
  4297. auto trace = CF_Trace_0("CF_ModuleCoreManager", "_OnCreate");
  4298. #endif
  4299.  
  4300. _OnDestroy();
  4301.  
  4302. g_CF_Module_Manager = new CF_ModuleCoreManager();
  4303.  
  4304. s_IsCreated = true;
  4305.  
  4306. for (int i = 0; i < s_ModuleNames.Count(); i++)
  4307. {
  4308. _Create(s_ModuleNames[i]);
  4309. }
  4310. }
  4311.  
  4312. static void _OnDestroy()
  4313. {
  4314. #ifdef CF_TRACE_ENABLED
  4315. auto trace = CF_Trace_0("CF_ModuleCoreManager", "_OnDestroy");
  4316. #endif
  4317.  
  4318. for (int i = s_Modules.Count() - 1; i >= 0; i--)
  4319. {
  4320. delete s_Modules[i];
  4321. }
  4322.  
  4323. s_ModulesMap.Clear();
  4324. s_Modules.Clear();
  4325.  
  4326. s_IsCreated = false;
  4327. }
  4328.  
  4329. /**
  4330. * @brief Inserts the module typename into the list of modules to create, creates if already instantiated
  4331. */
  4332. static void _Insert(typename type)
  4333. {
  4334. #ifdef CF_TRACE_ENABLED
  4335. auto trace = CF_Trace_1("CF_ModuleCoreManager", "_Insert").Add(type);
  4336. #endif
  4337.  
  4338. string className = type.ToString();
  4339. s_ModuleNames.Insert(className);
  4340.  
  4341. if (s_IsCreated)
  4342. {
  4343. _Create(className);
  4344. }
  4345. }
  4346.  
  4347. /**
  4348. * @brief Creates the module from the name of the class
  4349. */
  4350. static void _Create(string className)
  4351. {
  4352. #ifdef CF_TRACE_ENABLED
  4353. auto trace = CF_Trace_1("CF_ModuleCoreManager", "_Create").Add(className);
  4354. #endif
  4355.  
  4356. typename type = className.ToType();
  4357.  
  4358. if (s_ModulesMap.Contains(type))
  4359. {
  4360. return;
  4361. }
  4362.  
  4363. CF_ModuleCore module;
  4364. if (!Class.CastTo(module, type.Spawn()))
  4365. {
  4366. return;
  4367. }
  4368.  
  4369. s_ModulesMap.Insert(type, module);
  4370. s_Modules.Insert(module);
  4371.  
  4372. module.m_CF_GameFlag = 0;
  4373. if (module.IsClient())
  4374. {
  4375. module.m_CF_GameFlag |= 0x0F;
  4376. }
  4377.  
  4378. if (module.IsServer())
  4379. {
  4380. module.m_CF_GameFlag |= 0xF0;
  4381. }
  4382.  
  4383. module.Init();
  4384. }
  4385.  
  4386. static CF_ModuleCore Get(typename type)
  4387. {
  4388. return s_ModulesMap[type];
  4389. }
  4390.  
  4391. /**
  4392. * @brief Deprecated
  4393. */
  4394. static CF_ModuleCore GetModule(typename type)
  4395. {
  4396. return s_ModulesMap[type];
  4397. }
  4398.  
  4399. static CF_ModuleCore Get(string type)
  4400. {
  4401. return s_ModulesMap[type.ToType()];
  4402. }
  4403.  
  4404. static CF_ModuleCore Get(int index)
  4405. {
  4406. return s_Modules[index];
  4407. }
  4408.  
  4409. static int Count()
  4410. {
  4411. return s_Modules.Count();
  4412. }
  4413.  
  4414. // EVENTS
  4415.  
  4416. static void OnMissionStart(Class sender, CF_EventArgs args)
  4417. {
  4418. s_MissionStart.OnMissionStart(sender, args);
  4419.  
  4420. delete args;
  4421. }
  4422.  
  4423. static void OnMissionFinish(Class sender, CF_EventArgs args)
  4424. {
  4425. s_MissionFinish.OnMissionFinish(sender, args);
  4426.  
  4427. delete args;
  4428. }
  4429.  
  4430. static void OnMissionLoaded(Class sender, CF_EventArgs args)
  4431. {
  4432. s_MissionLoaded.OnMissionLoaded(sender, args);
  4433.  
  4434. delete args;
  4435. }
  4436.  
  4437. static void OnSettingsChanged(Class sender, CF_EventArgs args)
  4438. {
  4439. s_SettingsChanged.OnSettingsChanged(sender, args);
  4440.  
  4441. delete args;
  4442. }
  4443.  
  4444. static void OnPermissionsChanged(Class sender, CF_EventArgs args)
  4445. {
  4446. s_PermissionsChanged.OnPermissionsChanged(sender, args);
  4447.  
  4448. delete args;
  4449. }
  4450.  
  4451. static void OnWorldCleanup(Class sender, CF_EventArgs args)
  4452. {
  4453. s_WorldCleanup.OnWorldCleanup(sender, args);
  4454.  
  4455. delete args;
  4456. }
  4457.  
  4458. static void OnMPSessionStart(Class sender, CF_EventArgs args)
  4459. {
  4460. s_MPSessionStart.OnMPSessionStart(sender, args);
  4461.  
  4462. delete args;
  4463. }
  4464.  
  4465. static void OnMPSessionPlayerReady(Class sender, CF_EventArgs args)
  4466. {
  4467. s_MPSessionPlayerReady.OnMPSessionPlayerReady(sender, args);
  4468.  
  4469. delete args;
  4470. }
  4471.  
  4472. static void OnMPSessionFail(Class sender, CF_EventArgs args)
  4473. {
  4474. s_MPSessionFail.OnMPSessionFail(sender, args);
  4475.  
  4476. delete args;
  4477. }
  4478.  
  4479. static void OnMPSessionEnd(Class sender, CF_EventArgs args)
  4480. {
  4481. s_MPSessionEnd.OnMPSessionEnd(sender, args);
  4482.  
  4483. delete args;
  4484. }
  4485.  
  4486. static void OnMPConnectAbort(Class sender, CF_EventArgs args)
  4487. {
  4488. s_MPConnectAbort.OnMPConnectAbort(sender, args);
  4489.  
  4490. delete args;
  4491. }
  4492.  
  4493. static void OnMPConnectionLost(Class sender, CF_EventArgs args)
  4494. {
  4495. s_MPConnectionLost.OnMPConnectionLost(sender, args);
  4496.  
  4497. delete args;
  4498. }
  4499.  
  4500. static void OnRespawn(Class sender, CF_EventArgs args)
  4501. {
  4502. s_Respawn.OnRespawn(sender, args);
  4503.  
  4504. delete args;
  4505. }
  4506.  
  4507. static void OnLoginTime(Class sender, CF_EventArgs args)
  4508. {
  4509. s_LoginTime.OnLoginTime(sender, args);
  4510.  
  4511. delete args;
  4512. }
  4513.  
  4514. static void OnLoginStatus(Class sender, CF_EventArgs args)
  4515. {
  4516. s_LoginStatus.OnLoginStatus(sender, args);
  4517.  
  4518. delete args;
  4519. }
  4520.  
  4521. static void OnLogout(Class sender, CF_EventArgs args)
  4522. {
  4523. s_Logout.OnLogout(sender, args);
  4524.  
  4525. delete args;
  4526. }
  4527.  
  4528. static void OnChat(Class sender, CF_EventArgs args)
  4529. {
  4530. s_Chat.OnChat(sender, args);
  4531.  
  4532. delete args;
  4533. }
  4534. };
  4535. class CF_Modules<Class T>
  4536. {
  4537. static T Get()
  4538. {
  4539. typename type = T;
  4540. T module;
  4541. Class.CastTo(module, CF_ModuleCoreManager.s_ModulesMap[type]);
  4542. return module;
  4543. }
  4544.  
  4545. static bool Get(inout T module)
  4546. {
  4547. typename type = T;
  4548. return Class.CastTo(module, CF_ModuleCoreManager.s_ModulesMap[type]);
  4549. }
  4550. };
  4551. class CF_RegisterModule
  4552. {
  4553. void CF_RegisterModule(typename type)
  4554. {
  4555. CF_ModuleCoreManager._Insert(type);
  4556. }
  4557. };
  4558. /**
  4559. * EnMath.c
  4560. *
  4561. * DayZ Expansion Mod
  4562. * www.dayzexpansion.com
  4563. * © 2020 DayZ Expansion Mod Team
  4564. *
  4565. * This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.
  4566. * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/.
  4567. *
  4568. */
  4569.  
  4570. modded class Math
  4571. {
  4572. /**
  4573. * @brief Returns the direction the number is facing, 0 if zero
  4574. *
  4575. * @return float
  4576. */
  4577. static float Sign( float number )
  4578. {
  4579. if ( number > 0 )
  4580. return 1;
  4581. if ( number < 0 )
  4582. return -1;
  4583. return 1;
  4584. }
  4585.  
  4586. /**
  4587. * @brief Returns the direction the number is facing
  4588. *
  4589. * @return float
  4590. */
  4591. static float SignNoNeg( float number )
  4592. {
  4593. if ( number < 0 )
  4594. return -1;
  4595. return 1;
  4596. }
  4597.  
  4598. /**
  4599. * @brief Square the number but keeping the sign
  4600. *
  4601. * @return float
  4602. */
  4603. static float SquareSign( float number )
  4604. {
  4605. return number * number * Sign( number );
  4606. }
  4607.  
  4608. /**
  4609. * @brief (n * (n + 1)) * Sign(n)
  4610. *
  4611. * @return float
  4612. */
  4613. static float SquareSignPercent( float number )
  4614. {
  4615. return number * ( 1 + number ) * Sign( number );
  4616. }
  4617.  
  4618. static float Interpolate( float value, float cMin, float cMax, float vMin, float vMax )
  4619. {
  4620. if ( value <= cMin )
  4621. return vMin;
  4622. if ( value >= cMax )
  4623. return vMax;
  4624.  
  4625. return ( value - cMin ) / ( cMax - cMin ) * ( vMax - vMin ) + vMin;
  4626. }
  4627.  
  4628. static bool AngleDir( float a, float b )
  4629. {
  4630. float fR1 = a - b;
  4631. float fR2 = b - a;
  4632.  
  4633. if ( fR1 < 0 )
  4634. fR1 += 360;
  4635. if ( fR2 < 0 )
  4636. fR2 += 360;
  4637.  
  4638. return fR2 < fR1;
  4639. }
  4640.  
  4641. static float AngleDiff( float a, float b )
  4642. {
  4643. float angle = 180 - Math.AbsFloat( Math.AbsFloat( a - b ) - 180 );
  4644. if ( a + angle != b )
  4645. return -angle;
  4646. return angle;
  4647. }
  4648. };class CF_RegisterTypeConverter
  4649. {
  4650. void CF_RegisterTypeConverter(typename type)
  4651. {
  4652. CF_TypeConverter._Insert(type);
  4653. }
  4654. };
  4655. class CF_TypeConverter
  4656. {
  4657. private static autoptr array<string> m_TypeConverterNames = new array<string>();
  4658.  
  4659. private static autoptr map<typename, CF_TypeConverterBase> m_TypeConvertersMap = new map<typename, CF_TypeConverterBase>();
  4660. private static autoptr array<autoptr CF_TypeConverterBase> m_TypeConverters = new array<autoptr CF_TypeConverterBase>();
  4661.  
  4662. private static bool m_IsCreated;
  4663.  
  4664. private void CF_TypeConverter()
  4665. {
  4666. #ifdef CF_TRACE_ENABLED
  4667. auto trace = CF_Trace_0(this, "CF_TypeConverter");
  4668. #endif
  4669. }
  4670.  
  4671. void ~CF_TypeConverter()
  4672. {
  4673. #ifdef CF_TRACE_ENABLED
  4674. auto trace = CF_Trace_0(this, "~CF_TypeConverter");
  4675. #endif
  4676. }
  4677.  
  4678. static void _OnCreate()
  4679. {
  4680. #ifdef CF_TRACE_ENABLED
  4681. auto trace = CF_Trace_0("CF_TypeConverter", "_OnCreate");
  4682. #endif
  4683.  
  4684.  
  4685. _OnDestroy();
  4686.  
  4687. m_IsCreated = true;
  4688.  
  4689. for (int i = 0; i < m_TypeConverterNames.Count(); i++)
  4690. {
  4691. _Create(m_TypeConverterNames[i]);
  4692. }
  4693. }
  4694.  
  4695. static void _OnDestroy()
  4696. {
  4697. #ifdef CF_TRACE_ENABLED
  4698. auto trace = CF_Trace_0("CF_TypeConverter", "_OnDestroy");
  4699. #endif
  4700.  
  4701. m_TypeConvertersMap.Clear();
  4702. m_TypeConverters.Clear();
  4703.  
  4704. m_IsCreated = false;
  4705. }
  4706.  
  4707. /**
  4708. * @brief Inserts the typeconverter typename into the list of typeconverters to create, creates if already instantiated
  4709. */
  4710. static void _Insert(typename type)
  4711. {
  4712. #ifdef CF_TRACE_ENABLED
  4713. auto trace = CF_Trace_1("Insert").Add(type);
  4714. #endif
  4715.  
  4716. string className = type.ToString();
  4717. m_TypeConverterNames.Insert(className);
  4718.  
  4719. if (m_IsCreated)
  4720. {
  4721. _Create(className);
  4722. }
  4723. }
  4724.  
  4725. /**
  4726. * @brief Creates the typeconverter from the name of the class
  4727. */
  4728. static void _Create(string className)
  4729. {
  4730. #ifdef CF_TRACE_ENABLED
  4731. auto trace = CF_Trace_1("Create").Add(className);
  4732. #endif
  4733.  
  4734. CF_TypeConverterBase converter;
  4735. if (!Class.CastTo(converter, className.ToType().Spawn()))
  4736. {
  4737. return;
  4738. }
  4739.  
  4740. if (m_TypeConvertersMap.Contains(converter.GetType()))
  4741. {
  4742. return;
  4743. }
  4744.  
  4745. m_TypeConvertersMap.Insert(converter.GetType(), converter);
  4746. m_TypeConverters.Insert(converter);
  4747. }
  4748.  
  4749. static CF_TypeConverterBase Get(typename type)
  4750. {
  4751. #ifdef CF_TRACE_ENABLED
  4752. auto trace = CF_Trace_1("Get").Add(type);
  4753. #endif
  4754.  
  4755. CF_TypeConverterBase converter;
  4756. if (!m_TypeConvertersMap.Find(type, converter))
  4757. {
  4758. // if the type converter wasn't found, iterate over the list to find the inherited type and add it
  4759.  
  4760. typename inputType = type;
  4761. for (int i = m_TypeConverters.Count() - 1; i >= 0; i--)
  4762. {
  4763. if (type.IsInherited(m_TypeConverters[i].GetType()))
  4764. {
  4765. type = m_TypeConverters[i].GetType();
  4766. break;
  4767. }
  4768. }
  4769.  
  4770. if (type == inputType)
  4771. {
  4772. CF_Log.Error("Type Converter not found for type=" + type);
  4773. return null;
  4774. }
  4775.  
  4776. m_TypeConvertersMap.Find(type, converter);
  4777. }
  4778.  
  4779. return converter;
  4780. }
  4781.  
  4782. static CF_TypeConverterBase Get(Class instance, string variableName)
  4783. {
  4784. if (!instance)
  4785. {
  4786. return null;
  4787. }
  4788.  
  4789. typename instanceType = instance.Type();
  4790. int count = instanceType.GetVariableCount();
  4791. for (int index = 0; index < count; index++)
  4792. {
  4793. if (CF_String.EqualsIgnoreCase(variableName, instanceType.GetVariableName(index)))
  4794. {
  4795. typename variableType = instanceType.GetVariableType(index);
  4796. return Get(variableType);
  4797. }
  4798. }
  4799.  
  4800. return null;
  4801. }
  4802. };
  4803. /**
  4804. * @brief Super implementation to handle all possible conversions.
  4805. */
  4806. class CF_TypeConverterBase : Managed
  4807. {
  4808. void SetInt(int value)
  4809. {
  4810.  
  4811. }
  4812.  
  4813. int GetInt()
  4814. {
  4815. return 0;
  4816. }
  4817.  
  4818. void SetBool(bool value)
  4819. {
  4820.  
  4821. }
  4822.  
  4823. bool GetBool()
  4824. {
  4825. return false;
  4826. }
  4827.  
  4828. void SetFloat(float value)
  4829. {
  4830.  
  4831. }
  4832.  
  4833. float GetFloat()
  4834. {
  4835. return 0;
  4836. }
  4837.  
  4838. void SetVector(vector value)
  4839. {
  4840.  
  4841. }
  4842.  
  4843. vector GetVector()
  4844. {
  4845. return "0 0 0";
  4846. }
  4847.  
  4848. void SetString(string value)
  4849. {
  4850.  
  4851. }
  4852.  
  4853. string GetString()
  4854. {
  4855. return "";
  4856. }
  4857.  
  4858. void SetClass(Class value)
  4859. {
  4860.  
  4861. }
  4862.  
  4863. Class GetClass()
  4864. {
  4865. return null;
  4866. }
  4867.  
  4868. void SetManaged(Managed value)
  4869. {
  4870.  
  4871. }
  4872.  
  4873. Managed GetManaged()
  4874. {
  4875. return null;
  4876. }
  4877.  
  4878. typename GetType()
  4879. {
  4880. typename type;
  4881. return type;
  4882. }
  4883.  
  4884. override string GetDebugName()
  4885. {
  4886. return "[" + this + "] " + GetString();
  4887. }
  4888.  
  4889. bool IsIOSupported()
  4890. {
  4891. return false;
  4892. }
  4893.  
  4894. bool Read(Serializer ctx)
  4895. {
  4896. #ifdef CF_TRACE_ENABLED
  4897. auto trace = CF_Trace_1(this, "Read").Add(ctx);
  4898. #endif
  4899.  
  4900. CF_Log.Error("" + ClassName() + "::Read(Serializer) not implemented");
  4901.  
  4902. return false;
  4903. }
  4904.  
  4905. bool Write(Serializer ctx)
  4906. {
  4907. #ifdef CF_TRACE_ENABLED
  4908. auto trace = CF_Trace_1(this, "Write").Add(ctx);
  4909. #endif
  4910.  
  4911. CF_Log.Error("" + ClassName() + "::Write(Serializer) not implemented");
  4912.  
  4913. return false;
  4914. }
  4915.  
  4916. bool Read(CF_IO io)
  4917. {
  4918. #ifdef CF_TRACE_ENABLED
  4919. auto trace = CF_Trace_1(this, "Read").Add(io);
  4920. #endif
  4921.  
  4922. CF_Log.Error("" + ClassName() + "::Read(CF_IO) not implemented");
  4923.  
  4924. return false;
  4925. }
  4926.  
  4927. bool Write(CF_IO io)
  4928. {
  4929. #ifdef CF_TRACE_ENABLED
  4930. auto trace = CF_Trace_1(this, "Write").Add(io);
  4931. #endif
  4932.  
  4933. CF_Log.Error("" + ClassName() + "::Write(CF_IO) not implemented");
  4934.  
  4935. return false;
  4936. }
  4937.  
  4938. bool Read(Class instance, string variableName)
  4939. {
  4940. #ifdef CF_TRACE_ENABLED
  4941. auto trace = CF_Trace_2(this, "Read").Add(instance).Add(variableName);
  4942. #endif
  4943.  
  4944. CF_Log.Error("" + ClassName() + "::Read(Class, string) not implemented");
  4945.  
  4946. return false;
  4947. }
  4948.  
  4949. bool Write(Class instance, string variableName)
  4950. {
  4951. #ifdef CF_TRACE_ENABLED
  4952. auto trace = CF_Trace_2(this, "Write").Add(instance).Add(variableName);
  4953. #endif
  4954.  
  4955. CF_Log.Error("" + ClassName() + "::Write(Class, string) not implemented");
  4956.  
  4957. return false;
  4958. }
  4959.  
  4960. bool Read(Class instance, int variableIndex)
  4961. {
  4962. #ifdef CF_TRACE_ENABLED
  4963. auto trace = CF_Trace_2(this, "Read").Add(instance).Add(variableIndex);
  4964. #endif
  4965.  
  4966. CF_Log.Error("" + ClassName() + "::Read(Class, int) not implemented");
  4967.  
  4968. return false;
  4969. }
  4970. };
  4971. /**
  4972. * @brief Template
  4973. */
  4974. class CF_TypeConverterT<Class T> : CF_TypeConverterBase
  4975. {
  4976. protected T m_Value;
  4977.  
  4978. void Set(T value)
  4979. {
  4980. m_Value = value;
  4981. }
  4982.  
  4983. T Get()
  4984. {
  4985. return m_Value;
  4986. }
  4987.  
  4988. override typename GetType()
  4989. {
  4990. typename type = T;
  4991. return type;
  4992. }
  4993.  
  4994. override bool Read(Serializer ctx)
  4995. {
  4996. #ifdef CF_TRACE_ENABLED
  4997. auto trace = CF_Trace_1(this, "Read").Add(ctx);
  4998. #endif
  4999.  
  5000. return ctx.Read(m_Value);
  5001. }
  5002.  
  5003. override bool Write(Serializer ctx)
  5004. {
  5005. #ifdef CF_TRACE_ENABLED
  5006. auto trace = CF_Trace_1(this, "Write").Add(ctx);
  5007. #endif
  5008.  
  5009. return ctx.Write(m_Value);
  5010. }
  5011.  
  5012. override bool Read(Class instance, string variableName)
  5013. {
  5014. #ifdef CF_TRACE_ENABLED
  5015. auto trace = CF_Trace_2(this, "Read").Add(instance).Add(variableName);
  5016. #endif
  5017.  
  5018. EnScript.GetClassVar(instance, variableName, 0, m_Value);
  5019.  
  5020. return true;
  5021. }
  5022.  
  5023. override bool Write(Class instance, string variableName)
  5024. {
  5025. #ifdef CF_TRACE_ENABLED
  5026. auto trace = CF_Trace_2(this, "Write").Add(instance).Add(variableName);
  5027. #endif
  5028.  
  5029. EnScript.SetClassVar(instance, variableName, 0, m_Value);
  5030.  
  5031. return true;
  5032. }
  5033.  
  5034. override bool Read(Class instance, int variableIndex)
  5035. {
  5036. #ifdef CF_TRACE_ENABLED
  5037. auto trace = CF_Trace_2(this, "Read").Add(instance).Add(variableIndex);
  5038. #endif
  5039.  
  5040. typename instanceType = instance.Type();
  5041.  
  5042. typename variableType = instanceType.GetVariableType(variableIndex);
  5043. string variableName = instanceType.GetVariableName(variableIndex);
  5044.  
  5045. // Unfortunately 'Class' type variables results in a hard crash with no discernible pattern to lock them out
  5046. if (variableType.IsInherited(Class)) return false;
  5047.  
  5048. instanceType.GetVariableValue(instance, variableIndex, m_Value);
  5049.  
  5050. return true;
  5051. }
  5052. };
  5053. class CF_SHA256
  5054. {
  5055. static CF_Uint s_K[64] = {
  5056. 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
  5057. 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
  5058. 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
  5059. 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
  5060. 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
  5061. 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
  5062. 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
  5063. 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
  5064. };
  5065.  
  5066. static CF_Uint s_DataLength;
  5067. static CF_Byte s_Data[64];
  5068. static CF_Byte s_M[64];
  5069. static CF_Uint s_BitLen[2];
  5070. static CF_Uint s_State[8];
  5071. static CF_Byte s_Hash[64];
  5072.  
  5073. static void Process(CF_IO input, CF_IO output)
  5074. {
  5075. Process(input, output.m_Stream);
  5076. }
  5077.  
  5078. static void Process(CF_IO input, CF_Stream output)
  5079. {
  5080. if (!input) return;
  5081. if (!input.m_Stream) return;
  5082.  
  5083. input.m_Stream.SetPositionAtStart();
  5084.  
  5085. s_DataLength = 0;
  5086. s_BitLen[0] = 0;
  5087. s_BitLen[1] = 0;
  5088. s_State[0] = 0x6a09e667;
  5089. s_State[1] = 0xbb67ae85;
  5090. s_State[2] = 0x3c6ef372;
  5091. s_State[3] = 0xa54ff53a;
  5092. s_State[4] = 0x510e527f;
  5093. s_State[5] = 0x9b05688c;
  5094. s_State[6] = 0x1f83d9ab;
  5095. s_State[7] = 0x5be0cd19;
  5096.  
  5097. while (!input.EOF())
  5098. {
  5099. s_Data[s_DataLength] = input.ReadByte();
  5100. s_DataLength++;
  5101.  
  5102. if (s_DataLength == 64)
  5103. {
  5104. _Transform();
  5105.  
  5106. _AdjustBitLength(512);
  5107. s_DataLength = 0;
  5108. }
  5109. }
  5110.  
  5111. CF_Uint i = s_DataLength;
  5112. if (s_DataLength < 56)
  5113. {
  5114. s_Data[i++] = 0x80;
  5115.  
  5116. while (i < 56)
  5117. s_Data[i++] = 0x00;
  5118. }
  5119. else
  5120. {
  5121. s_Data[i++] = 0x80;
  5122.  
  5123. while (i < 64)
  5124. s_Data[i++] = 0x00;
  5125.  
  5126. _Transform();
  5127. }
  5128.  
  5129. _AdjustBitLength(s_DataLength * 8);
  5130.  
  5131. s_Data[63] = s_BitLen[0];
  5132. s_Data[62] = s_BitLen[0].ShiftRight(8);
  5133. s_Data[61] = s_BitLen[0].ShiftRight(16);
  5134. s_Data[60] = s_BitLen[0].ShiftRight(24);
  5135. s_Data[59] = s_BitLen[1];
  5136. s_Data[58] = s_BitLen[1].ShiftRight(8);
  5137. s_Data[57] = s_BitLen[1].ShiftRight(16);
  5138. s_Data[56] = s_BitLen[1].ShiftRight(24);
  5139.  
  5140. _Transform();
  5141.  
  5142. for (i = 0; i < 4; ++i)
  5143. {
  5144. int shift = 24 - (i * 8);
  5145. s_Hash[i ] = s_State[0].ShiftRight(shift);
  5146. s_Hash[i + 4 ] = s_State[1].ShiftRight(shift);
  5147. s_Hash[i + 8 ] = s_State[2].ShiftRight(shift);
  5148. s_Hash[i + 12] = s_State[3].ShiftRight(shift);
  5149. s_Hash[i + 16] = s_State[4].ShiftRight(shift);
  5150. s_Hash[i + 20] = s_State[5].ShiftRight(shift);
  5151. s_Hash[i + 24] = s_State[6].ShiftRight(shift);
  5152. s_Hash[i + 28] = s_State[7].ShiftRight(shift);
  5153. }
  5154.  
  5155. for (i = 0; i < 32; ++i)
  5156. {
  5157. output.Append(s_Hash[i] & 255);
  5158. }
  5159. }
  5160.  
  5161. static void _Transform()
  5162. {
  5163. CF_Uint a, b, c, d, e, f, g, h, i, j, t1, t2;
  5164.  
  5165. for (i = 0; i < 64; ++i) s_M[i] = 0;
  5166.  
  5167. for (i = 0; i < 16; ++i)
  5168. {
  5169. CF_Uint l1_a = s_Data[j] << 24;
  5170. CF_Uint l1_b = s_Data[j + 1] << 16;
  5171. CF_Uint l1_c = s_Data[j + 2] << 8;
  5172. CF_Uint l1_d = s_Data[j + 3];
  5173. s_M[i] = (l1_a | l1_b | l1_c | l1_d);
  5174. j += 4;
  5175. }
  5176.  
  5177. for (; i < 64; ++i)
  5178. {
  5179. CF_Uint l2_a = s_M[i - 2];
  5180. CF_Uint l2_b = CF_Uint.SIG1(l2_a);
  5181. CF_Uint l2_c = s_M[i - 7];
  5182. CF_Uint l2_d = s_M[i - 15];
  5183. CF_Uint l2_e = CF_Uint.SIG0(l2_d);
  5184. CF_Uint l2_f = s_M[i - 16];
  5185. s_M[i] = l2_b + l2_c + l2_e + l2_f;
  5186. }
  5187.  
  5188. a = s_State[0];
  5189. b = s_State[1];
  5190. c = s_State[2];
  5191. d = s_State[3];
  5192. e = s_State[4];
  5193. f = s_State[5];
  5194. g = s_State[6];
  5195. h = s_State[7];
  5196.  
  5197. for (i = 0; i < 64; ++i)
  5198. {
  5199. t1 = h.Add(CF_Uint.EP1(e)).Add(CF_Uint.CH(e, f, g)).Add(s_K[i]).Add(s_M[i]); //h + EP1(e) + CH(e, f, g) + s_K[i] + s_M[i];
  5200. t2 = CF_Uint.EP0(a).Add(CF_Uint.MAJ(a, b, c)); //EP0(a) + MAJ(a, b, c);
  5201. h = g;
  5202. g = f;
  5203. f = e;
  5204. e = d.Add(t1); //d + t1;
  5205. d = c;
  5206. c = b;
  5207. b = a;
  5208. a = t1.Add(t2); //t1 + t2;
  5209. }
  5210.  
  5211. s_State[0] = s_State[0] + a;
  5212. s_State[1] = s_State[1] + b;
  5213. s_State[2] = s_State[2] + c;
  5214. s_State[3] = s_State[3] + d;
  5215. s_State[4] = s_State[4] + e;
  5216. s_State[5] = s_State[5] + f;
  5217. s_State[6] = s_State[6] + g;
  5218. s_State[7] = s_State[7] + h;
  5219. }
  5220.  
  5221. static void _AdjustBitLength(CF_Uint c)
  5222. {
  5223. CF_Uint max_int = 0xffffffff;
  5224. CF_Uint test = max_int - c;
  5225. if (s_BitLen[0].IsGt(test)) //if a > test (unsigned comparison)
  5226. {
  5227. s_BitLen[1] = s_BitLen[1] + 1;
  5228. }
  5229.  
  5230. s_BitLen[0] = s_BitLen[0].Add(c); // A + C using unsigned math
  5231. }
  5232. };
  5233. class CF_EventSubscriber
  5234. {
  5235. /**
  5236. * @brief ATTRIBUTE Register a function as subscriber of up to 9 CF_EventHandler instances.
  5237. * If you need more than 9, please use the CF_MultiEventSubscriber attribute instead.
  5238. *
  5239. * @code
  5240. * [CF_EventSubscriber(ScriptCaller.Create(HandlerFunction), Event1, Event2, Event3 ... Event9)]
  5241. * void HandlerFunction(Class sender, CF_EventArgs args) {}
  5242. * @endcode
  5243. *
  5244. * @param subscriber Function to register as subscriber.
  5245. * @param evt1...9 CF_EventHandler instances to subscribe to.
  5246. * @return void.
  5247. */
  5248. void CF_EventSubscriber(ScriptCaller subscriber,
  5249. CF_EventHandlerBase evt1 = NULL,
  5250. CF_EventHandlerBase evt2 = NULL,
  5251. CF_EventHandlerBase evt3 = NULL,
  5252. CF_EventHandlerBase evt4 = NULL,
  5253. CF_EventHandlerBase evt5 = NULL,
  5254. CF_EventHandlerBase evt6 = NULL,
  5255. CF_EventHandlerBase evt7 = NULL,
  5256. CF_EventHandlerBase evt8 = NULL,
  5257. CF_EventHandlerBase evt9 = NULL)
  5258. {
  5259. UpdateSubscriptions(subscriber, {evt1, evt2, evt3, evt4, evt5, evt6, evt7, evt8, evt9});
  5260. }
  5261.  
  5262. static void UpdateSubscriptions(ScriptCaller subscriber, array<CF_EventHandlerBase> events)
  5263. {
  5264. foreach (CF_EventHandlerBase addEvent : events)
  5265. {
  5266. if (addEvent)
  5267. addEvent.AddSubscriber(subscriber);
  5268. }
  5269. }
  5270. }
  5271. class CF_MultiEventSubscriber
  5272. {
  5273. /**
  5274. * @brief ATTRIBUTE Register a function as subscriber of multiple CF_EventHandler instances.
  5275. * If you only need to subscribe to 9 or less instances, use the regular CF_EventSubscriber attribute instead.
  5276. *
  5277. * @code
  5278. * [CF_MultiEventSubscriber(ScriptCaller.Create(HandlerFunction), {Event1, Event2, Event3 ... EventN})]
  5279. * void HandlerFunction(Class sender, CF_EventArgs args) {}
  5280. * @endcode
  5281. *
  5282. * @param subscriber Function to register as subscriber.
  5283. * @param events Array of CF_EventHandler instances to subscribe to. Use the static array initializer syntax: {<data here>}.
  5284. * @return void.
  5285. */
  5286. void CF_MultiEventSubscriber(ScriptCaller subscriber, array<CF_EventHandlerBase> events)
  5287. {
  5288. CF_EventSubscriber.UpdateSubscriptions(subscriber, events);
  5289. }
  5290. };
  5291. // DO NOT REMOVE!!! For some reason without this there is a compile error cf_eventhandler.c(39): Too many parameters for 'Get' method ...
  5292. typedef array<ref ScriptCaller> CF_ScriptInvoker;
  5293.  
  5294. class CF_EventHandlerBase //Base class to be able to accept both CF_EventHandler and CF_EventHandlerT as function parameter
  5295. {
  5296. protected autoptr CF_ScriptInvoker m_aCallers = {};
  5297.  
  5298. void AddSubscriber(ScriptCaller caller)
  5299. {
  5300. #ifdef CF_TRACE_ENABLED
  5301. auto trace = CF_Trace_0(this, "AddSubscriber");
  5302. #endif
  5303.  
  5304. #ifndef DAYZ_1_21
  5305. // Make sure we do not add the same caller twice
  5306. foreach (ScriptCaller existingCaller : m_aCallers)
  5307. {
  5308. if (existingCaller && existingCaller.IsValid() && existingCaller.Equals(caller))
  5309. return;
  5310. }
  5311. #endif
  5312.  
  5313. m_aCallers.Insert(caller);
  5314. }
  5315.  
  5316. void RemoveSubscriber(ScriptCaller caller)
  5317. {
  5318. #ifdef CF_TRACE_ENABLED
  5319. auto trace = CF_Trace_0(this, "RemoveSubscriber");
  5320. #endif
  5321.  
  5322. m_aCallers.RemoveItem(caller);
  5323. }
  5324.  
  5325. void CF_EventHandlerBase()
  5326. {
  5327. #ifdef CF_TRACE_ENABLED
  5328. auto trace = CF_Trace_0(this, "CF_EventHandlerBase");
  5329. #endif
  5330. }
  5331.  
  5332. void ~CF_EventHandlerBase()
  5333. {
  5334. #ifdef CF_TRACE_ENABLED
  5335. auto trace = CF_Trace_0(this, "~CF_EventHandlerBase");
  5336. #endif
  5337. }
  5338. }
  5339.  
  5340. class CF_EventHandlerT<Class TEventArgs> extends CF_EventHandlerBase
  5341. {
  5342. void Invoke(Class sender = NULL, TEventArgs args = NULL)
  5343. {
  5344. #ifdef CF_TRACE_ENABLED
  5345. auto trace = CF_Trace_2(this, "Invoke").Add(sender).Add(args);
  5346. #endif
  5347.  
  5348. foreach (auto caller : m_aCallers)
  5349. {
  5350. #ifndef DAYZ_1_21
  5351. if (caller && caller.IsValid())
  5352. #else
  5353. if (caller)
  5354. #endif
  5355. caller.Invoke(sender, args);
  5356. }
  5357. }
  5358. }
  5359.  
  5360. class CF_EventHandler extends CF_EventHandlerT<CF_EventArgs>
  5361. {
  5362. }
  5363. class CF_LifecycleEvents
  5364. {
  5365. static const autoptr CF_EventHandler OnGameCreate = new CF_EventHandler();
  5366. static const autoptr CF_EventHandler OnGameDestroy = new CF_EventHandler();
  5367. static const autoptr CF_EventHandler OnMissionCreate = new CF_EventHandler();
  5368. static const autoptr CF_EventHandler OnMissionDestroy = new CF_EventHandler();
  5369.  
  5370. //!Single static class. Do not create with new or spawn - use CF_LifecycleEvents.<something> for access instead.
  5371. protected void CF_LifecycleEvents()
  5372. {
  5373. #ifdef CF_TRACE_ENABLED
  5374. auto trace = CF_Trace_0(this, "CF_LifecycleEvents");
  5375. #endif
  5376. }
  5377.  
  5378. protected void ~CF_LifecycleEvents()
  5379. {
  5380. #ifdef CF_TRACE_ENABLED
  5381. auto trace = CF_Trace_0(this, "~CF_LifecycleEvents");
  5382. #endif
  5383. }
  5384. }
  5385. /* TODO: Move to Community Framework */
  5386.  
  5387. class __Stack<Class T>
  5388. {
  5389. private T _data[256];
  5390. private int _count;
  5391.  
  5392. void __Stack()
  5393. {
  5394. }
  5395.  
  5396. T Pop()
  5397. {
  5398. T value;
  5399.  
  5400. if ( _count <= 0 )
  5401. {
  5402. _count = 0;
  5403. } else
  5404. {
  5405. value = _data[ _count - 1 ];
  5406. _count--;
  5407. }
  5408.  
  5409. return value;
  5410. }
  5411.  
  5412. T Peek()
  5413. {
  5414. return _data[ _count - 1 ];
  5415. }
  5416.  
  5417. T Push( T value )
  5418. {
  5419. _data[ _count ] = value;
  5420.  
  5421. _count++;
  5422.  
  5423. return value;
  5424. }
  5425.  
  5426. array<T> ToArray()
  5427. {
  5428. array<T> arr = new array<T>();
  5429. for ( int i = 0; i < _count; i++ )
  5430. arr.Insert(_data[i]);
  5431. return arr;
  5432. }
  5433.  
  5434. void Clear()
  5435. {
  5436. _count = 0;
  5437. }
  5438.  
  5439. T Get( int idx )
  5440. {
  5441. return _data[idx];
  5442. }
  5443.  
  5444. void Set( int idx, T value )
  5445. {
  5446. _data[idx] = value;
  5447. }
  5448.  
  5449. int Count()
  5450. {
  5451. return _count;
  5452. }
  5453. };CGame CF_CreateGame()
  5454. {
  5455. // Already assigns 'g_Game'
  5456. CreateGame();
  5457.  
  5458. CF._GameInit();
  5459.  
  5460. return g_Game;
  5461. }
  5462.  
  5463. typedef CommunityFramework CF;
  5464. class CommunityFramework : ModStructure
  5465. {
  5466. static CF_ObjectManager ObjectManager;
  5467. static CF_XML XML;
  5468.  
  5469. /**
  5470. * @brief [Internal] CommunityFramework initilization for 3_Game
  5471. *
  5472. * @return void
  5473. */
  5474. static void _GameInit()
  5475. {
  5476. }
  5477.  
  5478. /**
  5479. * @brief [Internal] CommunityFramework cleanup
  5480. *
  5481. * @return void
  5482. */
  5483. static void _Cleanup()
  5484. {
  5485. ObjectManager._Cleanup();
  5486. XML._Cleanup();
  5487. }
  5488.  
  5489. /**
  5490. * @brief Checks if the game is host
  5491. */
  5492. static bool IsMissionHost()
  5493. {
  5494. if (!g_Game) return false;
  5495.  
  5496. return g_Game.IsServer() || !g_Game.IsMultiplayer();
  5497. }
  5498.  
  5499. /**
  5500. * @brief Checks if the game is client
  5501. */
  5502. static bool IsMissionClient()
  5503. {
  5504. if (!g_Game) return false;
  5505.  
  5506. return g_Game.IsClient() || !g_Game.IsMultiplayer();
  5507. }
  5508.  
  5509. /**
  5510. * @brief Checks if the game is singleplayer
  5511. */
  5512. static bool IsMissionOffline()
  5513. {
  5514. if (!g_Game) return false;
  5515.  
  5516. return g_Game.IsServer() && !g_Game.IsMultiplayer();
  5517. }
  5518. };
  5519.  
  5520. class JM_CommunityFramework : CommunityFramework
  5521. {
  5522.  
  5523. };
  5524.  
  5525. //--------------------------------------------------------
  5526.  
  5527. const autoptr TStringArray _cf_characters = {
  5528. // "",
  5529. // "",
  5530. // "",
  5531. // "",
  5532. // "",
  5533. // "",
  5534. // "",
  5535. // "",
  5536. // "",
  5537. // "",
  5538. // "",
  5539. // "",
  5540. // "",
  5541. // "",
  5542. // "",
  5543. // "",
  5544. // "",
  5545. // "",
  5546. // "",
  5547. // "",
  5548. // "",
  5549. // "",
  5550. // "",
  5551. // "",
  5552. // "",
  5553. // "",
  5554. // "",
  5555. // "",
  5556. // "",
  5557. // "",
  5558. // "",
  5559. // "",
  5560. " ",
  5561. "!",
  5562. "\"",
  5563. "#",
  5564. "$",
  5565. "%",
  5566. "&",
  5567. "\'",
  5568. "(",
  5569. ")",
  5570. "*",
  5571. "+",
  5572. ",",
  5573. "-",
  5574. ".",
  5575. "/",
  5576. "0",
  5577. "1",
  5578. "2",
  5579. "3",
  5580. "4",
  5581. "5",
  5582. "6",
  5583. "7",
  5584. "8",
  5585. "9",
  5586. ":",
  5587. ";",
  5588. "<",
  5589. "=",
  5590. ">",
  5591. "?",
  5592. "@",
  5593. "A",
  5594. "B",
  5595. "C",
  5596. "D",
  5597. "E",
  5598. "F",
  5599. "G",
  5600. "H",
  5601. "I",
  5602. "J",
  5603. "K",
  5604. "L",
  5605. "M",
  5606. "N",
  5607. "O",
  5608. "P",
  5609. "Q",
  5610. "R",
  5611. "S",
  5612. "T",
  5613. "U",
  5614. "V",
  5615. "W",
  5616. "X",
  5617. "Y",
  5618. "Z",
  5619. "[",
  5620. "\\",
  5621. "]",
  5622. "^",
  5623. "_",
  5624. "`",
  5625. "a",
  5626. "b",
  5627. "c",
  5628. "d",
  5629. "e",
  5630. "f",
  5631. "g",
  5632. "h",
  5633. "i",
  5634. "j",
  5635. "k",
  5636. "l",
  5637. "m",
  5638. "n",
  5639. "o",
  5640. "p",
  5641. "q",
  5642. "r",
  5643. "s",
  5644. "t",
  5645. "u",
  5646. "v",
  5647. "w",
  5648. "x",
  5649. "y",
  5650. "z",
  5651. "{",
  5652. "|",
  5653. "}",
  5654. "~",
  5655. ""
  5656. };
  5657.  
  5658. //TODO: remove this when the CF refactor is completed
  5659. static string CF_XML_Indent( int level )
  5660. {
  5661. string str = "";
  5662.  
  5663. for ( int i = 0; i < level; ++i )
  5664. str += "\t";
  5665.  
  5666. return str;
  5667. }
  5668.  
  5669. static bool IsMissionHost()
  5670. {
  5671. if ( !GetGame() )
  5672. return false;
  5673.  
  5674. return GetGame().IsServer() || !GetGame().IsMultiplayer();
  5675. }
  5676.  
  5677. static bool IsMissionClient()
  5678. {
  5679. if ( !GetGame() )
  5680. return false;
  5681.  
  5682. return GetGame().IsClient() || !GetGame().IsMultiplayer();
  5683. }
  5684.  
  5685. static bool IsMissionOffline()
  5686. {
  5687. if ( !GetGame() )
  5688. return false;
  5689.  
  5690. return GetGame().IsServer() && !GetGame().IsMultiplayer();
  5691. }
  5692.  
  5693. static string CF_Indent( int level )
  5694. {
  5695. string str = "";
  5696.  
  5697. for ( int i = 0; i < level; ++i )
  5698. str += " ";
  5699.  
  5700. return str;
  5701. }
  5702.  
  5703. static void CF_DumpWidgets( Widget root, int tabs = 0 )
  5704. {
  5705. if ( !root )
  5706. {
  5707. return;
  5708. }
  5709.  
  5710. string tmp;
  5711. for ( int i = 0; i < tabs; i++ )
  5712. {
  5713. tmp += " ";
  5714. }
  5715.  
  5716. string invisible = "";
  5717.  
  5718. if ( !root.IsVisibleHierarchy() )
  5719. {
  5720. invisible = "[invisible]";
  5721. }
  5722.  
  5723. Print( tmp + "- " + root.GetName() + " (" + root.GetTypeName() + ") " + invisible );
  5724.  
  5725. bool collapse = false;
  5726. if ( root.GetChildren() )
  5727. {
  5728. collapse = true;
  5729. Print( tmp + "{" );
  5730. }
  5731.  
  5732. CF_DumpWidgets( root.GetChildren(), tabs + 1 );
  5733.  
  5734. if ( collapse )
  5735. {
  5736. Print( tmp + "}" );
  5737. }
  5738.  
  5739. CF_DumpWidgets( root.GetSibling(), tabs );
  5740. }
  5741.  
  5742.  
  5743.  
  5744. static void Assert_Log( string str, int offset = 1 )
  5745. {
  5746. Print( "==============================================WARNING=======================================================" );
  5747. string time = CF_Date.Now( false ).Format( CF_Date.DATETIME );
  5748. Print( "[WARNING " + time + "] " + str );
  5749. Print( "Do you see this message? Unless the time is within a second of the crash than this was not the cause." );
  5750.  
  5751. string dump = "";
  5752. DumpStackString(dump);
  5753. array<string> outputs = new array<string>();
  5754. dump.Split("\n", outputs);
  5755.  
  5756. for (int i = offset; i < outputs.Count(); i++)
  5757. {
  5758. Print("\t" + outputs[i]);
  5759. }
  5760.  
  5761. Print( "============================================================================================================" );
  5762. }
  5763.  
  5764. static bool Assert_Empty( string str, string message = "" )
  5765. {
  5766. if ( str == "" )
  5767. {
  5768. if ( message != "" )
  5769. message = ": " + message;
  5770.  
  5771. Assert_Log( "ASSERTION STRING EMPTY" + message, 2 );
  5772. return true;
  5773. }
  5774.  
  5775. return false;
  5776. }
  5777.  
  5778. static bool Assert_Null( Class cls, string message = "" )
  5779. {
  5780. if ( cls == NULL )
  5781. {
  5782. if ( message != "" )
  5783. message = ": " + message;
  5784.  
  5785. Assert_Log( "ASSERTION NULL" + message, 2 );
  5786. return true;
  5787. }
  5788.  
  5789. return false;
  5790. }
  5791.  
  5792. static bool Assert_False( bool cls, string message = "" )
  5793. {
  5794. if ( cls == false )
  5795. {
  5796. if ( message != "" )
  5797. message = ": " + message;
  5798.  
  5799. Assert_Log( "ASSERTION FALSE" + message, 2 );
  5800. return true;
  5801. }
  5802.  
  5803. return false;
  5804. }
  5805.  
  5806. static bool Assert_True( bool cls, string message = "" )
  5807. {
  5808. if ( cls == true )
  5809. {
  5810. if ( message != "" )
  5811. message = ": " + message;
  5812.  
  5813. Assert_Log( "ASSERTION TRUE" + message, 2 );
  5814. return true;
  5815. }
  5816.  
  5817. return false;
  5818. }class ConfigArray : ConfigEntry
  5819. {
  5820. override string GetType()
  5821. {
  5822. return "ARRAY";
  5823. }
  5824.  
  5825. override bool IsArray()
  5826. {
  5827. return true;
  5828. }
  5829.  
  5830. override ConfigArray GetArray()
  5831. {
  5832. return this;
  5833. }
  5834.  
  5835. override bool Parse( ConfigReader reader, ConfigFile file )
  5836. {
  5837. string c = reader.SkipWhitespace();
  5838.  
  5839. if ( c != "{" )
  5840. {
  5841. reader.Error( "'" + c + "' encountered instead of '{'" );
  5842. return false;
  5843. }
  5844.  
  5845. for ( int vpp = 0; vpp < 100; vpp++ )
  5846. {
  5847. c = reader.SkipWhitespace();
  5848.  
  5849. reader.BackChar();
  5850.  
  5851. ConfigArrayParam entry = NULL;
  5852.  
  5853. if ( c == "{" )
  5854. {
  5855. entry = new ConfigArrayParamArray();
  5856. entry._parent = this;
  5857. if ( !entry.Parse( reader, file ) )
  5858. return false;
  5859. } else
  5860. {
  5861. bool quoted;
  5862. string value = reader.GetQuotedWord( quoted );
  5863.  
  5864. if ( value.Length() > 0 )
  5865. {
  5866. if ( quoted )
  5867. {
  5868. entry = new ConfigArrayParamText();
  5869. entry._parent = this;
  5870. entry.SetText( value );
  5871. } else
  5872. {
  5873. if ( value.Contains( "." ) )
  5874. {
  5875. entry = new ConfigArrayParamFloat();
  5876. entry.SetFloat( value.ToFloat() );
  5877. entry._parent = this;
  5878. } else
  5879. {
  5880. entry = new ConfigArrayParamInt();
  5881. entry.SetInt( value.ToInt() );
  5882. entry._parent = this;
  5883. }
  5884. }
  5885. }
  5886. }
  5887.  
  5888. if ( entry )
  5889. _entries.Insert( entry );
  5890.  
  5891. c = reader.SkipWhitespace();
  5892.  
  5893. if ( c == "}" )
  5894. return true;
  5895.  
  5896. if ( c != "," && c != ";" )
  5897. {
  5898. reader.Error( "'" + c + "' encounted instead of ','" );
  5899. return false;
  5900. }
  5901. }
  5902.  
  5903. reader.Error( "Prematurely ending the array reading, going for too long." );
  5904. return false;
  5905. }
  5906. };class ConfigArrayParam : ConfigEntry
  5907. {
  5908. override string GetType()
  5909. {
  5910. return "ARRAY_PARAM_BASE";
  5911. }
  5912.  
  5913. override bool IsArrayParam()
  5914. {
  5915. return true;
  5916. }
  5917. };class ConfigArrayParamArray : ConfigArrayParam
  5918. {
  5919. private ref ConfigArray _value = new ConfigArray();
  5920.  
  5921. void ~ConfigArrayParamArray()
  5922. {
  5923. #ifdef CF_TRACE_ENABLED
  5924. auto trace = CF_Trace_0(this);
  5925. #endif
  5926.  
  5927. }
  5928.  
  5929. override string GetType()
  5930. {
  5931. return "ARRAY_PARAM";
  5932. }
  5933.  
  5934. override ConfigArray GetArray()
  5935. {
  5936. return _value;
  5937. }
  5938.  
  5939. override bool IsArray()
  5940. {
  5941. return true;
  5942. }
  5943. };class ConfigArrayParamFloat : ConfigArrayParam
  5944. {
  5945. private float _value;
  5946.  
  5947. override string GetType()
  5948. {
  5949. return "FLOAT_PARAM";
  5950. }
  5951.  
  5952. override bool IsFloat()
  5953. {
  5954. return true;
  5955. }
  5956.  
  5957. override float GetFloat()
  5958. {
  5959. return _value;
  5960. }
  5961.  
  5962. override void SetFloat( float value )
  5963. {
  5964. _value = value;
  5965. }
  5966. };class ConfigArrayParamInt : ConfigArrayParam
  5967. {
  5968. private int _value;
  5969.  
  5970. override string GetType()
  5971. {
  5972. return "INT_PARAM";
  5973. }
  5974.  
  5975. override bool IsInt()
  5976. {
  5977. return true;
  5978. }
  5979.  
  5980. override int GetInt()
  5981. {
  5982. return _value;
  5983. }
  5984.  
  5985. override void SetInt( int value )
  5986. {
  5987. _value = value;
  5988. }
  5989. };class ConfigArrayParamLong : ConfigArrayParam
  5990. {
  5991. private int _value;
  5992.  
  5993. override string GetType()
  5994. {
  5995. return "LONG_PARAM";
  5996. }
  5997.  
  5998. override bool IsLong()
  5999. {
  6000. return true;
  6001. }
  6002.  
  6003. override int GetLong()
  6004. {
  6005. return _value;
  6006. }
  6007.  
  6008. override void SetLong( int value )
  6009. {
  6010. _value = value;
  6011. }
  6012. };class ConfigArrayParamText : ConfigArrayParam
  6013. {
  6014. private string _value;
  6015.  
  6016. override string GetType()
  6017. {
  6018. return "TEXT_PARAM";
  6019. }
  6020.  
  6021. override bool IsText()
  6022. {
  6023. return true;
  6024. }
  6025.  
  6026. override string GetText()
  6027. {
  6028. return _value;
  6029. }
  6030.  
  6031. override void SetText( string value )
  6032. {
  6033. _value = value;
  6034. }
  6035. };class ConfigClassDeclaration : ConfigClass
  6036. {
  6037. override bool IsClassDecl()
  6038. {
  6039. return true;
  6040. }
  6041. };
  6042.  
  6043. class ConfigDelete : ConfigEntry
  6044. {
  6045. override bool IsDelete()
  6046. {
  6047. return true;
  6048. }
  6049. };
  6050.  
  6051. class ConfigClass : ConfigEntry
  6052. {
  6053. private ConfigClass _base;
  6054.  
  6055. void ConfigClass()
  6056. {
  6057.  
  6058. }
  6059.  
  6060. override string GetType()
  6061. {
  6062. return "CLASS";
  6063. }
  6064.  
  6065. override ConfigClass GetClass()
  6066. {
  6067. return this;
  6068. }
  6069.  
  6070. ConfigClass GetBase()
  6071. {
  6072. return _base;
  6073. }
  6074.  
  6075. private ConfigClass SetBase( string name )
  6076. {
  6077. int baseIndex = _parent.FindIndex( name );
  6078. int thisIndex = _parent.FindIndex( _name );
  6079. if ( baseIndex >= 0 && ( baseIndex < thisIndex || thisIndex < 0 ) )
  6080. {
  6081. return _parent._entries[ baseIndex ].GetClass();
  6082. }
  6083.  
  6084. ConfigEntry possibleEntry = NULL;
  6085.  
  6086. if ( _parent.GetClass()._base != NULL )
  6087. {
  6088. possibleEntry = _parent.GetClass()._base.Find( name, true, true );
  6089. }
  6090.  
  6091. if ( possibleEntry == NULL && _parent._parent != NULL )
  6092. {
  6093. possibleEntry = _parent._parent.GetClass().Find( name, true, true );
  6094. }
  6095.  
  6096. if ( possibleEntry != NULL && possibleEntry.IsClass() )
  6097. {
  6098. return possibleEntry.GetClass();
  6099. }
  6100.  
  6101. return NULL;
  6102. }
  6103.  
  6104. ConfigEntry Find( string name, bool checkParent, bool checkBase )
  6105. {
  6106. int idx = FindIndex( name, true );
  6107. if ( idx >= 0 )
  6108. return _entries[idx];
  6109.  
  6110. ConfigEntry entry = NULL;
  6111.  
  6112. if ( checkBase && _base != NULL )
  6113. {
  6114. entry = _base.Find( name, true, true );
  6115. if ( entry != NULL )
  6116. return entry;
  6117. }
  6118.  
  6119. if ( checkParent && _parent != NULL && _parent.GetClass() != NULL )
  6120. {
  6121. entry = _parent.GetClass().Find( name, true, checkBase );
  6122. if ( entry != NULL )
  6123. return entry;
  6124. }
  6125.  
  6126. return NULL;
  6127. }
  6128.  
  6129. override bool Parse( ConfigReader reader, ConfigFile file )
  6130. {
  6131. for ( int vpp = 0; vpp < 100; vpp++ )
  6132. {
  6133. string c = reader.SkipWhitespace();
  6134.  
  6135. if ( reader.EOF() )
  6136. {
  6137. if ( this == file )
  6138. return true;
  6139.  
  6140. reader.Error( "Unexpected EOF reached." );
  6141. return false;
  6142. }
  6143.  
  6144. if ( c == "#" )
  6145. {
  6146. reader.NextLine();
  6147. } else if (c == "}" )
  6148. {
  6149. c = reader.GetCharacter();
  6150. while ( reader.IsWhitespace( c ) || c == ";" )
  6151. c = reader.GetCharacter();
  6152.  
  6153. reader.BackChar();
  6154. return true;
  6155. }
  6156.  
  6157. reader.BackChar();
  6158.  
  6159. ConfigEntry entry = NULL;
  6160. string name = "";
  6161.  
  6162. string token = reader.GetWord();
  6163. if ( token == "delete" )
  6164. {
  6165. name = reader.GetWord();
  6166.  
  6167. c = reader.SkipWhitespace();
  6168.  
  6169. if ( c == ";" )
  6170. {
  6171. entry = new ConfigDelete();
  6172. entry._name = name;
  6173. entry._parent = this;
  6174. } else
  6175. {
  6176. reader.Error( "'" + c + "' encountered instead of ';'" );
  6177. return false;
  6178. }
  6179. } else if ( token == "class" )
  6180. {
  6181. name = reader.GetWord();
  6182.  
  6183. c = reader.SkipWhitespace();
  6184.  
  6185. if ( c == ";" )
  6186. {
  6187. entry = new ConfigClassDeclaration();
  6188. entry._name = name;
  6189. entry._parent = this;
  6190. } else
  6191. {
  6192. entry = new ConfigClass();
  6193. entry._name = name;
  6194. entry._parent = this;
  6195.  
  6196. if ( c == ":" )
  6197. {
  6198. string baseName = reader.GetWord();
  6199. ConfigEntry baseEntry = Find( baseName, true, true );
  6200. if ( baseEntry == NULL )
  6201. {
  6202. reader.Error( "Undefined base class '" + baseName + "'" );
  6203. return false;
  6204. }
  6205.  
  6206. if ( !baseEntry.IsClass() )
  6207. {
  6208. reader.Error( "'" + baseName + "' is not a class" );
  6209. return false;
  6210. }
  6211.  
  6212. entry.GetClass()._base = baseEntry.GetClass();
  6213. c = reader.GetCharacter();
  6214. }
  6215.  
  6216. while ( c != "{" )
  6217. {
  6218. if ( !reader.IsWhitespace(c) )
  6219. {
  6220. reader.Error( "'" + c + "' encountered instead of '{'");
  6221. return false;
  6222. }
  6223.  
  6224. c = reader.GetCharacter();
  6225. }
  6226.  
  6227. if ( !entry.Parse( reader, file ) )
  6228. return false;
  6229. }
  6230. } else if ( token == "enum" )
  6231. {
  6232. reader.Error( "Enum is not supported");
  6233. return false;
  6234. } else if ( token != "" )
  6235. {
  6236. c = reader.GetCharacter();
  6237. name = token;
  6238.  
  6239. if ( c == "[" )
  6240. {
  6241. c = reader.SkipWhitespace();
  6242.  
  6243. if (c != "]")
  6244. {
  6245. reader.Error( "'" + c + "' encountered instead of ']'" );
  6246. return false;
  6247. }
  6248.  
  6249. c = reader.SkipWhitespace();
  6250.  
  6251. if (c != "=")
  6252. {
  6253. reader.Error( "'" + c + "' encountered instead of '='" );
  6254. return false;
  6255. }
  6256.  
  6257. entry = new ConfigArray();
  6258. entry._name = name;
  6259. entry._parent = this;
  6260. if ( !entry.Parse( reader, file ) )
  6261. return false;
  6262.  
  6263. c = reader.SkipWhitespace();
  6264.  
  6265. if ( c != ";")
  6266. {
  6267. reader.Error( "'" + c + "' encountered instead of ';'" );
  6268. return false;
  6269. }
  6270. } else
  6271. {
  6272. while ( reader.IsWhitespace( c ) )
  6273. c = reader.GetCharacter();
  6274.  
  6275. if ( c != "=" )
  6276. {
  6277. reader.Error( "'" + c + "' encountered instead of '='" );
  6278. return false;
  6279. }
  6280.  
  6281. bool quoted;
  6282. string value = reader.GetQuotedWord( quoted );
  6283.  
  6284. c = reader.SkipWhitespace();
  6285.  
  6286. if (c == "}" )
  6287. {
  6288. reader.Warning( "'" + c + "' encountered instead of ';'" );
  6289. reader.BackChar();
  6290. } else if (c != ";" )
  6291. {
  6292. reader.Error( "Missing ';' at the end of the line" );
  6293. return false;
  6294.  
  6295. // TODO: resolve
  6296. /*
  6297. if (c != '\n' && c != '\r')
  6298. {
  6299. if (!quoted)
  6300. {
  6301. ParseError(input, $"'{(char)c}' encountered instead of ';'");
  6302. return false;
  6303. }
  6304. input.BackChar()
  6305. }
  6306. ParseWarning(input, $"Missing ';' at the end of the line");
  6307. */
  6308. }
  6309.  
  6310. if ( quoted )
  6311. {
  6312. entry = new ConfigValueText();
  6313. entry._name = name;
  6314. entry.SetText( value );
  6315. entry._parent = this;
  6316. } else
  6317. {
  6318. if ( value.Contains( "." ) )
  6319. {
  6320. entry = new ConfigValueFloat();
  6321. entry._name = name;
  6322. entry.SetFloat( value.ToFloat() );
  6323. entry._parent = this;
  6324. } else
  6325. {
  6326. entry = new ConfigValueInt();
  6327. entry._name = name;
  6328. entry.SetInt( value.ToInt() );
  6329. entry._parent = this;
  6330. }
  6331. }
  6332. }
  6333. }
  6334.  
  6335. if ( entry != NULL )
  6336. {
  6337. int idx = FindIndex( entry._name );
  6338. if ( idx < 0)
  6339. {
  6340. _entries.Insert( entry );
  6341. } else
  6342. {
  6343. reader.Error( "'" + entry._name + "' already defined" );
  6344. }
  6345. }
  6346. }
  6347.  
  6348. reader.Error( "Prematurely ending the class reading, going for too long." );
  6349. return false;
  6350. }
  6351. };class ConfigEntry : Managed
  6352. {
  6353. protected ref array< ref ConfigEntry > _entries;
  6354.  
  6355. protected ref ConfigEntry _parent;
  6356.  
  6357. protected string _name;
  6358.  
  6359. void ConfigEntry()
  6360. {
  6361. _entries = new array< ref ConfigEntry >();
  6362.  
  6363. _parent = NULL;
  6364.  
  6365. _name = "";
  6366. }
  6367.  
  6368. string GetType()
  6369. {
  6370. return "ENTRY";
  6371. }
  6372.  
  6373. string GetName()
  6374. {
  6375. return _name;
  6376. }
  6377.  
  6378. ConfigEntry GetParent()
  6379. {
  6380. return _parent;
  6381. }
  6382.  
  6383. ConfigClass GetClass()
  6384. {
  6385. return NULL;
  6386. }
  6387.  
  6388. bool IsValue()
  6389. {
  6390. return false;
  6391. }
  6392.  
  6393. bool IsClass()
  6394. {
  6395. return true;
  6396. }
  6397.  
  6398. bool IsClassDecl()
  6399. {
  6400. return true;
  6401. }
  6402.  
  6403. bool IsDelete()
  6404. {
  6405. return true;
  6406. }
  6407.  
  6408. bool IsText()
  6409. {
  6410. return false;
  6411. }
  6412.  
  6413. string GetText()
  6414. {
  6415. return "";
  6416. }
  6417.  
  6418. void SetText( string value )
  6419. {
  6420. }
  6421.  
  6422. bool IsFloat()
  6423. {
  6424. return false;
  6425. }
  6426.  
  6427. float GetFloat()
  6428. {
  6429. return 0;
  6430. }
  6431.  
  6432. void SetFloat( float value )
  6433. {
  6434. }
  6435.  
  6436. bool IsInt()
  6437. {
  6438. return false;
  6439. }
  6440.  
  6441. int GetInt()
  6442. {
  6443. return 0;
  6444. }
  6445.  
  6446. void SetInt( int value )
  6447. {
  6448. }
  6449.  
  6450. bool IsLong()
  6451. {
  6452. return false;
  6453. }
  6454.  
  6455. int GetLong()
  6456. {
  6457. return 0;
  6458. }
  6459.  
  6460. void SetLong( int value )
  6461. {
  6462. }
  6463.  
  6464. ConfigArray GetArray()
  6465. {
  6466. return NULL;
  6467. }
  6468.  
  6469. bool IsArrayParam()
  6470. {
  6471. return false;
  6472. }
  6473.  
  6474. bool IsArray()
  6475. {
  6476. return false;
  6477. }
  6478.  
  6479. int Count()
  6480. {
  6481. return _entries.Count();
  6482. }
  6483.  
  6484. ConfigEntry Get( int i )
  6485. {
  6486. return _entries[i];
  6487. }
  6488.  
  6489. int FindIndex( string name, bool isClass = false )
  6490. {
  6491. for ( int i = 0; i < _entries.Count(); i++ )
  6492. {
  6493. if ( isClass && !_entries[i].IsClass() )
  6494. continue;
  6495.  
  6496. if ( _entries[i]._name == name )
  6497. return i;
  6498. }
  6499.  
  6500. return -1;
  6501. }
  6502.  
  6503. bool Parse( ConfigReader reader, ConfigFile file )
  6504. {
  6505. CF_Log.Error( "Not implemented." );
  6506. return false;
  6507. }
  6508.  
  6509. ConfigEntry Get( string path )
  6510. {
  6511. TStringArray tokens = new TStringArray;
  6512. path.Split( " ", tokens );
  6513. return Get( tokens, 0 );
  6514. }
  6515.  
  6516. ConfigEntry Get( TStringArray tokens, int index = 0 )
  6517. {
  6518. string lowerToken = "" + tokens[ index ];
  6519. lowerToken.ToLower();
  6520. for ( int k = 0; k < _entries.Count(); ++k )
  6521. {
  6522. string nameLower = "" + _entries[k]._name;
  6523. nameLower.ToLower();
  6524.  
  6525. if ( lowerToken == nameLower )
  6526. {
  6527. if ( index + 1 >= tokens.Count() )
  6528. {
  6529. return _entries[k];
  6530. }
  6531.  
  6532. return _entries[k].Get( tokens, index + 1 );
  6533. }
  6534. }
  6535.  
  6536. if ( IsClass() && GetClass().GetBase() != NULL )
  6537. {
  6538. return GetClass().GetBase().Get( tokens, index );
  6539. }
  6540.  
  6541. return NULL;
  6542. }
  6543. };
  6544. class ConfigFile : ConfigClass
  6545. {
  6546. private ref ConfigReader _reader;
  6547.  
  6548. private void ConfigFile()
  6549. {
  6550. }
  6551.  
  6552. override string GetType()
  6553. {
  6554. return "FILE";
  6555. }
  6556.  
  6557. static ConfigFile Parse( string fileName )
  6558. {
  6559. ConfigFile file = new ConfigFile();
  6560.  
  6561. file.Parse( ConfigReader.Open( fileName ), file );
  6562.  
  6563. return file;
  6564. }
  6565. };class ConfigReader : Managed
  6566. {
  6567. private int _arrIdx = 0;
  6568. private int _bufIdx = -1;
  6569.  
  6570. private ref array< string > _lines = new array< string >;
  6571.  
  6572. private void ConfigReader()
  6573. {
  6574. #ifdef CF_TRACE_ENABLED
  6575. auto trace = CF_Trace_0(this);
  6576. #endif
  6577. }
  6578.  
  6579. void ~ConfigReader()
  6580. {
  6581. #ifdef CF_TRACE_ENABLED
  6582. auto trace = CF_Trace_0(this);
  6583. #endif
  6584. }
  6585.  
  6586. static ConfigReader Open( string path )
  6587. {
  6588. ConfigReader reader = new ConfigReader();
  6589.  
  6590. FileHandle fileHandle = OpenFile( path, FileMode.READ );
  6591.  
  6592. string lineContent;
  6593. while ( FGets( fileHandle, lineContent ) >= 0 )
  6594. {
  6595. if ( lineContent.Length() != 0 )
  6596. {
  6597. reader._lines.Insert( lineContent );
  6598. }
  6599. }
  6600.  
  6601. CloseFile( fileHandle );
  6602.  
  6603. return reader;
  6604. }
  6605.  
  6606. string BackChar()
  6607. {
  6608. _bufIdx--;
  6609. if ( _bufIdx < 0 )
  6610. {
  6611. if ( !PreviousLine() )
  6612. {
  6613. return "";
  6614. }
  6615. }
  6616.  
  6617. return _lines[_arrIdx].Substring( _bufIdx, 1 );
  6618. }
  6619.  
  6620. private string ReadChar()
  6621. {
  6622. _bufIdx++;
  6623.  
  6624. if ( _bufIdx >= _lines[_arrIdx].Length() )
  6625. {
  6626. if ( !NextLine() )
  6627. {
  6628. return "";
  6629. }
  6630. }
  6631.  
  6632. return _lines[_arrIdx].Substring( _bufIdx, 1 );
  6633. }
  6634.  
  6635. bool NextLine()
  6636. {
  6637. _bufIdx = 0;
  6638.  
  6639. _arrIdx++;
  6640.  
  6641. while ( _arrIdx < _lines.Count() )
  6642. {
  6643. if ( _lines[_arrIdx].Length() <= 0 )
  6644. _arrIdx++;
  6645. else
  6646. return true;
  6647. }
  6648.  
  6649. return false;
  6650. }
  6651.  
  6652. bool PreviousLine()
  6653. {
  6654. _arrIdx--;
  6655.  
  6656. while ( _arrIdx >= 0 )
  6657. {
  6658. if ( _lines[_arrIdx].Length() <= 0 )
  6659. _arrIdx--;
  6660. else
  6661. {
  6662. _bufIdx = _lines[_arrIdx].Length() - 1;
  6663. return true;
  6664. }
  6665. }
  6666.  
  6667. return false;
  6668. }
  6669.  
  6670. bool EOF()
  6671. {
  6672. return _arrIdx >= _lines.Count() || ( _arrIdx == _lines.Count() - 1 && _bufIdx >= _lines[_arrIdx].Length() );
  6673. }
  6674.  
  6675. private void SkipComment()
  6676. {
  6677. string c = ReadChar();
  6678. while ( true )
  6679. {
  6680. if ( EOF() )
  6681. {
  6682. CF_Log.Error( "Unexpected end of file while parsing XML comment!" );
  6683. break;
  6684. }
  6685.  
  6686. if ( c != "*" )
  6687. {
  6688. c = ReadChar();
  6689. continue;
  6690. }
  6691.  
  6692. BackChar();
  6693.  
  6694. string check = ReadChar();
  6695. if ( check == "/" )
  6696. {
  6697. return;
  6698. } else
  6699. {
  6700. c = ReadChar();
  6701. }
  6702. }
  6703. }
  6704.  
  6705. string GetCharacter()
  6706. {
  6707. string c = ReadChar();
  6708. while ( true )
  6709. {
  6710. if ( c == "/" )
  6711. {
  6712. c = ReadChar();
  6713. if ( c == "/" )
  6714. {
  6715. NextLine();
  6716. } else if ( c == "*" )
  6717. {
  6718. SkipComment();
  6719. } else
  6720. {
  6721. BackChar();
  6722. return c;
  6723. }
  6724. } else
  6725. {
  6726. return c;
  6727. }
  6728.  
  6729. c = ReadChar();
  6730. }
  6731.  
  6732. return c;
  6733. }
  6734.  
  6735. bool IsWhitespace( string c )
  6736. {
  6737. if ( c == " " )
  6738. return true;
  6739. if ( c == "\t" )
  6740. return true;
  6741. if ( c == "\n" )
  6742. return true;
  6743. if ( c == "\r" )
  6744. return true;
  6745.  
  6746. //if ( c == "" )
  6747. // Error( "Unexpected end of string" );
  6748.  
  6749. return false;
  6750. }
  6751.  
  6752. bool IsLetterOrDigit( string c )
  6753. {
  6754. return IsLetterOrDigit( c, false );
  6755. }
  6756.  
  6757. bool IsLetterOrDigit( string c, bool isQuoted )
  6758. {
  6759. int i = _cf_characters.Find( c );
  6760. if ( i == -1 )
  6761. {
  6762. return false;
  6763. }
  6764.  
  6765. if ( isQuoted )
  6766. {
  6767. return i >= 32 && i <= 126;
  6768. }
  6769.  
  6770. if ( i >= 48 && i <= 57 )
  6771. {
  6772. return true;
  6773. }
  6774.  
  6775. if ( i > 90 )
  6776. i -= 32;
  6777.  
  6778. if ( i >= 65 && i <= 90 )
  6779. {
  6780. return true;
  6781. }
  6782.  
  6783. return false;
  6784. }
  6785.  
  6786. string SkipWhitespace()
  6787. {
  6788. string c = GetCharacter();
  6789. while ( IsWhitespace( c ) )
  6790. c = GetCharacter();
  6791.  
  6792. return c;
  6793. }
  6794.  
  6795. string GetWord()
  6796. {
  6797. string word = "";
  6798.  
  6799. string c = SkipWhitespace();
  6800.  
  6801. while ( IsLetterOrDigit( c ) )
  6802. {
  6803. word = word + c;
  6804. c = GetCharacter();
  6805. }
  6806.  
  6807. BackChar();
  6808.  
  6809. return word;
  6810. }
  6811.  
  6812. string GetQuotedWord( out bool isQuoted )
  6813. {
  6814. string word = "";
  6815.  
  6816. string c = SkipWhitespace();
  6817.  
  6818. if ( c == "\"" )
  6819. {
  6820. c = "";
  6821. isQuoted = true;
  6822. } else
  6823. {
  6824. isQuoted = false;
  6825. }
  6826.  
  6827. while ( ( IsLetterOrDigit( c, isQuoted ) || c == "" ) && !EOF() )
  6828. {
  6829. word = word + c;
  6830. c = GetCharacter();
  6831. if ( isQuoted && c == "\"" )
  6832. {
  6833. return word;
  6834. }
  6835. }
  6836.  
  6837. BackChar();
  6838.  
  6839. return word;
  6840. }
  6841.  
  6842. void Error( string msg )
  6843. {
  6844. CF_Log.Error( "[" + ( _arrIdx + 1 ) + ":" + _bufIdx + "] " + msg );
  6845. }
  6846.  
  6847. void Warning( string msg )
  6848. {
  6849. CF_Log.Warn( "[" + ( _arrIdx + 1 ) + ":" + _bufIdx + "] " + msg );
  6850. }
  6851. };class ConfigValue : ConfigEntry
  6852. {
  6853. override string GetType()
  6854. {
  6855. return "VALUE";
  6856. }
  6857.  
  6858. override bool IsValue()
  6859. {
  6860. return true;
  6861. }
  6862. }class ConfigValueFloat : ConfigValue
  6863. {
  6864. private float _value;
  6865.  
  6866. override string GetType()
  6867. {
  6868. return "FLOAT";
  6869. }
  6870.  
  6871. override bool IsFloat()
  6872. {
  6873. return true;
  6874. }
  6875.  
  6876. override float GetFloat()
  6877. {
  6878. return _value;
  6879. }
  6880.  
  6881. override void SetFloat( float value )
  6882. {
  6883. _value = value;
  6884. }
  6885. };class ConfigValueInt : ConfigValue
  6886. {
  6887. private int _value;
  6888.  
  6889. override string GetType()
  6890. {
  6891. return "INT";
  6892. }
  6893.  
  6894. override bool IsInt()
  6895. {
  6896. return true;
  6897. }
  6898.  
  6899. override int GetInt()
  6900. {
  6901. return _value;
  6902. }
  6903.  
  6904. override void SetInt( int value )
  6905. {
  6906. _value = value;
  6907. }
  6908. };class ConfigValueLong : ConfigValue
  6909. {
  6910. private int _value;
  6911.  
  6912. override string GetType()
  6913. {
  6914. return "LONG";
  6915. }
  6916.  
  6917. override bool IsLong()
  6918. {
  6919. return true;
  6920. }
  6921.  
  6922. override int GetLong()
  6923. {
  6924. return _value;
  6925. }
  6926.  
  6927. override void SetLong( int value )
  6928. {
  6929. _value = value;
  6930. }
  6931. };class ConfigValueText : ConfigValue
  6932. {
  6933. private string _value;
  6934.  
  6935. override string GetType()
  6936. {
  6937. return "TEXT";
  6938. }
  6939.  
  6940. override bool IsText()
  6941. {
  6942. return true;
  6943. }
  6944.  
  6945. override string GetText()
  6946. {
  6947. return _value;
  6948. }
  6949.  
  6950. override void SetText( string value )
  6951. {
  6952. _value = value;
  6953. }
  6954. };enum ConfigValueTypes
  6955. {
  6956. Text,
  6957. Float,
  6958. Int,
  6959. Array,
  6960. UKN_1,
  6961. UKN_2,
  6962. Int64
  6963. };/*
  6964. Epoch Mod for DayZ Standalone
  6965.  
  6966. FileName: CreditsLoader.c
  6967.  
  6968. Authors: DayZ SA Epoch Dev Team and Community Contributors
  6969. https://github.com/EpochModTeam/DayZ_SA_Epoch/blob/experimental/README.md
  6970.  
  6971. Licensing:
  6972. https://github.com/EpochModTeam/DayZ_SA_Epoch/blob/experimental/LICENSE.md
  6973.  
  6974. Changelog:
  6975.  
  6976. [1/16/2019] AWOL / DirtySanchez
  6977. AWOL1 - DZSA Epoch Dev Team and Community Credits
  6978. [1/20/2019] AWOL
  6979. AWOL2 - Made credits dynamically support other mods via 'creditsJson' var in CfgMods. Also appended DayZ Game header and credits
  6980. [14/03/2019] Jacob_Mango
  6981. JM3 - Changed the formatting of the credits
  6982.  
  6983. [NewDate] Author(s)
  6984. Initials(Change#)-Description
  6985. */
  6986. modded class CreditsLoader
  6987. {
  6988. override static JsonDataCredits GetData()
  6989. {
  6990. #ifdef CF_TRACE_ENABLED
  6991. auto trace = CF_Trace_0("JsonDataCredits");
  6992. #endif
  6993.  
  6994. JsonDataCredits data = new JsonDataCredits;
  6995. data.Departments = {};
  6996.  
  6997. // get all mods
  6998. array<ref ModStructure> mods = ModLoader.GetMods();
  6999. foreach (auto mod : mods)
  7000. {
  7001. auto credits = mod.GetCredits();
  7002.  
  7003. if (!credits || !credits.Departments)
  7004. continue;
  7005.  
  7006. foreach (auto department : credits.Departments)
  7007. {
  7008. data.Departments.Insert(department);
  7009. }
  7010. }
  7011.  
  7012. // Append DayZ Game Credits Header
  7013. JsonDataCreditsDepartment dayzDepartmentHeader();
  7014. dayzDepartmentHeader.Sections = {};
  7015. dayzDepartmentHeader.DepartmentName = (" DayZ Standalone");
  7016. data.Departments.Insert(dayzDepartmentHeader);
  7017.  
  7018. // Append DayZ Game Credits
  7019. JsonDataCredits dayzCreditsData;
  7020. JsonFileLoader<ref JsonDataCredits>.JsonLoadFile(JSON_FILE_PATH, dayzCreditsData);
  7021. foreach (auto dayzDepartment : dayzCreditsData.Departments)
  7022. {
  7023. data.Departments.Insert(dayzDepartment);
  7024. };
  7025.  
  7026. return data;
  7027. }
  7028. };
  7029. class CF_EventChatArgs : CF_EventArgs
  7030. {
  7031. int Channel;
  7032. string From;
  7033. string Text;
  7034. string ColorConfig;
  7035.  
  7036. void CF_EventChatArgs(int channel, string from, string text, string colorConfig)
  7037. {
  7038. Channel = channel;
  7039. From = from;
  7040. Text = text;
  7041. ColorConfig = colorConfig;
  7042. }
  7043. };
  7044. class CF_EventLoginArgs : CF_EventArgs
  7045. {
  7046. string Line1;
  7047. string Line2;
  7048.  
  7049. void CF_EventLoginArgs(string line1, string line2)
  7050. {
  7051. Line1 = line1;
  7052. Line2 = line2;
  7053. }
  7054. };
  7055. class CF_EventRPCArgs : CF_EventArgs
  7056. {
  7057. PlayerIdentity Sender;
  7058. Object Target;
  7059. int ID;
  7060. Serializer Context;
  7061. };
  7062. class CF_Expression
  7063. {
  7064. protected string m_Source;
  7065. protected int m_Position = -1;
  7066.  
  7067. protected ref CF_ExpressionInstruction m_RootInstruction;
  7068. protected CF_ExpressionInstruction m_TailInstruction;
  7069.  
  7070. void SetSource(string source)
  7071. {
  7072. m_Source = source;
  7073. }
  7074.  
  7075. string GetSource()
  7076. {
  7077. return m_Source;
  7078. }
  7079.  
  7080. protected string BackChar()
  7081. {
  7082. m_Position--;
  7083.  
  7084. if ( m_Position < 0 )
  7085. m_Position = 0;
  7086.  
  7087. return m_Source[m_Position];
  7088. }
  7089.  
  7090. protected string GetChar()
  7091. {
  7092. m_Position++;
  7093.  
  7094. if ( m_Position >= m_Source.Length() )
  7095. m_Position = m_Source.Length();
  7096.  
  7097. return m_Source[m_Position];
  7098. }
  7099.  
  7100. protected bool EOF()
  7101. {
  7102. return m_Position >= m_Source.Length() - 1;
  7103. }
  7104.  
  7105. protected bool IsWhitespace( string c )
  7106. {
  7107. if ( c == " " )
  7108. return true;
  7109. if ( c == "\t" )
  7110. return true;
  7111. if ( c == "\n" )
  7112. return true;
  7113. if ( c == "\r" )
  7114. return true;
  7115.  
  7116. //if ( c == "" )
  7117. // CF_Log.Error( "Unexpected end of string" );
  7118.  
  7119. return false;
  7120. }
  7121.  
  7122. protected bool IsAlphanumeric( string c )
  7123. {
  7124. int i = c.ToAscii();
  7125.  
  7126. if (i >= 42 && i <= 57)
  7127. return true;
  7128.  
  7129. if ( i > 90 )
  7130. i -= 32;
  7131.  
  7132. if ( i >= 65 && i <= 90 )
  7133. return true;
  7134.  
  7135. return false;
  7136. }
  7137.  
  7138. protected bool IsLetterOrDigit( string c )
  7139. {
  7140. int i = c.ToAscii();
  7141.  
  7142. if ( i >= 48 && i <= 57 )
  7143. return true;
  7144.  
  7145. if ( i == 46 )
  7146. return true;
  7147.  
  7148. if ( i > 90 )
  7149. i -= 32;
  7150.  
  7151. if ( i >= 65 && i <= 90 )
  7152. return true;
  7153.  
  7154. return false;
  7155. }
  7156.  
  7157. protected string SkipWhitespace()
  7158. {
  7159. if ( EOF() )
  7160. return "\0";
  7161.  
  7162. string c = GetChar();
  7163. while ( IsWhitespace( c ) && !EOF() )
  7164. c = GetChar();
  7165.  
  7166. return c;
  7167. }
  7168.  
  7169. protected string GetToken()
  7170. {
  7171. string word = "";
  7172.  
  7173. string c = SkipWhitespace();
  7174.  
  7175. if ( c == "[" || c == "]" || c == "(" || c == ")" )
  7176. return c;
  7177.  
  7178. if ( IsAlphanumeric( c ) && !IsLetterOrDigit( c ) )
  7179. return c;
  7180.  
  7181. while ( IsLetterOrDigit( c ) )
  7182. {
  7183. word = word + c;
  7184. if ( EOF() )
  7185. return word;
  7186.  
  7187. c = GetChar();
  7188.  
  7189. if ( c == "[" || c == "]" || c == "(" || c == ")" || word == "/" || word == "*" )
  7190. break;
  7191. }
  7192.  
  7193. m_Position--;
  7194.  
  7195. return word;
  7196. }
  7197.  
  7198. protected bool IsNumber( string word )
  7199. {
  7200. bool decimal = false;
  7201.  
  7202. for ( int i = 0; i < word.Length(); i++ )
  7203. {
  7204. int c = word.Get(i).ToAscii();
  7205. if ( c == 46 )
  7206. {
  7207. if ( decimal )
  7208. return false;
  7209.  
  7210. decimal = true;
  7211. }
  7212. else if ( !( c >= 48 && c <= 57 ) )
  7213. {
  7214. return false;
  7215. }
  7216. }
  7217.  
  7218. return true;
  7219. }
  7220.  
  7221. float CompileEvaluate( map< string, float > variables )
  7222. {
  7223. if ( Compile( variables.GetKeyArray() ) )
  7224. return Evaluate( variables.GetValueArray() );
  7225.  
  7226. return 0;
  7227. }
  7228.  
  7229. /**
  7230. * @note Test function
  7231. */
  7232. float CompileEvaluateTest( map< string, float > variables, bool test )
  7233. {
  7234. if ( CompileTest( variables.GetKeyArray(), test ) )
  7235. return EvaluateTest( variables.GetValueArray(), test );
  7236.  
  7237. return 0;
  7238. }
  7239.  
  7240. bool Compile( array< string > variables )
  7241. {
  7242. _Compile( variables );
  7243.  
  7244. return true;
  7245. }
  7246.  
  7247. /**
  7248. * @note Test function
  7249. */
  7250. bool CompileTest( array< string > variables, bool test )
  7251. {
  7252. int start = TickCount( 0 );
  7253.  
  7254. bool success = Compile( variables );
  7255.  
  7256. int time = TickCount( start );
  7257. if ( test )
  7258. CF_Log.Info( "CF_Expression::Compile took " + time + " ticks to execute." );
  7259.  
  7260. return success;
  7261. }
  7262.  
  7263. float Evaluate( array< float > variables )
  7264. {
  7265. //! Make sure the evaluation position is set at the start
  7266. m_Position = -1;
  7267.  
  7268. return _Evaluate( variables );
  7269. }
  7270.  
  7271. float Evaluate()
  7272. {
  7273. //! Make sure the evaluation position is set at the start
  7274. m_Position = -1;
  7275.  
  7276. return _Evaluate(new array<float>());
  7277. }
  7278.  
  7279. /**
  7280. * @note Test function
  7281. */
  7282. float EvaluateTest( array< float > variables, bool test )
  7283. {
  7284. int start = TickCount( 0 );
  7285.  
  7286. m_Position = -1;
  7287. float num = _Evaluate( variables );
  7288.  
  7289. int time = TickCount( start );
  7290. if ( test )
  7291. CF_Log.Info( "CF_Expression::Evaluate took " + time + " ticks to execute." );
  7292.  
  7293. return num;
  7294. }
  7295.  
  7296. protected float _Evaluate( array< float > variables )
  7297. {
  7298. CF_ExpressionVM.StackPointer = 0;
  7299. CF_ExpressionVM.Variables = variables;
  7300.  
  7301. CF_ExpressionVM.CurrentInstruction = m_RootInstruction;
  7302.  
  7303. while (CF_ExpressionVM.CurrentInstruction)
  7304. {
  7305. CF_ExpressionVM.CurrentInstruction.Call();
  7306. CF_ExpressionVM.CurrentInstruction = CF_ExpressionVM.CurrentInstruction.next;
  7307. }
  7308.  
  7309. return CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer];
  7310. }
  7311.  
  7312. protected void ClearInstructions()
  7313. {
  7314. m_RootInstruction = null;
  7315. }
  7316.  
  7317. protected void AddInstruction(CF_ExpressionInstruction instruction)
  7318. {
  7319. if (!m_RootInstruction)
  7320. {
  7321. m_RootInstruction = instruction;
  7322. m_TailInstruction = instruction;
  7323. return;
  7324. }
  7325.  
  7326. m_TailInstruction.next = instruction;
  7327. m_TailInstruction = instruction;
  7328. }
  7329.  
  7330. protected int _Compile( array< string > variables )
  7331. {
  7332. return 0;
  7333. }
  7334.  
  7335. string ToRPN()
  7336. {
  7337. return _ToRPN();
  7338. }
  7339.  
  7340. /**
  7341. * @note Test function
  7342. */
  7343. string ToRPN( bool test )
  7344. {
  7345. int start = TickCount( 0 );
  7346.  
  7347. string rpn = _ToRPN();
  7348.  
  7349. int time = TickCount( start );
  7350. CF_Log.Info( "CF_Expression::ToRPN took " + time + " ticks to execute." );
  7351.  
  7352. return rpn;
  7353. }
  7354.  
  7355. /**
  7356. * @brief Converts the compiled expression into Reverse Polish Notation
  7357. *
  7358. * @return string
  7359. */
  7360. private string _ToRPN()
  7361. {
  7362. string rpn = string.Empty;
  7363.  
  7364. if (!m_RootInstruction)
  7365. return "0"; //! edge case because I managed to accidentally optimize this out
  7366.  
  7367. CF_ExpressionInstruction instruction = m_RootInstruction;
  7368. bool first = true;
  7369. while (instruction)
  7370. {
  7371. if (!first) rpn = rpn + " ";
  7372.  
  7373. first = false;
  7374.  
  7375. rpn = rpn + instruction.GetDebugName();
  7376.  
  7377. CF_ExpressionFunctionDef function;
  7378. if (CF_ExpressionVM.Find(instruction.GetDebugName(), function))
  7379. {
  7380. //! instruction doesn't store parameters in an array for memory reasons
  7381. if ( function.params != 0 )
  7382. {
  7383. rpn = rpn + " [";
  7384.  
  7385. if ( function.params >= 4 )
  7386. {
  7387. rpn = rpn + instruction.param1;
  7388. rpn = rpn + ", ";
  7389. rpn = rpn + instruction.param2;
  7390. rpn = rpn + ", ";
  7391. rpn = rpn + instruction.param3;
  7392. rpn = rpn + ", ";
  7393. rpn = rpn + instruction.param4;
  7394. } else if ( function.params >= 3 )
  7395. {
  7396. rpn = rpn + instruction.param1;
  7397. rpn = rpn + ", ";
  7398. rpn = rpn + instruction.param2;
  7399. rpn = rpn + ", ";
  7400. rpn = rpn + instruction.param3;
  7401. } else if ( function.params >= 2 )
  7402. {
  7403. rpn = rpn + instruction.param1;
  7404. rpn = rpn + ", ";
  7405. rpn = rpn + instruction.param2;
  7406. } else if ( function.params >= 1 )
  7407. {
  7408. rpn = rpn + instruction.param1;
  7409. }
  7410.  
  7411. rpn = rpn + "]";
  7412. }
  7413. }
  7414.  
  7415. instruction = instruction.next;
  7416. }
  7417.  
  7418. return rpn;
  7419. }
  7420. };
  7421. /*
  7422. * Private class
  7423. */
  7424. class CF_ExpressionCompileToken
  7425. {
  7426. string token;
  7427. ref array< float > parameters;
  7428.  
  7429. void CF_ExpressionCompileToken( string _token )
  7430. {
  7431. token = _token;
  7432. parameters = new array< float >();
  7433. }
  7434.  
  7435. CF_ExpressionInstruction ToOperation(CF_ExpressionFunctionDef funcDef, int variableIdx = -1)
  7436. {
  7437. CF_ExpressionInstruction instruction;
  7438. if (funcDef)
  7439. {
  7440. instruction = funcDef.SpawnFunction();
  7441. }
  7442. else
  7443. {
  7444. instruction = new CF_ExpressionInstruction();
  7445. }
  7446.  
  7447. instruction.SetFields(token, parameters, variableIdx);
  7448.  
  7449. return instruction;
  7450. }
  7451. };
  7452. class CF_ExpressionFunction : CF_ExpressionInstruction
  7453. {
  7454. };
  7455.  
  7456. class CF_ExpressionFunctionDef
  7457. {
  7458. int params = 0;
  7459. int precedence = 1;
  7460. bool associative = true;
  7461. typename type = CF_ExpressionFunction;
  7462.  
  7463. void CF_ExpressionFunctionDef(typename _type, int _params = 0, int _precedence = 1, bool _associative = true)
  7464. {
  7465. params = _params;
  7466. precedence = _precedence;
  7467. associative = _associative;
  7468. type = _type;
  7469. }
  7470.  
  7471. CF_ExpressionFunction SpawnFunction()
  7472. {
  7473. return CF_ExpressionFunction.Cast(type.Spawn());
  7474. }
  7475. };
  7476.  
  7477. class CF_ExpressionFunctionValue : CF_ExpressionFunction
  7478. {
  7479. static string CF_NAME = "#INTERNAL_0";
  7480.  
  7481. [CF_EventSubscriber(ScriptCaller.Create(CF_ExpressionFunctionValue.Init), CF_LifecycleEvents.OnGameCreate)]
  7482. static void Init()
  7483. {
  7484. CF_ExpressionVM.AddFunction(CF_NAME, new CF_ExpressionFunctionDef(CF_ExpressionFunctionValue, -1));
  7485. }
  7486.  
  7487. override void Call()
  7488. {
  7489. CF_ExpressionVM.Stack[++CF_ExpressionVM.StackPointer] = value;
  7490. }
  7491.  
  7492. override string GetDebugName()
  7493. {
  7494. return "" + value;
  7495. }
  7496. };
  7497.  
  7498. class CF_ExpressionFunctionVariable : CF_ExpressionFunction
  7499. {
  7500. static string CF_NAME = "#INTERNAL_1";
  7501.  
  7502. [CF_EventSubscriber(ScriptCaller.Create(CF_ExpressionFunctionVariable.Init), CF_LifecycleEvents.OnGameCreate)]
  7503. static void Init()
  7504. {
  7505. CF_ExpressionVM.AddFunction(CF_NAME, new CF_ExpressionFunctionDef(CF_ExpressionFunctionVariable, -1));
  7506. }
  7507.  
  7508. override void Call()
  7509. {
  7510. CF_ExpressionVM.Stack[++CF_ExpressionVM.StackPointer] = CF_ExpressionVM.Variables[variableIndex];
  7511. }
  7512.  
  7513. override string GetDebugName()
  7514. {
  7515. return token;
  7516. }
  7517. };
  7518.  
  7519. class CF_ExpressionFunctionPow : CF_ExpressionFunction
  7520. {
  7521. static string CF_NAME = "^";
  7522.  
  7523. [CF_EventSubscriber(ScriptCaller.Create(CF_ExpressionFunctionPow.Init), CF_LifecycleEvents.OnGameCreate)]
  7524. static void Init()
  7525. {
  7526. CF_ExpressionVM.AddFunction(CF_NAME, new CF_ExpressionFunctionDef(CF_ExpressionFunctionPow, 0, 4, false));
  7527. }
  7528.  
  7529. override void Call()
  7530. {
  7531. CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer] = Math.Pow(CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer--], CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer]);
  7532. }
  7533.  
  7534. override string GetDebugName()
  7535. {
  7536. return CF_NAME;
  7537. }
  7538. };
  7539.  
  7540. class CF_ExpressionFunctionMul : CF_ExpressionFunction
  7541. {
  7542. static string CF_NAME = "*";
  7543.  
  7544. [CF_EventSubscriber(ScriptCaller.Create(CF_ExpressionFunctionMul.Init), CF_LifecycleEvents.OnGameCreate)]
  7545. static void Init()
  7546. {
  7547. CF_ExpressionVM.AddFunction(CF_NAME, new CF_ExpressionFunctionDef(CF_ExpressionFunctionMul, 0, 3, true));
  7548. }
  7549.  
  7550. override void Call()
  7551. {
  7552. CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer] = CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer--] * CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer];
  7553. }
  7554.  
  7555. override string GetDebugName()
  7556. {
  7557. return CF_NAME;
  7558. }
  7559. };
  7560.  
  7561. class CF_ExpressionFunctionDiv : CF_ExpressionFunction
  7562. {
  7563. static string CF_NAME = "/";
  7564.  
  7565. [CF_EventSubscriber(ScriptCaller.Create(CF_ExpressionFunctionDiv.Init), CF_LifecycleEvents.OnGameCreate)]
  7566. static void Init()
  7567. {
  7568. CF_ExpressionVM.AddFunction(CF_NAME, new CF_ExpressionFunctionDef(CF_ExpressionFunctionDiv, 0, 3, true));
  7569. }
  7570.  
  7571. override void Call()
  7572. {
  7573. CF_ExpressionVM.StackPointer--;
  7574. CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer] = CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer] / CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer + 1];
  7575. }
  7576.  
  7577. override string GetDebugName()
  7578. {
  7579. return CF_NAME;
  7580. }
  7581. };
  7582.  
  7583. class CF_ExpressionFunctionAdd : CF_ExpressionFunction
  7584. {
  7585. static string CF_NAME = "+";
  7586.  
  7587. [CF_EventSubscriber(ScriptCaller.Create(CF_ExpressionFunctionAdd.Init), CF_LifecycleEvents.OnGameCreate)]
  7588. static void Init()
  7589. {
  7590. CF_ExpressionVM.AddFunction(CF_NAME, new CF_ExpressionFunctionDef(CF_ExpressionFunctionAdd, 0, 2, true));
  7591. }
  7592.  
  7593. override void Call()
  7594. {
  7595. CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer] = CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer--] + CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer];
  7596. }
  7597.  
  7598. override string GetDebugName()
  7599. {
  7600. return CF_NAME;
  7601. }
  7602. };
  7603.  
  7604. class CF_ExpressionFunctionSub : CF_ExpressionFunction
  7605. {
  7606. static string CF_NAME = "-";
  7607.  
  7608. [CF_EventSubscriber(ScriptCaller.Create(CF_ExpressionFunctionSub.Init), CF_LifecycleEvents.OnGameCreate)]
  7609. static void Init()
  7610. {
  7611. CF_ExpressionVM.AddFunction(CF_NAME, new CF_ExpressionFunctionDef(CF_ExpressionFunctionSub, 0, 2, true));
  7612. }
  7613.  
  7614. override void Call()
  7615. {
  7616. CF_ExpressionVM.StackPointer--;
  7617. CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer] = CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer] - CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer + 1];
  7618. }
  7619.  
  7620. override string GetDebugName()
  7621. {
  7622. return CF_NAME;
  7623. }
  7624. };
  7625.  
  7626. class CF_ExpressionFunctionFactor : CF_ExpressionFunction
  7627. {
  7628. static string CF_NAME = "factor";
  7629.  
  7630. [CF_EventSubscriber(ScriptCaller.Create(CF_ExpressionFunctionFactor.Init), CF_LifecycleEvents.OnGameCreate)]
  7631. static void Init()
  7632. {
  7633. CF_ExpressionVM.AddFunction(CF_NAME, new CF_ExpressionFunctionDef(CF_ExpressionFunctionFactor, 2));
  7634. }
  7635.  
  7636. override void Call()
  7637. {
  7638. CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer] = (Math.Clamp(CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer], param1, param2) - param1) / (param2 - param1);
  7639. }
  7640.  
  7641. override string GetDebugName()
  7642. {
  7643. return CF_NAME;
  7644. }
  7645. };
  7646.  
  7647. class CF_ExpressionFunctionReverseFactor : CF_ExpressionFunction
  7648. {
  7649. static string CF_NAME = "#factor_reverse";
  7650.  
  7651. [CF_EventSubscriber(ScriptCaller.Create(CF_ExpressionFunctionReverseFactor.Init), CF_LifecycleEvents.OnGameCreate)]
  7652. static void Init()
  7653. {
  7654. CF_ExpressionVM.AddFunction(CF_NAME, new CF_ExpressionFunctionDef(CF_ExpressionFunctionReverseFactor, 2));
  7655. }
  7656.  
  7657. override void Call()
  7658. {
  7659. CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer] = 1.0 - (Math.Clamp(CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer], param2, param1) - param2) / (param1 - param2);
  7660. }
  7661.  
  7662. override string GetDebugName()
  7663. {
  7664. return CF_NAME;
  7665. }
  7666. };
  7667.  
  7668. class CF_ExpressionFunctionCos : CF_ExpressionFunction
  7669. {
  7670. static string CF_NAME = "cos";
  7671.  
  7672. [CF_EventSubscriber(ScriptCaller.Create(CF_ExpressionFunctionCos.Init), CF_LifecycleEvents.OnGameCreate)]
  7673. static void Init()
  7674. {
  7675. CF_ExpressionVM.AddFunction(CF_NAME, new CF_ExpressionFunctionDef(CF_ExpressionFunctionCos));
  7676. }
  7677.  
  7678. override void Call()
  7679. {
  7680. CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer] = Math.Cos(CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer]);
  7681. }
  7682.  
  7683. override string GetDebugName()
  7684. {
  7685. return CF_NAME;
  7686. }
  7687. };
  7688.  
  7689. class CF_ExpressionFunctionSin : CF_ExpressionFunction
  7690. {
  7691. static string CF_NAME = "sin";
  7692.  
  7693. [CF_EventSubscriber(ScriptCaller.Create(CF_ExpressionFunctionSin.Init), CF_LifecycleEvents.OnGameCreate)]
  7694. static void Init()
  7695. {
  7696. CF_ExpressionVM.AddFunction(CF_NAME, new CF_ExpressionFunctionDef(CF_ExpressionFunctionSin));
  7697. }
  7698.  
  7699. override void Call()
  7700. {
  7701. CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer] = Math.Sin(CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer]);
  7702. }
  7703.  
  7704. override string GetDebugName()
  7705. {
  7706. return CF_NAME;
  7707. }
  7708. };
  7709.  
  7710. class CF_ExpressionFunctionMin : CF_ExpressionFunction
  7711. {
  7712. static string CF_NAME = "min";
  7713.  
  7714. [CF_EventSubscriber(ScriptCaller.Create(CF_ExpressionFunctionMin.Init), CF_LifecycleEvents.OnGameCreate)]
  7715. static void Init()
  7716. {
  7717. CF_ExpressionVM.AddFunction(CF_NAME, new CF_ExpressionFunctionDef(CF_ExpressionFunctionMin));
  7718. }
  7719.  
  7720. override void Call()
  7721. {
  7722. CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer] = Math.Min(CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer--], CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer]);
  7723. }
  7724.  
  7725. override string GetDebugName()
  7726. {
  7727. return CF_NAME;
  7728. }
  7729. };
  7730.  
  7731. class CF_ExpressionFunctionMax : CF_ExpressionFunction
  7732. {
  7733. static string CF_NAME = "max";
  7734.  
  7735. [CF_EventSubscriber(ScriptCaller.Create(CF_ExpressionFunctionMax.Init), CF_LifecycleEvents.OnGameCreate)]
  7736. static void Init()
  7737. {
  7738. CF_ExpressionVM.AddFunction(CF_NAME, new CF_ExpressionFunctionDef(CF_ExpressionFunctionMax));
  7739. }
  7740.  
  7741. override void Call()
  7742. {
  7743. CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer] = Math.Max(CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer--], CF_ExpressionVM.Stack[CF_ExpressionVM.StackPointer]);
  7744. }
  7745.  
  7746. override string GetDebugName()
  7747. {
  7748. return CF_NAME;
  7749. }
  7750. };
  7751. /*
  7752. * Private class
  7753. */
  7754. class CF_ExpressionInstruction
  7755. {
  7756. string token;
  7757. float value;
  7758.  
  7759. int variableIndex;
  7760.  
  7761. ref CF_ExpressionInstruction next;
  7762.  
  7763. float param1;
  7764. float param2;
  7765. float param3;
  7766. float param4;
  7767.  
  7768. void SetFields(string _token, array< float > _parameters, int _variableIndex)
  7769. {
  7770. token = _token;
  7771. if (_variableIndex == -2) value = _token.ToFloat();
  7772. variableIndex = _variableIndex;
  7773.  
  7774. //! Setting the variables
  7775. //! This looks bad but the code runs a couple of CPU ticks faster with it like this
  7776. //! For code that is expected to run 1000 times a frame this is important
  7777. if ( _parameters )
  7778. {
  7779. if ( _parameters.Count() >= 4 )
  7780. {
  7781. param1 = _parameters[0];
  7782. param2 = _parameters[1];
  7783. param3 = _parameters[2];
  7784. param4 = _parameters[3];
  7785. } else if ( _parameters.Count() >= 3 )
  7786. {
  7787. param1 = _parameters[0];
  7788. param2 = _parameters[1];
  7789. param3 = _parameters[2];
  7790. } else if ( _parameters.Count() >= 2 )
  7791. {
  7792. param1 = _parameters[0];
  7793. param2 = _parameters[1];
  7794. } else if ( _parameters.Count() >= 1 )
  7795. {
  7796. param1 = _parameters[0];
  7797. }
  7798. }
  7799. }
  7800.  
  7801. void Call();
  7802.  
  7803. override string GetDebugName()
  7804. {
  7805. return ToString();
  7806. }
  7807. };
  7808. class CF_ExpressionStackDebug
  7809. {
  7810. float Get(int index)
  7811. {
  7812. CF_Log.Info("[" + index + "]: " + CF_ExpressionVM.Stack[index] + "");
  7813. return CF_ExpressionVM.Stack[index];
  7814. }
  7815.  
  7816. void Set(int index, float value)
  7817. {
  7818. CF_Log.Info("[" + index + "]: " + CF_ExpressionVM.Stack[index] + " -> " + value + "");
  7819. CF_ExpressionVM.Stack[index] = value;
  7820. }
  7821. };
  7822. #ifdef CF_EXPRESSION_TEST
  7823. class CF_ExpressionTests
  7824. {
  7825. private string _current;
  7826. private int _cpu;
  7827. private int _failed;
  7828.  
  7829. private void CF_ExpressionTests()
  7830. {
  7831. }
  7832.  
  7833. static void Perform()
  7834. {
  7835. CF_ExpressionTests tests = new CF_ExpressionTests();
  7836. tests._Perform();
  7837. }
  7838.  
  7839. static void PerformSingle( string test )
  7840. {
  7841. CF_ExpressionTests tests = new CF_ExpressionTests();
  7842. tests.PerformTest( test );
  7843. }
  7844.  
  7845. protected void Setup( inout array< string > tests )
  7846. {
  7847. tests.Insert("TestMultiplication_SQF_1");
  7848. tests.Insert("TestDivision_SQF_1");
  7849. tests.Insert("TestAddition_SQF_1");
  7850. tests.Insert("TestSubtraction_SQF_1");
  7851.  
  7852. tests.Insert("TestMultiplication_Math_1");
  7853. tests.Insert("TestDivision_Math_1");
  7854. tests.Insert("TestAddition_Math_1");
  7855. tests.Insert("TestSubtraction_Math_1");
  7856.  
  7857. tests.Insert("TestVariable_SQF_1");
  7858.  
  7859. tests.Insert("TestVariable_Math_1");
  7860.  
  7861. tests.Insert("TestFunction_SQF_1");
  7862. tests.Insert("TestFunction_SQF_2");
  7863.  
  7864. tests.Insert("TestFunction_Math_1");
  7865. tests.Insert("TestFunction_Math_1");
  7866.  
  7867. tests.Insert("TestBrackets_SQF_1");
  7868.  
  7869. tests.Insert("TestBrackets_Math_2");
  7870.  
  7871. tests.Insert("TestOrderOfOperations_SQF_1");
  7872. tests.Insert("TestOrderOfOperations_SQF_2");
  7873. tests.Insert("TestOrderOfOperations_Math_1");
  7874. tests.Insert("TestOrderOfOperations_Math_2");
  7875.  
  7876. tests.Insert("TestSound_SQF_1");
  7877. tests.Insert("TestSound_SQF_2");
  7878.  
  7879. tests.Insert("TestSound_Math_1");
  7880. tests.Insert("TestSound_Math_2");
  7881. }
  7882.  
  7883. private void _Perform()
  7884. {
  7885. Print( "Starting tests" );
  7886.  
  7887. array< string > tests = new array< string >();
  7888. Setup( tests );
  7889.  
  7890. _failed = 0;
  7891.  
  7892. int start = TickCount( 0 );
  7893.  
  7894. for ( int i = 0; i < tests.Count(); i++ )
  7895. PerformTest( tests[i] );
  7896.  
  7897. int time = TickCount( start );
  7898.  
  7899. Print("\n");
  7900.  
  7901. if ( _failed == 0 )
  7902. {
  7903. Print( "Success. All " + tests.Count() + " passed!" );
  7904. } else
  7905. {
  7906. Print( "Tests failed. " + ( tests.Count() - _failed ) + "/" + tests.Count() + " passed." );
  7907. }
  7908. }
  7909.  
  7910. private void PerformTest( string method )
  7911. {
  7912. Print("\n");
  7913. Print("Running test \"" + method + "\"");
  7914.  
  7915. _current = method;
  7916.  
  7917. _cpu = TickCount( 0 );
  7918.  
  7919. GetGame().GameScript.CallFunction( this, _current, null, null );
  7920. }
  7921.  
  7922. private void _assert( float expectedNum, float actualNum, string expectedRPN, string actualRPN )
  7923. {
  7924. int time = TickCount( _cpu );
  7925. string info = "Test \"" + _current + "\" took " + time + " ticks to execute.";
  7926.  
  7927. if ( expectedNum != actualNum || expectedRPN != actualRPN )
  7928. {
  7929. Print( " Expected Result: " + expectedNum );
  7930. Print( " Actual Result: " + actualNum );
  7931.  
  7932. Print( " Expected RPN: " + expectedRPN );
  7933. Print( " Actual RPN: " + actualRPN );
  7934.  
  7935. info = "FAILED: " + info;
  7936.  
  7937. _failed++;
  7938. } else
  7939. {
  7940. Print( " Result: " + actualNum );
  7941. Print( " RPN: " + actualRPN );
  7942.  
  7943. info = "PASSED: " + info;
  7944. }
  7945.  
  7946. Print( "" + info );
  7947. Print( "" );
  7948. }
  7949.  
  7950. void TestMultiplication_SQF_1()
  7951. {
  7952. map< string, float > variables = new map< string, float >();
  7953.  
  7954. string expr = "5 * 5";
  7955. CF_Expression test = CF_ExpressionVM.Create(expr, CF_SQFExpression);
  7956.  
  7957. float expectedNum = 5 * 5;
  7958. float actualNum = test.CompileEvaluateTest(variables, true);
  7959.  
  7960. string expectedRPN = "5 5 *";
  7961. string actualRPN = test.ToRPN(true);
  7962.  
  7963. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  7964. }
  7965.  
  7966. void TestDivision_SQF_1()
  7967. {
  7968. map< string, float > variables = new map< string, float >();
  7969.  
  7970. string expr = "5 / 2";
  7971. CF_Expression test = CF_ExpressionVM.Create(expr, CF_SQFExpression);
  7972.  
  7973. float expectedNum = 5 / 2;
  7974. float actualNum = test.CompileEvaluateTest(variables, true);
  7975.  
  7976. string expectedRPN = "5 2 /";
  7977. string actualRPN = test.ToRPN(true);
  7978.  
  7979. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  7980. }
  7981.  
  7982. void TestAddition_SQF_1()
  7983. {
  7984. map< string, float > variables = new map< string, float >();
  7985.  
  7986. string expr = "5 + 2";
  7987. CF_Expression test = CF_ExpressionVM.Create(expr, CF_SQFExpression);
  7988.  
  7989. float expectedNum = 5 + 2;
  7990. float actualNum = test.CompileEvaluateTest(variables, true);
  7991.  
  7992. string expectedRPN = "5 2 +";
  7993. string actualRPN = test.ToRPN(true);
  7994.  
  7995. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  7996. }
  7997.  
  7998. void TestSubtraction_SQF_1()
  7999. {
  8000. map< string, float > variables = new map< string, float >();
  8001.  
  8002. string expr = "5 - 2";
  8003. CF_Expression test = CF_ExpressionVM.Create(expr, CF_SQFExpression);
  8004.  
  8005. float expectedNum = 5 - 2;
  8006. float actualNum = test.CompileEvaluateTest(variables, true);
  8007.  
  8008. string expectedRPN = "5 2 -";
  8009. string actualRPN = test.ToRPN(true);
  8010.  
  8011. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8012. }
  8013.  
  8014. void TestMultiplication_Math_1()
  8015. {
  8016. map< string, float > variables = new map< string, float >();
  8017.  
  8018. string expr = "5 * 5";
  8019. CF_Expression test = CF_ExpressionVM.Create(expr, CF_MathExpression);
  8020.  
  8021. float expectedNum = 5 * 5;
  8022. float actualNum = test.CompileEvaluateTest(variables, true);
  8023.  
  8024. string expectedRPN = "5 5 *";
  8025. string actualRPN = test.ToRPN(true);
  8026.  
  8027. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8028. }
  8029.  
  8030. void TestDivision_Math_1()
  8031. {
  8032. map< string, float > variables = new map< string, float >();
  8033.  
  8034. string expr = "5 / 2";
  8035. CF_Expression test = CF_ExpressionVM.Create(expr, CF_MathExpression);
  8036.  
  8037. float expectedNum = 5 / 2;
  8038. float actualNum = test.CompileEvaluateTest(variables, true);
  8039.  
  8040. string expectedRPN = "5 2 /";
  8041. string actualRPN = test.ToRPN(true);
  8042.  
  8043. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8044. }
  8045.  
  8046. void TestAddition_Math_1()
  8047. {
  8048. map< string, float > variables = new map< string, float >();
  8049.  
  8050. string expr = "5 + 2";
  8051. CF_Expression test = CF_ExpressionVM.Create(expr, CF_MathExpression);
  8052.  
  8053. float expectedNum = 5 + 2;
  8054. float actualNum = test.CompileEvaluateTest(variables, true);
  8055.  
  8056. string expectedRPN = "5 2 +";
  8057. string actualRPN = test.ToRPN(true);
  8058.  
  8059. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8060. }
  8061.  
  8062. void TestSubtraction_Math_1()
  8063. {
  8064. map< string, float > variables = new map< string, float >();
  8065.  
  8066. string expr = "5 - 2";
  8067. CF_Expression test = CF_ExpressionVM.Create(expr, CF_MathExpression);
  8068.  
  8069. float expectedNum = 5 - 2;
  8070. float actualNum = test.CompileEvaluateTest(variables, true);
  8071.  
  8072. string expectedRPN = "5 2 -";
  8073. string actualRPN = test.ToRPN(true);
  8074.  
  8075. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8076. }
  8077.  
  8078. void TestVariable_SQF_1()
  8079. {
  8080. map< string, float > variables = new map< string, float >();
  8081. variables["speed"] = 45;
  8082.  
  8083. string expr = "speed * 2";
  8084. CF_Expression test = CF_ExpressionVM.Create(expr, CF_SQFExpression);
  8085.  
  8086. float expectedNum = variables["speed"] * 2;
  8087. float actualNum = test.CompileEvaluateTest(variables, true);
  8088.  
  8089. string expectedRPN = "speed 2 *";
  8090. string actualRPN = test.ToRPN(true);
  8091.  
  8092. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8093. }
  8094.  
  8095. void TestVariable_Math_1()
  8096. {
  8097. map< string, float > variables = new map< string, float >();
  8098. variables["speed"] = 45;
  8099.  
  8100. string expr = "speed * 2";
  8101. CF_Expression test = CF_ExpressionVM.Create(expr, CF_MathExpression);
  8102.  
  8103. float expectedNum = variables["speed"] * 2;
  8104. float actualNum = test.CompileEvaluateTest(variables, true);
  8105.  
  8106. string expectedRPN = "speed 2 *";
  8107. string actualRPN = test.ToRPN(true);
  8108.  
  8109. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8110. }
  8111.  
  8112. void TestFunction_SQF_1()
  8113. {
  8114. map< string, float > variables = new map< string, float >();
  8115.  
  8116. string expr = "4 factor [0, 5]";
  8117. CF_Expression test = CF_ExpressionVM.Create(expr, CF_SQFExpression);
  8118.  
  8119. float expectedNum = Math.Interpolate(4, 0, 5, 0, 1);
  8120. float actualNum = test.CompileEvaluateTest(variables, true);
  8121.  
  8122. string expectedRPN = "4 factor [0, 5]";
  8123. string actualRPN = test.ToRPN(true);
  8124.  
  8125. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8126. }
  8127.  
  8128. void TestFunction_SQF_2()
  8129. {
  8130. map< string, float > variables = new map< string, float >();
  8131. variables["angle"] = 45;
  8132. variables["pi"] = Math.PI;
  8133. variables["toRad"] = Math.DEG2RAD;
  8134. variables["toDeg"] = Math.RAD2DEG;
  8135.  
  8136. string expr = "(angle * toRad) cos";
  8137. CF_Expression test = CF_ExpressionVM.Create(expr, CF_SQFExpression);
  8138.  
  8139. float expectedNum = Math.Cos(variables["angle"] * Math.DEG2RAD);
  8140. float actualNum = test.CompileEvaluateTest(variables, true);
  8141.  
  8142. string expectedRPN = "angle toRad * cos";
  8143. string actualRPN = test.ToRPN(true);
  8144.  
  8145. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8146. }
  8147.  
  8148. void TestFunction_Math_1()
  8149. {
  8150. map< string, float > variables = new map< string, float >();
  8151.  
  8152. string expr = "factor(4, 0, 5)";
  8153. CF_Expression test = CF_ExpressionVM.Create(expr, CF_MathExpression);
  8154.  
  8155. float expectedNum = Math.Interpolate(4, 0, 5, 0, 1);
  8156. float actualNum = test.CompileEvaluateTest(variables, true);
  8157.  
  8158. string expectedRPN = "4 factor [0, 5]";
  8159. string actualRPN = test.ToRPN(true);
  8160.  
  8161. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8162. }
  8163.  
  8164. void TestFunction_Math_2()
  8165. {
  8166. map< string, float > variables = new map< string, float >();
  8167. variables["angle"] = 45;
  8168. variables["pi"] = Math.PI;
  8169. variables["toRad"] = Math.DEG2RAD;
  8170. variables["toDeg"] = Math.RAD2DEG;
  8171.  
  8172. string expr = "cos(angle * toRad)";
  8173. CF_Expression test = CF_ExpressionVM.Create(expr, CF_MathExpression);
  8174.  
  8175. float expectedNum = Math.Cos(variables["angle"] * Math.DEG2RAD);
  8176. float actualNum = test.CompileEvaluateTest(variables, true);
  8177.  
  8178. string expectedRPN = "angle toRad * cos";
  8179. string actualRPN = test.ToRPN(true);
  8180.  
  8181. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8182. }
  8183.  
  8184. void TestBrackets_SQF_1()
  8185. {
  8186. map< string, float > variables = new map< string, float >();
  8187.  
  8188. string expr = "3 * (4 - 2) * 2";
  8189. CF_Expression test = CF_ExpressionVM.Create(expr, CF_SQFExpression);
  8190.  
  8191. float expectedNum = 3 * (4 - 2) * 2;
  8192. float actualNum = test.CompileEvaluateTest(variables, true);
  8193.  
  8194. string expectedRPN = "3 4 2 - 2 * *";
  8195. string actualRPN = test.ToRPN(true);
  8196.  
  8197. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8198. }
  8199.  
  8200. void TestBrackets_Math_1()
  8201. {
  8202. map< string, float > variables = new map< string, float >();
  8203.  
  8204. string expr = "3 * (4 - 2) * 2";
  8205. CF_Expression test = CF_ExpressionVM.Create(expr, CF_MathExpression);
  8206.  
  8207. float expectedNum = 3 * (4 - 2) * 2;
  8208. float actualNum = test.CompileEvaluateTest(variables, true);
  8209.  
  8210. string expectedRPN = "3 4 2 - 2 * *";
  8211. string actualRPN = test.ToRPN(true);
  8212.  
  8213. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8214. }
  8215.  
  8216. void TestOrderOfOperations_SQF_1()
  8217. {
  8218. map< string, float > variables = new map< string, float >();
  8219.  
  8220. string expr = "2 + 5 * 5 + 2";
  8221. CF_Expression test = CF_ExpressionVM.Create(expr, CF_SQFExpression);
  8222.  
  8223. float expectedNum = 2 + 5 * 5 + 2;
  8224. float actualNum = test.CompileEvaluateTest(variables, true);
  8225.  
  8226. string expectedRPN = "2 5 5 * 2 + +";
  8227. string actualRPN = test.ToRPN(true);
  8228.  
  8229. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8230. }
  8231.  
  8232. void TestOrderOfOperations_SQF_2()
  8233. {
  8234. map< string, float > variables = new map< string, float >();
  8235.  
  8236. string expr = "5 * 5 - 8 * 8";
  8237. CF_Expression test = CF_ExpressionVM.Create(expr, CF_SQFExpression);
  8238.  
  8239. float expectedNum = 5 * 5 - 8 * 8;
  8240. float actualNum = test.CompileEvaluateTest(variables, true);
  8241.  
  8242. string expectedRPN = "5 5 * 8 8 * -";
  8243. string actualRPN = test.ToRPN(true);
  8244.  
  8245. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8246. }
  8247.  
  8248. void TestOrderOfOperations_Math_1()
  8249. {
  8250. map< string, float > variables = new map< string, float >();
  8251.  
  8252. string expr = "2 + 5 * 5 + 2";
  8253. CF_Expression test = CF_ExpressionVM.Create(expr, CF_MathExpression);
  8254.  
  8255. float expectedNum = 2 + 5 * 5 + 2;
  8256. float actualNum = test.CompileEvaluateTest(variables, true);
  8257.  
  8258. string expectedRPN = "2 5 5 * 2 + +";
  8259. string actualRPN = test.ToRPN(true);
  8260.  
  8261. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8262. }
  8263.  
  8264. void TestOrderOfOperations_Math_2()
  8265. {
  8266. map< string, float > variables = new map< string, float >();
  8267.  
  8268. string expr = "5 * 5 - 8 * 8";
  8269. CF_Expression test = CF_ExpressionVM.Create(expr, CF_MathExpression);
  8270.  
  8271. float expectedNum = 5 * 5 - 8 * 8;
  8272. float actualNum = test.CompileEvaluateTest(variables, true);
  8273.  
  8274. string expectedRPN = "5 5 * 8 8 * -";
  8275. string actualRPN = test.ToRPN(true);
  8276.  
  8277. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8278. }
  8279.  
  8280. void TestSound_SQF_1()
  8281. {
  8282. map< string, float > variables = new map< string, float >();
  8283.  
  8284. variables["rpm"] = 7000;
  8285. variables["doors"] = 0;
  8286. variables["campos"] = 0;
  8287. variables["engineOn"] = 1;
  8288.  
  8289. string expr = "0.75 * 1 * (0.7 + 0.3 * (speed factor [10,60])) * engineOn * 1 * ((850 + ((rpm - 850)/(8000/5600))) factor [(((3250+4400)/2) - 2.5*200),(((3250+4400)/2) + 200)]) * ((1 - 0.25*doors) max campos) * (rpm factor[4800,6200])";
  8290. CF_Expression test = CF_ExpressionVM.Create(expr, CF_SQFExpression);
  8291.  
  8292. float expectedNum = 0.75 * 1 * (0.7 + 0.3 * Math.Interpolate( variables["speed"], 10, 60, 0, 1 ) ) * variables["engineOn"] * 1 * Math.Interpolate(850 + ((variables["rpm"] - 850)/(8000/5600)), (((3250+4400)/2) - 2.5*200),(((3250+4400)/2) + 200), 0, 1) * (Math.Max(1 - 0.25*variables["doors"], variables["campos"]) * Math.Interpolate(variables["rpm"], 4800,6200, 0, 1));
  8293. float actualNum = test.CompileEvaluateTest(variables, true);
  8294.  
  8295. string expectedRPN = "0.75 1 0.7 0.3 speed factor [10, 60] * + engineOn 1 850 rpm 850 - 8000 5600 / / + factor [3325, 4025] 1 0.25 doors * - campos max rpm factor [4800, 6200] * * * * * * *";
  8296. string actualRPN = test.ToRPN(true);
  8297.  
  8298. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8299. }
  8300.  
  8301. void TestSound_SQF_2()
  8302. {
  8303. map< string, float > variables = new map< string, float >();
  8304.  
  8305. variables["rpm"] = 1100;
  8306. variables["doors"] = 0;
  8307. variables["campos"] = 0;
  8308. variables["engineOn"] = 1;
  8309.  
  8310. string expr = "0.75 * 1 * engineOn * 0.4 * ((850 + ((rpm - 850)/(8000/5600))) factor [(((850+1200)/2) + 2.5*50),(((850+1200)/2) - 50)]) * ((1 - 0.25*doors) max campos)";
  8311. CF_Expression test = CF_ExpressionVM.Create(expr, CF_SQFExpression);
  8312.  
  8313. float expectedNum = 0.75 * 1 * variables["engineOn"] * 0.4 * Math.Interpolate(850 +((variables["rpm"] - 850)/(8000/5600)),(((850+1200)/2) - 50), (((850+1200)/2) + 2.5*50),0, 1) * Math.Max((1 - 0.25 * variables["doors"]), variables["campos"]);
  8314. float actualNum = test.CompileEvaluateTest(variables, true);
  8315.  
  8316. string expectedRPN = "0.75 1 engineOn 0.4 850 rpm 850 - 8000 5600 / / + factor [975, 1150] 1 0.25 doors * - campos max * * * * *";
  8317. string actualRPN = test.ToRPN(true);
  8318.  
  8319. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8320. }
  8321.  
  8322. void TestSound_Math_1()
  8323. {
  8324. map< string, float > variables = new map< string, float >();
  8325.  
  8326. variables["rpm"] = 7000;
  8327. variables["doors"] = 0;
  8328. variables["campos"] = 0;
  8329. variables["engineOn"] = 1;
  8330.  
  8331. string expr = "0.75 * 1 * (0.7 + 0.3 * factor( speed, 10, 60 ) ) * engineOn * 1 * factor(850 + ((rpm - 850)/(8000/5600)), (((3250+4400)/2) - 2.5*200),(((3250+4400)/2) + 200)) * (1 - 0.25*doors max campos) * factor(rpm, 4800,6200)";
  8332. CF_Expression test = CF_ExpressionVM.Create(expr, CF_MathExpression);
  8333.  
  8334. float expectedNum = 0.75 * 1 * (0.7 + 0.3 * Math.Interpolate( variables["speed"], 10, 60, 0, 1 ) ) * variables["engineOn"] * 1 * Math.Interpolate(850 + ((variables["rpm"] - 850)/(8000/5600)), (((3250+4400)/2) - 2.5*200),(((3250+4400)/2) + 200), 0, 1) * (Math.Max(1 - 0.25*variables["doors"], variables["campos"]) * Math.Interpolate(variables["rpm"], 4800,6200, 0, 1));
  8335. float actualNum = test.CompileEvaluateTest(variables, true);
  8336.  
  8337. string expectedRPN = "0.75 1 0.7 0.3 speed factor [10, 60] * + engineOn 1 850 rpm 850 - 8000 5600 / / + 1 0.25 doors campos max * - rpm factor [4800, 6200] * * factor [3325, 4025] * * * * *";
  8338. string actualRPN = test.ToRPN(true);
  8339.  
  8340. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8341. }
  8342.  
  8343. void TestSound_Math_2()
  8344. {
  8345. map< string, float > variables = new map< string, float >();
  8346.  
  8347. variables["rpm"] = 1100;
  8348. variables["doors"] = 0;
  8349. variables["campos"] = 0;
  8350. variables["engineOn"] = 1;
  8351.  
  8352. string expr = "0.75 * 1 * engineOn * 0.4 * factor(850 + ((rpm - 850)/(8000/5600)),(((850+1200)/2) + 2.5*50),(((850+1200)/2) - 50)) * ((1 - 0.25*doors) max campos)";
  8353. CF_Expression test = CF_ExpressionVM.Create(expr, CF_MathExpression);
  8354.  
  8355. float expectedNum = 0.75 * 1 * variables["engineOn"] * 0.4 * Math.Interpolate(850 +((variables["rpm"] - 850)/(8000/5600)),(((850+1200)/2) - 50), (((850+1200)/2) + 2.5*50),0, 1) * Math.Max((1 - 0.25 * variables["doors"]), variables["campos"]);
  8356. float actualNum = test.CompileEvaluateTest(variables, true);
  8357.  
  8358. string expectedRPN = "0.75 1 engineOn 0.4 850 rpm 850 - 8000 5600 / / + 1 0.25 doors * - campos max * factor [975, 1150] * * * *";
  8359. string actualRPN = test.ToRPN(true);
  8360.  
  8361. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8362. }
  8363.  
  8364. void TestPerformance()
  8365. {
  8366. map< string, float > variables = new map< string, float >();
  8367.  
  8368. variables["rpm"] = 7000;
  8369. variables["doors"] = 0;
  8370. variables["campos"] = 0;
  8371. variables["engineOn"] = 1;
  8372.  
  8373. string expr = "0.75 * 1 * (0.7 + 0.3 * (speed factor [10,60])) * engineOn * 1 * ((850 + ((rpm - 850)/(8000/5600))) factor [(((3250+4400)/2) - 2.5*200),(((3250+4400)/2) + 200)]) * ((1 - 0.25*doors) max campos) * (rpm factor[4800,6200])";
  8374. CF_Expression test = CF_ExpressionVM.Create(expr, CF_SQFExpression);
  8375.  
  8376. float expectedNum = 0.75 * 1 * (0.7 + 0.3 * Math.Interpolate( variables["speed"], 10, 60, 0, 1 ) ) * variables["engineOn"] * 1 * Math.Interpolate(850 + ((variables["rpm"] - 850)/(8000/5600)), (((3250+4400)/2) - 2.5*200),(((3250+4400)/2) + 200), 0, 1) * (Math.Max(1 - 0.25*variables["doors"], variables["campos"]) * Math.Interpolate(variables["rpm"], 4800,6200, 0, 1));
  8377. test.CompileTest(variables.GetKeyArray(), true);
  8378. array<float> varFloats = variables.GetValueArray();
  8379.  
  8380. float actualNum = test.EvaluateTest(varFloats, true);
  8381.  
  8382. string expectedRPN = "0.75 1 0.7 0.3 speed factor [10, 60] * + engineOn 1 850 rpm 850 - 8000 5600 / / + factor [3325, 4025] 1 0.25 doors * - campos max rpm factor [4800, 6200] * * * * * * *";
  8383. string actualRPN = test.ToRPN(true);
  8384.  
  8385. int count = 100000;
  8386.  
  8387. float s_start = GetGame().GetTickTime();
  8388. int t_start = TickCount( 0 );
  8389.  
  8390. for (int i = 0; i < count; i++)
  8391. {
  8392. test.Evaluate(varFloats);
  8393. }
  8394.  
  8395. int t_time = TickCount(t_start);
  8396. float s_time = GetGame().GetTickTime() - s_start;
  8397.  
  8398. Print( "TestPerformance took " + (t_time) + " ticks to execute for " + count + " iterations, an average of " + (t_time / count) + " ticks." );
  8399. Print( "TestPerformance took " + (s_time) + " seconds to execute for " + count + " iterations, an average of " + (s_time / (count / 1000.0)) + " milliseconds." );
  8400.  
  8401. _assert( expectedNum, actualNum, expectedRPN, actualRPN );
  8402. }
  8403. };
  8404. #endif
  8405. class CF_ExpressionVM
  8406. {
  8407. static CF_ExpressionInstruction CurrentInstruction;
  8408. static float Stack[16];
  8409. static ref CF_ExpressionStackDebug StackDebugger = new CF_ExpressionStackDebug();
  8410. static int StackPointer;
  8411. static array<float> Variables;
  8412.  
  8413. private static autoptr map<string, autoptr CF_ExpressionFunctionDef> s_Functions;
  8414.  
  8415. [CF_EventSubscriber(ScriptCaller.Create(CF_ExpressionVM.Destroy), CF_LifecycleEvents.OnGameDestroy)]
  8416. static void Destroy()
  8417. {
  8418. s_Functions = null;
  8419. }
  8420.  
  8421. static void AddFunction(string name, notnull CF_ExpressionFunctionDef function)
  8422. {
  8423. //! Init map
  8424. if (s_Functions == null)
  8425. {
  8426. s_Functions = new map<string, autoptr CF_ExpressionFunctionDef>();
  8427. }
  8428.  
  8429. //! Add the function
  8430. s_Functions[name] = function;
  8431. }
  8432.  
  8433. static CF_Expression Create(string src)
  8434. {
  8435. return Create(src, CF_MathExpression);
  8436. }
  8437.  
  8438. static CF_Expression Create(string src, typename type)
  8439. {
  8440. CF_Expression expr = CF_Expression.Cast(type.Spawn());
  8441. if (expr) expr.SetSource(src);
  8442. return expr;
  8443. }
  8444.  
  8445. static CF_Expression Compile(string src)
  8446. {
  8447. return Compile(src, new array<string>(), CF_MathExpression);
  8448. }
  8449.  
  8450. static CF_Expression Compile(string src, array<string> variables)
  8451. {
  8452. return Compile(src, variables, CF_MathExpression);
  8453. }
  8454.  
  8455. static CF_Expression Compile(string src, typename type)
  8456. {
  8457. return Compile(src, new array<string>(), type);
  8458. }
  8459.  
  8460. static CF_Expression Compile(string src, array<string> variables, typename type)
  8461. {
  8462. CF_Expression expr = Create(src, type);
  8463. expr.Compile(variables);
  8464. return expr;
  8465. }
  8466.  
  8467. static bool Find(string name, inout CF_ExpressionFunctionDef function)
  8468. {
  8469. return s_Functions.Find(name, function);
  8470. }
  8471.  
  8472. static bool Contains(string name)
  8473. {
  8474. return s_Functions.Contains(name);
  8475. }
  8476. };
  8477. class CF_MathExpression : CF_Expression
  8478. {
  8479. //! @Jacob-Mango: I want this to be protected or private but a compile error happens
  8480. int __Compile(array<string> variables)
  8481. {
  8482. array<ref CF_ExpressionCompileToken> dataStackStore();
  8483. __Stack<CF_ExpressionCompileToken> stack();
  8484.  
  8485. CF_ExpressionFunctionDef funcDef;
  8486. CF_ExpressionCompileToken compileToken;
  8487.  
  8488. while (!EOF())
  8489. {
  8490. string token = GetToken();
  8491.  
  8492. token = token.Trim();
  8493.  
  8494. if (token == ",")
  8495. break;
  8496.  
  8497. CF_ExpressionFunctionDef op1;
  8498. CF_ExpressionFunctionDef op2;
  8499.  
  8500. if (CF_ExpressionVM.Find(token, op1))
  8501. {
  8502. compileToken = new CF_ExpressionCompileToken(token);
  8503. dataStackStore.Insert(compileToken);
  8504.  
  8505. int startPosition = m_Position;
  8506.  
  8507. token = SkipWhitespace();
  8508. if (token == "(")
  8509. {
  8510. token = SkipWhitespace();
  8511. int paramidx = 0;
  8512. int nPos;
  8513.  
  8514. m_Position--;
  8515. while (token != ")")
  8516. {
  8517. //! First param can be a variabled expression, i.e. behaves as if this was brackets
  8518. if (paramidx == 0)
  8519. {
  8520. nPos = __Compile(variables);
  8521. m_Position = nPos - 1;
  8522. token = SkipWhitespace();
  8523. }
  8524. else
  8525. {
  8526. CF_Expression parameter = new CF_MathExpression();
  8527.  
  8528. parameter.m_Source = m_Source + "";
  8529. parameter.m_Position = m_Position + 0;
  8530.  
  8531. //! there should be no variables/functions inside a parameter for a function call
  8532. nPos = parameter._Compile(variables);
  8533. float nVal = parameter._Evaluate(new array<float>());
  8534.  
  8535. compileToken.parameters.Insert(nVal);
  8536.  
  8537. m_Position = nPos - 1;
  8538. token = SkipWhitespace();
  8539. }
  8540. paramidx++;
  8541. }
  8542. }
  8543. else
  8544. {
  8545. m_Position = startPosition;
  8546. }
  8547.  
  8548. //! factor function optimization
  8549. if (compileToken.token == CF_ExpressionFunctionFactor.CF_NAME)
  8550. {
  8551. if (compileToken.parameters[1] < compileToken.parameters[0])
  8552. {
  8553. compileToken.token = CF_ExpressionFunctionReverseFactor.CF_NAME;
  8554. }
  8555. }
  8556.  
  8557. while (stack.Count() > 0)
  8558. {
  8559. string tok = stack.Peek().token;
  8560. if (!CF_ExpressionVM.Find(tok, op2))
  8561. break;
  8562.  
  8563. int c = op1.precedence - op2.precedence;
  8564.  
  8565. if (op1.precedence != 1 && (c < 0 || (!op1.associative && c <= 0)))
  8566. AddInstruction(stack.Pop().ToOperation(op2));
  8567. else
  8568. break;
  8569. }
  8570.  
  8571. stack.Push(compileToken);
  8572. }
  8573. else if (token == "(")
  8574. {
  8575. dataStackStore.Insert(stack.Push(new CF_ExpressionCompileToken(token)));
  8576. }
  8577. else if (token == ")")
  8578. {
  8579. string topToken = "";
  8580.  
  8581. while (stack.Count() > 0)
  8582. {
  8583. compileToken = stack.Pop();
  8584. topToken = compileToken.token;
  8585. if ( compileToken.token == "(" )
  8586. break;
  8587.  
  8588. if (CF_ExpressionVM.Find( topToken, funcDef ))
  8589. AddInstruction( compileToken.ToOperation( funcDef ) );
  8590. }
  8591.  
  8592. if (topToken != "(")
  8593. break;
  8594. }
  8595. else
  8596. {
  8597. if ( IsNumber( token ) )
  8598. {
  8599. compileToken = new CF_ExpressionCompileToken( token );
  8600. if (CF_ExpressionVM.Find( CF_ExpressionFunctionValue.CF_NAME, funcDef ))
  8601. {
  8602. AddInstruction( compileToken.ToOperation( funcDef, -2 ) );
  8603. }
  8604. } else
  8605. {
  8606. compileToken = new CF_ExpressionCompileToken( token );
  8607. if (CF_ExpressionVM.Find( CF_ExpressionFunctionVariable.CF_NAME, funcDef ))
  8608. {
  8609. AddInstruction( compileToken.ToOperation( funcDef, variables.Find( token ) ) );
  8610. }
  8611. }
  8612. }
  8613. }
  8614.  
  8615. while (stack.Count() > 0)
  8616. {
  8617. compileToken = stack.Pop();
  8618. if ( !CF_ExpressionVM.Contains( compileToken.token ) )
  8619. CF_Log.Error( "No matching right parenthesis" );
  8620.  
  8621. if (CF_ExpressionVM.Find( compileToken.token, funcDef ))
  8622. {
  8623. AddInstruction( compileToken.ToOperation( funcDef ) );
  8624. }
  8625. }
  8626.  
  8627. while (dataStackStore.Count() > 0)
  8628. {
  8629. dataStackStore.Remove(0);
  8630. }
  8631.  
  8632. return m_Position;
  8633. }
  8634.  
  8635. protected override int _Compile(array<string> variables)
  8636. {
  8637. ClearInstructions();
  8638.  
  8639. return __Compile(variables);
  8640. }
  8641. };
  8642. class CF_SQFExpression : CF_Expression
  8643. {
  8644. protected override int _Compile(array<string> variables)
  8645. {
  8646. array<ref CF_ExpressionCompileToken> dataStackStore();
  8647. __Stack<CF_ExpressionCompileToken> stack();
  8648.  
  8649. ClearInstructions();
  8650.  
  8651. CF_ExpressionFunctionDef funcDef;
  8652. CF_ExpressionCompileToken compileToken;
  8653.  
  8654. while (!EOF())
  8655. {
  8656. string token = GetToken();
  8657.  
  8658. token = token.Trim();
  8659.  
  8660. if (token == "]" || token == ",")
  8661. break;
  8662.  
  8663. CF_ExpressionFunctionDef op1;
  8664. CF_ExpressionFunctionDef op2;
  8665.  
  8666. if (CF_ExpressionVM.Find(token, op1))
  8667. {
  8668. while (stack.Count() > 0)
  8669. {
  8670. string tok = stack.Peek().token;
  8671. if (!CF_ExpressionVM.Find(tok, op2))
  8672. break;
  8673.  
  8674. int c = op1.precedence - op2.precedence;
  8675.  
  8676. if (c < 0 || (!op1.associative && c <= 0))
  8677. AddInstruction(stack.Pop().ToOperation(op2));
  8678. else
  8679. break;
  8680. }
  8681.  
  8682. compileToken = stack.Push(new CF_ExpressionCompileToken(token));
  8683. dataStackStore.Insert(compileToken);
  8684.  
  8685. int startPosition = m_Position;
  8686.  
  8687. token = SkipWhitespace();
  8688. if (token == "[")
  8689. {
  8690. token = SkipWhitespace();
  8691. m_Position--;
  8692. while (token != "]")
  8693. {
  8694. CF_Expression parameter = new CF_SQFExpression();
  8695.  
  8696. parameter.m_Source = m_Source + "";
  8697. parameter.m_Position = m_Position + 0;
  8698.  
  8699. //! there should be no variables/functions inside a parameter for a function call
  8700. int nPos = parameter._Compile(variables);
  8701. float nVal = parameter._Evaluate(new array<float>());
  8702.  
  8703. compileToken.parameters.Insert(nVal);
  8704.  
  8705. m_Position = nPos - 1;
  8706. token = SkipWhitespace();
  8707. }
  8708.  
  8709. //! factor function optimization
  8710. if (compileToken.token == CF_ExpressionFunctionFactor.CF_NAME)
  8711. {
  8712. if (compileToken.parameters[1] < compileToken.parameters[0])
  8713. {
  8714. compileToken.token = CF_ExpressionFunctionReverseFactor.CF_NAME;
  8715. }
  8716. }
  8717. }
  8718. else
  8719. {
  8720. m_Position = startPosition;
  8721. }
  8722. }
  8723. else if (token == "(")
  8724. {
  8725. dataStackStore.Insert(stack.Push(new CF_ExpressionCompileToken(token)));
  8726. }
  8727. else if (token == ")")
  8728. {
  8729. string topToken = "";
  8730. while (stack.Count() > 0)
  8731. {
  8732. compileToken = stack.Pop();
  8733. topToken = compileToken.token;
  8734. if (compileToken.token == "(")
  8735. break;
  8736.  
  8737. if (CF_ExpressionVM.Find(topToken, funcDef))
  8738. AddInstruction(compileToken.ToOperation(funcDef));
  8739. }
  8740.  
  8741. if (topToken != "(")
  8742. CF_Log.Error("No matching left parenthesis");
  8743. }
  8744. else
  8745. {
  8746. if (IsNumber(token))
  8747. {
  8748. compileToken = new CF_ExpressionCompileToken(token);
  8749. if (CF_ExpressionVM.Find(CF_ExpressionFunctionValue.CF_NAME, funcDef))
  8750. {
  8751. AddInstruction(compileToken.ToOperation(funcDef, -2));
  8752. }
  8753. }
  8754. else
  8755. {
  8756. compileToken = new CF_ExpressionCompileToken(token);
  8757. if (CF_ExpressionVM.Find(CF_ExpressionFunctionVariable.CF_NAME, funcDef))
  8758. {
  8759. AddInstruction(compileToken.ToOperation(funcDef, variables.Find(token)));
  8760. }
  8761. }
  8762. }
  8763. }
  8764.  
  8765. while (stack.Count() > 0)
  8766. {
  8767. compileToken = stack.Pop();
  8768. if (!CF_ExpressionVM.Contains(compileToken.token))
  8769. CF_Log.Error("No matching right parenthesis");
  8770.  
  8771. if (CF_ExpressionVM.Find(compileToken.token, funcDef))
  8772. {
  8773. AddInstruction(compileToken.ToOperation(funcDef));
  8774. }
  8775. }
  8776.  
  8777. while (dataStackStore.Count() > 0)
  8778. {
  8779. dataStackStore.Remove(0);
  8780. }
  8781.  
  8782. return m_Position;
  8783. }
  8784. };
  8785.  
  8786. /**
  8787. * Backwards compatibility
  8788. */
  8789. class Expression : CF_SQFExpression
  8790. {
  8791. // DEPRECATED
  8792. string value;
  8793.  
  8794. void Expression(string val = "")
  8795. {
  8796. SetSource(val);
  8797. }
  8798. };
  8799. #ifdef CF_EXPRESSION_TEST
  8800. modded class DayZGame
  8801. {
  8802. private float m_CF_UpdateTime;
  8803. private int m_CF_Tests;
  8804.  
  8805. override void OnUpdate(bool doSim, float timeslice)
  8806. {
  8807. super.OnUpdate(doSim, timeslice);
  8808. if (!doSim) return;
  8809.  
  8810. m_CF_UpdateTime += timeslice;
  8811. if (m_CF_UpdateTime > 5.0 && m_CF_Tests < 3)
  8812. {
  8813. m_CF_UpdateTime = 0;
  8814. m_CF_Tests++;
  8815.  
  8816. CF_ExpressionTests.PerformSingle("TestPerformance");
  8817. }
  8818. }
  8819. };
  8820. #endif
  8821. modded class DayZGame
  8822. {
  8823. ref CF_EventRPCArgs m_CF_EventRPCArgs = new CF_EventRPCArgs();
  8824.  
  8825. void DayZGame()
  8826. {
  8827. CF_ModuleGameManager.UpdateGameFlag(this);
  8828. }
  8829.  
  8830. override void DeferredInit()
  8831. {
  8832. #ifdef CF_TRACE_ENABLED
  8833. auto trace = CF_Trace_0(this);
  8834. #endif
  8835.  
  8836. super.DeferredInit();
  8837.  
  8838. GetRPCManager();
  8839. }
  8840.  
  8841. override void OnUpdate(bool doSim, float timeslice)
  8842. {
  8843. super.OnUpdate(doSim, timeslice);
  8844.  
  8845. if (!GetGame().IsDedicatedServer())
  8846. {
  8847. foreach (auto input : CF_InputBindings.s_All)
  8848. {
  8849. input.Update(timeslice);
  8850. }
  8851. }
  8852. }
  8853.  
  8854. override void OnRPC(PlayerIdentity sender, Object target, int rpc_type, ParamsReadContext ctx)
  8855. {
  8856. #ifdef CF_TRACE_ENABLED
  8857. auto trace = CF_Trace_4(this).Add(sender).Add(target).Add(rpc_type).Add(ctx);
  8858. #endif
  8859.  
  8860. if (rpc_type == RPCManager.FRAMEWORK_RPC_ID)
  8861. {
  8862. GetRPCManager().OnRPC(sender, target, rpc_type, ctx);
  8863.  
  8864. return;
  8865. }
  8866.  
  8867. if (rpc_type == NotificationSystemRPC.Create)
  8868. {
  8869. NotificationSystem.RPC_CreateNotification(sender, target, ctx);
  8870.  
  8871. return;
  8872. }
  8873.  
  8874. if (rpc_type == CF_ModuleGame.NETWORKED_VARIABLES_RPC_ID)
  8875. {
  8876. // Only allow this RPC to be executed on the client, don't want to allow the client to edit server variables
  8877. if (GetGame().IsServer())
  8878. {
  8879. return;
  8880. }
  8881.  
  8882. string moduleName;
  8883. if (!ctx.Read(moduleName))
  8884. {
  8885. return;
  8886. }
  8887.  
  8888. // Check to see if the module can be found
  8889. CF_ModuleGame module;
  8890. if (!Class.CastTo(module, CF_ModuleCoreManager.Get(moduleName)))
  8891. {
  8892. return;
  8893. }
  8894.  
  8895. module.m_CF_NetworkedVariables.Read(ctx);
  8896.  
  8897. module.OnVariablesSynchronized(this, CF_EventArgs.Empty);
  8898.  
  8899. return;
  8900. }
  8901.  
  8902. m_CF_EventRPCArgs.Sender = sender;
  8903. m_CF_EventRPCArgs.Target = target;
  8904. m_CF_EventRPCArgs.ID = rpc_type;
  8905. m_CF_EventRPCArgs.Context = ctx;
  8906.  
  8907. if (CF_ModuleGameManager.OnRPC(this, m_CF_EventRPCArgs))
  8908. {
  8909. return;
  8910. }
  8911.  
  8912. super.OnRPC(sender, target, rpc_type, ctx);
  8913. }
  8914.  
  8915. override void OnEvent(EventType eventTypeId, Param params)
  8916. {
  8917. super.OnEvent(eventTypeId, params);
  8918.  
  8919. switch (eventTypeId)
  8920. {
  8921. case MPSessionStartEventTypeID:
  8922. {
  8923. CF_ModuleCoreManager.OnMPSessionStart(this, CF_EventArgs.Empty);
  8924.  
  8925. break;
  8926. }
  8927. case MPSessionEndEventTypeID:
  8928. {
  8929. CF_ModuleCoreManager.OnMPSessionEnd(this, CF_EventArgs.Empty);
  8930.  
  8931. break;
  8932. }
  8933. case MPSessionFailEventTypeID:
  8934. {
  8935. CF_ModuleCoreManager.OnMPSessionFail(this, CF_EventArgs.Empty);
  8936.  
  8937. break;
  8938. }
  8939. case MPSessionPlayerReadyEventTypeID:
  8940. {
  8941. CF_ModuleCoreManager.OnMPSessionPlayerReady(this, CF_EventArgs.Empty);
  8942.  
  8943. break;
  8944. }
  8945. case MPConnectionLostEventTypeID:
  8946. {
  8947. MPConnectionLostEventParams conLost_params;
  8948. if (Class.CastTo(conLost_params, params))
  8949. {
  8950. CF_ModuleCoreManager.OnMPConnectionLost(this, new CF_EventTimeArgs(conLost_params.param1));
  8951. }
  8952. break;
  8953. }
  8954. case WorldCleaupEventTypeID:
  8955. {
  8956. CF_ModuleCoreManager.OnWorldCleanup(this, CF_EventArgs.Empty);
  8957.  
  8958. break;
  8959. }
  8960. case ChatMessageEventTypeID:
  8961. {
  8962. ChatMessageEventParams chat_params;
  8963. if (Class.CastTo(chat_params, params))
  8964. {
  8965. CF_ModuleCoreManager.OnChat(this, new CF_EventChatArgs(chat_params.param1, chat_params.param2, chat_params.param3, chat_params.param4));
  8966. }
  8967.  
  8968. break;
  8969. }
  8970. case LoginTimeEventTypeID:
  8971. {
  8972. LoginTimeEventParams loginTimeParams;
  8973. if (Class.CastTo(loginTimeParams, params))
  8974. {
  8975. CF_ModuleCoreManager.OnLoginTime(this, new CF_EventTimeArgs(loginTimeParams.param1));
  8976. }
  8977. break;
  8978. }
  8979. case RespawnEventTypeID:
  8980. {
  8981. RespawnEventParams respawnParams;
  8982. if (Class.CastTo(respawnParams, params))
  8983. {
  8984. CF_ModuleCoreManager.OnRespawn(this, new CF_EventTimeArgs(respawnParams.param1));
  8985. }
  8986. break;
  8987. }
  8988. case LogoutEventTypeID:
  8989. {
  8990. LogoutEventParams logoutParams;
  8991. if (Class.CastTo(logoutParams, params))
  8992. {
  8993. CF_ModuleCoreManager.OnLogout(this, new CF_EventTimeArgs(logoutParams.param1));
  8994. }
  8995. break;
  8996. }
  8997. case LoginStatusEventTypeID:
  8998. {
  8999. LoginStatusEventParams loginStatusParams;
  9000. if (Class.CastTo(loginStatusParams, params))
  9001. {
  9002. CF_ModuleCoreManager.OnLoginStatus(this, new CF_EventLoginArgs(loginStatusParams.param1, loginStatusParams.param2));
  9003. }
  9004. break;
  9005. }
  9006. case ConnectingAbortEventTypeID:
  9007. {
  9008. CF_ModuleCoreManager.OnMPConnectAbort(this, CF_EventArgs.Empty);
  9009. break;
  9010. }
  9011. }
  9012. }
  9013.  
  9014. /**
  9015. * @brief An overrideable function that determines if the UI input of the player is being blocked by an editbox widget.
  9016. */
  9017. bool CF_UIInputBlocked()
  9018. {
  9019. if (GetGame().IsDedicatedServer())
  9020. {
  9021. return false;
  9022. }
  9023.  
  9024. Widget focusedWidget = GetFocus();
  9025. if (!focusedWidget)
  9026. {
  9027. return false;
  9028. }
  9029.  
  9030. return focusedWidget.ClassName().Contains("EditBoxWidget");
  9031. }
  9032. };
  9033. class CF_InputBinding
  9034. {
  9035. static int PRESS = 1;
  9036. static int RELEASE = 2;
  9037. static int HOLD = 4;
  9038. static int CLICK = 8;
  9039. static int DOUBLE_CLICK = 16;
  9040.  
  9041. ref CF_InputBinding m_Next;
  9042.  
  9043. string m_Function;
  9044. UAInput m_Input;
  9045. int m_InputLimits;
  9046. bool m_LimitMenu;
  9047.  
  9048. void UpdateLimits()
  9049. {
  9050. m_InputLimits = 0;
  9051. m_InputLimits &= m_Input.IsPressLimit() << 1;
  9052. m_InputLimits &= m_Input.IsReleaseLimit() << 2;
  9053. m_InputLimits &= m_Input.IsHoldLimit() << 3;
  9054. m_InputLimits &= m_Input.IsClickLimit() << 4;
  9055. m_InputLimits &= m_Input.IsDoubleClickLimit() << 5;
  9056. }
  9057. };
  9058. class CF_InputBindings
  9059. {
  9060. static ref array<CF_InputBindings> s_All = new array<CF_InputBindings>();
  9061.  
  9062. ref CF_InputBinding m_Head;
  9063. Class m_Instance;
  9064.  
  9065. /**
  9066. * @brief Constructor. Adds to the list of all input binding managers. Should be called on parent class construction
  9067. *
  9068. * @param instance The input binding parent
  9069. */
  9070. void CF_InputBindings(Class instance)
  9071. {
  9072. m_Instance = instance;
  9073.  
  9074. s_All.Insert(this);
  9075. }
  9076.  
  9077. /**
  9078. * @brief Removes from the list of all input binding managers. Should be called on parent class deletion
  9079. */
  9080. void ~CF_InputBindings()
  9081. {
  9082. s_All.RemoveItemUnOrdered(this);
  9083. }
  9084.  
  9085. /**
  9086. * @brief Binds input to head, pushes other entries back
  9087. *
  9088. * @param callback The function the input binding parent to call
  9089. * @param input The name of the input
  9090. * @param preventCallInMenu If the binding can be called while a menu is open
  9091. *
  9092. * @code
  9093. * bindings.Bind("Close", "UAUIBack", false);
  9094. * @endcode
  9095. */
  9096. void Bind(string callback, string input, bool preventCallInMenu = false)
  9097. {
  9098. Bind(callback, GetUApi().GetInputByName(input), preventCallInMenu);
  9099. }
  9100.  
  9101. /**
  9102. * @brief Binds input to head, pushes other entries back
  9103. *
  9104. * @param callback The function the input binding parent to call
  9105. * @param input The ID of the input. All inputs found within modded inputs is generated as a global int variable of the same name
  9106. * @param preventCallInMenu If the binding can be called while a menu is open
  9107. *
  9108. * @code
  9109. * bindings.Bind("Close", UAUIBack, false);
  9110. * @endcode
  9111. */
  9112. void Bind(string callback, int input, bool preventCallInMenu = false)
  9113. {
  9114. Bind(callback, GetUApi().GetInputByID(input), preventCallInMenu);
  9115. }
  9116.  
  9117. /**
  9118. * @brief Binds input to head, pushes other entries back
  9119. *
  9120. * @param callback The function the input binding parent to call
  9121. * @param input The instance of the input
  9122. * @param preventCallInMenu If the binding can be called while a menu is open
  9123. *
  9124. * @code
  9125. * bindings.Bind("Close", GetUApi().GetInputByID(UAUIBack), false);
  9126. * @endcode
  9127. */
  9128. void Bind(string callback, UAInput input, bool preventCallInMenu = false)
  9129. {
  9130. CF_InputBinding binding = new CF_InputBinding();
  9131. binding.m_Function = callback;
  9132. binding.m_Input = input;
  9133. binding.m_LimitMenu = preventCallInMenu;
  9134.  
  9135. Bind(binding);
  9136. }
  9137.  
  9138. /**
  9139. * @brief Binds input to head, pushes other entries back
  9140. *
  9141. * @param binding The instance of the binding to add to the list
  9142. */
  9143. void Bind(CF_InputBinding binding)
  9144. {
  9145. if (m_Head)
  9146. {
  9147. binding.m_Next = m_Head;
  9148. }
  9149.  
  9150. m_Head = binding;
  9151. m_Head.UpdateLimits();
  9152. }
  9153.  
  9154. /**
  9155. * @brief Checks for all input state changes and calls the necessary functions
  9156. *
  9157. * @param dt Unused.
  9158. */
  9159. void Update(float dt)
  9160. {
  9161. bool inMenu = GetGame().GetUIManager().GetMenu() || CF_ModuleGame.s_PreventInput;
  9162.  
  9163. CF_InputBinding binding = m_Head;
  9164. while (binding)
  9165. {
  9166. if (!inMenu || (inMenu && !binding.m_LimitMenu))
  9167. {
  9168. UAInput input = binding.m_Input;
  9169. bool isModified = input.LocalValue() != 0.0 || input.LocalRelease();
  9170.  
  9171. if (binding.m_InputLimits != 0)
  9172. {
  9173. if (isModified)
  9174. {
  9175. g_Script.CallFunctionParams(m_Instance, binding.m_Function, NULL, new Param1<UAInput>(input));
  9176. }
  9177. }
  9178. else if (isModified)
  9179. {
  9180. g_Script.CallFunctionParams(m_Instance, binding.m_Function, NULL, new Param1<UAInput>(input));
  9181. }
  9182. }
  9183.  
  9184. binding = binding.m_Next;
  9185. }
  9186. }
  9187. };
  9188. modded class DayZGame
  9189. {
  9190. void DayZGame()
  9191. {
  9192. #ifdef CF_TRACE_ENABLED
  9193. auto trace = CF_Trace_0(this);
  9194. #endif
  9195.  
  9196. CF_LifecycleEvents.OnGameCreate.Invoke(this, CF_EventArgs.Empty);
  9197. }
  9198.  
  9199. void ~DayZGame()
  9200. {
  9201. #ifdef CF_TRACE_ENABLED
  9202. auto trace = CF_Trace_0(this);
  9203. #endif
  9204.  
  9205. CF_LifecycleEvents.OnGameDestroy.Invoke(this, CF_EventArgs.Empty);
  9206. }
  9207. };
  9208. class ModInput
  9209. {
  9210. string Name;
  9211. string Localization;
  9212. bool Visible;
  9213. };
  9214. modded class ModLoader
  9215. {
  9216. static ref array<ref ModStructure> s_CF_Mods = new array<ref ModStructure>();
  9217. static ref map<string, ModStructure> s_CF_ModMap = new map<string, ModStructure>();
  9218.  
  9219. static ref array<ref CF_ModStorage> s_CF_ModStorages = new array<ref CF_ModStorage>();
  9220. static ref CF_ModStorageMap s_CF_ModStorageMap = new CF_ModStorageMap();
  9221. static ref map<int, ref map<int, CF_ModStorage>> s_CF_ModStorageHashedMap = new map<int, ref map<int, CF_ModStorage>>();
  9222.  
  9223. static CF_ModStorage CF_GetStorage(string name)
  9224. {
  9225. #ifdef CF_TRACE_ENABLED
  9226. auto trace = CF_Trace_1("ModLoader").Add(name);
  9227. #endif
  9228.  
  9229. LoadMods();
  9230.  
  9231. return s_CF_ModStorageMap[name];
  9232. }
  9233.  
  9234. static bool CF_IsModStorage(string name)
  9235. {
  9236. #ifdef CF_TRACE_ENABLED
  9237. auto trace = CF_Trace_1("ModLoader").Add(name);
  9238. #endif
  9239.  
  9240. LoadMods();
  9241.  
  9242. return s_CF_ModStorageMap.Contains(name);
  9243. }
  9244.  
  9245. static bool _CF_ReadModStorage(Serializer ctx, int version, inout array<ref CF_ModStorage> unloadedMods, inout int stackIndex, inout CF_ModStorageMap loadedMods)
  9246. {
  9247. #ifdef CF_TRACE_ENABLED
  9248. auto trace = CF_Trace_2("ModLoader").Add(ctx).Add(version);
  9249. #endif
  9250.  
  9251. LoadMods();
  9252.  
  9253. int hashA, hashB;
  9254. bool exists = false;
  9255. CF_ModStorage storage;
  9256.  
  9257. if (version > 3)
  9258. {
  9259. if (!ctx.Read(hashA)) return false;
  9260. if (!ctx.Read(hashB)) return false;
  9261. }
  9262. else
  9263. {
  9264. CF_String modName;
  9265. if (!ctx.Read(modName)) return false;
  9266.  
  9267. hashA = modName.Hash();
  9268. hashB = modName.Reverse().Hash();
  9269. }
  9270.  
  9271. auto hash = s_CF_ModStorageHashedMap[hashA];
  9272. if (hash)
  9273. {
  9274. storage = hash[hashB];
  9275. exists = storage != null;
  9276. }
  9277.  
  9278. if (!exists)
  9279. {
  9280. storage = new CF_ModStorage(null);
  9281.  
  9282. storage.m_HashA = hashA;
  9283. storage.m_HashB = hashB;
  9284. }
  9285.  
  9286. if (!ctx.Read(storage.m_Version)) return false;
  9287. if (!ctx.Read(storage.m_Data)) return false;
  9288.  
  9289. if (exists)
  9290. {
  9291. loadedMods.Insert(storage.GetMod().GetName(), storage);
  9292. }
  9293. else
  9294. {
  9295. unloadedMods[stackIndex] = storage;
  9296. stackIndex++;
  9297. }
  9298.  
  9299. return true;
  9300. }
  9301.  
  9302. static ModStructure Get(string name)
  9303. {
  9304. #ifdef CF_TRACE_ENABLED
  9305. auto trace = CF_Trace_1("ModLoader").Add(name);
  9306. #endif
  9307.  
  9308. LoadMods();
  9309.  
  9310. return s_CF_ModMap[name];
  9311. }
  9312.  
  9313. static bool Contains(string name)
  9314. {
  9315. #ifdef CF_TRACE_ENABLED
  9316. auto trace = CF_Trace_1("ModLoader").Add(name);
  9317. #endif
  9318.  
  9319. LoadMods();
  9320.  
  9321. return s_CF_ModMap.Contains(name);
  9322. }
  9323.  
  9324. static bool Find(string name, out ModStructure mod)
  9325. {
  9326. #ifdef CF_TRACE_ENABLED
  9327. auto trace = CF_Trace_1("ModLoader").Add(name);
  9328. #endif
  9329.  
  9330. LoadMods();
  9331.  
  9332. return s_CF_ModMap.Find(name, mod);
  9333. }
  9334.  
  9335. override static array<ref ModStructure> GetMods()
  9336. {
  9337. #ifdef CF_TRACE_ENABLED
  9338. auto trace = CF_Trace_0("ModLoader");
  9339. #endif
  9340.  
  9341. LoadMods();
  9342.  
  9343. return m_Mods;
  9344. }
  9345.  
  9346. override static void LoadMods()
  9347. {
  9348. if (m_Loaded)
  9349. {
  9350. return;
  9351. }
  9352.  
  9353. #ifdef CF_TRACE_ENABLED
  9354. auto trace = CF_Trace_0("ModLoader");
  9355. #endif
  9356.  
  9357. m_Mods = new array<ref ModStructure>;
  9358. m_Loaded = true;
  9359.  
  9360. int modCount = GetGame().ConfigGetChildrenCount("CfgMods");
  9361. for (int i = 2; i < modCount; i++)
  9362. {
  9363. string name;
  9364. GetGame().ConfigGetChildName("CfgMods", i, name);
  9365.  
  9366. ModStructure mod;
  9367.  
  9368. typename type = name.ToType();
  9369. if (!type.IsInherited(ModStructure))
  9370. {
  9371. type = ModStructure;
  9372. }
  9373.  
  9374. if (Class.CastTo(mod, type.Spawn()))
  9375. {
  9376. mod._CF_Init(i, name, "CfgMods " + name);
  9377.  
  9378. m_Mods.Insert(mod);
  9379.  
  9380. s_CF_Mods.Insert(mod);
  9381. s_CF_ModMap.Insert(name, mod);
  9382.  
  9383. if (mod.HasModStorage())
  9384. {
  9385. CF_ModStorage storage = new CF_ModStorage(mod);
  9386. s_CF_ModStorages.Insert(storage);
  9387. s_CF_ModStorageMap.Insert(mod, storage);
  9388.  
  9389. int hashA = mod.m_CF_HashA;
  9390. int hashB = mod.m_CF_HashB;
  9391.  
  9392. map<int, CF_ModStorage> hashStructures = s_CF_ModStorageHashedMap[hashA];
  9393. if (!hashStructures)
  9394. {
  9395. hashStructures = new map<int, CF_ModStorage>();
  9396. s_CF_ModStorageHashedMap.Insert(hashA, hashStructures);
  9397. }
  9398.  
  9399. if (hashStructures.Contains(hashB))
  9400. {
  9401. CF_Log.Error("Mod exists with duplicate hashes! Name=%0 A=%1 B=%2", mod.GetName(), hashA.ToString(), hashB.ToString());
  9402. }
  9403.  
  9404. hashStructures[hashB] = storage;
  9405. }
  9406. }
  9407. }
  9408. }
  9409. };
  9410. modded class ModStructure
  9411. {
  9412. protected CF_String m_CF_Name;
  9413.  
  9414. int m_CF_HashA;
  9415. int m_CF_HashB;
  9416.  
  9417. protected ref array<ref ModInput> m_CF_ModInputs;
  9418. protected ref JsonDataCredits m_CF_Credits;
  9419.  
  9420. protected string m_CF_ModVersion;
  9421. protected int m_CF_StorageVersion;
  9422.  
  9423. /**
  9424. * Set the mod specific data in here
  9425. *
  9426. * @param modName The name of the loaded mod, retrieved from the CfgMods params array
  9427. *
  9428. * @code
  9429. * override bool CF_OnLoad( string modName )
  9430. * {
  9431. * if ( modName != "JM_CommunityFramework" )
  9432. * return super.CF_OnLoad( modName );
  9433. *
  9434. * //! Set the storage version for this mod
  9435. * SetStorageVersion( 1 );
  9436. *
  9437. * return true;
  9438. * }
  9439. * @endcode
  9440. */
  9441. bool CF_OnLoad(CF_String modName)
  9442. {
  9443. return false;
  9444. }
  9445.  
  9446. /**
  9447. * @brief Backwards compatibility
  9448. *
  9449. * @deprecated
  9450. */
  9451. bool OnLoad(string modName)
  9452. {
  9453. return false;
  9454. }
  9455.  
  9456. void _CF_Init(int index, string name, string path)
  9457. {
  9458. m_ModIndex = index;
  9459. m_ModPath = path;
  9460.  
  9461. m_CF_Name = name;
  9462. m_CF_HashA = m_CF_Name.Hash();
  9463. m_CF_HashB = m_CF_Name.Reverse().Hash();
  9464.  
  9465. m_CF_ModInputs = new array<ref ModInput>;
  9466. m_CF_StorageVersion = 0;
  9467.  
  9468. if (GetGame().ConfigIsExisting(m_ModPath))
  9469. {
  9470. if (GetGame().ConfigIsExisting(m_ModPath + " storageVersion"))
  9471. {
  9472. SetStorageVersion(GetGame().ConfigGetInt(m_ModPath + " storageVersion"));
  9473. }
  9474.  
  9475. if (GetGame().ConfigIsExisting(m_ModPath + " creditsJson"))
  9476. {
  9477. string creditsPath;
  9478. GetGame().ConfigGetText(m_ModPath + " creditsJson", creditsPath);
  9479.  
  9480. JsonFileLoader<JsonDataCredits>.JsonLoadFile(creditsPath, m_CF_Credits);
  9481. }
  9482. else if (GetGame().ConfigIsExisting(m_ModPath + " credits"))
  9483. {
  9484. string credits = "";
  9485.  
  9486. m_CF_Credits = new JsonDataCredits;
  9487. m_CF_Credits.Departments = new array<ref JsonDataCreditsDepartment>;
  9488.  
  9489. JsonDataCreditsDepartment mod_department_header = new JsonDataCreditsDepartment;
  9490. mod_department_header.Sections = new array<ref JsonDataCreditsSection>;
  9491. mod_department_header.DepartmentName = " " + m_ModName;
  9492.  
  9493. string author = "";
  9494. bool hasAuthor = GetGame().ConfigIsExisting(m_ModPath + " author");
  9495. GetGame().ConfigGetText(m_ModPath + " author", author);
  9496.  
  9497. if (hasAuthor && author != "")
  9498. {
  9499. JsonDataCreditsSection mod_section_modheader_author = new JsonDataCreditsSection;
  9500. mod_section_modheader_author.SectionLines = new array<string>;
  9501. mod_section_modheader_author.SectionName = ("Author");
  9502.  
  9503. mod_section_modheader_author.SectionLines.Insert(author);
  9504.  
  9505. mod_department_header.Sections.Insert(mod_section_modheader_author);
  9506. }
  9507.  
  9508. GetGame().ConfigGetText(m_ModPath + " credits", credits);
  9509.  
  9510. if (credits != "")
  9511. {
  9512. JsonDataCreditsSection mod_section_modheader = new JsonDataCreditsSection;
  9513. mod_section_modheader.SectionLines = new array<string>;
  9514. mod_section_modheader.SectionName = ("Credits");
  9515.  
  9516. array<string> creditsArray = new array<string>;
  9517. credits.Split(", ", creditsArray);
  9518. foreach (string credit : creditsArray)
  9519. {
  9520. mod_section_modheader.SectionLines.Insert(credit);
  9521. }
  9522.  
  9523. mod_department_header.Sections.Insert(mod_section_modheader);
  9524. }
  9525.  
  9526. m_CF_Credits.Departments.Insert(mod_department_header);
  9527. }
  9528. else
  9529. {
  9530. m_CF_Credits = new JsonDataCredits;
  9531. }
  9532.  
  9533. if (GetGame().ConfigIsExisting(m_ModPath + " versionPath"))
  9534. {
  9535. string versionPath;
  9536. GetGame().ConfigGetText(m_ModPath + " versionPath", versionPath);
  9537.  
  9538. FileHandle file_handle = OpenFile(versionPath, FileMode.READ);
  9539.  
  9540. while (FGets(file_handle, m_CF_ModVersion) > 0)
  9541. break;
  9542.  
  9543. CloseFile(file_handle);
  9544. }
  9545. else if (GetGame().ConfigIsExisting(m_ModPath + " version"))
  9546. {
  9547. GetGame().ConfigGetText(m_ModPath + " version", m_CF_ModVersion);
  9548. }
  9549.  
  9550. if (GetGame().ConfigIsExisting(m_ModPath + " inputs"))
  9551. {
  9552. string inputPath;
  9553. GetGame().ConfigGetText(m_ModPath + " inputs", inputPath);
  9554.  
  9555. CF_XML_Document document;
  9556. if (inputPath != "" && CF.XML.ReadDocument(inputPath, document))
  9557. {
  9558. auto parent_tag = document.Get("modded_inputs")[0];
  9559. if (parent_tag)
  9560. parent_tag = parent_tag.GetTag("inputs")[0];
  9561. if (parent_tag)
  9562. parent_tag = parent_tag.GetTag("actions")[0];
  9563.  
  9564. array<CF_XML_Tag> inputs = null;
  9565. if (!parent_tag)
  9566. inputs = new array<CF_XML_Tag>();
  9567. else
  9568. inputs = parent_tag.GetTag("input");
  9569.  
  9570. for (int i = 0; i < inputs.Count(); i++)
  9571. {
  9572. ModInput modInput = new ModInput;
  9573.  
  9574. CF_XML_Attribute attrib = null;
  9575.  
  9576. attrib = inputs[i].GetAttribute("name");
  9577. if (attrib)
  9578. modInput.Name = attrib.ValueAsString();
  9579.  
  9580. attrib = inputs[i].GetAttribute("loc");
  9581. if (attrib)
  9582. modInput.Localization = attrib.ValueAsString();
  9583.  
  9584. attrib = inputs[i].GetAttribute("visible");
  9585. if (attrib)
  9586. modInput.Visible = attrib.ValueAsBool();
  9587. else
  9588. modInput.Visible = true;
  9589.  
  9590. m_CF_ModInputs.Insert(modInput);
  9591. }
  9592. }
  9593. }
  9594.  
  9595. LoadData();
  9596.  
  9597. if (ClassName() == "ModStructure" && !CF_OnLoad(m_CF_Name))
  9598. {
  9599. OnLoad(m_CF_Name);
  9600. }
  9601. }
  9602. }
  9603.  
  9604. array<ref ModInput> GetModInputs()
  9605. {
  9606. return m_CF_ModInputs;
  9607. }
  9608.  
  9609. JsonDataCredits GetCredits()
  9610. {
  9611. return m_CF_Credits;
  9612. }
  9613.  
  9614. string GetName()
  9615. {
  9616. return m_CF_Name;
  9617. }
  9618.  
  9619. string GetModPath()
  9620. {
  9621. return m_ModPath;
  9622. }
  9623.  
  9624. override string GetModName()
  9625. {
  9626. return m_ModName;
  9627. }
  9628.  
  9629. override string GetModLogo()
  9630. {
  9631. return m_ModLogo;
  9632. }
  9633.  
  9634. override string GetModLogoSmall()
  9635. {
  9636. return m_ModLogoSmall;
  9637. }
  9638.  
  9639. override string GetModLogoOver()
  9640. {
  9641. return m_ModLogoOver;
  9642. }
  9643.  
  9644. override string GetModActionURL()
  9645. {
  9646. return m_ModActionURL;
  9647. }
  9648.  
  9649. override string GetModToltip()
  9650. {
  9651. return m_ModTooltip;
  9652. }
  9653.  
  9654. override string GetModOverview()
  9655. {
  9656. return m_ModOverview;
  9657. }
  9658.  
  9659. string GetModVersion()
  9660. {
  9661. return m_CF_ModVersion;
  9662. }
  9663.  
  9664. int GetStorageVersion()
  9665. {
  9666. return m_CF_StorageVersion;
  9667. }
  9668.  
  9669. protected void SetStorageVersion(int version)
  9670. {
  9671. m_CF_StorageVersion = version;
  9672. }
  9673.  
  9674. bool HasModStorage()
  9675. {
  9676. return m_CF_StorageVersion > 0;
  9677. }
  9678.  
  9679. override string GetDebugName()
  9680. {
  9681. string str = super.GetDebugName();
  9682.  
  9683. str += ", GetName=" + GetName();
  9684. str += ", GetModPath=" + GetModPath();
  9685. str += ", GetModName=" + GetModName();
  9686. str += ", GetModLogo=" + GetModLogo();
  9687. str += ", GetModLogoSmall=" + GetModLogoSmall();
  9688. str += ", GetModLogoOver=" + GetModLogoOver();
  9689. str += ", GetModActionURL=" + GetModActionURL();
  9690. str += ", GetModToltip=" + GetModToltip();
  9691. str += ", GetModOverview=" + GetModOverview();
  9692. str += ", GetModVersion=" + GetModVersion();
  9693. str += ", GetStorageVersion=" + GetStorageVersion();
  9694. str += ", HasModStorage=" + HasModStorage();
  9695.  
  9696. return str;
  9697. }
  9698. };
  9699. /**
  9700. * @class CF_ModStorage
  9701. *
  9702. * @note Do not mod this class. Modding this class defeats the purpose of this being in Community Framework.
  9703. * You will break persistence if you mod it. Make a pull request here https://github.com/Jacob-Mango/DayZ-Community-Framework/pulls
  9704. */
  9705. class CF_ModStorage
  9706. {
  9707. static const int VERSION = 4;
  9708.  
  9709. static const int GAME_VERSION_FIRST_INSTALL = 116;
  9710. static const int GAME_VERSION_WIPE_FILE = 127;
  9711.  
  9712. static const int MODSTORAGE_INITIAL_IMPLEMENTATION = 2;
  9713.  
  9714. ModStructure m_Mod;
  9715.  
  9716. int m_Version;
  9717.  
  9718. int m_HashA;
  9719. int m_HashB;
  9720.  
  9721. string m_Data;
  9722. string m_Value;
  9723.  
  9724. void CF_ModStorage(ModStructure mod)
  9725. {
  9726. m_Mod = mod;
  9727.  
  9728. _ResetStream();
  9729. }
  9730.  
  9731. int GetVersion()
  9732. {
  9733. return m_Version;
  9734. }
  9735.  
  9736. ModStructure GetMod()
  9737. {
  9738. return m_Mod;
  9739. }
  9740.  
  9741. bool Read(out bool value)
  9742. {
  9743. m_Data.ParseStringEx(m_Value);
  9744.  
  9745. value = m_Value == "1";
  9746.  
  9747. return true;
  9748. }
  9749.  
  9750. bool Read(out int value)
  9751. {
  9752. m_Data.ParseStringEx(m_Value);
  9753.  
  9754. value = m_Value.ToInt();
  9755.  
  9756. return true;
  9757. }
  9758.  
  9759. bool Read(out float value)
  9760. {
  9761. m_Data.ParseStringEx(m_Value);
  9762.  
  9763. value = m_Value.ToFloat();
  9764.  
  9765. return true;
  9766. }
  9767.  
  9768. bool Read(out vector value)
  9769. {
  9770. m_Data.ParseStringEx(m_Value);
  9771.  
  9772. value = m_Value.ToVector();
  9773.  
  9774. return true;
  9775. }
  9776.  
  9777. bool Read(out string value)
  9778. {
  9779. m_Data.ParseStringEx(m_Value);
  9780.  
  9781. value = m_Value;
  9782.  
  9783. return true;
  9784. }
  9785.  
  9786. void Write(bool value)
  9787. {
  9788. if (value)
  9789. {
  9790. m_Data += " 1";
  9791. }
  9792. else
  9793. {
  9794. m_Data += " 0";
  9795. }
  9796. }
  9797.  
  9798. void Write(int value)
  9799. {
  9800. m_Data += " " + value.ToString();
  9801. }
  9802.  
  9803. void Write(float value)
  9804. {
  9805. m_Data += " " + value.ToString();
  9806. }
  9807.  
  9808. void Write(vector value)
  9809. {
  9810. m_Data += " \"" + value.ToString(false) + "\"";
  9811. }
  9812.  
  9813. void Write(string value)
  9814. {
  9815. m_Data += " \"" + value + "\"";
  9816. }
  9817.  
  9818. void _CopyStreamTo(Serializer ctx)
  9819. {
  9820. string data;
  9821. if (m_Data.Length() > 0)
  9822. {
  9823. data = m_Data.Substring(1, m_Data.Length() - 1);
  9824. }
  9825.  
  9826. // force resetting early so we can write the latest version
  9827. _ResetStream();
  9828.  
  9829. ctx.Write(m_HashA);
  9830. ctx.Write(m_HashB);
  9831.  
  9832. ctx.Write(m_Version);
  9833.  
  9834. ctx.Write(data);
  9835. }
  9836.  
  9837. // Read and Write functions can't be called, so we can't reset the stream
  9838. void _ResetStream()
  9839. {
  9840. if (!m_Mod)
  9841. {
  9842. return;
  9843. }
  9844.  
  9845. m_Data = string.Empty;
  9846.  
  9847. m_HashA = m_Mod.m_CF_HashA;
  9848. m_HashB = m_Mod.m_CF_HashB;
  9849.  
  9850. m_Version = m_Mod.GetStorageVersion();
  9851. }
  9852. };
  9853. class CF_ModStorageMap
  9854. {
  9855. autoptr map<string, CF_ModStorage> m_Map = new map<string, CF_ModStorage>();
  9856.  
  9857. CF_ModStorage Get(string name)
  9858. {
  9859. return m_Map[name];
  9860. }
  9861.  
  9862. CF_ModStorage Get(typename type)
  9863. {
  9864. return m_Map[type.ToString()];
  9865. }
  9866.  
  9867. bool Contains(string name)
  9868. {
  9869. return m_Map.Contains(name);
  9870. }
  9871.  
  9872. bool Find(string name, out CF_ModStorage storage)
  9873. {
  9874. return m_Map.Find(name, storage);
  9875. }
  9876.  
  9877. void Insert(string name, CF_ModStorage storage)
  9878. {
  9879. m_Map.Insert(name, storage);
  9880. }
  9881.  
  9882. void Insert(ModStructure mod, CF_ModStorage storage)
  9883. {
  9884. m_Map.Insert(mod.ClassName(), storage);
  9885. }
  9886. };
  9887. /**
  9888. * @class CF_ModStorageModule
  9889. *
  9890. * @brief Does not support unloading CF from the mods. Once loaded it can't be removed
  9891. */
  9892. #ifndef CF_MODSTORAGE_MODULE_DISABLE
  9893. [CF_RegisterModule(CF_ModStorageModule)]
  9894. #endif
  9895. class CF_ModStorageModule : CF_ModuleGame
  9896. {
  9897. static const string m_FileName = "modstorageids.bin";
  9898. protected string m_FilePath;
  9899.  
  9900. protected autoptr map<int, ref map<int, ref map<int, ref map<int, ref Param1<bool>>>>> m_IDs = new map<int, ref map<int, ref map<int, ref map<int, ref Param1<bool>>>>>();
  9901. protected bool m_IsLoaded;
  9902.  
  9903. protected autoptr FileSerializer m_Serializer;
  9904.  
  9905. /**
  9906. * @brief Checks if the persistent ID is in the map. If they aren't in the map then add and write to the file
  9907. */
  9908. void AddEntity(int b1, int b2, int b3, int b4)
  9909. {
  9910. Load();
  9911.  
  9912. if (!_AddEntity(b1, b2, b3, b4, false))
  9913. {
  9914. return;
  9915. }
  9916.  
  9917. m_Serializer.Write(b1);
  9918. m_Serializer.Write(b2);
  9919. m_Serializer.Write(b3);
  9920. m_Serializer.Write(b4);
  9921. }
  9922.  
  9923. /**
  9924. * @brief Checks to see if the persistent ID is loaded
  9925. */
  9926. bool IsEntity(int b1, int b2, int b3, int b4)
  9927. {
  9928. Load();
  9929.  
  9930. auto map_b1 = m_IDs[b1];
  9931. if (!map_b1)
  9932. {
  9933. return false;
  9934. }
  9935.  
  9936. auto map_b2 = map_b1[b2];
  9937. if (!map_b2)
  9938. {
  9939. return false;
  9940. }
  9941.  
  9942. auto map_b3 = map_b2[b3];
  9943. if (!map_b3)
  9944. {
  9945. return false;
  9946. }
  9947.  
  9948. auto val_b4 = map_b3[b4];
  9949. if (!val_b4)
  9950. {
  9951. return false;
  9952. }
  9953.  
  9954. return true;
  9955. }
  9956.  
  9957. /**
  9958. * @brief Reads the modstorage file
  9959. */
  9960. void Load(bool reload = false)
  9961. {
  9962. if (m_IsLoaded && !reload)
  9963. {
  9964. return;
  9965. }
  9966.  
  9967. m_IsLoaded = true;
  9968.  
  9969. int instanceId = g_Game.ServerConfigGetInt("instanceId");
  9970.  
  9971. string folder = "$mission:storage_" + instanceId + "/";
  9972. if (!FileExist(folder))
  9973. {
  9974. MakeDirectory(folder);
  9975. }
  9976.  
  9977. folder += "communityframework/";
  9978. if (!FileExist(folder))
  9979. {
  9980. MakeDirectory(folder);
  9981. }
  9982.  
  9983. m_FilePath = folder + m_FileName;
  9984.  
  9985. if (m_Serializer) m_Serializer.Close();
  9986.  
  9987. // Clear existing ids
  9988. m_IDs.Clear();
  9989.  
  9990. if (FileExist(m_FilePath))
  9991. {
  9992. FileHandle handle = OpenFile(m_FilePath, FileMode.READ);
  9993. if (handle != 0)
  9994. {
  9995. // Reads 4 ints (16 bytes) at a time
  9996. int data[4];
  9997. while (ReadFile(handle, data, 16) > 0)
  9998. {
  9999. _AddEntity(data[0], data[1], data[2], data[3], true);
  10000. }
  10001.  
  10002. CloseFile(handle);
  10003. }
  10004.  
  10005. m_Serializer = new FileSerializer();
  10006. m_Serializer.Open(m_FilePath, FileMode.APPEND);
  10007. }
  10008. else
  10009. {
  10010. m_Serializer = new FileSerializer();
  10011. m_Serializer.Open(m_FilePath, FileMode.WRITE);
  10012. }
  10013. }
  10014.  
  10015. /**
  10016. * @param loaded If the entity was added from the file
  10017. *
  10018. * @return True if newly added entity
  10019. */
  10020. private bool _AddEntity(int b1, int b2, int b3, int b4, bool loaded)
  10021. {
  10022. auto map_b1 = m_IDs[b1];
  10023. if (!map_b1)
  10024. {
  10025. map_b1 = new map<int, ref map<int, ref map<int, ref Param1<bool>>>>();
  10026. m_IDs[b1] = map_b1;
  10027. }
  10028.  
  10029. auto map_b2 = map_b1[b2];
  10030. if (!map_b2)
  10031. {
  10032. map_b2 = new map<int, ref map<int, ref Param1<bool>>>();
  10033. map_b1[b2] = map_b2;
  10034. }
  10035.  
  10036. auto map_b3 = map_b2[b3];
  10037. if (!map_b3)
  10038. {
  10039. map_b3 = new map<int, ref Param1<bool>>();
  10040. map_b2[b3] = map_b3;
  10041. }
  10042.  
  10043. auto val_b4 = map_b3[b4];
  10044. if (!val_b4)
  10045. {
  10046. val_b4 = new Param1<bool>(loaded);
  10047. map_b3[b4] = val_b4;
  10048.  
  10049. return true;
  10050. }
  10051.  
  10052. return false;
  10053. }
  10054. };
  10055. //TODO: Automate into a framework for other modders to use for their own testing
  10056. #ifdef CF_MODSTORAGE_TEST
  10057. class CF_ModStorageTest
  10058. {
  10059. private string _current;
  10060. private int _cpu;
  10061. private int _failed;
  10062.  
  10063. private void CF_ModStorageTest()
  10064. {
  10065. }
  10066.  
  10067. static void Perform()
  10068. {
  10069. CF_ModStorageTest tests = new CF_ModStorageTest();
  10070. tests._Perform();
  10071. }
  10072.  
  10073. static void PerformSingle(string test)
  10074. {
  10075. CF_ModStorageTest tests = new CF_ModStorageTest();
  10076. tests.PerformTest(test);
  10077. }
  10078.  
  10079. protected void Setup(inout array<string> tests)
  10080. {
  10081. tests.Insert("CreateEntity");
  10082. tests.Insert("TestEntity");
  10083. }
  10084.  
  10085. private void _Perform()
  10086. {
  10087. Print("Starting tests");
  10088.  
  10089. array<string> tests = new array<string>();
  10090. Setup(tests);
  10091.  
  10092. _failed = 0;
  10093.  
  10094. int start = TickCount(0);
  10095.  
  10096. for (int i = 0; i < tests.Count(); i++)
  10097. PerformTest(tests[i]);
  10098.  
  10099. int time = TickCount(start);
  10100.  
  10101. Print("\n");
  10102.  
  10103. if (_failed == 0)
  10104. {
  10105. Print("Success. All " + tests.Count() + " passed!");
  10106. }
  10107. else
  10108. {
  10109. Print("Tests failed. " + (tests.Count() - _failed) + "/" + tests.Count() + " passed.");
  10110. }
  10111. }
  10112.  
  10113. private void PerformTest(string method)
  10114. {
  10115. Print("\n");
  10116. Print("Running test \"" + method + "\"");
  10117.  
  10118. _current = method;
  10119.  
  10120. _cpu = TickCount(0);
  10121.  
  10122. GetGame().GameScript.CallFunction(this, _current, null, null);
  10123. }
  10124.  
  10125. private void _assert(string expected, string actual)
  10126. {
  10127. int time = TickCount(_cpu);
  10128. string info = "Test \"" + _current + "\" took " + time + " ticks to execute.";
  10129.  
  10130. Print(" Expected Result: " + expected);
  10131. Print(" Actual Result: " + actual);
  10132.  
  10133. if (expected != actual)
  10134. {
  10135. //Print( " Expected Result: " + expected );
  10136. //Print( " Actual Result: " + actual );
  10137.  
  10138. info = "FAILED: " + info;
  10139.  
  10140. _failed++;
  10141. }
  10142. else
  10143. {
  10144. info = "PASSED: " + info;
  10145. }
  10146.  
  10147. Print("" + info);
  10148. Print("");
  10149. }
  10150.  
  10151. EntityAI object;
  10152.  
  10153. void CreateEntity()
  10154. {
  10155. string objectType = "Apple";
  10156. object = EntityAI.Cast(GetGame().CreateObject(objectType, "0 0 0"));
  10157. }
  10158.  
  10159. void TestEntity()
  10160. {
  10161. object.SetPosition("5 5 0");
  10162. string prev = object.GetDebugName();
  10163.  
  10164. ScriptReadWriteContext ctx = new ScriptReadWriteContext;
  10165.  
  10166. object.OnStoreSave(ctx.GetWriteContext());
  10167. object.OnStoreLoad(ctx.GetReadContext(), GetGame().SaveVersion());
  10168.  
  10169. _assert(prev, object.GetDebugName());
  10170. }
  10171. };
  10172. #endif
  10173. static autoptr CF_ModuleConstructor g_CF_ModuleConstructor = null;
  10174.  
  10175. class CF_ModuleConstructor
  10176. {
  10177. private void CF_ModuleConstructor()
  10178. {
  10179. #ifdef CF_TRACE_ENABLED
  10180. auto trace = CF_Trace_0(this);
  10181. #endif
  10182.  
  10183. CF_ModuleCoreManager._OnCreate();
  10184. }
  10185.  
  10186. /**
  10187. * @note We can safely guarantee the destructor is called on script reload,
  10188. * we can't do the same for 'OnGameDestroy'.
  10189. */
  10190. void ~CF_ModuleConstructor()
  10191. {
  10192. #ifdef CF_TRACE_ENABLED
  10193. auto trace = CF_Trace_0(this);
  10194. #endif
  10195.  
  10196. CF_ModuleCoreManager._OnDestroy();
  10197. }
  10198.  
  10199. [CF_EventSubscriber(ScriptCaller.Create(CF_ModuleConstructor._Init), CF_LifecycleEvents.OnGameCreate)]
  10200. static void _Init()
  10201. {
  10202. if (g_CF_ModuleConstructor)
  10203. {
  10204. return;
  10205. }
  10206.  
  10207. g_CF_ModuleConstructor = new CF_ModuleConstructor();
  10208. }
  10209.  
  10210. [CF_EventSubscriber(ScriptCaller.Create(CF_ModuleConstructor._Cleanup), CF_LifecycleEvents.OnGameDestroy)]
  10211. static void _Cleanup()
  10212. {
  10213. g_CF_ModuleConstructor = null;
  10214. }
  10215. };
  10216. class CF_ModuleGame : CF_ModuleCore
  10217. {
  10218. const static int NETWORKED_VARIABLES_RPC_ID = 435022;
  10219.  
  10220. autoptr CF_InputBindings m_CF_Bindings = new CF_InputBindings(this);
  10221. autoptr CF_NetworkedVariables m_CF_NetworkedVariables = new CF_NetworkedVariables(this);
  10222.  
  10223. int m_CF_RPC_Minimum;
  10224. int m_CF_RPC_Maximum;
  10225.  
  10226. /**
  10227. * @brief Binds a module function to an input
  10228. *
  10229. * @param callback The function within 'm_Instance' to call
  10230. * @param input The name of the input
  10231. * @param preventCallInMenu If the binding can be called while a menu is open
  10232. *
  10233. * @code
  10234. * override void OnInit()
  10235. * {
  10236. * super.OnInit();
  10237. *
  10238. * Bind("Close", "UAUIBack", false);
  10239. * };
  10240. * @endcode
  10241. */
  10242. void Bind(string function, string input, bool limitMenu = false)
  10243. {
  10244. m_CF_Bindings.Bind(function, input, limitMenu);
  10245. }
  10246.  
  10247. /**
  10248. * @brief Binds a module function to an input
  10249. *
  10250. * @param callback The function within 'm_Instance' to call
  10251. * @param input The ID of the input. All inputs found within modded inputs is generated as a global int variable of the same name.
  10252. * @param preventCallInMenu If the binding can be called while a menu is open
  10253. *
  10254. * @code
  10255. * override void OnInit()
  10256. * {
  10257. * super.OnInit();
  10258. *
  10259. * Bind("Close", UAUIBack, false);
  10260. * };
  10261. * @endcode
  10262. */
  10263. void Bind(string function, int input, bool limitMenu = false)
  10264. {
  10265. m_CF_Bindings.Bind(function, input, limitMenu);
  10266. }
  10267.  
  10268. /**
  10269. * @brief Binds a module function to an input
  10270. *
  10271. * @param callback The function within 'm_Instance' to call
  10272. * @param input The name of the input
  10273. * @param preventCallInMenu If the binding can be called while a menu is open
  10274. *
  10275. * @code
  10276. * override void OnInit()
  10277. * {
  10278. * super.OnInit();
  10279. *
  10280. * Bind("Close", "UAUIBack", false);
  10281. * };
  10282. * @endcode
  10283. */
  10284. void Bind(string function, UAInput input, bool limitMenu = false)
  10285. {
  10286. m_CF_Bindings.Bind(function, input, limitMenu);
  10287. }
  10288.  
  10289. /**
  10290. * @brief Binds a module function to an input
  10291. *
  10292. * @param binding The instance of the binding to add to the list
  10293. *
  10294. * @code
  10295. * override void OnInit()
  10296. * {
  10297. * super.OnInit();
  10298. *
  10299. * CF_InputBinding binding = new CF_InputBinding();
  10300. * binding.m_Function = "Close";
  10301. * binding.m_Input = GetUApi().GetInputByID(UAUIBack);
  10302. * binding.m_LimitMenu = false;
  10303. *
  10304. * Bind(binding);
  10305. * };
  10306. * @endcode
  10307. */
  10308. void Bind(CF_InputBinding binding)
  10309. {
  10310. m_CF_Bindings.Bind(binding);
  10311. }
  10312.  
  10313. /**
  10314. * @brief Registers functions into legacy RPCFramework
  10315. */
  10316. void AddLegacyRPC(string funcName, int singlePlayerExecType = SingleplayerExecutionType.Server)
  10317. {
  10318. GetRPCManager().AddRPC(ClassName(), funcName, this, singlePlayerExecType);
  10319. }
  10320.  
  10321. /**
  10322. * @note Only call in 'OnInit'
  10323. */
  10324. bool RegisterNetSyncVariable(string name)
  10325. {
  10326. return m_CF_NetworkedVariables.Register(name);
  10327. }
  10328.  
  10329. void SetSynchDirty()
  10330. {
  10331. // Only the server can send data
  10332. if (!GetGame().IsDedicatedServer())
  10333. {
  10334. // No need to serialize in offline mode, just directly call 'OnVariablesSynchronized'
  10335. if (GetGame().IsServer())
  10336. {
  10337. OnVariablesSynchronized(this, CF_EventArgs.Empty);
  10338. }
  10339.  
  10340. return;
  10341. }
  10342.  
  10343. ScriptRPC rpc = new ScriptRPC();
  10344.  
  10345. rpc.Write(ClassName());
  10346.  
  10347. m_CF_NetworkedVariables.Write(rpc);
  10348.  
  10349. rpc.Send(null, CF_ModuleGame.NETWORKED_VARIABLES_RPC_ID, true, null);
  10350. }
  10351.  
  10352. int GetRPCMin()
  10353. {
  10354. return -1;
  10355. }
  10356.  
  10357. int GetRPCMax()
  10358. {
  10359. return -1;
  10360. }
  10361.  
  10362. void EnableRPC()
  10363. {
  10364. m_CF_RPC_Minimum = GetRPCMin();
  10365. m_CF_RPC_Maximum = GetRPCMax();
  10366.  
  10367. if (m_CF_RPC_Minimum == -1 || m_CF_RPC_Maximum == -1)
  10368. {
  10369. return;
  10370. }
  10371.  
  10372. CF_ModuleGameManager.s_RPC.Add(this);
  10373. }
  10374.  
  10375. /**
  10376. * @deprecated
  10377. */
  10378. void EnableUpdateInput();
  10379.  
  10380. void OnRPC(Class sender, CF_EventArgs args);
  10381.  
  10382. void OnVariablesSynchronized(Class sender, CF_EventArgs args);
  10383. };
  10384.  
  10385. typedef CF_ModuleGame CF_Module;
  10386. class CF_ModuleGameEvent : CF_ModuleCoreEvent
  10387. {
  10388. bool OnRPC(Class sender, CF_EventArgs args)
  10389. {
  10390. CF_EventRPCArgs rpc;
  10391. if (!Class.CastTo(rpc, args))
  10392. {
  10393. return false;
  10394. }
  10395.  
  10396. auto evt = this.m_Next;
  10397. while (evt)
  10398. {
  10399. auto module = CF_ModuleGame.Cast(evt.m_Value);
  10400.  
  10401. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0 && (module.m_CF_RPC_Minimum <= rpc.ID && rpc.ID < module.m_CF_RPC_Maximum))
  10402. {
  10403. module.OnRPC(sender, rpc);
  10404. return true;
  10405. }
  10406.  
  10407. evt = evt.m_Next;
  10408. }
  10409.  
  10410. return false;
  10411. }
  10412. };
  10413. class CF_ModuleGameManager
  10414. {
  10415. static ref CF_ModuleGameEvent s_RPC = new CF_ModuleGameEvent();
  10416.  
  10417. /**
  10418. * @brief Updates the flag for event calling. So server side modules don't get the event called on client and same for client side on server.
  10419. *
  10420. * @param game Passes in the CGame/DayZGame instance. If none provided, automatically obtains from global 'g_Game' variable
  10421. */
  10422. static void UpdateGameFlag(CGame game = null)
  10423. {
  10424. if (game == null)
  10425. {
  10426. game = g_Game;
  10427. }
  10428.  
  10429. // 0xFF = Single Player
  10430. // 0x0F = Client
  10431. // 0xF0 = Dedicated Server
  10432. CF_ModuleCoreManager.s_GameFlag = 0xFF;
  10433. if (game.IsMultiplayer())
  10434. {
  10435. CF_ModuleCoreManager.s_GameFlag = 0x0F;
  10436. if (game.IsServer())
  10437. {
  10438. CF_ModuleCoreManager.s_GameFlag = 0xF0;
  10439. }
  10440. }
  10441. }
  10442.  
  10443. static bool OnRPC(Class sender, CF_EventArgs args)
  10444. {
  10445. return s_RPC.OnRPC(sender, args);
  10446. }
  10447.  
  10448. static void OnUpdate(Class sender, CF_EventArgs args)
  10449. {
  10450. UpdateGameFlag();
  10451.  
  10452. CF_ModuleCoreManager.s_Update.OnUpdate(sender, args);
  10453.  
  10454. delete args;
  10455. }
  10456. };
  10457. /**
  10458. * @class JMModuleManagerBase
  10459. *
  10460. * @deprecated
  10461. */
  10462. class JMModuleManagerBase
  10463. {
  10464. protected bool m_PreventModuleBindings;
  10465.  
  10466. bool IsPreventingModuleBindings()
  10467. {
  10468. m_PreventModuleBindings = CF_ModuleGame.s_PreventInput;
  10469. return CF_ModuleGame.s_PreventInput;
  10470. }
  10471.  
  10472. void SetPreventModuleBindings(bool prevent)
  10473. {
  10474. CF_ModuleGame.s_PreventInput = prevent;
  10475. m_PreventModuleBindings = CF_ModuleGame.s_PreventInput;
  10476. }
  10477.  
  10478. void InitModules()
  10479. {
  10480. // does nothing
  10481. }
  10482.  
  10483. void Print_DumpModules()
  10484. {
  10485. // does nothing
  10486. }
  10487.  
  10488. void OnSettingsUpdated()
  10489. {
  10490. CF_ModuleCoreManager.OnSettingsChanged(this, CF_EventArgs.Empty);
  10491. }
  10492.  
  10493. void OnClientPermissionsUpdated()
  10494. {
  10495. CF_ModuleCoreManager.OnPermissionsChanged(this, CF_EventArgs.Empty);
  10496. }
  10497.  
  10498. void OnInit()
  10499. {
  10500. // does nothing
  10501. }
  10502.  
  10503. void OnMissionStart()
  10504. {
  10505. CF_ModuleCoreManager.OnMissionStart(this, CF_EventArgs.Empty);
  10506. }
  10507.  
  10508. void OnMissionFinish()
  10509. {
  10510. CF_ModuleCoreManager.OnMissionFinish(this, CF_EventArgs.Empty);
  10511. }
  10512.  
  10513. void OnMissionLoaded()
  10514. {
  10515. CF_ModuleCoreManager.OnMissionLoaded(this, CF_EventArgs.Empty);
  10516. }
  10517.  
  10518. void OnRPC(PlayerIdentity sender, Object target, int rpc_type, ParamsReadContext ctx)
  10519. {
  10520. auto args = new CF_EventRPCArgs();
  10521. args.Sender = sender;
  10522. args.Target = target;
  10523. args.ID = rpc_type;
  10524. args.Context = ctx;
  10525. CF_ModuleGameManager.OnRPC(this, args);
  10526. }
  10527.  
  10528. void OnUpdate(float timeslice)
  10529. {
  10530. CF_ModuleGameManager.OnUpdate(this, new CF_EventUpdateArgs(timeslice));
  10531. }
  10532.  
  10533. void OnWorldCleanup()
  10534. {
  10535. CF_ModuleCoreManager.OnWorldCleanup(this, CF_EventArgs.Empty);
  10536. }
  10537.  
  10538. void OnMPSessionStart()
  10539. {
  10540. CF_ModuleCoreManager.OnMPSessionStart(this, CF_EventArgs.Empty);
  10541. }
  10542.  
  10543. void OnMPSessionPlayerReady()
  10544. {
  10545. CF_ModuleCoreManager.OnMPSessionPlayerReady(this, CF_EventArgs.Empty);
  10546. }
  10547.  
  10548. void OnMPSessionFail()
  10549. {
  10550. CF_ModuleCoreManager.OnMPSessionFail(this, CF_EventArgs.Empty);
  10551. }
  10552.  
  10553. void OnMPSessionEnd()
  10554. {
  10555. CF_ModuleCoreManager.OnMPSessionEnd(this, CF_EventArgs.Empty);
  10556. }
  10557.  
  10558. void OnMPConnectAbort()
  10559. {
  10560. CF_ModuleCoreManager.OnMPConnectAbort(this, CF_EventArgs.Empty);
  10561. }
  10562.  
  10563. void OnMPConnectionLost(int duration)
  10564. {
  10565. CF_ModuleCoreManager.OnMPConnectionLost(this, new CF_EventTimeArgs(duration));
  10566. }
  10567.  
  10568. void OnRespawn(int time)
  10569. {
  10570. CF_ModuleCoreManager.OnRespawn(this, new CF_EventTimeArgs(time));
  10571. }
  10572. }
  10573.  
  10574. ref JMModuleManagerBase g_cf_ModuleManager = NULL;
  10575.  
  10576. static void DestroyModuleManager()
  10577. {
  10578. delete g_cf_ModuleManager;
  10579. }
  10580.  
  10581. static bool ModuleManagerExists()
  10582. {
  10583. return g_cf_ModuleManager != NULL;
  10584. }
  10585. class CF_NetworkedVariables
  10586. {
  10587. const static int MAX_COUNT = 256;
  10588.  
  10589. int m_Count;
  10590.  
  10591. ref CF_NetworkVariable m_Head;
  10592. CF_NetworkVariable m_Tail;
  10593.  
  10594. Class m_Instance;
  10595.  
  10596. void CF_NetworkedVariables(Class instance)
  10597. {
  10598. m_Instance = instance;
  10599. }
  10600.  
  10601. string ErrorPrefix()
  10602. {
  10603. return "(" + m_Instance + ") " + this + "::";
  10604. }
  10605.  
  10606. bool Register(string name)
  10607. {
  10608. // hard limit, no point attempting to sync more variables
  10609. if (m_Count >= MAX_COUNT)
  10610. {
  10611. CF_Log.Error(ErrorPrefix() + "Register('" + name + "') -> More than " + MAX_COUNT + " variables registered, got '" + m_Count + "'");
  10612. return false;
  10613. }
  10614.  
  10615. CF_NetworkVariable variable = new CF_NetworkVariable();
  10616.  
  10617. typename type = m_Instance.Type();
  10618. array<string> tokens();
  10619. name.Split(".", tokens);
  10620.  
  10621. variable.m_Name = name;
  10622.  
  10623. if (tokens.Count() != 0)
  10624. {
  10625. if (tokens.Count() >= CF_NetworkVariable.MAX_DEPTH - 1)
  10626. {
  10627. CF_Log.Error(ErrorPrefix() + "RegisterNetSyncVariable('" + name + "') -> Variable depth more than " + (CF_NetworkVariable.MAX_DEPTH - 1) + ", got '" + tokens.Count() + "'");
  10628. return false;
  10629. }
  10630.  
  10631. variable.m_Name = tokens[tokens.Count() - 1];
  10632.  
  10633. int i, j;
  10634.  
  10635. // iterate over all tokens to get the sub class for the variable
  10636. for (i = 0; i < tokens.Count() - 1; i++)
  10637. {
  10638. bool success = false;
  10639. for (j = 0; j < type.GetVariableCount(); j++)
  10640. {
  10641. if (type.GetVariableName(j) == tokens[i])
  10642. {
  10643. type = type.GetVariableType(j);
  10644.  
  10645. variable.m_AccessorIndices[variable.m_Count] = j;
  10646. variable.m_AccessorTypes[variable.m_Count] = type;
  10647. variable.m_Count++;
  10648.  
  10649. success = true;
  10650.  
  10651. break;
  10652. }
  10653. }
  10654.  
  10655. // couldn't find sub variable
  10656. if (!success)
  10657. {
  10658. Error(ErrorPrefix() + "RegisterNetSyncVariable('" + name + "') -> Couldn't find sub variable '" + tokens[i] + "'");
  10659. return false;
  10660. }
  10661. }
  10662. }
  10663.  
  10664. for (j = 0; j < type.GetVariableCount(); j++)
  10665. {
  10666. if (type.GetVariableName(j) == variable.m_Name)
  10667. {
  10668. type = type.GetVariableType(j);
  10669.  
  10670. variable.m_AccessorIndices[variable.m_Count] = j;
  10671. variable.m_AccessorTypes[variable.m_Count] = type;
  10672. variable.m_Count++;
  10673.  
  10674. variable.m_Converter = CF_TypeConverter.Get(type);
  10675.  
  10676. if (!variable.m_Converter)
  10677. {
  10678. CF_Log.Error(ErrorPrefix() + "RegisterNetSyncVariable('" + name + "') -> TypeConverter not found for type '" + type + "'");
  10679. return false;
  10680. }
  10681.  
  10682. if (!m_Tail)
  10683. {
  10684. m_Head = variable;
  10685. m_Tail = variable;
  10686. }
  10687. else
  10688. {
  10689. m_Tail.m_Next = variable;
  10690. m_Tail = variable;
  10691. }
  10692.  
  10693. m_Count++;
  10694.  
  10695. return true;
  10696. }
  10697. }
  10698.  
  10699. CF_Log.Error(ErrorPrefix() + "RegisterNetSyncVariable('" + name + "') -> Couldn't find variable '" + variable.m_Name + "'");
  10700. return false;
  10701. }
  10702.  
  10703. void Write(ParamsWriteContext ctx)
  10704. {
  10705. CF_NetworkVariable variable = m_Head;
  10706. while (variable)
  10707. {
  10708. Class instance = m_Instance;
  10709.  
  10710. int index = variable.m_Count - 1;
  10711.  
  10712. for (int j = 0; j < index; j++)
  10713. {
  10714. if (!instance)
  10715. {
  10716. break;
  10717. }
  10718.  
  10719. variable.m_AccessorTypes[j].GetVariableValue(instance, variable.m_AccessorIndices[j], instance);
  10720. }
  10721.  
  10722. if (instance)
  10723. {
  10724. variable.m_Converter.Read(instance, variable.m_AccessorIndices[index]);
  10725. }
  10726.  
  10727. // attempt writing even if instance is null so the count remains the same in sync
  10728. variable.m_Converter.Write(ctx);
  10729.  
  10730. variable = variable.m_Next;
  10731. }
  10732. }
  10733.  
  10734. void Read(ParamsReadContext ctx)
  10735. {
  10736. CF_NetworkVariable variable = m_Head;
  10737. while (variable)
  10738. {
  10739. Class instance = m_Instance;
  10740.  
  10741. for (int j = 0; j < variable.m_Count - 1; j++)
  10742. {
  10743. if (!instance)
  10744. {
  10745. break;
  10746. }
  10747.  
  10748. variable.m_AccessorTypes[j].GetVariableValue(instance, variable.m_AccessorIndices[j], instance);
  10749. }
  10750.  
  10751. // attempt reading even if instance is null so the count remains the same in sync
  10752. variable.m_Converter.Read(ctx);
  10753.  
  10754. if (instance)
  10755. {
  10756. variable.m_Converter.Write(instance, variable.m_Name);
  10757. }
  10758.  
  10759. variable = variable.m_Next;
  10760. }
  10761. }
  10762. };
  10763. class CF_NetworkVariable
  10764. {
  10765. static const int MAX_DEPTH = 4;
  10766.  
  10767. ref CF_NetworkVariable m_Next;
  10768.  
  10769. string m_Name;
  10770.  
  10771. int m_Count; // MAX_DEPTH
  10772. int m_AccessorIndices[MAX_DEPTH];
  10773. typename m_AccessorTypes[MAX_DEPTH];
  10774.  
  10775. CF_TypeConverterBase m_Converter;
  10776. };
  10777. modded class NotificationRuntimeData
  10778. {
  10779. string m_Icon;
  10780. string m_TitleText;
  10781.  
  10782. int m_Color;
  10783.  
  10784. bool m_HasShown;
  10785.  
  10786. void NotificationRuntimeData( float time, NotificationData data, string detail_text )
  10787. {
  10788. m_StaticData = data;
  10789. m_Icon = data.m_Icon;
  10790. m_TitleText = data.m_TitleText;
  10791.  
  10792. if ( detail_text != "" )
  10793. {
  10794. m_DetailText = detail_text;
  10795. } else
  10796. {
  10797. m_DetailText = m_StaticData.m_DescriptionText;
  10798. }
  10799.  
  10800. m_Color = ARGB( 255, 221, 38, 38 );
  10801. m_NotificationTime = time + NOTIFICATION_FADE_TIME;
  10802. }
  10803.  
  10804. void SetColor( int color )
  10805. {
  10806. m_Color = color;
  10807. }
  10808.  
  10809. int GetColor()
  10810. {
  10811. return m_Color;
  10812. }
  10813.  
  10814. override string GetIcon()
  10815. {
  10816. return m_Icon;
  10817. }
  10818.  
  10819. override string GetTitleText()
  10820. {
  10821. return m_TitleText;
  10822. }
  10823. }enum NotificationSystemRPC
  10824. {
  10825. INVALID = 9000,
  10826. Create,
  10827. COUNT
  10828. };
  10829.  
  10830. modded class NotificationSystem
  10831. {
  10832. /**
  10833. * Sending of the notification
  10834. *
  10835. * If on the client it will create the notification, otherwise on the server it sends the notification to the specified client(s)
  10836. *
  10837. * @param title A localised supported way of creating a notification
  10838. * @param text A localised supported way of creating a notification
  10839. * @param icon The icon the notification will use
  10840. * @param color The colour of the notification
  10841. * @param time How long the notification will stay on the screen for (in seconds)
  10842. * @param sendTo The player to send the notification to (everyone if NULL)
  10843. */
  10844. static void Create( StringLocaliser title, StringLocaliser text, string icon, int color, float time = 3, PlayerIdentity sendTo = NULL )
  10845. {
  10846. CreateNotification( title, text, icon, color, time, sendTo );
  10847. }
  10848.  
  10849. /**
  10850. * Sending of the notification
  10851. *
  10852. * If on the client it will create the notification, otherwise on the server it sends the notification to the specified client(s)
  10853. *
  10854. * @param title A localised supported way of creating a notification
  10855. * @param text A localised supported way of creating a notification
  10856. * @param icon The icon the notification will use
  10857. * @param color The colour of the notification
  10858. * @param time How long the notification will stay on the screen for (in seconds)
  10859. * @param sendTo The player to send the notification to (everyone if NULL)
  10860. */
  10861. static void CreateNotification( StringLocaliser title, StringLocaliser text, string icon, int color, float time = 3, PlayerIdentity sendTo = NULL )
  10862. {
  10863. if ( IsMissionHost() )
  10864. {
  10865. ScriptRPC rpc = new ScriptRPC();
  10866. rpc.Write( title );
  10867. rpc.Write( text );
  10868. rpc.Write( icon );
  10869. rpc.Write( color );
  10870. rpc.Write( time );
  10871. rpc.Send( NULL, NotificationSystemRPC.Create, true, sendTo );
  10872. } else
  10873. {
  10874. Exec_CreateNotification( title, text, icon, color, time );
  10875. }
  10876. }
  10877.  
  10878. /**
  10879. * Creation of the notification
  10880. *
  10881. * @param title A localised supported way of creating a notification
  10882. * @param text A localised supported way of creating a notification
  10883. * @param icon The icon the notification will use
  10884. * @param color The colour of the notification
  10885. * @param time How long the notification will stay on the screen for (in seconds)
  10886. */
  10887. private static void Exec_CreateNotification( StringLocaliser title, StringLocaliser text, string icon, int color, float time )
  10888. {
  10889. NotificationRuntimeData data = new NotificationRuntimeData( time, new NotificationData( icon, title.Format() ), text.Format() );
  10890. data.SetColor( color );
  10891.  
  10892. m_Instance.AddNotif( data );
  10893. }
  10894.  
  10895. /**
  10896. * An RPC handler for the data that is to be read from the notification.
  10897. *
  10898. * @param sender Always NULL
  10899. * @param target Always NULL
  10900. * @param ctx The data container for the rpc
  10901. */
  10902. static void RPC_CreateNotification( PlayerIdentity sender, Object target, ParamsReadContext ctx )
  10903. {
  10904. StringLocaliser title = new StringLocaliser( "" );
  10905. if ( !ctx.Read( title ) )
  10906. return;
  10907.  
  10908. StringLocaliser text = new StringLocaliser( "" );
  10909. if ( !ctx.Read( text ) )
  10910. return;
  10911.  
  10912. string icon;
  10913. if ( !ctx.Read( icon ) )
  10914. return;
  10915.  
  10916. int color;
  10917. if ( !ctx.Read( color ) )
  10918. return;
  10919.  
  10920. float time;
  10921. if ( !ctx.Read( time ) )
  10922. return;
  10923.  
  10924. Exec_CreateNotification( title, text, icon, color, time );
  10925. }
  10926.  
  10927. /**
  10928. * Adds the notification to the deferred array or displays it if
  10929. * the maximum has not yet been reached.
  10930. *
  10931. * @param data The notification data to be displayed
  10932. */
  10933. protected void AddNotif( NotificationRuntimeData data )
  10934. {
  10935. if ( m_TimeArray.Count() < MAX_NOTIFICATIONS )
  10936. {
  10937. float time = GetGame().GetTickTime() + data.GetTime();
  10938. data.SetTime( time + NOTIFICATION_FADE_TIME );
  10939.  
  10940. m_TimeArray.Insert( data );
  10941. m_OnNotificationAdded.Invoke( data );
  10942. }
  10943. else
  10944. {
  10945. m_DeferredArray.Insert( data );
  10946. }
  10947. }
  10948.  
  10949. /**
  10950. * Vanilla code to get the pre-created notification based on the type
  10951. *
  10952. * Required to create due to how Enforce Script modding works
  10953. *
  10954. * @param type The notification type
  10955. */
  10956. override NotificationData GetNotificationData( NotificationType type )
  10957. {
  10958. if ( m_DataArray.Contains( type ) )
  10959. {
  10960. return m_DataArray.Get( type );
  10961. }
  10962.  
  10963. return null;
  10964. }
  10965.  
  10966. /**
  10967. * Vanilla code to get the pre-created notification based on the type
  10968. *
  10969. * Required to create due to how Enforce Script modding works
  10970. *
  10971. * @param type The notification type
  10972. */
  10973. override static void AddNotification( NotificationType type, float show_time, string detail_text = "" )
  10974. {
  10975. NotificationRuntimeData data = new NotificationRuntimeData( show_time, m_Instance.GetNotificationData( type ), detail_text );
  10976.  
  10977. m_Instance.AddNotif( data );
  10978. }
  10979.  
  10980. override static void AddNotificationExtended( float show_time, string title_text, string detail_text = "", string icon = "" )
  10981. {
  10982. NotificationData temp_data = new NotificationData( icon, title_text );
  10983. NotificationRuntimeData data = new NotificationRuntimeData( show_time, temp_data, detail_text );
  10984.  
  10985. m_Instance.AddNotif( data );
  10986. }
  10987. };
  10988. class CF_ObjectManager_ObjectLink extends OLinkT
  10989. {
  10990. int flags;
  10991. int eventMask;
  10992. }
  10993.  
  10994. class CF_ObjectManager
  10995. {
  10996. //!Single static instance. Do not create with new or spawn - use CF.ObjectManager for access instead.
  10997. protected void CF_ObjectManager()
  10998. {
  10999. #ifdef CF_TRACE_ENABLED
  11000. auto trace = CF_Trace_0(this);
  11001. #endif
  11002. }
  11003.  
  11004. protected void ~CF_ObjectManager()
  11005. {
  11006. #ifdef CF_TRACE_ENABLED
  11007. auto trace = CF_Trace_0(this);
  11008. #endif
  11009. }
  11010.  
  11011. protected static const int HIDE_OBJECT_AXIS_OFFSET = 10000;
  11012.  
  11013. protected static const ref map<Object, ref CF_ObjectManager_ObjectLink> m_HiddenObjects = new map<Object, ref CF_ObjectManager_ObjectLink>();
  11014.  
  11015. protected static const ref array<ref CF_ObjectManager_ObjectLink> m_HiddenObjectsArray = new array<ref CF_ObjectManager_ObjectLink>();
  11016.  
  11017. /**
  11018. * @brief Hides a static map object (Houses, Vegetation, etc.) visually and physically.
  11019. * @code
  11020. * Object hidden = CF.ObjectManager.HideMapObject(object);
  11021. * @endcode
  11022. *
  11023. * @param object Object to be hidden
  11024. * @param updatePathGraph Performs a path graph update after the object has been hidden. Enabled by default.
  11025. * @return Object instance of the object that was hidden, NULL in case of failure or invalid params.
  11026. */
  11027. static Object HideMapObject(Object object, bool updatePathGraph = true)
  11028. {
  11029. if (!IsMapObject(object)) return NULL; //Object is not a map object
  11030.  
  11031. if (IsMapObjectHidden(object)) return NULL; //Object already hidden
  11032.  
  11033. //Remember the original position for path graph updates
  11034. auto originalPosition = object.GetPosition();
  11035.  
  11036. //Register object in it's current state
  11037. auto link = new CF_ObjectManager_ObjectLink(object);
  11038. link.flags = object.GetFlags();
  11039. link.eventMask = object.GetEventMask();
  11040.  
  11041. object.ClearFlags(link.flags, true);
  11042. object.ClearEventMask(link.eventMask);
  11043.  
  11044. m_HiddenObjects.Set(object, link);
  11045. m_HiddenObjectsArray.Insert(link);
  11046.  
  11047. vector tm[4];
  11048. object.GetTransform(tm);
  11049. tm[3] = tm[3] - Vector(HIDE_OBJECT_AXIS_OFFSET, HIDE_OBJECT_AXIS_OFFSET, HIDE_OBJECT_AXIS_OFFSET);
  11050. object.SetTransform(tm);
  11051. object.Update();
  11052.  
  11053. if (updatePathGraph && object.CanAffectPathgraph())
  11054. {
  11055. vector minMax[2];
  11056. auto objectRadius = object.ClippingInfo(minMax);
  11057. auto radiusVector = Vector(objectRadius, objectRadius, objectRadius);
  11058. g_Game.UpdatePathgraphRegion(originalPosition - radiusVector, originalPosition + radiusVector);
  11059. }
  11060.  
  11061. return object;
  11062. }
  11063.  
  11064. /**
  11065. * @brief Unhides an array of map objects
  11066. * @code
  11067. * array<Object> hidden = CF.ObjectManager.HideMapObjects(objects);
  11068. * @endcode
  11069. *
  11070. * @param objects Objects to be hidden
  11071. * @param updatePathGraph Performs a path graph update after the objects were hidden. Enabled by default.
  11072. * @return array<Object> Array of objects that were hidden.
  11073. */
  11074. static array<Object> HideMapObjects(array<Object> objects, bool updatePathGraph = true)
  11075. {
  11076. array<Object> hidden();
  11077.  
  11078. foreach (auto object: objects)
  11079. {
  11080. /*
  11081. Todo potential improvement:
  11082. Determine if a single path graph update over the whole area is more effective that many small ones.
  11083. Possible metrics:
  11084. - Object count to area ratio
  11085. - Max distance between objects
  11086. - Fixed radius lookup table
  11087. */
  11088. if (HideMapObject(object, updatePathGraph))
  11089. {
  11090. hidden.Insert(object);
  11091. }
  11092. }
  11093.  
  11094. return hidden;
  11095. }
  11096.  
  11097. /**
  11098. * @brief Hides static map objects at certain position and within a given radius
  11099. * @code
  11100. * array<Object> hidden = CF.ObjectManager.HideMapObjectsInRadius(position, 1000);
  11101. * @endcode
  11102. *
  11103. * @param centerPosition center coordinates for the hide area.
  11104. * @param radius radius of the hide area.
  11105. * @param limitHeight y-axis limit for the hide area (Sphere). Disabled by default.
  11106. * @param updatePathGraph Performs a path graph update after the objects were hidden. Enabled by default.
  11107. * @return array<Object> Array of objects that were hidden.
  11108. */
  11109. static array<Object> HideMapObjectsInRadius(vector centerPosition, float radius, bool limitHeight = false, bool updatePathGraph = true)
  11110. {
  11111. array<Object> objects();
  11112.  
  11113. if (limitHeight)
  11114. {
  11115. GetGame().GetObjectsAtPosition3D(centerPosition, radius, objects, NULL);
  11116. }
  11117. else
  11118. {
  11119. GetGame().GetObjectsAtPosition(centerPosition, radius, objects, NULL);
  11120. }
  11121.  
  11122. array<Object> hidden();
  11123.  
  11124. foreach (auto object: objects)
  11125. {
  11126. //Todo potential improvement -> s. HideMapObjects
  11127. if (HideMapObject(object, updatePathGraph))
  11128. {
  11129. hidden.Insert(object);
  11130. }
  11131. }
  11132.  
  11133. return hidden;
  11134. }
  11135.  
  11136. /**
  11137. * @brief Unhides a hidden static map object (Houses, Vegetation, etc.).
  11138. * @code
  11139. * Object unhidden = CF.ObjectManager.UnhideMapObject(hiddenObject);
  11140. * @endcode
  11141. *
  11142. * @param object Object to be unhidden
  11143. * @param updatePathGraph Performs a path graph update after the object has been unhidden. Enabled by default.
  11144. * @return Object instance of the object that was unhidden, NULL in case of failure or invalid params.
  11145. */
  11146. static Object UnhideMapObject(Object object, bool updatePathGraph = true)
  11147. {
  11148. //Remove object from hidden collection
  11149. auto link = m_HiddenObjects[object];
  11150.  
  11151. if (!link) return NULL; //Object not known as hidden
  11152.  
  11153. m_HiddenObjects.Remove(object);
  11154.  
  11155. auto arrayIdx = m_HiddenObjectsArray.Find(link);
  11156. if(arrayIdx >= 0) m_HiddenObjectsArray.Remove(arrayIdx);
  11157.  
  11158. vector tm[4];
  11159. object.GetTransform(tm);
  11160. tm[3] = tm[3] + Vector(HIDE_OBJECT_AXIS_OFFSET, HIDE_OBJECT_AXIS_OFFSET, HIDE_OBJECT_AXIS_OFFSET);
  11161. object.SetTransform(tm);
  11162.  
  11163. object.SetFlags(link.flags, true);
  11164. object.SetEventMask(link.eventMask);
  11165.  
  11166. object.Update();
  11167.  
  11168. if (updatePathGraph && object.CanAffectPathgraph())
  11169. {
  11170. vector minMax[2];
  11171. auto objectPosition = object.GetPosition();
  11172. auto objectRadius = object.ClippingInfo(minMax);
  11173. auto radiusVector = Vector(objectRadius, objectRadius, objectRadius);
  11174. g_Game.UpdatePathgraphRegion(objectPosition - radiusVector, objectPosition + radiusVector);
  11175. }
  11176.  
  11177. return object;
  11178. }
  11179.  
  11180. /**
  11181. * @brief Unhides an array of map objects
  11182. * @code
  11183. * array<Object> unhidden = CF.ObjectManager.UnhideMapObjects(hiddenObjects);
  11184. * @endcode
  11185. *
  11186. * @param objects Objects to be unhidden
  11187. * @param updatePathGraph Performs a path graph update after the objects were unhidden. Enabled by default.
  11188. * @return array<Object> Array of objects that were unhidden.
  11189. */
  11190. static array<Object> UnhideMapObjects(array<Object> objects, bool updatePathGraph = true)
  11191. {
  11192. array<Object> unhidden();
  11193.  
  11194. foreach (auto object: objects)
  11195. {
  11196. //Todo potential improvement -> s. HideMapObjects
  11197. if (UnhideMapObject(object, updatePathGraph))
  11198. {
  11199. unhidden.Insert(object);
  11200. }
  11201. }
  11202.  
  11203. return unhidden;
  11204. }
  11205.  
  11206. /**
  11207. * @brief Unhides static map objects at certain position and within a given radius
  11208. * @code
  11209. * array<Object> unhidden = CF.ObjectManager.UnhideMapObjectsInRadius(position, 1000);
  11210. * @endcode
  11211. *
  11212. * @param centerPosition center coordinates for the unhide area.
  11213. * @param radius radius of the unhide area.
  11214. * @param limitHeight y-axis limit for the unhide area (Sphere). Disabled by default.
  11215. * @param updatePathGraph Performs a path graph update after the objects were unhidden. Enabled by default.
  11216. * @return array<Object> Array of objects that were unhidden.
  11217. */
  11218. static array<Object> UnhideMapObjectsInRadius(vector centerPosition, float radius, bool limitHeight = false, bool updatePathGraph = true)
  11219. {
  11220. array<Object> objects();
  11221.  
  11222. if (limitHeight)
  11223. {
  11224. GetGame().GetObjectsAtPosition3D(centerPosition, radius, objects, NULL);
  11225. }
  11226. else
  11227. {
  11228. GetGame().GetObjectsAtPosition(centerPosition, radius, objects, NULL);
  11229. }
  11230.  
  11231. return UnhideMapObjects(objects, updatePathGraph);
  11232. }
  11233.  
  11234. /**
  11235. * @brief Unhides all hidden map objects
  11236. * @code
  11237. * array<Object> unhidden = CF.ObjectManager.UnhideAllMapObjects();
  11238. * @endcode
  11239. *
  11240. * @param updatePathGraph Performs a path graph update after the objects were unhidden. Enabled by default.
  11241. * @return array<Object> Array of objects that were unhidden.
  11242. */
  11243. static array<Object> UnhideAllMapObjects(bool updatePathGraph = true)
  11244. {
  11245. //Expected result would be all the hidden objects
  11246. auto unhidden = GetHiddenMapObjects();
  11247.  
  11248. for(int nObject = 0; nObject < unhidden.Count(); nObject++)
  11249. {
  11250. //Todo potential improvement -> s. HideMapObjects
  11251. if (!UnhideMapObject(unhidden[nObject], updatePathGraph))
  11252. {
  11253. //If - for what ever reason - the object was not unhidden, remove it from the result collection.
  11254. unhidden.RemoveOrdered(nObject--);
  11255. }
  11256. }
  11257.  
  11258. return unhidden;
  11259. }
  11260.  
  11261. /**
  11262. * @brief Returns all map objects that are currently hidden
  11263. * @code
  11264. * array<Object> objects = CF.ObjectManager.GetHiddenMapObjects();
  11265. * @endcode
  11266. *
  11267. * @return array<Object> Array of hidden objects.
  11268. */
  11269. static array<Object> GetHiddenMapObjects()
  11270. {
  11271. array<Object> objects();
  11272.  
  11273. foreach(auto link : m_HiddenObjectsArray)
  11274. {
  11275. objects.Insert(link.Ptr());
  11276. }
  11277.  
  11278. return objects;
  11279. }
  11280.  
  11281. /**
  11282. * @brief Checks if a map object is currently hidden.
  11283. * @code
  11284. * bool isHiddenObject = CF.ObjectManager.IsMapObjectHidden(object);
  11285. * @endcode
  11286. *
  11287. * @param object Object to check
  11288. * @return bool true if currently hidden, false otherwise.
  11289. */
  11290. static bool IsMapObjectHidden(Object object)
  11291. {
  11292. return m_HiddenObjects.Contains(object);
  11293. }
  11294.  
  11295. /**
  11296. * @brief Checks if the given object is part of the baked map objects.
  11297. * @code
  11298. * bool isMapObject = CF.ObjectManager.IsMapObject(object);
  11299. * @endcode
  11300. *
  11301. * @param object Object pointer
  11302. * @return bool true if it is a map object, false otherwise.
  11303. */
  11304. static bool IsMapObject(Object object)
  11305. {
  11306. if (!object) return false; //Null
  11307.  
  11308. // Added via p3d in TB with no config.
  11309. // Inherits from House in Cfg class -> Building, House, Wreck, Well, Tree, Bush, etc.
  11310. return ((object.GetType() == string.Empty) && (object.Type() == Object)) || object.IsKindOf("House") || object.IsTree() || object.IsBush() || object.IsRock() || object.IsInherited(Static);
  11311. }
  11312.  
  11313. /**
  11314. * @brief [Internal] CommunityFramework cleanup
  11315. *
  11316. * @return void
  11317. */
  11318. static void _Cleanup()
  11319. {
  11320. //Cleanup hidden object allocation
  11321. m_HiddenObjects.Clear();
  11322. delete m_HiddenObjects;
  11323.  
  11324. m_HiddenObjectsArray.Clear();
  11325. delete m_HiddenObjectsArray;
  11326. }
  11327. }
  11328. enum SingeplayerExecutionType
  11329. {
  11330. Server = 0,
  11331. Client,
  11332. Both
  11333. }
  11334.  
  11335. enum SingleplayerExecutionType
  11336. {
  11337. Server = 0,
  11338. Client,
  11339. Both
  11340. }
  11341.  
  11342. enum CallType
  11343. {
  11344. Server = 0,
  11345. Client
  11346. }
  11347.  
  11348. class RPCMetaWrapper
  11349. {
  11350. protected Class m_Instance;
  11351. protected int m_SPExecType;
  11352.  
  11353. void RPCMetaWrapper( Class instance, int spExecType )
  11354. {
  11355. m_Instance = instance;
  11356.  
  11357. m_SPExecType = spExecType;
  11358. }
  11359.  
  11360. Class GetInstance()
  11361. {
  11362. return m_Instance;
  11363. }
  11364.  
  11365. // Determines if the server or client function is what is called in singleplayer mode
  11366. int GetSPExecutionType()
  11367. {
  11368. return m_SPExecType;
  11369. }
  11370. };
  11371.  
  11372. class RPCManager
  11373. {
  11374. static const int FRAMEWORK_RPC_ID = 10042;
  11375.  
  11376. protected autoptr map< string, ref map< string, ref RPCMetaWrapper > > m_RPCActions = new map< string, ref map< string, ref RPCMetaWrapper > >;
  11377.  
  11378. void OnRPC( PlayerIdentity sender, Object target, int rpc_type, ParamsReadContext ctx )
  11379. {
  11380. #ifdef CF_TRACE_ENABLED
  11381. auto trace = CF_Trace_4(this).Add(sender).Add(target).Add(rpc_type).Add(ctx);
  11382. #endif
  11383.  
  11384. Param2< string, string > metaData;
  11385. if ( !ctx.Read( metaData ) )
  11386. {
  11387. CF_Log.Warn( "Failed reading the RPC metadata!");
  11388. return;
  11389. }
  11390.  
  11391. string modName = metaData.param1;
  11392. string funcName = metaData.param2;
  11393.  
  11394. string recievedFrom = "server";
  11395. if ( GetGame().IsDedicatedServer() )
  11396. {
  11397. if ( sender == NULL )
  11398. {
  11399. CF_Log.Warn( "RPC sent from invalid sender!");
  11400. return;
  11401. }
  11402.  
  11403. recievedFrom = sender.GetPlainId();
  11404. }
  11405.  
  11406. map< string, ref RPCMetaWrapper > functions;
  11407. if ( m_RPCActions.Find( modName, functions ) )
  11408. {
  11409. RPCMetaWrapper wrapper;
  11410. if ( functions.Find( funcName, wrapper ) )
  11411. {
  11412. if ( wrapper.GetInstance() )
  11413. {
  11414. auto functionCallData = new Param4< CallType, ParamsReadContext, PlayerIdentity, Object >( CallType.Server, ctx, sender, target );
  11415.  
  11416. if ( ( GetGame().IsServer() && GetGame().IsMultiplayer() ) || ( GetGame().IsServer() && !GetGame().IsMultiplayer() && ( wrapper.GetSPExecutionType() == SingleplayerExecutionType.Server || wrapper.GetSPExecutionType() == SingleplayerExecutionType.Both ) ) )
  11417. {
  11418. GetGame().GameScript.CallFunctionParams( wrapper.GetInstance(), funcName, NULL, functionCallData );
  11419. }
  11420.  
  11421. if ( ( GetGame().IsClient() && GetGame().IsMultiplayer() ) || ( GetGame().IsServer() && !GetGame().IsMultiplayer() && ( wrapper.GetSPExecutionType() == SingleplayerExecutionType.Client || wrapper.GetSPExecutionType() == SingleplayerExecutionType.Both ) ) )
  11422. {
  11423. //Update call type
  11424. functionCallData.param1 = CallType.Client;
  11425. GetGame().GameScript.CallFunctionParams( wrapper.GetInstance(), funcName, NULL, functionCallData );
  11426. }
  11427. }
  11428. } else
  11429. {
  11430. CF_Log.Warn( recievedFrom + " tried sending " + modName + "::<" + funcName + "> which does not seem to exist!");
  11431. }
  11432. } else
  11433. {
  11434. CF_Log.Warn( recievedFrom + " tried sending <" + modName + ">::" + funcName + " which does not seem to exist!");
  11435. }
  11436. }
  11437.  
  11438. void SendRPC( string modName, string funcName, Param params = NULL, bool guaranteed = false, PlayerIdentity sendToIdentity = NULL, Object sendToTarget = NULL )
  11439. {
  11440. #ifdef CF_TRACE_ENABLED
  11441. auto trace = CF_Trace_6(this).Add(modName).Add(funcName).Add(params).Add(guaranteed).Add(sendToIdentity).Add(sendToTarget);
  11442. #endif
  11443.  
  11444. auto sendData = new array< ref Param >;
  11445. sendData.Insert( new Param2< string, string >( modName, funcName ) );
  11446. sendData.Insert( params );
  11447.  
  11448. //In case we are in the singleplayer and the data is consumed twice for both client and server, we need to add it twice. Better than making a deep copy with more complicated rules on receiving
  11449. if ( !GetGame().IsMultiplayer() )
  11450. {
  11451. if ( m_RPCActions.Contains( modName ) )
  11452. {
  11453. if ( m_RPCActions[ modName ].Contains( funcName ) )
  11454. {
  11455. RPCMetaWrapper wrapper = m_RPCActions[ modName ][ funcName ];
  11456.  
  11457. if ( ( wrapper.GetSPExecutionType() == SingleplayerExecutionType.Both ) )
  11458. {
  11459. sendData.Insert( params );
  11460. }
  11461. }
  11462. }
  11463. }
  11464.  
  11465. GetGame().RPC( sendToTarget, FRAMEWORK_RPC_ID, sendData, guaranteed, sendToIdentity );
  11466. }
  11467.  
  11468. /**
  11469. * Warning: Does not support "SingleplayerExecutionType.Both"
  11470. */
  11471. void SendRPCs( string modName, string funcName, array< ref Param > params, bool guaranteed = false, PlayerIdentity sendToIdentity = NULL, Object sendToTarget = NULL )
  11472. {
  11473. #ifdef CF_TRACE_ENABLED
  11474. auto trace = CF_Trace_6(this).Add(modName).Add(funcName).Add(params).Add(guaranteed).Add(sendToIdentity).Add(sendToTarget);
  11475. #endif
  11476.  
  11477. params.InsertAt( new Param2< string, string >( modName, funcName ), 0 );
  11478.  
  11479. GetGame().RPC( sendToTarget, FRAMEWORK_RPC_ID, params, guaranteed, sendToIdentity );
  11480.  
  11481. if ( !GetGame().IsMultiplayer() )
  11482. {
  11483. if ( m_RPCActions.Contains( modName ) )
  11484. {
  11485. if ( m_RPCActions[ modName ].Contains( funcName ) )
  11486. {
  11487. RPCMetaWrapper wrapper = m_RPCActions[ modName ][ funcName ];
  11488.  
  11489. if ( ( wrapper.GetSPExecutionType() == SingleplayerExecutionType.Both ) )
  11490. {
  11491. CF_Log.Warn( modName + "::" + funcName + " does not support \"SingleplayerExecutionType.Both\" when using RPCManager::SendRPCs, use RPCManager::SendRPC instead!");
  11492. }
  11493. }
  11494. }
  11495. }
  11496. }
  11497.  
  11498. bool AddRPC( string modName, string funcName, Class instance, int singlePlayerExecType = SingleplayerExecutionType.Server )
  11499. {
  11500. #ifdef CF_TRACE_ENABLED
  11501. auto trace = CF_Trace_4(this).Add(modName).Add(funcName).Add(instance).Add(singlePlayerExecType);
  11502. #endif
  11503.  
  11504. if ( !m_RPCActions.Contains( modName ) )
  11505. {
  11506. m_RPCActions.Set( modName, new map< string, ref RPCMetaWrapper > );
  11507. }
  11508.  
  11509. auto wrapper = new RPCMetaWrapper( instance, singlePlayerExecType );
  11510.  
  11511. m_RPCActions[ modName ].Set( funcName, wrapper );
  11512.  
  11513. return true;
  11514. }
  11515. };
  11516.  
  11517. static ref RPCManager g_RPCManager;
  11518.  
  11519. static RPCManager GetRPCManager()
  11520. {
  11521. if ( !g_RPCManager )
  11522. {
  11523. g_RPCManager = new RPCManager();
  11524. }
  11525.  
  11526. return g_RPCManager;
  11527. }
  11528. static autoptr CF_TypeConverterConstructor g_CF_TypeConverterConstructor = null;
  11529.  
  11530. class CF_TypeConverterConstructor
  11531. {
  11532. private void CF_TypeConverterConstructor()
  11533. {
  11534. #ifdef CF_TRACE_ENABLED
  11535. auto trace = CF_Trace_0(this);
  11536. #endif
  11537.  
  11538. CF_TypeConverter._OnCreate();
  11539. }
  11540.  
  11541. /**
  11542. * @note We can safely guarantee the destructor is called on script reload,
  11543. * we can't do the same for 'OnGameDestroy'.
  11544. */
  11545. void ~CF_TypeConverterConstructor()
  11546. {
  11547. #ifdef CF_TRACE_ENABLED
  11548. auto trace = CF_Trace_0(this);
  11549. #endif
  11550.  
  11551. CF_TypeConverter._OnDestroy();
  11552. }
  11553.  
  11554. [CF_EventSubscriber(ScriptCaller.Create(CF_TypeConverterConstructor._Init), CF_LifecycleEvents.OnGameCreate)]
  11555. static void _Init()
  11556. {
  11557. if (g_CF_TypeConverterConstructor)
  11558. {
  11559. return;
  11560. }
  11561.  
  11562. g_CF_TypeConverterConstructor = new CF_TypeConverterConstructor();
  11563. }
  11564.  
  11565. [CF_EventSubscriber(ScriptCaller.Create(CF_TypeConverterConstructor._Cleanup), CF_LifecycleEvents.OnGameDestroy)]
  11566. static void _Cleanup()
  11567. {
  11568. g_CF_TypeConverterConstructor = null;
  11569. }
  11570. };
  11571. [CF_RegisterTypeConverter(CF_TypeConverterBool)]
  11572. class CF_TypeConverterBool : CF_TypeConverterT<bool>
  11573. {
  11574. override void SetInt(int value)
  11575. {
  11576. m_Value = value;
  11577. }
  11578.  
  11579. override int GetInt()
  11580. {
  11581. return m_Value;
  11582. }
  11583.  
  11584. override void SetBool(bool value)
  11585. {
  11586. m_Value = value;
  11587. }
  11588.  
  11589. override bool GetBool()
  11590. {
  11591. return m_Value;
  11592. }
  11593.  
  11594. override void SetFloat(float value)
  11595. {
  11596. m_Value = value;
  11597. }
  11598.  
  11599. override float GetFloat()
  11600. {
  11601. return m_Value;
  11602. }
  11603.  
  11604. override void SetVector(vector value)
  11605. {
  11606. }
  11607.  
  11608. override vector GetVector()
  11609. {
  11610. return vector.Zero;
  11611. }
  11612.  
  11613. override void SetString(string value)
  11614. {
  11615. m_Value = CF_Encoding.StringToBool(value);
  11616. }
  11617.  
  11618. override string GetString()
  11619. {
  11620. return "" + m_Value;
  11621. }
  11622.  
  11623. override bool IsIOSupported()
  11624. {
  11625. return true;
  11626. }
  11627.  
  11628. override bool Write(CF_IO io)
  11629. {
  11630. io.WriteBool(m_Value);
  11631.  
  11632. return true;
  11633. }
  11634.  
  11635. override bool Read(CF_IO io)
  11636. {
  11637. m_Value = io.ReadBool();
  11638.  
  11639. return true;
  11640. }
  11641. };
  11642. [CF_RegisterTypeConverter(CF_TypeConverterClass)]
  11643. class CF_TypeConverterClass : CF_TypeConverterT<Class>
  11644. {
  11645. override int GetInt()
  11646. {
  11647. return (int) m_Value;
  11648. }
  11649.  
  11650. override bool GetBool()
  11651. {
  11652. return m_Value != null;
  11653. }
  11654.  
  11655. override float GetFloat()
  11656. {
  11657. return GetInt();
  11658. }
  11659.  
  11660. override string GetString()
  11661. {
  11662. if (!m_Value) return "NULL";
  11663. return m_Value.GetDebugName();
  11664. }
  11665.  
  11666. override void SetClass(Class value)
  11667. {
  11668. m_Value = value;
  11669. }
  11670.  
  11671. override Class GetClass()
  11672. {
  11673. return m_Value;
  11674. }
  11675. };
  11676. [CF_RegisterTypeConverter(CF_TypeConverterDate)]
  11677. class CF_TypeConverterDate : CF_TypeConverterManaged
  11678. {
  11679. private string m_Format = "YYYY-MM-DD hh:mm:ss";
  11680.  
  11681. override void SetInt(int value)
  11682. {
  11683. CF_Date date = GetDate();
  11684. if (!date) return;
  11685.  
  11686. date.EpochToDate(value);
  11687. }
  11688.  
  11689. override int GetInt()
  11690. {
  11691. CF_Date date = GetDate();
  11692. if (!date) return 0;
  11693.  
  11694. return date.DateToEpoch();
  11695. }
  11696.  
  11697. override string GetString()
  11698. {
  11699. CF_Date date = GetDate();
  11700. if (!date) return "1970-01-01 00:00:00";
  11701.  
  11702. return date.ToString(m_Format);
  11703. }
  11704.  
  11705. override void SetString(string value)
  11706. {
  11707. CF_Date date = GetDate();
  11708. if (!date) return;
  11709.  
  11710. //date.StringToDate(value);
  11711. }
  11712.  
  11713. override typename GetType()
  11714. {
  11715. typename type = CF_Date;
  11716. return type;
  11717. }
  11718.  
  11719. CF_Date GetDate()
  11720. {
  11721. return CF_Date.Cast(m_Value);
  11722. }
  11723. };
  11724. [CF_RegisterTypeConverter(CF_TypeConverterExpression)]
  11725. class CF_TypeConverterExpression : CF_TypeConverterClass
  11726. {
  11727. override void SetBool(bool value)
  11728. {
  11729. }
  11730.  
  11731. override bool GetBool()
  11732. {
  11733. return GetFloat() != 0.0;
  11734. }
  11735.  
  11736. override void SetInt(int value)
  11737. {
  11738. }
  11739.  
  11740. override int GetInt()
  11741. {
  11742. return GetFloat();
  11743. }
  11744.  
  11745. override void SetFloat(float value)
  11746. {
  11747. }
  11748.  
  11749. override float GetFloat()
  11750. {
  11751. CF_Expression expr = GetExpression();
  11752. if (!expr) return 0;
  11753. return expr.Evaluate(new array<float>);
  11754. }
  11755.  
  11756. override string GetString()
  11757. {
  11758. CF_Expression expr = GetExpression();
  11759. if (!expr) return "";
  11760.  
  11761. return expr.GetSource();
  11762. }
  11763.  
  11764. override void SetString(string value)
  11765. {
  11766. CF_Expression expr = GetExpression();
  11767. if (!expr) return;
  11768.  
  11769. expr.SetSource(value);
  11770. expr.Compile(new array<string>);
  11771. }
  11772.  
  11773. override typename GetType()
  11774. {
  11775. typename type = CF_Expression;
  11776. return type;
  11777. }
  11778.  
  11779. CF_Expression GetExpression()
  11780. {
  11781. return CF_Expression.Cast(m_Value);
  11782. }
  11783. };
  11784. [CF_RegisterTypeConverter(CF_TypeConverterFile)]
  11785. class CF_TypeConverterFile : CF_TypeConverterClass
  11786. {
  11787. override string GetString()
  11788. {
  11789. CF_File file = GetFile();
  11790. if (!file)
  11791. {
  11792. return "";
  11793. }
  11794.  
  11795. return file.GetFileName();
  11796. }
  11797.  
  11798. override void SetString(string value)
  11799. {
  11800. CF_File file = GetFile();
  11801. if (!file)
  11802. {
  11803. return;
  11804. }
  11805.  
  11806. file.Rename(value);
  11807. }
  11808.  
  11809. override typename GetType()
  11810. {
  11811. typename type = CF_File;
  11812. return type;
  11813. }
  11814.  
  11815. CF_File GetFile()
  11816. {
  11817. return CF_File.Cast(m_Value);
  11818. }
  11819. };
  11820. [CF_RegisterTypeConverter(CF_TypeConverterFloat)]
  11821. class CF_TypeConverterFloat : CF_TypeConverterT<float>
  11822. {
  11823. override void SetInt(int value)
  11824. {
  11825. m_Value = value;
  11826. }
  11827.  
  11828. override int GetInt()
  11829. {
  11830. return m_Value;
  11831. }
  11832.  
  11833. override void SetBool(bool value)
  11834. {
  11835. m_Value = value;
  11836. }
  11837.  
  11838. override bool GetBool()
  11839. {
  11840. return m_Value != 0.0;
  11841. }
  11842.  
  11843. override void SetFloat(float value)
  11844. {
  11845. m_Value = value;
  11846. }
  11847.  
  11848. override float GetFloat()
  11849. {
  11850. return m_Value;
  11851. }
  11852.  
  11853. override void SetVector(vector value)
  11854. {
  11855. }
  11856.  
  11857. override vector GetVector()
  11858. {
  11859. return vector.Zero;
  11860. }
  11861.  
  11862. override void SetString(string value)
  11863. {
  11864. m_Value = value.ToFloat();
  11865. }
  11866.  
  11867. override string GetString()
  11868. {
  11869. return "" + m_Value;
  11870. }
  11871.  
  11872. override bool IsIOSupported()
  11873. {
  11874. return true;
  11875. }
  11876.  
  11877. override bool Write(CF_IO io)
  11878. {
  11879. io.WriteFloat(m_Value);
  11880.  
  11881. return true;
  11882. }
  11883.  
  11884. override bool Read(CF_IO io)
  11885. {
  11886. m_Value = io.ReadFloat();
  11887.  
  11888. return true;
  11889. }
  11890. };
  11891. [CF_RegisterTypeConverter(CF_TypeConverterInt)]
  11892. class CF_TypeConverterInt : CF_TypeConverterT<int>
  11893. {
  11894. override void SetInt(int value)
  11895. {
  11896. m_Value = value;
  11897. }
  11898.  
  11899. override int GetInt()
  11900. {
  11901. return m_Value;
  11902. }
  11903.  
  11904. override void SetBool(bool value)
  11905. {
  11906. m_Value = value;
  11907. }
  11908.  
  11909. override bool GetBool()
  11910. {
  11911. return m_Value != 0;
  11912. }
  11913.  
  11914. override void SetFloat(float value)
  11915. {
  11916. m_Value = value;
  11917. }
  11918.  
  11919. override float GetFloat()
  11920. {
  11921. return m_Value;
  11922. }
  11923.  
  11924. override void SetVector(vector value)
  11925. {
  11926. }
  11927.  
  11928. override vector GetVector()
  11929. {
  11930. return vector.Zero;
  11931. }
  11932.  
  11933. override void SetString(string value)
  11934. {
  11935. m_Value = value.ToInt();
  11936. }
  11937.  
  11938. override string GetString()
  11939. {
  11940. return "" + m_Value;
  11941. }
  11942.  
  11943. override bool IsIOSupported()
  11944. {
  11945. return true;
  11946. }
  11947.  
  11948. override bool Read(CF_IO io)
  11949. {
  11950. m_Value = io.ReadInt();
  11951.  
  11952. return true;
  11953. }
  11954.  
  11955. override bool Write(CF_IO io)
  11956. {
  11957. io.WriteInt(m_Value);
  11958.  
  11959. return true;
  11960. }
  11961. };
  11962. [CF_RegisterTypeConverter(CF_TypeConverterLocaliser)]
  11963. class CF_TypeConverterLocaliser : CF_TypeConverterClass
  11964. {
  11965. override string GetString()
  11966. {
  11967. CF_Localiser localiser = GetLocaliser();
  11968. if (!localiser)
  11969. {
  11970. return "";
  11971. }
  11972.  
  11973. return localiser.Format();
  11974. }
  11975.  
  11976. override void SetString(string value)
  11977. {
  11978. }
  11979.  
  11980. override typename GetType()
  11981. {
  11982. typename type = CF_Localiser;
  11983. return type;
  11984. }
  11985.  
  11986. CF_Localiser GetLocaliser()
  11987. {
  11988. return CF_Localiser.Cast(m_Value);
  11989. }
  11990. };
  11991. [CF_RegisterTypeConverter(CF_TypeConverterManaged)]
  11992. class CF_TypeConverterManaged : CF_TypeConverterT<Managed>
  11993. {
  11994. override string GetString()
  11995. {
  11996. if (!m_Value) return "NULL";
  11997. return m_Value.GetDebugName();
  11998. }
  11999.  
  12000. override void SetClass(Class value)
  12001. {
  12002. Class.CastTo(m_Value, value);
  12003. }
  12004.  
  12005. override Class GetClass()
  12006. {
  12007. return m_Value;
  12008. }
  12009.  
  12010. override void SetManaged(Managed value)
  12011. {
  12012. m_Value = value;
  12013. }
  12014.  
  12015. override Managed GetManaged()
  12016. {
  12017. return m_Value;
  12018. }
  12019. };
  12020. [CF_RegisterTypeConverter(CF_TypeConverterString)]
  12021. class CF_TypeConverterString : CF_TypeConverterT<string>
  12022. {
  12023. override void SetInt(int value)
  12024. {
  12025. m_Value = "" + value;
  12026. }
  12027.  
  12028. override int GetInt()
  12029. {
  12030. return m_Value.ToInt();
  12031. }
  12032.  
  12033. override void SetBool(bool value)
  12034. {
  12035. m_Value = "" + value;
  12036. }
  12037.  
  12038. override bool GetBool()
  12039. {
  12040. return CF_Encoding.StringToBool(m_Value);
  12041. }
  12042.  
  12043. override void SetFloat(float value)
  12044. {
  12045. m_Value = "" + value;
  12046. }
  12047.  
  12048. override float GetFloat()
  12049. {
  12050. return m_Value.ToFloat();
  12051. }
  12052.  
  12053. override void SetVector(vector value)
  12054. {
  12055. m_Value = "" + value;
  12056. }
  12057.  
  12058. override vector GetVector()
  12059. {
  12060. return m_Value.ToVector();
  12061. }
  12062.  
  12063. override void SetString(string value)
  12064. {
  12065. m_Value = value;
  12066. }
  12067.  
  12068. override string GetString()
  12069. {
  12070. return m_Value;
  12071. }
  12072.  
  12073. override bool IsIOSupported()
  12074. {
  12075. return true;
  12076. }
  12077.  
  12078. override bool Write(CF_IO io)
  12079. {
  12080. io.WriteString(m_Value);
  12081.  
  12082. return true;
  12083. }
  12084.  
  12085. override bool Read(CF_IO io)
  12086. {
  12087. m_Value = io.ReadString();
  12088.  
  12089. return true;
  12090. }
  12091. };
  12092. [CF_RegisterTypeConverter(CF_TypeConverterVector)]
  12093. class CF_TypeConverterVector : CF_TypeConverterT<vector>
  12094. {
  12095. override void SetVector(vector value)
  12096. {
  12097. m_Value = value;
  12098. }
  12099.  
  12100. override vector GetVector()
  12101. {
  12102. return m_Value;
  12103. }
  12104.  
  12105. override void SetString(string value)
  12106. {
  12107. m_Value = value.ToVector();
  12108. }
  12109.  
  12110. override string GetString()
  12111. {
  12112. return "" + m_Value;
  12113. }
  12114.  
  12115. override bool IsIOSupported()
  12116. {
  12117. return true;
  12118. }
  12119.  
  12120. override bool Write(CF_IO io)
  12121. {
  12122. io.WriteVector(m_Value);
  12123.  
  12124. return true;
  12125. }
  12126.  
  12127. override bool Read(CF_IO io)
  12128. {
  12129. m_Value = io.ReadVector();
  12130.  
  12131. return true;
  12132. }
  12133. };
  12134. typedef CF_Date JMDate; // Compatability with a variety of mods.
  12135.  
  12136. class CF_Date : Managed
  12137. {
  12138. // TODO: Stringtable
  12139. static const string MONTHS_FULL_NAME[12] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
  12140. static const string MONTHS_SHORT_NAME[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  12141. static const int DAYS_IN_MONTH[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  12142.  
  12143. static const string TIME = "hh:mm:ss";
  12144. static const string DATE = "YYYY-MM-DD";
  12145. static const string DATETIME = "YYYY-MM-DD hh:mm:ss";
  12146.  
  12147. protected bool m_UseUTC;
  12148.  
  12149. protected int m_Year;
  12150. protected int m_Month;
  12151. protected int m_Day;
  12152. protected int m_Hour;
  12153. protected int m_Minute;
  12154. protected int m_Second;
  12155.  
  12156. //! Compile error if protected
  12157. private void CF_Date()
  12158. {
  12159. }
  12160.  
  12161. static CF_Date Now(bool useUTC = false)
  12162. {
  12163. CF_Date date = new CF_Date();
  12164. date.m_UseUTC = useUTC;
  12165.  
  12166. if (date.m_UseUTC)
  12167. {
  12168. GetYearMonthDayUTC(date.m_Year, date.m_Month, date.m_Day);
  12169. GetHourMinuteSecondUTC(date.m_Hour, date.m_Minute, date.m_Second);
  12170. }
  12171. else
  12172. {
  12173. GetYearMonthDay(date.m_Year, date.m_Month, date.m_Day);
  12174. GetHourMinuteSecond(date.m_Hour, date.m_Minute, date.m_Second);
  12175. }
  12176.  
  12177. return date;
  12178. }
  12179.  
  12180. static CF_Date Epoch(int timestamp)
  12181. {
  12182. CF_Date date = new CF_Date();
  12183. date.m_UseUTC = false;
  12184.  
  12185. date.EpochToDate(timestamp);
  12186.  
  12187. return date;
  12188. }
  12189.  
  12190. static CF_Date CreateDate(int year, int month, int day)
  12191. {
  12192. CF_Date date = new CF_Date();
  12193. date.m_UseUTC = false;
  12194. date.m_Year = year;
  12195. date.m_Month = month;
  12196. date.m_Day = day;
  12197. GetHourMinuteSecond(date.m_Hour, date.m_Minute, date.m_Second);
  12198. return date;
  12199. }
  12200.  
  12201. static CF_Date CreateTime(int hour, int minute, int second)
  12202. {
  12203. CF_Date date = new CF_Date();
  12204. date.m_UseUTC = false;
  12205. GetYearMonthDay(date.m_Year, date.m_Month, date.m_Day);
  12206. date.m_Hour = hour;
  12207. date.m_Minute = minute;
  12208. date.m_Second = second;
  12209. return date;
  12210. }
  12211.  
  12212. static CF_Date CreateDateTime(int year, int month, int day, int hour, int minute, int second)
  12213. {
  12214. CF_Date date = new CF_Date();
  12215. date.m_UseUTC = false;
  12216. date.m_Year = year;
  12217. date.m_Month = month;
  12218. date.m_Day = day;
  12219. date.m_Hour = hour;
  12220. date.m_Minute = minute;
  12221. date.m_Second = second;
  12222. return date;
  12223. }
  12224.  
  12225. //! UTILS
  12226. static bool IsLeapYear(int year)
  12227. {
  12228. if (year % 400 == 0)
  12229. return true;
  12230.  
  12231. if (year % 100 == 0)
  12232. return false;
  12233.  
  12234. if (year % 4 == 0)
  12235. return true;
  12236.  
  12237. return false;
  12238. }
  12239.  
  12240. /**
  12241. * Based on: https://en.wikipedia.org/wiki/Unix_time
  12242. *
  12243. * MAJOR NOTE:
  12244. * Timestamp start at Year 1970, if any functions / methods linked
  12245. * to Timestamp, be aware of using any date at least starting at this
  12246. * year.
  12247. *
  12248. * @param {int} year
  12249. * @param {int} month
  12250. * @param {int} day
  12251. * @param {int} hour
  12252. * @param {int} minute
  12253. * @param {int} second
  12254. *
  12255. * @return Timestamp in m_Second
  12256. */
  12257. static int Timestamp(int year, int month, int day, int hours, int minutes, int seconds)
  12258. {
  12259. if (year < 1970)
  12260. return 0;
  12261.  
  12262. bool isLeapYear = IsLeapYear(year);
  12263. int timestamp = 0;
  12264.  
  12265. for (int iYear = 1970; iYear < year; ++iYear)
  12266. {
  12267. if (IsLeapYear(iYear))
  12268. {
  12269. timestamp += 31622400;
  12270. }
  12271. else
  12272. {
  12273. timestamp += 31536000;
  12274. }
  12275. }
  12276.  
  12277. for (int iMonth = 1; iMonth < month; iMonth++)
  12278. {
  12279. if (isLeapYear && iMonth == 2)
  12280. {
  12281. timestamp += 86400;
  12282. }
  12283. timestamp += DAYS_IN_MONTH[iMonth - 1] * 86400;
  12284. }
  12285.  
  12286. for (int iDay = 1; iDay < day; iDay++)
  12287. {
  12288. timestamp += 86400;
  12289. }
  12290.  
  12291. timestamp += hours * 3600;
  12292. timestamp += minutes * 60;
  12293. timestamp += seconds;
  12294. return timestamp;
  12295. }
  12296.  
  12297. static void TimestampToDate(int timestamp, out int year, out int month, out int day, out int hours, out int minutes, out int seconds)
  12298. {
  12299. if (timestamp < 0)
  12300. return;
  12301.  
  12302. int iTimestamp = 0;
  12303. iTimestamp = TimestampCalculYear(timestamp, year);
  12304. iTimestamp = TimestampCalculMonth(iTimestamp, timestamp, year, month);
  12305. iTimestamp = TimestampCalculDays(iTimestamp, timestamp, day);
  12306. iTimestamp = TimestampCalculHours(iTimestamp, timestamp, hours);
  12307. iTimestamp = TimestampCalculMinutes(iTimestamp, timestamp, minutes);
  12308. iTimestamp = TimestampCalculSeconds(iTimestamp, timestamp, seconds);
  12309. }
  12310.  
  12311. protected static int TimestampCalculYear(int timestamp, out int year)
  12312. {
  12313. int iTimestamp = 0;
  12314. year = 1970;
  12315.  
  12316. while (iTimestamp < timestamp)
  12317. {
  12318. int yearTimestamp;
  12319.  
  12320. if (IsLeapYear(year))
  12321. yearTimestamp = 31622400;
  12322. else
  12323. yearTimestamp = 31536000;
  12324.  
  12325. if (iTimestamp + yearTimestamp > timestamp)
  12326. break;
  12327.  
  12328. iTimestamp += yearTimestamp;
  12329. year++;
  12330. }
  12331.  
  12332. return iTimestamp;
  12333. }
  12334.  
  12335. protected static int TimestampCalculMonth(int iTimestamp, int timestamp, int year, out int month)
  12336. {
  12337. bool isLeapYear = IsLeapYear(year);
  12338. month = 0;
  12339.  
  12340. while (iTimestamp < timestamp)
  12341. {
  12342. int monthTimestamp;
  12343. if (isLeapYear && month == 1)
  12344. monthTimestamp = 2505600;
  12345. else
  12346. monthTimestamp = DAYS_IN_MONTH[month] * 86400;
  12347.  
  12348. if (iTimestamp + monthTimestamp > timestamp)
  12349. break;
  12350.  
  12351. iTimestamp += monthTimestamp;
  12352. month++;
  12353. }
  12354.  
  12355. month++;
  12356. return iTimestamp;
  12357. }
  12358.  
  12359. protected static int TimestampCalculDays(int iTimestamp, int timestamp, out int days)
  12360. {
  12361. days = 1;
  12362.  
  12363. while (iTimestamp < timestamp)
  12364. {
  12365. if (iTimestamp + 86400 > timestamp)
  12366. break;
  12367.  
  12368. iTimestamp += 86400;
  12369. days++;
  12370. }
  12371.  
  12372. return iTimestamp;
  12373. }
  12374.  
  12375. protected static int TimestampCalculHours(int iTimestamp, int timestamp, out int hours)
  12376. {
  12377. hours = 0;
  12378.  
  12379. while (iTimestamp < timestamp)
  12380. {
  12381. if (iTimestamp + 3600 > timestamp)
  12382. break;
  12383.  
  12384. iTimestamp += 3600;
  12385. hours++;
  12386. }
  12387.  
  12388. return iTimestamp;
  12389. }
  12390.  
  12391. protected static int TimestampCalculMinutes(int iTimestamp, int timestamp, out int minutes)
  12392. {
  12393. minutes = 0;
  12394.  
  12395. while (iTimestamp < timestamp)
  12396. {
  12397. if (iTimestamp + 60 > timestamp)
  12398. break;
  12399. iTimestamp += 60;
  12400. minutes++;
  12401. }
  12402.  
  12403. return iTimestamp;
  12404. }
  12405.  
  12406. protected static int TimestampCalculSeconds(int iTimestamp, int timestamp, out int seconds)
  12407. {
  12408. seconds = 0;
  12409.  
  12410. while (iTimestamp < timestamp)
  12411. {
  12412. iTimestamp++;
  12413. seconds++;
  12414. }
  12415.  
  12416. return iTimestamp;
  12417. }
  12418.  
  12419. int Compare(CF_Date other)
  12420. {
  12421. int timestamp1 = this.GetTimestamp();
  12422. int timestamp2 = other.GetTimestamp();
  12423.  
  12424. if (timestamp1 < timestamp2) {
  12425. return -1;
  12426. } else if (timestamp1 > timestamp2) {
  12427. return 1;
  12428. } else {
  12429. return 0;
  12430. }
  12431. }
  12432.  
  12433. void CalculateDifference(CF_Date other, out int hoursDiff, out int minutesDiff)
  12434. {
  12435. int timestamp1 = this.GetTimestamp();
  12436. int timestamp2 = other.GetTimestamp();
  12437.  
  12438. int timestampDiff = timestamp2 - timestamp1;
  12439. hoursDiff = timestampDiff / 3600;
  12440. minutesDiff = (timestampDiff % 3600) / 60;
  12441. }
  12442.  
  12443. void EpochToDate(int value)
  12444. {
  12445. int iTimestamp;
  12446. iTimestamp = TimestampCalculYear(value, m_Year);
  12447. iTimestamp = TimestampCalculMonth(iTimestamp, value, m_Year, m_Month);
  12448. iTimestamp = TimestampCalculDays(iTimestamp, value, m_Day);
  12449. iTimestamp = TimestampCalculHours(iTimestamp, value, m_Hour);
  12450. iTimestamp = TimestampCalculMinutes(iTimestamp, value, m_Minute);
  12451. iTimestamp = TimestampCalculSeconds(iTimestamp, value, m_Second);
  12452. }
  12453.  
  12454. int DateToEpoch()
  12455. {
  12456. return Timestamp(m_Year, m_Month, m_Day, m_Hour, m_Minute, m_Second);
  12457. }
  12458.  
  12459. /**
  12460. * @return string with format: "month day, year hours:minutes:seconds"
  12461. */
  12462. string DateToString()
  12463. {
  12464. string dateToString = GetFullMonthString();
  12465.  
  12466. dateToString += " " + m_Day.ToStringLen(2);
  12467. dateToString += ", " + m_Year;
  12468. dateToString += " " + m_Hour.ToStringLen(2) + ":" + m_Minute.ToStringLen(2) + ":" + m_Second.ToStringLen(2);
  12469. return dateToString;
  12470. }
  12471.  
  12472. override string GetDebugName()
  12473. {
  12474. return DateToString();
  12475. }
  12476.  
  12477. /**
  12478. * @param format Supply a format such as "YYYY-MM-DD hh:mm:ss"
  12479. */
  12480. string Format(string format)
  12481. {
  12482. FormatField(format, m_Year.ToString(), "Y");
  12483. FormatField(format, m_Month.ToString(), "M");
  12484. FormatField(format, m_Day.ToString(), "D");
  12485. FormatField(format, m_Hour.ToString(), "h");
  12486. FormatField(format, m_Minute.ToString(), "m");
  12487. FormatField(format, m_Second.ToString(), "s");
  12488.  
  12489. return format;
  12490. }
  12491.  
  12492. string ToString(string format)
  12493. {
  12494. return Format(format);
  12495. }
  12496.  
  12497. protected void FormatField(inout CF_String format, CF_String field, CF_String char)
  12498. {
  12499. int index;
  12500. int count = format.CountCharacter(char, index);
  12501.  
  12502. int length = field.Length();
  12503.  
  12504. if (length < count)
  12505. {
  12506. field = field.PadStringFront(count, "0");
  12507. }
  12508.  
  12509. if (field.Length() > count)
  12510. {
  12511. field = field.Substring(0, count);
  12512. }
  12513.  
  12514. format = format.SpliceString(index, field);
  12515. }
  12516.  
  12517. //! GETTERS
  12518. bool IsUsingUTC()
  12519. {
  12520. return m_UseUTC;
  12521. }
  12522.  
  12523. int GetYear()
  12524. {
  12525. return m_Year;
  12526. }
  12527.  
  12528. int GetMonth()
  12529. {
  12530. return m_Month;
  12531. }
  12532.  
  12533. string GetFullMonthString()
  12534. {
  12535. if (0 < m_Month && m_Month < 13)
  12536. {
  12537. return MONTHS_FULL_NAME[m_Month - 1];
  12538. }
  12539.  
  12540. return "undefined";
  12541. }
  12542.  
  12543. string GetShortMonthString()
  12544. {
  12545. if (0 < m_Month && m_Month < 13)
  12546. {
  12547. return MONTHS_SHORT_NAME[m_Month - 1];
  12548. }
  12549.  
  12550. return "undefined";
  12551. }
  12552.  
  12553. //! @note 0 = sunday
  12554. int GetDayOfWeek()
  12555. {
  12556. int y = m_Year;
  12557. int d = m_Day;
  12558. if (m_Month < 3)
  12559. d += y--;
  12560. else
  12561. d += y - 2;
  12562. return (23 * m_Month / 9 + d + 4 + y / 4 - y / 100 + y / 400) % 7;
  12563. }
  12564.  
  12565. int GetDay()
  12566. {
  12567. return m_Day;
  12568. }
  12569.  
  12570. int GetHours()
  12571. {
  12572. return m_Hour;
  12573. }
  12574.  
  12575. int GetMinutes()
  12576. {
  12577. return m_Minute;
  12578. }
  12579.  
  12580. int GetSeconds()
  12581. {
  12582. return m_Second;
  12583. }
  12584.  
  12585. int GetTimestamp()
  12586. {
  12587. return Timestamp(m_Year, m_Month, m_Day, m_Hour, m_Minute, m_Second);
  12588. }
  12589.  
  12590. //! SETTERS
  12591. void SetDate(int year, int month, int day, int hours, int minutes, int seconds)
  12592. {
  12593. SetYear(year);
  12594. SetMonth(month);
  12595. SetDay(day);
  12596. SetHours(hours);
  12597. SetMinutes(minutes);
  12598. SetSeconds(seconds);
  12599. }
  12600.  
  12601. void SetDate(int month, int day, int hours, int minutes, int seconds)
  12602. {
  12603. SetMonth(month);
  12604. SetDay(day);
  12605. SetHours(hours);
  12606. SetMinutes(minutes);
  12607. SetSeconds(seconds);
  12608. }
  12609.  
  12610. void SetDate(int day, int hours, int minutes, int seconds)
  12611. {
  12612. SetDay(day);
  12613. SetHours(hours);
  12614. SetMinutes(minutes);
  12615. SetSeconds(seconds);
  12616. }
  12617.  
  12618. void SetDate(int hours, int minutes, int seconds)
  12619. {
  12620. SetHours(hours);
  12621. SetMinutes(minutes);
  12622. SetSeconds(seconds);
  12623. }
  12624.  
  12625. void SetDate(int minutes, int seconds)
  12626. {
  12627. SetMinutes(minutes);
  12628. SetSeconds(seconds);
  12629. }
  12630.  
  12631. void SetYear(int year)
  12632. {
  12633. m_Year = year;
  12634. }
  12635.  
  12636. void SetMonth(int month)
  12637. {
  12638. if (0 < month && month < 13)
  12639. {
  12640. m_Month = month;
  12641. if (m_Day > DAYS_IN_MONTH[m_Month - 1])
  12642. {
  12643. m_Day = DAYS_IN_MONTH[m_Month - 1];
  12644. }
  12645. }
  12646. else
  12647. {
  12648. CF_Log.Error("Invalid SetMonth: " + month + ". Expected a value between 1 and 12!");
  12649. }
  12650. }
  12651.  
  12652. void SetDay(int day)
  12653. {
  12654. int monthDays = DAYS_IN_MONTH[m_Month - 1] + 1;
  12655.  
  12656. if (IsLeapYear(m_Year) && m_Month == 2)
  12657. {
  12658. monthDays++;
  12659. }
  12660.  
  12661. if (0 < day && day < monthDays)
  12662. {
  12663. m_Day = day;
  12664. }
  12665. else
  12666. {
  12667. CF_Log.Error("Invalid SetDay: " + day + ". Expected a value between 1 and " + DAYS_IN_MONTH[m_Month - 1] + "!");
  12668. }
  12669. }
  12670.  
  12671. void SetHours(int hours)
  12672. {
  12673. if (-1 < hours && hours < 24)
  12674. {
  12675. m_Hour = hours;
  12676. }
  12677. else
  12678. {
  12679. CF_Log.Error("Invalid SetHours: " + hours + ". Expected a value between 0 and 23!");
  12680. }
  12681. }
  12682.  
  12683. void SetMinutes(int minutes)
  12684. {
  12685. if (-1 < minutes && minutes < 60)
  12686. {
  12687. m_Minute = minutes;
  12688. }
  12689. else
  12690. {
  12691. CF_Log.Error("Invalid SetMinutes: " + minutes + ". Expected a value between 0 and 59!");
  12692. }
  12693. }
  12694.  
  12695. void SetSeconds(int seconds)
  12696. {
  12697. if (-1 < seconds && seconds < 60)
  12698. {
  12699. m_Second = seconds;
  12700. }
  12701. else
  12702. {
  12703. CF_Log.Error("Invalid SetSeconds: " + seconds + ". Expected a value between 0 and 59!");
  12704. }
  12705. }
  12706. };
  12707. /**@class CF_Localiser
  12708. * @brief This class handle string formatting over network
  12709. **/
  12710. class CF_Localiser
  12711. {
  12712. protected int m_Count;
  12713.  
  12714. protected string m_Strings[10];
  12715. protected bool m_Translates[10];
  12716.  
  12717. void CF_Localiser(string text = "", string param1 = "", string param2 = "", string param3 = "", string param4 = "", string param5 = "", string param6 = "", string param7 = "", string param8 = "", string param9 = "")
  12718. {
  12719. Set(-1, text);
  12720. Set(0, param1);
  12721. Set(1, param2);
  12722. Set(2, param3);
  12723. Set(3, param4);
  12724. Set(4, param5);
  12725. Set(5, param6);
  12726. Set(6, param7);
  12727. Set(7, param8);
  12728. Set(8, param9);
  12729. }
  12730.  
  12731. static void Write(ParamsWriteContext ctx, CF_Localiser localiser)
  12732. {
  12733. ctx.Write(localiser.m_Count);
  12734.  
  12735. for (int i = 0; i < localiser.m_Count; i++)
  12736. {
  12737. ctx.Write(localiser.m_Strings[i]);
  12738. ctx.Write(localiser.m_Translates[i]);
  12739. }
  12740. }
  12741.  
  12742. static bool Read(ParamsReadContext ctx, inout CF_Localiser localiser)
  12743. {
  12744. if (!localiser) localiser = new CF_Localiser();
  12745.  
  12746. if (!ctx.Read(localiser.m_Count)) return false;
  12747.  
  12748. for (int i = 0; i < localiser.m_Count; i++)
  12749. {
  12750. string str;
  12751. bool translates;
  12752.  
  12753. if (!ctx.Read(str) || !ctx.Read(translates)) return false;
  12754.  
  12755. localiser.m_Strings[i] = str;
  12756. localiser.m_Translates[i] = translates;
  12757. }
  12758.  
  12759. return true;
  12760. }
  12761.  
  12762. void SetTranslates(bool translates)
  12763. {
  12764. m_Translates[0] = translates;
  12765. }
  12766.  
  12767. string Format()
  12768. {
  12769. return GetDebugName();
  12770. }
  12771.  
  12772. override string GetDebugName()
  12773. {
  12774. string text = GetTranslated(-1);
  12775. string p1 = GetTranslated(0);
  12776. string p2 = GetTranslated(1);
  12777. string p3 = GetTranslated(2);
  12778. string p4 = GetTranslated(3);
  12779. string p5 = GetTranslated(4);
  12780. string p6 = GetTranslated(5);
  12781. string p7 = GetTranslated(6);
  12782. string p8 = GetTranslated(7);
  12783. string p9 = GetTranslated(8);
  12784.  
  12785. return string.Format(text, p1, p2, p3, p4, p5, p6, p7, p8, p9);
  12786. }
  12787.  
  12788. string GetText()
  12789. {
  12790. return Get(-1);
  12791. }
  12792.  
  12793. CF_Localiser Add(bool value)
  12794. {
  12795. return Set(m_Count - 1, value.ToString(), false);
  12796. }
  12797.  
  12798. CF_Localiser Add(int value)
  12799. {
  12800. return Set(m_Count - 1, value.ToString(), false);
  12801. }
  12802.  
  12803. CF_Localiser Add(float value)
  12804. {
  12805. return Set(m_Count - 1, value.ToString(), false);
  12806. }
  12807.  
  12808. CF_Localiser Add(vector value)
  12809. {
  12810. return Set(m_Count - 1, value.ToString(false), false);
  12811. }
  12812.  
  12813. CF_Localiser Add(Class value)
  12814. {
  12815. //TODO: use CF_TypeConverter here instead afer the PR is merged.
  12816.  
  12817. string toStr = "";
  12818. if (value) toStr = value.GetDebugName();
  12819. return Set(m_Count - 1, toStr, false);
  12820. }
  12821.  
  12822. CF_Localiser Add(string value, bool translates = true)
  12823. {
  12824. return Set(m_Count - 1, value, translates);
  12825. }
  12826.  
  12827. CF_Localiser Set(int index, bool value)
  12828. {
  12829. return Set(index, value.ToString(), false);
  12830. }
  12831.  
  12832. CF_Localiser Set(int index, int value)
  12833. {
  12834. return Set(index, value.ToString(), false);
  12835. }
  12836.  
  12837. CF_Localiser Set(int index, float value)
  12838. {
  12839. return Set(index, value.ToString(), false);
  12840. }
  12841.  
  12842. CF_Localiser Set(int index, vector value)
  12843. {
  12844. return Set(index, value.ToString(false), false);
  12845. }
  12846.  
  12847. CF_Localiser Set(int index, Class value)
  12848. {
  12849. string toStr = "";
  12850. if (value) toStr = value.GetDebugName();
  12851. return Set(index, toStr, false);
  12852. }
  12853.  
  12854. CF_Localiser Set(int index, string value)
  12855. {
  12856. return Set(index, value, true);
  12857. }
  12858.  
  12859. CF_Localiser Set(int index, string value, bool translates)
  12860. {
  12861. int realIndex = index + 1;
  12862. if (realIndex < 0 || realIndex > 9)
  12863. return this;
  12864.  
  12865. if (realIndex >= m_Count)
  12866. {
  12867. if (value == "" && realIndex != 0)
  12868. return this;
  12869.  
  12870. m_Count = realIndex + 1;
  12871. }
  12872.  
  12873. m_Strings[realIndex] = value;
  12874. m_Translates[realIndex] = translates;
  12875. return this;
  12876. }
  12877.  
  12878. string Get(int index)
  12879. {
  12880. int realIndex = index + 1;
  12881. if (realIndex < 0 || realIndex >= m_Count)
  12882. return "";
  12883. return m_Strings[realIndex];
  12884. }
  12885.  
  12886. string GetTranslated(int index)
  12887. {
  12888. int realIndex = index + 1;
  12889. if (realIndex < 0 || realIndex >= m_Count)
  12890. return "";
  12891. string value = m_Strings[realIndex];
  12892. if (m_Translates[realIndex])
  12893. {
  12894. value = Widget.TranslateString("#" + value);
  12895. if (value == "" || value[0] == " ")
  12896. return m_Strings[realIndex];
  12897. }
  12898. return value;
  12899. }
  12900.  
  12901. /* Backwards compatbility - to be removed after CF 1.4 */
  12902.  
  12903. CF_Localiser SetParam1(string arg)
  12904. {
  12905. return Set(1, arg);
  12906. }
  12907.  
  12908. CF_Localiser SetParam2(string arg)
  12909. {
  12910. return Set(2, arg);
  12911. }
  12912.  
  12913. CF_Localiser SetParam3(string arg)
  12914. {
  12915. return Set(3, arg);
  12916. }
  12917.  
  12918. CF_Localiser SetParam4(string arg)
  12919. {
  12920. return Set(4, arg);
  12921. }
  12922.  
  12923. CF_Localiser SetParam5(string arg)
  12924. {
  12925. return Set(5, arg);
  12926. }
  12927.  
  12928. CF_Localiser SetParam6(string arg)
  12929. {
  12930. return Set(6, arg);
  12931. }
  12932.  
  12933. CF_Localiser SetParam7(string arg)
  12934. {
  12935. return Set(7, arg);
  12936. }
  12937.  
  12938. CF_Localiser SetParam8(string arg)
  12939. {
  12940. return Set(8, arg);
  12941. }
  12942.  
  12943. CF_Localiser SetParam9(string arg)
  12944. {
  12945. return Set(9, arg);
  12946. }
  12947. };
  12948.  
  12949. class StringLocaliser : CF_Localiser
  12950. {
  12951.  
  12952. };
  12953. class CF_XML
  12954. {
  12955. static void _Cleanup()
  12956. {
  12957. }
  12958.  
  12959. static CF_XML_Reader Open(string path)
  12960. {
  12961. CF_XML_Reader reader = new CF_XML_Reader();
  12962.  
  12963. FileHandle fileHandle = OpenFile(path, FileMode.READ);
  12964.  
  12965. string lineContent;
  12966. while (FGets(fileHandle, lineContent) >= 0)
  12967. reader.AddLine(lineContent);
  12968.  
  12969. CloseFile(fileHandle);
  12970.  
  12971. return reader;
  12972. }
  12973.  
  12974. static bool ReadDocument(string file, out CF_XML_Document document)
  12975. {
  12976. if (!document)
  12977. document = new CF_XML_Document();
  12978.  
  12979. return document.Read(Open(file));
  12980. }
  12981.  
  12982. static void Read(string file, notnull CF_XML_Callback callback)
  12983. {
  12984. Process(Open(file), callback);
  12985. }
  12986.  
  12987. static void ReadAsync(string file, notnull CF_XML_Callback callback)
  12988. {
  12989. thread Process(Open(file), callback);
  12990. }
  12991.  
  12992. static void Process(CF_XML_Reader reader, CF_XML_Callback callback)
  12993. {
  12994. CF_XML_Document document = new CF_XML_Document();
  12995.  
  12996. callback.OnStart(document);
  12997.  
  12998. bool success = false;
  12999. if (document && reader)
  13000. {
  13001. success = document.Read(reader);
  13002. }
  13003.  
  13004. if (success)
  13005. {
  13006. callback.OnSuccess(document);
  13007. }
  13008. else
  13009. {
  13010. callback.OnFailure(document);
  13011. }
  13012. }
  13013. };
  13014.  
  13015. static CF_XML GetXMLApi()
  13016. {
  13017. return CF.XML;
  13018. }typedef CF_XML_Attribute XMLAttribute;
  13019.  
  13020. class CF_XML_Attribute : Managed
  13021. {
  13022. private string _name;
  13023. private string _value;
  13024.  
  13025. private CF_XML_Tag _parentTag;
  13026.  
  13027. void CF_XML_Attribute(CF_XML_Tag parent, string name)
  13028. {
  13029. _parentTag = parent;
  13030. _name = name;
  13031. _value = "";
  13032. }
  13033.  
  13034. CF_XML_Attribute Copy(CF_XML_Tag parent = NULL)
  13035. {
  13036. CF_XML_Attribute element = new CF_XML_Attribute(parent, _name);
  13037.  
  13038. element._value = _value;
  13039.  
  13040. return element;
  13041. }
  13042.  
  13043. string GetName()
  13044. {
  13045. return _name;
  13046. }
  13047.  
  13048. void SetValue(string value)
  13049. {
  13050. _value = value;
  13051. }
  13052.  
  13053. void SetValue(bool value)
  13054. {
  13055. if (value)
  13056. {
  13057. _value = "true";
  13058. }
  13059. else
  13060. {
  13061. _value = "false";
  13062. }
  13063. }
  13064.  
  13065. void SetValue(int value)
  13066. {
  13067. _value = "" + value;
  13068. }
  13069.  
  13070. void SetValue(float value)
  13071. {
  13072. _value = "" + value;
  13073. }
  13074.  
  13075. void SetValue(vector value)
  13076. {
  13077. _value = "" + value[0] + " " + value[1] + " " + value[2];
  13078. }
  13079.  
  13080. string GetValue()
  13081. {
  13082. return _value;
  13083. }
  13084.  
  13085. string ValueAsString()
  13086. {
  13087. return _value;
  13088. }
  13089.  
  13090. bool ValueAsBool()
  13091. {
  13092. if (_value == "true")
  13093. return true;
  13094.  
  13095. return false;
  13096. }
  13097.  
  13098. int ValueAsInt()
  13099. {
  13100. return _value.ToInt();
  13101. }
  13102.  
  13103. float ValueAsFloat()
  13104. {
  13105. return _value.ToFloat();
  13106. }
  13107.  
  13108. vector ValueAsVector()
  13109. {
  13110. array<string> tokens = new array<string>;
  13111. _value.Split(" ", tokens);
  13112.  
  13113. return Vector(tokens[0].ToFloat(), tokens[1].ToFloat(), tokens[2].ToFloat());
  13114. }
  13115.  
  13116. CF_XML_Tag GetParent()
  13117. {
  13118. return _parentTag;
  13119. }
  13120.  
  13121. void Debug(int level = 0)
  13122. {
  13123. string indent = CF_Indent(level);
  13124. CF_Log.Info(indent + " name=" + _name + " value=" + _value);
  13125. }
  13126.  
  13127. void OnWrite(FileHandle handle, int depth)
  13128. {
  13129. FPrint(handle, _name);
  13130. FPrint(handle, "=\"");
  13131. FPrint(handle, _value);
  13132. FPrint(handle, "\" ");
  13133. }
  13134. };typedef CF_XML_Callback XMLCallback;
  13135.  
  13136. class CF_XML_Callback : Managed
  13137. {
  13138. void OnStart(CF_XML_Document document);
  13139.  
  13140. void OnSuccess(CF_XML_Document document);
  13141.  
  13142. void OnFailure(CF_XML_Document document);
  13143. };typedef CF_XML_Document XMLDocument;
  13144.  
  13145. class CF_XML_Document : CF_XML_Element
  13146. {
  13147. private CF_XML_Tag _currentTag;
  13148.  
  13149. private ref CF_XML_Reader _reader;
  13150.  
  13151. private autoptr map<string, string> _entities = new map<string, string>();
  13152.  
  13153. void CF_XML_Document(CF_XML_Tag parent = NULL)
  13154. {
  13155. _entities.Insert("&quot;", "\"");
  13156. _entities.Insert("&amp;", "&");
  13157. _entities.Insert("&apos;", "\'");
  13158. _entities.Insert("&lt;", "<");
  13159. _entities.Insert("&gt;", ">");
  13160. }
  13161.  
  13162. override CF_XML_Tag CreateTag(string name)
  13163. {
  13164. if (_currentTag)
  13165. {
  13166. _currentTag = _currentTag.CreateTag(name);
  13167. }
  13168. else
  13169. {
  13170. _currentTag = super.CreateTag(name);
  13171. }
  13172.  
  13173. return _currentTag;
  13174. }
  13175.  
  13176. CF_XML_Document CopyDocument()
  13177. {
  13178. CF_XML_Document document = new CF_XML_Document(NULL);
  13179.  
  13180. for (int i = 0; i < _tags.Count(); ++i)
  13181. {
  13182. document._tags.Insert(_tags[i].Copy(this));
  13183. }
  13184.  
  13185. return document;
  13186. }
  13187.  
  13188. private bool ReadAttribute()
  13189. {
  13190. if (!_currentTag)
  13191. {
  13192. _reader.Err("Attempting to read attribute when not in tag!");
  13193. return false;
  13194. }
  13195.  
  13196. bool isQuoted;
  13197. string name = _reader.GetWord();
  13198. string eq = _reader.GetCharacter();
  13199. string value = _reader.GetQuotedWord(isQuoted);
  13200.  
  13201. if (eq != "=")
  13202. {
  13203. _reader.Err("Expected '=' for attribute, got: " + eq);
  13204. return false;
  13205. }
  13206.  
  13207. CF_XML_Attribute attrib = _currentTag.CreateAttribute(name);
  13208. attrib.SetValue(value);
  13209.  
  13210. return true;
  13211. }
  13212.  
  13213. private bool PopTag()
  13214. {
  13215. if (!_currentTag)
  13216. return true;
  13217.  
  13218. if (_currentTag.GetParent())
  13219. _currentTag = _currentTag.GetParent().GetParent();
  13220. else
  13221. _currentTag = NULL;
  13222.  
  13223. return true;
  13224. }
  13225.  
  13226. private bool ReadTag()
  13227. {
  13228. string c = _reader.SkipWhitespace();
  13229. string tagName = "";
  13230.  
  13231. if (c == "<")
  13232. {
  13233. c = _reader.GetCharacter();
  13234. if (c == "/")
  13235. {
  13236. tagName = _reader.GetWord();
  13237.  
  13238. if (_currentTag == NULL)
  13239. {
  13240. _reader.Err("Unexpected closing tag: " + tagName);
  13241. }
  13242.  
  13243. c = _reader.GetCharacter();
  13244. if (c != ">")
  13245. {
  13246. _reader.Err("Expected '>' for closing tag, got: " + c);
  13247. }
  13248.  
  13249. PopTag();
  13250.  
  13251. return true;
  13252. }
  13253.  
  13254. if (c != "?")
  13255. _reader.BackChar();
  13256.  
  13257. tagName = _reader.GetWord();
  13258.  
  13259. CreateTag(tagName);
  13260.  
  13261. c = _reader.SkipWhitespace();
  13262. while (c != "/" && c != "?" && c != ">")
  13263. {
  13264. c = _reader.BackChar();
  13265.  
  13266. if (!ReadAttribute())
  13267. return false;
  13268.  
  13269. c = _reader.SkipWhitespace();
  13270. }
  13271.  
  13272. if (c == "/" || c == "?")
  13273. {
  13274. c = _reader.GetCharacter();
  13275. if (c != ">")
  13276. {
  13277. _reader.Err("Expected '>' for inline closing tag, got: " + c);
  13278. }
  13279.  
  13280. PopTag();
  13281. }
  13282. else if (c == ">")
  13283. {
  13284. c = _reader.SkipWhitespace();
  13285. if (c == "<")
  13286. {
  13287. c = _reader.BackChar();
  13288. return true;
  13289. }
  13290.  
  13291. string content = c;
  13292.  
  13293. while (true)
  13294. {
  13295. bool wasNewLine = _reader.WasNewLine();
  13296. if (wasNewLine) c = _reader.SkipWhitespace();
  13297. else c = _reader.GetCharacter();
  13298.  
  13299. if (c != "<")
  13300. {
  13301. if (wasNewLine) content += "\n";
  13302. content += c;
  13303. continue;
  13304. }
  13305.  
  13306. c = _reader.GetCharacter();
  13307. if (c != "/")
  13308. {
  13309. _reader.Err("Expected '/' for inline closing tag, got: " + c);
  13310. }
  13311.  
  13312. tagName = _reader.GetWord();
  13313.  
  13314. if (tagName != _currentTag.GetName())
  13315. {
  13316. _reader.Err("Unexpected closing tag: " + tagName);
  13317. }
  13318.  
  13319. break;
  13320. }
  13321.  
  13322. foreach (string ent_key, string ent_val : _entities)
  13323. content.Replace(ent_key, ent_val);
  13324.  
  13325. _currentTag.GetContent().SetContent(content);
  13326.  
  13327. c = _reader.GetCharacter();
  13328. if (c != ">")
  13329. {
  13330. _reader.Err("Expected '>' for closing tag, got: " + c);
  13331. }
  13332.  
  13333. PopTag();
  13334.  
  13335. return true;
  13336. }
  13337. else
  13338. {
  13339. _reader.Err("Expected '>' for opening element within tag, got: " + c);
  13340. }
  13341.  
  13342. return true;
  13343. }
  13344.  
  13345. // could just be non-tagged content.
  13346.  
  13347. return true;
  13348. }
  13349.  
  13350. bool Read(CF_XML_Reader reader)
  13351. {
  13352. _reader = reader;
  13353.  
  13354. while (!_reader.EOF())
  13355. {
  13356. if (!ReadTag())
  13357. {
  13358. delete _reader;
  13359. return false;
  13360. }
  13361. }
  13362.  
  13363. delete _reader;
  13364. return true;
  13365. }
  13366.  
  13367. void Save(string path)
  13368. {
  13369. ThreadWrite(path);
  13370. //GetGame().GameScript.Call( this, "ThreadWrite", path );
  13371. }
  13372.  
  13373. private void ThreadWrite(string path)
  13374. {
  13375. FileHandle handle = OpenFile(path, FileMode.WRITE);
  13376. if (handle != 0)
  13377. {
  13378. OnWrite(handle, 0);
  13379. CloseFile(handle);
  13380. }
  13381. }
  13382. };typedef CF_XML_Element XMLElement;
  13383.  
  13384. class CF_XML_Element : Managed
  13385. {
  13386. protected autoptr array<autoptr CF_XML_Tag> _tags = new array<autoptr CF_XML_Tag>;
  13387.  
  13388. protected CF_XML_Tag _parentTag;
  13389.  
  13390. protected string _data;
  13391.  
  13392. void CF_XML_Element(CF_XML_Tag parent = NULL)
  13393. {
  13394. #ifdef CF_TRACE_ENABLED
  13395. auto trace = CF_Trace_1(this).Add(parent);
  13396. #endif
  13397.  
  13398. _parentTag = parent;
  13399. }
  13400.  
  13401. void ~CF_XML_Element()
  13402. {
  13403. #ifdef CF_TRACE_ENABLED
  13404. auto trace = CF_Trace_0(this);
  13405. #endif
  13406. }
  13407.  
  13408. CF_XML_Element Copy(CF_XML_Tag parent = NULL)
  13409. {
  13410. CF_XML_Element element = new CF_XML_Element(parent);
  13411.  
  13412. for (int i = 0; i < _tags.Count(); ++i)
  13413. {
  13414. element._tags.Insert(_tags[i].Copy(element));
  13415. }
  13416.  
  13417. element._data = "" + _data;
  13418.  
  13419. return element;
  13420. }
  13421.  
  13422. CF_XML_Tag CreateTag(string name)
  13423. {
  13424. CF_XML_Tag tag = new CF_XML_Tag(this, name);
  13425.  
  13426. _tags.Insert(tag);
  13427.  
  13428. return tag;
  13429. }
  13430.  
  13431. int Count()
  13432. {
  13433. return _tags.Count();
  13434. }
  13435.  
  13436. CF_XML_Tag Get(int index)
  13437. {
  13438. return _tags[index];
  13439. }
  13440.  
  13441. void Remove(CF_XML_Tag tag)
  13442. {
  13443. int index = _tags.Find(tag);
  13444. if (index >= 0)
  13445. _tags.Remove(index);
  13446. }
  13447.  
  13448. array<CF_XML_Tag> Get(string type)
  13449. {
  13450. array<CF_XML_Tag> tags = new array<CF_XML_Tag>;
  13451.  
  13452. for (int i = 0; i < _tags.Count(); ++i)
  13453. {
  13454. if (_tags[i].GetName() == type)
  13455. {
  13456. tags.Insert(_tags[i]);
  13457. }
  13458. }
  13459.  
  13460. return tags;
  13461. }
  13462.  
  13463. void SetContent(string data)
  13464. {
  13465. _data = data;
  13466. }
  13467.  
  13468. string GetContent()
  13469. {
  13470. return _data;
  13471. }
  13472.  
  13473. CF_XML_Tag GetParent()
  13474. {
  13475. return _parentTag;
  13476. }
  13477.  
  13478. void Debug(int level = 0)
  13479. {
  13480. string indent = CF_Indent(level);
  13481.  
  13482. CF_Log.Info(indent + "Tags: count=" + _tags.Count());
  13483. for (int i = 0; i < _tags.Count(); ++i)
  13484. {
  13485. _tags[i].Debug(level + 1);
  13486. }
  13487. }
  13488.  
  13489. void OnWrite(FileHandle handle, int depth)
  13490. {
  13491. string indent = CF_XML_Indent(depth);
  13492.  
  13493. FPrint(handle, _data);
  13494.  
  13495. for (int i = 0; i < _tags.Count(); ++i)
  13496. {
  13497. _tags[i].OnWrite(handle, depth);
  13498. }
  13499. }
  13500. };typedef CF_XML_Reader XMLReader;
  13501.  
  13502. class CF_XML_Reader : Managed
  13503. {
  13504. private int _arrIdx = 0;
  13505. private int _bufIdx = -1;
  13506.  
  13507. private bool _wasNewLine;
  13508.  
  13509. private ref array<string> _lines = new array<string>;
  13510.  
  13511. void CF_XML_Reader()
  13512. {
  13513. #ifdef CF_TRACE_ENABLED
  13514. auto trace = CF_Trace_0(this);
  13515. #endif
  13516. }
  13517.  
  13518. void ~CF_XML_Reader()
  13519. {
  13520. #ifdef CF_TRACE_ENABLED
  13521. auto trace = CF_Trace_0(this);
  13522. #endif
  13523. }
  13524.  
  13525. void GetPosition(out int arrIdx, out int bufIdx)
  13526. {
  13527. arrIdx = _arrIdx;
  13528. bufIdx = _bufIdx;
  13529. }
  13530.  
  13531. void SetPosition(out int arrIdx, out int bufIdx)
  13532. {
  13533. _arrIdx = arrIdx;
  13534. _bufIdx = bufIdx;
  13535. }
  13536.  
  13537. void Err(string message)
  13538. {
  13539. CF_Log.Error("[" + (_arrIdx + 1 ) + ":" + _bufIdx + "] " + message);
  13540. }
  13541.  
  13542. void AddLine(string line)
  13543. {
  13544. if (line.Length() != 0)
  13545. _lines.Insert(line);
  13546. }
  13547.  
  13548. bool WasNewLine()
  13549. {
  13550. return _wasNewLine;
  13551. }
  13552.  
  13553. string BackChar()
  13554. {
  13555. _wasNewLine = false;
  13556.  
  13557. _bufIdx--;
  13558. if (_bufIdx < 0)
  13559. {
  13560. _arrIdx--;
  13561.  
  13562. if (_arrIdx < 0)
  13563. {
  13564. return "";
  13565. }
  13566.  
  13567. _bufIdx = _lines[_arrIdx].Length() - 1;
  13568. }
  13569.  
  13570. if (_bufIdx == 0) _wasNewLine = true;
  13571.  
  13572. return _lines[_arrIdx].SubstringUtf8(_bufIdx, 1);
  13573. }
  13574.  
  13575. private string ReadChar()
  13576. {
  13577. _wasNewLine = false;
  13578.  
  13579. _bufIdx++;
  13580.  
  13581. if (_bufIdx >= _lines[_arrIdx].Length())
  13582. {
  13583. _bufIdx = 0;
  13584.  
  13585. _arrIdx++;
  13586.  
  13587. _wasNewLine = true;
  13588.  
  13589. if (_arrIdx >= _lines.Count())
  13590. {
  13591. return "";
  13592. }
  13593. }
  13594.  
  13595. return _lines[_arrIdx].SubstringUtf8(_bufIdx, 1);
  13596. }
  13597.  
  13598. bool EOF()
  13599. {
  13600. return _arrIdx >= _lines.Count() || (_arrIdx == _lines.Count() - 1 && _bufIdx >= _lines[_arrIdx].Length());
  13601. }
  13602.  
  13603. private void SkipComment()
  13604. {
  13605. string c = ReadChar();
  13606. while (true)
  13607. {
  13608. if (EOF())
  13609. {
  13610. CF_Log.Error("Unexpected end of file while parsing XML comment!");
  13611. break;
  13612. }
  13613.  
  13614. if (c != ">")
  13615. {
  13616. c = ReadChar();
  13617. continue;
  13618. }
  13619.  
  13620. BackChar();
  13621. BackChar();
  13622. BackChar();
  13623.  
  13624. string check = ReadChar() + ReadChar() + ReadChar();
  13625. if (check == "-->")
  13626. {
  13627. return;
  13628. }
  13629. else
  13630. {
  13631. c = ReadChar();
  13632. }
  13633. }
  13634. }
  13635.  
  13636. string GetCharacter()
  13637. {
  13638. string c = ReadChar();
  13639. while (true)
  13640. {
  13641. if (c == "<")
  13642. {
  13643. c = ReadChar();
  13644. if (c == "!")
  13645. {
  13646. c = ReadChar();
  13647. if (c == "-")
  13648. {
  13649. c = ReadChar();
  13650. if (c == "-")
  13651. {
  13652. SkipComment();
  13653. }
  13654. else
  13655. {
  13656. BackChar();
  13657. BackChar();
  13658. BackChar();
  13659. return "<";
  13660. }
  13661. }
  13662. else
  13663. {
  13664. BackChar();
  13665. BackChar();
  13666. return "<";
  13667. }
  13668. }
  13669. else
  13670. {
  13671. BackChar();
  13672. return "<";
  13673. }
  13674. }
  13675. else
  13676. {
  13677. return c;
  13678. }
  13679.  
  13680. c = ReadChar();
  13681. }
  13682.  
  13683. return c;
  13684. }
  13685.  
  13686. bool IsWhitespace(string c)
  13687. {
  13688. if (c == " ")
  13689. return true;
  13690. if (c == "\t")
  13691. return true;
  13692. if (c == "\n")
  13693. return true;
  13694. if (c == "\r")
  13695. return true;
  13696.  
  13697. //if ( c == "" )
  13698. // Error( "Unexpected end of string" );
  13699.  
  13700. return false;
  13701. }
  13702.  
  13703. bool IsLetterOrDigit(string c)
  13704. {
  13705. return IsLetterOrDigit(c, false);
  13706. }
  13707.  
  13708. bool IsLetterOrDigit(string c, bool isQuoted)
  13709. {
  13710. int i = c.ToAscii();
  13711. if (i >= 255 || i < 0) //! To my dear @DaOne, please don't use UTF-8 characters :)
  13712. return true;
  13713.  
  13714. if (i < 32)
  13715. return false;
  13716.  
  13717. if (isQuoted && i >= 32 && i <= 126)
  13718. return true;
  13719.  
  13720. if (i >= 48 && i <= 57)
  13721. return true;
  13722.  
  13723. if (i == 95)
  13724. return true;
  13725.  
  13726. if (i > 90)
  13727. i -= 32;
  13728.  
  13729. if (i >= 65 && i <= 90)
  13730. return true;
  13731.  
  13732. return false;
  13733. }
  13734.  
  13735. string SkipWhitespace()
  13736. {
  13737. string c = GetCharacter();
  13738. while (IsWhitespace(c) && !EOF())
  13739. c = GetCharacter();
  13740.  
  13741. return c;
  13742. }
  13743.  
  13744. string GetWord()
  13745. {
  13746. string word = "";
  13747.  
  13748. string c = SkipWhitespace();
  13749.  
  13750. while (IsLetterOrDigit(c) && !EOF())
  13751. {
  13752. word = word + c;
  13753. c = GetCharacter();
  13754. }
  13755.  
  13756. BackChar();
  13757.  
  13758. return word;
  13759. }
  13760.  
  13761. string GetQuotedWord(out bool isQuoted)
  13762. {
  13763. string word = "";
  13764.  
  13765. string c = SkipWhitespace();
  13766.  
  13767. if (c == "\"")
  13768. {
  13769. c = "";
  13770. isQuoted = true;
  13771. }
  13772.  
  13773. while ((IsLetterOrDigit(c, isQuoted) || c == "") && !EOF())
  13774. {
  13775. word = word + c;
  13776. c = GetCharacter();
  13777. if (isQuoted && c == "\"")
  13778. {
  13779. break;
  13780. }
  13781. }
  13782.  
  13783. if (!isQuoted)
  13784. BackChar();
  13785.  
  13786. return word;
  13787. }
  13788. };
  13789. typedef CF_XML_Tag XMLTag;
  13790.  
  13791. class CF_XML_Tag : Managed
  13792. {
  13793. private string _name;
  13794.  
  13795. private autoptr map<string, ref CF_XML_Attribute> _attributes;
  13796.  
  13797. private ref CF_XML_Element _element;
  13798.  
  13799. private CF_XML_Element _parentElement;
  13800.  
  13801. void CF_XML_Tag(CF_XML_Element parent, string name, bool isCopy = false)
  13802. {
  13803. #ifdef CF_TRACE_ENABLED
  13804. auto trace = CF_Trace_3(this).Add(parent).Add(name).Add(isCopy);
  13805. #endif
  13806.  
  13807. _attributes = new map<string, ref CF_XML_Attribute>;
  13808. _parentElement = parent;
  13809. _name = name;
  13810.  
  13811. if (!isCopy)
  13812. _element = new CF_XML_Element(this);
  13813. }
  13814.  
  13815. void ~CF_XML_Tag()
  13816. {
  13817. #ifdef CF_TRACE_ENABLED
  13818. auto trace = CF_Trace_0(this);
  13819. #endif
  13820.  
  13821. for (int i = 0; i < _attributes.Count(); ++i)
  13822. {
  13823. delete _attributes.GetElement(i);
  13824. }
  13825.  
  13826. delete _attributes;
  13827.  
  13828. delete _element;
  13829. }
  13830.  
  13831. CF_XML_Tag Copy(CF_XML_Element parent = NULL)
  13832. {
  13833. CF_XML_Tag tag = new CF_XML_Tag(parent, _name);
  13834.  
  13835. for (int i = 0; i < _attributes.Count(); ++i)
  13836. {
  13837. CF_XML_Attribute attrib = _attributes.GetElement(i).Copy(tag);
  13838. tag._attributes.Insert(attrib.GetName(), attrib);
  13839. }
  13840.  
  13841. tag._element = _element.Copy(tag);
  13842.  
  13843. return tag;
  13844. }
  13845.  
  13846. string GetName()
  13847. {
  13848. return _name;
  13849. }
  13850.  
  13851. CF_XML_Tag CreateTag(string name)
  13852. {
  13853. return _element.CreateTag(name);
  13854. }
  13855.  
  13856. array<CF_XML_Tag> GetTag(string type)
  13857. {
  13858. return _element.Get(type);
  13859. }
  13860.  
  13861. CF_XML_Attribute CreateAttribute(string name)
  13862. {
  13863. CF_XML_Attribute attrb = new CF_XML_Attribute(this, name);
  13864.  
  13865. _attributes.Insert(name, attrb);
  13866.  
  13867. return attrb;
  13868. }
  13869.  
  13870. CF_XML_Attribute GetAttribute(string name)
  13871. {
  13872. return _attributes.Get(name);
  13873. }
  13874.  
  13875. CF_XML_Element GetContent()
  13876. {
  13877. return _element;
  13878. }
  13879.  
  13880. CF_XML_Element GetParent()
  13881. {
  13882. return _parentElement;
  13883. }
  13884.  
  13885. void Debug(int level = 0)
  13886. {
  13887. string indent = CF_Indent(level);
  13888.  
  13889. CF_Log.Info(indent + "Tag:");
  13890. CF_Log.Info(indent + " name=" + _name);
  13891.  
  13892. CF_Log.Info(indent + "Attributes: count=" + _attributes.Count());
  13893. for (int i = 0; i < _attributes.Count(); ++i)
  13894. {
  13895. _attributes.GetElement(i).Debug(level);
  13896. }
  13897.  
  13898. CF_Log.Info(indent + "Element:");
  13899. _element.Debug(level + 1);
  13900. }
  13901.  
  13902. void OnWrite(FileHandle handle, int depth)
  13903. {
  13904. string indent = CF_XML_Indent(depth);
  13905.  
  13906. FPrint(handle, indent);
  13907. FPrint(handle, "<");
  13908. FPrint(handle, _name);
  13909.  
  13910. if (_attributes.Count() > 0)
  13911. {
  13912. FPrint(handle, " ");
  13913.  
  13914. for (int i = 0; i < _attributes.Count(); ++i)
  13915. {
  13916. _attributes.GetElement(i).OnWrite(handle, depth);
  13917. }
  13918. }
  13919.  
  13920. if (_element.Count() > 0)
  13921. {
  13922. FPrint(handle, ">\n");
  13923.  
  13924. _element.OnWrite(handle, depth + 1);
  13925.  
  13926. FPrint(handle, indent);
  13927. FPrint(handle, "<");
  13928. FPrint(handle, _name);
  13929. FPrint(handle, " ");
  13930. }
  13931. else if (_attributes.Count() == 0)
  13932. {
  13933. FPrint(handle, " ");
  13934. }
  13935.  
  13936. FPrint(handle, "/>\n");
  13937. }
  13938. };/*
  13939. modded class ModItemRegisterCallbacks
  13940. {
  13941. ref JMAnimRegister m_AnimRegister;
  13942.  
  13943. void ModItemRegisterCallbacks()
  13944. {
  13945. m_AnimRegister = new JMAnimRegister();
  13946. }
  13947.  
  13948. void ~ModItemRegisterCallbacks()
  13949. {
  13950. delete m_AnimRegister;
  13951. }
  13952.  
  13953. override void RegisterEmptyHanded( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior )
  13954. {
  13955. super.RegisterEmptyHanded( pType, pBehavior );
  13956.  
  13957. m_AnimRegister.OnRegisterEmptyHanded( pType, pBehavior );
  13958. m_AnimRegister.RegisterEmptyHanded( pType, pBehavior );
  13959. }
  13960.  
  13961. override void RegisterOneHanded( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior )
  13962. {
  13963. super.RegisterOneHanded( pType, pBehavior );
  13964.  
  13965. m_AnimRegister.OnRegisterOneHanded( pType, pBehavior );
  13966. m_AnimRegister.RegisterOneHanded( pType, pBehavior );
  13967. }
  13968.  
  13969. override void RegisterTwoHanded( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior )
  13970. {
  13971. super.RegisterTwoHanded( pType, pBehavior );
  13972.  
  13973. m_AnimRegister.OnRegisterTwoHanded( pType, pBehavior );
  13974. m_AnimRegister.RegisterTwoHanded( pType, pBehavior );
  13975. }
  13976.  
  13977. override void RegisterRestrained( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior )
  13978. {
  13979. super.RegisterRestrained( pType, pBehavior );
  13980.  
  13981. m_AnimRegister.OnRegisterRestrained( pType, pBehavior );
  13982. m_AnimRegister.RegisterRestrained( pType, pBehavior );
  13983. }
  13984.  
  13985. override void RegisterSurrender( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior )
  13986. {
  13987. super.RegisterSurrender( pType, pBehavior );
  13988.  
  13989. m_AnimRegister.OnRegisterSurrender( pType, pBehavior );
  13990. m_AnimRegister.RegisterSurrender( pType, pBehavior );
  13991. }
  13992.  
  13993. override void RegisterHeavy( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior )
  13994. {
  13995. super.RegisterHeavy( pType, pBehavior );
  13996.  
  13997. m_AnimRegister.OnRegisterHeavy( pType, pBehavior );
  13998. m_AnimRegister.RegisterHeavy( pType, pBehavior );
  13999. }
  14000.  
  14001. override void RegisterPistol( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior )
  14002. {
  14003. super.RegisterPistol( pType, pBehavior );
  14004.  
  14005. m_AnimRegister.OnRegisterPistol( pType, pBehavior );
  14006. m_AnimRegister.RegisterPistol( pType, pBehavior );
  14007. }
  14008.  
  14009. override void RegisterFireArms( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior )
  14010. {
  14011. super.RegisterFireArms( pType, pBehavior );
  14012.  
  14013. m_AnimRegister.OnRegisterFireArms( pType, pBehavior );
  14014. m_AnimRegister.RegisterFireArms( pType, pBehavior );
  14015. }
  14016.  
  14017. override void RegisterArcheryItem( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior )
  14018. {
  14019. super.RegisterArcheryItem( pType, pBehavior );
  14020.  
  14021. m_AnimRegister.OnRegisterArcheryItem( pType, pBehavior );
  14022. m_AnimRegister.RegisterArcheryItem( pType, pBehavior );
  14023. }
  14024.  
  14025. override void RegisterLauncher( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior )
  14026. {
  14027. super.RegisterLauncher( pType, pBehavior );
  14028.  
  14029. m_AnimRegister.OnRegisterLauncher( pType, pBehavior );
  14030. m_AnimRegister.RegisterLauncher( pType, pBehavior );
  14031. }
  14032.  
  14033. override void RegisterCustom( DayZPlayerType pType )
  14034. {
  14035. super.RegisterCustom( pType );
  14036.  
  14037. m_AnimRegister.OnRegisterCustom( pType, pBehavior );
  14038. m_AnimRegister.RegisterCustom( pType, pBehavior );
  14039. }
  14040.  
  14041. override void CustomBoneRemapping( DayZPlayerType pType )
  14042. {
  14043. super.CustomBoneRemapping( pType );
  14044.  
  14045. m_AnimRegister.OnBoneRemapping( pType );
  14046. m_AnimRegister.BoneRemapping( pType );
  14047. }
  14048. };
  14049. */
  14050.  
  14051. // 107 compatibility
  14052. class JMAnimRegister
  14053. {
  14054. static JMAnimRegister Register( DayZPlayerType pType )
  14055. {
  14056. JMAnimRegister animReg = new JMAnimRegister;
  14057.  
  14058. DayzPlayerItemBehaviorCfg behaviour;
  14059.  
  14060. behaviour = new DayzPlayerItemBehaviorCfg;
  14061. behaviour.SetEmptyHanded();
  14062. animReg.OnRegisterEmptyHanded( pType, behaviour );
  14063. animReg.RegisterEmptyHanded( pType, behaviour );
  14064.  
  14065. behaviour = new DayzPlayerItemBehaviorCfg;
  14066. behaviour.SetTwoHanded();
  14067. animReg.OnRegisterTwoHanded( pType, behaviour );
  14068. animReg.RegisterTwoHanded( pType, behaviour );
  14069.  
  14070. behaviour = new DayzPlayerItemBehaviorCfg;
  14071. behaviour.SetToolsOneHanded();
  14072. animReg.OnRegisterOneHanded( pType, behaviour );
  14073. animReg.RegisterOneHanded( pType, behaviour );
  14074.  
  14075. behaviour = new DayzPlayerItemBehaviorCfg;
  14076. behaviour.SetRestrained();
  14077. animReg.OnRegisterRestrained( pType, behaviour );
  14078. animReg.RegisterRestrained( pType, behaviour );
  14079.  
  14080. behaviour = new DayzPlayerItemBehaviorCfg;
  14081. behaviour.SetSurrender();
  14082. animReg.OnRegisterSurrender( pType, behaviour );
  14083. animReg.RegisterSurrender( pType, behaviour );
  14084.  
  14085. behaviour = new DayzPlayerItemBehaviorCfg;
  14086. behaviour.SetHeavyItems();
  14087. animReg.OnRegisterHeavy( pType, behaviour );
  14088. animReg.RegisterHeavy( pType, behaviour );
  14089.  
  14090. behaviour = new DayzPlayerItemBehaviorCfg;
  14091. behaviour.SetPistols();
  14092. animReg.OnRegisterPistol( pType, behaviour );
  14093. animReg.RegisterPistol( pType, behaviour );
  14094.  
  14095. behaviour = new DayzPlayerItemBehaviorCfg;
  14096. behaviour.SetFirearms();
  14097. animReg.OnRegisterFireArms( pType, behaviour );
  14098. animReg.RegisterFireArms( pType, behaviour );
  14099.  
  14100. behaviour = new DayzPlayerItemBehaviorCfg;
  14101. animReg.OnRegisterArcheryItem( pType, behaviour );
  14102. animReg.RegisterArcheryItem( pType, behaviour );
  14103.  
  14104. behaviour = new DayzPlayerItemBehaviorCfg;
  14105. animReg.OnRegisterLauncher( pType, behaviour );
  14106. animReg.RegisterLauncher( pType, behaviour );
  14107.  
  14108. animReg.OnRegisterCustom( pType );
  14109. animReg.RegisterCustom( pType );
  14110.  
  14111. animReg.OnBoneRemapping( pType );
  14112. animReg.BoneRemapping( pType );
  14113.  
  14114. return animReg;
  14115. }
  14116.  
  14117. void RegisterEmptyHanded( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14118. void OnRegisterEmptyHanded( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14119. void RegisterOneHanded( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14120. void OnRegisterOneHanded( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14121. void RegisterTwoHanded( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14122. void OnRegisterTwoHanded( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14123. void RegisterRestrained( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14124. void OnRegisterRestrained( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14125. void RegisterSurrender( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14126. void OnRegisterSurrender( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14127. void RegisterHeavy( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14128. void OnRegisterHeavy( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14129. void RegisterPistol( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14130. void OnRegisterPistol( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14131. void RegisterFireArms( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14132. void OnRegisterFireArms( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14133. void RegisterArcheryItem( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14134. void OnRegisterArcheryItem( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14135. void RegisterLauncher( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14136. void OnRegisterLauncher( DayZPlayerType pType, DayzPlayerItemBehaviorCfg pBehavior );
  14137. void RegisterCustom( DayZPlayerType pType );
  14138. void OnRegisterCustom( DayZPlayerType pType );
  14139. void BoneRemapping( DayZPlayerType pType );
  14140. void OnBoneRemapping( DayZPlayerType pType );
  14141. };modded class AdvancedCommunication
  14142. {
  14143. // autoptr CF_ModStorageBase m_CF_ModStorage = new CF_ModStorageObject<AdvancedCommunication>(this);
  14144. //
  14145. // override void OnStoreSave(ParamsWriteContext ctx)
  14146. // {
  14147. // super.OnStoreSave(ctx);
  14148. //
  14149. // m_CF_ModStorage.OnStoreSave(ctx);
  14150. // }
  14151. //
  14152. // override bool OnStoreLoad(ParamsReadContext ctx, int version)
  14153. // {
  14154. // if (!super.OnStoreLoad(ctx, version))
  14155. // {
  14156. // return false;
  14157. // }
  14158. //
  14159. // return m_CF_ModStorage.OnStoreLoad(ctx, version);
  14160. // }
  14161.  
  14162. /**
  14163. * @brief Refer to CF/ModStorage implementation of ItemBase::CF_OnStoreSave
  14164. */
  14165. void CF_OnStoreSave(CF_ModStorageMap storage)
  14166. {
  14167. }
  14168.  
  14169. /**
  14170. * @brief Refer to CF/ModStorage implementation of ItemBase::CF_OnStoreLoad
  14171. */
  14172. bool CF_OnStoreLoad(CF_ModStorageMap storage)
  14173. {
  14174. return true;
  14175. }
  14176. };
  14177. modded class AnimalBase
  14178. {
  14179. // autoptr CF_ModStorageBase m_CF_ModStorage = new CF_ModStorageObject<AnimalBase>(this);
  14180. //
  14181. // override void OnStoreSave(ParamsWriteContext ctx)
  14182. // {
  14183. // super.OnStoreSave(ctx);
  14184. //
  14185. // m_CF_ModStorage.OnStoreSave(ctx);
  14186. // }
  14187. //
  14188. // override bool OnStoreLoad(ParamsReadContext ctx, int version)
  14189. // {
  14190. // if (!super.OnStoreLoad(ctx, version))
  14191. // {
  14192. // return false;
  14193. // }
  14194. //
  14195. // return m_CF_ModStorage.OnStoreLoad(ctx, version);
  14196. // }
  14197.  
  14198. /**
  14199. * @brief Refer to CF/ModStorage implementation of ItemBase::CF_OnStoreSave
  14200. */
  14201. void CF_OnStoreSave(CF_ModStorageMap storage)
  14202. {
  14203. }
  14204.  
  14205. /**
  14206. * @brief Refer to CF/ModStorage implementation of ItemBase::CF_OnStoreLoad
  14207. */
  14208. bool CF_OnStoreLoad(CF_ModStorageMap storage)
  14209. {
  14210. return true;
  14211. }
  14212. };
  14213. modded class BuildingBase
  14214. {
  14215. // autoptr CF_ModStorageBase m_CF_ModStorage = new CF_ModStorageObject<BuildingBase>(this);
  14216. //
  14217. // override void OnStoreSave(ParamsWriteContext ctx)
  14218. // {
  14219. // super.OnStoreSave(ctx);
  14220. //
  14221. // m_CF_ModStorage.OnStoreSave(ctx);
  14222. // }
  14223. //
  14224. // override bool OnStoreLoad(ParamsReadContext ctx, int version)
  14225. // {
  14226. // if (!super.OnStoreLoad(ctx, version))
  14227. // {
  14228. // return false;
  14229. // }
  14230. //
  14231. // return m_CF_ModStorage.OnStoreLoad(ctx, version);
  14232. // }
  14233.  
  14234. /**
  14235. * @brief Refer to CF/ModStorage implementation of ItemBase::CF_OnStoreSave
  14236. */
  14237. void CF_OnStoreSave(CF_ModStorageMap storage)
  14238. {
  14239. }
  14240.  
  14241. /**
  14242. * @brief Refer to CF/ModStorage implementation of ItemBase::CF_OnStoreLoad
  14243. */
  14244. bool CF_OnStoreLoad(CF_ModStorageMap storage)
  14245. {
  14246. return true;
  14247. }
  14248. };
  14249. modded class CarScript
  14250. {
  14251. // autoptr CF_ModStorageBase m_CF_ModStorage = new CF_ModStorageObject<CarScript>(this);
  14252. //
  14253. // override void OnStoreSave(ParamsWriteContext ctx)
  14254. // {
  14255. // super.OnStoreSave(ctx);
  14256. //
  14257. // m_CF_ModStorage.OnStoreSave(ctx);
  14258. // }
  14259. //
  14260. // override bool OnStoreLoad(ParamsReadContext ctx, int version)
  14261. // {
  14262. // if (!super.OnStoreLoad(ctx, version))
  14263. // {
  14264. // return false;
  14265. // }
  14266. //
  14267. // return m_CF_ModStorage.OnStoreLoad(ctx, version);
  14268. // }
  14269.  
  14270. /**
  14271. * @brief Refer to CF/ModStorage implementation of ItemBase::CF_OnStoreSave
  14272. */
  14273. void CF_OnStoreSave(CF_ModStorageMap storage)
  14274. {
  14275. }
  14276.  
  14277. /**
  14278. * @brief Refer to CF/ModStorage implementation of ItemBase::CF_OnStoreLoad
  14279. */
  14280. bool CF_OnStoreLoad(CF_ModStorageMap storage)
  14281. {
  14282. return true;
  14283. }
  14284. };
  14285. modded class DayZPlayerImplement
  14286. {
  14287. // autoptr CF_ModStorageBase m_CF_ModStorage = new CF_ModStorageObject<DayZPlayerImplement>(this);
  14288. //
  14289. // override void OnStoreSave(ParamsWriteContext ctx)
  14290. // {
  14291. // super.OnStoreSave(ctx);
  14292. //
  14293. // m_CF_ModStorage.OnStoreSave(ctx);
  14294. // }
  14295. //
  14296. // override bool OnStoreLoad(ParamsReadContext ctx, int version)
  14297. // {
  14298. // if (!super.OnStoreLoad(ctx, version))
  14299. // {
  14300. // return false;
  14301. // }
  14302. //
  14303. // return m_CF_ModStorage.OnStoreLoad(ctx, version);
  14304. // }
  14305.  
  14306. /**
  14307. * @brief Refer to CF/ModStorage implementation of ItemBase::CF_OnStoreSave
  14308. */
  14309. void CF_OnStoreSave(CF_ModStorageMap storage)
  14310. {
  14311. }
  14312.  
  14313. /**
  14314. * @brief Refer to CF/ModStorage implementation of ItemBase::CF_OnStoreLoad
  14315. */
  14316. bool CF_OnStoreLoad(CF_ModStorageMap storage)
  14317. {
  14318. return true;
  14319. }
  14320. };
  14321. modded class HelicopterScript
  14322. {
  14323. // autoptr CF_ModStorageBase m_CF_ModStorage = new CF_ModStorageObject<HelicopterScript>(this);
  14324. //
  14325. // override void OnStoreSave(ParamsWriteContext ctx)
  14326. // {
  14327. // super.OnStoreSave(ctx);
  14328. //
  14329. // m_CF_ModStorage.OnStoreSave(ctx);
  14330. // }
  14331. //
  14332. // override bool OnStoreLoad(ParamsReadContext ctx, int version)
  14333. // {
  14334. // if (!super.OnStoreLoad(ctx, version))
  14335. // {
  14336. // return false;
  14337. // }
  14338. //
  14339. // return m_CF_ModStorage.OnStoreLoad(ctx, version);
  14340. // }
  14341.  
  14342. /**
  14343. * @brief Refer to CF/ModStorage implementation of ItemBase::CF_OnStoreSave
  14344. */
  14345. void CF_OnStoreSave(CF_ModStorageMap storage)
  14346. {
  14347. }
  14348.  
  14349. /**
  14350. * @brief Refer to CF/ModStorage implementation of ItemBase::CF_OnStoreLoad
  14351. */
  14352. bool CF_OnStoreLoad(CF_ModStorageMap storage)
  14353. {
  14354. return true;
  14355. }
  14356. };
  14357. modded class ItemBase
  14358. {
  14359. // autoptr CF_ModStorageBase m_CF_ModStorage = new CF_ModStorageObject<ItemBase>(this);
  14360. //
  14361. // override void OnStoreSave(ParamsWriteContext ctx)
  14362. // {
  14363. // super.OnStoreSave(ctx);
  14364. //
  14365. // m_CF_ModStorage.OnStoreSave(ctx);
  14366. // }
  14367. //
  14368. // override bool OnStoreLoad(ParamsReadContext ctx, int version)
  14369. // {
  14370. // if (!super.OnStoreLoad(ctx, version))
  14371. // {
  14372. // return false;
  14373. // }
  14374. //
  14375. // return m_CF_ModStorage.OnStoreLoad(ctx, version);
  14376. // }
  14377.  
  14378. /**
  14379. * @param storage Map of 'CF_ModStorage' classes
  14380. *
  14381. * @code
  14382. * modded class KitBase // extends from ItemBase
  14383. * {
  14384. * override void CF_OnStoreSave(CF_ModStorageMap storage)
  14385. * {
  14386. * //! Always call super at the start.
  14387. * super.CF_OnStoreSave(storage);
  14388. *
  14389. * auto ctx = storage["JM_CommunityFramework"];
  14390. *
  14391. * ctx.Write(GetOrientation());
  14392. * ctx.Write(6);
  14393.  
  14394. * ctx.Write("ThisVariableIsAddedWithVersion2");
  14395. * }
  14396. * }
  14397. */
  14398. void CF_OnStoreSave(CF_ModStorageMap storage)
  14399. {
  14400. }
  14401.  
  14402. /**
  14403. * @param storage Map of 'CF_ModStorage' classes
  14404. *
  14405. * @return True if loading was successful
  14406. *
  14407. * @code
  14408. * modded class KitBase // extends from ItemBase
  14409. * {
  14410. * override bool CF_OnStoreLoad(CF_ModStorageMap storage)
  14411. * {
  14412. * if (!super.CF_OnStoreLoad(storage)) return false;
  14413. *
  14414. * auto ctx = storage["JM_CommunityFramework"];
  14415. * if (!ctx) return true;
  14416. *
  14417. * vector orientation;
  14418. * if (!ctx.Read(orientation)) return false;
  14419. *
  14420. * string intVar;
  14421. * if (!ctx.Read(intVar)) return false;
  14422. *
  14423. * //! The version of the mod is set in config 'storageVersion' for 'CfgMods' class
  14424. *
  14425. * string strVar;
  14426. * if (ctx.GetVersion() > 1)
  14427. * {
  14428. * if (!ctx.Read(strVar)) return false;
  14429. * }
  14430. * else
  14431. * {
  14432. * strVar = "Default Value";
  14433. * }
  14434. *
  14435. * return true;
  14436. * }
  14437. * }
  14438. * @endcode
  14439. */
  14440. bool CF_OnStoreLoad(CF_ModStorageMap storage)
  14441. {
  14442. return true;
  14443. }
  14444. };
  14445. modded class DayZPlayerCameras
  14446. {
  14447. static override void RegisterCameras( DayZPlayerType pType )
  14448. {
  14449. JMAnimRegister.Register( pType );
  14450.  
  14451. pType.ResetCameraCreators();
  14452.  
  14453. //!
  14454. //! this registers camera ids for camera script class implementation
  14455. //! which camera is used at the time is specified by DayzPlayerImplement.CamraHandler which returns id
  14456. //!
  14457. pType.RegisterCameraCreator(DAYZCAMERA_1ST, DayZPlayerCamera1stPerson);
  14458. pType.RegisterCameraCreator(DAYZCAMERA_3RD_ERC, DayZPlayerCamera3rdPersonErc);
  14459. pType.RegisterCameraCreator(DAYZCAMERA_3RD_ERC_SPR, DayZPlayerCamera3rdPersonErcSpr);
  14460. pType.RegisterCameraCreator(DAYZCAMERA_3RD_ERC_RAISED, DayZPlayerCamera3rdPersonErcRaised);
  14461. pType.RegisterCameraCreator(DAYZCAMERA_3RD_CRO, DayZPlayerCamera3rdPersonCrouch);
  14462. pType.RegisterCameraCreator(DAYZCAMERA_3RD_CRO_RAISED, DayZPlayerCamera3rdPersonCrouchRaised);
  14463. pType.RegisterCameraCreator(DAYZCAMERA_3RD_PRO, DayZPlayerCamera3rdPersonProne);
  14464. pType.RegisterCameraCreator(DAYZCAMERA_3RD_PRO_RAISED, DayZPlayerCamera3rdPersonProneRaised);
  14465. pType.RegisterCameraCreator(DAYZCAMERA_IRONSIGHTS, DayZPlayerCameraIronsights);
  14466. pType.RegisterCameraCreator(DAYZCAMERA_OPTICS, DayZPlayerCameraOptics);
  14467. pType.RegisterCameraCreator(DAYZCAMERA_3RD_ERC_RAISED_MELEE, DayZPlayerCamera3rdPersonErcRaisedMelee);
  14468. pType.RegisterCameraCreator(DAYZCAMERA_1ST_UNCONSCIOUS, DayZPlayerCamera1stPersonUnconscious);
  14469. pType.RegisterCameraCreator(DAYZCAMERA_3RD_JUMP, DayZPlayerCamera3rdPersonJump);
  14470. pType.RegisterCameraCreator(DAYZCAMERA_3RD_CLIMB, DayZPlayerCamera3rdPersonClimb);
  14471.  
  14472. pType.RegisterCameraCreator(DAYZCAMERA_1ST_VEHICLE, DayZPlayerCamera1stPersonVehicle);
  14473. pType.RegisterCameraCreator(DAYZCAMERA_3RD_VEHICLE, DayZPlayerCamera3rdPersonVehicle);
  14474.  
  14475.  
  14476. //! Blend times when changing cameras
  14477. //! 3rd person erected camera transition
  14478. RegisterTransitionTime(DAYZCAMERA_3RD_ERC, DAYZCAMERA_3RD_CRO, 0.4, false);
  14479. RegisterTransitionTime(DAYZCAMERA_3RD_ERC, DAYZCAMERA_3RD_PRO, 0.8, false);
  14480. RegisterTransitionTime(DAYZCAMERA_3RD_ERC, DAYZCAMERA_3RD_PRO_RAISED, 0.8, false);
  14481. RegisterTransitionTime(DAYZCAMERA_3RD_ERC, DAYZCAMERA_3RD_ERC_RAISED, 0.2, false);
  14482. RegisterTransitionTime(DAYZCAMERA_3RD_ERC, DAYZCAMERA_3RD_ERC_RAISED_MELEE, 0.2, false);
  14483. RegisterTransitionTime(DAYZCAMERA_3RD_ERC, DAYZCAMERA_3RD_ERC_SPR, 0.6, false);
  14484. RegisterTransitionTime(DAYZCAMERA_3RD_ERC_RAISED, DAYZCAMERA_3RD_ERC_SPR, 0.7, false);
  14485. RegisterTransitionTime(DAYZCAMERA_3RD_ERC_RAISED, DAYZCAMERA_3RD_PRO_RAISED, 0.8, false);
  14486. RegisterTransitionTime(DAYZCAMERA_3RD_ERC_SPR, DAYZCAMERA_3RD_ERC, 0.3, false);
  14487. RegisterTransitionTime(DAYZCAMERA_3RD_ERC_SPR, DAYZCAMERA_3RD_CRO, 0.3, false);
  14488. RegisterTransitionTime(DAYZCAMERA_3RD_ERC_SPR, DAYZCAMERA_3RD_PRO, 0.5, false);
  14489. RegisterTransitionTime(DAYZCAMERA_3RD_ERC_SPR, DAYZCAMERA_3RD_ERC_RAISED, 0.3, false);
  14490. RegisterTransitionTime(DAYZCAMERA_3RD_ERC_SPR, DAYZCAMERA_3RD_JUMP, 0.1, false);
  14491. RegisterTransitionTime(DAYZCAMERA_3RD_JUMP, DAYZCAMERA_3RD_ERC_SPR, 0.2, false);
  14492. RegisterTransitionTime(DAYZCAMERA_3RD_ERC, DAYZCAMERA_3RD_JUMP, 0.05, false);
  14493. RegisterTransitionTime(DAYZCAMERA_3RD_JUMP, DAYZCAMERA_3RD_ERC, 0.3, false);
  14494. RegisterTransitionTime(DAYZCAMERA_3RD_ERC, DAYZCAMERA_3RD_CLIMB, 0.3, false);
  14495. RegisterTransitionTime(DAYZCAMERA_3RD_CLIMB, DAYZCAMERA_3RD_ERC, 0.3, false);
  14496.  
  14497. //! 3rd person crouch camera transitions
  14498. RegisterTransitionTime(DAYZCAMERA_3RD_CRO, DAYZCAMERA_3RD_ERC, 0.4, false);
  14499. RegisterTransitionTime(DAYZCAMERA_3RD_CRO, DAYZCAMERA_3RD_PRO, 0.6, true);
  14500. RegisterTransitionTime(DAYZCAMERA_3RD_CRO, DAYZCAMERA_3RD_CRO_RAISED, 0.2, true);
  14501. RegisterTransitionTime(DAYZCAMERA_3RD_CRO, DAYZCAMERA_3RD_ERC_SPR, 0.6, false);
  14502.  
  14503. //! 3rd person prone camera transitions
  14504. RegisterTransitionTime(DAYZCAMERA_3RD_PRO, DAYZCAMERA_3RD_ERC, 0.9, false);
  14505. RegisterTransitionTime(DAYZCAMERA_3RD_PRO, DAYZCAMERA_3RD_CRO, 0.7, false);
  14506. RegisterTransitionTime(DAYZCAMERA_3RD_PRO, DAYZCAMERA_3RD_PRO_RAISED, 0.2, false);
  14507. RegisterTransitionTime(DAYZCAMERA_3RD_PRO, DAYZCAMERA_3RD_ERC_SPR, 0.6, false);
  14508. RegisterTransitionTime(DAYZCAMERA_3RD_PRO_RAISED, DAYZCAMERA_3RD_CRO, 0.7, false);
  14509. RegisterTransitionTime(DAYZCAMERA_3RD_PRO_RAISED, DAYZCAMERA_3RD_CRO_RAISED, 0.7, false);
  14510. RegisterTransitionTime(DAYZCAMERA_3RD_PRO_RAISED, DAYZCAMERA_3RD_ERC, 0.9, false);
  14511. RegisterTransitionTime(DAYZCAMERA_3RD_PRO_RAISED, DAYZCAMERA_3RD_ERC_RAISED, 0.9, false);
  14512.  
  14513. //! ironsights camera transitions
  14514. RegisterTransitionTime(DAYZCAMERA_3RD_ERC_RAISED, DAYZCAMERA_IRONSIGHTS, TIME_CAMERACHANGE_02, true);
  14515. RegisterTransitionTime(DAYZCAMERA_3RD_CRO_RAISED, DAYZCAMERA_IRONSIGHTS, TIME_CAMERACHANGE_02, true);
  14516. RegisterTransitionTime(DAYZCAMERA_3RD_PRO_RAISED, DAYZCAMERA_IRONSIGHTS, TIME_CAMERACHANGE_02, true);
  14517. RegisterTransitionTime(DAYZCAMERA_1ST, DAYZCAMERA_IRONSIGHTS, TIME_CAMERACHANGE_01, true);
  14518.  
  14519. RegisterTransitionTime(DAYZCAMERA_3RD_ERC, DAYZCAMERA_IRONSIGHTS, TIME_CAMERACHANGE_02, true);
  14520. RegisterTransitionTime(DAYZCAMERA_3RD_CRO, DAYZCAMERA_IRONSIGHTS, TIME_CAMERACHANGE_02, true);
  14521. RegisterTransitionTime(DAYZCAMERA_3RD_PRO, DAYZCAMERA_IRONSIGHTS, TIME_CAMERACHANGE_02, true);
  14522.  
  14523. //! optics camera transitions
  14524. RegisterTransitionTime(DAYZCAMERA_IRONSIGHTS, DAYZCAMERA_OPTICS, TIME_CAMERACHANGE_02, true);
  14525. RegisterTransitionTime(DAYZCAMERA_3RD_ERC_RAISED, DAYZCAMERA_OPTICS, TIME_CAMERACHANGE_03, true);
  14526. RegisterTransitionTime(DAYZCAMERA_3RD_CRO_RAISED, DAYZCAMERA_OPTICS, TIME_CAMERACHANGE_03, true);
  14527. RegisterTransitionTime(DAYZCAMERA_3RD_PRO_RAISED, DAYZCAMERA_OPTICS, TIME_CAMERACHANGE_03, true);
  14528.  
  14529. RegisterTransitionTime(DAYZCAMERA_1ST, DAYZCAMERA_OPTICS, TIME_CAMERACHANGE_02, true); //handheld optics only
  14530. RegisterTransitionTime(DAYZCAMERA_3RD_ERC, DAYZCAMERA_OPTICS, TIME_CAMERACHANGE_02, true); //handheld optics only
  14531. RegisterTransitionTime(DAYZCAMERA_3RD_CRO, DAYZCAMERA_OPTICS, TIME_CAMERACHANGE_02, true); //handheld optics only
  14532. RegisterTransitionTime(DAYZCAMERA_3RD_PRO, DAYZCAMERA_OPTICS, TIME_CAMERACHANGE_02, true); //handheld optics only
  14533.  
  14534. //! register function to handle camera changes
  14535. pType.RegisterCameraOnChangeFnStatic(DayZPlayerCameras, "OnCameraChange");
  14536. };
  14537. };modded class ZombieBase
  14538. {
  14539. // autoptr CF_ModStorageBase m_CF_ModStorage = new CF_ModStorageObject<ZombieBase>(this);
  14540. //
  14541. // override void OnStoreSave(ParamsWriteContext ctx)
  14542. // {
  14543. // super.OnStoreSave(ctx);
  14544. //
  14545. // m_CF_ModStorage.OnStoreSave(ctx);
  14546. // }
  14547. //
  14548. // override bool OnStoreLoad(ParamsReadContext ctx, int version)
  14549. // {
  14550. // if (!super.OnStoreLoad(ctx, version))
  14551. // {
  14552. // return false;
  14553. // }
  14554. //
  14555. // return m_CF_ModStorage.OnStoreLoad(ctx, version);
  14556. // }
  14557.  
  14558. /**
  14559. * @brief Refer to CF/ModStorage implementation of ItemBase::CF_OnStoreSave
  14560. */
  14561. void CF_OnStoreSave(CF_ModStorageMap storage)
  14562. {
  14563. }
  14564.  
  14565. /**
  14566. * @brief Refer to CF/ModStorage implementation of ItemBase::CF_OnStoreLoad
  14567. */
  14568. bool CF_OnStoreLoad(CF_ModStorageMap storage)
  14569. {
  14570. return true;
  14571. }
  14572. };
  14573. class CF_EventPlayerArgs : CF_EventArgs
  14574. {
  14575. PlayerBase Player;
  14576. PlayerIdentity Identity;
  14577.  
  14578. void CF_EventPlayerArgs(PlayerBase player = null, PlayerIdentity identity = null)
  14579. {
  14580. Player = player;
  14581. Identity = identity;
  14582. }
  14583. };
  14584.  
  14585. class CF_EventPlayerDisconnectedArgs : CF_EventPlayerArgs
  14586. {
  14587. string UID;
  14588. int LogoutTime = -1; // -1 for Disconnected
  14589. bool AuthFailed;
  14590. };
  14591.  
  14592. class CF_EventNewPlayerArgs : CF_EventPlayerArgs
  14593. {
  14594. vector Position;
  14595. ParamsReadContext Context;
  14596.  
  14597. void CF_EventNewPlayerArgs(PlayerBase player = null, PlayerIdentity identity = null, vector position = "0 0 0", ParamsReadContext ctx = null)
  14598. {
  14599. Position = position;
  14600. Context = ctx;
  14601. }
  14602. };
  14603.  
  14604. class CF_EventPlayerPrepareArgs : CF_EventArgs
  14605. {
  14606. PlayerIdentity Identity;
  14607. bool UseDatabase;
  14608. vector Position;
  14609. float Yaw;
  14610. int PreloadTimeout;
  14611. };
  14612. class CF_ModStorageBase
  14613. {
  14614. void OnStoreSave(ParamsWriteContext ctx)
  14615. {
  14616. }
  14617.  
  14618. bool OnStoreLoad(ParamsReadContext ctx, int version)
  14619. {
  14620. return true;
  14621. }
  14622. };
  14623. #ifndef CF_MODSTORAGE_DISABLE
  14624. class CF_ModStorageObject<Class T> : CF_ModStorageBase
  14625. {
  14626. T m_Entity;
  14627.  
  14628. autoptr array<ref CF_ModStorage> m_UnloadedMods;
  14629.  
  14630. CF_ModStorageModule m_Module;
  14631.  
  14632. void CF_ModStorageObject(T entity)
  14633. {
  14634. m_Entity = entity;
  14635. m_UnloadedMods = new array<ref CF_ModStorage>();
  14636.  
  14637. ModLoader.LoadMods();
  14638.  
  14639. // Reset the stream for 'OnStoreSave'
  14640. foreach (auto mod : ModLoader.s_CF_ModStorages)
  14641. {
  14642. mod._ResetStream();
  14643. }
  14644.  
  14645. m_Module = CF_Modules<CF_ModStorageModule>.Get();
  14646. }
  14647.  
  14648. override void OnStoreSave(ParamsWriteContext ctx)
  14649. {
  14650. #ifdef CF_MODSTORAGE_TRACE
  14651. auto trace = CF_Trace_1(this).Add(ctx);
  14652. #endif
  14653.  
  14654. if (GetGame().SaveVersion() < CF_ModStorage.GAME_VERSION_FIRST_INSTALL)
  14655. {
  14656. return;
  14657. }
  14658.  
  14659. #ifndef CF_MODSTORAGE_MODULE_DISABLE
  14660. int b1, b2, b3, b4;
  14661. m_Entity.GetPersistentID(b1, b2, b3, b4);
  14662.  
  14663. // Add the entity to the file so on next load the game knows that it can read the modstorage for the entity
  14664. m_Module.AddEntity(b1, b2, b3, b4);
  14665. #endif
  14666.  
  14667. // Write the CF modstorage version
  14668. ctx.Write(CF_ModStorage.VERSION);
  14669.  
  14670. // Reset the stream for 'OnStoreSave'
  14671. foreach (auto mod : ModLoader.s_CF_ModStorages)
  14672. {
  14673. mod._ResetStream();
  14674. }
  14675.  
  14676. m_Entity.CF_OnStoreSave(ModLoader.s_CF_ModStorageMap);
  14677.  
  14678. ctx.Write(ModLoader.s_CF_ModStorages.Count() + m_UnloadedMods.Count());
  14679.  
  14680. foreach (auto mod2 : ModLoader.s_CF_ModStorages)
  14681. {
  14682. // also resets the stream for next 'OnStoreSave'
  14683. mod2._CopyStreamTo(ctx);
  14684. }
  14685.  
  14686. foreach (auto unloadedMod : m_UnloadedMods)
  14687. {
  14688. // Since mod is unloaded, the stream is not reset
  14689. unloadedMod._CopyStreamTo(ctx);
  14690. }
  14691. }
  14692.  
  14693. override bool OnStoreLoad(ParamsReadContext ctx, int version)
  14694. {
  14695. #ifdef CF_MODSTORAGE_TRACE
  14696. auto trace = CF_Trace_2(this).Add(ctx).Add(version);
  14697. #endif
  14698.  
  14699. // Clearing the unloaded mods data
  14700. m_UnloadedMods.Clear();
  14701.  
  14702. // Persistence version is prior to 1.10
  14703. if (version < CF_ModStorage.GAME_VERSION_FIRST_INSTALL)
  14704. {
  14705. return true;
  14706. }
  14707.  
  14708. #ifndef CF_MODSTORAGE_MODULE_DISABLE
  14709. int b1, b2, b3, b4;
  14710. m_Entity.GetPersistentID(b1, b2, b3, b4);
  14711.  
  14712. // If the version is less than the wipe file, the entity will be added automatically in 'OnStoreSave'
  14713. if (version >= CF_ModStorage.GAME_VERSION_WIPE_FILE)
  14714. {
  14715. if (!m_Module.IsEntity(b1, b2, b3, b4))
  14716. {
  14717. // Since the entity wasn't found we can assume that CF is freshly loaded
  14718. // Highly unlikely anything else happened that can cause this
  14719. // * A new entity won't take the ID of an old entity if it is in circulation
  14720. // * If this is a new entity, OnStoreSave would've been called at some point before 'OnStoreLoad'
  14721. return true;
  14722. }
  14723. }
  14724. #endif
  14725.  
  14726. int cf_version;
  14727. if (!ctx.Read(cf_version))
  14728. {
  14729. return false;
  14730. }
  14731.  
  14732. // CF version is prior to ModStorage implementation
  14733. if (cf_version < CF_ModStorage.MODSTORAGE_INITIAL_IMPLEMENTATION)
  14734. {
  14735. return true;
  14736. }
  14737.  
  14738. int numMods;
  14739. if (!ctx.Read(numMods))
  14740. {
  14741. return false;
  14742. }
  14743.  
  14744. m_UnloadedMods.Resize(numMods);
  14745.  
  14746. CF_ModStorageMap loadedMods();
  14747.  
  14748. int unloadedModsRead;
  14749. for (int modsRead = 0; modsRead < numMods; modsRead++)
  14750. {
  14751. if (!ModLoader._CF_ReadModStorage(ctx, cf_version, m_UnloadedMods, unloadedModsRead, loadedMods))
  14752. {
  14753. CF_Log.Error("Failed to read modstorage for entity Type=%1, Position=%2", m_Entity.GetType(), m_Entity.GetPosition().ToString());
  14754. return false;
  14755. }
  14756. }
  14757.  
  14758. m_UnloadedMods.Resize(unloadedModsRead);
  14759.  
  14760. m_Entity.CF_OnStoreLoad(loadedMods);
  14761.  
  14762. // Reset the stream for 'OnStoreSave'
  14763. foreach (auto mod : ModLoader.s_CF_ModStorages)
  14764. {
  14765. mod._ResetStream();
  14766. }
  14767.  
  14768. return true;
  14769. }
  14770. };
  14771. #endif
  14772. modded class BuildingBase
  14773. {
  14774. override void OnStoreSave(ParamsWriteContext ctx)
  14775. {
  14776. super.OnStoreSave(ctx);
  14777. ctx.Write(1);
  14778. }
  14779.  
  14780. override bool OnStoreLoad(ParamsReadContext ctx, int version)
  14781. {
  14782. if (!super.OnStoreLoad(ctx,version))
  14783. return false;
  14784.  
  14785. // If the persistence file is before 1.10, cf data doesn't exist
  14786. if (version < 116) return true;
  14787.  
  14788. int cf_version;
  14789. if (!ctx.Read( cf_version )) return false;
  14790.  
  14791. return true;
  14792. }
  14793. }
  14794.  
  14795. modded class AnimalBase
  14796. {
  14797. override void OnStoreSave(ParamsWriteContext ctx)
  14798. {
  14799. super.OnStoreSave(ctx);
  14800. ctx.Write(1);
  14801. }
  14802.  
  14803. override bool OnStoreLoad(ParamsReadContext ctx, int version)
  14804. {
  14805. if (!super.OnStoreLoad(ctx,version))
  14806. return false;
  14807.  
  14808. // If the persistence file is before 1.10, cf data doesn't exist
  14809. if (version < 116) return true;
  14810.  
  14811. int cf_version;
  14812. if (!ctx.Read( cf_version )) return false;
  14813.  
  14814. return true;
  14815. }
  14816. }
  14817.  
  14818. modded class ZombieBase
  14819. {
  14820. override void OnStoreSave(ParamsWriteContext ctx)
  14821. {
  14822. super.OnStoreSave(ctx);
  14823. ctx.Write(1);
  14824. }
  14825.  
  14826. override bool OnStoreLoad(ParamsReadContext ctx, int version)
  14827. {
  14828. if (!super.OnStoreLoad(ctx,version))
  14829. return false;
  14830.  
  14831. // If the persistence file is before 1.10, cf data doesn't exist
  14832. if (version < 116) return true;
  14833.  
  14834. int cf_version;
  14835. if (!ctx.Read( cf_version )) return false;
  14836.  
  14837. return true;
  14838. }
  14839. }
  14840.  
  14841. modded class ItemBase
  14842. {
  14843. override void OnStoreSave(ParamsWriteContext ctx)
  14844. {
  14845. super.OnStoreSave(ctx);
  14846. ctx.Write(1);
  14847. }
  14848.  
  14849. override bool OnStoreLoad(ParamsReadContext ctx, int version)
  14850. {
  14851. if (!super.OnStoreLoad(ctx,version))
  14852. return false;
  14853.  
  14854. // If the persistence file is before 1.10, cf data doesn't exist
  14855. if (version < 116) return true;
  14856.  
  14857. int cf_version;
  14858. if (!ctx.Read( cf_version )) return false;
  14859.  
  14860. return true;
  14861. }
  14862. }
  14863.  
  14864. modded class DayZPlayerImplement
  14865. {
  14866. override void OnStoreSave(ParamsWriteContext ctx)
  14867. {
  14868. super.OnStoreSave(ctx);
  14869. ctx.Write(1);
  14870. }
  14871.  
  14872. override bool OnStoreLoad(ParamsReadContext ctx, int version)
  14873. {
  14874. if (!super.OnStoreLoad(ctx,version))
  14875. return false;
  14876.  
  14877. // If the persistence file is before 1.10, cf data doesn't exist
  14878. if (version < 116) return true;
  14879.  
  14880. int cf_version;
  14881. if (!ctx.Read( cf_version )) return false;
  14882.  
  14883. return true;
  14884. }
  14885. }
  14886.  
  14887. modded class CarScript
  14888. {
  14889. override void OnStoreSave(ParamsWriteContext ctx)
  14890. {
  14891. super.OnStoreSave(ctx);
  14892. ctx.Write(1);
  14893. }
  14894.  
  14895. override bool OnStoreLoad(ParamsReadContext ctx, int version)
  14896. {
  14897. if (!super.OnStoreLoad(ctx,version))
  14898. return false;
  14899.  
  14900. // If the persistence file is before 1.10, cf data doesn't exist
  14901. if (version < 116) return true;
  14902.  
  14903. int cf_version;
  14904. if (!ctx.Read( cf_version )) return false;
  14905.  
  14906. return true;
  14907. }
  14908. }
  14909.  
  14910. modded class HelicopterScript
  14911. {
  14912. override void OnStoreSave(ParamsWriteContext ctx)
  14913. {
  14914. super.OnStoreSave(ctx);
  14915. ctx.Write(1);
  14916. }
  14917.  
  14918. override bool OnStoreLoad(ParamsReadContext ctx, int version)
  14919. {
  14920. if (!super.OnStoreLoad(ctx,version))
  14921. return false;
  14922.  
  14923. // If the persistence file is before 1.10, cf data doesn't exist
  14924. if (version < 116) return true;
  14925.  
  14926. int cf_version;
  14927. if (!ctx.Read( cf_version )) return false;
  14928.  
  14929. return true;
  14930. }
  14931. }
  14932.  
  14933. modded class AdvancedCommunication
  14934. {
  14935. override void OnStoreSave(ParamsWriteContext ctx)
  14936. {
  14937. super.OnStoreSave(ctx);
  14938. ctx.Write(1);
  14939. }
  14940.  
  14941. override bool OnStoreLoad(ParamsReadContext ctx, int version)
  14942. {
  14943. if (!super.OnStoreLoad(ctx,version))
  14944. return false;
  14945.  
  14946. // If the persistence file is before 1.10, cf data doesn't exist
  14947. if (version < 116) return true;
  14948.  
  14949. int cf_version;
  14950. if (!ctx.Read( cf_version )) return false;
  14951.  
  14952. return true;
  14953. }
  14954. }class CF_ModuleWorld : CF_ModuleGame
  14955. {
  14956. void EnableInvokeConnect()
  14957. {
  14958. CF_ModuleWorldManager.s_InvokeConnect.Add(this);
  14959. }
  14960.  
  14961. void EnableInvokeDisconnect()
  14962. {
  14963. CF_ModuleWorldManager.s_InvokeDisconnect.Add(this);
  14964. }
  14965.  
  14966. void EnableClientNew()
  14967. {
  14968. CF_ModuleWorldManager.s_ClientNew.Add(this);
  14969. }
  14970.  
  14971. void EnableClientRespawn()
  14972. {
  14973. CF_ModuleWorldManager.s_ClientRespawn.Add(this);
  14974. }
  14975.  
  14976. void EnableClientReady()
  14977. {
  14978. CF_ModuleWorldManager.s_ClientReady.Add(this);
  14979. }
  14980.  
  14981. void EnableClientPrepare()
  14982. {
  14983. CF_ModuleWorldManager.s_ClientPrepare.Add(this);
  14984. }
  14985.  
  14986. void EnableClientLogoutReconnect()
  14987. {
  14988. CF_ModuleWorldManager.s_ClientReconnect.Add(this);
  14989. }
  14990.  
  14991. void EnableClientLogout()
  14992. {
  14993. CF_ModuleWorldManager.s_ClientLogout.Add(this);
  14994. }
  14995.  
  14996. void EnableClientDisconnect()
  14997. {
  14998. CF_ModuleWorldManager.s_ClientDisconnect.Add(this);
  14999. }
  15000.  
  15001. void EnableClientLogoutCancelled()
  15002. {
  15003. CF_ModuleWorldManager.s_ClientLogoutCancelled.Add(this);
  15004. }
  15005.  
  15006. /**
  15007. * @brief See: MissionServer::InvokeOnConnect
  15008. */
  15009. void OnInvokeConnect(Class sender, CF_EventArgs args);
  15010.  
  15011. /**
  15012. * @brief See: MissionServer::InvokeOnDisconnect
  15013. */
  15014. void OnInvokeDisconnect(Class sender, CF_EventArgs args);
  15015.  
  15016. /**
  15017. * @brief See: ClientNewEventTypeID
  15018. */
  15019. void OnClientNew(Class sender, CF_EventArgs args);
  15020.  
  15021. /**
  15022. * @brief See: ClientRespawnEventTypeID
  15023. */
  15024. void OnClientRespawn(Class sender, CF_EventArgs args);
  15025.  
  15026. /**
  15027. * @brief See: ClientReadyEventTypeID
  15028. */
  15029. void OnClientReady(Class sender, CF_EventArgs args);
  15030.  
  15031. /**
  15032. * @brief See: ClientPrepareEventTypeID
  15033. */
  15034. void OnClientPrepare(Class sender, CF_EventArgs args);
  15035.  
  15036. /**
  15037. * @brief See: ClientReconnectEventTypeID
  15038. */
  15039. void OnClientReconnect(Class sender, CF_EventArgs args);
  15040.  
  15041. /**
  15042. * @brief See: ClientDisconnectedEventTypeID
  15043. */
  15044. void OnClientLogout(Class sender, CF_EventArgs args);
  15045.  
  15046. /**
  15047. * @brief See: MissionServer::PlayerDisconnected - Fires when the player has disconnected from the server (OnClientReconnect won't fire)
  15048. */
  15049. void OnClientDisconnect(Class sender, CF_EventArgs args);
  15050.  
  15051. /**
  15052. * @brief See: LogoutCancelEventTypeID
  15053. */
  15054. void OnClientLogoutCancelled(Class sender, CF_EventArgs args);
  15055. };
  15056. class CF_ModuleWorldEvent : CF_ModuleCoreEvent
  15057. {
  15058. void OnInvokeConnect(Class sender, CF_EventArgs args)
  15059. {
  15060. auto evt = this.m_Next;
  15061. while (evt)
  15062. {
  15063. auto module = CF_ModuleWorld.Cast(evt.m_Value);
  15064.  
  15065. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  15066. {
  15067. module.OnInvokeConnect(sender, args);
  15068. }
  15069.  
  15070. evt = evt.m_Next;
  15071. }
  15072. }
  15073.  
  15074. void OnInvokeDisconnect(Class sender, CF_EventArgs args)
  15075. {
  15076. auto evt = this.m_Next;
  15077. while (evt)
  15078. {
  15079. auto module = CF_ModuleWorld.Cast(evt.m_Value);
  15080.  
  15081. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  15082. {
  15083. module.OnInvokeDisconnect(sender, args);
  15084. }
  15085.  
  15086. evt = evt.m_Next;
  15087. }
  15088. }
  15089.  
  15090. void OnClientNew(Class sender, CF_EventArgs args)
  15091. {
  15092. auto evt = this.m_Next;
  15093. while (evt)
  15094. {
  15095. auto module = CF_ModuleWorld.Cast(evt.m_Value);
  15096.  
  15097. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  15098. {
  15099. module.OnClientNew(sender, args);
  15100. }
  15101.  
  15102. evt = evt.m_Next;
  15103. }
  15104. }
  15105.  
  15106. void OnClientRespawn(Class sender, CF_EventArgs args)
  15107. {
  15108. auto evt = this.m_Next;
  15109. while (evt)
  15110. {
  15111. auto module = CF_ModuleWorld.Cast(evt.m_Value);
  15112.  
  15113. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  15114. {
  15115. module.OnClientRespawn(sender, args);
  15116. }
  15117.  
  15118. evt = evt.m_Next;
  15119. }
  15120. }
  15121.  
  15122. void OnClientReady(Class sender, CF_EventArgs args)
  15123. {
  15124. auto evt = this.m_Next;
  15125. while (evt)
  15126. {
  15127. auto module = CF_ModuleWorld.Cast(evt.m_Value);
  15128.  
  15129. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  15130. {
  15131. module.OnClientReady(sender, args);
  15132. }
  15133.  
  15134. evt = evt.m_Next;
  15135. }
  15136. }
  15137.  
  15138. void OnClientPrepare(Class sender, CF_EventArgs args)
  15139. {
  15140. auto evt = this.m_Next;
  15141. while (evt)
  15142. {
  15143. auto module = CF_ModuleWorld.Cast(evt.m_Value);
  15144.  
  15145. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  15146. {
  15147. module.OnClientPrepare(sender, args);
  15148. }
  15149.  
  15150. evt = evt.m_Next;
  15151. }
  15152. }
  15153.  
  15154. void OnClientReconnect(Class sender, CF_EventArgs args)
  15155. {
  15156. auto evt = this.m_Next;
  15157. while (evt)
  15158. {
  15159. auto module = CF_ModuleWorld.Cast(evt.m_Value);
  15160.  
  15161. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  15162. {
  15163. module.OnClientReconnect(sender, args);
  15164. }
  15165.  
  15166. evt = evt.m_Next;
  15167. }
  15168. }
  15169.  
  15170. void OnClientLogout(Class sender, CF_EventArgs args)
  15171. {
  15172. auto evt = this.m_Next;
  15173. while (evt)
  15174. {
  15175. auto module = CF_ModuleWorld.Cast(evt.m_Value);
  15176.  
  15177. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  15178. {
  15179. module.OnClientLogout(sender, args);
  15180. }
  15181.  
  15182. evt = evt.m_Next;
  15183. }
  15184. }
  15185.  
  15186. void OnClientDisconnect(Class sender, CF_EventArgs args)
  15187. {
  15188. auto evt = this.m_Next;
  15189. while (evt)
  15190. {
  15191. auto module = CF_ModuleWorld.Cast(evt.m_Value);
  15192.  
  15193. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  15194. {
  15195. module.OnClientDisconnect(sender, args);
  15196. }
  15197.  
  15198. evt = evt.m_Next;
  15199. }
  15200. }
  15201.  
  15202. void OnClientLogoutCancelled(Class sender, CF_EventArgs args)
  15203. {
  15204. auto evt = this.m_Next;
  15205. while (evt)
  15206. {
  15207. auto module = CF_ModuleWorld.Cast(evt.m_Value);
  15208.  
  15209. if ((module.m_CF_GameFlag & CF_ModuleCoreManager.s_GameFlag) != 0)
  15210. {
  15211. module.OnClientLogoutCancelled(sender, args);
  15212. }
  15213.  
  15214. evt = evt.m_Next;
  15215. }
  15216. }
  15217. };
  15218. class CF_ModuleWorldManager
  15219. {
  15220. static autoptr CF_ModuleWorldEvent s_InvokeConnect = new CF_ModuleWorldEvent();
  15221. static autoptr CF_ModuleWorldEvent s_InvokeDisconnect = new CF_ModuleWorldEvent();
  15222. static autoptr CF_ModuleWorldEvent s_ClientNew = new CF_ModuleWorldEvent();
  15223. static autoptr CF_ModuleWorldEvent s_ClientRespawn = new CF_ModuleWorldEvent();
  15224. static autoptr CF_ModuleWorldEvent s_ClientReady = new CF_ModuleWorldEvent();
  15225. static autoptr CF_ModuleWorldEvent s_ClientPrepare = new CF_ModuleWorldEvent();
  15226. static autoptr CF_ModuleWorldEvent s_ClientReconnect = new CF_ModuleWorldEvent();
  15227. static autoptr CF_ModuleWorldEvent s_ClientLogout = new CF_ModuleWorldEvent();
  15228. static autoptr CF_ModuleWorldEvent s_ClientDisconnect = new CF_ModuleWorldEvent();
  15229. static autoptr CF_ModuleWorldEvent s_ClientLogoutCancelled = new CF_ModuleWorldEvent();
  15230.  
  15231. static void OnInvokeConnect(Class sender, CF_EventArgs args)
  15232. {
  15233. s_InvokeConnect.OnInvokeConnect(sender, args);
  15234.  
  15235. delete args;
  15236. }
  15237.  
  15238. static void OnInvokeDisconnect(Class sender, CF_EventArgs args)
  15239. {
  15240. s_InvokeDisconnect.OnInvokeDisconnect(sender, args);
  15241.  
  15242. delete args;
  15243. }
  15244.  
  15245. static void OnClientNew(Class sender, CF_EventArgs args)
  15246. {
  15247. s_ClientNew.OnClientNew(sender, args);
  15248.  
  15249. delete args;
  15250. }
  15251.  
  15252. static void OnClientRespawn(Class sender, CF_EventArgs args)
  15253. {
  15254. s_ClientRespawn.OnClientRespawn(sender, args);
  15255.  
  15256. delete args;
  15257. }
  15258.  
  15259. static void OnClientReady(Class sender, CF_EventArgs args)
  15260. {
  15261. s_ClientReady.OnClientReady(sender, args);
  15262.  
  15263. delete args;
  15264. }
  15265.  
  15266. static void OnClientPrepare(Class sender, CF_EventArgs args)
  15267. {
  15268. s_ClientPrepare.OnClientPrepare(sender, args);
  15269.  
  15270. delete args;
  15271. }
  15272.  
  15273. static void OnClientReconnect(Class sender, CF_EventArgs args)
  15274. {
  15275. s_ClientReconnect.OnClientReconnect(sender, args);
  15276.  
  15277. delete args;
  15278. }
  15279.  
  15280. static void OnClientLogout(Class sender, CF_EventArgs args)
  15281. {
  15282. s_ClientLogout.OnClientLogout(sender, args);
  15283.  
  15284. delete args;
  15285. }
  15286.  
  15287. static void OnClientDisconnect(Class sender, CF_EventArgs args)
  15288. {
  15289. s_ClientDisconnect.OnClientDisconnect(sender, args);
  15290.  
  15291. delete args;
  15292. }
  15293.  
  15294. static void OnClientLogoutCancelled(Class sender, CF_EventArgs args)
  15295. {
  15296. s_ClientLogoutCancelled.OnClientLogoutCancelled(sender, args);
  15297.  
  15298. delete args;
  15299. }
  15300. };
  15301. /**
  15302. * @class JMModuleBase
  15303. *
  15304. * @deprecated
  15305. */
  15306. class JMModuleBase : CF_ModuleWorld
  15307. {
  15308. /**
  15309. * Any module that inherits from 'JMModuleBase' probably expects all events to be enabled
  15310. */
  15311. override void Init()
  15312. {
  15313. EnableUpdate();
  15314. EnableMissionStart();
  15315. EnableMissionFinish();
  15316. EnableMissionLoaded();
  15317. EnableSettingsChanged();
  15318. EnablePermissionsChanged();
  15319. EnableWorldCleanup();
  15320. EnableMPSessionStart();
  15321. EnableMPSessionPlayerReady();
  15322. EnableMPSessionFail();
  15323. EnableMPSessionEnd();
  15324. EnableMPConnectAbort();
  15325. EnableMPConnectionLost();
  15326. EnableRespawn();
  15327. EnableRPC();
  15328. EnableInvokeConnect();
  15329. EnableInvokeDisconnect();
  15330. EnableClientNew();
  15331. EnableClientRespawn();
  15332. EnableClientReady();
  15333. EnableClientPrepare();
  15334. EnableClientLogoutReconnect();
  15335. EnableClientLogout();
  15336. EnableClientDisconnect();
  15337. EnableClientLogoutCancelled();
  15338.  
  15339. GetModuleManager().NP_InitModule(this);
  15340.  
  15341. RegisterKeyMouseBindings();
  15342.  
  15343. super.Init();
  15344. }
  15345.  
  15346. void Toggle()
  15347. {
  15348. }
  15349.  
  15350. void PreventInput(bool prevent)
  15351. {
  15352. }
  15353.  
  15354. string GetModuleName()
  15355. {
  15356. return ClassName();
  15357. }
  15358.  
  15359. typename GetModuleType()
  15360. {
  15361. return Type();
  15362. }
  15363.  
  15364. bool IsEnabled()
  15365. {
  15366. return true;
  15367. }
  15368.  
  15369. bool IsPreventingInput()
  15370. {
  15371. return false;
  15372. }
  15373.  
  15374. set<ref JMModuleBinding> GetBindings()
  15375. {
  15376. return new set<ref JMModuleBinding>();
  15377. }
  15378.  
  15379. override void OnRPC(Class sender, CF_EventArgs args)
  15380. {
  15381. super.OnRPC(sender, args);
  15382.  
  15383. auto rpc = CF_EventRPCArgs.Cast(args);
  15384. OnRPC(rpc.Sender, rpc.Target, rpc.ID, rpc.Context);
  15385. }
  15386.  
  15387. override void OnMissionStart(Class sender, CF_EventArgs args)
  15388. {
  15389. super.OnMissionStart(sender, args);
  15390.  
  15391. OnMissionStart();
  15392. }
  15393.  
  15394. override void OnMissionFinish(Class sender, CF_EventArgs args)
  15395. {
  15396. super.OnMissionFinish(sender, args);
  15397.  
  15398. OnMissionFinish();
  15399. }
  15400.  
  15401. override void OnMissionLoaded(Class sender, CF_EventArgs args)
  15402. {
  15403. super.OnMissionLoaded(sender, args);
  15404.  
  15405. OnMissionLoaded();
  15406. }
  15407.  
  15408. override void OnUpdate(Class sender, CF_EventArgs args)
  15409. {
  15410. super.OnUpdate(sender, args);
  15411.  
  15412. auto update = CF_EventUpdateArgs.Cast(args);
  15413. OnUpdate(update.DeltaTime);
  15414. }
  15415.  
  15416. override void OnSettingsChanged(Class sender, CF_EventArgs args)
  15417. {
  15418. super.OnSettingsChanged(sender, args);
  15419.  
  15420. OnSettingsUpdated();
  15421. }
  15422.  
  15423. override void OnPermissionsChanged(Class sender, CF_EventArgs args)
  15424. {
  15425. super.OnPermissionsChanged(sender, args);
  15426.  
  15427. OnClientPermissionsUpdated();
  15428. }
  15429.  
  15430. override void OnWorldCleanup(Class sender, CF_EventArgs args)
  15431. {
  15432. super.OnWorldCleanup(sender, args);
  15433.  
  15434. OnWorldCleanup();
  15435. }
  15436.  
  15437. override void OnMPSessionStart(Class sender, CF_EventArgs args)
  15438. {
  15439. super.OnMPSessionStart(sender, args);
  15440.  
  15441. OnMPSessionStart();
  15442. }
  15443.  
  15444. override void OnMPSessionPlayerReady(Class sender, CF_EventArgs args)
  15445. {
  15446. super.OnMPSessionPlayerReady(sender, args);
  15447.  
  15448. OnMPSessionPlayerReady();
  15449. }
  15450.  
  15451. override void OnMPSessionFail(Class sender, CF_EventArgs args)
  15452. {
  15453. super.OnMPSessionFail(sender, args);
  15454.  
  15455. OnMPSessionFail();
  15456. }
  15457.  
  15458. override void OnMPSessionEnd(Class sender, CF_EventArgs args)
  15459. {
  15460. super.OnMPSessionEnd(sender, args);
  15461.  
  15462. OnMPSessionEnd();
  15463. }
  15464.  
  15465. override void OnMPConnectAbort(Class sender, CF_EventArgs args)
  15466. {
  15467. super.OnMPConnectAbort(sender, args);
  15468.  
  15469. OnMPConnectAbort();
  15470. }
  15471.  
  15472. override void OnMPConnectionLost(Class sender, CF_EventArgs args)
  15473. {
  15474. super.OnMPConnectionLost(sender, args);
  15475.  
  15476. OnMPConnectionLost(CF_EventTimeArgs.Cast(args).Time);
  15477. }
  15478.  
  15479. override void OnRespawn(Class sender, CF_EventArgs args)
  15480. {
  15481. super.OnRespawn(sender, args);
  15482.  
  15483. OnRespawn(CF_EventTimeArgs.Cast(args).Time);
  15484. }
  15485.  
  15486. override void OnInvokeConnect(Class sender, CF_EventArgs args)
  15487. {
  15488. super.OnInvokeConnect(sender, args);
  15489.  
  15490. auto cArgs = CF_EventPlayerArgs.Cast(args);
  15491. OnInvokeConnect(cArgs.Player, cArgs.Identity);
  15492. }
  15493.  
  15494. override void OnInvokeDisconnect(Class sender, CF_EventArgs args)
  15495. {
  15496. super.OnInvokeDisconnect(sender, args);
  15497.  
  15498. auto cArgs = CF_EventPlayerArgs.Cast(args);
  15499. OnInvokeDisconnect(cArgs.Player);
  15500. }
  15501.  
  15502. override void OnClientNew(Class sender, CF_EventArgs args)
  15503. {
  15504. super.OnClientNew(sender, args);
  15505.  
  15506. auto cArgs = CF_EventNewPlayerArgs.Cast(args);
  15507. OnClientNew(cArgs.Player, cArgs.Identity, cArgs.Position, cArgs.Context);
  15508. }
  15509.  
  15510. override void OnClientRespawn(Class sender, CF_EventArgs args)
  15511. {
  15512. super.OnClientRespawn(sender, args);
  15513.  
  15514. auto cArgs = CF_EventPlayerArgs.Cast(args);
  15515. OnClientRespawn(cArgs.Player, cArgs.Identity);
  15516. }
  15517.  
  15518. override void OnClientReady(Class sender, CF_EventArgs args)
  15519. {
  15520. super.OnClientReady(sender, args);
  15521.  
  15522. auto cArgs = CF_EventPlayerArgs.Cast(args);
  15523. OnClientReady(cArgs.Player, cArgs.Identity);
  15524. }
  15525.  
  15526. override void OnClientPrepare(Class sender, CF_EventArgs args)
  15527. {
  15528. super.OnClientPrepare(sender, args);
  15529.  
  15530. auto cArgs = CF_EventPlayerPrepareArgs.Cast(args);
  15531. OnClientPrepare(cArgs.Identity, cArgs.UseDatabase, cArgs.Position, cArgs.Yaw, cArgs.PreloadTimeout);
  15532. }
  15533.  
  15534. override void OnClientReconnect(Class sender, CF_EventArgs args)
  15535. {
  15536. super.OnClientReconnect(sender, args);
  15537.  
  15538. auto cArgs = CF_EventPlayerArgs.Cast(args);
  15539. OnClientReconnect(cArgs.Player, cArgs.Identity);
  15540. }
  15541.  
  15542. override void OnClientLogout(Class sender, CF_EventArgs args)
  15543. {
  15544. super.OnClientLogout(sender, args);
  15545.  
  15546. auto cArgs = CF_EventPlayerDisconnectedArgs.Cast(args);
  15547. OnClientLogout(cArgs.Player, cArgs.Identity, cArgs.LogoutTime, cArgs.AuthFailed);
  15548. }
  15549.  
  15550. override void OnClientDisconnect(Class sender, CF_EventArgs args)
  15551. {
  15552. super.OnClientDisconnect(sender, args);
  15553.  
  15554. auto cArgs = CF_EventPlayerDisconnectedArgs.Cast(args);
  15555. OnClientDisconnect(cArgs.Player, cArgs.Identity, cArgs.UID);
  15556. }
  15557.  
  15558. override void OnClientLogoutCancelled(Class sender, CF_EventArgs args)
  15559. {
  15560. super.OnClientLogoutCancelled(sender, args);
  15561.  
  15562. auto cArgs = CF_EventPlayerArgs.Cast(args);
  15563. OnClientLogoutCancelled(cArgs.Player);
  15564. }
  15565.  
  15566. // Old Events
  15567. void OnRPC(PlayerIdentity sender, Object target, int rpc_type, ParamsReadContext ctx);
  15568. void OnMissionStart();
  15569. void OnMissionFinish();
  15570. void OnMissionLoaded();
  15571. void OnUpdate(float timeslice);
  15572. void OnSettingsUpdated();
  15573. void OnClientPermissionsUpdated();
  15574. void OnPermissionsChanged();
  15575. void OnWorldCleanup();
  15576. void OnMPSessionStart();
  15577. void OnMPSessionPlayerReady();
  15578. void OnMPSessionFail();
  15579. void OnMPSessionEnd();
  15580. void OnMPConnectAbort();
  15581. void OnMPConnectionLost(int duration);
  15582. void OnRespawn(int time);
  15583. void OnInvokeConnect(PlayerBase player, PlayerIdentity identity);
  15584. void OnInvokeDisconnect(PlayerBase player);
  15585. void OnClientNew(inout PlayerBase player, PlayerIdentity identity, vector pos, ParamsReadContext ctx);
  15586. void OnClientRespawn(PlayerBase player, PlayerIdentity identity);
  15587. void OnClientReady(PlayerBase player, PlayerIdentity identity);
  15588. void OnClientPrepare(PlayerIdentity identity, inout bool useDB, inout vector pos, inout float yaw, inout int preloadTimeout);
  15589. void OnClientReconnect(PlayerBase player, PlayerIdentity identity);
  15590. void OnClientLogout(PlayerBase player, PlayerIdentity identity, int logoutTime, bool authFailed);
  15591. void OnClientDisconnect(PlayerBase player, PlayerIdentity identity, string uid);
  15592. void OnClientLogoutCancelled(PlayerBase player);
  15593.  
  15594. void RegisterKeyMouseBindings()
  15595. {
  15596. }
  15597.  
  15598. void RegisterKeyMouseBinding(JMModuleBinding binding)
  15599. {
  15600. Bind(binding);
  15601.  
  15602. Error_Deprecated("RegisterKeyMouseBinding", "Bind");
  15603. }
  15604.  
  15605. void RegisterBinding(JMModuleBinding binding)
  15606. {
  15607. Bind(binding);
  15608.  
  15609. Error_Deprecated("RegisterBinding", "Bind");
  15610. }
  15611. };
  15612. /**
  15613. * @class JMModuleBinding
  15614. *
  15615. * @deprecated
  15616. */
  15617. class JMModuleBinding : CF_InputBinding
  15618. {
  15619. void JMModuleBinding(string callback, string input, bool menu = false)
  15620. {
  15621. m_Function = callback;
  15622. m_Input = GetUApi().GetInputByName(input);
  15623. m_LimitMenu = !menu;
  15624. }
  15625. };
  15626. /**
  15627. * @class JMModuleConstructorBase
  15628. *
  15629. * @deprecated
  15630. */
  15631. class JMModuleConstructorBase
  15632. {
  15633. autoptr TTypenameArray m_Modules = new TTypenameArray();
  15634.  
  15635. void JMModuleConstructorBase()
  15636. {
  15637. RegisterModules(m_Modules);
  15638. for (int i = 0; i < m_Modules.Count(); i++)
  15639. {
  15640. CF_ModuleCoreManager._Insert(m_Modules[i]);
  15641. }
  15642. }
  15643.  
  15644. void RegisterModules(out TTypenameArray modules);
  15645. };
  15646. /**
  15647. * @class JMModuleManager
  15648. *
  15649. * @deprecated
  15650. */
  15651. class JMModuleManager : JMModuleManagerBase
  15652. {
  15653. protected autoptr array<JMModuleBase> m_ModuleList;
  15654.  
  15655. void JMModuleManager()
  15656. {
  15657. m_ModuleList = new array<JMModuleBase>();
  15658. }
  15659.  
  15660. JMModuleBase GetModule(typename type)
  15661. {
  15662. return JMModuleBase.Cast(CF_ModuleCoreManager.Get(type));
  15663. }
  15664.  
  15665. protected void InitModule(JMModuleBase module)
  15666. {
  15667. #ifdef CF_TRACE_ENABLED
  15668. auto trace = CF_Trace_1(this).Add(module);
  15669. #endif
  15670.  
  15671. m_ModuleList.Insert(module);
  15672. }
  15673.  
  15674. /**
  15675. * @note Can't remove protected from 'InitModule'' without compile errors
  15676. */
  15677. void NP_InitModule(JMModuleBase module)
  15678. {
  15679. InitModule(module);
  15680. }
  15681.  
  15682. void OnInvokeConnect(PlayerBase player, PlayerIdentity identity)
  15683. {
  15684. CF_ModuleWorldManager.OnInvokeConnect(this, new CF_EventPlayerArgs(player, identity));
  15685. }
  15686.  
  15687. void OnInvokeDisconnect(PlayerBase player)
  15688. {
  15689. CF_ModuleWorldManager.OnInvokeDisconnect(this, new CF_EventPlayerArgs(player));
  15690. }
  15691.  
  15692. void OnClientNew(out PlayerBase player, PlayerIdentity identity, vector pos, ParamsReadContext ctx)
  15693. {
  15694. auto args = new CF_EventNewPlayerArgs(player, identity, pos, ctx);
  15695. CF_ModuleWorldManager.OnClientNew(this, args);
  15696. player = args.Player;
  15697. }
  15698.  
  15699. void OnClientReady(PlayerBase player, PlayerIdentity identity)
  15700. {
  15701. CF_ModuleWorldManager.OnClientReady(this, new CF_EventPlayerArgs(player, identity));
  15702. }
  15703.  
  15704. void OnClientPrepare(PlayerIdentity identity, out bool useDB, out vector pos, out float yaw, out int preloadTimeout)
  15705. {
  15706. auto args = new CF_EventPlayerPrepareArgs();
  15707. args.Identity = identity;
  15708. args.UseDatabase = useDB;
  15709. args.Position = pos;
  15710. args.Yaw = yaw;
  15711. args.PreloadTimeout = preloadTimeout;
  15712.  
  15713. CF_ModuleWorldManager.OnClientPrepare(this, args);
  15714. }
  15715.  
  15716. void OnClientReconnect(PlayerBase player, PlayerIdentity identity)
  15717. {
  15718. CF_ModuleWorldManager.OnClientReconnect(this, new CF_EventPlayerArgs(player, identity));
  15719. }
  15720.  
  15721. void OnClientRespawn(PlayerBase player, PlayerIdentity identity)
  15722. {
  15723. CF_ModuleWorldManager.OnClientRespawn(this, new CF_EventPlayerArgs(player, identity));
  15724. }
  15725.  
  15726. void OnClientLogout(PlayerBase player, PlayerIdentity identity, int logoutTime, bool authFailed)
  15727. {
  15728. auto args = new CF_EventPlayerDisconnectedArgs(player, identity);
  15729. args.LogoutTime = logoutTime;
  15730. args.AuthFailed = authFailed;
  15731.  
  15732. CF_ModuleWorldManager.OnClientLogout(this, args);
  15733. }
  15734.  
  15735. void OnClientDisconnect(PlayerBase player, PlayerIdentity identity, string uid)
  15736. {
  15737. auto args = new CF_EventPlayerDisconnectedArgs(player, identity);
  15738. args.UID = uid;
  15739.  
  15740. CF_ModuleWorldManager.OnClientDisconnect(this, args);
  15741. }
  15742.  
  15743. void OnClientLogoutCancelled(PlayerBase player)
  15744. {
  15745. CF_ModuleWorldManager.OnClientLogoutCancelled(this, new CF_EventPlayerArgs(player));
  15746. }
  15747. }
  15748.  
  15749. static JMModuleManager GetModuleManager()
  15750. {
  15751. if (!g_JMModuleManager)
  15752. {
  15753. g_JMModuleManager = new JMModuleManager();
  15754. }
  15755.  
  15756. return g_JMModuleManager;
  15757. }
  15758.  
  15759. static ref JMModuleManager g_JMModuleManager;
  15760.  
  15761. static void CreateModuleManager(JMModuleConstructorBase construct)
  15762. {
  15763. }
  15764. class CF_Surface
  15765. {
  15766. private static autoptr map<string, autoptr CF_Surface> s_Surfaces = new map<string, autoptr CF_Surface>();
  15767.  
  15768. private static string s_LastSurface;
  15769.  
  15770. string Name = s_LastSurface;
  15771.  
  15772. float Interior = GetValueFloat("interior");
  15773. float Deflection = GetValueFloat("deflection");
  15774. float Friction = GetValueFloat("friction");
  15775. float Restitution = GetValueFloat("restitution");
  15776.  
  15777. string SoundEnvironment = GetValueString("soundEnviron");
  15778. string SoundHit = GetValueString("soundHit");
  15779. string Character = GetValueString("character");
  15780.  
  15781. string Files = GetValueString("files");
  15782.  
  15783. float FootDamage = GetValueFloat("footDamage");
  15784. float Audibility = GetValueFloat("audibility");
  15785.  
  15786. string Impact = GetValueString("impact");
  15787.  
  15788. bool IsDigable = GetValueInt("isDigable");
  15789. bool IsFertile = GetValueInt("isFertile");
  15790. bool IsLiquid = GetValueInt("liquidType");
  15791. bool IsStairs = GetValueInt("isStairs");
  15792.  
  15793. int LiquidType = GetValueInt("liquidType");
  15794.  
  15795. float ChanceForCatch = GetValueFloat("chanceForCatch");
  15796. float WindModifier = GetValueFloat("windModifier");
  15797.  
  15798. CF_VehicleSurface VehicleSurface = GetValueVehicleSurface("vpSurface");
  15799.  
  15800. /**
  15801. * @brief Private constructor to prevent outside creation of the class
  15802. */
  15803. private void CF_Surface()
  15804. {
  15805. #ifdef CF_TRACE_ENABLED
  15806. auto trace = CF_Trace_0(this);
  15807. #endif
  15808.  
  15809. s_Surfaces[s_LastSurface] = this;
  15810. }
  15811.  
  15812. /**
  15813. * @brief Private constructor to prevent from marking as ref
  15814. */
  15815. private void ~CF_Surface()
  15816. {
  15817. #ifdef CF_TRACE_ENABLED
  15818. auto trace = CF_Trace_0(this);
  15819. #endif
  15820.  
  15821. }
  15822.  
  15823. /**
  15824. * @brief Get the surface by the name. From 'CfgSurfaces'
  15825. *
  15826. * @param name The class name of the surface
  15827. *
  15828. * @return Instance of the surface class, creates a new one if it doesn't exist
  15829. */
  15830. static CF_Surface Get(string name)
  15831. {
  15832. #ifdef CF_TRACE_ENABLED
  15833. auto trace = CF_Trace_1("CF_Surface").Add(name);
  15834. #endif
  15835.  
  15836. auto surf = s_Surfaces[name];
  15837. if (!surf)
  15838. {
  15839. s_LastSurface = name;
  15840. return new CF_Surface();
  15841. }
  15842.  
  15843. return surf;
  15844. }
  15845.  
  15846. /**
  15847. * @brief Get the surface at the position in the world
  15848. *
  15849. * @param position The position of the surface within the world
  15850. *
  15851. * @return Global instance of the surface class
  15852. */
  15853. static CF_Surface At(vector position)
  15854. {
  15855. string name;
  15856. GetGame().SurfaceGetType3D(position[0], position[1], position[2], name);
  15857. return CF_Surface.Get(name);
  15858. }
  15859.  
  15860. /**
  15861. * @brief Get the surface at the position in the world at it's maximum height
  15862. *
  15863. * @param x The x position of the surface within the world
  15864. * @param z The z position of the surface within the world
  15865. *
  15866. * @return Global instance of the surface class
  15867. */
  15868. static CF_Surface At(float x, float z)
  15869. {
  15870. string name;
  15871. GetGame().SurfaceGetType(x, z, name);
  15872. return CF_Surface.Get(name);
  15873. }
  15874.  
  15875. /**
  15876. * @brief Get the surface at the position in the world at it's maximum height
  15877. *
  15878. * @param object The object above the surface of the object
  15879. *
  15880. * @return Global instance of the surface class
  15881. */
  15882. static CF_Surface At(Object object)
  15883. {
  15884. string name;
  15885. int liquidType;
  15886. GetGame().SurfaceUnderObject(object, name, liquidType);
  15887. return CF_Surface.Get(name);
  15888. }
  15889.  
  15890. #ifdef CF_DebugUI
  15891. bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type)
  15892. {
  15893. instance.Add("Name", Name);
  15894. instance.Add("Interior", Interior);
  15895. instance.Add("Deflection", Deflection);
  15896. instance.Add("Friction", Friction);
  15897. instance.Add("Restitution", Restitution);
  15898. instance.Add("Sound Environent", SoundEnvironment);
  15899. instance.Add("Sound Hit", SoundHit);
  15900. instance.Add("Character", Character);
  15901. instance.Add("Files", Files);
  15902. instance.Add("Foot Damage", FootDamage);
  15903. instance.Add("Audibility", Audibility);
  15904. instance.Add("Impact", Impact);
  15905. instance.Add("Is Digable", IsDigable);
  15906. instance.Add("Is Fertile", IsFertile);
  15907. instance.Add("Is Liquid", IsLiquid);
  15908. instance.Add("Is Stairs", IsStairs);
  15909. instance.Add("LiquidType", LiquidType);
  15910. instance.Add("Chance For Catch", ChanceForCatch);
  15911. instance.Add("Wind Modifier", WindModifier);
  15912. instance.Add(VehicleSurface);
  15913.  
  15914. return true;
  15915. }
  15916. #endif
  15917.  
  15918. override string GetDebugName()
  15919. {
  15920. string str = this.ToString();
  15921.  
  15922. str += ",\n\tName=\"" + Name + "\"";
  15923. str += ",\n\tInterior=\"" + Interior + "\"";
  15924. str += ",\n\tDeflection=\"" + Deflection + "\"";
  15925. str += ",\n\tFriction=\"" + Friction + "\"";
  15926. str += ",\n\tRestitution=\"" + Restitution + "\"";
  15927. str += ",\n\tSoundEnvironent=\"" + SoundEnvironment + "\"";
  15928. str += ",\n\tSoundHit=\"" + SoundHit + "\"";
  15929. str += ",\n\tCharacter=\"" + Character + "\"";
  15930. str += ",\n\tFiles=\"" + Files + "\"";
  15931. str += ",\n\tFootDamage=\"" + FootDamage + "\""; ;
  15932. str += ",\n\tAudibility=\"" + Audibility + "\"";
  15933. str += ",\n\tImpact=\"" + Impact + "\"";
  15934. str += ",\n\tIsDigable=\"" + IsDigable + "\"";
  15935. str += ",\n\tIsFertile=\"" + IsFertile + "\"";
  15936. str += ",\n\tIsLiquid=\"" + IsLiquid + "\"";
  15937. str += ",\n\tIsStairs=\"" + IsStairs + "\"";
  15938. str += ",\n\tLiquidType=\"" + LiquidType + "\"";
  15939. str += ",\n\tChanceForCatch=\"" + ChanceForCatch + "\"";
  15940. str += ",\n\tWindModifier=\"" + WindModifier + "\"";
  15941. str += ",\n\tVehicleSurface=\"" + VehicleSurface.GetDebugName() + "\"";
  15942.  
  15943. return str;
  15944. }
  15945.  
  15946. [CF_EventSubscriber(ScriptCaller.Create(CF_Surface._GetAllSurfaces), CF_LifecycleEvents.OnMissionCreate)]
  15947. static void _GetAllSurfaces()
  15948. {
  15949. string path = "cfgSurfaces";
  15950. string name;
  15951. int count = GetGame().ConfigGetChildrenCount(path);
  15952.  
  15953. for (int index = 0; index < count; index++)
  15954. {
  15955. GetGame().ConfigGetChildName(path, index, name);
  15956.  
  15957. CF_Surface.Get(name);
  15958. }
  15959. }
  15960.  
  15961. private static int GetValueInt(string param)
  15962. {
  15963. string path = "CfgSurfaces" + " " + s_LastSurface + " " + param;
  15964. if (GetGame().ConfigIsExisting(path)) return GetGame().ConfigGetInt(path);
  15965. return 0;
  15966. }
  15967.  
  15968. private static float GetValueFloat(string param)
  15969. {
  15970. string path = "CfgSurfaces" + " " + s_LastSurface + " " + param;
  15971. if (GetGame().ConfigIsExisting(path)) return GetGame().ConfigGetFloat(path);
  15972. return 0;
  15973. }
  15974.  
  15975. private static string GetValueString(string param)
  15976. {
  15977. string path = "CfgSurfaces" + " " + s_LastSurface + " " + param;
  15978. if (GetGame().ConfigIsExisting(path)) return GetGame().ConfigGetTextOut(path);
  15979. return string.Empty;
  15980. }
  15981.  
  15982. private static CF_VehicleSurface GetValueVehicleSurface(string param)
  15983. {
  15984. return CF_VehicleSurface.Get(GetValueString(param));
  15985. }
  15986. };
  15987. class CF_VehicleSurface
  15988. {
  15989. private static autoptr map<string, autoptr CF_VehicleSurface> s_VehicleSurfaces = new map<string, autoptr CF_VehicleSurface>();
  15990.  
  15991. private static string s_LastSurface;
  15992.  
  15993. string Name = s_LastSurface;
  15994.  
  15995. float NoiseSteer = GetValueFloat("noiseSteer");
  15996. float NoiseFrequency = GetValueFloat("noiseFrequency");
  15997. float Roughness = GetValueFloat("roughness");
  15998. float FrictionOffroad = GetValueFloat("frictionOffroad");
  15999. float FrictionSlick = GetValueFloat("frictionSlick");
  16000. float RollResistance = GetValueFloat("rollResistance");
  16001. float RollDrag = GetValueFloat("rollDrag");
  16002.  
  16003. /**
  16004. * @brief Private constructor to prevent outside creation of the class
  16005. */
  16006. private void CF_VehicleSurface()
  16007. {
  16008. #ifdef CF_TRACE_ENABLED
  16009. auto trace = CF_Trace_0(this);
  16010. #endif
  16011.  
  16012. s_VehicleSurfaces[s_LastSurface] = this;
  16013. }
  16014.  
  16015. /**
  16016. * @brief Private constructor to prevent from marking as ref
  16017. */
  16018. private void ~CF_VehicleSurface()
  16019. {
  16020. #ifdef CF_TRACE_ENABLED
  16021. auto trace = CF_Trace_0(this);
  16022. #endif
  16023.  
  16024. }
  16025.  
  16026. /**
  16027. * @brief Get the vehicle surface by the name. From 'CfgVehicleSurfaces'
  16028. *
  16029. * @param name The class name of the surface
  16030. *
  16031. * @return Instance of the vehicle surface class, creates a new one if it doesn't exist
  16032. */
  16033. static CF_VehicleSurface Get(string name)
  16034. {
  16035. #ifdef CF_TRACE_ENABLED
  16036. auto trace = CF_Trace_1("CF_VehicleSurface").Add(name);
  16037. #endif
  16038.  
  16039. auto surf = s_VehicleSurfaces[name];
  16040. if (!surf)
  16041. {
  16042. s_LastSurface = name;
  16043. return new CF_VehicleSurface();
  16044. }
  16045.  
  16046. return surf;
  16047. }
  16048.  
  16049. /**
  16050. * @brief Get the vehicle surface at the position in the world
  16051. *
  16052. * @param position The position of the surface within the world
  16053. *
  16054. * @return Global instance of the vehicle surface class
  16055. */
  16056. static CF_VehicleSurface At(vector position)
  16057. {
  16058. return CF_Surface.At(position).VehicleSurface;
  16059. }
  16060.  
  16061. /**
  16062. * @brief Get the vehicle surface at the position in the world at it's maximum height
  16063. *
  16064. * @param x The x position of the surface within the world
  16065. * @param z The z position of the surface within the world
  16066. *
  16067. * @return Global instance of the vehicle surface class
  16068. */
  16069. static CF_VehicleSurface At(float x, float z)
  16070. {
  16071. return CF_Surface.At(x, z).VehicleSurface;
  16072. }
  16073.  
  16074. /**
  16075. * @brief Get the surface at the position in the world at it's maximum height
  16076. *
  16077. * @param object The object above the surface of the object
  16078. *
  16079. * @return Global instance of the surface class
  16080. */
  16081. static CF_VehicleSurface At(Object object)
  16082. {
  16083. string name;
  16084. int liquidType;
  16085. GetGame().SurfaceUnderObject(object, name, liquidType);
  16086. return CF_Surface.Get(name).VehicleSurface;
  16087. }
  16088.  
  16089. #ifdef CF_DebugUI
  16090. bool CF_OnDebugUpdate(CF_Debug instance, CF_DebugUI_Type type)
  16091. {
  16092. instance.Add("Name", Name);
  16093. instance.Add("Noise Steer", NoiseSteer);
  16094. instance.Add("Noise Frequency", NoiseFrequency);
  16095. instance.Add("Roughness", Roughness);
  16096. instance.Add("Friction Offroad", FrictionOffroad);
  16097. instance.Add("Friction Slick", FrictionSlick);
  16098. instance.Add("Roll Resistance", RollResistance);
  16099. instance.Add("Roll Drag", RollDrag);
  16100.  
  16101. return true;
  16102. }
  16103. #endif
  16104.  
  16105. override string GetDebugName()
  16106. {
  16107. string str = this.ToString();
  16108.  
  16109. str += ",\n\tName=\"" + Name + "\"";
  16110. str += ",\n\tNoiseSteer=\"" + NoiseSteer + "\"";
  16111. str += ",\n\tNoiseFrequency=\"" + NoiseFrequency + "\"";
  16112. str += ",\n\tRoughness=\"" + Roughness + "\"";
  16113. str += ",\n\tFrictionOffroad=\"" + FrictionOffroad + "\"";
  16114. str += ",\n\tFrictionSlick=\"" + FrictionSlick + "\"";
  16115. str += ",\n\tRollResistance=\"" + RollResistance + "\"";
  16116. str += ",\n\tRollDrag=\"" + RollDrag + "\"";
  16117.  
  16118. return str;
  16119. }
  16120.  
  16121. [CF_EventSubscriber(ScriptCaller.Create(CF_VehicleSurface._GetAllSurfaces), CF_LifecycleEvents.OnMissionCreate)]
  16122. static void _GetAllSurfaces()
  16123. {
  16124. string path = "CfgVehicleSurfaces";
  16125. string name;
  16126. int count = GetGame().ConfigGetChildrenCount(path);
  16127.  
  16128. for (int index = 0; index < count; index++)
  16129. {
  16130. GetGame().ConfigGetChildName(path, index, name);
  16131.  
  16132. CF_VehicleSurface.Get(name);
  16133. }
  16134. }
  16135.  
  16136. private static int GetValueInt(string param)
  16137. {
  16138. string path = "CfgVehicleSurfaces" + " " + s_LastSurface + " " + param;
  16139. if (GetGame().ConfigIsExisting(path)) return GetGame().ConfigGetInt(path);
  16140. return 0;
  16141. }
  16142.  
  16143. private static float GetValueFloat(string param)
  16144. {
  16145. string path = "CfgVehicleSurfaces" + " " + s_LastSurface + " " + param;
  16146. if (GetGame().ConfigIsExisting(path)) return GetGame().ConfigGetFloat(path);
  16147. return 0;
  16148. }
  16149.  
  16150. private static string GetValueString(string param)
  16151. {
  16152. string path = "CfgVehicleSurfaces" + " " + s_LastSurface + " " + param;
  16153. if (GetGame().ConfigIsExisting(path)) return GetGame().ConfigGetTextOut(path);
  16154. return string.Empty;
  16155. }
  16156. };
  16157. class CF_WeaponStableState : WeaponStableState
  16158. {
  16159. bool m_CF_HasBullet;
  16160. bool m_CF_HasMagazine;
  16161. bool m_CF_IsJammed;
  16162.  
  16163. override bool IsRepairEnabled()
  16164. {
  16165. return true;
  16166. }
  16167.  
  16168. override bool HasBullet()
  16169. {
  16170. return m_CF_HasBullet;
  16171. }
  16172.  
  16173. override bool HasMagazine()
  16174. {
  16175. return m_CF_HasMagazine;
  16176. }
  16177.  
  16178. override bool IsJammed()
  16179. {
  16180. return m_CF_IsJammed;
  16181. }
  16182.  
  16183. /**
  16184. * @brief Prevents default validation. 'm_muzzleHasBullet' is setup in 'WeaponFSM::CF_FindBestStableState' only.
  16185. */
  16186. #ifndef DAYZ_1_15
  16187. override void ValidateMuzzleArray()
  16188. {
  16189. return;
  16190. }
  16191. #endif
  16192. };
  16193. modded class Weapon_Base
  16194. {
  16195. /**
  16196. * @brief Spawns a magazine into the weapon as an attachment or into the internal magazine. Calls 'CF_AttachMagazine' on the spawned magazine.
  16197. *
  16198. * @param magazineType The class type of the magazine, must inherit from Magazine_Base
  16199. * @param quantity The amount of ammunition in the stack/magazine, -1 for max
  16200. * @param health The normalized health value, 0 is ruined, 1 is max health
  16201. *
  16202. * @return True if the magazine was spawned succesfully
  16203. */
  16204. bool CF_SpawnMagazine(string magazineType, int quantity = -1, float health = 1)
  16205. {
  16206. if (!GetGame().IsKindOf(magazineType, "Magazine_Base"))
  16207. {
  16208. return false;
  16209. }
  16210.  
  16211. InventoryLocation location();
  16212.  
  16213. Magazine_Base magazine;
  16214.  
  16215. bool isMagazine = !GetGame().IsKindOf(magazineType, "Ammunition_Base");
  16216. bool success;
  16217.  
  16218. if (isMagazine)
  16219. {
  16220. location.SetAttachment(this, NULL, InventorySlots.MAGAZINE);
  16221. success = Class.CastTo(magazine, SpawnEntity(magazineType, location, ECE_IN_INVENTORY, RF_DEFAULT));
  16222. }
  16223. else
  16224. {
  16225. InventoryLocation weaponLocation();
  16226. success = GetInventory().GetCurrentInventoryLocation(weaponLocation);
  16227. if (success)
  16228. {
  16229. EntityAI parent = weaponLocation.GetParent();
  16230.  
  16231. if (parent && parent.GetInventory().FindFirstFreeLocationForNewEntity(magazineType, FindInventoryLocationType.CARGO, location))
  16232. {
  16233. success = Class.CastTo(magazine, SpawnEntity(magazineType, location, ECE_IN_INVENTORY, RF_DEFAULT));
  16234. }
  16235. else
  16236. {
  16237. success = Class.CastTo(magazine, GetGame().CreateObjectEx(magazineType, GetWorldPosition(), ECE_PLACE_ON_SURFACE));
  16238. }
  16239. }
  16240. }
  16241.  
  16242. if (!success)
  16243. {
  16244. return false;
  16245. }
  16246.  
  16247. if (quantity != -1)
  16248. {
  16249. magazine.ServerSetAmmoCount(quantity);
  16250. }
  16251.  
  16252. magazine.SetHealth01("", "", health);
  16253.  
  16254. if (CF_AttachMagazine(magazine))
  16255. {
  16256. return false;
  16257. }
  16258.  
  16259. if (quantity == -1 && magazine)
  16260. {
  16261. if (isMagazine)
  16262. {
  16263. // make sure the magazine is full
  16264. magazine.ServerSetAmmoMax();
  16265. }
  16266. else
  16267. {
  16268. // delete overfill
  16269. GetGame().ObjectDelete(magazine);
  16270. magazine = null; // may be delayed
  16271. }
  16272. }
  16273.  
  16274. return true;
  16275. }
  16276.  
  16277. /**
  16278. * @brief Attaches a magazine to the weapon, fills up the internal magazine and chamber for all muzzle points.
  16279. *
  16280. * @param magazine The magazine to be attached
  16281. *
  16282. * @return True if operation successful
  16283. */
  16284. bool CF_AttachMagazine(Magazine_Base magazine)
  16285. {
  16286. bool isMagazine = !magazine.IsInherited(Ammunition_Base);
  16287.  
  16288. if (GetGame().IsDedicatedServer())
  16289. {
  16290. // Delete the entities from clients
  16291. GetGame().RemoteObjectDelete(this);
  16292. GetGame().RemoteObjectDelete(magazine);
  16293. }
  16294.  
  16295. // Magazine has to attach into the attachment slot
  16296. if (isMagazine)
  16297. {
  16298. InventoryLocation srcLocation();
  16299. magazine.GetInventory().GetCurrentInventoryLocation(srcLocation);
  16300.  
  16301. InventoryLocation dstLocation();
  16302. dstLocation.SetAttachment(this, magazine, InventorySlots.MAGAZINE);
  16303.  
  16304. // If false, then the magazine is already properly attached to the desired slot
  16305. if (!dstLocation.CompareLocationOnly(srcLocation) && !GameInventory.LocationMoveEntity(srcLocation, dstLocation))
  16306. {
  16307. return false;
  16308. }
  16309. }
  16310.  
  16311. float damage;
  16312. string ammoType;
  16313.  
  16314. int ammoCount = magazine.GetAmmoCount();
  16315. int muzzleCount = GetMuzzleCount();
  16316.  
  16317. for (int muzzle = 0; muzzle < muzzleCount; muzzle++)
  16318. {
  16319. int internalMagazineMax = GetInternalMagazineMaxCartridgeCount(muzzle);
  16320. while (GetInternalMagazineCartridgeCount(muzzle) < internalMagazineMax && ammoCount > 0)
  16321. {
  16322. ammoCount--;
  16323. if (magazine.ServerAcquireCartridge(damage, ammoType))
  16324. {
  16325. PushCartridgeToInternalMagazine(muzzle, damage, ammoType);
  16326. }
  16327. }
  16328.  
  16329. if (ammoCount > 0)
  16330. {
  16331. ammoCount--;
  16332.  
  16333. if (magazine.ServerAcquireCartridge(damage, ammoType))
  16334. {
  16335. PushCartridgeToChamber(muzzle, damage, ammoType);
  16336. ShowBullet(muzzle);
  16337. }
  16338. }
  16339. }
  16340.  
  16341. m_fsm.CF_FindBestStableState();
  16342.  
  16343. if (GetGame().IsDedicatedServer())
  16344. {
  16345. GetGame().RemoteObjectCreate(this);
  16346.  
  16347. // When ammoCount reaches zero the magazine is deleted
  16348. if (magazine)
  16349. {
  16350. GetGame().RemoteObjectCreate(magazine);
  16351. }
  16352. }
  16353.  
  16354. return true;
  16355. }
  16356.  
  16357. WeaponFSM CF_GetFSM()
  16358. {
  16359. return m_fsm;
  16360. }
  16361.  
  16362. void CF_SyncSelectionState(WeaponStableState state)
  16363. {
  16364. int muzzleCount = state.m_muzzleHasBullet.Count();
  16365. for (int muzzle = 0; muzzle < muzzleCount; muzzle++)
  16366. {
  16367. if (state.m_muzzleHasBullet[muzzle] != MuzzleState.E)
  16368. {
  16369. ShowBullet(muzzle);
  16370. }
  16371. else
  16372. {
  16373. HideBullet(muzzle);
  16374. }
  16375. }
  16376.  
  16377. if (state.HasMagazine())
  16378. {
  16379. ShowMagazine();
  16380. }
  16381. else
  16382. {
  16383. HideMagazine();
  16384. }
  16385. }
  16386. };
  16387. modded class WeaponFSM
  16388. {
  16389. /**
  16390. * @brief Finds the best stable state that matches the weapon.
  16391. *
  16392. * @return True if the repair was successful
  16393. */
  16394. bool CF_FindBestStableState()
  16395. {
  16396. // Only repair stable states
  16397. WeaponStableState state = WeaponStableState.Cast(m_State);
  16398. if (!state || !state.IsRepairEnabled())
  16399. {
  16400. return false;
  16401. }
  16402.  
  16403. // Make sure a weapon is assigned
  16404. Weapon_Base weapon = state.m_weapon;
  16405. if (!weapon)
  16406. {
  16407. return false;
  16408. }
  16409.  
  16410. CF_WeaponStableState comparingState = new CF_WeaponStableState();
  16411. comparingState.m_muzzleHasBullet.Clear();
  16412.  
  16413. int muzzleCount = weapon.GetMuzzleCount();
  16414. for (int muzzle = 0; muzzle < muzzleCount; muzzle++)
  16415. {
  16416. bool magazine = weapon.GetMagazine(muzzle) != null;
  16417. bool jammed = weapon.IsChamberJammed(muzzle);
  16418. bool empty = weapon.IsChamberEmpty(muzzle);
  16419. bool firedOut = weapon.IsChamberFiredOut(muzzle);
  16420. bool loaded = !empty && !firedOut;
  16421.  
  16422. if (loaded)
  16423. {
  16424. comparingState.m_muzzleHasBullet.Insert(MuzzleState.L);
  16425. }
  16426. else if (empty)
  16427. {
  16428. comparingState.m_muzzleHasBullet.Insert(MuzzleState.E);
  16429. }
  16430. else if (firedOut)
  16431. {
  16432. comparingState.m_muzzleHasBullet.Insert(MuzzleState.F);
  16433. }
  16434.  
  16435. comparingState.m_CF_HasMagazine |= magazine;
  16436. comparingState.m_CF_HasBullet |= !empty;
  16437. comparingState.m_CF_IsJammed |= jammed;
  16438. }
  16439.  
  16440. int count = m_Transitions.Count();
  16441. for (int i = 0; i < count; ++i)
  16442. {
  16443. WeaponStableState srcState;
  16444. if (!Class.CastTo(srcState, m_Transitions[i].m_srcState))
  16445. {
  16446. continue;
  16447. }
  16448.  
  16449. if (!srcState.CF_Equals(comparingState))
  16450. {
  16451. continue;
  16452. }
  16453.  
  16454. Terminate();
  16455. m_State = srcState;
  16456. Start(null, true);
  16457. weapon.CF_SyncSelectionState(srcState);
  16458. srcState.SyncAnimState();
  16459.  
  16460. return true;
  16461. }
  16462.  
  16463. return false;
  16464. }
  16465. };
  16466. modded class WeaponStableState
  16467. {
  16468. bool CF_Equals(WeaponStableState other)
  16469. {
  16470. if (IsRepairEnabled() != other.IsRepairEnabled())
  16471. {
  16472. return false;
  16473. }
  16474.  
  16475. if (HasBullet() != other.HasBullet())
  16476. {
  16477. return false;
  16478. }
  16479.  
  16480. if (HasMagazine() != other.HasMagazine())
  16481. {
  16482. return false;
  16483. }
  16484.  
  16485. if (IsJammed() != other.IsJammed())
  16486. {
  16487. return false;
  16488. }
  16489.  
  16490. int muzzleCount = m_muzzleHasBullet.Count();
  16491. if (muzzleCount != other.m_muzzleHasBullet.Count())
  16492. {
  16493. return false;
  16494. }
  16495.  
  16496. for (int muzzle = 0; muzzle < muzzleCount; muzzle++)
  16497. {
  16498. if (m_muzzleHasBullet[muzzle] != other.m_muzzleHasBullet[muzzle])
  16499. {
  16500. return false;
  16501. }
  16502. }
  16503.  
  16504. return true;
  16505. }
  16506. };
  16507. modded class KeybindingElement
  16508. {
  16509. bool R_WasSet
  16510. string R_DisplayName;
  16511.  
  16512. override void Reload()
  16513. {
  16514. super.Reload();
  16515.  
  16516. if ( R_WasSet )
  16517. {
  16518. m_ElementName.SetText( R_DisplayName );
  16519. }
  16520. }
  16521. }modded class KeybindingsGroup
  16522. {
  16523. void KeybindingsGroup( int index, Input input, Widget parent, KeybindingsMenu menu )
  16524. {
  16525. Widget subgroup = m_Root.FindAnyWidget( "group_content" );
  16526.  
  16527. TIntArray actions = new TIntArray;
  16528. GetUApi().GetActiveInputs( actions );
  16529.  
  16530. for( int i = 0; i < ModLoader.GetMods().Count(); i++ )
  16531. {
  16532. ModStructure mod = ModLoader.GetMods().Get( i );
  16533.  
  16534. bool display = GetGame().ConfigIsExisting( mod.GetModPath() + " inputs" );
  16535.  
  16536. TIntArray tempActions = new TIntArray;
  16537.  
  16538. AddCFSubgroup( subgroup, input, mod, display, actions, tempActions );
  16539.  
  16540. actions.Clear();
  16541. actions.Copy( tempActions );
  16542. }
  16543.  
  16544. AddDayZSubgroup( subgroup, input, actions );
  16545.  
  16546. subgroup.Update();
  16547.  
  16548. m_Root.SetHandler( this );
  16549. }
  16550.  
  16551. void AddCFAction( int index, Widget parent, Input input, string displayName )
  16552. {
  16553. KeybindingElement ele = new KeybindingElement( index, parent, this );
  16554. ele.R_WasSet = true;
  16555. ele.R_DisplayName = displayName;
  16556. ele.Reload();
  16557. m_KeyWidgets.Insert( index, ele );
  16558. }
  16559.  
  16560. override void AddSubgroup( /*int index, */Widget parent, Input input )
  16561. {
  16562. // does nothing
  16563. }
  16564.  
  16565. void AddCFSubgroup( Widget parent, Input input, ModStructure mod, bool display, TIntArray inActions, out TIntArray remainingActions )
  16566. {
  16567. Widget subgroup_content;
  16568.  
  16569. if ( display )
  16570. {
  16571. Widget subgroup = GetGame().GetWorkspace().CreateWidgets( "JM/CF/GUI/layouts/keybinding_subgroup.layout", parent );
  16572. TextWidget subgroup_name = TextWidget.Cast( subgroup.FindAnyWidget( "subgroup_text" ) );
  16573.  
  16574. string modDisplayName = "";
  16575. GetGame().ConfigGetText( mod.GetModPath() + " name", modDisplayName );
  16576.  
  16577. subgroup_name.SetText( modDisplayName );
  16578. subgroup_content = subgroup.FindAnyWidget( "subgroup_content" );
  16579. }
  16580.  
  16581. for ( int i = 0; i < inActions.Count(); i++ )
  16582. {
  16583. string displayName = "";
  16584. bool found = false;
  16585.  
  16586. for ( int j = 0; j < mod.GetModInputs().Count(); j++ )
  16587. {
  16588. int id = GetUApi().GetInputByName( mod.GetModInputs()[j].Name ).ID();
  16589. if ( id == inActions[i] )
  16590. {
  16591. displayName = Widget.TranslateString( "#" + mod.GetModInputs()[j].Localization );
  16592. int hashSymbol = displayName.IndexOf( " " );
  16593. if ( hashSymbol < 1 )
  16594. {
  16595. displayName = mod.GetModInputs()[j].Localization;
  16596. }
  16597. found = true;
  16598. }
  16599. }
  16600.  
  16601. if ( found )
  16602. {
  16603. if ( display )
  16604. {
  16605. AddCFAction( inActions.Get( i ), subgroup_content, input, displayName );
  16606. }
  16607. } else
  16608. {
  16609. remainingActions.Insert( inActions.Get( i ) );
  16610. }
  16611. }
  16612.  
  16613. if ( display )
  16614. {
  16615. subgroup_content.Update();
  16616. }
  16617. }
  16618.  
  16619. void AddDayZSubgroup( Widget parent, Input input, TIntArray inActions )
  16620. {
  16621. Widget subgroup = GetGame().GetWorkspace().CreateWidgets( "JM/CF/GUI/layouts/keybinding_subgroup.layout", parent );
  16622. TextWidget subgroup_name = TextWidget.Cast( subgroup.FindAnyWidget( "subgroup_text" ) );
  16623.  
  16624. subgroup_name.SetText( "DayZ Standalone" );
  16625. Widget subgroup_content = subgroup.FindAnyWidget( "subgroup_content" );
  16626.  
  16627. for( int i = 0; i < inActions.Count(); i++ )
  16628. {
  16629. AddAction( inActions.Get( i ), subgroup_content, input );
  16630. }
  16631.  
  16632. subgroup_content.Update();
  16633. }
  16634. }modded class MissionBase
  16635. {
  16636. void MissionBase()
  16637. {
  16638. #ifdef CF_TRACE_ENABLED
  16639. auto trace = CF_Trace_0(this);
  16640. #endif
  16641.  
  16642. CF_LifecycleEvents.OnMissionCreate.Invoke(this, CF_EventArgs.Empty);
  16643. }
  16644.  
  16645. void ~MissionBase()
  16646. {
  16647. #ifdef CF_TRACE_ENABLED
  16648. auto trace = CF_Trace_0(this);
  16649. #endif
  16650.  
  16651. CF_LifecycleEvents.OnMissionDestroy.Invoke(this, CF_EventArgs.Empty);
  16652. }
  16653. };
  16654. modded class MissionBase
  16655. {
  16656. protected bool m_bLoaded = false;
  16657.  
  16658. void MissionBase()
  16659. {
  16660. CF_ModuleGameManager.UpdateGameFlag();
  16661.  
  16662. // Deprecated
  16663. if (!ModuleManagerExists())
  16664. {
  16665. CreateModuleManager(new JMModuleConstructor());
  16666. }
  16667. }
  16668.  
  16669. void OnMissionLoaded()
  16670. {
  16671. }
  16672.  
  16673. void CF_OnUpdate(float timeslice)
  16674. {
  16675. if (g_Game.IsLoading())
  16676. {
  16677. return;
  16678. }
  16679.  
  16680. if (!m_bLoaded)
  16681. {
  16682. m_bLoaded = true;
  16683. OnMissionLoaded();
  16684. }
  16685.  
  16686. CF_ModuleGameManager.OnUpdate(this, new CF_EventUpdateArgs(timeslice));
  16687. }
  16688. };
  16689. modded class MissionGameplay
  16690. {
  16691. override void OnMissionStart()
  16692. {
  16693. super.OnMissionStart();
  16694.  
  16695. CF_ModuleCoreManager.OnSettingsChanged(this, CF_EventArgs.Empty);
  16696. CF_ModuleCoreManager.OnMissionStart(this, CF_EventArgs.Empty);
  16697. }
  16698.  
  16699. override void OnMissionFinish()
  16700. {
  16701. super.OnMissionFinish();
  16702.  
  16703. CF_ModuleCoreManager.OnMissionFinish(this, CF_EventArgs.Empty);
  16704. }
  16705.  
  16706. override void OnMissionLoaded()
  16707. {
  16708. super.OnMissionLoaded();
  16709.  
  16710. CF_ModuleCoreManager.OnMissionLoaded(this, CF_EventArgs.Empty);
  16711. }
  16712.  
  16713. override void OnUpdate( float timeslice )
  16714. {
  16715. CF_OnUpdate(timeslice);
  16716.  
  16717. super.OnUpdate( timeslice );
  16718. }
  16719. };
  16720. modded class MissionServer
  16721. {
  16722. void MissionServer()
  16723. {
  16724. GetRPCManager().AddRPC( "CF", "RecieveModList", this, SingeplayerExecutionType.Server );
  16725. }
  16726.  
  16727. override void OnEvent( EventType eventTypeId, Param params )
  16728. {
  16729. super.OnEvent( eventTypeId, params );
  16730.  
  16731. switch( eventTypeId )
  16732. {
  16733. case LogoutCancelEventTypeID:
  16734. LogoutCancelEventParams logoutCancelParams;
  16735.  
  16736. Class.CastTo( logoutCancelParams, params );
  16737.  
  16738. auto logoutCancelArgs = new CF_EventPlayerArgs();
  16739. Class.CastTo(logoutCancelArgs.Player, logoutCancelParams.param1);
  16740. CF_ModuleWorldManager.OnClientLogoutCancelled(this, logoutCancelArgs);
  16741.  
  16742. break;
  16743. }
  16744. }
  16745.  
  16746. override void OnInit()
  16747. {
  16748. super.OnInit();
  16749. }
  16750.  
  16751. override void OnMissionStart()
  16752. {
  16753. super.OnMissionStart();
  16754.  
  16755. CF_ModuleCoreManager.OnSettingsChanged(this, CF_EventArgs.Empty);
  16756. CF_ModuleCoreManager.OnMissionStart(this, CF_EventArgs.Empty);
  16757. }
  16758.  
  16759. override void OnMissionFinish()
  16760. {
  16761. super.OnMissionFinish();
  16762.  
  16763. CF_ModuleCoreManager.OnMissionFinish(this, CF_EventArgs.Empty);
  16764. }
  16765.  
  16766. override void OnMissionLoaded()
  16767. {
  16768. super.OnMissionLoaded();
  16769.  
  16770. CF_ModuleCoreManager.OnMissionLoaded(this, CF_EventArgs.Empty);
  16771. }
  16772.  
  16773. override void OnUpdate( float timeslice )
  16774. {
  16775. CF_OnUpdate(timeslice);
  16776.  
  16777. super.OnUpdate( timeslice );
  16778. }
  16779.  
  16780. override void InvokeOnConnect(PlayerBase player, PlayerIdentity identity)
  16781. {
  16782. super.InvokeOnConnect( player, identity );
  16783.  
  16784. CF_ModuleWorldManager.OnInvokeConnect(this, new CF_EventPlayerArgs(player, identity));
  16785. }
  16786.  
  16787. override void InvokeOnDisconnect( PlayerBase player )
  16788. {
  16789. super.InvokeOnDisconnect( player );
  16790.  
  16791. CF_ModuleWorldManager.OnInvokeDisconnect(this, new CF_EventPlayerArgs(player));
  16792. }
  16793.  
  16794. override void OnClientReadyEvent( PlayerIdentity identity, PlayerBase player )
  16795. {
  16796. super.OnClientReadyEvent( identity, player );
  16797.  
  16798. CF_ModuleWorldManager.OnClientReady(this, new CF_EventPlayerArgs(player, identity));
  16799. }
  16800.  
  16801. override void OnClientReconnectEvent( PlayerIdentity identity, PlayerBase player )
  16802. {
  16803. super.OnClientReconnectEvent( identity, player );
  16804.  
  16805. CF_ModuleWorldManager.OnClientReconnect(this, new CF_EventPlayerArgs(player, identity));
  16806. }
  16807.  
  16808. override void OnClientRespawnEvent( PlayerIdentity identity, PlayerBase player )
  16809. {
  16810. super.OnClientRespawnEvent( identity, player );
  16811.  
  16812. CF_ModuleWorldManager.OnClientRespawn(this, new CF_EventPlayerArgs(player, identity));
  16813. }
  16814.  
  16815. override void OnClientDisconnectedEvent( PlayerIdentity identity, PlayerBase player, int logoutTime, bool authFailed )
  16816. {
  16817. super.OnClientDisconnectedEvent( identity, player, logoutTime, authFailed );
  16818.  
  16819. auto args = new CF_EventPlayerDisconnectedArgs(player, identity);
  16820. args.LogoutTime = logoutTime;
  16821. args.AuthFailed = authFailed;
  16822.  
  16823. CF_ModuleWorldManager.OnClientLogout(this, args);
  16824. }
  16825.  
  16826. override void PlayerDisconnected( PlayerBase player, PlayerIdentity identity, string uid )
  16827. {
  16828. auto args = new CF_EventPlayerDisconnectedArgs(player, identity);
  16829. args.UID = uid;
  16830.  
  16831. // must call before vanilla
  16832. CF_ModuleWorldManager.OnClientDisconnect(this, args);
  16833.  
  16834. super.PlayerDisconnected( player, identity, uid );
  16835. }
  16836.  
  16837. override PlayerBase OnClientNewEvent( PlayerIdentity identity, vector pos, ParamsReadContext ctx )
  16838. {
  16839. PlayerBase player = super.OnClientNewEvent( identity, pos, ctx );
  16840.  
  16841. auto args = new CF_EventNewPlayerArgs(player, identity, pos, ctx);
  16842. CF_ModuleWorldManager.OnClientNew(this, args);
  16843.  
  16844. //TODO: allow the args to override these 'out' variables again, 'CF_ModuleWorldManager.OnClientNew' deletes 'args' before this can be used
  16845. //player = args.Player;
  16846.  
  16847. return player;
  16848. }
  16849.  
  16850. override void OnClientPrepareEvent( PlayerIdentity identity, out bool useDB, out vector pos, out float yaw, out int preloadTimeout )
  16851. {
  16852. auto args = new CF_EventPlayerPrepareArgs();
  16853. args.Identity = identity;
  16854. args.UseDatabase = useDB;
  16855. args.Position = pos;
  16856. args.Yaw = yaw;
  16857. args.PreloadTimeout = preloadTimeout;
  16858.  
  16859. CF_ModuleWorldManager.OnClientPrepare(this, args);
  16860.  
  16861. //TODO: allow the args to override these 'out' variables again, 'CF_ModuleWorldManager.OnClientPrepare' deletes 'args' before this can be used
  16862. //useDB = args.UseDatabase;
  16863. //pos = args.Position;
  16864. //yaw = args.Yaw;
  16865. //preloadTimeout = args.PreloadTimeout;
  16866.  
  16867. // must call module code before vanilla
  16868. super.OnClientPrepareEvent(identity, useDB, pos, yaw, preloadTimeout);
  16869. }
  16870. };
  16871. /**
  16872. * @class JMModuleConstructor
  16873. *
  16874. * @deprecated
  16875. */
  16876. class JMModuleConstructor : JMModuleConstructorBase
  16877. {
  16878. };
  16879. raP  Z  CfgPatches 3 CfgMods ” Z  JM_CF_Scripts L ” units weapons requiredVersion ÍÌÌ=requiredAddons  DZ_Data ”  JM_CommunityFramework µ Z  dir JM/CF  picture  action hideName hidePicture   name Community Framework  credits Jacob_Mango, Arkensor  creditsJson JM/CF/Scripts/Data/Credits.json  version 0.0.0  versionPath JM/CF/scripts/Data/Version.hpp  author Jacob_Mango  authorID 76561198103677868 extra  type mod defines
  16880. CF_MODULE_CONFIG CF_EXPRESSION CF_TRACE_STACK_NAME_ASSUMPTION_FIX CF_GHOSTICONS CF_MODSTORAGE_DISABLE CF_MODSTORAGE_MODULE_DISABLE CF_SURFACES CF_MODULES CF_REF_FIX CF_BUGFIX_REF dependencies  Core Game World Mission defs è Z  engineScriptModule e gameLibScriptModule ’ gameScriptModule  worldScriptModule ü missionScriptModule * Z  value files  JM/CF/Scripts/1_Core ’  value files  JM/CF/Scripts/2_GameLib   value CF_CreateGame files  JM/CF/Scripts/3_Game ü  value files  JM/CF/Scripts/4_World *  value files  JM/CF/Scripts/5_Mission Z [WorkbenchPluginAttribute("Build Mod", "Builds current mod", "F3", "", {"ResourceManager", "ScriptEditor"})]
  16881. class BuildMod: DayZProjectManager
  16882. {
  16883. override void Run()
  16884. {
  16885. RunDayZBatList({
  16886. string.Format("P:\\%1\\Workbench\\Batchfiles\\Exit.bat", ModName),
  16887. string.Format("P:\\%1\\Workbench\\Batchfiles\\ZBinarizeDeploy.bat", ModName)
  16888. });
  16889. }
  16890. }
  16891. [WorkbenchPluginAttribute("Edit Project", "Edit Project", "", "", {"ResourceManager", "ScriptEditor"})]
  16892. class DayZProjectManager: DayZTool
  16893. {
  16894. [Attribute("", "editbox")]
  16895. string ModName = "JM\\CF";
  16896.  
  16897. override void Run()
  16898. {
  16899. Workbench.ScriptDialog("Edit Project Settings", "", this);
  16900. }
  16901.  
  16902. override void RunDayZBat(string filepath, bool wait = false)
  16903. {
  16904. if (filepath.Length() < 2) return;
  16905.  
  16906. filepath.Replace("\\", "/");
  16907.  
  16908. if (filepath[1] != ":")
  16909. {
  16910. string cwd;
  16911. Workbench.GetCwd(cwd);
  16912. filepath = cwd + "/" + filepath;
  16913. }
  16914.  
  16915. int index = filepath.IndexOf("/");
  16916. int last_index = index;
  16917.  
  16918. while(index != -1)
  16919. {
  16920. last_index = index;
  16921. index = filepath.IndexOfFrom(last_index + 1, "/");
  16922. }
  16923.  
  16924. if (last_index == -1) return;
  16925.  
  16926. string path = filepath.Substring(0, last_index);
  16927. string bat = filepath.Substring(last_index + 1, filepath.Length() - last_index - 1);
  16928.  
  16929. Print("cmd /c \"chdir /D " + path + " & call " + bat + "\"");
  16930. Workbench.RunCmd("cmd /c \"chdir /D " + path + " & call " + bat + "\"", wait);
  16931. }
  16932.  
  16933.  
  16934. void RunDayZBatList(array<string> filepaths)
  16935. {
  16936. foreach (string file: filepaths) {
  16937. RunDayZBat(file, true);
  16938. }
  16939. }
  16940. }
  16941.  
  16942. [WorkbenchPluginAttribute("Launch Client", "Launches the game", "F8", "", {"ResourceManager", "ScriptEditor"})]
  16943. class LaunchClientModTool: DayZProjectManager
  16944. {
  16945. override void Run()
  16946. {
  16947. RunDayZBat(string.Format("P:\\%1\\Workbench\\Batchfiles\\LaunchClient.bat", ModName), true);
  16948. }
  16949. }
  16950.  
  16951.  
  16952.  
  16953.  
  16954. [WorkbenchPluginAttribute("Launch Local MP", "Launches the server and client, automatically joins", "F6", "", {"ResourceManager", "ScriptEditor"})]
  16955. class LaunchLocalMPModTool: DayZProjectManager
  16956. {
  16957. override void Run()
  16958. {
  16959. RunDayZBat(string.Format("P:\\%1\\Workbench\\Batchfiles\\LaunchLocalMP.bat", ModName), true);
  16960. }
  16961. }
  16962.  
  16963.  
  16964.  
  16965.  
  16966. [WorkbenchPluginAttribute("Launch Offline", "Launches the game in offline mode", "F5", "", {"ResourceManager", "ScriptEditor"})]
  16967. class LaunchOfflineModTool: DayZProjectManager
  16968. {
  16969. override void Run()
  16970. {
  16971. RunDayZBat(string.Format("P:\\%1\\Workbench\\Batchfiles\\LaunchOffline.bat", ModName), true);
  16972. }
  16973. }
  16974.  
  16975.  
  16976.  
  16977.  
  16978. [WorkbenchPluginAttribute("Launch Client", "Launches the game", "F9", "", {"ResourceManager", "ScriptEditor"})]
  16979. class LaunchServerModTool: DayZProjectManager
  16980. {
  16981. override void Run()
  16982. {
  16983. RunDayZBat(string.Format("P:\\%1\\Workbench\\Batchfiles\\LaunchServer.bat", ModName), true);
  16984. }
  16985. }
  16986.  
  16987.  
  16988.  
  16989. [WorkbenchPluginAttribute("Open Log Files", "Opens logfiles in NPP", "F4", "", {"ResourceManager", "ScriptEditor"})]
  16990. class OpenLogFiles: DayZProjectManager
  16991. {
  16992. override void Run()
  16993. {
  16994. RunDayZBat(string.Format("P:\\%1\\Workbench\\Batchfiles\\OpenLogs.bat", ModName), true);
  16995. }
  16996. }class PluginErrorMessage
  16997. {
  16998. static int Show(string message)
  16999. {
  17000. PluginErrorMessage msg();
  17001. return Workbench.ScriptDialog("Error", message, msg);
  17002. }
  17003.  
  17004. [ButtonAttribute("Ok")]
  17005. void Ok()
  17006. {
  17007.  
  17008. }
  17009. }
  17010. S¼Öâò¥aj@æ”du¢°F¹•‘
Add Comment
Please, Sign In to add comment