<commit_before>﻿using System;
using System.Collections.Generic;
using System.Text;
using Voxalia.Shared;
using BEPUutilities;
using BEPUphysics.BroadPhaseEntries;
using Voxalia.Shared.Files;
using Voxalia.Shared.Collision;
using Voxalia.ServerGame.EntitySystem;
using System.Threading;

namespace Voxalia.ServerGame.WorldSystem
{
    public class Chunk
    {
        public const int CHUNK_SIZE = FullChunkShape.CHUNK_SIZE;

        public const int RAM_USAGE = CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE * 5;

        public static List<Object> Lockers = new List<Object>();

        static Chunk()
        {
            Lockers = new List<Object>(21);
            for (int i = 0; i < 20; i++)
            {
                Lockers.Add(new Object());
            }
        }

        public Object GetLocker()
        {
            return Lockers[Math.Abs(WorldPosition.GetHashCode()) % 20];
        }

        public byte[] LOD = null;

        public bool LOD_Is_Air = false;

        public ChunkFlags Flags = ChunkFlags.NONE;
        
        public Region OwningRegion = null;

        public Vector3i WorldPosition;

        public volatile ASyncScheduleItem LoadSchedule = null;

        public Chunk()
        {
            BlocksInternal = new BlockInternal[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE];
        }

        public Chunk(byte[] _lod)
        {
            LOD = _lod;
            LOD_Is_Air = true;
            for (int i = 0; i < _lod.Length; i++)
            {
                if (_lod[i] != 0)
                {
                    LOD_Is_Air = false;
                    break;
                }
            }
        }

        public bool Contains(Location loc)
        {
            return loc.X >= WorldPosition.X * CHUNK_SIZE && loc.Y >= WorldPosition.Y * CHUNK_SIZE && loc.Z >= WorldPosition.Z * CHUNK_SIZE
                && loc.X < WorldPosition.X * CHUNK_SIZE + CHUNK_SIZE && loc.Y < WorldPosition.Y * CHUNK_SIZE + CHUNK_SIZE && loc.Z < WorldPosition.Z * CHUNK_SIZE + CHUNK_SIZE;
        }

        public BlockInternal[] BlocksInternal;

        public Material LODBlock(int x, int y, int z, int lod)
        {
            // TODO: Prefer maximum opaqueness.
            int xs = x * lod;
            int ys = y * lod;
            int zs = z * lod;
            for (int tz = lod - 1; tz >= 0; tz--)
            {
                Material c = GetBlockAt(xs, ys, zs + tz).Material;
                if (c != Material.AIR)
                {
                    return c;
                }
            }
            return Material.AIR;
        }
        
        /// <summary>
        /// Asyncable (math only).
        /// </summary>
        public int BlockIndex(int x, int y, int z)
        {
            return z * CHUNK_SIZE * CHUNK_SIZE + y * CHUNK_SIZE + x;<commit_msg>Improve LOD block stuff<commit_after>﻿using System;
using System.Collections.Generic;
using System.Text;
using Voxalia.Shared;
using BEPUutilities;
using BEPUphysics.BroadPhaseEntries;
using Voxalia.Shared.Files;
using Voxalia.Shared.Collision;
using Voxalia.ServerGame.EntitySystem;
using System.Threading;

namespace Voxalia.ServerGame.WorldSystem
{
    public class Chunk
    {
        public const int CHUNK_SIZE = FullChunkShape.CHUNK_SIZE;

        public const int RAM_USAGE = CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE * 5;

        public static List<Object> Lockers = new List<Object>();

        static Chunk()
        {
            Lockers = new List<Object>(21);
            for (int i = 0; i < 20; i++)
            {
                Lockers.Add(new Object());
            }
        }

        public Object GetLocker()
        {
            return Lockers[Math.Abs(WorldPosition.GetHashCode()) % 20];
        }

        public byte[] LOD = null;

        public bool LOD_Is_Air = false;

        public ChunkFlags Flags = ChunkFlags.NONE;
        
        public Region OwningRegion = null;

        public Vector3i WorldPosition;

        public volatile ASyncScheduleItem LoadSchedule = null;

        public Chunk()
        {
            BlocksInternal = new BlockInternal[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE];
        }

        public Chunk(byte[] _lod)
        {
            LOD = _lod;
            LOD_Is_Air = true;
            for (int i = 0; i < _lod.Length; i++)
            {
                if (_lod[i] != 0)
                {
                    LOD_Is_Air = false;
                    break;
                }
            }
        }

        public bool Contains(Location loc)
        {
            return loc.X >= WorldPosition.X * CHUNK_SIZE && loc.Y >= WorldPosition.Y * CHUNK_SIZE && loc.Z >= WorldPosition.Z * CHUNK_SIZE
                && loc.X < WorldPosition.X * CHUNK_SIZE + CHUNK_SIZE && loc.Y < WorldPosition.Y * CHUNK_SIZE + CHUNK_SIZE && loc.Z < WorldPosition.Z * CHUNK_SIZE + CHUNK_SIZE;
        }

        public BlockInternal[] BlocksInternal;

        public Material LODBlock(int x, int y, int z, int lod)
        {
            int xs = x * lod;
            int ys = y * lod;
            int zs = z * lod;
            Material mat = Material.AIR;
            for (int tz = lod - 1; tz >= 0; tz--)
            {
                Material c = GetBlockAt(xs, ys, zs + tz).Material;
                if (c.IsOpaque())
                {
                    return c;
                }
                else if (c != Material.AIR)
                {
                    mat = c;
                }
            }
            return mat;
        }
        
        /// <summary>
        /// Asyncable (math only).
        /// </summary>
        public int BlockIndex(int x, int y, int z)
        {
            return z * CHUNK_SIZE * CHUNK_SIZE + y * CHUNK_SIZE + x;
{'fraction_non_alphanumeric': 0.09536354056902002, 'fraction_numerical': 0.0045662100456621, 'mean_word_length': 1.4728614850195398, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '961242', 'n_tokens_mistral': 1728, 'n_tokens_neox': 1671, 'n_words': 428}