Shutting up the compiler; first steps on combo tracker; cleanup of stale code
authorMartin Read <martin@blackswordsonics.com>
Sat, 8 Feb 2014 17:12:36 +0000 (17:12 +0000)
committerMartin Read <martin@blackswordsonics.com>
Sat, 8 Feb 2014 17:12:36 +0000 (17:12 +0000)
main.cc

diff --git a/main.cc b/main.cc
index 6243fdd..fa4af2a 100644 (file)
--- a/main.cc
+++ b/main.cc
@@ -36,6 +36,7 @@
 #include <sys/stat.h>
 #include <time.h>
 #include <limits.h>
+#include <deque>
 
 /* Coord/Offset constants */
 Coord const Nowhere = { INT_MIN, INT_MIN };
@@ -87,10 +88,29 @@ static void rebuild_mapobjs(void)
     }
 }
 
+void wrapped_system(char const *cmd)
+{
+    int i = system(cmd);
+    if (i != 0)
+    {
+        throw(i);
+    }
+}
+
+void wrapped_fread(void *buf, size_t size, size_t nmemb, FILE *fp)
+{
+    size_t i = fread(buf, size, nmemb, fp);
+    if (i != nmemb)
+    {
+        throw(i);
+    }
+}
+
 void save_game(void)
 {
     FILE *fp;
     uint32_t tmp;
+    int i;
     fp = fopen("victrix-abyssi.sav", "wb");
     serialize_level(fp, &lvl);
     fwrite(permobjs, NUM_OF_PERMOBJS, sizeof (Permobj), fp);
@@ -108,7 +128,11 @@ void save_game(void)
     fflush(fp);
     fclose(fp);
     /* Compress! */
-    system("gzip victrix-abyssi.sav");
+    i = system("gzip victrix-abyssi.sav");
+    if (i != 0)
+    {
+        /// welp gzip failed
+    }
     game_finished = 1;
     return;
 }
@@ -116,18 +140,18 @@ void save_game(void)
 void load_game(void)
 {
     FILE *fp;
-    system("gunzip victrix-abyssi.sav");
+    wrapped_system("gunzip victrix-abyssi.sav");
     fp = fopen("victrix-abyssi.sav", "rb");
     deserialize_level(fp, &lvl);
-    fread(permobjs, NUM_OF_PERMOBJS, sizeof (Permobj), fp);
-    fread(monsters, MONSTERS_IN_PLAY, sizeof (Mon), fp);
-    fread(objects, OBJECTS_IN_PLAY, sizeof (Obj), fp);
+    wrapped_fread(permobjs, sizeof (Permobj), NUM_OF_PERMOBJS, fp);
+    wrapped_fread(monsters, sizeof (Mon), MONSTERS_IN_PLAY, fp);
+    wrapped_fread(objects, sizeof (Obj), OBJECTS_IN_PLAY, fp);
     rebuild_mapobjs();
     rebuild_mapmons();
-    fread(&depth, 1, sizeof depth, fp);
+    wrapped_fread(&depth, 1, sizeof depth, fp);
     depth = ntohl(depth);
-    fread(&u, 1, sizeof u, fp);
-    fread(&game_tick, 1, sizeof game_tick, fp);
+    wrapped_fread(&u, 1, sizeof u, fp);
+    wrapped_fread(&game_tick, 1, sizeof game_tick, fp);
     fclose(fp);
     look_around_you();
     status_updated = 1;
@@ -137,16 +161,6 @@ void load_game(void)
     unlink("victrix-abyssi.sav");
 }
 
-int exclusive_flat(int lower, int upper)
-{
-    return lower + one_die(upper - lower - 1);
-}
-
-int inclusive_flat(int lower, int upper)
-{
-    return lower + zero_die(upper - lower + 1);
-}
-
 Offset random_step(void)
 {
     switch (zero_die(8))
@@ -171,66 +185,68 @@ Offset random_step(void)
     return Stationary;
 }
 
-Coord inclusive_boxed(Coord topleft, Coord botright)
+void new_game(void)
 {
-    Coord c = { inclusive_flat(topleft.y, botright.y), inclusive_flat(topleft.x, botright.x) };
-    return c;
+    u_init();
+    flavours_init();
+    make_new_level();
+    status_updated = 1;
+    map_updated = 1;
+    hard_redraw = 1;
+    print_msg("Initialisation complete.\n");
 }
 
