forked from Mirrorlandia_minetest/minetest
Add nametag background setting and object property (#10937)
This commit is contained in:
parent
a8f6befd39
commit
f85e9ab925
@ -29,3 +29,4 @@ AlignAfterOpenBracket: DontAlign
|
|||||||
ContinuationIndentWidth: 16
|
ContinuationIndentWidth: 16
|
||||||
ConstructorInitializerIndentWidth: 16
|
ConstructorInitializerIndentWidth: 16
|
||||||
BreakConstructorInitializers: AfterColon
|
BreakConstructorInitializers: AfterColon
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
@ -451,6 +451,10 @@ keymap_decrease_viewing_range_min (View range decrease key) key -
|
|||||||
|
|
||||||
[**Basic]
|
[**Basic]
|
||||||
|
|
||||||
|
# Whether nametag backgrounds should be shown by default.
|
||||||
|
# Mods may still set a background.
|
||||||
|
show_nametag_backgrounds (Show nametag backgrounds by default) bool true
|
||||||
|
|
||||||
# Enable vertex buffer objects.
|
# Enable vertex buffer objects.
|
||||||
# This should greatly improve graphics performance.
|
# This should greatly improve graphics performance.
|
||||||
enable_vbo (VBO) bool true
|
enable_vbo (VBO) bool true
|
||||||
|
@ -6274,15 +6274,21 @@ object you are working with still exists.
|
|||||||
* `get_nametag_attributes()`
|
* `get_nametag_attributes()`
|
||||||
* returns a table with the attributes of the nametag of an object
|
* returns a table with the attributes of the nametag of an object
|
||||||
* {
|
* {
|
||||||
color = {a=0..255, r=0..255, g=0..255, b=0..255},
|
|
||||||
text = "",
|
text = "",
|
||||||
|
color = {a=0..255, r=0..255, g=0..255, b=0..255},
|
||||||
|
bgcolor = {a=0..255, r=0..255, g=0..255, b=0..255},
|
||||||
}
|
}
|
||||||
* `set_nametag_attributes(attributes)`
|
* `set_nametag_attributes(attributes)`
|
||||||
* sets the attributes of the nametag of an object
|
* sets the attributes of the nametag of an object
|
||||||
* `attributes`:
|
* `attributes`:
|
||||||
{
|
{
|
||||||
color = ColorSpec,
|
|
||||||
text = "My Nametag",
|
text = "My Nametag",
|
||||||
|
color = ColorSpec,
|
||||||
|
-- ^ Text color
|
||||||
|
bgcolor = ColorSpec or false,
|
||||||
|
-- ^ Sets background color of nametag
|
||||||
|
-- `false` will cause the background to be set automatically based on user settings
|
||||||
|
-- Default: false
|
||||||
}
|
}
|
||||||
|
|
||||||
#### Lua entity only (no-op for other objects)
|
#### Lua entity only (no-op for other objects)
|
||||||
@ -6956,9 +6962,13 @@ Player properties need to be saved manually.
|
|||||||
-- For all other objects, a nil or empty string removes the nametag.
|
-- For all other objects, a nil or empty string removes the nametag.
|
||||||
-- To hide a nametag, set its color alpha to zero. That will disable it entirely.
|
-- To hide a nametag, set its color alpha to zero. That will disable it entirely.
|
||||||
|
|
||||||
|
|
||||||
nametag_color = <ColorSpec>,
|
nametag_color = <ColorSpec>,
|
||||||
-- Sets color of nametag
|
-- Sets text color of nametag
|
||||||
|
|
||||||
|
nametag_bgcolor = <ColorSpec>,
|
||||||
|
-- Sets background color of nametag
|
||||||
|
-- `false` will cause the background to be set automatically based on user settings.
|
||||||
|
-- Default: false
|
||||||
|
|
||||||
infotext = "",
|
infotext = "",
|
||||||
-- By default empty, text to be shown when pointed at object
|
-- By default empty, text to be shown when pointed at object
|
||||||
|
@ -103,23 +103,35 @@ minetest.register_entity("testentities:nametag", {
|
|||||||
|
|
||||||
on_activate = function(self, staticdata)
|
on_activate = function(self, staticdata)
|
||||||
if staticdata ~= "" then
|
if staticdata ~= "" then
|
||||||
self.color = minetest.deserialize(staticdata).color
|
local data = minetest.deserialize(staticdata)
|
||||||
|
self.color = data.color
|
||||||
|
self.bgcolor = data.bgcolor
|
||||||
else
|
else
|
||||||
self.color = {
|
self.color = {
|
||||||
r = math.random(0, 255),
|
r = math.random(0, 255),
|
||||||
g = math.random(0, 255),
|
g = math.random(0, 255),
|
||||||
b = math.random(0, 255),
|
b = math.random(0, 255),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if math.random(0, 10) > 5 then
|
||||||
|
self.bgcolor = {
|
||||||
|
r = math.random(0, 255),
|
||||||
|
g = math.random(0, 255),
|
||||||
|
b = math.random(0, 255),
|
||||||
|
a = math.random(0, 255),
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
assert(self.color)
|
assert(self.color)
|
||||||
self.object:set_properties({
|
self.object:set_properties({
|
||||||
nametag = tostring(math.random(1000, 10000)),
|
nametag = tostring(math.random(1000, 10000)),
|
||||||
nametag_color = self.color,
|
nametag_color = self.color,
|
||||||
|
nametag_bgcolor = self.bgcolor,
|
||||||
})
|
})
|
||||||
end,
|
end,
|
||||||
|
|
||||||
get_staticdata = function(self)
|
get_staticdata = function(self)
|
||||||
return minetest.serialize({ color = self.color })
|
return minetest.serialize({ color = self.color, bgcolor = self.bgcolor })
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
@ -25,7 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
class TestClientActiveObjectMgr;
|
class TestClientActiveObjectMgr;
|
||||||
class TestServerActiveObjectMgr;
|
class TestServerActiveObjectMgr;
|
||||||
|
|
||||||
template <typename T> class ActiveObjectMgr
|
template <typename T>
|
||||||
|
class ActiveObjectMgr
|
||||||
{
|
{
|
||||||
friend class ::TestClientActiveObjectMgr;
|
friend class ::TestClientActiveObjectMgr;
|
||||||
friend class ::TestServerActiveObjectMgr;
|
friend class ::TestServerActiveObjectMgr;
|
||||||
|
@ -79,6 +79,7 @@ Camera::Camera(MapDrawControl &draw_control, Client *client):
|
|||||||
m_cache_fov = std::fmax(g_settings->getFloat("fov"), 45.0f);
|
m_cache_fov = std::fmax(g_settings->getFloat("fov"), 45.0f);
|
||||||
m_arm_inertia = g_settings->getBool("arm_inertia");
|
m_arm_inertia = g_settings->getBool("arm_inertia");
|
||||||
m_nametags.clear();
|
m_nametags.clear();
|
||||||
|
m_show_nametag_backgrounds = g_settings->getBool("show_nametag_backgrounds");
|
||||||
}
|
}
|
||||||
|
|
||||||
Camera::~Camera()
|
Camera::~Camera()
|
||||||
@ -696,18 +697,14 @@ void Camera::drawNametags()
|
|||||||
v2u32 screensize = driver->getScreenSize();
|
v2u32 screensize = driver->getScreenSize();
|
||||||
|
|
||||||
for (const Nametag *nametag : m_nametags) {
|
for (const Nametag *nametag : m_nametags) {
|
||||||
if (nametag->nametag_color.getAlpha() == 0) {
|
// Nametags are hidden in GenericCAO::updateNametag()
|
||||||
// Enforce hiding nametag,
|
|
||||||
// because if freetype is enabled, a grey
|
v3f pos = nametag->parent_node->getAbsolutePosition() + nametag->pos * BS;
|
||||||
// shadow can remain.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
v3f pos = nametag->parent_node->getAbsolutePosition() + nametag->nametag_pos * BS;
|
|
||||||
f32 transformed_pos[4] = { pos.X, pos.Y, pos.Z, 1.0f };
|
f32 transformed_pos[4] = { pos.X, pos.Y, pos.Z, 1.0f };
|
||||||
trans.multiplyWith1x4Matrix(transformed_pos);
|
trans.multiplyWith1x4Matrix(transformed_pos);
|
||||||
if (transformed_pos[3] > 0) {
|
if (transformed_pos[3] > 0) {
|
||||||
std::wstring nametag_colorless =
|
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(
|
core::dimension2d<u32> textsize = font->getDimension(
|
||||||
nametag_colorless.c_str());
|
nametag_colorless.c_str());
|
||||||
f32 zDiv = transformed_pos[3] == 0.0f ? 1.0f :
|
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> size(0, 0, textsize.Width, textsize.Height);
|
||||||
core::rect<s32> bg_size(-2, 0, textsize.Width+2, textsize.Height);
|
core::rect<s32> bg_size(-2, 0, textsize.Width+2, textsize.Height);
|
||||||
|
|
||||||
video::SColor textColor = nametag->nametag_color;
|
auto bgcolor = nametag->getBgColor(m_show_nametag_backgrounds);
|
||||||
|
if (bgcolor.getAlpha() != 0)
|
||||||
bool darkBackground = textColor.getLuminance() > 186;
|
driver->draw2DRectangle(bgcolor, bg_size + screen_pos);
|
||||||
video::SColor backgroundColor = darkBackground
|
|
||||||
? video::SColor(50, 50, 50, 50)
|
|
||||||
: video::SColor(50, 255, 255, 255);
|
|
||||||
driver->draw2DRectangle(backgroundColor, bg_size + screen_pos);
|
|
||||||
|
|
||||||
font->draw(
|
font->draw(
|
||||||
translate_string(utf8_to_wide(nametag->nametag_text)).c_str(),
|
translate_string(utf8_to_wide(nametag->text)).c_str(),
|
||||||
size + screen_pos, textColor);
|
size + screen_pos, nametag->textcolor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Nametag *Camera::addNametag(scene::ISceneNode *parent_node,
|
Nametag *Camera::addNametag(scene::ISceneNode *parent_node,
|
||||||
const std::string &nametag_text, video::SColor nametag_color,
|
const std::string &text, video::SColor textcolor,
|
||||||
const v3f &pos)
|
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);
|
m_nametags.push_back(nametag);
|
||||||
return nametag;
|
return nametag;
|
||||||
}
|
}
|
||||||
|
@ -25,27 +25,47 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include <ICameraSceneNode.h>
|
#include <ICameraSceneNode.h>
|
||||||
#include <ISceneNode.h>
|
#include <ISceneNode.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include "util/Optional.h"
|
||||||
|
|
||||||
class LocalPlayer;
|
class LocalPlayer;
|
||||||
struct MapDrawControl;
|
struct MapDrawControl;
|
||||||
class Client;
|
class Client;
|
||||||
class WieldMeshSceneNode;
|
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,
|
Nametag(scene::ISceneNode *a_parent_node,
|
||||||
const std::string &a_nametag_text,
|
const std::string &text,
|
||||||
const video::SColor &a_nametag_color,
|
const video::SColor &textcolor,
|
||||||
const v3f &a_nametag_pos):
|
const Optional<video::SColor> &bgcolor,
|
||||||
|
const v3f &pos):
|
||||||
parent_node(a_parent_node),
|
parent_node(a_parent_node),
|
||||||
nametag_text(a_nametag_text),
|
text(text),
|
||||||
nametag_color(a_nametag_color),
|
textcolor(textcolor),
|
||||||
nametag_pos(a_nametag_pos)
|
bgcolor(bgcolor),
|
||||||
|
pos(pos)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
scene::ISceneNode *parent_node;
|
|
||||||
std::string nametag_text;
|
video::SColor getBgColor(bool use_fallback) const
|
||||||
video::SColor nametag_color;
|
{
|
||||||
v3f nametag_pos;
|
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};
|
enum CameraMode {CAMERA_MODE_FIRST, CAMERA_MODE_THIRD, CAMERA_MODE_THIRD_FRONT};
|
||||||
@ -164,8 +184,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Nametag *addNametag(scene::ISceneNode *parent_node,
|
Nametag *addNametag(scene::ISceneNode *parent_node,
|
||||||
const std::string &nametag_text, video::SColor nametag_color,
|
const std::string &text, video::SColor textcolor,
|
||||||
const v3f &pos);
|
Optional<video::SColor> bgcolor, const v3f &pos);
|
||||||
|
|
||||||
void removeNametag(Nametag *nametag);
|
void removeNametag(Nametag *nametag);
|
||||||
|
|
||||||
@ -245,4 +265,5 @@ private:
|
|||||||
bool m_arm_inertia;
|
bool m_arm_inertia;
|
||||||
|
|
||||||
std::list<Nametag *> m_nametags;
|
std::list<Nametag *> m_nametags;
|
||||||
|
bool m_show_nametag_backgrounds;
|
||||||
};
|
};
|
||||||
|
@ -934,7 +934,7 @@ void GenericCAO::updateNametag()
|
|||||||
if (m_is_local_player) // No nametag for local player
|
if (m_is_local_player) // No nametag for local player
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_prop.nametag.empty()) {
|
if (m_prop.nametag.empty() || m_prop.nametag_color.getAlpha() == 0) {
|
||||||
// Delete nametag
|
// Delete nametag
|
||||||
if (m_nametag) {
|
if (m_nametag) {
|
||||||
m_client->getCamera()->removeNametag(m_nametag);
|
m_client->getCamera()->removeNametag(m_nametag);
|
||||||
@ -952,12 +952,14 @@ void GenericCAO::updateNametag()
|
|||||||
if (!m_nametag) {
|
if (!m_nametag) {
|
||||||
// Add nametag
|
// Add nametag
|
||||||
m_nametag = m_client->getCamera()->addNametag(node,
|
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 {
|
} else {
|
||||||
// Update nametag
|
// Update nametag
|
||||||
m_nametag->nametag_text = m_prop.nametag;
|
m_nametag->text = m_prop.nametag;
|
||||||
m_nametag->nametag_color = m_prop.nametag_color;
|
m_nametag->textcolor = m_prop.nametag_color;
|
||||||
m_nametag->nametag_pos = pos;
|
m_nametag->bgcolor = m_prop.nametag_bgcolor;
|
||||||
|
m_nametag->pos = pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,6 +240,7 @@ void set_default_settings()
|
|||||||
#endif
|
#endif
|
||||||
settings->setDefault("enable_particles", "true");
|
settings->setDefault("enable_particles", "true");
|
||||||
settings->setDefault("arm_inertia", "true");
|
settings->setDefault("arm_inertia", "true");
|
||||||
|
settings->setDefault("show_nametag_backgrounds", "true");
|
||||||
|
|
||||||
settings->setDefault("enable_minimap", "true");
|
settings->setDefault("enable_minimap", "true");
|
||||||
settings->setDefault("minimap_shape_round", "true");
|
settings->setDefault("minimap_shape_round", "true");
|
||||||
|
@ -24,6 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "util/basic_macros.h"
|
#include "util/basic_macros.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
static const video::SColor NULL_BGCOLOR{0, 1, 1, 1};
|
||||||
|
|
||||||
ObjectProperties::ObjectProperties()
|
ObjectProperties::ObjectProperties()
|
||||||
{
|
{
|
||||||
textures.emplace_back("unknown_object.png");
|
textures.emplace_back("unknown_object.png");
|
||||||
@ -62,6 +64,13 @@ std::string ObjectProperties::dump()
|
|||||||
os << ", nametag=" << nametag;
|
os << ", nametag=" << nametag;
|
||||||
os << ", nametag_color=" << "\"" << nametag_color.getAlpha() << "," << nametag_color.getRed()
|
os << ", nametag_color=" << "\"" << nametag_color.getAlpha() << "," << nametag_color.getRed()
|
||||||
<< "," << nametag_color.getGreen() << "," << nametag_color.getBlue() << "\" ";
|
<< "," << nametag_color.getGreen() << "," << nametag_color.getBlue() << "\" ";
|
||||||
|
|
||||||
|
if (nametag_bgcolor)
|
||||||
|
os << ", nametag_bgcolor=" << "\"" << nametag_color.getAlpha() << "," << nametag_color.getRed()
|
||||||
|
<< "," << nametag_color.getGreen() << "," << nametag_color.getBlue() << "\" ";
|
||||||
|
else
|
||||||
|
os << ", nametag_bgcolor=null ";
|
||||||
|
|
||||||
os << ", selectionbox=" << PP(selectionbox.MinEdge) << "," << PP(selectionbox.MaxEdge);
|
os << ", selectionbox=" << PP(selectionbox.MinEdge) << "," << PP(selectionbox.MaxEdge);
|
||||||
os << ", pointable=" << pointable;
|
os << ", pointable=" << pointable;
|
||||||
os << ", static_save=" << static_save;
|
os << ", static_save=" << static_save;
|
||||||
@ -121,6 +130,13 @@ void ObjectProperties::serialize(std::ostream &os) const
|
|||||||
writeU8(os, shaded);
|
writeU8(os, shaded);
|
||||||
writeU8(os, show_on_minimap);
|
writeU8(os, show_on_minimap);
|
||||||
|
|
||||||
|
if (!nametag_bgcolor)
|
||||||
|
writeARGB8(os, NULL_BGCOLOR);
|
||||||
|
else if (nametag_bgcolor.value().getAlpha() == 0)
|
||||||
|
writeARGB8(os, video::SColor(0, 0, 0, 0));
|
||||||
|
else
|
||||||
|
writeARGB8(os, nametag_bgcolor.value());
|
||||||
|
|
||||||
// Add stuff only at the bottom.
|
// Add stuff only at the bottom.
|
||||||
// Never remove anything, because we don't want new versions of this
|
// Never remove anything, because we don't want new versions of this
|
||||||
}
|
}
|
||||||
@ -182,5 +198,11 @@ void ObjectProperties::deSerialize(std::istream &is)
|
|||||||
if (is.eof())
|
if (is.eof())
|
||||||
return;
|
return;
|
||||||
show_on_minimap = tmp;
|
show_on_minimap = tmp;
|
||||||
|
|
||||||
|
auto bgcolor = readARGB8(is);
|
||||||
|
if (bgcolor != NULL_BGCOLOR)
|
||||||
|
nametag_bgcolor = bgcolor;
|
||||||
|
else
|
||||||
|
nametag_bgcolor = nullopt;
|
||||||
} catch (SerializationError &e) {}
|
} catch (SerializationError &e) {}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "util/Optional.h"
|
||||||
|
|
||||||
struct ObjectProperties
|
struct ObjectProperties
|
||||||
{
|
{
|
||||||
@ -53,6 +54,7 @@ struct ObjectProperties
|
|||||||
s8 glow = 0;
|
s8 glow = 0;
|
||||||
std::string nametag = "";
|
std::string nametag = "";
|
||||||
video::SColor nametag_color = video::SColor(255, 255, 255, 255);
|
video::SColor nametag_color = video::SColor(255, 255, 255, 255);
|
||||||
|
Optional<video::SColor> nametag_bgcolor = nullopt;
|
||||||
f32 automatic_face_movement_max_rotation_per_sec = -1.0f;
|
f32 automatic_face_movement_max_rotation_per_sec = -1.0f;
|
||||||
std::string infotext;
|
std::string infotext;
|
||||||
//! For dropped items, this contains item information.
|
//! For dropped items, this contains item information.
|
||||||
|
@ -312,6 +312,17 @@ void read_object_properties(lua_State *L, int index,
|
|||||||
prop->nametag_color = color;
|
prop->nametag_color = color;
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
lua_getfield(L, -1, "nametag_bgcolor");
|
||||||
|
if (!lua_isnil(L, -1)) {
|
||||||
|
if (lua_toboolean(L, -1)) {
|
||||||
|
video::SColor color;
|
||||||
|
if (read_color(L, -1, &color))
|
||||||
|
prop->nametag_bgcolor = color;
|
||||||
|
} else {
|
||||||
|
prop->nametag_bgcolor = nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
lua_getfield(L, -1, "automatic_face_movement_max_rotation_per_sec");
|
lua_getfield(L, -1, "automatic_face_movement_max_rotation_per_sec");
|
||||||
if (lua_isnumber(L, -1)) {
|
if (lua_isnumber(L, -1)) {
|
||||||
@ -403,6 +414,13 @@ void push_object_properties(lua_State *L, ObjectProperties *prop)
|
|||||||
lua_setfield(L, -2, "nametag");
|
lua_setfield(L, -2, "nametag");
|
||||||
push_ARGB8(L, prop->nametag_color);
|
push_ARGB8(L, prop->nametag_color);
|
||||||
lua_setfield(L, -2, "nametag_color");
|
lua_setfield(L, -2, "nametag_color");
|
||||||
|
if (prop->nametag_bgcolor) {
|
||||||
|
push_ARGB8(L, prop->nametag_bgcolor.value());
|
||||||
|
lua_setfield(L, -2, "nametag_bgcolor");
|
||||||
|
} else {
|
||||||
|
lua_pushboolean(L, false);
|
||||||
|
lua_setfield(L, -2, "nametag_bgcolor");
|
||||||
|
}
|
||||||
lua_pushnumber(L, prop->automatic_face_movement_max_rotation_per_sec);
|
lua_pushnumber(L, prop->automatic_face_movement_max_rotation_per_sec);
|
||||||
lua_setfield(L, -2, "automatic_face_movement_max_rotation_per_sec");
|
lua_setfield(L, -2, "automatic_face_movement_max_rotation_per_sec");
|
||||||
lua_pushlstring(L, prop->infotext.c_str(), prop->infotext.size());
|
lua_pushlstring(L, prop->infotext.c_str(), prop->infotext.size());
|
||||||
|
@ -50,22 +50,26 @@ bool LuaHelper::isNaN(lua_State *L, int idx)
|
|||||||
/*
|
/*
|
||||||
* Read template functions
|
* Read template functions
|
||||||
*/
|
*/
|
||||||
template <> bool LuaHelper::readParam(lua_State *L, int index)
|
template <>
|
||||||
|
bool LuaHelper::readParam(lua_State *L, int index)
|
||||||
{
|
{
|
||||||
return lua_toboolean(L, index) != 0;
|
return lua_toboolean(L, index) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> s16 LuaHelper::readParam(lua_State *L, int index)
|
template <>
|
||||||
|
s16 LuaHelper::readParam(lua_State *L, int index)
|
||||||
{
|
{
|
||||||
return lua_tonumber(L, index);
|
return lua_tonumber(L, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> int LuaHelper::readParam(lua_State *L, int index)
|
template <>
|
||||||
|
int LuaHelper::readParam(lua_State *L, int index)
|
||||||
{
|
{
|
||||||
return luaL_checkint(L, index);
|
return luaL_checkint(L, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> float LuaHelper::readParam(lua_State *L, int index)
|
template <>
|
||||||
|
float LuaHelper::readParam(lua_State *L, int index)
|
||||||
{
|
{
|
||||||
if (isNaN(L, index))
|
if (isNaN(L, index))
|
||||||
throw LuaError("NaN value is not allowed.");
|
throw LuaError("NaN value is not allowed.");
|
||||||
@ -73,7 +77,8 @@ template <> float LuaHelper::readParam(lua_State *L, int index)
|
|||||||
return (float)luaL_checknumber(L, index);
|
return (float)luaL_checknumber(L, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> v2s16 LuaHelper::readParam(lua_State *L, int index)
|
template <>
|
||||||
|
v2s16 LuaHelper::readParam(lua_State *L, int index)
|
||||||
{
|
{
|
||||||
v2s16 p;
|
v2s16 p;
|
||||||
CHECK_POS_TAB(index);
|
CHECK_POS_TAB(index);
|
||||||
@ -88,7 +93,8 @@ template <> v2s16 LuaHelper::readParam(lua_State *L, int index)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> v2f LuaHelper::readParam(lua_State *L, int index)
|
template <>
|
||||||
|
v2f LuaHelper::readParam(lua_State *L, int index)
|
||||||
{
|
{
|
||||||
v2f p;
|
v2f p;
|
||||||
CHECK_POS_TAB(index);
|
CHECK_POS_TAB(index);
|
||||||
@ -103,7 +109,8 @@ template <> v2f LuaHelper::readParam(lua_State *L, int index)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> v3f LuaHelper::readParam(lua_State *L, int index)
|
template <>
|
||||||
|
v3f LuaHelper::readParam(lua_State *L, int index)
|
||||||
{
|
{
|
||||||
v3f p;
|
v3f p;
|
||||||
CHECK_POS_TAB(index);
|
CHECK_POS_TAB(index);
|
||||||
@ -122,7 +129,8 @@ template <> v3f LuaHelper::readParam(lua_State *L, int index)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> std::string LuaHelper::readParam(lua_State *L, int index)
|
template <>
|
||||||
|
std::string LuaHelper::readParam(lua_State *L, int index)
|
||||||
{
|
{
|
||||||
size_t length;
|
size_t length;
|
||||||
std::string result;
|
std::string result;
|
||||||
|
@ -38,7 +38,8 @@ protected:
|
|||||||
* @param index Lua Index to read
|
* @param index Lua Index to read
|
||||||
* @return read value from Lua
|
* @return read value from Lua
|
||||||
*/
|
*/
|
||||||
template <typename T> static T readParam(lua_State *L, int index);
|
template <typename T>
|
||||||
|
static T readParam(lua_State *L, int index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a value using a template type T from Lua State L and index
|
* Read a value using a template type T from Lua State L and index
|
||||||
|
@ -737,6 +737,18 @@ int ObjectRef::l_set_nametag_attributes(lua_State *L)
|
|||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_getfield(L, -1, "bgcolor");
|
||||||
|
if (!lua_isnil(L, -1)) {
|
||||||
|
if (lua_toboolean(L, -1)) {
|
||||||
|
video::SColor color;
|
||||||
|
if (read_color(L, -1, &color))
|
||||||
|
prop->nametag_bgcolor = color;
|
||||||
|
} else {
|
||||||
|
prop->nametag_bgcolor = nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
std::string nametag = getstringfield_default(L, 2, "text", "");
|
std::string nametag = getstringfield_default(L, 2, "text", "");
|
||||||
prop->nametag = nametag;
|
prop->nametag = nametag;
|
||||||
|
|
||||||
@ -758,13 +770,24 @@ int ObjectRef::l_get_nametag_attributes(lua_State *L)
|
|||||||
if (!prop)
|
if (!prop)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
video::SColor color = prop->nametag_color;
|
|
||||||
|
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
push_ARGB8(L, color);
|
|
||||||
|
push_ARGB8(L, prop->nametag_color);
|
||||||
lua_setfield(L, -2, "color");
|
lua_setfield(L, -2, "color");
|
||||||
|
|
||||||
|
if (prop->nametag_bgcolor) {
|
||||||
|
push_ARGB8(L, prop->nametag_bgcolor.value());
|
||||||
|
lua_setfield(L, -2, "bgcolor");
|
||||||
|
} else {
|
||||||
|
lua_pushboolean(L, false);
|
||||||
|
lua_setfield(L, -2, "bgcolor");
|
||||||
|
}
|
||||||
|
|
||||||
lua_pushstring(L, prop->nametag.c_str());
|
lua_pushstring(L, prop->nametag.c_str());
|
||||||
lua_setfield(L, -2, "text");
|
lua_setfield(L, -2, "text");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
77
src/util/Optional.h
Normal file
77
src/util/Optional.h
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
Minetest
|
||||||
|
Copyright (C) 2021 rubenwardy
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
struct nullopt_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
constexpr nullopt_t nullopt{};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of optional for C++11, which aims to be
|
||||||
|
* compatible with a subset of std::optional features.
|
||||||
|
*
|
||||||
|
* Unfortunately, Minetest doesn't use C++17 yet.
|
||||||
|
*
|
||||||
|
* @tparam T The type to be stored
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
class Optional
|
||||||
|
{
|
||||||
|
bool m_has_value = false;
|
||||||
|
T m_value;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Optional() noexcept {}
|
||||||
|
Optional(nullopt_t) noexcept {}
|
||||||
|
Optional(const T &value) noexcept : m_has_value(true), m_value(value) {}
|
||||||
|
Optional(const Optional<T> &other) noexcept :
|
||||||
|
m_has_value(other.m_has_value), m_value(other.m_value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator=(nullopt_t) noexcept { m_has_value = false; }
|
||||||
|
|
||||||
|
void operator=(const Optional<T> &other) noexcept
|
||||||
|
{
|
||||||
|
m_has_value = other.m_has_value;
|
||||||
|
m_value = other.m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
T &value()
|
||||||
|
{
|
||||||
|
FATAL_ERROR_IF(!m_has_value, "optional doesn't have value");
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T &value() const
|
||||||
|
{
|
||||||
|
FATAL_ERROR_IF(!m_has_value, "optional doesn't have value");
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T &value_or(const T &def) const { return m_has_value ? m_value : def; }
|
||||||
|
|
||||||
|
bool has_value() const noexcept { return m_has_value; }
|
||||||
|
|
||||||
|
explicit operator bool() const { return m_has_value; }
|
||||||
|
};
|
@ -290,7 +290,7 @@ inline void writeS8(u8 *data, s8 i)
|
|||||||
|
|
||||||
inline void writeS16(u8 *data, s16 i)
|
inline void writeS16(u8 *data, s16 i)
|
||||||
{
|
{
|
||||||
writeU16(data, (u16)i);
|
writeU16(data, (u16)i);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void writeS32(u8 *data, s32 i)
|
inline void writeS32(u8 *data, s32 i)
|
||||||
|
Loading…
Reference in New Issue
Block a user