From: Christoph Sommer Date: Thu, 27 Dec 2007 02:49:12 +0000 (+0000) Subject: Added special "edit" mode to GameSession and Player to playtest levels. X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=3364223e2ff9e7c4ea784ea065d5c53e223e51c8;p=supertux.git Added special "edit" mode to GameSession and Player to playtest levels. In "edit" mode, Tux will not die and sequences will not play, but Tux will become a ghost instead. SVN-Revision: 5239 --- diff --git a/data/scripts/console.nut b/data/scripts/console.nut index cdb190eb0..dc4e05daa 100644 --- a/data/scripts/console.nut +++ b/data/scripts/console.nut @@ -14,6 +14,16 @@ function finish() Level.finish(true); } +function edit() +{ + Level.edit(true); +} + +function play() +{ + Level.edit(false); +} + function worldmapfinish() { save_state(); diff --git a/src/game_session.cpp b/src/game_session.cpp index 8fe62b5ed..ee036eb18 100644 --- a/src/game_session.cpp +++ b/src/game_session.cpp @@ -92,7 +92,7 @@ GameSession::GameSession(const std::string& levelfile_, Statistics* statistics) end_sequence(0), levelfile(levelfile_), best_level_statistics(statistics), capture_demo_stream(0), playback_demo_stream(0), demo_controller(0), - play_time(0) + play_time(0), edit_mode(false) { current_ = this; currentsector = NULL; @@ -116,6 +116,12 @@ GameSession::GameSession(const std::string& levelfile_, Statistics* statistics) void GameSession::restart_level() { + + if (edit_mode) { + force_ghost_mode(); + return; + } + game_pause = false; end_sequence = 0; @@ -311,6 +317,32 @@ GameSession::toggle_pause() } } +void +GameSession::set_editmode(bool edit_mode) +{ + if (this->edit_mode == edit_mode) return; + this->edit_mode = edit_mode; + + currentsector->get_players()[0]->set_edit_mode(edit_mode); + + if (edit_mode) { + + // entering edit mode + + } else { + + // leaving edit mode + restart_level(); + + } +} + +void +GameSession::force_ghost_mode() +{ + currentsector->get_players()[0]->set_ghost_mode(true); +} + HSQUIRRELVM GameSession::run_script(std::istream& in, const std::string& sourcename) { @@ -518,6 +550,11 @@ GameSession::finish(bool win) { using namespace WorldMapNS; + if (edit_mode) { + force_ghost_mode(); + return; + } + if(win) { if(WorldMap::current()) WorldMap::current()->finished_level(level.get()); @@ -549,6 +586,12 @@ GameSession::get_working_directory() void GameSession::start_sequence(const std::string& sequencename) { + // do not play sequences when in edit mode + if (edit_mode) { + force_ghost_mode(); + return; + } + // handle special "stoptux" sequence if (sequencename == "stoptux") { if (!end_sequence) { diff --git a/src/game_session.hpp b/src/game_session.hpp index 54d0ddedd..edae3a632 100644 --- a/src/game_session.hpp +++ b/src/game_session.hpp @@ -84,6 +84,16 @@ public: void toggle_pause(); + /** + * Enters or leaves level editor mode + */ + void set_editmode(bool edit_mode = true); + + /** + * Forces all Players to enter ghost mode + */ + void force_ghost_mode(); + private: void check_end_conditions(); void process_events(); @@ -136,6 +146,8 @@ private: std::auto_ptr game_menu; float play_time; /**< total time in seconds that this session ran interactively */ + + bool edit_mode; /**< true if GameSession runs in level editor mode */ }; #endif /*SUPERTUX_GAMELOOP_H*/ diff --git a/src/object/player.cpp b/src/object/player.cpp index d82bed27d..dc484c529 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -130,7 +130,7 @@ Player::Player(PlayerStatus* _player_status, const std::string& name) : scripting_controller(0), player_status(_player_status), scripting_controller_old(0), - grabbed_object(NULL), ghost_mode(false), climbing(0) + grabbed_object(NULL), ghost_mode(false), edit_mode(false), climbing(0) { this->name = name; controller = main_controller; @@ -1161,6 +1161,7 @@ Player::kill(bool completely) return; sound_manager->play("sounds/hurt.wav"); + if (climbing) stop_climbing(*climbing); physic.set_velocity_x(0); @@ -1183,6 +1184,13 @@ Player::kill(bool completely) duck = false; } } else { + + // do not die when in edit mode + if (edit_mode) { + set_ghost_mode(true); + return; + } + if (player_status->coins >= 25 && !GameSession::current()->get_reset_point_sectorname().empty()) { for (int i = 0; i < 5; i++) @@ -1241,7 +1249,7 @@ Player::check_bounds(Camera* camera) } /* fallen out of the level? */ - if (get_pos().y > Sector::current()->get_height()) { + if ((get_pos().y > Sector::current()->get_height()) && (!ghost_mode)) { kill(true); return; } @@ -1336,6 +1344,12 @@ Player::set_ghost_mode(bool enable) } +void +Player::set_edit_mode(bool enable) +{ + edit_mode = enable; +} + void Player::start_climbing(Climbable& climbable) { diff --git a/src/object/player.hpp b/src/object/player.hpp index 9fcda0d55..4eea2ccfa 100644 --- a/src/object/player.hpp +++ b/src/object/player.hpp @@ -252,6 +252,12 @@ public: void set_ghost_mode(bool enable); /** + * Switches edit mode on/off. + * In edit mode, Tux will enter ghost_mode instead of dying. + */ + void set_edit_mode(bool enable); + + /** * Returns whether ghost mode is currently enabled */ bool get_ghost_mode() { return ghost_mode; } @@ -311,6 +317,7 @@ private: void try_grab(); bool ghost_mode; /**< indicates if Tux should float around and through solid objects */ + bool edit_mode; /**< indicates if Tux should switch to ghost mode rather than dying */ Timer unduck_hurt_timer; /**< if Tux wants to stand up again after ducking and cannot, this timer is started */ diff --git a/src/scripting/level.cpp b/src/scripting/level.cpp index f780ee29b..8967741f1 100644 --- a/src/scripting/level.cpp +++ b/src/scripting/level.cpp @@ -65,4 +65,12 @@ namespace Scripting return; GameSession::current()->toggle_pause(); } + + void + Level::edit(bool edit_mode) + { + if(GameSession::current() == NULL) return; + GameSession::current()->set_editmode(edit_mode); + } + } diff --git a/src/scripting/level.hpp b/src/scripting/level.hpp index 2cdc258aa..b7d91a248 100644 --- a/src/scripting/level.hpp +++ b/src/scripting/level.hpp @@ -39,6 +39,9 @@ public: void flip_vertically(); /** toggle pause */ void toggle_pause(); + + /** Switch to and from edit mode */ + void edit(bool edit_mode); }; } diff --git a/src/scripting/wrapper.cpp b/src/scripting/wrapper.cpp index cda1f24d4..d001bbbc7 100644 --- a/src/scripting/wrapper.cpp +++ b/src/scripting/wrapper.cpp @@ -485,6 +485,35 @@ static SQInteger Level_toggle_pause_wrapper(HSQUIRRELVM vm) } +static SQInteger Level_edit_wrapper(HSQUIRRELVM vm) +{ + SQUserPointer data; + if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0))) { + sq_throwerror(vm, _SC("'edit' called without instance")); + return SQ_ERROR; + } + Scripting::Level* _this = reinterpret_cast (data); + SQBool arg0; + if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) { + sq_throwerror(vm, _SC("Argument 1 not a bool")); + return SQ_ERROR; + } + + try { + _this->edit(arg0 == SQTrue); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'edit'")); + return SQ_ERROR; + } + +} + static SQInteger ScriptedObject_release_hook(SQUserPointer ptr, SQInteger ) { Scripting::ScriptedObject* _this = reinterpret_cast (ptr); @@ -4477,6 +4506,12 @@ void register_supertux_wrapper(HSQUIRRELVM v) throw SquirrelError(v, "Couldn't register function 'toggle_pause'"); } + sq_pushstring(v, "edit", -1); + sq_newclosure(v, &Level_edit_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'edit'"); + } + if(SQ_FAILED(sq_createslot(v, -3))) { throw SquirrelError(v, "Couldn't register class 'Level'"); }