summaryrefslogtreecommitdiffstats
path: root/src/world/World.cpp
blob: abcfebf84f35669e96b091feb6e493368bc67290 (plain) (blame)
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
#include <world/World.hpp>

void World::ParseChunkData(std::shared_ptr<PacketChunkData> packet) {
	StreamBuffer chunkData(packet->Data.data(), packet->Data.size());
	std::bitset<16> bitmask(packet->PrimaryBitMask);
	for (int i = 0; i < 16; i++) {
		if (bitmask[i]) {
			Vector chunkPosition = Vector(packet->ChunkX, i, packet->ChunkZ);
			Section section = ParseSection(&chunkData, chunkPosition);
			auto it = sections.find(chunkPosition);
			if (it == sections.end()) {
				sections.insert(std::make_pair(chunkPosition, section));
			} else {
				using std::swap;
				swap(it->second, section);
			}
			sections.find(chunkPosition)->second.Parse();
		}
	}
}

Section World::ParseSection(StreamInput *data, Vector position) {
	unsigned char bitsPerBlock = data->ReadUByte();
	int paletteLength = data->ReadVarInt();
	std::vector<unsigned short> palette;
	for (int i = 0; i < paletteLength; i++) {
		palette.push_back(data->ReadVarInt());
	}
	int dataArrayLength = data->ReadVarInt();
	auto dataArray = data->ReadByteArray(dataArrayLength * 8);
	auto blockLight = data->ReadByteArray(4096 / 2);
	std::vector<unsigned char> skyLight;
	if (dimension == 0)
		skyLight = data->ReadByteArray(4096 / 2);
	return Section(position, dataArray.data(), dataArray.size(), blockLight.data(),
	               (skyLight.size() > 0 ? skyLight.data() : nullptr), bitsPerBlock, palette);
}

World::~World() {
}

World::World() {

}

bool World::isPlayerCollides(double X, double Y, double Z) {
	Vector PlayerChunk(floor(X / 16.0), floor(Y / 16.0), floor(Z / 16.0));
	std::vector<Vector> closestSectionsCoordinates = {
			Vector(PlayerChunk.GetX(), PlayerChunk.GetY(), PlayerChunk.GetZ()),
			Vector(PlayerChunk.GetX() + 1, PlayerChunk.GetY(), PlayerChunk.GetZ()),
			Vector(PlayerChunk.GetX() - 1, PlayerChunk.GetY(), PlayerChunk.GetZ()),
			Vector(PlayerChunk.GetX(), PlayerChunk.GetY() + 1, PlayerChunk.GetZ()),
			Vector(PlayerChunk.GetX(), PlayerChunk.GetY() - 1, PlayerChunk.GetZ()),
			Vector(PlayerChunk.GetX(), PlayerChunk.GetY(), PlayerChunk.GetZ() + 1),
			Vector(PlayerChunk.GetX(), PlayerChunk.GetY(), PlayerChunk.GetZ() - 1),
	};
	std::vector<std::map<Vector, Section>::iterator> closestSections;
	for (auto &coord:closestSectionsCoordinates) {
		auto it = sections.find(coord);
		if (it != sections.end())
			closestSections.push_back(it);
	}
	if (closestSections.empty())
		return false;

	for (auto &it:closestSections) {

		const double PlayerWidth = 0.6;
		const double PlayerHeight = 1.82;
		const double PlayerLength = 0.6;

		AABB playerColl;
		playerColl.x = X - PlayerWidth / 2 - 0.5;
		playerColl.w = PlayerWidth;
		playerColl.y = Y - 0.5f;
		playerColl.h = PlayerHeight;
		playerColl.z = Z - PlayerLength / 2 - 0.5;
		playerColl.l = PlayerLength;

		for (int x = 0; x < 16; x++) {
			for (int y = 0; y < 16; y++) {
				for (int z = 0; z < 16; z++) {
					Block block = it->second.GetBlock(Vector(x, y, z));
					if (block.id == 0 || block.id == 31)
						continue;
					AABB blockColl{(x + it->first.GetX() * 16) - 0.5,
					               (y + it->first.GetY() * 16) - 0.5,
					               (z + it->first.GetZ() * 16) - 0.5, 1, 1, 1};
					if (TestCollision(playerColl, blockColl))
						return true;
				}
			}
		}
	}
	return false;
}