From c0ab09af747fc431dfb459ede30788cb9cd1c56b Mon Sep 17 00:00:00 2001 From: BlockMen Date: Fri, 11 Apr 2014 15:32:46 +0200 Subject: [PATCH] Add player:set_eye_offset() by @MirceaKitsune and clean up --- doc/lua_api.txt | 3 +++ src/camera.cpp | 10 ++++++++-- src/camera.h | 2 ++ src/client.cpp | 11 +++++++++++ src/clientmap.cpp | 2 +- src/clientserver.h | 7 +++++++ src/content_cao.cpp | 10 ++++++++-- src/game.cpp | 2 -- src/game.h | 1 - src/hud.cpp | 1 - src/localplayer.cpp | 4 +++- src/localplayer.h | 5 ++++- src/script/lua_api/l_object.cpp | 33 ++++++++++++++++++++++++++++++++- src/script/lua_api/l_object.h | 5 ++++- src/server.cpp | 23 +++++++++++++++++++++++ src/server.h | 2 ++ 16 files changed, 108 insertions(+), 13 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index bfc12941b..b9865ae44 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1880,6 +1880,9 @@ Player-only: (no-op for other objects) ^ dig animation key frames ^ walk+dig animation key frames ^ animation frame speed +- set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0}): defines offset value for camera per player + ^ in first person view + ^ in third person view (max. values {x=-10/10,y=-10,15,z=-5/5}) InvRef: Reference to an inventory methods: diff --git a/src/camera.cpp b/src/camera.cpp index 6d17ff743..6fbd1dd8c 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -41,7 +41,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #define CAMERA_OFFSET_STEP 200 #include "nodedef.h" -#include "game.h" // CameraModes Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control, IGameDef *gamedef): @@ -297,8 +296,15 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, fall_bobbing *= g_settings->getFloat("fall_bobbing_amount"); } + // Calculate players eye offset for different camera modes + v3f PlayerEyeOffset = player->getEyeOffset(); + if (current_camera_mode == CAMERA_MODE_FIRST) + PlayerEyeOffset += player->eye_offset_first; + else + PlayerEyeOffset += player->eye_offset_third; + // Set head node transformation - m_headnode->setPosition(player->getEyeOffset()+v3f(0,cameratilt*-player->hurt_tilt_strength+fall_bobbing,0)); + m_headnode->setPosition(PlayerEyeOffset+v3f(0,cameratilt*-player->hurt_tilt_strength+fall_bobbing,0)); m_headnode->setRotation(v3f(player->getPitch(), 0, cameratilt*player->hurt_tilt_strength)); m_headnode->updateAbsolutePosition(); diff --git a/src/camera.h b/src/camera.h index 645b9355d..82c8d4be3 100644 --- a/src/camera.h +++ b/src/camera.h @@ -33,6 +33,8 @@ class LocalPlayer; struct MapDrawControl; class IGameDef; +enum CameraModes {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT}; + /* Client camera class, manages the player and camera scene nodes, the viewing distance and performs view bobbing etc. It also displays the wielded tool in front of the diff --git a/src/client.cpp b/src/client.cpp index 4f392ad7a..dbe959067 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1928,6 +1928,17 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) player->local_animations[3] = readV2F1000(is); player->local_animation_speed = readF1000(is); } + else if(command == TOCLIENT_EYE_OFFSET) + { + std::string datastring((char *)&data[2], datasize - 2); + std::istringstream is(datastring, std::ios_base::binary); + + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player != NULL); + + player->eye_offset_first = readV3F1000(is); + player->eye_offset_third = readV3F1000(is); + } else { infostream<<"Client: Ignoring unknown command " diff --git a/src/clientmap.cpp b/src/clientmap.cpp index c8b2d412d..0a5d00b99 100644 --- a/src/clientmap.cpp +++ b/src/clientmap.cpp @@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapblock.h" #include "profiler.h" #include "settings.h" -#include "game.h" // CameraModes +#include "camera.h" // CameraModes #include "util/mathconstants.h" #include diff --git a/src/clientserver.h b/src/clientserver.h index 3d1adfc2d..a8cd2ea70 100644 --- a/src/clientserver.h +++ b/src/clientserver.h @@ -540,6 +540,13 @@ enum ToClientCommand v2f1000 walk+dig f1000 frame_speed */ + + TOCLIENT_EYE_OFFSET = 0x52, + /* + u16 command + v3f1000 first + v3f1000 third + */ }; enum ToServerCommand diff --git a/src/content_cao.cpp b/src/content_cao.cpp index dc3bae00d..dbaf13cc8 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -41,7 +41,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/mathconstants.h" #include "map.h" #include "main.h" // g_settings -#include "game.h" // CameraModes +#include "camera.h" // CameraModes #include #include #include @@ -1099,8 +1099,14 @@ public: walking = true; m_animation_speed = player->local_animation_speed; + if(!player->touching_ground && + g_settings->getBool("free_move") && + m_gamedef->checkLocalPrivilege("fly") && + g_settings->getBool("fast_move") && + m_gamedef->checkLocalPrivilege("fast")) + m_animation_speed *= 1.5; if(controls.sneak && walking) - m_animation_speed = player->local_animation_speed/2; + m_animation_speed /= 2; player->last_animation_speed = m_animation_speed; diff --git a/src/game.cpp b/src/game.cpp index 02308b65d..2e8d3761d 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -977,8 +977,6 @@ bool nodePlacementPrediction(Client &client, return false; } -bool is_third_person = false; - static void show_chat_menu(FormspecFormSource* current_formspec, TextDest* current_textdest, IWritableTextureSource* tsrc, IrrlichtDevice * device, Client* client, std::string text) diff --git a/src/game.h b/src/game.h index de0b8483b..1c831c530 100644 --- a/src/game.h +++ b/src/game.h @@ -124,7 +124,6 @@ public: class ChatBackend; /* to avoid having to include chat.h */ struct SubgameSpec; -enum CameraModes {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT}; void the_game( bool &kill, diff --git a/src/hud.cpp b/src/hud.cpp index d21011176..750755649 100644 --- a/src/hud.cpp +++ b/src/hud.cpp @@ -30,7 +30,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "tile.h" #include "localplayer.h" #include "camera.h" -#include "game.h" // CameraModes #include diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 276d8e57c..264463d38 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -52,7 +52,9 @@ LocalPlayer::LocalPlayer(IGameDef *gamedef): m_need_to_get_new_sneak_node(true), m_can_jump(false), camera_mode(0), - last_animation(NO_ANIM) + last_animation(NO_ANIM), + eye_offset_first(v3f(0,0,0)), + eye_offset_third(v3f(0,0,0)) { // Initialize hp to 0, so that no hearts will be shown if server // doesn't support health points diff --git a/src/localplayer.h b/src/localplayer.h index 4a35ca929..67deb9367 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -27,7 +27,7 @@ class ClientEnvironment; class ClientActiveObject; -enum localPlayerAnimations {NO_ANIM, WALK_ANIM, DIG_ANIM, WD_ANIM}; // no local animation, walking, digging, both +enum LocalPlayerAnimations {NO_ANIM, WALK_ANIM, DIG_ANIM, WD_ANIM}; // no local animation, walking, digging, both class LocalPlayer : public Player { @@ -63,6 +63,9 @@ public: float camera_impact; int camera_mode; + v3f eye_offset_first; + v3f eye_offset_third; + int last_animation; float last_animation_speed; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index e801ddd5f..8f2bde036 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -406,7 +406,7 @@ int ObjectRef::l_set_animation(lua_State *L) return 0; } -// set_local_animation(self, {stand/ilde}, {walk}, {dig}, {walk+dig}, frame_speed) +// set_local_animation(self, {stand/idle}, {walk}, {dig}, {walk+dig}, frame_speed) int ObjectRef::l_set_local_animation(lua_State *L) { //NO_MAP_LOCK_REQUIRED; @@ -431,6 +431,36 @@ int ObjectRef::l_set_local_animation(lua_State *L) return 0; } +// set_eye_offset(self, v3f first pv, v3f third pv) +int ObjectRef::l_set_eye_offset(lua_State *L) +{ + //NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + Player *player = getplayer(ref); + if (player == NULL) + return 0; + // Do it + v3f offset_first = v3f(0, 0, 0); + v3f offset_third = v3f(0, 0, 0); + + if(!lua_isnil(L, 2)) + offset_first = read_v3f(L, 2); + if(!lua_isnil(L, 3)) + offset_third = read_v3f(L, 3); + + // 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 colision detetion to allow Y <= -1.5) */ + offset_third.Y = rangelim(offset_third.Y,-10,15); //1.5*BS + + if (!getServer(L)->setPlayerEyeOffset(player, offset_first, offset_third)) + return 0; + + lua_pushboolean(L, true); + return 0; +} + // set_bone_position(self, std::string bone, v3f position, v3f rotation) int ObjectRef::l_set_bone_position(lua_State *L) { @@ -1296,5 +1326,6 @@ const luaL_reg ObjectRef::methods[] = { luamethod(ObjectRef, set_sky), luamethod(ObjectRef, override_day_night_ratio), luamethod(ObjectRef, set_local_animation), + luamethod(ObjectRef, set_eye_offset), {0,0} }; diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index be1068c14..f6070585d 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -231,9 +231,12 @@ private: // override_day_night_ratio(self, type, list) static int l_override_day_night_ratio(lua_State *L); - // set_local_animation(self, {stand/ilde}, {walk}, {dig}, {walk+dig}, frame_speed) + // set_local_animation(self, {stand/idle}, {walk}, {dig}, {walk+dig}, frame_speed) static int l_set_local_animation(lua_State *L); + // set_eye_offset(self, v3f first pv, v3f third pv) + static int l_set_eye_offset(lua_State *L); + public: ObjectRef(ServerActiveObject *object); diff --git a/src/server.cpp b/src/server.cpp index 4f42cfabe..cbb9f427f 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -3502,6 +3502,20 @@ void Server::SendLocalPlayerAnimations(u16 peer_id, v2f animation_frames[4], f32 m_clients.send(peer_id, 0, data, true); } +void Server::SendEyeOffset(u16 peer_id, v3f first, v3f third) +{ + std::ostringstream os(std::ios_base::binary); + + writeU16(os, TOCLIENT_EYE_OFFSET); + writeV3F1000(os, first); + writeV3F1000(os, third); + + // Make data buffer + std::string s = os.str(); + SharedBuffer data((u8 *)s.c_str(), s.size()); + // Send as reliable + m_clients.send(peer_id, 0, data, true); +} void Server::SendPlayerPrivileges(u16 peer_id) { Player *player = m_env->getPlayer(peer_id); @@ -4605,6 +4619,15 @@ bool Server::setLocalPlayerAnimations(Player *player, v2f animation_frames[4], f return true; } +bool Server::setPlayerEyeOffset(Player *player, v3f first, v3f third) +{ + if (!player) + return false; + + SendEyeOffset(player->peer_id, first, third); + return true; +} + bool Server::setSky(Player *player, const video::SColor &bgcolor, const std::string &type, const std::vector ¶ms) { diff --git a/src/server.h b/src/server.h index c796fc827..23194a3ff 100644 --- a/src/server.h +++ b/src/server.h @@ -323,6 +323,7 @@ public: { return m_con.GetPeerAddress(peer_id); } bool setLocalPlayerAnimations(Player *player, v2f animation_frames[4], f32 frame_speed); + bool setPlayerEyeOffset(Player *player, v3f first, v3f third); bool setSky(Player *player, const video::SColor &bgcolor, const std::string &type, const std::vector ¶ms); @@ -364,6 +365,7 @@ private: void SendPlayerBreath(u16 peer_id); void SendMovePlayer(u16 peer_id); void SendLocalPlayerAnimations(u16 peer_id, v2f animation_frames[4], f32 animation_speed); + void SendEyeOffset(u16 peer_id, v3f first, v3f third); void SendPlayerPrivileges(u16 peer_id); void SendPlayerInventoryFormspec(u16 peer_id); void SendShowFormspecMessage(u16 peer_id, const std::string &formspec, const std::string &formname);