Browse Source

Fixes, block IDs, cluster & chunk health support

tags/v1.5.0
NorbiPeti NGnius (Graham) <ngniusness@gmail.com> 3 years ago
parent
commit
cfdc5e8c26
7 changed files with 154 additions and 43 deletions
  1. +1
    -1
      GamecraftModdingAPI/Block.cs
  2. +53
    -38
      GamecraftModdingAPI/Blocks/BlockEngine.cs
  3. +5
    -0
      GamecraftModdingAPI/Blocks/BlockIDs.cs
  4. +41
    -0
      GamecraftModdingAPI/Cluster.cs
  5. +37
    -0
      GamecraftModdingAPI/SimBody.cs
  6. +10
    -0
      GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs
  7. +7
    -4
      GamecraftModdingAPI/Utility/DebugInterfaceEngine.cs

+ 1
- 1
GamecraftModdingAPI/Block.cs View File

@@ -372,7 +372,7 @@ namespace GamecraftModdingAPI
public SimBody GetSimBody()
{
return BlockEngine.GetBlockInfo(this,
(GridConnectionsEntityStruct st) => new SimBody(st.machineRigidBodyId));
(GridConnectionsEntityStruct st) => new SimBody(st.machineRigidBodyId, st.clusterId));
}

private void OnPlacedInit(object sender, BlockPlacedRemovedEventArgs e)


+ 53
- 38
GamecraftModdingAPI/Blocks/BlockEngine.cs View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;

using Gamecraft.Wires;
using RobocraftX.Blocks;
@@ -9,6 +10,7 @@ using RobocraftX.Physics;
using RobocraftX.Scene.Simulation;
using Svelto.DataStructures;
using Svelto.ECS;
using Svelto.ECS.Hybrid;

using GamecraftModdingAPI.Engines;

@@ -90,28 +92,19 @@ namespace GamecraftModdingAPI.Blocks
{
if (entitiesDB.Exists<T>(block.Id))
return getter(entitiesDB.QueryEntity<T>(block.Id));
if (block.InitData.Group == null) return def;
var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group);
if (initializer.Has<T>())
return getter(initializer.Get<T>());
return def;
return GetBlockInitInfo(block, getter, def);
}
public U GetBlockInfoViewStruct<T, U>(Block block, Func<T, U> getter,
U def = default) where T : struct, INeedEGID, IEntityComponent
U def = default) where T : struct, IEntityViewComponent
{
if (entitiesDB.Exists<T>(block.Id))
{
// TODO: optimize by using EntitiesDB internal calls instead of iterating over everything
EntityCollection<T> entities = entitiesDB.QueryEntities<T>(block.Id.groupID);
for (int i = 0; i < entities.count; i++)
{
if (entities[i].ID == block.Id)
{
return getter(entities[i]);
}
}
}
return getter(entitiesDB.QueryEntity<T>(block.Id));
return GetBlockInitInfo(block, getter, def);
}

private U GetBlockInitInfo<T, U>(Block block, Func<T, U> getter, U def) where T : struct, IEntityComponent
{
if (block.InitData.Group == null) return def;
var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group);
if (initializer.Has<T>())
@@ -121,35 +114,26 @@ namespace GamecraftModdingAPI.Blocks

public delegate void Setter<T, U>(ref T component, U value) where T : struct, IEntityComponent;

public void SetBlockInfoViewStruct<T, U>(Block block, Setter<T, U> setter, U value) where T : struct, INeedEGID, IEntityComponent
public void SetBlockInfoViewStruct<T, U>(Block block, Setter<T, U> setter, U value) where T : struct, IEntityViewComponent
{
if (entitiesDB.Exists<T>(block.Id))
{
EntityCollection<T> entities = entitiesDB.QueryEntities<T>(block.Id.groupID);
for (int i = 0; i < entities.count; i++)
{
if (entities[i].ID == block.Id)
{
setter(ref entities[i], value);
return;
}
}
}
else if (block.InitData.Group != null)
{
var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group);
T component = initializer.Has<T>() ? initializer.Get<T>() : default;
ref T structRef = ref component;
setter(ref structRef, value);
initializer.Init(structRef);
}
setter(ref entitiesDB.QueryEntity<T>(block.Id), value);
else
SetBlockInitInfo(block, setter, value);
}
public void SetBlockInfo<T, U>(Block block, Setter<T, U> setter, U value) where T : unmanaged, IEntityComponent
{
if (entitiesDB.Exists<T>(block.Id))
setter(ref entitiesDB.QueryEntity<T>(block.Id), value);
else if (block.InitData.Group != null)
else
SetBlockInitInfo(block, setter, value);
}

private void SetBlockInitInfo<T, U>(Block block, Setter<T, U> setter, U value)
where T : struct, IEntityComponent
{
if (block.InitData.Group != null)
{
var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group);
T component = initializer.Has<T>() ? initializer.Get<T>() : default;
@@ -222,6 +206,22 @@ namespace GamecraftModdingAPI.Blocks
return list.ToArray();
}

public SimBody[] GetClusterBodies(uint cid)
{
var groups = entitiesDB.QueryEntities<GridConnectionsEntityStruct>();
var bodies = new HashSet<uint>();
foreach (var (coll, _) in groups)
{
foreach (var conn in coll)
{
if (conn.clusterId == cid)
bodies.Add(conn.machineRigidBodyId);
}
}

return bodies.Select(id => new SimBody(id)).ToArray();
}

public EGID? FindBlockEGID(uint id)
{
var groups = entitiesDB.FindGroups<DBEntityStruct>();
@@ -234,6 +234,21 @@ namespace GamecraftModdingAPI.Blocks
return null;
}

