Add on_object_hp_change callback and nametag images

wsc-dfc
Elias Fleckenstein 2021-05-10 20:45:05 +02:00
parent b84ed7d0be
commit c86dcd0f68
11 changed files with 101 additions and 11 deletions

View File

@ -106,6 +106,7 @@ core.registered_on_recieve_physics_override, core.register_on_recieve_physics_ov
core.registered_on_play_sound, core.register_on_play_sound = make_registration()
core.registered_on_spawn_particle, core.register_on_spawn_particle = make_registration()
core.registered_on_object_properties_change, core.register_on_object_properties_change = make_registration()
core.registered_on_object_hp_change, core.register_on_object_hp_change = make_registration()
core.registered_nodes = {}
core.registered_items = {}

View File

@ -766,6 +766,8 @@ Call these functions only at load time!
* `minetest.register_on_object_properties_change(function(obj))`
* Called every time the properties of an object are changed server-side
* May modify the object's properties without the fear of infinite recursion
* `minetest.register_on_object_hp_change(function(obj))`
* Called every time the hp of an object are changes server-side
### Setting-related
* `minetest.settings`: Settings object containing all of the settings from the
@ -1422,6 +1424,7 @@ This is basically a reference to a C++ `GenericCAO`.
* `punch()`: punches the object
* `rightclick()`: rightclicks the object
* `remove()`: removes the object permanently
* `set_nametag_images(images)`: Provides a list of images to be drawn below the nametag
### `Raycast`

View File

@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/numeric.h"
#include "constants.h"
#include "fontengine.h"
#include "guiscalingfilter.h"
#include "script/scripting_client.h"
#define CAMERA_OFFSET_STEP 200
@ -715,7 +716,7 @@ void Camera::drawNametags()
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);
core::rect<s32> bg_size(-2, 0, textsize.Width+2, textsize.Height);
core::rect<s32> bg_size(-2, 0, std::max(textsize.Width+2, (u32) nametag->images_dim.Width), textsize.Height + nametag->images_dim.Height);
auto bgcolor = nametag->getBgColor(m_show_nametag_backgrounds);
if (bgcolor.getAlpha() != 0)
@ -724,15 +725,29 @@ void Camera::drawNametags()
font->draw(
translate_string(utf8_to_wide(nametag->text)).c_str(),
size + screen_pos, nametag->textcolor);
v2s32 image_pos(screen_pos);
image_pos.Y += textsize.Height;
const video::SColor color(255, 255, 255, 255);
const video::SColor colors[] = {color, color, color, color};
for (video::ITexture *texture : nametag->images) {
core::dimension2di imgsize(texture->getOriginalSize());
core::rect<s32> rect(core::position2d<s32>(0, 0), imgsize);
draw2DImageFilterScaled(driver, texture, rect + image_pos, rect, NULL, colors, true);
image_pos += core::dimension2di(imgsize.Width, 0);
}
}
}
}
Nametag *Camera::addNametag(scene::ISceneNode *parent_node,
const std::string &text, video::SColor textcolor,
Optional<video::SColor> bgcolor, const v3f &pos)
Optional<video::SColor> bgcolor, const v3f &pos,
const std::vector<std::string> &images)
{
Nametag *nametag = new Nametag(parent_node, text, textcolor, bgcolor, pos);
Nametag *nametag = new Nametag(parent_node, text, textcolor, bgcolor, pos, m_client->tsrc(), images);
m_nametags.push_back(nametag);
return nametag;
}

View File

@ -39,18 +39,44 @@ struct Nametag
video::SColor textcolor;
Optional<video::SColor> bgcolor;
v3f pos;
ITextureSource *texture_source;
std::vector<video::ITexture *> images;
core::dimension2di images_dim;
Nametag(scene::ISceneNode *a_parent_node,
const std::string &text,
const video::SColor &textcolor,
const Optional<video::SColor> &bgcolor,
const v3f &pos):
const v3f &pos,
ITextureSource *tsrc,
const std::vector<std::string> &image_names):
parent_node(a_parent_node),
text(text),
textcolor(textcolor),
bgcolor(bgcolor),
pos(pos)
pos(pos),
texture_source(tsrc),
images(),
images_dim(0, 0)
{
setImages(image_names);
}
void setImages(const std::vector<std::string> &image_names)
{
images.clear();
images_dim = core::dimension2di(0, 0);
for (const std::string &image_name : image_names) {
video::ITexture *texture = texture_source->getTexture(image_name);
core::dimension2di imgsize(texture->getOriginalSize());
images_dim.Width += imgsize.Width;
if (images_dim.Height < imgsize.Height)
images_dim.Height = imgsize.Height;
images.push_back(texture);
}
}
video::SColor getBgColor(bool use_fallback) const
@ -185,7 +211,8 @@ public:
Nametag *addNametag(scene::ISceneNode *parent_node,
const std::string &text, video::SColor textcolor,
Optional<video::SColor> bgcolor, const v3f &pos);
Optional<video::SColor> bgcolor, const v3f &pos,
const std::vector<std::string> &image_names);
void removeNametag(Nametag *nametag);

View File

@ -962,13 +962,14 @@ void GenericCAO::updateNametag()
// Add nametag
m_nametag = m_client->getCamera()->addNametag(node,
m_prop.nametag, m_prop.nametag_color,
m_prop.nametag_bgcolor, pos);
m_prop.nametag_bgcolor, pos, nametag_images);
} 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->setImages(nametag_images);
}
}
@ -1863,6 +1864,9 @@ void GenericCAO::processMessage(const std::string &data)
// Same as 'ObjectRef::l_remove'
if (!m_is_player)
clearChildAttachments();
} else {
if (m_client->modsLoaded())
m_client->getScript()->on_object_hp_change(m_id);
}
} else if (cmd == AO_CMD_UPDATE_ARMOR_GROUPS) {
m_armor_groups.clear();

View File

@ -318,4 +318,6 @@ public:
void setProperties(ObjectProperties newprops);
void updateMeshCulling();
std::vector<std::string> nametag_images = {};
};

View File

@ -149,7 +149,7 @@ void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect,
bool selected)
{
if (selected) {
/* draw hihlighting around selected item */
/* draw highlighting around selected item */
if (use_hotbar_selected_image) {
core::rect<s32> imgrect2 = rect;
imgrect2.UpperLeftCorner.X -= (m_padding*2);

View File

@ -308,6 +308,21 @@ void ScriptApiClient::on_object_properties_change(s16 id)
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
}
void ScriptApiClient::on_object_hp_change(s16 id)
{
SCRIPTAPI_PRECHECKHEADER
// Get core.on_object_hp_change
lua_getglobal(L, "core");
lua_getfield(L, -1, "registered_on_object_hp_change");
// Push data
ClientObjectRef::create(L, id);
// Call functions
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
}
bool ScriptApiClient::on_inventory_open(Inventory *inventory)
{
SCRIPTAPI_PRECHECKHEADER

View File

@ -64,6 +64,7 @@ public:
bool on_play_sound(SimpleSoundSpec spec);
bool on_spawn_particle(struct ParticleParameters param);
void on_object_properties_change(s16 id);
void on_object_hp_change(s16 id);
bool on_inventory_open(Inventory *inventory);
void open_enderchest();

View File

@ -205,6 +205,23 @@ int ClientObjectRef::l_remove(lua_State *L)
return 0;
}
int ClientObjectRef::l_set_nametag_images(lua_State *L)
{
ClientObjectRef *ref = checkobject(L, 1);
GenericCAO *gcao = get_generic_cao(ref, L);
gcao->nametag_images.clear();
if(lua_istable(L, 2)){
lua_pushnil(L);
while(lua_next(L, 2) != 0){
gcao->nametag_images.push_back(lua_tostring(L, -1));
lua_pop(L, 1);
}
}
gcao->updateNametag();
return 0;
}
ClientObjectRef::ClientObjectRef(ClientActiveObject *object) : m_object(object)
{
}
@ -271,5 +288,7 @@ luaL_Reg ClientObjectRef::methods[] = {luamethod(ClientObjectRef, get_pos),
luamethod(ClientObjectRef, get_properties),
luamethod(ClientObjectRef, set_properties),
luamethod(ClientObjectRef, get_hp),
luamethod(ClientObjectRef, get_max_hp), luamethod(ClientObjectRef, punch),
luamethod(ClientObjectRef, rightclick), {0, 0}};
luamethod(ClientObjectRef, get_max_hp),
luamethod(ClientObjectRef, punch),
luamethod(ClientObjectRef, rightclick),
luamethod(ClientObjectRef, set_nametag_images), {0, 0}};

View File

@ -98,4 +98,7 @@ private:
// remove(self)
static int l_remove(lua_State *L);
// set_nametag_images(self, images)
static int l_set_nametag_images(lua_State *L);
};