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.DataStructures; using Svelto.ECS; using Svelto.ECS.EntityStructs; using Unity.Transforms; using Unity.Mathematics; using UnityEngine; using Gamecraft.Wires; using GamecraftModdingAPI.Utility; namespace GamecraftModdingAPI.Blocks { /// /// Engine which executes signal actions /// public class SignalEngine : IApiEngine { public string Name { get; } = "GamecraftModdingAPISignalGameEngine"; public IEntitiesDB entitiesDB { set; private get; } public bool IsInGame = false; private System.Random random = new System.Random(); public void Dispose() { IsInGame = false; } public void Ready() { IsInGame = true; } public void DoTheThing() { GamecraftModdingAPI.Tasks.Repeatable thing = new GamecraftModdingAPI.Tasks.Repeatable( () => { Thing(); }, () => { return IsSimulationMode(); } ); GamecraftModdingAPI.Tasks.Scheduler.Schedule(thing); } public void Thing() { uint count = 0; EGID[] eBlocks = GetElectricBlocks(); for (uint i = 0u; i < eBlocks.Length; i++) { uint[] ids = GetSignalIDs(eBlocks[i]); for (uint j = 0u; j < ids.Length; j++) { SetSignal(ids[j], (float)random.NextDouble()); count++; } } Logging.Log($"Did the thing on {count} inputs"); } // implementations for Signal static class public bool SetSignal(EGID blockID, float signal, out uint signalID, bool input = true) { signalID = GetSignalIDs(blockID, input)[0]; return SetSignal(signalID, signal); } public bool SetSignal(uint signalID, float signal, bool input = true) { ExclusiveGroup group = input ? NamedExclusiveGroup.Group : NamedExclusiveGroup.Group; if (entitiesDB.Exists(signalID, group)) { entitiesDB.QueryEntity(signalID, group).value = signal; return true; } return false; } public float AddSignal(EGID blockID, float signal, out uint signalID, bool clamp = true, bool input = true) { signalID = GetSignalIDs(blockID, input)[0]; return AddSignal(signalID, signal, clamp, input); } public float AddSignal(uint signalID, float signal, bool clamp = true, bool input = true) { ExclusiveGroup group = input ? NamedExclusiveGroup.Group : NamedExclusiveGroup.Group; if (entitiesDB.Exists(signalID, group)) { ref PortEntityStruct pes = ref entitiesDB.QueryEntity(signalID, group); pes.value += signal; if (clamp) { if (pes.value > Signals.POSITIVE_HIGH) { pes.value = Signals.POSITIVE_HIGH; } else if (pes.value < Signals.NEGATIVE_HIGH) { pes.value = Signals.NEGATIVE_HIGH; } return pes.value; } } return signal; } public float GetSignal(EGID blockID, out uint signalID, bool input = true) { signalID = GetSignalIDs(blockID, input)[0]; return GetSignal(signalID, input); } public float GetSignal(uint signalID, bool input = true) { ExclusiveGroup group = input ? NamedExclusiveGroup.Group : NamedExclusiveGroup.Group; if (entitiesDB.Exists(signalID, group)) { return entitiesDB.QueryEntity(signalID, group).value; } return 0f; } public uint[] GetSignalIDs(EGID blockID, bool input = true) { ref BlockPortsStruct bps = ref entitiesDB.QueryEntity(blockID); uint[] signals; if (input) { signals = new uint[bps.inputCount]; for (uint i = 0u; i < bps.inputCount; i++) { signals[i] = bps.firstInputID + i; } } else { signals = new uint[bps.outputCount]; for (uint i = 0u; i < bps.outputCount; i++) { signals[i] = bps.firstOutputID + i; } } return signals; } public EGID[] GetElectricBlocks() { uint count = entitiesDB.Count(BlockIdentifiers.OWNED_BLOCKS) + entitiesDB.Count(BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS); uint i = 0; EGID[] res = new EGID[count]; foreach (ref BlockPortsStruct s in entitiesDB.QueryEntities(BlockIdentifiers.OWNED_BLOCKS)) { res[i] = s.ID; i++; } foreach (ref BlockPortsStruct s in entitiesDB.QueryEntities(BlockIdentifiers.FUNCTIONAL_BLOCK_PARTS)) { res[i] = s.ID; i++; } return res; } public bool IsSimulationMode() { return GamecraftModdingAPI.Utility.GameState.IsSimulationMode(); } } }