Example #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);
        }
Example #2
0
        public static void Init()
        {
            FluidInfo Water = new FluidInfo();
            FluidInfo Lava  = new FluidInfo();

            Water.source = ItemTypes.IndexLookup.GetIndex("GreatWater");
            Water.fake   = ItemTypes.IndexLookup.GetIndex("GreatWaterFake");
            Water.bucket = ItemTypes.IndexLookup.GetIndex("bucketwater");

            //Lava.source = ItemTypes.IndexLookup.GetIndex("Khanx.SimpleFluids.Lava");
            //Lava.fake = ItemTypes.IndexLookup.GetIndex("Khanx.SimpleFluids.Fake.Lava");
            //Lava.bucket = ItemTypes.IndexLookup.GetIndex("Khanx.SimpleFluids.LavaBucket");

            int w_spreadDistance = ConfigManager.GetConfigIntOrDefault(NewColonyAPIEntry.ModName, "fluids.water.spreaddistance", 8);

            if (w_spreadDistance > W_MAX_DISTANCE || w_spreadDistance < W_MIN_DISTANCE)
            {
                Helpers.Logging.WriteLog(NewColonyAPIEntry.ModName, string.Format("Water spreaddistance must be between {0} and {1}", W_MIN_DISTANCE, W_MAX_DISTANCE), Helpers.Logging.LogType.Loading);
                w_spreadDistance = W_DEFAULT_DISTANCE;
            }
            Water.distance = w_spreadDistance;
            long w_spreadSpeed = ConfigManager.GetConfigIntOrDefault(NewColonyAPIEntry.ModName, "fluids.water.spreadspeed", 350);

            if (w_spreadSpeed > W_MAX_SPEED || w_spreadSpeed < W_MIN_SPEED)
            {
                Helpers.Logging.WriteLog(NewColonyAPIEntry.ModName, string.Format("Water spreadspeed must be between {0} and {1}", W_MIN_SPEED, W_MAX_SPEED), Helpers.Logging.LogType.Loading);
                w_spreadSpeed = W_DEFAULT_SPEED;
            }
            Water.time = w_spreadSpeed;

            int l_spreadDistance = ConfigManager.GetConfigIntOrDefault(NewColonyAPIEntry.ModName, "fluids.lava.spreaddistance", 8);

            if (l_spreadDistance > L_MAX_DISTANCE || l_spreadDistance < L_MIN_DISTANCE)
            {
                Helpers.Logging.WriteLog(NewColonyAPIEntry.ModName, string.Format("Lava spreaddistance must be between {0} and {1}", L_MIN_DISTANCE, L_MAX_DISTANCE), Helpers.Logging.LogType.Loading);
                l_spreadDistance = L_DEFAULT_DISTANCE;
            }
            Lava.distance = l_spreadDistance;
            long l_spreadSpeed = ConfigManager.GetConfigIntOrDefault(NewColonyAPIEntry.ModName, "fluids.lava.spreadspeed", 350);

            if (l_spreadSpeed > L_MAX_SPEED || l_spreadSpeed < L_MIN_SPEED)
            {
                Helpers.Logging.WriteLog(NewColonyAPIEntry.ModName, string.Format("Lava spreadspeed must be between {0} and {1}", L_MIN_SPEED, L_MAX_SPEED), Helpers.Logging.LogType.Loading);
                w_spreadSpeed = L_DEFAULT_SPEED;
            }
            Lava.time = l_spreadSpeed;

            _fluids[(int)EFluids.Water] = Water;
            _fluids[(int)EFluids.Lava]  = Lava;

            _FluidsThread.IsBackground = true;
            _FluidsThread.Start();
        }
Example #3
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)
            {
                ThreadManager.InvokeOnMainThread(() =>
                {
                    if (World.TryGetTypeAt(position, out ushort posToRemove) && (posToRemove == info.fake))
                    {
                        ServerManager.TryChangeBlock(position, BlockTypes.BuiltinBlocks.Types.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.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();
                    }
                }
            }
        }
Example #4
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)
            {
                ThreadManager.InvokeOnMainThread(() =>
                {
                    if (World.TryGetTypeAt(position, out ushort posType) && (posType == BlockTypes.BuiltinBlocks.Types.air.ItemIndex || posType == info.fake))
                    {
                        ServerManager.TryChangeBlock(position, info.source);
                    }
                });
            }
            else
            {
                ThreadManager.InvokeOnMainThread(() =>
                {
                    if (World.TryGetTypeAt(position, out ushort posType) && (posType == BlockTypes.BuiltinBlocks.Types.air.ItemIndex))
                    {
                        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 || typeDown == BlockTypes.BuiltinBlocks.Types.water.ItemIndex)
            {
                return;
            }

            //If down is air or fake.fluid -> SPREAD DOWN
            if (typeDown == BlockTypes.BuiltinBlocks.Types.air.ItemIndex || 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.BuiltinBlocks.Types.air.ItemIndex || typeAdj == info.fake)
                {
                    var adjDown = adj + Vector3Int.down;

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

                    if (typeAdjD == info.source || typeAdjD == BlockTypes.BuiltinBlocks.Types.water.ItemIndex) // Source
                    {
                        continue;
                    }

                    //Continue spreading down
                    if (typeAdjD == BlockTypes.BuiltinBlocks.Types.air.ItemIndex)
                    {
                        _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();
                    }
                }
            }
        }