Files
noggit-red/src/noggit/Action.cpp
2024-09-06 20:16:57 +00:00

851 lines
24 KiB
C++
Executable File

// This file is part of Noggit3, licensed under GNU General Public License (version 3).
#include "Action.hpp"
#include <noggit/MapChunk.h>
#include <noggit/MapView.h>
#include <noggit/texture_set.hpp>
#include <noggit/ContextObject.hpp>
#include <noggit/Log.h>
#include <cstring>
Noggit::Action::Action(MapView* map_view)
: QObject()
, _map_view(map_view)
{
}
void Noggit::Action::setFlags(int flags)
{
_flags = flags;
}
void Noggit::Action::addFlags(int flags)
{
_flags |= flags;
}
int Noggit::Action::getFlags()
{
return _flags;
}
void Noggit::Action::setModalityControllers(int modality_controls)
{
_modality_controls = modality_controls;
}
void Noggit::Action::addModalityControllers(int modality_controls)
{
_modality_controls |= modality_controls;
}
int Noggit::Action::getModalityControllers()
{
return _modality_controls;
}
void Noggit::Action::undo(bool redo)
{
_map_view->context()->makeCurrent(_map_view->context()->surface());
OpenGL::context::scoped_setter const _ (::gl, _map_view->context());
if (_flags & ActionFlags::eCHUNKS_TERRAIN)
{
for (auto& pair : redo ? _chunk_terrain_post : _chunk_terrain_pre)
{
std::memcpy(&pair.first->mVertices, pair.second.data(), 145 * 3 * sizeof(float));
pair.first->registerChunkUpdate(ChunkUpdateFlags::VERTEX);
}
for (auto& pair : redo ? _chunk_terrain_post : _chunk_terrain_pre)
{
_map_view->getWorld()->recalc_norms(pair.first);
pair.first->registerChunkUpdate(ChunkUpdateFlags::NORMALS);
}
_map_view->getWorld()->updateVertexCenter();
}
if (_flags & ActionFlags::eCHUNKS_TEXTURE)
{
for (auto& pair : redo ? _chunk_texture_post : _chunk_texture_pre)
{
auto texture_set = pair.first->getTextureSet();
texture_set->setAlphamaps(pair.second.alphamaps);
if (pair.second.tmp_edit_values)
texture_set->getTempAlphamaps() = std::make_unique<tmp_edit_alpha_values>(*pair.second.tmp_edit_values);
else
texture_set->getTempAlphamaps().reset();
std::memcpy(texture_set->getMCLYEntries(), &pair.second.layers_info, sizeof(layer_info) * 4);
texture_set->setNTextures(pair.second.n_textures);
auto textures = texture_set->getTextures();
textures->clear();
textures->reserve(pair.second.n_textures);
for (auto& filename : pair.second.textures)
{
textures->emplace_back(filename, Noggit::NoggitRenderContext::MAP_VIEW);
}
texture_set->markDirty();
texture_set->apply_alpha_changes();
pair.first->registerChunkUpdate(ChunkUpdateFlags::FLAGS); // for texture anim flags
}
}
if (_flags & ActionFlags::eCHUNKS_VERTEX_COLOR)
{
for (auto& pair : redo ? _chunk_vertex_color_post : _chunk_vertex_color_pre)
{
std::memcpy(&pair.first->mccv, pair.second.data(), 145 * 3 * sizeof(float));
pair.first->registerChunkUpdate(ChunkUpdateFlags::MCCV);;
}
}
if (_flags & ActionFlags::eOBJECTS_ADDED
|| _flags & ActionFlags::eOBJECTS_REMOVED
|| _flags & ActionFlags::eOBJECTS_TRANSFORMED)
{
tsl::robin_map<unsigned, std::vector<unsigned>> new_operation_map;
for(auto& pair : _object_operations)
{
if (redo)
{
unsigned uid = pair.first;
for (unsigned token : pair.second)
{
switch (token)
{
case ActionFlags::eOBJECTS_ADDED:
uid = handleObjectAdded(pair.first, redo);
break;
case ActionFlags::eOBJECTS_REMOVED:
uid = handleObjectRemoved(uid, redo);
break;
case ActionFlags::eOBJECTS_TRANSFORMED:
uid = handleObjectTransformed(uid, redo);
break;
default:
break;
}
}
new_operation_map[uid] = pair.second;
}
else
{
unsigned uid = pair.first;
for (auto it = pair.second.rbegin(); it != pair.second.rend(); ++it)
{
switch (*it)
{
case ActionFlags::eOBJECTS_ADDED:
uid = handleObjectAdded(uid, redo);
break;
case ActionFlags::eOBJECTS_REMOVED:
uid = handleObjectRemoved(uid, redo);
break;
case ActionFlags::eOBJECTS_TRANSFORMED:
uid = handleObjectTransformed(uid, redo);
break;
default:
break;
}
}
new_operation_map[uid] = pair.second;
}
}
_object_operations = std::move(new_operation_map);
}
if (_flags & ActionFlags::eCHUNKS_HOLES)
{
for (auto& pair : redo ? _chunk_holes_post : _chunk_holes_pre)
{
pair.first->holes = pair.second;
pair.first->registerChunkUpdate(ChunkUpdateFlags::HOLES);
}
}
if (_flags & ActionFlags::eCHUNKS_AREAID)
{
for (auto& pair : redo ? _chunk_area_id_post : _chunk_area_id_pre)
{
pair.first->areaID = pair.second;
pair.first->registerChunkUpdate(ChunkUpdateFlags::AREA_ID);
}
}
if (_flags & ActionFlags::eCHUNKS_FLAGS)
{
for (auto& pair : redo ? _chunk_flags_post : _chunk_flags_pre)
{
pair.first->header_flags = pair.second;
pair.first->registerChunkUpdate(ChunkUpdateFlags::FLAGS);
}
}
if (_flags & ActionFlags::eCHUNKS_WATER)
{
for (auto& pair : redo ? _chunk_liquid_post : _chunk_liquid_pre)
{
auto liquid_chunk = pair.first->liquid_chunk();
*liquid_chunk->getLayers() = pair.second;
liquid_chunk->update_layers();
liquid_chunk->tagUpdate();
}
}
if (_flags & ActionFlags::eVERTEX_SELECTION)
{
_map_view->getWorld()->setVertexSelectionCache(redo ? _vertex_selection_post : _vertex_selection_pre);
}
if (_flags & ActionFlags::eCHUNK_SHADOWS)
{
for (auto& pair : redo ? _chunk_shadow_map_post : _chunk_shadow_map_pre)
{
std::memcpy(&pair.first->_shadow_map, pair.second.data(), 64 * 64 * sizeof(uint8_t));
pair.first->update_shadows();
}
}
if (_flags & ActionFlags::eCHUNK_DOODADS_EXCLUSION)
{
for (auto& pair : redo ? _chunk_detaildoodad_exclusion_post : _chunk_detaildoodad_exclusion_pre)
{
std::memcpy(&pair.first->texture_set->_doodadStencil, pair.second.data(), 8 * sizeof(std::uint8_t));
pair.first->registerChunkUpdate(ChunkUpdateFlags::DETAILDOODADS_EXCLUSION);
}
}
if (_flags & ActionFlags::eCHUNKS_LAYERINFO)
{
for (auto& pair : redo ? _chunk_layerinfos_post : _chunk_layerinfos_pre)
{
auto texture_set = pair.first->getTextureSet();
std::memcpy(texture_set->getMCLYEntries(), &pair.second, sizeof(layer_info) * 4);
// TODO, enable this if texture flags get moved to this action flag.
// pair.first->registerChunkUpdate(ChunkUpdateFlags::FLAGS); // for texture anim flags.
pair.first->registerChunkUpdate(ChunkUpdateFlags::GROUND_EFFECT);
}
}
}
unsigned Noggit::Action::handleObjectAdded(unsigned uid, bool redo)
{
for (auto& pair : _added_objects_pre)
{
if (pair.first != uid)
continue;
unsigned new_uid = pair.first;
if (redo)
{
unsigned old_uid = pair.first;
SceneObject* obj;
if (pair.second.type == ActionObjectTypes::WMO)
obj = _map_view->getWorld()->addWMOAndGetInstance(pair.second.file_key, pair.second.pos, pair.second.dir, false);
else
obj = _map_view->getWorld()->addM2AndGetInstance(pair.second.file_key, pair.second.pos,
pair.second.scale, pair.second.dir, nullptr, false, false);
obj->instance_model()->wait_until_loaded();
obj->instance_model()->waitForChildrenLoaded();
obj->recalcExtents();
new_uid = obj->uid;
pair.first = new_uid;
// fix references in other actions
for (auto& pair_ : _removed_objects_pre)
{
if (pair_.first == old_uid)
{
pair_.first = new_uid;
break;
}
}
for (auto& pair_ : _transformed_objects_pre)
{
if (pair_.first == old_uid)
{
pair_.first = new_uid;
break;
}
}
for (auto& pair_ : _transformed_objects_post)
{
if (pair_.first == old_uid)
{
pair_.first = new_uid;
break;
}
}
}
else
{
_map_view->getWorld()->deleteInstance(pair.first, false);
}
return new_uid;
}
return -1;
}
unsigned Noggit::Action::handleObjectRemoved(unsigned uid, bool redo)
{
for (auto& pair : _removed_objects_pre)
{
if (pair.first != uid)
continue;
unsigned new_uid = pair.first;
if (!redo)
{
unsigned old_uid = pair.first;
SceneObject* obj;
if (pair.second.type == ActionObjectTypes::WMO)
obj = _map_view->getWorld()->addWMOAndGetInstance(pair.second.file_key, pair.second.pos, pair.second.dir, false);
else
obj = _map_view->getWorld()->addM2AndGetInstance(pair.second.file_key, pair.second.pos,
pair.second.scale, pair.second.dir, nullptr, false, false);
obj->instance_model()->wait_until_loaded();
obj->instance_model()->waitForChildrenLoaded();
obj->recalcExtents();
new_uid = obj->uid;
pair.first = new_uid;
// fix references in other actions
for (auto& pair_ : _added_objects_pre)
{
if (pair_.first == old_uid)
{
pair_.first = new_uid;
break;
}
}
for (auto& pair_ : _transformed_objects_pre)
{
if (pair_.first == old_uid)
{
pair_.first = new_uid;
break;
}
}
for (auto& pair_ : _transformed_objects_post)
{
if (pair_.first == old_uid)
{
pair_.first = new_uid;
break;
}
}
}
else
{
_map_view->getWorld()->deleteInstance(pair.first, false);
}
return new_uid;
}
return -1;
}
unsigned Noggit::Action::handleObjectTransformed(unsigned uid, bool redo)
{
for (auto& pair : redo ? _transformed_objects_post : _transformed_objects_pre)
{
if (pair.first != uid)
continue;
auto obj = _map_view->getWorld()->getObjectInstance(pair.first);
if (!obj)
continue;
_map_view->getWorld()->updateTilesEntry(obj, model_update::remove);
obj->pos = pair.second.pos;
obj->dir = pair.second.dir;
obj->scale = pair.second.scale;
obj->recalcExtents();
_map_view->getWorld()->updateTilesEntry(obj, model_update::add);
return pair.first;
}
return -1;
}
void Noggit::Action::finish()
{
if (_flags & ActionFlags::eCHUNKS_TERRAIN)
{
_chunk_terrain_post.resize(_chunk_terrain_pre.size());
for (int i = 0; i < _chunk_terrain_pre.size(); ++i)
{
auto& post =_chunk_terrain_post.at(i);
auto& pre = _chunk_terrain_pre.at(i);
post.first = pre.first;
std::memcpy(post.second.data(), &post.first->mVertices, 145 * 3 * sizeof(float));
}
}
if (_flags & ActionFlags::eCHUNKS_TEXTURE)
{
_chunk_texture_post.reserve(_chunk_texture_pre.size());
for (int i = 0; i < _chunk_texture_pre.size(); ++i)
{
auto& pre = _chunk_texture_pre.at(i);
TextureChangeCache cache;
auto texture_set = pre.first->getTextureSet();
cache.n_textures = texture_set->num();
const auto& sourceAlphamaps = *texture_set->getAlphamaps();
for (size_t i = 0; i < MAX_ALPHAMAPS; ++i) {
if (sourceAlphamaps[i])
cache.alphamaps[i] = std::make_unique<Alphamap>(*sourceAlphamaps[i]);
else
cache.alphamaps[i].reset();
}
const auto& source_temp_alphas = texture_set->getTempAlphamaps();
if (source_temp_alphas)
cache.tmp_edit_values = std::make_unique<tmp_edit_alpha_values>(*source_temp_alphas);
else
cache.tmp_edit_values.reset();
std::memcpy(&cache.layers_info, texture_set->getMCLYEntries(), sizeof(layer_info) * 4);
for (int j = 0; j < cache.n_textures; ++j)
{
cache.textures.push_back(texture_set->filename(j));
}
_chunk_texture_post.emplace_back(std::make_pair(pre.first, std::move(cache)));
}
}
if (_flags & ActionFlags::eCHUNKS_VERTEX_COLOR)
{
_chunk_vertex_color_post.resize(_chunk_vertex_color_pre.size());
for (int i = 0; i < _chunk_vertex_color_pre.size(); ++i)
{
auto& post =_chunk_vertex_color_post.at(i);
auto& pre = _chunk_vertex_color_pre.at(i);
post.first = pre.first;
std::memcpy(post.second.data(), &post.first->mccv, 145 * 3 * sizeof(float));
}
}
if (_flags & ActionFlags::eOBJECTS_TRANSFORMED)
{
_transformed_objects_post.resize(_transformed_objects_pre.size());
for (int i = 0; i < _transformed_objects_pre.size(); ++i)
{
auto& post =_transformed_objects_post.at(i);
auto& pre = _transformed_objects_pre.at(i);
post.first = pre.first;
post.second = pre.second;
auto instance = _map_view->getWorld()->get_model(post.first);
if (!instance)
{
post.second.pos = pre.second.pos;
post.second.dir = pre.second.dir;
post.second.scale = pre.second.scale;
continue;
}
auto obj = std::get<selected_object_type>(instance.value());
post.second.pos = obj->pos;
post.second.dir = obj->dir;
post.second.scale = obj->scale;
}
}
if (_flags & ActionFlags::eCHUNKS_HOLES)
{
_chunk_holes_post.resize(_chunk_holes_pre.size());
for (int i = 0; i < _chunk_holes_pre.size(); ++i)
{
auto& post = _chunk_holes_post.at(i);
auto& pre = _chunk_holes_pre.at(i);
post.first = pre.first;
post.second = pre.first->holes;
}
}
if (_flags & ActionFlags::eCHUNKS_AREAID)
{
_chunk_area_id_post.resize(_chunk_area_id_pre.size());
for (int i = 0; i < _chunk_area_id_pre.size(); ++i)
{
auto& post = _chunk_area_id_post.at(i);
auto& pre = _chunk_area_id_pre.at(i);
post.first = pre.first;
post.second = pre.first->areaID;
}
}
if (_flags & ActionFlags::eCHUNKS_FLAGS)
{
_chunk_flags_post.resize(_chunk_flags_pre.size());
for (int i = 0; i < _chunk_flags_pre.size(); ++i)
{
auto& post = _chunk_flags_post.at(i);
auto& pre = _chunk_flags_pre.at(i);
post.first = pre.first;
post.second = pre.first->header_flags;
}
}
if (_flags & ActionFlags::eCHUNKS_WATER)
{
_chunk_liquid_post.resize(_chunk_liquid_pre.size());
for (int i = 0; i < _chunk_liquid_pre.size(); ++i)
{
auto& post = _chunk_liquid_post.at(i);
auto& pre = _chunk_liquid_pre.at(i);
post.first = pre.first;
post.second = *pre.first->liquid_chunk()->getLayers();
}
}
if (_flags & ActionFlags::eVERTEX_SELECTION)
{
_vertex_selection_post = _map_view->getWorld()->getVertexSelectionCache();
}
if (_flags & ActionFlags::eCHUNK_SHADOWS)
{
_chunk_shadow_map_post.resize(_chunk_shadow_map_pre.size());
for (int i = 0; i < _chunk_shadow_map_pre.size(); ++i)
{
auto& post =_chunk_shadow_map_post.at(i);
auto& pre = _chunk_shadow_map_pre.at(i);
post.first = pre.first;
std::memcpy(post.second.data(), &post.first->_shadow_map, 64 * 64 * sizeof(std::uint8_t));
}
}
if (_post)
_post();
}
float* Noggit::Action::getChunkTerrainOriginalData(MapChunk* chunk)
{
for (auto& pair : _chunk_terrain_pre)
{
if (pair.first == chunk)
return pair.second.data();
}
return nullptr;
}
void Noggit::Action::setDelta(float delta)
{
_delta = delta;
}
float Noggit::Action::getDelta() const
{
return _delta;
}
void Noggit::Action::setBlockCursor(bool state)
{
_block_cursor = state;
}
bool Noggit::Action::getBlockCursor() const
{
return _block_cursor;
}
void Noggit::Action::setPostCallback(std::function<void()> function)
{
_post = function;
}
/* ============ */
/* Registrators */
/* ============ */
void Noggit::Action::registerChunkTerrainChange(MapChunk* chunk)
{
_flags |= ActionFlags::eCHUNKS_TERRAIN;
for (auto& pair : _chunk_terrain_pre)
{
if (pair.first == chunk)
return;
}
std::array<float, 145 * 3> data{};
std::memcpy(data.data(), &chunk->mVertices, 145 * 3 * sizeof(float));
_chunk_terrain_pre.emplace_back(std::make_pair(chunk, data));
//LogDebug << "Chunk: " << chunk->px << "_" << chunk->py << "on tile: " << chunk->mt->index.x << "_" << chunk->mt->index.z << std::endl;
}
void Noggit::Action::registerChunkTextureChange(MapChunk* chunk)
{
_flags |= ActionFlags::eCHUNKS_TEXTURE;
for (auto& pair : _chunk_texture_pre)
{
if (pair.first == chunk)
return;
}
TextureChangeCache cache;
auto texture_set = chunk->getTextureSet();
cache.n_textures = texture_set->num();
// cache.alphamaps = *texture_set->getAlphamaps();
// cache.tmp_edit_values = *texture_set->getTempAlphamaps();
const auto& sourceAlphamaps = *texture_set->getAlphamaps();
for (size_t i = 0; i < MAX_ALPHAMAPS; ++i)
{
if (sourceAlphamaps[i])
cache.alphamaps[i] = std::make_unique<Alphamap>(*sourceAlphamaps[i]);
else
cache.alphamaps[i].reset();
}
const auto& source_temp_alphas = texture_set->getTempAlphamaps();
if (source_temp_alphas)
cache.tmp_edit_values = std::make_unique<tmp_edit_alpha_values>(*source_temp_alphas);
else
cache.tmp_edit_values.reset();
std::memcpy(&cache.layers_info, texture_set->getMCLYEntries(), sizeof(layer_info) * 4);
for (int i = 0; i < cache.n_textures; ++i)
{
cache.textures.push_back(texture_set->filename(i));
}
// _chunk_texture_pre.emplace_back(std::make_pair(chunk, std::move( cache)));
auto cache_pair = std::make_pair(chunk, std::move(cache));
_chunk_texture_pre.emplace_back(std::move(cache_pair));
}
void Noggit::Action::registerChunkVertexColorChange(MapChunk* chunk)
{
_flags |= ActionFlags::eCHUNKS_VERTEX_COLOR;
for (auto& pair : _chunk_vertex_color_pre)
{
if (pair.first == chunk)
return;
}
std::array<float, 145 * 3> data{};
std::memcpy(data.data(), &chunk->mccv, 145 * 3 * sizeof(float));
_chunk_vertex_color_pre.emplace_back(std::make_pair(chunk, data));
}
void Noggit::Action::registerObjectTransformed(SceneObject* obj)
{
_flags |= ActionFlags::eOBJECTS_TRANSFORMED;
for (auto& pair : _transformed_objects_pre)
{
if (pair.first == obj->uid)
return;
}
_object_operations[obj->uid].emplace_back(ActionFlags::eOBJECTS_TRANSFORMED);
ActionObjectTypes type = obj->which() == eWMO ? ActionObjectTypes::WMO : ActionObjectTypes::M2;
_transformed_objects_pre.emplace_back(std::make_pair(obj->uid,
ObjectInstanceCache{obj->instance_model()->file_key()
, type
, obj->pos
, obj->dir
, obj->scale}));
}
void Noggit::Action::registerObjectAdded(SceneObject* obj)
{
_flags |= ActionFlags::eOBJECTS_ADDED;
for (auto& pair : _added_objects_pre)
{
if (pair.first == obj->uid)
return;
}
_object_operations[obj->uid].emplace_back(ActionFlags::eOBJECTS_ADDED);
ActionObjectTypes type = obj->which() == eWMO ? ActionObjectTypes::WMO : ActionObjectTypes::M2;
_added_objects_pre.emplace_back(std::make_pair(obj->uid,
ObjectInstanceCache{obj->instance_model()->file_key()
, type
, obj->pos
, obj->dir
, obj->scale}
));
}
void Noggit::Action::registerObjectRemoved(SceneObject* obj)
{
_flags |= ActionFlags::eOBJECTS_REMOVED;
for (auto& pair : _removed_objects_pre)
{
if (pair.first == obj->uid)
return;
}
_object_operations[obj->uid].emplace_back(ActionFlags::eOBJECTS_REMOVED);
ActionObjectTypes type = obj->which() == eWMO ? ActionObjectTypes::WMO : ActionObjectTypes::M2;
_removed_objects_pre.emplace_back(std::make_pair(obj->uid,
ObjectInstanceCache{obj->instance_model()->file_key()
, type
, obj->pos
, obj->dir
, obj->scale}
));
}
void Noggit::Action::registerChunkHoleChange(MapChunk* chunk)
{
_flags |= ActionFlags::eCHUNKS_HOLES;
for (auto& pair : _chunk_holes_pre)
{
if (pair.first == chunk)
return;
}
_chunk_holes_pre.emplace_back(std::make_pair(chunk, chunk->holes));
}
void Noggit::Action::registerChunkAreaIDChange(MapChunk* chunk)
{
_flags |= ActionFlags::eCHUNKS_AREAID;
for (auto& pair : _chunk_area_id_pre)
{
if (pair.first == chunk)
return;
}
_chunk_area_id_pre.emplace_back(std::make_pair(chunk, chunk->areaID));
}
void Noggit::Action::registerChunkFlagChange(MapChunk *chunk)
{
_flags |= ActionFlags::eCHUNKS_FLAGS;
for (auto& pair : _chunk_flags_pre)
{
if (pair.first == chunk)
return;
}
_chunk_flags_pre.emplace_back(std::make_pair(chunk, chunk->header_flags));
}
void Noggit::Action::registerChunkLiquidChange(MapChunk* chunk)
{
_flags |= ActionFlags::eCHUNKS_WATER;
for (auto& pair : _chunk_liquid_pre)
{
if (pair.first == chunk)
return;
}
_chunk_liquid_pre.emplace_back(std::make_pair(chunk, *chunk->liquid_chunk()->getLayers()));
}
void Noggit::Action::registerVertexSelectionChange()
{
_flags |= ActionFlags::eVERTEX_SELECTION;
if (_vertex_selection_recorded)
return;
_vertex_selection_pre = _map_view->getWorld()->getVertexSelectionCache();
_vertex_selection_recorded = true;
}
void Noggit::Action::registerChunkShadowChange(MapChunk *chunk)
{
_flags |= ActionFlags::eCHUNK_SHADOWS;
for (auto& pair : _chunk_shadow_map_pre)
{
if (pair.first == chunk)
return;
}
std::array<uint8_t, 64 * 64> data;
std::memcpy(data.data(), &chunk->_shadow_map, 64 * 64 * sizeof(std::uint8_t));
_chunk_shadow_map_pre.emplace_back(std::make_pair(chunk, std::move(data)));
}
void Noggit::Action::registerChunkLayerInfoChange(MapChunk* chunk)
{
_flags |= ActionFlags::eCHUNKS_LAYERINFO;
for (auto& pair : _chunk_layerinfos_pre)
{
if (pair.first == chunk)
return;
}
std::array<layer_info, 4> layer_infos{};
std::memcpy(&layer_infos, chunk->texture_set->getMCLYEntries(), sizeof(layer_info) * 4);
_chunk_layerinfos_pre.emplace_back(chunk, std::move(layer_infos));
}
void Noggit::Action::registerChunkDetailDoodadExclusionChange(MapChunk* chunk)
{
_flags |= ActionFlags::eCHUNK_DOODADS_EXCLUSION;
for (auto& pair : _chunk_detaildoodad_exclusion_pre)
{
if (pair.first == chunk)
return;
}
std::array<std::uint8_t, 8> data{};
std::memcpy(&data, chunk->texture_set->getDoodadStencilBase(), sizeof(std::uint8_t) * 8);
_chunk_detaildoodad_exclusion_pre.emplace_back(std::make_pair(chunk, data));
}
void Noggit::Action::registerAllChunkChanges(MapChunk* chunk)
{
registerChunkTerrainChange(chunk);
registerChunkTextureChange(chunk);
registerChunkVertexColorChange(chunk);
registerChunkHoleChange(chunk);
registerChunkAreaIDChange(chunk);
registerChunkFlagChange(chunk);
registerChunkLiquidChange(chunk);
registerVertexSelectionChange();
registerChunkShadowChange(chunk);
registerChunkLayerInfoChange(chunk);
registerChunkDetailDoodadExclusionChange(chunk);
}
Noggit::Action::~Action()
{
}