/// <summary>
    /// A recursive search that only returns true when the goal node has been found.
    /// </summary>
    /// <returns><c>true</c>, if the goal node has been found, <c>false</c> otherwise.</returns>
    /// <param name="graph">Graph.</param>
    /// <param name="visitedNode">The node we are currently on.</param>
    /// <param name="goalNode">The node that we want to reach.</param>
    bool RandomSearch(PipeNode[,] graph, PipeNode visitedNode, PipeNode goalNode)
    {
        visitedNode.visited = true;
        List <PipeNode> nodesToVisit = new List <PipeNode>();

        // If we have reached the goal
        if (goalNode.row == visitedNode.row && goalNode.col == visitedNode.col)
        {
            _path.Add(visitedNode);
            visitedNode.onPath = true;
            return(true);
        }

        // Check if bottom node is valid
        if (visitedNode.row + 1 < NUM_ROWS && !graph[visitedNode.row + 1, visitedNode.col].visited)
        {
            nodesToVisit.Add(graph[visitedNode.row + 1, visitedNode.col]);
        }

        // Check if left node is valid
        if (visitedNode.col - 1 >= 0 && !graph[visitedNode.row, visitedNode.col - 1].visited)
        {
            nodesToVisit.Add(graph[visitedNode.row, visitedNode.col - 1]);
        }

        // Check if right node is valid
        if (visitedNode.col + 1 < NUM_COLS && !graph[visitedNode.row, visitedNode.col + 1].visited)
        {
            nodesToVisit.Add(graph[visitedNode.row, visitedNode.col + 1]);
        }

        // Check if top node is valid
        if (visitedNode.row - 1 >= 0 && !graph[visitedNode.row - 1, visitedNode.col].visited)
        {
            nodesToVisit.Add(graph[visitedNode.row - 1, visitedNode.col]);
        }

        // Randomize the list of nodes to visit
        List <PipeNode> randomNodesToVisit = new List <PipeNode>();

        while (nodesToVisit.Count > 0)
        {
            int randomIndex = _rand.Next(0, nodesToVisit.Count);
            randomNodesToVisit.Add(nodesToVisit[randomIndex]);
            nodesToVisit.RemoveAt(randomIndex);
        }

        // Go into the next recursive iteration of each node to visit
        foreach (PipeNode node in randomNodesToVisit)
        {
            if (RandomSearch(graph, node, goalNode))
            {
                _path.Add(visitedNode);
                visitedNode.onPath = true;
                return(true);
            }
        }

        return(false);
    }
Exemple #2
0
        public void TestIfItCanSortAnArray()
        {
            // Arrange
            int[] data     = new int[] { 1, 4, 3, 2 };
            int[] expected = data.OrderByDescending(n => n).ToArray();
            IEnumerable <PipeNode> nodes = GetConnectedPipes(4);
            ISocket  masterRecv          = TestHelper.GetSocket();
            ISocket  masterSend          = TestHelper.GetSocket();
            PipeNode firstPipe           = nodes.ElementAt(0);

            Connect(sender: masterSend, to: firstPipe.GetReceiverFromLeft());
            Connect(sender: firstPipe.GetSenderToLeft(), to: masterRecv);
            PipeMaster master = TestHelper.GetPipeMaster(masterSend, masterRecv);

            // Act
            int count = 0;

            nodes.ToList().ForEach(n => n.Start(count++, 4));
            int[] actual = master.Sort(data);

            // Assert
            Verify.That(actual).IsEqualTo(expected).Now();

            // Reset
        }
        public override void draw(SpriteBatch spriteBatch, int x, int y, float alpha = 1)
        {
            string     drawSum            = this.GetSpriteKey(Game1.currentLocation);
            int        sourceRectPosition = DrawGuide[drawSum];
            DataAccess DataAccess         = DataAccess.GetDataAccess();

            if (DataAccess.LocationNodes.ContainsKey(Game1.currentLocation))
            {
                List <Node> nodes = DataAccess.LocationNodes[Game1.currentLocation];
                //Printer.Info(nodes.Count.ToString());
                Node node = nodes.Find(n => n.Position.Equals(TileLocation));
                if (node != null && node is PipeNode)
                {
                    PipeNode pipe         = (PipeNode)node;
                    float    transparency = 1f;
                    if (pipe.Passable)
                    {
                        Passable     = true;
                        transparency = 0.5f;
                    }
                    else
                    {
                        Passable     = false;
                        transparency = 1f;
                    }
                    if (pipe.PassingItem)
                    {
                        SpriteTexture = ItemMovingSprite;
                        spriteBatch.Draw(SpriteTexture, Game1.GlobalToLocal(Game1.viewport, new Vector2(x * 64, y * 64)),
                                         new Rectangle(sourceRectPosition * 16 % SpriteTexture.Bounds.Width,
                                                       sourceRectPosition * 16 / SpriteTexture.Bounds.Width * 16,
                                                       16, 16), Color.White * transparency, 0f, Vector2.Zero, 4f, SpriteEffects.None, ((float)(y * 64 + 32) / 10000f) + 0.001f);
                        drawItem(pipe, spriteBatch, x, y);
                    }
                    else if (pipe.Connecting)
                    {
                        SpriteTexture = ConnectingSprite;
                        spriteBatch.Draw(SpriteTexture, Game1.GlobalToLocal(Game1.viewport, new Vector2(x * 64, y * 64)),
                                         new Rectangle(sourceRectPosition * 16 % SpriteTexture.Bounds.Width,
                                                       sourceRectPosition * 16 / SpriteTexture.Bounds.Width * 16,
                                                       16, 16), Color.White * transparency, 0f, Vector2.Zero, 4f, SpriteEffects.None, ((float)(y * 64 + 32) / 10000f) + 0.001f);
                    }
                    else
                    {
                        SpriteTexture = DefaultSprite;
                        spriteBatch.Draw(SpriteTexture, Game1.GlobalToLocal(Game1.viewport, new Vector2(x * 64, y * 64)),
                                         new Rectangle(sourceRectPosition * 16 % SpriteTexture.Bounds.Width,
                                                       sourceRectPosition * 16 / SpriteTexture.Bounds.Width * 16,
                                                       16, 16), Color.White * transparency, 0f, Vector2.Zero, 4f, SpriteEffects.None, ((float)(y * 64 + 32) / 10000f) + 0.001f);
                    }

                    /*
                     * spriteBatch.Draw(SpriteTexture, Game1.GlobalToLocal(Game1.viewport, new Vector2(x * 64, y * 64 - 64)),
                     *      new Rectangle(sourceRectPosition * Fence.fencePieceWidth % SpriteTexture.Bounds.Width,
                     *      sourceRectPosition * Fence.fencePieceWidth / SpriteTexture.Bounds.Width * Fence.fencePieceHeight,
                     *      Fence.fencePieceWidth, Fence.fencePieceHeight), Color.White * transparency, 0f, Vector2.Zero, 4f, SpriteEffects.None, ((float)(y * 64 + 32) / 10000f) + 0.001f);
                     */
                }
            }
        }
