From ca542b1ef1e418e8d58c1da3e242c4ad65108c47 Mon Sep 17 00:00:00 2001 From: krawthekrow Date: Mon, 12 Sep 2016 17:15:09 +0800 Subject: [PATCH] autoexpand save when particles are translated out of boundaries --- src/client/GameSave.cpp | 87 +++++++++++++++++++++++++++++++-- src/client/GameSave.h | 2 + src/gui/game/GameController.cpp | 3 +- 3 files changed, 86 insertions(+), 6 deletions(-) diff --git a/src/client/GameSave.cpp b/src/client/GameSave.cpp index 3e955796e..887aba3e7 100644 --- a/src/client/GameSave.cpp +++ b/src/client/GameSave.cpp @@ -260,12 +260,82 @@ char * GameSave::Serialise(unsigned int & dataSize) return serialiseOPS(dataSize); } +void GameSave::Translate(vector2d translate) +{ + if(Collapsed()) + Expand(); + int nx, ny; + vector2d pos; + float minx = 0, miny = 0, maxx = 0, maxy = 0; + for (size_t i = 0; i < signs.size(); i++) + { + pos = v2d_new(signs[i].x, signs[i].y); + pos = v2d_add(pos,translate); + nx = floor(pos.x+0.5f); + ny = floor(pos.y+0.5f); + if (nx < minx) + minx = nx; + if (ny < miny) + miny = ny; + if (nx > maxx) + maxx = nx; + if (ny > maxy) + maxy = ny; + } + for (int i = 0; i < particlesCount; i++) + { + if (!particles[i].type) continue; + pos = v2d_new(particles[i].x, particles[i].y); + pos = v2d_add(pos,translate); + nx = floor(pos.x+0.5f); + ny = floor(pos.y+0.5f); + if (nx < minx) + minx = nx; + if (ny < miny) + miny = ny; + if (nx > maxx) + maxx = nx; + if (ny > maxy) + maxy = ny; + } + vector2d backCorrection = v2d_new( + (minx < 0) ? (-floor(minx / 4)) : 0, + (miny < 0) ? (-floor(miny / 4)) : 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; + int newWidth = (blockWidth + backCorrection.x + frontCorrection.x) * CELL; + int newHeight = (blockHeight + backCorrection.y + frontCorrection.y) * CELL; + if (newWidth > XRES) + frontCorrection.x = backCorrection.x = 0; + if (newHeight > YRES) + frontCorrection.y = backCorrection.y = 0; + + 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 + ); +} + void GameSave::Transform(matrix2d transform, vector2d translate) { if(Collapsed()) Expand(); - int x, y, nx, ny, width = blockWidth*CELL, height = blockHeight*CELL, newWidth, newHeight, newBlockWidth, newBlockHeight; - vector2d pos, tmp, ctl, cbr, vel; + + int width = blockWidth*CELL, height = blockHeight*CELL, newWidth, newHeight; + vector2d tmp, ctl, cbr; vector2d cornerso[4]; // undo any translation caused by rotation cornerso[0] = v2d_new(0,0); @@ -286,10 +356,19 @@ void GameSave::Transform(matrix2d transform, vector2d translate) translate = v2d_sub(translate,tmp); newWidth = floor(cbr.x+0.5f)-floor(ctl.x+0.5f)+1; newHeight = floor(cbr.y+0.5f)-floor(ctl.y+0.5f)+1; + Transform(transform, translate, newWidth, newHeight); +} + +void GameSave::Transform(matrix2d transform, vector2d translate, int newWidth, int newHeight) +{ + if(Collapsed()) + Expand(); + if (newWidth>XRES) newWidth = XRES; if (newHeight>YRES) newHeight = YRES; - newBlockWidth = newWidth/CELL; - newBlockHeight = newHeight/CELL; + + int x, y, nx, ny, newBlockWidth = newWidth / CELL, newBlockHeight = newHeight / CELL; + vector2d pos, vel; unsigned char ** blockMapNew; float **fanVelXNew, **fanVelYNew, **pressureNew, **velocityXNew, **velocityYNew, **ambientHeatNew; diff --git a/src/client/GameSave.h b/src/client/GameSave.h index dd689572b..9458afc46 100644 --- a/src/client/GameSave.h +++ b/src/client/GameSave.h @@ -76,7 +76,9 @@ public: void setSize(int width, int height); char * Serialise(unsigned int & dataSize); std::vector Serialise(); + void Translate(vector2d translate); void Transform(matrix2d transform, vector2d translate); + void Transform(matrix2d transform, vector2d translate, int newWidth, int newHeight); void Expand(); void Collapse(); diff --git a/src/gui/game/GameController.cpp b/src/gui/game/GameController.cpp index 6182c8197..05f8838df 100644 --- a/src/gui/game/GameController.cpp +++ b/src/gui/game/GameController.cpp @@ -544,9 +544,8 @@ void GameController::LoadStamp(GameSave *stamp) void GameController::TranslateSave(ui::Point point) { - matrix2d transform = m2d_identity; vector2d translate = v2d_new(point.X, point.Y); - gameModel->GetPlaceSave()->Transform(transform, translate); + gameModel->GetPlaceSave()->Translate(translate); gameModel->SetPlaceSave(gameModel->GetPlaceSave()); }