Make find mode work with the PROP tool

This commit is contained in:
Tamás Bálint Misius 2023-09-20 07:16:28 +02:00
parent ca6558bd5d
commit ef04068a85
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
14 changed files with 130 additions and 52 deletions

View File

@ -60,7 +60,7 @@ void ParticleDebug::Debug(int mode, int x, int y)
bool ParticleDebug::KeyPress(int key, int scan, bool shift, bool ctrl, bool alt, ui::Point currentMouse) bool ParticleDebug::KeyPress(int key, int scan, bool shift, bool ctrl, bool alt, ui::Point currentMouse)
{ {
if (key == 'f') if (key == 'f' && !ctrl)
{ {
model->SetPaused(1); model->SetPaused(1);
if (alt) if (alt)

View File

@ -0,0 +1,14 @@
#pragma once
#include "simulation/StructProperty.h"
struct FindingElement
{
StructProperty property;
PropertyValue value;
bool operator ==(const FindingElement &other) const
{
return property == other.property &&
value == other.value;
}
};

View File

@ -368,10 +368,41 @@ void Renderer::render_parts()
if(firea>255) firea = 255; if(firea>255) firea = 255;
else if(firea<0) firea = 0; else if(firea<0) firea = 0;
auto matchesFindingElement = false;
if (findingElement) if (findingElement)
{ {
if (TYP(findingElement) == parts[i].type && if (findingElement->property.Offset == offsetof(Particle, type))
(parts[i].type != PT_LIFE || (ID(findingElement) == parts[i].ctype))) {
auto ft = std::get<int>(findingElement->value);
matchesFindingElement = parts[i].type == TYP(ft);
if (ID(ft))
{
matchesFindingElement &= parts[i].ctype == ID(ft);
}
}
else
{
switch (findingElement->property.Type)
{
case StructProperty::Float:
matchesFindingElement = *((float*)(((char*)&sim->parts[i])+findingElement->property.Offset)) == std::get<float>(findingElement->value);
break;
case StructProperty::ParticleType:
case StructProperty::Integer:
matchesFindingElement = *((int*)(((char*)&sim->parts[i])+findingElement->property.Offset)) == std::get<int>(findingElement->value);
break;
case StructProperty::UInteger:
matchesFindingElement = *((unsigned int*)(((char*)&sim->parts[i])+findingElement->property.Offset)) == std::get<unsigned int>(findingElement->value);
break;
default:
break;
}
}
if (matchesFindingElement)
{ {
colr = firer = 255; colr = firer = 255;
colg = fireg = colb = fireb = 0; colg = fireg = colb = fireb = 0;
@ -416,7 +447,7 @@ void Renderer::render_parts()
BlendText(mousePos + Vec2{ -8-2*(sim->parts[i].life<100)-2*(sim->parts[i].life<10), -12 }, hp, 0xFFFFFF_rgb .WithAlpha(255)); BlendText(mousePos + Vec2{ -8-2*(sim->parts[i].life<100)-2*(sim->parts[i].life<10), -12 }, hp, 0xFFFFFF_rgb .WithAlpha(255));
} }
if (findingElement == t) if (matchesFindingElement)
{ {
colr = 255; colr = 255;
colg = colb = 0; colg = colb = 0;
@ -445,7 +476,7 @@ void Renderer::render_parts()
} }
} }
if (findingElement && findingElement == t) if (matchesFindingElement)
{ {
legr = 255; legr = 255;
legg = legb = 0; legg = legb = 0;
@ -469,7 +500,7 @@ void Renderer::render_parts()
legb = 255; legb = 255;
} }
if (findingElement && findingElement != t) if (matchesFindingElement)
{ {
colr /= 10; colr /= 10;
colg /= 10; colg /= 10;

View File

@ -1,12 +1,14 @@
#pragma once #pragma once
#include <array>
#include <memory>
#include <mutex>
#include <vector>
#include "Graphics.h" #include "Graphics.h"
#include "gui/interface/Point.h" #include "gui/interface/Point.h"
#include "common/tpt-rand.h" #include "common/tpt-rand.h"
#include "SimulationConfig.h" #include "SimulationConfig.h"
#include "FindingElement.h"
#include <optional>
#include <array>
#include <memory>
#include <mutex>
#include <vector>
class RenderPreset; class RenderPreset;
class Simulation; class Simulation;
@ -83,7 +85,7 @@ public:
bool blackDecorations; bool blackDecorations;
bool debugLines; bool debugLines;
pixel sampleColor; pixel sampleColor;
int findingElement; std::optional<FindingElement> findingElement;
int foundElements; int foundElements;
//Mouse position for debug information //Mouse position for debug information

View File

@ -235,7 +235,6 @@ Renderer::Renderer(Simulation * sim):
blackDecorations(false), blackDecorations(false),
debugLines(false), debugLines(false),
sampleColor(0xFFFFFFFF), sampleColor(0xFFFFFFFF),
findingElement(0),
foundElements(0), foundElements(0),
mousePos(0, 0), mousePos(0, 0),
zoomWindowPosition(0, 0), zoomWindowPosition(0, 0),

View File

@ -520,11 +520,7 @@ void GameView::NotifyActiveToolsChanged(GameModel * sender)
if (sender->GetRenderer()->findingElement) if (sender->GetRenderer()->findingElement)
{ {
Tool *active = sender->GetActiveTool(0); ren->findingElement = FindingElementCandidate();
if (!active->Identifier.Contains("_PT_"))
ren->findingElement = 0;
else
ren->findingElement = sender->GetActiveTool(0)->ToolID;
} }
} }
@ -1436,11 +1432,15 @@ void GameView::OnKeyPress(int key, int scan, bool repeat, bool shift, bool ctrl,
case SDL_SCANCODE_F: case SDL_SCANCODE_F:
if (ctrl) if (ctrl)
{ {
Tool *active = c->GetActiveTool(0); auto findingElementCandidate = FindingElementCandidate();
if (!active->Identifier.Contains("_PT_") || (ren->findingElement == active->ToolID)) if (ren->findingElement == findingElementCandidate)
ren->findingElement = 0; {
ren->findingElement = std::nullopt;
}
else else
ren->findingElement = active->ToolID; {
ren->findingElement = findingElementCandidate;
}
} }
else else
c->FrameStep(); c->FrameStep();
@ -2513,3 +2513,21 @@ ui::Point GameView::rectSnapCoords(ui::Point point1, ui::Point point2)
// SW-NE // SW-NE
return point1 + ui::Point((diff.X - diff.Y)/2, (diff.Y - diff.X)/2); return point1 + ui::Point((diff.X - diff.Y)/2, (diff.Y - diff.X)/2);
} }
std::optional<FindingElement> GameView::FindingElementCandidate() const
{
Tool *active = c->GetActiveTool(0);
if (active->Identifier.Contains("_PT_"))
{
return FindingElement{ Particle::GetProperties()[FIELD_TYPE], active->ToolID };
}
else if (active->Identifier == "DEFAULT_UI_PROPERTY")
{
auto configuration = static_cast<PropertyTool *>(active)->GetConfiguration();
if (configuration)
{
return FindingElement{ configuration->prop, configuration->propValue };
}
}
return std::nullopt;
}

View File

@ -1,11 +1,13 @@
#pragma once #pragma once
#include "common/String.h"
#include "gui/interface/Window.h"
#include "simulation/Sample.h"
#include "graphics/FindingElement.h"
#include <ctime> #include <ctime>
#include <deque> #include <deque>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "common/String.h" #include <optional>
#include "gui/interface/Window.h"
#include "simulation/Sample.h"
enum DrawMode enum DrawMode
{ {
@ -141,6 +143,8 @@ private:
Vec2<int> PlaceSavePos() const; Vec2<int> PlaceSavePos() const;
std::optional<FindingElement> FindingElementCandidate() const;
public: public:
GameView(); GameView();
virtual ~GameView(); virtual ~GameView();

View File

@ -183,7 +183,7 @@ void PropertyWindow::CheckProperty()
{ {
std::cout << "Got int value " << v << std::endl; std::cout << "Got int value " << v << std::endl;
} }
newConfiguration.propValue.Integer = v; newConfiguration.propValue = v;
break; break;
} }
case StructProperty::UInteger: case StructProperty::UInteger:
@ -207,22 +207,21 @@ void PropertyWindow::CheckProperty()
{ {
std::cout << "Got uint value " << v << std::endl; std::cout << "Got uint value " << v << std::endl;
} }
newConfiguration.propValue.UInteger = v; newConfiguration.propValue = v;
break; break;
} }
case StructProperty::Float: case StructProperty::Float:
{ {
if (properties[property->GetOption().second].Name == "temp") if (properties[property->GetOption().second].Name == "temp")
newConfiguration.propValue.Float = format::StringToTemperature(value, tool->gameModel.GetTemperatureScale()); newConfiguration.propValue = format::StringToTemperature(value, tool->gameModel.GetTemperatureScale());
else else
newConfiguration.propValue.Float = value.ToNumber<float>(); newConfiguration.propValue = value.ToNumber<float>();
} }
break; break;
default: default:
return; return;
} }
newConfiguration.propOffset = properties[property->GetOption().second].Offset; newConfiguration.prop = properties[property->GetOption().second];
newConfiguration.propType = properties[property->GetOption().second].Type;
newConfiguration.changeType = properties[property->GetOption().second].Name == "type"; newConfiguration.changeType = properties[property->GetOption().second].Name == "type";
} }
catch (const std::exception& ex) catch (const std::exception& ex)
@ -282,21 +281,21 @@ void PropertyTool::SetProperty(Simulation *sim, ui::Point position)
if (configuration->changeType) if (configuration->changeType)
{ {
sim->part_change_type(ID(i), int(sim->parts[ID(i)].x+0.5f), int(sim->parts[ID(i)].y+0.5f), configuration->propValue.Integer); sim->part_change_type(ID(i), int(sim->parts[ID(i)].x+0.5f), int(sim->parts[ID(i)].y+0.5f), std::get<int>(configuration->propValue));
return; return;
} }
switch (configuration->propType) switch (configuration->prop.Type)
{ {
case StructProperty::Float: case StructProperty::Float:
*((float*)(((char*)&sim->parts[ID(i)])+configuration->propOffset)) = configuration->propValue.Float; *((float*)(((char*)&sim->parts[ID(i)])+configuration->prop.Offset)) = std::get<float>(configuration->propValue);
break; break;
case StructProperty::ParticleType: case StructProperty::ParticleType:
case StructProperty::Integer: case StructProperty::Integer:
*((int*)(((char*)&sim->parts[ID(i)])+configuration->propOffset)) = configuration->propValue.Integer; *((int*)(((char*)&sim->parts[ID(i)])+configuration->prop.Offset)) = std::get<int>(configuration->propValue);
break; break;
case StructProperty::UInteger: case StructProperty::UInteger:
*((unsigned int*)(((char*)&sim->parts[ID(i)])+configuration->propOffset)) = configuration->propValue.UInteger; *((unsigned int*)(((char*)&sim->parts[ID(i)])+configuration->prop.Offset)) = std::get<unsigned int>(configuration->propValue);
break; break;
default: default:
break; break;
@ -391,5 +390,5 @@ void PropertyTool::DrawRect(Simulation *sim, Brush const &cBrush, ui::Point posi
void PropertyTool::DrawFill(Simulation *sim, Brush const &cBrush, ui::Point position) void PropertyTool::DrawFill(Simulation *sim, Brush const &cBrush, ui::Point position)
{ {
if (configuration) if (configuration)
sim->flood_prop(position.X, position.Y, configuration->propOffset, configuration->propValue, configuration->propType); sim->flood_prop(position.X, position.Y, configuration->prop, configuration->propValue);
} }

View File

@ -101,10 +101,9 @@ class PropertyTool: public Tool
public: public:
struct Configuration struct Configuration
{ {
StructProperty::PropertyType propType; StructProperty prop;
PropertyValue propValue; PropertyValue propValue;
bool changeType; bool changeType;
size_t propOffset;
}; };
private: private:
@ -131,6 +130,11 @@ public:
void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override; void DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging = false) override;
void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override; void DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) override;
void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override; void DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override;
std::optional<Configuration> GetConfiguration() const
{
return configuration;
}
}; };
class GOLTool: public Tool class GOLTool: public Tool

