From 4ff0a9f52c642fbc91249fb010167fc30fb0c739 Mon Sep 17 00:00:00 2001
From: jacob1 <jfu614@gmail.com>
Date: Mon, 2 Oct 2017 22:35:44 -0400
Subject: [PATCH] only expand stamp in the direction you are moving

---
 src/client/GameSave.cpp         | 25 +++++++++++++------------
 src/client/GameSave.h           |  2 +-
 src/gui/game/GameController.cpp |  5 ++++-
 src/gui/game/GameView.cpp       | 12 +++++++-----
 src/gui/game/GameView.h         |  3 +++
 5 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/src/client/GameSave.cpp b/src/client/GameSave.cpp
index 887aba3e7..958fed17c 100644
--- a/src/client/GameSave.cpp
+++ b/src/client/GameSave.cpp
@@ -260,13 +260,14 @@ char * GameSave::Serialise(unsigned int & dataSize)
 	return serialiseOPS(dataSize);
 }
 
-void GameSave::Translate(vector2d translate)
+vector2d GameSave::Translate(vector2d translate)
 {
-	if(Collapsed())
+	if (Collapsed())
 		Expand();
 	int nx, ny;
 	vector2d pos;
 	float minx = 0, miny = 0, maxx = 0, maxy = 0;
+	// determine minimum and maximum position of all particles / signs
 	for (size_t i = 0; i < signs.size(); i++)
 	{
 		pos = v2d_new(signs[i].x, signs[i].y);
@@ -298,23 +299,18 @@ void GameSave::Translate(vector2d translate)
 		if (ny > maxy)
 			maxy = ny;
 	}
+	// determine whether corrections are needed. If moving in this direction would delete stuff, expand the save
 	vector2d backCorrection = v2d_new(
-		(minx < 0) ? (-floor(minx / 4)) : 0,
-		(miny < 0) ? (-floor(miny / 4)) : 0
+		(minx < 0) ? (-floor(minx / CELL)) : 0,
+		(miny < 0) ? (-floor(miny / CELL)) : 0
 	);
 	int blockBoundsX = int(maxx / CELL) + 1, blockBoundsY = int(maxy / CELL) + 1;
 	vector2d frontCorrection = v2d_new(
 		(blockBoundsX > blockWidth) ? (blockBoundsX - blockWidth) : 0,
 		(blockBoundsY > blockHeight) ? (blockBoundsY - blockHeight) : 0
 	);
-	if (frontCorrection.x < backCorrection.x)
-		frontCorrection.x = backCorrection.x;
-	else
-		backCorrection.x = frontCorrection.x;
-	if (frontCorrection.y < backCorrection.y)
-		frontCorrection.y = backCorrection.y;
-	else
-		backCorrection.y = frontCorrection.y;
+
+	// get new width based on corrections
 	int newWidth = (blockWidth + backCorrection.x + frontCorrection.x) * CELL;
 	int newHeight = (blockHeight + backCorrection.y + frontCorrection.y) * CELL;
 	if (newWidth > XRES)
@@ -322,11 +318,16 @@ void GameSave::Translate(vector2d translate)
 	if (newHeight > YRES)
 		frontCorrection.y = backCorrection.y = 0;
 
+	// call Transform to do the transformation we wanted when calling this function
 	translate = v2d_add(translate, v2d_multiply_float(backCorrection, CELL));
 	Transform(m2d_identity, translate,
 		(blockWidth + backCorrection.x + frontCorrection.x) * CELL,
 		(blockHeight + backCorrection.y + frontCorrection.y) * CELL
 	);
+
+	// return how much we corrected. This is used to offset the position of the current stamp
+	// otherwise it would attempt to recenter it with the current height
+	return v2d_add(v2d_multiply_float(backCorrection, -CELL), v2d_multiply_float(frontCorrection, CELL));
 }
 
 void GameSave::Transform(matrix2d transform, vector2d translate)
diff --git a/src/client/GameSave.h b/src/client/GameSave.h
index 9458afc46..bd719ceab 100644
--- a/src/client/GameSave.h
+++ b/src/client/GameSave.h
@@ -76,7 +76,7 @@ public:
 	void setSize(int width, int height);
 	char * Serialise(unsigned int & dataSize);
 	std::vector<char> Serialise();
-	void Translate(vector2d translate);
+	vector2d Translate(vector2d translate);
 	void Transform(matrix2d transform, vector2d translate);
 	void Transform(matrix2d transform, vector2d translate, int newWidth, int newHeight);
 
