X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=ea493de1b25dfc3c5044cd775e500fd8fda2da15;hb=f6482a3218cec02ca8e251993972e681e47d4244;hp=f51b2dc48ab3d13ed1bddd881935af1974ba8e7b;hpb=6c76f4a6d82bd6d75b16a3072f61e79865117d8b;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index f51b2dc4..ea493de1 100644 --- a/src/game.c +++ b/src/game.c @@ -312,6 +312,19 @@ static void InitField(int x, int y, boolean init_game) Feld[x][y] = EL_LEERRAUM; break; + case EL_EM_KEY_1_FILE: + Feld[x][y] = EL_EM_KEY_1; + break; + case EL_EM_KEY_2_FILE: + Feld[x][y] = EL_EM_KEY_2; + break; + case EL_EM_KEY_3_FILE: + Feld[x][y] = EL_EM_KEY_3; + break; + case EL_EM_KEY_4_FILE: + Feld[x][y] = EL_EM_KEY_4; + break; + default: break; } @@ -339,6 +352,7 @@ void InitGame() player->action = 0; player->effective_action = 0; + player->programmed_action = 0; player->score = 0; player->gems_still_needed = level.edelsteine; @@ -371,6 +385,7 @@ void InitGame() player->move_delay = 0; player->last_move_dir = MV_NO_MOVING; + player->move_speed = (level.double_speed ? 4 : 8); player->snapped = FALSE; player->gone = FALSE; @@ -405,8 +420,12 @@ void InitGame() ScreenMovPos = 0; ScreenGfxPos = 0; + /* MoveSpeed = (level.double_speed ? 4 : 8); ScrollStepSize = TILEX / MoveSpeed; + */ + + ScrollStepSize = 0; AllPlayersGone = FALSE; SiebAktiv = FALSE; @@ -560,10 +579,10 @@ void InitGame() SBY_Lower = lev_fieldy - SCR_FIELDY + 1; } - if (lev_fieldx < SCR_FIELDX) + if (lev_fieldx + (SBX_Left == -1 ? 2 : 0) <= SCR_FIELDX) SBX_Left = SBX_Right = -1 * (SCR_FIELDX - lev_fieldx) / 2; - if (lev_fieldy < SCR_FIELDY) + if (lev_fieldy + (SBY_Upper == -1 ? 2 : 0) <= SCR_FIELDY) SBY_Upper = SBY_Lower = -1 * (SCR_FIELDY - lev_fieldy) / 2; scroll_x = SBX_Left; @@ -968,6 +987,29 @@ int MovingOrBlocked2Element(int x, int y) return element; } +static int MovingOrBlocked2ElementIfNotLeaving(int x, int y) +{ + /* like MovingOrBlocked2Element(), but if element is moving + and (x,y) is the field the moving element is just leaving, + return EL_BLOCKED instead of the element value */ + int element = Feld[x][y]; + + if (IS_MOVING(x, y)) + { + if (element == EL_BLOCKED) + { + int oldx, oldy; + + Blocked2Moving(x, y, &oldx, &oldy); + return Feld[oldx][oldy]; + } + else + return EL_BLOCKED; + } + else + return element; +} + static void RemoveField(int x, int y) { Feld[x][y] = EL_LEERRAUM; @@ -1529,6 +1571,10 @@ void Impact(int x, int y) case EL_SCHLUESSEL2: case EL_SCHLUESSEL3: case EL_SCHLUESSEL4: + case EL_EM_KEY_1: + case EL_EM_KEY_2: + case EL_EM_KEY_3: + case EL_EM_KEY_4: sound = SND_KINK; break; case EL_ZEIT_VOLL: @@ -3361,8 +3407,14 @@ static void PlayerActions(struct PlayerInfo *player, byte player_action) { DigField(player, 0, 0, 0, 0, DF_NO_PUSH); SnapField(player, 0, 0); + + /* if (++player->frame_reset_delay > MoveSpeed) player->Frame = 0; + */ + + if (++player->frame_reset_delay > player->move_speed) + player->Frame = 0; } if (tape.recording && num_stored_actions >= MAX_PLAYERS && save_tape_entry) @@ -3514,6 +3566,22 @@ void GameActions() { int actual_player_action = stored_player[i].effective_action; + if (stored_player[i].programmed_action) + { + /* this is very bad and need to be fixed!!! */ + unsigned long move_delay = stored_player[i].move_delay; + + /* + if (FrameReached(&move_delay, MoveSpeed)) + */ + + if (FrameReached(&move_delay, stored_player[i].move_speed)) + { + actual_player_action = stored_player[i].programmed_action; + stored_player[i].programmed_action = 0; + } + } + if (recorded_player_action) actual_player_action = recorded_player_action[i]; @@ -3822,7 +3890,11 @@ boolean MoveFigureOneStep(struct PlayerInfo *player, if (!options.network && !AllPlayersInSight(player, new_jx, new_jy)) return MF_NO_ACTION; +#if 0 element = MovingOrBlocked2Element(new_jx, new_jy); +#else + element = MovingOrBlocked2ElementIfNotLeaving(new_jx, new_jy); +#endif if (DONT_GO_TO(element)) { @@ -3852,7 +3924,12 @@ boolean MoveFigureOneStep(struct PlayerInfo *player, jy = player->jy = new_jy; StorePlayer[jx][jy] = player->element_nr; + /* player->MovPos = (dx > 0 || dy > 0 ? -1 : 1) * (TILEX - TILEX / MoveSpeed); + */ + + player->MovPos = + (dx > 0 || dy > 0 ? -1 : 1) * (TILEX - TILEX / player->move_speed); ScrollFigure(player, SCROLL_INIT); @@ -3868,22 +3945,36 @@ boolean MoveFigure(struct PlayerInfo *player, int dx, int dy) if (player->gone || (!dx && !dy)) return FALSE; + /* if (!FrameReached(&player->move_delay, MoveSpeed) && !tape.playing) return FALSE; + */ + + if (!FrameReached(&player->move_delay, player->move_speed) && !tape.playing) + return FALSE; if (player->MovPos) { /* should only happen if pre-1.2 tape recordings are played */ /* this is only for backward compatibility */ + /* int old_move_speed = MoveSpeed; + */ + + int old_move_speed = player->move_speed; #if DEBUG printf("THIS SHOULD ONLY HAPPEN WITH PRE-1.2 LEVEL TAPES.\n"); #endif /* scroll remaining steps with finest movement resolution */ + + /* MoveSpeed = 8; + */ + + player->move_speed = 8; while (player->MovPos) { @@ -3894,7 +3985,12 @@ boolean MoveFigure(struct PlayerInfo *player, int dx, int dy) BackToFront(); } + /* MoveSpeed = old_move_speed; + */ + + player->move_speed = old_move_speed; + } if (player->last_move_dir & (MV_LEFT | MV_RIGHT)) @@ -4011,6 +4107,7 @@ void ScrollFigure(struct PlayerInfo *player, int mode) { int jx = player->jx, jy = player->jy; int last_jx = player->last_jx, last_jy = player->last_jy; + int move_stepsize = TILEX / player->move_speed; if (!player->active || player->gone || !player->MovPos) return; @@ -4018,7 +4115,7 @@ void ScrollFigure(struct PlayerInfo *player, int mode) if (mode == SCROLL_INIT) { player->actual_frame_counter = FrameCounter; - player->GfxPos = ScrollStepSize * (player->MovPos / ScrollStepSize); + player->GfxPos = move_stepsize * (player->MovPos / move_stepsize); if (Feld[last_jx][last_jy] == EL_LEERRAUM) Feld[last_jx][last_jy] = EL_PLAYER_IS_LEAVING; @@ -4029,16 +4126,43 @@ void ScrollFigure(struct PlayerInfo *player, int mode) else if (!FrameReached(&player->actual_frame_counter, 1)) return; - player->MovPos += (player->MovPos > 0 ? -1 : 1) * TILEX / MoveSpeed; - player->GfxPos = ScrollStepSize * (player->MovPos / ScrollStepSize); + player->MovPos += (player->MovPos > 0 ? -1 : 1) * move_stepsize; + player->GfxPos = move_stepsize * (player->MovPos / move_stepsize); if (Feld[last_jx][last_jy] == EL_PLAYER_IS_LEAVING) Feld[last_jx][last_jy] = EL_LEERRAUM; + + /* + if (!player->MovPos && level.gravity) + { + if (player->action == MV_NO_MOVING) + player->programmed_action = MV_DOWN; + } + */ + + DrawPlayer(player); if (!player->MovPos) { + if (IS_QUICK_GATE(Feld[last_jx][last_jy])) + { + /* continue with normal speed after moving through port */ + /* FIX THIS: what about player already having eaten a speed pill? */ + + /* + MoveSpeed = 8; + ScrollStepSize = TILEX / MoveSpeed; + */ + + player->move_speed = 8; + + /* don't wait for the next move -- the whole move delay stuff + is worse at the moment; FIX THIS! ;-) */ + player->move_delay = 0; + } + player->last_jx = jx; player->last_jy = jy; @@ -4058,6 +4182,9 @@ void ScrollScreen(struct PlayerInfo *player, int mode) if (mode == SCROLL_INIT) { + /* set scrolling step size according to actual player's moving speed */ + ScrollStepSize = TILEX / player->move_speed; + screen_frame_counter = FrameCounter; ScreenMovDir = player->MovDir; ScreenMovPos = player->MovPos; @@ -4069,7 +4196,7 @@ void ScrollScreen(struct PlayerInfo *player, int mode) if (ScreenMovPos) { - ScreenMovPos += (ScreenMovPos > 0 ? -1 : 1) * TILEX / MoveSpeed; + ScreenMovPos += (ScreenMovPos > 0 ? -1 : 1) * ScrollStepSize; ScreenGfxPos = ScrollStepSize * (ScreenMovPos / ScrollStepSize); redraw_mask |= REDRAW_FIELD; } @@ -4104,7 +4231,11 @@ void TestIfGoodThingHitsBadThing(int goodx, int goody) if (!IN_LEV_FIELD(x, y)) continue; +#if 0 element = Feld[x][y]; +#else + element = MovingOrBlocked2ElementIfNotLeaving(x, y); +#endif if (DONT_TOUCH(element)) { @@ -4287,6 +4418,10 @@ int DigField(struct PlayerInfo *player, { int jx = player->jx, jy = player->jy; int dx = x - jx, dy = y - jy; + int move_direction = (dx == -1 ? MV_LEFT : + dx == +1 ? MV_RIGHT : + dy == -1 ? MV_UP : + dy == +1 ? MV_DOWN : MV_NO_MOVING); int element; if (!player->MovPos) @@ -4343,8 +4478,14 @@ int DigField(struct PlayerInfo *player, case EL_SPEED_PILL: RemoveField(x, y); + + player->move_speed = 4; + + /* MoveSpeed = 4; - ScrollStepSize = TILEX/4; + ScrollStepSize = TILEX / MoveSpeed; + */ + PlaySoundLevel(x, y, SND_PONG); break; @@ -4389,7 +4530,27 @@ int DigField(struct PlayerInfo *player, case EL_SCHLUESSEL3: case EL_SCHLUESSEL4: { - int key_nr = element-EL_SCHLUESSEL1; + int key_nr = element - EL_SCHLUESSEL1; + + RemoveField(x, y); + player->key[key_nr] = TRUE; + RaiseScoreElement(EL_SCHLUESSEL); + DrawMiniGraphicExt(drawto, gc, + DX_KEYS+key_nr*MINI_TILEX, DY_KEYS, + GFX_SCHLUESSEL1+key_nr); + DrawMiniGraphicExt(window, gc, + DX_KEYS+key_nr*MINI_TILEX, DY_KEYS, + GFX_SCHLUESSEL1+key_nr); + PlaySoundLevel(x, y, SND_PONG); + break; + } + + case EL_EM_KEY_1: + case EL_EM_KEY_2: + case EL_EM_KEY_3: + case EL_EM_KEY_4: + { + int key_nr = element - EL_EM_KEY_1; RemoveField(x, y); player->key[key_nr] = TRUE; @@ -4485,7 +4646,7 @@ int DigField(struct PlayerInfo *player, case EL_PFORTE2: case EL_PFORTE3: case EL_PFORTE4: - if (!player->key[element-EL_PFORTE1]) + if (!player->key[element - EL_PFORTE1]) return MF_NO_ACTION; break; @@ -4493,10 +4654,42 @@ int DigField(struct PlayerInfo *player, case EL_PFORTE2X: case EL_PFORTE3X: case EL_PFORTE4X: - if (!player->key[element-EL_PFORTE1X]) + if (!player->key[element - EL_PFORTE1X]) return MF_NO_ACTION; break; + case EL_EM_GATE_1: + case EL_EM_GATE_2: + case EL_EM_GATE_3: + case EL_EM_GATE_4: + if (!player->key[element - EL_EM_GATE_1]) + return MF_NO_ACTION; + + if (!IN_LEV_FIELD(x + dx, y + dy) || !IS_FREE(x + dx, y + dy)) + return MF_NO_ACTION; + + /* automatically move to the next field with double speed */ + player->programmed_action = move_direction; + player->move_speed = 4; + + break; + + case EL_EM_GATE_1X: + case EL_EM_GATE_2X: + case EL_EM_GATE_3X: + case EL_EM_GATE_4X: + if (!player->key[element - EL_EM_GATE_1X]) + return MF_NO_ACTION; + + if (!IN_LEV_FIELD(x + dx, y + dy) || !IS_FREE(x + dx, y + dy)) + return MF_NO_ACTION; + + /* automatically move to the next field with double speed */ + player->programmed_action = move_direction; + player->move_speed = 4; + + break; + case EL_SP_PORT1_LEFT: case EL_SP_PORT2_LEFT: case EL_SP_PORT1_RIGHT: @@ -4531,6 +4724,16 @@ int DigField(struct PlayerInfo *player, !IN_LEV_FIELD(x + dx, y + dy) || !IS_FREE(x + dx, y + dy)) return MF_NO_ACTION; + + /* automatically move to the next field with double speed */ + player->programmed_action = move_direction; + player->move_speed = 4; + + /* + MoveSpeed = 4; + ScrollStepSize = TILEX / MoveSpeed; + */ + break; case EL_AUSGANG_ZU: