Пример #1
0
        public void render()
        {
            for (int x = 0; x < tiles.GetLength(0); x++)
            {
                for (int y = 0; y < tiles.GetLength(1); y++)
                {
                    Engine.Engine.Draw(tiles[x, y].GetSprite(), new IntVec(x, y));
                }
            }

            Environment.Draw();
            //drawAStar();
            InteractableEnvironment.Draw();

            DroppedItems.Draw();
            LightSources.Draw();
            CharacterEntities.Draw();

            //CharacterEntities.InvokeOnAll( (GameCharacter character, IntVec position) =>
            //{
            //    position.X += character.GetSprite().Direction.X;
            //    position.Y += character.GetSprite().Direction.Y;
            //});

            //foreach (var pair in CharacterEntities.Tuples())
            //{
            //    pair.Item2.X += pair.Item1.GetSprite().Direction.X;
            //    pair.Item2.Y += pair.Item1.GetSprite().Direction.Y;
            //}
        }
Пример #2
0
        private void cache()
        {
            if (needToCache)
            {
                for (int x = 0; x < tiles.GetLength(0); x++)
                {
                    for (int y = 0; y < tiles.GetLength(1); y++)
                    {
                        cachedSolid[x, y] = tiles[x, y].isSolid;
                    }
                }

                foreach (IntVec position in CharacterEntities.Positions())
                {
                    cachedSolid[position.X, position.Y] = true;
                }

                foreach (Tuple <IEnvironmentObject, IntVec> enviro in Environment.Tuples())
                {
                    cachedSolid[enviro.Item2.X, enviro.Item2.Y] |= enviro.Item1.IsSolid();
                }

                foreach (Tuple <IInteractable, IntVec> enviro in InteractableEnvironment.Tuples())
                {
                    cachedSolid[enviro.Item2.X, enviro.Item2.Y] |= enviro.Item1.IsSolid();
                }

                foreach (Tuple <ILightSource, IntVec> enviro in LightSources.Tuples())
                {
                    //cachedSolid[enviro.Item2.X, enviro.Item2.Y] = true;
                }
                needToCache = false;
            }
        }
Пример #3
0
        public override void RemoveInvalidBlocks()
        {
            this._blockRefCount = 0;
            this._tickRefCount  = 0;

            for (int x = 0; x < 16; x++)
            {
                for (int y = 0; y < 16; y++)
                {
                    for (int z = 0; z < 16; z++)
                    {
                        var idx = GetCoordinateIndex(x, y, z);

                        var blockstate = this.Get(x, y, z, 0);//.Block;
                        if (blockstate == null)
                        {
                            continue;
                        }

                        var block = blockstate.Block;
                        //TransparentBlocks.Set(idx, block.Transparent);
                        // SolidBlocks.Set(idx, block.Solid);

                        if (!(block is Air))
                        {
                            ++this._blockRefCount;

                            if (block.RandomTicked)
                            {
                                ++this._tickRefCount;
                            }

                            if (block.BlockMaterial.IsWatterLoggable)
                            {
                                Set(1, x, y, z, BlockFactory.GetBlockState("minecraft:water"));
                            }
                        }

                        if (block.LightValue > 0)
                        {
                            var coords = new BlockCoordinates(x, y, z);

                            if (!LightSources.Contains(coords))
                            {
                                LightSources.Add(coords);
                            }

                            if (GetBlocklight(x, y, z) != block.LightValue)
                            {
                                SetBlocklight(x, y, z, (byte)block.LightValue);
                                SetBlockLightScheduled(x, y, z, true);
                            }
                        }
                    }
                }
            }
        }
