Allow bypassing snap points, handle single argument better in lua method, and misc review/other changes

This commit is contained in:
catsoften 2021-12-21 18:37:58 -05:00
parent 229404a9f1
commit 472360f0b9
No known key found for this signature in database
GPG Key ID: E4F118C248F12055
7 changed files with 73 additions and 43 deletions

View File

@ -2629,8 +2629,7 @@ char * GameSave::serialiseOPS(unsigned int & dataLength)
{
bson_append_double(&b, "customGravityX", double(customGravityX));
bson_append_double(&b, "customGravityY", double(customGravityY));
if (!(SAVE_VERSION < 97)) //Allow saves to be opened until version set
RESTRICTVERSION(97, 0);
RESTRICTVERSION(97, 0);
}
bson_append_start_object(&b, "minimumVersion");
bson_append_int(&b, "major", minimumMajorVersion);

View File

@ -7,19 +7,28 @@ DirectionSelector::DirectionSelector(ui::Point position, float radius):
radius(radius),
maxRadius(radius - (radius / 4)),
useSnapPoints(false),
snapPointRadius(0),
snapPoints(std::vector<ui::Point>()),
autoReturn(false),
backgroundColor(ui::Colour(0, 0, 0, 63)),
foregroundColor(ui::Colour(31, 31, 31, 127)),
foregroundColor(ui::Colour(63, 63, 63, 127)),
borderColor(ui::Colour(255, 255, 255)),
snapPointColor(ui::Colour(63, 63, 63, 127)),
updateCallback(nullptr),
changeCallback(nullptr),
mouseDown(false),
mouseHover(false),
altDown(false),
offset(ui::Point(0, 0))
{
}
void DirectionSelector::CheckHovering(int x, int y)
{
mouseHover = std::hypot((offset.X + radius) - x, (offset.Y + radius) - y) < radius / 4;
}
void DirectionSelector::SetSnapPoints(int newRadius, int points)
{
snapPointRadius = newRadius;
@ -74,14 +83,13 @@ void DirectionSelector::SetPosition(float x, float y)
offset.Y = y;
}
if (useSnapPoints)
if (useSnapPoints && !altDown)
{
std::vector<ui::Point>::iterator i;
for (i = snapPoints.begin(); i < snapPoints.end(); i++)
if (std::hypot(i->X - offset.X, i->Y - offset.Y) <= snapPointRadius)
for (const ui::Point& i : snapPoints)
if (std::hypot(i.X - offset.X, i.Y - offset.Y) <= snapPointRadius)
{
offset.X = i->X;
offset.Y = i->Y;
offset.X = i.X;
offset.Y = i.Y;
}
}
if (updateCallback)
@ -101,19 +109,15 @@ void DirectionSelector::Draw(const ui::Point& screenPos)
g->fillcircle(center.X, center.Y, radius, radius, backgroundColor.Red, backgroundColor.Green, backgroundColor.Blue, backgroundColor.Alpha);
g->drawcircle(center.X, center.Y, radius, radius, borderColor.Red, borderColor.Green, borderColor.Blue, borderColor.Alpha);
if (useSnapPoints)
{
std::vector<ui::Point>::iterator i;
for (i = snapPoints.begin(); i < snapPoints.end(); i++)
g->fillrect(
(center.X + i->X) - (radius / 30),
(center.Y + i->Y) - (radius / 30),
radius / 10, radius / 10,
snapPointColor.Red, snapPointColor.Green, snapPointColor.Blue, snapPointColor.Green
);
}
for (const ui::Point& i : snapPoints)
g->fillrect(
(center.X + i.X) - (radius / 30),
(center.Y + i.Y) - (radius / 30),
radius / 10, radius / 10,
snapPointColor.Red, snapPointColor.Green, snapPointColor.Blue, altDown ? (int)(snapPointColor.Alpha / 2) : snapPointColor.Alpha
);
g->fillcircle(center.X + offset.X, center.Y + offset.Y, radius / 4, radius / 4, foregroundColor.Red, foregroundColor.Green, foregroundColor.Blue, foregroundColor.Alpha);
g->fillcircle(center.X + offset.X, center.Y + offset.Y, radius / 4, radius / 4, foregroundColor.Red, foregroundColor.Green, foregroundColor.Blue, mouseHover ? std::min((int)(foregroundColor.Alpha * 1.5f), 255) : foregroundColor.Alpha);
g->drawcircle(center.X + offset.X, center.Y + offset.Y, radius / 4, radius / 4, borderColor.Red, borderColor.Green, borderColor.Blue, borderColor.Alpha);
}
@ -121,12 +125,14 @@ void DirectionSelector::OnMouseMoved(int x, int y, int dx, int dy)
{
if (mouseDown)
SetPositionAbs(x, y);
CheckHovering(x, y);
}
void DirectionSelector::OnMouseClick(int x, int y, unsigned button)
{
mouseDown = true;
SetPositionAbs(x, y);
CheckHovering(x, y);
}
void DirectionSelector::OnMouseUp(int x, int y, unsigned button)
@ -134,6 +140,7 @@ void DirectionSelector::OnMouseUp(int x, int y, unsigned button)
mouseDown = false;
if (autoReturn)
SetPosition(0, 0);
CheckHovering(x - Position.X, y - Position.Y);
if (changeCallback)
changeCallback(GetXValue(), GetYValue());

