From: Matthias Braun Date: Thu, 12 May 2005 15:13:55 +0000 (+0000) Subject: - Added a new script command to display text files X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=8f21eeeae4a09dc90aada92fc5afdc9297bfd0f0;p=supertux.git - Added a new script command to display text files - Refactored ScriptingInterpreter a small bit - Added the possibility to starts scripts for worldmap intro and level extro SVN-Revision: 2475 --- diff --git a/data/levels/world1/de.po b/data/levels/world1/de.po index 91a252b69..9fcf9deaf 100644 --- a/data/levels/world1/de.po +++ b/data/levels/world1/de.po @@ -43,7 +43,7 @@ msgid "" msgstr "" "-Penny ist verschwunden!\n" "\n" -"#Tux und Penny sassen gemtlich beim Picknick\n" +"#Tux und Penny sassen gemütlich beim Picknick\n" "#in den eisigen Ebenen der Antarktis.\n" "#Plötzlich sprang eine dunkle Kreatur hinter\n" "#einem Felsen hervor. Tux sah einen grellen\n" @@ -54,7 +54,7 @@ msgstr "" "#hatte lag jetzt ein Zettel:\n" "\n" "#\"Tux, mein Erzfeind!\n" -"#Ich habe deine Freundinn Penny entfhrt und\n" +"#Ich habe deine Freundinn Penny entführt und\n" "#halte sie in meiner Festung gefangen. Den Weg\n" "#dorthin bewachen meine finsteren Kreaturen!\n" "#Versuche gar nicht erst sie zu retten, du\n" diff --git a/data/levels/world1/worldmap.stwm b/data/levels/world1/worldmap.stwm index 8934bc942..64750865e 100644 --- a/data/levels/world1/worldmap.stwm +++ b/data/levels/world1/worldmap.stwm @@ -2,9 +2,11 @@ (supertux-worldmap (properties (name (_ "Icyisland")) - (intro-filename "intro.txt") (music "salcon.mod") ) + (intro-script " +display_text_file(\"intro.txt\") +") (spawnpoint (name "main") (x 4) @@ -150,7 +152,9 @@ (level (x 7) (y 20) - (extro-filename "extro.txt") + (extro-script " +display_text_file(\"extro.txt\") +") (name "level26.stl") (quit-worldmap #t)) ) diff --git a/src/badguy/yeti.cpp b/src/badguy/yeti.cpp index b0d022cc7..c38c3ac4d 100644 --- a/src/badguy/yeti.cpp +++ b/src/badguy/yeti.cpp @@ -25,6 +25,7 @@ #include "object/camera.h" #include "yeti_stalactite.h" #include "bouncing_snowball.h" +#include "game_session.h" #include "scripting/script_interpreter.h" static const float JUMP_VEL1 = 250; @@ -146,7 +147,8 @@ Yeti::collision_squished(Player& player) if(dead_script != "") { try { ScriptInterpreter* interpreter - = new ScriptInterpreter(Sector::current()); + = new ScriptInterpreter(GameSession::current()->get_working_directory()); + interpreter->register_sector(Sector::current()); std::istringstream in(dead_script); interpreter->load_script(in, "Yeti - dead-script"); interpreter->start_script(); diff --git a/src/game_session.cpp b/src/game_session.cpp index 1402e6457..2ef554d9d 100644 --- a/src/game_session.cpp +++ b/src/game_session.cpp @@ -64,6 +64,7 @@ #include "control/codecontroller.h" #include "control/joystickkeyboardcontroller.h" #include "main.h" +#include "file_system.h" #include "gameconfig.h" #include "gettext.h" @@ -648,6 +649,12 @@ GameSession::set_reset_point(const std::string& sector, const Vector& pos) reset_pos = pos; } +std::string +GameSession::get_working_directory() +{ + return FileSystem::dirname(levelfile); +} + void GameSession::display_info_box(const std::string& text) { diff --git a/src/game_session.h b/src/game_session.h index eb31ed465..59023b36e 100644 --- a/src/game_session.h +++ b/src/game_session.h @@ -89,6 +89,12 @@ public: void start_sequence(const std::string& sequencename); /// called by JoystickKeyboardController after an ascii key has been pressed void try_cheats(); + + /** returns the "working directory" usually this is the directory where the + * currently played level resides. This is used when locating additional + * resources for the current level/world + */ + std::string get_working_directory(); private: void restart_level(); diff --git a/src/scripting/functions.cpp b/src/scripting/functions.cpp index 5b24c9249..a3c211a12 100644 --- a/src/scripting/functions.cpp +++ b/src/scripting/functions.cpp @@ -1,9 +1,11 @@ #include #include #include +#include "textscroller.h" #include "functions.h" #include "script_interpreter.h" #include "tinygettext/tinygettext.h" +#include "resources.h" #include "gettext.h" namespace Scripting @@ -19,5 +21,12 @@ std::string translate(const std::string& text) return dictionary_manager.get_dictionary().translate(text); } +void display_text_file(const std::string& filename) +{ + std::string file + = ScriptInterpreter::current()->get_working_directory() + filename; + ::display_text_file(file); +} + } diff --git a/src/scripting/functions.h b/src/scripting/functions.h index f7c8f5c39..2f4d6c801 100644 --- a/src/scripting/functions.h +++ b/src/scripting/functions.h @@ -4,6 +4,8 @@ namespace Scripting { +/** displays a text file and scrolls it over the screen */ +void display_text_file(const std::string& filename); /** Suspends the script execution for the specified number of seconds */ void set_wakeup_time(float seconds); /** translates a give text into the users language (by looking it up in the .po diff --git a/src/scripting/script_interpreter.cpp b/src/scripting/script_interpreter.cpp index 095c6afca..13e9494a0 100644 --- a/src/scripting/script_interpreter.cpp +++ b/src/scripting/script_interpreter.cpp @@ -15,6 +15,8 @@ #include "wrapper.h" #include "wrapper_util.h" #include "sector.h" +#include "file_system.h" +#include "game_session.h" #include "object/text_object.h" #include "object/scripted_object.h" #include "object/display_effect.h" @@ -32,8 +34,8 @@ static void printfunc(HSQUIRRELVM, const char* str, ...) ScriptInterpreter* ScriptInterpreter::_current = 0; -ScriptInterpreter::ScriptInterpreter(Sector* sector) - : sound(0), level(0) +ScriptInterpreter::ScriptInterpreter(const std::string& new_working_directory) + : working_directory(new_working_directory), sound(0), level(0) { v = sq_open(1024); if(v == 0) @@ -59,8 +61,19 @@ ScriptInterpreter::ScriptInterpreter(Sector* sector) // register supertux API register_functions(v, supertux_global_functions); - register_classes(v, supertux_classes); + register_classes(v, supertux_classes); + // expose some "global" objects + sound = new Scripting::Sound(); + expose_object(sound, "Sound", "Sound"); + + level = new Scripting::Level(); + expose_object(level, "Level", "Level"); +} + +void +ScriptInterpreter::register_sector(Sector* sector) +{ // expose ScriptedObjects to the script for(Sector::GameObjects::iterator i = sector->gameobjects.begin(); i != sector->gameobjects.end(); ++i) { @@ -73,12 +86,6 @@ ScriptInterpreter::ScriptInterpreter(Sector* sector) 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); diff --git a/src/scripting/script_interpreter.h b/src/scripting/script_interpreter.h index df0003283..c4ecabc31 100644 --- a/src/scripting/script_interpreter.h +++ b/src/scripting/script_interpreter.h @@ -13,9 +13,11 @@ class Sector; class ScriptInterpreter : public GameObject { public: - ScriptInterpreter(Sector* sector); + ScriptInterpreter(const std::string& working_dir); ~ScriptInterpreter(); + void register_sector(Sector* sector); + void draw(DrawingContext& ); void update(float ); @@ -32,11 +34,18 @@ public: return _current; } + const std::string& get_working_directory() const + { + return working_directory; + } + private: HSQUIRRELVM v; static ScriptInterpreter* _current; Timer wakeup_timer; + /// this directory is used as base for all filenames used in scripts + std::string working_directory; Scripting::Sound* sound; Scripting::Level* level; }; diff --git a/src/scripting/wrapper.cpp b/src/scripting/wrapper.cpp index dbde0eccd..f675e996c 100644 --- a/src/scripting/wrapper.cpp +++ b/src/scripting/wrapper.cpp @@ -354,6 +354,16 @@ static int Text_set_visible_wrapper(HSQUIRRELVM v) return 0; } +static int display_text_file_wrapper(HSQUIRRELVM v) +{ + const char* arg0; + sq_getstring(v, 2, &arg0); + + Scripting::display_text_file(arg0); + + return 0; +} + static int set_wakeup_time_wrapper(HSQUIRRELVM v) { float arg0; @@ -376,6 +386,7 @@ static int translate_wrapper(HSQUIRRELVM v) } WrappedFunction supertux_global_functions[] = { + { "display_text_file", &display_text_file_wrapper }, { "set_wakeup_time", &set_wakeup_time_wrapper }, { "translate", &translate_wrapper }, { 0, 0 } diff --git a/src/sector.cpp b/src/sector.cpp index 11957a4b9..8a53d0514 100644 --- a/src/sector.cpp +++ b/src/sector.cpp @@ -418,7 +418,9 @@ Sector::activate(const std::string& spawnpoint) // Run init script if(init_script != "") { try { - ScriptInterpreter* interpreter = new ScriptInterpreter(this); + ScriptInterpreter* interpreter + = new ScriptInterpreter(GameSession::current()->get_working_directory()); + interpreter->register_sector(this); std::string sourcename = std::string("Sector(") + name + ") - init"; std::istringstream in(init_script); interpreter->load_script(in, sourcename); diff --git a/src/trigger/scripttrigger.cpp b/src/trigger/scripttrigger.cpp index 7a7c27a53..1e576cc81 100644 --- a/src/trigger/scripttrigger.cpp +++ b/src/trigger/scripttrigger.cpp @@ -85,7 +85,9 @@ ScriptTrigger::event(Player& , EventType type) { try { - ScriptInterpreter* interpreter = new ScriptInterpreter(Sector::current()); + ScriptInterpreter* interpreter + = new ScriptInterpreter(GameSession::current()->get_working_directory()); + interpreter->register_sector(Sector::current()); std::istringstream in(script); interpreter->load_script(in, "trigger-script"); interpreter->start_script(); diff --git a/src/worldmap.cpp b/src/worldmap.cpp index e193b0f81..872c2859a 100644 --- a/src/worldmap.cpp +++ b/src/worldmap.cpp @@ -51,6 +51,7 @@ #include "control/joystickkeyboardcontroller.h" #include "object/background.h" #include "object/tilemap.h" +#include "scripting/script_interpreter.h" Menu* worldmap_menu = 0; @@ -432,7 +433,8 @@ WorldMap::load_map() const lisp::Lisp* props = iter.lisp(); props->get("name", name); props->get("music", music); - props->get("intro-filename", intro_filename); + } else if(iter.item() == "intro-script") { + iter.value()->get(intro_script); } else if(iter.item() == "spawnpoint") { SpawnPoint* sp = new SpawnPoint(iter.lisp()); spawn_points.push_back(sp); @@ -519,7 +521,7 @@ WorldMap::parse_level_tile(const lisp::Lisp* level_lisp) level.south = true; level.west = true; - level_lisp->get("extro-filename", level.extro_filename); + level_lisp->get("extro-script", level.extro_script); level_lisp->get("next-worldmap", level.next_worldmap); level.quit_worldmap = false; @@ -840,10 +842,12 @@ WorldMap::update(float delta) /* The porpose of the next checking is that if the player lost the level (in case there is one), don't show anything */ if(level_finished) { - if (!level->extro_filename.empty()) { - // Display a text file - std::string filename = levels_path + level->extro_filename; - display_text_file(filename); + if (level->extro_script != "") { + ScriptInterpreter* interpreter = new ScriptInterpreter(levels_path); + std::istringstream in(level->extro_script); + interpreter->load_script(in, "level-extro-script"); + interpreter->start_script(); + add_object(interpreter); } if (!level->next_worldmap.empty()) @@ -986,9 +990,13 @@ WorldMap::display() song = sound_manager->load_music(datadir + "/music/" + music); sound_manager->play_music(song); - if(!intro_displayed && intro_filename != "") { - std::string filename = levels_path + intro_filename; - display_text_file(filename); + if(!intro_displayed && intro_script != "") { + ScriptInterpreter* interpreter = new ScriptInterpreter(levels_path); + std::istringstream in(intro_script); + interpreter->load_script(in, "worldmap-intro-script"); + interpreter->start_script(); + add_object(interpreter); + intro_displayed = true; } diff --git a/src/worldmap.h b/src/worldmap.h index 0894d28d2..fa71bbce3 100644 --- a/src/worldmap.h +++ b/src/worldmap.h @@ -158,9 +158,8 @@ public: /** Check if this level should be vertically flipped */ bool vertical_flip; - /** Filename of the extro text to show once the level is - successfully completed */ - std::string extro_filename; + /** Script that is run when the level is successfully finished */ + std::string extro_script; /** Go to this world */ std::string next_worldmap; @@ -198,7 +197,7 @@ private: Vector offset; std::string savegame_file; - std::string intro_filename; + std::string intro_script; bool intro_displayed; void get_level_title(Level& level);