Esempio n. 1
0
        public static Vector3Int ClosestSource(Vector3Int position, EFluids fluid)
        {
            FluidInfo info = _fluids[(int)fluid];

            LinkedList <Tuple <Vector3Int, int> > toVisit = new LinkedList <Tuple <Vector3Int, int> >();

            toVisit.AddLast(new Tuple <Vector3Int, int>(position, 0));

            List <Vector3Int> alreadyVisited = new List <Vector3Int>();

            while (toVisit.Count > 0)
            {
                var node = toVisit.First.Value;
                toVisit.RemoveFirst();

                if (alreadyVisited.Contains(node.Item1))
                {
                    continue;
                }

                alreadyVisited.Add(node.Item1);

                if (node.Item2 == info.distance)
                {
                    continue;
                }

                foreach (var adjacent in adjacents)
                {
                    var adj = node.Item1 + adjacent;

                    if (!World.TryGetTypeAt(adj, out ushort typeadj))
                    {
                        continue;
                    }

                    if (typeadj == info.source)
                    {
                        return(adj);
                    }

                    if (typeadj == info.fake)
                    {
                        if (!alreadyVisited.Contains(adj))
                        {
                            toVisit.AddLast(new Tuple <Vector3Int, int>(adj, node.Item2 + 1));
                        }
                    }
                }
            }

            return(Vector3Int.maximum);
        }
Esempio n. 2
0
        public static void TryRemove(Vector3Int position, EFluids fluid, int distance = int.MinValue)
        {
            //Log.Write(string.Format("<color=blue>TryRemove {0}</color>", position));

            FluidInfo info = _fluids[(int)fluid];

            if(!World.TryGetTypeAt(position, out ushort typeToRemove) && ( typeToRemove != info.source && typeToRemove != info.fake ))
                return;

            if(distance == int.MinValue)
                distance = info.distance;

            if(distance < 0)
                return;

            if(!World.TryGetTypeAt(position, out ushort type))
                return;

            if(type != info.fake)
                return;

            if(ClosestSource(position, fluid) == Vector3Int.maximum)
            {
                Pipliz.Threading.ThreadManager.InvokeOnMainThread(() =>
                {
                    if(World.TryGetTypeAt(position, out ushort posToRemove) && ( posToRemove == info.fake ))
                        ServerManager.TryChangeBlock(position, BlockTypes.Builtin.BuiltinBlocks.Air);
                });
            }

            var down = position + Vector3Int.down;

            if(!World.TryGetTypeAt(down, out ushort typeDown))
                return;

            if(typeDown == info.source)
            {
                _actions.Add(Time.MillisecondsSinceStart + info.time, delegate ()
                {
                    Remove(down, fluid);
                });

                _SomeAction.Set();
                return;
            }

            foreach(var adjacent in adjacents)
            {
                var adj = position + adjacent;

                if(!World.TryGetTypeAt(adj, out ushort typeAdj))
                    continue;

                if(typeAdj == info.fake)
                {
                    _actions.Add(Time.MillisecondsSinceStart + info.time, delegate ()
                    {
                        TryRemove(adj, fluid, distance - 1);
                    });

                    _SomeAction.Set();
                }
                else if(typeAdj == BlockTypes.Builtin.BuiltinBlocks.Air)
                {
                    var adjD = adj + Vector3Int.down;

                    if(!World.TryGetTypeAt(adjD, out ushort typeAdjD))
                        continue;

                    if(typeAdjD == info.source)
                    {
                        _actions.Add(Time.MillisecondsSinceStart + info.time, delegate ()
                        {
                            Remove(adjD, fluid);
                        });

                        _SomeAction.Set();
                    }
                }
            }
        }
