rnd-19990824-1-src
authorHolger Schemel <info@artsoft.org>
Tue, 24 Aug 1999 00:48:27 +0000 (02:48 +0200)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:34:10 +0000 (10:34 +0200)
src/editor.c
src/game.c
src/main.c
src/main.h
src/tools.c

index fdef6f27911007a9797e417fffcfb4d6de5fcb4b..95af54940eb6959187f49734ba911324c5c9f8bd 100644 (file)
@@ -1071,10 +1071,10 @@ int editor_element[] =
   EL_LIGHT_SWITCH_OFF,
   EL_LIGHT_SWITCH_ON,
 
-  EL_FORCE_FIELD,
+  EL_FORCE_FIELD_PASSIVE,
   EL_EXTRA_TIME,
   EL_LEERRAUM,
-  EL_LEERRAUM,
+  EL_FORCE_FIELD_ACTIVE,
 
   /*
   EL_CHAR('D'),
index fc0d64767d09631bef0d1fb55345d7ab2c7b26f2..96fa706fecafc873fc399fe30d001ccec37e92bb 100644 (file)
 
 /* forward declaration for internal use */
 static void CheckGravityMovement(struct PlayerInfo *);
+static void KillHeroUnlessForceField(struct PlayerInfo *);
 
 static void MapGameButtons();
 static void HandleGameButtons(struct GadgetInfo *);
@@ -475,6 +476,9 @@ void InitGame()
     player->last_jx = player->last_jy = 0;
     player->jx = player->jy = 0;
 
+    player->force_field_passive_time_left = 0;
+    player->force_field_active_time_left = 0;
+
     DigField(player, 0, 0, 0, 0, DF_NO_PUSH);
     SnapField(player, 0, 0);
 
@@ -1240,10 +1244,22 @@ void Explode(int ex, int ey, int phase, int mode)
       if (IS_MASSIVE(element) || element == EL_BURNING)
        continue;
 
+      if (IS_PLAYER(x, y) && FORCE_FIELD_ON(PLAYERINFO(x, y)))
+      {
+       if (IS_ACTIVE_BOMB(element))
+       {
+         /* re-activate things under the bomb like gate or penguin */
+         Feld[x][y] = (Store[x][y] ? Store[x][y] : EL_LEERRAUM);
+         Store[x][y] = 0;
+       }
+
+       continue;
+      }
+
       if (element == EL_EXPLODING)
        element = Store2[x][y];
 
