Prevent CtypeDraw from being called in simulation contexts

CtypeDraw is already not an interface event, so to prevent parts of the call stack from being upgraded back to interface event status is not why this change is necessary. Rather, it is necessary because some Lua functions that are allowed to be called from non-interface events may indirectly invoke CtypeDraw, which is most likely unintended. Ctype-drawing is intended to be an interface feature, not something that e.g. an Update function creating a circle of particles should invoke.

Also make the flags parameter mandatory across all relevant functions because it's too easy to add a millionth int parameter and forget to update all call sites.
This commit is contained in:
Tamás Bálint Misius
2025-04-14 18:59:30 +02:00
parent e6f297680b
commit e44e77f6d6
4 changed files with 37 additions and 33 deletions

View File

@@ -4,33 +4,33 @@
#include "gui/game/Brush.h"
void ElementTool::Draw(Simulation * sim, Brush const &brush, ui::Point position){
sim->CreateParts(position.X, position.Y, ToolID, brush);
sim->CreateParts(-2, position.X, position.Y, ToolID, brush, -1);
}
void ElementTool::DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging) {
sim->CreateLine(position1.X, position1.Y, position2.X, position2.Y, ToolID, brush);
sim->CreateLine(position1.X, position1.Y, position2.X, position2.Y, ToolID, brush, -1);
}
void ElementTool::DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) {
sim->CreateBox(position1.X, position1.Y, position2.X, position2.Y, ToolID);
sim->CreateBox(-2, position1.X, position1.Y, position2.X, position2.Y, ToolID, -1);
}
void ElementTool::DrawFill(Simulation * sim, Brush const &brush, ui::Point position) {
sim->FloodParts(position.X, position.Y, ToolID, -1);
sim->FloodParts(position.X, position.Y, ToolID, -1, -1);
}
void Element_LIGH_Tool::DrawLine(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2, bool dragging)
{
if (dragging)
sim->CreateParts(position1.X, position1.Y, brush.GetRadius().X, brush.GetRadius().Y, PT_LIGH);
sim->CreateParts(-2, position1.X, position1.Y, brush.GetRadius().X, brush.GetRadius().Y, PT_LIGH, -1);
}
void Element_TESC_Tool::DrawRect(Simulation * sim, Brush const &brush, ui::Point position1, ui::Point position2) {
int radiusInfo = brush.GetRadius().X*4+brush.GetRadius().Y*4+7;
sim->CreateBox(position1.X, position1.Y, position2.X, position2.Y, ToolID | PMAPID(radiusInfo));
sim->CreateBox(-2, position1.X, position1.Y, position2.X, position2.Y, ToolID | PMAPID(radiusInfo), -1);
}
void Element_TESC_Tool::DrawFill(Simulation * sim, Brush const &brush, ui::Point position) {
int radiusInfo = brush.GetRadius().X*4+brush.GetRadius().Y*4+7;
sim->FloodParts(position.X, position.Y, ToolID | PMAPID(radiusInfo), -1);
sim->FloodParts(position.X, position.Y, ToolID | PMAPID(radiusInfo), -1, -1);
}

View File

