summaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
Diffstat (limited to 'src/client')
-rw-r--r--src/client/camera.cpp35
-rw-r--r--src/client/camera.h47
-rw-r--r--src/client/client.cpp16
-rw-r--r--src/client/client.h10
-rw-r--r--src/client/clientevent.h55
-rw-r--r--src/client/clientmap.cpp45
-rw-r--r--src/client/content_cao.cpp12
-rw-r--r--src/client/game.cpp261
-rw-r--r--src/client/guiscalingfilter.cpp2
-rw-r--r--src/client/hud.cpp2
-rw-r--r--src/client/inputhandler.cpp15
-rw-r--r--src/client/inputhandler.h2
-rw-r--r--src/client/joystick_controller.cpp6
-rw-r--r--src/client/keys.h2
-rw-r--r--src/client/mapblock_mesh.cpp6
-rw-r--r--src/client/minimap.cpp11
-rw-r--r--src/client/render/anaglyph.cpp2
-rw-r--r--src/client/render/interlaced.cpp4
-rw-r--r--src/client/renderingengine.cpp4
-rw-r--r--src/client/shader.h5
-rw-r--r--src/client/sky.cpp5
-rw-r--r--src/client/sound_openal.cpp4
-rw-r--r--src/client/tile.cpp11
-rw-r--r--src/client/wieldmesh.cpp33
24 files changed, 332 insertions, 263 deletions
diff --git a/src/client/camera.cpp b/src/client/camera.cpp
index 9a08254b4..5158d0dd1 100644
--- a/src/client/camera.cpp
+++ b/src/client/camera.cpp
@@ -79,6 +79,7 @@ Camera::Camera(MapDrawControl &draw_control, Client *client):
m_cache_fov = std::fmax(g_settings->getFloat("fov"), 45.0f);
m_arm_inertia = g_settings->getBool("arm_inertia");
m_nametags.clear();
+ m_show_nametag_backgrounds = g_settings->getBool("show_nametag_backgrounds");
}
Camera::~Camera()
@@ -663,7 +664,7 @@ void Camera::wield(const ItemStack &item)
void Camera::drawWieldedTool(irr::core::matrix4* translation)
{
// Clear Z buffer so that the wielded tool stays in front of world geometry
- m_wieldmgr->getVideoDriver()->clearZBuffer();
+ m_wieldmgr->getVideoDriver()->clearBuffers(video::ECBF_DEPTH);
// Draw the wielded node (in a separate scene manager)
scene::ICameraSceneNode* cam = m_wieldmgr->getActiveCamera();
@@ -696,18 +697,14 @@ void Camera::drawNametags()
v2u32 screensize = driver->getScreenSize();
for (const Nametag *nametag : m_nametags) {
- if (nametag->nametag_color.getAlpha() == 0) {
- // Enforce hiding nametag,
- // because if freetype is enabled, a grey
- // shadow can remain.
- continue;
- }
- v3f pos = nametag->parent_node->getAbsolutePosition() + nametag->nametag_pos * BS;
+ // Nametags are hidden in GenericCAO::updateNametag()
+
+ v3f pos = nametag->parent_node->getAbsolutePosition() + nametag->pos * BS;
f32 transformed_pos[4] = { pos.X, pos.Y, pos.Z, 1.0f };
trans.multiplyWith1x4Matrix(transformed_pos);
if (transformed_pos[3] > 0) {
std::wstring nametag_colorless =
- unescape_translate(utf8_to_wide(nametag->nametag_text));
+ unescape_translate(utf8_to_wide(nametag->text));
core::dimension2d<u32> textsize = font->getDimension(
nametag_colorless.c_str());
f32 zDiv = transformed_pos[3] == 0.0f ? 1.0f :
@@ -720,26 +717,22 @@ void Camera::drawNametags()
core::rect<s32> size(0, 0, textsize.Width, textsize.Height);
core::rect<s32> bg_size(-2, 0, textsize.Width+2, textsize.Height);
- video::SColor textColor = nametag->nametag_color;
-
- bool darkBackground = textColor.getLuminance() > 186;
- video::SColor backgroundColor = darkBackground
- ? video::SColor(50, 50, 50, 50)
- : video::SColor(50, 255, 255, 255);
- driver->draw2DRectangle(backgroundColor, bg_size + screen_pos);
+ auto bgcolor = nametag->getBgColor(m_show_nametag_backgrounds);
+ if (bgcolor.getAlpha() != 0)
+ driver->draw2DRectangle(bgcolor, bg_size + screen_pos);
font->draw(
- translate_string(utf8_to_wide(nametag->nametag_text)).c_str(),
- size + screen_pos, textColor);
+ translate_string(utf8_to_wide(nametag->text)).c_str(),
+ size + screen_pos, nametag->textcolor);
}
}
}
Nametag *Camera::addNametag(scene::ISceneNode *parent_node,
- const std::string &nametag_text, video::SColor nametag_color,
- const v3f &pos)
+ const std::string &text, video::SColor textcolor,
+ Optional<video::SColor> bgcolor, const v3f &pos)
{
- Nametag *nametag = new Nametag(parent_node, nametag_text, nametag_color, pos);
+ Nametag *nametag = new Nametag(parent_node, text, textcolor, bgcolor, pos);
m_nametags.push_back(nametag);
return nametag;
}
diff --git a/src/client/camera.h b/src/client/camera.h
index 16a1961be..6fd8d9aa7 100644
--- a/src/client/camera.h
+++ b/src/client/camera.h
@@ -25,27 +25,47 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <ICameraSceneNode.h>
#include <ISceneNode.h>
#include <list>
+#include "util/Optional.h"
class LocalPlayer;
struct MapDrawControl;
class Client;
class WieldMeshSceneNode;
-struct Nametag {
+struct Nametag
+{
+ scene::ISceneNode *parent_node;
+ std::string text;
+ video::SColor textcolor;
+ Optional<video::SColor> bgcolor;
+ v3f pos;
+
Nametag(scene::ISceneNode *a_parent_node,
- const std::string &a_nametag_text,
- const video::SColor &a_nametag_color,
- const v3f &a_nametag_pos):
+ const std::string &text,
+ const video::SColor &textcolor,
+ const Optional<video::SColor> &bgcolor,
+ const v3f &pos):
parent_node(a_parent_node),
- nametag_text(a_nametag_text),
- nametag_color(a_nametag_color),
- nametag_pos(a_nametag_pos)
+ text(text),
+ textcolor(textcolor),
+ bgcolor(bgcolor),
+ pos(pos)
{
}
- scene::ISceneNode *parent_node;
- std::string nametag_text;
- video::SColor nametag_color;
- v3f nametag_pos;
+
+ video::SColor getBgColor(bool use_fallback) const
+ {
+ if (bgcolor)
+ return bgcolor.value();
+ else if (!use_fallback)
+ return video::SColor(0, 0, 0, 0);
+ else if (textcolor.getLuminance() > 186)
+ // Dark background for light text
+ return video::SColor(50, 50, 50, 50);
+ else
+ // Light background for dark text
+ return video::SColor(50, 255, 255, 255);
+ }
};
enum CameraMode {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT};
@@ -164,8 +184,8 @@ public:
}
Nametag *addNametag(scene::ISceneNode *parent_node,
- const std::string &nametag_text, video::SColor nametag_color,
- const v3f &pos);
+ const std::string &text, video::SColor textcolor,
+ Optional<video::SColor> bgcolor, const v3f &pos);
void removeNametag(Nametag *nametag);
@@ -245,4 +265,5 @@ private:
bool m_arm_inertia;
std::list<Nametag *> m_nametags;
+ bool m_show_nametag_backgrounds;
};
diff --git a/src/client/client.cpp b/src/client/client.cpp
index ef4a3cdfc..0486bc0a9 100644
--- a/src/client/client.cpp
+++ b/src/client/client.cpp
@@ -663,12 +663,15 @@ bool Client::loadMedia(const std::string &data, const std::string &filename,
io::IFileSystem *irrfs = RenderingEngine::get_filesystem();
video::IVideoDriver *vdrv = RenderingEngine::get_video_driver();
+#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR > 8
+ io::IReadFile *rfile = irrfs->createMemoryReadFile(
+ data.c_str(), data.size(), "_tempreadfile");
+#else
// Silly irrlicht's const-incorrectness
Buffer<char> data_rw(data.c_str(), data.size());
-
- // Create an irrlicht memory file
io::IReadFile *rfile = irrfs->createMemoryReadFile(
*data_rw, data_rw.getSize(), "_tempreadfile");
+#endif
FATAL_ERROR_IF(!rfile, "Could not create irrlicht memory file.");
@@ -1914,13 +1917,20 @@ scene::IAnimatedMesh* Client::getMesh(const std::string &filename, bool cache)
// Create the mesh, remove it from cache and return it
// This allows unique vertex colors and other properties for each instance
+#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR > 8
+ io::IReadFile *rfile = RenderingEngine::get_filesystem()->createMemoryReadFile(
+ data.c_str(), data.size(), filename.c_str());
+#else
Buffer<char> data_rw(data.c_str(), data.size()); // Const-incorrect Irrlicht
- io::IReadFile *rfile = RenderingEngine::get_filesystem()->createMemoryReadFile(
+ io::IReadFile *rfile = RenderingEngine::get_filesystem()->createMemoryReadFile(
*data_rw, data_rw.getSize(), filename.c_str());
+#endif
FATAL_ERROR_IF(!rfile, "Could not create/open RAM file");
scene::IAnimatedMesh *mesh = RenderingEngine::get_scene_manager()->getMesh(rfile);
rfile->drop();
+ if (!mesh)
+ return nullptr;
mesh->grab();
if (!cache)
RenderingEngine::get_mesh_cache()->removeMesh(mesh);
diff --git a/src/client/client.h b/src/client/client.h
index 25a1b97ba..da7f8e8a1 100644
--- a/src/client/client.h
+++ b/src/client/client.h
@@ -412,12 +412,7 @@ public:
inline bool checkCSMRestrictionFlag(CSMRestrictionFlags flag) const
{
- return m_csm_restriction_flags & flag;
- }
-
- inline std::unordered_map<u32, u32> &getHUDTranslationMap()
- {
- return m_hud_server_to_client;
+ return m_csm_restriction_flags & 0;
}
bool joinModChannel(const std::string &channel) override;
@@ -556,9 +551,6 @@ private:
// Relation of client id to object id
std::unordered_map<int, u16> m_sounds_to_objects;
- // Map server hud ids to client hud ids
- std::unordered_map<u32, u32> m_hud_server_to_client;
-
// Privileges
std::unordered_set<std::string> m_privileges;
diff --git a/src/client/clientevent.h b/src/client/clientevent.h
index 9bd31efce..2215aecbd 100644
--- a/src/client/clientevent.h
+++ b/src/client/clientevent.h
@@ -52,6 +52,31 @@ enum ClientEventType : u8
CLIENTEVENT_MAX,
};
+struct ClientEventHudAdd
+{
+ u32 server_id;
+ u8 type;
+ v2f pos, scale;
+ std::string name;
+ std::string text, text2;
+ u32 number, item, dir;
+ v2f align, offset;
+ v3f world_pos;
+ v2s32 size;
+ s16 z_index;
+};
+
+struct ClientEventHudChange
+{
+ u32 id;
+ HudElementStat stat;
+ v2f v2fdata;
+ std::string sdata;
+ u32 data;
+ v3f v3fdata;
+ v2s32 v2s32data;
+};
+
struct ClientEvent
{
ClientEventType type;
@@ -93,38 +118,12 @@ struct ClientEvent
{
u32 id;
} delete_particlespawner;
- struct
- {
- u32 server_id;
- u8 type;
- v2f *pos;
- std::string *name;
- v2f *scale;
- std::string *text;
- u32 number;
- u32 item;
- u32 dir;
- v2f *align;
- v2f *offset;
- v3f *world_pos;
- v2s32 *size;
- s16 z_index;
- std::string *text2;
- } hudadd;
+ ClientEventHudAdd *hudadd;
struct
{
u32 id;
} hudrm;
- struct
- {
- u32 id;
- HudElementStat stat;
- v2f *v2fdata;
- std::string *sdata;
- u32 data;
- v3f *v3fdata;
- v2s32 *v2s32data;
- } hudchange;
+ ClientEventHudChange *hudchange;
SkyboxParams *set_sky;
struct
{
diff --git a/src/client/clientmap.cpp b/src/client/clientmap.cpp
index b9e0cc2ce..be8343009 100644
--- a/src/client/clientmap.cpp
+++ b/src/client/clientmap.cpp
@@ -165,6 +165,9 @@ void ClientMap::updateDrawList()
v3s16 p_blocks_max;
getBlocksInViewRange(cam_pos_nodes, &p_blocks_min, &p_blocks_max);
+ // Read the vision range, unless unlimited range is enabled.
+ float range = m_control.range_all ? 1e7 : m_control.wanted_range;
+
// Number of blocks currently loaded by the client
u32 blocks_loaded = 0;
// Number of blocks with mesh in rendering range
@@ -182,6 +185,7 @@ void ClientMap::updateDrawList()
occlusion_culling_enabled = false;
}
+
// Uncomment to debug occluded blocks in the wireframe mode
// TODO: Include this as a flag for an extended debugging setting
//if (occlusion_culling_enabled && m_control.show_wireframe)
@@ -218,32 +222,34 @@ void ClientMap::updateDrawList()
continue;
}
- float range = 100000 * BS;
- if (!m_control.range_all)
- range = m_control.wanted_range * BS;
+ v3s16 block_coord = block->getPos();
+ v3s16 block_position = block->getPosRelative() + MAP_BLOCKSIZE / 2;
- float d = 0.0;
- if (!isBlockInSight(block->getPos(), camera_position,
- camera_direction, camera_fov, range, &d))
- continue;
+ // First, perform a simple distance check, with a padding of one extra block.
+ if (!m_control.range_all &&
+ block_position.getDistanceFrom(cam_pos_nodes) > range + MAP_BLOCKSIZE)
+ continue; // Out of range, skip.
+ // Keep the block alive as long as it is in range.
+ block->resetUsageTimer();
blocks_in_range_with_mesh++;
- /*
- Occlusion culling
- */
+ // Frustum culling
+ float d = 0.0;
+ if (!isBlockInSight(block_coord, camera_position,
+ camera_direction, camera_fov, range * BS, &d))
+ continue;
+
+ // Occlusion culling
if ((!m_control.range_all && d > m_control.wanted_range * BS) ||
(occlusion_culling_enabled && isBlockOccluded(block, cam_pos_nodes))) {
blocks_occlusion_culled++;
continue;
}
- // This block is in range. Reset usage timer.
- block->resetUsageTimer();
-
// Add to set
block->refGrab();
- m_drawlist[block->getPos()] = block;
+ m_drawlist[block_coord] = block;
sector_blocks_drawn++;
} // foreach sectorblocks
@@ -282,8 +288,6 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
const u32 daynight_ratio = m_client->getEnv().getDayNightRatio();
const v3f camera_position = m_camera_position;
- const v3f camera_direction = m_camera_direction;
- const f32 camera_fov = m_camera_fov;
/*
Get all blocks and draw all visible ones
@@ -310,11 +314,10 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
if (!block->mesh)
continue;
- float d = 0.0;
- if (!isBlockInSight(block->getPos(), camera_position,
- camera_direction, camera_fov, 100000 * BS, &d))
- continue;
-
+ v3f block_pos_r = intToFloat(block->getPosRelative() + MAP_BLOCKSIZE / 2, BS);
+ float d = camera_position.getDistanceFrom(block_pos_r);
+ d = MYMAX(0,d - BLOCK_MAX_RADIUS);
+
// Mesh animation
if (pass == scene::ESNRP_SOLID) {
//MutexAutoLock lock(block->mesh_mutex);
diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp
index c65977b44..97ae9afc4 100644
--- a/src/client/content_cao.cpp
+++ b/src/client/content_cao.cpp
@@ -934,7 +934,7 @@ void GenericCAO::updateNametag()
if (m_is_local_player) // No nametag for local player
return;
- if (m_prop.nametag.empty()) {
+ if (m_prop.nametag.empty() || m_prop.nametag_color.getAlpha() == 0) {
// Delete nametag
if (m_nametag) {
m_client->getCamera()->removeNametag(m_nametag);
@@ -952,12 +952,14 @@ void GenericCAO::updateNametag()
if (!m_nametag) {
// Add nametag
m_nametag = m_client->getCamera()->addNametag(node,
- m_prop.nametag, m_prop.nametag_color, pos);
+ m_prop.nametag, m_prop.nametag_color,
+ m_prop.nametag_bgcolor, pos);
} else {
// Update nametag
- m_nametag->nametag_text = m_prop.nametag;
- m_nametag->nametag_color = m_prop.nametag_color;
- m_nametag->nametag_pos = pos;
+ m_nametag->text = m_prop.nametag;
+ m_nametag->textcolor = m_prop.nametag_color;
+ m_nametag->bgcolor = m_prop.nametag_bgcolor;
+ m_nametag->pos = pos;
}
}
diff --git a/src/client/game.cpp b/src/client/game.cpp
index 3c58fb46f..31c782c51 100644
--- a/src/client/game.cpp
+++ b/src/client/game.cpp
@@ -68,6 +68,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/pointedthing.h"
#include "util/quicktune_shortcutter.h"
#include "irrlicht_changes/static_text.h"
+#include "irr_ptr.h"
#include "version.h"
#include "script/scripting_client.h"
#include "hud.h"
@@ -425,6 +426,7 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter
CachedPixelShaderSetting<float, 3> m_camera_offset_pixel;
CachedPixelShaderSetting<float, 3> m_camera_offset_vertex;
CachedPixelShaderSetting<SamplerLayer_t> m_base_texture;
+ CachedPixelShaderSetting<SamplerLayer_t> m_normal_texture;
Client *m_client;
public:
@@ -458,6 +460,7 @@ public:
m_camera_offset_pixel("cameraOffset"),
m_camera_offset_vertex("cameraOffset"),
m_base_texture("baseTexture"),
+ m_normal_texture("normalTexture"),
m_client(client)
{
g_settings->registerChangedCallback("enable_fog", settingsCallback, this);
@@ -545,8 +548,9 @@ public:
m_camera_offset_pixel.set(camera_offset_array, services);
m_camera_offset_vertex.set(camera_offset_array, services);
- SamplerLayer_t base_tex = 0;
+ SamplerLayer_t base_tex = 0, normal_tex = 1;
m_base_texture.set(&base_tex, services);
+ m_normal_texture.set(&normal_tex, services);
}
};
@@ -647,6 +651,8 @@ struct ClientEventHandler
THE GAME
****************************************************************************/
+using PausedNodesList = std::vector<std::pair<irr_ptr<scene::IAnimatedMeshSceneNode>, float>>;
+
/* This is not intended to be a public class. If a public class becomes
* desirable then it may be better to create another 'wrapper' class that
* hides most of the stuff in this class (nothing in this class is required
@@ -796,6 +802,9 @@ private:
void showDeathFormspec();
void showPauseMenu();
+ void pauseAnimation();
+ void resumeAnimation();
+
// ClientEvent handlers
void handleClientEvent_None(ClientEvent *event, CameraOrientation *cam);
void handleClientEvent_PlayerDamage(ClientEvent *event, CameraOrientation *cam);
@@ -823,6 +832,8 @@ private:
const NodeMetadata *meta);
static const ClientEventHandler clientEventHandler[CLIENTEVENT_MAX];
+ f32 getSensitivityScaleFactor() const;
+
InputHandler *input = nullptr;
Client *client = nullptr;
@@ -856,6 +867,9 @@ private:
Hud *hud = nullptr;
Minimap *mapper = nullptr;
+ // Map server hud ids to client hud ids
+ std::unordered_map<u32, u32> m_hud_server_to_client;
+
GameRunData runData;
Flags m_flags;
@@ -870,6 +884,7 @@ private:
std::string *error_message;
bool *reconnect_requested;
scene::ISceneNode *skybox;
+ PausedNodesList paused_animated_nodes;
bool simple_singleplayer_mode;
/* End 'cache' */
@@ -2331,7 +2346,6 @@ void Game::checkZoomEnabled()
m_game_ui->showTranslatedStatusText("Zoom currently disabled by game or mod");
}
-
void Game::updateCameraDirection(CameraOrientation *cam, float dtime)
{
if ((device->isWindowActive() && device->isWindowFocused()
@@ -2367,6 +2381,18 @@ void Game::updateCameraDirection(CameraOrientation *cam, float dtime)
}
}
+// Get the factor to multiply with sensitivity to get the same mouse/joystick
+// responsiveness independently of FOV.
+f32 Game::getSensitivityScaleFactor() const
+{
+ f32 fov_y = client->getCamera()->getFovY();
+
+ // Multiply by a constant such that it becomes 1.0 at 72 degree FOV and
+ // 16:9 aspect ratio to minimize disruption of existing sensitivity
+ // settings.
+ return tan(fov_y / 2.0f) * 1.3763818698f;
+}
+
void Game::updateCameraOrientation(CameraOrientation *cam, float dtime)
{
#ifdef HAVE_TOUCHSCREENGUI
@@ -2382,8 +2408,9 @@ void Game::updateCameraOrientation(CameraOrientation *cam, float dtime)
dist.Y = -dist.Y;
}
- cam->camera_yaw -= dist.X * m_cache_mouse_sensitivity;
- cam->camera_pitch += dist.Y * m_cache_mouse_sensitivity;
+ f32 sens_scale = getSensitivityScaleFactor();
+ cam->camera_yaw -= dist.X * m_cache_mouse_sensitivity * sens_scale;
+ cam->camera_pitch += dist.Y * m_cache_mouse_sensitivity * sens_scale;
if (dist.X != 0 || dist.Y != 0)
input->setMousePos(center.X, center.Y);
@@ -2392,7 +2419,8 @@ void Game::updateCameraOrientation(CameraOrientation *cam, float dtime)
#endif
if (m_cache_enable_joysticks) {
- f32 c = m_cache_joystick_frustum_sensitivity * (1.f / 32767.f) * dtime;
+ f32 sens_scale = getSensitivityScaleFactor();
+ f32 c = m_cache_joystick_frustum_sensitivity * (1.f / 32767.f) * dtime * sens_scale;
cam->camera_yaw -= input->joystick.getAxisWithoutDead(JA_FRUSTUM_HORIZONTAL) * c;
cam->camera_pitch += input->joystick.getAxisWithoutDead(JA_FRUSTUM_VERTICAL) * c;
}
@@ -2415,7 +2443,7 @@ void Game::updatePlayerControl(const CameraOrientation &cam)
input->isKeyDown(KeyType::LEFT),
input->isKeyDown(KeyType::RIGHT),
isKeyDown(KeyType::JUMP),
- isKeyDown(KeyType::SPECIAL1),
+ isKeyDown(KeyType::AUX1),
isKeyDown(KeyType::SNEAK),
isKeyDown(KeyType::ZOOM),
isKeyDown(KeyType::DIG),
@@ -2432,7 +2460,7 @@ void Game::updatePlayerControl(const CameraOrientation &cam)
( (u32)(isKeyDown(KeyType::LEFT) & 0x1) << 2) |
( (u32)(isKeyDown(KeyType::RIGHT) & 0x1) << 3) |
( (u32)(isKeyDown(KeyType::JUMP) & 0x1) << 4) |
- ( (u32)(isKeyDown(KeyType::SPECIAL1) & 0x1) << 5) |
+ ( (u32)(isKeyDown(KeyType::AUX1) & 0x1) << 5) |
( (u32)(isKeyDown(KeyType::SNEAK) & 0x1) << 6) |
( (u32)(isKeyDown(KeyType::DIG) & 0x1) << 7) |
( (u32)(isKeyDown(KeyType::PLACE) & 0x1) << 8) |
@@ -2481,6 +2509,9 @@ inline void Game::step(f32 *dtime)
if (can_be_and_is_paused) { // This is for a singleplayer server
*dtime = 0; // No time passes
} else {
+ if (simple_singleplayer_mode && !paused_animated_nodes.empty())
+ resumeAnimation();
+
if (server)
server->step(*dtime);
@@ -2488,6 +2519,33 @@ inline void Game::step(f32 *dtime)
}
}
+static void pauseNodeAnimation(PausedNodesList &paused, scene::ISceneNode *node) {
+ if (!node)
+ return;
+ for (auto &&child: node->getChildren())
+ pauseNodeAnimation(paused, child);
+ if (node->getType() != scene::ESNT_ANIMATED_MESH)
+ return;
+ auto animated_node = static_cast<scene::IAnimatedMeshSceneNode *>(node);
+ float speed = animated_node->getAnimationSpeed();
+ if (!speed)
+ return;
+ paused.push_back({grab(animated_node), speed});
+ animated_node->setAnimationSpeed(0.0f);
+}
+
+void Game::pauseAnimation()
+{
+ pauseNodeAnimation(paused_animated_nodes, smgr->getRootSceneNode());
+}
+
+void Game::resumeAnimation()
+{
+ for (auto &&pair: paused_animated_nodes)
+ pair.first->setAnimationSpeed(pair.second);
+ paused_animated_nodes.clear();
+}
+
const ClientEventHandler Game::clientEventHandler[CLIENTEVENT_MAX] = {
{&Game::handleClientEvent_None},
{&Game::handleClientEvent_PlayerDamage},
@@ -2602,132 +2660,100 @@ void Game::handleClientEvent_HandleParticleEvent(ClientEvent *event,
void Game::handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam)
{
LocalPlayer *player = client->getEnv().getLocalPlayer();
- auto &hud_server_to_client = client->getHUDTranslationMap();
- u32 server_id = event->hudadd.server_id;
+ u32 server_id = event->hudadd->server_id;
// ignore if we already have a HUD with that ID
- auto i = hud_server_to_client.find(server_id);
- if (i != hud_server_to_client.end()) {
- delete event->hudadd.pos;
- delete event->hudadd.name;
- delete event->hudadd.scale;
- delete event->hudadd.text;
- delete event->hudadd.align;
- delete event->hudadd.offset;
- delete event->hudadd.world_pos;
- delete event->hudadd.size;
- delete event->hudadd.text2;
+ auto i = m_hud_server_to_client.find(server_id);
+ if (i != m_hud_server_to_client.end()) {
+ delete event->hudadd;
return;
}
HudElement *e = new HudElement;
- e->type = (HudElementType)event->hudadd.type;
- e->pos = *event->hudadd.pos;
- e->name = *event->hudadd.name;
- e->scale = *event->hudadd.scale;
- e->text = *event->hudadd.text;
- e->number = event->hudadd.number;
- e->item = event->hudadd.item;
- e->dir = event->hudadd.dir;
- e->align = *event->hudadd.align;
- e->offset = *event->hudadd.offset;
- e->world_pos = *event->hudadd.world_pos;
- e->size = *event->hudadd.size;
- e->z_index = event->hudadd.z_index;
- e->text2 = *event->hudadd.text2;
- hud_server_to_client[server_id] = player->addHud(e);
-
- delete event->hudadd.pos;
- delete event->hudadd.name;
- delete event->hudadd.scale;
- delete event->hudadd.text;
- delete event->hudadd.align;
- delete event->hudadd.offset;
- delete event->hudadd.world_pos;
- delete event->hudadd.size;
- delete event->hudadd.text2;
+ e->type = static_cast<HudElementType>(event->hudadd->type);
+ e->pos = event->hudadd->pos;
+ e->name = event->hudadd->name;
+ e->scale = event->hudadd->scale;
+ e->text = event->hudadd->text;
+ e->number = event->hudadd->number;
+ e->item = event->hudadd->item;
+ e->dir = event->hudadd->dir;
+ e->align = event->hudadd->align;
+ e->offset = event->hudadd->offset;
+ e->world_pos = event->hudadd->world_pos;
+ e->size = event->hudadd->size;
+ e->z_index = event->hudadd->z_index;
+ e->text2 = event->hudadd->text2;
+ m_hud_server_to_client[server_id] = player->addHud(e);
+
+ delete event->hudadd;
}
void Game::handleClientEvent_HudRemove(ClientEvent *event, CameraOrientation *cam)
{
LocalPlayer *player = client->getEnv().getLocalPlayer();
- HudElement *e = player->removeHud(event->hudrm.id);
- delete e;
+
+ auto i = m_hud_server_to_client.find(event->hudrm.id);
+ if (i != m_hud_server_to_client.end()) {
+ HudElement *e = player->removeHud(i->second);
+ delete e;
+ m_hud_server_to_client.erase(i);
+ }
+
}
void Game::handleClientEvent_HudChange(ClientEvent *event, CameraOrientation *cam)
{
LocalPlayer *player = client->getEnv().getLocalPlayer();
- u32 id = event->hudchange.id;
- HudElement *e = player->getHud(id);
+ HudElement *e = nullptr;
- if (e == NULL) {
- delete event->hudchange.v3fdata;
- delete event->hudchange.v2fdata;
- delete event->hudchange.sdata;
- delete event->hudchange.v2s32data;
+ auto i = m_hud_server_to_client.find(event->hudchange->id);
+ if (i != m_hud_server_to_client.end()) {
+ e = player->getHud(i->second);
+ }
+
+ if (e == nullptr) {
+ delete event->hudchange;
return;
}
- switch (event->hudchange.stat) {
- case HUD_STAT_POS:
- e->pos = *event->hudchange.v2fdata;
- break;
+#define CASE_SET(statval, prop, dataprop) \
+ case statval: \
+ e->prop = event->hudchange->dataprop; \
+ break
- case HUD_STAT_NAME:
- e->name = *event->hudchange.sdata;
- break;
+ switch (event->hudchange->stat) {
+ CASE_SET(HUD_STAT_POS, pos, v2fdata);
- case HUD_STAT_SCALE:
- e->scale = *event->hudchange.v2fdata;
- break;
+ CASE_SET(HUD_STAT_NAME, name, sdata);
- case HUD_STAT_TEXT:
- e->text = *event->hudchange.sdata;
- break;
+ CASE_SET(HUD_STAT_SCALE, scale, v2fdata);
- case HUD_STAT_NUMBER:
- e->number = event->hudchange.data;
- break;
+ CASE_SET(HUD_STAT_TEXT, text, sdata);
- case HUD_STAT_ITEM:
- e->item = event->hudchange.data;
- break;
+ CASE_SET(HUD_STAT_NUMBER, number, data);
- case HUD_STAT_DIR:
- e->dir = event->hudchange.data;
- break;
+ CASE_SET(HUD_STAT_ITEM, item, data);
- case HUD_STAT_ALIGN:
- e->align = *event->hudchange.v2fdata;
- break;
+ CASE_SET(HUD_STAT_DIR, dir, data);
- case HUD_STAT_OFFSET:
- e->offset = *event->hudchange.v2fdata;
- break;
+ CASE_SET(HUD_STAT_ALIGN, align, v2fdata);
- case HUD_STAT_WORLD_POS:
- e->world_pos = *event->hudchange.v3fdata;
- break;
+ CASE_SET(HUD_STAT_OFFSET, offset, v2fdata);
- case HUD_STAT_SIZE:
- e->size = *event->hudchange.v2s32data;
- break;
+ CASE_SET(HUD_STAT_WORLD_POS, world_pos, v3fdata);
- case HUD_STAT_Z_INDEX:
- e->z_index = event->hudchange.data;
- break;
+ CASE_SET(HUD_STAT_SIZE, size, v2s32data);
- case HUD_STAT_TEXT2:
- e->text2 = *event->hudchange.sdata;
- break;
+ CASE_SET(HUD_STAT_Z_INDEX, z_index, data);
+
+ CASE_SET(HUD_STAT_TEXT2, text2, sdata);
}
- delete event->hudchange.v3fdata;
- delete event->hudchange.v2fdata;
- delete event->hudchange.sdata;
- delete event->hudchange.v2s32data;
+#undef CASE_SET
+
+ delete event->hudchange;
}
void Game::handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam)
@@ -3279,7 +3305,8 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
const ItemStack &selected_item, const v3s16 &nodepos, const v3s16 &neighbourpos,
const PointedThing &pointed, const NodeMetadata *meta)
{
- std::string prediction = selected_def.node_placement_prediction;
+ const auto &prediction = selected_def.node_placement_prediction;
+
const NodeDefManager *nodedef = client->ndef();
ClientMap &map = client->getEnv().getClientMap();
MapNode node;
@@ -3349,8 +3376,7 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
if (!found) {
errorstream << "Node placement prediction failed for "
- << selected_def.name << " (places "
- << prediction
+ << selected_def.name << " (places " << prediction
<< ") - Name not known" << std::endl;
// Handle this as if prediction was empty
// Report to server
@@ -3361,9 +3387,14 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
const ContentFeatures &predicted_f = nodedef->get(id);
// Predict param2 for facedir and wallmounted nodes
+ // Compare core.item_place_node() for what the server does
u8 param2 = 0;
- if (predicted_f.param_type_2 == CPT2_WALLMOUNTED ||
+ const u8 place_param2 = selected_def.place_param2;
+
+ if (place_param2) {
+ param2 = place_param2;
+ } else if (predicted_f.param_type_2 == CPT2_WALLMOUNTED ||
predicted_f.param_type_2 == CPT2_COLORED_WALLMOUNTED) {
v3s16 dir = nodepos - neighbourpos;
@@ -3374,9 +3405,7 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
} else {
param2 = dir.Z < 0 ? 5 : 4;
}
- }
-
- if (predicted_f.param_type_2 == CPT2_FACEDIR ||
+ } else if (predicted_f.param_type_2 == CPT2_FACEDIR ||
predicted_f.param_type_2 == CPT2_COLORED_FACEDIR) {
v3s16 dir = nodepos - floatToInt(client->getEnv().getLocalPlayer()->getPosition(), BS);
@@ -3387,11 +3416,9 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
}
}
- assert(param2 <= 5);
-
- //Check attachment if node is in group attached_node
- if (((ItemGroupList) predicted_f.groups)["attached_node"] != 0) {
- static v3s16 wallmounted_dirs[8] = {
+ // Check attachment if node is in group attached_node
+ if (itemgroup_get(predicted_f.groups, "attached_node") != 0) {
+ const static v3s16 wallmounted_dirs[8] = {
v3s16(0, 1, 0),
v3s16(0, -1, 0),
v3s16(1, 0, 0),
@@ -3416,11 +3443,11 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
}
// Apply color
- if ((predicted_f.param_type_2 == CPT2_COLOR
+ if (!place_param2 && (predicted_f.param_type_2 == CPT2_COLOR
|| predicted_f.param_type_2 == CPT2_COLORED_FACEDIR
|| predicted_f.param_type_2 == CPT2_COLORED_WALLMOUNTED)) {
- const std::string &indexstr = selected_item.metadata.getString(
- "palette_index", 0);
+ const auto &indexstr = selected_item.metadata.
+ getString("palette_index", 0);
if (!indexstr.empty()) {
s32 index = mystoi(indexstr);
if (predicted_f.param_type_2 == CPT2_COLOR) {
@@ -3460,11 +3487,10 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
soundmaker->m_player_rightpunch_sound = selected_def.sound_place_failed;
return false;
}
- } catch (InvalidPositionException &e) {
+ } catch (const InvalidPositionException &e) {
errorstream << "Node placement prediction failed for "
<< selected_def.name << " (places "
- << prediction
- << ") - Position not loaded" << std::endl;
+ << prediction << ") - Position not loaded" << std::endl;
soundmaker->m_player_rightpunch_sound = selected_def.sound_place_failed;
return false;
}
@@ -4218,6 +4244,9 @@ void Game::showPauseMenu()
fs_src, txt_dst, client->getFormspecPrepend(), sound);
formspec->setFocus("btn_continue");
formspec->doPause = true;
+
+ if (simple_singleplayer_mode)
+ pauseAnimation();
}
/****************************************************************************/
diff --git a/src/client/guiscalingfilter.cpp b/src/client/guiscalingfilter.cpp
index 406c096e6..8c565a52f 100644
--- a/src/client/guiscalingfilter.cpp
+++ b/src/client/guiscalingfilter.cpp
@@ -129,7 +129,7 @@ video::ITexture *guiScalingResizeCached(video::IVideoDriver *driver,
#endif
// Convert the scaled image back into a texture.
- scaled = driver->addTexture(scalename, destimg, NULL);
+ scaled = driver->addTexture(scalename, destimg);
destimg->drop();
g_txrCache[scalename] = scaled;
diff --git a/src/client/hud.cpp b/src/client/hud.cpp
index 46736b325..74c1828e3 100644
--- a/src/client/hud.cpp
+++ b/src/client/hud.cpp
@@ -950,7 +950,7 @@ void drawItemStack(
if (imesh && imesh->mesh) {
scene::IMesh *mesh = imesh->mesh;
- driver->clearZBuffer();
+ driver->clearBuffers(video::ECBF_DEPTH);
s32 delta = 0;
if (rotation_kind < IT_ROT_NONE) {
MeshTimeInfo &ti = rotation_time_infos[rotation_kind];
diff --git a/src/client/inputhandler.cpp b/src/client/inputhandler.cpp
index 608a405a8..b7e70fa6c 100644
--- a/src/client/inputhandler.cpp
+++ b/src/client/inputhandler.cpp
@@ -35,7 +35,7 @@ void KeyCache::populate()
key[KeyType::LEFT] = getKeySetting("keymap_left");
key[KeyType::RIGHT] = getKeySetting("keymap_right");
key[KeyType::JUMP] = getKeySetting("keymap_jump");
- key[KeyType::SPECIAL1] = getKeySetting("keymap_special1");
+ key[KeyType::AUX1] = getKeySetting("keymap_aux1");
key[KeyType::SNEAK] = getKeySetting("keymap_sneak");
key[KeyType::DIG] = getKeySetting("keymap_dig");
key[KeyType::PLACE] = getKeySetting("keymap_place");
@@ -113,17 +113,12 @@ bool MyEventReceiver::OnEvent(const SEvent &event)
if (event.EventType == irr::EET_KEY_INPUT_EVENT) {
const KeyPress &keyCode = event.KeyInput;
if (keysListenedFor[keyCode]) {
- // If the key is being held down then the OS may
- // send a continuous stream of keydown events.
- // In this case, we don't want to let this
- // stream reach the application as it will cause
- // certain actions to repeat constantly.
if (event.KeyInput.PressedDown) {
- if (!IsKeyDown(keyCode)) {
- keyWasDown.set(keyCode);
+ if (!IsKeyDown(keyCode))
keyWasPressed.set(keyCode);
- }
+
keyIsDown.set(keyCode);
+ keyWasDown.set(keyCode);
} else {
if (IsKeyDown(keyCode))
keyWasReleased.set(keyCode);
@@ -224,7 +219,7 @@ void RandomInputHandler::step(float dtime)
{
static RandomInputHandlerSimData rnd_data[] = {
{ "keymap_jump", 0.0f, 40 },
- { "keymap_special1", 0.0f, 40 },
+ { "keymap_aux1", 0.0f, 40 },
{ "keymap_forward", 0.0f, 40 },
{ "keymap_left", 0.0f, 40 },
{ "keymap_dig", 0.0f, 30 },
diff --git a/src/client/inputhandler.h b/src/client/inputhandler.h
index 7487bbdc7..1fb4cf0ec 100644
--- a/src/client/inputhandler.h
+++ b/src/client/inputhandler.h
@@ -201,7 +201,7 @@ private:
// The current state of keys
KeyList keyIsDown;
- // Whether a key was down
+ // Like keyIsDown but only reset when that key is read
KeyList keyWasDown;
// Whether a key has just been pressed
diff --git a/src/client/joystick_controller.cpp b/src/client/joystick_controller.cpp
index f61ae4ae6..919db5315 100644
--- a/src/client/joystick_controller.cpp
+++ b/src/client/joystick_controller.cpp
@@ -79,7 +79,7 @@ JoystickLayout create_default_layout()
// Accessible without any modifier pressed
JLO_B_PB(KeyType::JUMP, bm | 1 << 0, 1 << 0);
- JLO_B_PB(KeyType::SPECIAL1, bm | 1 << 1, 1 << 1);
+ JLO_B_PB(KeyType::AUX1, bm | 1 << 1, 1 << 1);
// Accessible with start button not pressed, but four pressed
// TODO find usage for button 0
@@ -126,11 +126,11 @@ JoystickLayout create_xbox_layout()
// 4 Buttons
JLO_B_PB(KeyType::JUMP, 1 << 0, 1 << 0); // A/green
JLO_B_PB(KeyType::ESC, 1 << 1, 1 << 1); // B/red
- JLO_B_PB(KeyType::SPECIAL1, 1 << 2, 1 << 2); // X/blue
+ JLO_B_PB(KeyType::AUX1, 1 << 2, 1 << 2); // X/blue
JLO_B_PB(KeyType::INVENTORY, 1 << 3, 1 << 3); // Y/yellow
// Analog Sticks
- JLO_B_PB(KeyType::SPECIAL1, 1 << 11, 1 << 11); // left
+ JLO_B_PB(KeyType::AUX1, 1 << 11, 1 << 11); // left
JLO_B_PB(KeyType::SNEAK, 1 << 12, 1 << 12); // right
// Triggers
diff --git a/src/client/keys.h b/src/client/keys.h
index 60a7a3c45..9f90da6b8 100644
--- a/src/client/keys.h
+++ b/src/client/keys.h
@@ -32,7 +32,7 @@ public:
LEFT,
RIGHT,
JUMP,
- SPECIAL1,
+ AUX1,
SNEAK,
AUTOFORWARD,
DIG,
diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp
index d78a86b2d..167e1e3ec 100644
--- a/src/client/mapblock_mesh.cpp
+++ b/src/client/mapblock_mesh.cpp
@@ -404,7 +404,7 @@ static void getNodeVertexDirs(const v3s16 &dir, v3s16 *vertex_dirs)
static void getNodeTextureCoords(v3f base, const v3f &scale, const v3s16 &dir, float *u, float *v)
{
- if (dir.X > 0 || dir.Y > 0 || dir.Z < 0)
+ if (dir.X > 0 || dir.Y != 0 || dir.Z < 0)
base -= scale;
if (dir == v3s16(0,0,1)) {
*u = -base.X - 1;
@@ -422,8 +422,8 @@ static void getNodeTextureCoords(v3f base, const v3f &scale, const v3s16 &dir, f
*u = base.X + 1;
*v = -base.Z - 2;
} else if (dir == v3s16(0,-1,0)) {
- *u = base.X;
- *v = base.Z;
+ *u = base.X + 1;
+ *v = base.Z + 1;
}
}
diff --git a/src/client/minimap.cpp b/src/client/minimap.cpp
index c6ccf86e8..dd810ee0a 100644
--- a/src/client/minimap.cpp
+++ b/src/client/minimap.cpp
@@ -304,7 +304,7 @@ void Minimap::setModeIndex(size_t index)
data->mode = m_modes[index];
m_current_mode_index = index;
} else {
- data->mode = MinimapModeDef{MINIMAP_TYPE_OFF, N_("Minimap hidden"), 0, 0, ""};
+ data->mode = MinimapModeDef{MINIMAP_TYPE_OFF, gettext("Minimap hidden"), 0, 0, ""};
m_current_mode_index = 0;
}
@@ -330,25 +330,26 @@ void Minimap::addMode(MinimapModeDef mode)
if (mode.label == "") {
switch (mode.type) {
case MINIMAP_TYPE_OFF:
- mode.label = N_("Minimap hidden");
+ mode.label = gettext("Minimap hidden");
break;
case MINIMAP_TYPE_SURFACE:
- mode.label = N_("Minimap in surface mode, Zoom x%d");
+ mode.label = gettext("Minimap in surface mode, Zoom x%d");
if (mode.map_size > 0)
zoom = 256 / mode.map_size;
break;
case MINIMAP_TYPE_RADAR:
- mode.label = N_("Minimap in radar mode, Zoom x%d");
+ mode.label = gettext("Minimap in radar mode, Zoom x%d");
if (mode.map_size > 0)
zoom = 512 / mode.map_size;
break;
case MINIMAP_TYPE_TEXTURE:
- mode.label = N_("Minimap in texture mode");
+ mode.label = gettext("Minimap in texture mode");
break;
default:
break;
}
}
+ // else: Custom labels need mod-provided client-side translation
if (zoom >= 0) {
char label_buf[1024];
diff --git a/src/client/render/anaglyph.cpp b/src/client/render/anaglyph.cpp
index 9ba4464a2..153e77400 100644
--- a/src/client/render/anaglyph.cpp
+++ b/src/client/render/anaglyph.cpp
@@ -40,7 +40,7 @@ void RenderingCoreAnaglyph::setupMaterial(int color_mask)
void RenderingCoreAnaglyph::useEye(bool right)
{
RenderingCoreStereo::useEye(right);
- driver->clearZBuffer();
+ driver->clearBuffers(video::ECBF_DEPTH);
setupMaterial(right ? video::ECP_GREEN | video::ECP_BLUE : video::ECP_RED);
}
diff --git a/src/client/render/interlaced.cpp b/src/client/render/interlaced.cpp
index ce8e92f21..3f79a8eb5 100644
--- a/src/client/render/interlaced.cpp
+++ b/src/client/render/interlaced.cpp
@@ -35,7 +35,11 @@ void RenderingCoreInterlaced::initMaterial()
IShaderSource *s = client->getShaderSource();
mat.UseMipMaps = false;
mat.ZBuffer = false;
+#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR > 8
+ mat.ZWriteEnable = video::EZW_OFF;
+#else
mat.ZWriteEnable = false;
+#endif
u32 shader = s->getShader("3d_interlaced_merge", TILE_MATERIAL_BASIC);
mat.MaterialType = s->getShaderInfo(shader).material;
for (int k = 0; k < 3; ++k) {
diff --git a/src/client/renderingengine.cpp b/src/client/renderingengine.cpp
index 99ff8c1ee..4f59bbae3 100644
--- a/src/client/renderingengine.cpp
+++ b/src/client/renderingengine.cpp
@@ -118,6 +118,8 @@ RenderingEngine::RenderingEngine(IEventReceiver *receiver)
}
SIrrlichtCreationParameters params = SIrrlichtCreationParameters();
+ if (g_logger.getTraceEnabled())
+ params.LoggingLevel = irr::ELL_DEBUG;
params.DriverType = driverType;
params.WindowSize = core::dimension2d<u32>(screen_w, screen_h);
params.Bits = bits;
@@ -325,9 +327,11 @@ static bool getWindowHandle(irr::video::IVideoDriver *driver, HWND &hWnd)
const video::SExposedVideoData exposedData = driver->getExposedVideoData();
switch (driver->getDriverType()) {
+#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 9
case video::EDT_DIRECT3D8:
hWnd = reinterpret_cast<HWND>(exposedData.D3D8.HWnd);
break;
+#endif
case video::EDT_DIRECT3D9:
hWnd = reinterpret_cast<HWND>(exposedData.D3D9.HWnd);
break;
diff --git a/src/client/shader.h b/src/client/shader.h
index 38ab76704..49a563115 100644
--- a/src/client/shader.h
+++ b/src/client/shader.h
@@ -96,9 +96,10 @@ public:
if (has_been_set && std::equal(m_sent, m_sent + count, value))
return;
if (is_pixel)
- services->setPixelShaderConstant(m_name, value, count);
+ services->setPixelShaderConstant(services->getPixelShaderConstantID(m_name), value, count);
else
- services->setVertexShaderConstant(m_name, value, count);
+ services->setVertexShaderConstant(services->getVertexShaderConstantID(m_name), value, count);
+
std::copy(value, value + count, m_sent);
has_been_set = true;
}
diff --git a/src/client/sky.cpp b/src/client/sky.cpp
index 3a40321dd..caf695e7a 100644
--- a/src/client/sky.cpp
+++ b/src/client/sky.cpp
@@ -39,12 +39,13 @@ static video::SMaterial baseMaterial()
{
video::SMaterial mat;
mat.Lighting = false;
-#if ENABLE_GLES
+#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR > 8
mat.ZBuffer = video::ECFN_DISABLED;
+ mat.ZWriteEnable = video::EZW_OFF;
#else
+ mat.ZWriteEnable = false;
mat.ZBuffer = video::ECFN_NEVER;
#endif
- mat.ZWriteEnable = false;
mat.AntiAliasing = 0;
mat.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
mat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
diff --git a/src/client/sound_openal.cpp b/src/client/sound_openal.cpp
index f4e61f93e..8dceeede6 100644
--- a/src/client/sound_openal.cpp
+++ b/src/client/sound_openal.cpp
@@ -671,8 +671,8 @@ public:
alSourcei(sound->source_id, AL_SOURCE_RELATIVE, false);
alSource3f(sound->source_id, AL_POSITION, pos.X, pos.Y, pos.Z);
- alSource3f(sound->source_id, AL_VELOCITY, 0, 0, 0);
- alSourcef(sound->source_id, AL_REFERENCE_DISTANCE, 30.0);
+ alSource3f(sound->source_id, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
+ alSourcef(sound->source_id, AL_REFERENCE_DISTANCE, 10.0f);
}
bool updateSoundGain(int id, float gain)
diff --git a/src/client/tile.cpp b/src/client/tile.cpp
index aad956ada..7e3901247 100644
--- a/src/client/tile.cpp
+++ b/src/client/tile.cpp
@@ -837,17 +837,16 @@ static video::IImage *createInventoryCubeImage(
image = scaled;
}
sanity_check(image->getPitch() == 4 * size);
- return reinterpret_cast<u32 *>(image->lock());
+ return reinterpret_cast<u32 *>(image->getData());
};
auto free_image = [] (video::IImage *image) -> void {
- image->unlock();
image->drop();
};
video::IImage *result = driver->createImage(video::ECF_A8R8G8B8, {cube_size, cube_size});
sanity_check(result->getPitch() == 4 * cube_size);
result->fill(video::SColor(0x00000000u));
- u32 *target = reinterpret_cast<u32 *>(result->lock());
+ u32 *target = reinterpret_cast<u32 *>(result->getData());
// Draws single cube face
// `shade_factor` is face brightness, in range [0.0, 1.0]
@@ -906,7 +905,6 @@ static video::IImage *createInventoryCubeImage(
{0, 5}, {1, 5},
});
- result->unlock();
return result;
}
@@ -2224,9 +2222,14 @@ video::SColor TextureSource::getTextureAverageColor(const std::string &name)
video::IVideoDriver *driver = RenderingEngine::get_video_driver();
video::SColor c(0, 0, 0, 0);
video::ITexture *texture = getTexture(name);
+ if (!texture)
+ return c;
video::IImage *image = driver->createImage(texture,
core::position2d<s32>(0, 0),
texture->getOriginalSize());
+ if (!image)
+ return c;
+
u32 total = 0;
u32 tR = 0;
u32 tG = 0;
diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp
index ad583210a..387eb17c3 100644
--- a/src/client/wieldmesh.cpp
+++ b/src/client/wieldmesh.cpp
@@ -294,7 +294,7 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename,
}
material.setFlag(video::EMF_ANISOTROPIC_FILTER, m_anisotropic_filter);
// mipmaps cause "thin black line" artifacts
-#if (IRRLICHT_VERSION_MAJOR >= 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2
+#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2
material.setFlag(video::EMF_USE_MIP_MAPS, false);
#endif
if (m_enable_shaders) {
@@ -303,23 +303,26 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename,
}
}
-scene::SMesh *createSpecialNodeMesh(Client *client, content_t id, std::vector<ItemPartColor> *colors, const ContentFeatures &f)
+static scene::SMesh *createSpecialNodeMesh(Client *client, MapNode n,
+ std::vector<ItemPartColor> *colors, const ContentFeatures &f)
{
MeshMakeData mesh_make_data(client, false);
MeshCollector collector;
mesh_make_data.setSmoothLighting(false);
MapblockMeshGenerator gen(&mesh_make_data, &collector);
- u8 param2 = 0;
- if (f.param_type_2 == CPT2_WALLMOUNTED ||
+
+ if (n.getParam2()) {
+ // keep it
+ } else if (f.param_type_2 == CPT2_WALLMOUNTED ||
f.param_type_2 == CPT2_COLORED_WALLMOUNTED) {
if (f.drawtype == NDT_TORCHLIKE)
- param2 = 1;
+ n.setParam2(1);
else if (f.drawtype == NDT_SIGNLIKE ||
f.drawtype == NDT_NODEBOX ||
f.drawtype == NDT_MESH)
- param2 = 4;
+ n.setParam2(4);
}
- gen.renderSingle(id, param2);
+ gen.renderSingle(n.getContent(), n.getParam2());
colors->clear();
scene::SMesh *mesh = new scene::SMesh();
@@ -413,9 +416,12 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
case NDT_LIQUID:
setCube(f, def.wield_scale);
break;
- default:
+ default: {
// Render non-trivial drawtypes like the actual node
- mesh = createSpecialNodeMesh(client, id, &m_colors, f);
+ MapNode n(id);
+ n.setParam2(def.place_param2);
+
+ mesh = createSpecialNodeMesh(client, n, &m_colors, f);
changeToMesh(mesh);
mesh->drop();
m_meshnode->setScale(
@@ -423,6 +429,7 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
/ (BS * f.visual_scale));
break;
}
+ }
u32 material_count = m_meshnode->getMaterialCount();
for (u32 i = 0; i < material_count; ++i) {
@@ -585,12 +592,16 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
result->buffer_colors.emplace_back(l0.has_color, l0.color);
break;
}
- default:
+ default: {
// Render non-trivial drawtypes like the actual node
- mesh = createSpecialNodeMesh(client, id, &result->buffer_colors, f);
+ MapNode n(id);
+ n.setParam2(def.place_param2);
+
+ mesh = createSpecialNodeMesh(client, n, &result->buffer_colors, f);
scaleMesh(mesh, v3f(0.12, 0.12, 0.12));
break;
}
+ }
u32 mc = mesh->getMeshBufferCount();
for (u32 i = 0; i < mc; ++i) {