mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-01-24 17:26:41 +00:00
Add a safe pointer model to ScriptInterface, additional bug/crash fixes.
This commit introduces pointer checks to various functions; so that entity_* will no longer crash or produce weird results if passed a Node pointer, etc. The checks are disabled by default, but can be enabled in ScriptInterface.cpp. Fixed possible crashes in a few more functions due to missing NULL-checks. There was a "feature" in the single Lua state that it would keep globals intact until the game was quit. That made any globals from mods "leak" into the game or other mods. Now it resets the Lua state when a mod is loaded or closed.
This commit is contained in:
parent
becd31770c
commit
4320b8296b
22 changed files with 298 additions and 103 deletions
|
@ -28,6 +28,7 @@ Beam::Beams Beam::beams;
|
|||
|
||||
Beam::Beam(Vector pos, float angle) : Quad()
|
||||
{
|
||||
addType(SCO_BEAM);
|
||||
cull = false;
|
||||
trace();
|
||||
//rotation.z = angle;
|
||||
|
|
|
@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
CollideEntity::CollideEntity() : Entity()
|
||||
{
|
||||
addType(SCO_COLLIDE_ENTITY);
|
||||
this->canBeTargetedByAvatar = true;
|
||||
weight = 0;
|
||||
bounceAmount = 0.5f;
|
||||
|
|
|
@ -167,6 +167,7 @@ bool Entity::canSetBoneLock()
|
|||
|
||||
Entity::Entity() : StateMachine(), DFSprite()
|
||||
{
|
||||
addType(SCO_ENTITY);
|
||||
poison = 0.0f;
|
||||
calledEntityDied = false;
|
||||
wasUnderWater = true;
|
||||
|
|
|
@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "../BBGE/StateMachine.h"
|
||||
#include "../ExternalLibs/tinyxml.h"
|
||||
#include "../BBGE/SkeletalSprite.h"
|
||||
#include "../BBGE/ScriptObject.h"
|
||||
|
||||
#include "DSQ.h"
|
||||
#include "Path.h"
|
||||
|
@ -193,7 +194,7 @@ enum BounceType
|
|||
BOUNCE_REAL = 1
|
||||
};
|
||||
|
||||
class Entity : public StateMachine, public DFSprite
|
||||
class Entity : public ScriptObject, public DFSprite, public StateMachine
|
||||
{
|
||||
public:
|
||||
Entity();
|
||||
|
|
|
@ -40,6 +40,7 @@ bool IngredientData::hasIET(IngredientEffectType iet)
|
|||
Ingredient::Ingredient(const Vector &pos, IngredientData *data, int amount)
|
||||
: Entity(), data(data), amount(amount), gone(false), used(false)
|
||||
{
|
||||
addType(SCO_INGREDIENT);
|
||||
entityType = ET_INGREDIENT;
|
||||
position = pos;
|
||||
lifeSpan = 30;
|
||||
|
|
|
@ -196,7 +196,8 @@ void Mod::applyStart()
|
|||
core->clearGarbage();
|
||||
recache();
|
||||
dsq->continuity.reset();
|
||||
|
||||
dsq->scriptInterface.reset();
|
||||
|
||||
// load the mod-init.lua file
|
||||
// which is in the root of the mod's folder
|
||||
// e.g. _mods/recachetest/
|
||||
|
@ -265,6 +266,7 @@ void Mod::stop()
|
|||
core->settings.runInBackground = false;
|
||||
debugMenu = false;
|
||||
shuttingDown = false;
|
||||
dsq->scriptInterface.reset();
|
||||
}
|
||||
|
||||
void Mod::update(float dt)
|
||||
|
|
|
@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
Path::Path()
|
||||
{
|
||||
addType(SCO_PATH);
|
||||
localWarpType = LOCALWARP_NONE;
|
||||
effectOn = true;
|
||||
time = 0;
|
||||
|
|
|
@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "../BBGE/Base.h"
|
||||
#include "../BBGE/Particles.h"
|
||||
#include "../BBGE/ScriptObject.h"
|
||||
#include "ScriptInterface.h"
|
||||
|
||||
#undef PATH_MAX // May be set by a system header.
|
||||
|
@ -67,7 +68,7 @@ enum PathShape
|
|||
PATHSHAPE_CIRCLE = 1
|
||||
};
|
||||
|
||||
class Path
|
||||
class Path : public ScriptObject
|
||||
{
|
||||
public:
|
||||
Path();
|
||||
|
|
|
@ -19,6 +19,7 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "ScriptInterface.h"
|
||||
#include "../BBGE/ScriptObject.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "lua.h"
|
||||
|
@ -37,14 +38,22 @@ extern "C"
|
|||
#include "../BBGE/MathFunctions.h"
|
||||
|
||||
|
||||
// Define this to 1 to check types of pointers passed to functions,
|
||||
// and warn if a type mismatch is detected. In this case,
|
||||
// the pointer is treated as NULL, to avoid crashing or undefined behavior.
|
||||
//#define CHECK_POINTER_TYPES 1
|
||||
|
||||
// If true, send all sort of script errors to errorLog instead of debugLog.
|
||||
// On win32, this pops up message boxes which help to locate errors easily,
|
||||
// On win32/OSX, this pops up message boxes which help to locate errors easily,
|
||||
// but can be annoying for regular gameplay.
|
||||
const bool loudScriptErrors = false;
|
||||
|
||||
// This setting causes NULL/0 pointers passed to a function to issue
|
||||
// a Lua error instead of silently ignoring it.
|
||||
// Some functions expect this behavior - do not enable!.
|
||||
const bool throwLuaErrors = false;
|
||||
|
||||
// Set this to true to complain (via errorLog()) whenever a script tries to
|
||||
// Set this to true to complain whenever a script tries to
|
||||
// get or set a global variable.
|
||||
const bool complainOnGlobalVar = false;
|
||||
|
||||
|
@ -312,10 +321,75 @@ static inline void luaPushPointer(lua_State *L, void *ptr)
|
|||
lua_pushnumber(L, 0);
|
||||
}
|
||||
|
||||
static std::string luaFormatStackInfo(lua_State *L)
|
||||
{
|
||||
lua_Debug ar;
|
||||
if (lua_getstack(L, 1, &ar))
|
||||
lua_getinfo(L, "Sl", &ar);
|
||||
else
|
||||
{
|
||||
snprintf(ar.short_src, sizeof(ar.short_src), "???");
|
||||
ar.currentline = 0;
|
||||
}
|
||||
std::ostringstream os;
|
||||
os << ar.short_src << ":" << ar.currentline;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
|
||||
#if CHECK_POINTER_TYPES
|
||||
// Not intended to be called.
|
||||
// Because wild typecasting expects X::_objtype to reside at the same relative
|
||||
// memory location, be sure this is the case before running into undefined behavior later.
|
||||
// - The C++ standard allows offsetof() only on POD-types. Oh well, it probably works anyways.
|
||||
// If it does not compile for some reason, comment it out, hope for the best, and go ahead.
|
||||
void compile_time_assertions()
|
||||
{
|
||||
#define oo(cls) offsetof(cls, _objtype)
|
||||
#define compile_assert(pred) switch(0){case 0:case (pred):;}
|
||||
compile_assert(oo(Path) == oo(Entity));
|
||||
compile_assert(oo(Path) == oo(Ingredient));
|
||||
compile_assert(oo(Path) == oo(CollideEntity));
|
||||
compile_assert(oo(Path) == oo(ScriptedEntity));
|
||||
compile_assert(oo(Path) == oo(Beam));
|
||||
compile_assert(oo(Path) == oo(Shot));
|
||||
compile_assert(oo(Path) == oo(Web));
|
||||
compile_assert(oo(Path) == oo(Bone));
|
||||
compile_assert(oo(Path) == oo(PauseQuad));
|
||||
compile_assert(oo(Path) == oo(Avatar));
|
||||
#undef oo
|
||||
#undef compile_assert
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void ensureType(lua_State *L, T *& ptr, ScriptObjectType ty)
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
ScriptObject *so = (ScriptObject*)(ptr);
|
||||
if (!so->isType(ty))
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "WARNING: " << luaFormatStackInfo(L)
|
||||
<< ": script passed wrong pointer to function (expected type: "
|
||||
<< ScriptObject::getTypeString(ty) << "; got: "
|
||||
<< so->getTypeString() << ')';
|
||||
scriptError(os.str());
|
||||
|
||||
ptr = NULL; // note that the pointer is passed by reference
|
||||
}
|
||||
}
|
||||
}
|
||||
# define ENSURE_TYPE(ptr, ty) ensureType(L, (ptr), (ty))
|
||||
#else
|
||||
# define ENSURE_TYPE(ptr, ty)
|
||||
#endif
|
||||
|
||||
static inline
|
||||
ScriptedEntity *scriptedEntity(lua_State *L, int slot = 1)
|
||||
{
|
||||
ScriptedEntity *se = (ScriptedEntity*)lua_touserdata(L, slot);
|
||||
ENSURE_TYPE(se, SCO_SCRIPTED_ENTITY);
|
||||
if (!se)
|
||||
debugLog("ScriptedEntity invalid pointer.");
|
||||
return se;
|
||||
|
@ -325,25 +399,17 @@ static inline
|
|||
CollideEntity *collideEntity(lua_State *L, int slot = 1)
|
||||
{
|
||||
CollideEntity *ce = (CollideEntity*)lua_touserdata(L, slot);
|
||||
ENSURE_TYPE(ce, SCO_COLLIDE_ENTITY);
|
||||
if (!ce)
|
||||
debugLog("CollideEntity invalid pointer.");
|
||||
return ce ;
|
||||
}
|
||||
|
||||
static inline
|
||||
RenderObject *object(lua_State *L, int slot = 1)
|
||||
{
|
||||
//RenderObject *obj = dynamic_cast<RenderObject*>((RenderObject*)(int(lua_tonumber(L, slot))));
|
||||
RenderObject *obj = static_cast<RenderObject*>(lua_touserdata(L, slot));
|
||||
if (!obj)
|
||||
debugLog("RenderObject invalid pointer");
|
||||
return obj;
|
||||
}
|
||||
|
||||
static inline
|
||||
Beam *beam(lua_State *L, int slot = 1)
|
||||
{
|
||||
Beam *b = (Beam*)lua_touserdata(L, slot);
|
||||
ENSURE_TYPE(b, SCO_BEAM);
|
||||
if (!b)
|
||||
debugLog("Beam invalid pointer.");
|
||||
return b;
|
||||
|
@ -364,6 +430,7 @@ static inline
|
|||
Shot *getShot(lua_State *L, int slot = 1)
|
||||
{
|
||||
Shot *shot = (Shot*)lua_touserdata(L, slot);
|
||||
ENSURE_TYPE(shot, SCO_SHOT);
|
||||
return shot;
|
||||
}
|
||||
|
||||
|
@ -371,13 +438,16 @@ static inline
|
|||
Web *getWeb(lua_State *L, int slot = 1)
|
||||
{
|
||||
Web *web = (Web*)lua_touserdata(L, slot);
|
||||
ENSURE_TYPE(web, SCO_WEB);
|
||||
return web;
|
||||
}
|
||||
|
||||
static inline
|
||||
Ingredient *getIng(lua_State *L, int slot = 1)
|
||||
{
|
||||
return (Ingredient*)lua_touserdata(L, slot);
|
||||
Ingredient *ing = (Ingredient*)lua_touserdata(L, slot);
|
||||
ENSURE_TYPE(ing, SCO_INGREDIENT);
|
||||
return ing;
|
||||
}
|
||||
|
||||
static inline
|
||||
|
@ -402,6 +472,7 @@ static inline
|
|||
Entity *entity(lua_State *L, int slot = 1)
|
||||
{
|
||||
Entity *ent = (Entity*)lua_touserdata(L, slot);
|
||||
ENSURE_TYPE(ent, SCO_ENTITY);
|
||||
if (!ent)
|
||||
{
|
||||
luaErrorMsg(L, "Entity Invalid Pointer");
|
||||
|
@ -421,6 +492,7 @@ static inline
|
|||
Bone *bone(lua_State *L, int slot = 1)
|
||||
{
|
||||
Bone *b = (Bone*)lua_touserdata(L, slot);
|
||||
ENSURE_TYPE(b, SCO_BONE);
|
||||
if (!b)
|
||||
{
|
||||
luaErrorMsg(L, "Bone Invalid Pointer");
|
||||
|
@ -445,6 +517,7 @@ static inline
|
|||
Path *path(lua_State *L, int slot = 1)
|
||||
{
|
||||
Path *p = (Path*)lua_touserdata(L, slot);
|
||||
ENSURE_TYPE(p, SCO_PATH);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -463,28 +536,15 @@ static RenderObject *boneToRenderObject(lua_State *L, int slot = 1)
|
|||
static PauseQuad *getPauseQuad(lua_State *L, int slot = 1)
|
||||
{
|
||||
PauseQuad *q = (PauseQuad*)lua_touserdata(L, slot);
|
||||
if (q)
|
||||
return q;
|
||||
else
|
||||
ENSURE_TYPE(q, SCO_PAUSEQUAD);
|
||||
if (!q)
|
||||
errorLog("Invalid PauseQuad/Particle");
|
||||
return 0;
|
||||
return q;
|
||||
}
|
||||
|
||||
static SkeletalSprite *getSkeletalSprite(Entity *e)
|
||||
{
|
||||
Avatar *a;
|
||||
ScriptedEntity *se;
|
||||
SkeletalSprite *skel = 0;
|
||||
if ((a = dynamic_cast<Avatar*>(e)) != 0)
|
||||
{
|
||||
//a->skeletalSprite.transitionAnimate(lua_tostring(L, 2), 0.15, lua_tointeger(L, 3));
|
||||
skel = &a->skeletalSprite;
|
||||
}
|
||||
else if ((se = dynamic_cast<ScriptedEntity*>(e)) != 0)
|
||||
{
|
||||
skel = &se->skeletalSprite;
|
||||
}
|
||||
return skel;
|
||||
return e ? &e->skeletalSprite : NULL;
|
||||
}
|
||||
|
||||
static bool looksLikeGlobal(const char *s)
|
||||
|
@ -537,20 +597,8 @@ luaFunc(indexWarnGlobal)
|
|||
|
||||
if (doWarn)
|
||||
{
|
||||
lua_Debug ar;
|
||||
if (lua_getstack(L, 1, &ar))
|
||||
{
|
||||
lua_getinfo(L, "Sl", &ar);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(ar.short_src, sizeof(ar.short_src), "???");
|
||||
ar.currentline = 0;
|
||||
}
|
||||
|
||||
lua_getinfo(L, "Sl", &ar);
|
||||
std::ostringstream os;
|
||||
os << "WARNING: " << ar.short_src << ":" << ar.currentline
|
||||
os << "WARNING: " << luaFormatStackInfo(L)
|
||||
<< ": script tried to get/call undefined global variable "
|
||||
<< varname;
|
||||
scriptError(os.str());
|
||||
|
@ -577,22 +625,11 @@ luaFunc(newindexWarnGlobal)
|
|||
|
||||
if (doWarn)
|
||||
{
|
||||
lua_Debug ar;
|
||||
if (lua_getstack(L, 1, &ar))
|
||||
{
|
||||
lua_getinfo(L, "Sl", &ar);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(ar.short_src, sizeof(ar.short_src), "???");
|
||||
ar.currentline = 0;
|
||||
}
|
||||
|
||||
std::ostringstream os;
|
||||
os << "WARNING: " << ar.short_src << ":" << ar.currentline
|
||||
os << "WARNING: " << luaFormatStackInfo(L)
|
||||
<< ": script set global "
|
||||
<< (lua_type(L, -2) == LUA_TFUNCTION ? "function" : "variable")
|
||||
<< " " << lua_tostring(L, -1);
|
||||
<< " " << varname;
|
||||
scriptError(os.str());
|
||||
}
|
||||
|
||||
|
@ -611,18 +648,8 @@ luaFunc(indexWarnInstance)
|
|||
lua_remove(L, -3);
|
||||
if (lua_isnil(L, -1))
|
||||
{
|
||||
lua_Debug ar;
|
||||
if (lua_getstack(L, 1, &ar))
|
||||
{
|
||||
lua_getinfo(L, "Sl", &ar);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(ar.short_src, sizeof(ar.short_src), "???");
|
||||
ar.currentline = 0;
|
||||
}
|
||||
std::ostringstream os;
|
||||
os << "WARNING: " << ar.short_src << ":" << ar.currentline
|
||||
os << "WARNING: " << luaFormatStackInfo(L)
|
||||
<< ": script tried to get/call undefined instance variable "
|
||||
<< lua_tostring(L, -2);
|
||||
errorLog(os.str());
|
||||
|
@ -1819,14 +1846,6 @@ luaFunc(loadMap)
|
|||
|
||||
luaFunc(entity_followPath)
|
||||
{
|
||||
/*
|
||||
std::ostringstream os2;
|
||||
os2 << lua_tointeger(L, 1);
|
||||
errorLog(os2.str());
|
||||
std::ostringstream os;
|
||||
os << "Entity: " << scriptedEntity(L)->name << " moving on Path: " << lua_tostring(L, 2);
|
||||
debugLog(os.str());
|
||||
*/
|
||||
Entity *e = entity(L);
|
||||
if (e)
|
||||
{
|
||||
|
@ -2627,16 +2646,16 @@ luaFunc(entity_setAnimLayerTimeMult)
|
|||
luaFunc(entity_animate)
|
||||
{
|
||||
SkeletalSprite *skel = getSkeletalSprite(entity(L));
|
||||
|
||||
// 0.15
|
||||
// 0.2
|
||||
float transition = lua_tonumber(L, 5);
|
||||
if (transition == -1)
|
||||
transition = 0;
|
||||
else if (transition == 0)
|
||||
transition = 0.2;
|
||||
float ret = skel->transitionAnimate(lua_tostring(L, 2), transition, lua_tointeger(L, 3), lua_tointeger(L, 4));
|
||||
|
||||
float ret = 0;
|
||||
if (skel)
|
||||
{
|
||||
float transition = lua_tonumber(L, 5);
|
||||
if (transition == -1)
|
||||
transition = 0;
|
||||
else if (transition == 0)
|
||||
transition = 0.2;
|
||||
ret = skel->transitionAnimate(lua_tostring(L, 2), transition, lua_tointeger(L, 3), lua_tointeger(L, 4));
|
||||
}
|
||||
luaReturnNum(ret);
|
||||
}
|
||||
|
||||
|
@ -3642,13 +3661,17 @@ luaFunc(entity_rotateToVec)
|
|||
|
||||
luaFunc(entity_update)
|
||||
{
|
||||
entity(L)->update(lua_tonumber(L, 2));
|
||||
Entity *e = entity(L);
|
||||
if (e)
|
||||
e->update(lua_tonumber(L, 2));
|
||||
luaReturnNum(0);
|
||||
}
|
||||
|
||||
luaFunc(entity_updateSkeletal)
|
||||
{
|
||||
entity(L)->skeletalSprite.update(lua_tonumber(L, 2));
|
||||
Entity *e = entity(L);
|
||||
if (e)
|
||||
e->skeletalSprite.update(lua_tonumber(L, 2));
|
||||
luaReturnNum(0);
|
||||
}
|
||||
|
||||
|
@ -3667,17 +3690,21 @@ luaFunc(entity_msg)
|
|||
|
||||
luaFunc(entity_updateCurrents)
|
||||
{
|
||||
luaReturnBool(entity(L)->updateCurrents(lua_tonumber(L, 2)));
|
||||
Entity *e = entity(L);
|
||||
luaReturnBool(e ? e->updateCurrents(lua_tonumber(L, 2)) : false);
|
||||
}
|
||||
|
||||
luaFunc(entity_updateLocalWarpAreas)
|
||||
{
|
||||
luaReturnBool(entity(L)->updateLocalWarpAreas(getBool(L, 2)));
|
||||
Entity *e = entity(L);
|
||||
luaReturnBool(e ? e->updateLocalWarpAreas(getBool(L, 2)) : false);
|
||||
}
|
||||
|
||||
luaFunc(entity_updateMovement)
|
||||
{
|
||||
scriptedEntity(L)->updateMovement(lua_tonumber(L, 2));
|
||||
ScriptedEntity *e = scriptedEntity(L);
|
||||
if (e)
|
||||
e->updateMovement(lua_tonumber(L, 2));
|
||||
luaReturnNum(0);
|
||||
}
|
||||
|
||||
|
@ -6586,12 +6613,14 @@ luaFunc(entity_getTarget)
|
|||
|
||||
luaFunc(entity_getTargetPositionX)
|
||||
{
|
||||
luaReturnInt(int(entity(L)->getTargetEntity()->position.x));
|
||||
Entity *e = entity(L);
|
||||
luaReturnInt(e ? e->getTargetEntity()->position.x : 0);
|
||||
}
|
||||
|
||||
luaFunc(entity_getTargetPositionY)
|
||||
{
|
||||
luaReturnInt(int(entity(L)->getTargetEntity()->position.y));
|
||||
Entity *e = entity(L);
|
||||
luaReturnNum(e ? e->getTargetEntity()->position.y : 0);
|
||||
}
|
||||
|
||||
luaFunc(entity_isNearObstruction)
|
||||
|
@ -7095,7 +7124,6 @@ luaFunc(entity_setFlag)
|
|||
luaFunc(entity_getFlag)
|
||||
{
|
||||
Entity *e = entity(L);
|
||||
int v = lua_tonumber(L, 2);
|
||||
int ret = 0;
|
||||
if (e)
|
||||
{
|
||||
|
@ -8821,9 +8849,21 @@ static const struct {
|
|||
// F U N C T I O N S
|
||||
//============================================================================================
|
||||
|
||||
ScriptInterface::ScriptInterface()
|
||||
: baseState(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void ScriptInterface::init()
|
||||
{
|
||||
baseState = createLuaVM();
|
||||
if (!baseState)
|
||||
baseState = createLuaVM();
|
||||
}
|
||||
|
||||
void ScriptInterface::reset()
|
||||
{
|
||||
shutdown();
|
||||
init();
|
||||
}
|
||||
|
||||
lua_State *ScriptInterface::createLuaVM()
|
||||
|
@ -8987,6 +9027,8 @@ void ScriptInterface::collectGarbage()
|
|||
|
||||
void ScriptInterface::shutdown()
|
||||
{
|
||||
destroyLuaVM(baseState);
|
||||
baseState = NULL;
|
||||
}
|
||||
|
||||
Script *ScriptInterface::openScript(const std::string &file, bool ignoremissing /* = false */)
|
||||
|
|
|
@ -77,7 +77,9 @@ protected:
|
|||
class ScriptInterface
|
||||
{
|
||||
public:
|
||||
ScriptInterface();
|
||||
void init();
|
||||
void reset();
|
||||
void collectGarbage();
|
||||
void shutdown();
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
bool ScriptedEntity::runningActivation = false;
|
||||
|
||||
ScriptedEntity::ScriptedEntity(const std::string &scriptName, Vector position, EntityType et) : CollideEntity(), Segmented(2, 26)
|
||||
{
|
||||
{
|
||||
addType(SCO_SCRIPTED_ENTITY);
|
||||
crushDelay = 0;
|
||||
autoSkeletalSpriteUpdate = true;
|
||||
script = 0;
|
||||
|
|
|
@ -323,6 +323,7 @@ Shot::Shot(DamageType damageType, Entity *firer, Vector pos, Entity *target, std
|
|||
|
||||
Shot::Shot() : Quad(), Segmented(0,0)
|
||||
{
|
||||
addType(SCO_SHOT);
|
||||
extraDamage= 0;
|
||||
waveTimer = rand()%314;
|
||||
emitter = 0;
|
||||
|
|
|
@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "CollideEntity.h"
|
||||
#include "Segmented.h"
|
||||
#include "../BBGE/Particles.h"
|
||||
#include "../BBGE/ScriptObject.h"
|
||||
|
||||
struct ShotData
|
||||
{
|
||||
|
@ -69,7 +70,7 @@ struct ShotData
|
|||
|
||||
};
|
||||
|
||||
class Shot : public Quad, public Segmented
|
||||
class Shot : public ScriptObject, public Quad, public Segmented
|
||||
{
|
||||
public:
|
||||
//Shot(DamageType damageType, Entity *firer, Vector pos, Entity *target, std::string tex="", float homingness=1000, int maxSpeed=400, int segments=10, float segMin=0.1, float segMax=5, float damage = 1, float lifeTime = 0);
|
||||
|
@ -136,7 +137,7 @@ protected:
|
|||
void onUpdate(float dt);
|
||||
};
|
||||
|
||||
class Beam : public Quad
|
||||
class Beam : public ScriptObject, public Quad
|
||||
{
|
||||
public:
|
||||
Beam(Vector pos, float angle);
|
||||
|
|
|
@ -27,6 +27,7 @@ Web::Webs Web::webs;
|
|||
|
||||
Web::Web() : RenderObject()
|
||||
{
|
||||
addType(SCO_WEB);
|
||||
webs.push_back(this);
|
||||
cull = false;
|
||||
parentEntity = 0;
|
||||
|
|
|
@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "../BBGE/Quad.h"
|
||||
#include "Entity.h"
|
||||
|
||||
class Web : public RenderObject
|
||||
class Web : public ScriptObject, public RenderObject
|
||||
{
|
||||
public:
|
||||
Web();
|
||||
|
|
|
@ -918,6 +918,7 @@ void Quad::onSetTexture()
|
|||
|
||||
PauseQuad::PauseQuad() : Quad(), pauseLevel(0)
|
||||
{
|
||||
addType(SCO_PAUSEQUAD);
|
||||
}
|
||||
|
||||
void PauseQuad::onUpdate(float dt)
|
||||
|
|
|
@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define __quad__
|
||||
|
||||
#include "RenderObject.h"
|
||||
#include "ScriptObject.h"
|
||||
|
||||
class QuadLight
|
||||
{
|
||||
|
@ -149,7 +150,7 @@ private:
|
|||
void initQuad();
|
||||
};
|
||||
|
||||
class PauseQuad : public Quad
|
||||
class PauseQuad : public ScriptObject, public Quad
|
||||
{
|
||||
public:
|
||||
PauseQuad();
|
||||
|
|
60
BBGE/ScriptObject.cpp
Normal file
60
BBGE/ScriptObject.cpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
Copyright (C) 2007, 2012 - Bit-Blot
|
||||
|
||||
This file is part of Aquaria.
|
||||
|
||||
Aquaria is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "ScriptObject.h"
|
||||
|
||||
static const char *scriptObjTypeNames[] =
|
||||
{
|
||||
/* (1 << 0) */ "Entity",
|
||||
/* (1 << 1) */ "Ingredient",
|
||||
/* (1 << 2) */ "CollideEntity",
|
||||
/* (1 << 3) */ "ScriptedEntity",
|
||||
/* (1 << 4) */ "Beam",
|
||||
/* (1 << 5) */ "Shot",
|
||||
/* (1 << 6) */ "Web",
|
||||
/* (1 << 7) */ "Bone",
|
||||
/* (1 << 8) */ "Path/Node",
|
||||
/* (1 << 9) */ "PauseQuad",
|
||||
NULL
|
||||
};
|
||||
|
||||
std::string ScriptObject::getTypeString(unsigned int ty)
|
||||
{
|
||||
if (ty == SCO_NONE)
|
||||
return "NO TYPE";
|
||||
|
||||
bool more = false;
|
||||
std::ostringstream os;
|
||||
for (int i = 0; scriptObjTypeNames[i]; ++i)
|
||||
{
|
||||
if (ty & (1 << i))
|
||||
{
|
||||
if (more)
|
||||
os << ", ";
|
||||
os << scriptObjTypeNames[i];
|
||||
more = true;
|
||||
}
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
74
BBGE/ScriptObject.h
Normal file
74
BBGE/ScriptObject.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
Copyright (C) 2007, 2012 - Bit-Blot
|
||||
|
||||
This file is part of Aquaria.
|
||||
|
||||
Aquaria is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
enum ScriptObjectType
|
||||
{
|
||||
SCO_NONE = 0x0000,
|
||||
|
||||
// If you change this enum, do not forget to adjust the string array in the cpp,
|
||||
// and to add additional compile time assertions to ScriptInterface.cpp as necessary!
|
||||
SCO_ENTITY = 0x0001,
|
||||
SCO_INGREDIENT = 0x0002,
|
||||
SCO_COLLIDE_ENTITY = 0x0004,
|
||||
SCO_SCRIPTED_ENTITY = 0x0008,
|
||||
SCO_BEAM = 0x0010,
|
||||
SCO_SHOT = 0x0020,
|
||||
SCO_WEB = 0x0040,
|
||||
SCO_BONE = 0x0080,
|
||||
SCO_PATH = 0x0100,
|
||||
SCO_PAUSEQUAD = 0x0200,
|
||||
|
||||
SCO_FORCE_32BIT = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
|
||||
class ScriptObject
|
||||
{
|
||||
public:
|
||||
|
||||
ScriptObject()
|
||||
: _objtype(SCO_NONE)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~ScriptObject() {}
|
||||
|
||||
inline void addType(ScriptObjectType ty)
|
||||
{
|
||||
_objtype = ScriptObjectType(int(ty) | int(_objtype)); // prevent the compiler from crying
|
||||
}
|
||||
|
||||
inline bool isType(ScriptObjectType bt) const
|
||||
{
|
||||
return (_objtype & bt) != 0;
|
||||
}
|
||||
|
||||
inline std::string getTypeString() const
|
||||
{
|
||||
return getTypeString(_objtype);
|
||||
}
|
||||
|
||||
static std::string getTypeString(unsigned int ty);
|
||||
|
||||
// public to allow the static compile check in ScriptInterface.cpp to work
|
||||
ScriptObjectType _objtype;
|
||||
};
|
|
@ -42,6 +42,7 @@ void SkeletalKeyframe::copyAllButTime(SkeletalKeyframe *copy)
|
|||
|
||||
Bone::Bone() : Quad()
|
||||
{
|
||||
addType(SCO_BONE);
|
||||
fileRenderQuad = true;
|
||||
skeleton = 0;
|
||||
generateCollisionMask = true;
|
||||
|
|
|
@ -37,7 +37,7 @@ enum AnimationCommand
|
|||
class ParticleEffect;
|
||||
class SkeletalSprite;
|
||||
|
||||
class Bone : public Quad
|
||||
class Bone : public ScriptObject, public Quad
|
||||
{
|
||||
public:
|
||||
Bone();
|
||||
|
|
|
@ -362,6 +362,7 @@ SET(BBGE_SRCS
|
|||
${BBGEDIR}/Resource.cpp
|
||||
${BBGEDIR}/RoundedRect.cpp
|
||||
${BBGEDIR}/ScreenTransition.cpp
|
||||
${BBGEDIR}/ScriptObject.cpp
|
||||
${BBGEDIR}/Shader.cpp
|
||||
${BBGEDIR}/SkeletalSprite.cpp
|
||||
${BBGEDIR}/Slider.cpp
|
||||
|
|
Loading…
Reference in a new issue