Пример #4
0
        public void RemoveInvalidBlocks()
        {
            this._blockRefCount = 0;
            this._tickRefCount  = 0;

            for (int x = 0; x < 16; x++)
            {
                for (int y = 0; y < 16; y++)
                {
                    for (int z = 0; z < 16; z++)
                    {
                        var idx = GetCoordinateIndex(x, y, z);

                        //foreach (var state in this.GetAll(x, y, z))
                        {
                            var block = this.Get(x, y, z, 0).Block;

                            TransparentBlocks.Set(idx, block.Transparent);
                            SolidBlocks.Set(idx, block.Solid);

                            if (!(block is Air))
                            {
                                ++this._blockRefCount;

                                if (block.RandomTicked)
                                {
                                    ++this._tickRefCount;
                                }
                            }

                            if (Alex.ServerType == ServerType.Java)
                            {
                                if (block.LightValue > 0)
                                {
                                    var coords = new BlockCoordinates(x, y, z);

                                    if (!LightSources.Contains(coords))
                                    {
                                        LightSources.Add(coords);
                                    }

                                    if (GetBlocklight(x, y, z) != block.LightValue)
                                    {
                                        SetBlocklight(x, y, z, (byte)block.LightValue);
                                        SetBlockLightScheduled(x, y, z, true);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            //CheckForSolidBorder();
        }
Пример #5
0
        protected internal override void UnloadContent()
        {
            particleEffectSheet = null;
            lightSheet          = null;
            lightSourceMap.Dispose();

            LightSources.Clear();
            LightSources = null;
            Effects.Clear();
            Effects = null;
        }
Пример #6
0
        private void UpdateLightSources()
        {
            var isPlaced = (Game1.currentLocation as DecoratableLocation)?.furniture.Contains(this) ?? false;

            foreach (var kv in LightSources.ToList())
            {
                if (ItemProvider.Contains(kv.Key) && isPlaced && GlowConfig.ShowLights)
                {
                    Game1.currentLightSources.Add(kv.Value);
                }
                else
                {
                    LightSources.Remove(kv.Key);
                    Game1.currentLightSources.Remove(kv.Value);
                }
            }
        }
Пример #7
0
        private void RenderGraphicsToScreen()
        {
            OpenGLUtil.UseFrameBuffer(0);     // make sure we are rendering to the screen
            GL.Viewport(0, 0, Width, Height); // set view prot to cover full window
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            mainProgram.UseProgram();

            // camera properties
            Matrix4 proj = Matrix4.CreatePerspectiveFieldOfView(Camera.VertFOV, Camera.AspectRatio, Camera.MinRange, Camera.MaxRange); // camera props
            Matrix4 view = Matrix4.LookAt(Camera.Pos.ToGLVector3(), Camera.LookAtPos.ToGLVector3(), Camera.UpDir.ToGLVector3());       // camera state

            mainProgram.SetCameraPosition(Camera.Pos.ToGLVector3());

            // light/shadow properties
            mainProgram.AddLights(openGLLights.ToArray());

            // material properties
            float   shininess     = 50.0f;
            Vector3 specularColor = (Color.White.ToGLVector3());

            mainProgram.SetMaterialProperties(specularColor, shininess);

            mainProgram.EnableAttributes();
            mainProgram.LoadBuffer(vertexBufferID);

            int startIndex = 0;

            foreach (IGraphicalBody body in Bodies)
            {
                // get the model matrix and send it
                Matrix4 scale       = Matrix4.Identity;
                Matrix4 rotation    = Matrix4.CreateFromQuaternion(body.Orientation.ToGLQuaternion());
                Matrix4 translation = Matrix4.CreateTranslation(body.Translation.ToGLVector3());
                Matrix4 model       = scale * rotation * translation;
                mainProgram.SetMVP(model, view, proj);
                mainProgram.SetShadowCasterMVPs(LightSources.Select((l, i) => model * depthViews[i] * depthProjs[i]).ToArray());

                int numVerts = body.Triangles.Length * 3;
                GL.DrawArrays(PrimitiveType.Triangles, startIndex, numVerts);
                startIndex += numVerts;
            }
            mainProgram.DisableAttributes();
        }
Пример #8
0
        private void UpdateItemGlow(Item item, SpriteBatch spriteBatch, Vector2 viewPosition, float alpha, float scaleSize, DepthProvider depthProvider)
        {
            var color = GetItemGlowColor(item);

            if (color == null)
            {
                return;
            }

            var isDarkItem = (color == Color.Black);

            if (GlowConfig.ShowGlows)
            {
                var colorAlpha = isDarkItem ? 0.8f : 0.6f;
                spriteBatch.Draw(
                    GlowTexture,
                    viewPosition + TileSize / 2 * (scaleSize * Config.Layout.Scale / Game1.pixelZoom),
                    GlowTexture.Bounds,
                    color.Value * colorAlpha * alpha,
                    0,
                    GlowTexture.Bounds.Center.ToVector(),
                    4f * (scaleSize * Config.Layout.Scale / Game1.pixelZoom),
                    SpriteEffects.None,
                    depthProvider.GetDepth());
            }

            if (isDarkItem || !GlowConfig.ShowLights)
            {
                return;
            }

            if (!LightSources.TryGetValue(item, out var light))
            {
                light = new LightSource(LightSource.lantern, Vector2.Zero, 32f / Game1.options.lightingQuality);
                LightSources.Add(item, light);
            }
            light.position = viewPosition + new Vector2(Game1.viewport.X, Game1.viewport.Y) + TileSize / 2;
        }
Пример #9
0
        private void RenderVR(Matrix4 viewProjMatrix, Vector3 camPos)
        {
            mainProgram.UseProgram();

            // camera properties
            mainProgram.SetCameraPosition(camPos);

            // light/shadow properties
            mainProgram.AddLights(openGLLights.ToArray());

            // material properties
            float   shininess     = 50.0f;
            Vector3 specularColor = (Color.White.ToGLVector3());

            mainProgram.SetMaterialProperties(specularColor, shininess);

            mainProgram.EnableAttributes();
            mainProgram.LoadBuffer(vertexBufferID);

            int startIndex = 0;

            foreach (IGraphicalBody body in Bodies)
            {
                // get the model matrix and send it
                Matrix4 scale       = Matrix4.Identity;
                Matrix4 rotation    = Matrix4.CreateFromQuaternion(body.Orientation.ToGLQuaternion());
                Matrix4 translation = Matrix4.CreateTranslation(body.Translation.ToGLVector3());
                Matrix4 model       = scale * rotation * translation;
                mainProgram.SetMVP(viewProjMatrix, model);
                mainProgram.SetShadowCasterMVPs(LightSources.Select((l, i) => model * depthViews[i] * depthProjs[i]).ToArray());

                int numVerts = body.Triangles.Length * 3;
                GL.DrawArrays(PrimitiveType.Triangles, startIndex, numVerts);
                startIndex += numVerts;
            }
            mainProgram.DisableAttributes();
        }
Пример #10
0
        public StarSystem(UniverseIni universe, Section section, FreelancerData data)
            : base(data)
        {
            if (universe == null)
            {
                throw new ArgumentNullException("universe");
            }
            if (section == null)
            {
                throw new ArgumentNullException("section");
            }
            string file = null;

            foreach (Entry e in section)
            {
                switch (e.Name.ToLowerInvariant())
                {
                case "nickname":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (Nickname != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    Nickname = e[0].ToString();
                    break;

                case "file":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (file != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    file = e[0].ToString();
                    break;

                case "pos":
                    if (e.Count != 2)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (Pos != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    Pos = new Vector2(e[0].ToSingle(), e[1].ToSingle());
                    break;

                case "msg_id_prefix":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (MsgIdPrefix != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    MsgIdPrefix = e[0].ToString();
                    break;

                case "visit":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (Visit != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    Visit = e[0].ToInt32();
                    break;

                case "strid_name":
                    if (e.Count == 0)
                    {
                        break;
                    }
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (IdsName != 0)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    IdsName = e[0].ToInt32();
                    break;

                case "ids_info":
                    if (e.Count == 0)
                    {
                        break;
                    }
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (IdsInfo != 0)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    IdsInfo = e[0].ToInt32();
                    break;

                case "navmapscale":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (NavMapScale != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    NavMapScale = e[0].ToSingle();
                    break;

                default:
                    throw new Exception("Invalid Entry in " + section.Name + ": " + e.Name);
                }
            }

            if (file == null)               //TODO: MultiUniverse
            {
                FLLog.Warning("Ini", "Unimplemented: Possible MultiUniverse system " + Nickname);
                MultiUniverse = true;
                return;
            }

            foreach (Section s in ParseFile(GameData.Freelancer.DataPath + "universe\\" + file))
            {
                switch (s.Name.ToLowerInvariant())
                {
                case "systeminfo":
                    foreach (Entry e in s)
                    {
                        switch (e.Name.ToLowerInvariant())
                        {
                        case "name":
                            if (e.Count != 1)
                            {
                                throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count);
                            }
                            if (Name != null)
                            {
                                throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name);
                            }
                            Name = e[0].ToString();
                            break;

                        case "space_color":
                            if (e.Count != 3)
                            {
                                throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count);
                            }
                            if (SpaceColor != null)
                            {
                                throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name);
                            }
                            SpaceColor = new Color4(e[0].ToInt32() / 255f, e[1].ToInt32() / 255f, e[2].ToInt32() / 255f, 1f);
                            break;

                        case "local_faction":
                            if (e.Count != 1)
                            {
                                throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count);
                            }
                            if (LocalFaction != null)
                            {
                                throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name);
                            }
                            LocalFaction = e[0].ToString();
                            break;

                        case "rpop_solar_detection":
                            if (e.Count != 1)
                            {
                                throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count);
                            }
                            if (RpopSolarDetection != null)
                            {
                                throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name);
                            }
                            RpopSolarDetection = e[0].ToBoolean();
                            break;

                        case "space_farclip":
                            if (SpaceFarClip != null)
                            {
                                throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name);
                            }
                            SpaceFarClip = e[0].ToSingle();
                            break;

                        default:
                            throw new Exception("Invalid Entry in " + section.Name + ": " + e.Name);
                        }
                    }
                    break;

                case "music":
                    foreach (Entry e in s)
                    {
                        switch (e.Name.ToLowerInvariant())
                        {
                        case "space":
                            if (e.Count != 1)
                            {
                                throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count);
                            }
                            if (MusicSpace != null)
                            {
                                throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name);
                            }
                            MusicSpace = e[0].ToString();
                            break;

                        case "danger":
                            if (e.Count != 1)
                            {
                                throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count);
                            }
                            if (MusicDanger != null)
                            {
                                throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name);
                            }
                            MusicDanger = e[0].ToString();
                            break;

                        case "battle":
                            if (e.Count != 1)
                            {
                                throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count);
                            }
                            if (MusicBattle != null)
                            {
                                throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name);
                            }
                            MusicBattle = e[0].ToString();
                            break;

                        default:
                            throw new Exception("Invalid Entry in " + section.Name + ": " + e.Name);
                        }
                    }
                    break;

                case "archetype":
                    foreach (Entry e in s)
                    {
                        switch (e.Name.ToLowerInvariant())
                        {
                        case "ship":
                            if (e.Count != 1)
                            {
                                throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count);
                            }
                            if (ArchetypeShip == null)
                            {
                                ArchetypeShip = new List <string>();
                            }
                            ArchetypeShip.Add(e[0].ToString());
                            break;

                        case "simple":
                            if (e.Count != 1)
                            {
                                throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count);
                            }
                            if (ArchetypeSimple == null)
                            {
                                ArchetypeSimple = new List <string>();
                            }
                            ArchetypeSimple.Add(e[0].ToString());
                            break;

                        case "solar":
                            if (e.Count != 1)
                            {
                                throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count);
                            }
                            if (ArchetypeSolar == null)
                            {
                                ArchetypeSolar = new List <string>();
                            }
                            ArchetypeSolar.Add(e[0].ToString());
                            break;

                        case "equipment":
                            if (e.Count != 1)
                            {
                                throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count);
                            }
                            if (ArchetypeEquipment == null)
                            {
                                ArchetypeEquipment = new List <string>();
                            }
                            ArchetypeEquipment.Add(e[0].ToString());
                            break;

                        case "snd":
                            if (e.Count != 1)
                            {
                                throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count);
                            }
                            if (ArchetypeSnd == null)
                            {
                                ArchetypeSnd = new List <string>();
                            }
                            ArchetypeSnd.Add(e[0].ToString());
                            break;

                        case "voice":
                            if (ArchetypeVoice == null)
                            {
                                ArchetypeVoice = new List <List <string> >();
                            }
                            ArchetypeVoice.Add(new List <string>());
                            foreach (IValue i in e)
                            {
                                ArchetypeVoice[ArchetypeVoice.Count - 1].Add(i.ToString());
                            }
                            break;

                        default:
                            throw new Exception("Invalid Entry in " + s.Name + ": " + e.Name);
                        }
                    }
                    break;

                case "dust":
                    foreach (Entry e in s)
                    {
                        switch (e.Name.ToLowerInvariant())
                        {
                        case "spacedust":
                            if (e.Count != 1)
                            {
                                throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count);
                            }
                            if (Spacedust != null)
                            {
                                throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name);
                            }
                            Spacedust = e[0].ToString();
                            break;

                        default:
                            throw new Exception("Invalid Entry in " + s.Name + ": " + e.Name);
                        }
                    }
                    break;

                case "nebula":
                    if (Nebulae == null)
                    {
                        Nebulae = new List <Nebula>();
                    }
                    Nebulae.Add(new Nebula(this, s, GameData));
                    break;

                case "asteroids":
                    if (Asteroids == null)
                    {
                        Asteroids = new List <AsteroidField>();
                    }
                    Asteroids.Add(new AsteroidField(this, s, GameData));
                    break;

                case "ambient":
                    foreach (Entry e in s)
                    {
                        switch (e.Name.ToLowerInvariant())
                        {
                        case "color":
                            if (e.Count != 3)
                            {
                                throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count);
                            }
                            if (AmbientColor != null)
                            {
                                throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name);
                            }
                            AmbientColor = new Color4(e[0].ToInt32() / 255f, e[1].ToInt32() / 255f, e[2].ToInt32() / 255f, 1f);
                            break;

                        default:
                            throw new Exception("Invalid Entry in " + s.Name + ": " + e.Name);
                        }
                    }
                    break;

                case "lightsource":
                    if (LightSources == null)
                    {
                        LightSources = new List <LightSource>();
                    }
                    LightSources.Add(new LightSource(s, GameData));
                    break;

                case "object":
                    if (Objects == null)
                    {
                        Objects = new List <SystemObject>();
                    }
                    Objects.Add(new SystemObject(universe, this, s, GameData));
                    break;

                case "encounterparameters":
                    if (EncounterParameters == null)
                    {
                        EncounterParameters = new List <EncounterParameter>();
                    }
                    EncounterParameters.Add(new EncounterParameter(s));
                    break;

                case "texturepanels":
                    TexturePanels = new TexturePanelsRef(s, GameData);
                    break;

                case "background":
                    foreach (Entry e in s)
                    {
                        switch (e.Name.ToLowerInvariant())
                        {
                        case "basic_stars":
                            if (e.Count != 1)
                            {
                                throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count);
                            }
                            if (BackgroundBasicStarsPath != null)
                            {
                                throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name);
                            }
                            BackgroundBasicStarsPath = VFS.GetPath(GameData.Freelancer.DataPath + e [0].ToString());
                            break;

                        case "complex_stars":
                            if (e.Count != 1)
                            {
                                throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count);
                            }
                            if (BackgroundComplexStarsPath != null)
                            {
                                throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name);
                            }
                            BackgroundComplexStarsPath = VFS.GetPath(GameData.Freelancer.DataPath + e [0].ToString());
                            break;

                        case "nebulae":
                            if (e.Count != 1)
                            {
                                throw new Exception("Invalid number of values in " + s.Name + " Entry " + e.Name + ": " + e.Count);
                            }
                            string temp = VFS.GetPath(GameData.Freelancer.DataPath + e[0].ToString(), false);
                            if (BackgroundNebulaePath != null && BackgroundNebulaePath != temp)
                            {
                                throw new Exception("Duplicate " + e.Name + " Entry in " + s.Name);
                            }
                            BackgroundNebulaePath = temp;
                            break;

                        default:
                            throw new Exception("Invalid Entry in " + s.Name + ": " + e.Name);
                        }
                    }
                    break;

                case "zone":
                    if (Zones == null)
                    {
                        Zones = new List <Zone>();
                    }
                    Zones.Add(new Zone(s, GameData));
                    break;

                case "field":
                    Field = new Field(s);
                    break;

                case "asteroidbillboards":
                    AsteroidBillboards = new AsteroidBillboards(s);
                    break;

                default:
                    throw new Exception("Invalid Section in " + file + ": " + s.Name);
                }
            }
        }
