Skip to content

Commit

Permalink
Feature: register new lua functions DrawBuildSquare and `DrawBuildS…
Browse files Browse the repository at this point in the history
…quareArray` to show build squares on custom building commands
  • Loading branch information
Aurelien Lambert committed Oct 29, 2024
1 parent 19b0efc commit 6dc9651
Show file tree
Hide file tree
Showing 9 changed files with 463 additions and 19 deletions.
7 changes: 7 additions & 0 deletions rts/Game/UI/CommandColors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,17 @@ CCommandColors::CCommandColors()
SETUP_COLOR(rangeSelfDestruct, 0.8f, 0.1f, 0.1f, 0.7f);
SETUP_COLOR(rangeInterceptorOn, 1.0f, 1.0f, 1.0f, 0.7f);
SETUP_COLOR(rangeInterceptorOff, 0.0f, 0.0f, 0.0f, 0.7f);

SETUP_COLOR(unitBox, 0.0f, 1.0f, 0.0f, 0.9f);
SETUP_COLOR(buildBox, 0.0f, 1.0f, 0.0f, 0.9f);
SETUP_COLOR(allyBuildBox, 0.8f, 0.8f, 0.2f, 0.9f);
SETUP_COLOR(mouseBox, 1.0f, 1.0f, 1.0f, 0.9f);
SETUP_COLOR(buildableSquare, 0.0f, 0.9f, 0.0f, 0.7f);
SETUP_COLOR(unbuildableSquare, 0.9f, 0.8f, 0.0f, 0.7f);
SETUP_COLOR(featureSquare, 0.9f, 0.8f, 0.0f, 0.7f);
SETUP_COLOR(illegalSquare, 0.9f, 0.0f, 0.0f, 0.7f);
SETUP_COLOR(undergroundStart, 0.0f, 0.0f, 1.0f, 0.5f);
SETUP_COLOR(undergroundEnd, 0.0f, 0.5f, 1.0f, 1.0f);
}


Expand Down
12 changes: 12 additions & 0 deletions rts/Game/UI/CommandColors.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ class CCommandColors {
const float* buildBox;
const float* allyBuildBox;
const float* mouseBox;
const float* buildableSquare;
const float* unbuildableSquare;
const float* featureSquare;
const float* illegalSquare;
const float* undergroundStart;
const float* undergroundEnd;

// for command queue rendering
const float* start;
Expand Down Expand Up @@ -156,6 +162,12 @@ class CCommandColors {
buildBoxIndex,
allyBuildBoxIndex,
mouseBoxIndex,
buildableSquareIndex,
unbuildableSquareIndex,
featureSquareIndex,
illegalSquareIndex,
undergroundStartIndex,
undergroundEndIndex,

ColorCount
};
Expand Down
222 changes: 222 additions & 0 deletions rts/Lua/LuaUnsyncedCtrl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ bool LuaUnsyncedCtrl::PushEntries(lua_State* L)
REGISTER_LUA_CFUNC(AddWorldUnit);

REGISTER_LUA_CFUNC(DrawUnitCommands);
REGISTER_LUA_CFUNC(DrawBuildSquare);
REGISTER_LUA_CFUNC(DrawBuildSquareArray);

REGISTER_LUA_CFUNC(SetTeamColor);

Expand Down Expand Up @@ -3382,6 +3384,226 @@ int LuaUnsyncedCtrl::SetBuildFacing(lua_State* L)
}


static bool ParseBuildInfo(
lua_State* L,
BuildInfo& buildInfo,
const char* caller,
int idx
) {
for (int i=0; i<5; i++) {
if (!lua_isnumber(L, idx+i)) {
luaL_error(L, "%s(): bad build info type", caller);
return false;
}
}

int unitDefID = lua_toint(L, idx);
float3 pos = {lua_tofloat(L, idx+1), lua_tofloat(L, idx+2), lua_tofloat(L, idx+3)};
int facing = lua_toint(L, idx+4);

buildInfo = BuildInfo(unitDefID, pos, facing);
return true;
}


static bool ParseBuildInfoTable(
lua_State* L,
BuildInfo& buildInfo,
const char* caller,
int idx
) {
if (!lua_istable(L, idx)) {
luaL_error(L, "%s(): bad build info type", caller);
return false;
}

lua_rawgeti(L, idx, 1);
if (!lua_isnumber(L, -1)) {
luaL_error(L, "%s(): bad unit def ID", caller);
return false;
}
int unitDefID = lua_toint(L, -1);
lua_pop(L, 1);

float3 pos;
for (int i=0; i<3; i++) {
lua_rawgeti(L, idx, i+2);
if (!lua_isnumber(L, -1)) {
luaL_error(L, "%s(): bad pos", caller);
return false;
}
pos[i] = lua_tofloat(L, -1);
lua_pop(L, 1);
}

lua_rawgeti(L, idx, 5);
if (!lua_isnumber(L, -1)) {
luaL_error(L, "%s(): bad facing", caller);
return false;
}
int facing = lua_toint(L, -1);
lua_pop(L, 1);

buildInfo = BuildInfo(unitDefID, pos, facing);
return true;
}


