Skip to content

Commit

Permalink
Add minetest.unregister_item and minetest.register_alias_force
Browse files Browse the repository at this point in the history
  • Loading branch information
paly2 authored and kwolekr committed Sep 8, 2016
1 parent 7eacdc7 commit aa33166
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 3 deletions.
38 changes: 38 additions & 0 deletions builtin/game/register.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
local register_item_raw = core.register_item_raw
core.register_item_raw = nil

local unregister_item_raw = core.unregister_item_raw
core.unregister_item_raw = nil

local register_alias_raw = core.register_alias_raw
core.register_alias_raw = nil

Expand Down Expand Up @@ -172,6 +175,27 @@ function core.register_item(name, itemdef)
register_item_raw(itemdef)
end

function core.unregister_item(name)
if not core.registered_items[name] then
core.log("warning", "Not unregistering item " ..name..
" because it doesn't exist.")
return
end
-- Erase from registered_* table
local type = core.registered_items[name].type
if type == "node" then
core.registered_nodes[name] = nil
elseif type == "craft" then
core.registered_craftitems[name] = nil
elseif type == "tool" then
core.registered_tools[name] = nil
end
core.registered_items[name] = nil


unregister_item_raw(name)
end

function core.register_node(name, nodedef)
nodedef.type = "node"
core.register_item(name, nodedef)
Expand Down Expand Up @@ -242,6 +266,20 @@ function core.register_alias(name, convert_to)
end
end

function core.register_alias_force(name, convert_to)
if forbidden_item_names[name] then
error("Unable to register alias: Name is forbidden: " .. name)
end
if core.registered_items[name] ~= nil then
core.unregister_item(name)
core.log("info", "Removed item " ..name..
" while attempting to force add an alias")
end
--core.log("Registering alias: " .. name .. " -> " .. convert_to)
core.registered_aliases[name] = convert_to
register_alias_raw(name, convert_to)
end

function core.on_craft(itemstack, player, old_craft_list, craft_inv)
for _, func in ipairs(core.registered_on_crafts) do
itemstack = func(itemstack, player, old_craft_list, craft_inv) or itemstack
Expand Down
15 changes: 14 additions & 1 deletion doc/lua_api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,17 @@ when registering it.
The `:` prefix can also be used for maintaining backwards compatibility.

