From 08ee9794fbc0960a8aab1af21d34f40685809e75 Mon Sep 17 00:00:00 2001 From: JDiaz Date: Mon, 11 Jan 2021 18:03:31 +0100 Subject: Implement on_rightclickplayer callback (#10775) Co-authored-by: rubenwardy --- src/script/cpp_api/s_player.cpp | 13 +++++++++++++ src/script/cpp_api/s_player.h | 1 + 2 files changed, 14 insertions(+) (limited to 'src/script/cpp_api') diff --git a/src/script/cpp_api/s_player.cpp b/src/script/cpp_api/s_player.cpp index 712120c61..d3e6138dc 100644 --- a/src/script/cpp_api/s_player.cpp +++ b/src/script/cpp_api/s_player.cpp @@ -77,6 +77,19 @@ bool ScriptApiPlayer::on_punchplayer(ServerActiveObject *player, return readParam(L, -1); } +void ScriptApiPlayer::on_rightclickplayer(ServerActiveObject *player, + ServerActiveObject *clicker) +{ + SCRIPTAPI_PRECHECKHEADER + // Get core.registered_on_rightclickplayers + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_rightclickplayers"); + // Call callbacks + objectrefGetOrCreate(L, player); + objectrefGetOrCreate(L, clicker); + runCallbacks(2, RUN_CALLBACKS_MODE_FIRST); +} + s32 ScriptApiPlayer::on_player_hpchange(ServerActiveObject *player, s32 hp_change, const PlayerHPChangeReason &reason) { diff --git a/src/script/cpp_api/s_player.h b/src/script/cpp_api/s_player.h index a337f975b..c0f141862 100644 --- a/src/script/cpp_api/s_player.h +++ b/src/script/cpp_api/s_player.h @@ -47,6 +47,7 @@ public: bool on_punchplayer(ServerActiveObject *player, ServerActiveObject *hitter, float time_from_last_punch, const ToolCapabilities *toolcap, v3f dir, s16 damage); + void on_rightclickplayer(ServerActiveObject *player, ServerActiveObject *clicker); s32 on_player_hpchange(ServerActiveObject *player, s32 hp_change, const PlayerHPChangeReason &reason); void on_playerReceiveFields(ServerActiveObject *player, -- cgit v1.2.3 From 4c76239818f5159314f30883f98b977d30aaa26c Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Fri, 22 Jan 2021 15:09:26 +0000 Subject: Remove dead code (#10845) --- src/client/client.cpp | 20 ----- src/client/client.h | 7 -- src/client/clientenvironment.cpp | 7 -- src/client/hud.cpp | 2 - src/client/mapblock_mesh.cpp | 7 -- src/client/mapblock_mesh.h | 2 - src/client/mesh_generator_thread.h | 1 - src/client/minimap.h | 1 - src/client/tile.cpp | 2 - src/emerge.cpp | 9 +-- src/exceptions.h | 5 -- src/filesys.cpp | 15 ---- src/filesys.h | 3 - src/gui/guiButtonItemImage.cpp | 1 - src/gui/guiButtonItemImage.h | 1 - src/gui/guiChatConsole.h | 2 - src/gui/guiEngine.cpp | 2 - src/gui/guiFormSpecMenu.cpp | 4 +- src/gui/guiFormSpecMenu.h | 2 +- src/map.cpp | 160 ------------------------------------- src/map.h | 8 +- src/mapblock.h | 9 --- src/mapgen/mapgen_v6.cpp | 3 +- src/network/networkexceptions.h | 8 +- src/pathfinder.cpp | 6 +- src/script/cpp_api/s_async.cpp | 29 ------- src/script/cpp_api/s_async.h | 6 -- src/server.h | 3 - src/server/player_sao.h | 1 - src/server/serveractiveobject.h | 3 - src/serverenvironment.h | 10 +-- 31 files changed, 8 insertions(+), 331 deletions(-) (limited to 'src/script/cpp_api') diff --git a/src/client/client.cpp b/src/client/client.cpp index af69d0ec9..6577c287d 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -159,20 +159,6 @@ void Client::loadMods() scanModIntoMemory(BUILTIN_MOD_NAME, getBuiltinLuaPath()); m_script->loadModFromMemory(BUILTIN_MOD_NAME); - // TODO Uncomment when server-sent CSM and verifying of builtin are complete - /* - // Don't load client-provided mods if disabled by server - if (checkCSMRestrictionFlag(CSMRestrictionFlags::CSM_RF_LOAD_CLIENT_MODS)) { - warningstream << "Client-provided mod loading is disabled by server." << - std::endl; - // If builtin integrity is wrong, disconnect user - if (!checkBuiltinIntegrity()) { - // TODO disconnect user - } - return; - } - */ - ClientModConfiguration modconf(getClientModsLuaPath()); m_mods = modconf.getMods(); // complain about mods with unsatisfied dependencies @@ -216,12 +202,6 @@ void Client::loadMods() m_script->on_minimap_ready(m_minimap); } -bool Client::checkBuiltinIntegrity() -{ - // TODO - return true; -} - void Client::scanModSubfolder(const std::string &mod_name, const std::string &mod_path, std::string mod_subpath) { diff --git a/src/client/client.h b/src/client/client.h index bffdc7ec6..25a1b97ba 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -415,11 +415,6 @@ public: return m_csm_restriction_flags & flag; } - u32 getCSMNodeRangeLimit() const - { - return m_csm_restriction_noderange; - } - inline std::unordered_map &getHUDTranslationMap() { return m_hud_server_to_client; @@ -437,7 +432,6 @@ public: } private: void loadMods(); - bool checkBuiltinIntegrity(); // Virtual methods from con::PeerHandler void peerAdded(con::Peer *peer) override; @@ -587,7 +581,6 @@ private: // Client modding ClientScripting *m_script = nullptr; - bool m_modding_enabled; std::unordered_map m_mod_storages; float m_mod_storage_save_timer = 10.0f; std::vector m_mods; diff --git a/src/client/clientenvironment.cpp b/src/client/clientenvironment.cpp index da1e6e9c7..fc7cbe254 100644 --- a/src/client/clientenvironment.cpp +++ b/src/client/clientenvironment.cpp @@ -334,13 +334,6 @@ GenericCAO* ClientEnvironment::getGenericCAO(u16 id) return NULL; } -bool isFreeClientActiveObjectId(const u16 id, - ClientActiveObjectMap &objects) -{ - return id != 0 && objects.find(id) == objects.end(); - -} - u16 ClientEnvironment::addActiveObject(ClientActiveObject *object) { // Register object. If failed return zero id diff --git a/src/client/hud.cpp b/src/client/hud.cpp index e956c2738..46736b325 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -571,8 +571,6 @@ void Hud::drawCompassTranslate(HudElement *e, video::ITexture *texture, void Hud::drawCompassRotate(HudElement *e, video::ITexture *texture, const core::rect &rect, int angle) { - core::dimension2di imgsize(texture->getOriginalSize()); - core::rect oldViewPort = driver->getViewPort(); core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION); core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW); diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp index 4c43fcb61..d78a86b2d 100644 --- a/src/client/mapblock_mesh.cpp +++ b/src/client/mapblock_mesh.cpp @@ -1176,13 +1176,6 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): } if (m_mesh[layer]) { -#if 0 - // Usually 1-700 faces and 1-7 materials - std::cout << "Updated MapBlock has " << fastfaces_new.size() - << " faces and uses " << m_mesh[layer]->getMeshBufferCount() - << " materials (meshbuffers)" << std::endl; -#endif - // Use VBO for mesh (this just would set this for ever buffer) if (m_enable_vbo) m_mesh[layer]->setHardwareMappingHint(scene::EHM_STATIC); diff --git a/src/client/mapblock_mesh.h b/src/client/mapblock_mesh.h index 0308b8161..3b17c4af9 100644 --- a/src/client/mapblock_mesh.h +++ b/src/client/mapblock_mesh.h @@ -125,8 +125,6 @@ public: m_animation_force_timer--; } - void updateCameraOffset(v3s16 camera_offset); - private: scene::IMesh *m_mesh[MAX_TILE_LAYERS]; MinimapMapblock *m_minimap_mapblock; diff --git a/src/client/mesh_generator_thread.h b/src/client/mesh_generator_thread.h index f3c5e7da8..4371b8390 100644 --- a/src/client/mesh_generator_thread.h +++ b/src/client/mesh_generator_thread.h @@ -40,7 +40,6 @@ struct QueuedMeshUpdate { v3s16 p = v3s16(-1337, -1337, -1337); bool ack_block_to_server = false; - bool urgent = false; int crack_level = -1; v3s16 crack_pos; MeshMakeData *data = nullptr; // This is generated in MeshUpdateQueue::pop() diff --git a/src/client/minimap.h b/src/client/minimap.h index 4a2c462f8..87c9668ee 100644 --- a/src/client/minimap.h +++ b/src/client/minimap.h @@ -138,7 +138,6 @@ public: size_t getMaxModeIndex() const { return m_modes.size() - 1; }; void nextMode(); - void setModesFromString(std::string modes_string); MinimapModeDef getModeDef() const { return data->mode; } video::ITexture *getMinimapTexture(); diff --git a/src/client/tile.cpp b/src/client/tile.cpp index 37836d0df..aad956ada 100644 --- a/src/client/tile.cpp +++ b/src/client/tile.cpp @@ -429,7 +429,6 @@ private: // Cached settings needed for making textures from meshes bool m_setting_trilinear_filter; bool m_setting_bilinear_filter; - bool m_setting_anisotropic_filter; }; IWritableTextureSource *createTextureSource() @@ -450,7 +449,6 @@ TextureSource::TextureSource() // for these settings to take effect m_setting_trilinear_filter = g_settings->getBool("trilinear_filter"); m_setting_bilinear_filter = g_settings->getBool("bilinear_filter"); - m_setting_anisotropic_filter = g_settings->getBool("anisotropic_filter"); } TextureSource::~TextureSource() diff --git a/src/emerge.cpp b/src/emerge.cpp index 12e407797..e0dc5628e 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -396,14 +396,7 @@ int EmergeManager::getGroundLevelAtPoint(v2s16 p) // TODO(hmmmm): Move this to ServerMap bool EmergeManager::isBlockUnderground(v3s16 blockpos) { -#if 0 - v2s16 p = v2s16((blockpos.X * MAP_BLOCKSIZE) + MAP_BLOCKSIZE / 2, - (blockpos.Y * MAP_BLOCKSIZE) + MAP_BLOCKSIZE / 2); - int ground_level = getGroundLevelAtPoint(p); - return blockpos.Y * (MAP_BLOCKSIZE + 1) <= min(water_level, ground_level); -#endif - - // Use a simple heuristic; the above method is wildly inaccurate anyway. + // Use a simple heuristic return blockpos.Y * (MAP_BLOCKSIZE + 1) <= mgparams->water_level; } diff --git a/src/exceptions.h b/src/exceptions.h index c54307653..a558adc5d 100644 --- a/src/exceptions.h +++ b/src/exceptions.h @@ -72,11 +72,6 @@ public: SettingNotFoundException(const std::string &s): BaseException(s) {} }; -class InvalidFilenameException : public BaseException { -public: - InvalidFilenameException(const std::string &s): BaseException(s) {} -}; - class ItemNotFoundException : public BaseException { public: ItemNotFoundException(const std::string &s): BaseException(s) {} diff --git a/src/filesys.cpp b/src/filesys.cpp index 28a33f4d0..eeba0c564 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -401,21 +401,6 @@ void GetRecursiveSubPaths(const std::string &path, } } -bool DeletePaths(const std::vector &paths) -{ - bool success = true; - // Go backwards to succesfully delete the output of GetRecursiveSubPaths - for(int i=paths.size()-1; i>=0; i--){ - const std::string &path = paths[i]; - bool did = DeleteSingleFileOrEmptyDirectory(path); - if(!did){ - errorstream<<"Failed to delete "< &ignore = {}); -// Tries to delete all, returns false if any failed -bool DeletePaths(const std::vector &paths); - // Only pass full paths to this one. True on success. bool RecursiveDeleteContent(const std::string &path); diff --git a/src/gui/guiButtonItemImage.cpp b/src/gui/guiButtonItemImage.cpp index d8b9042ac..39272fe37 100644 --- a/src/gui/guiButtonItemImage.cpp +++ b/src/gui/guiButtonItemImage.cpp @@ -39,7 +39,6 @@ GUIButtonItemImage::GUIButtonItemImage(gui::IGUIEnvironment *environment, item, getActiveFont(), client); sendToBack(m_image); - m_item_name = item; m_client = client; } diff --git a/src/gui/guiButtonItemImage.h b/src/gui/guiButtonItemImage.h index aad923bda..b90ac757e 100644 --- a/src/gui/guiButtonItemImage.h +++ b/src/gui/guiButtonItemImage.h @@ -42,7 +42,6 @@ public: Client *client); private: - std::string m_item_name; Client *m_client; GUIItemImage *m_image; }; diff --git a/src/gui/guiChatConsole.h b/src/gui/guiChatConsole.h index 204f9f9cc..896342ab0 100644 --- a/src/gui/guiChatConsole.h +++ b/src/gui/guiChatConsole.h @@ -68,8 +68,6 @@ public: // Irrlicht draw method virtual void draw(); - bool canTakeFocus(gui::IGUIElement* element) { return false; } - virtual bool OnEvent(const SEvent& event); virtual void setVisible(bool visible); diff --git a/src/gui/guiEngine.cpp b/src/gui/guiEngine.cpp index c5ad5c323..6e2c2b053 100644 --- a/src/gui/guiEngine.cpp +++ b/src/gui/guiEngine.cpp @@ -486,8 +486,6 @@ void GUIEngine::drawHeader(video::IVideoDriver *driver) splashrect += v2s32((screensize.Width/2)-(splashsize.X/2), ((free_space/2)-splashsize.Y/2)+10); - video::SColor bgcolor(255,50,50,50); - draw2DImageFilterScaled(driver, texture, splashrect, core::rect(core::position2d(0,0), core::dimension2di(texture->getOriginalSize())), diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index 973fc60a8..4415bdd3a 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -3505,8 +3505,6 @@ bool GUIFormSpecMenu::getAndroidUIInput() GUIInventoryList::ItemSpec GUIFormSpecMenu::getItemAtPos(v2s32 p) const { - core::rect imgrect(0, 0, imgsize.X, imgsize.Y); - for (const GUIInventoryList *e : m_inventorylists) { s32 item_index = e->getItemIndexAtPos(p); if (item_index != -1) @@ -3837,7 +3835,7 @@ ItemStack GUIFormSpecMenu::verifySelectedItem() return ItemStack(); } -void GUIFormSpecMenu::acceptInput(FormspecQuitMode quitmode=quit_mode_no) +void GUIFormSpecMenu::acceptInput(FormspecQuitMode quitmode) { if(m_text_dst) { diff --git a/src/gui/guiFormSpecMenu.h b/src/gui/guiFormSpecMenu.h index 37106cb65..d658aba7b 100644 --- a/src/gui/guiFormSpecMenu.h +++ b/src/gui/guiFormSpecMenu.h @@ -253,7 +253,7 @@ public: void updateSelectedItem(); ItemStack verifySelectedItem(); - void acceptInput(FormspecQuitMode quitmode); + void acceptInput(FormspecQuitMode quitmode=quit_mode_no); bool preprocessEvent(const SEvent& event); bool OnEvent(const SEvent& event); bool doPause; diff --git a/src/map.cpp b/src/map.cpp index 6a7cadca5..aff545921 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -530,23 +530,6 @@ void Map::transformLiquids(std::map &modified_blocks, u32 liquid_loop_max = g_settings->getS32("liquid_loop_max"); u32 loop_max = liquid_loop_max; -#if 0 - - /* If liquid_loop_max is not keeping up with the queue size increase - * loop_max up to a maximum of liquid_loop_max * dedicated_server_step. - */ - if (m_transforming_liquid.size() > loop_max * 2) { - // "Burst" mode - float server_step = g_settings->getFloat("dedicated_server_step"); - if (m_transforming_liquid_loop_count_multiplier - 1.0 < server_step) - m_transforming_liquid_loop_count_multiplier *= 1.0 + server_step / 10; - } else { - m_transforming_liquid_loop_count_multiplier = 1.0; - } - - loop_max *= m_transforming_liquid_loop_count_multiplier; -#endif - while (m_transforming_liquid.size() != 0) { // This should be done here so that it is done when continue is used @@ -1302,18 +1285,6 @@ ServerMap::~ServerMap() */ delete dbase; delete dbase_ro; - -#if 0 - /* - Free all MapChunks - */ - core::map::Iterator i = m_chunks.getIterator(); - for(; i.atEnd() == false; i++) - { - MapChunk *chunk = i.getNode()->getValue(); - delete chunk; - } -#endif } MapgenParams *ServerMap::getMapgenParams() @@ -1402,25 +1373,6 @@ bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data) data->vmanip = new MMVManip(this); data->vmanip->initialEmerge(full_bpmin, full_bpmax); - // Note: we may need this again at some point. -#if 0 - // Ensure none of the blocks to be generated were marked as - // containing CONTENT_IGNORE - for (s16 z = blockpos_min.Z; z <= blockpos_max.Z; z++) { - for (s16 y = blockpos_min.Y; y <= blockpos_max.Y; y++) { - for (s16 x = blockpos_min.X; x <= blockpos_max.X; x++) { - core::map::Node *n; - n = data->vmanip->m_loaded_blocks.find(v3s16(x, y, z)); - if (n == NULL) - continue; - u8 flags = n->getValue(); - flags &= ~VMANIP_BLOCK_CONTAINS_CIGNORE; - n->setValue(flags); - } - } - } -#endif - // Data is ready now. return true; } @@ -1431,8 +1383,6 @@ void ServerMap::finishBlockMake(BlockMakeData *data, v3s16 bpmin = data->blockpos_min; v3s16 bpmax = data->blockpos_max; - v3s16 extra_borders(1, 1, 1); - bool enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info; EMERGE_DBG_OUT("finishBlockMake(): " PP(bpmin) " - " PP(bpmax)); @@ -1525,116 +1475,6 @@ MapSector *ServerMap::createSector(v2s16 p2d) return sector; } -#if 0 -/* - This is a quick-hand function for calling makeBlock(). -*/ -MapBlock * ServerMap::generateBlock( - v3s16 p, - std::map &modified_blocks -) -{ - bool enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info"); - - TimeTaker timer("generateBlock"); - - //MapBlock *block = original_dummy; - - v2s16 p2d(p.X, p.Z); - v2s16 p2d_nodes = p2d * MAP_BLOCKSIZE; - - /* - Do not generate over-limit - */ - if(blockpos_over_limit(p)) - { - infostream<makeChunk(&data); - //mapgen::make_block(&data); - - if(enable_mapgen_debug_info == false) - t.stop(true); // Hide output - } - - /* - Blit data back on map, update lighting, add mobs and whatever this does - */ - finishBlockMake(&data, modified_blocks); - - /* - Get central block - */ - MapBlock *block = getBlockNoCreateNoEx(p); - -#if 0 - /* - Check result - */ - if(block) - { - bool erroneus_content = false; - for(s16 z0=0; z0getNode(p); - if(n.getContent() == CONTENT_IGNORE) - { - infostream<<"CONTENT_IGNORE at " - <<"("<setNode(v3s16(x0,y0,z0), n); - } - } - } -#endif - - if(enable_mapgen_debug_info == false) - timer.stop(true); // Hide output - - return block; -} -#endif - MapBlock * ServerMap::createBlock(v3s16 p) { /* diff --git a/src/map.h b/src/map.h index c8bae9451..e68795c4a 100644 --- a/src/map.h +++ b/src/map.h @@ -417,13 +417,7 @@ private: bool m_map_saving_enabled; int m_map_compression_level; -#if 0 - // Chunk size in MapSectors - // If 0, chunks are disabled. - s16 m_chunksize; - // Chunks - core::map m_chunks; -#endif + std::set m_chunks_in_progress; /* diff --git a/src/mapblock.h b/src/mapblock.h index 641a1b69b..7b82301e9 100644 --- a/src/mapblock.h +++ b/src/mapblock.h @@ -340,15 +340,6 @@ public: // is not valid on this MapBlock. bool isValidPositionParent(v3s16 p); MapNode getNodeParent(v3s16 p, bool *is_valid_position = NULL); - void setNodeParent(v3s16 p, MapNode & n); - - inline void drawbox(s16 x0, s16 y0, s16 z0, s16 w, s16 h, s16 d, MapNode node) - { - for (u16 z = 0; z < d; z++) - for (u16 y = 0; y < h; y++) - for (u16 x = 0; x < w; x++) - setNode(x0 + x, y0 + y, z0 + z, node); - } // Copies data to VoxelManipulator to getPosRelative() void copyTo(VoxelManipulator &dst); diff --git a/src/mapgen/mapgen_v6.cpp b/src/mapgen/mapgen_v6.cpp index e04180f96..bce9cee81 100644 --- a/src/mapgen/mapgen_v6.cpp +++ b/src/mapgen/mapgen_v6.cpp @@ -792,7 +792,7 @@ void MapgenV6::flowMud(s16 &mudflow_minpos, s16 &mudflow_maxpos) v3s16(0, 0, -1), // Front v3s16(-1, 0, 0), // Left }; - + // Iterate twice for (s16 k = 0; k < 2; k++) { for (s16 z = mudflow_minpos; z <= mudflow_maxpos; z++) @@ -1055,7 +1055,6 @@ void MapgenV6::growGrass() // Add surface nodes MapNode n_dirt_with_grass(c_dirt_with_grass); MapNode n_dirt_with_snow(c_dirt_with_snow); MapNode n_snowblock(c_snowblock); - MapNode n_snow(c_snow); const v3s16 &em = vm->m_area.getExtent(); u32 index = 0; diff --git a/src/network/networkexceptions.h b/src/network/networkexceptions.h index f4913928c..58a3bb490 100644 --- a/src/network/networkexceptions.h +++ b/src/network/networkexceptions.h @@ -56,12 +56,6 @@ public: InvalidIncomingDataException(const char *s) : BaseException(s) {} }; -class InvalidOutgoingDataException : public BaseException -{ -public: - InvalidOutgoingDataException(const char *s) : BaseException(s) {} -}; - class NoIncomingDataException : public BaseException { public: @@ -103,4 +97,4 @@ class SendFailedException : public BaseException { public: SendFailedException(const std::string &s) : BaseException(s) {} -}; \ No newline at end of file +}; diff --git a/src/pathfinder.cpp b/src/pathfinder.cpp index 3f0b98c10..1cb84997a 100644 --- a/src/pathfinder.cpp +++ b/src/pathfinder.cpp @@ -157,9 +157,8 @@ public: ArrayGridNodeContainer(Pathfinder *pathf, v3s16 dimensions); virtual PathGridnode &access(v3s16 p); -private: - v3s16 m_dimensions; +private: int m_x_stride; int m_y_stride; std::vector m_nodes_array; @@ -306,8 +305,6 @@ private: int m_max_index_y = 0; /**< max index of search area in y direction */ int m_max_index_z = 0; /**< max index of search area in z direction */ - - int m_searchdistance = 0; /**< max distance to search in each direction */ int m_maxdrop = 0; /**< maximum number of blocks a path may drop */ int m_maxjump = 0; /**< maximum number of blocks a path may jump */ int m_min_target_distance = 0; /**< current smalest path to target */ @@ -619,7 +616,6 @@ std::vector Pathfinder::getPath(v3s16 source, std::vector retval; //initialization - m_searchdistance = searchdistance; m_maxjump = max_jump; m_maxdrop = max_drop; m_start = source; diff --git a/src/script/cpp_api/s_async.cpp b/src/script/cpp_api/s_async.cpp index 5f1f9297e..0619b32c0 100644 --- a/src/script/cpp_api/s_async.cpp +++ b/src/script/cpp_api/s_async.cpp @@ -157,35 +157,6 @@ void AsyncEngine::step(lua_State *L) lua_pop(L, 2); // Pop core and error handler } -/******************************************************************************/ -void AsyncEngine::pushFinishedJobs(lua_State* L) { - // Result Table - MutexAutoLock l(resultQueueMutex); - - unsigned int index = 1; - lua_createtable(L, resultQueue.size(), 0); - int top = lua_gettop(L); - - while (!resultQueue.empty()) { - LuaJobInfo jobDone = resultQueue.front(); - resultQueue.pop_front(); - - lua_createtable(L, 0, 2); // Pre-allocate space for two map fields - int top_lvl2 = lua_gettop(L); - - lua_pushstring(L, "jobid"); - lua_pushnumber(L, jobDone.id); - lua_settable(L, top_lvl2); - - lua_pushstring(L, "retval"); - lua_pushlstring(L, jobDone.serializedResult.data(), - jobDone.serializedResult.size()); - lua_settable(L, top_lvl2); - - lua_rawseti(L, top, index++); - } -} - /******************************************************************************/ void AsyncEngine::prepareEnvironment(lua_State* L, int top) { diff --git a/src/script/cpp_api/s_async.h b/src/script/cpp_api/s_async.h index b1f4bf45f..99a4f891c 100644 --- a/src/script/cpp_api/s_async.h +++ b/src/script/cpp_api/s_async.h @@ -98,12 +98,6 @@ public: */ void step(lua_State *L); - /** - * Push a list of finished jobs onto the stack - * @param L The Lua stack - */ - void pushFinishedJobs(lua_State *L); - protected: /** * Get a Job from queue to be processed diff --git a/src/server.h b/src/server.h index 4b3ac5cf7..a7e85d0e1 100644 --- a/src/server.h +++ b/src/server.h @@ -564,9 +564,6 @@ private: // Craft definition manager IWritableCraftDefManager *m_craftdef; - // Event manager - EventManager *m_event; - // Mods std::unique_ptr m_modmgr; diff --git a/src/server/player_sao.h b/src/server/player_sao.h index 6aee8d5aa..8e2d8803f 100644 --- a/src/server/player_sao.h +++ b/src/server/player_sao.h @@ -114,7 +114,6 @@ public: void rightClick(ServerActiveObject *clicker); void setHP(s32 hp, const PlayerHPChangeReason &reason); void setHPRaw(u16 hp) { m_hp = hp; } - s16 readDamage(); u16 getBreath() const { return m_breath; } void setBreath(const u16 breath, bool send = true); diff --git a/src/server/serveractiveobject.h b/src/server/serveractiveobject.h index 25653a1ad..51f445914 100644 --- a/src/server/serveractiveobject.h +++ b/src/server/serveractiveobject.h @@ -162,8 +162,6 @@ public: {} virtual const ItemGroupList &getArmorGroups() const { static ItemGroupList rv; return rv; } - virtual void setPhysicsOverride(float physics_override_speed, float physics_override_jump, float physics_override_gravity) - {} virtual void setAnimation(v2f frames, float frame_speed, float frame_blend, bool frame_loop) {} virtual void getAnimation(v2f *frames, float *frame_speed, float *frame_blend, bool *frame_loop) @@ -206,7 +204,6 @@ public: } std::string generateUpdateInfantCommand(u16 infant_id, u16 protocol_version); - std::string generateUpdateNametagAttributesCommand(const video::SColor &color) const; void dumpAOMessagesToQueue(std::queue &queue); diff --git a/src/serverenvironment.h b/src/serverenvironment.h index c76d34a37..a11c814ed 100644 --- a/src/serverenvironment.h +++ b/src/serverenvironment.h @@ -190,14 +190,6 @@ enum ClearObjectsMode { CLEAR_OBJECTS_MODE_QUICK, }; -/* - The server-side environment. - - This is not thread-safe. Server uses an environment mutex. -*/ - -typedef std::unordered_map ServerActiveObjectMap; - class ServerEnvironment : public Environment { public: @@ -331,7 +323,7 @@ public: { return m_ao_manager.getObjectsInsideRadius(pos, radius, objects, include_obj_cb); } - + // Find all active objects inside a box void getObjectsInArea(std::vector &objects, const aabb3f &box, std::function include_obj_cb) -- cgit v1.2.3 From 83229921e5f378625d9ef63ede3dffbe778e1798 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sun, 17 Jan 2021 01:56:50 +0100 Subject: Rework use_texture_alpha to provide three opaque/clip/blend modes The change that turns nodeboxes and meshes opaque when possible is kept, as is the compatibility code that warns modders to adjust their nodedefs. --- builtin/game/features.lua | 1 + doc/lua_api.txt | 18 +++++-- src/nodedef.cpp | 110 ++++++++++++++++++++++++++-------------- src/nodedef.h | 56 +++++++++++++++----- src/script/common/c_content.cpp | 32 ++++++++---- src/script/cpp_api/s_node.cpp | 8 +++ src/script/cpp_api/s_node.h | 1 + src/unittest/test.cpp | 4 +- 8 files changed, 164 insertions(+), 66 deletions(-) (limited to 'src/script/cpp_api') diff --git a/builtin/game/features.lua b/builtin/game/features.lua index 4d3c90ff0..36ff1f0b0 100644 --- a/builtin/game/features.lua +++ b/builtin/game/features.lua @@ -18,6 +18,7 @@ core.features = { pathfinder_works = true, object_step_has_moveresult = true, direct_velocity_on_players = true, + use_texture_alpha_string_modes = true, } function core.has_feature(arg) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index cfc150edc..8156f785a 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -4386,6 +4386,8 @@ Utilities object_step_has_moveresult = true, -- Whether get_velocity() and add_velocity() can be used on players (5.4.0) direct_velocity_on_players = true, + -- nodedef's use_texture_alpha accepts new string modes (5.4.0) + use_texture_alpha_string_modes = true, } * `minetest.has_feature(arg)`: returns `boolean, missing_features` @@ -7340,10 +7342,18 @@ Used by `minetest.register_node`. -- If the node has a palette, then this setting only has an effect in -- the inventory and on the wield item. - use_texture_alpha = false, - -- Use texture's alpha channel - -- If this is set to false, the node will be rendered fully opaque - -- regardless of any texture transparency. + use_texture_alpha = ..., + -- Specifies how the texture's alpha channel will be used for rendering. + -- possible values: + -- * "opaque": Node is rendered opaque regardless of alpha channel + -- * "clip": A given pixel is either fully see-through or opaque + -- depending on the alpha channel being below/above 50% in value + -- * "blend": The alpha channel specifies how transparent a given pixel + -- of the rendered node is + -- The default is "opaque" for drawtypes normal, liquid and flowingliquid; + -- "clip" otherwise. + -- If set to a boolean value (deprecated): true either sets it to blend + -- or clip, false sets it to clip or opaque mode depending on the drawtype. palette = "palette.png", -- The node's `param2` is used to select a pixel from the image. diff --git a/src/nodedef.cpp b/src/nodedef.cpp index b2cfd1f87..57d4c008f 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -360,7 +360,7 @@ void ContentFeatures::reset() i = TileDef(); for (auto &j : tiledef_special) j = TileDef(); - alpha = 255; + alpha = ALPHAMODE_OPAQUE; post_effect_color = video::SColor(0, 0, 0, 0); param_type = CPT_NONE; param_type_2 = CPT2_NONE; @@ -405,6 +405,31 @@ void ContentFeatures::reset() node_dig_prediction = "air"; } +void ContentFeatures::setAlphaFromLegacy(u8 legacy_alpha) +{ + // No special handling for nodebox/mesh here as it doesn't make sense to + // throw warnings when the server is too old to support the "correct" way + switch (drawtype) { + case NDT_NORMAL: + alpha = legacy_alpha == 255 ? ALPHAMODE_OPAQUE : ALPHAMODE_CLIP; + break; + case NDT_LIQUID: + case NDT_FLOWINGLIQUID: + alpha = legacy_alpha == 255 ? ALPHAMODE_OPAQUE : ALPHAMODE_BLEND; + break; + default: + alpha = legacy_alpha == 255 ? ALPHAMODE_CLIP : ALPHAMODE_BLEND; + break; + } +} + +u8 ContentFeatures::getAlphaForLegacy() const +{ + // This is so simple only because 255 and 0 mean wildly different things + // depending on drawtype... + return alpha == ALPHAMODE_OPAQUE ? 255 : 0; +} + void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const { const u8 version = CONTENTFEATURES_VERSION; @@ -433,7 +458,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const for (const TileDef &td : tiledef_special) { td.serialize(os, protocol_version); } - writeU8(os, alpha); + writeU8(os, getAlphaForLegacy()); writeU8(os, color.getRed()); writeU8(os, color.getGreen()); writeU8(os, color.getBlue()); @@ -489,6 +514,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const os << serializeString16(node_dig_prediction); writeU8(os, leveled_max); + writeU8(os, alpha); } void ContentFeatures::deSerialize(std::istream &is) @@ -524,7 +550,7 @@ void ContentFeatures::deSerialize(std::istream &is) throw SerializationError("unsupported CF_SPECIAL_COUNT"); for (TileDef &td : tiledef_special) td.deSerialize(is, version, drawtype); - alpha = readU8(is); + setAlphaFromLegacy(readU8(is)); color.setRed(readU8(is)); color.setGreen(readU8(is)); color.setBlue(readU8(is)); @@ -582,10 +608,16 @@ void ContentFeatures::deSerialize(std::istream &is) try { node_dig_prediction = deSerializeString16(is); - u8 tmp_leveled_max = readU8(is); + + u8 tmp = readU8(is); if (is.eof()) /* readU8 doesn't throw exceptions so we have to do this */ throw SerializationError(""); - leveled_max = tmp_leveled_max; + leveled_max = tmp; + + tmp = readU8(is); + if (is.eof()) + throw SerializationError(""); + alpha = static_cast(tmp); } catch(SerializationError &e) {}; } @@ -677,6 +709,7 @@ bool ContentFeatures::textureAlphaCheck(ITextureSource *tsrc, const TileDef *til video::IVideoDriver *driver = RenderingEngine::get_video_driver(); static thread_local bool long_warning_printed = false; std::set seen; + for (int i = 0; i < length; i++) { if (seen.find(tiles[i].name) != seen.end()) continue; @@ -701,20 +734,21 @@ bool ContentFeatures::textureAlphaCheck(ITextureSource *tsrc, const TileDef *til break_loop: image->drop(); - if (!ok) { - warningstream << "Texture \"" << tiles[i].name << "\" of " - << name << " has transparent pixels, assuming " - "use_texture_alpha = true." << std::endl; - if (!long_warning_printed) { - warningstream << " This warning can be a false-positive if " - "unused pixels in the texture are transparent. However if " - "it is meant to be transparent, you *MUST* update the " - "nodedef and set use_texture_alpha = true! This compatibility " - "code will be removed in a few releases." << std::endl; - long_warning_printed = true; - } - return true; + if (ok) + continue; + warningstream << "Texture \"" << tiles[i].name << "\" of " + << name << " has transparency, assuming " + "use_texture_alpha = \"clip\"." << std::endl; + if (!long_warning_printed) { + warningstream << " This warning can be a false-positive if " + "unused pixels in the texture are transparent. However if " + "it is meant to be transparent, you *MUST* update the " + "nodedef and set use_texture_alpha = \"clip\"! This " + "compatibility code will be removed in a few releases." + << std::endl; + long_warning_printed = true; } + return true; } return false; } @@ -759,14 +793,18 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc bool is_liquid = false; - MaterialType material_type = (alpha == 255) ? - TILE_MATERIAL_BASIC : TILE_MATERIAL_ALPHA; + if (alpha == ALPHAMODE_LEGACY_COMPAT) { + // Before working with the alpha mode, resolve any legacy kludges + alpha = textureAlphaCheck(tsrc, tdef, 6) ? ALPHAMODE_CLIP : ALPHAMODE_OPAQUE; + } + + MaterialType material_type = alpha == ALPHAMODE_OPAQUE ? + TILE_MATERIAL_OPAQUE : (alpha == ALPHAMODE_CLIP ? TILE_MATERIAL_BASIC : + TILE_MATERIAL_ALPHA); switch (drawtype) { default: case NDT_NORMAL: - material_type = (alpha == 255) ? - TILE_MATERIAL_OPAQUE : TILE_MATERIAL_ALPHA; solidness = 2; break; case NDT_AIRLIKE: @@ -774,14 +812,14 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc break; case NDT_LIQUID: if (tsettings.opaque_water) - alpha = 255; + alpha = ALPHAMODE_OPAQUE; solidness = 1; is_liquid = true; break; case NDT_FLOWINGLIQUID: solidness = 0; if (tsettings.opaque_water) - alpha = 255; + alpha = ALPHAMODE_OPAQUE; is_liquid = true; break; case NDT_GLASSLIKE: @@ -833,19 +871,16 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc break; case NDT_MESH: case NDT_NODEBOX: - if (alpha == 255 && textureAlphaCheck(tsrc, tdef, 6)) - alpha = 0; - solidness = 0; - if (waving == 1) + if (waving == 1) { material_type = TILE_MATERIAL_WAVING_PLANTS; - else if (waving == 2) + } else if (waving == 2) { material_type = TILE_MATERIAL_WAVING_LEAVES; - else if (waving == 3) - material_type = (alpha == 255) ? TILE_MATERIAL_WAVING_LIQUID_OPAQUE : - TILE_MATERIAL_WAVING_LIQUID_BASIC; - else if (alpha == 255) - material_type = TILE_MATERIAL_OPAQUE; + } else if (waving == 3) { + material_type = alpha == ALPHAMODE_OPAQUE ? + TILE_MATERIAL_WAVING_LIQUID_OPAQUE : (alpha == ALPHAMODE_CLIP ? + TILE_MATERIAL_WAVING_LIQUID_BASIC : TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT); + } break; case NDT_TORCHLIKE: case NDT_SIGNLIKE: @@ -860,10 +895,11 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc if (is_liquid) { if (waving == 3) { - material_type = (alpha == 255) ? TILE_MATERIAL_WAVING_LIQUID_OPAQUE : - TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT; + material_type = alpha == ALPHAMODE_OPAQUE ? + TILE_MATERIAL_WAVING_LIQUID_OPAQUE : (alpha == ALPHAMODE_CLIP ? + TILE_MATERIAL_WAVING_LIQUID_BASIC : TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT); } else { - material_type = (alpha == 255) ? TILE_MATERIAL_LIQUID_OPAQUE : + material_type = alpha == ALPHAMODE_OPAQUE ? TILE_MATERIAL_LIQUID_OPAQUE : TILE_MATERIAL_LIQUID_TRANSPARENT; } } diff --git a/src/nodedef.h b/src/nodedef.h index 63b9474b9..6fc20518d 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -231,6 +231,14 @@ enum AlignStyle : u8 { ALIGN_STYLE_USER_DEFINED, }; +enum AlphaMode : u8 { + ALPHAMODE_BLEND, + ALPHAMODE_CLIP, + ALPHAMODE_OPAQUE, + ALPHAMODE_LEGACY_COMPAT, /* means either opaque or clip */ +}; + + /* Stand-alone definition of a TileSpec (basically a server-side TileSpec) */ @@ -315,9 +323,7 @@ struct ContentFeatures // These will be drawn over the base tiles. TileDef tiledef_overlay[6]; TileDef tiledef_special[CF_SPECIAL_COUNT]; // eg. flowing liquid - // If 255, the node is opaque. - // Otherwise it uses texture alpha. - u8 alpha; + AlphaMode alpha; // The color of the node. video::SColor color; std::string palette_name; @@ -418,20 +424,27 @@ struct ContentFeatures void serialize(std::ostream &os, u16 protocol_version) const; void deSerialize(std::istream &is); -#ifndef SERVER - /* - * Checks if any tile texture has any transparent pixels. - * Prints a warning and returns true if that is the case, false otherwise. - * This is supposed to be used for use_texture_alpha backwards compatibility. - */ - bool textureAlphaCheck(ITextureSource *tsrc, const TileDef *tiles, - int length); -#endif - - /* Some handy methods */ + void setDefaultAlphaMode() + { + switch (drawtype) { + case NDT_NORMAL: + case NDT_LIQUID: + case NDT_FLOWINGLIQUID: + alpha = ALPHAMODE_OPAQUE; + break; + case NDT_NODEBOX: + case NDT_MESH: + alpha = ALPHAMODE_LEGACY_COMPAT; // this should eventually be OPAQUE + break; + default: + alpha = ALPHAMODE_CLIP; + break; + } + } + bool needsBackfaceCulling() const { switch (drawtype) { @@ -465,6 +478,21 @@ struct ContentFeatures void updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc, scene::IMeshManipulator *meshmanip, Client *client, const TextureSettings &tsettings); #endif + +private: +#ifndef SERVER + /* + * Checks if any tile texture has any transparent pixels. + * Prints a warning and returns true if that is the case, false otherwise. + * This is supposed to be used for use_texture_alpha backwards compatibility. + */ + bool textureAlphaCheck(ITextureSource *tsrc, const TileDef *tiles, + int length); +#endif + + void setAlphaFromLegacy(u8 legacy_alpha); + + u8 getAlphaForLegacy() const; }; /*! diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 5d29422af..ecab7baa1 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -618,25 +618,39 @@ void read_content_features(lua_State *L, ContentFeatures &f, int index) } lua_pop(L, 1); + /* alpha & use_texture_alpha */ + // This is a bit complicated due to compatibility + + f.setDefaultAlphaMode(); + warn_if_field_exists(L, index, "alpha", - "Obsolete, only limited compatibility provided"); + "Obsolete, only limited compatibility provided; " + "replaced by \"use_texture_alpha\""); if (getintfield_default(L, index, "alpha", 255) != 255) - f.alpha = 0; + f.alpha = ALPHAMODE_BLEND; + + lua_getfield(L, index, "use_texture_alpha"); + if (lua_isboolean(L, -1)) { + warn_if_field_exists(L, index, "use_texture_alpha", + "Boolean values are deprecated; use the new choices"); + if (lua_toboolean(L, -1)) + f.alpha = (f.drawtype == NDT_NORMAL) ? ALPHAMODE_CLIP : ALPHAMODE_BLEND; + } else if (check_field_or_nil(L, -1, LUA_TSTRING, "use_texture_alpha")) { + int result = f.alpha; + string_to_enum(ScriptApiNode::es_TextureAlphaMode, result, + std::string(lua_tostring(L, -1))); + f.alpha = static_cast(result); + } + lua_pop(L, 1); - bool usealpha = getboolfield_default(L, index, - "use_texture_alpha", false); - if (usealpha) - f.alpha = 0; + /* Other stuff */ - // Read node color. lua_getfield(L, index, "color"); read_color(L, -1, &f.color); lua_pop(L, 1); getstringfield(L, index, "palette", f.palette_name); - /* Other stuff */ - lua_getfield(L, index, "post_effect_color"); read_color(L, -1, &f.post_effect_color); lua_pop(L, 1); diff --git a/src/script/cpp_api/s_node.cpp b/src/script/cpp_api/s_node.cpp index e0f9bcd78..269ebacb2 100644 --- a/src/script/cpp_api/s_node.cpp +++ b/src/script/cpp_api/s_node.cpp @@ -93,6 +93,14 @@ struct EnumString ScriptApiNode::es_NodeBoxType[] = {0, NULL}, }; +struct EnumString ScriptApiNode::es_TextureAlphaMode[] = + { + {ALPHAMODE_OPAQUE, "opaque"}, + {ALPHAMODE_CLIP, "clip"}, + {ALPHAMODE_BLEND, "blend"}, + {0, NULL}, + }; + bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node, ServerActiveObject *puncher, const PointedThing &pointed) { diff --git a/src/script/cpp_api/s_node.h b/src/script/cpp_api/s_node.h index 81b44f0f0..3f771c838 100644 --- a/src/script/cpp_api/s_node.h +++ b/src/script/cpp_api/s_node.h @@ -54,4 +54,5 @@ public: static struct EnumString es_ContentParamType2[]; static struct EnumString es_LiquidType[]; static struct EnumString es_NodeBoxType[]; + static struct EnumString es_TextureAlphaMode[]; }; diff --git a/src/unittest/test.cpp b/src/unittest/test.cpp index a783ccd32..af324e1b1 100644 --- a/src/unittest/test.cpp +++ b/src/unittest/test.cpp @@ -180,7 +180,7 @@ void TestGameDef::defineSomeNodes() "{default_water.png"; f = ContentFeatures(); f.name = itemdef.name; - f.alpha = 128; + f.alpha = ALPHAMODE_BLEND; f.liquid_type = LIQUID_SOURCE; f.liquid_viscosity = 4; f.is_ground_content = true; @@ -201,7 +201,7 @@ void TestGameDef::defineSomeNodes() "{default_lava.png"; f = ContentFeatures(); f.name = itemdef.name; - f.alpha = 128; + f.alpha = ALPHAMODE_OPAQUE; f.liquid_type = LIQUID_SOURCE; f.liquid_viscosity = 7; f.light_source = LIGHT_MAX-1; -- cgit v1.2.3 From 6e0e0324a48130376ab3c9fef03b84ee25608242 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sun, 31 Jan 2021 18:49:51 +0000 Subject: Fix minetest.dig_node returning true when node isn't diggable (#10890) --- builtin/game/item.lua | 6 ++++-- doc/lua_api.txt | 2 ++ src/script/cpp_api/s_node.cpp | 11 ++++++++--- 3 files changed, 14 insertions(+), 5 deletions(-) (limited to 'src/script/cpp_api') diff --git a/builtin/game/item.lua b/builtin/game/item.lua index 63f8d50e5..881aff52e 100644 --- a/builtin/game/item.lua +++ b/builtin/game/item.lua @@ -557,7 +557,7 @@ function core.node_dig(pos, node, digger) log("info", diggername .. " tried to dig " .. node.name .. " which is not diggable " .. core.pos_to_string(pos)) - return + return false end if core.is_protected(pos, diggername) then @@ -566,7 +566,7 @@ function core.node_dig(pos, node, digger) .. " at protected position " .. core.pos_to_string(pos)) core.record_protection_violation(pos, diggername) - return + return false end log('action', diggername .. " digs " @@ -649,6 +649,8 @@ function core.node_dig(pos, node, digger) local node_copy = {name=node.name, param1=node.param1, param2=node.param2} callback(pos_copy, node_copy, digger) end + + return true end function core.itemstring_with_palette(item, palette_index) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 8156f785a..df9e3f8b0 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -7628,6 +7628,8 @@ Used by `minetest.register_node`. on_dig = function(pos, node, digger), -- default: minetest.node_dig -- By default checks privileges, wears out tool and removes node. + -- return true if the node was dug successfully, false otherwise. + -- Deprecated: returning nil is the same as returning true. on_timer = function(pos, elapsed), -- default: nil diff --git a/src/script/cpp_api/s_node.cpp b/src/script/cpp_api/s_node.cpp index 269ebacb2..f23fbfbde 100644 --- a/src/script/cpp_api/s_node.cpp +++ b/src/script/cpp_api/s_node.cpp @@ -141,9 +141,14 @@ bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node, push_v3s16(L, p); pushnode(L, node, ndef); objectrefGetOrCreate(L, digger); - PCALL_RES(lua_pcall(L, 3, 0, error_handler)); - lua_pop(L, 1); // Pop error handler - return true; + PCALL_RES(lua_pcall(L, 3, 1, error_handler)); + + // nil is treated as true for backwards compat + bool result = lua_isnil(L, -1) || lua_toboolean(L, -1); + + lua_pop(L, 2); // Pop error handler and result + + return result; } void ScriptApiNode::node_on_construct(v3s16 p, MapNode node) -- cgit v1.2.3 From 3b78a223717c69918a5af422e21561f47ec74ce1 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Tue, 30 Mar 2021 01:25:11 +0300 Subject: Degrotate support for mesh nodes (#7840) --- builtin/game/item.lua | 6 +++- doc/lua_api.txt | 11 ++++-- games/devtest/mods/testnodes/drawtypes.lua | 56 +++++++++++++++++++++++++++++- src/client/content_mapblock.cpp | 16 ++++++--- src/client/content_mapblock.h | 2 +- src/mapnode.cpp | 21 +++++++++++ src/mapnode.h | 3 ++ src/nodedef.cpp | 3 +- src/nodedef.h | 4 ++- src/script/common/c_content.cpp | 3 +- src/script/cpp_api/s_node.cpp | 1 + 11 files changed, 113 insertions(+), 13 deletions(-) (limited to 'src/script/cpp_api') diff --git a/builtin/game/item.lua b/builtin/game/item.lua index b68177c22..17746e9a8 100644 --- a/builtin/game/item.lua +++ b/builtin/game/item.lua @@ -157,7 +157,7 @@ end function core.is_colored_paramtype(ptype) return (ptype == "color") or (ptype == "colorfacedir") or - (ptype == "colorwallmounted") + (ptype == "colorwallmounted") or (ptype == "colordegrotate") end function core.strip_param2_color(param2, paramtype2) @@ -168,6 +168,8 @@ function core.strip_param2_color(param2, paramtype2) param2 = math.floor(param2 / 32) * 32 elseif paramtype2 == "colorwallmounted" then param2 = math.floor(param2 / 8) * 8 + elseif paramtype2 == "colordegrotate" then + param2 = math.floor(param2 / 32) * 32 end -- paramtype2 == "color" requires no modification. return param2 @@ -345,6 +347,8 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2, color_divisor = 8 elseif def.paramtype2 == "colorfacedir" then color_divisor = 32 + elseif def.paramtype2 == "colordegrotate" then + color_divisor = 32 end if color_divisor then local color = math.floor(metatable.palette_index / color_divisor) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 737a690f6..8804c9e7f 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1048,9 +1048,9 @@ The function of `param2` is determined by `paramtype2` in node definition. * The height of the 'plantlike' section is stored in `param2`. * The height is (`param2` / 16) nodes. * `paramtype2 = "degrotate"` - * Only valid for "plantlike" drawtype. The rotation of the node is stored in - `param2`. - * Values range 0 - 179. The value stored in `param2` is multiplied by two to + * Valid for `plantlike` and `mesh` drawtypes. The rotation of the node is + stored in `param2`. + * Values range 0–239. The value stored in `param2` is multiplied by 1.5 to get the actual rotation in degrees of the node. * `paramtype2 = "meshoptions"` * Only valid for "plantlike" drawtype. `param2` encodes the shape and @@ -1088,6 +1088,11 @@ The function of `param2` is determined by `paramtype2` in node definition. * `param2` values 0-63 define 64 levels of internal liquid, 0 being empty and 63 being full. * Liquid texture is defined using `special_tiles = {"modname_tilename.png"}` +* `paramtype2 = "colordegrotate"` + * Same as `degrotate`, but with colors. + * The first (most-significant) three bits of `param2` tells which color + is picked from the palette. The palette should have 8 pixels. + * Remaining 5 bits store rotation in range 0–23 (i.e. in 15° steps) * `paramtype2 = "none"` * `param2` will not be used by the engine and can be used to store an arbitrary value diff --git a/games/devtest/mods/testnodes/drawtypes.lua b/games/devtest/mods/testnodes/drawtypes.lua index ff970144d..02d71b50d 100644 --- a/games/devtest/mods/testnodes/drawtypes.lua +++ b/games/devtest/mods/testnodes/drawtypes.lua @@ -223,6 +223,30 @@ minetest.register_node("testnodes:plantlike_waving", { -- param2 will rotate +local function rotate_on_rightclick(pos, node, clicker) + local def = minetest.registered_nodes[node.name] + local aux1 = clicker:get_player_control().aux1 + + local deg, deg_max + local color, color_mult = 0, 0 + if def.paramtype2 == "degrotate" then + deg = node.param2 + deg_max = 240 + elseif def.paramtype2 == "colordegrotate" then + -- MSB [3x color, 5x rotation] LSB + deg = node.param2 % 2^5 + deg_max = 24 + color_mult = 2^5 + color = math.floor(node.param2 / color_mult) + end + + deg = (deg + (aux1 and 10 or 1)) % deg_max + node.param2 = color * color_mult + deg + minetest.swap_node(pos, node) + minetest.chat_send_player(clicker:get_player_name(), + "Rotation is now " .. deg .. " / " .. deg_max) +end + minetest.register_node("testnodes:plantlike_degrotate", { description = S("Degrotate Plantlike Drawtype Test Node"), drawtype = "plantlike", @@ -230,12 +254,42 @@ minetest.register_node("testnodes:plantlike_degrotate", { paramtype2 = "degrotate", tiles = { "testnodes_plantlike_degrotate.png" }, - + on_rightclick = rotate_on_rightclick, + place_param2 = 7, walkable = false, sunlight_propagates = true, groups = { dig_immediate = 3 }, }) +minetest.register_node("testnodes:mesh_degrotate", { + description = S("Degrotate Mesh Drawtype Test Node"), + drawtype = "mesh", + paramtype = "light", + paramtype2 = "degrotate", + mesh = "testnodes_pyramid.obj", + tiles = { "testnodes_mesh_stripes2.png" }, + + on_rightclick = rotate_on_rightclick, + place_param2 = 7, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +minetest.register_node("testnodes:mesh_colordegrotate", { + description = S("Color Degrotate Mesh Drawtype Test Node"), + drawtype = "mesh", + paramtype2 = "colordegrotate", + palette = "testnodes_palette_facedir.png", + mesh = "testnodes_pyramid.obj", + tiles = { "testnodes_mesh_stripes2.png" }, + + on_rightclick = rotate_on_rightclick, + -- color index 1, 7 steps rotated + place_param2 = 1 * 2^5 + 7, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + -- param2 will change height minetest.register_node("testnodes:plantlike_leveled", { description = S("Leveled Plantlike Drawtype Test Node"), diff --git a/src/client/content_mapblock.cpp b/src/client/content_mapblock.cpp index 90284ecce..ce7235bca 100644 --- a/src/client/content_mapblock.cpp +++ b/src/client/content_mapblock.cpp @@ -968,7 +968,7 @@ void MapblockMeshGenerator::drawPlantlike() draw_style = PLANT_STYLE_CROSS; scale = BS / 2 * f->visual_scale; offset = v3f(0, 0, 0); - rotate_degree = 0; + rotate_degree = 0.0f; random_offset_Y = false; face_num = 0; plant_height = 1.0; @@ -988,7 +988,8 @@ void MapblockMeshGenerator::drawPlantlike() break; case CPT2_DEGROTATE: - rotate_degree = n.param2 * 2; + case CPT2_COLORED_DEGROTATE: + rotate_degree = 1.5f * n.getDegRotate(nodedef); break; case CPT2_LEVELED: @@ -1343,6 +1344,7 @@ void MapblockMeshGenerator::drawMeshNode() u8 facedir = 0; scene::IMesh* mesh; bool private_mesh; // as a grab/drop pair is not thread-safe + int degrotate = 0; if (f->param_type_2 == CPT2_FACEDIR || f->param_type_2 == CPT2_COLORED_FACEDIR) { @@ -1354,9 +1356,12 @@ void MapblockMeshGenerator::drawMeshNode() facedir = n.getWallMounted(nodedef); if (!enable_mesh_cache) facedir = wallmounted_to_facedir[facedir]; + } else if (f->param_type_2 == CPT2_DEGROTATE || + f->param_type_2 == CPT2_COLORED_DEGROTATE) { + degrotate = n.getDegRotate(nodedef); } - if (!data->m_smooth_lighting && f->mesh_ptr[facedir]) { + if (!data->m_smooth_lighting && f->mesh_ptr[facedir] && !degrotate) { // use cached meshes private_mesh = false; mesh = f->mesh_ptr[facedir]; @@ -1364,7 +1369,10 @@ void MapblockMeshGenerator::drawMeshNode() // no cache, clone and rotate mesh private_mesh = true; mesh = cloneMesh(f->mesh_ptr[0]); - rotateMeshBy6dFacedir(mesh, facedir); + if (facedir) + rotateMeshBy6dFacedir(mesh, facedir); + else if (degrotate) + rotateMeshXZby(mesh, 1.5f * degrotate); recalculateBoundingBox(mesh); meshmanip->recalculateNormals(mesh, true, false); } else diff --git a/src/client/content_mapblock.h b/src/client/content_mapblock.h index 487d84a07..a6c450d1f 100644 --- a/src/client/content_mapblock.h +++ b/src/client/content_mapblock.h @@ -139,7 +139,7 @@ public: // plantlike-specific PlantlikeStyle draw_style; v3f offset; - int rotate_degree; + float rotate_degree; bool random_offset_Y; int face_num; float plant_height; diff --git a/src/mapnode.cpp b/src/mapnode.cpp index 0551f3b6f..20980b238 100644 --- a/src/mapnode.cpp +++ b/src/mapnode.cpp @@ -177,6 +177,16 @@ v3s16 MapNode::getWallMountedDir(const NodeDefManager *nodemgr) const } } +u8 MapNode::getDegRotate(const NodeDefManager *nodemgr) const +{ + const ContentFeatures &f = nodemgr->get(*this); + if (f.param_type_2 == CPT2_DEGROTATE) + return getParam2() % 240; + if (f.param_type_2 == CPT2_COLORED_DEGROTATE) + return 10 * ((getParam2() & 0x1F) % 24); + return 0; +} + void MapNode::rotateAlongYAxis(const NodeDefManager *nodemgr, Rotation rot) { ContentParamType2 cpt2 = nodemgr->get(*this).param_type_2; @@ -230,6 +240,17 @@ void MapNode::rotateAlongYAxis(const NodeDefManager *nodemgr, Rotation rot) Rotation oldrot = wallmounted_to_rot[wmountface - 2]; param2 &= ~7; param2 |= rot_to_wallmounted[(oldrot - rot) & 3]; + } else if (cpt2 == CPT2_DEGROTATE) { + int angle = param2; // in 1.5° + angle += 60 * rot; // don’t do that on u8 + angle %= 240; + param2 = angle; + } else if (cpt2 == CPT2_COLORED_DEGROTATE) { + int angle = param2 & 0x1F; // in 15° + int color = param2 & 0xE0; + angle += 6 * rot; + angle %= 24; + param2 = color | angle; } } diff --git a/src/mapnode.h b/src/mapnode.h index a9ae63ba3..28ff9e43d 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -240,6 +240,9 @@ struct MapNode u8 getWallMounted(const NodeDefManager *nodemgr) const; v3s16 getWallMountedDir(const NodeDefManager *nodemgr) const; + /// @returns Rotation in range 0–239 (in 1.5° steps) + u8 getDegRotate(const NodeDefManager *nodemgr) const; + void rotateAlongYAxis(const NodeDefManager *nodemgr, Rotation rot); /*! diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 8a1f6203b..3dcac439f 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -944,7 +944,8 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc if (param_type_2 == CPT2_COLOR || param_type_2 == CPT2_COLORED_FACEDIR || - param_type_2 == CPT2_COLORED_WALLMOUNTED) + param_type_2 == CPT2_COLORED_WALLMOUNTED || + param_type_2 == CPT2_COLORED_DEGROTATE) palette = tsrc->getPalette(palette_name); if (drawtype == NDT_MESH && !mesh.empty()) { diff --git a/src/nodedef.h b/src/nodedef.h index 3e77624eb..b8cf7c14d 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -67,7 +67,7 @@ enum ContentParamType2 CPT2_WALLMOUNTED, // Block level like FLOWINGLIQUID CPT2_LEVELED, - // 2D rotation for things like plants + // 2D rotation CPT2_DEGROTATE, // Mesh options for plants CPT2_MESHOPTIONS, @@ -79,6 +79,8 @@ enum ContentParamType2 CPT2_COLORED_WALLMOUNTED, // Glasslike framed drawtype internal liquid level, param2 values 0 to 63 CPT2_GLASSLIKE_LIQUID_LEVEL, + // 3 bits of palette index, then degrotate + CPT2_COLORED_DEGROTATE, }; enum LiquidType diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index eca0c89d1..52baeae9d 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -685,7 +685,8 @@ void read_content_features(lua_State *L, ContentFeatures &f, int index) if (!f.palette_name.empty() && !(f.param_type_2 == CPT2_COLOR || f.param_type_2 == CPT2_COLORED_FACEDIR || - f.param_type_2 == CPT2_COLORED_WALLMOUNTED)) + f.param_type_2 == CPT2_COLORED_WALLMOUNTED || + f.param_type_2 == CPT2_COLORED_DEGROTATE)) warningstream << "Node " << f.name.c_str() << " has a palette, but not a suitable paramtype2." << std::endl; diff --git a/src/script/cpp_api/s_node.cpp b/src/script/cpp_api/s_node.cpp index f23fbfbde..029cb6308 100644 --- a/src/script/cpp_api/s_node.cpp +++ b/src/script/cpp_api/s_node.cpp @@ -65,6 +65,7 @@ struct EnumString ScriptApiNode::es_ContentParamType2[] = {CPT2_COLORED_FACEDIR, "colorfacedir"}, {CPT2_COLORED_WALLMOUNTED, "colorwallmounted"}, {CPT2_GLASSLIKE_LIQUID_LEVEL, "glasslikeliquidlevel"}, + {CPT2_COLORED_DEGROTATE, "colordegrotate"}, {0, NULL}, }; -- cgit v1.2.3 From 623f0a8613bd8677e259366a1d540deedb9d2302 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sun, 28 Mar 2021 22:53:48 +0200 Subject: Isolate library tables between sandbox and insecure env --- src/script/cpp_api/s_security.cpp | 44 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'src/script/cpp_api') diff --git a/src/script/cpp_api/s_security.cpp b/src/script/cpp_api/s_security.cpp index 63058d7c3..add7b1658 100644 --- a/src/script/cpp_api/s_security.cpp +++ b/src/script/cpp_api/s_security.cpp @@ -45,6 +45,21 @@ static inline void copy_safe(lua_State *L, const char *list[], unsigned len, int } } +static void shallow_copy_table(lua_State *L, int from=-2, int to=-1) +{ + if (from < 0) from = lua_gettop(L) + from + 1; + if (to < 0) to = lua_gettop(L) + to + 1; + lua_pushnil(L); + while (lua_next(L, from) != 0) { + assert(lua_type(L, -1) != LUA_TTABLE); + // duplicate key and value for lua_rawset + lua_pushvalue(L, -2); + lua_pushvalue(L, -2); + lua_rawset(L, to); + lua_pop(L, 1); + } +} + // Pushes the original version of a library function on the stack, from the old version static inline void push_original(lua_State *L, const char *lib, const char *func) { @@ -83,7 +98,10 @@ void ScriptApiSecurity::initializeSecurity() "unpack", "_VERSION", "xpcall", - // Completely safe libraries + }; + static const char *whitelist_tables[] = { + // These libraries are completely safe BUT we need to duplicate their table + // to ensure the sandbox can't affect the insecure env "coroutine", "string", "table", @@ -167,6 +185,17 @@ void ScriptApiSecurity::initializeSecurity() lua_pop(L, 1); + // Copy safe libraries + for (const char *libname : whitelist_tables) { + lua_getfield(L, old_globals, libname); + lua_newtable(L); + shallow_copy_table(L); + + lua_setglobal(L, libname); + lua_pop(L, 1); + } + + // Copy safe IO functions lua_getfield(L, old_globals, "io"); lua_newtable(L); @@ -222,6 +251,19 @@ void ScriptApiSecurity::initializeSecurity() #endif lua_pop(L, 1); // Pop globals_backup + + + /* + * In addition to copying the tables in whitelist_tables, we also need to + * replace the string metatable. Otherwise old_globals.string would + * be accessible via getmetatable("").__index from inside the sandbox. + */ + lua_pushliteral(L, ""); + lua_newtable(L); + lua_getglobal(L, "string"); + lua_setfield(L, -2, "__index"); + lua_setmetatable(L, -2); + lua_pop(L, 1); // Pop empty string } void ScriptApiSecurity::initializeSecurityClient() -- cgit v1.2.3 From 26cfbda653db1b843dbe2e78b0bb642f17cd5d8d Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 10 May 2021 16:51:54 +0200 Subject: Add on_object_properties_change callback --- builtin/client/register.lua | 1 + doc/client_lua_api.txt | 5 ++++- src/client/content_cao.cpp | 4 ++++ src/script/cpp_api/s_client.cpp | 36 ++++++++++++++++++++++++++---------- src/script/cpp_api/s_client.h | 1 + 5 files changed, 36 insertions(+), 11 deletions(-) (limited to 'src/script/cpp_api') diff --git a/builtin/client/register.lua b/builtin/client/register.lua index 2b5526523..5bf634699 100644 --- a/builtin/client/register.lua +++ b/builtin/client/register.lua @@ -105,6 +105,7 @@ core.registered_on_inventory_open, core.register_on_inventory_open = make_regist core.registered_on_recieve_physics_override, core.register_on_recieve_physics_override = make_registration() 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_nodes = {} core.registered_items = {} diff --git a/doc/client_lua_api.txt b/doc/client_lua_api.txt index 8b955db31..2728ed632 100644 --- a/doc/client_lua_api.txt +++ b/doc/client_lua_api.txt @@ -762,7 +762,10 @@ Call these functions only at load time! * `minetest.register_on_spawn_partice(function(particle definition))` * Called when recieving a spawn particle command from server * Newest functions are called first - * If any function returns true, the particel does not spawn + * If any function returns true, the particle does not spawn +* `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 ### Setting-related * `minetest.settings`: Settings object containing all of the settings from the diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index 27ba0b6dd..6ab83361a 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -1693,6 +1693,10 @@ void GenericCAO::processMessage(const std::string &data) newprops.deSerialize(is); setProperties(newprops); + // notify CSM + if (m_client->modsLoaded()) + m_client->getScript()->on_object_properties_change(m_id); + } else if (cmd == AO_CMD_UPDATE_POSITION) { // Not sent by the server if this object is an attachment. // We might however get here if the server notices the object being detached before the client. diff --git a/src/script/cpp_api/s_client.cpp b/src/script/cpp_api/s_client.cpp index b90decfb5..b8decf2cd 100644 --- a/src/script/cpp_api/s_client.cpp +++ b/src/script/cpp_api/s_client.cpp @@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "client/client.h" #include "common/c_converter.h" #include "common/c_content.h" +#include "lua_api/l_clientobject.h" #include "s_item.h" void ScriptApiClient::on_mods_loaded() @@ -176,7 +177,7 @@ bool ScriptApiClient::on_punchnode(v3s16 p, MapNode node) const NodeDefManager *ndef = getClient()->ndef(); - // Get core.registered_on_punchgnode + // Get core.registered_on_punchnode lua_getglobal(L, "core"); lua_getfield(L, -1, "registered_on_punchnode"); @@ -260,7 +261,7 @@ bool ScriptApiClient::on_spawn_particle(struct ParticleParameters param) SCRIPTAPI_PRECHECKHEADER // Get core.registered_on_play_sound - + lua_getglobal(L, "core"); lua_getfield(L, -1, "registered_on_spawn_particle"); @@ -285,13 +286,28 @@ bool ScriptApiClient::on_spawn_particle(struct ParticleParameters param) pushnode(L, param.node, getGameDef()->ndef()); lua_setfield(L, -2, "node"); } - setintfield(L, -1, "node_tile", param.node_tile); - + setintfield(L, -1, "node_tile", param.node_tile); + // Call functions runCallbacks(1, RUN_CALLBACKS_MODE_OR); return readParam(L, -1); } +void ScriptApiClient::on_object_properties_change(s16 id) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.on_object_properties_change + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_object_properties_change"); + + // Push data + ClientObjectRef::create(L, id); + + // Call functions + runCallbacks(1, RUN_CALLBACKS_MODE_FIRST); +} + bool ScriptApiClient::on_inventory_open(Inventory *inventory) { SCRIPTAPI_PRECHECKHEADER @@ -308,11 +324,11 @@ bool ScriptApiClient::on_inventory_open(Inventory *inventory) void ScriptApiClient::open_enderchest() { SCRIPTAPI_PRECHECKHEADER - + PUSH_ERROR_HANDLER(L); int error_handler = lua_gettop(L) - 1; lua_insert(L, error_handler); - + lua_getglobal(L, "core"); lua_getfield(L, -1, "open_enderchest"); if (lua_isfunction(L, -1)) @@ -322,10 +338,10 @@ void ScriptApiClient::open_enderchest() void ScriptApiClient::set_node_def(const ContentFeatures &f) { SCRIPTAPI_PRECHECKHEADER - + lua_getglobal(L, "core"); lua_getfield(L, -1, "registered_nodes"); - + push_content_features(L, f); lua_setfield(L, -2, f.name.c_str()); } @@ -333,10 +349,10 @@ void ScriptApiClient::set_node_def(const ContentFeatures &f) void ScriptApiClient::set_item_def(const ItemDefinition &i) { SCRIPTAPI_PRECHECKHEADER - + lua_getglobal(L, "core"); lua_getfield(L, -1, "registered_items"); - + push_item_definition(L, i); lua_setfield(L, -2, i.name.c_str()); } diff --git a/src/script/cpp_api/s_client.h b/src/script/cpp_api/s_client.h index 9f68a14fc..62921b528 100644 --- a/src/script/cpp_api/s_client.h +++ b/src/script/cpp_api/s_client.h @@ -63,6 +63,7 @@ public: bool new_move); bool on_play_sound(SimpleSoundSpec spec); bool on_spawn_particle(struct ParticleParameters param); + void on_object_properties_change(s16 id); bool on_inventory_open(Inventory *inventory); void open_enderchest(); -- cgit v1.2.3 From c86dcd0f682f76339989afec255bf3d7078db096 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 10 May 2021 20:45:05 +0200 Subject: Add on_object_hp_change callback and nametag images --- builtin/client/register.lua | 1 + doc/client_lua_api.txt | 3 +++ src/client/camera.cpp | 23 +++++++++++++++++++---- src/client/camera.h | 33 ++++++++++++++++++++++++++++++--- src/client/content_cao.cpp | 6 +++++- src/client/content_cao.h | 2 ++ src/client/hud.cpp | 2 +- src/script/cpp_api/s_client.cpp | 15 +++++++++++++++ src/script/cpp_api/s_client.h | 1 + src/script/lua_api/l_clientobject.cpp | 23 +++++++++++++++++++++-- src/script/lua_api/l_clientobject.h | 3 +++ 11 files changed, 101 insertions(+), 11 deletions(-) (limited to 'src/script/cpp_api') diff --git a/builtin/client/register.lua b/builtin/client/register.lua index 5bf634699..835ec5002 100644 --- a/builtin/client/register.lua +++ b/builtin/client/register.lua @@ -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 = {} diff --git a/doc/client_lua_api.txt b/doc/client_lua_api.txt index 2728ed632..2e347ec47 100644 --- a/doc/client_lua_api.txt +++ b/doc/client_lua_api.txt @@ -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` diff --git a/src/client/camera.cpp b/src/client/camera.cpp index 3afd45c55..854d9eae8 100644 --- a/src/client/camera.cpp +++ b/src/client/camera.cpp @@ -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 size(0, 0, textsize.Width, textsize.Height); - core::rect bg_size(-2, 0, textsize.Width+2, textsize.Height); + core::rect 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 rect(core::position2d(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 bgcolor, const v3f &pos) + Optional bgcolor, const v3f &pos, + const std::vector &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; } diff --git a/src/client/camera.h b/src/client/camera.h index 6fd8d9aa7..c162df515 100644 --- a/src/client/camera.h +++ b/src/client/camera.h @@ -39,18 +39,44 @@ struct Nametag video::SColor textcolor; Optional bgcolor; v3f pos; + ITextureSource *texture_source; + std::vector images; + core::dimension2di images_dim; Nametag(scene::ISceneNode *a_parent_node, const std::string &text, const video::SColor &textcolor, const Optional &bgcolor, - const v3f &pos): + const v3f &pos, + ITextureSource *tsrc, + const std::vector &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 &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 bgcolor, const v3f &pos); + Optional bgcolor, const v3f &pos, + const std::vector &image_names); void removeNametag(Nametag *nametag); diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index ea034f629..84d200a73 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -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(); diff --git a/src/client/content_cao.h b/src/client/content_cao.h index 360c30995..450023d19 100644 --- a/src/client/content_cao.h +++ b/src/client/content_cao.h @@ -318,4 +318,6 @@ public: void setProperties(ObjectProperties newprops); void updateMeshCulling(); + + std::vector nametag_images = {}; }; diff --git a/src/client/hud.cpp b/src/client/hud.cpp index 74c1828e3..5971948fd 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -149,7 +149,7 @@ void Hud::drawItem(const ItemStack &item, const core::rect& rect, bool selected) { if (selected) { - /* draw hihlighting around selected item */ + /* draw highlighting around selected item */ if (use_hotbar_selected_image) { core::rect imgrect2 = rect; imgrect2.UpperLeftCorner.X -= (m_padding*2); diff --git a/src/script/cpp_api/s_client.cpp b/src/script/cpp_api/s_client.cpp index b8decf2cd..2231cf573 100644 --- a/src/script/cpp_api/s_client.cpp +++ b/src/script/cpp_api/s_client.cpp @@ -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 diff --git a/src/script/cpp_api/s_client.h b/src/script/cpp_api/s_client.h index 62921b528..a2babfac8 100644 --- a/src/script/cpp_api/s_client.h +++ b/src/script/cpp_api/s_client.h @@ -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(); diff --git a/src/script/lua_api/l_clientobject.cpp b/src/script/lua_api/l_clientobject.cpp index 0147fd48b..8a4647d45 100644 --- a/src/script/lua_api/l_clientobject.cpp +++ b/src/script/lua_api/l_clientobject.cpp @@ -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}}; diff --git a/src/script/lua_api/l_clientobject.h b/src/script/lua_api/l_clientobject.h index 22d2f4a1c..60d10dcf6 100644 --- a/src/script/lua_api/l_clientobject.h +++ b/src/script/lua_api/l_clientobject.h @@ -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); }; -- cgit v1.2.3 From 4f613bbf5118ebe8c3610514e7f4206e930783bf Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 11 May 2021 14:07:30 +0200 Subject: Include tile definitions in get_node_def; Client-side minetest.object_refs table --- builtin/client/register.lua | 1 + builtin/common/misc_helpers.lua | 9 +++++ builtin/game/item.lua | 9 ----- doc/client_lua_api.txt | 61 +++++++++++++++++++++++++++++++++ src/client/clientenvironment.cpp | 11 +++++- src/client/game.cpp | 2 +- src/script/common/c_content.cpp | 63 ++++++++++++++++++++++++++++++----- src/script/cpp_api/s_base.cpp | 16 ++++++--- src/script/cpp_api/s_base.h | 5 +-- src/script/cpp_api/s_client.cpp | 4 +-- src/script/lua_api/l_client.cpp | 2 +- src/script/lua_api/l_clientobject.cpp | 59 ++++++++++++++++++++++++++++---- src/script/lua_api/l_clientobject.h | 2 ++ src/script/lua_api/l_localplayer.cpp | 2 +- src/serverenvironment.cpp | 8 ++--- 15 files changed, 212 insertions(+), 42 deletions(-) (limited to 'src/script/cpp_api') diff --git a/builtin/client/register.lua b/builtin/client/register.lua index 835ec5002..6a6d8e13c 100644 --- a/builtin/client/register.lua +++ b/builtin/client/register.lua @@ -110,3 +110,4 @@ core.registered_on_object_hp_change, core.register_on_object_hp_change = make_re core.registered_nodes = {} core.registered_items = {} +core.object_refs = {} diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua index b86d68f5f..308e2c7c7 100644 --- a/builtin/common/misc_helpers.lua +++ b/builtin/common/misc_helpers.lua @@ -785,3 +785,12 @@ end function core.is_nan(number) return number ~= number end + +function core.inventorycube(img1, img2, img3) + img2 = img2 or img1 + img3 = img3 or img1 + return "[inventorycube" + .. "{" .. img1:gsub("%^", "&") + .. "{" .. img2:gsub("%^", "&") + .. "{" .. img3:gsub("%^", "&") +end diff --git a/builtin/game/item.lua b/builtin/game/item.lua index dc0247e5f..cc0314e67 100644 --- a/builtin/game/item.lua +++ b/builtin/game/item.lua @@ -15,15 +15,6 @@ end -- Item definition helpers -- -function core.inventorycube(img1, img2, img3) - img2 = img2 or img1 - img3 = img3 or img1 - return "[inventorycube" - .. "{" .. img1:gsub("%^", "&") - .. "{" .. img2:gsub("%^", "&") - .. "{" .. img3:gsub("%^", "&") -end - function core.dir_to_facedir(dir, is6d) --account for y if requested if is6d and math.abs(dir.y) > math.abs(dir.x) and math.abs(dir.y) > math.abs(dir.z) then diff --git a/doc/client_lua_api.txt b/doc/client_lua_api.txt index 2e347ec47..e33fe0e3a 100644 --- a/doc/client_lua_api.txt +++ b/doc/client_lua_api.txt @@ -934,6 +934,8 @@ Call these functions only at load time! * Convert between two privilege representations ### Client Environment +* `minetest.object_refs` + * Map of object references, indexed by active object id * `minetest.get_player_names()` * Returns list of player names on server (nil if CSM_RF_READ_PLAYERINFO is enabled by server) * `minetest.get_objects_inside_radius(pos, radius)`: returns a list of @@ -1454,6 +1456,8 @@ It can be created via `Raycast(pos1, pos2, objects, liquids)` or ----------------- ### Definitions +* `minetest.inventorycube(img1, img2, img3)` + * Returns a string for making an image of a cube (useful as an item image) * `minetest.get_node_def(nodename)` * Returns [node definition](#node-definition) table of `nodename` * `minetest.get_item_def(itemstring)` @@ -1465,10 +1469,67 @@ It can be created via `Raycast(pos1, pos2, objects, liquids)` or {light_source=minetest.LIGHT_MAX})` * Doesnt really work yet an causes strange bugs, I'm working to make is better + +#### Tile definition + +* `"image.png"` +* `{name="image.png", animation={Tile Animation definition}}` +* `{name="image.png", backface_culling=bool, align_style="node"/"world"/"user", scale=int}` + * backface culling enabled by default for most nodes + * align style determines whether the texture will be rotated with the node + or kept aligned with its surroundings. "user" means that client + setting will be used, similar to `glasslike_framed_optional`. + Note: supported by solid nodes and nodeboxes only. + * scale is used to make texture span several (exactly `scale`) nodes, + instead of just one, in each direction. Works for world-aligned + textures only. + Note that as the effect is applied on per-mapblock basis, `16` should + be equally divisible by `scale` or you may get wrong results. +* `{name="image.png", color=ColorSpec}` + * the texture's color will be multiplied with this color. + * the tile's color overrides the owning node's color in all cases. + +##### Tile definition + + { + type = "vertical_frames", + + aspect_w = 16, + -- Width of a frame in pixels + + aspect_h = 16, + -- Height of a frame in pixels + + length = 3.0, + -- Full loop length + } + + { + type = "sheet_2d", + + frames_w = 5, + -- Width in number of frames + + frames_h = 3, + -- Height in number of frames + + frame_length = 0.5, + -- Length of a single frame + } + #### Node Definition ```lua { + tiles = {tile definition 1, def2, def3, def4, def5, def6}, + -- Textures of node; +Y, -Y, +X, -X, +Z, -Z + overlay_tiles = {tile definition 1, def2, def3, def4, def5, def6}, + -- Same as `tiles`, but these textures are drawn on top of the base + -- tiles. This is used to colorize only specific parts of the + -- texture. If the texture name is an empty string, that overlay is not + -- drawn + special_tiles = {tile definition 1, Tile definition 2}, + -- Special textures of node; used rarely. has_on_construct = bool, -- Whether the node has the on_construct callback defined has_on_destruct = bool, -- Whether the node has the on_destruct callback defined has_after_destruct = bool, -- Whether the node has the after_destruct callback defined diff --git a/src/client/clientenvironment.cpp b/src/client/clientenvironment.cpp index fd56c8f44..8e0d00bc9 100644 --- a/src/client/clientenvironment.cpp +++ b/src/client/clientenvironment.cpp @@ -352,6 +352,7 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type, { ClientActiveObject* obj = ClientActiveObject::create((ActiveObjectType) type, m_client, this); + if(obj == NULL) { infostream<<"ClientEnvironment::addActiveObject(): " @@ -362,6 +363,9 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type, obj->setId(id); + if (m_client->modsLoaded()) + m_client->getScript()->addObjectReference(dynamic_cast(obj)); + try { obj->initialize(init_data); @@ -394,9 +398,14 @@ void ClientEnvironment::removeActiveObject(u16 id) { // Get current attachment childs to detach them visually std::unordered_set attachment_childs; - if (auto *obj = getActiveObject(id)) + auto *obj = getActiveObject(id); + if (obj) { attachment_childs = obj->getAttachmentChildIds(); + if (m_client->modsLoaded()) + m_client->getScript()->removeObjectReference(dynamic_cast(obj)); + } + m_ao_manager.removeObject(id); // Perform a proper detach in Irrlicht diff --git a/src/client/game.cpp b/src/client/game.cpp index 104a6e374..e1f2fbe75 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -734,7 +734,7 @@ bool Game::connectToServer(const GameStartData &start_data, } else { wait_time += dtime; // Only time out if we aren't waiting for the server we started - if (!start_data.isSinglePlayer() && wait_time > 10) { + if (!start_data.local_server && !start_data.isSinglePlayer() && wait_time > 10) { *error_message = "Connection timed out."; errorstream << *error_message << std::endl; break; diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 8543b70ce..e56d07cc6 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -515,6 +515,35 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype) return tiledef; } +/******************************************************************************/ +void push_tiledef(lua_State *L, TileDef tiledef) +{ + lua_newtable(L); + setstringfield(L, -1, "name", tiledef.name); + setboolfield(L, -1, "backface_culling", tiledef.backface_culling); + setboolfield(L, -1, "tileable_horizontal", tiledef.tileable_horizontal); + setboolfield(L, -1, "tileable_vertical", tiledef.tileable_vertical); + std::string align_style; + switch (tiledef.align_style) { + case ALIGN_STYLE_USER_DEFINED: + align_style = "user"; + break; + case ALIGN_STYLE_WORLD: + align_style = "world"; + break; + default: + align_style = "node"; + } + setstringfield(L, -1, "align_style", align_style); + setintfield(L, -1, "scale", tiledef.scale); + if (tiledef.has_color) { + push_ARGB8(L, tiledef.color); + lua_setfield(L, -2, "color"); + } + push_animation_definition(L, tiledef.animation); + lua_setfield(L, -2, "animation"); +} + /******************************************************************************/ void read_content_features(lua_State *L, ContentFeatures &f, int index) { @@ -835,9 +864,32 @@ void push_content_features(lua_State *L, const ContentFeatures &c) std::string drawtype(ScriptApiNode::es_DrawType[(int)c.drawtype].str); std::string liquid_type(ScriptApiNode::es_LiquidType[(int)c.liquid_type].str); - /* Missing "tiles" because I don't see a usecase (at least not yet). */ + lua_newtable(L); + // tiles lua_newtable(L); + for (int i = 0; i < 6; i++) { + push_tiledef(L, c.tiledef[i]); + lua_rawseti(L, -2, i + 1); + } + lua_setfield(L, -2, "tiles"); + + // overlay_tiles + lua_newtable(L); + for (int i = 0; i < 6; i++) { + push_tiledef(L, c.tiledef_overlay[i]); + lua_rawseti(L, -2, i + 1); + } + lua_setfield(L, -2, "overlay_tiles"); + + // special_tiles + lua_newtable(L); + for (int i = 0; i < CF_SPECIAL_COUNT; i++) { + push_tiledef(L, c.tiledef_special[i]); + lua_rawseti(L, -2, i + 1); + } + lua_setfield(L, -2, "special_tiles"); + lua_pushboolean(L, c.has_on_construct); lua_setfield(L, -2, "has_on_construct"); lua_pushboolean(L, c.has_on_destruct); @@ -1886,14 +1938,7 @@ void push_pointed_thing(lua_State *L, const PointedThing &pointed, bool csm, } else if (pointed.type == POINTEDTHING_OBJECT) { lua_pushstring(L, "object"); lua_setfield(L, -2, "type"); - if (csm) { -#ifndef SERVER - ClientObjectRef::create(L, pointed.object_id); -#endif - } else { - push_objectRef(L, pointed.object_id); - } - + push_objectRef(L, pointed.object_id); lua_setfield(L, -2, "ref"); } else { lua_pushstring(L, "nothing"); diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index 1d62d8b65..867f61e0c 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "cpp_api/s_internal.h" #include "cpp_api/s_security.h" #include "lua_api/l_object.h" +#include "lua_api/l_clientobject.h" #include "common/c_converter.h" #include "server/player_sao.h" #include "filesys.h" @@ -354,13 +355,16 @@ void ScriptApiBase::setOriginFromTableRaw(int index, const char *fxn) * since we lose control over the ref and the contained pointer. */ -void ScriptApiBase::addObjectReference(ServerActiveObject *cobj) +void ScriptApiBase::addObjectReference(ActiveObject *cobj) { SCRIPTAPI_PRECHECKHEADER //infostream<<"scriptapi_add_object_reference: id="<getId()<(cobj)); + else + ObjectRef::create(L, dynamic_cast(cobj)); // Puts ObjectRef (as userdata) on stack int object = lua_gettop(L); // Get core.object_refs table @@ -375,7 +379,7 @@ void ScriptApiBase::addObjectReference(ServerActiveObject *cobj) lua_settable(L, objectstable); } -void ScriptApiBase::removeObjectReference(ServerActiveObject *cobj) +void ScriptApiBase::removeObjectReference(ActiveObject *cobj) { SCRIPTAPI_PRECHECKHEADER //infostream<<"scriptapi_rm_object_reference: id="<getId()<getId()); // Push id lua_gettable(L, objectstable); // Set object reference to NULL - ObjectRef::set_null(L); + if (m_type == ScriptingType::Client) + ClientObjectRef::set_null(L); + else + ObjectRef::set_null(L); lua_pop(L, 1); // pop object // Set object_refs[id] = nil @@ -413,7 +420,6 @@ void ScriptApiBase::objectrefGetOrCreate(lua_State *L, << ", this is probably a bug." << std::endl; } } - void ScriptApiBase::pushPlayerHPChangeReason(lua_State *L, const PlayerHPChangeReason &reason) { if (reason.hasLuaReference()) diff --git a/src/script/cpp_api/s_base.h b/src/script/cpp_api/s_base.h index 36331ad37..a7a2c7203 100644 --- a/src/script/cpp_api/s_base.h +++ b/src/script/cpp_api/s_base.h @@ -73,6 +73,7 @@ class Game; class IGameDef; class Environment; class GUIEngine; +class ActiveObject; class ServerActiveObject; struct PlayerHPChangeReason; @@ -99,8 +100,8 @@ public: RunCallbacksMode mode, const char *fxn); /* object */ - void addObjectReference(ServerActiveObject *cobj); - void removeObjectReference(ServerActiveObject *cobj); + void addObjectReference(ActiveObject *cobj); + void removeObjectReference(ActiveObject *cobj); IGameDef *getGameDef() { return m_gamedef; } Server* getServer(); diff --git a/src/script/cpp_api/s_client.cpp b/src/script/cpp_api/s_client.cpp index 2231cf573..7971e4081 100644 --- a/src/script/cpp_api/s_client.cpp +++ b/src/script/cpp_api/s_client.cpp @@ -302,7 +302,7 @@ void ScriptApiClient::on_object_properties_change(s16 id) lua_getfield(L, -1, "registered_on_object_properties_change"); // Push data - ClientObjectRef::create(L, id); + push_objectRef(L, id); // Call functions runCallbacks(1, RUN_CALLBACKS_MODE_FIRST); @@ -317,7 +317,7 @@ void ScriptApiClient::on_object_hp_change(s16 id) lua_getfield(L, -1, "registered_on_object_hp_change"); // Push data - ClientObjectRef::create(L, id); + push_objectRef(L, id); // Call functions runCallbacks(1, RUN_CALLBACKS_MODE_FIRST); diff --git a/src/script/lua_api/l_client.cpp b/src/script/lua_api/l_client.cpp index 484af2ec3..916983982 100644 --- a/src/script/lua_api/l_client.cpp +++ b/src/script/lua_api/l_client.cpp @@ -520,7 +520,7 @@ int ModApiClient::l_get_objects_inside_radius(lua_State *L) int i = 0; lua_createtable(L, objs.size(), 0); for (const auto obj : objs) { - ClientObjectRef::create(L, obj.obj); // TODO: getObjectRefOrCreate + push_objectRef(L, obj.obj->getId()); lua_rawseti(L, -2, ++i); } return 1; diff --git a/src/script/lua_api/l_clientobject.cpp b/src/script/lua_api/l_clientobject.cpp index 8a4647d45..5a1123169 100644 --- a/src/script/lua_api/l_clientobject.cpp +++ b/src/script/lua_api/l_clientobject.cpp @@ -48,6 +48,8 @@ ClientActiveObject *ClientObjectRef::get_cao(ClientObjectRef *ref) GenericCAO *ClientObjectRef::get_generic_cao(ClientObjectRef *ref, lua_State *L) { ClientActiveObject *obj = get_cao(ref); + if (! obj) + return nullptr; ClientEnvironment &env = getClient(L)->getEnv(); GenericCAO *gcao = env.getGenericCAO(obj->getId()); return gcao; @@ -57,6 +59,8 @@ int ClientObjectRef::l_get_pos(lua_State *L) { ClientObjectRef *ref = checkobject(L, 1); ClientActiveObject *cao = get_cao(ref); + if (! cao) + return 0; push_v3f(L, cao->getPosition() / BS); return 1; } @@ -65,6 +69,8 @@ int ClientObjectRef::l_get_velocity(lua_State *L) { ClientObjectRef *ref = checkobject(L, 1); GenericCAO *gcao = get_generic_cao(ref, L); + if (! gcao) + return 0; push_v3f(L, gcao->getVelocity() / BS); return 1; } @@ -73,6 +79,8 @@ int ClientObjectRef::l_get_acceleration(lua_State *L) { ClientObjectRef *ref = checkobject(L, 1); GenericCAO *gcao = get_generic_cao(ref, L); + if (! gcao) + return 0; push_v3f(L, gcao->getAcceleration() / BS); return 1; } @@ -81,6 +89,8 @@ int ClientObjectRef::l_get_rotation(lua_State *L) { ClientObjectRef *ref = checkobject(L, 1); GenericCAO *gcao = get_generic_cao(ref, L); + if (! gcao) + return 0; push_v3f(L, gcao->getRotation()); return 1; } @@ -89,6 +99,8 @@ int ClientObjectRef::l_is_player(lua_State *L) { ClientObjectRef *ref = checkobject(L, 1); GenericCAO *gcao = get_generic_cao(ref, L); + if (! gcao) + return 0; lua_pushboolean(L, gcao->isPlayer()); return 1; } @@ -97,6 +109,8 @@ int ClientObjectRef::l_is_local_player(lua_State *L) { ClientObjectRef *ref = checkobject(L, 1); GenericCAO *gcao = get_generic_cao(ref, L); + if (! gcao) + return 0; lua_pushboolean(L, gcao->isLocalPlayer()); return 1; } @@ -105,6 +119,8 @@ int ClientObjectRef::l_get_name(lua_State *L) { ClientObjectRef *ref = checkobject(L, 1); GenericCAO *gcao = get_generic_cao(ref, L); + if (! gcao) + return 0; lua_pushstring(L, gcao->getName().c_str()); return 1; } @@ -113,7 +129,12 @@ int ClientObjectRef::l_get_attach(lua_State *L) { ClientObjectRef *ref = checkobject(L, 1); GenericCAO *gcao = get_generic_cao(ref, L); - create(L, gcao->getParent()); + if (! gcao) + return 0; + ClientActiveObject *parent = gcao->getParent(); + if (! parent) + return 0; + push_objectRef(L, parent->getId()); return 1; } @@ -122,6 +143,8 @@ int ClientObjectRef::l_get_nametag(lua_State *L) log_deprecated(L,"Deprecated call to get_nametag, use get_properties().nametag instead"); ClientObjectRef *ref = checkobject(L, 1); GenericCAO *gcao = get_generic_cao(ref, L); + if (! gcao) + return 0; ObjectProperties *props = gcao->getProperties(); lua_pushstring(L, props->nametag.c_str()); return 1; @@ -132,6 +155,8 @@ int ClientObjectRef::l_get_item_textures(lua_State *L) log_deprecated(L,"Deprecated call to get_item_textures, use get_properties().textures instead"); ClientObjectRef *ref = checkobject(L, 1); GenericCAO *gcao = get_generic_cao(ref, L); + if (! gcao) + return 0; ObjectProperties *props = gcao->getProperties(); lua_newtable(L); @@ -146,6 +171,8 @@ int ClientObjectRef::l_get_max_hp(lua_State *L) log_deprecated(L,"Deprecated call to get_max_hp, use get_properties().hp_max instead"); ClientObjectRef *ref = checkobject(L, 1); GenericCAO *gcao = get_generic_cao(ref, L); + if (! gcao) + return 0; ObjectProperties *props = gcao->getProperties(); lua_pushnumber(L, props->hp_max); return 1; @@ -155,6 +182,8 @@ int ClientObjectRef::l_get_properties(lua_State *L) { ClientObjectRef *ref = checkobject(L, 1); GenericCAO *gcao = get_generic_cao(ref, L); + if (! gcao) + return 0; ObjectProperties *prop = gcao->getProperties(); push_object_properties(L, prop); return 1; @@ -164,6 +193,8 @@ int ClientObjectRef::l_set_properties(lua_State *L) { ClientObjectRef *ref = checkobject(L, 1); GenericCAO *gcao = get_generic_cao(ref, L); + if (! gcao) + return 0; ObjectProperties prop = *gcao->getProperties(); read_object_properties(L, 2, nullptr, &prop, getClient(L)->idef()); gcao->setProperties(prop); @@ -174,6 +205,8 @@ int ClientObjectRef::l_get_hp(lua_State *L) { ClientObjectRef *ref = checkobject(L, 1); GenericCAO *gcao = get_generic_cao(ref, L); + if (! gcao) + return 0; lua_pushnumber(L, gcao->getHp()); return 1; } @@ -182,6 +215,8 @@ int ClientObjectRef::l_punch(lua_State *L) { ClientObjectRef *ref = checkobject(L, 1); GenericCAO *gcao = get_generic_cao(ref, L); + if (! gcao) + return 0; PointedThing pointed(gcao->getId(), v3f(0, 0, 0), v3s16(0, 0, 0), 0); getClient(L)->interact(INTERACT_START_DIGGING, pointed); return 0; @@ -191,6 +226,8 @@ int ClientObjectRef::l_rightclick(lua_State *L) { ClientObjectRef *ref = checkobject(L, 1); GenericCAO *gcao = get_generic_cao(ref, L); + if (! gcao) + return 0; PointedThing pointed(gcao->getId(), v3f(0, 0, 0), v3s16(0, 0, 0), 0); getClient(L)->interact(INTERACT_PLACE, pointed); return 0; @@ -200,6 +237,8 @@ int ClientObjectRef::l_remove(lua_State *L) { ClientObjectRef *ref = checkobject(L, 1); ClientActiveObject *cao = get_cao(ref); + if (! cao) + return 0; getClient(L)->getEnv().removeActiveObject(cao->getId()); return 0; @@ -209,6 +248,8 @@ int ClientObjectRef::l_set_nametag_images(lua_State *L) { ClientObjectRef *ref = checkobject(L, 1); GenericCAO *gcao = get_generic_cao(ref, L); + if (! gcao) + return 0; gcao->nametag_images.clear(); if(lua_istable(L, 2)){ lua_pushnil(L); @@ -228,12 +269,10 @@ ClientObjectRef::ClientObjectRef(ClientActiveObject *object) : m_object(object) void ClientObjectRef::create(lua_State *L, ClientActiveObject *object) { - if (object) { - ClientObjectRef *o = new ClientObjectRef(object); - *(void **)(lua_newuserdata(L, sizeof(void *))) = o; - luaL_getmetatable(L, className); - lua_setmetatable(L, -2); - } + ClientObjectRef *o = new ClientObjectRef(object); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); } void ClientObjectRef::create(lua_State *L, s16 id) @@ -241,6 +280,12 @@ void ClientObjectRef::create(lua_State *L, s16 id) create(L, ((ClientEnvironment *)getEnv(L))->getActiveObject(id)); } +void ClientObjectRef::set_null(lua_State *L) +{ + ClientObjectRef *obj = checkobject(L, -1); + obj->m_object = nullptr; +} + int ClientObjectRef::gc_object(lua_State *L) { ClientObjectRef *obj = *(ClientObjectRef **)(lua_touserdata(L, 1)); diff --git a/src/script/lua_api/l_clientobject.h b/src/script/lua_api/l_clientobject.h index 60d10dcf6..c4c95cb41 100644 --- a/src/script/lua_api/l_clientobject.h +++ b/src/script/lua_api/l_clientobject.h @@ -35,6 +35,8 @@ public: static void create(lua_State *L, ClientActiveObject *object); static void create(lua_State *L, s16 id); + static void set_null(lua_State *L); + static ClientObjectRef *checkobject(lua_State *L, int narg); private: diff --git a/src/script/lua_api/l_localplayer.cpp b/src/script/lua_api/l_localplayer.cpp index 747657016..b8673379a 100644 --- a/src/script/lua_api/l_localplayer.cpp +++ b/src/script/lua_api/l_localplayer.cpp @@ -483,7 +483,7 @@ int LuaLocalPlayer::l_get_object(lua_State *L) ClientEnvironment &env = getClient(L)->getEnv(); ClientActiveObject *obj = env.getGenericCAO(player->getCAO()->getId()); - ClientObjectRef::create(L, obj); + push_objectRef(L, obj->getId()); return 1; } diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp index 3d9ba132b..cd5ac0753 100644 --- a/src/serverenvironment.cpp +++ b/src/serverenvironment.cpp @@ -1170,7 +1170,7 @@ void ServerEnvironment::clearObjects(ClearObjectsMode mode) // Tell the object about removal obj->removingFromEnvironment(); // Deregister in scripting api - m_script->removeObjectReference(obj); + m_script->removeObjectReference(dynamic_cast(obj)); // Delete active object if (obj->environmentDeletes()) @@ -1736,7 +1736,7 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object, } // Register reference in scripting api (must be done before post-init) - m_script->addObjectReference(object); + m_script->addObjectReference(dynamic_cast(object)); // Post-initialize object object->addedToEnvironment(dtime_s); @@ -1826,7 +1826,7 @@ void ServerEnvironment::removeRemovedObjects() // Tell the object about removal obj->removingFromEnvironment(); // Deregister in scripting api - m_script->removeObjectReference(obj); + m_script->removeObjectReference(dynamic_cast(obj)); // Delete if (obj->environmentDeletes()) @@ -2091,7 +2091,7 @@ void ServerEnvironment::deactivateFarObjects(bool _force_delete) // Tell the object about removal obj->removingFromEnvironment(); // Deregister in scripting api - m_script->removeObjectReference(obj); + m_script->removeObjectReference(dynamic_cast(obj)); // Delete active object if (obj->environmentDeletes()) -- cgit v1.2.3 From b7abc8df281390b1fb5def31866086029209aa67 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Tue, 11 May 2021 19:15:23 +0200 Subject: Add on_object_add callback --- builtin/client/register.lua | 1 + doc/client_lua_api.txt | 2 ++ src/client/content_cao.cpp | 3 +++ src/script/cpp_api/s_client.cpp | 19 +++++++++++++++++-- src/script/cpp_api/s_client.h | 1 + 5 files changed, 24 insertions(+), 2 deletions(-) (limited to 'src/script/cpp_api') diff --git a/builtin/client/register.lua b/builtin/client/register.lua index 6a6d8e13c..f17188b84 100644 --- a/builtin/client/register.lua +++ b/builtin/client/register.lua @@ -107,6 +107,7 @@ 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_on_object_add, core.register_on_object_add = make_registration() core.registered_nodes = {} core.registered_items = {} diff --git a/doc/client_lua_api.txt b/doc/client_lua_api.txt index e33fe0e3a..a02a281f5 100644 --- a/doc/client_lua_api.txt +++ b/doc/client_lua_api.txt @@ -763,6 +763,8 @@ Call these functions only at load time! * Called when recieving a spawn particle command from server * Newest functions are called first * If any function returns true, the particle does not spawn +* `minetest.register_on_object_add(function(obj))` + * Called every time an object is added * `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 diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index 84d200a73..5e9060fc8 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -829,6 +829,9 @@ void GenericCAO::addToScene(ITextureSource *tsrc) setNodeLight(m_last_light); updateMeshCulling(); + if (m_client->modsLoaded()) + m_client->getScript()->on_object_add(m_id); + if (m_client->modsLoaded()) m_client->getScript()->on_object_properties_change(m_id); } diff --git a/src/script/cpp_api/s_client.cpp b/src/script/cpp_api/s_client.cpp index 7971e4081..5990c4df2 100644 --- a/src/script/cpp_api/s_client.cpp +++ b/src/script/cpp_api/s_client.cpp @@ -297,7 +297,7 @@ void ScriptApiClient::on_object_properties_change(s16 id) { SCRIPTAPI_PRECHECKHEADER - // Get core.on_object_properties_change + // Get core.registered_on_object_properties_change lua_getglobal(L, "core"); lua_getfield(L, -1, "registered_on_object_properties_change"); @@ -312,7 +312,7 @@ void ScriptApiClient::on_object_hp_change(s16 id) { SCRIPTAPI_PRECHECKHEADER - // Get core.on_object_hp_change + // Get core.registered_on_object_hp_change lua_getglobal(L, "core"); lua_getfield(L, -1, "registered_on_object_hp_change"); @@ -323,6 +323,21 @@ void ScriptApiClient::on_object_hp_change(s16 id) runCallbacks(1, RUN_CALLBACKS_MODE_FIRST); } +void ScriptApiClient::on_object_add(s16 id) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_object_add + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_object_add"); + + // Push data + push_objectRef(L, id); + + // Call functions + runCallbacks(1, RUN_CALLBACKS_MODE_FIRST); +} + bool ScriptApiClient::on_inventory_open(Inventory *inventory) { SCRIPTAPI_PRECHECKHEADER diff --git a/src/script/cpp_api/s_client.h b/src/script/cpp_api/s_client.h index a2babfac8..12d96d81e 100644 --- a/src/script/cpp_api/s_client.h +++ b/src/script/cpp_api/s_client.h @@ -65,6 +65,7 @@ public: bool on_spawn_particle(struct ParticleParameters param); void on_object_properties_change(s16 id); void on_object_hp_change(s16 id); + void on_object_add(s16 id); bool on_inventory_open(Inventory *inventory); void open_enderchest(); -- cgit v1.2.3 From 96a37aed31cfb9c131e46eda80bdbe3d2289a546 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 13 May 2021 17:21:13 +0200 Subject: Add minetest.get_send_speed --- doc/client_lua_api.txt | 5 +++++ src/client/client.cpp | 16 ++++++++-------- src/client/localplayer.cpp | 10 ++++++++++ src/client/localplayer.h | 2 ++ src/script/cpp_api/s_client.cpp | 21 +++++++++++++++++++++ src/script/cpp_api/s_client.h | 2 ++ 6 files changed, 48 insertions(+), 8 deletions(-) (limited to 'src/script/cpp_api') diff --git a/doc/client_lua_api.txt b/doc/client_lua_api.txt index a02a281f5..3c8b1fbb6 100644 --- a/doc/client_lua_api.txt +++ b/doc/client_lua_api.txt @@ -674,6 +674,11 @@ Minetest namespace reference ### Global callback registration functions Call these functions only at load time! +* `minetest.get_send_speed(speed)` + * This function is called every time the player's speed is sent to server + * The `speed` argument is the actual speed of the player + * If you define it, you can return a modified `speed`. This speed will be + sent to server instead. * `minetest.open_enderchest()` * This function is called if the client uses the Keybind for it (by default "O") * You can override it diff --git a/src/client/client.cpp b/src/client/client.cpp index e0493e973..e6025ed7b 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -913,9 +913,9 @@ void Client::Send(NetworkPacket* pkt) // Will fill up 12 + 12 + 4 + 4 + 4 bytes void writePlayerPos(LocalPlayer *myplayer, ClientMap *clientMap, NetworkPacket *pkt) -{ +{ v3f pf = myplayer->getLegitPosition() * 100; - v3f sf = myplayer->getLegitSpeed() * 100; + v3f sf = myplayer->getSendSpeed() * 100; s32 pitch = myplayer->getPitch() * 100; s32 yaw = myplayer->getYaw() * 100; u32 keyPressed = myplayer->keyPressed; @@ -1286,7 +1286,7 @@ void Client::sendPlayerPos(v3f pos) if ( player->last_position == pos && - player->last_speed == player->getLegitSpeed() && + player->last_speed == player->getSendSpeed() && player->last_pitch == player->getPitch() && player->last_yaw == player->getYaw() && player->last_keyPressed == player->keyPressed && @@ -1295,7 +1295,7 @@ void Client::sendPlayerPos(v3f pos) return; player->last_position = pos; - player->last_speed = player->getLegitSpeed(); + player->last_speed = player->getSendSpeed(); player->last_pitch = player->getPitch(); player->last_yaw = player->getYaw(); player->last_keyPressed = player->keyPressed; @@ -1645,17 +1645,17 @@ void Client::addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server, bool ur void Client::updateAllMapBlocks() { v3s16 currentBlock = getNodeBlockPos(floatToInt(m_env.getLocalPlayer()->getPosition(), BS)); - + for (s16 X = currentBlock.X - 2; X <= currentBlock.X + 2; X++) for (s16 Y = currentBlock.Y - 2; Y <= currentBlock.Y + 2; Y++) for (s16 Z = currentBlock.Z - 2; Z <= currentBlock.Z + 2; Z++) addUpdateMeshTask(v3s16(X, Y, Z), false, true); - + Map &map = m_env.getMap(); - + std::vector positions; map.listAllLoadedBlocks(positions); - + for (v3s16 p : positions) { addUpdateMeshTask(p, false, false); } diff --git a/src/client/localplayer.cpp b/src/client/localplayer.cpp index c75404a4b..24a12c35e 100644 --- a/src/client/localplayer.cpp +++ b/src/client/localplayer.cpp @@ -709,6 +709,16 @@ v3s16 LocalPlayer::getLightPosition() const return floatToInt(m_position + v3f(0.0f, BS * 1.5f, 0.0f), BS); } +v3f LocalPlayer::getSendSpeed() +{ + v3f speed = getLegitSpeed(); + + if (m_client->modsLoaded()) + speed = m_client->getScript()->get_send_speed(speed); + + return speed; +} + v3f LocalPlayer::getEyeOffset() const { float eye_height = camera_barely_in_ceiling ? m_eye_height - 0.125f : m_eye_height; diff --git a/src/client/localplayer.h b/src/client/localplayer.h index 842c18015..eaac216d3 100644 --- a/src/client/localplayer.h +++ b/src/client/localplayer.h @@ -143,6 +143,8 @@ public: v3f getLegitSpeed() const { return m_freecam ? m_legit_speed : m_speed; } + v3f getSendSpeed(); + inline void setLegitPosition(const v3f &position) { if (m_freecam) diff --git a/src/script/cpp_api/s_client.cpp b/src/script/cpp_api/s_client.cpp index 5990c4df2..b0e7a073e 100644 --- a/src/script/cpp_api/s_client.cpp +++ b/src/script/cpp_api/s_client.cpp @@ -365,6 +365,27 @@ void ScriptApiClient::open_enderchest() lua_pcall(L, 0, 0, error_handler); } +v3f ScriptApiClient::get_send_speed(v3f speed) +{ + SCRIPTAPI_PRECHECKHEADER + + PUSH_ERROR_HANDLER(L); + int error_handler = lua_gettop(L) - 1; + lua_insert(L, error_handler); + + lua_getglobal(L, "core"); + lua_getfield(L, -1, "get_send_speed"); + if (lua_isfunction(L, -1)) { + speed /= BS; + push_v3f(L, speed); + lua_pcall(L, 1, 1, error_handler); + speed = read_v3f(L, -1); + speed *= BS; + } + + return speed; +} + void ScriptApiClient::set_node_def(const ContentFeatures &f) { SCRIPTAPI_PRECHECKHEADER diff --git a/src/script/cpp_api/s_client.h b/src/script/cpp_api/s_client.h index 12d96d81e..2f9ce7aa3 100644 --- a/src/script/cpp_api/s_client.h +++ b/src/script/cpp_api/s_client.h @@ -70,6 +70,8 @@ public: bool on_inventory_open(Inventory *inventory); void open_enderchest(); + v3f get_send_speed(v3f speed); + void set_node_def(const ContentFeatures &f); void set_item_def(const ItemDefinition &i); -- cgit v1.2.3 From 5131675a60a73ebc2bb06e343e296950682e3631 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 13 May 2021 18:15:45 +0200 Subject: Add guards to stop server build fail --- src/script/cpp_api/s_base.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/script/cpp_api') diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index 867f61e0c..5711ccbfd 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -361,9 +361,11 @@ void ScriptApiBase::addObjectReference(ActiveObject *cobj) //infostream<<"scriptapi_add_object_reference: id="<getId()<(cobj)); else +#endif ObjectRef::create(L, dynamic_cast(cobj)); // Puts ObjectRef (as userdata) on stack int object = lua_gettop(L); @@ -394,9 +396,11 @@ void ScriptApiBase::removeObjectReference(ActiveObject *cobj) lua_pushnumber(L, cobj->getId()); // Push id lua_gettable(L, objectstable); // Set object reference to NULL +#ifndef SERVER if (m_type == ScriptingType::Client) ClientObjectRef::set_null(L); else +#endif ObjectRef::set_null(L); lua_pop(L, 1); // pop object -- cgit v1.2.3