rocks_n_diamonds-0.9b2
authorHolger Schemel <info@artsoft.org>
Tue, 21 Nov 1995 19:48:46 +0000 (20:48 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:30:15 +0000 (10:30 +0200)
src/editor.c
src/files.c
src/game.c
src/game.h
src/init.c
src/main.c
src/main.h
src/screens.c
src/tools.c

index 454fb74e88981448c75eabbd3181e0fa25bbf3ca..7c4976892e53c51f0c3796312c0aa99f6be592e2 100644 (file)
@@ -36,13 +36,18 @@ int editor_element[] =
 
   EL_BETON,
   EL_MAUERWERK,
+  EL_MAUER_LEBT,
   EL_FELSBODEN,
+
   EL_SIEB_LEER,
+  EL_SIEB2_LEER,
+  EL_KOKOSNUSS,
+  EL_BOMBE,
 
   EL_EDELSTEIN,
   EL_DIAMANT,
-  EL_KOKOSNUSS,
-  EL_BOMBE,
+  EL_EDELSTEIN2,
+  EL_EDELSTEIN3,
 
   EL_MORAST_LEER,
   EL_MORAST_VOLL,
@@ -52,12 +57,12 @@ int editor_element[] =
   EL_KAEFER,
   EL_FLIEGER,
   EL_MAMPFER,
-  EL_ZOMBIE,
+  EL_MAMPFER2,
 
+  EL_ZOMBIE,
   EL_PACMAN,
   EL_DYNAMIT_AUS,
   EL_DYNAMIT,
-  EL_ABLENK_AUS,
 
   EL_BADEWANNE1,
   EL_SALZSAEURE,
@@ -75,19 +80,25 @@ int editor_element[] =
   EL_AMOEBE_NORM,
 
   EL_AMOEBE_VOLL,
-
-/*
   EL_LIFE,
-*/
   EL_LIFE_ASYNC,
+  EL_ABLENK_AUS,
 
   EL_ERZ_EDEL,
   EL_ERZ_DIAM,
+  EL_ERZ_EDEL2,
+  EL_ERZ_EDEL3,
 
   EL_ZEIT_VOLL,
   EL_ZEIT_LEER,
+
+  EL_DYNABOMB_NR,
+  EL_DYNABOMB_SZ,
+
+/*
   EL_BIRNE_AUS,
   EL_BIRNE_EIN,
+*/
 
   EL_SCHLUESSEL1,
   EL_SCHLUESSEL2,
index e349c062a9366d9971933f415ade98c6a96dd33d..1efc0a1acbf1f4a91d006136d209e489803b7f54 100644 (file)
@@ -155,9 +155,9 @@ void LoadLevel(int level_nr)
     level.edelsteine   = (fgetc(file)<<8) | fgetc(file);
     for(i=0;i<MAX_LEVNAMLEN;i++)
       level.name[i]    = fgetc(file);
-    for(i=0;i<MAX_SC_ENTRIES;i++)
+    level.name[MAX_LEVNAMLEN-1] = 0;
+    for(i=0;i<MAX_LEVSCORE_ENTRIES;i++)
       level.score[i]   = fgetc(file);
-    level.amoebe_inhalt = fgetc(file);
     for(i=0;i<4;i++)
       for(y=0;y<3;y++)
        for(x=0;x<3;x++)
@@ -165,8 +165,9 @@ void LoadLevel(int level_nr)
     level.tempo_amoebe = fgetc(file);
     level.dauer_sieb   = fgetc(file);
     level.dauer_ablenk = fgetc(file);
+    level.amoebe_inhalt = fgetc(file);
 
-    for(i=0;i<19;i++)  /* Rest reserviert / Headergröße 80 Bytes */
+    for(i=0;i<NUM_FREE_LVHD_BYTES;i++) /* Rest frei / Headergröße 80 Bytes */
       fgetc(file);
 
     for(y=0;y<MAX_LEV_FIELDY;y++) 
@@ -190,9 +191,8 @@ void LoadLevel(int level_nr)
     level.time         = 100;
     level.edelsteine   = 0;
     strncpy(level.name,"Nameless Level",MAX_LEVNAMLEN-1);
-    for(i=0;i<MAX_SC_ENTRIES;i++)
+    for(i=0;i<MAX_LEVSCORE_ENTRIES;i++)
       level.score[i]   = 10;
-    level.amoebe_inhalt = EL_DIAMANT;
     for(i=0;i<4;i++)
       for(y=0;y<3;y++)
        for(x=0;x<3;x++)
@@ -200,6 +200,7 @@ void LoadLevel(int level_nr)
     level.tempo_amoebe = 10;
     level.dauer_sieb   = 10;
     level.dauer_ablenk = 10;
+    level.amoebe_inhalt = EL_DIAMANT;
 
     for(y=0;y<STD_LEV_FIELDY;y++) 
       for(x=0;x<STD_LEV_FIELDX;x++) 
@@ -464,9 +465,8 @@ void SaveLevel(int level_nr)
 
   for(i=0;i<MAX_LEVNAMLEN;i++)
     fputc(level.name[i],file);
-  for(i=0;i<MAX_SC_ENTRIES;i++)
+  for(i=0;i<MAX_LEVSCORE_ENTRIES;i++)
     fputc(level.score[i],file);
-  fputc(level.amoebe_inhalt,file);
   for(i=0;i<4;i++)
     for(y=0;y<3;y++)
       for(x=0;x<3;x++)
@@ -474,8 +474,9 @@ void SaveLevel(int level_nr)
   fputc(level.tempo_amoebe,file);
   fputc(level.dauer_sieb,file);
   fputc(level.dauer_ablenk,file);
+  fputc(level.amoebe_inhalt,file);
 
-  for(i=0;i<19;i++)    /* Rest reserviert / Headergröße 80 Bytes */
+  for(i=0;i<NUM_FREE_LVHD_BYTES;i++)   /* Rest frei / Headergröße 80 Bytes */
     fputc(0,file);
 
   for(y=0;y<lev_fieldy;y++) 
index 8d88167b277ece9f7ddce9e0ebfcd0a030f523aa..46bbbf21fe046ac1bdae9a8e52ec5b9b9ff95717 100644 (file)
@@ -57,6 +57,7 @@ void InitGame()
 
   Dynamite = Score = 0;
   Gems = level.edelsteine;
+  DynaBombCount = DynaBombSize = DynaBombsLeft = 0;
   Key[0] = Key[1] = Key[2] = Key[3] = FALSE;
   MampferNr = 0;
   TimeLeft = level.time;
@@ -82,6 +83,7 @@ void InitGame()
     Feld[x][y] = Ur[x][y];
     MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0;
     Store[x][y] = Store2[x][y] = Frame[x][y] = AmoebaNr[x][y] = 0;
+    JustHit[x][y] = 0;
 
     switch(Feld[x][y])
     {
@@ -121,6 +123,7 @@ void InitGame()
       case EL_PACMAN_L:
       case EL_PACMAN_U:
       case EL_MAMPFER:
+      case EL_MAMPFER2:
       case EL_ZOMBIE:
       case EL_PACMAN:
        InitMovDir(x,y);
@@ -313,7 +316,7 @@ void GameWon()
   CloseDoor(DOOR_CLOSE_1);
 
   if (level_nr==player.handicap &&
-      level_nr<leveldir[leveldir_nr].num_ready
+      level_nr<leveldir[leveldir_nr].num_ready-1)
   { 
     player.handicap++; 
     bumplevel = TRUE;
@@ -503,7 +506,7 @@ void DrawDynamite(int x, int y)
 
 void CheckDynamite(int x, int y)
 {
-  CheckExploding=TRUE;
+  CheckExploding = TRUE;
 
   if (MovDelay[x][y])          /* neues Dynamit / in Wartezustand */
   {
@@ -524,7 +527,7 @@ void CheckDynamite(int x, int y)
   Bang(x,y);
 }
 
-void Explode(int ex, int ey, int phase)
+void Explode(int ex, int ey, int phase, int mode)
 {
   int x,y;
   int num_phase = 9, delay = 1;
@@ -545,7 +548,8 @@ void Explode(int ex, int ey, int phase)
       if (!IN_LEV_FIELD(x,y) || IS_MASSIV(element))
        continue;
 
-      if (center_element==EL_AMOEBA2DIAM && (x!=ex || y!=ey))
+      if ((mode!=EX_NORMAL || center_element==EL_AMOEBA2DIAM) &&
+         (x!=ex || y!=ey))
        continue;
 
       if (element==EL_EXPLODING)
@@ -561,10 +565,14 @@ void Explode(int ex, int ey, int phase)
        Store[x][y] = EL_EDELSTEIN;
       else if (element==EL_ERZ_DIAM)
        Store[x][y] = EL_DIAMANT;
+      else if (element==EL_ERZ_EDEL2)
+       Store[x][y] = EL_EDELSTEIN2;
+      else if (element==EL_ERZ_EDEL3)
+       Store[x][y] = EL_EDELSTEIN3;
       else if (!IS_PFORTE(Store[x][y]))
        Store[x][y] = EL_LEERRAUM;
 
-      if (x!=ex || y!=ey || center_element==EL_AMOEBA2DIAM)
+      if (x!=ex || y!=ey || center_element==EL_AMOEBA2DIAM || mode==EX_BORDER)
        Store2[x][y] = element;
 
       if (AmoebaNr[x][y] && (element==EL_AMOEBE_VOLL || element==EL_AMOEBING))
@@ -601,6 +609,7 @@ void Explode(int ex, int ey, int phase)
     else if (element==EL_BOMBE ||
             element==EL_DYNAMIT ||
             element==EL_DYNAMIT_AUS ||
+            element==EL_DYNABOMB ||
             element==EL_KAEFER)
     {
       Feld[x][y] = Store2[x][y];
@@ -630,14 +639,44 @@ void Explode(int ex, int ey, int phase)
     DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_EXPLOSION+(phase/delay-1));
   }
 
-  CheckExploding=TRUE;
+  CheckExploding = TRUE;
+}
+
+void DynaExplode(int ex, int ey, int size)
+{
+  int i,j;
+  static int xy[4][2] =
+  {
+    0,-1,
+    -1,0,
+    +1,0,
+    0,+1
+  };
+
+  Explode(ex,ey,0,EX_CENTER);
+
+  for(i=0;i<4;i++)
+  {
+    for(j=1;j<=size;j++)
+    {
+      int x = ex+j*xy[i%4][0];
+      int y = ey+j*xy[i%4][1];
+
+      if (!IN_LEV_FIELD(x,y) || IS_MASSIV(Feld[x][y]))
+       break;
+
+      Explode(x,y,0,EX_BORDER);
+    }
+  }
+
+  DynaBombsLeft++;
 }
 
 void Bang(int x, int y)
 {
   int element = Feld[x][y];
 
-  CheckExploding=TRUE;
+  CheckExploding = TRUE;
   PlaySoundLevel(x,y,SND_ROAAAR);
 
   switch(element)
@@ -649,6 +688,7 @@ void Bang(int x, int y)
       RaiseScore(level.score[SC_FLIEGER]);
       break;
     case EL_MAMPFER:
+    case EL_MAMPFER2:
       RaiseScore(level.score[SC_MAMPFER]);
       break;
     case EL_ZOMBIE:
@@ -661,7 +701,10 @@ void Bang(int x, int y)
       break;
   }
 
-  Explode(x,y,0);
+  if (element==EL_DYNABOMB)
+    DynaExplode(x,y,DynaBombSize);
+  else
+    Explode(x,y,0,EX_NORMAL);
 }
 
 void Blurb(int x, int y)
@@ -688,7 +731,7 @@ void Blurb(int x, int y)
   {
     int graphic = (element==EL_BLURB_LEFT ? GFX_BLURB_LEFT : GFX_BLURB_RIGHT);
 
-    CheckExploding=TRUE;
+    CheckExploding = TRUE;
 
     if (!MovDelay[x][y])       /* neue Phase / noch nicht gewartet */
       MovDelay[x][y] = 5;
@@ -757,7 +800,8 @@ void Impact(int x, int y)
       KillHero();
       return;
     }
-    else if (element==EL_FELSBROCKEN)
+    else if (element==EL_FELSBROCKEN ||
+            element==EL_EDELSTEIN2 || element==EL_EDELSTEIN3)
     {
       if (IS_ENEMY(MovingOrBlocked2Element(x,y+1)))
       {
@@ -789,7 +833,7 @@ void Impact(int x, int y)
   }
 
   /* Kein Geräusch beim Durchqueren des Siebes */
-  if (!lastline && Feld[x][y+1]==EL_SIEB_LEER)
+  if (!lastline && (Feld[x][y+1]==EL_SIEB_LEER || Feld[x][y+1]==EL_SIEB2_LEER))
     return;
 
   /* Geräusch beim Auftreffen */
@@ -800,6 +844,8 @@ void Impact(int x, int y)
     switch(element)
     {
       case EL_EDELSTEIN:
+      case EL_EDELSTEIN2:
+      case EL_EDELSTEIN3:
       case EL_DIAMANT:
         sound = SND_PLING;
        break;
@@ -936,6 +982,31 @@ void TurnRound(int x, int y)
 
     MovDelay[x][y]=8+8*RND(3);
   }
+  else if (element==EL_MAMPFER2)
+  {
+    if (MovDir[x][y]==MV_LEFT || MovDir[x][y]==MV_RIGHT)
+    {
+      MovDir[x][y]=(MovDir[x][y]==MV_LEFT ? MV_RIGHT : MV_LEFT);
+      if (IN_LEV_FIELD(x,y-1) &&
+         (IS_FREE(x,y-1) || IS_MAMPF2(Feld[x][y-1])) && RND(2))
+       MovDir[x][y]=MV_UP;
+      if (IN_LEV_FIELD(x,y+1) &&
+         (IS_FREE(x,y+1) || IS_MAMPF2(Feld[x][y+1])) && RND(2))
+       MovDir[x][y]=MV_DOWN;
+    }
+    else if (MovDir[x][y]==MV_UP || MovDir[x][y]==MV_DOWN)
+    {
+      MovDir[x][y]=(MovDir[x][y]==MV_UP ? MV_DOWN : MV_UP);
+      if (IN_LEV_FIELD(x-1,y) &&
+         (IS_FREE(x-1,y) || IS_MAMPF2(Feld[x-1][y])) && RND(2))
+       MovDir[x][y]=MV_LEFT;
+      if (IN_LEV_FIELD(x+1,y) &&
+         (IS_FREE(x+1,y) || IS_MAMPF2(Feld[x+1][y])) && RND(2))
+       MovDir[x][y]=MV_RIGHT;
+    }
+
+    MovDelay[x][y]=8+8*RND(3);
+  }
   else if (element==EL_PACMAN)
   {
     if (MovDir[x][y]==MV_LEFT || MovDir[x][y]==MV_RIGHT)
@@ -1010,7 +1081,7 @@ void StartMoving(int x, int y)
       }
       else if (Feld[x][y+1]==EL_MORAST_LEER)
       {
-       CheckMoving=TRUE;
+       CheckMoving = TRUE;
 
        if (!MovDelay[x][y])
          MovDelay[x][y] = 16;
@@ -1040,10 +1111,21 @@ void StartMoving(int x, int y)
        Store[x][y] = EL_SIEB_LEER;
       }
     }
-    else if (CAN_CHANGE(element) && Feld[x][y+1]==EL_SIEB_LEER)
+    else if (element==EL_SIEB2_VOLL)
+    {
+      if (IS_FREE(x,y+1))
+      {
+       InitMovingField(x,y,MV_DOWN);
+       Feld[x][y] = EL_CHANGED2(Store2[x][y]);
+       Store[x][y] = EL_SIEB2_LEER;
+      }
+    }
+    else if (CAN_CHANGE(element) &&
+            (Feld[x][y+1]==EL_SIEB_LEER || Feld[x][y+1]==EL_SIEB2_LEER))
     {
       InitMovingField(x,y,MV_DOWN);
-      Store[x][y] = EL_SIEB_VOLL;
+      Store[x][y] =
+       (Feld[x][y+1]==EL_SIEB_LEER ? EL_SIEB_VOLL : EL_SIEB2_VOLL);
       Store2[x][y+1] = element;
       SiebAktiv = 330;
     }
@@ -1053,7 +1135,7 @@ void StartMoving(int x, int y)
       InitMovingField(x,y,MV_DOWN);
       Store[x][y] = EL_SALZSAEURE;
     }
-    else if (CAN_SMASH(element) && Feld[x][y+1]==EL_BLOCKED)
+    else if (CAN_SMASH(element) && Feld[x][y+1]==EL_BLOCKED && JustHit[x][y])
     {
       Impact(x,y);
     }
@@ -1101,7 +1183,7 @@ void StartMoving(int x, int y)
     {
       MovDelay[x][y]--;
 
-      if (element==EL_ZOMBIE || element==EL_MAMPFER)
+      if (element==EL_ZOMBIE || element==EL_MAMPFER || element==EL_MAMPFER2)
       {
        int phase = MovDelay[x][y] % 8;
 
@@ -1112,7 +1194,8 @@ void StartMoving(int x, int y)
          DrawGraphic(SCROLLX(x),SCROLLY(y),
                      el2gfx(element)+phase);
 
-       if (element==EL_MAMPFER && MovDelay[x][y]%4==3)
+       if ((element==EL_MAMPFER || element==EL_MAMPFER2)
+           && MovDelay[x][y]%4==3)
          PlaySoundLevel(x,y,SND_NJAM);
       }
 
@@ -1150,6 +1233,20 @@ void StartMoving(int x, int y)
        DrawLevelField(newx,newy);
       }
     }
