rnd-20031207-1-src
[rocksndiamonds.git] / src / tools.c
index d98a4c1bb7085590176e46f3ed4f07274bc452e1..106d251ed5c7d45d01c0dcde7be7d1324f4e43b7 100644 (file)
@@ -91,8 +91,8 @@ void RedrawPlayfield(boolean force_redraw, int x, int y, int width, int height)
       if (setup.direct_draw)
        SetDrawtoField(DRAW_BACKBUFFER);
 
-      for(xx=BX1; xx<=BX2; xx++)
-       for(yy=BY1; yy<=BY2; yy++)
+      for (xx = BX1; xx <= BX2; xx++)
+       for (yy = BY1; yy <= BY2; yy++)
          if (xx >= x1 && xx <= x2 && yy >= y1 && yy <= y2)
            DrawScreenField(xx, yy);
       DrawAllPlayers();
@@ -263,8 +263,8 @@ void BackToFront()
 
   if (redraw_mask & REDRAW_TILES)
   {
-    for(x=0; x<SCR_FIELDX; x++)
-      for(y=0; y<SCR_FIELDY; y++)
+    for (x = 0; x < SCR_FIELDX; x++)
+      for (y =0 ; y < SCR_FIELDY; y++)
        if (redraw[redraw_x1 + x][redraw_y1 + y])
          BlitBitmap(buffer, window,
                     FX + x * TILEX, FX + y * TILEY, TILEX, TILEY,
@@ -286,8 +286,8 @@ void BackToFront()
 
   FlushDisplay();
 
-  for(x=0; x<MAX_BUF_XSIZE; x++)
-    for(y=0; y<MAX_BUF_YSIZE; y++)
+  for (x = 0; x < MAX_BUF_XSIZE; x++)
+    for (y = 0; y < MAX_BUF_YSIZE; y++)
       redraw[x][y] = 0;
   redraw_tiles = 0;
   redraw_mask = REDRAW_NONE;
@@ -308,9 +308,9 @@ void FadeToFront()
     ClearRectangle(window, REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
     FlushDisplay();
 
-    for(i=0;i<2*FULL_SYSIZE;i++)
+    for (i = 0; i < 2 * FULL_SYSIZE; i++)
     {
-      for(y=0;y<FULL_SYSIZE;y++)
+      for (y = 0; y < FULL_SYSIZE; y++)
       {
        BlitBitmap(backbuffer, window,
                   REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
@@ -321,7 +321,7 @@ void FadeToFront()
 #endif
 
 #if 0
-    for(i=1;i<FULL_SYSIZE;i+=2)
+    for (i = 1; i < FULL_SYSIZE; i+=2)
       BlitBitmap(backbuffer, window,
                 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
     FlushDisplay();
@@ -424,9 +424,9 @@ void SetBorderElement()
 
   BorderElement = EL_EMPTY;
 
-  for(y=0; y<lev_fieldy && BorderElement == EL_EMPTY; y++)
+  for (y = 0; y < lev_fieldy && BorderElement == EL_EMPTY; y++)
   {
-    for(x=0; x<lev_fieldx; x++)
+    for (x = 0; x < lev_fieldx; x++)
     {
       if (!IS_INDESTRUCTIBLE(Feld[x][y]))
        BorderElement = EL_STEELWALL;
@@ -486,7 +486,7 @@ void DrawLevelGraphicAnimation(int x, int y, int graphic)
 void DrawLevelElementAnimation(int x, int y, int element)
 {
 #if 1
-  int graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]);
+  int graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]);
 
   DrawGraphicAnimation(SCREENX(x), SCREENY(y), graphic);
 #else
@@ -518,7 +518,7 @@ void DrawLevelElementAnimationIfNeeded(int x, int y, int element)
   if (!IN_LEV_FIELD(x, y) || !IN_SCR_FIELD(sx, sy))
     return;
 
-  graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]);
+  graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]);
 
   if (!IS_NEW_FRAME(GfxFrame[x][y], graphic))
     return;
@@ -529,11 +529,48 @@ void DrawLevelElementAnimationIfNeeded(int x, int y, int element)
     DrawLevelFieldCrumbledSand(x, y);
 }
 
+static int getPlayerGraphic(struct PlayerInfo *player, int move_dir)
+{
+  if (player->use_murphy_graphic)
+  {
+    /* this works only because currently only one player can be "murphy" ... */
+    static int last_horizontal_dir = MV_LEFT;
+    int graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, move_dir);
+
+    if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
+      last_horizontal_dir = move_dir;
+
+    if (graphic == IMG_SP_MURPHY)      /* undefined => use special graphic */
+    {
+      int direction = (player->is_snapping ? move_dir : last_horizontal_dir);
+
+      graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, direction);
+    }
+
+    return graphic;
+  }
+  else
+    return el_act_dir2img(player->element_nr, player->GfxAction, move_dir);
+}
+
+static boolean equalGraphics(int graphic1, int graphic2)
+{
+  struct GraphicInfo *g1 = &graphic_info[graphic1];
+  struct GraphicInfo *g2 = &graphic_info[graphic2];
+
+  return (g1->bitmap      == g2->bitmap &&
+         g1->src_x       == g2->src_x &&
+         g1->src_y       == g2->src_y &&
+         g1->anim_frames == g2->anim_frames &&
+         g1->anim_delay  == g2->anim_delay &&
+         g1->anim_mode   == g2->anim_mode);
+}
+
 void DrawAllPlayers()
 {
   int i;
 
-  for(i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
     if (stored_player[i].active)
       DrawPlayer(&stored_player[i]);
 }
@@ -571,6 +608,8 @@ void DrawPlayer(struct PlayerInfo *player)
   int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
   int graphic;
   int action = ACTION_DEFAULT;
+  int last_player_graphic = getPlayerGraphic(player, move_dir);
+  int last_player_frame = player->Frame;
   int frame = 0;
 
   if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
@@ -589,11 +628,51 @@ void DrawPlayer(struct PlayerInfo *player)
   if (element == EL_EXPLOSION)
     return;
 
-  action = (player->is_pushing    ? ACTION_PUSHING    :
+#if 1
+
+  action = GetPlayerAction(player, move_dir);
+
+#else
+
+  action = (player->is_pushing   ? ACTION_PUSHING    :
            player->is_digging    ? ACTION_DIGGING    :
            player->is_collecting ? ACTION_COLLECTING :
            player->is_moving     ? ACTION_MOVING     :
-           player->is_snapping   ? ACTION_SNAPPING   : ACTION_DEFAULT);
+           player->is_snapping   ? ACTION_SNAPPING   :
+           player->is_sleeping   ? ACTION_SLEEPING   :
+           player->is_bored      ? ACTION_BORING     :
+           player->is_waiting    ? ACTION_WAITING    : ACTION_DEFAULT);
+
+  if (player->is_bored && player->num_special_action_bored > 0)
+  {
+    if (player->anim_delay_counter == 0 && player->post_delay_counter == 0)
+    {
+      int graphic_waiting;
+
+      action = ACTION_BORING_1 + SimpleRND(player->num_special_action_bored);
+      special_graphic = el_act_dir2img(EL_SP_MURPHY, action, move_dir);
+
+      player->anim_delay_counter =
+       graphic_info[special_graphic].anim_delay_fixed +
+       SimpleRND(graphic_info[special_graphic].anim_delay_random);
+      player->post_delay_counter =
+       graphic_info[special_graphic].post_delay_fixed +
+       SimpleRND(graphic_info[special_graphic].post_delay_random);
+      player->special_action_bored = action;
+    }
+
+    if (player->anim_delay_counter > 0)
+    {
+      action = player->special_action_bored;
+      player->anim_delay_counter--;
+    }
+
+    if (player->post_delay_counter > 0)
+    {
+      player->post_delay_counter--;
+    }
+  }
+#endif
 
 #if 0
   printf("::: '%s'\n", element_action_info[action].suffix);
@@ -672,6 +751,17 @@ void DrawPlayer(struct PlayerInfo *player)
   /* draw player himself                                                     */
   /* ----------------------------------------------------------------------- */
 
+#if 1
+
+  graphic = getPlayerGraphic(player, move_dir);
+
+  /* in the case of changed player action or direction, prevent the current
+     animation frame from being restarted for identical animations */
+  if (player->Frame == 0 && equalGraphics(graphic, last_player_graphic))
+    player->Frame = last_player_frame;
+
+#else
+
   if (player->use_murphy_graphic)
   {
     static int last_horizontal_dir = MV_LEFT;
@@ -691,6 +781,8 @@ void DrawPlayer(struct PlayerInfo *player)
   else
     graphic = el_act_dir2img(player->element_nr, player->GfxAction, move_dir);
 
+#endif
+
   frame = getGraphicAnimationFrame(graphic, player->Frame);
 
   if (player->GfxPos)
@@ -1072,7 +1164,7 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
   {
     SetRandomAnimationValue(lx, ly);
 
-    graphic = el_act_dir2img(element, GfxAction[lx][ly], MovDir[lx][ly]);
+    graphic = el_act_dir2img(element, GfxAction[lx][ly], GfxDir[lx][ly]);
     frame = getGraphicAnimationFrame(graphic, GfxFrame[lx][ly]);
   }
   else /* border element */
@@ -1182,7 +1274,7 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame)
 
     getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
 
-    for(i=0; i<4; i++)
+    for (i = 0; i < 4; i++)
     {
       int xx = x + xy[i][0];
       int yy = y + xy[i][1];
@@ -1227,7 +1319,7 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame)
     getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
 #endif
 
-    for(i=0; i<4; i++)
+    for (i = 0; i < 4; i++)
     {
       int xx = x + xy[i][0];
       int yy = y + xy[i][1];
@@ -1316,7 +1408,7 @@ void DrawLevelFieldCrumbledSandNeighbours(int x, int y)
   };
   int i;
 
-  for(i=0; i<4; i++)
+  for (i = 0; i < 4; i++)
   {
     int xx = x + xy[i][0];
     int yy = y + xy[i][1];
@@ -1564,7 +1656,7 @@ void AnimateEnvelope(int envelope_nr, int anim_mode, int action)
   int ystep = (ystart < yend || xstep == 0 ? 1 : 0);
   int x, y;
 
-  for (x=xstart, y=ystart; x <= xend && y <= yend; x += xstep, y += ystep)
+  for (x = xstart, y = ystart; x <= xend && y <= yend; x += xstep, y += ystep)
   {
     int xsize = (action == ACTION_CLOSING ? xend - (x - xstart) : x) + 2;
     int ysize = (action == ACTION_CLOSING ? yend - (y - ystart) : y) + 2;
@@ -1578,7 +1670,7 @@ void AnimateEnvelope(int envelope_nr, int anim_mode, int action)
 
     SetDrawtoField(DRAW_BACKBUFFER);
 
-    for (yy=0; yy < ysize; yy++) for (xx=0; xx < xsize; xx++)
+    for (yy = 0; yy < ysize; yy++) for (xx = 0; xx < xsize; xx++)
       DrawEnvelopeBackground(envelope_nr, sx,sy, xx,yy, xsize, ysize, font_nr);
 
     DrawTextToTextArea(SX + sx + font_width, SY + sy + font_height,
@@ -1665,8 +1757,8 @@ void DrawLevel()
   SetDrawBackgroundMask(REDRAW_NONE);
   ClearWindow();
 
-  for(x=BX1; x<=BX2; x++)
-    for(y=BY1; y<=BY2; y++)
+  for (x = BX1; x <= BX2; x++)
+    for (y = BY1; y <= BY2; y++)
       DrawScreenField(x, y);
 
   redraw_mask |= REDRAW_FIELD;
@@ -1676,8 +1768,8 @@ void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
 {
   int x,y;
 
-  for(x=0; x<size_x; x++)
-    for(y=0; y<size_y; y++)
+  for (x = 0; x < size_x; x++)
+    for (y = 0; y < size_y; y++)
       DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
 
   redraw_mask |= REDRAW_FIELD;
@@ -1697,9 +1789,9 @@ static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
   xpos += MICRO_TILEX;
   ypos += MICRO_TILEY;
 
-  for(x=-1; x<=STD_LEV_FIELDX; x++)
+  for (x = -1; x <= STD_LEV_FIELDX; x++)
   {
-    for(y=-1; y<=STD_LEV_FIELDY; y++)
+    for (y = -1; y <= STD_LEV_FIELDY; y++)
     {
       int lx = from_x + x, ly = from_y + y;
 
@@ -1955,7 +2047,7 @@ boolean Request(char *text, unsigned int req_state)
   game_status = GAME_MODE_PSEUDO_DOOR;
 
   /* write text for request */
-  for(ty=0; ty < MAX_REQUEST_LINES; ty++)
+  for (ty = 0; ty < MAX_REQUEST_LINES; ty++)
   {
     char text_line[MAX_REQUEST_LINE_LEN + 1];
     int tx, tl, tc;
@@ -1963,7 +2055,7 @@ boolean Request(char *text, unsigned int req_state)
     if (!*text)
       break;
 
-    for(tl=0,tx=0; tx < MAX_REQUEST_LINE_LEN; tl++,tx++)
+    for (tl = 0, tx = 0; tx < MAX_REQUEST_LINE_LEN; tl++, tx++)
     {
       tc = *(text + tx);
       if (!tc || tc == ' ')
@@ -2037,7 +2129,7 @@ boolean Request(char *text, unsigned int req_state)
   SetMouseCursor(CURSOR_DEFAULT);
 #endif
 
-  while(result < 0)
+  while (result < 0)
   {
     if (PendingEvent())
     {
@@ -2292,7 +2384,7 @@ unsigned int MoveDoor(unsigned int door_state)
        PlaySoundStereo(SND_DOOR_CLOSING, SOUND_MIDDLE);
     }
 
-    for(x = start; x <= end && !(door_1_done && door_2_done); x += stepsize)
+    for (x = start; x <= end && !(door_1_done && door_2_done); x += stepsize)
     {
       Bitmap *bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
       GC gc = bitmap->stored_clip_gc;
@@ -2609,7 +2701,7 @@ void CreateToolButtons()
 {
   int i;
 
-  for (i=0; i<NUM_TOOL_BUTTONS; i++)
+  for (i = 0; i < NUM_TOOL_BUTTONS; i++)
   {
     Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
     Bitmap *deco_bitmap = None;
@@ -2667,7 +2759,7 @@ void FreeToolButtons()
 {
   int i;
 
-  for (i=0; i<NUM_TOOL_BUTTONS; i++)
+  for (i = 0; i < NUM_TOOL_BUTTONS; i++)
     FreeGadget(tool_gadget[i]);
 }
 
@@ -2675,7 +2767,7 @@ static void UnmapToolButtons()
 {
   int i;
 
-  for (i=0; i<NUM_TOOL_BUTTONS; i++)
+  for (i = 0; i < NUM_TOOL_BUTTONS; i++)
     UnmapGadget(tool_gadget[i]);
 }