Exemple #4
0
 /// <summary>
 /// Called to finish ingress of new messages.
 /// </summary>
 public void QueueEndOfMessages()
 {
     messages.Add(PipeNode.fromEOF());
     lock (newItemLock) {
         Monitor.PulseAll(newItemLock);
     }
 }
Exemple #5
0
 public override void Initialize()
 {
     base.Initialize();
     if (!Owner.TryGetComponent <NodeContainerComponent>(out var container))
     {
         JoinedGridAtmos?.RemovePipeNetDevice(this);
         Logger.Error($"{typeof(GasCanisterPortComponent)} on entity {Owner.Uid} did not have a {nameof(NodeContainerComponent)}.");
         return;
     }
     _gasPort = container.Nodes.OfType <PipeNode>().FirstOrDefault();
     if (_gasPort == null)
     {
         JoinedGridAtmos?.RemovePipeNetDevice(this);
         Logger.Error($"{typeof(GasCanisterPortComponent)} on entity {Owner.Uid} could not find compatible {nameof(PipeNode)}s on its {nameof(NodeContainerComponent)}.");
         return;
     }
     if (Owner.TryGetComponent <SnapGridComponent>(out var snapGrid))
     {
         var anchoredCanister = snapGrid.GetLocal()
                                .Select(entity => entity.TryGetComponent <GasCanisterComponent>(out var canister) ? canister : null)
                                .Where(canister => canister != null)
                                .Where(canister => canister.Anchored)
                                .Where(canister => !canister.ConnectedToPort)
                                .FirstOrDefault();
         if (anchoredCanister != null)
         {
             anchoredCanister.TryConnectToPort();
         }
     }
 }
Exemple #6
0
    private IEnumerator AnimatePipe()
    {
        PipeNode currentNode = StartingNode;

        while (currentNode != null)
        {
            switch (currentNode.Type)
            {
            case PipeNode.NodeType.START:
                yield return(StartCoroutine(AnimateStart(currentNode.gameObject, currentNode.NextNode.gameObject)));

                break;

            case PipeNode.NodeType.CORNER:
                yield return(StartCoroutine(AnimateCorner(currentNode.PreviousNode.gameObject, currentNode.gameObject, currentNode.NextNode.gameObject)));

                break;

            case PipeNode.NodeType.END:
            default:
                yield return(StartCoroutine(AnimateEnd(currentNode.PreviousNode.gameObject, currentNode.gameObject)));

                break;
            }

            currentNode = currentNode.NextNode;
        }

        Destroy(startCap);
        Destroy(tube);
        Destroy(endCap);
    }