+    else if (element==EL_MAMPFER2 && IN_LEV_FIELD(newx,newy) &&
+            IS_MAMPF2(Feld[newx][newy]))
+    {
+      if (AmoebaNr[newx][newy] && Feld[newx][newy]==EL_AMOEBE_VOLL)
+       AmoebaCnt[AmoebaNr[newx][newy]]--;
+
+      if (IS_MOVING(newx,newy))
+       RemoveMovingField(newx,newy);
+      else
+      {
+       Feld[newx][newy] = EL_LEERRAUM;
+       DrawLevelField(newx,newy);
+      }
+    }
     else if (element==EL_PACMAN && IN_LEV_FIELD(newx,newy) &&
             IS_AMOEBOID(Feld[newx][newy]))
     {
@@ -1200,8 +1297,8 @@ void ContinueMoving(int x, int y)
 
   if (ABS(MovPos[x][y])>=TILEX)                /* Zielfeld erreicht */
   {
-    Feld[x][y]=EL_LEERRAUM;
-    Feld[newx][newy]=element;
+    Feld[x][y] = EL_LEERRAUM;
+    Feld[newx][newy] = element;
 
     if (Store[x][y]==EL_MORAST_VOLL)
     {
@@ -1225,6 +1322,17 @@ void ContinueMoving(int x, int y)
       Store[x][y] = Store2[x][y] = 0;
       Feld[x][y] = EL_SIEB_LEER;
     }
+    else if (Store[x][y]==EL_SIEB2_VOLL)
+    {
+      Store[x][y] = 0;
+      Feld[newx][newy] = EL_SIEB2_VOLL;
+      element = EL_SIEB2_VOLL;
+    }
+    else if (Store[x][y]==EL_SIEB2_LEER)
+    {
+      Store[x][y] = Store2[x][y] = 0;
+      Feld[x][y] = EL_SIEB2_LEER;
+    }
     else if (Store[x][y]==EL_SALZSAEURE)
     {
       Store[x][y] = 0;
@@ -1245,8 +1353,9 @@ void ContinueMoving(int x, int y)
     DrawLevelField(x,y);
     DrawLevelField(newx,newy);
 
-    Stop[newx][newy]=TRUE;
-    CheckMoving=TRUE;
+    Stop[newx][newy] = TRUE;
+    JustHit[x][newy] = 3;
+    CheckMoving = TRUE;
 
     if (DONT_TOUCH(element))   /* Käfer oder Flieger */
     {
@@ -1261,7 +1370,7 @@ void ContinueMoving(int x, int y)
   else                         /* noch in Bewegung */
   {
     DrawLevelField(x,y);
-    CheckMoving=TRUE;
+    CheckMoving = TRUE;
   }
 }
 
@@ -1376,7 +1485,7 @@ void AmoebeWaechst(int x, int y)
   static long sound_delay = 0;
   static int sound_delay_value = 0;
 
-  CheckExploding=TRUE;
+  CheckExploding = TRUE;
 
   if (!MovDelay[x][y])         /* neue Phase / noch nicht gewartet */
   {
@@ -1417,7 +1526,7 @@ void AmoebeAbleger(int ax, int ay)
     0,+1
   };
 
-  CheckExploding=TRUE;
+  CheckExploding = TRUE;
 
   if (!level.tempo_amoebe)
   {
@@ -1529,7 +1638,7 @@ void Life(int ax, int ay)
   int life_time = 20;
   int element = Feld[ax][ay];
 
-  CheckExploding=TRUE;
+  CheckExploding = TRUE;
 
   if (Stop[ax][ay])
     return;
@@ -1591,7 +1700,7 @@ void Life(int ax, int ay)
 
 void Ablenk(int x, int y)
 {
-  CheckExploding=TRUE;
+  CheckExploding = TRUE;
 
   if (!MovDelay[x][y])         /* neue Phase / noch nicht gewartet */
     MovDelay[x][y] = 33*(level.dauer_ablenk/10);
@@ -1616,7 +1725,7 @@ void Ablenk(int x, int y)
 
 void Birne(int x, int y)
 {
-  CheckExploding=TRUE;
+  CheckExploding = TRUE;
 
   if (!MovDelay[x][y])         /* neue Phase / noch nicht gewartet */
     MovDelay[x][y] = 400;
@@ -1647,7 +1756,7 @@ void Birne(int x, int y)
 
 void Blubber(int x, int y)
 {
-  CheckExploding=TRUE;
+  CheckExploding = TRUE;
 
   if (!MovDelay[x][y])         /* neue Phase / noch nicht gewartet */
     MovDelay[x][y] = 20;
@@ -1665,7 +1774,7 @@ void Blubber(int x, int y)
 
 void NussKnacken(int x, int y)
 {
-  CheckExploding=TRUE;
+  CheckExploding = TRUE;
 
   if (!MovDelay[x][y])         /* neue Phase / noch nicht gewartet */
     MovDelay[x][y] = 4;
@@ -1684,14 +1793,15 @@ void NussKnacken(int x, int y)
   }
 }
 
-void SiebAktivieren(int x, int y)
+void SiebAktivieren(int x, int y, int typ)
 {
-  CheckExploding=TRUE;
+  CheckExploding = TRUE;
 
   if (SiebAktiv>1)
   {
     if (SiebAktiv%2 && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
-      DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_SIEB_VOLL+3-(SiebAktiv%8)/2);
+      DrawGraphic(SCROLLX(x),SCROLLY(y),
+                 (typ==1 ? GFX_SIEB_VOLL : GFX_SIEB2_VOLL)+3-(SiebAktiv%8)/2);
 
 /*
     if (!(SiebAktiv%4))
@@ -1701,34 +1811,39 @@ void SiebAktivieren(int x, int y)
   }
   else
   {
-    Feld[x][y] = EL_SIEB_TOT;
+    Feld[x][y] = (typ==1 ? EL_SIEB_TOT : EL_SIEB2_TOT);
     DrawLevelField(x,y);
   }
 }
 
 void AusgangstuerPruefen(int x, int y)
 {
-  CheckExploding=TRUE;
+  CheckExploding = TRUE;
 
   if (!Gems)
+  {
     Feld[x][y] = EL_AUSGANG_ACT;
+    PlaySoundLevel(x,y,SND_OEFFNEN);
+  }
 }
 
 void AusgangstuerOeffnen(int x, int y)
 {
-  CheckExploding=TRUE;
+  int speed = 3;
+
+  CheckExploding = TRUE;
 
   if (!MovDelay[x][y])         /* neue Phase / noch nicht gewartet */
-    MovDelay[x][y] = 20;
+    MovDelay[x][y] = 5*speed;
 
   if (MovDelay[x][y])          /* neue Phase / in Wartezustand */
   {
     int tuer;
 
     MovDelay[x][y]--;
-    tuer = MovDelay[x][y]/5;
-    if (!(MovDelay[x][y]%5) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
-      DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_AUSGANG_ZU+3-tuer);
+    tuer = MovDelay[x][y]/speed;
+    if (!(MovDelay[x][y]%speed) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
+      DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_AUSGANG_AUF-tuer);
 
     if (!MovDelay[x][y])
     {
@@ -1738,6 +1853,137 @@ void AusgangstuerOeffnen(int x, int y)
   }
 }
 
+void AusgangstuerBlinken(int x, int y)
+{
+  CheckExploding = TRUE;
+
+  if (!MovDelay[x][y])         /* neue Phase / noch nicht gewartet */
+    MovDelay[x][y] = 16;
+
+  if (MovDelay[x][y])          /* neue Phase / in Wartezustand */
+  {
+    int phase;
+
+    MovDelay[x][y]--;
+    phase = (MovDelay[x][y] % 16)/2;
+    if (phase>3)
+      phase = 7-phase;
+    if (!(MovDelay[x][y]%2) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
+      DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_AUSGANG_AUF+phase);
+  }
+}
+
+void EdelsteinFunkeln(int x, int y)
+{
+  int speed = 2;
+
+  CheckExploding = TRUE;
+
+  if (IS_MOVING(x,y))
+    return;
+
+  if (!MovDelay[x][y])         /* neue Phase / noch nicht gewartet */
+    MovDelay[x][y] = 4*speed;
+
+  if (MovDelay[x][y])          /* neue Phase / in Wartezustand */
+  {
+    int phase;
+
+    MovDelay[x][y]--;
+    phase = MovDelay[x][y]/speed;
+    if (!(MovDelay[x][y]%speed) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
+      DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_EDELSTEIN2-phase);
+  }
+}
+
+void MauerWaechst(int x, int y)
+{
+  int speed = 3;
+
+  CheckExploding = TRUE;
+
+  if (!MovDelay[x][y])         /* neue Phase / noch nicht gewartet */
+    MovDelay[x][y] = 3*speed;
+
+  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)))
+      DrawGraphic(SCROLLX(x),SCROLLY(y),
+                 (Store[x][y]==MV_LEFT ? GFX_MAUER_L1 : GFX_MAUER_R1)+phase);
+
+    if (!MovDelay[x][y])
+    {
+      if (Store[x][y]==MV_LEFT)
+      {
+       if (IN_LEV_FIELD(x-1,y) && IS_MAUER(Feld[x-1][y]))
+         DrawLevelField(x-1,y);
+      }
+      else
+      {
+       if (IN_LEV_FIELD(x+1,y) && IS_MAUER(Feld[x+1][y]))
+         DrawLevelField(x+1,y);
+      }
+
+      Feld[x][y] = EL_MAUER_LEBT;
+      Store[x][y] = 0;
+      DrawLevelField(x,y);
+    }
+  }
+}
+
+void MauerAbleger(int ax, int ay)
+{
+  BOOL links_frei = FALSE, rechts_frei = FALSE;
+  BOOL links_massiv = FALSE, rechts_massiv = FALSE;
+
+  CheckExploding = TRUE;
+
+  if (!MovDelay[ax][ay])       /* neue Mauer / noch nicht gewartet */
+    MovDelay[ax][ay] = 3;
+
+  if (MovDelay[ax][ay])                /* neue Mauer / in Wartezustand */
+  {
+    MovDelay[ax][ay]--;
+    if (MovDelay[ax][ay])
+      return;
+  }
+
+  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)
+  {
+    Feld[ax-1][ay] = EL_MAUERND;
+    Store[ax-1][ay] = MV_LEFT;
+    if (IN_SCR_FIELD(SCROLLX(ax-1),SCROLLY(ay)))
+      DrawGraphic(SCROLLX(ax-1),SCROLLY(ay),GFX_MAUER_L1);
+  }
+  if (rechts_frei)
+  {
+    Feld[ax+1][ay] = EL_MAUERND;
+    Store[ax+1][ay] = MV_RIGHT;
+    if (IN_SCR_FIELD(SCROLLX(ax+1),SCROLLY(ay)))
+      DrawGraphic(SCROLLX(ax+1),SCROLLY(ay),GFX_MAUER_R1);
+  }
+
+  if (links_frei || rechts_frei)
+    DrawLevelField(ax,ay);
+
+  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)
+    Feld[ax][ay] = EL_MAUERWERK;
+}
+
 int GameActions(int mx, int my, int button)
 {
   static long time_delay=0, action_delay=0;
@@ -1777,7 +2023,11 @@ int GameActions(int mx, int my, int button)
 
     CheckMoving = CheckExploding = FALSE;
     for(y=0;y<lev_fieldy;y++) for(x=0;x<lev_fieldx;x++)
+    {
       Stop[x][y] = FALSE;
+      if (JustHit[x][y]>0)
+       JustHit[x][y]--;
+    }
 
     for(y=0;y<lev_fieldy;y++) for(x=0;x<lev_fieldx;x++)
     {
@@ -1787,13 +2037,17 @@ int GameActions(int mx, int my, int button)
        continue;
 
       if (!IS_MOVING(x,y) && (CAN_FALL(element) || CAN_MOVE(element)))
+      {
        StartMoving(x,y);
+       if (Feld[x][y]==EL_EDELSTEIN2)
+         EdelsteinFunkeln(x,y);
+      }
       else if (IS_MOVING(x,y))
        ContinueMoving(x,y);
-      else if (element==EL_DYNAMIT)
+      else if (element==EL_DYNAMIT || element==EL_DYNABOMB)
        CheckDynamite(x,y);
       else if (element==EL_EXPLODING)
-       Explode(x,y,Frame[x][y]);
+       Explode(x,y,Frame[x][y],EX_NORMAL);
       else if (element==EL_AMOEBING)
        AmoebeWaechst(x,y);
       else if (IS_AMOEBALIVE(element))
@@ -1812,11 +2066,22 @@ int GameActions(int mx, int my, int button)
        AusgangstuerPruefen(x,y);
       else if (element==EL_AUSGANG_ACT)
        AusgangstuerOeffnen(x,y);
-
-      if (SiebAktiv && (element==EL_SIEB_LEER ||
-                       element==EL_SIEB_VOLL ||
-                       Store[x][y]==EL_SIEB_LEER))
-       SiebAktivieren(x,y);
+      else if (element==EL_AUSGANG_AUF)
+       AusgangstuerBlinken(x,y);
+      else if (element==EL_MAUERND)
+       MauerWaechst(x,y);
+      else if (element==EL_MAUER_LEBT)
+       MauerAbleger(x,y);
+
+      if (SiebAktiv)
+      {
+       if (element==EL_SIEB_LEER || element==EL_SIEB_VOLL ||
+           Store[x][y]==EL_SIEB_LEER)
+         SiebAktivieren(x,y,1);
+       else if (element==EL_SIEB2_LEER || element==EL_SIEB2_VOLL ||
+                Store[x][y]==EL_SIEB2_LEER)
+         SiebAktivieren(x,y,2);
+      }
     }
 
     if (SiebAktiv)
@@ -2058,7 +2323,7 @@ void KillHero()
 
 int DigField(int x, int y, int mode)
 {
-  int dx=x-JX, dy=y-JY;
+  int dx = x-JX, dy = y-JY;
   int element;
   static long push_delay = 0;
   static int push_delay_value = 20;
@@ -2077,15 +2342,17 @@ int DigField(int x, int y, int mode)
   switch(element)
   {
     case EL_LEERRAUM:
-      CheckMoving=TRUE;
+      CheckMoving = TRUE;
       break;
     case EL_ERDREICH:
-      Feld[x][y]=EL_LEERRAUM;
-      CheckMoving=TRUE;
+      Feld[x][y] = EL_LEERRAUM;
+      CheckMoving = TRUE;
       break;
     case EL_EDELSTEIN:
-      Feld[x][y]=EL_LEERRAUM;
-      CheckMoving=TRUE;
+    case EL_EDELSTEIN2:
+    case EL_EDELSTEIN3:
+      Feld[x][y] = EL_LEERRAUM;
+      CheckMoving = TRUE;
       if (Gems>0)
        Gems--;
       RaiseScore(level.score[SC_EDELSTEIN]);
@@ -2093,8 +2360,8 @@ int DigField(int x, int y, int mode)
       PlaySoundLevel(x,y,SND_PONG);
       break;
     case EL_DIAMANT:
-      Feld[x][y]=EL_LEERRAUM;
-      CheckMoving=TRUE;
+      Feld[x][y] = EL_LEERRAUM;
+      CheckMoving = TRUE;
       Gems -= 3;
       if (Gems<0)
        Gems=0;
@@ -2103,13 +2370,28 @@ int DigField(int x, int y, int mode)
       PlaySoundLevel(x,y,SND_PONG);
       break;
     case EL_DYNAMIT_AUS:
-      Feld[x][y]=EL_LEERRAUM;
-      CheckMoving=TRUE;
+      Feld[x][y] = EL_LEERRAUM;
+      CheckMoving = TRUE;
       Dynamite++;
       RaiseScore(level.score[SC_DYNAMIT]);
       DrawText(DX_DYNAMITE,DY_DYNAMITE,int2str(Dynamite,3),FS_SMALL,FC_YELLOW);
       PlaySoundLevel(x,y,SND_PONG);
       break;
+    case EL_DYNABOMB_NR:
+      Feld[x][y] = EL_LEERRAUM;
+      CheckMoving = TRUE;
+      DynaBombCount++;
+      DynaBombsLeft++;
+      RaiseScore(level.score[SC_DYNAMIT]);
+      PlaySoundLevel(x,y,SND_PONG);
+      break;
+    case EL_DYNABOMB_SZ:
+      Feld[x][y] = EL_LEERRAUM;
+      CheckMoving = TRUE;
+      DynaBombSize++;
+      RaiseScore(level.score[SC_DYNAMIT]);
+      PlaySoundLevel(x,y,SND_PONG);
+      break;
     case EL_SCHLUESSEL1:
     case EL_SCHLUESSEL2:
     case EL_SCHLUESSEL3:
@@ -2132,7 +2414,7 @@ int DigField(int x, int y, int mode)
     }
     case EL_ABLENK_AUS:
       Feld[x][y] = EL_ABLENK_EIN;
-      CheckExploding=TRUE;
+      CheckExploding = TRUE;
       ZX=x;
       ZY=y;
       DrawLevelField(x,y);
@@ -2184,8 +2466,12 @@ int DigField(int x, int y, int mode)
       return(MF_NO_ACTION);
       break;
     case EL_AUSGANG_AUF:
+/*
       if (mode==DF_SNAP || Gems>0)
        return(MF_NO_ACTION);
+*/
+      if (mode==DF_SNAP)
+       return(MF_NO_ACTION);
       LevelSolved = GameOver = TRUE;
       PlaySoundLevel(x,y,SND_BUING);
       break;
@@ -2238,16 +2524,32 @@ BOOL SnapField(int dx, int dy)
 
 BOOL PlaceBomb(void)
 {
-  if (Dynamite==0 || Feld[JX][JY]==EL_DYNAMIT)
+  if ((Dynamite==0 && DynaBombsLeft==0) ||
+      Feld[JX][JY]==EL_DYNAMIT || Feld[JX][JY]==EL_DYNABOMB)
     return(FALSE);
 
   if (Feld[JX][JY]!=EL_LEERRAUM)
     Store[JX][JY] = Feld[JX][JY];
-  Feld[JX][JY] = EL_DYNAMIT;
-  MovDelay[JX][JY] = 48;
-  Dynamite--;
-  DrawText(DX_DYNAMITE,DY_DYNAMITE,int2str(Dynamite,3),FS_SMALL,FC_YELLOW);
-  DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_DYNAMIT);
+
+  if (Dynamite)
+  {
+    Feld[JX][JY] = EL_DYNAMIT;
+    MovDelay[JX][JY] = 48;
+    Dynamite--;
+    DrawText(DX_DYNAMITE,DY_DYNAMITE,int2str(Dynamite,3),FS_SMALL,FC_YELLOW);
+    DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_DYNAMIT);
+  }
+  else
+  {
+    Feld[JX][JY] = EL_DYNABOMB;
+    MovDelay[JX][JY] = 48;
+    DynaBombsLeft--;
+
+    /* ändern, wenn Maske für DYNABOMB vorliegt! */
+
+    DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_DYNAMIT);
+  }
+
   CheckExploding = TRUE;
   return(TRUE);
 }
index e7150b6be6ac963c8d9f6dc1a5844c1c888acccb..56be763ce0da76f092edd1ab4e25b5e789497f26 100644 (file)
 #define MF_MOVING      1
 #define MF_ACTION      2
 
+#define EX_NORMAL      0
+#define EX_CENTER      1
+#define EX_BORDER      2
+
 void GetPlayerConfig(void);
 void InitGame(void);
 void InitMovDir(int, int);
@@ -38,7 +42,8 @@ int MovingOrBlocked2Element(int, int);
 void RemoveMovingField(int, int);
 void DrawDynamite(int, int);
 void CheckDynamite(int, int);
-void Explode(int, int, int);
+void Explode(int, int, int, int);
+void DynaExplode(int, int, int);
 void Bang(int, int);
 void Blurb(int, int);
 void Impact(int, int);
@@ -53,9 +58,13 @@ void Life(int, int);
 void Ablenk(int, int);
 void Blubber(int, int);
 void NussKnacken(int, int);
-void SiebAktivieren(int x, int y);
-void AusgangstuerPruefen(int x, int y);
-void AusgangstuerOeffnen(int x, int y);
+void SiebAktivieren(int, int, int);
+void AusgangstuerPruefen(int, int);
+void AusgangstuerOeffnen(int, int);
+void AusgangstuerBlinken(int, int);
+void EdelsteinFunkeln(int, int);
+void MauerWaechst(int, int);
+void MauerAbleger(int, int);
 int GameActions(int, int, int);
 void ScrollLevel(int, int);
 BOOL MoveFigure(int, int);
index 8032ffb3d82bd798bd690dea25364937cdc4c3a8..251d32d64d6dd4efbb967486b22acd84cecd146a 100644 (file)
@@ -490,6 +490,7 @@ void InitElementProperties()
   {
     EL_BETON,
     EL_MAUERWERK,
+    EL_MAUER_LEBT,
     EL_FELSBODEN,
     EL_AUSGANG_ZU,
     EL_AUSGANG_ACT,
@@ -502,6 +503,10 @@ void InitElementProperties()
     EL_MORAST_LEER,
     EL_SIEB_VOLL,
     EL_SIEB_LEER,
+    EL_SIEB_TOT,
+    EL_SIEB2_VOLL,
+    EL_SIEB2_LEER,
+    EL_SIEB2_TOT,
     EL_LIFE,
     EL_LIFE_ASYNC,
     EL_BADEWANNE1,
@@ -537,6 +542,8 @@ void InitElementProperties()
     EL_FELSBODEN,
     EL_FELSBROCKEN,
     EL_EDELSTEIN,
+    EL_EDELSTEIN2,
+    EL_EDELSTEIN3,
     EL_DIAMANT,
     EL_BOMBE,
     EL_KOKOSNUSS,
@@ -556,21 +563,46 @@ void InitElementProperties()
     EL_KAEFER,
     EL_FLIEGER,
     EL_MAMPFER,
+    EL_MAMPFER2,
     EL_ZOMBIE,
     EL_PACMAN
   };
   static int ep_enemy_num = sizeof(ep_enemy)/sizeof(int);
 
+  static int ep_mauer[] =
+  {
+    EL_BETON,
+    EL_PFORTE1,
+    EL_PFORTE2,
+    EL_PFORTE3,
+    EL_PFORTE4,
+    EL_PFORTE1X,
+    EL_PFORTE2X,
+    EL_PFORTE3X,
+    EL_PFORTE4X,
+    EL_AUSGANG_ZU,
+    EL_AUSGANG_ACT,
+    EL_AUSGANG_AUF,
+    EL_MAUERWERK,
+    EL_FELSBODEN,
+    EL_MAUER_LEBT,
+    EL_MAUERND
+  };
+  static int ep_mauer_num = sizeof(ep_mauer)/sizeof(int);
+
   static int ep_can_fall[] =
   {
     EL_FELSBROCKEN,
     EL_EDELSTEIN,
+    EL_EDELSTEIN2,
+    EL_EDELSTEIN3,
     EL_DIAMANT,
     EL_BOMBE,
     EL_KOKOSNUSS,
     EL_TROPFEN,
     EL_MORAST_VOLL,
     EL_SIEB_VOLL,
+    EL_SIEB2_VOLL,
     EL_ZEIT_VOLL,
     EL_ZEIT_LEER
   };
@@ -580,6 +612,8 @@ void InitElementProperties()
   {
     EL_FELSBROCKEN,
     EL_EDELSTEIN,
+    EL_EDELSTEIN2,
+    EL_EDELSTEIN3,
     EL_DIAMANT,
     EL_SCHLUESSEL1,
     EL_SCHLUESSEL2,
@@ -597,6 +631,8 @@ void InitElementProperties()
   {
     EL_FELSBROCKEN,
     EL_EDELSTEIN,
+    EL_EDELSTEIN2,
+    EL_EDELSTEIN3,
     EL_DIAMANT
   };
   static int ep_can_change_num = sizeof(ep_can_change)/sizeof(int);
@@ -606,6 +642,7 @@ void InitElementProperties()
     EL_KAEFER,
     EL_FLIEGER,
     EL_MAMPFER,
+    EL_MAMPFER2,
     EL_ZOMBIE,
     EL_PACMAN
   };
@@ -640,6 +677,7 @@ void InitElementProperties()
     EL_KAEFER,
     EL_FLIEGER,
     EL_MAMPFER,
+    EL_MAMPFER2,
     EL_ZOMBIE,
     EL_PACMAN,
     EL_TROPFEN,
@@ -647,6 +685,26 @@ void InitElementProperties()
   };
   static int ep_dont_go_to_num = sizeof(ep_dont_go_to)/sizeof(int);
 
+  static int ep_mampf2[] =
+  {
+    EL_ERDREICH,
+    EL_KAEFER,
+    EL_FLIEGER,
+    EL_MAMPFER,
+    EL_ZOMBIE,
+    EL_PACMAN,
+    EL_TROPFEN,
+    EL_AMOEBE_TOT,
+    EL_AMOEBE_NASS,
+    EL_AMOEBE_NORM,
+    EL_AMOEBE_VOLL,
+    EL_EDELSTEIN,
+    EL_EDELSTEIN2,
+    EL_EDELSTEIN3,
+    EL_DIAMANT
+  };
+  static int ep_mampf2_num = sizeof(ep_mampf2)/sizeof(int);
+
   static long ep_bit[] =
   {
     EP_BIT_AMOEBALIVE,
@@ -658,13 +716,15 @@ void InitElementProperties()
     EP_BIT_MASSIV,
     EP_BIT_SLIPPERY,
     EP_BIT_ENEMY,
+    EP_BIT_MAUER,
     EP_BIT_CAN_FALL,
     EP_BIT_CAN_SMASH,
     EP_BIT_CAN_CHANGE,
     EP_BIT_CAN_MOVE,
     EP_BIT_COULD_MOVE,
     EP_BIT_DONT_TOUCH,
-    EP_BIT_DONT_GO_TO
+    EP_BIT_DONT_GO_TO,
+    EP_BIT_MAMPF2
   };
   static int *ep_array[] =
   {
@@ -677,13 +737,15 @@ void InitElementProperties()
     ep_massiv,
     ep_slippery,
     ep_enemy,
+    ep_mauer,
     ep_can_fall,
     ep_can_smash,
     ep_can_change,
     ep_can_move,
     ep_could_move,
     ep_dont_touch,
-    ep_dont_go_to
+    ep_dont_go_to,
+    ep_mampf2
   };
   static int *ep_num[] =
   {
@@ -696,13 +758,15 @@ void InitElementProperties()
     &ep_massiv_num,
     &ep_slippery_num,
     &ep_enemy_num,
+    &ep_mauer_num,
     &ep_can_fall_num,
     &ep_can_smash_num,
     &ep_can_change_num,
     &ep_can_move_num,
     &ep_could_move_num,
     &ep_dont_touch_num,
-    &ep_dont_go_to_num
+    &ep_dont_go_to_num,
+    &ep_mampf2_num
   };
   static int num_properties = sizeof(ep_num)/sizeof(int *);
 
