From 5e8d9d0308f76bb35e7578a8859d6f01977d0f69 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sat, 26 Sep 1998 04:28:56 +0200 Subject: [PATCH] rnd-19980926 --- src/cartoons.c | 6 +- src/editor.c | 5 + src/events.c | 83 ++-------- src/game.c | 413 +++++++++++++++++++++++++++++++++++-------------- src/game.h | 2 +- src/init.c | 21 ++- src/main.c | 5 +- src/main.h | 91 ++++++----- src/screens.c | 4 +- src/screens.h | 2 +- src/tools.c | 43 ++--- src/tools.h | 2 +- 12 files changed, 417 insertions(+), 260 deletions(-) diff --git a/src/cartoons.c b/src/cartoons.c index b8efebf3..2ffb823d 100644 --- a/src/cartoons.c +++ b/src/cartoons.c @@ -134,7 +134,7 @@ void HandleAnimation(int mode) for(xx=0;xxMovDir & (MV_LEFT|MV_RIGHT) ? ScreenMovPos : 0); + fy += (local_player->MovDir & (MV_UP|MV_DOWN) ? ScreenMovPos : 0); XCopyArea(display,fieldbuffer,backbuffer,gc, fx,fy, SXSIZE,SYSIZE, diff --git a/src/editor.c b/src/editor.c index fef23e2b..ae7e7e8c 100644 --- a/src/editor.c +++ b/src/editor.c @@ -86,6 +86,11 @@ int editor_element[] = EL_CHAR_A + ('N' - 'A'), EL_CHAR_A + ('E' - 'A'), + EL_SPIELER1, + EL_SPIELER2, + EL_SPIELER3, + EL_SPIELER4, + EL_SPIELFIGUR, EL_LEERRAUM, EL_ERDREICH, diff --git a/src/events.c b/src/events.c index d2b36488..039be790 100644 --- a/src/events.c +++ b/src/events.c @@ -171,7 +171,7 @@ void HandleExposeEvent(XExposeEvent *event) for(yy=0;yy=x1 && xx<=x2 && yy>=y1 && yy<=y2) DrawScreenField(xx,yy); - DrawPlayerField(); + DrawPlayerField(JX,JY); SetDrawtoField(DRAW_DIRECT); } @@ -180,8 +180,8 @@ void HandleExposeEvent(XExposeEvent *event) { int fx = FX, fy = FY; - fx += (PlayerMovDir & (MV_LEFT|MV_RIGHT) ? ScreenMovPos : 0); - fy += (PlayerMovDir & (MV_UP|MV_DOWN) ? ScreenMovPos : 0); + fx += (local_player->MovDir & (MV_LEFT|MV_RIGHT) ? ScreenMovPos : 0); + fy += (local_player->MovDir & (MV_UP|MV_DOWN) ? ScreenMovPos : 0); XCopyArea(display,fieldbuffer,backbuffer,gc, fx,fy, SXSIZE,SYSIZE, @@ -291,7 +291,7 @@ void HandleButton(int mx, int my, int button) HandleSetupScreen(mx,my,0,0,button); break; case PLAYING: - HandleGameActions(); + HandleGameActions(0); break; default: break; @@ -655,7 +655,11 @@ void HandleNoXEvent() break; case PLAYING: HandleJoystick(); - HandleGameActions(); + + /* + HandleGameActions(0); + */ + break; default: break; @@ -672,15 +676,10 @@ void HandleJoystick() int up = joy & JOY_UP; int down = joy & JOY_DOWN; int button = joy & JOY_BUTTON; - int button1 = joy & JOY_BUTTON_1; - int button2 = joy & JOY_BUTTON_2; int newbutton = (JoystickButton() == JOY_BUTTON_NEW_PRESSED); int dx = (left ? -1 : right ? 1 : 0); int dy = (up ? -1 : down ? 1 : 0); - if (game_status==PLAYING && (tape.playing || keyboard)) - newbutton = ((joy & JOY_BUTTON) != 0); - switch(game_status) { case MAINMENU: @@ -700,16 +699,18 @@ void HandleJoystick() HandleSetupScreen(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK); break; } + case HALLOFFAME: HandleHallOfFame(!newbutton); break; + case HELPSCREEN: HandleHelpScreen(!newbutton); break; + case PLAYING: - { - static int player_frame_reset_delay = 0; - BOOL moved = FALSE, snapped = FALSE, bombed = FALSE; + if (tape.playing || keyboard) + newbutton = ((joy & JOY_BUTTON) != 0); if (GameOver && newbutton) { @@ -722,61 +723,9 @@ void HandleJoystick() if (tape.pausing || PlayerGone) joy = 0; - if (joy) - { - player_frame_reset_delay = 0; - - if (button1) - snapped = SnapField(dx,dy); - else - { - if (button2) - bombed = PlaceBomb(); - moved = MoveFigure(dx,dy); - } - - if (tape.recording && (moved || snapped || bombed)) - { - if (bombed && !moved) - joy &= JOY_BUTTON; - TapeRecordAction(joy); - } - else if (tape.playing && snapped) - SnapField(0,0); /* stop snapping */ - } - else - { - DigField(0,0,0,0,DF_NO_PUSH); - SnapField(0,0); - if (++player_frame_reset_delay > MoveSpeed) - PlayerFrame = 0; - } - - if (tape.playing && !tape.pausing && !joy && tape.counter= tape.pos[tape.counter].delay) - { - PlayerMovDir = next_joy; - PlayerFrame = FrameCounter % 4; - PlayerPushing = TRUE; - } - } - } - } + HandleGameActions(joy); break; - } + default: break; } diff --git a/src/game.c b/src/game.c index c7b99a3d..fd581659 100644 --- a/src/game.c +++ b/src/game.c @@ -59,45 +59,75 @@ void GetPlayerConfig() void InitGame() { - int i,x,y; + int i, x,y; BOOL emulate_bd = TRUE; /* unless non-BOULDERDASH elements found */ BOOL emulate_sb = TRUE; /* unless non-SOKOBAN elements found */ + for(i=0; inr = 1; local_player->active = TRUE; local_player->local = TRUE; - actual_player = local_player; - - actual_player->score = 0; + player = local_player; - actual_player->gems_still_needed = level.edelsteine; - actual_player->sokobanfields_still_needed = 0; - actual_player->lights_still_needed = 0; - actual_player->friends_still_needed = 0; + player->score = 0; + player->gems_still_needed = level.edelsteine; + player->sokobanfields_still_needed = 0; + player->lights_still_needed = 0; + player->friends_still_needed = 0; for(i=0; i<4; i++) - actual_player->key[i] = FALSE; + player->key[i] = FALSE; - actual_player->dynamite = 0; - actual_player->dynabomb_count = 0; - actual_player->dynabomb_size = 0; - actual_player->dynabombs_left = 0; - actual_player->dynabomb_xl = FALSE; + player->dynamite = 0; + player->dynabomb_count = 0; + player->dynabomb_size = 0; + player->dynabombs_left = 0; + player->dynabomb_xl = FALSE; MampferNr = 0; FrameCounter = 0; TimeFrames = 0; TimeLeft = level.time; ScreenMovPos = 0; - PlayerMovDir = MV_NO_MOVING; - PlayerMovPos = 0; - PlayerGfxPos = 0; - PlayerFrame = 0; - PlayerPushing = FALSE; - PlayerGone = LevelSolved = GameOver = SiebAktiv = FALSE; + + player->MovDir = MV_NO_MOVING; + player->MovPos = 0; + player->Pushing = FALSE; + player->GfxPos = 0; + player->Frame = 0; + + player->frame_reset_delay = 0; + + player->push_delay = 0; + player->push_delay_value = 5; + + player->move_delay = 0; + player->last_move_dir = MV_NO_MOVING; + + player->lastJX = player->lastJY = 0; + player->JX = player->JY = 0; + + lastJX = lastJY = 0; JX = JY = 0; ZX = ZY = -1; + + /* test */ + for(i=1; iJX = JX; + player->JY = JY; + player->lastJX = lastJX; + player->lastJY = lastJY; + break; case EL_SPIELER2: case EL_SPIELER3: case EL_SPIELER4: + StorePlayer[x][y] = Feld[x][y]; Feld[x][y] = EL_LEERRAUM; + + stored_player[StorePlayer[x][y] - EL_SPIELER1].JX = x; + stored_player[StorePlayer[x][y] - EL_SPIELER1].JY = y; + stored_player[StorePlayer[x][y] - EL_SPIELER1].lastJX = x; + stored_player[StorePlayer[x][y] - EL_SPIELER1].lastJY = y; + break; case EL_BADEWANNE: if (xdynabomb_xl) + !player->dynabomb_xl) break; } } - actual_player->dynabombs_left++; + player->dynabombs_left++; } void Bang(int x, int y) @@ -842,7 +888,7 @@ void Bang(int x, int y) case EL_DYNABOMB_NR: case EL_DYNABOMB_SZ: case EL_DYNABOMB_XL: - DynaExplode(x,y,actual_player->dynabomb_size); + DynaExplode(x,y,player->dynabomb_size); break; case EL_BIRNE_AUS: case EL_BIRNE_EIN: @@ -1410,13 +1456,24 @@ void StartMoving(int x, int y) if (CAN_FALL(element) && y0 && IS_PLAYER(x-1,y)) || (xactive && pl->Pushing && pl->MovPos) + { + int nextJX = pl->JX + (pl->JX - pl->lastJX); + int nextJY = pl->JY + (pl->JY - pl->lastJY); + + if (x == nextJX && y == nextJY) + return; + } + } } if (element==EL_MORAST_VOLL) @@ -1682,7 +1739,7 @@ void StartMoving(int x, int y) else if (!IS_FREE(newx,newy)) { if (IS_PLAYER(x,y)) - DrawPlayerField(); + DrawPlayerField(x,y); else DrawLevelField(x,y); return; @@ -1703,7 +1760,7 @@ void StartMoving(int x, int y) else if (!IS_FREE(newx,newy)) { if (IS_PLAYER(x,y)) - DrawPlayerField(); + DrawPlayerField(x,y); else DrawLevelField(x,y); return; @@ -1714,7 +1771,7 @@ void StartMoving(int x, int y) if (!IS_FREE(newx,newy)) { if (IS_PLAYER(x,y)) - DrawPlayerField(); + DrawPlayerField(x,y); else DrawLevelField(x,y); return; @@ -1735,7 +1792,7 @@ void StartMoving(int x, int y) element1 != EL_BURNING && element2 != EL_BURNING) { if (IS_PLAYER(x,y)) - DrawPlayerField(); + DrawPlayerField(x,y); else DrawLevelField(x,y); @@ -1801,11 +1858,24 @@ void StartMoving(int x, int y) DrawGraphicAnimation(x,y, el2gfx(element), 2, 4, ANIM_NORMAL); else if (element==EL_SONDE) { - int nextJX = JX + (JX - lastJX); - int nextJY = JY + (JY - lastJY); + int i; + + /* check if this element is just being pushed */ + for(i=0; iactive && pl->Pushing && pl->GfxPos) + { + int nextJX = pl->JX + (pl->JX - pl->lastJX); + int nextJY = pl->JY + (pl->JY - pl->lastJY); + + if (x == nextJX && y == nextJY) + return; + } + } + + DrawGraphicAnimation(x,y, GFX_SONDE_START, 8, 2, ANIM_NORMAL); } return; @@ -2597,12 +2667,79 @@ void CheckForDragon(int x, int y) } } -void GameActions() +void PlayerActions(int player_action) +{ + BOOL moved = FALSE, snapped = FALSE, bombed = FALSE; + int left = player_action & JOY_LEFT; + int right = player_action & JOY_RIGHT; + int up = player_action & JOY_UP; + int down = player_action & JOY_DOWN; + int button1 = player_action & JOY_BUTTON_1; + int button2 = player_action & JOY_BUTTON_2; + int dx = (left ? -1 : right ? 1 : 0); + int dy = (up ? -1 : down ? 1 : 0); + + if (player_action) + { + player->frame_reset_delay = 0; + + if (button1) + snapped = SnapField(dx,dy); + else + { + if (button2) + bombed = PlaceBomb(); + moved = MoveFigure(dx,dy); + } + + if (tape.recording && (moved || snapped || bombed)) + { + if (bombed && !moved) + player_action &= JOY_BUTTON; + TapeRecordAction(player_action); + } + else if (tape.playing && snapped) + SnapField(0,0); /* stop snapping */ + } + else + { + DigField(0,0,0,0,DF_NO_PUSH); + SnapField(0,0); + if (++player->frame_reset_delay > MoveSpeed) + player->Frame = 0; + } + + if (tape.playing && !tape.pausing && !player_action && + tape.counter < tape.length) + { + int next_joy = tape.pos[tape.counter].joystickdata & (JOY_LEFT|JOY_RIGHT); + + if (next_joy == JOY_LEFT || next_joy == JOY_RIGHT) + { + int dx = (next_joy == JOY_LEFT ? -1 : +1); + + if (IN_LEV_FIELD(JX+dx,JY) && IS_PUSHABLE(Feld[JX+dx][JY])) + { + int el = Feld[JX+dx][JY]; + int push_delay = (IS_SB_ELEMENT(el) || el==EL_SONDE ? 2 : 10); + + if (tape.delay_played + push_delay >= tape.pos[tape.counter].delay) + { + player->MovDir = next_joy; + player->Frame = FrameCounter % 4; + player->Pushing = TRUE; + } + } + } + } +} + +void GameActions(int player_action) { static long action_delay = 0; long action_delay_value; int sieb_x = 0, sieb_y = 0; - int x, y, element; + int i, x,y, element; if (game_status != PLAYING) return; @@ -2615,12 +2752,32 @@ void GameActions() (tape.playing && tape.fast_forward ? FFWD_FRAME_DELAY : GAME_FRAME_DELAY); #endif - if (PlayerMovPos) - ScrollFigure(0); - /* main game synchronization point */ WaitUntilDelayReached(&action_delay, action_delay_value); + for(i=0; iJX; + JY = player->JY; + lastJX = player->lastJX; + lastJY = player->lastJY; + + if (!player->active) + continue; + + PlayerActions(player_action); + + if (player->MovPos) + ScrollFigure(0); + } + + player = local_player; + JX = player->JX; + JY = player->JY; + lastJX = player->lastJX; + lastJY = player->lastJY; + if (tape.pausing || (tape.playing && !TapePlayDelay())) return; else if (tape.recording) @@ -2765,7 +2922,32 @@ void GameActions() KillHero(); } - DrawPlayerField(); + + + + for(i=0; iJX; + JY = player->JY; + lastJX = player->lastJX; + lastJY = player->lastJY; + + if (!player->active) + continue; + + DrawPlayerField(player->JX,player->JY); + } + + player = local_player; + JX = player->JX; + JY = player->JY; + lastJX = player->lastJX; + lastJY = player->lastJY; + + /* + DrawPlayerField(JX,JY); + */ } void ScrollLevel(int dx, int dy) @@ -2773,7 +2955,7 @@ void ScrollLevel(int dx, int dy) int softscroll_offset = (soft_scrolling_on ? TILEX : 0); int x,y; - ScreenMovPos = PlayerGfxPos; + ScreenMovPos = player->GfxPos; XCopyArea(display,drawto_field,drawto_field,gc, FX + TILEX*(dx==-1) - softscroll_offset, @@ -2808,10 +2990,10 @@ BOOL MoveFigureOneStep(int dx, int dy, int real_dx, int real_dy) if (PlayerGone || (!dx && !dy)) return(MF_NO_ACTION); - PlayerMovDir = (dx < 0 ? MV_LEFT : - dx > 0 ? MV_RIGHT : - dy < 0 ? MV_UP : - dy > 0 ? MV_DOWN : MV_NO_MOVING); + player->MovDir = (dx < 0 ? MV_LEFT : + dx > 0 ? MV_RIGHT : + dy < 0 ? MV_UP : + dy > 0 ? MV_DOWN : MV_NO_MOVING); if (!IN_LEV_FIELD(newJX,newJY)) return(MF_NO_ACTION); @@ -2839,12 +3021,15 @@ BOOL MoveFigureOneStep(int dx, int dy, int real_dx, int real_dy) if (can_move != MF_MOVING) return(can_move); - lastJX = JX; - lastJY = JY; - JX = newJX; - JY = newJY; + lastJX = player->lastJX = JX; + lastJY = player->lastJY = JY; + JX = player->JX = newJX; + JY = player->JY = newJY; + + StorePlayer[lastJX][lastJY] = EL_LEERRAUM; + StorePlayer[JX][JY] = EL_SPIELER1; - PlayerMovPos = (dx > 0 || dy > 0 ? -1 : 1) * 7*TILEX/8; + player->MovPos = (dx > 0 || dy > 0 ? -1 : 1) * 7*TILEX/8; ScrollFigure(-1); @@ -2853,18 +3038,16 @@ BOOL MoveFigureOneStep(int dx, int dy, int real_dx, int real_dy) BOOL MoveFigure(int dx, int dy) { - static long move_delay = 0; - static int last_move_dir = MV_NO_MOVING; int moved = MF_NO_ACTION; int oldJX = JX, oldJY = JY; if (PlayerGone || (!dx && !dy)) return(FALSE); - if (!FrameReached(&move_delay,MoveSpeed) && !tape.playing) + if (!FrameReached(&player->move_delay,MoveSpeed) && !tape.playing) return(FALSE); - if (last_move_dir & (MV_LEFT | MV_RIGHT)) + if (player->last_move_dir & (MV_LEFT | MV_RIGHT)) { if (!(moved |= MoveFigureOneStep(0,dy, dx,dy))) moved |= MoveFigureOneStep(dx,0, dx,dy); @@ -2875,9 +3058,13 @@ BOOL MoveFigure(int dx, int dy) moved |= MoveFigureOneStep(0,dy, dx,dy); } - last_move_dir = MV_NO_MOVING; - if (moved & MF_MOVING) + /* + player->last_move_dir = MV_NO_MOVING; + */ + + + if (moved & MF_MOVING && player == local_player) { int old_scroll_x = scroll_x, old_scroll_y = scroll_y; int offset = (scroll_delay_on ? 3 : 0); @@ -2893,21 +3080,21 @@ BOOL MoveFigure(int dx, int dy) ScrollLevel(old_scroll_x - scroll_x, old_scroll_y - scroll_y); } - if (!(moved & MF_MOVING) && !PlayerPushing) - PlayerFrame = 0; + if (!(moved & MF_MOVING) && !player->Pushing) + player->Frame = 0; else - PlayerFrame = (PlayerFrame + 1) % 4; + player->Frame = (player->Frame + 1) % 4; if (moved & MF_MOVING) { if (oldJX != JX && oldJY == JY) - PlayerMovDir = (oldJX < JX ? MV_RIGHT : MV_LEFT); + player->MovDir = (oldJX < JX ? MV_RIGHT : MV_LEFT); else if (oldJX == JX && oldJY != JY) - PlayerMovDir = (oldJY < JY ? MV_DOWN : MV_UP); + player->MovDir = (oldJY < JY ? MV_DOWN : MV_UP); DrawLevelField(JX,JY); /* für "ErdreichAnbroeckeln()" */ - last_move_dir = PlayerMovDir; + player->last_move_dir = player->MovDir; } TestIfHeroHitsBadThing(); @@ -2924,40 +3111,34 @@ void ScrollFigure(int init) if (init) { - PlayerGfxPos = ScrollStepSize * (PlayerMovPos / ScrollStepSize); actual_frame_counter = FrameCounter; - /* - if (Feld[lastJX][lastJY] == EL_LEERRAUM && - IN_LEV_FIELD(lastJX,lastJY-1) && - CAN_FALL(Feld[lastJX][lastJY-1])) - Feld[lastJX][lastJY] = EL_PLAYER_IS_LEAVING; - */ + player->GfxPos = ScrollStepSize * (player->MovPos / ScrollStepSize); if (Feld[lastJX][lastJY] == EL_LEERRAUM) Feld[lastJX][lastJY] = EL_PLAYER_IS_LEAVING; - DrawPlayerField(); + DrawPlayerField(JX,JY); return; } else if (!FrameReached(&actual_frame_counter,1)) return; - PlayerMovPos += (PlayerMovPos > 0 ? -1 : 1) * TILEX/8; - PlayerGfxPos = ScrollStepSize * (PlayerMovPos / ScrollStepSize); + player->MovPos += (player->MovPos > 0 ? -1 : 1) * TILEX/8; + player->GfxPos = ScrollStepSize * (player->MovPos / ScrollStepSize); - if (ScreenMovPos && ScreenMovPos != PlayerGfxPos) + if (ScreenMovPos && ScreenMovPos != local_player->GfxPos) { - ScreenMovPos = PlayerGfxPos; + ScreenMovPos = local_player->GfxPos; redraw_mask |= REDRAW_FIELD; } if (Feld[lastJX][lastJY] == EL_PLAYER_IS_LEAVING) Feld[lastJX][lastJY] = EL_LEERRAUM; - DrawPlayerField(); + DrawPlayerField(JX,JY); - if (!PlayerMovPos) + if (!player->MovPos) { lastJX = JX; lastJY = JY; @@ -3149,19 +3330,17 @@ int DigField(int x, int y, int real_dx, int real_dy, int mode) { int dx = x-JX, dy = y-JY; int element; - static long push_delay = 0; - static int push_delay_value = 5; - if (!PlayerMovPos) - PlayerPushing = FALSE; + if (!player->MovPos) + player->Pushing = FALSE; if (mode == DF_NO_PUSH) { - push_delay = 0; + player->push_delay = 0; return(MF_NO_ACTION); } - if (IS_MOVING(x,y)) + if (IS_MOVING(x,y) || IS_PLAYER(x,y)) return(MF_NO_ACTION); element = Feld[x][y]; @@ -3205,7 +3384,7 @@ int DigField(int x, int y, int real_dx, int real_dy, int mode) case EL_DYNAMIT_AUS: Feld[x][y] = EL_LEERRAUM; - actual_player->dynamite++; + player->dynamite++; RaiseScoreElement(EL_DYNAMIT); DrawText(DX_DYNAMITE, DY_DYNAMITE, int2str(local_player->dynamite, 3), @@ -3215,22 +3394,22 @@ int DigField(int x, int y, int real_dx, int real_dy, int mode) case EL_DYNABOMB_NR: Feld[x][y] = EL_LEERRAUM; - actual_player->dynabomb_count++; - actual_player->dynabombs_left++; + player->dynabomb_count++; + player->dynabombs_left++; RaiseScoreElement(EL_DYNAMIT); PlaySoundLevel(x,y,SND_PONG); break; case EL_DYNABOMB_SZ: Feld[x][y] = EL_LEERRAUM; - actual_player->dynabomb_size++; + player->dynabomb_size++; RaiseScoreElement(EL_DYNAMIT); PlaySoundLevel(x,y,SND_PONG); break; case EL_DYNABOMB_XL: Feld[x][y] = EL_LEERRAUM; - actual_player->dynabomb_xl = TRUE; + player->dynabomb_xl = TRUE; RaiseScoreElement(EL_DYNAMIT); PlaySoundLevel(x,y,SND_PONG); break; @@ -3243,7 +3422,7 @@ int DigField(int x, int y, int real_dx, int real_dy, int mode) int key_nr = element-EL_SCHLUESSEL1; Feld[x][y] = EL_LEERRAUM; - actual_player->key[key_nr] = TRUE; + player->key[key_nr] = TRUE; RaiseScoreElement(EL_SCHLUESSEL); DrawMiniGraphicExt(drawto,gc, DX_KEYS+key_nr*MINI_TILEX,DY_KEYS, @@ -3270,7 +3449,7 @@ int DigField(int x, int y, int real_dx, int real_dy, int mode) if (dy || mode==DF_SNAP) return(MF_NO_ACTION); - PlayerPushing = TRUE; + player->Pushing = TRUE; if (!IN_LEV_FIELD(x+dx,y+dy) || Feld[x+dx][y+dy] != EL_LEERRAUM) return(MF_NO_ACTION); @@ -3281,15 +3460,16 @@ int DigField(int x, int y, int real_dx, int real_dy, int mode) return(MF_NO_ACTION); } - if (push_delay == 0) - push_delay = FrameCounter; - if (!FrameReached(&push_delay,push_delay_value) && !tape.playing) + if (player->push_delay == 0) + player->push_delay = FrameCounter; + if (!FrameReached(&player->push_delay, player->push_delay_value) && + !tape.playing) return(MF_NO_ACTION); Feld[x][y] = EL_LEERRAUM; Feld[x+dx][y+dy] = element; - push_delay_value = 2+RND(8); + player->push_delay_value = 2+RND(8); DrawLevelField(x+dx,y+dy); if (element==EL_FELSBROCKEN) @@ -3304,7 +3484,7 @@ int DigField(int x, int y, int real_dx, int real_dy, int mode) case EL_PFORTE2: case EL_PFORTE3: case EL_PFORTE4: - if (!actual_player->key[element-EL_PFORTE1]) + if (!player->key[element-EL_PFORTE1]) return(MF_NO_ACTION); break; @@ -3312,7 +3492,7 @@ int DigField(int x, int y, int real_dx, int real_dy, int mode) case EL_PFORTE2X: case EL_PFORTE3X: case EL_PFORTE4X: - if (!actual_player->key[element-EL_PFORTE1X]) + if (!player->key[element-EL_PFORTE1X]) return(MF_NO_ACTION); break; @@ -3360,7 +3540,7 @@ int DigField(int x, int y, int real_dx, int real_dy, int mode) if (mode==DF_SNAP) return(MF_NO_ACTION); - PlayerPushing = TRUE; + player->Pushing = TRUE; if (!IN_LEV_FIELD(x+dx,y+dy) || (Feld[x+dx][y+dy] != EL_LEERRAUM @@ -3379,9 +3559,10 @@ int DigField(int x, int y, int real_dx, int real_dy, int mode) return(MF_NO_ACTION); } - if (push_delay == 0) - push_delay = FrameCounter; - if (!FrameReached(&push_delay,push_delay_value) && !tape.playing) + if (player->push_delay == 0) + player->push_delay = FrameCounter; + if (!FrameReached(&player->push_delay, player->push_delay_value) && + !tape.playing) return(MF_NO_ACTION); if (IS_SB_ELEMENT(element)) @@ -3410,7 +3591,7 @@ int DigField(int x, int y, int real_dx, int real_dy, int mode) Feld[x+dx][y+dy] = element; } - push_delay_value = 2; + player->push_delay_value = 2; DrawLevelField(x,y); DrawLevelField(x+dx,y+dy); @@ -3437,7 +3618,7 @@ int DigField(int x, int y, int real_dx, int real_dy, int mode) break; } - push_delay = 0; + player->push_delay = 0; return(MF_MOVING); } @@ -3459,10 +3640,10 @@ BOOL SnapField(int dx, int dy) if (snapped) return(FALSE); - PlayerMovDir = (dx < 0 ? MV_LEFT : - dx > 0 ? MV_RIGHT : - dy < 0 ? MV_UP : - dy > 0 ? MV_DOWN : MV_NO_MOVING); + player->MovDir = (dx < 0 ? MV_LEFT : + dx > 0 ? MV_RIGHT : + dy < 0 ? MV_UP : + dy > 0 ? MV_DOWN : MV_NO_MOVING); if (!DigField(x,y, 0,0, DF_SNAP)) return(FALSE); @@ -3478,25 +3659,24 @@ BOOL PlaceBomb(void) { int element; - if (PlayerGone || PlayerMovPos) + if (PlayerGone || player->MovPos) return(FALSE); element = Feld[JX][JY]; - if ((actual_player->dynamite==0 && actual_player->dynabombs_left==0) || + if ((player->dynamite==0 && player->dynabombs_left==0) || element==EL_DYNAMIT || element==EL_DYNABOMB || element==EL_EXPLODING) return(FALSE); if (element != EL_LEERRAUM) Store[JX][JY] = element; - if (actual_player->dynamite) + if (player->dynamite) { Feld[JX][JY] = EL_DYNAMIT; MovDelay[JX][JY] = 96; - actual_player->dynamite--; - DrawText(DX_DYNAMITE, DY_DYNAMITE, - int2str(local_player->dynamite, 3), + player->dynamite--; + DrawText(DX_DYNAMITE, DY_DYNAMITE, int2str(local_player->dynamite, 3), FS_SMALL, FC_YELLOW); DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_DYNAMIT); } @@ -3504,7 +3684,7 @@ BOOL PlaceBomb(void) { Feld[JX][JY] = EL_DYNABOMB; MovDelay[JX][JY] = 96; - actual_player->dynabombs_left--; + player->dynabombs_left--; DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_DYNABOMB); } @@ -3549,8 +3729,7 @@ void PlaySoundLevel(int x, int y, int sound_nr) void RaiseScore(int value) { local_player->score += value; - DrawText(DX_SCORE, DY_SCORE, - int2str(local_player->score, 5), + DrawText(DX_SCORE, DY_SCORE, int2str(local_player->score, 5), FS_SMALL, FC_YELLOW); } diff --git a/src/game.h b/src/game.h index dabcb1af..56209335 100644 --- a/src/game.h +++ b/src/game.h @@ -72,7 +72,7 @@ void AusgangstuerBlinken(int, int); void EdelsteinFunkeln(int, int); void MauerWaechst(int, int); void MauerAbleger(int, int); -void GameActions(void); +void GameActions(int); void ScrollLevel(int, int); BOOL MoveFigureOneStep(int, int, int, int); BOOL MoveFigure(int, int); diff --git a/src/init.c b/src/init.c index 9092f382..c6cd0da3 100644 --- a/src/init.c +++ b/src/init.c @@ -80,7 +80,7 @@ void OpenAll(int argc, char *argv[]) void InitLevelAndPlayerInfo() { - local_player = &stored_player[0]; + player = local_player = &stored_player[0]; if (!LoadLevelInfo()) /* global level info */ CloseAll(); @@ -1203,6 +1203,16 @@ void InitElementProperties() }; static int ep_pushable_num = sizeof(ep_pushable)/sizeof(int); + static int ep_player[] = + { + EL_SPIELFIGUR, + EL_SPIELER1, + EL_SPIELER2, + EL_SPIELER3, + EL_SPIELER4 + }; + static int ep_player_num = sizeof(ep_player)/sizeof(int); + static long ep_bit[] = { EP_BIT_AMOEBALIVE, @@ -1228,7 +1238,8 @@ void InitElementProperties() EP_BIT_INACTIVE, EP_BIT_EXPLOSIVE, EP_BIT_MAMPF3, - EP_BIT_PUSHABLE + EP_BIT_PUSHABLE, + EP_BIT_PLAYER }; static int *ep_array[] = { @@ -1255,7 +1266,8 @@ void InitElementProperties() ep_inactive, ep_explosive, ep_mampf3, - ep_pushable + ep_pushable, + ep_player }; static int *ep_num[] = { @@ -1282,7 +1294,8 @@ void InitElementProperties() &ep_inactive_num, &ep_explosive_num, &ep_mampf3_num, - &ep_pushable_num + &ep_pushable_num, + &ep_player_num }; static int num_properties = sizeof(ep_num)/sizeof(int *); diff --git a/src/main.c b/src/main.c index b52761b3..2a8af5d0 100644 --- a/src/main.c +++ b/src/main.c @@ -77,6 +77,7 @@ int MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; int MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; int Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; int Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; +int StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; int Frame[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; int Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; int JustHit[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; @@ -91,8 +92,6 @@ int FX = SX, FY = SY, ScreenMovPos = 0, ScrollStepSize = TILEX/8; int GameFrameDelay = GAME_FRAME_DELAY, MoveSpeed = 8; int BX1 = 0, BY1 = 0, BX2 = SCR_FIELDX-1, BY2 = SCR_FIELDY-1; int JX,JY, lastJX,lastJY, ZX,ZY, ExitX,ExitY; -int PlayerMovDir, PlayerMovPos, PlayerPushing; -int PlayerFrame, PlayerGfxPos; int PlayerGone, LevelSolved, GameOver; int FrameCounter, TimeFrames, TimeLeft; int MampferNr, SiebAktiv; @@ -100,7 +99,7 @@ int MampferNr, SiebAktiv; struct LevelDirInfo leveldir[MAX_LEVDIR_ENTRIES]; struct LevelInfo level; struct PlayerInfo stored_player[MAX_PLAYERS+1]; -struct PlayerInfo *local_player, *actual_player; +struct PlayerInfo *local_player, *player; struct HiScore highscore[MAX_SCORE_ENTRIES]; struct SoundInfo Sound[NUM_SOUNDS]; struct RecordingInfo tape; diff --git a/src/main.h b/src/main.h index 928489ab..ae4d2807 100644 --- a/src/main.h +++ b/src/main.h @@ -31,7 +31,7 @@ #endif #else #include "msdos.h" -#endif // von #ifndef MSDOS +#endif /* #ifndef MSDOS */ #include #include @@ -53,16 +53,16 @@ typedef int BOOL; #define WIN_XPOS 0 #define WIN_YPOS 0 #else -#define WIN_XPOS (XRES-WIN_XSIZE)/2 -#define WIN_YPOS (YRES-WIN_YSIZE)/2 +#define WIN_XPOS ((XRES - WIN_XSIZE) / 2) +#define WIN_YPOS ((YRES - WIN_YSIZE) / 2) #endif #define SCR_FIELDX 17 #define SCR_FIELDY 17 #define MAX_BUF_XSIZE (SCR_FIELDX + 2) #define MAX_BUF_YSIZE (SCR_FIELDY + 2) -#define MIN_LEV_FIELDX (SCR_FIELDX-2) -#define MIN_LEV_FIELDY (SCR_FIELDY-2) +#define MIN_LEV_FIELDX (SCR_FIELDX - 2) +#define MIN_LEV_FIELDY (SCR_FIELDY - 2) #define STD_LEV_FIELDX 64 #define STD_LEV_FIELDY 32 #define MAX_LEV_FIELDX 128 @@ -71,36 +71,24 @@ typedef int BOOL; #define MAX_PLAYERS 4 #ifndef MIN -#define MIN(a,b) ((a)<(b) ? (a) : (b)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif #ifndef MAX -#define MAX(a,b) ((a)>(b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif #ifndef ABS -#define ABS(a) ((a)<0 ? -(a) : (a)) +#define ABS(a) ((a) < 0 ? -(a) : (a)) #endif #ifndef SIGN -#define SIGN(a) ((a)<0 ? -1 : ((a)>0 ? 1 : 0)) +#define SIGN(a) ((a) < 0 ? -1 : ((a)>0 ? 1 : 0)) #endif -#define SCROLLX(a) ((a)-scroll_x) -#define SCROLLY(a) ((a)-scroll_y) -#define UNSCROLLX(a) ((a)+scroll_x) -#define UNSCROLLY(a) ((a)+scroll_y) +#define SCROLLX(a) ((a) - scroll_x) +#define SCROLLY(a) ((a) - scroll_y) +#define UNSCROLLX(a) ((a) + scroll_x) +#define UNSCROLLY(a) ((a) + scroll_y) #define IN_SCR_FIELD(x,y) ((x)>=BX1 && (x)<=BX2 && (y)>=BY1 &&(y)<=BY2) #define IN_LEV_FIELD(x,y) ((x)>=0 && (x)=0 &&(y)=EL_BLOCKED) -#define TIMESIZE (TimeLeft*100/level.time) +#define IS_DRAWABLE(e) ((e) < EL_BLOCKED) +#define IS_NOT_DRAWABLE(e) ((e) >= EL_BLOCKED) +#define TIMESIZE (TimeLeft * 100 / level.time) #define TAPE_IS_EMPTY(x) ((x).length == 0) #define TAPE_IS_STOPPED(x) (!(x).recording && !(x).playing &&!(x).pausing) @@ -207,7 +210,7 @@ struct HiScore struct PlayerInfo { - BOOL active, local; + int nr, active, local; char login_name[MAX_NAMELEN]; char alias_name[MAX_NAMELEN]; @@ -217,10 +220,19 @@ struct PlayerInfo int level_nr; int JX,JY, lastJX,lastJY, ZX,ZY, ExitX,ExitY; - int PlayerMovDir, PlayerMovPos, PlayerPushing; - int PlayerFrame, PlayerGfxPos; + int MovDir, MovPos, Pushing; + int Frame, GfxPos; + int PlayerGone, LevelSolved, GameOver; + int frame_reset_delay; + + long move_delay; + int last_move_dir; + + long push_delay; + int push_delay_value; + int score; int gems_still_needed; int sokobanfields_still_needed; @@ -333,6 +345,7 @@ extern int MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern int MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern int Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern int Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; +extern int StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern int Frame[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern int Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern int JustHit[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; @@ -347,8 +360,6 @@ extern int FX,FY, ScreenMovPos, ScrollStepSize; extern int GameFrameDelay, MoveSpeed; extern int BX1,BY1, BX2,BY2; extern int JX,JY, lastJX,lastJY, ZX,ZY, ExitX,ExitY; -extern int PlayerMovDir, PlayerMovPos, PlayerPushing; -extern int PlayerFrame, PlayerGfxPos; extern int PlayerGone,LevelSolved,GameOver; extern int FrameCounter,TimeFrames,TimeLeft; extern int MampferNr, SiebAktiv; @@ -356,7 +367,7 @@ extern int MampferNr, SiebAktiv; extern struct LevelDirInfo leveldir[]; extern struct LevelInfo level; extern struct PlayerInfo stored_player[]; -extern struct PlayerInfo *local_player, *actual_player; +extern struct PlayerInfo *local_player, *player; extern struct HiScore highscore[]; extern struct RecordingInfo tape; extern struct SoundInfo Sound[]; diff --git a/src/screens.c b/src/screens.c index 9f0ec9f9..aca0be51 100644 --- a/src/screens.c +++ b/src/screens.c @@ -1299,7 +1299,7 @@ void CalibrateJoystick() DrawSetupScreen(); } -void HandleGameActions() +void HandleGameActions(int player_action) { if (game_status != PLAYING) return; @@ -1310,7 +1310,7 @@ void HandleGameActions() if (PlayerGone && !TAPE_IS_STOPPED(tape)) TapeStop(); - GameActions(); + GameActions(player_action); BackToFront(); } diff --git a/src/screens.h b/src/screens.h index a21dd598..abe2f198 100644 --- a/src/screens.h +++ b/src/screens.h @@ -38,7 +38,7 @@ void HandleHallOfFame(int); void DrawSetupScreen(void); void HandleSetupScreen(int, int, int, int, int); void CalibrateJoystick(void); -void HandleGameActions(void); +void HandleGameActions(int); void HandleVideoButtons(int, int, int); void HandleSoundButtons(int, int, int); void HandleGameButtons(int, int, int); diff --git a/src/tools.c b/src/tools.c index 08c6dc68..f742f69e 100644 --- a/src/tools.c +++ b/src/tools.c @@ -109,8 +109,8 @@ void BackToFront() if (soft_scrolling_on) { - fx += (PlayerMovDir & (MV_LEFT|MV_RIGHT) ? ScreenMovPos : 0); - fy += (PlayerMovDir & (MV_UP|MV_DOWN) ? ScreenMovPos : 0); + fx += (local_player->MovDir & (MV_LEFT|MV_RIGHT) ? ScreenMovPos : 0); + fy += (local_player->MovDir & (MV_UP|MV_DOWN) ? ScreenMovPos : 0); } XCopyArea(display,buffer,window,gc, @@ -330,16 +330,17 @@ void DrawTextExt(Drawable d, GC gc, int x, int y, } } -void DrawPlayerField() +void DrawPlayerField(int x, int y) { - int x = JX, y = JY; + int lastJX = player->lastJX, lastJY = player->lastJY; int sx = SCROLLX(x), sy = SCROLLY(y); - int sxx = 0, syy = 0; - int element = Feld[x][y]; int graphic, phase; + if (!IS_PLAYER(x,y)) + return; + if (PlayerGone) return; @@ -373,12 +374,12 @@ void DrawPlayerField() else DrawLevelField(lastJX,lastJY); - if (PlayerPushing) + if (player->Pushing) { int nextJX = JX + (JX - lastJX); int nextJY = JY + (JY - lastJY); - if (PlayerGfxPos) + if (player->GfxPos) { if (Feld[nextJX][nextJY] == EL_SOKOBAN_FELD_VOLL) DrawLevelElement(nextJX,nextJY, EL_SOKOBAN_FELD_LEER); @@ -399,23 +400,23 @@ void DrawPlayerField() /* draw player himself */ - if (PlayerMovDir==MV_LEFT) - graphic = (PlayerPushing ? GFX_SPIELER_PUSH_LEFT : GFX_SPIELER_LEFT); - else if (PlayerMovDir==MV_RIGHT) - graphic = (PlayerPushing ? GFX_SPIELER_PUSH_RIGHT : GFX_SPIELER_RIGHT); - else if (PlayerMovDir==MV_UP) + if (player->MovDir==MV_LEFT) + graphic = (player->Pushing ? GFX_SPIELER_PUSH_LEFT : GFX_SPIELER_LEFT); + else if (player->MovDir==MV_RIGHT) + graphic = (player->Pushing ? GFX_SPIELER_PUSH_RIGHT : GFX_SPIELER_RIGHT); + else if (player->MovDir==MV_UP) graphic = GFX_SPIELER_UP; else /* MV_DOWN || MV_NO_MOVING */ graphic = GFX_SPIELER_DOWN; - graphic += PlayerFrame; + graphic += player->Frame; - if (PlayerGfxPos) + if (player->GfxPos) { - if (PlayerMovDir == MV_LEFT || PlayerMovDir == MV_RIGHT) - sxx = PlayerGfxPos; + if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT) + sxx = player->GfxPos; else - syy = PlayerGfxPos; + syy = player->GfxPos; } if (!soft_scrolling_on && ScreenMovPos) @@ -423,7 +424,7 @@ void DrawPlayerField() DrawGraphicShiftedThruMask(sx,sy, sxx,syy, graphic, NO_CUTTING); - if (PlayerPushing && PlayerGfxPos) + if (player->Pushing && player->GfxPos) { int nextJX = JX + (JX - lastJX); int nextJY = JY + (JY - lastJY); @@ -439,9 +440,9 @@ void DrawPlayerField() if (element == EL_FELSBROCKEN && sxx) { - int phase = (PlayerGfxPos / (TILEX/4)); + int phase = (player->GfxPos / (TILEX/4)); - if (PlayerMovDir == MV_LEFT) + if (player->MovDir == MV_LEFT) graphic += phase; else graphic += (phase+4)%4; diff --git a/src/tools.h b/src/tools.h index 4b7edaf1..47239c90 100644 --- a/src/tools.h +++ b/src/tools.h @@ -63,7 +63,7 @@ void FadeToFront(); void ClearWindow(); void DrawText(int, int, char *, int, int); void DrawTextExt(Drawable, GC, int, int, char *, int, int); -void DrawPlayerField(void); +void DrawPlayerField(int, int); void DrawGraphicAnimationExt(int, int, int, int, int, int, int); void DrawGraphicAnimation(int, int, int, int, int, int); void DrawGraphicAnimationThruMask(int, int, int, int, int, int); -- 2.34.1