Add custom gravity mode and replace hardcoded gravity interactions (#820)
Co-authored-by: Tamás Bálint Misius <lbphacker@gmail.com>
This commit is contained in:
parent
a0016a2b9c
commit
6aa68adbf4
@ -26,6 +26,8 @@ GameSave::GameSave(const GameSave & save):
|
|||||||
aheatEnable(save.aheatEnable),
|
aheatEnable(save.aheatEnable),
|
||||||
paused(save.paused),
|
paused(save.paused),
|
||||||
gravityMode(save.gravityMode),
|
gravityMode(save.gravityMode),
|
||||||
|
customGravityX(save.customGravityX),
|
||||||
|
customGravityY(save.customGravityY),
|
||||||
airMode(save.airMode),
|
airMode(save.airMode),
|
||||||
ambientAirTemp(save.ambientAirTemp),
|
ambientAirTemp(save.ambientAirTemp),
|
||||||
edgeMode(save.edgeMode),
|
edgeMode(save.edgeMode),
|
||||||
@ -174,6 +176,8 @@ void GameSave::InitVars()
|
|||||||
aheatEnable = false;
|
aheatEnable = false;
|
||||||
paused = false;
|
paused = false;
|
||||||
gravityMode = 0;
|
gravityMode = 0;
|
||||||
|
customGravityX = 0.0f;
|
||||||
|
customGravityY = 0.0f;
|
||||||
airMode = 0;
|
airMode = 0;
|
||||||
ambientAirTemp = R_TEMP + 273.15f;
|
ambientAirTemp = R_TEMP + 273.15f;
|
||||||
edgeMode = 0;
|
edgeMode = 0;
|
||||||
@ -702,6 +706,8 @@ void GameSave::readOPS(char * data, int dataLength)
|
|||||||
CheckBsonFieldBool(iter, "waterEEnabled", &waterEEnabled);
|
CheckBsonFieldBool(iter, "waterEEnabled", &waterEEnabled);
|
||||||
CheckBsonFieldBool(iter, "paused", &paused);
|
CheckBsonFieldBool(iter, "paused", &paused);
|
||||||
CheckBsonFieldInt(iter, "gravityMode", &gravityMode);
|
CheckBsonFieldInt(iter, "gravityMode", &gravityMode);
|
||||||
|
CheckBsonFieldFloat(iter, "customGravityX", &customGravityX);
|
||||||
|
CheckBsonFieldFloat(iter, "customGravityY", &customGravityY);
|
||||||
CheckBsonFieldInt(iter, "airMode", &airMode);
|
CheckBsonFieldInt(iter, "airMode", &airMode);
|
||||||
CheckBsonFieldFloat(iter, "ambientAirTemp", &ambientAirTemp);
|
CheckBsonFieldFloat(iter, "ambientAirTemp", &ambientAirTemp);
|
||||||
CheckBsonFieldInt(iter, "edgeMode", &edgeMode);
|
CheckBsonFieldInt(iter, "edgeMode", &edgeMode);
|
||||||
@ -2614,6 +2620,12 @@ char * GameSave::serialiseOPS(unsigned int & dataLength)
|
|||||||
bson_append_string(&b, "platform", IDENT_PLATFORM);
|
bson_append_string(&b, "platform", IDENT_PLATFORM);
|
||||||
bson_append_string(&b, "builtType", IDENT_BUILD);
|
bson_append_string(&b, "builtType", IDENT_BUILD);
|
||||||
bson_append_finish_object(&b);
|
bson_append_finish_object(&b);
|
||||||
|
if (gravityMode == 3)
|
||||||
|
{
|
||||||
|
bson_append_double(&b, "customGravityX", double(customGravityX));
|
||||||
|
bson_append_double(&b, "customGravityY", double(customGravityY));
|
||||||
|
RESTRICTVERSION(97, 0);
|
||||||
|
}
|
||||||
bson_append_start_object(&b, "minimumVersion");
|
bson_append_start_object(&b, "minimumVersion");
|
||||||
bson_append_int(&b, "major", minimumMajorVersion);
|
bson_append_int(&b, "major", minimumMajorVersion);
|
||||||
bson_append_int(&b, "minor", minimumMinorVersion);
|
bson_append_int(&b, "minor", minimumMinorVersion);
|
||||||
|
@ -95,6 +95,8 @@ public:
|
|||||||
bool aheatEnable;
|
bool aheatEnable;
|
||||||
bool paused;
|
bool paused;
|
||||||
int gravityMode;
|
int gravityMode;
|
||||||
|
float customGravityX;
|
||||||
|
float customGravityY;
|
||||||
int airMode;
|
int airMode;
|
||||||
float ambientAirTemp;
|
float ambientAirTemp;
|
||||||
int edgeMode;
|
int edgeMode;
|
||||||
|
@ -809,7 +809,7 @@ void GameController::ResetSpark()
|
|||||||
|
|
||||||
void GameController::SwitchGravity()
|
void GameController::SwitchGravity()
|
||||||
{
|
{
|
||||||
gameModel->GetSimulation()->gravityMode = (gameModel->GetSimulation()->gravityMode+1)%3;
|
gameModel->GetSimulation()->gravityMode = (gameModel->GetSimulation()->gravityMode+1)%4;
|
||||||
|
|
||||||
switch (gameModel->GetSimulation()->gravityMode)
|
switch (gameModel->GetSimulation()->gravityMode)
|
||||||
{
|
{
|
||||||
@ -822,6 +822,9 @@ void GameController::SwitchGravity()
|
|||||||
case 2:
|
case 2:
|
||||||
gameModel->SetInfoTip("Gravity: Radial");
|
gameModel->SetInfoTip("Gravity: Radial");
|
||||||
break;
|
break;
|
||||||
|
case 3:
|
||||||
|
gameModel->SetInfoTip("Gravity: Custom");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -954,6 +954,8 @@ void GameModel::SetSave(SaveInfo * newSave, bool invertIncludePressure)
|
|||||||
GameSave * saveData = currentSave->GetGameSave();
|
GameSave * saveData = currentSave->GetGameSave();
|
||||||
SetPaused(saveData->paused | GetPaused());
|
SetPaused(saveData->paused | GetPaused());
|
||||||
sim->gravityMode = saveData->gravityMode;
|
sim->gravityMode = saveData->gravityMode;
|
||||||
|
sim->customGravityX = saveData->customGravityX;
|
||||||
|
sim->customGravityY = saveData->customGravityY;
|
||||||
sim->air->airMode = saveData->airMode;
|
sim->air->airMode = saveData->airMode;
|
||||||
sim->air->ambientAirTemp = saveData->ambientAirTemp;
|
sim->air->ambientAirTemp = saveData->ambientAirTemp;
|
||||||
sim->edgeMode = saveData->edgeMode;
|
sim->edgeMode = saveData->edgeMode;
|
||||||
@ -1016,6 +1018,8 @@ void GameModel::SetSaveFile(SaveFile * newSave, bool invertIncludePressure)
|
|||||||
GameSave * saveData = newSave->GetGameSave();
|
GameSave * saveData = newSave->GetGameSave();
|
||||||
SetPaused(saveData->paused | GetPaused());
|
SetPaused(saveData->paused | GetPaused());
|
||||||
sim->gravityMode = saveData->gravityMode;
|
sim->gravityMode = saveData->gravityMode;
|
||||||
|
sim->customGravityX = saveData->customGravityX;
|
||||||
|
sim->customGravityY = saveData->customGravityY;
|
||||||
sim->air->airMode = saveData->airMode;
|
sim->air->airMode = saveData->airMode;
|
||||||
sim->air->ambientAirTemp = saveData->ambientAirTemp;
|
sim->air->ambientAirTemp = saveData->ambientAirTemp;
|
||||||
sim->edgeMode = saveData->edgeMode;
|
sim->edgeMode = saveData->edgeMode;
|
||||||
@ -1329,6 +1333,8 @@ void GameModel::ClearSimulation()
|
|||||||
{
|
{
|
||||||
//Load defaults
|
//Load defaults
|
||||||
sim->gravityMode = 0;
|
sim->gravityMode = 0;
|
||||||
|
sim->customGravityX = 0.0f;
|
||||||
|
sim->customGravityY = 0.0f;
|
||||||
sim->air->airMode = 0;
|
sim->air->airMode = 0;
|
||||||
sim->legacy_enable = false;
|
sim->legacy_enable = false;
|
||||||
sim->water_equal_test = false;
|
sim->water_equal_test = false;
|
||||||
|
150
src/gui/interface/DirectionSelector.cpp
Normal file
150
src/gui/interface/DirectionSelector.cpp
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
#include "DirectionSelector.h"
|
||||||
|
|
||||||
|
namespace ui {
|
||||||
|
|
||||||
|
DirectionSelector::DirectionSelector(ui::Point position, float radius):
|
||||||
|
ui::Component(position, ui::Point(radius * 2, radius * 2)),
|
||||||
|
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(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;
|
||||||
|
snapPoints.clear();
|
||||||
|
snapPoints.push_back(ui::Point(0, 0));
|
||||||
|
for (int i = 1; i < points; i++)
|
||||||
|
{
|
||||||
|
int dist = ((float)i / (float)(points - 1)) * maxRadius;
|
||||||
|
snapPoints.push_back(ui::Point(0, dist));
|
||||||
|
snapPoints.push_back(ui::Point(0, -1 * dist));
|
||||||
|
snapPoints.push_back(ui::Point(-1 * dist, 0));
|
||||||
|
snapPoints.push_back(ui::Point(dist, 0));
|
||||||
|
}
|
||||||
|
useSnapPoints = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirectionSelector::ClearSnapPoints()
|
||||||
|
{
|
||||||
|
useSnapPoints = false;
|
||||||
|
snapPoints.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
float DirectionSelector::GetXValue()
|
||||||
|
{
|
||||||
|
return offset.X / maxRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
float DirectionSelector::GetYValue()
|
||||||
|
{
|
||||||
|
return offset.Y / maxRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
float DirectionSelector::GetTotalValue()
|
||||||
|
{
|
||||||
|
return std::hypot(offset.X, offset.Y) / maxRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirectionSelector::SetPositionAbs(float absx, float absy)
|
||||||
|
{
|
||||||
|
SetPosition(absx - radius, absy - radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirectionSelector::SetPosition(float x, float y)
|
||||||
|
{
|
||||||
|
if (std::hypot(x, y) > maxRadius)
|
||||||
|
{
|
||||||
|
offset.X = (maxRadius * x) / std::hypot(x, y);
|
||||||
|
offset.Y = (maxRadius * y) / std::hypot(x, y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
offset.X = x;
|
||||||
|
offset.Y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useSnapPoints && !altDown)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (updateCallback)
|
||||||
|
updateCallback(GetXValue(), GetYValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirectionSelector::SetValues(float x, float y)
|
||||||
|
{
|
||||||
|
SetPosition(x * maxRadius, y * maxRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirectionSelector::Draw(const ui::Point& screenPos)
|
||||||
|
{
|
||||||
|
Graphics * g = GetGraphics();
|
||||||
|
ui::Point center = screenPos + radius;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
mouseDown = false;
|
||||||
|
if (autoReturn)
|
||||||
|
SetPosition(0, 0);
|
||||||
|
CheckHovering(x - Position.X, y - Position.Y);
|
||||||
|
|
||||||
|
if (changeCallback)
|
||||||
|
changeCallback(GetXValue(), GetYValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
86
src/gui/interface/DirectionSelector.h
Normal file
86
src/gui/interface/DirectionSelector.h
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#ifndef DIRECTIONSELECTOR_H_
|
||||||
|
#define DIRECTIONSELECTOR_H_
|
||||||
|
|
||||||
|
#include "Component.h"
|
||||||
|
#include "Colour.h"
|
||||||
|
#include "graphics/Graphics.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <vector>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace ui {
|
||||||
|
|
||||||
|
class DirectionSelector : public ui::Component
|
||||||
|
{
|
||||||
|
const float radius;
|
||||||
|
const float maxRadius;
|
||||||
|
|
||||||
|
bool useSnapPoints;
|
||||||
|
int snapPointRadius;
|
||||||
|
|
||||||
|
std::vector<ui::Point> snapPoints;
|
||||||
|
|
||||||
|
bool autoReturn;
|
||||||
|
|
||||||
|
ui::Colour backgroundColor;
|
||||||
|
ui::Colour foregroundColor;
|
||||||
|
ui::Colour borderColor;
|
||||||
|
ui::Colour snapPointColor;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using DirectionSelectorCallback = std::function<void(float x, float y)>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DirectionSelectorCallback updateCallback;
|
||||||
|
DirectionSelectorCallback 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;
|
||||||
|
|
||||||
|
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; }
|
||||||
|
inline void SetSnapPointColor(ui::Colour color) { snapPointColor = color; }
|
||||||
|
|
||||||
|
float GetXValue();
|
||||||
|
float GetYValue();
|
||||||
|
float GetTotalValue();
|
||||||
|
|
||||||
|
void SetPositionAbs(float absx, float absy);
|
||||||
|
void SetPosition(float x, float y);
|
||||||
|
void SetValues(float x, float y);
|
||||||
|
|
||||||
|
void Draw(const ui::Point& screenPos) override;
|
||||||
|
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(DirectionSelectorCallback callback) { updateCallback = callback; }
|
||||||
|
inline void SetChangeCallback(DirectionSelectorCallback callback) { changeCallback = callback; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace ui */
|
||||||
|
#endif /* DIRECTIONSELECTOR_H_ */
|
@ -5,6 +5,7 @@ gui_files += files(
|
|||||||
'Component.cpp',
|
'Component.cpp',
|
||||||
'ContextMenu.cpp',
|
'ContextMenu.cpp',
|
||||||
'CopyTextButton.cpp',
|
'CopyTextButton.cpp',
|
||||||
|
'DirectionSelector.cpp',
|
||||||
'DropDown.cpp',
|
'DropDown.cpp',
|
||||||
'Engine.cpp',
|
'Engine.cpp',
|
||||||
'Label.cpp',
|
'Label.cpp',
|
||||||
|
@ -42,6 +42,16 @@ void OptionsController::SetGravityMode(int gravityMode)
|
|||||||
model->SetGravityMode(gravityMode);
|
model->SetGravityMode(gravityMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OptionsController::SetCustomGravityX(float x)
|
||||||
|
{
|
||||||
|
model->SetCustomGravityX(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OptionsController::SetCustomGravityY(float y)
|
||||||
|
{
|
||||||
|
model->SetCustomGravityY(y);
|
||||||
|
}
|
||||||
|
|
||||||
void OptionsController::SetAirMode(int airMode)
|
void OptionsController::SetAirMode(int airMode)
|
||||||
{
|
{
|
||||||
model->SetAirMode(airMode);
|
model->SetAirMode(airMode);
|
||||||
|
@ -21,6 +21,8 @@ public:
|
|||||||
void SetNewtonianGravity(bool state);
|
void SetNewtonianGravity(bool state);
|
||||||
void SetWaterEqualisation(bool state);
|
void SetWaterEqualisation(bool state);
|
||||||
void SetGravityMode(int gravityMode);
|
void SetGravityMode(int gravityMode);
|
||||||
|
void SetCustomGravityX(float x);
|
||||||
|
void SetCustomGravityY(float y);
|
||||||
void SetAirMode(int airMode);
|
void SetAirMode(int airMode);
|
||||||
void SetAmbientAirTemperature(float ambientAirTemp);
|
void SetAmbientAirTemperature(float ambientAirTemp);
|
||||||
void SetEdgeMode(int edgeMode);
|
void SetEdgeMode(int edgeMode);
|
||||||
|
@ -111,6 +111,28 @@ void OptionsModel::SetGravityMode(int gravityMode)
|
|||||||
notifySettingsChanged();
|
notifySettingsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float OptionsModel::GetCustomGravityX()
|
||||||
|
{
|
||||||
|
return sim->customGravityX;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OptionsModel::SetCustomGravityX(float x)
|
||||||
|
{
|
||||||
|
sim->customGravityX = x;
|
||||||
|
notifySettingsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
float OptionsModel::GetCustomGravityY()
|
||||||
|
{
|
||||||
|
return sim->customGravityY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OptionsModel::SetCustomGravityY(float y)
|
||||||
|
{
|
||||||
|
sim->customGravityY = y;
|
||||||
|
notifySettingsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
int OptionsModel::GetScale()
|
int OptionsModel::GetScale()
|
||||||
{
|
{
|
||||||
return ui::Engine::Ref().GetScale();
|
return ui::Engine::Ref().GetScale();
|
||||||
|
@ -34,6 +34,10 @@ public:
|
|||||||
void SetEdgeMode(int edgeMode);
|
void SetEdgeMode(int edgeMode);
|
||||||
int GetGravityMode();
|
int GetGravityMode();
|
||||||
void SetGravityMode(int gravityMode);
|
void SetGravityMode(int gravityMode);
|
||||||
|
float GetCustomGravityX();
|
||||||
|
void SetCustomGravityX(float x);
|
||||||
|
float GetCustomGravityY();
|
||||||
|
void SetCustomGravityY(float y);
|
||||||
int GetScale();
|
int GetScale();
|
||||||
void SetScale(int scale);
|
void SetScale(int scale);
|
||||||
bool GetResizable();
|
bool GetResizable();
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <cmath>
|
||||||
#include "SDLCompat.h"
|
#include "SDLCompat.h"
|
||||||
|
|
||||||
#include "OptionsController.h"
|
#include "OptionsController.h"
|
||||||
@ -21,6 +22,7 @@
|
|||||||
#include "gui/interface/Engine.h"
|
#include "gui/interface/Engine.h"
|
||||||
#include "gui/interface/Label.h"
|
#include "gui/interface/Label.h"
|
||||||
#include "gui/interface/Textbox.h"
|
#include "gui/interface/Textbox.h"
|
||||||
|
#include "gui/interface/DirectionSelector.h"
|
||||||
|
|
||||||
OptionsView::OptionsView():
|
OptionsView::OptionsView():
|
||||||
ui::Window(ui::Point(-1, -1), ui::Point(320, 340))
|
ui::Window(ui::Point(-1, -1), ui::Point(320, 340))
|
||||||
@ -143,7 +145,82 @@ OptionsView::OptionsView():
|
|||||||
gravityMode->AddOption(std::pair<String, int>("Vertical", 0));
|
gravityMode->AddOption(std::pair<String, int>("Vertical", 0));
|
||||||
gravityMode->AddOption(std::pair<String, int>("Off", 1));
|
gravityMode->AddOption(std::pair<String, int>("Off", 1));
|
||||||
gravityMode->AddOption(std::pair<String, int>("Radial", 2));
|
gravityMode->AddOption(std::pair<String, int>("Radial", 2));
|
||||||
gravityMode->SetActionCallback({ [this] { c->SetGravityMode(gravityMode->GetOption().second); } });
|
gravityMode->AddOption(std::pair<String, int>("Custom", 3));
|
||||||
|
|
||||||
|
class GravityWindow : public ui::Window
|
||||||
|
{
|
||||||
|
void OnTryExit(ExitMethod method)
|
||||||
|
{
|
||||||
|
CloseActiveWindow();
|
||||||
|
SelfDestruct();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDraw()
|
||||||
|
{
|
||||||
|
Graphics * g = GetGraphics();
|
||||||
|
|
||||||
|
g->clearrect(Position.X-2, Position.Y-2, Size.X+3, Size.Y+3);
|
||||||
|
g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 200, 200, 200, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui::DirectionSelector * gravityDirection;
|
||||||
|
ui::Label * labelValues;
|
||||||
|
|
||||||
|
OptionsController * c;
|
||||||
|
|
||||||
|
public:
|
||||||
|
GravityWindow(ui::Point position, int radius, float x, float y, OptionsController * c_):
|
||||||
|
ui::Window(position, ui::Point((radius * 2) + 20, (radius * 2) + 75)),
|
||||||
|
gravityDirection(new ui::DirectionSelector(ui::Point(10, 32), radius)),
|
||||||
|
c(c_)
|
||||||
|
{
|
||||||
|
ui::Label * tempLabel = new ui::Label(ui::Point(4, 1), ui::Point(Size.X - 8, 22), "Custom Gravity");
|
||||||
|
tempLabel->SetTextColour(style::Colour::InformationTitle);
|
||||||
|
tempLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
|
||||||
|
tempLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||||
|
AddComponent(tempLabel);
|
||||||
|
|
||||||
|
Separator * tempSeparator = new Separator(ui::Point(0, 22), ui::Point(Size.X, 1));
|
||||||
|
AddComponent(tempSeparator);
|
||||||
|
|
||||||
|
labelValues = new ui::Label(ui::Point(0, (radius * 2) + 37), ui::Point(Size.X, 16), String::Build( "X:", std::round(x * 10.0f) / 10,
|
||||||
|
" Y:", std::round(y * 10.0f) / 10,
|
||||||
|
" Total:", std::round(std::hypot(x, y) * 10.0f) / 10));
|
||||||
|
labelValues->Appearance.HorizontalAlign = ui::Appearance::AlignCentre;
|
||||||
|
labelValues->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||||
|
AddComponent(labelValues);
|
||||||
|
|
||||||
|
gravityDirection->SetValues(x / 2.0f, y / 2.0f);
|
||||||
|
gravityDirection->SetUpdateCallback([this](float x, float y) {
|
||||||
|
labelValues->SetText(String::Build( "X:", std::round(x * 20.0f) / 10,
|
||||||
|
" Y:", std::round(y * 20.0f) / 10,
|
||||||
|
" Total:", std::round(gravityDirection->GetTotalValue() * 20.0f) / 10));
|
||||||
|
});
|
||||||
|
gravityDirection->SetSnapPoints(5, 5);
|
||||||
|
AddComponent(gravityDirection);
|
||||||
|
|
||||||
|
ui::Button * okayButton = new ui::Button(ui::Point(0, Size.Y - 17), ui::Point(Size.X, 17), "OK");
|
||||||
|
okayButton->Appearance.HorizontalAlign = ui::Appearance::AlignCentre;
|
||||||
|
okayButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||||
|
okayButton->Appearance.BorderInactive = ui::Colour(200, 200, 200);
|
||||||
|
okayButton->SetActionCallback({ [this] {
|
||||||
|
c->SetCustomGravityX(gravityDirection->GetXValue() * 2.0f);
|
||||||
|
c->SetCustomGravityY(gravityDirection->GetYValue() * 2.0f);
|
||||||
|
CloseActiveWindow();
|
||||||
|
SelfDestruct();
|
||||||
|
} });
|
||||||
|
AddComponent(okayButton);
|
||||||
|
SetOkayButton(okayButton);
|
||||||
|
|
||||||
|
MakeActiveWindow();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
gravityMode->SetActionCallback({ [this] {
|
||||||
|
c->SetGravityMode(gravityMode->GetOption().second);
|
||||||
|
if (gravityMode->GetOption().second == 3)
|
||||||
|
new GravityWindow(ui::Point(-1, -1), 50, customGravityX, customGravityY, c);
|
||||||
|
} });
|
||||||
|
|
||||||
tempLabel = new ui::Label(ui::Point(8, currentY), ui::Point(Size.X-96, 16), "Gravity Simulation Mode");
|
tempLabel = new ui::Label(ui::Point(8, currentY), ui::Point(Size.X-96, 16), "Gravity Simulation Mode");
|
||||||
tempLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
|
tempLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
|
||||||
@ -432,6 +509,8 @@ void OptionsView::NotifySettingsChanged(OptionsModel * sender)
|
|||||||
ambientAirTemp->SetText(sb.Build());
|
ambientAirTemp->SetText(sb.Build());
|
||||||
}
|
}
|
||||||
gravityMode->SetOption(sender->GetGravityMode());
|
gravityMode->SetOption(sender->GetGravityMode());
|
||||||
|
customGravityX = sender->GetCustomGravityX();
|
||||||
|
customGravityY = sender->GetCustomGravityY();
|
||||||
decoSpace->SetOption(sender->GetDecoSpace());
|
decoSpace->SetOption(sender->GetDecoSpace());
|
||||||
edgeMode->SetOption(sender->GetEdgeMode());
|
edgeMode->SetOption(sender->GetEdgeMode());
|
||||||
scale->SetOption(sender->GetScale());
|
scale->SetOption(sender->GetScale());
|
||||||
|
@ -40,6 +40,7 @@ class OptionsView: public ui::Window
|
|||||||
ui::Checkbox * includePressure;
|
ui::Checkbox * includePressure;
|
||||||
ui::Checkbox * perfectCirclePressure;
|
ui::Checkbox * perfectCirclePressure;
|
||||||
ui::ScrollPanel * scrollPanel;
|
ui::ScrollPanel * scrollPanel;
|
||||||
|
float customGravityX, customGravityY;
|
||||||
bool initializedAirTempPreview = false;
|
bool initializedAirTempPreview = false;
|
||||||
void UpdateAmbientAirTempPreview(float airTemp, bool isValid);
|
void UpdateAmbientAirTempPreview(float airTemp, bool isValid);
|
||||||
void UpdateAirTemp(String temp, bool isDefocus);
|
void UpdateAirTemp(String temp, bool isDefocus);
|
||||||
|
@ -842,6 +842,7 @@ void LuaScriptInterface::initSimulationAPI()
|
|||||||
{"gravityGrid", simulation_gravityGrid},
|
{"gravityGrid", simulation_gravityGrid},
|
||||||
{"edgeMode", simulation_edgeMode},
|
{"edgeMode", simulation_edgeMode},
|
||||||
{"gravityMode", simulation_gravityMode},
|
{"gravityMode", simulation_gravityMode},
|
||||||
|
{"customGravity", simulation_customGravity},
|
||||||
{"airMode", simulation_airMode},
|
{"airMode", simulation_airMode},
|
||||||
{"waterEqualisation", simulation_waterEqualisation},
|
{"waterEqualisation", simulation_waterEqualisation},
|
||||||
{"waterEqualization", simulation_waterEqualisation},
|
{"waterEqualization", simulation_waterEqualisation},
|
||||||
@ -1964,6 +1965,26 @@ int LuaScriptInterface::simulation_gravityMode(lua_State * l)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LuaScriptInterface::simulation_customGravity(lua_State * l)
|
||||||
|
{
|
||||||
|
int acount = lua_gettop(l);
|
||||||
|
if (acount == 0)
|
||||||
|
{
|
||||||
|
lua_pushnumber(l, luacon_sim->customGravityX);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
int LuaScriptInterface::simulation_airMode(lua_State * l)
|
int LuaScriptInterface::simulation_airMode(lua_State * l)
|
||||||
{
|
{
|
||||||
int acount = lua_gettop(l);
|
int acount = lua_gettop(l);
|
||||||
|
@ -101,6 +101,7 @@ class LuaScriptInterface: public CommandInterface
|
|||||||
static int simulation_gravityGrid(lua_State * l);
|
static int simulation_gravityGrid(lua_State * l);
|
||||||
static int simulation_edgeMode(lua_State * l);
|
static int simulation_edgeMode(lua_State * l);
|
||||||
static int simulation_gravityMode(lua_State * l);
|
static int simulation_gravityMode(lua_State * l);
|
||||||
|
static int simulation_customGravity(lua_State * l);
|
||||||
static int simulation_airMode(lua_State * l);
|
static int simulation_airMode(lua_State * l);
|
||||||
static int simulation_waterEqualisation(lua_State * l);
|
static int simulation_waterEqualisation(lua_State * l);
|
||||||
static int simulation_ambientAirTemp(lua_State * l);
|
static int simulation_ambientAirTemp(lua_State * l);
|
||||||
|
@ -115,13 +115,18 @@ void Air::update_airh(void)
|
|||||||
dh += AIR_VADV*(1.0f-tx)*ty*((bmap_blockairh[j+1][i]&0x8) ? odh : hv[j+1][i]);
|
dh += AIR_VADV*(1.0f-tx)*ty*((bmap_blockairh[j+1][i]&0x8) ? odh : hv[j+1][i]);
|
||||||
dh += AIR_VADV*tx*ty*((bmap_blockairh[j+1][i+1]&0x8) ? odh : hv[j+1][i+1]);
|
dh += AIR_VADV*tx*ty*((bmap_blockairh[j+1][i+1]&0x8) ? odh : hv[j+1][i+1]);
|
||||||
}
|
}
|
||||||
if(!sim.gravityMode)
|
|
||||||
{ //Vertical gravity only for the time being
|
|
||||||
float airdiff = hv[y-1][x]-hv[y][x];
|
|
||||||
if(airdiff>0 && !(bmap_blockairh[y-1][x]&0x8))
|
|
||||||
vy[y][x] -= airdiff/5000.0f;
|
|
||||||
}
|
|
||||||
ohv[y][x] = dh;
|
ohv[y][x] = dh;
|
||||||
|
if (x>=2 && x<XRES/CELL-2 && y>=2 && y<YRES/CELL-2)
|
||||||
|
{
|
||||||
|
float convGravX, convGravY;
|
||||||
|
sim.GetGravityField(x*CELL, y*CELL, -1.0f, -1.0f, convGravX, convGravY);
|
||||||
|
auto weight = ((hv[y][x] - hv[y][x-1]) * convGravX + (hv[y][x] - hv[y-1][x]) * convGravY) / 5000.0f;
|
||||||
|
if (weight > 0 && !(bmap_blockairh[y-1][x]&0x8))
|
||||||
|
{
|
||||||
|
vx[y][x] += weight * convGravX;
|
||||||
|
vy[y][x] += weight * convGravY;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memcpy(hv, ohv, sizeof(hv));
|
memcpy(hv, ohv, sizeof(hv));
|
||||||
|
@ -545,6 +545,8 @@ void Simulation::SaveSimOptions(GameSave * gameSave)
|
|||||||
if (!gameSave)
|
if (!gameSave)
|
||||||
return;
|
return;
|
||||||
gameSave->gravityMode = gravityMode;
|
gameSave->gravityMode = gravityMode;
|
||||||
|
gameSave->customGravityX = customGravityX;
|
||||||
|
gameSave->customGravityY = customGravityY;
|
||||||
gameSave->airMode = air->airMode;
|
gameSave->airMode = air->airMode;
|
||||||
gameSave->ambientAirTemp = air->ambientAirTemp;
|
gameSave->ambientAirTemp = air->ambientAirTemp;
|
||||||
gameSave->edgeMode = edgeMode;
|
gameSave->edgeMode = edgeMode;
|
||||||
@ -2834,8 +2836,19 @@ int Simulation::try_move(int i, int x, int y, int nx, int ny)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PT_CNCT:
|
case PT_CNCT:
|
||||||
if (y < ny && (TYP(pmap[y+1][x]) == PT_CNCT || TYP(pmap[y+1][x]) == 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;
|
return 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PT_GBMB:
|
case PT_GBMB:
|
||||||
if (parts[i].life > 0)
|
if (parts[i].life > 0)
|
||||||
@ -3322,24 +3335,41 @@ int Simulation::create_part(int p, int x, int y, int t, int v)
|
|||||||
|
|
||||||
void Simulation::GetGravityField(int x, int y, float particleGrav, float newtonGrav, float & pGravX, float & pGravY)
|
void Simulation::GetGravityField(int x, int y, float particleGrav, float newtonGrav, float & pGravX, float & pGravY)
|
||||||
{
|
{
|
||||||
pGravX = newtonGrav*gravx[(y/CELL)*(XRES/CELL)+(x/CELL)];
|
|
||||||
pGravY = newtonGrav*gravy[(y/CELL)*(XRES/CELL)+(x/CELL)];
|
|
||||||
switch (gravityMode)
|
switch (gravityMode)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case 0: //normal, vertical gravity
|
case 0: //normal, vertical gravity
|
||||||
pGravY += particleGrav;
|
pGravX = 0;
|
||||||
|
pGravY = particleGrav;
|
||||||
break;
|
break;
|
||||||
case 1: //no gravity
|
case 1: //no gravity
|
||||||
|
pGravX = 0;
|
||||||
|
pGravY = 0;
|
||||||
break;
|
break;
|
||||||
case 2: //radial gravity
|
case 2: //radial gravity
|
||||||
if (x-XCNTR != 0 || y-YCNTR != 0)
|
|
||||||
{
|
{
|
||||||
float pGravMult = particleGrav/sqrtf(float((x-XCNTR)*(x-XCNTR) + (y-YCNTR)*(y-YCNTR)));
|
pGravX = 0;
|
||||||
pGravX -= pGravMult * (float)(x - XCNTR);
|
pGravY = 0;
|
||||||
pGravY -= pGravMult * (float)(y - YCNTR);
|
auto dx = x-XCNTR;
|
||||||
|
auto dy = y-YCNTR;
|
||||||
|
if (dx || dy)
|
||||||
|
{
|
||||||
|
auto pGravD = 0.01f - hypotf(dx, dy);
|
||||||
|
pGravX = particleGrav * (dx / pGravD);
|
||||||
|
pGravY = particleGrav * (dy / pGravD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case 3: //custom gravity
|
||||||
|
pGravX = particleGrav * customGravityX;
|
||||||
|
pGravY = particleGrav * customGravityY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (newtonGrav)
|
||||||
|
{
|
||||||
|
pGravX += newtonGrav*gravx[(y/CELL)*(XRES/CELL)+(x/CELL)];
|
||||||
|
pGravY += newtonGrav*gravy[(y/CELL)*(XRES/CELL)+(x/CELL)];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Simulation::create_gain_photon(int pp)//photons from PHOT going through GLOW
|
void Simulation::create_gain_photon(int pp)//photons from PHOT going through GLOW
|
||||||
@ -3467,7 +3497,6 @@ void Simulation::UpdateParticles(int start, int end)
|
|||||||
int h_count = 0;
|
int h_count = 0;
|
||||||
int surround[8];
|
int surround[8];
|
||||||
int surround_hconduct[8];
|
int surround_hconduct[8];
|
||||||
float pGravX, pGravY, pGravD;
|
|
||||||
bool transitionOccurred;
|
bool transitionOccurred;
|
||||||
|
|
||||||
//the main particle loop function, goes over all particles.
|
//the main particle loop function, goes over all particles.
|
||||||
@ -3538,35 +3567,10 @@ void Simulation::UpdateParticles(int start, int end)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pGravX = pGravY = 0;
|
float pGravX = 0, pGravY = 0;
|
||||||
if (!(elements[t].Properties & TYPE_SOLID))
|
if (!(elements[t].Properties & TYPE_SOLID) && (elements[t].Gravity || elements[t].NewtonianGravity))
|
||||||
{
|
{
|
||||||
if (elements[t].Gravity)
|
GetGravityField(x, y, elements[t].Gravity, elements[t].NewtonianGravity, pGravX, pGravY);
|
||||||
{
|
|
||||||
//Gravity mode by Moach
|
|
||||||
switch (gravityMode)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case 0:
|
|
||||||
pGravX = 0.0f;
|
|
||||||
pGravY = elements[t].Gravity;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
pGravX = pGravY = 0.0f;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
pGravD = 0.01f - hypotf(float(x - XCNTR), float(y - YCNTR));
|
|
||||||
pGravX = elements[t].Gravity * ((float)(x - XCNTR) / pGravD);
|
|
||||||
pGravY = elements[t].Gravity * ((float)(y - YCNTR) / pGravD);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (elements[t].NewtonianGravity)
|
|
||||||
{
|
|
||||||
//Get some gravity from the gravity map
|
|
||||||
pGravX += elements[t].NewtonianGravity * gravx[(y/CELL)*(XRES/CELL)+(x/CELL)];
|
|
||||||
pGravY += elements[t].NewtonianGravity * gravy[(y/CELL)*(XRES/CELL)+(x/CELL)];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//velocity updates for the particle
|
//velocity updates for the particle
|
||||||
@ -3613,8 +3617,14 @@ void Simulation::UpdateParticles(int start, int end)
|
|||||||
|
|
||||||
if (!legacy_enable)
|
if (!legacy_enable)
|
||||||
{
|
{
|
||||||
if (y-2 >= 0 && y-2 < YRES && (elements[t].Properties&TYPE_LIQUID) && (t!=PT_GEL || gel_scale > (1 + RNG::Ref().between(0, 254)))) {//some heat convection for liquids
|
if ((elements[t].Properties&TYPE_LIQUID) && (t!=PT_GEL || gel_scale > (1 + RNG::Ref().between(0, 254))))
|
||||||
r = pmap[y-2][x];
|
{
|
||||||
|
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 != x || offsetY != y) && offsetX >= 0 && offsetX < XRES && offsetY >= 0 && offsetY < YRES) {//some heat convection for liquids
|
||||||
|
r = pmap[offsetY][offsetX];
|
||||||
if (!(!r || parts[i].type != TYP(r))) {
|
if (!(!r || parts[i].type != TYP(r))) {
|
||||||
if (parts[i].temp>parts[ID(r)].temp) {
|
if (parts[i].temp>parts[ID(r)].temp) {
|
||||||
swappage = parts[i].temp;
|
swappage = parts[i].temp;
|
||||||
@ -3623,6 +3633,7 @@ void Simulation::UpdateParticles(int start, int end)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//heat transfer code
|
//heat transfer code
|
||||||
h_count = 0;
|
h_count = 0;
|
||||||
@ -4550,24 +4561,7 @@ killed:
|
|||||||
for (j=0;j<rt;j++)
|
for (j=0;j<rt;j++)
|
||||||
{
|
{
|
||||||
// Calculate overall gravity direction
|
// Calculate overall gravity direction
|
||||||
switch (gravityMode)
|
GetGravityField(nx, ny, ptGrav, 1.0f, pGravX, pGravY);
|
||||||
{
|
|
||||||
default:
|
|
||||||
case 0:
|
|
||||||
pGravX = 0.0f;
|
|
||||||
pGravY = ptGrav;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
pGravX = pGravY = 0.0f;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
pGravD = 0.01f - hypotf(float(nx - XCNTR), float(ny - YCNTR));
|
|
||||||
pGravX = ptGrav * ((float)(nx - XCNTR) / pGravD);
|
|
||||||
pGravY = ptGrav * ((float)(ny - YCNTR) / pGravD);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pGravX += gravx[(ny/CELL)*(XRES/CELL)+(nx/CELL)];
|
|
||||||
pGravY += gravy[(ny/CELL)*(XRES/CELL)+(nx/CELL)];
|
|
||||||
// Scale gravity vector so that the largest component is 1 pixel
|
// Scale gravity vector so that the largest component is 1 pixel
|
||||||
if (fabsf(pGravY)>fabsf(pGravX))
|
if (fabsf(pGravY)>fabsf(pGravX))
|
||||||
mv = fabsf(pGravY);
|
mv = fabsf(pGravY);
|
||||||
@ -4622,24 +4616,7 @@ killed:
|
|||||||
for (j=0;j<rt;j++)
|
for (j=0;j<rt;j++)
|
||||||
{
|
{
|
||||||
// Calculate overall gravity direction
|
// Calculate overall gravity direction
|
||||||
switch (gravityMode)
|
GetGravityField(nx, ny, ptGrav, 1.0f, pGravX, pGravY);
|
||||||
{
|
|
||||||
default:
|
|
||||||
case 0:
|
|
||||||
pGravX = 0.0f;
|
|
||||||
pGravY = ptGrav;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
pGravX = pGravY = 0.0f;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
pGravD = 0.01f - hypotf(float(nx - XCNTR), float(ny - YCNTR));
|
|
||||||
pGravX = ptGrav * ((float)(nx - XCNTR) / pGravD);
|
|
||||||
pGravY = ptGrav * ((float)(ny - YCNTR) / pGravD);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pGravX += gravx[(ny/CELL)*(XRES/CELL)+(nx/CELL)];
|
|
||||||
pGravY += gravy[(ny/CELL)*(XRES/CELL)+(nx/CELL)];
|
|
||||||
// Scale gravity vector so that the largest component is 1 pixel
|
// Scale gravity vector so that the largest component is 1 pixel
|
||||||
if (fabsf(pGravY)>fabsf(pGravX))
|
if (fabsf(pGravY)>fabsf(pGravX))
|
||||||
mv = fabsf(pGravY);
|
mv = fabsf(pGravY);
|
||||||
@ -5272,6 +5249,8 @@ Simulation::Simulation():
|
|||||||
GSPEED(1),
|
GSPEED(1),
|
||||||
edgeMode(0),
|
edgeMode(0),
|
||||||
gravityMode(0),
|
gravityMode(0),
|
||||||
|
customGravityX(0),
|
||||||
|
customGravityY(0),
|
||||||
legacy_enable(0),
|
legacy_enable(0),
|
||||||
aheat_enable(0),
|
aheat_enable(0),
|
||||||
water_equal_test(0),
|
water_equal_test(0),
|
||||||
|
@ -105,6 +105,8 @@ public:
|
|||||||
//Simulation Settings
|
//Simulation Settings
|
||||||
int edgeMode;
|
int edgeMode;
|
||||||
int gravityMode;
|
int gravityMode;
|
||||||
|
float customGravityX;
|
||||||
|
float customGravityY;
|
||||||
int legacy_enable;
|
int legacy_enable;
|
||||||
int aheat_enable;
|
int aheat_enable;
|
||||||
int water_equal_test;
|
int water_equal_test;
|
||||||
|
@ -155,6 +155,10 @@ int Element_STKM_run_stickman(playerst *playerp, UPDATE_FUNC_ARGS)
|
|||||||
gvy = ((float)(parts[i].y - YCNTR) / gravd);
|
gvy = ((float)(parts[i].y - YCNTR) / gravd);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 3:
|
||||||
|
gvx = sim->customGravityX;
|
||||||
|
gvy = sim->customGravityY;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gvx += sim->gravx[((int)parts[i].y/CELL)*(XRES/CELL)+((int)parts[i].x/CELL)];
|
gvx += sim->gravx[((int)parts[i].y/CELL)*(XRES/CELL)+((int)parts[i].x/CELL)];
|
||||||
|
Reference in New Issue
Block a user