Tools for building games mainly focused on changing block properties. And noclip.
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.

BlockMod.cs 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. using System;
  2. using System.Linq;
  3. using GamecraftModdingAPI;
  4. using GamecraftModdingAPI.Commands;
  5. using GamecraftModdingAPI.Engines;
  6. using GamecraftModdingAPI.Players;
  7. using GamecraftModdingAPI.Utility;
  8. using HarmonyLib;
  9. using IllusionPlugin;
  10. using RobocraftX.Character.Weapons;
  11. using RobocraftX.Common.Players;
  12. using Svelto.ECS;
  13. using Svelto.ECS.Internal;
  14. using Unity.Mathematics;
  15. namespace BlockMod
  16. {
  17. public class BlockMod : IPlugin
  18. {
  19. public void OnApplicationStart()
  20. {
  21. Main.Init();
  22. GameClient.SetDebugInfo("BlockModInfo", GetBlockInfo);
  23. Block[] blocks = new Block[0];
  24. CommandBuilder.Builder("scaleBlocksRelative",
  25. "Scales the blocks you're looking at, relative to current size (current scale * new scale)." +
  26. " The block you're looking at stays where it is, everything else is moved next to it." +
  27. " The command remembers the cluster of blocks, use forgetBlocks to forget it.")
  28. .Action<float, float, float>((scaleX, scaleY, scaleZ) =>
  29. {
  30. var bl = new Player(PlayerType.Local).GetBlockLookedAt();
  31. var cubes = GetCubes(ref blocks, bl);
  32. if (cubes == null) return;
  33. float3 reference = bl.Position;
  34. float3 scale = new float3(scaleX, scaleY, scaleZ);
  35. foreach (var block in cubes)
  36. {
  37. block.Scale *= scale;
  38. block.Position = reference + (block.Position - reference) * scale;
  39. }
  40. Logging.CommandLog("Blocks scaled.");
  41. }).Build();
  42. CommandBuilder.Builder("scaleIndividually", "Scales the blocks you're looking at, but doesn't move them." +
  43. "The scale is relative, 1 means no change. Look at a block previously scaled to scale all of the blocks that were connected to it.")
  44. .Action<float, float, float>((scaleX, scaleY, scaleZ) =>
  45. {
  46. var cubes = GetCubesLookedAt(ref blocks);
  47. if (cubes == null) return;
  48. float3 scale = new float3(scaleX, scaleY, scaleZ);
  49. foreach (var block in cubes)
  50. block.Scale *= scale;
  51. }).Build();
  52. CommandBuilder.Builder("moveBlocks", "Moves the blocks around.")
  53. .Action<float, float, float>((x, y, z) =>
  54. {
  55. var cubes = GetCubesLookedAt(ref blocks);
  56. if (cubes == null) return;
  57. foreach (var block in cubes)
  58. block.Position += new float3(x, y, z);
  59. }).Build();
  60. CommandBuilder.Builder("forgetBlocks", "Forgets the cluster of blocks that we're changing.")
  61. .Action(() => blocks = new Block[0]).Build();
  62. GameEngineManager.AddGameEngine(new Test());
  63. }
  64. private class Test : IApiEngine
  65. {
  66. public void Ready()
  67. {
  68. try
  69. {
  70. CommandBuilder.Builder("weaponTest").Action(() =>
  71. {
  72. var type = AccessTools.TypeByName("RobocraftX.Character.Weapons.CharacterEquippedWeaponStruct");
  73. var dict = QueryEntitiesAndIndexInternal(
  74. new EGID(new Player(PlayerType.Local).Id, PlayersExclusiveGroups.LocalPlayers),
  75. out uint i, type);
  76. var dtype = typeof(ITypeSafeDictionary<>).MakeGenericType(type);
  77. var obj = Convert.ChangeType(dict, dtype);
  78. Array arr = (Array) AccessTools.PropertyGetter(dtype, "unsafeValues")
  79. .Invoke(obj, new object[0]);
  80. foreach (var element in arr)
  81. element.GetType().GetField("equippedWeaponType")
  82. .SetValue(element, WeaponType.PISTOL);
  83. }).Build();
  84. }
  85. catch
  86. {
  87. // ignored
  88. }
  89. }
  90. private ITypeSafeDictionary QueryEntitiesAndIndexInternal(EGID entityGID, out uint index, Type type)
  91. {
  92. index = 0U;
  93. ITypeSafeDictionary typeSafeDictionary;
  94. if (!QueryEntityDictionary(entityGID.groupID, out typeSafeDictionary, type))
  95. return null;
  96. return !typeSafeDictionary.TryFindIndex(entityGID.entityID, out index) ? null : typeSafeDictionary;
  97. }
  98. private bool QueryEntityDictionary(
  99. uint group,
  100. out ITypeSafeDictionary typeSafeDictionary,
  101. Type type)
  102. {
  103. object[] ps = {group, type, null};
  104. bool ret = (bool) AccessTools.Method("Svelto.ECS.EntitiesDB:UnsafeQueryEntityDictionary")
  105. .Invoke(entitiesDB, ps);
  106. typeSafeDictionary = (ITypeSafeDictionary) ps[2];
  107. return ret;
  108. }
  109. public EntitiesDB entitiesDB { get; set; }
  110. public void Dispose()
  111. {
  112. }
  113. public string Name { get; } = "TestEngine";
  114. public bool isRemovable { get; } = true;
  115. }
  116. private string GetBlockInfo()
  117. {
  118. if (GameState.IsBuildMode())
  119. {
  120. var block = new Player(PlayerType.Local).GetBlockLookedAt();
  121. float3 pos = block.Position;
  122. float3 rot = block.Rotation;
  123. float3 scale = block.Scale;
  124. return $"Block: {block.Type} at {pos.x:F} {pos.y:F} {pos.z:F}\n" +
  125. $"- Rotation: {rot.x:F}° {rot.y:F}° {rot.z:F}°\n" +
  126. $"- Color: {block.Color.Color} darkness: {block.Color.Darkness}\n" +
  127. $"- Scale: {scale.x:F} {scale.y:F} {scale.z:F}\n" +
  128. $"- Label: {block.Label}";
  129. }
  130. if (GameState.IsSimulationMode())
  131. {
  132. var body = new Player(PlayerType.Local).GetSimBodyLookedAt();
  133. float3 pos = body.Position;
  134. float3 rot = body.Rotation;
  135. float3 vel = body.Velocity;
  136. float3 ave = body.AngularVelocity;
  137. float3 com = body.CenterOfMass;
  138. return $"Body at {pos.x:F} {pos.y:F} {pos.z:F}\n" +
  139. $"- Rotation: {rot.x:F}° {rot.y:F}° {rot.z:F}°\n" +
  140. $"- Velocity: {vel.x:F} {vel.y:F} {vel.z:F}\n" +
  141. $"- Angular velocity: {ave.x:F} {ave.y:F} {ave.z:F}\n" +
  142. $"- {(body.Static ? "Static body" : $"Mass: {body.Mass:F} center: {com.x:F} {com.y:F} {com.z:F}")}";
  143. }
  144. return "Switching modes...";
  145. }
  146. private bool SameCluster(Block[] bs, Block block)
  147. {
  148. var id = block.Id;
  149. return bs.Any(b => b.Id == id);
  150. }
  151. private Block[] GetCubes(ref Block[] bs, Block block) =>
  152. SameCluster(bs, block) ? bs : bs = block.GetConnectedCubes();
  153. private Block[] GetCubesLookedAt(ref Block[] bs)
  154. {
  155. var bl = new Player(PlayerType.Local).GetBlockLookedAt();
  156. if (bl == null) return null;
  157. var cubes = GetCubes(ref bs, bl);
  158. return cubes;
  159. }
  160. public void OnApplicationQuit()
  161. {
  162. }
  163. public void OnLevelWasLoaded(int level)
  164. {
  165. }
  166. public void OnLevelWasInitialized(int level)
  167. {
  168. }
  169. public void OnUpdate()
  170. {
  171. }
  172. public void OnFixedUpdate()
  173. {
  174. }
  175. public string Name { get; } = "BlockMod";
  176. public string Version { get; } = "v1.0.0";
  177. }
  178. }