From 6a76c226e10e92c3e3339096f07f8ab065e2098b Mon Sep 17 00:00:00 2001 From: Kahrl Date: Thu, 12 Jan 2012 06:10:39 +0100 Subject: The huge item definition and item namespace unification patch (itemdef), see http://c55.me/minetest/wiki/doku.php?id=changes:itemdef --- src/itemdef.cpp | 502 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 502 insertions(+) create mode 100644 src/itemdef.cpp (limited to 'src/itemdef.cpp') diff --git a/src/itemdef.cpp b/src/itemdef.cpp new file mode 100644 index 000000000..aa888bbdf --- /dev/null +++ b/src/itemdef.cpp @@ -0,0 +1,502 @@ +/* +Minetest-c55 +Copyright (C) 2010-2011 celeron55, Perttu Ahola +Copyright (C) 2011 Kahrl + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 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 General Public License for more details. + +You should have received a copy of the GNU 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 "itemdef.h" + +#include "gamedef.h" +#include "nodedef.h" +#include "materials.h" +#include "inventory.h" +#ifndef SERVER +#include "mapblock_mesh.h" +#include "mesh.h" +#include "tile.h" +#endif +#include "log.h" +#include "utility.h" +#include +#include + +/* + ItemDefinition +*/ +ItemDefinition::ItemDefinition() +{ + resetInitial(); +} + +ItemDefinition::ItemDefinition(const ItemDefinition &def) +{ + resetInitial(); + *this = def; +} + +ItemDefinition& ItemDefinition::operator=(const ItemDefinition &def) +{ + if(this == &def) + return *this; + + reset(); + + type = def.type; + name = def.name; + description = def.description; + inventory_image = def.inventory_image; + wield_image = def.wield_image; + wield_scale = def.wield_scale; + stack_max = def.stack_max; + usable = def.usable; + liquids_pointable = def.liquids_pointable; + if(def.tool_digging_properties) + { + tool_digging_properties = new ToolDiggingProperties( + *def.tool_digging_properties); + } +#ifndef SERVER + inventory_texture = def.inventory_texture; + if(def.wield_mesh) + { + wield_mesh = def.wield_mesh; + wield_mesh->grab(); + } +#endif + return *this; +} + +ItemDefinition::~ItemDefinition() +{ + reset(); +} + +void ItemDefinition::resetInitial() +{ + // Initialize pointers to NULL so reset() does not delete undefined pointers + tool_digging_properties = NULL; +#ifndef SERVER + inventory_texture = NULL; + wield_mesh = NULL; +#endif + reset(); +} + +void ItemDefinition::reset() +{ + type = ITEM_NONE; + name = ""; + description = ""; + inventory_image = ""; + wield_image = ""; + wield_scale = v3f(1.0, 1.0, 1.0); + stack_max = 99; + usable = false; + liquids_pointable = false; + if(tool_digging_properties) + { + delete tool_digging_properties; + tool_digging_properties = NULL; + } + +#ifndef SERVER + inventory_texture = NULL; + if(wield_mesh) + { + wield_mesh->drop(); + wield_mesh = NULL; + } +#endif +} + +void ItemDefinition::serialize(std::ostream &os) const +{ + writeU8(os, 0); // version + writeU8(os, type); + os<serialize(tmp_os); + tool_digging_properties_s = tmp_os.str(); + } + os<deSerialize(tmp_is); + } +} + +/* + CItemDefManager +*/ + +// SUGG: Support chains of aliases? + +class CItemDefManager: public IWritableItemDefManager +{ +public: + CItemDefManager() + { + clear(); + } + virtual ~CItemDefManager() + { + } + virtual const ItemDefinition& get(const std::string &name_) const + { + // Convert name according to possible alias + std::string name = getAlias(name_); + // Get the definition + std::map::const_iterator i; + i = m_item_definitions.find(name); + if(i == m_item_definitions.end()) + i = m_item_definitions.find("unknown"); + assert(i != m_item_definitions.end()); + return *(i->second); + } + virtual std::string getAlias(const std::string &name) const + { + std::map::const_iterator i; + i = m_aliases.find(name); + if(i != m_aliases.end()) + return i->second; + return name; + } + virtual std::set getAll() const + { + std::set result; + for(std::map::const_iterator + i = m_item_definitions.begin(); + i != m_item_definitions.end(); i++) + { + result.insert(i->first); + } + for(std::map::const_iterator + i = m_aliases.begin(); + i != m_aliases.end(); i++) + { + result.insert(i->first); + } + return result; + } + virtual bool isKnown(const std::string &name_) const + { + // Convert name according to possible alias + std::string name = getAlias(name_); + // Get the definition + std::map::const_iterator i; + return m_item_definitions.find(name) != m_item_definitions.end(); + } + void clear() + { + for(std::map::const_iterator + i = m_item_definitions.begin(); + i != m_item_definitions.end(); i++) + { + delete i->second; + } + m_item_definitions.clear(); + m_aliases.clear(); + + // Add the four builtin items: + // "" is the hand + // "unknown" is returned whenever an undefined item is accessed + // "air" is the air node + // "ignore" is the ignore node + + ItemDefinition* hand_def = new ItemDefinition; + hand_def->name = ""; + hand_def->wield_image = "wieldhand.png"; + hand_def->tool_digging_properties = new ToolDiggingProperties; + m_item_definitions.insert(std::make_pair("", hand_def)); + + ItemDefinition* unknown_def = new ItemDefinition; + unknown_def->name = "unknown"; + m_item_definitions.insert(std::make_pair("unknown", unknown_def)); + + ItemDefinition* air_def = new ItemDefinition; + air_def->type = ITEM_NODE; + air_def->name = "air"; + m_item_definitions.insert(std::make_pair("air", air_def)); + + ItemDefinition* ignore_def = new ItemDefinition; + ignore_def->type = ITEM_NODE; + ignore_def->name = "ignore"; + m_item_definitions.insert(std::make_pair("ignore", ignore_def)); + } + virtual void registerItem(const ItemDefinition &def) + { + infostream<<"ItemDefManager: registering \""< "<getTextureSource(); + INodeDefManager *nodedef = gamedef->getNodeDefManager(); + IrrlichtDevice *device = tsrc->getDevice(); + video::IVideoDriver *driver = device->getVideoDriver(); + + for(std::map::iterator + i = m_item_definitions.begin(); + i != m_item_definitions.end(); i++) + { + ItemDefinition *def = i->second; + + bool need_node_mesh = false; + + // Create an inventory texture + def->inventory_texture = NULL; + if(def->inventory_image != "") + { + def->inventory_texture = tsrc->getTextureRaw(def->inventory_image); + } + else if(def->type == ITEM_NODE) + { + need_node_mesh = true; + } + + // Create a wield mesh + if(def->wield_mesh != NULL) + { + def->wield_mesh->drop(); + def->wield_mesh = NULL; + } + if(def->type == ITEM_NODE && def->wield_image == "") + { + need_node_mesh = true; + } + else if(def->wield_image != "" || def->inventory_image != "") + { + // Extrude the wield image into a mesh + + std::string imagename; + if(def->wield_image != "") + imagename = def->wield_image; + else + imagename = def->inventory_image; + + def->wield_mesh = createExtrudedMesh( + tsrc->getTextureRaw(imagename), + driver, + def->wield_scale * v3f(40.0, 40.0, 4.0)); + if(def->wield_mesh == NULL) + { + infostream<<"ItemDefManager: WARNING: " + <<"updateTexturesAndMeshes(): " + <<"Unable to create extruded mesh for item " + <name<getId(def->name); + const ContentFeatures &f = nodedef->get(id); + + /* + Make a mesh from the node + */ + MeshMakeData mesh_make_data; + MapNode mesh_make_node( + id, + (f.param_type == CPT_LIGHT) ? 0xee : 0, + 0); + mesh_make_data.fillSingleNode(1000, &mesh_make_node); + scene::IMesh *node_mesh = + makeMapBlockMesh(&mesh_make_data, gamedef); + setMeshColor(node_mesh, video::SColor(255, 255, 255, 255)); + + /* + Scale and translate the mesh so it's a unit cube + centered on the origin + */ + scaleMesh(node_mesh, v3f(1.0/BS, 1.0/BS, 1.0/BS)); + translateMesh(node_mesh, v3f(-1.0, -1.0, -1.0)); + + /* + Draw node mesh into a render target texture + */ + if(def->inventory_texture == NULL && node_mesh != NULL) + { + core::dimension2d dim(64,64); + std::string rtt_texture_name = "INVENTORY_" + + def->name + "_RTT"; + v3f camera_position(0, 1.0, -1.5); + camera_position.rotateXZBy(45); + v3f camera_lookat(0, 0, 0); + core::CMatrix4 camera_projection_matrix; + // Set orthogonal projection + camera_projection_matrix.buildProjectionMatrixOrthoLH( + 1.65, 1.65, 0, 100); + + video::SColorf ambient_light(0.2,0.2,0.2); + v3f light_position(10, 100, -50); + video::SColorf light_color(0.5,0.5,0.5); + f32 light_radius = 1000; + + def->inventory_texture = generateTextureFromMesh( + node_mesh, device, dim, rtt_texture_name, + camera_position, + camera_lookat, + camera_projection_matrix, + ambient_light, + light_position, + light_color, + light_radius); + // Note: might have returned NULL + } + + /* + Use the node mesh as the wield mesh + */ + if(def->wield_mesh == NULL && node_mesh != NULL) + { + // Scale to proper wield mesh proportions + scaleMesh(node_mesh, v3f(30.0, 30.0, 30.0) + * def->wield_scale); + def->wield_mesh = node_mesh; + def->wield_mesh->grab(); + } + + + if(node_mesh != NULL) + node_mesh->drop(); + } + } +#endif + } + void serialize(std::ostream &os) + { + writeU8(os, 0); // version + u16 count = m_item_definitions.size(); + writeU16(os, count); + for(std::map::const_iterator + i = m_item_definitions.begin(); + i != m_item_definitions.end(); i++) + { + ItemDefinition *def = i->second; + // Serialize ItemDefinition and write wrapped in a string + std::ostringstream tmp_os(std::ios::binary); + def->serialize(tmp_os); + os<::const_iterator + i = m_aliases.begin(); i != m_aliases.end(); i++) + { + os<first); + os<second); + } + } + void deSerialize(std::istream &is) + { + // Clear everything + clear(); + // Deserialize + int version = readU8(is); + if(version != 0) + throw SerializationError("unsupported ItemDefManager version"); + u16 count = readU16(is); + for(u16 i=0; i m_item_definitions; + // Aliases + std::map m_aliases; +}; + +IWritableItemDefManager* createItemDefManager() +{ + return new CItemDefManager(); +} + -- cgit v1.2.3