static bool ParseBuildInfoArray(
lua_State* L,
std::vector<BuildInfo>& buildInfos,
const char* caller,
int idx
) {
if (!lua_istable(L, idx)) {
luaL_error(L, "%s(): error parsing build info array", caller);
return false;
}

for (lua_pushnil(L); lua_next(L, idx) != 0; lua_pop(L, 1)) {
buildInfos.emplace_back();
if (!ParseBuildInfoTable(L, buildInfos.back(), caller, -1)) {
return false;
}
}

return true;
}


static bool ParseBuildSquareOptions(
lua_State* L,
LuaBuildSquareOptions& opts,
const char* caller,
const int idx
) {
if (lua_istable(L, idx)) {
for (lua_pushnil(L); lua_next(L, idx) != 0; lua_pop(L, 1)) {
// "key" = value (table format of CommandNotify)
// ignore the "coded" key; not a boolean value
if (lua_israwstring(L, -2)) {
if (lua_isboolean(L, -1)) {
const bool value = lua_toboolean(L, -1);
switch (hashString(lua_tostring(L, -2))) {
case hashString("unbuildable"):
opts.unbuildable = value;
break;
}
} else if (lua_istable(L, -1)) {
float color[4];
LuaUtils::ParseFloatArray(L, -1, &color[0], 4);
switch (hashString(lua_tostring(L, -2))) {
case hashString("defaultColor"):
opts.defaultColor = &color[0];
break;
case hashString("buildableColor"):
opts.buildableColor = &color[0];
break;
case hashString("unbuildableColor"):
opts.unbuildableColor = &color[0];
break;
case hashString("featureColor"):
opts.featureColor = &color[0];
break;
case hashString("illegalColor"):
opts.illegalColor = &color[0];
break;
}
}
}
}
} else if (!lua_isnil(L, idx)) {
luaL_error(L, "%s(): bad options-argument type", caller);
return false;
}
return true;
}


/***
*
* @function Spring.DrawBuildSquare
* @number unitDefID
* @number x
* @number y
* @number z
* @number facing
* @bool[opt] unbuildable
* @tparam[opt] rgb buildableColor
* @tparam[opt] rgb unbuildableColor
* @tparam[opt] rgb featureColor
* @tparam[opt] rgb illegalColor
* @treturn nil
*/
int LuaUnsyncedCtrl::DrawBuildSquare(lua_State* L)
{
const int args = lua_gettop(L); // number of arguments

BuildInfo buildInfo;
if (!ParseBuildInfo(L, buildInfo, __func__, 1)) {
return 0;
}

LuaBuildSquareOptions opts;
if (args >= 6) {
if (!ParseBuildSquareOptions(L, opts, __func__, 6)) {
return 0;
}
}

unitDrawer->AddLuaBuildSquare(buildInfo, opts);
return 0;
}


/*** Build Info spec
*
* @table buildInfoSpec
*
* Used when assigning multiple commands at once
*
* @number unitDefID
* @number x
* @number y
* @number z
* @number facing
*/


/***
*
* @function Spring.DrawBuildSquareArray
* @tparam {buildInfoSpec,...} buildInfoArray
* @bool[opt] unbuildable
* @tparam[opt] rgb buildableColor
* @tparam[opt] rgb unbuildableColor
* @tparam[opt] rgb featureColor
* @tparam[opt] rgb illegalColor
* @treturn nil
*/
int LuaUnsyncedCtrl::DrawBuildSquareArray(lua_State* L)
{
const int args = lua_gettop(L); // number of arguments

std::vector<BuildInfo> buildInfos;
if (!ParseBuildInfoArray(L, buildInfos, __func__, 1)) {
return 0;
}

LuaBuildSquareOptions opts;
if (args >= 2) {
if (!ParseBuildSquareOptions(L, opts, __func__, 2)) {
return 0;
}
}

for (BuildInfo &buildInfo: buildInfos) {
unitDrawer->AddLuaBuildSquare(buildInfo, opts);
}
return 0;
}


/******************************************************************************
* UI
* @section ui
Expand Down
2 changes: 2 additions & 0 deletions rts/Lua/LuaUnsyncedCtrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class LuaUnsyncedCtrl {
static int AddWorldUnit(lua_State* L);

static int DrawUnitCommands(lua_State* L);
static int DrawBuildSquare(lua_State* L);
static int DrawBuildSquareArray(lua_State* L);

static int SetTeamColor(lua_State* L);

Expand Down
Loading

0 comments on commit 6dc9651

Please sign in to comment.