1 /*
2 Copyright (C) 2007, 2010 - Bit-Blot
3 
4 This file is part of Aquaria.
5 
6 Aquaria is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 
15 See the GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 */
21 
22 #include "ScriptInterface.h"
23 #include "../BBGE/ScriptObject.h"
24 extern "C"
25 {
26 	#include "lua.h"
27 	#include "lauxlib.h"
28 	#include "lualib.h"
29 }
30 #include "DSQ.h"
31 #include "Game.h"
32 #include "Avatar.h"
33 #include "ScriptedEntity.h"
34 #include "Shot.h"
35 #include "Entity.h"
36 #include "Web.h"
37 #include "GridRender.h"
38 #include "AfterEffect.h"
39 #include "PathFinding.h"
40 #include <algorithm>
41 #include "Gradient.h"
42 
43 #include "../BBGE/MathFunctions.h"
44 
45 // Define this to 1 to check types of pointers passed to functions,
46 // and warn if a type mismatch is detected. In this case,
47 // the pointer is treated as NULL, to avoid crashing or undefined behavior.
48 // Note: There are a few functions that depend on this (isObject and related).
49 //       They will still work as expected when this is disabled.
50 #define CHECK_POINTER_TYPES 1
51 
52 // If true, send all sort of script errors to errorLog instead of debugLog.
53 // On win32/OSX, this pops up message boxes which help to locate errors easily,
54 // but can be annoying for regular gameplay.
55 bool loudScriptErrors = false;
56 
57 // Set this to true to complain whenever a script tries to
58 // get or set a global variable.
59 bool complainOnGlobalVar = false;
60 
61 // Set this to true to complain whenever a script tries to get an undefined
62 // thread-local variable.
63 bool complainOnUndefLocal = false;
64 
65 // Set to true to make 'os' and 'io' Lua tables accessible
66 bool allowUnsafeFunctions = false;
67 
68 
69 // List of all interface functions called by C++ code, terminated by NULL.
70 static const char * const interfaceFunctions[] = {
71 	"action",
72 	"activate",
73 	"animationKey",
74 	"castSong",
75 	"canShotHit",
76 	"cookFailure",
77 	"damage",
78 	"deathNotify",
79 	"dieEaten",
80 	"dieNormal",
81 	"enterState",
82 	"entityDied",
83 	"exitState",
84 	"exitTimer",
85 	"getIngredientEffectString",
86 	"hitEntity",
87 	"hitSurface",
88 	"init",
89 	"lightFlare",
90 	"msg",
91 	"postInit",
92 	"preUpdate",
93 	"shiftWorlds",
94 	"shotHitEntity",
95 	"song",
96 	"songNote",
97 	"songNoteDone",
98 	"sporesDropped",
99 	"update",
100 	"useIngredient",
101 	"useTreasure",
102 	NULL
103 };
104 
105 //============================================================================================
106 // R U L E S  F O R  W R I T I N G  S C R I P T S
107 //============================================================================================
108 
109 //
110 // All scripts in Aquaria run as separate threads in the same Lua state.
111 // This means that scripts must follow certain rules to avoid interfering
112 // with each other:
113 //
114 // -- DON'T use global variables (or functions).  Use file-scope or
115 //    instance locals instead.
116 //
117 //    Since every script runs in the same Lua state and thus shares the
118 //    same global environment, global variables set in one script affect
119 //    every other script.  Something as innocuous-looking as "hits = 10"
120 //    would set a "hits" variable in _every_ script -- overwriting any
121 //    value that another script might have already set!
122 //
123 //    For constant values and functions (which are in effect constant
124 //    values), you can use Lua's "local" keyword to declare the value as
125 //    local to the script file which declares it.  Any functions defined
126 //    later in the file will then be able to access those local values as
127 //    function upvalues, thus avoiding touching the global environment.
128 //    (However, remember to define the constants or functions _before_
129 //    you use them!)
130 //
131 //    For variables, a file-scope local won't work, because a script's
132 //    functions are shared across all instances of that script -- for
133 //    example, every active jellyfish entity calls the same "update"
134 //    function.  If you used file-scope locals, then you'd have no way to
135 //    separate one instance's data from another.  Instead, the Aquaria
136 //    script engine provides a Lua table specific to each script instance,
137 //    into which instance-local variables can be stored.  This table is
138 //    loaded into the global variable "v" when any script function is
139 //    called from the game, so functions can store variables in this table
140 //    without worrying that another instance of the script will clobber
141 //    them.
142 //
143 //    The instance-local table is also available to code in the script
144 //    outside any functions, which is executed when the script is loaded.
145 //    In this case, the values in the table are used as defaults and
146 //    copied into the instance-local table of each new instance of the
147 //    script.
148 //
149 //    If you use any include files, be aware that file-scope locals in the
150 //    include files can only be used inside those files, since they would
151 //    be out of scope in the calling file.  To export constants or
152 //    functions to the calling file, you'll have to use instance locals
153 //    instead.  (As an exception, if you have constants which you know are
154 //    unique across all scripts, you can define them as globals.  Aquaria
155 //    itself defines a number of global constants for use in scripts --
156 //    see the "SCRIPT CONSTANTS" section toward the bottom of this file.)
157 //
158 // -- DO define instance functions in the global namespace.
159 //
160 //    As an exception to the rule above, interface functions such as
161 //    init() or update() _should_ be defined in the global namespace.
162 //    For example:
163 //
164 //        local function doUpdateStuff(dt)
165 //            -- Some update stuff.
166 //        end
167 //        function update(dt)
168 //            doUpdateStuff(dt)
169 //            -- Other update stuff.
170 //        end
171 //
172 //    The script engine will take care of ensuring that different scripts'
173 //    functions don't interfere with each other.
174 //
175 // -- DON'T call interface functions from within a script.
176 //
177 //    Interface functions, such as init() and update(), are treated
178 //    specially by the script engine, and attempting to call them from
179 //    other script functions will fail.  If you need to perform the same
180 //    processing from two or more different interface functions, define
181 //    a local function with the necessary code and call it from the
182 //    interface functions.
183 //
184 //    It _is_ possible, though not recommended, to have a local function
185 //    with the same name as an interface function.  For example, if you
186 //    write a script containing:
187 //
188 //        local function activate(me)
189 //            -- Do something.
190 //        end
191 //
192 //    then you can call activate() from other functions without problems.
193 //    The local function, activate() in this case, will naturally not be
194 //    visible to the script engine.  (This is discouraged because someone
195 //    reading the code may be confused at seeing what looks like an
196 //    interface function defined locally.)
197 //
198 // -- DON'T call any functions from the outermost (file) scope of an
199 //    instanced script file.
200 //
201 //    "Instanced" script files are those for which multiple instances may
202 //    be created, i.e. entity or node scripts.  For these, the script
203 //    itself is executed only once, when it is loaded; any statements
204 //    outside function definitions will be executed at this time, but not
205 //    when a new script instance is created.  For example, if you try to
206 //    call a function such as math.random() to set a different value for
207 //    each instance, you'll instead end up with the same value for every
208 //    instance.  In cases like this, the variable should be set in the
209 //    script's init() function, not at file scope.
210 //
211 //    Likewise, any functions which have side effects or otherwise modify
212 //    program state should not be called from file scope.  Call them from
213 //    init() instead.
214 //
215 // -- DON'T declare non-constant Lua tables at file scope in instanced
216 //    scripts.
217 //
218 //    One non-obvious result of the above restrictions is that tables
219 //    intended to be modified by the script cannot be declared at file
220 //    scope, even as instance variables.  The reason for this is that
221 //    table variables in Lua are actually pointers; the Lua statement
222 //    "v.table = {}" is functionally the same as "v.table = newtable()",
223 //    where the hypothetical newtable() function allocates and returns a
224 //    pointer to a table object, and thus falls under the restriction
225 //    that functions must not be called at file scope.  Table variables
226 //    in instanced scripts must therefore be initialized in the init()
227 //    function, even if you're only setting the variable to an empty
228 //    table.
229 //
230 // In summary:
231 //
232 // -- Never use global variables or functions, except interface functions.
233 // -- Constants and local functions should be defined with "local":
234 //        local MY_CONSTANT = 42
235 //        local function getMyConstant()  return MY_CONSTANT  end
236 // -- Variables should be stored in the "v" table:
237 //        function update(dt)  v.timer = v.timer + dt  end
238 // -- Variables (except table variables) can have default values set when
239 //    the script is loaded:
240 //        v.countdown = 5
241 //        function update(dt)  v.countdown = v.countdown - dt  end
242 // -- Non-constant tables must be initialized in init(), even if the
243 //    variable is always set to the same thing (such as an empty table).
244 // -- Never call interface functions from other functions.
245 // -- Always perform instance-specific setup in init(), not at file scope.
246 //
247 // ====================
248 // Compatibility notes:
249 // ====================
250 //
251 // Due to the use of an instance variable table (the "v" global), scripts
252 // written for this version of Aquaria will _not_ work with commercial
253 // releases (at least through version 1.1.3) of the game; likewise, the
254 // scripts from those commercial releases, and mods written to target
255 // those releases, will not work with this engine.
256 //
257 // The latter problem is unfortunately an unsolvable one, in any practical
258 // sense.  Since the original engine created a new Lua state for each
259 // script, scripts could create and modify global variables with impunity.
260 // The mere act of loading such a script could wreak havoc on the single
261 // Lua state used in the current engine, and attempting to work around
262 // this would require at least the implementation of a custom Lua parser
263 // to analyze and/or alter each script before it was passed to the Lua
264 // interpreter.
265 //
266 // However, the former problem -- of writing scripts for this version of
267 // the engine which also work on earlier versions -- can be solved with
268 // a few extra lines of code at the top of each script.  Since the new
269 // engine initializes the "v" global before each call to a script,
270 // including when the script is first loaded, scripts can check for the
271 // existence of this variable and assign an empty table to it if needed,
272 // such as with this line:
273 //
274 // if not v then v = {} end
275 //
276 // Additionally, the current engine provides built-in constants which
277 // were formerly loaded from external files.  To differentiate between
278 // this and other versions of the engine, the script interface exports a
279 // constant named AQUARIA_VERSION, generated directly from the program
280 // version (shown on the title screen) as:
281 //     major*10000 + minor*100 + revision
282 // For example, in version 1.1.3, AQUARIA_VERSION == 10103.  In earlier
283 // versions of the engine, the value of this constant will be nil, which
284 // can be used as a trigger to load the constant definition file from
285 // that version:
286 //
287 // if not AQUARIA_VERSION then dofile("scripts/entities/entityinclude.lua") end
288 //
289 // Note that scripts should _not_ rely on AQUARIA_VERSION for the v = {}
290 // assignment.  The code "if not AQUARIA_VERSION then v = {} end" would
291 // work correctly in a top-level script, but if executed from a script
292 // used as an include file, the table created in the include file would
293 // overwrite any existing table created by the file's caller.
294 //
295 
296 //============================================================================================
297 // S C R I P T  C O M M A N D S
298 //============================================================================================
299 
scriptError(const std::string & msg)300 static void scriptError(const std::string& msg)
301 {
302 	if(loudScriptErrors)
303 		errorLog(msg);
304 	else
305 		debugLog(msg);
306 }
307 
luaPushPointer(lua_State * L,void * ptr)308 static inline void luaPushPointer(lua_State *L, void *ptr)
309 {
310 	// All the scripts do this:
311 	//    x = getFirstEntity()
312 	//    while x =~ 0 do x = getNextEntity() end
313 	// The problem is this is now a pointer ("light user data"), so in
314 	//  Lua, it's never equal to 0 (or nil!), even if it's NULL.
315 	// So we push an actual zero when we get a NULL to keep the existing
316 	//  scripts happy.  --ryan.
317 	if (ptr != NULL)
318 		lua_pushlightuserdata(L, ptr);
319 	else
320 		lua_pushnumber(L, 0);
321 }
322 
luaFormatStackInfo(lua_State * L,int level=1)323 static std::string luaFormatStackInfo(lua_State *L, int level = 1)
324 {
325 	lua_Debug ar;
326 	std::ostringstream os;
327 	if (lua_getstack(L, level, &ar) && lua_getinfo(L, "Sln", &ar))
328 	{
329 		os << ar.short_src << ":" << ar.currentline
330 			<< " ([" << ar.what << "] "  << ar.namewhat << " " << (ar.name ? ar.name : "(?)") << ")";
331 	}
332 	else
333 	{
334 		os << "???:0";
335 	}
336 
337 	return os.str();
338 }
339 
scriptDebug(lua_State * L,const std::string & msg)340 static void scriptDebug(lua_State *L, const std::string& msg)
341 {
342 	debugLog(luaFormatStackInfo(L) + ": " + msg);
343 }
344 
scriptError(lua_State * L,const std::string & msg)345 static void scriptError(lua_State *L, const std::string& msg)
346 {
347 	lua_Debug dummy;
348 	std::ostringstream os;
349 	os << msg;
350 	for (int level = 0; lua_getstack(L, level, &dummy); ++level)
351 		os << '\n' << luaFormatStackInfo(L, level);
352 
353 	scriptError(os.str());
354 }
355 
356 
357 #if CHECK_POINTER_TYPES
358 // Not intended to be called.
359 // Because wild typecasting expects X::_objtype to reside at the same relative
360 // memory location, be sure this is the case before running into undefined behavior later.
361 // - The C++ standard allows offsetof() only on POD-types. Oh well, it probably works anyways.
362 // If it does not compile for some reason, comment it out, hope for the best, and go ahead.
363 #if !(defined(__GNUC__) && __GNUC__ <= 2)
compile_time_assertions()364 static void compile_time_assertions()
365 {
366 #define oo(cls) offsetof(cls, _objtype)
367 	compile_assert(oo(Path) == oo(RenderObject));
368 	compile_assert(oo(Path) == oo(Entity));
369 	compile_assert(oo(Path) == oo(Ingredient));
370 	compile_assert(oo(Path) == oo(CollideEntity));
371 	compile_assert(oo(Path) == oo(ScriptedEntity));
372 	compile_assert(oo(Path) == oo(Beam));
373 	compile_assert(oo(Path) == oo(Shot));
374 	compile_assert(oo(Path) == oo(Web));
375 	compile_assert(oo(Path) == oo(Bone));
376 	compile_assert(oo(Path) == oo(PauseQuad));
377 	compile_assert(oo(Path) == oo(Quad));
378 	compile_assert(oo(Path) == oo(Avatar));
379 	compile_assert(oo(Path) == oo(BaseText));
380 	compile_assert(oo(Path) == oo(PauseQuad));
381 	compile_assert(oo(Path) == oo(ParticleEffect));
382 #undef oo
383 }
384 #endif
385 
386 template <typename T>
ensureType(lua_State * L,T * & ptr,ScriptObjectType ty)387 static void ensureType(lua_State *L, T *& ptr, ScriptObjectType ty)
388 {
389 	if (ptr)
390 	{
391 		ScriptObject *so = (ScriptObject*)(ptr);
392 		if (!so->isType(ty))
393 		{
394 			std::ostringstream os;
395 			os << "WARNING: script passed wrong pointer to function (expected type: "
396 				<< ScriptObject::getTypeString(ty) << "; got: "
397 				<< so->getTypeString() << ')';
398 			scriptError(L, os.str());
399 
400 			ptr = NULL; // note that the pointer is passed by reference
401 		}
402 	}
403 }
404 #  define ENSURE_TYPE(ptr, ty) ensureType(L, (ptr), (ty))
405 #  define typecheckOnly(func) func
406 #else
407 #  define ENSURE_TYPE(ptr, ty)
408 #  define typecheckOnly(func)
409 #endif
410 
411 static inline
robj(lua_State * L,int slot=1)412 RenderObject *robj(lua_State *L, int slot = 1)
413 {
414 	RenderObject *r = (RenderObject*)lua_touserdata(L, slot);
415 	ENSURE_TYPE(r, SCO_RENDEROBJECT);
416 	if (!r)
417 		scriptDebug(L, "RenderObject invalid pointer.");
418 	return r;
419 }
420 
421 static inline
scriptedEntity(lua_State * L,int slot=1)422 ScriptedEntity *scriptedEntity(lua_State *L, int slot = 1)
423 {
424 	ScriptedEntity *se = (ScriptedEntity*)lua_touserdata(L, slot);
425 	ENSURE_TYPE(se, SCO_SCRIPTED_ENTITY);
426 	if (!se)
427 		scriptDebug(L, "ScriptedEntity invalid pointer.");
428 	return se;
429 }
430 
431 static inline
collideEntity(lua_State * L,int slot=1)432 CollideEntity *collideEntity(lua_State *L, int slot = 1)
433 {
434 	CollideEntity *ce = (CollideEntity*)lua_touserdata(L, slot);
435 	ENSURE_TYPE(ce, SCO_COLLIDE_ENTITY);
436 	if (!ce)
437 		scriptDebug(L, "CollideEntity invalid pointer.");
438 	return ce ;
439 }
440 
441 static inline
beam(lua_State * L,int slot=1)442 Beam *beam(lua_State *L, int slot = 1)
443 {
444 	Beam *b = (Beam*)lua_touserdata(L, slot);
445 	ENSURE_TYPE(b, SCO_BEAM);
446 	if (!b)
447 		scriptDebug(L, "Beam invalid pointer.");
448 	return b;
449 }
450 
451 static inline
getString(lua_State * L,int slot=1)452 std::string getString(lua_State *L, int slot = 1)
453 {
454 	std::string sr;
455 	if (lua_isstring(L, slot))
456 	{
457 		sr = lua_tostring(L, slot);
458 	}
459 	return sr;
460 }
461 
462 static inline
getCString(lua_State * L,int slot=1)463 const char *getCString(lua_State *L, int slot = 1)
464 {
465 	return lua_isstring(L, slot) ? lua_tostring(L, slot) : NULL;
466 }
467 
468 static inline
getShot(lua_State * L,int slot=1)469 Shot *getShot(lua_State *L, int slot = 1)
470 {
471 	Shot *shot = (Shot*)lua_touserdata(L, slot);
472 	ENSURE_TYPE(shot, SCO_SHOT);
473 	if (!shot)
474 		scriptDebug(L, "Shot invalid pointer.");
475 	return shot;
476 }
477 
478 static inline
getWeb(lua_State * L,int slot=1)479 Web *getWeb(lua_State *L, int slot = 1)
480 {
481 	Web *web = (Web*)lua_touserdata(L, slot);
482 	ENSURE_TYPE(web, SCO_WEB);
483 	if (!web)
484 		scriptDebug(L, "Web invalid pointer.");
485 	return web;
486 }
487 
488 static inline
getIng(lua_State * L,int slot=1)489 Ingredient *getIng(lua_State *L, int slot = 1)
490 {
491 	Ingredient *ing = (Ingredient*)lua_touserdata(L, slot);
492 	ENSURE_TYPE(ing, SCO_INGREDIENT);
493 	if (!ing)
494 		scriptDebug(L, "Ingredient invalid pointer.");
495 	return ing;
496 }
497 
498 static inline
getBool(lua_State * L,int slot=1)499 bool getBool(lua_State *L, int slot = 1)
500 {
501 	if (lua_isnumber(L, slot))
502 	{
503 		return bool(lua_tonumber(L, slot));
504 	}
505 	else if (lua_islightuserdata(L, slot))
506 	{
507 		return (lua_touserdata(L, slot) != NULL);
508 	}
509 	else if (lua_isboolean(L, slot))
510 	{
511 		return lua_toboolean(L, slot);
512 	}
513 	return false;
514 }
515 
516 static inline
entity(lua_State * L,int slot=1)517 Entity *entity(lua_State *L, int slot = 1)
518 {
519 	Entity *ent = (Entity*)lua_touserdata(L, slot);
520 	ENSURE_TYPE(ent, SCO_ENTITY);
521 	if (!ent)
522 	{
523 		scriptDebug(L, "Entity Invalid Pointer");
524 	}
525 	return ent;
526 }
527 
528 static inline
getVector(lua_State * L,int slot=1)529 Vector getVector(lua_State *L, int slot = 1)
530 {
531 	Vector v(lua_tonumber(L, slot), lua_tonumber(L, slot+1));
532 	return v;
533 }
534 
535 
536 static inline
bone(lua_State * L,int slot=1)537 Bone *bone(lua_State *L, int slot = 1)
538 {
539 	Bone *b = (Bone*)lua_touserdata(L, slot);
540 	ENSURE_TYPE(b, SCO_BONE);
541 	if (!b)
542 	{
543 		scriptDebug(L, "Bone Invalid Pointer");
544 	}
545 	return b;
546 }
547 
548 static inline
pathFromName(lua_State * L,int slot=1)549 Path *pathFromName(lua_State *L, int slot = 1)
550 {
551 	std::string s = getString(L, slot);
552 	stringToLower(s);
553 	Path *p = dsq->game->getPathByName(s);
554 	if (!p)
555 	{
556 		debugLog("Could not find path [" + s + "]");
557 	}
558 	return p;
559 }
560 
561 static inline
path(lua_State * L,int slot=1)562 Path *path(lua_State *L, int slot = 1)
563 {
564 	Path *p = (Path*)lua_touserdata(L, slot);
565 	ENSURE_TYPE(p, SCO_PATH);
566 	return p;
567 }
568 
569 static inline
getQuad(lua_State * L,int slot=1)570 Quad *getQuad(lua_State *L, int slot = 1)
571 {
572 	Quad *q = (Quad*)lua_touserdata(L, slot);
573 	ENSURE_TYPE(q, SCO_QUAD);
574 	if (!q)
575 		scriptDebug(L, "Invalid Quad");
576 	return q;
577 }
578 
579 static inline
getText(lua_State * L,int slot=1)580 BaseText *getText(lua_State *L, int slot = 1)
581 {
582 	BaseText *q = (BaseText*)lua_touserdata(L, slot);
583 	ENSURE_TYPE(q, SCO_TEXT);
584 	if (!q)
585 		scriptDebug(L, "Invalid Text");
586 	return q;
587 }
588 
589 static inline
getShader(lua_State * L,int slot=1)590 Shader *getShader(lua_State *L, int slot = 1)
591 {
592 	Shader *q = (Shader*)lua_touserdata(L, slot);
593 	ENSURE_TYPE(q, SCO_SHADER);
594 	if (!q)
595 		scriptDebug(L, "Invalid Shader");
596 	return q;
597 }
598 
getSkeletalSprite(Entity * e)599 static SkeletalSprite *getSkeletalSprite(Entity *e)
600 {
601 	return e ? &e->skeletalSprite : NULL;
602 }
603 
604 static inline
getParticle(lua_State * L,int slot=1)605 ParticleEffect *getParticle(lua_State *L, int slot = 1)
606 {
607 	ParticleEffect *q = (ParticleEffect*)lua_touserdata(L, slot);
608 	ENSURE_TYPE(q, SCO_PARTICLE_EFFECT);
609 	if (!q)
610 		scriptDebug(L, "Invalid Particle Effect");
611 	return q;
612 }
613 
looksLikeGlobal(const char * s)614 static bool looksLikeGlobal(const char *s)
615 {
616 	for( ; *s; ++s)
617 		if( !((*s >= 'A' && *s <= 'Z') || *s == '_' || (*s >= '0' && *s <= '9')) ) // accept any uppercase, number, and _ char
618 			return false;
619 	return true;
620 }
621 
interpolateVec1(lua_State * L,InterpolatedVector & vec,int argOffs)622 inline float interpolateVec1(lua_State *L, InterpolatedVector& vec, int argOffs)
623 {
624 	return vec.interpolateTo(
625 		lua_tonumber (L, argOffs  ),  // value
626 		lua_tonumber (L, argOffs+1),  // time
627 		lua_tointeger(L, argOffs+2),  // loopType
628 		getBool      (L, argOffs+3),  // pingPong
629 		getBool      (L, argOffs+4)); // ease
630 }
631 
interpolateVec1z(lua_State * L,InterpolatedVector & vec,int argOffs)632 inline float interpolateVec1z(lua_State *L, InterpolatedVector& vec, int argOffs)
633 {
634 	return vec.interpolateTo(
635 		Vector(0.0f, 0.0f, lua_tonumber (L, argOffs  )),  // value, last component
636 		lua_tonumber (L, argOffs+1),  // time
637 		lua_tointeger(L, argOffs+2),  // loopType
638 		getBool      (L, argOffs+3),  // pingPong
639 		getBool      (L, argOffs+4)); // ease
640 }
641 
interpolateVec2(lua_State * L,InterpolatedVector & vec,int argOffs)642 inline float interpolateVec2(lua_State *L, InterpolatedVector& vec, int argOffs)
643 {
644 	return vec.interpolateTo(
645 		Vector(lua_tonumber (L, argOffs  ),  // x value
646 		       lua_tonumber (L, argOffs+1)), // y value
647 		lua_tonumber (L, argOffs+2),         // time
648 		lua_tointeger(L, argOffs+3),         // loopType
649 		getBool(L, argOffs+4),               // pingPong
650 		getBool(L, argOffs+5));              // ease
651 }
652 
interpolateVec3(lua_State * L,InterpolatedVector & vec,int argOffs)653 inline float interpolateVec3(lua_State *L, InterpolatedVector& vec, int argOffs)
654 {
655 	return vec.interpolateTo(
656 		Vector(lua_tonumber (L, argOffs  ),  // x value
657 		       lua_tonumber (L, argOffs+1),  // y value
658 		       lua_tonumber (L, argOffs+2)), // z value
659 		lua_tonumber (L, argOffs+3),         // time
660 		lua_tointeger(L, argOffs+4),         // loopType
661 		getBool(L, argOffs+5),               // pingPong
662 		getBool(L, argOffs+6));              // ease
663 }
664 
safePath(lua_State * L,const std::string & path)665 static void safePath(lua_State *L, const std::string& path)
666 {
667 	// invalid characters for file/path names.
668 	// Filter out \ as well, it'd work on on win32 only, so it's not supposed to be used.
669 	size_t invchr = path.find_first_of("\\\":*?<>|");
670 	if(invchr != std::string::npos)
671 	{
672 		lua_pushfstring(L, "Invalid char in path/file name: %c", path[invchr]);
673 		lua_error(L);
674 	}
675 	// Block attempts to access files outside of the "safe area"
676 	if(path.length())
677 	{
678 		if(path[0] == '/')
679 		{
680 			if(!(dsq->mod.isActive() && path.substr(0, dsq->mod.getBaseModPath().length()) == dsq->mod.getBaseModPath()))
681 			{
682 				lua_pushliteral(L, "Absolute paths are not allowed");
683 				lua_error(L);
684 			}
685 		}
686 		if(path.find("../") != std::string::npos)
687 		{
688 			lua_pushliteral(L, "Accessing parent is not allowed");
689 			lua_error(L);
690 		}
691 	}
692 }
693 
694 
695 //----------------------------------//
696 
697 #define luaFunc(func)		static int l_##func(lua_State *L)
698 #define luaReturnBool(bool)	do {lua_pushboolean(L, (bool)); return 1;} while(0)
699 #define luaReturnInt(num)	do {lua_pushinteger(L, (num)); return 1;} while(0)
700 #define luaReturnNum(num)	do {lua_pushnumber(L, (num)); return 1;} while(0)
701 #define luaReturnPtr(ptr)	do {luaPushPointer(L, (ptr)); return 1;} while(0)
702 #define luaReturnStr(str)	do {lua_pushstring(L, (str)); return 1;} while(0)
703 #define luaReturnVec2(x,y)	do {lua_pushnumber(L, (x)); lua_pushnumber(L, (y)); return 2;} while(0)
704 #define luaReturnVec3(x,y,z)	do {lua_pushnumber(L, (x)); lua_pushnumber(L, (y)); lua_pushnumber(L, (z)); return 3;} while(0)
705 #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)
706 #define luaReturnNil()		return 0;
707 
708 // Set the global "v" to the instance's local variable table.  Must be
709 // called when starting a script.
fixupLocalVars(lua_State * L)710 static void fixupLocalVars(lua_State *L)
711 {
712 	lua_getglobal(L, "_threadvars");
713 	lua_pushlightuserdata(L, L);
714 	lua_gettable(L, -2);
715 	lua_remove(L, -2);
716 	lua_setglobal(L, "v");
717 }
718 
luaFunc(indexWarnGlobal)719 luaFunc(indexWarnGlobal)
720 {
721 	lua_pushvalue(L, -1);
722 	lua_rawget(L, -3);
723 	lua_remove(L, -3);
724 
725 	if (lua_isnil(L, -1))
726 	{
727 		// Don't warn on "v" or known interface functions.
728 		lua_pushvalue(L, -2);
729 		const char *varname = lua_tostring(L, -1);
730 		bool doWarn = (strcmp(varname, "v") != 0);
731 		for (unsigned int i = 0; doWarn && interfaceFunctions[i] != NULL; i++)
732 		{
733 			doWarn = (strcmp(varname, interfaceFunctions[i]) != 0);
734 		}
735 
736 		if (doWarn)
737 		{
738 			std::string s = "WARNING: script tried to get/call undefined global variable ";
739 			s += varname;
740 			scriptError(L, s);
741 		}
742 
743 		lua_pop(L, 1);
744 	}
745 
746 	lua_remove(L, -2);
747 
748 	return 1;
749 }
750 
luaFunc(newindexWarnGlobal)751 luaFunc(newindexWarnGlobal)
752 {
753 	// Don't warn on "v" or known interface functions.
754 	lua_pushvalue(L, -2);
755 	const char *varname = lua_tostring(L, -1);
756 	bool doWarn = (strcmp(varname, "v") != 0) && !looksLikeGlobal(varname);
757 	for (unsigned int i = 0; doWarn && interfaceFunctions[i] != NULL; i++)
758 	{
759 		doWarn = (strcmp(varname, interfaceFunctions[i]) != 0);
760 	}
761 
762 	if (doWarn)
763 	{
764 		std::ostringstream os;
765 		os << "WARNING: script set global "
766 		   << lua_typename(L, lua_type(L, -2))
767 		   << " " << varname;
768 		scriptError(L, os.str());
769 	}
770 
771 	lua_pop(L, 1);
772 
773 	// Do the set anyway.
774 	lua_rawset(L, -3);
775 	lua_pop(L, 1);
776 	return 0;
777 }
778 
luaFunc(indexWarnInstance)779 luaFunc(indexWarnInstance)
780 {
781 	lua_pushvalue(L, -1);
782 	lua_rawget(L, -3);
783 	lua_remove(L, -3);
784 	if (lua_isnil(L, -1))
785 	{
786 		std::ostringstream os;
787 		os << "WARNING: script tried to get/call undefined instance variable "
788 		   << getString(L, -2);
789 		scriptError(L, os.str());
790 	}
791 	lua_remove(L, -2);
792 
793 	return 1;
794 }
795 
luaFunc(panicHandler)796 luaFunc(panicHandler)
797 {
798 	std::string err = luaFormatStackInfo(L) + ": Lua PANIC: " + getString(L, -1);
799 	exit_error(err);
800 	return 0;
801 }
802 
findFile_helper(const char * rawname,std::string & fname)803 static bool findFile_helper(const char *rawname, std::string &fname)
804 {
805 	if (!rawname)
806 		return false;
807 	if (dsq->mod.isActive())
808 	{
809 		fname = dsq->mod.getPath();
810 		if(fname[fname.length() - 1] != '/')
811 			fname += '/';
812 		fname += rawname;
813 		fname = localisePath(fname, dsq->mod.getPath());
814 		fname = core->adjustFilenameCase(fname);
815 		if (exists(fname))
816 			return true;
817 	}
818 	fname = localisePath(rawname);
819 	fname = core->adjustFilenameCase(fname);
820 	return exists(fname);
821 }
822 
loadFile_helper(lua_State * L,const char * fn)823 static int loadFile_helper(lua_State *L, const char *fn)
824 {
825 #ifdef BBGE_BUILD_VFS
826 	unsigned long size = 0;
827 	const char *data = readFile(fn, &size);
828 	if (!data)
829 	{
830 		lua_pushfstring(L, "cannot open %s", fn);
831 		return LUA_ERRFILE;
832 	}
833 	else
834 	{
835 		int result = luaL_loadbuffer(L, data, size, fn);
836 		delete [] data;
837 		return result;
838 	}
839 #else
840 	return luaL_loadfile(L, fn);
841 #endif
842 }
843 
luaFunc(dofile_caseinsensitive)844 luaFunc(dofile_caseinsensitive)
845 {
846 	// This is Lua's dofile(), with some tweaks.  --ryan.
847 	std::string fname;
848 	findFile_helper(luaL_checkstring(L, 1), fname);
849 
850 	int n = lua_gettop(L);
851 	if (loadFile_helper(L, fname.c_str()) != 0)
852 		lua_error(L);
853 	lua_call(L, 0, LUA_MULTRET);
854 	return lua_gettop(L) - n;
855 }
856 
luaFunc(loadfile_caseinsensitive)857 luaFunc(loadfile_caseinsensitive)
858 {
859 	// This is Lua's loadfile(), with some tweaks.  --FG.
860 	std::string fname;
861 	findFile_helper(luaL_checkstring(L, 1), fname);
862 
863 	if (loadFile_helper(L, fname.c_str()) == 0)  /* OK? */
864 		return 1;
865 	else
866 	{
867 		lua_pushnil(L);
868 		lua_insert(L, -2);  /* put before error message */
869 		return 2;  /* return nil plus error message */
870 	}
871 }
872 
luaFunc(fileExists)873 luaFunc(fileExists)
874 {
875 	const std::string s = getString(L);
876 	safePath(L, s);
877 	std::string res;
878 	bool there = findFile_helper(s.c_str(), res);
879 	lua_pushboolean(L, there);
880 	lua_pushstring(L, res.c_str());
881 	return 2;
882 }
883 
luaFunc(getModName)884 luaFunc(getModName)
885 {
886 	luaReturnStr(dsq->mod.isActive() ? dsq->mod.getName().c_str() : "");
887 }
888 
luaFunc(getModPath)889 luaFunc(getModPath)
890 {
891 	std::string path;
892 	if (dsq->mod.isActive())
893 	{
894 		path = dsq->mod.getPath();
895 		if(path[path.length() - 1] != '/')
896 			path += '/';
897 	}
898 	luaReturnStr(path.c_str());
899 }
900 
901 
902 
903 // ----- RenderObject common functions -----
904 
905 #define forwardCall(func) l_##func(L)
906 
907 #define MakeTypeCheckFunc(fname, ty) luaFunc(fname) \
908 	{ ScriptObject *r = (ScriptObject*)lua_touserdata(L, 1); luaReturnBool(r ? r->isType(ty) : false); }
909 
910 MakeTypeCheckFunc(isNode, SCO_PATH);
911 MakeTypeCheckFunc(isObject, SCO_RENDEROBJECT);
MakeTypeCheckFunc(isEntity,SCO_ENTITY)912 MakeTypeCheckFunc(isEntity, SCO_ENTITY)
913 MakeTypeCheckFunc(isScriptedEntity, SCO_SCRIPTED_ENTITY)
914 MakeTypeCheckFunc(isBone, SCO_BONE)
915 MakeTypeCheckFunc(isShot, SCO_SHOT)
916 MakeTypeCheckFunc(isWeb, SCO_WEB)
917 MakeTypeCheckFunc(isIng, SCO_INGREDIENT)
918 MakeTypeCheckFunc(isBeam, SCO_BEAM)
919 MakeTypeCheckFunc(isText, SCO_TEXT)
920 MakeTypeCheckFunc(isShader, SCO_SHADER)
921 MakeTypeCheckFunc(isParticleEffect, SCO_PARTICLE_EFFECT)
922 
923 #undef MakeTypeCheckFunc
924 
925 // special, because it would return true on almost everything that is RenderObject based.
926 // Instead, return true only for stuff created with createQuad()
927 luaFunc(isQuad)
928 {
929 	RenderObject *r = robj(L);
930 	luaReturnBool(r ? r->isExactType(ScriptObjectType(SCO_RENDEROBJECT | SCO_QUAD)) : false);
931 }
932 
933 
luaFunc(obj_setPosition)934 luaFunc(obj_setPosition)
935 {
936 	RenderObject *r = robj(L);
937 	if (r)
938 	{
939 		r->position.stop();
940 		interpolateVec2(L, r->position, 2);
941 	}
942 	luaReturnNil();
943 }
944 
luaFunc(obj_scale)945 luaFunc(obj_scale)
946 {
947 	RenderObject *r = robj(L);
948 	if (r)
949 	{
950 		r->scale.stop();
951 		interpolateVec2(L, r->scale, 2);
952 	}
953 	luaReturnNil();
954 }
955 
luaFunc(obj_getScale)956 luaFunc(obj_getScale)
957 {
958 	RenderObject *r = robj(L);
959 	Vector s;
960 	if (r)
961 		s = r->scale;
962 	luaReturnVec2(s.x, s.y);
963 }
964 
luaFunc(obj_alpha)965 luaFunc(obj_alpha)
966 {
967 	RenderObject *r = robj(L);
968 	if (r)
969 	{
970 		r->alpha.stop();
971 		interpolateVec1(L, r->alpha, 2);
972 	}
973 	luaReturnNil();
974 }
975 
luaFunc(obj_alphaMod)976 luaFunc(obj_alphaMod)
977 {
978 	RenderObject *r = robj(L);
979 	if (r)
980 		r->alphaMod = lua_tonumber(L, 2);
981 	luaReturnNil()
982 }
983 
luaFunc(obj_getAlphaMod)984 luaFunc(obj_getAlphaMod)
985 {
986 	RenderObject *r = robj(L);
987 	luaReturnNum(r ? r->alphaMod : 0.0f);
988 }
989 
luaFunc(obj_getAlpha)990 luaFunc(obj_getAlpha)
991 {
992 	RenderObject *r = robj(L);
993 	luaReturnNum(r ? r->alpha.x : 0.0f);
994 }
995 
luaFunc(obj_color)996 luaFunc(obj_color)
997 {
998 	RenderObject *r = robj(L);
999 	if (r)
1000 	{
1001 		r->color.stop();
1002 		interpolateVec3(L, r->color, 2);
1003 	}
1004 	luaReturnNil();
1005 }
1006 
luaFunc(obj_getColor)1007 luaFunc(obj_getColor)
1008 {
1009 	RenderObject *r = robj(L);
1010 	Vector c;
1011 	if(r)
1012 		c = r->color;
1013 	luaReturnVec3(c.x, c.y, c.z);
1014 }
1015 
1016 
luaFunc(obj_rotate)1017 luaFunc(obj_rotate)
1018 {
1019 	RenderObject *r = robj(L);
1020 	if (r)
1021 	{
1022 		r->rotation.stop();
1023 		interpolateVec1z(L, r->rotation, 2);
1024 	}
1025 	luaReturnNil();
1026 }
1027 
luaFunc(obj_rotateOffset)1028 luaFunc(obj_rotateOffset)
1029 {
1030 	RenderObject *r = robj(L);
1031 	if (r)
1032 	{
1033 		r->rotationOffset.stop();
1034 		interpolateVec1z(L, r->rotationOffset, 2);
1035 	}
1036 	luaReturnNil();
1037 }
1038 
luaFunc(obj_getRotation)1039 luaFunc(obj_getRotation)
1040 {
1041 	RenderObject *r = robj(L);
1042 	luaReturnNum(r ? r->rotation.z : 0.0f);
1043 }
1044 
luaFunc(obj_getRotationOffset)1045 luaFunc(obj_getRotationOffset)
1046 {
1047 	RenderObject *r = robj(L);
1048 	luaReturnNum(r ? r->rotationOffset.z : 0.0f);
1049 }
1050 
luaFunc(obj_offset)1051 luaFunc(obj_offset)
1052 {
1053 	RenderObject *r = robj(L);
1054 	if (r)
1055 	{
1056 		r->offset.stop();
1057 		interpolateVec2(L, r->offset, 2);
1058 	}
1059 	luaReturnNil();
1060 }
1061 
luaFunc(obj_internalOffset)1062 luaFunc(obj_internalOffset)
1063 {
1064 	RenderObject *r = robj(L);
1065 	if (r)
1066 	{
1067 		r->internalOffset.stop();
1068 		interpolateVec2(L, r->internalOffset, 2);
1069 	}
1070 	luaReturnNil();
1071 }
1072 
luaFunc(obj_getInternalOffset)1073 luaFunc(obj_getInternalOffset)
1074 {
1075 	RenderObject *r = robj(L);
1076 	Vector io;
1077 	if (r)
1078 		io = r->internalOffset;
1079 	luaReturnVec2(io.x, io.y);
1080 }
1081 
luaFunc(obj_getPosition)1082 luaFunc(obj_getPosition)
1083 {
1084 	float x=0,y=0;
1085 	RenderObject *r = robj(L);
1086 	if (r)
1087 	{
1088 		x = r->position.x;
1089 		y = r->position.y;
1090 	}
1091 	luaReturnVec2(x, y);
1092 }
1093 
1094 
luaFunc(obj_getOffset)1095 luaFunc(obj_getOffset)
1096 {
1097 	float x=0,y=0;
1098 	RenderObject *r = robj(L);
1099 	if (r)
1100 	{
1101 		x = r->offset.x;
1102 		y = r->offset.y;
1103 	}
1104 	luaReturnVec2(x, y);
1105 }
luaFunc(obj_x)1106 luaFunc(obj_x)
1107 {
1108 	RenderObject *r = robj(L);
1109 	float x = 0;
1110 	if (r)
1111 		x = r->position.x;
1112 	luaReturnNum(x);
1113 }
1114 
luaFunc(obj_y)1115 luaFunc(obj_y)
1116 {
1117 	RenderObject *r = robj(L);
1118 	float y = 0;
1119 	if (r)
1120 		y = r->position.y;
1121 	luaReturnNum(y);
1122 }
1123 
luaFunc(obj_setBlendType)1124 luaFunc(obj_setBlendType)
1125 {
1126 	RenderObject *r = robj(L);
1127 	if (r)
1128 		r->setBlendType(lua_tointeger(L, 2));
1129 	luaReturnNil();
1130 }
1131 
luaFunc(obj_setTexture)1132 luaFunc(obj_setTexture)
1133 {
1134 	RenderObject *r = robj(L);
1135 	luaReturnBool(r ? r->setTexture(getString(L, 2)) : false);
1136 }
1137 
luaFunc(obj_getTexture)1138 luaFunc(obj_getTexture)
1139 {
1140     RenderObject *r = robj(L);
1141     if (r && r->texture)
1142         luaReturnStr(r->texture->name.c_str());
1143     luaReturnStr("");
1144 }
1145 
luaFunc(obj_delete)1146 luaFunc(obj_delete)
1147 {
1148 	RenderObject *r = robj(L);
1149 	if (r)
1150 	{
1151 		float time = lua_tonumber(L, 2);
1152 		if (time == 0)
1153 		{
1154 			r->safeKill();
1155 		}
1156 		else
1157 		{
1158 			r->fadeAlphaWithLife = true;
1159 			r->setLife(1);
1160 			r->setDecayRate(1.0f/time);
1161 		}
1162 	}
1163 	luaReturnNil();
1164 }
1165 
luaFunc(obj_setLife)1166 luaFunc(obj_setLife)
1167 {
1168 	RenderObject *r = robj(L);
1169 	if (r)
1170 		r->setLife(lua_tonumber(L, 2));
1171 	luaReturnNil();
1172 }
1173 
luaFunc(obj_getLife)1174 luaFunc(obj_getLife)
1175 {
1176 	RenderObject *r = robj(L);
1177 	luaReturnNum(r ? r->life : 0.0f);
1178 }
1179 
luaFunc(obj_setDecayRate)1180 luaFunc(obj_setDecayRate)
1181 {
1182 	RenderObject *r = robj(L);
1183 	if (r)
1184 		r->setDecayRate(lua_tonumber(L, 2));
1185 	luaReturnNil();
1186 }
1187 
luaFunc(obj_addDeathNotify)1188 luaFunc(obj_addDeathNotify)
1189 {
1190 	RenderObject *r = robj(L);
1191 	RenderObject *which = robj(L, 2);
1192 	if (r && which)
1193 		r->addDeathNotify(which);
1194 	luaReturnNil();
1195 }
1196 
luaFunc(obj_addChild)1197 luaFunc(obj_addChild)
1198 {
1199 	RenderObject *r = robj(L);
1200 	RenderObject *which = robj(L, 2);
1201 	bool takeOwnership = getBool(L, 3);
1202 	bool front = getBool(L, 4);
1203 	if (r && which)
1204 	{
1205 		if (takeOwnership)
1206 		{
1207 			// HACK: this is ugly, but necessary to prevent double-deletion
1208 			// anyways, dangerous; addChild() may fail, causing a small memory leak (and an error message)
1209 			dsq->getState(dsq->game->name)->removeRenderObjectFromList(which);
1210 			which->setStateDataObject(NULL);
1211 			core->removeRenderObject(which, Core::DO_NOT_DESTROY_RENDER_OBJECT);
1212 			r->addChild(which, PM_POINTER, RBP_NONE, front ? CHILD_FRONT : CHILD_BACK);
1213 		}
1214 		else
1215 			r->addChild(which, PM_STATIC);
1216 	}
1217 	luaReturnNil();
1218 }
1219 
luaFunc(obj_setRenderBeforeParent)1220 luaFunc(obj_setRenderBeforeParent)
1221 {
1222 	RenderObject *r = robj(L);
1223 	if (r)
1224 		r->renderBeforeParent = getBool(L, 2);
1225 	luaReturnNil();
1226 }
1227 
luaFunc(obj_isRenderBeforeParent)1228 luaFunc(obj_isRenderBeforeParent)
1229 {
1230 	RenderObject *r = robj(L);
1231 	luaReturnBool(r ? r->renderBeforeParent : false);
1232 }
1233 
1234 // Not so pretty: Because RenderObject has a `velocity' vector,
1235 // and Entity has `vel' ADDITIONALLY, we need to use
1236 // extra functions to manage RenderObject's velocities.
1237 // Different names were chosen to allow avoid name clashing. -- FG
1238 
luaFunc(obj_setInternalVel)1239 luaFunc(obj_setInternalVel)
1240 {
1241 	RenderObject *r = robj(L);
1242 	if (r)
1243 	{
1244 		r->velocity.stop();
1245 		interpolateVec2(L, r->velocity, 2);
1246 	}
1247 	luaReturnNil();
1248 }
1249 
luaFunc(obj_setInternalVelLen)1250 luaFunc(obj_setInternalVelLen)
1251 {
1252 	RenderObject *r = robj(L);
1253 	if (r)
1254 	{
1255 		r->velocity.stop();
1256 		r->velocity.setLength2D(lua_tonumber(L, 2));
1257 	}
1258 	luaReturnNil();
1259 }
1260 
luaFunc(obj_getInternalVelLen)1261 luaFunc(obj_getInternalVelLen)
1262 {
1263 	RenderObject *r = robj(L);
1264 	luaReturnNum(r ? r->velocity.getLength2D() : 0.0f);
1265 }
1266 
1267 
luaFunc(obj_getInternalVel)1268 luaFunc(obj_getInternalVel)
1269 {
1270 	Vector v;
1271 	RenderObject *r = robj(L);
1272 	if (r)
1273 		v = r->velocity;
1274 	luaReturnVec2(v.x, v.y);
1275 }
1276 
luaFunc(obj_ivelx)1277 luaFunc(obj_ivelx)
1278 {
1279 	RenderObject *r = robj(L);
1280 	luaReturnNum(r ? r->velocity.x : 0.0f);
1281 }
1282 
luaFunc(obj_ively)1283 luaFunc(obj_ively)
1284 {
1285 	RenderObject *r = robj(L);
1286 	luaReturnNum(r ? r->velocity.y : 0.0f);
1287 }
1288 
luaFunc(obj_addInternalVel)1289 luaFunc(obj_addInternalVel)
1290 {
1291 	RenderObject *r = robj(L);
1292 	if (r)
1293 		r->velocity += Vector(lua_tonumber(L, 2), lua_tonumber(L, 3));
1294 	luaReturnNil();
1295 }
1296 
luaFunc(obj_isInternalVelIn)1297 luaFunc(obj_isInternalVelIn)
1298 {
1299 	RenderObject *r = robj(L);
1300 	luaReturnBool(r ? r->velocity.isLength2DIn(lua_tonumber(L, 2)) : false);
1301 }
1302 
luaFunc(obj_setGravity)1303 luaFunc(obj_setGravity)
1304 {
1305 	RenderObject *r = robj(L);
1306 	if (r)
1307 	{
1308 		r->gravity.stop();
1309 		interpolateVec2(L, r->gravity, 2);
1310 	}
1311 	luaReturnNil();
1312 }
1313 
luaFunc(obj_getGravity)1314 luaFunc(obj_getGravity)
1315 {
1316 	Vector v;
1317 	RenderObject *r = robj(L);
1318 	if (r)
1319 		v = r->gravity;
1320 	luaReturnVec2(v.x, v.y);
1321 }
1322 
luaFunc(obj_getCollideRadius)1323 luaFunc(obj_getCollideRadius)
1324 {
1325 	RenderObject *r = robj(L);
1326 	luaReturnNum(r ? r->collideRadius : 0);
1327 }
1328 
luaFunc(obj_setCollideRadius)1329 luaFunc(obj_setCollideRadius)
1330 {
1331 	RenderObject *r = robj(L);
1332 	if (r)
1333 		r->collideRadius = lua_tonumber(L, 2);
1334 	luaReturnNil();
1335 }
1336 
luaFunc(obj_getNormal)1337 luaFunc(obj_getNormal)
1338 {
1339 	Vector v(0, 1);
1340 	RenderObject *r = robj(L);
1341 	if (r)
1342 		v = r->getForward();
1343 	luaReturnVec2(v.x, v.y);
1344 }
1345 
luaFunc(obj_getVectorToObj)1346 luaFunc(obj_getVectorToObj)
1347 {
1348 	RenderObject *r1 = robj(L);
1349 	RenderObject *r2 = robj(L, 2);
1350 	if (r1 && r2)
1351 	{
1352 		Vector diff = r2->position - r1->position;
1353 		luaReturnVec2(diff.x, diff.y);
1354 	}
1355 	else
1356 	{
1357 		luaReturnVec2(0, 0);
1358 	}
1359 }
1360 
luaFunc(obj_stopInterpolating)1361 luaFunc(obj_stopInterpolating)
1362 {
1363 	RenderObject *r = robj(L);
1364 	if (r)
1365 		r->position.stop();
1366 	luaReturnNil();
1367 }
1368 
luaFunc(obj_isInterpolating)1369 luaFunc(obj_isInterpolating)
1370 {
1371 	RenderObject *r = robj(L);
1372 	luaReturnBool(r ? r->position.isInterpolating() : false);
1373 }
1374 
luaFunc(obj_followCamera)1375 luaFunc(obj_followCamera)
1376 {
1377 	RenderObject *r = robj(L);
1378 	if (r)
1379 		r->followCamera = lua_tonumber(L, 2);
1380 	luaReturnNil();
1381 }
1382 
luaFunc(obj_update)1383 luaFunc(obj_update)
1384 {
1385 	RenderObject *r = robj(L);
1386 	if (r)
1387 		r->update(lua_tonumber(L, 2));
1388 	luaReturnNil();
1389 }
1390 
luaFunc(obj_getWorldPosition)1391 luaFunc(obj_getWorldPosition)
1392 {
1393 	RenderObject *b = robj(L);
1394 	float x = 0, y = 0;
1395 	if (b)
1396 	{
1397 		Vector v = b->getWorldCollidePosition(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)));
1398 		x = v.x;
1399 		y = v.y;
1400 	}
1401 	luaReturnVec2(x, y);
1402 }
1403 
luaFunc(obj_getWorldRotation)1404 luaFunc(obj_getWorldRotation)
1405 {
1406 	RenderObject *r = robj(L);
1407 	luaReturnNum(r ? r->getWorldRotation() : 0.0f);
1408 }
1409 
luaFunc(obj_getWorldPositionAndRotation)1410 luaFunc(obj_getWorldPositionAndRotation)
1411 {
1412 	RenderObject *r = robj(L);
1413 	if (r)
1414 	{
1415 		Vector v = r->getWorldPositionAndRotation();
1416 		luaReturnVec3(v.x, v.y, v.z);
1417 	}
1418 	luaReturnVec3(0.0f, 0.0f, 0.0f);
1419 }
1420 
luaFunc(obj_moveToFront)1421 luaFunc(obj_moveToFront)
1422 {
1423 	RenderObject *r = robj(L);
1424 	if (r)
1425 		r->moveToFront();
1426 	luaReturnNil();
1427 }
1428 
luaFunc(obj_moveToBack)1429 luaFunc(obj_moveToBack)
1430 {
1431 	RenderObject *r = robj(L);
1432 	if (r)
1433 		r->moveToBack();
1434 	luaReturnNil();
1435 }
1436 
luaFunc(obj_setLayer)1437 luaFunc(obj_setLayer)
1438 {
1439 	RenderObject *r = robj(L);
1440 	if (r)
1441 		core->switchRenderObjectLayer(r, lua_tointeger(L, 2));
1442 	luaReturnNil();
1443 }
1444 
luaFunc(obj_getLayer)1445 luaFunc(obj_getLayer)
1446 {
1447 	RenderObject *r = robj(L);
1448 	luaReturnInt(r ? r->layer : 0);
1449 }
1450 
luaFunc(obj_setRenderPass)1451 luaFunc(obj_setRenderPass)
1452 {
1453 	RenderObject *r = robj(L);
1454 	int pass = lua_tointeger(L, 2);
1455 	if (r)
1456 		r->setRenderPass(pass);
1457 	luaReturnNil();
1458 }
1459 
luaFunc(obj_setOverrideRenderPass)1460 luaFunc(obj_setOverrideRenderPass)
1461 {
1462 	RenderObject *r = robj(L);
1463 	int pass = lua_tointeger(L, 2);
1464 	if (r)
1465 		r->setOverrideRenderPass(pass);
1466 	luaReturnNil();
1467 }
1468 
luaFunc(obj_fh)1469 luaFunc(obj_fh)
1470 {
1471 	RenderObject *r = robj(L);
1472 	if (r)
1473 		r->flipHorizontal();
1474 	luaReturnNil();
1475 }
1476 
luaFunc(obj_fhTo)1477 luaFunc(obj_fhTo)
1478 {
1479 	RenderObject *r = robj(L);
1480 	bool b = getBool(L);
1481 	if (r)
1482 		r->fhTo(b);
1483 	luaReturnNil();
1484 }
1485 
luaFunc(obj_fv)1486 luaFunc(obj_fv)
1487 {
1488 	RenderObject *r = robj(L);
1489 	if (r)
1490 		r->flipVertical();
1491 	luaReturnNil();
1492 }
1493 
luaFunc(obj_isfh)1494 luaFunc(obj_isfh)
1495 {
1496 	RenderObject *r = robj(L);
1497 	luaReturnBool(r ? r->isfh() : false);
1498 }
1499 
luaFunc(obj_isfv)1500 luaFunc(obj_isfv)
1501 {
1502 	RenderObject *r = robj(L);
1503 	luaReturnBool(r ? r->isfv() : false);
1504 }
1505 
luaFunc(obj_isfhr)1506 luaFunc(obj_isfhr)
1507 {
1508 	RenderObject *r = robj(L);
1509 	luaReturnBool(r ? r->isfhr() : false);
1510 }
1511 
luaFunc(obj_isfvr)1512 luaFunc(obj_isfvr)
1513 {
1514 	RenderObject *r = robj(L);
1515 	luaReturnBool(r ? r->isfvr() : false);
1516 }
1517 
luaFunc(obj_damageFlash)1518 luaFunc(obj_damageFlash)
1519 {
1520 	RenderObject *r = robj(L);
1521 	int type = lua_tointeger(L, 2);
1522 	if (r)
1523 	{
1524 		Vector toColor = Vector(1, 0.1, 0.1);
1525 		if (type == 1)
1526 			toColor = Vector(1, 1, 0.1);
1527 		r->color = Vector(1,1,1);
1528 		r->color.interpolateTo(toColor, 0.1, 5, 1);
1529 	}
1530 	luaReturnNil();
1531 }
1532 
luaFunc(obj_setCull)1533 luaFunc(obj_setCull)
1534 {
1535 	RenderObject *r = robj(L);
1536 	if (r)
1537 		r->cull = getBool(L, 2);
1538 	luaReturnNil();
1539 }
1540 
luaFunc(obj_setCullRadius)1541 luaFunc(obj_setCullRadius)
1542 {
1543 	RenderObject *r = robj(L);
1544 	if (r)
1545 		r->setOverrideCullRadius(lua_tonumber(L, 2));
1546 	luaReturnNil();
1547 }
1548 
luaFunc(obj_isScaling)1549 luaFunc(obj_isScaling)
1550 {
1551 	RenderObject *r = robj(L);
1552 	luaReturnBool(r ? r->scale.isInterpolating() : false);
1553 }
1554 
luaFunc(obj_isRotating)1555 luaFunc(obj_isRotating)
1556 {
1557 	RenderObject *r = robj(L);
1558 	luaReturnBool(r ? r->rotation.isInterpolating() : false);
1559 }
1560 
luaFunc(obj_setUpdateCull)1561 luaFunc(obj_setUpdateCull)
1562 {
1563 	RenderObject *r = robj(L);;
1564 	if (r)
1565 		r->updateCull = lua_tonumber(L, 2);
1566 	luaReturnNil();
1567 }
1568 
luaFunc(obj_getUpdateCull)1569 luaFunc(obj_getUpdateCull)
1570 {
1571 	RenderObject *r = robj(L);;
1572 	luaReturnNum(r ? r->updateCull : 0.0f);
1573 }
1574 
luaFunc(obj_setPositionX)1575 luaFunc(obj_setPositionX)
1576 {
1577 	RenderObject *r = robj(L);
1578 	if (r)
1579 		r->position.x = lua_tonumber(L, 2);
1580 	luaReturnNil();
1581 }
1582 
luaFunc(obj_setPositionY)1583 luaFunc(obj_setPositionY)
1584 {
1585 	RenderObject *r = robj(L);
1586 	if (r)
1587 		r->position.y = lua_tonumber(L, 2);
1588 	luaReturnNil();
1589 }
1590 
luaFunc(obj_enableMotionBlur)1591 luaFunc(obj_enableMotionBlur)
1592 {
1593 	RenderObject *r = robj(L);
1594 	if (r)
1595 		r->enableMotionBlur(10, 2);
1596 	luaReturnNil();
1597 }
1598 
luaFunc(obj_disableMotionBlur)1599 luaFunc(obj_disableMotionBlur)
1600 {
1601 	RenderObject *r = robj(L);
1602 	if (r)
1603 		r->disableMotionBlur();
1604 	luaReturnNil();
1605 }
1606 
luaFunc(obj_collideCircleVsLine)1607 luaFunc(obj_collideCircleVsLine)
1608 {
1609 	RenderObject *r = robj(L);
1610 	float x1, y1, x2, y2, sz;
1611 	x1 = lua_tonumber(L, 2);
1612 	y1 = lua_tonumber(L, 3);
1613 	x2 = lua_tonumber(L, 4);
1614 	y2 = lua_tonumber(L, 5);
1615 	sz = lua_tonumber(L, 6);
1616 	bool v = false;
1617 	if (r)
1618 		v = dsq->game->collideCircleVsLine(r, Vector(x1, y1), Vector(x2, y2), sz);
1619 	luaReturnBool(v);
1620 }
1621 
luaFunc(obj_collideCircleVsLineAngle)1622 luaFunc(obj_collideCircleVsLineAngle)
1623 {
1624 	RenderObject *r = robj(L);
1625 	float angle = lua_tonumber(L, 2);
1626 	float start=lua_tonumber(L, 3), end=lua_tonumber(L, 4), radius=lua_tonumber(L, 5);
1627 	float x=lua_tonumber(L, 6);
1628 	float y=lua_tonumber(L, 7);
1629 	bool v = false;
1630 	if (r)
1631 		v = dsq->game->collideCircleVsLineAngle(r, angle, start, end, radius, Vector(x,y));
1632 	luaReturnBool(v);
1633 }
1634 
luaFunc(obj_fadeAlphaWithLife)1635 luaFunc(obj_fadeAlphaWithLife)
1636 {
1637 	RenderObject *r = robj(L);
1638 	if (r)
1639 		r->fadeAlphaWithLife = getBool(L, 2);
1640 	luaReturnNil();
1641 }
1642 
luaFunc(obj_getWorldScale)1643 luaFunc(obj_getWorldScale)
1644 {
1645 	RenderObject *r = robj(L);
1646 	Vector s;
1647 	if (r)
1648 		s = r->getRealScale();
1649 	luaReturnVec2(s.x, s.y);
1650 }
1651 
luaFunc(obj_getParent)1652 luaFunc(obj_getParent)
1653 {
1654 	RenderObject *r = robj(L);
1655 	luaReturnPtr(r ? r->getParent() : NULL);
1656 }
1657 
1658 
1659 // ----- end RenderObject common functions -----
1660 
1661 // ----- Quad common functions -----
1662 
luaFunc(quad_isVisible)1663 luaFunc(quad_isVisible)
1664 {
1665 	Quad *q = getQuad(L);
1666 	luaReturnBool(q ? q->renderQuad : false);
1667 }
1668 
luaFunc(quad_setVisible)1669 luaFunc(quad_setVisible)
1670 {
1671 	Quad *q = getQuad(L);
1672 	if (q)
1673 		q->renderQuad = getBool(L, 2);
1674 	luaReturnNil();
1675 }
1676 
luaFunc(quad_getWidth)1677 luaFunc(quad_getWidth)
1678 {
1679 	Quad *q = getQuad(L);
1680 	luaReturnNum(q ? q->width : 0.0f);
1681 }
1682 
luaFunc(quad_getHeight)1683 luaFunc(quad_getHeight)
1684 {
1685 	Quad *q = getQuad(L);
1686 	luaReturnNum(q ? q->height : 0.0f);
1687 }
1688 
luaFunc(quad_setWidth)1689 luaFunc(quad_setWidth)
1690 {
1691 	Quad *q = getQuad(L);
1692 	if (q)
1693 		q->setWidth(lua_tonumber(L, 2));
1694 	luaReturnNil();
1695 }
1696 
luaFunc(quad_setHeight)1697 luaFunc(quad_setHeight)
1698 {
1699 	Quad *q = getQuad(L);
1700 	if (q)
1701 		q->setHeight(lua_tonumber(L, 2));
1702 	luaReturnNil();
1703 }
1704 
luaFunc(quad_setSegs)1705 luaFunc(quad_setSegs)
1706 {
1707 	Quad *b = getQuad(L);
1708 	if (b)
1709 		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));
1710 	luaReturnNil();
1711 }
1712 
luaFunc(quad_setRepeatTexture)1713 luaFunc(quad_setRepeatTexture)
1714 {
1715 	Quad *b = getQuad(L);
1716 	if (b)
1717 		b->repeatTextureToFill(getBool(L, 2));
1718 	luaReturnNil();
1719 }
1720 
luaFunc(quad_setRepeatScale)1721 luaFunc(quad_setRepeatScale)
1722 {
1723 	Quad *b = getQuad(L);
1724 	if (b)
1725 		b->repeatToFillScale = Vector(lua_tonumber(L, 2), lua_tonumber(L, 3));
1726 	luaReturnNil();
1727 }
1728 
luaFunc(quad_isRepeatTexture)1729 luaFunc(quad_isRepeatTexture)
1730 {
1731 	Quad *b = getQuad(L);
1732 	luaReturnBool(b ? b->isRepeatingTextureToFill() : false);
1733 }
1734 
luaFunc(quad_setTexOffset)1735 luaFunc(quad_setTexOffset)
1736 {
1737 	Quad *b = getQuad(L);
1738 	if (b)
1739 		b->texOff = Vector(lua_tonumber(L, 2), lua_tonumber(L, 3));
1740 	luaReturnNil();
1741 }
1742 
luaFunc(quad_getTexOffset)1743 luaFunc(quad_getTexOffset)
1744 {
1745 	Quad *b = getQuad(L);
1746 	Vector v;
1747 	if (b)
1748 		v = b->texOff;
1749 	luaReturnVec2(v.x, v.y);
1750 }
1751 
luaFunc(quad_setRenderBorder)1752 luaFunc(quad_setRenderBorder)
1753 {
1754 	Quad *b = getQuad(L);
1755 	if (b)
1756 		b->renderBorder = getBool(L, 2);
1757 	luaReturnNil();
1758 }
1759 
luaFunc(quad_isRenderBorder)1760 luaFunc(quad_isRenderBorder)
1761 {
1762 	Quad *b = getQuad(L);
1763 	luaReturnBool(b ? b->renderBorder : false);
1764 }
1765 
luaFunc(quad_setRenderCenter)1766 luaFunc(quad_setRenderCenter)
1767 {
1768 	Quad *b = getQuad(L);
1769 	if (b)
1770 		b->renderCenter = getBool(L, 2);
1771 	luaReturnNil();
1772 }
1773 
luaFunc(quad_isRenderCenter)1774 luaFunc(quad_isRenderCenter)
1775 {
1776 	Quad *b = getQuad(L);
1777 	luaReturnBool(b ? b->renderCenter : false);
1778 }
1779 
1780 
luaFunc(quad_borderAlpha)1781 luaFunc(quad_borderAlpha)
1782 {
1783 	Quad *b = getQuad(L);
1784 	if (b)
1785 		b->borderAlpha = lua_tonumber(L, 2);
1786 	luaReturnNil();
1787 }
1788 
luaFunc(quad_getBorderAlpha)1789 luaFunc(quad_getBorderAlpha)
1790 {
1791 	Quad *b = getQuad(L);
1792 	luaReturnNum(b ? b->borderAlpha : 0.0f);
1793 }
1794 
1795 // --- standard set/get functions for each type, wrapping RenderObject functions ---
1796 
1797 #define MK_FUNC(base, getter, prefix, suffix)	\
1798 	luaFunc(prefix##_##suffix) \
1799 	{									\
1800 		typecheckOnly(getter(L));		\
1801 		return forwardCall(base##_##suffix);		\
1802 	}
1803 
1804 #define MK_ALIAS(prefix, suffix, alias) // not yet used here. defined to avoid warnings
1805 
1806 #define RO_FUNC(getter, prefix, suffix) MK_FUNC(obj,  getter, prefix, suffix)
1807 #define Q_FUNC(getter, prefix, suffix)  MK_FUNC(quad, getter, prefix, suffix)
1808 
1809 #define MAKE_ROBJ_FUNCS(getter, prefix) \
1810 	RO_FUNC(getter, prefix,  setPosition	) \
1811 	RO_FUNC(getter, prefix,  scale			) \
1812 	RO_FUNC(getter, prefix,  getScale		) \
1813 	RO_FUNC(getter, prefix,  isScaling		) \
1814 	RO_FUNC(getter, prefix,  alpha			) \
1815 	RO_FUNC(getter, prefix,  alphaMod		) \
1816 	RO_FUNC(getter, prefix,  getAlpha		) \
1817 	RO_FUNC(getter, prefix,  getAlphaMod	) \
1818 	RO_FUNC(getter, prefix,  color			) \
1819 	RO_FUNC(getter, prefix,  getColor		) \
1820 	RO_FUNC(getter, prefix,  rotate			) \
1821 	RO_FUNC(getter, prefix,  rotateOffset	) \
1822 	RO_FUNC(getter, prefix,  getRotation	) \
1823 	RO_FUNC(getter, prefix,  getRotationOffset) \
1824 	RO_FUNC(getter, prefix,  isRotating		) \
1825 	RO_FUNC(getter, prefix,  offset			) \
1826 	RO_FUNC(getter, prefix,  getOffset		) \
1827 	RO_FUNC(getter, prefix,  internalOffset	) \
1828 	RO_FUNC(getter, prefix,  getInternalOffset) \
1829 	RO_FUNC(getter, prefix,  getPosition	) \
1830 	RO_FUNC(getter, prefix,  getTexture		) \
1831 	RO_FUNC(getter, prefix,  x				) \
1832 	RO_FUNC(getter, prefix,  y				) \
1833 	RO_FUNC(getter, prefix,  setBlendType	) \
1834 	RO_FUNC(getter, prefix,  setTexture		) \
1835 	RO_FUNC(getter, prefix,  delete			) \
1836 	RO_FUNC(getter, prefix,  getLife		) \
1837 	RO_FUNC(getter, prefix,  setLife		) \
1838 	RO_FUNC(getter, prefix,  setDecayRate	) \
1839 	RO_FUNC(getter, prefix,  addDeathNotify	) \
1840 	RO_FUNC(getter, prefix,  setInternalVel	) \
1841 	RO_FUNC(getter, prefix,  setInternalVelLen) \
1842 	RO_FUNC(getter, prefix,  getInternalVel	) \
1843 	RO_FUNC(getter, prefix,  ivelx			) \
1844 	RO_FUNC(getter, prefix,  ively			) \
1845 	RO_FUNC(getter, prefix,  addInternalVel	) \
1846 	RO_FUNC(getter, prefix,  isInternalVelIn) \
1847 	RO_FUNC(getter, prefix,  getInternalVelLen) \
1848 	RO_FUNC(getter, prefix,  setGravity		) \
1849 	RO_FUNC(getter, prefix,  getGravity		) \
1850 	RO_FUNC(getter, prefix,  getCollideRadius) \
1851 	RO_FUNC(getter, prefix,  setCollideRadius) \
1852 	RO_FUNC(getter, prefix,  getNormal		) \
1853 	RO_FUNC(getter, prefix,  stopInterpolating)\
1854 	RO_FUNC(getter, prefix,  isInterpolating)\
1855 	RO_FUNC(getter, prefix,  followCamera	) \
1856 	RO_FUNC(getter, prefix,  update			) \
1857 	RO_FUNC(getter, prefix,  getWorldPosition) \
1858 	RO_FUNC(getter, prefix,  getWorldRotation) \
1859 	RO_FUNC(getter, prefix,  getWorldPositionAndRotation)\
1860 	RO_FUNC(getter, prefix,  moveToFront	) \
1861 	RO_FUNC(getter, prefix,  moveToBack		) \
1862 	RO_FUNC(getter, prefix,  setLayer		) \
1863 	RO_FUNC(getter, prefix,  getLayer		) \
1864 	RO_FUNC(getter, prefix,  setRenderBeforeParent) \
1865 	RO_FUNC(getter, prefix,  isRenderBeforeParent) \
1866 	RO_FUNC(getter, prefix,  addChild		) \
1867 	RO_FUNC(getter, prefix,  fh				) \
1868 	RO_FUNC(getter, prefix,  fv				) \
1869 	RO_FUNC(getter, prefix,  fhTo			) \
1870 	RO_FUNC(getter, prefix,  isfh			) \
1871 	RO_FUNC(getter, prefix,  isfv			) \
1872 	RO_FUNC(getter, prefix,  isfhr			) \
1873 	RO_FUNC(getter, prefix,  isfvr			) \
1874 	RO_FUNC(getter, prefix,  damageFlash	) \
1875 	RO_FUNC(getter, prefix,  setCull		) \
1876 	RO_FUNC(getter, prefix,  setCullRadius	) \
1877 	RO_FUNC(getter, prefix,  setUpdateCull	) \
1878 	RO_FUNC(getter, prefix,  getUpdateCull	) \
1879 	RO_FUNC(getter, prefix,  setRenderPass	) \
1880 	RO_FUNC(getter, prefix,  setOverrideRenderPass	) \
1881 	RO_FUNC(getter, prefix,  setPositionX	) \
1882 	RO_FUNC(getter, prefix,  setPositionY	) \
1883 	RO_FUNC(getter, prefix,  enableMotionBlur	) \
1884 	RO_FUNC(getter, prefix,  disableMotionBlur	) \
1885 	RO_FUNC(getter, prefix,  collideCircleVsLine) \
1886 	RO_FUNC(getter, prefix,  collideCircleVsLineAngle) \
1887 	RO_FUNC(getter, prefix,  getVectorToObj	) \
1888 	RO_FUNC(getter, prefix,  fadeAlphaWithLife	) \
1889 	RO_FUNC(getter, prefix,  getWorldScale	) \
1890 	RO_FUNC(getter, prefix,  getParent		) \
1891 	MK_ALIAS(prefix, fh, flipHorizontal	) \
1892 	MK_ALIAS(prefix, fv, flipVertical	)
1893 
1894 #define MAKE_QUAD_FUNCS(getter, prefix)	\
1895 	MAKE_ROBJ_FUNCS(getter, prefix)		\
1896 	Q_FUNC(getter, prefix,  setVisible		) \
1897 	Q_FUNC(getter, prefix,  isVisible		) \
1898 	Q_FUNC(getter, prefix,  setWidth		) \
1899 	Q_FUNC(getter, prefix,  setHeight		) \
1900 	Q_FUNC(getter, prefix,  getWidth		) \
1901 	Q_FUNC(getter, prefix,  getHeight		) \
1902 	Q_FUNC(getter, prefix,  setSegs			) \
1903 	Q_FUNC(getter, prefix,  setRepeatTexture) \
1904 	Q_FUNC(getter, prefix,  isRepeatTexture	) \
1905 	Q_FUNC(getter, prefix,  setRepeatScale	) \
1906 	Q_FUNC(getter, prefix,  setRenderBorder	) \
1907 	Q_FUNC(getter, prefix,  isRenderBorder	) \
1908 	Q_FUNC(getter, prefix,  setRenderCenter	) \
1909 	Q_FUNC(getter, prefix,  isRenderCenter	) \
1910 	Q_FUNC(getter, prefix,  borderAlpha		) \
1911 	Q_FUNC(getter, prefix,  getBorderAlpha	) \
1912 	Q_FUNC(getter, prefix,  setTexOffset	) \
1913 	Q_FUNC(getter, prefix,  getTexOffset	)
1914 
1915 // This should reflect the internal class hierarchy,
1916 // e.g. a Beam is a Quad, so it can use quad_* functions
1917 #define EXPAND_FUNC_PROTOTYPES \
1918 	MAKE_QUAD_FUNCS(entity,   entity) \
1919 	MAKE_QUAD_FUNCS(bone,     bone	) \
1920 	MAKE_QUAD_FUNCS(getShot,  shot	) \
1921 	MAKE_QUAD_FUNCS(beam,     beam	) \
1922 	MAKE_ROBJ_FUNCS(getQuad,  quad	) \
1923 	MAKE_ROBJ_FUNCS(getWeb,   web	) \
1924 	MAKE_ROBJ_FUNCS(getText,  text	) \
1925 	MAKE_ROBJ_FUNCS(getParticle, pe	)
1926 
1927 // first time, create them. (There is a second use of this further down, with different MK_* macros)
1928 EXPAND_FUNC_PROTOTYPES
1929 
1930 
luaFunc(debugBreak)1931 luaFunc(debugBreak)
1932 {
1933 	debugLog("DEBUG BREAK");
1934 	triggerBreakpoint();
1935 	luaReturnNil();
1936 }
1937 
luaFunc(setIgnoreAction)1938 luaFunc(setIgnoreAction)
1939 {
1940 	dsq->game->setIgnoreAction((AquariaActions)lua_tointeger(L, 1), getBool(L, 2));
1941 	luaReturnNil();
1942 }
1943 
luaFunc(isIgnoreAction)1944 luaFunc(isIgnoreAction)
1945 {
1946 	luaReturnBool(dsq->game->isIgnoreAction((AquariaActions)lua_tointeger(L, 1)));
1947 }
1948 
luaFunc(sendAction)1949 luaFunc(sendAction)
1950 {
1951 	AquariaActions ac = (AquariaActions)lua_tointeger(L, 1);
1952 	int state = lua_tointeger(L, 2);
1953 	int mask = lua_tointeger(L, 3);
1954 	if(!mask)
1955 		mask = -1;
1956 	if(mask & 1)
1957 		dsq->game->action(ac, state);
1958 	if((mask & 2) && dsq->game->avatar)
1959 		dsq->game->avatar->action(ac, state);
1960 	luaReturnNil();
1961 }
1962 
luaFunc(randRange)1963 luaFunc(randRange)
1964 {
1965 	int n1 = lua_tointeger(L, 1);
1966 	int n2 = lua_tointeger(L, 2);
1967 	int spread = n2-n1;
1968 
1969 	int r = rand()%spread;
1970 	r += n1;
1971 
1972 	luaReturnNum(r);
1973 }
1974 
luaFunc(upgradeHealth)1975 luaFunc(upgradeHealth)
1976 {
1977 	dsq->continuity.upgradeHealth();
1978 	luaReturnNil();
1979 }
1980 
luaFunc(shakeCamera)1981 luaFunc(shakeCamera)
1982 {
1983 	dsq->shakeCamera(lua_tonumber(L,1), lua_tonumber(L, 2));
1984 	luaReturnNil();
1985 }
1986 
luaFunc(rumble)1987 luaFunc(rumble)
1988 {
1989 	dsq->rumble(lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3));
1990 	luaReturnNil();
1991 }
1992 
luaFunc(changeForm)1993 luaFunc(changeForm)
1994 {
1995 	dsq->game->avatar->changeForm((FormType)lua_tointeger(L, 1));
1996 	luaReturnNil();
1997 }
1998 
luaFunc(getWaterLevel)1999 luaFunc(getWaterLevel)
2000 {
2001 	luaReturnNum(dsq->game->getWaterLevel());
2002 }
2003 
luaFunc(setPoison)2004 luaFunc(setPoison)
2005 {
2006 	dsq->continuity.setPoison(lua_tonumber(L, 1), lua_tonumber(L, 2));
2007 	luaReturnNil();
2008 }
2009 
luaFunc(cureAllStatus)2010 luaFunc(cureAllStatus)
2011 {
2012 	dsq->continuity.cureAllStatus();
2013 	luaReturnNil();
2014 }
2015 
luaFunc(setMusicToPlay)2016 luaFunc(setMusicToPlay)
2017 {
2018 	if (lua_isstring(L, 1))
2019 		dsq->game->setMusicToPlay(getString(L, 1));
2020 	luaReturnNil();
2021 }
2022 
luaFunc(setActivePet)2023 luaFunc(setActivePet)
2024 {
2025 	Entity *e = dsq->game->setActivePet(lua_tonumber(L, 1));
2026 
2027 	luaReturnPtr(e);
2028 }
2029 
luaFunc(setWaterLevel)2030 luaFunc(setWaterLevel)
2031 {
2032 	interpolateVec1(L, dsq->game->waterLevel, 1);
2033 	luaReturnNum(dsq->game->waterLevel.x);
2034 }
2035 
luaFunc(getForm)2036 luaFunc(getForm)
2037 {
2038 	luaReturnNum(dsq->continuity.form);
2039 }
2040 
luaFunc(isForm)2041 luaFunc(isForm)
2042 {
2043 	FormType form = FormType(lua_tointeger(L, 1));
2044 	bool v = (form == dsq->continuity.form);
2045 	luaReturnBool(v);
2046 }
2047 
luaFunc(learnFormUpgrade)2048 luaFunc(learnFormUpgrade)
2049 {
2050 	dsq->continuity.learnFormUpgrade((FormUpgradeType)lua_tointeger(L, 1));
2051 	luaReturnNil();
2052 }
2053 
luaFunc(hasLi)2054 luaFunc(hasLi)
2055 {
2056 	luaReturnBool(dsq->continuity.hasLi());
2057 }
2058 
luaFunc(hasFormUpgrade)2059 luaFunc(hasFormUpgrade)
2060 {
2061 	luaReturnBool(dsq->continuity.hasFormUpgrade((FormUpgradeType)lua_tointeger(L, 1)));
2062 }
2063 
2064 // This used to be castSong(), but that name is already taken by an interface function. -- FG
luaFunc(singSong)2065 luaFunc(singSong)
2066 {
2067 	dsq->continuity.castSong(lua_tonumber(L, 1));
2068 	luaReturnNil();
2069 }
2070 
luaFunc(isStory)2071 luaFunc(isStory)
2072 {
2073 	luaReturnBool(dsq->continuity.isStory(lua_tonumber(L, 1)));
2074 }
2075 
luaFunc(getNoteVector)2076 luaFunc(getNoteVector)
2077 {
2078 	int note = lua_tointeger(L, 1);
2079 	float mag = lua_tonumber(L, 2);
2080 	Vector v = dsq->getNoteVector(note, mag);
2081 	luaReturnVec2(v.x, v.y);
2082 }
2083 
luaFunc(getNoteColor)2084 luaFunc(getNoteColor)
2085 {
2086 	int note = lua_tointeger(L, 1);
2087 	Vector v = dsq->getNoteColor(note);
2088 	luaReturnVec3(v.x, v.y, v.z);
2089 }
2090 
luaFunc(getRandNote)2091 luaFunc(getRandNote)
2092 {
2093 	//int note = lua_tointeger(L, 1);
2094 
2095 	luaReturnNum(dsq->getRandNote());
2096 }
2097 
luaFunc(getStory)2098 luaFunc(getStory)
2099 {
2100 	luaReturnNum(dsq->continuity.getStory());
2101 }
2102 
luaFunc(foundLostMemory)2103 luaFunc(foundLostMemory)
2104 {
2105 	int num = 0;
2106 	if (dsq->continuity.getFlag(FLAG_SECRET01)) num++;
2107 	if (dsq->continuity.getFlag(FLAG_SECRET02)) num++;
2108 	if (dsq->continuity.getFlag(FLAG_SECRET03)) num++;
2109 
2110 	int sbank = 800+(num-1);
2111 	dsq->game->setControlHint(dsq->continuity.stringBank.get(sbank), 0, 0, 0, 4, "13/face");
2112 
2113 	dsq->sound->playSfx("memory-found");
2114 
2115 	luaReturnNil();
2116 }
2117 
luaFunc(setStory)2118 luaFunc(setStory)
2119 {
2120 	dsq->continuity.setStory(lua_tonumber(L, 1));
2121 	luaReturnNil();
2122 }
2123 
luaFunc(confirm)2124 luaFunc(confirm)
2125 {
2126 	std::string s1 = getString(L, 1);
2127 	std::string s2 = getString(L, 2);
2128 	bool b = dsq->confirm(s1, s2);
2129 	luaReturnBool(b);
2130 }
2131 
luaFunc(createWeb)2132 luaFunc(createWeb)
2133 {
2134 	Web *web = new Web();
2135 	dsq->game->addRenderObject(web, LR_PARTICLES);
2136 	luaReturnPtr(web);
2137 }
2138 
2139 // spore has base entity
luaFunc(createSpore)2140 luaFunc(createSpore)
2141 {
2142 	Vector pos(lua_tonumber(L, 1), lua_tonumber(L, 2));
2143 	if (Spore::isPositionClear(pos))
2144 	{
2145 		Spore *spore = new Spore(pos);
2146 		dsq->game->addRenderObject(spore, LR_ENTITIES);
2147 		luaReturnPtr(spore);
2148 	}
2149 	else
2150 		luaReturnPtr(NULL);
2151 }
2152 
luaFunc(web_addPoint)2153 luaFunc(web_addPoint)
2154 {
2155 	Web *w = getWeb(L);
2156 	float x = lua_tonumber(L, 2);
2157 	float y = lua_tonumber(L, 3);
2158 	int r = 0;
2159 	if (w)
2160 	{
2161 		r = w->addPoint(Vector(x,y));
2162 	}
2163 	luaReturnInt(r);
2164 }
2165 
luaFunc(web_setPoint)2166 luaFunc(web_setPoint)
2167 {
2168 	Web *w = getWeb(L);
2169 	int pt = lua_tointeger(L, 2);
2170 	float x = lua_tonumber(L, 3);
2171 	float y = lua_tonumber(L, 4);
2172 	if (w)
2173 	{
2174 		w->setPoint(pt, Vector(x, y));
2175 	}
2176 	luaReturnInt(pt);
2177 }
2178 
luaFunc(web_getNumPoints)2179 luaFunc(web_getNumPoints)
2180 {
2181 	Web *web = getWeb(L);
2182 	int num = 0;
2183 	if (web)
2184 	{
2185 		num = web->getNumPoints();
2186 	}
2187 	luaReturnInt(num);
2188 }
2189 
luaFunc(getFirstShot)2190 luaFunc(getFirstShot)
2191 {
2192 	luaReturnPtr(Shot::getFirstShot());
2193 }
2194 
luaFunc(getNextShot)2195 luaFunc(getNextShot)
2196 {
2197 	luaReturnPtr(Shot::getNextShot());
2198 }
2199 
luaFunc(shot_getName)2200 luaFunc(shot_getName)
2201 {
2202 	Shot *s = getShot(L);
2203 	luaReturnStr(s ? s->getName() : "");
2204 }
2205 
luaFunc(shot_setOut)2206 luaFunc(shot_setOut)
2207 {
2208 	Shot *shot = getShot(L);
2209 	float outness = lua_tonumber(L, 2);
2210 	if (shot && shot->firer)
2211 	{
2212 		Vector adjust = shot->velocity;
2213 		adjust.setLength2D(outness);
2214 		shot->position += adjust;
2215 		/*
2216 		std::ostringstream os;
2217 		os << "out(" << adjust.x << ", " << adjust.y << ")";
2218 		debugLog(os.str());
2219 		*/
2220 	}
2221 	luaReturnNil();
2222 }
2223 
luaFunc(shot_setAimVector)2224 luaFunc(shot_setAimVector)
2225 {
2226 	Shot *shot = getShot(L);
2227 	float ax = lua_tonumber(L, 2);
2228 	float ay = lua_tonumber(L, 3);
2229 	if (shot)
2230 	{
2231 		shot->setAimVector(Vector(ax, ay));
2232 	}
2233 	luaReturnNil();
2234 }
2235 
luaFunc(shot_getEffectTime)2236 luaFunc(shot_getEffectTime)
2237 {
2238 	if (lua_isstring(L, 1))
2239 	{
2240 		ShotData *data = Shot::getShotData(lua_tostring(L, 1));
2241 		luaReturnNum(data ? data->effectTime : 0.0f);
2242 	}
2243 
2244 	Shot *shot = getShot(L);
2245 	luaReturnNum((shot && shot->shotData) ? shot->shotData->effectTime : 0.0f);
2246 }
2247 
luaFunc(shot_isIgnoreShield)2248 luaFunc(shot_isIgnoreShield)
2249 {
2250 	if (lua_isstring(L, 1))
2251 	{
2252 		ShotData *data = Shot::getShotData(lua_tostring(L, 1));
2253 		luaReturnBool(data ? data->ignoreShield : false);
2254 	}
2255 
2256 	Shot *shot = getShot(L);
2257 	luaReturnBool((shot && shot->shotData) ? shot->shotData->ignoreShield : false);
2258 }
2259 
luaFunc(shot_getFirer)2260 luaFunc(shot_getFirer)
2261 {
2262 	Shot *shot = getShot(L);
2263 	luaReturnPtr(shot ? shot->firer : NULL);
2264 }
2265 
luaFunc(shot_setFirer)2266 luaFunc(shot_setFirer)
2267 {
2268 	Shot *shot = getShot(L);
2269 	if(shot)
2270 	{
2271 		Entity *e = lua_isuserdata(L, 2) ? entity(L, 2) : NULL;
2272 		shot->firer = e;
2273 	}
2274 
2275 	luaReturnNil();
2276 }
2277 
luaFunc(shot_setTarget)2278 luaFunc(shot_setTarget)
2279 {
2280 	Shot *shot = getShot(L);
2281 	if(shot)
2282 	{
2283 		Entity *e = lua_isuserdata(L, 2) ? entity(L, 2) : NULL;
2284 		shot->setTarget(e);
2285 	}
2286 	luaReturnNil();
2287 }
2288 
luaFunc(shot_getTarget)2289 luaFunc(shot_getTarget)
2290 {
2291 	Shot *shot = getShot(L);
2292 	luaReturnPtr(shot ? shot->target : NULL);
2293 }
2294 
luaFunc(shot_setExtraDamage)2295 luaFunc(shot_setExtraDamage)
2296 {
2297 	Shot *shot = getShot(L);
2298 	if(shot)
2299 		shot->extraDamage = lua_tonumber(L, 2);
2300 	luaReturnNil();
2301 }
2302 
luaFunc(shot_getExtraDamage)2303 luaFunc(shot_getExtraDamage)
2304 {
2305 	Shot *shot = getShot(L);
2306 	luaReturnNum(shot ? shot->extraDamage : 0.0f);
2307 }
2308 
luaFunc(shot_getDamage)2309 luaFunc(shot_getDamage)
2310 {
2311 	Shot *shot = getShot(L);
2312 	luaReturnNum(shot ? shot->getDamage() : 0.0f);
2313 }
2314 
luaFunc(shot_getDamageType)2315 luaFunc(shot_getDamageType)
2316 {
2317 	if (lua_isstring(L, 1))
2318 	{
2319 		ShotData *data = Shot::getShotData(lua_tostring(L, 1));
2320 		luaReturnInt(data ? data->damageType : 0);
2321 	}
2322 
2323 	Shot *shot = getShot(L);
2324 	luaReturnNum(shot ? shot->getDamageType() : DT_NONE);
2325 }
2326 
luaFunc(shot_getMaxSpeed)2327 luaFunc(shot_getMaxSpeed)
2328 {
2329 	if (lua_isstring(L, 1))
2330 	{
2331 		ShotData *data = Shot::getShotData(lua_tostring(L, 1));
2332 		luaReturnNum(data ? data->maxSpeed : 0.0f);
2333 	}
2334 
2335 	Shot *shot = getShot(L);
2336 	luaReturnNum(shot ? shot->maxSpeed : 0.0f);
2337 }
2338 
luaFunc(shot_setMaxSpeed)2339 luaFunc(shot_setMaxSpeed)
2340 {
2341 	Shot *shot = getShot(L);
2342 	if (shot)
2343 		shot->maxSpeed = lua_tonumber(L, 2);
2344 	luaReturnNil();
2345 }
2346 
luaFunc(shot_getHomingness)2347 luaFunc(shot_getHomingness)
2348 {
2349 	if (lua_isstring(L, 1))
2350 	{
2351 		ShotData *data = Shot::getShotData(lua_tostring(L, 1));
2352 		luaReturnNum(data ? data->homing : 0.0f);
2353 	}
2354 
2355 	Shot *shot = getShot(L);
2356 	luaReturnNum(shot ? shot->homingness : 0.0f);
2357 }
2358 
luaFunc(shot_setHomingness)2359 luaFunc(shot_setHomingness)
2360 {
2361 	Shot *shot = getShot(L);
2362 	if (shot)
2363 		shot->homingness = lua_tonumber(L, 2);
2364 	luaReturnNil();
2365 }
2366 
luaFunc(shot_getLifeTime)2367 luaFunc(shot_getLifeTime)
2368 {
2369 	if (lua_isstring(L, 1))
2370 	{
2371 		ShotData *data = Shot::getShotData(lua_tostring(L, 1));
2372 		luaReturnNum(data ? data->lifeTime : 0.0f);
2373 	}
2374 
2375 	Shot *shot = getShot(L);
2376 	luaReturnNum(shot ? shot->lifeTime : 0.0f);
2377 }
2378 
luaFunc(shot_setLifeTime)2379 luaFunc(shot_setLifeTime)
2380 {
2381 	Shot *shot = getShot(L);
2382 	if (shot)
2383 		shot->lifeTime = lua_tonumber(L, 2);
2384 	luaReturnNil();
2385 }
2386 
luaFunc(shot_setDamageType)2387 luaFunc(shot_setDamageType)
2388 {
2389 	Shot *shot = getShot(L);
2390 	if (shot)
2391 		shot->damageType = (DamageType)lua_tointeger(L, 2);
2392 	luaReturnNil();
2393 }
2394 
luaFunc(shot_setCheckDamageTarget)2395 luaFunc(shot_setCheckDamageTarget)
2396 {
2397 	Shot *shot = getShot(L);
2398 	if (shot)
2399 		shot->checkDamageTarget = getBool(L, 2);
2400 	luaReturnNil();
2401 }
2402 
luaFunc(shot_isCheckDamageTarget)2403 luaFunc(shot_isCheckDamageTarget)
2404 {
2405 	if (lua_isstring(L, 1))
2406 	{
2407 		ShotData *data = Shot::getShotData(lua_tostring(L, 1));
2408 		luaReturnBool(data ? data->checkDamageTarget : false);
2409 	}
2410 
2411 	Shot *shot = getShot(L);
2412 	luaReturnBool(shot ? shot->checkDamageTarget : false);
2413 }
2414 
luaFunc(shot_setTrailPrt)2415 luaFunc(shot_setTrailPrt)
2416 {
2417 	Shot *shot = getShot(L);
2418 	if (shot)
2419 		shot->setParticleEffect(getString(L, 2));
2420 	luaReturnNil();
2421 }
2422 
luaFunc(shot_setTargetPoint)2423 luaFunc(shot_setTargetPoint)
2424 {
2425 	Shot *shot = getShot(L);
2426 	if (shot)
2427 		shot->setTargetPoint(lua_tointeger(L, 2));
2428 	luaReturnNil();
2429 }
2430 
luaFunc(shot_getTargetPoint)2431 luaFunc(shot_getTargetPoint)
2432 {
2433 	Shot *shot = getShot(L);
2434 	luaReturnInt(shot ? shot->targetPt : 0);
2435 }
2436 
luaFunc(shot_canHitEntity)2437 luaFunc(shot_canHitEntity)
2438 {
2439 	Shot *shot = getShot(L);
2440 	Entity *e = entity(L, 2);
2441 	bool hit = false;
2442 	if(shot && e && shot->isActive() && dsq->game->isEntityCollideWithShot(e, shot))
2443 	{
2444 		DamageData d;
2445 		d.attacker = shot->firer;
2446 		d.damage = shot->getDamage();
2447 		d.damageType = shot->getDamageType();
2448 		d.shot = shot;
2449 		hit = e->canShotHit(d);
2450 	}
2451 	luaReturnBool(hit);
2452 }
2453 
2454 
2455 typedef std::pair<Shot*, float> ShotDistancePair;
2456 static std::vector<ShotDistancePair> filteredShots(20);
2457 static int filteredShotIdx = 0;
2458 
_shotDistanceCmp(const ShotDistancePair & a,const ShotDistancePair & b)2459 static bool _shotDistanceCmp(const ShotDistancePair& a, const ShotDistancePair& b)
2460 {
2461 	return a.second < b.second;
2462 }
_shotDistanceEq(const ShotDistancePair & a,const ShotDistancePair & b)2463 static bool _shotDistanceEq(const ShotDistancePair& a, const ShotDistancePair& b)
2464 {
2465 	return a.first == b.first;
2466 }
2467 
_shotFilter(lua_State * L)2468 static size_t _shotFilter(lua_State *L)
2469 {
2470 	const Vector p(lua_tonumber(L, 1), lua_tonumber(L, 2));
2471 	const float radius = lua_tonumber(L, 3);
2472 	const DamageType dt = lua_isnumber(L, 5) ? (DamageType)lua_tointeger(L, 5) : DT_NONE;
2473 
2474 	const float sqrRadius = radius * radius;
2475 	float distsq;
2476 	const bool skipRadiusCheck = radius <= 0;
2477 	size_t added = 0;
2478 	for(Shot::Shots::iterator it = Shot::shots.begin(); it != Shot::shots.end(); ++it)
2479 	{
2480 		Shot *s = *it;
2481 
2482 		if (s->isActive() && s->life >= 1.0f)
2483 		{
2484 			if (dt == DT_NONE || s->getDamageType() == dt)
2485 			{
2486 				if (skipRadiusCheck || (distsq = (s->position - p).getSquaredLength2D()) <= sqrRadius)
2487 				{
2488 					filteredShots.push_back(std::make_pair(s, distsq));
2489 					++added;
2490 				}
2491 			}
2492 		}
2493 	}
2494 	if(added)
2495 	{
2496 		std::sort(filteredShots.begin(), filteredShots.end(), _shotDistanceCmp);
2497 		std::vector<ShotDistancePair>::iterator newend = std::unique(filteredShots.begin(), filteredShots.end(), _shotDistanceEq);
2498 		filteredShots.resize(std::distance(filteredShots.begin(), newend));
2499 	}
2500 
2501 	// Add terminator if there is none
2502 	if(filteredShots.size() && filteredShots.back().first)
2503 		filteredShots.push_back(std::make_pair((Shot*)NULL, 0.0f)); // terminator
2504 
2505 	filteredShotIdx = 0; // Reset getNextFilteredShot() iteration index
2506 
2507 	return added;
2508 }
2509 
luaFunc(filterNearestShots)2510 luaFunc(filterNearestShots)
2511 {
2512 	filteredShots.clear();
2513 	luaReturnInt(_shotFilter(L));
2514 }
2515 
luaFunc(filterNearestShotsAdd)2516 luaFunc(filterNearestShotsAdd)
2517 {
2518 	// Remove terminator if there is one
2519 	if(filteredShots.size() && !filteredShots.back().first)
2520 		filteredShots.pop_back();
2521 	luaReturnInt(_shotFilter(L));
2522 }
2523 
luaFunc(getNextFilteredShot)2524 luaFunc(getNextFilteredShot)
2525 {
2526 	ShotDistancePair sp = filteredShots[filteredShotIdx];
2527 	if (sp.first)
2528 		++filteredShotIdx;
2529 	luaPushPointer(L, sp.first);
2530 	lua_pushnumber(L, sp.second);
2531 	return 2;
2532 }
2533 
2534 
luaFunc(entity_setVel)2535 luaFunc(entity_setVel)
2536 {
2537 	Entity *e = entity(L);
2538 	if (e)
2539 		e->vel = Vector(lua_tonumber(L, 2), lua_tonumber(L, 3));
2540 	luaReturnNil();
2541 }
2542 
luaFunc(entity_setVelLen)2543 luaFunc(entity_setVelLen)
2544 {
2545 	Entity *e = entity(L);
2546 	if (e)
2547 		e->vel.setLength2D(lua_tonumber(L, 2));
2548 	luaReturnNil();
2549 }
2550 
luaFunc(entity_getVelLen)2551 luaFunc(entity_getVelLen)
2552 {
2553 	Entity *e = entity(L);
2554 	luaReturnNum(e ? e->vel.getLength2D() : 0.0f);
2555 }
2556 
2557 
luaFunc(entity_getVel)2558 luaFunc(entity_getVel)
2559 {
2560 	Vector v;
2561 	Entity *e = entity(L);
2562 	if (e)
2563 		v = e->vel;
2564 	luaReturnVec2(v.x, v.y);
2565 }
2566 
luaFunc(entity_velx)2567 luaFunc(entity_velx)
2568 {
2569 	Entity *e = entity(L);
2570 	luaReturnNum(e ? e->vel.x : 0.0f);
2571 }
2572 
luaFunc(entity_vely)2573 luaFunc(entity_vely)
2574 {
2575 	Entity *e = entity(L);
2576 	luaReturnNum(e ? e->vel.y : 0.0f);
2577 }
2578 
luaFunc(entity_addVel)2579 luaFunc(entity_addVel)
2580 {
2581 	Entity *e = entity(L);
2582 	if (e)
2583 		e->vel += Vector(lua_tonumber(L, 2), lua_tonumber(L, 3));
2584 	luaReturnNil();
2585 }
2586 
luaFunc(entity_addRandomVel)2587 luaFunc(entity_addRandomVel)
2588 {
2589 	Entity *e = entity(L);
2590 	float len = lua_tonumber(L, 2);
2591 	Vector add;
2592 	if (e && len)
2593 	{
2594 		int angle = int(rand()%360);
2595 		float a = MathFunctions::toRadians(angle);
2596 		add.x = sinf(a);
2597 		add.y = cosf(a);
2598 		add.setLength2D(len);
2599 		e->vel += add;
2600 	}
2601 	luaReturnVec2(add.x, add.y);
2602 }
2603 
luaFunc(entity_isVelIn)2604 luaFunc(entity_isVelIn)
2605 {
2606 	Entity *e = entity(L);
2607 	luaReturnBool(e ? e->vel.isLength2DIn(lua_tonumber(L, 2)) : false);
2608 
2609 }
2610 
luaFunc(entity_clearVel)2611 luaFunc(entity_clearVel)
2612 {
2613 	Entity *e = entity(L);
2614 	if (e)
2615 		e->vel = Vector(0,0,0);
2616 	luaReturnNil();
2617 }
2618 // end extra Entity::vel functions
2619 
luaFunc(entity_getPushVec)2620 luaFunc(entity_getPushVec)
2621 {
2622 	Entity *e = entity(L);
2623 	Vector v;
2624 	if (e)
2625 		v = e->getPushVec();
2626 	luaReturnVec2(v.x, v.y);
2627 }
2628 
luaFunc(entity_addIgnoreShotDamageType)2629 luaFunc(entity_addIgnoreShotDamageType)
2630 {
2631 	Entity *e = entity(L);
2632 	if (e)
2633 	{
2634 		e->addIgnoreShotDamageType((DamageType)lua_tointeger(L, 2));
2635 	}
2636 	luaReturnNil();
2637 }
2638 
luaFunc(entity_warpLastPosition)2639 luaFunc(entity_warpLastPosition)
2640 {
2641 	Entity *e = entity(L);
2642 	if (e)
2643 	{
2644 		e->warpLastPosition();
2645 	}
2646 	luaReturnNil();
2647 }
2648 
2649 
luaFunc(entity_velTowards)2650 luaFunc(entity_velTowards)
2651 {
2652 	Entity *e = entity(L);
2653 	float x = lua_tonumber(L, 2);
2654 	float y = lua_tonumber(L, 3);
2655 	float velLen = lua_tonumber(L, 4);
2656 	float range = lua_tonumber(L, 5);
2657 	if (e)
2658 	{
2659 		Vector pos(x,y);
2660 		if (range==0 || ((pos - e->position).getLength2D() < range))
2661 		{
2662 			Vector add = pos - e->position;
2663 			add.setLength2D(velLen);
2664 			e->vel2 += add;
2665 		}
2666 	}
2667 	luaReturnNil();
2668 }
2669 
luaFunc(entity_getBoneLockEntity)2670 luaFunc(entity_getBoneLockEntity)
2671 {
2672 	Entity *e = entity(L);
2673 	Entity *ent = NULL;
2674 	if (e)
2675 	{
2676 		BoneLock *b = e->getBoneLock();
2677 		ent = b->entity;
2678 		//ent = e->boneLock.entity;
2679 	}
2680 	luaReturnPtr(ent);
2681 }
2682 
luaFunc(entity_getBoneLockData)2683 luaFunc(entity_getBoneLockData)
2684 {
2685 	Entity *e = entity(L);
2686 	if (!e)
2687 		luaReturnNil();
2688 	BoneLock b = *e->getBoneLock(); // always safe to deref
2689 
2690 	lua_pushboolean(L, b.on);
2691 	luaPushPointer(L, b.bone);
2692 	lua_pushnumber(L, b.origRot);
2693 	lua_pushnumber(L, b.wallNormal.x);
2694 	lua_pushnumber(L, b.wallNormal.y);
2695 	lua_pushnumber(L, b.localOffset.x);
2696 	lua_pushnumber(L, b.localOffset.y);
2697 	return 7;
2698 }
2699 
luaFunc(entity_ensureLimit)2700 luaFunc(entity_ensureLimit)
2701 {
2702 	Entity *e = entity(L);
2703 	dsq->game->ensureLimit(e, lua_tonumber(L, 2), lua_tonumber(L, 3));
2704 	luaReturnNil();
2705 }
2706 
luaFunc(entity_setRidingPosition)2707 luaFunc(entity_setRidingPosition)
2708 {
2709 	Entity *e = entity(L);
2710 	if (e)
2711 		e->setRidingPosition(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)));
2712 	luaReturnNil();
2713 }
2714 
luaFunc(entity_setRidingData)2715 luaFunc(entity_setRidingData)
2716 {
2717 	Entity *e = entity(L);
2718 	if (e)
2719 		e->setRidingData(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), lua_tonumber(L, 4), getBool(L, 5));
2720 	luaReturnNil();
2721 }
2722 
luaFunc(entity_getRidingPosition)2723 luaFunc(entity_getRidingPosition)
2724 {
2725 	Entity *e = entity(L);
2726 	Vector v;
2727 	if (e)
2728 		v = e->getRidingPosition();
2729 	luaReturnVec2(v.x, v.y);
2730 }
2731 
luaFunc(entity_getRidingRotation)2732 luaFunc(entity_getRidingRotation)
2733 {
2734 	Entity *e = entity(L);
2735 	luaReturnNum(e ? e->getRidingRotation() : 0.0f);
2736 }
2737 
luaFunc(entity_getRidingFlip)2738 luaFunc(entity_getRidingFlip)
2739 {
2740 	Entity *e = entity(L);
2741 	luaReturnBool(e && e->getRidingFlip());
2742 }
2743 
2744 
luaFunc(entity_setBoneLock)2745 luaFunc(entity_setBoneLock)
2746 {
2747 	Entity *e = entity(L);
2748 	bool ret = false;
2749 	if (e)
2750 	{
2751 		BoneLock bl;
2752 		if (lua_isuserdata(L, 2))
2753 		{
2754 			Entity *e2 = entity(L, 2);
2755 			Bone *b = 0;
2756 			if (lua_isuserdata(L, 3))
2757 				b = bone(L, 3);
2758 
2759 			bl.entity = e2;
2760 			bl.bone = b;
2761 			bl.on = true;
2762 			bl.collisionMaskIndex = dsq->game->lastCollideMaskIndex;
2763 		}
2764 		ret = e->setBoneLock(bl);
2765 	}
2766 	luaReturnBool(ret);
2767 }
2768 
luaFunc(entity_setIngredient)2769 luaFunc(entity_setIngredient)
2770 {
2771 	Entity *e = entity(L);
2772 	if (e)
2773 	{
2774 		e->setIngredientData(getString(L,2));
2775 	}
2776 	luaReturnNil();
2777 }
2778 
luaFunc(entity_setSegsMaxDist)2779 luaFunc(entity_setSegsMaxDist)
2780 {
2781 	ScriptedEntity *se = scriptedEntity(L);
2782 	if (se)
2783 		se->setMaxDist(lua_tonumber(L, 2));
2784 
2785 	luaReturnNil();
2786 }
2787 
luaFunc(entity_setBounceType)2788 luaFunc(entity_setBounceType)
2789 {
2790 	Entity *e = entity(L);
2791 	int v = lua_tointeger(L, 2);
2792 	if (e)
2793 	{
2794 		e->setBounceType((BounceType)v);
2795 	}
2796 	luaReturnNum(v);
2797 }
2798 
2799 
luaFunc(user_set_demo_intro)2800 luaFunc(user_set_demo_intro)
2801 {
2802 #ifndef AQUARIA_DEMO
2803 	dsq->user.demo.intro = lua_tointeger(L, 1);
2804 #endif
2805 	luaReturnNil();
2806 }
2807 
luaFunc(user_save)2808 luaFunc(user_save)
2809 {
2810 	dsq->user.save();
2811 	luaReturnNil();
2812 }
2813 
luaFunc(entity_setAutoSkeletalUpdate)2814 luaFunc(entity_setAutoSkeletalUpdate)
2815 {
2816 	ScriptedEntity *e = scriptedEntity(L);
2817 	bool v = getBool(L, 2);
2818 	if (e)
2819 		e->setAutoSkeletalUpdate(v);
2820 	luaReturnBool(v);
2821 }
2822 
luaFunc(entity_getBounceType)2823 luaFunc(entity_getBounceType)
2824 {
2825 	Entity *e = entity(L);
2826 	BounceType bt=BOUNCE_SIMPLE;
2827 	if (e)
2828 	{
2829 		bt = (BounceType)e->getBounceType();
2830 	}
2831 	luaReturnInt((int)bt);
2832 }
2833 
luaFunc(entity_setDieTimer)2834 luaFunc(entity_setDieTimer)
2835 {
2836 	Entity *e = entity(L);
2837 	if (e)
2838 	{
2839 		e->setDieTimer(lua_tonumber(L, 2));
2840 	}
2841 	luaReturnNil();
2842 }
2843 
luaFunc(entity_setLookAtPoint)2844 luaFunc(entity_setLookAtPoint)
2845 {
2846 	Entity *e = entity(L);
2847 	if (e)
2848 	{
2849 		e->lookAtPoint = Vector(lua_tonumber(L, 2), lua_tonumber(L, 3));
2850 	}
2851 	luaReturnNil();
2852 }
2853 
luaFunc(entity_getLookAtPoint)2854 luaFunc(entity_getLookAtPoint)
2855 {
2856 	Entity *e = entity(L);
2857 	Vector pos;
2858 	if (e)
2859 	{
2860 		pos = e->getLookAtPoint();
2861 	}
2862 	luaReturnVec2(pos.x, pos.y);
2863 }
2864 
luaFunc(entity_setRiding)2865 luaFunc(entity_setRiding)
2866 {
2867 	Entity *e = entity(L);
2868 	Entity *e2 = 0;
2869 	if (lua_touserdata(L, 2) != NULL)
2870 		e2 = entity(L, 2);
2871 	if (e)
2872 	{
2873 		e->setRiding(e2);
2874 	}
2875 	luaReturnNil();
2876 }
2877 
luaFunc(entity_getHealthPerc)2878 luaFunc(entity_getHealthPerc)
2879 {
2880 	Entity *e = entity(L);
2881 	float p = 0;
2882 	if (e)
2883 	{
2884 		p = e->getHealthPerc();
2885 	}
2886 	luaReturnNum(p);
2887 }
2888 
luaFunc(entity_getRiding)2889 luaFunc(entity_getRiding)
2890 {
2891 	Entity *e = entity(L);
2892 	Entity *ret = 0;
2893 	if (e)
2894 		ret = e->getRiding();
2895 	luaReturnPtr(ret);
2896 }
2897 
luaFunc(entity_setTargetPriority)2898 luaFunc(entity_setTargetPriority)
2899 {
2900 	Entity *e = entity(L);
2901 	if (e)
2902 	{
2903 		e->targetPriority = lua_tonumber(L, 2);
2904 	}
2905 	luaReturnNil();
2906 }
2907 
luaFunc(entity_getTargetPriority)2908 luaFunc(entity_getTargetPriority)
2909 {
2910 	Entity *e = entity(L);
2911 	luaReturnInt(e ? e->targetPriority : 0);
2912 }
2913 
luaFunc(isQuitFlag)2914 luaFunc(isQuitFlag)
2915 {
2916 	luaReturnBool(dsq->isQuitFlag());
2917 }
2918 
luaFunc(isDeveloperKeys)2919 luaFunc(isDeveloperKeys)
2920 {
2921 	luaReturnBool(dsq->isDeveloperKeys());
2922 }
2923 
luaFunc(isDemo)2924 luaFunc(isDemo)
2925 {
2926 #ifdef AQUARIA_DEMO
2927 	luaReturnBool(true);
2928 #else
2929 	luaReturnBool(false);
2930 #endif
2931 }
2932 
luaFunc(isWithin)2933 luaFunc(isWithin)
2934 {
2935 	Vector v1 = getVector(L, 1);
2936 	Vector v2 = getVector(L, 3);
2937 	float dist = lua_tonumber(L, 5);
2938 	/*
2939 	std::ostringstream os;
2940 	os << "v1(" << v1.x << ", " << v1.y << ") v2(" << v2.x << ", " << v2.y << ")";
2941 	debugLog(os.str());
2942 	*/
2943 	Vector d = v2-v1;
2944 	bool v = false;
2945 	if (d.isLength2DIn(dist))
2946 	{
2947 		v = true;
2948 	}
2949 	luaReturnBool(v);
2950 }
2951 
luaFunc(toggleDamageSprite)2952 luaFunc(toggleDamageSprite)
2953 {
2954 	dsq->game->toggleDamageSprite(getBool(L));
2955 	luaReturnNil();
2956 }
2957 
luaFunc(toggleCursor)2958 luaFunc(toggleCursor)
2959 {
2960 	dsq->toggleCursor(getBool(L, 1), lua_tonumber(L, 2));
2961 	luaReturnNil();
2962 }
2963 
luaFunc(toggleBlackBars)2964 luaFunc(toggleBlackBars)
2965 {
2966 	dsq->toggleBlackBars(getBool(L, 1));
2967 	luaReturnNil();
2968 }
2969 
luaFunc(setBlackBarsColor)2970 luaFunc(setBlackBarsColor)
2971 {
2972 	Vector c(lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3));
2973 	dsq->setBlackBarsColor(c);
2974 	luaReturnNil();
2975 }
2976 
luaFunc(toggleLiCombat)2977 luaFunc(toggleLiCombat)
2978 {
2979 	dsq->continuity.toggleLiCombat(getBool(L));
2980 	luaReturnNil();
2981 }
2982 
luaFunc(getNoteName)2983 luaFunc(getNoteName)
2984 {
2985 	luaReturnStr(dsq->game->getNoteName(lua_tonumber(L, 1), getString(L, 2)).c_str());
2986 }
2987 
luaFunc(getWorldType)2988 luaFunc(getWorldType)
2989 {
2990 	luaReturnNum((int)dsq->continuity.getWorldType());
2991 }
2992 
luaFunc(setWorldType)2993 luaFunc(setWorldType)
2994 {
2995 	WorldType wt = (WorldType)lua_tointeger(L, 1);
2996 	bool trans = getBool(L, 2);
2997 	dsq->continuity.applyWorldEffects(wt, trans, 1); // last arg is not used
2998 	luaReturnNil();
2999 }
3000 
luaFunc(isWorldPaused)3001 luaFunc(isWorldPaused)
3002 {
3003 	luaReturnBool(dsq->game->isWorldPaused());
3004 }
3005 
luaFunc(setWorldPaused)3006 luaFunc(setWorldPaused)
3007 {
3008 	dsq->game->setWorldPaused(getBool(L, 1));
3009 	luaReturnNil();
3010 }
3011 
luaFunc(getNearestNodeByType)3012 luaFunc(getNearestNodeByType)
3013 {
3014 	float x = lua_tonumber(L, 1);
3015 	float y = lua_tonumber(L, 2);
3016 	int type = lua_tointeger(L, 3);
3017 
3018 	luaReturnPtr(dsq->game->getNearestPath(Vector(x,y), (PathType)type));
3019 }
3020 
luaFunc(fadeOutMusic)3021 luaFunc(fadeOutMusic)
3022 {
3023 	dsq->sound->fadeMusic(SFT_OUT, lua_tonumber(L, 1));
3024 	luaReturnNil();
3025 }
3026 
luaFunc(getNode)3027 luaFunc(getNode)
3028 {
3029 	luaReturnPtr(pathFromName(L));
3030 }
3031 
luaFunc(getNodeToActivate)3032 luaFunc(getNodeToActivate)
3033 {
3034 	luaReturnPtr(dsq->game->avatar->pathToActivate);
3035 }
3036 
luaFunc(setNodeToActivate)3037 luaFunc(setNodeToActivate)
3038 {
3039 	dsq->game->avatar->pathToActivate = path(L, 1);
3040 	luaReturnNil();
3041 }
3042 
luaFunc(getEntityToActivate)3043 luaFunc(getEntityToActivate)
3044 {
3045 	luaReturnPtr(dsq->game->avatar->entityToActivate);
3046 }
3047 
luaFunc(setEntityToActivate)3048 luaFunc(setEntityToActivate)
3049 {
3050 	dsq->game->avatar->entityToActivate = entity(L, 1);
3051 	luaReturnNil();
3052 }
3053 
luaFunc(hasThingToActivate)3054 luaFunc(hasThingToActivate)
3055 {
3056 	luaReturnBool(dsq->game->avatar->hasThingToActivate());
3057 }
3058 
luaFunc(setActivation)3059 luaFunc(setActivation)
3060 {
3061 	dsq->game->activation = getBool(L, 1);
3062 	luaReturnNil();
3063 }
3064 
luaFunc(debugLog)3065 luaFunc(debugLog)
3066 {
3067 	const char *s = lua_tostring(L, 1);
3068 	if(s)
3069 		debugLog(s);
3070 	luaReturnStr(s);
3071 }
3072 
luaFunc(errorLog)3073 luaFunc(errorLog)
3074 {
3075 	const char *s = lua_tostring(L, 1);
3076 	if(s)
3077 		errorLog(s);
3078 	luaReturnStr(s);
3079 }
3080 
luaFunc(reconstructGrid)3081 luaFunc(reconstructGrid)
3082 {
3083 	dsq->game->reconstructGrid(true);
3084 	luaReturnNil();
3085 }
3086 
luaFunc(reconstructEntityGrid)3087 luaFunc(reconstructEntityGrid)
3088 {
3089 	dsq->game->reconstructEntityGrid();
3090 	luaReturnNil();
3091 }
3092 
luaFunc(dilateGrid)3093 luaFunc(dilateGrid)
3094 {
3095 	unsigned int radius = lua_tointeger(L, 1);
3096 	ObsType test = (ObsType)lua_tointeger(L, 2);
3097 	ObsType set = (ObsType)lua_tointeger(L, 3);
3098 	ObsType allowOverwrite = (ObsType)lua_tointeger(L, 4);
3099 	dsq->game->dilateGrid(radius, test, set, allowOverwrite);
3100 	luaReturnNil();
3101 }
3102 
luaFunc(entity_setCanLeaveWater)3103 luaFunc(entity_setCanLeaveWater)
3104 {
3105 	Entity *e = entity(L);
3106 	bool v = getBool(L, 2);
3107 	if (e)
3108 	{
3109 		e->setCanLeaveWater(v);
3110 	}
3111 	luaReturnNil();
3112 }
3113 
luaFunc(entity_setSegmentTexture)3114 luaFunc(entity_setSegmentTexture)
3115 {
3116 	ScriptedEntity *e = scriptedEntity(L);
3117 	if (e)
3118 	{
3119 		RenderObject *ro = e->getSegment(lua_tonumber(L, 2));
3120 		if (ro)
3121 		{
3122 			ro->setTexture(getString(L, 3));
3123 		}
3124 	}
3125 	luaReturnNil();
3126 }
3127 
luaFunc(entity_findNearestEntityOfType)3128 luaFunc(entity_findNearestEntityOfType)
3129 {
3130 	Entity *e = entity(L);
3131 	Entity *nearest = 0;
3132 	if (e)
3133 	{
3134 		EntityType et = (EntityType)lua_tointeger(L, 2);
3135 		int maxRange = lua_tointeger(L, 3);
3136 		float smallestDist = HUGE_VALF;
3137 		Entity *closest = 0;
3138 		FOR_ENTITIES(i)
3139 		{
3140 			Entity *ee = *i;
3141 			if (ee != e)
3142 			{
3143 				float dist = (ee->position - e->position).getSquaredLength2D();
3144 				if (ee->health > 0 && !ee->isEntityDead() && ee->getEntityType() == et && dist < smallestDist)
3145 				{
3146 					smallestDist = dist;
3147 					closest = ee;
3148 				}
3149 			}
3150 		}
3151 		if (maxRange == 0 || smallestDist <= sqr(maxRange))
3152 		{
3153 			nearest = closest;
3154 		}
3155 	}
3156 	luaReturnPtr(nearest);
3157 }
3158 
luaFunc(createShot)3159 luaFunc(createShot)
3160 {
3161 	Entity *e = entity(L,2);
3162 	Entity *t = 0;
3163 	if (lua_touserdata(L, 3) != NULL)
3164 		t = entity(L,3);
3165 	Shot *s = 0;
3166 	Vector pos, aim;
3167 	pos.x = lua_tonumber(L, 4);
3168 	pos.y = lua_tonumber(L, 5);
3169 	aim.x = lua_tonumber(L, 6);
3170 	aim.y = lua_tonumber(L, 7);
3171 
3172 
3173 	s = dsq->game->fireShot(getString(L, 1), e, t, pos, aim);
3174 
3175 	luaReturnPtr(s);
3176 }
3177 
luaFunc(isSkippingCutscene)3178 luaFunc(isSkippingCutscene)
3179 {
3180 	luaReturnBool(dsq->isSkippingCutscene());
3181 }
3182 
3183 // deprecated, use entity_playSfx
luaFunc(entity_sound)3184 luaFunc(entity_sound)
3185 {
3186 	Entity *e = entity(L);
3187 	if (e && !dsq->isSkippingCutscene())
3188 	{
3189 		float freq = lua_tonumber(L, 3);
3190 		// HACK: most old scripts still use a freq value of ~1000 as normal pitch.
3191 		// Pitch values this high produce a barely audible click only,
3192 		// so a cheap hack like this fixes it without changing older scripts. -- FG
3193 		if (freq >= 100)
3194 			freq *= 0.001f;
3195 		e->sound(getString(L, 2), freq, lua_tonumber(L, 4));
3196 	}
3197 	luaReturnNil();
3198 }
3199 
luaFunc(entity_playSfx)3200 luaFunc(entity_playSfx)
3201 {
3202 	Entity *e = entity(L);
3203 	void *h = NULL;
3204 	if (e && !dsq->isSkippingCutscene())
3205 	{
3206 		PlaySfx sfx;
3207 		sfx.name = getString(L, 2);
3208 		sfx.freq = lua_tonumber(L, 3);
3209 		sfx.vol = lua_tonumber(L, 4);
3210 		if(sfx.vol <= 0)
3211 			sfx.vol = 1;
3212 		sfx.loops = lua_tonumber(L, 5);
3213 
3214 		float fadeOut = lua_tonumber(L, 6);
3215 		sfx.maxdist = lua_tonumber(L, 7);
3216 		sfx.relative = false;
3217 		sfx.positional = true;
3218 		Vector pos = e->position + e->offset;
3219 		sfx.x = pos.x;
3220 		sfx.y = pos.y;
3221 
3222 		h = core->sound->playSfx(sfx);
3223 		if (fadeOut != 0)
3224 		{
3225 			sound->fadeSfx(h, SFT_OUT, fadeOut);
3226 		}
3227 
3228 		e->linkSound(h);
3229 		e->updateSoundPosition();
3230 	}
3231 	luaReturnPtr(h);
3232 }
3233 
luaFunc(entity_setStopSoundsOnDeath)3234 luaFunc(entity_setStopSoundsOnDeath)
3235 {
3236 	Entity *e = entity(L);
3237 	if (e)
3238 		e->setStopSoundsOnDeath(getBool(L, 2));
3239 	luaReturnNil();
3240 }
3241 
luaFunc(entity_setSpiritFreeze)3242 luaFunc(entity_setSpiritFreeze)
3243 {
3244 	Entity *e = entity(L);
3245 	if (e)
3246 	{
3247 		e->setSpiritFreeze(getBool(L,2));
3248 	}
3249 	luaReturnNil();
3250 }
3251 
luaFunc(entity_setPauseFreeze)3252 luaFunc(entity_setPauseFreeze)
3253 {
3254 	Entity *e = entity(L);
3255 	if (e)
3256 	{
3257 		e->setPauseFreeze(getBool(L,2));
3258 	}
3259 	luaReturnNil();
3260 }
3261 
luaFunc(node_setSpiritFreeze)3262 luaFunc(node_setSpiritFreeze)
3263 {
3264 	Path *e = path(L);
3265 	if (e)
3266 		e->spiritFreeze = getBool(L,2);
3267 	luaReturnNil();
3268 }
3269 
luaFunc(node_setPauseFreeze)3270 luaFunc(node_setPauseFreeze)
3271 {
3272 	Path *e = path(L);
3273 	if (e)
3274 		e->pauseFreeze = getBool(L,2);
3275 	luaReturnNil();
3276 }
3277 
luaFunc(entity_setFillGrid)3278 luaFunc(entity_setFillGrid)
3279 {
3280 	Entity *e = entity(L);
3281 	bool b = getBool(L,2);
3282 	if (e)
3283 	{
3284 		e->fillGridFromQuad = b;
3285 	}
3286 	luaReturnNil();
3287 }
3288 
luaFunc(entity_isFillGrid)3289 luaFunc(entity_isFillGrid)
3290 {
3291 	Entity *e = entity(L);
3292 	luaReturnBool(e ? e->fillGridFromQuad : false);
3293 }
3294 
luaFunc(entity_getAimVector)3295 luaFunc(entity_getAimVector)
3296 {
3297 	Entity *e = entity(L);
3298 	Vector aim;
3299 	float adjust = lua_tonumber(L, 2);
3300 	float len = lua_tonumber(L, 3);
3301 	bool flip = getBool(L, 4);
3302 	if (e)
3303 	{
3304 		float a = e->rotation.z;
3305 		if (!flip)
3306 			a += adjust;
3307 		else
3308 		{
3309 			if (e->isfh())
3310 			{
3311 				a -= adjust;
3312 			}
3313 			else
3314 			{
3315 				a += adjust;
3316 			}
3317 		}
3318 		a = MathFunctions::toRadians(a);
3319 		aim = Vector(sinf(a)*len, cosf(a)*len);
3320 	}
3321 	luaReturnVec2(aim.x, aim.y);
3322 }
3323 
luaFunc(entity_getVectorToEntity)3324 luaFunc(entity_getVectorToEntity)
3325 {
3326 	typecheckOnly(entity(L));
3327 	typecheckOnly(entity(L, 2));
3328 	return forwardCall(obj_getVectorToObj);
3329 }
3330 
luaFunc(entity_setDropChance)3331 luaFunc(entity_setDropChance)
3332 {
3333 	Entity *e = entity(L);
3334 	if (e)
3335 	{
3336 		e->dropChance = lua_tonumber(L, 2);
3337 		float amount = lua_tonumber(L, 3);
3338 		ScriptedEntity *se = dynamic_cast<ScriptedEntity*>(e);
3339 		if (se && amount)
3340 		{
3341 			se->manaBallAmount = amount;
3342 		}
3343 	}
3344 	luaReturnNil();
3345 }
3346 
luaFunc(entity_warpToNode)3347 luaFunc(entity_warpToNode)
3348 {
3349 	Entity *e = entity(L);
3350 	Path *p = path(L, 2);
3351 	if (e && p)
3352 	{
3353 		e->position.stopPath();
3354 		e->position = p->nodes[0].position;
3355 		e->rotateToVec(Vector(0,-1), 0.1);
3356 	}
3357 	luaReturnNil();
3358 }
3359 
luaFunc(entity_stopPull)3360 luaFunc(entity_stopPull)
3361 {
3362 	Entity *e = entity(L);
3363 	if (e)
3364 		e->stopPull();
3365 	luaReturnNil();
3366 }
3367 
luaFunc(entity_moveToNode)3368 luaFunc(entity_moveToNode)
3369 {
3370 	Entity *e = entity(L);
3371 	Path *p = path(L, 2);
3372 	float time = 0;
3373 	if (e && p)
3374 	{
3375 		float speed = dsq->continuity.getSpeedType(lua_tointeger(L, 3));
3376 		time = e->moveToPos(p->nodes[0].position, speed, lua_tointeger(L, 4), 0);
3377 	}
3378 	luaReturnNum(time);
3379 }
3380 
luaFunc(entity_swimToNode)3381 luaFunc(entity_swimToNode)
3382 {
3383 	Entity *e = entity(L);
3384 	Path *p = path(L, 2);
3385 	float time = 0;
3386 	if (e && p)
3387 	{
3388 		float speed = dsq->continuity.getSpeedType(lua_tointeger(L, 3));
3389 		time = e->moveToPos(p->nodes[0].position, speed, lua_tointeger(L, 4), 1);
3390 	}
3391 	luaReturnNum(time);
3392 }
3393 
luaFunc(entity_swimToPosition)3394 luaFunc(entity_swimToPosition)
3395 {
3396 	Entity *e = entity(L);
3397 	float time = 0;
3398 	if (e)
3399 	{
3400 		float speed = dsq->continuity.getSpeedType(lua_tointeger(L, 4));
3401 		time = e->moveToPos(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), speed, lua_tointeger(L, 5), 1);
3402 	}
3403 	luaReturnNum(time);
3404 }
3405 
luaFunc(entity_moveToNodeSpeed)3406 luaFunc(entity_moveToNodeSpeed)
3407 {
3408 	Entity *e = entity(L);
3409 	Path *p = path(L, 2);
3410 	float time = 0;
3411 	if (e && p)
3412 		time = e->moveToPos(p->nodes[0].position, lua_tonumber(L, 3), lua_tointeger(L, 4), 0);
3413 	luaReturnNum(time);
3414 }
3415 
luaFunc(entity_swimToNodeSpeed)3416 luaFunc(entity_swimToNodeSpeed)
3417 {
3418 	Entity *e = entity(L);
3419 	Path *p = path(L, 2);
3420 	float time = 0;
3421 	if (e && p)
3422 		time = e->moveToPos(p->nodes[0].position, lua_tonumber(L, 3), lua_tointeger(L, 4), 1);
3423 	luaReturnNum(time);
3424 }
3425 
luaFunc(entity_swimToPositionSpeed)3426 luaFunc(entity_swimToPositionSpeed)
3427 {
3428 	Entity *e = entity(L);
3429 	float time = 0;
3430 	if (e)
3431 		time = e->moveToPos(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), lua_tonumber(L, 4), lua_tointeger(L, 5), 1);
3432 	luaReturnNum(time);
3433 }
3434 
3435 
luaFunc(avatar_setCanDie)3436 luaFunc(avatar_setCanDie)
3437 {
3438 	dsq->game->avatar->canDie = getBool(L, 1);
3439 
3440 	luaReturnNil();
3441 }
3442 
3443 // not naming this avatar_* because it rather belongs into the UI category...
luaFunc(setCanActivate)3444 luaFunc(setCanActivate)
3445 {
3446 	dsq->game->avatar->setCanActivateStuff(getBool(L, 1));
3447 	luaReturnNil();
3448 }
3449 
luaFunc(setSeeMapMode)3450 luaFunc(setSeeMapMode)
3451 {
3452 	dsq->game->avatar->setSeeMapMode((SeeMapMode)lua_tointeger(L, 1));
3453 	luaReturnNil();
3454 }
3455 
luaFunc(avatar_setCanBurst)3456 luaFunc(avatar_setCanBurst)
3457 {
3458 	dsq->game->avatar->setCanBurst(getBool(L, 1));
3459 	luaReturnNil();
3460 }
3461 
luaFunc(avatar_canBurst)3462 luaFunc(avatar_canBurst)
3463 {
3464 	luaReturnBool(dsq->game->avatar->canBurst());
3465 }
3466 
luaFunc(avatar_setCanLockToWall)3467 luaFunc(avatar_setCanLockToWall)
3468 {
3469 	dsq->game->avatar->setCanLockToWall(getBool(L, 1));
3470 	luaReturnNil();
3471 }
3472 
luaFunc(avatar_canLockToWall)3473 luaFunc(avatar_canLockToWall)
3474 {
3475 	luaReturnBool(dsq->game->avatar->canLockToWall());
3476 }
3477 
luaFunc(avatar_setCanSwimAgainstCurrents)3478 luaFunc(avatar_setCanSwimAgainstCurrents)
3479 {
3480 	dsq->game->avatar->setCanSwimAgainstCurrents(getBool(L, 1));
3481 	luaReturnNil();
3482 }
3483 
luaFunc(avatar_canSwimAgainstCurrents)3484 luaFunc(avatar_canSwimAgainstCurrents)
3485 {
3486 	luaReturnBool(dsq->game->avatar->canSwimAgainstCurrents());
3487 }
3488 
luaFunc(avatar_setCanCollideWithShots)3489 luaFunc(avatar_setCanCollideWithShots)
3490 {
3491 	dsq->game->avatar->setCollideWithShots(getBool(L, 1));
3492 	luaReturnNil();
3493 }
3494 
luaFunc(avatar_canCollideWithShots)3495 luaFunc(avatar_canCollideWithShots)
3496 {
3497 	luaReturnBool(dsq->game->avatar->canCollideWithShots());
3498 }
3499 
luaFunc(avatar_setCollisionAvoidanceData)3500 luaFunc(avatar_setCollisionAvoidanceData)
3501 {
3502 	dsq->game->avatar->setCollisionAvoidanceData(lua_tointeger(L, 1), lua_tonumber(L, 2));
3503 	luaReturnNil();
3504 }
3505 
luaFunc(avatar_toggleCape)3506 luaFunc(avatar_toggleCape)
3507 {
3508 	dsq->game->avatar->toggleCape(getBool(L,1));
3509 
3510 	luaReturnNil();
3511 }
3512 
luaFunc(avatar_setBlockSinging)3513 luaFunc(avatar_setBlockSinging)
3514 {
3515 	bool b = getBool(L);
3516 	dsq->game->avatar->setBlockSinging(b);
3517 	luaReturnNil();
3518 }
3519 
luaFunc(avatar_isBlockSinging)3520 luaFunc(avatar_isBlockSinging)
3521 {
3522 	luaReturnBool(dsq->game->avatar->isBlockSinging());
3523 }
3524 
luaFunc(avatar_setBlockBackflip)3525 luaFunc(avatar_setBlockBackflip)
3526 {
3527 	dsq->game->avatar->blockBackFlip = getBool(L);
3528 	luaReturnNil();
3529 }
3530 
luaFunc(avatar_isBlockBackflip)3531 luaFunc(avatar_isBlockBackflip)
3532 {
3533 	dsq->game->avatar->blockBackFlip = getBool(L);
3534 	luaReturnNil();
3535 }
3536 
luaFunc(avatar_fallOffWall)3537 luaFunc(avatar_fallOffWall)
3538 {
3539 	dsq->game->avatar->fallOffWall();
3540 	luaReturnNil();
3541 }
3542 
luaFunc(avatar_isBursting)3543 luaFunc(avatar_isBursting)
3544 {
3545 	luaReturnBool(dsq->game->avatar->bursting);
3546 }
3547 
luaFunc(avatar_isLockable)3548 luaFunc(avatar_isLockable)
3549 {
3550 	luaReturnBool(dsq->game->avatar->isLockable());
3551 }
3552 
luaFunc(avatar_isRolling)3553 luaFunc(avatar_isRolling)
3554 {
3555 	luaReturnBool(dsq->game->avatar->isRolling());
3556 }
3557 
luaFunc(avatar_isSwimming)3558 luaFunc(avatar_isSwimming)
3559 {
3560 	luaReturnBool(dsq->game->avatar->isSwimming());
3561 }
3562 
luaFunc(avatar_isOnWall)3563 luaFunc(avatar_isOnWall)
3564 {
3565 	bool v = dsq->game->avatar->state.lockedToWall;
3566 	luaReturnBool(v);
3567 }
3568 
luaFunc(avatar_isShieldActive)3569 luaFunc(avatar_isShieldActive)
3570 {
3571 	bool v = (dsq->game->avatar->activeAura == AURA_SHIELD);
3572 	luaReturnBool(v);
3573 }
3574 
luaFunc(avatar_setShieldActive)3575 luaFunc(avatar_setShieldActive)
3576 {
3577 	bool on = getBool(L, 1);
3578 	if (on)
3579 		dsq->game->avatar->activateAura(AURA_SHIELD);
3580 	else
3581 		dsq->game->avatar->stopAura();
3582 	luaReturnNil();
3583 }
3584 
luaFunc(avatar_getStillTimer)3585 luaFunc(avatar_getStillTimer)
3586 {
3587 	luaReturnNum(dsq->game->avatar->stillTimer.getValue());
3588 }
3589 
luaFunc(avatar_getRollDirection)3590 luaFunc(avatar_getRollDirection)
3591 {
3592 	int v = 0;
3593 	if (dsq->game->avatar->isRolling())
3594 		v = dsq->game->avatar->rollDir;
3595 	luaReturnNum(v);
3596 }
3597 
luaFunc(avatar_getSpellCharge)3598 luaFunc(avatar_getSpellCharge)
3599 {
3600 	luaReturnNum(dsq->game->avatar->state.spellCharge);
3601 }
3602 
luaFunc(avatar_setSpeedMult)3603 luaFunc(avatar_setSpeedMult)
3604 {
3605 	dsq->continuity.setSpeedMultiplier(lua_tonumber(L, 1), lua_tonumber(L, 2));
3606 	luaReturnNil();
3607 }
3608 
luaFunc(avatar_setSpeedMult2)3609 luaFunc(avatar_setSpeedMult2)
3610 {
3611 	dsq->continuity.speedMult2 = lua_tonumber(L, 1);
3612 	luaReturnNil();
3613 }
3614 
luaFunc(avatar_getSpeedMult)3615 luaFunc(avatar_getSpeedMult)
3616 {
3617 	luaReturnNum(dsq->continuity.speedMult);
3618 }
3619 
luaFunc(avatar_getSpeedMult2)3620 luaFunc(avatar_getSpeedMult2)
3621 {
3622 	luaReturnNum(dsq->continuity.speedMult2);
3623 }
3624 
luaFunc(jumpState)3625 luaFunc(jumpState)
3626 {
3627 	dsq->enqueueJumpState(getString(L, 1), getBool(L, 2));
3628 	luaReturnNil();
3629 }
3630 
luaFunc(goToTitle)3631 luaFunc(goToTitle)
3632 {
3633 	dsq->title();
3634 	luaReturnNil();
3635 }
3636 
luaFunc(getEnqueuedState)3637 luaFunc(getEnqueuedState)
3638 {
3639 	luaReturnStr(dsq->getEnqueuedJumpState().c_str());
3640 }
3641 
luaFunc(learnSong)3642 luaFunc(learnSong)
3643 {
3644 	dsq->continuity.learnSong(lua_tointeger(L, 1));
3645 	luaReturnNil();
3646 }
3647 
luaFunc(unlearnSong)3648 luaFunc(unlearnSong)
3649 {
3650 	dsq->continuity.unlearnSong(lua_tointeger(L, 1));
3651 	luaReturnNil();
3652 }
3653 
luaFunc(showInGameMenu)3654 luaFunc(showInGameMenu)
3655 {
3656 	dsq->game->showInGameMenu(getBool(L, 1), getBool(L, 2), (MenuPage)lua_tointeger(L, 3));
3657 	luaReturnNil();
3658 }
3659 
luaFunc(hideInGameMenu)3660 luaFunc(hideInGameMenu)
3661 {
3662 	bool skipEffect = getBool(L, 1);
3663 	bool cancel = getBool(L, 2);
3664 	dsq->game->hideInGameMenu(!skipEffect, cancel);
3665 	luaReturnNil();
3666 }
3667 
luaFunc(showImage)3668 luaFunc(showImage)
3669 {
3670 	dsq->game->showImage(getString(L));
3671 	luaReturnNil();
3672 }
3673 
luaFunc(hideImage)3674 luaFunc(hideImage)
3675 {
3676 	dsq->game->hideImage();
3677 	luaReturnNil();
3678 }
3679 
luaFunc(hasSong)3680 luaFunc(hasSong)
3681 {
3682 	bool b = dsq->continuity.hasSong(lua_tointeger(L, 1));
3683 	luaReturnBool(b);
3684 }
3685 
luaFunc(loadSound)3686 luaFunc(loadSound)
3687 {
3688 	void *handle = core->sound->loadLocalSound(getString(L, 1));
3689 	luaReturnPtr(handle);
3690 }
3691 
luaFunc(loadMap)3692 luaFunc(loadMap)
3693 {
3694 	std::string s = getString(L, 1);
3695 	std::string n = getString(L, 2);
3696 
3697 	if (!s.empty())
3698 	{
3699 		if (!n.empty())
3700 		{
3701 			if (dsq->game->avatar)
3702 				dsq->game->avatar->disableInput();
3703 			dsq->game->warpToSceneNode(s, n);
3704 		}
3705 		else
3706 		{
3707 			if (dsq->game->avatar)
3708 				dsq->game->avatar->disableInput();
3709 			dsq->game->transitionToScene(s);
3710 		}
3711 	}
3712 	luaReturnNil();
3713 }
3714 
luaFunc(entity_followPath)3715 luaFunc(entity_followPath)
3716 {
3717 	Entity *e = entity(L);
3718 	float time = 0;
3719 	if (e)
3720 	{
3721 		Path *p = path(L, 2);
3722 		int speedType = lua_tointeger(L, 3);
3723 		int dir = lua_tointeger(L, 4);
3724 		float speed = dsq->continuity.getSpeedType(speedType);
3725 		time = e->followPath(p, speed, dir);
3726 	}
3727 	luaReturnNum(time);
3728 }
3729 
luaFunc(entity_followPathSpeed)3730 luaFunc(entity_followPathSpeed)
3731 {
3732 	Entity *e = entity(L);
3733 	float time = 0;
3734 	if (e)
3735 	{
3736 		Path *p = path(L, 2);
3737 		float speed = lua_tonumber(L, 3);
3738 		int dir = lua_tointeger(L, 4);
3739 		time = e->followPath(p, speed, dir);
3740 	}
3741 	luaReturnNum(time);
3742 }
3743 
luaFunc(spawnIngredient)3744 luaFunc(spawnIngredient)
3745 {
3746 	int times = lua_tointeger(L, 4);
3747 	if (times == 0) times = 1;
3748 	bool out = getBool(L, 5);
3749 	Entity *e = dsq->game->spawnIngredient(getString(L, 1), Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), times, out);
3750 
3751 	luaReturnPtr(e);
3752 }
3753 
luaFunc(getNearestIngredient)3754 luaFunc(getNearestIngredient)
3755 {
3756 	Ingredient *i = dsq->game->getNearestIngredient(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)), lua_tonumber(L, 3));
3757 	luaReturnPtr(i);
3758 }
3759 
luaFunc(spawnAllIngredients)3760 luaFunc(spawnAllIngredients)
3761 {
3762 	dsq->spawnAllIngredients(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)));
3763 	luaReturnNil();
3764 }
3765 
luaFunc(spawnParticleEffect)3766 luaFunc(spawnParticleEffect)
3767 {
3768 	float t = lua_tonumber(L, 4);
3769 	// having t and rot reversed compared to the DSQ function is intentional
3770 	float rot = lua_tonumber(L, 5);
3771 	int layer = lua_tointeger(L, 6);
3772 	if (!layer)
3773 		layer = LR_PARTICLES;
3774 	float follow = lua_tonumber(L, 7);
3775 	ParticleEffect *pe = dsq->spawnParticleEffect(getString(L, 1), Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)),
3776 		rot, t, layer, follow);
3777 	luaReturnPtr(pe);
3778 }
3779 
luaFunc(setNumSuckPositions)3780 luaFunc(setNumSuckPositions)
3781 {
3782 	particleManager->setNumSuckPositions(lua_tointeger(L, 1));
3783 	luaReturnNil();
3784 }
3785 
luaFunc(setSuckPosition)3786 luaFunc(setSuckPosition)
3787 {
3788 	particleManager->setSuckPosition(lua_tointeger(L, 1), Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)));
3789 	luaReturnNil();
3790 }
3791 
luaFunc(getSuckPosition)3792 luaFunc(getSuckPosition)
3793 {
3794 	Vector *v = particleManager->getSuckPosition(lua_tointeger(L, 1));
3795 	if(v)
3796 		luaReturnVec2(v->x, v->y);
3797 	luaReturnVec2(0.0f, 0.0f);
3798 }
3799 
3800 
luaFunc(bone_showFrame)3801 luaFunc(bone_showFrame)
3802 {
3803 	Bone *b = bone(L);
3804 	if (b)
3805 		b->showFrame(lua_tointeger(L, 2));
3806 	luaReturnNil();
3807 }
3808 
luaFunc(bone_setSegmentOffset)3809 luaFunc(bone_setSegmentOffset)
3810 {
3811 	Bone *b = bone(L);
3812 	if (b)
3813 		b->segmentOffset = Vector(lua_tonumber(L, 2), lua_tonumber(L, 3));
3814 	luaReturnNil();
3815 }
3816 
luaFunc(bone_setSegmentProps)3817 luaFunc(bone_setSegmentProps)
3818 {
3819 	Bone *b = bone(L);
3820 	if (b)
3821 	{
3822 		b->setSegmentProps(lua_tonumber(L, 2), lua_tonumber(L, 3), getBool(L, 4));
3823 	}
3824 	luaReturnNil();
3825 }
3826 
luaFunc(bone_setSegmentChainHead)3827 luaFunc(bone_setSegmentChainHead)
3828 {
3829 	Bone *b = bone(L);
3830 	if (b)
3831 	{
3832 		if (getBool(L, 2))
3833 			b->segmentChain = 1;
3834 		else
3835 			b->segmentChain = 0;
3836 	}
3837 	luaReturnNil();
3838 }
3839 
luaFunc(bone_addSegment)3840 luaFunc(bone_addSegment)
3841 {
3842 	Bone *b = bone(L);
3843 	Bone *b2 = bone(L, 2);
3844 	if (b && b2)
3845 		b->addSegment(b2);
3846 	luaReturnNil();
3847 }
3848 
luaFunc(bone_setAnimated)3849 luaFunc(bone_setAnimated)
3850 {
3851 	Bone *b = bone(L);
3852 	if (b)
3853 	{
3854 		b->setAnimated(lua_tointeger(L, 2));
3855 	}
3856 	luaReturnNil();
3857 }
3858 
luaFunc(bone_lookAtEntity)3859 luaFunc(bone_lookAtEntity)
3860 {
3861 	Bone *b = bone(L);
3862 	Entity *e = entity(L, 2);
3863 	if (b && e)
3864 	{
3865 		Vector pos = e->position;
3866 		if (e->getEntityType() == ET_AVATAR)
3867 		{
3868 			pos = e->skeletalSprite.getBoneByIdx(1)->getWorldPosition();
3869 		}
3870 		b->lookAt(pos, lua_tonumber(L, 3), lua_tonumber(L, 4),lua_tonumber(L, 5), lua_tonumber(L, 6));
3871 	}
3872 	luaReturnNil();
3873 }
3874 
luaFunc(bone_lookAtPosition)3875 luaFunc(bone_lookAtPosition)
3876 {
3877 	Bone *b = bone(L);
3878 	if (b)
3879 	{
3880 		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));
3881 	}
3882 	luaReturnNil();
3883 }
3884 
luaFunc(entity_resetTimer)3885 luaFunc(entity_resetTimer)
3886 {
3887 	ScriptedEntity *se = scriptedEntity(L);
3888 	if (se)
3889 		se->resetTimer(lua_tonumber(L, 2));
3890 	luaReturnNil();
3891 }
3892 
luaFunc(entity_stopFollowingPath)3893 luaFunc(entity_stopFollowingPath)
3894 {
3895 	Entity *e = entity(L);
3896 	if (e)
3897 	{
3898 		if (e->isFollowingPath())
3899 		{
3900 			e->stopFollowingPath();
3901 		}
3902 	}
3903 	luaReturnNil();
3904 }
3905 
luaFunc(entity_slowToStopPath)3906 luaFunc(entity_slowToStopPath)
3907 {
3908 	Entity *e = entity(L);
3909 	if (e)
3910 	{
3911 		if (e->isFollowingPath())
3912 		{
3913 			debugLog("calling slow to stop path");
3914 			e->slowToStopPath(lua_tonumber(L, 2));
3915 		}
3916 		else
3917 		{
3918 			debugLog("wasn't following path");
3919 		}
3920 	}
3921 	luaReturnNil();
3922 }
3923 
luaFunc(entity_stopTimer)3924 luaFunc(entity_stopTimer)
3925 {
3926 	ScriptedEntity *se = scriptedEntity(L);
3927 	if (se)
3928 		se->stopTimer();
3929 	luaReturnNil();
3930 }
3931 
luaFunc(entity_createEntity)3932 luaFunc(entity_createEntity)
3933 {
3934 	Entity *e = entity(L);
3935 	Entity *ret = NULL;
3936 	if (e)
3937 		ret = dsq->game->createEntity(dsq->getEntityTypeIndexByName(getString(L, 2)), 0, e->position, 0, false, "", ET_ENEMY, true);
3938 	luaReturnPtr(ret);
3939 }
3940 
luaFunc(entity_checkSplash)3941 luaFunc(entity_checkSplash)
3942 {
3943 	Entity *e = entity(L);
3944 	bool ret = false;
3945 	float x = lua_tonumber(L, 2);
3946 	float y = lua_tonumber(L, 3);
3947 	if (e)
3948 		ret = e->checkSplash(Vector(x,y));
3949 	luaReturnBool(ret);
3950 }
3951 
luaFunc(entity_isInCurrent)3952 luaFunc(entity_isInCurrent)
3953 {
3954 	Entity *e = entity(L);
3955 	luaReturnBool(e ? e->isInCurrent() : false);
3956 }
3957 
luaFunc(entity_isUnderWater)3958 luaFunc(entity_isUnderWater)
3959 {
3960 	Entity *e = entity(L);
3961 	bool b = false;
3962 	if (e)
3963 	{
3964 		b = e->isUnderWater(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)));
3965 	}
3966 	luaReturnBool(b);
3967 }
3968 
luaFunc(entity_isBeingPulled)3969 luaFunc(entity_isBeingPulled)
3970 {
3971 	Entity *e = entity(L);
3972 	bool v= false;
3973 	if (e)
3974 		v = (dsq->game->avatar->pullTarget == e);
3975 	luaReturnBool(v);
3976 }
3977 
luaFunc(avatar_setPullTarget)3978 luaFunc(avatar_setPullTarget)
3979 {
3980 	Entity *e = 0;
3981 	if (lua_isuserdata(L, 1))
3982 		e = entity(L, 1);
3983 
3984 	if (dsq->game->avatar->pullTarget != 0)
3985 		dsq->game->avatar->pullTarget->stopPull();
3986 
3987 	dsq->game->avatar->pullTarget = e;
3988 
3989 	if (e)
3990 		e->startPull();
3991 
3992 	luaReturnNil();
3993 }
3994 
luaFunc(entity_isDead)3995 luaFunc(entity_isDead)
3996 {
3997 	Entity *e = entity(L);
3998 	bool v= false;
3999 	if (e)
4000 	{
4001 		v = e->isEntityDead();
4002 	}
4003 	luaReturnBool(v);
4004 }
4005 
4006 
luaFunc(getLastCollidePosition)4007 luaFunc(getLastCollidePosition)
4008 {
4009 	luaReturnVec2(dsq->game->lastCollidePosition.x, dsq->game->lastCollidePosition.y);
4010 }
4011 
luaFunc(getLastCollideTileType)4012 luaFunc(getLastCollideTileType)
4013 {
4014 	luaReturnInt(dsq->game->lastCollideTileType);
4015 }
4016 
luaFunc(collideCircleWithGrid)4017 luaFunc(collideCircleWithGrid)
4018 {
4019 	bool c = dsq->game->collideCircleWithGrid(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)), lua_tonumber(L, 3));
4020 	luaReturnBool(c);
4021 }
4022 
4023 
luaFunc(entity_isNearGround)4024 luaFunc(entity_isNearGround)
4025 {
4026 	Entity *e = entity(L);
4027 	bool value = false;
4028 	if (e)
4029 	{
4030 		int sampleArea = lua_tointeger(L, 2);
4031 		Vector v = dsq->game->getWallNormal(e->position, sampleArea);
4032 		if (!v.isZero())
4033 		{
4034 			//if (v.y < -0.5f && fabsf(v.x) < 0.4f)
4035 			if (v.y < 0 && fabsf(v.x) < 0.6f)
4036 			{
4037 				value = true;
4038 			}
4039 		}
4040 		/*
4041 		Vector v = e->position + Vector(0,e->collideRadius + TILE_SIZE/2);
4042 		std::ostringstream os;
4043 		os << "checking (" << v.x << ", " << v.y << ")";
4044 		debugLog(os.str());
4045 		TileVector t(v);
4046 		TileVector c;
4047 		for (int i = -5; i < 5; i++)
4048 		{
4049 			c.x = t.x+i;
4050 			c.y = t.y;
4051 			if (dsq->game->isObstructed(t))
4052 			{
4053 				value = true;
4054 			}
4055 		}
4056 		*/
4057 	}
4058 	luaReturnBool(value);
4059 }
4060 
luaFunc(entity_isHit)4061 luaFunc(entity_isHit)
4062 {
4063 	Entity *e = entity(L);
4064 	bool v = false;
4065 	if (e)
4066 		v = e->isHit();
4067 	luaReturnBool(v);
4068 }
4069 
luaFunc(entity_waitForPath)4070 luaFunc(entity_waitForPath)
4071 {
4072 	Entity *e = entity(L);
4073 	while (e && e->isFollowingPath())
4074 	{
4075 		core->main(FRAME_TIME);
4076 	}
4077 	luaReturnNil();
4078 }
4079 
luaFunc(quitNestedMain)4080 luaFunc(quitNestedMain)
4081 {
4082 	core->quitNestedMain();
4083 	luaReturnNil();
4084 }
4085 
luaFunc(isNestedMain)4086 luaFunc(isNestedMain)
4087 {
4088 	luaReturnBool(core->isNested());
4089 }
4090 
luaFunc(entity_watchForPath)4091 luaFunc(entity_watchForPath)
4092 {
4093 	dsq->game->avatar->disableInput();
4094 
4095 	Entity *e = entity(L);
4096 	while (e && e->isFollowingPath())
4097 	{
4098 		core->main(FRAME_TIME);
4099 	}
4100 
4101 	dsq->game->avatar->enableInput();
4102 	luaReturnNil();
4103 }
4104 
4105 
luaFunc(watchForVoice)4106 luaFunc(watchForVoice)
4107 {
4108 	int quit = lua_tointeger(L, 1);
4109 	while (dsq->sound->isPlayingVoice())
4110 	{
4111 		dsq->watch(FRAME_TIME, quit);
4112 		if (quit && dsq->isQuitFlag())
4113 		{
4114 			dsq->sound->stopVoice();
4115 			break;
4116 		}
4117 	}
4118 	luaReturnNil();
4119 }
4120 
4121 
luaFunc(entity_isSlowingToStopPath)4122 luaFunc(entity_isSlowingToStopPath)
4123 {
4124 	Entity *e = entity(L);
4125 	bool v = false;
4126 	if (e)
4127 	{
4128 		v = e->isSlowingToStopPath();
4129 	}
4130 	luaReturnBool(v);
4131 }
4132 
luaFunc(entity_resumePath)4133 luaFunc(entity_resumePath)
4134 {
4135 	Entity *e = entity(L);
4136 	if (e)
4137 	{
4138 		e->position.resumePath();
4139 	}
4140 	luaReturnNil();
4141 }
4142 
luaFunc(entity_isAnimating)4143 luaFunc(entity_isAnimating)
4144 {
4145 	Entity *e = entity(L);
4146 	bool v= false;
4147 	if (e)
4148 	{
4149 		v = e->skeletalSprite.isAnimating(lua_tonumber(L, 2));
4150 	}
4151 	luaReturnBool(v);
4152 }
4153 
4154 
luaFunc(entity_getAnimationName)4155 luaFunc(entity_getAnimationName)
4156 {
4157 	Entity *e = entity(L);
4158 	const char *ret = "";
4159 	int layer = lua_tointeger(L, 2);
4160 	if (e)
4161 	{
4162 		if (Animation *anim = e->skeletalSprite.getCurrentAnimation(layer))
4163 		{
4164 			ret = anim->name.c_str();
4165 		}
4166 	}
4167 	luaReturnStr(ret);
4168 }
4169 
luaFunc(entity_getAnimationLength)4170 luaFunc(entity_getAnimationLength)
4171 {
4172 	Entity *e = entity(L);
4173 	float ret=0;
4174 	if (e)
4175 	{
4176 		Animation *anim = 0;
4177 		if (lua_isstring(L, 2))
4178 			anim = e->skeletalSprite.getAnimation(lua_tostring(L, 2));
4179 		else
4180 		{
4181 			int layer = lua_tointeger(L, 2);
4182 			anim = e->skeletalSprite.getCurrentAnimation(layer);
4183 		}
4184 		if (anim)
4185 			ret = anim->getAnimationLength();
4186 	}
4187 	luaReturnNum(ret);
4188 }
4189 
luaFunc(entity_hasAnimation)4190 luaFunc(entity_hasAnimation)
4191 {
4192 	Entity *e = entity(L);
4193 	Animation *anim = e->skeletalSprite.getAnimation(getString(L, 2));
4194 	luaReturnBool(anim != NULL);
4195 }
4196 
luaFunc(entity_isFollowingPath)4197 luaFunc(entity_isFollowingPath)
4198 {
4199 	Entity *e = entity(L);
4200 	if (e)
4201 		luaReturnBool(e->isFollowingPath());
4202 	else
4203 		luaReturnBool(false);
4204 }
4205 
luaFunc(entity_toggleBone)4206 luaFunc(entity_toggleBone)
4207 {
4208 	Entity *e = entity(L);
4209 	Bone *b = bone(L, 2);
4210 	if (e && b)
4211 	{
4212 		e->skeletalSprite.toggleBone(e->skeletalSprite.getBoneIdx(b), lua_tonumber(L, 3));
4213 	}
4214 	luaReturnNil();
4215 }
4216 
luaFunc(entity_setEntityType)4217 luaFunc(entity_setEntityType)
4218 {
4219 	Entity *e = entity(L);
4220 	if (e)
4221 		e->setEntityType(EntityType(lua_tointeger(L, 2)));
4222 	luaReturnNil();
4223 }
4224 
luaFunc(entity_getEntityType)4225 luaFunc(entity_getEntityType)
4226 {
4227 	Entity *e = entity(L);
4228 	if (e)
4229 		luaReturnInt(int(e->getEntityType()));
4230 	else
4231 		luaReturnInt(0);
4232 }
4233 
luaFunc(cam_snap)4234 luaFunc(cam_snap)
4235 {
4236 	dsq->game->snapCam();
4237 	luaReturnNil();
4238 }
4239 
luaFunc(cam_toNode)4240 luaFunc(cam_toNode)
4241 {
4242 	Path *p = path(L);
4243 	if (p)
4244 	{
4245 		dsq->game->setCameraFollow(&p->nodes[0].position);
4246 	}
4247 	luaReturnNil();
4248 }
4249 
luaFunc(cam_toEntity)4250 luaFunc(cam_toEntity)
4251 {
4252 	if (lua_touserdata(L, 1) == NULL)
4253 	{
4254 		Vector *pos = 0;
4255 		dsq->game->setCameraFollow(pos);
4256 	}
4257 	else
4258 	{
4259 		Entity *e = entity(L);
4260 		if (e)
4261 		{
4262 			dsq->game->setCameraFollowEntity(e);
4263 		}
4264 	}
4265 	luaReturnNil();
4266 }
4267 
luaFunc(cam_setPosition)4268 luaFunc(cam_setPosition)
4269 {
4270 	float x = lua_tonumber(L, 1);
4271 	float y = lua_tonumber(L, 2);
4272 	float time = lua_tonumber(L, 3);
4273 	int loopType = lua_tointeger(L, 4);
4274 	bool pingPong = getBool(L, 5);
4275 	bool ease = getBool(L, 6);
4276 
4277 	Vector p(x,y);
4278 
4279 	dsq->game->cameraInterp.stop();
4280 	dsq->game->cameraInterp.interpolateTo(p, time, loopType, pingPong, ease);
4281 
4282 	dsq->cameraPos = dsq->game->getCameraPositionFor(dsq->game->cameraInterp);
4283 	luaReturnNil();
4284 }
4285 
4286 
luaFunc(entity_spawnParticlesFromCollisionMask)4287 luaFunc(entity_spawnParticlesFromCollisionMask)
4288 {
4289 	Entity *e = entity(L);
4290 	if (e)
4291 	{
4292 		int intv = lua_tointeger(L, 3);
4293 		if (intv <= 0)
4294 			intv = 1;
4295 		e->spawnParticlesFromCollisionMask(getString(L, 2), intv);
4296 	}
4297 
4298 	luaReturnNil();
4299 }
4300 
luaFunc(entity_initEmitter)4301 luaFunc(entity_initEmitter)
4302 {
4303 	ScriptedEntity *se = scriptedEntity(L);
4304 	int e = lua_tointeger(L, 2);
4305 	std::string pfile = getString(L, 3);
4306 	if (se)
4307 	{
4308 		se->initEmitter(e, pfile);
4309 	}
4310 	luaReturnNil();
4311 }
4312 
luaFunc(entity_startEmitter)4313 luaFunc(entity_startEmitter)
4314 {
4315 	ScriptedEntity *se = scriptedEntity(L);
4316 	int e = lua_tointeger(L, 2);
4317 	if (se)
4318 	{
4319 		se->startEmitter(e);
4320 	}
4321 	luaReturnNil();
4322 }
4323 
luaFunc(entity_stopEmitter)4324 luaFunc(entity_stopEmitter)
4325 {
4326 	ScriptedEntity *se = scriptedEntity(L);
4327 	int e = lua_tointeger(L, 2);
4328 	if (se)
4329 	{
4330 		se->stopEmitter(e);
4331 	}
4332 	luaReturnNil();
4333 }
4334 
luaFunc(entity_getEmitter)4335 luaFunc(entity_getEmitter)
4336 {
4337 	ScriptedEntity *se = scriptedEntity(L);
4338 	luaReturnPtr(se ? se->getEmitter(lua_tointeger(L, 2)) : NULL);
4339 }
4340 
luaFunc(entity_getNumEmitters)4341 luaFunc(entity_getNumEmitters)
4342 {
4343 	ScriptedEntity *se = scriptedEntity(L);
4344 	luaReturnInt(se ? se->getNumEmitters() : 0);
4345 }
4346 
luaFunc(entity_initStrands)4347 luaFunc(entity_initStrands)
4348 {
4349 	ScriptedEntity *e = scriptedEntity(L);
4350 	if (e)
4351 	{
4352 		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)));
4353 	}
4354 	luaReturnNil();
4355 }
4356 
luaFunc(entity_initSkeletal)4357 luaFunc(entity_initSkeletal)
4358 {
4359 	Entity *e = entity(L);
4360 	if (e)
4361 	{
4362 		e->renderQuad = false;
4363 		e->setWidthHeight(128, 128);
4364 		e->skeletalSprite.loadSkeletal(getString(L, 2));
4365 		const char *s = lua_tostring(L, 3);
4366 		if (s && *s)
4367 			e->skeletalSprite.loadSkin(s);
4368 	}
4369 	luaReturnNil();
4370 }
4371 
luaFunc(entity_loadSkin)4372 luaFunc(entity_loadSkin)
4373 {
4374 	Entity *e = entity(L);
4375 	if (e && e->skeletalSprite.isLoaded())
4376 	{
4377 		const char *s = lua_tostring(L, 2);
4378 		if (s && *s)
4379 			e->skeletalSprite.loadSkin(s);
4380 	}
4381 	luaReturnNil();
4382 }
4383 
luaFunc(entity_getSkeletalName)4384 luaFunc(entity_getSkeletalName)
4385 {
4386 	Entity *e = entity(L);
4387 	const char *s = "";
4388 	if (e && e->skeletalSprite.isLoaded())
4389 		s = e->skeletalSprite.filenameLoaded.c_str();
4390 	luaReturnStr(s);
4391 }
4392 
luaFunc(entity_hasSkeletal)4393 luaFunc(entity_hasSkeletal)
4394 {
4395 	Entity *e = entity(L);
4396 	luaReturnBool(e && e->skeletalSprite.isLoaded());
4397 }
4398 
luaFunc(entity_getNumAnimLayers)4399 luaFunc(entity_getNumAnimLayers)
4400 {
4401 	Entity *e = entity(L);
4402 	luaReturnInt(e ? e->skeletalSprite.getNumAnimLayers() : 0);
4403 }
4404 
luaFunc(entity_idle)4405 luaFunc(entity_idle)
4406 {
4407 	Entity *e = entity(L);
4408 	if (e)
4409 	{
4410 		e->idle();
4411 	}
4412 	luaReturnNil();
4413 }
4414 
luaFunc(entity_stopAllAnimations)4415 luaFunc(entity_stopAllAnimations)
4416 {
4417 	Entity *e = entity(L);
4418 	if (e)
4419 		e->skeletalSprite.stopAllAnimations();
4420 	luaReturnNil();
4421 }
4422 
luaFunc(entity_setAnimLayerTimeMult)4423 luaFunc(entity_setAnimLayerTimeMult)
4424 {
4425 	Entity *e = entity(L);
4426 	int layer = 0;
4427 	float t = 0;
4428 	if (e)
4429 	{
4430 		layer = lua_tointeger(L, 2);
4431 		t = lua_tonumber(L, 3);
4432 		AnimationLayer *l = e->skeletalSprite.getAnimationLayer(layer);
4433 		if (l)
4434 		{
4435 			interpolateVec1(L, l->timeMultiplier, 3);
4436 		}
4437 	}
4438 	luaReturnNum(t);
4439 }
4440 
luaFunc(entity_getAnimLayerTimeMult)4441 luaFunc(entity_getAnimLayerTimeMult)
4442 {
4443 	Entity *e = entity(L);
4444 	float t = 0;
4445 	if (e)
4446 	{
4447 		AnimationLayer *l = e->skeletalSprite.getAnimationLayer(lua_tointeger(L, 2));
4448 		if (l)
4449 		{
4450 			t = l->timeMultiplier.x;
4451 		}
4452 	}
4453 	luaReturnNum(t);
4454 }
4455 
luaFunc(entity_animate)4456 luaFunc(entity_animate)
4457 {
4458 	SkeletalSprite *skel = getSkeletalSprite(entity(L));
4459 	float ret = 0;
4460 	if (skel)
4461 	{
4462 		float transition = lua_tonumber(L, 5);
4463 		if (transition == -1)
4464 			transition = 0;
4465 		else if (transition == 0)
4466 			transition = 0.2;
4467 		ret = skel->transitionAnimate(getString(L, 2), transition, lua_tointeger(L, 3), lua_tointeger(L, 4));
4468 	}
4469 	luaReturnNum(ret);
4470 }
4471 
luaFunc(entity_stopAnimation)4472 luaFunc(entity_stopAnimation)
4473 {
4474 	SkeletalSprite *skel = getSkeletalSprite(entity(L));
4475 	if (skel)
4476 	{
4477 		AnimationLayer *animlayer = skel->getAnimationLayer(lua_tointeger(L, 2));
4478 		if (animlayer)
4479 			animlayer->stopAnimation();
4480 	}
4481 	luaReturnNil();
4482 }
4483 
luaFunc(entity_getAnimationLoop)4484 luaFunc(entity_getAnimationLoop)
4485 {
4486 	int loop = 0;
4487 	SkeletalSprite *skel = getSkeletalSprite(entity(L));
4488 	if (skel)
4489 	{
4490 		AnimationLayer *animlayer = skel->getAnimationLayer(lua_tointeger(L, 2));
4491 		if (animlayer)
4492 			loop = animlayer->loop ? animlayer->loop : animlayer->enqueuedAnimationLoop;
4493 	}
4494 	luaReturnInt(loop);
4495 }
4496 
4497 // entity, x, y, time, ease, relative
luaFunc(entity_move)4498 luaFunc(entity_move)
4499 {
4500 	Entity *e = entity(L);
4501 	bool ease = lua_tointeger(L, 5);
4502 	Vector p(lua_tonumber(L, 2), lua_tonumber(L, 3));
4503 	if (getBool(L, 6))
4504 		p = e->position + p;
4505 
4506 	e->position.interpolateTo(p, lua_tonumber(L, 4), 0, 0, getBool(L, 5));
4507 	luaReturnNil();
4508 }
4509 
luaFunc(spawnManaBall)4510 luaFunc(spawnManaBall)
4511 {
4512 	Vector p;
4513 	p.x = lua_tonumber(L, 1);
4514 	p.y = lua_tonumber(L, 2);
4515 	float amount = lua_tonumber(L, 3);
4516 	dsq->game->spawnManaBall(p, amount);
4517 	luaReturnNil();
4518 }
4519 
luaFunc(spawnAroundEntity)4520 luaFunc(spawnAroundEntity)
4521 {
4522 	Entity *e = entity(L);
4523 	int num = lua_tointeger(L, 2);
4524 	float radius = lua_tonumber(L, 3);
4525 	std::string entType = getString(L, 4);
4526 	std::string name = getString(L, 5);
4527 	int idx = dsq->game->getIdxForEntityType(entType);
4528 	if (e)
4529 	{
4530 		Vector pos = e->position;
4531 		for (int i = 0; i < num; i++)
4532 		{
4533 			float angle = i*((2*PI)/float(num));
4534 
4535 			e = dsq->game->createEntity(idx, 0, pos + Vector(sinf(angle)*radius, cosf(angle)*radius), 0, false, name);
4536 		}
4537 	}
4538 	luaReturnNil();
4539 }
4540 
luaFunc(createBeam)4541 luaFunc(createBeam)
4542 {
4543 	int x = lua_tointeger(L, 1);
4544 	int y = lua_tointeger(L, 2);
4545 	float a = lua_tonumber(L, 3);
4546 	int l = lua_tointeger(L, 4);
4547 	Beam *b = new Beam(Vector(x,y), a);
4548 	if (l == 1)
4549 		dsq->game->addRenderObject(b, LR_PARTICLES);
4550 	else
4551 		dsq->game->addRenderObject(b, LR_ENTITIES_MINUS2);
4552 	luaReturnPtr(b);
4553 }
4554 
luaFunc(beam_setDamage)4555 luaFunc(beam_setDamage)
4556 {
4557 	Beam *b = beam(L);
4558 	if (b)
4559 	{
4560 		b->setDamage(lua_tonumber(L, 2));
4561 	}
4562 	luaReturnNil();
4563 }
4564 
luaFunc(beam_setDamageType)4565 luaFunc(beam_setDamageType)
4566 {
4567 	Beam *b = beam(L);
4568 	if (b)
4569 	{
4570 		b->damageData.damageType = (DamageType)lua_tointeger(L, 2);
4571 	}
4572 	luaReturnNil();
4573 }
4574 
luaFunc(beam_setBeamWidth)4575 luaFunc(beam_setBeamWidth)
4576 {
4577 	Beam *b = beam(L);
4578 	if (b)
4579 	{
4580 		b->setBeamWidth(lua_tonumber(L, 2));
4581 	}
4582 	luaReturnNil();
4583 }
4584 
luaFunc(beam_setAngle)4585 luaFunc(beam_setAngle)
4586 {
4587 	Beam *b = beam(L);
4588 	if (b)
4589 	{
4590 		b->angle = lua_tonumber(L, 2);
4591 		b->trace();
4592 	}
4593 	luaReturnNil();
4594 }
4595 
luaFunc(beam_setFirer)4596 luaFunc(beam_setFirer)
4597 {
4598 	Beam *b = beam(L);
4599 	if (b)
4600 		b->setFirer(entity(L, 2));
4601 	luaReturnNil();
4602 }
4603 
4604 // Note the additional trace() call
luaFunc(beam_setPosition_override)4605 luaFunc(beam_setPosition_override)
4606 {
4607 	Beam *b = beam(L);
4608 	if (b)
4609 	{
4610 		forwardCall(obj_setPosition);
4611 		b->trace();
4612 	}
4613 	luaReturnNil();
4614 }
4615 
luaFunc(beam_getEndPos)4616 luaFunc(beam_getEndPos)
4617 {
4618 	Beam *b = beam(L);
4619 	Vector v;
4620 	if (b)
4621 		v = b->endPos;
4622 	luaReturnVec2(v.x, v.y);
4623 }
4624 
luaFunc(getStringBank)4625 luaFunc(getStringBank)
4626 {
4627 	luaReturnStr(dsq->continuity.stringBank.get(lua_tointeger(L, 1)).c_str());
4628 }
4629 
luaFunc(isPlat)4630 luaFunc(isPlat)
4631 {
4632 	int plat = lua_tointeger(L, 1);
4633 	bool v = false;
4634 #ifdef BBGE_BUILD_WINDOWS
4635 	v = (plat == 0);
4636 #elif BBGE_BUILD_MACOSX
4637 	v = (plat == 1);
4638 #elif BBGE_BUILD_UNIX
4639 	v = (plat == 2);
4640 #endif
4641 	luaReturnBool(v);
4642 }
4643 
luaFunc(createEntity)4644 luaFunc(createEntity)
4645 {
4646 	std::string type = getString(L, 1);
4647 	std::string name;
4648 	if (lua_isstring(L, 2))
4649 		name = lua_tostring(L, 2);
4650 	int x = lua_tointeger(L, 3);
4651 	int y = lua_tointeger(L, 4);
4652 
4653 	Entity *e = 0;
4654 	e = dsq->game->createEntity(type, 0, Vector(x, y), 0, false, name, ET_ENEMY, true);
4655 
4656 	luaReturnPtr(e);
4657 }
4658 
luaFunc(savePoint)4659 luaFunc(savePoint)
4660 {
4661 	Path *p = path(L);
4662 	Vector position;
4663 	if (p)
4664 	{
4665 		//dsq->game->avatar->moveToNode(p, 0, 0, 1);
4666 		position = p->nodes[0].position;
4667 	}
4668 
4669 	dsq->doSavePoint(position);
4670 	luaReturnNil();
4671 }
4672 
luaFunc(saveMenu)4673 luaFunc(saveMenu)
4674 {
4675 	dsq->doSaveSlotMenu(SSM_SAVE);
4676 	luaReturnNil();
4677 }
4678 
luaFunc(pause)4679 luaFunc(pause)
4680 {
4681 	dsq->game->togglePause(1);
4682 	luaReturnNil();
4683 }
4684 
luaFunc(unpause)4685 luaFunc(unpause)
4686 {
4687 	dsq->game->togglePause(0);
4688 	luaReturnNil();
4689 }
4690 
luaFunc(isPaused)4691 luaFunc(isPaused)
4692 {
4693 	luaReturnBool(dsq->game->isPaused());
4694 }
4695 
luaFunc(isInGameMenu)4696 luaFunc(isInGameMenu)
4697 {
4698 	luaReturnBool(dsq->game->isInGameMenu());
4699 }
4700 
luaFunc(isInEditor)4701 luaFunc(isInEditor)
4702 {
4703 	luaReturnBool(dsq->game->isSceneEditorActive());
4704 }
4705 
luaFunc(clearControlHint)4706 luaFunc(clearControlHint)
4707 {
4708 	dsq->game->clearControlHint();
4709 	luaReturnNil();
4710 }
4711 
luaFunc(setSceneColor)4712 luaFunc(setSceneColor)
4713 {
4714 	interpolateVec3(L, dsq->game->sceneColor3, 1);
4715 	luaReturnNil();
4716 }
4717 
luaFunc(getSceneColor)4718 luaFunc(getSceneColor)
4719 {
4720 	const Vector& c = dsq->game->sceneColor3;
4721 	luaReturnVec3(c.x, c.y, c.z);
4722 }
4723 
luaFunc(setSceneColor2)4724 luaFunc(setSceneColor2)
4725 {
4726 	interpolateVec3(L, dsq->game->sceneColor2, 1);
4727 	luaReturnNil();
4728 }
4729 
luaFunc(getSceneColor2)4730 luaFunc(getSceneColor2)
4731 {
4732 	const Vector& c = dsq->game->sceneColor2;
4733 	luaReturnVec3(c.x, c.y, c.z);
4734 }
4735 
luaFunc(setCameraLerpDelay)4736 luaFunc(setCameraLerpDelay)
4737 {
4738 	dsq->game->cameraLerpDelay = lua_tonumber(L, 1);
4739 	luaReturnNil();
4740 }
4741 
luaFunc(setControlHint)4742 luaFunc(setControlHint)
4743 {
4744 	std::string str = getString(L, 1);
4745 	bool left = getBool(L, 2);
4746 	bool right = getBool(L, 3);
4747 	bool middle = getBool(L, 4);
4748 	float t = lua_tonumber(L, 5);
4749 	std::string s;
4750 	if (lua_isstring(L, 6))
4751 		s = lua_tostring(L, 6);
4752 	int songType = lua_tointeger(L, 7);
4753 	float scale = lua_tonumber(L, 8);
4754 	if (scale == 0)
4755 		scale = 1;
4756 
4757 	dsq->game->setControlHint(str, left, right, middle, t, s, false, songType, scale);
4758 	luaReturnNil();
4759 }
4760 
luaFunc(setCanChangeForm)4761 luaFunc(setCanChangeForm)
4762 {
4763 	dsq->game->avatar->canChangeForm = getBool(L);
4764 	luaReturnNil();
4765 }
4766 
luaFunc(setInvincibleOnNested)4767 luaFunc(setInvincibleOnNested)
4768 {
4769 	dsq->game->invincibleOnNested = getBool(L);
4770 	luaReturnNil();
4771 }
4772 
luaFunc(setCanWarp)4773 luaFunc(setCanWarp)
4774 {
4775 	dsq->game->avatar->canWarp = getBool(L);
4776 	luaReturnNil();
4777 }
4778 
luaFunc(entity_generateCollisionMask)4779 luaFunc(entity_generateCollisionMask)
4780 {
4781 	Entity *e = entity(L);
4782 	float num = lua_tonumber(L, 2);
4783 	if (e)
4784 	{
4785 		e->generateCollisionMask(num);
4786 	}
4787 	luaReturnNil();
4788 }
4789 
luaFunc(entity_damage)4790 luaFunc(entity_damage)
4791 {
4792 	Entity *e = entity(L);
4793 	bool didDamage = false;
4794 	if (e)
4795 	{
4796 		DamageData d;
4797 		//d.attacker = e;
4798 		d.attacker = lua_isuserdata(L, 2) ? entity(L, 2) : NULL;
4799 		d.damage = lua_tonumber(L, 3);
4800 		d.damageType = (DamageType)lua_tointeger(L, 4);
4801 		d.effectTime = lua_tonumber(L, 5);
4802 		d.useTimer = !getBool(L, 6);
4803 		d.shot = lua_isuserdata(L, 7) ? getShot(L, 7) : NULL;
4804 		d.hitPos = Vector(lua_tonumber(L, 8), lua_tonumber(L, 9));
4805 		didDamage = e->damage(d);
4806 	}
4807 	luaReturnBool(didDamage);
4808 }
4809 
4810 // must be called in init
luaFunc(entity_setEntityLayer)4811 luaFunc(entity_setEntityLayer)
4812 {
4813 	ScriptedEntity *e = scriptedEntity(L);
4814 	int l = lua_tointeger(L, 2);
4815 	if (e)
4816 	{
4817 		e->setEntityLayer(l);
4818 	}
4819 	luaReturnNil();
4820 }
4821 
4822 // Note that this overrides the generic obj_setRenderPass function for entities.
4823 // (It's registered as "entity_setRenderPass" to Lua)
luaFunc(entity_setRenderPass_override)4824 luaFunc(entity_setRenderPass_override)
4825 {
4826 	Entity *e = entity(L);
4827 	int pass = lua_tointeger(L, 2);
4828 	if (e)
4829 		e->setOverrideRenderPass(pass);
4830 	luaReturnNil();
4831 }
4832 
4833 // intended to be used for setting max health and refilling it all
luaFunc(entity_setHealth)4834 luaFunc(entity_setHealth)
4835 {
4836 	Entity *e = entity(L, 1);
4837 	if (e)
4838 		e->health = e->maxHealth = lua_tonumber(L, 2);
4839 	luaReturnNil();
4840 }
4841 
luaFunc(entity_setCurrentHealth)4842 luaFunc(entity_setCurrentHealth)
4843 {
4844 	Entity *e = entity(L, 1);
4845 	if (e)
4846 		e->health = lua_tonumber(L, 2);
4847 	luaReturnNil();
4848 }
4849 
luaFunc(entity_setMaxHealth)4850 luaFunc(entity_setMaxHealth)
4851 {
4852 	Entity *e = entity(L, 1);
4853 	if (e)
4854 		e->maxHealth = lua_tonumber(L, 2);
4855 	luaReturnNil();
4856 }
4857 
luaFunc(entity_changeHealth)4858 luaFunc(entity_changeHealth)
4859 {
4860 	Entity *e = entity(L, 1);
4861 	if (e)
4862 		e->health += lua_tonumber(L, 2);
4863 	luaReturnNil();
4864 }
4865 
luaFunc(entity_heal)4866 luaFunc(entity_heal)
4867 {
4868 	Entity *e = entity(L);
4869 	if (e)
4870 		e->heal(lua_tonumber(L, 2));
4871 	luaReturnNil();
4872 }
4873 
luaFunc(entity_revive)4874 luaFunc(entity_revive)
4875 {
4876 	Entity *e = entity(L);
4877 	if (e)
4878 		e->revive(lua_tonumber(L, 2));
4879 	luaReturnNil();
4880 }
4881 
luaFunc(screenFadeCapture)4882 luaFunc(screenFadeCapture)
4883 {
4884 	dsq->screenTransition->capture();
4885 	luaReturnNil();
4886 }
4887 
4888 
luaFunc(screenFadeTransition)4889 luaFunc(screenFadeTransition)
4890 {
4891 	dsq->screenTransition->transition(lua_tonumber(L, 1));
4892 	luaReturnNil();
4893 }
4894 
luaFunc(screenFadeGo)4895 luaFunc(screenFadeGo)
4896 {
4897 	dsq->screenTransition->go(lua_tonumber(L, 1));
4898 	luaReturnNil();
4899 }
4900 
luaFunc(isEscapeKey)4901 luaFunc(isEscapeKey)
4902 {
4903 	bool isDown = dsq->game->isActing(ACTION_ESC);
4904 	luaReturnBool(isDown);
4905 }
4906 
luaFunc(isLeftMouse)4907 luaFunc(isLeftMouse)
4908 {
4909 	bool isDown = core->mouse.buttons.left || (dsq->game->avatar && dsq->game->avatar->pollAction(ACTION_PRIMARY));
4910 	luaReturnBool(isDown);
4911 }
4912 
luaFunc(isRightMouse)4913 luaFunc(isRightMouse)
4914 {
4915 	bool isDown = core->mouse.buttons.right || (dsq->game->avatar && dsq->game->avatar->pollAction(ACTION_SECONDARY));
4916 	luaReturnBool(isDown);
4917 }
4918 
luaFunc(setTimerTextAlpha)4919 luaFunc(setTimerTextAlpha)
4920 {
4921 	dsq->game->setTimerTextAlpha(lua_tonumber(L, 1), lua_tonumber(L, 2));
4922 	luaReturnNil();
4923 }
4924 
luaFunc(setTimerText)4925 luaFunc(setTimerText)
4926 {
4927 	dsq->game->setTimerText(lua_tonumber(L, 1));
4928 	luaReturnNil();
4929 }
4930 
luaFunc(getWallNormal)4931 luaFunc(getWallNormal)
4932 {
4933 	float x,y;
4934 	x = lua_tonumber(L, 1);
4935 	y = lua_tonumber(L, 2);
4936 	int range = lua_tointeger(L, 3);
4937 	int obs  = lua_tointeger(L, 4);
4938 	if (range == 0)
4939 		range = 5;
4940 	if (!obs)
4941 		obs = OT_BLOCKING;
4942 
4943 	Vector n = dsq->game->getWallNormal(Vector(x, y), range, NULL, obs);
4944 
4945 	luaReturnVec2(n.x, n.y);
4946 }
4947 
luaFunc(incrFlag)4948 luaFunc(incrFlag)
4949 {
4950 	std::string f = getString(L, 1);
4951 	int v = 1;
4952 	if (lua_isnumber(L, 2))
4953 		v = lua_tointeger(L, 2);
4954 	dsq->continuity.setFlag(f, dsq->continuity.getFlag(f)+v);
4955 	luaReturnNil();
4956 }
4957 
luaFunc(decrFlag)4958 luaFunc(decrFlag)
4959 {
4960 	std::string f = getString(L, 1);
4961 	int v = 1;
4962 	if (lua_isnumber(L, 2))
4963 		v = lua_tointeger(L, 2);
4964 	dsq->continuity.setFlag(f, dsq->continuity.getFlag(f)-v);
4965 	luaReturnNil();
4966 }
4967 
luaFunc(setFlag)4968 luaFunc(setFlag)
4969 {
4970 	/*
4971 	if (lua_isstring(L, 1))
4972 		dsq->continuity.setFlag(lua_tostring(L, 1), lua_tonumber(L, 2));
4973 	else
4974 	*/
4975 	dsq->continuity.setFlag(lua_tointeger(L, 1), lua_tointeger(L, 2));
4976 	luaReturnNil();
4977 }
4978 
luaFunc(getFlag)4979 luaFunc(getFlag)
4980 {
4981 	int v = 0;
4982 	/*
4983 	if (lua_isstring(L, 1))
4984 		v = dsq->continuity.getFlag(lua_tostring(L, 1));
4985 	else if (lua_isnumber(L, 1))
4986 	*/
4987 	v = dsq->continuity.getFlag(lua_tointeger(L, 1));
4988 
4989 	luaReturnNum(v);
4990 }
4991 
luaFunc(getStringFlag)4992 luaFunc(getStringFlag)
4993 {
4994 	luaReturnStr(dsq->continuity.getStringFlag(getString(L, 1)).c_str());
4995 }
4996 
luaFunc(node_setEmitter)4997 luaFunc(node_setEmitter)
4998 {
4999 	Path *p = path(L);
5000 	if(p)
5001 		p->setEmitter(getString(L, 2));
5002 	luaReturnPtr(p->emitter);
5003 }
5004 
luaFunc(node_getEmitter)5005 luaFunc(node_getEmitter)
5006 {
5007 	Path *p = path(L);
5008 	luaReturnPtr(p ? p->emitter : NULL);
5009 }
5010 
5011 
luaFunc(node_setActive)5012 luaFunc(node_setActive)
5013 {
5014 	Path *p = path(L);
5015 	bool v = getBool(L, 2);
5016 	if (p)
5017 	{
5018 		p->active = v;
5019 		if(p->emitter)
5020 		{
5021 			if(v)
5022 				p->emitter->start();
5023 			else
5024 				p->emitter->stop();
5025 		}
5026 	}
5027 	luaReturnNil();
5028 }
5029 
luaFunc(node_isActive)5030 luaFunc(node_isActive)
5031 {
5032 	Path *p = path(L);
5033 	luaReturnBool(p ? p->active : false);
5034 }
5035 
luaFunc(node_setCursorActivation)5036 luaFunc(node_setCursorActivation)
5037 {
5038 	Path *p = path(L);
5039 	bool v = getBool(L, 2);
5040 	if (p)
5041 	{
5042 		p->cursorActivation = v;
5043 	}
5044 	luaReturnNil();
5045 }
5046 
luaFunc(node_setActivationRange)5047 luaFunc(node_setActivationRange)
5048 {
5049 	Path *p = path(L);
5050 	if(p)
5051 		p->activationRange = lua_tonumber(L, 2);
5052 	luaReturnNil();
5053 }
5054 
luaFunc(node_setCatchActions)5055 luaFunc(node_setCatchActions)
5056 {
5057 	Path *p = path(L);
5058 	bool v = getBool(L, 2);
5059 	if (p)
5060 	{
5061 		p->catchActions = v;
5062 	}
5063 	luaReturnNil();
5064 }
5065 
luaFunc(node_isEntityInRange)5066 luaFunc(node_isEntityInRange)
5067 {
5068 	Path *p = path(L);
5069 	Entity *e = entity(L,2);
5070 	float range = lua_tonumber(L, 3);
5071 	bool v = false;
5072 	if (p && e)
5073 	{
5074 		if ((p->nodes[0].position - e->position).isLength2DIn(range))
5075 		{
5076 			v = true;
5077 		}
5078 	}
5079 	luaReturnBool(v);
5080 }
5081 
luaFunc(node_isEntityPast)5082 luaFunc(node_isEntityPast)
5083 {
5084 	Path *p = path(L);
5085 	bool past = false;
5086 	if (p && !p->nodes.empty())
5087 	{
5088 		PathNode *n = &p->nodes[0];
5089 		Entity *e = entity(L, 2);
5090 		if (e)
5091 		{
5092 			bool checkY = getBool(L, 3);
5093 			int dir = lua_tointeger(L, 4);
5094 			float range = lua_tonumber(L, 5);
5095 			if (!checkY)
5096 			{
5097 				if (e->position.x > n->position.x-range && e->position.x < n->position.x+range)
5098 				{
5099 					if (!dir)
5100 					{
5101 						if (e->position.y < n->position.y)
5102 							past = true;
5103 					}
5104 					else
5105 					{
5106 						if (e->position.y > n->position.y)
5107 							past = true;
5108 					}
5109 				}
5110 			}
5111 			else
5112 			{
5113 				if (e->position.y > n->position.y-range && e->position.y < n->position.y+range)
5114 				{
5115 					if (!dir)
5116 					{
5117 						if (e->position.x < n->position.x)
5118 							past = true;
5119 					}
5120 					else
5121 					{
5122 						if (e->position.x > n->position.x)
5123 							past = true;
5124 					}
5125 				}
5126 			}
5127 		}
5128 	}
5129 	luaReturnBool(past);
5130 }
5131 
luaFunc(node_x)5132 luaFunc(node_x)
5133 {
5134 	Path *p = path(L);
5135 	float v = 0;
5136 	if (p)
5137 	{
5138 		v = p->nodes[0].position.x;
5139 	}
5140 	luaReturnNum(v);
5141 }
5142 
luaFunc(node_y)5143 luaFunc(node_y)
5144 {
5145 	Path *p = path(L);
5146 	float v = 0;
5147 	if (p)
5148 	{
5149 		v = p->nodes[0].position.y;
5150 	}
5151 	luaReturnNum(v);
5152 }
5153 
luaFunc(entity_isName)5154 luaFunc(entity_isName)
5155 {
5156 	Entity *e = entity(L);
5157 	std::string s = getString(L, 2);
5158 	bool ret = false;
5159 	if (e)
5160 	{
5161 		ret = (nocasecmp(s,e->name)==0);
5162 	}
5163 	luaReturnBool(ret);
5164 }
5165 
5166 
luaFunc(entity_getName)5167 luaFunc(entity_getName)
5168 {
5169 	Entity *e = entity(L);
5170 	const char *s = "";
5171 	if (e)
5172 	{
5173 		s = e->name.c_str();
5174 	}
5175 	luaReturnStr(s);
5176 }
5177 
luaFunc(node_getContent)5178 luaFunc(node_getContent)
5179 {
5180 	Path *p = path(L);
5181 	const char *s = "";
5182 	if (p)
5183 	{
5184 		s = p->content.c_str();
5185 	}
5186 	luaReturnStr(s);
5187 }
5188 
luaFunc(node_getAmount)5189 luaFunc(node_getAmount)
5190 {
5191 	Path *p = path(L);
5192 	float a = 0;
5193 	if (p)
5194 	{
5195 		a = p->amount;
5196 	}
5197 	luaReturnNum(a);
5198 }
5199 
luaFunc(node_getSize)5200 luaFunc(node_getSize)
5201 {
5202 	Path *p = path(L);
5203 	int w=0,h=0;
5204 	if (p)
5205 	{
5206 		w = p->rect.getWidth();
5207 		h = p->rect.getHeight();
5208 	}
5209 	luaReturnVec2(w, h);
5210 }
5211 
luaFunc(node_getName)5212 luaFunc(node_getName)
5213 {
5214 	Path *p = path(L);
5215 	const char *s = "";
5216 	if (p)
5217 	{
5218 		s = p->name.c_str();
5219 	}
5220 	luaReturnStr(s);
5221 }
5222 
luaFunc(node_getLabel)5223 luaFunc(node_getLabel)
5224 {
5225 	Path *p = path(L);
5226 	const char *s = "";
5227 	if (p)
5228 	{
5229 		s = p->label.c_str();
5230 	}
5231 	luaReturnStr(s);
5232 }
5233 
luaFunc(node_getPathPosition)5234 luaFunc(node_getPathPosition)
5235 {
5236 	Path *p = path(L);
5237 	int idx = lua_tointeger(L, 2);
5238 	float x=0,y=0;
5239 	if (p)
5240 	{
5241 		PathNode *node = p->getPathNode(idx);
5242 		if (node)
5243 		{
5244 			x = node->position.x;
5245 			y = node->position.y;
5246 		}
5247 	}
5248 	luaReturnVec2(x, y);
5249 }
5250 
luaFunc(node_getPosition)5251 luaFunc(node_getPosition)
5252 {
5253 	Path *p = path(L);
5254 	float x=0,y=0;
5255 	if (p)
5256 	{
5257 		PathNode *node = &p->nodes[0];
5258 		x = node->position.x;
5259 		y = node->position.y;
5260 	}
5261 	luaReturnVec2(x, y);
5262 }
5263 
luaFunc(node_setPosition)5264 luaFunc(node_setPosition)
5265 {
5266 	Path *p = path(L);
5267 	float x=0,y=0;
5268 	if (p)
5269 	{
5270 		x = lua_tonumber(L, 2);
5271 		y = lua_tonumber(L, 3);
5272 		PathNode *node = &p->nodes[0];
5273 		node->position = Vector(x, y);
5274 	}
5275 	luaReturnNil();
5276 }
5277 
luaFunc(node_getShape)5278 luaFunc(node_getShape)
5279 {
5280 	Path *p = path(L);
5281 	luaReturnInt(p ? p->pathShape : 0);
5282 }
5283 
5284 
luaFunc(registerSporeDrop)5285 luaFunc(registerSporeDrop)
5286 {
5287 	float x, y;
5288 	int t=0;
5289 	x = lua_tonumber(L, 1);
5290 	y = lua_tonumber(L, 2);
5291 	t = lua_tointeger(L, 3);
5292 
5293 	dsq->game->registerSporeDrop(Vector(x,y), t);
5294 
5295 	luaReturnNil();
5296 }
5297 
luaFunc(setStringFlag)5298 luaFunc(setStringFlag)
5299 {
5300 	std::string n = getString(L, 1);
5301 	std::string v = getString(L, 2);
5302 	dsq->continuity.setStringFlag(n, v);
5303 	luaReturnNil();
5304 }
5305 
luaFunc(centerText)5306 luaFunc(centerText)
5307 {
5308 	dsq->centerText(getString(L, 1));
5309 	luaReturnNil();
5310 }
5311 
luaFunc(msg)5312 luaFunc(msg)
5313 {
5314 	dsq->screenMessage(getString(L, 1));
5315 	luaReturnNil();
5316 }
5317 
luaFunc(chance)5318 luaFunc(chance)
5319 {
5320 	int r = rand()%100;
5321 	int c = lua_tointeger(L, 1);
5322 	if (c == 0)
5323 		luaReturnBool(false);
5324 	else
5325 	{
5326 		if (r <= c || c==100)
5327 			luaReturnBool(true);
5328 		else
5329 			luaReturnBool(false);
5330 	}
5331 }
5332 
luaFunc(entity_handleShotCollisions)5333 luaFunc(entity_handleShotCollisions)
5334 {
5335 	Entity *e = entity(L);
5336 	if (e)
5337 	{
5338 		dsq->game->handleShotCollisions(e);
5339 	}
5340 	luaReturnNil();
5341 }
5342 
luaFunc(entity_handleShotCollisionsSkeletal)5343 luaFunc(entity_handleShotCollisionsSkeletal)
5344 {
5345 	Entity *e = entity(L);
5346 	if (e)
5347 	{
5348 		dsq->game->handleShotCollisionsSkeletal(e);
5349 	}
5350 	luaReturnNil();
5351 }
5352 
luaFunc(entity_handleShotCollisionsHair)5353 luaFunc(entity_handleShotCollisionsHair)
5354 {
5355 	Entity *e = entity(L);
5356 	if (e)
5357 	{
5358 		dsq->game->handleShotCollisionsHair(e, lua_tointeger(L, 2), lua_tonumber(L, 3));
5359 	}
5360 	luaReturnNil();
5361 }
5362 
luaFunc(entity_collideSkeletalVsCircle)5363 luaFunc(entity_collideSkeletalVsCircle)
5364 {
5365 	Entity *e = entity(L);
5366 	RenderObject *e2 = robj(L,2);
5367 	Bone *b = 0;
5368 	if (e && e2)
5369 	{
5370 		b = dsq->game->collideSkeletalVsCircle(e,e2);
5371 	}
5372 	luaReturnPtr(b);
5373 }
5374 
luaFunc(entity_collideSkeletalVsCirclePos)5375 luaFunc(entity_collideSkeletalVsCirclePos)
5376 {
5377 	Entity *e = entity(L);
5378 	Bone *b = 0;
5379 	if (e)
5380 	{
5381 		b = dsq->game->collideSkeletalVsCircle(e, Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), lua_tonumber(L, 4));
5382 	}
5383 	luaReturnPtr(b);
5384 }
5385 
luaFunc(entity_collideSkeletalVsLine)5386 luaFunc(entity_collideSkeletalVsLine)
5387 {
5388 	Entity *e = entity(L);
5389 	int x1, y1, x2, y2, sz;
5390 	x1 = lua_tonumber(L, 2);
5391 	y1 = lua_tonumber(L, 3);
5392 	x2 = lua_tonumber(L, 4);
5393 	y2 = lua_tonumber(L, 5);
5394 	sz = lua_tonumber(L, 6);
5395 	Bone *b = 0;
5396 	if (e)
5397 	{
5398 		b = dsq->game->collideSkeletalVsLine(e, Vector(x1, y1), Vector(x2, y2), sz);
5399 	}
5400 	luaReturnPtr(b);
5401 }
5402 
luaFunc(entity_collideHairVsCircle)5403 luaFunc(entity_collideHairVsCircle)
5404 {
5405 	Entity *e = entity(L);
5406 	Entity *e2 = entity(L, 2);
5407 	bool col=false;
5408 	if (e && e2)
5409 	{
5410 		int num = lua_tointeger(L, 3);
5411 		// perc: percent of hairWidth to use as collide radius
5412 		float perc = lua_tonumber(L, 4);
5413 		int colSegment;
5414 		col = dsq->game->collideHairVsCircle(e, num, e2->position, e2->collideRadius, perc, &colSegment);
5415 		if(col)
5416 		{
5417 			lua_pushboolean(L, true);
5418 			lua_pushinteger(L, colSegment);
5419 			return 2;
5420 		}
5421 	}
5422 	luaReturnBool(false);
5423 }
5424 
luaFunc(entity_collideSkeletalVsCircleForListByName)5425 luaFunc(entity_collideSkeletalVsCircleForListByName)
5426 {
5427 	Entity *e = entity(L);
5428 	std::string name;
5429 	if (lua_isstring(L, 2))
5430 		name = lua_tostring(L, 2);
5431 	if (e && !name.empty())
5432 	{
5433 		FOR_ENTITIES(i)
5434 		{
5435 			Entity *e2 = *i;
5436 			if (e2->life == 1 && e2->name == name)
5437 			{
5438 				Bone *b = dsq->game->collideSkeletalVsCircle(e, e2);
5439 				if (b)
5440 				{
5441 					DamageData d;
5442 					d.attacker = e2;
5443 					d.bone = b;
5444 					e->damage(d);
5445 				}
5446 			}
5447 		}
5448 	}
5449 	luaReturnNil();
5450 }
5451 
luaFunc(entity_debugText)5452 luaFunc(entity_debugText)
5453 {
5454 	Entity *e = entity(L);
5455 	const char *txt = lua_tostring(L, 2);
5456 	if (e && txt)
5457 	{
5458 		BitmapText *f = new BitmapText(&dsq->smallFont);
5459 		f->setText(txt);
5460 		f->position = e->position;
5461 		core->getTopStateData()->addRenderObject(f, LR_DEBUG_TEXT);
5462 		f->setLife(5);
5463 		f->setDecayRate(1);
5464 		f->fadeAlphaWithLife=1;
5465 	}
5466 	luaReturnNil();
5467 }
5468 
luaFunc(entity_getHealth)5469 luaFunc(entity_getHealth)
5470 {
5471 	Entity *e = entity(L);
5472 	luaReturnNum(e ? e->health : 0);
5473 }
5474 
luaFunc(entity_getMaxHealth)5475 luaFunc(entity_getMaxHealth)
5476 {
5477 	Entity *e = entity(L);
5478 	luaReturnNum(e ? e->maxHealth : 0);
5479 }
5480 
luaFunc(entity_initSegments)5481 luaFunc(entity_initSegments)
5482 {
5483 	ScriptedEntity *se = scriptedEntity(L);
5484 	if (se)
5485 		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));
5486 
5487 	luaReturnNil();
5488 }
5489 
luaFunc(entity_warpSegments)5490 luaFunc(entity_warpSegments)
5491 {
5492 	ScriptedEntity *se = scriptedEntity(L);
5493 	if (se)
5494 		se->warpSegments();
5495 
5496 	luaReturnNil()
5497 }
5498 
luaFunc(avatar_incrLeaches)5499 luaFunc(avatar_incrLeaches)
5500 {
5501 	dsq->game->avatar->leaches++;
5502 	luaReturnNil();
5503 }
5504 
luaFunc(avatar_decrLeaches)5505 luaFunc(avatar_decrLeaches)
5506 {
5507 	// Not checking for underflow here because this allows some neat tricks.
5508 	dsq->game->avatar->leaches--;
5509 	luaReturnNil();
5510 }
5511 
luaFunc(entity_rotateToVel)5512 luaFunc(entity_rotateToVel)
5513 {
5514 	Entity *e = entity(L);
5515 	if (e)
5516 	{
5517 		if (!e->vel.isZero())
5518 		{
5519 			e->rotateToVec(e->vel, lua_tonumber(L, 2), lua_tointeger(L, 3));
5520 		}
5521 	}
5522 	luaReturnNil();
5523 }
5524 
luaFunc(entity_rotateToEntity)5525 luaFunc(entity_rotateToEntity)
5526 {
5527 	Entity *e = entity(L);
5528 	Entity *e2 = entity(L, 2);
5529 
5530 	if (e && e2)
5531 	{
5532 		Vector vec = e2->position - e->position;
5533 		if (!vec.isZero())
5534 		{
5535 			e->rotateToVec(vec, lua_tonumber(L, 3), lua_tointeger(L, 4));
5536 		}
5537 	}
5538 	luaReturnNil();
5539 }
5540 
luaFunc(entity_rotateToVec)5541 luaFunc(entity_rotateToVec)
5542 {
5543 	Entity *e = entity(L);
5544 	Vector vec(lua_tonumber(L, 2), lua_tonumber(L, 3));
5545 	if (e)
5546 	{
5547 		if (!vec.isZero())
5548 		{
5549 			e->rotateToVec(vec, lua_tonumber(L, 4), lua_tointeger(L, 5));
5550 		}
5551 	}
5552 	luaReturnNil();
5553 }
5554 
luaFunc(entity_updateSkeletal)5555 luaFunc(entity_updateSkeletal)
5556 {
5557 	Entity *e = entity(L);
5558 	if (e)
5559 	{
5560 		bool oldIgnore = e->skeletalSprite.ignoreUpdate;
5561 		e->skeletalSprite.ignoreUpdate = false;
5562 		e->skeletalSprite.update(lua_tonumber(L, 2));
5563 		e->skeletalSprite.ignoreUpdate = oldIgnore;
5564 	}
5565 	luaReturnNil();
5566 }
5567 
luaFunc(entity_msg)5568 luaFunc(entity_msg)
5569 {
5570 	Entity *e = entity(L);
5571 	if (e)
5572 	{
5573 		// pass everything on the stack except the entity pointer
5574 		int res = e->messageVariadic(L, lua_gettop(L) - 1);
5575 		if (res >= 0)
5576 			return res;
5577 	}
5578 	luaReturnNil();
5579 }
5580 
luaFunc(node_msg)5581 luaFunc(node_msg)
5582 {
5583 	Path *p = path(L);
5584 	if (p)
5585 	{
5586 		// pass everything on the stack except the entity pointer
5587 		int res = p->messageVariadic(L, lua_gettop(L) - 1);
5588 		if (res >= 0)
5589 			return res;
5590 	}
5591 	luaReturnNil();
5592 }
5593 
luaFunc(entity_updateCurrents)5594 luaFunc(entity_updateCurrents)
5595 {
5596 	Entity *e = entity(L);
5597 	luaReturnBool(e ? e->updateCurrents(lua_tonumber(L, 2)) : false);
5598 }
5599 
luaFunc(entity_updateLocalWarpAreas)5600 luaFunc(entity_updateLocalWarpAreas)
5601 {
5602 	Entity *e = entity(L);
5603 	luaReturnBool(e ? e->updateLocalWarpAreas(getBool(L, 2)) : false);
5604 }
5605 
luaFunc(entity_updateMovement)5606 luaFunc(entity_updateMovement)
5607 {
5608 	ScriptedEntity *e = scriptedEntity(L);
5609 	if (e)
5610 		e->updateMovement(lua_tonumber(L, 2));
5611 	luaReturnNil();
5612 }
5613 
luaFunc(entity_applySurfaceNormalForce)5614 luaFunc(entity_applySurfaceNormalForce)
5615 {
5616 	Entity *e = entity(L);
5617 	if (e)
5618 	{
5619 		Vector v;
5620 		if (!e->ridingOnEntity)
5621 		{
5622 			v = dsq->game->getWallNormal(e->position, 8);
5623 		}
5624 		else
5625 		{
5626 			v = e->position - e->ridingOnEntity->position;
5627 			e->ridingOnEntity = 0;
5628 		}
5629 		v.setLength2D(lua_tointeger(L, 2));
5630 		e->vel += v;
5631 	}
5632 	luaReturnNil();
5633 }
5634 
luaFunc(entity_doElementInteraction)5635 luaFunc(entity_doElementInteraction)
5636 {
5637 	Entity *e = entity(L);
5638 	if (e)
5639 	{
5640 		float mult = lua_tonumber(L, 2);
5641 		float touchWidth = lua_tonumber(L, 3);
5642 		if (!touchWidth)
5643 			touchWidth = 16;
5644 
5645 		ElementUpdateList& elems = dsq->game->elementInteractionList;
5646 		for (ElementUpdateList::iterator it = elems.begin(); it != elems.end(); ++it)
5647 		{
5648 			(*it)->doInteraction(e, mult, touchWidth);
5649 		}
5650 	}
5651 	luaReturnNil();
5652 }
5653 
luaFunc(avatar_setElementEffectMult)5654 luaFunc(avatar_setElementEffectMult)
5655 {
5656 	dsq->game->avatar->elementEffectMult = lua_tonumber(L, 1);
5657 	luaReturnNil();
5658 }
5659 
luaFunc(flingMonkey)5660 luaFunc(flingMonkey)
5661 {
5662 	Entity *e = entity(L);
5663 
5664 	dsq->continuity.flingMonkey(e);
5665 
5666 	luaReturnNil();
5667 }
5668 
luaFunc(entity_getDistanceToTarget)5669 luaFunc(entity_getDistanceToTarget)
5670 {
5671 	Entity *e = entity(L);
5672 	float dist = 0;
5673 	if (e)
5674 	{
5675 		Entity *t = e->getTargetEntity();
5676 		if (t)
5677 		{
5678 			dist = (t->position - e->position).getLength2D();
5679 		}
5680 	}
5681 	luaReturnNum(dist);
5682 }
5683 
luaFunc(entity_getDistanceToPoint)5684 luaFunc(entity_getDistanceToPoint)
5685 {
5686 	Entity *e = entity(L);
5687 	float dist = 0;
5688 	if (e)
5689 	{
5690 		Vector p(lua_tonumber(L, 2), lua_tonumber(L, 3));
5691 		dist = (p - e->position).getLength2D();
5692 	}
5693 	luaReturnNum(dist);
5694 }
5695 
luaFunc(entity_watchEntity)5696 luaFunc(entity_watchEntity)
5697 {
5698 	Entity *e = entity(L);
5699 	Entity *e2 = 0;
5700 	if (lua_touserdata(L, 2) != NULL)
5701 		e2 = entity(L, 2);
5702 
5703 	if (e)
5704 	{
5705 		e->watchEntity(e2);
5706 	}
5707 	luaReturnNil();
5708 }
5709 
luaFunc(setNaijaHeadTexture)5710 luaFunc(setNaijaHeadTexture)
5711 {
5712 	Avatar *a = dsq->game->avatar;
5713 	if (a)
5714 	{
5715 		a->setHeadTexture(getString(L, 1), lua_tonumber(L, 2));
5716 	}
5717 	luaReturnNil();
5718 }
5719 
luaFunc(entity_flipToSame)5720 luaFunc(entity_flipToSame)
5721 {
5722 	Entity *e = entity(L);
5723 	Entity *e2 = entity(L, 2);
5724 	if (e && e2)
5725 	{
5726 		if ((e->isfh() && !e2->isfh())
5727 			|| (!e->isfh() && e2->isfh()))
5728 		{
5729 			e->flipHorizontal();
5730 		}
5731 	}
5732 	luaReturnNil();
5733 }
5734 
luaFunc(entity_flipToEntity)5735 luaFunc(entity_flipToEntity)
5736 {
5737 	Entity *e = entity(L);
5738 	Entity *e2 = entity(L, 2);
5739 	if (e && e2)
5740 	{
5741 		e->flipToTarget(e2->position);
5742 	}
5743 	luaReturnNil();
5744 }
5745 
luaFunc(entity_flipToNode)5746 luaFunc(entity_flipToNode)
5747 {
5748 	Entity *e = entity(L);
5749 	Path *p = path(L, 2);
5750 	PathNode *n = &p->nodes[0];
5751 	if (e && n)
5752 	{
5753 		e->flipToTarget(n->position);
5754 	}
5755 	luaReturnNil();
5756 }
5757 
luaFunc(entity_flipToVel)5758 luaFunc(entity_flipToVel)
5759 {
5760 	Entity *e = entity(L);
5761 	if (e)
5762 	{
5763 		e->flipToVel();
5764 	}
5765 	luaReturnNil();
5766 }
5767 
luaFunc(node_isEntityIn)5768 luaFunc(node_isEntityIn)
5769 {
5770 	Path *p = path(L,1);
5771 	Entity *e = entity(L,2);
5772 
5773 	bool v = false;
5774 	if (e && p)
5775 	{
5776 		if (!p->nodes.empty())
5777 		{
5778 			v = p->isCoordinateInside(e->position);
5779 			//(e->position - p->nodes[0].position);
5780 		}
5781 	}
5782 	luaReturnBool(v);
5783 }
5784 
luaFunc(node_isPositionIn)5785 luaFunc(node_isPositionIn)
5786 {
5787 	Path *p = path(L,1);
5788 	float x = lua_tonumber(L, 2);
5789 	float y = lua_tonumber(L, 3);
5790 
5791 	bool v = false;
5792 	if (p)
5793 	{
5794 		if (!p->nodes.empty())
5795 		{
5796 			v = p->rect.isCoordinateInside(Vector(x,y) - p->nodes[0].position);
5797 		}
5798 	}
5799 	luaReturnBool(v);
5800 }
5801 
luaFunc(entity_isInDarkness)5802 luaFunc(entity_isInDarkness)
5803 {
5804 	Entity *e = entity(L);
5805 	bool d = false;
5806 	if (e)
5807 	{
5808 		d = e->isInDarkness();
5809 	}
5810 	luaReturnBool(d);
5811 }
5812 
luaFunc(entity_isInRect)5813 luaFunc(entity_isInRect)
5814 {
5815 	Entity *e = entity(L);
5816 	bool v= false;
5817 	float x1, y1, x2, y2;
5818 	x1 = lua_tonumber(L, 2);
5819 	y1 = lua_tonumber(L, 3);
5820 	x2 = lua_tonumber(L, 4);
5821 	y2 = lua_tonumber(L, 5);
5822 	if (e)
5823 	{
5824 		if (e->position.x > x1 && e->position.x < x2)
5825 		{
5826 			if (e->position.y > y1 && e->position.y < y2)
5827 			{
5828 				v = true;
5829 			}
5830 		}
5831 	}
5832 	luaReturnBool(v);
5833 }
5834 
luaFunc(createQuad)5835 luaFunc(createQuad)
5836 {
5837 	PauseQuad *q = new PauseQuad();
5838 	q->setTexture(getString(L, 1));
5839 	int layer = lua_tointeger(L, 2);
5840 	if (layer == 13)
5841 		layer = 13;
5842 	else
5843 		layer = (LR_PARTICLES+1) - LR_ELEMENTS1;
5844 	dsq->game->addRenderObject(q, LR_ELEMENTS1+(layer-1));
5845 	q->moveToFront();
5846 
5847 	luaReturnPtr(q);
5848 }
5849 
luaFunc(quad_setPauseLevel)5850 luaFunc(quad_setPauseLevel)
5851 {
5852 	Quad *q = getQuad(L);
5853 	ENSURE_TYPE(q, SCO_PAUSEQUAD);
5854 	if (q)
5855 		((PauseQuad*)q)->pauseLevel = lua_tointeger(L, 2);
5856 	luaReturnNil();
5857 }
5858 
luaFunc(setupEntity)5859 luaFunc(setupEntity)
5860 {
5861 	ScriptedEntity *se = scriptedEntity(L);
5862 	if (se)
5863 	{
5864 		std::string tex;
5865 		if (lua_isstring(L, 2))
5866 		{
5867 			tex = lua_tostring(L, 2);
5868 		}
5869 		se->setupEntity(tex, lua_tonumber(L, 3));
5870 	}
5871 	luaReturnNil();
5872 }
5873 
luaFunc(setupBasicEntity)5874 luaFunc(setupBasicEntity)
5875 {
5876 	ScriptedEntity *se = scriptedEntity(L);
5877 	//-- texture, health, manaballamount, exp, money, collideRadius, initState
5878 	if (se)
5879 		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));
5880 
5881 	luaReturnNil();
5882 }
5883 
luaFunc(entity_setBeautyFlip)5884 luaFunc(entity_setBeautyFlip)
5885 {
5886 	Entity *e = entity(L);
5887 	if (e)
5888 	{
5889 		e->beautyFlip = getBool(L, 2);
5890 	}
5891 	luaReturnNil();
5892 }
5893 
luaFunc(setInvincible)5894 luaFunc(setInvincible)
5895 {
5896 	dsq->game->invinciblity = getBool(L, 1);
5897 
5898 	luaReturnBool(dsq->game->invinciblity);
5899 }
5900 
luaFunc(entity_setInvincible)5901 luaFunc(entity_setInvincible)
5902 {
5903 	Entity *e = entity(L);
5904 	if (e)
5905 	{
5906 		e->setInvincible(getBool(L, 2));
5907 
5908 	}
5909 	luaReturnNil();
5910 }
5911 
luaFunc(entity_setDeathSound)5912 luaFunc(entity_setDeathSound)
5913 {
5914 	Entity *e = entity(L);
5915 	if (e)
5916 	{
5917 		e->deathSound = getString(L, 2);
5918 	}
5919 	luaReturnNil();
5920 }
5921 
luaFunc(entity_setDeathParticleEffect)5922 luaFunc(entity_setDeathParticleEffect)
5923 {
5924 	ScriptedEntity *se = scriptedEntity(L);
5925 	if (se)
5926 	{
5927 		se->deathParticleEffect = getString(L, 2);
5928 	}
5929 	luaReturnNil();
5930 }
5931 
luaFunc(entity_setNaijaReaction)5932 luaFunc(entity_setNaijaReaction)
5933 {
5934 	Entity *e = entity(L);
5935 	std::string s;
5936 	if (lua_isstring(L, 2))
5937 		s = lua_tostring(L, 2);
5938 	if (e)
5939 	{
5940 		e->naijaReaction = s;
5941 	}
5942 	luaReturnNil();
5943 }
5944 
luaFunc(entity_setName)5945 luaFunc(entity_setName)
5946 {
5947 	Entity *e = entity(L);
5948 	std::string s;
5949 	if (lua_isstring(L, 2))
5950 		s = lua_tostring(L, 2);
5951 	if (e)
5952 	{
5953 		debugLog("setting entity name to: " + s);
5954 		e->setName(s);
5955 	}
5956 	luaReturnNil();
5957 }
5958 
luaFunc(entity_pathBurst)5959 luaFunc(entity_pathBurst)
5960 {
5961 	Entity *e = entity(L);
5962 	bool v = false;
5963 	if (e)
5964 		v = e->pathBurst(lua_tointeger(L, 2));
5965 	luaReturnBool(v);
5966 }
5967 
luaFunc(entity_moveTowardsAngle)5968 luaFunc(entity_moveTowardsAngle)
5969 {
5970 	Entity *e = entity(L);
5971 	if (e)
5972 		e->moveTowardsAngle(lua_tointeger(L, 2), lua_tonumber(L, 3), lua_tointeger(L, 4));
5973 	luaReturnNil();
5974 }
5975 
luaFunc(entity_moveAroundAngle)5976 luaFunc(entity_moveAroundAngle)
5977 {
5978 	Entity *e = entity(L);
5979 	if (e)
5980 		e->moveTowardsAngle(lua_tointeger(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4));
5981 	luaReturnNil();
5982 }
5983 
luaFunc(entity_moveTowards)5984 luaFunc(entity_moveTowards)
5985 {
5986 	Entity *e = entity(L);
5987 	if (e)
5988 		e->moveTowards(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), lua_tonumber(L, 4), lua_tonumber(L, 5));
5989 	luaReturnNil();
5990 }
5991 
luaFunc(entity_moveAround)5992 luaFunc(entity_moveAround)
5993 {
5994 	Entity *e = entity(L);
5995 	if (e)
5996 		e->moveAround(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6));
5997 	luaReturnNil();
5998 }
5999 
luaFunc(entity_addVel2)6000 luaFunc(entity_addVel2)
6001 {
6002 	Entity *e = entity(L);
6003 	if (e)
6004 		e->vel2 += Vector(lua_tonumber(L, 2), lua_tonumber(L, 3));
6005 	luaReturnNil();
6006 }
6007 
luaFunc(entity_setVel2)6008 luaFunc(entity_setVel2)
6009 {
6010 	Entity *e = entity(L);
6011 	if (e)
6012 	{
6013 		e->vel2 = Vector(lua_tonumber(L, 2), lua_tonumber(L, 3));
6014 	}
6015 	luaReturnNil();
6016 }
6017 
luaFunc(entity_getVel2Len)6018 luaFunc(entity_getVel2Len)
6019 {
6020 	Entity *e = entity(L);
6021 	luaReturnNum(e ? e->vel2.getLength2D() : 0.0f);
6022 }
6023 
luaFunc(entity_setVel2Len)6024 luaFunc(entity_setVel2Len)
6025 {
6026 	Entity *e = entity(L);
6027 	if(e)
6028 		e->vel2.setLength2D(lua_tonumber(L, 2));
6029 	luaReturnNil();
6030 };
6031 
luaFunc(entity_getVel2)6032 luaFunc(entity_getVel2)
6033 {
6034 	Entity *e = entity(L);
6035 	Vector vel2;
6036 	if(e)
6037 		vel2 = e->vel2;
6038 	luaReturnVec2(vel2.x, vel2.y);
6039 }
6040 
luaFunc(entity_isValidTarget)6041 luaFunc(entity_isValidTarget)
6042 {
6043 	Entity *e = entity(L);
6044 	Entity *e2 = 0;
6045 	if (lua_tonumber(L, 2)!=0)
6046 		e2 = entity(L);
6047 	bool b = false;
6048 	if (e)
6049 		b = dsq->game->isValidTarget(e, e2);
6050 	luaReturnBool(b);
6051 }
luaFunc(entity_clearVel2)6052 luaFunc(entity_clearVel2)
6053 {
6054 	Entity *e = entity(L);
6055 	if (e)
6056 		e->vel2 = Vector(0,0,0);
6057 	luaReturnNil();
6058 }
6059 
luaFunc(getScreenCenter)6060 luaFunc(getScreenCenter)
6061 {
6062 	luaReturnVec2(core->screenCenter.x, core->screenCenter.y);
6063 }
6064 
luaFunc(entity_isState)6065 luaFunc(entity_isState)
6066 {
6067 	Entity *e = entity(L);
6068 	bool v=false;
6069 	if (e)
6070 	{
6071 		v = (e->getState() == lua_tointeger(L, 2));
6072 	}
6073 	luaReturnBool(v);
6074 }
6075 
luaFunc(entity_getState)6076 luaFunc(entity_getState)
6077 {
6078 	Entity *e = entity(L);
6079 	int state = 0;
6080 	if (e)
6081 		state = e->getState();
6082 	luaReturnNum(state);
6083 }
6084 
luaFunc(entity_getEnqueuedState)6085 luaFunc(entity_getEnqueuedState)
6086 {
6087 	Entity *e = entity(L);
6088 	int state = 0;
6089 	if (e)
6090 		state = e->getEnqueuedState();
6091 	luaReturnNum(state);
6092 }
6093 
luaFunc(entity_getPrevState)6094 luaFunc(entity_getPrevState)
6095 {
6096 	Entity *e = entity(L);
6097 	int state = 0;
6098 	if (e)
6099 		state = e->getPrevState();
6100 	luaReturnNum(state);
6101 }
6102 
luaFunc(entity_setTarget)6103 luaFunc(entity_setTarget)
6104 {
6105 	Entity *e = entity(L);
6106 	Entity *t = 0;
6107 	if (lua_touserdata(L, 2) != NULL)
6108 	{
6109 		t = entity(L, 2);
6110 	}
6111 	if (e)
6112 	{
6113 		e->setTargetEntity(t);
6114 	}
6115 	luaReturnNil();
6116 }
6117 
luaFunc(entity_setBounce)6118 luaFunc(entity_setBounce)
6119 {
6120 	CollideEntity *e = collideEntity(L);
6121 	if (e)
6122 		e->bounceAmount = lua_tonumber(L, 2);
6123 	luaReturnNil();
6124 }
6125 
luaFunc(avatar_isSinging)6126 luaFunc(avatar_isSinging)
6127 {
6128 	bool b = dsq->game->avatar->isSinging();
6129 	luaReturnBool(b);
6130 }
6131 
luaFunc(avatar_isTouchHit)6132 luaFunc(avatar_isTouchHit)
6133 {
6134 	//avatar_canBeTouchHit
6135 	bool b = !(dsq->game->avatar->bursting && dsq->continuity.form == FORM_BEAST);
6136 	luaReturnBool(b);
6137 }
6138 
luaFunc(avatar_clampPosition)6139 luaFunc(avatar_clampPosition)
6140 {
6141 	dsq->game->avatar->clampPosition();
6142 	luaReturnNil();
6143 }
6144 
luaFunc(entity_setMaxSpeed)6145 luaFunc(entity_setMaxSpeed)
6146 {
6147 	Entity *e = entity(L);
6148 	if (e)
6149 		e->setMaxSpeed(lua_tonumber(L, 2));
6150 
6151 	luaReturnNil();
6152 }
6153 
luaFunc(entity_getMaxSpeed)6154 luaFunc(entity_getMaxSpeed)
6155 {
6156 	Entity *e = entity(L);
6157 	int v = 0;
6158 	if (e)
6159 		v = e->getMaxSpeed();
6160 
6161 	luaReturnNum(v);
6162 }
6163 
luaFunc(entity_setMaxSpeedLerp)6164 luaFunc(entity_setMaxSpeedLerp)
6165 {
6166 	Entity *e = entity(L);
6167 	if (e)
6168 		interpolateVec1(L, e->maxSpeedLerp, 2);
6169 
6170 	luaReturnNil();
6171 }
6172 
luaFunc(entity_getMaxSpeedLerp)6173 luaFunc(entity_getMaxSpeedLerp)
6174 {
6175 	Entity *e = entity(L);
6176 	luaReturnNum(e ? e->maxSpeedLerp.x : 0.0f);
6177 }
6178 
6179 // note: this is a weaker setState than perform
6180 // this is so that things can override it
6181 // for example getting PUSH-ed (Force) or FROZEN (bubbled)
luaFunc(entity_setState)6182 luaFunc(entity_setState)
6183 {
6184 	Entity *me = entity(L);
6185 	if (me)
6186 	{
6187 		int state = lua_tointeger(L, 2);
6188 		float time = lua_tonumber(L, 3);
6189 		if (time == 0)
6190 			time = -1;
6191 		bool force = getBool(L, 4);
6192 		me->setState(state, time, force);
6193 	}
6194 	luaReturnNil();
6195 }
6196 
luaFunc(entity_getBoneByIdx)6197 luaFunc(entity_getBoneByIdx)
6198 {
6199 	Entity *e = entity(L);
6200 	Bone *b = 0;
6201 	if (e)
6202 	{
6203 		int n = 0;
6204 		if (lua_isnumber(L, 2))
6205 		{
6206 			n = lua_tointeger(L, 2);
6207 			b = e->skeletalSprite.getBoneByIdx(n);
6208 		}
6209 	}
6210 	luaReturnPtr(b);
6211 }
6212 
luaFunc(entity_getBoneByName)6213 luaFunc(entity_getBoneByName)
6214 {
6215 	Entity *e = entity(L);
6216 	luaReturnPtr(e ? e->skeletalSprite.getBoneByName(getString(L, 2)) : NULL);
6217 }
6218 
luaFunc(entity_getBoneByInternalId)6219 luaFunc(entity_getBoneByInternalId)
6220 {
6221 	Entity *e = entity(L);
6222 	if(!e)
6223 		luaReturnPtr(NULL);
6224 	size_t i = lua_tointeger(L, 1);
6225 	if(i >= e->skeletalSprite.bones.size())
6226 		luaReturnPtr(NULL);
6227 	luaReturnPtr(e->skeletalSprite.bones[i]);
6228 }
6229 
luaFunc(entity_getNumBones)6230 luaFunc(entity_getNumBones)
6231 {
6232 	Entity *e = entity(L);
6233 	luaReturnInt(e ? (int)e->skeletalSprite.bones.size() : 0);
6234 }
6235 
luaFunc(bone_getIndex)6236 luaFunc(bone_getIndex)
6237 {
6238 	Bone *b = bone(L);
6239 	int idx = -1;
6240 	if (b)
6241 		idx = b->boneIdx;
6242 	luaReturnNum(idx);
6243 }
6244 
luaFunc(bone_getName)6245 luaFunc(bone_getName)
6246 {
6247 	const char *n = "";
6248 	Bone *b = bone(L);
6249 	if (b)
6250 	{
6251 		n = b->name.c_str();
6252 	}
6253 	luaReturnStr(n);
6254 }
6255 
luaFunc(bone_isName)6256 luaFunc(bone_isName)
6257 {
6258 	Bone *b = bone(L);
6259 	bool v = false;
6260 	const char *s = lua_tostring(L, 2);
6261 	if (b && s)
6262 	{
6263 		v = b->name == s;
6264 	}
6265 	luaReturnBool(v);
6266 }
6267 
luaFunc(overrideZoom)6268 luaFunc(overrideZoom)
6269 {
6270 	dsq->game->overrideZoom(lua_tonumber(L, 1), lua_tonumber(L, 2));
6271 
6272 	luaReturnNil();
6273 }
6274 
luaFunc(getZoom)6275 luaFunc(getZoom)
6276 {
6277 	luaReturnNum(dsq->globalScale.x);
6278 }
6279 
luaFunc(disableOverrideZoom)6280 luaFunc(disableOverrideZoom)
6281 {
6282 	dsq->game->toggleOverrideZoom(false);
6283 	luaReturnNil();
6284 }
6285 
luaFunc(setMaxLookDistance)6286 luaFunc(setMaxLookDistance)
6287 {
6288 	dsq->game->maxLookDistance = lua_tonumber(L, 1);
6289 	luaReturnNil();
6290 }
6291 
6292 
6293 // dt, range, mod
luaFunc(entity_doSpellAvoidance)6294 luaFunc(entity_doSpellAvoidance)
6295 {
6296 	Entity *e = entity(L);
6297 	if (e)
6298 		e->doSpellAvoidance(lua_tonumber(L, 2), lua_tointeger(L, 3), lua_tonumber(L, 4));
6299 	luaReturnNil();
6300 }
6301 
6302 // dt, range, mod, ignore
luaFunc(entity_doEntityAvoidance)6303 luaFunc(entity_doEntityAvoidance)
6304 {
6305 	Entity *e = entity(L);
6306 	if (e)
6307 		e->doEntityAvoidance(lua_tonumber(L, 2), lua_tointeger(L, 3), lua_tonumber(L, 4), e->getTargetEntity());
6308 	luaReturnNil();
6309 }
6310 
6311 // doCollisionAvoidance(me, dt, search, mod)
luaFunc(entity_doCollisionAvoidance)6312 luaFunc(entity_doCollisionAvoidance)
6313 {
6314 	Entity *e = entity(L);
6315 	bool ret = false;
6316 
6317 	bool useVel2 = getBool(L, 6);
6318 	bool onlyVP = getBool(L, 7);
6319 	int ignoreObs = lua_tointeger(L, 8);
6320 
6321 	if (e)
6322 	{
6323 		if (useVel2)
6324 			ret = e->doCollisionAvoidance(lua_tonumber(L, 2), lua_tointeger(L, 3), lua_tonumber(L, 4), &e->vel2, lua_tonumber(L, 5), ignoreObs, onlyVP);
6325 		else
6326 			ret = e->doCollisionAvoidance(lua_tonumber(L, 2), lua_tointeger(L, 3), lua_tonumber(L, 4), 0, lua_tonumber(L, 5), ignoreObs);
6327 	}
6328 	luaReturnBool(ret);
6329 }
6330 
luaFunc(setOverrideMusic)6331 luaFunc(setOverrideMusic)
6332 {
6333 	dsq->game->overrideMusic = getString(L, 1);
6334 	luaReturnNil();
6335 }
6336 
luaFunc(setOverrideVoiceFader)6337 luaFunc(setOverrideVoiceFader)
6338 {
6339 	dsq->sound->setOverrideVoiceFader(lua_tonumber(L, 1));
6340 	luaReturnNil();
6341 }
6342 
luaFunc(setGameSpeed)6343 luaFunc(setGameSpeed)
6344 {
6345 	dsq->gameSpeed.stop();
6346 	dsq->gameSpeed.stopPath();
6347 	interpolateVec1(L, dsq->gameSpeed, 1);
6348 	luaReturnNil();
6349 }
6350 
luaFunc(bedEffects)6351 luaFunc(bedEffects)
6352 {
6353 	dsq->overlay->alpha.interpolateTo(1, 2);
6354 	dsq->sound->fadeMusic(SFT_OUT, 1);
6355 	core->main(1);
6356 	// music goes here
6357 	dsq->sound->fadeMusic(SFT_CROSS, 1);
6358 	dsq->sound->playMusic("Sleep");
6359 	core->main(6);
6360 	Vector bedPosition(lua_tointeger(L, 1), lua_tointeger(L, 2));
6361 	if (bedPosition.x == 0 && bedPosition.y == 0)
6362 	{
6363 		bedPosition = dsq->game->avatar->position;
6364 	}
6365 	dsq->game->positionToAvatar = bedPosition;
6366 	dsq->game->transitionToScene(dsq->game->sceneName);
6367 
6368 	luaReturnNil();
6369 }
6370 
luaFunc(entity_setDeathScene)6371 luaFunc(entity_setDeathScene)
6372 {
6373 	Entity *e = entity(L);
6374 	if (e)
6375 	{
6376 		e->setDeathScene(getBool(L, 2));
6377 	}
6378 	luaReturnNil();
6379 }
6380 
luaFunc(entity_isDeathScene)6381 luaFunc(entity_isDeathScene)
6382 {
6383 	Entity *e = entity(L);
6384 	luaReturnBool(e ? e->isDeathScene() : false);
6385 }
6386 
luaFunc(entity_setCurrentTarget)6387 luaFunc(entity_setCurrentTarget)
6388 {
6389 	Entity *e = entity(L);
6390 	if (e)
6391 		e->currentEntityTarget = lua_tointeger(L, 2);
6392 	luaReturnNil();
6393 }
6394 
luaFunc(setMiniMapHint)6395 luaFunc(setMiniMapHint)
6396 {
6397 	std::istringstream is(getString(L, 1));
6398 	is >> dsq->game->miniMapHint.scene >> dsq->game->miniMapHint.warpAreaType;
6399 	dsq->game->updateMiniMapHintPosition();
6400 
6401 	luaReturnNil();
6402 }
6403 
luaFunc(entityFollowEntity)6404 luaFunc(entityFollowEntity)
6405 {
6406 	Entity *e = dsq->getEntityByName(getString(L, 1));
6407 	if (e)
6408 	{
6409 		e->followEntity = dsq->getEntityByName(getString(L, 2));
6410 	}
6411 
6412 	luaReturnNil();
6413 }
6414 
luaFunc(entity_isFollowingEntity)6415 luaFunc(entity_isFollowingEntity)
6416 {
6417 	Entity *e = entity(L);
6418 	bool v = false;
6419 	if (e)
6420 		v = e->followEntity != 0;
6421 	luaReturnBool(v);
6422 }
6423 
luaFunc(entity_followEntity)6424 luaFunc(entity_followEntity)
6425 {
6426 	Entity *e1 = entity(L);
6427 	Entity *e2 = 0;
6428 	if (lua_touserdata(L, 2) != NULL)
6429 	{
6430 		e2 = entity(L, 2);
6431 	}
6432 	if (e1)
6433 	{
6434 		e1->followEntity = e2;
6435 		e1->followPos = lua_tointeger(L, 3);
6436 	}
6437 	luaReturnNil();
6438 }
6439 
luaFunc(toggleInput)6440 luaFunc(toggleInput)
6441 {
6442 	bool v = getBool(L, 1);
6443 	if (v)
6444 		dsq->game->avatar->enableInput();
6445 	else
6446 		dsq->game->avatar->disableInput();
6447 	luaReturnNil();
6448 }
6449 
luaFunc(warpAvatar)6450 luaFunc(warpAvatar)
6451 {
6452 	dsq->game->positionToAvatar = Vector(lua_tointeger(L, 2),lua_tointeger(L, 3));
6453 	dsq->game->transitionToScene(getString(L, 1));
6454 
6455 	luaReturnNil();
6456 }
6457 
luaFunc(warpNaijaToSceneNode)6458 luaFunc(warpNaijaToSceneNode)
6459 {
6460 	std::string scene = getString(L, 1);
6461 	std::string node = getString(L, 2);
6462 	std::string flip = getString(L, 3);
6463 	if (!scene.empty() && !node.empty())
6464 	{
6465 		dsq->game->toNode = node;
6466 		stringToLower(flip);
6467 		if (flip == "l")
6468 			dsq->game->toFlip = 0;
6469 		if (flip == "r")
6470 			dsq->game->toFlip = 1;
6471 		dsq->game->transitionToScene(scene);
6472 	}
6473 
6474 	luaReturnNil();
6475 }
6476 
luaFunc(entity_setDamageTarget)6477 luaFunc(entity_setDamageTarget)
6478 {
6479 	Entity *e = entity(L);
6480 	if (e)
6481 	{
6482 		e->setDamageTarget((DamageType)lua_tointeger(L, 2), getBool(L, 3));
6483 	}
6484 	luaReturnNil();
6485 }
6486 
luaFunc(entity_setAllDamageTargets)6487 luaFunc(entity_setAllDamageTargets)
6488 {
6489 	Entity *e = entity(L);
6490 	if (e)
6491 	{
6492 		e->setAllDamageTargets(getBool(L, 2));
6493 	}
6494 	luaReturnNil();
6495 }
6496 
luaFunc(entity_isDamageTarget)6497 luaFunc(entity_isDamageTarget)
6498 {
6499 	Entity *e = entity(L);
6500 	bool v=false;
6501 	if (e)
6502 	{
6503 		v = e->isDamageTarget((DamageType)lua_tointeger(L, 2));
6504 	}
6505 	luaReturnBool(v);
6506 }
6507 
luaFunc(entity_setTargetRange)6508 luaFunc(entity_setTargetRange)
6509 {
6510 	Entity *e = entity(L);
6511 	if (e)
6512 	{
6513 		e->targetRange = lua_tonumber(L, 2);
6514 	}
6515 	luaReturnNil();
6516 }
6517 
luaFunc(entity_getTargetRange)6518 luaFunc(entity_getTargetRange)
6519 {
6520 	Entity *e = entity(L);
6521 	luaReturnInt(e ? e->getTargetRange() : 0);
6522 }
6523 
luaFunc(entity_clearTargetPoints)6524 luaFunc(entity_clearTargetPoints)
6525 {
6526 	Entity *e = entity(L);
6527 	if (e)
6528 		e->clearTargetPoints();
6529 	luaReturnNil();
6530 }
6531 
luaFunc(entity_addTargetPoint)6532 luaFunc(entity_addTargetPoint)
6533 {
6534 	Entity *e = entity(L);
6535 	if (e)
6536 		e->addTargetPoint(Vector(lua_tonumber(L,2), lua_tonumber(L, 3)));
6537 	luaReturnNil();
6538 }
6539 
luaFunc(entity_getTargetPoint)6540 luaFunc(entity_getTargetPoint)
6541 {
6542 	Entity *e = entity(L);
6543 	int idx = lua_tointeger(L, 2);
6544 	Vector v;
6545 	if (e)
6546 	{
6547 		v = e->getTargetPoint(idx);
6548 	}
6549 	luaReturnVec2(v.x, v.y);
6550 }
6551 
luaFunc(entity_getRandomTargetPoint)6552 luaFunc(entity_getRandomTargetPoint)
6553 {
6554 	Entity *e = entity(L);
6555 	Vector v;
6556 	int idx = 0;
6557 	if (e)
6558 	{
6559 		idx = e->getRandomTargetPoint();
6560 	}
6561 	luaReturnNum(idx);
6562 }
6563 
luaFunc(entity_getNumTargetPoints)6564 luaFunc(entity_getNumTargetPoints)
6565 {
6566 	Entity *e = entity(L);
6567 	luaReturnInt(e ? e->getNumTargetPoints() : 0);
6568 }
6569 
luaFunc(playVisualEffect)6570 luaFunc(playVisualEffect)
6571 {
6572 	Entity *target = NULL;
6573 	if(lua_isuserdata(L, 4))
6574 		target = entity(L, 4);
6575 	dsq->playVisualEffect(lua_tonumber(L, 1), Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), target);
6576 	luaReturnNil();
6577 }
6578 
luaFunc(playNoEffect)6579 luaFunc(playNoEffect)
6580 {
6581 	dsq->playNoEffect();
6582 	luaReturnNil();
6583 }
6584 
luaFunc(createShockEffect)6585 luaFunc(createShockEffect)
6586 {
6587 	if (core->afterEffectManager)
6588 	{
6589 		core->afterEffectManager->addEffect(new ShockEffect(
6590 			Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)), // position
6591 			Vector(lua_tonumber(L, 3), lua_tonumber(L, 4)), // original position
6592 			lua_tonumber(L, 5),   // amplitude
6593 			lua_tonumber(L, 6),   // amplitude decay
6594 			lua_tonumber(L, 7),   // frequency
6595 			lua_tonumber(L, 8),   // wave length
6596 			lua_tonumber(L, 9))); // time multiplier
6597 	}
6598 	luaReturnNil();
6599 }
6600 
luaFunc(emote)6601 luaFunc(emote)
6602 {
6603 	int emote = lua_tointeger(L, 1);
6604 	dsq->emote.playSfx(emote);
6605 	luaReturnNil();
6606 }
6607 
luaFunc(playSfx)6608 luaFunc(playSfx)
6609 {
6610 	PlaySfx sfx;
6611 	sfx.name = getString(L, 1);
6612 	sfx.freq = lua_tonumber(L, 2);
6613 	sfx.vol = lua_tonumber(L, 3);
6614 	if (sfx.vol <= 0)
6615 		sfx.vol = 1;
6616 	sfx.loops = lua_tointeger(L, 4);
6617 	if(lua_isnumber(L, 5) && lua_isnumber(L, 6))
6618 	{
6619 		sfx.x = lua_tonumber(L, 5);
6620 		sfx.y =  lua_tonumber(L, 6);
6621 		sfx.positional = true;
6622 	}
6623 	sfx.maxdist = lua_tonumber(L, 7);
6624 	if(lua_isnoneornil(L, 8))
6625 		sfx.relative = (sfx.x == 0 && sfx.y == 0);
6626 	else
6627 		sfx.relative = getBool(L, 8);
6628 
6629 	void *handle = NULL;
6630 
6631 	if (!dsq->isSkippingCutscene())
6632 	{
6633 		handle = core->sound->playSfx(sfx);
6634 	}
6635 
6636 	luaReturnPtr(handle);
6637 }
6638 
luaFunc(fadeSfx)6639 luaFunc(fadeSfx)
6640 {
6641 	void *header = lua_touserdata(L, 1);
6642 	float ft = lua_tonumber(L, 2);
6643 
6644 	core->sound->fadeSfx(header, SFT_OUT, ft);
6645 
6646 	luaReturnPtr(header);
6647 }
6648 
luaFunc(resetTimer)6649 luaFunc(resetTimer)
6650 {
6651 	dsq->resetTimer();
6652 	luaReturnNil();
6653 }
6654 
luaFunc(stopMusic)6655 luaFunc(stopMusic)
6656 {
6657 	dsq->sound->stopMusic();
6658 	luaReturnNil();
6659 }
6660 
luaFunc(playMusic)6661 luaFunc(playMusic)
6662 {
6663 	float crossfadeTime = 0.8;
6664 	dsq->sound->playMusic(getString(L, 1), SLT_LOOP, SFT_CROSS, crossfadeTime);
6665 	luaReturnNil();
6666 }
6667 
luaFunc(playMusicStraight)6668 luaFunc(playMusicStraight)
6669 {
6670 	dsq->sound->setMusicFader(1,0);
6671 	dsq->sound->playMusic(getString(L, 1), SLT_LOOP, SFT_IN, 0.5); //SFT_IN, 0.1);//, SFT_IN, 0.2);
6672 	luaReturnNil();
6673 }
6674 
luaFunc(playMusicOnce)6675 luaFunc(playMusicOnce)
6676 {
6677 	float crossfadeTime = 0.8;
6678 	dsq->sound->playMusic(getString(L, 1), SLT_NONE, SFT_CROSS, crossfadeTime);
6679 	luaReturnNil();
6680 }
6681 
luaFunc(addInfluence)6682 luaFunc(addInfluence)
6683 {
6684 	ParticleInfluence pinf;
6685 	pinf.pos.x = lua_tonumber(L, 1);
6686 	pinf.pos.y = lua_tonumber(L, 2);
6687 	pinf.size = lua_tonumber(L, 3);
6688 	pinf.spd = lua_tonumber(L, 4);
6689 	pinf.pull = getBool(L, 5);
6690 	dsq->particleManager->addInfluence(pinf);
6691 	luaReturnNil();
6692 }
6693 
luaFunc(updateMusic)6694 luaFunc(updateMusic)
6695 {
6696 	dsq->game->updateMusic();
6697 	luaReturnNil();
6698 }
6699 
luaFunc(entity_grabTarget)6700 luaFunc(entity_grabTarget)
6701 {
6702 	Entity *e = entity(L);
6703 	if (e)
6704 		e->attachEntity(e->getTargetEntity(), Vector(lua_tointeger(L, 2), lua_tointeger(L, 3)));
6705 	luaReturnNil();
6706 }
6707 
luaFunc(entity_clampToHit)6708 luaFunc(entity_clampToHit)
6709 {
6710 	Entity *e = entity(L);
6711 	if (e)
6712 		e->clampToHit();
6713 	luaReturnNil();
6714 }
6715 
luaFunc(entity_clampToSurface)6716 luaFunc(entity_clampToSurface)
6717 {
6718 	Entity *e = entity(L);
6719 	bool ret = e && e->clampToSurface(lua_tonumber(L, 2));
6720 
6721 	luaReturnBool(ret);
6722 }
6723 
luaFunc(entity_checkSurface)6724 luaFunc(entity_checkSurface)
6725 {
6726 	Entity *e = entity(L);
6727 	bool c = false;
6728 
6729 	if (e)
6730 	{
6731 		c = e->checkSurface(lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4));
6732 	}
6733 
6734 	luaReturnBool(c);
6735 }
6736 
luaFunc(entity_switchSurfaceDirection)6737 luaFunc(entity_switchSurfaceDirection)
6738 {
6739 	ScriptedEntity *e = scriptedEntity(L);
6740 	if (!e)
6741 		luaReturnNil();
6742 
6743 	int n = -1;
6744 	if (lua_isnumber(L, 2))
6745 	{
6746 		n = lua_tonumber(L, 2);
6747 	}
6748 
6749 	if (e->isv(EV_SWITCHCLAMP, 1))
6750 	{
6751 		Vector oldPos = e->position;
6752 		if (e->isNearObstruction(0))
6753 		{
6754 			Vector n = dsq->game->getWallNormal(e->position);
6755 			if (!n.isZero())
6756 			{
6757 				do
6758 				{
6759 					e->position += n * 2;
6760 				}
6761 				while(e->isNearObstruction(0));
6762 			}
6763 		}
6764 		Vector usePos = e->position;
6765 		e->position = oldPos;
6766 		e->clampToSurface(0, usePos);
6767 	}
6768 
6769 	if (n == -1)
6770 	{
6771 		if (e->surfaceMoveDir)
6772 			e->surfaceMoveDir = 0;
6773 		else
6774 			e->surfaceMoveDir = 1;
6775 	}
6776 	else
6777 	{
6778 		e->surfaceMoveDir = n;
6779 	}
6780 
6781 	luaReturnNil();
6782 }
6783 
luaFunc(entity_adjustPositionBySurfaceNormal)6784 luaFunc(entity_adjustPositionBySurfaceNormal)
6785 {
6786 	ScriptedEntity *e = scriptedEntity(L);
6787 	if (e && !e->ridingOnEntity)
6788 	{
6789 		Vector v = dsq->game->getWallNormal(e->position);
6790 		if (v.x != 0 || v.y != 0)
6791 		{
6792 			v.setLength2D(lua_tonumber(L, 2));
6793 			e->position += v;
6794 		}
6795 		e->setv(EV_CRAWLING, 0);
6796 		//e->setCrawling(false);
6797 	}
6798 	luaReturnNil();
6799 }
6800 
6801 // HACK: move functionality inside entity class
luaFunc(entity_moveAlongSurface)6802 luaFunc(entity_moveAlongSurface)
6803 {
6804 	ScriptedEntity *e = scriptedEntity(L);
6805 
6806 	if (e && e->isv(EV_CLAMPING,0))
6807 	{
6808 		e->lastPosition = e->position;
6809 
6810 		//if (!e->position.isInterpolating())
6811 		{
6812 
6813 
6814 			/*
6815 			if (dsq->game->isObstructed(TileVector(e->position)))
6816 			{
6817 				e->moveOutOfWall();
6818 			}
6819 			*/
6820 
6821 			Vector v;
6822 			if (e->ridingOnEntity)
6823 			{
6824 				v = (e->position - e->ridingOnEntity->position);
6825 				v.normalize2D();
6826 			}
6827 			else
6828 				v = dsq->game->getWallNormal(e->position);
6829 			//int outFromWall = lua_tointeger(L, 5);
6830 			int outFromWall = e->getv(EV_WALLOUT);
6831 			bool invisibleIn = e->isSittingOnInvisibleIn();
6832 
6833 			/*
6834 			if (invisibleIn)
6835 				debugLog("Found invisibleIn");
6836 			else
6837 				debugLog("NOT FOUND");
6838 			*/
6839 
6840 			/*
6841 			for (int x = -2; x < 2; x++)
6842 			{
6843 				for (int y = -2; y< 2; y++)
6844 				{
6845 					if (dsq->game->getGrid(TileVector(x,y))== OT_INVISIBLEIN)
6846 					{
6847 						debugLog("found invisible in");
6848 						invisibleIn = true;
6849 						break;
6850 					}
6851 				}
6852 			}
6853 			*/
6854 			if (invisibleIn)
6855 				outFromWall -= TILE_SIZE;
6856 			float t = 0.1;
6857 			e->offset.interpolateTo(v*outFromWall, t);
6858 			/*
6859 			if (outFromWall)
6860 			{
6861 				//e->lastWallOffset = dsq->game->getWallNormal(e->position)*outFromWall;
6862 				//e->offset.interpolateTo(dsq->game->getWallNormal(e->position)*outFromWall, time*2);
6863 				//e->offset = v*outFromWall;
6864 
6865 				//float t = 0;
6866 				e->offset.interpolateTo(v*outFromWall, t);
6867 				//pos += e->lastWallOffset;
6868 			}
6869 			else
6870 			{
6871 				e->offset.interpolateTo(Vector(0,0), t);
6872 				//e->offset.interpolateTo(Vector(0,0), time*2);
6873 				//e->lastWallOffset = Vector(0,0);g
6874 			}
6875 			*/
6876 			// HACK: make this an optional parameter?
6877 			//e->rotateToVec(v, 0.1);
6878 			float dt = lua_tonumber(L, 2);
6879 			float speed = lua_tonumber(L, 3);
6880 			//int climbHeight = lua_tonumber(L, 4);
6881 			Vector mov;
6882 			if (e->surfaceMoveDir==1)
6883 				mov = Vector(v.y, -v.x);
6884 			else
6885 				mov = Vector(-v.y, v.x);
6886 			e->position += mov * speed * dt;
6887 
6888 			if (e->ridingOnEntity)
6889 				e->ridingOnEntityOffset = e->position - e->ridingOnEntity->position;
6890 
6891 			e->vel = 0;
6892 
6893 			/*
6894 			float adjustbit = float(speed)/float(TILE_SIZE);
6895 			if (e->isNearObstruction(0))
6896 			{
6897 				Vector n = dsq->game->getWallNormal(e->position);
6898 				if (!n.isZero())
6899 				{
6900 					Vector sp = e->position;
6901 					e->position += n * adjustbit * dt;
6902 				}
6903 			}
6904 			if (!e->isNearObstruction(1))
6905 			{
6906 				Vector n = dsq->game->getWallNormal(e->position);
6907 				if (!n.isZero())
6908 				{
6909 					Vector sp = e->position;
6910 					e->position -= n * adjustbit * dt;
6911 				}
6912 			}
6913 			*/
6914 				/*
6915 				Vector sp = e->position;
6916 				e->clampToSurface();
6917 				*/
6918 				/*
6919 				e->position = sp;
6920 				e->internalOffset.interpolateTo(e->position-sp, 0.2);
6921 				*/
6922 				/*
6923 				e->position = e->lastPosition;
6924 				e->position.interpolateTo(to*0.5f + e->position*0.5f, 0.5);
6925 				*/
6926 					/*
6927 					Vector to = e->position;
6928 					e->position = e->lastPosition;
6929 					e->position.interpolateTo(to, 0.5);
6930 					*/
6931 					/*
6932 					e->position = sp;
6933 					e->internalOffset.interpolateTo(e->position - sp, 0.2);
6934 					*/
6935 					//e->clampToSurface(0.1);
6936 		}
6937 	}
6938 
6939 	luaReturnNil();
6940 }
6941 
luaFunc(entity_rotateToSurfaceNormal)6942 luaFunc(entity_rotateToSurfaceNormal)
6943 {
6944 	//ScriptedEntity *e = scriptedEntity(L);
6945 	Entity *e = entity(L);
6946 	float t = lua_tonumber(L, 2);
6947 	int n = lua_tointeger(L, 3);
6948 	float rot = lua_tonumber(L, 4);
6949 	if (e)
6950 	{
6951 		e->rotateToSurfaceNormal(t, n, rot);
6952 	}
6953 	//Entity *e = entity(L);
6954 
6955 	luaReturnNil();
6956 }
6957 
luaFunc(entity_releaseTarget)6958 luaFunc(entity_releaseTarget)
6959 {
6960 	Entity *e = entity(L);
6961 	if (e)
6962 		e->detachEntity(e->getTargetEntity());
6963 	luaReturnNil();
6964 }
6965 
luaFunc(esetv)6966 luaFunc(esetv)
6967 {
6968 	Entity *e = entity(L);
6969 	EV ev = (EV)lua_tointeger(L, 2);
6970 	int n = lua_tointeger(L, 3);
6971 	if (e)
6972 		e->setv(ev, n);
6973 	luaReturnNum(n);
6974 }
6975 
luaFunc(egetv)6976 luaFunc(egetv)
6977 {
6978 	Entity *e = entity(L);
6979 	EV ev = (EV)lua_tointeger(L, 2);
6980 	int v = 0;
6981 	if (e)
6982 		v = e->getv(ev);
6983 	luaReturnNum(v);
6984 }
6985 
luaFunc(esetvf)6986 luaFunc(esetvf)
6987 {
6988 	Entity *e = entity(L);
6989 	EV ev = (EV)lua_tointeger(L, 2);
6990 	float n = lua_tonumber(L, 3);
6991 	if (e)
6992 		e->setvf(ev, n);
6993 	luaReturnNum(n);
6994 }
6995 
luaFunc(egetvf)6996 luaFunc(egetvf)
6997 {
6998 	Entity *e = entity(L);
6999 	float vf = 0;
7000 	if (e)
7001 	{
7002 		EV ev = (EV)lua_tointeger(L, 2);
7003 		vf = e->getvf(ev);
7004 	}
7005 	luaReturnNum(vf);
7006 }
7007 
luaFunc(eisv)7008 luaFunc(eisv)
7009 {
7010 	Entity *e = entity(L);
7011 	EV ev = (EV)lua_tointeger(L, 2);
7012 	int n = lua_tointeger(L, 3);
7013 	bool b = 0;
7014 	if (e)
7015 		b = e->isv(ev, n);
7016 	luaReturnBool(b);
7017 }
7018 
luaFunc(vector_normalize)7019 luaFunc(vector_normalize)
7020 {
7021 	float x = lua_tonumber(L, 1);
7022 	float y = lua_tonumber(L, 2);
7023 	Vector v(x,y);
7024 	v.normalize2D();
7025 	luaReturnVec2(v.x, v.y);
7026 }
7027 
luaFunc(vector_getLength)7028 luaFunc(vector_getLength)
7029 {
7030 	float x = lua_tonumber(L, 1);
7031 	float y = lua_tonumber(L, 2);
7032 	Vector v(x,y);
7033 	float len = v.getLength2D();
7034 	luaReturnNum(len);
7035 }
7036 
luaFunc(vector_setLength)7037 luaFunc(vector_setLength)
7038 {
7039 	float x = lua_tonumber(L, 1);
7040 	float y = lua_tonumber(L, 2);
7041 	Vector v(x,y);
7042 	v.setLength2D(lua_tonumber(L, 3));
7043 	luaReturnVec2(v.x, v.y);
7044 }
7045 
luaFunc(vector_dot)7046 luaFunc(vector_dot)
7047 {
7048 	float x = lua_tonumber(L, 1);
7049 	float y = lua_tonumber(L, 2);
7050 	float x2 = lua_tonumber(L, 3);
7051 	float y2 = lua_tonumber(L, 4);
7052 	Vector v(x,y);
7053 	Vector v2(x2,y2);
7054 	luaReturnNum(v.dot2D(v2));
7055 }
7056 
luaFunc(vector_cap)7057 luaFunc(vector_cap)
7058 {
7059 	float x = lua_tonumber(L, 1);
7060 	float y = lua_tonumber(L, 2);
7061 	Vector v(x,y);
7062 	v.capLength2D(lua_tonumber(L, 3));
7063 	luaReturnVec2(v.x, v.y);
7064 }
7065 
luaFunc(vector_isLength2DIn)7066 luaFunc(vector_isLength2DIn)
7067 {
7068 	float x = lua_tonumber(L, 1);
7069 	float y = lua_tonumber(L, 2);
7070 	Vector v(x,y);
7071 	bool ret = v.isLength2DIn(lua_tonumber(L, 3));
7072 	luaReturnBool(ret);
7073 }
7074 
luaFunc(entity_push)7075 luaFunc(entity_push)
7076 {
7077 	Entity *e = entity(L);
7078 	if (e)
7079 	{
7080 		e->push(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6));
7081 	}
7082 	luaReturnNil();
7083 }
7084 
luaFunc(entity_pushTarget)7085 luaFunc(entity_pushTarget)
7086 {
7087 	Entity *e = entity(L);
7088 	if (e)
7089 	{
7090 		Entity *target = e->getTargetEntity();
7091 		if (target)
7092 		{
7093 			Vector diff = target->position - e->position;
7094 			diff.setLength2D(lua_tointeger(L, 2));
7095 			target->vel += diff;
7096 		}
7097 	}
7098 
7099 	luaReturnNil();
7100 }
7101 
luaFunc(entity_getPushDamage)7102 luaFunc(entity_getPushDamage)
7103 {
7104 	Entity *e = entity(L);
7105 	luaReturnNum(e ? e->getPushDamage() : 0.0f);
7106 }
7107 
luaFunc(watch)7108 luaFunc(watch)
7109 {
7110 	float t = lua_tonumber(L, 1);
7111 	int quit = lua_tointeger(L, 2);
7112 	dsq->watch(t, quit);
7113 	luaReturnNil();
7114 }
7115 
luaFunc(wait)7116 luaFunc(wait)
7117 {
7118 	core->main(lua_tonumber(L, 1));
7119 	luaReturnNil();
7120 }
7121 
luaFunc(warpNaijaToEntity)7122 luaFunc(warpNaijaToEntity)
7123 {
7124 	Entity *e = dsq->getEntityByName(getString(L, 1));
7125 	if (e)
7126 	{
7127 		dsq->overlay->alpha.interpolateTo(1, 1);
7128 		core->main(1);
7129 
7130 		Vector offset(lua_tointeger(L, 2), lua_tointeger(L, 3));
7131 		dsq->game->avatar->position = e->position + offset;
7132 
7133 		dsq->overlay->alpha.interpolateTo(0, 1);
7134 		core->main(1);
7135 	}
7136 	luaReturnNil();
7137 }
7138 
luaFunc(getTimer)7139 luaFunc(getTimer)
7140 {
7141 	float n = lua_tonumber(L, 1);
7142 	if (n == 0)
7143 		n = 1;
7144 	luaReturnNum(dsq->game->getTimer(n));
7145 }
7146 
luaFunc(getHalfTimer)7147 luaFunc(getHalfTimer)
7148 {
7149 	float n = lua_tonumber(L, 1);
7150 	if (n == 0)
7151 		n = 1;
7152 	luaReturnNum(dsq->game->getHalfTimer(n));
7153 }
7154 
luaFunc(getOldDT)7155 luaFunc(getOldDT)
7156 {
7157 	luaReturnNum(core->get_old_dt());
7158 }
7159 
luaFunc(getDT)7160 luaFunc(getDT)
7161 {
7162 	luaReturnNum(core->get_current_dt());
7163 }
7164 
luaFunc(getFPS)7165 luaFunc(getFPS)
7166 {
7167 	luaReturnInt(core->fps);
7168 }
7169 
luaFunc(isNested)7170 luaFunc(isNested)
7171 {
7172 	luaReturnBool(core->isNested());
7173 }
7174 
luaFunc(getNumberOfEntitiesNamed)7175 luaFunc(getNumberOfEntitiesNamed)
7176 {
7177 	std::string s = getString(L);
7178 	int c = dsq->game->getNumberOfEntitiesNamed(s);
7179 	luaReturnNum(c);
7180 }
7181 
luaFunc(entity_pullEntities)7182 luaFunc(entity_pullEntities)
7183 {
7184 	Entity *e = entity(L);
7185 	if (e)
7186 	{
7187 		Vector pos(lua_tonumber(L, 2), lua_tonumber(L, 3));
7188 		float range = lua_tonumber(L, 4);
7189 		float len = lua_tonumber(L, 5);
7190 		float dt = lua_tonumber(L, 6);
7191 		FOR_ENTITIES(i)
7192 		{
7193 			Entity *ent = *i;
7194 			if (ent != e && (e->getEntityType() == ET_ENEMY || e->getEntityType() == ET_AVATAR) && e->isUnderWater())
7195 			{
7196 				Vector diff = ent->position - pos;
7197 				if (diff.isLength2DIn(range))
7198 				{
7199 					Vector pull = pos - ent->position;
7200 					pull.setLength2D(float(len) * dt);
7201 					ent->vel2 += pull;
7202 					/*
7203 					std::ostringstream os;
7204 					os << "ent: " << ent->name << " + (" << pull.x << ", " << pull.y << ")";
7205 					debugLog(os.str());
7206 					*/
7207 				}
7208 			}
7209 		}
7210 	}
7211 	luaReturnNil();
7212 }
7213 
7214 // Note that this overrides the generic obj_delete function for entities.
7215 // (It's registered as "entity_delete" to Lua)
7216 // There is at least one known case where this is necessary:
7217 // Avatar::pullTarget does a life check to drop the pointer;
7218 // If it's instantly deleted, this will cause a crash.
luaFunc(entity_delete_override)7219 luaFunc(entity_delete_override)
7220 {
7221 	Entity *e = entity(L);
7222 	if (e)
7223 	{
7224 		float time = lua_tonumber(L, 2);
7225 		if (time == 0)
7226 		{
7227 			e->alpha = 0;
7228 			e->setLife(0);
7229 			e->setDecayRate(1);
7230 		}
7231 		else
7232 		{
7233 			e->fadeAlphaWithLife = true;
7234 			e->setLife(1);
7235 			e->setDecayRate(1.0f/time);
7236 		}
7237 	}
7238 	luaReturnNil();
7239 }
7240 
luaFunc(entity_isRidingOnEntity)7241 luaFunc(entity_isRidingOnEntity)
7242 {
7243 	Entity *e = entity(L);
7244 	if (e)
7245 		luaReturnPtr(e->ridingOnEntity);
7246 	else
7247 		luaReturnPtr(NULL);
7248 }
7249 
7250 //entity_setProperty(me, EP_SOLID, true)
luaFunc(entity_isProperty)7251 luaFunc(entity_isProperty)
7252 {
7253 	Entity *e = entity(L);
7254 	bool v = false;
7255 	if (e)
7256 	{
7257 		v = e->isEntityProperty((EntityProperty)lua_tointeger(L, 2));
7258 	}
7259 	luaReturnBool(v);
7260 }
7261 
7262 //entity_setProperty(me, EP_SOLID, true)
luaFunc(entity_setProperty)7263 luaFunc(entity_setProperty)
7264 {
7265 	Entity *e = entity(L);
7266 	if (e)
7267 	{
7268 		e->setEntityProperty((EntityProperty)lua_tointeger(L, 2), getBool(L, 3));
7269 	}
7270 	luaReturnNil();
7271 }
7272 
luaFunc(entity_setActivation)7273 luaFunc(entity_setActivation)
7274 {
7275 	ScriptedEntity *e = scriptedEntity(L);
7276 	if (e)
7277 	{
7278 		int type = lua_tointeger(L, 2);
7279 		// cursor radius
7280 		float activationRadius = lua_tonumber(L, 3);
7281 		float range = lua_tonumber(L, 4);
7282 		e->activationType = (Entity::ActivationType)type;
7283 		e->activationRange = range;
7284 		e->activationRadius = activationRadius;
7285 	}
7286 
7287 	luaReturnNil();
7288 }
7289 
luaFunc(entity_setActivationType)7290 luaFunc(entity_setActivationType)
7291 {
7292 	Entity *e = entity(L);
7293 	if (e)
7294 		e->activationType = (Entity::ActivationType)lua_tointeger(L, 2);
7295 
7296 	luaReturnNil();
7297 }
7298 
luaFunc(entity_hasTarget)7299 luaFunc(entity_hasTarget)
7300 {
7301 	Entity *e = entity(L);
7302 	if (e)
7303 		luaReturnBool(e->hasTarget(e->currentEntityTarget));
7304 	else
7305 		luaReturnBool(false);
7306 }
7307 
luaFunc(entity_hurtTarget)7308 luaFunc(entity_hurtTarget)
7309 {
7310 	Entity *e = entity(L);
7311 	if (e && e->getTargetEntity())
7312 	{
7313 		DamageData d;
7314 		d.attacker = e;
7315 		d.damage = lua_tointeger(L, 2);
7316 		e->getTargetEntity(e->currentEntityTarget)->damage(d);
7317 	}
7318 	/*
7319 	if (e && e->getTargetEntity())
7320 		e->getTargetEntity(e->currentEntityTarget)->damage(lua_tointeger(L, 2), 0, e);
7321 	*/
7322 	luaReturnNil();
7323 }
7324 
7325 // radius dmg speed pushtime
luaFunc(entity_touchAvatarDamage)7326 luaFunc(entity_touchAvatarDamage)
7327 {
7328 	Entity *e = entity(L);
7329 	bool v = false;
7330 	if (e)
7331 	{
7332 		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)));
7333 	}
7334 	luaReturnBool(v);
7335 }
7336 
luaFunc(entity_getDistanceToEntity)7337 luaFunc(entity_getDistanceToEntity)
7338 {
7339 	Entity *e = entity(L);
7340 	Entity *e2 = entity(L, 2);
7341 	float d = 0;
7342 	if (e && e2)
7343 	{
7344 		Vector diff = e->position - e2->position;
7345 		d = diff.getLength2D();
7346 	}
7347 	luaReturnNum(d);
7348 }
7349 
luaFunc(entity_isEntityInside)7350 luaFunc(entity_isEntityInside)
7351 {
7352 	Entity *e = entity(L);
7353 	luaReturnBool(e ? e->isEntityInside() : false);
7354 }
7355 
7356 // entity_istargetInRange
luaFunc(entity_isTargetInRange)7357 luaFunc(entity_isTargetInRange)
7358 {
7359 	Entity *e = entity(L);
7360 	if (e)
7361 		luaReturnBool(e->isTargetInRange(lua_tointeger(L, 2), e->currentEntityTarget));
7362 	else
7363 		luaReturnBool(false);
7364 }
7365 
luaFunc(randAngle360)7366 luaFunc(randAngle360)
7367 {
7368 	luaReturnNum(randAngle360());
7369 }
7370 
luaFunc(randVector)7371 luaFunc(randVector)
7372 {
7373 	float num = lua_tonumber(L, 1);
7374 	if (num == 0)
7375 		num = 1;
7376 	Vector v = randVector(num);
7377 	luaReturnVec2(v.x, v.y);
7378 }
7379 
luaFunc(getNaija)7380 luaFunc(getNaija)
7381 {
7382 	luaReturnPtr(dsq->game->avatar);
7383 }
7384 
luaFunc(getLi)7385 luaFunc(getLi)
7386 {
7387 	luaReturnPtr(dsq->game->li);
7388 }
7389 
luaFunc(setLi)7390 luaFunc(setLi)
7391 {
7392 	dsq->game->li = entity(L);
7393 
7394 	luaReturnNil();
7395 }
7396 
luaFunc(entity_isPositionInRange)7397 luaFunc(entity_isPositionInRange)
7398 {
7399 	Entity *e = entity(L);
7400 	bool v = false;
7401 	int x, y;
7402 	x = lua_tonumber(L, 2);
7403 	y = lua_tonumber(L, 3);
7404 	if (e)
7405 	{
7406 		if ((e->position - Vector(x,y)).isLength2DIn(lua_tonumber(L, 4)))
7407 		{
7408 			v = true;
7409 		}
7410 	}
7411 	luaReturnBool(v);
7412 }
7413 
luaFunc(entity_isEntityInRange)7414 luaFunc(entity_isEntityInRange)
7415 {
7416 	Entity *e1 = entity(L);
7417 	Entity *e2 = entity(L, 2);
7418 	bool v= false;
7419 	if (e1 && e2)
7420 	{
7421 		//v = ((e2->position - e1->position).getSquaredLength2D() < sqr(lua_tonumber(L, 3)));
7422 		v = (e2->position - e1->position).isLength2DIn(lua_tonumber(L, 3));
7423 	}
7424 	luaReturnBool(v);
7425 }
7426 
7427 //entity_moveTowardsTarget(spd, dt)
luaFunc(entity_moveTowardsTarget)7428 luaFunc(entity_moveTowardsTarget)
7429 {
7430 	Entity *e = entity(L);
7431 	if (e)
7432 	{
7433 		e->moveTowardsTarget(lua_tonumber(L, 2), lua_tonumber(L, 3), e->currentEntityTarget);
7434 	}
7435 
7436 	luaReturnNil();
7437 }
7438 
7439 // entity dt speed dir
luaFunc(entity_moveAroundTarget)7440 luaFunc(entity_moveAroundTarget)
7441 {
7442 	Entity *e = entity(L);
7443 	if (e)
7444 		e->moveAroundTarget(lua_tonumber(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), e->currentEntityTarget);
7445 	// do stuff
7446 	luaReturnNil();
7447 }
7448 
luaFunc(entity_rotateToTarget)7449 luaFunc(entity_rotateToTarget)
7450 {
7451 	Entity *e = entity(L);
7452 	if (e)
7453 	{
7454 		Entity *t = e->getTargetEntity(e->currentEntityTarget);
7455 		if (t)
7456 		{
7457 			Vector v = t->position - e->position;
7458 			e->rotateToVec(v, lua_tonumber(L, 2), lua_tointeger(L, 3));
7459 		}
7460 	}
7461 	luaReturnNil();
7462 }
7463 
luaFunc(entity_partWidthHeight)7464 luaFunc(entity_partWidthHeight)
7465 {
7466 	ScriptedEntity *e = scriptedEntity(L);
7467 	Quad *r = (Quad*)e->partMap[getString(L, 2)];
7468 	if (r)
7469 	{
7470 		int w = lua_tointeger(L, 3);
7471 		int h = lua_tointeger(L, 4);
7472 		r->setWidthHeight(w, h);
7473 	}
7474 	luaReturnNil();
7475 }
7476 
luaFunc(entity_partSetSegs)7477 luaFunc(entity_partSetSegs)
7478 {
7479 	ScriptedEntity *e = scriptedEntity(L);
7480 	Quad *r = (Quad*)e->partMap[getString(L, 2)];
7481 	if (r)
7482 	{
7483 		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));
7484 	}
7485 	luaReturnNil();
7486 }
7487 
luaFunc(entity_getID)7488 luaFunc(entity_getID)
7489 {
7490 	Entity *e = entity(L);
7491 	luaReturnNum(e ? e->getID() : 0);
7492 }
7493 
luaFunc(getEntityByID)7494 luaFunc(getEntityByID)
7495 {
7496 	debugLog("Calling getEntityByID");
7497 	int v = lua_tointeger(L, 1);
7498 	Entity *found = 0;
7499 	if (v)
7500 	{
7501 		std::ostringstream os;
7502 		os << "searching for entity with id: " << v;
7503 		debugLog(os.str());
7504 		FOR_ENTITIES(i)
7505 		{
7506 			Entity *e = *i;
7507 			if (e->getID() == v)
7508 			{
7509 				found = e;
7510 				break;
7511 			}
7512 		}
7513 		if (!found)
7514 		{
7515 			std::ostringstream os;
7516 			os << "entity with id: " << v << " not found!";
7517 			debugLog(os.str());
7518 		}
7519 		else
7520 		{
7521 			std::ostringstream os;
7522 			os << "Found: " << found->name;
7523 			debugLog(os.str());
7524 		}
7525 	}
7526 	else
7527 	{
7528 		debugLog("entity ID was 0");
7529 	}
7530 	luaReturnPtr(found);
7531 }
7532 
luaFunc(node_activate)7533 luaFunc(node_activate)
7534 {
7535 	Path *p = path(L);
7536 	Entity *e = 0;
7537 	if (lua_touserdata(L, 2) != NULL)
7538 		e = entity(L, 2);
7539 	if (p)
7540 	{
7541 		p->activate(e);
7542 	}
7543 	luaReturnNil();
7544 }
7545 
luaFunc(node_setElementsInLayerActive)7546 luaFunc(node_setElementsInLayerActive)
7547 {
7548 	Path *p = path(L);
7549 	if (p)
7550 	{
7551 		int l = lua_tointeger(L, 2);
7552 		bool v = getBool(L, 3);
7553 		for (Element *e = dsq->getFirstElementOnLayer(l); e; e = e->bgLayerNext)
7554 		{
7555 			if (e && p->isCoordinateInside(e->position))
7556 			{
7557 				e->setElementActive(v);
7558 			}
7559 		}
7560 	}
7561 	luaReturnNil();
7562 }
7563 
luaFunc(node_getNumEntitiesIn)7564 luaFunc(node_getNumEntitiesIn)
7565 {
7566 	Path *p = path(L);
7567 	std::string name;
7568 	if (lua_isstring(L, 2))
7569 	{
7570 		name = lua_tostring(L, 2);
7571 	}
7572 	int c = 0;
7573 	if (p && !p->nodes.empty())
7574 	{
7575 		FOR_ENTITIES(i)
7576 		{
7577 			Entity *e = *i;
7578 			if (name.empty() || (nocasecmp(e->name, name)==0))
7579 			{
7580 				if (p->isCoordinateInside(e->position))
7581 				{
7582 					c++;
7583 				}
7584 			}
7585 		}
7586 	}
7587 	luaReturnNum(c);
7588 }
7589 
luaFunc(node_getNearestEntity)7590 luaFunc(node_getNearestEntity)
7591 {
7592 	Path *p = path(L);
7593 	Entity *closest=0;
7594 
7595 	if (p && !p->nodes.empty())
7596 	{
7597 
7598 		Vector pos = p->nodes[0].position;
7599 		std::string name;
7600 		Entity *ignore = 0;
7601 		if (lua_isstring(L, 2))
7602 			name = lua_tostring(L, 2);
7603 		if (lua_isuserdata(L, 3))
7604 			ignore = entity(L, 3);
7605 
7606 		float smallestDist = HUGE_VALF;
7607 		FOR_ENTITIES(i)
7608 		{
7609 			Entity *e = *i;
7610 			if (e != ignore && e->isPresent() && e->isNormalLayer())
7611 			{
7612 				if (name.empty() || (nocasecmp(e->name, name)==0))
7613 				{
7614 					float dist = (pos - e->position).getSquaredLength2D();
7615 					if (dist < smallestDist)
7616 					{
7617 						smallestDist = dist;
7618 						closest = e;
7619 					}
7620 				}
7621 			}
7622 		}
7623 	}
7624 	luaReturnPtr(closest);
7625 }
7626 
luaFunc(node_getNearestNode)7627 luaFunc(node_getNearestNode)
7628 {
7629 	Path *p = path(L);
7630 	Path *closest = 0;
7631 	if (p && !p->nodes.empty())
7632 	{
7633 		std::string name;
7634 		if (lua_isstring(L, 2))
7635 			name = lua_tostring(L, 2);
7636 		Path *ignore = path(L, 3);
7637 		closest = dsq->game->getNearestPath(p->nodes[0].position, name, ignore);
7638 	}
7639 	luaReturnPtr(closest);
7640 }
7641 
luaFunc(entity_getNearestBoneToPosition)7642 luaFunc(entity_getNearestBoneToPosition)
7643 {
7644 	Entity *me = entity(L);
7645 	Vector p(lua_tonumber(L, 2), lua_tonumber(L, 3));
7646 	float smallestDist = HUGE_VALF;
7647 	Bone *closest = 0;
7648 	if (me)
7649 	{
7650 		for (int i = 0; i < me->skeletalSprite.bones.size(); i++)
7651 		{
7652 			Bone *b = me->skeletalSprite.bones[i];
7653 			float dist = (b->getWorldPosition() - p).getSquaredLength2D();
7654 			if (dist < smallestDist)
7655 			{
7656 				smallestDist = dist;
7657 				closest = b;
7658 			}
7659 		}
7660 	}
7661 	luaReturnPtr(closest);
7662 }
7663 
luaFunc(entity_getNearestNode)7664 luaFunc(entity_getNearestNode)
7665 {
7666 	Entity *me = entity(L);
7667 	Path *closest = 0;
7668 	if (me)
7669 	{
7670 		std::string name;
7671 		if (lua_isstring(L, 2))
7672 			name = lua_tostring(L, 2);
7673 		Path *ignore = path(L, 3);
7674 		closest = dsq->game->getNearestPath(me->position, name, ignore);
7675 	}
7676 	luaReturnPtr(closest);
7677 }
7678 
luaFunc(ing_hasIET)7679 luaFunc(ing_hasIET)
7680 {
7681 	Ingredient *i = getIng(L, 1);
7682 	bool has = i && i->hasIET((IngredientEffectType)lua_tointeger(L, 2));
7683 	luaReturnBool(has);
7684 }
7685 
luaFunc(ing_getIngredientName)7686 luaFunc(ing_getIngredientName)
7687 {
7688 	Ingredient *i = getIng(L, 1);
7689 	IngredientData *data = i ? i->getIngredientData() : 0;
7690 	luaReturnStr(data ? data->name.c_str() : "");
7691 }
7692 
luaFunc(entity_getNearestEntity)7693 luaFunc(entity_getNearestEntity)
7694 {
7695 	Entity *me = entity(L);
7696 	if (!me)
7697 		luaReturnPtr(0);
7698 
7699 	const char *name = 0;
7700 	if (lua_isstring(L, 2))
7701 	{
7702 		name = lua_tostring(L, 2);
7703 		if (!*name)
7704 			name = NULL;
7705 	}
7706 
7707 	bool nameCheck = true;
7708 	if (name && (name[0] == '!' || name[0] == '~'))
7709 	{
7710 		name++;
7711 		nameCheck = false;
7712 	}
7713 
7714 	float range = lua_tonumber(L, 3);
7715 	EntityType type = ET_NOTYPE;
7716 	if (lua_isnumber(L, 4))
7717 		type = (EntityType)lua_tointeger(L, 4);
7718 
7719 	DamageType damageTarget = DT_NONE;
7720 	if (lua_isnumber(L, 5))
7721 		damageTarget = (DamageType)lua_tointeger(L, 5);
7722 	Entity *closest = 0;
7723 	Entity *ignore = 0;
7724 	if (lua_isuserdata(L, 6))
7725 		ignore = entity(L, 6);
7726 
7727 	float smallestDist = range ? sqr(range) : HUGE_VALF;
7728 	FOR_ENTITIES(i)
7729 	{
7730 		Entity *e = *i;
7731 		if (e != me && e != ignore && e->isPresent() && e->isNormalLayer())
7732 		{
7733 			if (type == ET_NOTYPE || e->getEntityType() == type)
7734 			{
7735 				if (damageTarget == DT_NONE || e->isDamageTarget((DamageType)damageTarget))
7736 				{
7737 					if (!name || ((nocasecmp(e->name, name)==0) == nameCheck))
7738 					{
7739 						float dist = (me->position - e->position).getSquaredLength2D();
7740 						if (dist < smallestDist)
7741 						{
7742 							smallestDist = dist;
7743 							closest = e;
7744 						}
7745 					}
7746 				}
7747 			}
7748 		}
7749 	}
7750 	luaReturnPtr(closest);
7751 }
7752 
luaFunc(getNearestEntity)7753 luaFunc(getNearestEntity)
7754 {
7755 	Vector p(lua_tonumber(L, 1), lua_tonumber(L, 2));
7756 	int radius = lua_tointeger(L, 3);
7757 	Entity *ignore = lua_isuserdata(L, 4) ? entity(L, 4) : NULL;
7758 	EntityType et = lua_isnumber(L, 5) ? (EntityType)lua_tointeger(L, 5) : ET_NOTYPE;
7759 	DamageType dt = lua_isnumber(L, 6) ? (DamageType)lua_tointeger(L, 6) : DT_NONE;
7760 	int lrStart = lua_isnumber(L, 7) ? lua_tointeger(L, 7) : -1;
7761 	int lrEnd = lua_isnumber(L, 8) ? lua_tointeger(L, 8) : -1;
7762 
7763 	Entity *target = dsq->game->getNearestEntity(p, radius, ignore, ET_ENEMY, dt, lrStart, lrEnd);
7764 	luaReturnPtr(target);
7765 }
7766 
luaFunc(findWall)7767 luaFunc(findWall)
7768 {
7769 	float x = lua_tonumber(L, 1);
7770 	float y = lua_tonumber(L, 2);
7771 	int dirx = lua_tointeger(L, 3);
7772 	int diry = lua_tointeger(L, 4);
7773 	if (dirx == 0 && diry == 0){ debugLog("dirx && diry are zero!"); luaReturnNum(0); }
7774 
7775 	TileVector t(Vector(x, y));
7776 	while (!dsq->game->isObstructed(t))
7777 	{
7778 		t.x += dirx;
7779 		t.y += diry;
7780 	}
7781 	Vector v = t.worldVector();
7782 	int wall = 0;
7783 	if (diry != 0)		wall = v.y;
7784 	if (dirx != 0)		wall = v.x;
7785 	luaReturnNum(wall);
7786 }
7787 
luaFunc(toggleVersionLabel)7788 luaFunc(toggleVersionLabel)
7789 {
7790 	bool on = getBool(L, 1);
7791 
7792 	dsq->toggleVersionLabel(on);
7793 
7794 	luaReturnBool(on);
7795 }
7796 
luaFunc(setVersionLabelText)7797 luaFunc(setVersionLabelText)
7798 {
7799 	dsq->setVersionLabelText();
7800 	luaReturnNil();
7801 }
7802 
luaFunc(setCutscene)7803 luaFunc(setCutscene)
7804 {
7805 	dsq->setCutscene(getBool(L, 1), getBool(L, 2));
7806 	luaReturnNil();
7807 }
7808 
luaFunc(isInCutscene)7809 luaFunc(isInCutscene)
7810 {
7811 	luaReturnBool(dsq->isInCutscene());
7812 }
7813 
luaFunc(toggleSteam)7814 luaFunc(toggleSteam)
7815 {
7816 	bool on = getBool(L, 1);
7817 	for (Path *p = dsq->game->getFirstPathOfType(PATH_STEAM); p; p = p->nextOfType)
7818 	{
7819 		p->setActive(on);
7820 	}
7821 	luaReturnBool(on);
7822 }
7823 
luaFunc(getFirstEntity)7824 luaFunc(getFirstEntity)
7825 {
7826 	luaReturnPtr(dsq->getFirstEntity());
7827 }
7828 
luaFunc(getNextEntity)7829 luaFunc(getNextEntity)
7830 {
7831 	luaReturnPtr(dsq->getNextEntity());
7832 }
7833 
7834 typedef std::pair<Entity*, float> EntityDistancePair;
7835 static std::vector<EntityDistancePair> filteredEntities(20);
7836 static int filteredEntityIdx = 0;
7837 
_entityDistanceCmp(const EntityDistancePair & a,const EntityDistancePair & b)7838 static bool _entityDistanceCmp(const EntityDistancePair& a, const EntityDistancePair& b)
7839 {
7840 	return a.second < b.second;
7841 }
_entityDistanceEq(const EntityDistancePair & a,const EntityDistancePair & b)7842 static bool _entityDistanceEq(const EntityDistancePair& a, const EntityDistancePair& b)
7843 {
7844 	return a.first == b.first;
7845 }
7846 
_entityFilter(lua_State * L)7847 static size_t _entityFilter(lua_State *L)
7848 {
7849 	const Vector p(lua_tonumber(L, 1), lua_tonumber(L, 2));
7850 	const float radius = lua_tonumber(L, 3);
7851 	const Entity *ignore = lua_isuserdata(L, 4) ? entity(L, 4) : NULL;
7852 	const EntityType et = lua_isnumber(L, 5) ? (EntityType)lua_tointeger(L, 5) : ET_NOTYPE;
7853 	const DamageType dt = lua_isnumber(L, 6) ? (DamageType)lua_tointeger(L, 6) : DT_NONE;
7854 	const int lrStart = lua_isnumber(L, 7) ? lua_tointeger(L, 7) : -1;
7855 	const int lrEnd = lua_isnumber(L, 8) ? lua_tointeger(L, 8) : -1;
7856 
7857 	const float sqrRadius = radius * radius;
7858 	float distsq;
7859 	const bool skipLayerCheck = lrStart == -1 || lrEnd == -1;
7860 	const bool skipRadiusCheck = radius <= 0;
7861 	size_t added = 0;
7862 	FOR_ENTITIES(i)
7863 	{
7864 		Entity *e = *i;
7865 		distsq = (e->position - p).getSquaredLength2D();
7866 		if (skipRadiusCheck || distsq <= sqrRadius)
7867 		{
7868 			if (e != ignore && e->isPresent())
7869 			{
7870 				if (skipLayerCheck || (e->layer >= lrStart && e->layer <= lrEnd))
7871 				{
7872 					if (et == ET_NOTYPE || e->getEntityType() == et)
7873 					{
7874 						if (dt == DT_NONE || e->isDamageTarget(dt))
7875 						{
7876 							filteredEntities.push_back(std::make_pair(e, distsq));
7877 							++added;
7878 						}
7879 					}
7880 				}
7881 			}
7882 		}
7883 	}
7884 	if(added)
7885 	{
7886 		std::sort(filteredEntities.begin(), filteredEntities.end(), _entityDistanceCmp);
7887 		std::vector<EntityDistancePair>::iterator newend = std::unique(filteredEntities.begin(), filteredEntities.end(), _entityDistanceEq);
7888 		filteredEntities.resize(std::distance(filteredEntities.begin(), newend));
7889 	}
7890 
7891 	// Add terminator if there is none
7892 	if(filteredEntities.size() && filteredEntities.back().first)
7893 		filteredEntities.push_back(std::make_pair((Entity*)NULL, 0.0f)); // terminator
7894 
7895 	filteredEntityIdx = 0; // Reset getNextFilteredEntity() iteration index
7896 
7897 	return added;
7898 }
7899 
luaFunc(filterNearestEntities)7900 luaFunc(filterNearestEntities)
7901 {
7902 	filteredEntities.clear();
7903 	luaReturnInt(_entityFilter(L));
7904 }
7905 
luaFunc(filterNearestEntitiesAdd)7906 luaFunc(filterNearestEntitiesAdd)
7907 {
7908 	// Remove terminator if there is one
7909 	if(filteredEntities.size() && !filteredEntities.back().first)
7910 		filteredEntities.pop_back();
7911 	luaReturnInt(_entityFilter(L));
7912 }
7913 
luaFunc(getNextFilteredEntity)7914 luaFunc(getNextFilteredEntity)
7915 {
7916 	EntityDistancePair ep = filteredEntities[filteredEntityIdx];
7917 	if (ep.first)
7918 		++filteredEntityIdx;
7919 	luaPushPointer(L, ep.first);
7920 	lua_pushnumber(L, ep.second);
7921 	return 2;
7922 }
7923 
luaFunc(getEntity)7924 luaFunc(getEntity)
7925 {
7926 	Entity *ent = 0;
7927 	// THIS WAS IMPORTANT: this was for getting entity by NUMBER IN LIST used for looping through all entities in script
7928 	if (lua_isnumber(L, 1))
7929 	{
7930 		//HACK: FIX:
7931 		// this has been disabled due to switching to list based entities
7932 	}
7933 	else if (lua_isstring(L, 1))
7934 	{
7935 		std::string s = lua_tostring(L, 1);
7936 		ent = dsq->getEntityByName(s);
7937 	}
7938 	luaReturnPtr(ent);
7939 }
7940 
luaFunc(entity_partAlpha)7941 luaFunc(entity_partAlpha)
7942 {
7943 	ScriptedEntity *e = scriptedEntity(L);
7944 	if (e)
7945 	{
7946 		RenderObject *r = e->partMap[getString(L, 2)];
7947 		if (r)
7948 		{
7949 			float start = lua_tonumber(L, 3);
7950 			if (start != -1)
7951 				r->alpha = start;
7952 			interpolateVec1(L, r->alpha, 4);
7953 		}
7954 	}
7955 	luaReturnNil();
7956 }
7957 
luaFunc(entity_partBlendType)7958 luaFunc(entity_partBlendType)
7959 {
7960 	ScriptedEntity *e = scriptedEntity(L);
7961 	if (e)
7962 		e->partMap[getString(L, 2)]->setBlendType(lua_tointeger(L, 3));
7963 	luaReturnNil();
7964 }
7965 
luaFunc(entity_partRotate)7966 luaFunc(entity_partRotate)
7967 {
7968 	ScriptedEntity *e = scriptedEntity(L);
7969 	if (e)
7970 	{
7971 		RenderObject *r = e->partMap[getString(L, 2)];
7972 		if (r)
7973 			interpolateVec1z(L, r->rotation, 3);
7974 	}
7975 	luaReturnNil();
7976 }
7977 
luaFunc(entity_getStateTime)7978 luaFunc(entity_getStateTime)
7979 {
7980 	Entity *e = entity(L);
7981 	float t = 0;
7982 	if (e)
7983 		t = e->getStateTime();
7984 	luaReturnNum(t);
7985 }
7986 
luaFunc(entity_setStateTime)7987 luaFunc(entity_setStateTime)
7988 {
7989 	Entity *e = entity(L);
7990 	float t = lua_tonumber(L, 2);
7991 	if (e)
7992 		e->setStateTime(t);
7993 	luaReturnNum(t);
7994 }
7995 
luaFunc(entity_offsetUpdate)7996 luaFunc(entity_offsetUpdate)
7997 {
7998 	Entity *e = entity(L);
7999 	if (e)
8000 	{
8001 		float uc = e->updateCull;
8002 		e->updateCull = -1;
8003 		float t = float(rand()%10000)/1000.0f;
8004 		e->update(t);
8005 		e->updateCull = uc;
8006 	}
8007 	luaReturnNil();
8008 }
8009 
8010 // not to be confused with obj_setLayer or entity_setEntityLayer!!
luaFunc(entity_switchLayer)8011 luaFunc(entity_switchLayer)
8012 {
8013 	Entity *e = entity(L);
8014 	if (e)
8015 	{
8016 		int lcode = lua_tointeger(L, 2);
8017 		int toLayer = LR_ENTITIES;
8018 
8019 		toLayer = dsq->getEntityLayerToLayer(lcode);
8020 
8021 		if (e->getEntityType() == ET_AVATAR)
8022 			toLayer = LR_ENTITIES;
8023 
8024 		core->switchRenderObjectLayer(e, toLayer);
8025 	}
8026 	luaReturnNil();
8027 }
8028 
8029 // entity numSegments segmentLength width texture
luaFunc(entity_initHair)8030 luaFunc(entity_initHair)
8031 {
8032 	Entity *se = entity(L);
8033 	if (se)
8034 	{
8035 		se->initHair(lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4), getString(L, 5));
8036 	}
8037 	luaReturnNil();
8038 }
8039 
luaFunc(entity_getHair)8040 luaFunc(entity_getHair)
8041 {
8042 	Entity *e = entity(L);
8043 	luaReturnPtr(e ? e->hair : NULL);
8044 }
8045 
luaFunc(entity_clearHair)8046 luaFunc(entity_clearHair)
8047 {
8048 	Entity *e = entity(L);
8049 	if (e && e->hair)
8050 	{
8051 		e->hair->safeKill();
8052 		e->hair = 0;
8053 	}
8054 	luaReturnNil();
8055 }
8056 
luaFunc(entity_getHairPosition)8057 luaFunc(entity_getHairPosition)
8058 {
8059 	Entity *se = entity(L);
8060 	float x=0;
8061 	float y=0;
8062 	int idx = lua_tointeger(L, 2);
8063 	if (se && se->hair)
8064 	{
8065 		HairNode *h = se->hair->getHairNode(idx);
8066 		if (h)
8067 		{
8068 			x = h->position.x;
8069 			y = h->position.y;
8070 		}
8071 	}
8072 	luaReturnVec2(x, y);
8073 }
8074 
8075 // entity x y z
luaFunc(entity_setHairHeadPosition)8076 luaFunc(entity_setHairHeadPosition)
8077 {
8078 	Entity *se = entity(L);
8079 	if (se)
8080 	{
8081 		se->setHairHeadPosition(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)));
8082 	}
8083 	luaReturnNil();
8084 }
8085 
luaFunc(entity_updateHair)8086 luaFunc(entity_updateHair)
8087 {
8088 	Entity *se = entity(L);
8089 	if (se)
8090 	{
8091 		se->updateHair(lua_tonumber(L, 2));
8092 	}
8093 	luaReturnNil();
8094 }
8095 
8096 // entity x y dt
luaFunc(entity_exertHairForce)8097 luaFunc(entity_exertHairForce)
8098 {
8099 	ScriptedEntity *se = scriptedEntity(L);
8100 	if (se)
8101 	{
8102 		if (se->hair)
8103 			se->hair->exertForce(Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), lua_tonumber(L, 4), lua_tonumber(L, 5));
8104 	}
8105 	luaReturnNil();
8106 }
8107 
luaFunc(entity_initPart)8108 luaFunc(entity_initPart)
8109 {
8110 	std::string partName(getString(L, 2));
8111 	std::string partTex(getString(L, 3));
8112 	Vector partPosition(lua_tonumber(L, 4), lua_tonumber(L, 5));
8113 	bool renderAfter = getBool(L, 6);
8114 	bool partFlipH = getBool(L, 7);
8115 	bool partFlipV = getBool(L,8);
8116 	Vector offsetInterpolateTo(lua_tonumber(L, 9), lua_tonumber(L, 10));
8117 	float offsetInterpolateTime = lua_tonumber(L, 11);
8118 
8119 
8120 	ScriptedEntity *e = scriptedEntity(L);
8121 	if (e)
8122 	{
8123 		Quad *q = new Quad;
8124 		q->setTexture(partTex);
8125 		q->renderBeforeParent = !renderAfter;
8126 
8127 
8128 		q->position = partPosition;
8129 		if (offsetInterpolateTo.x != 0 || offsetInterpolateTo.y != 0)
8130 			q->offset.interpolateTo(offsetInterpolateTo, offsetInterpolateTime, -1, 1, 1);
8131 		if (partFlipH)
8132 			q->flipHorizontal();
8133 		if (partFlipV)
8134 			q->flipVertical();
8135 
8136 		e->addChild(q, PM_POINTER);
8137 		e->registerNewPart(q, partName);
8138 	}
8139 
8140 	luaReturnNil();
8141 }
8142 
luaFunc(entity_findTarget)8143 luaFunc(entity_findTarget)
8144 {
8145 	Entity *e = entity(L);
8146 	if (e)
8147 		e->findTarget(lua_tointeger(L, 2), lua_tointeger(L, 3), e->currentEntityTarget);
8148 
8149 	luaReturnNil();
8150 }
8151 
luaFunc(entity_doFriction)8152 luaFunc(entity_doFriction)
8153 {
8154 	Entity *e = entity(L);
8155 	if (e)
8156 	{
8157 		e->doFriction(lua_tonumber(L, 2), lua_tonumber(L, 3));
8158 	}
8159 	luaReturnNil();
8160 }
8161 
luaFunc(entity_doGlint)8162 luaFunc(entity_doGlint)
8163 {
8164 	Entity *e = entity(L);
8165 	if (e)
8166 		e->doGlint(e->position, Vector(2,2), getString(L,2), (RenderObject::BlendTypes)lua_tointeger(L, 3));
8167 	luaReturnNil();
8168 }
8169 
luaFunc(entity_getTarget)8170 luaFunc(entity_getTarget)
8171 {
8172 	Entity *e = entity(L);
8173 	Entity *retEnt = NULL;
8174 	if (e)
8175 	{
8176 		retEnt = e->getTargetEntity(lua_tonumber(L, 2));
8177 		//e->activate();
8178 	}
8179 	luaReturnPtr(retEnt);
8180 }
8181 
luaFunc(entity_getTargetPositionX)8182 luaFunc(entity_getTargetPositionX)
8183 {
8184 	Entity *e = entity(L);
8185 	luaReturnInt(e ? e->getTargetEntity()->position.x : 0);
8186 }
8187 
luaFunc(entity_getTargetPositionY)8188 luaFunc(entity_getTargetPositionY)
8189 {
8190 	Entity *e = entity(L);
8191 	luaReturnNum(e ? e->getTargetEntity()->position.y : 0);
8192 }
8193 
luaFunc(entity_isNearObstruction)8194 luaFunc(entity_isNearObstruction)
8195 {
8196 	Entity *e = entity(L);
8197 	int sz = lua_tointeger(L, 2);
8198 	int type = lua_tointeger(L, 3);
8199 	bool v = false;
8200 	if (e)
8201 	{
8202 		v = e->isNearObstruction(sz, type);
8203 	}
8204 	luaReturnBool(v);
8205 }
8206 
luaFunc(entity_isInvincible)8207 luaFunc(entity_isInvincible)
8208 {
8209 	Entity *e = entity(L);
8210 	bool v = false;
8211 	if (e)
8212 	{
8213 		v = e->isInvincible();
8214 	}
8215 	luaReturnBool(v);
8216 }
8217 
luaFunc(entity_setEatType)8218 luaFunc(entity_setEatType)
8219 {
8220 	Entity *e = entity(L);
8221 	int et = lua_tointeger(L, 2);
8222 	if (e)
8223 		e->setEatType((EatType)et, getString(L, 3));
8224 	luaReturnInt(et);
8225 }
8226 
luaFunc(getMapName)8227 luaFunc(getMapName)
8228 {
8229 	luaReturnStr(dsq->game->sceneName.c_str());
8230 }
8231 
luaFunc(isMapName)8232 luaFunc(isMapName)
8233 {
8234 	std::string s1 = dsq->game->sceneName;
8235 	std::string s2 = getString(L, 1);
8236 	stringToUpper(s1);
8237 	stringToUpper(s2);
8238 	bool ret = (s1 == s2);
8239 
8240 	luaReturnBool(ret);
8241 }
8242 
luaFunc(mapNameContains)8243 luaFunc(mapNameContains)
8244 {
8245 	std::string s = dsq->game->sceneName;
8246 	stringToLower(s);
8247 	bool b = (s.find(getString(L, 1)) != std::string::npos);
8248 	luaReturnBool(b);
8249 }
8250 
luaFunc(entity_fireGas)8251 luaFunc(entity_fireGas)
8252 {
8253 	Entity *e = entity(L);
8254 	if (e)
8255 	{
8256 		int radius = lua_tointeger(L, 2);
8257 		float life = lua_tonumber(L, 3);
8258 		float damage = lua_tonumber(L, 4);
8259 		std::string gfx = getString(L, 5);
8260 		float colorx = lua_tonumber(L, 6);
8261 		float colory = lua_tonumber(L, 7);
8262 		float colorz = lua_tonumber(L, 8);
8263 		float offx = lua_tonumber(L, 9);
8264 		float offy = lua_tonumber(L, 10);
8265 		float poisonTime = lua_tonumber(L, 11);
8266 
8267 		GasCloud *c = new GasCloud(e, e->position + Vector(offx, offy), gfx, Vector(colorx, colory, colorz), radius, life, damage, false, poisonTime);
8268 		core->getTopStateData()->addRenderObject(c, LR_PARTICLES);
8269 	}
8270 	luaReturnNil();
8271 }
8272 
luaFunc(isInputEnabled)8273 luaFunc(isInputEnabled)
8274 {
8275 	luaReturnBool(dsq->game->avatar->isInputEnabled());
8276 }
8277 
luaFunc(enableInput)8278 luaFunc(enableInput)
8279 {
8280 	dsq->game->avatar->enableInput();
8281 	luaReturnNil();
8282 }
8283 
luaFunc(disableInput)8284 luaFunc(disableInput)
8285 {
8286 	dsq->game->avatar->disableInput();
8287 	luaReturnNil();
8288 }
8289 
luaFunc(getInputMode)8290 luaFunc(getInputMode)
8291 {
8292 	luaReturnInt(dsq->inputMode);
8293 }
8294 
luaFunc(getJoystickAxisLeft)8295 luaFunc(getJoystickAxisLeft)
8296 {
8297 	Vector v = core->joystick.position;
8298 	luaReturnVec2(v.x, v.y);
8299 }
8300 
luaFunc(getJoystickAxisRight)8301 luaFunc(getJoystickAxisRight)
8302 {
8303 	Vector v = core->joystick.rightStick;
8304 	luaReturnVec2(v.x, v.y);
8305 }
8306 
luaFunc(quit)8307 luaFunc(quit)
8308 {
8309 #ifdef AQUARIA_DEMO
8310 	dsq->nag(NAG_QUIT);
8311 #else
8312 	dsq->quit();
8313 #endif
8314 
8315 	luaReturnNil();
8316 }
8317 
luaFunc(doModSelect)8318 luaFunc(doModSelect)
8319 {
8320 	dsq->doModSelect();
8321 	luaReturnNil();
8322 }
8323 
luaFunc(doLoadMenu)8324 luaFunc(doLoadMenu)
8325 {
8326 	dsq->doLoadMenu();
8327 	luaReturnNil();
8328 }
8329 
luaFunc(resetContinuity)8330 luaFunc(resetContinuity)
8331 {
8332 	dsq->continuity.reset();
8333 	luaReturnNil();
8334 }
8335 
luaFunc(toWindowFromWorld)8336 luaFunc(toWindowFromWorld)
8337 {
8338 	float x = lua_tonumber(L, 1);
8339 	float y = lua_tonumber(L, 2);
8340 	x = x - core->screenCenter.x;
8341 	y = y - core->screenCenter.y;
8342 	x *= core->globalScale.x;
8343 	y *= core->globalScale.x;
8344 	x = 400+x;
8345 	y = 300+y;
8346 	luaReturnVec2(x, y);
8347 }
8348 
luaFunc(setMousePos)8349 luaFunc(setMousePos)
8350 {
8351 	core->setMousePosition(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)));
8352 	luaReturnNil();
8353 }
8354 
luaFunc(getMousePos)8355 luaFunc(getMousePos)
8356 {
8357 	luaReturnVec2(core->mouse.position.x, core->mouse.position.y);
8358 }
8359 
luaFunc(getMouseWorldPos)8360 luaFunc(getMouseWorldPos)
8361 {
8362 	Vector v = dsq->getGameCursorPosition();
8363 	luaReturnVec2(v.x, v.y);
8364 }
8365 
luaFunc(getMouseWheelChange)8366 luaFunc(getMouseWheelChange)
8367 {
8368 	luaReturnNum(core->mouse.scrollWheelChange);
8369 }
8370 
luaFunc(setMouseConstraintCircle)8371 luaFunc(setMouseConstraintCircle)
8372 {
8373 	core->setMouseConstraintCircle(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)), lua_tonumber(L, 3));
8374 	luaReturnNil();
8375 }
8376 
luaFunc(setMouseConstraint)8377 luaFunc(setMouseConstraint)
8378 {
8379 	core->setMouseConstraint(getBool(L, 1));
8380 	luaReturnNil();
8381 }
8382 
luaFunc(fade)8383 luaFunc(fade)
8384 {
8385 	dsq->overlay->color.interpolateTo(Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5)), lua_tonumber(L, 6));
8386 	dsq->overlay->alpha.interpolateTo(lua_tonumber(L, 1), lua_tonumber(L, 2));
8387 	luaReturnNil();
8388 }
8389 
luaFunc(fade2)8390 luaFunc(fade2)
8391 {
8392 	dsq->overlay2->color.interpolateTo(Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5)), lua_tonumber(L, 6));
8393 	dsq->overlay2->alpha.interpolateTo(lua_tonumber(L, 1), lua_tonumber(L, 2));
8394 	luaReturnNil();
8395 }
8396 
luaFunc(fade3)8397 luaFunc(fade3)
8398 {
8399 	dsq->overlay3->color.interpolateTo(Vector(lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5)), lua_tonumber(L, 6));
8400 	dsq->overlay3->alpha.interpolateTo(lua_tonumber(L, 1), lua_tonumber(L, 2));
8401 	luaReturnNil();
8402 }
8403 
luaFunc(vision)8404 luaFunc(vision)
8405 {
8406 	dsq->vision(getString(L, 1), lua_tonumber(L, 2), getBool(L, 3));
8407 	luaReturnNil();
8408 }
8409 
luaFunc(musicVolume)8410 luaFunc(musicVolume)
8411 {
8412 	dsq->sound->setMusicFader(lua_tonumber(L, 1), lua_tonumber(L, 2));
8413 	luaReturnNil();
8414 }
8415 
luaFunc(voice)8416 luaFunc(voice)
8417 {
8418 	float vmod = lua_tonumber(L, 2);
8419 	if (vmod == 0)
8420 		vmod = -1;
8421 	else if (vmod == -1)
8422 		vmod = 0;
8423 	dsq->voice(getString(L, 1), vmod);
8424 	luaReturnNil();
8425 }
8426 
luaFunc(voiceOnce)8427 luaFunc(voiceOnce)
8428 {
8429 	dsq->voiceOnce(getString(L, 1));
8430 	luaReturnNil();
8431 }
8432 
luaFunc(voiceInterupt)8433 luaFunc(voiceInterupt)
8434 {
8435 	dsq->voiceInterupt(getString(L, 1));
8436 	luaReturnNil();
8437 }
8438 
luaFunc(stopVoice)8439 luaFunc(stopVoice)
8440 {
8441 	dsq->stopVoice();
8442 	luaReturnNil();
8443 }
8444 
luaFunc(stopAllSfx)8445 luaFunc(stopAllSfx)
8446 {
8447 	dsq->sound->stopAllSfx();
8448 	luaReturnNil();
8449 }
8450 
luaFunc(stopAllVoice)8451 luaFunc(stopAllVoice)
8452 {
8453 	dsq->sound->stopAllVoice();
8454 	luaReturnNil();
8455 }
8456 
luaFunc(fadeIn)8457 luaFunc(fadeIn)
8458 {
8459 	dsq->overlay->alpha.interpolateTo(0, lua_tonumber(L, 1));
8460 	luaReturnNil();
8461 }
8462 
luaFunc(fadeOut)8463 luaFunc(fadeOut)
8464 {
8465 	dsq->overlay->color = 0;
8466 	dsq->overlay->alpha.interpolateTo(1, lua_tonumber(L, 1));
8467 	luaReturnNil();
8468 }
8469 
luaFunc(entity_setWeight)8470 luaFunc(entity_setWeight)
8471 {
8472 	CollideEntity *e = collideEntity(L);
8473 	if (e)
8474 		e->weight = lua_tonumber(L, 2);
8475 	luaReturnNil();
8476 }
8477 
luaFunc(entity_getWeight)8478 luaFunc(entity_getWeight)
8479 {
8480 	CollideEntity *e = collideEntity(L);
8481 	luaReturnNum(e ? e->weight : 0.0f);
8482 }
8483 
luaFunc(pickupGem)8484 luaFunc(pickupGem)
8485 {
8486 	dsq->continuity.pickupGem(getString(L), !getBool(L, 2));
8487 	luaReturnInt(dsq->continuity.gems.size() - 1);
8488 }
8489 
luaFunc(setGemPosition)8490 luaFunc(setGemPosition)
8491 {
8492 	int gemId = lua_tointeger(L, 1);
8493 	std::string mapname = getString(L, 4);
8494 	if(mapname.empty())
8495 		mapname = dsq->game->sceneName;
8496 	Vector pos(lua_tonumber(L, 2), lua_tonumber(L, 3));
8497 	bool result = false;
8498 
8499 	WorldMapTile *tile = dsq->continuity.worldMap.getWorldMapTile(mapname);
8500 	if(tile)
8501 	{
8502 		pos = dsq->game->worldMapRender->getWorldToTile(tile, pos, true, true);
8503 		if(gemId >= 0 && gemId < dsq->continuity.gems.size())
8504 		{
8505 			Continuity::Gems::iterator it = dsq->continuity.gems.begin();
8506 			std::advance(it, gemId);
8507 			GemData& gem = *it;
8508 			gem.pos = pos;
8509 			gem.mapName = mapname;
8510 			result = true;
8511 		}
8512 		else
8513 		{
8514 			debugLog("setGemPosition: invalid index");
8515 		}
8516 	}
8517 	else
8518 	{
8519 		debugLog("setGemPosition: Map tile does not exist: " + mapname);
8520 	}
8521 	luaReturnBool(result);
8522 }
8523 
luaFunc(setGemName)8524 luaFunc(setGemName)
8525 {
8526 	int gemId = lua_tointeger(L, 1);
8527 	bool result = false;
8528 
8529 	if(gemId >= 0 && gemId < dsq->continuity.gems.size())
8530 	{
8531 		Continuity::Gems::iterator it = dsq->continuity.gems.begin();
8532 		std::advance(it, gemId);
8533 		GemData& gem = *it;
8534 		gem.name = getString(L, 2);
8535 		result = true;
8536 	}
8537 	else
8538 		debugLog("setGemName: invalid index");
8539 
8540 	luaReturnBool(result);
8541 }
8542 
luaFunc(setGemBlink)8543 luaFunc(setGemBlink)
8544 {
8545 	int gemId = lua_tointeger(L, 1);
8546 	bool result = false;
8547 
8548 	if(gemId >= 0 && gemId < dsq->continuity.gems.size())
8549 	{
8550 		Continuity::Gems::iterator it = dsq->continuity.gems.begin();
8551 		std::advance(it, gemId);
8552 		GemData& gem = *it;
8553 		gem.blink = getBool(L, 2);
8554 		result = true;
8555 	}
8556 	else
8557 		debugLog("setGemBlink: invalid index");
8558 
8559 	luaReturnBool(result);
8560 }
8561 
luaFunc(removeGem)8562 luaFunc(removeGem)
8563 {
8564 	int gemId = lua_tointeger(L, 1);
8565 	if(gemId >= 0 && gemId < dsq->continuity.gems.size())
8566 	{
8567 		Continuity::Gems::iterator it = dsq->continuity.gems.begin();
8568 		std::advance(it, gemId);
8569 		dsq->continuity.removeGemData(&(*it));
8570 		if(dsq->game->worldMapRender->isOn())
8571 			dsq->game->worldMapRender->fixGems();
8572 	}
8573 	luaReturnNil();
8574 }
8575 
luaFunc(beaconEffect)8576 luaFunc(beaconEffect)
8577 {
8578 	int index = lua_tointeger(L, 1);
8579 
8580 	BeaconData *b = dsq->continuity.getBeaconByIndex(index);
8581 
8582 	float p1 = 0.7f;
8583 	float p2 = 1.0f - p1;
8584 
8585 	dsq->clickRingEffect(dsq->game->miniMapRender->getWorldPosition(), 0, (b->color*p1) + Vector(p2, p2, p2), 1);
8586 	dsq->clickRingEffect(dsq->game->miniMapRender->getWorldPosition(), 1, (b->color*p1) + Vector(p2, p2, p2), 1);
8587 
8588 	dsq->sound->playSfx("ping");
8589 
8590 	luaReturnNil();
8591 }
8592 
luaFunc(setBeacon)8593 luaFunc(setBeacon)
8594 {
8595 	int index = lua_tointeger(L, 1);
8596 
8597 	bool v = getBool(L, 2);
8598 
8599 	Vector pos;
8600 	pos.x = lua_tonumber(L, 3);
8601 	pos.y = lua_tonumber(L, 4);
8602 
8603 	Vector color;
8604 	color.x = lua_tonumber(L, 5);
8605 	color.y = lua_tonumber(L, 6);
8606 	color.z = lua_tonumber(L, 7);
8607 
8608 	dsq->continuity.setBeacon(index, v, pos, color);
8609 
8610 	luaReturnNil();
8611 }
8612 
luaFunc(getBeacon)8613 luaFunc(getBeacon)
8614 {
8615 	int index = lua_tointeger(L, 1);
8616 	bool v = false;
8617 
8618 	if (dsq->continuity.getBeaconByIndex(index))
8619 	{
8620 		v = true;
8621 	}
8622 
8623 	luaReturnBool(v);
8624 }
8625 
luaFunc(getCostume)8626 luaFunc(getCostume)
8627 {
8628 	luaReturnStr(dsq->continuity.costume.c_str());
8629 }
8630 
luaFunc(setCostume)8631 luaFunc(setCostume)
8632 {
8633 	dsq->continuity.setCostume(getString(L));
8634 	luaReturnNil();
8635 }
8636 
luaFunc(setLayerRenderPass)8637 luaFunc(setLayerRenderPass)
8638 {
8639 	int layer = lua_tointeger(L, 1);
8640 	int startPass = lua_tointeger(L, 2);
8641 	int endPass = lua_tointeger(L, 3);
8642 	if(layer >= 0 && layer < core->renderObjectLayers.size())
8643 	{
8644 		core->renderObjectLayers[layer].startPass = startPass;
8645 		core->renderObjectLayers[layer].endPass = endPass;
8646 	}
8647 	luaReturnNil();
8648 }
8649 
luaFunc(setElementLayerVisible)8650 luaFunc(setElementLayerVisible)
8651 {
8652 	int l = lua_tointeger(L, 1);
8653 	bool v = getBool(L, 2);
8654 	dsq->game->setElementLayerVisible(l, v);
8655 	luaReturnNil();
8656 }
8657 
luaFunc(isElementLayerVisible)8658 luaFunc(isElementLayerVisible)
8659 {
8660 	luaReturnBool(dsq->game->isElementLayerVisible(lua_tonumber(L, 1)));
8661 }
8662 
luaFunc(isStreamingVoice)8663 luaFunc(isStreamingVoice)
8664 {
8665 	bool v = dsq->sound->isPlayingVoice();
8666 	luaReturnBool(v);
8667 }
8668 
luaFunc(isObstructed)8669 luaFunc(isObstructed)
8670 {
8671 	int obs = lua_tointeger(L, 3);
8672 	luaReturnBool(dsq->game->isObstructed(TileVector(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2))), obs ? obs : -1));
8673 }
8674 
luaFunc(getObstruction)8675 luaFunc(getObstruction)
8676 {
8677 	luaReturnInt(dsq->game->getGrid(TileVector(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)))));
8678 }
8679 
luaFunc(getGridRaw)8680 luaFunc(getGridRaw)
8681 {
8682 	luaReturnInt(dsq->game->getGridRaw(TileVector(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)))));
8683 }
8684 
luaFunc(isObstructedBlock)8685 luaFunc(isObstructedBlock)
8686 {
8687 	float x = lua_tonumber(L, 1);
8688 	float y = lua_tonumber(L, 2);
8689 	int span = lua_tointeger(L, 3);
8690 	TileVector t(Vector(x,y));
8691 
8692 	bool obs = false;
8693 	for (int xx = t.x-span; xx <= t.x+span; xx++)
8694 	{
8695 		for (int yy = t.y-span; yy <= t.y+span; yy++)
8696 		{
8697 			if (dsq->game->isObstructed(TileVector(xx, yy)))
8698 			{
8699 				obs = true;
8700 				break;
8701 			}
8702 		}
8703 	}
8704 	luaReturnBool(obs);
8705 }
8706 
luaFunc(node_getFlag)8707 luaFunc(node_getFlag)
8708 {
8709 	Path *p = path(L);
8710 	int v = 0;
8711 	if (p)
8712 	{
8713 		v = dsq->continuity.getPathFlag(p);
8714 	}
8715 	luaReturnNum(v);
8716 }
8717 
luaFunc(node_isFlag)8718 luaFunc(node_isFlag)
8719 {
8720 	Path *p = path(L);
8721 	int c = lua_tointeger(L, 2);
8722 	bool ret = false;
8723 	if (p)
8724 	{
8725 		ret = (c == dsq->continuity.getPathFlag(p));
8726 	}
8727 	luaReturnBool(ret);
8728 }
8729 
luaFunc(node_setFlag)8730 luaFunc(node_setFlag)
8731 {
8732 	Path *p = path(L);
8733 	int v = lua_tointeger(L, 2);
8734 	if (p)
8735 	{
8736 		dsq->continuity.setPathFlag(p, v);
8737 	}
8738 	luaReturnNum(v);
8739 }
8740 
luaFunc(entity_isFlag)8741 luaFunc(entity_isFlag)
8742 {
8743 	Entity *e = entity(L);
8744 	int v = lua_tointeger(L, 2);
8745 	bool b = false;
8746 	if (e)
8747 	{
8748 		b = (dsq->continuity.getEntityFlag(dsq->game->sceneName, e->getID())==v);
8749 	}
8750 	luaReturnBool(b);
8751 }
8752 
luaFunc(entity_setFlag)8753 luaFunc(entity_setFlag)
8754 {
8755 	Entity *e = entity(L);
8756 	int v = lua_tointeger(L, 2);
8757 	if (e)
8758 	{
8759 		dsq->continuity.setEntityFlag(dsq->game->sceneName, e->getID(), v);
8760 	}
8761 	luaReturnNil();
8762 }
8763 
luaFunc(entity_setPoison)8764 luaFunc(entity_setPoison)
8765 {
8766 	Entity *e = entity(L);
8767 	if(e)
8768 		e->setPoison(lua_tonumber(L, 2), lua_tonumber(L, 3));
8769 	luaReturnNil();
8770 }
8771 
luaFunc(entity_getPoison)8772 luaFunc(entity_getPoison)
8773 {
8774 	Entity *e = entity(L);
8775 	luaReturnNum(e ? e->getPoison() : 0.0f);
8776 }
8777 
luaFunc(entity_getFlag)8778 luaFunc(entity_getFlag)
8779 {
8780 	Entity *e = entity(L);
8781 	int ret = 0;
8782 	if (e)
8783 	{
8784 		ret = dsq->continuity.getEntityFlag(dsq->game->sceneName, e->getID());
8785 	}
8786 	luaReturnNum(ret);
8787 }
8788 
luaFunc(isFlag)8789 luaFunc(isFlag)
8790 {
8791 	int v = 0;
8792 	/*
8793 	if (lua_isstring(L, 1))
8794 		v = dsq->continuity.getFlag(lua_tostring(L, 1));
8795 	else if (lua_isnumber(L, 1))
8796 	*/
8797 	bool f = false;
8798 	if (lua_isnumber(L, 1))
8799 	{
8800 		v = dsq->continuity.getFlag(lua_tointeger(L, 1));
8801 		f = (v == lua_tointeger(L, 2));
8802 	}
8803 	else
8804 	{
8805 		v = dsq->continuity.getFlag(getString(L, 1));
8806 		f = (v == lua_tointeger(L, 2));
8807 	}
8808 	/*
8809 	int f = 0;
8810 	dsq->continuity.getFlag(lua_tostring(L, 1));
8811 
8812 	*/
8813 	luaReturnBool(f);
8814 }
8815 
luaFunc(avatar_updatePosition)8816 luaFunc(avatar_updatePosition)
8817 {
8818 	dsq->game->avatar->updatePosition();
8819 	luaReturnNil();
8820 }
8821 
luaFunc(avatar_toggleMovement)8822 luaFunc(avatar_toggleMovement)
8823 {
8824 	dsq->game->avatar->toggleMovement(getBool(L));
8825 	luaReturnNil();
8826 }
8827 
luaFunc(clearShots)8828 luaFunc(clearShots)
8829 {
8830 	Shot::killAllShots();
8831 	luaReturnNil();
8832 }
8833 
luaFunc(clearHelp)8834 luaFunc(clearHelp)
8835 {
8836 	float t = 0.4;
8837 
8838 	RenderObjectLayer *rl = &core->renderObjectLayers[LR_HELP];
8839 	RenderObject *ro = rl->getFirst();
8840 	while (ro)
8841 	{
8842 		ro->setLife(t);
8843 		ro->setDecayRate(1);
8844 		ro->alpha.stopPath();
8845 		ro->alpha.interpolateTo(0,t-0.01f);
8846 
8847 		ro = rl->getNext();
8848 	}
8849 
8850 	luaReturnNil();
8851 }
8852 
luaFunc(setLiPower)8853 luaFunc(setLiPower)
8854 {
8855 	float m = lua_tonumber(L, 1);
8856 	float t = lua_tonumber(L, 2);
8857 	dsq->continuity.setLiPower(m, t);
8858 	luaReturnNil();
8859 }
8860 
luaFunc(getLiPower)8861 luaFunc(getLiPower)
8862 {
8863 	luaReturnNum(dsq->continuity.liPower);
8864 }
8865 
luaFunc(getPetPower)8866 luaFunc(getPetPower)
8867 {
8868 	luaReturnNum(dsq->continuity.petPower);
8869 }
8870 
luaFunc(appendUserDataPath)8871 luaFunc(appendUserDataPath)
8872 {
8873 	std::string path = getString(L, 1);
8874 
8875 	if (!dsq->getUserDataFolder().empty())
8876 		path = dsq->getUserDataFolder() + "/" + path;
8877 
8878 	luaReturnStr(path.c_str());
8879 }
8880 
luaFunc(getScreenVirtualOff)8881 luaFunc(getScreenVirtualOff)
8882 {
8883 	luaReturnVec2(core->getVirtualOffX(), core->getVirtualOffY());
8884 }
8885 
luaFunc(getScreenSize)8886 luaFunc(getScreenSize)
8887 {
8888 	luaReturnVec2(core->width, core->height);
8889 }
8890 
luaFunc(getScreenVirtualSize)8891 luaFunc(getScreenVirtualSize)
8892 {
8893 	luaReturnVec2(core->getVirtualWidth(), core->getVirtualHeight());
8894 }
8895 
luaFunc(isMiniMapCursorOkay)8896 luaFunc(isMiniMapCursorOkay)
8897 {
8898 	luaReturnBool(dsq->isMiniMapCursorOkay());
8899 }
8900 
luaFunc(isShuttingDownGameState)8901 luaFunc(isShuttingDownGameState)
8902 {
8903 	luaReturnBool(dsq->game->isShuttingDownGameState());
8904 }
8905 
_fillPathfindTables(lua_State * L,VectorPath & path,int xs_idx,int ys_idx)8906 static void _fillPathfindTables(lua_State *L, VectorPath& path, int xs_idx, int ys_idx)
8907 {
8908 	const unsigned num = path.getNumPathNodes();
8909 
8910 	if(lua_istable(L, xs_idx))
8911 		lua_pushvalue(L, xs_idx);
8912 	else
8913 		lua_createtable(L, num, 0);
8914 
8915 	if(lua_istable(L, ys_idx))
8916 		lua_pushvalue(L, ys_idx);
8917 	else
8918 		lua_createtable(L, num, 0);
8919 
8920 	// [..., xs, yx]
8921 	for(unsigned i = 0; i < num; ++i)
8922 	{
8923 		const VectorPathNode *n = path.getPathNode(i);
8924 		lua_pushnumber(L, n->value.x);  // [..., xs, ys, x]
8925 		lua_rawseti(L, -3, i+1);        // [..., xs, ys]
8926 		lua_pushnumber(L, n->value.y);  // [..., xs, ys, y]
8927 		lua_rawseti(L, -2, i+1);        // [..., xs, ys]
8928 	}
8929 	// terminate tables
8930 	lua_pushnil(L);            // [..., xs, ys, nil]
8931 	lua_rawseti(L, -3, num+1); // [..., xs, ys]
8932 	lua_pushnil(L);            // [..., xs, ys, nil]
8933 	lua_rawseti(L, -2, num+1); // [..., xs, ys]
8934 }
8935 
_pathfindDelete(lua_State * L)8936 static int _pathfindDelete(lua_State *L)
8937 {
8938 	PathFinding::State *state = *(PathFinding::State**)luaL_checkudata(L, 1, "pathfinder");
8939 	PathFinding::deleteFindPath(state);
8940 	return 0;
8941 }
8942 
8943 // startx, starty, endx, endy [, step, xtab, ytab, obsMask]
luaFunc(findPath)8944 luaFunc(findPath)
8945 {
8946 	VectorPath path;
8947 	Vector start(lua_tonumber(L, 1), lua_tonumber(L, 2));
8948 	Vector end(lua_tonumber(L, 3), lua_tonumber(L, 4));
8949 	ObsType obs = ObsType(lua_tointeger(L, 8));
8950 	if(!PathFinding::generatePathSimple(path, start, end, lua_tointeger(L, 5), obs))
8951 		luaReturnBool(false);
8952 
8953 	const unsigned num = path.getNumPathNodes();
8954 	lua_pushinteger(L, num);
8955 
8956 	_fillPathfindTables(L, path, 6, 7);
8957 
8958 	return 3; // found path?, x positions, y positions
8959 }
8960 
luaFunc(createFindPath)8961 luaFunc(createFindPath)
8962 {
8963 	PathFinding::State **statep = (PathFinding::State**)lua_newuserdata(L, sizeof(void*));
8964 	*statep = PathFinding::initFindPath();
8965 	luaL_getmetatable(L, "pathfinder");
8966 	lua_setmetatable(L, -2);
8967 	return 1;
8968 }
8969 
luaFunc(findPathBegin)8970 luaFunc(findPathBegin)
8971 {
8972 	PathFinding::State *state = *(PathFinding::State**)luaL_checkudata(L, 1, "pathfinder");
8973 	Vector start(lua_tonumber(L, 1), lua_tonumber(L, 2));
8974 	Vector end(lua_tonumber(L, 3), lua_tonumber(L, 4));
8975 	ObsType obs = ObsType(lua_tointeger(L, 8));
8976 	PathFinding::beginFindPath(state, start, end, obs);
8977 	luaReturnNil();
8978 }
8979 
luaFunc(findPathUpdate)8980 luaFunc(findPathUpdate)
8981 {
8982 	PathFinding::State *state = *(PathFinding::State**)luaL_checkudata(L, 1, "pathfinder");
8983 	int limit = lua_tointeger(L, 2);
8984 	bool done = PathFinding::updateFindPath(state, limit);
8985 	luaReturnBool(done);
8986 }
8987 
luaFunc(findPathFinish)8988 luaFunc(findPathFinish)
8989 {
8990 	PathFinding::State *state = *(PathFinding::State**)luaL_checkudata(L, 1, "pathfinder");
8991 	VectorPath path;
8992 	bool found = PathFinding::finishFindPath(state, path);
8993 	if(!found)
8994 		luaReturnBool(false);
8995 
8996 	lua_pushinteger(L, (int)path.getNumPathNodes());
8997 	_fillPathfindTables(L, path, 2, 3);
8998 	return 3;
8999 }
9000 
luaFunc(findPathGetStats)9001 luaFunc(findPathGetStats)
9002 {
9003 	PathFinding::State *state = *(PathFinding::State**)luaL_checkudata(L, 1, "pathfinder");
9004 	unsigned stepsDone, nodesExpanded;
9005 	PathFinding::getStats(state, stepsDone, nodesExpanded);
9006 	lua_pushinteger(L, stepsDone);
9007 	lua_pushinteger(L, nodesExpanded);
9008 	return 2;
9009 }
9010 
luaFunc(castLine)9011 luaFunc(castLine)
9012 {
9013 	Vector v(lua_tonumber(L, 1), lua_tonumber(L, 2));
9014 	Vector end(lua_tonumber(L, 3), lua_tonumber(L, 4));
9015 	int tiletype = lua_tointeger(L, 5);
9016 	if(!tiletype)
9017 		tiletype = OT_BLOCKING;
9018 	Vector step = end - v;
9019 	int steps = step.getLength2D() / TILE_SIZE;
9020 	step.setLength2D(TILE_SIZE);
9021 
9022 	for(int i = 0; i < steps; ++i)
9023 	{
9024 		if(dsq->game->getGridRaw(TileVector(v)) & tiletype)
9025 		{
9026 			lua_pushinteger(L, dsq->game->getGrid(TileVector(v)));
9027 			lua_pushnumber(L, v.x);
9028 			lua_pushnumber(L, v.y);
9029 			return 3;
9030 		}
9031 		v += step;
9032 	}
9033 
9034 	lua_pushboolean(L, false);
9035 	lua_pushnumber(L, v.x);
9036 	lua_pushnumber(L, v.y);
9037 	return 3;
9038 }
9039 
luaFunc(getUserInputString)9040 luaFunc(getUserInputString)
9041 {
9042 	luaReturnStr(dsq->getUserInputString(getString(L, 1), getString(L, 2), true).c_str());
9043 }
9044 
luaFunc(getMaxCameraValues)9045 luaFunc(getMaxCameraValues)
9046 {
9047 	luaReturnVec4(dsq->game->cameraMin.x, dsq->game->cameraMin.y, dsq->game->cameraMax.x, dsq->game->cameraMax.y);
9048 }
9049 
9050 
luaFunc(inv_isFull)9051 luaFunc(inv_isFull)
9052 {
9053 	IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
9054 	bool full = false;
9055 	if(data)
9056 		full = dsq->continuity.isIngredientFull(data);
9057 	luaReturnBool(full);
9058 }
9059 
luaFunc(inv_getMaxAmount)9060 luaFunc(inv_getMaxAmount)
9061 {
9062 	IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
9063 	luaReturnInt(data ? data->maxAmount : 0);
9064 }
9065 
luaFunc(inv_getAmount)9066 luaFunc(inv_getAmount)
9067 {
9068 	IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
9069 	luaReturnInt(data ? data->amount : 0);
9070 }
9071 
luaFunc(inv_add)9072 luaFunc(inv_add)
9073 {
9074 	IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
9075 	if(data)
9076 		dsq->continuity.pickupIngredient(data, lua_tointeger(L, 2), false, false);
9077 	luaReturnNil();
9078 }
9079 
luaFunc(inv_getGfx)9080 luaFunc(inv_getGfx)
9081 {
9082 	luaReturnStr(dsq->continuity.getIngredientGfx(getString(L, 1)).c_str());
9083 }
9084 
luaFunc(inv_remove)9085 luaFunc(inv_remove)
9086 {
9087 	IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
9088 	if(data && data->amount > 0)
9089 	{
9090 		data->amount--;
9091 		dsq->game->dropIngrNames.push_back(data->name);
9092 		dsq->continuity.removeEmptyIngredients();
9093 		if(dsq->game->isInGameMenu())
9094 			dsq->game->refreshFoodSlots(true);
9095 	}
9096 	luaReturnNil();
9097 }
9098 
luaFunc(inv_getType)9099 luaFunc(inv_getType)
9100 {
9101 	IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
9102 	luaReturnInt(data ? data->type : 0);
9103 }
9104 
luaFunc(inv_getDisplayName)9105 luaFunc(inv_getDisplayName)
9106 {
9107 	IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
9108 	luaReturnStr(data ? data->displayName.c_str() : "");
9109 }
9110 
luaFunc(inv_pickupEffect)9111 luaFunc(inv_pickupEffect)
9112 {
9113 	IngredientData *data = dsq->continuity.getIngredientDataByName(getString(L, 1));
9114 	if(data)
9115 		dsq->game->pickupIngredientEffects(data);
9116 	luaReturnNil();
9117 }
9118 
luaFunc(inv_getNumItems)9119 luaFunc(inv_getNumItems)
9120 {
9121 	luaReturnInt(dsq->continuity.getIngredientHeldSize());
9122 }
9123 
luaFunc(inv_getItemName)9124 luaFunc(inv_getItemName)
9125 {
9126 	IngredientData *data = dsq->continuity.getIngredientHeldByIndex(lua_tointeger(L, 1));
9127 	luaReturnStr(data ? data->name.c_str() : "");
9128 }
9129 
9130 
luaFunc(getIngredientDataSize)9131 luaFunc(getIngredientDataSize)
9132 {
9133 	luaReturnInt(dsq->continuity.getIngredientDataSize());
9134 }
9135 
luaFunc(getIngredientDataName)9136 luaFunc(getIngredientDataName)
9137 {
9138 	IngredientData *data = dsq->continuity.getIngredientDataByIndex(lua_tointeger(L, 1));
9139 	luaReturnStr(data ? data->name.c_str() : "");
9140 }
9141 
luaFunc(learnRecipe)9142 luaFunc(learnRecipe)
9143 {
9144 	std::string name = getString(L, 1);
9145 	bool show = getBool(L, 2);
9146 	dsq->continuity.learnRecipe(name, show);
9147 	luaReturnNil();
9148 }
9149 
luaFunc(setBGGradient)9150 luaFunc(setBGGradient)
9151 {
9152 	if(!dsq->game->grad)
9153 		dsq->game->createGradient();
9154 	Vector c1(lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3));
9155 	Vector c2(lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6));
9156 	if(getBool(L, 7))
9157 		dsq->game->grad->makeHorizontal(c1, c2);
9158 	else
9159 		dsq->game->grad->makeVertical(c1, c2);
9160 	luaReturnNil();
9161 }
9162 
luaFunc(createDebugText)9163 luaFunc(createDebugText)
9164 {
9165 	DebugFont *txt = new DebugFont(lua_tointeger(L, 2), getString(L, 1));
9166 	txt->position = Vector(lua_tonumber(L, 3), lua_tonumber(L, 4));
9167 	dsq->game->addRenderObject(txt, LR_DEBUG_TEXT);
9168 	luaReturnPtr(txt);
9169 }
9170 
luaFunc(createBitmapText)9171 luaFunc(createBitmapText)
9172 {
9173 	BmpFont *font = &dsq->smallFont;
9174 	BitmapText *txt = new BitmapText(font);
9175 	txt->setText(getString(L, 1));
9176 	txt->setFontSize(lua_tointeger(L, 2));
9177 	txt->position = Vector(lua_tonumber(L, 3), lua_tonumber(L, 4));
9178 	dsq->game->addRenderObject(txt, LR_HUD);
9179 	luaReturnPtr(txt);
9180 }
9181 
createArialText(lua_State * L,TTFFont * font)9182 static int createArialText(lua_State *L, TTFFont *font)
9183 {
9184 	TTFText *txt = new TTFText(font);
9185 	txt->setText(getString(L, 1));
9186 	//txt->setFontSize(lua_tointeger(L, 2)); // not supported; param is ignored for API compat with the create*Text functions
9187 	txt->position = Vector(lua_tonumber(L, 3), lua_tonumber(L, 4));
9188 	dsq->game->addRenderObject(txt, LR_HUD);
9189 	luaReturnPtr(txt);
9190 }
9191 
luaFunc(createArialTextBig)9192 luaFunc(createArialTextBig)
9193 {
9194 	return createArialText(L, &dsq->fontArialBig);
9195 }
9196 
luaFunc(createArialTextSmall)9197 luaFunc(createArialTextSmall)
9198 {
9199 	return createArialText(L, &dsq->fontArialSmall);
9200 }
9201 
9202 
luaFunc(text_setText)9203 luaFunc(text_setText)
9204 {
9205 	BaseText *txt = getText(L);
9206 	if (txt)
9207 		txt->setText(getString(L, 2));
9208 	luaReturnNil();
9209 }
9210 
luaFunc(text_setFontSize)9211 luaFunc(text_setFontSize)
9212 {
9213 	BaseText *txt = getText(L);
9214 	if (txt)
9215 		txt->setFontSize(lua_tonumber(L, 2));
9216 	luaReturnNil();
9217 }
9218 
luaFunc(text_setWidth)9219 luaFunc(text_setWidth)
9220 {
9221 	BaseText *txt = getText(L);
9222 	if (txt)
9223 		txt->setWidth(lua_tonumber(L, 2));
9224 	luaReturnNil();
9225 }
9226 
luaFunc(text_setAlign)9227 luaFunc(text_setAlign)
9228 {
9229 	BaseText *txt = getText(L);
9230 	if (txt)
9231 		txt->setAlign((Align)lua_tointeger(L, 2));
9232 	luaReturnNil();
9233 }
9234 
luaFunc(text_getHeight)9235 luaFunc(text_getHeight)
9236 {
9237 	BaseText *txt = getText(L);
9238 	luaReturnNum(txt ? txt->getHeight() : 0.0f);
9239 }
9240 
luaFunc(text_getLineHeight)9241 luaFunc(text_getLineHeight)
9242 {
9243 	BaseText *txt = getText(L);
9244 	luaReturnNum(txt ? txt->getLineHeight() : 0.0f);
9245 }
9246 
luaFunc(text_getNumLines)9247 luaFunc(text_getNumLines)
9248 {
9249 	BaseText *txt = getText(L);
9250 	luaReturnInt(txt ? txt->getNumLines() : 0);
9251 }
9252 
luaFunc(text_getStringWidth)9253 luaFunc(text_getStringWidth)
9254 {
9255 	BaseText *txt = getText(L);
9256 	luaReturnNum(txt ? txt->getStringWidth(getString(L, 2)) : 0.0f);
9257 }
9258 
luaFunc(text_getActualWidth)9259 luaFunc(text_getActualWidth)
9260 {
9261 	BaseText *txt = getText(L);
9262 	luaReturnNum(txt ? txt->getActualWidth() : 0.0f);
9263 }
9264 
luaFunc(loadShader)9265 luaFunc(loadShader)
9266 {
9267 	int handle = 0;
9268 	const char *vertRaw = getCString(L, 1);
9269 	const char *fragRaw = getCString(L, 2);
9270 	std::string vert, frag;
9271 	if(vertRaw)
9272 		findFile_helper(vertRaw, vert);
9273 	if(fragRaw)
9274 		findFile_helper(fragRaw, frag);
9275 
9276 	if(core->afterEffectManager)
9277 		handle = core->afterEffectManager->loadShaderFile(vert.c_str(), frag.c_str());
9278 
9279 	luaReturnInt(handle);
9280 }
9281 
luaFunc(createShader)9282 luaFunc(createShader)
9283 {
9284 	int handle = 0;
9285 	if(core->afterEffectManager)
9286 		handle = core->afterEffectManager->loadShaderSrc(getCString(L, 1), getCString(L, 2));
9287 	luaReturnInt(handle);
9288 }
9289 
luaFunc(shader_setAsAfterEffect)9290 luaFunc(shader_setAsAfterEffect)
9291 {
9292 	int handle = lua_tointeger(L, 1);
9293 	int pos = lua_tointeger(L, 2);
9294 	bool done = false;
9295 
9296 	if(core->afterEffectManager)
9297 		done = core->afterEffectManager->setShaderPipelinePos(handle, pos);
9298 
9299 	luaReturnBool(done);
9300 }
9301 
luaFunc(shader_setNumAfterEffects)9302 luaFunc(shader_setNumAfterEffects)
9303 {
9304 	if(core->afterEffectManager)
9305 		core->afterEffectManager->setShaderPipelineSize(lua_tointeger(L, 1));
9306 	luaReturnNil();
9307 }
9308 
luaFunc(shader_setInt)9309 luaFunc(shader_setInt)
9310 {
9311 	if(core->afterEffectManager)
9312 	{
9313 		Shader *sh = core->afterEffectManager->getShaderPtr(lua_tointeger(L, 1));
9314 		const char *name = getCString(L, 2);
9315 		if(sh && name)
9316 			sh->setInt(name, lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5), lua_tointeger(L, 6));
9317 	}
9318 	luaReturnNil();
9319 }
9320 
luaFunc(shader_setFloat)9321 luaFunc(shader_setFloat)
9322 {
9323 	if(core->afterEffectManager)
9324 	{
9325 		Shader *sh = core->afterEffectManager->getShaderPtr(lua_tointeger(L, 1));
9326 		const char *name = getCString(L, 2);
9327 		if(sh && name)
9328 			sh->setFloat(name, lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6));
9329 	}
9330 	luaReturnNil();
9331 }
9332 
luaFunc(shader_delete)9333 luaFunc(shader_delete)
9334 {
9335 	if(core->afterEffectManager)
9336 		core->afterEffectManager->deleteShader(lua_tointeger(L, 1));
9337 	luaReturnNil();
9338 }
9339 
luaFunc(pe_start)9340 luaFunc(pe_start)
9341 {
9342 	ParticleEffect *pe = getParticle(L);
9343 	if (pe)
9344 		pe->start();
9345 	luaReturnNil();
9346 }
9347 
luaFunc(pe_stop)9348 luaFunc(pe_stop)
9349 {
9350 	ParticleEffect *pe = getParticle(L);
9351 	if (pe)
9352 		pe->stop();
9353 	luaReturnNil();
9354 }
9355 
luaFunc(pe_isRunning)9356 luaFunc(pe_isRunning)
9357 {
9358 	ParticleEffect *pe = getParticle(L);
9359 	luaReturnBool(pe && pe->isRunning());
9360 }
9361 
luaFunc(getPerformanceCounter)9362 luaFunc(getPerformanceCounter)
9363 {
9364 #ifdef BBGE_BUILD_SDL2
9365 	luaReturnNum((lua_Number)SDL_GetPerformanceCounter());
9366 #else
9367 	luaReturnNum((lua_Number)SDL_GetTicks());
9368 #endif
9369 }
9370 
luaFunc(getPerformanceFreq)9371 luaFunc(getPerformanceFreq)
9372 {
9373 #ifdef BBGE_BUILD_SDL2
9374 	luaReturnNum((lua_Number)SDL_GetPerformanceFrequency());
9375 #else
9376 	luaReturnNum((lua_Number)1000);
9377 #endif
9378 }
9379 
9380 //--------------------------------------------------------------------------------------------
9381 
9382 #define luaRegister(func)	{#func, l_##func}
9383 
9384 static const struct {
9385 	const char *name;
9386 	lua_CFunction func;
9387 } luaFunctionTable[] = {
9388 
9389 	// override Lua's standard dofile() and loadfile(), so we can handle filename case issues.
9390 	{"dofile", l_dofile_caseinsensitive},
9391 	{"loadfile", l_loadfile_caseinsensitive},
9392 
9393 	luaRegister(fileExists),
9394 	luaRegister(getModName),
9395 	luaRegister(getModPath),
9396 
9397 	luaRegister(debugBreak),
9398 	luaRegister(setIgnoreAction),
9399 	luaRegister(isIgnoreAction),
9400 	luaRegister(sendAction),
9401 
9402 	luaRegister(rumble),
9403 	luaRegister(shakeCamera),
9404 	luaRegister(upgradeHealth),
9405 
9406 	luaRegister(cureAllStatus),
9407 	luaRegister(setPoison),
9408 	luaRegister(setMusicToPlay),
9409 	luaRegister(confirm),
9410 
9411 	luaRegister(randRange),
9412 
9413 	luaRegister(flingMonkey),
9414 
9415 
9416 	luaRegister(setLiPower),
9417 	luaRegister(getLiPower),
9418 	luaRegister(getPetPower),
9419 	luaRegister(getTimer),
9420 	luaRegister(getHalfTimer),
9421 	luaRegister(getOldDT),
9422 	luaRegister(getDT),
9423 	luaRegister(getFPS),
9424 	luaRegister(setCostume),
9425 	luaRegister(getCostume),
9426 	luaRegister(getNoteName),
9427 
9428 	luaRegister(getWorldType),
9429 	luaRegister(setWorldType),
9430 	luaRegister(setWorldPaused),
9431 	luaRegister(isWorldPaused),
9432 
9433 	luaRegister(getWaterLevel),
9434 	luaRegister(setWaterLevel),
9435 
9436 	luaRegister(createQuad),
9437 	luaRegister(quad_setPauseLevel),
9438 
9439 	luaRegister(setupEntity),
9440 	luaRegister(setActivePet),
9441 
9442 	luaRegister(reconstructGrid),
9443 	luaRegister(reconstructEntityGrid),
9444 	luaRegister(dilateGrid),
9445 
9446 	luaRegister(ing_hasIET),
9447 	luaRegister(ing_getIngredientName),
9448 
9449 	luaRegister(esetv),
9450 	luaRegister(esetvf),
9451 	luaRegister(egetv),
9452 	luaRegister(egetvf),
9453 	luaRegister(eisv),
9454 
9455 	luaRegister(entity_addIgnoreShotDamageType),
9456 	luaRegister(entity_ensureLimit),
9457 	luaRegister(entity_getBoneLockEntity),
9458 	luaRegister(entity_getBoneLockData),
9459 
9460 	luaRegister(entity_setRidingPosition),
9461 	luaRegister(entity_setRidingData),
9462 	luaRegister(entity_getRidingPosition),
9463 	luaRegister(entity_getRidingRotation),
9464 	luaRegister(entity_getRidingFlip),
9465 	luaRegister(entity_setBoneLock),
9466 	luaRegister(entity_setIngredient),
9467 	luaRegister(entity_setDeathScene),
9468 	luaRegister(entity_isDeathScene),
9469 
9470 	luaRegister(entity_setBeautyFlip),
9471 	luaRegister(entity_setInvincible),
9472 
9473 	luaRegister(setInvincible),
9474 
9475 	luaRegister(entity_setLookAtPoint),
9476 	luaRegister(entity_getLookAtPoint),
9477 
9478 	luaRegister(entity_setDieTimer),
9479 	luaRegister(entity_setAutoSkeletalUpdate),
9480 	luaRegister(entity_updateSkeletal),
9481 	luaRegister(entity_setBounceType),
9482 
9483 	luaRegister(entity_getHealthPerc),
9484 	luaRegister(entity_getBounceType),
9485 	luaRegister(entity_setRiding),
9486 	luaRegister(entity_getRiding),
9487 
9488 	luaRegister(entity_setNaijaReaction),
9489 
9490 	luaRegister(entity_setEatType),
9491 
9492 	luaRegister(entity_setSpiritFreeze),
9493 	luaRegister(entity_setPauseFreeze),
9494 	luaRegister(node_setSpiritFreeze),
9495 	luaRegister(node_setPauseFreeze),
9496 
9497 	luaRegister(entity_setCanLeaveWater),
9498 
9499 	luaRegister(entity_pullEntities),
9500 
9501 	luaRegister(entity_setEntityLayer),
9502 
9503 	luaRegister(entity_clearTargetPoints),
9504 	luaRegister(entity_addTargetPoint),
9505 
9506 
9507 	luaRegister(entity_setCullRadius),
9508 
9509 	luaRegister(entity_switchLayer),
9510 
9511 	luaRegister(entity_debugText),
9512 
9513 
9514 	luaRegister(avatar_setCanDie),
9515 	luaRegister(setCanActivate),
9516 	luaRegister(setSeeMapMode),
9517 	luaRegister(avatar_toggleCape),
9518 	luaRegister(avatar_setPullTarget),
9519 
9520 	luaRegister(avatar_setCanLockToWall),
9521 	luaRegister(avatar_canLockToWall),
9522 	luaRegister(avatar_setCanBurst),
9523 	luaRegister(avatar_canBurst),
9524 	luaRegister(avatar_setCanSwimAgainstCurrents),
9525 	luaRegister(avatar_canSwimAgainstCurrents),
9526 	luaRegister(avatar_setCanCollideWithShots),
9527 	luaRegister(avatar_canCollideWithShots),
9528 	luaRegister(avatar_setCollisionAvoidanceData),
9529 
9530 	luaRegister(avatar_clampPosition),
9531 	luaRegister(avatar_updatePosition),
9532 
9533 	luaRegister(pause),
9534 	luaRegister(unpause),
9535 	luaRegister(isPaused),
9536 	luaRegister(isInGameMenu),
9537 	luaRegister(isInEditor),
9538 
9539 
9540 	luaRegister(vector_normalize),
9541 	luaRegister(vector_setLength),
9542 	luaRegister(vector_getLength),
9543 
9544 	luaRegister(vector_dot),
9545 
9546 	luaRegister(vector_isLength2DIn),
9547 	luaRegister(vector_cap),
9548 
9549 
9550 	luaRegister(entity_setDeathParticleEffect),
9551 	luaRegister(entity_setDeathSound),
9552 
9553 	luaRegister(entity_setDamageTarget),
9554 	luaRegister(entity_setAllDamageTargets),
9555 
9556 	luaRegister(entity_isDamageTarget),
9557 	luaRegister(entity_isValidTarget),
9558 
9559 	luaRegister(entity_isUnderWater),
9560 	luaRegister(entity_checkSplash),
9561 	luaRegister(entity_isInCurrent),
9562 
9563 	luaRegister(entity_getRandomTargetPoint),
9564 	luaRegister(entity_getTargetPoint),
9565 	luaRegister(entity_getNumTargetPoints),
9566 
9567 	luaRegister(entity_setTargetRange),
9568 	luaRegister(entity_getTargetRange),
9569 
9570 	luaRegister(bone_addSegment),
9571 
9572 	luaRegister(bone_setSegmentOffset),
9573 	luaRegister(bone_setSegmentProps),
9574 	luaRegister(bone_setSegmentChainHead),
9575 	luaRegister(bone_setAnimated),
9576 	luaRegister(bone_showFrame),
9577 
9578 	luaRegister(bone_lookAtEntity),
9579 	luaRegister(bone_lookAtPosition),
9580 
9581 	luaRegister(entity_partSetSegs),
9582 
9583 	luaRegister(entity_adjustPositionBySurfaceNormal),
9584 	luaRegister(entity_applySurfaceNormalForce),
9585 
9586 	luaRegister(entity_doElementInteraction),
9587 	luaRegister(avatar_setElementEffectMult),
9588 
9589 	luaRegister(createBeam),
9590 	luaRegister(beam_setAngle),
9591 	luaRegister(beam_setDamage),
9592 	luaRegister(beam_setBeamWidth),
9593 	luaRegister(beam_setFirer),
9594 	luaRegister(beam_setDamageType),
9595 	luaRegister(beam_getEndPos),
9596 
9597 	luaRegister(getStringBank),
9598 
9599 	luaRegister(isPlat),
9600 
9601 
9602 	luaRegister(createEntity),
9603 	luaRegister(entity_setWeight),
9604 	luaRegister(entity_getWeight),
9605 
9606 	luaRegister(entity_setActivationType),
9607 
9608 	luaRegister(isQuitFlag),
9609 	luaRegister(isDeveloperKeys),
9610 	luaRegister(isDemo),
9611 
9612 	luaRegister(isInputEnabled),
9613 	luaRegister(disableInput),
9614 
9615 	luaRegister(getInputMode),
9616 	luaRegister(getJoystickAxisLeft),
9617 	luaRegister(getJoystickAxisRight),
9618 
9619 	luaRegister(setMousePos),
9620 	luaRegister(getMousePos),
9621 	luaRegister(getMouseWorldPos),
9622 	luaRegister(getMouseWheelChange),
9623 	luaRegister(setMouseConstraintCircle),
9624 	luaRegister(setMouseConstraint),
9625 
9626 	luaRegister(resetContinuity),
9627 
9628 	luaRegister(quit),
9629 	luaRegister(doModSelect),
9630 	luaRegister(doLoadMenu),
9631 
9632 
9633 	luaRegister(enableInput),
9634 	luaRegister(fade),
9635 	luaRegister(fade2),
9636 	luaRegister(fade3),
9637 
9638 	luaRegister(getMapName),
9639 	luaRegister(isMapName),
9640 	luaRegister(mapNameContains),
9641 
9642 	luaRegister(entity_getAimVector),
9643 
9644 	luaRegister(entity_getVectorToEntity),
9645 
9646 	luaRegister(entity_getDistanceToTarget),
9647 	luaRegister(entity_getDistanceToPoint),
9648 	luaRegister(entity_move),
9649 
9650 	luaRegister(entity_getID),
9651 
9652 	luaRegister(getEntityByID),
9653 
9654 	luaRegister(entity_setBounce),
9655 	luaRegister(entity_setActivation),
9656 	luaRegister(entity_rotateToEntity),
9657 
9658 	luaRegister(entity_fireGas),
9659 	luaRegister(entity_rotateToTarget),
9660 
9661 	luaRegister(entity_switchSurfaceDirection),
9662 
9663 	luaRegister(entity_moveAlongSurface),
9664 	luaRegister(entity_rotateToSurfaceNormal),
9665 	luaRegister(entity_clampToSurface),
9666 	luaRegister(entity_checkSurface),
9667 	luaRegister(entity_clampToHit),
9668 
9669 	luaRegister(entity_grabTarget),
9670 	luaRegister(entity_releaseTarget),
9671 
9672 	luaRegister(entity_getStateTime),
9673 	luaRegister(entity_setStateTime),
9674 
9675 	luaRegister(entity_doFriction),
9676 
9677 	luaRegister(entity_partWidthHeight),
9678 	luaRegister(entity_partBlendType),
9679 	luaRegister(entity_partRotate),
9680 	luaRegister(entity_partAlpha),
9681 
9682 	luaRegister(entity_getHealth),
9683 	luaRegister(entity_getMaxHealth),
9684 	luaRegister(entity_pushTarget),
9685 	luaRegister(entity_getPushDamage),
9686 	luaRegister(entity_msg),
9687 	luaRegister(node_msg),
9688 	luaRegister(entity_updateMovement),
9689 	luaRegister(entity_updateCurrents),
9690 	luaRegister(entity_updateLocalWarpAreas),
9691 
9692 	luaRegister(entity_getTargetPositionX),
9693 	luaRegister(entity_getTargetPositionY),
9694 
9695 	luaRegister(avatar_incrLeaches),
9696 	luaRegister(avatar_decrLeaches),
9697 	luaRegister(entity_rotateToVel),
9698 	luaRegister(entity_rotateToVec),
9699 
9700 	luaRegister(entity_setSegsMaxDist),
9701 
9702 	luaRegister(entity_offsetUpdate),
9703 
9704 	luaRegister(entity_createEntity),
9705 	luaRegister(entity_resetTimer),
9706 	luaRegister(entity_stopTimer),
9707 	luaRegister(entity_stopPull),
9708 	luaRegister(entity_setTargetPriority),
9709 	luaRegister(entity_getTargetPriority),
9710 
9711 	luaRegister(entity_setEntityType),
9712 	luaRegister(entity_getEntityType),
9713 
9714 	luaRegister(entity_setSegmentTexture),
9715 
9716 	luaRegister(entity_spawnParticlesFromCollisionMask),
9717 	luaRegister(entity_initEmitter),
9718 	luaRegister(entity_startEmitter),
9719 	luaRegister(entity_stopEmitter),
9720 	luaRegister(entity_getEmitter),
9721 	luaRegister(entity_getNumEmitters),
9722 
9723 	luaRegister(entity_initPart),
9724 	luaRegister(entity_initSegments),
9725 	luaRegister(entity_warpSegments),
9726 	luaRegister(entity_initSkeletal),
9727 	luaRegister(entity_loadSkin),
9728 	luaRegister(entity_hasSkeletal),
9729 	luaRegister(entity_getNumAnimLayers),
9730 	luaRegister(entity_getSkeletalName),
9731 	luaRegister(entity_initStrands),
9732 
9733 	luaRegister(entity_hurtTarget),
9734 	luaRegister(entity_doSpellAvoidance),
9735 	luaRegister(entity_doEntityAvoidance),
9736 	luaRegister(entity_rotate),
9737 	luaRegister(entity_doGlint),
9738 	luaRegister(entity_findTarget),
9739 	luaRegister(entity_hasTarget),
9740 	luaRegister(entity_isInRect),
9741 	luaRegister(entity_isInDarkness),
9742 
9743 	luaRegister(entity_isRidingOnEntity),
9744 
9745 	luaRegister(entity_isBeingPulled),
9746 
9747 	luaRegister(entity_isNearObstruction),
9748 	luaRegister(entity_isDead),
9749 
9750 	luaRegister(entity_isTargetInRange),
9751 	luaRegister(entity_getDistanceToEntity),
9752 	luaRegister(entity_isEntityInside),
9753 
9754 	luaRegister(entity_isInvincible),
9755 
9756 	luaRegister(entity_isNearGround),
9757 
9758 	luaRegister(entity_moveTowardsTarget),
9759 	luaRegister(entity_moveAroundTarget),
9760 
9761 	luaRegister(entity_moveTowardsAngle),
9762 	luaRegister(entity_moveAroundAngle),
9763 	luaRegister(entity_moveTowards),
9764 	luaRegister(entity_moveAround),
9765 
9766 	luaRegister(entity_setMaxSpeed),
9767 	luaRegister(entity_getMaxSpeed),
9768 	luaRegister(entity_setMaxSpeedLerp),
9769 	luaRegister(entity_getMaxSpeedLerp),
9770 	luaRegister(entity_setState),
9771 	luaRegister(entity_getState),
9772 	luaRegister(entity_getEnqueuedState),
9773 
9774 	luaRegister(entity_getPrevState),
9775 	luaRegister(entity_doCollisionAvoidance),
9776 	luaRegister(entity_animate),
9777 	luaRegister(entity_setAnimLayerTimeMult),
9778 	luaRegister(entity_getAnimLayerTimeMult),
9779 	luaRegister(entity_stopAnimation),
9780 	luaRegister(entity_getAnimationLoop),
9781 
9782 	luaRegister(entity_setCurrentTarget),
9783 	luaRegister(entity_stopInterpolating),
9784 
9785 	luaRegister(entity_followPath),
9786 	luaRegister(entity_followPathSpeed),
9787 	luaRegister(entity_isFollowingPath),
9788 	luaRegister(entity_followEntity),
9789 	luaRegister(entity_sound),
9790 	luaRegister(entity_playSfx),
9791 
9792 	luaRegister(registerSporeDrop),
9793 
9794 	luaRegister(spawnIngredient),
9795 	luaRegister(spawnAllIngredients),
9796 	luaRegister(spawnParticleEffect),
9797 	luaRegister(spawnManaBall),
9798 
9799 	luaRegister(isEscapeKey),
9800 
9801 	luaRegister(resetTimer),
9802 
9803 	luaRegister(addInfluence),
9804 	luaRegister(setSuckPosition),
9805 	luaRegister(setSuckPosition),
9806 	luaRegister(setNumSuckPositions),
9807 	luaRegister(setupBasicEntity),
9808 	luaRegister(playMusic),
9809 	luaRegister(playMusicStraight),
9810 	luaRegister(stopMusic),
9811 
9812 	luaRegister(user_set_demo_intro),
9813 	luaRegister(user_save),
9814 
9815 	luaRegister(playMusicOnce),
9816 
9817 	luaRegister(playSfx),
9818 	luaRegister(fadeSfx),
9819 
9820 	luaRegister(emote),
9821 
9822 	luaRegister(playVisualEffect),
9823 	luaRegister(playNoEffect),
9824 	luaRegister(createShockEffect),
9825 
9826 	luaRegister(setOverrideMusic),
9827 
9828 	luaRegister(setOverrideVoiceFader),
9829 	luaRegister(setGameSpeed),
9830 	luaRegister(warpAvatar),
9831 	luaRegister(warpNaijaToSceneNode),
9832 
9833 	luaRegister(toWindowFromWorld),
9834 
9835 	luaRegister(toggleDamageSprite),
9836 
9837 	luaRegister(toggleLiCombat),
9838 
9839 	luaRegister(toggleCursor),
9840 	luaRegister(toggleBlackBars),
9841 	luaRegister(setBlackBarsColor),
9842 
9843 	luaRegister(entityFollowEntity),
9844 
9845 	luaRegister(setMiniMapHint),
9846 	luaRegister(bedEffects),
9847 
9848 	luaRegister(warpNaijaToEntity),
9849 
9850 	luaRegister(setNaijaHeadTexture),
9851 
9852 	luaRegister(incrFlag),
9853 	luaRegister(decrFlag),
9854 	luaRegister(setFlag),
9855 	luaRegister(getFlag),
9856 	luaRegister(setStringFlag),
9857 	luaRegister(getStringFlag),
9858 	luaRegister(learnSong),
9859 	luaRegister(unlearnSong),
9860 	luaRegister(hasSong),
9861 	luaRegister(hasLi),
9862 
9863 	luaRegister(setCanWarp),
9864 	luaRegister(setCanChangeForm),
9865 	luaRegister(setInvincibleOnNested),
9866 
9867 	luaRegister(setControlHint),
9868 	luaRegister(setCameraLerpDelay),
9869 	luaRegister(screenFadeGo),
9870 	luaRegister(screenFadeTransition),
9871 	luaRegister(screenFadeCapture),
9872 
9873 	luaRegister(clearControlHint),
9874 
9875 
9876 	luaRegister(savePoint),
9877 	luaRegister(saveMenu),
9878 	luaRegister(wait),
9879 	luaRegister(watch),
9880 
9881 	luaRegister(quitNestedMain),
9882 	luaRegister(isNestedMain),
9883 
9884 
9885 	luaRegister(msg),
9886 	luaRegister(centerText),
9887 	luaRegister(watchForVoice),
9888 
9889 	luaRegister(setLayerRenderPass),
9890 	luaRegister(setElementLayerVisible),
9891 	luaRegister(isElementLayerVisible),
9892 
9893 	luaRegister(isWithin),
9894 
9895 
9896 
9897 	luaRegister(pickupGem),
9898 	luaRegister(setGemPosition),
9899 	luaRegister(setGemName),
9900 	luaRegister(setGemBlink),
9901 	luaRegister(removeGem),
9902 	luaRegister(setBeacon),
9903 	luaRegister(getBeacon),
9904 	luaRegister(beaconEffect),
9905 
9906 	luaRegister(chance),
9907 
9908 	luaRegister(goToTitle),
9909 	luaRegister(jumpState),
9910 	luaRegister(getEnqueuedState),
9911 
9912 
9913 	luaRegister(fadeIn),
9914 	luaRegister(fadeOut),
9915 
9916 	luaRegister(vision),
9917 
9918 	luaRegister(musicVolume),
9919 
9920 	luaRegister(voice),
9921 	luaRegister(voiceOnce),
9922 	luaRegister(voiceInterupt),
9923 
9924 
9925 	luaRegister(stopVoice),
9926 	luaRegister(stopAllVoice),
9927 	luaRegister(stopAllSfx),
9928 
9929 
9930 
9931 	luaRegister(fadeOutMusic),
9932 
9933 
9934 	luaRegister(isStreamingVoice),
9935 
9936 	luaRegister(changeForm),
9937 	luaRegister(getForm),
9938 	luaRegister(isForm),
9939 	luaRegister(learnFormUpgrade),
9940 	luaRegister(hasFormUpgrade),
9941 
9942 
9943 	luaRegister(singSong),
9944 	luaRegister(isObstructed),
9945 	luaRegister(isObstructedBlock),
9946 	luaRegister(getObstruction),
9947 	luaRegister(getGridRaw),
9948 	luaRegister(findPath),
9949 	luaRegister(createFindPath),
9950 	luaRegister(findPathBegin),
9951 	luaRegister(findPathUpdate),
9952 	luaRegister(findPathFinish),
9953 	luaRegister(findPathGetStats),
9954 	luaRegister(castLine),
9955 	luaRegister(getUserInputString),
9956 	luaRegister(getMaxCameraValues),
9957 
9958 	luaRegister(isFlag),
9959 
9960 	luaRegister(entity_isFlag),
9961 	luaRegister(entity_setFlag),
9962 	luaRegister(entity_getFlag),
9963 
9964 	luaRegister(node_isFlag),
9965 	luaRegister(node_setFlag),
9966 	luaRegister(node_getFlag),
9967 
9968 	luaRegister(avatar_getStillTimer),
9969 	luaRegister(avatar_getSpellCharge),
9970 
9971 	luaRegister(avatar_isSinging),
9972 	luaRegister(avatar_isTouchHit),
9973 	luaRegister(avatar_isBursting),
9974 	luaRegister(avatar_isLockable),
9975 	luaRegister(avatar_isRolling),
9976 	luaRegister(avatar_isSwimming),
9977 	luaRegister(avatar_isOnWall),
9978 	luaRegister(avatar_isShieldActive),
9979 	luaRegister(avatar_setShieldActive),
9980 	luaRegister(avatar_getRollDirection),
9981 
9982 	luaRegister(avatar_fallOffWall),
9983 	luaRegister(avatar_setBlockSinging),
9984 	luaRegister(avatar_isBlockSinging),
9985 	luaRegister(avatar_setBlockBackflip),
9986 	luaRegister(avatar_isBlockBackflip),
9987 
9988 	luaRegister(avatar_setSpeedMult),
9989 	luaRegister(avatar_setSpeedMult2),
9990 	luaRegister(avatar_getSpeedMult),
9991 	luaRegister(avatar_getSpeedMult2),
9992 
9993 
9994 	luaRegister(avatar_toggleMovement),
9995 
9996 
9997 	luaRegister(showInGameMenu),
9998 	luaRegister(hideInGameMenu),
9999 
10000 
10001 	luaRegister(showImage),
10002 	luaRegister(hideImage),
10003 	luaRegister(clearHelp),
10004 	luaRegister(clearShots),
10005 
10006 
10007 
10008 	luaRegister(getEntity),
10009 	luaRegister(getFirstEntity),
10010 	luaRegister(getNextEntity),
10011 	luaRegister(filterNearestEntities),
10012 	luaRegister(filterNearestEntitiesAdd),
10013 	luaRegister(getNextFilteredEntity),
10014 
10015 	luaRegister(setStory),
10016 	luaRegister(getStory),
10017 	luaRegister(getNoteColor),
10018 	luaRegister(getNoteVector),
10019 	luaRegister(getRandNote),
10020 
10021 	luaRegister(foundLostMemory),
10022 
10023 	luaRegister(isStory),
10024 
10025 	luaRegister(entity_damage),
10026 	luaRegister(entity_heal),
10027 
10028 	luaRegister(getNearestIngredient),
10029 
10030 	luaRegister(getNearestNodeByType),
10031 
10032 	luaRegister(getNode),
10033 	luaRegister(getNodeToActivate),
10034 	luaRegister(setNodeToActivate),
10035 	luaRegister(getEntityToActivate),
10036 	luaRegister(setEntityToActivate),
10037 	luaRegister(hasThingToActivate),
10038 	luaRegister(setActivation),
10039 
10040 	luaRegister(entity_warpToNode),
10041 	luaRegister(entity_moveToNode),
10042 	luaRegister(entity_moveToNodeSpeed),
10043 
10044 	luaRegister(cam_toNode),
10045 	luaRegister(cam_snap),
10046 	luaRegister(cam_toEntity),
10047 	luaRegister(cam_setPosition),
10048 
10049 
10050 	luaRegister(entity_flipToEntity),
10051 	luaRegister(entity_flipToSame),
10052 
10053 	luaRegister(entity_flipToNode),
10054 	luaRegister(entity_flipToVel),
10055 
10056 	luaRegister(entity_swimToNode),
10057 	luaRegister(entity_swimToNodeSpeed),
10058 	luaRegister(entity_swimToPosition),
10059 	luaRegister(entity_swimToPositionSpeed),
10060 
10061 
10062 	luaRegister(createShot),
10063 
10064 	luaRegister(entity_isHit),
10065 
10066 
10067 
10068 	luaRegister(createWeb),
10069 	luaRegister(web_addPoint),
10070 	luaRegister(web_setPoint),
10071 	luaRegister(web_getNumPoints),
10072 
10073 	luaRegister(createSpore),
10074 
10075 	luaRegister(getFirstShot),
10076 	luaRegister(getNextShot),
10077 	luaRegister(shot_setAimVector),
10078 	luaRegister(shot_setOut),
10079 	luaRegister(shot_getEffectTime),
10080 	luaRegister(shot_isIgnoreShield),
10081 	luaRegister(shot_setFirer),
10082 	luaRegister(shot_getFirer),
10083 	luaRegister(shot_setTarget),
10084 	luaRegister(shot_getTarget),
10085 	luaRegister(shot_setExtraDamage),
10086 	luaRegister(shot_getExtraDamage),
10087 	luaRegister(shot_getDamage),
10088 	luaRegister(shot_getDamageType),
10089 	luaRegister(shot_getName),
10090 	luaRegister(shot_getMaxSpeed),
10091 	luaRegister(shot_setMaxSpeed),
10092 	luaRegister(shot_getHomingness),
10093 	luaRegister(shot_setHomingness),
10094 	luaRegister(shot_getLifeTime),
10095 	luaRegister(shot_setLifeTime),
10096 	luaRegister(shot_setDamageType),
10097 	luaRegister(shot_setCheckDamageTarget),
10098 	luaRegister(shot_isCheckDamageTarget),
10099 	luaRegister(shot_setTrailPrt),
10100 	luaRegister(shot_setTargetPoint),
10101 	luaRegister(shot_getTargetPoint),
10102 	luaRegister(shot_canHitEntity),
10103 	luaRegister(filterNearestShots),
10104 	luaRegister(filterNearestShotsAdd),
10105 	luaRegister(getNextFilteredShot),
10106 	luaRegister(entity_pathBurst),
10107 	luaRegister(entity_handleShotCollisions),
10108 	luaRegister(entity_handleShotCollisionsSkeletal),
10109 	luaRegister(entity_handleShotCollisionsHair),
10110 	luaRegister(entity_collideSkeletalVsCircle),
10111 	luaRegister(entity_collideSkeletalVsCirclePos),
10112 	luaRegister(entity_collideSkeletalVsLine),
10113 	luaRegister(entity_collideSkeletalVsCircleForListByName),
10114 	luaRegister(entity_collideCircleVsLine),
10115 	luaRegister(entity_collideCircleVsLineAngle),
10116 
10117 	luaRegister(entity_collideHairVsCircle),
10118 
10119 	luaRegister(entity_setDropChance),
10120 
10121 	luaRegister(entity_waitForPath),
10122 	luaRegister(entity_watchForPath),
10123 
10124 	luaRegister(entity_revive),
10125 
10126 	luaRegister(entity_getTarget),
10127 	luaRegister(entity_isState),
10128 
10129 	luaRegister(entity_setProperty),
10130 	luaRegister(entity_isProperty),
10131 
10132 
10133 	luaRegister(entity_initHair),
10134 	luaRegister(entity_getHairPosition),
10135 	luaRegister(entity_getHair),
10136 	luaRegister(entity_clearHair),
10137 
10138 	luaRegister(entity_setHairHeadPosition),
10139 	luaRegister(entity_updateHair),
10140 	luaRegister(entity_exertHairForce),
10141 
10142 	luaRegister(entity_setName),
10143 
10144 	luaRegister(getNumberOfEntitiesNamed),
10145 
10146 	luaRegister(isNested),
10147 	luaRegister(isSkippingCutscene),
10148 
10149 	luaRegister(entity_idle),
10150 	luaRegister(entity_stopAllAnimations),
10151 
10152 	luaRegister(entity_getBoneByIdx),
10153 	luaRegister(entity_getBoneByName),
10154 	luaRegister(entity_getBoneByInternalId),
10155 	luaRegister(entity_getNumBones),
10156 
10157 
10158 
10159 	luaRegister(toggleInput),
10160 
10161 	luaRegister(entity_setTarget),
10162 
10163 	luaRegister(getScreenCenter),
10164 
10165 
10166 
10167 	luaRegister(debugLog),
10168 	luaRegister(errorLog),
10169 	luaRegister(loadMap),
10170 
10171 	luaRegister(loadSound),
10172 
10173 	luaRegister(node_activate),
10174 	luaRegister(node_getName),
10175 	luaRegister(node_getLabel),
10176 	luaRegister(node_getPathPosition),
10177 	luaRegister(node_getPosition),
10178 	luaRegister(node_setPosition),
10179 	luaRegister(node_getContent),
10180 	luaRegister(node_getAmount),
10181 	luaRegister(node_getSize),
10182 	luaRegister(node_getShape),
10183 
10184 	luaRegister(toggleSteam),
10185 	luaRegister(toggleVersionLabel),
10186 	luaRegister(setVersionLabelText),
10187 
10188 	luaRegister(appendUserDataPath),
10189 
10190 	luaRegister(setCutscene),
10191 	luaRegister(isInCutscene),
10192 
10193 
10194 
10195 	luaRegister(node_getNumEntitiesIn),
10196 
10197 
10198 	luaRegister(entity_getName),
10199 	luaRegister(entity_isName),
10200 
10201 
10202 	luaRegister(node_setActivationRange),
10203 	luaRegister(node_setCursorActivation),
10204 	luaRegister(node_setCatchActions),
10205 
10206 	luaRegister(node_setElementsInLayerActive),
10207 
10208 
10209 	luaRegister(entity_setHealth),
10210 	luaRegister(entity_setCurrentHealth),
10211 	luaRegister(entity_setMaxHealth),
10212 	luaRegister(entity_changeHealth),
10213 
10214 	luaRegister(node_setActive),
10215 	luaRegister(node_isActive),
10216 	luaRegister(node_setEmitter),
10217 	luaRegister(node_getEmitter),
10218 
10219 
10220 	luaRegister(setSceneColor),
10221 	luaRegister(getSceneColor),
10222 	luaRegister(setSceneColor2),
10223 	luaRegister(getSceneColor2),
10224 
10225 	luaRegister(entity_watchEntity),
10226 
10227 	luaRegister(entity_isEntityInRange),
10228 	luaRegister(entity_isPositionInRange),
10229 
10230 	luaRegister(entity_stopFollowingPath),
10231 	luaRegister(entity_slowToStopPath),
10232 	luaRegister(entity_isSlowingToStopPath),
10233 
10234 	luaRegister(entity_findNearestEntityOfType),
10235 	luaRegister(entity_isFollowingEntity),
10236 	luaRegister(entity_resumePath),
10237 
10238 	luaRegister(entity_generateCollisionMask),
10239 
10240 	luaRegister(entity_isAnimating),
10241 	luaRegister(entity_getAnimationName),
10242 	luaRegister(entity_getAnimationLength),
10243 	luaRegister(entity_hasAnimation),
10244 
10245 	luaRegister(entity_setCull),
10246 
10247 	luaRegister(entity_setFillGrid),
10248 	luaRegister(entity_isFillGrid),
10249 
10250 	luaRegister(entity_push),
10251 
10252 	luaRegister(entity_alpha),
10253 
10254 	luaRegister(findWall),
10255 
10256 
10257 	luaRegister(overrideZoom),
10258 	luaRegister(disableOverrideZoom),
10259 	luaRegister(getZoom),
10260 	luaRegister(setMaxLookDistance),
10261 
10262 
10263 
10264 	luaRegister(spawnAroundEntity),
10265 
10266 	luaRegister(entity_toggleBone),
10267 
10268 	luaRegister(bone_getName),
10269 	luaRegister(bone_isName),
10270 	luaRegister(bone_getIndex),
10271 	luaRegister(node_x),
10272 	luaRegister(node_y),
10273 	luaRegister(node_isEntityPast),
10274 	luaRegister(node_isEntityInRange),
10275 	luaRegister(node_isPositionIn),
10276 
10277 
10278 
10279 	luaRegister(entity_warpLastPosition),
10280 	luaRegister(entity_setVel),
10281 	luaRegister(entity_setVelLen),
10282 	luaRegister(entity_getVelLen),
10283 	luaRegister(entity_getVel),
10284 	luaRegister(entity_velx),
10285 	luaRegister(entity_vely),
10286 	luaRegister(entity_addVel),
10287 	luaRegister(entity_addRandomVel),
10288 	luaRegister(entity_isVelIn),
10289 	luaRegister(entity_clearVel),
10290 	luaRegister(entity_velTowards),
10291 
10292 	luaRegister(entity_setVel2),
10293 	luaRegister(entity_setVel2Len),
10294 	luaRegister(entity_getVel2Len),
10295 	luaRegister(entity_addVel2),
10296 	luaRegister(entity_getVel2),
10297 	luaRegister(entity_clearVel2),
10298 
10299 	luaRegister(entity_getPushVec),
10300 
10301 
10302 	luaRegister(updateMusic),
10303 
10304 	luaRegister(entity_touchAvatarDamage),
10305 	luaRegister(getNaija),
10306 	luaRegister(getLi),
10307 	luaRegister(setLi),
10308 
10309 	luaRegister(randAngle360),
10310 	luaRegister(randVector),
10311 
10312 	luaRegister(entity_getNearestEntity),
10313 	luaRegister(entity_getNearestBoneToPosition),
10314 	luaRegister(getNearestEntity),
10315 
10316 	luaRegister(entity_getNearestNode),
10317 	luaRegister(entity_setPoison),
10318 	luaRegister(entity_getPoison),
10319 
10320 	luaRegister(node_getNearestEntity),
10321 	luaRegister(node_getNearestNode),
10322 
10323 
10324 	luaRegister(node_isEntityIn),
10325 
10326 
10327 
10328 	luaRegister(isLeftMouse),
10329 	luaRegister(isRightMouse),
10330 
10331 
10332 	luaRegister(setTimerTextAlpha),
10333 	luaRegister(setTimerText),
10334 
10335 
10336 	luaRegister(getWallNormal),
10337 	luaRegister(getLastCollidePosition),
10338 	luaRegister(getLastCollideTileType),
10339 	luaRegister(collideCircleWithGrid),
10340 
10341 	luaRegister(getScreenVirtualOff),
10342 	luaRegister(getScreenSize),
10343 	luaRegister(getScreenVirtualSize),
10344 	luaRegister(isMiniMapCursorOkay),
10345 	luaRegister(isShuttingDownGameState),
10346 	luaRegister(setBGGradient),
10347 
10348 	luaRegister(inv_isFull),
10349 	luaRegister(inv_getMaxAmount),
10350 	luaRegister(inv_getAmount),
10351 	luaRegister(inv_add),
10352 	luaRegister(inv_getGfx),
10353 	luaRegister(inv_remove),
10354 	luaRegister(inv_getType),
10355 	luaRegister(inv_getDisplayName),
10356 	luaRegister(inv_pickupEffect),
10357 	luaRegister(inv_getNumItems),
10358 	luaRegister(inv_getItemName),
10359 	luaRegister(learnRecipe),
10360 	luaRegister(getIngredientDataSize),
10361 	luaRegister(getIngredientDataName),
10362 
10363 	luaRegister(createDebugText),
10364 	luaRegister(createBitmapText),
10365 	luaRegister(createArialTextBig),
10366 	luaRegister(createArialTextSmall),
10367 	luaRegister(text_setText),
10368 	luaRegister(text_setFontSize),
10369 	luaRegister(text_setWidth),
10370 	luaRegister(text_setAlign),
10371 	luaRegister(text_getHeight),
10372 	luaRegister(text_getStringWidth),
10373 	luaRegister(text_getActualWidth),
10374 	luaRegister(text_getLineHeight),
10375 	luaRegister(text_getNumLines),
10376 
10377 	luaRegister(loadShader),
10378 	luaRegister(createShader),
10379 	luaRegister(shader_setAsAfterEffect),
10380 	luaRegister(shader_setNumAfterEffects),
10381 	luaRegister(shader_setFloat),
10382 	luaRegister(shader_setInt),
10383 	luaRegister(shader_delete),
10384 
10385 	luaRegister(pe_start),
10386 	luaRegister(pe_stop),
10387 	luaRegister(pe_isRunning),
10388 
10389 	luaRegister(isQuad),
10390 	luaRegister(isNode),
10391 	luaRegister(isObject),
10392 	luaRegister(isEntity),
10393 	luaRegister(isScriptedEntity),
10394 	luaRegister(isBone),
10395 	luaRegister(isShot),
10396 	luaRegister(isWeb),
10397 	luaRegister(isIng),
10398 	luaRegister(isBeam),
10399 	luaRegister(isText),
10400 	luaRegister(isShader),
10401 	luaRegister(isParticleEffect),
10402 
10403 	luaRegister(getPerformanceCounter),
10404 	luaRegister(getPerformanceFreq),
10405 
10406 
10407 
10408 #undef MK_FUNC
10409 #undef MK_ALIAS
10410 #define MK_FUNC(base, getter, prefix, suffix) luaRegister(prefix##_##suffix),
10411 #define MK_STR(s) #s
10412 #define MK_ALIAS(prefix, suffix, alias) {MK_STR(prefix) "_" MK_STR(alias), l_##prefix##_##suffix},
10413 
10414 	EXPAND_FUNC_PROTOTYPES
10415 
10416 	// obj_* are not in the define above
10417 	MAKE_ROBJ_FUNCS(_, obj)
10418 	// same for quad_* base functions
10419 	MAKE_QUAD_FUNCS(_, quad)
10420 
10421 	// -- overrides / special cases--
10422 
10423 	{"bone_getPosition", l_bone_getWorldPosition},
10424 	{ "entity_delete", l_entity_delete_override },
10425 	{ "entity_setRenderPass", l_entity_setRenderPass_override },
10426 	{ "beam_setPosition", l_beam_setPosition_override },
10427 
10428 	// -- deprecated/compatibility related functions below here --
10429 
10430 	{"entity_incrTargetLeaches", l_avatar_incrLeaches},
10431 	{"entity_decrTargetLeaches", l_avatar_decrLeaches},
10432 	{"entity_soundFreq", l_entity_sound},
10433 	{"entity_interpolateTo", l_entity_setPosition},
10434 	{"entity_isFlippedHorizontal", l_entity_isfh},
10435 	{"entity_isFlippedVertical", l_entity_isfv},
10436 	{"entity_rotateTo", l_entity_rotate},
10437 	{"entity_setColor", l_entity_color},
10438 	{"entity_setInternalOffset", l_entity_internalOffset},
10439 	{"getIngredientGfx", l_inv_getGfx},
10440 
10441 	{"bone_setColor", l_bone_color},
10442 
10443 	{"node_setEffectOn", l_node_setActive},
10444 	{"node_isEffectOn", l_node_isActive},
10445 
10446 };
10447 
10448 //============================================================================================
10449 // S C R I P T  C O N S T A N T S
10450 //============================================================================================
10451 
10452 #define luaConstant(name)					{#name, name}
10453 #define luaConstantFromClass(name,class)	{#name, class::name}
10454 
10455 static const struct {
10456 	const char *name;
10457 	lua_Number value;
10458 } luaConstantTable[] = {
10459 
10460 	{"AQUARIA_VERSION", VERSION_MAJOR*10000 + VERSION_MINOR*100 + VERSION_REVISION},
10461 
10462 	// emotes
10463 	luaConstant(EMOTE_NAIJAEVILLAUGH),
10464 	luaConstant(EMOTE_NAIJAGIGGLE),
10465 	luaConstant(EMOTE_NAIJALAUGH),
10466 	luaConstant(EMOTE_NAIJASADSIGH),
10467 	luaConstant(EMOTE_NAIJASIGH),
10468 	luaConstant(EMOTE_NAIJAWOW),
10469 	luaConstant(EMOTE_NAIJAUGH),
10470 	luaConstant(EMOTE_NAIJALOW),
10471 	luaConstant(EMOTE_NAIJALI),
10472 	{"EMOTE_NAIJAEW",			9},  // FIXME: unused
10473 
10474 	// Li expressions
10475 	{"EXPRESSION_NORMAL",		0},
10476 	{"EXPRESSION_ANGRY",		1},
10477 	{"EXPRESSION_HAPPY",		2},
10478 	{"EXPRESSION_HURT",			3},
10479 	{"EXPRESSION_LAUGH",		4},
10480 	{"EXPRESSION_SURPRISE",		5},
10481 
10482 	luaConstantFromClass(OVERRIDE_NONE,	RenderObject),
10483 
10484 	//actions
10485 	luaConstant(ACTION_MENULEFT),
10486 	luaConstant(ACTION_MENURIGHT),
10487 	luaConstant(ACTION_MENUUP),
10488 	luaConstant(ACTION_MENUDOWN),
10489 
10490 	{"WATCH_QUIT",				1},
10491 
10492 	{"BEACON_HOMECAVE",			1},
10493 	{"BEACON_ENERGYTEMPLE",		2},
10494 	{"BEACON_MITHALAS",			3},
10495 	{"BEACON_FOREST",			4},
10496 	{"BEACON_LI",				5},
10497 	{"BEACON_SUNTEMPLE",		6},
10498 	{"BEACON_SONGCAVE",			7},
10499 
10500 	{"PLAT_WIN",				0},
10501 	{"PLAT_MAC",				1},
10502 	{"PLAT_LNX",				2},
10503 
10504 	// ingredient effect types
10505 	luaConstant(IET_NONE),
10506 	luaConstant(IET_HP),
10507 	luaConstant(IET_DEFENSE),
10508 	luaConstant(IET_SPEED),
10509 	luaConstant(IET_RANDOM),
10510 	luaConstant(IET_MAXHP),
10511 	luaConstant(IET_INVINCIBLE),
10512 	luaConstant(IET_TRIP),
10513 	luaConstant(IET_REGEN),
10514 	luaConstant(IET_LI),
10515 	luaConstant(IET_FISHPOISON),
10516 	luaConstant(IET_BITE),
10517 	luaConstant(IET_EAT),
10518 	luaConstant(IET_LIGHT),
10519 	luaConstant(IET_YUM),
10520 	luaConstant(IET_PETPOWER),
10521 	luaConstant(IET_WEB),
10522 	luaConstant(IET_ENERGY),
10523 	luaConstant(IET_POISON),
10524 	luaConstant(IET_BLIND),
10525 	luaConstant(IET_ALLSTATUS),
10526 	luaConstant(IET_MAX),
10527 
10528 	// menu pages
10529 	luaConstant(MENUPAGE_NONE),
10530 	luaConstant(MENUPAGE_SONGS),
10531 	luaConstant(MENUPAGE_FOOD),
10532 	luaConstant(MENUPAGE_TREASURES),
10533 	luaConstant(MENUPAGE_PETS),
10534 
10535 	// Entity States
10536 	luaConstantFromClass(STATE_DEAD,		Entity),
10537 	luaConstantFromClass(STATE_IDLE,		Entity),
10538 	luaConstantFromClass(STATE_PUSH,		Entity),
10539 	luaConstantFromClass(STATE_PUSHDELAY,	Entity),
10540 	luaConstantFromClass(STATE_PLANTED,		Entity),
10541 	luaConstantFromClass(STATE_PULLED,		Entity),
10542 	luaConstantFromClass(STATE_FOLLOWNAIJA,	Entity),
10543 	luaConstantFromClass(STATE_DEATHSCENE,	Entity),
10544 	luaConstantFromClass(STATE_ATTACK,		Entity),
10545 	luaConstantFromClass(STATE_CHARGE0,		Entity),
10546 	luaConstantFromClass(STATE_CHARGE1,		Entity),
10547 	luaConstantFromClass(STATE_CHARGE2,		Entity),
10548 	luaConstantFromClass(STATE_CHARGE3,		Entity),
10549 	luaConstantFromClass(STATE_WAIT,		Entity),
10550 	luaConstantFromClass(STATE_HUG,			Entity),
10551 	luaConstantFromClass(STATE_EATING,		Entity),
10552 	luaConstantFromClass(STATE_FOLLOW,		Entity),
10553 	luaConstantFromClass(STATE_TITLE,		Entity),
10554 	// Remainder are script-specific, not used by C++ code
10555 	{"STATE_HATCH",			25},
10556 	{"STATE_CARRIED",		26},
10557 
10558 	{"STATE_HOSTILE",		100},
10559 
10560 	{"STATE_CLOSE",			200},
10561 	{"STATE_OPEN",			201},
10562 	{"STATE_CLOSED",		202},
10563 	{"STATE_OPENED",		203},
10564 	{"STATE_CHARGED",		300},
10565 	{"STATE_INHOLDER",		301},
10566 	{"STATE_DISABLED",		302},
10567 	{"STATE_FLICKER",		303},
10568 	{"STATE_ACTIVE",		304},
10569 	{"STATE_USED",			305},
10570 	{"STATE_BLOATED",		306},
10571 	{"STATE_DELAY",			307},
10572 	{"STATE_DONE",			309},
10573 	{"STATE_RAGE",			310},
10574 	{"STATE_CALM",			311},
10575 	{"STATE_DESCEND",		312},
10576 	{"STATE_SING",			313},
10577 	{"STATE_TRANSFORM",		314},
10578 	{"STATE_GROW",			315},
10579 	{"STATE_MATING",		316},
10580 	{"STATE_SHRINK",		317},
10581 	{"STATE_MOVE",			319},
10582 	{"STATE_TRANSITION",	320},
10583 	{"STATE_TRANSITION2",	321},
10584 	{"STATE_TRAPPEDINCREATOR",	322},
10585 	{"STATE_GRAB",			323},
10586 	{"STATE_FIGURE",		324},
10587 	{"STATE_CUTSCENE",		325},
10588 	{"STATE_WAITFORCUTSCENE",	326},
10589 	{"STATE_FIRE",			327},
10590 	{"STATE_FIRING",		328},
10591 	{"STATE_PREP",			329},
10592 	{"STATE_INTRO",			330},
10593 	{"STATE_PUPPET",		331},
10594 
10595 	{"STATE_COLLECT",				400},
10596 	{"STATE_COLLECTED",				401},
10597 	{"STATE_COLLECTEDINHOUSE",		402},
10598 
10599 
10600 	//{"STATE_ATTACK"},		500},
10601 	{"STATE_STEP",			501},
10602 	{"STATE_AWAKEN",		502},
10603 
10604 	{"STATE_WEAK",			600},
10605 	{"STATE_BREAK",			601},
10606 	{"STATE_BROKEN",		602},
10607 
10608 	{"STATE_PULSE",			700},
10609 	{"STATE_ON",			701},
10610 	{"STATE_OFF",			702},
10611 	{"STATE_SEED",			703},
10612 	{"STATE_PLANTED",		704},
10613 	{"STATE_SK_RED",		705},
10614 	{"STATE_SK_GREEN",		706},
10615 	{"STATE_SK_BLUE",		707},
10616 	{"STATE_SK_YELLOW",		708},
10617 	{"STATE_WAITFORKISS",	710},
10618 	{"STATE_KISS",			711},
10619 	{"STATE_START",			712},
10620 	{"STATE_RACE",			714},
10621 	{"STATE_RESTART",		715},
10622 	{"STATE_APPEAR",		716},
10623 
10624 	{"STATE_MOVETOWEED",	2000},
10625 	{"STATE_PULLWEED",		2001},
10626 	{"STATE_DONEWEED",		2002},
10627 
10628 	{"ORIENT_NONE",			-1},
10629 	{"ORIENT_LEFT",			0},
10630 	{"ORIENT_RIGHT",		1},
10631 	{"ORIENT_UP",			2},
10632 	{"ORIENT_DOWN",			3},
10633 	{"ORIENT_HORIZONTAL",	4},
10634 	{"ORIENT_VERTICAL",		5},
10635 
10636 	// for entity_isNearObstruction
10637 	luaConstant(OBSCHECK_RANGE),
10638 	luaConstant(OBSCHECK_4DIR),
10639 	luaConstant(OBSCHECK_DOWN),
10640 	luaConstant(OBSCHECK_8DIR),
10641 
10642 	luaConstant(EV_WALLOUT),
10643 	luaConstant(EV_WALLTRANS),
10644 	luaConstant(EV_CLAMPING),
10645 	luaConstant(EV_SWITCHCLAMP),
10646 	luaConstant(EV_CLAMPTRANSF),
10647 	luaConstant(EV_MOVEMENT),
10648 	luaConstant(EV_COLLIDE),
10649 	luaConstant(EV_TOUCHDMG),
10650 	luaConstant(EV_FRICTION),
10651 	luaConstant(EV_LOOKAT),
10652 	luaConstant(EV_CRAWLING),
10653 	luaConstant(EV_ENTITYDIED),
10654 	luaConstant(EV_TYPEID),
10655 	luaConstant(EV_COLLIDELEVEL),
10656 	luaConstant(EV_BONELOCKED),
10657 	luaConstant(EV_FLIPTOPATH),
10658 	luaConstant(EV_NOINPUTNOVEL),
10659 	luaConstant(EV_VINEPUSH),
10660 	luaConstant(EV_BEASTBURST),
10661 	luaConstant(EV_MINIMAP),
10662 	luaConstant(EV_SOULSCREAMRADIUS),
10663 	luaConstant(EV_WEBSLOW),
10664 	luaConstant(EV_NOAVOID),
10665 	luaConstant(EV_MAX),
10666 
10667 	{"EVT_NONE",				0},
10668 	{"EVT_THERMALVENT",			1},
10669 	{"EVT_GLOBEJELLY",			2},
10670 	{"EVT_CELLWHITE",			3},
10671 	{"EVT_CELLRED",				4},
10672 	{"EVT_PET",					5},
10673 	{"EVT_DARKLISHOT",			6},
10674 	{"EVT_ROCK",				7},
10675 	{"EVT_FORESTGODVINE",		8},
10676 	{"EVT_CONTAINER",			9},
10677 	{"EVT_PISTOLSHRIMP",		10},
10678 	{"EVT_GATEWAYMUTANT",		11},
10679 
10680 
10681 	// PATH/node types
10682 	luaConstant(PATH_NONE),
10683 	luaConstant(PATH_CURRENT),
10684 	luaConstant(PATH_STEAM),
10685 	luaConstant(PATH_LI),
10686 	luaConstant(PATH_SAVEPOINT),
10687 	luaConstant(PATH_WARP),
10688 	luaConstant(PATH_SPIRITPORTAL),
10689 	luaConstant(PATH_BGSFXLOOP),
10690 	luaConstant(PATH_RADARHIDE),
10691 	luaConstant(PATH_COOK),
10692 	luaConstant(PATH_WATERBUBBLE),
10693 	luaConstant(PATH_GEM),
10694 	luaConstant(PATH_SETING),
10695 	luaConstant(PATH_SETENT),
10696 
10697 	// Entity Types
10698 	luaConstant(ET_AVATAR),
10699 	luaConstant(ET_ENEMY),
10700 	luaConstant(ET_PET),
10701 	luaConstant(ET_FLOCK),
10702 	luaConstant(ET_NEUTRAL),
10703 	luaConstant(ET_INGREDIENT),
10704 
10705 	luaConstant(EP_SOLID),
10706 	luaConstant(EP_MOVABLE),
10707 	luaConstant(EP_BATTERY),
10708 	luaConstant(EP_BLOCKER),
10709 
10710 	// ACTIVATION TYPES
10711 	{"AT_NONE",				-1},
10712 	{"AT_NORMAL",			0},
10713 	{"AT_CLICK",			0},
10714 	{"AT_RANGE",			1},
10715 
10716 	luaConstant(WT_NORMAL),
10717 	luaConstant(WT_SPIRIT),
10718 
10719 	{"SPEED_NORMAL",		0},
10720 	{"SPEED_SLOW",			1},
10721 	{"SPEED_FAST",			2},
10722 	{"SPEED_VERYFAST",		3},
10723 	{"SPEED_MODSLOW",		4},
10724 	{"SPEED_VERYSLOW",		5},
10725 	{"SPEED_FAST2",			6},
10726 	{"SPEED_LITOCAVE",		7},
10727 
10728 	luaConstant(BOUNCE_NONE),
10729 	luaConstant(BOUNCE_SIMPLE),
10730 	luaConstant(BOUNCE_REAL),
10731 
10732 	{"LOOP_INFINITE",		-1},
10733 	{"LOOP_INF",			-1},
10734 
10735 	{"LAYER_BODY",			0},
10736 	{"LAYER_UPPERBODY",		1},
10737 	{"LAYER_HEAD",			2},
10738 	{"LAYER_OVERRIDE",		3},
10739 
10740 	luaConstant(SONG_NONE),
10741 	luaConstant(SONG_HEAL),
10742 	luaConstant(SONG_ENERGYFORM),
10743 	luaConstant(SONG_SONGDOOR1),
10744 	luaConstant(SONG_SPIRITFORM),
10745 	luaConstant(SONG_BIND),
10746 	{"SONG_PULL",				SONG_BIND},
10747 	luaConstant(SONG_NATUREFORM),
10748 	luaConstant(SONG_BEASTFORM),
10749 	luaConstant(SONG_SHIELDAURA),
10750 	{"SONG_SHIELD",				SONG_SHIELDAURA},
10751 	luaConstant(SONG_SONGDOOR2),
10752 	luaConstant(SONG_DUALFORM),
10753 	luaConstant(SONG_FISHFORM),
10754 	luaConstant(SONG_SUNFORM),
10755 	{"SONG_LIGHTFORM",			SONG_SUNFORM},
10756 	luaConstant(SONG_LI),
10757 	luaConstant(SONG_TIME),
10758 	luaConstant(SONG_LANCE),
10759 	luaConstant(SONG_MAP),
10760 	luaConstant(SONG_ANIMA),
10761 	luaConstant(SONG_MAX),
10762 
10763 	luaConstantFromClass(BLEND_DEFAULT,	RenderObject),
10764 	luaConstantFromClass(BLEND_ADD,		RenderObject),
10765 	{"BLEND_ADDITIVE",					RenderObject::BLEND_ADD},
10766 	luaConstantFromClass(BLEND_SUB,		RenderObject),
10767 	luaConstantFromClass(BLEND_MULT,	RenderObject),
10768 
10769 	{"ENDING_NAIJACAVE",				10},
10770 	{"ENDING_NAIJACAVEDONE",			11},
10771 	{"ENDING_SECRETCAVE",				12},
10772 	{"ENDING_MAINAREA",					13},
10773 	{"ENDING_DONE",						14},
10774 
10775 
10776 	{"FLAG_SONGCAVECRYSTAL",			20},
10777 	{"FLAG_TEIRA",						50},
10778 	{"FLAG_SHARAN",						51},
10779 	{"FLAG_DRASK",						52},
10780 	{"FLAG_VEDHA",						53},
10781 
10782 	{"FLAG_ENERGYTEMPLE01DOOR",			100},
10783 	{"FLAG_ENERGYDOOR02",				101},
10784 	{"FLAG_ENERGYSLOT01",				102},
10785 	{"FLAG_ENERGYSLOT02",				103},
10786 	{"FLAG_ENERGYSLOT_MAINAREA",		104},
10787 	{"FLAG_MAINAREA_ENERGYTEMPLE_ROCK",	105},
10788 	{"FLAG_ENERGYSLOT_FIRST",			106},
10789 	{"FLAG_ENERGYDOOR03",				107},
10790 	{"FLAG_ENERGYGODENCOUNTER",			108},
10791 	{"FLAG_ENERGYBOSSDEAD",				109},
10792 	{"FLAG_MAINAREA_ETENTER2",			110},
10793 	{"FLAG_SUNTEMPLE_WATERLEVEL",		111},
10794 	{"FLAG_SUNTEMPLE_LIGHTCRYSTAL",		112},
10795 	{"FLAG_SUNKENCITY_PUZZLE",			113},
10796 	{"FLAG_SUNKENCITY_BOSS",			114},
10797 	{"FLAG_MITHALAS_THRONEROOM",		115},
10798 	{"FLAG_BOSS_MITHALA",				116},
10799 	{"FLAG_BOSS_FOREST",				117},
10800 	{"FLAG_FISHCAVE",					118},
10801 	{"FLAG_VISION_VEIL",				119},
10802 	{"FLAG_MITHALAS_PRIESTS",			120},
10803 	{"FLAG_FIRSTTRANSTURTLE",			121},
10804 	{"FLAG_13PROGRESSION",				122},
10805 	{"FLAG_FINAL",						123},
10806 	{"FLAG_SPIRIT_ERULIAN",				124},
10807 	{"FLAG_SPIRIT_KROTITE",				125},
10808 	{"FLAG_SPIRIT_DRASK",				126},
10809 	{"FLAG_SPIRIT_DRUNIAD",				127},
10810 	{"FLAG_BOSS_SUNWORM",				128},
10811 	{"FLAG_WHALELAMPPUZZLE",			129},
10812 
10813 	{"FLAG_TRANSTURTLE_VEIL01",			130},
10814 	{"FLAG_TRANSTURTLE_OPENWATER06",	131},
10815 	{"FLAG_TRANSTURTLE_FOREST04",		132},
10816 	{"FLAG_TRANSTURTLE_OPENWATER03",	133},
10817 	{"FLAG_TRANSTURTLE_FOREST05",		134},
10818 	{"FLAG_TRANSTURTLE_MAINAREA",		135},
10819 	{"FLAG_TRANSTURTLE_SEAHORSE",		136},
10820 	{"FLAG_TRANSTURTLE_VEIL02",			137},
10821 	{"FLAG_TRANSTURTLE_ABYSS03",		138},
10822 	{"FLAG_TRANSTURTLE_FINALBOSS",		139},
10823 
10824 	{"FLAG_NAIJA_SWIM",					200},
10825 	{"FLAG_NAIJA_MINIMAP",				201},
10826 	{"FLAG_NAIJA_SPEEDBOOST",			202},
10827 	{"FLAG_NAIJA_MEMORYCRYSTAL",		203},
10828 	{"FLAG_NAIJA_SINGING",				204},
10829 	{"FLAG_NAIJA_LEAVESVEDHA",			205},
10830 	{"FLAG_NAIJA_SONGDOOR",				206},
10831 	{"FLAG_NAIJA_ENTERVEDHACAVE",		207},
10832 	{"FLAG_NAIJA_INTERACT",				208},
10833 	{"FLAG_NAIJA_ENTERSONGCAVE",		209},
10834 	{"FLAG_NAIJA_ENERGYFORMSHOT",		210},
10835 	{"FLAG_NAIJA_ENERGYFORMCHARGE",		211},
10836 	{"FLAG_NAIJA_RETURNTONORMALFORM",	212},
10837 	{"FLAG_NAIJA_ENERGYBARRIER",		213},
10838 	{"FLAG_NAIJA_SOLIDENERGYBARRIER",	214},
10839 	{"FLAG_NAIJA_ENTERENERGYTEMPLE",	215},
10840 	{"FLAG_NAIJA_OPENWATERS",			216},
10841 	{"FLAG_NAIJA_SINGING",				217},
10842 	{"FLAG_NAIJA_INGAMEMENU",			218},
10843 	{"FLAG_NAIJA_SINGINGHINT",			219},
10844 	{"FLAG_NAIJA_LOOK",					220},
10845 	{"FLAG_HINT_MINIMAP",				221},
10846 	{"FLAG_HINT_HEALTHPLANT",			222},
10847 	{"FLAG_HINT_SLEEP",					223},
10848 	{"FLAG_HINT_COLLECTIBLE",			224},
10849 	{"FLAG_HINT_IGFDEMO",				225},
10850 	{"FLAG_HINT_BEASTFORM1",			226},
10851 	{"FLAG_HINT_BEASTFORM2",			227},
10852 	{"FLAG_HINT_LISONG",				228},
10853 	{"FLAG_HINT_ENERGYTARGET",			229},
10854 	{"FLAG_HINT_NATUREFORMABILITY",		230},
10855 	{"FLAG_HINT_LICOMBAT",				231},
10856 	{"FLAG_HINT_COOKING",				232},
10857 	{"FLAG_NAIJA_FIRSTVINE",			233},
10858 	luaConstant(FLAG_SECRET01),
10859 	luaConstant(FLAG_SECRET02),
10860 	luaConstant(FLAG_SECRET03),
10861 	{"FLAG_DEEPWHALE",					237},
10862 	{"FLAG_OMPO",						238},
10863 	{"FLAG_HINT_SINGBULB",				239},
10864 	{"FLAG_ENDING",						240},
10865 	{"FLAG_NAIJA_BINDSHELL",			241},
10866 	{"FLAG_NAIJA_BINDROCK",				242},
10867 	{"FLAG_HINT_ROLLGEAR",				243},
10868 	{"FLAG_FIRSTHEALTHUPGRADE",			244},
10869 	{"FLAG_MAINAREA_TRANSTURTLE_ROCK",	245},
10870 	{"FLAG_SKIPSECRETCHECK",			246},
10871 	{"FLAG_SEAHORSEBESTTIME",			247},
10872 	{"FLAG_SEAHORSETIMETOBEAT",			248},
10873 	{"FLAG_HINT_BINDMERMEN",			249},
10874 
10875 
10876 	{"FLAG_CREATORVOICE",				250},
10877 
10878 	{"FLAG_HINT_DUALFORMCHANGE",		251},
10879 	{"FLAG_HINT_DUALFORMCHARGE",		252},
10880 	{"FLAG_HINT_HEALTHUPGRADE",			253},
10881 
10882 	{"FLAG_VISION_ENERGYTEMPLE",		300},
10883 
10884 	luaConstant(FLAG_COLLECTIBLE_START),
10885 	{"FLAG_COLLECTIBLE_SONGCAVE",			500},
10886 	{"FLAG_COLLECTIBLE_ENERGYTEMPLE",		501},
10887 	{"FLAG_COLLECTIBLE_ENERGYSTATUE",		502},
10888 	{"FLAG_COLLECTIBLE_ENERGYBOSS",			503},
10889 	{"FLAG_COLLECTIBLE_NAIJACAVE",			504},
10890 	{"FLAG_COLLECTIBLE_CRABCOSTUME",		505},
10891 	{"FLAG_COLLECTIBLE_JELLYPLANT",			506},
10892 	{"FLAG_COLLECTIBLE_MITHALASPOT",		507},
10893 	{"FLAG_COLLECTIBLE_SEAHORSECOSTUME",	508},
10894 	{"FLAG_COLLECTIBLE_CHEST",				509},
10895 	{"FLAG_COLLECTIBLE_BANNER",				510},
10896 	{"FLAG_COLLECTIBLE_MITHALADOLL",		511},
10897 	{"FLAG_COLLECTIBLE_WALKERBABY",			512},
10898 	{"FLAG_COLLECTIBLE_SEEDBAG",			513},
10899 	{"FLAG_COLLECTIBLE_ARNASSISTATUE",		514},
10900 	{"FLAG_COLLECTIBLE_GEAR",				515},
10901 	{"FLAG_COLLECTIBLE_SUNKEY",				516},
10902 	{"FLAG_COLLECTIBLE_URCHINCOSTUME",		517},
10903 	{"FLAG_COLLECTIBLE_TEENCOSTUME",		518},
10904 	{"FLAG_COLLECTIBLE_MUTANTCOSTUME",		519},
10905 	{"FLAG_COLLECTIBLE_JELLYCOSTUME",		520},
10906 	{"FLAG_COLLECTIBLE_MITHALANCOSTUME",	521},
10907 	{"FLAG_COLLECTIBLE_ANEMONESEED",		522},
10908 	{"FLAG_COLLECTIBLE_BIOSEED",			523},
10909 	{"FLAG_COLLECTIBLE_TURTLEEGG",			524},
10910 	{"FLAG_COLLECTIBLE_SKULL",				525},
10911 	{"FLAG_COLLECTIBLE_TRIDENTHEAD",		526},
10912 	{"FLAG_COLLECTIBLE_SPORESEED",			527},
10913 	{"FLAG_COLLECTIBLE_UPSIDEDOWNSEED",		528},
10914 	{"FLAG_COLLECTIBLE_STONEHEAD",			529},
10915 	{"FLAG_COLLECTIBLE_STARFISH",			530},
10916 	{"FLAG_COLLECTIBLE_BLACKPEARL",			531},
10917 	luaConstant(FLAG_COLLECTIBLE_END),
10918 
10919 	luaConstant(FLAG_PET_ACTIVE),
10920 	luaConstant(FLAG_PET_NAMESTART),
10921 	{"FLAG_PET_NAUTILUS",					601},
10922 	{"FLAG_PET_DUMBO",						602},
10923 	{"FLAG_PET_BLASTER",					603},
10924 	{"FLAG_PET_PIRANHA",					604},
10925 
10926 	luaConstant(FLAG_UPGRADE_WOK),
10927 	// does the player have access to 3 slots all the time?
10928 
10929 	{"FLAG_COLLECTIBLE_NAUTILUSPRIME",	630},
10930 	{"FLAG_COLLECTIBLE_DUMBOEGG",		631},
10931 	{"FLAG_COLLECTIBLE_BLASTEREGG",		632},
10932 	{"FLAG_COLLECTIBLE_PIRANHAEGG",		633},
10933 
10934 	{"FLAG_ENTER_HOMEWATERS",			650},
10935 	{"FLAG_ENTER_SONGCAVE",				651},
10936 	{"FLAG_ENTER_ENERGYTEMPLE",			652},
10937 	{"FLAG_ENTER_OPENWATERS",			653},
10938 	{"FLAG_ENTER_HOMECAVE",				654},
10939 	{"FLAG_ENTER_FOREST",				655},
10940 	{"FLAG_ENTER_VEIL",					656},
10941 	{"FLAG_ENTER_MITHALAS",				657},
10942 	{"FLAG_ENTER_MERMOGCAVE",			658},
10943 	{"FLAG_ENTER_MITHALAS",				659},
10944 	{"FLAG_ENTER_SUNTEMPLE",			660},
10945 	{"FLAG_ENTER_ABYSS",				661},
10946 	{"FLAG_ENTER_SUNKENCITY",			662},
10947 	{"FLAG_ENTER_FORESTSPRITECAVE",		663},
10948 	{"FLAG_ENTER_FISHCAVE",				664},
10949 	{"FLAG_ENTER_MITHALASCATHEDRAL",	665},
10950 	{"FLAG_ENTER_TURTLECAVE",			666},
10951 	{"FLAG_ENTER_FROZENVEIL",			667},
10952 	{"FLAG_ENTER_ICECAVE",				668},
10953 	{"FLAG_ENTER_SEAHORSE",				669},
10954 
10955 
10956 	{"FLAG_MINIBOSS_START",				700},
10957 	{"FLAG_MINIBOSS_NAUTILUSPRIME",		700},
10958 	{"FLAG_MINIBOSS_KINGJELLY",			701},
10959 	{"FLAG_MINIBOSS_MERGOG",			702},
10960 	{"FLAG_MINIBOSS_CRAB",				703},
10961 	{"FLAG_MINIBOSS_OCTOMUN",			704},
10962 	{"FLAG_MINIBOSS_MANTISSHRIMP",		705},
10963 	{"FLAG_MINIBOSS_PRIESTS",			706},
10964 	{"FLAG_MINIBOSS_END",				720},
10965 
10966 	{"FLAG_MAMATURTLE_RESCUE1",			750},
10967 	{"FLAG_MAMATURTLE_RESCUE2",			751},
10968 	{"FLAG_MAMATURTLE_RESCUE3",			752},
10969 
10970 	{"FLAG_SONGDOOR1",					800},
10971 	luaConstant(FLAG_SEALOAFANNOYANCE),
10972 
10973 	{"FLAG_SEAL_KING",					900},
10974 	{"FLAG_SEAL_QUEEN",					901},
10975 	{"FLAG_SEAL_PRINCE",				902},
10976 
10977 	{"FLAG_HEALTHUPGRADES",				950},
10978 	{"FLAG_HEALTHUPGRADES_END",			960},
10979 
10980 	luaConstant(FLAG_LI),
10981 	luaConstant(FLAG_LICOMBAT),
10982 
10983 
10984 
10985 	luaConstant(MAX_FLAGS),
10986 
10987 	{"ALPHA_NEARZERO",					0.001},
10988 
10989 	{"SUNKENCITY_START",				0},
10990 	{"SUNKENCITY_CLIMBDOWN",			1},
10991 	{"SUNKENCITY_RUNAWAY",				2},
10992 	{"SUNKENCITY_INHOLE",				3},
10993 	{"SUNKENCITY_GF",					4},
10994 	{"SUNKENCITY_BULLIES",				5},
10995 	{"SUNKENCITY_ANIMA",				6},
10996 	{"SUNKENCITY_BOSSWAIT",				7},
10997 	{"SUNKENCITY_CLAY1",				8},
10998 	{"SUNKENCITY_CLAY2",				9},
10999 	{"SUNKENCITY_CLAY3",				10},
11000 	{"SUNKENCITY_CLAY4",				11},
11001 	{"SUNKENCITY_CLAY5",				12},
11002 	{"SUNKENCITY_CLAY6",				13},
11003 	{"SUNKENCITY_CLAYDONE",				14},
11004 	{"SUNKENCITY_BOSSFIGHT",			15},
11005 	{"SUNKENCITY_BOSSDONE",				16},
11006 	{"SUNKENCITY_FINALTONGUE",			17},
11007 
11008 	{"FINAL_START",						0},
11009 	{"FINAL_SOMETHING",					1},
11010 	{"FINAL_FREEDLI",					2},
11011 
11012 	luaConstantFromClass(ANIM_NONE,		Bone),
11013 	luaConstantFromClass(ANIM_POS,		Bone),
11014 	luaConstantFromClass(ANIM_ROT,		Bone),
11015 	luaConstantFromClass(ANIM_ALL,		Bone),
11016 
11017 	luaConstant(FORM_NORMAL),
11018 	luaConstant(FORM_ENERGY),
11019 	luaConstant(FORM_BEAST),
11020 	luaConstant(FORM_NATURE),
11021 	luaConstant(FORM_SPIRIT),
11022 	luaConstant(FORM_DUAL),
11023 	luaConstant(FORM_FISH),
11024 	luaConstant(FORM_SUN),
11025 	{"FORM_LIGHT",			FORM_SUN},
11026 	luaConstant(FORM_MAX),
11027 
11028 	luaConstant(VFX_SHOCK),
11029 	luaConstant(VFX_RIPPLE),
11030 
11031 	luaConstant(EAT_NONE),
11032 	luaConstant(EAT_DEFAULT),
11033 	luaConstant(EAT_FILE),
11034 	luaConstant(EAT_MAX),
11035 
11036 	luaConstant(DT_NONE),
11037 	luaConstant(DT_ENEMY),
11038 	luaConstant(DT_ENEMY_ENERGYBLAST),
11039 	luaConstant(DT_ENEMY_SHOCK),
11040 	luaConstant(DT_ENEMY_BITE),
11041 	luaConstant(DT_ENEMY_TRAP),
11042 	luaConstant(DT_ENEMY_WEB),
11043 	luaConstant(DT_ENEMY_BEAM),
11044 	luaConstant(DT_ENEMY_GAS),
11045 	luaConstant(DT_ENEMY_INK),
11046 	luaConstant(DT_ENEMY_POISON),
11047 	luaConstant(DT_ENEMY_ACTIVEPOISON),
11048 	luaConstant(DT_ENEMY_CREATOR),
11049 	luaConstant(DT_ENEMY_MANTISBOMB),
11050 	luaConstant(DT_ENEMY_MAX),
11051 	{"DT_ENEMY_END",			DT_ENEMY_MAX},
11052 
11053 	luaConstant(DT_AVATAR),
11054 	luaConstant(DT_AVATAR_ENERGYBLAST),
11055 	luaConstant(DT_AVATAR_SHOCK),
11056 	luaConstant(DT_AVATAR_BITE),
11057 	luaConstant(DT_AVATAR_VOMIT),
11058 	luaConstant(DT_AVATAR_ACID),
11059 	luaConstant(DT_AVATAR_SPORECHILD),
11060 	luaConstant(DT_AVATAR_LIZAP),
11061 	luaConstant(DT_AVATAR_NATURE),
11062 	luaConstant(DT_AVATAR_ENERGYROLL),
11063 	luaConstant(DT_AVATAR_VINE),
11064 	luaConstant(DT_AVATAR_EAT),
11065 	luaConstant(DT_AVATAR_EAT_BASICSHOT),
11066 	luaConstant(DT_AVATAR_EAT_MAX),
11067 	luaConstant(DT_AVATAR_LANCEATTACH),
11068 	luaConstant(DT_AVATAR_LANCE),
11069 	luaConstant(DT_AVATAR_CREATORSHOT),
11070 	luaConstant(DT_AVATAR_DUALFORMLI),
11071 	luaConstant(DT_AVATAR_DUALFORMNAIJA),
11072 	luaConstant(DT_AVATAR_BUBBLE),
11073 	luaConstant(DT_AVATAR_SEED),
11074 	luaConstant(DT_AVATAR_PET),
11075 	luaConstant(DT_AVATAR_PETNAUTILUS),
11076 	luaConstant(DT_AVATAR_PETBITE),
11077 	luaConstant(DT_AVATAR_MAX),
11078 	{"DT_AVATAR_END",			DT_AVATAR_MAX},
11079 
11080 	luaConstant(DT_TOUCH),
11081 	luaConstant(DT_CRUSH),
11082 	luaConstant(DT_SPIKES),
11083 	luaConstant(DT_STEAM),
11084 	luaConstant(DT_WALLHURT),
11085 
11086 
11087 	luaConstant(FRAME_TIME),
11088 
11089 	luaConstant(FORMUPGRADE_ENERGY1),
11090 	luaConstant(FORMUPGRADE_ENERGY2),
11091 	luaConstant(FORMUPGRADE_BEAST),
11092 
11093 	luaConstant(TILE_SIZE),
11094 
11095 	luaConstant(INPUT_MOUSE),
11096 	luaConstant(INPUT_JOYSTICK),
11097 	luaConstant(INPUT_KEYBOARD),
11098 
11099 	luaConstant(ANIMLAYER_FLOURISH),
11100 	luaConstant(ANIMLAYER_OVERRIDE),
11101 	luaConstant(ANIMLAYER_ARMOVERRIDE),
11102 	luaConstant(ANIMLAYER_UPPERBODYIDLE),
11103 	luaConstant(ANIMLAYER_HEADOVERRIDE),
11104 
11105 	luaConstant(OT_EMPTY),
11106 	luaConstant(OT_BLACK),
11107 	luaConstant(OT_BLACKINVIS),
11108 	luaConstant(OT_INVISIBLE),
11109 	luaConstant(OT_INVISIBLEIN),
11110 	luaConstant(OT_HURT),
11111 	luaConstant(OT_INVISIBLEENT),
11112 	luaConstant(OT_USER1),
11113 	luaConstant(OT_USER2),
11114 	luaConstant(OT_MASK_BLACK),
11115 	luaConstant(OT_BLOCKING),
11116 	luaConstant(OT_USER_MASK),
11117 
11118 	luaConstant(SEE_MAP_NEVER),
11119 	luaConstant(SEE_MAP_DEFAULT),
11120 	luaConstant(SEE_MAP_ALWAYS),
11121 
11122 	luaConstant(ALIGN_CENTER),
11123 	luaConstant(ALIGN_LEFT),
11124 
11125 	luaConstant(PATHSHAPE_RECT),
11126 	luaConstant(PATHSHAPE_CIRCLE),
11127 };
11128 
11129 //============================================================================================
11130 // F U N C T I O N S
11131 //============================================================================================
11132 
ScriptInterface()11133 ScriptInterface::ScriptInterface()
11134 : baseState(NULL), _sballoc(8, 128)
11135 {
11136 }
11137 
init()11138 void ScriptInterface::init()
11139 {
11140 	bool devmode = dsq->isDeveloperKeys();
11141 
11142 	// Everything on in dev mode, everything off otherwise.
11143 	loudScriptErrors = devmode;
11144 	complainOnGlobalVar = devmode;
11145 	complainOnUndefLocal = devmode;
11146 
11147 	allowUnsafeFunctions = dsq->user.system.allowDangerousScriptFunctions;
11148 
11149 	if (!baseState)
11150 		baseState = createLuaVM();
11151 }
11152 
reset()11153 void ScriptInterface::reset()
11154 {
11155 	shutdown();
11156 	init();
11157 }
11158 
the_alloc(void * ud,void * ptr,size_t osize,size_t nsize)11159 void *ScriptInterface::the_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
11160 {
11161 	ScriptInterface *this_ = (ScriptInterface*)ud;
11162 	return this_->_sballoc.Alloc(ptr, nsize, osize);
11163 }
11164 
createLuaVM()11165 lua_State *ScriptInterface::createLuaVM()
11166 {
11167 	lua_State *state = lua_newstate(the_alloc, this);	/* opens Lua */
11168 	luaL_openlibs(state);
11169 
11170 	if(!allowUnsafeFunctions)
11171 	{
11172 		lua_pushnil(state);
11173 		lua_setglobal(state, "os");
11174 		lua_pushnil(state);
11175 		lua_setglobal(state, "io");
11176 		lua_pushnil(state);
11177 		lua_setglobal(state, "package");
11178 	}
11179 
11180 	// Set up various tables for state management:
11181 
11182 	// -- Interface function tables for each script file.
11183 	lua_newtable(state);
11184 	lua_setglobal(state, "_scriptfuncs");
11185 
11186 	// -- Number of users (active threads) for each script file.
11187 	lua_newtable(state);
11188 	lua_setglobal(state, "_scriptusers");
11189 
11190 	// -- Initial instance-local tables for each script file.
11191 	lua_newtable(state);
11192 	lua_setglobal(state, "_scriptvars");
11193 
11194 	// -- Instance-local variable tables for each thread.
11195 	lua_newtable(state);
11196 	lua_setglobal(state, "_threadvars");
11197 
11198 	// -- Active threads (so they aren't garbage-collected).
11199 	lua_newtable(state);
11200 	lua_setglobal(state, "_threadtable");
11201 
11202 	// Register all custom functions and constants.
11203 	for (unsigned int i = 0; i < sizeof(luaFunctionTable)/sizeof(*luaFunctionTable); i++)
11204 	{
11205 		lua_register(state, luaFunctionTable[i].name, luaFunctionTable[i].func);
11206 	}
11207 	for (unsigned int i = 0; i < sizeof(luaConstantTable)/sizeof(*luaConstantTable); i++)
11208 	{
11209 		lua_pushnumber(state, luaConstantTable[i].value);
11210 		lua_setglobal(state, luaConstantTable[i].name);
11211 	}
11212 
11213 	// Add hooks to monitor global get/set operations if requested.
11214 	if (complainOnGlobalVar)
11215 	{
11216 		if (!lua_getmetatable(state, LUA_GLOBALSINDEX))
11217 			lua_newtable(state);
11218 		lua_pushcfunction(state, l_indexWarnGlobal);
11219 		lua_setfield(state, -2, "__index");
11220 		lua_pushcfunction(state, l_newindexWarnGlobal);
11221 		lua_setfield(state, -2, "__newindex");
11222 		lua_setmetatable(state, LUA_GLOBALSINDEX);
11223 	}
11224 
11225 	// In case a script errors outside of any protected environment, report and exit.
11226 	lua_atpanic(state, l_panicHandler);
11227 
11228 	// Register Lua classes
11229 	luaL_newmetatable(state, "pathfinder");
11230 	lua_pushliteral(state, "__gc");
11231 	lua_pushcfunction(state, _pathfindDelete);
11232 	lua_settable(state, -3);
11233 	lua_pop(state, 1);
11234 
11235 	// All done, return the new state.
11236 	return state;
11237 }
11238 
destroyLuaVM(lua_State * state)11239 void ScriptInterface::destroyLuaVM(lua_State *state)
11240 {
11241 	if (state)
11242 		lua_close(state);
11243 }
11244 
11245 // Initial value for the instance-local table should be on the stack of
11246 // the base Lua state; it will be popped when this function returns.
createLuaThread(const std::string & file)11247 lua_State *ScriptInterface::createLuaThread(const std::string &file)
11248 {
11249 	lua_State *thread = lua_newthread(baseState);
11250 	if (!thread)
11251 	{
11252 		lua_pop(baseState, 1);
11253 		return NULL;
11254 	}
11255 
11256 	// Save the thread object in a Lua table to prevent it from being
11257 	// garbage-collected.
11258 	lua_getglobal(baseState, "_threadtable");
11259 	lua_pushlightuserdata(baseState, thread);
11260 	lua_pushvalue(baseState, -3);  // -3 = thread
11261 	lua_rawset(baseState, -3);     // -3 = _threadtable
11262 	lua_pop(baseState, 2);
11263 
11264 	// Set up the instance-local variable table for this thread, copying
11265 	// the contents of the initial-value table.
11266 	lua_newtable(baseState);
11267 	lua_pushnil(baseState);
11268 	while (lua_next(baseState, -3))
11269 	{
11270 		// We need to save a copy of the key for the next iteration.
11271 		lua_pushvalue(baseState, -2);
11272 		lua_insert(baseState, -2);
11273 		lua_settable(baseState, -4);
11274 	}
11275 	lua_remove(baseState, -2);  // We no longer need the original table.
11276 	if (complainOnUndefLocal)
11277 	{
11278 		if (!lua_getmetatable(baseState, -1))
11279 			lua_newtable(baseState);
11280 		lua_pushcfunction(baseState, l_indexWarnInstance);
11281 		lua_setfield(baseState, -2, "__index");
11282 		lua_setmetatable(baseState, -2);
11283 	}
11284 	lua_getglobal(baseState, "_threadvars");
11285 	lua_pushlightuserdata(baseState, thread);
11286 	lua_pushvalue(baseState, -3);  // -3 = instance-local table
11287 	lua_rawset(baseState, -3);     // -3 = _threadvars
11288 	lua_pop(baseState, 2);
11289 
11290 	// Update the usage count for this script.
11291 	lua_getglobal(baseState, "_scriptusers");
11292 	lua_getfield(baseState, -1, file.c_str());
11293 	const int users = lua_tointeger(baseState, -1) + 1;
11294 	lua_pop(baseState, 1);
11295 	lua_pushinteger(baseState, users);
11296 	lua_setfield(baseState, -2, file.c_str());
11297 	lua_pop(baseState, 1);
11298 
11299 	return thread;
11300 }
11301 
11302 // Returns the number of remaining users of this script.
destroyLuaThread(const std::string & file,lua_State * thread)11303 int ScriptInterface::destroyLuaThread(const std::string &file, lua_State *thread)
11304 {
11305 	// Threads are not explicitly closed; instead, we delete the thread
11306 	// resources from the state-global tables, thus allowing them to be
11307 	// garbage-collected.  collectGarbage() can be called at a convenient
11308 	// time to forcibly free all dead thread resources.
11309 
11310 	lua_getglobal(baseState, "_threadtable");
11311 	lua_pushlightuserdata(baseState, thread);
11312 	lua_pushnil(baseState);
11313 	lua_rawset(baseState, -3);
11314 	lua_pop(baseState, 1);
11315 
11316 	lua_getglobal(baseState, "_threadvars");
11317 	lua_pushlightuserdata(baseState, thread);
11318 	lua_pushnil(baseState);
11319 	lua_rawset(baseState, -3);
11320 	lua_pop(baseState, 1);
11321 
11322 	lua_getglobal(baseState, "_scriptusers");
11323 	lua_getfield(baseState, -1, file.c_str());
11324 	const int users = lua_tointeger(baseState, -1) - 1;
11325 	lua_pop(baseState, 1);
11326 	if (users > 0)
11327 		lua_pushinteger(baseState, users);
11328 	else
11329 		lua_pushnil(baseState);
11330 	lua_setfield(baseState, -2, file.c_str());
11331 	lua_pop(baseState, 1);
11332 
11333 	return users;
11334 }
11335 
collectGarbage()11336 void ScriptInterface::collectGarbage()
11337 {
11338 	lua_gc(baseState, LUA_GCCOLLECT, 0);
11339 }
11340 
gcGetStats()11341 int ScriptInterface::gcGetStats()
11342 {
11343 	return lua_gc(baseState, LUA_GCCOUNT, 0);
11344 }
11345 
shutdown()11346 void ScriptInterface::shutdown()
11347 {
11348 	destroyLuaVM(baseState);
11349 	baseState = NULL;
11350 }
11351 
openScript(const std::string & file,bool ignoremissing)11352 Script *ScriptInterface::openScript(const std::string &file, bool ignoremissing /* = false */)
11353 {
11354 	std::string realFile = localisePathInternalModpath(file);
11355 	realFile = core->adjustFilenameCase(realFile);
11356 	bool loadedScript = false;
11357 
11358 	lua_getglobal(baseState, "_scriptvars");
11359 	lua_getfield(baseState, -1, realFile.c_str());
11360 	lua_remove(baseState, -2);
11361 	if (!lua_istable(baseState, -1))
11362 	{
11363 		// We must not have loaded the script yet, so load it.
11364 		loadedScript = true;
11365 
11366 		// Clear out the (presumably nil) getfield() result from the stack.
11367 		lua_pop(baseState, 1);
11368 
11369 		// Create a new variable table for the initial run of the script.
11370 		// This will become the initial instance-local variable table for
11371 		// all instances of this script.
11372 		lua_newtable(baseState);
11373 		if (complainOnUndefLocal)
11374 		{
11375 			if (!lua_getmetatable(baseState, -1))
11376 				lua_newtable(baseState);
11377 			lua_pushcfunction(baseState, l_indexWarnInstance);
11378 			lua_setfield(baseState, -2, "__index");
11379 			lua_setmetatable(baseState, -2);
11380 		}
11381 
11382 		// Save the current value of the "v" global, so we can restore it
11383 		// after we run the script.  (We do this here and in Script::call()
11384 		// so that nested Lua calls don't disrupt the caller's instance
11385 		// variable table.)
11386 		lua_getglobal(baseState, "v");
11387 
11388 		// Load the file itself.  This leaves the Lua chunk on the stack.
11389 		int result = loadFile_helper(baseState, realFile.c_str());
11390 		if (result != 0)
11391 		{
11392 			if(result != LUA_ERRFILE || (result == LUA_ERRFILE && !ignoremissing))
11393 				scriptError("Error loading script [" + realFile + "]: " + lua_tostring(baseState, -1));
11394 			lua_pop(baseState, 2);
11395 			return NULL;
11396 		}
11397 
11398 		// Do the initial run of the script, popping the Lua chunk.
11399 		lua_getglobal(baseState, "_threadvars");
11400 		lua_pushlightuserdata(baseState, baseState);
11401 		lua_pushvalue(baseState, -5);
11402 		lua_settable(baseState, -3);
11403 		lua_pop(baseState, 1);
11404 		fixupLocalVars(baseState);
11405 		result = lua_pcall(baseState, 0, 0, 0);
11406 		lua_getglobal(baseState, "_threadvars");
11407 		lua_pushlightuserdata(baseState, baseState);
11408 		lua_pushnil(baseState);
11409 		lua_settable(baseState, -3);
11410 		lua_pop(baseState, 1);
11411 		if (result != 0)
11412 		{
11413 			scriptError("Error doing initial run of script [" + realFile + "]: " + lua_tostring(baseState, -1));
11414 			lua_pop(baseState, 2);
11415 			return NULL;
11416 		}
11417 
11418 		// Restore the old value of the "v" global.
11419 		lua_setglobal(baseState, "v");
11420 
11421 		// Store the instance-local table in the _scriptvars table.
11422 		lua_getglobal(baseState, "_scriptvars");
11423 		lua_pushvalue(baseState, -2);
11424 		lua_setfield(baseState, -2, realFile.c_str());
11425 		lua_pop(baseState, 1);
11426 
11427 		// Generate an interface function table for the script, and
11428 		// clear out the functions from the global environment.
11429 		lua_getglobal(baseState, "_scriptfuncs");
11430 		lua_newtable(baseState);
11431 		for (unsigned int i = 0; interfaceFunctions[i] != NULL; i++)
11432 		{
11433 			const char *funcName = interfaceFunctions[i];
11434 			lua_getglobal(baseState, funcName);
11435 			if (!lua_isnil(baseState, -1))
11436 			{
11437 				lua_setfield(baseState, -2, funcName);
11438 				lua_pushnil(baseState);
11439 				lua_setglobal(baseState, funcName);
11440 			}
11441 			else
11442 			{
11443 				lua_pop(baseState, 1);
11444 			}
11445 		}
11446 		lua_setfield(baseState, -2, realFile.c_str());
11447 		lua_pop(baseState, 1);
11448 
11449 		// Leave the instance-local table on the stack for createLuaThread().
11450 	}
11451 
11452 	lua_State *thread = createLuaThread(realFile.c_str());
11453 	if (!thread)
11454 	{
11455 		scriptError("Unable to create new thread for script [" + realFile + "]");
11456 		if (loadedScript)
11457 		{
11458 			lua_getglobal(baseState, "_scriptfuncs");
11459 			lua_pushnil(baseState);
11460 			lua_setfield(baseState, -2, realFile.c_str());
11461 			lua_pop(baseState, 1);
11462 			lua_getglobal(baseState, "_scriptvars");
11463 			lua_pushnil(baseState);
11464 			lua_setfield(baseState, -2, realFile.c_str());
11465 			lua_pop(baseState, 1);
11466 		}
11467 		return NULL;
11468 	}
11469 
11470 	return new Script(thread, realFile);
11471 }
11472 
closeScript(Script * script)11473 void ScriptInterface::closeScript(Script *script)
11474 {
11475 	const char *file = script->getFile().c_str();
11476 	int users = destroyLuaThread(file, script->getLuaState());
11477 
11478 	// If this was the last instance of this script, unload the script itself.
11479 	if (users <= 0)
11480 	{
11481 		lua_getglobal(baseState, "_scriptfuncs");
11482 		lua_pushnil(baseState);
11483 		lua_setfield(baseState, -2, file);
11484 		lua_pop(baseState, 1);
11485 		lua_getglobal(baseState, "_scriptvars");
11486 		lua_pushnil(baseState);
11487 		lua_setfield(baseState, -2, file);
11488 		lua_pop(baseState, 1);
11489 	}
11490 
11491 	delete script;
11492 }
11493 
runScriptNum(const std::string & file,const std::string & func,int num)11494 bool ScriptInterface::runScriptNum(const std::string &file, const std::string &func, int num)
11495 {
11496 	std::string realFile = file;
11497 	if (file.find('/')==std::string::npos)
11498 		realFile = "scripts/" + file + ".lua";
11499 	Script *script = openScript(realFile);
11500 	if (!script)
11501 		return false;
11502 
11503 	if (!script->call(func.c_str(), num))
11504 	{
11505 		debugLog(script->getLastError());
11506 		debugLog("(error calling func: " + func + " in script: " + file + ")");
11507 		closeScript(script);
11508 		return false;
11509 	}
11510 
11511 	closeScript(script);
11512 	return true;
11513 }
11514 
runScript(const std::string & file,const std::string & func,bool ignoremissing)11515 bool ScriptInterface::runScript(const std::string &file, const std::string &func, bool ignoremissing /* = false */)
11516 {
11517 	std::string realFile = file;
11518 	if (file.find('/')==std::string::npos)
11519 		realFile = "scripts/" + file + ".lua";
11520 	Script *script = openScript(realFile, ignoremissing);
11521 	if (!script)
11522 		return false;
11523 
11524 	if (!func.empty() && !script->call(func.c_str()))
11525 	{
11526 		debugLog(script->getLastError());
11527 		debugLog("(error calling func: " + func + " in script: " + file + ")");
11528 		closeScript(script);
11529 		return false;
11530 	}
11531 
11532 	closeScript(script);
11533 	return true;
11534 }
11535 
11536 //-------------------------------------------------------------------------
11537 
lookupFunc(const char * name)11538 void Script::lookupFunc(const char *name)
11539 {
11540 	lua_getglobal(L, "_scriptfuncs");  // [_scriptfuncs]
11541 	lua_getfield(L, -1, file.c_str()); // [_scriptfuncs, tab]
11542 	lua_remove(L, -2);                 // [tab]
11543 	lua_getfield(L, -1, name);         // [tab, f]
11544 	lua_remove(L, -2);                 // [f]
11545 }
11546 
doCall(int nparams,int nrets)11547 bool Script::doCall(int nparams, int nrets)
11548 {
11549 	// Push the current value of the "v" global onto the Lua stack,
11550 	// so we can restore the current script's instance variable table
11551 	// before returning.
11552 	lua_getglobal(L, "v");                      // [f, ..., v]
11553 
11554 	lua_insert(L, -(nparams+2));                // [v, f, ...]
11555 	fixupLocalVars(L);
11556 
11557 	int vpos = lua_gettop(L) - (nparams+1);
11558 
11559 	bool result;
11560 	if (lua_pcall(L, nparams, nrets, 0) == 0)   // [v, ...]
11561 	{
11562 		result = true;
11563 	}
11564 	else
11565 	{
11566 		lastError = lua_tostring(L, -1);
11567 		lastError += " [";
11568 		lastError += luaFormatStackInfo(L);
11569 		lastError += "]";
11570 		lua_pop(L, 1);
11571 		result = false;
11572 	}
11573 
11574 	if (nrets != 0)
11575 	{
11576 		lua_pushvalue(L, vpos);                // [v, ..., v]
11577 		lua_remove(L, vpos);                   // [..., v]
11578 	}
11579 
11580 	lua_setglobal(L, "v");                     // [...]
11581 
11582 	return result;
11583 }
11584 
call(const char * name)11585 bool Script::call(const char *name)
11586 {
11587 	lookupFunc(name);
11588 	return doCall(0);
11589 }
11590 
call(const char * name,float param1)11591 bool Script::call(const char *name, float param1)
11592 {
11593 	lookupFunc(name);
11594 	lua_pushnumber(L, param1);
11595 	return doCall(1);
11596 }
11597 
call(const char * name,void * param1)11598 bool Script::call(const char *name, void *param1)
11599 {
11600 	lookupFunc(name);
11601 	luaPushPointer(L, param1);
11602 	return doCall(1);
11603 }
11604 
call(const char * name,void * param1,float param2)11605 bool Script::call(const char *name, void *param1, float param2)
11606 {
11607 	lookupFunc(name);
11608 	luaPushPointer(L, param1);
11609 	lua_pushnumber(L, param2);
11610 	return doCall(2);
11611 }
11612 
call(const char * name,void * param1,void * param2)11613 bool Script::call(const char *name, void *param1, void *param2)
11614 {
11615 	lookupFunc(name);
11616 	luaPushPointer(L, param1);
11617 	luaPushPointer(L, param2);
11618 	return doCall(2);
11619 }
11620 
call(const char * name,void * param1,float param2,float param3)11621 bool Script::call(const char *name, void *param1, float param2, float param3)
11622 {
11623 	lookupFunc(name);
11624 	luaPushPointer(L, param1);
11625 	lua_pushnumber(L, param2);
11626 	lua_pushnumber(L, param3);
11627 	return doCall(3);
11628 }
11629 
call(const char * name,void * param1,float param2,float param3,bool * ret1)11630 bool Script::call(const char *name, void *param1, float param2, float param3, bool *ret1)
11631 {
11632 	lookupFunc(name);
11633 	luaPushPointer(L, param1);
11634 	lua_pushnumber(L, param2);
11635 	lua_pushnumber(L, param3);
11636 	if (!doCall(3, 1))
11637 		return false;
11638 	*ret1 = lua_toboolean(L, -1);
11639 	lua_pop(L, 1);
11640 	return true;
11641 }
11642 
call(const char * name,void * param1,const char * param2,float param3)11643 bool Script::call(const char *name, void *param1, const char *param2, float param3)
11644 {
11645 	lookupFunc(name);
11646 	luaPushPointer(L, param1);
11647 	lua_pushstring(L, param2);
11648 	lua_pushnumber(L, param3);
11649 	return doCall(3);
11650 }
11651 
call(const char * name,void * param1,const char * param2,void * param3)11652 bool Script::call(const char *name, void *param1, const char *param2, void *param3)
11653 {
11654 	lookupFunc(name);
11655 	luaPushPointer(L, param1);
11656 	lua_pushstring(L, param2);
11657 	luaPushPointer(L, param3);
11658 	return doCall(3);
11659 }
11660 
call(const char * name,void * param1,void * param2,void * param3)11661 bool Script::call(const char *name, void *param1, void *param2, void *param3)
11662 {
11663 	lookupFunc(name);
11664 	luaPushPointer(L, param1);
11665 	luaPushPointer(L, param2);
11666 	luaPushPointer(L, param3);
11667 	return doCall(3);
11668 }
11669 
call(const char * name,void * param1,float param2,float param3,float param4)11670 bool Script::call(const char *name, void *param1, float param2, float param3, float param4)
11671 {
11672 	lookupFunc(name);
11673 	luaPushPointer(L, param1);
11674 	lua_pushnumber(L, param2);
11675 	lua_pushnumber(L, param3);
11676 	lua_pushnumber(L, param4);
11677 	return doCall(4);
11678 }
11679 
call(const char * name,void * param1,void * param2,void * param3,void * param4)11680 bool Script::call(const char *name, void *param1, void *param2, void *param3, void *param4)
11681 {
11682 	lookupFunc(name);
11683 	luaPushPointer(L, param1);
11684 	luaPushPointer(L, param2);
11685 	luaPushPointer(L, param3);
11686 	luaPushPointer(L, param4);
11687 	return doCall(4);
11688 }
11689 
call(const char * name,void * param1,void * param2,void * param3,float param4,float param5,float param6,float param7,void * param8,bool * ret1)11690 bool Script::call(const char *name, void *param1, void *param2, void *param3, float param4, float param5, float param6, float param7, void *param8, bool *ret1)
11691 {
11692 	lookupFunc(name);
11693 	luaPushPointer(L, param1);
11694 	luaPushPointer(L, param2);
11695 	luaPushPointer(L, param3);
11696 	lua_pushnumber(L, param4);
11697 	lua_pushnumber(L, param5);
11698 	lua_pushnumber(L, param6);
11699 	lua_pushnumber(L, param7);
11700 	luaPushPointer(L, param8);
11701 	if (!doCall(8, 1))
11702 		return false;
11703 	*ret1 = lua_toboolean(L, -1);
11704 	lua_pop(L, 1);
11705 	return true;
11706 }
11707 
call(const char * name,const char * param,bool * ret)11708 bool Script::call(const char *name, const char *param, bool *ret)
11709 {
11710 	lookupFunc(name);
11711 	lua_pushstring(L, param);
11712 	if (!doCall(1, 1))
11713 		return false;
11714 	*ret = lua_toboolean(L, -1);
11715 	lua_pop(L, 1);
11716 	return true;
11717 }
11718 
call(const char * name,const char * param,std::string * ret)11719 bool Script::call(const char *name, const char *param, std::string *ret)
11720 {
11721 	lookupFunc(name);
11722 	lua_pushstring(L, param);
11723 	if (!doCall(1, 1))
11724 		return false;
11725 	*ret = getString(L, -1);
11726 	lua_pop(L, 1);
11727 	return true;
11728 }
11729 
call(const char * name,const char * param1,const char * param2,const char * param3,std::string * ret)11730 bool Script::call(const char *name, const char *param1, const char *param2, const char *param3, std::string *ret)
11731 {
11732 	lookupFunc(name);
11733 	lua_pushstring(L, param1);
11734 	lua_pushstring(L, param2);
11735 	lua_pushstring(L, param3);
11736 	if (!doCall(3, 1))
11737 		return false;
11738 	*ret = getString(L, -1);
11739 	lua_pop(L, 1);
11740 	return true;
11741 }
11742 
callVariadic(const char * name,lua_State * fromL,int nparams,void * param)11743 int Script::callVariadic(const char *name, lua_State *fromL, int nparams, void *param)
11744 {
11745 	int oldtop = lua_gettop(L);
11746 
11747 	lookupFunc(name);
11748 	luaPushPointer(L, param);
11749 
11750 	// If both stacks are the same, we already pushed 2 more entries to the stack.
11751 	int pos = (L == fromL) ? -(nparams+2) : -nparams;
11752 	for (int i = 0; i < nparams; ++i)
11753 		lua_pushvalue(fromL, pos);
11754 
11755 	// Move them to the other stack. Ignored if L == fromL.
11756 	lua_xmove(fromL, L, nparams);
11757 
11758 	// Do the call
11759 	if (!doCall(nparams + 1, LUA_MULTRET))
11760 		return -1;
11761 
11762 	nparams = lua_gettop(L) - oldtop;
11763 	lua_xmove(L, fromL, nparams);
11764 
11765 	return nparams;
11766 }
11767