From: Christoph Sommer Date: Tue, 27 Jun 2006 22:25:37 +0000 (+0000) Subject: Made Wind scriptable X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=d0e404874455994e6276d23d76fb9f1ea6d06094;p=supertux.git Made Wind scriptable SVN-Revision: 3790 --- diff --git a/data/levels/test/wind.stl b/data/levels/test/wind.stl index 6c84a98c2..8f7d234f5 100644 --- a/data/levels/test/wind.stl +++ b/data/levels/test/wind.stl @@ -5,8 +5,6 @@ (sector (name "main") (background - (x 0) - (y 0) (speed 0.5) (image "images/background/arctis.jpg") ) @@ -42,7 +40,18 @@ (x 668.0976) (y 833.941) ) + (switch + (script "pipeair1.start(); +wait(3); +pipeair1.stop(); +") + (x 907) + (y 858) + (sprite "images/objects/switch/left.sprite") + ) (wind + (name "pipeair1") + (blowing #f) (speed-x 0) (speed-y -600) (acceleration 3) diff --git a/src/object/wind.cpp b/src/object/wind.cpp index 60669aa6d..fff0b793e 100644 --- a/src/object/wind.cpp +++ b/src/object/wind.cpp @@ -26,8 +26,10 @@ #include "random_generator.hpp" #include "sector.hpp" #include "particles.hpp" +#include "scripting/wind.hpp" +#include "scripting/squirrel_util.hpp" -Wind::Wind(const lisp::Lisp& reader) : acceleration(100), elapsed_time(0) +Wind::Wind(const lisp::Lisp& reader) : name(""), blowing(true), acceleration(100), elapsed_time(0) { reader.get("x", bbox.p1.x); reader.get("y", bbox.p1.y); @@ -36,6 +38,9 @@ Wind::Wind(const lisp::Lisp& reader) : acceleration(100), elapsed_time(0) reader.get("height", h); bbox.set_size(w, h); + reader.get("name", name); + reader.get("blowing", blowing); + float speed_x = 0, speed_y = 0; reader.get("speed-x", speed_x); reader.get("speed-y", speed_y); @@ -50,6 +55,9 @@ void Wind::update(float elapsed_time) { this->elapsed_time = elapsed_time; + + if (!blowing) return; + // TODO: nicer, configurable particles for wind? if (systemRandom.rand(0, 100) < 20) { // emit a particle @@ -67,6 +75,8 @@ Wind::draw(DrawingContext& ) HitResponse Wind::collision(GameObject& other, const CollisionHit& ) { + if (!blowing) return ABORT_MOVE; + Player* player = dynamic_cast (&other); if (player) { if (!player->on_ground()) { @@ -77,4 +87,31 @@ Wind::collision(GameObject& other, const CollisionHit& ) return ABORT_MOVE; } +void +Wind::expose(HSQUIRRELVM vm, SQInteger table_idx) +{ + if (name == "") return; + Scripting::Wind* interface = new Scripting::Wind(this); + expose_object(vm, table_idx, interface, name, true); +} + +void +Wind::unexpose(HSQUIRRELVM vm, SQInteger table_idx) +{ + if (name == "") return; + Scripting::unexpose_object(vm, table_idx, name); +} + +void +Wind::start() +{ + blowing = true; +} + +void +Wind::stop() +{ + blowing = false; +} + IMPLEMENT_FACTORY(Wind, "wind"); diff --git a/src/object/wind.hpp b/src/object/wind.hpp index 39e5fd594..2da07d968 100644 --- a/src/object/wind.hpp +++ b/src/object/wind.hpp @@ -24,13 +24,14 @@ #include "moving_object.hpp" #include "math/rect.hpp" #include "sprite/sprite.hpp" +#include "script_interface.hpp" class Player; /** * Defines an area that will gently push Players in one direction */ -class Wind : public MovingObject +class Wind : public MovingObject, public ScriptInterface { public: Wind(const lisp::Lisp& reader); @@ -39,7 +40,23 @@ public: void draw(DrawingContext& context); HitResponse collision(GameObject& other, const CollisionHit& hit); + /** + * start blowing + */ + void start(); + + /** + * stop blowing + */ + void stop(); + + virtual void expose(HSQUIRRELVM vm, SQInteger table_idx); + virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx); + private: + std::string name; /**< user-defined name for use in scripts or empty string if not scriptable */ + + bool blowing; /**< true if wind is currently switched on */ Vector speed; float acceleration; diff --git a/src/scripting/wind.cpp b/src/scripting/wind.cpp new file mode 100644 index 000000000..6140108d6 --- /dev/null +++ b/src/scripting/wind.cpp @@ -0,0 +1,50 @@ +// $Id: wind.cpp 3719 2006-06-24 13:27:29Z anmaster $ +// +// 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/wind.hpp" +#include "scripting/wind.hpp" +#include "math/vector.hpp" + +#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented." + +namespace Scripting +{ + + Wind::Wind(::Wind* wind) + : wind(wind) + { } + + Wind::~Wind() + { } + + void Wind::start() + { + wind->start(); + } + + void Wind::stop() + { + wind->stop(); + } + +} diff --git a/src/scripting/wind.hpp b/src/scripting/wind.hpp new file mode 100644 index 000000000..0ad749401 --- /dev/null +++ b/src/scripting/wind.hpp @@ -0,0 +1,53 @@ +// $Id: wind.hpp 3719 2006-06-24 13:27:29Z anmaster $ +// +// 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_WIND_H__ +#define __SCRIPTING_WIND_H__ + +#ifndef SCRIPTING_API +class Wind; +typedef Wind _Wind; +#endif + +namespace Scripting +{ + +class Wind +{ +public: +#ifndef SCRIPTING_API + Wind(_Wind* wind); + ~Wind(); +#endif + + /** Start wind */ + void start(); + + /** Stop wind */ + void stop(); + +#ifndef SCRIPTING_API + _Wind* wind; +#endif +}; + +} + +#endif + diff --git a/src/scripting/wrapper.cpp b/src/scripting/wrapper.cpp index 92e90ef9d..561a6110f 100644 --- a/src/scripting/wrapper.cpp +++ b/src/scripting/wrapper.cpp @@ -1767,6 +1767,61 @@ static SQInteger Candle_set_burning_wrapper(HSQUIRRELVM vm) } +static SQInteger Wind_release_hook(SQUserPointer ptr, SQInteger ) +{ + Scripting::Wind* _this = reinterpret_cast (ptr); + delete _this; + return 0; +} + +static SQInteger Wind_start_wrapper(HSQUIRRELVM vm) +{ + SQUserPointer data; + if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) { + sq_throwerror(vm, _SC("'start' called without instance")); + return SQ_ERROR; + } + Scripting::Wind* _this = reinterpret_cast (data); + + try { + _this->start(); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'start'")); + return SQ_ERROR; + } + +} + +static SQInteger Wind_stop_wrapper(HSQUIRRELVM vm) +{ + SQUserPointer data; + if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) { + sq_throwerror(vm, _SC("'stop' called without instance")); + return SQ_ERROR; + } + Scripting::Wind* _this = reinterpret_cast (data); + + try { + _this->stop(); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop'")); + return SQ_ERROR; + } + +} + static SQInteger display_wrapper(HSQUIRRELVM vm) { return Scripting::display(vm); @@ -2591,6 +2646,32 @@ void create_squirrel_instance(HSQUIRRELVM v, Scripting::Candle* object, bool set sq_remove(v, -2); // remove root table } +void create_squirrel_instance(HSQUIRRELVM v, Scripting::Wind* object, bool setup_releasehook) +{ + using namespace Wrapper; + + sq_pushroottable(v); + sq_pushstring(v, "Wind", -1); + if(SQ_FAILED(sq_get(v, -2))) { + std::ostringstream msg; + msg << "Couldn't resolved squirrel type 'Wind'"; + 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 'Wind'"; + throw SquirrelError(v, msg.str()); + } + sq_remove(v, -2); // remove object name + + if(setup_releasehook) { + sq_setreleasehook(v, -1, Wind_release_hook); + } + + sq_remove(v, -2); // remove root table +} + void register_supertux_wrapper(HSQUIRRELVM v) { using namespace Wrapper; @@ -3282,6 +3363,29 @@ void register_supertux_wrapper(HSQUIRRELVM v) throw SquirrelError(v, "Couldn't register class 'Candle'"); } + // Register class Wind + sq_pushstring(v, "Wind", -1); + if(sq_newclass(v, SQFalse) < 0) { + std::ostringstream msg; + msg << "Couldn't create new class 'Wind'"; + throw SquirrelError(v, msg.str()); + } + sq_pushstring(v, "start", -1); + sq_newclosure(v, &Wind_start_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'start'"); + } + + sq_pushstring(v, "stop", -1); + sq_newclosure(v, &Wind_stop_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'stop'"); + } + + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register class 'Wind'"); + } + } } // end of namespace Scripting diff --git a/src/scripting/wrapper.hpp b/src/scripting/wrapper.hpp index 706d5d81a..4d0af7c34 100644 --- a/src/scripting/wrapper.hpp +++ b/src/scripting/wrapper.hpp @@ -23,6 +23,7 @@ void create_squirrel_instance(HSQUIRRELVM v, Scripting::Player* object, bool set 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); +void create_squirrel_instance(HSQUIRRELVM v, Scripting::Wind* object, bool setup_releasehook = false); } diff --git a/src/scripting/wrapper.interface.hpp b/src/scripting/wrapper.interface.hpp index 17dd71f0c..51c4c86e0 100644 --- a/src/scripting/wrapper.interface.hpp +++ b/src/scripting/wrapper.interface.hpp @@ -10,4 +10,5 @@ #include "anchor_points.hpp" #include "platform.hpp" #include "candle.hpp" +#include "wind.hpp"