index 0e3f612bff6fb402f8952b215151142810209a0c..573ea9cb98599e000066b7a99b0c5be3ccd7aad9 100644 (file)
@@ -64,6 +64,7 @@ int           Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 int            Store2[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];
 int            AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 int            AmoebaCnt[MAX_NUM_AMOEBA];
 long           Elementeigenschaften[MAX_ELEMENTS];
@@ -73,6 +74,7 @@ int           lev_fieldx,lev_fieldy, scroll_x,scroll_y;
 
 int            LevelSolved,GameOver, JX,JY, ZX,ZY;
 int            Gems,Dynamite,Key[4],TimeLeft,Score,MampferNr;
+int            DynaBombCount, DynaBombSize, DynaBombsLeft;
 int            CheckMoving,CheckExploding, SiebAktiv;
 
 struct LevelDirInfo    leveldir[MAX_LEVDIR_ENTRIES];
index 905688b335820cbe8c8dcf239d284478a5f81c7a..7d92afb41a1078f9d2de23aa2e454abcb67d83ee 100644 (file)
 #include <X11/Intrinsic.h>
 #include <X11/keysymdef.h>
 
+#ifdef   XPM_INCLUDE_FILE
 #include XPM_INCLUDE_FILE
+#else
+#include "YOU HAVE TO SET 'XPM_INCLUDE_FILE' IN THE 'Makefile'!!!"
+#endif
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -67,40 +71,6 @@ typedef int BOOL;
 #define IS_MOVING(x,y) (MovPos[x][y]!=0)
 #define IS_BLOCKED(x,y)        (Feld[x][y]==EL_BLOCKED)
 
