diff options
Diffstat (limited to '')
-rw-r--r-- | src/GameState.cpp | 205 |
1 files changed, 167 insertions, 38 deletions
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 |