Added ability to define a 'target time' for levels which is taken into consideration...
authorLMH <lmh.0013@gmail.com>
Fri, 6 Sep 2013 03:22:38 +0000 (17:22 -1000)
committerTobias Markus <tobbi@mozilla-uk.org>
Sat, 26 Oct 2013 16:45:21 +0000 (18:45 +0200)
As a proof of principle, Icy Island levels prior to the underground sequence have been assigned arbitrary but attainable target times.  However, this feature probably should only be used with great care in the main game (if at all).  Statistics still need to be modified to display the target time if defined, otherwise it will be confusing to players trying for perfet stats.

23 files changed:
data/levels/world1/01 - Welcome to Antarctica.stl
data/levels/world1/02 - The Journey Begins.stl
data/levels/world1/03 - Via Nostalgica.stl
data/levels/world1/04 - Tobgle Road.stl
data/levels/world1/05 - The Somewhat Smaller Bath.stl
data/levels/world1/06 - The Frosted Fields.stl
data/levels/world1/07 - Oh No More Snowballs.stl
data/levels/world1/08 - Stone Cold.stl
data/levels/world1/09 - Grumbels Sense of Snow.stl
data/levels/world1/10 - 23rd Airborne.stl
data/levels/world1/11 - Night Chill.stl
data/levels/world1/12 - Into the Stars.stl
data/levels/world1/13 - Above the Arctic Skies.stl
data/levels/world1/14 - Entrance to the Cave.stl
data/levels/world1/Fork_in_the_Road.stl
src/supertux/level.cpp
src/supertux/level.hpp
src/supertux/statistics.cpp
src/supertux/statistics.hpp
src/worldmap/level.cpp
src/worldmap/level.hpp
src/worldmap/worldmap.cpp
src/worldmap/worldmap.hpp

index 3440892..02c8515 100755 (executable)
@@ -2,6 +2,7 @@
   (version 2)
   (name (_ "Welcome to Antarctica"))
   (author "SuperTux Team")