View File

@ -24,7 +24,7 @@ class DirectionSelector : public ui::Component
std::vector<ui::Point> snapPoints;
bool autoReturn;
ui::Colour backgroundColor;
ui::Colour foregroundColor;
ui::Colour borderColor;
@ -34,9 +34,13 @@ class DirectionSelector : public ui::Component
std::function<void(float x, float y)> changeCallback;
bool mouseDown;
bool mouseHover;
bool altDown;
ui::Point offset;
void CheckHovering(int x, int y);
public:
DirectionSelector(ui::Point position, float radius);
virtual ~DirectionSelector() = default;
@ -44,9 +48,12 @@ public:
void SetSnapPoints(int newRadius, int points);
void ClearSnapPoints();
inline void EnableSnapPoints() { useSnapPoints = true; }
inline void DisableSnapPoints() { useSnapPoints = false; }
inline void EnableAutoReturn() { autoReturn = true; }
inline void DisableAutoReturn() { autoReturn = false; }
inline void SetBackgroundColor(ui::Colour color) { backgroundColor = color; }
inline void SetForegroundColor(ui::Colour color) { foregroundColor = color; }
inline void SetBorderColor(ui::Colour color) { borderColor = color; }
@ -64,6 +71,8 @@ public:
void OnMouseMoved(int x, int y, int dx, int dy) override;
void OnMouseClick(int x, int y, unsigned int button) override;
void OnMouseUp(int x, int y, unsigned button) override;
inline void OnKeyPress(int key, int scan, bool repeat, bool shift, bool ctrl, bool alt) override { altDown = alt; }
inline void OnKeyRelease(int key, int scan, bool repeat, bool shift, bool ctrl, bool alt) override { altDown = alt; }
inline void SetUpdateCallback(std::function<void(float x, float y)> callback) { updateCallback = callback; }
inline void SetChangeCallback(std::function<void(float x, float y)> callback) { changeCallback = callback; }

View File

@ -190,17 +190,26 @@ OptionsView::OptionsView():
labelX->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
labelX->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
StringBuilder temp;
temp << "X:" << std::round(x * 10) / 10;
labelX->SetText(temp.Build());
AddComponent(labelX);
labelY->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
labelY->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
temp = StringBuilder();
temp << "Y:" << std::round(y * 10) / 10;
labelY->SetText(temp.Build());
AddComponent(labelY);
labelTotal->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
labelTotal->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
temp = StringBuilder();
temp << "Total:" << std::round(std::hypot(x, y) * 10) / 10;
labelTotal->SetText(temp.Build());
AddComponent(labelTotal);
gravityDirection->SetSnapPoints(5, 4);
gravityDirection->SetValues(x / 1.5f, y / 1.5f);
gravityDirection->SetUpdateCallback([this](float x, float y) {
StringBuilder temp;
temp << "X:" << std::round(x * 15) / 10;
@ -214,7 +223,7 @@ OptionsView::OptionsView():
temp << "Total:" << std::round(gravityDirection->GetTotalValue() * 15) / 10;
labelTotal->SetText(temp.Build());
});
gravityDirection->SetValues(x, y);
gravityDirection->SetSnapPoints(5, 4);
AddComponent(gravityDirection);
ui::Button * okayButton = new ui::Button(ui::Point(0, Size.Y - 17), ui::Point(Size.X, 17), "OK");
@ -527,8 +536,8 @@ void OptionsView::NotifySettingsChanged(OptionsModel * sender)
ambientAirTemp->SetText(sb.Build());
}
gravityMode->SetOption(sender->GetGravityMode());
customGravityX = sender->GetCustomGravityX() / 1.5;
customGravityY = sender->GetCustomGravityY() / 1.5;
customGravityX = sender->GetCustomGravityX();
customGravityY = sender->GetCustomGravityY();
decoSpace->SetOption(sender->GetDecoSpace());
edgeMode->SetOption(sender->GetEdgeMode());
scale->SetOption(sender->GetScale());

