summaryrefslogtreecommitdiff
path: root/source/game/planets/ChunkMap.cs
blob: 234d0341460286bf069cc0c0ab59f52c3bde9e20 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
using System;
using Celesteia.Game.Components.Items;
using Celesteia.Game.Planets.Generation;
using Celesteia.Resources;
using Microsoft.Xna.Framework;
using MonoGame.Extended;

namespace Celesteia.Game.Planets {
    public class ChunkMap {
        public int Width, Height;
        public int BlockWidth => Width * Chunk.CHUNK_SIZE;
        public int BlockHeight => Height * Chunk.CHUNK_SIZE;
        
        public Chunk[,] Map;

        public ChunkMap(int w, int h) {
            Width = w;
            Height = h;

            Map = new Chunk[w, h];
        }

        public Chunk GetChunk(int chunkX, int chunkY) => ChunkIsInMap(chunkX, chunkY) ? Map[chunkX, chunkY] : null;
        public Chunk GetChunk(ChunkVector cv) => GetChunk(cv.X, cv.Y);
        public Chunk GetChunkAtCoordinates(int x, int y) => GetChunk(x / Chunk.CHUNK_SIZE, y / Chunk.CHUNK_SIZE);
        public Chunk GetChunkAtPoint(Point point) => GetChunkAtCoordinates(point.X, point.Y);

        // BACKGROUND MANAGEMENT
        public BlockState GetBackground(int blockX, int blockY) {
            Chunk c = GetChunkAtCoordinates(blockX, blockY);
            if (c != null) return c.GetBackground(blockX % Chunk.CHUNK_SIZE, blockY % Chunk.CHUNK_SIZE);

            return BlockState.None;
        }
        public BlockState GetBackground(Point point) => GetBackground(point.X, point.Y);

        public void SetBackgroundID(int blockX, int blockY, byte id) {
            Chunk c = GetChunkAtCoordinates(blockX, blockY);
            if (c != null) c.SetBackground(blockX % Chunk.CHUNK_SIZE, blockY % Chunk.CHUNK_SIZE, id);
        }
        public void SetBackgroundID(Point point, byte id) => SetBackgroundID(point.X, point.Y, id);

        public void AddBackgroundBreakProgress(int blockX, int blockY, int power, out ItemStack drops) {
            drops = null;
            Chunk c = GetChunkAtCoordinates(blockX, blockY);
            if (c != null) c.AddBreakProgress(blockX % Chunk.CHUNK_SIZE, blockY % Chunk.CHUNK_SIZE, power, true, out drops);
        }
        public void AddBackgroundBreakProgress(Point point, int power, out ItemStack drops) => AddBackgroundBreakProgress(point.X, point.Y, power, out drops);

        // FOREGROUND MANAGEMENT
        public BlockState GetForeground(int blockX, int blockY) {
            Chunk c = GetChunkAtCoordinates(blockX, blockY);
            if (c != null) return c.GetForeground(blockX % Chunk.CHUNK_SIZE, blockY % Chunk.CHUNK_SIZE);

            return BlockState.None;
        }
        public BlockState GetForeground(Point point) => GetForeground(point.X, point.Y);

        public void SetForegroundID(int blockX, int blockY, byte id) {
            Chunk c = GetChunkAtCoordinates(blockX, blockY);
            if (c != null) c.SetForeground(blockX % Chunk.CHUNK_SIZE, blockY % Chunk.CHUNK_SIZE, id);
        }
        public void SetForegroundID(Point point, byte id) => SetForegroundID(point.X, point.Y, id);

        public void AddForegroundBreakProgress(int blockX, int blockY, int power, out ItemStack drops) {
            drops = null;
            Chunk c = GetChunkAtCoordinates(blockX, blockY);
            if (c != null) c.AddBreakProgress(blockX % Chunk.CHUNK_SIZE, blockY % Chunk.CHUNK_SIZE, power, false, out drops);
        }
        public void AddForegroundBreakProgress(Point point, int power, out ItemStack drops) => AddForegroundBreakProgress(point.X, point.Y, power, out drops);

        // FOR ADJACENCY CHECKS
        public bool GetAny(int blockX, int blockY) {
            Chunk c = GetChunkAtCoordinates(blockX, blockY);
            return c != null && (
                !c.GetForeground(blockX % Chunk.CHUNK_SIZE, blockY % Chunk.CHUNK_SIZE).Empty ||
                !c.GetBackground(blockX % Chunk.CHUNK_SIZE, blockY % Chunk.CHUNK_SIZE).Empty
            );
        }

        // COLLISION CHECKS

        public RectangleF? TestBoundingBox(int x, int y, RectangleF? box) {
            if (!box.HasValue) return null;

            return new RectangleF(
                x, y,
                box.Value.Width, box.Value.Height
            );
        }
        public RectangleF? TestBoundingBox(int x, int y) => TestBoundingBox(x, y, GetForeground(x, y).Type.BoundingBox);

        // CHUNK IN MAP CHECKS
        public bool ChunkIsInMap(int chunkX, int chunkY) => !(chunkX < 0 || chunkY < 0 || chunkX >= Width || chunkY >= Height);
        public bool ChunkIsInMap(ChunkVector cv) => ChunkIsInMap(cv.X, cv.Y);

        public virtual Vector2 GetSpawnpoint() => Vector2.Zero;
    }
}