+  (target-time 30)
   (license "GPL 2+ / CC-by-sa 3.0")
   (sector
     (name "main")
index 4e73adb..9169cdb 100755 (executable)
@@ -2,6 +2,7 @@
   (version 2)
   (name (_ "The Journey Begins"))
   (author "SuperTux Team")
+  (target-time 30)
   (license "GPL 2+ / CC-by-sa 3.0")
   (sector
     (name "main")
index f73e39a..ff3a213 100755 (executable)
@@ -2,6 +2,7 @@
   (version 2)
   (name (_ "Via Nostalgica"))
   (author "SuperTux Team")
+  (target-time 60)
   (license "GPL 2+ / CC-by-sa 3.0")
   (sector
     (name "main")
index aef2eb0..da6c508 100755 (executable)
@@ -2,6 +2,7 @@
   (version 2)
   (name (_ "Tobgle Road"))
   (author "SuperTux Team")
+  (target-time 60)
   (license "GPL 2+ / CC-by-sa 3.0")
   (sector
     (name "main")
index 3158bc1..3bc1174 100755 (executable)
@@ -3,6 +3,7 @@
   (name (_ "The Somewhat Smaller Bath"))
   (author "Philippe Saint-Pierre")
   (license "GPL 2+ / CC-by-sa 3.0")
+  (target-time 60)
   (sector
     (name "main")
     (music "music/chipdisko.ogg")
index f16bccc..4605f2c 100755 (executable)
@@ -3,6 +3,7 @@
   (name (_ "The Frosted Fields"))
   (author "SuperTux Team")
   (license "GPL 2+ / CC-by-sa 3.0")
+  (target-time 80)
   (sector
     (name "main")
     (music "music/chipdisko.ogg")
index e689924..f38a3f8 100755 (executable)
@@ -3,6 +3,7 @@
   (name (_ "Oh no! More Snowballs!"))
   (author "Voluptuous Pachyderm")
   (license "GPL 2+ / CC-by-sa 3.0")
+  (target-time 80)
   (sector
     (name "main")
     (music "music/voc-daytime2.music")
index 98b94ba..23527f5 100755 (executable)
@@ -3,6 +3,7 @@
   (name (_ "Stone Cold"))
   (author "SuperTux Team")
   (license "GPL 2+ / CC-by-sa 3.0")
+  (target-time 80)
   (sector
     (name "main")
     (music "music/chipdisko.ogg")
index ce6abc2..1eef5b9 100755 (executable)
@@ -3,6 +3,7 @@
   (name (_ "Grumbel's Sense of Snow"))
   (author "SuperTux Team")
   (license "GPL 2+ / CC-by-sa 3.0")
+  (target-time 80)
   (sector
     (name "main")
     (music "music/chipdisko.ogg")
index 13705fc..15d02c4 100755 (executable)
@@ -3,6 +3,7 @@
   (name (_ "23rd Airborne"))
   (author "SuperTux Team")
   (license "GPL 2+ / CC-by-sa 3.0")
+  (target-time 80)
   (sector
     (name "main")
     (music "music/airship_remix.music")
index 48f991b..4f3b45e 100755 (executable)
@@ -3,6 +3,7 @@
   (name (_ "Night Chill"))
   (author "SuperTux Team")
   (license "GPL 2+ / CC-by-sa 3.0")
+  (target-time 100)
   (sector
     (name "main")
     (music "music/voc-night.music")
index 4bfae2c..89afa57 100755 (executable)
@@ -3,6 +3,7 @@
   (name (_ "Into the Stars"))
   (author "SuperTux Team")
   (license "GPL 2+ / CC-by-sa 3.0")
+  (target-time 80)
   (sector
     (name "main")
     (music "music/voc-night.music")
index 90cf22a..b24bfec 100755 (executable)
@@ -3,6 +3,7 @@
   (name (_ "Above the Arctic Skies"))
   (author "SuperTux Team")
   (license "GPL 2+ / CC-by-sa 3.0")
+  (target-time 40)
   (sector
     (name "main")
     (music "music/airship_remix.music")
index 5dd1f8c..b4eeedf 100755 (executable)
@@ -3,6 +3,7 @@
   (name (_ "Entrance to the Cave"))
   (author "SuperTux Team")
   (license "GPL 2+ / CC-by-sa 3.0")
+  (target-time 80)
   (sector
     (name "main")
     (music "music/chipdisko.ogg")
index 523b64a..a441a59 100644 (file)
@@ -4,6 +4,7 @@
   (author "LMH")
   (contact "lmh.0013@gmail.com")
   (license "GPL 2 / CC-by-sa 3.0")
+  (target-time 60)
   (sector
     (name "main")
     (music "music/voc-daytime2.ogg")
index 0d78d53..9b179bc 100644 (file)
@@ -40,6 +40,7 @@ Level::Level() :
   on_menukey_script(),
   sectors(),
   stats(),
+  target_time(),
   tileset(NULL), 
   free_tileset(false)
 {
@@ -120,6 +121,8 @@ Level::load(const std::string& filepath)
         Sector* sector = new Sector(this);
         sector->parse(*(iter.lisp()));
         add_sector(sector);
+      } else if(token == "target-time") {
+        iter.value()->get(target_time);
       } else {
         log_warning << "Unknown token '" << token << "' in level file" << std::endl;
       }
index b2b8dd9..aadc49b 100644 (file)
@@ -41,6 +41,7 @@ public:
   std::string on_menukey_script;
   Sectors     sectors;
   Statistics  stats;
+  float       target_time;
   TileSet    *tileset;
   bool        free_tileset;
 
index 0dd695d..975880a 100644 (file)
@@ -273,11 +273,12 @@ Statistics::operator+=(const Statistics& s2)
 }
 
 bool
-Statistics::completed(const Statistics& stats)
+Statistics::completed(const Statistics& stats, const float target_time)
 {
   return (stats.coins == stats.total_coins && 
       stats.badguys == stats.total_badguys && 
-      stats.secrets == stats.total_secrets);
+      stats.secrets == stats.total_secrets &&
+      ((!target_time) || (stats.time <= target_time)));
 }
 
 void
index 880cd47..e11c39d 100644 (file)
@@ -65,7 +65,7 @@ public:
   void reset(); /**< Set stats (but not totals) to zero */
   void merge(const Statistics& stats); /**< Given another Statistics object finds the best of each one */
   void operator+=(const Statistics& o); /**< Add two Statistics objects */
-  bool completed(const Statistics& stats); /* Check if stats match total stats */
+  bool completed(const Statistics& stats, const float target_time); /* Check if stats match total stats */
 
   void declare_invalid(); /**< marks statistics as invalid for their entire lifetime (e.g. after cheating). Invalid statistics will not be merged or drawn. */
   
index 569f31f..b60fad0 100644 (file)
@@ -37,6 +37,7 @@ LevelTile::LevelTile(const std::string& basedir, const Reader& lisp) :
   auto_play(false), 
   sprite(),
   statistics(),
+  target_time(),
   extro_script(),
   basedir(basedir), 
   picture_cached(false),
index 8730d29..58935b1 100644 (file)
@@ -50,6 +50,7 @@ public:
 
   /** Statistics for level tiles */
   Statistics statistics;
+  float target_time;
 
   /** Script that is run when the level is successfully finished */
   std::string extro_script;
index e082d8f..31d631c 100644 (file)
@@ -364,6 +364,24 @@ WorldMap::get_level_title(LevelTile& level)
   }
 }
 
+void
+WorldMap::get_level_target_time(LevelTile& level)
+{
+  try {
+    lisp::Parser parser;
+    const lisp::Lisp* root = parser.parse(levels_path + level.get_name());
+
+    const lisp::Lisp* level_lisp = root->get_lisp("supertux-level");
+    if(!level_lisp)
+      return;
+
+    level_lisp->get("target-time", level.target_time);
+  } catch(std::exception& e) {
+    log_warning << "Problem when reading level target time: " << e.what() << std::endl;
+    return;
+  }
+}
+
 void WorldMap::calculate_total_stats()
 {
   total_stats.zero();
@@ -461,7 +479,8 @@ WorldMap::finished_level(Level* gamelevel)
   // deal with statistics
   level->statistics.merge(gamelevel->stats);
   calculate_total_stats();
-  if(level->statistics.completed(level->statistics)) {
+  get_level_target_time(*level);
+  if(level->statistics.completed(level->statistics, level->target_time)) {
     level->perfect = true;
     level->sprite->set_action("perfect");
   }
index 1fbf858..29cd50f 100644 (file)
@@ -225,6 +225,7 @@ public:
 
 private:
   void get_level_title(LevelTile& level);
+  void get_level_target_time(LevelTile& level);
   void draw_status(DrawingContext& context);
   void calculate_total_stats();