Skip to content

Commit f0ee1e2

Browse files
committed
electrical arc upgrade, stage 4: add a new ModifyElectricArcPoints function with a handy valueToVec3d utility function
1 parent 47025a7 commit f0ee1e2

File tree

3 files changed

+152
-0
lines changed

3 files changed

+152
-0
lines changed

code/scripting/api/objs/ship.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
#include "ship/shiphit.h"
3939
#include "waypoint.h"
4040

41+
#include "scripting/lua/LuaException.h"
42+
#include "scripting/lua/LuaUtil.h"
43+
4144
extern void ship_reset_disabled_physics(object *objp, int ship_class);
4245
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);
4346
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);
@@ -2902,5 +2905,68 @@ ADE_FUNC(ModifyElectricArc, l_Ship, "number index, vector firstPoint, vector sec
29022905
return ADE_RETURN_NIL;
29032906
}
29042907

2908+
ADE_FUNC(ModifyElectricArcPoints, l_Ship, "number index, table points, [number width]",
2909+
"Sets the collection of persistent points to be used by this arc, as well as optionally the arc's width. "
2910+
"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.",
2911+
nullptr,
2912+
nullptr)
2913+
{
2914+
object_h* objh = nullptr;
2915+
int index;
2916+
luacpp::LuaTable luaPoints;
2917+
float width = 0.0f;
2918+
2919+
int args = ade_get_args(L, "oit|f", l_Ship.GetPtr(&objh), &index, &luaPoints, &width);
2920+
if (args < 3)
2921+
return ADE_RETURN_NIL;
2922+
2923+
if (!objh->isValid())
2924+
return ADE_RETURN_NIL;
2925+
2926+
auto shipp = &Ships[objh->objp()->instance];
2927+
2928+
index--; // Lua -> FS2
2929+
if (SCP_vector_inbounds(shipp->electrical_arcs, index) && luaPoints.isValid())
2930+
{
2931+
SCP_vector<vec3d> fsoPoints;
2932+
2933+
// convert Lua points to FSO points
2934+
for (const auto &entry : luaPoints)
2935+
{
2936+
try
2937+
{
2938+
fsoPoints.push_back(luacpp::util::valueToVec3d(entry.second));
2939+
}
2940+
catch (const luacpp::LuaException &e)
2941+
{
2942+
LuaError(L, "%s", e.what());
2943+
return ADE_RETURN_NIL;
2944+
}
2945+
}
2946+
2947+
if (fsoPoints.size() < 2)
2948+
{
2949+
LuaError(L, "Points table passed to ship:ModifyElectricArcPoints() has fewer than two points!");
2950+
return ADE_RETURN_NIL;
2951+
}
2952+
2953+
auto &arc = shipp->electrical_arcs[index];
2954+
arc.endpoint_1 = fsoPoints.front();
2955+
arc.endpoint_2 = fsoPoints.back();
2956+
2957+
// need to create the persistent point storage if it isn't set up yet
2958+
if (!arc.persistent_arc_points)
2959+
arc.persistent_arc_points.reset(new SCP_vector<vec3d>());
2960+
2961+
// assign all of our new points to the persistent point storage
2962+
arc.persistent_arc_points->operator=(std::move(fsoPoints));
2963+
2964+
if (args >= 4)
2965+
arc.width = width;
2966+
}
2967+
2968+
return ADE_RETURN_NIL;
2969+
}
2970+
29052971
}
29062972
}

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)