Make tangible.find use center={x,y,z} instead of centerx= etc

This commit is contained in:
2024-03-13 15:39:09 -04:00
parent 357e3766fb
commit fd8166f09c
7 changed files with 81 additions and 115 deletions

View File

@@ -61,18 +61,8 @@ static AnimValue parse_anim_value(LuaCoreStack &LS, LuaSlot val, LuaSlot tmp) {
result.set_number(LS.cknumber(val));
} else if (LS.isstring(val)) {
result.set_string(LS.ckstring(val));
} else if (LS.istable(val)) {
util::DXYZ xyz;
LS.rawget(tmp, val, 1);
if (!LS.isnumber(tmp)) return result;
xyz.x = LS.cknumber(tmp);
LS.rawget(tmp, val, 2);
if (!LS.isnumber(tmp)) return result;
xyz.y = LS.cknumber(tmp);
LS.rawget(tmp, val, 3);
if (!LS.isnumber(tmp)) return result;
xyz.z = LS.cknumber(tmp);
result.set_dxyz(xyz);
} else if (LS.isxyz(val)) {
result.set_dxyz(LS.ckxyz(val));
} else if (LS.rawequal(val, LuaToken("auto"))) {
result.set_auto();
} else {

View File

@@ -5,15 +5,12 @@
#include "wrap-string.hpp"
#include "wrap-set.hpp"
#include "wrap-sstream.hpp"
#include "util.hpp"
LuaSpecial LuaRegistry(LUA_REGISTRYINDEX);
LuaNilMarker LuaNil;
LuaNewTableMarker LuaNewTable;
inline bool ascii_islower(char c) { return (c >= 'a') && (c <= 'z'); }
inline bool ascii_isupper(char c) { return (c >= 'A') && (c <= 'Z'); }
inline bool ascii_isdigit(char c) { return (c >= '0') && (c <= '9'); }
LuaFunctionReg::LuaFunctionReg(const char *n, const char *a, const char *d, bool s, lua_CFunction f) {
name_ = n;
args_ = a;
@@ -115,6 +112,21 @@ bool LuaCoreStack::isint(LuaSlot s) const {
return false;
}
bool LuaCoreStack::isxyz(LuaSlot s) const {
if (lua_istable(L_, s) && (lua_nkeys(L_, s) == 3)) {
int top = lua_gettop(L_);
lua_rawgeti(L_, s, 3);
lua_rawgeti(L_, s, 2);
lua_rawgeti(L_, s, 1);
if (lua_isnumber(L_, -1) && lua_isnumber(L_, -2) && lua_isnumber(L_, -3)) {
lua_settop(L_, top);
return true;
}
lua_settop(L_, top);
}
return false;
}
bool LuaCoreStack::ckboolean(LuaSlot s) const {
checkboolean(s, "value");
return lua_toboolean(L_, s) ? true:false;
@@ -172,6 +184,26 @@ LuaToken LuaCoreStack::cktoken(LuaSlot s) const {
return LuaToken(lua_touserdata(L_, s));
}
util::DXYZ LuaCoreStack::ckxyz(LuaSlot s) const {
if (lua_istable(L_, s) && (lua_nkeys(L_, s) == 3)) {
int top = lua_gettop(L_);
lua_rawgeti(L_, s, 3);
lua_rawgeti(L_, s, 2);
lua_rawgeti(L_, s, 1);
if (lua_isnumber(L_, -1) && lua_isnumber(L_, -2) && lua_isnumber(L_, -3)) {
util::DXYZ result;
result.x = lua_tonumber(L_, -1);
result.y = lua_tonumber(L_, -2);
result.z = lua_tonumber(L_, -3);
lua_settop(L_, top);
return result;
}
lua_settop(L_, top);
}
argerr("argument", "vector");
return util::DXYZ();
}
void LuaCoreStack::clearmetatable(LuaSlot tab) const {
lua_pushnil(L_);
lua_setmetatable(L_, tab);
@@ -225,14 +257,7 @@ lua_State *LuaCoreStack::newthread(LuaSlot target) const {
}
bool LuaCoreStack::valididentifier(std::string_view str) {
if (str.size() == 0) return false;
char c=str[0];
if ((!ascii_islower(c)) && (!ascii_isupper(c)) && (c!='_')) return false;
for (int i = 1; i < int(str.size()); i++) {
char c = str[i];
if ((!ascii_islower(c)) && (!ascii_isupper(c)) && (!ascii_isdigit(c)) && (c!='_')) return false;
}
return true;
return sv::is_lua_id(str);
}
bool LuaCoreStack::validint64(int64_t value) {

View File

@@ -143,6 +143,7 @@
#ifndef LUASTACK_HPP
#define LUASTACK_HPP
#include "util.hpp"
#include "wrap-string.hpp"
#include "wrap-set.hpp"
#include <cstring>
@@ -379,6 +380,7 @@ public:
bool isboolean(LuaSlot s) const { return lua_type(L_, s) == LUA_TBOOLEAN; }
bool isnil(LuaSlot s) const { return lua_type(L_, s) == LUA_TNIL; }
bool istoken(LuaSlot s) const { return lua_islightuserdata(L_, s) != 0; }
bool isxyz(LuaSlot s) const;
void checktable(LuaSlot s, const char *n) const { if (!istable(s)) argerr(n, "table"); }
void checkstring(LuaSlot s, const char *n) const { if (!isstring(s)) argerr(n, "string"); }
@@ -391,6 +393,7 @@ public:
void checkboolean(LuaSlot s, const char *n) const { if (!isboolean(s)) argerr(n, "boolean"); }
void checknil(LuaSlot s, const char *n) const { if (!isnil(s)) argerr(n, "nil"); }
void checktoken(LuaSlot s, const char *n) const { if (!istoken(s)) argerr(n, "token"); }
void checkxyz(LuaSlot s, const char *n) const { if (!isxyz(s)) argerr(n, "xyz"); }
bool ckboolean(LuaSlot s) const;
lua_Integer ckinteger(LuaSlot s) const;
@@ -400,6 +403,7 @@ public:
std::string_view ckstringview(LuaSlot s) const;
lua_State *ckthread(LuaSlot s) const;
LuaToken cktoken(LuaSlot s) const;
util::DXYZ ckxyz(LuaSlot s) const;
void clearmetatable(LuaSlot tab) const;
void setmetatable(LuaSlot tab, LuaSlot mt) const;

View File

@@ -840,40 +840,24 @@ void PlaneScan::configure(LuaKeywordParser &kp) {
have_plane = true;
}
kp.parse(vx, "centerx");
kp.parse(vy, "centery");
kp.parse(vz, "centerz");
if ((!LS.isnil(vx)) || (!LS.isnil(vy)) || (!LS.isnil(vz))) {
LS.checknumber(vx, "centerx");
LS.checknumber(vy, "centery");
LS.checknumber(vz, "centerz");
center_.x = LS.cknumber(vx);
center_.y = LS.cknumber(vy);
center_.z = LS.cknumber(vz);
if (kp.parse(val, "center")) {
LS.checkxyz(val, "center");
util::DXYZ xyz = LS.ckxyz(val);
center_ = xyz;
have_center = true;
}
if (kp.parse(val, "radius")) {
LS.checknumber(val, "radius");
radius_.x = LS.cknumber(val);
radius_.y = radius_.z = radius_.x;
have_radius = true;
}
kp.parse(vx, "radiusx");
kp.parse(vy, "radiusy");
kp.parse(vz, "radiusz");
if ((!LS.isnil(vx)) || (!LS.isnil(vy)) || (!LS.isnil(vz))) {
LS.checknumber(vx, "radiusx");
LS.checknumber(vy, "radiusy");
LS.checknumber(vz, "radiusz");
if (have_radius) {
luaL_error(L, "scan configuration: specified both 'radius' and 'radiusx'");
if (LS.isnumber(val)) {
radius_.x = LS.cknumber(val);
radius_.y = radius_.z = radius_.x;
have_radius = true;
} else {
LS.checkxyz(val, "radius");
util::DXYZ xyz = LS.ckxyz(val);
radius_ = xyz;
have_radius = true;
}
radius_.x = LS.cknumber(vx);
radius_.y = LS.cknumber(vy);
radius_.z = LS.cknumber(vz);
have_radius = true;
}
if (kp.parse(val, "shape")) {

View File

@@ -2,7 +2,7 @@
#include "wrap-vector.hpp"
#include "util.hpp"
#include "fast-float.hpp"
#include "luastack.hpp"
#include <algorithm>
#include <sys/types.h>
@@ -178,7 +178,14 @@ int common_prefix_length(string_view a, string_view b) {
}
bool is_lua_id(string_view str) {
return LuaCoreStack::valididentifier(str);
if (str.size() == 0) return false;
char c=str[0];
if ((!ascii_isalpha(c)) && (c!='_')) return false;
for (int i = 1; i < int(str.size()); i++) {
char c = str[i];
if ((!ascii_isalnum(c)) && (c!='_')) return false;
}
return true;
}
bool is_lua_comment(string_view s) {

View File

@@ -29,8 +29,7 @@
#include <limits>
#include <iomanip>
// #include <cstdint>
#include "luastack.hpp"
#include <cstdarg>
#include "spookyv2.hpp"
namespace sv {
@@ -342,7 +341,8 @@ struct NumXYZ {
Number x, y, z;
NumXYZ() { x=0; y=0; z=0; }
NumXYZ(Number ix, Number iy, Number iz) { x=ix; y=iy; z=iz; }
void operator =(const NumXYZ &other) { x = other.x; y = other.y; z = other.z; }
void operator =(const NumXYZ<double> &other) { x = other.x; y = other.y; z = other.z; }
void operator =(const NumXYZ<float> &other) { x = other.x; y = other.y; z = other.z; }
void operator =(Number n) { x = n; y = n; z = n; }
bool operator ==(const NumXYZ &o) const { return x==o.x && y == o.y && z==o.z; }
bool operator !=(const NumXYZ &o) const { return x!=o.x || y != o.y || z!=o.z; }

View File

@@ -22,7 +22,7 @@ LuaDefine(tangible_xyz, "tan",
"|Returns four values: x, y, z, plane") {
LuaArg tanobj;
LuaRet x, y, z, plane;
LuaDefStack LS(L, tanobj, x, y, z);
LuaDefStack LS(L, tanobj, x, y, z, plane);
World *w = World::fetch_global_pointer(L);
Tangible *tan = w->tangible_get(LS, tanobj, false);
AnimCoreState pos = tan->anim_queue_.get_final_core_state();
@@ -212,9 +212,11 @@ LuaDefine(tangible_animate, "tan,options,config",
LuaDefine(tangible_setclass, "tan,class",
"|Set the class of the tangible."
"|"
"|The class can be a 'class table' (ie, a table of methods), "
"|or it can be a string that names a class. The tangible is "
"|given an __index metamethod that points at the class table.") {
"|given an __index metamethod that points at the class table."
"|") {
LuaArg tanobj, classname;
LuaVar classtab, mt;
LuaDefStack LS(L, tanobj, classname, classtab, mt);
@@ -231,8 +233,10 @@ LuaDefine(tangible_setclass, "tan,class",
LuaDefine(tangible_getclass, "tan",
"|Get the class of the tangible, if any."
"|"
"|The return value is a string, the class name, not"
"|the class table.") {
"|the class table."
"|") {
LuaArg tanobj;
LuaVar classtab;
LuaRet classname;
@@ -251,6 +255,7 @@ LuaDefine(tangible_getclass, "tan",
LuaDefine(tangible_delete, "tan",
"|Delete the specified tangible."
"|"
"|This cannot be used to delete player tangibles,"
"|To delete a player, use tangible.redirect") {
LuaArg tanobj;
@@ -399,46 +404,6 @@ LuaDefine(tangible_place, "",
return LS.result();
}
LuaDefine(tangible_near, "tan,radius,omit_nowhere,omit_self",
"|Deprecated. Use tangible.find instead.") {
LuaArg ltan, lradius, lomit_nowhere, lomit_self;
LuaRet list;
LuaDefStack LS(L, ltan, lradius, lomit_nowhere, lomit_self, list);
World *w = World::fetch_global_pointer(L);
Tangible *tan = w->tangible_get(LS, ltan, false);
PlaneScan scan;
scan.set_radius(LS.cknumber(lradius));
scan.set_shape(PlaneScan::SPHERE);
scan.set_sorted(true);
scan.set_near(tan->id(), !LS.ckboolean(lomit_self));
scan.set_omit_nowhere(LS.ckboolean(lomit_nowhere));
util::IdVector idv;
w->get_near(scan, &idv);
tangible_getall(LS, list, idv);
return LS.result();
}
LuaDefine(tangible_scan, "plane,x,y,radius,omit_nowhere",
"|Deprecated. Use tangible.find instead.") {
LuaArg lplane, lx, ly, lradius, lomit_nowhere;
LuaRet list;
LuaDefStack LS(L, lplane, lx, ly, lradius, lomit_nowhere, list);
World *w = World::fetch_global_pointer(L);
PlaneScan scan;
scan.set_plane(LS.ckstring(lplane));
scan.set_center_and_radius(util::XYZ(LS.cknumber(lx), LS.cknumber(ly), 0), LS.cknumber(lradius));
scan.set_shape(PlaneScan::SPHERE);
scan.set_sorted(true);
scan.set_omit_nowhere(LS.ckboolean(lomit_nowhere));
util::IdVector idv;
w->get_near(scan, &idv);
tangible_getall(LS, list, idv);
return LS.result();
}
LuaDefine(tangible_find, "config",
"|Find tangibles by their location."
"|"
@@ -447,25 +412,16 @@ LuaDefine(tangible_find, "config",
"|include these parameters in the table:"
"|"
"| plane : the plane to search (a string)"
"| centerx : x-coordinate of the center of the search"
"| centery : y-coordinate of the center of the search"
"| centerz : z-coordinate of the center of the search"
"| radius : the radius of the search"
"| center : xyz of the center of the search (a vector)"
"| radius : the radius of the search (a vector or number)"
"| shape : 'box', 'sphere', or 'cylinder'"
"|"
"|Shape has a default: 'sphere'. The other parameters do"
"|not have default values."
"|"
"|Instead of specifying the radius as a single float,"
"|you may optionally specify separate radii for each dimension."
"|"
"| radiusx : the radius in the x-dimension."
"| radiusy : the radius in the y-dimension."
"| radiusz : the radius in the z-dimension."
"|"
"|If you specify different radii in each dimension, then the"
"|'sphere' shape will actually be a spheroid, and the 'cylinder'"
"|shape will actually be a cylindroid."
"|If you specify the radius as a vector, ie, different radii in"
"|each dimension, then the 'sphere' shape will actually be a"
"|spheroid, and the 'cylinder' shape will actually be a cylindroid."
"|"
"|Instead of specifying the center and plane, you can specify"
"|a tangible to search near:"