rnd-20030502-2-src
authorHolger Schemel <info@artsoft.org>
Fri, 2 May 2003 19:07:21 +0000 (21:07 +0200)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:41:41 +0000 (10:41 +0200)
src/conftime.h
src/editor.c
src/files.c
src/game.c
src/main.h

index 3660059167364cbc578f41684c5041bf3fa92f1e..a1c7eb1ebbb97d3cb91b4dace568697a7ca10fd8 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2003-05-02 17:40]"
+#define COMPILE_DATE_STRING "[2003-05-02 20:55]"
index 6a054d19f25e344160575ff308a6b8898e168a6a..a726f9139671e95d179840c3a14ce2ae93ef4dfb 100644 (file)
@@ -566,8 +566,8 @@ static int random_placement_background_element = EL_SAND;
 static boolean random_placement_background_restricted = FALSE;
 static boolean stick_element_properties_window = FALSE;
 static boolean custom_element_properties[NUM_ELEMENT_PROPERTIES];
-static boolean custom_element_changes[42];
-static int custom_element_change_delay[2];
+static boolean custom_element_change_events[NUM_CHANGE_EVENTS];
+static struct CustomElementChangeInfo custom_element_change;
 
 static struct
 {
@@ -656,16 +656,16 @@ static struct
     0,                                 999,
     GADGET_ID_CHANGE_DELAY_FIX_DOWN,   GADGET_ID_CHANGE_DELAY_FIX_UP,
     GADGET_ID_CHANGE_DELAY_FIX_TEXT,
-    &custom_element_change_delay[0],
-    NULL,                              "frames (fixed)"
+    &custom_element_change.delay_fixed,
+    NULL,                              "seconds (fixed)"
   },
   {
     ED_COUNT_CHANGE_DELAY_XPOS,                ED_COUNTER_YPOS2(6),
     0,                                 999,
     GADGET_ID_CHANGE_DELAY_RND_DOWN,   GADGET_ID_CHANGE_DELAY_RND_UP,
     GADGET_ID_CHANGE_DELAY_RND_TEXT,
-    &custom_element_change_delay[1],
-    NULL,                              "frames (random)"
+    &custom_element_change.delay_random,
+    NULL,                              "seconds (random)"
   }
 };
 
@@ -974,13 +974,13 @@ static struct
   {
     ED_SETTINGS_XPOS2,                 ED_COUNTER_YPOS2(5),
     GADGET_ID_CHANGE_DELAY_FIXED,
-    &custom_element_changes[0],
+    &custom_element_change_events[CE_DELAY_FIXED],
     "delay of",                                "element changes after fixed delay"
   },
   {
     ED_SETTINGS_XPOS2,                 ED_COUNTER_YPOS2(6),
     GADGET_ID_CHANGE_DELAY_RANDOM,
-    &custom_element_changes[1],
+    &custom_element_change_events[CE_DELAY_RANDOM],
     "delay of",                                "element changes after random delay"
   }
 };
@@ -2911,16 +2911,28 @@ static void CopyCustomElementPropertiesToEditor(int element)
 {
   int i;
 
+  i = properties_element - EL_CUSTOM_START;
+  custom_element_change = level.custom_element[i].change;
+
   for (i=0; i < NUM_ELEMENT_PROPERTIES; i++)
     custom_element_properties[i] = HAS_PROPERTY(element, i);
+
+  for (i=0; i < NUM_CHANGE_EVENTS; i++)
+    custom_element_change_events[i] = HAS_CHANGE_EVENT(element, i);
 }
 
 static void CopyCustomElementPropertiesToGame(int element)
 {
   int i;
 
+  i = properties_element - EL_CUSTOM_START;
+  level.custom_element[i].change = custom_element_change;
+
   for (i=0; i < NUM_ELEMENT_PROPERTIES; i++)
     SET_PROPERTY(element, i, custom_element_properties[i]);
+
+  for (i=0; i < NUM_CHANGE_EVENTS; i++)
+    SET_CHANGE_EVENT(element, i, custom_element_change_events[i]);
 }
 
 void DrawLevelEd()
@@ -3324,7 +3336,7 @@ static void DrawCustomChangedArea()
   int area_y = ypos / MINI_TILEY;
   int area_sx = SX + xpos;
   int area_sy = SY + ypos;
-  int element = properties_element - EL_CUSTOM_START;
+  int i = properties_element - EL_CUSTOM_START;
 
   if (!IS_CUSTOM_ELEMENT(properties_element))
   {
@@ -3334,7 +3346,7 @@ static void DrawCustomChangedArea()
     return;
   }
 
