Иконка ресурса

FREE JData : 0.1.0 0.1.0

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
// Requires: Picasso
#define DEBUG
#define DISABLED_DEBUG_PINS
using System.Collections.Generic;
using System;
using System.Drawing;
using System.IO;
using Facepunch;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Oxide.Game.Rust.Libraries.Covalence;
using UnityEngine;
namespace Oxide.Plugins {
    [Info("JData", "JohnWillikers", "0.1.0")]
    [Description("Data Stuff")]
    class JData : CovalencePlugin {
        // Begin Plugin References
        [PluginReference]
        private Picasso Picasso;
        // End Plugin References
        private DataFileSystem data_dir = new DataFileSystem($"{Interface.Oxide.DataDirectory}");
        private Dictionary<string, Project> user_loaded_projects = new Dictionary<string, Project>();
        public void SetNewDataDir(string name) {
            user_loaded_projects.Clear();
            data_dir = new DataFileSystem($"{Interface.Oxide.DataDirectory}\\{name}");
        }
        [HookMethod("BuildChip")]
        public void BuildChip(string chip_name, IPlayer player) {
            Project loaded_project = GetUserProject(player.Id);
            if (loaded_project == null) {
                player.Reply($"No project loaded | /c_load <project_name>");
                return;
            }
            Chip chip = loaded_project.ReadChip(chip_name);
            if (chip == null) return;
            player.Reply($"Spawning {chip.Name}");
            GenericPosition position = player.Position();
            chip.Init(0);
            var buildObjectStuff = chip.Build(player, this, loaded_project, new Vector3(position.X, position.Y, position.Z - 3), new Quaternion(0, 0, 0, 0));
            //new Quaternion(1, 1, 0, 0));
            player.Reply($"Built {buildObjectStuff[2]} electrical entities");
        }
        [Command("c_clear")]
        private void ProjectClearCommand(IPlayer player, string command, string[] args) {
            ClearEntities(player);
        }
        public void ClearEntities(IPlayer player) {
            player.Reply("Clearing");
            Project project = GetUserProject(player.Id.ToString());
            project.ClearCommonEntities();
            player.Reply("Done Clearing");
        }
        public Project AssignProjectToUser(string uId, string project_name) {
            Project loaded_project = ReadProject(project_name);
            if (loaded_project == null) return null;
            if (user_loaded_projects.ContainsKey(uId)) user_loaded_projects[uId] = loaded_project;
            else user_loaded_projects.Add(uId, loaded_project);
            return loaded_project;
        }
        public bool UnloadUserProject(string uId) {
            if (user_loaded_projects.ContainsKey(uId)) {
                user_loaded_projects.Remove(uId);
                Puts($"Unloaded {uId}'s project");
                return true;
            }
            else {
                return false;
            }
        }
        public Project GetUserProject(string uId) {
            return (user_loaded_projects.ContainsKey(uId)) ? user_loaded_projects[uId] : null;
        }
        public void BindSaveSign(Vector3 position, Quaternion rotation, Picasso.Signs sign_type, int width, int height, int yOffset, Picasso.FontSize fontSize, Dictionary<string, Brush> lines, System.Drawing.Color backgroundColor = default(System.Drawing.Color)) {
            Picasso.SpawnSign(position, rotation, sign_type, width, height, yOffset, fontSize, lines, backgroundColor );
        }
        private Project ReadProject(string name) {
            if (data_dir.ExistsDatafile($"{name}/ProjectSettings")) {
                Project project = data_dir.ReadObject<Project>($"{name}/ProjectSettings");
                project.dataFileSystem = new DataFileSystem($"{Interface.Oxide.DataDirectory}\\rust_circuit_boss\\{name}");
                return project;
            }
            else return null;
        }
    }
    // BEGIN DATATYPES FOR DE-SERIALIZATION
    enum Gates {
        SPLITTER = 0, BLOCKER = 1, MEMORY_CELL = 2, E_BRANCH = 3, AND = 4, OR = 5, XOR = 6, TEST_GENERATOR = 7, SIMPLE_SWITCH = 8, SMART_SWITCH = 9, GREEN_LIGHT = 10, RED_LIGHT = 11, WHITE_LIGHT = 12, NOT = 13, TIMER = 14
    }
    class RustComponentDefinition {
        public byte slotNumber;
        public Vector3 offset;
    }
    class ParentHelpers {
        // Prefabs
        public Dictionary<Gates, string> prefab_gate_bindings = new Dictionary<Gates, string> {
            {
                Gates.SPLITTER, "assets/prefabs/deployable/playerioents/splitter/splitter.prefab"
            }
            , {
                Gates.BLOCKER, "assets/prefabs/deployable/playerioents/gates/blocker/electrical.blocker.deployed.prefab"
            }
            , {
                Gates.MEMORY_CELL, "assets/prefabs/deployable/playerioents/gates/dflipflop/electrical.memorycell.deployed.prefab"
            }
            , {
                Gates.E_BRANCH, "assets/prefabs/deployable/playerioents/gates/branch/electrical.branch.deployed.prefab"
            }
            , {
                Gates.AND, "assets/prefabs/deployable/playerioents/gates/andswitch/andswitch.entity.prefab"
            }
            , {
                Gates.OR, "assets/prefabs/deployable/playerioents/gates/orswitch/orswitch.entity.prefab"
            }
            , {
                Gates.XOR, "assets/prefabs/deployable/playerioents/gates/xorswitch/xorswitch.entity.prefab"
            }
            , {
                Gates.TEST_GENERATOR, "assets/prefabs/deployable/playerioents/generators/generator.small.prefab"
            }
            , {
                Gates.SIMPLE_SWITCH, "assets/prefabs/deployable/playerioents/simpleswitch/switch.prefab"
            }
            , {
                Gates.SMART_SWITCH, "assets/prefabs/deployable/playerioents/app/smartswitch/smartswitch.prefab"
            }
            , {
                Gates.GREEN_LIGHT, "assets/prefabs/misc/permstore/industriallight/industrial.wall.lamp.green.deployed.prefab"
            }
            , {
                Gates.RED_LIGHT, "assets/prefabs/misc/permstore/industriallight/industrial.wall.lamp.red.deployed.prefab"
            }
            , {
                Gates.WHITE_LIGHT, "assets/prefabs/misc/permstore/industriallight/industrial.wall.lamp.deployed.prefab"
            }
            , {
                Gates.NOT, "na"
            }
            , {
                Gates.TIMER, "assets/prefabs/deployable/playerioents/timers/timer.prefab"
            }
        }
        ;
        // Strings
        public Dictionary<string, Gates> string_to_gates = new Dictionary<string, Gates> {
            {
                "SPLITTER", Gates.SPLITTER
            }
            , {
                "BLOCKER", Gates.BLOCKER
            }
            , {
                "MEMORY_CELL", Gates.MEMORY_CELL
            }
            , {
                "E_BRANCH", Gates.E_BRANCH
            }
            , {
                "AND", Gates.AND
            }
            , {
                "OR", Gates.OR
            }
            , {
                "XOR", Gates.XOR
            }
            , {
                "TEST_GENERATOR", Gates.TEST_GENERATOR
            }
            , {
                "SWITCH", Gates.SIMPLE_SWITCH
            }
            , {
                "SMART_SWITCH", Gates.SMART_SWITCH
            }
            , {
                "G_LIGHT", Gates.GREEN_LIGHT
            }
            , {
                "R_LIGHT", Gates.RED_LIGHT
            }
            , {
                "W_LIGHT", Gates.WHITE_LIGHT
            }
            , {
                "NOT", Gates.NOT
            }
            , {
                "TIMER", Gates.TIMER
            }
        }
        ;
        // IO Definitions
        public Dictionary<Gates, Dictionary<string, RustComponentDefinition>> io_definitions = new Dictionary<Gates, Dictionary<string, RustComponentDefinition>> {
            {
                Gates.TEST_GENERATOR, new Dictionary<string, RustComponentDefinition> {
                    {
                        "Power Output 1", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(0f, -.77f, 0f)
                        }
                    }
                    , {
                        "Power Output 2", new RustComponentDefinition {
                            slotNumber = 1, offset = new Vector3(0f, -.77f, -.42f)
                        }
                    }
                    , {
                        "Power Output 3", new RustComponentDefinition {
                            slotNumber = 2, offset = new Vector3(0f, -.77f, .42f)
                        }
                    }
                }
            }
            , {
                Gates.NOT, new Dictionary<string, RustComponentDefinition> {
                    {
                        "Input A", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(.03f, -.8f, 0f)
                        }
                    }
                    , {
                        "Power Out", new RustComponentDefinition {
                            slotNumber = 1, offset = new Vector3(0f, -1.28f, 0f)
                        }
                    }
                }
            }
            , {
                Gates.AND, new Dictionary<string, RustComponentDefinition> {
                    {
                        "Input A", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(.03f, -.8f, 0f)
                        }
                    }
                    , {
                        "Input B", new RustComponentDefinition {
                            slotNumber = 1, offset = new Vector3(-.03f, -.8f, 0f)
                        }
                    }
                    , {
                        "Power Out", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(0f, -1.28f, 0f)
                        }
                    }
                }
            }
            , {
                Gates.XOR, new Dictionary<string, RustComponentDefinition> {
                    {
                        "Input A", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(.03f, -.8f, 0f)
                        }
                    }
                    , {
                        "Input B", new RustComponentDefinition {
                            slotNumber = 1, offset = new Vector3(-.03f, -.8f, 0f)
                        }
                    }
                    , {
                        "Power Out", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(0f, -1.28f, 0f)
                        }
                    }
                }
            }
            , {
                Gates.OR, new Dictionary<string, RustComponentDefinition> {
                    {
                        "Input A", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(.03f, -.8f, 0f)
                        }
                    }
                    , {
                        "Input B", new RustComponentDefinition {
                            slotNumber = 1, offset = new Vector3(-.03f, -.8f, 0f)
                        }
                    }
                    , {
                        "Power Out", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(0f, -1.28f, 0f)
                        }
                    }
                }
            }
            , {
                Gates.MEMORY_CELL, new Dictionary<string, RustComponentDefinition> {
                    {
                        "Power In", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(0f, .15f, 0f)
                        }
                    }
                    , {
                        "SET", new RustComponentDefinition {
                            slotNumber = 1, offset = new Vector3(.08f, -.06f, 0f)
                        }
                    }
                    , {
                        "RESET", new RustComponentDefinition {
                            slotNumber = 2, offset = new Vector3(.08f, .02f, 0f)
                        }
                    }
                    , {
                        "TOGGLE", new RustComponentDefinition {
                            slotNumber = 3, offset = new Vector3(.08f, .08f, 0f)
                        }
                    }
                    , {
                        "Out", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(.04f, -.144f, 0f)
                        }
                    }
                    , {
                        "Inverted_Out", new RustComponentDefinition {
                            slotNumber = 1, offset = new Vector3(-.04f, -.144f, 0f)
                        }
                    }
                }
            }
            , {
                Gates.BLOCKER, new Dictionary<string, RustComponentDefinition> {
                    {
                        "Power In", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(0f, .15f, 0f)
                        }
                    }
                    , {
                        "Block Pass", new RustComponentDefinition {
                            slotNumber = 1, offset = new Vector3(-.05f, 0f, 0f)
                        }
                    }
                    , {
                        "Power Out", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(0f, -.15f, 0f)
                        }
                    }
                }
            }
            , {
                Gates.SPLITTER, new Dictionary<string, RustComponentDefinition> {
                    {
                        "Power In", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(0f, -1.4f, 0f)
                        }
                    }
                    , {
                        "Power Out 1", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(-.13f, -.82f, 0f)
                        }
                    }
                    , {
                        "Power Out 2", new RustComponentDefinition {
                            slotNumber = 1, offset = new Vector3(0f, -.82f, 0f)
                        }
                    }
                    , {
                        "Power Out 3", new RustComponentDefinition {
                            slotNumber = 2, offset = new Vector3(.13f, -.82f, 0f)
                        }
                    }
                }
            }
            , {
                Gates.E_BRANCH, new Dictionary<string, RustComponentDefinition> {
                    {
                        "Power Out", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(.05f, -.15f, 0f)
                        }
                    }
                    , {
                        "Branch Out", new RustComponentDefinition {
                            slotNumber = 1, offset = new Vector3(-.05f, -.15f, 0f)
                        }
                    }
                    , {
                        "Power In", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(0f, .15f, 0f)
                        }
                    }
                }
            }
            , {
                Gates.SIMPLE_SWITCH, new Dictionary<string, RustComponentDefinition> {
                    {
                        "Electric Input", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(0f, -.8f, 0f)
                        }
                    }
                    , {
                        "Output", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(0f, -1.18f, 0f)
                        }
                    }
                }
            }
            , {
                Gates.SMART_SWITCH, new Dictionary<string, RustComponentDefinition> {
                    {
                        "Electric Input", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(0f, -.8f, 0f)
                        }
                    }
                    , {
                        "Output", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(0f, -1.18f, 0f)
                        }
                    }
                }
            }
            , {
                Gates.GREEN_LIGHT, new Dictionary<string, RustComponentDefinition> {
                    {
                        "Power In", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(.2f, 0, 0)
                        }
                    }
                    , {
                        "Passthrough", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(-.2f, 0, 0)
                        }
                    }
                }
            }
            , {
                Gates.RED_LIGHT, new Dictionary<string, RustComponentDefinition> {
                    {
                        "Power In", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(.2f, 0, 0)
                        }
                    }
                    , {
                        "Passthrough", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(-.2f, 0, 0)
                        }
                    }
                }
            }
            , {
                Gates.WHITE_LIGHT, new Dictionary<string, RustComponentDefinition> {
                    {
                        "Power In", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(.2f, 0, 0)
                        }
                    }
                    , {
                        "Passthrough", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(-.2f, 0, 0)
                        }
                    }
                }
            }
            , {
                Gates.TIMER, new Dictionary<string, RustComponentDefinition> {
                    {
                        "Electric Input", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(0f, -.8f, 0f)
                        }
                    }
                    , {
                        "Toggle On", new RustComponentDefinition {
                            slotNumber = 1, offset = new Vector3(.15f, -1.05f, 0f)
                        }
                    }
                    , {
                        "Output", new RustComponentDefinition {
                            slotNumber = 0, offset = new Vector3(0f, -1.28f, 0f)
                        }
                    }
                }
            }
        }
        ;
        public void ClearCommonEntities() {
            foreach (KeyValuePair<Gates, string> entry in prefab_gate_bindings) {
                ConsoleSystem.Run(ConsoleSystem.Option.Server.Quiet(), $"del {entry.Value}");
            }
            foreach (string prefab in Picasso.SignBindings) {
                ConsoleSystem.Run(ConsoleSystem.Option.Server.Quiet(), $"del {prefab}");
            }
        }
        /**
         * Spawns an Entity in the World
         *
         * @param string prefab
         * @param Vector3 pos
         * @param Quaternion tor
         */
        public BaseEntity SpawnEntity(string prefab, Vector3 pos, Quaternion rot) {
            var entity = GameManager.server.CreateEntity(prefab, pos, rot);
            var transform = entity.transform;
            transform.position = pos;
            transform.rotation = rot;
            var eBranch = entity as ElectricalBranch;
            if (eBranch != null) eBranch.branchAmount = 100000;
            var testGen = entity as ElectricGenerator;
            if (testGen != null) testGen.electricAmount = 2140000000;
            var timerSwitch = entity as TimerSwitch;
            if (timerSwitch != null) {
                timerSwitch.timerLength = 2;
            }
            entity.Spawn();
            return entity;
        }
        /*
         * Wires two Entities together
         * returns the IOSlots that were wired
         *
         * @param IOEntity source
         * @param Gates source_binding
         * @param string source_slot
         * @param IOEntity target
         * @param Gates target_binding
         * @param string target_slot
         * @return IOEntity.IOSlot[]
        */
        public IOEntity.IOSlot[] WireEntites(IPlayer player, IOEntity source, Gates source_binding, string source_slot, IOEntity target, Gates target_binding, string target_slot, WireTool.WireColour wire_color = WireTool.WireColour.Default ) {
            // Get Indexes for IO Slots
#if DEBUG_PINS
            player.Reply($"Source: {source_binding} | {source_slot}");
            player.Reply($"Target: {target_binding} | {target_slot}");
#endif
            RustComponentDefinition sourceDefinition = io_definitions[source_binding == Gates.NOT ? Gates.XOR : source_binding][source_slot];
            RustComponentDefinition targetDefinition = io_definitions[target_binding == Gates.NOT ? Gates.XOR : target_binding][target_slot];
            byte sourceIndex = sourceDefinition.slotNumber;
            byte targetIndex = targetDefinition.slotNumber;
            // Define Input and Output Slots
            var inputSlot = target.inputs[targetIndex] ;
            var outputSlot = source.outputs[sourceIndex];
            // Setup Output Slot
            if (inputSlot.connectedTo == null) outputSlot.connectedTo = new IOEntity.IORef();
            inputSlot.connectedTo.Set(source);
            inputSlot.connectedToSlot = sourceIndex;
            inputSlot.connectedTo.Init();
            // Setup Output Slot
            if (outputSlot.connectedTo == null) outputSlot.connectedTo = new IOEntity.IORef();
            outputSlot.connectedTo.Set(target);
            outputSlot.connectedToSlot = targetIndex;
            outputSlot.connectedTo.Init();
            // Setup Wire - TODO FIXED THIS BROKEN SHIT (COULD BE FIXED SHIT NOW)
            outputSlot.wireColour = wire_color;
            outputSlot.type = IOEntity.IOType.Electric;
            var sourcePosition = source.transform.position;
            var targetPosition = target.transform.position;
            var lineList = new List<Vector3>() {
                Vector3.zero - sourceDefinition.offset, (targetPosition - sourcePosition) - targetDefinition.offset
            }
            ;
            outputSlot.linePoints = lineList.ToArray();
            // Update source and Target
            source.MarkDirtyForceUpdateOutputs();
            source.SendNetworkUpdate();
            target.MarkDirtyForceUpdateOutputs();
            target.SendNetworkUpdate();
            return new IOEntity.IOSlot[2] {
                inputSlot, outputSlot
            }
            ;
        }
    }
    // BEGIND DATATYPES FOR DE-SERIALIZATION
    class Chip : ParentHelpers {
        public string Name;
        public long ID;
        public HashSet<SubChip> SubChips = new HashSet<SubChip>();
        public HashSet<Pin> InputPins = new HashSet<Pin>();
        public HashSet<Pin> OutputPins = new HashSet<Pin>();
        public HashSet<Connection> Connections = new HashSet<Connection>();
        public Dictionary<long, Pin> DicInputPins = new Dictionary<long, Pin>();
        public Dictionary<long, Pin> DicOutputPins = new Dictionary<long, Pin>();
        public void Init(long newId) {
            ID = newId;
            foreach (Connection connection in Connections) {
                if (connection.Source.SubChipID == 0) connection.Source.SubChipID = ID;
                if (connection.Target.SubChipID == 0) connection.Target.SubChipID = ID;
            }
            foreach (Pin pin in InputPins) {
                DicInputPins.Add(pin.ID, pin);
            }
            foreach (Pin pin in OutputPins) {
                DicOutputPins.Add(pin.ID, pin);
            }
        }
        private IOEntity LocateConnectionEntity(IPlayer player, ConnectionIO connection, Dictionary<string, IOEntity> pins, Dictionary<string, IOEntity> electricalComponents ) {
#if DEBUG_PINS
            player.Reply($"PIN Identifier: {connection.SubChipID}_{connection.PinID}");
            if(pins.ContainsKey($"{connection.SubChipID}_{connection.PinID}")) player.Reply($"Found Pin {connection.PinID} in Pins");
            else if (electricalComponents.ContainsKey(connection.SubChipID.ToString())) player.Reply($"Found Pin {connection.PinID} in Electrical Components");
            else player.Reply($"Unable to find Pin {connection.PinID} in Pins or Electrical Components");
#endif
            return pins.ContainsKey($"{connection.SubChipID}_{connection.PinID}") ? pins[$"{connection.SubChipID}_{connection.PinID}"] : electricalComponents[connection.SubChipID.ToString()];
        }
        private void Wire(JData thisInstance, IPlayer player, Project project_reference, Dictionary<string, Chip> chipDefinitions, Dictionary<string, IOEntity> pins, Dictionary<string, IOEntity> electricalComponents, int totalEntityCount ) {
#if DEBUG_PINS
            player.Reply($"PIN STACK: {String.Join(" | ", pins.Keys)}");
#endif
            // Our list of connections to wire up, this takes into account duplicate pins, as well as their positions.HashSet<object[]> pinsToWire = new HashSet<object[]>();
            Dictionary<string, Vector3> duplicatePinPositions = new Dictionary<string, Vector3>();
            Dictionary<string, int> duplicatePins = new Dictionary<string, int>();
            // Iterate over this chips connections
            foreach (Connection connection in Connections) {
                // If we somehow wire something to itself, skip it
                if (connection.Source.SubChipID == connection.Target.SubChipID) continue;
                // Grab our entities for wiring
                var sourceEntity = LocateConnectionEntity(player, connection.Source, pins, electricalComponents);
                var targetEntity = LocateConnectionEntity(player, connection.Target, pins, electricalComponents);
                //Check if the source entity has connections to multiple components
                //We create an int and init it to 0 then add up for additional times we
                //See a source connected
                var duplicatePinId = $"{connection.Source.SubChipID.ToString()}_{connection.Source.PinID.ToString()}";
                if (!duplicatePins.ContainsKey(duplicatePinId)) {
                    duplicatePinPositions.Add(duplicatePinId, sourceEntity.transform.position);
                    duplicatePins.Add(duplicatePinId, 0);
                }
                else {
                    duplicatePins[duplicatePinId]++;
                }
                // BEGIN Locating Gate Types
                var sourceChipId = connection.Source.SubChipID.ToString();
                var sourcePinId = connection.Source.PinID;
                var targetChipId = connection.Target.SubChipID.ToString();
                var targetPinId = connection.Target.PinID;
                var sourceGate = connection.Source.SubChipID == ID ? Gates.OR : string_to_gates.ContainsKey(chipDefinitions[sourceChipId].Name) ? string_to_gates[chipDefinitions[sourceChipId].Name] : Gates.E_BRANCH;
                var targetGate = connection.Target.SubChipID == ID ? Gates.E_BRANCH : string_to_gates.ContainsKey(chipDefinitions[targetChipId].Name) ? string_to_gates[chipDefinitions[targetChipId].Name] : Gates.OR;
                // END Locating Gate Types
                // BEGIN Locating Gate Slots
                var sourceSlot = "";
                if (sourceGate == Gates.NOT || sourceGate == Gates.AND || (sourceGate == Gates.OR && chipDefinitions[sourceChipId].Name != "OR")) {
                    sourceSlot = "Power Out";
                }
                else if (sourceGate == Gates.E_BRANCH && chipDefinitions[sourceChipId].Name != "E_BRANCH") {
                    sourceSlot = "Power Out";
                }
                else {
                    sourceSlot = chipDefinitions[sourceChipId].DicOutputPins[sourcePinId].Name;
                }
#if DEBUG_PINS
                player.Reply(chipDefinitions[targetChipId].Name);
                player.Reply(sourcePinId.ToString());
                player.Reply(prefab_gate_bindings[targetGate]);
#endif
                var targetSlot = "";
                if (targetGate == Gates.NOT) {
                    targetSlot = "Input A";
                }
                else if (targetGate == Gates.AND) {
                    targetSlot = targetPinId == 0 ? "Input A" : "Input B";
                }
                else if (targetGate == Gates.OR && chipDefinitions[targetChipId].Name != "OR") {
                    targetSlot = "Input A";
                }
                else if (targetGate == Gates.E_BRANCH && chipDefinitions[targetChipId].Name != "E_BRANCH") {
                    targetSlot = "Power In";
                }
                else {
                    targetSlot = chipDefinitions[targetChipId].DicInputPins[targetPinId].Name;
                }
                //END Locating Gate Slots
                // If a switch add a sign showing its output connection
                if (sourceGate == Gates.SIMPLE_SWITCH) {
                    var sourcePosition = sourceEntity.transform.position;
                    thisInstance.BindSaveSign(new Vector3(sourcePosition.x -.7f, sourcePosition.y +.75f, sourcePosition.z), new Quaternion(0, 0, 0, 0),  //new Quaternion(0, 1, 0, 0),
                    Picasso.Signs.WoodenSmall, 128, 64, 17, Picasso.FontSize.Small, new Dictionary<string, Brush> {
                        {
                            chipDefinitions[targetChipId].Name, Brushes.Black
                        }
                        , {
                            chipDefinitions[targetChipId].DicInputPins[connection.Target.PinID].Name, Brushes.Orange
                        }
                    }
                    , System.Drawing.Color.Green );
                }
                // Add definition be iterated on later
                pinsToWire.Add(new object[8] {
                    duplicatePinId, sourceEntity, sourceGate, sourceSlot, targetEntity, targetGate, targetSlot, connection.GetWireColor()
                }
                );
            }
            // Next spawn Splitters for duplicate pin connections.Dictionary<string, List<IOEntity>> duplicatePinsConnector = new Dictionary<string, List<IOEntity>>();
            foreach (KeyValuePair<string, int> pin in duplicatePins) {
                // If this pin had a single connection, skip it
                if (pin.Value == 0) continue;
                // Position the Splitter next to our component
                Vector3 startPosition = new Vector3(duplicatePinPositions[pin.Key].x, duplicatePinPositions[pin.Key].y, duplicatePinPositions[pin.Key].z + 1);
                // If we have 2 connections, just spawn a single splitter
                if (pin.Value == 1) {
                    duplicatePinsConnector.Add(pin.Key, new List<IOEntity> {
                        SpawnEntity(prefab_gate_bindings[Gates.SPLITTER], startPosition, new Quaternion(0, 0, 0, 0)  //new Quaternion(1, 1, 0, 0)
                        )as IOEntity
                    }
                    );
                    totalEntityCount++;
                    continue;
                }
                // If we get this far then we can assume we have more than 2 connections
                // We need to spawn a splitter for every 2 connections
                // We also need to wire the splitters together
                List<IOEntity> splitters = new List<IOEntity>();
                Vector3 multiSplitterPos = new Vector3(startPosition.x, startPosition.y + 1, startPosition.z);
                // player.Reply($"Pin Count: {pin.Value}");
                // player.Reply($"double val: {(double) pin.Value / 2}");
                // player.Reply($"loop counter: { Math.Ceiling((double) pin.Value / 2)}");
                for (int i = 0; i <= (int) Math.Ceiling((double) pin.Value / 2);
                i++) {
                    multiSplitterPos = new Vector3(multiSplitterPos.x, multiSplitterPos.y, multiSplitterPos.z - 1);
                    splitters.Add(SpawnEntity(prefab_gate_bindings[Gates.SPLITTER], multiSplitterPos, new Quaternion(0, 0, 0, 0)  //new Quaternion(1, 1, 0, 0)
                    ) as IOEntity);
                    totalEntityCount++;
                    // Only self wire if on the second or greater iteration
                    if (i == 0) continue;
                    WireEntites(player, splitters[i - 1], Gates.SPLITTER, "Power Out 3", splitters[i], Gates.SPLITTER, "Power In" );
                }
                duplicatePinsConnector.Add(pin.Key, splitters);
            }
            Dictionary<string, int> timesConnected = new Dictionary<string, int>();
            foreach (object[] wireInstructions in pinsToWire) {
                var duplicatePinId = wireInstructions[0] as string;
                if (duplicatePins.ContainsKey(duplicatePinId) && duplicatePins[duplicatePinId] > 0) {
                    WireEntites(player, wireInstructions[1] as IOEntity, (Gates) wireInstructions[2], wireInstructions[3] as string, duplicatePinsConnector[duplicatePinId][0], Gates.SPLITTER, "Power In", (WireTool.WireColour) wireInstructions[7] );
                    if (! timesConnected.ContainsKey(duplicatePinId)) timesConnected.Add(duplicatePinId, 0);
                    else timesConnected[duplicatePinId]++;
                    // Which Splitter in our Splitter Stack do we want to select for connection
                    int duplicatePinsConnectorIndex = 0;
                    if (timesConnected[duplicatePinId] >= 2) {
                        duplicatePinsConnectorIndex = (int) Math.Floor((double) timesConnected[duplicatePinId] / 2);
                    }
                    // Which pin on the splitter do we want to connect to
                    var splitterConnection = $"Power Out {timesConnected[duplicatePinId] + 1}";
                    if (timesConnected[duplicatePinId] >= 2) {
                        splitterConnection = timesConnected[duplicatePinId] % 2 == 0 ? "Power Out 1" : "Power Out 2";
                    }
                    // player.Reply($"Times Connected {timesConnected[duplicatePinId]}");
                    // player.Reply($"PinID {duplicatePinId}");
                    // player.Reply($"DupeCount {duplicatePinsConnector[duplicatePinId].Count}");
                    // player.Reply($"Current Index {duplicatePinsConnectorIndex}");
                    WireEntites(player, duplicatePinsConnector[duplicatePinId][duplicatePinsConnectorIndex], Gates.SPLITTER, splitterConnection, wireInstructions[4] as IOEntity, (Gates) wireInstructions[5], wireInstructions[6] as string, (WireTool.WireColour) wireInstructions[7] );
                    continue;
                }
                WireEntites(player, wireInstructions[1] as IOEntity, (Gates) wireInstructions[2], wireInstructions[3] as string, wireInstructions[4] as IOEntity, (Gates) wireInstructions[5], wireInstructions[6] as string, (WireTool.WireColour) wireInstructions[7] );
            }
        }
        public object[] Build(IPlayer player, JData thisInstance, Project project_reference, Vector3 startPosition, Quaternion startRotation, bool depthShouldBeZOrY = true) {
            var customChipCount = 1;
            var chipDefinitions = new Dictionary<string, Chip>();
            var pins = BuildPins(startPosition, startRotation);
            // Our Pins
            int totalEntityCount = 0 + pins.Count;
            var electricalComponents = new Dictionary<string, IOEntity>();
            // Every E Component we spawned for vanilla items
            chipDefinitions.Add(ID.ToString(), this);
#if DEBUG
            player.Reply($"Building {Name} ({ID})");
#endif
            thisInstance.BindSaveSign(new Vector3(startPosition.x + 2, startPosition.y + 5.5f, startPosition.z), new Quaternion(0, 0, 0, 0),  //new Quaternion(0, 1, 0, 0),
            Picasso.Signs.WoodenSmall, 128, 64, 17, Picasso.FontSize.Small, new Dictionary<string, Brush> {
                {
                    Name, Brushes.Yellow
                }
                , {
                    ID.ToString(), Brushes.Orange
                }
            }
            , System.Drawing.Color.Blue );
            // Build our SubChips for this Chip
            foreach (SubChip chip in SubChips) {
                // Add Chip Definition to our Dictionary
                if (! chipDefinitions.ContainsKey(chip.ID.ToString())) {
                    Chip chipDefinition = project_reference.ReadChip(chip.Name);
                    if (chipDefinition != null) {
                        chipDefinition.Init(chip.ID);
                        chipDefinitions.Add(chip.ID.ToString(), chipDefinition);
                    }
                }
                // Convert Chip Point into Vector3
                var chipPoint = new Dictionary<string, float>();
                foreach (Dictionary<string, float> point in chip.Points) {
                    chipPoint.Add("X", point["X"]);
                    chipPoint.Add("Y", point["Y"]);
                }
                // Adjust our Chip Position
                var localChipAdjustedPosition = new Vector3(startPosition.x - chipPoint["X"], startPosition.y + chipPoint["Y"], startPosition.z);
                // Is Custom Chip
                if (!string_to_gates.ContainsKey(chip.Name)) {
                    thisInstance.BindSaveSign(localChipAdjustedPosition, new Quaternion(0, 0, 0, 0),  //new Quaternion(0, 1, 0, 0),
                    Picasso.Signs.WoodenSmall, 128, 64, 17, Picasso.FontSize.Small, new Dictionary<string, Brush> {
                        {
                            chip.Name, Brushes.Yellow
                        }
                        , {
                            chip.ID.ToString(), Brushes.Orange
                        }
                    }
                    , System.Drawing.Color.Black );
                    Vector3 nextSpot = new Vector3(startPosition.x, startPosition.y, startPosition.z - (15 * customChipCount));
                    if (!depthShouldBeZOrY) {
                        nextSpot = new Vector3(startPosition.x, startPosition.y + (15 * customChipCount), startPosition.z);
                    }
                    var subChipDefinition = chipDefinitions[chip.ID.ToString()];
                    var buildObjects = subChipDefinition.Build(player, thisInstance, project_reference, nextSpot, startRotation, !depthShouldBeZOrY);
                    totalEntityCount += (int) buildObjects[2];
                    // Add our SubChip Pins to our Pins List
                    foreach (KeyValuePair<string, IOEntity> entry in buildObjects[0] as Dictionary<string, IOEntity>) {
                        if (!pins.ContainsKey(entry.Key)) pins.Add(entry.Key, entry.Value);
                    }
                    Chip subChipInnerDefintion = buildObjects[1] as Chip;
                    if (!chipDefinitions.ContainsKey(subChipInnerDefintion.ID.ToString())) chipDefinitions.Add(subChipInnerDefintion.ID.ToString(), subChipInnerDefintion);
                    customChipCount++;
                }
                // If NOT || AND (DSL reserved) we spawn them as vanilla items
                else if (string_to_gates[chip.Name] == Gates.AND || string_to_gates[chip.Name] == Gates.NOT) {
                    var chipDefinition = new Chip {
                        Name = chip.Name, InputPins = new HashSet<Pin>(), OutputPins = new HashSet<Pin>(), Connections = new HashSet<Connection>()
                    }
                    ;
                    chipDefinition.Init(chip.ID);
                    chipDefinitions.Add(chip.ID.ToString(), chipDefinition);
                    if (string_to_gates[chip.Name] == Gates.NOT) {
                        // Spawn our Pin
                        electricalComponents.Add(chip.ID.ToString(), BuildNot(player, localChipAdjustedPosition, startRotation));
                        totalEntityCount += 2;
                    }
                    else {
                        // Spawn our Pin
                        electricalComponents.Add(chip.ID.ToString(), SpawnEntity(prefab_gate_bindings[Gates.AND], localChipAdjustedPosition, startRotation ) as IOEntity);
                        totalEntityCount ++;
                    }
                }
                // Normal Electrical Components
                else if (string_to_gates.ContainsKey(chip.Name)) {
                    electricalComponents.Add(chip.ID.ToString(), SpawnEntity(prefab_gate_bindings[string_to_gates[chip.Name]], localChipAdjustedPosition, startRotation ) as IOEntity);
                    totalEntityCount++;
                }
                // Build Custom Chips Recursively
                else {
                    throw new Exception($"Unable to handle chip {chip.Name} ({chip.ID})");
                }
            }
            Wire(thisInstance, player, project_reference, chipDefinitions, pins, electricalComponents, totalEntityCount);
            return new object[] {
                pins, chipDefinitions[ID.ToString()], totalEntityCount
            }
            ;
        }
        private IOEntity BuildNot(IPlayer player, Vector3 localChipAdjustedPosition, Quaternion startRotation) {
            var xor_switch = SpawnEntity(prefab_gate_bindings[Gates.XOR], localChipAdjustedPosition, startRotation ) as IOEntity;
            var test_generator = SpawnEntity(prefab_gate_bindings[Gates.TEST_GENERATOR], new Vector3(localChipAdjustedPosition.x, localChipAdjustedPosition.y, localChipAdjustedPosition.z - 3), startRotation ) as IOEntity;
            WireEntites(player, test_generator, Gates.TEST_GENERATOR, "Power Output 1", xor_switch, Gates.XOR, "Input B" );
            return xor_switch;
        }
        /**
         * Spawns Our Pins in the World
         *
         * @param string prefab
         * @param Vector3 pos
         * @param Quaternion tor
         * @return Dictionary<string, IOEntity>
         */
        public Dictionary<string, IOEntity> BuildPins(Vector3 startPosition, Quaternion startRotation) {
            var pinEntities = new Dictionary<string, IOEntity>();
            // Iterate over our Pin List
            foreach (Pin pin in OutputPins) {
                // Spawn our Pin
                pinEntities.Add($"{ID}_{pin.ID}", SpawnEntity(prefab_gate_bindings[Gates.E_BRANCH], new Vector3(startPosition.x - 8, startPosition.y + pin.PositionY, startPosition.z), startRotation ) as IOEntity);
            }
            foreach (Pin pin in InputPins) {
                // Spawn our Pin
                pinEntities.Add($"{ID}_{pin.ID}", SpawnEntity(prefab_gate_bindings[Gates.OR], new Vector3(startPosition.x + 10, startPosition.y + pin.PositionY, startPosition.z), startRotation ) as IOEntity);
            }
            return pinEntities;
        }
        public string ToString() {
            string message = $"{Name} \n SubChips:\n";
            foreach (SubChip chip in SubChips) {
                message += $"{chip.ToString()}\n";
            }
            message += "Connections\n";
            foreach (Connection connection in Connections) {
                message += $"{connection.ToString()}\n";
            }
            return message;
        }
    }
    class Pin {
        public string Name;
        public long ID;
        public float PositionY;
        public string ToString() {
            return $"Pin ({ID}) - {Name}";
        }
    }
    class ConnectionIO {
        public long PinID;
        public long PinType;
        public long SubChipID;
        public string ToString() {
            return $"Chip: {SubChipID} \n Pin: {PinID}";
        }
    }
    class Connection {
        public ConnectionIO Source;
        public ConnectionIO Target;
        public string ColourThemeName;
        public string ToString() {
            return $"Source\n {Source.ToString()} \n Target\n {Target.ToString()}";
        }
        public WireTool.WireColour GetWireColor() {
            switch (ColourThemeName) {
                case "Red" : return WireTool.WireColour.Red;
                case "Yellow" : return WireTool.WireColour.Yellow;
                case "Green" : return WireTool.WireColour.Green;
                case "Blue" : return WireTool.WireColour.Blue;
                case "Indigo" : return WireTool.WireColour.Purple;
                default : return WireTool.WireColour.Default;
            }
        }
    }
    class SubChip {
        public string Name;
        public long ID;
        public HashSet<Dictionary<string, float>> Points;
        public string ToString() {
            return $"{Name} ({ID})";
        }
        public Gates GetGate() {
            var dic = new Dictionary<string, Gates> {
                {
                    "SPLITTER", Gates.SPLITTER
                }
                , {
                    "BLOCKER", Gates.BLOCKER
                }
                , {
                    "MEMORY_CELL", Gates.MEMORY_CELL
                }
                , {
                    "E_BRANCH", Gates.E_BRANCH
                }
                , {
                    "AND", Gates.AND
                }
                , {
                    "OR", Gates.OR
                }
                , {
                    "XOR", Gates.XOR
                }
                , {
                    "TEST_GENERATOR", Gates.TEST_GENERATOR
                }
                , {
                    "SWITCH", Gates.SIMPLE_SWITCH
                }
                , {
                    "SMART_SWITCH", Gates.SMART_SWITCH
                }
                , {
                    "G_LIGHT", Gates.GREEN_LIGHT
                }
                , {
                    "R_LIGHT", Gates.RED_LIGHT
                }
                , {
                    "W_LIGHT", Gates.WHITE_LIGHT
                }
            }
            ;
            return dic[Name];
        }
    }
    class Project : ParentHelpers {
        public string ProjectName;
        public HashSet<string> AllCreatedChips = new HashSet<string>();
        public DataFileSystem dataFileSystem = new DataFileSystem($"{Interfa
// ... [Code preview truncated due to length. Full source in attached file] ...

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху