diff --git a/doc/lua_api.txt b/doc/lua_api.txt index d3aaa309c..9a46c7b57 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -6880,6 +6880,10 @@ Player properties need to be saved manually. shaded = true, -- Setting this to 'false' disables diffuse lighting of entity + + show_on_minimap = false, + -- Defaults to true for players, false for other entities. + -- If set to true the entity will show as a marker on the minimap. } Entity definition diff --git a/src/client/camera.h b/src/client/camera.h index 3a59637bc..16a1961be 100644 --- a/src/client/camera.h +++ b/src/client/camera.h @@ -169,8 +169,6 @@ public: void removeNametag(Nametag *nametag); - const std::list &getNametags() { return m_nametags; } - void drawNametags(); inline void addArmInertia(f32 player_yaw); diff --git a/src/client/client.cpp b/src/client/client.cpp index 0bd98b256..af69d0ec9 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -326,6 +326,8 @@ Client::~Client() } delete m_minimap; + m_minimap = nullptr; + delete m_media_downloader; } diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index fae06554a..42184b08f 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -47,6 +47,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include "client/shader.h" +#include "client/minimap.h" class Settings; struct ToolCapabilities; @@ -566,6 +567,9 @@ void GenericCAO::removeFromScene(bool permanent) m_client->getCamera()->removeNametag(m_nametag); m_nametag = nullptr; } + + if (m_marker && m_client->getMinimap()) + m_client->getMinimap()->removeMarker(&m_marker); } void GenericCAO::addToScene(ITextureSource *tsrc) @@ -794,6 +798,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc) node->setParent(m_matrixnode); updateNametag(); + updateMarker(); updateNodePos(); updateAnimation(); updateBonePosition(); @@ -885,6 +890,23 @@ u16 GenericCAO::getLightPosition(v3s16 *pos) return 3; } +void GenericCAO::updateMarker() +{ + if (!m_prop.show_on_minimap) { + if (m_marker) + m_client->getMinimap()->removeMarker(&m_marker); + return; + } + + if (m_marker) + return; + + scene::ISceneNode *node = getSceneNode(); + if (!node) + return; + m_marker = m_client->getMinimap()->addMarker(node); +} + void GenericCAO::updateNametag() { if (m_is_local_player) // No nametag for local player @@ -1576,6 +1598,8 @@ void GenericCAO::processMessage(const std::string &data) u8 cmd = readU8(is); if (cmd == AO_CMD_SET_PROPERTIES) { ObjectProperties newprops; + newprops.show_on_minimap = m_is_player; // default + newprops.deSerialize(is); // Check what exactly changed @@ -1609,6 +1633,8 @@ void GenericCAO::processMessage(const std::string &data) if ((m_is_player && !m_is_local_player) && m_prop.nametag.empty()) m_prop.nametag = m_name; + if (m_is_local_player) + m_prop.show_on_minimap = false; if (expire_visuals) { expireVisuals(); @@ -1621,6 +1647,7 @@ void GenericCAO::processMessage(const std::string &data) updateTextures(m_current_texture_modifier); } updateNametag(); + updateMarker(); } } else if (cmd == AO_CMD_UPDATE_POSITION) { // Not sent by the server if this object is an attachment. diff --git a/src/client/content_cao.h b/src/client/content_cao.h index daf697767..435fc2931 100644 --- a/src/client/content_cao.h +++ b/src/client/content_cao.h @@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., class Camera; class Client; struct Nametag; +struct MinimapMarker; /* SmoothTranslator @@ -84,6 +85,7 @@ private: scene::IBillboardSceneNode *m_spritenode = nullptr; scene::IDummyTransformationSceneNode *m_matrixnode = nullptr; Nametag *m_nametag = nullptr; + MinimapMarker *m_marker = nullptr; v3f m_position = v3f(0.0f, 10.0f * BS, 0); v3f m_velocity; v3f m_acceleration; @@ -254,6 +256,8 @@ public: void updateNametag(); + void updateMarker(); + void updateNodePos(); void step(float dtime, ClientEnvironment *env); diff --git a/src/client/minimap.cpp b/src/client/minimap.cpp index 6bae408b4..d068ad5f7 100644 --- a/src/client/minimap.cpp +++ b/src/client/minimap.cpp @@ -252,6 +252,10 @@ Minimap::~Minimap() driver->removeTexture(data->minimap_overlay_square); driver->removeTexture(data->object_marker_red); + for (MinimapMarker *m : m_markers) + delete m; + m_markers.clear(); + delete data; delete m_minimap_update_thread; } @@ -678,21 +682,34 @@ void Minimap::drawMinimap(core::rect rect) { } } +MinimapMarker* Minimap::addMarker(scene::ISceneNode *parent_node) +{ + MinimapMarker *m = new MinimapMarker(parent_node); + m_markers.push_back(m); + return m; +} + +void Minimap::removeMarker(MinimapMarker **m) +{ + m_markers.remove(*m); + delete *m; + *m = nullptr; +} + void Minimap::updateActiveMarkers() { video::IImage *minimap_mask = data->minimap_shape_round ? data->minimap_mask_round : data->minimap_mask_square; - const std::list &nametags = client->getCamera()->getNametags(); - m_active_markers.clear(); + v3f cam_offset = intToFloat(client->getCamera()->getOffset(), BS); + v3s16 pos_offset = data->pos - v3s16(data->mode.map_size / 2, + data->mode.scan_height / 2, + data->mode.map_size / 2); - for (Nametag *nametag : nametags) { - v3s16 pos = floatToInt(nametag->parent_node->getAbsolutePosition() + - intToFloat(client->getCamera()->getOffset(), BS), BS); - pos -= data->pos - v3s16(data->mode.map_size / 2, - data->mode.scan_height / 2, - data->mode.map_size / 2); + for (MinimapMarker *marker : m_markers) { + v3s16 pos = floatToInt(marker->parent_node->getAbsolutePosition() + + cam_offset, BS) - pos_offset; if (pos.X < 0 || pos.X > data->mode.map_size || pos.Y < 0 || pos.Y > data->mode.scan_height || pos.Z < 0 || pos.Z > data->mode.map_size) { diff --git a/src/client/minimap.h b/src/client/minimap.h index 11374b116..4a2c462f8 100644 --- a/src/client/minimap.h +++ b/src/client/minimap.h @@ -48,6 +48,13 @@ struct MinimapModeDef { u16 scale; }; +struct MinimapMarker { + MinimapMarker(scene::ISceneNode *parent_node): + parent_node(parent_node) + { + } + scene::ISceneNode *parent_node; +}; struct MinimapPixel { //! The topmost node that the minimap displays. MapNode n; @@ -142,6 +149,9 @@ public: scene::SMeshBuffer *getMinimapMeshBuffer(); + MinimapMarker* addMarker(scene::ISceneNode *parent_node); + void removeMarker(MinimapMarker **marker); + void updateActiveMarkers(); void drawMinimap(); void drawMinimap(core::rect rect); @@ -162,5 +172,6 @@ private: u16 m_surface_mode_scan_height; f32 m_angle; std::mutex m_mutex; + std::list m_markers; std::list m_active_markers; }; diff --git a/src/object_properties.cpp b/src/object_properties.cpp index c31c667e7..f31773060 100644 --- a/src/object_properties.cpp +++ b/src/object_properties.cpp @@ -70,6 +70,7 @@ std::string ObjectProperties::dump() os << ", use_texture_alpha=" << use_texture_alpha; os << ", damage_texture_modifier=" << damage_texture_modifier; os << ", shaded=" << shaded; + os << ", show_on_minimap=" << show_on_minimap; return os.str(); } @@ -118,6 +119,7 @@ void ObjectProperties::serialize(std::ostream &os) const writeU8(os, use_texture_alpha); os << serializeString16(damage_texture_modifier); writeU8(os, shaded); + writeU8(os, show_on_minimap); // Add stuff only at the bottom. // Never remove anything, because we don't want new versions of this @@ -174,7 +176,11 @@ void ObjectProperties::deSerialize(std::istream &is) damage_texture_modifier = deSerializeString16(is); u8 tmp = readU8(is); if (is.eof()) - throw SerializationError(""); + return; shaded = tmp; + tmp = readU8(is); + if (is.eof()) + return; + show_on_minimap = tmp; } catch (SerializationError &e) {} } diff --git a/src/object_properties.h b/src/object_properties.h index f010c1daf..adb483527 100644 --- a/src/object_properties.h +++ b/src/object_properties.h @@ -62,6 +62,7 @@ struct ObjectProperties float zoom_fov = 0.0f; bool use_texture_alpha = false; bool shaded = true; + bool show_on_minimap = false; ObjectProperties(); std::string dump(); diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index a95cf94a1..e3cb9042e 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -331,6 +331,7 @@ void read_object_properties(lua_State *L, int index, getfloatfield(L, -1, "zoom_fov", prop->zoom_fov); getboolfield(L, -1, "use_texture_alpha", prop->use_texture_alpha); getboolfield(L, -1, "shaded", prop->shaded); + getboolfield(L, -1, "show_on_minimap", prop->show_on_minimap); getstringfield(L, -1, "damage_texture_modifier", prop->damage_texture_modifier); } @@ -419,6 +420,8 @@ void push_object_properties(lua_State *L, ObjectProperties *prop) lua_setfield(L, -2, "shaded"); lua_pushlstring(L, prop->damage_texture_modifier.c_str(), prop->damage_texture_modifier.size()); lua_setfield(L, -2, "damage_texture_modifier"); + lua_pushboolean(L, prop->show_on_minimap); + lua_setfield(L, -2, "show_on_minimap"); } /******************************************************************************/ diff --git a/src/server/player_sao.cpp b/src/server/player_sao.cpp index 344d18a20..9fb53380c 100644 --- a/src/server/player_sao.cpp +++ b/src/server/player_sao.cpp @@ -55,6 +55,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, session_t p m_prop.backface_culling = false; m_prop.makes_footstep_sound = true; m_prop.stepheight = PLAYER_DEFAULT_STEPHEIGHT * BS; + m_prop.show_on_minimap = true; m_hp = m_prop.hp_max; m_breath = m_prop.breath_max; // Disable zoom in survival mode using a value of 0