@@ -332,6 +332,10 @@ static int partCreate(lua_State *L)
lua_pushinteger(L, -1);
return 1;
}
if (newID == -2)
{
lsi->AssertInterfaceEvent();
}
int type = lua_tointeger(L, 4);
int v = -1;
if (lua_gettop(L) >= 5)
@@ -509,7 +513,7 @@ static int createParts(lua_State *L)
RasterizeEllipseRows(Vec2<float>(rx * rx, ry * ry), [lsi, c, center](int xLim, int dy) {
for (auto pos : RectBetween(center + Vec2(-xLim, dy), center + Vec2(xLim, dy)))
{
lsi->sim->CreateParts(pos.X, pos.Y, 0, 0, c, 0);
lsi->sim->CreateParts(-1, pos.X, pos.Y, 0, 0, c, 0);
}
});
lua_pushinteger(L, 0); // return value doesn't make sense anyway
@@ -525,7 +529,7 @@ static int createParts(lua_State *L)
newBrush->SetRadius(ui::Point(rx, ry));
int c = luaL_optint(L,5,lsi->gameModel->GetActiveTool(0)->ToolID);
int ret = lsi->sim->CreateParts(x, y, c, *newBrush, uiFlags);
int ret = lsi->sim->CreateParts(-2, x, y, c, *newBrush, uiFlags);
lua_pushinteger(L, ret);
return 1;
}
@@ -574,7 +578,7 @@ static int createBox(lua_State *L)
if (!(lsi->eventTraits & eventTraitInterface) && !lua_isnoneornil(L, 5) && flags == 0)
{
int c = luaL_checkint(L, 5); // note: weird: has to be specified in a sim context but not in a ui context
lsi->sim->CreateBox(x1, y1, x2, y2, c, 0);
lsi->sim->CreateBox(-1, x1, y1, x2, y2, c, 0);
return 0;
}
@@ -582,7 +586,7 @@ static int createBox(lua_State *L)
int c = luaL_optint(L,5,lsi->gameModel->GetActiveTool(0)->ToolID);
int uiFlags = luaL_optint(L,6,lsi->sim->replaceModeFlags);
lsi->sim->CreateBox(x1, y1, x2, y2, c, uiFlags);
lsi->sim->CreateBox(-2, x1, y1, x2, y2, c, uiFlags);
return 0;
}

View File

@@ -354,7 +354,7 @@ int Simulation::FloodWalls(int x, int y, int wall, int bm)
return 1;
}
int Simulation::CreatePartFlags(int x, int y, int c, int flags)
int Simulation::CreatePartFlags(int p, int x, int y, int c, int flags)
{
if (x < 0 || y < 0 || x >= XRES || y >= YRES)
{
@@ -397,7 +397,7 @@ int Simulation::CreatePartFlags(int x, int y, int c, int flags)
}
else
{
return (create_part(-2, x, y, TYP(c), ID(c)) == -1);
return (create_part(p, x, y, TYP(c), ID(c)) == -1);
}
// I'm sure at least one compiler exists that would complain if this wasn't here
@@ -738,7 +738,7 @@ void Simulation::ApplyDecorationFill(const RendererFrame &frame, int x, int y, i
free(bitmap);
}
int Simulation::CreateParts(int positionX, int positionY, int c, Brush const &cBrush, int flags)
int Simulation::CreateParts(int p, int positionX, int positionY, int c, Brush const &cBrush, int flags)
{
if (flags == -1)
flags = replaceModeFlags;
@@ -754,7 +754,7 @@ int Simulation::CreateParts(int positionX, int positionY, int c, Brush const &cB
newlife = 55;
c = PMAP(newlife, c);
lightningRecreate = currentTick + std::max(newlife / 4, 1);
return CreatePartFlags(positionX, positionY, c, flags);
return CreatePartFlags(p, positionX, positionY, c, flags);
}
else if (c == PT_TESC)
{
@@ -768,12 +768,12 @@ int Simulation::CreateParts(int positionX, int positionY, int c, Brush const &cB
{
ui::Point coords = ui::Point(positionX, positionY) + off;
if (coords.X >= 0 && coords.Y >= 0 && coords.X < XRES && coords.Y < YRES)
CreatePartFlags(coords.X, coords.Y, c, flags);
CreatePartFlags(p, coords.X, coords.Y, c, flags);
}
return 0;
}
int Simulation::CreateParts(int x, int y, int rx, int ry, int c, int flags)
int Simulation::CreateParts(int p, int x, int y, int rx, int ry, int c, int flags)
{
bool created = false;
@@ -802,7 +802,7 @@ int Simulation::CreateParts(int x, int y, int rx, int ry, int c, int flags)
for (int j = -ry; j <= ry; j++)
for (int i = -rx; i <= rx; i++)
if (CreatePartFlags(x+i, y+j, c, flags))
if (CreatePartFlags(p, x+i, y+j, c, flags))
created = true;
return !created;
}
@@ -838,9 +838,9 @@ void Simulation::CreateLine(int x1, int y1, int x2, int y2, int c, Brush const &
for (x=x1; x<=x2; x++)
{
if (reverseXY)
CreateParts(y, x, c, cBrush, flags);
CreateParts(-2, y, x, c, cBrush, flags);
else
CreateParts(x, y, c, cBrush, flags);
CreateParts(-2, x, y, c, cBrush, flags);
e += de;
if (e >= 0.5f)
{
@@ -848,16 +848,16 @@ void Simulation::CreateLine(int x1, int y1, int x2, int y2, int c, Brush const &
if (!(rx+ry) && ((y1<y2) ? (y<=y2) : (y>=y2)))
{
if (reverseXY)
CreateParts(y, x, c, cBrush, flags);
CreateParts(-2, y, x, c, cBrush, flags);
else
CreateParts(x, y, c, cBrush, flags);
CreateParts(-2, x, y, c, cBrush, flags);
}
e -= 1.0f;
}
}
}
void Simulation::CreateBox(int x1, int y1, int x2, int y2, int c, int flags)
void Simulation::CreateBox(int p, int x1, int y1, int x2, int y2, int c, int flags)
{
int i, j;
if (x1>x2)
@@ -874,7 +874,7 @@ void Simulation::CreateBox(int x1, int y1, int x2, int y2, int c, int flags)
}
for (j=y2; j>=y1; j--)
for (i=x1; i<=x2; i++)
CreateParts(i, j, 0, 0, c, flags);
CreateParts(p, i, j, 0, 0, c, flags);
}
int Simulation::FloodParts(int x, int y, int fullc, int cm, int flags)
@@ -974,7 +974,7 @@ int Simulation::FloodParts(int x, int y, int fullc, int cm, int flags)
created_something = 1;
}
}
else if (CreateParts(x, y, 0, 0, fullc, flags))
else if (CreateParts(-2, x, y, 0, 0, fullc, flags))
created_something = 1;
bitmap[(y * XRES) + x] = 1;
}

