Skip to content

Commit 6f94d67

Browse files
authored
Merge pull request #6063 from Goober5000/sexp_boolean
allow boolean and numeric scripted SEXPs to return special values
2 parents 0ffd9bc + 897e388 commit 6f94d67

File tree

4 files changed

+58
-1
lines changed

4 files changed

+58
-1
lines changed

code/parse/sexp/LuaSEXP.cpp

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "parse/parselo.h"
1111
#include "parse/sexp.h"
1212
#include "parse/sexp/sexp_lookup.h"
13+
#include "scripting/api/objs/enums.h"
1314
#include "scripting/api/objs/hudgauge.h"
1415
#include "scripting/api/objs/message.h"
1516
#include "scripting/api/objs/model.h"
@@ -32,7 +33,8 @@ using namespace luacpp;
3233

3334
namespace sexp {
3435

35-
static SCP_unordered_map<SCP_string, int> parameter_type_mapping{{ "boolean", OPF_BOOL },
36+
static SCP_unordered_map<SCP_string, int> parameter_type_mapping {
37+
{ "boolean", OPF_BOOL },
3638
{ "number", OPF_NUMBER },
3739
{ "ship", OPF_SHIP },
3840
{ "shipname", OPF_SHIP },
@@ -337,6 +339,34 @@ luacpp::LuaValue LuaSEXP::sexpToLua(int node, int argnum, int parent_node) const
337339
}
338340
}
339341
}
342+
bool LuaSEXP::maybeExtractSexpSpecialRetVal(const luacpp::LuaValue& value, int& sexp_retval) {
343+
// see if this return value is actually a SEXP_ enum
344+
if (value.getValueType() == ValueType::USERDATA) {
345+
try {
346+
using namespace scripting::api;
347+
enum_h enumeration;
348+
value.getValue(l_Enum.Get(&enumeration)); // this might throw a LuaException
349+
switch (enumeration.index) {
350+
case LE_SEXP_TRUE:
351+
case LE_SEXP_FALSE:
352+
case LE_SEXP_KNOWN_FALSE:
353+
case LE_SEXP_KNOWN_TRUE:
354+
case LE_SEXP_UNKNOWN:
355+
case LE_SEXP_NAN:
356+
case LE_SEXP_NAN_FOREVER:
357+
case LE_SEXP_CANT_EVAL:
358+
sexp_retval = *enumeration.value;
359+
return true;
360+
default:
361+
break;
362+
}
363+
} catch (const LuaException& le) {
364+
// just ignore the exception because we follow a different code path if the conversion failed
365+
SCP_UNUSED(le);
366+
}
367+
}
368+
return false;
369+
}
340370
int LuaSEXP::getSexpReturnValue(const LuaValueList& retVals) const {
341371
switch (_return_type) {
342372
case OPR_NUMBER:
@@ -347,6 +377,10 @@ int LuaSEXP::getSexpReturnValue(const LuaValueList& retVals) const {
347377
retVals.size());
348378
return 0;
349379
} else if (retVals[0].getValueType() != ValueType::NUMBER) {
380+
int sexp_retval;
381+
if (maybeExtractSexpSpecialRetVal(retVals[0], sexp_retval)) {
382+
return sexp_retval;
383+
}
350384
Warning(LOCATION, "Wrong return type detected for Lua SEXP '%s', expected a number.", _name.c_str());
351385
return 0;
352386
} else {
@@ -360,6 +394,10 @@ int LuaSEXP::getSexpReturnValue(const LuaValueList& retVals) const {
360394
retVals.size());
361395
return SEXP_FALSE;
362396
} else if (retVals[0].getValueType() != ValueType::BOOLEAN) {
397+
int sexp_retval;
398+
if (maybeExtractSexpSpecialRetVal(retVals[0], sexp_retval)) {
399+
return sexp_retval;
400+
}
363401
Warning(LOCATION, "Wrong return type detected for Lua SEXP '%s', expected a boolean.", _name.c_str());
364402
return SEXP_FALSE;
365403
} else {

code/parse/sexp/LuaSEXP.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ class LuaSEXP : public DynamicSEXP {
3030
// just a helper for parseTable
3131
static bool parseCheckEndOfDescription();
3232

33+
// another helper
34+
static bool maybeExtractSexpSpecialRetVal(const luacpp::LuaValue& value, int& sexp_retval);
35+
3336
public:
3437
static std::pair<SCP_string, int> get_parameter_type(const SCP_string& name);
3538
static int get_return_type(const SCP_string& name);

code/scripting/api/objs/enums.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,14 @@ const lua_enum_def_list Enumerations[] = {
172172
{"SCROLLBACK_SOURCE_SATISFIED", LE_SCROLLBACK_SOURCE_SATISFIED, true},
173173
{"SCROLLBACK_SOURCE_COMMAND", LE_SCROLLBACK_SOURCE_COMMAND, true},
174174
{"SCROLLBACK_SOURCE_NETPLAYER", LE_SCROLLBACK_SOURCE_NETPLAYER, true},
175+
{"SEXP_TRUE", LE_SEXP_TRUE, SEXP_TRUE, true},
176+
{"SEXP_FALSE", LE_SEXP_FALSE, SEXP_FALSE, true},
177+
{"SEXP_KNOWN_FALSE", LE_SEXP_KNOWN_FALSE, SEXP_KNOWN_FALSE, true},
178+
{"SEXP_KNOWN_TRUE", LE_SEXP_KNOWN_TRUE, SEXP_KNOWN_TRUE, true},
179+
{"SEXP_UNKNOWN", LE_SEXP_UNKNOWN, SEXP_UNKNOWN, true},
180+
{"SEXP_NAN", LE_SEXP_NAN, SEXP_NAN, true},
181+
{"SEXP_NAN_FOREVER", LE_SEXP_NAN_FOREVER, SEXP_NAN_FOREVER, true},
182+
{"SEXP_CANT_EVAL", LE_SEXP_CANT_EVAL, SEXP_CANT_EVAL, true},
175183
};
176184

177185
const size_t Num_enumerations = sizeof(Enumerations) / sizeof(lua_enum_def_list);

code/scripting/api/objs/enums.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,14 @@ enum lua_enum : int32_t {
171171
LE_SCROLLBACK_SOURCE_SATISFIED,
172172
LE_SCROLLBACK_SOURCE_COMMAND,
173173
LE_SCROLLBACK_SOURCE_NETPLAYER,
174+
LE_SEXP_TRUE,
175+
LE_SEXP_FALSE,
176+
LE_SEXP_KNOWN_FALSE,
177+
LE_SEXP_KNOWN_TRUE,
178+
LE_SEXP_UNKNOWN,
179+
LE_SEXP_NAN,
180+
LE_SEXP_NAN_FOREVER,
181+
LE_SEXP_CANT_EVAL,
174182
ENUM_NEXT_INDEX,
175183
ENUM_COMBINATION,
176184
ENUM_INVALID

0 commit comments

Comments
 (0)