From 0455efd20d16866b841817340677e82a632a228e Mon Sep 17 00:00:00 2001 From: auria Date: Mon, 5 Dec 2011 22:00:42 +0000 Subject: [PATCH] Massive refactor in challenge code to allow having more than 1 progression git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@10349 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- CMakeLists.txt | 2 +- src/challenges/challenge.cpp | 146 +--------- src/challenges/challenge.hpp | 92 +------ src/challenges/challenge_data.cpp | 141 +++++++++- src/challenges/challenge_data.hpp | 76 +++++- src/challenges/game_slot.cpp | 216 +++++++++++++++ src/challenges/game_slot.hpp | 97 +++++++ src/challenges/unlock_manager.cpp | 250 ++++++------------ src/challenges/unlock_manager.hpp | 44 ++- .../Xcode/STK_XCode.xcodeproj/project.pbxproj | 6 + src/io/xml_writer.hpp | 2 + src/karts/kart_properties_manager.cpp | 4 +- src/main.cpp | 8 +- src/modes/world.cpp | 2 +- src/race/race_manager.cpp | 4 +- src/states_screens/arenas_screen.cpp | 4 +- src/states_screens/challenges.cpp | 18 +- .../dialogs/race_over_dialog.cpp | 8 +- src/states_screens/dialogs/story_mode_new.cpp | 2 + src/states_screens/feature_unlocked.cpp | 12 +- src/states_screens/grand_prix_lose.cpp | 6 +- src/states_screens/grand_prix_win.cpp | 8 +- src/states_screens/kart_selection.cpp | 4 +- src/states_screens/race_result_gui.cpp | 8 +- src/states_screens/race_setup_screen.cpp | 2 +- src/states_screens/tracks_screen.cpp | 6 +- 26 files changed, 702 insertions(+), 466 deletions(-) create mode 100644 src/challenges/game_slot.cpp create mode 100644 src/challenges/game_slot.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 25c229c98..fc9197cc7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,7 +180,7 @@ else() message("-- Font tool deactivated, the font tool won't be built (only useful for developers)") endif() -set( SRCS ${SRCS} src/addons/addon.cpp src/addons/addon.hpp src/addons/addons_manager.cpp src/addons/addons_manager.hpp src/addons/dummy_network_http.hpp src/addons/inetwork_http.hpp src/addons/network_http.cpp src/addons/network_http.hpp src/addons/news_manager.cpp src/addons/news_manager.hpp src/addons/request.cpp src/addons/request.hpp src/addons/zip.cpp src/addons/zip.hpp src/animations/animation_base.cpp src/animations/animation_base.hpp src/animations/billboard_animation.cpp src/animations/billboard_animation.hpp src/animations/ipo.cpp src/animations/ipo.hpp src/animations/three_d_animation.cpp src/animations/three_d_animation.hpp src/audio/dummy_sfx.hpp src/audio/music.hpp src/audio/music_dummy.hpp src/audio/music_information.cpp src/audio/music_information.hpp src/audio/music_manager.cpp src/audio/music_manager.hpp src/audio/music_ogg.cpp src/audio/music_ogg.hpp src/audio/sfx_base.hpp src/audio/sfx_buffer.cpp src/audio/sfx_buffer.hpp src/audio/sfx_manager.cpp src/audio/sfx_manager.hpp src/audio/sfx_openal.cpp src/audio/sfx_openal.hpp src/challenges/challenge.cpp src/challenges/challenge.hpp src/challenges/challenge_data.cpp src/challenges/challenge_data.hpp src/challenges/unlock_manager.cpp src/challenges/unlock_manager.hpp src/config/device_config.cpp src/config/device_config.hpp src/config/player.hpp src/config/stk_config.cpp src/config/stk_config.hpp src/config/user_config.cpp src/config/user_config.hpp src/enet/callbacks.c src/enet/compress.c src/enet/host.c src/enet/include/enet/callbacks.h src/enet/include/enet/enet.h src/enet/include/enet/list.h src/enet/include/enet/protocol.h src/enet/include/enet/time.h src/enet/include/enet/types.h src/enet/include/enet/unix.h src/enet/include/enet/utility.h src/enet/include/enet/win32.h src/enet/list.c src/enet/packet.c src/enet/peer.c src/enet/protocol.c src/enet/unix.c src/enet/win32.c src/graphics/camera.cpp src/graphics/camera.hpp src/graphics/CBatchingMesh.cpp src/graphics/CBatchingMesh.hpp src/graphics/explosion.cpp src/graphics/explosion.hpp src/graphics/hardware_skinning.cpp src/graphics/hardware_skinning.hpp src/graphics/hit_effect.hpp src/graphics/hit_sfx.cpp src/graphics/hit_sfx.hpp src/graphics/irr_driver.cpp src/graphics/irr_driver.hpp src/graphics/lod_node.cpp src/graphics/lod_node.hpp src/graphics/material.cpp src/graphics/material.hpp src/graphics/material_manager.cpp src/graphics/material_manager.hpp src/graphics/mesh_tools.cpp src/graphics/mesh_tools.hpp src/graphics/moving_texture.cpp src/graphics/moving_texture.hpp src/graphics/particle_emitter.cpp src/graphics/particle_emitter.hpp src/graphics/particle_kind.cpp src/graphics/particle_kind.hpp src/graphics/particle_kind_manager.cpp src/graphics/particle_kind_manager.hpp src/graphics/per_camera_node.cpp src/graphics/per_camera_node.hpp src/graphics/post_processing.cpp src/graphics/post_processing.hpp src/graphics/rain.cpp src/graphics/rain.hpp src/graphics/referee.cpp src/graphics/referee.hpp src/graphics/shadow.cpp src/graphics/shadow.hpp src/graphics/skid_marks.cpp src/graphics/skid_marks.hpp src/graphics/slip_stream.cpp src/graphics/slip_stream.hpp src/graphics/stars.cpp src/graphics/stars.hpp src/guiengine/abstract_state_manager.cpp src/guiengine/abstract_state_manager.hpp src/guiengine/abstract_top_level_container.cpp src/guiengine/abstract_top_level_container.hpp src/guiengine/CGUISpriteBank.cpp src/guiengine/CGUISpriteBank.h src/guiengine/engine.cpp src/guiengine/engine.hpp src/guiengine/event_handler.cpp src/guiengine/event_handler.hpp src/guiengine/layout_manager.cpp src/guiengine/layout_manager.hpp src/guiengine/modaldialog.cpp src/guiengine/modaldialog.hpp src/guiengine/scalable_font.cpp src/guiengine/scalable_font.hpp src/guiengine/screen.cpp src/guiengine/screen.hpp src/guiengine/screen_loader.cpp src/guiengine/skin.cpp src/guiengine/skin.hpp src/guiengine/widget.cpp src/guiengine/widget.hpp src/guiengine/widgets/bubble_widget.cpp src/guiengine/widgets/bubble_widget.hpp src/guiengine/widgets/button_widget.cpp src/guiengine/widgets/button_widget.hpp src/guiengine/widgets/CGUIEditBox.cpp src/guiengine/widgets/CGUIEditBox.h src/guiengine/widgets/check_box_widget.cpp src/guiengine/widgets/check_box_widget.hpp src/guiengine/widgets/dynamic_ribbon_widget.cpp src/guiengine/widgets/dynamic_ribbon_widget.hpp src/guiengine/widgets/icon_button_widget.cpp src/guiengine/widgets/icon_button_widget.hpp src/guiengine/widgets/label_widget.cpp src/guiengine/widgets/label_widget.hpp src/guiengine/widgets/list_widget.cpp src/guiengine/widgets/list_widget.hpp src/guiengine/widgets/model_view_widget.cpp src/guiengine/widgets/model_view_widget.hpp src/guiengine/widgets/progress_bar_widget.cpp src/guiengine/widgets/progress_bar_widget.hpp src/guiengine/widgets/ribbon_widget.cpp src/guiengine/widgets/ribbon_widget.hpp src/guiengine/widgets/spinner_widget.cpp src/guiengine/widgets/spinner_widget.hpp src/guiengine/widgets/text_box_widget.cpp src/guiengine/widgets/text_box_widget.hpp src/guiengine/widgets.hpp src/input/binding.cpp src/input/binding.hpp src/input/device_manager.cpp src/input/device_manager.hpp src/input/input.hpp src/input/input_device.cpp src/input/input_device.hpp src/input/input_manager.cpp src/input/input_manager.hpp src/io/file_manager.cpp src/io/file_manager.hpp src/io/xml_node.cpp src/io/xml_node.hpp src/io/xml_writer.cpp src/io/xml_writer.hpp src/items/attachment.cpp src/items/attachment.hpp src/items/attachment_manager.cpp src/items/attachment_manager.hpp src/items/attachment_plugin.hpp src/items/bowling.cpp src/items/bowling.hpp src/items/cake.cpp src/items/cake.hpp src/items/flyable.cpp src/items/flyable.hpp src/items/item.cpp src/items/item.hpp src/items/item_manager.cpp src/items/item_manager.hpp src/items/plunger.cpp src/items/plunger.hpp src/items/powerup.cpp src/items/powerup.hpp src/items/powerup_manager.cpp src/items/powerup_manager.hpp src/items/projectile_manager.cpp src/items/projectile_manager.hpp src/items/rubber_ball.cpp src/items/rubber_ball.hpp src/items/rubber_band.cpp src/items/rubber_band.hpp src/items/swatter.cpp src/items/swatter.hpp src/karts/controller/ai_base_controller.cpp src/karts/controller/ai_base_controller.hpp src/karts/controller/controller.cpp src/karts/controller/controller.hpp src/karts/controller/default_ai_controller.cpp src/karts/controller/default_ai_controller.hpp src/karts/controller/end_controller.cpp src/karts/controller/end_controller.hpp src/karts/controller/kart_control.hpp src/karts/controller/new_ai_controller.cpp src/karts/controller/new_ai_controller.hpp src/karts/controller/player_controller.cpp src/karts/controller/player_controller.hpp src/karts/emergency_animation.cpp src/karts/emergency_animation.hpp src/karts/kart.cpp src/karts/kart.hpp src/karts/kart_model.cpp src/karts/kart_model.hpp src/karts/kart_properties.cpp src/karts/kart_properties.hpp src/karts/kart_properties_manager.cpp src/karts/kart_properties_manager.hpp src/karts/kart_with_stats.cpp src/karts/kart_with_stats.hpp src/karts/max_speed.cpp src/karts/max_speed.hpp src/karts/moveable.cpp src/karts/moveable.hpp src/main.cpp src/main_loop.cpp src/main_loop.hpp src/modes/follow_the_leader.cpp src/modes/follow_the_leader.hpp src/modes/game_tutorial.cpp src/modes/game_tutorial.hpp src/modes/linear_world.cpp src/modes/linear_world.hpp src/modes/profile_world.cpp src/modes/profile_world.hpp src/modes/standard_race.cpp src/modes/standard_race.hpp src/modes/three_strikes_battle.cpp src/modes/three_strikes_battle.hpp src/modes/tutorial_race.cpp src/modes/tutorial_race.hpp src/modes/world.cpp src/modes/world.hpp src/modes/world_status.cpp src/modes/world_status.hpp src/modes/world_with_rank.cpp src/modes/world_with_rank.hpp src/network/character_confirm_message.hpp src/network/character_info_message.hpp src/network/character_selected_message.hpp src/network/connect_message.cpp src/network/connect_message.hpp src/network/flyable_info.hpp src/network/item_info.hpp src/network/kart_control_message.cpp src/network/kart_control_message.hpp src/network/kart_update_message.cpp src/network/kart_update_message.hpp src/network/message.cpp src/network/message.hpp src/network/network_kart.cpp src/network/network_kart.hpp src/network/network_manager.cpp src/network/network_manager.hpp src/network/num_players_message.hpp src/network/race_info_message.cpp src/network/race_info_message.hpp src/network/race_result_ack_message.hpp src/network/race_result_message.cpp src/network/race_result_message.hpp src/network/race_start_message.hpp src/network/race_state.cpp src/network/race_state.hpp src/network/remote_kart_info.hpp src/network/world_loaded_message.hpp src/physics/btKart.cpp src/physics/btKart.hpp src/physics/btKartRaycast.cpp src/physics/btKartRaycast.hpp src/physics/btUprightConstraint.cpp src/physics/btUprightConstraint.hpp src/physics/irr_debug_drawer.cpp src/physics/irr_debug_drawer.hpp src/physics/kart_motion_state.hpp src/physics/physical_object.cpp src/physics/physical_object.hpp src/physics/physics.cpp src/physics/physics.hpp src/physics/stk_dynamics_world.hpp src/physics/triangle_mesh.cpp src/physics/triangle_mesh.hpp src/physics/user_pointer.hpp src/race/grand_prix_data.cpp src/race/grand_prix_data.hpp src/race/grand_prix_manager.cpp src/race/grand_prix_manager.hpp src/race/highscore_manager.cpp src/race/highscore_manager.hpp src/race/highscores.cpp src/race/highscores.hpp src/race/history.cpp src/race/history.hpp src/race/race_manager.cpp src/race/race_manager.hpp src/replay/replay_base.cpp src/replay/replay_base.hpp src/replay/replay_buffer_tpl.hpp src/replay/replay_buffers.cpp src/replay/replay_buffers.hpp src/replay/replay_player.cpp src/replay/replay_player.hpp src/replay/replay_recorder.cpp src/replay/replay_recorder.hpp src/states_screens/addons_screen.cpp src/states_screens/addons_screen.hpp src/states_screens/arenas_screen.cpp src/states_screens/arenas_screen.hpp src/states_screens/challenges.cpp src/states_screens/challenges.hpp src/states_screens/credits.cpp src/states_screens/credits.hpp src/states_screens/dialogs/add_device_dialog.cpp src/states_screens/dialogs/add_device_dialog.hpp src/states_screens/dialogs/addons_loading.cpp src/states_screens/dialogs/addons_loading.hpp src/states_screens/dialogs/confirm_resolution_dialog.cpp src/states_screens/dialogs/confirm_resolution_dialog.hpp src/states_screens/dialogs/enter_player_name_dialog.cpp src/states_screens/dialogs/enter_player_name_dialog.hpp src/states_screens/dialogs/gp_info_dialog.cpp src/states_screens/dialogs/gp_info_dialog.hpp src/states_screens/dialogs/message_dialog.cpp src/states_screens/dialogs/message_dialog.hpp src/states_screens/dialogs/player_info_dialog.cpp src/states_screens/dialogs/player_info_dialog.hpp src/states_screens/dialogs/press_a_key_dialog.cpp src/states_screens/dialogs/press_a_key_dialog.hpp src/states_screens/dialogs/race_over_dialog.cpp src/states_screens/dialogs/race_over_dialog.hpp src/states_screens/dialogs/race_paused_dialog.cpp src/states_screens/dialogs/race_paused_dialog.hpp src/states_screens/dialogs/story_mode_new.cpp src/states_screens/dialogs/story_mode_new.hpp src/states_screens/dialogs/track_info_dialog.cpp src/states_screens/dialogs/track_info_dialog.hpp src/states_screens/feature_unlocked.cpp src/states_screens/feature_unlocked.hpp src/states_screens/grand_prix_lose.cpp src/states_screens/grand_prix_lose.hpp src/states_screens/grand_prix_win.cpp src/states_screens/grand_prix_win.hpp src/states_screens/help_screen_1.cpp src/states_screens/help_screen_1.hpp src/states_screens/help_screen_2.cpp src/states_screens/help_screen_2.hpp src/states_screens/help_screen_3.cpp src/states_screens/help_screen_3.hpp src/states_screens/help_screen_4.cpp src/states_screens/help_screen_4.hpp src/states_screens/kart_selection.cpp src/states_screens/kart_selection.hpp src/states_screens/main_menu_screen.cpp src/states_screens/main_menu_screen.hpp src/states_screens/minimal_race_gui.cpp src/states_screens/minimal_race_gui.hpp src/states_screens/options_screen_audio.cpp src/states_screens/options_screen_audio.hpp src/states_screens/options_screen_input.cpp src/states_screens/options_screen_input.hpp src/states_screens/options_screen_input2.cpp src/states_screens/options_screen_input2.hpp src/states_screens/options_screen_players.cpp src/states_screens/options_screen_players.hpp src/states_screens/options_screen_ui.cpp src/states_screens/options_screen_ui.hpp src/states_screens/options_screen_video.cpp src/states_screens/options_screen_video.hpp src/states_screens/race_gui.cpp src/states_screens/race_gui.hpp src/states_screens/race_gui_base.cpp src/states_screens/race_gui_base.hpp src/states_screens/race_result_gui.cpp src/states_screens/race_result_gui.hpp src/states_screens/race_setup_screen.cpp src/states_screens/race_setup_screen.hpp src/states_screens/state_manager.cpp src/states_screens/state_manager.hpp src/states_screens/story_mode_lobby.cpp src/states_screens/story_mode_lobby.hpp src/states_screens/tracks_screen.cpp src/states_screens/tracks_screen.hpp src/states_screens/tutorial_screen.cpp src/states_screens/tutorial_screen.hpp src/tinygettext/dictionary.cpp src/tinygettext/dictionary.hpp src/tinygettext/dictionary_manager.cpp src/tinygettext/dictionary_manager.hpp src/tinygettext/file_system.hpp src/tinygettext/iconv.cpp src/tinygettext/iconv.hpp src/tinygettext/language.cpp src/tinygettext/language.hpp src/tinygettext/log.cpp src/tinygettext/log.hpp src/tinygettext/log_stream.hpp src/tinygettext/plural_forms.cpp src/tinygettext/plural_forms.hpp src/tinygettext/po_parser.cpp src/tinygettext/po_parser.hpp src/tinygettext/stk_file_system.cpp src/tinygettext/stk_file_system.hpp src/tinygettext/tinygettext.cpp src/tinygettext/tinygettext.hpp src/tracks/ambient_light_sphere.cpp src/tracks/ambient_light_sphere.hpp src/tracks/bezier_curve.cpp src/tracks/bezier_curve.hpp src/tracks/check_lap.cpp src/tracks/check_lap.hpp src/tracks/check_line.cpp src/tracks/check_line.hpp src/tracks/check_manager.cpp src/tracks/check_manager.hpp src/tracks/check_sphere.cpp src/tracks/check_sphere.hpp src/tracks/check_structure.cpp src/tracks/check_structure.hpp src/tracks/graph_node.cpp src/tracks/graph_node.hpp src/tracks/lod_node_loader.cpp src/tracks/lod_node_loader.hpp src/tracks/quad.cpp src/tracks/quad.hpp src/tracks/quad_graph.cpp src/tracks/quad_graph.hpp src/tracks/quad_set.cpp src/tracks/quad_set.hpp src/tracks/terrain_info.cpp src/tracks/terrain_info.hpp src/tracks/track.cpp src/tracks/track.hpp src/tracks/track_manager.cpp src/tracks/track_manager.hpp src/tracks/track_object.cpp src/tracks/track_object.hpp src/tracks/track_object_manager.cpp src/tracks/track_object_manager.hpp src/tracks/track_sector.cpp src/tracks/track_sector.hpp src/tutorial/tutorial.cpp src/tutorial/tutorial.hpp src/tutorial/tutorial_data.cpp src/tutorial/tutorial_data.hpp src/tutorial/tutorial_manager.cpp src/tutorial/tutorial_manager.hpp src/utils/aligned_array.hpp src/utils/constants.cpp src/utils/constants.hpp src/utils/leak_check.cpp src/utils/leak_check.hpp src/utils/no_copy.hpp src/utils/profiler.cpp src/utils/profiler.hpp src/utils/ptr_vector.hpp src/utils/random_generator.cpp src/utils/random_generator.hpp src/utils/string_utils.cpp src/utils/string_utils.hpp src/utils/synchronised.hpp src/utils/time.hpp src/utils/translation.cpp src/utils/translation.hpp src/utils/utf8/checked.h src/utils/utf8/core.h src/utils/utf8/unchecked.h src/utils/utf8.h src/utils/vec3.cpp src/utils/vec3.hpp) +set( SRCS ${SRCS} src/addons/addon.cpp src/addons/addon.hpp src/addons/addons_manager.cpp src/addons/addons_manager.hpp src/addons/dummy_network_http.hpp src/addons/inetwork_http.hpp src/addons/network_http.cpp src/addons/network_http.hpp src/addons/news_manager.cpp src/addons/news_manager.hpp src/addons/request.cpp src/addons/request.hpp src/addons/zip.cpp src/addons/zip.hpp src/animations/animation_base.cpp src/animations/animation_base.hpp src/animations/billboard_animation.cpp src/animations/billboard_animation.hpp src/animations/ipo.cpp src/animations/ipo.hpp src/animations/three_d_animation.cpp src/animations/three_d_animation.hpp src/audio/dummy_sfx.hpp src/audio/music.hpp src/audio/music_dummy.hpp src/audio/music_information.cpp src/audio/music_information.hpp src/audio/music_manager.cpp src/audio/music_manager.hpp src/audio/music_ogg.cpp src/audio/music_ogg.hpp src/audio/sfx_base.hpp src/audio/sfx_buffer.cpp src/audio/sfx_buffer.hpp src/audio/sfx_manager.cpp src/audio/sfx_manager.hpp src/audio/sfx_openal.cpp src/audio/sfx_openal.hpp src/challenges/challenge.cpp src/challenges/challenge.hpp src/challenges/challenge_data.cpp src/challenges/challenge_data.hpp src/challenges/game_slot.cpp src/challenges/game_slot.hpp src/challenges/unlock_manager.cpp src/challenges/unlock_manager.hpp src/config/device_config.cpp src/config/device_config.hpp src/config/player.hpp src/config/stk_config.cpp src/config/stk_config.hpp src/config/user_config.cpp src/config/user_config.hpp src/enet/callbacks.c src/enet/compress.c src/enet/host.c src/enet/include/enet/callbacks.h src/enet/include/enet/enet.h src/enet/include/enet/list.h src/enet/include/enet/protocol.h src/enet/include/enet/time.h src/enet/include/enet/types.h src/enet/include/enet/unix.h src/enet/include/enet/utility.h src/enet/include/enet/win32.h src/enet/list.c src/enet/packet.c src/enet/peer.c src/enet/protocol.c src/enet/unix.c src/enet/win32.c src/graphics/camera.cpp src/graphics/camera.hpp src/graphics/CBatchingMesh.cpp src/graphics/CBatchingMesh.hpp src/graphics/explosion.cpp src/graphics/explosion.hpp src/graphics/hardware_skinning.cpp src/graphics/hardware_skinning.hpp src/graphics/hit_effect.hpp src/graphics/hit_sfx.cpp src/graphics/hit_sfx.hpp src/graphics/irr_driver.cpp src/graphics/irr_driver.hpp src/graphics/lod_node.cpp src/graphics/lod_node.hpp src/graphics/material.cpp src/graphics/material.hpp src/graphics/material_manager.cpp src/graphics/material_manager.hpp src/graphics/mesh_tools.cpp src/graphics/mesh_tools.hpp src/graphics/moving_texture.cpp src/graphics/moving_texture.hpp src/graphics/particle_emitter.cpp src/graphics/particle_emitter.hpp src/graphics/particle_kind.cpp src/graphics/particle_kind.hpp src/graphics/particle_kind_manager.cpp src/graphics/particle_kind_manager.hpp src/graphics/per_camera_node.cpp src/graphics/per_camera_node.hpp src/graphics/post_processing.cpp src/graphics/post_processing.hpp src/graphics/rain.cpp src/graphics/rain.hpp src/graphics/referee.cpp src/graphics/referee.hpp src/graphics/shadow.cpp src/graphics/shadow.hpp src/graphics/skid_marks.cpp src/graphics/skid_marks.hpp src/graphics/slip_stream.cpp src/graphics/slip_stream.hpp src/graphics/stars.cpp src/graphics/stars.hpp src/guiengine/abstract_state_manager.cpp src/guiengine/abstract_state_manager.hpp src/guiengine/abstract_top_level_container.cpp src/guiengine/abstract_top_level_container.hpp src/guiengine/CGUISpriteBank.cpp src/guiengine/CGUISpriteBank.h src/guiengine/engine.cpp src/guiengine/engine.hpp src/guiengine/event_handler.cpp src/guiengine/event_handler.hpp src/guiengine/layout_manager.cpp src/guiengine/layout_manager.hpp src/guiengine/modaldialog.cpp src/guiengine/modaldialog.hpp src/guiengine/scalable_font.cpp src/guiengine/scalable_font.hpp src/guiengine/screen.cpp src/guiengine/screen.hpp src/guiengine/screen_loader.cpp src/guiengine/skin.cpp src/guiengine/skin.hpp src/guiengine/widget.cpp src/guiengine/widget.hpp src/guiengine/widgets/bubble_widget.cpp src/guiengine/widgets/bubble_widget.hpp src/guiengine/widgets/button_widget.cpp src/guiengine/widgets/button_widget.hpp src/guiengine/widgets/CGUIEditBox.cpp src/guiengine/widgets/CGUIEditBox.h src/guiengine/widgets/check_box_widget.cpp src/guiengine/widgets/check_box_widget.hpp src/guiengine/widgets/dynamic_ribbon_widget.cpp src/guiengine/widgets/dynamic_ribbon_widget.hpp src/guiengine/widgets/icon_button_widget.cpp src/guiengine/widgets/icon_button_widget.hpp src/guiengine/widgets/label_widget.cpp src/guiengine/widgets/label_widget.hpp src/guiengine/widgets/list_widget.cpp src/guiengine/widgets/list_widget.hpp src/guiengine/widgets/model_view_widget.cpp src/guiengine/widgets/model_view_widget.hpp src/guiengine/widgets/progress_bar_widget.cpp src/guiengine/widgets/progress_bar_widget.hpp src/guiengine/widgets/ribbon_widget.cpp src/guiengine/widgets/ribbon_widget.hpp src/guiengine/widgets/spinner_widget.cpp src/guiengine/widgets/spinner_widget.hpp src/guiengine/widgets/text_box_widget.cpp src/guiengine/widgets/text_box_widget.hpp src/guiengine/widgets.hpp src/input/binding.cpp src/input/binding.hpp src/input/device_manager.cpp src/input/device_manager.hpp src/input/input.hpp src/input/input_device.cpp src/input/input_device.hpp src/input/input_manager.cpp src/input/input_manager.hpp src/io/file_manager.cpp src/io/file_manager.hpp src/io/xml_node.cpp src/io/xml_node.hpp src/io/xml_writer.cpp src/io/xml_writer.hpp src/items/attachment.cpp src/items/attachment.hpp src/items/attachment_manager.cpp src/items/attachment_manager.hpp src/items/attachment_plugin.hpp src/items/bowling.cpp src/items/bowling.hpp src/items/cake.cpp src/items/cake.hpp src/items/flyable.cpp src/items/flyable.hpp src/items/item.cpp src/items/item.hpp src/items/item_manager.cpp src/items/item_manager.hpp src/items/plunger.cpp src/items/plunger.hpp src/items/powerup.cpp src/items/powerup.hpp src/items/powerup_manager.cpp src/items/powerup_manager.hpp src/items/projectile_manager.cpp src/items/projectile_manager.hpp src/items/rubber_ball.cpp src/items/rubber_ball.hpp src/items/rubber_band.cpp src/items/rubber_band.hpp src/items/swatter.cpp src/items/swatter.hpp src/karts/controller/ai_base_controller.cpp src/karts/controller/ai_base_controller.hpp src/karts/controller/controller.cpp src/karts/controller/controller.hpp src/karts/controller/default_ai_controller.cpp src/karts/controller/default_ai_controller.hpp src/karts/controller/end_controller.cpp src/karts/controller/end_controller.hpp src/karts/controller/kart_control.hpp src/karts/controller/new_ai_controller.cpp src/karts/controller/new_ai_controller.hpp src/karts/controller/player_controller.cpp src/karts/controller/player_controller.hpp src/karts/emergency_animation.cpp src/karts/emergency_animation.hpp src/karts/kart.cpp src/karts/kart.hpp src/karts/kart_model.cpp src/karts/kart_model.hpp src/karts/kart_properties.cpp src/karts/kart_properties.hpp src/karts/kart_properties_manager.cpp src/karts/kart_properties_manager.hpp src/karts/kart_with_stats.cpp src/karts/kart_with_stats.hpp src/karts/max_speed.cpp src/karts/max_speed.hpp src/karts/moveable.cpp src/karts/moveable.hpp src/main.cpp src/main_loop.cpp src/main_loop.hpp src/modes/follow_the_leader.cpp src/modes/follow_the_leader.hpp src/modes/game_tutorial.cpp src/modes/game_tutorial.hpp src/modes/linear_world.cpp src/modes/linear_world.hpp src/modes/profile_world.cpp src/modes/profile_world.hpp src/modes/standard_race.cpp src/modes/standard_race.hpp src/modes/three_strikes_battle.cpp src/modes/three_strikes_battle.hpp src/modes/tutorial_race.cpp src/modes/tutorial_race.hpp src/modes/world.cpp src/modes/world.hpp src/modes/world_status.cpp src/modes/world_status.hpp src/modes/world_with_rank.cpp src/modes/world_with_rank.hpp src/network/character_confirm_message.hpp src/network/character_info_message.hpp src/network/character_selected_message.hpp src/network/connect_message.cpp src/network/connect_message.hpp src/network/flyable_info.hpp src/network/item_info.hpp src/network/kart_control_message.cpp src/network/kart_control_message.hpp src/network/kart_update_message.cpp src/network/kart_update_message.hpp src/network/message.cpp src/network/message.hpp src/network/network_kart.cpp src/network/network_kart.hpp src/network/network_manager.cpp src/network/network_manager.hpp src/network/num_players_message.hpp src/network/race_info_message.cpp src/network/race_info_message.hpp src/network/race_result_ack_message.hpp src/network/race_result_message.cpp src/network/race_result_message.hpp src/network/race_start_message.hpp src/network/race_state.cpp src/network/race_state.hpp src/network/remote_kart_info.hpp src/network/world_loaded_message.hpp src/physics/btKart.cpp src/physics/btKart.hpp src/physics/btKartRaycast.cpp src/physics/btKartRaycast.hpp src/physics/btUprightConstraint.cpp src/physics/btUprightConstraint.hpp src/physics/irr_debug_drawer.cpp src/physics/irr_debug_drawer.hpp src/physics/kart_motion_state.hpp src/physics/physical_object.cpp src/physics/physical_object.hpp src/physics/physics.cpp src/physics/physics.hpp src/physics/stk_dynamics_world.hpp src/physics/triangle_mesh.cpp src/physics/triangle_mesh.hpp src/physics/user_pointer.hpp src/race/grand_prix_data.cpp src/race/grand_prix_data.hpp src/race/grand_prix_manager.cpp src/race/grand_prix_manager.hpp src/race/highscore_manager.cpp src/race/highscore_manager.hpp src/race/highscores.cpp src/race/highscores.hpp src/race/history.cpp src/race/history.hpp src/race/race_manager.cpp src/race/race_manager.hpp src/replay/replay_base.cpp src/replay/replay_base.hpp src/replay/replay_buffer_tpl.hpp src/replay/replay_buffers.cpp src/replay/replay_buffers.hpp src/replay/replay_player.cpp src/replay/replay_player.hpp src/replay/replay_recorder.cpp src/replay/replay_recorder.hpp src/states_screens/addons_screen.cpp src/states_screens/addons_screen.hpp src/states_screens/arenas_screen.cpp src/states_screens/arenas_screen.hpp src/states_screens/challenges.cpp src/states_screens/challenges.hpp src/states_screens/credits.cpp src/states_screens/credits.hpp src/states_screens/dialogs/add_device_dialog.cpp src/states_screens/dialogs/add_device_dialog.hpp src/states_screens/dialogs/addons_loading.cpp src/states_screens/dialogs/addons_loading.hpp src/states_screens/dialogs/confirm_resolution_dialog.cpp src/states_screens/dialogs/confirm_resolution_dialog.hpp src/states_screens/dialogs/enter_player_name_dialog.cpp src/states_screens/dialogs/enter_player_name_dialog.hpp src/states_screens/dialogs/gp_info_dialog.cpp src/states_screens/dialogs/gp_info_dialog.hpp src/states_screens/dialogs/message_dialog.cpp src/states_screens/dialogs/message_dialog.hpp src/states_screens/dialogs/player_info_dialog.cpp src/states_screens/dialogs/player_info_dialog.hpp src/states_screens/dialogs/press_a_key_dialog.cpp src/states_screens/dialogs/press_a_key_dialog.hpp src/states_screens/dialogs/race_over_dialog.cpp src/states_screens/dialogs/race_over_dialog.hpp src/states_screens/dialogs/race_paused_dialog.cpp src/states_screens/dialogs/race_paused_dialog.hpp src/states_screens/dialogs/story_mode_new.cpp src/states_screens/dialogs/story_mode_new.hpp src/states_screens/dialogs/track_info_dialog.cpp src/states_screens/dialogs/track_info_dialog.hpp src/states_screens/feature_unlocked.cpp src/states_screens/feature_unlocked.hpp src/states_screens/grand_prix_lose.cpp src/states_screens/grand_prix_lose.hpp src/states_screens/grand_prix_win.cpp src/states_screens/grand_prix_win.hpp src/states_screens/help_screen_1.cpp src/states_screens/help_screen_1.hpp src/states_screens/help_screen_2.cpp src/states_screens/help_screen_2.hpp src/states_screens/help_screen_3.cpp src/states_screens/help_screen_3.hpp src/states_screens/help_screen_4.cpp src/states_screens/help_screen_4.hpp src/states_screens/kart_selection.cpp src/states_screens/kart_selection.hpp src/states_screens/main_menu_screen.cpp src/states_screens/main_menu_screen.hpp src/states_screens/minimal_race_gui.cpp src/states_screens/minimal_race_gui.hpp src/states_screens/options_screen_audio.cpp src/states_screens/options_screen_audio.hpp src/states_screens/options_screen_input.cpp src/states_screens/options_screen_input.hpp src/states_screens/options_screen_input2.cpp src/states_screens/options_screen_input2.hpp src/states_screens/options_screen_players.cpp src/states_screens/options_screen_players.hpp src/states_screens/options_screen_ui.cpp src/states_screens/options_screen_ui.hpp src/states_screens/options_screen_video.cpp src/states_screens/options_screen_video.hpp src/states_screens/race_gui.cpp src/states_screens/race_gui.hpp src/states_screens/race_gui_base.cpp src/states_screens/race_gui_base.hpp src/states_screens/race_result_gui.cpp src/states_screens/race_result_gui.hpp src/states_screens/race_setup_screen.cpp src/states_screens/race_setup_screen.hpp src/states_screens/state_manager.cpp src/states_screens/state_manager.hpp src/states_screens/story_mode_lobby.cpp src/states_screens/story_mode_lobby.hpp src/states_screens/tracks_screen.cpp src/states_screens/tracks_screen.hpp src/states_screens/tutorial_screen.cpp src/states_screens/tutorial_screen.hpp src/tinygettext/dictionary.cpp src/tinygettext/dictionary.hpp src/tinygettext/dictionary_manager.cpp src/tinygettext/dictionary_manager.hpp src/tinygettext/file_system.hpp src/tinygettext/iconv.cpp src/tinygettext/iconv.hpp src/tinygettext/language.cpp src/tinygettext/language.hpp src/tinygettext/log.cpp src/tinygettext/log.hpp src/tinygettext/log_stream.hpp src/tinygettext/plural_forms.cpp src/tinygettext/plural_forms.hpp src/tinygettext/po_parser.cpp src/tinygettext/po_parser.hpp src/tinygettext/stk_file_system.cpp src/tinygettext/stk_file_system.hpp src/tinygettext/tinygettext.cpp src/tinygettext/tinygettext.hpp src/tracks/ambient_light_sphere.cpp src/tracks/ambient_light_sphere.hpp src/tracks/bezier_curve.cpp src/tracks/bezier_curve.hpp src/tracks/check_lap.cpp src/tracks/check_lap.hpp src/tracks/check_line.cpp src/tracks/check_line.hpp src/tracks/check_manager.cpp src/tracks/check_manager.hpp src/tracks/check_sphere.cpp src/tracks/check_sphere.hpp src/tracks/check_structure.cpp src/tracks/check_structure.hpp src/tracks/graph_node.cpp src/tracks/graph_node.hpp src/tracks/lod_node_loader.cpp src/tracks/lod_node_loader.hpp src/tracks/quad.cpp src/tracks/quad.hpp src/tracks/quad_graph.cpp src/tracks/quad_graph.hpp src/tracks/quad_set.cpp src/tracks/quad_set.hpp src/tracks/terrain_info.cpp src/tracks/terrain_info.hpp src/tracks/track.cpp src/tracks/track.hpp src/tracks/track_manager.cpp src/tracks/track_manager.hpp src/tracks/track_object.cpp src/tracks/track_object.hpp src/tracks/track_object_manager.cpp src/tracks/track_object_manager.hpp src/tracks/track_sector.cpp src/tracks/track_sector.hpp src/tutorial/tutorial.cpp src/tutorial/tutorial.hpp src/tutorial/tutorial_data.cpp src/tutorial/tutorial_data.hpp src/tutorial/tutorial_manager.cpp src/tutorial/tutorial_manager.hpp src/utils/aligned_array.hpp src/utils/constants.cpp src/utils/constants.hpp src/utils/leak_check.cpp src/utils/leak_check.hpp src/utils/no_copy.hpp src/utils/profiler.cpp src/utils/profiler.hpp src/utils/ptr_vector.hpp src/utils/random_generator.cpp src/utils/random_generator.hpp src/utils/string_utils.cpp src/utils/string_utils.hpp src/utils/synchronised.hpp src/utils/time.hpp src/utils/translation.cpp src/utils/translation.hpp src/utils/utf8/checked.h src/utils/utf8/core.h src/utils/utf8/unchecked.h src/utils/utf8.h src/utils/vec3.cpp src/utils/vec3.hpp) if (APPLE) # icon files to copy in the bundle diff --git a/src/challenges/challenge.cpp b/src/challenges/challenge.cpp index 38bf9efc7..2d1b9591d 100644 --- a/src/challenges/challenge.cpp +++ b/src/challenges/challenge.cpp @@ -21,7 +21,9 @@ #include +#include "challenges/challenge_data.hpp" #include "io/xml_node.hpp" +#include "io/xml_writer.hpp" #include "karts/kart_properties_manager.hpp" #include "karts/kart_properties.hpp" #include "race/grand_prix_manager.hpp" @@ -31,141 +33,12 @@ #include "utils/translation.hpp" #include "utils/string_utils.hpp" -const irr::core::stringw Challenge::UnlockableFeature::getUnlockedMessage() const -{ - switch (m_type) - { - case UNLOCK_TRACK: - { // {} avoids compiler warning - const Track* track = track_manager->getTrack(m_name); - - // shouldn't happen but let's avoid crashes as much as possible... - if (track == NULL) return irr::core::stringw( L"????" ); - - return _("New track '%s' now available", core::stringw(track->getName())); - break; - } - case UNLOCK_MODE: - { - return _("New game mode '%s' now available", m_user_name); - } - case UNLOCK_GP: - { - const GrandPrixData* gp = grand_prix_manager->getGrandPrix(m_name); - - // shouldn't happen but let's avoid crashes as much as possible... - if (gp == NULL) return irr::core::stringw( L"????" ); - - const irr::core::stringw& gp_user_name = gp->getName(); - return _("New Grand Prix '%s' now available", gp_user_name); - } - case UNLOCK_DIFFICULTY: - { - return _("New difficulty '%s' now available", m_user_name); - } - case UNLOCK_KART: - { - const KartProperties* kp = - kart_properties_manager->getKart(m_name); - - // shouldn't happen but let's avoid crashes as much as possible... - if (kp == NULL) return irr::core::stringw( L"????" ); - - return _("New kart '%s' now available", core::stringw(kp->getName())); - } - default: - assert(false); - return L""; - } // switch -} // UnlockableFeature::getUnlockedMessage - //----------------------------------------------------------------------------- -/** Sets that the given track will be unlocked if this challenge - * is unlocked. - * \param track_name Name of the track to unlock. - */ -void Challenge::addUnlockTrackReward(const std::string &track_name) -{ - - if (track_manager->getTrack(track_name) == NULL) - { - throw std::runtime_error(StringUtils::insertValues("Challenge refers to unknown track <%s>", track_name.c_str())); - } - - UnlockableFeature feature; - feature.m_name = track_name; - feature.m_type = UNLOCK_TRACK; - m_feature.push_back(feature); -} // addUnlockTrackReward - -//----------------------------------------------------------------------------- - -void Challenge::addUnlockModeReward(const std::string &internal_mode_name, - const irr::core::stringw &user_mode_name) -{ - UnlockableFeature feature; - feature.m_name = internal_mode_name; - feature.m_type = UNLOCK_MODE; - feature.m_user_name = user_mode_name; - m_feature.push_back(feature); -} // addUnlockModeReward - -//----------------------------------------------------------------------------- -void Challenge::addUnlockGPReward(const std::string &gp_name) -{ - if (grand_prix_manager->getGrandPrix(gp_name) == NULL) - { - throw std::runtime_error(StringUtils::insertValues("Challenge refers to unknown Grand Prix <%s>", gp_name.c_str())); - } - - UnlockableFeature feature; - - feature.m_name = gp_name.c_str(); - - feature.m_type = UNLOCK_GP; - m_feature.push_back(feature); -} // addUnlockGPReward - -//----------------------------------------------------------------------------- - -void Challenge::addUnlockDifficultyReward(const std::string &internal_name, - const irr::core::stringw &user_name) -{ - UnlockableFeature feature; - feature.m_name = internal_name; - feature.m_type = UNLOCK_DIFFICULTY; - feature.m_user_name = user_name; - m_feature.push_back(feature); -} // addUnlockDifficultyReward - -//----------------------------------------------------------------------------- -void Challenge::addUnlockKartReward(const std::string &internal_name, - const irr::core::stringw &user_name) -{ - try - { - kart_properties_manager->getKartId(internal_name); - } - catch (std::exception& e) - { - (void)e; // avoid compiler warning - throw std::runtime_error(StringUtils::insertValues("Challenge refers to unknown kart <%s>", internal_name.c_str())); - } - - UnlockableFeature feature; - feature.m_name = internal_name; - feature.m_type = UNLOCK_KART; - feature.m_user_name = user_name; - m_feature.push_back(feature); -} // addUnlockKartReward - -//----------------------------------------------------------------------------- -/** Loads the state for a challenge object (esp. m_state), and calls the - * virtual function loadAdditionalInfo for additional information +/** Loads the state for a challenge object (esp. m_state) */ void Challenge::load(const XMLNode* challengesNode) { - const XMLNode* node = challengesNode->getNode( getId() ); + const XMLNode* node = challengesNode->getNode( m_data->getId() ); if(node == NULL) return; // See if the challenge is solved (it's activated later from the @@ -173,15 +46,12 @@ void Challenge::load(const XMLNode* challengesNode) bool finished=false; node->get("solved", &finished); m_state = finished ? CH_SOLVED : CH_INACTIVE; - - if(!finished) loadAdditionalInfo(node); } // load //----------------------------------------------------------------------------- -void Challenge::save(std::ofstream& writer) +void Challenge::save(XMLWriter& writer) { - writer << " <" << getId() << " solved=\"" - << (isSolved() ? "true" : "false") << "\""; - if(!isSolved()) saveAdditionalInfo(writer); - writer << " />\n"; + writer << L" <" << core::stringw(m_data->getId().c_str()) << L" solved=\"" + << (isSolved() ? L"true" : L"false") << L"\""; + writer << L" />\n"; } // save diff --git a/src/challenges/challenge.hpp b/src/challenges/challenge.hpp index 4c0037f18..d53fc5585 100644 --- a/src/challenges/challenge.hpp +++ b/src/challenges/challenge.hpp @@ -35,92 +35,29 @@ #include "utils/translation.hpp" class XMLNode; - +class XMLWriter; +class ChallengeData; /** - * \brief A class for all challenges + * \brief The state of a challenge for one player * \ingroup challenges */ class Challenge : public NoCopy { -public: - enum REWARD_TYPE {UNLOCK_TRACK, - UNLOCK_GP, - UNLOCK_MODE, - UNLOCK_KART, - UNLOCK_DIFFICULTY}; - // ------------------------------------------------------------------------ - class UnlockableFeature - { - public: - - std::string m_name; // internal name - irr::core::stringw m_user_name; // not all types of feature have one - REWARD_TYPE m_type; - - const irr::core::stringw getUnlockedMessage() const; - }; // UnlockableFeature - // ------------------------------------------------------------------------ - private: enum {CH_INACTIVE, // challenge not yet possible CH_ACTIVE, // challenge possible, but not yet solved CH_SOLVED} m_state; // challenge was solved - /** Short, internal name for this challenge. */ - std::string m_id; - /** Name used in menu for this challenge. */ - irr::core::stringw m_name; - /** Message the user gets when the feature is not yet unlocked. */ - irr::core::stringw m_challenge_description; - /** Features to unlock. */ - std::vector m_feature; - /** What needs to be done before accessing this challenge. */ - std::vector m_prerequisites; + ChallengeData* m_data; + public: - Challenge(const std::string &id, const std::string &name); - Challenge() : m_state(CH_INACTIVE), m_id(""), m_name("") - { } + Challenge(ChallengeData* data) : m_state(CH_INACTIVE) + { m_data = data; } virtual ~Challenge() {}; - void addUnlockTrackReward(const std::string &track_name); - void addUnlockModeReward(const std::string &internal_mode_name, - const irr::core::stringw &user_mode_name); - void addUnlockGPReward(const std::string &gp_name); - void addUnlockDifficultyReward(const std::string &internal_name, - const irr::core::stringw &user_name); - void addUnlockKartReward(const std::string &internal_name, - const irr::core::stringw &user_name); void load(const XMLNode* config); - void save(std::ofstream& writer); - // These functions are meant for customisation, e.g. load/save - // additional state information specific to the challenge - virtual void loadAdditionalInfo(const XMLNode* config) {}; - virtual void saveAdditionalInfo(std::ofstream& writer) {}; - // ------------------------------------------------------------------------ - /** Returns the id of the challenge. */ - const std::string &getId() const { return m_id; } - // ------------------------------------------------------------------------ - /** Returns the name of the challenge. */ - const irr::core::stringw getName() const - { return irr::core::stringw(_(m_name.c_str())); } - // ------------------------------------------------------------------------ - /** Sets the name of the challenge. */ - void setName(const irr::core::stringw & s) { m_name = s; } - // ------------------------------------------------------------------------ - /** Sets the id of this challenge. */ - void setId(const std::string& s) { m_id = s; } - // ------------------------------------------------------------------------ - const std::vector& - getFeatures() const { return m_feature; } - // ------------------------------------------------------------------------ - void setChallengeDescription(const irr::core::stringw& d) - {m_challenge_description=d; } - // ------------------------------------------------------------------------ - const irr::core::stringw - getChallengeDescription() const - {return _(m_challenge_description.c_str()); } - // ------------------------------------------------------------------------ - void addDependency(const std::string id) {m_prerequisites.push_back(id);} + void save(XMLWriter& writer); + // ------------------------------------------------------------------------ bool isSolved() const {return m_state==CH_SOLVED; } // ------------------------------------------------------------------------ @@ -130,9 +67,6 @@ public: // ------------------------------------------------------------------------ void setActive() {m_state = CH_ACTIVE; } // ------------------------------------------------------------------------ - const std::vector& - getPrerequisites() const {return m_prerequisites; } - // ------------------------------------------------------------------------ /** These functions are called when a race is finished. It allows * the challenge to unlock features (when returning true), otherwise * the feature remains locked. */ @@ -142,11 +76,7 @@ public: * the challenge to unlock features (when returning true), otherwise * the feature remains locked. */ virtual bool grandPrixFinished() {return false; } - // ------------------------------------------------------------------------ - /** Sets the right parameters in RaceManager to try this challenge */ - virtual void setRace() const = 0; - // ------------------------------------------------------------------------ - /** Checks if a challenge is valid. */ - virtual void check() const = 0; + + ChallengeData* getData() { return m_data; } }; #endif diff --git a/src/challenges/challenge_data.cpp b/src/challenges/challenge_data.cpp index 7ed1e20dd..2c884ca0f 100644 --- a/src/challenges/challenge_data.cpp +++ b/src/challenges/challenge_data.cpp @@ -145,11 +145,11 @@ ChallengeData::ChallengeData(const std::string& filename) if (grand_prix_manager->getGrandPrix(m_gp_id) == NULL) error("gp"); } - getUnlocks(root, "unlock-track", Challenge::UNLOCK_TRACK); - getUnlocks(root, "unlock-gp", Challenge::UNLOCK_GP ); - getUnlocks(root, "unlock-mode", Challenge::UNLOCK_MODE ); - getUnlocks(root, "unlock-difficulty", Challenge::UNLOCK_DIFFICULTY); - getUnlocks(root, "unlock-kart", Challenge::UNLOCK_KART); + getUnlocks(root, "unlock-track", ChallengeData::UNLOCK_TRACK); + getUnlocks(root, "unlock-gp", ChallengeData::UNLOCK_GP ); + getUnlocks(root, "unlock-mode", ChallengeData::UNLOCK_MODE ); + getUnlocks(root, "unlock-difficulty", ChallengeData::UNLOCK_DIFFICULTY); + getUnlocks(root, "unlock-kart", ChallengeData::UNLOCK_KART); if (getFeatures().size() == 0) { @@ -349,3 +349,134 @@ bool ChallengeData::grandPrixFinished() return true; } // grandPrixFinished + +// ---------------------------------------------------------------------------- + +const irr::core::stringw ChallengeData::UnlockableFeature::getUnlockedMessage() const +{ + switch (m_type) + { + case UNLOCK_TRACK: + { // {} avoids compiler warning + const Track* track = track_manager->getTrack(m_name); + + // shouldn't happen but let's avoid crashes as much as possible... + if (track == NULL) return irr::core::stringw( L"????" ); + + return _("New track '%s' now available", core::stringw(track->getName())); + break; + } + case UNLOCK_MODE: + { + return _("New game mode '%s' now available", m_user_name); + } + case UNLOCK_GP: + { + const GrandPrixData* gp = grand_prix_manager->getGrandPrix(m_name); + + // shouldn't happen but let's avoid crashes as much as possible... + if (gp == NULL) return irr::core::stringw( L"????" ); + + const irr::core::stringw& gp_user_name = gp->getName(); + return _("New Grand Prix '%s' now available", gp_user_name); + } + case UNLOCK_DIFFICULTY: + { + return _("New difficulty '%s' now available", m_user_name); + } + case UNLOCK_KART: + { + const KartProperties* kp = + kart_properties_manager->getKart(m_name); + + // shouldn't happen but let's avoid crashes as much as possible... + if (kp == NULL) return irr::core::stringw( L"????" ); + + return _("New kart '%s' now available", core::stringw(kp->getName())); + } + default: + assert(false); + return L""; + } // switch +} // UnlockableFeature::getUnlockedMessage + +//----------------------------------------------------------------------------- +/** Sets that the given track will be unlocked if this challenge + * is unlocked. + * \param track_name Name of the track to unlock. + */ +void ChallengeData::addUnlockTrackReward(const std::string &track_name) +{ + + if (track_manager->getTrack(track_name) == NULL) + { + throw std::runtime_error(StringUtils::insertValues("Challenge refers to unknown track <%s>", track_name.c_str())); + } + + UnlockableFeature feature; + feature.m_name = track_name; + feature.m_type = UNLOCK_TRACK; + m_feature.push_back(feature); +} // addUnlockTrackReward + +//----------------------------------------------------------------------------- + +void ChallengeData::addUnlockModeReward(const std::string &internal_mode_name, + const irr::core::stringw &user_mode_name) +{ + UnlockableFeature feature; + feature.m_name = internal_mode_name; + feature.m_type = UNLOCK_MODE; + feature.m_user_name = user_mode_name; + m_feature.push_back(feature); +} // addUnlockModeReward + +//----------------------------------------------------------------------------- +void ChallengeData::addUnlockGPReward(const std::string &gp_name) +{ + if (grand_prix_manager->getGrandPrix(gp_name) == NULL) + { + throw std::runtime_error(StringUtils::insertValues("Challenge refers to unknown Grand Prix <%s>", gp_name.c_str())); + } + + UnlockableFeature feature; + + feature.m_name = gp_name.c_str(); + + feature.m_type = UNLOCK_GP; + m_feature.push_back(feature); +} // addUnlockGPReward + +//----------------------------------------------------------------------------- + +void ChallengeData::addUnlockDifficultyReward(const std::string &internal_name, + const irr::core::stringw &user_name) +{ + UnlockableFeature feature; + feature.m_name = internal_name; + feature.m_type = UNLOCK_DIFFICULTY; + feature.m_user_name = user_name; + m_feature.push_back(feature); +} // addUnlockDifficultyReward + +//----------------------------------------------------------------------------- +void ChallengeData::addUnlockKartReward(const std::string &internal_name, + const irr::core::stringw &user_name) +{ + try + { + kart_properties_manager->getKartId(internal_name); + } + catch (std::exception& e) + { + (void)e; // avoid compiler warning + throw std::runtime_error(StringUtils::insertValues("Challenge refers to unknown kart <%s>", internal_name.c_str())); + } + + UnlockableFeature feature; + feature.m_name = internal_name; + feature.m_type = UNLOCK_KART; + feature.m_user_name = user_name; + m_feature.push_back(feature); +} // addUnlockKartReward + diff --git a/src/challenges/challenge_data.hpp b/src/challenges/challenge_data.hpp index 3a1eeab1b..a7b0df071 100644 --- a/src/challenges/challenge_data.hpp +++ b/src/challenges/challenge_data.hpp @@ -29,10 +29,30 @@ #include "race/race_manager.hpp" /** + * \brief the description of one challenge * \ingroup challenges */ -class ChallengeData : public Challenge +class ChallengeData { +public: + enum REWARD_TYPE {UNLOCK_TRACK, + UNLOCK_GP, + UNLOCK_MODE, + UNLOCK_KART, + UNLOCK_DIFFICULTY}; + // ------------------------------------------------------------------------ + class UnlockableFeature + { + public: + + std::string m_name; // internal name + irr::core::stringw m_user_name; // not all types of feature have one + REWARD_TYPE m_type; + + const irr::core::stringw getUnlockedMessage() const; + }; // UnlockableFeature + // ------------------------------------------------------------------------ + private: RaceManager::MajorRaceModeType m_major; RaceManager::MinorRaceModeType m_minor; @@ -49,9 +69,21 @@ private: int m_version; void getUnlocks(const XMLNode *root, const std::string &type, - Challenge::REWARD_TYPE reward); + ChallengeData::REWARD_TYPE reward); void error(const char *id) const; + /** Short, internal name for this challenge. */ + std::string m_id; + /** Name used in menu for this challenge. */ + irr::core::stringw m_name; + /** Message the user gets when the feature is not yet unlocked. */ + irr::core::stringw m_challenge_description; + /** Features to unlock. */ + std::vector m_feature; + /** What needs to be done before accessing this challenge. */ + std::vector m_prerequisites; + + public: #ifdef WIN32 ChallengeData(const std::string& filename); @@ -59,6 +91,8 @@ public: ChallengeData(const std::string& filename) throw(std::runtime_error); #endif + virtual ~ChallengeData() {} + /** sets the right parameters in RaceManager to try this challenge */ void setRace() const; @@ -67,6 +101,44 @@ public: virtual bool grandPrixFinished(); /** Returns the version number of this challenge. */ int getVersion() const { return m_version; } + + + const std::vector& + getFeatures() const { return m_feature; } + + void setChallengeDescription(const irr::core::stringw& d) + {m_challenge_description=d; } + + const irr::core::stringw getChallengeDescription() const + {return _(m_challenge_description.c_str()); } + + void addDependency(const std::string id) {m_prerequisites.push_back(id);} + + const std::vector& + getPrerequisites() const {return m_prerequisites; } + + /** Returns the id of the challenge. */ + const std::string &getId() const { return m_id; } + + /** Returns the name of the challenge. */ + const irr::core::stringw getName() const + { return irr::core::stringw(_(m_name.c_str())); } + + /** Sets the name of the challenge. */ + void setName(const irr::core::stringw & s) { m_name = s; } + + /** Sets the id of this challenge. */ + void setId(const std::string& s) { m_id = s; } + + void addUnlockTrackReward(const std::string &track_name); + void addUnlockModeReward(const std::string &internal_mode_name, + const irr::core::stringw &user_mode_name); + void addUnlockGPReward(const std::string &gp_name); + void addUnlockDifficultyReward(const std::string &internal_name, + const irr::core::stringw &user_name); + void addUnlockKartReward(const std::string &internal_name, + const irr::core::stringw &user_name); + }; // ChallengeData #endif // HEADER_CHALLENGE_DATA_HPP diff --git a/src/challenges/game_slot.cpp b/src/challenges/game_slot.cpp new file mode 100644 index 000000000..797cc58ae --- /dev/null +++ b/src/challenges/game_slot.cpp @@ -0,0 +1,216 @@ +// $Id$ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2010 SuperTuxKart-Team +// +// 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 3 +// 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 "challenges/game_slot.hpp" + +#include "challenges/challenge_data.hpp" +#include "challenges/unlock_manager.hpp" +#include "io/xml_writer.hpp" + +//----------------------------------------------------------------------------- + +bool GameSlot::isLocked(const std::string& feature) +{ + return m_locked_features.find(feature)!=m_locked_features.end(); +} // featureIsLocked + //----------------------------------------------------------------------------- + +const std::vector GameSlot::getUnlockedFeatures() +{ + std::vector out; + + std::map::const_iterator i; + for(i = m_challenges_state.begin(); + i != m_challenges_state.end(); i++) + { + if (i->second->isSolved()) out.push_back(i->second->getData()); + } + + return out; +} +//----------------------------------------------------------------------------- +const std::vector GameSlot::getLockedChallenges() +{ + std::vector out; + + std::map::const_iterator i; + for(i = m_challenges_state.begin(); + i != m_challenges_state.end(); i++) + { + if (!i->second->isSolved()) out.push_back(i->second->getData()); + } + + return out; +} + +//----------------------------------------------------------------------------- +void GameSlot::computeActive() +{ + std::map::const_iterator i; + for(i = m_challenges_state.begin(); + i != m_challenges_state.end(); i++) + { + // Changed challenge + // ----------------- + if((i->second)->isSolved()) + { + // The constructor calls computeActive, which actually locks + // all features, so unlock the solved ones (and don't try to + // save the state, since we are currently reading it) + + unlockFeature(i->second, /*save*/ false); + continue; + } + + // Otherwise lock the feature, and check if the challenge is active + // ---------------------------------------------------------------- + lockFeature(i->second); + std::vector pre_req=(i->second)->getData()->getPrerequisites(); + bool allSolved=true; + for(std::vector::iterator pre =pre_req.begin(); + pre!=pre_req.end(); pre++) + { + const Challenge* p = m_challenges_state[*pre]; + if(!p) + { + fprintf(stderr,"Challenge prerequisite '%s' of '%s' not found - ignored\n", + pre->c_str(), i->first.c_str()); + //continue; + allSolved=false; + break; + } + else if(!p->isSolved()) + { + allSolved=false; + break; + } + } // for all pre in pre_req + if(allSolved) + { + i->second->setActive(); + } // if solved + } // for i + clearUnlocked(); +} // computeActive + +//----------------------------------------------------------------------------- + +void GameSlot::lockFeature(Challenge *challenge) +{ + const std::vector& features = challenge->getData()->getFeatures(); + + const unsigned int amount = (unsigned int)features.size(); + for(unsigned int n=0; ngetData()->getFeatures().size(); + for(unsigned int n=0; ngetData()->getFeatures()[n].m_name; + std::map::iterator p=m_locked_features.find(feature); + if(p==m_locked_features.end()) + { + //fprintf(stderr,"Unlocking feature '%s' failed: feature is not locked.\n", + // (feature).c_str()); + return; + } + m_locked_features.erase(p); + } + + // Add to list of recently unlocked features + m_unlocked_features.push_back(c->getData()); + c->setSolved(); // reset isActive flag + + // Save the new unlock information + if(do_save) unlock_manager->save(); +} // unlockFeature + +//----------------------------------------------------------------------------- + +std::vector GameSlot::getActiveChallenges() +{ + computeActive(); + + std::vector out; + + std::map::const_iterator i; + for(i = m_challenges_state.begin(); + i != m_challenges_state.end(); i++) + { + if (i->second->isActive()) out.push_back(i->second->getData()); + } + + return out; +} // getActiveChallenges + +//----------------------------------------------------------------------------- + +/** This is called when a race is finished. Call all active challenges + */ +void GameSlot::raceFinished() +{ + std::map::const_iterator i; + for(i = m_challenges_state.begin(); + i != m_challenges_state.end(); i++) + { + if(i->second->isActive() && i->second->raceFinished()) + { + unlockFeature(i->second); + } // if isActive && challenge solved + } + //race_manager->setCoinTarget(0); //reset +} // raceFinished + +//----------------------------------------------------------------------------- + +void GameSlot::grandPrixFinished() +{ + std::map::const_iterator i; + for(i = m_challenges_state.begin(); + i != m_challenges_state.end(); i++) + { + if(i->second->isActive() && i->second->grandPrixFinished()) + { + printf("===== A FEATURE WAS UNLOCKED BECAUSE YOU WON THE GP!! ==\n"); + unlockFeature(i->second); + } + } + race_manager->setCoinTarget(0); +} // grandPrixFinished + +//----------------------------------------------------------------------------- + +void GameSlot::save(XMLWriter& out) +{ + out << L" \n"; + std::map::const_iterator i; + for(i = m_challenges_state.begin(); + i != m_challenges_state.end(); i++) + { + i->second->save(out); + } + out << " \n"; +} diff --git a/src/challenges/game_slot.hpp b/src/challenges/game_slot.hpp new file mode 100644 index 000000000..65121028c --- /dev/null +++ b/src/challenges/game_slot.hpp @@ -0,0 +1,97 @@ +// $Id$ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2010 SuperTuxKart-Team +// +// 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 3 +// 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 GAME_SLOT_HPP +#define GAME_SLOT_HPP + + +#include +#include +#include +#include + +class ChallengeData; +class Challenge; +class XMLWriter; + +/** + * \ingroup challenges + * This class contains the progression through challenges for one game slot + */ + +class GameSlot +{ + irr::core::stringw m_player_name; + std::string m_kart_ident; + + /** Contains whether each feature of the challenge is locked or unlocked */ + std::map m_locked_features; + + /** Recently unlocked features (they are waiting here + * until they are shown to the user) */ + std::vector m_unlocked_features; + + std::map m_challenges_state; + + friend class UnlockManager; + + void computeActive(); + +public: + + GameSlot(const irr::core::stringw& player_name) + { + m_player_name = player_name; + } + + const irr::core::stringw& getPlayerName() const { return m_player_name; } + const std::string& getKartIdent () const { return m_kart_ident; } + void setKartIdent(const std::string& kart_ident) { m_kart_ident = kart_ident; } + + + /** Returns the list of recently unlocked features (e.g. call at the end of a + race to know if any features were unlocked) */ + const std::vector + getRecentlyUnlockedFeatures() {return m_unlocked_features;} + + /** Clear the list of recently unlocked challenges */ + void clearUnlocked () {m_unlocked_features.clear(); } + + + /** Returns a complete list of all solved challenges */ + const std::vector getUnlockedFeatures(); + + /** Returns the list of currently inaccessible (locked) challenges */ + const std::vector getLockedChallenges(); + + bool isLocked (const std::string& feature); + + void lockFeature (Challenge *challenge); + + void unlockFeature (Challenge* c, bool do_save=true); + + std::vector getActiveChallenges(); + + void raceFinished (); + void grandPrixFinished (); + + void save (XMLWriter& file); +}; + +#endif diff --git a/src/challenges/unlock_manager.cpp b/src/challenges/unlock_manager.cpp index 82d307c5c..1372ed052 100644 --- a/src/challenges/unlock_manager.cpp +++ b/src/challenges/unlock_manager.cpp @@ -27,9 +27,11 @@ #include "audio/sfx_base.hpp" #include "audio/sfx_manager.hpp" +#include "config/player.hpp" #include "config/user_config.hpp" #include "challenges/challenge_data.hpp" #include "io/file_manager.hpp" +#include "io/xml_writer.hpp" #include "karts/kart_properties_manager.hpp" #include "race/race_manager.hpp" #include "tracks/track_manager.hpp" @@ -45,6 +47,8 @@ UnlockManager::UnlockManager() // in main). unlock_manager=this; + m_current_game_slot = 0; + m_locked_sound = sfx_manager->createSoundSource("locked"); @@ -173,19 +177,6 @@ void UnlockManager::addChallenge(const std::string& filename) } // addChallenge -//----------------------------------------------------------------------------- -std::vector UnlockManager::getActiveChallenges() -{ - computeActive(); - std::vector all_active; - for(AllChallengesType::iterator i =m_all_challenges.begin(); - i!=m_all_challenges.end(); i++) - { - if(i->second->isActive()) all_active.push_back(i->second); - } - return all_active; -} // getActiveChallenges - //----------------------------------------------------------------------------- const ChallengeData* UnlockManager::getChallenge(const std::string& id) { @@ -204,29 +195,52 @@ void UnlockManager::load() { std::cerr << "Challenge file '" << filename << "' will be created." << std::endl; + + createSlotsIfNeeded(); save(); if (root) delete root; - computeActive(); return; } - for(AllChallengesType::iterator i =m_all_challenges.begin(); - i!=m_all_challenges.end(); i++) + std::vector xml_game_slots; + root->getNodes("gameslot", xml_game_slots); + for (unsigned int n=0; nsecond->load(root); + core::stringw player_name; + xml_game_slots[n]->get("player", &player_name); + + GameSlot* slot = new GameSlot(player_name); + + std::string kart_id; + xml_game_slots[n]->get("kart", &kart_id); + slot->setKartIdent(kart_id); + + m_game_slots.push_back(slot); + + for(AllChallengesType::iterator i = m_all_challenges.begin(); + i!=m_all_challenges.end(); i++) + { + ChallengeData* curr = i->second; + Challenge* state = new Challenge(curr); + slot->m_challenges_state[curr->getId()] = state; + state->load(root); + } + slot->computeActive(); } - computeActive(); + + bool something_changed = createSlotsIfNeeded(); + if (something_changed) save(); delete root; } // load //----------------------------------------------------------------------------- + void UnlockManager::save() { - std::ofstream challenge_file; std::string filename = file_manager->getChallengeFile("challenges.xml"); - challenge_file.open(filename.c_str()); + XMLWriter challenge_file(filename.c_str()); if(!challenge_file.is_open()) { @@ -237,16 +251,61 @@ void UnlockManager::save() challenge_file << "\n"; challenge_file << "\n"; - for(AllChallengesType::iterator i = m_all_challenges.begin(); - i!= m_all_challenges.end(); i++) + GameSlot* curr; + for_in (curr, m_game_slots) { - i->second->save(challenge_file); + curr->save(challenge_file); } challenge_file << "\n\n"; challenge_file.close(); } // save +//----------------------------------------------------------------------------- + +bool UnlockManager::createSlotsIfNeeded() +{ + bool something_changed = false; + + // make sure all players have at least one game slot associated + PtrVector& players = UserConfigParams::m_all_players; + for (int n=0; ngetPlayerName() == players[n].getName()) + { + exists = true; + break; + } + } + + + if (!exists) + { + printf("==> No, creating one\n"); + GameSlot* slot = new GameSlot(players[n].getName()); + + for(AllChallengesType::iterator i = m_all_challenges.begin(); + i!=m_all_challenges.end(); i++) + { + ChallengeData* cd = i->second; + slot->m_challenges_state[cd->getId()] = new Challenge(cd); + } + slot->computeActive(); + m_game_slots.push_back(slot); + + something_changed = true; + } + } + + return something_changed; +} + //----------------------------------------------------------------------------- void UnlockManager::playLockSound() const { @@ -264,150 +323,5 @@ bool UnlockManager::isSupportedVersion(const ChallengeData &challenge) return (challenge.getVersion()>=1 && challenge.getVersion()<=1); } // isSupportedVersion -//----------------------------------------------------------------------------- -void UnlockManager::computeActive() -{ - for(AllChallengesType::iterator i =m_all_challenges.begin(); - i!=m_all_challenges.end(); i++) - { - // Changed challenge - // ----------------- - if((i->second)->isSolved()) - { - // The constructor calls computeActive, which actually locks - // all features, so unlock the solved ones (and don't try to - // save the state, since we are currently reading it) - - unlockFeature(i->second, /*save*/ false); - continue; - } - - // Otherwise lock the feature, and check if the challenge is active - // ---------------------------------------------------------------- - lockFeature(i->second); - std::vector pre_req=(i->second)->getPrerequisites(); - bool allSolved=true; - for(std::vector::iterator pre =pre_req.begin(); - pre!=pre_req.end(); pre++) - { - const ChallengeData *p = getChallenge(*pre); - if(!p) - { - fprintf(stderr,"Challenge prerequisite '%s' of '%s' not found - ignored\n", - pre->c_str(), i->first.c_str()); - //continue; - allSolved=false; - break; - } - else if(!p->isSolved()) - { - allSolved=false; - break; - } - } // for all pre in pre_req - if(allSolved) - { - i->second->setActive(); - } // if solved - } // for i - clearUnlocked(); -} // computeActive //----------------------------------------------------------------------------- -/** This is called when a race is finished. Call all active challenges -*/ -void UnlockManager::raceFinished() -{ - for(AllChallengesType::iterator i =m_all_challenges.begin(); - i!=m_all_challenges.end(); i++) - { - if(i->second->isActive() && i->second->raceFinished()) - { - unlockFeature(i->second); - } // if isActive && challenge solved - } - //race_manager->setCoinTarget(0); //reset -} // raceFinished - -//----------------------------------------------------------------------------- -void UnlockManager::grandPrixFinished() -{ - for(AllChallengesType::iterator i =m_all_challenges.begin(); - i!=m_all_challenges.end(); i++) - { - if(i->second->isActive() && i->second->grandPrixFinished()) - { - std::cout << "===== A FEATURE WAS UNLOCKED BECAUSE YOU WON THE GP!! ==\n"; - unlockFeature(i->second); - } - } - race_manager->setCoinTarget(0); -} // grandPrixFinished - -//----------------------------------------------------------------------------- -void UnlockManager::lockFeature(const ChallengeData *challenge) -{ - const unsigned int amount = (unsigned int)challenge->getFeatures().size(); - for(unsigned int n=0; ngetFeatures()[n].m_name]=true; -} // lockFeature - -//----------------------------------------------------------------------------- - -void UnlockManager::unlockFeature(ChallengeData* c, bool do_save) -{ - const unsigned int amount = (unsigned int)c->getFeatures().size(); - for(unsigned int n=0; ngetFeatures()[n].m_name; - std::map::iterator p=m_locked_features.find(feature); - if(p==m_locked_features.end()) - { - //fprintf(stderr,"Unlocking feature '%s' failed: feature is not locked.\n", - // (feature).c_str()); - return; - } - m_locked_features.erase(p); - } - - // Add to list of recently unlocked features - m_unlocked_features.push_back(c); - c->setSolved(); // reset isActive flag - - // Save the new unlock information - if(do_save) save(); -} // unlockFeature - -//----------------------------------------------------------------------------- -bool UnlockManager::isLocked(const std::string& feature) -{ - return m_locked_features.find(feature)!=m_locked_features.end(); -} // featureIsLocked -//----------------------------------------------------------------------------- -const std::vector UnlockManager::getUnlockedFeatures() -{ - std::vector out; - - for(AllChallengesType::const_iterator i =m_all_challenges.begin(); - i!=m_all_challenges.end(); i++) - { - if (i->second->isSolved()) out.push_back(i->second); - } - - return out; -} -//----------------------------------------------------------------------------- -const std::vector UnlockManager::getLockedChallenges() -{ - std::vector out; - - for(AllChallengesType::const_iterator i =m_all_challenges.begin(); - i!=m_all_challenges.end(); i++) - { - if (!i->second->isSolved() && !i->second->isActive()) out.push_back(i->second); - } - - return out; -} - - diff --git a/src/challenges/unlock_manager.hpp b/src/challenges/unlock_manager.hpp index 23ca793d1..6cf2ee0c3 100644 --- a/src/challenges/unlock_manager.hpp +++ b/src/challenges/unlock_manager.hpp @@ -23,7 +23,10 @@ #include #include "challenges/challenge_data.hpp" +#include "challenges/game_slot.hpp" + #include "utils/no_copy.hpp" +#include "utils/ptr_vector.hpp" #include @@ -38,15 +41,20 @@ class UnlockManager : public NoCopy { private: SFXBase *m_locked_sound; - typedef std::map AllChallengesType; - AllChallengesType m_all_challenges; - std::map m_locked_features; - std::vector m_unlocked_features; - void computeActive (); + void load (); - void unlockFeature (ChallengeData* c, bool do_save=true); + typedef std::map AllChallengesType; + AllChallengesType m_all_challenges; + + PtrVector m_game_slots; + void readAllChallengesInDirs(const std::vector* all_dirs); + bool createSlotsIfNeeded(); + + int m_current_game_slot; + + friend class GameSlot; public: UnlockManager (); @@ -54,34 +62,18 @@ public: void addOrFreeChallenge(ChallengeData *c); void addChallenge (const std::string& filename); void save (); - std::vector - getActiveChallenges(); - - /** Returns the list of recently unlocked features (e.g. call at the end of a - race to know if any features were unlocked) */ - const std::vector - getRecentlyUnlockedFeatures() {return m_unlocked_features;} - - /** Clear the list of recently unlocked challenges */ - void clearUnlocked () {m_unlocked_features.clear(); } - - /** Returns a complete list of all solved challenges */ - const std::vector getUnlockedFeatures(); - - /** Returns the list of currently inaccessible (locked) challenges */ - const std::vector getLockedChallenges(); const ChallengeData *getChallenge (const std::string& id); - void raceFinished (); - void grandPrixFinished (); - void lockFeature (const ChallengeData *challenge); - bool isLocked (const std::string& feature); bool isSupportedVersion(const ChallengeData &challenge); /** Eye- (or rather ear-) candy. Play a sound when user tries to access a locked area */ void playLockSound() const; + GameSlot* getCurrentSlot() { return m_game_slots.get(m_current_game_slot); } + + void setCurrentSlot(int slotid) { m_current_game_slot = slotid; } + }; // UnlockManager extern UnlockManager* unlock_manager; diff --git a/src/ide/Xcode/STK_XCode.xcodeproj/project.pbxproj b/src/ide/Xcode/STK_XCode.xcodeproj/project.pbxproj index 3fd3cd47c..60b1338fa 100644 --- a/src/ide/Xcode/STK_XCode.xcodeproj/project.pbxproj +++ b/src/ide/Xcode/STK_XCode.xcodeproj/project.pbxproj @@ -359,6 +359,7 @@ 95E246BE111A2959000C965D /* confirm_resolution_dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95E246BC111A2959000C965D /* confirm_resolution_dialog.cpp */; }; 95E5C318148C17E500AD3FCC /* story_mode_lobby.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95E5C316148C17E500AD3FCC /* story_mode_lobby.cpp */; }; 95E5C335148C19F500AD3FCC /* story_mode_new.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95E5C333148C19F500AD3FCC /* story_mode_new.cpp */; }; + 95E5C3C2148C418100AD3FCC /* game_slot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95E5C3C0148C418100AD3FCC /* game_slot.cpp */; }; 95E6A0C011DCF37800AE088A /* addons_loading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95E6A0BE11DCF37800AE088A /* addons_loading.cpp */; }; 95ECA10010124C5000D47C5F /* button_widget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95ECA0EC10124C5000D47C5F /* button_widget.cpp */; }; 95ECA10110124C5000D47C5F /* check_box_widget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95ECA0EE10124C5000D47C5F /* check_box_widget.cpp */; }; @@ -1335,6 +1336,8 @@ 95E5C317148C17E500AD3FCC /* story_mode_lobby.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = story_mode_lobby.hpp; path = ../../states_screens/story_mode_lobby.hpp; sourceTree = SOURCE_ROOT; }; 95E5C333148C19F500AD3FCC /* story_mode_new.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = story_mode_new.cpp; path = ../../states_screens/dialogs/story_mode_new.cpp; sourceTree = SOURCE_ROOT; }; 95E5C334148C19F500AD3FCC /* story_mode_new.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = story_mode_new.hpp; path = ../../states_screens/dialogs/story_mode_new.hpp; sourceTree = SOURCE_ROOT; }; + 95E5C3C0148C418100AD3FCC /* game_slot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = game_slot.cpp; path = ../../challenges/game_slot.cpp; sourceTree = SOURCE_ROOT; }; + 95E5C3C1148C418100AD3FCC /* game_slot.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = game_slot.hpp; path = ../../challenges/game_slot.hpp; sourceTree = SOURCE_ROOT; }; 95E6A0BE11DCF37800AE088A /* addons_loading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = addons_loading.cpp; path = ../../states_screens/dialogs/addons_loading.cpp; sourceTree = SOURCE_ROOT; }; 95E6A0BF11DCF37800AE088A /* addons_loading.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = addons_loading.hpp; path = ../../states_screens/dialogs/addons_loading.hpp; sourceTree = SOURCE_ROOT; }; 95ECA0EC10124C5000D47C5F /* button_widget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = button_widget.cpp; path = ../../guiengine/widgets/button_widget.cpp; sourceTree = SOURCE_ROOT; }; @@ -2416,6 +2419,8 @@ 95C2AE270F296541000D3E5D /* challenge.hpp */, 95C2AE280F296541000D3E5D /* challenge_data.cpp */, 95C2AE290F296541000D3E5D /* challenge_data.hpp */, + 95E5C3C0148C418100AD3FCC /* game_slot.cpp */, + 95E5C3C1148C418100AD3FCC /* game_slot.hpp */, 95C2AE2A0F296541000D3E5D /* unlock_manager.cpp */, 95C2AE2B0F296541000D3E5D /* unlock_manager.hpp */, ); @@ -3195,6 +3200,7 @@ 95AA4C67148AF2CC0053771D /* lod_node_loader.cpp in Sources */, 95E5C318148C17E500AD3FCC /* story_mode_lobby.cpp in Sources */, 95E5C335148C19F500AD3FCC /* story_mode_new.cpp in Sources */, + 95E5C3C2148C418100AD3FCC /* game_slot.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/io/xml_writer.hpp b/src/io/xml_writer.hpp index 15bc6cb4c..78b6cbe60 100644 --- a/src/io/xml_writer.hpp +++ b/src/io/xml_writer.hpp @@ -49,6 +49,8 @@ public: } void close(); + + bool is_open() { return m_base.is_open(); } }; #endif diff --git a/src/karts/kart_properties_manager.cpp b/src/karts/kart_properties_manager.cpp index bd3819231..0366b5866 100644 --- a/src/karts/kart_properties_manager.cpp +++ b/src/karts/kart_properties_manager.cpp @@ -354,7 +354,7 @@ bool KartPropertiesManager::kartAvailable(int kartid) if ( kartid == *it) return false; } const KartProperties *kartprop = getKartById(kartid); - if(unlock_manager->isLocked(kartprop->getIdent())) return false; + if(unlock_manager->getCurrentSlot()->isLocked(kartprop->getIdent())) return false; return true; } // kartAvailable @@ -463,7 +463,7 @@ void KartPropertiesManager::getRandomKartList(int count, const KartProperties &kp=m_karts_properties[karts_in_group[i]]; if (!used[karts_in_group[i]] && m_kart_available[karts_in_group[i]] && - !unlock_manager->isLocked(kp.getIdent()) ) + !unlock_manager->getCurrentSlot()->isLocked(kp.getIdent()) ) { random_kart_queue.push_back(kp.getIdent()); } diff --git a/src/main.cpp b/src/main.cpp index aa415d454..03f436aaa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -703,7 +703,7 @@ int handleCmdLine(int argc, char **argv) } else if( (!strcmp(argv[i], "--kart") && i+1isLocked(argv[i+1])) + if (!unlock_manager->getCurrentSlot()->isLocked(argv[i+1])) { const KartProperties *prop = kart_properties_manager->getKart(argv[i+1]); @@ -764,7 +764,7 @@ int handleCmdLine(int argc, char **argv) else if( (!strcmp(argv[i], "--track") || !strcmp(argv[i], "-t")) && i+1isLocked(argv[i+1])) + if (!unlock_manager->getCurrentSlot()->isLocked(argv[i+1])) { race_manager->setTrack(argv[i+1]); fprintf ( stdout, "You choose to start in track: %s.\n", @@ -829,7 +829,7 @@ int handleCmdLine(int argc, char **argv) for (size_t i = 0; i != track_manager->getNumberOfTracks(); i++) { const Track *track = track_manager->getTrack(i); - if (!unlock_manager->isLocked(track->getIdent())) + if (!unlock_manager->getCurrentSlot()->isLocked(track->getIdent())) { fprintf ( stdout, "\t%14s: %ls\n", track->getIdent().c_str(), @@ -847,7 +847,7 @@ int handleCmdLine(int argc, char **argv) { const KartProperties* KP = kart_properties_manager->getKartById(i); - if (!unlock_manager->isLocked(KP->getIdent())) + if (!unlock_manager->getCurrentSlot()->isLocked(KP->getIdent())) { fprintf (stdout, "\t%10s: %ls\n", KP->getIdent().c_str(), KP->getName()); diff --git a/src/modes/world.cpp b/src/modes/world.cpp index 0e6f88f4f..c504cd88e 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -332,7 +332,7 @@ void World::terminateRace() updateHighscores(&best_highscore_rank, &best_finish_time, &highscore_who, &best_player); - unlock_manager->raceFinished(); + unlock_manager->getCurrentSlot()->raceFinished(); if (m_race_gui) m_race_gui->clearAllMessages(); // we can't delete the race gui here, since it is needed in case of diff --git a/src/race/race_manager.cpp b/src/race/race_manager.cpp index e4772df98..e416d585f 100644 --- a/src/race/race_manager.cpp +++ b/src/race/race_manager.cpp @@ -102,7 +102,7 @@ void RaceManager::setDefaultAIKartList(const std::vector& ai_list) name.c_str()); continue; } - if(unlock_manager->isLocked(name)) + if(unlock_manager->getCurrentSlot()->isLocked(name)) { printf("Kart '%s' is locked and therefore ignored.\n", name.c_str()); @@ -489,7 +489,7 @@ void RaceManager::exitRace() // were finished, and not when a race is aborted. if (m_major_mode==MAJOR_MODE_GRAND_PRIX && m_track_number==(int)m_tracks.size()) { - unlock_manager->grandPrixFinished(); + unlock_manager->getCurrentSlot()->grandPrixFinished(); StateManager::get()->resetAndGoToScreen( MainMenuScreen::getInstance() ); diff --git a/src/states_screens/arenas_screen.cpp b/src/states_screens/arenas_screen.cpp index 67f6c9e43..44b29fb52 100644 --- a/src/states_screens/arenas_screen.cpp +++ b/src/states_screens/arenas_screen.cpp @@ -200,7 +200,7 @@ void ArenasScreen::buildTrackList() Track* curr = track_manager->getTrack(n); if (!curr->isArena()) continue; - if (unlock_manager->isLocked(curr->getIdent())) + if (unlock_manager->getCurrentSlot()->isLocked(curr->getIdent())) { w->addItem( _("Locked : solve active challenges to gain access to more!"), "locked", curr->getScreenshotFile(), LOCKED_BADGE ); @@ -223,7 +223,7 @@ void ArenasScreen::buildTrackList() Track* curr = track_manager->getTrack(currArenas[n]); if (!curr->isArena()) continue; - if (unlock_manager->isLocked(curr->getIdent())) + if (unlock_manager->getCurrentSlot()->isLocked(curr->getIdent())) { w->addItem( _("Locked : solve active challenges to gain access to more!"), "locked", curr->getScreenshotFile(), LOCKED_BADGE ); diff --git a/src/states_screens/challenges.cpp b/src/states_screens/challenges.cpp index be241b3bf..1c6c8a431 100644 --- a/src/states_screens/challenges.cpp +++ b/src/states_screens/challenges.cpp @@ -69,9 +69,11 @@ void ChallengesScreen::beforeAddingWidget() DynamicRibbonWidget* w = this->getWidget("challenges"); assert( w != NULL ); - const std::vector& activeChallenges = unlock_manager->getActiveChallenges(); - const std::vector& solvedChallenges = unlock_manager->getUnlockedFeatures(); - const std::vector& lockedChallenges = unlock_manager->getLockedChallenges(); + GameSlot* slot = unlock_manager->getCurrentSlot(); + + const std::vector& activeChallenges = slot->getActiveChallenges(); + const std::vector& solvedChallenges = slot->getUnlockedFeatures(); + const std::vector& lockedChallenges = slot->getLockedChallenges(); const int activeChallengeAmount = activeChallenges.size(); const int solvedChallengeAmount = solvedChallenges.size(); @@ -92,9 +94,11 @@ void ChallengesScreen::init() // Re-build track list everytime (accounts for locking changes, etc.) w->clearItems(); - const std::vector& activeChallenges = unlock_manager->getActiveChallenges(); - const std::vector& solvedChallenges = unlock_manager->getUnlockedFeatures(); - const std::vector& lockedChallenges = unlock_manager->getLockedChallenges(); + GameSlot* slot = unlock_manager->getCurrentSlot(); + + const std::vector& activeChallenges = slot->getActiveChallenges(); + const std::vector& solvedChallenges = slot->getUnlockedFeatures(); + const std::vector& lockedChallenges = slot->getLockedChallenges(); const int activeChallengeAmount = activeChallenges.size(); const int solvedChallengeAmount = solvedChallenges.size(); @@ -158,7 +162,7 @@ void ChallengesScreen::eventCallback(GUIEngine::Widget* widget, const std::strin UserConfigParams::m_default_kart.revertToDefaults(); } - const Challenge* c = unlock_manager->getChallenge(selection); + const ChallengeData* c = unlock_manager->getChallenge(selection); if (c == NULL) { std::cerr << "[ChallengesScreen] ERROR: cannot find challenge '" << selection.c_str() << "'!\n"; diff --git a/src/states_screens/dialogs/race_over_dialog.cpp b/src/states_screens/dialogs/race_over_dialog.cpp index 2dfa1d017..5dcf8b7c7 100644 --- a/src/states_screens/dialogs/race_over_dialog.cpp +++ b/src/states_screens/dialogs/race_over_dialog.cpp @@ -309,7 +309,7 @@ RaceOverDialog::RaceOverDialog(const float percentWidth, } // ---- Buttons at the bottom - if (unlock_manager->getRecentlyUnlockedFeatures().size() > 0) + if (unlock_manager->getCurrentSlot()->getRecentlyUnlockedFeatures().size() > 0) { const int label_y = m_area.getHeight() - (button_h + margin_between_buttons)*2; @@ -480,8 +480,8 @@ GUIEngine::EventPropagation RaceOverDialog::processEvent(const std::string& even else if (eventSource == "seeunlocked") { std::vector unlocked = - unlock_manager->getRecentlyUnlockedFeatures(); - unlock_manager->clearUnlocked(); + unlock_manager->getCurrentSlot()->getRecentlyUnlockedFeatures(); + unlock_manager->getCurrentSlot()->clearUnlocked(); FeatureUnlockedCutScene* scene = FeatureUnlockedCutScene::getInstance(); @@ -505,7 +505,7 @@ GUIEngine::EventPropagation RaceOverDialog::processEvent(const std::string& even void RaceOverDialog::escapePressed() { - if (unlock_manager->getRecentlyUnlockedFeatures().size() > 0) + if (unlock_manager->getCurrentSlot()->getRecentlyUnlockedFeatures().size() > 0) { std::string what = "seeunlocked"; processEvent(what); diff --git a/src/states_screens/dialogs/story_mode_new.cpp b/src/states_screens/dialogs/story_mode_new.cpp index aa0d04373..cf67bbbb0 100644 --- a/src/states_screens/dialogs/story_mode_new.cpp +++ b/src/states_screens/dialogs/story_mode_new.cpp @@ -50,6 +50,8 @@ StoryModeNewDialog::StoryModeNewDialog(const float w, const float h) : RibbonWidget* difficulty = getWidget("difficulty"); difficulty->setSelection( 1 /* medium */, PLAYER_ID_GAME_MASTER ); + + ident->setFocusForPlayer(PLAYER_ID_GAME_MASTER); } // ----------------------------------------------------------------------------- diff --git a/src/states_screens/feature_unlocked.cpp b/src/states_screens/feature_unlocked.cpp index 7c9505318..dd1ca3771 100644 --- a/src/states_screens/feature_unlocked.cpp +++ b/src/states_screens/feature_unlocked.cpp @@ -504,7 +504,7 @@ void FeatureUnlockedCutScene::addUnlockedThings(const std::vector& + const std::vector& unlockedFeatures = unlocked[n]->getFeatures(); assert(unlockedFeatures.size() > 0); @@ -512,7 +512,7 @@ void FeatureUnlockedCutScene::addUnlockedThings(const std::vectorgetTrack(unlockedFeatures[i].m_name); @@ -522,7 +522,7 @@ void FeatureUnlockedCutScene::addUnlockedThings(const std::vector images; const GrandPrixData* gp = @@ -560,7 +560,7 @@ void FeatureUnlockedCutScene::addUnlockedThings(const std::vectorgetKart(unlockedFeatures[i].m_name); @@ -595,7 +595,7 @@ void FeatureUnlockedCutScene::addUnlockedThings(const std::vectorsetMajorMode (RaceManager::MAJOR_MODE_SINGLE); - if (unlock_manager->getRecentlyUnlockedFeatures().size() > 0) + if (unlock_manager->getCurrentSlot()->getRecentlyUnlockedFeatures().size() > 0) { std::vector unlocked = - unlock_manager->getRecentlyUnlockedFeatures(); - unlock_manager->clearUnlocked(); + unlock_manager->getCurrentSlot()->getRecentlyUnlockedFeatures(); + unlock_manager->getCurrentSlot()->clearUnlocked(); FeatureUnlockedCutScene* scene = FeatureUnlockedCutScene::getInstance(); diff --git a/src/states_screens/grand_prix_win.cpp b/src/states_screens/grand_prix_win.cpp index 14da931be..bf4fc6e8f 100644 --- a/src/states_screens/grand_prix_win.cpp +++ b/src/states_screens/grand_prix_win.cpp @@ -96,7 +96,7 @@ void GrandPrixWin::loadedFromFile() void GrandPrixWin::init() { Screen::init(); - if (unlock_manager->getRecentlyUnlockedFeatures().size() > 0) + if (unlock_manager->getCurrentSlot()->getRecentlyUnlockedFeatures().size() > 0) { const core::dimension2d& frame_size = GUIEngine::getDriver()->getCurrentRenderTargetSize(); @@ -394,11 +394,11 @@ void GrandPrixWin::eventCallback(GUIEngine::Widget* widget, // un-set the GP mode so that after unlocking, it doesn't try to continue the GP race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE); - if (unlock_manager->getRecentlyUnlockedFeatures().size() > 0) + if (unlock_manager->getCurrentSlot()->getRecentlyUnlockedFeatures().size() > 0) { std::vector unlocked = - unlock_manager->getRecentlyUnlockedFeatures(); - unlock_manager->clearUnlocked(); + unlock_manager->getCurrentSlot()->getRecentlyUnlockedFeatures(); + unlock_manager->getCurrentSlot()->clearUnlocked(); FeatureUnlockedCutScene* scene = FeatureUnlockedCutScene::getInstance(); diff --git a/src/states_screens/kart_selection.cpp b/src/states_screens/kart_selection.cpp index a9a1c01ff..e67c22a22 100644 --- a/src/states_screens/kart_selection.cpp +++ b/src/states_screens/kart_selection.cpp @@ -1962,7 +1962,7 @@ void KartSelectionScreen::setKartsFromCurrentGroup() { const KartProperties* prop = kart_properties_manager->getKartById(n); - if (unlock_manager->isLocked(prop->getIdent())) + if (unlock_manager->getCurrentSlot()->isLocked(prop->getIdent())) { w->addItem( _("Locked : solve active challenges to gain access " @@ -1993,7 +1993,7 @@ void KartSelectionScreen::setKartsFromCurrentGroup() kart_properties_manager->getKartById(group[n]); const std::string &icon_path = prop->getAbsoluteIconFile(); - if (unlock_manager->isLocked(prop->getIdent())) + if (unlock_manager->getCurrentSlot()->isLocked(prop->getIdent())) { w->addItem( _("Locked : solve active challenges to gain access " diff --git a/src/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp index 3b04dbe43..046f28cbb 100644 --- a/src/states_screens/race_result_gui.cpp +++ b/src/states_screens/race_result_gui.cpp @@ -91,7 +91,7 @@ void RaceResultGUI::enableAllButtons() // If something was unlocked // ------------------------- - int n = unlock_manager->getRecentlyUnlockedFeatures().size(); + int n = unlock_manager->getCurrentSlot()->getRecentlyUnlockedFeatures().size(); if(n>0) { top->setText(n==1 ? _("See unlocked feature") @@ -138,7 +138,7 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget, // If something was unlocked, the 'continue' button was // actually used to display "Show unlocked feature(s)" text. // --------------------------------------------------------- - int n = unlock_manager->getRecentlyUnlockedFeatures().size(); + int n = unlock_manager->getCurrentSlot()->getRecentlyUnlockedFeatures().size(); if(n>0) { if(name=="top") @@ -149,8 +149,8 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget, } std::vector unlocked = - unlock_manager->getRecentlyUnlockedFeatures(); - unlock_manager->clearUnlocked(); + unlock_manager->getCurrentSlot()->getRecentlyUnlockedFeatures(); + unlock_manager->getCurrentSlot()->clearUnlocked(); FeatureUnlockedCutScene* scene = FeatureUnlockedCutScene::getInstance(); scene->addUnlockedThings(unlocked); diff --git a/src/states_screens/race_setup_screen.cpp b/src/states_screens/race_setup_screen.cpp index ad505dfb5..65319a458 100644 --- a/src/states_screens/race_setup_screen.cpp +++ b/src/states_screens/race_setup_screen.cpp @@ -205,7 +205,7 @@ void RaceSetupScreen::init() name2 += _("Contains no powerups, so only your driving skills matter!"); w2->addItem( name2, IDENT_TTRIAL, RaceManager::getIconOf(RaceManager::MINOR_MODE_TIME_TRIAL)); - if (unlock_manager->isLocked(IDENT_FTL)) + if (unlock_manager->getCurrentSlot()->isLocked(IDENT_FTL)) { w2->addItem( _("Locked : solve active challenges to gain access to more!"), "locked", RaceManager::getIconOf(RaceManager::MINOR_MODE_FOLLOW_LEADER), true); diff --git a/src/states_screens/tracks_screen.cpp b/src/states_screens/tracks_screen.cpp index 408c17729..75b4595e3 100644 --- a/src/states_screens/tracks_screen.cpp +++ b/src/states_screens/tracks_screen.cpp @@ -247,7 +247,7 @@ void TracksScreen::init() sshot_files.push_back("gui/main_help.png"); } - if (unlock_manager->isLocked(gp->getId())) + if (unlock_manager->getCurrentSlot()->isLocked(gp->getId())) { gps_widget->addAnimatedItem(_("Locked!"), "locked", sshot_files, 1.5f, LOCKED_BADGE | TROPHY_BADGE, @@ -304,7 +304,7 @@ void TracksScreen::buildTrackList() Track* curr = track_manager->getTrack( n ); if (curr->isArena()) continue; - if (unlock_manager->isLocked(curr->getIdent())) + if (unlock_manager->getCurrentSlot()->isLocked(curr->getIdent())) { tracks_widget->addItem( _("Locked : solve active challenges to gain access to more!"), "locked", curr->getScreenshotFile(), LOCKED_BADGE, @@ -329,7 +329,7 @@ void TracksScreen::buildTrackList() Track* curr = track_manager->getTrack( curr_group[n] ); if (curr->isArena()) continue; - if (unlock_manager->isLocked(curr->getIdent())) + if (unlock_manager->getCurrentSlot()->isLocked(curr->getIdent())) { tracks_widget->addItem( _("Locked : solve active challenges to gain access to more!"), "locked", curr->getScreenshotFile(), LOCKED_BADGE,