diff options
Diffstat (limited to 'src/world')
-rw-r--r-- | src/world/Block.cpp | 2 | ||||
-rw-r--r-- | src/world/Block.hpp | 15 | ||||
-rw-r--r-- | src/world/Collision.cpp | 2 | ||||
-rw-r--r-- | src/world/Collision.hpp | 8 | ||||
-rw-r--r-- | src/world/GameState.cpp | 389 | ||||
-rw-r--r-- | src/world/Section.cpp | 16 | ||||
-rw-r--r-- | src/world/Section.hpp | 43 | ||||
-rw-r--r-- | src/world/World.cpp | 8 | ||||
-rw-r--r-- | src/world/World.hpp | 37 |
9 files changed, 407 insertions, 113 deletions
diff --git a/src/world/Block.cpp b/src/world/Block.cpp index e88068a..74ac406 100644 --- a/src/world/Block.cpp +++ b/src/world/Block.cpp @@ -1,4 +1,4 @@ -#include "Block.hpp" +#include <world/Block.hpp> Block::~Block() {} diff --git a/src/world/Block.hpp b/src/world/Block.hpp deleted file mode 100644 index 2f823fe..0000000 --- a/src/world/Block.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -struct Block { - Block(); - - Block(unsigned short id, unsigned char state); - - ~Block(); - - unsigned short id : 13; - unsigned char state : 4; - //unsigned char light:4; -}; - -bool operator<(const Block &lhs, const Block &rhs);
\ No newline at end of file diff --git a/src/world/Collision.cpp b/src/world/Collision.cpp index 4f2c837..8fc562b 100644 --- a/src/world/Collision.cpp +++ b/src/world/Collision.cpp @@ -1,4 +1,4 @@ -#include "Collision.hpp" +#include <world/Collision.hpp> bool TestCollision(AABB first, AABB second) { double firstXl = first.x; diff --git a/src/world/Collision.hpp b/src/world/Collision.hpp deleted file mode 100644 index b88fbf7..0000000 --- a/src/world/Collision.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -struct AABB { - double x,y,z; - double w,l,h; -}; - -bool TestCollision(AABB first, AABB second);
\ No newline at end of file diff --git a/src/world/GameState.cpp b/src/world/GameState.cpp new file mode 100644 index 0000000..b484b06 --- /dev/null +++ b/src/world/GameState.cpp @@ -0,0 +1,389 @@ +#include <GameState.hpp> + +GameState::GameState(NetworkClient *Net, bool &quit) : nc(Net), isRunning(quit) { + Front = glm::vec3(0.0f, 0.0f, -1.0f); + this->SetPosition(glm::vec3(0.0f, 0.0f, 3.0f)); + this->WorldUp = glm::vec3(0.0f, 1.0f, 0.0f); + this->updateCameraVectors(); +} + +void GameState::Update(float deltaTime) { + if (g_IsGameStarted) { + std::chrono::steady_clock clock; + static auto timeOfPreviousSendedPacket(clock.now()); + auto delta = clock.now() - timeOfPreviousSendedPacket; + using namespace std::chrono_literals; + if (delta >= 50ms) { + nc->SendPacket(std::make_shared<PacketPlayerPositionAndLookSB>(g_PlayerX, g_PlayerY, g_PlayerZ, g_PlayerYaw, + g_PlayerPitch, g_OnGround)); + timeOfPreviousSendedPacket = clock.now(); + } + + const float gravity = -9.8f; + g_PlayerVelocityY += gravity * deltaTime; + + bool isCollides = world.isPlayerCollides(g_PlayerX, g_PlayerY + g_PlayerVelocityY * deltaTime, + g_PlayerZ); + if (!isCollides) { + g_PlayerY += g_PlayerVelocityY * deltaTime; + g_OnGround = false; + } else { + g_PlayerVelocityY = 0; + if (g_OnGround == false) { + auto updatePacket = std::make_shared<PacketPlayerPosition>(g_PlayerX, g_PlayerY, g_PlayerZ, true); + nc->SendPacket(updatePacket); + } + g_OnGround = true; + } + + isCollides = world.isPlayerCollides(g_PlayerX + g_PlayerVelocityX * deltaTime, g_PlayerY, + g_PlayerZ + g_PlayerVelocityZ * deltaTime); + if (!isCollides) { + g_PlayerX += g_PlayerVelocityX * deltaTime; + g_PlayerZ += g_PlayerVelocityZ * deltaTime; + } + + const float AirResistance = 10.0f; + glm::vec3 vel(g_PlayerVelocityX, 0, g_PlayerVelocityZ); + glm::vec3 resistForce = -vel * AirResistance * deltaTime; + vel += resistForce; + g_PlayerVelocityX = vel.x; + g_PlayerVelocityZ = vel.z; + } + + + //Packet handling + auto ptr = nc->ReceivePacket(); + while (ptr != nullptr) { + switch ((PacketNamePlayCB) ptr->GetPacketId()) { + case SpawnObject: + break; + case SpawnExperienceOrb: + break; + case SpawnGlobalEntity: + break; + case SpawnMob: + break; + case SpawnPainting: + break; + case SpawnPlayer: + break; + case AnimationCB: + break; + case Statistics: + break; + case BlockBreakAnimation: + break; + case UpdateBlockEntity: + break; + case BlockAction: + break; + case BlockChange: + break; + case BossBar: + break; + case ServerDifficulty: + break; + case TabCompleteCB: + break; + case ChatMessageCB: + break; + case MultiBlockChange: + break; + case ConfirmTransactionCB: + break; + case CloseWindowCB: + break; + case OpenWindow: + break; + case WindowItems: + break; + case WindowProperty: + break; + case SetSlot: + 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; + isRunning = false; + break; + } + case EntityStatus: + break; + case Explosion: + break; + case UnloadChunk: + break; + case ChangeGameState: + break; + 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); + g_PlayerEid = packet->EntityId; + g_Gamemode = (packet->Gamemode & 0b11111011); + g_Dimension = packet->Dimension; + g_Difficulty = packet->Difficulty; + g_MaxPlayers = packet->MaxPlayers; + g_LevelType = packet->LevelType; + g_ReducedDebugInfo = packet->ReducedDebugInfo; + LOG(INFO) << "Gamemode is " << g_Gamemode << ", Difficulty is " << (int) g_Difficulty + << ", Level Type is " << g_LevelType; + break; + } + case Map: + break; + case EntityRelativeMove: + break; + case EntityLookAndRelativeMove: + break; + case EntityLook: + break; + case Entity: + break; + case VehicleMove: + break; + case OpenSignEditor: + break; + case PlayerAbilitiesCB: + break; + case CombatEvent: + break; + case PlayerListItem: + break; + case PlayerPositionAndLookCB: { + auto packet = std::static_pointer_cast<PacketPlayerPositionAndLookCB>(ptr); + if ((packet->Flags & 0x10) != 0) { + g_PlayerPitch += packet->Pitch; + } else { + g_PlayerPitch = packet->Pitch; + }; + + if ((packet->Flags & 0x08) != 0) { + g_PlayerYaw += packet->Yaw; + } else { + g_PlayerYaw = packet->Yaw; + } + + if ((packet->Flags & 0x01) != 0) { + g_PlayerX += packet->X; + } else { + g_PlayerX = packet->X; + } + + if ((packet->Flags & 0x02) != 0) { + g_PlayerY += packet->Y; + } else { + g_PlayerY = packet->Y; + } + + if ((packet->Flags & 0x04) != 0) { + g_PlayerZ += packet->Z; + } else { + g_PlayerZ = packet->Z; + } + + //if (!g_IsGameStarted) + LOG(INFO) << "PlayerPos is " << g_PlayerX << ", " << g_PlayerY << ", " << g_PlayerZ << "\t\tAngle: " + << g_PlayerYaw << "," << g_PlayerPitch; + + g_IsGameStarted = true; + + auto packetResponse = std::make_shared<PacketTeleportConfirm>(packet->TeleportId); + auto packetPerformRespawn = std::make_shared<PacketClientStatus>(0); + + nc->SendPacket(packetResponse); + nc->SendPacket(packetPerformRespawn); + break; + } + case UseBed: + break; + case UnlockRecipes: + break; + case DestroyEntities: + break; + case RemoveEntityEffect: + break; + case ResourcePackSend: + break; + case Respawn: + break; + case EntityHeadLook: + break; + case SelectAdvancementTab: + break; + case WorldBorder: + break; + case Camera: + break; + case HeldItemChangeCB: + break; + case DisplayScoreboard: + break; + case EntityMetadata: + break; + case AttachEntity: + break; + case EntityVelocity: + break; + case EntityEquipment: + break; + case SetExperience: + break; + case UpdateHealth: { + auto packet = std::static_pointer_cast<PacketUpdateHealth>(ptr); + g_PlayerHealth = packet->Health; + if (g_PlayerHealth <= 0) { + LOG(INFO) << "Player is dead. Respawning..."; + auto packetPerformRespawn = std::make_shared<PacketClientStatus>(0); + nc->SendPacket(packetPerformRespawn); + } + break; + } + case ScoreboardObjective: + break; + case SetPassengers: + break; + case Teams: + break; + case UpdateScore: + break; + case SpawnPosition: { + auto packet = std::static_pointer_cast<PacketSpawnPosition>(ptr); + g_SpawnPosition = packet->Location; + LOG(INFO) << "Spawn position is " << g_SpawnPosition.GetX() << "," << g_SpawnPosition.GetY() << "," + << g_SpawnPosition.GetZ(); + break; + } + case TimeUpdate: + break; + case Title: + break; + case SoundEffect: + break; + case PlayerListHeaderAndFooter: + break; + case CollectItem: + break; + case EntityTeleport: + break; + case Advancements: + break; + case EntityProperties: + break; + case EntityEffect: + break; + } + ptr = nc->ReceivePacket(); + } +} + +void GameState::HandleMovement(GameState::Direction direction, float deltaTime) { + const float PlayerSpeed = 40.0; + float velocity = PlayerSpeed * deltaTime; + glm::vec3 vel(g_PlayerVelocityX, g_PlayerVelocityY, g_PlayerVelocityZ); + glm::vec3 front(cos(glm::radians(this->Yaw())) * cos(glm::radians(this->Pitch())), 0, + sin(glm::radians(this->Yaw())) * cos(glm::radians(this->Pitch()))); + front = glm::normalize(front); + glm::vec3 right = glm::normalize(glm::cross(front, this->WorldUp)); + 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 (g_OnGround) { + vel.y += 5; + g_OnGround = false; + } + break; + } + g_PlayerVelocityX = vel.x; + g_PlayerVelocityY = vel.y; + g_PlayerVelocityZ = vel.z; + + /*bool isCollides = world.isPlayerCollides(g_PlayerX, g_PlayerY, g_PlayerZ); + if (isCollides) { + SetPosition(previousPos); + return; + } + auto updatePacket = std::make_shared<PacketPlayerPosition>(g_PlayerX, g_PlayerY, g_PlayerZ, true); + nc->SendPacket(updatePacket);*/ +} + +void GameState::HandleRotation(double yaw, double pitch) { + this->SetYaw(Yaw() + yaw); + this->SetPitch(Pitch() + pitch); + if (this->Pitch() > 89.0f) + this->SetPitch(89.0f); + if (this->Pitch() < -89.0f) + this->SetPitch(-89.0f); + this->updateCameraVectors(); + + auto updatePacket = std::make_shared<PacketPlayerLook>(g_PlayerYaw, g_PlayerPitch, g_OnGround); + nc->SendPacket(updatePacket); +} + +glm::mat4 GameState::GetViewMatrix() { + return glm::lookAt(this->Position(), this->Position() + this->Front, this->Up); +} + +void GameState::updateCameraVectors() { + glm::vec3 front; + front.x = cos(glm::radians(this->Yaw())) * cos(glm::radians(this->Pitch())); + front.y = sin(glm::radians(this->Pitch())); + front.z = sin(glm::radians(this->Yaw())) * cos(glm::radians(this->Pitch())); + this->Front = glm::normalize(front); + this->Right = glm::normalize(glm::cross(this->Front, this->WorldUp)); + this->Up = glm::normalize(glm::cross(this->Right, this->Front)); +} + +float GameState::Yaw() { + return g_PlayerYaw + 90; +} + +float GameState::Pitch() { + return -g_PlayerPitch; +} + +void GameState::SetYaw(float yaw) { + g_PlayerYaw = yaw - 90; +} + +void GameState::SetPitch(float pitch) { + g_PlayerPitch = -pitch; +} + +glm::vec3 GameState::Position() { + return glm::vec3(g_PlayerX - 0.5, g_PlayerY + 1.12, g_PlayerZ - 0.5); +} + +void GameState::SetPosition(glm::vec3 Position) { + g_PlayerX = Position.x + 0.5; + g_PlayerY = Position.y - 1.12; + g_PlayerZ = Position.z + 0.5; +} diff --git a/src/world/Section.cpp b/src/world/Section.cpp index 8f94ad7..a338e49 100644 --- a/src/world/Section.cpp +++ b/src/world/Section.cpp @@ -1,8 +1,11 @@ -#include "Section.hpp" +#include <world/Section.hpp> -Section::Section(byte *dataBlocks, size_t dataBlocksLength, byte *dataLight, byte *dataSky, byte bitsPerBlock, +Section::Section(Vector position, byte *dataBlocks, size_t dataBlocksLength, byte *dataLight, byte *dataSky, + byte bitsPerBlock, std::vector<unsigned short> palette) { + worldPosition = position; + m_dataBlocksLen = dataBlocksLength; m_dataBlocks = new byte[m_dataBlocksLen]; std::copy(dataBlocks, dataBlocks + m_dataBlocksLen, m_dataBlocks); @@ -97,7 +100,7 @@ void Section::Parse() { } Section &Section::operator=(Section other) { - std::swap(*this,other); + std::swap(*this, other); return *this; } @@ -113,6 +116,7 @@ void swap(Section &a, Section &b) { } Section::Section(const Section &other) { + worldPosition = other.worldPosition; m_dataBlocksLen = other.m_dataBlocksLen; m_dataBlocks = new byte[m_dataBlocksLen]; std::copy(other.m_dataBlocks, other.m_dataBlocks + m_dataBlocksLen, m_dataBlocks); @@ -127,4 +131,8 @@ Section::Section(const Section &other) { m_palette = other.m_palette; m_bitsPerBlock = other.m_bitsPerBlock; -}
\ No newline at end of file +} + +Vector Section::GetPosition() { + return worldPosition; +} diff --git a/src/world/Section.hpp b/src/world/Section.hpp deleted file mode 100644 index 657fc13..0000000 --- a/src/world/Section.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include <vector> -#include <map> -#include <condition_variable> -#include <easylogging++.h> -#include "Block.hpp" -#include "../utility/Vector.hpp" -#include "../utility/utility.h" - -const int SECTION_WIDTH = 16; -const int SECTION_LENGTH = 16; -const int SECTION_HEIGHT = 16; - -class Section { - std::vector<unsigned short> m_palette; - byte *m_dataBlocks = nullptr; - size_t m_dataBlocksLen; - byte *m_dataLight = nullptr; - byte *m_dataSkyLight = nullptr; - byte m_bitsPerBlock = 0; - std::vector<Block> m_blocks; - std::condition_variable parseWaiter; - - Section(); - -public: - void Parse(); - - Section(byte *dataBlocks, size_t dataBlocksLength, byte *dataLight, byte *dataSky, byte bitsPerBlock, - std::vector<unsigned short> palette); - - ~Section(); - - Block &GetBlock(Vector pos); - - Section &operator=(Section other); - - friend void swap(Section &a, Section& b); - - Section(const Section &other); - -};
\ No newline at end of file diff --git a/src/world/World.cpp b/src/world/World.cpp index 394598b..abcfebf 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -1,4 +1,4 @@ -#include "World.hpp" +#include <world/World.hpp> void World::ParseChunkData(std::shared_ptr<PacketChunkData> packet) { StreamBuffer chunkData(packet->Data.data(), packet->Data.size()); @@ -6,7 +6,7 @@ void World::ParseChunkData(std::shared_ptr<PacketChunkData> packet) { for (int i = 0; i < 16; i++) { if (bitmask[i]) { Vector chunkPosition = Vector(packet->ChunkX, i, packet->ChunkZ); - Section section = ParseSection(&chunkData); + Section section = ParseSection(&chunkData, chunkPosition); auto it = sections.find(chunkPosition); if (it == sections.end()) { sections.insert(std::make_pair(chunkPosition, section)); @@ -19,7 +19,7 @@ void World::ParseChunkData(std::shared_ptr<PacketChunkData> packet) { } } -Section World::ParseSection(StreamInput *data) { +Section World::ParseSection(StreamInput *data, Vector position) { unsigned char bitsPerBlock = data->ReadUByte(); int paletteLength = data->ReadVarInt(); std::vector<unsigned short> palette; @@ -32,7 +32,7 @@ Section World::ParseSection(StreamInput *data) { std::vector<unsigned char> skyLight; if (dimension == 0) skyLight = data->ReadByteArray(4096 / 2); - return Section(dataArray.data(), dataArray.size(), blockLight.data(), + return Section(position, dataArray.data(), dataArray.size(), blockLight.data(), (skyLight.size() > 0 ? skyLight.data() : nullptr), bitsPerBlock, palette); } diff --git a/src/world/World.hpp b/src/world/World.hpp deleted file mode 100644 index e315baf..0000000 --- a/src/world/World.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include <map> -#include <thread> -#include <mutex> -#include <condition_variable> -#include <queue> -#include <bitset> -#include <easylogging++.h> -#include "Block.hpp" -#include "Section.hpp" -#include "../network/Packet.hpp" -#include "Collision.hpp" - -class World { - //utility vars - World(const World &other); - - World &operator=(const World &other); - - //game vars - int dimension = 0; - - //game methods - Section ParseSection(StreamInput *data); - -public: - World(); - - ~World(); - - void ParseChunkData(std::shared_ptr<PacketChunkData> packet); - - std::map<Vector, Section> sections; - - bool isPlayerCollides(double X, double Y, double Z); -};
\ No newline at end of file |