set_wakeup_time(time);
suspend();
}
-
Text.set_text(translate(\"The Crazy Nolok Dance\"));
Text.fade_in(2);
TUX.set_animation(\"jump\");
Text.fade_out(1);
wait(1);
NOLOK.set_visible(true);
-PENNY.set_velocity(-200, 200);
tuxjumps <- 2;
while(true) {
wait(0.8);
(speed 0.500000)
)
(spawnpoint (name "main") (x 480) (y 448))
- (yeti (x 2) (y 177))
+ (yeti
+ (x 2)
+ (y 177)
+ (dead-script "
+Sound.play_sound(\"invincible\");
+Text.set_text(\"You made it!\");
+Text.set_font(\"big\");
+Text.fade_in(1.5);
+set_wakeup_time(4);
+suspend();
+Text.fade_out(1);
+set_wakeup_time(1.5);
+suspend();
+Level.finish();
+")
+ )
(particles-snow
)
(yeti_stalactite (x 97) (y 46))
#include <config.h>
#include <float.h>
+#include <sstream>
#include "yeti.h"
#include "object/camera.h"
#include "yeti_stalactite.h"
#include "bouncing_snowball.h"
+#include "scripting/script_interpreter.h"
static const float JUMP_VEL1 = 250;
static const float JUMP_VEL2 = 700;
sound_manager->preload_sound("yeti_gna");
sound_manager->preload_sound("yeti_roar");
hit_points = INITIAL_HITPOINTS;
+ reader.get("dead-script", dead_script);
}
Yeti::~Yeti()
sound_manager->play_sound("yeti_roar");
hit_points--;
if(hit_points <= 0) {
- sprite->set_action("dead");
+ sprite->set_action("dead");
kill_squished(player);
+
+ // start script
+ if(dead_script != "") {
+ try {
+ ScriptInterpreter* interpreter
+ = new ScriptInterpreter(Sector::current());
+ std::istringstream in(dead_script);
+ interpreter->load_script(in, "Yeti - dead-script");
+ interpreter->start_script();
+ Sector::current()->add_object(interpreter);
+ } catch(std::exception& e) {
+ std::cerr << "Couldn't execute yeti dead script: " << e.what() << "\n";
+ }
+ }
} else {
safe_timer.start(SAFE_TIME);
}
Timer safe_timer;
int jumpcount;
int hit_points;
+ std::string dead_script;
};
#endif
}
void
+GameSession::finish()
+{
+ exit_status = ES_LEVEL_FINISHED;
+}
+
+void
GameSession::respawn(const std::string& sector, const std::string& spawnpoint)
{
newsector = sector;
{ current_ = this; }
static GameSession* current() { return current_; }
+ /// ends the level as finished
+ void finish();
void respawn(const std::string& sectorname,
const std::string& spawnpointname);
void set_reset_point(const std::string& sectorname,
#include "math/vector.h"
ScriptedObject::ScriptedObject(const lisp::Lisp& lisp)
- : solid(true), physic_enabled(true), visible(true)
+ : solid(true), physic_enabled(true), visible(true), new_vel_set(false)
{
lisp.get("name", name);
if(name == "")
void
ScriptedObject::set_velocity(float x, float y)
{
- physic.set_velocity(x, y);
+ new_vel = Vector(x, y);
+ new_vel_set = true;
}
float
if(!physic_enabled)
return;
+ if(new_vel_set) {
+ physic.set_velocity(new_vel.x, new_vel.y);
+ new_vel_set = false;
+ }
movement = physic.get_movement(elapsed_time);
}
bool solid;
bool physic_enabled;
bool visible;
+ bool new_vel_set;
+ Vector new_vel;
Physic physic;
Sprite* sprite;
};
void set_wakeup_time(float seconds)
{
- ScriptInterpreter::current()->suspend(seconds);
+ ScriptInterpreter::current()->set_wakeup_time(seconds);
}
std::string translate(const std::string& text)
#include <string>
#include <stdio.h>
#include "level.h"
-
-#define NOIMPL printf("%s not implemented.\n", __PRETTY_FUNCTION__);
+#include "game_session.h"
namespace Scripting
{
void
Level::finish()
{
- NOIMPL;
+ GameSession::current()->finish();
}
void
- Level::spawn(const std::string& , const std::string& )
+ Level::spawn(const std::string& sector, const std::string& spawnpoint)
{
- NOIMPL;
+ GameSession::current()->respawn(sector, spawnpoint);
}
}
#include "wrapper.h"
#include "wrapper_util.h"
+#include "sector.h"
+#include "object/text_object.h"
+#include "object/scripted_object.h"
+#include "scripting/sound.h"
+#include "scripting/scripted_object.h"
static void printfunc(HSQUIRRELVM, const char* str, ...)
{
ScriptInterpreter* ScriptInterpreter::_current = 0;
-ScriptInterpreter::ScriptInterpreter()
+ScriptInterpreter::ScriptInterpreter(Sector* sector)
+ : sound(0), level(0)
{
v = sq_open(1024);
if(v == 0)
// register supertux API
register_functions(v, supertux_global_functions);
register_classes(v, supertux_classes);
+
+ // expose ScriptedObjects to the script
+ for(Sector::GameObjects::iterator i = sector->gameobjects.begin();
+ i != sector->gameobjects.end(); ++i) {
+ GameObject* object = *i;
+ Scripting::ScriptedObject* scripted_object
+ = dynamic_cast<Scripting::ScriptedObject*> (object);
+ if(!scripted_object)
+ continue;
+
+ std::cout << "Exposing " << scripted_object->get_name() << "\n";
+ expose_object(scripted_object, scripted_object->get_name(),
+ "ScriptedObject");
+ }
+ // expose some "global" objects
+ sound = new Scripting::Sound();
+ expose_object(sound, "Sound", "Sound");
+ level = new Scripting::Level();
+ expose_object(level, "Level", "Level");
+ TextObject* text_object = new TextObject();
+ sector->add_object(text_object);
+ Scripting::Text* text = static_cast<Scripting::Text*> (text_object);
+ expose_object(text, "Text", "Text");
}
ScriptInterpreter::~ScriptInterpreter()
{
+ sq_close(v);
+ delete sound;
+ delete level;
}
static SQInteger squirrel_read_char(SQUserPointer file)
}
void
-ScriptInterpreter::run_script()
+ScriptInterpreter::start_script()
{
_current = this;
sq_push(v, -2);
if(sq_call(v, 1, false) < 0)
throw SquirrelError(v, "Couldn't start script");
_current = 0;
+ if(sq_getvmstate(v) != SQ_VMSTATE_SUSPENDED) {
+ printf("script ended...\n");
+ remove_me();
+ }
}
void
}
void
-ScriptInterpreter::suspend(float seconds)
+ScriptInterpreter::set_wakeup_time(float seconds)
{
- resume_timer.start(seconds);
+ wakeup_timer.start(seconds);
}
void
-ScriptInterpreter::update()
+ScriptInterpreter::action(float )
{
- if(resume_timer.check()) {
- _current = this;
- if(sq_wakeupvm(v, false, false) < 0)
- throw SquirrelError(v, "Couldn't resume script");
- _current = 0;
+ if(!wakeup_timer.check())
+ return;
+
+ _current = this;
+ if(sq_wakeupvm(v, false, false) < 0)
+ throw SquirrelError(v, "Couldn't resume script");
+ _current = 0;
+ if(sq_getvmstate(v) != SQ_VMSTATE_SUSPENDED) {
+ printf("script ended...\n");
+ remove_me();
}
}
+
+void
+ScriptInterpreter::draw(DrawingContext& )
+{
+}
#include <squirrel.h>
#include <iostream>
#include "timer.h"
+#include "game_object.h"
+#include "scripting/sound.h"
+#include "scripting/level.h"
-class ScriptInterpreter
+class Sector;
+
+class ScriptInterpreter : public GameObject
{
public:
- ScriptInterpreter();
+ ScriptInterpreter(Sector* sector);
~ScriptInterpreter();
+ void draw(DrawingContext& );
+ void action(float );
+
void load_script(std::istream& in, const std::string& sourcename = "");
- void run_script();
+ void start_script();
void expose_object(void* object, const std::string& name,
const std::string& type);
- void suspend(float seconds);
- void update();
+ void set_wakeup_time(float seconds);
static ScriptInterpreter* current()
{
private:
HSQUIRRELVM v;
static ScriptInterpreter* _current;
- Timer resume_timer;
+ Timer wakeup_timer;
+
+ Scripting::Sound* sound;
+ Scripting::Level* level;
};
#endif
+++ /dev/null
-#include <config.h>
-
-#include <string>
-#include <stdio.h>
-#include "scripted_object.h"
-
-#define NOIMPL printf("%s not implemented.\n", __PRETTY_FUNCTION__)
-
-namespace Scripting
-{
- ScriptedObject::ScriptedObject()
- {}
-
- ScriptedObject::~ScriptedObject()
- {}
-
- void
- ScriptedObject::set_animation(const std::string& )
- {
- NOIMPL;
- }
-
- std::string
- ScriptedObject::get_animation()
- {
- NOIMPL;
- return "";
- }
-
- void
- ScriptedObject::move(float , float )
- {
- NOIMPL;
- }
-
- void
- ScriptedObject::set_pos(float , float )
- {
- NOIMPL;
- }
-
- float
- ScriptedObject::get_pos_x()
- {
- NOIMPL;
- return -1;
- }
-
- float
- ScriptedObject::get_pos_y()
- {
- NOIMPL;
- return -1;
- }
-
- void
- ScriptedObject::set_velocity(float , float )
- {
- NOIMPL;
- }
-
- float
- ScriptedObject::get_velocity_x()
- {
- NOIMPL;
- return -1;
- }
-
- float
- ScriptedObject::get_velocity_y()
- {
- NOIMPL;
- return -1;
- }
-}
{
public:
#ifndef SCRIPTING_API
- ScriptedObject();
- virtual ~ScriptedObject();
+ virtual ~ScriptedObject()
+ {}
#endif
virtual void set_animation(const std::string& animation) = 0;
Sector::Sector()
: gravity(10), player(0), solids(0), camera(0),
- interpreter(0), currentmusic(LEVEL_MUSIC)
+ currentmusic(LEVEL_MUSIC)
{
song_title = "Mortimers_chipdisko.mod";
player = new Player(&player_status);
// Run init script
if(init_script != "") {
try {
- // TODO we should keep the interpreter across sessions (or some variables)
- // so that you can store information across levels/sectors...
- delete interpreter;
- interpreter = 0;
- interpreter = new ScriptInterpreter();
-
- // expose ScriptedObjects to the script
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- GameObject* object = *i;
- Scripting::ScriptedObject* scripted_object
- = dynamic_cast<Scripting::ScriptedObject*> (object);
- if(!scripted_object)
- continue;
-
- std::cout << "Exposing " << scripted_object->get_name() << "\n";
- interpreter->expose_object(scripted_object,
- scripted_object->get_name(),
- "ScriptedObject");
- }
- Scripting::Sound* sound = new Scripting::Sound();
- interpreter->expose_object(sound, "Sound", "Sound");
- TextObject* text_object = new TextObject();
- add_object(text_object);
- Scripting::Text* text = static_cast<Scripting::Text*> (text_object);
- interpreter->expose_object(text, "Text", "Text");
-
+ ScriptInterpreter* interpreter = new ScriptInterpreter(this);
std::string sourcename = std::string("Sector(") + name + ") - init";
std::istringstream in(init_script);
- printf("Load script.\n");
interpreter->load_script(in, sourcename);
- printf("run script.\n");
- interpreter->run_script();
+ interpreter->start_script();
+ add_object(interpreter);
+ init_script = "";
} catch(std::exception& e) {
std::cerr << "Couldn't execute init script: " << e.what() << "\n";
}
void
Sector::action(float elapsed_time)
{
- if(interpreter)
- interpreter->update();
-
player->check_bounds(camera);
#if 0
private:
std::vector<Bullet*> bullets;
- ScriptInterpreter* interpreter;
std::string init_script;
public: // TODO make this private again