Exemple #7
0
        private IEnumerable <PipeNode> GetConnectedPipes(int amount)
        {
            ISocket[]  leftReceivers  = new ISocket[amount];
            ISocket[]  leftSenders    = new ISocket[amount];
            ISocket[]  rightReceivers = new ISocket[amount];
            ISocket[]  rightSenders   = new ISocket[amount];
            PipeNode[] nodes          = new PipeNode[amount];
            for (int i = 0; i < amount; i++)
            {
                leftReceivers[i] = TestHelper.GetSocket();
                leftSenders[i]   = TestHelper.GetSocket();
                if (i < amount - 1)
                {
                    rightReceivers[i] = TestHelper.GetSocket();
                    rightSenders[i]   = TestHelper.GetSocket();
                }

                if (i > 0)
                {
                    // Se conecta con el nodo anterior
                    Connect(sender: rightSenders[i - 1], to: leftReceivers[i]);
                    Connect(sender: leftSenders[i], to: rightReceivers[i - 1]);
                }

                nodes[i] = new PipeNode(rightSenders[i], leftReceivers[i], leftSenders[i], rightReceivers[i]);
            }

            return(nodes);
        }
        //ESTO PARA GUARDAR OVERLOADED ITEMS
        public override SObject Save()
        {
            //For 1.6
            DataAccess DataAccess = DataAccess.GetDataAccess();

            if (DataAccess.LocationNodes.ContainsKey(Game1.currentLocation))
            {
                List <Node> nodes = DataAccess.LocationNodes[Game1.currentLocation];
                Node        node  = nodes.Find(n => n.Position.Equals(TileLocation));
                if (node != null && node is PipeNode)
                {
                    PipeNode pipe = (PipeNode)node;
                    if (pipe.StoredItem != null)
                    {
                        /*
                         * if (!modData.ContainsKey("StoredItem")) { modData.Add("StoredItem", pipe.StoredItem.Name); }
                         * else { modData["StoredItem"] = pipe.StoredItem.Name; }
                         * if (!modData.ContainsKey("StoredItemStack")) { modData.Add("StoredItemStack", pipe.StoredItem.Stack.ToString()); }
                         * else { modData["StoredItemStack"] = pipe.StoredItem.Stack.ToString(); }
                         */
                        //Implement with 1.6
                        //Create item with utility method

                        //Temp solution:

                        //Return to extractor
                        if (Globals.Debug)
                        {
                            Printer.Info("Waiting for clogged pipes to return to output...");
                        }
                        int  i    = 0;
                        bool sent = false;
                        while (i < pipe.ParentNetwork.Outputs.Count && !sent)
                        {
                            if (pipe.ParentNetwork.Outputs[i].ConnectedContainer.CanRecieveItem(pipe.StoredItem))
                            {
                                pipe.FlushPipe(pipe.StoredItem, pipe.ParentNetwork.Outputs[i]);
                                sent = true;
                                if (Globals.Debug)
                                {
                                    Printer.Info("Pipe unclogged succesfully!");
                                }
                            }
                            i++;
                        }
                        if (!sent)
                        {
                            Printer.Error("Clogged pipe couldn't be emptied at saving. These items will be lost: ");
                            Printer.Error($"In {Name} at {pipe.Position} at {pipe.Location.Name} holding {pipe.StoredItem.Stack} {pipe.StoredItem.Name} were lost.");
                        }
                    }
                }
            }
            //Fence fence = new Fence(tileLocation, 1, false);
            //fence.modData = modData;

            return(base.Save());
        }
Exemple #9
0
        public void InitialiseNodeNew(Vector3Int Location, Matrix matrix, Matrix4x4 Matrix4x4)
        {
            var ZeroedLocation = new Vector3Int(x: Location.x, y: Location.y, 0);
            var metaData       = matrix.MetaDataLayer.Get(ZeroedLocation);
            var pipeNode       = new PipeNode();
            var rotation       = Matrix4x4;
            int Offset         = PipeFunctions.GetOffsetAngle(rotation.rotation.eulerAngles.z);

            pipeNode.Initialise(this, metaData, ZeroedLocation, matrix, Offset);
            metaData.PipeData.Add(pipeNode);
        }
Exemple #10
0
        public override NodeViewModel CreateModel()
        {
            FilterNode result = null;

            switch (filter)
            {
            case NoiseFilter.Pipe:
                result = new PipeNode();
                break;

            case NoiseFilter.SumFractal:
                result = new SumFractalNode();
                break;

            case NoiseFilter.SinFractal:
                result = new SinFractalNode();
                break;

            case NoiseFilter.Billow:
                result = new BillowNode();
                break;

            case NoiseFilter.MultiFractal:
                result = new MultiFractalNode();
                break;

            case NoiseFilter.HeterogeneousMultiFractal:
                result = new HeterogeneousMultiFractalNode();
                break;

            case NoiseFilter.HybridMultiFractal:
                result = new HybridMultiFractalNode();
                break;

            case NoiseFilter.RidgedMultiFractal:
                result = new RidgedMultiFractalNode();
                break;

            case NoiseFilter.Voronoi:
                result = new VoronoiNode();
                break;
            }

            (result.Frequency.Editor as FloatEditorViewModel).Value      = frequency;
            (result.Lacunarity.Editor as FloatEditorViewModel).Value     = lacunarity;
            (result.Octaves.Editor as ValueEditorViewModel <int?>).Value = octaves;
            (result.Offset.Editor as FloatEditorViewModel).Value         = offset;
            (result.Gain.Editor as FloatEditorViewModel).Value           = gain;

            result.Name     = name;
            result.Position = pos;

            return(result);
        }
Exemple #11
0
        public void InitialiseNode(Vector3Int Location, Matrix matrix)
        {
            var ZeroedLocation = new Vector3Int(x: Location.x, y: Location.y, 0);
            var metaData       = matrix.MetaDataLayer.Get(ZeroedLocation);
            var pipeNode       = new PipeNode();
            var rotation       = matrix.UnderFloorLayer.Tilemap.GetTransformMatrix(Location);
            int Offset         = PipeFunctions.GetOffsetAngle(rotation.rotation.eulerAngles.z);

            pipeNode.Initialise(this, metaData, ZeroedLocation, matrix, Offset);
            metaData.PipeData.Add(pipeNode);
        }
Exemple #12
0
        public override bool AddAdjacent(Side side, Node node)
        {
            bool added = false;

            if (Adjacents[side] == null)
            {
                added           = true;
                Adjacents[side] = node;
                node.AddAdjacent(Sides.GetInverse(side), this);
                if (node is PipeNode && node.ParentNetwork != null)
                {
                    PipeNode pipeNode = (PipeNode)node;
                    AdjNetworks.Add(pipeNode.ParentNetwork);
                    pipeNode.ParentNetwork.AddNode(this);
                }
            }
            return(added);
        }
Exemple #13
0
 public override void Initialize()
 {
     base.Initialize();
     _atmosSystem = EntitySystem.Get <AtmosphereSystem>();
     if (!Owner.TryGetComponent <NodeContainerComponent>(out var container))
     {
         JoinedGridAtmos?.RemovePipeNetDevice(this);
         Logger.Error($"{typeof(BaseSiphonComponent)} on entity {Owner.Uid} did not have a {nameof(NodeContainerComponent)}.");
         return;
     }
     _scrubberOutlet = container.Nodes.OfType <PipeNode>().FirstOrDefault();
     if (_scrubberOutlet == null)
     {
         JoinedGridAtmos?.RemovePipeNetDevice(this);
         Logger.Error($"{typeof(BaseSiphonComponent)} on entity {Owner.Uid} could not find compatible {nameof(PipeNode)}s on its {nameof(NodeContainerComponent)}.");
         return;
     }
 }
    /// <summary>
    /// Helper function that instantiates a path with the appropriate pipes.
    /// </summary>
    void InstantiatePath()
    {
        // 1) Initializing nodes
        for (int r = 0; r < NUM_ROWS; r++)
        {
            for (int c = 0; c < NUM_COLS; c++)
            {
                _graph[r, c] = new PipeNode(r, c);
            }
        }

        // 2) Find a start, end, and a random path in between
        int      randColStart = _rand.Next(0, NUM_COLS);
        int      randColEnd   = _rand.Next(0, NUM_COLS);
        PipeNode startNode    = _graph[0, randColStart];
        PipeNode endNode      = _graph[NUM_ROWS - 1, randColEnd];

        RandomSearch(_graph, startNode, endNode);

        // 3) Populate the path tiles with the appropriate pipe
        GameObject pipeTiles = new GameObject();

        pipeTiles.transform.name   = "Pipe Tiles";
        pipeTiles.transform.parent = transform;
        for (int i = 0; i < _path.Count; i++)
        {
            // Inititalize the pipe tile and its componenets
            GameObject pipeTile = new GameObject();
            pipeTile.AddComponent <SpriteRenderer>();
            pipeTile.AddComponent <BoxCollider2D>();

            pipeTile.transform.name = "Pipe Tile " + i;
            pipeTile.GetComponent <SpriteRenderer>().sprite = DeterminePipe(i);
            pipeTile.GetComponent <BoxCollider2D>().size    = new Vector2(1, 1);

            Quaternion rotation = Quaternion.Euler(new Vector3(0f, 0f, _possibleRotations[_rand.Next(0, _possibleRotations.Length)]));
            Vector3    position = new Vector3(_path[i].col, -_path[i].row, 0f);
            _path[i].tile        = Instantiate(pipeTile, position, rotation).transform;
            _path[i].tile.parent = pipeTiles.transform;

            Destroy(pipeTile);
        }
    }
Exemple #15
0
        public override void Initialize()
        {
            base.Initialize();
            if (!Owner.TryGetComponent <NodeContainerComponent>(out var container))
            {
                JoinedGridAtmos?.RemovePipeNetDevice(this);
                Logger.Error($"{typeof(BasePumpComponent)} on entity {Owner.Uid} did not have a {nameof(NodeContainerComponent)}.");
                return;
            }
            var pipeNodes = container.Nodes.OfType <PipeNode>();

            _inletPipe  = pipeNodes.Where(pipe => pipe.PipeDirection == _inletDirection).FirstOrDefault();
            _outletPipe = pipeNodes.Where(pipe => pipe.PipeDirection == _outletDirection).FirstOrDefault();
            if (_inletPipe == null | _outletPipe == null)
            {
                JoinedGridAtmos?.RemovePipeNetDevice(this);
                Logger.Error($"{typeof(BasePumpComponent)} on entity {Owner.Uid} could not find compatible {nameof(PipeNode)}s on its {nameof(NodeContainerComponent)}.");
                return;
            }
        }
Exemple #16
0
        public override bool RemoveAdjacent(Side side, Node node)
        {
            bool removed = false;

            if (Adjacents[side] != null)
            {
                removed         = true;
                Adjacents[side] = null;
                node.RemoveAdjacent(Sides.GetInverse(side), this);
                if (node != null && node is PipeNode)
                {
                    PipeNode pipeNode = (PipeNode)node;
                    AdjNetworks.Remove(pipeNode.ParentNetwork);
                    if (pipeNode.ParentNetwork != null)
                    {
                        pipeNode.ParentNetwork.RemoveNode(this);
                    }
                }
            }
            return(removed);
        }
Exemple #17
0
 public static ISocket GetReceiverFromLeft(this PipeNode target)
 {
     return((ISocket)Fasterflect.FieldExtensions.GetFieldValue(target, "receiverFromLeft"));
 }
Exemple #18
0
 internal override ExpressionNode VisitPipeNode(PipeNode node)
 {
     return base.VisitPipeNode(node);
 }
 private void Scrub(float timeDelta, GasVentScrubberComponent scrubber, GasMixture?tile, PipeNode outlet)
 {
     Scrub(timeDelta, scrubber.TransferRate, scrubber.PumpDirection, scrubber.FilterGases, tile, outlet.Air);
 }
Exemple #20
0
 internal virtual ExpressionNode VisitPipeNode(PipeNode node)
 {
     node.BaseNode.Accept(this);
     return node;
 }
