X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=fd58165902daf1fb29f4b49747943b541fb28d9b;hb=5e8d9d0308f76bb35e7578a8859d6f01977d0f69;hp=2ed2996640d37d969c134f6d6975ecb351eddf72;hpb=19e3dfa321d39a822bda8fa489fb76f25f9f9165;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 2ed29966..fd581659 100644 --- a/src/game.c +++ b/src/game.c @@ -23,74 +23,111 @@ #include "tape.h" #include "joystick.h" - - -int tst = 0; -int tst2 = 0; - - - -extern int GameSpeed; -extern int MoveSpeed; - void GetPlayerConfig() { int old_joystick_nr = joystick_nr; if (sound_status==SOUND_OFF) - player.setup &= ~SETUP_SOUND; + local_player->setup &= ~SETUP_SOUND; if (!sound_loops_allowed) { - player.setup &= ~SETUP_SOUND_LOOPS; - player.setup &= ~SETUP_SOUND_MUSIC; + local_player->setup &= ~SETUP_SOUND_LOOPS; + local_player->setup &= ~SETUP_SOUND_MUSIC; } - sound_on = sound_simple_on = SETUP_SOUND_ON(player.setup); - sound_loops_on = SETUP_SOUND_LOOPS_ON(player.setup); - sound_music_on = SETUP_SOUND_MUSIC_ON(player.setup); - toons_on = SETUP_TOONS_ON(player.setup); - direct_draw_on = SETUP_DIRECT_DRAW_ON(player.setup); - fading_on = SETUP_FADING_ON(player.setup); - autorecord_on = SETUP_AUTO_RECORD_ON(player.setup); - joystick_nr = SETUP_2ND_JOYSTICK_ON(player.setup); - quick_doors = SETUP_QUICK_DOORS_ON(player.setup); - scroll_delay_on = SETUP_SCROLL_DELAY_ON(player.setup); - soft_scrolling_on = SETUP_SOFT_SCROLL_ON(player.setup); + sound_on = sound_simple_on = SETUP_SOUND_ON(local_player->setup); + sound_loops_on = SETUP_SOUND_LOOPS_ON(local_player->setup); + sound_music_on = SETUP_SOUND_MUSIC_ON(local_player->setup); + toons_on = SETUP_TOONS_ON(local_player->setup); + direct_draw_on = SETUP_DIRECT_DRAW_ON(local_player->setup); + fading_on = SETUP_FADING_ON(local_player->setup); + autorecord_on = SETUP_AUTO_RECORD_ON(local_player->setup); + joystick_nr = SETUP_2ND_JOYSTICK_ON(local_player->setup); + quick_doors = SETUP_QUICK_DOORS_ON(local_player->setup); + scroll_delay_on = SETUP_SCROLL_DELAY_ON(local_player->setup); + soft_scrolling_on = SETUP_SOFT_SCROLL_ON(local_player->setup); +#ifndef MSDOS if (joystick_nr != old_joystick_nr) { if (joystick_device) close(joystick_device); InitJoystick(); } +#endif } 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 */ - Dynamite = Score = 0; - Gems = level.edelsteine; - SokobanFields = Lights = Friends = 0; - DynaBombCount = DynaBombSize = DynaBombsLeft = 0; - DynaBombXL = FALSE; - Key[0] = Key[1] = Key[2] = Key[3] = FALSE; + for(i=0; inr = 1; + local_player->active = TRUE; + local_player->local = TRUE; + + player = local_player; + + 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++) + player->key[i] = 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 (xlights_still_needed++; break; case EL_SOKOBAN_FELD_LEER: - SokobanFields++; + local_player->sokobanfields_still_needed++; break; case EL_MAULWURF: case EL_PINGUIN: - Friends++; + local_player->friends_still_needed++; break; case EL_SCHWEIN: case EL_DRACHE: @@ -220,13 +275,13 @@ void InitGame() int2str(level_nr,2),FS_SMALL,FC_YELLOW); DrawTextExt(pix[PIX_DB_DOOR],gc, DOOR_GFX_PAGEX1+XX_EMERALDS,DOOR_GFX_PAGEY1+YY_EMERALDS, - int2str(Gems,3),FS_SMALL,FC_YELLOW); + int2str(local_player->gems_still_needed,3),FS_SMALL,FC_YELLOW); DrawTextExt(pix[PIX_DB_DOOR],gc, DOOR_GFX_PAGEX1+XX_DYNAMITE,DOOR_GFX_PAGEY1+YY_DYNAMITE, - int2str(Dynamite,3),FS_SMALL,FC_YELLOW); + int2str(local_player->dynamite,3),FS_SMALL,FC_YELLOW); DrawTextExt(pix[PIX_DB_DOOR],gc, DOOR_GFX_PAGEX1+XX_SCORE,DOOR_GFX_PAGEY1+YY_SCORE, - int2str(Score,5),FS_SMALL,FC_YELLOW); + int2str(local_player->score,5),FS_SMALL,FC_YELLOW); DrawTextExt(pix[PIX_DB_DOOR],gc, DOOR_GFX_PAGEX1+XX_TIME,DOOR_GFX_PAGEY1+YY_TIME, int2str(TimeLeft,3),FS_SMALL,FC_YELLOW); @@ -369,21 +424,21 @@ void GameWon() if (TimeLeft) { if (sound_loops_on) - PlaySoundExt(SND_SIRR,PSND_MAX_VOLUME,PSND_MAX_RIGHT,PSND_LOOP); + PlaySoundExt(SND_SIRR, PSND_MAX_VOLUME, PSND_MAX_RIGHT, PSND_LOOP); - while(TimeLeft>0) + while(TimeLeft > 0) { if (!sound_loops_on) - PlaySoundStereo(SND_SIRR,PSND_MAX_RIGHT); + PlaySoundStereo(SND_SIRR, PSND_MAX_RIGHT); if (TimeLeft && !(TimeLeft % 10)) RaiseScore(level.score[SC_ZEITBONUS]); if (TimeLeft > 100 && !(TimeLeft % 10)) TimeLeft -= 10; else TimeLeft--; - DrawText(DX_TIME,DY_TIME,int2str(TimeLeft,3),FS_SMALL,FC_YELLOW); + DrawText(DX_TIME, DY_TIME, int2str(TimeLeft,3), FS_SMALL, FC_YELLOW); BackToFront(); - Delay(10000); + Delay(10); } if (sound_loops_on) @@ -393,7 +448,7 @@ void GameWon() FadeSounds(); /* Hero disappears */ - DrawLevelElement(ExitX,ExitY,Feld[ExitX][ExitY]); + DrawLevelField(ExitX, ExitY); BackToFront(); if (tape.playing) @@ -407,15 +462,15 @@ void GameWon() SaveLevelTape(tape.level_nr); /* Ask to save tape */ } - if (level_nr==player.handicap && - level_nrhandicap && + level_nr < leveldir[leveldir_nr].levels-1) { - player.handicap++; + local_player->handicap++; bumplevel = TRUE; SavePlayerInfo(PLAYER_LEVEL); } - if ((hi_pos=NewHiScore())>=0) + if ((hi_pos=NewHiScore()) >= 0) { game_status = HALLOFFAME; DrawHallOfFame(hi_pos); @@ -440,21 +495,23 @@ BOOL NewHiScore() LoadScore(level_nr); - if (!strcmp(player.alias_name,EMPTY_ALIAS) || - Scorealias_name,EMPTY_ALIAS) || + local_player->score < highscore[MAX_SCORE_ENTRIES-1].Score) return(-1); for(k=0;khighscore[k].Score) /* Spieler kommt in Highscore-Liste */ + if (local_player->score > highscore[k].Score) { + /* Spieler kommt in Highscore-Liste */ + if (kalias_name,highscore[l].Name)) m = l; if (m==k) /* Spieler überschreibt seine alte Position */ goto put_into_list; @@ -470,14 +527,14 @@ BOOL NewHiScore() #ifdef ONE_PER_NAME put_into_list: #endif - sprintf(highscore[k].Name,player.alias_name); - highscore[k].Score = Score; + sprintf(highscore[k].Name,local_player->alias_name); + highscore[k].Score = local_player->score; position = k; break; } #ifdef ONE_PER_NAME - else if (!strcmp(player.alias_name,highscore[k].Name)) + else if (!strcmp(local_player->alias_name,highscore[k].Name)) break; /* Spieler schon mit besserer Punktzahl in der Liste */ #endif @@ -496,7 +553,7 @@ void InitMovingField(int x, int y, int direction) MovDir[x][y] = direction; MovDir[newx][newy] = direction; - if (Feld[newx][newy]==EL_LEERRAUM) + if (Feld[newx][newy] == EL_LEERRAUM) Feld[newx][newy] = EL_BLOCKED; } @@ -597,12 +654,12 @@ void DrawDynamite(int x, int y) if (Feld[x][y]==EL_DYNAMIT) { - if ((phase = (48-MovDelay[x][y])/6) > 6) + if ((phase = (96-MovDelay[x][y])/12) > 6) phase = 6; } else { - if ((phase = ((48-MovDelay[x][y])/3) % 8) > 3) + if ((phase = ((96-MovDelay[x][y])/6) % 8) > 3) phase = 7-phase; } @@ -619,12 +676,12 @@ void CheckDynamite(int x, int y) MovDelay[x][y]--; if (MovDelay[x][y]) { - if (!(MovDelay[x][y] % 6)) + if (!(MovDelay[x][y] % 12)) PlaySoundLevel(x,y,SND_ZISCH); - if (Feld[x][y]==EL_DYNAMIT && !(MovDelay[x][y] % 6)) + if (Feld[x][y]==EL_DYNAMIT && !(MovDelay[x][y] % 12)) DrawDynamite(x,y); - else if (Feld[x][y]==EL_DYNABOMB && !(MovDelay[x][y] % 3)) + else if (Feld[x][y]==EL_DYNABOMB && !(MovDelay[x][y] % 6)) DrawDynamite(x,y); return; @@ -638,7 +695,7 @@ void CheckDynamite(int x, int y) void Explode(int ex, int ey, int phase, int mode) { int x,y; - int num_phase = 9, delay = 1; + int num_phase = 9, delay = 2; int last_phase = num_phase*delay; int half_phase = (num_phase/2)*delay; @@ -800,12 +857,12 @@ void DynaExplode(int ex, int ey, int size) if (element != EL_LEERRAUM && element != EL_ERDREICH && element != EL_EXPLODING && - !DynaBombXL) + !player->dynabomb_xl) break; } } - DynaBombsLeft++; + player->dynabombs_left++; } void Bang(int x, int y) @@ -831,7 +888,7 @@ void Bang(int x, int y) case EL_DYNABOMB_NR: case EL_DYNABOMB_SZ: case EL_DYNABOMB_XL: - DynaExplode(x,y,DynaBombSize); + DynaExplode(x,y,player->dynabomb_size); break; case EL_BIRNE_AUS: case EL_BIRNE_EIN: @@ -868,13 +925,13 @@ void Blurb(int x, int y) int graphic = (element==EL_BLURB_LEFT ? GFX_BLURB_LEFT : GFX_BLURB_RIGHT); if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ - MovDelay[x][y] = 5; + MovDelay[x][y] = 9; if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ { MovDelay[x][y]--; - if (MovDelay[x][y] && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y))) - DrawGraphic(SCROLLX(x),SCROLLY(y),graphic+4-MovDelay[x][y]); + if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y))) + DrawGraphic(SCROLLX(x),SCROLLY(y),graphic+4-MovDelay[x][y]/2); if (!MovDelay[x][y]) { @@ -1093,7 +1150,7 @@ void TurnRound(int x, int y) MovDir[x][y] = left_dir; if (element==EL_KAEFER && MovDir[x][y] != old_move_dir) - MovDelay[x][y] = 5; + MovDelay[x][y] = 9; else if (element==EL_BUTTERFLY) /* && MovDir[x][y]==left_dir) */ MovDelay[x][y] = 1; } @@ -1109,7 +1166,7 @@ void TurnRound(int x, int y) MovDir[x][y] = right_dir; if (element==EL_FLIEGER && MovDir[x][y] != old_move_dir) - MovDelay[x][y] = 5; + MovDelay[x][y] = 9; else if (element==EL_FIREFLY) /* && MovDir[x][y]==right_dir) */ MovDelay[x][y] = 1; } @@ -1135,7 +1192,7 @@ void TurnRound(int x, int y) else MovDir[x][y] = back_dir; - MovDelay[x][y] = 8+8*RND(3); + MovDelay[x][y] = 16+16*RND(3); } else if (element==EL_MAMPFER2) { @@ -1159,7 +1216,7 @@ void TurnRound(int x, int y) else MovDir[x][y] = back_dir; - MovDelay[x][y] = 8+8*RND(3); + MovDelay[x][y] = 16+16*RND(3); } else if (element==EL_PACMAN) { @@ -1183,7 +1240,7 @@ void TurnRound(int x, int y) else MovDir[x][y] = back_dir; - MovDelay[x][y] = 3+RND(20); + MovDelay[x][y] = 6+RND(40); } else if (element==EL_SCHWEIN) { @@ -1346,9 +1403,9 @@ void TurnRound(int x, int y) Moving2Blocked(x,y,&newx,&newy); if (IN_LEV_FIELD(newx,newy) && IS_FREE_OR_PLAYER(newx,newy)) - MovDelay[x][y] = 4+4*!RND(3); + MovDelay[x][y] = 8+8*!RND(3); else - MovDelay[x][y] = 8; + MovDelay[x][y] = 16; } else { @@ -1399,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) @@ -1419,7 +1487,7 @@ void StartMoving(int x, int y) else if (Feld[x][y+1]==EL_MORAST_LEER) { if (!MovDelay[x][y]) - MovDelay[x][y] = 16; + MovDelay[x][y] = TILEY + 1; if (MovDelay[x][y]) { @@ -1448,7 +1516,7 @@ void StartMoving(int x, int y) else if (Feld[x][y+1]==EL_SIEB_LEER) { if (!MovDelay[x][y]) - MovDelay[x][y] = 2; + MovDelay[x][y] = TILEY/4 + 1; if (MovDelay[x][y]) { @@ -1474,7 +1542,7 @@ void StartMoving(int x, int y) else if (Feld[x][y+1]==EL_SIEB2_LEER) { if (!MovDelay[x][y]) - MovDelay[x][y] = 2; + MovDelay[x][y] = TILEY/4 + 1; if (MovDelay[x][y]) { @@ -1655,8 +1723,8 @@ void StartMoving(int x, int y) if (IN_SCR_FIELD(SCROLLX(newx),SCROLLY(newy))) DrawGraphicThruMask(SCROLLX(newx),SCROLLY(newy),el2gfx(element)); - Friends--; - if (!Friends && PlayerGone && !GameOver) + local_player->friends_still_needed--; + if (!local_player->friends_still_needed && PlayerGone && !GameOver) LevelSolved = GameOver = TRUE; return; @@ -1671,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; @@ -1692,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; @@ -1703,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; @@ -1724,11 +1792,11 @@ 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); - MovDelay[x][y] = 25; + MovDelay[x][y] = 50; Feld[newx][newy] = EL_BURNING; if (IN_LEV_FIELD(newx1,newy1) && Feld[newx1][newy1] == EL_LEERRAUM) Feld[newx1][newy1] = EL_BURNING; @@ -1787,9 +1855,28 @@ void StartMoving(int x, int y) if (element == EL_KAEFER || element == EL_FLIEGER) DrawLevelField(x,y); else if (element == EL_BUTTERFLY || element == EL_FIREFLY) - DrawGraphicAnimation(x,y, el2gfx(element), 2, 2, ANIM_NORMAL); + DrawGraphicAnimation(x,y, el2gfx(element), 2, 4, ANIM_NORMAL); else if (element==EL_SONDE) - DrawGraphicAnimation(x,y, GFX_SONDE_START, 8, 1, ANIM_NORMAL); + { + 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; } @@ -2041,9 +2128,9 @@ void AmoebeWaechst(int x, int y) if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ { - MovDelay[x][y] = 4; + MovDelay[x][y] = 7; - if (DelayReached(&sound_delay,sound_delay_value)) + if (DelayReached(&sound_delay, sound_delay_value)) { PlaySoundLevel(x,y,SND_AMOEBE); sound_delay_value = 30; @@ -2053,8 +2140,8 @@ void AmoebeWaechst(int x, int y) if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ { MovDelay[x][y]--; - if (MovDelay[x][y] && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y))) - DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_AMOEBING+3-MovDelay[x][y]); + if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y))) + DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_AMOEBING+3-MovDelay[x][y]/2); if (!MovDelay[x][y]) { @@ -2198,7 +2285,7 @@ void Life(int ax, int ay) { int x1,y1,x2,y2; static int life[4] = { 2,3,3,3 }; /* "Life"-Parameter */ - int life_time = 20; + int life_time = 40; int element = Feld[ax][ay]; if (Stop[ax][ay]) @@ -2286,7 +2373,7 @@ void Ablenk(int x, int y) void Birne(int x, int y) { if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ - MovDelay[x][y] = 400; + MovDelay[x][y] = 800; if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ { @@ -2314,19 +2401,22 @@ void Birne(int x, int y) void Blubber(int x, int y) { - DrawGraphicAnimation(x,y, GFX_GEBLUBBER, 4, 5, ANIM_NORMAL); + if (y > 0 && IS_MOVING(x,y-1) && MovDir[x][y-1] == MV_DOWN) + DrawLevelField(x,y-1); + else + DrawGraphicAnimation(x,y, GFX_GEBLUBBER, 4, 10, ANIM_NORMAL); } void NussKnacken(int x, int y) { if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ - MovDelay[x][y] = 4; + MovDelay[x][y] = 7; if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ { MovDelay[x][y]--; - if (MovDelay[x][y] && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y))) - DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_CRACKINGNUT+3-MovDelay[x][y]); + if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y))) + DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_CRACKINGNUT+3-MovDelay[x][y]/2); if (!MovDelay[x][y]) { @@ -2338,14 +2428,16 @@ void NussKnacken(int x, int y) void SiebAktivieren(int x, int y, int typ) { - if (SiebAktiv%2 && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y))) + if (!(SiebAktiv % 4) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y))) DrawGraphic(SCROLLX(x),SCROLLY(y), - (typ==1 ? GFX_SIEB_VOLL : GFX_SIEB2_VOLL)+3-(SiebAktiv%8)/2); + (typ==1 ? GFX_SIEB_VOLL : GFX_SIEB2_VOLL)+3-(SiebAktiv%16)/4); } void AusgangstuerPruefen(int x, int y) { - if (!Gems && !SokobanFields && !Lights) + if (!local_player->gems_still_needed && + !local_player->sokobanfields_still_needed && + !local_player->lights_still_needed) { Feld[x][y] = EL_AUSGANG_ACT; @@ -2358,18 +2450,18 @@ void AusgangstuerPruefen(int x, int y) void AusgangstuerOeffnen(int x, int y) { - int speed = 3; + int delay = 6; if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ - MovDelay[x][y] = 5*speed; + MovDelay[x][y] = 5*delay; if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ { int tuer; MovDelay[x][y]--; - tuer = MovDelay[x][y]/speed; - if (!(MovDelay[x][y]%speed) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y))) + tuer = MovDelay[x][y]/delay; + if (!(MovDelay[x][y]%delay) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y))) DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_AUSGANG_AUF-tuer); if (!MovDelay[x][y]) @@ -2382,7 +2474,7 @@ void AusgangstuerOeffnen(int x, int y) void AusgangstuerBlinken(int x, int y) { - DrawGraphicAnimation(x,y, GFX_AUSGANG_AUF, 4, 2, ANIM_OSCILLATE); + DrawGraphicAnimation(x,y, GFX_AUSGANG_AUF, 4, 4, ANIM_OSCILLATE); } void EdelsteinFunkeln(int x, int y) @@ -2391,18 +2483,11 @@ void EdelsteinFunkeln(int x, int y) return; if (Feld[x][y] == EL_EDELSTEIN_BD) - { - const int delay = 4; /* war: 2 */ - const int frames = 4; - int phase = (FrameCounter % (delay*frames)) / delay; - - if (!(FrameCounter % delay)) - DrawGraphic(SCROLLX(x),SCROLLY(y), GFX_EDELSTEIN_BD - phase); - } + DrawGraphicAnimation(x,y, GFX_EDELSTEIN_BD, 4, 4, ANIM_REVERSE); else { if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ - MovDelay[x][y] = 6*!SimpleRND(500); + MovDelay[x][y] = 11 * !SimpleRND(500); if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ { @@ -2416,16 +2501,27 @@ void EdelsteinFunkeln(int x, int y) if (MovDelay[x][y]) { int src_x,src_y, dest_x,dest_y; - int phase = MovDelay[x][y]-1; + int phase = (MovDelay[x][y]-1)/2; + + if (phase > 2) + phase = 4-phase; - src_x = SX+GFX_PER_LINE*TILEX; - src_y = SY+(phase > 2 ? 4-phase : phase)*TILEY; - dest_x = FX+SCROLLX(x)*TILEX; - dest_y = FY+SCROLLY(y)*TILEY; + src_x = SX + GFX_PER_LINE*TILEX; + src_y = SY + phase*TILEY; + dest_x = FX + SCROLLX(x)*TILEX; + dest_y = FY + SCROLLY(y)*TILEY; + /* XSetClipOrigin(display,clip_gc[PIX_BACK],dest_x-src_x,dest_y-src_y); XCopyArea(display,pix[PIX_BACK],drawto_field,clip_gc[PIX_BACK], src_x,src_y, TILEX,TILEY, dest_x,dest_y); + */ + + XSetClipMask(display, tile_clip_gc, + tile_clipmask[GFX_MASK_SPARKLING + phase]); + XSetClipOrigin(display, tile_clip_gc, dest_x,dest_y); + XCopyArea(display, pix[PIX_BACK], drawto_field, tile_clip_gc, + src_x,src_y, TILEX,TILEY, dest_x,dest_y); if (direct_draw_on) { @@ -2440,18 +2536,18 @@ void EdelsteinFunkeln(int x, int y) void MauerWaechst(int x, int y) { - int speed = 3; + int delay = 6; if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */ - MovDelay[x][y] = 3*speed; + MovDelay[x][y] = 3*delay; if (MovDelay[x][y]) /* neue Phase / in Wartezustand */ { int phase; MovDelay[x][y]--; - phase = 2-MovDelay[x][y]/speed; - if (!(MovDelay[x][y]%speed) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y))) + phase = 2-MovDelay[x][y]/delay; + if (!(MovDelay[x][y]%delay) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y))) DrawGraphic(SCROLLX(x),SCROLLY(y), (Store[x][y]==MV_LEFT ? GFX_MAUER_L1 : GFX_MAUER_R1)+phase); @@ -2481,7 +2577,7 @@ void MauerAbleger(int ax, int ay) BOOL links_massiv = FALSE, rechts_massiv = FALSE; if (!MovDelay[ax][ay]) /* neue Mauer / noch nicht gewartet */ - MovDelay[ax][ay] = 3; + MovDelay[ax][ay] = 6; if (MovDelay[ax][ay]) /* neue Mauer / in Wartezustand */ { @@ -2571,251 +2667,245 @@ void CheckForDragon(int x, int y) } } -void GameActions() +void PlayerActions(int player_action) { - static long action_delay = 0; - long action_delay_value; - - if (game_status != PLAYING) - return; - -/* - action_delay_value = - (tape.playing && tape.fast_forward ? FFWD_FRAME_DELAY : GAME_FRAME_DELAY); -*/ - - action_delay_value = - (tape.playing && tape.fast_forward ? FFWD_FRAME_DELAY : GameSpeed); - - /* - if (DelayReached(&action_delay, action_delay_value)) - */ - - - - if (PlayerMovPos) - ScrollFigure(0); - - DrawPlayerField(); - - - - - tst++; + 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 (0) + 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 { - static long last_Counter = 0; - long new_Counter = Counter(); - - printf("--> %ld / %ld [%d]\n", - new_Counter - last_Counter, - new_Counter, - FrameCounter); - last_Counter = new_Counter; + 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 (!DelayReached(&action_delay, action_delay_value)) - return; - */ - - - while(!DelayReached(&action_delay, action_delay_value)) - Delay(1000); - - - - - /* - printf("-----------\n"); - */ - - - - FrameCounter++; - - + if (tape.delay_played + push_delay >= tape.pos[tape.counter].delay) + { + player->MovDir = next_joy; + player->Frame = FrameCounter % 4; + player->Pushing = TRUE; + } + } + } + } +} - /* - if (PlayerMovPos) - ScrollFigure(0); +void GameActions(int player_action) +{ + static long action_delay = 0; + long action_delay_value; + int sieb_x = 0, sieb_y = 0; + int i, x,y, element; - DrawPlayerField(); - */ + if (game_status != PLAYING) + return; +#ifdef DEBUG + action_delay_value = + (tape.playing && tape.fast_forward ? FFWD_FRAME_DELAY : GameFrameDelay); +#else + action_delay_value = + (tape.playing && tape.fast_forward ? FFWD_FRAME_DELAY : GAME_FRAME_DELAY); +#endif - tst2 = tst; - tst = 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; - if (0) - { - static long last_Counter = 0; - long new_Counter = Counter(); + PlayerActions(player_action); - printf("--> %ld / %ld [%d]\n", - new_Counter - last_Counter, - new_Counter, - FrameCounter); - last_Counter = new_Counter; + if (player->MovPos) + ScrollFigure(0); } + player = local_player; + JX = player->JX; + JY = player->JY; + lastJX = player->lastJX; + lastJY = player->lastJY; - /* - printf("--> %ld / ", Counter()); - */ + if (tape.pausing || (tape.playing && !TapePlayDelay())) + return; + else if (tape.recording) + TapeRecordDelay(); + FrameCounter++; + TimeFrames++; + for(y=0;y0) + JustHit[x][y]--; - /* - FrameCounter++; - */ - - - TimeFrames++; - - for(y=0;y0) - JustHit[x][y]--; + int oldx,oldy; -#if DEBUG - if (IS_BLOCKED(x,y)) + Blocked2Moving(x,y,&oldx,&oldy); + if (!IS_MOVING(oldx,oldy)) { - int oldx,oldy; - - Blocked2Moving(x,y,&oldx,&oldy); - if (!IS_MOVING(oldx,oldy)) - { - printf("GameActions(): (BLOCKED=>MOVING) context corrupted!\n"); - printf("GameActions(): BLOCKED: x = %d, y = %d\n",x,y); - printf("GameActions(): !MOVING: oldx = %d, oldy = %d\n",oldx,oldy); - printf("GameActions(): This should never happen!\n"); - } + printf("GameActions(): (BLOCKED=>MOVING) context corrupted!\n"); + printf("GameActions(): BLOCKED: x = %d, y = %d\n",x,y); + printf("GameActions(): !MOVING: oldx = %d, oldy = %d\n",oldx,oldy); + printf("GameActions(): This should never happen!\n"); } + } #endif + } - } + for(y=0;y0 && TimeFrames>=(100/GameSpeed) && !tape.pausing) + if (TimeLeft>0 && TimeFrames>=(1000/GameFrameDelay) && !tape.pausing) { TimeFrames = 0; TimeLeft--; @@ -2832,9 +2922,32 @@ void GameActions() KillHero(); } - DrawPlayerField(); - BackToFront(); + + + 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) @@ -2842,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, @@ -2877,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); @@ -2908,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); @@ -2922,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); @@ -2944,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); @@ -2962,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(); @@ -2990,129 +3108,40 @@ BOOL MoveFigure(int dx, int dy) void ScrollFigure(int init) { static long actual_frame_counter = 0; - static int oldJX = -1, oldJY = -1; if (init) { - - PlayerGfxPos = - (TILEX/ScrollSteps) * (PlayerMovPos / (TILEX/ScrollSteps)); - - - - if (0) - { - static long last_Counter = 0; - long new_Counter = Counter(); - - printf("--> %ld / %ld [%d, %d]\n", - new_Counter - last_Counter, - new_Counter, - FrameCounter, - tst2); - last_Counter = new_Counter; - } - - - - - if (oldJX != -1 && oldJY != -1) - DrawLevelElement(oldJX,oldJY, Feld[oldJX][oldJY]); - - 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; - DrawLevelElement(lastJX,lastJY, Feld[lastJX][lastJY]); - DrawPlayerField(); - - oldJX = lastJX; - oldJY = lastJY; actual_frame_counter = FrameCounter; - if (PlayerPushing) - { - int nextJX = JX + (JX - lastJX); - int nextJY = JY + (JY - lastJY); - - if (Feld[nextJX][nextJY] == EL_SOKOBAN_FELD_VOLL) - DrawLevelElement(nextJX,nextJY, EL_SOKOBAN_FELD_LEER); - else - DrawLevelElement(nextJX,nextJY, EL_LEERRAUM); - } - - DrawPlayerField(); + player->GfxPos = ScrollStepSize * (player->MovPos / ScrollStepSize); - if (Store[lastJX][lastJY]) - { - DrawGraphic(SCROLLX(lastJX),SCROLLY(lastJY), - el2gfx(Store[lastJX][lastJY])); - DrawGraphicThruMask(SCROLLX(lastJX),SCROLLY(lastJY), - el2gfx(Feld[lastJX][lastJY])); - } - else if (Feld[lastJX][lastJY]==EL_DYNAMIT) - DrawDynamite(lastJX,lastJY); - else - DrawLevelField(lastJX,lastJY); + if (Feld[lastJX][lastJY] == EL_LEERRAUM) + Feld[lastJX][lastJY] = EL_PLAYER_IS_LEAVING; + DrawPlayerField(JX,JY); return; } else if (!FrameReached(&actual_frame_counter,1)) return; - PlayerMovPos += (PlayerMovPos > 0 ? -1 : 1) * TILEX/8; - - - PlayerGfxPos = - (TILEX/ScrollSteps) * (PlayerMovPos / (TILEX/ScrollSteps)); + player->MovPos += (player->MovPos > 0 ? -1 : 1) * TILEX/8; + player->GfxPos = ScrollStepSize * (player->MovPos / ScrollStepSize); - if (ScreenMovPos) + if (ScreenMovPos && ScreenMovPos != local_player->GfxPos) { - ScreenMovPos = PlayerGfxPos; + ScreenMovPos = local_player->GfxPos; redraw_mask |= REDRAW_FIELD; } - if (Feld[oldJX][oldJY] == EL_PLAYER_IS_LEAVING) - Feld[oldJX][oldJY] = EL_LEERRAUM; + if (Feld[lastJX][lastJY] == EL_PLAYER_IS_LEAVING) + Feld[lastJX][lastJY] = EL_LEERRAUM; - DrawLevelElement(oldJX,oldJY, Feld[oldJX][oldJY]); - DrawPlayerField(); + DrawPlayerField(JX,JY); - - - if (Store[oldJX][oldJY]) - { - DrawGraphic(SCROLLX(oldJX),SCROLLY(oldJY),el2gfx(Store[oldJX][oldJY])); - DrawGraphicThruMask(SCROLLX(oldJX),SCROLLY(oldJY), - el2gfx(Feld[oldJX][oldJY])); - } - else if (Feld[oldJX][oldJY]==EL_DYNAMIT) - DrawDynamite(oldJX,oldJY); - else - DrawLevelField(oldJX,oldJY); - - if (PlayerPushing) - { - int nextJX = JX + (JX - lastJX); - int nextJY = JY + (JY - lastJY); - - if (PlayerGfxPos) - { - if (Feld[nextJX][nextJY] == EL_SOKOBAN_FELD_VOLL) - DrawLevelElement(nextJX,nextJY, EL_SOKOBAN_FELD_LEER); - else - DrawLevelElement(nextJX,nextJY, EL_LEERRAUM); - } - else - DrawLevelElement(nextJX,nextJY, Feld[nextJX][nextJY]); - } - - if (!PlayerMovPos) + if (!player->MovPos) { lastJX = JX; lastJY = JY; - - oldJX = oldJY = -1; } } @@ -3301,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]; @@ -3334,49 +3361,55 @@ int DigField(int x, int y, int real_dx, int real_dy, int mode) case EL_EDELSTEIN_LILA: Feld[x][y] = EL_LEERRAUM; MovDelay[x][y] = 0; /* wegen EDELSTEIN_BD-Funkeln! */ - if (Gems>0) - Gems--; + if (local_player->gems_still_needed > 0) + local_player->gems_still_needed--; RaiseScoreElement(EL_EDELSTEIN); - DrawText(DX_EMERALDS,DY_EMERALDS,int2str(Gems,3),FS_SMALL,FC_YELLOW); - PlaySoundLevel(x,y,SND_PONG); + DrawText(DX_EMERALDS, DY_EMERALDS, + int2str(local_player->gems_still_needed, 3), + FS_SMALL, FC_YELLOW); + PlaySoundLevel(x, y, SND_PONG); break; case EL_DIAMANT: Feld[x][y] = EL_LEERRAUM; - Gems -= 3; - if (Gems<0) - Gems=0; + local_player->gems_still_needed -= 3; + if (local_player->gems_still_needed < 0) + local_player->gems_still_needed = 0; RaiseScoreElement(EL_DIAMANT); - DrawText(DX_EMERALDS,DY_EMERALDS,int2str(Gems,3),FS_SMALL,FC_YELLOW); - PlaySoundLevel(x,y,SND_PONG); + DrawText(DX_EMERALDS, DY_EMERALDS, + int2str(local_player->gems_still_needed, 3), + FS_SMALL, FC_YELLOW); + PlaySoundLevel(x, y, SND_PONG); break; case EL_DYNAMIT_AUS: Feld[x][y] = EL_LEERRAUM; - Dynamite++; + player->dynamite++; RaiseScoreElement(EL_DYNAMIT); - DrawText(DX_DYNAMITE,DY_DYNAMITE,int2str(Dynamite,3),FS_SMALL,FC_YELLOW); + DrawText(DX_DYNAMITE, DY_DYNAMITE, + int2str(local_player->dynamite, 3), + FS_SMALL, FC_YELLOW); PlaySoundLevel(x,y,SND_PONG); break; case EL_DYNABOMB_NR: Feld[x][y] = EL_LEERRAUM; - DynaBombCount++; - DynaBombsLeft++; + player->dynabomb_count++; + player->dynabombs_left++; RaiseScoreElement(EL_DYNAMIT); PlaySoundLevel(x,y,SND_PONG); break; case EL_DYNABOMB_SZ: Feld[x][y] = EL_LEERRAUM; - DynaBombSize++; + player->dynabomb_size++; RaiseScoreElement(EL_DYNAMIT); PlaySoundLevel(x,y,SND_PONG); break; case EL_DYNABOMB_XL: Feld[x][y] = EL_LEERRAUM; - DynaBombXL = TRUE; + player->dynabomb_xl = TRUE; RaiseScoreElement(EL_DYNAMIT); PlaySoundLevel(x,y,SND_PONG); break; @@ -3389,14 +3422,14 @@ 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; - Key[key_nr] = TRUE; + player->key[key_nr] = TRUE; RaiseScoreElement(EL_SCHLUESSEL); - DrawMiniGraphicExtHiRes(drawto,gc, - DX_KEYS+key_nr*MINI_TILEX,DY_KEYS, - GFX_SCHLUESSEL1+key_nr); - DrawMiniGraphicExtHiRes(window,gc, - DX_KEYS+key_nr*MINI_TILEX,DY_KEYS, - GFX_SCHLUESSEL1+key_nr); + 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; } @@ -3416,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); @@ -3427,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) @@ -3450,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 (!Key[element-EL_PFORTE1]) + if (!player->key[element-EL_PFORTE1]) return(MF_NO_ACTION); break; @@ -3458,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 (!Key[element-EL_PFORTE1X]) + if (!player->key[element-EL_PFORTE1X]) return(MF_NO_ACTION); break; @@ -3475,14 +3509,14 @@ int DigField(int x, int y, int real_dx, int real_dy, int mode) PlayerGone = TRUE; PlaySoundLevel(x,y,SND_BUING); - if (!Friends) + if (!local_player->friends_still_needed) LevelSolved = GameOver = TRUE; break; case EL_BIRNE_AUS: Feld[x][y] = EL_BIRNE_EIN; - Lights--; + local_player->lights_still_needed--; DrawLevelField(x,y); PlaySoundLevel(x,y,SND_DENG); return(MF_ACTION); @@ -3506,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 @@ -3525,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)) @@ -3535,7 +3570,7 @@ int DigField(int x, int y, int real_dx, int real_dy, int mode) if (element == EL_SOKOBAN_FELD_VOLL) { Feld[x][y] = EL_SOKOBAN_FELD_LEER; - SokobanFields++; + local_player->sokobanfields_still_needed++; } else Feld[x][y] = EL_LEERRAUM; @@ -3543,7 +3578,7 @@ int DigField(int x, int y, int real_dx, int real_dy, int mode) if (Feld[x+dx][y+dy] == EL_SOKOBAN_FELD_LEER) { Feld[x+dx][y+dy] = EL_SOKOBAN_FELD_VOLL; - SokobanFields--; + local_player->sokobanfields_still_needed--; if (element == EL_SOKOBAN_OBJEKT) PlaySoundLevel(x,y,SND_DENG); } @@ -3556,14 +3591,15 @@ 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); PlaySoundLevel(x+dx,y+dy,SND_PUSCH); if (IS_SB_ELEMENT(element) && - SokobanFields == 0 && game_emulation == EMU_SOKOBAN) + local_player->sokobanfields_still_needed == 0 && + game_emulation == EMU_SOKOBAN) { LevelSolved = GameOver = TRUE; PlaySoundLevel(x,y,SND_BUING); @@ -3582,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); } @@ -3604,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); @@ -3623,31 +3659,32 @@ BOOL PlaceBomb(void) { int element; - if (PlayerGone || PlayerMovPos) + if (PlayerGone || player->MovPos) return(FALSE); element = Feld[JX][JY]; - if ((Dynamite==0 && DynaBombsLeft==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 (Dynamite) + if (player->dynamite) { Feld[JX][JY] = EL_DYNAMIT; - MovDelay[JX][JY] = 48; - Dynamite--; - DrawText(DX_DYNAMITE,DY_DYNAMITE,int2str(Dynamite,3),FS_SMALL,FC_YELLOW); + MovDelay[JX][JY] = 96; + player->dynamite--; + DrawText(DX_DYNAMITE, DY_DYNAMITE, int2str(local_player->dynamite, 3), + FS_SMALL, FC_YELLOW); DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_DYNAMIT); } else { Feld[JX][JY] = EL_DYNABOMB; - MovDelay[JX][JY] = 48; - DynaBombsLeft--; + MovDelay[JX][JY] = 96; + player->dynabombs_left--; DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_DYNABOMB); } @@ -3670,7 +3707,13 @@ void PlaySoundLevel(int x, int y, int sound_nr) return; volume = PSND_MAX_VOLUME; +#ifndef MSDOS stereo = (sx-SCR_FIELDX/2)*12; +#else + stereo = PSND_MIDDLE+(2*sx-(SCR_FIELDX-1))*5; + if(stereo > PSND_MAX_RIGHT) stereo = PSND_MAX_RIGHT; + if(stereo < PSND_MAX_LEFT) stereo = PSND_MAX_LEFT; +#endif if (!IN_SCR_FIELD(sx,sy)) { @@ -3685,8 +3728,9 @@ void PlaySoundLevel(int x, int y, int sound_nr) void RaiseScore(int value) { - Score += value; - DrawText(DX_SCORE,DY_SCORE,int2str(Score,5),FS_SMALL,FC_YELLOW); + local_player->score += value; + DrawText(DX_SCORE, DY_SCORE, int2str(local_player->score, 5), + FS_SMALL, FC_YELLOW); } void RaiseScoreElement(int element)