-  ElementContent[0][0][0] = level.custom_element_successor[element];
+  ElementContent[0][0][0] = level.custom_element[i].change.successor;
 
   DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY);
   DrawMiniElement(area_x, area_y, ElementContent[0][0][0]);
@@ -3903,14 +3915,14 @@ static void DrawPropertiesAdvanced()
 {
   char infotext[MAX_OUTPUT_LINESIZE + 1];
   int max_infotext_len = getMaxInfoTextLength();
-  int xoffset_above = 0;
-  int yoffset_above = -(MINI_TILEX + ED_GADGET_DISTANCE);
   int xoffset_right = getCounterGadgetWidth();
   int yoffset_right = ED_BORDER_SIZE;
   int xoffset_right2 = ED_CHECKBUTTON_XSIZE + 2 * ED_GADGET_DISTANCE;
   int yoffset_right2 = ED_BORDER_SIZE;
   int i, x, y;
 
+  CopyCustomElementPropertiesToEditor(properties_element);
+
   /* draw stickybutton gadget */
   i = ED_CHECKBUTTON_ID_STICK_ELEMENT;
   x = checkbutton_info[i].x + xoffset_right2;
@@ -3924,16 +3936,6 @@ static void DrawPropertiesAdvanced()
   /* draw counter gadgets */
   for (i=ED_COUNTER_ID_CHANGE_FIRST; i<=ED_COUNTER_ID_CHANGE_LAST; i++)
   {
-    if (counterbutton_info[i].infotext_above)
-    {
-      x = counterbutton_info[i].x + xoffset_above;
-      y = counterbutton_info[i].y + yoffset_above;
-
-      sprintf(infotext, "%s:", counterbutton_info[i].infotext_above);
-      infotext[max_infotext_len] = '\0';
-      DrawTextF(x, y, FONT_TEXT_1, infotext);
-    }
-
     if (counterbutton_info[i].infotext_right)
     {
       x = counterbutton_info[i].x + xoffset_right;
@@ -4754,7 +4756,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
        {
          int i = properties_element - EL_CUSTOM_START;
 
-         level.custom_element_successor[i] = new_element;
+         level.custom_element[i].change.successor = new_element;
        }
        else if (id == GADGET_ID_RANDOM_BACKGROUND)
          random_placement_background_element = new_element;
@@ -4922,6 +4924,10 @@ static void HandleCounterButtons(struct GadgetInfo *gi)
     default:
       break;
   }
+
+  if (counter_id >= ED_COUNTER_ID_CHANGE_FIRST &&
+      counter_id <= ED_COUNTER_ID_CHANGE_LAST)
+    CopyCustomElementPropertiesToGame(properties_element);
 }
 
 static void HandleTextInputGadgets(struct GadgetInfo *gi)
@@ -4965,8 +4971,10 @@ static void HandleCheckbuttons(struct GadgetInfo *gi)
 
   *checkbutton_info[type_id].value ^= TRUE;
 
-  if (type_id >= ED_CHECKBUTTON_ID_CUSTOM_FIRST &&
-      type_id <= ED_CHECKBUTTON_ID_CUSTOM_LAST)
+  if ((type_id >= ED_CHECKBUTTON_ID_CUSTOM_FIRST &&
+       type_id <= ED_CHECKBUTTON_ID_CUSTOM_LAST) ||
+      (type_id >= ED_CHECKBUTTON_ID_CHANGE_FIRST &&
+       type_id <= ED_CHECKBUTTON_ID_CHANGE_LAST))
     CopyCustomElementPropertiesToGame(properties_element);
 }
 
index 1321fe9cc7be00bc3511c13887a56af1a331aef4..c94e1a5c5f01cd60d35cf7774200c08b683ee9cc 100644 (file)
@@ -97,7 +97,10 @@ static void setLevelInfoToDefaults()
 
   for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
   {
-    level.custom_element_successor[i] = EL_EMPTY_SPACE;
+    level.custom_element[i].change.events = CE_BITMASK_DEFAULT;
+    level.custom_element[i].change.successor = EL_EMPTY_SPACE;
+    level.custom_element[i].change.delay_fixed = 0;
+    level.custom_element[i].change.delay_random = 0;
 
     /* start with no properties at all */
 #if 1
@@ -372,7 +375,7 @@ static int LoadLevel_CUS2(FILE *file, int chunk_size, struct LevelInfo *level)
     int i = element - EL_CUSTOM_START;
 
     if (IS_CUSTOM_ELEMENT(element))
-      level->custom_element_successor[i] = custom_element_successor;
+      level->custom_element[i].change.successor = custom_element_successor;
     else
       Error(ERR_WARN, "invalid custom element number %d", element);
   }