View File

@@ -220,19 +220,19 @@ public:
void ApplyDecorationFill(const RendererFrame &frame, int x, int y, int colR, int colG, int colB, int colA, int replaceR, int replaceG, int replaceB);
//Drawing Walls
int CreateWalls(int x, int y, int rx, int ry, int wall, Brush const *cBrush = nullptr);
void CreateWallLine(int x1, int y1, int x2, int y2, int rx, int ry, int wall, Brush const *cBrush = nullptr);
int CreateWalls(int x, int y, int rx, int ry, int wall, Brush const *cBrush);
void CreateWallLine(int x1, int y1, int x2, int y2, int rx, int ry, int wall, Brush const *cBrush);
void CreateWallBox(int x1, int y1, int x2, int y2, int wall);
int FloodWalls(int x, int y, int wall, int bm);
//Drawing Particles
int CreateParts(int positionX, int positionY, int c, Brush const &cBrush, int flags = -1);
int CreateParts(int x, int y, int rx, int ry, int c, int flags = -1);
int CreatePartFlags(int x, int y, int c, int flags);
void CreateLine(int x1, int y1, int x2, int y2, int c, Brush const &cBrush, int flags = -1);
int CreateParts(int p, int positionX, int positionY, int c, Brush const &cBrush, int flags);
int CreateParts(int p, int x, int y, int rx, int ry, int c, int flags);
int CreatePartFlags(int p, int x, int y, int c, int flags);
void CreateLine(int x1, int y1, int x2, int y2, int c, Brush const &cBrush, int flags);
void CreateLine(int x1, int y1, int x2, int y2, int c);
void CreateBox(int x1, int y1, int x2, int y2, int c, int flags = -1);
int FloodParts(int x, int y, int c, int cm, int flags = -1);
void CreateBox(int p, int x1, int y1, int x2, int y2, int c, int flags);
int FloodParts(int x, int y, int c, int cm, int flags);
void GetGravityField(int x, int y, float particleGrav, float newtonGrav, float & pGravX, float & pGravY);