### Aliases
Aliases can be added by using `minetest.register_alias(name, convert_to)`.
Aliases can be added by using `minetest.register_alias(name, convert_to)` or
`minetest.register_alias_force(name, convert_to).

This will make Minetest to convert things called name to things called
`convert_to`.

The only difference between `minetest.register_alias` and
`minetest.register_alias_force` is that if an item called `name` exists,
`minetest.register_alias` will do nothing while
`minetest.register_alias_force` will unregister it.

This can be used for maintaining backwards compatibility.

This can be also used for setting quick access names for things, e.g. if
Expand Down Expand Up @@ -464,6 +470,11 @@ the global `minetest.registered_*` tables.
* `minetest.register_craftitem(name, item definition)`
* added to `minetest.registered_items[name]`

* `minetest.unregister_item(name)`
* Unregisters the item name from engine, and deletes the entry with key
* `name` from `minetest.registered_items` and from the associated item
* table according to its nature: minetest.registered_nodes[] etc

* `minetest.register_biome(biome definition)`
* returns an integer uniquely identifying the registered biome
* added to `minetest.registered_biome` with the key of `biome.name`
Expand Down Expand Up @@ -1883,7 +1894,9 @@ Call these functions only at load time!
* `minetest.register_node(name, node definition)`
* `minetest.register_tool(name, item definition)`
* `minetest.register_craftitem(name, item definition)`
* `minetest.unregister_item(name)`
* `minetest.register_alias(name, convert_to)`
* `minetest.register_alias_force(name, convert_to)`
* `minetest.register_craft(recipe)`
* Check recipe table syntax for different types below.
* `minetest.clear_craft(recipe)`
Expand Down
10 changes: 8 additions & 2 deletions src/itemdef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,11 +466,17 @@ class CItemDefManager: public IWritableItemDefManager
infostream<<"ItemDefManager: erased alias "<<def.name
<<" because item was defined"<<std::endl;
}
virtual void unregisterItem(const std::string &name)
{
verbosestream<<"ItemDefManager: unregistering \""<<name<<"\""<<std::endl;

delete m_item_definitions[name];
m_item_definitions.erase(name);
}
virtual void registerAlias(const std::string &name,
const std::string &convert_to)
{
if(m_item_definitions.find(name) == m_item_definitions.end())
{
if (m_item_definitions.find(name) == m_item_definitions.end()) {
verbosestream<<"ItemDefManager: setting alias "<<name
<<" -> "<<convert_to<<std::endl;
m_aliases[name] = convert_to;
Expand Down
1 change: 1 addition & 0 deletions src/itemdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ class IWritableItemDefManager : public IItemDefManager
virtual void clear()=0;
// Register item definition
virtual void registerItem(const ItemDefinition &def)=0;
virtual void unregisterItem(const std::string &name)=0;
// Set an alias so that items named <name> will load as <convert_to>.
// Alias is not set if <name> has already been defined.
// Alias will be removed if <name> is defined at a later point of time.
Expand Down
35 changes: 35 additions & 0 deletions src/nodedef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,7 @@ class CNodeDefManager: public IWritableNodeDefManager {
content_t allocateId();
virtual content_t set(const std::string &name, const ContentFeatures &def);
virtual content_t allocateDummy(const std::string &name);
virtual void removeNode(const std::string &name);
virtual void updateAliases(IItemDefManager *idef);
virtual void applyTextureOverrides(const std::string &override_filepath);
virtual void updateTextures(IGameDef *gamedef,
Expand Down Expand Up @@ -1072,6 +1073,40 @@ content_t CNodeDefManager::allocateDummy(const std::string &name)
}


void CNodeDefManager::removeNode(const std::string &name)
{
// Pre-condition
assert(name != "");

// Erase name from name ID mapping
content_t id = CONTENT_IGNORE;
if (m_name_id_mapping.getId(name, id)) {
m_name_id_mapping.eraseName(name);
m_name_id_mapping_with_aliases.erase(name);
}

// Erase node content from all groups it belongs to
for (std::map<std::string, GroupItems>::iterator iter_groups =
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++;
}

// Check if group is empty
if (items.size() == 0)
m_group_to_items.erase(iter_groups++);
else
iter_groups++;
}
}


void CNodeDefManager::updateAliases(IItemDefManager *idef)
{
std::set<std::string> all = idef->getAll();
Expand Down
2 changes: 2 additions & 0 deletions src/nodedef.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,8 @@ class IWritableNodeDefManager : public INodeDefManager {
const ContentFeatures &def)=0;
// If returns CONTENT_IGNORE, could not allocate id
virtual content_t allocateDummy(const std::string &name)=0;
// Remove a node
virtual void removeNode(const std::string &name)=0;

/*
Update item alias mapping.
Expand Down
22 changes: 22 additions & 0 deletions src/script/lua_api/l_item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,27 @@ int ModApiItemMod::l_register_item_raw(lua_State *L)
return 0; /* number of results */
}

// unregister_item(name)
int ModApiItemMod::l_unregister_item_raw(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
std::string name = luaL_checkstring(L, 1);

IWritableItemDefManager *idef =
getServer(L)->getWritableItemDefManager();

// Unregister the node
if (idef->get(name).type == ITEM_NODE) {
IWritableNodeDefManager *ndef =
getServer(L)->getWritableNodeDefManager();
ndef->removeNode(name);
}

idef->unregisterItem(name);

return 0; /* number of results */
}

// register_alias_raw(name, convert_to_name)
int ModApiItemMod::l_register_alias_raw(lua_State *L)
{
Expand Down Expand Up @@ -570,6 +591,7 @@ int ModApiItemMod::l_get_name_from_content_id(lua_State *L)
void ModApiItemMod::Initialize(lua_State *L, int top)
{
API_FCT(register_item_raw);
API_FCT(unregister_item_raw);
API_FCT(register_alias_raw);
API_FCT(get_content_id);
API_FCT(get_name_from_content_id);
Expand Down
1 change: 1 addition & 0 deletions src/script/lua_api/l_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ class LuaItemStack : public ModApiBase {
class ModApiItemMod : public ModApiBase {
private:
static int l_register_item_raw(lua_State *L);
static int l_unregister_item_raw(lua_State *L);
static int l_register_alias_raw(lua_State *L);
static int l_get_content_id(lua_State *L);
static int l_get_name_from_content_id(lua_State *L);
Expand Down

0 comments on commit aa33166

Please sign in to comment.