From f81231933de4e2f826bd12a1433e1cef9a7fd71b Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Sun, 23 Apr 2006 16:45:45 +0000 Subject: [PATCH] - Worldmap scripts have their own roottable now (like sectors already have) - Make FloatingImage work for worldmaps too - keys are now handled by squirrel scritps SVN-Revision: 3390 --- data/levels/world2/default.nut | 46 ++++++++++++++++++++++++++++++---- data/levels/world2/level1.stl | 1 + data/levels/world2/worldmap.stwm | 1 + data/scripts/default.nut | 6 +++++ src/player_status.cpp | 2 +- src/scripting/floating_image.cpp | 14 +++++++++-- src/sector.cpp | 5 +++- src/worldmap/worldmap.cpp | 53 ++++++++++++++++++++++++++++++++++++++++ src/worldmap/worldmap.hpp | 3 +++ 9 files changed, 122 insertions(+), 9 deletions(-) diff --git a/data/levels/world2/default.nut b/data/levels/world2/default.nut index 091e665b7..f271897fa 100644 --- a/data/levels/world2/default.nut +++ b/data/levels/world2/default.nut @@ -22,30 +22,66 @@ function level2_init() Tux.activate(); } -// Initialize keys +/*************************************** + * Handling of the "keys" in the world * + ***************************************/ if(! ("world2_keys" in state)) state.world2_keys <- {} local keys = state.world2_keys; if(! ("brass" in keys)) keys.brass <- false; +if(! ("iron" in keys)) + keys.iron <- false; +if(! ("bronze" in keys)) + keys.bronze <- false; +if(! ("silver" in keys)) + keys.silver <- false; if(! ("gold" in keys)) keys.gold <- false; +/// this function updates the key images (call this if tux has collected a key) +function update_keys() +{ + local keys = state.world2_keys; + key_brass.set_action(keys.brass ? "display" : "outline"); + key_iron.set_action(keys.iron ? "display" : "outline"); + key_bronze.set_action(keys.bronze ? "display" : "outline"); + key_silver.set_action(keys.silver ? "display" : "outline"); + key_gold.set_action(keys.gold ? "display" : "outline"); +} + local x = 10; local y = 10; key_brass <- FloatingImage("images/objects/keys/key_brass.sprite"); -key_brass.set_anchor_point(ANCHOR_TOPLEFT); +key_brass.set_anchor_point(ANCHOR_TOP_LEFT); key_brass.set_pos(x, y); key_brass.set_visible(true); -key_brass.set_action(keys.brass ? "display" : "outline"); +x += 30; + +key_iron <- FloatingImage("images/objects/keys/key_iron.sprite"); +key_iron.set_anchor_point(ANCHOR_TOP_LEFT); +key_iron.set_pos(x, y); +key_iron.set_visible(true); +x += 30; + +key_bronze <- FloatingImage("images/objects/keys/key_bronze.sprite"); +key_bronze.set_anchor_point(ANCHOR_TOP_LEFT); +key_bronze.set_pos(x, y); +key_bronze.set_visible(true); +x += 30; + +key_silver <- FloatingImage("images/objects/keys/key_silver.sprite"); +key_silver.set_anchor_point(ANCHOR_TOP_LEFT); +key_silver.set_pos(x, y); +key_silver.set_visible(true); x += 30; key_gold <- FloatingImage("images/objects/keys/key_gold.sprite"); -key_gold.set_anchor_point(ANCHOR_TOPLEFT); +key_gold.set_anchor_point(ANCHOR_TOP_LEFT); key_gold.set_pos(x, y); key_gold.set_visible(true); -key_gold.set_action(keys.gold ? "display" : "outline"); x += 30; +update_keys(); diff --git a/data/levels/world2/level1.stl b/data/levels/world2/level1.stl index 327fa2688..676f08056 100644 --- a/data/levels/world2/level1.stl +++ b/data/levels/world2/level1.stl @@ -7,6 +7,7 @@ (name "main") (music "music/forest2.ogg") (gravity 10.000000) + (init-script "import(\"levels/world2/default.nut\");") (tilemap (layer "background") (solid #f) diff --git a/data/levels/world2/worldmap.stwm b/data/levels/world2/worldmap.stwm index bfa22c089..31febb477 100644 --- a/data/levels/world2/worldmap.stwm +++ b/data/levels/world2/worldmap.stwm @@ -5,6 +5,7 @@ (sector (name "main") (music "music/forestmap.ogg") + (init-script "import(\"levels/world2/default.nut\");") (tilemap (width 70) (height 50) diff --git a/data/scripts/default.nut b/data/scripts/default.nut index f3a262e03..981913a69 100644 --- a/data/scripts/default.nut +++ b/data/scripts/default.nut @@ -2,6 +2,9 @@ * This script gets loaded into the squirrel root vm in supertux. So functions * and variables you define here can be used in all threads */ + + +// TODO: move this to world2 function end_level() { Sound.play_music("music/leveldone.ogg"); @@ -26,3 +29,6 @@ function println(val) print("\n"); } +if(! ("state" in this)) + state <- {}; + diff --git a/src/player_status.cpp b/src/player_status.cpp index edd22cee3..24a1b992e 100644 --- a/src/player_status.cpp +++ b/src/player_status.cpp @@ -78,7 +78,7 @@ void PlayerStatus::add_coins(int count) { coins = std::min(coins + count, MAX_COINS); - if(count > 100) + if(count >= 100) sound_manager->play("sounds/lifeup.wav"); else sound_manager->play("sounds/coin.wav"); diff --git a/src/scripting/floating_image.cpp b/src/scripting/floating_image.cpp index 8b09e64f8..5f323c2dc 100644 --- a/src/scripting/floating_image.cpp +++ b/src/scripting/floating_image.cpp @@ -20,18 +20,28 @@ #include #include +#include #include "floating_image.hpp" #include "sector.hpp" #include "object/floating_image.hpp" +#include "worldmap/worldmap.hpp" namespace Scripting { FloatingImage::FloatingImage(const std::string& spritefile) { - assert(Sector::current() != NULL); + using namespace WorldMapNS; + floating_image = new _FloatingImage(spritefile); - Sector::current()->add_object(floating_image); + if(Sector::current() != NULL) { + Sector::current()->add_object(floating_image); + } else if(WorldMap::current() != NULL) { + WorldMap::current()->add_object(floating_image); + } else { + delete floating_image; + throw new std::runtime_error("Neither sector nor worldmap active"); + } } FloatingImage::~FloatingImage() diff --git a/src/sector.cpp b/src/sector.cpp index 3a0e2299d..dc9a699a6 100644 --- a/src/sector.cpp +++ b/src/sector.cpp @@ -84,6 +84,8 @@ Sector::Sector(Level* parent) // create a new squirrel table for the sector using namespace Scripting; + sq_collectgarbage(global_vm); + sq_newtable(global_vm); sq_pushroottable(global_vm); if(SQ_FAILED(sq_setdelegate(global_vm, -2))) @@ -108,6 +110,7 @@ Sector::~Sector() sq_release(global_vm, &object); } sq_release(global_vm, §or_table); + sq_collectgarbage(global_vm); update_game_objects(); assert(gameobjects_new.size() == 0); @@ -485,7 +488,7 @@ Sector::activate(const Vector& player_pos) _current->deactivate(); _current = this; - // register sectortable as current_sector in scripting + // register sectortable as sector in scripting HSQUIRRELVM vm = Scripting::global_vm; sq_pushroottable(vm); sq_pushstring(vm, "sector", -1); diff --git a/src/worldmap/worldmap.cpp b/src/worldmap/worldmap.cpp index 946b21f17..7f841b8f4 100644 --- a/src/worldmap/worldmap.cpp +++ b/src/worldmap/worldmap.cpp @@ -150,6 +150,22 @@ WorldMap::WorldMap(const std::string& filename) worldmap_menu->add_entry(MNID_QUITWORLDMAP, _("Quit World")); load(filename); + + // create a new squirrel table for the worldmap + using namespace Scripting; + + sq_collectgarbage(global_vm); + sq_newtable(global_vm); + sq_pushroottable(global_vm); + if(SQ_FAILED(sq_setdelegate(global_vm, -2))) + throw Scripting::SquirrelError(global_vm, "Couldn't set worldmap_table delegate"); + + sq_resetobject(&worldmap_table); + if(SQ_FAILED(sq_getstackobj(global_vm, -1, &worldmap_table))) + throw Scripting::SquirrelError(global_vm, "Couldn't get table from stack"); + + sq_addref(global_vm, &worldmap_table); + sq_pop(global_vm, 1); } WorldMap::~WorldMap() @@ -161,6 +177,9 @@ WorldMap::~WorldMap() HSQOBJECT& object = *i; sq_release(global_vm, &object); } + sq_release(global_vm, &worldmap_table); + + sq_collectgarbage(global_vm); if(current_ == this) current_ = NULL; @@ -214,6 +233,8 @@ WorldMap::load(const std::string& filename) add_object(new Background(*(iter.lisp()))); } else if(iter.item() == "music") { iter.value()->get(music); + } else if(iter.item() == "init-script") { + iter.value()->get(init_script); } else if(iter.item() == "worldmap-spawnpoint") { SpawnPoint* sp = new SpawnPoint(iter.lisp()); spawn_points.push_back(sp); @@ -643,6 +664,34 @@ WorldMap::setup() current_ = this; load_state(); + + // register worldmap_table as worldmap in scripting + using namespace Scripting; + + sq_pushroottable(global_vm); + sq_pushstring(global_vm, "worldmap", -1); + sq_pushobject(global_vm, worldmap_table); + if(SQ_FAILED(sq_createslot(global_vm, -3))) + throw SquirrelError(global_vm, "Couldn't set worldmap in roottable"); + sq_pop(global_vm, 1); + + if(init_script != "") { + std::istringstream in(init_script); + run_script(in, "WorldMap::init"); + } +} + +void +WorldMap::leave() +{ + // remove worldmap_table from roottable + using namespace Scripting; + + sq_pushroottable(global_vm); + sq_pushstring(global_vm, "worldmap", -1); + if(SQ_FAILED(sq_deleteslot(global_vm, -2, SQFalse))) + throw SquirrelError(global_vm, "Couldn't unset worldmap in roottable"); + sq_pop(global_vm, 1); } static void store_float(HSQUIRRELVM vm, const char* name, float val) @@ -922,6 +971,10 @@ WorldMap::run_script(std::istream& in, const std::string& sourcename) HSQUIRRELVM vm = object_to_vm(object); + // set worldmap_table as roottable for the thread + sq_pushobject(vm, worldmap_table); + sq_setroottable(vm); + compile_and_run(vm, in, sourcename); return vm; diff --git a/src/worldmap/worldmap.hpp b/src/worldmap/worldmap.hpp index 1490b9ce0..75d8f8f9f 100644 --- a/src/worldmap/worldmap.hpp +++ b/src/worldmap/worldmap.hpp @@ -78,6 +78,7 @@ private: std::string name; std::string music; + std::string init_script; typedef std::vector GameObjects; GameObjects game_objects; @@ -105,6 +106,7 @@ private: Statistics total_stats; + HSQOBJECT worldmap_table; typedef std::vector ScriptList; ScriptList scripts; @@ -118,6 +120,7 @@ public: { return current_; } virtual void setup(); + virtual void leave(); /** Update worldmap state */ virtual void update(float delta); -- 2.11.0