View File

@ -22,6 +22,7 @@ struct Particle
}; };
// important: these are indices into the vector returned by Particle::GetProperties, not indices into Particle // important: these are indices into the vector returned by Particle::GetProperties, not indices into Particle
constexpr unsigned int FIELD_TYPE = 0;
constexpr unsigned int FIELD_LIFE = 1; constexpr unsigned int FIELD_LIFE = 1;
constexpr unsigned int FIELD_CTYPE = 2; constexpr unsigned int FIELD_CTYPE = 2;
constexpr unsigned int FIELD_TMP = 9; constexpr unsigned int FIELD_TMP = 9;

View File

@ -489,7 +489,7 @@ CoordStack& Simulation::getCoordStackSingleton()
return cs; return cs;
} }
int Simulation::flood_prop(int x, int y, size_t propoffset, PropertyValue propvalue, StructProperty::PropertyType proptype) int Simulation::flood_prop(int x, int y, StructProperty prop, PropertyValue propvalue)
{ {
int i, x1, x2, dy = 1; int i, x1, x2, dy = 1;
int did_something = 0; int did_something = 0;
@ -531,18 +531,18 @@ int Simulation::flood_prop(int x, int y, size_t propoffset, PropertyValue propva
i = photons[y][x]; i = photons[y][x];
if (!i) if (!i)
continue; continue;
switch (proptype) { switch (prop.Type) {
case StructProperty::Float: case StructProperty::Float:
*((float*)(((char*)&parts[ID(i)])+propoffset)) = propvalue.Float; *((float*)(((char*)&parts[ID(i)])+prop.Offset)) = std::get<float>(propvalue);
break; break;
case StructProperty::ParticleType: case StructProperty::ParticleType:
case StructProperty::Integer: case StructProperty::Integer:
*((int*)(((char*)&parts[ID(i)])+propoffset)) = propvalue.Integer; *((int*)(((char*)&parts[ID(i)])+prop.Offset)) = std::get<int>(propvalue);
break; break;
case StructProperty::UInteger: case StructProperty::UInteger:
*((unsigned int*)(((char*)&parts[ID(i)])+propoffset)) = propvalue.UInteger; *((unsigned int*)(((char*)&parts[ID(i)])+prop.Offset)) = std::get<unsigned int>(propvalue);
break; break;
default: default:

View File

@ -149,7 +149,7 @@ public:
void create_gain_photon(int pp); void create_gain_photon(int pp);
void kill_part(int i); void kill_part(int i);
bool FloodFillPmapCheck(int x, int y, int type); bool FloodFillPmapCheck(int x, int y, int type);
int flood_prop(int x, int y, size_t propoffset, PropertyValue propvalue, StructProperty::PropertyType proptype); int flood_prop(int x, int y, StructProperty prop, PropertyValue propvalue);
bool flood_water(int x, int y, int i); bool flood_water(int x, int y, int i);
int FloodINST(int x, int y); int FloodINST(int x, int y);
void detach(int i); void detach(int i);

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "common/String.h" #include "common/String.h"
#include <cstdint> #include <cstdint>
#include <variant>
struct StructProperty struct StructProperty
{ {
@ -36,13 +37,20 @@ struct StructProperty
{ {
} }
bool operator ==(const StructProperty &other) const
{
return Name == other.Name &&
Type == other.Type &&
Offset == other.Offset;
}
}; };
union PropertyValue { using PropertyValue = std::variant<
int Integer; int,
unsigned int UInteger; unsigned int,
float Float; float
}; >;
struct StructPropertyAlias struct StructPropertyAlias
{ {

View File

@ -75,9 +75,7 @@ static int update(UPDATE_FUNC_ARGS)
{ {
if ((ID(pmap[y][x]) == i)) if ((ID(pmap[y][x]) == i))
{ {
PropertyValue value; sim->flood_prop(x, y, Particle::GetProperties()[FIELD_TMP], 2);
value.Integer = 2;
sim->flood_prop(x, y, offsetof(Particle, tmp), value, StructProperty::Integer);
} }
parts[i].tmp = 2; parts[i].tmp = 2;
} }