mirror of
https://github.com/minetest/minetest.git
synced 2024-08-19 04:54:18 +02:00
Add third person view
This commit is contained in:
parent
e149d1ad9a
commit
a1db9242ec
@ -1874,6 +1874,12 @@ Player-only: (no-op for other objects)
|
|||||||
- override_day_night_ratio(ratio or nil)
|
- override_day_night_ratio(ratio or nil)
|
||||||
^ 0...1: Overrides day-night ratio, controlling sunlight to a specific amount
|
^ 0...1: Overrides day-night ratio, controlling sunlight to a specific amount
|
||||||
^ nil: Disables override, defaulting to sunlight based on day-night cycle
|
^ nil: Disables override, defaulting to sunlight based on day-night cycle
|
||||||
|
- set_local_animation({x=0, y=79}, {x=168, y=187}, {x=189, y=198}, {x=200, y=219}, frame_speed=30): set animation for player model in third person view
|
||||||
|
^ stand/idle animation key frames
|
||||||
|
^ walk animation key frames
|
||||||
|
^ dig animation key frames
|
||||||
|
^ walk+dig animation key frames
|
||||||
|
^ animation frame speed
|
||||||
|
|
||||||
InvRef: Reference to an inventory
|
InvRef: Reference to an inventory
|
||||||
methods:
|
methods:
|
||||||
|
@ -361,6 +361,7 @@
|
|||||||
# try reducing it, but don't reduce it to a number below double of targeted
|
# try reducing it, but don't reduce it to a number below double of targeted
|
||||||
# client number
|
# client number
|
||||||
#max_packets_per_iteration = 1024
|
#max_packets_per_iteration = 1024
|
||||||
|
|
||||||
#
|
#
|
||||||
# Physics stuff
|
# Physics stuff
|
||||||
#
|
#
|
||||||
|
@ -40,6 +40,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#define CAMERA_OFFSET_STEP 200
|
#define CAMERA_OFFSET_STEP 200
|
||||||
|
|
||||||
|
#include "nodedef.h"
|
||||||
|
#include "game.h" // CameraModes
|
||||||
|
|
||||||
Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control,
|
Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control,
|
||||||
IGameDef *gamedef):
|
IGameDef *gamedef):
|
||||||
m_smgr(smgr),
|
m_smgr(smgr),
|
||||||
@ -248,7 +251,8 @@ void Camera::step(f32 dtime)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
|
void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
|
||||||
v2u32 screensize, f32 tool_reload_ratio)
|
v2u32 screensize, f32 tool_reload_ratio,
|
||||||
|
int current_camera_mode, ClientEnvironment &c_env)
|
||||||
{
|
{
|
||||||
// Get player position
|
// Get player position
|
||||||
// Smooth the movement when walking up stairs
|
// Smooth the movement when walking up stairs
|
||||||
@ -276,7 +280,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
|
|||||||
|
|
||||||
// Fall bobbing animation
|
// Fall bobbing animation
|
||||||
float fall_bobbing = 0;
|
float fall_bobbing = 0;
|
||||||
if(player->camera_impact >= 1)
|
if(player->camera_impact >= 1 && current_camera_mode < CAMERA_MODE_THIRD)
|
||||||
{
|
{
|
||||||
if(m_view_bobbing_fall == -1) // Effect took place and has finished
|
if(m_view_bobbing_fall == -1) // Effect took place and has finished
|
||||||
player->camera_impact = m_view_bobbing_fall = 0;
|
player->camera_impact = m_view_bobbing_fall = 0;
|
||||||
@ -303,7 +307,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
|
|||||||
v3f rel_cam_target = v3f(0,0,1);
|
v3f rel_cam_target = v3f(0,0,1);
|
||||||
v3f rel_cam_up = v3f(0,1,0);
|
v3f rel_cam_up = v3f(0,1,0);
|
||||||
|
|
||||||
if (m_view_bobbing_anim != 0)
|
if (m_view_bobbing_anim != 0 && current_camera_mode < CAMERA_MODE_THIRD)
|
||||||
{
|
{
|
||||||
f32 bobfrac = my_modf(m_view_bobbing_anim * 2);
|
f32 bobfrac = my_modf(m_view_bobbing_anim * 2);
|
||||||
f32 bobdir = (m_view_bobbing_anim < 0.5) ? 1.0 : -1.0;
|
f32 bobdir = (m_view_bobbing_anim < 0.5) ? 1.0 : -1.0;
|
||||||
@ -352,19 +356,60 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
|
|||||||
v3f abs_cam_up;
|
v3f abs_cam_up;
|
||||||
m_headnode->getAbsoluteTransformation().rotateVect(abs_cam_up, rel_cam_up);
|
m_headnode->getAbsoluteTransformation().rotateVect(abs_cam_up, rel_cam_up);
|
||||||
|
|
||||||
|
// Seperate camera position for calculation
|
||||||
|
v3f my_cp = m_camera_position;
|
||||||
|
|
||||||
|
// Reposition the camera for third person view
|
||||||
|
if (current_camera_mode > CAMERA_MODE_FIRST) {
|
||||||
|
|
||||||
|
if (current_camera_mode == CAMERA_MODE_THIRD_FRONT)
|
||||||
|
m_camera_direction *= -1;
|
||||||
|
|
||||||
|
my_cp.Y += 2;
|
||||||
|
|
||||||
|
// Calculate new position
|
||||||
|
bool abort = false;
|
||||||
|
for (int i = BS; i <= BS*2; i++) {
|
||||||
|
my_cp.X = m_camera_position.X + m_camera_direction.X*-i;
|
||||||
|
my_cp.Z = m_camera_position.Z + m_camera_direction.Z*-i;
|
||||||
|
if (i > 12)
|
||||||
|
my_cp.Y = m_camera_position.Y + (m_camera_direction.Y*-i);
|
||||||
|
|
||||||
|
// Prevent camera positioned inside nodes
|
||||||
|
INodeDefManager *nodemgr = m_gamedef->ndef();
|
||||||
|
MapNode n = c_env.getClientMap().getNodeNoEx(floatToInt(my_cp, BS));
|
||||||
|
const ContentFeatures& features = nodemgr->get(n);
|
||||||
|
if(features.walkable) {
|
||||||
|
my_cp.X += m_camera_direction.X*-1*-BS/2;
|
||||||
|
my_cp.Z += m_camera_direction.Z*-1*-BS/2;
|
||||||
|
my_cp.Y += m_camera_direction.Y*-1*-BS/2;
|
||||||
|
abort = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If node blocks camera position don't move y to heigh
|
||||||
|
if (abort && my_cp.Y > player_position.Y+BS*2)
|
||||||
|
my_cp.Y = player_position.Y+BS*2;
|
||||||
|
}
|
||||||
|
|
||||||
// Update offset if too far away from the center of the map
|
// Update offset if too far away from the center of the map
|
||||||
m_camera_offset.X += CAMERA_OFFSET_STEP*
|
m_camera_offset.X += CAMERA_OFFSET_STEP*
|
||||||
(((s16)(m_camera_position.X/BS) - m_camera_offset.X)/CAMERA_OFFSET_STEP);
|
(((s16)(my_cp.X/BS) - m_camera_offset.X)/CAMERA_OFFSET_STEP);
|
||||||
m_camera_offset.Y += CAMERA_OFFSET_STEP*
|
m_camera_offset.Y += CAMERA_OFFSET_STEP*
|
||||||
(((s16)(m_camera_position.Y/BS) - m_camera_offset.Y)/CAMERA_OFFSET_STEP);
|
(((s16)(my_cp.Y/BS) - m_camera_offset.Y)/CAMERA_OFFSET_STEP);
|
||||||
m_camera_offset.Z += CAMERA_OFFSET_STEP*
|
m_camera_offset.Z += CAMERA_OFFSET_STEP*
|
||||||
(((s16)(m_camera_position.Z/BS) - m_camera_offset.Z)/CAMERA_OFFSET_STEP);
|
(((s16)(my_cp.Z/BS) - m_camera_offset.Z)/CAMERA_OFFSET_STEP);
|
||||||
|
|
||||||
// Set camera node transformation
|
// Set camera node transformation
|
||||||
m_cameranode->setPosition(m_camera_position-intToFloat(m_camera_offset, BS));
|
m_cameranode->setPosition(my_cp-intToFloat(m_camera_offset, BS));
|
||||||
m_cameranode->setUpVector(abs_cam_up);
|
m_cameranode->setUpVector(abs_cam_up);
|
||||||
// *100.0 helps in large map coordinates
|
// *100.0 helps in large map coordinates
|
||||||
m_cameranode->setTarget(m_camera_position-intToFloat(m_camera_offset, BS) + 100 * m_camera_direction);
|
m_cameranode->setTarget(my_cp-intToFloat(m_camera_offset, BS) + 100 * m_camera_direction);
|
||||||
|
|
||||||
|
// update the camera position in front-view mode to render blocks behind player
|
||||||
|
if (current_camera_mode == CAMERA_MODE_THIRD_FRONT)
|
||||||
|
m_camera_position = my_cp;
|
||||||
|
|
||||||
// Get FOV setting
|
// Get FOV setting
|
||||||
f32 fov_degrees = g_settings->getFloat("fov");
|
f32 fov_degrees = g_settings->getFloat("fov");
|
||||||
|
@ -27,6 +27,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
#include <ICameraSceneNode.h>
|
#include <ICameraSceneNode.h>
|
||||||
|
|
||||||
|
#include "client.h"
|
||||||
|
|
||||||
class LocalPlayer;
|
class LocalPlayer;
|
||||||
struct MapDrawControl;
|
struct MapDrawControl;
|
||||||
class IGameDef;
|
class IGameDef;
|
||||||
@ -113,7 +115,8 @@ public:
|
|||||||
// Update the camera from the local player's position.
|
// Update the camera from the local player's position.
|
||||||
// busytime is used to adjust the viewing range.
|
// busytime is used to adjust the viewing range.
|
||||||
void update(LocalPlayer* player, f32 frametime, f32 busytime,
|
void update(LocalPlayer* player, f32 frametime, f32 busytime,
|
||||||
v2u32 screensize, f32 tool_reload_ratio);
|
v2u32 screensize, f32 tool_reload_ratio,
|
||||||
|
int current_camera_mode, ClientEnvironment &c_env);
|
||||||
|
|
||||||
// Render distance feedback loop
|
// Render distance feedback loop
|
||||||
void updateViewingRange(f32 frametime_in, f32 busytime_in);
|
void updateViewingRange(f32 frametime_in, f32 busytime_in);
|
||||||
|
@ -1914,6 +1914,20 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
|||||||
event.override_day_night_ratio.ratio_f = day_night_ratio_f;
|
event.override_day_night_ratio.ratio_f = day_night_ratio_f;
|
||||||
m_client_event_queue.push_back(event);
|
m_client_event_queue.push_back(event);
|
||||||
}
|
}
|
||||||
|
else if(command == TOCLIENT_LOCAL_PLAYER_ANIMATIONS)
|
||||||
|
{
|
||||||
|
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->local_animations[0] = readV2F1000(is);
|
||||||
|
player->local_animations[1] = readV2F1000(is);
|
||||||
|
player->local_animations[2] = readV2F1000(is);
|
||||||
|
player->local_animations[3] = readV2F1000(is);
|
||||||
|
player->local_animation_speed = readF1000(is);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
infostream<<"Client: Ignoring unknown command "
|
infostream<<"Client: Ignoring unknown command "
|
||||||
|
@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "mapblock.h"
|
#include "mapblock.h"
|
||||||
#include "profiler.h"
|
#include "profiler.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "game.h" // CameraModes
|
||||||
#include "util/mathconstants.h"
|
#include "util/mathconstants.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -866,13 +867,16 @@ void ClientMap::renderPostFx()
|
|||||||
v3f camera_position = m_camera_position;
|
v3f camera_position = m_camera_position;
|
||||||
m_camera_mutex.Unlock();
|
m_camera_mutex.Unlock();
|
||||||
|
|
||||||
|
LocalPlayer *player = m_client->getEnv().getLocalPlayer();
|
||||||
|
|
||||||
MapNode n = getNodeNoEx(floatToInt(camera_position, BS));
|
MapNode n = getNodeNoEx(floatToInt(camera_position, BS));
|
||||||
|
|
||||||
// - If the player is in a solid node, make everything black.
|
// - If the player is in a solid node, make everything black.
|
||||||
// - If the player is in liquid, draw a semi-transparent overlay.
|
// - If the player is in liquid, draw a semi-transparent overlay.
|
||||||
|
// - Do not if player is in third person mode
|
||||||
const ContentFeatures& features = nodemgr->get(n);
|
const ContentFeatures& features = nodemgr->get(n);
|
||||||
video::SColor post_effect_color = features.post_effect_color;
|
video::SColor post_effect_color = features.post_effect_color;
|
||||||
if(features.solidness == 2 && !(g_settings->getBool("noclip") && m_gamedef->checkLocalPrivilege("noclip")))
|
if(features.solidness == 2 && !(g_settings->getBool("noclip") && m_gamedef->checkLocalPrivilege("noclip")) && player->camera_mode == CAMERA_MODE_FIRST)
|
||||||
{
|
{
|
||||||
post_effect_color = video::SColor(255, 0, 0, 0);
|
post_effect_color = video::SColor(255, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -530,6 +530,16 @@ enum ToClientCommand
|
|||||||
u8 do_override (boolean)
|
u8 do_override (boolean)
|
||||||
u16 day-night ratio 0...65535
|
u16 day-night ratio 0...65535
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
TOCLIENT_LOCAL_PLAYER_ANIMATIONS = 0x51,
|
||||||
|
/*
|
||||||
|
u16 command
|
||||||
|
v2f1000 stand/idle
|
||||||
|
v2f1000 walk
|
||||||
|
v2f1000 dig
|
||||||
|
v2f1000 walk+dig
|
||||||
|
f1000 frame_speed
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ToServerCommand
|
enum ToServerCommand
|
||||||
|
@ -41,6 +41,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "util/mathconstants.h"
|
#include "util/mathconstants.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "main.h" // g_settings
|
#include "main.h" // g_settings
|
||||||
|
#include "game.h" // CameraModes
|
||||||
#include <IMeshManipulator.h>
|
#include <IMeshManipulator.h>
|
||||||
#include <IAnimatedMeshSceneNode.h>
|
#include <IAnimatedMeshSceneNode.h>
|
||||||
#include <IBoneSceneNode.h>
|
#include <IBoneSceneNode.h>
|
||||||
@ -858,7 +859,7 @@ public:
|
|||||||
|
|
||||||
m_visuals_expired = false;
|
m_visuals_expired = false;
|
||||||
|
|
||||||
if(!m_prop.is_visible || m_is_local_player)
|
if(!m_prop.is_visible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//video::IVideoDriver* driver = smgr->getVideoDriver();
|
//video::IVideoDriver* driver = smgr->getVideoDriver();
|
||||||
@ -1078,6 +1079,60 @@ public:
|
|||||||
|
|
||||||
void step(float dtime, ClientEnvironment *env)
|
void step(float dtime, ClientEnvironment *env)
|
||||||
{
|
{
|
||||||
|
// Handel model of local player instantly to prevent lags
|
||||||
|
if(m_is_local_player) {
|
||||||
|
LocalPlayer *player = m_env->getLocalPlayer();
|
||||||
|
|
||||||
|
if (player->camera_mode > CAMERA_MODE_FIRST) {
|
||||||
|
int old_anim = player->last_animation;
|
||||||
|
float old_anim_speed = player->last_animation_speed;
|
||||||
|
m_is_visible = true;
|
||||||
|
m_position = player->getPosition() + v3f(0,BS,0);
|
||||||
|
m_velocity = v3f(0,0,0);
|
||||||
|
m_acceleration = v3f(0,0,0);
|
||||||
|
pos_translator.vect_show = m_position;
|
||||||
|
m_yaw = player->getYaw();
|
||||||
|
PlayerControl controls = player->getPlayerControl();
|
||||||
|
|
||||||
|
bool walking = false;
|
||||||
|
if(controls.up || controls.down || controls.left || controls.right)
|
||||||
|
walking = true;
|
||||||
|
|
||||||
|
m_animation_speed = player->local_animation_speed;
|
||||||
|
if(controls.sneak && walking)
|
||||||
|
m_animation_speed = player->local_animation_speed/2;
|
||||||
|
|
||||||
|
player->last_animation_speed = m_animation_speed;
|
||||||
|
|
||||||
|
if(walking && (controls.LMB || controls.RMB)) {
|
||||||
|
m_animation_range = player->local_animations[3];
|
||||||
|
player->last_animation = WD_ANIM;
|
||||||
|
} else if(walking) {
|
||||||
|
m_animation_range = player->local_animations[1];
|
||||||
|
player->last_animation = WALK_ANIM;
|
||||||
|
} else if(controls.LMB || controls.RMB) {
|
||||||
|
m_animation_range = player->local_animations[2];
|
||||||
|
player->last_animation = DIG_ANIM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset animation when no input detected
|
||||||
|
if (!walking && !controls.LMB && !controls.RMB) {
|
||||||
|
player->last_animation = NO_ANIM;
|
||||||
|
if (old_anim != NO_ANIM) {
|
||||||
|
m_animation_range = player->local_animations[0];
|
||||||
|
updateAnimation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update local player animations
|
||||||
|
if ((player->last_animation != old_anim && player->last_animation != NO_ANIM) || m_animation_speed != old_anim_speed)
|
||||||
|
updateAnimation();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
m_is_visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(m_visuals_expired && m_smgr && m_irr){
|
if(m_visuals_expired && m_smgr && m_irr){
|
||||||
m_visuals_expired = false;
|
m_visuals_expired = false;
|
||||||
|
|
||||||
@ -1701,6 +1756,7 @@ public:
|
|||||||
bool sneak = !readU8(is);
|
bool sneak = !readU8(is);
|
||||||
bool sneak_glitch = !readU8(is);
|
bool sneak_glitch = !readU8(is);
|
||||||
|
|
||||||
|
|
||||||
if(m_is_local_player)
|
if(m_is_local_player)
|
||||||
{
|
{
|
||||||
LocalPlayer *player = m_env->getLocalPlayer();
|
LocalPlayer *player = m_env->getLocalPlayer();
|
||||||
@ -1713,11 +1769,25 @@ public:
|
|||||||
}
|
}
|
||||||
else if(cmd == GENERIC_CMD_SET_ANIMATION)
|
else if(cmd == GENERIC_CMD_SET_ANIMATION)
|
||||||
{
|
{
|
||||||
m_animation_range = readV2F1000(is);
|
if (!m_is_local_player) {
|
||||||
m_animation_speed = readF1000(is);
|
m_animation_range = readV2F1000(is);
|
||||||
m_animation_blend = readF1000(is);
|
m_animation_speed = readF1000(is);
|
||||||
|
m_animation_blend = readF1000(is);
|
||||||
updateAnimation();
|
updateAnimation();
|
||||||
|
} else {
|
||||||
|
LocalPlayer *player = m_env->getLocalPlayer();
|
||||||
|
if(player->last_animation == NO_ANIM) {
|
||||||
|
m_animation_range = readV2F1000(is);
|
||||||
|
m_animation_speed = readF1000(is);
|
||||||
|
m_animation_blend = readF1000(is);
|
||||||
|
}
|
||||||
|
// update animation only if object is not player
|
||||||
|
// or the received animation is not registered
|
||||||
|
if(m_animation_range.X != player->local_animations[1].X &&
|
||||||
|
m_animation_range.X != player->local_animations[2].X &&
|
||||||
|
m_animation_range.X != player->local_animations[3].X)
|
||||||
|
updateAnimation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(cmd == GENERIC_CMD_SET_BONE_POSITION)
|
else if(cmd == GENERIC_CMD_SET_BONE_POSITION)
|
||||||
{
|
{
|
||||||
|
@ -53,6 +53,7 @@ void set_default_settings(Settings *settings)
|
|||||||
settings->setDefault("keymap_toggle_update_camera", "KEY_F4");
|
settings->setDefault("keymap_toggle_update_camera", "KEY_F4");
|
||||||
settings->setDefault("keymap_toggle_debug", "KEY_F5");
|
settings->setDefault("keymap_toggle_debug", "KEY_F5");
|
||||||
settings->setDefault("keymap_toggle_profiler", "KEY_F6");
|
settings->setDefault("keymap_toggle_profiler", "KEY_F6");
|
||||||
|
settings->setDefault("keymap_camera_mode", "KEY_F7");
|
||||||
settings->setDefault("keymap_increase_viewing_range_min", "+");
|
settings->setDefault("keymap_increase_viewing_range_min", "+");
|
||||||
settings->setDefault("keymap_decrease_viewing_range_min", "-");
|
settings->setDefault("keymap_decrease_viewing_range_min", "-");
|
||||||
settings->setDefault("anaglyph", "false");
|
settings->setDefault("anaglyph", "false");
|
||||||
|
30
src/game.cpp
30
src/game.cpp
@ -977,6 +977,8 @@ bool nodePlacementPrediction(Client &client,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_third_person = false;
|
||||||
|
|
||||||
static void show_chat_menu(FormspecFormSource* current_formspec,
|
static void show_chat_menu(FormspecFormSource* current_formspec,
|
||||||
TextDest* current_textdest, IWritableTextureSource* tsrc,
|
TextDest* current_textdest, IWritableTextureSource* tsrc,
|
||||||
IrrlichtDevice * device, Client* client, std::string text)
|
IrrlichtDevice * device, Client* client, std::string text)
|
||||||
@ -1470,6 +1472,8 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
|
|||||||
f32 camera_yaw = 0; // "right/left"
|
f32 camera_yaw = 0; // "right/left"
|
||||||
f32 camera_pitch = 0; // "up/down"
|
f32 camera_pitch = 0; // "up/down"
|
||||||
|
|
||||||
|
int current_camera_mode = CAMERA_MODE_FIRST; // start in first-person view
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Clouds
|
Clouds
|
||||||
*/
|
*/
|
||||||
@ -2251,7 +2255,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
|
|||||||
else{
|
else{
|
||||||
s32 dx = input->getMousePos().X - displaycenter.X;
|
s32 dx = input->getMousePos().X - displaycenter.X;
|
||||||
s32 dy = input->getMousePos().Y - displaycenter.Y;
|
s32 dy = input->getMousePos().Y - displaycenter.Y;
|
||||||
if(invert_mouse)
|
if(invert_mouse || player->camera_mode == CAMERA_MODE_THIRD_FRONT)
|
||||||
dy = -dy;
|
dy = -dy;
|
||||||
//infostream<<"window active, pos difference "<<dx<<","<<dy<<std::endl;
|
//infostream<<"window active, pos difference "<<dx<<","<<dy<<std::endl;
|
||||||
|
|
||||||
@ -2659,9 +2663,21 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
|
|||||||
LocalPlayer* player = client.getEnv().getLocalPlayer();
|
LocalPlayer* player = client.getEnv().getLocalPlayer();
|
||||||
float full_punch_interval = playeritem_toolcap.full_punch_interval;
|
float full_punch_interval = playeritem_toolcap.full_punch_interval;
|
||||||
float tool_reload_ratio = time_from_last_punch / full_punch_interval;
|
float tool_reload_ratio = time_from_last_punch / full_punch_interval;
|
||||||
|
|
||||||
|
if(input->wasKeyDown(getKeySetting("keymap_camera_mode"))) {
|
||||||
|
|
||||||
|
if (current_camera_mode == CAMERA_MODE_FIRST)
|
||||||
|
current_camera_mode = CAMERA_MODE_THIRD;
|
||||||
|
else if (current_camera_mode == CAMERA_MODE_THIRD)
|
||||||
|
current_camera_mode = CAMERA_MODE_THIRD_FRONT;
|
||||||
|
else
|
||||||
|
current_camera_mode = CAMERA_MODE_FIRST;
|
||||||
|
|
||||||
|
}
|
||||||
|
player->camera_mode = current_camera_mode;
|
||||||
tool_reload_ratio = MYMIN(tool_reload_ratio, 1.0);
|
tool_reload_ratio = MYMIN(tool_reload_ratio, 1.0);
|
||||||
camera.update(player, dtime, busytime, screensize,
|
camera.update(player, dtime, busytime, screensize, tool_reload_ratio,
|
||||||
tool_reload_ratio);
|
current_camera_mode, client.getEnv());
|
||||||
camera.step(dtime);
|
camera.step(dtime);
|
||||||
|
|
||||||
v3f player_position = player->getPosition();
|
v3f player_position = player->getPosition();
|
||||||
@ -2717,6 +2733,10 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
|
|||||||
core::line3d<f32> shootline(camera_position,
|
core::line3d<f32> shootline(camera_position,
|
||||||
camera_position + camera_direction * BS * (d+1));
|
camera_position + camera_direction * BS * (d+1));
|
||||||
|
|
||||||
|
// prevent player pointing anything in front-view
|
||||||
|
if (current_camera_mode == CAMERA_MODE_THIRD_FRONT)
|
||||||
|
shootline = core::line3d<f32>(0,0,0,0,0,0);
|
||||||
|
|
||||||
ClientActiveObject *selected_object = NULL;
|
ClientActiveObject *selected_object = NULL;
|
||||||
|
|
||||||
PointedThing pointed = getPointedThing(
|
PointedThing pointed = getPointedThing(
|
||||||
@ -3507,7 +3527,9 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
|
|||||||
/*
|
/*
|
||||||
Wielded tool
|
Wielded tool
|
||||||
*/
|
*/
|
||||||
if(show_hud && (player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE))
|
if(show_hud &&
|
||||||
|
(player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE) &&
|
||||||
|
current_camera_mode < CAMERA_MODE_THIRD)
|
||||||
{
|
{
|
||||||
// Warning: This clears the Z buffer.
|
// Warning: This clears the Z buffer.
|
||||||
camera.drawWieldedTool();
|
camera.drawWieldedTool();
|
||||||
|
@ -124,6 +124,7 @@ public:
|
|||||||
|
|
||||||
class ChatBackend; /* to avoid having to include chat.h */
|
class ChatBackend; /* to avoid having to include chat.h */
|
||||||
struct SubgameSpec;
|
struct SubgameSpec;
|
||||||
|
enum CameraModes {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT};
|
||||||
|
|
||||||
void the_game(
|
void the_game(
|
||||||
bool &kill,
|
bool &kill,
|
||||||
|
@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
#include "localplayer.h"
|
#include "localplayer.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
|
#include "game.h" // CameraModes
|
||||||
|
|
||||||
#include <IGUIStaticText.h>
|
#include <IGUIStaticText.h>
|
||||||
|
|
||||||
@ -384,7 +385,8 @@ void Hud::drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem, s
|
|||||||
|
|
||||||
|
|
||||||
void Hud::drawCrosshair() {
|
void Hud::drawCrosshair() {
|
||||||
if (!(player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE))
|
if (!(player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) ||
|
||||||
|
player->camera_mode == CAMERA_MODE_THIRD_FRONT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (use_crosshair_image) {
|
if (use_crosshair_image) {
|
||||||
|
@ -50,7 +50,9 @@ LocalPlayer::LocalPlayer(IGameDef *gamedef):
|
|||||||
m_old_node_below(32767,32767,32767),
|
m_old_node_below(32767,32767,32767),
|
||||||
m_old_node_below_type("air"),
|
m_old_node_below_type("air"),
|
||||||
m_need_to_get_new_sneak_node(true),
|
m_need_to_get_new_sneak_node(true),
|
||||||
m_can_jump(false)
|
m_can_jump(false),
|
||||||
|
camera_mode(0),
|
||||||
|
last_animation(NO_ANIM)
|
||||||
{
|
{
|
||||||
// Initialize hp to 0, so that no hearts will be shown if server
|
// Initialize hp to 0, so that no hearts will be shown if server
|
||||||
// doesn't support health points
|
// doesn't support health points
|
||||||
|
@ -27,6 +27,8 @@ class ClientEnvironment;
|
|||||||
|
|
||||||
class ClientActiveObject;
|
class ClientActiveObject;
|
||||||
|
|
||||||
|
enum localPlayerAnimations {NO_ANIM, WALK_ANIM, DIG_ANIM, WD_ANIM}; // no local animation, walking, digging, both
|
||||||
|
|
||||||
class LocalPlayer : public Player
|
class LocalPlayer : public Player
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -60,6 +62,9 @@ public:
|
|||||||
unsigned int last_keyPressed;
|
unsigned int last_keyPressed;
|
||||||
|
|
||||||
float camera_impact;
|
float camera_impact;
|
||||||
|
int camera_mode;
|
||||||
|
int last_animation;
|
||||||
|
float last_animation_speed;
|
||||||
|
|
||||||
std::string hotbar_image;
|
std::string hotbar_image;
|
||||||
std::string hotbar_selected_image;
|
std::string hotbar_selected_image;
|
||||||
|
@ -269,6 +269,9 @@ public:
|
|||||||
bool physics_override_sneak;
|
bool physics_override_sneak;
|
||||||
bool physics_override_sneak_glitch;
|
bool physics_override_sneak_glitch;
|
||||||
|
|
||||||
|
v2f local_animations[4];
|
||||||
|
float local_animation_speed;
|
||||||
|
|
||||||
u16 hp;
|
u16 hp;
|
||||||
|
|
||||||
float hurt_tilt_timer;
|
float hurt_tilt_timer;
|
||||||
|
@ -406,6 +406,31 @@ int ObjectRef::l_set_animation(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set_local_animation(self, {stand/ilde}, {walk}, {dig}, {walk+dig}, frame_speed)
|
||||||
|
int ObjectRef::l_set_local_animation(lua_State *L)
|
||||||
|
{
|
||||||
|
//NO_MAP_LOCK_REQUIRED;
|
||||||
|
ObjectRef *ref = checkobject(L, 1);
|
||||||
|
Player *player = getplayer(ref);
|
||||||
|
if (player == NULL)
|
||||||
|
return 0;
|
||||||
|
// Do it
|
||||||
|
v2f frames[4];
|
||||||
|
for (int i=0;i<4;i++) {
|
||||||
|
if(!lua_isnil(L, 2+1))
|
||||||
|
frames[i] = read_v2f(L, 2+i);
|
||||||
|
}
|
||||||
|
float frame_speed = 30;
|
||||||
|
if(!lua_isnil(L, 6))
|
||||||
|
frame_speed = lua_tonumber(L, 6);
|
||||||
|
|
||||||
|
if (!getServer(L)->setLocalPlayerAnimations(player, frames, frame_speed))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
lua_pushboolean(L, true);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// set_bone_position(self, std::string bone, v3f position, v3f rotation)
|
// set_bone_position(self, std::string bone, v3f position, v3f rotation)
|
||||||
int ObjectRef::l_set_bone_position(lua_State *L)
|
int ObjectRef::l_set_bone_position(lua_State *L)
|
||||||
{
|
{
|
||||||
@ -1270,5 +1295,6 @@ const luaL_reg ObjectRef::methods[] = {
|
|||||||
luamethod(ObjectRef, hud_set_hotbar_selected_image),
|
luamethod(ObjectRef, hud_set_hotbar_selected_image),
|
||||||
luamethod(ObjectRef, set_sky),
|
luamethod(ObjectRef, set_sky),
|
||||||
luamethod(ObjectRef, override_day_night_ratio),
|
luamethod(ObjectRef, override_day_night_ratio),
|
||||||
|
luamethod(ObjectRef, set_local_animation),
|
||||||
{0,0}
|
{0,0}
|
||||||
};
|
};
|
||||||
|
@ -231,6 +231,9 @@ private:
|
|||||||
// override_day_night_ratio(self, type, list)
|
// override_day_night_ratio(self, type, list)
|
||||||
static int l_override_day_night_ratio(lua_State *L);
|
static int l_override_day_night_ratio(lua_State *L);
|
||||||
|
|
||||||
|
// set_local_animation(self, {stand/ilde}, {walk}, {dig}, {walk+dig}, frame_speed)
|
||||||
|
static int l_set_local_animation(lua_State *L);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ObjectRef(ServerActiveObject *object);
|
ObjectRef(ServerActiveObject *object);
|
||||||
|
|
||||||
|
@ -3484,6 +3484,24 @@ void Server::SendMovePlayer(u16 peer_id)
|
|||||||
m_clients.send(peer_id, 0, data, true);
|
m_clients.send(peer_id, 0, data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Server::SendLocalPlayerAnimations(u16 peer_id, v2f animation_frames[4], f32 animation_speed)
|
||||||
|
{
|
||||||
|
std::ostringstream os(std::ios_base::binary);
|
||||||
|
|
||||||
|
writeU16(os, TOCLIENT_LOCAL_PLAYER_ANIMATIONS);
|
||||||
|
writeV2F1000(os, animation_frames[0]);
|
||||||
|
writeV2F1000(os, animation_frames[1]);
|
||||||
|
writeV2F1000(os, animation_frames[2]);
|
||||||
|
writeV2F1000(os, animation_frames[3]);
|
||||||
|
writeF1000(os, animation_speed);
|
||||||
|
|
||||||
|
// Make data buffer
|
||||||
|
std::string s = os.str();
|
||||||
|
SharedBuffer<u8> data((u8 *)s.c_str(), s.size());
|
||||||
|
// Send as reliable
|
||||||
|
m_clients.send(peer_id, 0, data, true);
|
||||||
|
}
|
||||||
|
|
||||||
void Server::SendPlayerPrivileges(u16 peer_id)
|
void Server::SendPlayerPrivileges(u16 peer_id)
|
||||||
{
|
{
|
||||||
Player *player = m_env->getPlayer(peer_id);
|
Player *player = m_env->getPlayer(peer_id);
|
||||||
@ -4578,6 +4596,15 @@ void Server::hudSetHotbarSelectedImage(Player *player, std::string name) {
|
|||||||
SendHUDSetParam(player->peer_id, HUD_PARAM_HOTBAR_SELECTED_IMAGE, name);
|
SendHUDSetParam(player->peer_id, HUD_PARAM_HOTBAR_SELECTED_IMAGE, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Server::setLocalPlayerAnimations(Player *player, v2f animation_frames[4], f32 frame_speed)
|
||||||
|
{
|
||||||
|
if (!player)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SendLocalPlayerAnimations(player->peer_id, animation_frames, frame_speed);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Server::setSky(Player *player, const video::SColor &bgcolor,
|
bool Server::setSky(Player *player, const video::SColor &bgcolor,
|
||||||
const std::string &type, const std::vector<std::string> ¶ms)
|
const std::string &type, const std::vector<std::string> ¶ms)
|
||||||
{
|
{
|
||||||
|
@ -322,6 +322,8 @@ public:
|
|||||||
inline Address getPeerAddress(u16 peer_id)
|
inline Address getPeerAddress(u16 peer_id)
|
||||||
{ return m_con.GetPeerAddress(peer_id); }
|
{ return m_con.GetPeerAddress(peer_id); }
|
||||||
|
|
||||||
|
bool setLocalPlayerAnimations(Player *player, v2f animation_frames[4], f32 frame_speed);
|
||||||
|
|
||||||
bool setSky(Player *player, const video::SColor &bgcolor,
|
bool setSky(Player *player, const video::SColor &bgcolor,
|
||||||
const std::string &type, const std::vector<std::string> ¶ms);
|
const std::string &type, const std::vector<std::string> ¶ms);
|
||||||
|
|
||||||
@ -361,6 +363,7 @@ private:
|
|||||||
void SendPlayerHP(u16 peer_id);
|
void SendPlayerHP(u16 peer_id);
|
||||||
void SendPlayerBreath(u16 peer_id);
|
void SendPlayerBreath(u16 peer_id);
|
||||||
void SendMovePlayer(u16 peer_id);
|
void SendMovePlayer(u16 peer_id);
|
||||||
|
void SendLocalPlayerAnimations(u16 peer_id, v2f animation_frames[4], f32 animation_speed);
|
||||||
void SendPlayerPrivileges(u16 peer_id);
|
void SendPlayerPrivileges(u16 peer_id);
|
||||||
void SendPlayerInventoryFormspec(u16 peer_id);
|
void SendPlayerInventoryFormspec(u16 peer_id);
|
||||||
void SendShowFormspecMessage(u16 peer_id, const std::string &formspec, const std::string &formname);
|
void SendShowFormspecMessage(u16 peer_id, const std::string &formspec, const std::string &formname);
|
||||||
|
Loading…
Reference in New Issue
Block a user