2005-07-03 18:25:48 +02:00
|
|
|
#include "precompiled.h"
|
|
|
|
|
|
|
|
#include "MessageHandler.h"
|
|
|
|
|
2005-08-20 17:44:50 +02:00
|
|
|
#include "../CommandProc.h"
|
|
|
|
|
2005-07-03 18:25:48 +02:00
|
|
|
#include "graphics/Terrain.h"
|
|
|
|
#include "ps/Game.h"
|
|
|
|
|
|
|
|
namespace AtlasMessage {
|
|
|
|
|
2005-09-13 05:57:34 +02:00
|
|
|
|
2005-08-20 17:44:50 +02:00
|
|
|
BEGIN_COMMAND(AlterElevation)
|
2005-07-03 18:25:48 +02:00
|
|
|
|
2005-08-20 17:44:50 +02:00
|
|
|
// TODO: much more efficient version of this, and without the memory leaks
|
|
|
|
u16* OldTerrain;
|
|
|
|
u16* NewTerrain;
|
2005-07-03 18:25:48 +02:00
|
|
|
|
2005-08-20 17:44:50 +02:00
|
|
|
void Construct()
|
|
|
|
{
|
|
|
|
OldTerrain = NewTerrain = NULL;
|
|
|
|
}
|
|
|
|
void Destruct()
|
|
|
|
{
|
|
|
|
delete OldTerrain;
|
|
|
|
delete NewTerrain;
|
|
|
|
}
|
2005-07-03 18:25:48 +02:00
|
|
|
|
2005-09-13 05:57:34 +02:00
|
|
|
void Do()
|
|
|
|
{
|
2005-07-03 18:25:48 +02:00
|
|
|
|
2005-08-20 17:44:50 +02:00
|
|
|
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
|
2005-07-03 18:25:48 +02:00
|
|
|
|
2005-08-20 17:44:50 +02:00
|
|
|
int verts = terrain->GetVerticesPerSide()*terrain->GetVerticesPerSide();
|
|
|
|
OldTerrain = new u16[verts];
|
|
|
|
memcpy(OldTerrain, terrain->GetHeightMap(), verts*sizeof(u16));
|
|
|
|
|
2005-09-13 05:57:34 +02:00
|
|
|
int amount = (int)d->amount;
|
|
|
|
|
2005-09-30 02:59:42 +02:00
|
|
|
// If the framerate is very high, 'amount' is often very
|
2005-09-13 05:57:34 +02:00
|
|
|
// small (even zero) so the integer truncation is significant
|
|
|
|
static float roundingError = 0.0;
|
|
|
|
roundingError += d->amount - (float)amount;
|
|
|
|
if (roundingError >= 1.f)
|
|
|
|
{
|
|
|
|
amount += (int)roundingError;
|
|
|
|
roundingError -= (float)(int)roundingError;
|
|
|
|
}
|
|
|
|
|
2005-09-12 22:04:26 +02:00
|
|
|
CVector3D vec;
|
|
|
|
d->pos.GetWorldSpace(vec);
|
|
|
|
uint32_t x, z;
|
|
|
|
terrain->CalcFromPosition(vec, x, z);
|
2005-09-13 05:57:34 +02:00
|
|
|
terrain->RaiseVertex(x, z, amount);
|
2005-08-20 17:44:50 +02:00
|
|
|
terrain->MakeDirty(x, z, x, z);
|
|
|
|
}
|
|
|
|
|
2005-09-13 05:57:34 +02:00
|
|
|
void Undo()
|
|
|
|
{
|
2005-08-20 17:44:50 +02:00
|
|
|
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
|
|
|
|
if (! NewTerrain)
|
|
|
|
{
|
|
|
|
int verts = terrain->GetVerticesPerSide()*terrain->GetVerticesPerSide();
|
|
|
|
NewTerrain = new u16[verts];
|
|
|
|
memcpy(NewTerrain, terrain->GetHeightMap(), verts*sizeof(u16));
|
|
|
|
}
|
|
|
|
terrain->SetHeightMap(OldTerrain); // CTerrain duplicates the data
|
|
|
|
}
|
|
|
|
|
2005-09-13 05:57:34 +02:00
|
|
|
void Redo()
|
|
|
|
{
|
2005-08-20 17:44:50 +02:00
|
|
|
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
|
|
|
|
terrain->SetHeightMap(NewTerrain); // CTerrain duplicates the data
|
|
|
|
}
|
|
|
|
|
2005-09-13 05:57:34 +02:00
|
|
|
void MergeWithSelf(cAlterElevation* prev)
|
|
|
|
{
|
2005-08-20 19:37:48 +02:00
|
|
|
std::swap(prev->NewTerrain, NewTerrain);
|
2005-08-20 17:44:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
END_COMMAND(AlterElevation);
|
2005-07-03 18:25:48 +02:00
|
|
|
|
|
|
|
}
|