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];
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)
{
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[element].change_delay = 0;
+
+ if (HAS_CHANGE_EVENT(element, CE_DELAY_FIXED))
+ changing_element[element].change_delay +=
+ change->delay_fixed * change->delay_frames;
+
+ if (HAS_CHANGE_EVENT(element, CE_DELAY_RANDOM));
+ /* random frame delay added at runtime for each element individually */
+ }
}
AllPlayersGone = FALSE;
- game.yam_content_nr = 0;
+ game.yamyam_content_nr = 0;
game.magic_wall_active = FALSE;
game.magic_wall_time_left = 0;
game.light_time_left = 0;
Feld[ex][ey] = center_element;
}
- for (y=ey-1; y<=ey+1; y++) for(x=ex-1; x<=ex+1; x++)
+ for (y = ey - 1; y <= ey + 1; y++) for(x = ex - 1; x <= ex + 1; x++)
{
int element;
Store[x][y] = EL_BD_DIAMOND;
else if (center_element == EL_SP_ELECTRON)
Store[x][y] = EL_SP_INFOTRON;
- else if (center_element == EL_YAMYAM)
- Store[x][y] = level.yam_content[game.yam_content_nr][x-ex+1][y-ey+1];
else if (center_element == EL_AMOEBA_TO_DIAMOND)
Store[x][y] = level.amoeba_content;
+ else if (center_element == EL_YAMYAM)
+ Store[x][y] =
+ level.yamyam_content[game.yamyam_content_nr][x - ex + 1][y - ey + 1];
+ else if (IS_CUSTOM_ELEMENT(center_element))
+ Store[x][y] =
+ CUSTOM_ELEMENT_INFO(center_element).content[x - ex + 1][y - ey + 1];
else if (element == EL_WALL_EMERALD)
Store[x][y] = EL_EMERALD;
else if (element == EL_WALL_DIAMOND)
}
if (center_element == EL_YAMYAM)
- game.yam_content_nr = (game.yam_content_nr + 1) % level.num_yam_contents;
+ game.yamyam_content_nr =
+ (game.yamyam_content_nr + 1) % level.num_yamyam_contents;
return;
}
if (IS_PLAYER(x, y))
KillHeroUnlessProtected(x, y);
- else if (IS_CAN_EXPLODE(element))
+ else if (CAN_EXPLODE(element))
{
Feld[x][y] = Store2[x][y];
Store2[x][y] = 0;
if (phase == delay)
DrawLevelFieldCrumbledSand(x, y);
- if (IS_WALKABLE_OVER(Back[x][y]))
+ if (IS_WALKABLE_OVER(Back[x][y]) && Back[x][y] != EL_EMPTY)
{
DrawLevelElement(x, y, Back[x][y]);
DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic, frame);
{
int flamed = MovingOrBlocked2Element(xx, yy);
- if (IS_ENEMY(flamed) || IS_CAN_EXPLODE(flamed))
+ if (IS_ENEMY(flamed) || CAN_EXPLODE(flamed))
Bang(xx, yy);
else
RemoveMovingField(xx, yy);
{
int element = Feld[x][y];
+ if (IS_MOVING(x, y)) /* never change a running system :-) */
+ 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;
+ int delay_frames = level.custom_element[i].change.delay_frames;
+
+ MovDelay[x][y] += RND(max_random_delay * delay_frames);
+ }
+
ResetGfxAnimation(x, y);
ResetRandomAnimationValue(x, y);
ResetGfxAnimation(x, y);
ResetRandomAnimationValue(x, y);
+#if 1
+ InitField(x, y, FALSE);
+ if (CAN_MOVE(element))
+ InitMovDir(x, y);
+#endif
DrawLevelField(x, y);
if (changing_element[element].post_change_function)
element = Feld[x][y];
graphic = el2img(element);
+#if 0
+ if (element == -1)
+ {
+ printf("::: %d,%d: %d [%d]\n", x, y, element, FrameCounter);
+
+ element = graphic = 0;
+ }
+#endif
+
if (graphic_info[graphic].anim_global_sync)
GfxFrame[x][y] = FrameCounter;
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))
+ else if (IS_ANIMATED(graphic) && !IS_AUTO_CHANGING(element))
DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
+#if 1
+ /* this may take place after moving, therefore element may have changed */
+ if (IS_AUTO_CHANGING(Feld[x][y]))
+ ChangeElement(x, y);
+#endif
+
if (IS_BELT_ACTIVE(element))
PlaySoundLevelAction(x, y, ACTION_ACTIVE);
if (!player->active || (!dx && !dy))
return FALSE;
-#if 0
- {
- static boolean done = FALSE;
- static old_count = -1;
-
- if (FrameCounter < old_count)
- done = FALSE;
-
- if (FrameCounter < 100)
- {
- printf("::: wanna move [%d] [%d]\n",
- FrameCounter, player->push_delay_value);
- done = TRUE;
- old_count = FrameCounter;
- }
- }
-#endif
-
#if 0
if (!FrameReached(&player->move_delay, player->move_delay_value) &&
!tape.playing)
dy == +1 ? MV_DOWN : MV_NO_MOVING);
int element;
-#if 0
- {
- static boolean done = FALSE;
-
- if (FrameCounter < 10)
- done = FALSE;
-
- if (!done &&
- real_dx == -1 &&
- FrameCounter > 10)
- {
- printf("::: wanna move left [%d] [%d]\n",
- FrameCounter, player->push_delay_value);
- done = TRUE;
- }
- }
-#endif
-
if (player->MovPos == 0)
{
player->is_digging = FALSE;
{
player->Switching = FALSE;
player->push_delay = 0;
+
return MF_NO_ACTION;
}
element = Feld[x][y];
+#if 1
+ if (mode == DF_SNAP && !IS_SNAPPABLE(element) &&
+ game.engine_version >= VERSION_IDENT(2,2,0))
+ return MF_NO_ACTION;
+#endif
+
switch (element)
{
case EL_EMPTY:
break;
default:
+
if (IS_WALKABLE(element))
{
break;
#if 1
if (mode != DF_SNAP)
{
- GfxElement[x][y] = element;
+ GfxElement[x][y] =
+ (CAN_BE_CRUMBLED(element) ? EL_SAND : GFX_ELEMENT(element));
player->is_digging = TRUE;
}
#endif
int jx = player->jx, jy = player->jy;
int x = jx + dx, y = jy + dy;
+ if (player->MovPos && game.engine_version >= VERSION_IDENT(2,2,0))
+ return FALSE;
+
if (!player->active || !IN_LEV_FIELD(x, y))
return FALSE;
dy < 0 ? MV_UP :
dy > 0 ? MV_DOWN : MV_NO_MOVING);
- if (!DigField(player, x, y, 0, 0, DF_SNAP))
+ if (DigField(player, x, y, 0, 0, DF_SNAP) == MF_NO_ACTION)
return FALSE;
player->snapped = TRUE;