X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=7e678bfbd4f063ea04e37486abb4c7143f408f2d;hb=e7f36cd97c8580345714b4a22d6b4ad291e50ed6;hp=3392e0ec441dc340dd7079932825f91896d253e1;hpb=823bddb0d9cc63ddda17a2cd20266aa3b82bde38;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 3392e0ec..7e678bfb 100644 --- a/src/game.c +++ b/src/game.c @@ -21,6 +21,7 @@ #include "files.h" #include "tape.h" #include "joystick.h" +#include "network.h" void GetPlayerConfig() { @@ -62,13 +63,22 @@ void InitGame() BOOL emulate_bd = TRUE; /* unless non-BOULDERDASH elements found */ BOOL emulate_sb = TRUE; /* unless non-SOKOBAN elements found */ + /* don't play tapes over network */ + network_playing = (network && !tape.playing); + for(i=0; inr = i; + player->index_nr = i; + player->element_nr = EL_SPIELER1 + i; + + player->present = FALSE; player->active = FALSE; + + /* player->local = FALSE; + */ player->score = 0; player->gems_still_needed = level.edelsteine; @@ -124,8 +134,16 @@ void InitGame() player->GameOver = FALSE; } + /* local_player->active = TRUE; local_player->local = TRUE; + */ + + network_player_action_received = FALSE; + + /* initial null action */ + if (network_playing) + SendToServer_MovePlayer(MV_NO_MOVING); ZX = ZY = -1; @@ -170,16 +188,30 @@ void InitGame() struct PlayerInfo *player = &stored_player[Feld[x][y] - EL_SPIELER1]; int jx = player->jx, jy = player->jy; - /* remove duplicate players */ + /* + player->active = TRUE; + */ + + player->present = TRUE; + if (player->connected) + { + player->active = TRUE; + + printf("Player %d activated.\n", player->element_nr); + printf("[Local player is %d and currently %s.]\n", + local_player->element_nr, + local_player->active ? "active" : "not active"); + } + + /* remove potentially duplicate players */ if (StorePlayer[jx][jy] == Feld[x][y]) StorePlayer[jx][jy] = 0; - player->active = TRUE; - StorePlayer[x][y] = Feld[x][y]; Feld[x][y] = EL_LEERRAUM; player->jx = player->last_jx = x; player->jy = player->last_jy = y; + break; } case EL_BADEWANNE: @@ -257,6 +289,52 @@ void InitGame() } } + /* check if any connected player was not found in playfield */ + for(i=0; iconnected && !player->present) + { + printf("Oops!\n"); + + + for(j=0; jjx, jy = some_player->jy; + + /* assign first free player found that is present in the playfield */ + if (some_player->present && !some_player->connected) + { + player->present = TRUE; + player->active = TRUE; + some_player->present = FALSE; + + StorePlayer[jx][jy] = player->element_nr; + player->jx = player->last_jx = jx; + player->jy = player->last_jy = jy; + + break; + } + } + } + } + + for(i=0; ipresent, + player->connected, + player->active); + if (local_player == player) + printf("Player %d is local player.\n", i+1); + } + + game_emulation = (emulate_bd ? EMU_BOULDERDASH : emulate_sb ? EMU_SOKOBAN : EMU_NONE); @@ -313,6 +391,12 @@ void InitGame() PlaySoundLoop(background_loop[level_nr % num_bg_loops]); XAutoRepeatOff(display); + + + for (i=0;i<4;i++) + printf("Spieler %d %saktiv.\n", + i+1, (stored_player[i].active ? "" : "nicht ")); + } void InitMovDir(int x, int y) @@ -989,6 +1073,9 @@ void Impact(int x, int y) /* Element darunter berührt? */ if (!lastline) { + if (Feld[x][y+1] == EL_PLAYER_IS_LEAVING) + return; + object_hit = (!IS_FREE(x,y+1) && (!IS_MOVING(x,y+1) || MovDir[x][y+1]!=MV_DOWN || MovPos[x][y+1]<=TILEY/2)); @@ -2589,23 +2676,37 @@ void MauerWaechst(int x, int y) phase = 2-MovDelay[x][y]/delay; if (!(MovDelay[x][y]%delay) && IN_SCR_FIELD(SCREENX(x),SCREENY(y))) DrawGraphic(SCREENX(x),SCREENY(y), - (Store[x][y]==MV_LEFT ? GFX_MAUER_L1 : GFX_MAUER_R1)+phase); + (MovDir[x][y] == MV_LEFT ? GFX_MAUER_LEFT : + MovDir[x][y] == MV_RIGHT ? GFX_MAUER_RIGHT : + MovDir[x][y] == MV_UP ? GFX_MAUER_UP : + GFX_MAUER_DOWN ) + phase); if (!MovDelay[x][y]) { - if (Store[x][y]==MV_LEFT) + if (MovDir[x][y] == MV_LEFT) { if (IN_LEV_FIELD(x-1,y) && IS_MAUER(Feld[x-1][y])) DrawLevelField(x-1,y); } - else + else if (MovDir[x][y] == MV_RIGHT) { if (IN_LEV_FIELD(x+1,y) && IS_MAUER(Feld[x+1][y])) DrawLevelField(x+1,y); } + else if (MovDir[x][y] == MV_UP) + { + if (IN_LEV_FIELD(x,y-1) && IS_MAUER(Feld[x][y-1])) + DrawLevelField(x,y-1); + } + else + { + if (IN_LEV_FIELD(x,y+1) && IS_MAUER(Feld[x][y+1])) + DrawLevelField(x,y+1); + } - Feld[x][y] = EL_MAUER_LEBT; + Feld[x][y] = Store[x][y]; Store[x][y] = 0; + MovDir[x][y] = MV_NO_MOVING; DrawLevelField(x,y); } } @@ -2613,7 +2714,10 @@ void MauerWaechst(int x, int y) void MauerAbleger(int ax, int ay) { + int element = Feld[ax][ay]; + BOOL oben_frei = FALSE, unten_frei = FALSE; BOOL links_frei = FALSE, rechts_frei = FALSE; + BOOL oben_massiv = FALSE, unten_massiv = FALSE; BOOL links_massiv = FALSE, rechts_massiv = FALSE; if (!MovDelay[ax][ay]) /* neue Mauer / noch nicht gewartet */ @@ -2626,35 +2730,72 @@ void MauerAbleger(int ax, int ay) return; } + if (IN_LEV_FIELD(ax,ay-1) && IS_FREE(ax,ay-1)) + oben_frei = TRUE; + if (IN_LEV_FIELD(ax,ay+1) && IS_FREE(ax,ay+1)) + unten_frei = TRUE; if (IN_LEV_FIELD(ax-1,ay) && IS_FREE(ax-1,ay)) links_frei = TRUE; if (IN_LEV_FIELD(ax+1,ay) && IS_FREE(ax+1,ay)) rechts_frei = TRUE; - if (links_frei) + if (element == EL_MAUER_Y || element == EL_MAUER_XY) { - Feld[ax-1][ay] = EL_MAUERND; - Store[ax-1][ay] = MV_LEFT; - if (IN_SCR_FIELD(SCREENX(ax-1),SCREENY(ay))) - DrawGraphic(SCREENX(ax-1),SCREENY(ay),GFX_MAUER_L1); + if (oben_frei) + { + Feld[ax][ay-1] = EL_MAUERND; + Store[ax][ay-1] = element; + MovDir[ax][ay-1] = MV_UP; + if (IN_SCR_FIELD(SCREENX(ax),SCREENY(ay-1))) + DrawGraphic(SCREENX(ax),SCREENY(ay-1),GFX_MAUER_UP); + } + if (unten_frei) + { + Feld[ax][ay+1] = EL_MAUERND; + Store[ax][ay+1] = element; + MovDir[ax][ay+1] = MV_DOWN; + if (IN_SCR_FIELD(SCREENX(ax),SCREENY(ay+1))) + DrawGraphic(SCREENX(ax),SCREENY(ay+1),GFX_MAUER_DOWN); + } } - if (rechts_frei) + + if (element == EL_MAUER_X || element == EL_MAUER_XY || + element == EL_MAUER_LEBT) { - Feld[ax+1][ay] = EL_MAUERND; - Store[ax+1][ay] = MV_RIGHT; - if (IN_SCR_FIELD(SCREENX(ax+1),SCREENY(ay))) - DrawGraphic(SCREENX(ax+1),SCREENY(ay),GFX_MAUER_R1); + if (links_frei) + { + Feld[ax-1][ay] = EL_MAUERND; + Store[ax-1][ay] = element; + MovDir[ax-1][ay] = MV_LEFT; + if (IN_SCR_FIELD(SCREENX(ax-1),SCREENY(ay))) + DrawGraphic(SCREENX(ax-1),SCREENY(ay),GFX_MAUER_LEFT); + } + if (rechts_frei) + { + Feld[ax+1][ay] = EL_MAUERND; + Store[ax+1][ay] = element; + MovDir[ax+1][ay] = MV_RIGHT; + if (IN_SCR_FIELD(SCREENX(ax+1),SCREENY(ay))) + DrawGraphic(SCREENX(ax+1),SCREENY(ay),GFX_MAUER_RIGHT); + } } - if (links_frei || rechts_frei) + if (element == EL_MAUER_LEBT && (links_frei || rechts_frei)) DrawLevelField(ax,ay); + if (!IN_LEV_FIELD(ax,ay-1) || IS_MAUER(Feld[ax][ay-1])) + oben_massiv = TRUE; + if (!IN_LEV_FIELD(ax,ay+1) || IS_MAUER(Feld[ax][ay+1])) + unten_massiv = TRUE; if (!IN_LEV_FIELD(ax-1,ay) || IS_MAUER(Feld[ax-1][ay])) links_massiv = TRUE; if (!IN_LEV_FIELD(ax+1,ay) || IS_MAUER(Feld[ax+1][ay])) rechts_massiv = TRUE; - if (links_massiv && rechts_massiv) + if (((oben_massiv && unten_massiv) || + element == EL_MAUER_X || element == EL_MAUER_LEBT) && + ((links_massiv && rechts_massiv) || + element == EL_MAUER_Y)) Feld[ax][ay] = EL_MAUERWERK; } @@ -2707,9 +2848,9 @@ void CheckForDragon(int x, int y) } } -void PlayerActions(struct PlayerInfo *player, int player_action) +void PlayerActions(struct PlayerInfo *player, byte player_action) { - static int stored_player_action[MAX_PLAYERS]; + static byte stored_player_action[MAX_PLAYERS]; static int num_stored_actions = 0; BOOL moved = FALSE, snapped = FALSE, bombed = FALSE; int jx = player->jx, jy = player->jy; @@ -2722,7 +2863,7 @@ void PlayerActions(struct PlayerInfo *player, int player_action) int dx = (left ? -1 : right ? 1 : 0); int dy = (up ? -1 : down ? 1 : 0); - stored_player_action[player->nr] = 0; + stored_player_action[player->index_nr] = 0; num_stored_actions++; if (!player->active || player->gone) @@ -2746,7 +2887,7 @@ void PlayerActions(struct PlayerInfo *player, int player_action) if (bombed && !moved) player_action &= JOY_BUTTON; - stored_player_action[player->nr] = player_action; + stored_player_action[player->index_nr] = player_action; /* this allows cycled sequences of PlayerActions() */ if (num_stored_actions >= MAX_PLAYERS) @@ -2770,7 +2911,7 @@ void PlayerActions(struct PlayerInfo *player, int player_action) tape.counter < tape.length) { int next_joy = - tape.pos[tape.counter].joystickdata[player->nr] & (JOY_LEFT|JOY_RIGHT); + tape.pos[tape.counter].action[player->index_nr] & (JOY_LEFT|JOY_RIGHT); if (next_joy == JOY_LEFT || next_joy == JOY_RIGHT) { @@ -2792,7 +2933,7 @@ void PlayerActions(struct PlayerInfo *player, int player_action) } } -void GameActions(int player_action) +void GameActions(byte player_action) { static long action_delay = 0; long action_delay_value; @@ -2814,18 +2955,73 @@ void GameActions(int player_action) /* main game synchronization point */ WaitUntilDelayReached(&action_delay, action_delay_value); + if (network_playing && !network_player_action_received) + { + /* +#ifdef DEBUG + printf("DEBUG: try to get network player actions in time\n"); +#endif + */ + + /* last chance to get network player actions without main loop delay */ + HandleNetworking(); + + if (game_status != PLAYING) + return; + + if (!network_player_action_received) + { + /* +#ifdef DEBUG + printf("DEBUG: failed to get network player actions in time\n"); +#endif + */ + return; + } + } + + + if (tape.pausing || (tape.playing && !TapePlayDelay())) + return; + else if (tape.recording) + TapeRecordDelay(); + + if (tape.playing) recorded_player_action = TapePlayAction(); else recorded_player_action = NULL; + if (network_playing) + SendToServer_MovePlayer(player_action); + for(i=0; ilast_jy = jy; jx = player->jx = new_jx; jy = player->jy = new_jy; - StorePlayer[jx][jy] = EL_SPIELER1 + player->nr; + StorePlayer[jx][jy] = player->element_nr; player->MovPos = (dx > 0 || dy > 0 ? -1 : 1) * 7*TILEX/8; @@ -3152,11 +3363,19 @@ BOOL MoveFigure(struct PlayerInfo *player, int dx, int dy) if (moved & MF_MOVING && player == local_player) */ - if (moved & MF_MOVING && !ScreenMovPos) + if (moved & MF_MOVING && !ScreenMovPos && + (player == local_player || !network)) { int old_scroll_x = scroll_x, old_scroll_y = scroll_y; int offset = (scroll_delay_on ? 3 : 0); + /* + if (player == local_player) + { + printf("MOVING LOCAL PLAYER && SCROLLING\n"); + } + */ + if (!IN_VIS_FIELD(SCREENX(jx),SCREENY(jy))) { /* actual player has left the screen -- scroll in that direction */ @@ -3215,22 +3434,15 @@ BOOL MoveFigure(struct PlayerInfo *player, int dx, int dy) if (scroll_x != old_scroll_x || scroll_y != old_scroll_y) { - if (networking || AllPlayersInVisibleScreen()) + if (!network && !AllPlayersInVisibleScreen()) { - ScrollScreen(player, SCROLL_INIT); - - /* - ScreenMovDir = player->MovDir; - ScreenMovPos = player->MovPos; - ScreenGfxPos = ScrollStepSize * (ScreenMovPos / ScrollStepSize); - */ - - ScrollLevel(old_scroll_x - scroll_x, old_scroll_y - scroll_y); + scroll_x = old_scroll_x; + scroll_y = old_scroll_y; } else { - scroll_x = old_scroll_x; - scroll_y = old_scroll_y; + ScrollScreen(player, SCROLL_INIT); + ScrollLevel(old_scroll_x - scroll_x, old_scroll_y - scroll_y); } } } @@ -3275,10 +3487,6 @@ void ScrollFigure(struct PlayerInfo *player, int mode) player->actual_frame_counter = FrameCounter; player->GfxPos = ScrollStepSize * (player->MovPos / ScrollStepSize); - /* - ScreenGfxPos = local_player->GfxPos; - */ - if (Feld[last_jx][last_jy] == EL_LEERRAUM) Feld[last_jx][last_jy] = EL_PLAYER_IS_LEAVING; @@ -3291,22 +3499,6 @@ void ScrollFigure(struct PlayerInfo *player, int mode) player->MovPos += (player->MovPos > 0 ? -1 : 1) * TILEX/8; player->GfxPos = ScrollStepSize * (player->MovPos / ScrollStepSize); - /* - if (ScreenMovPos) - { - ScreenMovPos += (ScreenMovPos > 0 ? -1 : 1) * TILEX/8; - ScreenGfxPos = ScrollStepSize * (ScreenMovPos / ScrollStepSize); - } - */ - - /* - if (ScreenGfxPos && ScreenGfxPos != local_player->GfxPos) - { - ScreenGfxPos = local_player->GfxPos; - redraw_mask |= REDRAW_FIELD; - } - */ - if (Feld[last_jx][last_jy] == EL_PLAYER_IS_LEAVING) Feld[last_jx][last_jy] = EL_LEERRAUM; @@ -3344,12 +3536,6 @@ void ScrollScreen(struct PlayerInfo *player, int mode) if (ScreenMovPos) { - /* - printf("ScreenMovDir = %d, ", ScreenMovDir); - printf("ScreenMovPos = %d, ", ScreenMovPos); - printf("ScreenGfxPos = %d\n", ScreenGfxPos); - */ - ScreenMovPos += (ScreenMovPos > 0 ? -1 : 1) * TILEX/8; ScreenGfxPos = ScrollStepSize * (ScreenMovPos / ScrollStepSize); redraw_mask |= REDRAW_FIELD; @@ -3918,15 +4104,17 @@ BOOL PlaceBomb(struct PlayerInfo *player) player->dynamite--; DrawText(DX_DYNAMITE, DY_DYNAMITE, int2str(local_player->dynamite, 3), FS_SMALL, FC_YELLOW); - DrawGraphicThruMask(SCREENX(jx),SCREENY(jy),GFX_DYNAMIT); + if (IN_SCR_FIELD(SCREENX(jx),SCREENY(jy))) + DrawGraphicThruMask(SCREENX(jx),SCREENY(jy),GFX_DYNAMIT); } else { Feld[jx][jy] = EL_DYNABOMB; - Store2[jx][jy] = EL_SPIELER1 + player->nr; /* for DynaExplode() */ + Store2[jx][jy] = player->element_nr; /* for DynaExplode() */ MovDelay[jx][jy] = 96; player->dynabombs_left--; - DrawGraphicThruMask(SCREENX(jx),SCREENY(jy),GFX_DYNABOMB); + if (IN_SCR_FIELD(SCREENX(jx),SCREENY(jy))) + DrawGraphicThruMask(SCREENX(jx),SCREENY(jy),GFX_DYNABOMB); } return(TRUE);