mirror of
https://github.com/The-Powder-Toy/The-Powder-Toy.git
synced 2025-01-17 06:18:22 +01:00
Implement Lua tools
This commit is contained in:
parent
ff4500620e
commit
00ec4e0754
@ -1729,3 +1729,11 @@ bool GameController::ThreadedRenderingAllowed()
|
|||||||
{
|
{
|
||||||
return gameModel->GetThreadedRendering() && !commandInterface->HaveSimGraphicsEventHandlers();
|
return gameModel->GetThreadedRendering() && !commandInterface->HaveSimGraphicsEventHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameController::SetToolIndex(ByteString identifier, std::optional<int> index)
|
||||||
|
{
|
||||||
|
if (commandInterface)
|
||||||
|
{
|
||||||
|
commandInterface->SetToolIndex(identifier, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -206,4 +206,6 @@ public:
|
|||||||
void BeforeSimDraw();
|
void BeforeSimDraw();
|
||||||
void AfterSimDraw();
|
void AfterSimDraw();
|
||||||
bool ThreadedRenderingAllowed();
|
bool ThreadedRenderingAllowed();
|
||||||
|
|
||||||
|
void SetToolIndex(ByteString identifier, std::optional<int> index);
|
||||||
};
|
};
|
||||||
|
@ -598,6 +598,14 @@ Brush *GameModel::GetBrushByID(int i)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GameModel::GetBrushIndex(const Brush &brush)
|
||||||
|
{
|
||||||
|
auto it = std::find_if(brushList.begin(), brushList.end(), [&brush](auto &ptr) {
|
||||||
|
return ptr.get() == &brush;
|
||||||
|
});
|
||||||
|
return int(it - brushList.begin());
|
||||||
|
}
|
||||||
|
|
||||||
int GameModel::GetBrushID()
|
int GameModel::GetBrushID()
|
||||||
{
|
{
|
||||||
return currentBrush;
|
return currentBrush;
|
||||||
@ -1647,6 +1655,7 @@ void GameModel::AllocTool(std::unique_ptr<Tool> tool)
|
|||||||
index = int(tools.size());
|
index = int(tools.size());
|
||||||
tools.emplace_back();
|
tools.emplace_back();
|
||||||
}
|
}
|
||||||
|
GameController::Ref().SetToolIndex(tool->Identifier, *index);
|
||||||
tools[*index] = std::move(tool);
|
tools[*index] = std::move(tool);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1659,6 +1668,7 @@ void GameModel::FreeTool(Tool *tool)
|
|||||||
}
|
}
|
||||||
auto &ptr = tools[*index];
|
auto &ptr = tools[*index];
|
||||||
DeselectTool(ptr->Identifier);
|
DeselectTool(ptr->Identifier);
|
||||||
|
GameController::Ref().SetToolIndex(ptr->Identifier, std::nullopt);
|
||||||
ptr.reset();
|
ptr.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +213,7 @@ public:
|
|||||||
Brush &GetBrush();
|
Brush &GetBrush();
|
||||||
Brush *GetBrushByID(int i);
|
Brush *GetBrushByID(int i);
|
||||||
int GetBrushID();
|
int GetBrushID();
|
||||||
|
int GetBrushIndex(const Brush &brush);
|
||||||
int BrushListSize() const
|
int BrushListSize() const
|
||||||
{
|
{
|
||||||
return int(brushList.size());
|
return int(brushList.size());
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "gui/game/GameControllerEvents.h"
|
#include "gui/game/GameControllerEvents.h"
|
||||||
#include "TPTSTypes.h"
|
#include "TPTSTypes.h"
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
class GameModel;
|
class GameModel;
|
||||||
class GameController;
|
class GameController;
|
||||||
@ -55,5 +56,7 @@ public:
|
|||||||
AnyType tptS_quit(std::deque<String> * words);
|
AnyType tptS_quit(std::deque<String> * words);
|
||||||
ValueType testType(String word);
|
ValueType testType(String word);
|
||||||
|
|
||||||
|
void SetToolIndex(ByteString identifier, std::optional<int> index);
|
||||||
|
|
||||||
static CommandInterfacePtr Create(GameController *newGameController, GameModel *newGameModel);
|
static CommandInterfacePtr Create(GameController *newGameController, GameModel *newGameModel);
|
||||||
};
|
};
|
||||||
|
@ -155,6 +155,7 @@ LuaScriptInterface::LuaScriptInterface(GameController *newGameController, GameMo
|
|||||||
LuaRenderer::Open(L);
|
LuaRenderer::Open(L);
|
||||||
LuaSimulation::Open(L);
|
LuaSimulation::Open(L);
|
||||||
LuaSocket::Open(L);
|
LuaSocket::Open(L);
|
||||||
|
LuaTools::Open(L);
|
||||||
{
|
{
|
||||||
lua_getglobal(L, "os");
|
lua_getglobal(L, "os");
|
||||||
lua_pushcfunction(L, osExit);
|
lua_pushcfunction(L, osExit);
|
||||||
@ -210,6 +211,12 @@ void CommandInterface::Init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CommandInterface::SetToolIndex(ByteString identifier, std::optional<int> index)
|
||||||
|
{
|
||||||
|
auto *lsi = static_cast<LuaScriptInterface *>(this);
|
||||||
|
LuaTools::SetToolIndex(lsi->L, identifier, index);
|
||||||
|
}
|
||||||
|
|
||||||
void LuaGetProperty(lua_State *L, StructProperty property, intptr_t propertyAddress)
|
void LuaGetProperty(lua_State *L, StructProperty property, intptr_t propertyAddress)
|
||||||
{
|
{
|
||||||
switch (property.Type)
|
switch (property.Type)
|
||||||
|
@ -58,6 +58,17 @@ struct CustomElement
|
|||||||
LuaSmartRef changeType;
|
LuaSmartRef changeType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CustomTool
|
||||||
|
{
|
||||||
|
LuaSmartRef perform;
|
||||||
|
LuaSmartRef click;
|
||||||
|
LuaSmartRef drag;
|
||||||
|
LuaSmartRef draw;
|
||||||
|
LuaSmartRef drawLine;
|
||||||
|
LuaSmartRef drawRect;
|
||||||
|
LuaSmartRef drawFill;
|
||||||
|
};
|
||||||
|
|
||||||
class LuaScriptInterface : public CommandInterface
|
class LuaScriptInterface : public CommandInterface
|
||||||
{
|
{
|
||||||
LuaStatePtr luaState;
|
LuaStatePtr luaState;
|
||||||
@ -86,6 +97,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<CustomElement> customElements; // must come after luaState
|
std::vector<CustomElement> customElements; // must come after luaState
|
||||||
|
std::vector<CustomTool> customTools;
|
||||||
|
|
||||||
EventTraits eventTraits = eventTraitNone;
|
EventTraits eventTraits = eventTraitNone;
|
||||||
|
|
||||||
@ -204,6 +216,12 @@ namespace LuaSocket
|
|||||||
void OpenTCP(lua_State *L);
|
void OpenTCP(lua_State *L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace LuaTools
|
||||||
|
{
|
||||||
|
void Open(lua_State *L);
|
||||||
|
void SetToolIndex(lua_State *L, ByteString identifier, std::optional<int> index);
|
||||||
|
}
|
||||||
|
|
||||||
inline LuaScriptInterface *GetLSI()
|
inline LuaScriptInterface *GetLSI()
|
||||||
{
|
{
|
||||||
return static_cast<LuaScriptInterface *>(&CommandInterface::Ref());
|
return static_cast<LuaScriptInterface *>(&CommandInterface::Ref());
|
||||||
|
@ -2020,21 +2020,6 @@ void LuaSimulation::Open(lua_State *L)
|
|||||||
LCONSTAS("NUM_WALLS", UI_WALLCOUNT);
|
LCONSTAS("NUM_WALLS", UI_WALLCOUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
lua_newtable(L);
|
|
||||||
auto &toolList = lsi->gameModel->GetTools();
|
|
||||||
for (int i = 0; i < int(toolList.size()); ++i)
|
|
||||||
{
|
|
||||||
tpt_lua_pushByteString(L, toolList[i]->Identifier);
|
|
||||||
lua_pushinteger(L, i);
|
|
||||||
lua_settable(L, -3);
|
|
||||||
lua_pushinteger(L, i);
|
|
||||||
tpt_lua_pushByteString(L, toolList[i]->Identifier);
|
|
||||||
lua_settable(L, -3);
|
|
||||||
}
|
|
||||||
lua_setfield(L, -2, "tools");
|
|
||||||
LCONSTAS("NUM_TOOLS", UI_WALLCOUNT);
|
|
||||||
}
|
|
||||||
#undef LCONSTAS
|
#undef LCONSTAS
|
||||||
#undef LCONSTF
|
#undef LCONSTF
|
||||||
#undef LCONST
|
#undef LCONST
|
||||||
|
394
src/lua/LuaTools.cpp
Normal file
394
src/lua/LuaTools.cpp
Normal file
@ -0,0 +1,394 @@
|
|||||||
|
#include "LuaScriptInterface.h"
|
||||||
|
#include "gui/game/GameModel.h"
|
||||||
|
#include "simulation/SimTool.h"
|
||||||
|
#include "simulation/Simulation.h"
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
static int allocate(lua_State *L)
|
||||||
|
{
|
||||||
|
luaL_checktype(L, 1, LUA_TSTRING);
|
||||||
|
luaL_checktype(L, 2, LUA_TSTRING);
|
||||||
|
auto group = tpt_lua_toByteString(L, 1).ToUpper();
|
||||||
|
auto name = tpt_lua_toByteString(L, 2).ToUpper();
|
||||||
|
if (name.Contains("_"))
|
||||||
|
{
|
||||||
|
return luaL_error(L, "The tool name may not contain '_'.");
|
||||||
|
}
|
||||||
|
if (group.Contains("_"))
|
||||||
|
{
|
||||||
|
return luaL_error(L, "The group name may not contain '_'.");
|
||||||
|
}
|
||||||
|
if (group == "DEFAULT")
|
||||||
|
{
|
||||||
|
return luaL_error(L, "You cannot create tools in the 'DEFAULT' group.");
|
||||||
|
}
|
||||||
|
auto *lsi = GetLSI();
|
||||||
|
auto identifier = group + "_TOOL_" + name;
|
||||||
|
{
|
||||||
|
SimTool tool;
|
||||||
|
tool.Identifier = identifier;
|
||||||
|
lsi->gameModel->AllocTool(std::make_unique<SimTool>(tool));
|
||||||
|
}
|
||||||
|
lsi->gameModel->BuildMenus();
|
||||||
|
auto index = *lsi->gameModel->GetToolIndex(lsi->gameModel->GetToolFromIdentifier(identifier));
|
||||||
|
lsi->customTools.resize(std::max(int(lsi->customTools.size()), index + 1));
|
||||||
|
lua_pushinteger(L, index);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsDefault(Tool *tool)
|
||||||
|
{
|
||||||
|
return tool->Identifier.BeginsWith("DEFAULT_");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ffree(lua_State *L)
|
||||||
|
{
|
||||||
|
int index = luaL_checkinteger(L, 1);
|
||||||
|
auto *lsi = GetLSI();
|
||||||
|
auto *tool = lsi->gameModel->GetToolByIndex(index);
|
||||||
|
if (!tool)
|
||||||
|
{
|
||||||
|
return luaL_error(L, "Invalid tool");
|
||||||
|
}
|
||||||
|
if (IsDefault(tool))
|
||||||
|
{
|
||||||
|
return luaL_error(L, "Cannot free default tools");
|
||||||
|
}
|
||||||
|
lsi->customTools[index] = {};
|
||||||
|
lsi->gameModel->FreeTool(tool);
|
||||||
|
lsi->gameModel->BuildMenus();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int luaPerformWrapper(SimTool *tool, Simulation *sim, Particle *cpart, int x, int y, int brushX, int brushY, float strength)
|
||||||
|
{
|
||||||
|
int ok = 0;
|
||||||
|
auto *lsi = GetLSI();
|
||||||
|
auto L = lsi->L;
|
||||||
|
auto index = *lsi->gameModel->GetToolIndex(tool);
|
||||||
|
auto &customTools = lsi->customTools;
|
||||||
|
if (customTools[index].perform)
|
||||||
|
{
|
||||||
|
lua_rawgeti(L, LUA_REGISTRYINDEX, customTools[index].perform);
|
||||||
|
if (cpart)
|
||||||
|
{
|
||||||
|
lua_pushinteger(L, cpart - &lsi->sim->parts[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lua_pushnil(L);
|
||||||
|
}
|
||||||
|
lua_pushinteger(L, x);
|
||||||
|
lua_pushinteger(L, y);
|
||||||
|
lua_pushnumber(L, tool->Strength);
|
||||||
|
lua_pushboolean(L, tool->shiftBehaviour);
|
||||||
|
lua_pushboolean(L, tool->ctrlBehaviour);
|
||||||
|
lua_pushboolean(L, tool->altBehaviour);
|
||||||
|
lua_pushinteger(L, brushX);
|
||||||
|
lua_pushinteger(L, brushY);
|
||||||
|
if (tpt_lua_pcall(L, 9, 1, 0, eventTraitNone))
|
||||||
|
{
|
||||||
|
lsi->Log(CommandInterface::LogError, "In perform func: " + LuaGetError());
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
if (lua_isboolean(L, -1))
|
||||||
|
{
|
||||||
|
ok = lua_toboolean(L, -1);
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void luaClickWrapper(SimTool *tool, Simulation *sim, const Brush &brush, ui::Point position)
|
||||||
|
{
|
||||||
|
auto *lsi = GetLSI();
|
||||||
|
auto L = lsi->L;
|
||||||
|
auto index = *lsi->gameModel->GetToolIndex(tool);
|
||||||
|
auto &customTools = lsi->customTools;
|
||||||
|
if (customTools[index].click)
|
||||||
|
{
|
||||||
|
lua_rawgeti(L, LUA_REGISTRYINDEX, customTools[index].click);
|
||||||
|
lua_pushinteger(L, lsi->gameModel->GetBrushIndex(brush));
|
||||||
|
lua_pushinteger(L, position.X);
|
||||||
|
lua_pushinteger(L, position.Y);
|
||||||
|
lua_pushnumber(L, tool->Strength);
|
||||||
|
lua_pushboolean(L, tool->shiftBehaviour);
|
||||||
|
lua_pushboolean(L, tool->ctrlBehaviour);
|
||||||
|
lua_pushboolean(L, tool->altBehaviour);
|
||||||
|
if (tpt_lua_pcall(L, 7, 0, 0, eventTraitNone))
|
||||||
|
{
|
||||||
|
lsi->Log(CommandInterface::LogError, "In click func: " + LuaGetError());
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void luaDragWrapper(SimTool *tool, Simulation *sim, const Brush &brush, ui::Point position1, ui::Point position2)
|
||||||
|
{
|
||||||
|
auto *lsi = GetLSI();
|
||||||
|
auto L = lsi->L;
|
||||||
|
auto index = *lsi->gameModel->GetToolIndex(tool);
|
||||||
|
auto &customTools = lsi->customTools;
|
||||||
|
if (customTools[index].drag)
|
||||||
|
{
|
||||||
|
lua_rawgeti(L, LUA_REGISTRYINDEX, customTools[index].drag);
|
||||||
|
lua_pushinteger(L, lsi->gameModel->GetBrushIndex(brush));
|
||||||
|
lua_pushinteger(L, position1.X);
|
||||||
|
lua_pushinteger(L, position1.Y);
|
||||||
|
lua_pushinteger(L, position2.X);
|
||||||
|
lua_pushinteger(L, position2.Y);
|
||||||
|
lua_pushnumber(L, tool->Strength);
|
||||||
|
lua_pushboolean(L, tool->shiftBehaviour);
|
||||||
|
lua_pushboolean(L, tool->ctrlBehaviour);
|
||||||
|
lua_pushboolean(L, tool->altBehaviour);
|
||||||
|
if (tpt_lua_pcall(L, 9, 0, 0, eventTraitNone))
|
||||||
|
{
|
||||||
|
lsi->Log(CommandInterface::LogError, "In drag func: " + LuaGetError());
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void luaDrawWrapper(SimTool *tool, Simulation *sim, const Brush &brush, ui::Point position)
|
||||||
|
{
|
||||||
|
auto *lsi = GetLSI();
|
||||||
|
auto L = lsi->L;
|
||||||
|
auto index = *lsi->gameModel->GetToolIndex(tool);
|
||||||
|
auto &customTools = lsi->customTools;
|
||||||
|
if (customTools[index].draw)
|
||||||
|
{
|
||||||
|
lua_rawgeti(L, LUA_REGISTRYINDEX, customTools[index].draw);
|
||||||
|
lua_pushinteger(L, lsi->gameModel->GetBrushIndex(brush));
|
||||||
|
lua_pushinteger(L, position.X);
|
||||||
|
lua_pushinteger(L, position.Y);
|
||||||
|
lua_pushnumber(L, tool->Strength);
|
||||||
|
lua_pushboolean(L, tool->shiftBehaviour);
|
||||||
|
lua_pushboolean(L, tool->ctrlBehaviour);
|
||||||
|
lua_pushboolean(L, tool->altBehaviour);
|
||||||
|
if (tpt_lua_pcall(L, 7, 0, 0, eventTraitNone))
|
||||||
|
{
|
||||||
|
lsi->Log(CommandInterface::LogError, "In draw func: " + LuaGetError());
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void luaDrawLineWrapper(SimTool *tool, Simulation *sim, const Brush &brush, ui::Point position1, ui::Point position2, bool dragging)
|
||||||
|
{
|
||||||
|
auto *lsi = GetLSI();
|
||||||
|
auto L = lsi->L;
|
||||||
|
auto index = *lsi->gameModel->GetToolIndex(tool);
|
||||||
|
auto &customTools = lsi->customTools;
|
||||||
|
if (customTools[index].drawLine)
|
||||||
|
{
|
||||||
|
lua_rawgeti(L, LUA_REGISTRYINDEX, customTools[index].drawLine);
|
||||||
|
lua_pushinteger(L, lsi->gameModel->GetBrushIndex(brush));
|
||||||
|
lua_pushinteger(L, position1.X);
|
||||||
|
lua_pushinteger(L, position1.Y);
|
||||||
|
lua_pushinteger(L, position2.X);
|
||||||
|
lua_pushinteger(L, position2.Y);
|
||||||
|
lua_pushnumber(L, tool->Strength);
|
||||||
|
lua_pushboolean(L, tool->shiftBehaviour);
|
||||||
|
lua_pushboolean(L, tool->ctrlBehaviour);
|
||||||
|
lua_pushboolean(L, tool->altBehaviour);
|
||||||
|
if (tpt_lua_pcall(L, 9, 0, 0, eventTraitNone))
|
||||||
|
{
|
||||||
|
lsi->Log(CommandInterface::LogError, "In drawLine func: " + LuaGetError());
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void luaDrawRectWrapper(SimTool *tool, Simulation *sim, const Brush &brush, ui::Point position1, ui::Point position2)
|
||||||
|
{
|
||||||
|
auto *lsi = GetLSI();
|
||||||
|
auto L = lsi->L;
|
||||||
|
auto index = *lsi->gameModel->GetToolIndex(tool);
|
||||||
|
auto &customTools = lsi->customTools;
|
||||||
|
if (customTools[index].drawRect)
|
||||||
|
{
|
||||||
|
lua_rawgeti(L, LUA_REGISTRYINDEX, customTools[index].drawRect);
|
||||||
|
lua_pushinteger(L, lsi->gameModel->GetBrushIndex(brush));
|
||||||
|
lua_pushinteger(L, position1.X);
|
||||||
|
lua_pushinteger(L, position1.Y);
|
||||||
|
lua_pushinteger(L, position2.X);
|
||||||
|
lua_pushinteger(L, position2.Y);
|
||||||
|
lua_pushnumber(L, tool->Strength);
|
||||||
|
lua_pushboolean(L, tool->shiftBehaviour);
|
||||||
|
lua_pushboolean(L, tool->ctrlBehaviour);
|
||||||
|
lua_pushboolean(L, tool->altBehaviour);
|
||||||
|
if (tpt_lua_pcall(L, 9, 0, 0, eventTraitNone))
|
||||||
|
{
|
||||||
|
lsi->Log(CommandInterface::LogError, "In drawRect func: " + LuaGetError());
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void luaDrawFillWrapper(SimTool *tool, Simulation *sim, const Brush &brush, ui::Point position)
|
||||||
|
{
|
||||||
|
auto *lsi = GetLSI();
|
||||||
|
auto L = lsi->L;
|
||||||
|
auto index = *lsi->gameModel->GetToolIndex(tool);
|
||||||
|
auto &customTools = lsi->customTools;
|
||||||
|
if (customTools[index].drawFill)
|
||||||
|
{
|
||||||
|
lua_rawgeti(L, LUA_REGISTRYINDEX, customTools[index].drawFill);
|
||||||
|
lua_pushinteger(L, lsi->gameModel->GetBrushIndex(brush));
|
||||||
|
lua_pushinteger(L, position.X);
|
||||||
|
lua_pushinteger(L, position.Y);
|
||||||
|
lua_pushnumber(L, tool->Strength);
|
||||||
|
lua_pushboolean(L, tool->shiftBehaviour);
|
||||||
|
lua_pushboolean(L, tool->ctrlBehaviour);
|
||||||
|
lua_pushboolean(L, tool->altBehaviour);
|
||||||
|
if (tpt_lua_pcall(L, 7, 0, 0, eventTraitNone))
|
||||||
|
{
|
||||||
|
lsi->Log(CommandInterface::LogError, "In drawFill func: " + LuaGetError());
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct DependentFalse : std::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
static int property(lua_State *L)
|
||||||
|
{
|
||||||
|
auto *lsi = GetLSI();
|
||||||
|
int index = luaL_checkinteger(L, 1);
|
||||||
|
auto *tool = lsi->gameModel->GetToolByIndex(index);
|
||||||
|
if (!tool)
|
||||||
|
{
|
||||||
|
return luaL_error(L, "Invalid tool");
|
||||||
|
}
|
||||||
|
ByteString propertyName = tpt_lua_checkByteString(L, 2);
|
||||||
|
auto handleCallback = [lsi, L, index, tool, &propertyName](
|
||||||
|
auto customToolMember,
|
||||||
|
auto simToolMember,
|
||||||
|
auto wrapper,
|
||||||
|
const char *luaPropertyName
|
||||||
|
) {
|
||||||
|
if (propertyName == luaPropertyName)
|
||||||
|
{
|
||||||
|
if (lua_gettop(L) > 2)
|
||||||
|
{
|
||||||
|
if (IsDefault(tool))
|
||||||
|
{
|
||||||
|
luaL_error(L, "Cannot change callbacks of default tools");
|
||||||
|
}
|
||||||
|
if (lua_type(L, 3) == LUA_TFUNCTION)
|
||||||
|
{
|
||||||
|
(lsi->customTools[index].*customToolMember).Assign(L, 3);
|
||||||
|
(static_cast<SimTool *>(tool)->*simToolMember) = wrapper;
|
||||||
|
}
|
||||||
|
else if (lua_type(L, 3) == LUA_TBOOLEAN && !lua_toboolean(L, 3))
|
||||||
|
{
|
||||||
|
(lsi->customTools[index].*customToolMember).Clear();
|
||||||
|
(static_cast<SimTool *>(tool)->*simToolMember) = SimTool().*simToolMember;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
luaL_error(L, "Invalid tool property");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
if (handleCallback(&CustomTool::perform , &SimTool::Perform , luaPerformWrapper , "Perform" ) ||
|
||||||
|
handleCallback(&CustomTool::click , &SimTool::PerformClick , luaClickWrapper , "Click" ) ||
|
||||||
|
handleCallback(&CustomTool::drag , &SimTool::PerformDrag , luaDragWrapper , "Drag" ) ||
|
||||||
|
handleCallback(&CustomTool::draw , &SimTool::PerformDraw , luaDrawWrapper , "Draw" ) ||
|
||||||
|
handleCallback(&CustomTool::drawLine, &SimTool::PerformDrawLine, luaDrawLineWrapper, "DrawLine") ||
|
||||||
|
handleCallback(&CustomTool::drawRect, &SimTool::PerformDrawRect, luaDrawRectWrapper, "DrawRect") ||
|
||||||
|
handleCallback(&CustomTool::drawFill, &SimTool::PerformDrawFill, luaDrawFillWrapper, "DrawFill"))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int returnValueCount = 0;
|
||||||
|
auto handleProperty = [L, tool, &propertyName, &returnValueCount](auto simToolMember, const char *luaPropertyName) {
|
||||||
|
if (propertyName == luaPropertyName)
|
||||||
|
{
|
||||||
|
auto &thing = tool->*simToolMember;
|
||||||
|
using PropertyType = std::remove_reference_t<decltype(thing)>;
|
||||||
|
if (lua_gettop(L) > 2)
|
||||||
|
{
|
||||||
|
if constexpr (std::is_same_v<PropertyType, String >) thing = tpt_lua_checkString(L, 3);
|
||||||
|
else if constexpr (std::is_same_v<PropertyType, RGB<uint8_t>>) thing = RGB<uint8_t>::Unpack(luaL_checkinteger(L, 3));
|
||||||
|
else static_assert(DependentFalse<PropertyType>::value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if constexpr (std::is_same_v<PropertyType, String >) tpt_lua_pushString(L, thing);
|
||||||
|
else if constexpr (std::is_same_v<PropertyType, RGB<uint8_t>>) lua_pushinteger(L, thing.Pack());
|
||||||
|
else static_assert(DependentFalse<PropertyType>::value);
|
||||||
|
returnValueCount = 1;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
if (handleProperty(&SimTool::Name , "Name" ) ||
|
||||||
|
handleProperty(&SimTool::Description, "Description") ||
|
||||||
|
handleProperty(&SimTool::Colour , "Colour" ) ||
|
||||||
|
handleProperty(&SimTool::Colour , "Color" ))
|
||||||
|
{
|
||||||
|
return returnValueCount;
|
||||||
|
}
|
||||||
|
if (propertyName == "Identifier")
|
||||||
|
{
|
||||||
|
tpt_lua_pushByteString(L, tool->Identifier);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return luaL_error(L, "Invalid tool property");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int exists(lua_State *L)
|
||||||
|
{
|
||||||
|
int index = luaL_checkinteger(L, 1);
|
||||||
|
auto *lsi = GetLSI();
|
||||||
|
lua_pushboolean(L, bool(lsi->gameModel->GetToolByIndex(index)));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaTools::Open(lua_State *L)
|
||||||
|
{
|
||||||
|
auto *lsi = GetLSI();
|
||||||
|
static const luaL_Reg reg[] = {
|
||||||
|
#define LFUNC(v) { #v, v }
|
||||||
|
LFUNC(allocate),
|
||||||
|
LFUNC(property),
|
||||||
|
LFUNC(exists),
|
||||||
|
#undef LFUNC
|
||||||
|
{ "free", ffree },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
lua_newtable(L);
|
||||||
|
luaL_register(L, NULL, reg);
|
||||||
|
lua_setglobal(L, "tools");
|
||||||
|
auto &toolList = lsi->gameModel->GetTools();
|
||||||
|
for (int i = 0; i < int(toolList.size()); ++i)
|
||||||
|
{
|
||||||
|
if (!toolList[i])
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
SetToolIndex(L, toolList[i]->Identifier, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaTools::SetToolIndex(lua_State *L, ByteString identifier, std::optional<int> index)
|
||||||
|
{
|
||||||
|
lua_getglobal(L, "tools");
|
||||||
|
tpt_lua_pushByteString(L, identifier);
|
||||||
|
if (index)
|
||||||
|
{
|
||||||
|
lua_pushinteger(L, *index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lua_pushnil(L);
|
||||||
|
}
|
||||||
|
lua_settable(L, -3);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
@ -37,3 +37,7 @@ String CommandInterface::FormatCommand(String command)
|
|||||||
{
|
{
|
||||||
return PlainFormatCommand(command);
|
return PlainFormatCommand(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CommandInterface::SetToolIndex(ByteString identifier, std::optional<int> index)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@ -55,15 +55,15 @@ tpt.setfpscap = tpt.fpsCap
|
|||||||
ui.MOUSE_UP_BLUR = ui.MOUSEUP_BLUR
|
ui.MOUSE_UP_BLUR = ui.MOUSEUP_BLUR
|
||||||
ui.MOUSE_UP_DRAW_END = ui.MOUSEUP_DRAWEND
|
ui.MOUSE_UP_DRAW_END = ui.MOUSEUP_DRAWEND
|
||||||
ui.MOUSE_UP_NORMAL = ui.MOUSEUP_NORMAL
|
ui.MOUSE_UP_NORMAL = ui.MOUSEUP_NORMAL
|
||||||
sim.TOOL_HEAT = sim.tools.DEFAULT_TOOL_HEAT
|
sim.TOOL_HEAT = tools.DEFAULT_TOOL_HEAT
|
||||||
sim.TOOL_COOL = sim.tools.DEFAULT_TOOL_COOL
|
sim.TOOL_COOL = tools.DEFAULT_TOOL_COOL
|
||||||
sim.TOOL_VAC = sim.tools.DEFAULT_TOOL_VAC
|
sim.TOOL_VAC = tools.DEFAULT_TOOL_VAC
|
||||||
sim.TOOL_PGRV = sim.tools.DEFAULT_TOOL_PGRV
|
sim.TOOL_PGRV = tools.DEFAULT_TOOL_PGRV
|
||||||
sim.TOOL_AIR = sim.tools.DEFAULT_TOOL_AIR
|
sim.TOOL_AIR = tools.DEFAULT_TOOL_AIR
|
||||||
sim.TOOL_NGRV = sim.tools.DEFAULT_TOOL_NGRV
|
sim.TOOL_NGRV = tools.DEFAULT_TOOL_NGRV
|
||||||
sim.TOOL_MIX = sim.tools.DEFAULT_TOOL_MIX
|
sim.TOOL_MIX = tools.DEFAULT_TOOL_MIX
|
||||||
sim.TOOL_CYCL = sim.tools.DEFAULT_TOOL_CYCL
|
sim.TOOL_CYCL = tools.DEFAULT_TOOL_CYCL
|
||||||
sim.TOOL_WIND = sim.tools.DEFAULT_TOOL_WIND
|
sim.TOOL_WIND = tools.DEFAULT_TOOL_WIND
|
||||||
if socket then
|
if socket then
|
||||||
socket.gettime = socket.getTime
|
socket.gettime = socket.getTime
|
||||||
end
|
end
|
||||||
|
@ -21,6 +21,7 @@ luaconsole_files = files(
|
|||||||
'LuaSocket.cpp',
|
'LuaSocket.cpp',
|
||||||
'LuaSmartRef.cpp',
|
'LuaSmartRef.cpp',
|
||||||
'LuaTextbox.cpp',
|
'LuaTextbox.cpp',
|
||||||
|
'LuaTools.cpp',
|
||||||
'LuaWindow.cpp',
|
'LuaWindow.cpp',
|
||||||
)
|
)
|
||||||
if lua_variant != 'luajit'
|
if lua_variant != 'luajit'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user