From 24e5b19904a9b115a92e933bd62748ff5c198613 Mon Sep 17 00:00:00 2001 From: Christoph Sommer Date: Fri, 2 Jun 2006 23:46:39 +0000 Subject: [PATCH] Candle can now be turned on and off via squirrel scripting SVN-Revision: 3627 --- data/images/objects/candle/candle.sprite | 8 ++- data/images/objects/candle/off.png | Bin 0 -> 792 bytes data/levels/test/candle.stl | 111 +++++++++++++++++++++++++++++++ src/object/candle.cpp | 65 +++++++++++++++--- src/object/candle.hpp | 20 ++++-- src/scripting/candle.cpp | 50 ++++++++++++++ src/scripting/candle.hpp | 50 ++++++++++++++ src/scripting/wrapper.cpp | 110 ++++++++++++++++++++++++++++++ src/scripting/wrapper.hpp | 1 + src/scripting/wrapper.interface.hpp | 1 + 10 files changed, 402 insertions(+), 14 deletions(-) create mode 100644 data/images/objects/candle/off.png create mode 100644 data/levels/test/candle.stl create mode 100644 src/scripting/candle.cpp create mode 100644 src/scripting/candle.hpp diff --git a/data/images/objects/candle/candle.sprite b/data/images/objects/candle/candle.sprite index 1234648b9..17f735df4 100644 --- a/data/images/objects/candle/candle.sprite +++ b/data/images/objects/candle/candle.sprite @@ -1,6 +1,6 @@ (supertux-sprite (action - (name "default") + (name "on") (images "candle-1.png" "candle-2.png" @@ -8,5 +8,11 @@ "candle-4.png" ) ) + (action + (name "off") + (images + "off.png" + ) + ) ) diff --git a/data/images/objects/candle/off.png b/data/images/objects/candle/off.png new file mode 100644 index 0000000000000000000000000000000000000000..0f86706eaf3013ef1bb72948622ae48bf293ec7e GIT binary patch literal 792 zcmV+z1LypSP)FWFU8GbZ8({Xk{QrNlj4iWF>9@00MkTL_t(o!|jwyXcJKs zhW|S=d39>iw4qJY*oU?u1T^lnC5zw#Vo@3tB%6SgNU0kUHwr;fx@~bKxOXKYx+n$; z;-W32U@^5cVo|5shlvf^iM^R*a%bGTvS~9L^X<>Q-?{gkA862^L4yO})g(x*wfufB zkN8103m}W1pf|qazvcFRin&?~W2eDAN}f8z^CUQNS#$=x@J@`?z72aqp9ePPa8}#pB|af&=jG^(>)A2g`fOac+2I^w_Nv+vO&#_be@EwU@8Ii**;!=RuyN z&|`B9T#Aldun{IBoqmI2`U5BMC>k*X=BekM$?N0e{e+eAb!`>TUd-Zm8N_DhsSyIC zt-b$j*Wo?^+AcP>@_N1?qs49o$H8KR0Naq>KA4<(r~?85zFzHUUl&Bt0h^7p*Ij@N zLA^gpA6HaO1rZ^A+vYirLq*k4sq(Fc|&Ex1+gID>&NlH5iq7>>xWt~Du@Wv zsuThblSRPA^Fx)E);3)!Gu4P3FcU(q&dtqAcalFGm8m}XW=zbu51u&(RNd+MYH zflwlmcp8t#J2g#1u~^inr>99KlflZ$%Bn2OzIwmF>def{XSdtkNhw7xmm`@>2C^(G zrBdmg5i^jZlt#1J>~16yK}SbN)#Y;OJ3BiSRaN7L452K`Zm-vC@%#N)SXdAwNg{$E z*t)yBi6Keoa5xg-a9A*zOb7;ppp?RDwVEiU_YPbj7K{De)kr85iVhAAB9%%(Q51MQ z9=P3ZXqtAD #include "candle.hpp" +#include "scripting/candle.hpp" +#include "scripting/squirrel_util.hpp" +#include "sector.hpp" +#include "object/sprite_particle.hpp" #include "object_factory.hpp" Candle::Candle(const lisp::Lisp& lisp) - : MovingSprite(lisp, "images/objects/candle/candle.sprite", LAYER_BACKGROUNDTILES+1, COLGROUP_DISABLED) + : MovingSprite(lisp, "images/objects/candle/candle.sprite", LAYER_BACKGROUNDTILES+1, COLGROUP_DISABLED), burning(true), name("") { -} + lisp.get("name", name); + lisp.get("burning", burning); -void -Candle::write(lisp::Writer& writer) -{ - writer.start_list("candle"); - writer.write_float("x", bbox.p1.x); - writer.write_float("y", bbox.p1.y); - writer.end_list("candle"); + if (burning) { + sprite->set_action("on"); + } else { + sprite->set_action("off"); + } } HitResponse @@ -42,4 +45,48 @@ Candle::collision(GameObject& , const CollisionHit& ) return FORCE_MOVE; } +void +Candle::expose(HSQUIRRELVM vm, SQInteger table_idx) +{ + if (name == "") return; + Scripting::Candle* interface = new Scripting::Candle(this); + expose_object(vm, table_idx, interface, name, true); +} + +void +Candle::unexpose(HSQUIRRELVM vm, SQInteger table_idx) +{ + if (name == "") return; + Scripting::unexpose_object(vm, table_idx, name); +} + +void +Candle::puff_smoke() +{ + Vector ppos = bbox.get_middle(); + Vector pspeed = Vector(0, -150); + Vector paccel = Vector(0,0); + Sector::current()->add_object(new SpriteParticle("images/objects/particles/smoke.sprite", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_BACKGROUNDTILES+2)); +} + +bool +Candle::get_burning() +{ + return burning; +} + +void +Candle::set_burning(bool burning) +{ + if (this->burning == burning) return; + this->burning = burning; + if (burning) { + sprite->set_action("on"); + puff_smoke(); + } else { + sprite->set_action("off"); + puff_smoke(); + } +} + IMPLEMENT_FACTORY(Candle, "candle"); diff --git a/src/object/candle.hpp b/src/object/candle.hpp index dd5864767..38ea32589 100644 --- a/src/object/candle.hpp +++ b/src/object/candle.hpp @@ -20,23 +20,35 @@ #ifndef __CANDLE_H__ #define __CANDLE_H__ +#include + #include "lisp/lisp.hpp" #include "object/moving_sprite.hpp" -#include "serializable.hpp" +#include "script_interface.hpp" /** - * A burning candle: Simple level decoration. + * A burning candle: Simple, scriptable level decoration. */ -class Candle : public MovingSprite, public Serializable +class Candle : public MovingSprite, public ScriptInterface { public: Candle(const lisp::Lisp& lisp); virtual Candle* clone() const { return new Candle(*this); } - void write(lisp::Writer& writer); HitResponse collision(GameObject& other, const CollisionHit& hit); + virtual void expose(HSQUIRRELVM vm, SQInteger table_idx); + virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx); + + void puff_smoke(); /**< spawn a puff of smoke */ + + bool get_burning(); /**< returns true if candle is lighted */ + void set_burning(bool burning); /**< true: light candle, false: extinguish candle */ + private: + bool burning; /**< true if candle is currently lighted */ + std::string name; /**< user-defined name for use in scripts or empty string if not scriptable */ + }; #endif diff --git a/src/scripting/candle.cpp b/src/scripting/candle.cpp new file mode 100644 index 000000000..1a4d3a655 --- /dev/null +++ b/src/scripting/candle.cpp @@ -0,0 +1,50 @@ +// $Id: candle.cpp 3327 2006-04-13 15:02:40Z ravu_al_hemio $ +// +// SuperTux +// Copyright (C) 2006 Matthias Braun +// +// This program 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 + +#include +#include +#include "object/candle.hpp" +#include "scripting/candle.hpp" +#include "math/vector.hpp" + +#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented." + +namespace Scripting +{ + + Candle::Candle(::Candle* candle) + : candle(candle) + { } + + Candle::~Candle() + { } + + bool Candle::get_burning() + { + return candle->get_burning(); + } + + void Candle::set_burning(bool burning) + { + candle->set_burning(burning); + } + +} diff --git a/src/scripting/candle.hpp b/src/scripting/candle.hpp new file mode 100644 index 000000000..d68f30f64 --- /dev/null +++ b/src/scripting/candle.hpp @@ -0,0 +1,50 @@ +// $Id: candle.hpp 3327 2006-04-13 15:02:40Z ravu_al_hemio $ +// +// SuperTux +// Copyright (C) 2006 Matthias Braun +// +// This program 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. + +#ifndef __SCRIPTING_CANDLE_H__ +#define __SCRIPTING_CANDLE_H__ + +#ifndef SCRIPTING_API +class Candle; +typedef Candle _Candle; +#endif + +namespace Scripting +{ + +class Candle +{ +public: +#ifndef SCRIPTING_API + Candle(_Candle* candle); + ~Candle(); +#endif + + bool get_burning(); /**< returns true if candle is lighted */ + void set_burning(bool burning); /**< true: light candle, false: extinguish candle */ + +#ifndef SCRIPTING_API + _Candle* candle; +#endif +}; + +} + +#endif + diff --git a/src/scripting/wrapper.cpp b/src/scripting/wrapper.cpp index e9a07388f..92e90ef9d 100644 --- a/src/scripting/wrapper.cpp +++ b/src/scripting/wrapper.cpp @@ -1706,6 +1706,67 @@ static SQInteger Platform_stop_moving_wrapper(HSQUIRRELVM vm) } +static SQInteger Candle_release_hook(SQUserPointer ptr, SQInteger ) +{ + Scripting::Candle* _this = reinterpret_cast (ptr); + delete _this; + return 0; +} + +static SQInteger Candle_get_burning_wrapper(HSQUIRRELVM vm) +{ + SQUserPointer data; + if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) { + sq_throwerror(vm, _SC("'get_burning' called without instance")); + return SQ_ERROR; + } + Scripting::Candle* _this = reinterpret_cast (data); + + try { + bool return_value = _this->get_burning(); + + sq_pushbool(vm, return_value); + return 1; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_burning'")); + return SQ_ERROR; + } + +} + +static SQInteger Candle_set_burning_wrapper(HSQUIRRELVM vm) +{ + SQUserPointer data; + if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) { + sq_throwerror(vm, _SC("'set_burning' called without instance")); + return SQ_ERROR; + } + Scripting::Candle* _this = reinterpret_cast (data); + SQBool arg0; + if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) { + sq_throwerror(vm, _SC("Argument 1 not a bool")); + return SQ_ERROR; + } + + try { + _this->set_burning(arg0 == SQTrue); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_burning'")); + return SQ_ERROR; + } + +} + static SQInteger display_wrapper(HSQUIRRELVM vm) { return Scripting::display(vm); @@ -2504,6 +2565,32 @@ void create_squirrel_instance(HSQUIRRELVM v, Scripting::Platform* object, bool s sq_remove(v, -2); // remove root table } +void create_squirrel_instance(HSQUIRRELVM v, Scripting::Candle* object, bool setup_releasehook) +{ + using namespace Wrapper; + + sq_pushroottable(v); + sq_pushstring(v, "Candle", -1); + if(SQ_FAILED(sq_get(v, -2))) { + std::ostringstream msg; + msg << "Couldn't resolved squirrel type 'Candle'"; + throw SquirrelError(v, msg.str()); + } + + if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) { + std::ostringstream msg; + msg << "Couldn't setup squirrel instance for object of type 'Candle'"; + throw SquirrelError(v, msg.str()); + } + sq_remove(v, -2); // remove object name + + if(setup_releasehook) { + sq_setreleasehook(v, -1, Candle_release_hook); + } + + sq_remove(v, -2); // remove root table +} + void register_supertux_wrapper(HSQUIRRELVM v) { using namespace Wrapper; @@ -3172,6 +3259,29 @@ void register_supertux_wrapper(HSQUIRRELVM v) throw SquirrelError(v, "Couldn't register class 'Platform'"); } + // Register class Candle + sq_pushstring(v, "Candle", -1); + if(sq_newclass(v, SQFalse) < 0) { + std::ostringstream msg; + msg << "Couldn't create new class 'Candle'"; + throw SquirrelError(v, msg.str()); + } + sq_pushstring(v, "get_burning", -1); + sq_newclosure(v, &Candle_get_burning_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'get_burning'"); + } + + sq_pushstring(v, "set_burning", -1); + sq_newclosure(v, &Candle_set_burning_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'set_burning'"); + } + + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register class 'Candle'"); + } + } } // end of namespace Scripting diff --git a/src/scripting/wrapper.hpp b/src/scripting/wrapper.hpp index 897ab11a4..706d5d81a 100644 --- a/src/scripting/wrapper.hpp +++ b/src/scripting/wrapper.hpp @@ -22,6 +22,7 @@ void create_squirrel_instance(HSQUIRRELVM v, Scripting::Text* object, bool setup void create_squirrel_instance(HSQUIRRELVM v, Scripting::Player* object, bool setup_releasehook = false); void create_squirrel_instance(HSQUIRRELVM v, Scripting::FloatingImage* object, bool setup_releasehook = false); void create_squirrel_instance(HSQUIRRELVM v, Scripting::Platform* object, bool setup_releasehook = false); +void create_squirrel_instance(HSQUIRRELVM v, Scripting::Candle* object, bool setup_releasehook = false); } diff --git a/src/scripting/wrapper.interface.hpp b/src/scripting/wrapper.interface.hpp index 6f8eae83b..17dd71f0c 100644 --- a/src/scripting/wrapper.interface.hpp +++ b/src/scripting/wrapper.interface.hpp @@ -9,4 +9,5 @@ #include "floating_image.hpp" #include "anchor_points.hpp" #include "platform.hpp" +#include "candle.hpp" -- 2.11.0