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)
{
if (key == 'f')
if (key == 'f' && !ctrl)
{
model->SetPaused(1);
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;
else if(firea<0) firea = 0;
auto matchesFindingElement = false;
if (findingElement)
{
if (TYP(findingElement) == parts[i].type &&
(parts[i].type != PT_LIFE || (ID(findingElement) == parts[i].ctype)))
if (findingElement->property.Offset == offsetof(Particle, type))
{
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;
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));
}
if (findingElement == t)
if (matchesFindingElement)
{
colr = 255;
colg = colb = 0;
@ -445,7 +476,7 @@ void Renderer::render_parts()
}
}
if (findingElement && findingElement == t)
if (matchesFindingElement)
{
legr = 255;
legg = legb = 0;
@ -469,7 +500,7 @@ void Renderer::render_parts()
legb = 255;
}
if (findingElement && findingElement != t)
if (matchesFindingElement)
{
colr /= 10;
colg /= 10;

View File

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

View File

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

View File

@ -520,11 +520,7 @@ void GameView::NotifyActiveToolsChanged(GameModel * sender)
if (sender->GetRenderer()->findingElement)
{
Tool *active = sender->GetActiveTool(0);
if (!active->Identifier.Contains("_PT_"))
ren->findingElement = 0;
else
ren->findingElement = sender->GetActiveTool(0)->ToolID;
ren->findingElement = FindingElementCandidate();
}
}
@ -1436,11 +1432,15 @@ void GameView::OnKeyPress(int key, int scan, bool repeat, bool shift, bool ctrl,
case SDL_SCANCODE_F:
if (ctrl)
{
Tool *active = c->GetActiveTool(0);
if (!active->Identifier.Contains("_PT_") || (ren->findingElement == active->ToolID))
ren->findingElement = 0;
auto findingElementCandidate = FindingElementCandidate();
if (ren->findingElement == findingElementCandidate)
{
ren->findingElement = std::nullopt;
}
else
ren->findingElement = active->ToolID;
{
ren->findingElement = findingElementCandidate;
}
}
else
c->FrameStep();
@ -2513,3 +2513,21 @@ ui::Point GameView::rectSnapCoords(ui::Point point1, ui::Point point2)
// SW-NE
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
#include "common/String.h"
#include "gui/interface/Window.h"
#include "simulation/Sample.h"
#include "graphics/FindingElement.h"
#include <ctime>
#include <deque>
#include <memory>
#include <vector>
#include "common/String.h"
#include "gui/interface/Window.h"
#include "simulation/Sample.h"
#include <optional>
enum DrawMode
{
@ -141,6 +143,8 @@ private:
Vec2<int> PlaceSavePos() const;
std::optional<FindingElement> FindingElementCandidate() const;
public:
GameView();
virtual ~GameView();

View File

@ -183,7 +183,7 @@ void PropertyWindow::CheckProperty()
{
std::cout << "Got int value " << v << std::endl;
}
newConfiguration.propValue.Integer = v;
newConfiguration.propValue = v;
break;
}
case StructProperty::UInteger:
@ -207,22 +207,21 @@ void PropertyWindow::CheckProperty()
{
std::cout << "Got uint value " << v << std::endl;
}
newConfiguration.propValue.UInteger = v;
newConfiguration.propValue = v;
break;
}
case StructProperty::Float:
{
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
newConfiguration.propValue.Float = value.ToNumber<float>();
newConfiguration.propValue = value.ToNumber<float>();
}
break;
default:
return;
}
newConfiguration.propOffset = properties[property->GetOption().second].Offset;
newConfiguration.propType = properties[property->GetOption().second].Type;
newConfiguration.prop = properties[property->GetOption().second];
newConfiguration.changeType = properties[property->GetOption().second].Name == "type";
}
catch (const std::exception& ex)
@ -282,21 +281,21 @@ void PropertyTool::SetProperty(Simulation *sim, ui::Point position)
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;
}
switch (configuration->propType)
switch (configuration->prop.Type)
{
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;
case StructProperty::ParticleType:
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;
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;
default:
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)
{
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:
struct Configuration
{
StructProperty::PropertyType propType;
StructProperty prop;
PropertyValue propValue;
bool changeType;
size_t propOffset;
};
private:
@ -131,6 +130,11 @@ public:
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 DrawFill(Simulation * sim, Brush const &brush, ui::Point position) override;
std::optional<Configuration> GetConfiguration() const
{
return configuration;
}
};
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
constexpr unsigned int FIELD_TYPE = 0;
constexpr unsigned int FIELD_LIFE = 1;
constexpr unsigned int FIELD_CTYPE = 2;
constexpr unsigned int FIELD_TMP = 9;

View File

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

View File

@ -149,7 +149,7 @@ public:
void create_gain_photon(int pp);
void kill_part(int i);
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);
int FloodINST(int x, int y);
void detach(int i);

View File

@ -1,6 +1,7 @@
#pragma once
#include "common/String.h"
#include <cstdint>
#include <variant>
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 {
int Integer;
unsigned int UInteger;
float Float;
};
using PropertyValue = std::variant<
int,
unsigned int,
float
>;
struct StructPropertyAlias
{

View File

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