Skip to content

Commit 2f879e8

Browse files
linewriter1024sfan5
authored andcommittedAug 12, 2019
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.
1 parent 91114b5 commit 2f879e8

File tree

2 files changed

+36
-14
lines changed

2 files changed

+36
-14
lines changed
 

‎src/nodedef.cpp

+28-14
Original file line numberDiff line numberDiff line change
@@ -1202,6 +1202,26 @@ inline void NodeDefManager::fixSelectionBoxIntUnion()
12021202
}
12031203

12041204

1205+
void NodeDefManager::eraseIdFromGroups(content_t id)
1206+
{
1207+
// For all groups in m_group_to_items...
1208+
for (auto iter_groups = m_group_to_items.begin();
1209+
iter_groups != m_group_to_items.end();) {
1210+
// Get the group items vector.
1211+
std::vector<content_t> &items = iter_groups->second;
1212+
1213+
// Remove any occurence of the id in the group items vector.
1214+
items.erase(std::remove(items.begin(), items.end(), id), items.end());
1215+
1216+
// If group is empty, erase its vector from the map.
1217+
if (items.empty())
1218+
iter_groups = m_group_to_items.erase(iter_groups);
1219+
else
1220+
++iter_groups;
1221+
}
1222+
}
1223+
1224+
12051225
// IWritableNodeDefManager
12061226
content_t NodeDefManager::set(const std::string &name, const ContentFeatures &def)
12071227
{
@@ -1222,19 +1242,24 @@ content_t NodeDefManager::set(const std::string &name, const ContentFeatures &de
12221242
assert(id != CONTENT_IGNORE);
12231243
addNameIdMapping(id, name);
12241244
}
1245+
1246+
// If there is already ContentFeatures registered for this id, clear old groups
1247+
if (id < m_content_features.size())
1248+
eraseIdFromGroups(id);
1249+
12251250
m_content_features[id] = def;
12261251
verbosestream << "NodeDefManager: registering content id \"" << id
12271252
<< "\": name=\"" << def.name << "\""<<std::endl;
12281253

12291254
getNodeBoxUnion(def.selection_box, def, &m_selection_box_union);
12301255
fixSelectionBoxIntUnion();
1256+
12311257
// Add this content to the list of all groups it belongs to
1232-
// FIXME: This should remove a node from groups it no longer
1233-
// belongs to when a node is re-registered
12341258
for (const auto &group : def.groups) {
12351259
const std::string &group_name = group.first;
12361260
m_group_to_items[group_name].push_back(id);
12371261
}
1262+
12381263
return id;
12391264
}
12401265

@@ -1260,18 +1285,7 @@ void NodeDefManager::removeNode(const std::string &name)
12601285
m_name_id_mapping_with_aliases.erase(name);
12611286
}
12621287

1263-
// Erase node content from all groups it belongs to
1264-
for (std::unordered_map<std::string, std::vector<content_t>>::iterator iter_groups =
1265-
m_group_to_items.begin(); iter_groups != m_group_to_items.end();) {
1266-
std::vector<content_t> &items = iter_groups->second;
1267-
items.erase(std::remove(items.begin(), items.end(), id), items.end());
1268-
1269-
// Check if group is empty
1270-
if (items.empty())
1271-
m_group_to_items.erase(iter_groups++);
1272-
else
1273-
++iter_groups;
1274-
}
1288+
eraseIdFromGroups(id);
12751289
}
12761290

12771291

‎src/nodedef.h

+8
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,14 @@ class NodeDefManager {
668668
*/
669669
void addNameIdMapping(content_t i, std::string name);
670670

671+
/*!
672+
* Removes a content ID from all groups.
673+
* Erases content IDs from vectors in \ref m_group_to_items and
674+
* removes empty vectors.
675+
* @param id Content ID
676+
*/
677+
void eraseIdFromGroups(content_t id);
678+
671679
/*!
672680
* Recalculates m_selection_box_int_union based on
673681
* m_selection_box_union.

0 commit comments

Comments
 (0)
Please sign in to comment.