forked from Mirrorlandia_minetest/minetest
Clear old item groups when they are overridden. (#8753)
This fixes overridden items keeping their old groups in the group to items mapping even after their groups have been changed in lua. It also prevents a more widespread issue where overriding an item will add its content ID *twice* to the mapping, resulting in odd behaviour in features such as ABMs.
This commit is contained in:
parent
91114b562f
commit
2f879e8bbd
@ -1202,6 +1202,26 @@ inline void NodeDefManager::fixSelectionBoxIntUnion()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NodeDefManager::eraseIdFromGroups(content_t id)
|
||||||
|
{
|
||||||
|
// For all groups in m_group_to_items...
|
||||||
|
for (auto iter_groups = m_group_to_items.begin();
|
||||||
|
iter_groups != m_group_to_items.end();) {
|
||||||
|
// Get the group items vector.
|
||||||
|
std::vector<content_t> &items = iter_groups->second;
|
||||||
|
|
||||||
|
// Remove any occurence of the id in the group items vector.
|
||||||
|
items.erase(std::remove(items.begin(), items.end(), id), items.end());
|
||||||
|
|
||||||
|
// If group is empty, erase its vector from the map.
|
||||||
|
if (items.empty())
|
||||||
|
iter_groups = m_group_to_items.erase(iter_groups);
|
||||||
|
else
|
||||||
|
++iter_groups;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// IWritableNodeDefManager
|
// IWritableNodeDefManager
|
||||||
content_t NodeDefManager::set(const std::string &name, const ContentFeatures &def)
|
content_t NodeDefManager::set(const std::string &name, const ContentFeatures &def)
|
||||||
{
|
{
|
||||||
@ -1222,19 +1242,24 @@ content_t NodeDefManager::set(const std::string &name, const ContentFeatures &de
|
|||||||
assert(id != CONTENT_IGNORE);
|
assert(id != CONTENT_IGNORE);
|
||||||
addNameIdMapping(id, name);
|
addNameIdMapping(id, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there is already ContentFeatures registered for this id, clear old groups
|
||||||
|
if (id < m_content_features.size())
|
||||||
|
eraseIdFromGroups(id);
|
||||||
|
|
||||||
m_content_features[id] = def;
|
m_content_features[id] = def;
|
||||||
verbosestream << "NodeDefManager: registering content id \"" << id
|
verbosestream << "NodeDefManager: registering content id \"" << id
|
||||||
<< "\": name=\"" << def.name << "\""<<std::endl;
|
<< "\": name=\"" << def.name << "\""<<std::endl;
|
||||||
|
|
||||||
getNodeBoxUnion(def.selection_box, def, &m_selection_box_union);
|
getNodeBoxUnion(def.selection_box, def, &m_selection_box_union);
|
||||||
fixSelectionBoxIntUnion();
|
fixSelectionBoxIntUnion();
|
||||||
|
|
||||||
// Add this content to the list of all groups it belongs to
|
// Add this content to the list of all groups it belongs to
|
||||||
// FIXME: This should remove a node from groups it no longer
|
|
||||||
// belongs to when a node is re-registered
|
|
||||||
for (const auto &group : def.groups) {
|
for (const auto &group : def.groups) {
|
||||||
const std::string &group_name = group.first;
|
const std::string &group_name = group.first;
|
||||||
m_group_to_items[group_name].push_back(id);
|
m_group_to_items[group_name].push_back(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1260,18 +1285,7 @@ void NodeDefManager::removeNode(const std::string &name)
|
|||||||
m_name_id_mapping_with_aliases.erase(name);
|
m_name_id_mapping_with_aliases.erase(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Erase node content from all groups it belongs to
|
eraseIdFromGroups(id);
|
||||||
for (std::unordered_map<std::string, std::vector<content_t>>::iterator iter_groups =
|
|
||||||
m_group_to_items.begin(); iter_groups != m_group_to_items.end();) {
|
|
||||||
std::vector<content_t> &items = iter_groups->second;
|
|
||||||
items.erase(std::remove(items.begin(), items.end(), id), items.end());
|
|
||||||
|
|
||||||
// Check if group is empty
|
|
||||||
if (items.empty())
|
|
||||||
m_group_to_items.erase(iter_groups++);
|
|
||||||
else
|
|
||||||
++iter_groups;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -668,6 +668,14 @@ private:
|
|||||||
*/
|
*/
|
||||||
void addNameIdMapping(content_t i, std::string name);
|
void addNameIdMapping(content_t i, std::string name);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Removes a content ID from all groups.
|
||||||
|
* Erases content IDs from vectors in \ref m_group_to_items and
|
||||||
|
* removes empty vectors.
|
||||||
|
* @param id Content ID
|
||||||
|
*/
|
||||||
|
void eraseIdFromGroups(content_t id);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Recalculates m_selection_box_int_union based on
|
* Recalculates m_selection_box_int_union based on
|
||||||
* m_selection_box_union.
|
* m_selection_box_union.
|
||||||
|
Loading…
Reference in New Issue
Block a user