mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2024-12-01 15:35:47 +00:00
12069 lines
246 KiB
C++
12069 lines
246 KiB
C++
#/*
|
|
Copyright (C) 2007, 2010 - Bit-Blot
|
|
|
|
This file is part of Aquaria.
|
|
|
|
Aquaria is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include "SDL.h"
|
|
#include "ScriptInterface.h"
|
|
#include "../BBGE/ScriptObject.h"
|
|
extern "C"
|
|
{
|
|
#include "lua.h"
|
|
#include "lauxlib.h"
|
|
#include "lualib.h"
|
|
}
|
|
|
|
#include "ReadXML.h"
|
|
|
|
#include "DSQ.h"
|
|
#include "Game.h"
|
|
#include "Avatar.h"
|
|
#include "ScriptedEntity.h"
|
|
#include "Shot.h"
|
|
#include "Entity.h"
|
|
#include "Web.h"
|
|
#include "GridRender.h"
|
|
#include "AfterEffect.h"
|
|
#include "PathFinding.h"
|
|
#include <algorithm>
|
|
#include "Gradient.h"
|
|
#include "InGameMenu.h"
|
|
#include "GasCloud.h"
|
|
#include "Ingredient.h"
|
|
#include "Beam.h"
|
|
#include "Hair.h"
|
|
#include "Spore.h"
|
|
#include "Shader.h"
|
|
#include "ActionMapper.h"
|
|
|
|
|
|
#include "../BBGE/MathFunctions.h"
|
|
|
|
// Define this to 1 to check types of pointers passed to functions,
|
|
// and warn if a type mismatch is detected. In this case,
|
|
// the pointer is treated as NULL, to avoid crashing or undefined behavior.
|
|
// Note: There are a few functions that depend on this (isObject and related).
|
|
// They will still work as expected when this is disabled.
|
|
#define CHECK_POINTER_TYPES 1
|
|
|
|
// If true, send all sort of script errors to errorLog instead of debugLog.
|
|
// On win32/OSX, this pops up message boxes which help to locate errors easily,
|
|
// but can be annoying for regular gameplay.
|
|
bool loudScriptErrors = false;
|
|
|
|
// Set this to true to complain whenever a script tries to
|
|
// get or set a global variable.
|
|
bool complainOnGlobalVar = false;
|
|
|
|
// Set this to true to complain whenever a script tries to get an undefined
|
|
// thread-local variable.
|
|
bool complainOnUndefLocal = false;
|
|
|
|
// Set to true to make 'os' and 'io' Lua tables accessible
|
|
bool allowUnsafeFunctions = false;
|
|
|
|
|
|
// List of all interface functions called by C++ code, terminated by NULL.
|
|
static const char * const interfaceFunctions[] = {
|
|
"action",
|
|
"activate",
|
|
"animationKey",
|
|
"castSong",
|
|
"canShotHit",
|
|
"cookFailure",
|
|
"damage",
|
|
"deathNotify",
|
|
"dieEaten",
|
|
"dieNormal",
|
|
"enterState",
|
|
"entityDied",
|
|
"exitState",
|
|
"exitTimer",
|
|
"getIngredientEffectString",
|
|
"hitEntity",
|
|
"hitSurface",
|
|
"init",
|
|
"lightFlare",
|
|
"msg",
|
|
"postInit",
|
|
"preUpdate",
|
|
"shiftWorlds",
|
|
"shotHitEntity",
|
|
"song",
|
|
"songNote",
|
|
"songNoteDone",
|
|
"sporesDropped",
|
|
"update",
|
|
"useIngredient",
|
|
"useTreasure",
|
|
NULL
|
|
};
|
|
|
|
//============================================================================================
|
|
// R U L E S F O R W R I T I N G S C R I P T S
|
|
//============================================================================================
|
|
|
|
//
|
|
// All scripts in Aquaria run as separate threads in the same Lua state.
|
|
// This means that scripts must follow certain rules to avoid interfering
|
|
// with each other:
|
|
//
|
|
// -- DON'T use global variables (or functions). Use file-scope or
|
|
// instance locals instead.
|
|
//
|
|
// Since every script runs in the same Lua state and thus shares the
|
|
// same global environment, global variables set in one script affect
|
|
// every other script. Something as innocuous-looking as "hits = 10"
|
|
// would set a "hits" variable in _every_ script -- overwriting any
|
|
// value that another script might have already set!
|
|
//
|
|
// For constant values and functions (which are in effect constant
|
|
// values), you can use Lua's "local" keyword to declare the value as
|
|
// local to the script file which declares it. Any functions defined
|
|
// later in the file will then be able to access those local values as
|
|
// function upvalues, thus avoiding touching the global environment.
|
|
// (However, remember to define the constants or functions _before_
|
|
// you use them!)
|
|
//
|
|
// For variables, a file-scope local won't work, because a script's
|
|
// functions are shared across all instances of that script -- for
|
|
// example, every active jellyfish entity calls the same "update"
|
|
// function. If you used file-scope locals, then you'd have no way to
|
|
// separate one instance's data from another. Instead, the Aquaria
|
|
// script engine provides a Lua table specific to each script instance,
|
|
// into which instance-local variables can be stored. This table is
|
|
// loaded into the global variable "v" when any script function is
|
|
// called from the game, so functions can store variables in this table
|
|
// without worrying that another instance of the script will clobber
|
|
// them.
|
|
//
|
|
// The instance-local table is also available to code in the script
|
|
// outside any functions, which is executed when the script is loaded.
|
|
// In this case, the values in the table are used as defaults and
|
|
// copied into the instance-local table of each new instance of the
|
|
// script.
|
|
//
|
|
// If you use any include files, be aware that file-scope locals in the
|
|
// include files can only be used inside those files, since they would
|
|
// be out of scope in the calling file. To export constants or
|
|
// functions to the calling file, you'll have to use instance locals
|
|
// instead. (As an exception, if you have constants which you know are
|
|
// unique across all scripts, you can define them as globals. Aquaria
|
|
// itself defines a number of global constants for use in scripts --
|
|
// see the "SCRIPT CONSTANTS" section toward the bottom of this file.)
|
|
//
|
|
// -- DO define instance functions in the global namespace.
|
|
//
|
|
// As an exception to the rule above, interface functions such as
|
|
// init() or update() _should_ be defined in the global namespace.
|
|
// For example:
|
|
//
|
|
// local function doUpdateStuff(dt)
|
|
// -- Some update stuff.
|
|
// end
|
|
// function update(dt)
|
|
// doUpdateStuff(dt)
|
|
// -- Other update stuff.
|
|
// end
|
|
//
|
|
// The script engine will take care of ensuring that different scripts'
|
|
// functions don't interfere with each other.
|
|
//
|
|
// -- DON'T call interface functions from within a script.
|
|
//
|
|
// Interface functions, such as init() and update(), are treated
|
|
// specially by the script engine, and attempting to call them from
|
|
// other script functions will fail. If you need to perform the same
|
|
// processing from two or more different interface functions, define
|
|
// a local function with the necessary code and call it from the
|
|
// interface functions.
|
|
//
|
|
// It _is_ possible, though not recommended, to have a local function
|
|
// with the same name as an interface function. For example, if you
|
|
// write a script containing:
|
|
//
|
|
// local function activate(me)
|
|
// -- Do something.
|
|
// end
|
|
//
|
|
// then you can call activate() from other functions without problems.
|
|
// The local function, activate() in this case, will naturally not be
|
|
// visible to the script engine. (This is discouraged because someone
|
|
// reading the code may be confused at seeing what looks like an
|
|
// interface function defined locally.)
|
|
//
|
|
// -- DON'T call any functions from the outermost (file) scope of an
|
|
// instanced script file.
|
|
//
|
|
// "Instanced" script files are those for which multiple instances may
|
|
// be created, i.e. entity or node scripts. For these, the script
|
|
// itself is executed only once, when it is loaded; any statements
|
|
// outside function definitions will be executed at this time, but not
|
|
// when a new script instance is created. For example, if you try to
|
|
// call a function such as math.random() to set a different value for
|
|
// each instance, you'll instead end up with the same value for every
|
|
// instance. In cases like this, the variable should be set in the
|
|
// script's init() function, not at file scope.
|
|
//
|
|
// Likewise, any functions which have side effects or otherwise modify
|
|
// program state should not be called from file scope. Call them from
|
|
// init() instead.
|
|
//
|
|
// -- DON'T declare non-constant Lua tables at file scope in instanced
|
|
// scripts.
|
|
//
|
|
// One non-obvious result of the above restrictions is that tables
|
|
// intended to be modified by the script cannot be declared at file
|
|
// scope, even as instance variables. The reason for this is that
|
|
// table variables in Lua are actually pointers; the Lua statement
|
|
// "v.table = {}" is functionally the same as "v.table = newtable()",
|
|
// where the hypothetical newtable() function allocates and returns a
|
|
// pointer to a table object, and thus falls under the restriction
|
|
// that functions must not be called at file scope. Table variables
|
|
// in instanced scripts must therefore be initialized in the init()
|
|
// function, even if you're only setting the variable to an empty
|
|
// table.
|
|
//
|
|
// In summary:
|
|
//
|
|
// -- Never use global variables or functions, except interface functions.
|
|
// -- Constants and local functions should be defined with "local":
|
|
// local MY_CONSTANT = 42
|
|
// local function getMyConstant() return MY_CONSTANT end
|
|
// -- Variables should be stored in the "v" table:
|
|
// function update(dt) v.timer = v.timer + dt end
|
|
// -- Variables (except table variables) can have default values set when
|
|
// the script is loaded:
|
|
// v.countdown = 5
|
|
// function update(dt) v.countdown = v.countdown - dt end
|
|
// -- Non-constant tables must be initialized in init(), even if the
|
|
// variable is always set to the same thing (such as an empty table).
|
|
// -- Never call interface functions from other functions.
|
|
// -- Always perform instance-specific setup in init(), not at file scope.
|
|
//
|
|
// ====================
|
|
// Compatibility notes:
|
|
// ====================
|
|
//
|
|
// Due to the use of an instance variable table (the "v" global), scripts
|
|
// written for this version of Aquaria will _not_ work with commercial
|
|
// releases (at least through version 1.1.3) of the game; likewise, the
|
|
// scripts from those commercial releases, and mods written to target
|
|
// those releases, will not work with this engine.
|
|
//
|
|
// The latter problem is unfortunately an unsolvable one, in any practical
|
|
// sense. Since the original engine created a new Lua state for each
|
|
// script, scripts could create and modify global variables with impunity.
|
|
// The mere act of loading such a script could wreak havoc on the single
|
|
// Lua state used in the current engine, and attempting to work around
|
|
// this would require at least the implementation of a custom Lua parser
|
|
// to analyze and/or alter each script before it was passed to the Lua
|
|
// interpreter.
|
|
//
|
|
// However, the former problem -- of writing scripts for this version of
|
|
// the engine which also work on earlier versions -- can be solved with
|
|
// a few extra lines of code at the top of each script. Since the new
|
|
// engine initializes the "v" global before each call to a script,
|
|
// including when the script is first loaded, scripts can check for the
|
|
// existence of this variable and assign an empty table to it if needed,
|
|
// such as with this line:
|
|
//
|
|
// if not v then v = {} end
|
|
//
|
|
// Additionally, the current engine provides built-in constants which
|
|
// were formerly loaded from external files. To differentiate between
|
|
// this and other versions of the engine, the script interface exports a
|
|
// constant named AQUARIA_VERSION, generated directly from the program
|
|
// version (shown on the title screen) as:
|
|
// major*10000 + minor*100 + revision
|
|
// For example, in version 1.1.3, AQUARIA_VERSION == 10103. In earlier
|
|
// versions of the engine, the value of this constant will be nil, which
|
|
// can be used as a trigger to load the constant definition file from
|
|
// that version:
|
|
//
|
|
// if not AQUARIA_VERSION then dofile("scripts/entities/entityinclude.lua") end
|
|
//
|
|
// Note that scripts should _not_ rely on AQUARIA_VERSION for the v = {}
|
|
// assignment. The code "if not AQUARIA_VERSION then v = {} end" would
|
|
// work correctly in a top-level script, but if executed from a script
|
|
// used as an include file, the table created in the include file would
|
|
// overwrite any existing table created by the file's caller.
|
|
//
|
|
|
|
//============================================================================================
|
|
// S C R I P T C O M M A N D S
|
|
//============================================================================================
|
|
|
|
static void scriptError(const std::string& msg)
|
|
{
|
|
if(loudScriptErrors)
|
|
errorLog(msg);
|
|
else
|
|
debugLog(msg);
|
|
}
|
|
|
|
static inline void luaPushPointer(lua_State *L, void *ptr)
|
|
{
|
|
// All the scripts do this:
|
|
// x = getFirstEntity()
|
|
// while x =~ 0 do x = getNextEntity() end
|
|
// The problem is this is now a pointer ("light user data"), so in
|
|
// Lua, it's never equal to 0 (or nil!), even if it's NULL.
|
|
// So we push an actual zero when we get a NULL to keep the existing
|
|
// scripts happy. --ryan.
|
|
if (ptr != NULL)
|
|
lua_pushlightuserdata(L, ptr);
|
|
else
|
|
lua_pushnumber(L, 0);
|
|
}
|
|
|
|
static std::string luaFormatStackInfo(lua_State *L, int level = 1)
|
|
{
|
|
lua_Debug ar;
|
|
std::ostringstream os;
|
|
if (lua_getstack(L, level, &ar) && lua_getinfo(L, "Sln", &ar))
|
|
{
|
|
os << ar.short_src << ":" << ar.currentline
|
|
<< " ([" << ar.what << "] " << ar.namewhat << " " << (ar.name ? ar.name : "(?)") << ")";
|
|
}
|
|
else
|
|
{
|
|
os << "???:0";
|
|
}
|
|
|
|
return os.str();
|
|
}
|
|
|
|
static void scriptDebug(lua_State *L, const std::string& msg)
|
|
{
|
|
debugLog(luaFormatStackInfo(L) + ": " + msg);
|
|
}
|
|
|
|
static void scriptError(lua_State *L, const std::string& msg)
|
|
{
|
|
lua_Debug dummy;
|
|
std::ostringstream os;
|
|
os << msg;
|
|
for (int level = 0; lua_getstack(L, level, &dummy); ++level)
|
|
os << '\n' << luaFormatStackInfo(L, level);
|
|
|
|
scriptError(os.str());
|
|
}
|
|
|
|
|
|
#if CHECK_POINTER_TYPES
|
|
// Not intended to be called.
|
|
// Because wild typecasting expects X::_objtype to reside at the same relative
|
|
// memory location, be sure this is the case before running into undefined behavior later.
|
|
// - The C++ standard allows offsetof() only on POD-types. Oh well, it probably works anyways.
|
|
// If it does not compile for some reason, comment it out, hope for the best, and go ahead.
|
|
#if !(defined(__GNUC__) && __GNUC__ <= 2)
|
|
static void compile_time_assertions()
|
|
{
|
|
#define oo(cls) offsetof(cls, _objtype)
|
|
compile_assert(oo(Path) == oo(RenderObject));
|
|
compile_assert(oo(Path) == oo(Entity));
|
|
compile_assert(oo(Path) == oo(Ingredient));
|
|
compile_assert(oo(Path) == oo(CollideEntity));
|
|
compile_assert(oo(Path) == oo(ScriptedEntity));
|
|
compile_assert(oo(Path) == oo(Beam));
|
|
compile_assert(oo(Path) == oo(Shot));
|
|
compile_assert(oo(Path) == oo(Web));
|
|
compile_assert(oo(Path) == oo(Bone));
|
|
compile_assert(oo(Path) == oo(PauseQuad));
|
|
compile_assert(oo(Path) == oo(Quad));
|
|
compile_assert(oo(Path) == oo(Avatar));
|
|
compile_assert(oo(Path) == oo(BaseText));
|
|
compile_assert(oo(Path) == oo(PauseQuad));
|
|
compile_assert(oo(Path) == oo(ParticleEffect));
|
|
#undef oo
|
|
}
|
|
#endif
|
|
|
|
template <typename T>
|
|
static void ensureType(lua_State *L, T *& ptr, ScriptObjectType ty)
|
|
{
|
|
if (ptr)
|
|
{
|
|
ScriptObject *so = (ScriptObject*)(ptr);
|
|
if (!so->isType(ty))
|
|
{
|
|
std::ostringstream os;
|
|
os << "WARNING: script passed wrong pointer to function (expected type: "
|
|
<< ScriptObject::getTypeString(ty) << "; got: "
|
|
<< so->getTypeString() << ')';
|
|
scriptError(L, os.str());
|
|
|
|
ptr = NULL; // note that the pointer is passed by reference
|
|
}
|
|
}
|
|
}
|
|
template <typename T>
|
|
static void ensureTypeNoError(lua_State *L, T *& ptr, ScriptObjectType ty)
|
|
{
|
|
if (ptr)
|
|
{
|
|
ScriptObject *so = (ScriptObject*)(ptr);
|
|
if (!so->isType(ty))
|
|
ptr = NULL;
|
|
}
|
|
}
|
|
# define ENSURE_TYPE(ptr, ty) ensureType(L, (ptr), (ty))
|
|
# define ENSURE_TYPE_NO_ERROR(ptr, ty) ensureTypeNoError(L, (ptr), (ty))
|
|
# define typecheckOnly(func) func
|
|
#else
|
|
# define ENSURE_TYPE(ptr, ty)
|
|
# define ENSURE_TYPE_NO_ERROR(ptr, ty)
|
|
# define typecheckOnly(func)
|
|
#endif
|
|
|
|
static inline
|
|
RenderObject *robj(lua_State *L, int slot = 1)
|
|
{
|
|
RenderObject *r = (RenderObject*)lua_touserdata(L, slot);
|
|
ENSURE_TYPE(r, SCO_RENDEROBJECT);
|
|
if (!r)
|
|
scriptDebug(L, "RenderObject invalid pointer.");
|
|
return r;
|
|
}
|
|
|
|
static inline
|
|
ScriptedEntity *scriptedEntity(lua_State *L, int slot = 1)
|
|
{
|
|
ScriptedEntity *se = (ScriptedEntity*)lua_touserdata(L, slot);
|
|
ENSURE_TYPE(se, SCO_SCRIPTED_ENTITY);
|
|
if (!se)
|
|
scriptDebug(L, "ScriptedEntity invalid pointer.");
|
|
return se;
|
|
}
|
|
|
|
static inline
|
|
ScriptedEntity *scriptedEntityOpt(lua_State *L, int slot = 1)
|
|
{
|
|
ScriptedEntity *se = (ScriptedEntity*)lua_touserdata(L, slot);
|
|
ENSURE_TYPE_NO_ERROR(se, SCO_SCRIPTED_ENTITY); // Dont't error if not ScriptedEntity...
|
|
if (se)
|
|
return se;
|
|
|
|
ENSURE_TYPE(se, SCO_ENTITY); // ... but error if not even Entity
|
|
return NULL; // still return NULL
|
|
}
|
|
|
|
static inline
|
|
CollideEntity *collideEntity(lua_State *L, int slot = 1)
|
|
{
|
|
CollideEntity *ce = (CollideEntity*)lua_touserdata(L, slot);
|
|
ENSURE_TYPE(ce, SCO_COLLIDE_ENTITY);
|
|
if (!ce)
|
|
scriptDebug(L, "CollideEntity invalid pointer.");
|
|
return ce ;
|
|
}
|
|
|
|
static inline
|
|
Beam *beam(lua_State *L, int slot = 1)
|
|
{
|
|
Beam *b = (Beam*)lua_touserdata(L, slot);
|
|
ENSURE_TYPE(b, SCO_BEAM);
|
|
if (!b)
|
|
scriptDebug(L, "Beam invalid pointer.");
|
|
return b;
|
|
}
|
|
|
|
static inline
|
|
std::string getString(lua_State *L, int slot = 1)
|
|
{
|
|
std::string sr;
|
|
if (lua_isstring(L, slot))
|
|
{
|
|
sr = lua_tostring(L, slot);
|
|
}
|
|
return sr;
|
|
}
|
|
|
|
static inline
|
|
const char *getCString(lua_State *L, int slot = 1)
|
|
{
|
|
return lua_isstring(L, slot) ? lua_tostring(L, slot) : NULL;
|
|
}
|
|
|
|
static inline
|
|
Shot *getShot(lua_State *L, int slot = 1)
|
|
{
|
|
Shot *shot = (Shot*)lua_touserdata(L, slot);
|
|
ENSURE_TYPE(shot, SCO_SHOT);
|
|
if (!shot)
|
|
scriptDebug(L, "Shot invalid pointer.");
|
|
return shot;
|
|
}
|
|
|
|
static inline
|
|
Web *getWeb(lua_State *L, int slot = 1)
|
|
{
|
|
Web *web = (Web*)lua_touserdata(L, slot);
|
|
ENSURE_TYPE(web, SCO_WEB);
|
|
if (!web)
|
|
scriptDebug(L, "Web invalid pointer.");
|
|
return web;
|
|
}
|
|
|
|
static inline
|
|
Ingredient *getIng(lua_State *L, int slot = 1)
|
|
{
|
|
Ingredient *ing = (Ingredient*)lua_touserdata(L, slot);
|
|
ENSURE_TYPE(ing, SCO_INGREDIENT);
|
|
if (!ing)
|
|
scriptDebug(L, "Ingredient invalid pointer.");
|
|
return ing;
|
|
}
|
|
|
|
static inline
|
|
bool getBool(lua_State *L, int slot = 1)
|
|
{
|
|
if (lua_isnumber(L, slot))
|
|
{
|
|
return bool(lua_tonumber(L, slot));
|
|
}
|
|
else if (lua_islightuserdata(L, slot))
|
|
{
|
|
return (lua_touserdata(L, slot) != NULL);
|
|
}
|
|
else if (lua_isboolean(L, slot))
|
|
{
|
|
return lua_toboolean(L, slot);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static inline
|
|
Entity *entity(lua_State *L, int slot = 1)
|
|
{
|
|
Entity *ent = (Entity*)lua_touserdata(L, slot);
|
|
ENSURE_TYPE(ent, SCO_ENTITY);
|
|
if (!ent)
|
|
{
|
|
scriptDebug(L, "Entity Invalid Pointer");
|
|
}
|
|
return ent;
|
|
}
|
|
|
|
static inline
|
|
Vector getVector(lua_State *L, int slot = 1)
|
|
{
|
|
Vector v(lua_tonumber(L, slot), lua_tonumber(L, slot+1));
|
|
return v;
|
|
}
|
|
|
|
|
|
static inline
|
|
Bone *bone(lua_State *L, int slot = 1)
|
|
{
|
|
Bone *b = (Bone*)lua_touserdata(L, slot);
|
|
ENSURE_TYPE(b, SCO_BONE);
|
|
if (!b)
|
|
{
|
|
scriptDebug(L, "Bone Invalid Pointer");
|
|
}
|
|
return b;
|
|
}
|
|
|
|
static inline
|
|
Path *pathFromName(lua_State *L, int slot = 1)
|
|
{
|
|
std::string s = getString(L, slot);
|
|
stringToLower(s);
|
|
Path *p = dsq->game->getPathByName(s);
|
|
if (!p)
|
|
{
|
|
debugLog("Could not find path [" + s + "]");
|
|
}
|
|
return p;
|
|
}
|
|
|
|
static inline
|
|
Path *path(lua_State *L, int slot = 1)
|
|
{
|
|
Path *p = (Path*)lua_touserdata(L, slot);
|
|
ENSURE_TYPE(p, SCO_PATH);
|
|
return p;
|
|
}
|
|
|
|
static inline
|
|
Quad *getQuad(lua_State *L, int slot = 1)
|
|
{
|
|
Quad *q = (Quad*)lua_touserdata(L, slot);
|
|
ENSURE_TYPE(q, SCO_QUAD);
|
|
if (!q)
|
|
scriptDebug(L, "Invalid Quad");
|
|
return q;
|
|
}
|
|
|
|
static inline
|
|
BaseText *getText(lua_State *L, int slot = 1)
|
|
{
|
|
BaseText *q = (BaseText*)lua_touserdata(L, slot);
|
|
ENSURE_TYPE(q, SCO_TEXT);
|
|
if (!q)
|
|
scriptDebug(L, "Invalid Text");
|
|
return q;
|
|
}
|
|
|
|
static SkeletalSprite *getSkeletalSprite(Entity *e)
|
|
{
|
|
return e ? &e->skeletalSprite : NULL;
|
|
}
|
|
|
|
static inline
|
|
ParticleEffect *getParticle(lua_State *L, int slot = 1)
|
|
{
|
|
ParticleEffect *q = (ParticleEffect*)lua_touserdata(L, slot);
|
|
ENSURE_TYPE(q, SCO_PARTICLE_EFFECT);
|
|
if (!q)
|
|
scriptDebug(L, "Invalid Particle Effect");
|
|
return q;
|
|
}
|
|
|
|
static bool looksLikeGlobal(const char *s)
|
|
{
|
|
for( ; *s; ++s)
|
|
if( !((*s >= 'A' && *s <= 'Z') || *s == '_' || (*s >= '0' && *s <= '9')) ) // accept any uppercase, number, and _ char
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
inline float interpolateVec1(lua_State *L, InterpolatedVector& vec, int argOffs)
|
|
{
|
|
return vec.interpolateTo(
|
|
lua_tonumber (L, argOffs ), // value
|
|
lua_tonumber (L, argOffs+1), // time
|
|
lua_tointeger(L, argOffs+2), // loopType
|
|
getBool (L, argOffs+3), // pingPong
|
|
getBool (L, argOffs+4)); // ease
|
|
}
|
|
|
|
inline float interpolateVec1z(lua_State *L, InterpolatedVector& vec, int argOffs)
|
|
{
|
|
return vec.interpolateTo(
|
|
Vector(0.0f, 0.0f, lua_tonumber (L, argOffs )), // value, last component
|
|
lua_tonumber (L, argOffs+1), // time
|
|
lua_tointeger(L, argOffs+2), // loopType
|
|
getBool (L, argOffs+3), // pingPong
|
|
getBool (L, argOffs+4)); // ease
|
|
}
|
|
|
|
inline float interpolateVec2(lua_State *L, InterpolatedVector& vec, int argOffs)
|
|
{
|
|
return vec.interpolateTo(
|
|
Vector(lua_tonumber (L, argOffs ), // x value
|
|
lua_tonumber (L, argOffs+1)), // y value
|
|
lua_tonumber (L, argOffs+2), // time
|
|
lua_tointeger(L, argOffs+3), // loopType
|
|
getBool(L, argOffs+4), // pingPong
|
|
getBool(L, argOffs+5)); // ease
|
|
}
|
|
|
|
inline float interpolateVec3(lua_State *L, InterpolatedVector& vec, int argOffs)
|
|
{
|
|
return vec.interpolateTo(
|
|
Vector(lua_tonumber (L, argOffs ), // x value
|
|
lua_tonumber (L, argOffs+1), // y value
|
|
lua_tonumber (L, argOffs+2)), // z value
|
|
lua_tonumber (L, argOffs+3), // time
|
|
lua_tointeger(L, argOffs+4), // loopType
|
|
getBool(L, argOffs+5), // pingPong
|
|
getBool(L, argOffs+6)); // ease
|
|
}
|
|
|
|
static void safePath(lua_State *L, const std::string& path)
|
|
{
|
|
// invalid characters for file/path names.
|
|
// Filter out \ as well, it'd work on on win32 only, so it's not supposed to be used.
|
|
size_t invchr = path.find_first_of("\\\":*?<>|");
|
|
if(invchr != std::string::npos)
|
|
{
|
|
lua_pushfstring(L, "Invalid char in path/file name: %c", path[invchr]);
|
|
lua_error(L);
|
|
}
|
|
// Block attempts to access files outside of the "safe area"
|
|
if(path.length())
|
|
{
|
|
if(path[0] == '/')
|
|
{
|
|
if(!(dsq->mod.isActive() && path.substr(0, dsq->mod.getBaseModPath().length()) == dsq->mod.getBaseModPath()))
|
|
{
|
|
lua_pushliteral(L, "Absolute paths are not allowed");
|
|
lua_error(L);
|
|
}
|
|
}
|
|
if(path.find("../") != std::string::npos)
|
|
{
|
|
lua_pushliteral(L, "Accessing parent is not allowed");
|
|
lua_error(L);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//----------------------------------//
|
|
|
|
#define luaFunc(func) static int l_##func(lua_State *L)
|
|
#define luaReturnBool(bool) do {lua_pushboolean(L, (bool)); return 1;} while(0)
|
|
#define luaReturnInt(num) do {lua_pushinteger(L, (num)); return 1;} while(0)
|
|
#define luaReturnNum(num) do {lua_pushnumber(L, (num)); return 1;} while(0)
|
|
#define luaReturnPtr(ptr) do {luaPushPointer(L, (ptr)); return 1;} while(0)
|
|
#define luaReturnStr(str) do {lua_pushstring(L, (str)); return 1;} while(0)
|
|
#define luaReturnVec2(x,y) do {lua_pushnumber(L, (x)); lua_pushnumber(L, (y)); return 2;} while(0)
|
|
#define luaReturnVec3(x,y,z) do {lua_pushnumber(L, (x)); lua_pushnumber(L, (y)); lua_pushnumber(L, (z)); return 3;} while(0)
|
|
#define luaReturnVec4(x,y,z,w) do {lua_pushnumber(L, (x)); lua_pushnumber(L, (y)); lua_pushnumber(L, (z)); lua_pushnumber(L, (w)); return 4;} while(0)
|
|
#define luaReturnNil() return 0;
|
|
|
|
static void pushLocalVarTab(lua_State *L, lua_State *Lv)
|
|
{
|
|
lua_getglobal(L, "_threadvars");
|
|
// [_thv]
|
|
lua_pushlightuserdata(L, Lv);
|
|
// [_thv][L]
|
|
lua_gettable(L, -2);
|
|
// [_thv][v]
|
|
lua_remove(L, -2);
|
|
// [v]
|
|
}
|
|
|
|
// Set the global "v" to the instance's local variable table. Must be
|
|
// called when starting a script.
|
|
static void fixupLocalVars(lua_State *L)
|
|
{
|
|
pushLocalVarTab(L, L);
|
|
lua_setglobal(L, "v");
|
|
}
|
|
|
|
luaFunc(indexWarnGlobal)
|
|
{
|
|
lua_pushvalue(L, -1);
|
|
lua_rawget(L, -3);
|
|
lua_remove(L, -3);
|
|
|
|
if (lua_isnil(L, -1))
|
|
{
|
|
// Don't warn on "v" or known interface functions.
|
|
lua_pushvalue(L, -2);
|
|
const char *varname = lua_tostring(L, -1);
|
|
bool doWarn = (strcmp(varname, "v") != 0);
|
|
for (unsigned int i = 0; doWarn && interfaceFunctions[i] != NULL; i++)
|
|
{
|
|
doWarn = (strcmp(varname, interfaceFunctions[i]) != 0);
|
|
}
|
|
|
|
if (doWarn)
|
|
{
|
|
std::string s = "WARNING: script tried to get/call undefined global variable ";
|
|
s += varname;
|
|
scriptError(L, s);
|
|
}
|
|
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
lua_remove(L, -2);
|
|
|
|
return 1;
|
|
}
|
|
|
|
luaFunc(newindexWarnGlobal)
|
|
{
|
|
// Don't warn on "v" or known interface functions.
|
|
lua_pushvalue(L, -2);
|
|
const char *varname = lua_tostring(L, -1);
|
|
bool doWarn = (strcmp(varname, "v") != 0) && !looksLikeGlobal(varname);
|
|
for (unsigned int i = 0; doWarn && interfaceFunctions[i] != NULL; i++)
|
|
{
|
|
doWarn = (strcmp(varname, interfaceFunctions[i]) != 0);
|
|
}
|
|
|
|
if (doWarn)
|
|
{
|
|
std::ostringstream os;
|
|
os << "WARNING: script set global "
|
|
<< lua_typename(L, lua_type(L, -2))
|
|
<< " " << varname;
|
|
scriptError(L, os.str());
|
|
}
|
|
|
|
lua_pop(L, 1);
|
|
|
|
// Do the set anyway.
|
|
lua_rawset(L, -3);
|
|
lua_pop(L, 1);
|
|
return 0;
|
|
}
|
|
|
|
luaFunc(indexWarnInstance)
|
|
{
|
|
lua_pushvalue(L, -1);
|
|
lua_rawget(L, -3);
|
|
lua_remove(L, -3);
|
|
if (lua_isnil(L, -1))
|
|
{
|
|
std::ostringstream os;
|
|
os << "WARNING: script tried to get/call undefined instance variable "
|
|
<< getString(L, -2);
|
|
scriptError(L, os.str());
|
|
}
|
|
lua_remove(L, -2);
|
|
|
|
return 1;
|
|
}
|
|
|
|
luaFunc(panicHandler)
|
|
{
|
|
std::string err = luaFormatStackInfo(L) + ": Lua PANIC: " + getString(L, -1);
|
|
exit_error(err);
|
|
return 0;
|
|
}
|
|
|
|
static bool findFile_helper(const char *rawname, std::string &fname)
|
|
{
|
|
if (!rawname)
|
|
return false;
|
|
if (dsq->mod.isActive())
|
|
{
|
|
fname = dsq->mod.getPath();
|
|
if(fname[fname.length() - 1] != '/')
|
|
fname += '/';
|
|
fname += rawname;
|
|
fname = localisePath(fname, dsq->mod.getPath());
|
|
fname = adjustFilenameCase(fname);
|
|
if (exists(fname))
|
|
return true;
|
|
}
|
|
fname = localisePath(rawname);
|
|
fname = adjustFilenameCase(fname);
|
|
return exists(fname);
|
|
}
|
|
|
|
static int loadFile_helper(lua_State *L, const char *fn)
|
|
{
|
|
#ifdef BBGE_BUILD_VFS
|
|
unsigned long size = 0;
|
|
const char *data = readFile(fn, &size);
|
|
if (!data)
|
|
{
|
|
lua_pushfstring(L, "cannot open %s", fn);
|
|
return LUA_ERRFILE;
|
|
}
|
|
else
|
|
{
|
|
int result = luaL_loadbuffer(L, data, size, fn);
|
|
delete [] data;
|
|
return result;
|
|
}
|
|
#else
|
|
return luaL_loadfile(L, fn);
|
|
#endif
|
|
}
|
|
|
|
luaFunc(dofile_caseinsensitive)
|
|
{
|
|
// This is Lua's dofile(), with some tweaks. --ryan.
|
|
std::string fname;
|
|
findFile_helper(luaL_checkstring(L, 1), fname);
|
|
|
|
int n = lua_gettop(L);
|
|
if (loadFile_helper(L, fname.c_str()) != 0)
|
|
lua_error(L);
|
|
lua_call(L, 0, LUA_MULTRET);
|
|
return lua_gettop(L) - n;
|
|
}
|
|
|
|
luaFunc(loadfile_caseinsensitive)
|
|
{
|
|
// This is Lua's loadfile(), with some tweaks. --FG.
|
|
std::string fname;
|
|
findFile_helper(luaL_checkstring(L, 1), fname);
|
|
|
|
if (loadFile_helper(L, fname.c_str()) == 0) /* OK? */
|
|
return 1;
|
|
else
|
|
{
|
|
lua_pushnil(L);
|
|
lua_insert(L, -2); /* put before error message */
|
|
return 2; /* return nil plus error message */
|
|
}
|
|
}
|
|
|
|
#ifdef BBGE_BUILD_SDL2
|
|
#define LUAAPI_HAS_CLIPBOARD
|
|
luaFunc(os_setclipboard)
|
|
{
|
|
const char *s = getCString(L);
|
|
SDL_SetClipboardText(s ? s : "");
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(os_getclipboard)
|
|
{
|
|
char *s = SDL_GetClipboardText();
|
|
lua_pushstring(L, s ? s : "");
|
|
if(s)
|
|
SDL_free(s);
|
|
return 1;
|
|
}
|
|
#endif
|
|
|
|
luaFunc(fileExists)
|
|
{
|
|
const std::string s = getString(L);
|
|
safePath(L, s);
|
|
std::string res;
|
|
bool there = findFile_helper(s.c_str(), res);
|
|
lua_pushboolean(L, there);
|
|
lua_pushstring(L, res.c_str());
|
|
return 2;
|
|
}
|
|
|
|
luaFunc(getModName)
|
|
{
|
|
luaReturnStr(dsq->mod.isActive() ? dsq->mod.getName().c_str() : "");
|
|
}
|
|
|
|
luaFunc(getModPath)
|
|
{
|
|
std::string path;
|
|
if (dsq->mod.isActive())
|
|
{
|
|
path = dsq->mod.getPath();
|
|
if(path[path.length() - 1] != '/')
|
|
path += '/';
|
|
}
|
|
luaReturnStr(path.c_str());
|
|
}
|
|
|
|
luaFunc(getInterfaceFunctionNames)
|
|
{
|
|
lua_newtable(L);
|
|
for(unsigned i = 0; interfaceFunctions[i]; ++i)
|
|
{
|
|
lua_pushstring(L, interfaceFunctions[i]);
|
|
lua_rawseti(L, -2, i+1);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
// ----- RenderObject common functions -----
|
|
|
|
#define forwardCall(func) l_##func(L)
|
|
|
|
#define MakeTypeCheckFunc(fname, ty) luaFunc(fname) \
|
|
{ ScriptObject *r = (ScriptObject*)lua_touserdata(L, 1); luaReturnBool(r ? r->isType(ty) : false); }
|
|
|
|
MakeTypeCheckFunc(isNode, SCO_PATH)
|
|
MakeTypeCheckFunc(isObject, SCO_RENDEROBJECT)
|
|
MakeTypeCheckFunc(isEntity, SCO_ENTITY)
|
|
MakeTypeCheckFunc(isScriptedEntity, SCO_SCRIPTED_ENTITY)
|
|
MakeTypeCheckFunc(isBone, SCO_BONE)
|
|
MakeTypeCheckFunc(isShot, SCO_SHOT)
|
|
MakeTypeCheckFunc(isWeb, SCO_WEB)
|
|
MakeTypeCheckFunc(isIng, SCO_INGREDIENT)
|
|
MakeTypeCheckFunc(isBeam, SCO_BEAM)
|
|
MakeTypeCheckFunc(isText, SCO_TEXT)
|
|
MakeTypeCheckFunc(isShader, SCO_SHADER)
|
|
MakeTypeCheckFunc(isParticleEffect, SCO_PARTICLE_EFFECT)
|
|
|
|
#undef MakeTypeCheckFunc
|
|
|
|
// special, because it would return true on almost everything that is RenderObject based.
|
|
// Instead, return true only for stuff created with createQuad()
|
|
luaFunc(isQuad)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnBool(r ? r->isExactType(ScriptObjectType(SCO_RENDEROBJECT | SCO_QUAD)) : false);
|
|
}
|
|
|
|
|
|
luaFunc(obj_setPosition)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
{
|
|
r->position.stop();
|
|
interpolateVec2(L, r->position, 2);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_scale)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
{
|
|
r->scale.stop();
|
|
interpolateVec2(L, r->scale, 2);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_getScale)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
Vector s;
|
|
if (r)
|
|
s = r->scale;
|
|
luaReturnVec2(s.x, s.y);
|
|
}
|
|
|
|
luaFunc(obj_alpha)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
{
|
|
r->alpha.stop();
|
|
interpolateVec1(L, r->alpha, 2);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_alphaMod)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->alphaMod = lua_tonumber(L, 2);
|
|
luaReturnNil()
|
|
}
|
|
|
|
luaFunc(obj_getAlphaMod)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnNum(r ? r->alphaMod : 0.0f);
|
|
}
|
|
|
|
luaFunc(obj_getAlpha)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnNum(r ? r->alpha.x : 0.0f);
|
|
}
|
|
|
|
luaFunc(obj_color)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
{
|
|
r->color.stop();
|
|
interpolateVec3(L, r->color, 2);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_getColor)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
Vector c;
|
|
if(r)
|
|
c = r->color;
|
|
luaReturnVec3(c.x, c.y, c.z);
|
|
}
|
|
|
|
|
|
luaFunc(obj_rotate)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
{
|
|
r->rotation.stop();
|
|
interpolateVec1z(L, r->rotation, 2);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_rotateOffset)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
{
|
|
r->rotationOffset.stop();
|
|
interpolateVec1z(L, r->rotationOffset, 2);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_getRotation)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnNum(r ? r->rotation.z : 0.0f);
|
|
}
|
|
|
|
luaFunc(obj_getRotationOffset)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnNum(r ? r->rotationOffset.z : 0.0f);
|
|
}
|
|
|
|
luaFunc(obj_offset)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
{
|
|
r->offset.stop();
|
|
interpolateVec2(L, r->offset, 2);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_internalOffset)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
{
|
|
r->internalOffset.stop();
|
|
interpolateVec2(L, r->internalOffset, 2);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_getInternalOffset)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
Vector io;
|
|
if (r)
|
|
io = r->internalOffset;
|
|
luaReturnVec2(io.x, io.y);
|
|
}
|
|
|
|
luaFunc(obj_getPosition)
|
|
{
|
|
float x=0,y=0;
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
{
|
|
x = r->position.x;
|
|
y = r->position.y;
|
|
}
|
|
luaReturnVec2(x, y);
|
|
}
|
|
|
|
|
|
luaFunc(obj_getOffset)
|
|
{
|
|
float x=0,y=0;
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
{
|
|
x = r->offset.x;
|
|
y = r->offset.y;
|
|
}
|
|
luaReturnVec2(x, y);
|
|
}
|
|
luaFunc(obj_x)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
float x = 0;
|
|
if (r)
|
|
x = r->position.x;
|
|
luaReturnNum(x);
|
|
}
|
|
|
|
luaFunc(obj_y)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
float y = 0;
|
|
if (r)
|
|
y = r->position.y;
|
|
luaReturnNum(y);
|
|
}
|
|
|
|
luaFunc(obj_setBlendType)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->setBlendType(lua_tointeger(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_getBlendType)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnInt(r ? r->blendType : 0);
|
|
}
|
|
|
|
luaFunc(obj_setTexture)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnBool(r ? r->setTexture(getString(L, 2)) : false);
|
|
}
|
|
|
|
luaFunc(obj_getTexture)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r && r->texture)
|
|
luaReturnStr(r->texture->name.c_str());
|
|
luaReturnStr("");
|
|
}
|
|
|
|
luaFunc(obj_delete)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
{
|
|
float time = lua_tonumber(L, 2);
|
|
if (time == 0)
|
|
{
|
|
r->safeKill();
|
|
}
|
|
else
|
|
{
|
|
r->fadeAlphaWithLife = true;
|
|
r->setLife(1);
|
|
r->setDecayRate(1.0f/time);
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_setLife)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->setLife(lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_getLife)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnNum(r ? r->life : 0.0f);
|
|
}
|
|
|
|
luaFunc(obj_setDecayRate)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->setDecayRate(lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_addDeathNotify)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
RenderObject *which = robj(L, 2);
|
|
if (r && which)
|
|
r->addDeathNotify(which);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_addChild)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
RenderObject *which = robj(L, 2);
|
|
bool takeOwnership = getBool(L, 3);
|
|
bool front = getBool(L, 4);
|
|
if (r && which)
|
|
{
|
|
if (takeOwnership)
|
|
{
|
|
// HACK: this is ugly, but necessary to prevent double-deletion
|
|
// anyways, dangerous; addChild() may fail, causing a small memory leak (and an error message)
|
|
dsq->getState(dsq->game->name)->removeRenderObjectFromList(which);
|
|
which->setStateDataObject(NULL);
|
|
core->removeRenderObject(which, Core::DO_NOT_DESTROY_RENDER_OBJECT);
|
|
r->addChild(which, PM_POINTER, RBP_NONE, front ? CHILD_FRONT : CHILD_BACK);
|
|
}
|
|
else
|
|
r->addChild(which, PM_STATIC);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_getChild)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
size_t idx = lua_tointeger(L, 2);
|
|
luaReturnPtr(r && idx < r->children.size() ? r->children[idx] : NULL);
|
|
}
|
|
|
|
luaFunc(obj_removeChild)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
RenderObject *which = robj(L, 2);
|
|
if(r && which)
|
|
r->removeChild(which);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_removeChildIdx)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
size_t idx = lua_tointeger(L, 2);
|
|
if(r && idx < r->children.size())
|
|
r->removeChild(r->children[idx]);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_removeAllChildren)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
bool del = getBool(L, 2);
|
|
if(r)
|
|
{
|
|
if(del)
|
|
for(RenderObject::Children::iterator it = r->children.begin(); it != r->children.end(); ++it)
|
|
(*it)->safeKill();
|
|
r->children.clear();
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_getNumChildren)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnInt(r ? (int)r->children.size() : 0);
|
|
}
|
|
|
|
luaFunc(obj_setRenderBeforeParent)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->renderBeforeParent = getBool(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_isRenderBeforeParent)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnBool(r ? r->renderBeforeParent : false);
|
|
}
|
|
|
|
// Not so pretty: Because RenderObject has a `velocity' vector,
|
|
// and Entity has `vel' ADDITIONALLY, we need to use
|
|
// extra functions to manage RenderObject's velocities.
|
|
// Different names were chosen to allow avoid name clashing. -- FG
|
|
|
|
luaFunc(obj_setInternalVel)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
{
|
|
r->velocity.stop();
|
|
interpolateVec2(L, r->velocity, 2);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_setInternalVelLen)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
{
|
|
r->velocity.stop();
|
|
r->velocity.setLength2D(lua_tonumber(L, 2));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_getInternalVelLen)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnNum(r ? r->velocity.getLength2D() : 0.0f);
|
|
}
|
|
|
|
|
|
luaFunc(obj_getInternalVel)
|
|
{
|
|
Vector v;
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
v = r->velocity;
|
|
luaReturnVec2(v.x, v.y);
|
|
}
|
|
|
|
luaFunc(obj_ivelx)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnNum(r ? r->velocity.x : 0.0f);
|
|
}
|
|
|
|
luaFunc(obj_ively)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnNum(r ? r->velocity.y : 0.0f);
|
|
}
|
|
|
|
luaFunc(obj_addInternalVel)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->velocity += Vector(lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_isInternalVelIn)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnBool(r ? r->velocity.isLength2DIn(lua_tonumber(L, 2)) : false);
|
|
}
|
|
|
|
luaFunc(obj_setGravity)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
{
|
|
r->gravity.stop();
|
|
interpolateVec2(L, r->gravity, 2);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_getGravity)
|
|
{
|
|
Vector v;
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
v = r->gravity;
|
|
luaReturnVec2(v.x, v.y);
|
|
}
|
|
|
|
luaFunc(obj_getCollideRadius)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnNum(r ? r->collideRadius : 0);
|
|
}
|
|
|
|
luaFunc(obj_setCollideRadius)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->collideRadius = lua_tonumber(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_getNormal)
|
|
{
|
|
Vector v(0, 1);
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
v = r->getForward();
|
|
luaReturnVec2(v.x, v.y);
|
|
}
|
|
|
|
luaFunc(obj_getVectorToObj)
|
|
{
|
|
RenderObject *r1 = robj(L);
|
|
RenderObject *r2 = robj(L, 2);
|
|
if (r1 && r2)
|
|
{
|
|
Vector diff = r2->position - r1->position;
|
|
luaReturnVec2(diff.x, diff.y);
|
|
}
|
|
else
|
|
{
|
|
luaReturnVec2(0, 0);
|
|
}
|
|
}
|
|
|
|
luaFunc(obj_stopInterpolating)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->position.stop();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_isInterpolating)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnBool(r ? r->position.isInterpolating() : false);
|
|
}
|
|
|
|
luaFunc(obj_followCamera)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->followCamera = lua_tonumber(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_update)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->update(lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_getWorldPosition)
|
|
{
|
|
RenderObject *b = robj(L);
|
|
float x = 0, y = 0;
|
|
if (b)
|
|
{
|
|
Vector v = b->getWorldCollidePosition(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)));
|
|
x = v.x;
|
|
y = v.y;
|
|
}
|
|
luaReturnVec2(x, y);
|
|
}
|
|
|
|
luaFunc(obj_getWorldRotation)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnNum(r ? r->getWorldRotation() : 0.0f);
|
|
}
|
|
|
|
luaFunc(obj_getWorldPositionAndRotation)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
{
|
|
Vector v = r->getWorldPositionAndRotation();
|
|
luaReturnVec3(v.x, v.y, v.z);
|
|
}
|
|
luaReturnVec3(0.0f, 0.0f, 0.0f);
|
|
}
|
|
|
|
luaFunc(obj_moveToFront)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->moveToFront();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_moveToBack)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->moveToBack();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_setLayer)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
core->switchRenderObjectLayer(r, lua_tointeger(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_getLayer)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnInt(r ? r->layer : 0);
|
|
}
|
|
|
|
luaFunc(obj_setRenderPass)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
int pass = lua_tointeger(L, 2);
|
|
if (r)
|
|
r->setRenderPass(pass);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_setOverrideRenderPass)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
int pass = lua_tointeger(L, 2);
|
|
if (r)
|
|
r->setOverrideRenderPass(pass);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_fh)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->flipHorizontal();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_fhTo)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
bool b = getBool(L);
|
|
if (r)
|
|
r->fhTo(b);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_fv)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->flipVertical();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_isfh)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnBool(r ? r->isfh() : false);
|
|
}
|
|
|
|
luaFunc(obj_isfv)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnBool(r ? r->isfv() : false);
|
|
}
|
|
|
|
luaFunc(obj_isfhr)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnBool(r ? r->isfhr() : false);
|
|
}
|
|
|
|
luaFunc(obj_isfvr)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnBool(r ? r->isfvr() : false);
|
|
}
|
|
|
|
luaFunc(obj_damageFlash)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
int type = lua_tointeger(L, 2);
|
|
if (r)
|
|
{
|
|
Vector toColor = Vector(1, 0.1f, 0.1f);
|
|
if (type == 1)
|
|
toColor = Vector(1, 1, 0.1f);
|
|
r->color = Vector(1,1,1);
|
|
r->color.interpolateTo(toColor, 0.1f, 5, 1);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_setCull)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->cull = getBool(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_setCullRadius)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->setOverrideCullRadius(lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_isScaling)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnBool(r ? r->scale.isInterpolating() : false);
|
|
}
|
|
|
|
luaFunc(obj_isRotating)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnBool(r ? r->rotation.isInterpolating() : false);
|
|
}
|
|
|
|
luaFunc(obj_setUpdateCull)
|
|
{
|
|
RenderObject *r = robj(L);;
|
|
if (r)
|
|
r->updateCull = lua_tonumber(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_getUpdateCull)
|
|
{
|
|
RenderObject *r = robj(L);;
|
|
luaReturnNum(r ? r->updateCull : 0.0f);
|
|
}
|
|
|
|
luaFunc(obj_setPositionX)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->position.x = lua_tonumber(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_setPositionY)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->position.y = lua_tonumber(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_enableMotionBlur)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->enableMotionBlur(10, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_disableMotionBlur)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->disableMotionBlur();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_collideCircleVsLine)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
float x1, y1, x2, y2, sz;
|
|
x1 = lua_tonumber(L, 2);
|
|
y1 = lua_tonumber(L, 3);
|
|
x2 = lua_tonumber(L, 4);
|
|
y2 = lua_tonumber(L, 5);
|
|
sz = lua_tonumber(L, 6);
|
|
bool v = false;
|
|
if (r)
|
|
v = dsq->game->collideCircleVsLine(r, Vector(x1, y1), Vector(x2, y2), sz);
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(obj_collideCircleVsLineAngle)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
float angle = lua_tonumber(L, 2);
|
|
float start=lua_tonumber(L, 3), end=lua_tonumber(L, 4), radius=lua_tonumber(L, 5);
|
|
float x=lua_tonumber(L, 6);
|
|
float y=lua_tonumber(L, 7);
|
|
bool v = false;
|
|
if (r)
|
|
v = dsq->game->collideCircleVsLineAngle(r, angle, start, end, radius, Vector(x,y));
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(obj_fadeAlphaWithLife)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
if (r)
|
|
r->fadeAlphaWithLife = getBool(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(obj_getWorldScale)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
Vector s;
|
|
if (r)
|
|
s = r->getRealScale();
|
|
luaReturnVec2(s.x, s.y);
|
|
}
|
|
|
|
luaFunc(obj_getParent)
|
|
{
|
|
RenderObject *r = robj(L);
|
|
luaReturnPtr(r ? r->getParent() : NULL);
|
|
}
|
|
|
|
|
|
// ----- end RenderObject common functions -----
|
|
|
|
// ----- Quad common functions -----
|
|
|
|
luaFunc(quad_isVisible)
|
|
{
|
|
Quad *q = getQuad(L);
|
|
luaReturnBool(q ? q->renderQuad : false);
|
|
}
|
|
|
|
luaFunc(quad_setVisible)
|
|
{
|
|
Quad *q = getQuad(L);
|
|
if (q)
|
|
q->renderQuad = getBool(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(quad_getWidth)
|
|
{
|
|
Quad *q = getQuad(L);
|
|
luaReturnNum(q ? q->width : 0.0f);
|
|
}
|
|
|
|
luaFunc(quad_getHeight)
|
|
{
|
|
Quad *q = getQuad(L);
|
|
luaReturnNum(q ? q->height : 0.0f);
|
|
}
|
|
|
|
luaFunc(quad_setWidth)
|
|
{
|
|
Quad *q = getQuad(L);
|
|
if (q)
|
|
q->setWidth(lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(quad_setHeight)
|
|
{
|
|
Quad *q = getQuad(L);
|
|
if (q)
|
|
q->setHeight(lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(quad_setSegs)
|
|
{
|
|
Quad *b = getQuad(L);
|
|
if (b)
|
|
b->setSegs(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6), lua_tonumber(L, 7), lua_tonumber(L, 8), getBool(L, 9));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(quad_setRepeatTexture)
|
|
{
|
|
Quad *b = getQuad(L);
|
|
if (b)
|
|
b->repeatTextureToFill(getBool(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(quad_setRepeatScale)
|
|
{
|
|
Quad *b = getQuad(L);
|
|
if (b)
|
|
b->repeatToFillScale = Vector(lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(quad_isRepeatTexture)
|
|
{
|
|
Quad *b = getQuad(L);
|
|
luaReturnBool(b ? b->isRepeatingTextureToFill() : false);
|
|
}
|
|
|
|
luaFunc(quad_setTexOffset)
|
|
{
|
|
Quad *b = getQuad(L);
|
|
if (b)
|
|
b->texOff = Vector(lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(quad_getTexOffset)
|
|
{
|
|
Quad *b = getQuad(L);
|
|
Vector v;
|
|
if (b)
|
|
v = b->texOff;
|
|
luaReturnVec2(v.x, v.y);
|
|
}
|
|
|
|
luaFunc(quad_setRenderBorder)
|
|
{
|
|
Quad *b = getQuad(L);
|
|
if (b)
|
|
b->renderBorder = getBool(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(quad_isRenderBorder)
|
|
{
|
|
Quad *b = getQuad(L);
|
|
luaReturnBool(b ? b->renderBorder : false);
|
|
}
|
|
|
|
luaFunc(quad_setRenderCenter)
|
|
{
|
|
Quad *b = getQuad(L);
|
|
if (b)
|
|
b->renderCenter = getBool(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(quad_isRenderCenter)
|
|
{
|
|
Quad *b = getQuad(L);
|
|
luaReturnBool(b ? b->renderCenter : false);
|
|
}
|
|
|
|
|
|
luaFunc(quad_borderAlpha)
|
|
{
|
|
Quad *b = getQuad(L);
|
|
if (b)
|
|
b->borderAlpha = lua_tonumber(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(quad_getBorderAlpha)
|
|
{
|
|
Quad *b = getQuad(L);
|
|
luaReturnNum(b ? b->borderAlpha : 0.0f);
|
|
}
|
|
|
|
// --- standard set/get functions for each type, wrapping RenderObject functions ---
|
|
|
|
#define MK_FUNC(base, getter, prefix, suffix) \
|
|
luaFunc(prefix##_##suffix) \
|
|
{ \
|
|
typecheckOnly(getter(L)); \
|
|
return forwardCall(base##_##suffix); \
|
|
}
|
|
|
|
#define MK_ALIAS(prefix, suffix, alias) // not yet used here. defined to avoid warnings
|
|
|
|
#define RO_FUNC(getter, prefix, suffix) MK_FUNC(obj, getter, prefix, suffix)
|
|
#define Q_FUNC(getter, prefix, suffix) MK_FUNC(quad, getter, prefix, suffix)
|
|
|
|
#define MAKE_ROBJ_FUNCS(getter, prefix) \
|
|
RO_FUNC(getter, prefix, setPosition ) \
|
|
RO_FUNC(getter, prefix, scale ) \
|
|
RO_FUNC(getter, prefix, getScale ) \
|
|
RO_FUNC(getter, prefix, isScaling ) \
|
|
RO_FUNC(getter, prefix, alpha ) \
|
|
RO_FUNC(getter, prefix, alphaMod ) \
|
|
RO_FUNC(getter, prefix, getAlpha ) \
|
|
RO_FUNC(getter, prefix, getAlphaMod ) \
|
|
RO_FUNC(getter, prefix, color ) \
|
|
RO_FUNC(getter, prefix, getColor ) \
|
|
RO_FUNC(getter, prefix, rotate ) \
|
|
RO_FUNC(getter, prefix, rotateOffset ) \
|
|
RO_FUNC(getter, prefix, getRotation ) \
|
|
RO_FUNC(getter, prefix, getRotationOffset) \
|
|
RO_FUNC(getter, prefix, isRotating ) \
|
|
RO_FUNC(getter, prefix, offset ) \
|
|
RO_FUNC(getter, prefix, getOffset ) \
|
|
RO_FUNC(getter, prefix, internalOffset ) \
|
|
RO_FUNC(getter, prefix, getInternalOffset) \
|
|
RO_FUNC(getter, prefix, getPosition ) \
|
|
RO_FUNC(getter, prefix, getTexture ) \
|
|
RO_FUNC(getter, prefix, x ) \
|
|
RO_FUNC(getter, prefix, y ) \
|
|
RO_FUNC(getter, prefix, setBlendType ) \
|
|
RO_FUNC(getter, prefix, getBlendType ) \
|
|
RO_FUNC(getter, prefix, setTexture ) \
|
|
RO_FUNC(getter, prefix, delete ) \
|
|
RO_FUNC(getter, prefix, getLife ) \
|
|
RO_FUNC(getter, prefix, setLife ) \
|
|
RO_FUNC(getter, prefix, setDecayRate ) \
|
|
RO_FUNC(getter, prefix, addDeathNotify ) \
|
|
RO_FUNC(getter, prefix, setInternalVel ) \
|
|
RO_FUNC(getter, prefix, setInternalVelLen) \
|
|
RO_FUNC(getter, prefix, getInternalVel ) \
|
|
RO_FUNC(getter, prefix, ivelx ) \
|
|
RO_FUNC(getter, prefix, ively ) \
|
|
RO_FUNC(getter, prefix, addInternalVel ) \
|
|
RO_FUNC(getter, prefix, isInternalVelIn) \
|
|
RO_FUNC(getter, prefix, getInternalVelLen) \
|
|
RO_FUNC(getter, prefix, setGravity ) \
|
|
RO_FUNC(getter, prefix, getGravity ) \
|
|
RO_FUNC(getter, prefix, getCollideRadius) \
|
|
RO_FUNC(getter, prefix, setCollideRadius) \
|
|
RO_FUNC(getter, prefix, getNormal ) \
|
|
RO_FUNC(getter, prefix, stopInterpolating)\
|
|
RO_FUNC(getter, prefix, isInterpolating)\
|
|
RO_FUNC(getter, prefix, followCamera ) \
|
|
RO_FUNC(getter, prefix, update ) \
|
|
RO_FUNC(getter, prefix, getWorldPosition) \
|
|
RO_FUNC(getter, prefix, getWorldRotation) \
|
|
RO_FUNC(getter, prefix, getWorldPositionAndRotation)\
|
|
RO_FUNC(getter, prefix, moveToFront ) \
|
|
RO_FUNC(getter, prefix, moveToBack ) \
|
|
RO_FUNC(getter, prefix, setLayer ) \
|
|
RO_FUNC(getter, prefix, getLayer ) \
|
|
RO_FUNC(getter, prefix, setRenderBeforeParent) \
|
|
RO_FUNC(getter, prefix, isRenderBeforeParent) \
|
|
RO_FUNC(getter, prefix, addChild ) \
|
|
RO_FUNC(getter, prefix, getChild ) \
|
|
RO_FUNC(getter, prefix, removeChild ) \
|
|
RO_FUNC(getter, prefix, removeChildIdx ) \
|
|
RO_FUNC(getter, prefix, removeAllChildren) \
|
|
RO_FUNC(getter, prefix, getNumChildren ) \
|
|
RO_FUNC(getter, prefix, fh ) \
|
|
RO_FUNC(getter, prefix, fv ) \
|
|
RO_FUNC(getter, prefix, fhTo ) \
|
|
RO_FUNC(getter, prefix, isfh ) \
|
|
RO_FUNC(getter, prefix, isfv ) \
|
|
RO_FUNC(getter, prefix, isfhr ) \
|
|
RO_FUNC(getter, prefix, isfvr ) \
|
|
RO_FUNC(getter, prefix, damageFlash ) \
|
|
RO_FUNC(getter, prefix, setCull ) \
|
|
RO_FUNC(getter, prefix, setCullRadius ) \
|
|
RO_FUNC(getter, prefix, setUpdateCull ) \
|
|
RO_FUNC(getter, prefix, getUpdateCull ) \
|
|
RO_FUNC(getter, prefix, setRenderPass ) \
|
|
RO_FUNC(getter, prefix, setOverrideRenderPass ) \
|
|
RO_FUNC(getter, prefix, setPositionX ) \
|
|
RO_FUNC(getter, prefix, setPositionY ) \
|
|
RO_FUNC(getter, prefix, enableMotionBlur ) \
|
|
RO_FUNC(getter, prefix, disableMotionBlur ) \
|
|
RO_FUNC(getter, prefix, collideCircleVsLine) \
|
|
RO_FUNC(getter, prefix, collideCircleVsLineAngle) \
|
|
RO_FUNC(getter, prefix, getVectorToObj ) \
|
|
RO_FUNC(getter, prefix, fadeAlphaWithLife ) \
|
|
RO_FUNC(getter, prefix, getWorldScale ) \
|
|
RO_FUNC(getter, prefix, getParent ) \
|
|
MK_ALIAS(prefix, fh, flipHorizontal ) \
|
|
MK_ALIAS(prefix, fv, flipVertical )
|
|
|
|
#define MAKE_QUAD_FUNCS(getter, prefix) \
|
|
MAKE_ROBJ_FUNCS(getter, prefix) \
|
|
Q_FUNC(getter, prefix, setVisible ) \
|
|
Q_FUNC(getter, prefix, isVisible ) \
|
|
Q_FUNC(getter, prefix, setWidth ) \
|
|
Q_FUNC(getter, prefix, setHeight ) \
|
|
Q_FUNC(getter, prefix, getWidth ) \
|
|
Q_FUNC(getter, prefix, getHeight ) \
|
|
Q_FUNC(getter, prefix, setSegs ) \
|
|
Q_FUNC(getter, prefix, setRepeatTexture) \
|
|
Q_FUNC(getter, prefix, isRepeatTexture ) \
|
|
Q_FUNC(getter, prefix, setRepeatScale ) \
|
|
Q_FUNC(getter, prefix, setRenderBorder ) \
|
|
Q_FUNC(getter, prefix, isRenderBorder ) \
|
|
Q_FUNC(getter, prefix, setRenderCenter ) \
|
|
Q_FUNC(getter, prefix, isRenderCenter ) \
|
|
Q_FUNC(getter, prefix, borderAlpha ) \
|
|
Q_FUNC(getter, prefix, getBorderAlpha ) \
|
|
Q_FUNC(getter, prefix, setTexOffset ) \
|
|
Q_FUNC(getter, prefix, getTexOffset )
|
|
|
|
// This should reflect the internal class hierarchy,
|
|
// e.g. a Beam is a Quad, so it can use quad_* functions
|
|
#define EXPAND_FUNC_PROTOTYPES \
|
|
MAKE_QUAD_FUNCS(entity, entity) \
|
|
MAKE_QUAD_FUNCS(bone, bone ) \
|
|
MAKE_QUAD_FUNCS(getShot, shot ) \
|
|
MAKE_QUAD_FUNCS(beam, beam ) \
|
|
MAKE_ROBJ_FUNCS(getQuad, quad ) \
|
|
MAKE_ROBJ_FUNCS(getWeb, web ) \
|
|
MAKE_ROBJ_FUNCS(getText, text ) \
|
|
MAKE_ROBJ_FUNCS(getParticle, pe )
|
|
|
|
// first time, create them. (There is a second use of this further down, with different MK_* macros)
|
|
EXPAND_FUNC_PROTOTYPES
|
|
|
|
|
|
luaFunc(debugBreak)
|
|
{
|
|
debugLog("DEBUG BREAK");
|
|
triggerBreakpoint();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setIgnoreAction)
|
|
{
|
|
dsq->game->setIgnoreAction((AquariaActions)lua_tointeger(L, 1), getBool(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(isIgnoreAction)
|
|
{
|
|
luaReturnBool(dsq->game->isIgnoreAction((AquariaActions)lua_tointeger(L, 1)));
|
|
}
|
|
|
|
luaFunc(sendAction)
|
|
{
|
|
AquariaActions ac = (AquariaActions)lua_tointeger(L, 1);
|
|
int state = lua_tointeger(L, 2);
|
|
int mask = lua_tointeger(L, 3);
|
|
int source = lua_tointeger(L, 4);
|
|
InputDevice device = (InputDevice)lua_tointeger(L, 5);
|
|
if(!mask)
|
|
mask = -1;
|
|
if(mask & 1)
|
|
dsq->game->action(ac, state, source, device);
|
|
if((mask & 2) && dsq->game->avatar)
|
|
dsq->game->avatar->action(ac, state, source, device);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(randRange)
|
|
{
|
|
int n1 = lua_tointeger(L, 1);
|
|
int n2 = lua_tointeger(L, 2);
|
|
int spread = n2-n1;
|
|
|
|
int r = rand()%spread;
|
|
r += n1;
|
|
|
|
luaReturnNum(r);
|
|
}
|
|
|
|
luaFunc(upgradeHealth)
|
|
{
|
|
dsq->continuity.upgradeHealth();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(shakeCamera)
|
|
{
|
|
dsq->shakeCamera(lua_tonumber(L,1), lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(rumble)
|
|
{
|
|
int source = lua_tointeger(L, 4) - 1;
|
|
Avatar *a = dsq->game->avatar;
|
|
InputDevice device = (InputDevice)lua_tointeger(L, 5);
|
|
if(device == INPUT_NODEVICE) // default: use avatar status
|
|
device = a ? a->getLastActionInputDevice() : INPUT_NODEVICE;
|
|
dsq->rumble(lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3), source, device);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(changeForm)
|
|
{
|
|
dsq->game->avatar->changeForm((FormType)lua_tointeger(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(getWaterLevel)
|
|
{
|
|
luaReturnNum(dsq->game->getWaterLevel());
|
|
}
|
|
|
|
luaFunc(setPoison)
|
|
{
|
|
dsq->continuity.setPoison(lua_tonumber(L, 1), lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(cureAllStatus)
|
|
{
|
|
dsq->continuity.cureAllStatus();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setMusicToPlay)
|
|
{
|
|
if (lua_isstring(L, 1))
|
|
dsq->game->setMusicToPlay(getString(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setActivePet)
|
|
{
|
|
Entity *e = dsq->game->setActivePet(lua_tonumber(L, 1));
|
|
|
|
luaReturnPtr(e);
|
|
}
|
|
|
|
luaFunc(setWaterLevel)
|
|
{
|
|
interpolateVec1(L, dsq->game->waterLevel, 1);
|
|
luaReturnNum(dsq->game->waterLevel.x);
|
|
}
|
|
|
|
luaFunc(getForm)
|
|
{
|
|
luaReturnNum(dsq->continuity.form);
|
|
}
|
|
|
|
luaFunc(isForm)
|
|
{
|
|
FormType form = FormType(lua_tointeger(L, 1));
|
|
bool v = (form == dsq->continuity.form);
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(learnFormUpgrade)
|
|
{
|
|
dsq->continuity.learnFormUpgrade((FormUpgradeType)lua_tointeger(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(hasLi)
|
|
{
|
|
luaReturnBool(dsq->continuity.hasLi());
|
|
}
|
|
|
|
luaFunc(hasFormUpgrade)
|
|
{
|
|
luaReturnBool(dsq->continuity.hasFormUpgrade((FormUpgradeType)lua_tointeger(L, 1)));
|
|
}
|
|
|
|
// This used to be castSong(), but that name is already taken by an interface function. -- FG
|
|
luaFunc(singSong)
|
|
{
|
|
dsq->continuity.castSong(lua_tonumber(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(isStory)
|
|
{
|
|
luaReturnBool(dsq->continuity.isStory(lua_tonumber(L, 1)));
|
|
}
|
|
|
|
luaFunc(getNoteVector)
|
|
{
|
|
int note = lua_tointeger(L, 1);
|
|
float mag = lua_tonumber(L, 2);
|
|
Vector v = dsq->getNoteVector(note, mag);
|
|
luaReturnVec2(v.x, v.y);
|
|
}
|
|
|
|
luaFunc(getNoteColor)
|
|
{
|
|
int note = lua_tointeger(L, 1);
|
|
Vector v = dsq->getNoteColor(note);
|
|
luaReturnVec3(v.x, v.y, v.z);
|
|
}
|
|
|
|
luaFunc(getRandNote)
|
|
{
|
|
luaReturnNum(dsq->getRandNote());
|
|
}
|
|
|
|
luaFunc(getStory)
|
|
{
|
|
luaReturnNum(dsq->continuity.getStory());
|
|
}
|
|
|
|
luaFunc(foundLostMemory)
|
|
{
|
|
int num = 0;
|
|
if (dsq->continuity.getFlag(FLAG_SECRET01)) num++;
|
|
if (dsq->continuity.getFlag(FLAG_SECRET02)) num++;
|
|
if (dsq->continuity.getFlag(FLAG_SECRET03)) num++;
|
|
|
|
int sbank = 800+(num-1);
|
|
dsq->game->setControlHint(dsq->continuity.stringBank.get(sbank), 0, 0, 0, 4, "13/face");
|
|
|
|
dsq->sound->playSfx("memory-found");
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setStory)
|
|
{
|
|
dsq->continuity.setStory(lua_tonumber(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(confirm)
|
|
{
|
|
std::string s1 = getString(L, 1);
|
|
std::string s2 = getString(L, 2);
|
|
bool b = dsq->confirm(s1, s2);
|
|
luaReturnBool(b);
|
|
}
|
|
|
|
luaFunc(createWeb)
|
|
{
|
|
Web *web = new Web();
|
|
dsq->game->addRenderObject(web, LR_PARTICLES);
|
|
luaReturnPtr(web);
|
|
}
|
|
|
|
// spore has base entity
|
|
luaFunc(createSpore)
|
|
{
|
|
Vector pos(lua_tonumber(L, 1), lua_tonumber(L, 2));
|
|
if (Spore::isPositionClear(pos))
|
|
{
|
|
Spore *spore = new Spore(pos);
|
|
dsq->game->addRenderObject(spore, LR_ENTITIES);
|
|
luaReturnPtr(spore);
|
|
}
|
|
else
|
|
luaReturnPtr(NULL);
|
|
}
|
|
|
|
luaFunc(web_addPoint)
|
|
{
|
|
Web *w = getWeb(L);
|
|
float x = lua_tonumber(L, 2);
|
|
float y = lua_tonumber(L, 3);
|
|
int r = 0;
|
|
if (w)
|
|
{
|
|
r = w->addPoint(Vector(x,y));
|
|
}
|
|
luaReturnInt(r);
|
|
}
|
|
|
|
luaFunc(web_setPoint)
|
|
{
|
|
Web *w = getWeb(L);
|
|
int pt = lua_tointeger(L, 2);
|
|
float x = lua_tonumber(L, 3);
|
|
float y = lua_tonumber(L, 4);
|
|
if (w)
|
|
{
|
|
w->setPoint(pt, Vector(x, y));
|
|
}
|
|
luaReturnInt(pt);
|
|
}
|
|
|
|
luaFunc(web_getNumPoints)
|
|
{
|
|
Web *web = getWeb(L);
|
|
int num = 0;
|
|
if (web)
|
|
{
|
|
num = web->getNumPoints();
|
|
}
|
|
luaReturnInt(num);
|
|
}
|
|
|
|
luaFunc(getFirstShot)
|
|
{
|
|
luaReturnPtr(Shot::getFirstShot());
|
|
}
|
|
|
|
luaFunc(getNextShot)
|
|
{
|
|
luaReturnPtr(Shot::getNextShot());
|
|
}
|
|
|
|
luaFunc(shot_getName)
|
|
{
|
|
Shot *s = getShot(L);
|
|
luaReturnStr(s ? s->getName() : "");
|
|
}
|
|
|
|
luaFunc(shot_setOut)
|
|
{
|
|
Shot *shot = getShot(L);
|
|
float outness = lua_tonumber(L, 2);
|
|
if (shot && shot->firer)
|
|
{
|
|
Vector adjust = shot->velocity;
|
|
adjust.setLength2D(outness);
|
|
shot->position += adjust;
|
|
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(shot_setAimVector)
|
|
{
|
|
Shot *shot = getShot(L);
|
|
float ax = lua_tonumber(L, 2);
|
|
float ay = lua_tonumber(L, 3);
|
|
if (shot)
|
|
{
|
|
shot->setAimVector(Vector(ax, ay));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(shot_getEffectTime)
|
|
{
|
|
if (lua_isstring(L, 1))
|
|
{
|
|
ShotData *data = Shot::getShotData(lua_tostring(L, 1));
|
|
luaReturnNum(data ? data->effectTime : 0.0f);
|
|
}
|
|
|
|
Shot *shot = getShot(L);
|
|
luaReturnNum((shot && shot->shotData) ? shot->shotData->effectTime : 0.0f);
|
|
}
|
|
|
|
luaFunc(shot_isIgnoreShield)
|
|
{
|
|
if (lua_isstring(L, 1))
|
|
{
|
|
ShotData *data = Shot::getShotData(lua_tostring(L, 1));
|
|
luaReturnBool(data ? data->ignoreShield : false);
|
|
}
|
|
|
|
Shot *shot = getShot(L);
|
|
luaReturnBool((shot && shot->shotData) ? shot->shotData->ignoreShield : false);
|
|
}
|
|
|
|
luaFunc(shot_getFirer)
|
|
{
|
|
Shot *shot = getShot(L);
|
|
luaReturnPtr(shot ? shot->firer : NULL);
|
|
}
|
|
|
|
luaFunc(shot_setFirer)
|
|
{
|
|
Shot *shot = getShot(L);
|
|
if(shot)
|
|
{
|
|
Entity *e = lua_isuserdata(L, 2) ? entity(L, 2) : NULL;
|
|
shot->firer = e;
|
|
}
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(shot_setTarget)
|
|
{
|
|
Shot *shot = getShot(L);
|
|
if(shot)
|
|
{
|
|
Entity *e = lua_isuserdata(L, 2) ? entity(L, 2) : NULL;
|
|
shot->setTarget(e);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(shot_getTarget)
|
|
{
|
|
Shot *shot = getShot(L);
|
|
luaReturnPtr(shot ? shot->target : NULL);
|
|
}
|
|
|
|
luaFunc(shot_setExtraDamage)
|
|
{
|
|
Shot *shot = getShot(L);
|
|
if(shot)
|
|
shot->extraDamage = lua_tonumber(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(shot_getExtraDamage)
|
|
{
|
|
Shot *shot = getShot(L);
|
|
luaReturnNum(shot ? shot->extraDamage : 0.0f);
|
|
}
|
|
|
|
luaFunc(shot_getDamage)
|
|
{
|
|
Shot *shot = getShot(L);
|
|
luaReturnNum(shot ? shot->getDamage() : 0.0f);
|
|
}
|
|
|
|
luaFunc(shot_getDamageType)
|
|
{
|
|
if (lua_isstring(L, 1))
|
|
{
|
|
ShotData *data = Shot::getShotData(lua_tostring(L, 1));
|
|
luaReturnInt(data ? data->damageType : 0);
|
|
}
|
|
|
|
Shot *shot = getShot(L);
|
|
luaReturnNum(shot ? shot->getDamageType() : DT_NONE);
|
|
}
|
|
|
|
luaFunc(shot_getMaxSpeed)
|
|
{
|
|
if (lua_isstring(L, 1))
|
|
{
|
|
ShotData *data = Shot::getShotData(lua_tostring(L, 1));
|
|
luaReturnNum(data ? data->maxSpeed : 0.0f);
|
|
}
|
|
|
|
Shot *shot = getShot(L);
|
|
luaReturnNum(shot ? shot->maxSpeed : 0.0f);
|
|
}
|
|
|
|
luaFunc(shot_setMaxSpeed)
|
|
{
|
|
Shot *shot = getShot(L);
|
|
if (shot)
|
|
shot->maxSpeed = lua_tonumber(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(shot_getHomingness)
|
|
{
|
|
if (lua_isstring(L, 1))
|
|
{
|
|
ShotData *data = Shot::getShotData(lua_tostring(L, 1));
|
|
luaReturnNum(data ? data->homing : 0.0f);
|
|
}
|
|
|
|
Shot *shot = getShot(L);
|
|
luaReturnNum(shot ? shot->homingness : 0.0f);
|
|
}
|
|
|
|
luaFunc(shot_setHomingness)
|
|
{
|
|
Shot *shot = getShot(L);
|
|
if (shot)
|
|
shot->homingness = lua_tonumber(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(shot_getLifeTime)
|
|
{
|
|
if (lua_isstring(L, 1))
|
|
{
|
|
ShotData *data = Shot::getShotData(lua_tostring(L, 1));
|
|
luaReturnNum(data ? data->lifeTime : 0.0f);
|
|
}
|
|
|
|
Shot *shot = getShot(L);
|
|
luaReturnNum(shot ? shot->lifeTime : 0.0f);
|
|
}
|
|
|
|
luaFunc(shot_setLifeTime)
|
|
{
|
|
Shot *shot = getShot(L);
|
|
if (shot)
|
|
shot->lifeTime = lua_tonumber(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(shot_setDamageType)
|
|
{
|
|
Shot *shot = getShot(L);
|
|
if (shot)
|
|
shot->damageType = (DamageType)lua_tointeger(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(shot_setCheckDamageTarget)
|
|
{
|
|
Shot *shot = getShot(L);
|
|
if (shot)
|
|
shot->checkDamageTarget = getBool(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(shot_isCheckDamageTarget)
|
|
{
|
|
if (lua_isstring(L, 1))
|
|
{
|
|
ShotData *data = Shot::getShotData(lua_tostring(L, 1));
|
|
luaReturnBool(data ? data->checkDamageTarget : false);
|
|
}
|
|
|
|
Shot *shot = getShot(L);
|
|
luaReturnBool(shot ? shot->checkDamageTarget : false);
|
|
}
|
|
|
|
luaFunc(shot_setTrailPrt)
|
|
{
|
|
Shot *shot = getShot(L);
|
|
if (shot)
|
|
shot->setParticleEffect(getString(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(shot_setTargetPoint)
|
|
{
|
|
Shot *shot = getShot(L);
|
|
if (shot)
|
|
shot->setTargetPoint(lua_tointeger(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(shot_getTargetPoint)
|
|
{
|
|
Shot *shot = getShot(L);
|
|
luaReturnInt(shot ? shot->targetPt : 0);
|
|
}
|
|
|
|
luaFunc(shot_canHitEntity)
|
|
{
|
|
Shot *shot = getShot(L);
|
|
Entity *e = entity(L, 2);
|
|
bool hit = false;
|
|
if(shot && e && shot->isActive() && dsq->game->isEntityCollideWithShot(e, shot))
|
|
{
|
|
DamageData d;
|
|
d.attacker = shot->firer;
|
|
d.damage = shot->getDamage();
|
|
d.damageType = shot->getDamageType();
|
|
d.shot = shot;
|
|
hit = e->canShotHit(d);
|
|
}
|
|
luaReturnBool(hit);
|
|
}
|
|
|
|
|
|
typedef std::pair<Shot*, float> ShotDistancePair;
|
|
static std::vector<ShotDistancePair> filteredShots(20);
|
|
static int filteredShotIdx = 0;
|
|
|
|
static bool _shotDistanceCmp(const ShotDistancePair& a, const ShotDistancePair& b)
|
|
{
|
|
return a.second < b.second;
|
|
}
|
|
static bool _shotDistanceEq(const ShotDistancePair& a, const ShotDistancePair& b)
|
|
{
|
|
return a.first == b.first;
|
|
}
|
|
|
|
static size_t _shotFilter(lua_State *L)
|
|
{
|
|
const Vector p(lua_tonumber(L, 1), lua_tonumber(L, 2));
|
|
const float radius = lua_tonumber(L, 3);
|
|
const DamageType dt = lua_isnumber(L, 5) ? (DamageType)lua_tointeger(L, 5) : DT_NONE;
|
|
|
|
const float sqrRadius = radius * radius;
|
|
float distsq;
|
|
const bool skipRadiusCheck = radius <= 0;
|
|
size_t added = 0;
|
|
for(Shot::Shots::iterator it = Shot::shots.begin(); it != Shot::shots.end(); ++it)
|
|
{
|
|
Shot *s = *it;
|
|
|
|
if (s->isActive() && s->life >= 1.0f)
|
|
{
|
|
if (dt == DT_NONE || s->getDamageType() == dt)
|
|
{
|
|
distsq = (s->position - p).getSquaredLength2D();
|
|
if (skipRadiusCheck || distsq <= sqrRadius)
|
|
{
|
|
filteredShots.push_back(std::make_pair(s, distsq));
|
|
++added;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(added)
|
|
{
|
|
std::sort(filteredShots.begin(), filteredShots.end(), _shotDistanceCmp);
|
|
std::vector<ShotDistancePair>::iterator newend = std::unique(filteredShots.begin(), filteredShots.end(), _shotDistanceEq);
|
|
filteredShots.resize(std::distance(filteredShots.begin(), newend));
|
|
}
|
|
|
|
// Add terminator if there is none
|
|
if(filteredShots.size() && filteredShots.back().first)
|
|
filteredShots.push_back(std::make_pair((Shot*)NULL, 0.0f)); // terminator
|
|
|
|
filteredShotIdx = 0; // Reset getNextFilteredShot() iteration index
|
|
|
|
return added;
|
|
}
|
|
|
|
luaFunc(filterNearestShots)
|
|
{
|
|
filteredShots.clear();
|
|
luaReturnInt(_shotFilter(L));
|
|
}
|
|
|
|
luaFunc(filterNearestShotsAdd)
|
|
{
|
|
// Remove terminator if there is one
|
|
if(filteredShots.size() && !filteredShots.back().first)
|
|
filteredShots.pop_back();
|
|
luaReturnInt(_shotFilter(L));
|
|
}
|
|
|
|
luaFunc(getNextFilteredShot)
|
|
{
|
|
ShotDistancePair sp = filteredShots[filteredShotIdx];
|
|
if (sp.first)
|
|
++filteredShotIdx;
|
|
luaPushPointer(L, sp.first);
|
|
lua_pushnumber(L, sp.second);
|
|
return 2;
|
|
}
|
|
|
|
|
|
luaFunc(entity_setVel)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->vel = Vector(lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setVelLen)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->vel.setLength2D(lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getVelLen)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnNum(e ? e->vel.getLength2D() : 0.0f);
|
|
}
|
|
|
|
|
|
luaFunc(entity_getVel)
|
|
{
|
|
Vector v;
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
v = e->vel;
|
|
luaReturnVec2(v.x, v.y);
|
|
}
|
|
|
|
luaFunc(entity_velx)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnNum(e ? e->vel.x : 0.0f);
|
|
}
|
|
|
|
luaFunc(entity_vely)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnNum(e ? e->vel.y : 0.0f);
|
|
}
|
|
|
|
luaFunc(entity_addVel)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->vel += Vector(lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_addRandomVel)
|
|
{
|
|
Entity *e = entity(L);
|
|
float len = lua_tonumber(L, 2);
|
|
Vector add;
|
|
if (e && len)
|
|
{
|
|
int angle = int(rand()%360);
|
|
float a = MathFunctions::toRadians(angle);
|
|
add.x = sinf(a);
|
|
add.y = cosf(a);
|
|
add.setLength2D(len);
|
|
e->vel += add;
|
|
}
|
|
luaReturnVec2(add.x, add.y);
|
|
}
|
|
|
|
luaFunc(entity_isVelIn)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnBool(e ? e->vel.isLength2DIn(lua_tonumber(L, 2)) : false);
|
|
|
|
}
|
|
|
|
luaFunc(entity_clearVel)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->vel = Vector(0,0,0);
|
|
luaReturnNil();
|
|
}
|
|
// end extra Entity::vel functions
|
|
|
|
luaFunc(entity_getPushVec)
|
|
{
|
|
Entity *e = entity(L);
|
|
Vector v;
|
|
if (e)
|
|
v = e->getPushVec();
|
|
luaReturnVec2(v.x, v.y);
|
|
}
|
|
|
|
luaFunc(entity_addIgnoreShotDamageType)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->addIgnoreShotDamageType((DamageType)lua_tointeger(L, 2));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_warpLastPosition)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->warpLastPosition();
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
|
|
luaFunc(entity_velTowards)
|
|
{
|
|
Entity *e = entity(L);
|
|
float x = lua_tonumber(L, 2);
|
|
float y = lua_tonumber(L, 3);
|
|
float velLen = lua_tonumber(L, 4);
|
|
float range = lua_tonumber(L, 5);
|
|
if (e)
|
|
{
|
|
Vector pos(x,y);
|
|
if (range==0 || ((pos - e->position).getLength2D() < range))
|
|
{
|
|
Vector add = pos - e->position;
|
|
add.setLength2D(velLen);
|
|
e->vel2 += add;
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getBoneLockEntity)
|
|
{
|
|
Entity *e = entity(L);
|
|
Entity *ent = NULL;
|
|
if (e)
|
|
{
|
|
BoneLock *b = e->getBoneLock();
|
|
ent = b->entity;
|
|
|
|
}
|
|
luaReturnPtr(ent);
|
|
}
|
|
|
|
luaFunc(entity_getBoneLockData)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (!e)
|
|
luaReturnNil();
|
|
BoneLock b = *e->getBoneLock(); // always safe to deref
|
|
|
|
lua_pushboolean(L, b.on);
|
|
luaPushPointer(L, b.bone);
|
|
lua_pushnumber(L, b.origRot);
|
|
lua_pushnumber(L, b.wallNormal.x);
|
|
lua_pushnumber(L, b.wallNormal.y);
|
|
lua_pushnumber(L, b.localOffset.x);
|
|
lua_pushnumber(L, b.localOffset.y);
|
|
return 7;
|
|
}
|
|
|
|
luaFunc(entity_ensureLimit)
|
|
{
|
|
Entity *e = entity(L);
|
|
dsq->game->ensureLimit(e, lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setRidingPosition)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->setRidingPosition(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setRidingData)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->setRidingData(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), lua_tonumber(L, 4), getBool(L, 5));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getRidingPosition)
|
|
{
|
|
Entity *e = entity(L);
|
|
Vector v;
|
|
if (e)
|
|
v = e->getRidingPosition();
|
|
luaReturnVec2(v.x, v.y);
|
|
}
|
|
|
|
luaFunc(entity_getRidingRotation)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnNum(e ? e->getRidingRotation() : 0.0f);
|
|
}
|
|
|
|
luaFunc(entity_getRidingFlip)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnBool(e && e->getRidingFlip());
|
|
}
|
|
|
|
|
|
luaFunc(entity_setBoneLock)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool ret = false;
|
|
if (e)
|
|
{
|
|
BoneLock bl;
|
|
if (lua_isuserdata(L, 2))
|
|
{
|
|
Entity *e2 = entity(L, 2);
|
|
Bone *b = 0;
|
|
if (lua_isuserdata(L, 3))
|
|
b = bone(L, 3);
|
|
|
|
bl.entity = e2;
|
|
bl.bone = b;
|
|
bl.on = true;
|
|
bl.collisionMaskIndex = dsq->game->lastCollideMaskIndex;
|
|
}
|
|
ret = e->setBoneLock(bl);
|
|
}
|
|
luaReturnBool(ret);
|
|
}
|
|
|
|
luaFunc(entity_setIngredient)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->setIngredientData(getString(L,2));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setSegsMaxDist)
|
|
{
|
|
ScriptedEntity *se = scriptedEntity(L);
|
|
if (se)
|
|
se->setMaxDist(lua_tonumber(L, 2));
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setBounceType)
|
|
{
|
|
Entity *e = entity(L);
|
|
int v = lua_tointeger(L, 2);
|
|
if (e)
|
|
{
|
|
e->setBounceType((BounceType)v);
|
|
}
|
|
luaReturnNum(v);
|
|
}
|
|
|
|
|
|
luaFunc(user_set_demo_intro)
|
|
{
|
|
#ifndef AQUARIA_DEMO
|
|
dsq->user.demo.intro = lua_tointeger(L, 1);
|
|
#endif
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(user_save)
|
|
{
|
|
dsq->user.save();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setAutoSkeletalUpdate)
|
|
{
|
|
ScriptedEntity *e = scriptedEntity(L);
|
|
bool v = getBool(L, 2);
|
|
if (e)
|
|
e->setAutoSkeletalUpdate(v);
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(entity_getBounceType)
|
|
{
|
|
Entity *e = entity(L);
|
|
BounceType bt=BOUNCE_SIMPLE;
|
|
if (e)
|
|
{
|
|
bt = (BounceType)e->getBounceType();
|
|
}
|
|
luaReturnInt((int)bt);
|
|
}
|
|
|
|
luaFunc(entity_setDieTimer)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->setDieTimer(lua_tonumber(L, 2));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setLookAtPoint)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->lookAtPoint = Vector(lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getLookAtPoint)
|
|
{
|
|
Entity *e = entity(L);
|
|
Vector pos;
|
|
if (e)
|
|
{
|
|
pos = e->getLookAtPoint();
|
|
}
|
|
luaReturnVec2(pos.x, pos.y);
|
|
}
|
|
|
|
luaFunc(entity_setRiding)
|
|
{
|
|
Entity *e = entity(L);
|
|
Entity *e2 = 0;
|
|
if (lua_touserdata(L, 2) != NULL)
|
|
e2 = entity(L, 2);
|
|
if (e)
|
|
{
|
|
e->setRiding(e2);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getHealthPerc)
|
|
{
|
|
Entity *e = entity(L);
|
|
float p = 0;
|
|
if (e)
|
|
{
|
|
p = e->getHealthPerc();
|
|
}
|
|
luaReturnNum(p);
|
|
}
|
|
|
|
luaFunc(entity_getRiding)
|
|
{
|
|
Entity *e = entity(L);
|
|
Entity *ret = 0;
|
|
if (e)
|
|
ret = e->getRiding();
|
|
luaReturnPtr(ret);
|
|
}
|
|
|
|
luaFunc(entity_setTargetPriority)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->targetPriority = lua_tonumber(L, 2);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getTargetPriority)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnInt(e ? e->targetPriority : 0);
|
|
}
|
|
|
|
// returns nil for non-scripted entities
|
|
luaFunc(entity_v)
|
|
{
|
|
ScriptedEntity *se = scriptedEntityOpt(L);
|
|
return se ? se->pushLuaVars(L) : 0;
|
|
}
|
|
|
|
luaFunc(node_v)
|
|
{
|
|
Path *n = path(L);
|
|
return n ? n->pushLuaVars(L) : 0;
|
|
}
|
|
|
|
luaFunc(isQuitFlag)
|
|
{
|
|
luaReturnBool(dsq->isQuitFlag());
|
|
}
|
|
|
|
luaFunc(isDeveloperKeys)
|
|
{
|
|
luaReturnBool(dsq->isDeveloperKeys());
|
|
}
|
|
|
|
luaFunc(isDemo)
|
|
{
|
|
#ifdef AQUARIA_DEMO
|
|
luaReturnBool(true);
|
|
#else
|
|
luaReturnBool(false);
|
|
#endif
|
|
}
|
|
|
|
luaFunc(isWithin)
|
|
{
|
|
Vector v1 = getVector(L, 1);
|
|
Vector v2 = getVector(L, 3);
|
|
float dist = lua_tonumber(L, 5);
|
|
|
|
Vector d = v2-v1;
|
|
bool v = false;
|
|
if (d.isLength2DIn(dist))
|
|
{
|
|
v = true;
|
|
}
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(toggleDamageSprite)
|
|
{
|
|
dsq->game->toggleDamageSprite(getBool(L));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(toggleCursor)
|
|
{
|
|
dsq->toggleCursor(getBool(L, 1), lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(toggleBlackBars)
|
|
{
|
|
dsq->toggleBlackBars(getBool(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setBlackBarsColor)
|
|
{
|
|
Vector c(lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
dsq->setBlackBarsColor(c);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(toggleLiCombat)
|
|
{
|
|
dsq->continuity.toggleLiCombat(getBool(L));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(getNoteName)
|
|
{
|
|
luaReturnStr(dsq->game->getNoteName(lua_tonumber(L, 1), getString(L, 2)).c_str());
|
|
}
|
|
|
|
luaFunc(getWorldType)
|
|
{
|
|
luaReturnNum((int)dsq->continuity.getWorldType());
|
|
}
|
|
|
|
luaFunc(setWorldType)
|
|
{
|
|
WorldType wt = (WorldType)lua_tointeger(L, 1);
|
|
bool trans = getBool(L, 2);
|
|
dsq->continuity.applyWorldEffects(wt, trans, 1); // last arg is not used
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(isWorldPaused)
|
|
{
|
|
luaReturnBool(dsq->game->isWorldPaused());
|
|
}
|
|
|
|
luaFunc(setWorldPaused)
|
|
{
|
|
dsq->game->setWorldPaused(getBool(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(getNearestNodeByType)
|
|
{
|
|
float x = lua_tonumber(L, 1);
|
|
float y = lua_tonumber(L, 2);
|
|
int type = lua_tointeger(L, 3);
|
|
|
|
luaReturnPtr(dsq->game->getNearestPath(Vector(x,y), (PathType)type));
|
|
}
|
|
|
|
luaFunc(fadeOutMusic)
|
|
{
|
|
dsq->sound->fadeMusic(SFT_OUT, lua_tonumber(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(getNode)
|
|
{
|
|
luaReturnPtr(pathFromName(L));
|
|
}
|
|
|
|
luaFunc(getNodeToActivate)
|
|
{
|
|
luaReturnPtr(dsq->game->avatar->pathToActivate);
|
|
}
|
|
|
|
luaFunc(setNodeToActivate)
|
|
{
|
|
dsq->game->avatar->pathToActivate = path(L, 1);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(getEntityToActivate)
|
|
{
|
|
luaReturnPtr(dsq->game->avatar->entityToActivate);
|
|
}
|
|
|
|
luaFunc(setEntityToActivate)
|
|
{
|
|
dsq->game->avatar->entityToActivate = entity(L, 1);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(hasThingToActivate)
|
|
{
|
|
luaReturnBool(dsq->game->avatar->hasThingToActivate());
|
|
}
|
|
|
|
luaFunc(setActivation)
|
|
{
|
|
dsq->game->activation = getBool(L, 1);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(debugLog)
|
|
{
|
|
const char *s = lua_tostring(L, 1);
|
|
if(s)
|
|
debugLog(s);
|
|
luaReturnStr(s);
|
|
}
|
|
|
|
luaFunc(errorLog)
|
|
{
|
|
const char *s = lua_tostring(L, 1);
|
|
if(s)
|
|
errorLog(s);
|
|
luaReturnStr(s);
|
|
}
|
|
|
|
luaFunc(reconstructGrid)
|
|
{
|
|
dsq->game->reconstructGrid(true);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(reconstructEntityGrid)
|
|
{
|
|
dsq->game->reconstructEntityGrid();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(dilateGrid)
|
|
{
|
|
unsigned int radius = lua_tointeger(L, 1);
|
|
ObsType test = (ObsType)lua_tointeger(L, 2);
|
|
ObsType set = (ObsType)lua_tointeger(L, 3);
|
|
ObsType allowOverwrite = (ObsType)lua_tointeger(L, 4);
|
|
dsq->game->dilateGrid(radius, test, set, allowOverwrite);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setCanLeaveWater)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool v = getBool(L, 2);
|
|
if (e)
|
|
{
|
|
e->setCanLeaveWater(v);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setSegmentTexture)
|
|
{
|
|
ScriptedEntity *e = scriptedEntity(L);
|
|
if (e)
|
|
{
|
|
RenderObject *ro = e->getSegment(lua_tonumber(L, 2));
|
|
if (ro)
|
|
{
|
|
ro->setTexture(getString(L, 3));
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_findNearestEntityOfType)
|
|
{
|
|
Entity *e = entity(L);
|
|
Entity *nearest = 0;
|
|
if (e)
|
|
{
|
|
EntityType et = (EntityType)lua_tointeger(L, 2);
|
|
int maxRange = lua_tointeger(L, 3);
|
|
float smallestDist = HUGE_VALF;
|
|
Entity *closest = 0;
|
|
FOR_ENTITIES(i)
|
|
{
|
|
Entity *ee = *i;
|
|
if (ee != e)
|
|
{
|
|
float dist = (ee->position - e->position).getSquaredLength2D();
|
|
if (ee->health > 0 && !ee->isEntityDead() && ee->getEntityType() == et && dist < smallestDist)
|
|
{
|
|
smallestDist = dist;
|
|
closest = ee;
|
|
}
|
|
}
|
|
}
|
|
if (maxRange == 0 || smallestDist <= sqr(maxRange))
|
|
{
|
|
nearest = closest;
|
|
}
|
|
}
|
|
luaReturnPtr(nearest);
|
|
}
|
|
|
|
luaFunc(createShot)
|
|
{
|
|
Entity *e = entity(L,2);
|
|
Entity *t = 0;
|
|
if (lua_touserdata(L, 3) != NULL)
|
|
t = entity(L,3);
|
|
Shot *s = 0;
|
|
Vector pos, aim;
|
|
pos.x = lua_tonumber(L, 4);
|
|
pos.y = lua_tonumber(L, 5);
|
|
aim.x = lua_tonumber(L, 6);
|
|
aim.y = lua_tonumber(L, 7);
|
|
|
|
|
|
s = dsq->game->fireShot(getString(L, 1), e, t, pos, aim);
|
|
|
|
luaReturnPtr(s);
|
|
}
|
|
|
|
luaFunc(isSkippingCutscene)
|
|
{
|
|
luaReturnBool(dsq->isSkippingCutscene());
|
|
}
|
|
|
|
// deprecated, use entity_playSfx
|
|
luaFunc(entity_sound)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e && !dsq->isSkippingCutscene())
|
|
{
|
|
float freq = lua_tonumber(L, 3);
|
|
// HACK: most old scripts still use a freq value of ~1000 as normal pitch.
|
|
// Pitch values this high produce a barely audible click only,
|
|
// so a cheap hack like this fixes it without changing older scripts. -- FG
|
|
if (freq >= 100)
|
|
freq *= 0.001f;
|
|
e->sound(getString(L, 2), freq, lua_tonumber(L, 4));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_playSfx)
|
|
{
|
|
Entity *e = entity(L);
|
|
void *h = NULL;
|
|
if (e && !dsq->isSkippingCutscene())
|
|
{
|
|
PlaySfx sfx;
|
|
sfx.name = getString(L, 2);
|
|
sfx.freq = lua_tonumber(L, 3);
|
|
sfx.vol = lua_tonumber(L, 4);
|
|
if(sfx.vol <= 0)
|
|
sfx.vol = 1;
|
|
sfx.loops = lua_tonumber(L, 5);
|
|
|
|
float fadeOut = lua_tonumber(L, 6);
|
|
sfx.maxdist = lua_tonumber(L, 7);
|
|
sfx.relative = false;
|
|
sfx.positional = true;
|
|
Vector pos = e->position + e->offset;
|
|
sfx.x = pos.x;
|
|
sfx.y = pos.y;
|
|
|
|
h = core->sound->playSfx(sfx);
|
|
if (fadeOut != 0)
|
|
{
|
|
sound->fadeSfx(h, SFT_OUT, fadeOut);
|
|
}
|
|
|
|
e->linkSound(h);
|
|
e->updateSoundPosition();
|
|
}
|
|
luaReturnPtr(h);
|
|
}
|
|
|
|
luaFunc(entity_setStopSoundsOnDeath)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->setStopSoundsOnDeath(getBool(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setSpiritFreeze)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->setSpiritFreeze(getBool(L,2));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setPauseFreeze)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->setPauseFreeze(getBool(L,2));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(node_setSpiritFreeze)
|
|
{
|
|
Path *e = path(L);
|
|
if (e)
|
|
e->spiritFreeze = getBool(L,2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(node_setPauseFreeze)
|
|
{
|
|
Path *e = path(L);
|
|
if (e)
|
|
e->pauseFreeze = getBool(L,2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setFillGrid)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool b = getBool(L,2);
|
|
if (e)
|
|
{
|
|
e->fillGridFromQuad = b;
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_isFillGrid)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnBool(e ? e->fillGridFromQuad : false);
|
|
}
|
|
|
|
luaFunc(entity_getAimVector)
|
|
{
|
|
Entity *e = entity(L);
|
|
Vector aim;
|
|
float adjust = lua_tonumber(L, 2);
|
|
float len = lua_tonumber(L, 3);
|
|
bool flip = getBool(L, 4);
|
|
if (e)
|
|
{
|
|
float a = e->rotation.z;
|
|
if (!flip)
|
|
a += adjust;
|
|
else
|
|
{
|
|
if (e->isfh())
|
|
{
|
|
a -= adjust;
|
|
}
|
|
else
|
|
{
|
|
a += adjust;
|
|
}
|
|
}
|
|
a = MathFunctions::toRadians(a);
|
|
aim = Vector(sinf(a)*len, cosf(a)*len);
|
|
}
|
|
luaReturnVec2(aim.x, aim.y);
|
|
}
|
|
|
|
luaFunc(entity_getVectorToEntity)
|
|
{
|
|
typecheckOnly(entity(L));
|
|
typecheckOnly(entity(L, 2));
|
|
return forwardCall(obj_getVectorToObj);
|
|
}
|
|
|
|
luaFunc(entity_setDropChance)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->dropChance = lua_tonumber(L, 2);
|
|
float amount = lua_tonumber(L, 3);
|
|
ScriptedEntity *se = dynamic_cast<ScriptedEntity*>(e);
|
|
if (se && amount)
|
|
{
|
|
se->manaBallAmount = amount;
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_warpToNode)
|
|
{
|
|
Entity *e = entity(L);
|
|
Path *p = path(L, 2);
|
|
if (e && p)
|
|
{
|
|
e->position.stopPath();
|
|
e->position = p->nodes[0].position;
|
|
e->rotateToVec(Vector(0,-1), 0.1f);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_stopPull)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->stopPull();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_moveToNode)
|
|
{
|
|
Entity *e = entity(L);
|
|
Path *p = path(L, 2);
|
|
float time = 0;
|
|
if (e && p)
|
|
{
|
|
float speed = dsq->continuity.getSpeedType(lua_tointeger(L, 3));
|
|
time = e->moveToPos(p->nodes[0].position, speed, lua_tointeger(L, 4), 0);
|
|
}
|
|
luaReturnNum(time);
|
|
}
|
|
|
|
luaFunc(entity_swimToNode)
|
|
{
|
|
Entity *e = entity(L);
|
|
Path *p = path(L, 2);
|
|
float time = 0;
|
|
if (e && p)
|
|
{
|
|
float speed = dsq->continuity.getSpeedType(lua_tointeger(L, 3));
|
|
time = e->moveToPos(p->nodes[0].position, speed, lua_tointeger(L, 4), 1);
|
|
}
|
|
luaReturnNum(time);
|
|
}
|
|
|
|
luaFunc(entity_swimToPosition)
|
|
{
|
|
Entity *e = entity(L);
|
|
float time = 0;
|
|
if (e)
|
|
{
|
|
float speed = dsq->continuity.getSpeedType(lua_tointeger(L, 4));
|
|
time = e->moveToPos(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), speed, lua_tointeger(L, 5), 1);
|
|
}
|
|
luaReturnNum(time);
|
|
}
|
|
|
|
luaFunc(entity_moveToNodeSpeed)
|
|
{
|
|
Entity *e = entity(L);
|
|
Path *p = path(L, 2);
|
|
float time = 0;
|
|
if (e && p)
|
|
time = e->moveToPos(p->nodes[0].position, lua_tonumber(L, 3), lua_tointeger(L, 4), 0);
|
|
luaReturnNum(time);
|
|
}
|
|
|
|
luaFunc(entity_swimToNodeSpeed)
|
|
{
|
|
Entity *e = entity(L);
|
|
Path *p = path(L, 2);
|
|
float time = 0;
|
|
if (e && p)
|
|
time = e->moveToPos(p->nodes[0].position, lua_tonumber(L, 3), lua_tointeger(L, 4), 1);
|
|
luaReturnNum(time);
|
|
}
|
|
|
|
luaFunc(entity_swimToPositionSpeed)
|
|
{
|
|
Entity *e = entity(L);
|
|
float time = 0;
|
|
if (e)
|
|
time = e->moveToPos(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), lua_tonumber(L, 4), lua_tointeger(L, 5), 1);
|
|
luaReturnNum(time);
|
|
}
|
|
|
|
|
|
luaFunc(avatar_setCanDie)
|
|
{
|
|
dsq->game->avatar->canDie = getBool(L, 1);
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
// not naming this avatar_* because it rather belongs into the UI category...
|
|
luaFunc(setCanActivate)
|
|
{
|
|
dsq->game->avatar->setCanActivateStuff(getBool(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setSeeMapMode)
|
|
{
|
|
dsq->game->avatar->setSeeMapMode((SeeMapMode)lua_tointeger(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(avatar_setCanBurst)
|
|
{
|
|
dsq->game->avatar->setCanBurst(getBool(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(avatar_canBurst)
|
|
{
|
|
luaReturnBool(dsq->game->avatar->canBurst());
|
|
}
|
|
|
|
luaFunc(avatar_setCanLockToWall)
|
|
{
|
|
dsq->game->avatar->setCanLockToWall(getBool(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(avatar_canLockToWall)
|
|
{
|
|
luaReturnBool(dsq->game->avatar->canLockToWall());
|
|
}
|
|
|
|
luaFunc(avatar_setCanSwimAgainstCurrents)
|
|
{
|
|
dsq->game->avatar->setCanSwimAgainstCurrents(getBool(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(avatar_canSwimAgainstCurrents)
|
|
{
|
|
luaReturnBool(dsq->game->avatar->canSwimAgainstCurrents());
|
|
}
|
|
|
|
luaFunc(avatar_setCanCollideWithShots)
|
|
{
|
|
dsq->game->avatar->setCollideWithShots(getBool(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(avatar_canCollideWithShots)
|
|
{
|
|
luaReturnBool(dsq->game->avatar->canCollideWithShots());
|
|
}
|
|
|
|
luaFunc(avatar_setCollisionAvoidanceData)
|
|
{
|
|
dsq->game->avatar->setCollisionAvoidanceData(lua_tointeger(L, 1), lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(avatar_toggleCape)
|
|
{
|
|
dsq->game->avatar->toggleCape(getBool(L,1));
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(avatar_setBlockSinging)
|
|
{
|
|
bool b = getBool(L);
|
|
dsq->game->avatar->setBlockSinging(b);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(avatar_isBlockSinging)
|
|
{
|
|
luaReturnBool(dsq->game->avatar->isBlockSinging());
|
|
}
|
|
|
|
luaFunc(avatar_setBlockBackflip)
|
|
{
|
|
dsq->game->avatar->blockBackFlip = getBool(L);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(avatar_isBlockBackflip)
|
|
{
|
|
dsq->game->avatar->blockBackFlip = getBool(L);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(avatar_fallOffWall)
|
|
{
|
|
dsq->game->avatar->fallOffWall();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(avatar_isBursting)
|
|
{
|
|
luaReturnBool(dsq->game->avatar->bursting);
|
|
}
|
|
|
|
luaFunc(avatar_isLockable)
|
|
{
|
|
luaReturnBool(dsq->game->avatar->isLockable());
|
|
}
|
|
|
|
luaFunc(avatar_isRolling)
|
|
{
|
|
luaReturnBool(dsq->game->avatar->isRolling());
|
|
}
|
|
|
|
luaFunc(avatar_isSwimming)
|
|
{
|
|
luaReturnBool(dsq->game->avatar->isSwimming());
|
|
}
|
|
|
|
luaFunc(avatar_isOnWall)
|
|
{
|
|
bool v = dsq->game->avatar->state.lockedToWall;
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(avatar_isShieldActive)
|
|
{
|
|
bool v = (dsq->game->avatar->activeAura == AURA_SHIELD);
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(avatar_setShieldActive)
|
|
{
|
|
bool on = getBool(L, 1);
|
|
if (on)
|
|
dsq->game->avatar->activateAura(AURA_SHIELD);
|
|
else
|
|
dsq->game->avatar->stopAura();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(avatar_getStillTimer)
|
|
{
|
|
luaReturnNum(dsq->game->avatar->stillTimer.getValue());
|
|
}
|
|
|
|
luaFunc(avatar_getRollDirection)
|
|
{
|
|
int v = 0;
|
|
if (dsq->game->avatar->isRolling())
|
|
v = dsq->game->avatar->rollDir;
|
|
luaReturnNum(v);
|
|
}
|
|
|
|
luaFunc(avatar_getSpellCharge)
|
|
{
|
|
luaReturnNum(dsq->game->avatar->state.spellCharge);
|
|
}
|
|
|
|
luaFunc(avatar_setSpeedMult)
|
|
{
|
|
dsq->continuity.setSpeedMultiplier(lua_tonumber(L, 1), lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(avatar_setSpeedMult2)
|
|
{
|
|
dsq->continuity.speedMult2 = lua_tonumber(L, 1);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(avatar_getSpeedMult)
|
|
{
|
|
luaReturnNum(dsq->continuity.speedMult);
|
|
}
|
|
|
|
luaFunc(avatar_getSpeedMult2)
|
|
{
|
|
luaReturnNum(dsq->continuity.speedMult2);
|
|
}
|
|
|
|
luaFunc(jumpState)
|
|
{
|
|
dsq->enqueueJumpState(getString(L, 1), getBool(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(goToTitle)
|
|
{
|
|
dsq->title();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(getEnqueuedState)
|
|
{
|
|
luaReturnStr(dsq->getEnqueuedJumpState().c_str());
|
|
}
|
|
|
|
luaFunc(learnSong)
|
|
{
|
|
dsq->continuity.learnSong(lua_tointeger(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(unlearnSong)
|
|
{
|
|
dsq->continuity.unlearnSong(lua_tointeger(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(showInGameMenu)
|
|
{
|
|
dsq->game->getInGameMenu()->show(getBool(L, 1), getBool(L, 2), (MenuPage)lua_tointeger(L, 3));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(hideInGameMenu)
|
|
{
|
|
bool skipEffect = getBool(L, 1);
|
|
bool cancel = getBool(L, 2);
|
|
dsq->game->getInGameMenu()->hide(!skipEffect, cancel);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(showImage)
|
|
{
|
|
dsq->game->showImage(getString(L));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(hideImage)
|
|
{
|
|
dsq->game->hideImage();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(hasSong)
|
|
{
|
|
bool b = dsq->continuity.hasSong(lua_tointeger(L, 1));
|
|
luaReturnBool(b);
|
|
}
|
|
|
|
luaFunc(loadSound)
|
|
{
|
|
void *handle = core->sound->loadLocalSound(getString(L, 1));
|
|
luaReturnPtr(handle);
|
|
}
|
|
|
|
luaFunc(loadMap)
|
|
{
|
|
std::string s = getString(L, 1);
|
|
std::string n = getString(L, 2);
|
|
|
|
if (!s.empty())
|
|
{
|
|
if (!n.empty())
|
|
{
|
|
if (dsq->game->avatar)
|
|
dsq->game->avatar->disableInput();
|
|
dsq->game->warpToSceneNode(s, n);
|
|
}
|
|
else
|
|
{
|
|
if (dsq->game->avatar)
|
|
dsq->game->avatar->disableInput();
|
|
dsq->game->transitionToScene(s);
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_followPath)
|
|
{
|
|
Entity *e = entity(L);
|
|
float time = 0;
|
|
if (e)
|
|
{
|
|
Path *p = path(L, 2);
|
|
int speedType = lua_tointeger(L, 3);
|
|
int dir = lua_tointeger(L, 4);
|
|
float speed = dsq->continuity.getSpeedType(speedType);
|
|
time = e->followPath(p, speed, dir);
|
|
}
|
|
luaReturnNum(time);
|
|
}
|
|
|
|
luaFunc(entity_followPathSpeed)
|
|
{
|
|
Entity *e = entity(L);
|
|
float time = 0;
|
|
if (e)
|
|
{
|
|
Path *p = path(L, 2);
|
|
float speed = lua_tonumber(L, 3);
|
|
int dir = lua_tointeger(L, 4);
|
|
time = e->followPath(p, speed, dir);
|
|
}
|
|
luaReturnNum(time);
|
|
}
|
|
|
|
luaFunc(spawnIngredient)
|
|
{
|
|
int times = lua_tointeger(L, 4);
|
|
if (times == 0) times = 1;
|
|
bool out = getBool(L, 5);
|
|
Entity *e = dsq->game->spawnIngredient(getString(L, 1), Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), times, out);
|
|
|
|
luaReturnPtr(e);
|
|
}
|
|
|
|
luaFunc(getNearestIngredient)
|
|
{
|
|
Ingredient *i = dsq->game->getNearestIngredient(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)), lua_tonumber(L, 3));
|
|
luaReturnPtr(i);
|
|
}
|
|
|
|
luaFunc(spawnAllIngredients)
|
|
{
|
|
dsq->spawnAllIngredients(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(spawnParticleEffect)
|
|
{
|
|
float t = lua_tonumber(L, 4);
|
|
// having t and rot reversed compared to the DSQ function is intentional
|
|
float rot = lua_tonumber(L, 5);
|
|
int layer = lua_tointeger(L, 6);
|
|
if (!layer)
|
|
layer = LR_PARTICLES;
|
|
float follow = lua_tonumber(L, 7);
|
|
ParticleEffect *pe = dsq->spawnParticleEffect(getString(L, 1), Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)),
|
|
rot, t, layer, follow);
|
|
luaReturnPtr(pe);
|
|
}
|
|
|
|
luaFunc(setNumSuckPositions)
|
|
{
|
|
particleManager->setNumSuckPositions(lua_tointeger(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setSuckPosition)
|
|
{
|
|
particleManager->setSuckPosition(lua_tointeger(L, 1), Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(getSuckPosition)
|
|
{
|
|
Vector *v = particleManager->getSuckPosition(lua_tointeger(L, 1));
|
|
if(v)
|
|
luaReturnVec2(v->x, v->y);
|
|
luaReturnVec2(0.0f, 0.0f);
|
|
}
|
|
|
|
|
|
luaFunc(bone_showFrame)
|
|
{
|
|
Bone *b = bone(L);
|
|
if (b)
|
|
b->showFrame(lua_tointeger(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(bone_setSegmentOffset)
|
|
{
|
|
Bone *b = bone(L);
|
|
if (b)
|
|
b->segmentOffset = Vector(lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(bone_setSegmentProps)
|
|
{
|
|
Bone *b = bone(L);
|
|
if (b)
|
|
{
|
|
b->setSegmentProps(lua_tonumber(L, 2), lua_tonumber(L, 3), getBool(L, 4));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(bone_setSegmentChainHead)
|
|
{
|
|
Bone *b = bone(L);
|
|
if (b)
|
|
{
|
|
if (getBool(L, 2))
|
|
b->segmentChain = 1;
|
|
else
|
|
b->segmentChain = 0;
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(bone_addSegment)
|
|
{
|
|
Bone *b = bone(L);
|
|
Bone *b2 = bone(L, 2);
|
|
if (b && b2)
|
|
b->addSegment(b2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(bone_setAnimated)
|
|
{
|
|
Bone *b = bone(L);
|
|
if (b)
|
|
{
|
|
b->setAnimated(lua_tointeger(L, 2));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(bone_lookAtEntity)
|
|
{
|
|
Bone *b = bone(L);
|
|
Entity *e = entity(L, 2);
|
|
if (b && e)
|
|
{
|
|
Vector pos = e->position;
|
|
if (e->getEntityType() == ET_AVATAR)
|
|
{
|
|
pos = e->skeletalSprite.getBoneByIdx(1)->getWorldPosition();
|
|
}
|
|
b->lookAt(pos, lua_tonumber(L, 3), lua_tonumber(L, 4),lua_tonumber(L, 5), lua_tonumber(L, 6));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(bone_lookAtPosition)
|
|
{
|
|
Bone *b = bone(L);
|
|
if (b)
|
|
{
|
|
b->lookAt(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6), lua_tonumber(L, 7));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_stopFollowingPath)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
if (e->isFollowingPath())
|
|
{
|
|
e->stopFollowingPath();
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_slowToStopPath)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
if (e->isFollowingPath())
|
|
{
|
|
debugLog("calling slow to stop path");
|
|
e->slowToStopPath(lua_tonumber(L, 2));
|
|
}
|
|
else
|
|
{
|
|
debugLog("wasn't following path");
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_createEntity)
|
|
{
|
|
Entity *e = entity(L);
|
|
Entity *ret = NULL;
|
|
if (e)
|
|
ret = dsq->game->createEntity(dsq->getEntityTypeIndexByName(getString(L, 2)), 0, e->position, 0, false, "", ET_ENEMY, true);
|
|
luaReturnPtr(ret);
|
|
}
|
|
|
|
luaFunc(entity_checkSplash)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool ret = false;
|
|
float x = lua_tonumber(L, 2);
|
|
float y = lua_tonumber(L, 3);
|
|
if (e)
|
|
ret = e->checkSplash(Vector(x,y));
|
|
luaReturnBool(ret);
|
|
}
|
|
|
|
luaFunc(entity_isInCurrent)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnBool(e ? e->isInCurrent() : false);
|
|
}
|
|
|
|
luaFunc(entity_isUnderWater)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool b = false;
|
|
if (e)
|
|
{
|
|
b = e->isUnderWater(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)));
|
|
}
|
|
luaReturnBool(b);
|
|
}
|
|
|
|
luaFunc(entity_isBeingPulled)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool v= false;
|
|
if (e)
|
|
v = (dsq->game->avatar->pullTarget == e);
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(avatar_setPullTarget)
|
|
{
|
|
Entity *e = 0;
|
|
if (lua_isuserdata(L, 1))
|
|
e = entity(L, 1);
|
|
|
|
if (dsq->game->avatar->pullTarget != 0)
|
|
dsq->game->avatar->pullTarget->stopPull();
|
|
|
|
dsq->game->avatar->pullTarget = e;
|
|
|
|
if (e)
|
|
e->startPull();
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_isDead)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool v= false;
|
|
if (e)
|
|
{
|
|
v = e->isEntityDead();
|
|
}
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
|
|
luaFunc(getLastCollidePosition)
|
|
{
|
|
luaReturnVec2(dsq->game->lastCollidePosition.x, dsq->game->lastCollidePosition.y);
|
|
}
|
|
|
|
luaFunc(getLastCollideTileType)
|
|
{
|
|
luaReturnInt(dsq->game->lastCollideTileType);
|
|
}
|
|
|
|
luaFunc(collideCircleWithGrid)
|
|
{
|
|
bool c = dsq->game->collideCircleWithGrid(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)), lua_tonumber(L, 3));
|
|
luaReturnBool(c);
|
|
}
|
|
|
|
|
|
luaFunc(entity_isNearGround)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool value = false;
|
|
if (e)
|
|
{
|
|
int sampleArea = lua_tointeger(L, 2);
|
|
Vector v = dsq->game->getWallNormal(e->position, sampleArea);
|
|
if (!v.isZero())
|
|
{
|
|
|
|
if (v.y < 0 && fabsf(v.x) < 0.6f)
|
|
{
|
|
value = true;
|
|
}
|
|
}
|
|
|
|
}
|
|
luaReturnBool(value);
|
|
}
|
|
|
|
luaFunc(entity_isHit)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool v = false;
|
|
if (e)
|
|
v = e->isHit();
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(entity_waitForPath)
|
|
{
|
|
Entity *e = entity(L);
|
|
while (e && e->isFollowingPath())
|
|
{
|
|
core->run(FRAME_TIME);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(quitNestedMain)
|
|
{
|
|
core->quitNestedMain();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(isNestedMain)
|
|
{
|
|
luaReturnBool(core->isNested());
|
|
}
|
|
|
|
luaFunc(entity_watchForPath)
|
|
{
|
|
dsq->game->avatar->disableInput();
|
|
|
|
Entity *e = entity(L);
|
|
while (e && e->isFollowingPath())
|
|
{
|
|
core->run(FRAME_TIME);
|
|
}
|
|
|
|
dsq->game->avatar->enableInput();
|
|
luaReturnNil();
|
|
}
|
|
|
|
|
|
luaFunc(watchForVoice)
|
|
{
|
|
int quit = lua_tointeger(L, 1);
|
|
while (dsq->sound->isPlayingVoice())
|
|
{
|
|
dsq->watch(FRAME_TIME, quit);
|
|
if (quit && dsq->isQuitFlag())
|
|
{
|
|
dsq->sound->stopVoice();
|
|
break;
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
|
|
luaFunc(entity_isSlowingToStopPath)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool v = false;
|
|
if (e)
|
|
{
|
|
v = e->isSlowingToStopPath();
|
|
}
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(entity_resumePath)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->position.resumePath();
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_isAnimating)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool v= false;
|
|
if (e)
|
|
{
|
|
v = e->skeletalSprite.isAnimating(lua_tonumber(L, 2));
|
|
}
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
|
|
luaFunc(entity_getAnimationName)
|
|
{
|
|
Entity *e = entity(L);
|
|
const char *ret = "";
|
|
int layer = lua_tointeger(L, 2);
|
|
if (e)
|
|
{
|
|
if (Animation *anim = e->skeletalSprite.getCurrentAnimation(layer))
|
|
{
|
|
ret = anim->name.c_str();
|
|
}
|
|
}
|
|
luaReturnStr(ret);
|
|
}
|
|
|
|
luaFunc(entity_getAnimationLength)
|
|
{
|
|
Entity *e = entity(L);
|
|
float ret=0;
|
|
if (e)
|
|
{
|
|
Animation *anim = 0;
|
|
if (lua_isstring(L, 2))
|
|
anim = e->skeletalSprite.getAnimation(lua_tostring(L, 2));
|
|
else
|
|
{
|
|
int layer = lua_tointeger(L, 2);
|
|
anim = e->skeletalSprite.getCurrentAnimation(layer);
|
|
}
|
|
if (anim)
|
|
ret = anim->getAnimationLength();
|
|
}
|
|
luaReturnNum(ret);
|
|
}
|
|
|
|
luaFunc(entity_hasAnimation)
|
|
{
|
|
Entity *e = entity(L);
|
|
Animation *anim = e->skeletalSprite.getAnimation(getString(L, 2));
|
|
luaReturnBool(anim != NULL);
|
|
}
|
|
|
|
luaFunc(entity_isFollowingPath)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
luaReturnBool(e->isFollowingPath());
|
|
else
|
|
luaReturnBool(false);
|
|
}
|
|
|
|
luaFunc(entity_toggleBone)
|
|
{
|
|
Entity *e = entity(L);
|
|
Bone *b = bone(L, 2);
|
|
if (e && b)
|
|
{
|
|
e->skeletalSprite.toggleBone(e->skeletalSprite.getBoneIdx(b), lua_tonumber(L, 3));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setEntityType)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->setEntityType(EntityType(lua_tointeger(L, 2)));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getEntityType)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
luaReturnInt(int(e->getEntityType()));
|
|
else
|
|
luaReturnInt(0);
|
|
}
|
|
|
|
luaFunc(cam_snap)
|
|
{
|
|
dsq->game->snapCam();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(cam_toNode)
|
|
{
|
|
Path *p = path(L);
|
|
if (p)
|
|
{
|
|
dsq->game->setCameraFollow(&p->nodes[0].position);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(cam_toEntity)
|
|
{
|
|
if (lua_touserdata(L, 1) == NULL)
|
|
{
|
|
Vector *pos = 0;
|
|
dsq->game->setCameraFollow(pos);
|
|
}
|
|
else
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
dsq->game->setCameraFollowEntity(e);
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(cam_setPosition)
|
|
{
|
|
float x = lua_tonumber(L, 1);
|
|
float y = lua_tonumber(L, 2);
|
|
float time = lua_tonumber(L, 3);
|
|
int loopType = lua_tointeger(L, 4);
|
|
bool pingPong = getBool(L, 5);
|
|
bool ease = getBool(L, 6);
|
|
|
|
Vector p(x,y);
|
|
|
|
dsq->game->cameraInterp.stop();
|
|
dsq->game->cameraInterp.interpolateTo(p, time, loopType, pingPong, ease);
|
|
|
|
dsq->cameraPos = dsq->game->getCameraPositionFor(dsq->game->cameraInterp);
|
|
luaReturnNil();
|
|
}
|
|
|
|
|
|
luaFunc(entity_spawnParticlesFromCollisionMask)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
int intv = lua_tointeger(L, 3);
|
|
if (intv <= 0)
|
|
intv = 1;
|
|
e->spawnParticlesFromCollisionMask(getString(L, 2), intv);
|
|
}
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_initEmitter)
|
|
{
|
|
ScriptedEntity *se = scriptedEntity(L);
|
|
int e = lua_tointeger(L, 2);
|
|
std::string pfile = getString(L, 3);
|
|
if (se)
|
|
{
|
|
se->initEmitter(e, pfile);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_startEmitter)
|
|
{
|
|
ScriptedEntity *se = scriptedEntity(L);
|
|
int e = lua_tointeger(L, 2);
|
|
if (se)
|
|
{
|
|
se->startEmitter(e);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_stopEmitter)
|
|
{
|
|
ScriptedEntity *se = scriptedEntity(L);
|
|
int e = lua_tointeger(L, 2);
|
|
if (se)
|
|
{
|
|
se->stopEmitter(e);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getEmitter)
|
|
{
|
|
ScriptedEntity *se = scriptedEntity(L);
|
|
luaReturnPtr(se ? se->getEmitter(lua_tointeger(L, 2)) : NULL);
|
|
}
|
|
|
|
luaFunc(entity_getNumEmitters)
|
|
{
|
|
ScriptedEntity *se = scriptedEntity(L);
|
|
luaReturnInt(se ? se->getNumEmitters() : 0);
|
|
}
|
|
|
|
luaFunc(entity_initStrands)
|
|
{
|
|
ScriptedEntity *e = scriptedEntity(L);
|
|
if (e)
|
|
{
|
|
e->initStrands(lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), Vector(lua_tonumber(L, 6), lua_tonumber(L, 7), lua_tonumber(L, 8)));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_initSkeletal)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->renderQuad = false;
|
|
e->setWidthHeight(128, 128);
|
|
e->skeletalSprite.loadSkeletal(getString(L, 2));
|
|
const char *s = lua_tostring(L, 3);
|
|
if (s && *s)
|
|
e->skeletalSprite.loadSkin(s);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_loadSkin)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e && e->skeletalSprite.isLoaded())
|
|
{
|
|
const char *s = lua_tostring(L, 2);
|
|
if (s && *s)
|
|
e->skeletalSprite.loadSkin(s);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getSkeletalName)
|
|
{
|
|
Entity *e = entity(L);
|
|
const char *s = "";
|
|
if (e && e->skeletalSprite.isLoaded())
|
|
s = e->skeletalSprite.filenameLoaded.c_str();
|
|
luaReturnStr(s);
|
|
}
|
|
|
|
luaFunc(entity_hasSkeletal)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnBool(e && e->skeletalSprite.isLoaded());
|
|
}
|
|
|
|
luaFunc(entity_getNumAnimLayers)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnInt(e ? e->skeletalSprite.getNumAnimLayers() : 0);
|
|
}
|
|
|
|
luaFunc(entity_idle)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->idle();
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_stopAllAnimations)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->skeletalSprite.stopAllAnimations();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setAnimLayerTimeMult)
|
|
{
|
|
Entity *e = entity(L);
|
|
int layer = 0;
|
|
float t = 0;
|
|
if (e)
|
|
{
|
|
layer = lua_tointeger(L, 2);
|
|
t = lua_tonumber(L, 3);
|
|
AnimationLayer *l = e->skeletalSprite.getAnimationLayer(layer);
|
|
if (l)
|
|
{
|
|
interpolateVec1(L, l->timeMultiplier, 3);
|
|
}
|
|
}
|
|
luaReturnNum(t);
|
|
}
|
|
|
|
luaFunc(entity_getAnimLayerTimeMult)
|
|
{
|
|
Entity *e = entity(L);
|
|
float t = 0;
|
|
if (e)
|
|
{
|
|
AnimationLayer *l = e->skeletalSprite.getAnimationLayer(lua_tointeger(L, 2));
|
|
if (l)
|
|
{
|
|
t = l->timeMultiplier.x;
|
|
}
|
|
}
|
|
luaReturnNum(t);
|
|
}
|
|
|
|
luaFunc(entity_animate)
|
|
{
|
|
SkeletalSprite *skel = getSkeletalSprite(entity(L));
|
|
float ret = 0;
|
|
if (skel)
|
|
{
|
|
float transition = lua_tonumber(L, 5);
|
|
if (transition == -1)
|
|
transition = 0;
|
|
else if (transition == 0)
|
|
transition = 0.2f;
|
|
ret = skel->transitionAnimate(getString(L, 2), transition, lua_tointeger(L, 3), lua_tointeger(L, 4));
|
|
}
|
|
luaReturnNum(ret);
|
|
}
|
|
|
|
luaFunc(entity_stopAnimation)
|
|
{
|
|
SkeletalSprite *skel = getSkeletalSprite(entity(L));
|
|
if (skel)
|
|
{
|
|
AnimationLayer *animlayer = skel->getAnimationLayer(lua_tointeger(L, 2));
|
|
if (animlayer)
|
|
animlayer->stopAnimation();
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getAnimationLoop)
|
|
{
|
|
int loop = 0;
|
|
SkeletalSprite *skel = getSkeletalSprite(entity(L));
|
|
if (skel)
|
|
{
|
|
AnimationLayer *animlayer = skel->getAnimationLayer(lua_tointeger(L, 2));
|
|
if (animlayer)
|
|
loop = animlayer->loop ? animlayer->loop : animlayer->enqueuedAnimationLoop;
|
|
}
|
|
luaReturnInt(loop);
|
|
}
|
|
|
|
// entity, x, y, time, ease, relative
|
|
luaFunc(entity_move)
|
|
{
|
|
Entity *e = entity(L);
|
|
//bool ease = lua_tointeger(L, 5);
|
|
Vector p(lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
if (getBool(L, 6))
|
|
p = e->position + p;
|
|
|
|
e->position.interpolateTo(p, lua_tonumber(L, 4), 0, 0, getBool(L, 5));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(spawnManaBall)
|
|
{
|
|
Vector p;
|
|
p.x = lua_tonumber(L, 1);
|
|
p.y = lua_tonumber(L, 2);
|
|
float amount = lua_tonumber(L, 3);
|
|
dsq->game->spawnManaBall(p, amount);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(spawnAroundEntity)
|
|
{
|
|
Entity *e = entity(L);
|
|
int num = lua_tointeger(L, 2);
|
|
float radius = lua_tonumber(L, 3);
|
|
std::string entType = getString(L, 4);
|
|
std::string name = getString(L, 5);
|
|
int idx = dsq->game->getIdxForEntityType(entType);
|
|
if (e)
|
|
{
|
|
Vector pos = e->position;
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
float angle = i*((2*PI)/float(num));
|
|
|
|
e = dsq->game->createEntity(idx, 0, pos + Vector(sinf(angle)*radius, cosf(angle)*radius), 0, false, name);
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(createBeam)
|
|
{
|
|
int x = lua_tointeger(L, 1);
|
|
int y = lua_tointeger(L, 2);
|
|
float a = lua_tonumber(L, 3);
|
|
int l = lua_tointeger(L, 4);
|
|
Beam *b = new Beam(Vector(x,y), a);
|
|
if (l == 1)
|
|
dsq->game->addRenderObject(b, LR_PARTICLES);
|
|
else
|
|
dsq->game->addRenderObject(b, LR_ENTITIES_MINUS2);
|
|
luaReturnPtr(b);
|
|
}
|
|
|
|
luaFunc(beam_setDamage)
|
|
{
|
|
Beam *b = beam(L);
|
|
if (b)
|
|
{
|
|
b->setDamage(lua_tonumber(L, 2));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(beam_setDamageType)
|
|
{
|
|
Beam *b = beam(L);
|
|
if (b)
|
|
{
|
|
b->damageData.damageType = (DamageType)lua_tointeger(L, 2);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(beam_setBeamWidth)
|
|
{
|
|
Beam *b = beam(L);
|
|
if (b)
|
|
{
|
|
b->setBeamWidth(lua_tonumber(L, 2));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(beam_setAngle)
|
|
{
|
|
Beam *b = beam(L);
|
|
if (b)
|
|
{
|
|
b->angle = lua_tonumber(L, 2);
|
|
b->trace();
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(beam_setFirer)
|
|
{
|
|
Beam *b = beam(L);
|
|
if (b)
|
|
b->setFirer(entity(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
// Note the additional trace() call
|
|
luaFunc(beam_setPosition_override)
|
|
{
|
|
Beam *b = beam(L);
|
|
if (b)
|
|
{
|
|
forwardCall(obj_setPosition);
|
|
b->trace();
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(beam_getEndPos)
|
|
{
|
|
Beam *b = beam(L);
|
|
Vector v;
|
|
if (b)
|
|
v = b->endPos;
|
|
luaReturnVec2(v.x, v.y);
|
|
}
|
|
|
|
luaFunc(getStringBank)
|
|
{
|
|
luaReturnStr(dsq->continuity.stringBank.get(lua_tointeger(L, 1)).c_str());
|
|
}
|
|
|
|
luaFunc(isPlat)
|
|
{
|
|
int plat = lua_tointeger(L, 1);
|
|
bool v = false;
|
|
#ifdef BBGE_BUILD_WINDOWS
|
|
v = (plat == 0);
|
|
#elif BBGE_BUILD_MACOSX
|
|
v = (plat == 1);
|
|
#elif BBGE_BUILD_UNIX
|
|
v = (plat == 2);
|
|
#endif
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(createEntity)
|
|
{
|
|
std::string type = getString(L, 1);
|
|
std::string name;
|
|
if (lua_isstring(L, 2))
|
|
name = lua_tostring(L, 2);
|
|
int x = lua_tointeger(L, 3);
|
|
int y = lua_tointeger(L, 4);
|
|
|
|
Entity *e = 0;
|
|
e = dsq->game->createEntity(type, 0, Vector(x, y), 0, false, name, ET_ENEMY, true);
|
|
|
|
luaReturnPtr(e);
|
|
}
|
|
|
|
luaFunc(savePoint)
|
|
{
|
|
Path *p = path(L);
|
|
Vector position;
|
|
if (p)
|
|
{
|
|
|
|
position = p->nodes[0].position;
|
|
}
|
|
|
|
dsq->doSavePoint(position);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(saveMenu)
|
|
{
|
|
dsq->doSaveSlotMenu(SSM_SAVE);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setSceneDisplayNameInSave)
|
|
{
|
|
dsq->game->sceneDisplayName = getString(L);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(pause)
|
|
{
|
|
dsq->game->togglePause(1);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(unpause)
|
|
{
|
|
dsq->game->togglePause(0);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(isPaused)
|
|
{
|
|
luaReturnBool(dsq->game->isPaused());
|
|
}
|
|
|
|
luaFunc(isInGameMenu)
|
|
{
|
|
luaReturnBool(dsq->game->isInGameMenu());
|
|
}
|
|
|
|
luaFunc(isInEditor)
|
|
{
|
|
luaReturnBool(dsq->game->isSceneEditorActive());
|
|
}
|
|
|
|
luaFunc(clearControlHint)
|
|
{
|
|
dsq->game->clearControlHint();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setSceneColor)
|
|
{
|
|
interpolateVec3(L, dsq->game->sceneColor3, 1);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(getSceneColor)
|
|
{
|
|
const Vector& c = dsq->game->sceneColor3;
|
|
luaReturnVec3(c.x, c.y, c.z);
|
|
}
|
|
|
|
luaFunc(setSceneColor2)
|
|
{
|
|
interpolateVec3(L, dsq->game->sceneColor2, 1);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(getSceneColor2)
|
|
{
|
|
const Vector& c = dsq->game->sceneColor2;
|
|
luaReturnVec3(c.x, c.y, c.z);
|
|
}
|
|
|
|
luaFunc(setCameraLerpDelay)
|
|
{
|
|
dsq->game->cameraLerpDelay = lua_tonumber(L, 1);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setControlHint)
|
|
{
|
|
std::string str = getString(L, 1);
|
|
bool left = getBool(L, 2);
|
|
bool right = getBool(L, 3);
|
|
bool middle = getBool(L, 4);
|
|
float t = lua_tonumber(L, 5);
|
|
std::string s;
|
|
if (lua_isstring(L, 6))
|
|
s = lua_tostring(L, 6);
|
|
int songType = lua_tointeger(L, 7);
|
|
float scale = lua_tonumber(L, 8);
|
|
if (scale == 0)
|
|
scale = 1;
|
|
|
|
dsq->game->setControlHint(str, left, right, middle, t, s, false, songType, scale);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setCanChangeForm)
|
|
{
|
|
dsq->game->avatar->canChangeForm = getBool(L);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setInvincibleOnNested)
|
|
{
|
|
dsq->game->invincibleOnNested = getBool(L);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setCanWarp)
|
|
{
|
|
dsq->game->avatar->canWarp = getBool(L);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_generateCollisionMask)
|
|
{
|
|
Entity *e = entity(L);
|
|
float num = lua_tonumber(L, 2);
|
|
if (e)
|
|
{
|
|
e->generateCollisionMask(num);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_damage)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool didDamage = false;
|
|
if (e)
|
|
{
|
|
DamageData d;
|
|
|
|
d.attacker = lua_isuserdata(L, 2) ? entity(L, 2) : NULL;
|
|
d.damage = lua_tonumber(L, 3);
|
|
d.damageType = (DamageType)lua_tointeger(L, 4);
|
|
d.effectTime = lua_tonumber(L, 5);
|
|
d.useTimer = !getBool(L, 6);
|
|
d.shot = lua_isuserdata(L, 7) ? getShot(L, 7) : NULL;
|
|
d.hitPos = Vector(lua_tonumber(L, 8), lua_tonumber(L, 9));
|
|
didDamage = e->damage(d);
|
|
}
|
|
luaReturnBool(didDamage);
|
|
}
|
|
|
|
// must be called in init
|
|
luaFunc(entity_setEntityLayer)
|
|
{
|
|
ScriptedEntity *e = scriptedEntity(L);
|
|
int l = lua_tointeger(L, 2);
|
|
if (e)
|
|
{
|
|
e->setEntityLayer(l);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
// Note that this overrides the generic obj_setRenderPass function for entities.
|
|
// (It's registered as "entity_setRenderPass" to Lua)
|
|
luaFunc(entity_setRenderPass_override)
|
|
{
|
|
Entity *e = entity(L);
|
|
int pass = lua_tointeger(L, 2);
|
|
if (e)
|
|
e->setOverrideRenderPass(pass);
|
|
luaReturnNil();
|
|
}
|
|
|
|
// intended to be used for setting max health and refilling it all
|
|
luaFunc(entity_setHealth)
|
|
{
|
|
Entity *e = entity(L, 1);
|
|
if (e)
|
|
e->health = e->maxHealth = lua_tonumber(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setCurrentHealth)
|
|
{
|
|
Entity *e = entity(L, 1);
|
|
if (e)
|
|
e->health = lua_tonumber(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setMaxHealth)
|
|
{
|
|
Entity *e = entity(L, 1);
|
|
if (e)
|
|
e->maxHealth = lua_tonumber(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_changeHealth)
|
|
{
|
|
Entity *e = entity(L, 1);
|
|
if (e)
|
|
e->health += lua_tonumber(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_heal)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->heal(lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_revive)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->revive(lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(screenFadeCapture)
|
|
{
|
|
dsq->screenTransition->capture();
|
|
luaReturnNil();
|
|
}
|
|
|
|
|
|
luaFunc(screenFadeTransition)
|
|
{
|
|
dsq->screenTransition->transition(lua_tonumber(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(screenFadeGo)
|
|
{
|
|
dsq->screenTransition->go(lua_tonumber(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(isEscapeKey)
|
|
{
|
|
int source = lua_tointeger(L, 1) - 1;
|
|
bool isDown = dsq->game->isActing(ACTION_ESC, source);
|
|
luaReturnBool(isDown);
|
|
}
|
|
|
|
luaFunc(isLeftMouse)
|
|
{
|
|
int source = lua_tointeger(L, 1) - 1;
|
|
bool isDown = (source < 0 && core->mouse.buttons.left)
|
|
|| (dsq->game->avatar && dsq->game->avatar->isActing(ACTION_PRIMARY, source));
|
|
luaReturnBool(isDown);
|
|
}
|
|
|
|
luaFunc(isRightMouse)
|
|
{
|
|
int source = lua_tointeger(L, 1) - 1;
|
|
bool isDown = (source < 0 && core->mouse.buttons.right)
|
|
|| (dsq->game->avatar && dsq->game->avatar->isActing(ACTION_SECONDARY, source));
|
|
luaReturnBool(isDown);
|
|
}
|
|
|
|
luaFunc(setTimerTextAlpha)
|
|
{
|
|
dsq->game->setTimerTextAlpha(lua_tonumber(L, 1), lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setTimerText)
|
|
{
|
|
dsq->game->setTimerText(lua_tonumber(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(getWallNormal)
|
|
{
|
|
float x,y;
|
|
x = lua_tonumber(L, 1);
|
|
y = lua_tonumber(L, 2);
|
|
int range = lua_tointeger(L, 3);
|
|
int obs = lua_tointeger(L, 4);
|
|
if (range == 0)
|
|
range = 5;
|
|
if (!obs)
|
|
obs = OT_BLOCKING;
|
|
|
|
Vector n = dsq->game->getWallNormal(Vector(x, y), range, NULL, obs);
|
|
|
|
luaReturnVec2(n.x, n.y);
|
|
}
|
|
|
|
luaFunc(incrFlag)
|
|
{
|
|
std::string f = getString(L, 1);
|
|
int v = 1;
|
|
if (lua_isnumber(L, 2))
|
|
v = lua_tointeger(L, 2);
|
|
dsq->continuity.setFlag(f, dsq->continuity.getFlag(f)+v);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(decrFlag)
|
|
{
|
|
std::string f = getString(L, 1);
|
|
int v = 1;
|
|
if (lua_isnumber(L, 2))
|
|
v = lua_tointeger(L, 2);
|
|
dsq->continuity.setFlag(f, dsq->continuity.getFlag(f)-v);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setFlag)
|
|
{
|
|
|
|
dsq->continuity.setFlag(lua_tointeger(L, 1), lua_tointeger(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(getFlag)
|
|
{
|
|
int v = 0;
|
|
|
|
v = dsq->continuity.getFlag(lua_tointeger(L, 1));
|
|
|
|
luaReturnNum(v);
|
|
}
|
|
|
|
luaFunc(getStringFlag)
|
|
{
|
|
luaReturnStr(dsq->continuity.getStringFlag(getString(L, 1)).c_str());
|
|
}
|
|
|
|
luaFunc(node_setEmitter)
|
|
{
|
|
Path *p = path(L);
|
|
if(p)
|
|
p->setEmitter(getString(L, 2));
|
|
luaReturnPtr(p->emitter);
|
|
}
|
|
|
|
luaFunc(node_getEmitter)
|
|
{
|
|
Path *p = path(L);
|
|
luaReturnPtr(p ? p->emitter : NULL);
|
|
}
|
|
|
|
|
|
luaFunc(node_setActive)
|
|
{
|
|
Path *p = path(L);
|
|
bool v = getBool(L, 2);
|
|
if (p)
|
|
{
|
|
p->active = v;
|
|
if(p->emitter)
|
|
{
|
|
if(v)
|
|
p->emitter->start();
|
|
else
|
|
p->emitter->stop();
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(node_isActive)
|
|
{
|
|
Path *p = path(L);
|
|
luaReturnBool(p ? p->active : false);
|
|
}
|
|
|
|
luaFunc(node_setCursorActivation)
|
|
{
|
|
Path *p = path(L);
|
|
bool v = getBool(L, 2);
|
|
if (p)
|
|
{
|
|
p->cursorActivation = v;
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(node_setActivationRange)
|
|
{
|
|
Path *p = path(L);
|
|
if(p)
|
|
p->activationRange = lua_tonumber(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(node_setCatchActions)
|
|
{
|
|
Path *p = path(L);
|
|
bool v = getBool(L, 2);
|
|
if (p)
|
|
{
|
|
p->catchActions = v;
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(node_isEntityInRange)
|
|
{
|
|
Path *p = path(L);
|
|
Entity *e = entity(L,2);
|
|
float range = lua_tonumber(L, 3);
|
|
bool v = false;
|
|
if (p && e)
|
|
{
|
|
if ((p->nodes[0].position - e->position).isLength2DIn(range))
|
|
{
|
|
v = true;
|
|
}
|
|
}
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(node_isEntityPast)
|
|
{
|
|
Path *p = path(L);
|
|
bool past = false;
|
|
if (p && !p->nodes.empty())
|
|
{
|
|
PathNode *n = &p->nodes[0];
|
|
Entity *e = entity(L, 2);
|
|
if (e)
|
|
{
|
|
bool checkY = getBool(L, 3);
|
|
int dir = lua_tointeger(L, 4);
|
|
float range = lua_tonumber(L, 5);
|
|
if (!checkY)
|
|
{
|
|
if (e->position.x > n->position.x-range && e->position.x < n->position.x+range)
|
|
{
|
|
if (!dir)
|
|
{
|
|
if (e->position.y < n->position.y)
|
|
past = true;
|
|
}
|
|
else
|
|
{
|
|
if (e->position.y > n->position.y)
|
|
past = true;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (e->position.y > n->position.y-range && e->position.y < n->position.y+range)
|
|
{
|
|
if (!dir)
|
|
{
|
|
if (e->position.x < n->position.x)
|
|
past = true;
|
|
}
|
|
else
|
|
{
|
|
if (e->position.x > n->position.x)
|
|
past = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
luaReturnBool(past);
|
|
}
|
|
|
|
luaFunc(node_x)
|
|
{
|
|
Path *p = path(L);
|
|
float v = 0;
|
|
if (p)
|
|
{
|
|
v = p->nodes[0].position.x;
|
|
}
|
|
luaReturnNum(v);
|
|
}
|
|
|
|
luaFunc(node_y)
|
|
{
|
|
Path *p = path(L);
|
|
float v = 0;
|
|
if (p)
|
|
{
|
|
v = p->nodes[0].position.y;
|
|
}
|
|
luaReturnNum(v);
|
|
}
|
|
|
|
luaFunc(entity_isName)
|
|
{
|
|
Entity *e = entity(L);
|
|
std::string s = getString(L, 2);
|
|
bool ret = false;
|
|
if (e)
|
|
{
|
|
ret = (nocasecmp(s,e->name)==0);
|
|
}
|
|
luaReturnBool(ret);
|
|
}
|
|
|
|
|
|
luaFunc(entity_getName)
|
|
{
|
|
Entity *e = entity(L);
|
|
const char *s = "";
|
|
if (e)
|
|
{
|
|
s = e->name.c_str();
|
|
}
|
|
luaReturnStr(s);
|
|
}
|
|
|
|
luaFunc(node_getContent)
|
|
{
|
|
Path *p = path(L);
|
|
const char *s = "";
|
|
if (p)
|
|
{
|
|
s = p->content.c_str();
|
|
}
|
|
luaReturnStr(s);
|
|
}
|
|
|
|
luaFunc(node_getAmount)
|
|
{
|
|
Path *p = path(L);
|
|
float a = 0;
|
|
if (p)
|
|
{
|
|
a = p->amount;
|
|
}
|
|
luaReturnNum(a);
|
|
}
|
|
|
|
luaFunc(node_getSize)
|
|
{
|
|
Path *p = path(L);
|
|
int w=0,h=0;
|
|
if (p)
|
|
{
|
|
w = p->rect.getWidth();
|
|
h = p->rect.getHeight();
|
|
}
|
|
luaReturnVec2(w, h);
|
|
}
|
|
|
|
luaFunc(node_getName)
|
|
{
|
|
Path *p = path(L);
|
|
const char *s = "";
|
|
if (p)
|
|
{
|
|
s = p->name.c_str();
|
|
}
|
|
luaReturnStr(s);
|
|
}
|
|
|
|
luaFunc(node_getLabel)
|
|
{
|
|
Path *p = path(L);
|
|
const char *s = "";
|
|
if (p)
|
|
{
|
|
s = p->label.c_str();
|
|
}
|
|
luaReturnStr(s);
|
|
}
|
|
|
|
luaFunc(node_getPathPosition)
|
|
{
|
|
Path *p = path(L);
|
|
int idx = lua_tointeger(L, 2);
|
|
float x=0,y=0;
|
|
if (p)
|
|
{
|
|
PathNode *node = p->getPathNode(idx);
|
|
if (node)
|
|
{
|
|
x = node->position.x;
|
|
y = node->position.y;
|
|
}
|
|
}
|
|
luaReturnVec2(x, y);
|
|
}
|
|
|
|
luaFunc(node_getPosition)
|
|
{
|
|
Path *p = path(L);
|
|
float x=0,y=0;
|
|
if (p)
|
|
{
|
|
PathNode *node = &p->nodes[0];
|
|
x = node->position.x;
|
|
y = node->position.y;
|
|
}
|
|
luaReturnVec2(x, y);
|
|
}
|
|
|
|
luaFunc(node_setPosition)
|
|
{
|
|
Path *p = path(L);
|
|
float x=0,y=0;
|
|
if (p)
|
|
{
|
|
x = lua_tonumber(L, 2);
|
|
y = lua_tonumber(L, 3);
|
|
PathNode *node = &p->nodes[0];
|
|
node->position = Vector(x, y);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(node_getShape)
|
|
{
|
|
Path *p = path(L);
|
|
luaReturnInt(p ? p->pathShape : 0);
|
|
}
|
|
|
|
|
|
luaFunc(registerSporeDrop)
|
|
{
|
|
float x, y;
|
|
int t=0;
|
|
x = lua_tonumber(L, 1);
|
|
y = lua_tonumber(L, 2);
|
|
t = lua_tointeger(L, 3);
|
|
|
|
dsq->game->registerSporeDrop(Vector(x,y), t);
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setStringFlag)
|
|
{
|
|
std::string n = getString(L, 1);
|
|
std::string v = getString(L, 2);
|
|
dsq->continuity.setStringFlag(n, v);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(centerText)
|
|
{
|
|
dsq->centerText(getString(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
// this used to be msg(), but this is already an interface function name
|
|
luaFunc(screenMessage)
|
|
{
|
|
dsq->screenMessage(getString(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(chance)
|
|
{
|
|
int r = rand()%100;
|
|
int c = lua_tointeger(L, 1);
|
|
if (c == 0)
|
|
luaReturnBool(false);
|
|
else
|
|
{
|
|
if (r <= c || c==100)
|
|
luaReturnBool(true);
|
|
else
|
|
luaReturnBool(false);
|
|
}
|
|
}
|
|
|
|
luaFunc(entity_handleShotCollisions)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
dsq->game->handleShotCollisions(e);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_handleShotCollisionsSkeletal)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
dsq->game->handleShotCollisionsSkeletal(e);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_handleShotCollisionsHair)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
dsq->game->handleShotCollisionsHair(e, lua_tointeger(L, 2), lua_tonumber(L, 3));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_collideSkeletalVsCircle)
|
|
{
|
|
Entity *e = entity(L);
|
|
RenderObject *e2 = robj(L,2);
|
|
Bone *b = 0;
|
|
if (e && e2)
|
|
{
|
|
b = dsq->game->collideSkeletalVsCircle(e,e2);
|
|
}
|
|
luaReturnPtr(b);
|
|
}
|
|
|
|
luaFunc(entity_collideSkeletalVsCirclePos)
|
|
{
|
|
Entity *e = entity(L);
|
|
Bone *b = 0;
|
|
if (e)
|
|
{
|
|
b = dsq->game->collideSkeletalVsCircle(e, Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), lua_tonumber(L, 4));
|
|
}
|
|
luaReturnPtr(b);
|
|
}
|
|
|
|
luaFunc(entity_collideSkeletalVsLine)
|
|
{
|
|
Entity *e = entity(L);
|
|
int x1, y1, x2, y2, sz;
|
|
x1 = lua_tonumber(L, 2);
|
|
y1 = lua_tonumber(L, 3);
|
|
x2 = lua_tonumber(L, 4);
|
|
y2 = lua_tonumber(L, 5);
|
|
sz = lua_tonumber(L, 6);
|
|
Bone *b = 0;
|
|
if (e)
|
|
{
|
|
b = dsq->game->collideSkeletalVsLine(e, Vector(x1, y1), Vector(x2, y2), sz);
|
|
}
|
|
luaReturnPtr(b);
|
|
}
|
|
|
|
luaFunc(entity_collideHairVsCircle)
|
|
{
|
|
Entity *e = entity(L);
|
|
Entity *e2 = entity(L, 2);
|
|
bool col=false;
|
|
if (e && e2)
|
|
{
|
|
int num = lua_tointeger(L, 3);
|
|
// perc: percent of hairWidth to use as collide radius
|
|
float perc = lua_tonumber(L, 4);
|
|
int colSegment;
|
|
col = dsq->game->collideHairVsCircle(e, num, e2->position, e2->collideRadius, perc, &colSegment);
|
|
if(col)
|
|
{
|
|
lua_pushboolean(L, true);
|
|
lua_pushinteger(L, colSegment);
|
|
return 2;
|
|
}
|
|
}
|
|
luaReturnBool(false);
|
|
}
|
|
|
|
luaFunc(entity_collideSkeletalVsCircleForListByName)
|
|
{
|
|
Entity *e = entity(L);
|
|
std::string name;
|
|
if (lua_isstring(L, 2))
|
|
name = lua_tostring(L, 2);
|
|
if (e && !name.empty())
|
|
{
|
|
FOR_ENTITIES(i)
|
|
{
|
|
Entity *e2 = *i;
|
|
if (e2->life == 1 && e2->name == name)
|
|
{
|
|
Bone *b = dsq->game->collideSkeletalVsCircle(e, e2);
|
|
if (b)
|
|
{
|
|
DamageData d;
|
|
d.attacker = e2;
|
|
d.bone = b;
|
|
e->damage(d);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_debugText)
|
|
{
|
|
Entity *e = entity(L);
|
|
const char *txt = lua_tostring(L, 2);
|
|
if (e && txt)
|
|
{
|
|
BitmapText *f = new BitmapText(&dsq->smallFont);
|
|
f->setText(txt);
|
|
f->position = e->position;
|
|
core->getTopStateData()->addRenderObject(f, LR_DEBUG_TEXT);
|
|
f->setLife(5);
|
|
f->setDecayRate(1);
|
|
f->fadeAlphaWithLife=1;
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getHealth)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnNum(e ? e->health : 0);
|
|
}
|
|
|
|
luaFunc(entity_getMaxHealth)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnNum(e ? e->maxHealth : 0);
|
|
}
|
|
|
|
luaFunc(entity_initSegments)
|
|
{
|
|
ScriptedEntity *se = scriptedEntity(L);
|
|
if (se)
|
|
se->initSegments(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), getString(L, 5), getString(L, 6), lua_tointeger(L, 7), lua_tointeger(L, 8), lua_tonumber(L, 9), lua_tointeger(L, 10));
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_warpSegments)
|
|
{
|
|
ScriptedEntity *se = scriptedEntity(L);
|
|
if (se)
|
|
se->warpSegments();
|
|
|
|
luaReturnNil()
|
|
}
|
|
|
|
luaFunc(avatar_incrLeaches)
|
|
{
|
|
dsq->game->avatar->leaches++;
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(avatar_decrLeaches)
|
|
{
|
|
// Not checking for underflow here because this allows some neat tricks.
|
|
dsq->game->avatar->leaches--;
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_incrTargetLeaches) // DEPRECATED
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e && e->getTargetEntity() == dsq->game->avatar)
|
|
dsq->game->avatar->leaches++;
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_decrTargetLeaches) // DEPRECATED
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e && e->getTargetEntity() == dsq->game->avatar)
|
|
dsq->game->avatar->leaches--;
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_rotateToVel)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
if (!e->vel.isZero())
|
|
{
|
|
e->rotateToVec(e->vel, lua_tonumber(L, 2), lua_tointeger(L, 3));
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_rotateToEntity)
|
|
{
|
|
Entity *e = entity(L);
|
|
Entity *e2 = entity(L, 2);
|
|
|
|
if (e && e2)
|
|
{
|
|
Vector vec = e2->position - e->position;
|
|
if (!vec.isZero())
|
|
{
|
|
e->rotateToVec(vec, lua_tonumber(L, 3), lua_tointeger(L, 4));
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_rotateToVec)
|
|
{
|
|
Entity *e = entity(L);
|
|
Vector vec(lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
if (e)
|
|
{
|
|
if (!vec.isZero())
|
|
{
|
|
e->rotateToVec(vec, lua_tonumber(L, 4), lua_tointeger(L, 5));
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_updateSkeletal)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
bool oldIgnore = e->skeletalSprite.ignoreUpdate;
|
|
e->skeletalSprite.ignoreUpdate = false;
|
|
e->skeletalSprite.update(lua_tonumber(L, 2));
|
|
e->skeletalSprite.ignoreUpdate = oldIgnore;
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_msg)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
// pass everything on the stack except the entity pointer
|
|
int res = e->messageVariadic(L, lua_gettop(L) - 1);
|
|
if (res >= 0)
|
|
return res;
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(node_msg)
|
|
{
|
|
Path *p = path(L);
|
|
if (p)
|
|
{
|
|
// pass everything on the stack except the entity pointer
|
|
int res = p->messageVariadic(L, lua_gettop(L) - 1);
|
|
if (res >= 0)
|
|
return res;
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_updateCurrents)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnBool(e ? e->updateCurrents(lua_tonumber(L, 2)) : false);
|
|
}
|
|
|
|
luaFunc(entity_updateLocalWarpAreas)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnBool(e ? e->updateLocalWarpAreas(getBool(L, 2)) : false);
|
|
}
|
|
|
|
luaFunc(entity_updateMovement)
|
|
{
|
|
ScriptedEntity *e = scriptedEntity(L);
|
|
if (e)
|
|
e->updateMovement(lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_applySurfaceNormalForce)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
Vector v;
|
|
if (!e->ridingOnEntity)
|
|
{
|
|
v = dsq->game->getWallNormal(e->position, 8);
|
|
}
|
|
else
|
|
{
|
|
v = e->position - e->ridingOnEntity->position;
|
|
e->ridingOnEntity = 0;
|
|
}
|
|
v.setLength2D(lua_tointeger(L, 2));
|
|
e->vel += v;
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_doElementInteraction)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
float mult = lua_tonumber(L, 2);
|
|
float touchWidth = lua_tonumber(L, 3);
|
|
if (!touchWidth)
|
|
touchWidth = 16;
|
|
|
|
ElementUpdateList& elems = dsq->game->elementInteractionList;
|
|
for (ElementUpdateList::iterator it = elems.begin(); it != elems.end(); ++it)
|
|
{
|
|
(*it)->doInteraction(e, mult, touchWidth);
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(avatar_setElementEffectMult)
|
|
{
|
|
dsq->game->avatar->elementEffectMult = lua_tonumber(L, 1);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(flingMonkey)
|
|
{
|
|
Entity *e = entity(L);
|
|
|
|
dsq->continuity.flingMonkey(e);
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getDistanceToTarget)
|
|
{
|
|
Entity *e = entity(L);
|
|
float dist = 0;
|
|
if (e)
|
|
{
|
|
Entity *t = e->getTargetEntity();
|
|
if (t)
|
|
{
|
|
dist = (t->position - e->position).getLength2D();
|
|
}
|
|
}
|
|
luaReturnNum(dist);
|
|
}
|
|
|
|
luaFunc(entity_getDistanceToPoint)
|
|
{
|
|
Entity *e = entity(L);
|
|
float dist = 0;
|
|
if (e)
|
|
{
|
|
Vector p(lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
dist = (p - e->position).getLength2D();
|
|
}
|
|
luaReturnNum(dist);
|
|
}
|
|
|
|
luaFunc(entity_watchEntity)
|
|
{
|
|
Entity *e = entity(L);
|
|
Entity *e2 = 0;
|
|
if (lua_touserdata(L, 2) != NULL)
|
|
e2 = entity(L, 2);
|
|
|
|
if (e)
|
|
{
|
|
e->watchEntity(e2);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setNaijaHeadTexture)
|
|
{
|
|
Avatar *a = dsq->game->avatar;
|
|
if (a)
|
|
{
|
|
a->setHeadTexture(getString(L, 1), lua_tonumber(L, 2));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_flipToSame)
|
|
{
|
|
Entity *e = entity(L);
|
|
Entity *e2 = entity(L, 2);
|
|
if (e && e2)
|
|
{
|
|
if ((e->isfh() && !e2->isfh())
|
|
|| (!e->isfh() && e2->isfh()))
|
|
{
|
|
e->flipHorizontal();
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_flipToEntity)
|
|
{
|
|
Entity *e = entity(L);
|
|
Entity *e2 = entity(L, 2);
|
|
if (e && e2)
|
|
{
|
|
e->flipToTarget(e2->position);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_flipToNode)
|
|
{
|
|
Entity *e = entity(L);
|
|
Path *p = path(L, 2);
|
|
PathNode *n = &p->nodes[0];
|
|
if (e && n)
|
|
{
|
|
e->flipToTarget(n->position);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_flipToVel)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->flipToVel();
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(node_isEntityIn)
|
|
{
|
|
Path *p = path(L,1);
|
|
Entity *e = entity(L,2);
|
|
|
|
bool v = false;
|
|
if (e && p)
|
|
{
|
|
if (!p->nodes.empty())
|
|
{
|
|
v = p->isCoordinateInside(e->position);
|
|
//(e->position - p->nodes[0].position);
|
|
}
|
|
}
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(node_isPositionIn)
|
|
{
|
|
Path *p = path(L,1);
|
|
float x = lua_tonumber(L, 2);
|
|
float y = lua_tonumber(L, 3);
|
|
|
|
bool v = false;
|
|
if (p)
|
|
{
|
|
if (!p->nodes.empty())
|
|
{
|
|
v = p->rect.isCoordinateInside(Vector(x,y) - p->nodes[0].position);
|
|
}
|
|
}
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(entity_isInDarkness)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool d = false;
|
|
if (e)
|
|
{
|
|
d = e->isInDarkness();
|
|
}
|
|
luaReturnBool(d);
|
|
}
|
|
|
|
luaFunc(entity_isInRect)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool v= false;
|
|
float x1, y1, x2, y2;
|
|
x1 = lua_tonumber(L, 2);
|
|
y1 = lua_tonumber(L, 3);
|
|
x2 = lua_tonumber(L, 4);
|
|
y2 = lua_tonumber(L, 5);
|
|
if (e)
|
|
{
|
|
if (e->position.x > x1 && e->position.x < x2)
|
|
{
|
|
if (e->position.y > y1 && e->position.y < y2)
|
|
{
|
|
v = true;
|
|
}
|
|
}
|
|
}
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(createQuad)
|
|
{
|
|
PauseQuad *q = new PauseQuad();
|
|
q->setTexture(getString(L, 1));
|
|
int layer = lua_tointeger(L, 2);
|
|
if (layer == 13)
|
|
layer = 13;
|
|
else
|
|
layer = (LR_PARTICLES+1) - LR_ELEMENTS1;
|
|
dsq->game->addRenderObject(q, LR_ELEMENTS1+(layer-1));
|
|
q->moveToFront();
|
|
|
|
luaReturnPtr(q);
|
|
}
|
|
|
|
luaFunc(quad_setPauseLevel)
|
|
{
|
|
Quad *q = getQuad(L);
|
|
ENSURE_TYPE(q, SCO_PAUSEQUAD);
|
|
if (q)
|
|
((PauseQuad*)q)->pauseLevel = lua_tointeger(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setupEntity)
|
|
{
|
|
ScriptedEntity *se = scriptedEntity(L);
|
|
if (se)
|
|
{
|
|
std::string tex;
|
|
if (lua_isstring(L, 2))
|
|
{
|
|
tex = lua_tostring(L, 2);
|
|
}
|
|
se->setupEntity(tex, lua_tonumber(L, 3));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setupBasicEntity)
|
|
{
|
|
ScriptedEntity *se = scriptedEntity(L);
|
|
//-- texture, health, manaballamount, exp, money, collideRadius, initState
|
|
if (se)
|
|
se->setupBasicEntity(getString(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5), lua_tointeger(L, 6), lua_tointeger(L, 7), lua_tointeger(L, 8), lua_tointeger(L, 9), lua_tointeger(L, 10), lua_tointeger(L, 11), lua_tointeger(L, 12), lua_tointeger(L, 13), lua_tointeger(L, 14));
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setBeautyFlip)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->beautyFlip = getBool(L, 2);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setInvincible)
|
|
{
|
|
dsq->game->invinciblity = getBool(L, 1);
|
|
|
|
luaReturnBool(dsq->game->invinciblity);
|
|
}
|
|
|
|
luaFunc(entity_setInvincible)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->setInvincible(getBool(L, 2));
|
|
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setDeathSound)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->deathSound = getString(L, 2);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setDeathParticleEffect)
|
|
{
|
|
ScriptedEntity *se = scriptedEntity(L);
|
|
if (se)
|
|
{
|
|
se->deathParticleEffect = getString(L, 2);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setNaijaReaction)
|
|
{
|
|
Entity *e = entity(L);
|
|
std::string s;
|
|
if (lua_isstring(L, 2))
|
|
s = lua_tostring(L, 2);
|
|
if (e)
|
|
{
|
|
e->naijaReaction = s;
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setName)
|
|
{
|
|
Entity *e = entity(L);
|
|
std::string s;
|
|
if (lua_isstring(L, 2))
|
|
s = lua_tostring(L, 2);
|
|
if (e)
|
|
{
|
|
debugLog("setting entity name to: " + s);
|
|
e->setName(s);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_pathBurst)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool v = false;
|
|
if (e)
|
|
v = e->pathBurst(lua_tointeger(L, 2));
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(entity_moveTowardsAngle)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->moveTowardsAngle(lua_tointeger(L, 2), lua_tonumber(L, 3), lua_tointeger(L, 4));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_moveAroundAngle)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->moveTowardsAngle(lua_tointeger(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_moveTowards)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->moveTowards(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), lua_tonumber(L, 4), lua_tonumber(L, 5));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_moveAround)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->moveAround(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_addVel2)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->vel2 += Vector(lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setVel2)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->vel2 = Vector(lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getVel2Len)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnNum(e ? e->vel2.getLength2D() : 0.0f);
|
|
}
|
|
|
|
luaFunc(entity_setVel2Len)
|
|
{
|
|
Entity *e = entity(L);
|
|
if(e)
|
|
e->vel2.setLength2D(lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getVel2)
|
|
{
|
|
Entity *e = entity(L);
|
|
Vector vel2;
|
|
if(e)
|
|
vel2 = e->vel2;
|
|
luaReturnVec2(vel2.x, vel2.y);
|
|
}
|
|
|
|
luaFunc(entity_isValidTarget)
|
|
{
|
|
Entity *e = entity(L);
|
|
Entity *e2 = 0;
|
|
if (lua_tonumber(L, 2)!=0)
|
|
e2 = entity(L);
|
|
bool b = false;
|
|
if (e)
|
|
b = dsq->game->isValidTarget(e, e2);
|
|
luaReturnBool(b);
|
|
}
|
|
luaFunc(entity_clearVel2)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->vel2 = Vector(0,0,0);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(getScreenCenter)
|
|
{
|
|
luaReturnVec2(core->screenCenter.x, core->screenCenter.y);
|
|
}
|
|
|
|
luaFunc(entity_isState)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool v=false;
|
|
if (e)
|
|
{
|
|
v = (e->getState() == lua_tointeger(L, 2));
|
|
}
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(entity_getState)
|
|
{
|
|
Entity *e = entity(L);
|
|
int state = 0;
|
|
if (e)
|
|
state = e->getState();
|
|
luaReturnNum(state);
|
|
}
|
|
|
|
luaFunc(entity_getEnqueuedState)
|
|
{
|
|
Entity *e = entity(L);
|
|
int state = 0;
|
|
if (e)
|
|
state = e->getEnqueuedState();
|
|
luaReturnNum(state);
|
|
}
|
|
|
|
luaFunc(entity_getPrevState)
|
|
{
|
|
Entity *e = entity(L);
|
|
int state = 0;
|
|
if (e)
|
|
state = e->getPrevState();
|
|
luaReturnNum(state);
|
|
}
|
|
|
|
luaFunc(entity_setTarget)
|
|
{
|
|
Entity *e = entity(L);
|
|
Entity *t = 0;
|
|
if (lua_touserdata(L, 2) != NULL)
|
|
{
|
|
t = entity(L, 2);
|
|
}
|
|
if (e)
|
|
{
|
|
e->setTargetEntity(t);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setBounce)
|
|
{
|
|
CollideEntity *e = collideEntity(L);
|
|
if (e)
|
|
e->bounceAmount = lua_tonumber(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(avatar_isSinging)
|
|
{
|
|
bool b = dsq->game->avatar->isSinging();
|
|
luaReturnBool(b);
|
|
}
|
|
|
|
luaFunc(avatar_isTouchHit)
|
|
{
|
|
//avatar_canBeTouchHit
|
|
bool b = !(dsq->game->avatar->bursting && dsq->continuity.form == FORM_BEAST);
|
|
luaReturnBool(b);
|
|
}
|
|
|
|
luaFunc(avatar_clampPosition)
|
|
{
|
|
dsq->game->avatar->clampPosition();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setMaxSpeed)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->setMaxSpeed(lua_tonumber(L, 2));
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getMaxSpeed)
|
|
{
|
|
Entity *e = entity(L);
|
|
int v = 0;
|
|
if (e)
|
|
v = e->getMaxSpeed();
|
|
|
|
luaReturnNum(v);
|
|
}
|
|
|
|
luaFunc(entity_setMaxSpeedLerp)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
interpolateVec1(L, e->maxSpeedLerp, 2);
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getMaxSpeedLerp)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnNum(e ? e->maxSpeedLerp.x : 0.0f);
|
|
}
|
|
|
|
// note: this is a weaker setState than perform
|
|
// this is so that things can override it
|
|
// for example getting PUSH-ed (Force) or FROZEN (bubbled)
|
|
luaFunc(entity_setState)
|
|
{
|
|
Entity *me = entity(L);
|
|
if (me)
|
|
{
|
|
int state = lua_tointeger(L, 2);
|
|
float time = lua_tonumber(L, 3);
|
|
if (time == 0)
|
|
time = -1;
|
|
bool force = getBool(L, 4);
|
|
me->setState(state, time, force);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getBoneByIdx)
|
|
{
|
|
Entity *e = entity(L);
|
|
Bone *b = 0;
|
|
if (e)
|
|
{
|
|
int n = 0;
|
|
if (lua_isnumber(L, 2))
|
|
{
|
|
n = lua_tointeger(L, 2);
|
|
b = e->skeletalSprite.getBoneByIdx(n);
|
|
}
|
|
}
|
|
luaReturnPtr(b);
|
|
}
|
|
|
|
luaFunc(entity_getBoneByName)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnPtr(e ? e->skeletalSprite.getBoneByName(getString(L, 2)) : NULL);
|
|
}
|
|
|
|
luaFunc(entity_getBoneByInternalId)
|
|
{
|
|
Entity *e = entity(L);
|
|
size_t i = lua_tointeger(L, 2);
|
|
luaReturnPtr((e && i < e->skeletalSprite.bones.size()) ? e->skeletalSprite.bones[i] : NULL);
|
|
}
|
|
|
|
luaFunc(entity_getNumBones)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnInt(e ? (int)e->skeletalSprite.bones.size() : 0);
|
|
}
|
|
|
|
luaFunc(bone_getIndex)
|
|
{
|
|
Bone *b = bone(L);
|
|
int idx = -1;
|
|
if (b)
|
|
idx = b->boneIdx;
|
|
luaReturnNum(idx);
|
|
}
|
|
|
|
luaFunc(bone_getName)
|
|
{
|
|
const char *n = "";
|
|
Bone *b = bone(L);
|
|
if (b)
|
|
{
|
|
n = b->name.c_str();
|
|
}
|
|
luaReturnStr(n);
|
|
}
|
|
|
|
luaFunc(bone_isName)
|
|
{
|
|
Bone *b = bone(L);
|
|
bool v = false;
|
|
const char *s = lua_tostring(L, 2);
|
|
if (b && s)
|
|
{
|
|
v = b->name == s;
|
|
}
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(overrideZoom)
|
|
{
|
|
dsq->game->overrideZoom(lua_tonumber(L, 1), lua_tonumber(L, 2));
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(getZoom)
|
|
{
|
|
luaReturnNum(dsq->globalScale.x);
|
|
}
|
|
|
|
luaFunc(disableOverrideZoom)
|
|
{
|
|
dsq->game->toggleOverrideZoom(false);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setMaxLookDistance)
|
|
{
|
|
dsq->game->maxLookDistance = lua_tonumber(L, 1);
|
|
luaReturnNil();
|
|
}
|
|
|
|
|
|
// dt, range, mod
|
|
luaFunc(entity_doSpellAvoidance)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->doSpellAvoidance(lua_tonumber(L, 2), lua_tointeger(L, 3), lua_tonumber(L, 4));
|
|
luaReturnNil();
|
|
}
|
|
|
|
// dt, range, mod, ignore
|
|
luaFunc(entity_doEntityAvoidance)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->doEntityAvoidance(lua_tonumber(L, 2), lua_tointeger(L, 3), lua_tonumber(L, 4), e->getTargetEntity());
|
|
luaReturnNil();
|
|
}
|
|
|
|
// doCollisionAvoidance(me, dt, search, mod)
|
|
luaFunc(entity_doCollisionAvoidance)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool ret = false;
|
|
|
|
bool useVel2 = getBool(L, 6);
|
|
bool onlyVP = getBool(L, 7);
|
|
int ignoreObs = lua_tointeger(L, 8);
|
|
|
|
if (e)
|
|
{
|
|
if (useVel2)
|
|
ret = e->doCollisionAvoidance(lua_tonumber(L, 2), lua_tointeger(L, 3), lua_tonumber(L, 4), &e->vel2, lua_tonumber(L, 5), ignoreObs, onlyVP);
|
|
else
|
|
ret = e->doCollisionAvoidance(lua_tonumber(L, 2), lua_tointeger(L, 3), lua_tonumber(L, 4), 0, lua_tonumber(L, 5), ignoreObs);
|
|
}
|
|
luaReturnBool(ret);
|
|
}
|
|
|
|
luaFunc(setOverrideMusic)
|
|
{
|
|
dsq->game->overrideMusic = getString(L, 1);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setOverrideVoiceFader)
|
|
{
|
|
dsq->sound->setOverrideVoiceFader(lua_tonumber(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setGameSpeed)
|
|
{
|
|
dsq->gameSpeed.stop();
|
|
dsq->gameSpeed.stopPath();
|
|
interpolateVec1(L, dsq->gameSpeed, 1);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(bedEffects)
|
|
{
|
|
dsq->overlay->alpha.interpolateTo(1, 2);
|
|
dsq->sound->fadeMusic(SFT_OUT, 1);
|
|
core->run(1);
|
|
// music goes here
|
|
dsq->sound->fadeMusic(SFT_CROSS, 1);
|
|
dsq->sound->playMusic("Sleep");
|
|
core->run(6);
|
|
Vector bedPosition(lua_tointeger(L, 1), lua_tointeger(L, 2));
|
|
if (bedPosition.x == 0 && bedPosition.y == 0)
|
|
{
|
|
bedPosition = dsq->game->avatar->position;
|
|
}
|
|
dsq->game->positionToAvatar = bedPosition;
|
|
dsq->game->transitionToScene(dsq->game->sceneName);
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setDeathScene)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->setDeathScene(getBool(L, 2));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_isDeathScene)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnBool(e ? e->isDeathScene() : false);
|
|
}
|
|
|
|
luaFunc(entity_setCurrentTarget)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->currentEntityTarget = lua_tointeger(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entityFollowEntity)
|
|
{
|
|
Entity *e = dsq->getEntityByName(getString(L, 1));
|
|
if (e)
|
|
{
|
|
e->followEntity = dsq->getEntityByName(getString(L, 2));
|
|
}
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_isFollowingEntity)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool v = false;
|
|
if (e)
|
|
v = e->followEntity != 0;
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(entity_followEntity)
|
|
{
|
|
Entity *e1 = entity(L);
|
|
Entity *e2 = 0;
|
|
if (lua_touserdata(L, 2) != NULL)
|
|
{
|
|
e2 = entity(L, 2);
|
|
}
|
|
if (e1)
|
|
{
|
|
e1->followEntity = e2;
|
|
e1->followPos = lua_tointeger(L, 3);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(toggleInput)
|
|
{
|
|
bool v = getBool(L, 1);
|
|
if (v)
|
|
dsq->game->avatar->enableInput();
|
|
else
|
|
dsq->game->avatar->disableInput();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(warpAvatar)
|
|
{
|
|
dsq->game->positionToAvatar = Vector(lua_tointeger(L, 2),lua_tointeger(L, 3));
|
|
dsq->game->transitionToScene(getString(L, 1));
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(warpNaijaToSceneNode)
|
|
{
|
|
std::string scene = getString(L, 1);
|
|
std::string node = getString(L, 2);
|
|
std::string flip = getString(L, 3);
|
|
if (!scene.empty() && !node.empty())
|
|
{
|
|
dsq->game->toNode = node;
|
|
stringToLower(flip);
|
|
if (flip == "l")
|
|
dsq->game->toFlip = 0;
|
|
if (flip == "r")
|
|
dsq->game->toFlip = 1;
|
|
dsq->game->transitionToScene(scene);
|
|
}
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setDamageTarget)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->setDamageTarget((DamageType)lua_tointeger(L, 2), getBool(L, 3));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setAllDamageTargets)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->setAllDamageTargets(getBool(L, 2));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_isDamageTarget)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool v=false;
|
|
if (e)
|
|
{
|
|
v = e->isDamageTarget((DamageType)lua_tointeger(L, 2));
|
|
}
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(entity_setTargetRange)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->targetRange = lua_tonumber(L, 2);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getTargetRange)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnInt(e ? e->getTargetRange() : 0);
|
|
}
|
|
|
|
luaFunc(entity_clearTargetPoints)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->clearTargetPoints();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_addTargetPoint)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->addTargetPoint(Vector(lua_tonumber(L,2), lua_tonumber(L, 3)));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getTargetPoint)
|
|
{
|
|
Entity *e = entity(L);
|
|
int idx = lua_tointeger(L, 2);
|
|
Vector v;
|
|
if (e)
|
|
{
|
|
v = e->getTargetPoint(idx);
|
|
}
|
|
luaReturnVec2(v.x, v.y);
|
|
}
|
|
|
|
luaFunc(entity_getRandomTargetPoint)
|
|
{
|
|
Entity *e = entity(L);
|
|
Vector v;
|
|
int idx = 0;
|
|
if (e)
|
|
{
|
|
idx = e->getRandomTargetPoint();
|
|
}
|
|
luaReturnNum(idx);
|
|
}
|
|
|
|
luaFunc(entity_getNumTargetPoints)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnInt(e ? e->getNumTargetPoints() : 0);
|
|
}
|
|
|
|
luaFunc(playVisualEffect)
|
|
{
|
|
Entity *target = NULL;
|
|
if(lua_isuserdata(L, 4))
|
|
target = entity(L, 4);
|
|
dsq->playVisualEffect(lua_tonumber(L, 1), Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), target);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(playNoEffect)
|
|
{
|
|
dsq->playNoEffect();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(createShockEffect)
|
|
{
|
|
if (core->afterEffectManager)
|
|
{
|
|
core->afterEffectManager->addEffect(new ShockEffect(
|
|
Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)), // position
|
|
Vector(lua_tonumber(L, 3), lua_tonumber(L, 4)), // original position
|
|
lua_tonumber(L, 5), // amplitude
|
|
lua_tonumber(L, 6), // amplitude decay
|
|
lua_tonumber(L, 7), // frequency
|
|
lua_tonumber(L, 8), // wave length
|
|
lua_tonumber(L, 9))); // time multiplier
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(emote)
|
|
{
|
|
int emote = lua_tointeger(L, 1);
|
|
dsq->emote.playSfx(emote);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(playSfx)
|
|
{
|
|
PlaySfx sfx;
|
|
sfx.name = getString(L, 1);
|
|
sfx.freq = lua_tonumber(L, 2);
|
|
sfx.vol = lua_tonumber(L, 3);
|
|
if (sfx.vol <= 0)
|
|
sfx.vol = 1;
|
|
sfx.loops = lua_tointeger(L, 4);
|
|
if(lua_isnumber(L, 5) && lua_isnumber(L, 6))
|
|
{
|
|
sfx.x = lua_tonumber(L, 5);
|
|
sfx.y = lua_tonumber(L, 6);
|
|
sfx.positional = true;
|
|
}
|
|
sfx.maxdist = lua_tonumber(L, 7);
|
|
if(lua_isnoneornil(L, 8))
|
|
sfx.relative = (sfx.x == 0 && sfx.y == 0);
|
|
else
|
|
sfx.relative = getBool(L, 8);
|
|
|
|
void *handle = NULL;
|
|
|
|
if (!dsq->isSkippingCutscene())
|
|
{
|
|
handle = core->sound->playSfx(sfx);
|
|
}
|
|
|
|
luaReturnPtr(handle);
|
|
}
|
|
|
|
luaFunc(fadeSfx)
|
|
{
|
|
void *header = lua_touserdata(L, 1);
|
|
float ft = lua_tonumber(L, 2);
|
|
|
|
core->sound->fadeSfx(header, SFT_OUT, ft);
|
|
|
|
luaReturnPtr(header);
|
|
}
|
|
|
|
luaFunc(resetTimer)
|
|
{
|
|
dsq->resetTimer();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(stopMusic)
|
|
{
|
|
dsq->sound->stopMusic();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(playMusic)
|
|
{
|
|
float crossfadeTime = 0.8f;
|
|
dsq->sound->playMusic(getString(L, 1), SLT_LOOP, SFT_CROSS, crossfadeTime);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(playMusicStraight)
|
|
{
|
|
dsq->sound->setMusicFader(1,0);
|
|
dsq->sound->playMusic(getString(L, 1), SLT_LOOP, SFT_IN, 0.5);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(playMusicOnce)
|
|
{
|
|
float crossfadeTime = 0.8f;
|
|
dsq->sound->playMusic(getString(L, 1), SLT_NONE, SFT_CROSS, crossfadeTime);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(addInfluence)
|
|
{
|
|
ParticleInfluence pinf;
|
|
pinf.pos.x = lua_tonumber(L, 1);
|
|
pinf.pos.y = lua_tonumber(L, 2);
|
|
pinf.size = lua_tonumber(L, 3);
|
|
pinf.spd = lua_tonumber(L, 4);
|
|
pinf.pull = getBool(L, 5);
|
|
dsq->particleManager->addInfluence(pinf);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(updateMusic)
|
|
{
|
|
dsq->game->updateMusic();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_grabTarget)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->attachEntity(e->getTargetEntity(), Vector(lua_tointeger(L, 2), lua_tointeger(L, 3)));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_clampToHit)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->clampToHit();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_clampToSurface)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool ret = e && e->clampToSurface(lua_tonumber(L, 2));
|
|
|
|
luaReturnBool(ret);
|
|
}
|
|
|
|
luaFunc(entity_checkSurface)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool c = false;
|
|
|
|
if (e)
|
|
{
|
|
c = e->checkSurface(lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4));
|
|
}
|
|
|
|
luaReturnBool(c);
|
|
}
|
|
|
|
luaFunc(entity_switchSurfaceDirection)
|
|
{
|
|
ScriptedEntity *e = scriptedEntity(L);
|
|
if (!e)
|
|
luaReturnNil();
|
|
|
|
int n = -1;
|
|
if (lua_isnumber(L, 2))
|
|
{
|
|
n = lua_tonumber(L, 2);
|
|
}
|
|
|
|
if (e->isv(EV_SWITCHCLAMP, 1))
|
|
{
|
|
Vector oldPos = e->position;
|
|
if (e->isNearObstruction(0))
|
|
{
|
|
Vector n = dsq->game->getWallNormal(e->position);
|
|
if (!n.isZero())
|
|
{
|
|
do
|
|
{
|
|
e->position += n * 2;
|
|
}
|
|
while(e->isNearObstruction(0));
|
|
}
|
|
}
|
|
Vector usePos = e->position;
|
|
e->position = oldPos;
|
|
e->clampToSurface(0, usePos);
|
|
}
|
|
|
|
if (n == -1)
|
|
{
|
|
if (e->surfaceMoveDir)
|
|
e->surfaceMoveDir = 0;
|
|
else
|
|
e->surfaceMoveDir = 1;
|
|
}
|
|
else
|
|
{
|
|
e->surfaceMoveDir = n;
|
|
}
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_adjustPositionBySurfaceNormal)
|
|
{
|
|
ScriptedEntity *e = scriptedEntity(L);
|
|
if (e && !e->ridingOnEntity)
|
|
{
|
|
Vector v = dsq->game->getWallNormal(e->position);
|
|
if (v.x != 0 || v.y != 0)
|
|
{
|
|
v.setLength2D(lua_tonumber(L, 2));
|
|
e->position += v;
|
|
}
|
|
e->setv(EV_CRAWLING, 0);
|
|
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
// HACK: move functionality inside entity class
|
|
luaFunc(entity_moveAlongSurface)
|
|
{
|
|
ScriptedEntity *e = scriptedEntity(L);
|
|
|
|
if (e && e->isv(EV_CLAMPING,0))
|
|
{
|
|
e->lastPosition = e->position;
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Vector v;
|
|
if (e->ridingOnEntity)
|
|
{
|
|
v = (e->position - e->ridingOnEntity->position);
|
|
v.normalize2D();
|
|
}
|
|
else
|
|
v = dsq->game->getWallNormal(e->position);
|
|
|
|
int outFromWall = e->getv(EV_WALLOUT);
|
|
bool invisibleIn = e->isSittingOnInvisibleIn();
|
|
|
|
|
|
|
|
if (invisibleIn)
|
|
outFromWall -= TILE_SIZE;
|
|
float t = 0.1f;
|
|
e->offset.interpolateTo(v*outFromWall, t);
|
|
|
|
|
|
|
|
float dt = lua_tonumber(L, 2);
|
|
float speed = lua_tonumber(L, 3);
|
|
|
|
Vector mov;
|
|
if (e->surfaceMoveDir==1)
|
|
mov = Vector(v.y, -v.x);
|
|
else
|
|
mov = Vector(-v.y, v.x);
|
|
e->position += mov * speed * dt;
|
|
|
|
if (e->ridingOnEntity)
|
|
e->ridingOnEntityOffset = e->position - e->ridingOnEntity->position;
|
|
|
|
e->vel = 0;
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_rotateToSurfaceNormal)
|
|
{
|
|
|
|
Entity *e = entity(L);
|
|
float t = lua_tonumber(L, 2);
|
|
int n = lua_tointeger(L, 3);
|
|
float rot = lua_tonumber(L, 4);
|
|
if (e)
|
|
{
|
|
e->rotateToSurfaceNormal(t, n, rot);
|
|
}
|
|
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_releaseTarget)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->detachEntity(e->getTargetEntity());
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(esetv)
|
|
{
|
|
Entity *e = entity(L);
|
|
EV ev = (EV)lua_tointeger(L, 2);
|
|
int n = lua_tointeger(L, 3);
|
|
if (e)
|
|
e->setv(ev, n);
|
|
luaReturnNum(n);
|
|
}
|
|
|
|
luaFunc(egetv)
|
|
{
|
|
Entity *e = entity(L);
|
|
EV ev = (EV)lua_tointeger(L, 2);
|
|
int v = 0;
|
|
if (e)
|
|
v = e->getv(ev);
|
|
luaReturnNum(v);
|
|
}
|
|
|
|
luaFunc(esetvf)
|
|
{
|
|
Entity *e = entity(L);
|
|
EV ev = (EV)lua_tointeger(L, 2);
|
|
float n = lua_tonumber(L, 3);
|
|
if (e)
|
|
e->setvf(ev, n);
|
|
luaReturnNum(n);
|
|
}
|
|
|
|
luaFunc(egetvf)
|
|
{
|
|
Entity *e = entity(L);
|
|
float vf = 0;
|
|
if (e)
|
|
{
|
|
EV ev = (EV)lua_tointeger(L, 2);
|
|
vf = e->getvf(ev);
|
|
}
|
|
luaReturnNum(vf);
|
|
}
|
|
|
|
luaFunc(eisv)
|
|
{
|
|
Entity *e = entity(L);
|
|
EV ev = (EV)lua_tointeger(L, 2);
|
|
int n = lua_tointeger(L, 3);
|
|
bool b = 0;
|
|
if (e)
|
|
b = e->isv(ev, n);
|
|
luaReturnBool(b);
|
|
}
|
|
|
|
luaFunc(vector_normalize)
|
|
{
|
|
float x = lua_tonumber(L, 1);
|
|
float y = lua_tonumber(L, 2);
|
|
Vector v(x,y);
|
|
v.normalize2D();
|
|
luaReturnVec2(v.x, v.y);
|
|
}
|
|
|
|
luaFunc(vector_getLength)
|
|
{
|
|
float x = lua_tonumber(L, 1);
|
|
float y = lua_tonumber(L, 2);
|
|
Vector v(x,y);
|
|
float len = v.getLength2D();
|
|
luaReturnNum(len);
|
|
}
|
|
|
|
luaFunc(vector_setLength)
|
|
{
|
|
float x = lua_tonumber(L, 1);
|
|
float y = lua_tonumber(L, 2);
|
|
Vector v(x,y);
|
|
v.setLength2D(lua_tonumber(L, 3));
|
|
luaReturnVec2(v.x, v.y);
|
|
}
|
|
|
|
luaFunc(vector_dot)
|
|
{
|
|
float x = lua_tonumber(L, 1);
|
|
float y = lua_tonumber(L, 2);
|
|
float x2 = lua_tonumber(L, 3);
|
|
float y2 = lua_tonumber(L, 4);
|
|
Vector v(x,y);
|
|
Vector v2(x2,y2);
|
|
luaReturnNum(v.dot2D(v2));
|
|
}
|
|
|
|
luaFunc(vector_cap)
|
|
{
|
|
float x = lua_tonumber(L, 1);
|
|
float y = lua_tonumber(L, 2);
|
|
Vector v(x,y);
|
|
v.capLength2D(lua_tonumber(L, 3));
|
|
luaReturnVec2(v.x, v.y);
|
|
}
|
|
|
|
luaFunc(vector_isLength2DIn)
|
|
{
|
|
float x = lua_tonumber(L, 1);
|
|
float y = lua_tonumber(L, 2);
|
|
Vector v(x,y);
|
|
bool ret = v.isLength2DIn(lua_tonumber(L, 3));
|
|
luaReturnBool(ret);
|
|
}
|
|
|
|
luaFunc(entity_push)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->push(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_pushTarget)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
Entity *target = e->getTargetEntity();
|
|
if (target)
|
|
{
|
|
Vector diff = target->position - e->position;
|
|
diff.setLength2D(lua_tointeger(L, 2));
|
|
target->vel += diff;
|
|
}
|
|
}
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getPushDamage)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnNum(e ? e->getPushDamage() : 0.0f);
|
|
}
|
|
|
|
luaFunc(watch)
|
|
{
|
|
float t = lua_tonumber(L, 1);
|
|
int quit = lua_tointeger(L, 2);
|
|
dsq->watch(t, quit);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(wait)
|
|
{
|
|
core->run(lua_tonumber(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(warpNaijaToEntity)
|
|
{
|
|
Entity *e = dsq->getEntityByName(getString(L, 1));
|
|
if (e)
|
|
{
|
|
dsq->overlay->alpha.interpolateTo(1, 1);
|
|
core->run(1);
|
|
|
|
Vector offset(lua_tointeger(L, 2), lua_tointeger(L, 3));
|
|
dsq->game->avatar->position = e->position + offset;
|
|
|
|
dsq->overlay->alpha.interpolateTo(0, 1);
|
|
core->run(1);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(getTimer)
|
|
{
|
|
float n = lua_tonumber(L, 1);
|
|
if (n == 0)
|
|
n = 1;
|
|
luaReturnNum(dsq->game->getTimer(n));
|
|
}
|
|
|
|
luaFunc(getHalfTimer)
|
|
{
|
|
float n = lua_tonumber(L, 1);
|
|
if (n == 0)
|
|
n = 1;
|
|
luaReturnNum(dsq->game->getHalfTimer(n));
|
|
}
|
|
|
|
luaFunc(getOldDT)
|
|
{
|
|
luaReturnNum(core->get_old_dt());
|
|
}
|
|
|
|
luaFunc(getDT)
|
|
{
|
|
luaReturnNum(core->get_current_dt());
|
|
}
|
|
|
|
luaFunc(getFPS)
|
|
{
|
|
luaReturnInt(core->fps);
|
|
}
|
|
|
|
luaFunc(isNested)
|
|
{
|
|
luaReturnBool(core->isNested());
|
|
}
|
|
|
|
luaFunc(getNumberOfEntitiesNamed)
|
|
{
|
|
std::string s = getString(L);
|
|
int c = dsq->game->getNumberOfEntitiesNamed(s);
|
|
luaReturnNum(c);
|
|
}
|
|
|
|
luaFunc(entity_pullEntities)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
Vector pos(lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
float range = lua_tonumber(L, 4);
|
|
float len = lua_tonumber(L, 5);
|
|
float dt = lua_tonumber(L, 6);
|
|
FOR_ENTITIES(i)
|
|
{
|
|
Entity *ent = *i;
|
|
if (ent != e && (e->getEntityType() == ET_ENEMY || e->getEntityType() == ET_AVATAR) && e->isUnderWater())
|
|
{
|
|
Vector diff = ent->position - pos;
|
|
if (diff.isLength2DIn(range))
|
|
{
|
|
Vector pull = pos - ent->position;
|
|
pull.setLength2D(float(len) * dt);
|
|
ent->vel2 += pull;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
// Note that this overrides the generic obj_delete function for entities.
|
|
// (It's registered as "entity_delete" to Lua)
|
|
// There is at least one known case where this is necessary:
|
|
// Avatar::pullTarget does a life check to drop the pointer;
|
|
// If it's instantly deleted, this will cause a crash.
|
|
luaFunc(entity_delete_override)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
float time = lua_tonumber(L, 2);
|
|
if (time == 0)
|
|
{
|
|
e->alpha = 0;
|
|
e->setLife(0);
|
|
e->setDecayRate(1);
|
|
}
|
|
else
|
|
{
|
|
e->fadeAlphaWithLife = true;
|
|
e->setLife(1);
|
|
e->setDecayRate(1.0f/time);
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_isRidingOnEntity)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
luaReturnPtr(e->ridingOnEntity);
|
|
else
|
|
luaReturnPtr(NULL);
|
|
}
|
|
|
|
|
|
luaFunc(entity_isProperty)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool v = false;
|
|
if (e)
|
|
{
|
|
v = e->isEntityProperty((EntityProperty)lua_tointeger(L, 2));
|
|
}
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
|
|
luaFunc(entity_setProperty)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->setEntityProperty((EntityProperty)lua_tointeger(L, 2), getBool(L, 3));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setActivation)
|
|
{
|
|
ScriptedEntity *e = scriptedEntity(L);
|
|
if (e)
|
|
{
|
|
int type = lua_tointeger(L, 2);
|
|
// cursor radius
|
|
float activationRadius = lua_tonumber(L, 3);
|
|
float range = lua_tonumber(L, 4);
|
|
e->activationType = (Entity::ActivationType)type;
|
|
e->activationRange = range;
|
|
e->activationRadius = activationRadius;
|
|
}
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setActivationType)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->activationType = (Entity::ActivationType)lua_tointeger(L, 2);
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_hasTarget)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
luaReturnBool(e->hasTarget(e->currentEntityTarget));
|
|
else
|
|
luaReturnBool(false);
|
|
}
|
|
|
|
luaFunc(entity_hurtTarget)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e && e->getTargetEntity())
|
|
{
|
|
DamageData d;
|
|
d.attacker = e;
|
|
d.damage = lua_tointeger(L, 2);
|
|
e->getTargetEntity(e->currentEntityTarget)->damage(d);
|
|
}
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
// radius dmg speed pushtime
|
|
luaFunc(entity_touchAvatarDamage)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool v = false;
|
|
if (e)
|
|
{
|
|
v = e->touchAvatarDamage(lua_tonumber(L, 2), lua_tonumber(L, 3), Vector(-1,-1,-1), lua_tonumber(L, 4), lua_tonumber(L, 5), Vector(lua_tonumber(L, 6), lua_tonumber(L, 7)));
|
|
}
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(entity_getDistanceToEntity)
|
|
{
|
|
Entity *e = entity(L);
|
|
Entity *e2 = entity(L, 2);
|
|
float d = 0;
|
|
if (e && e2)
|
|
{
|
|
Vector diff = e->position - e2->position;
|
|
d = diff.getLength2D();
|
|
}
|
|
luaReturnNum(d);
|
|
}
|
|
|
|
luaFunc(entity_isEntityInside)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnBool(e ? e->isEntityInside() : false);
|
|
}
|
|
|
|
// entity_istargetInRange
|
|
luaFunc(entity_isTargetInRange)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
luaReturnBool(e->isTargetInRange(lua_tointeger(L, 2), e->currentEntityTarget));
|
|
else
|
|
luaReturnBool(false);
|
|
}
|
|
|
|
luaFunc(randAngle360)
|
|
{
|
|
luaReturnNum(randAngle360());
|
|
}
|
|
|
|
luaFunc(randVector)
|
|
{
|
|
float num = lua_tonumber(L, 1);
|
|
if (num == 0)
|
|
num = 1;
|
|
Vector v = randVector(num);
|
|
luaReturnVec2(v.x, v.y);
|
|
}
|
|
|
|
luaFunc(getNaija)
|
|
{
|
|
luaReturnPtr(dsq->game->avatar);
|
|
}
|
|
|
|
luaFunc(getLi)
|
|
{
|
|
luaReturnPtr(dsq->game->li);
|
|
}
|
|
|
|
luaFunc(setLi)
|
|
{
|
|
dsq->game->li = entity(L);
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_isPositionInRange)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool v = false;
|
|
int x, y;
|
|
x = lua_tonumber(L, 2);
|
|
y = lua_tonumber(L, 3);
|
|
if (e)
|
|
{
|
|
if ((e->position - Vector(x,y)).isLength2DIn(lua_tonumber(L, 4)))
|
|
{
|
|
v = true;
|
|
}
|
|
}
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(entity_isEntityInRange)
|
|
{
|
|
Entity *e1 = entity(L);
|
|
Entity *e2 = entity(L, 2);
|
|
bool v= false;
|
|
if (e1 && e2)
|
|
{
|
|
//v = ((e2->position - e1->position).getSquaredLength2D() < sqr(lua_tonumber(L, 3)));
|
|
v = (e2->position - e1->position).isLength2DIn(lua_tonumber(L, 3));
|
|
}
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
//entity_moveTowardsTarget(spd, dt)
|
|
luaFunc(entity_moveTowardsTarget)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->moveTowardsTarget(lua_tonumber(L, 2), lua_tonumber(L, 3), e->currentEntityTarget);
|
|
}
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
// entity dt speed dir
|
|
luaFunc(entity_moveAroundTarget)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->moveAroundTarget(lua_tonumber(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), e->currentEntityTarget);
|
|
// do stuff
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_rotateToTarget)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
Entity *t = e->getTargetEntity(e->currentEntityTarget);
|
|
if (t)
|
|
{
|
|
Vector v = t->position - e->position;
|
|
e->rotateToVec(v, lua_tonumber(L, 2), lua_tointeger(L, 3));
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_partWidthHeight)
|
|
{
|
|
ScriptedEntity *e = scriptedEntity(L);
|
|
Quad *r = (Quad*)e->partMap[getString(L, 2)];
|
|
if (r)
|
|
{
|
|
int w = lua_tointeger(L, 3);
|
|
int h = lua_tointeger(L, 4);
|
|
r->setWidthHeight(w, h);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_partSetSegs)
|
|
{
|
|
ScriptedEntity *e = scriptedEntity(L);
|
|
Quad *r = (Quad*)e->partMap[getString(L, 2)];
|
|
if (r)
|
|
{
|
|
r->setSegs(lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6), lua_tonumber(L, 7), lua_tonumber(L, 8), lua_tonumber(L, 9), lua_tointeger(L, 10));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getID)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnNum(e ? e->getID() : 0);
|
|
}
|
|
|
|
luaFunc(getEntityByID)
|
|
{
|
|
//debugLog("Calling getEntityByID");
|
|
int v = lua_tointeger(L, 1);
|
|
Entity *found = 0;
|
|
if (v)
|
|
{
|
|
//std::ostringstream os;
|
|
//os << "searching for entity with id: " << v;
|
|
//debugLog(os.str());
|
|
FOR_ENTITIES(i)
|
|
{
|
|
Entity *e = *i;
|
|
if (e->getID() == v)
|
|
{
|
|
found = e;
|
|
break;
|
|
}
|
|
}
|
|
/*if (!found)
|
|
{
|
|
std::ostringstream os;
|
|
os << "entity with id: " << v << " not found!";
|
|
debugLog(os.str());
|
|
}
|
|
else
|
|
{
|
|
std::ostringstream os;
|
|
os << "Found: " << found->name;
|
|
debugLog(os.str());
|
|
}*/
|
|
}
|
|
/*else
|
|
{
|
|
debugLog("entity ID was 0");
|
|
}*/
|
|
luaReturnPtr(found);
|
|
}
|
|
|
|
luaFunc(node_activate)
|
|
{
|
|
Path *p = path(L);
|
|
Entity *e = 0;
|
|
if (lua_touserdata(L, 2) != NULL)
|
|
e = entity(L, 2);
|
|
if (p)
|
|
{
|
|
p->activate(e);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(node_setElementsInLayerActive)
|
|
{
|
|
Path *p = path(L);
|
|
if (p)
|
|
{
|
|
int l = lua_tointeger(L, 2);
|
|
bool v = getBool(L, 3);
|
|
for (Element *e = dsq->getFirstElementOnLayer(l); e; e = e->bgLayerNext)
|
|
{
|
|
if (e && p->isCoordinateInside(e->position))
|
|
{
|
|
e->setElementActive(v);
|
|
}
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(node_getNumEntitiesIn)
|
|
{
|
|
Path *p = path(L);
|
|
std::string name;
|
|
if (lua_isstring(L, 2))
|
|
{
|
|
name = lua_tostring(L, 2);
|
|
}
|
|
int c = 0;
|
|
if (p && !p->nodes.empty())
|
|
{
|
|
FOR_ENTITIES(i)
|
|
{
|
|
Entity *e = *i;
|
|
if (name.empty() || (nocasecmp(e->name, name)==0))
|
|
{
|
|
if (p->isCoordinateInside(e->position))
|
|
{
|
|
c++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
luaReturnNum(c);
|
|
}
|
|
|
|
luaFunc(node_getNearestEntity)
|
|
{
|
|
Path *p = path(L);
|
|
Entity *closest=0;
|
|
|
|
if (p && !p->nodes.empty())
|
|
{
|
|
|
|
Vector pos = p->nodes[0].position;
|
|
std::string name;
|
|
Entity *ignore = 0;
|
|
if (lua_isstring(L, 2))
|
|
name = lua_tostring(L, 2);
|
|
if (lua_isuserdata(L, 3))
|
|
ignore = entity(L, 3);
|
|
|
|
float smallestDist = HUGE_VALF;
|
|
FOR_ENTITIES(i)
|
|
{
|
|
Entity *e = *i;
|
|
if (e != ignore && e->isPresent() && e->isNormalLayer())
|
|
{
|
|
if (name.empty() || (nocasecmp(e->name, name)==0))
|
|
{
|
|
float dist = (pos - e->position).getSquaredLength2D();
|
|
if (dist < smallestDist)
|
|
{
|
|
smallestDist = dist;
|
|
closest = e;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
luaReturnPtr(closest);
|
|
}
|
|
|
|
luaFunc(node_getNearestNode)
|
|
{
|
|
Path *p = path(L);
|
|
Path *closest = 0;
|
|
if (p && !p->nodes.empty())
|
|
{
|
|
std::string name;
|
|
if (lua_isstring(L, 2))
|
|
name = lua_tostring(L, 2);
|
|
Path *ignore = path(L, 3);
|
|
closest = dsq->game->getNearestPath(p->nodes[0].position, name, ignore);
|
|
}
|
|
luaReturnPtr(closest);
|
|
}
|
|
|
|
luaFunc(entity_getNearestBoneToPosition)
|
|
{
|
|
Entity *me = entity(L);
|
|
Vector p(lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
float smallestDist = HUGE_VALF;
|
|
Bone *closest = 0;
|
|
if (me)
|
|
{
|
|
for (size_t i = 0; i < me->skeletalSprite.bones.size(); i++)
|
|
{
|
|
Bone *b = me->skeletalSprite.bones[i];
|
|
float dist = (b->getWorldPosition() - p).getSquaredLength2D();
|
|
if (dist < smallestDist)
|
|
{
|
|
smallestDist = dist;
|
|
closest = b;
|
|
}
|
|
}
|
|
}
|
|
luaReturnPtr(closest);
|
|
}
|
|
|
|
luaFunc(entity_getNearestNode)
|
|
{
|
|
Entity *me = entity(L);
|
|
Path *closest = 0;
|
|
if (me)
|
|
{
|
|
std::string name;
|
|
if (lua_isstring(L, 2))
|
|
name = lua_tostring(L, 2);
|
|
Path *ignore = path(L, 3);
|
|
closest = dsq->game->getNearestPath(me->position, name, ignore);
|
|
}
|
|
luaReturnPtr(closest);
|
|
}
|
|
|
|
luaFunc(ing_hasIET)
|
|
{
|
|
Ingredient *i = getIng(L, 1);
|
|
bool has = i && i->hasIET((IngredientEffectType)lua_tointeger(L, 2));
|
|
luaReturnBool(has);
|
|
}
|
|
|
|
luaFunc(ing_getIngredientName)
|
|
{
|
|
Ingredient *i = getIng(L, 1);
|
|
IngredientData *data = i ? i->getIngredientData() : 0;
|
|
luaReturnStr(data ? data->name.c_str() : "");
|
|
}
|
|
|
|
luaFunc(entity_getNearestEntity)
|
|
{
|
|
Entity *me = entity(L);
|
|
if (!me)
|
|
luaReturnPtr(0);
|
|
|
|
const char *name = 0;
|
|
if (lua_isstring(L, 2))
|
|
{
|
|
name = lua_tostring(L, 2);
|
|
if (!*name)
|
|
name = NULL;
|
|
}
|
|
|
|
bool nameCheck = true;
|
|
if (name && (name[0] == '!' || name[0] == '~'))
|
|
{
|
|
name++;
|
|
nameCheck = false;
|
|
}
|
|
|
|
float range = lua_tonumber(L, 3);
|
|
EntityType type = ET_NOTYPE;
|
|
if (lua_isnumber(L, 4))
|
|
type = (EntityType)lua_tointeger(L, 4);
|
|
|
|
DamageType damageTarget = DT_NONE;
|
|
if (lua_isnumber(L, 5))
|
|
damageTarget = (DamageType)lua_tointeger(L, 5);
|
|
Entity *closest = 0;
|
|
Entity *ignore = 0;
|
|
if (lua_isuserdata(L, 6))
|
|
ignore = entity(L, 6);
|
|
|
|
float smallestDist = range ? sqr(range) : HUGE_VALF;
|
|
FOR_ENTITIES(i)
|
|
{
|
|
Entity *e = *i;
|
|
if (e != me && e != ignore && e->isPresent() && e->isNormalLayer())
|
|
{
|
|
if (type == ET_NOTYPE || e->getEntityType() == type)
|
|
{
|
|
if (damageTarget == DT_NONE || e->isDamageTarget((DamageType)damageTarget))
|
|
{
|
|
if (!name || ((nocasecmp(e->name, name)==0) == nameCheck))
|
|
{
|
|
float dist = (me->position - e->position).getSquaredLength2D();
|
|
if (dist < smallestDist)
|
|
{
|
|
smallestDist = dist;
|
|
closest = e;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
luaReturnPtr(closest);
|
|
}
|
|
|
|
luaFunc(getNearestEntity)
|
|
{
|
|
Vector p(lua_tonumber(L, 1), lua_tonumber(L, 2));
|
|
float radius = lua_tonumber(L, 3);
|
|
Entity *ignore = lua_isuserdata(L, 4) ? entity(L, 4) : NULL;
|
|
//EntityType et = lua_isnumber(L, 5) ? (EntityType)lua_tointeger(L, 5) : ET_NOTYPE;
|
|
DamageType dt = lua_isnumber(L, 6) ? (DamageType)lua_tointeger(L, 6) : DT_NONE;
|
|
int lrStart = lua_isnumber(L, 7) ? lua_tointeger(L, 7) : -1;
|
|
int lrEnd = lua_isnumber(L, 8) ? lua_tointeger(L, 8) : -1;
|
|
|
|
Entity *target = dsq->game->getNearestEntity(p, radius, ignore, ET_ENEMY, dt, lrStart, lrEnd);
|
|
luaReturnPtr(target);
|
|
}
|
|
|
|
luaFunc(findWall)
|
|
{
|
|
float x = lua_tonumber(L, 1);
|
|
float y = lua_tonumber(L, 2);
|
|
int dirx = lua_tointeger(L, 3);
|
|
int diry = lua_tointeger(L, 4);
|
|
if (dirx == 0 && diry == 0){ debugLog("dirx && diry are zero!"); luaReturnNum(0); }
|
|
|
|
TileVector t(Vector(x, y));
|
|
while (!dsq->game->isObstructed(t))
|
|
{
|
|
t.x += dirx;
|
|
t.y += diry;
|
|
}
|
|
Vector v = t.worldVector();
|
|
int wall = 0;
|
|
if (diry != 0) wall = v.y;
|
|
if (dirx != 0) wall = v.x;
|
|
luaReturnNum(wall);
|
|
}
|
|
|
|
luaFunc(toggleVersionLabel)
|
|
{
|
|
bool on = getBool(L, 1);
|
|
|
|
dsq->toggleVersionLabel(on);
|
|
|
|
luaReturnBool(on);
|
|
}
|
|
|
|
luaFunc(setVersionLabelText)
|
|
{
|
|
dsq->setVersionLabelText();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setCutscene)
|
|
{
|
|
dsq->setCutscene(getBool(L, 1), getBool(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(isInCutscene)
|
|
{
|
|
luaReturnBool(dsq->isInCutscene());
|
|
}
|
|
|
|
luaFunc(toggleSteam)
|
|
{
|
|
bool on = getBool(L, 1);
|
|
for (Path *p = dsq->game->getFirstPathOfType(PATH_STEAM); p; p = p->nextOfType)
|
|
{
|
|
p->setActive(on);
|
|
}
|
|
luaReturnBool(on);
|
|
}
|
|
|
|
luaFunc(getFirstEntity)
|
|
{
|
|
luaReturnPtr(dsq->getFirstEntity());
|
|
}
|
|
|
|
luaFunc(getNextEntity)
|
|
{
|
|
luaReturnPtr(dsq->getNextEntity());
|
|
}
|
|
|
|
typedef std::pair<Entity*, float> EntityDistancePair;
|
|
static std::vector<EntityDistancePair> filteredEntities(20);
|
|
static int filteredEntityIdx = 0;
|
|
|
|
static bool _entityDistanceCmp(const EntityDistancePair& a, const EntityDistancePair& b)
|
|
{
|
|
return a.second < b.second;
|
|
}
|
|
static bool _entityDistanceEq(const EntityDistancePair& a, const EntityDistancePair& b)
|
|
{
|
|
return a.first == b.first;
|
|
}
|
|
|
|
static size_t _entityFilter(lua_State *L)
|
|
{
|
|
const Vector p(lua_tonumber(L, 1), lua_tonumber(L, 2));
|
|
const float radius = lua_tonumber(L, 3);
|
|
const Entity *ignore = lua_isuserdata(L, 4) ? entity(L, 4) : NULL;
|
|
const EntityType et = lua_isnumber(L, 5) ? (EntityType)lua_tointeger(L, 5) : ET_NOTYPE;
|
|
const DamageType dt = lua_isnumber(L, 6) ? (DamageType)lua_tointeger(L, 6) : DT_NONE;
|
|
const unsigned lrStart = lua_isnumber(L, 7) ? lua_tointeger(L, 7) : -1;
|
|
const unsigned lrEnd = lua_isnumber(L, 8) ? lua_tointeger(L, 8) : -1;
|
|
|
|
const float sqrRadius = radius * radius;
|
|
float distsq;
|
|
const bool skipLayerCheck = lrStart == -1 || lrEnd == -1;
|
|
const bool skipRadiusCheck = radius <= 0;
|
|
size_t added = 0;
|
|
FOR_ENTITIES(i)
|
|
{
|
|
Entity *e = *i;
|
|
distsq = (e->position - p).getSquaredLength2D();
|
|
if (skipRadiusCheck || distsq <= sqrRadius)
|
|
{
|
|
if (e != ignore && e->isPresent())
|
|
{
|
|
if (skipLayerCheck || (e->layer >= lrStart && e->layer <= lrEnd))
|
|
{
|
|
if (et == ET_NOTYPE || e->getEntityType() == et)
|
|
{
|
|
if (dt == DT_NONE || e->isDamageTarget(dt))
|
|
{
|
|
filteredEntities.push_back(std::make_pair(e, distsq));
|
|
++added;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(added)
|
|
{
|
|
std::sort(filteredEntities.begin(), filteredEntities.end(), _entityDistanceCmp);
|
|
std::vector<EntityDistancePair>::iterator newend = std::unique(filteredEntities.begin(), filteredEntities.end(), _entityDistanceEq);
|
|
filteredEntities.resize(std::distance(filteredEntities.begin(), newend));
|
|
}
|
|
|
|
// Add terminator if there is none
|
|
if(filteredEntities.size() && filteredEntities.back().first)
|
|
filteredEntities.push_back(std::make_pair((Entity*)NULL, 0.0f)); // terminator
|
|
|
|
filteredEntityIdx = 0; // Reset getNextFilteredEntity() iteration index
|
|
|
|
return added;
|
|
}
|
|
|
|
luaFunc(filterNearestEntities)
|
|
{
|
|
filteredEntities.clear();
|
|
luaReturnInt(_entityFilter(L));
|
|
}
|
|
|
|
luaFunc(filterNearestEntitiesAdd)
|
|
{
|
|
// Remove terminator if there is one
|
|
if(filteredEntities.size() && !filteredEntities.back().first)
|
|
filteredEntities.pop_back();
|
|
luaReturnInt(_entityFilter(L));
|
|
}
|
|
|
|
luaFunc(getNextFilteredEntity)
|
|
{
|
|
const EntityDistancePair& ep = filteredEntities[filteredEntityIdx];
|
|
luaPushPointer(L, ep.first);
|
|
lua_pushnumber(L, ep.second);
|
|
if (ep.first)
|
|
++filteredEntityIdx;
|
|
return 2;
|
|
}
|
|
|
|
// MISSING FOR ANDROID COMPAT
|
|
//luaFunc(getEntityList)
|
|
//luaFunc(entity_getEntityListInRange) // (me, range)
|
|
//luaFunc(vector_getEntityListInRange) // (x, y, range)
|
|
|
|
luaFunc(getEntity)
|
|
{
|
|
Entity *ent = 0;
|
|
// THIS WAS IMPORTANT: this was for getting entity by NUMBER IN LIST used for looping through all entities in script
|
|
if (lua_isnumber(L, 1))
|
|
{
|
|
//HACK: FIX:
|
|
// this has been disabled due to switching to list based entities
|
|
}
|
|
else if (lua_isstring(L, 1))
|
|
{
|
|
std::string s = lua_tostring(L, 1);
|
|
ent = dsq->getEntityByName(s);
|
|
}
|
|
luaReturnPtr(ent);
|
|
}
|
|
|
|
luaFunc(entity_partAlpha)
|
|
{
|
|
ScriptedEntity *e = scriptedEntity(L);
|
|
if (e)
|
|
{
|
|
RenderObject *r = e->partMap[getString(L, 2)];
|
|
if (r)
|
|
{
|
|
float start = lua_tonumber(L, 3);
|
|
if (start != -1)
|
|
r->alpha = start;
|
|
interpolateVec1(L, r->alpha, 4);
|
|
}
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_partBlendType)
|
|
{
|
|
ScriptedEntity *e = scriptedEntity(L);
|
|
if (e)
|
|
e->partMap[getString(L, 2)]->setBlendType(lua_tointeger(L, 3));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_partRotate)
|
|
{
|
|
ScriptedEntity *e = scriptedEntity(L);
|
|
if (e)
|
|
{
|
|
RenderObject *r = e->partMap[getString(L, 2)];
|
|
if (r)
|
|
interpolateVec1z(L, r->rotation, 3);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getStateTime)
|
|
{
|
|
Entity *e = entity(L);
|
|
float t = 0;
|
|
if (e)
|
|
t = e->getStateTime();
|
|
luaReturnNum(t);
|
|
}
|
|
|
|
luaFunc(entity_setStateTime)
|
|
{
|
|
Entity *e = entity(L);
|
|
float t = lua_tonumber(L, 2);
|
|
if (e)
|
|
e->setStateTime(t);
|
|
luaReturnNum(t);
|
|
}
|
|
|
|
luaFunc(entity_offsetUpdate)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
float uc = e->updateCull;
|
|
e->updateCull = -1;
|
|
float t = float(rand()%10000)/1000.0f;
|
|
e->update(t);
|
|
e->updateCull = uc;
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
// not to be confused with obj_setLayer or entity_setEntityLayer!!
|
|
luaFunc(entity_switchLayer)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
int lcode = lua_tointeger(L, 2);
|
|
int toLayer = LR_ENTITIES;
|
|
|
|
toLayer = dsq->getEntityLayerToLayer(lcode);
|
|
|
|
if (e->getEntityType() == ET_AVATAR)
|
|
toLayer = LR_ENTITIES;
|
|
|
|
core->switchRenderObjectLayer(e, toLayer);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
// entity numSegments segmentLength width texture
|
|
luaFunc(entity_initHair)
|
|
{
|
|
Entity *se = entity(L);
|
|
if (se)
|
|
{
|
|
se->initHair(lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4), getString(L, 5));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getHair)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnPtr(e ? e->hair : NULL);
|
|
}
|
|
|
|
luaFunc(entity_clearHair)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e && e->hair)
|
|
{
|
|
e->hair->safeKill();
|
|
e->hair = 0;
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getHairPosition)
|
|
{
|
|
Entity *se = entity(L);
|
|
float x=0;
|
|
float y=0;
|
|
int idx = lua_tointeger(L, 2);
|
|
if (se && se->hair)
|
|
{
|
|
HairNode *h = se->hair->getHairNode(idx);
|
|
if (h)
|
|
{
|
|
x = h->position.x;
|
|
y = h->position.y;
|
|
}
|
|
}
|
|
luaReturnVec2(x, y);
|
|
}
|
|
|
|
// entity x y z
|
|
luaFunc(entity_setHairHeadPosition)
|
|
{
|
|
Entity *se = entity(L);
|
|
if (se)
|
|
{
|
|
se->setHairHeadPosition(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_updateHair)
|
|
{
|
|
Entity *se = entity(L);
|
|
if (se)
|
|
{
|
|
se->updateHair(lua_tonumber(L, 2));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
// entity x y dt
|
|
luaFunc(entity_exertHairForce)
|
|
{
|
|
ScriptedEntity *se = scriptedEntity(L);
|
|
if (se)
|
|
{
|
|
if (se->hair)
|
|
se->hair->exertForce(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), lua_tonumber(L, 4), lua_tonumber(L, 5));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_initPart)
|
|
{
|
|
std::string partName(getString(L, 2));
|
|
std::string partTex(getString(L, 3));
|
|
Vector partPosition(lua_tonumber(L, 4), lua_tonumber(L, 5));
|
|
bool renderAfter = getBool(L, 6);
|
|
bool partFlipH = getBool(L, 7);
|
|
bool partFlipV = getBool(L,8);
|
|
Vector offsetInterpolateTo(lua_tonumber(L, 9), lua_tonumber(L, 10));
|
|
float offsetInterpolateTime = lua_tonumber(L, 11);
|
|
|
|
|
|
ScriptedEntity *e = scriptedEntity(L);
|
|
if (e)
|
|
{
|
|
Quad *q = new Quad;
|
|
q->setTexture(partTex);
|
|
q->renderBeforeParent = !renderAfter;
|
|
|
|
|
|
q->position = partPosition;
|
|
if (offsetInterpolateTo.x != 0 || offsetInterpolateTo.y != 0)
|
|
q->offset.interpolateTo(offsetInterpolateTo, offsetInterpolateTime, -1, 1, 1);
|
|
if (partFlipH)
|
|
q->flipHorizontal();
|
|
if (partFlipV)
|
|
q->flipVertical();
|
|
|
|
e->addChild(q, PM_POINTER);
|
|
e->registerNewPart(q, partName);
|
|
}
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_findTarget)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->findTarget(lua_tointeger(L, 2), lua_tointeger(L, 3), e->currentEntityTarget);
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_doFriction)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
e->doFriction(lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_doGlint)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
e->doGlint(e->position, Vector(2,2), getString(L,2), (RenderObject::BlendTypes)lua_tointeger(L, 3));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getTarget)
|
|
{
|
|
Entity *e = entity(L);
|
|
Entity *retEnt = NULL;
|
|
if (e)
|
|
{
|
|
retEnt = e->getTargetEntity(lua_tonumber(L, 2));
|
|
|
|
}
|
|
luaReturnPtr(retEnt);
|
|
}
|
|
|
|
luaFunc(entity_getTargetPositionX)
|
|
{
|
|
Entity *e = entity(L);
|
|
Entity *t = e ? e->getTargetEntity() : NULL;
|
|
luaReturnNum(t ? t->position.x : 0.0f);
|
|
}
|
|
|
|
luaFunc(entity_getTargetPositionY)
|
|
{
|
|
Entity *e = entity(L);
|
|
Entity *t = e ? e->getTargetEntity() : NULL;
|
|
luaReturnNum(t ? t->position.y : 0.0f);
|
|
}
|
|
|
|
luaFunc(entity_isNearObstruction)
|
|
{
|
|
Entity *e = entity(L);
|
|
int sz = lua_tointeger(L, 2);
|
|
int type = lua_tointeger(L, 3);
|
|
bool v = false;
|
|
if (e)
|
|
{
|
|
v = e->isNearObstruction(sz, type);
|
|
}
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(entity_isInvincible)
|
|
{
|
|
Entity *e = entity(L);
|
|
bool v = false;
|
|
if (e)
|
|
{
|
|
v = e->isInvincible();
|
|
}
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(entity_setEatType)
|
|
{
|
|
Entity *e = entity(L);
|
|
int et = lua_tointeger(L, 2);
|
|
if (e)
|
|
e->setEatType((EatType)et, getString(L, 3));
|
|
luaReturnInt(et);
|
|
}
|
|
|
|
luaFunc(getMapName)
|
|
{
|
|
luaReturnStr(dsq->game->sceneName.c_str());
|
|
}
|
|
|
|
luaFunc(isMapName)
|
|
{
|
|
std::string s1 = dsq->game->sceneName;
|
|
std::string s2 = getString(L, 1);
|
|
stringToUpper(s1);
|
|
stringToUpper(s2);
|
|
bool ret = (s1 == s2);
|
|
|
|
luaReturnBool(ret);
|
|
}
|
|
|
|
luaFunc(mapNameContains)
|
|
{
|
|
std::string s = dsq->game->sceneName;
|
|
stringToLower(s);
|
|
bool b = (s.find(getString(L, 1)) != std::string::npos);
|
|
luaReturnBool(b);
|
|
}
|
|
|
|
luaFunc(entity_fireGas)
|
|
{
|
|
Entity *e = entity(L);
|
|
if (e)
|
|
{
|
|
int radius = lua_tointeger(L, 2);
|
|
float life = lua_tonumber(L, 3);
|
|
float damage = lua_tonumber(L, 4);
|
|
std::string gfx = getString(L, 5);
|
|
float colorx = lua_tonumber(L, 6);
|
|
float colory = lua_tonumber(L, 7);
|
|
float colorz = lua_tonumber(L, 8);
|
|
float offx = lua_tonumber(L, 9);
|
|
float offy = lua_tonumber(L, 10);
|
|
float poisonTime = lua_tonumber(L, 11);
|
|
|
|
GasCloud *c = new GasCloud(e, e->position + Vector(offx, offy), gfx, Vector(colorx, colory, colorz), radius, life, damage, false, poisonTime);
|
|
core->getTopStateData()->addRenderObject(c, LR_PARTICLES);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(isInputEnabled)
|
|
{
|
|
luaReturnBool(dsq->game->avatar->isInputEnabled());
|
|
}
|
|
|
|
luaFunc(enableInput)
|
|
{
|
|
dsq->game->avatar->enableInput();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(disableInput)
|
|
{
|
|
dsq->game->avatar->disableInput();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(getInputMode)
|
|
{
|
|
luaReturnInt(dsq->inputMode);
|
|
}
|
|
|
|
static Joystick *_getJoystick(lua_State *L, int idx = 1)
|
|
{
|
|
int source = lua_tointeger(L, idx) - 1;
|
|
if(source < 0)
|
|
return core->getJoystick(0); // HACK: FIXME: do something sensible instead
|
|
|
|
return core->getJoystickForSourceID(source);
|
|
}
|
|
|
|
luaFunc(getJoystickAxisLeft)
|
|
{
|
|
Vector v;
|
|
if(Joystick *j = _getJoystick(L))
|
|
v = j->position;
|
|
luaReturnVec2(v.x, v.y);
|
|
}
|
|
|
|
luaFunc(getJoystickAxisRight)
|
|
{
|
|
Vector v;
|
|
if(Joystick *j = _getJoystick(L))
|
|
v = j->rightStick;
|
|
luaReturnVec2(v.x, v.y);
|
|
}
|
|
|
|
luaFunc(quit)
|
|
{
|
|
#ifdef AQUARIA_DEMO
|
|
dsq->nag(NAG_QUIT);
|
|
#else
|
|
dsq->quit();
|
|
#endif
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(doModSelect)
|
|
{
|
|
dsq->doModSelect();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(doLoadMenu)
|
|
{
|
|
dsq->doLoadMenu();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(resetContinuity)
|
|
{
|
|
dsq->continuity.reset();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(toWindowFromWorld)
|
|
{
|
|
float x = lua_tonumber(L, 1);
|
|
float y = lua_tonumber(L, 2);
|
|
x = x - core->screenCenter.x;
|
|
y = y - core->screenCenter.y;
|
|
x *= core->globalScale.x;
|
|
y *= core->globalScale.x;
|
|
x = 400+x;
|
|
y = 300+y;
|
|
luaReturnVec2(x, y);
|
|
}
|
|
|
|
luaFunc(setMousePos)
|
|
{
|
|
core->setMousePosition(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(getMousePos)
|
|
{
|
|
luaReturnVec2(core->mouse.position.x, core->mouse.position.y);
|
|
}
|
|
|
|
luaFunc(getMouseWorldPos)
|
|
{
|
|
Vector v = dsq->getGameCursorPosition();
|
|
luaReturnVec2(v.x, v.y);
|
|
}
|
|
|
|
luaFunc(getMouseWheelChange)
|
|
{
|
|
luaReturnNum(core->mouse.scrollWheelChange);
|
|
}
|
|
|
|
luaFunc(setMouseConstraintCircle)
|
|
{
|
|
core->setMouseConstraintCircle(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)), lua_tonumber(L, 3));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setMouseConstraint)
|
|
{
|
|
core->setMouseConstraint(getBool(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(fade)
|
|
{
|
|
dsq->overlay->color.interpolateTo(Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5)), lua_tonumber(L, 6));
|
|
dsq->overlay->alpha.interpolateTo(lua_tonumber(L, 1), lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(fade2)
|
|
{
|
|
dsq->overlay2->color.interpolateTo(Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5)), lua_tonumber(L, 6));
|
|
dsq->overlay2->alpha.interpolateTo(lua_tonumber(L, 1), lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(fade3)
|
|
{
|
|
dsq->overlay3->color.interpolateTo(Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5)), lua_tonumber(L, 6));
|
|
dsq->overlay3->alpha.interpolateTo(lua_tonumber(L, 1), lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(vision)
|
|
{
|
|
dsq->vision(getString(L, 1), lua_tonumber(L, 2), getBool(L, 3));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(musicVolume)
|
|
{
|
|
dsq->sound->setMusicFader(lua_tonumber(L, 1), lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(voice)
|
|
{
|
|
float vmod = lua_tonumber(L, 2);
|
|
if (vmod == 0)
|
|
vmod = -1;
|
|
else if (vmod == -1)
|
|
vmod = 0;
|
|
dsq->voice(getString(L, 1), vmod);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(voiceOnce)
|
|
{
|
|
dsq->voiceOnce(getString(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(voiceInterupt)
|
|
{
|
|
dsq->voiceInterupt(getString(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(stopVoice)
|
|
{
|
|
dsq->stopVoice();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(stopAllSfx)
|
|
{
|
|
dsq->sound->stopAllSfx();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(stopAllVoice)
|
|
{
|
|
dsq->sound->stopAllVoice();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(fadeIn)
|
|
{
|
|
dsq->overlay->alpha.interpolateTo(0, lua_tonumber(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(fadeOut)
|
|
{
|
|
dsq->overlay->color = 0;
|
|
dsq->overlay->alpha.interpolateTo(1, lua_tonumber(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setWeight)
|
|
{
|
|
CollideEntity *e = collideEntity(L);
|
|
if (e)
|
|
e->weight = lua_tonumber(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getWeight)
|
|
{
|
|
CollideEntity *e = collideEntity(L);
|
|
luaReturnNum(e ? e->weight : 0.0f);
|
|
}
|
|
|
|
luaFunc(pickupGem)
|
|
{
|
|
dsq->continuity.pickupGem(getString(L), !getBool(L, 2));
|
|
luaReturnInt(dsq->continuity.gems.size() - 1);
|
|
}
|
|
|
|
luaFunc(setGemPosition)
|
|
{
|
|
size_t gemId = lua_tointeger(L, 1);
|
|
std::string mapname = getString(L, 4);
|
|
if(mapname.empty())
|
|
mapname = dsq->game->sceneName;
|
|
Vector pos(lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
bool result = false;
|
|
|
|
WorldMapTile *tile = dsq->continuity.worldMap.getWorldMapTile(mapname);
|
|
if(tile)
|
|
{
|
|
pos = dsq->game->worldMapRender->getWorldToTile(tile, pos, true, true);
|
|
if(gemId < dsq->continuity.gems.size())
|
|
{
|
|
Continuity::Gems::iterator it = dsq->continuity.gems.begin();
|
|
std::advance(it, gemId);
|
|
GemData& gem = *it;
|
|
gem.pos = pos;
|
|
gem.mapName = mapname;
|
|
result = true;
|
|
}
|
|
else
|
|
{
|
|
debugLog("setGemPosition: invalid index");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
debugLog("setGemPosition: Map tile does not exist: " + mapname);
|
|
}
|
|
luaReturnBool(result);
|
|
}
|
|
|
|
luaFunc(setGemName)
|
|
{
|
|
size_t gemId = lua_tointeger(L, 1);
|
|
bool result = false;
|
|
|
|
if(gemId < dsq->continuity.gems.size())
|
|
{
|
|
Continuity::Gems::iterator it = dsq->continuity.gems.begin();
|
|
std::advance(it, gemId);
|
|
GemData& gem = *it;
|
|
gem.name = getString(L, 2);
|
|
result = true;
|
|
}
|
|
else
|
|
debugLog("setGemName: invalid index");
|
|
|
|
luaReturnBool(result);
|
|
}
|
|
|
|
luaFunc(setGemBlink)
|
|
{
|
|
size_t gemId = lua_tointeger(L, 1);
|
|
bool result = false;
|
|
|
|
if(gemId < dsq->continuity.gems.size())
|
|
{
|
|
Continuity::Gems::iterator it = dsq->continuity.gems.begin();
|
|
std::advance(it, gemId);
|
|
GemData& gem = *it;
|
|
gem.blink = getBool(L, 2);
|
|
result = true;
|
|
}
|
|
else
|
|
debugLog("setGemBlink: invalid index");
|
|
|
|
luaReturnBool(result);
|
|
}
|
|
|
|
luaFunc(removeGem)
|
|
{
|
|
size_t gemId = lua_tointeger(L, 1);
|
|
if(gemId < dsq->continuity.gems.size())
|
|
{
|
|
Continuity::Gems::iterator it = dsq->continuity.gems.begin();
|
|
std::advance(it, gemId);
|
|
dsq->continuity.removeGemData(&(*it));
|
|
if(dsq->game->worldMapRender->isOn())
|
|
dsq->game->worldMapRender->fixGems();
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(beaconEffect)
|
|
{
|
|
int index = lua_tointeger(L, 1);
|
|
|
|
BeaconData *b = dsq->continuity.getBeaconByIndex(index);
|
|
|
|
float p1 = 0.7f;
|
|
float p2 = 1.0f - p1;
|
|
|
|
dsq->clickRingEffect(dsq->game->miniMapRender->getWorldPosition(), 0, (b->color*p1) + Vector(p2, p2, p2), 1);
|
|
dsq->clickRingEffect(dsq->game->miniMapRender->getWorldPosition(), 1, (b->color*p1) + Vector(p2, p2, p2), 1);
|
|
|
|
dsq->sound->playSfx("ping");
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setBeacon)
|
|
{
|
|
int index = lua_tointeger(L, 1);
|
|
|
|
bool v = getBool(L, 2);
|
|
|
|
Vector pos;
|
|
pos.x = lua_tonumber(L, 3);
|
|
pos.y = lua_tonumber(L, 4);
|
|
|
|
Vector color;
|
|
color.x = lua_tonumber(L, 5);
|
|
color.y = lua_tonumber(L, 6);
|
|
color.z = lua_tonumber(L, 7);
|
|
|
|
dsq->continuity.setBeacon(index, v, pos, color);
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(getBeacon)
|
|
{
|
|
int index = lua_tointeger(L, 1);
|
|
bool v = false;
|
|
|
|
if (dsq->continuity.getBeaconByIndex(index))
|
|
{
|
|
v = true;
|
|
}
|
|
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(getCostume)
|
|
{
|
|
luaReturnStr(dsq->continuity.costume.c_str());
|
|
}
|
|
|
|
luaFunc(setCostume)
|
|
{
|
|
dsq->continuity.setCostume(getString(L));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setLayerRenderPass)
|
|
{
|
|
size_t layer = lua_tointeger(L, 1);
|
|
int startPass = lua_tointeger(L, 2);
|
|
int endPass = lua_tointeger(L, 3);
|
|
if(layer < core->renderObjectLayers.size())
|
|
{
|
|
core->renderObjectLayers[layer].startPass = startPass;
|
|
core->renderObjectLayers[layer].endPass = endPass;
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setElementLayerVisible)
|
|
{
|
|
int l = lua_tointeger(L, 1);
|
|
bool v = getBool(L, 2);
|
|
dsq->game->setElementLayerVisible(l, v);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(isElementLayerVisible)
|
|
{
|
|
luaReturnBool(dsq->game->isElementLayerVisible(lua_tonumber(L, 1)));
|
|
}
|
|
|
|
luaFunc(isStreamingVoice)
|
|
{
|
|
bool v = dsq->sound->isPlayingVoice();
|
|
luaReturnBool(v);
|
|
}
|
|
|
|
luaFunc(isObstructed)
|
|
{
|
|
int obs = lua_tointeger(L, 3);
|
|
luaReturnBool(dsq->game->isObstructed(TileVector(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2))), obs ? obs : -1));
|
|
}
|
|
|
|
luaFunc(isObstructedRaw)
|
|
{
|
|
int obs = lua_tointeger(L, 3);
|
|
luaReturnBool(dsq->game->isObstructedRaw(TileVector(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2))), obs));
|
|
}
|
|
|
|
luaFunc(getObstruction)
|
|
{
|
|
luaReturnInt(dsq->game->getGrid(TileVector(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)))));
|
|
}
|
|
|
|
luaFunc(getGridRaw)
|
|
{
|
|
luaReturnInt(dsq->game->getGridRaw(TileVector(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)))));
|
|
}
|
|
|
|
luaFunc(isObstructedBlock)
|
|
{
|
|
float x = lua_tonumber(L, 1);
|
|
float y = lua_tonumber(L, 2);
|
|
int span = lua_tointeger(L, 3);
|
|
TileVector t(Vector(x,y));
|
|
|
|
bool obs = false;
|
|
for (int xx = t.x-span; xx <= t.x+span; xx++)
|
|
{
|
|
for (int yy = t.y-span; yy <= t.y+span; yy++)
|
|
{
|
|
if (dsq->game->isObstructed(TileVector(xx, yy)))
|
|
{
|
|
obs = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
luaReturnBool(obs);
|
|
}
|
|
|
|
luaFunc(node_getFlag)
|
|
{
|
|
Path *p = path(L);
|
|
int v = 0;
|
|
if (p)
|
|
{
|
|
v = dsq->continuity.getPathFlag(p);
|
|
}
|
|
luaReturnNum(v);
|
|
}
|
|
|
|
luaFunc(node_isFlag)
|
|
{
|
|
Path *p = path(L);
|
|
int c = lua_tointeger(L, 2);
|
|
bool ret = false;
|
|
if (p)
|
|
{
|
|
ret = (c == dsq->continuity.getPathFlag(p));
|
|
}
|
|
luaReturnBool(ret);
|
|
}
|
|
|
|
luaFunc(node_setFlag)
|
|
{
|
|
Path *p = path(L);
|
|
int v = lua_tointeger(L, 2);
|
|
if (p)
|
|
{
|
|
dsq->continuity.setPathFlag(p, v);
|
|
}
|
|
luaReturnNum(v);
|
|
}
|
|
|
|
luaFunc(entity_isFlag)
|
|
{
|
|
Entity *e = entity(L);
|
|
int v = lua_tointeger(L, 2);
|
|
bool b = false;
|
|
if (e)
|
|
{
|
|
b = (dsq->continuity.getEntityFlag(dsq->game->sceneName, e->getID())==v);
|
|
}
|
|
luaReturnBool(b);
|
|
}
|
|
|
|
luaFunc(entity_setFlag)
|
|
{
|
|
Entity *e = entity(L);
|
|
int v = lua_tointeger(L, 2);
|
|
if (e)
|
|
{
|
|
dsq->continuity.setEntityFlag(dsq->game->sceneName, e->getID(), v);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_setPoison)
|
|
{
|
|
Entity *e = entity(L);
|
|
if(e)
|
|
e->setPoison(lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_getPoison)
|
|
{
|
|
Entity *e = entity(L);
|
|
luaReturnNum(e ? e->getPoison() : 0.0f);
|
|
}
|
|
|
|
luaFunc(entity_getFlag)
|
|
{
|
|
Entity *e = entity(L);
|
|
int ret = 0;
|
|
if (e)
|
|
{
|
|
ret = dsq->continuity.getEntityFlag(dsq->game->sceneName, e->getID());
|
|
}
|
|
luaReturnNum(ret);
|
|
}
|
|
|
|
luaFunc(isFlag)
|
|
{
|
|
int v = 0;
|
|
|
|
bool f = false;
|
|
if (lua_isnumber(L, 1))
|
|
{
|
|
v = dsq->continuity.getFlag(lua_tointeger(L, 1));
|
|
f = (v == lua_tointeger(L, 2));
|
|
}
|
|
else
|
|
{
|
|
v = dsq->continuity.getFlag(getString(L, 1));
|
|
f = (v == lua_tointeger(L, 2));
|
|
}
|
|
|
|
luaReturnBool(f);
|
|
}
|
|
|
|
luaFunc(avatar_updatePosition)
|
|
{
|
|
dsq->game->avatar->updatePosition();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(avatar_toggleMovement)
|
|
{
|
|
dsq->game->avatar->toggleMovement(getBool(L));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(clearShots)
|
|
{
|
|
Shot::killAllShots();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(clearHelp)
|
|
{
|
|
float t = 0.4f;
|
|
|
|
RenderObjectLayer *rl = &core->renderObjectLayers[LR_HELP];
|
|
RenderObject *ro = rl->getFirst();
|
|
while (ro)
|
|
{
|
|
ro->setLife(t);
|
|
ro->setDecayRate(1);
|
|
ro->alpha.stopPath();
|
|
ro->alpha.interpolateTo(0,t-0.01f);
|
|
|
|
ro = rl->getNext();
|
|
}
|
|
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setLiPower)
|
|
{
|
|
float m = lua_tonumber(L, 1);
|
|
float t = lua_tonumber(L, 2);
|
|
dsq->continuity.setLiPower(m, t);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(getLiPower)
|
|
{
|
|
luaReturnNum(dsq->continuity.liPower);
|
|
}
|
|
|
|
luaFunc(getPetPower)
|
|
{
|
|
luaReturnNum(dsq->continuity.petPower);
|
|
}
|
|
|
|
luaFunc(appendUserDataPath)
|
|
{
|
|
std::string path = getString(L, 1);
|
|
|
|
if (!dsq->getUserDataFolder().empty())
|
|
path = dsq->getUserDataFolder() + "/" + path;
|
|
|
|
luaReturnStr(path.c_str());
|
|
}
|
|
|
|
luaFunc(getScreenVirtualOff)
|
|
{
|
|
luaReturnVec2(core->getVirtualOffX(), core->getVirtualOffY());
|
|
}
|
|
|
|
luaFunc(getScreenSize)
|
|
{
|
|
luaReturnVec2(core->width, core->height);
|
|
}
|
|
|
|
luaFunc(getScreenVirtualSize)
|
|
{
|
|
luaReturnVec2(core->getVirtualWidth(), core->getVirtualHeight());
|
|
}
|
|
|
|
luaFunc(isMiniMapCursorOkay)
|
|
{
|
|
luaReturnBool(dsq->isMiniMapCursorOkay());
|
|
}
|
|
|
|
luaFunc(isShuttingDownGameState)
|
|
{
|
|
luaReturnBool(dsq->game->isShuttingDownGameState());
|
|
}
|
|
|
|
static void _fillPathfindTables(lua_State *L, VectorPath& path, int xs_idx, int ys_idx)
|
|
{
|
|
const unsigned num = path.getNumPathNodes();
|
|
|
|
if(lua_istable(L, xs_idx))
|
|
lua_pushvalue(L, xs_idx);
|
|
else
|
|
lua_createtable(L, num, 0);
|
|
|
|
if(lua_istable(L, ys_idx))
|
|
lua_pushvalue(L, ys_idx);
|
|
else
|
|
lua_createtable(L, num, 0);
|
|
|
|
// [..., xs, yx]
|
|
for(unsigned i = 0; i < num; ++i)
|
|
{
|
|
const VectorPathNode *n = path.getPathNode(i);
|
|
lua_pushnumber(L, n->value.x); // [..., xs, ys, x]
|
|
lua_rawseti(L, -3, i+1); // [..., xs, ys]
|
|
lua_pushnumber(L, n->value.y); // [..., xs, ys, y]
|
|
lua_rawseti(L, -2, i+1); // [..., xs, ys]
|
|
}
|
|
// terminate tables
|
|
lua_pushnil(L); // [..., xs, ys, nil]
|
|
lua_rawseti(L, -3, num+1); // [..., xs, ys]
|
|
lua_pushnil(L); // [..., xs, ys, nil]
|
|
lua_rawseti(L, -2, num+1); // [..., xs, ys]
|
|
}
|
|
|
|
static int _pathfindDelete(lua_State *L)
|
|
{
|
|
PathFinding::State *state = *(PathFinding::State**)luaL_checkudata(L, 1, "pathfinder");
|
|
PathFinding::deleteFindPath(state);
|
|
return 0;
|
|
}
|
|
|
|
// startx, starty, endx, endy [, step, xtab, ytab, obsMask]
|
|
luaFunc(findPath)
|
|
{
|
|
VectorPath path;
|
|
Vector start(lua_tonumber(L, 1), lua_tonumber(L, 2));
|
|
Vector end(lua_tonumber(L, 3), lua_tonumber(L, 4));
|
|
ObsType obs = ObsType(lua_tointeger(L, 8));
|
|
if(!PathFinding::generatePathSimple(path, start, end, lua_tointeger(L, 5), obs))
|
|
luaReturnBool(false);
|
|
|
|
const unsigned num = path.getNumPathNodes();
|
|
lua_pushinteger(L, num);
|
|
|
|
_fillPathfindTables(L, path, 6, 7);
|
|
|
|
return 3; // found path?, x positions, y positions
|
|
}
|
|
|
|
luaFunc(createFindPath)
|
|
{
|
|
PathFinding::State **statep = (PathFinding::State**)lua_newuserdata(L, sizeof(void*));
|
|
*statep = PathFinding::initFindPath();
|
|
luaL_getmetatable(L, "pathfinder");
|
|
lua_setmetatable(L, -2);
|
|
return 1;
|
|
}
|
|
|
|
luaFunc(findPathBegin)
|
|
{
|
|
PathFinding::State *state = *(PathFinding::State**)luaL_checkudata(L, 1, "pathfinder");
|
|
Vector start(lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
Vector end(lua_tonumber(L, 4), lua_tonumber(L, 5));
|
|
ObsType obs = ObsType(lua_tointeger(L, 6));
|
|
PathFinding::beginFindPath(state, start, end, obs);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(findPathUpdate)
|
|
{
|
|
PathFinding::State *state = *(PathFinding::State**)luaL_checkudata(L, 1, "pathfinder");
|
|
int limit = lua_tointeger(L, 2);
|
|
bool done = PathFinding::updateFindPath(state, limit);
|
|
luaReturnBool(done);
|
|
}
|
|
|
|
luaFunc(findPathFinish)
|
|
{
|
|
PathFinding::State *state = *(PathFinding::State**)luaL_checkudata(L, 1, "pathfinder");
|
|
VectorPath path;
|
|
bool found = PathFinding::finishFindPath(state, path, lua_tointeger(L, 2));
|
|
if(!found)
|
|
luaReturnBool(false);
|
|
|
|
lua_pushinteger(L, (int)path.getNumPathNodes());
|
|
_fillPathfindTables(L, path, 3, 4);
|
|
return 3;
|
|
}
|
|
|
|
luaFunc(findPathGetStats)
|
|
{
|
|
PathFinding::State *state = *(PathFinding::State**)luaL_checkudata(L, 1, "pathfinder");
|
|
unsigned stepsDone, nodesExpanded;
|
|
PathFinding::getStats(state, stepsDone, nodesExpanded);
|
|
lua_pushinteger(L, stepsDone);
|
|
lua_pushinteger(L, nodesExpanded);
|
|
return 2;
|
|
}
|
|
|
|
luaFunc(findPathFreeMemory)
|
|
{
|
|
PathFinding::State *state = *(PathFinding::State**)luaL_checkudata(L, 1, "pathfinder");
|
|
PathFinding::purgeFindPath(state);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(castLine)
|
|
{
|
|
Vector v(lua_tonumber(L, 1), lua_tonumber(L, 2));
|
|
Vector end(lua_tonumber(L, 3), lua_tonumber(L, 4));
|
|
int tiletype = lua_tointeger(L, 5);
|
|
if(!tiletype)
|
|
tiletype = OT_BLOCKING;
|
|
bool invert = getBool(L, 6);
|
|
Vector step = end - v;
|
|
int steps = step.getLength2D() / TILE_SIZE;
|
|
step.setLength2D(TILE_SIZE);
|
|
|
|
if(!invert)
|
|
{
|
|
for(int i = 0; i < steps; ++i)
|
|
{
|
|
if(dsq->game->getGridRaw(TileVector(v)) & tiletype)
|
|
{
|
|
lua_pushinteger(L, dsq->game->getGrid(TileVector(v)));
|
|
lua_pushnumber(L, v.x);
|
|
lua_pushnumber(L, v.y);
|
|
return 3;
|
|
}
|
|
v += step;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(int i = 0; i < steps; ++i)
|
|
{
|
|
if(!(dsq->game->getGridRaw(TileVector(v)) & tiletype))
|
|
{
|
|
lua_pushinteger(L, dsq->game->getGrid(TileVector(v)));
|
|
lua_pushnumber(L, v.x);
|
|
lua_pushnumber(L, v.y);
|
|
return 3;
|
|
}
|
|
v += step;
|
|
}
|
|
}
|
|
|
|
lua_pushboolean(L, false);
|
|
lua_pushnumber(L, v.x);
|
|
lua_pushnumber(L, v.y);
|
|
return 3;
|
|
}
|
|
|
|
luaFunc(getUserInputString)
|
|
{
|
|
luaReturnStr(dsq->getUserInputString(getString(L, 1), getString(L, 2), true).c_str());
|
|
}
|
|
|
|
luaFunc(getMaxCameraValues)
|
|
{
|
|
luaReturnVec4(dsq->game->cameraMin.x, dsq->game->cameraMin.y, dsq->game->cameraMax.x, dsq->game->cameraMax.y);
|
|
}
|
|
|
|
|
|
luaFunc(inv_isFull)
|
|
{
|
|
IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
|
|
bool full = false;
|
|
if(data)
|
|
full = dsq->continuity.isIngredientFull(data);
|
|
luaReturnBool(full);
|
|
}
|
|
|
|
luaFunc(inv_getMaxAmount)
|
|
{
|
|
IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
|
|
luaReturnInt(data ? data->maxAmount : 0);
|
|
}
|
|
|
|
luaFunc(inv_getAmount)
|
|
{
|
|
IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
|
|
luaReturnInt(data ? data->amount : 0);
|
|
}
|
|
|
|
luaFunc(inv_add)
|
|
{
|
|
IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
|
|
if(data)
|
|
dsq->continuity.pickupIngredient(data, lua_tointeger(L, 2), false, false);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(inv_getGfx)
|
|
{
|
|
luaReturnStr(dsq->continuity.getIngredientGfx(getString(L, 1)).c_str());
|
|
}
|
|
|
|
luaFunc(inv_remove)
|
|
{
|
|
IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
|
|
if(data && data->amount > 0)
|
|
{
|
|
data->amount--;
|
|
dsq->continuity.removeEmptyIngredients();
|
|
if(dsq->game->isInGameMenu())
|
|
dsq->game->getInGameMenu()->refreshFoodSlots(true);
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(inv_getType)
|
|
{
|
|
IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
|
|
luaReturnInt(data ? data->type : 0);
|
|
}
|
|
|
|
luaFunc(inv_getDisplayName)
|
|
{
|
|
IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
|
|
luaReturnStr(data ? data->displayName.c_str() : "");
|
|
}
|
|
|
|
luaFunc(inv_pickupEffect)
|
|
{
|
|
IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
|
|
if(data)
|
|
dsq->game->pickupIngredientEffects(data);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(inv_getNumItems)
|
|
{
|
|
luaReturnInt(dsq->continuity.getIngredientHeldSize());
|
|
}
|
|
|
|
luaFunc(inv_getItemName)
|
|
{
|
|
IngredientData *data = dsq->continuity.getIngredientHeldByIndex(lua_tointeger(L, 1));
|
|
luaReturnStr(data ? data->name.c_str() : "");
|
|
}
|
|
|
|
|
|
luaFunc(getIngredientDataSize)
|
|
{
|
|
luaReturnInt(dsq->continuity.getIngredientDataSize());
|
|
}
|
|
|
|
luaFunc(getIngredientDataName)
|
|
{
|
|
IngredientData *data = dsq->continuity.getIngredientDataByIndex(lua_tointeger(L, 1));
|
|
luaReturnStr(data ? data->name.c_str() : "");
|
|
}
|
|
|
|
luaFunc(learnRecipe)
|
|
{
|
|
std::string name = getString(L, 1);
|
|
bool show = getBool(L, 2);
|
|
dsq->continuity.learnRecipe(name, show);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(setBGGradient)
|
|
{
|
|
if(!dsq->game->grad)
|
|
dsq->game->createGradient();
|
|
Vector c1(lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3));
|
|
Vector c2(lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6));
|
|
if(getBool(L, 7))
|
|
dsq->game->grad->makeHorizontal(c1, c2);
|
|
else
|
|
dsq->game->grad->makeVertical(c1, c2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(createDebugText)
|
|
{
|
|
DebugFont *txt = new DebugFont(lua_tointeger(L, 2), getString(L, 1));
|
|
txt->position = Vector(lua_tonumber(L, 3), lua_tonumber(L, 4));
|
|
dsq->game->addRenderObject(txt, LR_DEBUG_TEXT);
|
|
luaReturnPtr(txt);
|
|
}
|
|
|
|
luaFunc(createBitmapText)
|
|
{
|
|
BmpFont *font = &dsq->smallFont;
|
|
BitmapText *txt = new BitmapText(font);
|
|
txt->setText(getString(L, 1));
|
|
txt->setFontSize(lua_tointeger(L, 2));
|
|
txt->position = Vector(lua_tonumber(L, 3), lua_tonumber(L, 4));
|
|
dsq->game->addRenderObject(txt, LR_HUD);
|
|
luaReturnPtr(txt);
|
|
}
|
|
|
|
static int createArialText(lua_State *L, TTFFont *font)
|
|
{
|
|
TTFText *txt = new TTFText(font);
|
|
txt->setText(getString(L, 1));
|
|
//txt->setFontSize(lua_tointeger(L, 2)); // not supported; param is ignored for API compat with the create*Text functions
|
|
txt->position = Vector(lua_tonumber(L, 3), lua_tonumber(L, 4));
|
|
dsq->game->addRenderObject(txt, LR_HUD);
|
|
luaReturnPtr(txt);
|
|
}
|
|
|
|
luaFunc(createArialTextBig)
|
|
{
|
|
return createArialText(L, &dsq->fontArialBig);
|
|
}
|
|
|
|
luaFunc(createArialTextSmall)
|
|
{
|
|
return createArialText(L, &dsq->fontArialSmall);
|
|
}
|
|
|
|
|
|
luaFunc(text_setText)
|
|
{
|
|
BaseText *txt = getText(L);
|
|
if (txt)
|
|
txt->setText(getString(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(text_setFontSize)
|
|
{
|
|
BaseText *txt = getText(L);
|
|
if (txt)
|
|
txt->setFontSize(lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(text_setWidth)
|
|
{
|
|
BaseText *txt = getText(L);
|
|
if (txt)
|
|
txt->setWidth(lua_tonumber(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(text_setAlign)
|
|
{
|
|
BaseText *txt = getText(L);
|
|
if (txt)
|
|
txt->setAlign((Align)lua_tointeger(L, 2));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(text_getHeight)
|
|
{
|
|
BaseText *txt = getText(L);
|
|
luaReturnNum(txt ? txt->getHeight() : 0.0f);
|
|
}
|
|
|
|
luaFunc(text_getLineHeight)
|
|
{
|
|
BaseText *txt = getText(L);
|
|
luaReturnNum(txt ? txt->getLineHeight() : 0.0f);
|
|
}
|
|
|
|
luaFunc(text_getNumLines)
|
|
{
|
|
BaseText *txt = getText(L);
|
|
luaReturnInt(txt ? txt->getNumLines() : 0);
|
|
}
|
|
|
|
luaFunc(text_getStringWidth)
|
|
{
|
|
BaseText *txt = getText(L);
|
|
luaReturnNum(txt ? txt->getStringWidth(getString(L, 2)) : 0.0f);
|
|
}
|
|
|
|
luaFunc(text_getActualWidth)
|
|
{
|
|
BaseText *txt = getText(L);
|
|
luaReturnNum(txt ? txt->getActualWidth() : 0.0f);
|
|
}
|
|
|
|
luaFunc(loadShader)
|
|
{
|
|
int handle = 0;
|
|
const char *vertRaw = getCString(L, 1);
|
|
const char *fragRaw = getCString(L, 2);
|
|
std::string vert, frag;
|
|
if(vertRaw)
|
|
findFile_helper(vertRaw, vert);
|
|
if(fragRaw)
|
|
findFile_helper(fragRaw, frag);
|
|
|
|
if(core->afterEffectManager)
|
|
handle = core->afterEffectManager->loadShaderFile(vert.c_str(), frag.c_str());
|
|
|
|
luaReturnInt(handle);
|
|
}
|
|
|
|
luaFunc(createShader)
|
|
{
|
|
int handle = 0;
|
|
if(core->afterEffectManager)
|
|
handle = core->afterEffectManager->loadShaderSrc(getCString(L, 1), getCString(L, 2));
|
|
luaReturnInt(handle);
|
|
}
|
|
|
|
luaFunc(shader_setAsAfterEffect)
|
|
{
|
|
int handle = lua_tointeger(L, 1);
|
|
int pos = lua_tointeger(L, 2);
|
|
bool done = false;
|
|
|
|
if(core->afterEffectManager)
|
|
done = core->afterEffectManager->setShaderPipelinePos(handle, pos);
|
|
|
|
luaReturnBool(done);
|
|
}
|
|
|
|
luaFunc(shader_setNumAfterEffects)
|
|
{
|
|
if(core->afterEffectManager)
|
|
core->afterEffectManager->setShaderPipelineSize(lua_tointeger(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(shader_setInt)
|
|
{
|
|
if(core->afterEffectManager)
|
|
{
|
|
Shader *sh = core->afterEffectManager->getShaderPtr(lua_tointeger(L, 1));
|
|
const char *name = getCString(L, 2);
|
|
if(sh && name)
|
|
sh->setInt(name, lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5), lua_tointeger(L, 6));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(shader_setFloat)
|
|
{
|
|
if(core->afterEffectManager)
|
|
{
|
|
Shader *sh = core->afterEffectManager->getShaderPtr(lua_tointeger(L, 1));
|
|
const char *name = getCString(L, 2);
|
|
if(sh && name)
|
|
sh->setFloat(name, lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6));
|
|
}
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(shader_delete)
|
|
{
|
|
if(core->afterEffectManager)
|
|
core->afterEffectManager->deleteShader(lua_tointeger(L, 1));
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(pe_start)
|
|
{
|
|
ParticleEffect *pe = getParticle(L);
|
|
if (pe)
|
|
pe->start();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(pe_stop)
|
|
{
|
|
ParticleEffect *pe = getParticle(L);
|
|
if (pe)
|
|
pe->stop();
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(pe_isRunning)
|
|
{
|
|
ParticleEffect *pe = getParticle(L);
|
|
luaReturnBool(pe && pe->isRunning());
|
|
}
|
|
|
|
luaFunc(getPerformanceCounter)
|
|
{
|
|
#ifdef BBGE_BUILD_SDL2
|
|
luaReturnNum((lua_Number)SDL_GetPerformanceCounter());
|
|
#else
|
|
luaReturnNum((lua_Number)SDL_GetTicks());
|
|
#endif
|
|
}
|
|
|
|
luaFunc(getPerformanceFreq)
|
|
{
|
|
#ifdef BBGE_BUILD_SDL2
|
|
luaReturnNum((lua_Number)SDL_GetPerformanceFrequency());
|
|
#else
|
|
luaReturnNum((lua_Number)1000);
|
|
#endif
|
|
}
|
|
|
|
// ---------- Minimap related ------------------
|
|
|
|
luaFunc(getMinimapRender)
|
|
{
|
|
luaReturnPtr(dsq->game->miniMapRender);
|
|
}
|
|
|
|
luaFunc(minimap_setWaterBitTex)
|
|
{
|
|
luaReturnBool(MiniMapRender::setWaterBitTex(getString(L)));
|
|
}
|
|
luaFunc(minimap_setTopTex)
|
|
{
|
|
luaReturnBool(MiniMapRender::setTopTex(getString(L)));
|
|
}
|
|
luaFunc(minimap_setBottomTex)
|
|
{
|
|
luaReturnBool(MiniMapRender::setBottomTex(getString(L)));
|
|
}
|
|
luaFunc(minimap_setAvatarIconTex)
|
|
{
|
|
luaReturnBool(MiniMapRender::setAvatarTex(getString(L)));
|
|
}
|
|
luaFunc(minimap_setHealthBarTex)
|
|
{
|
|
luaReturnBool(MiniMapRender::setAvatarTex(getString(L)));
|
|
}
|
|
luaFunc(minimap_setMaxHealthMarkerTex)
|
|
{
|
|
luaReturnBool(MiniMapRender::setMaxHealthMarkerTex(getString(L)));
|
|
}
|
|
|
|
template<typename T>
|
|
int mmicon_delete(lua_State *L, T *obj)
|
|
{
|
|
delete obj->minimapIcon;
|
|
obj->minimapIcon = NULL;
|
|
luaReturnNil();
|
|
}
|
|
template<typename T>
|
|
int mmicon_tex(lua_State *L, T *obj)
|
|
{
|
|
if(!obj)
|
|
luaReturnNil();
|
|
MinimapIcon *ico = obj->ensureMinimapIcon();
|
|
bool good = ico->setTexture(getString(L, 2));
|
|
luaReturnBool(good);
|
|
}
|
|
template<typename T>
|
|
int mmicon_size(lua_State *L, T *obj)
|
|
{
|
|
if(!obj)
|
|
luaReturnNil();
|
|
luaReturnNum(interpolateVec2(L, obj->ensureMinimapIcon()->size, 2));
|
|
}
|
|
template<typename T>
|
|
int mmicon_color(lua_State *L, T *obj)
|
|
{
|
|
if(!obj)
|
|
luaReturnNil();
|
|
luaReturnNum(interpolateVec3(L, obj->ensureMinimapIcon()->color, 2));
|
|
}
|
|
template<typename T>
|
|
int mmicon_alpha(lua_State *L, T *obj)
|
|
{
|
|
if(!obj)
|
|
luaReturnNil();
|
|
luaReturnNum(interpolateVec1(L, obj->ensureMinimapIcon()->alpha, 2));
|
|
}
|
|
template<typename T>
|
|
int mmicon_scaleWithDistance(lua_State *L, T *obj)
|
|
{
|
|
if(!obj)
|
|
luaReturnNil();
|
|
obj->ensureMinimapIcon()->scaleWithDistance = getBool(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
template<typename T>
|
|
int mmicon_throb(lua_State *L, T *obj)
|
|
{
|
|
if(!obj)
|
|
luaReturnNil();
|
|
obj->ensureMinimapIcon()->throbMult = lua_tonumber(L, 2);
|
|
luaReturnNil();
|
|
}
|
|
|
|
luaFunc(entity_mmicon_delete) { return mmicon_delete(L, entity(L)); }
|
|
luaFunc(entity_mmicon_tex) { return mmicon_tex(L, entity(L)); }
|
|
luaFunc(entity_mmicon_size) { return mmicon_size(L, entity(L)); }
|
|
luaFunc(entity_mmicon_color) { return mmicon_color(L, entity(L)); }
|
|
luaFunc(entity_mmicon_alpha) { return mmicon_alpha(L, entity(L)); }
|
|
luaFunc(entity_mmicon_scaleWithDistance) { return mmicon_scaleWithDistance(L, entity(L)); }
|
|
luaFunc(entity_mmicon_throb) { return mmicon_throb(L, entity(L)); }
|
|
|
|
luaFunc(node_mmicon_delete) { return mmicon_delete(L, path(L)); }
|
|
luaFunc(node_mmicon_tex) { return mmicon_tex(L, path(L)); }
|
|
luaFunc(node_mmicon_size) { return mmicon_size(L, path(L)); }
|
|
luaFunc(node_mmicon_color) { return mmicon_color(L, path(L)); }
|
|
luaFunc(node_mmicon_alpha) { return mmicon_alpha(L, path(L)); }
|
|
luaFunc(node_mmicon_scaleWithDistance) { return mmicon_scaleWithDistance(L, path(L)); }
|
|
luaFunc(node_mmicon_throb) { return mmicon_throb(L, path(L)); }
|
|
|
|
|
|
class LuaXMLConverter : public tinyxml2::XMLVisitor
|
|
{
|
|
public:
|
|
LuaXMLConverter(lua_State *lua) : L(lua) {}
|
|
virtual ~LuaXMLConverter() {}
|
|
|
|
virtual bool VisitEnter( const tinyxml2::XMLDocument& /*doc*/ )
|
|
{
|
|
lua_newtable(L);
|
|
indexes.push_back(0);
|
|
return true;
|
|
}
|
|
|
|
virtual bool VisitExit( const tinyxml2::XMLDocument& /*doc*/ )
|
|
{
|
|
indexes.pop_back();
|
|
assert(indexes.empty());
|
|
// Leave the root table on the stack
|
|
return true;
|
|
}
|
|
|
|
virtual bool VisitEnter( const tinyxml2::XMLElement& element, const tinyxml2::XMLAttribute *a)
|
|
{
|
|
lua_newtable(L);
|
|
indexes.push_back(0);
|
|
if(a)
|
|
{
|
|
lua_newtable(L);
|
|
for( ; a; a = a->Next())
|
|
{
|
|
lua_pushstring(L, a->Value());
|
|
lua_setfield(L, -2, a->Name());
|
|
}
|
|
lua_setfield(L, -2, "attr");
|
|
}
|
|
if(const char *name = element.Value())
|
|
{
|
|
lua_pushstring(L, name);
|
|
lua_setfield(L, -2, "name");
|
|
}
|
|
if(const char *text = element.GetText())
|
|
{
|
|
lua_pushstring(L, text);
|
|
lua_setfield(L, -2, "text");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
virtual bool VisitExit( const tinyxml2::XMLElement& /*element*/ )
|
|
{
|
|
indexes.pop_back();
|
|
lua_rawseti(L, -2, ++indexes.back());
|
|
return true;
|
|
}
|
|
|
|
protected:
|
|
std::vector<unsigned> indexes;
|
|
lua_State * const L;
|
|
};
|
|
|
|
luaFunc(loadXMLTable)
|
|
{
|
|
const std::string s = getString(L);
|
|
safePath(L, s);
|
|
std::string fn;
|
|
if(!findFile_helper(s.c_str(), fn))
|
|
luaReturnNil();
|
|
|
|
tinyxml2::XMLDocument xml;
|
|
tinyxml2::XMLError err = readXML(fn, xml);
|
|
if(err != tinyxml2::XML_SUCCESS)
|
|
{
|
|
lua_pushboolean(L, false);
|
|
lua_pushinteger(L, err);
|
|
return 2;
|
|
}
|
|
|
|
LuaXMLConverter cvt(L);
|
|
xml.Accept(&cvt);
|
|
return 1;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
|
|
#define luaRegister(func) {#func, l_##func}
|
|
|
|
static const struct {
|
|
const char *name;
|
|
lua_CFunction func;
|
|
} luaFunctionTable[] = {
|
|
|
|
// override Lua's standard dofile() and loadfile(), so we can handle filename case issues.
|
|
{"dofile", l_dofile_caseinsensitive},
|
|
{"loadfile", l_loadfile_caseinsensitive},
|
|
|
|
luaRegister(fileExists),
|
|
luaRegister(getModName),
|
|
luaRegister(getModPath),
|
|
luaRegister(getInterfaceFunctionNames),
|
|
|
|
luaRegister(debugBreak),
|
|
luaRegister(setIgnoreAction),
|
|
luaRegister(isIgnoreAction),
|
|
luaRegister(sendAction),
|
|
|
|
luaRegister(rumble),
|
|
luaRegister(shakeCamera),
|
|
luaRegister(upgradeHealth),
|
|
|
|
luaRegister(cureAllStatus),
|
|
luaRegister(setPoison),
|
|
luaRegister(setMusicToPlay),
|
|
luaRegister(confirm),
|
|
|
|
luaRegister(randRange),
|
|
|
|
luaRegister(flingMonkey),
|
|
|
|
|
|
luaRegister(setLiPower),
|
|
luaRegister(getLiPower),
|
|
luaRegister(getPetPower),
|
|
luaRegister(getTimer),
|
|
luaRegister(getHalfTimer),
|
|
luaRegister(getOldDT),
|
|
luaRegister(getDT),
|
|
luaRegister(getFPS),
|
|
luaRegister(setCostume),
|
|
luaRegister(getCostume),
|
|
luaRegister(getNoteName),
|
|
|
|
luaRegister(getWorldType),
|
|
luaRegister(setWorldType),
|
|
luaRegister(setWorldPaused),
|
|
luaRegister(isWorldPaused),
|
|
|
|
luaRegister(getWaterLevel),
|
|
luaRegister(setWaterLevel),
|
|
|
|
luaRegister(createQuad),
|
|
luaRegister(quad_setPauseLevel),
|
|
|
|
luaRegister(setupEntity),
|
|
luaRegister(setActivePet),
|
|
|
|
luaRegister(reconstructGrid),
|
|
luaRegister(reconstructEntityGrid),
|
|
luaRegister(dilateGrid),
|
|
|
|
luaRegister(ing_hasIET),
|
|
luaRegister(ing_getIngredientName),
|
|
|
|
luaRegister(esetv),
|
|
luaRegister(esetvf),
|
|
luaRegister(egetv),
|
|
luaRegister(egetvf),
|
|
luaRegister(eisv),
|
|
|
|
luaRegister(entity_addIgnoreShotDamageType),
|
|
luaRegister(entity_ensureLimit),
|
|
luaRegister(entity_getBoneLockEntity),
|
|
luaRegister(entity_getBoneLockData),
|
|
|
|
luaRegister(entity_setRidingPosition),
|
|
luaRegister(entity_setRidingData),
|
|
luaRegister(entity_getRidingPosition),
|
|
luaRegister(entity_getRidingRotation),
|
|
luaRegister(entity_getRidingFlip),
|
|
luaRegister(entity_setBoneLock),
|
|
luaRegister(entity_setIngredient),
|
|
luaRegister(entity_setDeathScene),
|
|
luaRegister(entity_isDeathScene),
|
|
|
|
luaRegister(entity_setBeautyFlip),
|
|
luaRegister(entity_setInvincible),
|
|
|
|
luaRegister(setInvincible),
|
|
|
|
luaRegister(entity_setLookAtPoint),
|
|
luaRegister(entity_getLookAtPoint),
|
|
|
|
luaRegister(entity_setDieTimer),
|
|
luaRegister(entity_setAutoSkeletalUpdate),
|
|
luaRegister(entity_updateSkeletal),
|
|
luaRegister(entity_setBounceType),
|
|
|
|
luaRegister(entity_getHealthPerc),
|
|
luaRegister(entity_getBounceType),
|
|
luaRegister(entity_setRiding),
|
|
luaRegister(entity_getRiding),
|
|
|
|
luaRegister(entity_setNaijaReaction),
|
|
|
|
luaRegister(entity_setEatType),
|
|
|
|
luaRegister(entity_setSpiritFreeze),
|
|
luaRegister(entity_setPauseFreeze),
|
|
luaRegister(node_setSpiritFreeze),
|
|
luaRegister(node_setPauseFreeze),
|
|
|
|
luaRegister(entity_setCanLeaveWater),
|
|
|
|
luaRegister(entity_pullEntities),
|
|
|
|
luaRegister(entity_setEntityLayer),
|
|
|
|
luaRegister(entity_clearTargetPoints),
|
|
luaRegister(entity_addTargetPoint),
|
|
|
|
|
|
luaRegister(entity_setCullRadius),
|
|
|
|
luaRegister(entity_switchLayer),
|
|
|
|
luaRegister(entity_debugText),
|
|
|
|
|
|
luaRegister(avatar_setCanDie),
|
|
luaRegister(setCanActivate),
|
|
luaRegister(setSeeMapMode),
|
|
luaRegister(avatar_toggleCape),
|
|
luaRegister(avatar_setPullTarget),
|
|
|
|
luaRegister(avatar_setCanLockToWall),
|
|
luaRegister(avatar_canLockToWall),
|
|
luaRegister(avatar_setCanBurst),
|
|
luaRegister(avatar_canBurst),
|
|
luaRegister(avatar_setCanSwimAgainstCurrents),
|
|
luaRegister(avatar_canSwimAgainstCurrents),
|
|
luaRegister(avatar_setCanCollideWithShots),
|
|
luaRegister(avatar_canCollideWithShots),
|
|
luaRegister(avatar_setCollisionAvoidanceData),
|
|
|
|
luaRegister(avatar_clampPosition),
|
|
luaRegister(avatar_updatePosition),
|
|
|
|
luaRegister(pause),
|
|
luaRegister(unpause),
|
|
luaRegister(isPaused),
|
|
luaRegister(isInGameMenu),
|
|
luaRegister(isInEditor),
|
|
|
|
|
|
luaRegister(vector_normalize),
|
|
luaRegister(vector_setLength),
|
|
luaRegister(vector_getLength),
|
|
|
|
luaRegister(vector_dot),
|
|
|
|
luaRegister(vector_isLength2DIn),
|
|
luaRegister(vector_cap),
|
|
|
|
|
|
luaRegister(entity_setDeathParticleEffect),
|
|
luaRegister(entity_setDeathSound),
|
|
luaRegister(entity_setStopSoundsOnDeath),
|
|
|
|
luaRegister(entity_setDamageTarget),
|
|
luaRegister(entity_setAllDamageTargets),
|
|
|
|
luaRegister(entity_isDamageTarget),
|
|
luaRegister(entity_isValidTarget),
|
|
|
|
luaRegister(entity_isUnderWater),
|
|
luaRegister(entity_checkSplash),
|
|
luaRegister(entity_isInCurrent),
|
|
|
|
luaRegister(entity_getRandomTargetPoint),
|
|
luaRegister(entity_getTargetPoint),
|
|
luaRegister(entity_getNumTargetPoints),
|
|
|
|
luaRegister(entity_setTargetRange),
|
|
luaRegister(entity_getTargetRange),
|
|
|
|
luaRegister(bone_addSegment),
|
|
|
|
luaRegister(bone_setSegmentOffset),
|
|
luaRegister(bone_setSegmentProps),
|
|
luaRegister(bone_setSegmentChainHead),
|
|
luaRegister(bone_setAnimated),
|
|
luaRegister(bone_showFrame),
|
|
|
|
luaRegister(bone_lookAtEntity),
|
|
luaRegister(bone_lookAtPosition),
|
|
|
|
luaRegister(entity_partSetSegs),
|
|
|
|
luaRegister(entity_adjustPositionBySurfaceNormal),
|
|
luaRegister(entity_applySurfaceNormalForce),
|
|
|
|
luaRegister(entity_doElementInteraction),
|
|
luaRegister(avatar_setElementEffectMult),
|
|
|
|
luaRegister(createBeam),
|
|
luaRegister(beam_setAngle),
|
|
luaRegister(beam_setDamage),
|
|
luaRegister(beam_setBeamWidth),
|
|
luaRegister(beam_setFirer),
|
|
luaRegister(beam_setDamageType),
|
|
luaRegister(beam_getEndPos),
|
|
|
|
luaRegister(getStringBank),
|
|
|
|
luaRegister(isPlat),
|
|
|
|
|
|
luaRegister(createEntity),
|
|
luaRegister(entity_setWeight),
|
|
luaRegister(entity_getWeight),
|
|
|
|
luaRegister(entity_setActivationType),
|
|
|
|
luaRegister(entity_v),
|
|
luaRegister(node_v),
|
|
|
|
luaRegister(isQuitFlag),
|
|
luaRegister(isDeveloperKeys),
|
|
luaRegister(isDemo),
|
|
|
|
luaRegister(isInputEnabled),
|
|
luaRegister(disableInput),
|
|
|
|
luaRegister(getInputMode),
|
|
luaRegister(getJoystickAxisLeft),
|
|
luaRegister(getJoystickAxisRight),
|
|
|
|
luaRegister(setMousePos),
|
|
luaRegister(getMousePos),
|
|
luaRegister(getMouseWorldPos),
|
|
luaRegister(getMouseWheelChange),
|
|
luaRegister(setMouseConstraintCircle),
|
|
luaRegister(setMouseConstraint),
|
|
|
|
luaRegister(resetContinuity),
|
|
|
|
luaRegister(quit),
|
|
luaRegister(doModSelect),
|
|
luaRegister(doLoadMenu),
|
|
|
|
|
|
luaRegister(enableInput),
|
|
luaRegister(fade),
|
|
luaRegister(fade2),
|
|
luaRegister(fade3),
|
|
|
|
luaRegister(getMapName),
|
|
luaRegister(isMapName),
|
|
luaRegister(mapNameContains),
|
|
|
|
luaRegister(entity_getAimVector),
|
|
|
|
luaRegister(entity_getVectorToEntity),
|
|
|
|
luaRegister(entity_getDistanceToTarget),
|
|
luaRegister(entity_getDistanceToPoint),
|
|
luaRegister(entity_move),
|
|
|
|
luaRegister(entity_getID),
|
|
|
|
luaRegister(getEntityByID),
|
|
|
|
luaRegister(entity_setBounce),
|
|
luaRegister(entity_setActivation),
|
|
luaRegister(entity_rotateToEntity),
|
|
|
|
luaRegister(entity_fireGas),
|
|
luaRegister(entity_rotateToTarget),
|
|
|
|
luaRegister(entity_switchSurfaceDirection),
|
|
|
|
luaRegister(entity_moveAlongSurface),
|
|
luaRegister(entity_rotateToSurfaceNormal),
|
|
luaRegister(entity_clampToSurface),
|
|
luaRegister(entity_checkSurface),
|
|
luaRegister(entity_clampToHit),
|
|
|
|
luaRegister(entity_grabTarget),
|
|
luaRegister(entity_releaseTarget),
|
|
|
|
luaRegister(entity_getStateTime),
|
|
luaRegister(entity_setStateTime),
|
|
|
|
luaRegister(entity_doFriction),
|
|
|
|
luaRegister(entity_partWidthHeight),
|
|
luaRegister(entity_partBlendType),
|
|
luaRegister(entity_partRotate),
|
|
luaRegister(entity_partAlpha),
|
|
|
|
luaRegister(entity_getHealth),
|
|
luaRegister(entity_getMaxHealth),
|
|
luaRegister(entity_pushTarget),
|
|
luaRegister(entity_getPushDamage),
|
|
luaRegister(entity_msg),
|
|
luaRegister(node_msg),
|
|
luaRegister(entity_updateMovement),
|
|
luaRegister(entity_updateCurrents),
|
|
luaRegister(entity_updateLocalWarpAreas),
|
|
|
|
luaRegister(entity_getTargetPositionX),
|
|
luaRegister(entity_getTargetPositionY),
|
|
|
|
luaRegister(avatar_incrLeaches),
|
|
luaRegister(avatar_decrLeaches),
|
|
luaRegister(entity_rotateToVel),
|
|
luaRegister(entity_rotateToVec),
|
|
|
|
luaRegister(entity_setSegsMaxDist),
|
|
|
|
luaRegister(entity_offsetUpdate),
|
|
|
|
luaRegister(entity_createEntity),
|
|
luaRegister(entity_stopPull),
|
|
luaRegister(entity_setTargetPriority),
|
|
luaRegister(entity_getTargetPriority),
|
|
|
|
luaRegister(entity_setEntityType),
|
|
luaRegister(entity_getEntityType),
|
|
|
|
luaRegister(entity_setSegmentTexture),
|
|
|
|
luaRegister(entity_spawnParticlesFromCollisionMask),
|
|
luaRegister(entity_initEmitter),
|
|
luaRegister(entity_startEmitter),
|
|
luaRegister(entity_stopEmitter),
|
|
luaRegister(entity_getEmitter),
|
|
luaRegister(entity_getNumEmitters),
|
|
|
|
luaRegister(entity_initPart),
|
|
luaRegister(entity_initSegments),
|
|
luaRegister(entity_warpSegments),
|
|
luaRegister(entity_initSkeletal),
|
|
luaRegister(entity_loadSkin),
|
|
luaRegister(entity_hasSkeletal),
|
|
luaRegister(entity_getNumAnimLayers),
|
|
luaRegister(entity_getSkeletalName),
|
|
luaRegister(entity_initStrands),
|
|
|
|
luaRegister(entity_hurtTarget),
|
|
luaRegister(entity_doSpellAvoidance),
|
|
luaRegister(entity_doEntityAvoidance),
|
|
luaRegister(entity_rotate),
|
|
luaRegister(entity_doGlint),
|
|
luaRegister(entity_findTarget),
|
|
luaRegister(entity_hasTarget),
|
|
luaRegister(entity_isInRect),
|
|
luaRegister(entity_isInDarkness),
|
|
|
|
luaRegister(entity_isRidingOnEntity),
|
|
|
|
luaRegister(entity_isBeingPulled),
|
|
|
|
luaRegister(entity_isNearObstruction),
|
|
luaRegister(entity_isDead),
|
|
|
|
luaRegister(entity_isTargetInRange),
|
|
luaRegister(entity_getDistanceToEntity),
|
|
luaRegister(entity_isEntityInside),
|
|
|
|
luaRegister(entity_isInvincible),
|
|
|
|
luaRegister(entity_isNearGround),
|
|
|
|
luaRegister(entity_moveTowardsTarget),
|
|
luaRegister(entity_moveAroundTarget),
|
|
|
|
luaRegister(entity_moveTowardsAngle),
|
|
luaRegister(entity_moveAroundAngle),
|
|
luaRegister(entity_moveTowards),
|
|
luaRegister(entity_moveAround),
|
|
|
|
luaRegister(entity_setMaxSpeed),
|
|
luaRegister(entity_getMaxSpeed),
|
|
luaRegister(entity_setMaxSpeedLerp),
|
|
luaRegister(entity_getMaxSpeedLerp),
|
|
luaRegister(entity_setState),
|
|
luaRegister(entity_getState),
|
|
luaRegister(entity_getEnqueuedState),
|
|
|
|
luaRegister(entity_getPrevState),
|
|
luaRegister(entity_doCollisionAvoidance),
|
|
luaRegister(entity_animate),
|
|
luaRegister(entity_setAnimLayerTimeMult),
|
|
luaRegister(entity_getAnimLayerTimeMult),
|
|
luaRegister(entity_stopAnimation),
|
|
luaRegister(entity_getAnimationLoop),
|
|
|
|
luaRegister(entity_setCurrentTarget),
|
|
luaRegister(entity_stopInterpolating),
|
|
|
|
luaRegister(entity_followPath),
|
|
luaRegister(entity_followPathSpeed),
|
|
luaRegister(entity_isFollowingPath),
|
|
luaRegister(entity_followEntity),
|
|
luaRegister(entity_sound),
|
|
luaRegister(entity_playSfx),
|
|
|
|
luaRegister(registerSporeDrop),
|
|
|
|
luaRegister(spawnIngredient),
|
|
luaRegister(spawnAllIngredients),
|
|
luaRegister(spawnParticleEffect),
|
|
luaRegister(spawnManaBall),
|
|
|
|
luaRegister(isEscapeKey),
|
|
|
|
luaRegister(resetTimer),
|
|
|
|
luaRegister(addInfluence),
|
|
luaRegister(getSuckPosition),
|
|
luaRegister(setSuckPosition),
|
|
luaRegister(setNumSuckPositions),
|
|
luaRegister(setupBasicEntity),
|
|
luaRegister(playMusic),
|
|
luaRegister(playMusicStraight),
|
|
luaRegister(stopMusic),
|
|
|
|
luaRegister(user_set_demo_intro),
|
|
luaRegister(user_save),
|
|
|
|
luaRegister(playMusicOnce),
|
|
|
|
luaRegister(playSfx),
|
|
luaRegister(fadeSfx),
|
|
|
|
luaRegister(emote),
|
|
|
|
luaRegister(playVisualEffect),
|
|
luaRegister(playNoEffect),
|
|
luaRegister(createShockEffect),
|
|
|
|
luaRegister(setOverrideMusic),
|
|
|
|
luaRegister(setOverrideVoiceFader),
|
|
luaRegister(setGameSpeed),
|
|
luaRegister(warpAvatar),
|
|
luaRegister(warpNaijaToSceneNode),
|
|
|
|
luaRegister(toWindowFromWorld),
|
|
|
|
luaRegister(toggleDamageSprite),
|
|
|
|
luaRegister(toggleLiCombat),
|
|
|
|
luaRegister(toggleCursor),
|
|
luaRegister(toggleBlackBars),
|
|
luaRegister(setBlackBarsColor),
|
|
|
|
luaRegister(entityFollowEntity),
|
|
|
|
luaRegister(bedEffects),
|
|
|
|
luaRegister(warpNaijaToEntity),
|
|
|
|
luaRegister(setNaijaHeadTexture),
|
|
|
|
luaRegister(incrFlag),
|
|
luaRegister(decrFlag),
|
|
luaRegister(setFlag),
|
|
luaRegister(getFlag),
|
|
luaRegister(setStringFlag),
|
|
luaRegister(getStringFlag),
|
|
luaRegister(learnSong),
|
|
luaRegister(unlearnSong),
|
|
luaRegister(hasSong),
|
|
luaRegister(hasLi),
|
|
|
|
luaRegister(setCanWarp),
|
|
luaRegister(setCanChangeForm),
|
|
luaRegister(setInvincibleOnNested),
|
|
|
|
luaRegister(setControlHint),
|
|
luaRegister(setCameraLerpDelay),
|
|
luaRegister(screenFadeGo),
|
|
luaRegister(screenFadeTransition),
|
|
luaRegister(screenFadeCapture),
|
|
|
|
luaRegister(clearControlHint),
|
|
|
|
|
|
luaRegister(savePoint),
|
|
luaRegister(saveMenu),
|
|
luaRegister(setSceneDisplayNameInSave),
|
|
luaRegister(wait),
|
|
luaRegister(watch),
|
|
|
|
luaRegister(quitNestedMain),
|
|
luaRegister(isNestedMain),
|
|
|
|
|
|
luaRegister(screenMessage),
|
|
luaRegister(centerText),
|
|
luaRegister(watchForVoice),
|
|
|
|
luaRegister(setLayerRenderPass),
|
|
luaRegister(setElementLayerVisible),
|
|
luaRegister(isElementLayerVisible),
|
|
|
|
luaRegister(isWithin),
|
|
|
|
|
|
|
|
luaRegister(pickupGem),
|
|
luaRegister(setGemPosition),
|
|
luaRegister(setGemName),
|
|
luaRegister(setGemBlink),
|
|
luaRegister(removeGem),
|
|
luaRegister(setBeacon),
|
|
luaRegister(getBeacon),
|
|
luaRegister(beaconEffect),
|
|
|
|
luaRegister(chance),
|
|
|
|
luaRegister(goToTitle),
|
|
luaRegister(jumpState),
|
|
luaRegister(getEnqueuedState),
|
|
|
|
|
|
luaRegister(fadeIn),
|
|
luaRegister(fadeOut),
|
|
|
|
luaRegister(vision),
|
|
|
|
luaRegister(musicVolume),
|
|
|
|
luaRegister(voice),
|
|
luaRegister(voiceOnce),
|
|
luaRegister(voiceInterupt),
|
|
|
|
|
|
luaRegister(stopVoice),
|
|
luaRegister(stopAllVoice),
|
|
luaRegister(stopAllSfx),
|
|
|
|
|
|
|
|
luaRegister(fadeOutMusic),
|
|
|
|
|
|
luaRegister(isStreamingVoice),
|
|
|
|
luaRegister(changeForm),
|
|
luaRegister(getForm),
|
|
luaRegister(isForm),
|
|
luaRegister(learnFormUpgrade),
|
|
luaRegister(hasFormUpgrade),
|
|
|
|
|
|
luaRegister(singSong),
|
|
luaRegister(isObstructed),
|
|
luaRegister(isObstructedRaw),
|
|
luaRegister(isObstructedBlock),
|
|
luaRegister(getObstruction),
|
|
luaRegister(getGridRaw),
|
|
luaRegister(findPath),
|
|
luaRegister(createFindPath),
|
|
luaRegister(findPathBegin),
|
|
luaRegister(findPathUpdate),
|
|
luaRegister(findPathFinish),
|
|
luaRegister(findPathGetStats),
|
|
luaRegister(findPathFreeMemory),
|
|
luaRegister(castLine),
|
|
luaRegister(getUserInputString),
|
|
luaRegister(getMaxCameraValues),
|
|
|
|
luaRegister(isFlag),
|
|
|
|
luaRegister(entity_isFlag),
|
|
luaRegister(entity_setFlag),
|
|
luaRegister(entity_getFlag),
|
|
|
|
luaRegister(node_isFlag),
|
|
luaRegister(node_setFlag),
|
|
luaRegister(node_getFlag),
|
|
|
|
luaRegister(avatar_getStillTimer),
|
|
luaRegister(avatar_getSpellCharge),
|
|
|
|
luaRegister(avatar_isSinging),
|
|
luaRegister(avatar_isTouchHit),
|
|
luaRegister(avatar_isBursting),
|
|
luaRegister(avatar_isLockable),
|
|
luaRegister(avatar_isRolling),
|
|
luaRegister(avatar_isSwimming),
|
|
luaRegister(avatar_isOnWall),
|
|
luaRegister(avatar_isShieldActive),
|
|
luaRegister(avatar_setShieldActive),
|
|
luaRegister(avatar_getRollDirection),
|
|
|
|
luaRegister(avatar_fallOffWall),
|
|
luaRegister(avatar_setBlockSinging),
|
|
luaRegister(avatar_isBlockSinging),
|
|
luaRegister(avatar_setBlockBackflip),
|
|
luaRegister(avatar_isBlockBackflip),
|
|
|
|
luaRegister(avatar_setSpeedMult),
|
|
luaRegister(avatar_setSpeedMult2),
|
|
luaRegister(avatar_getSpeedMult),
|
|
luaRegister(avatar_getSpeedMult2),
|
|
|
|
|
|
luaRegister(avatar_toggleMovement),
|
|
|
|
|
|
luaRegister(showInGameMenu),
|
|
luaRegister(hideInGameMenu),
|
|
|
|
|
|
luaRegister(showImage),
|
|
luaRegister(hideImage),
|
|
luaRegister(clearHelp),
|
|
luaRegister(clearShots),
|
|
|
|
|
|
|
|
luaRegister(getEntity),
|
|
luaRegister(getFirstEntity),
|
|
luaRegister(getNextEntity),
|
|
luaRegister(filterNearestEntities),
|
|
luaRegister(filterNearestEntitiesAdd),
|
|
luaRegister(getNextFilteredEntity),
|
|
|
|
luaRegister(setStory),
|
|
luaRegister(getStory),
|
|
luaRegister(getNoteColor),
|
|
luaRegister(getNoteVector),
|
|
luaRegister(getRandNote),
|
|
|
|
luaRegister(foundLostMemory),
|
|
|
|
luaRegister(isStory),
|
|
|
|
luaRegister(entity_damage),
|
|
luaRegister(entity_heal),
|
|
|
|
luaRegister(getNearestIngredient),
|
|
|
|
luaRegister(getNearestNodeByType),
|
|
|
|
luaRegister(getNode),
|
|
luaRegister(getNodeToActivate),
|
|
luaRegister(setNodeToActivate),
|
|
luaRegister(getEntityToActivate),
|
|
luaRegister(setEntityToActivate),
|
|
luaRegister(hasThingToActivate),
|
|
luaRegister(setActivation),
|
|
|
|
luaRegister(entity_warpToNode),
|
|
luaRegister(entity_moveToNode),
|
|
luaRegister(entity_moveToNodeSpeed),
|
|
|
|
luaRegister(cam_toNode),
|
|
luaRegister(cam_snap),
|
|
luaRegister(cam_toEntity),
|
|
luaRegister(cam_setPosition),
|
|
|
|
|
|
luaRegister(entity_flipToEntity),
|
|
luaRegister(entity_flipToSame),
|
|
|
|
luaRegister(entity_flipToNode),
|
|
luaRegister(entity_flipToVel),
|
|
|
|
luaRegister(entity_swimToNode),
|
|
luaRegister(entity_swimToNodeSpeed),
|
|
luaRegister(entity_swimToPosition),
|
|
luaRegister(entity_swimToPositionSpeed),
|
|
|
|
|
|
luaRegister(createShot),
|
|
|
|
luaRegister(entity_isHit),
|
|
|
|
|
|
|
|
luaRegister(createWeb),
|
|
luaRegister(web_addPoint),
|
|
luaRegister(web_setPoint),
|
|
luaRegister(web_getNumPoints),
|
|
|
|
luaRegister(createSpore),
|
|
|
|
luaRegister(getFirstShot),
|
|
luaRegister(getNextShot),
|
|
luaRegister(shot_setAimVector),
|
|
luaRegister(shot_setOut),
|
|
luaRegister(shot_getEffectTime),
|
|
luaRegister(shot_isIgnoreShield),
|
|
luaRegister(shot_setFirer),
|
|
luaRegister(shot_getFirer),
|
|
luaRegister(shot_setTarget),
|
|
luaRegister(shot_getTarget),
|
|
luaRegister(shot_setExtraDamage),
|
|
luaRegister(shot_getExtraDamage),
|
|
luaRegister(shot_getDamage),
|
|
luaRegister(shot_getDamageType),
|
|
luaRegister(shot_getName),
|
|
luaRegister(shot_getMaxSpeed),
|
|
luaRegister(shot_setMaxSpeed),
|
|
luaRegister(shot_getHomingness),
|
|
luaRegister(shot_setHomingness),
|
|
luaRegister(shot_getLifeTime),
|
|
luaRegister(shot_setLifeTime),
|
|
luaRegister(shot_setDamageType),
|
|
luaRegister(shot_setCheckDamageTarget),
|
|
luaRegister(shot_isCheckDamageTarget),
|
|
luaRegister(shot_setTrailPrt),
|
|
luaRegister(shot_setTargetPoint),
|
|
luaRegister(shot_getTargetPoint),
|
|
luaRegister(shot_canHitEntity),
|
|
luaRegister(filterNearestShots),
|
|
luaRegister(filterNearestShotsAdd),
|
|
luaRegister(getNextFilteredShot),
|
|
luaRegister(entity_pathBurst),
|
|
luaRegister(entity_handleShotCollisions),
|
|
luaRegister(entity_handleShotCollisionsSkeletal),
|
|
luaRegister(entity_handleShotCollisionsHair),
|
|
luaRegister(entity_collideSkeletalVsCircle),
|
|
luaRegister(entity_collideSkeletalVsCirclePos),
|
|
luaRegister(entity_collideSkeletalVsLine),
|
|
luaRegister(entity_collideSkeletalVsCircleForListByName),
|
|
luaRegister(entity_collideCircleVsLine),
|
|
luaRegister(entity_collideCircleVsLineAngle),
|
|
|
|
luaRegister(entity_collideHairVsCircle),
|
|
|
|
luaRegister(entity_setDropChance),
|
|
|
|
luaRegister(entity_waitForPath),
|
|
luaRegister(entity_watchForPath),
|
|
|
|
luaRegister(entity_revive),
|
|
|
|
luaRegister(entity_getTarget),
|
|
luaRegister(entity_isState),
|
|
|
|
luaRegister(entity_setProperty),
|
|
luaRegister(entity_isProperty),
|
|
|
|
|
|
luaRegister(entity_initHair),
|
|
luaRegister(entity_getHairPosition),
|
|
luaRegister(entity_getHair),
|
|
luaRegister(entity_clearHair),
|
|
|
|
luaRegister(entity_setHairHeadPosition),
|
|
luaRegister(entity_updateHair),
|
|
luaRegister(entity_exertHairForce),
|
|
|
|
luaRegister(entity_setName),
|
|
|
|
luaRegister(getNumberOfEntitiesNamed),
|
|
|
|
luaRegister(isNested),
|
|
luaRegister(isSkippingCutscene),
|
|
|
|
luaRegister(entity_idle),
|
|
luaRegister(entity_stopAllAnimations),
|
|
|
|
luaRegister(entity_getBoneByIdx),
|
|
luaRegister(entity_getBoneByName),
|
|
luaRegister(entity_getBoneByInternalId),
|
|
luaRegister(entity_getNumBones),
|
|
|
|
|
|
|
|
luaRegister(toggleInput),
|
|
|
|
luaRegister(entity_setTarget),
|
|
|
|
luaRegister(getScreenCenter),
|
|
|
|
|
|
|
|
luaRegister(debugLog),
|
|
luaRegister(errorLog),
|
|
luaRegister(loadMap),
|
|
|
|
luaRegister(loadSound),
|
|
|
|
luaRegister(node_activate),
|
|
luaRegister(node_getName),
|
|
luaRegister(node_getLabel),
|
|
luaRegister(node_getPathPosition),
|
|
luaRegister(node_getPosition),
|
|
luaRegister(node_setPosition),
|
|
luaRegister(node_getContent),
|
|
luaRegister(node_getAmount),
|
|
luaRegister(node_getSize),
|
|
luaRegister(node_getShape),
|
|
|
|
luaRegister(toggleSteam),
|
|
luaRegister(toggleVersionLabel),
|
|
luaRegister(setVersionLabelText),
|
|
|
|
luaRegister(appendUserDataPath),
|
|
|
|
luaRegister(setCutscene),
|
|
luaRegister(isInCutscene),
|
|
|
|
|
|
|
|
luaRegister(node_getNumEntitiesIn),
|
|
|
|
|
|
luaRegister(entity_getName),
|
|
luaRegister(entity_isName),
|
|
|
|
|
|
luaRegister(node_setActivationRange),
|
|
luaRegister(node_setCursorActivation),
|
|
luaRegister(node_setCatchActions),
|
|
|
|
luaRegister(node_setElementsInLayerActive),
|
|
|
|
|
|
luaRegister(entity_setHealth),
|
|
luaRegister(entity_setCurrentHealth),
|
|
luaRegister(entity_setMaxHealth),
|
|
luaRegister(entity_changeHealth),
|
|
|
|
luaRegister(node_setActive),
|
|
luaRegister(node_isActive),
|
|
luaRegister(node_setEmitter),
|
|
luaRegister(node_getEmitter),
|
|
|
|
|
|
luaRegister(setSceneColor),
|
|
luaRegister(getSceneColor),
|
|
luaRegister(setSceneColor2),
|
|
luaRegister(getSceneColor2),
|
|
|
|
luaRegister(entity_watchEntity),
|
|
|
|
luaRegister(entity_isEntityInRange),
|
|
luaRegister(entity_isPositionInRange),
|
|
|
|
luaRegister(entity_stopFollowingPath),
|
|
luaRegister(entity_slowToStopPath),
|
|
luaRegister(entity_isSlowingToStopPath),
|
|
|
|
luaRegister(entity_findNearestEntityOfType),
|
|
luaRegister(entity_isFollowingEntity),
|
|
luaRegister(entity_resumePath),
|
|
|
|
luaRegister(entity_generateCollisionMask),
|
|
|
|
luaRegister(entity_isAnimating),
|
|
luaRegister(entity_getAnimationName),
|
|
luaRegister(entity_getAnimationLength),
|
|
luaRegister(entity_hasAnimation),
|
|
|
|
luaRegister(entity_setCull),
|
|
|
|
luaRegister(entity_setFillGrid),
|
|
luaRegister(entity_isFillGrid),
|
|
|
|
luaRegister(entity_push),
|
|
|
|
luaRegister(entity_alpha),
|
|
|
|
luaRegister(findWall),
|
|
|
|
|
|
luaRegister(overrideZoom),
|
|
luaRegister(disableOverrideZoom),
|
|
luaRegister(getZoom),
|
|
luaRegister(setMaxLookDistance),
|
|
|
|
|
|
|
|
luaRegister(spawnAroundEntity),
|
|
|
|
luaRegister(entity_toggleBone),
|
|
|
|
luaRegister(bone_getName),
|
|
luaRegister(bone_isName),
|
|
luaRegister(bone_getIndex),
|
|
luaRegister(node_x),
|
|
luaRegister(node_y),
|
|
luaRegister(node_isEntityPast),
|
|
luaRegister(node_isEntityInRange),
|
|
luaRegister(node_isPositionIn),
|
|
|
|
|
|
|
|
luaRegister(entity_warpLastPosition),
|
|
luaRegister(entity_setVel),
|
|
luaRegister(entity_setVelLen),
|
|
luaRegister(entity_getVelLen),
|
|
luaRegister(entity_getVel),
|
|
luaRegister(entity_velx),
|
|
luaRegister(entity_vely),
|
|
luaRegister(entity_addVel),
|
|
luaRegister(entity_addRandomVel),
|
|
luaRegister(entity_isVelIn),
|
|
luaRegister(entity_clearVel),
|
|
luaRegister(entity_velTowards),
|
|
|
|
luaRegister(entity_setVel2),
|
|
luaRegister(entity_setVel2Len),
|
|
luaRegister(entity_getVel2Len),
|
|
luaRegister(entity_addVel2),
|
|
luaRegister(entity_getVel2),
|
|
luaRegister(entity_clearVel2),
|
|
|
|
luaRegister(entity_getPushVec),
|
|
|
|
|
|
luaRegister(updateMusic),
|
|
|
|
luaRegister(entity_touchAvatarDamage),
|
|
luaRegister(getNaija),
|
|
luaRegister(getLi),
|
|
luaRegister(setLi),
|
|
|
|
luaRegister(randAngle360),
|
|
luaRegister(randVector),
|
|
|
|
luaRegister(entity_getNearestEntity),
|
|
luaRegister(entity_getNearestBoneToPosition),
|
|
luaRegister(getNearestEntity),
|
|
|
|
luaRegister(entity_getNearestNode),
|
|
luaRegister(entity_setPoison),
|
|
luaRegister(entity_getPoison),
|
|
|
|
luaRegister(node_getNearestEntity),
|
|
luaRegister(node_getNearestNode),
|
|
|
|
|
|
luaRegister(node_isEntityIn),
|
|
|
|
|
|
|
|
luaRegister(isLeftMouse),
|
|
luaRegister(isRightMouse),
|
|
|
|
|
|
luaRegister(setTimerTextAlpha),
|
|
luaRegister(setTimerText),
|
|
|
|
|
|
luaRegister(getWallNormal),
|
|
luaRegister(getLastCollidePosition),
|
|
luaRegister(getLastCollideTileType),
|
|
luaRegister(collideCircleWithGrid),
|
|
|
|
luaRegister(getScreenVirtualOff),
|
|
luaRegister(getScreenSize),
|
|
luaRegister(getScreenVirtualSize),
|
|
luaRegister(isMiniMapCursorOkay),
|
|
luaRegister(isShuttingDownGameState),
|
|
luaRegister(setBGGradient),
|
|
|
|
luaRegister(inv_isFull),
|
|
luaRegister(inv_getMaxAmount),
|
|
luaRegister(inv_getAmount),
|
|
luaRegister(inv_add),
|
|
luaRegister(inv_getGfx),
|
|
luaRegister(inv_remove),
|
|
luaRegister(inv_getType),
|
|
luaRegister(inv_getDisplayName),
|
|
luaRegister(inv_pickupEffect),
|
|
luaRegister(inv_getNumItems),
|
|
luaRegister(inv_getItemName),
|
|
luaRegister(learnRecipe),
|
|
luaRegister(getIngredientDataSize),
|
|
luaRegister(getIngredientDataName),
|
|
|
|
luaRegister(createDebugText),
|
|
luaRegister(createBitmapText),
|
|
luaRegister(createArialTextBig),
|
|
luaRegister(createArialTextSmall),
|
|
luaRegister(text_setText),
|
|
luaRegister(text_setFontSize),
|
|
luaRegister(text_setWidth),
|
|
luaRegister(text_setAlign),
|
|
luaRegister(text_getHeight),
|
|
luaRegister(text_getStringWidth),
|
|
luaRegister(text_getActualWidth),
|
|
luaRegister(text_getLineHeight),
|
|
luaRegister(text_getNumLines),
|
|
|
|
luaRegister(loadShader),
|
|
luaRegister(createShader),
|
|
luaRegister(shader_setAsAfterEffect),
|
|
luaRegister(shader_setNumAfterEffects),
|
|
luaRegister(shader_setFloat),
|
|
luaRegister(shader_setInt),
|
|
luaRegister(shader_delete),
|
|
|
|
luaRegister(pe_start),
|
|
luaRegister(pe_stop),
|
|
luaRegister(pe_isRunning),
|
|
|
|
luaRegister(isQuad),
|
|
luaRegister(isNode),
|
|
luaRegister(isObject),
|
|
luaRegister(isEntity),
|
|
luaRegister(isScriptedEntity),
|
|
luaRegister(isBone),
|
|
luaRegister(isShot),
|
|
luaRegister(isWeb),
|
|
luaRegister(isIng),
|
|
luaRegister(isBeam),
|
|
luaRegister(isText),
|
|
luaRegister(isShader),
|
|
luaRegister(isParticleEffect),
|
|
|
|
luaRegister(getPerformanceCounter),
|
|
luaRegister(getPerformanceFreq),
|
|
|
|
luaRegister(getMinimapRender),
|
|
luaRegister(minimap_setWaterBitTex),
|
|
luaRegister(minimap_setTopTex),
|
|
luaRegister(minimap_setBottomTex),
|
|
luaRegister(minimap_setAvatarIconTex),
|
|
luaRegister(minimap_setHealthBarTex),
|
|
luaRegister(minimap_setMaxHealthMarkerTex),
|
|
luaRegister(entity_mmicon_delete),
|
|
luaRegister(entity_mmicon_tex),
|
|
luaRegister(entity_mmicon_size),
|
|
luaRegister(entity_mmicon_color),
|
|
luaRegister(entity_mmicon_alpha),
|
|
luaRegister(entity_mmicon_scaleWithDistance),
|
|
luaRegister(entity_mmicon_throb),
|
|
luaRegister(node_mmicon_delete),
|
|
luaRegister(node_mmicon_tex),
|
|
luaRegister(node_mmicon_size),
|
|
luaRegister(node_mmicon_color),
|
|
luaRegister(node_mmicon_alpha),
|
|
luaRegister(node_mmicon_scaleWithDistance),
|
|
luaRegister(node_mmicon_throb),
|
|
|
|
luaRegister(loadXMLTable),
|
|
|
|
#undef MK_FUNC
|
|
#undef MK_ALIAS
|
|
#define MK_FUNC(base, getter, prefix, suffix) luaRegister(prefix##_##suffix),
|
|
#define MK_STR(s) #s
|
|
#define MK_ALIAS(prefix, suffix, alias) {MK_STR(prefix) "_" MK_STR(alias), l_##prefix##_##suffix},
|
|
|
|
EXPAND_FUNC_PROTOTYPES
|
|
|
|
// obj_* are not in the define above
|
|
MAKE_ROBJ_FUNCS(_, obj)
|
|
// same for quad_* base functions
|
|
MAKE_QUAD_FUNCS(_, quad)
|
|
|
|
// -- overrides / special cases--
|
|
|
|
{"bone_getPosition", l_bone_getWorldPosition},
|
|
{ "entity_delete", l_entity_delete_override },
|
|
{ "entity_setRenderPass", l_entity_setRenderPass_override },
|
|
{ "beam_setPosition", l_beam_setPosition_override },
|
|
|
|
// -- deprecated/compatibility related functions below here --
|
|
|
|
luaRegister(entity_incrTargetLeaches),
|
|
luaRegister(entity_decrTargetLeaches),
|
|
{"entity_soundFreq", l_entity_sound},
|
|
{"entity_interpolateTo", l_entity_setPosition},
|
|
{"entity_isFlippedHorizontal", l_entity_isfh},
|
|
{"entity_isFlippedVertical", l_entity_isfv},
|
|
{"entity_rotateTo", l_entity_rotate},
|
|
{"entity_setColor", l_entity_color},
|
|
{"entity_setInternalOffset", l_entity_internalOffset},
|
|
{"getIngredientGfx", l_inv_getGfx},
|
|
|
|
{"bone_setColor", l_bone_color},
|
|
|
|
{"node_setEffectOn", l_node_setActive},
|
|
{"node_isEffectOn", l_node_isActive},
|
|
|
|
};
|
|
|
|
//============================================================================================
|
|
// S C R I P T C O N S T A N T S
|
|
//============================================================================================
|
|
|
|
#define luaConstant(name) {#name, name}
|
|
#define luaConstantFromClass(name,class) {#name, class::name}
|
|
|
|
static const struct {
|
|
const char *name;
|
|
lua_Number value;
|
|
} luaConstantTable[] = {
|
|
|
|
{"AQUARIA_VERSION", VERSION_MAJOR*10000 + VERSION_MINOR*100 + VERSION_REVISION},
|
|
|
|
// emotes
|
|
luaConstant(EMOTE_NAIJAEVILLAUGH),
|
|
luaConstant(EMOTE_NAIJAGIGGLE),
|
|
luaConstant(EMOTE_NAIJALAUGH),
|
|
luaConstant(EMOTE_NAIJASADSIGH),
|
|
luaConstant(EMOTE_NAIJASIGH),
|
|
luaConstant(EMOTE_NAIJAWOW),
|
|
luaConstant(EMOTE_NAIJAUGH),
|
|
luaConstant(EMOTE_NAIJALOW),
|
|
luaConstant(EMOTE_NAIJALI),
|
|
{"EMOTE_NAIJAEW", 9}, // FIXME: unused
|
|
|
|
// Li expressions
|
|
{"EXPRESSION_NORMAL", 0},
|
|
{"EXPRESSION_ANGRY", 1},
|
|
{"EXPRESSION_HAPPY", 2},
|
|
{"EXPRESSION_HURT", 3},
|
|
{"EXPRESSION_LAUGH", 4},
|
|
{"EXPRESSION_SURPRISE", 5},
|
|
|
|
luaConstantFromClass(OVERRIDE_NONE, RenderObject),
|
|
|
|
//actions
|
|
luaConstant(ACTION_MENULEFT),
|
|
luaConstant(ACTION_MENURIGHT),
|
|
luaConstant(ACTION_MENUUP),
|
|
luaConstant(ACTION_MENUDOWN),
|
|
|
|
{"WATCH_QUIT", 1},
|
|
|
|
{"BEACON_HOMECAVE", 1},
|
|
{"BEACON_ENERGYTEMPLE", 2},
|
|
{"BEACON_MITHALAS", 3},
|
|
{"BEACON_FOREST", 4},
|
|
{"BEACON_LI", 5},
|
|
{"BEACON_SUNTEMPLE", 6},
|
|
{"BEACON_SONGCAVE", 7},
|
|
|
|
{"PLAT_WIN", 0},
|
|
{"PLAT_MAC", 1},
|
|
{"PLAT_LNX", 2},
|
|
|
|
// ingredient effect types
|
|
luaConstant(IET_NONE),
|
|
luaConstant(IET_HP),
|
|
luaConstant(IET_DEFENSE),
|
|
luaConstant(IET_SPEED),
|
|
luaConstant(IET_RANDOM),
|
|
luaConstant(IET_MAXHP),
|
|
luaConstant(IET_INVINCIBLE),
|
|
luaConstant(IET_TRIP),
|
|
luaConstant(IET_REGEN),
|
|
luaConstant(IET_LI),
|
|
luaConstant(IET_FISHPOISON),
|
|
luaConstant(IET_BITE),
|
|
luaConstant(IET_EAT),
|
|
luaConstant(IET_LIGHT),
|
|
luaConstant(IET_YUM),
|
|
luaConstant(IET_PETPOWER),
|
|
luaConstant(IET_WEB),
|
|
luaConstant(IET_ENERGY),
|
|
luaConstant(IET_POISON),
|
|
luaConstant(IET_BLIND),
|
|
luaConstant(IET_ALLSTATUS),
|
|
luaConstant(IET_MAX),
|
|
|
|
// menu pages
|
|
luaConstant(MENUPAGE_NONE),
|
|
luaConstant(MENUPAGE_SONGS),
|
|
luaConstant(MENUPAGE_FOOD),
|
|
luaConstant(MENUPAGE_TREASURES),
|
|
luaConstant(MENUPAGE_PETS),
|
|
|
|
// Entity States
|
|
luaConstantFromClass(STATE_DEAD, Entity),
|
|
luaConstantFromClass(STATE_IDLE, Entity),
|
|
luaConstantFromClass(STATE_PUSH, Entity),
|
|
luaConstantFromClass(STATE_PUSHDELAY, Entity),
|
|
luaConstantFromClass(STATE_PLANTED, Entity),
|
|
luaConstantFromClass(STATE_PULLED, Entity),
|
|
luaConstantFromClass(STATE_FOLLOWNAIJA, Entity),
|
|
luaConstantFromClass(STATE_DEATHSCENE, Entity),
|
|
luaConstantFromClass(STATE_ATTACK, Entity),
|
|
luaConstantFromClass(STATE_CHARGE0, Entity),
|
|
luaConstantFromClass(STATE_CHARGE1, Entity),
|
|
luaConstantFromClass(STATE_CHARGE2, Entity),
|
|
luaConstantFromClass(STATE_CHARGE3, Entity),
|
|
luaConstantFromClass(STATE_WAIT, Entity),
|
|
luaConstantFromClass(STATE_HUG, Entity),
|
|
luaConstantFromClass(STATE_EATING, Entity),
|
|
luaConstantFromClass(STATE_FOLLOW, Entity),
|
|
luaConstantFromClass(STATE_TITLE, Entity),
|
|
// Remainder are script-specific, not used by C++ code
|
|
{"STATE_HATCH", 25},
|
|
{"STATE_CARRIED", 26},
|
|
|
|
{"STATE_HOSTILE", 100},
|
|
|
|
{"STATE_CLOSE", 200},
|
|
{"STATE_OPEN", 201},
|
|
{"STATE_CLOSED", 202},
|
|
{"STATE_OPENED", 203},
|
|
{"STATE_CHARGED", 300},
|
|
{"STATE_INHOLDER", 301},
|
|
{"STATE_DISABLED", 302},
|
|
{"STATE_FLICKER", 303},
|
|
{"STATE_ACTIVE", 304},
|
|
{"STATE_USED", 305},
|
|
{"STATE_BLOATED", 306},
|
|
{"STATE_DELAY", 307},
|
|
{"STATE_DONE", 309},
|
|
{"STATE_RAGE", 310},
|
|
{"STATE_CALM", 311},
|
|
{"STATE_DESCEND", 312},
|
|
{"STATE_SING", 313},
|
|
{"STATE_TRANSFORM", 314},
|
|
{"STATE_GROW", 315},
|
|
{"STATE_MATING", 316},
|
|
{"STATE_SHRINK", 317},
|
|
{"STATE_MOVE", 319},
|
|
{"STATE_TRANSITION", 320},
|
|
{"STATE_TRANSITION2", 321},
|
|
{"STATE_TRAPPEDINCREATOR", 322},
|
|
{"STATE_GRAB", 323},
|
|
{"STATE_FIGURE", 324},
|
|
{"STATE_CUTSCENE", 325},
|
|
{"STATE_WAITFORCUTSCENE", 326},
|
|
{"STATE_FIRE", 327},
|
|
{"STATE_FIRING", 328},
|
|
{"STATE_PREP", 329},
|
|
{"STATE_INTRO", 330},
|
|
{"STATE_PUPPET", 331},
|
|
|
|
{"STATE_COLLECT", 400},
|
|
{"STATE_COLLECTED", 401},
|
|
{"STATE_COLLECTEDINHOUSE", 402},
|
|
|
|
|
|
//{"STATE_ATTACK"}, 500},
|
|
{"STATE_STEP", 501},
|
|
{"STATE_AWAKEN", 502},
|
|
|
|
{"STATE_WEAK", 600},
|
|
{"STATE_BREAK", 601},
|
|
{"STATE_BROKEN", 602},
|
|
|
|
{"STATE_PULSE", 700},
|
|
{"STATE_ON", 701},
|
|
{"STATE_OFF", 702},
|
|
{"STATE_SEED", 703},
|
|
{"STATE_PLANTED", 704},
|
|
{"STATE_SK_RED", 705},
|
|
{"STATE_SK_GREEN", 706},
|
|
{"STATE_SK_BLUE", 707},
|
|
{"STATE_SK_YELLOW", 708},
|
|
{"STATE_WAITFORKISS", 710},
|
|
{"STATE_KISS", 711},
|
|
{"STATE_START", 712},
|
|
{"STATE_RACE", 714},
|
|
{"STATE_RESTART", 715},
|
|
{"STATE_APPEAR", 716},
|
|
|
|
{"STATE_MOVETOWEED", 2000},
|
|
{"STATE_PULLWEED", 2001},
|
|
{"STATE_DONEWEED", 2002},
|
|
|
|
{"ORIENT_NONE", -1},
|
|
{"ORIENT_LEFT", 0},
|
|
{"ORIENT_RIGHT", 1},
|
|
{"ORIENT_UP", 2},
|
|
{"ORIENT_DOWN", 3},
|
|
{"ORIENT_HORIZONTAL", 4},
|
|
{"ORIENT_VERTICAL", 5},
|
|
|
|
// for entity_isNearObstruction
|
|
luaConstant(OBSCHECK_RANGE),
|
|
luaConstant(OBSCHECK_4DIR),
|
|
luaConstant(OBSCHECK_DOWN),
|
|
luaConstant(OBSCHECK_8DIR),
|
|
|
|
luaConstant(EV_WALLOUT),
|
|
luaConstant(EV_WALLTRANS),
|
|
luaConstant(EV_CLAMPING),
|
|
luaConstant(EV_SWITCHCLAMP),
|
|
luaConstant(EV_CLAMPTRANSF),
|
|
luaConstant(EV_MOVEMENT),
|
|
luaConstant(EV_COLLIDE),
|
|
luaConstant(EV_TOUCHDMG),
|
|
luaConstant(EV_FRICTION),
|
|
luaConstant(EV_LOOKAT),
|
|
luaConstant(EV_CRAWLING),
|
|
luaConstant(EV_ENTITYDIED),
|
|
luaConstant(EV_TYPEID),
|
|
luaConstant(EV_COLLIDELEVEL),
|
|
luaConstant(EV_BONELOCKED),
|
|
luaConstant(EV_FLIPTOPATH),
|
|
luaConstant(EV_NOINPUTNOVEL),
|
|
luaConstant(EV_VINEPUSH),
|
|
luaConstant(EV_BEASTBURST),
|
|
luaConstant(EV_MINIMAP),
|
|
luaConstant(EV_SOULSCREAMRADIUS),
|
|
luaConstant(EV_WEBSLOW),
|
|
luaConstant(EV_NOAVOID),
|
|
luaConstant(EV_MAX),
|
|
|
|
{"EVT_NONE", 0},
|
|
{"EVT_THERMALVENT", 1},
|
|
{"EVT_GLOBEJELLY", 2},
|
|
{"EVT_CELLWHITE", 3},
|
|
{"EVT_CELLRED", 4},
|
|
{"EVT_PET", 5},
|
|
{"EVT_DARKLISHOT", 6},
|
|
{"EVT_ROCK", 7},
|
|
{"EVT_FORESTGODVINE", 8},
|
|
{"EVT_CONTAINER", 9},
|
|
{"EVT_PISTOLSHRIMP", 10},
|
|
{"EVT_GATEWAYMUTANT", 11},
|
|
|
|
|
|
// PATH/node types
|
|
luaConstant(PATH_NONE),
|
|
luaConstant(PATH_CURRENT),
|
|
luaConstant(PATH_STEAM),
|
|
luaConstant(PATH_LI),
|
|
luaConstant(PATH_SAVEPOINT),
|
|
luaConstant(PATH_WARP),
|
|
luaConstant(PATH_SPIRITPORTAL),
|
|
luaConstant(PATH_BGSFXLOOP),
|
|
luaConstant(PATH_RADARHIDE),
|
|
luaConstant(PATH_COOK),
|
|
luaConstant(PATH_WATERBUBBLE),
|
|
luaConstant(PATH_GEM),
|
|
luaConstant(PATH_SETING),
|
|
luaConstant(PATH_SETENT),
|
|
|
|
// Entity Types
|
|
luaConstant(ET_AVATAR),
|
|
luaConstant(ET_ENEMY),
|
|
luaConstant(ET_PET),
|
|
luaConstant(ET_FLOCK),
|
|
luaConstant(ET_NEUTRAL),
|
|
luaConstant(ET_INGREDIENT),
|
|
|
|
luaConstant(EP_SOLID),
|
|
luaConstant(EP_MOVABLE),
|
|
luaConstant(EP_BATTERY),
|
|
luaConstant(EP_BLOCKER),
|
|
|
|
// ACTIVATION TYPES
|
|
{"AT_NONE", -1},
|
|
{"AT_NORMAL", 0},
|
|
{"AT_CLICK", 0},
|
|
{"AT_RANGE", 1},
|
|
|
|
luaConstant(WT_NORMAL),
|
|
luaConstant(WT_SPIRIT),
|
|
|
|
{"SPEED_NORMAL", 0},
|
|
{"SPEED_SLOW", 1},
|
|
{"SPEED_FAST", 2},
|
|
{"SPEED_VERYFAST", 3},
|
|
{"SPEED_MODSLOW", 4},
|
|
{"SPEED_VERYSLOW", 5},
|
|
{"SPEED_FAST2", 6},
|
|
{"SPEED_LITOCAVE", 7},
|
|
|
|
luaConstant(BOUNCE_NONE),
|
|
luaConstant(BOUNCE_SIMPLE),
|
|
luaConstant(BOUNCE_REAL),
|
|
|
|
{"LOOP_INFINITE", -1},
|
|
{"LOOP_INF", -1},
|
|
|
|
{"LAYER_BODY", 0},
|
|
{"LAYER_UPPERBODY", 1},
|
|
{"LAYER_HEAD", 2},
|
|
{"LAYER_OVERRIDE", 3},
|
|
|
|
luaConstant(SONG_NONE),
|
|
luaConstant(SONG_HEAL),
|
|
luaConstant(SONG_ENERGYFORM),
|
|
luaConstant(SONG_SONGDOOR1),
|
|
luaConstant(SONG_SPIRITFORM),
|
|
luaConstant(SONG_BIND),
|
|
{"SONG_PULL", SONG_BIND},
|
|
luaConstant(SONG_NATUREFORM),
|
|
luaConstant(SONG_BEASTFORM),
|
|
luaConstant(SONG_SHIELDAURA),
|
|
{"SONG_SHIELD", SONG_SHIELDAURA},
|
|
luaConstant(SONG_SONGDOOR2),
|
|
luaConstant(SONG_DUALFORM),
|
|
luaConstant(SONG_FISHFORM),
|
|
luaConstant(SONG_SUNFORM),
|
|
{"SONG_LIGHTFORM", SONG_SUNFORM},
|
|
luaConstant(SONG_LI),
|
|
luaConstant(SONG_TIME),
|
|
luaConstant(SONG_LANCE),
|
|
luaConstant(SONG_MAP),
|
|
luaConstant(SONG_ANIMA),
|
|
luaConstant(SONG_MAX),
|
|
|
|
luaConstantFromClass(BLEND_DEFAULT, RenderObject),
|
|
luaConstantFromClass(BLEND_ADD, RenderObject),
|
|
{"BLEND_ADDITIVE", RenderObject::BLEND_ADD},
|
|
luaConstantFromClass(BLEND_SUB, RenderObject),
|
|
luaConstantFromClass(BLEND_MULT, RenderObject),
|
|
|
|
{"ENDING_NAIJACAVE", 10},
|
|
{"ENDING_NAIJACAVEDONE", 11},
|
|
{"ENDING_SECRETCAVE", 12},
|
|
{"ENDING_MAINAREA", 13},
|
|
{"ENDING_DONE", 14},
|
|
|
|
|
|
{"FLAG_SONGCAVECRYSTAL", 20},
|
|
{"FLAG_TEIRA", 50},
|
|
{"FLAG_SHARAN", 51},
|
|
{"FLAG_DRASK", 52},
|
|
{"FLAG_VEDHA", 53},
|
|
|
|
{"FLAG_ENERGYTEMPLE01DOOR", 100},
|
|
{"FLAG_ENERGYDOOR02", 101},
|
|
{"FLAG_ENERGYSLOT01", 102},
|
|
{"FLAG_ENERGYSLOT02", 103},
|
|
{"FLAG_ENERGYSLOT_MAINAREA", 104},
|
|
{"FLAG_MAINAREA_ENERGYTEMPLE_ROCK", 105},
|
|
{"FLAG_ENERGYSLOT_FIRST", 106},
|
|
{"FLAG_ENERGYDOOR03", 107},
|
|
{"FLAG_ENERGYGODENCOUNTER", 108},
|
|
{"FLAG_ENERGYBOSSDEAD", 109},
|
|
{"FLAG_MAINAREA_ETENTER2", 110},
|
|
{"FLAG_SUNTEMPLE_WATERLEVEL", 111},
|
|
{"FLAG_SUNTEMPLE_LIGHTCRYSTAL", 112},
|
|
{"FLAG_SUNKENCITY_PUZZLE", 113},
|
|
{"FLAG_SUNKENCITY_BOSS", 114},
|
|
{"FLAG_MITHALAS_THRONEROOM", 115},
|
|
{"FLAG_BOSS_MITHALA", 116},
|
|
{"FLAG_BOSS_FOREST", 117},
|
|
{"FLAG_FISHCAVE", 118},
|
|
{"FLAG_VISION_VEIL", 119},
|
|
{"FLAG_MITHALAS_PRIESTS", 120},
|
|
{"FLAG_FIRSTTRANSTURTLE", 121},
|
|
{"FLAG_13PROGRESSION", 122},
|
|
{"FLAG_FINAL", 123},
|
|
{"FLAG_SPIRIT_ERULIAN", 124},
|
|
{"FLAG_SPIRIT_KROTITE", 125},
|
|
{"FLAG_SPIRIT_DRASK", 126},
|
|
{"FLAG_SPIRIT_DRUNIAD", 127},
|
|
{"FLAG_BOSS_SUNWORM", 128},
|
|
{"FLAG_WHALELAMPPUZZLE", 129},
|
|
|
|
{"FLAG_TRANSTURTLE_VEIL01", 130},
|
|
{"FLAG_TRANSTURTLE_OPENWATER06", 131},
|
|
{"FLAG_TRANSTURTLE_FOREST04", 132},
|
|
{"FLAG_TRANSTURTLE_OPENWATER03", 133},
|
|
{"FLAG_TRANSTURTLE_FOREST05", 134},
|
|
{"FLAG_TRANSTURTLE_MAINAREA", 135},
|
|
{"FLAG_TRANSTURTLE_SEAHORSE", 136},
|
|
{"FLAG_TRANSTURTLE_VEIL02", 137},
|
|
{"FLAG_TRANSTURTLE_ABYSS03", 138},
|
|
{"FLAG_TRANSTURTLE_FINALBOSS", 139},
|
|
|
|
{"FLAG_NAIJA_SWIM", 200},
|
|
{"FLAG_NAIJA_MINIMAP", 201},
|
|
{"FLAG_NAIJA_SPEEDBOOST", 202},
|
|
{"FLAG_NAIJA_MEMORYCRYSTAL", 203},
|
|
{"FLAG_NAIJA_SINGING", 204},
|
|
{"FLAG_NAIJA_LEAVESVEDHA", 205},
|
|
{"FLAG_NAIJA_SONGDOOR", 206},
|
|
{"FLAG_NAIJA_ENTERVEDHACAVE", 207},
|
|
{"FLAG_NAIJA_INTERACT", 208},
|
|
{"FLAG_NAIJA_ENTERSONGCAVE", 209},
|
|
{"FLAG_NAIJA_ENERGYFORMSHOT", 210},
|
|
{"FLAG_NAIJA_ENERGYFORMCHARGE", 211},
|
|
{"FLAG_NAIJA_RETURNTONORMALFORM", 212},
|
|
{"FLAG_NAIJA_ENERGYBARRIER", 213},
|
|
{"FLAG_NAIJA_SOLIDENERGYBARRIER", 214},
|
|
{"FLAG_NAIJA_ENTERENERGYTEMPLE", 215},
|
|
{"FLAG_NAIJA_OPENWATERS", 216},
|
|
{"FLAG_NAIJA_SINGING", 217},
|
|
{"FLAG_NAIJA_INGAMEMENU", 218},
|
|
{"FLAG_NAIJA_SINGINGHINT", 219},
|
|
{"FLAG_NAIJA_LOOK", 220},
|
|
{"FLAG_HINT_MINIMAP", 221},
|
|
{"FLAG_HINT_HEALTHPLANT", 222},
|
|
{"FLAG_HINT_SLEEP", 223},
|
|
{"FLAG_HINT_COLLECTIBLE", 224},
|
|
{"FLAG_HINT_IGFDEMO", 225},
|
|
{"FLAG_HINT_BEASTFORM1", 226},
|
|
{"FLAG_HINT_BEASTFORM2", 227},
|
|
{"FLAG_HINT_LISONG", 228},
|
|
{"FLAG_HINT_ENERGYTARGET", 229},
|
|
{"FLAG_HINT_NATUREFORMABILITY", 230},
|
|
{"FLAG_HINT_LICOMBAT", 231},
|
|
{"FLAG_HINT_COOKING", 232},
|
|
{"FLAG_NAIJA_FIRSTVINE", 233},
|
|
luaConstant(FLAG_SECRET01),
|
|
luaConstant(FLAG_SECRET02),
|
|
luaConstant(FLAG_SECRET03),
|
|
{"FLAG_DEEPWHALE", 237},
|
|
{"FLAG_OMPO", 238},
|
|
{"FLAG_HINT_SINGBULB", 239},
|
|
{"FLAG_ENDING", 240},
|
|
{"FLAG_NAIJA_BINDSHELL", 241},
|
|
{"FLAG_NAIJA_BINDROCK", 242},
|
|
{"FLAG_HINT_ROLLGEAR", 243},
|
|
{"FLAG_FIRSTHEALTHUPGRADE", 244},
|
|
{"FLAG_MAINAREA_TRANSTURTLE_ROCK", 245},
|
|
{"FLAG_SKIPSECRETCHECK", 246},
|
|
{"FLAG_SEAHORSEBESTTIME", 247},
|
|
{"FLAG_SEAHORSETIMETOBEAT", 248},
|
|
{"FLAG_HINT_BINDMERMEN", 249},
|
|
|
|
|
|
{"FLAG_CREATORVOICE", 250},
|
|
|
|
{"FLAG_HINT_DUALFORMCHANGE", 251},
|
|
{"FLAG_HINT_DUALFORMCHARGE", 252},
|
|
{"FLAG_HINT_HEALTHUPGRADE", 253},
|
|
|
|
{"FLAG_VISION_ENERGYTEMPLE", 300},
|
|
|
|
luaConstant(FLAG_COLLECTIBLE_START),
|
|
{"FLAG_COLLECTIBLE_SONGCAVE", 500},
|
|
{"FLAG_COLLECTIBLE_ENERGYTEMPLE", 501},
|
|
{"FLAG_COLLECTIBLE_ENERGYSTATUE", 502},
|
|
{"FLAG_COLLECTIBLE_ENERGYBOSS", 503},
|
|
{"FLAG_COLLECTIBLE_NAIJACAVE", 504},
|
|
{"FLAG_COLLECTIBLE_CRABCOSTUME", 505},
|
|
{"FLAG_COLLECTIBLE_JELLYPLANT", 506},
|
|
{"FLAG_COLLECTIBLE_MITHALASPOT", 507},
|
|
{"FLAG_COLLECTIBLE_SEAHORSECOSTUME", 508},
|
|
{"FLAG_COLLECTIBLE_CHEST", 509},
|
|
{"FLAG_COLLECTIBLE_BANNER", 510},
|
|
{"FLAG_COLLECTIBLE_MITHALADOLL", 511},
|
|
{"FLAG_COLLECTIBLE_WALKERBABY", 512},
|
|
{"FLAG_COLLECTIBLE_SEEDBAG", 513},
|
|
{"FLAG_COLLECTIBLE_ARNASSISTATUE", 514},
|
|
{"FLAG_COLLECTIBLE_GEAR", 515},
|
|
{"FLAG_COLLECTIBLE_SUNKEY", 516},
|
|
{"FLAG_COLLECTIBLE_URCHINCOSTUME", 517},
|
|
{"FLAG_COLLECTIBLE_TEENCOSTUME", 518},
|
|
{"FLAG_COLLECTIBLE_MUTANTCOSTUME", 519},
|
|
{"FLAG_COLLECTIBLE_JELLYCOSTUME", 520},
|
|
{"FLAG_COLLECTIBLE_MITHALANCOSTUME", 521},
|
|
{"FLAG_COLLECTIBLE_ANEMONESEED", 522},
|
|
{"FLAG_COLLECTIBLE_BIOSEED", 523},
|
|
{"FLAG_COLLECTIBLE_TURTLEEGG", 524},
|
|
{"FLAG_COLLECTIBLE_SKULL", 525},
|
|
{"FLAG_COLLECTIBLE_TRIDENTHEAD", 526},
|
|
{"FLAG_COLLECTIBLE_SPORESEED", 527},
|
|
{"FLAG_COLLECTIBLE_UPSIDEDOWNSEED", 528},
|
|
{"FLAG_COLLECTIBLE_STONEHEAD", 529},
|
|
{"FLAG_COLLECTIBLE_STARFISH", 530},
|
|
{"FLAG_COLLECTIBLE_BLACKPEARL", 531},
|
|
luaConstant(FLAG_COLLECTIBLE_END),
|
|
|
|
luaConstant(FLAG_PET_ACTIVE),
|
|
luaConstant(FLAG_PET_NAMESTART),
|
|
{"FLAG_PET_NAUTILUS", 601},
|
|
{"FLAG_PET_DUMBO", 602},
|
|
{"FLAG_PET_BLASTER", 603},
|
|
{"FLAG_PET_PIRANHA", 604},
|
|
|
|
luaConstant(FLAG_UPGRADE_WOK),
|
|
// does the player have access to 3 slots all the time?
|
|
|
|
{"FLAG_COLLECTIBLE_NAUTILUSPRIME", 630},
|
|
{"FLAG_COLLECTIBLE_DUMBOEGG", 631},
|
|
{"FLAG_COLLECTIBLE_BLASTEREGG", 632},
|
|
{"FLAG_COLLECTIBLE_PIRANHAEGG", 633},
|
|
|
|
{"FLAG_ENTER_HOMEWATERS", 650},
|
|
{"FLAG_ENTER_SONGCAVE", 651},
|
|
{"FLAG_ENTER_ENERGYTEMPLE", 652},
|
|
{"FLAG_ENTER_OPENWATERS", 653},
|
|
{"FLAG_ENTER_HOMECAVE", 654},
|
|
{"FLAG_ENTER_FOREST", 655},
|
|
{"FLAG_ENTER_VEIL", 656},
|
|
{"FLAG_ENTER_MITHALAS", 657},
|
|
{"FLAG_ENTER_MERMOGCAVE", 658},
|
|
{"FLAG_ENTER_MITHALAS", 659},
|
|
{"FLAG_ENTER_SUNTEMPLE", 660},
|
|
{"FLAG_ENTER_ABYSS", 661},
|
|
{"FLAG_ENTER_SUNKENCITY", 662},
|
|
{"FLAG_ENTER_FORESTSPRITECAVE", 663},
|
|
{"FLAG_ENTER_FISHCAVE", 664},
|
|
{"FLAG_ENTER_MITHALASCATHEDRAL", 665},
|
|
{"FLAG_ENTER_TURTLECAVE", 666},
|
|
{"FLAG_ENTER_FROZENVEIL", 667},
|
|
{"FLAG_ENTER_ICECAVE", 668},
|
|
{"FLAG_ENTER_SEAHORSE", 669},
|
|
|
|
|
|
{"FLAG_MINIBOSS_START", 700},
|
|
{"FLAG_MINIBOSS_NAUTILUSPRIME", 700},
|
|
{"FLAG_MINIBOSS_KINGJELLY", 701},
|
|
{"FLAG_MINIBOSS_MERGOG", 702},
|
|
{"FLAG_MINIBOSS_CRAB", 703},
|
|
{"FLAG_MINIBOSS_OCTOMUN", 704},
|
|
{"FLAG_MINIBOSS_MANTISSHRIMP", 705},
|
|
{"FLAG_MINIBOSS_PRIESTS", 706},
|
|
{"FLAG_MINIBOSS_END", 720},
|
|
|
|
{"FLAG_MAMATURTLE_RESCUE1", 750},
|
|
{"FLAG_MAMATURTLE_RESCUE2", 751},
|
|
{"FLAG_MAMATURTLE_RESCUE3", 752},
|
|
|
|
{"FLAG_SONGDOOR1", 800},
|
|
luaConstant(FLAG_SEALOAFANNOYANCE),
|
|
|
|
{"FLAG_SEAL_KING", 900},
|
|
{"FLAG_SEAL_QUEEN", 901},
|
|
{"FLAG_SEAL_PRINCE", 902},
|
|
|
|
{"FLAG_HEALTHUPGRADES", 950},
|
|
{"FLAG_HEALTHUPGRADES_END", 960},
|
|
|
|
luaConstant(FLAG_LI),
|
|
luaConstant(FLAG_LICOMBAT),
|
|
|
|
|
|
|
|
luaConstant(MAX_FLAGS),
|
|
|
|
{"ALPHA_NEARZERO", 0.001},
|
|
|
|
{"SUNKENCITY_START", 0},
|
|
{"SUNKENCITY_CLIMBDOWN", 1},
|
|
{"SUNKENCITY_RUNAWAY", 2},
|
|
{"SUNKENCITY_INHOLE", 3},
|
|
{"SUNKENCITY_GF", 4},
|
|
{"SUNKENCITY_BULLIES", 5},
|
|
{"SUNKENCITY_ANIMA", 6},
|
|
{"SUNKENCITY_BOSSWAIT", 7},
|
|
{"SUNKENCITY_CLAY1", 8},
|
|
{"SUNKENCITY_CLAY2", 9},
|
|
{"SUNKENCITY_CLAY3", 10},
|
|
{"SUNKENCITY_CLAY4", 11},
|
|
{"SUNKENCITY_CLAY5", 12},
|
|
{"SUNKENCITY_CLAY6", 13},
|
|
{"SUNKENCITY_CLAYDONE", 14},
|
|
{"SUNKENCITY_BOSSFIGHT", 15},
|
|
{"SUNKENCITY_BOSSDONE", 16},
|
|
{"SUNKENCITY_FINALTONGUE", 17},
|
|
|
|
{"FINAL_START", 0},
|
|
{"FINAL_SOMETHING", 1},
|
|
{"FINAL_FREEDLI", 2},
|
|
|
|
luaConstantFromClass(ANIM_NONE, Bone),
|
|
luaConstantFromClass(ANIM_POS, Bone),
|
|
luaConstantFromClass(ANIM_ROT, Bone),
|
|
luaConstantFromClass(ANIM_ALL, Bone),
|
|
|
|
luaConstant(FORM_NORMAL),
|
|
luaConstant(FORM_ENERGY),
|
|
luaConstant(FORM_BEAST),
|
|
luaConstant(FORM_NATURE),
|
|
luaConstant(FORM_SPIRIT),
|
|
luaConstant(FORM_DUAL),
|
|
luaConstant(FORM_FISH),
|
|
luaConstant(FORM_SUN),
|
|
{"FORM_LIGHT", FORM_SUN},
|
|
luaConstant(FORM_MAX),
|
|
|
|
luaConstant(VFX_SHOCK),
|
|
luaConstant(VFX_RIPPLE),
|
|
|
|
luaConstant(EAT_NONE),
|
|
luaConstant(EAT_DEFAULT),
|
|
luaConstant(EAT_FILE),
|
|
luaConstant(EAT_MAX),
|
|
|
|
luaConstant(DT_NONE),
|
|
luaConstant(DT_ENEMY),
|
|
luaConstant(DT_ENEMY_ENERGYBLAST),
|
|
luaConstant(DT_ENEMY_SHOCK),
|
|
luaConstant(DT_ENEMY_BITE),
|
|
luaConstant(DT_ENEMY_TRAP),
|
|
luaConstant(DT_ENEMY_WEB),
|
|
luaConstant(DT_ENEMY_BEAM),
|
|
luaConstant(DT_ENEMY_GAS),
|
|
luaConstant(DT_ENEMY_INK),
|
|
luaConstant(DT_ENEMY_POISON),
|
|
luaConstant(DT_ENEMY_ACTIVEPOISON),
|
|
luaConstant(DT_ENEMY_CREATOR),
|
|
luaConstant(DT_ENEMY_MANTISBOMB),
|
|
luaConstant(DT_ENEMY_MAX),
|
|
{"DT_ENEMY_END", DT_ENEMY_MAX},
|
|
|
|
luaConstant(DT_AVATAR),
|
|
luaConstant(DT_AVATAR_ENERGYBLAST),
|
|
luaConstant(DT_AVATAR_SHOCK),
|
|
luaConstant(DT_AVATAR_BITE),
|
|
luaConstant(DT_AVATAR_VOMIT),
|
|
luaConstant(DT_AVATAR_ACID),
|
|
luaConstant(DT_AVATAR_SPORECHILD),
|
|
luaConstant(DT_AVATAR_LIZAP),
|
|
luaConstant(DT_AVATAR_NATURE),
|
|
luaConstant(DT_AVATAR_ENERGYROLL),
|
|
luaConstant(DT_AVATAR_VINE),
|
|
luaConstant(DT_AVATAR_EAT),
|
|
luaConstant(DT_AVATAR_EAT_BASICSHOT),
|
|
luaConstant(DT_AVATAR_EAT_MAX),
|
|
luaConstant(DT_AVATAR_LANCEATTACH),
|
|
luaConstant(DT_AVATAR_LANCE),
|
|
luaConstant(DT_AVATAR_CREATORSHOT),
|
|
luaConstant(DT_AVATAR_DUALFORMLI),
|
|
luaConstant(DT_AVATAR_DUALFORMNAIJA),
|
|
luaConstant(DT_AVATAR_BUBBLE),
|
|
luaConstant(DT_AVATAR_SEED),
|
|
luaConstant(DT_AVATAR_PET),
|
|
luaConstant(DT_AVATAR_PETNAUTILUS),
|
|
luaConstant(DT_AVATAR_PETBITE),
|
|
luaConstant(DT_AVATAR_MAX),
|
|
{"DT_AVATAR_END", DT_AVATAR_MAX},
|
|
|
|
luaConstant(DT_TOUCH),
|
|
luaConstant(DT_CRUSH),
|
|
luaConstant(DT_SPIKES),
|
|
luaConstant(DT_STEAM),
|
|
luaConstant(DT_WALLHURT),
|
|
|
|
|
|
luaConstant(FRAME_TIME),
|
|
|
|
luaConstant(FORMUPGRADE_ENERGY1),
|
|
luaConstant(FORMUPGRADE_ENERGY2),
|
|
luaConstant(FORMUPGRADE_BEAST),
|
|
|
|
luaConstant(TILE_SIZE),
|
|
|
|
luaConstant(INPUT_MOUSE),
|
|
luaConstant(INPUT_JOYSTICK),
|
|
luaConstant(INPUT_KEYBOARD),
|
|
|
|
luaConstant(ANIMLAYER_FLOURISH),
|
|
luaConstant(ANIMLAYER_OVERRIDE),
|
|
luaConstant(ANIMLAYER_ARMOVERRIDE),
|
|
luaConstant(ANIMLAYER_UPPERBODYIDLE),
|
|
luaConstant(ANIMLAYER_HEADOVERRIDE),
|
|
|
|
luaConstant(OT_EMPTY),
|
|
luaConstant(OT_BLACK),
|
|
luaConstant(OT_BLACKINVIS),
|
|
luaConstant(OT_INVISIBLE),
|
|
luaConstant(OT_INVISIBLEIN),
|
|
luaConstant(OT_HURT),
|
|
luaConstant(OT_INVISIBLEENT),
|
|
luaConstant(OT_USER1),
|
|
luaConstant(OT_USER2),
|
|
luaConstant(OT_MASK_BLACK),
|
|
luaConstant(OT_BLOCKING),
|
|
luaConstant(OT_USER_MASK),
|
|
luaConstant(OT_OUTOFBOUNDS),
|
|
|
|
luaConstant(SEE_MAP_NEVER),
|
|
luaConstant(SEE_MAP_DEFAULT),
|
|
luaConstant(SEE_MAP_ALWAYS),
|
|
|
|
luaConstant(ALIGN_CENTER),
|
|
luaConstant(ALIGN_LEFT),
|
|
|
|
luaConstant(PATHSHAPE_RECT),
|
|
luaConstant(PATHSHAPE_CIRCLE),
|
|
};
|
|
|
|
//============================================================================================
|
|
// F U N C T I O N S
|
|
//============================================================================================
|
|
|
|
ScriptInterface::ScriptInterface()
|
|
: baseState(NULL), _sballoc(8, 128)
|
|
{
|
|
}
|
|
|
|
void ScriptInterface::init()
|
|
{
|
|
bool devmode = dsq->isDeveloperKeys();
|
|
|
|
// Everything on in dev mode, everything off otherwise.
|
|
loudScriptErrors = devmode;
|
|
complainOnGlobalVar = devmode;
|
|
complainOnUndefLocal = devmode;
|
|
|
|
allowUnsafeFunctions = dsq->user.system.allowDangerousScriptFunctions;
|
|
|
|
if (!baseState)
|
|
baseState = createLuaVM();
|
|
}
|
|
|
|
void ScriptInterface::reset()
|
|
{
|
|
shutdown();
|
|
init();
|
|
}
|
|
|
|
void *ScriptInterface::the_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
|
|
{
|
|
ScriptInterface *this_ = (ScriptInterface*)ud;
|
|
return this_->_sballoc.Alloc(ptr, nsize, osize);
|
|
}
|
|
|
|
lua_State *ScriptInterface::createLuaVM()
|
|
{
|
|
lua_State *state = lua_newstate(the_alloc, this); /* opens Lua */
|
|
luaL_openlibs(state);
|
|
|
|
#ifdef LUAAPI_HAS_CLIPBOARD
|
|
lua_getglobal(state, "os");
|
|
lua_pushcfunction(state, l_os_getclipboard);
|
|
lua_setfield(state, -2, "getclipboard");
|
|
lua_pushcfunction(state, l_os_setclipboard);
|
|
lua_setfield(state, -2, "setclipboard");
|
|
lua_pop(state, 1);
|
|
#endif
|
|
|
|
if(!allowUnsafeFunctions)
|
|
{
|
|
lua_pushnil(state);
|
|
lua_setglobal(state, "os");
|
|
lua_pushnil(state);
|
|
lua_setglobal(state, "io");
|
|
lua_pushnil(state);
|
|
lua_setglobal(state, "package");
|
|
}
|
|
|
|
// Set up various tables for state management:
|
|
|
|
// -- Interface function tables for each script file.
|
|
lua_newtable(state);
|
|
lua_setglobal(state, "_scriptfuncs");
|
|
|
|
// -- Number of users (active threads) for each script file.
|
|
lua_newtable(state);
|
|
lua_setglobal(state, "_scriptusers");
|
|
|
|
// -- Initial instance-local tables for each script file.
|
|
lua_newtable(state);
|
|
lua_setglobal(state, "_scriptvars");
|
|
|
|
// -- Instance-local variable tables for each thread.
|
|
lua_newtable(state);
|
|
lua_setglobal(state, "_threadvars");
|
|
|
|
// -- Active threads (so they aren't garbage-collected).
|
|
lua_newtable(state);
|
|
lua_setglobal(state, "_threadtable");
|
|
|
|
// Register all custom functions and constants.
|
|
for (unsigned int i = 0; i < sizeof(luaFunctionTable)/sizeof(*luaFunctionTable); i++)
|
|
{
|
|
lua_register(state, luaFunctionTable[i].name, luaFunctionTable[i].func);
|
|
}
|
|
for (unsigned int i = 0; i < sizeof(luaConstantTable)/sizeof(*luaConstantTable); i++)
|
|
{
|
|
lua_pushnumber(state, luaConstantTable[i].value);
|
|
lua_setglobal(state, luaConstantTable[i].name);
|
|
}
|
|
|
|
// Add hooks to monitor global get/set operations if requested.
|
|
if (complainOnGlobalVar)
|
|
{
|
|
if (!lua_getmetatable(state, LUA_GLOBALSINDEX))
|
|
lua_newtable(state);
|
|
lua_pushcfunction(state, l_indexWarnGlobal);
|
|
lua_setfield(state, -2, "__index");
|
|
lua_pushcfunction(state, l_newindexWarnGlobal);
|
|
lua_setfield(state, -2, "__newindex");
|
|
lua_setmetatable(state, LUA_GLOBALSINDEX);
|
|
}
|
|
|
|
// In case a script errors outside of any protected environment, report and exit.
|
|
lua_atpanic(state, l_panicHandler);
|
|
|
|
// Register Lua classes
|
|
luaL_newmetatable(state, "pathfinder");
|
|
lua_pushliteral(state, "__gc");
|
|
lua_pushcfunction(state, _pathfindDelete);
|
|
lua_settable(state, -3);
|
|
lua_pop(state, 1);
|
|
|
|
// All done, return the new state.
|
|
return state;
|
|
}
|
|
|
|
void ScriptInterface::destroyLuaVM(lua_State *state)
|
|
{
|
|
if (state)
|
|
lua_close(state);
|
|
}
|
|
|
|
// Initial value for the instance-local table should be on the stack of
|
|
// the base Lua state; it will be popped when this function returns.
|
|
lua_State *ScriptInterface::createLuaThread(const std::string &file)
|
|
{
|
|
lua_State *thread = lua_newthread(baseState);
|
|
if (!thread)
|
|
{
|
|
lua_pop(baseState, 1);
|
|
return NULL;
|
|
}
|
|
|
|
// Save the thread object in a Lua table to prevent it from being
|
|
// garbage-collected.
|
|
lua_getglobal(baseState, "_threadtable");
|
|
lua_pushlightuserdata(baseState, thread);
|
|
lua_pushvalue(baseState, -3); // -3 = thread
|
|
lua_rawset(baseState, -3); // -3 = _threadtable
|
|
lua_pop(baseState, 2);
|
|
|
|
// Set up the instance-local variable table for this thread, copying
|
|
// the contents of the initial-value table.
|
|
lua_newtable(baseState);
|
|
lua_pushnil(baseState);
|
|
while (lua_next(baseState, -3))
|
|
{
|
|
// We need to save a copy of the key for the next iteration.
|
|
lua_pushvalue(baseState, -2);
|
|
lua_insert(baseState, -2);
|
|
lua_settable(baseState, -4);
|
|
}
|
|
lua_remove(baseState, -2); // We no longer need the original table.
|
|
if (complainOnUndefLocal)
|
|
{
|
|
if (!lua_getmetatable(baseState, -1))
|
|
lua_newtable(baseState);
|
|
lua_pushcfunction(baseState, l_indexWarnInstance);
|
|
lua_setfield(baseState, -2, "__index");
|
|
lua_setmetatable(baseState, -2);
|
|
}
|
|
lua_getglobal(baseState, "_threadvars");
|
|
lua_pushlightuserdata(baseState, thread);
|
|
lua_pushvalue(baseState, -3); // -3 = instance-local table
|
|
lua_rawset(baseState, -3); // -3 = _threadvars
|
|
lua_pop(baseState, 2);
|
|
|
|
// Update the usage count for this script.
|
|
lua_getglobal(baseState, "_scriptusers");
|
|
lua_getfield(baseState, -1, file.c_str());
|
|
const int users = lua_tointeger(baseState, -1) + 1;
|
|
lua_pop(baseState, 1);
|
|
lua_pushinteger(baseState, users);
|
|
lua_setfield(baseState, -2, file.c_str());
|
|
lua_pop(baseState, 1);
|
|
|
|
return thread;
|
|
}
|
|
|
|
// Returns the number of remaining users of this script.
|
|
int ScriptInterface::destroyLuaThread(const std::string &file, lua_State *thread)
|
|
{
|
|
// Threads are not explicitly closed; instead, we delete the thread
|
|
// resources from the state-global tables, thus allowing them to be
|
|
// garbage-collected. collectGarbage() can be called at a convenient
|
|
// time to forcibly free all dead thread resources.
|
|
|
|
lua_getglobal(baseState, "_threadtable");
|
|
lua_pushlightuserdata(baseState, thread);
|
|
lua_pushnil(baseState);
|
|
lua_rawset(baseState, -3);
|
|
lua_pop(baseState, 1);
|
|
|
|
lua_getglobal(baseState, "_threadvars");
|
|
lua_pushlightuserdata(baseState, thread);
|
|
lua_pushnil(baseState);
|
|
lua_rawset(baseState, -3);
|
|
lua_pop(baseState, 1);
|
|
|
|
lua_getglobal(baseState, "_scriptusers");
|
|
lua_getfield(baseState, -1, file.c_str());
|
|
const int users = lua_tointeger(baseState, -1) - 1;
|
|
lua_pop(baseState, 1);
|
|
if (users > 0)
|
|
lua_pushinteger(baseState, users);
|
|
else
|
|
lua_pushnil(baseState);
|
|
lua_setfield(baseState, -2, file.c_str());
|
|
lua_pop(baseState, 1);
|
|
|
|
return users;
|
|
}
|
|
|
|
void ScriptInterface::collectGarbage()
|
|
{
|
|
lua_gc(baseState, LUA_GCCOLLECT, 0);
|
|
}
|
|
|
|
int ScriptInterface::gcGetStats()
|
|
{
|
|
return lua_gc(baseState, LUA_GCCOUNT, 0);
|
|
}
|
|
|
|
void ScriptInterface::shutdown()
|
|
{
|
|
destroyLuaVM(baseState);
|
|
baseState = NULL;
|
|
}
|
|
|
|
Script *ScriptInterface::openScript(const std::string &file, bool ignoremissing /* = false */)
|
|
{
|
|
std::string realFile = localisePathInternalModpath(file);
|
|
realFile = adjustFilenameCase(realFile);
|
|
bool loadedScript = false;
|
|
|
|
lua_getglobal(baseState, "_scriptvars");
|
|
lua_getfield(baseState, -1, realFile.c_str());
|
|
lua_remove(baseState, -2);
|
|
if (!lua_istable(baseState, -1))
|
|
{
|
|
// We must not have loaded the script yet, so load it.
|
|
loadedScript = true;
|
|
|
|
// Clear out the (presumably nil) getfield() result from the stack.
|
|
lua_pop(baseState, 1);
|
|
|
|
// Create a new variable table for the initial run of the script.
|
|
// This will become the initial instance-local variable table for
|
|
// all instances of this script.
|
|
lua_newtable(baseState);
|
|
if (complainOnUndefLocal)
|
|
{
|
|
if (!lua_getmetatable(baseState, -1))
|
|
lua_newtable(baseState);
|
|
lua_pushcfunction(baseState, l_indexWarnInstance);
|
|
lua_setfield(baseState, -2, "__index");
|
|
lua_setmetatable(baseState, -2);
|
|
}
|
|
|
|
// Save the current value of the "v" global, so we can restore it
|
|
// after we run the script. (We do this here and in Script::call()
|
|
// so that nested Lua calls don't disrupt the caller's instance
|
|
// variable table.)
|
|
lua_getglobal(baseState, "v");
|
|
|
|
// Load the file itself. This leaves the Lua chunk on the stack.
|
|
int result = loadFile_helper(baseState, realFile.c_str());
|
|
if (result != 0)
|
|
{
|
|
if(result != LUA_ERRFILE || (result == LUA_ERRFILE && !ignoremissing))
|
|
scriptError("Error loading script [" + realFile + "]: " + lua_tostring(baseState, -1));
|
|
lua_pop(baseState, 2);
|
|
return NULL;
|
|
}
|
|
|
|
// Do the initial run of the script, popping the Lua chunk.
|
|
lua_getglobal(baseState, "_threadvars");
|
|
lua_pushlightuserdata(baseState, baseState);
|
|
lua_pushvalue(baseState, -5);
|
|
lua_settable(baseState, -3);
|
|
lua_pop(baseState, 1);
|
|
fixupLocalVars(baseState);
|
|
result = lua_pcall(baseState, 0, 0, 0);
|
|
lua_getglobal(baseState, "_threadvars");
|
|
lua_pushlightuserdata(baseState, baseState);
|
|
lua_pushnil(baseState);
|
|
lua_settable(baseState, -3);
|
|
lua_pop(baseState, 1);
|
|
if (result != 0)
|
|
{
|
|
scriptError("Error doing initial run of script [" + realFile + "]: " + lua_tostring(baseState, -1));
|
|
lua_pop(baseState, 2);
|
|
return NULL;
|
|
}
|
|
|
|
// Restore the old value of the "v" global.
|
|
lua_setglobal(baseState, "v");
|
|
|
|
// Store the instance-local table in the _scriptvars table.
|
|
lua_getglobal(baseState, "_scriptvars");
|
|
lua_pushvalue(baseState, -2);
|
|
lua_setfield(baseState, -2, realFile.c_str());
|
|
lua_pop(baseState, 1);
|
|
|
|
// Generate an interface function table for the script, and
|
|
// clear out the functions from the global environment.
|
|
lua_getglobal(baseState, "_scriptfuncs");
|
|
lua_newtable(baseState);
|
|
for (unsigned int i = 0; interfaceFunctions[i] != NULL; i++)
|
|
{
|
|
const char *funcName = interfaceFunctions[i];
|
|
lua_getglobal(baseState, funcName);
|
|
if (!lua_isnil(baseState, -1))
|
|
{
|
|
lua_setfield(baseState, -2, funcName);
|
|
lua_pushnil(baseState);
|
|
lua_setglobal(baseState, funcName);
|
|
}
|
|
else
|
|
{
|
|
lua_pop(baseState, 1);
|
|
}
|
|
}
|
|
lua_setfield(baseState, -2, realFile.c_str());
|
|
lua_pop(baseState, 1);
|
|
|
|
// Leave the instance-local table on the stack for createLuaThread().
|
|
}
|
|
|
|
lua_State *thread = createLuaThread(realFile.c_str());
|
|
if (!thread)
|
|
{
|
|
scriptError("Unable to create new thread for script [" + realFile + "]");
|
|
if (loadedScript)
|
|
{
|
|
lua_getglobal(baseState, "_scriptfuncs");
|
|
lua_pushnil(baseState);
|
|
lua_setfield(baseState, -2, realFile.c_str());
|
|
lua_pop(baseState, 1);
|
|
lua_getglobal(baseState, "_scriptvars");
|
|
lua_pushnil(baseState);
|
|
lua_setfield(baseState, -2, realFile.c_str());
|
|
lua_pop(baseState, 1);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
return new Script(thread, realFile);
|
|
}
|
|
|
|
void ScriptInterface::closeScript(Script *script)
|
|
{
|
|
const char *file = script->getFile().c_str();
|
|
int users = destroyLuaThread(file, script->getLuaState());
|
|
|
|
// If this was the last instance of this script, unload the script itself.
|
|
if (users <= 0)
|
|
{
|
|
lua_getglobal(baseState, "_scriptfuncs");
|
|
lua_pushnil(baseState);
|
|
lua_setfield(baseState, -2, file);
|
|
lua_pop(baseState, 1);
|
|
lua_getglobal(baseState, "_scriptvars");
|
|
lua_pushnil(baseState);
|
|
lua_setfield(baseState, -2, file);
|
|
lua_pop(baseState, 1);
|
|
}
|
|
|
|
delete script;
|
|
}
|
|
|
|
bool ScriptInterface::runScriptNum(const std::string &file, const std::string &func, int num)
|
|
{
|
|
std::string realFile = file;
|
|
if (file.find('/')==std::string::npos)
|
|
realFile = "scripts/" + file + ".lua";
|
|
Script *script = openScript(realFile);
|
|
if (!script)
|
|
return false;
|
|
|
|
if (!script->call(func.c_str(), num))
|
|
{
|
|
debugLog(script->getLastError());
|
|
debugLog("(error calling func: " + func + " in script: " + file + ")");
|
|
closeScript(script);
|
|
return false;
|
|
}
|
|
|
|
closeScript(script);
|
|
return true;
|
|
}
|
|
|
|
bool ScriptInterface::runScript(const std::string &file, const std::string &func, bool ignoremissing /* = false */)
|
|
{
|
|
std::string realFile = file;
|
|
if (file.find('/')==std::string::npos)
|
|
realFile = "scripts/" + file + ".lua";
|
|
Script *script = openScript(realFile, ignoremissing);
|
|
if (!script)
|
|
return false;
|
|
|
|
if (!func.empty() && !script->call(func.c_str()))
|
|
{
|
|
debugLog(script->getLastError());
|
|
debugLog("(error calling func: " + func + " in script: " + file + ")");
|
|
closeScript(script);
|
|
return false;
|
|
}
|
|
|
|
closeScript(script);
|
|
return true;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
void Script::lookupFunc(const char *name)
|
|
{
|
|
lua_getglobal(L, "_scriptfuncs"); // [_scriptfuncs]
|
|
lua_getfield(L, -1, file.c_str()); // [_scriptfuncs, tab]
|
|
lua_remove(L, -2); // [tab]
|
|
lua_getfield(L, -1, name); // [tab, f]
|
|
lua_remove(L, -2); // [f]
|
|
}
|
|
|
|
bool Script::doCall(int nparams, int nrets)
|
|
{
|
|
// Push the current value of the "v" global onto the Lua stack,
|
|
// so we can restore the current script's instance variable table
|
|
// before returning.
|
|
lua_getglobal(L, "v"); // [f, ..., v]
|
|
|
|
lua_insert(L, -(nparams+2)); // [v, f, ...]
|
|
fixupLocalVars(L);
|
|
|
|
int vpos = lua_gettop(L) - (nparams+1);
|
|
|
|
bool result;
|
|
if (lua_pcall(L, nparams, nrets, 0) == 0) // [v, ...]
|
|
{
|
|
result = true;
|
|
}
|
|
else
|
|
{
|
|
lastError = lua_tostring(L, -1);
|
|
lastError += " [";
|
|
lastError += luaFormatStackInfo(L);
|
|
lastError += "]";
|
|
lua_pop(L, 1);
|
|
result = false;
|
|
}
|
|
|
|
if (nrets != 0)
|
|
{
|
|
lua_pushvalue(L, vpos); // [v, ..., v]
|
|
lua_remove(L, vpos); // [..., v]
|
|
}
|
|
|
|
lua_setglobal(L, "v"); // [...]
|
|
|
|
return result;
|
|
}
|
|
|
|
bool Script::call(const char *name)
|
|
{
|
|
lookupFunc(name);
|
|
return doCall(0);
|
|
}
|
|
|
|
bool Script::call(const char *name, float param1)
|
|
{
|
|
lookupFunc(name);
|
|
lua_pushnumber(L, param1);
|
|
return doCall(1);
|
|
}
|
|
|
|
bool Script::call(const char *name, void *param1)
|
|
{
|
|
lookupFunc(name);
|
|
luaPushPointer(L, param1);
|
|
return doCall(1);
|
|
}
|
|
|
|
bool Script::call(const char *name, void *param1, float param2)
|
|
{
|
|
lookupFunc(name);
|
|
luaPushPointer(L, param1);
|
|
lua_pushnumber(L, param2);
|
|
return doCall(2);
|
|
}
|
|
|
|
bool Script::call(const char *name, void *param1, void *param2)
|
|
{
|
|
lookupFunc(name);
|
|
luaPushPointer(L, param1);
|
|
luaPushPointer(L, param2);
|
|
return doCall(2);
|
|
}
|
|
|
|
bool Script::call(const char *name, void *param1, float param2, float param3)
|
|
{
|
|
lookupFunc(name);
|
|
luaPushPointer(L, param1);
|
|
lua_pushnumber(L, param2);
|
|
lua_pushnumber(L, param3);
|
|
return doCall(3);
|
|
}
|
|
|
|
bool Script::call(const char *name, void *param1, float param2, float param3, bool *ret1)
|
|
{
|
|
lookupFunc(name);
|
|
luaPushPointer(L, param1);
|
|
lua_pushnumber(L, param2);
|
|
lua_pushnumber(L, param3);
|
|
if (!doCall(3, 1))
|
|
return false;
|
|
*ret1 = lua_toboolean(L, -1);
|
|
lua_pop(L, 1);
|
|
return true;
|
|
}
|
|
|
|
bool Script::call(const char *name, void *param1, int param2, int param3, int param4, bool *ret1)
|
|
{
|
|
lookupFunc(name);
|
|
luaPushPointer(L, param1);
|
|
lua_pushinteger(L, param2);
|
|
lua_pushinteger(L, param3);
|
|
lua_pushinteger(L, param4);
|
|
if (!doCall(4, 1))
|
|
return false;
|
|
*ret1 = lua_toboolean(L, -1);
|
|
lua_pop(L, 1);
|
|
return true;
|
|
}
|
|
|
|
bool Script::call(const char *name, void *param1, const char *param2, float param3)
|
|
{
|
|
lookupFunc(name);
|
|
luaPushPointer(L, param1);
|
|
lua_pushstring(L, param2);
|
|
lua_pushnumber(L, param3);
|
|
return doCall(3);
|
|
}
|
|
|
|
bool Script::call(const char *name, void *param1, const char *param2, void *param3)
|
|
{
|
|
lookupFunc(name);
|
|
luaPushPointer(L, param1);
|
|
lua_pushstring(L, param2);
|
|
luaPushPointer(L, param3);
|
|
return doCall(3);
|
|
}
|
|
|
|
bool Script::call(const char *name, void *param1, void *param2, void *param3)
|
|
{
|
|
lookupFunc(name);
|
|
luaPushPointer(L, param1);
|
|
luaPushPointer(L, param2);
|
|
luaPushPointer(L, param3);
|
|
return doCall(3);
|
|
}
|
|
|
|
bool Script::call(const char *name, void *param1, float param2, float param3, float param4)
|
|
{
|
|
lookupFunc(name);
|
|
luaPushPointer(L, param1);
|
|
lua_pushnumber(L, param2);
|
|
lua_pushnumber(L, param3);
|
|
lua_pushnumber(L, param4);
|
|
return doCall(4);
|
|
}
|
|
|
|
bool Script::call(const char *name, void *param1, void *param2, void *param3, void *param4)
|
|
{
|
|
lookupFunc(name);
|
|
luaPushPointer(L, param1);
|
|
luaPushPointer(L, param2);
|
|
luaPushPointer(L, param3);
|
|
luaPushPointer(L, param4);
|
|
return doCall(4);
|
|
}
|
|
|
|
bool Script::call(const char *name, void *param1, void *param2, void *param3, float param4, float param5, float param6, float param7, void *param8, bool *ret1)
|
|
{
|
|
lookupFunc(name);
|
|
luaPushPointer(L, param1);
|
|
luaPushPointer(L, param2);
|
|
luaPushPointer(L, param3);
|
|
lua_pushnumber(L, param4);
|
|
lua_pushnumber(L, param5);
|
|
lua_pushnumber(L, param6);
|
|
lua_pushnumber(L, param7);
|
|
luaPushPointer(L, param8);
|
|
if (!doCall(8, 1))
|
|
return false;
|
|
*ret1 = lua_toboolean(L, -1);
|
|
lua_pop(L, 1);
|
|
return true;
|
|
}
|
|
|
|
bool Script::call(const char *name, const char *param, bool *ret)
|
|
{
|
|
lookupFunc(name);
|
|
lua_pushstring(L, param);
|
|
if (!doCall(1, 1))
|
|
return false;
|
|
*ret = lua_toboolean(L, -1);
|
|
lua_pop(L, 1);
|
|
return true;
|
|
}
|
|
|
|
bool Script::call(const char *name, const char *param, std::string *ret)
|
|
{
|
|
lookupFunc(name);
|
|
lua_pushstring(L, param);
|
|
if (!doCall(1, 1))
|
|
return false;
|
|
*ret = getString(L, -1);
|
|
lua_pop(L, 1);
|
|
return true;
|
|
}
|
|
|
|
bool Script::call(const char *name, const char *param1, const char *param2, const char *param3, std::string *ret)
|
|
{
|
|
lookupFunc(name);
|
|
lua_pushstring(L, param1);
|
|
lua_pushstring(L, param2);
|
|
lua_pushstring(L, param3);
|
|
if (!doCall(3, 1))
|
|
return false;
|
|
*ret = getString(L, -1);
|
|
lua_pop(L, 1);
|
|
return true;
|
|
}
|
|
|
|
int Script::callVariadic(const char *name, lua_State *fromL, int nparams, void *param)
|
|
{
|
|
int oldtop = lua_gettop(L);
|
|
|
|
lookupFunc(name);
|
|
luaPushPointer(L, param);
|
|
|
|
// If both stacks are the same, we already pushed 2 more entries to the stack.
|
|
int pos = (L == fromL) ? -(nparams+2) : -nparams;
|
|
for (int i = 0; i < nparams; ++i)
|
|
lua_pushvalue(fromL, pos);
|
|
|
|
// Move them to the other stack. Ignored if L == fromL.
|
|
lua_xmove(fromL, L, nparams);
|
|
|
|
// Do the call
|
|
if (!doCall(nparams + 1, LUA_MULTRET))
|
|
return -1;
|
|
|
|
nparams = lua_gettop(L) - oldtop;
|
|
lua_xmove(L, fromL, nparams);
|
|
|
|
return nparams;
|
|
}
|
|
|
|
int Script::pushLocalVars(lua_State *Ltarget)
|
|
{
|
|
pushLocalVarTab(Ltarget, L);
|
|
return 1;
|
|
}
|