From: Ondřej Hošek Date: Thu, 13 Apr 2006 18:30:55 +0000 (+0000) Subject: * "Outsourced" cheats from GameSession to scripting system. X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=53b4479f1e7e148ee0f8940de236359513bb4558;p=supertux.git * "Outsourced" cheats from GameSession to scripting system. * Implemented a new cheat (draw_solids_only(bool)) which deactivates drawing of non-solid layers (useful for debugging AND for cheating). SVN-Revision: 3329 --- diff --git a/src/game_session.cpp b/src/game_session.cpp index 6b9a79766..26301fabb 100644 --- a/src/game_session.cpp +++ b/src/game_session.cpp @@ -72,24 +72,6 @@ // binary fraction... static const float LOGICAL_FPS = 64.0; -namespace { - const char* consoleCommands[] = { - "foo", - "whereami", - "camera", - "grease", - "invincible", - "mortal", - "shrink", - "kill", - "gotoend", - "flip", - "finish", - "restart", - "quit" - }; -} - using namespace WorldMapNS; GameSession* GameSession::current_ = 0; @@ -107,10 +89,6 @@ GameSession::GameSession(const std::string& levelfile_, GameSessionMode mode, game_pause = false; fps_fps = 0; - for (uint16_t i=0; i < sizeof(::consoleCommands)/sizeof(typeof(consoleCommands[0])); i++) { - Console::instance->registerCommand(consoleCommands[i], this); - } - statistics_backdrop.reset(new Surface("images/engine/menu/score-backdrop.png")); restart_level(true); @@ -335,79 +313,6 @@ GameSession::process_events() } } -bool -GameSession::consoleCommand(std::string command, std::vector) -{ - if (command == "foo") { - log_info << "bar" << std::endl; - return true; - } - - if (currentsector == 0) return false; - Player& tux = *currentsector->player; - - // Cheating words (the goal of this is really for debugging, - // but could be used for some cheating, nothing wrong with that) - if (command == "grease") { - tux.physic.set_velocity_x(tux.physic.get_velocity_x()*3); - return true; - } - if (command == "invincible") { - // be invincle for the rest of the level - tux.invincible_timer.start(10000); - return true; - } - if (command == "mortal") { - // give up invincibility - tux.invincible_timer.stop(); - return true; - } - if (command == "shrink") { - // remove powerups - tux.kill(tux.SHRINK); - return true; - } - if (command == "kill") { - tux.kill(tux.KILL); - return true; - } - if (command == "restart") { - restart_level(true); - return true; - } - if (command == "whereami") { - log_info << "You are at x " << tux.get_pos().x << ", y " << tux.get_pos().y << std::endl; - return true; - } - if (command == "gotoend") { - // goes to the end of the level - tux.move(Vector( - (currentsector->solids->get_width()*32) - (SCREEN_WIDTH*2), 0)); - currentsector->camera->reset( - Vector(tux.get_pos().x, tux.get_pos().y)); - return true; - } - if (command == "flip") { - FlipLevelTransformer flip_transformer; - flip_transformer.transform(GameSession::current()->get_current_level()); - return true; - } - if (command == "finish") { - finish(true); - return true; - } - if (command == "camera") { - log_info << "Camera is at " << Sector::current()->camera->get_translation().x << "," << Sector::current()->camera->get_translation().y << std::endl; - return true; - } - if (command == "quit") { - main_loop->quit(); - return true; - } - - return false; -} - void GameSession::check_end_conditions() { diff --git a/src/game_session.hpp b/src/game_session.hpp index bed98b2fd..e41eb1e66 100644 --- a/src/game_session.hpp +++ b/src/game_session.hpp @@ -54,7 +54,7 @@ class CodeController; * The GameSession class controlls the controll flow of the Game (the part * where you actually play a level) */ -class GameSession : public Screen, public ConsoleCommandReceiver +class GameSession : public Screen { public: GameSession(const std::string& levelfile, GameSessionMode mode, @@ -94,11 +94,9 @@ public: * resources for the current level/world */ std::string get_working_directory(); - bool consoleCommand(std::string command, std::vector arguments); /**< callback from Console; return false if command was unknown, true otherwise */ - -private: void restart_level(bool fromBeginning = true); +private: void check_end_conditions(); void process_events(); void capture_demo_step(); diff --git a/src/scripting/functions.cpp b/src/scripting/functions.cpp index 53c0ffe6f..83b21974e 100644 --- a/src/scripting/functions.cpp +++ b/src/scripting/functions.cpp @@ -37,6 +37,11 @@ #include "worldmap.hpp" #include "world.hpp" #include "sector.hpp" +#include "object/player.hpp" +#include "object/tilemap.hpp" +#include "main.hpp" +#include "object/camera.hpp" +#include "flip_level_transformer.hpp" #include "squirrel_error.hpp" #include "wrapper_util.hpp" @@ -130,6 +135,11 @@ void debug_collrects(bool enable) Sector::show_collrects = enable; } +void draw_solids_only(bool enable) +{ + Sector::draw_solids_only = enable; +} + void save_state() { if(World::current() == NULL) @@ -138,5 +148,122 @@ void save_state() World::current()->save_state(); } +// not added to header, function to only be used by others +// in this file +bool validate_sector_player() +{ + if (Sector::current() == 0) + { + log_info << "No current sector." << std::endl; + return false; + } + + if (Sector::current()->player == 0) + { + log_info << "No player." << std::endl; + return false; + } + return true; +} + +void grease() +{ + if (!validate_sector_player()) return; + ::Player* tux = Sector::current()->player; // Scripting::Player != ::Player + tux->physic.set_velocity_x(tux->physic.get_velocity_x()*3); +} + +void invincible() +{ + if (!validate_sector_player()) return; + ::Player* tux = Sector::current()->player; + tux->invincible_timer.start(10000); +} + +void mortal() +{ + if (!validate_sector_player()) return; + ::Player* tux = Sector::current()->player; + tux->invincible_timer.stop(); +} + +void shrink() +{ + if (!validate_sector_player()) return; + ::Player* tux = Sector::current()->player; + tux->kill(tux->SHRINK); +} + +void kill() +{ + if (!validate_sector_player()) return; + ::Player* tux = Sector::current()->player; + tux->kill(tux->KILL); +} + +void restart() +{ + if (GameSession::current() == 0) + { + log_info << "No game session" << std::endl; + return; + } + GameSession::current()->restart_level(); +} + +void whereami() +{ + if (!validate_sector_player()) return; + ::Player* tux = Sector::current()->player; + log_info << "You are at x " << tux->get_pos().x << ", y " << tux->get_pos().y << std::endl; +} + +void gotoend() +{ + if (!validate_sector_player()) return; + ::Player* tux = Sector::current()->player; + tux->move(Vector( + (Sector::current()->solids->get_width()*32) - (SCREEN_WIDTH*2), 0)); + Sector::current()->camera->reset( + Vector(tux->get_pos().x, tux->get_pos().y)); +} + +void flip() +{ + if (GameSession::current() == 0) + { + log_info << "No game session" << std::endl; + return; + } + if (GameSession::current()->get_current_level() == 0) + { + log_info << "No current level" << std::endl; + return; + } + FlipLevelTransformer flip_transformer; + flip_transformer.transform(GameSession::current()->get_current_level()); +} + +void finish() +{ + if (GameSession::current() == 0) + { + log_info << "No game session" << std::endl; + return; + } + GameSession::current()->finish(true); +} + +void camera() +{ + if (!validate_sector_player()) return; + log_info << "Camera is at " << Sector::current()->camera->get_translation().x << "," << Sector::current()->camera->get_translation().y << std::endl; +} + +void quit() +{ + main_loop->quit(); +} + } diff --git a/src/scripting/functions.hpp b/src/scripting/functions.hpp index 8c0b6ef82..eec7465d0 100644 --- a/src/scripting/functions.hpp +++ b/src/scripting/functions.hpp @@ -100,6 +100,72 @@ void add_key(int new_key); */ void debug_collrects(bool enable); +/** + * enable/disable drawing of non-solid layers + */ +void draw_solids_only(bool enable); + +// ------- Items after this line were formerly in game_session.cpp + +/** + * speeds Tux up + */ +void grease(); + +/** + * makes Tux invincible for 10000 units of time + */ +void invincible(); + +/** + * recall Tux's invincibility + */ +void mortal(); + +/** + * hurt Tux (kill when Small Tux, otherwise lose powerup or shrink) + */ +void shrink(); + +/** + * kill Tux + */ +void kill(); + +/** + * reinitialise and respawn Tux at the beginning of the current level + */ +void restart(); + +/** + * print Tux's current coordinates in a level + */ +void whereami(); + +/** + * move Tux near the end of the level + */ +void gotoend(); + +/** + * flip the level vertically + */ +void flip(); + +/** + * quit the level, marking it as solved + */ +void finish(); + +/** + * show the camera's coordinates + */ +void camera(); + +/** + * exit the game + */ +void quit(); } #endif diff --git a/src/scripting/wrapper.cpp b/src/scripting/wrapper.cpp index 7bbb4ead0..f914a3347 100644 --- a/src/scripting/wrapper.cpp +++ b/src/scripting/wrapper.cpp @@ -1725,6 +1725,257 @@ static int debug_collrects_wrapper(HSQUIRRELVM vm) } +static int draw_solids_only_wrapper(HSQUIRRELVM vm) +{ + SQBool arg0; + if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) { + sq_throwerror(vm, _SC("Argument 1 not a bool")); + return SQ_ERROR; + } + + try { + Scripting::draw_solids_only(arg0); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'draw_solids_only'")); + return SQ_ERROR; + } + +} + +static int grease_wrapper(HSQUIRRELVM vm) +{ + (void) vm; + + try { + Scripting::grease(); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'grease'")); + return SQ_ERROR; + } + +} + +static int invincible_wrapper(HSQUIRRELVM vm) +{ + (void) vm; + + try { + Scripting::invincible(); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'invincible'")); + return SQ_ERROR; + } + +} + +static int mortal_wrapper(HSQUIRRELVM vm) +{ + (void) vm; + + try { + Scripting::mortal(); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'mortal'")); + return SQ_ERROR; + } + +} + +static int shrink_wrapper(HSQUIRRELVM vm) +{ + (void) vm; + + try { + Scripting::shrink(); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'shrink'")); + return SQ_ERROR; + } + +} + +static int kill_wrapper(HSQUIRRELVM vm) +{ + (void) vm; + + try { + Scripting::kill(); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'kill'")); + return SQ_ERROR; + } + +} + +static int restart_wrapper(HSQUIRRELVM vm) +{ + (void) vm; + + try { + Scripting::restart(); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'restart'")); + return SQ_ERROR; + } + +} + +static int whereami_wrapper(HSQUIRRELVM vm) +{ + (void) vm; + + try { + Scripting::whereami(); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'whereami'")); + return SQ_ERROR; + } + +} + +static int gotoend_wrapper(HSQUIRRELVM vm) +{ + (void) vm; + + try { + Scripting::gotoend(); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'gotoend'")); + return SQ_ERROR; + } + +} + +static int flip_wrapper(HSQUIRRELVM vm) +{ + (void) vm; + + try { + Scripting::flip(); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'flip'")); + return SQ_ERROR; + } + +} + +static int finish_wrapper(HSQUIRRELVM vm) +{ + (void) vm; + + try { + Scripting::finish(); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'finish'")); + return SQ_ERROR; + } + +} + +static int camera_wrapper(HSQUIRRELVM vm) +{ + (void) vm; + + try { + Scripting::camera(); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'camera'")); + return SQ_ERROR; + } + +} + +static int quit_wrapper(HSQUIRRELVM vm) +{ + (void) vm; + + try { + Scripting::quit(); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'quit'")); + return SQ_ERROR; + } + +} + } // end of namespace Wrapper void create_squirrel_instance(HSQUIRRELVM v, Scripting::DisplayEffect* object, bool setup_releasehook) @@ -2095,6 +2346,84 @@ void register_supertux_wrapper(HSQUIRRELVM v) throw SquirrelError(v, "Couldn't register function 'debug_collrects'"); } + sq_pushstring(v, "draw_solids_only", -1); + sq_newclosure(v, &draw_solids_only_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'draw_solids_only'"); + } + + sq_pushstring(v, "grease", -1); + sq_newclosure(v, &grease_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'grease'"); + } + + sq_pushstring(v, "invincible", -1); + sq_newclosure(v, &invincible_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'invincible'"); + } + + sq_pushstring(v, "mortal", -1); + sq_newclosure(v, &mortal_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'mortal'"); + } + + sq_pushstring(v, "shrink", -1); + sq_newclosure(v, &shrink_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'shrink'"); + } + + sq_pushstring(v, "kill", -1); + sq_newclosure(v, &kill_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'kill'"); + } + + sq_pushstring(v, "restart", -1); + sq_newclosure(v, &restart_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'restart'"); + } + + sq_pushstring(v, "whereami", -1); + sq_newclosure(v, &whereami_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'whereami'"); + } + + sq_pushstring(v, "gotoend", -1); + sq_newclosure(v, &gotoend_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'gotoend'"); + } + + sq_pushstring(v, "flip", -1); + sq_newclosure(v, &flip_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'flip'"); + } + + sq_pushstring(v, "finish", -1); + sq_newclosure(v, &finish_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'finish'"); + } + + sq_pushstring(v, "camera", -1); + sq_newclosure(v, &camera_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'camera'"); + } + + sq_pushstring(v, "quit", -1); + sq_newclosure(v, &quit_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'quit'"); + } + // Register class DisplayEffect sq_pushstring(v, "DisplayEffect", -1); if(sq_newclass(v, SQFalse) < 0) { diff --git a/src/sector.cpp b/src/sector.cpp index c0492f799..93a08585d 100644 --- a/src/sector.cpp +++ b/src/sector.cpp @@ -68,6 +68,7 @@ Sector* Sector::_current = 0; bool Sector::show_collrects = false; +bool Sector::draw_solids_only = false; Sector::Sector() : currentmusic(LEVEL_MUSIC), gravity(10), @@ -700,7 +701,14 @@ Sector::draw(DrawingContext& context) GameObject* object = *i; if(!object->is_valid()) continue; - + + if (draw_solids_only) + { + TileMap* tm = dynamic_cast(object); + if (tm && !tm->is_solid()) + continue; + } + object->draw(context); } diff --git a/src/sector.hpp b/src/sector.hpp index 638855694..c6b486d48 100644 --- a/src/sector.hpp +++ b/src/sector.hpp @@ -173,6 +173,7 @@ private: public: // TODO make this private again /// show collision rectangles of moving objects (for debugging) static bool show_collrects; + static bool draw_solids_only; GameObjects gameobjects; MovingObjects moving_objects;