#define USE_GFX_RESET_GFX_ANIMATION (USE_NEW_STUFF * 1)
#define USE_BOTH_SWITCHGATE_SWITCHES (USE_NEW_STUFF * 1)
#define USE_PLAYER_GRAVITY (USE_NEW_STUFF * 1)
+#define USE_FIXED_BORDER_RUNNING_GFX (USE_NEW_STUFF * 1)
+#define USE_QUICKSAND_BD_ROCK_BUGFIX (USE_NEW_STUFF * 0)
#define USE_QUICKSAND_IMPACT_BUGFIX (USE_NEW_STUFF * 0)
+#define USE_CODE_THAT_BREAKS_SNAKE_BITE (USE_NEW_STUFF * 1)
+
+
/* for DigField() */
#define DF_NO_PUSH 0
#define DF_DIG 1
((e) >= NUM_FILE_ELEMENTS ? EL_UNKNOWN : (e))
#endif
-#define GET_TARGET_ELEMENT(e, ch, cv, cs) \
+#define RESOLVED_REFERENCE_ELEMENT(be, e) \
+ ((be) + (e) - EL_SELF < EL_CUSTOM_START ? EL_CUSTOM_START : \
+ (be) + (e) - EL_SELF > EL_CUSTOM_END ? EL_CUSTOM_END : \
+ (be) + (e) - EL_SELF)
+
+#define GET_TARGET_ELEMENT(be, e, ch, cv, cs) \
((e) == EL_TRIGGER_PLAYER ? (ch)->actual_trigger_player : \
(e) == EL_TRIGGER_ELEMENT ? (ch)->actual_trigger_element : \
(e) == EL_TRIGGER_CE_VALUE ? (ch)->actual_trigger_ce_value : \
(e) == EL_TRIGGER_CE_SCORE ? (ch)->actual_trigger_ce_score : \
(e) == EL_CURRENT_CE_VALUE ? (cv) : \
- (e) == EL_CURRENT_CE_SCORE ? (cs) : (e))
+ (e) == EL_CURRENT_CE_SCORE ? (cs) : \
+ (e) >= EL_LAST_CE_8 && (e) <= EL_NEXT_CE_8 ? \
+ RESOLVED_REFERENCE_ELEMENT(be, e) : \
+ (e))
#define CAN_GROW_INTO(e) \
((e) == EL_SAND || (IS_DIGGABLE(e) && level.grow_into_diggable))
InitField(x, y, init_game);
#endif
}
+
break;
}
}
#endif
+#if 0
+static void replace_reference_element(int base_element, int *element)
+{
+ if (*element >= EL_LAST_CE_8 && *element <= EL_NEXT_CE_8)
+ {
+ *element = base_element + *element - EL_SELF;
+ *element = (*element < EL_CUSTOM_START ? EL_CUSTOM_START :
+ *element > EL_CUSTOM_END ? EL_CUSTOM_END : *element);
+ }
+}
+#endif
+
/*
=============================================================================
InitGameEngine()
for (l = 0; l < group->num_elements_resolved; l++)
trigger_events[group->element_resolved[l]][k] = TRUE;
}
+#if 1
+ else if (trigger_element == EL_ANY_ELEMENT)
+ for (l = 0; l < MAX_NUM_ELEMENTS; l++)
+ trigger_events[l][k] = TRUE;
+#endif
else
trigger_events[trigger_element][k] = TRUE;
}
EL_EMPTY);
}
}
+
+#if 0
+ /* ---------- initialize reference elements ------------------------------- */
+ for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
+ {
+ int element = EL_CUSTOM_START + i;
+ struct ElementInfo *ei = &element_info[element];
+
+ for (y = 0; y < 3; y++) for (x = 0; x < 3; x++)
+ replace_reference_element(element, &ei->content.e[x][y]);
+
+ for (j = 0; j < ei->num_change_pages; j++)
+ {
+ struct ElementChangeInfo *change = &ei->change_page[j];
+
+ replace_reference_element(element, &change->target_element);
+ replace_reference_element(element, &change->trigger_element);
+
+ for (y = 0; y < 3; y++) for (x = 0; x < 3; x++)
+ replace_reference_element(element, &change->target_content.e[x][y]);
+ }
+ }
+#endif
}
int get_num_special_action(int element, int action_first, int action_last)
player->last_move_dir = MV_NONE;
+ player->is_active = FALSE;
+
player->is_waiting = FALSE;
player->is_moving = FALSE;
player->is_auto_moving = FALSE;
started_moving = TRUE;
Feld[x][y] = EL_QUICKSAND_EMPTYING;
+#if USE_QUICKSAND_BD_ROCK_BUGFIX
+ if (Store[x][y] != EL_ROCK && Store[x][y] != EL_BD_ROCK)
+ Store[x][y] = EL_ROCK;
+#else
Store[x][y] = EL_ROCK;
+#endif
PlayLevelSoundAction(x, y, ACTION_EMPTYING);
}
if (element == EL_EXPANDABLE_WALL_HORIZONTAL ||
element == EL_EXPANDABLE_WALL_ANY ||
- element == EL_EXPANDABLE_WALL)
+ element == EL_EXPANDABLE_WALL ||
+ element == EL_BD_EXPANDABLE_WALL)
{
if (links_frei)
{
if (ei->collect_score == 0)
{
+ int xx, yy;
+
#if 0
printf("::: CE_SCORE_GETS_ZERO\n");
#endif
#if 0
printf("::: RESULT: %d, %d\n", Feld[x][y], ChangePage[x][y]);
#endif
+
+#if 1
+ /*
+ This is a very special case that seems to be a mixture between
+ CheckElementChange() and CheckTriggeredElementChange(): while
+ the first one only affects single elements that are triggered
+ directly, the second one affects multiple elements in the playfield
+ that are triggered indirectly by another element. This is a third
+ case: Changing the CE score always affects multiple identical CEs,
+ so every affected CE must be checked, not only the single CE for
+ which the CE score was changed in the first place (as every instance
+ of that CE shares the same CE score, and therefore also can change)!
+ */
+ SCAN_PLAYFIELD(xx, yy)
+ {
+ if (Feld[xx][yy] == element)
+ CheckElementChange(xx, yy, element, EL_UNDEFINED,
+ CE_SCORE_GETS_ZERO);
+ }
+#endif
}
}
#endif
boolean new_element_is_player = ELEM_IS_PLAYER(new_element);
boolean add_player_onto_element = (new_element_is_player &&
+#if USE_CODE_THAT_BREAKS_SNAKE_BITE
+ /* this breaks SnakeBite when a snake is
+ halfway through a door that closes */
+ /* NOW FIXED AT LEVEL INIT IN files.c */
new_element != EL_SOKOBAN_FIELD_PLAYER &&
+#endif
IS_WALKABLE(old_element));
#if 0
ChangeEvent[ex][ey] = ChangeEvent[x][y];
content_element = change->target_content.e[xx][yy];
- target_element = GET_TARGET_ELEMENT(content_element, change,
+ target_element = GET_TARGET_ELEMENT(element, content_element, change,
ce_value, ce_score);
CreateElementFromChange(ex, ey, target_element);
}
else
{
- target_element = GET_TARGET_ELEMENT(change->target_element, change,
+ target_element = GET_TARGET_ELEMENT(element, change->target_element, change,
ce_value, ce_score);
if (element == EL_DIAGONAL_GROWING ||
for (i = 0; i < MAX_PLAYERS; i++)
effective_action[i] = stored_player[i].effective_action;
+#if 0
+ printf("::: %04d: %08x\n", FrameCounter, effective_action[0]);
+#endif
+
GameActions_EM(effective_action, warp_mode);
CheckLevelTime();
else if (element == EL_EXPANDABLE_WALL ||
element == EL_EXPANDABLE_WALL_HORIZONTAL ||
element == EL_EXPANDABLE_WALL_VERTICAL ||
- element == EL_EXPANDABLE_WALL_ANY)
+ element == EL_EXPANDABLE_WALL_ANY ||
+ element == EL_BD_EXPANDABLE_WALL)
MauerAbleger(x, y);
else if (element == EL_FLAMES)
CheckForDragon(x, y);
{
int move_dir_horizontal = player->effective_action & MV_HORIZONTAL;
int move_dir_vertical = player->effective_action & MV_VERTICAL;
- boolean player_is_snapping = player->effective_action & JOY_BUTTON_1;
+ boolean player_is_snapping = (player->effective_action & JOY_BUTTON_1);
int jx = player->jx, jy = player->jy;
boolean player_is_moving_to_valid_field =
(!player_is_snapping &&
player->move_delay_value = original_move_delay_value;
}
+ player->is_active = FALSE;
+
if (player->last_move_dir & MV_HORIZONTAL)
{
if (!(moved |= MovePlayerOneStep(player, 0, dy, dx, dy)))
moved |= MovePlayerOneStep(player, 0, dy, dx, dy);
}
+#if USE_FIXED_BORDER_RUNNING_GFX
+ if (!moved && !player->is_active)
+ {
+ player->is_moving = FALSE;
+ player->is_digging = FALSE;
+ player->is_collecting = FALSE;
+ player->is_snapping = FALSE;
+ player->is_pushing = FALSE;
+ }
+#endif
+
jx = player->jx;
jy = player->jy;
}
player->is_pushing = TRUE;
+ player->is_active = TRUE;
if (!(IN_LEV_FIELD(nextx, nexty) &&
(IS_FREE(nextx, nexty) ||
if (is_player) /* function can also be called by EL_PENGUIN */
{
if (Feld[x][y] != element) /* really digged/collected something */
+ {
player->is_collecting = !player->is_digging;
+ player->is_active = TRUE;
+ }
}
return MP_MOVING;
return FALSE;
player->is_snapping = TRUE;
+ player->is_active = TRUE;
if (player->MovPos == 0)
{