mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Basic camera control API (#15796)
This commit is contained in:
parent
50819ace8f
commit
ba62808fe8
18 changed files with 162 additions and 42 deletions
|
@ -8827,6 +8827,14 @@ child will follow movement and rotation of that bone.
|
||||||
Same limits as for `thirdperson_back` apply.
|
Same limits as for `thirdperson_back` apply.
|
||||||
Defaults to `thirdperson_back` if unspecified.
|
Defaults to `thirdperson_back` if unspecified.
|
||||||
* `get_eye_offset()`: Returns camera offset vectors as set via `set_eye_offset`.
|
* `get_eye_offset()`: Returns camera offset vectors as set via `set_eye_offset`.
|
||||||
|
* `set_camera(params)`: Sets camera parameters.
|
||||||
|
* `mode`: Defines the camera mode used
|
||||||
|
- `any`: free choice between all modes (default)
|
||||||
|
- `first`: first-person camera
|
||||||
|
- `third`: third-person camera
|
||||||
|
- `third_front`: third-person camera, looking opposite of movement direction
|
||||||
|
* Supported by client since 5.12.0.
|
||||||
|
* `get_camera()`: Returns the camera parameters as a table as above.
|
||||||
* `send_mapblock(blockpos)`:
|
* `send_mapblock(blockpos)`:
|
||||||
* Sends an already loaded mapblock to the player.
|
* Sends an already loaded mapblock to the player.
|
||||||
* Returns `false` if nothing was sent (note that this can also mean that
|
* Returns `false` if nothing was sent (note that this can also mean that
|
||||||
|
|
|
@ -375,6 +375,9 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 tool_reload_ratio)
|
||||||
{
|
{
|
||||||
v3f eye_offset = player->getEyeOffset();
|
v3f eye_offset = player->getEyeOffset();
|
||||||
switch(m_camera_mode) {
|
switch(m_camera_mode) {
|
||||||
|
case CAMERA_MODE_ANY:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
case CAMERA_MODE_FIRST:
|
case CAMERA_MODE_FIRST:
|
||||||
eye_offset += player->eye_offset_first;
|
eye_offset += player->eye_offset_first;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -57,8 +57,6 @@ struct Nametag
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CameraMode {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Client camera class, manages the player and camera scene nodes, the viewing distance
|
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
|
and performs view bobbing etc. It also displays the wielded tool in front of the
|
||||||
|
@ -169,7 +167,8 @@ public:
|
||||||
void drawWieldedTool(irr::core::matrix4* translation=NULL);
|
void drawWieldedTool(irr::core::matrix4* translation=NULL);
|
||||||
|
|
||||||
// Toggle the current camera mode
|
// Toggle the current camera mode
|
||||||
void toggleCameraMode() {
|
void toggleCameraMode()
|
||||||
|
{
|
||||||
if (m_camera_mode == CAMERA_MODE_FIRST)
|
if (m_camera_mode == CAMERA_MODE_FIRST)
|
||||||
m_camera_mode = CAMERA_MODE_THIRD;
|
m_camera_mode = CAMERA_MODE_THIRD;
|
||||||
else if (m_camera_mode == CAMERA_MODE_THIRD)
|
else if (m_camera_mode == CAMERA_MODE_THIRD)
|
||||||
|
@ -185,7 +184,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
//read the current camera mode
|
//read the current camera mode
|
||||||
inline CameraMode getCameraMode()
|
inline CameraMode getCameraMode() const
|
||||||
{
|
{
|
||||||
return m_camera_mode;
|
return m_camera_mode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,6 +217,7 @@ public:
|
||||||
void handleCommand_MediaPush(NetworkPacket *pkt);
|
void handleCommand_MediaPush(NetworkPacket *pkt);
|
||||||
void handleCommand_MinimapModes(NetworkPacket *pkt);
|
void handleCommand_MinimapModes(NetworkPacket *pkt);
|
||||||
void handleCommand_SetLighting(NetworkPacket *pkt);
|
void handleCommand_SetLighting(NetworkPacket *pkt);
|
||||||
|
void handleCommand_Camera(NetworkPacket* pkt);
|
||||||
|
|
||||||
void ProcessData(NetworkPacket *pkt);
|
void ProcessData(NetworkPacket *pkt);
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ enum ClientEventType : u8
|
||||||
CE_SET_STARS,
|
CE_SET_STARS,
|
||||||
CE_OVERRIDE_DAY_NIGHT_RATIO,
|
CE_OVERRIDE_DAY_NIGHT_RATIO,
|
||||||
CE_CLOUD_PARAMS,
|
CE_CLOUD_PARAMS,
|
||||||
|
CE_UPDATE_CAMERA,
|
||||||
CLIENTEVENT_MAX,
|
CLIENTEVENT_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,11 +67,14 @@ struct ClientEventHudChange
|
||||||
|
|
||||||
struct ClientEvent
|
struct ClientEvent
|
||||||
{
|
{
|
||||||
|
// TODO: should get rid of this ctor
|
||||||
|
ClientEvent() : type(CE_NONE) {}
|
||||||
|
|
||||||
|
ClientEvent(ClientEventType type) : type(type) {}
|
||||||
|
|
||||||
ClientEventType type;
|
ClientEventType type;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
// struct{
|
|
||||||
//} none;
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
u16 amount;
|
u16 amount;
|
||||||
|
@ -86,8 +90,6 @@ struct ClientEvent
|
||||||
std::string *formspec;
|
std::string *formspec;
|
||||||
std::string *formname;
|
std::string *formname;
|
||||||
} show_formspec;
|
} show_formspec;
|
||||||
// struct{
|
|
||||||
//} textures_updated;
|
|
||||||
ParticleParameters *spawn_particle;
|
ParticleParameters *spawn_particle;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
|
|
@ -564,6 +564,7 @@ protected:
|
||||||
void updatePauseState();
|
void updatePauseState();
|
||||||
void step(f32 dtime);
|
void step(f32 dtime);
|
||||||
void processClientEvents(CameraOrientation *cam);
|
void processClientEvents(CameraOrientation *cam);
|
||||||
|
void updateCameraMode(); // call after changing it
|
||||||
void updateCameraOffset();
|
void updateCameraOffset();
|
||||||
void updateCamera(f32 dtime);
|
void updateCamera(f32 dtime);
|
||||||
void updateSound(f32 dtime);
|
void updateSound(f32 dtime);
|
||||||
|
@ -665,6 +666,7 @@ private:
|
||||||
void handleClientEvent_OverrideDayNigthRatio(ClientEvent *event,
|
void handleClientEvent_OverrideDayNigthRatio(ClientEvent *event,
|
||||||
CameraOrientation *cam);
|
CameraOrientation *cam);
|
||||||
void handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *cam);
|
void handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *cam);
|
||||||
|
void handleClientEvent_UpdateCamera(ClientEvent *event, CameraOrientation *cam);
|
||||||
|
|
||||||
void updateChat(f32 dtime);
|
void updateChat(f32 dtime);
|
||||||
|
|
||||||
|
@ -1921,6 +1923,9 @@ void Game::processKeyInput()
|
||||||
toggleFog();
|
toggleFog();
|
||||||
} else if (wasKeyDown(KeyType::TOGGLE_UPDATE_CAMERA)) {
|
} else if (wasKeyDown(KeyType::TOGGLE_UPDATE_CAMERA)) {
|
||||||
toggleUpdateCamera();
|
toggleUpdateCamera();
|
||||||
|
} else if (wasKeyPressed(KeyType::CAMERA_MODE)) {
|
||||||
|
camera->toggleCameraMode();
|
||||||
|
updateCameraMode();
|
||||||
} else if (wasKeyPressed(KeyType::TOGGLE_DEBUG)) {
|
} else if (wasKeyPressed(KeyType::TOGGLE_DEBUG)) {
|
||||||
toggleDebug();
|
toggleDebug();
|
||||||
} else if (wasKeyPressed(KeyType::TOGGLE_PROFILER)) {
|
} else if (wasKeyPressed(KeyType::TOGGLE_PROFILER)) {
|
||||||
|
@ -2575,6 +2580,7 @@ const ClientEventHandler Game::clientEventHandler[CLIENTEVENT_MAX] = {
|
||||||
{&Game::handleClientEvent_SetStars},
|
{&Game::handleClientEvent_SetStars},
|
||||||
{&Game::handleClientEvent_OverrideDayNigthRatio},
|
{&Game::handleClientEvent_OverrideDayNigthRatio},
|
||||||
{&Game::handleClientEvent_CloudParams},
|
{&Game::handleClientEvent_CloudParams},
|
||||||
|
{&Game::handleClientEvent_UpdateCamera},
|
||||||
};
|
};
|
||||||
|
|
||||||
void Game::handleClientEvent_None(ClientEvent *event, CameraOrientation *cam)
|
void Game::handleClientEvent_None(ClientEvent *event, CameraOrientation *cam)
|
||||||
|
@ -2879,6 +2885,13 @@ void Game::handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *
|
||||||
clouds->setSpeed(v2f(event->cloud_params.speed_x, event->cloud_params.speed_y));
|
clouds->setSpeed(v2f(event->cloud_params.speed_x, event->cloud_params.speed_y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Game::handleClientEvent_UpdateCamera(ClientEvent *event, CameraOrientation *cam)
|
||||||
|
{
|
||||||
|
// no parameters to update here, this just makes sure the camera is in the
|
||||||
|
// state it should be after something was changed.
|
||||||
|
updateCameraMode();
|
||||||
|
}
|
||||||
|
|
||||||
void Game::processClientEvents(CameraOrientation *cam)
|
void Game::processClientEvents(CameraOrientation *cam)
|
||||||
{
|
{
|
||||||
while (client->hasClientEvents()) {
|
while (client->hasClientEvents()) {
|
||||||
|
@ -2935,12 +2948,7 @@ void Game::updateCamera(f32 dtime)
|
||||||
ClientEnvironment &env = client->getEnv();
|
ClientEnvironment &env = client->getEnv();
|
||||||
LocalPlayer *player = env.getLocalPlayer();
|
LocalPlayer *player = env.getLocalPlayer();
|
||||||
|
|
||||||
/*
|
// For interaction purposes, get info about the held item
|
||||||
For interaction purposes, get info about the held item
|
|
||||||
- What item is it?
|
|
||||||
- Is it a usable item?
|
|
||||||
- Can it point to liquids?
|
|
||||||
*/
|
|
||||||
ItemStack playeritem;
|
ItemStack playeritem;
|
||||||
{
|
{
|
||||||
ItemStack selected, hand;
|
ItemStack selected, hand;
|
||||||
|
@ -2950,23 +2958,6 @@ void Game::updateCamera(f32 dtime)
|
||||||
ToolCapabilities playeritem_toolcap =
|
ToolCapabilities playeritem_toolcap =
|
||||||
playeritem.getToolCapabilities(itemdef_manager);
|
playeritem.getToolCapabilities(itemdef_manager);
|
||||||
|
|
||||||
if (wasKeyPressed(KeyType::CAMERA_MODE)) {
|
|
||||||
GenericCAO *playercao = player->getCAO();
|
|
||||||
|
|
||||||
// If playercao not loaded, don't change camera
|
|
||||||
if (!playercao)
|
|
||||||
return;
|
|
||||||
|
|
||||||
camera->toggleCameraMode();
|
|
||||||
|
|
||||||
if (g_touchcontrols)
|
|
||||||
g_touchcontrols->setUseCrosshair(!isTouchCrosshairDisabled());
|
|
||||||
|
|
||||||
// Make the player visible depending on camera mode.
|
|
||||||
playercao->updateMeshCulling();
|
|
||||||
playercao->setChildrenVisible(camera->getCameraMode() > CAMERA_MODE_FIRST);
|
|
||||||
}
|
|
||||||
|
|
||||||
float full_punch_interval = playeritem_toolcap.full_punch_interval;
|
float full_punch_interval = playeritem_toolcap.full_punch_interval;
|
||||||
float tool_reload_ratio = runData.time_from_last_punch / full_punch_interval;
|
float tool_reload_ratio = runData.time_from_last_punch / full_punch_interval;
|
||||||
|
|
||||||
|
@ -2981,6 +2972,25 @@ void Game::updateCamera(f32 dtime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Game::updateCameraMode()
|
||||||
|
{
|
||||||
|
LocalPlayer *player = client->getEnv().getLocalPlayer();
|
||||||
|
|
||||||
|
// Obey server choice
|
||||||
|
if (player->allowed_camera_mode != CAMERA_MODE_ANY)
|
||||||
|
camera->setCameraMode(player->allowed_camera_mode);
|
||||||
|
|
||||||
|
if (g_touchcontrols)
|
||||||
|
g_touchcontrols->setUseCrosshair(!isTouchCrosshairDisabled());
|
||||||
|
|
||||||
|
GenericCAO *playercao = player->getCAO();
|
||||||
|
if (playercao) {
|
||||||
|
// Make the player visible depending on camera mode.
|
||||||
|
playercao->updateMeshCulling();
|
||||||
|
playercao->setChildrenVisible(camera->getCameraMode() > CAMERA_MODE_FIRST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Game::updateCameraOffset()
|
void Game::updateCameraOffset()
|
||||||
{
|
{
|
||||||
ClientEnvironment &env = client->getEnv();
|
ClientEnvironment &env = client->getEnv();
|
||||||
|
@ -3057,6 +3067,9 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)
|
||||||
core::line3d<f32> shootline;
|
core::line3d<f32> shootline;
|
||||||
|
|
||||||
switch (camera->getCameraMode()) {
|
switch (camera->getCameraMode()) {
|
||||||
|
case CAMERA_MODE_ANY:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
case CAMERA_MODE_FIRST:
|
case CAMERA_MODE_FIRST:
|
||||||
// Shoot from camera position, with bobbing
|
// Shoot from camera position, with bobbing
|
||||||
shootline.start = camera->getPosition();
|
shootline.start = camera->getPosition();
|
||||||
|
|
|
@ -83,7 +83,7 @@ const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] =
|
||||||
{ "TOCLIENT_MOVEMENT", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_Movement }, // 0x45
|
{ "TOCLIENT_MOVEMENT", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_Movement }, // 0x45
|
||||||
{ "TOCLIENT_SPAWN_PARTICLE", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_SpawnParticle }, // 0x46
|
{ "TOCLIENT_SPAWN_PARTICLE", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_SpawnParticle }, // 0x46
|
||||||
{ "TOCLIENT_ADD_PARTICLESPAWNER", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_AddParticleSpawner }, // 0x47
|
{ "TOCLIENT_ADD_PARTICLESPAWNER", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_AddParticleSpawner }, // 0x47
|
||||||
null_command_handler,
|
{ "TOCLIENT_CAMERA", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_Camera }, // 0x48
|
||||||
{ "TOCLIENT_HUDADD", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudAdd }, // 0x49
|
{ "TOCLIENT_HUDADD", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudAdd }, // 0x49
|
||||||
{ "TOCLIENT_HUDRM", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudRemove }, // 0x4a
|
{ "TOCLIENT_HUDRM", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudRemove }, // 0x4a
|
||||||
{ "TOCLIENT_HUDCHANGE", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudChange }, // 0x4b
|
{ "TOCLIENT_HUDCHANGE", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudChange }, // 0x4b
|
||||||
|
|
|
@ -1530,7 +1530,19 @@ void Client::handleCommand_EyeOffset(NetworkPacket* pkt)
|
||||||
*pkt >> player->eye_offset_third_front;
|
*pkt >> player->eye_offset_third_front;
|
||||||
} catch (PacketError &e) {
|
} catch (PacketError &e) {
|
||||||
player->eye_offset_third_front = player->eye_offset_third;
|
player->eye_offset_third_front = player->eye_offset_third;
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::handleCommand_Camera(NetworkPacket* pkt)
|
||||||
|
{
|
||||||
|
LocalPlayer *player = m_env.getLocalPlayer();
|
||||||
|
assert(player);
|
||||||
|
|
||||||
|
u8 tmp;
|
||||||
|
*pkt >> tmp;
|
||||||
|
player->allowed_camera_mode = static_cast<CameraMode>(tmp);
|
||||||
|
|
||||||
|
m_client_event_queue.push(new ClientEvent(CE_UPDATE_CAMERA));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::handleCommand_UpdatePlayerList(NetworkPacket* pkt)
|
void Client::handleCommand_UpdatePlayerList(NetworkPacket* pkt)
|
||||||
|
|
|
@ -442,6 +442,11 @@ enum ToClientCommand : u16
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
TOCLIENT_CAMERA = 0x48,
|
||||||
|
/*
|
||||||
|
u8 allowed_camera_mode
|
||||||
|
*/
|
||||||
|
|
||||||
TOCLIENT_HUDADD = 0x49,
|
TOCLIENT_HUDADD = 0x49,
|
||||||
/*
|
/*
|
||||||
u32 id
|
u32 id
|
||||||
|
|
|
@ -183,7 +183,7 @@ const ClientCommandFactory clientCommandFactoryTable[TOCLIENT_NUM_MSG_TYPES] =
|
||||||
{ "TOCLIENT_MOVEMENT", 0, true }, // 0x45
|
{ "TOCLIENT_MOVEMENT", 0, true }, // 0x45
|
||||||
{ "TOCLIENT_SPAWN_PARTICLE", 0, true }, // 0x46
|
{ "TOCLIENT_SPAWN_PARTICLE", 0, true }, // 0x46
|
||||||
{ "TOCLIENT_ADD_PARTICLESPAWNER", 0, true }, // 0x47
|
{ "TOCLIENT_ADD_PARTICLESPAWNER", 0, true }, // 0x47
|
||||||
null_command_factory, // 0x48
|
{ "TOCLIENT_CAMERA", 0, true }, // 0x48
|
||||||
{ "TOCLIENT_HUDADD", 1, true }, // 0x49
|
{ "TOCLIENT_HUDADD", 1, true }, // 0x49
|
||||||
{ "TOCLIENT_HUDRM", 1, true }, // 0x4a
|
{ "TOCLIENT_HUDRM", 1, true }, // 0x4a
|
||||||
{ "TOCLIENT_HUDCHANGE", 1, true }, // 0x4b
|
{ "TOCLIENT_HUDCHANGE", 1, true }, // 0x4b
|
||||||
|
|
|
@ -20,12 +20,6 @@
|
||||||
|
|
||||||
namespace ParticleParamTypes
|
namespace ParticleParamTypes
|
||||||
{
|
{
|
||||||
template <bool cond, typename T>
|
|
||||||
using enableIf = typename std::enable_if<cond, T>::type;
|
|
||||||
// std::enable_if_t does not appear to be present in GCC????
|
|
||||||
// std::is_enum_v also missing. wtf. these are supposed to be
|
|
||||||
// present as of c++14
|
|
||||||
|
|
||||||
template<typename T> using BlendFunction = T(float,T,T);
|
template<typename T> using BlendFunction = T(float,T,T);
|
||||||
#define DECL_PARAM_SRZRS(type) \
|
#define DECL_PARAM_SRZRS(type) \
|
||||||
void serializeParameterValue (std::ostream& os, type v); \
|
void serializeParameterValue (std::ostream& os, type v); \
|
||||||
|
@ -57,12 +51,12 @@ namespace ParticleParamTypes
|
||||||
* that's hideous and unintuitive. instead, we supply the following functions to
|
* that's hideous and unintuitive. instead, we supply the following functions to
|
||||||
* transparently map enumeration types to their underlying values. */
|
* transparently map enumeration types to their underlying values. */
|
||||||
|
|
||||||
template <typename E, enableIf<std::is_enum<E>::value, bool> = true>
|
template <typename E, std::enable_if_t<std::is_enum_v<E>, bool> = true>
|
||||||
void serializeParameterValue(std::ostream& os, E k) {
|
void serializeParameterValue(std::ostream& os, E k) {
|
||||||
serializeParameterValue(os, (std::underlying_type_t<E>)k);
|
serializeParameterValue(os, (std::underlying_type_t<E>)k);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename E, enableIf<std::is_enum<E>::value, bool> = true>
|
template <typename E, std::enable_if_t<std::is_enum_v<E>, bool> = true>
|
||||||
void deSerializeParameterValue(std::istream& is, E& k) {
|
void deSerializeParameterValue(std::istream& is, E& k) {
|
||||||
std::underlying_type_t<E> v;
|
std::underlying_type_t<E> v;
|
||||||
deSerializeParameterValue(is, v);
|
deSerializeParameterValue(is, v);
|
||||||
|
|
|
@ -15,6 +15,13 @@
|
||||||
#include "porting.h" // strlcpy
|
#include "porting.h" // strlcpy
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
|
const struct EnumString es_CameraMode[] = {
|
||||||
|
{CAMERA_MODE_ANY, "any"},
|
||||||
|
{CAMERA_MODE_FIRST, "first"},
|
||||||
|
{CAMERA_MODE_THIRD, "third"},
|
||||||
|
{CAMERA_MODE_THIRD_FRONT, "third_front"},
|
||||||
|
{0, nullptr}
|
||||||
|
};
|
||||||
|
|
||||||
bool is_valid_player_name(std::string_view name)
|
bool is_valid_player_name(std::string_view name)
|
||||||
{
|
{
|
||||||
|
|
13
src/player.h
13
src/player.h
|
@ -126,6 +126,17 @@ struct PlayerPhysicsOverride
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @note numeric values are part of network protocol
|
||||||
|
enum CameraMode {
|
||||||
|
// not a mode. indicates that any may be used.
|
||||||
|
CAMERA_MODE_ANY = 0,
|
||||||
|
CAMERA_MODE_FIRST,
|
||||||
|
CAMERA_MODE_THIRD,
|
||||||
|
CAMERA_MODE_THIRD_FRONT
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const struct EnumString es_CameraMode[];
|
||||||
|
|
||||||
class Map;
|
class Map;
|
||||||
struct HudElement;
|
struct HudElement;
|
||||||
class Environment;
|
class Environment;
|
||||||
|
@ -160,6 +171,8 @@ public:
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CameraMode allowed_camera_mode = CAMERA_MODE_ANY;
|
||||||
|
|
||||||
v3f eye_offset_first;
|
v3f eye_offset_first;
|
||||||
v3f eye_offset_third;
|
v3f eye_offset_third;
|
||||||
v3f eye_offset_third_front;
|
v3f eye_offset_third_front;
|
||||||
|
|
|
@ -492,6 +492,39 @@ int ObjectRef::l_get_eye_offset(lua_State *L)
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ObjectRef::l_set_camera(lua_State *L)
|
||||||
|
{
|
||||||
|
NO_MAP_LOCK_REQUIRED;
|
||||||
|
ObjectRef *ref = checkObject<ObjectRef>(L, 1);
|
||||||
|
RemotePlayer *player = getplayer(ref);
|
||||||
|
if (player == nullptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
luaL_checktype(L, 2, LUA_TTABLE);
|
||||||
|
|
||||||
|
lua_getfield(L, -1, "mode");
|
||||||
|
if (lua_isstring(L, -1))
|
||||||
|
string_to_enum(es_CameraMode, player->allowed_camera_mode, lua_tostring(L, -1));
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
getServer(L)->SendCamera(player->getPeerId(), player);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ObjectRef::l_get_camera(lua_State *L)
|
||||||
|
{
|
||||||
|
NO_MAP_LOCK_REQUIRED;
|
||||||
|
ObjectRef *ref = checkObject<ObjectRef>(L, 1);
|
||||||
|
RemotePlayer *player = getplayer(ref);
|
||||||
|
if (player == nullptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
lua_newtable(L);
|
||||||
|
setstringfield(L, -1, "mode", enum_to_string(es_CameraMode, player->allowed_camera_mode));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// send_mapblock(self, pos)
|
// send_mapblock(self, pos)
|
||||||
int ObjectRef::l_send_mapblock(lua_State *L)
|
int ObjectRef::l_send_mapblock(lua_State *L)
|
||||||
{
|
{
|
||||||
|
@ -2900,6 +2933,8 @@ luaL_Reg ObjectRef::methods[] = {
|
||||||
luamethod(ObjectRef, respawn),
|
luamethod(ObjectRef, respawn),
|
||||||
luamethod(ObjectRef, set_flags),
|
luamethod(ObjectRef, set_flags),
|
||||||
luamethod(ObjectRef, get_flags),
|
luamethod(ObjectRef, get_flags),
|
||||||
|
luamethod(ObjectRef, set_camera),
|
||||||
|
luamethod(ObjectRef, get_camera),
|
||||||
|
|
||||||
{0,0}
|
{0,0}
|
||||||
};
|
};
|
||||||
|
|
|
@ -378,6 +378,12 @@ private:
|
||||||
// get_eye_offset(self)
|
// get_eye_offset(self)
|
||||||
static int l_get_eye_offset(lua_State *L);
|
static int l_get_eye_offset(lua_State *L);
|
||||||
|
|
||||||
|
// set_camera(self, {params})
|
||||||
|
static int l_set_camera(lua_State *L);
|
||||||
|
|
||||||
|
// get_camera(self)
|
||||||
|
static int l_get_camera(lua_State *L);
|
||||||
|
|
||||||
// set_nametag_attributes(self, attributes)
|
// set_nametag_attributes(self, attributes)
|
||||||
static int l_set_nametag_attributes(lua_State *L);
|
static int l_set_nametag_attributes(lua_State *L);
|
||||||
|
|
||||||
|
|
|
@ -1944,6 +1944,15 @@ void Server::SendSetLighting(session_t peer_id, const Lighting &lighting)
|
||||||
Send(&pkt);
|
Send(&pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Server::SendCamera(session_t peer_id, Player *player)
|
||||||
|
{
|
||||||
|
NetworkPacket pkt(TOCLIENT_CAMERA, 1, peer_id);
|
||||||
|
|
||||||
|
pkt << static_cast<u8>(player->allowed_camera_mode);
|
||||||
|
|
||||||
|
Send(&pkt);
|
||||||
|
}
|
||||||
|
|
||||||
void Server::SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed)
|
void Server::SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed)
|
||||||
{
|
{
|
||||||
NetworkPacket pkt(TOCLIENT_TIME_OF_DAY, 0, peer_id);
|
NetworkPacket pkt(TOCLIENT_TIME_OF_DAY, 0, peer_id);
|
||||||
|
|
|
@ -45,6 +45,7 @@ class BanManager;
|
||||||
class Inventory;
|
class Inventory;
|
||||||
class ModChannelMgr;
|
class ModChannelMgr;
|
||||||
class RemotePlayer;
|
class RemotePlayer;
|
||||||
|
class Player;
|
||||||
class PlayerSAO;
|
class PlayerSAO;
|
||||||
struct PlayerHPChangeReason;
|
struct PlayerHPChangeReason;
|
||||||
class IRollbackManager;
|
class IRollbackManager;
|
||||||
|
@ -409,6 +410,7 @@ public:
|
||||||
void SendMovePlayerRel(session_t peer_id, const v3f &added_pos);
|
void SendMovePlayerRel(session_t peer_id, const v3f &added_pos);
|
||||||
void SendPlayerSpeed(session_t peer_id, const v3f &added_vel);
|
void SendPlayerSpeed(session_t peer_id, const v3f &added_vel);
|
||||||
void SendPlayerFov(session_t peer_id);
|
void SendPlayerFov(session_t peer_id);
|
||||||
|
void SendCamera(session_t peer_id, Player *player);
|
||||||
|
|
||||||
void SendMinimapModes(session_t peer_id,
|
void SendMinimapModes(session_t peer_id,
|
||||||
std::vector<MinimapMode> &modes,
|
std::vector<MinimapMode> &modes,
|
||||||
|
@ -546,6 +548,7 @@ private:
|
||||||
void SendCloudParams(session_t peer_id, const CloudParams ¶ms);
|
void SendCloudParams(session_t peer_id, const CloudParams ¶ms);
|
||||||
void SendOverrideDayNightRatio(session_t peer_id, bool do_override, float ratio);
|
void SendOverrideDayNightRatio(session_t peer_id, bool do_override, float ratio);
|
||||||
void SendSetLighting(session_t peer_id, const Lighting &lighting);
|
void SendSetLighting(session_t peer_id, const Lighting &lighting);
|
||||||
|
|
||||||
void broadcastModChannelMessage(const std::string &channel,
|
void broadcastModChannelMessage(const std::string &channel,
|
||||||
const std::string &message, session_t from_peer);
|
const std::string &message, session_t from_peer);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
struct EnumString
|
struct EnumString
|
||||||
{
|
{
|
||||||
|
@ -14,4 +15,13 @@ struct EnumString
|
||||||
|
|
||||||
bool string_to_enum(const EnumString *spec, int &result, std::string_view str);
|
bool string_to_enum(const EnumString *spec, int &result, std::string_view str);
|
||||||
|
|
||||||
|
template <typename T, std::enable_if_t<std::is_enum_v<T>, bool> = true>
|
||||||
|
bool string_to_enum(const EnumString *spec, T &result, std::string_view str)
|
||||||
|
{
|
||||||
|
int result_int = result;
|
||||||
|
bool ret = string_to_enum(spec, result_int, str);
|
||||||
|
result = static_cast<T>(result_int);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
const char *enum_to_string(const EnumString *spec, int num);
|
const char *enum_to_string(const EnumString *spec, int num);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue