rnd-20040129-1-src
authorHolger Schemel <info@artsoft.org>
Thu, 29 Jan 2004 16:39:26 +0000 (17:39 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:45:39 +0000 (10:45 +0200)
* fixed bug: infotron can now smash yellow disks
* added "choice type" for group element selection
* fixed bug with initial invulnerability of non-yellow player
* added level loader for loading native Supaplex packed levels
  (including multi-part levels like the "splvls99" levels)

ChangeLog
src/conftime.h
src/editor.c
src/files.c
src/game.c
src/libgame/system.h
src/main.h

index aa185bf5e07d1966295f2a3cbe5ce8b3e63cea0e..3f77708c044a9ac4235020688dd0439f094dd46e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2004-01-29
+       * fixed bug: infotron can now smash yellow disks
+
+2004-01-26
+       * added "choice type" for group element selection
+
+2004-01-25
+       * fixed bug with initial invulnerability of non-yellow player
+
+2004-01-23
+       * added level loader for loading native Supaplex packed levels
+         (including multi-part levels like the "splvls99" levels)
 
 2004-01-19
        * fixed bug which allowed creating emeralds by escaping explosions
index 63f8de9cd6c71e705e4d83a7c47888165d1a67d2..c163785e19076b4af24025f425bde8d76b51225c 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2004-01-25 13:45]"
+#define COMPILE_DATE_STRING "[2004-01-29 17:39]"
index c58d03efa120d15c34f053ada3f1425808606176..44afd5ca752523b4e3055f36b10a4a2a3ff2c9a9 100644 (file)
 #define GADGET_ID_CHANGE_SIDES         (GADGET_ID_SELECTBOX_FIRST + 14)
 #define GADGET_ID_CHANGE_POWER         (GADGET_ID_SELECTBOX_FIRST + 15)
 #define GADGET_ID_SELECT_CHANGE_PAGE   (GADGET_ID_SELECTBOX_FIRST + 16)
+#define GADGET_ID_GROUP_CHOICE_MODE    (GADGET_ID_SELECTBOX_FIRST + 17)
 
 /* textbutton identifiers */
-#define GADGET_ID_TEXTBUTTON_FIRST     (GADGET_ID_SELECTBOX_FIRST + 17)
+#define GADGET_ID_TEXTBUTTON_FIRST     (GADGET_ID_SELECTBOX_FIRST + 18)
 
 #define GADGET_ID_PROPERTIES_INFO      (GADGET_ID_TEXTBUTTON_FIRST + 0)
 #define GADGET_ID_PROPERTIES_CONFIG    (GADGET_ID_TEXTBUTTON_FIRST + 1)
 #define ED_SELECTBOX_ID_CHANGE_SIDES           14
 #define ED_SELECTBOX_ID_CHANGE_POWER           15
 #define ED_SELECTBOX_ID_SELECT_CHANGE_PAGE     16
+#define ED_SELECTBOX_ID_GROUP_CHOICE_MODE      17
 
-#define ED_NUM_SELECTBOX                       17
+#define ED_NUM_SELECTBOX                       18
 
 #define ED_SELECTBOX_ID_CUSTOM_FIRST   ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE
 #define ED_SELECTBOX_ID_CUSTOM_LAST    ED_SELECTBOX_ID_CUSTOM_CONSISTENCY
@@ -1141,7 +1143,7 @@ static struct ValueTextInfo options_move_stepsize[] =
 static struct ValueTextInfo options_move_leave_type[] =
 {
   { LEAVE_TYPE_UNLIMITED,      "leave behind"                  },
-  { LEAVE_TYPE_LIMITED,                "change to"                     },
+  { LEAVE_TYPE_LIMITED,                "change it to"                  },
   { -1,                                NULL                            }
 };
 
@@ -1256,6 +1258,16 @@ static struct ValueTextInfo options_change_page[MAX_CHANGE_PAGES + 1] =
   { -1,                                NULL                            }
 };
 
+static struct ValueTextInfo options_group_choice_mode[] =
+{
+  { ANIM_RANDOM,               "random"                        },
+  { ANIM_LOOP,                 "loop"                          },
+  { ANIM_LINEAR,               "linear"                        },
+  { ANIM_PINGPONG,             "pingpong"                      },
+  { ANIM_PINGPONG2,            "pingpong 2"                    },
+  { -1,                                NULL                            }
+};
+
 static struct
 {
   int x, y;
@@ -1408,6 +1420,17 @@ static struct
     &custom_element.current_change_page,
     NULL, NULL,                                "element config page"
   },
+
+  /* ---------- element settings: configure (group elements) --------------- */
+
+  {
+    ED_SETTINGS_XPOS(0),               ED_SETTINGS_YPOS(10),
+    GADGET_ID_GROUP_CHOICE_MODE,       GADGET_ID_NONE,
+    -1,
+    options_group_choice_mode,
+    &group_element_info.choice_mode,
+    "choice type:", NULL,              "type of group element choice"
+  },
 };
 
 static struct
@@ -6536,6 +6559,9 @@ static void DrawPropertiesConfig()
     /* draw counter gadgets */
     MapCounterButtons(ED_COUNTER_ID_GROUP_CONTENT);
 
+    /* draw selectbox gadgets */
+    MapSelectboxGadget(ED_SELECTBOX_ID_GROUP_CHOICE_MODE);
+
     /* draw drawing area gadgets */
     DrawGroupElementArea(properties_element);
 
@@ -7804,7 +7830,8 @@ static void HandleSelectboxGadgets(struct GadgetInfo *gi)
   else if ((type_id >= ED_SELECTBOX_ID_CUSTOM_FIRST &&
            type_id <= ED_SELECTBOX_ID_CUSTOM_LAST) ||
           (type_id >= ED_SELECTBOX_ID_CHANGE_FIRST &&
-           type_id <= ED_SELECTBOX_ID_CHANGE_LAST))
+           type_id <= ED_SELECTBOX_ID_CHANGE_LAST) ||
+          (type_id == ED_SELECTBOX_ID_GROUP_CHOICE_MODE))
     CopyElementPropertiesToGame(properties_element);
 }
 
index e365cd1f8c8dd4f28916a38b8541d6b43e9fa990..40cdbcf4274549672be9cc57f8571f607028df82 100644 (file)
@@ -258,6 +258,8 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
 
       /* default: only one element in group */
       element_info[element].group->num_elements = 1;
+
+      element_info[element].group->choice_mode = ANIM_RANDOM;
     }
   }
 
@@ -1077,8 +1079,10 @@ static int LoadLevel_GRP1(FILE *file, int chunk_size, struct LevelInfo *level)
   ei->use_gfx_element = getFile8Bit(file);
   ei->gfx_element = getMappedElement(getFile16BitBE(file));
 
+  group->choice_mode = getFile8Bit(file);
+
   /* some free bytes for future values and padding */
-  ReadUnusedBytesFromFile(file, 4);
+  ReadUnusedBytesFromFile(file, 3);
 
   for (i = 0; i < MAX_ELEMENTS_IN_GROUP; i++)
     group->element[i] = getMappedElement(getFile16BitBE(file));
@@ -2488,8 +2492,10 @@ static void SaveLevel_GRP1(FILE *file, struct LevelInfo *level, int element)
   putFile8Bit(file, ei->use_gfx_element);
   putFile16BitBE(file, ei->gfx_element);
 
+  putFile8Bit(file, group->choice_mode);
+
   /* some free bytes for future values and padding */
-  WriteUnusedBytesToFile(file, 4);
+  WriteUnusedBytesToFile(file, 3);
 
   for (i = 0; i < MAX_ELEMENTS_IN_GROUP; i++)
     putFile16BitBE(file, group->element[i]);
index bab2a31211f966ac2cfa56d2328e64da733fd4f6..6e5475ebd9bf1bba0b561fd55d9485de5900501c 100644 (file)
@@ -810,9 +810,22 @@ static void InitField(int x, int y, boolean init_game)
       else if (IS_GROUP_ELEMENT(element))
       {
        struct ElementGroupInfo *group = element_info[element].group;
-       int random_pos = RND(group->num_elements_resolved);
+       int last_anim_random_frame = gfx.anim_random_frame;
+       int element_pos;
 
-       Feld[x][y] = group->element_resolved[random_pos];
+       if (group->choice_mode == ANIM_RANDOM)
+         gfx.anim_random_frame = RND(group->num_elements_resolved);
+
+       element_pos = getAnimationFrame(group->num_elements_resolved, 1,
+                                       group->choice_mode, 0,
+                                       group->choice_pos);
+
+       if (group->choice_mode == ANIM_RANDOM)
+         gfx.anim_random_frame = last_anim_random_frame;
+
+       group->choice_pos++;
+
+       Feld[x][y] = group->element_resolved[element_pos];
 
        InitField(x, y, init_game);
       }
@@ -861,8 +874,10 @@ static void resolve_group_element(int group_element, int recursion_depth)
   if (recursion_depth == 0)                    /* initialization */
   {
     group = element_info[group_element].group;
-    group->num_elements_resolved = 0;
     group_nr = group_element - EL_GROUP_START;
+
+    group->num_elements_resolved = 0;
+    group->choice_pos = 0;
   }
 
   for (i = 0; i < actual_group->num_elements; i++)
@@ -1406,7 +1421,9 @@ void InitGame()
        {
          player->present = TRUE;
          player->active = TRUE;
+
          some_player->present = FALSE;
+         some_player->active = FALSE;
 
          StorePlayer[jx][jy] = player->element_nr;
          player->jx = player->last_jx = jx;
@@ -1420,7 +1437,7 @@ void InitGame()
 
   if (tape.playing)
   {
-    /* when playing a tape, eliminate all players who do not participate */
+    /* when playing a tape, eliminate all players which do not participate */
 
     for (i = 0; i < MAX_PLAYERS; i++)
     {
@@ -1451,6 +1468,8 @@ void InitGame()
            int jx = player->jx, jy = player->jy;
 
            player->active = FALSE;
+           player->present = FALSE;
+
            StorePlayer[jx][jy] = 0;
            Feld[jx][jy] = EL_EMPTY;
          }
@@ -3347,11 +3366,13 @@ void Impact(int x, int y)
        return;
       }
     }
-    else if ((element == EL_SP_INFOTRON ||
-             element == EL_SP_ZONK) &&
-            (smashed == EL_SP_SNIKSNAK ||
-             smashed == EL_SP_ELECTRON ||
-             smashed == EL_SP_DISK_ORANGE))
+    else if (((element == EL_SP_INFOTRON ||
+              element == EL_SP_ZONK) &&
+             (smashed == EL_SP_SNIKSNAK ||
+              smashed == EL_SP_ELECTRON ||
+              smashed == EL_SP_DISK_ORANGE)) ||
+            (element == EL_SP_INFOTRON &&
+             smashed == EL_SP_DISK_YELLOW))
     {
       Bang(x, y + 1);
       return;
@@ -5116,6 +5137,7 @@ void ContinueMoving(int x, int y)
   ResetGfxAnimation(x, y);     /* reset animation values for old field */
 
 #if 1
+  /* some elements can leave other elements behind after moving */
   if (IS_CUSTOM_ELEMENT(element) && !IS_PLAYER(x, y) &&
       ei->move_leave_element != EL_EMPTY &&
       (ei->move_leave_type == LEAVE_TYPE_UNLIMITED ||
@@ -7528,6 +7550,40 @@ void ScrollLevel(int dx, int dy)
   redraw_mask |= REDRAW_FIELD;
 }
 
+static boolean canEnterSupaplexPort(int x, int y, int move_dir)
+{
+  int dx = (move_dir & MV_LEFT ? -1 : move_dir & MV_RIGHT ? +1 : 0);
+  int dy = (move_dir & MV_UP ? -1 : move_dir & MV_DOWN ? +1 : 0);
+  int nextx = x + dx, nexty = y + dy;
+  int element = Feld[x][y];
+
+  if ((dx == -1 &&
+       element != EL_SP_PORT_LEFT &&
+       element != EL_SP_GRAVITY_PORT_LEFT &&
+       element != EL_SP_PORT_HORIZONTAL &&
+       element != EL_SP_PORT_ANY) ||
+      (dx == +1 &&
+       element != EL_SP_PORT_RIGHT &&
+       element != EL_SP_GRAVITY_PORT_RIGHT &&
+       element != EL_SP_PORT_HORIZONTAL &&
+       element != EL_SP_PORT_ANY) ||
+      (dy == -1 &&
+       element != EL_SP_PORT_UP &&
+       element != EL_SP_GRAVITY_PORT_UP &&
+       element != EL_SP_PORT_VERTICAL &&
+       element != EL_SP_PORT_ANY) ||
+      (dy == +1 &&
+       element != EL_SP_PORT_DOWN &&
+       element != EL_SP_GRAVITY_PORT_DOWN &&
+       element != EL_SP_PORT_VERTICAL &&
+       element != EL_SP_PORT_ANY) ||
+      !IN_LEV_FIELD(nextx, nexty) ||
+      !IS_FREE(nextx, nexty))
+    return FALSE;
+
+  return TRUE;
+}
+
 static void CheckGravityMovement(struct PlayerInfo *player)
 {
   if (game.gravity && !player->programmed_action)
index af6b95a259e841b9775811103dd640ad1317be01..086f01c2aa11a5a73627878f7fca9f54c1831e82 100644 (file)
 #define SETUP_FILENAME         "setup.cnf"
 #define LEVELSETUP_FILENAME    "lvlsetup.cnf"
 #define EDITORSETUP_FILENAME   "edsetup.cnf"
-#define HELPANIM_FILENAME      "helpanim.conf"
-#define HELPTEXT_FILENAME      "helptext.conf"
+#define HELPANIM_FILENAME      "helpanim.cnf"
+#define HELPTEXT_FILENAME      "helptext.cnf"
 #define LEVELINFO_FILENAME     "lvlinfo.cnf"
 #define GRAPHICSINFO_FILENAME  "gfxinfo.cnf"
 #define SOUNDSINFO_FILENAME    "sndinfo.cnf"
index 062c7a603bb9b8b38003f3635262f89968cdaef8..9d78b18a008fdf70bded85d3c9fdaea6cbce07db 100644 (file)
@@ -1483,12 +1483,16 @@ struct ElementGroupInfo
   int num_elements;                    /* number of elements in this group */
   short element[MAX_ELEMENTS_IN_GROUP];        /* list of elements in this group */
 
+  int choice_mode;             /* how to choose element from group */
+
   /* ---------- internal values used at runtime when playing ---------- */
 
   /* the following is the same as above, but with recursively resolved group
      elements (group elements may also contain further group elements!) */
   int num_elements_resolved;
   short element_resolved[NUM_FILE_ELEMENTS];
+
+  int choice_pos;              /* current element choice position */
 };
 
 struct ElementInfo