A stable modding interface between Techblox and mods https://mod.exmods.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TweakableEngine.cs 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. using System;
  2. using System.Reflection;
  3. using RobocraftX.Blocks;
  4. using Gamecraft.Wires;
  5. using GamecraftModdingAPI.Utility;
  6. using Svelto.ECS;
  7. namespace GamecraftModdingAPI.Blocks
  8. {
  9. public class TweakableEngine : IApiEngine
  10. {
  11. public string Name { get; } = "GamecraftModdingAPITweakableGameEngine";
  12. public EntitiesDB entitiesDB { set; private get; }
  13. public bool IsInGame = false;
  14. public void Dispose()
  15. {
  16. IsInGame = false;
  17. }
  18. public void Ready()
  19. {
  20. IsInGame = true;
  21. }
  22. // Implementations for Tweakable static class
  23. public T GetStatAny<T>(EGID blockID, TweakableStat stat)
  24. {
  25. switch (stat)
  26. {
  27. case TweakableStat.TopSpeed:
  28. if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
  29. {
  30. return (T)(object)entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID).maxVelocity;
  31. }
  32. break;
  33. case TweakableStat.Torque:
  34. if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
  35. {
  36. return (T)(object)entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID).maxForce;
  37. }
  38. break;
  39. case TweakableStat.MaxExtension:
  40. if (entitiesDB.Exists<PistonReadOnlyStruct>(blockID))
  41. {
  42. return (T)(object)entitiesDB.QueryEntity<PistonReadOnlyStruct>(blockID).maxDeviation;
  43. }
  44. break;
  45. case TweakableStat.MinAngle:
  46. if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
  47. {
  48. return (T)(object)entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID).minDeviation;
  49. }
  50. break;
  51. case TweakableStat.MaxAngle:
  52. if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
  53. {
  54. return (T)(object)entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID).maxDeviation;
  55. }
  56. break;
  57. case TweakableStat.Reverse:
  58. if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
  59. {
  60. return (T)(object)entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID).reverse;
  61. }
  62. else if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
  63. {
  64. return (T)(object)entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID).reverse;
  65. }
  66. break;
  67. case TweakableStat.StartValue:
  68. if (entitiesDB.Exists<SignalGeneratorEntityStruct>(blockID))
  69. {
  70. return (T)(object)entitiesDB.QueryEntity<SignalGeneratorEntityStruct>(blockID).startValue;
  71. }
  72. break;
  73. }
  74. return default(T);
  75. }
  76. public T GetStatAny<T>(uint blockID, TweakableStat stat)
  77. {
  78. return GetStatAny<T>(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat);
  79. }
  80. public dynamic GetStatDynamic(EGID blockID, TweakableStat stat)
  81. {
  82. switch (stat)
  83. {
  84. case TweakableStat.TopSpeed:
  85. if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
  86. {
  87. return entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID).maxVelocity;
  88. }
  89. break;
  90. case TweakableStat.Torque:
  91. if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
  92. {
  93. return entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID).maxForce;
  94. }
  95. break;
  96. case TweakableStat.MaxExtension:
  97. if (entitiesDB.Exists<PistonReadOnlyStruct>(blockID))
  98. {
  99. return entitiesDB.QueryEntity<PistonReadOnlyStruct>(blockID).maxDeviation;
  100. }
  101. break;
  102. case TweakableStat.MinAngle:
  103. if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
  104. {
  105. return entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID).minDeviation;
  106. }
  107. break;
  108. case TweakableStat.MaxAngle:
  109. if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
  110. {
  111. return entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID).maxDeviation;
  112. }
  113. break;
  114. case TweakableStat.Reverse:
  115. if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
  116. {
  117. return entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID).reverse;
  118. }
  119. else if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
  120. {
  121. return entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID).reverse;
  122. }
  123. break;
  124. case TweakableStat.StartValue:
  125. if (entitiesDB.Exists<SignalGeneratorEntityStruct>(blockID))
  126. {
  127. return entitiesDB.QueryEntity<SignalGeneratorEntityStruct>(blockID).startValue;
  128. }
  129. break;
  130. }
  131. return null;
  132. }
  133. public dynamic GetStatDynamic(uint blockID, TweakableStat stat)
  134. {
  135. return GetStatDynamic(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat);
  136. }
  137. public T SetStatAny<T>(EGID blockID, TweakableStat stat, T value)
  138. {
  139. switch (stat)
  140. {
  141. case TweakableStat.TopSpeed:
  142. if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
  143. {
  144. ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
  145. refStruct.maxVelocity = (float)(object)value;
  146. return (T)(object)refStruct.maxVelocity;
  147. }
  148. break;
  149. case TweakableStat.Torque:
  150. if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
  151. {
  152. ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
  153. refStruct.maxForce = (float)(object)value;
  154. return (T)(object)refStruct.maxForce;
  155. }
  156. break;
  157. case TweakableStat.MaxExtension:
  158. if (entitiesDB.Exists<PistonReadOnlyStruct>(blockID))
  159. {
  160. ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<PistonReadOnlyStruct>(blockID);
  161. refStruct.maxDeviation = (float)(object)value;
  162. return (T)(object)refStruct.maxDeviation;
  163. }
  164. break;
  165. case TweakableStat.MinAngle:
  166. if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
  167. {
  168. ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
  169. refStruct.minDeviation = (float)(object)value;
  170. return (T)(object)refStruct.minDeviation;
  171. }
  172. break;
  173. case TweakableStat.MaxAngle:
  174. if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
  175. {
  176. ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
  177. refStruct.maxDeviation = (float)(object)value;
  178. return (T)(object)refStruct.maxDeviation;
  179. }
  180. break;
  181. case TweakableStat.Reverse:
  182. if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
  183. {
  184. ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
  185. refStruct.reverse = (bool)(object)value;
  186. return (T)(object)refStruct.reverse;
  187. }
  188. else if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
  189. {
  190. ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
  191. refStruct.reverse = (bool)(object)value;
  192. return (T)(object)refStruct.reverse;
  193. }
  194. break;
  195. case TweakableStat.StartValue:
  196. if (entitiesDB.Exists<SignalGeneratorEntityStruct>(blockID))
  197. {
  198. ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity<SignalGeneratorEntityStruct>(blockID);
  199. refStruct.startValue = (float)(object)value;
  200. return (T)(object)refStruct.startValue;
  201. }
  202. break;
  203. }
  204. return default(T);
  205. }
  206. public T SetStatAny<T>(uint blockID, TweakableStat stat, T value)
  207. {
  208. return SetStatAny<T>(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value);
  209. }
  210. public dynamic SetStatDynamic(EGID blockID, TweakableStat stat, dynamic value)
  211. {
  212. switch (stat)
  213. {
  214. case TweakableStat.TopSpeed:
  215. if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
  216. {
  217. ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
  218. refStruct.maxVelocity = value;
  219. return refStruct.maxVelocity;
  220. }
  221. break;
  222. case TweakableStat.Torque:
  223. if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
  224. {
  225. ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
  226. refStruct.maxForce = value;
  227. return refStruct.maxForce;
  228. }
  229. break;
  230. case TweakableStat.MaxExtension:
  231. if (entitiesDB.Exists<PistonReadOnlyStruct>(blockID))
  232. {
  233. ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<PistonReadOnlyStruct>(blockID);
  234. refStruct.maxDeviation = value;
  235. return refStruct.maxDeviation;
  236. }
  237. break;
  238. case TweakableStat.MinAngle:
  239. if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
  240. {
  241. ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
  242. refStruct.minDeviation = value;
  243. return refStruct.minDeviation;
  244. }
  245. break;
  246. case TweakableStat.MaxAngle:
  247. if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
  248. {
  249. ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
  250. refStruct.maxDeviation = value;
  251. return refStruct.maxDeviation;
  252. }
  253. break;
  254. case TweakableStat.Reverse:
  255. if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
  256. {
  257. ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
  258. refStruct.reverse = value;
  259. return refStruct.reverse;
  260. }
  261. else if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
  262. {
  263. ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
  264. refStruct.reverse = value;
  265. return refStruct.reverse;
  266. }
  267. break;
  268. case TweakableStat.StartValue:
  269. if (entitiesDB.Exists<SignalGeneratorEntityStruct>(blockID))
  270. {
  271. ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity<SignalGeneratorEntityStruct>(blockID);
  272. refStruct.startValue = value;
  273. return refStruct.startValue;
  274. }
  275. break;
  276. }
  277. return null;
  278. }
  279. public dynamic SetStatDynamic(uint blockID, TweakableStat stat, dynamic value)
  280. {
  281. return SetStatDynamic(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value);
  282. }
  283. public T AddStatAny<T>(EGID blockID, TweakableStat stat, T value)
  284. {
  285. switch (stat)
  286. {
  287. case TweakableStat.TopSpeed:
  288. if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
  289. {
  290. ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
  291. refStruct.maxVelocity += (float)(object)value;
  292. return (T)(object)refStruct.maxVelocity;
  293. }
  294. break;
  295. case TweakableStat.Torque:
  296. if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
  297. {
  298. ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
  299. refStruct.maxForce += (float)(object)value;
  300. return (T)(object)refStruct.maxForce;
  301. }
  302. break;
  303. case TweakableStat.MaxExtension:
  304. if (entitiesDB.Exists<PistonReadOnlyStruct>(blockID))
  305. {
  306. ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<PistonReadOnlyStruct>(blockID);
  307. refStruct.maxDeviation += (float)(object)value;
  308. return (T)(object)refStruct.maxDeviation;
  309. }
  310. break;
  311. case TweakableStat.MinAngle:
  312. if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
  313. {
  314. ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
  315. refStruct.minDeviation += (float)(object)value;
  316. return (T)(object)refStruct.minDeviation;
  317. }
  318. break;
  319. case TweakableStat.MaxAngle:
  320. if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
  321. {
  322. ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
  323. refStruct.maxDeviation += (float)(object)value;
  324. return (T)(object)refStruct.maxDeviation;
  325. }
  326. break;
  327. case TweakableStat.Reverse:
  328. // '+' is associated with logical OR in some fields, so it technically isn't invalid to "add" booleans
  329. if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
  330. {
  331. ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
  332. refStruct.reverse = refStruct.reverse || (bool)(object)value;
  333. return (T)(object)refStruct.reverse;
  334. }
  335. else if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
  336. {
  337. ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
  338. refStruct.reverse = refStruct.reverse || (bool)(object)value;
  339. return (T)(object)refStruct.reverse;
  340. }
  341. break;
  342. case TweakableStat.StartValue:
  343. if (entitiesDB.Exists<SignalGeneratorEntityStruct>(blockID))
  344. {
  345. ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity<SignalGeneratorEntityStruct>(blockID);
  346. refStruct.startValue += (float)(object)value;
  347. return (T)(object)refStruct.startValue;
  348. }
  349. break;
  350. }
  351. return default(T);
  352. }
  353. public T AddStatAny<T>(uint blockID, TweakableStat stat, T value)
  354. {
  355. return AddStatAny<T>(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value);
  356. }
  357. public dynamic AddStatDynamic(EGID blockID, TweakableStat stat, dynamic value)
  358. {
  359. switch (stat)
  360. {
  361. case TweakableStat.TopSpeed:
  362. if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
  363. {
  364. ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
  365. refStruct.maxVelocity += value;
  366. return refStruct.maxVelocity;
  367. }
  368. break;
  369. case TweakableStat.Torque:
  370. if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
  371. {
  372. ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
  373. refStruct.maxForce += value;
  374. return refStruct.maxForce;
  375. }
  376. break;
  377. case TweakableStat.MaxExtension:
  378. if (entitiesDB.Exists<PistonReadOnlyStruct>(blockID))
  379. {
  380. ref PistonReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<PistonReadOnlyStruct>(blockID);
  381. refStruct.maxDeviation += value;
  382. return refStruct.maxDeviation;
  383. }
  384. break;
  385. case TweakableStat.MinAngle:
  386. if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
  387. {
  388. ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
  389. refStruct.minDeviation += value;
  390. return refStruct.minDeviation;
  391. }
  392. break;
  393. case TweakableStat.MaxAngle:
  394. if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
  395. {
  396. ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
  397. refStruct.maxDeviation += value;
  398. return refStruct.maxDeviation;
  399. }
  400. break;
  401. case TweakableStat.Reverse:
  402. // '+' is associated with logical OR in some fields, so it technically isn't invalid to "add" booleans
  403. if (entitiesDB.Exists<MotorReadOnlyStruct>(blockID))
  404. {
  405. ref MotorReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<MotorReadOnlyStruct>(blockID);
  406. refStruct.reverse = refStruct.reverse || value;
  407. return refStruct.reverse;
  408. }
  409. else if (entitiesDB.Exists<ServoReadOnlyStruct>(blockID))
  410. {
  411. ref ServoReadOnlyStruct refStruct = ref entitiesDB.QueryEntity<ServoReadOnlyStruct>(blockID);
  412. refStruct.reverse = refStruct.reverse || value;
  413. return refStruct.reverse;
  414. }
  415. break;
  416. case TweakableStat.StartValue:
  417. if (entitiesDB.Exists<SignalGeneratorEntityStruct>(blockID))
  418. {
  419. ref SignalGeneratorEntityStruct refStruct = ref entitiesDB.QueryEntity<SignalGeneratorEntityStruct>(blockID);
  420. refStruct.startValue += value;
  421. return refStruct.startValue;
  422. }
  423. break;
  424. }
  425. return null;
  426. }
  427. public dynamic AddStatDynamic(uint blockID, TweakableStat stat, dynamic value)
  428. {
  429. return AddStatDynamic(new EGID(blockID, BlockIdentifiers.OWNED_BLOCKS), stat, value);
  430. }
  431. }
  432. }