+ case O_PLAYER_ROCKET_LAUNCHER:
+ // much simpler; cannot snap-push stones
+ if (cave->kill_player)
+ {
+ explode(cave, x, y);
+ break;
+ }
+
+ cave->player_seen_ago = 0;
+ // bd4 intermission caves have many players. so if one of them has exited,
+ // do not change the flag anymore. so this if () is needed
+ if (cave->player_state != GD_PL_EXITED)
+ cave->player_state = GD_PL_LIVING;
+
+ // firing a rocket?
+ if (player_move != GD_MV_STILL)
+ {
+ // if the player does not move, nothing to do
+ GdElement what = get_dir(cave, x, y, player_move);
+ GdElement remains = what;
+
+ // to fire a rocket, diagonal movement should not be allowed.
+ // so either x or y must be zero
+ if (player_fire)
+ {
+ // placing a rocket into empty space
+ if (is_space_dir(cave, x, y, player_move))
+ {
+ switch (player_move)
+ {
+ case GD_MV_RIGHT:
+ store_dir(cave, x, y, player_move, O_ROCKET_1);
+ if (!cave->infinite_rockets)
+ store(cave, x, y, O_PLAYER);
+ break;
+
+ case GD_MV_UP:
+ store_dir(cave, x, y, player_move, O_ROCKET_2);
+ if (!cave->infinite_rockets)
+ store(cave, x, y, O_PLAYER);
+ break;
+
+ case GD_MV_LEFT:
+ store_dir(cave, x, y, player_move, O_ROCKET_3);
+ if (!cave->infinite_rockets)
+ store(cave, x, y, O_PLAYER);
+ break;
+
+ case GD_MV_DOWN:
+ store_dir(cave, x, y, player_move, O_ROCKET_4);
+ if (!cave->infinite_rockets)
+ store(cave, x, y, O_PLAYER);
+ break;
+
+ default:
+ // cannot fire in other directions
+ break;
+ }
+
+ gd_sound_play(cave, GD_S_BOMB_PLACING, O_BOMB, x, y);
+ }
+
+ // a player with rocket launcher cannot snap elements, so stop here
+ break;
+ }
+
+ // pushing and collecting
+ // if we are 'eating' a teleporter, and the function returns true
+ // (teleporting worked), break here
+ if (what == O_TELEPORTER && do_teleporter(cave, x, y, player_move))
+ break;
+
+ // player fire is false...
+ if (do_push(cave, x, y, player_move, FALSE))
+ {
+ remains = O_SPACE;
+ }
+ else
+ {
+ // get element. if cannot get, player_get_element will return the same
+ remains = player_get_element(cave, what, x, y);
+ }
+
+ // if something changed, OR there is space, move.
+ if (remains != what || remains == O_SPACE)
+ {
+ // if anything changed, apply the change.
+ move(cave, x, y, player_move, O_PLAYER_ROCKET_LAUNCHER);
+ }
+ }
+ break;
+