X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=3471f671a8e145e01f08d994ff138154a085540c;hb=e6856beb007b3f09036a04290c6b162953ddfece;hp=e69b1e6182af1d54529f3bfb883cc2d9d0851816;hpb=667288cc3f60989bfc84ac50bb69dae0c7bb5b22;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index e69b1e61..3471f671 100644 --- a/src/game.c +++ b/src/game.c @@ -95,6 +95,7 @@ #define EMU_NONE 0 #define EMU_BOULDERDASH 1 #define EMU_SOKOBAN 2 +#define EMU_SUPAPLEX 3 /* to control special behaviour of certain game elements */ int game_emulation = EMU_NONE; @@ -176,6 +177,7 @@ static void InitField(int x, int y, boolean init_game) switch (Feld[x][y]) { case EL_SPIELFIGUR: + case EL_SP_MURPHY: if (init_game) Feld[x][y] = EL_SPIELER1; /* no break! */ @@ -260,6 +262,8 @@ static void InitField(int x, int y, boolean init_game) case EL_MAMPFER2: case EL_ROBOT: case EL_PACMAN: + case EL_SP_SNIKSNAK: + case EL_SP_ELECTRON: InitMovDir(x, y); break; @@ -298,6 +302,10 @@ static void InitField(int x, int y, boolean init_game) MovDir[x][y] = 1 << RND(4); break; + case EL_SP_EMPTY: + Feld[x][y] = EL_LEERRAUM; + break; + default: break; } @@ -308,6 +316,7 @@ void InitGame() int i, j, x, y; boolean emulate_bd = TRUE; /* unless non-BOULDERDASH elements found */ boolean emulate_sb = TRUE; /* unless non-SOKOBAN elements found */ + boolean emulate_sp = TRUE; /* unless non-SUPAPLEX elements found */ /* don't play tapes over network */ network_playing = (options.network && !tape.playing); @@ -421,14 +430,19 @@ void InitGame() } } - for(y=0; yjx >= MIDPOSX-1) @@ -615,6 +630,7 @@ void InitMovDir(int x, int y) Feld[x][y] = EL_KAEFER; MovDir[x][y] = direction[0][element - EL_KAEFER_R]; break; + case EL_FLIEGER_R: case EL_FLIEGER_O: case EL_FLIEGER_L: @@ -622,6 +638,7 @@ void InitMovDir(int x, int y) Feld[x][y] = EL_FLIEGER; MovDir[x][y] = direction[0][element - EL_FLIEGER_R]; break; + case EL_BUTTERFLY_R: case EL_BUTTERFLY_O: case EL_BUTTERFLY_L: @@ -629,6 +646,7 @@ void InitMovDir(int x, int y) Feld[x][y] = EL_BUTTERFLY; MovDir[x][y] = direction[0][element - EL_BUTTERFLY_R]; break; + case EL_FIREFLY_R: case EL_FIREFLY_O: case EL_FIREFLY_L: @@ -636,6 +654,7 @@ void InitMovDir(int x, int y) Feld[x][y] = EL_FIREFLY; MovDir[x][y] = direction[0][element - EL_FIREFLY_R]; break; + case EL_PACMAN_R: case EL_PACMAN_O: case EL_PACMAN_L: @@ -643,6 +662,15 @@ void InitMovDir(int x, int y) Feld[x][y] = EL_PACMAN; MovDir[x][y] = direction[0][element - EL_PACMAN_R]; break; + + case EL_SP_SNIKSNAK: + MovDir[x][y] = MV_UP; + break; + + case EL_SP_ELECTRON: + MovDir[x][y] = MV_LEFT; + break; + default: MovDir[x][y] = 1 << RND(4); if (element != EL_KAEFER && @@ -663,7 +691,8 @@ void InitMovDir(int x, int y) MovDir[x][y] = direction[0][i]; break; } - else if (element == EL_FLIEGER || element == EL_FIREFLY) + else if (element == EL_FLIEGER || element == EL_FIREFLY || + element == EL_SP_SNIKSNAK || element == EL_SP_ELECTRON) { MovDir[x][y] = direction[1][i]; break; @@ -1033,6 +1062,9 @@ void Explode(int ex, int ey, int phase, int mode) Store[x][y] = EL_EDELSTEIN_GELB; break; } + + if (game_emulation == EMU_SUPAPLEX) + Store[x][y] = EL_LEERRAUM; } else if (center_element == EL_MAULWURF) Store[x][y] = EL_EDELSTEIN_ROT; @@ -1042,6 +1074,8 @@ void Explode(int ex, int ey, int phase, int mode) Store[x][y] = ((x == ex && y == ey) ? EL_DIAMANT : EL_EDELSTEIN); else if (center_element == EL_BUTTERFLY) Store[x][y] = EL_EDELSTEIN_BD; + else if (center_element == EL_SP_ELECTRON) + Store[x][y] = EL_SP_INFOTRON; else if (center_element == EL_MAMPFER) Store[x][y] = level.mampfer_inhalt[MampferNr][x-ex+1][y-ey+1]; else if (center_element == EL_AMOEBA2DIAM) @@ -1123,12 +1157,19 @@ void Explode(int ex, int ey, int phase, int mode) InitMovDir(x, y); DrawLevelField(x, y); } - else if (!(phase%delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y))) + else if (!(phase % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y))) { + int graphic = GFX_EXPLOSION; + + if (game_emulation == EMU_SUPAPLEX) + graphic = (Store[x][y] == EL_SP_INFOTRON ? + GFX_SP_EXPLODE_INFOTRON : + GFX_SP_EXPLODE_EMPTY); + if (phase == delay) ErdreichAnbroeckeln(SCREENX(x), SCREENY(y)); - DrawGraphic(SCREENX(x), SCREENY(y), GFX_EXPLOSION+(phase/delay-1)); + DrawGraphic(SCREENX(x), SCREENY(y), graphic + (phase / delay - 1)); } } @@ -1280,7 +1321,8 @@ void Impact(int x, int y) return; } - if (element == EL_BOMBE && (lastline || object_hit)) /* element is bomb */ + if ((element == EL_BOMBE || element == EL_SP_DISK_ORANGE) && + (lastline || object_hit)) /* element is bomb */ { Bang(x, y); return; @@ -1338,10 +1380,11 @@ void Impact(int x, int y) return; } } - else if (element == EL_FELSBROCKEN) + else if (element == EL_FELSBROCKEN || element == EL_SP_ZONK) { - if (IS_ENEMY(smashed) || smashed == EL_BOMBE || smashed == EL_SONDE || - smashed == EL_SCHWEIN || smashed == EL_DRACHE) + if (IS_ENEMY(smashed) || + smashed == EL_BOMBE || smashed == EL_SP_DISK_ORANGE || + smashed == EL_SONDE || smashed == EL_SCHWEIN || smashed == EL_DRACHE) { Bang(x, y+1); return; @@ -1480,7 +1523,8 @@ void TurnRound(int x, int y) else if (element == EL_BUTTERFLY) /* && MovDir[x][y] == left_dir) */ MovDelay[x][y] = 1; } - else if (element == EL_FLIEGER || element == EL_FIREFLY) + else if (element == EL_FLIEGER || element == EL_FIREFLY || + element == EL_SP_SNIKSNAK || element == EL_SP_ELECTRON) { TestIfBadThingHitsOtherBadThing(x, y); @@ -1491,7 +1535,9 @@ void TurnRound(int x, int y) !IS_FREE_OR_PLAYER(move_x, move_y)) MovDir[x][y] = right_dir; - if (element == EL_FLIEGER && MovDir[x][y] != old_move_dir) + if ((element == EL_FLIEGER || + element == EL_SP_SNIKSNAK || element == EL_SP_ELECTRON) + && MovDir[x][y] != old_move_dir) MovDelay[x][y] = 9; else if (element == EL_FIREFLY) /* && MovDir[x][y] == right_dir) */ MovDelay[x][y] = 1; @@ -1969,7 +2015,9 @@ void StartMoving(int x, int y) if (element!=EL_MAMPFER && element!=EL_MAMPFER2 && element!=EL_PACMAN) { TurnRound(x, y); - if (MovDelay[x][y] && (element == EL_KAEFER || element == EL_FLIEGER)) + if (MovDelay[x][y] && (element == EL_KAEFER || element == EL_FLIEGER || + element == EL_SP_SNIKSNAK || + element == EL_SP_ELECTRON)) DrawLevelField(x, y); } } @@ -1978,8 +2026,8 @@ void StartMoving(int x, int y) { MovDelay[x][y]--; - if (element == EL_ROBOT || element == EL_MAMPFER || - element == EL_MAMPFER2) + if (element == EL_ROBOT || + element == EL_MAMPFER || element == EL_MAMPFER2) { int phase = MovDelay[x][y] % 8; @@ -1993,6 +2041,8 @@ void StartMoving(int x, int y) && MovDelay[x][y]%4 == 3) PlaySoundLevel(x, y, SND_NJAM); } + else if (element == EL_SP_ELECTRON) + DrawGraphicAnimation(x, y, GFX2_SP_ELECTRON, 8, 2, ANIM_NORMAL); else if (element == EL_DRACHE) { int i; @@ -2214,12 +2264,15 @@ void StartMoving(int x, int y) TurnRound(x, y); - if (element == EL_KAEFER || element == EL_FLIEGER) + if (element == EL_KAEFER || element == EL_FLIEGER || + element == EL_SP_SNIKSNAK) DrawLevelField(x, y); else if (element == EL_BUTTERFLY || element == EL_FIREFLY) DrawGraphicAnimation(x, y, el2gfx(element), 2, 4, ANIM_NORMAL); else if (element == EL_SONDE) DrawGraphicAnimation(x, y, GFX_SONDE_START, 8, 2, ANIM_NORMAL); + else if (element == EL_SP_ELECTRON) + DrawGraphicAnimation(x, y, GFX2_SP_ELECTRON, 8, 2, ANIM_NORMAL); return; } @@ -2244,7 +2297,7 @@ void ContinueMoving(int x, int y) int newx = x + dx, newy = y + dy; int step = (horiz_move ? dx : dy) * TILEX/8; - if (CAN_FALL(element) && horiz_move) + if (CAN_FALL(element) && horiz_move && !IS_SP_ELEMENT(element)) step*=2; else if (element == EL_TROPFEN) step/=2; @@ -2607,7 +2660,7 @@ void AmoebeAbleger(int ax, int ay) if (newax == ax && neway == ay) /* amoeba cannot grow */ { - if (i == 4 && !waiting_for_player) + if (i == 4 && (!waiting_for_player || game_emulation == EMU_BOULDERDASH)) { Feld[ax][ay] = EL_AMOEBE_TOT; DrawLevelField(ax, ay); @@ -3442,6 +3495,10 @@ void GameActions() MauerAbleger(x, y); else if (element == EL_BURNING) CheckForDragon(x, y); + else if (element == EL_SP_TERMINAL) + DrawGraphicAnimation(x, y, GFX2_SP_TERMINAL, 7, 12, ANIM_NORMAL); + else if (element == EL_SP_TERMINAL_ACTIVE) + DrawGraphicAnimation(x, y, GFX2_SP_TERMINAL_ACTIVE, 7, 4, ANIM_NORMAL); if (SiebAktiv) { @@ -4128,6 +4185,7 @@ int DigField(struct PlayerInfo *player, break; case EL_DYNAMIT_AUS: + case EL_SP_DISK_RED: RemoveField(x, y); player->dynamite++; RaiseScoreElement(EL_DYNAMIT); @@ -4187,10 +4245,39 @@ int DigField(struct PlayerInfo *player, return MF_ACTION; break; + case EL_SP_TERMINAL: + { + int xx, yy; + + for (yy=0; yygems_still_needed > 0) + return MF_NO_ACTION; + + player->LevelSolved = player->GameOver = TRUE; + PlaySoundLevel(x, y, SND_BUING); + break; + case EL_FELSBROCKEN: case EL_BOMBE: case EL_KOKOSNUSS: case EL_ZEIT_LEER: + case EL_SP_ZONK: + case EL_SP_DISK_ORANGE: if (dy || mode == DF_SNAP) return MF_NO_ACTION; @@ -4241,6 +4328,42 @@ int DigField(struct PlayerInfo *player, return MF_NO_ACTION; break; + case EL_SP_PORT1_LEFT: + case EL_SP_PORT2_LEFT: + case EL_SP_PORT1_RIGHT: + case EL_SP_PORT2_RIGHT: + case EL_SP_PORT1_UP: + case EL_SP_PORT2_UP: + case EL_SP_PORT1_DOWN: + case EL_SP_PORT2_DOWN: + case EL_SP_PORT_X: + case EL_SP_PORT_Y: + case EL_SP_PORT_XY: + if ((dx == -1 && + element != EL_SP_PORT1_LEFT && + element != EL_SP_PORT2_LEFT && + element != EL_SP_PORT_X && + element != EL_SP_PORT_XY) || + (dx == +1 && + element != EL_SP_PORT1_RIGHT && + element != EL_SP_PORT2_RIGHT && + element != EL_SP_PORT_X && + element != EL_SP_PORT_XY) || + (dy == -1 && + element != EL_SP_PORT1_UP && + element != EL_SP_PORT2_UP && + element != EL_SP_PORT_Y && + element != EL_SP_PORT_XY) || + (dy == +1 && + element != EL_SP_PORT1_DOWN && + element != EL_SP_PORT2_DOWN && + element != EL_SP_PORT_Y && + element != EL_SP_PORT_XY) || + !IN_LEV_FIELD(x + dx, y + dy) || + !IS_FREE(x + dx, y + dy)) + return MF_NO_ACTION; + break; + case EL_AUSGANG_ZU: case EL_AUSGANG_ACT: /* door is not (yet) open */ @@ -4286,6 +4409,7 @@ int DigField(struct PlayerInfo *player, case EL_SOKOBAN_FELD_VOLL: case EL_SOKOBAN_OBJEKT: case EL_SONDE: + case EL_SP_DISK_YELLOW: if (mode == DF_SNAP) return MF_NO_ACTION;