#include "util/serialize.h"
#include "util/string.h"
#include "util/numeric.h"
+#include "util/basic_macros.h"
#include "map.h"
#include "gamedef.h"
#include "nodedef.h"
#include "inventory.h"
#include "mapblock.h"
-#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
-
RollbackNode::RollbackNode(Map *map, v3s16 p, IGameDef *gamedef)
{
- INodeDefManager *ndef = gamedef->ndef();
- MapNode n = map->getNodeNoEx(p);
+ const NodeDefManager *ndef = gamedef->ndef();
+ MapNode n = map->getNode(p);
name = ndef->get(n).name;
param1 = n.param1;
param2 = n.param2;
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();
}
}
// If metadata differs, action is always important
if(n_old.meta != n_new.meta)
return true;
- INodeDefManager *ndef = gamedef->ndef();
+ const NodeDefManager *ndef = gamedef->ndef();
// Both are of the same name, so a single definition is needed
const ContentFeatures &def = ndef->get(n_old.name);
// If the type is flowing liquid, action is not important
case TYPE_NOTHING:
return true;
case TYPE_SET_NODE: {
- INodeDefManager *ndef = gamedef->ndef();
+ const NodeDefManager *ndef = gamedef->ndef();
// Make sure position is loaded from disk
map->emergeBlock(getContainerPos(p, MAP_BLOCKSIZE), false);
// Check current node
- MapNode current_node = map->getNodeNoEx(p);
+ MapNode current_node = map->getNode(p);
std::string current_name = ndef->get(current_node).name;
// If current node not the new node, it's bad
if (current_name != n_new.name) {
return false;
}
// Create rollback node
- MapNode n(ndef, n_old.name, n_old.param1, n_old.param2);
+ content_t id = CONTENT_IGNORE;
+ if (!ndef->getId(n_old.name, id)) {
+ // The old node is not registered
+ return false;
+ }
+ MapNode n(id, n_old.param1, n_old.param2);
// Set rollback node
try {
if (!map->addNodeWithEvent(p, n)) {
} else {
NodeMetadata *meta = map->getNodeMetadata(p);
if (!meta) {
- meta = new NodeMetadata(gamedef);
+ meta = new NodeMetadata(gamedef->idef());
if (!map->setNodeMetadata(p, meta)) {
delete meta;
infostream << "RollbackAction::applyRevert(): "
}
}
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);
MapEditEvent event;
event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
- event.p = blockpos;
- map->dispatchEvent(&event);
- // Set the block to be saved
- MapBlock *block = map->getBlockNoCreateNoEx(blockpos);
- if (block) {
- block->raiseModified(MOD_STATE_WRITE_NEEDED,
- MOD_REASON_REPORT_META_CHANGE);
- }
+ event.p = p;
+ map->dispatchEvent(event);
} catch (InvalidPositionException &e) {
infostream << "RollbackAction::applyRevert(): "
<< "InvalidPositionException: " << e.what()
case TYPE_MODIFY_INVENTORY_STACK: {
InventoryLocation loc;
loc.deSerialize(inventory_location);
- std::string real_name = gamedef->idef()->getAlias(inventory_stack.name);
Inventory *inv = imgr->getInventory(loc);
if (!inv) {
infostream << "RollbackAction::applyRevert(): Could not get "
<< inventory_location << std::endl;
return false;
}
+
// If item was added, take away item, otherwise add removed item
if (inventory_add) {
// Silently ignore different current item
- if (list->getItem(inventory_index).name != real_name)
+ if (list->getItem(inventory_index).name !=
+ gamedef->idef()->getAlias(inventory_stack.name))
return false;
list->takeItem(inventory_index, inventory_stack.count);
} else {