Made Wind scriptable
authorChristoph Sommer <mail@christoph-sommer.de>
Tue, 27 Jun 2006 22:25:37 +0000 (22:25 +0000)
committerChristoph Sommer <mail@christoph-sommer.de>
Tue, 27 Jun 2006 22:25:37 +0000 (22:25 +0000)
SVN-Revision: 3790

data/levels/test/wind.stl
src/object/wind.cpp
src/object/wind.hpp
src/scripting/wind.cpp [new file with mode: 0644]
src/scripting/wind.hpp [new file with mode: 0644]
src/scripting/wrapper.cpp
src/scripting/wrapper.hpp
src/scripting/wrapper.interface.hpp

index 6c84a98..8f7d234 100644 (file)
@@ -5,8 +5,6 @@
   (sector
     (name "main")
     (background
-      (x 0)
-      (y 0)
       (speed 0.5)
       (image "images/background/arctis.jpg")
     )
       (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)
index 60669aa..fff0b79 100644 (file)
 #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<Player*> (&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");
index 39e5fd5..2da07d9 100644 (file)
 #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 (file)
index 0000000..6140108
--- /dev/null
@@ -0,0 +1,50 @@
+//  $Id: wind.cpp 3719 2006-06-24 13:27:29Z anmaster $
+//
+//  SuperTux
+//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+//  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 <config.h>
+
+#include <string>
+#include <stdio.h>
+#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 (file)
index 0000000..0ad7494
--- /dev/null
@@ -0,0 +1,53 @@
+//  $Id: wind.hpp 3719 2006-06-24 13:27:29Z anmaster $
+//
+//  SuperTux
+//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+//  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
+
index 92e90ef..561a611 100644 (file)
@@ -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<Scripting::Wind*> (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<Scripting::Wind*> (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<Scripting::Wind*> (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
index 706d5d8..4d0af7c 100644 (file)
@@ -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);
 
 }
 
index 17dd71f..51c4c86 100644 (file)
@@ -10,4 +10,5 @@
 #include "anchor_points.hpp"
 #include "platform.hpp"
 #include "candle.hpp"
+#include "wind.hpp"