-Coord exclusive_boxed(Coord topleft, Coord botright)
+std::deque<Action> past_actions;
+
+enum Combo_phase
 {
-    Coord c = { exclusive_flat(topleft.y, botright.y), exclusive_flat(topleft.x, botright.x) };
-    return c;
-}
+    Combo_invalid,
+    Combo_link,
+    Combo_finisher
+};
+/* \brief Process action combos
+ *
+ * This function is responsible for detecting whether the most recently
+ * attempted action is a possible step in a combo, a combo finisher, or a
+ * combo-invalid move (for example, quaffing a potion is a combo breaker). It
+ * uses the contents of the deque past_actions to make the decision.
+ *
+ * \param act Pointer to attempted action
+ * \param revised_act Pointer to storage location for revised action
+ * \return true if revised_act was written to; false otherwise
+ */
 
-int one_die(int sides)
+bool detect_combo(Action const *act, Action *revised_act)
 {
-    int rval;
-    if (sides < 2)
+    //Combo_phase p;
+    // for now, we use if rather than switch because there are only two
+    // valid action types in a combo: move, and attack.
+    if (act->cmd == WALK)
     {
-        return 1;
+        *revised_act = *act;
+        return true;
     }
-    rval = 1 + (rng() / ((RNG_MAX / sides) + 1));
-    return rval;
-}
-
-int zero_die(int sides)
-{
-    int rval;
-    if (sides < 2)
+    else if (act->cmd == ATTACK)
     {
-        return 0;
+        *revised_act = *act;
+        return true;
     }
-    rval = rng() / ((RNG_MAX / sides) + 1);
-    return rval;
-}
-
-int dice(int count, int sides)
-{
-    int total = 0;
-    for ( ; count > 0; count--)
+    else
     {
-        total += one_die(sides);
+        return false;
     }
-    return total;
-}
-
-void new_game(void)
-{
-    u_init();
-    flavours_init();
-    make_new_level();
-    status_updated = 1;
-    map_updated = 1;
-    hard_redraw = 1;
-    print_msg("Initialisation complete.\n");
 }
 
 Action_cost do_player_action(Action *act)
 {
     int slot;
-    Action_cost cost;
     Offset step;
+    Action redact;
+    bool rewritten = detect_combo(act, &redact);
+    if (rewritten)
+    {
+        act = &redact;
+    }
     switch (act->cmd)
     {
     case WALK:
@@ -276,37 +292,13 @@ Action_cost do_player_action(Action *act)
         break;
 
     case WEAR_ARMOUR:
-        cost = Cost_none;
-        if (u.armour != NO_OBJ)
-        {
-            print_msg("You are already wearing armour.\n");
-        }
-        else
-        {
-            slot = inv_select(POCLASS_ARMOUR, "wear", 0);
-            if (slot != SLOT_CANCEL)
-            {
-                u.armour = u.inventory[slot];
-                recalc_defence();
-                if (objects[u.armour].obj_id == PO_SET_OF_RIBBONS)
-                {
-                    print_msg("You grit your teeth, trying to get used to the tingle of\nthe ribbons' magic against your skin.\n");
-                }
-                else
-                {
-                    print_msg("Wearing ");
-                    print_obj_name(u.armour);
-                    print_msg(".\n");
-                }
-                cost = Cost_std;
-            }
-        }
-        return cost;
+        slot = act->details[0];
+        return wear_armour(slot);
 
     case EMANATE_ARMOUR:
         if (u.armour == NO_OBJ)
         {
-            print_msg("You are not wearing any armour.\n");
+            notify_emanate_no_armour();
             return Cost_none;
         }
         return emanate_armour();
@@ -314,7 +306,7 @@ Action_cost do_player_action(Action *act)
     case ZAP_WEAPON:
         if (u.weapon == NO_OBJ)
         {
-            print_msg("You have no weapon in hand.\n");
+            notify_zap_no_weapon();
             return Cost_none;
         }
         return zap_weapon();
@@ -322,7 +314,7 @@ Action_cost do_player_action(Action *act)
     case MAGIC_RING:
         if (u.weapon == NO_OBJ)
         {
-            print_msg("You are not wearing a ring.\n");
+            notify_magic_no_ring();
             return Cost_none;
         }
         return magic_ring();
@@ -429,12 +421,12 @@ Action_cost do_player_action(Action *act)
 void main_loop(void)
 {
     int i;
-    int action_speed;
+    int action_speed = 0;
     print_msg("Welcome to the Abyss, Princess %s.\n", u.name);
     print_msg("Press '?' for help.\n");
     while (!game_finished)
     {
-        switch (game_tick % 4)
+        switch (game_tick & 3)
         {
         case 0:
         case 2:
@@ -494,8 +486,6 @@ int main(void)
     struct stat s;
     int i;
     display_init();
-    memset(lvl.objs, -1, sizeof lvl.objs);
-    memset(lvl.mons, -1, sizeof lvl.mons);
     rng_init();
     /* Do we have a saved game? */
     i = stat("victrix-abyssi.sav.gz", &s);