-      if (IS_PLAYER(ex, ey))
+      if (IS_PLAYER(ex, ey) && !FORCE_FIELD_ON(PLAYERINFO(ex, ey)))
       {
        switch(StorePlayer[ex][ey])
        {
@@ -1344,7 +1360,7 @@ void Explode(int ex, int ey, int phase, int mode)
     int element = Store2[x][y];
 
     if (IS_PLAYER(x, y))
-      KillHero(PLAYERINFO(x, y));
+      KillHeroUnlessForceField(PLAYERINFO(x, y));
     else if (IS_EXPLOSIVE(element))
     {
       Feld[x][y] = Store2[x][y];
@@ -1444,8 +1460,10 @@ void Bang(int x, int y)
   else
     PlaySoundLevel(x, y, SND_ROAAAR);
 
+#if 0
   if (IS_PLAYER(x, y)) /* remove objects that might cause smaller explosion */
     element = EL_LEERRAUM;
+#endif
 
   switch(element)
   {
@@ -1473,7 +1491,10 @@ void Bang(int x, int y)
     case EL_PINGUIN:
     case EL_BIRNE_AUS:
     case EL_BIRNE_EIN:
-      Explode(x, y, EX_PHASE_START, EX_CENTER);
+      if (IS_PLAYER(x, y))
+       Explode(x, y, EX_PHASE_START, EX_NORMAL);
+      else
+       Explode(x, y, EX_PHASE_START, EX_CENTER);
       break;
     default:
       Explode(x, y, EX_PHASE_START, EX_NORMAL);
@@ -1686,7 +1707,7 @@ void Impact(int x, int y)
   if (element == EL_TROPFEN && (lastline || object_hit))       /* acid drop */
   {
     if (object_hit && IS_PLAYER(x, y+1))
-      KillHero(PLAYERINFO(x, y+1));
+      KillHeroUnlessForceField(PLAYERINFO(x, y+1));
     else if (object_hit && (smashed == EL_MAULWURF || smashed == EL_PINGUIN))
       Bang(x, y+1);
     else
@@ -1719,7 +1740,7 @@ void Impact(int x, int y)
 
     if (IS_PLAYER(x, y+1))
     {
-      KillHero(PLAYERINFO(x, y+1));
+      KillHeroUnlessForceField(PLAYERINFO(x, y+1));
       return;
     }
     else if (smashed == EL_MAULWURF || smashed == EL_PINGUIN)
@@ -1889,10 +1910,10 @@ void TurnRound(int x, int y)
     TestIfBadThingHitsOtherBadThing(x, y);
 
     if (IN_LEV_FIELD(right_x, right_y) &&
-       IS_FREE_OR_PLAYER(right_x, right_y))
+       IS_FREE(right_x, right_y))
       MovDir[x][y] = right_dir;
     else if (!IN_LEV_FIELD(move_x, move_y) ||
-            !IS_FREE_OR_PLAYER(move_x, move_y))
+            !IS_FREE(move_x, move_y))
       MovDir[x][y] = left_dir;
 
     if (element == EL_KAEFER && MovDir[x][y] != old_move_dir)
@@ -1906,10 +1927,10 @@ void TurnRound(int x, int y)
     TestIfBadThingHitsOtherBadThing(x, y);
 
     if (IN_LEV_FIELD(left_x, left_y) &&
-       IS_FREE_OR_PLAYER(left_x, left_y))
+       IS_FREE(left_x, left_y))
       MovDir[x][y] = left_dir;
     else if (!IN_LEV_FIELD(move_x, move_y) ||
-            !IS_FREE_OR_PLAYER(move_x, move_y))
+            !IS_FREE(move_x, move_y))
       MovDir[x][y] = right_dir;
 
     if ((element == EL_FLIEGER ||
@@ -2496,12 +2517,20 @@ void StartMoving(int x, int y)
 
     Moving2Blocked(x, y, &newx, &newy);        /* get next screen position */
 
-    if (IS_ENEMY(element) && IS_PLAYER(newx, newy))
+    if (IS_ENEMY(element) && IS_PLAYER(newx, newy) &&
+       !FORCE_FIELD_ON(PLAYERINFO(newx, newy)))
     {
+
+#if 1
+      TestIfBadThingHitsHero(x, y);
+      return;
+#else
       /* enemy got the player */
       MovDir[x][y] = 0;
       KillHero(PLAYERINFO(newx, newy));
       return;
+#endif
+
     }
     else if ((element == EL_MAULWURF || element == EL_PINGUIN ||
              element == EL_ROBOT || element == EL_SONDE) &&
@@ -3977,8 +4006,10 @@ void GameActions()
       CloseSwitchgate(x, y);
     else if (element == EL_EXTRA_TIME)
       DrawGraphicAnimation(x, y, GFX_EXTRA_TIME, 6, 4, ANIM_NORMAL);
-    else if (element == EL_FORCE_FIELD)
-      DrawGraphicAnimation(x, y, GFX_FORCE_FIELD, 6, 4, ANIM_NORMAL);
+    else if (element == EL_FORCE_FIELD_PASSIVE)
+      DrawGraphicAnimation(x, y, GFX_FORCE_FIELD_PASSIVE, 6, 4, ANIM_NORMAL);
+    else if (element == EL_FORCE_FIELD_ACTIVE)
+      DrawGraphicAnimation(x, y, GFX_FORCE_FIELD_ACTIVE, 6, 4, ANIM_NORMAL);
 
     if (game.magic_wall_active)
     {
@@ -4061,11 +4092,22 @@ void GameActions()
     }
   }
 
-  if (TimeFrames >= (1000 / GameFrameDelay) && !tape.pausing)
+  if (TimeFrames >= (1000 / GameFrameDelay))
   {
     TimeFrames = 0;
     TimePlayed++;
 
+    for (i=0; i<MAX_PLAYERS; i++)
+    {
+      if (FORCE_FIELD_ON(&stored_player[i]))
+      {
+       stored_player[i].force_field_passive_time_left--;
+
+       if (stored_player[i].force_field_active_time_left > 0)
+         stored_player[i].force_field_active_time_left--;
+      }
+    }
+
     if (tape.recording || tape.playing)
       DrawVideoDisplay(VIDEO_STATE_TIME_ON, TimePlayed);
 
@@ -4223,7 +4265,14 @@ boolean MoveFigureOneStep(struct PlayerInfo *player,
       BuryHero(player);
     }
     else
-      KillHero(player);
+    {
+#if 1
+      TestIfBadThingHitsHero(new_jx, new_jy);
+#else
+      if (player->force_field_time_left == 0)
+       KillHero(player);
+#endif
+    }
 
     return MF_MOVING;
   }
@@ -4537,7 +4586,14 @@ void TestIfGoodThingHitsBadThing(int goodx, int goody)
   if (killx != goodx || killy != goody)
   {
     if (IS_PLAYER(goodx, goody))
-      KillHero(PLAYERINFO(goodx, goody));
+    {
+      struct PlayerInfo *player = PLAYERINFO(goodx, goody);
+
+      if (player->force_field_active_time_left > 0)
+       Bang(killx, killy);
+      else if (player->force_field_passive_time_left == 0)
+       KillHero(player);
+    }
     else
       Bang(goodx, goody);
   }
@@ -4592,7 +4648,14 @@ void TestIfBadThingHitsGoodThing(int badx, int bady)
   if (killx != badx || killy != bady)
   {
     if (IS_PLAYER(killx, killy))
-      KillHero(PLAYERINFO(killx, killy));
+    {
+      struct PlayerInfo *player = PLAYERINFO(killx, killy);
+
+      if (player->force_field_active_time_left > 0)
+       Bang(badx, bady);
+      else if (player->force_field_passive_time_left == 0)
+       KillHero(player);
+    }
     else
       Bang(killx, killy);
   }
@@ -4662,10 +4725,20 @@ void KillHero(struct PlayerInfo *player)
   if (IS_PFORTE(Feld[jx][jy]))
     Feld[jx][jy] = EL_LEERRAUM;
 
+  /* deactivate force field (else Bang()/Explode() would not work right) */
+  player->force_field_passive_time_left = 0;
+  player->force_field_active_time_left = 0;
+
   Bang(jx, jy);
   BuryHero(player);
 }
 
+static void KillHeroUnlessForceField(struct PlayerInfo *player)
+{
+  if (!FORCE_FIELD_ON(player))
+    KillHero(player);
+}
+
 void BuryHero(struct PlayerInfo *player)
 {
   int jx = player->jx, jy = player->jy;
@@ -4787,8 +4860,16 @@ int DigField(struct PlayerInfo *player,
       PlaySoundStereo(SND_GONG, PSND_MAX_RIGHT);
       break;
 
-    case EL_FORCE_FIELD:
+    case EL_FORCE_FIELD_PASSIVE:
+      RemoveField(x, y);
+      player->force_field_passive_time_left += 10;
+      PlaySoundLevel(x, y, SND_PONG);
+      break;
+
+    case EL_FORCE_FIELD_ACTIVE:
       RemoveField(x, y);
+      player->force_field_passive_time_left += 10;
+      player->force_field_active_time_left += 10;
       PlaySoundLevel(x, y, SND_PONG);
       break;
 
index dac98c0f266f06eb8807be35f0c8189a80e617e7..daa3408176e44c6f698425e2e89b8f6288f583dc 100644 (file)
@@ -463,7 +463,7 @@ char *element_info[] =
   "white door",                                        /* 260 */
   "gray door (opened by white key)",
   "white key",
-  "force field",
+  "force field (passive)",
   "extra time",
   "switch gate (open)",
   "switch gate (closed)",
@@ -517,10 +517,11 @@ char *element_info[] =
   "mole (starts moving down)",
   "steel wall (slanted)",
   "invisible sand",
-  "-",
-  "-",
-  "-",
-  "-",                                         /* 320 */
+  "dx unknown 15",
+  "dx unknown 42",
+  "dx unknown 229",
+  "dx unknown 233",                            /* 320 */
+  "force field (active, kills enemies)",
   "-",
   "-",
   "-",
index 5cfda96e0ec68531089cbfc9c44b0ada4fd3fad1..9ae8be8755859d1db69733f117162c43f50ae2e8 100644 (file)
@@ -191,6 +191,7 @@ typedef unsigned char byte;
 #define TAPE_IS_STOPPED(x)     (!(x).recording && !(x).playing &&!(x).pausing)
 
 #define PLAYERINFO(x,y)                (&stored_player[StorePlayer[x][y]-EL_SPIELER1])
+#define FORCE_FIELD_ON(p)      ((p)->force_field_passive_time_left > 0)
 
 /* Pixmaps with graphic file */
 #define PIX_BACK               0
@@ -353,6 +354,8 @@ struct PlayerInfo
   int key[4];
   int dynamite;
   int dynabomb_count, dynabomb_size, dynabombs_left, dynabomb_xl;
+  int force_field_passive_time_left;
+  int force_field_active_time_left;
 };
 
 struct LevelInfo
@@ -850,7 +853,7 @@ extern char         *element_info[];
 #define EL_DOOR_WHITE          260
 #define EL_DOOR_WHITE_GRAY     261
 #define EL_KEY_WHITE           262
-#define EL_FORCE_FIELD         263
+#define EL_FORCE_FIELD_PASSIVE 263
 #define EL_EXTRA_TIME          264
 #define EL_SWITCHGATE_OPEN     265
 #define EL_SWITCHGATE_CLOSED   266
@@ -904,6 +907,11 @@ extern char                *element_info[];
 #define EL_MOLE_DOWN           314
 #define EL_STEEL_SLANTED       315
 #define EL_SAND_INVISIBLE      316
+#define EL_DX_UNKNOWN_15       317
+#define EL_DX_UNKNOWN_42       318
+#define EL_DX_UNKNOWN_229      319
+#define EL_DX_UNKNOWN_233      320
+#define EL_FORCE_FIELD_ACTIVE  321
 
 /* "real" (and therefore drawable) runtime elements */
 #define EL_SIEB_LEER           500
@@ -1321,7 +1329,8 @@ extern char               *element_info[];
 #define GFX_STEEL_SLANTED      (GFX_START_ROCKSDC + 15 * DC_PER_LINE +  5)
 
 #define GFX_EXTRA_TIME         (GFX_START_ROCKSDC +  0 * DC_PER_LINE +  8)
-#define GFX_FORCE_FIELD                (GFX_START_ROCKSDC +  1 * DC_PER_LINE +  8)
+#define GFX_FORCE_FIELD_PASSIVE        (GFX_START_ROCKSDC +  1 * DC_PER_LINE +  8)
+#define GFX_FORCE_FIELD_ACTIVE (GFX_START_ROCKSDC +  1 * DC_PER_LINE +  8)
 
 /* graphics from "RocksFont" */
 #define GFX_CHAR_START         (GFX_START_ROCKSFONT)
@@ -1379,6 +1388,10 @@ extern char              *element_info[];
 #define GFX_MOLE_RIGHT         GFX_CHAR_FRAGE
 #define GFX_MOLE_UP            GFX_CHAR_FRAGE
 #define GFX_MOLE_DOWN          GFX_CHAR_FRAGE
+#define GFX_DX_UNKNOWN_15      GFX_CHAR_FRAGE
+#define GFX_DX_UNKNOWN_42      GFX_CHAR_FRAGE
+#define GFX_DX_UNKNOWN_229     GFX_CHAR_FRAGE
+#define GFX_DX_UNKNOWN_233     GFX_CHAR_FRAGE
 
 /* the names of the sounds */
 #define SND_ALCHEMY            0
index 41fd86eb12a560033ca6864d414deb58862f4cbe..4403a9cedd220d636cae487874bc1b282a8ce31c 100644 (file)
@@ -44,6 +44,8 @@ extern boolean wait_for_vsync;
 
 /* forward declaration for internal use */
 static int getGraphicAnimationPhase(int, int, int);
+static void DrawGraphicAnimationShiftedThruMask(int, int, int, int, int,
+                                               int, int, int);
 static void UnmapToolButtons();
 static void HandleToolButtons(struct GadgetInfo *);
 
@@ -604,6 +606,10 @@ void DrawPlayer(struct PlayerInfo *player)
 
   DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
 
+  if (FORCE_FIELD_ON(player))
+    DrawGraphicAnimationShiftedThruMask(sx, sy, sxx, syy, GFX_FUNKELN_BLAU,
+                                       3, 8, ANIM_OSCILLATE);
+
   if (player->Pushing && player->GfxPos)
   {
     int px = SCREENX(next_jx), py = SCREENY(next_jy);
@@ -732,6 +738,17 @@ void DrawGraphicAnimationThruMask(int x, int y, int graphic,
   DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
 }
 
+static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
+                                               int sxx, int syy,
+                                               int graphic,
+                                               int frames, int delay,
+                                               int mode)
+{
+  int phase = getGraphicAnimationPhase(frames, delay, mode);
+
+  DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
+}
+
 void getGraphicSource(int graphic, int *pixmap_nr, int *x, int *y)
 {
   if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
@@ -2487,7 +2504,8 @@ int el2gfx(int element)
     case EL_DOOR_WHITE:                return GFX_DOOR_WHITE;
     case EL_DOOR_WHITE_GRAY:   return GFX_DOOR_WHITE_GRAY;
     case EL_KEY_WHITE:         return GFX_KEY_WHITE;
-    case EL_FORCE_FIELD:       return GFX_FORCE_FIELD;
+    case EL_FORCE_FIELD_PASSIVE:return GFX_FORCE_FIELD_PASSIVE;
+    case EL_FORCE_FIELD_ACTIVE:        return GFX_FORCE_FIELD_ACTIVE;
     case EL_EXTRA_TIME:                return GFX_EXTRA_TIME;
     case EL_SWITCHGATE_OPEN:   return GFX_SWITCHGATE_OPEN;
     case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
@@ -2541,6 +2559,10 @@ int el2gfx(int element)
     case EL_MOLE_DOWN:         return GFX_MOLE_DOWN;
     case EL_STEEL_SLANTED:     return GFX_STEEL_SLANTED;
     case EL_SAND_INVISIBLE:    return GFX_SAND_INVISIBLE;
+    case EL_DX_UNKNOWN_15:     return GFX_DX_UNKNOWN_15;
+    case EL_DX_UNKNOWN_42:     return GFX_DX_UNKNOWN_42;
+    case EL_DX_UNKNOWN_229:    return GFX_DX_UNKNOWN_229;
+    case EL_DX_UNKNOWN_233:    return GFX_DX_UNKNOWN_233;
 
     default:
     {