View File

@ -11,7 +11,6 @@ namespace ui
class DropDown;
class Textbox;
class Button;
class DirectionSelector;
}
class OptionsModel;

View File

@ -1974,6 +1974,12 @@ int LuaScriptInterface::simulation_customGravity(lua_State * l)
lua_pushnumber(l, luacon_sim->customGravityY);
return 2;
}
else if (acount == 1)
{
luacon_sim->customGravityX = 0.0f;
luacon_sim->customGravityY = luaL_optnumber(l, 1, 0.0f);
return 0;
}
luacon_sim->customGravityX = luaL_optnumber(l, 1, 0.0f);
luacon_sim->customGravityY = luaL_optnumber(l, 2, 0.0f);
return 0;

View File

@ -2837,15 +2837,16 @@ int Simulation::try_move(int i, int x, int y, int nx, int ny)
break;
case PT_CNCT:
{
float offsetX, offsetY; // Calculate offset from gravity
GetGravityField(x, y, 1.0f, 1.0f, offsetX, offsetY);
if (offsetX > 0.0f) offsetX = 1.0f;
else if (offsetX < 0.0f) offsetX = -1.0f;
if (offsetY > 0.0f) offsetY = 1.0f;
else if (offsetY < 0.0f) offsetY = -1.0f;
if (((nx - x) * offsetX > 0 || offsetX == 0.0f) && // Check direction based on gravity
((ny - y) * offsetY > 0 || offsetY == 0.0f) &&
(TYP(pmap[y+(int)offsetY][x+(int)offsetX]) == PT_CNCT || TYP(pmap[y+(int)offsetY][x+(int)offsetX]) == PT_ROCK)) //check below CNCT for another CNCT or ROCK
float cnctGravX, cnctGravY; // Calculate offset from gravity
GetGravityField(x, y, elements[PT_CNCT].Gravity, elements[PT_CNCT].Gravity, cnctGravX, cnctGravY);
int offsetX = 0, offsetY = 0;
if (cnctGravX > 0.0f) offsetX++;
else if (cnctGravX < 0.0f) offsetX--;
if (cnctGravY > 0.0f) offsetY++;
else if (cnctGravY < 0.0f) offsetY--;
if ((offsetX != 0) != (offsetY != 0) && // Is this a different position (avoid diagonals, doesn't work well)
((nx - x) * offsetX > 0 || (ny - y) * offsetY > 0) && // Is the destination particle below the moving particle
(TYP(pmap[y+offsetY][x+offsetX]) == PT_CNCT || TYP(pmap[y+offsetY][x+offsetX]) == PT_ROCK)) //check below CNCT for another CNCT or ROCK
return 0;
}
break;
@ -3637,12 +3638,12 @@ void Simulation::UpdateParticles(int start, int end)
if (pGravX != 0 || pGravY != 0)
{
// Calculate offset from gravity
float convX, convY;
GetGravityField(x, y, -2.0f, -2.0f, convX, convY);
convX += x;
convY += y;
if ((int)convX >= 0 && (int)convX < XRES && (int)convY >= 0 && (int)convY < YRES && (elements[t].Properties&TYPE_LIQUID) && (t!=PT_GEL || gel_scale > (1 + RNG::Ref().between(0, 254)))) {//some heat convection for liquids
r = pmap[(int)convY][(int)convX];
float convGravX, convGravY;
GetGravityField(x, y, -2.0f, -2.0f, convGravX, convGravY);
int offsetX = std::round(convGravX + x);
int offsetY = std::round(convGravY + y);
if (offsetX >= 0 && offsetX < XRES && offsetY >= 0 && offsetY < YRES && (elements[t].Properties&TYPE_LIQUID) && (t!=PT_GEL || gel_scale > (1 + RNG::Ref().between(0, 254)))) {//some heat convection for liquids
r = pmap[offsetY][offsetX];
if (!(!r || parts[i].type != TYP(r))) {
if (parts[i].temp>parts[ID(r)].temp) {
swappage = parts[i].temp;