summaryrefslogtreecommitdiffstats
path: root/src/GameState.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/GameState.cpp205
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