-/*
-
-#define IS_AMOEBALIVE(e) ((e)==EL_AMOEBE_NASS || (e)==EL_AMOEBE_NORM || (e)==EL_AMOEBE_VOLL)
-#define IS_AMOEBOID(e) ((e)==EL_AMOEBE_TOT || IS_AMOEBALIVE(e))
-#define IS_BADEWANNOID(e) ((e)>=EL_BADEWANNE1 && (e)<=EL_BADEWANNE5)
-#define IS_SCHLUESSEL(e) ((e)>=EL_SCHLUESSEL1 && (e)<=EL_SCHLUESSEL4)
-#define IS_PFORTE(e)   ((e)>=EL_PFORTE1 && (e)<=EL_PFORTE4X)
-
-#define IS_SOLID(e)    ((e)==EL_BETON || (e)==EL_MAUERWERK || (e)==EL_FELSBODEN || (e)==EL_AUSGANG_ZU || (e)==EL_AUSGANG_ACT || (e)==EL_AUSGANG_AUF || IS_AMOEBOID(e) || (e)==EL_MORAST_VOLL || (e)==EL_MORAST_LEER || (e)==EL_SIEB_VOLL || (e)==EL_SIEB_LEER || (e)==EL_LIFE || (e)==EL_LIFE_ASYNC || IS_BADEWANNOID(e))
-
-#define IS_MASSIV(e)   ((e)==EL_BETON || (e)==EL_SALZSAEURE || IS_BADEWANNOID(e) || IS_PFORTE(e))
-
-#define IS_SLIPPERY(e) ((e)==EL_FELSBODEN || (e)==EL_FELSBROCKEN || (e)==EL_EDELSTEIN || (e)==EL_DIAMANT || (e)==EL_BOMBE || (e)==EL_KOKOSNUSS || (e)==EL_ABLENK_EIN || (e)==EL_ABLENK_AUS || (e)==EL_ZEIT_VOLL || (e)==EL_ZEIT_LEER || (e)==EL_BIRNE_EIN || (e)==EL_BIRNE_AUS || (e)==EL_BADEWANNE1 || (e)==EL_BADEWANNE2)
-
-#define IS_ENEMY(e)    ((e)==EL_KAEFER || (e)==EL_FLIEGER || (e)==EL_MAMPFER || (e)==EL_ZOMBIE || (e)==EL_PACMAN)
-
-#define CAN_FALL(e)    ((e)==EL_FELSBROCKEN || (e)==EL_EDELSTEIN || (e)==EL_DIAMANT || (e)==EL_BOMBE || (e)==EL_KOKOSNUSS || (e)==EL_TROPFEN || (e)==EL_MORAST_VOLL || (e)==EL_SIEB_VOLL || (e)==EL_ZEIT_VOLL || (e)==EL_ZEIT_LEER)
-
-#define CAN_SMASH(e)   ((e)==EL_FELSBROCKEN || (e)==EL_EDELSTEIN || (e)==EL_DIAMANT || IS_SCHLUESSEL(e) || (e)==EL_BOMBE || (e)==EL_KOKOSNUSS || (e)==EL_TROPFEN || (e)==EL_ZEIT_VOLL || (e)==EL_ZEIT_LEER)
-
-#define CAN_CHANGE(e)  ((e)==EL_FELSBROCKEN || (e)==EL_EDELSTEIN || (e)==EL_DIAMANT)
-
-#define CAN_MOVE(e)    ((e)==EL_KAEFER || (e)==EL_FLIEGER || (e)==EL_MAMPFER || (e)==EL_ZOMBIE || (e)==EL_PACMAN)
-
-#define COULD_MOVE(e)  (((e)>=EL_KAEFER_R && (e)<=EL_KAEFER_U) || ((e)>=EL_FLIEGER_R && (e)<=EL_FLIEGER_U) || ((e)>=EL_PACMAN_R && (e)==EL_PACMAN_U))
-
-#define DONT_TOUCH(e)  ((e)==EL_KAEFER || (e)==EL_FLIEGER)
-#define DONT_GO_TO(e)  (IS_ENEMY(e) || (e)==EL_TROPFEN || (e)==EL_SALZSAEURE)
-
-#define IS_CHAR(e)     ((e)>=EL_CHAR_START && (e)<=EL_CHAR_END)
-
-*/
-
-
 #define EP_BIT_AMOEBALIVE      (1<<0)
 #define EP_BIT_AMOEBOID                (1<<1)
 #define EP_BIT_BADEWANNOID     (1<<2)
