private void cmdSnowAccum(IServerPlayer player, int groupId, CmdArgs args)
        {
            WeatherSystemServer wsys = api.ModLoader.GetModSystem <WeatherSystemServer>();

            string cmd = args.PopWord();

            if (cmd == "on")
            {
                wsys.snowSimSnowAccu.ProcessChunks = true;
                player.SendMessage(groupId, "Snow accum process chunks on", EnumChatType.CommandSuccess);
                return;
            }

            if (cmd == "off")
            {
                wsys.snowSimSnowAccu.ProcessChunks = false;
                player.SendMessage(groupId, "Snow accum process chunks off", EnumChatType.CommandSuccess);
                return;
            }

            if (cmd == "processhere")
            {
                BlockPos plrPos    = player.Entity.Pos.AsBlockPos;
                int      chunksize = api.World.BlockAccessor.ChunkSize;
                Vec2i    chunkPos  = new Vec2i(plrPos.X / chunksize, plrPos.Z / chunksize);

                wsys.snowSimSnowAccu.AddToCheckQueue(chunkPos);
                player.SendMessage(groupId, "Ok, added to check queue", EnumChatType.CommandSuccess);
                return;
            }

            if (cmd == "info")
            {
                BlockPos        plrPos    = player.Entity.Pos.AsBlockPos;
                int             chunksize = api.World.BlockAccessor.ChunkSize;
                Vec2i           chunkPos  = new Vec2i(plrPos.X / chunksize, plrPos.Z / chunksize);
                IServerMapChunk mc        = sapi.WorldManager.GetMapChunk(chunkPos.X, chunkPos.Y);

                double lastSnowAccumUpdateTotalHours = mc.GetModdata <double>("lastSnowAccumUpdateTotalHours");

                player.SendMessage(groupId, "lastSnowAccumUpdateTotalHours: " + lastSnowAccumUpdateTotalHours, EnumChatType.CommandSuccess);

                int regionX = (int)player.Entity.Pos.X / sapi.World.BlockAccessor.RegionSize;
                int regionZ = (int)player.Entity.Pos.Z / sapi.World.BlockAccessor.RegionSize;

                WeatherSystemServer wsysServer = sapi.ModLoader.GetModSystem <WeatherSystemServer>();
                long index2d = wsysServer.MapRegionIndex2D(regionX, regionZ);
                WeatherSimulationRegion simregion;
                wsysServer.weatherSimByMapRegion.TryGetValue(index2d, out simregion);

                int reso = WeatherSimulationRegion.snowAccumResolution;

                SnowAccumSnapshot sumsnapshot = new SnowAccumSnapshot()
                {
                    //SumTemperatureByRegionCorner = new API.FloatDataMap3D(reso, reso, reso),
                    SnowAccumulationByRegionCorner = new FloatDataMap3D(reso, reso, reso)
                };
                float[] sumdata = sumsnapshot.SnowAccumulationByRegionCorner.Data;

                // Can't grow bigger than one full snow block
                float max = 3 + 0.5f;

                int len = simregion.SnowAccumSnapshots.Length;
                int i   = simregion.SnowAccumSnapshots.Start;

                // This code here causes wacky snow patterns
                // The lerp itself is fine!!!
                while (len-- > 0)
                {
                    SnowAccumSnapshot hoursnapshot = simregion.SnowAccumSnapshots[i];
                    i = (i + 1) % simregion.SnowAccumSnapshots.Length;

                    float[] snowaccumdata = hoursnapshot.SnowAccumulationByRegionCorner.Data;
                    for (int j = 0; j < snowaccumdata.Length; j++)
                    {
                        sumdata[j] = GameMath.Clamp(sumdata[j] + snowaccumdata[j], -max, max);
                    }

                    lastSnowAccumUpdateTotalHours = Math.Max(lastSnowAccumUpdateTotalHours, hoursnapshot.TotalHours);
                }



                for (int j = 0; j < sumdata.Length; j++)
                {
                    player.SendMessage(groupId, j + ": " + sumdata[j], EnumChatType.CommandSuccess);
                }

                return;
            }

            if (cmd == "here")
            {
                float amount = (float)args.PopFloat(0);

                BlockPos        plrPos    = player.Entity.Pos.AsBlockPos;
                int             chunksize = api.World.BlockAccessor.ChunkSize;
                Vec2i           chunkPos  = new Vec2i(plrPos.X / chunksize, plrPos.Z / chunksize);
                IServerMapChunk mc        = sapi.WorldManager.GetMapChunk(chunkPos.X, chunkPos.Y);
                int             reso      = WeatherSimulationRegion.snowAccumResolution;

                SnowAccumSnapshot sumsnapshot = new SnowAccumSnapshot()
                {
                    SumTemperatureByRegionCorner   = new FloatDataMap3D(reso, reso, reso),
                    SnowAccumulationByRegionCorner = new FloatDataMap3D(reso, reso, reso)
                };

                sumsnapshot.SnowAccumulationByRegionCorner.Data.Fill(amount);

                var updatepacket = wsys.snowSimSnowAccu.UpdateSnowLayer(sumsnapshot, true, mc, chunkPos, null);
                wsys.snowSimSnowAccu.accum = 1f;

                var ba = sapi.World.GetBlockAccessorBulkMinimalUpdate(true, false);
                ba.UpdateSnowAccumMap = false;

                wsys.snowSimSnowAccu.processBlockUpdates(mc, updatepacket, ba);
                ba.Commit();

                player.SendMessage(groupId, "Ok, test snow accum gen complete", EnumChatType.CommandSuccess);
                return;
            }
        }
        private UpdateSnowLayerChunk GetSnowUpdate(WeatherSimulationRegion simregion, IServerMapChunk mc, Vec2i chunkPos, IWorldChunk[] chunksCol)
        {
            double lastSnowAccumUpdateTotalHours = mc.GetModdata <double>("lastSnowAccumUpdateTotalHours");
            double startTotalHours = lastSnowAccumUpdateTotalHours;

            int reso = WeatherSimulationRegion.snowAccumResolution;

            SnowAccumSnapshot sumsnapshot = new SnowAccumSnapshot()
            {
                SnowAccumulationByRegionCorner = new FloatDataMap3D(reso, reso, reso)
            };

            float[] sumdata = sumsnapshot.SnowAccumulationByRegionCorner.Data;

            // Can't grow bigger than one full snow block
            float max = ws.GeneralConfig.SnowLayerBlocks.Count + 0.6f;

            int len      = simregion.SnowAccumSnapshots.Length;
            int i        = simregion.SnowAccumSnapshots.Start;
            int newCount = 0;

            lock (WeatherSimulationRegion.snowAccumSnapshotLock)
            {
                while (len-- > 0)
                {
                    SnowAccumSnapshot hoursnapshot = simregion.SnowAccumSnapshots[i];
                    i = (i + 1) % simregion.SnowAccumSnapshots.Length;

                    if (hoursnapshot == null || lastSnowAccumUpdateTotalHours >= hoursnapshot.TotalHours)
                    {
                        continue;
                    }

                    float[] snowaccumdata = hoursnapshot.SnowAccumulationByRegionCorner.Data;
                    for (int j = 0; j < snowaccumdata.Length; j++)
                    {
                        sumdata[j] = GameMath.Clamp(sumdata[j] + snowaccumdata[j], -max, max);
                    }

                    lastSnowAccumUpdateTotalHours = Math.Max(lastSnowAccumUpdateTotalHours, hoursnapshot.TotalHours);
                    newCount++;
                }
            }

            if (newCount == 0)
            {
                return(null);
            }

            bool ignoreOldAccum = false;

            if (lastSnowAccumUpdateTotalHours - startTotalHours >= sapi.World.Calendar.DaysPerYear * sapi.World.Calendar.HoursPerDay)
            {
                ignoreOldAccum = true;
            }

            UpdateSnowLayerChunk ch = UpdateSnowLayer(sumsnapshot, ignoreOldAccum, mc, chunkPos, chunksCol);

            if (ch != null)
            {
                ch.LastSnowAccumUpdateTotalHours = lastSnowAccumUpdateTotalHours;
                ch.Coords = chunkPos.Copy();
            }
            return(ch);
        }