public Cluster GetCluster(uint sbid)
{
var groups = entitiesDB.QueryEntities<GridConnectionsEntityStruct>();
foreach (var (coll, _) in groups)
{
foreach (var conn in coll)
{
if (conn.machineRigidBodyId == sbid)
return new Cluster(conn.clusterId);
}
}

return null;
}

#if DEBUG
public EntitiesDB GetEntitiesDB()
{


+ 5
- 0
GamecraftModdingAPI/Blocks/BlockIDs.cs View File

@@ -192,6 +192,9 @@ namespace GamecraftModdingAPI.Blocks
PlayerFilter,
TeamFilter,
Number2Text, //193
DestructionManager = 260,
ChunkHealthModifier,
ClusterHealthModifier, //262
BeachTree1 = 200,
BeachTree2,
BeachTree3,
@@ -243,6 +246,8 @@ namespace GamecraftModdingAPI.Blocks
AdvancedRotator,
MusicBlock, //256
PlasmaCannonBlock,
QuantumRiflePickup = 300,
QuantumRifleAmmoPickup,
MagmaRockCube=777,
MagmaRockCubeSliced,
MagmaRockSlope,


+ 41
- 0
GamecraftModdingAPI/Cluster.cs View File

@@ -0,0 +1,41 @@
using Gamecraft.Damage;
using RobocraftX.Common;
using Svelto.ECS;

namespace GamecraftModdingAPI
{
/// <summary>
/// Represnts a cluster of blocks in time running mode, meaning blocks that are connected either directly or via joints.
/// </summary>
public class Cluster
{
public EGID Id { get; }

public Cluster(EGID id)
{
Id = id;
}

public Cluster(uint id) : this(new EGID(id, CommonExclusiveGroups.SIMULATION_CLUSTERS_GROUP))
{
}

public float InitialHealth
{
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).initialHealth;
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).initialHealth = value;
}

public float CurrentHealth
{
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).currentHealth;
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).currentHealth = value;
}

public float HealthMultiplier
{
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).healthMultiplier;
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).healthMultiplier = value;
}
}
}

+ 37
- 0
GamecraftModdingAPI/SimBody.cs View File

@@ -3,6 +3,7 @@ using Svelto.ECS;
using Unity.Mathematics;
using UnityEngine;

using Gamecraft.Damage;
using RobocraftX.Common;
using RobocraftX.Physics;

@@ -15,6 +16,14 @@ namespace GamecraftModdingAPI
{
public EGID Id { get; }

/// <summary>
/// The cluster this chunk belongs to, or null if the chunk doesn't exist. Get the SimBody from a Block if possible for good performance here.
/// </summary>
public Cluster Cluster => cluster ?? (cluster = clusterId == uint.MaxValue ? Block.BlockEngine.GetCluster(Id.entityID) : new Cluster(clusterId));

private Cluster cluster;
private uint clusterId;

public SimBody(EGID id)
{
Id = id;
@@ -24,6 +33,11 @@ namespace GamecraftModdingAPI
{
}

internal SimBody(uint id, uint clusterID) : this(id)
{
clusterId = clusterID;
}

/// <summary>
/// The position of this body. When setting the position, update the position of the connected bodies as well,
/// otherwise unexpected forces may arise.
@@ -70,6 +84,29 @@ namespace GamecraftModdingAPI
//set => GetStruct().physicsMass.CenterOfMass = value;
}

public float Volume
{
get => GetStruct().volume;
}

public float InitialHealth
{
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).initialHealth;
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).initialHealth = value;
}

public float CurrentHealth
{
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).currentHealth;
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).currentHealth = value;
}

public float HealthMultiplier
{
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).healthMultiplier;
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).healthMultiplier = value;
}

/// <summary>
/// Whether the body can be moved or static.
/// </summary>


+ 10
- 0
GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs View File

@@ -268,6 +268,16 @@ namespace GamecraftModdingAPI.Tests
})
.Build();

CommandBuilder.Builder("TestChunkHealth", "Sets the chunk looked at to the given health.")
.Action((float val, float max) =>
{
var body = new Player(PlayerType.Local).GetSimBodyLookedAt();
if (body == null) return;
body.CurrentHealth = val;
body.InitialHealth = max;
Logging.CommandLog("Health set to: " + val);
}).Build();

GameClient.SetDebugInfo("InstalledMods", InstalledMods);
Block.Placed += (sender, args) =>
Logging.MetaDebugLog("Placed block " + args.Type + " with ID " + args.ID);


+ 7
- 4
GamecraftModdingAPI/Utility/DebugInterfaceEngine.cs View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Text.Formatting;
using GamecraftModdingAPI.Blocks;
using GamecraftModdingAPI.Engines;
@@ -46,9 +47,9 @@ namespace GamecraftModdingAPI.Utility
var array = new CodeInstruction[]
{
new CodeInstruction(OpCodes.Ldloc_0), //StringBuffer
new CodeInstruction(OpCodes.Call, ((Action<StringBuffer>)AddInfo).Method)
new CodeInstruction(OpCodes.Call, ((Action<StringBuilder>)AddInfo).Method)
};
list.InsertRange(index, array);
list.InsertRange(index - 1, array); //-1: ldloc.1 ("local") before ldfld
}
catch (Exception e)
{
@@ -58,13 +59,15 @@ namespace GamecraftModdingAPI.Utility
return list;
}

public static void AddInfo(StringBuffer sb)
public static void AddInfo(StringBuilder sb)
{
foreach (var info in _extraInfo)
{
try
{
sb.Append(info.Value() + "\n");
string text = info.Value().Trim();
if (text.Length != 0)
sb.Append(text + "\n");
}
catch (Exception e)
{


Loading…
Cancel
Save