summaryrefslogtreecommitdiffstats
path: root/src/world
diff options
context:
space:
mode:
Diffstat (limited to 'src/world')
-rw-r--r--src/world/Collision.cpp28
-rw-r--r--src/world/Collision.hpp8
-rw-r--r--src/world/Section.cpp31
-rw-r--r--src/world/Section.hpp37
-rw-r--r--src/world/World.cpp151
-rw-r--r--src/world/World.hpp27
6 files changed, 161 insertions, 121 deletions
diff --git a/src/world/Collision.cpp b/src/world/Collision.cpp
new file mode 100644
index 0000000..4f2c837
--- /dev/null
+++ b/src/world/Collision.cpp
@@ -0,0 +1,28 @@
+#include "Collision.hpp"
+
+bool TestCollision(AABB first, AABB second) {
+ double firstXl = first.x;
+ double firstXr = first.x + first.w;
+
+ double firstYl = first.y;
+ double firstYr = first.y + first.h;
+
+ double firstZl = first.z;
+ double firstZr = first.z + first.l;
+
+
+ double secondXl = second.x;
+ double secondXr = second.x + second.w;
+
+ double secondYl = second.y;
+ double secondYr = second.y + second.h;
+
+ double secondZl = second.z;
+ double secondZr = second.z + second.l;
+
+ bool collidesOnX = firstXr >= secondXl && firstXl <= secondXr;
+ bool collidesOnY = firstYr >= secondYl && firstYl <= secondYr;
+ bool collidesOnZ = firstZr >= secondZl && firstZl <= secondZr;
+
+ return collidesOnX && collidesOnY && collidesOnZ;
+}
diff --git a/src/world/Collision.hpp b/src/world/Collision.hpp
new file mode 100644
index 0000000..b88fbf7
--- /dev/null
+++ b/src/world/Collision.hpp
@@ -0,0 +1,8 @@
+#pragma once
+
+struct AABB {
+ double x,y,z;
+ double w,l,h;
+};
+
+bool TestCollision(AABB first, AABB second); \ No newline at end of file
diff --git a/src/world/Section.cpp b/src/world/Section.cpp
index 63c7f97..8f94ad7 100644
--- a/src/world/Section.cpp
+++ b/src/world/Section.cpp
@@ -1,7 +1,8 @@
#include "Section.hpp"
+
Section::Section(byte *dataBlocks, size_t dataBlocksLength, byte *dataLight, byte *dataSky, byte bitsPerBlock,
- std::vector<unsigned short> palette) {
+ std::vector<unsigned short> palette) {
m_dataBlocksLen = dataBlocksLength;
m_dataBlocks = new byte[m_dataBlocksLen];
std::copy(dataBlocks, dataBlocks + m_dataBlocksLen, m_dataBlocks);
@@ -93,30 +94,22 @@ void Section::Parse() {
m_dataSkyLight = nullptr;
parseWaiter.notify_all();
- /*static std::map<Block,int> totalBlocks;
- for (int x=0;x<16;x++)
- for (int y=0;y<16;y++)
- for (int z=0;z<16;z++)
- totalBlocks[GetBlock(Vector(x,y,z))]++;
- LOG(ERROR)<<"Logging chunk";
- for (auto& it:totalBlocks){
- LOG(WARNING)<<it.first.id<<":"<<(int)it.first.state<<" = "<<it.second;
- }*/
}
Section &Section::operator=(Section other) {
- other.swap(*this);
+ std::swap(*this,other);
return *this;
}
-void Section::swap(Section &other) {
- std::swap(other.m_dataBlocksLen, m_dataBlocksLen);
- std::swap(other.m_dataBlocks, m_dataBlocks);
- std::swap(other.m_dataLight, m_dataLight);
- std::swap(other.m_dataSkyLight, m_dataSkyLight);
- std::swap(other.m_blocks, m_blocks);
- std::swap(other.m_palette, m_palette);
- std::swap(other.m_bitsPerBlock, m_bitsPerBlock);
+void swap(Section &a, Section &b) {
+ using std::swap;
+ swap(a.m_dataBlocksLen, b.m_dataBlocksLen);
+ swap(a.m_dataBlocks, b.m_dataBlocks);
+ swap(a.m_dataLight, b.m_dataLight);
+ swap(a.m_dataSkyLight, b.m_dataSkyLight);
+ swap(a.m_blocks, b.m_blocks);
+ swap(a.m_palette, b.m_palette);
+ swap(a.m_bitsPerBlock, b.m_bitsPerBlock);
}
Section::Section(const Section &other) {
diff --git a/src/world/Section.hpp b/src/world/Section.hpp
index 36fc91a..657fc13 100644
--- a/src/world/Section.hpp
+++ b/src/world/Section.hpp
@@ -5,38 +5,39 @@
#include <condition_variable>
#include <easylogging++.h>
#include "Block.hpp"
-#include "../packet/Field.hpp"
+#include "../utility/Vector.hpp"
+#include "../utility/utility.h"
const int SECTION_WIDTH = 16;
const int SECTION_LENGTH = 16;
const int SECTION_HEIGHT = 16;
class Section {
- std::vector<unsigned short> m_palette;
- byte *m_dataBlocks = nullptr;
- size_t m_dataBlocksLen;
- byte *m_dataLight = nullptr;
- byte *m_dataSkyLight = nullptr;
- byte m_bitsPerBlock = 0;
- std::vector<Block> m_blocks;
- std::condition_variable parseWaiter;
+ std::vector<unsigned short> m_palette;
+ byte *m_dataBlocks = nullptr;
+ size_t m_dataBlocksLen;
+ byte *m_dataLight = nullptr;
+ byte *m_dataSkyLight = nullptr;
+ byte m_bitsPerBlock = 0;
+ std::vector<Block> m_blocks;
+ std::condition_variable parseWaiter;
- Section();
+ Section();
public:
- void Parse();
+ void Parse();
- Section(byte *dataBlocks, size_t dataBlocksLength, byte *dataLight, byte *dataSky, byte bitsPerBlock,
- std::vector<unsigned short> palette);
+ Section(byte *dataBlocks, size_t dataBlocksLength, byte *dataLight, byte *dataSky, byte bitsPerBlock,
+ std::vector<unsigned short> palette);
- ~Section();
+ ~Section();
- Block &GetBlock(Vector pos);
+ Block &GetBlock(Vector pos);
- Section &operator=(Section other);
+ Section &operator=(Section other);
- void swap(Section &other);
+ friend void swap(Section &a, Section& b);
- Section(const Section &other);
+ Section(const Section &other);
}; \ No newline at end of file
diff --git a/src/world/World.cpp b/src/world/World.cpp
index 2220627..394598b 100644
--- a/src/world/World.cpp
+++ b/src/world/World.cpp
@@ -1,84 +1,39 @@
#include "World.hpp"
-void World::ParseChunkData(Packet packet) {
- int chunkX = packet.GetField(0).GetInt();
- int chunkZ = packet.GetField(1).GetInt();
- bool isGroundContinuous = packet.GetField(2).GetBool();
- std::bitset<16> bitmask(packet.GetField(3).GetVarInt());
- int entities = packet.GetField(5).GetVarInt();
-
- size_t dataLen = packet.GetField(5).GetLength();
- byte *content = new byte[dataLen];
- byte *contentOrigPtr = content;
- packet.GetField(5).CopyToBuff(content);
-
- if (isGroundContinuous)
- dataLen -= 256;
-
- byte *biomes = content + packet.GetField(5).GetLength() - 256;
+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]) {
- size_t len = 0;
- Vector chunkPosition = Vector(chunkX, i, chunkZ);
- if (!m_sections.insert(std::make_pair(chunkPosition, ParseSection(content, len))).second)
- LOG(ERROR) << "Chunk not created: " << chunkPosition;
- auto sectionIter = m_sections.find(chunkPosition);
- if (sectionIter == m_sections.end())
- LOG(ERROR) << "Created chunk not found: " << chunkPosition;
- else
- sectionIter->second.Parse();
- content += len;
+ Vector chunkPosition = Vector(packet->ChunkX, i, packet->ChunkZ);
+ Section section = ParseSection(&chunkData);
+ 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();
}
}
- delete[] contentOrigPtr;
}
-Section World::ParseSection(byte *data, size_t &dataLen) {
- dataLen = 0;
-
- Field fBitsPerBlock = FieldParser::Parse(UnsignedByte, data);
- byte bitsPerBlock = fBitsPerBlock.GetUByte();
- data += fBitsPerBlock.GetLength();
- dataLen += fBitsPerBlock.GetLength();
-
- Field fPaletteLength = FieldParser::Parse(VarIntType, data);
- int paletteLength = fPaletteLength.GetVarInt();
- data += fPaletteLength.GetLength();
- dataLen += fPaletteLength.GetLength();
-
+Section World::ParseSection(StreamInput *data) {
+ unsigned char bitsPerBlock = data->ReadUByte();
+ int paletteLength = data->ReadVarInt();
std::vector<unsigned short> palette;
- if (paletteLength > 0) {
- for (unsigned char i = 0; i < paletteLength; i++) {
- endswap(&i);
- Field f = FieldParser::Parse(VarIntType, data);
- data += f.GetLength();
- dataLen += f.GetLength();
- palette.push_back(f.GetVarInt());
- endswap(&i);
- }
+ for (int i = 0; i < paletteLength; i++) {
+ palette.push_back(data->ReadVarInt());
}
-
- Field fDataLength = FieldParser::Parse(VarIntType, data);
- data += fDataLength.GetLength();
- dataLen += fDataLength.GetLength();
-
- int dataLength = fDataLength.GetVarInt();
- size_t dataSize = dataLength * 8;
- dataLen += dataSize;
- byte *dataBlocks = data;
-
- data += 2048;
- dataLen += 2048;
- byte *dataLight = data;
-
- byte *dataSky = nullptr;
- if (m_dimension == 0) {
- data += 2048;
- dataLen += 2048;
- dataSky = data;
- }
-
- return Section(dataBlocks, dataSize, dataLight, dataSky, bitsPerBlock, palette);
+ 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(dataArray.data(), dataArray.size(), blockLight.data(),
+ (skyLight.size() > 0 ? skyLight.data() : nullptr), bitsPerBlock, palette);
}
World::~World() {
@@ -86,4 +41,56 @@ World::~World() {
World::World() {
-} \ No newline at end of file
+}
+
+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;
+}
diff --git a/src/world/World.hpp b/src/world/World.hpp
index b33499c..e315baf 100644
--- a/src/world/World.hpp
+++ b/src/world/World.hpp
@@ -8,27 +8,30 @@
#include <bitset>
#include <easylogging++.h>
#include "Block.hpp"
-#include "../packet/Packet.hpp"
#include "Section.hpp"
+#include "../network/Packet.hpp"
+#include "Collision.hpp"
class World {
- //utility vars
- World(const World &other);
+ //utility vars
+ World(const World &other);
- World &operator=(const World &other);
+ World &operator=(const World &other);
- //game vars
- int m_dimension = 0;
+ //game vars
+ int dimension = 0;
- //game methods
- Section ParseSection(byte *data, size_t &dataLen);
+ //game methods
+ Section ParseSection(StreamInput *data);
public:
- World();
+ World();
- ~World();
+ ~World();
- void ParseChunkData(Packet packet);
+ void ParseChunkData(std::shared_ptr<PacketChunkData> packet);
- std::map<Vector, Section> m_sections;
+ std::map<Vector, Section> sections;
+
+ bool isPlayerCollides(double X, double Y, double Z);
}; \ No newline at end of file