Skip to content

Commit 2606d31

Browse files
committed
electrical arc upgrade, stage 4: add a new ModifyElectricArcPoints function with a handy valueToVec3d utility function
1 parent 8548e7f commit 2606d31

3 files changed

Lines changed: 152 additions & 0 deletions

File tree

code/scripting/api/objs/ship.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
#include "ship/shipfx.h"
3737
#include "ship/shiphit.h"
3838

39+
#include "scripting/lua/LuaException.h"
40+
#include "scripting/lua/LuaUtil.h"
41+
3942
extern void ship_reset_disabled_physics(object *objp, int ship_class);
4043
extern bool sexp_check_flag_arrays(const char *flag_name, Object::Object_Flags &object_flag, Ship::Ship_Flags &ship_flags, Mission::Parse_Object_Flags &parse_obj_flag, AI::AI_Flags &ai_flag);
4144
extern void sexp_alter_ship_flag_helper(object_ship_wing_point_team &oswpt, bool future_ships, Object::Object_Flags object_flag, Ship::Ship_Flags ship_flag, Mission::Parse_Object_Flags parse_obj_flag, AI::AI_Flags ai_flag, bool set_flag);
@@ -2824,5 +2827,68 @@ ADE_FUNC(ModifyElectricArc, l_Ship, "number index, vector firstPoint, vector sec
28242827
return ADE_RETURN_NIL;
28252828
}
28262829

2830+
ADE_FUNC(ModifyElectricArcPoints, l_Ship, "number index, table points, [number width]",
2831+
"Sets the collection of persistent points to be used by this arc, as well as optionally the arc's width. "
2832+
"The table of points should consist of Vectors (e.g. created with ba.createVector()), arrays with three elements each, or tables with 'x'/'X', 'y'/'Y', and 'z'/'Z' pairs. There must be at least two points.",
2833+
nullptr,
2834+
nullptr)
2835+
{
2836+
object_h* objh = nullptr;
2837+
int index;
2838+
luacpp::LuaTable luaPoints;
2839+
float width = 0.0f;
2840+
2841+
int args = ade_get_args(L, "oit|f", l_Ship.GetPtr(&objh), &index, &luaPoints, &width);
2842+
if (args < 3)
2843+
return ADE_RETURN_NIL;
2844+
2845+
if (!objh->isValid())
2846+
return ADE_RETURN_NIL;
2847+
2848+
auto shipp = &Ships[objh->objp()->instance];
2849+
2850+
index--; // Lua -> FS2
2851+
if (SCP_vector_inbounds(shipp->electrical_arcs, index) && luaPoints.isValid())
2852+
{
2853+
SCP_vector<vec3d> fsoPoints;
2854+
2855+
// convert Lua points to FSO points
2856+
for (const auto &entry : luaPoints)
2857+
{
2858+
try
2859+
{
2860+
fsoPoints.push_back(luacpp::util::valueToVec3d(entry.second));
2861+
}
2862+
catch (const luacpp::LuaException &e)
2863+
{
2864+
LuaError(L, "%s", e.what());
2865+
return ADE_RETURN_NIL;
2866+
}
2867+
}
2868+
2869+
if (fsoPoints.size() < 2)
2870+
{
2871+
LuaError(L, "Points table passed to ship:ModifyElectricArcPoints() has fewer than two points!");
2872+
return ADE_RETURN_NIL;
2873+
}
2874+
2875+
auto &arc = shipp->electrical_arcs[index];
2876+
arc.endpoint_1 = fsoPoints.front();
2877+
arc.endpoint_2 = fsoPoints.back();
2878+
2879+
// need to create the persistent point storage if it isn't set up yet
2880+
if (!arc.persistent_arc_points)
2881+
arc.persistent_arc_points.reset(new SCP_vector<vec3d>());
2882+
2883+
// assign all of our new points to the persistent point storage
2884+
arc.persistent_arc_points->operator=(std::move(fsoPoints));
2885+
2886+
if (args >= 4)
2887+
arc.width = width;
2888+
}
2889+
2890+
return ADE_RETURN_NIL;
2891+
}
2892+
28272893
}
28282894
}

code/scripting/lua/LuaUtil.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11

22
#include "LuaUtil.h"
33

4+
#include "scripting/api/objs/vecmath.h"
5+
46
namespace {
57
const char* mainStateRefName = "_lua_mainthread";
68
}
@@ -62,5 +64,81 @@ lua_State* getMainThread(lua_State* L)
6264
return state;
6365
}
6466

67+
vec3d valueToVec3d(const LuaValue &luaValue)
68+
{
69+
if (luaValue.is(luacpp::ValueType::TABLE))
70+
{
71+
vec3d tablePoint = vmd_zero_vector;
72+
int index = 0;
73+
bool is_array = false;
74+
bool is_table = false;
75+
76+
// we have to go deeper
77+
luacpp::LuaTable childTable;
78+
childTable.setReference(luaValue.getReference());
79+
for (const auto &childEntry : childTable)
80+
{
81+
// note: this is pre-increment
82+
if (index >= 3)
83+
throw LuaException("Vec3d table has more than three entries!");
84+
85+
if (!childEntry.second.is(luacpp::ValueType::NUMBER))
86+
throw LuaException("Value in vec3d table is not a number!");
87+
88+
auto number = static_cast<float>(childEntry.second.getValue<double>());
89+
90+
if (childEntry.first.is(luacpp::ValueType::STRING))
91+
{
92+
is_table = true;
93+
if (is_array)
94+
throw LuaException("Vec3d table has an unexpected format!");
95+
96+
const auto &str = childEntry.first.getValue<SCP_string>();
97+
if (lcase_equal(str, "x"))
98+
tablePoint.xyz.x = number;
99+
else if (lcase_equal(str, "y"))
100+
tablePoint.xyz.y = number;
101+
else if (lcase_equal(str, "z"))
102+
tablePoint.xyz.z = number;
103+
else
104+
throw LuaException("Vec3d table has an entry other than x/X, y/Y, or z/Z!");
105+
}
106+
else
107+
{
108+
is_array = true;
109+
if (is_table)
110+
throw LuaException("Vec3d table has an unexpected format!");
111+
112+
tablePoint.a1d[index] = number;
113+
}
114+
115+
index++;
116+
}
117+
118+
// note: this is post-increment
119+
if (index < 3)
120+
throw LuaException("Vec3d table has fewer than three entries!");
121+
122+
return tablePoint;
123+
}
124+
else if (luaValue.is(luacpp::ValueType::USERDATA))
125+
{
126+
try
127+
{
128+
vec3d v;
129+
luaValue.getValue(scripting::api::l_Vector.Get(&v));
130+
return v;
131+
}
132+
catch (const luacpp::LuaException& /*e*/)
133+
{
134+
throw LuaException("Userdata in vec3d table is not a vector!");
135+
}
136+
}
137+
else
138+
{
139+
throw LuaException("Vec3d value is of an unhandled type!");
140+
}
141+
}
142+
65143
} // namespace util
66144
} // namespace luacpp

code/scripting/lua/LuaUtil.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ void tableToList(LuaTable& table, Container& list) {
9191
}
9292

9393
const char* getValueName(ValueType type);
94+
95+
/**
96+
* Processes a LuaValue and returns a vec3d. The LuaValue could be a Vector, an array with three elements, or a table with x/X, y/Y, and z/Z entries.
97+
*
98+
* Throws a LuaException if the conversion was not successful.
99+
*/
100+
vec3d valueToVec3d(const LuaValue &luaValue);
101+
94102
}
95103
}
96104

0 commit comments

Comments
 (0)