diff options
-rw-r--r-- | src/AssetManager.cpp | 294 | ||||
-rw-r--r-- | src/AssetManager.hpp | 19 | ||||
-rw-r--r-- | src/Block.cpp | 4 | ||||
-rw-r--r-- | src/Block.hpp | 25 | ||||
-rw-r--r-- | src/Entity.cpp | 128 | ||||
-rw-r--r-- | src/Event.cpp | 1 | ||||
-rw-r--r-- | src/Event.hpp | 3 | ||||
-rw-r--r-- | src/Frustum.cpp | 2 | ||||
-rw-r--r-- | src/GameState.cpp | 205 | ||||
-rw-r--r-- | src/GameState.hpp | 65 | ||||
-rw-r--r-- | src/GlobalState.cpp | 88 | ||||
-rw-r--r-- | src/Packet.hpp | 910 | ||||
-rw-r--r-- | src/Render.cpp | 600 | ||||
-rw-r--r-- | src/RendererSection.cpp | 6 | ||||
-rw-r--r-- | src/RendererWorld.cpp | 16 | ||||
-rw-r--r-- | src/Utility.cpp | 83 | ||||
-rw-r--r-- | src/Utility.hpp | 56 | ||||
-rw-r--r-- | src/Vector.hpp | 210 | ||||
-rw-r--r-- | src/World.cpp | 67 | ||||
-rw-r--r-- | src/main.cpp | 2 |
20 files changed, 1549 insertions, 1235 deletions
diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index 0507bc1..0561992 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -19,184 +19,183 @@ const std::string pathToTextureIndex = "./textures.json"; const fs::path pathToModels = "./assets/minecraft/models/"; AssetManager::AssetManager() { - LoadIds(); - LoadTextureResources(); + LoadIds(); + LoadTextureResources(); LoadBlockModels(); } void AssetManager::LoadIds() { - std::ifstream in(pathToAssetsList); - nlohmann::json index; - in >> index; - for (auto &it:index) { - unsigned short id = it["type"].get<int>(); - unsigned char state = it["meta"].get<int>(); - std::string blockName = it["text_type"].get<std::string>(); + std::ifstream in(pathToAssetsList); + nlohmann::json index; + in >> index; + for (auto &it:index) { + unsigned short id = it["type"].get<int>(); + unsigned char state = it["meta"].get<int>(); + std::string blockName = it["text_type"].get<std::string>(); assetIds[blockName] = BlockId{ id, state }; - } - LOG(INFO) << "Loaded " << assetIds.size() << " ids"; + } + LOG(INFO) << "Loaded " << assetIds.size() << " ids"; } AssetManager::~AssetManager() { - delete textureAtlas; + delete textureAtlas; } //TODO: This function must be replaced with runtime texture atlas generating void AssetManager::LoadTextureResources() { - std::ifstream in(pathToTextureIndex); - nlohmann::json index; - in >> index; - std::string filename = index["meta"]["image"].get<std::string>(); - float textureWidth = index["meta"]["size"]["w"].get<int>(); - float textureHeight = index["meta"]["size"]["h"].get<int>(); + std::ifstream in(pathToTextureIndex); + nlohmann::json index; + in >> index; + std::string filename = index["meta"]["image"].get<std::string>(); + float textureWidth = index["meta"]["size"]["w"].get<int>(); + float textureHeight = index["meta"]["size"]["h"].get<int>(); size_t sizeName = 0,sizeTexture = 0; - for (auto &it:index["frames"]) { - auto frame = it["frame"]; - TextureCoordinates coord; - coord.x = frame["x"].get<int>() / textureWidth; - coord.y = frame["y"].get<int>() / textureHeight; - coord.w = frame["w"].get<int>() / textureWidth; - coord.h = frame["h"].get<int>() / textureHeight; - std::string assetName = it["filename"].get<std::string>(); - assetName.insert(0, "minecraft/textures/"); - assetName.erase(assetName.length() - 4); + for (auto &it:index["frames"]) { + auto frame = it["frame"]; + TextureCoordinates coord; + coord.x = frame["x"].get<int>() / textureWidth; + coord.y = frame["y"].get<int>() / textureHeight; + coord.w = frame["w"].get<int>() / textureWidth; + coord.h = frame["h"].get<int>() / textureHeight; + std::string assetName = it["filename"].get<std::string>(); + assetName.insert(0, "minecraft/textures/"); + assetName.erase(assetName.length() - 4); assetName.shrink_to_fit(); sizeName += sizeof(assetName) + assetName.capacity(); sizeTexture += sizeof(coord); - assetTextures[assetName] = coord; - } - textureAtlas = new Texture(filename); - LOG(INFO) << "Texture atlas id is " << textureAtlas->texture; + assetTextures[assetName] = coord; + } + textureAtlas = new Texture(filename); + LOG(INFO) << "Texture atlas id is " << textureAtlas->texture; } TextureCoordinates AssetManager::GetTextureByAssetName(std::string AssetName) { - if (assetTextures.find(AssetName) != assetTextures.end()) - return assetTextures[AssetName]; - else - return TextureCoordinates{-1, -1, -1, -1}; + if (assetTextures.find(AssetName) != assetTextures.end()) + return assetTextures[AssetName]; + else + return TextureCoordinates{-1, -1, -1, -1}; } std::string AssetManager::GetTextureAssetNameByBlockId(BlockTextureId block) { - //Block sides: 0 - bottom, 1 - top, 2 - north, 3 - south, 4 - west, 5 - east 6 - every side - const std::map<BlockTextureId, std::string> lookupTable = { - {BlockTextureId(0, 0), "minecraft/textures/blocks/air"}, - {BlockTextureId(1, 0), "minecraft/textures/blocks/stone"}, - {BlockTextureId(1, 1), "minecraft/textures/blocks/stone_granite"}, - - {BlockTextureId(2, 0, 0), "minecraft/textures/blocks/dirt"}, - {BlockTextureId(2, 0, 1), "minecraft/textures/blocks/grass_top"}, - {BlockTextureId(2, 0, 2), "minecraft/textures/blocks/grass_side"}, - {BlockTextureId(2, 0, 3), "minecraft/textures/blocks/grass_side"}, - {BlockTextureId(2, 0, 4), "minecraft/textures/blocks/grass_side"}, - {BlockTextureId(2, 0, 5), "minecraft/textures/blocks/grass_side"}, - - {BlockTextureId(3, 0), "minecraft/textures/blocks/dirt"}, - {BlockTextureId(4, 0), "minecraft/textures/blocks/cobblestone"}, - {BlockTextureId(5, 0), "minecraft/textures/blocks/planks"}, - - {BlockTextureId(7, 0), "minecraft/textures/blocks/bedrock"}, - - {BlockTextureId(17, 0, 0), "minecraft/textures/blocks/log_oak_top"}, - {BlockTextureId(17, 0, 1), "minecraft/textures/blocks/log_oak_top"}, - {BlockTextureId(17, 0, 2), "minecraft/textures/blocks/log_oak"}, - {BlockTextureId(17, 0, 3), "minecraft/textures/blocks/log_oak"}, - {BlockTextureId(17, 0, 4), "minecraft/textures/blocks/log_oak"}, - {BlockTextureId(17, 0, 5), "minecraft/textures/blocks/log_oak"}, - - {BlockTextureId(17, 1, 0), "minecraft/textures/blocks/log_spruce_top"}, - {BlockTextureId(17, 1, 1), "minecraft/textures/blocks/log_spruce_top"}, - {BlockTextureId(17, 1, 2), "minecraft/textures/blocks/log_spruce"}, - {BlockTextureId(17, 1, 3), "minecraft/textures/blocks/log_spruce"}, - {BlockTextureId(17, 1, 4), "minecraft/textures/blocks/log_spruce"}, - {BlockTextureId(17, 1, 5), "minecraft/textures/blocks/log_spruce"}, - - {BlockTextureId(17, 2, 0), "minecraft/textures/blocks/log_birch_top"}, - {BlockTextureId(17, 2, 1), "minecraft/textures/blocks/log_birch_top"}, - {BlockTextureId(17, 2, 2), "minecraft/textures/blocks/log_birch"}, - {BlockTextureId(17, 2, 3), "minecraft/textures/blocks/log_birch"}, - {BlockTextureId(17, 2, 4), "minecraft/textures/blocks/log_birch"}, - {BlockTextureId(17, 2, 5), "minecraft/textures/blocks/log_birch"}, - - {BlockTextureId(17, 3, 0), "minecraft/textures/blocks/log_jungle_top"}, - {BlockTextureId(17, 3, 1), "minecraft/textures/blocks/log_jungle_top"}, - {BlockTextureId(17, 3, 2), "minecraft/textures/blocks/log_jungle"}, - {BlockTextureId(17, 3, 3), "minecraft/textures/blocks/log_jungle"}, - {BlockTextureId(17, 3, 4), "minecraft/textures/blocks/log_jungle"}, - {BlockTextureId(17, 3, 5), "minecraft/textures/blocks/log_jungle"}, - - {BlockTextureId(18, 0), "minecraft/textures/blocks/leaves_oak"}, - {BlockTextureId(18, 1), "minecraft/textures/blocks/leaves_spruce"}, - {BlockTextureId(18, 2), "minecraft/textures/blocks/leaves_birch"}, - {BlockTextureId(18, 3), "minecraft/textures/blocks/leaves_jungle"}, - - {BlockTextureId(61, 0, 0), "minecraft/textures/blocks/furnace_side"}, - {BlockTextureId(61, 0, 1), "minecraft/textures/blocks/furnace_top"}, - {BlockTextureId(61, 0, 2), "minecraft/textures/blocks/furnace_front_off"}, - {BlockTextureId(61, 0, 3), "minecraft/textures/blocks/furnace_side"}, - {BlockTextureId(61, 0, 4), "minecraft/textures/blocks/furnace_side"}, - {BlockTextureId(61, 0, 5), "minecraft/textures/blocks/furnace_side"}, - - {BlockTextureId(62, 0, 0), "minecraft/textures/blocks/furnace_side"}, - {BlockTextureId(62, 0, 1), "minecraft/textures/blocks/furnace_top"}, - {BlockTextureId(62, 0, 2), "minecraft/textures/blocks/furnace_front_on"}, - {BlockTextureId(62, 0, 3), "minecraft/textures/blocks/furnace_side"}, - {BlockTextureId(62, 0, 4), "minecraft/textures/blocks/furnace_side"}, - {BlockTextureId(62, 0, 5), "minecraft/textures/blocks/furnace_side"}, - - - {BlockTextureId(31, 0), "minecraft/textures/blocks/deadbush"}, - {BlockTextureId(31, 1), "minecraft/textures/blocks/tallgrass"}, - {BlockTextureId(31, 2), "minecraft/textures/blocks/fern"}, - }; - auto ret = lookupTable.find(block); - if (ret == lookupTable.end()) - return ""; - else - return ret->second; + //Block sides: 0 - bottom, 1 - top, 2 - north, 3 - south, 4 - west, 5 - east 6 - every side + const std::map<BlockTextureId, std::string> lookupTable = { + {BlockTextureId(0, 0), "minecraft/textures/blocks/air"}, + {BlockTextureId(1, 0), "minecraft/textures/blocks/stone"}, + {BlockTextureId(1, 1), "minecraft/textures/blocks/stone_granite"}, + + {BlockTextureId(2, 0, 0), "minecraft/textures/blocks/dirt"}, + {BlockTextureId(2, 0, 1), "minecraft/textures/blocks/grass_top"}, + {BlockTextureId(2, 0, 2), "minecraft/textures/blocks/grass_side"}, + {BlockTextureId(2, 0, 3), "minecraft/textures/blocks/grass_side"}, + {BlockTextureId(2, 0, 4), "minecraft/textures/blocks/grass_side"}, + {BlockTextureId(2, 0, 5), "minecraft/textures/blocks/grass_side"}, + + {BlockTextureId(3, 0), "minecraft/textures/blocks/dirt"}, + {BlockTextureId(4, 0), "minecraft/textures/blocks/cobblestone"}, + {BlockTextureId(5, 0), "minecraft/textures/blocks/planks"}, + + {BlockTextureId(7, 0), "minecraft/textures/blocks/bedrock"}, + + {BlockTextureId(17, 0, 0), "minecraft/textures/blocks/log_oak_top"}, + {BlockTextureId(17, 0, 1), "minecraft/textures/blocks/log_oak_top"}, + {BlockTextureId(17, 0, 2), "minecraft/textures/blocks/log_oak"}, + {BlockTextureId(17, 0, 3), "minecraft/textures/blocks/log_oak"}, + {BlockTextureId(17, 0, 4), "minecraft/textures/blocks/log_oak"}, + {BlockTextureId(17, 0, 5), "minecraft/textures/blocks/log_oak"}, + + {BlockTextureId(17, 1, 0), "minecraft/textures/blocks/log_spruce_top"}, + {BlockTextureId(17, 1, 1), "minecraft/textures/blocks/log_spruce_top"}, + {BlockTextureId(17, 1, 2), "minecraft/textures/blocks/log_spruce"}, + {BlockTextureId(17, 1, 3), "minecraft/textures/blocks/log_spruce"}, + {BlockTextureId(17, 1, 4), "minecraft/textures/blocks/log_spruce"}, + {BlockTextureId(17, 1, 5), "minecraft/textures/blocks/log_spruce"}, + + {BlockTextureId(17, 2, 0), "minecraft/textures/blocks/log_birch_top"}, + {BlockTextureId(17, 2, 1), "minecraft/textures/blocks/log_birch_top"}, + {BlockTextureId(17, 2, 2), "minecraft/textures/blocks/log_birch"}, + {BlockTextureId(17, 2, 3), "minecraft/textures/blocks/log_birch"}, + {BlockTextureId(17, 2, 4), "minecraft/textures/blocks/log_birch"}, + {BlockTextureId(17, 2, 5), "minecraft/textures/blocks/log_birch"}, + + {BlockTextureId(17, 3, 0), "minecraft/textures/blocks/log_jungle_top"}, + {BlockTextureId(17, 3, 1), "minecraft/textures/blocks/log_jungle_top"}, + {BlockTextureId(17, 3, 2), "minecraft/textures/blocks/log_jungle"}, + {BlockTextureId(17, 3, 3), "minecraft/textures/blocks/log_jungle"}, + {BlockTextureId(17, 3, 4), "minecraft/textures/blocks/log_jungle"}, + {BlockTextureId(17, 3, 5), "minecraft/textures/blocks/log_jungle"}, + + {BlockTextureId(18, 0), "minecraft/textures/blocks/leaves_oak"}, + {BlockTextureId(18, 1), "minecraft/textures/blocks/leaves_spruce"}, + {BlockTextureId(18, 2), "minecraft/textures/blocks/leaves_birch"}, + {BlockTextureId(18, 3), "minecraft/textures/blocks/leaves_jungle"}, + + {BlockTextureId(61, 0, 0), "minecraft/textures/blocks/furnace_side"}, + {BlockTextureId(61, 0, 1), "minecraft/textures/blocks/furnace_top"}, + {BlockTextureId(61, 0, 2), "minecraft/textures/blocks/furnace_front_off"}, + {BlockTextureId(61, 0, 3), "minecraft/textures/blocks/furnace_side"}, + {BlockTextureId(61, 0, 4), "minecraft/textures/blocks/furnace_side"}, + {BlockTextureId(61, 0, 5), "minecraft/textures/blocks/furnace_side"}, + + {BlockTextureId(62, 0, 0), "minecraft/textures/blocks/furnace_side"}, + {BlockTextureId(62, 0, 1), "minecraft/textures/blocks/furnace_top"}, + {BlockTextureId(62, 0, 2), "minecraft/textures/blocks/furnace_front_on"}, + {BlockTextureId(62, 0, 3), "minecraft/textures/blocks/furnace_side"}, + {BlockTextureId(62, 0, 4), "minecraft/textures/blocks/furnace_side"}, + {BlockTextureId(62, 0, 5), "minecraft/textures/blocks/furnace_side"}, + + + {BlockTextureId(31, 0), "minecraft/textures/blocks/deadbush"}, + {BlockTextureId(31, 1), "minecraft/textures/blocks/tallgrass"}, + {BlockTextureId(31, 2), "minecraft/textures/blocks/fern"}, + }; + + auto ret = lookupTable.find(block); + return (ret == lookupTable.end()) ? "" : ret->second; } GLuint AssetManager::GetTextureAtlas() { - return textureAtlas->texture; + return textureAtlas->texture; } TextureCoordinates AssetManager::GetTextureByBlock(BlockTextureId block) { - std::string assetName = this->GetTextureAssetNameByBlockId(block); - return this->GetTextureByAssetName(assetName); + std::string assetName = this->GetTextureAssetNameByBlockId(block); + return this->GetTextureByAssetName(assetName); } const std::map<BlockTextureId, glm::vec4> &AssetManager::GetTextureAtlasIndexes() { - if (!textureAtlasIndexes.empty()) - return textureAtlasIndexes; - - LOG(INFO) << "Initializing texture atlas..."; - for (int id = 1; id < 128; id++) { - for (int state = 0; state < 16; state++) { - BlockTextureId blockTextureId(id, state, 6); - if (!this->GetTextureByBlock(blockTextureId) && - !this->GetTextureByBlock(BlockTextureId(id, state, 0))) { - continue; - } - if (this->GetTextureByBlock(blockTextureId)) { - for (int i = 0; i < 6; i++) { - TextureCoordinates tc = this->GetTextureByBlock(BlockTextureId(id, state, 6)); - textureAtlasIndexes[BlockTextureId(id, state, i)] = glm::vec4(tc.x, tc.y, tc.w, tc.h); - } - } else { - for (int i = 0; i < 6; i++) { - TextureCoordinates tc = this->GetTextureByBlock(BlockTextureId(id, state, i)); - textureAtlasIndexes[BlockTextureId(id, state, i)] = glm::vec4(tc.x, tc.y, tc.w, tc.h); - } - } - } - } - LOG(INFO) << "Created " << textureAtlasIndexes.size() << " texture indexes"; - - return textureAtlasIndexes; + if (!textureAtlasIndexes.empty()) + return textureAtlasIndexes; + + LOG(INFO) << "Initializing texture atlas..."; + for (int id = 1; id < 128; id++) { + for (int state = 0; state < 16; state++) { + BlockTextureId blockTextureId(id, state, 6); + if (!this->GetTextureByBlock(blockTextureId) && + !this->GetTextureByBlock(BlockTextureId(id, state, 0))) { + continue; + } + + if (this->GetTextureByBlock(blockTextureId)) { + for (int i = 0; i < 6; i++) { + TextureCoordinates tc = this->GetTextureByBlock(BlockTextureId(id, state, 6)); + textureAtlasIndexes[BlockTextureId(id, state, i)] = glm::vec4(tc.x, tc.y, tc.w, tc.h); + } + } else { + for (int i = 0; i < 6; i++) { + TextureCoordinates tc = this->GetTextureByBlock(BlockTextureId(id, state, i)); + textureAtlasIndexes[BlockTextureId(id, state, i)] = glm::vec4(tc.x, tc.y, tc.w, tc.h); + } + } + } + } + LOG(INFO) << "Created " << textureAtlasIndexes.size() << " texture indexes"; + + return textureAtlasIndexes; } AssetManager &AssetManager::Instance() { - static AssetManager assetManager; - return assetManager; + static AssetManager assetManager; + return assetManager; } const BlockModel *AssetManager::GetBlockModelByBlockId(BlockId block) { @@ -233,14 +232,10 @@ const BlockModel *AssetManager::GetBlockModelByBlockId(BlockId block) { std::string blockName = blockIdToBlockName[block]; auto modelIt = models.find(blockName); - if (modelIt == models.end()) - return nullptr; - - return &modelIt->second; + return (modelIt == models.end()) ? nullptr : &modelIt->second; } void AssetManager::LoadBlockModels() { - std::function<void(std::string)> parseModel = [&](std::string ModelName) { if (models.find(ModelName) != models.end()) return; @@ -377,7 +372,6 @@ void AssetManager::LoadBlockModels() { continue; std::string modelName = dirEntry.path().stem().generic_string(); - parseModel("block/" + modelName); } } diff --git a/src/AssetManager.hpp b/src/AssetManager.hpp index 1169b7d..b828ee1 100644 --- a/src/AssetManager.hpp +++ b/src/AssetManager.hpp @@ -13,7 +13,8 @@ class Texture; struct TextureCoordinates { - TextureCoordinates(float x = -1, float y = -1, float w = -1, float h = -1) : x(x), y(y), w(w), h(h) {} + TextureCoordinates(float x = -1, float y = -1, float w = -1, float h = -1) + : x(x), y(y), w(w), h(h) {} bool operator==(const TextureCoordinates &rhs) const { return x == rhs.x && @@ -35,11 +36,12 @@ struct TextureCoordinates { struct BlockTextureId { //Block sides: 0 - bottom, 1 - top, 2 - north, 3 - south, 4 - west, 5 - east 6 - every side - BlockTextureId(int id = 0, int state = 0, int side = 6) : id(id), state(state), side(side) {} + BlockTextureId(int id = 0, int state = 0, int side = 6) + : id(id), state(state), side(side) {} - int id:9; - int state:4; - int side:3; + int id : 9; + int state : 4; + int side : 3; bool operator<(const BlockTextureId &rhs) const { @@ -59,7 +61,7 @@ struct BlockModel { bool IsBlock = false; std::string BlockName; - bool AmbientOcclusion=true; + bool AmbientOcclusion = true; enum DisplayVariants { thirdperson_righthand, @@ -72,6 +74,7 @@ struct BlockModel { fixed, DisplayVariantsCount, }; + struct DisplayData { Vector rotation; Vector translation; @@ -105,6 +108,7 @@ struct BlockModel { east, none, }; + struct FaceData { struct Uv { int x1, y1, x2, y2; @@ -122,7 +126,8 @@ struct BlockModel { std::vector<ElementData> Elements; }; -inline bool operator==(const BlockModel::ElementData::FaceData::Uv &lhs, const BlockModel::ElementData::FaceData::Uv &rhs) { +inline bool operator==(const BlockModel::ElementData::FaceData::Uv &lhs, + const BlockModel::ElementData::FaceData::Uv &rhs) { return lhs.x1 == rhs.x1 && lhs.y1 == rhs.y1 && lhs.x2 == rhs.x2 && lhs.y2 == rhs.y2; } diff --git a/src/Block.cpp b/src/Block.cpp index 667670d..303909b 100644 --- a/src/Block.cpp +++ b/src/Block.cpp @@ -2,7 +2,9 @@ Block::~Block() {} -Block::Block(unsigned short id, unsigned char state, unsigned char light, unsigned char sky) : id(id), state(state), light(light), sky (sky) {} +Block::Block(unsigned short id, unsigned char state, + unsigned char light, unsigned char sky) + : id(id), state(state), light(light), sky (sky) {} Block::Block() : id(0), state(0), light(0), sky(0) {} diff --git a/src/Block.hpp b/src/Block.hpp index 12d2907..cd01f9a 100644 --- a/src/Block.hpp +++ b/src/Block.hpp @@ -3,14 +3,13 @@ #include <functional> struct Block { - Block(); + Block(); + Block(unsigned short id, unsigned char state, + unsigned char light, unsigned char sky); + ~Block(); - Block(unsigned short id, unsigned char state, unsigned char light, unsigned char sky); - - ~Block(); - - unsigned short id : 13; - unsigned char state : 4; + unsigned short id : 13; + unsigned char state : 4; unsigned char light : 4; unsigned char sky : 4; }; @@ -20,6 +19,15 @@ struct BlockId { unsigned char state : 4; }; +enum BlockFacing { + Bottom = 0, + Top, + North, + South, + West, + East +}; + bool operator==(const BlockId& lhs, const BlockId &rhs); bool operator<(const BlockId& lhs, const BlockId &rhs); @@ -27,8 +35,7 @@ bool operator<(const BlockId& lhs, const BlockId &rhs); namespace std { template <> struct hash<BlockId> { - std::size_t operator()(const BlockId& k) const - { + std::size_t operator()(const BlockId& k) const { size_t id = std::hash<unsigned short>()(k.id); size_t state = std::hash<unsigned char>()(k.state); diff --git a/src/Entity.cpp b/src/Entity.cpp index d91e78d..a3a9527 100644 --- a/src/Entity.cpp +++ b/src/Entity.cpp @@ -1,14 +1,12 @@ #include "Entity.hpp" -VectorF Entity::DecodeVelocity(short x, short y, short z) -{ +VectorF Entity::DecodeVelocity(short x, short y, short z) { const float ticksPerSecond = 20; const double velMod = 1 / 8000.0; return VectorF(x * velMod * ticksPerSecond, y*velMod*ticksPerSecond, z*velMod*ticksPerSecond); } -VectorF Entity::DecodeDeltaPos(short deltaX, short deltaY, short deltaZ) -{ +VectorF Entity::DecodeDeltaPos(short deltaX, short deltaY, short deltaZ) { const double posMod = 4096.0; return VectorF(deltaX / posMod, deltaY / posMod, deltaZ / posMod); } @@ -29,75 +27,73 @@ double Entity::EncodePitch(double pitch) { return -pitch; } -Entity CreateObject(ObjectType type) -{ +Entity CreateObject(ObjectType type) { Entity entity; entity.type = EntityType::Object; switch (type) { - case ObjectType::Boat: - break; - case ObjectType::ItemStack: - entity.width = 0.25; - entity.height = 0.25; - break; - case ObjectType::AreaEffectCloud: - break; - case ObjectType::Minecart: - break; - case ObjectType::ActivatedTNT: - break; - case ObjectType::EnderCrystal: - break; - case ObjectType::TippedArrow: - break; - case ObjectType::Snowball: - break; - case ObjectType::Egg: - break; - case ObjectType::FireBall: - break; - case ObjectType::FireCharge: - break; - case ObjectType::ThrownEnderpearl: - break; - case ObjectType::WitherSkull: - break; - case ObjectType::ShulkerBullet: - break; - case ObjectType::LlamaSpit: - break; - case ObjectType::FallingObjects: - break; - case ObjectType::Itemframes: - break; - case ObjectType::EyeOfEnder: - break; - case ObjectType::ThrownPotion: - break; - case ObjectType::ThrownExpBottle: - break; - case ObjectType::FireworkRocket: - break; - case ObjectType::LeashKnot: - break; - case ObjectType::ArmorStand: - break; - case ObjectType::EvocationFangs: - break; - case ObjectType::FishingHook: - break; - case ObjectType::SpectralArrow: - break; - case ObjectType::DragonFireball: - break; - default: - break; + case ObjectType::Boat: + break; + case ObjectType::ItemStack: + entity.width = 0.25; + entity.height = 0.25; + break; + case ObjectType::AreaEffectCloud: + break; + case ObjectType::Minecart: + break; + case ObjectType::ActivatedTNT: + break; + case ObjectType::EnderCrystal: + break; + case ObjectType::TippedArrow: + break; + case ObjectType::Snowball: + break; + case ObjectType::Egg: + break; + case ObjectType::FireBall: + break; + case ObjectType::FireCharge: + break; + case ObjectType::ThrownEnderpearl: + break; + case ObjectType::WitherSkull: + break; + case ObjectType::ShulkerBullet: + break; + case ObjectType::LlamaSpit: + break; + case ObjectType::FallingObjects: + break; + case ObjectType::Itemframes: + break; + case ObjectType::EyeOfEnder: + break; + case ObjectType::ThrownPotion: + break; + case ObjectType::ThrownExpBottle: + break; + case ObjectType::FireworkRocket: + break; + case ObjectType::LeashKnot: + break; + case ObjectType::ArmorStand: + break; + case ObjectType::EvocationFangs: + break; + case ObjectType::FishingHook: + break; + case ObjectType::SpectralArrow: + break; + case ObjectType::DragonFireball: + break; + default: + break; } return entity; } -Entity CreateMob(MobType type) -{ +Entity CreateMob(MobType type) { Entity entity; entity.type = EntityType::Mob; return entity; diff --git a/src/Event.cpp b/src/Event.cpp index 08c9ee7..5c126bb 100644 --- a/src/Event.cpp +++ b/src/Event.cpp @@ -57,6 +57,7 @@ void EventListener::PollEvents() { std::lock_guard<std::recursive_mutex> rawLock (rawEventsMutex); if (rawEvents.empty()) return; + std::lock_guard<std::recursive_mutex> eventsLock (eventsMutex); std::lock_guard<std::recursive_mutex> handlersLock (handlersMutex); while (!rawEvents.empty()) { diff --git a/src/Event.hpp b/src/Event.hpp index 4cdcdc3..4e04a5a 100644 --- a/src/Event.hpp +++ b/src/Event.hpp @@ -55,7 +55,7 @@ public: template<typename T> const T& get() const { if (typeid(T) != data->Type()) - throw std::runtime_error(std::string("Type ") + typeid(T).name() + " encountered but " + data->Type().name() + " expected"); + throw std::runtime_error(std::string("Type ") + typeid(T).name() +" encountered but " + data->Type().name() + " expected"); return static_cast<EventData<T>*>(data.get())->data; } }; @@ -69,6 +69,7 @@ class EventListener { std::recursive_mutex eventsMutex; std::queue<Event> rawEvents; std::recursive_mutex rawEventsMutex; + public: EventListener(); diff --git a/src/Frustum.cpp b/src/Frustum.cpp index dbad920..e928e6b 100644 --- a/src/Frustum.cpp +++ b/src/Frustum.cpp @@ -3,7 +3,7 @@ #include <glm/gtc/type_ptr.hpp> void Frustum::NormalizePlane(FrustumSide side) { - float magnitude = (float)sqrt(frustum[side][A] * frustum[side][A] + frustum[side][B] * frustum[side][B] + frustum[side][C] * frustum[side][C]); + float magnitude = (float) sqrt(frustum[side][A] * frustum[side][A] + frustum[side][B] * frustum[side][B] + frustum[side][C] * frustum[side][C]); frustum[side][A] /= magnitude; frustum[side][B] /= magnitude; diff --git a/src/GameState.cpp b/src/GameState.cpp index 28e8007..6c2ad42 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -7,24 +7,30 @@ #include "Packet.hpp" void GameState::Update(float deltaTime) { - if (g_IsGameStarted) { - std::chrono::steady_clock clock; - static auto timeOfPreviousSendedPacket(clock.now()); + if (g_IsGameStarted) { + std::chrono::steady_clock clock; + static auto timeOfPreviousSendedPacket(clock.now()); auto delta = clock.now() - timeOfPreviousSendedPacket; - using namespace std::chrono_literals; + using namespace std::chrono_literals; if (delta >= 50ms) { - auto packetToSend = std::make_shared<PacketPlayerPositionAndLookSB>(player->pos.x, player->pos.y, player->pos.z, player->yaw, player->pitch, player->onGround); + auto packetToSend = std::make_shared<PacketPlayerPositionAndLookSB>( + player->pos.x, player->pos.y, player->pos.z, + player->yaw, player->pitch, player->onGround); + auto packet = std::static_pointer_cast<Packet>(packetToSend); - PUSH_EVENT("SendPacket",packet); + PUSH_EVENT("SendPacket", packet); timeOfPreviousSendedPacket = clock.now(); } bool prevOnGround = player->onGround; world.UpdatePhysics(deltaTime); if (player->onGround != prevOnGround) { - auto updatePacket = std::make_shared<PacketPlayerPosition>(player->pos.x, player->pos.y, player->pos.z, player->onGround); + auto updatePacket = std::make_shared<PacketPlayerPosition>( + player->pos.x, player->pos.y, + player->pos.z, player->onGround); + auto packet = std::static_pointer_cast<Packet>(updatePacket); - PUSH_EVENT("SendPacket",packet); + PUSH_EVENT("SendPacket", packet); } @@ -37,15 +43,26 @@ void GameState::Update(float deltaTime) { direction.z = sin(glm::radians(playerYaw)) * cos(glm::radians(playerPitch)); RaycastResult raycast = world.Raycast(player->pos + player->EyeOffset, direction); - selectedBlock = raycast.isHit ? raycast.hitBlock : Vector(0,0,0); - distanceToSelectedBlock = raycast.isHit ? (player->pos - raycast.hitPos).GetLength() : 0.0f; + if (raycast.isHit != isBlockSelected || ((raycast.isHit == true && isBlockSelected == true) && + selectedBlock != raycast.hitBlock)) { + PUSH_EVENT("SelectedBlockChanged", 0); + } + + if (raycast.isHit) { + selectedBlock = raycast.hitBlock; + distanceToSelectedBlock = (player->pos - raycast.hitPos).GetLength(); + } else { + selectedBlock = Vector(0, 0, 0); + distanceToSelectedBlock = 0.0f; + } + + isBlockSelected = raycast.isHit; raycastHit = raycast.hitPos; - } + } } -void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) -{ - switch ((PacketNamePlayCB)ptr->GetPacketId()) { +void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) { + switch ((PacketNamePlayCB) ptr->GetPacketId()) { case SpawnObject: { auto packet = std::static_pointer_cast<PacketSpawnObject>(ptr); Entity entity = CreateObject(static_cast<ObjectType>(packet->Type)); @@ -60,10 +77,13 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) PUSH_EVENT("EntityChanged", entity.entityId); break; } + case SpawnExperienceOrb: break; + case SpawnGlobalEntity: break; + case SpawnMob: { auto packet = std::static_pointer_cast<PacketSpawnMob>(ptr); Entity entity; @@ -78,8 +98,10 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) PUSH_EVENT("EntityChanged", entity.entityId); break; } + case SpawnPainting: break; + case SpawnPlayer: { auto packet = std::static_pointer_cast<PacketSpawnPlayer>(ptr); Entity entity; @@ -105,28 +127,33 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) break; case BlockAction: break; + case BlockChange: { auto packet = std::static_pointer_cast<PacketBlockChange>(ptr); world.ParseChunkData(packet); break; } + case BossBar: break; case ServerDifficulty: break; case TabCompleteCB: break; + case ChatMessageCB: { auto packet = std::static_pointer_cast<PacketChatMessageCB>(ptr); LOG(INFO) << "Message (" << int(packet->Position) << "): " << packet->JsonData.text; PUSH_EVENT("ChatMessageReceived", std::make_tuple(packet->JsonData, packet->Position)); break; } + case MultiBlockChange: { auto packet = std::static_pointer_cast<PacketMultiBlockChange>(ptr); world.ParseChunkData(packet); break; } + case ConfirmTransactionCB: { auto packet = std::static_pointer_cast<PacketConfirmTransactionCB>(ptr); if (packet->WindowId == 0) { @@ -138,14 +165,17 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) } break; } + case CloseWindowCB: break; + case OpenWindow: { auto packet = std::static_pointer_cast<PacketOpenWindow>(ptr); LOG(INFO) << "Open new window " << packet->WindowTitle << ": " << packet->WindowId; break; } + case WindowItems: { auto packet = std::static_pointer_cast<PacketWindowItems>(ptr); if (packet->WindowId == 0) { @@ -154,8 +184,10 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) } break; } + case WindowProperty: break; + case SetSlot: { auto packet = std::static_pointer_cast<PacketSetSlot>(ptr); if (packet->WindowId == 0) { @@ -163,41 +195,51 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) } break; } + case SetCooldown: break; case PluginMessageCB: break; case NamedSoundEffect: break; + case DisconnectPlay: { auto packet = std::static_pointer_cast<PacketDisconnectPlay>(ptr); LOG(INFO) << "Disconnect reason: " << packet->Reason; PUSH_EVENT("Disconnected", packet->Reason); break; } + case EntityStatus: break; case Explosion: break; + case UnloadChunk: { auto packet = std::static_pointer_cast<PacketUnloadChunk>(ptr); world.ParseChunkData(packet); break; } + case ChangeGameState: break; - case KeepAliveCB: + + case KeepAliveCB: { LOG(WARNING) << "Receive KeepAlive packet in GameState handler"; break; + } + case ChunkData: { auto packet = std::static_pointer_cast<PacketChunkData>(ptr); world.ParseChunkData(packet); break; } + case Effect: break; case Particle: break; + case JoinGame: { auto packet = std::static_pointer_cast<PacketJoinGame>(ptr); Entity entity; @@ -219,8 +261,10 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) PUSH_EVENT("PlayerConnected", 0); break; } + case Map: break; + case EntityRelativeMove: { auto packet = std::static_pointer_cast<PacketEntityRelativeMove>(ptr); Entity &entity = world.GetEntity(packet->EntityId); @@ -229,6 +273,7 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) LOG(INFO) << "M: " << packet->EntityId; break; } + case EntityLookAndRelativeMove: { auto packet = std::static_pointer_cast<PacketEntityLookAndRelativeMove>(ptr); Entity &entity = world.GetEntity(packet->EntityId); @@ -237,6 +282,7 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) entity.yaw = packet->Yaw / 256.0; break; } + case EntityLook: { auto packet = std::static_pointer_cast<PacketEntityLook>(ptr); Entity &entity = world.GetEntity(packet->EntityId); @@ -245,6 +291,7 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) //LOG(INFO) << "L: " << packet->EntityId; break; } + case EntityCB: break; case VehicleMove: @@ -257,13 +304,14 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) break; case PlayerListItem: break; + case PlayerPositionAndLookCB: { auto packet = std::static_pointer_cast<PacketPlayerPositionAndLookCB>(ptr); if ((packet->Flags & 0x10) != 0) { player->pitch += packet->Pitch; } else { player->pitch = packet->Pitch; - }; + } if ((packet->Flags & 0x08) != 0) { player->yaw += packet->Yaw; @@ -306,10 +354,12 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) PUSH_EVENT("SendPacket",std::static_pointer_cast<Packet>(packetPerformRespawn)); break; } + case UseBed: break; case UnlockRecipes: break; + case DestroyEntities: { auto packet = std::static_pointer_cast<PacketDestroyEntities>(ptr); for (unsigned int entityId : packet->EntityIds) { @@ -317,6 +367,7 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) } break; } + case RemoveEntityEffect: break; case ResourcePackSend: @@ -339,16 +390,19 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) break; case AttachEntity: break; + case EntityVelocity: { auto packet = std::static_pointer_cast<PacketEntityVelocity>(ptr); Entity &entity = world.GetEntity(packet->EntityId); entity.vel = Entity::DecodeVelocity(packet->VelocityX, packet->VelocityY, packet->VelocityZ); break; } + case EntityEquipment: break; case SetExperience: break; + case UpdateHealth: { auto packet = std::static_pointer_cast<PacketUpdateHealth>(ptr); g_PlayerHealth = packet->Health; @@ -359,6 +413,7 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) } break; } + case ScoreboardObjective: break; case SetPassengers: @@ -367,6 +422,7 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) break; case UpdateScore: break; + case SpawnPosition: { auto packet = std::static_pointer_cast<PacketSpawnPosition>(ptr); g_SpawnPosition = packet->Location; @@ -374,12 +430,14 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) << g_SpawnPosition.z; break; } + case TimeUpdate: { auto packet = std::static_pointer_cast<PacketTimeUpdate>(ptr); WorldAge = packet->WorldAge; TimeOfDay = packet->TimeOfDay; break; } + case Title: break; case SoundEffect: @@ -388,6 +446,7 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) break; case CollectItem: break; + case EntityTeleport: { auto packet = std::static_pointer_cast<PacketEntityTeleport>(ptr); Entity &entity = world.GetEntity(packet->EntityId); @@ -396,6 +455,7 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) entity.yaw = packet->Yaw / 256.0; break; } + case Advancements: break; case EntityProperties: @@ -403,6 +463,7 @@ void GameState::UpdatePacket(std::shared_ptr<Packet> ptr) case EntityEffect: break; } + while (!playerInventory.pendingTransactions.empty()) { auto packet = std::make_shared<PacketClickWindow>(playerInventory.pendingTransactions.front()); playerInventory.pendingTransactions.pop(); @@ -431,25 +492,33 @@ void GameState::HandleMovement(GameState::Direction direction, float deltaTime) glm::vec3 vel = player->vel.glm(); switch (direction) { - case FORWARD: - vel += front * velocity; - break; - case BACKWARD: - vel -= front * velocity; - break; - case RIGHT: - vel += right * velocity; - break; - case LEFT: - vel -= right * velocity; - break; - case JUMP: - if (player->onGround) { - vel.y += 10; - player->onGround = false; - } - break; - } + case FORWARD: { + vel += front * velocity; + break; + } + + case BACKWARD: { + vel -= front * velocity; + break; + } + + case RIGHT: { + vel += right * velocity; + break; + } + + case LEFT: { + vel -= right * velocity; + break; + } + + case JUMP: + if (player->onGround) { + vel.y += 10; + player->onGround = false; + } + break; + } player->vel = VectorF(vel.x, vel.y, vel.z); } @@ -485,15 +554,75 @@ glm::mat4 GameState::GetViewMatrix() { return glm::lookAt(eyePos, eyePos + front, up); } +// TODO: it should actually be something like this: +// function start_digging(): +// send_packet(packet_type=start_digging_packet) +// delay(time=selected_block_dig_time, action=finish_digging) void GameState::StartDigging() { + if (!isBlockSelected) + return; + auto packetStart = std::make_shared<PacketPlayerDigging>(0,selectedBlock,1); - auto packetStop = std::make_shared<PacketPlayerDigging>(2,selectedBlock,1); auto packet = std::static_pointer_cast<Packet>(packetStart); PUSH_EVENT("SendPacket",packet); - packet = std::static_pointer_cast<Packet>(packetStop); + + FinishDigging(); +} + +void GameState::FinishDigging() { + auto packetFinish = std::make_shared<PacketPlayerDigging>(2,selectedBlock,1); + auto packet = std::static_pointer_cast<Packet>(packetFinish); PUSH_EVENT("SendPacket",packet); } -void GameState::StopDigging() { +// TODO: it should actually be something like this: +// function cancel_digging(): +// if finish_digging is in delayed_actions: +// send_packet(packet_type=start_digging_packet) +// remove_delayed_action(finish_digging) +void GameState::CancelDigging() { + auto packetCancel = std::make_shared<PacketPlayerDigging>(1,selectedBlock,1); + auto packet = std::static_pointer_cast<Packet>(packetCancel); + PUSH_EVENT("SendPacket", packet); +} + +BlockFacing detectHitFace(VectorF raycastHit, Vector selectedBlock) { + auto vec = VectorF(selectedBlock.x + .5, selectedBlock.y + .5, selectedBlock.z +.5) - raycastHit; + + // TODO: move these vectors to Vector.hpp + static const auto vecUp = VectorF(0, 1, 0); + static const auto vecRight = VectorF(1, 0, 0); + static const auto vecForward = VectorF(0, 0, -1); + const double up = vec.cosBetween(vecUp); + const double down = -up; + const double right = vec.cosBetween(vecRight); + const double left = -right; + const double forward = vec.cosBetween(vecForward); + const double backward = -forward; + + const double min_cos = _min(up, down, right, left, forward, backward); + if (min_cos == down) + return BlockFacing::Bottom; + else if (min_cos == up) + return BlockFacing::Top; + else if (min_cos == forward) + return BlockFacing::North; + else if (min_cos == backward) + return BlockFacing::South; + else if (min_cos == left) + return BlockFacing::West; + else return BlockFacing::East; } + +void GameState::PlaceBlock() { + if (!isBlockSelected) + return; + + BlockFacing face = detectHitFace(raycastHit, selectedBlock); + auto packetPlace = std::make_shared<PacketPlayerBlockPlacement>( + selectedBlock, (unsigned char) face, 0, 0, 0, 0); + + auto packet = std::static_pointer_cast<Packet>(packetPlace); + PUSH_EVENT("SendPacket", packet); +}
\ No newline at end of file diff --git a/src/GameState.hpp b/src/GameState.hpp index fac9923..81ab3dc 100644 --- a/src/GameState.hpp +++ b/src/GameState.hpp @@ -20,40 +20,42 @@ public: ~GameState() = default; - void Update(float deltaTime); + void Update(float deltaTime); void UpdatePacket(std::shared_ptr<Packet> ptr); - enum Direction { - FORWARD, BACKWARD, LEFT, RIGHT, JUMP - }; - void StartDigging(); - void StopDigging(); - void HandleMovement(GameState::Direction direction, float deltaTime); - void HandleRotation(double yaw, double pitch); - glm::mat4 GetViewMatrix(); + enum Direction { + FORWARD, BACKWARD, LEFT, RIGHT, JUMP + }; + void StartDigging(); + void FinishDigging(); + void CancelDigging(); + void PlaceBlock(); + void HandleMovement(GameState::Direction direction, float deltaTime); + void HandleRotation(double yaw, double pitch); + glm::mat4 GetViewMatrix(); Entity* player; - World world; + World world; - std::string g_PlayerUuid = ""; - std::string g_PlayerName = ""; - bool g_IsGameStarted = false; - int g_PlayerEid = 0; - int g_Gamemode = 0; - int g_Dimension = 0; - unsigned char g_Difficulty = 0; - unsigned char g_MaxPlayers = 0; - std::string g_LevelType = ""; - bool g_ReducedDebugInfo = false; - Vector g_SpawnPosition; - bool g_PlayerInvulnerable = false; - bool g_PlayerFlying = false; - bool g_PlayerAllowFlying = false; - bool g_PlayerCreativeMode = false; - float g_PlayerFlyingSpeed = 0; - float g_PlayerFovModifier = 0; - float g_PlayerHealth = 0; + std::string g_PlayerUuid = ""; + std::string g_PlayerName = ""; + bool g_IsGameStarted = false; + int g_PlayerEid = 0; + int g_Gamemode = 0; + int g_Dimension = 0; + unsigned char g_Difficulty = 0; + unsigned char g_MaxPlayers = 0; + std::string g_LevelType = ""; + bool g_ReducedDebugInfo = false; + Vector g_SpawnPosition; + bool g_PlayerInvulnerable = false; + bool g_PlayerFlying = false; + bool g_PlayerAllowFlying = false; + bool g_PlayerCreativeMode = false; + float g_PlayerFlyingSpeed = 0; + float g_PlayerFovModifier = 0; + float g_PlayerHealth = 0; long long WorldAge = 0; long long TimeOfDay = 0; @@ -61,7 +63,8 @@ public: Window playerInventory; std::vector<Window> openedWindows; - Vector selectedBlock; - float distanceToSelectedBlock; - VectorF raycastHit; + bool isBlockSelected; + Vector selectedBlock; + float distanceToSelectedBlock; + VectorF raycastHit; }; diff --git a/src/GlobalState.cpp b/src/GlobalState.cpp index ce8cb05..8d75bac 100644 --- a/src/GlobalState.cpp +++ b/src/GlobalState.cpp @@ -42,9 +42,10 @@ void InitEvents() { isPhysRunning = true; threadPhys = std::thread(&PhysExec); try { - nc = std::make_unique<NetworkClient>(std::get<0>(data), std::get<1>(data), std::get<2>(data)); - } - catch (std::exception &e) { + nc = std::make_unique<NetworkClient>(std::get<0>(data), + std::get<1>(data), + std::get<2>(data)); + } catch (std::exception &e) { LOG(WARNING) << "Connection failed"; PUSH_EVENT("ConnectionFailed", std::string(e.what())); isPhysRunning = false; @@ -98,47 +99,47 @@ void PhysExec() { if (!gs) return; switch (eventData.get<SDL_Scancode>()) { - case SDL_SCANCODE_W: - isMoving[GameState::FORWARD] = true; - break; - case SDL_SCANCODE_A: - isMoving[GameState::LEFT] = true; - break; - case SDL_SCANCODE_S: - isMoving[GameState::BACKWARD] = true; - break; - case SDL_SCANCODE_D: - isMoving[GameState::RIGHT] = true; - break; - case SDL_SCANCODE_SPACE: - isMoving[GameState::JUMP] = true; - break; - default: - break; - } + case SDL_SCANCODE_W: + isMoving[GameState::FORWARD] = true; + break; + case SDL_SCANCODE_A: + isMoving[GameState::LEFT] = true; + break; + case SDL_SCANCODE_S: + isMoving[GameState::BACKWARD] = true; + break; + case SDL_SCANCODE_D: + isMoving[GameState::RIGHT] = true; + break; + case SDL_SCANCODE_SPACE: + isMoving[GameState::JUMP] = true; + break; + default: + break; + } }); listener.RegisterHandler("KeyReleased", [](const Event& eventData) { if (!gs) return; switch (eventData.get<SDL_Scancode>()) { - case SDL_SCANCODE_W: - isMoving[GameState::FORWARD] = false; - break; - case SDL_SCANCODE_A: - isMoving[GameState::LEFT] = false; - break; - case SDL_SCANCODE_S: - isMoving[GameState::BACKWARD] = false; - break; - case SDL_SCANCODE_D: - isMoving[GameState::RIGHT] = false; - break; - case SDL_SCANCODE_SPACE: - isMoving[GameState::JUMP] = false; - break; - default: - break; + case SDL_SCANCODE_W: + isMoving[GameState::FORWARD] = false; + break; + case SDL_SCANCODE_A: + isMoving[GameState::LEFT] = false; + break; + case SDL_SCANCODE_S: + isMoving[GameState::BACKWARD] = false; + break; + case SDL_SCANCODE_D: + isMoving[GameState::RIGHT] = false; + break; + case SDL_SCANCODE_SPACE: + isMoving[GameState::JUMP] = false; + break; + default: + break; } }); @@ -159,7 +160,16 @@ void PhysExec() { }); listener.RegisterHandler("LmbReleased",[](const Event& eventData) { - gs->StopDigging(); + gs->CancelDigging(); + }); + + listener.RegisterHandler("RmbPressed", [](const Event& eventData) { + gs->PlaceBlock(); + }); + + listener.RegisterHandler("SelectedBlockChanged", [](const Event& eventData) { + //TODO: + //gs->CancelDigging(); }); LoopExecutionTimeController timer(std::chrono::milliseconds(8)); diff --git a/src/Packet.hpp b/src/Packet.hpp index 1920ea6..7b18ce1 100644 --- a/src/Packet.hpp +++ b/src/Packet.hpp @@ -3,520 +3,520 @@ #include "Stream.hpp" enum PacketNameLoginSB { - LoginStart = 0x00, - EncryptionResponse = 0x01, + LoginStart = 0x00, + EncryptionResponse = 0x01, }; enum PacketNamePlaySB { - TeleportConfirm = 0x00, - TabCompleteSB, - ChatMessageSB, - ClientStatus, - ClientSettings, - ConfirmTransactionSB, - EnchantItem, - ClickWindow, - CloseWindowSB, - PluginMessageSB, - UseEntity, - KeepAliveSB, - Player, - PlayerPosition, - PlayerPositionAndLookSB, - PlayerLook, - VehicleMoveSB, - SteerBoat, + TeleportConfirm = 0x00, + TabCompleteSB, + ChatMessageSB, + ClientStatus, + ClientSettings, + ConfirmTransactionSB, + EnchantItem, + ClickWindow, + CloseWindowSB, + PluginMessageSB, + UseEntity, + KeepAliveSB, + Player, + PlayerPosition, + PlayerPositionAndLookSB, + PlayerLook, + VehicleMoveSB, + SteerBoat, CraftRecipeRequest, - PlayerAbilitiesSB, - PlayerDigging, - EntityAction, - SteerVehicle, - CraftingBookData, - ResourcePackStatus, - AdvancementTab, - HeldItemChangeSB, - CreativeInventoryAction, - UpdateSign, - AnimationSB, - Spectate, - PlayerBlockPlacement, - UseItem, + PlayerAbilitiesSB, + PlayerDigging, + EntityAction, + SteerVehicle, + CraftingBookData, + ResourcePackStatus, + AdvancementTab, + HeldItemChangeSB, + CreativeInventoryAction, + UpdateSign, + AnimationSB, + Spectate, + PlayerBlockPlacement, + UseItem, }; enum PacketNameHandshakingCB { - Handshake = 0x00, + Handshake = 0x00, }; enum PacketNameLoginCB { - Disconnect = 0x00, - EncryptionRequest = 0x01, - LoginSuccess = 0x02, - SetCompression = 0x03, + Disconnect = 0x00, + EncryptionRequest = 0x01, + LoginSuccess = 0x02, + SetCompression = 0x03, }; enum PacketNamePlayCB { - SpawnObject = 0x00, - SpawnExperienceOrb, - SpawnGlobalEntity, - SpawnMob, - SpawnPainting, - SpawnPlayer, - AnimationCB, - Statistics, - BlockBreakAnimation, - UpdateBlockEntity, - BlockAction, - BlockChange, - BossBar, - ServerDifficulty, - TabCompleteCB, - ChatMessageCB, - MultiBlockChange, - ConfirmTransactionCB, - CloseWindowCB, - OpenWindow, - WindowItems, - WindowProperty, - SetSlot, - SetCooldown, - PluginMessageCB, - NamedSoundEffect, - DisconnectPlay, - EntityStatus, - Explosion, - UnloadChunk, - ChangeGameState, - KeepAliveCB, - ChunkData, - Effect, - Particle, - JoinGame, - Map, - EntityRelativeMove, - EntityLookAndRelativeMove, - EntityLook, - EntityCB, - VehicleMove, - OpenSignEditor, + SpawnObject = 0x00, + SpawnExperienceOrb, + SpawnGlobalEntity, + SpawnMob, + SpawnPainting, + SpawnPlayer, + AnimationCB, + Statistics, + BlockBreakAnimation, + UpdateBlockEntity, + BlockAction, + BlockChange, + BossBar, + ServerDifficulty, + TabCompleteCB, + ChatMessageCB, + MultiBlockChange, + ConfirmTransactionCB, + CloseWindowCB, + OpenWindow, + WindowItems, + WindowProperty, + SetSlot, + SetCooldown, + PluginMessageCB, + NamedSoundEffect, + DisconnectPlay, + EntityStatus, + Explosion, + UnloadChunk, + ChangeGameState, + KeepAliveCB, + ChunkData, + Effect, + Particle, + JoinGame, + Map, + EntityRelativeMove, + EntityLookAndRelativeMove, + EntityLook, + EntityCB, + VehicleMove, + OpenSignEditor, CraftRecipeResponse, - PlayerAbilitiesCB, - CombatEvent, - PlayerListItem, - PlayerPositionAndLookCB, - UseBed, - UnlockRecipes, - DestroyEntities, - RemoveEntityEffect, - ResourcePackSend, - Respawn, - EntityHeadLook, - SelectAdvancementTab, - WorldBorder, - Camera, - HeldItemChangeCB, - DisplayScoreboard, - EntityMetadata, - AttachEntity, - EntityVelocity, - EntityEquipment, - SetExperience, - UpdateHealth, - ScoreboardObjective, - SetPassengers, - Teams, - UpdateScore, - SpawnPosition, - TimeUpdate, - Title, - SoundEffect, - PlayerListHeaderAndFooter, - CollectItem, - EntityTeleport, - Advancements, - EntityProperties, - EntityEffect, + PlayerAbilitiesCB, + CombatEvent, + PlayerListItem, + PlayerPositionAndLookCB, + UseBed, + UnlockRecipes, + DestroyEntities, + RemoveEntityEffect, + ResourcePackSend, + Respawn, + EntityHeadLook, + SelectAdvancementTab, + WorldBorder, + Camera, + HeldItemChangeCB, + DisplayScoreboard, + EntityMetadata, + AttachEntity, + EntityVelocity, + EntityEquipment, + SetExperience, + UpdateHealth, + ScoreboardObjective, + SetPassengers, + Teams, + UpdateScore, + SpawnPosition, + TimeUpdate, + Title, + SoundEffect, + PlayerListHeaderAndFooter, + CollectItem, + EntityTeleport, + Advancements, + EntityProperties, + EntityEffect, }; struct Packet { - virtual ~Packet() = default; - virtual void ToStream(StreamOutput *stream) = 0; - virtual void FromStream(StreamInput *stream) = 0; - virtual int GetPacketId() = 0; + virtual ~Packet() = default; + virtual void ToStream(StreamOutput *stream) = 0; + virtual void FromStream(StreamInput *stream) = 0; + virtual int GetPacketId() = 0; }; struct PacketHandshake : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteVarInt(protocolVersion); - stream->WriteString(serverAddress); - stream->WriteUShort(serverPort); - stream->WriteVarInt(nextState); - } - - void FromStream(StreamInput *stream) override { - protocolVersion = stream->ReadVarInt(); - serverAddress = stream->ReadString(); - serverPort = stream->ReadUShort(); - nextState = stream->ReadVarInt(); - } - - int GetPacketId() override { - return PacketNameHandshakingCB::Handshake; - } - - int protocolVersion; - std::string serverAddress; - unsigned short serverPort; - int nextState; + void ToStream(StreamOutput *stream) override { + stream->WriteVarInt(protocolVersion); + stream->WriteString(serverAddress); + stream->WriteUShort(serverPort); + stream->WriteVarInt(nextState); + } + + void FromStream(StreamInput *stream) override { + protocolVersion = stream->ReadVarInt(); + serverAddress = stream->ReadString(); + serverPort = stream->ReadUShort(); + nextState = stream->ReadVarInt(); + } + + int GetPacketId() override { + return PacketNameHandshakingCB::Handshake; + } + + int protocolVersion; + std::string serverAddress; + unsigned short serverPort; + int nextState; }; struct PacketLoginStart : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteString(Username); - } + void ToStream(StreamOutput *stream) override { + stream->WriteString(Username); + } - void FromStream(StreamInput *stream) override { - Username = stream->ReadString(); - } + void FromStream(StreamInput *stream) override { + Username = stream->ReadString(); + } - int GetPacketId() override { - return PacketNameLoginSB::LoginStart; - } + int GetPacketId() override { + return PacketNameLoginSB::LoginStart; + } - std::string Username; + std::string Username; }; struct PacketLoginSuccess : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteString(Uuid); - stream->WriteString(Username); - } - - void FromStream(StreamInput *stream) override { - Uuid = stream->ReadString(); - Username = stream->ReadString(); - } - - int GetPacketId() override { - return PacketNameLoginCB::LoginSuccess; - } - - std::string Uuid; - std::string Username; + void ToStream(StreamOutput *stream) override { + stream->WriteString(Uuid); + stream->WriteString(Username); + } + + void FromStream(StreamInput *stream) override { + Uuid = stream->ReadString(); + Username = stream->ReadString(); + } + + int GetPacketId() override { + return PacketNameLoginCB::LoginSuccess; + } + + std::string Uuid; + std::string Username; }; struct PacketJoinGame : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteInt(EntityId); - stream->WriteUByte(Gamemode); - stream->WriteInt(Dimension); - stream->WriteUByte(Difficulty); - stream->WriteUByte(MaxPlayers); - stream->WriteString(LevelType); - stream->WriteBool(ReducedDebugInfo); - } - - void FromStream(StreamInput *stream) override { - EntityId = stream->ReadInt(); - Gamemode = stream->ReadUByte(); - Dimension = stream->ReadInt(); - Difficulty = stream->ReadUByte(); - MaxPlayers = stream->ReadUByte(); - LevelType = stream->ReadString(); - ReducedDebugInfo = stream->ReadBool(); - } - - int GetPacketId() override { - return PacketNamePlayCB::JoinGame; - } - - int EntityId; - unsigned char Gamemode; - int Dimension; - unsigned char Difficulty; - unsigned char MaxPlayers; - std::string LevelType; - bool ReducedDebugInfo; + void ToStream(StreamOutput *stream) override { + stream->WriteInt(EntityId); + stream->WriteUByte(Gamemode); + stream->WriteInt(Dimension); + stream->WriteUByte(Difficulty); + stream->WriteUByte(MaxPlayers); + stream->WriteString(LevelType); + stream->WriteBool(ReducedDebugInfo); + } + + void FromStream(StreamInput *stream) override { + EntityId = stream->ReadInt(); + Gamemode = stream->ReadUByte(); + Dimension = stream->ReadInt(); + Difficulty = stream->ReadUByte(); + MaxPlayers = stream->ReadUByte(); + LevelType = stream->ReadString(); + ReducedDebugInfo = stream->ReadBool(); + } + + int GetPacketId() override { + return PacketNamePlayCB::JoinGame; + } + + int EntityId; + unsigned char Gamemode; + int Dimension; + unsigned char Difficulty; + unsigned char MaxPlayers; + std::string LevelType; + bool ReducedDebugInfo; }; struct PacketDisconnectPlay : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteString(Reason); //TODO: Implement chat-wrapper - } + void ToStream(StreamOutput *stream) override { + stream->WriteString(Reason); //TODO: Implement chat-wrapper + } - void FromStream(StreamInput *stream) override { - Reason = stream->ReadChat().text; - } + void FromStream(StreamInput *stream) override { + Reason = stream->ReadChat().text; + } - int GetPacketId() override { - return PacketNamePlayCB::DisconnectPlay; - } + int GetPacketId() override { + return PacketNamePlayCB::DisconnectPlay; + } - std::string Reason; + std::string Reason; }; struct PacketSpawnPosition : Packet { - void ToStream(StreamOutput *stream) override { - stream->WritePosition(Location); - } + void ToStream(StreamOutput *stream) override { + stream->WritePosition(Location); + } - void FromStream(StreamInput *stream) override { - Location = stream->ReadPosition(); - } + void FromStream(StreamInput *stream) override { + Location = stream->ReadPosition(); + } - int GetPacketId() override { - return PacketNamePlayCB::SpawnPosition; - } + int GetPacketId() override { + return PacketNamePlayCB::SpawnPosition; + } - Vector Location; + Vector Location; }; struct PacketKeepAliveCB : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteLong(KeepAliveId); - } + void ToStream(StreamOutput *stream) override { + stream->WriteLong(KeepAliveId); + } - void FromStream(StreamInput *stream) override { - KeepAliveId = stream->ReadLong(); - } + void FromStream(StreamInput *stream) override { + KeepAliveId = stream->ReadLong(); + } - int GetPacketId() override { - return PacketNamePlayCB::KeepAliveCB; - } + int GetPacketId() override { + return PacketNamePlayCB::KeepAliveCB; + } - long long KeepAliveId; + long long KeepAliveId; }; struct PacketKeepAliveSB : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteLong(KeepAliveId); - } + void ToStream(StreamOutput *stream) override { + stream->WriteLong(KeepAliveId); + } - void FromStream(StreamInput *stream) override { - KeepAliveId = stream->ReadLong(); - } + void FromStream(StreamInput *stream) override { + KeepAliveId = stream->ReadLong(); + } - int GetPacketId() override { - return PacketNamePlaySB::KeepAliveSB; - } + int GetPacketId() override { + return PacketNamePlaySB::KeepAliveSB; + } - long long KeepAliveId; + long long KeepAliveId; - PacketKeepAliveSB(int KeepAliveId) : KeepAliveId(KeepAliveId) {} + PacketKeepAliveSB(int KeepAliveId) : KeepAliveId(KeepAliveId) {} }; struct PacketPlayerPositionAndLookCB : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteDouble(X); - stream->WriteDouble(Y); - stream->WriteDouble(Z); - stream->WriteFloat(Yaw); - stream->WriteFloat(Pitch); - stream->WriteUByte(Flags); - stream->WriteVarInt(TeleportId); - } - - void FromStream(StreamInput *stream) override { - X = stream->ReadDouble(); - Y = stream->ReadDouble(); - Z = stream->ReadDouble(); - Yaw = stream->ReadFloat(); - Pitch = stream->ReadFloat(); - Flags = stream->ReadUByte(); - TeleportId = stream->ReadVarInt(); - } - - int GetPacketId() override { - return PacketNamePlayCB::PlayerPositionAndLookCB; - } - - double X; - double Y; - double Z; - float Yaw; - float Pitch; - unsigned char Flags; - int TeleportId; + void ToStream(StreamOutput *stream) override { + stream->WriteDouble(X); + stream->WriteDouble(Y); + stream->WriteDouble(Z); + stream->WriteFloat(Yaw); + stream->WriteFloat(Pitch); + stream->WriteUByte(Flags); + stream->WriteVarInt(TeleportId); + } + + void FromStream(StreamInput *stream) override { + X = stream->ReadDouble(); + Y = stream->ReadDouble(); + Z = stream->ReadDouble(); + Yaw = stream->ReadFloat(); + Pitch = stream->ReadFloat(); + Flags = stream->ReadUByte(); + TeleportId = stream->ReadVarInt(); + } + + int GetPacketId() override { + return PacketNamePlayCB::PlayerPositionAndLookCB; + } + + double X; + double Y; + double Z; + float Yaw; + float Pitch; + unsigned char Flags; + int TeleportId; }; struct PacketTeleportConfirm : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteVarInt(TeleportId); - } + void ToStream(StreamOutput *stream) override { + stream->WriteVarInt(TeleportId); + } - void FromStream(StreamInput *stream) override { - TeleportId = stream->ReadVarInt(); - } + void FromStream(StreamInput *stream) override { + TeleportId = stream->ReadVarInt(); + } - int GetPacketId() override { - return PacketNamePlaySB::TeleportConfirm; - } + int GetPacketId() override { + return PacketNamePlaySB::TeleportConfirm; + } - int TeleportId; + int TeleportId; - PacketTeleportConfirm(int TeleportId) : TeleportId(TeleportId) {} + PacketTeleportConfirm(int TeleportId) : TeleportId(TeleportId) {} }; struct PacketClientStatus : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteVarInt(ActionId); - } + void ToStream(StreamOutput *stream) override { + stream->WriteVarInt(ActionId); + } - void FromStream(StreamInput *stream) override { - ActionId = stream->ReadVarInt(); - } + void FromStream(StreamInput *stream) override { + ActionId = stream->ReadVarInt(); + } - int GetPacketId() override { - return PacketNamePlaySB::ClientStatus; - } + int GetPacketId() override { + return PacketNamePlaySB::ClientStatus; + } - int ActionId; + int ActionId; - PacketClientStatus(int ActionId) : ActionId(ActionId) {} + PacketClientStatus(int ActionId) : ActionId(ActionId) {} }; struct PacketPlayerPositionAndLookSB : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteDouble(X); - stream->WriteDouble(FeetY); - stream->WriteDouble(Z); - stream->WriteFloat(Yaw); - stream->WriteFloat(Pitch); - stream->WriteBool(OnGround); - } - - void FromStream(StreamInput *stream) override { - X = stream->ReadDouble(); - FeetY = stream->ReadDouble(); - Z = stream->ReadDouble(); - Yaw = stream->ReadFloat(); - Pitch = stream->ReadFloat(); - OnGround = stream->ReadBool(); - } - - int GetPacketId() override { - return PacketNamePlaySB::PlayerPositionAndLookSB; - } - - - double X; - double FeetY; - double Z; - float Yaw; - float Pitch; - bool OnGround; - - PacketPlayerPositionAndLookSB(double X, double FeetY, double Z, - float Yaw, float Pitch, bool OnGround) : X(X), FeetY(FeetY), Z(Z), Yaw(Yaw), - Pitch(Pitch), OnGround(OnGround) {} + void ToStream(StreamOutput *stream) override { + stream->WriteDouble(X); + stream->WriteDouble(FeetY); + stream->WriteDouble(Z); + stream->WriteFloat(Yaw); + stream->WriteFloat(Pitch); + stream->WriteBool(OnGround); + } + + void FromStream(StreamInput *stream) override { + X = stream->ReadDouble(); + FeetY = stream->ReadDouble(); + Z = stream->ReadDouble(); + Yaw = stream->ReadFloat(); + Pitch = stream->ReadFloat(); + OnGround = stream->ReadBool(); + } + + int GetPacketId() override { + return PacketNamePlaySB::PlayerPositionAndLookSB; + } + + + double X; + double FeetY; + double Z; + float Yaw; + float Pitch; + bool OnGround; + + PacketPlayerPositionAndLookSB(double X, double FeetY, double Z, + float Yaw, float Pitch, bool OnGround) : X(X), FeetY(FeetY), Z(Z), Yaw(Yaw), + Pitch(Pitch), OnGround(OnGround) {} }; struct PacketChunkData : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteInt(ChunkX); - stream->WriteInt(ChunkZ); - stream->WriteBool(GroundUpContinuous); - stream->WriteInt(PrimaryBitMask); - stream->WriteVarInt(Data.size()); - stream->WriteByteArray(Data); - stream->WriteVarInt(BlockEntities.size()); - //LOG(FATAL) << "Serializing unimplemented packet"; - } - - void FromStream(StreamInput *stream) override { - ChunkX = stream->ReadInt(); - ChunkZ = stream->ReadInt(); - GroundUpContinuous = stream->ReadBool(); - PrimaryBitMask = stream->ReadVarInt(); - int Size = stream->ReadVarInt(); - Data = stream->ReadByteArray(Size); - int NumberOfBlockEntities = stream->ReadVarInt(); //TODO: Need NBT - for (int i = 0; i < NumberOfBlockEntities; i++) { - //BlockEntities[i] = stream->ReadNbt(); - } - } - - int GetPacketId() override { - return PacketNamePlayCB::ChunkData; - } - - int ChunkX; - int ChunkZ; - bool GroundUpContinuous; - int PrimaryBitMask; - //int Size; - std::vector<unsigned char> Data; - //int NumberOfBlockEntities; - std::vector<int> BlockEntities; //TODO: Replace int with NbtTag and implement NbtTree + void ToStream(StreamOutput *stream) override { + stream->WriteInt(ChunkX); + stream->WriteInt(ChunkZ); + stream->WriteBool(GroundUpContinuous); + stream->WriteInt(PrimaryBitMask); + stream->WriteVarInt(Data.size()); + stream->WriteByteArray(Data); + stream->WriteVarInt(BlockEntities.size()); + //LOG(FATAL) << "Serializing unimplemented packet"; + } + + void FromStream(StreamInput *stream) override { + ChunkX = stream->ReadInt(); + ChunkZ = stream->ReadInt(); + GroundUpContinuous = stream->ReadBool(); + PrimaryBitMask = stream->ReadVarInt(); + int Size = stream->ReadVarInt(); + Data = stream->ReadByteArray(Size); + int NumberOfBlockEntities = stream->ReadVarInt(); //TODO: Need NBT + for (int i = 0; i < NumberOfBlockEntities; i++) { + //BlockEntities[i] = stream->ReadNbt(); + } + } + + int GetPacketId() override { + return PacketNamePlayCB::ChunkData; + } + + int ChunkX; + int ChunkZ; + bool GroundUpContinuous; + int PrimaryBitMask; + //int Size; + std::vector<unsigned char> Data; + //int NumberOfBlockEntities; + std::vector<int> BlockEntities; //TODO: Replace int with NbtTag and implement NbtTree }; struct PacketPlayerPosition : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteDouble(X); - stream->WriteDouble(FeetY); - stream->WriteDouble(Z); - stream->WriteBool(OnGround); - } - - void FromStream(StreamInput *stream) override { - X = stream->ReadDouble(); - FeetY = stream->ReadDouble(); - Z = stream->ReadDouble(); - OnGround = stream->ReadBool(); - } - - int GetPacketId() override { - return PacketNamePlaySB::PlayerPosition; - } - - double X; - double FeetY; - double Z; - bool OnGround; - - PacketPlayerPosition(double X, double Y, double Z, bool ground) : X(X), FeetY(Y), Z(Z), OnGround(ground) {} + void ToStream(StreamOutput *stream) override { + stream->WriteDouble(X); + stream->WriteDouble(FeetY); + stream->WriteDouble(Z); + stream->WriteBool(OnGround); + } + + void FromStream(StreamInput *stream) override { + X = stream->ReadDouble(); + FeetY = stream->ReadDouble(); + Z = stream->ReadDouble(); + OnGround = stream->ReadBool(); + } + + int GetPacketId() override { + return PacketNamePlaySB::PlayerPosition; + } + + double X; + double FeetY; + double Z; + bool OnGround; + + PacketPlayerPosition(double X, double Y, double Z, bool ground) : X(X), FeetY(Y), Z(Z), OnGround(ground) {} }; struct PacketPlayerLook : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteFloat(Yaw); - stream->WriteFloat(Pitch); - stream->WriteBool(OnGround); - } - - void FromStream(StreamInput *stream) override { - Yaw = stream->ReadFloat(); - Pitch = stream->ReadFloat(); - OnGround = stream->ReadBool(); - } - - int GetPacketId() override { - return PacketNamePlaySB::PlayerLook; - } - - float Yaw; - float Pitch; - bool OnGround; - - PacketPlayerLook(float Yaw, float Pitch, bool ground) : Yaw(Yaw), Pitch(Pitch), OnGround(ground) {} + void ToStream(StreamOutput *stream) override { + stream->WriteFloat(Yaw); + stream->WriteFloat(Pitch); + stream->WriteBool(OnGround); + } + + void FromStream(StreamInput *stream) override { + Yaw = stream->ReadFloat(); + Pitch = stream->ReadFloat(); + OnGround = stream->ReadBool(); + } + + int GetPacketId() override { + return PacketNamePlaySB::PlayerLook; + } + + float Yaw; + float Pitch; + bool OnGround; + + PacketPlayerLook(float Yaw, float Pitch, bool ground) : Yaw(Yaw), Pitch(Pitch), OnGround(ground) {} }; struct PacketUpdateHealth : Packet { - void ToStream(StreamOutput *stream) override { - stream->WriteFloat(Health); - stream->WriteVarInt(Food); - stream->WriteFloat(FoodSaturation); - } - - void FromStream(StreamInput *stream) override { - Health = stream->ReadFloat(); - Food = stream->ReadVarInt(); - FoodSaturation = stream->ReadFloat(); - } - - int GetPacketId() override { - return PacketNamePlayCB::UpdateHealth; - } - - float Health; - int Food; - float FoodSaturation; + void ToStream(StreamOutput *stream) override { + stream->WriteFloat(Health); + stream->WriteVarInt(Food); + stream->WriteFloat(FoodSaturation); + } + + void FromStream(StreamInput *stream) override { + Health = stream->ReadFloat(); + Food = stream->ReadVarInt(); + FoodSaturation = stream->ReadFloat(); + } + + int GetPacketId() override { + return PacketNamePlayCB::UpdateHealth; + } + + float Health; + int Food; + float FoodSaturation; }; struct PacketSpawnObject : Packet { @@ -1095,23 +1095,55 @@ struct PacketChatMessageSB : Packet { }; struct PacketPlayerDigging : Packet { - void ToStream(StreamOutput *stream) override { + void ToStream(StreamOutput *stream) override { stream->WriteVarInt(Status); stream->WritePosition(Location); stream->WriteByte(Face); - } + } - void FromStream(StreamInput *stream) override { + void FromStream(StreamInput *stream) override { - } + } - int GetPacketId() override { - return PacketNamePlaySB::PlayerDigging; - } + int GetPacketId() override { + return PacketNamePlaySB::PlayerDigging; + } + + int Status; + Vector Location; + signed char Face; + + PacketPlayerDigging(int status, const Vector& location, signed char face) : Status(status),Location(location),Face(face) {}; +}; + +struct PacketPlayerBlockPlacement : Packet { + void ToStream(StreamOutput *stream) override { + stream->WritePosition(location); + stream->WriteByte(face); + stream->WriteByte(hand); + stream->WriteFloat(cursorPositionX); + stream->WriteFloat(cursorPositionY); + stream->WriteFloat(cursorPositionZ); + } + + void FromStream(StreamInput *stream) override { + + } + + int GetPacketId() override { + return PacketNamePlaySB::PlayerBlockPlacement; + } - int Status; - Vector Location; - signed char Face; + PacketPlayerBlockPlacement( + const Vector& location, signed char face, unsigned char hand, + float cursorPositionX, float cursorPositionY, float cursorPositionZ) + : location(location), face(face), hand(hand), cursorPositionX(cursorPositionX), + cursorPositionY(cursorPositionY), cursorPositionZ(cursorPositionZ) {}; - PacketPlayerDigging(int status, const Vector& location, signed char face) : Status(status),Location(location),Face(face) {}; + Vector location; + signed char face; + unsigned char hand; + float cursorPositionX; + float cursorPositionY; + float cursorPositionZ; };
\ No newline at end of file diff --git a/src/Render.cpp b/src/Render.cpp index 534782e..b5d24b6 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -13,7 +13,9 @@ #include "GameState.hpp" #include "RendererWorld.hpp" -Render::Render(unsigned int windowWidth, unsigned int windowHeight, std::string windowTitle) : timer(std::chrono::milliseconds(16)) { +Render::Render(unsigned int windowWidth, unsigned int windowHeight, + std::string windowTitle) + : timer(std::chrono::milliseconds(16)) { InitEvents(); InitSdl(windowWidth, windowHeight, windowTitle); @@ -34,7 +36,7 @@ Render::~Render() { } void Render::InitSdl(unsigned int WinWidth, unsigned int WinHeight, std::string WinTitle) { - LOG(INFO) << "Creating window: " << WinWidth << "x" << WinHeight << " \"" << WinTitle << "\""; + LOG(INFO) << "Creating window: " << WinWidth << "x" << WinHeight << " \"" << WinTitle << "\""; if (SDL_Init(SDL_INIT_VIDEO) < 0) throw std::runtime_error("SDL initalization failed: " + std::string(SDL_GetError())); @@ -44,7 +46,10 @@ void Render::InitSdl(unsigned int WinWidth, unsigned int WinHeight, std::string SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); - window = SDL_CreateWindow(WinTitle.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WinWidth, WinHeight, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); + window = SDL_CreateWindow( + WinTitle.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + WinWidth, WinHeight, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); + if (!window) throw std::runtime_error("Window creation failed: " + std::string(SDL_GetError())); @@ -52,7 +57,7 @@ void Render::InitSdl(unsigned int WinWidth, unsigned int WinHeight, std::string if (!glContext) throw std::runtime_error("OpenGl context creation failed: " + std::string(SDL_GetError())); - SetMouseCapture(false); + SetMouseCapture(false); renderState.WindowWidth = WinWidth; renderState.WindowHeight = WinHeight; @@ -60,34 +65,34 @@ void Render::InitSdl(unsigned int WinWidth, unsigned int WinHeight, std::string } void Render::InitGlew() { - LOG(INFO) << "Initializing GLEW"; - glewExperimental = GL_TRUE; - GLenum glewStatus = glewInit(); - glCheckError(); - if (glewStatus != GLEW_OK) { - LOG(FATAL) << "Failed to initialize GLEW: " << glewGetErrorString(glewStatus); - } + LOG(INFO) << "Initializing GLEW"; + glewExperimental = GL_TRUE; + GLenum glewStatus = glewInit(); + glCheckError(); + if (glewStatus != GLEW_OK) { + LOG(FATAL) << "Failed to initialize GLEW: " << glewGetErrorString(glewStatus); + } int width, height; SDL_GL_GetDrawableSize(window, &width, &height); glViewport(0, 0, width, height); glClearColor(0.8,0.8,0.8, 1.0f); - glEnable(GL_DEPTH_TEST); + glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - glFrontFace(GL_CCW); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glFrontFace(GL_CCW); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glCheckError(); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glCheckError(); if (glActiveTexture == nullptr) { throw std::runtime_error("GLEW initialization failed with unknown reason"); } } void Render::PrepareToRendering() { - //TextureAtlas texture - glActiveTexture(GL_TEXTURE0); + //TextureAtlas texture + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, AssetManager::Instance().GetTextureAtlas()); AssetManager::Instance().GetTextureAtlasIndexes(); @@ -103,13 +108,13 @@ void Render::UpdateKeyboard() { for (auto key : toUpdate) { bool isPressed = kbState[key]; if (!isKeyPressed[key] && isPressed) { - PUSH_EVENT("KeyPressed", key); + PUSH_EVENT("KeyPressed", key); } if (isKeyPressed[key] && isPressed) { //KeyHeld } if (isKeyPressed[key] && !isPressed) { - PUSH_EVENT("KeyReleased", key); + PUSH_EVENT("KeyReleased", key); } isKeyPressed[key] = isPressed; } @@ -141,94 +146,127 @@ void Render::HandleEvents() { ImGui_ImplSdlGL3_ProcessEvent(&event); switch (event.type) { - case SDL_QUIT: - LOG(INFO) << "Received close event by window closing"; - PUSH_EVENT("Exit",0); - break; - case SDL_WINDOWEVENT: { - switch (event.window.event) { - case SDL_WINDOWEVENT_RESIZED: { - int width, height; - SDL_GL_GetDrawableSize(window, &width, &height); - glViewport(0, 0, width, height); - renderState.WindowWidth = width; - renderState.WindowHeight = height; - break; - } - case SDL_WINDOWEVENT_FOCUS_GAINED: - HasFocus = true; - break; - case SDL_WINDOWEVENT_FOCUS_LOST: - HasFocus = false; - if (GlobalState::GetState() == State::Inventory || GlobalState::GetState() == State::Playing || GlobalState::GetState() == State::Chat) - GlobalState::SetState(State::Paused); + case SDL_QUIT: { + LOG(INFO) << "Received close event by window closing"; + PUSH_EVENT("Exit",0); break; } - break; - } - case SDL_KEYDOWN: - switch (event.key.keysym.scancode) { - case SDL_SCANCODE_ESCAPE: - switch (GlobalState::GetState()) { - case State::Playing: - GlobalState::SetState(State::Paused); - break; - case State::Inventory: - GlobalState::SetState(State::Paused); - break; - case State::Paused: - GlobalState::SetState(State::Playing); - break; - case State::MainMenu: - LOG(INFO) << "Received close event by esc"; - PUSH_EVENT("Exit",0); - break; - } - break; - case SDL_SCANCODE_E: - switch (GlobalState::GetState()) { - case State::Playing: - GlobalState::SetState(State::Inventory); - break; - case State::Inventory: - GlobalState::SetState(State::Playing); - break; + + case SDL_WINDOWEVENT: { + switch (event.window.event) { + case SDL_WINDOWEVENT_RESIZED: { + int width, height; + SDL_GL_GetDrawableSize(window, &width, &height); + glViewport(0, 0, width, height); + renderState.WindowWidth = width; + renderState.WindowHeight = height; + break; + } + + case SDL_WINDOWEVENT_FOCUS_GAINED: + HasFocus = true; + break; + + case SDL_WINDOWEVENT_FOCUS_LOST: { + HasFocus = false; + auto state = GlobalState::GetState(); + if (state == State::Inventory || + state == State::Playing || + state == State::Chat) { + GlobalState::SetState(State::Paused); + } + break; + } + } break; - case SDL_SCANCODE_T: - if (!ImGui::GetIO().WantCaptureKeyboard) - switch (GlobalState::GetState()) { - case State::Playing: - GlobalState::SetState(State::Chat); - SetMouseCapture(false); + } + + case SDL_KEYDOWN: { + switch (event.key.keysym.scancode) { + case SDL_SCANCODE_ESCAPE: { + auto state = GlobalState::GetState(); + if (state == State::Playing) { + GlobalState::SetState(State::Paused); + } else if (state == State::Paused || + state == State::Inventory || + state == State::Chat) { + GlobalState::SetState(State::Playing); + } else if (state == State::MainMenu) { + LOG(INFO) << "Received close event by esc"; + PUSH_EVENT("Exit", 0); + } + break; - case State::Chat: - GlobalState::SetState(State::Playing); - SetMouseCapture(true); + } + + case SDL_SCANCODE_E: { + auto state = GlobalState::GetState(); + if (state == State::Playing) { + GlobalState::SetState(State::Inventory); + } else if (state == State::Inventory) { + GlobalState::SetState(State::Playing); + } + break; } + + case SDL_SCANCODE_SLASH: + case SDL_SCANCODE_T: { + if (!ImGui::GetIO().WantCaptureKeyboard) { + auto state = GlobalState::GetState(); + if (state == State::Playing) { + GlobalState::SetState(State::Chat); + } else if (state == State::Chat) { + GlobalState::SetState(State::Playing); + } + } + + break; + } + + default: + break; + } + break; } - break; - case SDL_MOUSEMOTION: - if (isMouseCaptured) { - double deltaX = event.motion.xrel; - double deltaY = event.motion.yrel; - deltaX *= sensetivity; - deltaY *= sensetivity * -1; - PUSH_EVENT("MouseMove", std::make_tuple(deltaX, deltaY)); + + case SDL_MOUSEMOTION: { + if (isMouseCaptured) { + double deltaX = event.motion.xrel; + double deltaY = event.motion.yrel; + deltaX *= sensetivity; + deltaY *= sensetivity * -1; + PUSH_EVENT("MouseMove", std::make_tuple(deltaX, deltaY)); + } + + break; } + + case SDL_MOUSEBUTTONDOWN: { + if (isMouseCaptured && !ImGui::GetIO().WantCaptureMouse) { + if (event.button.button == SDL_BUTTON_LEFT) + PUSH_EVENT("LmbPressed", 0); + else if (event.button.button == SDL_BUTTON_RIGHT) + PUSH_EVENT("RmbPressed", 0); + } + break; - case SDL_MOUSEBUTTONDOWN: - if (event.button.button == SDL_BUTTON_LEFT && !ImGui::GetIO().WantCaptureMouse) - PUSH_EVENT("LmbPressed",0); + } + + case SDL_MOUSEBUTTONUP: { + if (isMouseCaptured && !ImGui::GetIO().WantCaptureMouse) { + if (event.button.button == SDL_BUTTON_LEFT) + PUSH_EVENT("LmbReleased", 0); + else if (event.button.button == SDL_BUTTON_RIGHT) + PUSH_EVENT("RmbReleased", 0); + } break; - case SDL_MOUSEBUTTONUP: - if (event.button.button == SDL_BUTTON_LEFT && !ImGui::GetIO().WantCaptureMouse) - PUSH_EVENT("LmbReleased",0); + } + + default: break; - default: - break; } } } @@ -254,7 +292,6 @@ void Render::SetMouseCapture(bool IsCaptured) { } void Render::Update() { - HandleEvents(); if (HasFocus && GlobalState::GetState() == State::Playing) UpdateKeyboard(); if (isMouseCaptured) HandleMouseCapture(); @@ -272,7 +309,12 @@ void Render::RenderGui() { auto& io = ImGui::GetIO(); io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); } - const ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings; + + const ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoTitleBar | + ImGuiWindowFlags_NoResize | + ImGuiWindowFlags_NoMove | + ImGuiWindowFlags_AlwaysAutoResize| + ImGuiWindowFlags_NoSavedSettings; //ImGui::ShowTestWindow(); @@ -285,203 +327,235 @@ void Render::RenderGui() { float gameTime = DebugInfo::gameThreadTime / 100.0f; if (world) { ImGui::Text("TPS: %.1f (%.2fms)", 1000.0f / gameTime, gameTime); - ImGui::Text("Sections loaded: %d", (int)DebugInfo::totalSections); - ImGui::Text("SectionsRenderer: %d (%d)", (int)DebugInfo::renderSections, (int)DebugInfo::readyRenderer); - ImGui::Text("Culled sections: %d", (int)DebugInfo::renderSections - world->culledSections); - ImGui::Text("Player pos: %.1f %.1f %.1f OnGround=%d", world->GameStatePtr()->player->pos.x, world->GameStatePtr()->player->pos.y, world->GameStatePtr()->player->pos.z, world->GameStatePtr()->player->onGround); - ImGui::Text("Player vel: %.1f %.1f %.1f", world->GameStatePtr()->player->vel.x, world->GameStatePtr()->player->vel.y, world->GameStatePtr()->player->vel.z); - ImGui::Text("Player health: %.1f/%.1f", world->GameStatePtr()->g_PlayerHealth, 20.0f); - ImGui::Text("Selected block: %d %d %d : %.1f",world->GameStatePtr()->selectedBlock.x,world->GameStatePtr()->selectedBlock.y,world->GameStatePtr()->selectedBlock.z,world->GameStatePtr()->distanceToSelectedBlock); + ImGui::Text("Sections loaded: %d", (int) DebugInfo::totalSections); + ImGui::Text( + "SectionsRenderer: %d (%d)", + (int) DebugInfo::renderSections,(int) DebugInfo::readyRenderer); + + ImGui::Text( + "Culled sections: %d", + (int) DebugInfo::renderSections - world->culledSections); + + ImGui::Text( + "Player pos: %.1f %.1f %.1f OnGround=%d", + world->GameStatePtr()->player->pos.x, + world->GameStatePtr()->player->pos.y, + world->GameStatePtr()->player->pos.z, + world->GameStatePtr()->player->onGround); + + ImGui::Text( + "Player vel: %.1f %.1f %.1f", + world->GameStatePtr()->player->vel.x, + world->GameStatePtr()->player->vel.y, + world->GameStatePtr()->player->vel.z); + + ImGui::Text( + "Player health: %.1f/%.1f", + world->GameStatePtr()->g_PlayerHealth, 20.0f); + + ImGui::Text( + "Selected block: %d %d %d : %.1f", + world->GameStatePtr()->selectedBlock.x, + world->GameStatePtr()->selectedBlock.y, + world->GameStatePtr()->selectedBlock.z, + world->GameStatePtr()->distanceToSelectedBlock); } ImGui::End(); switch (GlobalState::GetState()) { - case State::MainMenu: { - ImGui::SetNextWindowPosCenter(); - ImGui::Begin("Menu", 0, windowFlags); - static char buff[512] = "127.0.0.1"; - static int port = 25565; - static char buffName[512] = "HelloOne"; - if (ImGui::Button("Connect")) { - PUSH_EVENT("ConnectToServer", std::make_tuple(std::string(buff), (unsigned short)port, std::string(buffName))); - } - ImGui::InputText("Username", buffName, 512); - ImGui::InputText("Address", buff, 512); - ImGui::InputInt("Port", &port); - ImGui::Separator(); - if (ImGui::Button("Exit")) - PUSH_EVENT("Exit",0); - ImGui::End(); - break; - } - case State::Loading: - break; - case State::Chat: { - ImGui::SetNextWindowPosCenter(); - ImGui::Begin("Chat", 0, windowFlags); - for (const auto& msg : chatMessages) { - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1,1,1,1)); - ImGui::TextWrapped("%s", msg.c_str()); - ImGui::PopStyleColor(); - } - static char buff[256]; - ImGui::InputText("", buff, 256); - ImGui::SameLine(); - if (ImGui::Button("Send")) { - PUSH_EVENT("SendChatMessage", std::string(buff)); + case State::MainMenu: { + ImGui::SetNextWindowPosCenter(); + ImGui::Begin("Menu", 0, windowFlags); + static char buff[512] = "127.0.0.1"; + static int port = 25565; + static char buffName[512] = "HelloOne"; + if (ImGui::Button("Connect")) { + PUSH_EVENT("ConnectToServer", std::make_tuple(std::string(buff), + (unsigned short) port, std::string(buffName))); + } + ImGui::InputText("Username", buffName, 512); + ImGui::InputText("Address", buff, 512); + ImGui::InputInt("Port", &port); + ImGui::Separator(); + if (ImGui::Button("Exit")) + PUSH_EVENT("Exit",0); + ImGui::End(); + break; } - ImGui::End(); - break; - } - case State::Inventory: { - auto renderSlot = [](const SlotDataType &slot, int i) -> bool { - return ImGui::Button(((slot.BlockId == -1 ? " ##" : - AssetManager::Instance().GetAssetNameByBlockId(BlockId{ (unsigned short)slot.BlockId,0 }) + " x" + std::to_string(slot.ItemCount) + "##") - + std::to_string(i)).c_str()); - }; - ImGui::SetNextWindowPosCenter(); - ImGui::Begin("Inventory", 0, windowFlags); - Window& inventory = world->GameStatePtr()->playerInventory; - //Hand and drop slots - if (renderSlot(inventory.handSlot, -1)) { - } - ImGui::SameLine(); - if (ImGui::Button("Drop")) { - inventory.MakeClick(-1, true, true); - } - ImGui::SameLine(); - ImGui::Text("Hand slot and drop mode"); - ImGui::Separator(); - //Crafting - if (renderSlot(inventory.slots[1], 1)) { - inventory.MakeClick(1, true); - } - ImGui::SameLine(); - if (renderSlot(inventory.slots[2], 2)) { - inventory.MakeClick(2, true); - } - //Crafting result - ImGui::SameLine(); - ImGui::Text("Result"); - ImGui::SameLine(); - if (renderSlot(inventory.slots[0], 0)) { - inventory.MakeClick(0, true); - } - //Crafting second line - if (renderSlot(inventory.slots[3], 3)) { - inventory.MakeClick(3, true); - } - ImGui::SameLine(); - if (renderSlot(inventory.slots[4], 4)) { - inventory.MakeClick(4, true); - } - ImGui::Separator(); - //Armor and offhand - for (int i = 5; i < 8 + 1; i++) { - if (renderSlot(inventory.slots[i], i)) { - inventory.MakeClick(i, true); + case State::Loading: + break; + + case State::Chat: { + ImGui::SetNextWindowPosCenter(); + ImGui::Begin("Chat", 0, windowFlags); + for (const auto& msg : chatMessages) { + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1,1,1,1)); + ImGui::TextWrapped("%s", msg.c_str()); + ImGui::PopStyleColor(); } + static char buff[256]; + ImGui::InputText("", buff, 256); ImGui::SameLine(); + if (ImGui::Button("Send")) { + PUSH_EVENT("SendChatMessage", std::string(buff)); + } + ImGui::End(); + break; } - if (renderSlot(inventory.slots[45], 45)) { - inventory.MakeClick(45, true); - } - ImGui::SameLine(); - ImGui::Text("Armor and offhand"); - ImGui::Separator(); - for (int i = 36; i < 44 + 1; i++) { - if (renderSlot(inventory.slots[i], i)) { - inventory.MakeClick(i, true); + + case State::Inventory: { + auto renderSlot = [](const SlotDataType &slot, int i) -> bool { + return ImGui::Button(((slot.BlockId == -1 ? " ##" : + AssetManager::Instance().GetAssetNameByBlockId(BlockId{ (unsigned short)slot.BlockId,0 }) + " x" + std::to_string(slot.ItemCount) + "##") + + std::to_string(i)).c_str()); + }; + ImGui::SetNextWindowPosCenter(); + ImGui::Begin("Inventory", 0, windowFlags); + Window& inventory = world->GameStatePtr()->playerInventory; + //Hand and drop slots + if (renderSlot(inventory.handSlot, -1)) { + } ImGui::SameLine(); - } - ImGui::Text("Hotbar"); - ImGui::Separator(); - ImGui::Text("Main inventory"); - for (int i = 9; i < 17 + 1; i++) { - if (renderSlot(inventory.slots[i], i)) { - inventory.MakeClick(i, true); + if (ImGui::Button("Drop")) { + inventory.MakeClick(-1, true, true); } ImGui::SameLine(); - } - ImGui::Text(""); - for (int i = 18; i < 26 + 1; i++) { - if (renderSlot(inventory.slots[i], i)) { - inventory.MakeClick(i, true); + ImGui::Text("Hand slot and drop mode"); + ImGui::Separator(); + //Crafting + if (renderSlot(inventory.slots[1], 1)) { + inventory.MakeClick(1, true); } ImGui::SameLine(); - } - ImGui::Text(""); - for (int i = 27; i < 35 + 1; i++) { - if (renderSlot(inventory.slots[i], i)) { - inventory.MakeClick(i, true); + if (renderSlot(inventory.slots[2], 2)) { + inventory.MakeClick(2, true); } + //Crafting result ImGui::SameLine(); - } - ImGui::End(); + ImGui::Text("Result"); + ImGui::SameLine(); + if (renderSlot(inventory.slots[0], 0)) { + inventory.MakeClick(0, true); + } + //Crafting second line + if (renderSlot(inventory.slots[3], 3)) { + inventory.MakeClick(3, true); + } + ImGui::SameLine(); + if (renderSlot(inventory.slots[4], 4)) { + inventory.MakeClick(4, true); + } + ImGui::Separator(); + //Armor and offhand + for (int i = 5; i < 8 + 1; i++) { + if (renderSlot(inventory.slots[i], i)) { + inventory.MakeClick(i, true); + } + ImGui::SameLine(); + } + if (renderSlot(inventory.slots[45], 45)) { + inventory.MakeClick(45, true); + } + ImGui::SameLine(); + ImGui::Text("Armor and offhand"); + ImGui::Separator(); + for (int i = 36; i < 44 + 1; i++) { + if (renderSlot(inventory.slots[i], i)) { + inventory.MakeClick(i, true); + } + ImGui::SameLine(); + } + ImGui::Text("Hotbar"); + ImGui::Separator(); + ImGui::Text("Main inventory"); + for (int i = 9; i < 17 + 1; i++) { + if (renderSlot(inventory.slots[i], i)) { + inventory.MakeClick(i, true); + } + ImGui::SameLine(); + } + ImGui::Text(""); + for (int i = 18; i < 26 + 1; i++) { + if (renderSlot(inventory.slots[i], i)) { + inventory.MakeClick(i, true); + } + ImGui::SameLine(); + } + ImGui::Text(""); + for (int i = 27; i < 35 + 1; i++) { + if (renderSlot(inventory.slots[i], i)) { + inventory.MakeClick(i, true); + } + ImGui::SameLine(); + } + ImGui::End(); - break; - } - case State::Paused: { - ImGui::SetNextWindowPosCenter(); - ImGui::Begin("Pause Menu", 0, windowFlags); - if (ImGui::Button("Continue")) { - GlobalState::SetState(State::Playing); + break; } - ImGui::Separator(); - static float distance = world->MaxRenderingDistance; - ImGui::SliderFloat("Render distance", &distance, 1.0f, 16.0f); - static float sense = sensetivity; - ImGui::SliderFloat("Sensetivity", &sense, 0.01f, 1.0f); + case State::Paused: { + ImGui::SetNextWindowPosCenter(); + ImGui::Begin("Pause Menu", 0, windowFlags); + if (ImGui::Button("Continue")) { + GlobalState::SetState(State::Playing); + } + ImGui::Separator(); + static float distance = world->MaxRenderingDistance; + ImGui::SliderFloat("Render distance", &distance, 1.0f, 16.0f); - static float targetFps = 60.0f; - ImGui::SliderFloat("Target FPS", &targetFps, 1.0f, 300.0f); + static float sense = sensetivity; + ImGui::SliderFloat("Sensetivity", &sense, 0.01f, 1.0f); - static bool wireframe = isWireframe; + static float targetFps = 60.0f; + ImGui::SliderFloat("Target FPS", &targetFps, 1.0f, 300.0f); - ImGui::Checkbox("Wireframe", &wireframe); + static bool wireframe = isWireframe; - static bool vsync = false; + ImGui::Checkbox("Wireframe", &wireframe); - ImGui::Checkbox("VSync", &vsync); + static bool vsync = false; - if (ImGui::Button("Apply settings")) { - if (distance != world->MaxRenderingDistance) { - world->MaxRenderingDistance = distance; - PUSH_EVENT("UpdateSectionsRender", 0); - } + ImGui::Checkbox("VSync", &vsync); + + if (ImGui::Button("Apply settings")) { + if (distance != world->MaxRenderingDistance) { + world->MaxRenderingDistance = distance; + PUSH_EVENT("UpdateSectionsRender", 0); + } - if (sense != sensetivity) - sensetivity = sense; + if (sense != sensetivity) + sensetivity = sense; - isWireframe = wireframe; - timer.SetDelayLength(std::chrono::duration<double, std::milli>(1.0 / targetFps * 1000.0)); - if (vsync) { - timer.SetDelayLength(std::chrono::milliseconds(0)); - SDL_GL_SetSwapInterval(1); - } else - SDL_GL_SetSwapInterval(0); + isWireframe = wireframe; + timer.SetDelayLength(std::chrono::duration<double, std::milli>(1.0 / targetFps * 1000.0)); + if (vsync) { + timer.SetDelayLength(std::chrono::milliseconds(0)); + SDL_GL_SetSwapInterval(1); + } else + SDL_GL_SetSwapInterval(0); + } + ImGui::Separator(); + + if (ImGui::Button("Disconnect")) { + PUSH_EVENT("Disconnect", std::string("Disconnected by user")); + } + ImGui::End(); + break; } - ImGui::Separator(); - if (ImGui::Button("Disconnect")) { - PUSH_EVENT("Disconnect", std::string("Disconnected by user")); + case State::InitialLoading: + break; + + case State::Playing: { + ImGui::SetNextWindowPosCenter(); + ImGui::Begin("",0,windowFlags); + ImGui::End(); + break; } - ImGui::End(); - break; - } - case State::InitialLoading: - break; - case State::Playing: { - ImGui::SetNextWindowPosCenter(); - ImGui::Begin("",0,windowFlags); - ImGui::End(); - break; - } } ImGui::Render(); diff --git a/src/RendererSection.cpp b/src/RendererSection.cpp index 23b0a42..0311171 100644 --- a/src/RendererSection.cpp +++ b/src/RendererSection.cpp @@ -162,12 +162,10 @@ void RendererSection::Render(RenderState &renderState) { glCheckError(); } -Vector RendererSection::GetPosition() -{ +Vector RendererSection::GetPosition() { return sectionPos; } -size_t RendererSection::GetHash() -{ +size_t RendererSection::GetHash() { return hash; }
\ No newline at end of file diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp index 8390de7..16f7950 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -60,8 +60,7 @@ void RendererWorld::WorkerFunction(size_t workerId) { } } -void RendererWorld::UpdateAllSections(VectorF playerPos) -{ +void RendererWorld::UpdateAllSections(VectorF playerPos) { Vector playerChunk(std::floor(gs->player->pos.x / 16), 0, std::floor(gs->player->pos.z / 16)); std::vector<Vector> suitableChunks; @@ -213,7 +212,7 @@ RendererWorld::~RendererWorld() { faces += it.second.numOfFaces; } sectionsMutex.unlock(); - LOG(INFO) << "Total faces to render: "<<faces; + LOG(INFO) << "Total faces to render: " << faces; isRunning = false; for (int i = 0; i < numOfWorkers; i++) workers[i].join(); @@ -227,7 +226,10 @@ RendererWorld::~RendererWorld() { void RendererWorld::Render(RenderState & renderState) { //Common GLint projectionLoc, viewLoc, modelLoc, pvLoc, windowSizeLoc, colorLoc; - glm::mat4 projection = glm::perspective(45.0f, (float)renderState.WindowWidth / (float)renderState.WindowHeight, 0.1f, 10000000.0f); + glm::mat4 projection = glm::perspective( + 45.0f, (float) renderState.WindowWidth / (float) renderState.WindowHeight, + 0.1f, 10000000.0f + ); glm::mat4 view = gs->GetViewMatrix(); glm::mat4 projView = projection * view; @@ -328,7 +330,11 @@ void RendererWorld::Render(RenderState & renderState) { } } - double lengthToSection = (gs->player->pos - VectorF(section.first.x*16,section.first.y*16,section.first.z*16)).GetLength(); + double lengthToSection = (gs->player->pos - + VectorF(section.first.x*16, + section.first.y*16, + section.first.z*16) + ).GetLength(); if (!isVisible && lengthToSection > 30.0f) { sectionsMutex.lock(); diff --git a/src/Utility.cpp b/src/Utility.cpp index 0fb10cf..848ee02 100644 --- a/src/Utility.cpp +++ b/src/Utility.cpp @@ -5,40 +5,41 @@ #include <easylogging++.h> GLenum glCheckError_(const char *file, int line) { - GLenum errorCode; - while ((errorCode = glGetError()) != GL_NO_ERROR) { - std::string error; - switch (errorCode) { - case GL_INVALID_ENUM: - error = "INVALID_ENUM"; - break; - case GL_INVALID_VALUE: - error = "INVALID_VALUE"; - break; - case GL_INVALID_OPERATION: - error = "INVALID_OPERATION"; - break; - case GL_STACK_OVERFLOW: - error = "STACK_OVERFLOW"; - break; - case GL_STACK_UNDERFLOW: - error = "STACK_UNDERFLOW"; - break; - case GL_OUT_OF_MEMORY: - error = "OUT_OF_MEMORY"; - break; - case GL_INVALID_FRAMEBUFFER_OPERATION: - error = "INVALID_FRAMEBUFFER_OPERATION"; - break; - } - static int t = 0; - LOG(ERROR) << "OpenGL error: " << error << " at " << file << ":" << line; - } - return errorCode; + GLenum errorCode; + while ((errorCode = glGetError()) != GL_NO_ERROR) { + std::string error; + switch (errorCode) { + case GL_INVALID_ENUM: + error = "INVALID_ENUM"; + break; + case GL_INVALID_VALUE: + error = "INVALID_VALUE"; + break; + case GL_INVALID_OPERATION: + error = "INVALID_OPERATION"; + break; + case GL_STACK_OVERFLOW: + error = "STACK_OVERFLOW"; + break; + case GL_STACK_UNDERFLOW: + error = "STACK_UNDERFLOW"; + break; + case GL_OUT_OF_MEMORY: + error = "OUT_OF_MEMORY"; + break; + case GL_INVALID_FRAMEBUFFER_OPERATION: + error = "INVALID_FRAMEBUFFER_OPERATION"; + break; + } + static int t = 0; + LOG(ERROR) << "OpenGL error: " << error << " at " << file << ":" << line; + } + return errorCode; } -LoopExecutionTimeController::LoopExecutionTimeController(duration delayLength) : delayLength(delayLength) { - previousUpdate = clock::now(); +LoopExecutionTimeController::LoopExecutionTimeController(duration delayLength) + : delayLength(delayLength) { + previousUpdate = clock::now(); } LoopExecutionTimeController::~LoopExecutionTimeController() { @@ -46,16 +47,16 @@ LoopExecutionTimeController::~LoopExecutionTimeController() { } void LoopExecutionTimeController::SetDelayLength(duration length) { - delayLength = length; + delayLength = length; } unsigned long long LoopExecutionTimeController::GetIterations() { - return iterations; + return iterations; } void LoopExecutionTimeController::Update() { - iterations++; - auto timeToSleep = delayLength - GetDelta(); + iterations++; + auto timeToSleep = delayLength - GetDelta(); if (timeToSleep.count() > 0) std::this_thread::sleep_for(timeToSleep); previousPreviousUpdate = previousUpdate; @@ -68,8 +69,8 @@ double LoopExecutionTimeController::GetDeltaMs() { } LoopExecutionTimeController::duration LoopExecutionTimeController::GetDelta() { - auto now = clock::now(); - return duration(now-previousUpdate); + auto now = clock::now(); + return duration(now-previousUpdate); } double LoopExecutionTimeController::GetDeltaS() { @@ -77,13 +78,11 @@ double LoopExecutionTimeController::GetDeltaS() { return delta.count(); } -double LoopExecutionTimeController::GetRealDeltaS() -{ +double LoopExecutionTimeController::GetRealDeltaS() { return std::chrono::duration<double,std::ratio<1,1>>(previousUpdate - previousPreviousUpdate).count(); } -double LoopExecutionTimeController::RemainTimeMs() -{ +double LoopExecutionTimeController::RemainTimeMs() { auto remain = delayLength - GetDelta(); return remain.count(); } diff --git a/src/Utility.hpp b/src/Utility.hpp index e8c508d..9b90cb9 100644 --- a/src/Utility.hpp +++ b/src/Utility.hpp @@ -11,18 +11,38 @@ using Uuid = std::vector<unsigned char>; template<class T> void endswap(T *objp) { - unsigned char *memp = reinterpret_cast<unsigned char *>(objp); - std::reverse(memp, memp + sizeof(T)); + unsigned char *memp = reinterpret_cast<unsigned char *>(objp); + std::reverse(memp, memp + sizeof(T)); } template<class T> void endswap(T &obj) { - unsigned char *raw = reinterpret_cast<unsigned char *>(&obj); - std::reverse(raw, raw + sizeof(T)); + unsigned char *raw = reinterpret_cast<unsigned char *>(&obj); + std::reverse(raw, raw + sizeof(T)); +} + +template<typename T> +T _min(T a, T b) { + return (a > b) ? b : a; +} + +template<typename T, typename... Args> +T _min(T a, T b, Args... args) { + return _min(a > b ? b : a, args...); +} + +template<typename T> +T _max(T a, T b) { + return (a > b) ? a : b; +} + +template<typename T, typename... Args> +T _max(T a, T b, Args... args) { + return _max(a > b ? a : b, args...); } inline void endswap(unsigned char *arr, size_t arrLen) { - std::reverse(arr, arr + arrLen); + std::reverse(arr, arr + arrLen); } GLenum glCheckError_(const char *file, int line); @@ -30,27 +50,27 @@ GLenum glCheckError_(const char *file, int line); class LoopExecutionTimeController { - using clock = std::chrono::steady_clock ; - using timePoint = std::chrono::time_point<clock>; - using duration = std::chrono::duration<double,std::milli>; - timePoint previousUpdate; + using clock = std::chrono::steady_clock ; + using timePoint = std::chrono::time_point<clock>; + using duration = std::chrono::duration<double,std::milli>; + timePoint previousUpdate; timePoint previousPreviousUpdate; - duration delayLength; - unsigned long long iterations=0; + duration delayLength; + unsigned long long iterations=0; public: - LoopExecutionTimeController(duration delayLength); + LoopExecutionTimeController(duration delayLength); - ~LoopExecutionTimeController(); + ~LoopExecutionTimeController(); - void SetDelayLength(duration length); + void SetDelayLength(duration length); - unsigned long long GetIterations(); + unsigned long long GetIterations(); - void Update(); + void Update(); - double GetDeltaMs(); + double GetDeltaMs(); - duration GetDelta(); + duration GetDelta(); double GetDeltaS(); diff --git a/src/Vector.hpp b/src/Vector.hpp index 5795db2..03b1ec4 100644 --- a/src/Vector.hpp +++ b/src/Vector.hpp @@ -7,108 +7,134 @@ template<class T> struct Vector3 { - T x, y, z; + T x, y, z; - Vector3(T X = 0, T Y = 0, T Z = 0) : x(X), y(Y), z(Z) {} + Vector3(T X = 0, T Y = 0, T Z = 0) : x(X), y(Y), z(Z) {} - Vector3(const Vector3 &rhs) : x(rhs.x), y(rhs.y), z(rhs.z) {} + Vector3(const Vector3 &rhs) : x(rhs.x), y(rhs.y), z(rhs.z) {} - ~Vector3() = default; + ~Vector3() = default; - double GetLength() const { return std::sqrt(std::pow(x, 2) + std::pow(y, 2) + std::pow(z, 2)); } + double GetLength() const { return std::sqrt(std::pow(x, 2) + std::pow(y, 2) + std::pow(z, 2)); } - operator glm::vec3() const { - return glm::vec3(x, y, z); - } + operator glm::vec3() const { + return glm::vec3(x, y, z); + } glm::vec3 glm() const { return (glm::vec3)(*this); } - void swap(Vector3 &rhs) noexcept { - std::swap(x, rhs.x); - std::swap(y, rhs.y); - std::swap(z, rhs.z); - } - - Vector3 &operator=(Vector3 rhs) noexcept { - rhs.swap(*this); - return *this; - } - - Vector3 operator*(T rhs) const { - return Vector3<T>( - x * rhs, - y * rhs, - z * rhs - ); - } - - Vector3 operator/(T rhs) const { - return Vector3<T>( - x / rhs, - y / rhs, - z / rhs - ); - } - - Vector3 operator+(const Vector3 &rhs) const { - return Vector3<T>( - x + rhs.x, - y + rhs.y, - z + rhs.z - ); - } - - Vector3 operator-(const Vector3 &rhs) const { - return Vector3<T>( - x - rhs.x, - y - rhs.y, - z - rhs.z - ); - } - - Vector3 operator*(const Vector3 &rhs) const { - return Vector3<T>( - x * rhs.x, - y * rhs.y, - z * rhs.z - ); - } - - Vector3 operator/(const Vector3 &rhs) const { - return Vector3<T>( - x / rhs.x, - y / rhs.y, - z / rhs.z - ); - } - - bool operator==(const Vector3 &rhs) const { - return (x == rhs.x && y == rhs.y && z == rhs.z); - } - - bool operator!=(const Vector3 &rhs) const { - return !(*this == rhs); - } - - bool operator<(const Vector3 &rhs) const { - if (x < rhs.x) - return true; - if (rhs.x < x) - return false; - if (y < rhs.y) - return true; - if (rhs.y < y) - return false; - return z < rhs.z; - } - - - friend std::ostream &operator<<(std::ostream &os, const Vector3 &vector3) { - os << vector3.x << ", " << vector3.y << ", " << vector3.z; - return os; - } + void swap(Vector3 &rhs) noexcept { + std::swap(x, rhs.x); + std::swap(y, rhs.y); + std::swap(z, rhs.z); + } + + T dot(const Vector3 &rhs) const { + return x*rhs.x + y*rhs.y + z*rhs.z; + } + + double cosBetween(const Vector3<T> &rhs) const { + return dot(rhs) / GetLength() / rhs.GetLength(); + } + + Vector3<double> normalize() { + auto length = GetLength(); + + return Vector3<double> ( + x / length, + y / length, + z / length + ); + } + + Vector3 &operator=(Vector3 rhs) noexcept { + rhs.swap(*this); + return *this; + } + + Vector3 operator*(T rhs) const { + return Vector3<T>( + x * rhs, + y * rhs, + z * rhs + ); + } + + Vector3 operator/(T rhs) const { + return Vector3<T>( + x / rhs, + y / rhs, + z / rhs + ); + } + + Vector3 operator+(const Vector3 &rhs) const { + return Vector3<T>( + x + rhs.x, + y + rhs.y, + z + rhs.z + ); + } + + Vector3 operator-(const Vector3 &rhs) const { + return Vector3<T>( + x - rhs.x, + y - rhs.y, + z - rhs.z + ); + } + + Vector3 operator-() const { + return Vector3<T> ( + -x, + -y, + -z + ); + } + + Vector3 operator*(const Vector3 &rhs) const { + return Vector3<T>( + x * rhs.x, + y * rhs.y, + z * rhs.z + ); + } + + Vector3 operator/(const Vector3 &rhs) const { + return Vector3<T>( + x / rhs.x, + y / rhs.y, + z / rhs.z + ); + } + + bool operator==(const Vector3 &rhs) const { + return (x == rhs.x && y == rhs.y && z == rhs.z); + } + + bool operator!=(const Vector3 &rhs) const { + return !(*this == rhs); + } + + bool operator<(const Vector3 &rhs) const { + if (x < rhs.x) + return true; + if (rhs.x < x) + return false; + if (y < rhs.y) + return true; + if (rhs.y < y) + return false; + return z < rhs.z; + } + + + friend std::ostream &operator<<(std::ostream &os, const Vector3 &vector3) { + os << vector3.x << ", " << vector3.y << ", " << vector3.z; + return os; + } }; using VectorF = Vector3<double>; diff --git a/src/World.cpp b/src/World.cpp index 4678964..59399f5 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -21,13 +21,13 @@ void World::ParseChunkData(std::shared_ptr<PacketChunkData> packet) { if (!sections.insert(std::make_pair(chunkPosition, std::make_unique<Section>(section))).second) { LOG(ERROR) << "New chunk not created " << chunkPosition << " potential memory leak"; } + UpdateSectionsList(); + } else { + std::swap(*sections.at(chunkPosition).get(), section); } - else { - using std::swap; - swap(*sections.at(chunkPosition).get(), section); - } - PUSH_EVENT("ChunkChanged", chunkPosition); + + PUSH_EVENT("ChunkChanged", chunkPosition); } } } @@ -53,7 +53,9 @@ Section World::ParseSection(StreamInput *data, Vector position) { std::vector<long long> blockArray(blockData, blockData + dataArray.size() / sizeof(long long)); - return Section(position, bitsPerBlock, std::move(palette), std::move(blockArray), std::move(blockLight), std::move(skyLight)); + return Section( + position, bitsPerBlock, std::move(palette),std::move(blockArray), + std::move(blockLight), std::move(skyLight)); } World::~World() { @@ -64,7 +66,8 @@ 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)); - if (sections.find(PlayerChunk) == sections.end() || sections.find(PlayerChunk - Vector(0, 1, 0)) == sections.end()) + if (sections.find(PlayerChunk) == sections.end() || + sections.find(PlayerChunk - Vector(0, 1, 0)) == sections.end()) return false; std::vector<Vector> closestSectionsCoordinates = { @@ -135,16 +138,17 @@ const Section &World::GetSection(Vector sectionPos) { } } +// TODO: skip liquid blocks RaycastResult World::Raycast(glm::vec3 position, glm::vec3 direction) { const float maxLen = 5.0; const float step = 0.01; glm::vec3 pos; - float len=0; + float len = 0; Vector blockPos = Vector(position.x,position.y,position.z); while (GetBlockId(blockPos) == BlockId{0, 0} && len <= maxLen) { pos = position + direction * len; len += step; - blockPos = Vector(floor(pos.x),floor(pos.y),floor(pos.z)); + blockPos = Vector(floor(pos.x), floor(pos.y), floor(pos.z)); } RaycastResult result; @@ -154,8 +158,7 @@ RaycastResult World::Raycast(glm::vec3 position, glm::vec3 direction) { return result; } -void World::UpdatePhysics(float delta) -{ +void World::UpdatePhysics(float delta) { struct CollisionResult { bool isCollide; //Vector block; @@ -164,7 +167,6 @@ void World::UpdatePhysics(float delta) }; auto testCollision = [this](double width, double height, VectorF pos)->CollisionResult { - int blockXBegin = pos.x - width - 1.0; int blockXEnd = pos.x + width + 0.5; int blockYBegin = pos.y - 0.5; @@ -211,6 +213,7 @@ void World::UpdatePhysics(float delta) it.pos = newPos; } } + { //Horizontal velocity VectorF newPos = it.pos + VectorF(it.vel.x, 0, it.vel.z) * delta; auto coll = testCollision(it.width, it.height, newPos); @@ -231,8 +234,7 @@ void World::UpdatePhysics(float delta) DebugInfo::totalSections = sections.size(); } -Entity & World::GetEntity(unsigned int EntityId) -{ +Entity& World::GetEntity(unsigned int EntityId){ entitiesMutex.lock(); for (auto& it : entities) { if (it.entityId == EntityId) { @@ -241,12 +243,12 @@ Entity & World::GetEntity(unsigned int EntityId) } } entitiesMutex.unlock(); + static Entity fallback; return fallback; } -std::vector<unsigned int> World::GetEntitiesList() -{ +std::vector<unsigned int> World::GetEntitiesList() { entitiesMutex.lock(); std::vector<unsigned int> ret; for (auto& it : entities) { @@ -256,8 +258,7 @@ std::vector<unsigned int> World::GetEntitiesList() return ret; } -void World::AddEntity(Entity entity) -{ +void World::AddEntity(Entity entity) { entitiesMutex.lock(); for (auto& it : entities) { if (it.entityId == entity.entityId) { @@ -270,8 +271,7 @@ void World::AddEntity(Entity entity) entitiesMutex.unlock(); } -void World::DeleteEntity(unsigned int EntityId) -{ +void World::DeleteEntity(unsigned int EntityId) { entitiesMutex.lock(); auto it = entities.begin(); for (; it != entities.end(); ++it) { @@ -285,10 +285,16 @@ void World::DeleteEntity(unsigned int EntityId) } void World::ParseChunkData(std::shared_ptr<PacketBlockChange> packet) { - SetBlockId(packet->Position, BlockId{(unsigned short) (packet->BlockId >> 4),(unsigned char) (packet->BlockId & 0xF) }); - - Vector sectionPos(std::floor(packet->Position.x / 16.0), std::floor(packet->Position.y / 16.0), std::floor(packet->Position.z / 16.0)); - PUSH_EVENT("ChunkChanged", sectionPos); + SetBlockId(packet->Position, + BlockId { + (unsigned short) (packet->BlockId >> 4), + (unsigned char) (packet->BlockId & 0xF) + }); + + Vector sectionPos(std::floor(packet->Position.x / 16.0), + std::floor(packet->Position.y / 16.0), + std::floor(packet->Position.z / 16.0)); + PUSH_EVENT("ChunkChanged", sectionPos); } void World::ParseChunkData(std::shared_ptr<PacketMultiBlockChange> packet) { @@ -306,7 +312,7 @@ void World::ParseChunkData(std::shared_ptr<PacketMultiBlockChange> packet) { } for (auto& sectionPos : changedSections) - PUSH_EVENT("ChunkChanged", sectionPos); + PUSH_EVENT("ChunkChanged", sectionPos); } void World::ParseChunkData(std::shared_ptr<PacketUnloadChunk> packet) { @@ -316,7 +322,7 @@ void World::ParseChunkData(std::shared_ptr<PacketUnloadChunk> packet) { toRemove.push_back(it); } for (auto& it : toRemove) { - PUSH_EVENT("ChunkDeleted", it->first); + PUSH_EVENT("ChunkDeleted", it->first); sections.erase(it); } UpdateSectionsList(); @@ -332,14 +338,19 @@ void World::UpdateSectionsList() { } BlockId World::GetBlockId(Vector pos) { - Vector sectionPos(std::floor(pos.x / 16.0), std::floor(pos.y / 16.0), std::floor(pos.z / 16.0)); + Vector sectionPos(std::floor(pos.x / 16.0), + std::floor(pos.y / 16.0), + std::floor(pos.z / 16.0)); Section* section = GetSectionPtr(sectionPos); return !section ? BlockId{0, 0} : section->GetBlockId(pos - (sectionPos * 16)); } void World::SetBlockId(Vector pos, BlockId block) { - Vector sectionPos(std::floor(pos.x / 16.0), std::floor(pos.y / 16.0), std::floor(pos.z / 16.0)); + Vector sectionPos(std::floor(pos.x / 16.0), + std::floor(pos.y / 16.0), + std::floor(pos.z / 16.0)); + Section* section = GetSectionPtr(sectionPos); section->SetBlockId(pos - (sectionPos * 16), block); PUSH_EVENT("ChunkChanged",sectionPos); diff --git a/src/main.cpp b/src/main.cpp index eac2417..cb2daa8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -47,7 +47,7 @@ int main(int argc, char** argv) { LOG(ERROR) << e.what(); return -1; } - + GlobalState::Exec(); return 0; |