|
- 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 block movement 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();
- }
- }
- }
|