Exemple #21
0
        public void TestIfItCanSortNumbers()
        {
            // Arrange
            ManualResetEvent waitForLeft  = new ManualResetEvent(false);
            ManualResetEvent waitForRight = new ManualResetEvent(false);

            int[] dataFromLeft  = new int[] { 1, 3, 2 };
            int   leftRecvIndex = 0;

            int[] dataFromRight  = new int[] { 2, 1 };
            int   rightRecvIndex = 0;

            int[] expectedSentToRight = new int[] { 1, 2 };
            int[] expectedSentToLeft  = new int[] { 3, 2, 1 };

            PipeNode target            = GetPipeNode();
            ISocket  senderToRight     = target.GetSenderToRight();
            ISocket  receiverFromLeft  = target.GetReceiverFromLeft();
            ISocket  receiverFromRight = target.GetReceiverFromRight();
            ISocket  senderToLeft      = target.GetSenderToLeft();

            receiverFromLeft.Recv(Arg.Any <int>()).Returns(call =>
            {
                if (leftRecvIndex == dataFromLeft.Length)
                {
                    waitForLeft.Set();
                    Thread.Sleep(call.Arg <int>() + 1);
                    return(new byte[] { 0, 0, 0, 0 });
                }

                return(BitConverter.GetBytes(dataFromLeft[leftRecvIndex++]));
            });

            receiverFromRight.Recv(Arg.Any <int>()).Returns(call =>
            {
                if (leftRecvIndex == dataFromLeft.Length)
                {
                    if (rightRecvIndex < dataFromRight.Length)
                    {
                        return(BitConverter.GetBytes(dataFromRight[rightRecvIndex++]));
                    }
                    else
                    {
                        waitForRight.Set();
                        Thread.Sleep(call.Arg <int>() + 1);
                    }
                }
                else
                {
                    waitForLeft.WaitOne();
                    Thread.Sleep(call.Arg <int>() + 1);
                }

                return(new byte[] { 0, 0, 0, 0 });
            });

            int expectedKept = 3;
            int actualKept   = -1;

            // Act
            target.Start(0, 3);
            waitForRight.WaitOne();

            // Assert
            var actualSentToRight = senderToRight.GetSentIntArray();
            var actualSentToLeft  = senderToLeft.GetSentIntArray();

            actualKept = target.GetKept();

            Verify.That(actualKept).IsEqualTo(expectedKept, "Bad expected number kept").Now();
            Verify.That(actualSentToRight).IsEqualTo(expectedSentToRight, "Bad expected sent to right numbers").Now();
            Verify.That(actualSentToLeft).IsEqualTo(expectedSentToLeft, "Bad expected sent to left numbers.").Now();

            // Reset
        }
Exemple #22
0
        private void Scrub(AtmosphereSystem atmosphereSystem, GasVentScrubberComponent scrubber, AppearanceComponent?appearance, GasMixture?tile, PipeNode outlet)
        {
            // Cannot scrub if tile is null or air-blocked.
            if (tile == null ||
                outlet.Air.Pressure >= 50 * Atmospherics.OneAtmosphere)    // Cannot scrub if pressure too high.
            {
                appearance?.SetData(ScrubberVisuals.State, ScrubberState.Off);
                return;
            }

            if (scrubber.PumpDirection == ScrubberPumpDirection.Scrubbing)
            {
                appearance?.SetData(ScrubberVisuals.State, scrubber.WideNet ? ScrubberState.WideScrub : ScrubberState.Scrub);
                var transferMoles = MathF.Min(1f, (scrubber.VolumeRate / tile.Volume) * tile.TotalMoles);

                // Take a gas sample.
                var removed = tile.Remove(transferMoles);

                // Nothing left to remove from the tile.
                if (MathHelper.CloseTo(removed.TotalMoles, 0f))
                {
                    return;
                }

                atmosphereSystem.ScrubInto(removed, outlet.Air, scrubber.FilterGases);

                // Remix the gases.
                atmosphereSystem.Merge(tile, removed);
            }
            else if (scrubber.PumpDirection == ScrubberPumpDirection.Siphoning)
            {
                appearance?.SetData(ScrubberVisuals.State, ScrubberState.Siphon);
                var transferMoles = tile.TotalMoles * (scrubber.VolumeRate / tile.Volume);

                var removed = tile.Remove(transferMoles);

                outlet.AssumeAir(removed);
            }
        }
        private void Scrub(GasVentScrubberComponent scrubber, AppearanceComponent?appearance, TileAtmosphere?tile, PipeNode outlet)
        {
            // Cannot scrub if tile is null or air-blocked.
            if (tile?.Air == null)
            {
                return;
            }

            // Cannot scrub if pressure too high.
            if (outlet.Air.Pressure >= 50 * Atmospherics.OneAtmosphere)
            {
                return;
            }

            if (scrubber.PumpDirection == ScrubberPumpDirection.Scrubbing)
            {
                appearance?.SetData(ScrubberVisuals.State, scrubber.WideNet ? ScrubberState.WideScrub : ScrubberState.Scrub);
                var transferMoles = MathF.Min(1f, (scrubber.VolumeRate / tile.Air.Volume) * tile.Air.TotalMoles);

                // Take a gas sample.
                var removed = tile.Air.Remove(transferMoles);

                // Nothing left to remove from the tile.
                if (MathHelper.CloseTo(removed.TotalMoles, 0f))
                {
                    return;
                }

                // TODO: Entity system dependency
                Get <AtmosphereSystem>().ScrubInto(removed, outlet.Air, scrubber.FilterGases);

                // Remix the gases.
                tile.AssumeAir(removed);
            }
            else if (scrubber.PumpDirection == ScrubberPumpDirection.Siphoning)
            {
                appearance?.SetData(ScrubberVisuals.State, ScrubberState.Siphon);
                var transferMoles = tile.Air.TotalMoles * (scrubber.VolumeRate / tile.Air.Volume);

                var removed = tile.Air.Remove(transferMoles);

                outlet.AssumeAir(removed);
                tile.Invalidate();
            }
        }
 internal override ExpressionNode VisitPipeNode(PipeNode node)
 {
     node.BaseNode.Accept(this);
     graph.Connectors.Add(new PipeGSConnector());
     node.Operator.Accept(this);
     return node;
 }
    /// <summary>
    /// Checks the orientation.
    /// </summary>
    /// <returns><c>true</c>, if the pipe is in the correct orientation, <c>false</c> otherwise.</returns>
    /// <param name="index">Index of the current pipe on path.</param>
    bool CheckOrientation(int index)
    {
        PipeNode currNode  = _path[index];
        float    zRotation = currNode.tile.rotation.eulerAngles.z;

        // These booleans are determined when the path is constructed (but before the tiles are randomized)
        bool hasTopNeighbor    = currNode.neighbors.Contains(PipeNode.NodePosition.TOP);
        bool hasBottomNeighbor = currNode.neighbors.Contains(PipeNode.NodePosition.BOTTOM);
        bool hasLeftNeighbor   = currNode.neighbors.Contains(PipeNode.NodePosition.LEFT);
        bool hasRightNeighbor  = currNode.neighbors.Contains(PipeNode.NodePosition.RIGHT);

        if (currNode.pipeType == PipeNode.PipeType.I)
        {
            if (Mathf.Abs(zRotation) <= EPSILON || Mathf.Abs(zRotation - 180f) <= EPSILON)
            {
                if (hasTopNeighbor && hasBottomNeighbor)
                {
                    return(true);
                }
            }
            else if (Mathf.Abs(zRotation - 90f) <= EPSILON || Mathf.Abs(zRotation - 270f) <= EPSILON)
            {
                if (hasLeftNeighbor && hasRightNeighbor)
                {
                    return(true);
                }
            }
        }
        else if (currNode.pipeType == PipeNode.PipeType.C)
        {
            if (Mathf.Abs(zRotation) <= EPSILON)
            {
                if (hasTopNeighbor && hasLeftNeighbor)
                {
                    return(true);
                }
            }
            else if (Mathf.Abs(zRotation - 90f) <= EPSILON)
            {
                if (hasLeftNeighbor && hasBottomNeighbor)
                {
                    return(true);
                }
            }
            else if (Mathf.Abs(zRotation - 180f) <= EPSILON)
            {
                if (hasBottomNeighbor && hasRightNeighbor)
                {
                    return(true);
                }
            }
            else if (Mathf.Abs(zRotation - 270f) <= EPSILON)
            {
                if (hasRightNeighbor && hasTopNeighbor)
                {
                    return(true);
                }
            }
        }
        else if (currNode.pipeType == PipeNode.PipeType.T)
        {
            if (Mathf.Abs(zRotation) <= EPSILON)
            {
                if (hasLeftNeighbor && hasTopNeighbor && hasRightNeighbor)
                {
                    return(true);
                }
            }
            else if (Mathf.Abs(zRotation - 90f) <= EPSILON)
            {
                if (hasTopNeighbor && hasLeftNeighbor && hasBottomNeighbor)
                {
                    return(true);
                }
            }
            else if (Mathf.Abs(zRotation - 180f) <= EPSILON)
            {
                if (hasRightNeighbor && hasBottomNeighbor && hasLeftNeighbor)
                {
                    return(true);
                }
            }
            else if (Mathf.Abs(zRotation - 270f) <= EPSILON)
            {
                if (hasBottomNeighbor && hasRightNeighbor && hasTopNeighbor)
                {
                    return(true);
                }
            }
        }
        else if (currNode.pipeType == PipeNode.PipeType.CROSS)
        {
            return(true);
        }

        return(false);
    }
