diff --git a/Aquaria/Path.cpp b/Aquaria/Path.cpp index 2caef69..0635754 100644 --- a/Aquaria/Path.cpp +++ b/Aquaria/Path.cpp @@ -40,7 +40,6 @@ Path::Path() pathType = PATH_NONE; neverSpawned = true; spawnedEntity = 0; - script = 0; updateFunction = activateFunction = false; cursorActivation = false; rect.setWidth(64); @@ -215,11 +214,7 @@ void Path::destroy() emitter->safeKill(); emitter = 0; } - if (script) - { - dsq->scriptInterface.closeScript(script); - script = 0; - } + closeScript(); } Path::~Path() @@ -724,11 +719,6 @@ void Path::luaDebugMsg(const std::string &func, const std::string &msg) debugLog("luaScriptError: Path [" + name + "]: " + func + " : " + msg); } -int Path::pushLuaVars(lua_State *L) -{ - return script ? script->pushLocalVars(L) : 0; -} - MinimapIcon *Path::ensureMinimapIcon() { if(!minimapIcon) diff --git a/Aquaria/Path.h b/Aquaria/Path.h index 777eb77..3af4727 100644 --- a/Aquaria/Path.h +++ b/Aquaria/Path.h @@ -24,12 +24,13 @@ 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" #include "Rect.h" +#include "Scriptable.h" #undef PATH_MAX // May be set by a system header. struct MinimapIcon; +class Entity; class PathNode { @@ -72,7 +73,7 @@ enum PathShape PATHSHAPE_CIRCLE = 1 }; -class Path : public ScriptObject +class Path : public ScriptObject, public Scriptable { public: Path(); @@ -112,7 +113,6 @@ public: void refreshScript(); MinimapIcon *ensureMinimapIcon(); - Script *script; bool updateFunction; bool activateFunction; bool cursorActivation; @@ -157,7 +157,6 @@ public: int messageVariadic(lua_State *L, int nparams); void luaDebugMsg(const std::string &func, const std::string &msg); - int pushLuaVars(lua_State *L); }; #endif diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index 5b91be9..361a01e 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -3057,6 +3057,12 @@ luaFunc(node_v) return n ? n->pushLuaVars(L) : 0; } +luaFunc(shot_v) +{ + Shot *s = getShot(L); + return s ? s->pushLuaVars(L) : 0; +} + luaFunc(isQuitFlag) { luaReturnBool(dsq->isQuitFlag()); @@ -9938,6 +9944,7 @@ static const struct { luaRegister(entity_v), luaRegister(node_v), + luaRegister(shot_v), luaRegister(isQuitFlag), luaRegister(isDeveloperKeys), diff --git a/Aquaria/Scriptable.cpp b/Aquaria/Scriptable.cpp new file mode 100644 index 0000000..e9f73d4 --- /dev/null +++ b/Aquaria/Scriptable.cpp @@ -0,0 +1,21 @@ +#include "Scriptable.h" +#include "ScriptInterface.h" +#include "DSQ.h" + +Scriptable::Scriptable() : script(0) +{ +} + +int Scriptable::pushLuaVars(lua_State *L) +{ + return script ? script->pushLocalVars(L) : 0; +} + +void Scriptable::closeScript() +{ + if (script) + { + dsq->scriptInterface.closeScript(script); + script = 0; + } +} diff --git a/Aquaria/Scriptable.h b/Aquaria/Scriptable.h new file mode 100644 index 0000000..2fbdcee --- /dev/null +++ b/Aquaria/Scriptable.h @@ -0,0 +1,26 @@ +#ifndef AQUARIA_SCRIPTABLE_H +#define AQUARIA_SCRIPTABLE_H + +class Script; +struct lua_State; + +// Object that has a script attached +class Scriptable +{ +public: + Scriptable(); + + Script *script; // NULL if no script is attached + + int pushLuaVars(lua_State *L); + void closeScript(); + + // Note! Before you attempt to move here some common functions like message() or anything that takes a 'this'-pointer: + // ScriptInterface uses raw pointers everywhere. 'this' is always passed as a void*, so if we make any such method that pushes 'this' + // a method of the Scriptable class, then that would pass an offset pointer. + // Eg. Entity *e casted to ((void*)e) is not the same as ((void*)(Scriptable*)e)! And since ScriptInterface does (Entity*)lua_touserdata(L, slot), + // this would break horribly since the necessary type infos to fix the pointer are not preserved. + // A fix would be to dynamic_cast from a common base class, but right now that isn't worth the hassle. +}; + +#endif diff --git a/Aquaria/ScriptedEntity.cpp b/Aquaria/ScriptedEntity.cpp index 1c9cabd..86036a5 100644 --- a/Aquaria/ScriptedEntity.cpp +++ b/Aquaria/ScriptedEntity.cpp @@ -31,7 +31,6 @@ ScriptedEntity::ScriptedEntity(const std::string &scriptName, Vector position, E { addType(SCO_SCRIPTED_ENTITY); crushDelay = 0; - script = 0; songNoteFunction = songNoteDoneFunction = true; addChild(&pullEmitter, PM_STATIC); @@ -93,11 +92,6 @@ int ScriptedEntity::messageVariadic(lua_State *L, int nparams) return Entity::messageVariadic(L, nparams); } -int ScriptedEntity::pushLuaVars(lua_State *L) -{ - return script ? script->pushLocalVars(L) : 0; -} - void ScriptedEntity::warpSegments() { Segmented::warpSegments(position); @@ -394,11 +388,7 @@ void ScriptedEntity::destroy() { CollideEntity::destroy(); - if (script) - { - dsq->scriptInterface.closeScript(script); - script = 0; - } + closeScript(); } void ScriptedEntity::song(SongType songType) diff --git a/Aquaria/ScriptedEntity.h b/Aquaria/ScriptedEntity.h index 5fc0da3..8805c3f 100644 --- a/Aquaria/ScriptedEntity.h +++ b/Aquaria/ScriptedEntity.h @@ -24,11 +24,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "CollideEntity.h" #include "Segmented.h" #include "Particles.h" +#include "Scriptable.h" struct lua_State; class Script; -class ScriptedEntity : public CollideEntity, public Segmented +class ScriptedEntity : public CollideEntity, public Segmented, public Scriptable { public: ScriptedEntity(const std::string &scriptName, Vector position, EntityType et = ET_ENEMY); @@ -50,7 +51,6 @@ public: void entityDied(Entity *e); void message(const std::string &msg, int v); int messageVariadic(lua_State *L, int nparams); - int pushLuaVars(lua_State *L); static bool runningActivation; @@ -105,7 +105,6 @@ protected: void onHitWall(); bool reverseSegments; - Script *script; void onUpdate(float dt); void onEnterState(int action); void onExitState(int action); diff --git a/Aquaria/Shot.cpp b/Aquaria/Shot.cpp index 9408d9e..352ca80 100644 --- a/Aquaria/Shot.cpp +++ b/Aquaria/Shot.cpp @@ -298,7 +298,6 @@ Shot::Shot() : Quad(), Segmented(0,0) enqueuedForDelete = false; shotIdx = shots.size(); shots.push_back(this); - script = 0; updateScript = false; } @@ -431,8 +430,7 @@ void Shot::onEndOfLife() if(script) { script->call("dieNormal", this); - dsq->scriptInterface.closeScript(script); - script = 0; + closeScript(); } destroySegments(0.2f); dead = true; diff --git a/Aquaria/Shot.h b/Aquaria/Shot.h index 150316b..bb7f2e1 100644 --- a/Aquaria/Shot.h +++ b/Aquaria/Shot.h @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "CollideEntity.h" #include "Segmented.h" +#include "Scriptable.h" class ParticleEffect; class Script; @@ -73,7 +74,7 @@ struct ShotData }; -class Shot : public Quad, public Segmented +class Shot : public Quad, public Segmented, public Scriptable { public: @@ -144,7 +145,6 @@ protected: bool fired; bool enqueuedForDelete; void onUpdate(float dt); - Script *script; bool updateScript; private: diff --git a/CMakeLists.txt b/CMakeLists.txt index daeb4a5..63359c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -453,6 +453,7 @@ SET(AQUARIA_SRCS ${SRCDIR}/RecipeMenuEntry.cpp ${SRCDIR}/SceneEditor.cpp ${SRCDIR}/SchoolFish.cpp + ${SRCDIR}/Scriptable.cpp ${SRCDIR}/ScriptedEntity.cpp ${SRCDIR}/ScriptInterface.cpp ${SRCDIR}/Segmented.cpp diff --git a/win/vc90/Aquaria.vcproj b/win/vc90/Aquaria.vcproj index 2afa0ec..1b96696 100644 --- a/win/vc90/Aquaria.vcproj +++ b/win/vc90/Aquaria.vcproj @@ -631,6 +631,14 @@ RelativePath="..\..\Aquaria\SchoolFish.h" > + + + +