@@ -110,14 +80,16 @@ typedef int BOOL;
 #define EP_BIT_MASSIV          (1<<6)
 #define EP_BIT_SLIPPERY                (1<<7)
 #define EP_BIT_ENEMY           (1<<8)
-#define EP_BIT_CAN_FALL                (1<<9)
-#define EP_BIT_CAN_SMASH       (1<<10)
-#define EP_BIT_CAN_CHANGE      (1<<11)
-#define EP_BIT_CAN_MOVE                (1<<12)
-#define EP_BIT_COULD_MOVE      (1<<13)
-#define EP_BIT_DONT_TOUCH      (1<<14)
-#define EP_BIT_DONT_GO_TO      (1<<15)
-#define EP_BIT_CHAR            (1<<16)
+#define EP_BIT_MAUER           (1<<9)
+#define EP_BIT_CAN_FALL                (1<<10)
+#define EP_BIT_CAN_SMASH       (1<<11)
+#define EP_BIT_CAN_CHANGE      (1<<12)
+#define EP_BIT_CAN_MOVE                (1<<13)
+#define EP_BIT_COULD_MOVE      (1<<14)
+#define EP_BIT_DONT_TOUCH      (1<<15)
+#define EP_BIT_DONT_GO_TO      (1<<16)
+#define EP_BIT_MAMPF2          (1<<17)
+#define EP_BIT_CHAR            (1<<18)
 
 #define IS_AMOEBALIVE(e)       (Elementeigenschaften[e] & EP_BIT_AMOEBALIVE)
 #define IS_AMOEBOID(e)         (Elementeigenschaften[e] & EP_BIT_AMOEBOID)
@@ -128,6 +100,7 @@ typedef int BOOL;
 #define IS_MASSIV(e)           (Elementeigenschaften[e] & EP_BIT_MASSIV)
 #define IS_SLIPPERY(e)         (Elementeigenschaften[e] & EP_BIT_SLIPPERY)
 #define IS_ENEMY(e)            (Elementeigenschaften[e] & EP_BIT_ENEMY)
+#define IS_MAUER(e)            (Elementeigenschaften[e] & EP_BIT_MAUER)
 #define CAN_FALL(e)            (Elementeigenschaften[e] & EP_BIT_CAN_FALL)
 #define CAN_SMASH(e)           (Elementeigenschaften[e] & EP_BIT_CAN_SMASH)
 #define CAN_CHANGE(e)          (Elementeigenschaften[e] & EP_BIT_CAN_CHANGE)
@@ -135,10 +108,15 @@ typedef int BOOL;
 #define COULD_MOVE(e)          (Elementeigenschaften[e] & EP_BIT_COULD_MOVE)
 #define DONT_TOUCH(e)          (Elementeigenschaften[e] & EP_BIT_DONT_TOUCH)
 #define DONT_GO_TO(e)          (Elementeigenschaften[e] & EP_BIT_DONT_GO_TO)
+#define IS_MAMPF2(e)           (Elementeigenschaften[e] & EP_BIT_MAMPF2)
 #define IS_CHAR(e)             (Elementeigenschaften[e] & EP_BIT_CHAR)
 
 #define EL_CHANGED(e)          ((e)==EL_FELSBROCKEN ? EL_EDELSTEIN :   \
                                 (e)==EL_EDELSTEIN   ? EL_DIAMANT :     \
+                                (e)==EL_EDELSTEIN2   ? EL_DIAMANT :    \
+                                (e)==EL_EDELSTEIN3   ? EL_DIAMANT :    \
+                                EL_FELSBROCKEN)
+#define EL_CHANGED2(e)         ((e)==EL_FELSBROCKEN ? EL_EDELSTEIN2 :  \
                                 EL_FELSBROCKEN)
 #define IS_DRAWABLE(e)         ((e)<EL_BLOCKED)
 #define IS_NOT_DRAWABLE(e)     ((e)>=EL_BLOCKED)
@@ -164,7 +142,8 @@ typedef int BOOL;
 #define MAX_NAMELEN            (10+1)
 
 #define MAX_LEVNAMLEN          32
-#define MAX_SC_ENTRIES         15
+#define MAX_LEVSCORE_ENTRIES   16
+#define NUM_FREE_LVHD_BYTES    18
 #define MAX_TAPELEN            10000
 
 #define MAX_LEVDIR_FILENAME    (64+1)
@@ -204,12 +183,12 @@ struct LevelInfo
   int time;
   int edelsteine;
   char name[MAX_LEVNAMLEN];
-  int score[MAX_SC_ENTRIES];
-  int amoebe_inhalt;
+  int score[MAX_LEVSCORE_ENTRIES];
   int mampfer_inhalt[4][3][3];
   int tempo_amoebe;
   int dauer_sieb;
   int dauer_ablenk;
+  int amoebe_inhalt;
 };
 
 struct LevelDirInfo
@@ -288,6 +267,7 @@ extern int          Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern int             Store2[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];
 extern int             AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern int             AmoebaCnt[MAX_NUM_AMOEBA];
 extern long            Elementeigenschaften[MAX_ELEMENTS];
@@ -297,6 +277,7 @@ extern int          lev_fieldx,lev_fieldy, scroll_x,scroll_y;
 
 extern int             LevelSolved,GameOver, JX,JY, ZX,ZY;
 extern int             Gems,Dynamite,Key[4],TimeLeft,Score,MampferNr;
+extern int             DynaBombCount, DynaBombSize, DynaBombsLeft;
 extern int             CheckMoving,CheckExploding, SiebAktiv;
 
 extern struct LevelDirInfo     leveldir[];
@@ -354,9 +335,9 @@ extern char        *progname;
 #define GFX_STARTX             SX
 #define GFX_STARTY             SY
 #define MINI_GFX_STARTX                SX
-#define MINI_GFX_STARTY                432
+#define MINI_GFX_STARTY                424
 #define MICRO_GFX_STARTX       SX
-#define MICRO_GFX_STARTY       528
+#define MICRO_GFX_STARTY       536
 #define GFX_PER_LINE           16
 #define MINI_GFX_PER_LINE      32
 #define MICRO_GFX_PER_LINE     128
@@ -423,6 +404,17 @@ extern char               *progname;
 #define EL_AMOEBA2DIAM 52
 #define EL_ZEIT_VOLL   53
 #define EL_ZEIT_LEER   54
+#define EL_MAUER_LEBT  55
+#define EL_EDELSTEIN2  56
+#define EL_EDELSTEIN3  57
+#define EL_ERZ_EDEL2   58
+#define EL_ERZ_EDEL3   59
+#define EL_MAMPFER2    60
+#define EL_SIEB2_LEER  61
+#define EL_SIEB2_VOLL  62
+#define EL_DYNABOMB    63
+#define EL_DYNABOMB_NR 64
+#define EL_DYNABOMB_SZ 65
 
 #define EL_SPIELER1    80
 #define EL_SPIELER2    81
@@ -449,6 +441,7 @@ extern char        *progname;
 #define EL_SIEB_TOT    105
 #define EL_AUSGANG_ACT 106
 #define EL_AUSGANG_AUF 107
+#define EL_SIEB2_TOT   108
 
 #define EL_CHAR_START  120
 #define EL_CHAR_ASCII0 (EL_CHAR_START-32)
@@ -488,6 +481,7 @@ extern char        *progname;
 #define EL_BLURB_LEFT  303
 #define EL_BLURB_RIGHT 304
 #define EL_AMOEBING    305
+#define EL_MAUERND     306
 
 /* names for the graphic objects */
 /* Zeile 0 (0) */
@@ -499,7 +493,8 @@ extern char        *progname;
 #define GFX_BETON      4
 #define        GFX_MAUERWERK   5
 #define        GFX_FELSBODEN   6
-#define GFX_BOMBE_MM   7
+#define GFX_DYNABOMB   7
+#define GFX_DYNABOMB_NR        GFX_DYNABOMB
 #define        GFX_EDELSTEIN   8
 #define GFX_DIAMANT    10
 #define        GFX_FELSBROCKEN 12
@@ -531,9 +526,6 @@ extern char        *progname;
 #define GFX_PFORTE2X   41
 #define GFX_PFORTE3X   42
 #define GFX_PFORTE4X   43
-#define        GFX_AUSGANG_ZU  44
-#define        GFX_AUSGANG_ACT 44
-#define        GFX_AUSGANG_AUF 47
 /* Zeile 3 (48) */
 #define GFX_DYNAMIT_AUS        48
 #define GFX_DYNAMIT    49
@@ -568,6 +560,8 @@ extern char        *progname;
 #define GFX_AMOEBE_NORM        GFX_AMOEBE_LEBT
 #define GFX_AMOEBE_TOT 108
 #define GFX_AMOEBA2DIAM        GFX_AMOEBE_TOT
+#define GFX_BIRNE_AUS  112
+#define GFX_BIRNE_EIN  113
 #define GFX_ZEIT_VOLL  114
 #define GFX_ZEIT_LEER  115
 /* Zeile 7 (112) */
@@ -578,15 +572,33 @@ extern char              *progname;
 #define GFX_SIEB_TOT   GFX_SIEB_LEER
 #define GFX_ERZ_EDEL   132
 #define GFX_ERZ_DIAM   133
-#define GFX_BIRNE_AUS  134
-#define GFX_BIRNE_EIN  135
+#define GFX_ERZ_EDEL2  134
+#define GFX_ERZ_EDEL3  135
 #define GFX_AMOEBE_VOLL        136
 #define GFX_KUGEL_ROT  140
 #define GFX_KUGEL_BLAU 141
 #define GFX_KUGEL_GELB 142