Exemple #26
0
 public static ISocket GetSenderToRight(this PipeNode target)
 {
     return((ISocket)Fasterflect.FieldExtensions.GetFieldValue(target, "senderToRight"));
 }
        public void drawItem(PipeNode pipe, SpriteBatch spriteBatch, int x, int y)
        {
            Item      item = pipe.StoredItem;
            Texture2D SpriteSheet;
            Rectangle srcRect;
            Vector2   originalPosition;
            Vector2   position;

            //How to handle drawing custom mod items
            //Igual hacer como coger la sprite y redimensionarla
            //relativamente a su size original y listo
            //try catch para loadear la sprite
            if (item is PipeItem)
            {
                PipeItem pipeItem = (PipeItem)item;
                SpriteSheet      = pipeItem.ItemTexture;
                srcRect          = new Rectangle(0, 0, 16, 16);
                originalPosition = Game1.GlobalToLocal(Game1.viewport, new Vector2(x * 64, y * 64 - 64));
                position         = new Vector2(originalPosition.X + 16, originalPosition.Y + 64 + 16);
                spriteBatch.Draw(SpriteSheet, position, srcRect, Color.White, 0f, Vector2.Zero, 2f, SpriteEffects.None,
                                 ((float)(y * 64 + 32) / 10000f) + 0.002f);
            }
            else if (item is PPMItem)
            {
                PPMItem PPM = (PPMItem)item;
                SpriteSheet      = PPM.ItemTexture;
                srcRect          = new Rectangle(0, 0, 16, 32);
                originalPosition = Game1.GlobalToLocal(Game1.viewport, new Vector2(x * 64, y * 64 - 64));
                position         = new Vector2(originalPosition.X + 23, originalPosition.Y + 64 + 10);
                spriteBatch.Draw(SpriteSheet, position, srcRect, Color.White, 0f, Vector2.Zero, 1.2f, SpriteEffects.None,
                                 ((float)(y * 64 + 32) / 10000f) + 0.002f);
            }
            else if (item is SObject && (item as SObject).bigCraftable.Value)
            {
                SpriteSheet      = Game1.bigCraftableSpriteSheet;
                srcRect          = SObject.getSourceRectForBigCraftable(item.ParentSheetIndex);
                originalPosition = Game1.GlobalToLocal(Game1.viewport, new Vector2(x * 64, y * 64 - 64));
                position         = new Vector2(originalPosition.X + 23, originalPosition.Y + 64 + 10);
                spriteBatch.Draw(SpriteSheet, position, srcRect, Color.White, 0f, Vector2.Zero, 1.2f, SpriteEffects.None,
                                 ((float)(y * 64 + 32) / 10000f) + 0.002f);
            }
            else if (item is Tool)
            {
                Tool tool = (Tool)item;
                if (item is MeleeWeapon || item is Slingshot || item is Sword)
                {
                    SpriteSheet      = Tool.weaponsTexture;
                    srcRect          = Game1.getSquareSourceRectForNonStandardTileSheet(SpriteSheet, 16, 16, tool.IndexOfMenuItemView);
                    originalPosition = Game1.GlobalToLocal(Game1.viewport, new Vector2(x * 64, y * 64 - 64));
                    position         = new Vector2(originalPosition.X + 19, originalPosition.Y + 64 + 19);
                    spriteBatch.Draw(SpriteSheet, position, srcRect, Color.White, 0f, Vector2.Zero, 1.7f, SpriteEffects.None,
                                     ((float)(y * 64 + 32) / 10000f) + 0.002f);
                }
                else
                {
                    SpriteSheet      = Game1.toolSpriteSheet;
                    srcRect          = Game1.getSquareSourceRectForNonStandardTileSheet(SpriteSheet, 16, 16, tool.IndexOfMenuItemView);
                    originalPosition = Game1.GlobalToLocal(Game1.viewport, new Vector2(x * 64, y * 64 - 64));
                    position         = new Vector2(originalPosition.X + 19, originalPosition.Y + 64 + 18);
                    spriteBatch.Draw(SpriteSheet, position, srcRect, Color.White, 0f, Vector2.Zero, 1.7f, SpriteEffects.None,
                                     ((float)(y * 64 + 32) / 10000f) + 0.002f);
                }
            }
            //Boots = standard
            else if (item is Boots)
            {
                Boots boot = (Boots)item;
                SpriteSheet      = Game1.objectSpriteSheet;
                srcRect          = Game1.getSourceRectForStandardTileSheet(Game1.objectSpriteSheet, boot.indexInTileSheet.Value, 16, 16);
                originalPosition = Game1.GlobalToLocal(Game1.viewport, new Vector2(x * 64, y * 64 - 64));
                position         = new Vector2(originalPosition.X + 18, originalPosition.Y + 64 + 16);
                spriteBatch.Draw(SpriteSheet, position, srcRect, Color.White, 0f, Vector2.Zero, 2f, SpriteEffects.None,
                                 ((float)(y * 64 + 32) / 10000f) + 0.002f);
            }
            //rings = standard
            else if (item is Ring)
            {
                SpriteSheet      = Game1.objectSpriteSheet;
                srcRect          = Game1.getSourceRectForStandardTileSheet(Game1.objectSpriteSheet, item.ParentSheetIndex, 16, 16);
                originalPosition = Game1.GlobalToLocal(Game1.viewport, new Vector2(x * 64, y * 64 - 64));
                position         = new Vector2(originalPosition.X + 10, originalPosition.Y + 64 + 14);
                spriteBatch.Draw(SpriteSheet, position, srcRect, Color.White, 0f, Vector2.Zero, 2.5f, SpriteEffects.None,
                                 ((float)(y * 64 + 32) / 10000f) + 0.002f);
            }
            else if (item is Hat)
            {
                Hat hat = (Hat)item;
                SpriteSheet      = FarmerRenderer.hatsTexture;
                srcRect          = new Rectangle((int)hat.which * 20 % FarmerRenderer.hatsTexture.Width, (int)hat.which * 20 / FarmerRenderer.hatsTexture.Width * 20 * 4, 20, 20);
                originalPosition = Game1.GlobalToLocal(Game1.viewport, new Vector2(x * 64, y * 64 - 64));
                position         = new Vector2(originalPosition.X + 12, originalPosition.Y + 64 + 18);
                spriteBatch.Draw(SpriteSheet, position, srcRect, Color.White, 0f, Vector2.Zero, 2f, SpriteEffects.None,
                                 ((float)(y * 64 + 32) / 10000f) + 0.002f);
            }
            else if (item is Clothing)
            {
                Clothing cloth         = (Clothing)item;
                Color    clothes_color = cloth.clothesColor;
                if (cloth.isPrismatic.Value)
                {
                    clothes_color = Utility.GetPrismaticColor();
                }
                if (cloth.clothesType.Value == 0)
                {
                    SpriteSheet      = FarmerRenderer.shirtsTexture;
                    srcRect          = new Rectangle(cloth.indexInTileSheetMale.Value * 8 % 128, cloth.indexInTileSheetMale.Value * 8 / 128 * 32, 8, 8);
                    originalPosition = Game1.GlobalToLocal(Game1.viewport, new Vector2(x * 64, y * 64 - 64));
                    position         = new Vector2(originalPosition.X + 20, originalPosition.Y + 64 + 20);
                    spriteBatch.Draw(SpriteSheet, position, srcRect, clothes_color, 0f, Vector2.Zero, 3f, SpriteEffects.None,
                                     ((float)(y * 64 + 32) / 10000f) + 0.002f);
                }
                else if (cloth.clothesType.Value == 1)
                {
                    SpriteSheet      = FarmerRenderer.pantsTexture;
                    srcRect          = new Rectangle(192 * (cloth.indexInTileSheetMale.Value % (FarmerRenderer.pantsTexture.Width / 192)), 688 * (cloth.indexInTileSheetMale.Value / (FarmerRenderer.pantsTexture.Width / 192)) + 672, 16, 16);
                    originalPosition = Game1.GlobalToLocal(Game1.viewport, new Vector2(x * 64, y * 64 - 64));
                    position         = new Vector2(originalPosition.X + 8, originalPosition.Y + 64 + 10);
                    spriteBatch.Draw(SpriteSheet, position, srcRect, clothes_color, 0f, Vector2.Zero, 3f, SpriteEffects.None,
                                     ((float)(y * 64 + 32) / 10000f) + 0.002f);
                }
            }
            else
            {
                SpriteSheet      = Game1.objectSpriteSheet;
                srcRect          = Game1.getSourceRectForStandardTileSheet(Game1.objectSpriteSheet, item.ParentSheetIndex, 16, 16);
                originalPosition = Game1.GlobalToLocal(Game1.viewport, new Vector2(x * 64, y * 64 - 64));
                position         = new Vector2(originalPosition.X + 17, originalPosition.Y + 64 + 17);
                spriteBatch.Draw(SpriteSheet, position, srcRect, Color.White, 0f, Vector2.Zero, 1.9f, SpriteEffects.None,
                                 ((float)(y * 64 + 32) / 10000f) + 0.002f);
            }
        }