@@ -762,12 +765,12 @@ static void SaveLevel_CUS2(FILE *file, struct LevelInfo *level,
   {
     int element = EL_CUSTOM_START + i;
 
-    if (level->custom_element_successor[i] != EL_EMPTY_SPACE)
+    if (level->custom_element[i].change.successor != EL_EMPTY_SPACE)
     {
       if (check < num_changed_custom_elements)
       {
        putFile16BitBE(file, element);
-       putFile16BitBE(file, level->custom_element_successor[i]);
+       putFile16BitBE(file, level->custom_element[i].change.successor);
       }
 
       check++;
@@ -827,7 +830,7 @@ void SaveLevel(int level_nr)
 
   /* check for non-standard custom elements and calculate "CUS2" chunk size */
   for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
-    if (level.custom_element_successor[i] != EL_EMPTY_SPACE)
+    if (level.custom_element[i].change.successor != EL_EMPTY_SPACE)
       num_changed_custom_elements2++;
 
   putFileChunkBE(file, "RND1", CHUNK_SIZE_UNDEFINED);
index 55658d8028daa1452f936a5e4398fe2d89a9db76..38445772bead7746bf5fc0738298e8611e1ab154 100644 (file)
@@ -154,38 +154,144 @@ struct ChangingElementInfo
 
 static struct ChangingElementInfo changing_element_list[] =
 {
-  { EL_NUT_BREAKING,           EL_EMERALD,              6, NULL, NULL, NULL },
-  { EL_PEARL_BREAKING,         EL_EMPTY,                8, NULL, NULL, NULL },
-  { EL_EXIT_OPENING,           EL_EXIT_OPEN,           29, NULL, NULL, NULL },
-
-  { EL_SWITCHGATE_OPENING,     EL_SWITCHGATE_OPEN,     29, NULL, NULL, NULL },
-  { EL_SWITCHGATE_CLOSING,     EL_SWITCHGATE_CLOSED,   29, NULL, NULL, NULL },
-
-  { EL_TIMEGATE_OPENING,       EL_TIMEGATE_OPEN,       29, NULL, NULL, NULL },
-  { EL_TIMEGATE_CLOSING,       EL_TIMEGATE_CLOSED,     29, NULL, NULL, NULL },
-
-  { EL_ACID_SPLASH_LEFT,       EL_EMPTY,                8, NULL, NULL, NULL },
-  { EL_ACID_SPLASH_RIGHT,      EL_EMPTY,                8, NULL, NULL, NULL },
-
-  { EL_SP_BUGGY_BASE,          EL_SP_BUGGY_BASE_ACTIVATING, 0,
-    InitBuggyBase, NULL, NULL },
-  { EL_SP_BUGGY_BASE_ACTIVATING,EL_SP_BUGGY_BASE_ACTIVE, 0,
-    InitBuggyBase, NULL, NULL },
-  { EL_SP_BUGGY_BASE_ACTIVE,   EL_SP_BUGGY_BASE,        0,
-    InitBuggyBase, WarnBuggyBase, NULL },
-
-  { EL_TRAP,                   EL_TRAP_ACTIVE,          0,
-    InitTrap, NULL, ActivateTrap },
-  { EL_TRAP_ACTIVE,            EL_TRAP,                31,
-    NULL, ChangeActiveTrap, NULL },
-
-  { EL_ROBOT_WHEEL_ACTIVE,     EL_ROBOT_WHEEL,          0,
-    InitRobotWheel, RunRobotWheel, StopRobotWheel },
+  {
+    EL_NUT_BREAKING,
+    EL_EMERALD,
+    6,
+    NULL,
+    NULL,
+    NULL
+  },
+  {
+    EL_PEARL_BREAKING,
+    EL_EMPTY,
+    8,
+    NULL,
+    NULL,
+    NULL
+  },
+  {
+    EL_EXIT_OPENING,
+    EL_EXIT_OPEN,
+    29,
+    NULL,
+    NULL,
+    NULL
+  },
+  {
+    EL_SWITCHGATE_OPENING,
+    EL_SWITCHGATE_OPEN,
+    29,
+    NULL,
+    NULL,
+    NULL
+  },
+  {
+    EL_SWITCHGATE_CLOSING,
+    EL_SWITCHGATE_CLOSED,
+    29,
+    NULL,
+    NULL,
+    NULL
+  },
+  {
+    EL_TIMEGATE_OPENING,
+    EL_TIMEGATE_OPEN,
+    29,
+    NULL,
+    NULL,
+    NULL
+  },
+  {
+    EL_TIMEGATE_CLOSING,
+    EL_TIMEGATE_CLOSED,
+    29,
+    NULL,
+    NULL,
+    NULL
+  },
 
-  { EL_TIMEGATE_SWITCH_ACTIVE, EL_TIMEGATE_SWITCH,      0,
-    InitTimegateWheel, RunTimegateWheel, NULL },
+  {
+    EL_ACID_SPLASH_LEFT,
+    EL_EMPTY,
+    8,
+    NULL,
+    NULL,
+    NULL
+  },
+  {
+    EL_ACID_SPLASH_RIGHT,
+    EL_EMPTY,
+    8,
+    NULL,
+    NULL,
+    NULL
+  },
+  {
+    EL_SP_BUGGY_BASE,
+    EL_SP_BUGGY_BASE_ACTIVATING,
+    0,
+    InitBuggyBase,
+    NULL,
+    NULL
+  },
+  {
+    EL_SP_BUGGY_BASE_ACTIVATING,
+    EL_SP_BUGGY_BASE_ACTIVE,
+    0,
+    InitBuggyBase,
+    NULL,
+    NULL
+  },
+  {
+    EL_SP_BUGGY_BASE_ACTIVE,
+    EL_SP_BUGGY_BASE,
+    0,
+    InitBuggyBase,
+    WarnBuggyBase,
+    NULL
+  },
+  {
+    EL_TRAP,
+    EL_TRAP_ACTIVE,
+    0,
+    InitTrap,
+    NULL,
+    ActivateTrap
+  },
+  {
+    EL_TRAP_ACTIVE,
+    EL_TRAP,
+    31,
+    NULL,
+    ChangeActiveTrap,
+    NULL
+  },
+  {
+    EL_ROBOT_WHEEL_ACTIVE,
+    EL_ROBOT_WHEEL,
+    0,
+    InitRobotWheel,
+    RunRobotWheel,
+    StopRobotWheel
+  },
+  {
+    EL_TIMEGATE_SWITCH_ACTIVE,
+    EL_TIMEGATE_SWITCH,
+    0,
+    InitTimegateWheel,
+    RunTimegateWheel,
+    NULL
+  },
 
-  { EL_UNDEFINED,              EL_UNDEFINED,           -1, NULL        }
+  {
+    EL_UNDEFINED,
+    EL_UNDEFINED,
+    -1,
+    NULL,
+    NULL,
+    NULL
+  }
 };
 
 static struct ChangingElementInfo changing_element[MAX_NUM_ELEMENTS];
@@ -561,6 +667,7 @@ static void InitGameEngine()
     changing_element[i].post_change_function = NULL;
   }
 
+  /* add changing elements from pre-defined list */
   i = 0;
   while (changing_element_list[i].base_element != EL_UNDEFINED)
   {
@@ -576,6 +683,30 @@ static void InitGameEngine()
 
     i++;
   }
+
+  /* add changing elements from custom element configuration */
+  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+  {
+    struct CustomElementChangeInfo *change = &level.custom_element[i].change;
+    int element = EL_CUSTOM_START + i;
+
+    /* only add custom elements that change after fixed/random frame delay */
+    if (!IS_CHANGEABLE(element) ||
+       (!HAS_CHANGE_EVENT(element, CE_DELAY_FIXED) &&
+        !HAS_CHANGE_EVENT(element, CE_DELAY_RANDOM)))
+      continue;
+
+    changing_element[element].base_element = element;
+    changing_element[element].next_element = change->successor;
+    changing_element[i].change_delay = 0;
+
+    if (HAS_CHANGE_EVENT(element, CE_DELAY_FIXED))
+      changing_element[element].change_delay +=
+       change->delay_fixed * FRAMES_PER_SECOND;
+
+    if (HAS_CHANGE_EVENT(element, CE_DELAY_RANDOM));
+    /* random frame delay added at runtime for each element individually */
+  }
 }
 
 
@@ -4422,10 +4553,22 @@ static void ChangeElement(int x, int y)
 {
   int element = Feld[x][y];
 
+  if (IS_MOVING(x, y))                 /* never change moving elements */
+    return;
+
   if (MovDelay[x][y] == 0)             /* initialize element change */
   {
     MovDelay[x][y] = changing_element[element].change_delay + 1;
 
+    if (IS_CUSTOM_ELEMENT(element) &&
+       HAS_CHANGE_EVENT(element, CE_DELAY_RANDOM))
+    {
+      int i = element - EL_CUSTOM_START;
+      int max_random_delay = level.custom_element[i].change.delay_random;
+
+      MovDelay[x][y] += RND(max_random_delay * FRAMES_PER_SECOND);
+    }
+
     ResetGfxAnimation(x, y);
     ResetRandomAnimationValue(x, y);
 
@@ -4729,13 +4872,20 @@ void GameActions()
       MauerAbleger(x, y);
     else if (element == EL_FLAMES)
       CheckForDragon(x, y);
+#if 0
     else if (IS_AUTO_CHANGING(element))
       ChangeElement(x, y);
+#endif
     else if (element == EL_EXPLOSION)
       ;        /* drawing of correct explosion animation is handled separately */
     else if (IS_ANIMATED(graphic))
       DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
 
+#if 1
+    if (IS_AUTO_CHANGING(element))
+      ChangeElement(x, y);
+#endif
+
     if (IS_BELT_ACTIVE(element))
       PlaySoundLevelAction(x, y, ACTION_ACTIVE);
 
index c92fe607dd11f84072725a93077b7cc05312636f..3f9f9177b39dbb4c5401082ca1b71cc851cd4f4c 100644 (file)
 #define EP_BITMASK_DEFAULT     0
 
 #define PROPERTY_BIT(p)                (1 << ((p) % 32))
-#define PROPERTY_VAR(e, p)     (Properties[e][(p) / 32])
-#define HAS_PROPERTY(e, p)     ((PROPERTY_VAR(e, p) & PROPERTY_BIT(p)) != 0)
-#define SET_PROPERTY(e, p, v)  ((v) ?                                     \
+#define PROPERTY_VAR(e,p)      (Properties[e][(p) / 32])
+#define HAS_PROPERTY(e,p)      ((PROPERTY_VAR(e, p) & PROPERTY_BIT(p)) != 0)
+#define SET_PROPERTY(e,p,v)    ((v) ?                                     \
                                 (PROPERTY_VAR(e,p) |=  PROPERTY_BIT(p)) : \
                                 (PROPERTY_VAR(e,p) &= ~PROPERTY_BIT(p)))
 
+
+/* values for change events for custom elements */
+#define CE_DELAY_FIXED         0
+#define CE_DELAY_RANDOM                1
+
+#define NUM_CHANGE_EVENTS      2
+
+#define CE_BITMASK_DEFAULT     0
+
+#define CUSTOM_ELEMENT_INFO(e) (level.custom_element[(e) - EL_CUSTOM_START])
+
+#define CH_EVENT_BIT(c)                (1 << (c))
+#define CH_EVENT_VAR(e)                (CUSTOM_ELEMENT_INFO(e).change.events)
+
+#define HAS_CHANGE_EVENT(e,c)  (IS_CUSTOM_ELEMENT(e) &&                  \
+                                (CH_EVENT_VAR(e) & CH_EVENT_BIT(c)) != 0)
+#define SET_CHANGE_EVENT(e,c,v)        (IS_CUSTOM_ELEMENT(e) ?                   \
+                                ((v) ?                                   \
+                                 (CH_EVENT_VAR(e) |=  CH_EVENT_BIT(c)) : \
+                                 (CH_EVENT_VAR(e) &= ~CH_EVENT_BIT(c))) : 0)
+
+
 /* macros for configurable properties */
 #define IS_DIGGABLE(e)         HAS_PROPERTY(e, EP_DIGGABLE)
 #define IS_COLLECTIBLE(e)      HAS_PROPERTY(e, EP_COLLECTIBLE)
@@ -1033,6 +1055,21 @@ struct PlayerInfo
   int shield_deadly_time_left;
 };
 
+struct CustomElementChangeInfo
+{
+  unsigned long events;        /* bitfield for change events */
+
+  short successor;     /* new custom element after change */
+
+  int delay_fixed;     /* added frame delay before changed (fixed) */
+  int delay_random;    /* added frame delay before changed (random) */
+};
+
+struct CustomElementInfo
+{
+  struct CustomElementChangeInfo change;
+};
+
 struct LevelInfo
 {
   int file_version;    /* file format version the level is stored with    */
@@ -1061,7 +1098,7 @@ struct LevelInfo
   boolean gravity;
   boolean em_slippery_gems;    /* EM style "gems slip from wall" behaviour */
 
-  short custom_element_successor[NUM_CUSTOM_ELEMENTS];
+  struct CustomElementInfo custom_element[NUM_CUSTOM_ELEMENTS];
 
   boolean no_level_file;
 };