diff --git a/doc/lua_api.md b/doc/lua_api.md index 6d76981ef..93c898918 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -7962,11 +7962,16 @@ child will follow movement and rotation of that bone. * `frame_speed` sets the animations frame speed. Default is 30. * `get_local_animation()`: returns idle, walk, dig, walk_while_dig tables and `frame_speed`. -* `set_eye_offset([firstperson, thirdperson])`: defines offset vectors for - camera per player. An argument defaults to `{x=0, y=0, z=0}` if unspecified. - * in first person view - * in third person view (max. values `{x=-10/10,y=-10,15,z=-5/5}`) -* `get_eye_offset()`: returns first and third person offsets. +* `set_eye_offset([firstperson, thirdperson_back, thirdperson_front])`: Sets camera offset vectors. + * `firstperson`: Offset in first person view. + Defaults to `vector.zero()` if unspecified. + * `thirdperson_back`: Offset in third person back view. + Clamped between `vector.new(-10, -10, -5)` and `vector.new(10, 15, 5)`. + Defaults to `vector.zero()` if unspecified. + * `thirdperson_front`: Offset in third person front view. + Same limits as for `thirdperson_back` apply. + Defaults to `thirdperson_back` if unspecified. +* `get_eye_offset()`: Returns camera offset vectors as set via `set_eye_offset`. * `send_mapblock(blockpos)`: * Sends an already loaded mapblock to the player. * Returns `false` if nothing was sent (note that this can also mean that diff --git a/src/client/camera.cpp b/src/client/camera.cpp index e8517dd9c..af70f4ebd 100644 --- a/src/client/camera.cpp +++ b/src/client/camera.cpp @@ -382,9 +382,9 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 tool_reload_ratio) eye_offset += player->eye_offset_third; break; case CAMERA_MODE_THIRD_FRONT: - eye_offset.X += player->eye_offset_third.X; - eye_offset.Y += player->eye_offset_third.Y; - eye_offset.Z -= player->eye_offset_third.Z; + eye_offset.X += player->eye_offset_third_front.X; + eye_offset.Y += player->eye_offset_third_front.Y; + eye_offset.Z -= player->eye_offset_third_front.Z; break; } diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index d75a4e68b..2cb3b20ed 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -1518,6 +1518,11 @@ void Client::handleCommand_EyeOffset(NetworkPacket* pkt) assert(player != NULL); *pkt >> player->eye_offset_first >> player->eye_offset_third; + try { + *pkt >> player->eye_offset_third_front; + } catch (PacketError &e) { + player->eye_offset_third_front = player->eye_offset_third; + }; } void Client::handleCommand_UpdatePlayerList(NetworkPacket* pkt) diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index 88698bf55..5b9ead992 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -751,6 +751,7 @@ enum ToClientCommand /* v3f1000 first v3f1000 third + v3f1000 third_front */ TOCLIENT_DELETE_PARTICLESPAWNER = 0x53, diff --git a/src/player.h b/src/player.h index 1a59a17ce..af1d73f4a 100644 --- a/src/player.h +++ b/src/player.h @@ -180,6 +180,7 @@ public: v3f eye_offset_first; v3f eye_offset_third; + v3f eye_offset_third_front; Inventory inventory; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 684a55dc4..3815f815f 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -435,7 +435,7 @@ int ObjectRef::l_get_local_animation(lua_State *L) return 5; } -// set_eye_offset(self, firstperson, thirdperson) +// set_eye_offset(self, firstperson, thirdperson_back, thirdperson_front) int ObjectRef::l_set_eye_offset(lua_State *L) { NO_MAP_LOCK_REQUIRED; @@ -446,14 +446,19 @@ int ObjectRef::l_set_eye_offset(lua_State *L) v3f offset_first = readParam(L, 2, v3f(0, 0, 0)); v3f offset_third = readParam(L, 3, v3f(0, 0, 0)); + v3f offset_third_front = readParam(L, 4, offset_third); // Prevent abuse of offset values (keep player always visible) - offset_third.X = rangelim(offset_third.X,-10,10); - offset_third.Z = rangelim(offset_third.Z,-5,5); - /* TODO: if possible: improve the camera collision detection to allow Y <= -1.5) */ - offset_third.Y = rangelim(offset_third.Y,-10,15); //1.5*BS + auto clamp_third = [] (v3f &vec) { + vec.X = rangelim(vec.X, -10, 10); + vec.Z = rangelim(vec.Z, -5, 5); + /* TODO: if possible: improve the camera collision detection to allow Y <= -1.5) */ + vec.Y = rangelim(vec.Y, -10, 15); // 1.5 * BS + }; + clamp_third(offset_third); + clamp_third(offset_third_front); - getServer(L)->setPlayerEyeOffset(player, offset_first, offset_third); + getServer(L)->setPlayerEyeOffset(player, offset_first, offset_third, offset_third_front); return 0; } @@ -468,7 +473,8 @@ int ObjectRef::l_get_eye_offset(lua_State *L) push_v3f(L, player->eye_offset_first); push_v3f(L, player->eye_offset_third); - return 2; + push_v3f(L, player->eye_offset_third_front); + return 3; } // send_mapblock(self, pos) diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index 35e38151b..cbbe4f921 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -358,7 +358,7 @@ private: // get_local_animation(self) static int l_get_local_animation(lua_State *L); - // set_eye_offset(self, firstperson, thirdperson) + // set_eye_offset(self, firstperson, thirdperson, thirdperson_front) static int l_set_eye_offset(lua_State *L); // get_eye_offset(self) diff --git a/src/server.cpp b/src/server.cpp index 3e11709eb..f74c960a0 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1981,10 +1981,10 @@ void Server::SendLocalPlayerAnimations(session_t peer_id, v2s32 animation_frames Send(&pkt); } -void Server::SendEyeOffset(session_t peer_id, v3f first, v3f third) +void Server::SendEyeOffset(session_t peer_id, v3f first, v3f third, v3f third_front) { NetworkPacket pkt(TOCLIENT_EYE_OFFSET, 0, peer_id); - pkt << first << third; + pkt << first << third << third_front; Send(&pkt); } @@ -3405,12 +3405,13 @@ void Server::setLocalPlayerAnimations(RemotePlayer *player, SendLocalPlayerAnimations(player->getPeerId(), animation_frames, frame_speed); } -void Server::setPlayerEyeOffset(RemotePlayer *player, const v3f &first, const v3f &third) +void Server::setPlayerEyeOffset(RemotePlayer *player, const v3f &first, const v3f &third, const v3f &third_front) { sanity_check(player); player->eye_offset_first = first; player->eye_offset_third = third; - SendEyeOffset(player->getPeerId(), first, third); + player->eye_offset_third_front = third_front; + SendEyeOffset(player->getPeerId(), first, third, third_front); } void Server::setSky(RemotePlayer *player, const SkyboxParams ¶ms) diff --git a/src/server.h b/src/server.h index 6c9f80180..9f4a17217 100644 --- a/src/server.h +++ b/src/server.h @@ -320,7 +320,7 @@ public: void setLocalPlayerAnimations(RemotePlayer *player, v2s32 animation_frames[4], f32 frame_speed); - void setPlayerEyeOffset(RemotePlayer *player, const v3f &first, const v3f &third); + void setPlayerEyeOffset(RemotePlayer *player, const v3f &first, const v3f &third, const v3f &third_front); void setSky(RemotePlayer *player, const SkyboxParams ¶ms); void setSun(RemotePlayer *player, const SunParams ¶ms); @@ -451,7 +451,7 @@ private: void SendLocalPlayerAnimations(session_t peer_id, v2s32 animation_frames[4], f32 animation_speed); - void SendEyeOffset(session_t peer_id, v3f first, v3f third); + void SendEyeOffset(session_t peer_id, v3f first, v3f third, v3f third_front); void SendPlayerPrivileges(session_t peer_id); void SendPlayerInventoryFormspec(session_t peer_id); void SendPlayerFormspecPrepend(session_t peer_id);