(tile (id 916)
(images
(region "worldmap/antarctica/pier.png" 64 0 32 32))
- (stop #t)
+ (stop #f)
(north #f)
(south #f)
(west #t)
- (east #f))
+ (east #t))
)
}
HitResponse
-BadGuy::collision_player(Player& player, const CollisionHit& hit)
+BadGuy::collision_player(Player& player, const CollisionHit& )
{
if(player.is_invincible()) {
kill_fall();
return ABORT_MOVE;
}
+ /*
printf("PlayerHit: GT %3.1f PM: %3.1f %3.1f BM: %3.1f %3.1f Hit: %3.1f %3.1f\n",
game_time,
player.get_movement().x, player.get_movement().y,
get_movement().x, get_movement().y,
hit.normal.x, hit.normal.y);
+ */
+
// hit from above?
if(player.get_movement().y /*- get_movement().y*/ > 0
&& player.get_bbox().p2.y <
#include "lisp/lisp.hpp"
#include "lisp/parser.hpp"
#include "resources.hpp"
-#include "misc.hpp"
#include "statistics.hpp"
#include "timer.hpp"
+#include "options_menu.hpp"
#include "object/fireworks.hpp"
#include "textscroller.hpp"
#include "control/codecontroller.hpp"
// binary fraction...
static const float LOGICAL_FPS = 64.0;
+enum GameMenuIDs {
+ MNID_CONTINUE,
+ MNID_ABORTLEVEL
+};
+
GameSession* GameSession::current_ = NULL;
-GameSession::GameSession(const std::string& levelfile_, GameSessionMode mode,
- Statistics* statistics)
- : level(0), currentsector(0), mode(mode),
+GameSession::GameSession(const std::string& levelfile_, Statistics* statistics)
+ : level(0), currentsector(0),
end_sequence(NO_ENDSEQUENCE), end_sequence_controller(0),
levelfile(levelfile_), best_level_statistics(statistics),
capture_demo_stream(0), playback_demo_stream(0), demo_controller(0)
currentsector = NULL;
game_pause = false;
- fps_fps = 0;
statistics_backdrop.reset(new Surface("images/engine/menu/score-backdrop.png"));
restart_level(true);
+
+ game_menu.reset(new Menu());
+ game_menu->add_label(_("Pause"));
+ game_menu->add_hl();
+ game_menu->add_entry(MNID_CONTINUE, _("Continue"));
+ game_menu->add_submenu(_("Options"), get_options_menu());
+ game_menu->add_hl();
+ game_menu->add_entry(MNID_ABORTLEVEL, _("Abort Level"));
}
void
currentsector->activate("main");
}
- if(mode == ST_GL_PLAY || mode == ST_GL_LOAD_LEVEL_FILE)
- levelintro();
+ levelintro();
currentsector->play_music(LEVEL_MUSIC);
if(currentsector->player->is_dying() || end_sequence != NO_ENDSEQUENCE)
return; // don't let the player open the menu, when he is dying
- if(mode == ST_GL_TEST) {
- main_loop->exit_screen();
- } else if (!Menu::current()) {
- Menu::set_current(game_menu);
+ if (!Menu::current()) {
+ Menu::set_current(game_menu.get());
game_menu->set_active_item(MNID_CONTINUE);
game_pause = true;
} else {
if(menu) {
menu->update();
- if(menu == game_menu) {
+ if(menu == game_menu.get()) {
switch (game_menu->check()) {
case MNID_CONTINUE:
Menu::set_current(0);
}
}
-#if 0
-GameSession::ExitStatus
-GameSession::run()
-{
- Menu::set_current(0);
- current_ = this;
-
- int fps_cnt = 0;
-
- // Eat unneeded events
- SDL_Event event;
- while(SDL_PollEvent(&event))
- {}
-
- draw();
-
- Uint32 fps_ticks = SDL_GetTicks();
- Uint32 fps_nextframe_ticks = SDL_GetTicks();
- Uint32 ticks;
- bool skipdraw = false;
-
- while (exit_status == ES_NONE) {
- // we run in a logical framerate so elapsed time is a constant
- // This will make the game run determistic and not different on different
- // machines
- static const float elapsed_time = 1.0 / LOGICAL_FPS;
- // old code... float elapsed_time = float(ticks - lastticks) / 1000.;
- if(!game_pause)
- game_time += elapsed_time;
-
- // regulate fps
- ticks = SDL_GetTicks();
- if(ticks > fps_nextframe_ticks) {
- if(skipdraw == true) {
- // already skipped last frame? we have to slow down the game then...
- skipdraw = false;
- fps_nextframe_ticks -= (Uint32) (1000.0 / LOGICAL_FPS);
- } else {
- // don't draw all frames when we're getting too slow
- skipdraw = true;
- }
- } else {
- skipdraw = false;
- while(fps_nextframe_ticks > ticks) {
- /* just wait */
- // If we really have to wait long, then do an imprecise SDL_Delay()
- Uint32 diff = fps_nextframe_ticks - ticks;
- if(diff > 15) {
- SDL_Delay(diff - 10);
- }
- ticks = SDL_GetTicks();
- }
- }
- fps_nextframe_ticks = ticks + (Uint32) (1000.0 / LOGICAL_FPS);
-
- process_events();
- process_menu();
-
- // Update the world state and all objects in the world
- if(!game_pause)
- {
- // Update the world
- check_end_conditions();
- if (end_sequence == ENDSEQUENCE_RUNNING)
- update(elapsed_time/2);
- else if(end_sequence == NO_ENDSEQUENCE)
- update(elapsed_time);
- }
-
- if(!skipdraw)
- draw();
-
- // update sounds
- sound_manager->update();
-
- /* Time stops in pause mode */
- if(game_pause || Menu::current())
- {
- continue;
- }
-
- /* Handle music: */
- if (currentsector->player->invincible_timer.started() &&
- currentsector->player->invincible_timer.get_timeleft()
- > TUX_INVINCIBLE_TIME_WARNING && !end_sequence)
- {
- currentsector->play_music(HERRING_MUSIC);
- }
- /* or just normal music? */
- else if(currentsector->get_music_type() != LEVEL_MUSIC && !end_sequence)
- {
- currentsector->play_music(LEVEL_MUSIC);
- }
-
- /* Calculate frames per second */
- if(config->show_fps)
- {
- ++fps_cnt;
-
- if(SDL_GetTicks() - fps_ticks >= 500)
- {
- fps_fps = (float) fps_cnt / .5;
- fps_cnt = 0;
- fps_ticks = SDL_GetTicks();
- }
- }
- }
-
- // just in case
- currentsector = 0;
- main_controller->reset();
- return exit_status;
-}
-#endif
-
void
GameSession::finish(bool win)
{
{
player_status->draw(context);
- if(config->show_fps) {
- char str[60];
- snprintf(str, sizeof(str), "%3.1f", fps_fps);
- const char* fpstext = "FPS";
- context.draw_text(white_text, fpstext, Vector(SCREEN_WIDTH - white_text->get_text_width(fpstext) - gold_text->get_text_width(" 99999") - BORDER_X, BORDER_Y + 20), LEFT_ALLIGN, LAYER_FOREGROUND1);
- context.draw_text(gold_text, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y + 20), RIGHT_ALLIGN, LAYER_FOREGROUND1);
- }
-
// draw level stats while end_sequence is running
if (end_sequence) {
global_stats.draw_endseq_panel(context, best_level_statistics, statistics_backdrop.get());
#include "console.hpp"
#include "video/surface.hpp"
-/* GameLoop modes */
-enum GameSessionMode {
- ST_GL_PLAY,
- ST_GL_TEST,
- ST_GL_LOAD_GAME,
- ST_GL_LOAD_LEVEL_FILE,
- ST_GL_DEMO_GAME
-};
-
-enum GameMenuIDs {
- MNID_CONTINUE,
- MNID_ABORTLEVEL
-};
-
-extern int game_started;
-
class Level;
class Sector;
class Statistics;
class DrawingContext;
class CodeController;
+class Menu;
/**
* The GameSession class controlls the controll flow of the Game (the part
class GameSession : public Screen
{
public:
- GameSession(const std::string& levelfile, GameSessionMode mode,
- Statistics* statistics = NULL);
+ GameSession(const std::string& levelfile, Statistics* statistics = NULL);
~GameSession();
void record_demo(const std::string& filename);
/// ends the current level
void finish(bool win = true);
- void respawn(const std::string& sectorname,
- const std::string& spawnpointname);
- void set_reset_point(const std::string& sectorname,
- const Vector& pos);
+ void respawn(const std::string& sectorname, const std::string& spawnpointname);
+ void set_reset_point(const std::string& sectorname, const Vector& pos);
void display_info_box(const std::string& text);
Sector* get_current_sector()
void start_sequence(const std::string& sequencename);
- /** returns the "working directory" usually this is the directory where the
+ /**
+ * 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
*/
Sector* currentsector;
- GameSessionMode mode;
int levelnb;
- float fps_fps;
int pause_menu_frame;
/** If true the end_sequence will be played, user input will be
std::string capture_file;
std::istream* playback_demo_stream;
CodeController* demo_controller;
+
+ std::auto_ptr<Menu> game_menu;
};
#endif /*SUPERTUX_GAMELOOP_H*/
--- /dev/null
+// $Id: log.hpp 3327 2006-04-13 15:02:40Z ravu_al_hemio $
+//
+// SuperTux Debug Helper Functions
+// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+#include <config.h>
+
+#include "log.hpp"
+#include "math/vector.hpp"
+
+std::ostream& operator<<(std::ostream& out, const Vector& vector)
+{
+ out << '[' << vector.x << ',' << vector.y << ']';
+ return out;
+}
+
#endif
+class Vector;
+std::ostream& operator<< (std::ostream& str, const Vector& vector);
+
#endif
#include "video/surface.hpp"
#include "video/texture_manager.hpp"
#include "control/joystickkeyboardcontroller.hpp"
-#include "misc.hpp"
+#include "options_menu.hpp"
#include "mainloop.hpp"
#include "title.hpp"
#include "game_session.hpp"
timelog("scripting");
init_scripting();
- timelog("menu");
- setup_menu();
timelog("resources");
load_shared();
timelog(0);
// So we simply mount that path here...
std::string dir = FileSystem::dirname(config->start_level);
PHYSFS_addToSearchPath(dir.c_str(), true);
- GameSession* session
- = new GameSession(
- FileSystem::basename(config->start_level), ST_GL_LOAD_LEVEL_FILE);
+ std::auto_ptr<GameSession> session
+ (new GameSession(FileSystem::basename(config->start_level)));
if(config->start_demo != "")
session->play_demo(config->start_demo);
if(config->record_demo != "")
session->record_demo(config->record_demo);
- main_loop->push_screen(session);
+ main_loop->push_screen(session.release());
} else {
main_loop->push_screen(new TitleScreen());
}
delete main_loop;
main_loop = NULL;
- free_menu();
+ free_options_menu();
unload_shared();
quit_audio();
#include "script_manager.hpp"
#include "screen.hpp"
#include "timer.hpp"
+#include "player_status.hpp"
// the engine will be run with a logical framerate of 64fps.
// We chose 64fps here because it is a power of 2, so 1/64 gives an "even"
}
void
+MainLoop::draw_fps(DrawingContext& context, float fps_fps)
+{
+ char str[60];
+ snprintf(str, sizeof(str), "%3.1f", fps_fps);
+ const char* fpstext = "FPS";
+ context.draw_text(white_text, fpstext, Vector(SCREEN_WIDTH - white_text->get_text_width(fpstext) - gold_text->get_text_width(" 99999") - BORDER_X, BORDER_Y + 20), LEFT_ALLIGN, LAYER_FOREGROUND1);
+ context.draw_text(gold_text, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y + 20), RIGHT_ALLIGN, LAYER_FOREGROUND1);
+}
+
+void
MainLoop::run()
{
DrawingContext context;
unsigned int frame_count;
- float fps_fps;
+ float fps_fps = 0;
Uint32 fps_ticks = SDL_GetTicks();
Uint32 fps_nextframe_ticks = SDL_GetTicks();
Uint32 ticks;
Menu::current()->draw(context);
Console::instance->draw(context);
+ if(config->show_fps)
+ draw_fps(context, fps_fps);
+
context.do_drawing();
/* Calculate frames per second */
class Screen;
class Console;
+class DrawingContext;
class MainLoop
{
void push_screen(Screen* screen);
private:
+ void draw_fps(DrawingContext& context, float fps);
+
bool running;
float speed;
bool nextpush;
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobas Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#include "misc.hpp"
-#include "main.hpp"
-#include "gameconfig.hpp"
-#include "game_session.hpp"
-#include "gui/menu.hpp"
-#include "gui/button.hpp"
-#include "audio/sound_manager.hpp"
-#include "title.hpp"
-#include "resources.hpp"
-#include "worldmap/worldmap.hpp"
-#include "gettext.hpp"
-#include "options_menu.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-
-Menu* main_menu = NULL;
-Menu* game_menu = NULL;
-
-void setup_menu()
-{
- main_menu = new Menu();
- game_menu = new Menu();
-
- main_menu->set_pos(SCREEN_WIDTH/2, 335);
- main_menu->add_entry(MNID_STARTGAME, _("Start Game"));
- main_menu->add_entry(MNID_LEVELS_CONTRIB, _("Contrib Levels"));
- main_menu->add_submenu(_("Options"), get_options_menu());
- main_menu->add_entry(MNID_CREDITS, _("Credits"));
- main_menu->add_entry(MNID_QUITMAINMENU, _("Quit"));
-
- game_menu->add_label(_("Pause"));
- game_menu->add_hl();
- game_menu->add_entry(MNID_CONTINUE, _("Continue"));
- game_menu->add_submenu(_("Options"), get_options_menu());
- game_menu->add_hl();
- game_menu->add_entry(MNID_ABORTLEVEL, _("Abort Level"));
-}
-
-void free_menu()
-{
- delete main_menu;
- delete game_menu;
- free_options_menu();
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobas Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef SUPERTUX_MISC_H
-#define SUPERTUX_MISC_H
-
-enum MainMenuIDs {
- MNID_STARTGAME,
- MNID_LEVELS_CONTRIB,
- MNID_OPTIONMENU,
- MNID_LEVELEDITOR,
- MNID_CREDITS,
- MNID_QUITMAINMENU
-};
-
-/* Create and setup menus. */
-void setup_menu();
-void free_menu();
-
-#endif
#ifndef SUPERTUX_RESOURCES_H
#define SUPERTUX_RESOURCES_H
-class SpriteManager;
-class Menu;
class Font;
-class Surface;
-class SoundManager;
-class TileManager;
class MouseCursor;
-extern Menu* main_menu;
-extern Menu* game_menu;
-
extern MouseCursor* mouse_cursor;
extern Font* gold_text;
#include "worldmap/worldmap.hpp"
#include "world.hpp"
#include "sector.hpp"
+#include "gameconfig.hpp"
#include "object/player.hpp"
#include "object/tilemap.hpp"
#include "main.hpp"
{
using namespace WorldMapNS;
- std::auto_ptr<WorldMap> worldmap(new WorldMap());
- worldmap->loadmap(filename);
- main_loop->push_screen(worldmap.release());
+ main_loop->push_screen(new WorldMap(filename));
}
void load_level(const std::string& filename)
{
- main_loop->push_screen(new GameSession(filename, ST_GL_PLAY));
+ main_loop->push_screen(new GameSession(filename));
}
static SQInteger squirrel_read_char(SQUserPointer file)
Sector::show_collrects = enable;
}
-void draw_solids_only(bool enable)
+void debug_draw_fps(bool enable)
+{
+ config->show_fps = enable;
+}
+
+void debug_draw_solids_only(bool enable)
{
Sector::draw_solids_only = enable;
}
void debug_collrects(bool enable);
/**
+ * enable/disable drawing of fps
+ */
+void debug_draw_fps(bool enable);
+
+/**
* enable/disable drawing of non-solid layers
*/
-void draw_solids_only(bool enable);
+void debug_draw_solids_only(bool enable);
/**
* speeds Tux up
}
-static int draw_solids_only_wrapper(HSQUIRRELVM vm)
+static int debug_draw_fps_wrapper(HSQUIRRELVM vm)
{
SQBool arg0;
if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
}
try {
- Scripting::draw_solids_only(arg0);
+ Scripting::debug_draw_fps(arg0);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'draw_solids_only'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'debug_draw_fps'"));
+ return SQ_ERROR;
+ }
+
+}
+
+static int debug_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::debug_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 'debug_draw_solids_only'"));
return SQ_ERROR;
}
throw SquirrelError(v, "Couldn't register function 'debug_collrects'");
}
- sq_pushstring(v, "draw_solids_only", -1);
- sq_newclosure(v, &draw_solids_only_wrapper, 0);
+ sq_pushstring(v, "debug_draw_fps", -1);
+ sq_newclosure(v, &debug_draw_fps_wrapper, 0);
+ if(SQ_FAILED(sq_createslot(v, -3))) {
+ throw SquirrelError(v, "Couldn't register function 'debug_draw_fps'");
+ }
+
+ sq_pushstring(v, "debug_draw_solids_only", -1);
+ sq_newclosure(v, &debug_draw_solids_only_wrapper, 0);
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'draw_solids_only'");
+ throw SquirrelError(v, "Couldn't register function 'debug_draw_solids_only'");
}
sq_pushstring(v, "grease", -1);
extern float game_time;
/**
- * new simpler timer designed to be used in the update functions of objects
+ * Simple timer designed to be used in the update functions of objects
*/
class Timer
{
#include "object/player.hpp"
#include "resources.hpp"
#include "gettext.hpp"
-#include "misc.hpp"
#include "textscroller.hpp"
#include "file_system.hpp"
#include "control/joystickkeyboardcontroller.hpp"
#include "control/codecontroller.hpp"
#include "main.hpp"
#include "log.hpp"
+#include "options_menu.hpp"
#include "console.hpp"
+enum MainMenuIDs {
+ MNID_STARTGAME,
+ MNID_LEVELS_CONTRIB,
+ MNID_OPTIONMENU,
+ MNID_LEVELEDITOR,
+ MNID_CREDITS,
+ MNID_QUITMAINMENU
+};
+
void
TitleScreen::update_load_game_menu()
{
if (contrib_world_menu->get_item_by_id(index).kind == MN_ACTION) {
sound_manager->stop_music();
GameSession* session =
- new GameSession(
- current_world->get_level_filename(index), ST_GL_PLAY);
+ new GameSession(current_world->get_level_filename(index));
main_loop->push_screen(session);
}
}
TitleScreen::TitleScreen()
{
controller.reset(new CodeController());
- titlesession.reset(new GameSession("levels/misc/menu.stl", ST_GL_DEMO_GAME));
+ titlesession.reset(new GameSession("levels/misc/menu.stl"));
Player* player = titlesession->get_current_sector()->player;
player->set_controller(controller.get());
+
+ main_menu.reset(new Menu());
+ main_menu->set_pos(SCREEN_WIDTH/2, 335);
+ main_menu->add_entry(MNID_STARTGAME, _("Start Game"));
+ main_menu->add_entry(MNID_LEVELS_CONTRIB, _("Contrib Levels"));
+ main_menu->add_submenu(_("Options"), get_options_menu());
+ main_menu->add_entry(MNID_CREDITS, _("Credits"));
+ main_menu->add_entry(MNID_QUITMAINMENU, _("Quit"));
}
TitleScreen::~TitleScreen()
sector->activate(sector->player->get_pos());
}
- Menu::set_current(main_menu);
+ Menu::set_current(main_menu.get());
}
void
Sector* sector = titlesession->get_current_sector();
sector->draw(context);
- /*
- if (Menu::current() == main_menu)
- context.draw_surface(logo, Vector(SCREEN_WIDTH/2 - logo->get_width()/2, 30),
- LAYER_FOREGROUND1+1);
- */
-
context.draw_text(white_small_text, " SuperTux " PACKAGE_VERSION "\n",
Vector(0, SCREEN_HEIGHT - 50), LEFT_ALLIGN, LAYER_FOREGROUND1);
context.draw_text(white_small_text,
if(menu) {
menu->update();
- if(menu == main_menu) {
+ if(menu == main_menu.get()) {
switch (main_menu->check()) {
case MNID_STARTGAME:
// Start Game, ie. goto the slots menu
}
update_load_save_game_menu(load_game_menu);
- Menu::set_current(main_menu);
+ Menu::set_current(main_menu.get());
}*/
process_load_game_menu();
} else if(menu == contrib_menu.get()) {
// reopen menu of user closed it (so that the app doesn't close when user
// accidently hit ESC)
if(Menu::current() == 0) {
- Menu::set_current(main_menu);
+ Menu::set_current(main_menu.get());
}
}
void check_contrib_world_menu();
void free_contrib_menu();
+ std::auto_ptr<Menu> main_menu;
std::auto_ptr<Menu> load_game_menu;
std::auto_ptr<Menu> contrib_menu;
std::auto_ptr<Menu> contrib_world_menu;
HSQUIRRELVM new_vm = ScriptManager::instance->create_thread();
Scripting::compile_and_run(new_vm, in, filename);
} catch(std::exception& e) {
+ // fallback: try to load worldmap worldmap.stwm
using namespace WorldMapNS;
- // fallback try to load worldmap
- std::auto_ptr<WorldMap> worldmap (new WorldMap);
- worldmap->loadmap(basedir + "worldmap.stwm");
- main_loop->push_screen(worldmap.release());
+ main_loop->push_screen(new WorldMap(basedir + "worldmap.stwm"));
}
}
#include "sprite_change.hpp"
#include "sprite/sprite_manager.hpp"
#include "sprite/sprite.hpp"
+#include "video/drawing_context.hpp"
namespace WorldMapNS
{
SpriteChange::SpriteChange(const lisp::Lisp* lisp)
- : enter(false), in_stay_action(false)
+ : change_on_touch(false), in_stay_action(false)
{
lisp->get("x", pos.x);
lisp->get("y", pos.y);
- lisp->get("enter", enter);
+ lisp->get("change-on-touch", change_on_touch);
std::string spritefile = "";
lisp->get("sprite", spritefile);
}
void
-SpriteChange::draw(DrawingContext& )
+SpriteChange::draw(DrawingContext& context)
{
+ if(in_stay_action && stay_action != "") {
+ sprite->set_action(stay_action);
+ sprite->draw(context, pos * 32 + Vector(16, 16), LAYER_OBJECTS-1);
+ }
}
void
* should tuxs sprite change when the tile has been completely entered,
* or already when the tile was just touched
*/
- bool enter;
+ bool change_on_touch;
/// sprite to change tux image to
std::auto_ptr<Sprite> sprite;
/**
#include "worldmap.hpp"
#include "level.hpp"
#include "special_tile.hpp"
+#include "sprite_change.hpp"
#include "control/joystickkeyboardcontroller.hpp"
#include "main.hpp"
// We got a new direction, so lets start walking when possible
Vector next_tile;
- if ((!level || level->solved) && worldmap->path_ok(input_direction, tile_pos, &next_tile))
- {
+ if ((!level || level->solved)
+ && worldmap->path_ok(input_direction, tile_pos, &next_tile)) {
tile_pos = next_tile;
moving = true;
direction = input_direction;
back_direction = reverse_dir(direction);
- }
- else if (input_direction == back_direction)
- {
+ } else if (input_direction == back_direction) {
moving = true;
direction = input_direction;
tile_pos = worldmap->get_next_tile(tile_pos, direction);
back_direction = reverse_dir(direction);
}
-
}
bool
void
Tux::tryContinueWalking(float elapsed_time)
{
- if (!moving) return;
+ if (!moving)
+ return;
// Let tux walk
offset += TUXSPEED * elapsed_time;
// Do nothing if we have not yet reached the next tile
- if (offset <= 32) return;
+ if (offset <= 32)
+ return;
offset -= 32;
+ SpriteChange* sprite_change = worldmap->at_sprite_change(tile_pos);
+ if(sprite_change != NULL) {
+ sprite.reset(new Sprite( *(sprite_change->sprite.get()) ));
+ sprite_change->in_stay_action = false;
+ }
+
// if this is a special_tile with passive_message, display it
SpecialTile* special_tile = worldmap->at_special_tile();
if(special_tile && special_tile->passive_message)
}
}
-
-
// stop if we reached a level, a WORLDMAP_STOP tile or a special tile without a passive_message
- if ((worldmap->at_level()) || (worldmap->at(tile_pos)->getData() & Tile::WORLDMAP_STOP) || (special_tile && !special_tile->passive_message))
- {
- if(special_tile && !special_tile->map_message.empty() && !special_tile->passive_message) worldmap->passive_message_timer.start(0);
+ if ((worldmap->at_level())
+ || (worldmap->at(tile_pos)->getData() & Tile::WORLDMAP_STOP)
+ || (special_tile && !special_tile->passive_message)) {
+ if(special_tile && !special_tile->map_message.empty()
+ && !special_tile->passive_message)
+ worldmap->passive_message_timer.start(0);
stop();
return;
}
// if user wants to change direction, try changing, else guess the direction in which to walk next
const Tile* tile = worldmap->at(tile_pos);
- if (direction != input_direction)
- {
- if(canWalk(tile, input_direction))
- {
+ if (direction != input_direction) {
+ if(canWalk(tile, input_direction)) {
direction = input_direction;
back_direction = reverse_dir(direction);
}
- }
- else
- {
+ } else {
Direction dir = D_NONE;
- if (tile->getData() & Tile::WORLDMAP_NORTH && back_direction != D_NORTH) dir = D_NORTH;
- else if (tile->getData() & Tile::WORLDMAP_SOUTH && back_direction != D_SOUTH) dir = D_SOUTH;
- else if (tile->getData() & Tile::WORLDMAP_EAST && back_direction != D_EAST) dir = D_EAST;
- else if (tile->getData() & Tile::WORLDMAP_WEST && back_direction != D_WEST) dir = D_WEST;
-
- if (dir == D_NONE)
- {
+ if (tile->getData() & Tile::WORLDMAP_NORTH && back_direction != D_NORTH)
+ dir = D_NORTH;
+ else if (tile->getData() & Tile::WORLDMAP_SOUTH && back_direction != D_SOUTH)
+ dir = D_SOUTH;
+ else if (tile->getData() & Tile::WORLDMAP_EAST && back_direction != D_EAST)
+ dir = D_EAST;
+ else if (tile->getData() & Tile::WORLDMAP_WEST && back_direction != D_WEST)
+ dir = D_WEST;
+
+ if (dir == D_NONE) {
// Should never be reached if tiledata is good
log_warning << "Could not determine where to walk next" << std::endl;
stop();
}
// Walk automatically to the next tile
- if(direction != D_NONE)
- {
- Vector next_tile;
- if (worldmap->path_ok(direction, tile_pos, &next_tile))
- {
- tile_pos = next_tile;
- }
- else
- {
- log_warning << "Tilemap data is buggy" << std::endl;
- stop();
- }
+ if(direction == D_NONE)
+ return;
+
+ Vector next_tile;
+ if (!worldmap->path_ok(direction, tile_pos, &next_tile)) {
+ log_warning << "Tilemap data is buggy" << std::endl;
+ stop();
+ return;
+ }
+
+ SpriteChange* next_sprite = worldmap->at_sprite_change(next_tile);
+ if(next_sprite != NULL && next_sprite->change_on_touch) {
+ sprite.reset(new Sprite( *(next_sprite->sprite.get()) ));
+ next_sprite->in_stay_action = false;
+ }
+ SpriteChange* last_sprite = worldmap->at_sprite_change(tile_pos);
+ if(last_sprite != NULL && next_sprite != NULL) {
+ log_debug << "Old: " << tile_pos << " New: " << next_tile << std::endl;
+ last_sprite->in_stay_action = true;
}
+
+ tile_pos = next_tile;
}
void
Tux::update(float elapsed_time)
{
updateInputDirection();
- if (moving) tryContinueWalking(elapsed_time); else tryStartWalking();
+ if (moving)
+ tryContinueWalking(elapsed_time);
+ else
+ tryStartWalking();
}
}
#include "sector.hpp"
#include "worldmap.hpp"
#include "resources.hpp"
-#include "misc.hpp"
#include "log.hpp"
#include "world.hpp"
#include "player_status.hpp"
//---------------------------------------------------------------------------
-WorldMap::WorldMap()
+WorldMap::WorldMap(const std::string& filename)
: tux(0), solids(0)
{
tile_manager.reset(new TileManager("images/worldmap.strf"));
name = "<no title>";
music = "music/salcon.ogg";
- intro_displayed = false;
total_stats.reset();
worldmap_menu->add_submenu(_("Options"), get_options_menu());
worldmap_menu->add_hl();
worldmap_menu->add_entry(MNID_QUITWORLDMAP, _("Quit World"));
+
+ load(filename);
}
WorldMap::~WorldMap()
if(current_ == this)
current_ = NULL;
- clear_objects();
+ for(GameObjects::iterator i = game_objects.begin();
+ i != game_objects.end(); ++i)
+ delete *i;
+
for(SpawnPoints::iterator i = spawn_points.begin();
i != spawn_points.end(); ++i) {
delete *i;
}
void
-WorldMap::clear_objects()
-{
- for(GameObjects::iterator i = game_objects.begin();
- i != game_objects.end(); ++i)
- delete *i;
- game_objects.clear();
- solids = 0;
- tux = new Tux(this);
- add_object(tux);
-}
-
-// Don't forget to set map_filename before calling this
-void
-WorldMap::load_map()
+WorldMap::load(const std::string& filename)
{
+ map_filename = filename;
levels_path = FileSystem::dirname(map_filename);
try {
if(!sector)
throw std::runtime_error("No sector sepcified in worldmap file.");
- clear_objects();
lisp::ListIterator iter(sector);
while(iter.next()) {
if(iter.item() == "tilemap") {
add_object(new Background(*(iter.lisp())));
} else if(iter.item() == "music") {
iter.value()->get(music);
- } else if(iter.item() == "intro-script") {
- iter.value()->get(intro_script);
} else if(iter.item() == "worldmap-spawnpoint") {
SpawnPoint* sp = new SpawnPoint(iter.lisp());
spawn_points.push_back(sp);
SpecialTile* special_tile = new SpecialTile(iter.lisp());
special_tiles.push_back(special_tile);
game_objects.push_back(special_tile);
- } else if(iter.item() == "spritechange") {
+ } else if(iter.item() == "sprite-change") {
SpriteChange* sprite_change = new SpriteChange(iter.lisp());
sprite_changes.push_back(sprite_change);
game_objects.push_back(sprite_change);
}
bool
-WorldMap::path_ok(Direction direction, Vector old_pos, Vector* new_pos)
+WorldMap::path_ok(Direction direction, const Vector& old_pos, Vector* new_pos)
{
*new_pos = get_next_tile(old_pos, direction);
&& at(*new_pos)->getData() & Tile::WORLDMAP_NORTH);
case D_NONE:
- assert(!"path_ok() can't work if direction is NONE");
+ assert(!"path_ok() can't walk if direction is NONE");
}
return false;
}
if (level->pos == tux->get_tile_pos()) {
// do a shriking fade to the level
- shrink_fade(Vector((level->pos.x*32 + 16 + offset.x),
- (level->pos.y*32 + 16 + offset.y)), 500);
+ shrink_fade(Vector((level->pos.x*32 + 16 + camera_offset.x),
+ (level->pos.y*32 + 16 + camera_offset.y)), 500);
try {
- GameSession *session =
- new GameSession(levels_path + level->name,
- ST_GL_LOAD_LEVEL_FILE, &level->statistics);
- main_loop->push_screen(session);
+ main_loop->push_screen(new GameSession(
+ levels_path + level->name, &level->statistics));
} catch(std::exception& e) {
log_fatal << "Couldn't load level: " << e.what() << std::endl;
}
}
SpriteChange*
-WorldMap::at_sprite_change()
+WorldMap::at_sprite_change(const Vector& pos)
{
+ for(SpriteChanges::iterator i = sprite_changes.begin();
+ i != sprite_changes.end(); ++i) {
+ SpriteChange* sprite_change = *i;
+ if(sprite_change->pos == pos)
+ return sprite_change;
+ }
+
return NULL;
}
return count;
}
-void
-WorldMap::loadmap(const std::string& filename)
-{
- savegame_file = "";
- map_filename = filename;
- load_map();
-}
-
} // namespace WorldMapNS
Direction string_to_direction(const std::string& d);
Direction reverse_dir(Direction d);
-/** */
+/**
+ * Screen that displays a worldmap
+ */
class WorldMap : public Screen
{
private:
typedef std::vector<SpawnPoint*> SpawnPoints;
SpawnPoints spawn_points;
- Vector offset;
- std::string savegame_file;
-
- std::string intro_script;
- bool intro_displayed;
-
- void get_level_title(Level& level);
-
- void draw_status(DrawingContext& context);
-
- // to avoid calculating total stats all the time. This way only
- // when need, it is calculated.
Statistics total_stats;
- void calculate_total_stats();
public:
- WorldMap();
+ WorldMap(const std::string& filename);
~WorldMap();
- void load_map();
-
void add_object(GameObject* object);
- void clear_objects();
static WorldMap* current()
{ return current_; }
- void setup();
-
- /** Update Tux position */
- void update(float delta);
+ virtual void setup();
- /** Draw one frame */
- void draw(DrawingContext& context);
+ /** Update worldmap state */
+ virtual void update(float delta);
+ /** Draw worldmap */
+ virtual void draw(DrawingContext& context);
Vector get_next_tile(Vector pos, Direction direction);
const Tile* at(Vector pos);
Level* at_level();
SpecialTile* at_special_tile();
- SpriteChange* at_sprite_change();
+ SpriteChange* at_sprite_change(const Vector& pos);
/** Check if it is possible to walk from \a pos into \a direction,
if possible, write the new position to \a new_pos */
- bool path_ok(Direction direction, Vector pos, Vector* new_pos);
+ bool path_ok(Direction direction, const Vector& pos, Vector* new_pos);
/**
* Save worldmap state to squirrel state table
*/
void load_state();
- /**
- * Load a worldmap
- */
- void loadmap(const std::string& filename);
-
const std::string& get_title() const
{ return name; }
- void set_map_filename(std::string filename)
- { map_filename = filename; }
-
private:
+ void get_level_title(Level& level);
+ void draw_status(DrawingContext& context);
+ void calculate_total_stats();
+
+ void load(const std::string& filename);
void on_escape_press();
void parse_special_tile(const lisp::Lisp* lisp);
void parse_sprite_change(const lisp::Lisp* lisp);