mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 09:15:29 +01:00 
			
		
		
		
	Allow to scale nametag by distance and set font size (#16267)
This commit is contained in:
		@@ -9604,6 +9604,16 @@ Player properties need to be saved manually.
 | 
			
		||||
    -- `false` will cause the background to be set automatically based on user settings.
 | 
			
		||||
    -- Default: false
 | 
			
		||||
 | 
			
		||||
    nametag_fontsize = 1,
 | 
			
		||||
    -- Sets the font size of the nametag in pixels.
 | 
			
		||||
    -- `false` will cause the size to be set automatically based on user settings.
 | 
			
		||||
    -- Default: false
 | 
			
		||||
 | 
			
		||||
    nametag_scale_z = false,
 | 
			
		||||
    -- If enabled, the nametag will be scaled by Z in screen space, meaning it becomes
 | 
			
		||||
    -- smaller the further away the object is.
 | 
			
		||||
    -- Default: false
 | 
			
		||||
 | 
			
		||||
    infotext = "",
 | 
			
		||||
    -- Same as infotext for nodes. Empty by default
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -631,55 +631,91 @@ void Camera::drawNametags()
 | 
			
		||||
	core::matrix4 trans = m_cameranode->getProjectionMatrix();
 | 
			
		||||
	trans *= m_cameranode->getViewMatrix();
 | 
			
		||||
 | 
			
		||||
	gui::IGUIFont *font = g_fontengine->getFont();
 | 
			
		||||
	// This isn't the actual size, just a placeholder so we can easily apply
 | 
			
		||||
	// the user's font size preference...
 | 
			
		||||
	const u32 default_font_size = 16;
 | 
			
		||||
	// ...by multiplying this in.
 | 
			
		||||
	const f32 font_size_mult = g_fontengine->getFontSize(FM_Unspecified) / (float)default_font_size;
 | 
			
		||||
	// Minimum distance until z-scaled nametags actually become smaller
 | 
			
		||||
	const f32 minimum_d = 1.0f * BS;
 | 
			
		||||
 | 
			
		||||
	video::IVideoDriver *driver = RenderingEngine::get_video_driver();
 | 
			
		||||
	v2u32 screensize = driver->getScreenSize();
 | 
			
		||||
 | 
			
		||||
	// Note: hidden nametags (e.g. GenericCAO) are removed from the array
 | 
			
		||||
	for (const Nametag *nametag : m_nametags) {
 | 
			
		||||
		// 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->text));
 | 
			
		||||
			core::dimension2d<u32> textsize = font->getDimension(
 | 
			
		||||
				nametag_colorless.c_str());
 | 
			
		||||
			f32 zDiv = transformed_pos[3] == 0.0f ? 1.0f :
 | 
			
		||||
				core::reciprocal(transformed_pos[3]);
 | 
			
		||||
			v2s32 screen_pos;
 | 
			
		||||
			screen_pos.X = screensize.X *
 | 
			
		||||
				(0.5 * transformed_pos[0] * zDiv + 0.5) - textsize.Width / 2;
 | 
			
		||||
			screen_pos.Y = screensize.Y *
 | 
			
		||||
				(0.5 - transformed_pos[1] * zDiv * 0.5) - textsize.Height / 2;
 | 
			
		||||
			core::rect<s32> size(0, 0, textsize.Width, textsize.Height);
 | 
			
		||||
		if (transformed_pos[3] <= 0) // negative Z means behind camera
 | 
			
		||||
			continue;
 | 
			
		||||
		f32 zDiv = transformed_pos[3] == 0.0f ? 1.0f : (1.0f / transformed_pos[3]);
 | 
			
		||||
 | 
			
		||||
			auto bgcolor = nametag->getBgColor(m_show_nametag_backgrounds);
 | 
			
		||||
			if (bgcolor.getAlpha() != 0) {
 | 
			
		||||
				core::rect<s32> bg_size(-2, 0, textsize.Width + 2, textsize.Height);
 | 
			
		||||
				driver->draw2DRectangle(bgcolor, bg_size + screen_pos);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			font->draw(
 | 
			
		||||
				translate_string(utf8_to_wide(nametag->text)).c_str(),
 | 
			
		||||
				size + screen_pos, nametag->textcolor);
 | 
			
		||||
		u32 font_size = 0;
 | 
			
		||||
		if (nametag->scale_z) {
 | 
			
		||||
			// Higher default since nametag should be reasonably visible
 | 
			
		||||
			// even at distance.
 | 
			
		||||
			u32 base_size = nametag->textsize.value_or(default_font_size * 4);
 | 
			
		||||
			f32 adjusted_d = std::max(transformed_pos[3] - minimum_d, 0.0f);
 | 
			
		||||
			f32 adjusted_zDiv = adjusted_d == 0.0f ? 1.0f : (1.0f / adjusted_d);
 | 
			
		||||
			font_size = myround(font_size_mult *
 | 
			
		||||
				rangelim(base_size * BS * adjusted_zDiv, 0, base_size));
 | 
			
		||||
		} else {
 | 
			
		||||
			font_size = myround(font_size_mult * nametag->textsize.value_or(default_font_size));
 | 
			
		||||
		}
 | 
			
		||||
		if (font_size <= 1)
 | 
			
		||||
			continue;
 | 
			
		||||
		// TODO: This is quite primitive. It would be better to let the GPU handle
 | 
			
		||||
		// scaling (draw to RTT first?).
 | 
			
		||||
		{
 | 
			
		||||
			// Because the current approach puts a high load on the font engine
 | 
			
		||||
			// we quantize the font size and set an arbitrary maximum...
 | 
			
		||||
			font_size = MYMIN(font_size, 256);
 | 
			
		||||
			if (font_size > 128)
 | 
			
		||||
				font_size &= ~(1|2|4);
 | 
			
		||||
			else if (font_size > 64)
 | 
			
		||||
				font_size &= ~(1|2);
 | 
			
		||||
			else if (font_size > 32)
 | 
			
		||||
				font_size &= ~1;
 | 
			
		||||
		}
 | 
			
		||||
		auto *font = g_fontengine->getFont(font_size);
 | 
			
		||||
		assert(font);
 | 
			
		||||
 | 
			
		||||
		const auto wtext = utf8_to_wide(nametag->text);
 | 
			
		||||
		// Measure dimensions with escapes removed
 | 
			
		||||
		core::dimension2du textsize = font->getDimension(unescape_translate(wtext).c_str());
 | 
			
		||||
		v2s32 screen_pos;
 | 
			
		||||
		screen_pos.X = screensize.X *
 | 
			
		||||
			(0.5f + transformed_pos[0] * zDiv * 0.5f) - textsize.Width / 2;
 | 
			
		||||
		screen_pos.Y = screensize.Y *
 | 
			
		||||
			(0.5f - transformed_pos[1] * zDiv * 0.5f) - textsize.Height / 2;
 | 
			
		||||
		core::rect<s32> size(0, 0, textsize.Width, textsize.Height);
 | 
			
		||||
 | 
			
		||||
		auto bgcolor = nametag->getBgColor(m_show_nametag_backgrounds);
 | 
			
		||||
		if (bgcolor.getAlpha() != 0) {
 | 
			
		||||
			core::rect<s32> bg_size(-2, 0, textsize.Width + 2, textsize.Height);
 | 
			
		||||
			driver->draw2DRectangle(bgcolor, bg_size + screen_pos);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// but draw text with escapes
 | 
			
		||||
		font->draw(translate_string(wtext).c_str(),
 | 
			
		||||
			size + screen_pos, nametag->textcolor);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Nametag *Camera::addNametag(scene::ISceneNode *parent_node,
 | 
			
		||||
		const std::string &text, video::SColor textcolor,
 | 
			
		||||
		std::optional<video::SColor> bgcolor, const v3f &pos)
 | 
			
		||||
Nametag *Camera::addNametag(const Nametag ¶ms)
 | 
			
		||||
{
 | 
			
		||||
	Nametag *nametag = new Nametag(parent_node, text, textcolor, bgcolor, pos);
 | 
			
		||||
	assert(params.parent_node);
 | 
			
		||||
	auto *nametag = new Nametag(params);
 | 
			
		||||
	m_nametags.push_back(nametag);
 | 
			
		||||
	return nametag;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Camera::removeNametag(Nametag *nametag)
 | 
			
		||||
{
 | 
			
		||||
	m_nametags.remove(nametag);
 | 
			
		||||
	auto it = std::find(m_nametags.begin(), m_nametags.end(), nametag);
 | 
			
		||||
	assert(it != m_nametags.end());
 | 
			
		||||
	m_nametags.erase(it);
 | 
			
		||||
	delete nametag;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,28 +23,17 @@ class WieldMeshSceneNode;
 | 
			
		||||
 | 
			
		||||
struct Nametag
 | 
			
		||||
{
 | 
			
		||||
	scene::ISceneNode *parent_node;
 | 
			
		||||
	scene::ISceneNode *parent_node = nullptr;
 | 
			
		||||
	std::string text;
 | 
			
		||||
	video::SColor textcolor;
 | 
			
		||||
	std::optional<video::SColor> bgcolor;
 | 
			
		||||
	v3f pos;
 | 
			
		||||
 | 
			
		||||
	Nametag(scene::ISceneNode *a_parent_node,
 | 
			
		||||
			const std::string &text,
 | 
			
		||||
			const video::SColor &textcolor,
 | 
			
		||||
			const std::optional<video::SColor> &bgcolor,
 | 
			
		||||
			const v3f &pos):
 | 
			
		||||
		parent_node(a_parent_node),
 | 
			
		||||
		text(text),
 | 
			
		||||
		textcolor(textcolor),
 | 
			
		||||
		bgcolor(bgcolor),
 | 
			
		||||
		pos(pos)
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
	std::optional<u32> textsize;
 | 
			
		||||
	v3f pos; // offset from parent node
 | 
			
		||||
	bool scale_z;
 | 
			
		||||
 | 
			
		||||
	video::SColor getBgColor(bool use_fallback) const
 | 
			
		||||
	{
 | 
			
		||||
		if (bgcolor)
 | 
			
		||||
		if (bgcolor.has_value())
 | 
			
		||||
			return bgcolor.value();
 | 
			
		||||
		else if (!use_fallback)
 | 
			
		||||
			return video::SColor(0, 0, 0, 0);
 | 
			
		||||
@@ -189,9 +178,7 @@ public:
 | 
			
		||||
		return m_camera_mode;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Nametag *addNametag(scene::ISceneNode *parent_node,
 | 
			
		||||
		const std::string &text, video::SColor textcolor,
 | 
			
		||||
		std::optional<video::SColor> bgcolor, const v3f &pos);
 | 
			
		||||
	Nametag *addNametag(const Nametag ¶ms);
 | 
			
		||||
 | 
			
		||||
	void removeNametag(Nametag *nametag);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -947,17 +947,15 @@ void GenericCAO::updateNametag()
 | 
			
		||||
 | 
			
		||||
	v3f pos;
 | 
			
		||||
	pos.Y = m_prop.selectionbox.MaxEdge.Y + 0.3f;
 | 
			
		||||
	// Add or update nametag
 | 
			
		||||
	Nametag tmp{node, m_prop.nametag, m_prop.nametag_color,
 | 
			
		||||
			m_prop.nametag_bgcolor, m_prop.nametag_fontsize, pos,
 | 
			
		||||
			m_prop.nametag_scale_z};
 | 
			
		||||
	if (!m_nametag) {
 | 
			
		||||
		// Add nametag
 | 
			
		||||
		m_nametag = m_client->getCamera()->addNametag(node,
 | 
			
		||||
			m_prop.nametag, m_prop.nametag_color,
 | 
			
		||||
			m_prop.nametag_bgcolor, pos);
 | 
			
		||||
		m_nametag = m_client->getCamera()->addNametag(tmp);
 | 
			
		||||
		assert(m_nametag);
 | 
			
		||||
	} else {
 | 
			
		||||
		// Update nametag
 | 
			
		||||
		m_nametag->text = m_prop.nametag;
 | 
			
		||||
		m_nametag->textcolor = m_prop.nametag_color;
 | 
			
		||||
		m_nametag->bgcolor = m_prop.nametag_bgcolor;
 | 
			
		||||
		m_nametag->pos = pos;
 | 
			
		||||
		*m_nametag = tmp;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,11 @@ ObjectProperties::ObjectProperties()
 | 
			
		||||
 | 
			
		||||
std::string ObjectProperties::dump() const
 | 
			
		||||
{
 | 
			
		||||
	const auto &put_color = [] (std::ostream &os, video::SColor color) {
 | 
			
		||||
		os << "\"" << color.getAlpha() << "," << color.getRed() << ","
 | 
			
		||||
			<< color.getGreen() << "," << color.getBlue() << "\" ";
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	std::ostringstream os(std::ios::binary);
 | 
			
		||||
	os << "hp_max=" << hp_max;
 | 
			
		||||
	os << ", breath_max=" << breath_max;
 | 
			
		||||
@@ -49,10 +54,8 @@ std::string ObjectProperties::dump() const
 | 
			
		||||
	}
 | 
			
		||||
	os << "]";
 | 
			
		||||
	os << ", colors=[";
 | 
			
		||||
	for (const video::SColor &color : colors) {
 | 
			
		||||
		os << "\"" << color.getAlpha() << "," << color.getRed() << ","
 | 
			
		||||
			<< color.getGreen() << "," << color.getBlue() << "\" ";
 | 
			
		||||
	}
 | 
			
		||||
	for (const video::SColor &color : colors)
 | 
			
		||||
		put_color(os, color);
 | 
			
		||||
	os << "]";
 | 
			
		||||
	os << ", spritediv=" << spritediv;
 | 
			
		||||
	os << ", initial_sprite_basepos=" << initial_sprite_basepos;
 | 
			
		||||
@@ -62,15 +65,18 @@ std::string ObjectProperties::dump() const
 | 
			
		||||
	os << ", backface_culling="<< backface_culling;
 | 
			
		||||
	os << ", glow=" << glow;
 | 
			
		||||
	os << ", nametag=" << nametag;
 | 
			
		||||
	os << ", nametag_color=" << "\"" << nametag_color.getAlpha() << "," << nametag_color.getRed()
 | 
			
		||||
			<< "," << nametag_color.getGreen() << "," << nametag_color.getBlue() << "\" ";
 | 
			
		||||
 | 
			
		||||
	os << ", nametag_color=";
 | 
			
		||||
	put_color(os, nametag_color);
 | 
			
		||||
	os << ", nametag_bgcolor=";
 | 
			
		||||
	if (nametag_bgcolor)
 | 
			
		||||
		os << ", nametag_bgcolor=" << "\"" << nametag_color.getAlpha() << "," << nametag_color.getRed()
 | 
			
		||||
		   << "," << nametag_color.getGreen() << "," << nametag_color.getBlue() << "\" ";
 | 
			
		||||
		put_color(os, nametag_bgcolor.value());
 | 
			
		||||
	else
 | 
			
		||||
		os << ", nametag_bgcolor=null ";
 | 
			
		||||
 | 
			
		||||
		os << "=null ";
 | 
			
		||||
	os << ", nametag_fontsize=";
 | 
			
		||||
	if (nametag_fontsize)
 | 
			
		||||
		os << "=" << nametag_fontsize.value() << " ";
 | 
			
		||||
	else
 | 
			
		||||
		os << "=null ";
 | 
			
		||||
	os << ", selectionbox=" << selectionbox.MinEdge << "," << selectionbox.MaxEdge;
 | 
			
		||||
	os << ", rotate_selectionbox=" << rotate_selectionbox;
 | 
			
		||||
	os << ", pointable=" << Pointabilities::toStringPointabilityType(pointable);
 | 
			
		||||
@@ -83,22 +89,24 @@ std::string ObjectProperties::dump() const
 | 
			
		||||
	os << ", damage_texture_modifier=" << damage_texture_modifier;
 | 
			
		||||
	os << ", shaded=" << shaded;
 | 
			
		||||
	os << ", show_on_minimap=" << show_on_minimap;
 | 
			
		||||
	os << ", nametag_scale_z=" << nametag_scale_z;
 | 
			
		||||
	return os.str();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static auto tie(const ObjectProperties &o)
 | 
			
		||||
static inline auto tie(const ObjectProperties &o)
 | 
			
		||||
{
 | 
			
		||||
	// Make sure to add new members to this list!
 | 
			
		||||
	return std::tie(
 | 
			
		||||
	o.textures, o.colors, o.collisionbox, o.selectionbox, o.visual, o.mesh,
 | 
			
		||||
	o.damage_texture_modifier, o.nametag, o.infotext, o.wield_item, o.visual_size,
 | 
			
		||||
	o.nametag_color, o.nametag_bgcolor, o.spritediv, o.initial_sprite_basepos,
 | 
			
		||||
	o.nametag_color, o.nametag_bgcolor, o.nametag_fontsize, o.spritediv,
 | 
			
		||||
	o.initial_sprite_basepos,
 | 
			
		||||
	o.stepheight, o.automatic_rotate, o.automatic_face_movement_dir_offset,
 | 
			
		||||
	o.automatic_face_movement_max_rotation_per_sec, o.eye_height, o.zoom_fov,
 | 
			
		||||
	o.node, o.hp_max, o.breath_max, o.glow, o.pointable, o.physical,
 | 
			
		||||
	o.collideWithObjects, o.rotate_selectionbox, o.is_visible, o.makes_footstep_sound,
 | 
			
		||||
	o.automatic_face_movement_dir, o.backface_culling, o.static_save, o.use_texture_alpha,
 | 
			
		||||
	o.shaded, o.show_on_minimap
 | 
			
		||||
	o.shaded, o.show_on_minimap, o.nametag_scale_z
 | 
			
		||||
	);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -202,6 +210,13 @@ void ObjectProperties::serialize(std::ostream &os) const
 | 
			
		||||
	writeU8(os, node.getParam1());
 | 
			
		||||
	writeU8(os, node.getParam2());
 | 
			
		||||
 | 
			
		||||
	if (!nametag_fontsize)
 | 
			
		||||
		writeU32(os, U32_MAX); // null placeholder
 | 
			
		||||
	else
 | 
			
		||||
		writeU32(os, nametag_fontsize.value());
 | 
			
		||||
 | 
			
		||||
	writeU8(os, nametag_scale_z);
 | 
			
		||||
 | 
			
		||||
	// Add stuff only at the bottom.
 | 
			
		||||
	// Never remove anything, because we don't want new versions of this!
 | 
			
		||||
}
 | 
			
		||||
@@ -306,5 +321,14 @@ void ObjectProperties::deSerialize(std::istream &is)
 | 
			
		||||
	node.param1 = readU8(is);
 | 
			
		||||
	node.param2 = readU8(is);
 | 
			
		||||
 | 
			
		||||
	u32 fontsize;
 | 
			
		||||
	if (!tryRead<u32, readU32>(fontsize, is))
 | 
			
		||||
		return;
 | 
			
		||||
	if (fontsize != U32_MAX)
 | 
			
		||||
		nametag_fontsize = fontsize;
 | 
			
		||||
	else
 | 
			
		||||
		nametag_fontsize = std::nullopt;
 | 
			
		||||
	nametag_scale_z = readU8(is);
 | 
			
		||||
 | 
			
		||||
	// Add new properties down here and remember to use either tryRead<> or a try-catch.
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -56,6 +56,7 @@ struct ObjectProperties
 | 
			
		||||
	f32 automatic_face_movement_max_rotation_per_sec = -1.0f;
 | 
			
		||||
	float eye_height = 1.625f;
 | 
			
		||||
	float zoom_fov = 0.0f;
 | 
			
		||||
	std::optional<u32> nametag_fontsize;
 | 
			
		||||
	MapNode node = MapNode(CONTENT_IGNORE);
 | 
			
		||||
	u16 hp_max = 1;
 | 
			
		||||
	u16 breath_max = 0;
 | 
			
		||||
@@ -73,6 +74,7 @@ struct ObjectProperties
 | 
			
		||||
	bool use_texture_alpha = false;
 | 
			
		||||
	bool shaded = true;
 | 
			
		||||
	bool show_on_minimap = false;
 | 
			
		||||
	bool nametag_scale_z = false;
 | 
			
		||||
 | 
			
		||||
	ObjectProperties();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -267,7 +267,7 @@ void push_item_definition_full(lua_State *L, const ItemDefinition &i)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
const std::array<const char *, 33> object_property_keys = {
 | 
			
		||||
const std::array<const char *, 35> object_property_keys = {
 | 
			
		||||
	"hp_max",
 | 
			
		||||
	"breath_max",
 | 
			
		||||
	"physical",
 | 
			
		||||
@@ -302,6 +302,8 @@ const std::array<const char *, 33> object_property_keys = {
 | 
			
		||||
	"damage_texture_modifier",
 | 
			
		||||
	"show_on_minimap",
 | 
			
		||||
	// "node" is intentionally not here as it's gated behind `fallback` below!
 | 
			
		||||
	"nametag_fontsize",
 | 
			
		||||
	"nametag_scale_z",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
@@ -467,7 +469,7 @@ void read_object_properties(lua_State *L, int index,
 | 
			
		||||
	lua_pop(L, 1);
 | 
			
		||||
	lua_getfield(L, -1, "nametag_bgcolor");
 | 
			
		||||
	if (!lua_isnil(L, -1)) {
 | 
			
		||||
		if (lua_toboolean(L, -1)) {
 | 
			
		||||
		if (lua_toboolean(L, -1)) { // truthy
 | 
			
		||||
			video::SColor color;
 | 
			
		||||
			if (read_color(L, -1, &color))
 | 
			
		||||
				prop->nametag_bgcolor = color;
 | 
			
		||||
@@ -476,6 +478,16 @@ void read_object_properties(lua_State *L, int index,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	lua_pop(L, 1);
 | 
			
		||||
	lua_getfield(L, -1, "nametag_fontsize");
 | 
			
		||||
	if (!lua_isnil(L, -1)) {
 | 
			
		||||
		if (lua_toboolean(L, -1)) { // truthy
 | 
			
		||||
			prop->nametag_fontsize = lua_tointeger(L, -1);
 | 
			
		||||
		} else {
 | 
			
		||||
			prop->nametag_fontsize = std::nullopt;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	lua_pop(L, 1);
 | 
			
		||||
	getboolfield(L, -1, "nametag_scale_z", prop->nametag_scale_z);
 | 
			
		||||
 | 
			
		||||
	getstringfield(L, -1, "infotext", prop->infotext);
 | 
			
		||||
	getboolfield(L, -1, "static_save", prop->static_save);
 | 
			
		||||
@@ -570,13 +582,18 @@ void push_object_properties(lua_State *L, const ObjectProperties *prop)
 | 
			
		||||
	lua_setfield(L, -2, "nametag");
 | 
			
		||||
	push_ARGB8(L, prop->nametag_color);
 | 
			
		||||
	lua_setfield(L, -2, "nametag_color");
 | 
			
		||||
	if (prop->nametag_bgcolor) {
 | 
			
		||||
	if (prop->nametag_bgcolor)
 | 
			
		||||
		push_ARGB8(L, prop->nametag_bgcolor.value());
 | 
			
		||||
		lua_setfield(L, -2, "nametag_bgcolor");
 | 
			
		||||
	} else {
 | 
			
		||||
	else
 | 
			
		||||
		lua_pushboolean(L, false);
 | 
			
		||||
		lua_setfield(L, -2, "nametag_bgcolor");
 | 
			
		||||
	}
 | 
			
		||||
	lua_setfield(L, -2, "nametag_bgcolor");
 | 
			
		||||
	if (prop->nametag_fontsize)
 | 
			
		||||
		lua_pushinteger(L, prop->nametag_fontsize.value());
 | 
			
		||||
	else
 | 
			
		||||
		lua_pushboolean(L, false);
 | 
			
		||||
	lua_setfield(L, -2, "nametag_fontsize");
 | 
			
		||||
	lua_pushboolean(L, prop->nametag_scale_z);
 | 
			
		||||
	lua_setfield(L, -2, "nametag_scale_z");
 | 
			
		||||
	lua_pushlstring(L, prop->infotext.c_str(), prop->infotext.size());
 | 
			
		||||
	lua_setfield(L, -2, "infotext");
 | 
			
		||||
	lua_pushboolean(L, prop->static_save);
 | 
			
		||||
 
 | 
			
		||||
@@ -59,8 +59,7 @@ extern struct EnumString es_TileAnimationType[];
 | 
			
		||||
extern struct EnumString es_ItemType[];
 | 
			
		||||
extern struct EnumString es_TouchInteractionMode[];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern const std::array<const char *, 33> object_property_keys;
 | 
			
		||||
extern const std::array<const char *, 35> object_property_keys;
 | 
			
		||||
 | 
			
		||||
void read_content_features(lua_State *L, ContentFeatures &f, int index);
 | 
			
		||||
void push_content_features(lua_State *L, const ContentFeatures &c);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user