X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=09eea8f3bf0c635affcf0b99b2916fe2c5378c75;hb=2447100f7c3eacf4361973fa90814d9bd0e2b055;hp=bf409f086759b55851e1b2906433ad2329a10a1c;hpb=44051f2e9b98cc3cf5e065616ef0c7569262dd06;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index bf409f08..09eea8f3 100644 --- a/src/game.c +++ b/src/game.c @@ -42,6 +42,9 @@ #define USE_ELEMENT_TOUCHING_BUGFIX (USE_NEW_STUFF * 1) #define USE_NEW_CONTINUOUS_SNAPPING (USE_NEW_STUFF * 1) #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_IMPACT_BUGFIX (USE_NEW_STUFF * 0) @@ -364,6 +367,8 @@ void RemovePlayer(struct PlayerInfo *); boolean SnapField(struct PlayerInfo *, int, int); boolean DropElement(struct PlayerInfo *); +static int getInvisibleActiveFromInvisibleElement(int); +static int getInvisibleFromInvisibleActiveElement(int); static struct GadgetInfo *game_gadget[NUM_GAME_BUTTONS]; @@ -776,6 +781,7 @@ static int get_move_delay_from_stepsize(int move_stepsize) static void SetPlayerMoveSpeed(struct PlayerInfo *player, int move_stepsize, boolean init_game) { + int player_nr = player->index_nr; int move_delay = get_move_delay_from_stepsize(move_stepsize); boolean cannot_move = (move_stepsize == STEPSIZE_NOT_MOVING ? TRUE : FALSE); @@ -787,8 +793,8 @@ static void SetPlayerMoveSpeed(struct PlayerInfo *player, int move_stepsize, if (init_game) { - player->move_delay = game.initial_move_delay; - player->move_delay_value = game.initial_move_delay_value; + player->move_delay = game.initial_move_delay[player_nr]; + player->move_delay_value = game.initial_move_delay_value[player_nr]; player->move_delay_value_next = -1; @@ -1117,16 +1123,26 @@ static void InitField(int x, int y, boolean init_game) } break; +#if !USE_BOTH_SWITCHGATE_SWITCHES case EL_SWITCHGATE_SWITCH_DOWN: /* always start with same switch pos */ if (init_game) Feld[x][y] = EL_SWITCHGATE_SWITCH_UP; break; +#endif case EL_LIGHT_SWITCH_ACTIVE: if (init_game) game.light_time_left = level.time_light * FRAMES_PER_SECOND; break; + case EL_INVISIBLE_STEELWALL: + case EL_INVISIBLE_WALL: + case EL_INVISIBLE_SAND: + if (game.light_time_left > 0 || + game.lenses_time_left > 0) + Feld[x][y] = getInvisibleActiveFromInvisibleElement(element); + break; + case EL_EMC_MAGIC_BALL: if (game.ball_state) Feld[x][y] = EL_EMC_MAGIC_BALL_ACTIVE; @@ -1580,8 +1596,9 @@ static void InitGameEngine() #if 1 /* dynamically adjust player properties according to level information */ - game.initial_move_delay_value = - get_move_delay_from_stepsize(level.initial_player_stepsize); + for (i = 0; i < MAX_PLAYERS; i++) + game.initial_move_delay_value[i] = + get_move_delay_from_stepsize(level.initial_player_stepsize[i]); #else /* dynamically adjust player properties according to level information */ game.initial_move_delay_value = @@ -1589,8 +1606,10 @@ static void InitGameEngine() #endif /* dynamically adjust player properties according to game engine version */ - game.initial_move_delay = (game.engine_version <= VERSION_IDENT(2,0,1,0) ? - game.initial_move_delay_value : 0); + for (i = 0; i < MAX_PLAYERS; i++) + game.initial_move_delay[i] = + (game.engine_version <= VERSION_IDENT(2,0,1,0) ? + game.initial_move_delay_value[i] : 0); /* ---------- initialize player's initial push delay --------------------- */ @@ -1749,8 +1768,22 @@ static void InitGameEngine() { if (!IS_CUSTOM_ELEMENT(i)) { +#if 1 + /* set default push delay values (corrected since version 3.0.7-1) */ + if (game.engine_version < VERSION_IDENT(3,0,7,1)) + { + element_info[i].push_delay_fixed = 2; + element_info[i].push_delay_random = 8; + } + else + { + element_info[i].push_delay_fixed = 8; + element_info[i].push_delay_random = 8; + } +#else element_info[i].push_delay_fixed = game.default_push_delay_fixed; element_info[i].push_delay_random = game.default_push_delay_random; +#endif } } @@ -1951,6 +1984,8 @@ void InitGame() player->block_last_field = FALSE; /* initialized in InitPlayerField() */ player->block_delay_adjustment = 0; /* initialized in InitPlayerField() */ + player->gravity = level.initial_player_gravity[i]; + player->can_fall_into_acid = CAN_MOVE_INTO_ACID(player->element_nr); player->actual_frame_counter = 0; @@ -1959,6 +1994,8 @@ void InitGame() player->last_move_dir = MV_NONE; + player->is_active = FALSE; + player->is_waiting = FALSE; player->is_moving = FALSE; player->is_auto_moving = FALSE; @@ -2006,7 +2043,7 @@ void InitGame() player->show_envelope = 0; #if 1 - SetPlayerMoveSpeed(player, level.initial_player_stepsize, TRUE); + SetPlayerMoveSpeed(player, level.initial_player_stepsize[i], TRUE); #else player->move_delay = game.initial_move_delay; player->move_delay_value = game.initial_move_delay_value; @@ -2072,8 +2109,15 @@ void InitGame() game.timegate_time_left = 0; game.switchgate_pos = 0; game.wind_direction = level.wind_direction_initial; + +#if !USE_PLAYER_GRAVITY +#if 1 + game.gravity = FALSE; +#else game.gravity = level.initial_gravity; +#endif game.explosions_delayed = TRUE; +#endif game.lenses_time_left = 0; game.magnify_time_left = 0; @@ -3012,22 +3056,38 @@ void InitPlayerGfxAnimation(struct PlayerInfo *player, int action, int dir) } } -static void ResetRandomAnimationValue(int x, int y) +#if USE_GFX_RESET_GFX_ANIMATION +static void ResetGfxFrame(int x, int y, boolean redraw) { - GfxRandom[x][y] = INIT_GFX_RANDOM(); + int element = Feld[x][y]; + int graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); + int last_gfx_frame = GfxFrame[x][y]; + + if (graphic_info[graphic].anim_global_sync) + GfxFrame[x][y] = FrameCounter; + else if (ANIM_MODE(graphic) == ANIM_CE_VALUE) + GfxFrame[x][y] = CustomValue[x][y]; + else if (ANIM_MODE(graphic) == ANIM_CE_SCORE) + GfxFrame[x][y] = element_info[element].collect_score; + else if (ANIM_MODE(graphic) == ANIM_CE_DELAY) + GfxFrame[x][y] = ChangeDelay[x][y]; + + if (redraw && GfxFrame[x][y] != last_gfx_frame) + DrawLevelGraphicAnimation(x, y, graphic); } +#endif static void ResetGfxAnimation(int x, int y) { -#if USE_GFX_RESET_GFX_ANIMATION +#if 0 int element, graphic; #endif - GfxFrame[x][y] = 0; GfxAction[x][y] = ACTION_DEFAULT; GfxDir[x][y] = MovDir[x][y]; + GfxFrame[x][y] = 0; -#if USE_GFX_RESET_GFX_ANIMATION +#if 0 element = Feld[x][y]; graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); @@ -3037,9 +3097,20 @@ static void ResetGfxAnimation(int x, int y) GfxFrame[x][y] = CustomValue[x][y]; else if (ANIM_MODE(graphic) == ANIM_CE_SCORE) GfxFrame[x][y] = element_info[element].collect_score; + else if (ANIM_MODE(graphic) == ANIM_CE_DELAY) + GfxFrame[x][y] = ChangeDelay[x][y]; +#endif + +#if USE_GFX_RESET_GFX_ANIMATION + ResetGfxFrame(x, y, FALSE); #endif } +static void ResetRandomAnimationValue(int x, int y) +{ + GfxRandom[x][y] = INIT_GFX_RANDOM(); +} + void InitMovingField(int x, int y, int direction) { int element = Feld[x][y]; @@ -3068,6 +3139,8 @@ void InitMovingField(int x, int y, int direction) GfxFrame[x][y] = CustomValue[x][y]; else if (ANIM_MODE(graphic) == ANIM_CE_SCORE) GfxFrame[x][y] = element_info[element].collect_score; + else if (ANIM_MODE(graphic) == ANIM_CE_DELAY) + GfxFrame[x][y] = ChangeDelay[x][y]; #endif /* this is needed for CEs with property "can move" / "not moving" */ @@ -4386,12 +4459,25 @@ static void ToggleSwitchgateSwitch(int x, int y) { int element = Feld[xx][yy]; +#if !USE_BOTH_SWITCHGATE_SWITCHES if (element == EL_SWITCHGATE_SWITCH_UP || element == EL_SWITCHGATE_SWITCH_DOWN) { Feld[xx][yy] = EL_SWITCHGATE_SWITCH_UP + game.switchgate_pos; DrawLevelField(xx, yy); } +#else + if (element == EL_SWITCHGATE_SWITCH_UP) + { + Feld[xx][yy] = EL_SWITCHGATE_SWITCH_DOWN; + DrawLevelField(xx, yy); + } + else if (element == EL_SWITCHGATE_SWITCH_DOWN) + { + Feld[xx][yy] = EL_SWITCHGATE_SWITCH_UP; + DrawLevelField(xx, yy); + } +#endif else if (element == EL_SWITCHGATE_OPEN || element == EL_SWITCHGATE_OPENING) { @@ -5697,7 +5783,7 @@ inline static void TurnRoundExt(int x, int y) static void TurnRound(int x, int y) { int direction = MovDir[x][y]; -#if 1 +#if 0 int element, graphic; #endif @@ -5712,6 +5798,8 @@ static void TurnRound(int x, int y) GfxAction[x][y] = ACTION_TURNING_FROM_LEFT + MV_DIR_TO_BIT(direction); #if 1 + ResetGfxFrame(x, y, FALSE); +#else element = Feld[x][y]; graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); @@ -5721,6 +5809,8 @@ static void TurnRound(int x, int y) GfxFrame[x][y] = CustomValue[x][y]; else if (ANIM_MODE(graphic) == ANIM_CE_SCORE) GfxFrame[x][y] = element_info[element].collect_score; + else if (ANIM_MODE(graphic) == ANIM_CE_DELAY) + GfxFrame[x][y] = ChangeDelay[x][y]; #endif } @@ -7940,7 +8030,7 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) CA_ARG_MAX); int action_arg_number_reset = - (action_type == CA_SET_PLAYER_SPEED ? level.initial_player_stepsize : + (action_type == CA_SET_PLAYER_SPEED ? level.initial_player_stepsize[0] : action_type == CA_SET_LEVEL_GEMS ? level.gems_needed : action_type == CA_SET_LEVEL_TIME ? level.time : action_type == CA_SET_LEVEL_SCORE ? 0 : @@ -8066,6 +8156,7 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) break; } +#if !USE_PLAYER_GRAVITY case CA_SET_LEVEL_GRAVITY: { game.gravity = (action_arg == CA_ARG_GRAVITY_OFF ? FALSE : @@ -8074,6 +8165,7 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) game.gravity); break; } +#endif case CA_SET_LEVEL_WIND: { @@ -8160,6 +8252,10 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) action_mode = (action_arg == CA_ARG_SPEED_SLOWER ? CA_MODE_DIVIDE : CA_MODE_MULTIPLY); } + else if (action_arg == CA_ARG_NUMBER_RESET) + { + action_arg_number = level.initial_player_stepsize[i]; + } move_stepsize = getModifiedActionNumber(move_stepsize, @@ -8212,6 +8308,25 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) break; } +#if USE_PLAYER_GRAVITY + case CA_SET_PLAYER_GRAVITY: + { + for (i = 0; i < MAX_PLAYERS; i++) + { + if (trigger_player_bits & (1 << i)) + { + stored_player[i].gravity = + (action_arg == CA_ARG_GRAVITY_OFF ? FALSE : + action_arg == CA_ARG_GRAVITY_ON ? TRUE : + action_arg == CA_ARG_GRAVITY_TOGGLE ? !stored_player[i].gravity : + stored_player[i].gravity); + } + } + + break; + } +#endif + case CA_SET_PLAYER_ARTWORK: { for (i = 0; i < MAX_PLAYERS; i++) @@ -8247,27 +8362,34 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) case CA_SET_CE_VALUE: { #if USE_NEW_CUSTOM_VALUE - int last_custom_value = CustomValue[x][y]; + int last_ce_value = CustomValue[x][y]; CustomValue[x][y] = action_arg_number_new; #if 0 - printf("::: Count == %d\n", CustomValue[x][y]); + printf("::: CE value == %d\n", CustomValue[x][y]); #endif - if (CustomValue[x][y] == 0 && last_custom_value > 0) + if (CustomValue[x][y] != last_ce_value) { + CheckElementChange(x, y, element, EL_UNDEFINED, CE_VALUE_CHANGES); + CheckTriggeredElementChange(x, y, element, CE_VALUE_CHANGES_OF_X); + + if (CustomValue[x][y] == 0) + { #if 0 - printf("::: CE_VALUE_GETS_ZERO\n"); + printf("::: CE_VALUE_GETS_ZERO\n"); #endif - CheckElementChange(x, y, element, EL_UNDEFINED, CE_VALUE_GETS_ZERO); - CheckTriggeredElementChange(x, y, element, CE_VALUE_GETS_ZERO_OF_X); + CheckElementChange(x, y, element, EL_UNDEFINED, CE_VALUE_GETS_ZERO); + CheckTriggeredElementChange(x, y, element, CE_VALUE_GETS_ZERO_OF_X); #if 0 - printf("::: RESULT: %d, %d\n", Feld[x][y], ChangePage[x][y]); + printf("::: RESULT: %d, %d\n", Feld[x][y], ChangePage[x][y]); #endif + } } + #endif break; @@ -8275,8 +8397,37 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) case CA_SET_CE_SCORE: { +#if USE_NEW_CUSTOM_VALUE + int last_ce_score = ei->collect_score; + ei->collect_score = action_arg_number_new; +#if 0 + printf("::: CE score == %d\n", ei->collect_score); +#endif + + if (ei->collect_score != last_ce_score) + { + CheckElementChange(x, y, element, EL_UNDEFINED, CE_SCORE_CHANGES); + CheckTriggeredElementChange(x, y, element, CE_SCORE_CHANGES_OF_X); + + if (ei->collect_score == 0) + { +#if 0 + printf("::: CE_SCORE_GETS_ZERO\n"); +#endif + + CheckElementChange(x, y, element, EL_UNDEFINED, CE_SCORE_GETS_ZERO); + CheckTriggeredElementChange(x, y, element, CE_SCORE_GETS_ZERO_OF_X); + +#if 0 + printf("::: RESULT: %d, %d\n", Feld[x][y], ChangePage[x][y]); +#endif + } + } + +#endif + break; } @@ -8302,11 +8453,13 @@ static void CreateFieldExt(int x, int y, int element, boolean is_change) #if USE_NEW_CUSTOM_VALUE int last_ce_value = CustomValue[x][y]; #endif - boolean add_player = (ELEM_IS_PLAYER(new_element) && - IS_WALKABLE(old_element)); + boolean new_element_is_player = ELEM_IS_PLAYER(new_element); + boolean add_player_onto_element = (new_element_is_player && + new_element != EL_SOKOBAN_FIELD_PLAYER && + IS_WALKABLE(old_element)); #if 0 - /* check if element under player changes from accessible to unaccessible + /* check if element under the player changes from accessible to unaccessible (needed for special case of dropping element which then changes) */ if (IS_PLAYER(x, y) && !PLAYER_EXPLOSION_PROTECTED(x, y) && IS_ACCESSIBLE(old_element) && !IS_ACCESSIBLE(new_element)) @@ -8317,7 +8470,7 @@ static void CreateFieldExt(int x, int y, int element, boolean is_change) } #endif - if (!add_player) + if (!add_player_onto_element) { if (IS_MOVING(x, y) || IS_BLOCKED(x, y)) RemoveMovingField(x, y); @@ -8355,8 +8508,9 @@ static void CreateFieldExt(int x, int y, int element, boolean is_change) } #if 1 - /* check if element under player changes from accessible to unaccessible + /* check if element under the player changes from accessible to unaccessible (needed for special case of dropping element which then changes) */ + /* (must be checked after creating new element for walkable group elements) */ if (IS_PLAYER(x, y) && !PLAYER_EXPLOSION_PROTECTED(x, y) && IS_ACCESSIBLE(old_element) && !IS_ACCESSIBLE(new_element)) { @@ -8367,7 +8521,7 @@ static void CreateFieldExt(int x, int y, int element, boolean is_change) #endif /* "ChangeCount" not set yet to allow "entered by player" change one time */ - if (ELEM_IS_PLAYER(new_element)) + if (new_element_is_player) RelocatePlayer(x, y, new_element); if (is_change) @@ -9720,6 +9874,9 @@ void GameActions_RND() printf("::: Yo man! Rocks can fall!\n"); #endif +#if 1 + ResetGfxFrame(x, y, TRUE); +#else if (graphic_info[graphic].anim_global_sync) GfxFrame[x][y] = FrameCounter; else if (ANIM_MODE(graphic) == ANIM_CE_VALUE) @@ -9744,6 +9901,18 @@ void GameActions_RND() #endif DrawLevelGraphicAnimation(x, y, graphic); } + else if (ANIM_MODE(graphic) == ANIM_CE_DELAY) + { + int old_gfx_frame = GfxFrame[x][y]; + + GfxFrame[x][y] = ChangeDelay[x][y]; + +#if 1 + if (GfxFrame[x][y] != old_gfx_frame) +#endif + DrawLevelGraphicAnimation(x, y, graphic); + } +#endif if (ANIM_MODE(graphic) == ANIM_RANDOM && IS_NEXT_FRAME(GfxFrame[x][y], graphic)) @@ -10190,7 +10359,11 @@ static boolean canMoveToValidFieldWithGravity(int x, int y, int move_dir) static void CheckGravityMovement(struct PlayerInfo *player) { +#if USE_PLAYER_GRAVITY + if (player->gravity && !player->programmed_action) +#else if (game.gravity && !player->programmed_action) +#endif { int move_dir_horizontal = player->effective_action & MV_HORIZONTAL; int move_dir_vertical = player->effective_action & MV_VERTICAL; @@ -10212,7 +10385,11 @@ static void CheckGravityMovementWhenNotMoving(struct PlayerInfo *player) { return CheckGravityMovement(player); +#if USE_PLAYER_GRAVITY + if (player->gravity && !player->programmed_action) +#else if (game.gravity && !player->programmed_action) +#endif { int jx = player->jx, jy = player->jy; boolean field_under_player_is_free = @@ -10413,6 +10590,8 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) 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))) @@ -10424,6 +10603,17 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int 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; @@ -10595,8 +10785,13 @@ void ScrollPlayer(struct PlayerInfo *player, int mode) last_field_block_delay += player->move_delay_value; /* when blocking enabled, prevent moving up despite gravity */ +#if USE_PLAYER_GRAVITY + if (player->gravity && player->MovDir == MV_UP) + block_delay_adjustment = -1; +#else if (game.gravity && player->MovDir == MV_UP) block_delay_adjustment = -1; +#endif } /* add block delay adjustment (also possible when not blocking) */ @@ -11518,6 +11713,8 @@ int DigField(struct PlayerInfo *player, game.engine_version >= VERSION_IDENT(2,2,0,0)) old_element = Back[jx][jy]; + /* checking here causes player to move into acid even if the current field + cannot be left to that direction */ #if 0 #if USE_FIXED_DONT_RUN_INTO if (player_can_move && DONT_RUN_INTO(element)) @@ -11539,6 +11736,43 @@ int DigField(struct PlayerInfo *player, #endif #endif +#if 1 /* ------------------------------ NEW ------------------------------ */ + + if (IS_WALKABLE(old_element) && !ACCESS_FROM(old_element, move_direction)) + return MP_NO_ACTION; /* field has no opening in this direction */ + + if (IS_PASSABLE(old_element) && !ACCESS_FROM(old_element,opposite_direction)) + return MP_NO_ACTION; /* field has no opening in this direction */ + +#if USE_FIXED_DONT_RUN_INTO + if (player_can_move && element == EL_ACID && move_direction == MV_DOWN) + { + SplashAcid(x, y); +#if 1 + Feld[jx][jy] = player->artwork_element; +#else + Feld[jx][jy] = EL_PLAYER_1; +#endif + InitMovingField(jx, jy, MV_DOWN); + Store[jx][jy] = EL_ACID; + ContinueMoving(jx, jy); + BuryPlayer(player); + + return MP_DONT_RUN_INTO; + } +#endif + +#if USE_FIXED_DONT_RUN_INTO + if (player_can_move && DONT_RUN_INTO(element)) + { + TestIfPlayerRunsIntoBadThing(jx, jy, player->MovDir); + + return MP_DONT_RUN_INTO; + } +#endif + +#else /* ------------------------------ OLD ------------------------------ */ + #if 1 #if USE_FIXED_DONT_RUN_INTO if (player_can_move && DONT_RUN_INTO(element)) @@ -11556,6 +11790,7 @@ int DigField(struct PlayerInfo *player, if (IS_PASSABLE(old_element) && !ACCESS_FROM(old_element,opposite_direction)) return MP_NO_ACTION; /* field has no opening in this direction */ + /* checking here causes player to explode when moving into acid */ #if 1 #if USE_FIXED_DONT_RUN_INTO if (player_can_move && element == EL_ACID && move_direction == MV_DOWN) @@ -11572,6 +11807,8 @@ int DigField(struct PlayerInfo *player, #endif #endif +#endif /* ------------------------------ END ------------------------------ */ + #if 0 #if USE_FIXED_DONT_RUN_INTO if (player_can_move && DONT_RUN_INTO(element)) @@ -11624,10 +11861,17 @@ int DigField(struct PlayerInfo *player, return MP_NO_ACTION; } +#if USE_PLAYER_GRAVITY + if (player->gravity && is_player && !player->is_auto_moving && + canFallDown(player) && move_direction != MV_DOWN && + !canMoveToValidFieldWithGravity(jx, jy, move_direction)) + return MP_NO_ACTION; /* player cannot walk here due to gravity */ +#else if (game.gravity && is_player && !player->is_auto_moving && canFallDown(player) && move_direction != MV_DOWN && !canMoveToValidFieldWithGravity(jx, jy, move_direction)) return MP_NO_ACTION; /* player cannot walk here due to gravity */ +#endif if (player_can_move && IS_WALKABLE(element) && ACCESS_FROM(element, opposite_direction)) @@ -11691,23 +11935,50 @@ int DigField(struct PlayerInfo *player, if (!player->key[EM_GATE_GRAY_ACTIVE_NR(element)]) return MP_NO_ACTION; } + else if (IS_EMC_GATE(element)) + { + if (!player->key[EMC_GATE_NR(element)]) + return MP_NO_ACTION; + } + else if (IS_EMC_GATE_GRAY(element)) + { + if (!player->key[EMC_GATE_GRAY_NR(element)]) + return MP_NO_ACTION; + } + else if (IS_EMC_GATE_GRAY_ACTIVE(element)) + { + if (!player->key[EMC_GATE_GRAY_ACTIVE_NR(element)]) + return MP_NO_ACTION; + } else if (IS_SP_PORT(element)) { if (element == EL_SP_GRAVITY_PORT_LEFT || element == EL_SP_GRAVITY_PORT_RIGHT || element == EL_SP_GRAVITY_PORT_UP || element == EL_SP_GRAVITY_PORT_DOWN) +#if USE_PLAYER_GRAVITY + player->gravity = !player->gravity; +#else game.gravity = !game.gravity; +#endif else if (element == EL_SP_GRAVITY_ON_PORT_LEFT || element == EL_SP_GRAVITY_ON_PORT_RIGHT || element == EL_SP_GRAVITY_ON_PORT_UP || element == EL_SP_GRAVITY_ON_PORT_DOWN) +#if USE_PLAYER_GRAVITY + player->gravity = TRUE; +#else game.gravity = TRUE; +#endif else if (element == EL_SP_GRAVITY_OFF_PORT_LEFT || element == EL_SP_GRAVITY_OFF_PORT_RIGHT || element == EL_SP_GRAVITY_OFF_PORT_UP || element == EL_SP_GRAVITY_OFF_PORT_DOWN) +#if USE_PLAYER_GRAVITY + player->gravity = FALSE; +#else game.gravity = FALSE; +#endif } /* automatically move to the next field with double speed */ @@ -11927,6 +12198,7 @@ int DigField(struct PlayerInfo *player, } player->is_pushing = TRUE; + player->is_active = TRUE; if (!(IN_LEV_FIELD(nextx, nexty) && (IS_FREE(nextx, nexty) || @@ -12179,7 +12451,10 @@ int DigField(struct PlayerInfo *player, 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; @@ -12248,6 +12523,7 @@ boolean SnapField(struct PlayerInfo *player, int dx, int dy) return FALSE; player->is_snapping = TRUE; + player->is_active = TRUE; if (player->MovPos == 0) {