Exemple #28
0
        private void Scrub(float timeDelta, GasVentScrubberComponent scrubber, GasMixture?tile, PipeNode outlet)
        {
            // Cannot scrub if tile is null or air-blocked.
            if (tile == null ||
                outlet.Air.Pressure >= 50 * Atmospherics.OneAtmosphere)    // Cannot scrub if pressure too high.
            {
                return;
            }

            // Take a gas sample.
            var ratio   = MathF.Min(1f, timeDelta * scrubber.TransferRate / tile.Volume);
            var removed = tile.RemoveRatio(ratio);

            // Nothing left to remove from the tile.
            if (MathHelper.CloseToPercent(removed.TotalMoles, 0f))
            {
                return;
            }

            if (scrubber.PumpDirection == ScrubberPumpDirection.Scrubbing)
            {
                _atmosphereSystem.ScrubInto(removed, outlet.Air, scrubber.FilterGases);

                // Remix the gases.
                _atmosphereSystem.Merge(tile, removed);
            }
            else if (scrubber.PumpDirection == ScrubberPumpDirection.Siphoning)
            {
                _atmosphereSystem.Merge(outlet.Air, removed);
            }
        }
Exemple #29
0
 public static int GetKept(this PipeNode target)
 {
     return((int)Fasterflect.FieldExtensions.GetFieldValue(target, "keptNumber"));
 }
    /// <summary>
    /// Determines which pipe sprite to use based on the number of neighbors
    /// and their orientation.
    /// </summary>
    /// <returns>The sprite based on the number of neighbors.</returns>
    /// <param name="index">Index of the current node on the path.</param>
    Sprite DeterminePipe(int index)
    {
        PipeNode currNode     = _path[index];
        int      numNeighbors = 0;

        // Check top node
        if (currNode.row - 1 >= 0 && _graph[currNode.row - 1, currNode.col].onPath)
        {
            numNeighbors++;
            currNode.neighbors.Add(PipeNode.NodePosition.TOP);
        }

        // Check bottom node
        if (currNode.row + 1 < NUM_ROWS && _graph[currNode.row + 1, currNode.col].onPath)
        {
            numNeighbors++;
            currNode.neighbors.Add(PipeNode.NodePosition.BOTTOM);
        }

        // Check left node
        if (currNode.col - 1 >= 0 && _graph[currNode.row, currNode.col - 1].onPath)
        {
            numNeighbors++;
            currNode.neighbors.Add(PipeNode.NodePosition.LEFT);
        }

        // Check right node
        if (currNode.col + 1 < NUM_COLS && _graph[currNode.row, currNode.col + 1].onPath)
        {
            numNeighbors++;
            currNode.neighbors.Add(PipeNode.NodePosition.RIGHT);
        }

        // Add a neighbor on the bottom for the last tile
        if (index == 0)
        {
            numNeighbors++;
            currNode.neighbors.Add(PipeNode.NodePosition.BOTTOM);
        }
        // Add a neighbor on the top for the first tile
        else if (index == _path.Count - 1)
        {
            numNeighbors++;
            currNode.neighbors.Add(PipeNode.NodePosition.TOP);
        }

        // Determine which sprite to use
        if (numNeighbors == 4)
        {
            currNode.pipeType = PipeNode.PipeType.CROSS;
            return(crossPipeSprite);
        }
        else if (numNeighbors == 3)
        {
            currNode.pipeType = PipeNode.PipeType.T;
            return(tPipeSprite);
        }
        else
        {
            if (index == 0 && currNode.col == _path[index + 1].col)
            {
                currNode.pipeType = PipeNode.PipeType.I;
                return(iPipeSprite);
            }
            else if (index == _path.Count - 1 && currNode.col == _path[index - 1].col)
            {
                currNode.pipeType = PipeNode.PipeType.I;
                return(iPipeSprite);
            }
            else if (index != 0 && index != _path.Count - 1 &&
                     (_path[index + 1].col == _path[index - 1].col ||
                      _path[index + 1].row == _path[index - 1].row))
            {
                currNode.pipeType = PipeNode.PipeType.I;
                return(iPipeSprite);
            }
            else
            {
                currNode.pipeType = PipeNode.PipeType.C;
                return(cPipeSprite);
            }
        }
    }