summaryrefslogtreecommitdiffstats
path: root/src/world
diff options
context:
space:
mode:
Diffstat (limited to 'src/world')
-rw-r--r--src/world/Block.cpp2
-rw-r--r--src/world/Block.hpp15
-rw-r--r--src/world/Collision.cpp2
-rw-r--r--src/world/Collision.hpp8
-rw-r--r--src/world/GameState.cpp389
-rw-r--r--src/world/Section.cpp16
-rw-r--r--src/world/Section.hpp43
-rw-r--r--src/world/World.cpp8
-rw-r--r--src/world/World.hpp37
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