+#define GFX_KUGEL_GRAU 143
+#define GFX_DYNABOMB_SZ        GFX_KUGEL_GRAU
 /* Zeile 9 (144) */
 #define GFX_BLURB_LEFT 144
 #define GFX_BLURB_RIGHT        148
+#define GFX_EDELSTEIN3 152
+/* Zeile 10 (160) */
+#define GFX_EDELSTEIN2 163
+#define GFX_MAUER_R1   165
+#define GFX_MAUER_R    167
+#define GFX_MAUER_L1   168
+#define GFX_MAUER_L    170
+#define GFX_MAUER_LEBT 171
+#define GFX_SIEB2_LEER 172
+#define GFX_SIEB2_VOLL GFX_SIEB2_LEER
+#define GFX_SIEB2_TOT  GFX_SIEB2_LEER
+/* Zeile 11 (176) */
+#define        GFX_AUSGANG_ZU  176
+#define        GFX_AUSGANG_ACT 177
+#define        GFX_AUSGANG_AUF 180
+#define GFX_MAMPFER2   184
 
 #define        GFX_SCHLUESSEL  GFX_SCHLUESSEL1
 
index 5246fa82a76ce42a2bf6cde9990c401802621ba7..f26a200b2f3fb65247c5fc5465d50163358d918f 100644 (file)
@@ -118,15 +118,18 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
   {
     static long level_delay = 0;
     int step = (button==1 ? 1 : button==2 ? 5 : 10);
+    int new_level_nr, old_level_nr = level_nr;
 
-    if (!DelayReached(&level_delay,20))
+    new_level_nr = level_nr + (x==11 ? -step : +step);
+    if (new_level_nr<0)
+      new_level_nr = 0;
+    if (new_level_nr>LEVELDIR_SIZE(leveldir[leveldir_nr])-1)
+      new_level_nr = LEVELDIR_SIZE(leveldir[leveldir_nr])-1;
+
+    if (old_level_nr==new_level_nr || !DelayReached(&level_delay,20))
       goto out;
 
-    level_nr += (x==11 ? -step : +step);
-    if (level_nr<0)
-      level_nr = 0;
-    if (level_nr>LEVELDIR_SIZE(leveldir[leveldir_nr])-1)
-      level_nr = LEVELDIR_SIZE(leveldir[leveldir_nr])-1;
+    level_nr = new_level_nr;
 
     if (level_nr>player.handicap && level_nr<leveldir[leveldir_nr].num_ready)
     {
@@ -233,25 +236,37 @@ static int helpscreen_frame[MAX_HELPSCREEN_ELS];
 static int helpscreen_delay[MAX_HELPSCREEN_ELS];
 static int helpscreen_action[] =
 {
+  GFX_SPIELFIGUR,1,100,                                                HA_NEXT,
   GFX_ERDREICH,1,100,                                          HA_NEXT,
   GFX_LEERRAUM,1,100,                                          HA_NEXT,
   GFX_MORAST_LEER,1,100,                                       HA_NEXT,
   GFX_BETON,1,100,                                             HA_NEXT,
   GFX_MAUERWERK,1,100,                                         HA_NEXT,
+  GFX_MAUER_R1,3,4, GFX_MAUERWERK,1,20, GFX_LEERRAUM,1,10,
+  GFX_MAUER_L1,3,4, GFX_MAUERWERK,1,20, GFX_LEERRAUM,1,10,     HA_NEXT,
+  GFX_UNSICHTBAR,1,100,                                                HA_NEXT,
   GFX_FELSBODEN,1,100,                                         HA_NEXT,
+  GFX_CHAR_A,30,3, GFX_CHAR_AUSRUF,32,3,                       HA_NEXT,
   GFX_EDELSTEIN,2,5,                                           HA_NEXT,
   GFX_DIAMANT,2,5,                                             HA_NEXT,
+  GFX_EDELSTEIN2,2,5,                                          HA_NEXT,
+  GFX_EDELSTEIN3,2,5,                                          HA_NEXT,
   GFX_FELSBROCKEN,4,5,                                         HA_NEXT,
   GFX_BOMBE,1,50, GFX_EXPLOSION,8,1, GFX_LEERRAUM,1,10,                HA_NEXT,
   GFX_KOKOSNUSS,1,50, GFX_CRACKINGNUT,3,1, GFX_EDELSTEIN,1,10, HA_NEXT,
   GFX_ERZ_EDEL,1,50, GFX_EXPLOSION,8,1, GFX_EDELSTEIN,1,10,    HA_NEXT,
   GFX_ERZ_DIAM,1,50, GFX_EXPLOSION,8,1, GFX_DIAMANT,1,10,      HA_NEXT,
+  GFX_ERZ_EDEL2,1,50, GFX_EXPLOSION,8,1, GFX_EDELSTEIN2,1,10,  HA_NEXT,
+  GFX_ERZ_EDEL3,1,50, GFX_EXPLOSION,8,1, GFX_EDELSTEIN3,1,10,  HA_NEXT,
   GFX_GEBLUBBER,4,4,                                           HA_NEXT,
   GFX_SCHLUESSEL1,4,33,                                                HA_NEXT,
   GFX_PFORTE1,4,33,                                            HA_NEXT,
   GFX_PFORTE1X,4,33,                                           HA_NEXT,
   GFX_DYNAMIT_AUS,1,100,                                       HA_NEXT,
   GFX_DYNAMIT,7,6, GFX_EXPLOSION,8,1, GFX_LEERRAUM,1,10,       HA_NEXT,
+  GFX_DYNABOMB,1,33, GFX_EXPLOSION,8,1, GFX_LEERRAUM,1,10,     HA_NEXT,
+  GFX_DYNABOMB_NR,1,100,                                       HA_NEXT,
+  GFX_DYNABOMB_SZ,1,100,                                       HA_NEXT,
   GFX_FLIEGER+4,1,3, GFX_FLIEGER+0,1,3, GFX_FLIEGER+4,1,3,
   GFX_FLIEGER+5,1,3, GFX_FLIEGER+1,1,3, GFX_FLIEGER+5,1,3,
   GFX_FLIEGER+6,1,3, GFX_FLIEGER+2,1,3, GFX_FLIEGER+6,1,3,
@@ -266,44 +281,82 @@ static int helpscreen_action[] =
   GFX_PACMAN+3,1,3, GFX_PACMAN+7,1,2, GFX_PACMAN+3,1,3,                HA_NEXT,
   GFX_MAMPFER+0,4,0, GFX_MAMPFER+3,1,0, GFX_MAMPFER+2,1,0,
   GFX_MAMPFER+1,1,0,                                           HA_NEXT,
+  GFX_MAMPFER2+0,4,0, GFX_MAMPFER2+3,1,0, GFX_MAMPFER2+2,1,0,
+  GFX_MAMPFER2+1,1,0,                                          HA_NEXT,
   GFX_ZOMBIE+0,4,0, GFX_ZOMBIE+3,1,0, GFX_ZOMBIE+2,1,0,
   GFX_ZOMBIE+1,1,0,                                            HA_NEXT,
   GFX_ABLENK,4,1,                                              HA_NEXT,
-  GFX_AMOEBE_LEBT,4,40,                                                HA_NEXT,
+  GFX_BIRNE_AUS,1,33, GFX_BIRNE_EIN,1,33,                      HA_NEXT,
+  GFX_ZEIT_VOLL,1,33, GFX_ZEIT_LEER,1,33,                      HA_NEXT,
+  GFX_TROPFEN,1,33, GFX_AMOEBING,4,1, GFX_AMOEBE_LEBT,1,10,    HA_NEXT,
   GFX_AMOEBE_TOT+2,2,50, GFX_AMOEBE_TOT,2,50,                  HA_NEXT,
+  GFX_AMOEBE_LEBT,4,40,                                                HA_NEXT,
+  GFX_AMOEBE_LEBT,1,10,        GFX_AMOEBING,4,2,                       HA_NEXT,
+  GFX_AMOEBE_LEBT,1,33, GFX_AMOEBE_TOT,1,33, GFX_EXPLOSION,8,1,
+  GFX_DIAMANT,1,10,                                            HA_NEXT,
+  GFX_LIFE,1,100,                                              HA_NEXT,
+  GFX_LIFE_ASYNC,1,100,                                                HA_NEXT,
   GFX_SIEB_LEER,4,2,                                           HA_NEXT,
+  GFX_SIEB2_LEER,4,2,                                          HA_NEXT,
+  GFX_AUSGANG_ZU,1,100, GFX_AUSGANG_ACT,4,2,
+  GFX_AUSGANG_AUF+0,4,1, GFX_AUSGANG_AUF+3,1,1,
+  GFX_AUSGANG_AUF+2,1,1, GFX_AUSGANG_AUF+1,1,1,                        HA_NEXT,
+  GFX_AUSGANG_AUF+0,4,1, GFX_AUSGANG_AUF+3,1,1,
+  GFX_AUSGANG_AUF+2,1,1, GFX_AUSGANG_AUF+1,1,1,                        HA_NEXT,
   HA_END
 };
 static char *helpscreen_eltext[][2] =
 {
-  "Normal sand:", "You can dig through it",
-  "Empty field:", "You can walk through it",
-  "Quicksand: You cannot pass it,", "but rocks can fall though it",
-  "Massive Wall:", "Nothing can go through it",
-  "Normal Wall: You can't go through", "it, but you can bomb it away",
-  "Old Wall: Like normal wall, but", "some things can fall down from it",
-  "Emerald: You must collect enough of", "them to finish a level",
-  "Diamond: Counts as 3 emeralds;", "Can be destroyed by rocks",
-  "Rock: Smashes several things;", "Can be moved by the player",
-  "Bomb: You can move it, but be", "careful when dropping it",
-  "Nut: Throw a rock on it to open it;", "Each nut contains an emerald",
-  "Wall with an Emerald inside:", "Bomb the wall away to get it",
-  "Wall with a Diamond inside:", "Bomb the wall away to get it",
-  "Acid: Destroys everything that", "falls or walks into it",
-  "Key: Opens the door that has the", "same color (red/yellow/green/blue)",
-  "Door: Can be opened by the key", "with the same color",
-  "Door: You have to find out the", "right color of the key for it",
-  "Dynamite: Collect it and use it to", "destroy walls or kill enemies",
-  "Dynamite: This one explodes after", "a few seconds",
-  "Spaceship: Moves at the left side", "of walls; don't touch it!",
-  "Bug: Moves at the right side of", "walls; don't touch it!",
-  "Pacman: Eats the amoeba and you,", "if you're not careful",
-  "Cruncher: Eats diamonds and you,", "if you're not careful",
-  "Robot: Tries to kill the player", "",
-  "Magic Wheel: Touch it to get rid of", "the robots for some seconds",
-  "Living Amoeba: Grows through empty", "fields, sand and quicksand",
-  "Dead Amoeba: Does not grow, but", "can still kill bugs and spaceships",
-  "Magic Wall: Changes rocks, emeralds", "and diamonds when they pass it",
+  "THE HERO:",                         "(Is _this_ guy good old Rockford?)",
+  "Normal sand:",                      "You can dig through it",
+  "Empty field:",                      "You can walk through it",
+  "Quicksand: You cannot pass it,",    "but rocks can fall though it",
+  "Massive Wall:",                     "Nothing can go through it",
+  "Normal Wall: You can't go through", "it, but you can bomb it away",
+  "Growing Wall: Grows to the left or",        "right if there is an empty field",
+  "Invisible Wall: Behaves like normal","wall, but is invisible",
+  "Old Wall: Like normal wall, but",   "some things can fall down from it",
+  "Letter Wall: Looks like a letter,", "behaves like a normal wall",
+  "Emerald: You must collect enough of","them to finish a level",
+  "Diamond: Counts as 3 emeralds, but",        "can be destroyed by rocks",
+  "Diamond (BD style): Counts like one","emerald and behaves a bit different",
+  "Red emerald: Seems to behave like", "the BD style diamond",
+  "Rock: Smashes several things;",     "Can be moved by the player",
+  "Bomb: You can move it, but be",     "careful when dropping it",
+  "Nut: Throw a rock on it to open it;","Each nut contains an emerald",
+  "Wall with an emerald inside:",      "Bomb the wall away to get it",
+  "Wall with a diamond inside:",       "Bomb the wall away to get it",
+  "Wall with BD style diamond inside:",        "Bomb the wall away to get it",
+  "Wall with red emerald inside:",     "Bomb the wall away to get it",
+  "Acid: Things that fall in are gone",        "forever (including our hero)",
+  "Key: Opens the door that has the",  "same color (red/yellow/green/blue)",
+  "Door: Can be opened by the key",    "with the same color",
+  "Door: You have to find out the",    "right color of the key for it",
+  "Dynamite: Collect it and use it to",        "destroy walls or kill enemies",
+  "Dynamite: This one explodes after", "a few seconds",
+  "Dyna Bomb: Explodes in 4 directions","with variable explosion size",
+  "Dyna Bomb: Increases the number of",        "dyna bombs available at a time",
+  "Dyna Bomb: Increases the size of",  "explosion of dyna bombs",
+  "Spaceship: Moves at the left side", "of walls; don't touch it!",
+  "Bug: Moves at the right side of",   "walls; don't touch it!",
+  "Pacman: Eats the amoeba and you,",  "if you're not careful",
+  "Cruncher: Eats diamonds and you,",  "if you're not careful",
+  "Cruncher (BD style):",              "Eats almost everything",
+  "Robot: Tries to kill the player",   "",
+  "Magic Wheel: Touch it to get rid of","the robots for some seconds",
+  "Light Bulb: It seems to have no",   "special function, but looks nice",
+  "Extra Time Orb: Adds some seconds", "to the time available for the level",
+  "Amoeba Drop: Grows to an amoeba on",        "the ground - don't touch it",
+  "Dead Amoeba: Does not grow, but",   "can still kill bugs and spaceships",
+  "Normal Amoeba: Grows through empty",        "fields, sand and quicksand",
+  "Dropping Amoeba: This one makes",   "drops that grow to a new amoeba",
+  "Living Amoeba (BD style): Contains",        "other element, when surrounded",
+  "Game Of Life: Behaves like the well","known 'Game Of Life' (2333 style)",
+  "Biomaze: A bit like the 'Game Of",  "Life', but builds crazy mazes",
+  "Magic Wall: Changes rocks, emeralds","and diamonds when they pass it",
+  "Magic Wall (BD style):",            "Changes rocks and BD style diamonds",
+  "Exit door: Opens if you have enough","emeralds to finish the level",
+  "Open exit door: Enter here to leave","the level and exit the actual game",
 };
 static int num_helpscreen_els = sizeof(helpscreen_eltext)/(2*sizeof(char *));
 
@@ -492,6 +545,16 @@ void DrawHelpScreenCreditsText()
   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+4*ystep+60,
           text,FS_SMALL,FC_RED);
 
+  sprintf(text,"If you have created new levels,");
+  DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+7*ystep,
+          text,FS_SMALL,FC_YELLOW);
+  sprintf(text,"send them to me to include them!");
+  DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+8*ystep,
+          text,FS_SMALL,FC_YELLOW);
+  sprintf(text,":-)");
+  DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+ystart+9*ystep,
+          text,FS_SMALL,FC_YELLOW);
+
   sprintf(text,"Press any key or button for main menu");
   DrawText(SX+(SXSIZE-strlen(text)*FONT2_XSIZE)/2,SY+SYSIZE-20,
           text,FS_SMALL,FC_BLUE);
