A potential future improvement to this mechanism would be adding an optional "target_time" to levels which needs to be reached before the level is marked as "perfect".
Note that this change will cause a one-time reset of all level stats- sorry.
glow effects
new badguys: iceflame, ghostflame, livefire, goldbomb, smartblock
new bonuses: coinrain, coinexplode
+statistics improved
Supertux Release 0.3.4 (2013-07)
--------------------------------
(hitbox 16 16 0 0)
(images "leveldot_green.png")
)
+ (action
+ (name "perfect")
+ (hitbox 16 16 0 0)
+ (images "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green_perfect-0.png"
+ "leveldot_green_perfect-1.png"
+ "leveldot_green_perfect-2.png"
+ "leveldot_green_perfect-3.png"
+ "leveldot_green_perfect-2.png"
+ "leveldot_green_perfect-1.png"
+ "leveldot_green_perfect-0.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png")
+ )
)
(hitbox 16 16 0 0)
(images "leveldot_green.png")
)
+ (action
+ (name "perfect")
+ (hitbox 16 16 0 0)
+ (images "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green_perfect-0.png"
+ "leveldot_green_perfect-1.png"
+ "leveldot_green_perfect-2.png"
+ "leveldot_green_perfect-3.png"
+ "leveldot_green_perfect-2.png"
+ "leveldot_green_perfect-1.png"
+ "leveldot_green_perfect-0.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png")
+ )
)
(hitbox 16 16 0 0)
(images "leveldot_green.png")
)
+ (action
+ (name "perfect")
+ (hitbox 16 16 0 0)
+ (images "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green_perfect-0.png"
+ "leveldot_green_perfect-1.png"
+ "leveldot_green_perfect-2.png"
+ "leveldot_green_perfect-3.png"
+ "leveldot_green_perfect-2.png"
+ "leveldot_green_perfect-1.png"
+ "leveldot_green_perfect-0.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png"
+ "leveldot_green.png")
+ )
)
(action
(name "solved")
(hitbox 16 16 0 0)
+ (images "level_star.png")
+ )
+ (action
+ (name "perfect")
+ (hitbox 16 16 0 0)
(images "level_star.png"
"level_star1.png"
"level_star1.png"
if (s2.total_secrets != nv_secrets) total_secrets += s2.total_secrets;
}
+bool
+Statistics::completed(const Statistics& stats)
+{
+ return (stats.coins == stats.total_coins &&
+ stats.badguys == stats.total_badguys &&
+ stats.secrets == stats.total_secrets);
+}
+
void
Statistics::declare_invalid()
{
Statistics(); /**< Creates new statistics, call reset() before counting */
~Statistics();
- /// read statistics from lisp file
- //void parse(const Reader& lisp);
- /// write statistics to lisp file
- //void write(Writer& writer);
-
/**
* serialize statistics object as squirrel table "statistics"
*/
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 */
void declare_invalid(); /**< marks statistics as invalid for their entire lifetime (e.g. after cheating). Invalid statistics will not be merged or drawn. */
pos(),
title(),
solved(false),
+ perfect(false),
auto_play(false),
sprite(),
statistics(),
Vector pos;
std::string title;
bool solved;
+ bool perfect;
bool auto_play; /**< true if Tux should automatically enter this level if it's unfinished */
SpritePtr sprite;
// We got a new direction, so lets start walking when possible
Vector next_tile;
- if ((!level || level->solved)
+ if ((!level || level->solved || level->perfect)
&& worldmap->path_ok(input_direction, tile_pos, &next_tile)) {
tile_pos = next_tile;
moving = true;
// deal with statistics
level->statistics.merge(gamelevel->stats);
calculate_total_stats();
+ if(level->statistics.completed(level->statistics)) {
+ level->perfect = true;
+ level->sprite->set_action("perfect");
+ }
save_state();
sq_newtable(vm);
store_bool(vm, "solved", level->solved);
+ store_bool(vm, "perfect", level->perfect);
level->statistics.serialize_to_squirrel(vm);
sq_createslot(vm, -3);
sq_pushstring(vm, level->get_name().c_str(), -1);
if(SQ_SUCCEEDED(sq_get(vm, -2))) {
level->solved = read_bool(vm, "solved");
- level->sprite->set_action(level->solved ? "solved" : "default");
+ level->perfect = read_bool(vm, "perfect");
+ if(!level->solved)
+ level->sprite->set_action("default");
+ else
+ level->sprite->set_action((level->sprite->has_action("perfect") && level->perfect) ? "perfect" : "solved");
level->statistics.unserialize_from_squirrel(vm);
sq_pop(vm, 1);
}