191 lines
7.1 KiB
C#
191 lines
7.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
using RobocraftX;
|
|
using RobocraftX.Blocks;
|
|
using RobocraftX.Blocks.Ghost;
|
|
using RobocraftX.Common;
|
|
using RobocraftX.Multiplayer;
|
|
using RobocraftX.SimulationModeState;
|
|
using RobocraftX.UECS;
|
|
using Unity.Entities;
|
|
using Svelto.Context;
|
|
using Svelto.ECS;
|
|
using Svelto.ECS.EntityStructs;
|
|
using Unity.Transforms;
|
|
using Unity.Mathematics;
|
|
using UnityEngine;
|
|
|
|
using GamecraftModdingAPI.Utility;
|
|
|
|
namespace GamecraftModdingAPI.Blocks
|
|
{
|
|
/// <summary>
|
|
/// Engine which executes signal actions
|
|
/// </summary>
|
|
public class SignalEngine : IApiEngine
|
|
{
|
|
public string Name { get; } = "GamecraftModdingAPISignalGameEngine";
|
|
|
|
public IEntitiesDB entitiesDB { set; private get; }
|
|
|
|
public bool IsInGame = false;
|
|
|
|
private Stack<uint> cubesStack = new Stack<uint>();
|
|
private bool stackInUse = false;
|
|
|
|
private Gamecraft.DataStructures.FasterList<uint> cubesList = new Gamecraft.DataStructures.FasterList<uint>();
|
|
private bool listInUse = false;
|
|
|
|
public void Dispose()
|
|
{
|
|
IsInGame = false;
|
|
}
|
|
|
|
public void Ready()
|
|
{
|
|
IsInGame = true;
|
|
}
|
|
|
|
// implementations for Signal static class
|
|
|
|
public bool SetSignal(uint blockID, uint channel, float signal, out EGID clusterID)
|
|
{
|
|
clusterID = GetClusterEGID(blockID, channel);
|
|
return SetSignal(clusterID, signal);
|
|
}
|
|
|
|
public bool SetSignal(EGID clusterID, float signal)
|
|
{
|
|
if (entitiesDB.Exists<ChannelOutputSignalDataStruct>(clusterID))
|
|
{
|
|
entitiesDB.QueryEntity<ChannelOutputSignalDataStruct>(clusterID).outputSignal = signal;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public float AddSignal(uint blockID, uint channel, float signal, out EGID clusterID, bool clamp = true)
|
|
{
|
|
clusterID = GetClusterEGID(blockID, channel);
|
|
return AddSignal(clusterID, signal, clamp);
|
|
}
|
|
|
|
public float AddSignal(EGID clusterID, float signal, bool clamp=true)
|
|
{
|
|
if (entitiesDB.Exists<ChannelOutputSignalDataStruct>(clusterID))
|
|
{
|
|
ref ChannelOutputSignalDataStruct chanOutSig = ref entitiesDB.QueryEntity<ChannelOutputSignalDataStruct>(clusterID);
|
|
chanOutSig.outputSignal += signal;
|
|
if (clamp)
|
|
{
|
|
if (chanOutSig.outputSignal > Signals.POSITIVE_HIGH)
|
|
{
|
|
chanOutSig.outputSignal = Signals.POSITIVE_HIGH;
|
|
}
|
|
else if (chanOutSig.outputSignal < Signals.NEGATIVE_HIGH)
|
|
{
|
|
chanOutSig.outputSignal = Signals.NEGATIVE_HIGH;
|
|
}
|
|
return chanOutSig.outputSignal;
|
|
}
|
|
}
|
|
return signal;
|
|
}
|
|
|
|
public float GetSignal(uint blockID, uint channel, out EGID clusterID)
|
|
{
|
|
clusterID = GetClusterEGID(blockID, channel);
|
|
return GetSignal(clusterID);
|
|
}
|
|
|
|
public float GetSignal(EGID clusterID)
|
|
{
|
|
if (entitiesDB.Exists<ChannelOutputSignalDataStruct>(clusterID))
|
|
{
|
|
return entitiesDB.QueryEntity<ChannelOutputSignalDataStruct>(clusterID).outputSignal;
|
|
}
|
|
return 0f;
|
|
}
|
|
|
|
public EGID GetClusterEGID(uint blockID, uint channel)
|
|
{
|
|
//uint[] connectedCubeIDs = GetConductivelyConnectedBlocks(blockID);
|
|
//uint index;
|
|
//ElectricityEntityStruct[] structs;
|
|
EGID elecEGID = new EGID(blockID, CommonExclusiveGroups.OWNED_BLOCKS_GROUP);
|
|
if (!entitiesDB.Exists<ElectricityEntityStruct>(elecEGID))
|
|
{
|
|
elecEGID = new EGID(blockID, CommonExclusiveGroups.FUNCTIONAL_BLOCK_PART_GROUP);
|
|
}
|
|
if (!entitiesDB.Exists<ElectricityEntityStruct>(elecEGID))
|
|
{
|
|
return default;
|
|
}
|
|
ref ElectricityEntityStruct eStruct = ref entitiesDB.QueryEntity<ElectricityEntityStruct>(elecEGID);
|
|
ref ConductiveClusterID clusterId = ref entitiesDB.QueryEntity<ConductiveClusterIdStruct>(eStruct.ID).clusterId;
|
|
uint operatingChannel = entitiesDB.QueryEntity<SignalOperatingChannelStruct>(eStruct.ID).operatingChannel;
|
|
EGID eGID = new EGID(channel, BlockIdentifiers.OUTPUT_SIGNAL_CHANNELS + clusterId.ID);
|
|
if (clusterId.initialized && clusterId.isConductive && entitiesDB.Exists<ChannelOutputSignalDataStruct>(eGID))
|
|
{
|
|
return eGID;
|
|
}
|
|
return default;
|
|
}
|
|
|
|
public uint[] GetElectricBlocks()
|
|
{
|
|
uint count = entitiesDB.Count<ElectricityEntityStruct>(CommonExclusiveGroups.FUNCTIONAL_CUBES_IN_BOTH_SIM_AND_BUILD[0])
|
|
+ entitiesDB.Count<ElectricityEntityStruct>(CommonExclusiveGroups.FUNCTIONAL_CUBES_IN_BOTH_SIM_AND_BUILD[1]);
|
|
uint i = 0;
|
|
uint[] res = new uint[count];
|
|
foreach (ref var ees in entitiesDB.QueryEntities<ElectricityEntityStruct>(CommonExclusiveGroups.FUNCTIONAL_CUBES_IN_BOTH_SIM_AND_BUILD))
|
|
{
|
|
res[i] = ees.ID.entityID;
|
|
i++;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
private uint[] GetConductivelyConnectedBlocks(uint blockID)
|
|
{
|
|
if (!(stackInUse || listInUse))
|
|
{
|
|
stackInUse = true;
|
|
listInUse = true;
|
|
cubesStack.Clear();
|
|
cubesList.FastClear();
|
|
ConnectedCubesUtility.TreeTraversal.GetConnectedCubes(entitiesDB, blockID, cubesStack, cubesList, (in GridConnectionsEntityStruct g) => { return g.isIsolator; });
|
|
uint[] res = cubesList.ToArray();
|
|
stackInUse = false;
|
|
listInUse = false;
|
|
foreach (var id in res)
|
|
{
|
|
entitiesDB.QueryEntity<GridConnectionsEntityStruct>(id, CommonExclusiveGroups.OWNED_BLOCKS_GROUP).isProcessed = false;
|
|
}
|
|
return res;
|
|
}
|
|
else
|
|
{
|
|
Stack<uint> cubeStack = new Stack<uint>();
|
|
Gamecraft.DataStructures.FasterList<uint> cubeList = new Gamecraft.DataStructures.FasterList<uint>();
|
|
ConnectedCubesUtility.TreeTraversal.GetConnectedCubes(entitiesDB, blockID, cubesStack, cubesList, (in GridConnectionsEntityStruct g) => { return g.isIsolator; });
|
|
uint[] res = cubesList.ToArray();
|
|
foreach (var id in res)
|
|
{
|
|
entitiesDB.QueryEntity<GridConnectionsEntityStruct>(id, CommonExclusiveGroups.OWNED_BLOCKS_GROUP).isProcessed = false;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
}
|
|
|
|
public bool IsSimulationMode()
|
|
{
|
|
return GamecraftModdingAPI.Utility.GameState.IsSimulationMode();
|
|
}
|
|
}
|
|
}
|