diff --git a/src/gui/game/GameController.cpp b/src/gui/game/GameController.cpp
index 05f8838df..88f5bbdf8 100644
--- a/src/gui/game/GameController.cpp
+++ b/src/gui/game/GameController.cpp
@@ -545,8 +545,11 @@ void GameController::LoadStamp(GameSave *stamp)
 void GameController::TranslateSave(ui::Point point)
 {
 	vector2d translate = v2d_new(point.X, point.Y);
-	gameModel->GetPlaceSave()->Translate(translate);
+	vector2d translated = gameModel->GetPlaceSave()->Translate(translate);
+	ui::Point currentPlaceSaveOffset = gameView->GetPlaceSaveOffset();
+	// resets placeSaveOffset to 0, which is why we back it up first
 	gameModel->SetPlaceSave(gameModel->GetPlaceSave());
+	gameView->SetPlaceSaveOffset(ui::Point(translated.x, translated.y) + currentPlaceSaveOffset);
 }
 
 void GameController::TransformSave(matrix2d transform)
diff --git a/src/gui/game/GameView.cpp b/src/gui/game/GameView.cpp
index 088480529..861158e8a 100644
--- a/src/gui/game/GameView.cpp
+++ b/src/gui/game/GameView.cpp
@@ -203,7 +203,8 @@ GameView::GameView():
 	selectPoint2(0, 0),
 	currentMouse(0, 0),
 	mousePosition(0, 0),
-	placeSaveThumb(NULL)
+	placeSaveThumb(NULL),
+	placeSaveOffset(0, 0)
 {
 
 	int currentX = 1;
@@ -1244,8 +1245,8 @@ void GameView::OnMouseUp(int x, int y, unsigned button)
 				{
 					if (placeSaveThumb && y <= WINDOWH-BARSIZE)
 					{
-						int thumbX = selectPoint2.X - (placeSaveThumb->Width/2);
-						int thumbY = selectPoint2.Y - (placeSaveThumb->Height/2);
+						int thumbX = selectPoint2.X - ((placeSaveThumb->Width-placeSaveOffset.X)/2);
+						int thumbY = selectPoint2.Y - ((placeSaveThumb->Height-placeSaveOffset.Y)/2);
 
 						if (thumbX < 0)
 							thumbX = 0;
@@ -1947,6 +1948,7 @@ void GameView::NotifyLogChanged(GameModel * sender, string entry)
 void GameView::NotifyPlaceSaveChanged(GameModel * sender)
 {
 	delete placeSaveThumb;
+	placeSaveOffset = ui::Point(0, 0);
 	if(sender->GetPlaceSave())
 	{
 		placeSaveThumb = SaveRenderer::Ref().Render(sender->GetPlaceSave());
@@ -2164,8 +2166,8 @@ void GameView::OnDraw()
 			{
 				if(placeSaveThumb && selectPoint2.X!=-1)
 				{
-					int thumbX = selectPoint2.X - (placeSaveThumb->Width/2) + CELL/2;
-					int thumbY = selectPoint2.Y - (placeSaveThumb->Height/2) + CELL/2;
+					int thumbX = selectPoint2.X - ((placeSaveThumb->Width-placeSaveOffset.X)/2) + CELL/2;
+					int thumbY = selectPoint2.Y - ((placeSaveThumb->Height-placeSaveOffset.Y)/2) + CELL/2;
 
 					ui::Point thumbPos = c->NormaliseBlockCoord(ui::Point(thumbX, thumbY));
 
diff --git a/src/gui/game/GameView.h b/src/gui/game/GameView.h
index 2d87cf228..0d673f264 100644
--- a/src/gui/game/GameView.h
+++ b/src/gui/game/GameView.h
@@ -110,6 +110,7 @@ private:
 	ui::Point mousePosition;
 
 	VideoBuffer * placeSaveThumb;
+	ui::Point placeSaveOffset;
 
 	SimulationSample sample;
 
@@ -147,6 +148,8 @@ public:
 	void ExitPrompt();
 	SelectMode GetSelectMode() { return selectMode; }
 	void BeginStampSelection();
+	ui::Point GetPlaceSaveOffset() { return placeSaveOffset; }
+	void SetPlaceSaveOffset(ui::Point offset) { placeSaveOffset = offset; }
 	int Record(bool record);
 
 	//all of these are only here for one debug lines