summaryrefslogtreecommitdiffstats
path: root/src/gamestate/GameState.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gamestate/GameState.cpp')
-rw-r--r--src/gamestate/GameState.cpp518
1 files changed, 392 insertions, 126 deletions
diff --git a/src/gamestate/GameState.cpp b/src/gamestate/GameState.cpp
index 5c5b9c4..3f3469d 100644
--- a/src/gamestate/GameState.cpp
+++ b/src/gamestate/GameState.cpp
@@ -1,131 +1,397 @@
#include "GameState.hpp"
-GameState::GameState(NetworkClient *Net) : nc(Net) {
- Packet *response = nc->GetPacket();
- if (response->GetId() != 0x02) {
- LOG(ERROR) << "Response id is " << response->GetId();
- throw std::runtime_error("Response id is not 0x02");
- }
- PacketParser::Parse(*response, Login);
- g_PlayerUuid = response->GetField(0).GetString();
- g_PlayerName = response->GetField(1).GetString();
- delete response;
- m_networkState = ConnectionState::Play;
- LOG(INFO) << g_PlayerName << "'s UUID is " << g_PlayerUuid;
+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() {
- Packet *packetPtr;
-
- try {
- packetPtr = nc->GetPacket();
- if (packetPtr == nullptr)
- return;
- PacketParser::Parse(*packetPtr, m_networkState);
- } catch (std::exception &e) {
- LOG(ERROR) << "Catched exception during packet pulling: " << e.what();
- return;
- }
- Packet &packet = *packetPtr;
- nlohmann::json json;
-
- switch (packet.GetId()) {
- case 0x23:
- g_PlayerEid = packet.GetField(0).GetInt();
- g_Gamemode = (packet.GetField(1).GetUByte() & 0b11111011);
- g_Dimension = packet.GetField(2).GetInt();
- g_Difficulty = packet.GetField(3).GetUByte();
- g_MaxPlayers = packet.GetField(4).GetUByte();
- g_LevelType = packet.GetField(5).GetString();
- g_ReducedDebugInfo = packet.GetField(6).GetBool();
- LOG(INFO) << "Gamemode is " << g_Gamemode << ", Difficulty is " << (int) g_Difficulty
- << ", Level Type is " << g_LevelType;
- break;
- case 0x0D:
- g_Difficulty = packet.GetField(0).GetUByte();
- LOG(INFO) << "Difficulty now is " << (int) g_Difficulty;
- break;
- case 0x43:
- g_SpawnPosition = packet.GetField(0).GetPosition();
- LOG(INFO) << "Spawn position is " << g_SpawnPosition.GetX() << "," << g_SpawnPosition.GetY() << ","
- << g_SpawnPosition.GetZ();
- break;
- case 0x2B:
- g_PlayerInvulnerable = (packet.GetField(0).GetByte() & 0x01) != 0;
- g_PlayerFlying = (packet.GetField(0).GetByte() & 0x02) != 0;
- g_PlayerAllowFlying = (packet.GetField(0).GetByte() & 0x04) != 0;
- g_PlayerCreativeMode = (packet.GetField(0).GetByte() & 0x08) != 0;
- g_PlayerFlyingSpeed = packet.GetField(1).GetFloat();
- g_PlayerFovModifier = packet.GetField(2).GetFloat();
- LOG(INFO) << "FOV modifier is " << g_PlayerFovModifier;
- break;
- case 0x2E:
- if ((packet.GetField(5).GetByte() & 0x10) != 0) {
- g_PlayerPitch += packet.GetField(4).GetFloat();
- } else {
- g_PlayerPitch = packet.GetField(4).GetFloat();
- };
-
- if ((packet.GetField(5).GetByte() & 0x08) != 0) {
- g_PlayerYaw += packet.GetField(3).GetFloat();
- } else {
- g_PlayerYaw = packet.GetField(3).GetFloat();
- }
-
- if ((packet.GetField(5).GetByte() & 0x01) != 0) {
- g_PlayerX += packet.GetField(0).GetDouble();
- } else {
- g_PlayerX = packet.GetField(0).GetDouble();
- }
-
- if ((packet.GetField(5).GetByte() & 0x02) != 0) {
- g_PlayerY += packet.GetField(1).GetDouble();
- } else {
- g_PlayerY = packet.GetField(1).GetDouble();
- }
-
- if ((packet.GetField(5).GetByte() & 0x04) != 0) {
- g_PlayerZ += packet.GetField(2).GetDouble();
- } else {
- g_PlayerZ = packet.GetField(2).GetDouble();
- }
-
- g_IsGameStarted = true;
- nc->AddPacketToQueue(PacketBuilder::CPlay0x03(0));
- nc->AddPacketToQueue(PacketBuilder::CPlay0x00(packet.GetField(6).GetVarInt()));
- LOG(INFO) << "Game is started!";
- LOG(INFO) << "PlayerPos is " << g_PlayerX << ", " << g_PlayerY << ", " << g_PlayerZ << "\tAngle: "
- << g_PlayerYaw
- << "," << g_PlayerPitch;
- break;
- case 0x1A:
- json = nlohmann::json::parse(packet.GetField(0).GetString());
- LOG(INFO) << "Disconnect reason: " << json["text"].get<std::string>();
- throw 119;
- break;
- case 0x20:
- world.ParseChunkData(packet);
- break;
- case 0x07:
- LOG(INFO) << "Statistics: ";
- for (int i = 0; i < packet.GetField(0).GetVarInt(); i++) {
- LOG(INFO) << "\t" << packet.GetField(1).GetArray()[0].GetString() << ": "
- << packet.GetField(1).GetArray()[1].GetVarInt();
- }
- break;
- default:
- break;
- }
- if (g_IsGameStarted) {
- std::chrono::steady_clock clock;
- static auto timeOfPreviousSendedPpalPacket(clock.now());
- std::chrono::duration<double, std::milli> delta = clock.now() - timeOfPreviousSendedPpalPacket;
- if (delta.count() >= 50) {
- nc->AddPacketToQueue(
- PacketBuilder::CPlay0x0D(g_PlayerX, g_PlayerY, g_PlayerZ, g_PlayerYaw, g_PlayerPitch, true));
- timeOfPreviousSendedPpalPacket = clock.now();
- }
- }
-
- delete packetPtr;
+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;
+ 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;
+ if (std::abs(g_PlayerVelocityX) > 0.01)
+ g_PlayerVelocityX -= AirResistance * deltaTime * (g_PlayerVelocityX > 0 ? 1 : -1);
+ else
+ g_PlayerVelocityX = 0;
+ if (std::abs(g_PlayerVelocityZ) > 0.01)
+ g_PlayerVelocityZ -= AirResistance * deltaTime * (g_PlayerVelocityZ > 0 ? 1 : -1);
+ else
+ g_PlayerVelocityZ = 0;*/
+ 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();
+ if (ptr == nullptr)
+ return;
+ 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<1) {
+ 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;
+ }
+}
+
+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;
+ break;
+ }
+ g_PlayerVelocityX = vel.x;
+ g_PlayerVelocityY = vel.y;
+ g_PlayerVelocityZ = vel.z;
+ const double MaxSpeed = 5.0;
+ /*if (g_PlayerVelocityX > MaxSpeed || g_PlayerVelocityX < -MaxSpeed)
+ g_PlayerVelocityX = MaxSpeed * (g_PlayerVelocityX > 0 ? 1 : -1);
+ if (g_PlayerVelocityZ > MaxSpeed || g_PlayerVelocityZ < -MaxSpeed)
+ g_PlayerVelocityZ = MaxSpeed * (g_PlayerVelocityZ > 0 ? 1 : -1);*/
+
+
+ /*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;
}