index 625159f316b2366220597d9b4bb945a401aceffd..09da1bd31e6ce2d11bdcfbc4d8482d4fe8ee13c5 100644 (file)
@@ -452,16 +452,17 @@ void DrawElementShifted(int x, int y, int dx, int dy, int element,int cut_mode)
       graphic += 3;
   }
   else if ((element==EL_FELSBROCKEN ||
-           element==EL_EDELSTEIN ||
-           element==EL_DIAMANT) && horiz_move && phase)
+           element==EL_EDELSTEIN || element==EL_EDELSTEIN2 ||
+           element==EL_EDELSTEIN3 || element==EL_DIAMANT)
+          && horiz_move && phase)
   {
     if (element==EL_FELSBROCKEN)
       graphic += 2;
     else
       graphic += 1;
   }
-  else if ((element==EL_SIEB_LEER ||
-           element==EL_SIEB_VOLL) && SiebAktiv)
+  else if ((element==EL_SIEB_LEER || element==EL_SIEB2_LEER ||
+           element==EL_SIEB_VOLL || element==EL_SIEB2_VOLL) && SiebAktiv)
   {
     graphic += 3-(SiebAktiv%8)/2;
   }
@@ -470,6 +471,22 @@ void DrawElementShifted(int x, int y, int dx, int dy, int element,int cut_mode)
     graphic = (element==EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
     graphic += (x+2*y) % 4;
   }
+  else if (element==EL_MAUER_LEBT)
+  {
+    BOOL links_massiv = FALSE, rechts_massiv = FALSE;
+
+    if (!IN_LEV_FIELD(ux-1,uy) || IS_MAUER(Feld[ux-1][uy]))
+      links_massiv = TRUE;
+    if (!IN_LEV_FIELD(ux+1,uy) || IS_MAUER(Feld[ux+1][uy]))
+      rechts_massiv = TRUE;
+
+    if (links_massiv && rechts_massiv)
+      graphic = GFX_MAUERWERK;
+    else if (links_massiv)
+      graphic = GFX_MAUER_R;
+    else if (rechts_massiv)
+      graphic = GFX_MAUER_L;
+  }
 
   if (dx || dy)
     DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode);
@@ -625,10 +642,12 @@ void DrawScreenField(int x, int y)
 
     if (Store[ux][uy]==EL_MORAST_LEER ||
        Store[ux][uy]==EL_SIEB_LEER ||
+       Store[ux][uy]==EL_SIEB2_LEER ||
        Store[ux][uy]==EL_AMOEBE_NASS)
       cut_mode = CUT_ABOVE;
     else if (Store[ux][uy]==EL_MORAST_VOLL ||
        Store[ux][uy]==EL_SIEB_VOLL ||
+       Store[ux][uy]==EL_SIEB2_VOLL ||
        Store[ux][uy]==EL_SALZSAEURE)
       cut_mode = CUT_BELOW;
 
@@ -656,6 +675,7 @@ void DrawScreenField(int x, int y)
 
     if (Store[oldx][oldy]==EL_MORAST_LEER ||
        Store[oldx][oldy]==EL_SIEB_LEER ||
+       Store[oldx][oldy]==EL_SIEB2_LEER ||
        Store[oldx][oldy]==EL_AMOEBE_NASS)
       cut_mode = CUT_ABOVE;
 
@@ -1354,6 +1374,18 @@ int el2gfx(int element)
     case EL_BIRNE_EIN:         return(GFX_BIRNE_EIN);
     case EL_ZEIT_VOLL:         return(GFX_ZEIT_VOLL);
     case EL_ZEIT_LEER:         return(GFX_ZEIT_LEER);
+    case EL_MAUER_LEBT:                return(GFX_MAUER_LEBT);
+    case EL_EDELSTEIN2:                return(GFX_EDELSTEIN2);
+    case EL_EDELSTEIN3:                return(GFX_EDELSTEIN3);
+    case EL_ERZ_EDEL2:         return(GFX_ERZ_EDEL2);
+    case EL_ERZ_EDEL3:         return(GFX_ERZ_EDEL3);
+    case EL_MAMPFER2:          return(GFX_MAMPFER2);
+    case EL_SIEB2_LEER:                return(GFX_SIEB2_LEER);
+    case EL_SIEB2_VOLL:                return(GFX_SIEB2_VOLL);
+    case EL_SIEB2_TOT:         return(GFX_SIEB2_TOT);
+    case EL_DYNABOMB:          return(GFX_DYNABOMB);
+    case EL_DYNABOMB_NR:       return(GFX_DYNABOMB_NR);
+    case EL_DYNABOMB_SZ:       return(GFX_DYNABOMB_SZ);
     default:
     {
       if (IS_CHAR(element))