#include "badguy/jumpy.hpp"
#include "trigger/sequence_trigger.hpp"
#include "player_status.hpp"
-#include "scripting/script_interpreter.hpp"
-#include "scripting/sound.hpp"
-#include "scripting/scripted_object.hpp"
-#include "scripting/text.hpp"
+#include "script_manager.hpp"
+#include "scripting/wrapper_util.hpp"
+#include "script_interface.hpp"
#include "msg.hpp"
Sector* Sector::_current = 0;
Sector::Sector()
- : gravity(10), player(0), solids(0), camera(0),
- currentmusic(LEVEL_MUSIC)
+ : currentmusic(LEVEL_MUSIC), gravity(10),
+ player(0), solids(0), camera(0)
{
- player = new Player(player_status);
- add_object(player);
+ add_object(new Player(player_status));
+ add_object(new DisplayEffect());
+ add_object(new TextObject());
#ifdef USE_GRID
- grid = new CollisionGrid(32000, 32000);
-#else
- grid = 0;
+ grid.reset(new CollisionGrid(32000, 32000));
#endif
+
+ script_manager.reset(new ScriptManager(ScriptManager::instance));
+
+ // create a new squirrel table for the sector
+ HSQUIRRELVM vm = ScriptManager::instance->get_vm();
+
+ sq_newtable(vm);
+ sq_pushroottable(vm);
+ if(SQ_FAILED(sq_setdelegate(vm, -2)))
+ throw Scripting::SquirrelError(vm, "Couldn't set sector_table delegate");
+
+ sq_resetobject(§or_table);
+ if(SQ_FAILED(sq_getstackobj(vm, -1, §or_table)))
+ throw Scripting::SquirrelError(vm, "Couldn't get sector table");
+ sq_addref(vm, §or_table);
+ sq_pop(vm, 1);
}
Sector::~Sector()
{
+ deactivate();
+
+ script_manager.reset(NULL);
+ sq_release(ScriptManager::instance->get_vm(), §or_table);
+
update_game_objects();
assert(gameobjects_new.size() == 0);
- delete grid;
-
for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end();
++i) {
+ before_object_remove(*i);
delete *i;
}
for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end();
++i)
delete *i;
-
- if(_current == this)
- _current = 0;
}
GameObject*
void
Sector::parse(const lisp::Lisp& sector)
-{
- _current = this;
-
+{
lisp::ListIterator iter(§or);
while(iter.next()) {
const std::string& token = iter.item();
void
Sector::parse_old_format(const lisp::Lisp& reader)
{
- _current = this;
-
name = "main";
reader.get("gravity", gravity);
}
}
+HSQUIRRELVM
+Sector::run_script(std::istream& in, const std::string& sourcename)
+{
+ // create new thread and keep a weakref
+ HSQUIRRELVM vm = script_manager->create_thread();
+
+ // set sector_table as roottable for the thread
+ sq_pushobject(vm, sector_table);
+ sq_setroottable(vm);
+
+ Scripting::compile_and_run(vm, in, sourcename);
+
+ return vm;
+}
+
void
Sector::add_object(GameObject* object)
{
} else {
activate(sp->pos);
}
+}
+
+void
+Sector::activate(const Vector& player_pos)
+{
+ if(_current != this) {
+ if(_current != NULL)
+ _current->deactivate();
+ _current = this;
+
+ // register sectortable as current_sector in scripting
+ HSQUIRRELVM vm = ScriptManager::instance->get_vm();
+ sq_pushroottable(vm);
+ sq_pushstring(vm, "sector", -1);
+ sq_pushobject(vm, sector_table);
+ if(SQ_FAILED(sq_createslot(vm, -3)))
+ throw Scripting::SquirrelError(vm, "Couldn't set sector in roottable");
+ sq_pop(vm, 1);
+
+ for(GameObjects::iterator i = gameobjects.begin();
+ i != gameobjects.end(); ++i) {
+ GameObject* object = *i;
+
+ try_expose(object);
+ }
+ }
+
+ player->move(player_pos);
+ camera->reset(player->get_pos());
// Run init script
if(init_script != "") {
- ScriptInterpreter::add_script_object(this,
- std::string("Sector(") + name + ") - init", init_script);
+ std::istringstream in(init_script);
+ run_script(in, std::string("Sector(") + name + ") - init");
}
}
void
-Sector::activate(const Vector& player_pos)
+Sector::deactivate()
{
- _current = this;
+ if(_current != this)
+ return;
+
+ // remove sector entry from global vm
+ HSQUIRRELVM vm = ScriptManager::instance->get_vm();
+ sq_pushroottable(vm);
+ sq_pushstring(vm, "sector", -1);
+ if(SQ_FAILED(sq_deleteslot(vm, -2, SQFalse)))
+ throw Scripting::SquirrelError(vm, "Couldn't unset sector in roottable");
+ sq_pop(vm, 1);
+
+ for(GameObjects::iterator i = gameobjects.begin();
+ i != gameobjects.end(); ++i) {
+ GameObject* object = *i;
+
+ try_unexpose(object);
+ }
- player->move(player_pos);
- camera->reset(player->get_pos());
+ _current = NULL;
}
Rect
void
Sector::update(float elapsed_time)
{
+ script_manager->update();
+
player->check_bounds(camera);
#if 0
++i;
continue;
}
+
+ before_object_remove(object);
delete *i;
i = gameobjects.erase(i);
i != gameobjects_new.end(); ++i)
{
GameObject* object = *i;
+
+ before_object_add(object);
- Bullet* bullet = dynamic_cast<Bullet*> (object);
- if(bullet)
- bullets.push_back(bullet);
-
- MovingObject* movingobject = dynamic_cast<MovingObject*> (object);
- if(movingobject) {
- moving_objects.push_back(movingobject);
- #ifdef USE_GRID
- grid->add_object(movingobject);
+ gameobjects.push_back(object);
+ }
+ gameobjects_new.clear();
+}
+
+bool
+Sector::before_object_add(GameObject* object)
+{
+ Bullet* bullet = dynamic_cast<Bullet*> (object);
+ if(bullet)
+ bullets.push_back(bullet);
+
+ MovingObject* movingobject = dynamic_cast<MovingObject*> (object);
+ if(movingobject) {
+ moving_objects.push_back(movingobject);
+#ifdef USE_GRID
+ grid->add_object(movingobject);
#endif
+ }
+
+ TileMap* tilemap = dynamic_cast<TileMap*> (object);
+ if(tilemap && tilemap->is_solid()) {
+ if(solids == 0) {
+ solids = tilemap;
+ } else {
+ msg_warning << "Another solid tilemaps added. Ignoring" << std::endl;
}
-
- TileMap* tilemap = dynamic_cast<TileMap*> (object);
- if(tilemap && tilemap->is_solid()) {
- if(solids == 0) {
- solids = tilemap;
- } else {
- msg_warning << "Another solid tilemaps added. Ignoring" << std::endl;
- }
+ }
+
+ Camera* camera = dynamic_cast<Camera*> (object);
+ if(camera) {
+ if(this->camera != 0) {
+ msg_warning << "Multiple cameras added. Ignoring" << std::endl;
+ return false;
}
+ this->camera = camera;
+ }
- Camera* camera = dynamic_cast<Camera*> (object);
- if(camera) {
- if(this->camera != 0) {
- msg_warning << "Multiple cameras added. Ignoring" << std::endl;
- continue;
- }
- this->camera = camera;
+ Player* player = dynamic_cast<Player*> (object);
+ if(player) {
+ if(this->player != 0) {
+ msg_warning << "Multiple players added. Ignoring" << std::endl;
+ return false;
}
+ this->player = player;
+ }
- gameobjects.push_back(object);
+ if(_current == this) {
+ try_expose(object);
}
- gameobjects_new.clear();
+
+ return true;
+}
+
+void
+Sector::try_expose(GameObject* object)
+{
+ ScriptInterface* interface = dynamic_cast<ScriptInterface*> (object);
+ if(interface != NULL) {
+ HSQUIRRELVM vm = script_manager->get_vm();
+ sq_pushobject(vm, sector_table);
+ interface->expose(vm, -1);
+ sq_pop(vm, 1);
+ }
+}
+
+void
+Sector::before_object_remove(GameObject* object)
+{
+ if(_current == this)
+ try_unexpose(object);
}
void
+Sector::try_unexpose(GameObject* object)
+{
+ ScriptInterface* interface = dynamic_cast<ScriptInterface*> (object);
+ if(interface != NULL) {
+ HSQUIRRELVM vm = script_manager->get_vm();
+ sq_pushobject(vm, sector_table);
+ interface->unexpose(vm, -1);
+ sq_pop(vm, 1);
+ }
+}
+
+void
Sector::draw(DrawingContext& context)
{
context.push_transform();