From 98e36d7d681abc508aa81b6f9df0c8c87c7cfe17 Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Sun, 8 Jan 2017 11:01:35 +0100 Subject: Move ServerEnvironment to dedicated cpp/header files * also cleanup some unneeded inclusions --- src/script/lua_api/l_nodemeta.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/script/lua_api/l_nodemeta.cpp') diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp index c8bc7d558..3cdd3cbfe 100644 --- a/src/script/lua_api/l_nodemeta.cpp +++ b/src/script/lua_api/l_nodemeta.cpp @@ -22,7 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_inventory.h" #include "common/c_converter.h" #include "common/c_content.h" -#include "environment.h" +#include "serverenvironment.h" #include "map.h" #include "gamedef.h" #include "nodemetadata.h" -- cgit v1.2.3 From 8e7449e09253e138716d8dbad6a2ab5c6e089e28 Mon Sep 17 00:00:00 2001 From: Ner'zhul Date: Mon, 9 Jan 2017 20:39:22 +0100 Subject: Environment & IGameDef code refactoring (#4985) * Environment code refactoring * Cleanup includes & class declarations in client & server environment to improve build speed * ServerEnvironment::m_gamedef is now a pointer to Server instead of IGameDef, permitting to cleanup many casts. * Cleanup IGameDef * Move ITextureSource* IGameDef::getTextureSource() to Client only. * Also move ITextureSource *IGameDef::tsrc() helper * drop getShaderSource, getSceneManager, getSoundManager & getCamera abstract call * drop unused emerge() call * cleanup server unused functions (mentionned before) * Drop one unused parameter from ContentFeatures::updateTextures * move checkLocalPrivilege to Client * Remove some unnecessary casts * create_formspec_menu: remove IWritableTextureSource pointer, as client already knows it * Fix some comments * Change required IGameDef to Server/Client pointers * Previous change that game.cpp sometimes calls functions with Client + InventoryManager + IGameDef in same functions but it's the same objects * Remove duplicate Client pointer in GUIFormSpecMenu::GUIFormSpecMenu * drop ClientMap::sectorWasDrawn which is unused --- build/android/jni/Android.mk | 2 ++ src/camera.cpp | 21 ++++++------ src/camera.h | 6 ++-- src/client.cpp | 2 +- src/client.h | 17 +++++----- src/clientenvironment.cpp | 30 +++++++++--------- src/clientenvironment.h | 8 ++--- src/clientmap.cpp | 7 ++-- src/clientmap.h | 21 ++++-------- src/clientobject.cpp | 9 +++--- src/clientobject.h | 21 +++--------- src/collision.cpp | 3 ++ src/content_cao.cpp | 67 +++++++++++++++++++-------------------- src/content_cao.h | 9 +++--- src/content_cso.cpp | 13 +------- src/content_mapblock.cpp | 6 ++-- src/content_sao.cpp | 20 ++++++------ src/emerge.cpp | 14 ++++---- src/emerge.h | 3 +- src/environment.h | 7 ---- src/game.cpp | 59 +++++++++++++++------------------- src/gamedef.h | 29 ++--------------- src/guiEngine.cpp | 2 -- src/guiFormSpecMenu.cpp | 39 +++++++++++------------ src/guiFormSpecMenu.h | 6 +--- src/hud.cpp | 20 ++++++------ src/hud.h | 8 ++--- src/itemdef.cpp | 22 ++++++------- src/itemdef.h | 9 +++--- src/localplayer.cpp | 23 +++++++------- src/localplayer.h | 4 +-- src/mapblock_mesh.cpp | 25 +++++++-------- src/mapblock_mesh.h | 8 ++--- src/mg_biome.cpp | 11 +++---- src/mg_biome.h | 5 +-- src/mg_schematic.cpp | 10 +++--- src/mg_schematic.h | 6 ++-- src/nodedef.cpp | 16 ++++++---- src/nodedef.h | 4 +-- src/particles.cpp | 16 ++++------ src/particles.h | 2 +- src/pathfinder.cpp | 6 +--- src/script/lua_api/l_nodemeta.cpp | 6 +--- src/server.cpp | 18 ----------- src/server.h | 6 +--- src/serverenvironment.cpp | 20 ++++++------ src/serverenvironment.h | 12 ++++--- src/wieldmesh.cpp | 26 +++++++-------- src/wieldmesh.h | 6 ++-- 49 files changed, 301 insertions(+), 409 deletions(-) (limited to 'src/script/lua_api/l_nodemeta.cpp') diff --git a/build/android/jni/Android.mk b/build/android/jni/Android.mk index 2567457b9..3be856770 100644 --- a/build/android/jni/Android.mk +++ b/build/android/jni/Android.mk @@ -117,6 +117,7 @@ LOCAL_SRC_FILES := \ jni/src/cavegen.cpp \ jni/src/chat.cpp \ jni/src/client.cpp \ + jni/src/clientenvironment.cpp \ jni/src/clientiface.cpp \ jni/src/clientmap.cpp \ jni/src/clientmedia.cpp \ @@ -210,6 +211,7 @@ LOCAL_SRC_FILES := \ jni/src/rollback_interface.cpp \ jni/src/serialization.cpp \ jni/src/server.cpp \ + jni/src/serverenvironment.cpp \ jni/src/serverlist.cpp \ jni/src/serverobject.cpp \ jni/src/shader.cpp \ diff --git a/src/camera.cpp b/src/camera.cpp index 43980db1c..4768e8778 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -27,7 +27,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "settings.h" #include "wieldmesh.h" #include "noise.h" // easeCurve -#include "gamedef.h" #include "sound.h" #include "event.h" #include "profiler.h" @@ -41,7 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "nodedef.h" Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control, - IGameDef *gamedef): + Client *client): m_playernode(NULL), m_headnode(NULL), m_cameranode(NULL), @@ -50,7 +49,7 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control, m_wieldnode(NULL), m_draw_control(draw_control), - m_gamedef(gamedef), + m_client(client), m_camera_position(0,0,0), m_camera_direction(0,0,0), @@ -88,7 +87,7 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control, m_wieldmgr = smgr->createNewSceneManager(); m_wieldmgr->addCameraSceneNode(); m_wieldnode = new WieldMeshSceneNode(m_wieldmgr->getRootSceneNode(), m_wieldmgr, -1, false); - m_wieldnode->setItem(ItemStack(), m_gamedef); + m_wieldnode->setItem(ItemStack(), m_client); m_wieldnode->drop(); // m_wieldmgr grabbed it /* TODO: Add a callback function so these can be updated when a setting @@ -151,7 +150,7 @@ void Camera::step(f32 dtime) m_wield_change_timer = MYMIN(m_wield_change_timer + dtime, 0.125); if (m_wield_change_timer >= 0 && was_under_zero) - m_wieldnode->setItem(m_wield_item_next, m_gamedef); + m_wieldnode->setItem(m_wield_item_next, m_client); if (m_view_bobbing_state != 0) { @@ -189,7 +188,7 @@ void Camera::step(f32 dtime) (was > 0.5f && m_view_bobbing_anim <= 0.5f)); if(step) { MtEvent *e = new SimpleTriggerEvent("ViewBobbingStep"); - m_gamedef->event()->put(e); + m_client->event()->put(e); } } } @@ -210,10 +209,10 @@ void Camera::step(f32 dtime) if(m_digging_button == 0) { MtEvent *e = new SimpleTriggerEvent("CameraPunchLeft"); - m_gamedef->event()->put(e); + m_client->event()->put(e); } else if(m_digging_button == 1) { MtEvent *e = new SimpleTriggerEvent("CameraPunchRight"); - m_gamedef->event()->put(e); + m_client->event()->put(e); } } } @@ -352,7 +351,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, my_cp.Y = m_camera_position.Y + (m_camera_direction.Y*-i); // Prevent camera positioned inside nodes - INodeDefManager *nodemgr = m_gamedef->ndef(); + INodeDefManager *nodemgr = m_client->ndef(); MapNode n = c_env.getClientMap().getNodeNoEx(floatToInt(my_cp, BS)); const ContentFeatures& features = nodemgr->get(n); if(features.walkable) @@ -390,7 +389,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, // Get FOV f32 fov_degrees; - if (player->getPlayerControl().zoom && m_gamedef->checkLocalPrivilege("zoom")) { + if (player->getPlayerControl().zoom && m_client->checkLocalPrivilege("zoom")) { fov_degrees = m_cache_zoom_fov; } else { fov_degrees = m_cache_fov; @@ -468,7 +467,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, const bool climbing = movement_Y && player->is_climbing; if ((walking || swimming || climbing) && m_cache_view_bobbing && - (!g_settings->getBool("free_move") || !m_gamedef->checkLocalPrivilege("fly"))) + (!g_settings->getBool("free_move") || !m_client->checkLocalPrivilege("fly"))) { // Start animation m_view_bobbing_state = 1; diff --git a/src/camera.h b/src/camera.h index cb0e9686d..b5be26718 100644 --- a/src/camera.h +++ b/src/camera.h @@ -33,7 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc., class LocalPlayer; struct MapDrawControl; -class IGameDef; +class Client; class WieldMeshSceneNode; struct Nametag { @@ -61,7 +61,7 @@ class Camera { public: Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control, - IGameDef *gamedef); + Client *client); ~Camera(); // Get player scene node. @@ -189,7 +189,7 @@ private: // draw control MapDrawControl& m_draw_control; - IGameDef *m_gamedef; + Client *m_client; video::IVideoDriver *m_driver; // Absolute camera position diff --git a/src/client.cpp b/src/client.cpp index 693a90604..c2471dbd7 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -221,7 +221,7 @@ Client::Client( m_event(event), m_mesh_update_thread(), m_env( - new ClientMap(this, this, control, + new ClientMap(this, control, device->getSceneManager()->getRootSceneNode(), device->getSceneManager(), 666), device->getSceneManager(), diff --git a/src/client.h b/src/client.h index 9a09704a6..df3e7e605 100644 --- a/src/client.h +++ b/src/client.h @@ -34,7 +34,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "localplayer.h" #include "hud.h" #include "particles.h" -#include "network/networkpacket.h" struct MeshMakeData; class MapBlockMesh; @@ -51,6 +50,7 @@ class Database; class Mapper; struct MinimapMapblock; class Camera; +class NetworkPacket; struct QueuedMeshUpdate { @@ -402,9 +402,6 @@ public: void ProcessData(NetworkPacket *pkt); - // Returns true if something was received - bool AsyncProcessPacket(); - bool AsyncProcessData(); void Send(NetworkPacket* pkt); void interact(u8 action, const PointedThing& pointed); @@ -422,8 +419,9 @@ public: void sendRespawn(); void sendReady(); - ClientEnvironment& getEnv() - { return m_env; } + ClientEnvironment& getEnv() { return m_env; } + ITextureSource *tsrc() { return getTextureSource(); } + ISoundManager *sound() { return getSoundManager(); } // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent) void removeNode(v3s16 p); @@ -521,14 +519,15 @@ public: virtual IItemDefManager* getItemDefManager(); virtual INodeDefManager* getNodeDefManager(); virtual ICraftDefManager* getCraftDefManager(); - virtual ITextureSource* getTextureSource(); + ITextureSource* getTextureSource(); virtual IShaderSource* getShaderSource(); - virtual scene::ISceneManager* getSceneManager(); + IShaderSource *shsrc() { return getShaderSource(); } + scene::ISceneManager* getSceneManager(); virtual u16 allocateUnknownNodeId(const std::string &name); virtual ISoundManager* getSoundManager(); virtual MtEventManager* getEventManager(); virtual ParticleManager* getParticleManager(); - virtual bool checkLocalPrivilege(const std::string &priv) + bool checkLocalPrivilege(const std::string &priv) { return checkPrivilege(priv); } virtual scene::IAnimatedMesh* getMesh(const std::string &filename); diff --git a/src/clientenvironment.cpp b/src/clientenvironment.cpp index e831de109..65646c6b4 100644 --- a/src/clientenvironment.cpp +++ b/src/clientenvironment.cpp @@ -34,13 +34,13 @@ with this program; if not, write to the Free Software Foundation, Inc., */ ClientEnvironment::ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr, - ITextureSource *texturesource, IGameDef *gamedef, + ITextureSource *texturesource, Client *client, IrrlichtDevice *irr): m_map(map), m_local_player(NULL), m_smgr(smgr), m_texturesource(texturesource), - m_gamedef(gamedef), + m_client(client), m_irr(irr) { char zero = 0; @@ -94,7 +94,7 @@ void ClientEnvironment::step(float dtime) stepTimeOfDay(dtime); // Get some settings - bool fly_allowed = m_gamedef->checkLocalPrivilege("fly"); + bool fly_allowed = m_client->checkLocalPrivilege("fly"); bool free_move = fly_allowed && g_settings->getBool("free_move"); // Get local player @@ -223,7 +223,7 @@ void ClientEnvironment::step(float dtime) f32 post_factor = 1; // 1 hp per node/s if(info.type == COLLISION_NODE) { - const ContentFeatures &f = m_gamedef->ndef()-> + const ContentFeatures &f = m_client->ndef()-> get(m_map->getNodeNoEx(info.node_p)); // Determine fall damage multiplier int addp = itemgroup_get(f.groups, "fall_damage_add_percent"); @@ -237,7 +237,7 @@ void ClientEnvironment::step(float dtime) if(damage != 0){ damageLocalPlayer(damage, true); MtEvent *e = new SimpleTriggerEvent("PlayerFallingDamage"); - m_gamedef->event()->put(e); + m_client->event()->put(e); } } } @@ -259,11 +259,11 @@ void ClientEnvironment::step(float dtime) u32 damage_per_second = 0; damage_per_second = MYMAX(damage_per_second, - m_gamedef->ndef()->get(n1).damage_per_second); + m_client->ndef()->get(n1).damage_per_second); damage_per_second = MYMAX(damage_per_second, - m_gamedef->ndef()->get(n2).damage_per_second); + m_client->ndef()->get(n2).damage_per_second); damage_per_second = MYMAX(damage_per_second, - m_gamedef->ndef()->get(n3).damage_per_second); + m_client->ndef()->get(n3).damage_per_second); if(damage_per_second != 0) { @@ -272,7 +272,7 @@ void ClientEnvironment::step(float dtime) } // Protocol v29 make this behaviour obsolete - if (((Client*) getGameDef())->getProtoVersion() < 29) { + if (getGameDef()->getProtoVersion() < 29) { /* Drowning */ @@ -282,7 +282,7 @@ void ClientEnvironment::step(float dtime) // head v3s16 p = floatToInt(pf + v3f(0, BS * 1.6, 0), BS); MapNode n = m_map->getNodeNoEx(p); - ContentFeatures c = m_gamedef->ndef()->get(n); + ContentFeatures c = m_client->ndef()->get(n); u8 drowning_damage = c.drowning; if (drowning_damage > 0 && lplayer->hp > 0) { u16 breath = lplayer->getBreath(); @@ -306,7 +306,7 @@ void ClientEnvironment::step(float dtime) // head v3s16 p = floatToInt(pf + v3f(0, BS * 1.6, 0), BS); MapNode n = m_map->getNodeNoEx(p); - ContentFeatures c = m_gamedef->ndef()->get(n); + ContentFeatures c = m_client->ndef()->get(n); if (!lplayer->hp) { lplayer->setBreath(11); } else if (c.drowning == 0) { @@ -332,7 +332,7 @@ void ClientEnvironment::step(float dtime) v3s16 p = lplayer->getLightPosition(); node_at_lplayer = m_map->getNodeNoEx(p); - u16 light = getInteriorLight(node_at_lplayer, 0, m_gamedef->ndef()); + u16 light = getInteriorLight(node_at_lplayer, 0, m_client->ndef()); u8 day = light & 0xff; u8 night = (light >> 8) & 0xff; finalColorBlend(lplayer->light_color, day, night, day_night_ratio); @@ -360,7 +360,7 @@ void ClientEnvironment::step(float dtime) v3s16 p = obj->getLightPosition(); MapNode n = m_map->getNodeNoEx(p, &pos_ok); if (pos_ok) - light = n.getLightBlend(day_night_ratio, m_gamedef->ndef()); + light = n.getLightBlend(day_night_ratio, m_client->ndef()); else light = blend_light(day_night_ratio, LIGHT_SUN, 0); @@ -467,7 +467,7 @@ u16 ClientEnvironment::addActiveObject(ClientActiveObject *object) v3s16 p = object->getLightPosition(); MapNode n = m_map->getNodeNoEx(p, &pos_ok); if (pos_ok) - light = n.getLightBlend(getDayNightRatio(), m_gamedef->ndef()); + light = n.getLightBlend(getDayNightRatio(), m_client->ndef()); else light = blend_light(getDayNightRatio(), LIGHT_SUN, 0); @@ -480,7 +480,7 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type, const std::string &init_data) { ClientActiveObject* obj = - ClientActiveObject::create((ActiveObjectType) type, m_gamedef, this); + ClientActiveObject::create((ActiveObjectType) type, m_client, this); if(obj == NULL) { infostream<<"ClientEnvironment::addActiveObject(): " diff --git a/src/clientenvironment.h b/src/clientenvironment.h index e6292b5b7..b30a7a6d7 100644 --- a/src/clientenvironment.h +++ b/src/clientenvironment.h @@ -30,6 +30,7 @@ class ClientMap; class ClientActiveObject; class GenericCAO; class LocalPlayer; +struct PointedThing; /* The client-side environment. @@ -66,15 +67,14 @@ class ClientEnvironment : public Environment { public: ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr, - ITextureSource *texturesource, IGameDef *gamedef, + ITextureSource *texturesource, Client *client, IrrlichtDevice *device); ~ClientEnvironment(); Map & getMap(); ClientMap & getClientMap(); - IGameDef *getGameDef() - { return m_gamedef; } + Client *getGameDef() { return m_client; } void step(f32 dtime); @@ -175,7 +175,7 @@ private: LocalPlayer *m_local_player; scene::ISceneManager *m_smgr; ITextureSource *m_texturesource; - IGameDef *m_gamedef; + Client *m_client; IrrlichtDevice *m_irr; UNORDERED_MAP m_active_objects; std::vector m_simple_objects; diff --git a/src/clientmap.cpp b/src/clientmap.cpp index 542eb03e8..7e688daad 100644 --- a/src/clientmap.cpp +++ b/src/clientmap.cpp @@ -35,13 +35,12 @@ with this program; if not, write to the Free Software Foundation, Inc., ClientMap::ClientMap( Client *client, - IGameDef *gamedef, MapDrawControl &control, scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id ): - Map(dout_client, gamedef), + Map(dout_client, client), scene::ISceneNode(parent, mgr, id), m_client(client), m_control(control), @@ -140,7 +139,7 @@ static bool isOccluded(Map *map, v3s16 p0, v3s16 p1, float step, float stepfac, return false; } -void ClientMap::getBlocksInViewRange(v3s16 cam_pos_nodes, +void ClientMap::getBlocksInViewRange(v3s16 cam_pos_nodes, v3s16 *p_blocks_min, v3s16 *p_blocks_max) { v3s16 box_nodes_d = m_control.wanted_range * v3s16(1, 1, 1); @@ -766,7 +765,7 @@ void ClientMap::renderPostFx(CameraMode cam_mode) const ContentFeatures& features = m_nodedef->get(n); video::SColor post_effect_color = features.post_effect_color; if(features.solidness == 2 && !(g_settings->getBool("noclip") && - m_gamedef->checkLocalPrivilege("noclip")) && + m_client->checkLocalPrivilege("noclip")) && cam_mode == CAMERA_MODE_FIRST) { post_effect_color = video::SColor(255, 0, 0, 0); diff --git a/src/clientmap.h b/src/clientmap.h index cb686ff33..84228f4ca 100644 --- a/src/clientmap.h +++ b/src/clientmap.h @@ -59,7 +59,7 @@ class ITextureSource; /* ClientMap - + This is the only map class that is able to render itself on screen. */ @@ -68,7 +68,6 @@ class ClientMap : public Map, public scene::ISceneNode public: ClientMap( Client *client, - IGameDef *gamedef, MapDrawControl &control, scene::ISceneNode* parent, scene::ISceneManager* mgr, @@ -114,13 +113,13 @@ public: driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); renderMap(driver, SceneManager->getSceneNodeRenderPass()); } - + virtual const aabb3f &getBoundingBox() const { return m_box; } - - void getBlocksInViewRange(v3s16 cam_pos_nodes, + + void getBlocksInViewRange(v3s16 cam_pos_nodes, v3s16 *p_blocks_min, v3s16 *p_blocks_max); void updateDrawList(video::IVideoDriver* driver); void renderMap(video::IVideoDriver* driver, s32 pass); @@ -132,20 +131,14 @@ public: // For debug printing virtual void PrintInfo(std::ostream &out); - - // Check if sector was drawn on last render() - bool sectorWasDrawn(v2s16 p) - { - return (m_last_drawn_sectors.find(p) != m_last_drawn_sectors.end()); - } const MapDrawControl & getControl() const { return m_control; } f32 getCameraFov() const { return m_camera_fov; } private: Client *m_client; - + aabb3f m_box; - + MapDrawControl &m_control; v3f m_camera_position; @@ -154,7 +147,7 @@ private: v3s16 m_camera_offset; std::map m_drawlist; - + std::set m_last_drawn_sectors; bool m_cache_trilinear_filter; diff --git a/src/clientobject.cpp b/src/clientobject.cpp index ff3f47187..89a0474a4 100644 --- a/src/clientobject.cpp +++ b/src/clientobject.cpp @@ -20,16 +20,15 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "clientobject.h" #include "debug.h" #include "porting.h" -#include "constants.h" /* ClientActiveObject */ -ClientActiveObject::ClientActiveObject(u16 id, IGameDef *gamedef, +ClientActiveObject::ClientActiveObject(u16 id, Client *client, ClientEnvironment *env): ActiveObject(id), - m_gamedef(gamedef), + m_client(client), m_env(env) { } @@ -40,7 +39,7 @@ ClientActiveObject::~ClientActiveObject() } ClientActiveObject* ClientActiveObject::create(ActiveObjectType type, - IGameDef *gamedef, ClientEnvironment *env) + Client *client, ClientEnvironment *env) { // Find factory function UNORDERED_MAP::iterator n = m_types.find(type); @@ -52,7 +51,7 @@ ClientActiveObject* ClientActiveObject::create(ActiveObjectType type, } Factory f = n->second; - ClientActiveObject *object = (*f)(gamedef, env); + ClientActiveObject *object = (*f)(client, env); return object; } diff --git a/src/clientobject.h b/src/clientobject.h index 83931e438..f0bde0adc 100644 --- a/src/clientobject.h +++ b/src/clientobject.h @@ -25,20 +25,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "util/cpp11_container.h" -/* - -Some planning -------------- - -* Client receives a network packet with information of added objects - in it -* Client supplies the information to its ClientEnvironment -* The environment adds the specified objects to itself - -*/ - class ClientEnvironment; class ITextureSource; +class Client; class IGameDef; class LocalPlayer; struct ItemStack; @@ -47,7 +36,7 @@ class WieldMeshSceneNode; class ClientActiveObject : public ActiveObject { public: - ClientActiveObject(u16 id, IGameDef *gamedef, ClientEnvironment *env); + ClientActiveObject(u16 id, Client *client, ClientEnvironment *env); virtual ~ClientActiveObject(); virtual void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, @@ -89,7 +78,7 @@ public: virtual void initialize(const std::string &data){} // Create a certain type of ClientActiveObject - static ClientActiveObject* create(ActiveObjectType type, IGameDef *gamedef, + static ClientActiveObject* create(ActiveObjectType type, Client *client, ClientEnvironment *env); // If returns true, punch will not be sent to the server @@ -99,9 +88,9 @@ public: protected: // Used for creating objects based on type - typedef ClientActiveObject* (*Factory)(IGameDef *gamedef, ClientEnvironment *env); + typedef ClientActiveObject* (*Factory)(Client *client, ClientEnvironment *env); static void registerType(u16 type, Factory f); - IGameDef *m_gamedef; + Client *m_client; ClientEnvironment *m_env; private: // Used for creating objects based on type diff --git a/src/collision.cpp b/src/collision.cpp index 595fa8059..c0891c152 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -22,9 +22,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "map.h" #include "nodedef.h" #include "gamedef.h" +#ifndef SERVER #include "clientenvironment.h" +#endif #include "serverenvironment.h" #include "serverobject.h" +#include "util/timetaker.h" #include "profiler.h" // float error is 10 - 9.96875 = 0.03125 diff --git a/src/content_cao.cpp b/src/content_cao.cpp index a02d5168e..a4c0bf14d 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -33,7 +33,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "collision.h" #include "settings.h" #include "serialization.h" // For decompressZlib -#include "gamedef.h" #include "clientobject.h" #include "mesh.h" #include "itemdef.h" @@ -139,7 +138,7 @@ static void setBillboardTextureMatrix(scene::IBillboardSceneNode *bill, class TestCAO : public ClientActiveObject { public: - TestCAO(IGameDef *gamedef, ClientEnvironment *env); + TestCAO(Client *client, ClientEnvironment *env); virtual ~TestCAO(); ActiveObjectType getType() const @@ -147,7 +146,7 @@ public: return ACTIVEOBJECT_TYPE_TEST; } - static ClientActiveObject* create(IGameDef *gamedef, ClientEnvironment *env); + static ClientActiveObject* create(Client *client, ClientEnvironment *env); void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, IrrlichtDevice *irr); @@ -169,8 +168,8 @@ private: // Prototype TestCAO proto_TestCAO(NULL, NULL); -TestCAO::TestCAO(IGameDef *gamedef, ClientEnvironment *env): - ClientActiveObject(0, gamedef, env), +TestCAO::TestCAO(Client *client, ClientEnvironment *env): + ClientActiveObject(0, client, env), m_node(NULL), m_position(v3f(0,10*BS,0)) { @@ -181,9 +180,9 @@ TestCAO::~TestCAO() { } -ClientActiveObject* TestCAO::create(IGameDef *gamedef, ClientEnvironment *env) +ClientActiveObject* TestCAO::create(Client *client, ClientEnvironment *env) { - return new TestCAO(gamedef, env); + return new TestCAO(client, env); } void TestCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, @@ -283,7 +282,7 @@ void TestCAO::processMessage(const std::string &data) class ItemCAO : public ClientActiveObject { public: - ItemCAO(IGameDef *gamedef, ClientEnvironment *env); + ItemCAO(Client *client, ClientEnvironment *env); virtual ~ItemCAO(); ActiveObjectType getType() const @@ -291,7 +290,7 @@ public: return ACTIVEOBJECT_TYPE_ITEM; } - static ClientActiveObject* create(IGameDef *gamedef, ClientEnvironment *env); + static ClientActiveObject* create(Client *client, ClientEnvironment *env); void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, IrrlichtDevice *irr); @@ -331,13 +330,13 @@ private: // Prototype ItemCAO proto_ItemCAO(NULL, NULL); -ItemCAO::ItemCAO(IGameDef *gamedef, ClientEnvironment *env): - ClientActiveObject(0, gamedef, env), +ItemCAO::ItemCAO(Client *client, ClientEnvironment *env): + ClientActiveObject(0, client, env), m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.), m_node(NULL), m_position(v3f(0,10*BS,0)) { - if(!gamedef && !env) + if(!client && !env) { ClientActiveObject::registerType(getType(), create); } @@ -347,9 +346,9 @@ ItemCAO::~ItemCAO() { } -ClientActiveObject* ItemCAO::create(IGameDef *gamedef, ClientEnvironment *env) +ClientActiveObject* ItemCAO::create(Client *client, ClientEnvironment *env) { - return new ItemCAO(gamedef, env); + return new ItemCAO(client, env); } void ItemCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, @@ -433,7 +432,7 @@ void ItemCAO::updateNodePos() void ItemCAO::updateInfoText() { try{ - IItemDefManager *idef = m_gamedef->idef(); + IItemDefManager *idef = m_client->idef(); ItemStack item; item.deSerialize(m_itemstring, idef); if(item.isKnown(idef)) @@ -458,10 +457,10 @@ void ItemCAO::updateTexture() std::istringstream is(m_itemstring, std::ios_base::binary); video::ITexture *texture = NULL; try{ - IItemDefManager *idef = m_gamedef->idef(); + IItemDefManager *idef = m_client->idef(); ItemStack item; item.deSerialize(is, idef); - texture = idef->getInventoryTexture(item.getDefinition(idef).name, m_gamedef); + texture = idef->getInventoryTexture(item.getDefinition(idef).name, m_client); } catch(SerializationError &e) { @@ -538,15 +537,15 @@ void ItemCAO::initialize(const std::string &data) #include "genericobject.h" -GenericCAO::GenericCAO(IGameDef *gamedef, ClientEnvironment *env): - ClientActiveObject(0, gamedef, env), +GenericCAO::GenericCAO(Client *client, ClientEnvironment *env): + ClientActiveObject(0, client, env), // m_is_player(false), m_is_local_player(false), // m_smgr(NULL), m_irr(NULL), - m_gamedef(NULL), + m_client(NULL), m_selection_box(-BS/3.,-BS/3.,-BS/3., BS/3.,BS/3.,BS/3.), m_meshnode(NULL), m_animated_meshnode(NULL), @@ -581,10 +580,10 @@ GenericCAO::GenericCAO(IGameDef *gamedef, ClientEnvironment *env): m_last_light(255), m_is_visible(false) { - if (gamedef == NULL) { + if (client == NULL) { ClientActiveObject::registerType(getType(), create); } else { - m_gamedef = gamedef; + m_client = client; } } @@ -793,7 +792,7 @@ void GenericCAO::removeFromScene(bool permanent) } if (m_nametag) { - m_gamedef->getCamera()->removeNametag(m_nametag); + m_client->getCamera()->removeNametag(m_nametag); m_nametag = NULL; } } @@ -906,7 +905,7 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, } else if(m_prop.visual == "mesh") { infostream<<"GenericCAO::addToScene(): mesh"<getMesh(m_prop.mesh); + scene::IAnimatedMesh *mesh = m_client->getMesh(m_prop.mesh); if(mesh) { m_animated_meshnode = smgr->addAnimatedMeshSceneNode(mesh, NULL); @@ -937,12 +936,12 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, infostream<<"textures: "<= 1){ infostream<<"textures[0]: "<idef(); + IItemDefManager *idef = m_client->idef(); ItemStack item(m_prop.textures[0], 1, 0, "", idef); m_wield_meshnode = new WieldMeshSceneNode( smgr->getRootSceneNode(), smgr, -1); - m_wield_meshnode->setItem(item, m_gamedef); + m_wield_meshnode->setItem(item, m_client); m_wield_meshnode->setScale(v3f(m_prop.visual_size.X/2, m_prop.visual_size.Y/2, @@ -959,7 +958,7 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, scene::ISceneNode *node = getSceneNode(); if (node && m_prop.nametag != "" && !m_is_local_player) { // Add nametag - m_nametag = m_gamedef->getCamera()->addNametag(node, + m_nametag = m_client->getCamera()->addNametag(node, m_prop.nametag, m_prop.nametag_color); } @@ -1058,11 +1057,11 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) // increase speed if using fast or flying fast if((g_settings->getBool("fast_move") && - m_gamedef->checkLocalPrivilege("fast")) && + m_client->checkLocalPrivilege("fast")) && (controls.aux1 || (!player->touching_ground && g_settings->getBool("free_move") && - m_gamedef->checkLocalPrivilege("fly")))) + m_client->checkLocalPrivilege("fly")))) new_speed *= 1.5; // slowdown speed if sneeking if(controls.sneak && walking) @@ -1129,7 +1128,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) } removeFromScene(false); - addToScene(m_smgr, m_gamedef->tsrc(), m_irr); + addToScene(m_smgr, m_client->tsrc(), m_irr); // Attachments, part 2: Now that the parent has been refreshed, put its attachments back for (std::vector::size_type i = 0; i < m_children.size(); i++) { @@ -1199,12 +1198,12 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) m_step_distance_counter = 0; if(!m_is_local_player && m_prop.makes_footstep_sound) { - INodeDefManager *ndef = m_gamedef->ndef(); + INodeDefManager *ndef = m_client->ndef(); v3s16 p = floatToInt(getPosition() + v3f(0, (m_prop.collisionbox.MinEdge.Y-0.5)*BS, 0), BS); MapNode n = m_env->getMap().getNodeNoEx(p); SimpleSoundSpec spec = ndef->get(n).sound_footstep; - m_gamedef->sound()->playSoundAt(spec, false, getPosition()); + m_client->sound()->playSoundAt(spec, false, getPosition()); } } } @@ -1305,7 +1304,7 @@ void GenericCAO::updateTexturePos() void GenericCAO::updateTextures(const std::string &mod) { - ITextureSource *tsrc = m_gamedef->tsrc(); + ITextureSource *tsrc = m_client->tsrc(); bool use_trilinear_filter = g_settings->getBool("trilinear_filter"); bool use_bilinear_filter = g_settings->getBool("bilinear_filter"); @@ -1778,7 +1777,7 @@ bool GenericCAO::directReportPunch(v3f dir, const ItemStack *punchitem, { assert(punchitem); // pre-condition const ToolCapabilities *toolcap = - &punchitem->getToolCapabilities(m_gamedef->idef()); + &punchitem->getToolCapabilities(m_client->idef()); PunchDamageResult result = getPunchDamage( m_armor_groups, toolcap, diff --git a/src/content_cao.h b/src/content_cao.h index a158e8296..96a160055 100644 --- a/src/content_cao.h +++ b/src/content_cao.h @@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "itemgroup.h" class Camera; +class Client; struct Nametag; /* @@ -68,7 +69,7 @@ private: // scene::ISceneManager *m_smgr; IrrlichtDevice *m_irr; - IGameDef *m_gamedef; + Client *m_client; aabb3f m_selection_box; scene::IMeshSceneNode *m_meshnode; scene::IAnimatedMeshSceneNode *m_animated_meshnode; @@ -109,13 +110,13 @@ private: std::vector m_children; public: - GenericCAO(IGameDef *gamedef, ClientEnvironment *env); + GenericCAO(Client *client, ClientEnvironment *env); ~GenericCAO(); - static ClientActiveObject* create(IGameDef *gamedef, ClientEnvironment *env) + static ClientActiveObject* create(Client *client, ClientEnvironment *env) { - return new GenericCAO(gamedef, env); + return new GenericCAO(client, env); } inline ActiveObjectType getType() const diff --git a/src/content_cso.cpp b/src/content_cso.cpp index c0407f460..aca71212b 100644 --- a/src/content_cso.cpp +++ b/src/content_cso.cpp @@ -21,20 +21,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "client/tile.h" #include "clientenvironment.h" -#include "gamedef.h" +#include "client.h" #include "map.h" -/* -static void setBillboardTextureMatrix(scene::IBillboardSceneNode *bill, - float txs, float tys, int col, int row) -{ - video::SMaterial& material = bill->getMaterial(0); - core::matrix4& matrix = material.getTextureMatrix(0); - matrix.setTextureTranslate(txs*col, tys*row); - matrix.setTextureScale(txs, tys); -} -*/ - class SmokePuffCSO: public ClientSimpleObject { float m_age; diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index 8ce0f1e0a..a7134590b 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -26,7 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "client/tile.h" #include "mesh.h" #include -#include "gamedef.h" +#include "client.h" #include "log.h" #include "noise.h" @@ -188,8 +188,8 @@ static inline int NeighborToIndex(const v3s16 &pos) void mapblock_mesh_generate_special(MeshMakeData *data, MeshCollector &collector) { - INodeDefManager *nodedef = data->m_gamedef->ndef(); - scene::ISceneManager* smgr = data->m_gamedef->getSceneManager(); + INodeDefManager *nodedef = data->m_client->ndef(); + scene::ISceneManager* smgr = data->m_client->getSceneManager(); scene::IMeshManipulator* meshmanip = smgr->getMeshManipulator(); // 0ms diff --git a/src/content_sao.cpp b/src/content_sao.cpp index f866d4372..dd8bdc592 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -273,7 +273,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended) v3f p_pos = m_base_position; v3f p_velocity = m_velocity; v3f p_acceleration = m_acceleration; - moveresult = collisionMoveSimple(m_env,m_env->getGameDef(), + moveresult = collisionMoveSimple(m_env, m_env->getGameDef(), pos_max_d, box, m_prop.stepheight, dtime, &p_pos, &p_velocity, p_acceleration, this, m_prop.collideWithObjects); @@ -945,7 +945,7 @@ void PlayerSAO::step(float dtime, bool send_recommended) // get head position v3s16 p = floatToInt(m_base_position + v3f(0, BS * 1.6, 0), BS); MapNode n = m_env->getMap().getNodeNoEx(p); - const ContentFeatures &c = ((Server*) m_env->getGameDef())->ndef()->get(n); + const ContentFeatures &c = m_env->getGameDef()->ndef()->get(n); // If node generates drown if (c.drowning > 0) { if (m_hp > 0 && m_breath > 0) @@ -954,7 +954,7 @@ void PlayerSAO::step(float dtime, bool send_recommended) // No more breath, damage player if (m_breath == 0) { setHP(m_hp - c.drowning); - ((Server*) m_env->getGameDef())->SendPlayerHPOrDie(this); + m_env->getGameDef()->SendPlayerHPOrDie(this); } } } @@ -963,7 +963,7 @@ void PlayerSAO::step(float dtime, bool send_recommended) // get head position v3s16 p = floatToInt(m_base_position + v3f(0, BS * 1.6, 0), BS); MapNode n = m_env->getMap().getNodeNoEx(p); - const ContentFeatures &c = ((Server*) m_env->getGameDef())->ndef()->get(n); + const ContentFeatures &c = m_env->getGameDef()->ndef()->get(n); // If player is alive & no drowning, breath if (m_hp > 0 && c.drowning == 0) setBreath(m_breath + 1); @@ -985,7 +985,7 @@ void PlayerSAO::step(float dtime, bool send_recommended) m_attachment_position = v3f(0,0,0); m_attachment_rotation = v3f(0,0,0); setBasePosition(m_last_good_position); - ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); + m_env->getGameDef()->SendMovePlayer(m_peer_id); } //dstream<<"PlayerSAO::step: dtime: "<getGameDef())->SendMovePlayer(m_peer_id); + m_env->getGameDef()->SendMovePlayer(m_peer_id); } void PlayerSAO::moveTo(v3f pos, bool continuous) @@ -1118,7 +1118,7 @@ void PlayerSAO::moveTo(v3f pos, bool continuous) setBasePosition(pos); // Movement caused by this command is always valid m_last_good_position = pos; - ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); + m_env->getGameDef()->SendMovePlayer(m_peer_id); } void PlayerSAO::setYaw(const float yaw) @@ -1148,7 +1148,7 @@ void PlayerSAO::setWantedRange(const s16 range) void PlayerSAO::setYawAndSend(const float yaw) { setYaw(yaw); - ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); + m_env->getGameDef()->SendMovePlayer(m_peer_id); } void PlayerSAO::setPitch(const float pitch) @@ -1162,7 +1162,7 @@ void PlayerSAO::setPitch(const float pitch) void PlayerSAO::setPitchAndSend(const float pitch) { setPitch(pitch); - ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); + m_env->getGameDef()->SendMovePlayer(m_peer_id); } int PlayerSAO::punch(v3f dir, @@ -1273,7 +1273,7 @@ void PlayerSAO::setBreath(const u16 breath, bool send) m_breath = MYMIN(breath, PLAYER_MAX_BREATH); if (send) - ((Server *) m_env->getGameDef())->SendPlayerBreath(this); + m_env->getGameDef()->SendPlayerBreath(this); } void PlayerSAO::setArmorGroups(const ItemGroupList &armor_groups) diff --git a/src/emerge.cpp b/src/emerge.cpp index 25b2e924b..3f0a46010 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -89,13 +89,13 @@ private: //// EmergeManager //// -EmergeManager::EmergeManager(IGameDef *gamedef) +EmergeManager::EmergeManager(Server *server) { - this->ndef = gamedef->getNodeDefManager(); - this->biomemgr = new BiomeManager(gamedef); - this->oremgr = new OreManager(gamedef); - this->decomgr = new DecorationManager(gamedef); - this->schemmgr = new SchematicManager(gamedef); + this->ndef = server->getNodeDefManager(); + this->biomemgr = new BiomeManager(server); + this->oremgr = new OreManager(server); + this->decomgr = new DecorationManager(server); + this->schemmgr = new SchematicManager(server); this->gen_notify_on = 0; // Note that accesses to this variable are not synchronized. @@ -128,7 +128,7 @@ EmergeManager::EmergeManager(IGameDef *gamedef) m_qlimit_generate = 1; for (s16 i = 0; i < nthreads; i++) - m_threads.push_back(new EmergeThread((Server *)gamedef, i)); + m_threads.push_back(new EmergeThread(server, i)); infostream << "EmergeManager: using " << nthreads << " threads" << std::endl; } diff --git a/src/emerge.h b/src/emerge.h index 71ad97da3..76653e6cd 100644 --- a/src/emerge.h +++ b/src/emerge.h @@ -42,6 +42,7 @@ class BiomeManager; class OreManager; class DecorationManager; class SchematicManager; +class Server; // Structure containing inputs/outputs for chunk generation struct BlockMakeData { @@ -115,7 +116,7 @@ public: SchematicManager *schemmgr; // Methods - EmergeManager(IGameDef *gamedef); + EmergeManager(Server *server); ~EmergeManager(); bool initMapgens(MapgenParams *mgparams); diff --git a/src/environment.h b/src/environment.h index 14a18421b..0cc3222f9 100644 --- a/src/environment.h +++ b/src/environment.h @@ -42,13 +42,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "threading/atomic.h" #include "network/networkprotocol.h" // for AccessDeniedCode -class ITextureSource; -class IGameDef; -class Map; -class GameScripting; -class Player; -class PointedThing; - class Environment { public: diff --git a/src/game.cpp b/src/game.cpp index cfa6234ff..1070cb1b2 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -916,16 +916,14 @@ bool nodePlacementPrediction(Client &client, } static inline void create_formspec_menu(GUIFormSpecMenu **cur_formspec, - InventoryManager *invmgr, IGameDef *gamedef, - IWritableTextureSource *tsrc, IrrlichtDevice *device, - JoystickController *joystick, - IFormSource *fs_src, TextDest *txt_dest, Client *client) + Client *client, IrrlichtDevice *device, JoystickController *joystick, + IFormSource *fs_src, TextDest *txt_dest) { if (*cur_formspec == 0) { *cur_formspec = new GUIFormSpecMenu(device, joystick, - guiroot, -1, &g_menumgr, invmgr, gamedef, tsrc, - fs_src, txt_dest, client); + guiroot, -1, &g_menumgr, client, client->getTextureSource(), + fs_src, txt_dest); (*cur_formspec)->doPause = false; /* @@ -950,9 +948,9 @@ static inline void create_formspec_menu(GUIFormSpecMenu **cur_formspec, #endif static void show_deathscreen(GUIFormSpecMenu **cur_formspec, - InventoryManager *invmgr, IGameDef *gamedef, + Client *client, IWritableTextureSource *tsrc, IrrlichtDevice *device, - JoystickController *joystick, Client *client) + JoystickController *joystick) { std::string formspec = std::string(FORMSPEC_VERSION_STRING) + @@ -968,13 +966,12 @@ static void show_deathscreen(GUIFormSpecMenu **cur_formspec, FormspecFormSource *fs_src = new FormspecFormSource(formspec); LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_DEATH_SCREEN", client); - create_formspec_menu(cur_formspec, invmgr, gamedef, tsrc, device, - joystick, fs_src, txt_dst, NULL); + create_formspec_menu(cur_formspec, client, device, joystick, fs_src, txt_dst); } /******************************************************************************/ static void show_pause_menu(GUIFormSpecMenu **cur_formspec, - InventoryManager *invmgr, IGameDef *gamedef, + Client *client, IWritableTextureSource *tsrc, IrrlichtDevice *device, JoystickController *joystick, bool singleplayermode) { @@ -1041,8 +1038,7 @@ static void show_pause_menu(GUIFormSpecMenu **cur_formspec, FormspecFormSource *fs_src = new FormspecFormSource(os.str()); LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_PAUSE_MENU"); - create_formspec_menu(cur_formspec, invmgr, gamedef, tsrc, device, - joystick, fs_src, txt_dst, NULL); + create_formspec_menu(cur_formspec, client, device, joystick, fs_src, txt_dst); std::string con("btn_continue"); (*cur_formspec)->setFocus(con); (*cur_formspec)->doPause = true; @@ -1534,7 +1530,6 @@ private: bool *kill; std::string *error_message; bool *reconnect_requested; - IGameDef *gamedef; // Convenience (same as *client) scene::ISceneNode *skybox; bool random_input; @@ -2011,7 +2006,7 @@ bool Game::createClient(const std::string &playername, /* Camera */ - camera = new Camera(smgr, *draw_control, gamedef); + camera = new Camera(smgr, *draw_control, client); if (!camera || !camera->successfullyCreated(*error_message)) return false; client->setCamera(camera); @@ -2068,7 +2063,7 @@ bool Game::createClient(const std::string &playername, player->hurt_tilt_timer = 0; player->hurt_tilt_strength = 0; - hud = new Hud(driver, smgr, guienv, gamedef, player, local_inventory); + hud = new Hud(driver, smgr, guienv, client, player, local_inventory); if (!hud) { *error_message = "Memory error: could not create HUD"; @@ -2198,8 +2193,6 @@ bool Game::connectToServer(const std::string &playername, if (!client) return false; - gamedef = client; // Client acts as our GameDef - infostream << "Connecting to server at "; connect_address.print(&infostream); infostream << std::endl; @@ -2445,7 +2438,7 @@ inline bool Game::handleCallbacks() void Game::processQueues() { texture_src->processQueue(); - itemdef_manager->processQueue(gamedef); + itemdef_manager->processQueue(client); shader_src->processQueue(); } @@ -2617,7 +2610,7 @@ void Game::processKeyInput(VolatileRunFlags *flags, openInventory(); } else if (wasKeyDown(KeyType::ESC) || input->wasKeyDown(CancelKey)) { if (!gui_chat_console->isOpenInhibited()) { - show_pause_menu(¤t_formspec, client, gamedef, + show_pause_menu(¤t_formspec, client, texture_src, device, &input->joystick, simple_singleplayer_mode); } @@ -2769,8 +2762,7 @@ void Game::openInventory() PlayerInventoryFormSource *fs_src = new PlayerInventoryFormSource(client); TextDest *txt_dst = new TextDestPlayerInventory(client); - create_formspec_menu(¤t_formspec, client, gamedef, texture_src, - device, &input->joystick, fs_src, txt_dst, client); + create_formspec_menu(¤t_formspec, client, device, &input->joystick, fs_src, txt_dst); cur_formname = ""; InventoryLocation inventoryloc; @@ -3245,13 +3237,13 @@ void Game::processClientEvents(CameraOrientation *cam, float *damage_flash) rangelim(event.player_damage.amount / 4, 1.0, 4.0); MtEvent *e = new SimpleTriggerEvent("PlayerDamage"); - gamedef->event()->put(e); + client->event()->put(e); } else if (event.type == CE_PLAYER_FORCE_MOVE) { cam->camera_yaw = event.player_force_move.yaw; cam->camera_pitch = event.player_force_move.pitch; } else if (event.type == CE_DEATHSCREEN) { - show_deathscreen(¤t_formspec, client, gamedef, texture_src, - device, &input->joystick, client); + show_deathscreen(¤t_formspec, client, texture_src, + device, &input->joystick); chat_backend->addMessage(L"", L"You died."); @@ -3271,9 +3263,8 @@ void Game::processClientEvents(CameraOrientation *cam, float *damage_flash) TextDestPlayerInventory *txt_dst = new TextDestPlayerInventory(client, *(event.show_formspec.formname)); - create_formspec_menu(¤t_formspec, client, gamedef, - texture_src, device, &input->joystick, - fs_src, txt_dst, client); + create_formspec_menu(¤t_formspec, client, device, &input->joystick, + fs_src, txt_dst); cur_formname = *(event.show_formspec.formname); } @@ -3282,7 +3273,7 @@ void Game::processClientEvents(CameraOrientation *cam, float *damage_flash) } else if ((event.type == CE_SPAWN_PARTICLE) || (event.type == CE_ADD_PARTICLESPAWNER) || (event.type == CE_DELETE_PARTICLESPAWNER)) { - client->getParticleManager()->handleParticleEvent(&event, gamedef, + client->getParticleManager()->handleParticleEvent(&event, client, smgr, player); } else if (event.type == CE_HUDADD) { u32 id = event.hudadd.id; @@ -3840,8 +3831,8 @@ void Game::handlePointingAtNode(GameRunData *runData, &client->getEnv().getClientMap(), nodepos); TextDest *txt_dst = new TextDestNodeMetadata(nodepos, client); - create_formspec_menu(¤t_formspec, client, gamedef, - texture_src, device, &input->joystick, fs_src, txt_dst, client); + create_formspec_menu(¤t_formspec, client, + device, &input->joystick, fs_src, txt_dst); cur_formname = ""; current_formspec->setFormSpec(meta->getString("formspec"), inventoryloc); @@ -3972,7 +3963,7 @@ void Game::handleDigging(GameRunData *runData, if (m_cache_enable_particles) { const ContentFeatures &features = client->getNodeDefManager()->get(n); - client->getParticleManager()->addPunchingParticles(gamedef, smgr, + client->getParticleManager()->addPunchingParticles(client, smgr, player, nodepos, features.tiles); } } @@ -4019,7 +4010,7 @@ void Game::handleDigging(GameRunData *runData, if (m_cache_enable_particles) { const ContentFeatures &features = client->getNodeDefManager()->get(wasnode); - client->getParticleManager()->addDiggingParticles(gamedef, smgr, + client->getParticleManager()->addDiggingParticles(client, smgr, player, nodepos, features.tiles); } @@ -4043,7 +4034,7 @@ void Game::handleDigging(GameRunData *runData, // Send event to trigger sound MtEvent *e = new NodeDugEvent(nodepos, wasnode); - gamedef->event()->put(e); + client->event()->put(e); } if (runData->dig_time_complete < 100000.0) { diff --git a/src/gamedef.h b/src/gamedef.h index 7e3da4cac..cb624bd6a 100644 --- a/src/gamedef.h +++ b/src/gamedef.h @@ -53,47 +53,22 @@ public: virtual INodeDefManager* getNodeDefManager()=0; virtual ICraftDefManager* getCraftDefManager()=0; - // This is always thread-safe, but referencing the irrlicht texture - // pointers in other threads than main thread will make things explode. - virtual ITextureSource* getTextureSource()=0; - - virtual IShaderSource* getShaderSource()=0; - // Used for keeping track of names/ids of unknown nodes virtual u16 allocateUnknownNodeId(const std::string &name)=0; - // Only usable on the client - virtual ISoundManager* getSoundManager()=0; virtual MtEventManager* getEventManager()=0; - virtual scene::IAnimatedMesh* getMesh(const std::string &filename) - { return NULL; } - virtual scene::ISceneManager* getSceneManager()=0; - - virtual Camera* getCamera() - { return NULL; } - virtual void setCamera(Camera *camera) {} // Only usable on the server, and NOT thread-safe. It is usable from the // environment thread. - virtual IRollbackManager* getRollbackManager(){return NULL;} - - // Only usable on the server. Thread safe if not written while running threads. - virtual EmergeManager *getEmergeManager() { return NULL; } - - // Used on the client - virtual bool checkLocalPrivilege(const std::string &priv) - { return false; } + virtual IRollbackManager* getRollbackManager() { return NULL; } // Shorthands IItemDefManager *idef() { return getItemDefManager(); } INodeDefManager *ndef() { return getNodeDefManager(); } ICraftDefManager *cdef() { return getCraftDefManager(); } - ITextureSource *tsrc() { return getTextureSource(); } - ISoundManager *sound() { return getSoundManager(); } - IShaderSource *shsrc() { return getShaderSource(); } + MtEventManager *event() { return getEventManager(); } IRollbackManager *rollback() { return getRollbackManager();} - EmergeManager *emerge() { return getEmergeManager(); } }; #endif diff --git a/src/guiEngine.cpp b/src/guiEngine.cpp index a3c35f68d..6d66ed08d 100644 --- a/src/guiEngine.cpp +++ b/src/guiEngine.cpp @@ -194,11 +194,9 @@ GUIEngine::GUIEngine( irr::IrrlichtDevice* dev, -1, m_menumanager, NULL /* &client */, - NULL /* gamedef */, m_texture_source, m_formspecgui, m_buttonhandler, - NULL, false); m_menu->allowClose(false); diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp index bfc7a9b79..45b0e9c11 100644 --- a/src/guiFormSpecMenu.cpp +++ b/src/guiFormSpecMenu.cpp @@ -81,13 +81,12 @@ static unsigned int font_line_height(gui::IGUIFont *font) GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev, JoystickController *joystick, gui::IGUIElement* parent, s32 id, IMenuManager *menumgr, - InventoryManager *invmgr, IGameDef *gamedef, + Client *client, ISimpleTextureSource *tsrc, IFormSource* fsrc, TextDest* tdst, - Client* client, bool remap_dbl_click) : + bool remap_dbl_click) : GUIModalMenu(dev->getGUIEnvironment(), parent, id, menumgr), m_device(dev), - m_invmgr(invmgr), - m_gamedef(gamedef), + m_invmgr(client), m_tsrc(tsrc), m_client(client), m_selected_item(NULL), @@ -307,8 +306,8 @@ void GUIFormSpecMenu::parseContainerEnd(parserData* data) void GUIFormSpecMenu::parseList(parserData* data,std::string element) { - if (m_gamedef == 0) { - warningstream<<"invalid use of 'list' with m_gamedef==0"<explicit_size) warningstream<<"invalid use of item_image_button without a size[] element"<idef(); + IItemDefManager *idef = m_client->idef(); ItemStack item; item.deSerialize(item_name, idef); @@ -2297,14 +2296,14 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase, if(!item.empty()) { drawItemStack(driver, m_font, item, - rect, &AbsoluteClippingRect, m_gamedef, + rect, &AbsoluteClippingRect, m_client, rotation_kind); } // Draw tooltip std::wstring tooltip_text = L""; if (hovering && !m_selected_item) { - tooltip_text = utf8_to_wide(item.getDefinition(m_gamedef->idef()).description); + tooltip_text = utf8_to_wide(item.getDefinition(m_client->idef()).description); } if (tooltip_text != L"") { std::vector tt_rows = str_split(tooltip_text, L'\n'); @@ -2349,7 +2348,7 @@ void GUIFormSpecMenu::drawSelectedItem() if (!m_selected_item) { drawItemStack(driver, m_font, ItemStack(), core::rect(v2s32(0, 0), v2s32(0, 0)), - NULL, m_gamedef, IT_ROT_DRAGGED); + NULL, m_client, IT_ROT_DRAGGED); return; } @@ -2363,7 +2362,7 @@ void GUIFormSpecMenu::drawSelectedItem() core::rect imgrect(0,0,imgsize.X,imgsize.Y); core::rect rect = imgrect + (m_pointer - imgrect.getCenter()); rect.constrainTo(driver->getViewPort()); - drawItemStack(driver, m_font, stack, rect, NULL, m_gamedef, IT_ROT_DRAGGED); + drawItemStack(driver, m_font, stack, rect, NULL, m_client, IT_ROT_DRAGGED); } void GUIFormSpecMenu::drawMenu() @@ -2488,11 +2487,11 @@ void GUIFormSpecMenu::drawMenu() */ for(u32 i=0; iidef(); + IItemDefManager *idef = m_client->idef(); ItemStack item; item.deSerialize(spec.item_name, idef); core::rect imgrect(0, 0, spec.geom.X, spec.geom.Y); @@ -2509,7 +2508,7 @@ void GUIFormSpecMenu::drawMenu() #endif } drawItemStack(driver, m_font, item, rect, &AbsoluteClippingRect, - m_gamedef, IT_ROT_NONE); + m_client, IT_ROT_NONE); } /* @@ -2527,7 +2526,7 @@ void GUIFormSpecMenu::drawMenu() if (!item_hovered) { drawItemStack(driver, m_font, ItemStack(), core::rect(v2s32(0, 0), v2s32(0, 0)), - NULL, m_gamedef, IT_ROT_HOVERED); + NULL, m_client, IT_ROT_HOVERED); } /* TODO find way to show tooltips on touchscreen */ @@ -3470,7 +3469,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) // Check how many items can be moved move_amount = stack_from.count = MYMIN(move_amount, stack_from.count); - ItemStack leftover = stack_to.addItem(stack_from, m_gamedef->idef()); + ItemStack leftover = stack_to.addItem(stack_from, m_client->idef()); // If source stack cannot be added to destination stack at all, // they are swapped if ((leftover.count == stack_from.count) && diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h index 95df11e6a..94b52e6f0 100644 --- a/src/guiFormSpecMenu.h +++ b/src/guiFormSpecMenu.h @@ -34,7 +34,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/string.h" #include "util/enriched_string.h" -class IGameDef; class InventoryManager; class ISimpleTextureSource; class Client; @@ -289,12 +288,10 @@ public: JoystickController *joystick, gui::IGUIElement* parent, s32 id, IMenuManager *menumgr, - InventoryManager *invmgr, - IGameDef *gamedef, + Client *client, ISimpleTextureSource *tsrc, IFormSource* fs_src, TextDest* txt_dst, - Client* client, bool remap_dbl_click = true); ~GUIFormSpecMenu(); @@ -384,7 +381,6 @@ protected: irr::IrrlichtDevice* m_device; InventoryManager *m_invmgr; - IGameDef *m_gamedef; ISimpleTextureSource *m_tsrc; Client *m_client; diff --git a/src/hud.cpp b/src/hud.cpp index 43d957380..a602125e3 100644 --- a/src/hud.cpp +++ b/src/hud.cpp @@ -22,10 +22,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "hud.h" #include "settings.h" #include "util/numeric.h" -#include "util/string.h" #include "log.h" -#include "gamedef.h" -#include "itemdef.h" +#include "client.h" #include "inventory.h" #include "client/tile.h" #include "localplayer.h" @@ -41,13 +39,13 @@ with this program; if not, write to the Free Software Foundation, Inc., #endif Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr, - gui::IGUIEnvironment* guienv, IGameDef *gamedef, LocalPlayer *player, + gui::IGUIEnvironment* guienv, Client *client, LocalPlayer *player, Inventory *inventory) { this->driver = driver; this->smgr = smgr; this->guienv = guienv; - this->gamedef = gamedef; + this->client = client; this->player = player; this->inventory = inventory; @@ -61,7 +59,7 @@ Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr, for (unsigned int i = 0; i < 4; i++) hbar_colors[i] = video::SColor(255, 255, 255, 255); - tsrc = gamedef->getTextureSource(); + tsrc = client->getTextureSource(); v3f crosshair_color = g_settings->getV3F("crosshair_color"); u32 cross_r = rangelim(myround(crosshair_color.X), 0, 255); @@ -92,7 +90,7 @@ Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr, m_selection_material.Lighting = false; if (g_settings->getBool("enable_shaders")) { - IShaderSource *shdrsrc = gamedef->getShaderSource(); + IShaderSource *shdrsrc = client->getShaderSource(); u16 shader_id = shdrsrc->getShader( mode == "halo" ? "selection_shader" : "default_shader", 1, 1); m_selection_material.MaterialType = shdrsrc->getShaderInfo(shader_id).material; @@ -193,7 +191,7 @@ void Hud::drawItem(const ItemStack &item, const core::rect& rect, if (!use_hotbar_image) driver->draw2DRectangle(bgcolor2, rect, NULL); drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL, - gamedef, selected ? IT_ROT_SELECTED : IT_ROT_NONE); + client, selected ? IT_ROT_SELECTED : IT_ROT_NONE); } //NOTE: selectitem = 0 -> no selected; selectitem 1-based @@ -629,7 +627,7 @@ void drawItemStack(video::IVideoDriver *driver, const ItemStack &item, const core::rect &rect, const core::rect *clip, - IGameDef *gamedef, + Client *client, ItemRotationKind rotation_kind) { static MeshTimeInfo rotation_time_infos[IT_ROT_NONE]; @@ -643,8 +641,8 @@ void drawItemStack(video::IVideoDriver *driver, return; } - const ItemDefinition &def = item.getDefinition(gamedef->idef()); - scene::IMesh* mesh = gamedef->idef()->getWieldMesh(def.name, gamedef); + const ItemDefinition &def = item.getDefinition(client->idef()); + scene::IMesh* mesh = client->idef()->getWieldMesh(def.name, client); if (mesh) { driver->clearZBuffer(); diff --git a/src/hud.h b/src/hud.h index a4d7990e9..efa0c3648 100644 --- a/src/hud.h +++ b/src/hud.h @@ -95,7 +95,7 @@ struct HudElement { #include #include "irr_aabb3d.h" -class IGameDef; +class Client; class ITextureSource; class Inventory; class InventoryList; @@ -107,7 +107,7 @@ public: video::IVideoDriver *driver; scene::ISceneManager* smgr; gui::IGUIEnvironment *guienv; - IGameDef *gamedef; + Client *client; LocalPlayer *player; Inventory *inventory; ITextureSource *tsrc; @@ -121,7 +121,7 @@ public: bool use_hotbar_selected_image; Hud(video::IVideoDriver *driver,scene::ISceneManager* smgr, - gui::IGUIEnvironment* guienv, IGameDef *gamedef, LocalPlayer *player, + gui::IGUIEnvironment* guienv, Client *client, LocalPlayer *player, Inventory *inventory); ~Hud(); @@ -190,7 +190,7 @@ void drawItemStack(video::IVideoDriver *driver, const ItemStack &item, const core::rect &rect, const core::rect *clip, - IGameDef *gamedef, + Client *client, ItemRotationKind rotation_kind); #endif diff --git a/src/itemdef.cpp b/src/itemdef.cpp index 1aa6331dc..5ba9d8f9a 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -20,7 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "itemdef.h" -#include "gamedef.h" #include "nodedef.h" #include "tool.h" #include "inventory.h" @@ -29,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mesh.h" #include "wieldmesh.h" #include "client/tile.h" +#include "client.h" #endif #include "log.h" #include "settings.h" @@ -317,7 +317,7 @@ public: #ifndef SERVER public: ClientCached* createClientCachedDirect(const std::string &name, - IGameDef *gamedef) const + Client *client) const { infostream<<"Lazily creating item texture and mesh for \"" <getTextureSource(); + ITextureSource *tsrc = client->getTextureSource(); const ItemDefinition &def = get(name); // Create new ClientCached @@ -345,7 +345,7 @@ public: ItemStack item = ItemStack(); item.name = def.name; - scene::IMesh *mesh = getItemMesh(gamedef, item); + scene::IMesh *mesh = getItemMesh(client, item); cc->wield_mesh = mesh; // Put in cache @@ -354,7 +354,7 @@ public: return cc; } ClientCached* getClientCached(const std::string &name, - IGameDef *gamedef) const + Client *client) const { ClientCached *cc = NULL; m_clientcached.get(name, &cc); @@ -363,7 +363,7 @@ public: if(thr_is_current_thread(m_main_thread)) { - return createClientCachedDirect(name, gamedef); + return createClientCachedDirect(name, client); } else { @@ -392,18 +392,18 @@ public: } // Get item inventory texture virtual video::ITexture* getInventoryTexture(const std::string &name, - IGameDef *gamedef) const + Client *client) const { - ClientCached *cc = getClientCached(name, gamedef); + ClientCached *cc = getClientCached(name, client); if(!cc) return NULL; return cc->inventory_texture; } // Get item wield mesh virtual scene::IMesh* getWieldMesh(const std::string &name, - IGameDef *gamedef) const + Client *client) const { - ClientCached *cc = getClientCached(name, gamedef); + ClientCached *cc = getClientCached(name, client); if(!cc) return NULL; return cc->wield_mesh; @@ -543,7 +543,7 @@ public: request = m_get_clientcached_queue.pop(); m_get_clientcached_queue.pushResult(request, - createClientCachedDirect(request.key, gamedef)); + createClientCachedDirect(request.key, (Client *)gamedef)); } #endif } diff --git a/src/itemdef.h b/src/itemdef.h index dcb98e8a9..2ade6116a 100644 --- a/src/itemdef.h +++ b/src/itemdef.h @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "itemgroup.h" #include "sound.h" class IGameDef; +class Client; struct ToolCapabilities; /* @@ -107,10 +108,10 @@ public: #ifndef SERVER // Get item inventory texture virtual video::ITexture* getInventoryTexture(const std::string &name, - IGameDef *gamedef) const=0; + Client *client) const=0; // Get item wield mesh virtual scene::IMesh* getWieldMesh(const std::string &name, - IGameDef *gamedef) const=0; + Client *client) const=0; #endif virtual void serialize(std::ostream &os, u16 protocol_version)=0; @@ -133,10 +134,10 @@ public: #ifndef SERVER // Get item inventory texture virtual video::ITexture* getInventoryTexture(const std::string &name, - IGameDef *gamedef) const=0; + Client *client) const=0; // Get item wield mesh virtual scene::IMesh* getWieldMesh(const std::string &name, - IGameDef *gamedef) const=0; + Client *client) const=0; #endif // Remove all registered item and node definitions and aliases diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 4d0ca0600..b859c6455 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -21,7 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "event.h" #include "collision.h" -#include "gamedef.h" #include "nodedef.h" #include "settings.h" #include "environment.h" @@ -32,8 +31,8 @@ with this program; if not, write to the Free Software Foundation, Inc., LocalPlayer */ -LocalPlayer::LocalPlayer(Client *gamedef, const char *name): - Player(name, gamedef->idef()), +LocalPlayer::LocalPlayer(Client *client, const char *name): + Player(name, client->idef()), parent(0), hp(PLAYER_MAX_HP), got_teleported(false), @@ -79,7 +78,7 @@ LocalPlayer::LocalPlayer(Client *gamedef, const char *name): camera_barely_in_ceiling(false), m_collisionbox(-BS * 0.30, 0.0, -BS * 0.30, BS * 0.30, BS * 1.75, BS * 0.30), m_cao(NULL), - m_gamedef(gamedef) + m_client(client) { // Initialize hp to 0, so that no hearts will be shown if server // doesn't support health points @@ -96,7 +95,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d, std::vector *collision_info) { Map *map = &env->getMap(); - INodeDefManager *nodemgr = m_gamedef->ndef(); + INodeDefManager *nodemgr = m_client->ndef(); v3f position = getPosition(); @@ -109,8 +108,8 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d, } // Skip collision detection if noclip mode is used - bool fly_allowed = m_gamedef->checkLocalPrivilege("fly"); - bool noclip = m_gamedef->checkLocalPrivilege("noclip") && + bool fly_allowed = m_client->checkLocalPrivilege("fly"); + bool noclip = m_client->checkLocalPrivilege("noclip") && g_settings->getBool("noclip"); bool free_move = noclip && fly_allowed && g_settings->getBool("free_move"); if (free_move) { @@ -241,7 +240,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d, v3f accel_f = v3f(0,0,0); - collisionMoveResult result = collisionMoveSimple(env, m_gamedef, + collisionMoveResult result = collisionMoveSimple(env, m_client, pos_max_d, m_collisionbox, player_stepheight, dtime, &position, &m_speed, accel_f); @@ -376,7 +375,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d, if(!result.standing_on_object && !touching_ground_was && touching_ground) { MtEvent *e = new SimpleTriggerEvent("PlayerRegainGround"); - m_gamedef->event()->put(e); + m_client->event()->put(e); // Set camera impact value to be used for view bobbing camera_impact = getSpeed().Y * -1; @@ -448,8 +447,8 @@ void LocalPlayer::applyControl(float dtime) v3f speedH = v3f(0,0,0); // Horizontal (X, Z) v3f speedV = v3f(0,0,0); // Vertical (Y) - bool fly_allowed = m_gamedef->checkLocalPrivilege("fly"); - bool fast_allowed = m_gamedef->checkLocalPrivilege("fast"); + bool fly_allowed = m_client->checkLocalPrivilege("fly"); + bool fast_allowed = m_client->checkLocalPrivilege("fast"); bool free_move = fly_allowed && g_settings->getBool("free_move"); bool fast_move = fast_allowed && g_settings->getBool("fast_move"); @@ -599,7 +598,7 @@ void LocalPlayer::applyControl(float dtime) setSpeed(speedJ); MtEvent *e = new SimpleTriggerEvent("PlayerJump"); - m_gamedef->event()->put(e); + m_client->event()->put(e); } } else if(in_liquid) diff --git a/src/localplayer.h b/src/localplayer.h index 7a1cb7466..cbdcb9867 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -35,7 +35,7 @@ enum LocalPlayerAnimations {NO_ANIM, WALK_ANIM, DIG_ANIM, WD_ANIM}; // no local class LocalPlayer : public Player { public: - LocalPlayer(Client *gamedef, const char *name); + LocalPlayer(Client *client, const char *name); virtual ~LocalPlayer(); ClientActiveObject *parent; @@ -162,7 +162,7 @@ private: aabb3f m_collisionbox; GenericCAO* m_cao; - Client *m_gamedef; + Client *m_client; }; #endif diff --git a/src/mapblock_mesh.cpp b/src/mapblock_mesh.cpp index 977eabb6e..143adb410 100644 --- a/src/mapblock_mesh.cpp +++ b/src/mapblock_mesh.cpp @@ -23,7 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "map.h" #include "profiler.h" #include "nodedef.h" -#include "gamedef.h" #include "mesh.h" #include "minimap.h" #include "content_mapblock.h" @@ -43,14 +42,14 @@ static void applyFacesShading(video::SColor &color, const float factor) MeshMakeData */ -MeshMakeData::MeshMakeData(IGameDef *gamedef, bool use_shaders, +MeshMakeData::MeshMakeData(Client *client, bool use_shaders, bool use_tangent_vertices): m_vmanip(), m_blockpos(-1337,-1337,-1337), m_crack_pos_relative(-1337, -1337, -1337), m_smooth_lighting(false), m_show_hud(false), - m_gamedef(gamedef), + m_client(client), m_use_shaders(use_shaders), m_use_tangent_vertices(use_tangent_vertices) {} @@ -233,7 +232,7 @@ static u16 getSmoothLightCombined(v3s16 p, MeshMakeData *data) v3s16(1,1,1), }; - INodeDefManager *ndef = data->m_gamedef->ndef(); + INodeDefManager *ndef = data->m_client->ndef(); u16 ambient_occlusion = 0; u16 light_count = 0; @@ -664,7 +663,7 @@ static u8 face_contents(content_t m1, content_t m2, bool *equivalent, */ TileSpec getNodeTileN(MapNode mn, v3s16 p, u8 tileindex, MeshMakeData *data) { - INodeDefManager *ndef = data->m_gamedef->ndef(); + INodeDefManager *ndef = data->m_client->ndef(); TileSpec spec = ndef->get(mn).tiles[tileindex]; // Apply temporary crack if (p == data->m_crack_pos_relative) @@ -677,7 +676,7 @@ TileSpec getNodeTileN(MapNode mn, v3s16 p, u8 tileindex, MeshMakeData *data) */ TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 dir, MeshMakeData *data) { - INodeDefManager *ndef = data->m_gamedef->ndef(); + INodeDefManager *ndef = data->m_client->ndef(); // Direction must be (1,0,0), (-1,0,0), (0,1,0), (0,-1,0), // (0,0,1), (0,0,-1) or (0,0,0) @@ -734,7 +733,7 @@ TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 dir, MeshMakeData *data) u16 tile_index=facedir*16 + dir_i; TileSpec spec = getNodeTileN(mn, p, dir_to_tile[tile_index], data); spec.rotation=dir_to_tile[tile_index + 1]; - spec.texture = data->m_gamedef->tsrc()->getTexture(spec.texture_id); + spec.texture = data->m_client->tsrc()->getTexture(spec.texture_id); return spec; } @@ -753,7 +752,7 @@ static void getTileInfo( ) { VoxelManipulator &vmanip = data->m_vmanip; - INodeDefManager *ndef = data->m_gamedef->ndef(); + INodeDefManager *ndef = data->m_client->ndef(); v3s16 blockpos_nodes = data->m_blockpos * MAP_BLOCKSIZE; MapNode &n0 = vmanip.getNodeRefUnsafe(blockpos_nodes + p); @@ -1020,10 +1019,10 @@ static void updateAllFastFaceRows(MeshMakeData *data, MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): m_mesh(new scene::SMesh()), m_minimap_mapblock(NULL), - m_gamedef(data->m_gamedef), - m_driver(m_gamedef->tsrc()->getDevice()->getVideoDriver()), - m_tsrc(m_gamedef->getTextureSource()), - m_shdrsrc(m_gamedef->getShaderSource()), + m_client(data->m_client), + m_driver(m_client->tsrc()->getDevice()->getVideoDriver()), + m_tsrc(m_client->getTextureSource()), + m_shdrsrc(m_client->getShaderSource()), m_animation_force_timer(0), // force initial animation m_last_crack(-1), m_crack_materials(), @@ -1243,7 +1242,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): if (m_use_tangent_vertices) { scene::IMeshManipulator* meshmanip = - m_gamedef->getSceneManager()->getMeshManipulator(); + m_client->getSceneManager()->getMeshManipulator(); meshmanip->recalculateTangents(m_mesh, true, false, false); } diff --git a/src/mapblock_mesh.h b/src/mapblock_mesh.h index 8376468da..5adb7df3f 100644 --- a/src/mapblock_mesh.h +++ b/src/mapblock_mesh.h @@ -26,7 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/cpp11_container.h" #include -class IGameDef; +class Client; class IShaderSource; /* @@ -45,11 +45,11 @@ struct MeshMakeData bool m_smooth_lighting; bool m_show_hud; - IGameDef *m_gamedef; + Client *m_client; bool m_use_shaders; bool m_use_tangent_vertices; - MeshMakeData(IGameDef *gamedef, bool use_shaders, + MeshMakeData(Client *client, bool use_shaders, bool use_tangent_vertices = false); /* @@ -128,7 +128,7 @@ public: private: scene::IMesh *m_mesh; MinimapMapblock *m_minimap_mapblock; - IGameDef *m_gamedef; + Client *m_client; video::IVideoDriver *m_driver; ITextureSource *m_tsrc; IShaderSource *m_shdrsrc; diff --git a/src/mg_biome.cpp b/src/mg_biome.cpp index 78034bf6c..d564e9415 100644 --- a/src/mg_biome.cpp +++ b/src/mg_biome.cpp @@ -20,10 +20,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mg_biome.h" #include "mg_decoration.h" #include "emerge.h" -#include "gamedef.h" +#include "server.h" #include "nodedef.h" #include "map.h" //for MMVManip -#include "log.h" #include "util/numeric.h" #include "util/mathconstants.h" #include "porting.h" @@ -33,10 +32,10 @@ with this program; if not, write to the Free Software Foundation, Inc., /////////////////////////////////////////////////////////////////////////////// -BiomeManager::BiomeManager(IGameDef *gamedef) : - ObjDefManager(gamedef, OBJDEF_BIOME) +BiomeManager::BiomeManager(Server *server) : + ObjDefManager(server, OBJDEF_BIOME) { - m_gamedef = gamedef; + m_server = server; // Create default biome to be used in case none exist Biome *b = new Biome; @@ -73,7 +72,7 @@ BiomeManager::~BiomeManager() void BiomeManager::clear() { - EmergeManager *emerge = m_gamedef->getEmergeManager(); + EmergeManager *emerge = m_server->getEmergeManager(); // Remove all dangling references in Decorations DecorationManager *decomgr = emerge->decomgr; diff --git a/src/mg_biome.h b/src/mg_biome.h index a10193bc3..15088f7dd 100644 --- a/src/mg_biome.h +++ b/src/mg_biome.h @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "nodedef.h" #include "noise.h" +class Server; class Settings; class BiomeManager; @@ -186,7 +187,7 @@ private: class BiomeManager : public ObjDefManager { public: - BiomeManager(IGameDef *gamedef); + BiomeManager(Server *server); virtual ~BiomeManager(); const char *getObjectTitle() const @@ -223,7 +224,7 @@ public: virtual void clear(); private: - IGameDef *m_gamedef; + Server *m_server; }; diff --git a/src/mg_schematic.cpp b/src/mg_schematic.cpp index e028215dc..3d08d86fa 100644 --- a/src/mg_schematic.cpp +++ b/src/mg_schematic.cpp @@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include "mg_schematic.h" -#include "gamedef.h" +#include "server.h" #include "mapgen.h" #include "emerge.h" #include "map.h" @@ -34,16 +34,16 @@ with this program; if not, write to the Free Software Foundation, Inc., /////////////////////////////////////////////////////////////////////////////// -SchematicManager::SchematicManager(IGameDef *gamedef) : - ObjDefManager(gamedef, OBJDEF_SCHEMATIC) +SchematicManager::SchematicManager(Server *server) : + ObjDefManager(server, OBJDEF_SCHEMATIC) { - m_gamedef = gamedef; + m_server = server; } void SchematicManager::clear() { - EmergeManager *emerge = m_gamedef->getEmergeManager(); + EmergeManager *emerge = m_server->getEmergeManager(); // Remove all dangling references in Decorations DecorationManager *decomgr = emerge->decomgr; diff --git a/src/mg_schematic.h b/src/mg_schematic.h index da8859540..1d46e6ac4 100644 --- a/src/mg_schematic.h +++ b/src/mg_schematic.h @@ -29,7 +29,7 @@ class Mapgen; class MMVManip; class PseudoRandom; class NodeResolver; -class IGameDef; +class Server; /* Minetest Schematic File Format @@ -123,7 +123,7 @@ public: class SchematicManager : public ObjDefManager { public: - SchematicManager(IGameDef *gamedef); + SchematicManager(Server *server); virtual ~SchematicManager() {} virtual void clear(); @@ -139,7 +139,7 @@ public: } private: - IGameDef *m_gamedef; + Server *m_server; }; void generate_nodelist_and_update_ids(MapNode *nodes, size_t nodecount, diff --git a/src/nodedef.cpp b/src/nodedef.cpp index dbbdf95d2..b7d023897 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef SERVER #include "client/tile.h" #include "mesh.h" +#include "client.h" #include #endif #include "log.h" @@ -572,8 +573,7 @@ void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile, #ifndef SERVER void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc, - scene::ISceneManager *smgr, scene::IMeshManipulator *meshmanip, - IGameDef *gamedef, const TextureSettings &tsettings) + scene::IMeshManipulator *meshmanip, Client *client, const TextureSettings &tsettings) { // minimap pixel color - the average color of a texture if (tsettings.enable_minimap && tiledef[0].name != "") @@ -709,7 +709,7 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc if ((drawtype == NDT_MESH) && (mesh != "")) { // Meshnode drawtype // Read the mesh and apply scale - mesh_ptr[0] = gamedef->getMesh(mesh); + mesh_ptr[0] = client->getMesh(mesh); if (mesh_ptr[0]){ v3f scale = v3f(1.0, 1.0, 1.0) * BS * visual_scale; scaleMesh(mesh_ptr[0], scale); @@ -1316,9 +1316,11 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef, #ifndef SERVER infostream << "CNodeDefManager::updateTextures(): Updating " "textures in node definitions" << std::endl; - ITextureSource *tsrc = gamedef->tsrc(); - IShaderSource *shdsrc = gamedef->getShaderSource(); - scene::ISceneManager* smgr = gamedef->getSceneManager(); + + Client *client = (Client *)gamedef; + ITextureSource *tsrc = client->tsrc(); + IShaderSource *shdsrc = client->getShaderSource(); + scene::ISceneManager* smgr = client->getSceneManager(); scene::IMeshManipulator* meshmanip = smgr->getMeshManipulator(); TextureSettings tsettings; tsettings.readSettings(); @@ -1326,7 +1328,7 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef, u32 size = m_content_features.size(); for (u32 i = 0; i < size; i++) { - m_content_features[i].updateTextures(tsrc, shdsrc, smgr, meshmanip, gamedef, tsettings); + m_content_features[i].updateTextures(tsrc, shdsrc, meshmanip, client, tsettings); progress_callback(progress_callback_args, i, size); } #endif diff --git a/src/nodedef.h b/src/nodedef.h index 284c4a198..183b95d87 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef SERVER #include "client/tile.h" #include "shader.h" +class Client; #endif #include "itemgroup.h" #include "sound.h" // SimpleSoundSpec @@ -322,8 +323,7 @@ struct ContentFeatures u32 shader_id, bool use_normal_texture, bool backface_culling, u8 alpha, u8 material_type); void updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc, - scene::ISceneManager *smgr, scene::IMeshManipulator *meshmanip, - IGameDef *gamedef, const TextureSettings &tsettings); + scene::IMeshManipulator *meshmanip, Client *client, const TextureSettings &tsettings); #endif }; diff --git a/src/particles.cpp b/src/particles.cpp index 97f42e2c4..d9eb3cfa5 100644 --- a/src/particles.cpp +++ b/src/particles.cpp @@ -18,11 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "particles.h" -#include "constants.h" -#include "debug.h" -#include "settings.h" -#include "client/tile.h" -#include "gamedef.h" +#include "client.h" #include "collision.h" #include #include "util/numeric.h" @@ -452,7 +448,7 @@ void ParticleManager::clearAll () } } -void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, +void ParticleManager::handleParticleEvent(ClientEvent *event, Client *client, scene::ISceneManager* smgr, LocalPlayer *player) { switch (event->type) { @@ -477,9 +473,9 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, } video::ITexture *texture = - gamedef->tsrc()->getTextureForMesh(*(event->add_particlespawner.texture)); + client->tsrc()->getTextureForMesh(*(event->add_particlespawner.texture)); - ParticleSpawner* toadd = new ParticleSpawner(gamedef, smgr, player, + ParticleSpawner* toadd = new ParticleSpawner(client, smgr, player, event->add_particlespawner.amount, event->add_particlespawner.spawntime, *event->add_particlespawner.minpos, @@ -520,9 +516,9 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, } case CE_SPAWN_PARTICLE: { video::ITexture *texture = - gamedef->tsrc()->getTextureForMesh(*(event->spawn_particle.texture)); + client->tsrc()->getTextureForMesh(*(event->spawn_particle.texture)); - Particle* toadd = new Particle(gamedef, smgr, player, m_env, + Particle* toadd = new Particle(client, smgr, player, m_env, *event->spawn_particle.pos, *event->spawn_particle.vel, *event->spawn_particle.acc, diff --git a/src/particles.h b/src/particles.h index eb8c6665d..00cb2c08e 100644 --- a/src/particles.h +++ b/src/particles.h @@ -170,7 +170,7 @@ public: void step (float dtime); - void handleParticleEvent(ClientEvent *event,IGameDef *gamedef, + void handleParticleEvent(ClientEvent *event, Client *client, scene::ISceneManager* smgr, LocalPlayer *player); void addDiggingParticles(IGameDef* gamedef, scene::ISceneManager* smgr, diff --git a/src/pathfinder.cpp b/src/pathfinder.cpp index 84aa9252c..b240ec21f 100644 --- a/src/pathfinder.cpp +++ b/src/pathfinder.cpp @@ -24,12 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "pathfinder.h" #include "serverenvironment.h" -#include "gamedef.h" +#include "server.h" #include "nodedef.h" -#include "map.h" -#include "log.h" -#include "irr_aabb3d.h" -#include "util/basic_macros.h" //#define PATHFINDER_DEBUG //#define PATHFINDER_CALC_TIME diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp index 3cdd3cbfe..3d03c0c41 100644 --- a/src/script/lua_api/l_nodemeta.cpp +++ b/src/script/lua_api/l_nodemeta.cpp @@ -20,14 +20,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_nodemeta.h" #include "lua_api/l_internal.h" #include "lua_api/l_inventory.h" -#include "common/c_converter.h" #include "common/c_content.h" #include "serverenvironment.h" #include "map.h" -#include "gamedef.h" -#include "nodemetadata.h" - - +#include "server.h" /* NodeMetaRef diff --git a/src/server.cpp b/src/server.cpp index 60dbef0d2..7380d37c2 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -50,7 +50,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "content_abm.h" #include "content_sao.h" #include "mods.h" -#include "sound.h" // dummySoundManager #include "event_manager.h" #include "serverlist.h" #include "util/string.h" @@ -3310,29 +3309,12 @@ ICraftDefManager *Server::getCraftDefManager() { return m_craftdef; } -ITextureSource *Server::getTextureSource() -{ - return NULL; -} -IShaderSource *Server::getShaderSource() -{ - return NULL; -} -scene::ISceneManager *Server::getSceneManager() -{ - return NULL; -} u16 Server::allocateUnknownNodeId(const std::string &name) { return m_nodedef->allocateDummy(name); } -ISoundManager *Server::getSoundManager() -{ - return &dummySoundManager; -} - MtEventManager *Server::getEventManager() { return m_event; diff --git a/src/server.h b/src/server.h index fe7b50b77..a86f75f1d 100644 --- a/src/server.h +++ b/src/server.h @@ -283,13 +283,9 @@ public: virtual IItemDefManager* getItemDefManager(); virtual INodeDefManager* getNodeDefManager(); virtual ICraftDefManager* getCraftDefManager(); - virtual ITextureSource* getTextureSource(); - virtual IShaderSource* getShaderSource(); virtual u16 allocateUnknownNodeId(const std::string &name); - virtual ISoundManager* getSoundManager(); virtual MtEventManager* getEventManager(); - virtual scene::ISceneManager* getSceneManager(); - virtual IRollbackManager *getRollbackManager() { return m_rollback; } + IRollbackManager *getRollbackManager() { return m_rollback; } virtual EmergeManager *getEmergeManager() { return m_emerge; } IWritableItemDefManager* getWritableItemDefManager(); diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp index c9fa64ec5..e1962bcff 100644 --- a/src/serverenvironment.cpp +++ b/src/serverenvironment.cpp @@ -352,11 +352,11 @@ void ActiveBlockList::update(std::vector &active_positions, */ ServerEnvironment::ServerEnvironment(ServerMap *map, - GameScripting *scriptIface, IGameDef *gamedef, + GameScripting *scriptIface, Server *server, const std::string &path_world) : m_map(map), m_script(scriptIface), - m_gamedef(gamedef), + m_server(server), m_path_world(path_world), m_send_recommended_timer(0), m_active_block_interval_overload_skip(0), @@ -487,7 +487,7 @@ void ServerEnvironment::kickAllPlayers(AccessDeniedCode reason, for (std::vector::iterator it = m_players.begin(); it != m_players.end(); ++it) { RemotePlayer *player = dynamic_cast(*it); - ((Server*)m_gamedef)->DenyAccessVerCompliant(player->peer_id, + m_server->DenyAccessVerCompliant(player->peer_id, player->protocol_version, reason, str_reason, reconnect); } } @@ -501,7 +501,7 @@ void ServerEnvironment::saveLoadedPlayers() it != m_players.end(); ++it) { if ((*it)->checkModified()) { - (*it)->save(players_path, m_gamedef); + (*it)->save(players_path, m_server); } } } @@ -511,7 +511,7 @@ void ServerEnvironment::savePlayer(RemotePlayer *player) std::string players_path = m_path_world + DIR_DELIM "players"; fs::CreateDir(players_path); - player->save(players_path, m_gamedef); + player->save(players_path, m_server); } RemotePlayer *ServerEnvironment::loadPlayer(const std::string &playername, PlayerSAO *sao) @@ -523,7 +523,7 @@ RemotePlayer *ServerEnvironment::loadPlayer(const std::string &playername, Playe RemotePlayer *player = getPlayer(playername.c_str()); if (!player) { - player = new RemotePlayer("", m_gamedef->idef()); + player = new RemotePlayer("", m_server->idef()); newplayer = true; } @@ -632,7 +632,7 @@ void ServerEnvironment::loadMeta() } catch (SettingNotFoundException &e) { // No problem, this is expected. Just continue with an empty string } - m_lbm_mgr.loadIntroductionTimes(lbm_introduction_times, m_gamedef, m_game_time); + m_lbm_mgr.loadIntroductionTimes(lbm_introduction_times, m_server, m_game_time); m_day_count = args.exists("day_count") ? args.getU64("day_count") : 0; @@ -640,7 +640,7 @@ void ServerEnvironment::loadMeta() void ServerEnvironment::loadDefaultMeta() { - m_lbm_mgr.loadIntroductionTimes("", m_gamedef, m_game_time); + m_lbm_mgr.loadIntroductionTimes("", m_server, m_game_time); } struct ActiveABM @@ -902,7 +902,7 @@ void ServerEnvironment::addLoadingBlockModifierDef(LoadingBlockModifierDef *lbm) bool ServerEnvironment::setNode(v3s16 p, const MapNode &n) { - INodeDefManager *ndef = m_gamedef->ndef(); + INodeDefManager *ndef = m_server->ndef(); MapNode n_old = m_map->getNodeNoEx(p); // Call destructor @@ -929,7 +929,7 @@ bool ServerEnvironment::setNode(v3s16 p, const MapNode &n) bool ServerEnvironment::removeNode(v3s16 p) { - INodeDefManager *ndef = m_gamedef->ndef(); + INodeDefManager *ndef = m_server->ndef(); MapNode n_old = m_map->getNodeNoEx(p); // Call destructor diff --git a/src/serverenvironment.h b/src/serverenvironment.h index 20a783ea5..d71d29a9c 100644 --- a/src/serverenvironment.h +++ b/src/serverenvironment.h @@ -29,6 +29,8 @@ class PlayerSAO; class ServerEnvironment; class ActiveBlockModifier; class ServerActiveObject; +class Server; +class GameScripting; /* {Active, Loading} block modifier interface. @@ -190,7 +192,7 @@ class ServerEnvironment : public Environment { public: ServerEnvironment(ServerMap *map, GameScripting *scriptIface, - IGameDef *gamedef, const std::string &path_world); + Server *server, const std::string &path_world); ~ServerEnvironment(); Map & getMap(); @@ -201,8 +203,8 @@ public: GameScripting* getScriptIface() { return m_script; } - IGameDef *getGameDef() - { return m_gamedef; } + Server *getGameDef() + { return m_server; } float getSendRecommendedInterval() { return m_recommended_send_interval; } @@ -377,8 +379,8 @@ private: ServerMap *m_map; // Lua state GameScripting* m_script; - // Game definition - IGameDef *m_gamedef; + // Server definition + Server *m_server; // World path const std::string m_path_world; // Active object list diff --git a/src/wieldmesh.cpp b/src/wieldmesh.cpp index 9c4d5b642..c305238fe 100644 --- a/src/wieldmesh.cpp +++ b/src/wieldmesh.cpp @@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "settings.h" #include "wieldmesh.h" #include "inventory.h" -#include "gamedef.h" +#include "client.h" #include "itemdef.h" #include "nodedef.h" #include "mesh.h" @@ -283,7 +283,7 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename, video::SMaterial &material = m_meshnode->getMaterial(0); material.setTexture(0, tsrc->getTextureForMesh(imagename)); material.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; - material.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; + material.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; material.MaterialType = m_material_type; material.setFlag(video::EMF_BACK_FACE_CULLING, true); // Enable bi/trilinear filtering only for high resolution textures @@ -304,12 +304,12 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename, } } -void WieldMeshSceneNode::setItem(const ItemStack &item, IGameDef *gamedef) +void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client) { - ITextureSource *tsrc = gamedef->getTextureSource(); - IItemDefManager *idef = gamedef->getItemDefManager(); - IShaderSource *shdrsrc = gamedef->getShaderSource(); - INodeDefManager *ndef = gamedef->getNodeDefManager(); + ITextureSource *tsrc = client->getTextureSource(); + IItemDefManager *idef = client->getItemDefManager(); + IShaderSource *shdrsrc = client->getShaderSource(); + INodeDefManager *ndef = client->getNodeDefManager(); const ItemDefinition &def = item.getDefinition(idef); const ContentFeatures &f = ndef->get(def.name); content_t id = ndef->getId(def.name); @@ -341,7 +341,7 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, IGameDef *gamedef) } else if (f.drawtype == NDT_NORMAL || f.drawtype == NDT_ALLFACES) { setCube(f.tiles, def.wield_scale, tsrc); } else { - MeshMakeData mesh_make_data(gamedef, false); + MeshMakeData mesh_make_data(client, false); MapNode mesh_make_node(id, 255, 0); mesh_make_data.fillSingleNode(&mesh_make_node); MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); @@ -435,11 +435,11 @@ void WieldMeshSceneNode::changeToMesh(scene::IMesh *mesh) m_meshnode->setVisible(true); } -scene::IMesh *getItemMesh(IGameDef *gamedef, const ItemStack &item) +scene::IMesh *getItemMesh(Client *client, const ItemStack &item) { - ITextureSource *tsrc = gamedef->getTextureSource(); - IItemDefManager *idef = gamedef->getItemDefManager(); - INodeDefManager *ndef = gamedef->getNodeDefManager(); + ITextureSource *tsrc = client->getTextureSource(); + IItemDefManager *idef = client->getItemDefManager(); + INodeDefManager *ndef = client->getNodeDefManager(); const ItemDefinition &def = item.getDefinition(idef); const ContentFeatures &f = ndef->get(def.name); content_t id = ndef->getId(def.name); @@ -470,7 +470,7 @@ scene::IMesh *getItemMesh(IGameDef *gamedef, const ItemStack &item) mesh = cloneMesh(g_extrusion_mesh_cache->createCube()); scaleMesh(mesh, v3f(1.2, 1.2, 1.2)); } else { - MeshMakeData mesh_make_data(gamedef, false); + MeshMakeData mesh_make_data(client, false); MapNode mesh_make_node(id, 255, 0); mesh_make_data.fillSingleNode(&mesh_make_node); MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); diff --git a/src/wieldmesh.h b/src/wieldmesh.h index 0b3136bc1..0162c5e5a 100644 --- a/src/wieldmesh.h +++ b/src/wieldmesh.h @@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include struct ItemStack; -class IGameDef; +class Client; class ITextureSource; struct TileSpec; @@ -42,7 +42,7 @@ public: v3f wield_scale, ITextureSource *tsrc); void setExtruded(const std::string &imagename, v3f wield_scale, ITextureSource *tsrc, u8 num_frames); - void setItem(const ItemStack &item, IGameDef *gamedef); + void setItem(const ItemStack &item, Client *client); // Sets the vertex color of the wield mesh. // Must only be used if the constructor was called with lighting = false @@ -77,7 +77,7 @@ private: aabb3f m_bounding_box; }; -scene::IMesh *getItemMesh(IGameDef *gamedef, const ItemStack &item); +scene::IMesh *getItemMesh(Client *client, const ItemStack &item); scene::IMesh *getExtrudedMesh(ITextureSource *tsrc, const std::string &imagename); -- cgit v1.2.3 From 79d752ba4f6f0197627cc20f99b2540f63b6dc88 Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Mon, 2 Jan 2017 15:17:28 +0100 Subject: from_table: Fix crash for missing inventory or field --- doc/lua_api.txt | 3 ++- src/script/lua_api/l_nodemeta.cpp | 46 +++++++++++++++++++++++---------------- 2 files changed, 29 insertions(+), 20 deletions(-) (limited to 'src/script/lua_api/l_nodemeta.cpp') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index ff745c1c2..9a1cb6bac 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2781,8 +2781,9 @@ Can be gotten via `minetest.get_meta(pos)`. * `get_inventory()`: returns `InvRef` * `to_table()`: returns `nil` or `{fields = {...}, inventory = {list1 = {}, ...}}` * `from_table(nil or {})` - * to clear metadata, use from_table(nil) + * Any non-table value will clear the metadata * See "Node Metadata" + * returns `true` on success ### `NodeTimerRef` Node Timers: a high resolution persistent per-node timer. diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp index 3d03c0c41..631aa68ce 100644 --- a/src/script/lua_api/l_nodemeta.cpp +++ b/src/script/lua_api/l_nodemeta.cpp @@ -250,7 +250,7 @@ int NodeMetaRef::l_from_table(lua_State *L) // clear old metadata first ref->m_env->getMap().removeNodeMetadata(ref->m_p); - if(lua_isnil(L, base)){ + if (!lua_istable(L, base)) { // No metadata lua_pushboolean(L, true); return 1; @@ -258,34 +258,42 @@ int NodeMetaRef::l_from_table(lua_State *L) // Create new metadata NodeMetadata *meta = getmeta(ref, true); - if(meta == NULL){ + if (meta == NULL) { lua_pushboolean(L, false); return 1; } + // Set fields lua_getfield(L, base, "fields"); - int fieldstable = lua_gettop(L); - lua_pushnil(L); - while(lua_next(L, fieldstable) != 0){ - // key at index -2 and value at index -1 - std::string name = lua_tostring(L, -2); - size_t cl; - const char *cs = lua_tolstring(L, -1, &cl); - std::string value(cs, cl); - meta->setString(name, value); - lua_pop(L, 1); // removes value, keeps key for next iteration + if (lua_istable(L, -1)) { + int fieldstable = lua_gettop(L); + lua_pushnil(L); + while (lua_next(L, fieldstable) != 0) { + // key at index -2 and value at index -1 + std::string name = lua_tostring(L, -2); + size_t cl; + const char *cs = lua_tolstring(L, -1, &cl); + meta->setString(name, std::string(cs, cl)); + lua_pop(L, 1); // Remove value, keep key for next iteration + } + lua_pop(L, 1); } + // Set inventory Inventory *inv = meta->getInventory(); lua_getfield(L, base, "inventory"); - int inventorytable = lua_gettop(L); - lua_pushnil(L); - while(lua_next(L, inventorytable) != 0){ - // key at index -2 and value at index -1 - std::string name = lua_tostring(L, -2); - read_inventory_list(L, -1, inv, name.c_str(), getServer(L)); - lua_pop(L, 1); // removes value, keeps key for next iteration + if (lua_istable(L, -1)) { + int inventorytable = lua_gettop(L); + lua_pushnil(L); + while (lua_next(L, inventorytable) != 0) { + // key at index -2 and value at index -1 + std::string name = lua_tostring(L, -2); + read_inventory_list(L, -1, inv, name.c_str(), getServer(L)); + lua_pop(L, 1); // Remove value, keep key for next iteration + } + lua_pop(L, 1); } + reportMetadataChange(ref); lua_pushboolean(L, true); return 1; -- cgit v1.2.3 From 13f94ecad5d4fcda08663ee91e45b4a205a1dadb Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Tue, 31 Jan 2017 16:18:45 +0000 Subject: Make NodeMetaRef::getmeta a non-static member --- src/script/lua_api/l_nodemeta.cpp | 28 ++++++++++++++-------------- src/script/lua_api/l_nodemeta.h | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'src/script/lua_api/l_nodemeta.cpp') diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp index 631aa68ce..8391de03c 100644 --- a/src/script/lua_api/l_nodemeta.cpp +++ b/src/script/lua_api/l_nodemeta.cpp @@ -36,12 +36,12 @@ NodeMetaRef* NodeMetaRef::checkobject(lua_State *L, int narg) return *(NodeMetaRef**)ud; // unbox pointer } -NodeMetadata* NodeMetaRef::getmeta(NodeMetaRef *ref, bool auto_create) +NodeMetadata* NodeMetaRef::getmeta(bool auto_create) { - NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p); - if(meta == NULL && auto_create) { - meta = new NodeMetadata(ref->m_env->getGameDef()->idef()); - if(!ref->m_env->getMap().setNodeMetadata(ref->m_p, meta)) { + NodeMetadata *meta = m_env->getMap().getNodeMetadata(m_p); + if (meta == NULL && auto_create) { + meta = new NodeMetadata(m_env->getGameDef()->idef()); + if (!m_env->getMap().setNodeMetadata(m_p, meta)) { delete meta; return NULL; } @@ -83,7 +83,7 @@ int NodeMetaRef::l_get_string(lua_State *L) NodeMetaRef *ref = checkobject(L, 1); std::string name = luaL_checkstring(L, 2); - NodeMetadata *meta = getmeta(ref, false); + NodeMetadata *meta = ref->getmeta(false); if(meta == NULL){ lua_pushlstring(L, "", 0); return 1; @@ -104,7 +104,7 @@ int NodeMetaRef::l_set_string(lua_State *L) const char *s = lua_tolstring(L, 3, &len); std::string str(s, len); - NodeMetadata *meta = getmeta(ref, !str.empty()); + NodeMetadata *meta = ref->getmeta(!str.empty()); if(meta == NULL || str == meta->getString(name)) return 0; meta->setString(name, str); @@ -120,7 +120,7 @@ int NodeMetaRef::l_get_int(lua_State *L) NodeMetaRef *ref = checkobject(L, 1); std::string name = lua_tostring(L, 2); - NodeMetadata *meta = getmeta(ref, false); + NodeMetadata *meta = ref->getmeta(false); if(meta == NULL){ lua_pushnumber(L, 0); return 1; @@ -140,7 +140,7 @@ int NodeMetaRef::l_set_int(lua_State *L) int a = lua_tointeger(L, 3); std::string str = itos(a); - NodeMetadata *meta = getmeta(ref, true); + NodeMetadata *meta = ref->getmeta(true); if(meta == NULL || str == meta->getString(name)) return 0; meta->setString(name, str); @@ -156,7 +156,7 @@ int NodeMetaRef::l_get_float(lua_State *L) NodeMetaRef *ref = checkobject(L, 1); std::string name = lua_tostring(L, 2); - NodeMetadata *meta = getmeta(ref, false); + NodeMetadata *meta = ref->getmeta(false); if(meta == NULL){ lua_pushnumber(L, 0); return 1; @@ -176,7 +176,7 @@ int NodeMetaRef::l_set_float(lua_State *L) float a = lua_tonumber(L, 3); std::string str = ftos(a); - NodeMetadata *meta = getmeta(ref, true); + NodeMetadata *meta = ref->getmeta(true); if(meta == NULL || str == meta->getString(name)) return 0; meta->setString(name, str); @@ -190,7 +190,7 @@ int NodeMetaRef::l_get_inventory(lua_State *L) MAP_LOCK_REQUIRED; NodeMetaRef *ref = checkobject(L, 1); - getmeta(ref, true); // try to ensure the metadata exists + ref->getmeta(true); // try to ensure the metadata exists InvRef::createNodeMeta(L, ref->m_p); return 1; } @@ -202,7 +202,7 @@ int NodeMetaRef::l_to_table(lua_State *L) NodeMetaRef *ref = checkobject(L, 1); - NodeMetadata *meta = getmeta(ref, true); + NodeMetadata *meta = ref->getmeta(true); if (meta == NULL) { lua_pushnil(L); return 1; @@ -257,7 +257,7 @@ int NodeMetaRef::l_from_table(lua_State *L) } // Create new metadata - NodeMetadata *meta = getmeta(ref, true); + NodeMetadata *meta = ref->getmeta(true); if (meta == NULL) { lua_pushboolean(L, false); return 1; diff --git a/src/script/lua_api/l_nodemeta.h b/src/script/lua_api/l_nodemeta.h index e39ac3931..4ce338b18 100644 --- a/src/script/lua_api/l_nodemeta.h +++ b/src/script/lua_api/l_nodemeta.h @@ -52,7 +52,7 @@ private: * @param auto_create when true, try to create metadata information for the node if it has none. * @return pointer to a @c NodeMetadata object or @c NULL in case of error. */ - static NodeMetadata* getmeta(NodeMetaRef *ref, bool auto_create); + virtual NodeMetadata* getmeta(bool auto_create); static void reportMetadataChange(NodeMetaRef *ref); -- cgit v1.2.3 From c2e7b1f57941cb34cb7e3d71dc040fad53a64e3e Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Tue, 31 Jan 2017 16:43:45 +0000 Subject: Derive NodeMetaRef from MetaDataRef --- .gitignore | 2 +- build/android/jni/Android.mk | 1 + src/metadata.cpp | 48 ++++++-- src/metadata.h | 4 +- src/script/lua_api/CMakeLists.txt | 2 +- src/script/lua_api/l_metadata.cpp | 252 ++++++++++++++++++++++++++++++++++++++ src/script/lua_api/l_metadata.h | 71 +++++++++++ src/script/lua_api/l_nodemeta.cpp | 224 +++++---------------------------- src/script/lua_api/l_nodemeta.h | 35 ++---- 9 files changed, 407 insertions(+), 232 deletions(-) create mode 100644 src/script/lua_api/l_metadata.cpp create mode 100644 src/script/lua_api/l_metadata.h (limited to 'src/script/lua_api/l_nodemeta.cpp') diff --git a/.gitignore b/.gitignore index d7e0daab4..c2600afeb 100644 --- a/.gitignore +++ b/.gitignore @@ -74,6 +74,7 @@ locale/ *.a *.ninja .ninja* +*.gch ## Android build files build/android/src/main/assets @@ -86,4 +87,3 @@ build/android/obj build/android/local.properties build/android/.gradle timestamp - diff --git a/build/android/jni/Android.mk b/build/android/jni/Android.mk index 8f333c3d4..70a3d29c0 100644 --- a/build/android/jni/Android.mk +++ b/build/android/jni/Android.mk @@ -307,6 +307,7 @@ LOCAL_SRC_FILES += \ jni/src/script/lua_api/l_item.cpp \ jni/src/script/lua_api/l_mainmenu.cpp \ jni/src/script/lua_api/l_mapgen.cpp \ + jni/src/script/lua_api/l_metadata.cpp \ jni/src/script/lua_api/l_nodemeta.cpp \ jni/src/script/lua_api/l_nodetimer.cpp \ jni/src/script/lua_api/l_noise.cpp \ diff --git a/src/metadata.cpp b/src/metadata.cpp index 8e04aa2d3..96453d710 100644 --- a/src/metadata.cpp +++ b/src/metadata.cpp @@ -37,12 +37,39 @@ bool Metadata::empty() const return m_stringvars.size() == 0; } -std::string Metadata::getString(const std::string &name, - u16 recursion) const +size_t Metadata::size() const +{ + return m_stringvars.size(); +} + +bool Metadata::contains(const std::string &name) const +{ + return m_stringvars.find(name) != m_stringvars.end(); +} + +bool Metadata::operator==(const Metadata &other) const +{ + if (size() != other.size()) + return false; + + for (StringMap::const_iterator it = m_stringvars.begin(); + it != m_stringvars.end(); ++it) { + if (!other.contains(it->first) || + other.getString(it->first) != it->second) + return false; + } + + return true; +} + +const std::string &Metadata::getString(const std::string &name, + u16 recursion) const { StringMap::const_iterator it = m_stringvars.find(name); - if (it == m_stringvars.end()) - return ""; + if (it == m_stringvars.end()) { + static const std::string empty_string = std::string(""); + return empty_string; + } return resolveString(it->second, recursion); } @@ -56,14 +83,13 @@ void Metadata::setString(const std::string &name, const std::string &var) } } -std::string Metadata::resolveString(const std::string &str, - u16 recursion) const +const std::string &Metadata::resolveString(const std::string &str, + u16 recursion) const { - if (recursion > 1) { - return str; - } - if (str.substr(0, 2) == "${" && str[str.length() - 1] == '}') { + if (recursion <= 1 && + str.substr(0, 2) == "${" && str[str.length() - 1] == '}') { return getString(str.substr(2, str.length() - 3), recursion + 1); + } else { + return str; } - return str; } diff --git a/src/metadata.h b/src/metadata.h index a96bfc408..a629c0615 100644 --- a/src/metadata.h +++ b/src/metadata.h @@ -44,10 +44,10 @@ public: bool empty() const; // Generic key/value store - std::string getString(const std::string &name, u16 recursion = 0) const; + const std::string &getString(const std::string &name, u16 recursion = 0) const; void setString(const std::string &name, const std::string &var); // Support variable names in values - std::string resolveString(const std::string &str, u16 recursion = 0) const; + const std::string &resolveString(const std::string &str, u16 recursion = 0) const; const StringMap &getStrings() const { return m_stringvars; diff --git a/src/script/lua_api/CMakeLists.txt b/src/script/lua_api/CMakeLists.txt index d507dcf70..efccce515 100644 --- a/src/script/lua_api/CMakeLists.txt +++ b/src/script/lua_api/CMakeLists.txt @@ -6,6 +6,7 @@ set(common_SCRIPT_LUA_API_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/l_inventory.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_item.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_mapgen.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_metadata.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_nodemeta.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_nodetimer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_noise.cpp @@ -22,4 +23,3 @@ set(common_SCRIPT_LUA_API_SRCS set(client_SCRIPT_LUA_API_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/l_mainmenu.cpp PARENT_SCOPE) - diff --git a/src/script/lua_api/l_metadata.cpp b/src/script/lua_api/l_metadata.cpp new file mode 100644 index 000000000..b54005bac --- /dev/null +++ b/src/script/lua_api/l_metadata.cpp @@ -0,0 +1,252 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_metadata.h" +#include "lua_api/l_internal.h" +#include "common/c_content.h" +#include "serverenvironment.h" +#include "map.h" +#include "server.h" + +// LUALIB_API +void *luaL_checkudata_is_metadataref(lua_State *L, int ud) { + void *p = lua_touserdata(L, ud); + if (p != NULL && // value is a userdata? + lua_getmetatable(L, ud)) { // does it have a metatable? + lua_getfield(L, -1, "metadata_class"); + if (lua_type(L, -1) == LUA_TSTRING) { // does it have a metadata_class field? + return p; + } + } + luaL_typerror(L, ud, "MetaDataRef"); + return NULL; +} + +MetaDataRef* MetaDataRef::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata_is_metadataref(L, narg); + if (!ud) + luaL_typerror(L, narg, "MetaDataRef"); + + return *(MetaDataRef**)ud; // unbox pointer +} + +// Exported functions + +// get_string(self, name) +int MetaDataRef::l_get_string(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = luaL_checkstring(L, 2); + + Metadata *meta = ref->getmeta(false); + if (meta == NULL) { + lua_pushlstring(L, "", 0); + return 1; + } + + const std::string &str = meta->getString(name); + lua_pushlstring(L, str.c_str(), str.size()); + return 1; +} + +// set_string(self, name, var) +int MetaDataRef::l_set_string(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = luaL_checkstring(L, 2); + size_t len = 0; + const char *s = lua_tolstring(L, 3, &len); + std::string str(s, len); + + Metadata *meta = ref->getmeta(!str.empty()); + if (meta == NULL || str == meta->getString(name)) + return 0; + + meta->setString(name, str); + ref->reportMetadataChange(); + return 0; +} + +// get_int(self, name) +int MetaDataRef::l_get_int(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = lua_tostring(L, 2); + + Metadata *meta = ref->getmeta(false); + if (meta == NULL) { + lua_pushnumber(L, 0); + return 1; + } + + const std::string &str = meta->getString(name); + lua_pushnumber(L, stoi(str)); + return 1; +} + +// set_int(self, name, var) +int MetaDataRef::l_set_int(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = lua_tostring(L, 2); + int a = lua_tointeger(L, 3); + std::string str = itos(a); + + Metadata *meta = ref->getmeta(true); + if (meta == NULL || str == meta->getString(name)) + return 0; + + meta->setString(name, str); + ref->reportMetadataChange(); + return 0; +} + +// get_float(self, name) +int MetaDataRef::l_get_float(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = lua_tostring(L, 2); + + Metadata *meta = ref->getmeta(false); + if (meta == NULL) { + lua_pushnumber(L, 0); + return 1; + } + + const std::string &str = meta->getString(name); + lua_pushnumber(L, stof(str)); + return 1; +} + +// set_float(self, name, var) +int MetaDataRef::l_set_float(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = lua_tostring(L, 2); + float a = lua_tonumber(L, 3); + std::string str = ftos(a); + + Metadata *meta = ref->getmeta(true); + if (meta == NULL || str == meta->getString(name)) + return 0; + + meta->setString(name, str); + ref->reportMetadataChange(); + return 0; +} + +// to_table(self) +int MetaDataRef::l_to_table(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + + Metadata *meta = ref->getmeta(true); + if (meta == NULL) { + lua_pushnil(L); + return 1; + } + lua_newtable(L); + + ref->handleToTable(L, meta); + + return 1; +} + +// from_table(self, table) +int MetaDataRef::l_from_table(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + int base = 2; + + ref->clearMeta(); + + if (!lua_istable(L, base)) { + // No metadata + lua_pushboolean(L, true); + return 1; + } + + // Create new metadata + Metadata *meta = ref->getmeta(true); + if (meta == NULL) { + lua_pushboolean(L, false); + return 1; + } + + bool was_successful = ref->handleFromTable(L, base, meta); + ref->reportMetadataChange(); + lua_pushboolean(L, was_successful); + return 1; +} + +void MetaDataRef::handleToTable(lua_State *L, Metadata *meta) +{ + lua_newtable(L); + { + const StringMap &fields = meta->getStrings(); + for (StringMap::const_iterator + it = fields.begin(); it != fields.end(); ++it) { + const std::string &name = it->first; + const std::string &value = it->second; + lua_pushlstring(L, name.c_str(), name.size()); + lua_pushlstring(L, value.c_str(), value.size()); + lua_settable(L, -3); + } + } + lua_setfield(L, -2, "fields"); +} + +bool MetaDataRef::handleFromTable(lua_State *L, int table, Metadata *meta) +{ + // Set fields + lua_getfield(L, table, "fields"); + if (lua_istable(L, -1)) { + int fieldstable = lua_gettop(L); + lua_pushnil(L); + while (lua_next(L, fieldstable) != 0) { + // key at index -2 and value at index -1 + std::string name = lua_tostring(L, -2); + size_t cl; + const char *cs = lua_tolstring(L, -1, &cl); + meta->setString(name, std::string(cs, cl)); + lua_pop(L, 1); // Remove value, keep key for next iteration + } + lua_pop(L, 1); + } + + return true; +} diff --git a/src/script/lua_api/l_metadata.h b/src/script/lua_api/l_metadata.h new file mode 100644 index 000000000..561be6adf --- /dev/null +++ b/src/script/lua_api/l_metadata.h @@ -0,0 +1,71 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#ifndef L_METADATA_H_ +#define L_METADATA_H_ + +#include "lua_api/l_base.h" +#include "irrlichttypes_bloated.h" + +class Metadata; + +/* + NodeMetaRef +*/ + +class MetaDataRef : public ModApiBase { +public: + virtual ~MetaDataRef() {} +protected: + static MetaDataRef *checkobject(lua_State *L, int narg); + + virtual void reportMetadataChange() {} + virtual Metadata* getmeta(bool auto_create) = 0; + virtual void clearMeta() = 0; + + virtual void handleToTable(lua_State *L, Metadata *meta); + virtual bool handleFromTable(lua_State *L, int table, Metadata *meta); + + // Exported functions + + // get_string(self, name) + static int l_get_string(lua_State *L); + + // set_string(self, name, var) + static int l_set_string(lua_State *L); + + // get_int(self, name) + static int l_get_int(lua_State *L); + + // set_int(self, name, var) + static int l_set_int(lua_State *L); + + // get_float(self, name) + static int l_get_float(lua_State *L); + + // set_float(self, name, var) + static int l_set_float(lua_State *L); + + // to_table(self) + static int l_to_table(lua_State *L); + + // from_table(self, table) + static int l_from_table(lua_State *L); +}; + +#endif /* L_NODEMETA_H_ */ diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp index 8391de03c..4b2b392da 100644 --- a/src/script/lua_api/l_nodemeta.cpp +++ b/src/script/lua_api/l_nodemeta.cpp @@ -36,7 +36,7 @@ NodeMetaRef* NodeMetaRef::checkobject(lua_State *L, int narg) return *(NodeMetaRef**)ud; // unbox pointer } -NodeMetadata* NodeMetaRef::getmeta(bool auto_create) +Metadata* NodeMetaRef::getmeta(bool auto_create) { NodeMetadata *meta = m_env->getMap().getNodeMetadata(m_p); if (meta == NULL && auto_create) { @@ -49,17 +49,22 @@ NodeMetadata* NodeMetaRef::getmeta(bool auto_create) return meta; } -void NodeMetaRef::reportMetadataChange(NodeMetaRef *ref) +void NodeMetaRef::clearMeta() +{ + m_env->getMap().removeNodeMetadata(m_p); +} + +void NodeMetaRef::reportMetadataChange() { // NOTE: This same code is in rollback_interface.cpp // Inform other things that the metadata has changed - v3s16 blockpos = getNodeBlockPos(ref->m_p); + v3s16 blockpos = getNodeBlockPos(m_p); MapEditEvent event; event.type = MEET_BLOCK_NODE_METADATA_CHANGED; event.p = blockpos; - ref->m_env->getMap().dispatchEvent(&event); + m_env->getMap().dispatchEvent(&event); // Set the block to be saved - MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos); + MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(blockpos); if (block) { block->raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_REPORT_META_CHANGE); @@ -75,115 +80,6 @@ int NodeMetaRef::gc_object(lua_State *L) { return 0; } -// get_string(self, name) -int NodeMetaRef::l_get_string(lua_State *L) -{ - MAP_LOCK_REQUIRED; - - NodeMetaRef *ref = checkobject(L, 1); - std::string name = luaL_checkstring(L, 2); - - NodeMetadata *meta = ref->getmeta(false); - if(meta == NULL){ - lua_pushlstring(L, "", 0); - return 1; - } - std::string str = meta->getString(name); - lua_pushlstring(L, str.c_str(), str.size()); - return 1; -} - -// set_string(self, name, var) -int NodeMetaRef::l_set_string(lua_State *L) -{ - MAP_LOCK_REQUIRED; - - NodeMetaRef *ref = checkobject(L, 1); - std::string name = luaL_checkstring(L, 2); - size_t len = 0; - const char *s = lua_tolstring(L, 3, &len); - std::string str(s, len); - - NodeMetadata *meta = ref->getmeta(!str.empty()); - if(meta == NULL || str == meta->getString(name)) - return 0; - meta->setString(name, str); - reportMetadataChange(ref); - return 0; -} - -// get_int(self, name) -int NodeMetaRef::l_get_int(lua_State *L) -{ - MAP_LOCK_REQUIRED; - - NodeMetaRef *ref = checkobject(L, 1); - std::string name = lua_tostring(L, 2); - - NodeMetadata *meta = ref->getmeta(false); - if(meta == NULL){ - lua_pushnumber(L, 0); - return 1; - } - std::string str = meta->getString(name); - lua_pushnumber(L, stoi(str)); - return 1; -} - -// set_int(self, name, var) -int NodeMetaRef::l_set_int(lua_State *L) -{ - MAP_LOCK_REQUIRED; - - NodeMetaRef *ref = checkobject(L, 1); - std::string name = lua_tostring(L, 2); - int a = lua_tointeger(L, 3); - std::string str = itos(a); - - NodeMetadata *meta = ref->getmeta(true); - if(meta == NULL || str == meta->getString(name)) - return 0; - meta->setString(name, str); - reportMetadataChange(ref); - return 0; -} - -// get_float(self, name) -int NodeMetaRef::l_get_float(lua_State *L) -{ - MAP_LOCK_REQUIRED; - - NodeMetaRef *ref = checkobject(L, 1); - std::string name = lua_tostring(L, 2); - - NodeMetadata *meta = ref->getmeta(false); - if(meta == NULL){ - lua_pushnumber(L, 0); - return 1; - } - std::string str = meta->getString(name); - lua_pushnumber(L, stof(str)); - return 1; -} - -// set_float(self, name, var) -int NodeMetaRef::l_set_float(lua_State *L) -{ - MAP_LOCK_REQUIRED; - - NodeMetaRef *ref = checkobject(L, 1); - std::string name = lua_tostring(L, 2); - float a = lua_tonumber(L, 3); - std::string str = ftos(a); - - NodeMetadata *meta = ref->getmeta(true); - if(meta == NULL || str == meta->getString(name)) - return 0; - meta->setString(name, str); - reportMetadataChange(ref); - return 0; -} - // get_inventory(self) int NodeMetaRef::l_get_inventory(lua_State *L) { @@ -195,34 +91,12 @@ int NodeMetaRef::l_get_inventory(lua_State *L) return 1; } -// to_table(self) -int NodeMetaRef::l_to_table(lua_State *L) +void NodeMetaRef::handleToTable(lua_State *L, Metadata *_meta) { - MAP_LOCK_REQUIRED; - - NodeMetaRef *ref = checkobject(L, 1); - - NodeMetadata *meta = ref->getmeta(true); - if (meta == NULL) { - lua_pushnil(L); - return 1; - } - lua_newtable(L); - // fields - lua_newtable(L); - { - StringMap fields = meta->getStrings(); - for (StringMap::const_iterator - it = fields.begin(); it != fields.end(); ++it) { - const std::string &name = it->first; - const std::string &value = it->second; - lua_pushlstring(L, name.c_str(), name.size()); - lua_pushlstring(L, value.c_str(), value.size()); - lua_settable(L, -3); - } - } - lua_setfield(L, -2, "fields"); + MetaDataRef::handleToTable(L, _meta); + + NodeMetadata *meta = (NodeMetadata*) _meta; // inventory lua_newtable(L); @@ -236,52 +110,20 @@ int NodeMetaRef::l_to_table(lua_State *L) } } lua_setfield(L, -2, "inventory"); - return 1; } // from_table(self, table) -int NodeMetaRef::l_from_table(lua_State *L) +bool NodeMetaRef::handleFromTable(lua_State *L, int table, Metadata *_meta) { - MAP_LOCK_REQUIRED; - - NodeMetaRef *ref = checkobject(L, 1); - int base = 2; - - // clear old metadata first - ref->m_env->getMap().removeNodeMetadata(ref->m_p); - - if (!lua_istable(L, base)) { - // No metadata - lua_pushboolean(L, true); - return 1; - } + // fields + if (!MetaDataRef::handleFromTable(L, table, _meta)) + return false; - // Create new metadata - NodeMetadata *meta = ref->getmeta(true); - if (meta == NULL) { - lua_pushboolean(L, false); - return 1; - } + NodeMetadata *meta = (NodeMetadata*) _meta; - // Set fields - lua_getfield(L, base, "fields"); - if (lua_istable(L, -1)) { - int fieldstable = lua_gettop(L); - lua_pushnil(L); - while (lua_next(L, fieldstable) != 0) { - // key at index -2 and value at index -1 - std::string name = lua_tostring(L, -2); - size_t cl; - const char *cs = lua_tolstring(L, -1, &cl); - meta->setString(name, std::string(cs, cl)); - lua_pop(L, 1); // Remove value, keep key for next iteration - } - lua_pop(L, 1); - } - - // Set inventory + // inventory Inventory *inv = meta->getInventory(); - lua_getfield(L, base, "inventory"); + lua_getfield(L, table, "inventory"); if (lua_istable(L, -1)) { int inventorytable = lua_gettop(L); lua_pushnil(L); @@ -294,9 +136,7 @@ int NodeMetaRef::l_from_table(lua_State *L) lua_pop(L, 1); } - reportMetadataChange(ref); - lua_pushboolean(L, true); - return 1; + return true; } @@ -332,6 +172,10 @@ void NodeMetaRef::Register(lua_State *L) lua_pushvalue(L, methodtable); lua_settable(L, metatable); // hide metatable from Lua getmetatable() + lua_pushliteral(L, "metadata_class"); + lua_pushlstring(L, className, strlen(className)); + lua_settable(L, metatable); + lua_pushliteral(L, "__index"); lua_pushvalue(L, methodtable); lua_settable(L, metatable); @@ -351,14 +195,14 @@ void NodeMetaRef::Register(lua_State *L) const char NodeMetaRef::className[] = "NodeMetaRef"; const luaL_reg NodeMetaRef::methods[] = { - luamethod(NodeMetaRef, get_string), - luamethod(NodeMetaRef, set_string), - luamethod(NodeMetaRef, get_int), - luamethod(NodeMetaRef, set_int), - luamethod(NodeMetaRef, get_float), - luamethod(NodeMetaRef, set_float), + luamethod(MetaDataRef, get_string), + luamethod(MetaDataRef, set_string), + luamethod(MetaDataRef, get_int), + luamethod(MetaDataRef, set_int), + luamethod(MetaDataRef, get_float), + luamethod(MetaDataRef, set_float), + luamethod(MetaDataRef, to_table), + luamethod(MetaDataRef, from_table), luamethod(NodeMetaRef, get_inventory), - luamethod(NodeMetaRef, to_table), - luamethod(NodeMetaRef, from_table), {0,0} }; diff --git a/src/script/lua_api/l_nodemeta.h b/src/script/lua_api/l_nodemeta.h index 4ce338b18..d03f086c9 100644 --- a/src/script/lua_api/l_nodemeta.h +++ b/src/script/lua_api/l_nodemeta.h @@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #define L_NODEMETA_H_ #include "lua_api/l_base.h" +#include "lua_api/l_metadata.h" #include "irrlichttypes_bloated.h" class ServerEnvironment; @@ -29,7 +30,7 @@ class NodeMetadata; NodeMetaRef */ -class NodeMetaRef : public ModApiBase { +class NodeMetaRef : public MetaDataRef { private: v3s16 m_p; ServerEnvironment *m_env; @@ -52,42 +53,22 @@ private: * @param auto_create when true, try to create metadata information for the node if it has none. * @return pointer to a @c NodeMetadata object or @c NULL in case of error. */ - virtual NodeMetadata* getmeta(bool auto_create); + virtual Metadata* getmeta(bool auto_create); + virtual void clearMeta(); - static void reportMetadataChange(NodeMetaRef *ref); + virtual void reportMetadataChange(); + + virtual void handleToTable(lua_State *L, Metadata *_meta); + virtual bool handleFromTable(lua_State *L, int table, Metadata *_meta); // Exported functions // garbage collector static int gc_object(lua_State *L); - // get_string(self, name) - static int l_get_string(lua_State *L); - - // set_string(self, name, var) - static int l_set_string(lua_State *L); - - // get_int(self, name) - static int l_get_int(lua_State *L); - - // set_int(self, name, var) - static int l_set_int(lua_State *L); - - // get_float(self, name) - static int l_get_float(lua_State *L); - - // set_float(self, name, var) - static int l_set_float(lua_State *L); - // get_inventory(self) static int l_get_inventory(lua_State *L); - // to_table(self) - static int l_to_table(lua_State *L); - - // from_table(self, table) - static int l_from_table(lua_State *L); - public: NodeMetaRef(v3s16 p, ServerEnvironment *env); -- cgit v1.2.3 From 000ec260017256016b62bb9936bbda1ff969e252 Mon Sep 17 00:00:00 2001 From: red-001 Date: Tue, 4 Apr 2017 06:41:37 +0100 Subject: [CSM] Add local node meta reference. (#5508) --- doc/client_lua_api.md | 15 ++++++++++- src/script/clientscripting.cpp | 2 ++ src/script/lua_api/l_client.cpp | 13 ++++++++++ src/script/lua_api/l_client.h | 3 +++ src/script/lua_api/l_nodemeta.cpp | 54 +++++++++++++++++++++++++++++++++------ src/script/lua_api/l_nodemeta.h | 12 ++++++++- 6 files changed, 89 insertions(+), 10 deletions(-) (limited to 'src/script/lua_api/l_nodemeta.cpp') diff --git a/doc/client_lua_api.md b/doc/client_lua_api.md index c9ccbeefa..68156efd3 100644 --- a/doc/client_lua_api.md +++ b/doc/client_lua_api.md @@ -690,6 +690,8 @@ Call these functions only at load time! for unloaded areas. * `minetest.get_node_or_nil(pos)` * Same as `get_node` but returns `nil` for unloaded areas. +* `minetest.get_meta(pos)` + * Get a `NodeMetaRef` at that position ### Player * `minetest.get_wielded_item()` @@ -794,7 +796,18 @@ It can be created via `Settings(filename)`. * write changes to file * `to_table()`: returns `{[key1]=value1,...}` -Definition tables +### NodeMetaRef +Node metadata: reference extra data and functionality stored in a node. +Can be obtained via `minetest.get_meta(pos)`. + +#### Methods +* `get_string(name)` +* `get_int(name)` +* `get_float(name)` +* `to_table()`: returns `nil` or a table with keys: + * `fields`: key-value storage + * `inventory`: `{list1 = {}, ...}}` + ----------------- ### Chat command definition (`register_chatcommand`) diff --git a/src/script/clientscripting.cpp b/src/script/clientscripting.cpp index df30a7253..17c53985d 100644 --- a/src/script/clientscripting.cpp +++ b/src/script/clientscripting.cpp @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_sound.h" #include "lua_api/l_util.h" #include "lua_api/l_item.h" +#include "lua_api/l_nodemeta.h" ClientScripting::ClientScripting(Client *client): ScriptApiBase() @@ -68,4 +69,5 @@ void ClientScripting::InitializeModApi(lua_State *L, int top) LuaItemStack::Register(L); StorageRef::Register(L); LuaMinimap::Register(L); + NodeMetaRef::RegisterClient(L); } diff --git a/src/script/lua_api/l_client.cpp b/src/script/lua_api/l_client.cpp index 5f9474702..5a0cd5cc3 100644 --- a/src/script/lua_api/l_client.cpp +++ b/src/script/lua_api/l_client.cpp @@ -25,8 +25,11 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gettext.h" #include "l_internal.h" #include "lua_api/l_item.h" +#include "lua_api/l_nodemeta.h" #include "mainmenumanager.h" #include "util/string.h" +#include "clientenvironment.h" +#include "map.h" extern MainGameCallback *g_gamecallback; @@ -182,6 +185,15 @@ int ModApiClient::l_get_wielded_item(lua_State *L) return 1; } +// get_meta(pos) +int ModApiClient::l_get_meta(lua_State *L) +{ + v3s16 p = read_v3s16(L, 1); + NodeMetadata *meta = getClient(L)->getEnv().getMap().getNodeMetadata(p); + NodeMetaRef::createClient(L, meta); + return 1; +} + void ModApiClient::Initialize(lua_State *L, int top) { API_FCT(get_current_modname); @@ -196,4 +208,5 @@ void ModApiClient::Initialize(lua_State *L, int top) API_FCT(get_node_or_nil); API_FCT(get_wielded_item); API_FCT(disconnect); + API_FCT(get_meta); } diff --git a/src/script/lua_api/l_client.h b/src/script/lua_api/l_client.h index d7f92ac1c..94b154bb4 100644 --- a/src/script/lua_api/l_client.h +++ b/src/script/lua_api/l_client.h @@ -62,6 +62,9 @@ private: // get_wielded_item() static int l_get_wielded_item(lua_State *L); + // get_meta(pos) + static int l_get_meta(lua_State *L); + public: static void Initialize(lua_State *L, int top); }; diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp index 4b2b392da..4368a8c50 100644 --- a/src/script/lua_api/l_nodemeta.cpp +++ b/src/script/lua_api/l_nodemeta.cpp @@ -38,6 +38,9 @@ NodeMetaRef* NodeMetaRef::checkobject(lua_State *L, int narg) Metadata* NodeMetaRef::getmeta(bool auto_create) { + if (m_is_local) + return m_meta; + NodeMetadata *meta = m_env->getMap().getNodeMetadata(m_p); if (meta == NULL && auto_create) { meta = new NodeMetadata(m_env->getGameDef()->idef()); @@ -142,7 +145,14 @@ bool NodeMetaRef::handleFromTable(lua_State *L, int table, Metadata *_meta) NodeMetaRef::NodeMetaRef(v3s16 p, ServerEnvironment *env): m_p(p), - m_env(env) + m_env(env), + m_is_local(false) +{ +} + +NodeMetaRef::NodeMetaRef(Metadata *meta): + m_meta(meta), + m_is_local(true) { } @@ -161,7 +171,17 @@ void NodeMetaRef::create(lua_State *L, v3s16 p, ServerEnvironment *env) lua_setmetatable(L, -2); } -void NodeMetaRef::Register(lua_State *L) +// Client-sided version of the above +void NodeMetaRef::createClient(lua_State *L, Metadata *meta) +{ + NodeMetaRef *o = new NodeMetaRef(meta); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); +} + +const char NodeMetaRef::className[] = "NodeMetaRef"; +void NodeMetaRef::RegisterCommon(lua_State *L) { lua_newtable(L); int methodtable = lua_gettop(L); @@ -185,16 +205,17 @@ void NodeMetaRef::Register(lua_State *L) lua_settable(L, metatable); lua_pop(L, 1); // drop metatable +} - luaL_openlib(L, 0, methods, 0); // fill methodtable +void NodeMetaRef::Register(lua_State *L) +{ + RegisterCommon(L); + luaL_openlib(L, 0, methodsServer, 0); // fill methodtable lua_pop(L, 1); // drop methodtable - - // Cannot be created from Lua - //lua_register(L, className, create_object); } -const char NodeMetaRef::className[] = "NodeMetaRef"; -const luaL_reg NodeMetaRef::methods[] = { + +const luaL_reg NodeMetaRef::methodsServer[] = { luamethod(MetaDataRef, get_string), luamethod(MetaDataRef, set_string), luamethod(MetaDataRef, get_int), @@ -206,3 +227,20 @@ const luaL_reg NodeMetaRef::methods[] = { luamethod(NodeMetaRef, get_inventory), {0,0} }; + + +void NodeMetaRef::RegisterClient(lua_State *L) +{ + RegisterCommon(L); + luaL_openlib(L, 0, methodsClient, 0); // fill methodtable + lua_pop(L, 1); // drop methodtable +} + + +const luaL_reg NodeMetaRef::methodsClient[] = { + luamethod(MetaDataRef, get_string), + luamethod(MetaDataRef, get_int), + luamethod(MetaDataRef, get_float), + luamethod(MetaDataRef, to_table), + {0,0} +}; diff --git a/src/script/lua_api/l_nodemeta.h b/src/script/lua_api/l_nodemeta.h index d03f086c9..6d146416b 100644 --- a/src/script/lua_api/l_nodemeta.h +++ b/src/script/lua_api/l_nodemeta.h @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_base.h" #include "lua_api/l_metadata.h" #include "irrlichttypes_bloated.h" +#include "nodemetadata.h" class ServerEnvironment; class NodeMetadata; @@ -34,9 +35,12 @@ class NodeMetaRef : public MetaDataRef { private: v3s16 m_p; ServerEnvironment *m_env; + Metadata *m_meta; + bool m_is_local; static const char className[]; - static const luaL_reg methods[]; + static const luaL_reg methodsServer[]; + static const luaL_reg methodsClient[]; static NodeMetaRef *checkobject(lua_State *L, int narg); @@ -71,6 +75,7 @@ private: public: NodeMetaRef(v3s16 p, ServerEnvironment *env); + NodeMetaRef(Metadata *meta); ~NodeMetaRef(); @@ -78,7 +83,12 @@ public: // Not callable from Lua; all references are created on the C side. static void create(lua_State *L, v3s16 p, ServerEnvironment *env); + // Client-sided version of the above + static void createClient(lua_State *L, Metadata *meta); + + static void RegisterCommon(lua_State *L); static void Register(lua_State *L); + static void RegisterClient(lua_State *L); }; #endif /* L_NODEMETA_H_ */ -- cgit v1.2.3 From 41c54830242269de073e4a0c10d1775dfdf6811d Mon Sep 17 00:00:00 2001 From: Loïc Blot Date: Sat, 8 Apr 2017 09:28:37 +0200 Subject: Replace luaL_reg with luaL_Reg as recent LuaJIT dropped the Lua 5.0 compat (#5541) We are bundling Lua5.1 which has same macro --- src/script/lua_api/l_areastore.cpp | 4 ++-- src/script/lua_api/l_areastore.h | 2 +- src/script/lua_api/l_inventory.cpp | 2 +- src/script/lua_api/l_inventory.h | 2 +- src/script/lua_api/l_item.cpp | 2 +- src/script/lua_api/l_item.h | 2 +- src/script/lua_api/l_itemstackmeta.cpp | 2 +- src/script/lua_api/l_itemstackmeta.h | 2 +- src/script/lua_api/l_minimap.cpp | 2 +- src/script/lua_api/l_minimap.h | 2 +- src/script/lua_api/l_nodemeta.cpp | 4 ++-- src/script/lua_api/l_nodemeta.h | 4 ++-- src/script/lua_api/l_nodetimer.cpp | 2 +- src/script/lua_api/l_nodetimer.h | 2 +- src/script/lua_api/l_noise.cpp | 10 +++++----- src/script/lua_api/l_noise.h | 10 +++++----- src/script/lua_api/l_object.cpp | 2 +- src/script/lua_api/l_object.h | 2 +- src/script/lua_api/l_settings.cpp | 2 +- src/script/lua_api/l_settings.h | 2 +- src/script/lua_api/l_storage.cpp | 2 +- src/script/lua_api/l_storage.h | 2 +- src/script/lua_api/l_vmanip.cpp | 2 +- src/script/lua_api/l_vmanip.h | 2 +- 24 files changed, 35 insertions(+), 35 deletions(-) (limited to 'src/script/lua_api/l_nodemeta.cpp') diff --git a/src/script/lua_api/l_areastore.cpp b/src/script/lua_api/l_areastore.cpp index 09a5c78f9..b81985a7f 100644 --- a/src/script/lua_api/l_areastore.cpp +++ b/src/script/lua_api/l_areastore.cpp @@ -74,7 +74,7 @@ static inline void push_areas(lua_State *L, const std::vector &areas, static int deserialization_helper(lua_State *L, AreaStore *as, std::istream &is) { - try { + try { as->deserialize(is); } catch (const SerializationError &e) { lua_pushboolean(L, false); @@ -380,7 +380,7 @@ void LuaAreaStore::Register(lua_State *L) } const char LuaAreaStore::className[] = "AreaStore"; -const luaL_reg LuaAreaStore::methods[] = { +const luaL_Reg LuaAreaStore::methods[] = { luamethod(LuaAreaStore, get_area), luamethod(LuaAreaStore, get_areas_for_pos), luamethod(LuaAreaStore, get_areas_in_area), diff --git a/src/script/lua_api/l_areastore.h b/src/script/lua_api/l_areastore.h index 7dea08df4..8292e7712 100644 --- a/src/script/lua_api/l_areastore.h +++ b/src/script/lua_api/l_areastore.h @@ -28,7 +28,7 @@ class LuaAreaStore : public ModApiBase { private: static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; static int gc_object(lua_State *L); diff --git a/src/script/lua_api/l_inventory.cpp b/src/script/lua_api/l_inventory.cpp index 9a4aa845d..f5e76a7b6 100644 --- a/src/script/lua_api/l_inventory.cpp +++ b/src/script/lua_api/l_inventory.cpp @@ -463,7 +463,7 @@ void InvRef::Register(lua_State *L) } const char InvRef::className[] = "InvRef"; -const luaL_reg InvRef::methods[] = { +const luaL_Reg InvRef::methods[] = { luamethod(InvRef, is_empty), luamethod(InvRef, get_size), luamethod(InvRef, set_size), diff --git a/src/script/lua_api/l_inventory.h b/src/script/lua_api/l_inventory.h index cc5333965..91d41c0d0 100644 --- a/src/script/lua_api/l_inventory.h +++ b/src/script/lua_api/l_inventory.h @@ -36,7 +36,7 @@ private: InventoryLocation m_loc; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; static InvRef *checkobject(lua_State *L, int narg); diff --git a/src/script/lua_api/l_item.cpp b/src/script/lua_api/l_item.cpp index 7e6f457e1..19b5b0955 100644 --- a/src/script/lua_api/l_item.cpp +++ b/src/script/lua_api/l_item.cpp @@ -462,7 +462,7 @@ void LuaItemStack::Register(lua_State *L) } const char LuaItemStack::className[] = "ItemStack"; -const luaL_reg LuaItemStack::methods[] = { +const luaL_Reg LuaItemStack::methods[] = { luamethod(LuaItemStack, is_empty), luamethod(LuaItemStack, get_name), luamethod(LuaItemStack, set_name), diff --git a/src/script/lua_api/l_item.h b/src/script/lua_api/l_item.h index 1ba5d79e0..b4efaefc8 100644 --- a/src/script/lua_api/l_item.h +++ b/src/script/lua_api/l_item.h @@ -28,7 +28,7 @@ private: ItemStack m_stack; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // Exported functions diff --git a/src/script/lua_api/l_itemstackmeta.cpp b/src/script/lua_api/l_itemstackmeta.cpp index 304a7cdf3..efdd77b51 100644 --- a/src/script/lua_api/l_itemstackmeta.cpp +++ b/src/script/lua_api/l_itemstackmeta.cpp @@ -102,7 +102,7 @@ void ItemStackMetaRef::Register(lua_State *L) } const char ItemStackMetaRef::className[] = "ItemStackMetaRef"; -const luaL_reg ItemStackMetaRef::methods[] = { +const luaL_Reg ItemStackMetaRef::methods[] = { luamethod(MetaDataRef, get_string), luamethod(MetaDataRef, set_string), luamethod(MetaDataRef, get_int), diff --git a/src/script/lua_api/l_itemstackmeta.h b/src/script/lua_api/l_itemstackmeta.h index 6f9b2016c..4ef64a91e 100644 --- a/src/script/lua_api/l_itemstackmeta.h +++ b/src/script/lua_api/l_itemstackmeta.h @@ -31,7 +31,7 @@ private: ItemStack *istack; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; static ItemStackMetaRef *checkobject(lua_State *L, int narg); diff --git a/src/script/lua_api/l_minimap.cpp b/src/script/lua_api/l_minimap.cpp index 182894f4f..c68602909 100644 --- a/src/script/lua_api/l_minimap.cpp +++ b/src/script/lua_api/l_minimap.cpp @@ -201,7 +201,7 @@ void LuaMinimap::Register(lua_State *L) } const char LuaMinimap::className[] = "Minimap"; -const luaL_reg LuaMinimap::methods[] = { +const luaL_Reg LuaMinimap::methods[] = { luamethod(LuaMinimap, show), luamethod(LuaMinimap, hide), luamethod(LuaMinimap, get_pos), diff --git a/src/script/lua_api/l_minimap.h b/src/script/lua_api/l_minimap.h index 9a299b4fd..8be72b8e7 100644 --- a/src/script/lua_api/l_minimap.h +++ b/src/script/lua_api/l_minimap.h @@ -28,7 +28,7 @@ class LuaMinimap : public ModApiBase { private: static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // garbage collector static int gc_object(lua_State *L); diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp index 4368a8c50..55d11fc13 100644 --- a/src/script/lua_api/l_nodemeta.cpp +++ b/src/script/lua_api/l_nodemeta.cpp @@ -215,7 +215,7 @@ void NodeMetaRef::Register(lua_State *L) } -const luaL_reg NodeMetaRef::methodsServer[] = { +const luaL_Reg NodeMetaRef::methodsServer[] = { luamethod(MetaDataRef, get_string), luamethod(MetaDataRef, set_string), luamethod(MetaDataRef, get_int), @@ -237,7 +237,7 @@ void NodeMetaRef::RegisterClient(lua_State *L) } -const luaL_reg NodeMetaRef::methodsClient[] = { +const luaL_Reg NodeMetaRef::methodsClient[] = { luamethod(MetaDataRef, get_string), luamethod(MetaDataRef, get_int), luamethod(MetaDataRef, get_float), diff --git a/src/script/lua_api/l_nodemeta.h b/src/script/lua_api/l_nodemeta.h index 6d146416b..2ac028079 100644 --- a/src/script/lua_api/l_nodemeta.h +++ b/src/script/lua_api/l_nodemeta.h @@ -39,8 +39,8 @@ private: bool m_is_local; static const char className[]; - static const luaL_reg methodsServer[]; - static const luaL_reg methodsClient[]; + static const luaL_Reg methodsServer[]; + static const luaL_Reg methodsClient[]; static NodeMetaRef *checkobject(lua_State *L, int narg); diff --git a/src/script/lua_api/l_nodetimer.cpp b/src/script/lua_api/l_nodetimer.cpp index ed11cc58e..17b275c46 100644 --- a/src/script/lua_api/l_nodetimer.cpp +++ b/src/script/lua_api/l_nodetimer.cpp @@ -162,7 +162,7 @@ void NodeTimerRef::Register(lua_State *L) } const char NodeTimerRef::className[] = "NodeTimerRef"; -const luaL_reg NodeTimerRef::methods[] = { +const luaL_Reg NodeTimerRef::methods[] = { luamethod(NodeTimerRef, start), luamethod(NodeTimerRef, set), luamethod(NodeTimerRef, stop), diff --git a/src/script/lua_api/l_nodetimer.h b/src/script/lua_api/l_nodetimer.h index 239112037..ae362d8b3 100644 --- a/src/script/lua_api/l_nodetimer.h +++ b/src/script/lua_api/l_nodetimer.h @@ -32,7 +32,7 @@ private: ServerEnvironment *m_env; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; static int gc_object(lua_State *L); diff --git a/src/script/lua_api/l_noise.cpp b/src/script/lua_api/l_noise.cpp index e0039371f..e3e76191f 100644 --- a/src/script/lua_api/l_noise.cpp +++ b/src/script/lua_api/l_noise.cpp @@ -135,7 +135,7 @@ void LuaPerlinNoise::Register(lua_State *L) const char LuaPerlinNoise::className[] = "PerlinNoise"; -const luaL_reg LuaPerlinNoise::methods[] = { +const luaL_Reg LuaPerlinNoise::methods[] = { luamethod(LuaPerlinNoise, get2d), luamethod(LuaPerlinNoise, get3d), {0,0} @@ -393,7 +393,7 @@ void LuaPerlinNoiseMap::Register(lua_State *L) const char LuaPerlinNoiseMap::className[] = "PerlinNoiseMap"; -const luaL_reg LuaPerlinNoiseMap::methods[] = { +const luaL_Reg LuaPerlinNoiseMap::methods[] = { luamethod(LuaPerlinNoiseMap, get2dMap), luamethod(LuaPerlinNoiseMap, get2dMap_flat), luamethod(LuaPerlinNoiseMap, calc2dMap), @@ -498,7 +498,7 @@ void LuaPseudoRandom::Register(lua_State *L) const char LuaPseudoRandom::className[] = "PseudoRandom"; -const luaL_reg LuaPseudoRandom::methods[] = { +const luaL_Reg LuaPseudoRandom::methods[] = { luamethod(LuaPseudoRandom, next), {0,0} }; @@ -597,7 +597,7 @@ void LuaPcgRandom::Register(lua_State *L) const char LuaPcgRandom::className[] = "PcgRandom"; -const luaL_reg LuaPcgRandom::methods[] = { +const luaL_Reg LuaPcgRandom::methods[] = { luamethod(LuaPcgRandom, next), luamethod(LuaPcgRandom, rand_normal_dist), {0,0} @@ -711,7 +711,7 @@ void LuaSecureRandom::Register(lua_State *L) } const char LuaSecureRandom::className[] = "SecureRandom"; -const luaL_reg LuaSecureRandom::methods[] = { +const luaL_Reg LuaSecureRandom::methods[] = { luamethod(LuaSecureRandom, next_bytes), {0,0} }; diff --git a/src/script/lua_api/l_noise.h b/src/script/lua_api/l_noise.h index 11ec348bf..f252b5ba2 100644 --- a/src/script/lua_api/l_noise.h +++ b/src/script/lua_api/l_noise.h @@ -32,7 +32,7 @@ class LuaPerlinNoise : public ModApiBase private: NoiseParams np; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // Exported functions @@ -64,7 +64,7 @@ class LuaPerlinNoiseMap : public ModApiBase Noise *noise; bool m_is3d; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // Exported functions @@ -103,7 +103,7 @@ private: PseudoRandom m_pseudo; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // Exported functions @@ -134,7 +134,7 @@ private: PcgRandom m_rnd; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // Exported functions @@ -169,7 +169,7 @@ class LuaSecureRandom : public ModApiBase private: static const size_t RAND_BUF_SIZE = 2048; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; u32 m_rand_idx; char m_rand_buf[RAND_BUF_SIZE]; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index d5681b809..f9d2754e7 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1823,7 +1823,7 @@ void ObjectRef::Register(lua_State *L) } const char ObjectRef::className[] = "ObjectRef"; -const luaL_reg ObjectRef::methods[] = { +const luaL_Reg ObjectRef::methods[] = { // ServerActiveObject luamethod(ObjectRef, remove), luamethod_aliased(ObjectRef, get_pos, getpos), diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index 2c9aa559a..b6fc35bc2 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -37,7 +37,7 @@ private: ServerActiveObject *m_object; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; public: static ObjectRef *checkobject(lua_State *L, int narg); diff --git a/src/script/lua_api/l_settings.cpp b/src/script/lua_api/l_settings.cpp index d3fe03005..809f7d115 100644 --- a/src/script/lua_api/l_settings.cpp +++ b/src/script/lua_api/l_settings.cpp @@ -214,7 +214,7 @@ LuaSettings* LuaSettings::checkobject(lua_State* L, int narg) } const char LuaSettings::className[] = "Settings"; -const luaL_reg LuaSettings::methods[] = { +const luaL_Reg LuaSettings::methods[] = { luamethod(LuaSettings, get), luamethod(LuaSettings, get_bool), luamethod(LuaSettings, set), diff --git a/src/script/lua_api/l_settings.h b/src/script/lua_api/l_settings.h index d5edd32ce..b90f0a8f2 100644 --- a/src/script/lua_api/l_settings.h +++ b/src/script/lua_api/l_settings.h @@ -28,7 +28,7 @@ class LuaSettings : public ModApiBase { private: static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // garbage collector static int gc_object(lua_State *L); diff --git a/src/script/lua_api/l_storage.cpp b/src/script/lua_api/l_storage.cpp index 867ab9c8d..59906dda5 100644 --- a/src/script/lua_api/l_storage.cpp +++ b/src/script/lua_api/l_storage.cpp @@ -129,7 +129,7 @@ void StorageRef::clearMeta() } const char StorageRef::className[] = "StorageRef"; -const luaL_reg StorageRef::methods[] = { +const luaL_Reg StorageRef::methods[] = { luamethod(MetaDataRef, get_string), luamethod(MetaDataRef, set_string), luamethod(MetaDataRef, get_int), diff --git a/src/script/lua_api/l_storage.h b/src/script/lua_api/l_storage.h index e09b8b391..ec6f8d941 100644 --- a/src/script/lua_api/l_storage.h +++ b/src/script/lua_api/l_storage.h @@ -41,7 +41,7 @@ private: ModMetadata *m_object; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; virtual Metadata *getmeta(bool auto_create); virtual void clearMeta(); diff --git a/src/script/lua_api/l_vmanip.cpp b/src/script/lua_api/l_vmanip.cpp index 5f129d2af..7316fb200 100644 --- a/src/script/lua_api/l_vmanip.cpp +++ b/src/script/lua_api/l_vmanip.cpp @@ -452,7 +452,7 @@ void LuaVoxelManip::Register(lua_State *L) } const char LuaVoxelManip::className[] = "VoxelManip"; -const luaL_reg LuaVoxelManip::methods[] = { +const luaL_Reg LuaVoxelManip::methods[] = { luamethod(LuaVoxelManip, read_from_map), luamethod(LuaVoxelManip, get_data), luamethod(LuaVoxelManip, set_data), diff --git a/src/script/lua_api/l_vmanip.h b/src/script/lua_api/l_vmanip.h index 65fc0d97a..b6a69f36a 100644 --- a/src/script/lua_api/l_vmanip.h +++ b/src/script/lua_api/l_vmanip.h @@ -38,7 +38,7 @@ private: bool is_mapgen_vm; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; static int gc_object(lua_State *L); -- cgit v1.2.3 From 58d83a7bb2f992194c3df304b1dcbb81f98f78c0 Mon Sep 17 00:00:00 2001 From: Dániel Juhász Date: Fri, 10 Mar 2017 18:25:58 +0100 Subject: Hardware coloring for itemstacks Adds the possibility to colorize item stacks based on their metadata. In the item/node definition you can specify palette (an image file) and color (fallback color if the item has no palette or metadata). Then you can add palette_index to the metadata. Dropped itemstacks with different colors do not merge. --- builtin/game/item_entity.lua | 31 +++++++++---- doc/lua_api.txt | 18 ++++++++ src/camera.cpp | 3 +- src/client/tile.cpp | 69 +++++++++++++++++++++++++++- src/client/tile.h | 15 ++++--- src/content_cao.cpp | 39 +++++++++------- src/hud.cpp | 20 +++++++-- src/itemdef.cpp | 55 +++++++++++++++++++---- src/itemdef.h | 18 +++++++- src/nodedef.cpp | 82 +--------------------------------- src/object_properties.cpp | 2 + src/object_properties.h | 2 + src/script/common/c_content.cpp | 14 +++++- src/script/common/c_content.h | 3 +- src/script/cpp_api/s_entity.cpp | 5 ++- src/script/lua_api/l_itemstackmeta.cpp | 5 +++ src/script/lua_api/l_metadata.cpp | 14 ++++++ src/script/lua_api/l_metadata.h | 3 ++ src/script/lua_api/l_nodemeta.cpp | 5 +++ src/script/lua_api/l_object.cpp | 2 +- src/script/lua_api/l_storage.cpp | 5 +++ src/wieldmesh.cpp | 19 +++++--- src/wieldmesh.h | 18 +++++++- 23 files changed, 308 insertions(+), 139 deletions(-) (limited to 'src/script/lua_api/l_nodemeta.cpp') diff --git a/builtin/game/item_entity.lua b/builtin/game/item_entity.lua index be158c119..7b8247116 100644 --- a/builtin/game/item_entity.lua +++ b/builtin/game/item_entity.lua @@ -53,6 +53,8 @@ core.register_entity(":__builtin:item", { if itemtable then itemname = stack:to_table().name end + -- Backwards compatibility: old clients use the texture + -- to get the type of the item local item_texture = nil local item_type = "" if core.registered_items[itemname] then @@ -66,6 +68,7 @@ core.register_entity(":__builtin:item", { visual_size = {x = s, y = s}, collisionbox = {-c, -c, -c, c, c, c}, automatic_rotate = math.pi * 0.5, + wield_item = itemstring, } self.object:set_properties(prop) end, @@ -101,31 +104,39 @@ core.register_entity(":__builtin:item", { self:set_item(self.itemstring) end, + -- moves items from this stack to an other stack try_merge_with = function(self, own_stack, object, obj) + -- other item's stack local stack = ItemStack(obj.itemstring) - if own_stack:get_name() == stack:get_name() and stack:get_free_space() > 0 then + -- only merge if items are the same + if own_stack:get_name() == stack:get_name() and + own_stack:get_meta() == stack:get_meta() and + own_stack:get_wear() == stack:get_wear() and + stack:get_free_space() > 0 then local overflow = false local count = stack:get_count() + own_stack:get_count() local max_count = stack:get_stack_max() if count > max_count then overflow = true + stack:set_count(max_count) count = count - max_count + own_stack:set_count(count) else self.itemstring = '' + stack:set_count(count) end local pos = object:getpos() pos.y = pos.y + (count - stack:get_count()) / max_count * 0.15 object:moveto(pos, false) local s, c - local max_count = stack:get_stack_max() - local name = stack:get_name() if not overflow then - obj.itemstring = name .. " " .. count + obj.itemstring = stack:to_string() s = 0.2 + 0.1 * (count / max_count) c = s object:set_properties({ visual_size = {x = s, y = s}, - collisionbox = {-c, -c, -c, c, c, c} + collisionbox = {-c, -c, -c, c, c, c}, + wield_item = obj.itemstring }) self.object:remove() -- merging succeeded @@ -133,18 +144,20 @@ core.register_entity(":__builtin:item", { else s = 0.4 c = 0.3 + obj.itemstring = stack:to_string() object:set_properties({ visual_size = {x = s, y = s}, - collisionbox = {-c, -c, -c, c, c, c} + collisionbox = {-c, -c, -c, c, c, c}, + wield_item = obj.itemstring }) - obj.itemstring = name .. " " .. max_count s = 0.2 + 0.1 * (count / max_count) c = s + self.itemstring = own_stack:to_string() self.object:set_properties({ visual_size = {x = s, y = s}, - collisionbox = {-c, -c, -c, c, c, c} + collisionbox = {-c, -c, -c, c, c, c}, + wield_item = self.itemstring }) - self.itemstring = name .. " " .. count end end -- merging didn't succeed diff --git a/doc/lua_api.txt b/doc/lua_api.txt index ca1b5d14c..721f5448a 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1480,6 +1480,9 @@ Item metadata only contains a key-value store. Some of the values in the key-value store are handled specially: * `description`: Set the itemstack's description. Defaults to idef.description +* `color`: A `ColorString`, which sets the stack's color. +* `palette_index`: If the item has a palette, this is used to get the + current color from the palette. Example stuff: @@ -2855,6 +2858,8 @@ See `StorageRef`, `NodeMetaRef` and `ItemStackMetaRef`. * Any non-table value will clear the metadata * See "Node Metadata" for an example * returns `true` on success +* `equals(other)` + * returns `true` if this metadata has the same key-value pairs as `other` ### `NodeMetaRef` Node metadata: reference extra data and functionality stored in a node. @@ -3735,6 +3740,19 @@ Definition tables {hard = 1, metal = 1, spikes = 1} inventory_image = "default_tool_steelaxe.png", wield_image = "", + palette = "", + --[[ + ^ An image file containing the palette of a node. + ^ You can set the currently used color as the + ^ "palette_index" field of the item stack metadata. + ^ The palette is always stretched to fit indices + ^ between 0 and 255, to ensure compatibility with + ^ "colorfacedir" and "colorwallmounted" nodes. + ]] + color = "0xFFFFFFFF", + --[[ + ^ The color of the item. The palette overrides this. + ]] wield_scale = {x = 1, y = 1, z = 1}, stack_max = 99, range = 4.0, diff --git a/src/camera.cpp b/src/camera.cpp index d5c337fe8..7e83dadeb 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -501,7 +501,8 @@ void Camera::setDigging(s32 button) void Camera::wield(const ItemStack &item) { - if (item.name != m_wield_item_next.name) { + if (item.name != m_wield_item_next.name || + item.metadata != m_wield_item_next.metadata) { m_wield_item_next = item; if (m_wield_change_timer > 0) m_wield_change_timer = -m_wield_change_timer; diff --git a/src/client/tile.cpp b/src/client/tile.cpp index 86ca7d422..0aa06980c 100644 --- a/src/client/tile.cpp +++ b/src/client/tile.cpp @@ -341,6 +341,8 @@ public: */ video::ITexture* getTextureForMesh(const std::string &name, u32 *id); + virtual Palette* getPalette(const std::string &name); + // Returns a pointer to the irrlicht device virtual IrrlichtDevice* getDevice() { @@ -377,8 +379,6 @@ public: video::ITexture* generateTextureFromMesh( const TextureFromMeshParams ¶ms); - video::IImage* generateImage(const std::string &name); - video::ITexture* getNormalTexture(const std::string &name); video::SColor getTextureAverageColor(const std::string &name); video::ITexture *getShaderFlagsTexture(bool normamap_present); @@ -401,6 +401,13 @@ private: // if baseimg is NULL, it is created. Otherwise stuff is made on it. bool generateImagePart(std::string part_of_name, video::IImage *& baseimg); + /*! Generates an image from a full string like + * "stone.png^mineral_coal.png^[crack:1:0". + * Shall be called from the main thread. + * The returned Image should be dropped. + */ + video::IImage* generateImage(const std::string &name); + // Thread-safe cache of what source images are known (true = known) MutexedMap m_source_image_existence; @@ -419,6 +426,9 @@ private: // but can't be deleted because the ITexture* might still be used std::vector m_texture_trash; + // Maps image file names to loaded palettes. + UNORDERED_MAP m_palettes; + // Cached settings needed for making textures from meshes bool m_setting_trilinear_filter; bool m_setting_bilinear_filter; @@ -682,6 +692,61 @@ video::ITexture* TextureSource::getTextureForMesh(const std::string &name, u32 * return getTexture(name + "^[applyfiltersformesh", id); } +Palette* TextureSource::getPalette(const std::string &name) +{ + // Only the main thread may load images + sanity_check(thr_is_current_thread(m_main_thread)); + + if (name == "") + return NULL; + + UNORDERED_MAP::iterator it = m_palettes.find(name); + if (it == m_palettes.end()) { + // Create palette + video::IImage *img = generateImage(name); + if (!img) { + warningstream << "TextureSource::getPalette(): palette \"" << name + << "\" could not be loaded." << std::endl; + return NULL; + } + Palette new_palette; + u32 w = img->getDimension().Width; + u32 h = img->getDimension().Height; + // Real area of the image + u32 area = h * w; + if (area == 0) + return NULL; + if (area > 256) { + warningstream << "TextureSource::getPalette(): the specified" + << " palette image \"" << name << "\" is larger than 256" + << " pixels, using the first 256." << std::endl; + area = 256; + } else if (256 % area != 0) + warningstream << "TextureSource::getPalette(): the " + << "specified palette image \"" << name << "\" does not " + << "contain power of two pixels." << std::endl; + // We stretch the palette so it will fit 256 values + // This many param2 values will have the same color + u32 step = 256 / area; + // For each pixel in the image + for (u32 i = 0; i < area; i++) { + video::SColor c = img->getPixel(i % w, i / w); + // Fill in palette with 'step' colors + for (u32 j = 0; j < step; j++) + new_palette.push_back(c); + } + img->drop(); + // Fill in remaining elements + while (new_palette.size() < 256) + new_palette.push_back(video::SColor(0xFFFFFFFF)); + m_palettes[name] = new_palette; + it = m_palettes.find(name); + } + if (it != m_palettes.end()) + return &((*it).second); + return NULL; +} + void TextureSource::processQueue() { /* diff --git a/src/client/tile.h b/src/client/tile.h index d04ab918a..5eec0f2ea 100644 --- a/src/client/tile.h +++ b/src/client/tile.h @@ -33,6 +33,8 @@ class IGameDef; struct TileSpec; struct TileDef; +typedef std::vector Palette; + /* tile.{h,cpp}: Texture handling stuff. */ @@ -106,14 +108,15 @@ public: const std::string &name, u32 *id = NULL)=0; virtual video::ITexture* getTextureForMesh( const std::string &name, u32 *id = NULL) = 0; + /*! + * Returns a palette from the given texture name. + * The pointer is valid until the texture source is + * destructed. + * Should be called from the main thread. + */ + virtual Palette* getPalette(const std::string &name) = 0; virtual IrrlichtDevice* getDevice()=0; virtual bool isKnownSourceImage(const std::string &name)=0; - /*! Generates an image from a full string like - * "stone.png^mineral_coal.png^[crack:1:0". - * Shall be called from the main thread. - * The returned Image should be dropped. - */ - virtual video::IImage* generateImage(const std::string &name)=0; virtual video::ITexture* generateTextureFromMesh( const TextureFromMeshParams ¶ms)=0; virtual video::ITexture* getNormalTexture(const std::string &name)=0; diff --git a/src/content_cao.cpp b/src/content_cao.cpp index e0b1c4cd2..84f198b75 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -933,23 +933,30 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, errorstream<<"GenericCAO::addToScene(): Could not load mesh "<= 1){ - infostream<<"textures[0]: "<idef(); - ItemStack item(m_prop.textures[0], 1, 0, idef); - - m_wield_meshnode = new WieldMeshSceneNode( - smgr->getRootSceneNode(), smgr, -1); - m_wield_meshnode->setItem(item, m_client); - - m_wield_meshnode->setScale(v3f(m_prop.visual_size.X/2, - m_prop.visual_size.Y/2, - m_prop.visual_size.X/2)); - u8 li = m_last_light; - m_wield_meshnode->setColor(video::SColor(255,li,li,li)); + ItemStack item; + infostream << "GenericCAO::addToScene(): wielditem" << std::endl; + if (m_prop.wield_item == "") { + // Old format, only textures are specified. + infostream << "textures: " << m_prop.textures.size() << std::endl; + if (m_prop.textures.size() >= 1) { + infostream << "textures[0]: " << m_prop.textures[0] + << std::endl; + IItemDefManager *idef = m_client->idef(); + item = ItemStack(m_prop.textures[0], 1, 0, idef); + } + } else { + infostream << "serialized form: " << m_prop.wield_item << std::endl; + item.deSerialize(m_prop.wield_item, m_client->idef()); } + m_wield_meshnode = new WieldMeshSceneNode(smgr->getRootSceneNode(), + smgr, -1); + m_wield_meshnode->setItem(item, m_client); + + m_wield_meshnode->setScale( + v3f(m_prop.visual_size.X / 2, m_prop.visual_size.Y / 2, + m_prop.visual_size.X / 2)); + u8 li = m_last_light; + m_wield_meshnode->setColor(video::SColor(255, li, li, li)); } else { infostream<<"GenericCAO::addToScene(): \""< #ifdef HAVE_TOUCHSCREENGUI @@ -642,9 +643,10 @@ void drawItemStack(video::IVideoDriver *driver, } const ItemDefinition &def = item.getDefinition(client->idef()); - scene::IMesh* mesh = client->idef()->getWieldMesh(def.name, client); + ItemMesh *imesh = client->idef()->getWieldMesh(def.name, client); - if (mesh) { + if (imesh && imesh->mesh) { + scene::IMesh *mesh = imesh->mesh; driver->clearZBuffer(); s32 delta = 0; if (rotation_kind < IT_ROT_NONE) { @@ -667,16 +669,28 @@ void drawItemStack(video::IVideoDriver *driver, matrix.makeIdentity(); if (enable_animations) { - float timer_f = (float)delta / 5000.0; + float timer_f = (float) delta / 5000.0; matrix.setRotationDegrees(core::vector3df(0, 360 * timer_f, 0)); } driver->setTransform(video::ETS_WORLD, matrix); driver->setViewPort(rect); + video::SColor basecolor = + client->idef()->getItemstackColor(item, client); + u32 mc = mesh->getMeshBufferCount(); for (u32 j = 0; j < mc; ++j) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); + // we can modify vertices relatively fast, + // because these meshes are not buffered. + assert(buf->getHardwareMappingHint_Vertex() == scene::EHM_NEVER); + video::SColor c = basecolor; + if (imesh->buffer_colors.size() > j) { + std::pair p = imesh->buffer_colors[j]; + c = p.first ? p.second : basecolor; + } + colorizeMeshBuffer(buf, &c); video::SMaterial &material = buf->getMaterial(); material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; material.Lighting = false; diff --git a/src/itemdef.cpp b/src/itemdef.cpp index 627ad1b6c..51d8f1d5d 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -82,6 +82,8 @@ ItemDefinition& ItemDefinition::operator=(const ItemDefinition &def) sound_place = def.sound_place; sound_place_failed = def.sound_place_failed; range = def.range; + palette_image = def.palette_image; + color = def.color; return *this; } @@ -104,6 +106,8 @@ void ItemDefinition::reset() description = ""; inventory_image = ""; wield_image = ""; + palette_image = ""; + color = video::SColor(0xFFFFFFFF); wield_scale = v3f(1.0, 1.0, 1.0); stack_max = 99; usable = false; @@ -153,6 +157,8 @@ void ItemDefinition::serialize(std::ostream &os, u16 protocol_version) const writeF1000(os, range); os << serializeString(sound_place_failed.name); writeF1000(os, sound_place_failed.gain); + os << serializeString(palette_image); + writeU32(os, color.color); } void ItemDefinition::deSerialize(std::istream &is) @@ -209,6 +215,8 @@ void ItemDefinition::deSerialize(std::istream &is) try { sound_place_failed.name = deSerializeString(is); sound_place_failed.gain = readF1000(is); + palette_image = deSerializeString(is); + color.set(readU32(is)); } catch(SerializationError &e) {}; } @@ -224,11 +232,13 @@ class CItemDefManager: public IWritableItemDefManager struct ClientCached { video::ITexture *inventory_texture; - scene::IMesh *wield_mesh; + ItemMesh wield_mesh; + Palette *palette; ClientCached(): inventory_texture(NULL), - wield_mesh(NULL) + wield_mesh(), + palette(NULL) {} }; #endif @@ -250,8 +260,8 @@ public: i = values.begin(); i != values.end(); ++i) { ClientCached *cc = *i; - if (cc->wield_mesh) - cc->wield_mesh->drop(); + if (cc->wield_mesh.mesh) + cc->wield_mesh.mesh->drop(); delete cc; } @@ -335,8 +345,9 @@ public: ItemStack item = ItemStack(); item.name = def.name; - scene::IMesh *mesh = getItemMesh(client, item); - cc->wield_mesh = mesh; + getItemMesh(client, item, &(cc->wield_mesh)); + + cc->palette = tsrc->getPalette(def.palette_image); // Put in cache m_clientcached.set(name, cc); @@ -390,13 +401,41 @@ public: return cc->inventory_texture; } // Get item wield mesh - virtual scene::IMesh* getWieldMesh(const std::string &name, + virtual ItemMesh* getWieldMesh(const std::string &name, Client *client) const { ClientCached *cc = getClientCached(name, client); if(!cc) return NULL; - return cc->wield_mesh; + return &(cc->wield_mesh); + } + + // Get item palette + virtual Palette* getPalette(const std::string &name, + Client *client) const + { + ClientCached *cc = getClientCached(name, client); + if(!cc) + return NULL; + return cc->palette; + } + + virtual video::SColor getItemstackColor(const ItemStack &stack, + Client *client) const + { + // Look for direct color definition + const std::string &colorstring = stack.metadata.getString("color", 0); + video::SColor directcolor; + if ((colorstring != "") + && parseColorString(colorstring, directcolor, true)) + return directcolor; + // See if there is a palette + Palette *palette = getPalette(stack.name, client); + const std::string &index = stack.metadata.getString("palette_index", 0); + if ((palette != NULL) && (index != "")) + return (*palette)[mystoi(index, 0, 255)]; + // Fallback color + return get(stack.name).color; } #endif void clear() diff --git a/src/itemdef.h b/src/itemdef.h index 01ec4fa2f..2d7ff570d 100644 --- a/src/itemdef.h +++ b/src/itemdef.h @@ -30,6 +30,11 @@ with this program; if not, write to the Free Software Foundation, Inc., class IGameDef; class Client; struct ToolCapabilities; +#ifndef SERVER +#include "client/tile.h" +struct ItemMesh; +struct ItemStack; +#endif /* Base item definition @@ -57,6 +62,8 @@ struct ItemDefinition */ std::string inventory_image; // Optional for nodes, mandatory for tools/craftitems std::string wield_image; // If empty, inventory_image or mesh (only nodes) is used + std::string palette_image; // If specified, the item will be colorized based on this + video::SColor color; // The fallback color of the node. v3f wield_scale; /* @@ -110,8 +117,15 @@ public: virtual video::ITexture* getInventoryTexture(const std::string &name, Client *client) const=0; // Get item wield mesh - virtual scene::IMesh* getWieldMesh(const std::string &name, + virtual ItemMesh* getWieldMesh(const std::string &name, Client *client) const=0; + // Get item palette + virtual Palette* getPalette(const std::string &name, + Client *client) const = 0; + // Returns the base color of an item stack: the color of all + // tiles that do not define their own color. + virtual video::SColor getItemstackColor(const ItemStack &stack, + Client *client) const = 0; #endif virtual void serialize(std::ostream &os, u16 protocol_version)=0; @@ -136,7 +150,7 @@ public: virtual video::ITexture* getInventoryTexture(const std::string &name, Client *client) const=0; // Get item wield mesh - virtual scene::IMesh* getWieldMesh(const std::string &name, + virtual ItemMesh* getWieldMesh(const std::string &name, Client *client) const=0; #endif diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 2745a45e8..558acafd6 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -786,6 +786,8 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc tiledef_special[j].backface_culling, material_type); } + palette = tsrc->getPalette(palette_name); + if ((drawtype == NDT_MESH) && (mesh != "")) { // Meshnode drawtype // Read the mesh and apply scale @@ -859,9 +861,6 @@ public: virtual void removeNode(const std::string &name); virtual void updateAliases(IItemDefManager *idef); virtual void applyTextureOverrides(const std::string &override_filepath); - //! Returns a palette or NULL if not found. Only on client. - std::vector *getPalette(const ContentFeatures &f, - const IGameDef *gamedef); virtual void updateTextures(IGameDef *gamedef, void (*progress_cbk)(void *progress_args, u32 progress, u32 max_progress), void *progress_cbk_args); @@ -910,9 +909,6 @@ private: // Next possibly free id content_t m_next_id; - // Maps image file names to loaded palettes. - UNORDERED_MAP > m_palettes; - // NodeResolvers to callback once node registration has ended std::vector m_pending_resolve_callbacks; @@ -1401,78 +1397,6 @@ void CNodeDefManager::applyTextureOverrides(const std::string &override_filepath } } -std::vector *CNodeDefManager::getPalette( - const ContentFeatures &f, const IGameDef *gamedef) -{ -#ifndef SERVER - // This works because colors always use the most significant bits - // of param2. If you add a new colored type which uses param2 - // in a more advanced way, you should change this code, too. - u32 palette_pixels = 0; - switch (f.param_type_2) { - case CPT2_COLOR: - palette_pixels = 256; - break; - case CPT2_COLORED_FACEDIR: - palette_pixels = 8; - break; - case CPT2_COLORED_WALLMOUNTED: - palette_pixels = 32; - break; - default: - return NULL; - } - // This many param2 values will have the same color - u32 step = 256 / palette_pixels; - const std::string &name = f.palette_name; - if (name == "") - return NULL; - Client *client = (Client *) gamedef; - ITextureSource *tsrc = client->tsrc(); - - UNORDERED_MAP >::iterator it = - m_palettes.find(name); - if (it == m_palettes.end()) { - // Create palette - if (!tsrc->isKnownSourceImage(name)) { - warningstream << "CNodeDefManager::getPalette(): palette \"" << name - << "\" could not be loaded." << std::endl; - return NULL; - } - video::IImage *img = tsrc->generateImage(name); - std::vector new_palette; - u32 w = img->getDimension().Width; - u32 h = img->getDimension().Height; - // Real area of the image - u32 area = h * w; - if (area != palette_pixels) - warningstream << "CNodeDefManager::getPalette(): the " - << "specified palette image \"" << name << "\" does not " - << "contain exactly " << palette_pixels - << " pixels." << std::endl; - if (area > palette_pixels) - area = palette_pixels; - // For each pixel in the image - for (u32 i = 0; i < area; i++) { - video::SColor c = img->getPixel(i % w, i / w); - // Fill in palette with 'step' colors - for (u32 j = 0; j < step; j++) - new_palette.push_back(c); - } - img->drop(); - // Fill in remaining elements - while (new_palette.size() < 256) - new_palette.push_back(video::SColor(0xFFFFFFFF)); - m_palettes[name] = new_palette; - it = m_palettes.find(name); - } - if (it != m_palettes.end()) - return &((*it).second); - -#endif - return NULL; -} - void CNodeDefManager::updateTextures(IGameDef *gamedef, void (*progress_callback)(void *progress_args, u32 progress, u32 max_progress), void *progress_callback_args) @@ -1489,12 +1413,10 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef, TextureSettings tsettings; tsettings.readSettings(); - m_palettes.clear(); u32 size = m_content_features.size(); for (u32 i = 0; i < size; i++) { ContentFeatures *f = &(m_content_features[i]); - f->palette = getPalette(*f, gamedef); f->updateTextures(tsrc, shdsrc, meshmanip, client, tsettings); progress_callback(progress_callback_args, i, size); } diff --git a/src/object_properties.cpp b/src/object_properties.cpp index f4e4953ba..a77368151 100644 --- a/src/object_properties.cpp +++ b/src/object_properties.cpp @@ -117,6 +117,7 @@ void ObjectProperties::serialize(std::ostream &os) const writeARGB8(os, nametag_color); writeF1000(os, automatic_face_movement_max_rotation_per_sec); os << serializeString(infotext); + os << serializeString(wield_item); // Add stuff only at the bottom. // Never remove anything, because we don't want new versions of this @@ -159,6 +160,7 @@ void ObjectProperties::deSerialize(std::istream &is) nametag_color = readARGB8(is); automatic_face_movement_max_rotation_per_sec = readF1000(is); infotext = deSerializeString(is); + wield_item = deSerializeString(is); }catch(SerializationError &e){} } else diff --git a/src/object_properties.h b/src/object_properties.h index 082d9a529..908757a64 100644 --- a/src/object_properties.h +++ b/src/object_properties.h @@ -52,6 +52,8 @@ struct ObjectProperties video::SColor nametag_color; f32 automatic_face_movement_max_rotation_per_sec; std::string infotext; + //! For dropped items, this contains item information. + std::string wield_item; ObjectProperties(); std::string dump(); diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 99e12cd82..bcae874b9 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -58,6 +58,12 @@ ItemDefinition read_item_definition(lua_State* L,int index, getstringfield(L, index, "description", def.description); getstringfield(L, index, "inventory_image", def.inventory_image); getstringfield(L, index, "wield_image", def.wield_image); + getstringfield(L, index, "palette", def.palette_image); + + // Read item color. + lua_getfield(L, index, "color"); + read_color(L, -1, &def.color); + lua_pop(L, 1); lua_getfield(L, index, "wield_scale"); if(lua_istable(L, -1)){ @@ -118,7 +124,7 @@ ItemDefinition read_item_definition(lua_State* L,int index, /******************************************************************************/ void read_object_properties(lua_State *L, int index, - ObjectProperties *prop) + ObjectProperties *prop, IItemDefManager *idef) { if(index < 0) index = lua_gettop(L) + 1 + index; @@ -216,6 +222,10 @@ void read_object_properties(lua_State *L, int index, } lua_pop(L, 1); getstringfield(L, -1, "infotext", prop->infotext); + lua_getfield(L, -1, "wield_item"); + if (!lua_isnil(L, -1)) + prop->wield_item = read_item(L, -1, idef).getItemString(); + lua_pop(L, 1); } /******************************************************************************/ @@ -284,6 +294,8 @@ void push_object_properties(lua_State *L, ObjectProperties *prop) lua_setfield(L, -2, "automatic_face_movement_max_rotation_per_sec"); lua_pushlstring(L, prop->infotext.c_str(), prop->infotext.size()); lua_setfield(L, -2, "infotext"); + lua_pushlstring(L, prop->wield_item.c_str(), prop->wield_item.size()); + lua_setfield(L, -2, "wield_item"); } /******************************************************************************/ diff --git a/src/script/common/c_content.h b/src/script/common/c_content.h index 10cccbb01..949b136eb 100644 --- a/src/script/common/c_content.h +++ b/src/script/common/c_content.h @@ -89,7 +89,8 @@ void push_tool_capabilities (lua_State *L, ItemDefinition read_item_definition (lua_State *L, int index, ItemDefinition default_def); void read_object_properties (lua_State *L, int index, - ObjectProperties *prop); + ObjectProperties *prop, + IItemDefManager *idef); void push_object_properties (lua_State *L, ObjectProperties *prop); diff --git a/src/script/cpp_api/s_entity.cpp b/src/script/cpp_api/s_entity.cpp index 9e2193970..2e1d277e4 100644 --- a/src/script/cpp_api/s_entity.cpp +++ b/src/script/cpp_api/s_entity.cpp @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "object_properties.h" #include "common/c_converter.h" #include "common/c_content.h" +#include "server.h" bool ScriptApiEntity::luaentity_Add(u16 id, const char *name) { @@ -187,11 +188,11 @@ void ScriptApiEntity::luaentity_GetProperties(u16 id, getstringfield(L, -1, "mesh", prop->mesh); // Deprecated: read object properties directly - read_object_properties(L, -1, prop); + read_object_properties(L, -1, prop, getServer()->idef()); // Read initial_properties lua_getfield(L, -1, "initial_properties"); - read_object_properties(L, -1, prop); + read_object_properties(L, -1, prop, getServer()->idef()); lua_pop(L, 1); } diff --git a/src/script/lua_api/l_itemstackmeta.cpp b/src/script/lua_api/l_itemstackmeta.cpp index efdd77b51..c37a82116 100644 --- a/src/script/lua_api/l_itemstackmeta.cpp +++ b/src/script/lua_api/l_itemstackmeta.cpp @@ -92,6 +92,10 @@ void ItemStackMetaRef::Register(lua_State *L) lua_pushcfunction(L, gc_object); lua_settable(L, metatable); + lua_pushliteral(L, "__eq"); + lua_pushcfunction(L, l_equals); + lua_settable(L, metatable); + lua_pop(L, 1); // drop metatable luaL_openlib(L, 0, methods, 0); // fill methodtable @@ -111,5 +115,6 @@ const luaL_Reg ItemStackMetaRef::methods[] = { luamethod(MetaDataRef, set_float), luamethod(MetaDataRef, to_table), luamethod(MetaDataRef, from_table), + luamethod(MetaDataRef, equals), {0,0} }; diff --git a/src/script/lua_api/l_metadata.cpp b/src/script/lua_api/l_metadata.cpp index b54005bac..5f4e984cb 100644 --- a/src/script/lua_api/l_metadata.cpp +++ b/src/script/lua_api/l_metadata.cpp @@ -250,3 +250,17 @@ bool MetaDataRef::handleFromTable(lua_State *L, int table, Metadata *meta) return true; } + +// equals(self, other) +int MetaDataRef::l_equals(lua_State *L) +{ + MetaDataRef *ref1 = checkobject(L, 1); + Metadata *data1 = ref1->getmeta(false); + MetaDataRef *ref2 = checkobject(L, 2); + Metadata *data2 = ref2->getmeta(false); + if (data1 == NULL || data2 == NULL) + lua_pushboolean(L, data1 == data2); + else + lua_pushboolean(L, *data1 == *data2); + return 1; +} diff --git a/src/script/lua_api/l_metadata.h b/src/script/lua_api/l_metadata.h index be31d95ad..a4d8214d3 100644 --- a/src/script/lua_api/l_metadata.h +++ b/src/script/lua_api/l_metadata.h @@ -67,6 +67,9 @@ protected: // from_table(self, table) static int l_from_table(lua_State *L); + + // equals(self, other) + static int l_equals(lua_State *L); }; #endif /* L_NODEMETA_H_ */ diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp index 55d11fc13..c65d56f14 100644 --- a/src/script/lua_api/l_nodemeta.cpp +++ b/src/script/lua_api/l_nodemeta.cpp @@ -204,6 +204,10 @@ void NodeMetaRef::RegisterCommon(lua_State *L) lua_pushcfunction(L, gc_object); lua_settable(L, metatable); + lua_pushliteral(L, "__eq"); + lua_pushcfunction(L, l_equals); + lua_settable(L, metatable); + lua_pop(L, 1); // drop metatable } @@ -225,6 +229,7 @@ const luaL_Reg NodeMetaRef::methodsServer[] = { luamethod(MetaDataRef, to_table), luamethod(MetaDataRef, from_table), luamethod(NodeMetaRef, get_inventory), + luamethod(MetaDataRef, equals), {0,0} }; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index f9d2754e7..0699705cb 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -737,7 +737,7 @@ int ObjectRef::l_set_properties(lua_State *L) ObjectProperties *prop = co->accessObjectProperties(); if (!prop) return 0; - read_object_properties(L, 2, prop); + read_object_properties(L, 2, prop, getServer(L)->idef()); co->notifyObjectPropertiesModified(); return 0; } diff --git a/src/script/lua_api/l_storage.cpp b/src/script/lua_api/l_storage.cpp index 59906dda5..4c6b2a182 100644 --- a/src/script/lua_api/l_storage.cpp +++ b/src/script/lua_api/l_storage.cpp @@ -98,6 +98,10 @@ void StorageRef::Register(lua_State *L) lua_pushcfunction(L, gc_object); lua_settable(L, metatable); + lua_pushliteral(L, "__eq"); + lua_pushcfunction(L, l_equals); + lua_settable(L, metatable); + lua_pop(L, 1); // drop metatable luaL_openlib(L, 0, methods, 0); // fill methodtable @@ -138,5 +142,6 @@ const luaL_Reg StorageRef::methods[] = { luamethod(MetaDataRef, set_float), luamethod(MetaDataRef, to_table), luamethod(MetaDataRef, from_table), + luamethod(MetaDataRef, equals), {0,0} }; diff --git a/src/wieldmesh.cpp b/src/wieldmesh.cpp index 089a67f33..40af0be5f 100644 --- a/src/wieldmesh.cpp +++ b/src/wieldmesh.cpp @@ -318,11 +318,15 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client) u32 shader_id = shdrsrc->getShader("wielded_shader", TILE_MATERIAL_BASIC, NDT_NORMAL); m_material_type = shdrsrc->getShaderInfo(shader_id).material; } + + // Color-related m_colors.clear(); + video::SColor basecolor = idef->getItemstackColor(item, client); // If wield_image is defined, it overrides everything else if (def.wield_image != "") { setExtruded(def.wield_image, def.wield_scale, tsrc, 1); + m_colors.push_back(basecolor); return; } // Handle nodes @@ -371,7 +375,7 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client) } else { material.setTexture(0, tile->texture); } - m_colors.push_back(tile->color); + m_colors.push_back(tile->has_color ? tile->color : basecolor); material.MaterialType = m_material_type; if (m_enable_shaders) { if (tile->normal_texture) { @@ -389,6 +393,7 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client) } else if (def.inventory_image != "") { setExtruded(def.inventory_image, def.wield_scale, tsrc, 1); + m_colors.push_back(basecolor); return; } @@ -455,7 +460,7 @@ void WieldMeshSceneNode::changeToMesh(scene::IMesh *mesh) m_meshnode->setVisible(true); } -scene::IMesh *getItemMesh(Client *client, const ItemStack &item) +void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) { ITextureSource *tsrc = client->getTextureSource(); IItemDefManager *idef = client->getItemDefManager(); @@ -475,12 +480,13 @@ scene::IMesh *getItemMesh(Client *client, const ItemStack &item) // If inventory_image is defined, it overrides everything else if (def.inventory_image != "") { mesh = getExtrudedMesh(tsrc, def.inventory_image); - return mesh; + result->mesh = mesh; + result->buffer_colors.push_back( + std::pair(false, video::SColor(0xFFFFFFFF))); } else if (def.type == ITEM_NODE) { if (f.mesh_ptr[0]) { mesh = cloneMesh(f.mesh_ptr[0]); scaleMesh(mesh, v3f(0.12, 0.12, 0.12)); - setMeshColor(mesh, video::SColor (255, 255, 255, 255)); } else if (f.drawtype == NDT_PLANTLIKE) { mesh = getExtrudedMesh(tsrc, tsrc->getTextureName(f.tiles[0].texture_id)); @@ -515,6 +521,8 @@ scene::IMesh *getItemMesh(Client *client, const ItemStack &item) for (u32 i = 0; i < mc; ++i) { const TileSpec *tile = &(f.tiles[i]); scene::IMeshBuffer *buf = mesh->getMeshBuffer(i); + result->buffer_colors.push_back( + std::pair(tile->has_color, tile->color)); colorizeMeshBuffer(buf, &tile->color); video::SMaterial &material = buf->getMaterial(); material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; @@ -532,9 +540,8 @@ scene::IMesh *getItemMesh(Client *client, const ItemStack &item) rotateMeshXZby(mesh, -45); rotateMeshYZby(mesh, -30); - return mesh; + result->mesh = mesh; } - return NULL; } scene::IMesh * getExtrudedMesh(ITextureSource *tsrc, diff --git a/src/wieldmesh.h b/src/wieldmesh.h index 200587058..94edb1de6 100644 --- a/src/wieldmesh.h +++ b/src/wieldmesh.h @@ -28,6 +28,22 @@ class Client; class ITextureSource; struct TileSpec; +struct ItemMesh +{ + scene::IMesh* mesh; + /*! + * Stores the color of each mesh buffer. + * If the boolean is true, the color is fixed, else + * palettes can modify it. + */ + std::vector > buffer_colors; + + ItemMesh(): + mesh(NULL), + buffer_colors() + {} +}; + /* Wield item scene node, renders the wield mesh of some item */ @@ -79,7 +95,7 @@ private: aabb3f m_bounding_box; }; -scene::IMesh *getItemMesh(Client *client, const ItemStack &item); +void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result); scene::IMesh *getExtrudedMesh(ITextureSource *tsrc, const std::string &imagename); #endif -- cgit v1.2.3 From a7e131f53e211ffbe38d34d23b33e13cc401f013 Mon Sep 17 00:00:00 2001 From: Loïc Blot Date: Tue, 25 Apr 2017 10:17:53 +0200 Subject: Fix various points reported by cppcheck (#5656) * Fix various performance issues reported by cppcheck + code style (CI) * Make CI happy with code style on master * guiFileSelectMenu: remove useless includes * some performance fixes pointed by cppcheck * remove some useless casts * TextDest: remove unused setFormSpec function * Fix various iterator post-increment reported by cppcheck --- src/game.cpp | 3 ++- src/guiFormSpecMenu.h | 2 +- src/map_settings_manager.cpp | 13 ++++++------- src/nodedef.cpp | 7 +++---- src/script/cpp_api/s_async.cpp | 10 +++++----- src/script/cpp_api/s_node.cpp | 2 +- src/script/lua_api/l_client.cpp | 2 +- src/script/lua_api/l_craft.cpp | 2 +- src/script/lua_api/l_env.cpp | 5 ++--- src/script/lua_api/l_mainmenu.cpp | 2 +- src/script/lua_api/l_nodemeta.cpp | 2 +- src/script/lua_api/l_server.cpp | 4 ++-- src/util/thread.h | 6 +++--- 13 files changed, 29 insertions(+), 31 deletions(-) (limited to 'src/script/lua_api/l_nodemeta.cpp') diff --git a/src/game.cpp b/src/game.cpp index fbc0cf35f..31a48531c 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -202,7 +202,8 @@ public: return meta->getString("formspec"); } - std::string resolveText(std::string str) + + virtual std::string resolveText(const std::string &str) { NodeMetadata *meta = m_map->getNodeMetadata(m_p); diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h index e30565be8..af2d3f45e 100644 --- a/src/guiFormSpecMenu.h +++ b/src/guiFormSpecMenu.h @@ -69,7 +69,7 @@ public: virtual ~IFormSource(){} virtual std::string getForm() = 0; // Fill in variables in field text - virtual std::string resolveText(std::string str){ return str; } + virtual std::string resolveText(const std::string &str) { return str; } }; class GUIFormSpecMenu : public GUIModalMenu diff --git a/src/map_settings_manager.cpp b/src/map_settings_manager.cpp index 53d17125c..52f88778c 100644 --- a/src/map_settings_manager.cpp +++ b/src/map_settings_manager.cpp @@ -25,14 +25,13 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "map_settings_manager.h" -MapSettingsManager::MapSettingsManager( - Settings *user_settings, const std::string &map_meta_path) +MapSettingsManager::MapSettingsManager(Settings *user_settings, + const std::string &map_meta_path): + mapgen_params(NULL), + m_map_meta_path(map_meta_path), + m_map_settings(new Settings()), + m_user_settings(user_settings) { - m_map_meta_path = map_meta_path; - m_user_settings = user_settings; - m_map_settings = new Settings; - mapgen_params = NULL; - assert(m_user_settings != NULL); } diff --git a/src/nodedef.cpp b/src/nodedef.cpp index db28325aa..ce2834c91 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -1318,22 +1318,21 @@ void CNodeDefManager::removeNode(const std::string &name) // Erase node content from all groups it belongs to for (UNORDERED_MAP::iterator iter_groups = - m_group_to_items.begin(); - iter_groups != m_group_to_items.end();) { + m_group_to_items.begin(); iter_groups != m_group_to_items.end();) { GroupItems &items = iter_groups->second; for (GroupItems::iterator iter_groupitems = items.begin(); iter_groupitems != items.end();) { if (iter_groupitems->first == id) items.erase(iter_groupitems++); else - iter_groupitems++; + ++iter_groupitems; } // Check if group is empty if (items.size() == 0) m_group_to_items.erase(iter_groups++); else - iter_groups++; + ++iter_groups; } } diff --git a/src/script/cpp_api/s_async.cpp b/src/script/cpp_api/s_async.cpp index a1bec83bf..080ae887c 100644 --- a/src/script/cpp_api/s_async.cpp +++ b/src/script/cpp_api/s_async.cpp @@ -46,26 +46,26 @@ AsyncEngine::~AsyncEngine() // Request all threads to stop for (std::vector::iterator it = workerThreads.begin(); - it != workerThreads.end(); it++) { + it != workerThreads.end(); ++it) { (*it)->stop(); } // Wake up all threads for (std::vector::iterator it = workerThreads.begin(); - it != workerThreads.end(); it++) { + it != workerThreads.end(); ++it) { jobQueueCounter.post(); } // Wait for threads to finish for (std::vector::iterator it = workerThreads.begin(); - it != workerThreads.end(); it++) { + it != workerThreads.end(); ++it) { (*it)->wait(); } // Force kill all threads for (std::vector::iterator it = workerThreads.begin(); - it != workerThreads.end(); it++) { + it != workerThreads.end(); ++it) { delete *it; } @@ -205,7 +205,7 @@ void AsyncEngine::pushFinishedJobs(lua_State* L) { void AsyncEngine::prepareEnvironment(lua_State* L, int top) { for (UNORDERED_MAP::iterator it = functionList.begin(); - it != functionList.end(); it++) { + it != functionList.end(); ++it) { lua_pushstring(L, it->first.c_str()); lua_pushcfunction(L, it->second); lua_settable(L, top); diff --git a/src/script/cpp_api/s_node.cpp b/src/script/cpp_api/s_node.cpp index 2723f84e1..1ae8f58a5 100644 --- a/src/script/cpp_api/s_node.cpp +++ b/src/script/cpp_api/s_node.cpp @@ -263,7 +263,7 @@ void ScriptApiNode::node_on_receive_fields(v3s16 p, lua_pushstring(L, formname.c_str()); // formname lua_newtable(L); // fields StringMap::const_iterator it; - for (it = fields.begin(); it != fields.end(); it++) { + for (it = fields.begin(); it != fields.end(); ++it) { const std::string &name = it->first; const std::string &value = it->second; lua_pushstring(L, name.c_str()); diff --git a/src/script/lua_api/l_client.cpp b/src/script/lua_api/l_client.cpp index be3a749de..09ea5506b 100644 --- a/src/script/lua_api/l_client.cpp +++ b/src/script/lua_api/l_client.cpp @@ -83,7 +83,7 @@ int ModApiClient::l_get_player_names(lua_State *L) int newTable = lua_gettop(L); int index = 1; std::list::const_iterator iter; - for (iter = plist.begin(); iter != plist.end(); iter++) { + for (iter = plist.begin(); iter != plist.end(); ++iter) { lua_pushstring(L, (*iter).c_str()); lua_rawseti(L, newTable, index); index++; diff --git a/src/script/lua_api/l_craft.cpp b/src/script/lua_api/l_craft.cpp index 2236566de..315391856 100644 --- a/src/script/lua_api/l_craft.cpp +++ b/src/script/lua_api/l_craft.cpp @@ -414,7 +414,7 @@ static void push_craft_recipe(lua_State *L, IGameDef *gdef, lua_newtable(L); // items std::vector::const_iterator iter = input.items.begin(); - for (u16 j = 1; iter != input.items.end(); iter++, j++) { + for (u16 j = 1; iter != input.items.end(); ++iter, j++) { if (iter->empty()) continue; lua_pushstring(L, iter->name.c_str()); diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index 1fa7845b5..75b07fa37 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -534,7 +534,7 @@ int ModApiEnvMod::l_get_objects_inside_radius(lua_State *L) ScriptApiBase *script = getScriptApiBase(L); lua_createtable(L, ids.size(), 0); std::vector::const_iterator iter = ids.begin(); - for(u32 i = 0; iter != ids.end(); iter++) { + for(u32 i = 0; iter != ids.end(); ++iter) { ServerActiveObject *obj = env->getActiveObject(*iter); // Insert object reference into table script->objectrefGetOrCreate(L, obj); @@ -985,8 +985,7 @@ int ModApiEnvMod::l_find_path(lua_State *L) lua_newtable(L); int top = lua_gettop(L); unsigned int index = 1; - for (std::vector::iterator i = path.begin(); i != path.end();i++) - { + for (std::vector::iterator i = path.begin(); i != path.end(); ++i) { lua_pushnumber(L,index); push_v3s16(L, *i); lua_settable(L, top); diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 3d204db98..4d0be257c 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -297,7 +297,7 @@ int ModApiMainMenu::l_get_games(lua_State *L) int table2 = lua_gettop(L); int internal_index=1; for (std::set::iterator iter = games[i].addon_mods_paths.begin(); - iter != games[i].addon_mods_paths.end(); iter++) { + iter != games[i].addon_mods_paths.end(); ++iter) { lua_pushnumber(L,internal_index); lua_pushstring(L,(*iter).c_str()); lua_settable(L, table2); diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp index c65d56f14..6232112c5 100644 --- a/src/script/lua_api/l_nodemeta.cpp +++ b/src/script/lua_api/l_nodemeta.cpp @@ -107,7 +107,7 @@ void NodeMetaRef::handleToTable(lua_State *L, Metadata *_meta) if (inv) { std::vector lists = inv->getLists(); for(std::vector::const_iterator - i = lists.begin(); i != lists.end(); i++) { + i = lists.begin(); i != lists.end(); ++i) { push_inventory_list(L, inv, (*i)->getName().c_str()); lua_setfield(L, -2, (*i)->getName().c_str()); } diff --git a/src/script/lua_api/l_server.cpp b/src/script/lua_api/l_server.cpp index d94f3e31d..813d5a945 100644 --- a/src/script/lua_api/l_server.cpp +++ b/src/script/lua_api/l_server.cpp @@ -103,7 +103,7 @@ int ModApiServer::l_get_player_privs(lua_State *L) int table = lua_gettop(L); std::set privs_s = server->getPlayerEffectivePrivs(name); for(std::set::const_iterator - i = privs_s.begin(); i != privs_s.end(); i++){ + i = privs_s.begin(); i != privs_s.end(); ++i){ lua_pushboolean(L, true); lua_setfield(L, table, i->c_str()); } @@ -417,7 +417,7 @@ int ModApiServer::l_get_modnames(lua_State *L) // Package them up for Lua lua_createtable(L, modlist.size(), 0); std::vector::iterator iter = modlist.begin(); - for (u16 i = 0; iter != modlist.end(); iter++) { + for (u16 i = 0; iter != modlist.end(); ++iter) { lua_pushstring(L, iter->c_str()); lua_rawseti(L, -2, ++i); } diff --git a/src/util/thread.h b/src/util/thread.h index f54b8b48f..b96f302f6 100644 --- a/src/util/thread.h +++ b/src/util/thread.h @@ -83,8 +83,8 @@ public: GetRequest() {} ~GetRequest() {} - GetRequest(Key a_key) { - key = a_key; + GetRequest(const Key &a_key): key(a_key) + { } Key key; @@ -106,7 +106,7 @@ public: return m_queue.empty(); } - void add(Key key, Caller caller, CallerData callerdata, + void add(const Key &key, Caller caller, CallerData callerdata, ResultQueue *dest) { typename std::deque >::iterator i; -- cgit v1.2.3 From 071e114ffa945522a7a9acc3259427166992d5ee Mon Sep 17 00:00:00 2001 From: sfan5 Date: Wed, 10 May 2017 15:29:21 +0200 Subject: Private nodemeta (#5702) * Private node metadata that isn't sent to the client --- doc/lua_api.txt | 4 ++ games/minimal/mods/default/init.lua | 2 + games/minimal/mods/experimental/init.lua | 10 ++++- src/mapblock.cpp | 7 ++-- src/nodemetadata.cpp | 63 +++++++++++++++++++++++++------- src/nodemetadata.h | 16 ++++++-- src/rollback_interface.cpp | 4 +- src/script/lua_api/l_nodemeta.cpp | 27 ++++++++++++++ src/script/lua_api/l_nodemeta.h | 3 ++ src/serialization.h | 5 ++- 10 files changed, 114 insertions(+), 27 deletions(-) (limited to 'src/script/lua_api/l_nodemeta.cpp') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 901dd3c46..a295d7d0e 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2895,6 +2895,10 @@ Can be obtained via `minetest.get_meta(pos)`. #### Methods * All methods in MetaDataRef * `get_inventory()`: returns `InvRef` +* `mark_as_private(name or {name1, name2, ...})`: Mark specific vars as private + This will prevent them from being sent to the client. Note that the "private" + status will only be remembered if an associated key-value pair exists, meaning + it's best to call this when initializing all other meta (e.g. on_construct). ### `ItemStackMetaRef` ItemStack metadata: reference extra data and functionality stored in a stack. diff --git a/games/minimal/mods/default/init.lua b/games/minimal/mods/default/init.lua index 64970f922..7d26f38a0 100644 --- a/games/minimal/mods/default/init.lua +++ b/games/minimal/mods/default/init.lua @@ -1228,6 +1228,8 @@ minetest.register_node("default:chest_locked", { meta:set_string("owner", "") local inv = meta:get_inventory() inv:set_size("main", 8*4) + -- this is not really the intended usage but works for testing purposes: + meta:mark_as_private("owner") end, can_dig = function(pos,player) local meta = minetest.get_meta(pos); diff --git a/games/minimal/mods/experimental/init.lua b/games/minimal/mods/experimental/init.lua index 5e98e1a80..6e0fb1738 100644 --- a/games/minimal/mods/experimental/init.lua +++ b/games/minimal/mods/experimental/init.lua @@ -502,10 +502,16 @@ minetest.register_craftitem("experimental:tester_tool_1", { on_use = function(itemstack, user, pointed_thing) --print(dump(pointed_thing)) if pointed_thing.type == "node" then - if minetest.get_node(pointed_thing.under).name == "experimental:tester_node_1" then + local node = minetest.get_node(pointed_thing.under) + if node.name == "experimental:tester_node_1" or node.name == "default:chest" then local p = pointed_thing.under minetest.log("action", "Tester tool used at "..minetest.pos_to_string(p)) - minetest.dig_node(p) + if node.name == "experimental:tester_node_1" then + minetest.dig_node(p) + else + minetest.get_meta(p):mark_as_private({"infotext", "formspec"}) + minetest.chat_send_player(user:get_player_name(), "Verify that chest is unusable now.") + end else local p = pointed_thing.above minetest.log("action", "Tester tool used at "..minetest.pos_to_string(p)) diff --git a/src/mapblock.cpp b/src/mapblock.cpp index 1a0b01f2b..ec10a49bb 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -611,7 +611,7 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk) Node metadata */ std::ostringstream oss(std::ios_base::binary); - m_node_metadata.serialize(oss); + m_node_metadata.serialize(oss, version, disk); compressZlib(oss.str(), os); /* @@ -669,11 +669,10 @@ void MapBlock::deSerialize(std::istream &is, u8 version, bool disk) u8 flags = readU8(is); is_underground = (flags & 0x01) ? true : false; m_day_night_differs = (flags & 0x02) ? true : false; - if (version < 27) { + if (version < 27) m_lighting_complete = 0xFFFF; - } else { + else m_lighting_complete = readU16(is); - } m_generated = (flags & 0x08) ? false : true; /* diff --git a/src/nodemetadata.cpp b/src/nodemetadata.cpp index 9b60cf33e..0e8195c34 100644 --- a/src/nodemetadata.cpp +++ b/src/nodemetadata.cpp @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "inventory.h" #include "log.h" #include "util/serialize.h" +#include "util/basic_macros.h" #include "constants.h" // MAP_BLOCKSIZE #include @@ -39,28 +40,38 @@ NodeMetadata::~NodeMetadata() delete m_inventory; } -void NodeMetadata::serialize(std::ostream &os) const +void NodeMetadata::serialize(std::ostream &os, u8 version, bool disk) const { - int num_vars = m_stringvars.size(); + int num_vars = disk ? m_stringvars.size() : countNonPrivate(); writeU32(os, num_vars); for (StringMap::const_iterator it = m_stringvars.begin(); it != m_stringvars.end(); ++it) { + bool priv = isPrivate(it->first); + if (!disk && priv) + continue; + os << serializeString(it->first); os << serializeLongString(it->second); + if (version >= 2) + writeU8(os, (priv) ? 1 : 0); } m_inventory->serialize(os); } -void NodeMetadata::deSerialize(std::istream &is) +void NodeMetadata::deSerialize(std::istream &is, u8 version) { - m_stringvars.clear(); + clear(); int num_vars = readU32(is); for(int i=0; i= 2) { + if (readU8(is) == 1) + markPrivate(name, true); + } } m_inventory->deSerialize(is); @@ -69,6 +80,7 @@ void NodeMetadata::deSerialize(std::istream &is) void NodeMetadata::clear() { Metadata::clear(); + m_privatevars.clear(); m_inventory->clear(); } @@ -77,11 +89,34 @@ bool NodeMetadata::empty() const return Metadata::empty() && m_inventory->getLists().size() == 0; } + +void NodeMetadata::markPrivate(const std::string &name, bool set) +{ + if (set) + m_privatevars.insert(name); + else + m_privatevars.erase(name); +} + +int NodeMetadata::countNonPrivate() const +{ + // m_privatevars can contain names not actually present + // DON'T: return m_stringvars.size() - m_privatevars.size(); + int n = 0; + for (StringMap::const_iterator + it = m_stringvars.begin(); + it != m_stringvars.end(); ++it) { + if (isPrivate(it->first) == false) + n++; + } + return n; +} + /* NodeMetadataList */ -void NodeMetadataList::serialize(std::ostream &os) const +void NodeMetadataList::serialize(std::ostream &os, u8 blockver, bool disk) const { /* Version 0 is a placeholder for "nothing to see here; go away." @@ -93,7 +128,8 @@ void NodeMetadataList::serialize(std::ostream &os) const return; } - writeU8(os, 1); // version + u8 version = (blockver > 27) ? 2 : 1; + writeU8(os, version); writeU16(os, count); for(std::map::const_iterator @@ -108,7 +144,7 @@ void NodeMetadataList::serialize(std::ostream &os) const u16 p16 = p.Z * MAP_BLOCKSIZE * MAP_BLOCKSIZE + p.Y * MAP_BLOCKSIZE + p.X; writeU16(os, p16); - data->serialize(os); + data->serialize(os, version, disk); } } @@ -123,7 +159,7 @@ void NodeMetadataList::deSerialize(std::istream &is, IItemDefManager *item_def_m return; } - if (version != 1) { + if (version > 2) { std::string err_str = std::string(FUNCTION_NAME) + ": version " + itos(version) + " not supported"; infostream << err_str << std::endl; @@ -132,7 +168,7 @@ void NodeMetadataList::deSerialize(std::istream &is, IItemDefManager *item_def_m u16 count = readU16(is); - for (u16 i=0; i < count; i++) { + for (u16 i = 0; i < count; i++) { u16 p16 = readU16(is); v3s16 p; @@ -143,15 +179,14 @@ void NodeMetadataList::deSerialize(std::istream &is, IItemDefManager *item_def_m p.X = p16; if (m_data.find(p) != m_data.end()) { - warningstream<<"NodeMetadataList::deSerialize(): " - <<"already set data at position" - <<"("<deSerialize(is); + data->deSerialize(is, version); m_data[p] = data; } } diff --git a/src/nodemetadata.h b/src/nodemetadata.h index f46c0fe91..0d72485bc 100644 --- a/src/nodemetadata.h +++ b/src/nodemetadata.h @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #define NODEMETADATA_HEADER #include "metadata.h" +#include "util/cpp11_container.h" /* NodeMetadata stores arbitary amounts of data for special blocks. @@ -40,8 +41,8 @@ public: NodeMetadata(IItemDefManager *item_def_mgr); ~NodeMetadata(); - void serialize(std::ostream &os) const; - void deSerialize(std::istream &is); + void serialize(std::ostream &os, u8 version, bool disk=true) const; + void deSerialize(std::istream &is, u8 version); void clear(); bool empty() const; @@ -52,8 +53,17 @@ public: return m_inventory; } + inline bool isPrivate(const std::string &name) const + { + return m_privatevars.count(name) != 0; + } + void markPrivate(const std::string &name, bool set); + private: + int countNonPrivate() const; + Inventory *m_inventory; + UNORDERED_SET m_privatevars; }; @@ -66,7 +76,7 @@ class NodeMetadataList public: ~NodeMetadataList(); - void serialize(std::ostream &os) const; + void serialize(std::ostream &os, u8 blockver, bool disk=true) const; void deSerialize(std::istream &is, IItemDefManager *item_def_mgr); // Add all keys in this list to the vector keys diff --git a/src/rollback_interface.cpp b/src/rollback_interface.cpp index 40a33a51d..d02d1cb3e 100644 --- a/src/rollback_interface.cpp +++ b/src/rollback_interface.cpp @@ -44,7 +44,7 @@ RollbackNode::RollbackNode(Map *map, v3s16 p, IGameDef *gamedef) NodeMetadata *metap = map->getNodeMetadata(p); if (metap) { std::ostringstream os(std::ios::binary); - metap->serialize(os); + metap->serialize(os, 1); // FIXME: version bump?? meta = os.str(); } } @@ -165,7 +165,7 @@ bool RollbackAction::applyRevert(Map *map, InventoryManager *imgr, IGameDef *gam } } std::istringstream is(n_old.meta, std::ios::binary); - meta->deSerialize(is); + meta->deSerialize(is, 1); // FIXME: version bump?? } // Inform other things that the meta data has changed v3s16 blockpos = getContainerPos(p, MAP_BLOCKSIZE); diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp index 6232112c5..5dfa6d52e 100644 --- a/src/script/lua_api/l_nodemeta.cpp +++ b/src/script/lua_api/l_nodemeta.cpp @@ -94,6 +94,32 @@ int NodeMetaRef::l_get_inventory(lua_State *L) return 1; } +// mark_as_private(self, or {, , ...}) +int NodeMetaRef::l_mark_as_private(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + NodeMetaRef *ref = checkobject(L, 1); + NodeMetadata *meta = dynamic_cast(ref->getmeta(true)); + assert(meta); + + if (lua_istable(L, 2)) { + lua_pushnil(L); + while (lua_next(L, 2) != 0) { + // key at index -2 and value at index -1 + luaL_checktype(L, -1, LUA_TSTRING); + meta->markPrivate(lua_tostring(L, -1), true); + // removes value, keeps key for next iteration + lua_pop(L, 1); + } + } else if (lua_isstring(L, 2)) { + meta->markPrivate(lua_tostring(L, 2), true); + } + ref->reportMetadataChange(); + + return 0; +} + void NodeMetaRef::handleToTable(lua_State *L, Metadata *_meta) { // fields @@ -229,6 +255,7 @@ const luaL_Reg NodeMetaRef::methodsServer[] = { luamethod(MetaDataRef, to_table), luamethod(MetaDataRef, from_table), luamethod(NodeMetaRef, get_inventory), + luamethod(NodeMetaRef, mark_as_private), luamethod(MetaDataRef, equals), {0,0} }; diff --git a/src/script/lua_api/l_nodemeta.h b/src/script/lua_api/l_nodemeta.h index 2ac028079..dd4260ff9 100644 --- a/src/script/lua_api/l_nodemeta.h +++ b/src/script/lua_api/l_nodemeta.h @@ -73,6 +73,9 @@ private: // get_inventory(self) static int l_get_inventory(lua_State *L); + // mark_as_private(self, or {, , ...}) + static int l_mark_as_private(lua_State *L); + public: NodeMetaRef(v3s16 p, ServerEnvironment *env); NodeMetaRef(Metadata *meta); diff --git a/src/serialization.h b/src/serialization.h index 52c63098e..c91c3241f 100644 --- a/src/serialization.h +++ b/src/serialization.h @@ -63,13 +63,14 @@ with this program; if not, write to the Free Software Foundation, Inc., 25: Improved node timer format 26: Never written; read the same as 25 27: Added light spreading flags to blocks + 28: Added "private" flag to NodeMetadata */ // This represents an uninitialized or invalid format #define SER_FMT_VER_INVALID 255 // Highest supported serialization version -#define SER_FMT_VER_HIGHEST_READ 27 +#define SER_FMT_VER_HIGHEST_READ 28 // Saved on disk version -#define SER_FMT_VER_HIGHEST_WRITE 27 +#define SER_FMT_VER_HIGHEST_WRITE 28 // Lowest supported serialization version #define SER_FMT_VER_LOWEST_READ 0 // Lowest serialization version for writing -- cgit v1.2.3