Esempio n. 3
0
        public static void Spread(Vector3Int position, EFluids fluid, int distance = int.MinValue, bool start = true)
        {
            //Log.Write(string.Format("<color=blue>Spread {0}</color>", position));

            FluidInfo info = _fluids[(int)fluid];

            if(distance == int.MinValue)
                distance = info.distance;

            if(distance <= 0)
                return;

            if(start)
            {
                Pipliz.Threading.ThreadManager.InvokeOnMainThread(() =>
                {
                    if(World.TryGetTypeAt(position, out ushort posType) && ( posType == BlockTypes.Builtin.BuiltinBlocks.Air || posType == info.fake ))
                        ServerManager.TryChangeBlock(position, info.source);
                });
            }
            else
            {
                Pipliz.Threading.ThreadManager.InvokeOnMainThread(() =>
                {
                    if(World.TryGetTypeAt(position, out ushort posType) && ( posType == BlockTypes.Builtin.BuiltinBlocks.Air ))
                        ServerManager.TryChangeBlock(position, info.fake);
                });
            }

            var down = position + Vector3Int.down;

            if(!World.TryGetTypeAt(down, out ushort typeDown))
                return;

            //If DOWN is source -> IGNORE
            if(typeDown == info.source)
                return;

            //If down is air or fake.fluid -> SPREAD DOWN
            if(typeDown == BlockTypes.Builtin.BuiltinBlocks.Air || typeDown == info.fake)
            {
                _actions.Add(Time.MillisecondsSinceStart + info.time, delegate ()
                {
                    Spread(down, fluid);
                });

                _SomeAction.Set();
                return;
            }

            foreach(var adjacent in adjacents)
            {
                var adj = position + adjacent;

                if(!World.TryGetTypeAt(adj, out ushort typeAdj))
                    continue;

                if(typeAdj == BlockTypes.Builtin.BuiltinBlocks.Air || typeAdj == info.fake)
                {
                    var adjDown = adj + Vector3Int.down;

                    if(!World.TryGetTypeAt(adjDown, out ushort typeAdjD))
                        continue;

                    if(typeAdjD == info.source) // Source
                        continue;

                    //Continue spreading down
                    if(typeAdjD == BlockTypes.Builtin.BuiltinBlocks.Air)
                    {
                        _actions.Add(Time.MillisecondsSinceStart + info.time, delegate ()
                        {
                            Spread(adjDown, fluid);
                        });

                        _SomeAction.Set();
                    }
                    else //Spread Side
                    {
                        _actions.Add(Time.MillisecondsSinceStart + info.time, delegate ()
                        {
                            Spread(adj, fluid, distance - 1, false);
                        });

                        _SomeAction.Set();
                    }
                }
            }
        }
Esempio n. 4
0
        public static void Remove(Vector3Int position, EFluids fluid, ushort newType = ushort.MaxValue)
        {
            //Log.Write(string.Format("<color=blue>Remove {0}</color>", position));

            FluidInfo info = _fluids[(int)fluid];

            if (!World.TryGetTypeAt(position, out ushort posToRemove) && (posToRemove != info.source && posToRemove != info.fake))
            {
                return;
            }

            ThreadManager.InvokeOnMainThread(() =>
            {
                if (newType == ushort.MaxValue)
                {
                    ServerManager.TryChangeBlock(position, BlockTypes.BuiltinBlocks.Types.air);
                }
                else
                {
                    ServerManager.TryChangeBlock(position, newType);
                }
            });

            var down = position + Vector3Int.down;

            if (!World.TryGetTypeAt(down, out ushort typeDown))
            {
                return;
            }

            //If DOWN is source
            if (typeDown == info.source)
            {
                _actions.Add(Time.MillisecondsSinceStart + info.time, delegate()
                {
                    Remove(down, fluid);
                });

                _SomeAction.Set();
                return;
            }

            foreach (var adjacent in adjacents)
            {
                var adj = position + adjacent;

                if (!World.TryGetTypeAt(adj, out ushort typeAdj))
                {
                    continue;
                }

                if (typeAdj == info.fake)
                {
                    _actions.Add(Time.MillisecondsSinceStart + info.time, delegate()
                    {
                        TryRemove(adj, fluid, info.distance - 1);
                    });

                    _SomeAction.Set();
                }
                else if (typeAdj == BlockTypes.BuiltinBlocks.Types.air.ItemIndex)
                {
                    var adjD = adj + Vector3Int.down;

                    if (!World.TryGetTypeAt(adjD, out ushort typeAdjD))
                    {
                        continue;
                    }

                    if (typeAdjD == info.source)
                    {
                        _actions.Add(Time.MillisecondsSinceStart + info.time, delegate()
                        {
                            Remove(adjD, fluid);
                        });

                        _SomeAction.Set();
                    }
                }
            }
        }