Пример #11
0
        public void Set(int storage, int x, int y, int z, BlockState state)
        {
            if (storage > _blockStorages.Length)
            {
                throw new IndexOutOfRangeException($"The storage id {storage} does not exist!");
            }

            var blockCoordinates = new BlockCoordinates(x, y, z);

            if (state == null)
            {
                Log.Warn($"State == null");
                return;
            }

            var coordsIndex = GetCoordinateIndex(x, y, z);

            if (storage == 0)
            {
                if (state.Block.LightValue > 0)
                {
                    if (!LightSources.Contains(blockCoordinates))
                    {
                        LightSources.Add(blockCoordinates);
                    }

                    SetBlocklight(x, y, z, (byte)state.Block.LightValue);
                    SetBlockLightScheduled(x, y, z, true);
                }
                else
                {
                    if (LightSources.Contains(blockCoordinates))
                    {
                        LightSources.Remove(blockCoordinates);
                    }
                }

                BlockState iblockstate = this.Get(x, y, z, storage);
                if (iblockstate != null)
                {
                    Block block = iblockstate.Block;

                    if (!(block is Air))
                    {
                        --this._blockRefCount;

                        if (block.RandomTicked)
                        {
                            --this._tickRefCount;
                        }


                        TransparentBlocks.Set(coordsIndex, true);
                        SolidBlocks.Set(coordsIndex, false);
                    }
                }

                OnBlockSet(x, y, z, state, iblockstate);
            }

            Block block1 = state.Block;

            if (storage == 0)
            {
                if (!(block1 is Air))
                {
                    ++this._blockRefCount;

                    if (block1.RandomTicked)
                    {
                        ++this._tickRefCount;
                    }

                    TransparentBlocks.Set(coordsIndex, block1.Transparent);
                    SolidBlocks.Set(coordsIndex, block1.Solid);
                }
            }

            if (state != null)
            {
                _blockStorages[storage].Set(x, y, z, state);
            }

            //ScheduledUpdates.Set(coordsIndex, true);
            SetScheduled(x, y, z, true);

            IsDirty = true;
        }