#include "libgame/libgame.h"
#include "game.h"
+#include "init.h"
#include "tools.h"
#include "screens.h"
-#include "init.h"
#include "files.h"
#include "tape.h"
#include "network.h"
#define DOUBLE_PLAYER_SPEED(p) (HALVE_MOVE_DELAY((p)->move_delay_value))
#define HALVE_PLAYER_SPEED(p) (DOUBLE_MOVE_DELAY((p)->move_delay_value))
+#define INIT_GFX_RANDOM() (SimpleRND(1000000))
+
/* game button identifiers */
#define GAME_CTRL_ID_STOP 0
#define GAME_CTRL_ID_PAUSE 1
#define NUM_GAME_BUTTONS 6
+
/* forward declaration for internal use */
+
+static void InitBeltMovement(void);
static void CloseAllOpenTimegates(void);
static void CheckGravityMovement(struct PlayerInfo *);
static void KillHeroUnlessProtected(int, int);
-void PlaySoundLevel(int, int, int);
-void PlaySoundLevelAction(int, int, int);
-void PlaySoundLevelElementAction(int, int, int, int);
+static void PlaySoundLevel(int, int, int);
+static void PlaySoundLevelNearest(int, int, int);
+static void PlaySoundLevelAction(int, int, int);
+static void PlaySoundLevelElementAction(int, int, int, int);
+static void PlaySoundLevelActionIfLoop(int, int, int);
+static void StopSoundLevelActionIfLoop(int, int, int);
static void MapGameButtons();
static void HandleGameButtons(struct GadgetInfo *);
static struct GadgetInfo *game_gadget[NUM_GAME_BUTTONS];
-#define SND_ACTION_UNKNOWN 0
-#define SND_ACTION_WAITING 1
-#define SND_ACTION_MOVING 2
-#define SND_ACTION_DIGGING 3
-#define SND_ACTION_COLLECTING 4
-#define SND_ACTION_PASSING 5
-#define SND_ACTION_IMPACT 6
-#define SND_ACTION_PUSHING 7
-#define SND_ACTION_ACTIVATING 8
-#define SND_ACTION_ACTIVE 9
-#define NUM_SND_ACTIONS 10
+/* ------------------------------------------------------------------------- */
+/* definition of elements that automatically change to other elements after */
+/* a specified time, eventually calling a function when changing */
+/* ------------------------------------------------------------------------- */
-static struct
-{
- char *text;
- int value;
- boolean is_loop;
-} sound_action_properties[] =
-{
- /* insert _all_ loop sound actions here */
- { ".waiting", SND_ACTION_WAITING, TRUE },
- { ".moving", SND_ACTION_MOVING, TRUE }, /* continuos moving */
- { ".active", SND_ACTION_ACTIVE, TRUE },
- { ".growing", SND_ACTION_UNKNOWN, TRUE },
- { ".attacking", SND_ACTION_UNKNOWN, TRUE },
-
- /* other (non-loop) sound actions are optional */
- { ".stepping", SND_ACTION_MOVING, FALSE }, /* discrete moving */
- { ".digging", SND_ACTION_DIGGING, FALSE },
- { ".collecting", SND_ACTION_COLLECTING, FALSE },
- { ".passing", SND_ACTION_PASSING, FALSE },
- { ".impact", SND_ACTION_IMPACT, FALSE },
- { ".pushing", SND_ACTION_PUSHING, FALSE },
- { ".activating", SND_ACTION_ACTIVATING, FALSE },
- { NULL, 0, 0 },
-};
-static int element_action_sound[MAX_NUM_ELEMENTS][NUM_SND_ACTIONS];
-static boolean is_loop_sound[NUM_SOUND_FILES];
+/* forward declaration for changer functions */
+static void InitBuggyBase(int x, int y);
+static void WarnBuggyBase(int x, int y);
-#define IS_LOOP_SOUND(x) (is_loop_sound[x])
+static void InitTrap(int x, int y);
+static void ActivateTrap(int x, int y);
+static void ChangeActiveTrap(int x, int y);
+static void InitRobotWheel(int x, int y);
+static void RunRobotWheel(int x, int y);
+static void StopRobotWheel(int x, int y);
-#ifdef DEBUG
-#if 0
-static unsigned int getStateCheckSum(int counter)
+static void InitTimegateWheel(int x, int y);
+static void RunTimegateWheel(int x, int y);
+
+struct ChangingElementInfo
{
- int x, y;
- unsigned int mult = 1;
- unsigned int checksum = 0;
- /*
- static short lastFeld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
- */
- static boolean first_game = TRUE;
+ int base_element;
+ int next_element;
+ int change_delay;
+ void (*pre_change_function)(int x, int y);
+ void (*change_function)(int x, int y);
+ void (*post_change_function)(int x, int y);
+};
- for (y=0; y<lev_fieldy; y++) for(x=0; x<lev_fieldx; x++)
+static struct ChangingElementInfo changing_element_list[] =
+{
{
- /*
- if (counter == 3)
- {
- if (first_game)
- lastFeld[x][y] = Feld[x][y];
- else if (lastFeld[x][y] != Feld[x][y])
- printf("DIFF: [%d][%d]: lastFeld == %d != %d == Feld\n",
- x, y, lastFeld[x][y], Feld[x][y]);
- }
- */
+ EL_NUT_BREAKING,
+ EL_EMERALD,
+ 6,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ EL_PEARL_BREAKING,
+ EL_EMPTY,
+ 8,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ EL_EXIT_OPENING,
+ EL_EXIT_OPEN,
+ 29,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ EL_SWITCHGATE_OPENING,
+ EL_SWITCHGATE_OPEN,
+ 29,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ EL_SWITCHGATE_CLOSING,
+ EL_SWITCHGATE_CLOSED,
+ 29,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ EL_TIMEGATE_OPENING,
+ EL_TIMEGATE_OPEN,
+ 29,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ EL_TIMEGATE_CLOSING,
+ EL_TIMEGATE_CLOSED,
+ 29,
+ NULL,
+ NULL,
+ NULL
+ },
- checksum += mult++ * Ur[x][y];
- checksum += mult++ * Feld[x][y];
+ {
+ EL_ACID_SPLASH_LEFT,
+ EL_EMPTY,
+ 8,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ EL_ACID_SPLASH_RIGHT,
+ EL_EMPTY,
+ 8,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ EL_SP_BUGGY_BASE,
+ EL_SP_BUGGY_BASE_ACTIVATING,
+ 0,
+ InitBuggyBase,
+ NULL,
+ NULL
+ },
+ {
+ EL_SP_BUGGY_BASE_ACTIVATING,
+ EL_SP_BUGGY_BASE_ACTIVE,
+ 0,
+ InitBuggyBase,
+ NULL,
+ NULL
+ },
+ {
+ EL_SP_BUGGY_BASE_ACTIVE,
+ EL_SP_BUGGY_BASE,
+ 0,
+ InitBuggyBase,
+ WarnBuggyBase,
+ NULL
+ },
+ {
+ EL_TRAP,
+ EL_TRAP_ACTIVE,
+ 0,
+ InitTrap,
+ NULL,
+ ActivateTrap
+ },
+ {
+ EL_TRAP_ACTIVE,
+ EL_TRAP,
+ 31,
+ NULL,
+ ChangeActiveTrap,
+ NULL
+ },
+ {
+ EL_ROBOT_WHEEL_ACTIVE,
+ EL_ROBOT_WHEEL,
+ 0,
+ InitRobotWheel,
+ RunRobotWheel,
+ StopRobotWheel
+ },
+ {
+ EL_TIMEGATE_SWITCH_ACTIVE,
+ EL_TIMEGATE_SWITCH,
+ 0,
+ InitTimegateWheel,
+ RunTimegateWheel,
+ NULL
+ },
- /*
- checksum += mult++ * MovPos[x][y];
- checksum += mult++ * MovDir[x][y];
- checksum += mult++ * MovDelay[x][y];
- checksum += mult++ * Store[x][y];
- checksum += mult++ * Store2[x][y];
- checksum += mult++ * StorePlayer[x][y];
- checksum += mult++ * Frame[x][y];
- checksum += mult++ * AmoebaNr[x][y];
- checksum += mult++ * JustStopped[x][y];
- checksum += mult++ * Stop[x][y];
- */
+ {
+ EL_UNDEFINED,
+ EL_UNDEFINED,
+ -1,
+ NULL,
+ NULL,
+ NULL
}
+};
- if (counter == 3 && first_game)
- first_game = FALSE;
-
- return checksum;
-}
-#endif
-#endif
-
+static struct ChangingElementInfo changing_element[MAX_NUM_ELEMENTS];
+#define IS_AUTO_CHANGING(e) (changing_element[e].base_element != EL_UNDEFINED)
void GetPlayerConfig()
static int getBeltNrFromBeltElement(int element)
{
- return (element < EL_CONVEYOR_BELT2_LEFT ? 0 :
- element < EL_CONVEYOR_BELT3_LEFT ? 1 :
- element < EL_CONVEYOR_BELT4_LEFT ? 2 : 3);
+ return (element < EL_CONVEYOR_BELT_2_LEFT ? 0 :
+ element < EL_CONVEYOR_BELT_3_LEFT ? 1 :
+ element < EL_CONVEYOR_BELT_4_LEFT ? 2 : 3);
}
static int getBeltNrFromBeltActiveElement(int element)
{
- return (element < EL_CONVEYOR_BELT2_LEFT_ACTIVE ? 0 :
- element < EL_CONVEYOR_BELT3_LEFT_ACTIVE ? 1 :
- element < EL_CONVEYOR_BELT4_LEFT_ACTIVE ? 2 : 3);
+ return (element < EL_CONVEYOR_BELT_2_LEFT_ACTIVE ? 0 :
+ element < EL_CONVEYOR_BELT_3_LEFT_ACTIVE ? 1 :
+ element < EL_CONVEYOR_BELT_4_LEFT_ACTIVE ? 2 : 3);
}
static int getBeltNrFromBeltSwitchElement(int element)
{
- return (element < EL_CONVEYOR_BELT2_SWITCH_LEFT ? 0 :
- element < EL_CONVEYOR_BELT3_SWITCH_LEFT ? 1 :
- element < EL_CONVEYOR_BELT4_SWITCH_LEFT ? 2 : 3);
+ return (element < EL_CONVEYOR_BELT_2_SWITCH_LEFT ? 0 :
+ element < EL_CONVEYOR_BELT_3_SWITCH_LEFT ? 1 :
+ element < EL_CONVEYOR_BELT_4_SWITCH_LEFT ? 2 : 3);
}
static int getBeltDirNrFromBeltSwitchElement(int element)
{
static int belt_base_element[4] =
{
- EL_CONVEYOR_BELT1_SWITCH_LEFT,
- EL_CONVEYOR_BELT2_SWITCH_LEFT,
- EL_CONVEYOR_BELT3_SWITCH_LEFT,
- EL_CONVEYOR_BELT4_SWITCH_LEFT
+ EL_CONVEYOR_BELT_1_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_2_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_3_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_4_SWITCH_LEFT
};
int belt_nr = getBeltNrFromBeltSwitchElement(element);
Feld[x][y] = EL_SP_MURPHY_CLONE;
break;
}
+ else
+ {
+ stored_player[0].use_murphy_graphic = TRUE;
+ }
+
+ Feld[x][y] = EL_PLAYER_1;
}
/* no break! */
- case EL_PLAYER1:
- case EL_PLAYER2:
- case EL_PLAYER3:
- case EL_PLAYER4:
+ case EL_PLAYER_1:
+ case EL_PLAYER_2:
+ case EL_PLAYER_3:
+ case EL_PLAYER_4:
if (init_game)
{
- struct PlayerInfo *player = &stored_player[Feld[x][y] - EL_PLAYER1];
+ struct PlayerInfo *player = &stored_player[Feld[x][y] - EL_PLAYER_1];
int jx = player->jx, jy = player->jy;
player->present = TRUE;
case EL_STONEBLOCK:
if (x < lev_fieldx-1 && Feld[x+1][y] == EL_ACID)
- Feld[x][y] = EL_ACIDPOOL_TOPLEFT;
+ Feld[x][y] = EL_ACID_POOL_TOPLEFT;
else if (x > 0 && Feld[x-1][y] == EL_ACID)
- Feld[x][y] = EL_ACIDPOOL_TOPRIGHT;
- else if (y > 0 && Feld[x][y-1] == EL_ACIDPOOL_TOPLEFT)
- Feld[x][y] = EL_ACIDPOOL_BOTTOMLEFT;
+ Feld[x][y] = EL_ACID_POOL_TOPRIGHT;
+ else if (y > 0 && Feld[x][y-1] == EL_ACID_POOL_TOPLEFT)
+ Feld[x][y] = EL_ACID_POOL_BOTTOMLEFT;
else if (y > 0 && Feld[x][y-1] == EL_ACID)
- Feld[x][y] = EL_ACIDPOOL_BOTTOM;
- else if (y > 0 && Feld[x][y-1] == EL_ACIDPOOL_TOPRIGHT)
- Feld[x][y] = EL_ACIDPOOL_BOTTOMRIGHT;
+ Feld[x][y] = EL_ACID_POOL_BOTTOM;
+ else if (y > 0 && Feld[x][y-1] == EL_ACID_POOL_TOPRIGHT)
+ Feld[x][y] = EL_ACID_POOL_BOTTOMRIGHT;
break;
case EL_BUG_RIGHT:
case EL_AMOEBA_DROP:
if (y == lev_fieldy - 1)
{
- Feld[x][y] = EL_AMOEBA_CREATING;
+ Feld[x][y] = EL_AMOEBA_GROWING;
Store[x][y] = EL_AMOEBA_WET;
}
break;
Feld[x][y] = EL_EMPTY;
break;
- case EL_EM_KEY1_FILE:
- Feld[x][y] = EL_EM_KEY1;
+ case EL_EM_KEY_1_FILE:
+ Feld[x][y] = EL_EM_KEY_1;
break;
- case EL_EM_KEY2_FILE:
- Feld[x][y] = EL_EM_KEY2;
+ case EL_EM_KEY_2_FILE:
+ Feld[x][y] = EL_EM_KEY_2;
break;
- case EL_EM_KEY3_FILE:
- Feld[x][y] = EL_EM_KEY3;
+ case EL_EM_KEY_3_FILE:
+ Feld[x][y] = EL_EM_KEY_3;
break;
- case EL_EM_KEY4_FILE:
- Feld[x][y] = EL_EM_KEY4;
+ case EL_EM_KEY_4_FILE:
+ Feld[x][y] = EL_EM_KEY_4;
break;
- case EL_CONVEYOR_BELT1_SWITCH_LEFT:
- case EL_CONVEYOR_BELT1_SWITCH_MIDDLE:
- case EL_CONVEYOR_BELT1_SWITCH_RIGHT:
- case EL_CONVEYOR_BELT2_SWITCH_LEFT:
- case EL_CONVEYOR_BELT2_SWITCH_MIDDLE:
- case EL_CONVEYOR_BELT2_SWITCH_RIGHT:
- case EL_CONVEYOR_BELT3_SWITCH_LEFT:
- case EL_CONVEYOR_BELT3_SWITCH_MIDDLE:
- case EL_CONVEYOR_BELT3_SWITCH_RIGHT:
- case EL_CONVEYOR_BELT4_SWITCH_LEFT:
- case EL_CONVEYOR_BELT4_SWITCH_MIDDLE:
- case EL_CONVEYOR_BELT4_SWITCH_RIGHT:
+ case EL_CONVEYOR_BELT_1_SWITCH_LEFT:
+ case EL_CONVEYOR_BELT_1_SWITCH_MIDDLE:
+ case EL_CONVEYOR_BELT_1_SWITCH_RIGHT:
+ case EL_CONVEYOR_BELT_2_SWITCH_LEFT:
+ case EL_CONVEYOR_BELT_2_SWITCH_MIDDLE:
+ case EL_CONVEYOR_BELT_2_SWITCH_RIGHT:
+ case EL_CONVEYOR_BELT_3_SWITCH_LEFT:
+ case EL_CONVEYOR_BELT_3_SWITCH_MIDDLE:
+ case EL_CONVEYOR_BELT_3_SWITCH_RIGHT:
+ case EL_CONVEYOR_BELT_4_SWITCH_LEFT:
+ case EL_CONVEYOR_BELT_4_SWITCH_MIDDLE:
+ case EL_CONVEYOR_BELT_4_SWITCH_RIGHT:
if (init_game)
{
int belt_nr = getBeltNrFromBeltSwitchElement(Feld[x][y]);
for (i=0; i<MAX_PLAYERS; i++)
for (j=0; j<4; j++)
if (stored_player[i].key[j])
- DrawNewMiniGraphicExt(drawto, DX_KEYS + j * MINI_TILEX, DY_KEYS,
- GFX_SCHLUESSEL1 + j);
+ DrawMiniGraphicExt(drawto, DX_KEYS + j * MINI_TILEX, DY_KEYS,
+ el2edimg(EL_KEY_1 + j));
DrawText(DX + XX_EMERALDS, DY + YY_EMERALDS,
- int2str(local_player->gems_still_needed, 3), FS_SMALL, FC_YELLOW);
+ int2str(local_player->gems_still_needed, 3), FONT_TEXT_2);
DrawText(DX + XX_DYNAMITE, DY + YY_DYNAMITE,
- int2str(local_player->dynamite, 3), FS_SMALL, FC_YELLOW);
+ int2str(local_player->dynamite, 3), FONT_TEXT_2);
DrawText(DX + XX_SCORE, DY + YY_SCORE,
- int2str(local_player->score, 5), FS_SMALL, FC_YELLOW);
+ int2str(local_player->score, 5), FONT_TEXT_2);
DrawText(DX + XX_TIME, DY + YY_TIME,
- int2str(TimeLeft, 3), FS_SMALL, FC_YELLOW);
-}
-
-
-/*
- =============================================================================
- InitGameSound()
- -----------------------------------------------------------------------------
- initialize sound effect lookup table for element actions
- =============================================================================
-*/
-
-void InitGameSound()
-{
- int sound_effect_properties[NUM_SOUND_FILES];
- int i, j;
-
-#if 0
- debug_print_timestamp(0, NULL);
-#endif
-
- for (i=0; i<MAX_NUM_ELEMENTS; i++)
- for (j=0; j<NUM_SND_ACTIONS; j++)
- element_action_sound[i][j] = -1;
-
- for (i=0; i<NUM_SOUND_FILES; i++)
- {
- int len_effect_text = strlen(sound_files[i].token);
-
- sound_effect_properties[i] = SND_ACTION_UNKNOWN;
- is_loop_sound[i] = FALSE;
-
- /* determine all loop sounds and identify certain sound classes */
-
- for (j=0; sound_action_properties[j].text; j++)
- {
- int len_action_text = strlen(sound_action_properties[j].text);
-
- if (len_action_text < len_effect_text &&
- strcmp(&sound_files[i].token[len_effect_text - len_action_text],
- sound_action_properties[j].text) == 0)
- {
- sound_effect_properties[i] = sound_action_properties[j].value;
-
- if (sound_action_properties[j].is_loop)
- is_loop_sound[i] = TRUE;
- }
- }
-
- /* associate elements and some selected sound actions */
-
- for (j=0; j<MAX_NUM_ELEMENTS; j++)
- {
- if (element_info[j].sound_class_name)
- {
- int len_class_text = strlen(element_info[j].sound_class_name);
-
- if (len_class_text + 1 < len_effect_text &&
- strncmp(sound_files[i].token,
- element_info[j].sound_class_name, len_class_text) == 0 &&
- sound_files[i].token[len_class_text] == '.')
- {
- int sound_action_value = sound_effect_properties[i];
-
- element_action_sound[j][sound_action_value] = i;
- }
- }
- }
- }
-
-#if 0
- debug_print_timestamp(0, "InitGameEngine");
-#endif
-
-#if 0
- /* TEST ONLY */
- {
- int element = EL_SAND;
- int sound_action = SND_ACTION_DIGGING;
- int j = 0;
-
- while (sound_action_properties[j].text)
- {
- if (sound_action_properties[j].value == sound_action)
- printf("element %d, sound action '%s' == %d\n",
- element, sound_action_properties[j].text,
- element_action_sound[element][sound_action]);
- j++;
- }
- }
-#endif
+ int2str(TimeLeft, 3), FONT_TEXT_2);
}
{
int i;
+ /* set game engine from tape file when re-playing, else from level file */
game.engine_version = (tape.playing ? tape.engine_version :
level.game_version);
+ /* dynamically adjust element properties according to game engine version */
+ InitElementPropertiesEngine(game.engine_version);
+
#if 0
printf("level %d: level version == %06d\n", level_nr, level.game_version);
printf(" tape version == %06d [%s] [file: %06d]\n",
game.initial_move_delay_value =
(level.double_speed ? MOVE_DELAY_HIGH_SPEED : MOVE_DELAY_NORMAL_SPEED);
+#if 0
/* dynamically adjust element properties according to game engine version */
{
static int ep_em_slippery_wall[] =
{
EL_STEELWALL,
EL_WALL,
- EL_WALL_GROWING,
- EL_WALL_GROWING_X,
- EL_WALL_GROWING_Y,
- EL_WALL_GROWING_XY
+ EL_EXPANDABLE_WALL,
+ EL_EXPANDABLE_WALL_HORIZONTAL,
+ EL_EXPANDABLE_WALL_VERTICAL,
+ EL_EXPANDABLE_WALL_ANY
};
static int ep_em_slippery_wall_num = SIZEOF_ARRAY_INT(ep_em_slippery_wall);
+ /* special EM style gems behaviour */
for (i=0; i<ep_em_slippery_wall_num; i++)
- {
- if (level.em_slippery_gems) /* special EM style gems behaviour */
- Elementeigenschaften2[ep_em_slippery_wall[i]] |=
- EP_BIT_EM_SLIPPERY_WALL;
- else
- Elementeigenschaften2[ep_em_slippery_wall[i]] &=
- ~EP_BIT_EM_SLIPPERY_WALL;
- }
+ SET_PROPERTY(ep_em_slippery_wall[i], EP_EM_SLIPPERY_WALL,
+ level.em_slippery_gems);
- /* "EL_WALL_GROWING_ACTIVE" wasn't slippery for EM gems in version 2.0.1 */
- if (level.em_slippery_gems && game.engine_version > VERSION_IDENT(2,0,1))
- Elementeigenschaften2[EL_WALL_GROWING_ACTIVE] |= EP_BIT_EM_SLIPPERY_WALL;
- else
- Elementeigenschaften2[EL_WALL_GROWING_ACTIVE] &=~EP_BIT_EM_SLIPPERY_WALL;
+ /* "EL_EXPANDABLE_WALL_GROWING" wasn't slippery for EM gems in 2.0.1 */
+ SET_PROPERTY(EL_EXPANDABLE_WALL_GROWING, EP_EM_SLIPPERY_WALL,
+ (level.em_slippery_gems &&
+ game.engine_version > VERSION_IDENT(2,0,1)));
+ }
+#endif
+
+ /* initialize changing elements information */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ {
+ changing_element[i].base_element = EL_UNDEFINED;
+ changing_element[i].next_element = EL_UNDEFINED;
+ changing_element[i].change_delay = -1;
+ changing_element[i].pre_change_function = NULL;
+ changing_element[i].change_function = NULL;
+ changing_element[i].post_change_function = NULL;
+ }
+
+ /* add changing elements from pre-defined list */
+ i = 0;
+ while (changing_element_list[i].base_element != EL_UNDEFINED)
+ {
+ struct ChangingElementInfo *ce = &changing_element_list[i];
+ int element = ce->base_element;
+
+ changing_element[element].base_element = ce->base_element;
+ changing_element[element].next_element = ce->next_element;
+ changing_element[element].change_delay = ce->change_delay;
+ changing_element[element].pre_change_function = ce->pre_change_function;
+ changing_element[element].change_function = ce->change_function;
+ changing_element[element].post_change_function = ce->post_change_function;
+
+ i++;
+ }
+
+ /* add changing elements from custom element configuration */
+ for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+ {
+ struct CustomElementChangeInfo *change = &level.custom_element[i].change;
+ int element = EL_CUSTOM_START + i;
+
+ /* only add custom elements that change after fixed/random frame delay */
+ if (!IS_CHANGEABLE(element) ||
+ (!HAS_CHANGE_EVENT(element, CE_DELAY_FIXED) &&
+ !HAS_CHANGE_EVENT(element, CE_DELAY_RANDOM)))
+ continue;
+
+ changing_element[element].base_element = element;
+ changing_element[element].next_element = change->successor;
+ changing_element[element].change_delay = 0;
+
+ if (HAS_CHANGE_EVENT(element, CE_DELAY_FIXED))
+ changing_element[element].change_delay +=
+ change->delay_fixed * change->delay_frames;
+
+ if (HAS_CHANGE_EVENT(element, CE_DELAY_RANDOM));
+ /* random frame delay added at runtime for each element individually */
}
}
struct PlayerInfo *player = &stored_player[i];
player->index_nr = i;
- player->element_nr = EL_PLAYER1 + i;
+ player->element_nr = EL_PLAYER_1 + i;
player->present = FALSE;
player->active = FALSE;
player->Pushing = FALSE;
player->Switching = FALSE;
player->GfxPos = 0;
+ player->GfxDir = MV_NO_MOVING;
+ player->GfxAction = ACTION_DEFAULT;
player->Frame = 0;
+ player->StepFrame = 0;
- player->actual_frame_counter = 0;
+ player->use_murphy_graphic = FALSE;
+ player->use_disk_red_graphic = FALSE;
- player->frame_reset_delay = 0;
+ player->actual_frame_counter = 0;
player->last_move_dir = MV_NO_MOVING;
player->is_moving = FALSE;
+ player->is_moving = FALSE;
+ player->is_waiting = FALSE;
+ player->is_digging = FALSE;
+ player->is_collecting = FALSE;
+
player->move_delay = game.initial_move_delay;
player->move_delay_value = game.initial_move_delay_value;
player->last_jx = player->last_jy = 0;
player->jx = player->jy = 0;
- player->shield_passive_time_left = 0;
- player->shield_active_time_left = 0;
+ player->shield_normal_time_left = 0;
+ player->shield_deadly_time_left = 0;
DigField(player, 0, 0, 0, 0, DF_NO_PUSH);
SnapField(player, 0, 0);
AllPlayersGone = FALSE;
- game.yam_content_nr = 0;
+ game.yamyam_content_nr = 0;
game.magic_wall_active = FALSE;
game.magic_wall_time_left = 0;
game.light_time_left = 0;
{
Feld[x][y] = Ur[x][y];
MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0;
- Store[x][y] = Store2[x][y] = StorePlayer[x][y] = 0;
- Frame[x][y] = 0;
- GfxAction[x][y] = GFX_ACTION_DEFAULT;
+ Store[x][y] = Store2[x][y] = StorePlayer[x][y] = Back[x][y] = 0;
AmoebaNr[x][y] = 0;
JustStopped[x][y] = 0;
Stop[x][y] = FALSE;
+ ExplodePhase[x][y] = 0;
ExplodeField[x][y] = EX_NO_EXPLOSION;
+
+ GfxFrame[x][y] = 0;
+ GfxAction[x][y] = ACTION_DEFAULT;
+ GfxRandom[x][y] = INIT_GFX_RANDOM();
+ GfxElement[x][y] = EL_UNDEFINED;
}
}
}
}
+ InitBeltMovement();
+
game.emulation = (emulate_bd ? EMU_BOULDERDASH :
emulate_sb ? EMU_SOKOBAN :
emulate_sp ? EMU_SUPAPLEX : EMU_NONE);
DrawLevel();
DrawAllPlayers();
- FadeToFront();
/* after drawing the level, correct some elements */
if (game.timegate_time_left == 0)
BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY);
redraw_mask |= REDRAW_FROM_BACKBUFFER;
+ FadeToFront();
/* copy default game door content to main double buffer */
- BlitBitmap(pix[PIX_DOOR], drawto,
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
DOOR_GFX_PAGEX5, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY);
if (level_nr < 100)
- DrawText(DX + XX_LEVEL, DY + YY_LEVEL,
- int2str(level_nr, 2), FS_SMALL, FC_YELLOW);
+ DrawText(DX + XX_LEVEL, DY + YY_LEVEL, int2str(level_nr, 2), FONT_TEXT_2);
else
{
DrawTextExt(drawto, DX + XX_EMERALDS, DY + YY_EMERALDS,
- int2str(level_nr, 3), FS_SMALL, FC_SPECIAL3);
+ int2str(level_nr, 3), FONT_LEVEL_NUMBER, BLIT_OPAQUE);
BlitBitmap(drawto, drawto,
DX + XX_EMERALDS, DY + YY_EMERALDS + 1,
- FONT5_XSIZE * 3, FONT5_YSIZE - 1,
+ getFontWidth(FONT_LEVEL_NUMBER) * 3,
+ getFontHeight(FONT_LEVEL_NUMBER) - 1,
DX + XX_LEVEL - 1, DY + YY_LEVEL + 1);
}
MapTapeButtons();
/* copy actual game door content to door double buffer for OpenDoor() */
- BlitBitmap(drawto, pix[PIX_DB_DOOR],
+ BlitBitmap(drawto, bitmap_db_door,
DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
OpenDoor(DOOR_OPEN_ALL);
- PlaySoundStereo(SND_GAME_STARTING, SOUND_MAX_RIGHT);
+ PlaySoundStereo(SND_GAME_STARTING, SOUND_MIDDLE);
if (setup.sound_music)
PlayMusic(level_nr);
- KeyboardAutoRepeatOff();
+ KeyboardAutoRepeatOffUnlessAutoplay();
if (options.debug)
{
if (local_player->MovPos)
return;
+ if (tape.playing && tape.auto_play)
+ tape.auto_play_level_solved = TRUE;
+
local_player->LevelSolved = FALSE;
- PlaySoundStereo(SND_GAME_WINNING, SOUND_MAX_RIGHT);
+ PlaySoundStereo(SND_GAME_WINNING, SOUND_MIDDLE);
if (TimeLeft)
{
if (!tape.playing && setup.sound_loops)
- PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MAX_RIGHT,
+ PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MIDDLE,
SND_CTRL_PLAY_LOOP);
while (TimeLeft > 0)
{
if (!tape.playing && !setup.sound_loops)
- PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_RIGHT);
+ PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MIDDLE);
if (TimeLeft > 0 && !(TimeLeft % 10))
- RaiseScore(level.score[SC_ZEITBONUS]);
+ RaiseScore(level.score[SC_TIME_BONUS]);
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), FONT_TEXT_2);
BackToFront();
if (!tape.playing)
else if (level.time == 0) /* level without time limit */
{
if (!tape.playing && setup.sound_loops)
- PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MAX_RIGHT,
+ PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MIDDLE,
SND_CTRL_PLAY_LOOP);
while (TimePlayed < 999)
{
if (!tape.playing && !setup.sound_loops)
- PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_RIGHT);
+ PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MIDDLE);
if (TimePlayed < 999 && !(TimePlayed % 10))
- RaiseScore(level.score[SC_ZEITBONUS]);
+ RaiseScore(level.score[SC_TIME_BONUS]);
if (TimePlayed < 900 && !(TimePlayed % 10))
TimePlayed += 10;
else
TimePlayed++;
- DrawText(DX_TIME, DY_TIME, int2str(TimePlayed, 3), FS_SMALL, FC_YELLOW);
+ DrawText(DX_TIME, DY_TIME, int2str(TimePlayed, 3), FONT_TEXT_2);
BackToFront();
if (!tape.playing)
StopSound(SND_GAME_LEVELTIME_BONUS);
}
-#if 0
- FadeSounds();
-#endif
-
/* Hero disappears */
- DrawNewLevelField(ExitX, ExitY);
+ DrawLevelField(ExitX, ExitY);
BackToFront();
if (tape.playing)
if ((hi_pos = NewHiScore()) >= 0)
{
- game_status = HALLOFFAME;
+ game_status = GAME_MODE_SCORES;
DrawHallOfFame(hi_pos);
if (raise_level)
{
}
else
{
- game_status = MAINMENU;
+ game_status = GAME_MODE_MAIN;
if (raise_level)
{
level_nr++;
return position;
}
+void InitPlayerGfxAnimation(struct PlayerInfo *player, int action, int dir)
+{
+ if (player->GfxAction != action || player->GfxDir != dir)
+ {
+#if 0
+ printf("Player frame reset! (%d => %d, %d => %d)\n",
+ player->GfxAction, action, player->GfxDir, dir);
+#endif
+
+ player->GfxAction = action;
+ player->GfxDir = dir;
+ player->Frame = 0;
+ player->StepFrame = 0;
+ }
+}
+
+static void ResetRandomAnimationValue(int x, int y)
+{
+ GfxRandom[x][y] = INIT_GFX_RANDOM();
+}
+
+static void ResetGfxAnimation(int x, int y)
+{
+ GfxFrame[x][y] = 0;
+ GfxAction[x][y] = ACTION_DEFAULT;
+}
+
void InitMovingField(int x, int y, int direction)
{
+ int element = Feld[x][y];
int newx = x + (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0);
int newy = y + (direction == MV_UP ? -1 : direction == MV_DOWN ? +1 : 0);
- MovDir[x][y] = direction;
- MovDir[newx][newy] = direction;
+ if (!JustStopped[x][y] || direction != MovDir[x][y])
+ ResetGfxAnimation(x, y);
+
+ MovDir[newx][newy] = MovDir[x][y] = direction;
if (Feld[newx][newy] == EL_EMPTY)
Feld[newx][newy] = EL_BLOCKED;
- GfxAction[x][y] = GFX_ACTION_MOVING;
+ if (direction == MV_DOWN && CAN_FALL(element))
+ GfxAction[x][y] = ACTION_FALLING;
+ else
+ GfxAction[x][y] = ACTION_MOVING;
+
+ GfxFrame[newx][newy] = GfxFrame[x][y];
+ GfxAction[newx][newy] = GfxAction[x][y];
+ GfxRandom[newx][newy] = GfxRandom[x][y];
}
void Moving2Blocked(int x, int y, int *goes_to_x, int *goes_to_y)
static void RemoveField(int x, int y)
{
Feld[x][y] = EL_EMPTY;
+ GfxElement[x][y] = EL_UNDEFINED;
MovPos[x][y] = 0;
MovDir[x][y] = 0;
MovDelay[x][y] = 0;
(Feld[oldx][oldy] == EL_QUICKSAND_EMPTYING ||
Feld[oldx][oldy] == EL_MAGIC_WALL_EMPTYING ||
Feld[oldx][oldy] == EL_BD_MAGIC_WALL_EMPTYING ||
- Feld[oldx][oldy] == EL_AMOEBA_DRIPPING))
+ Feld[oldx][oldy] == EL_AMOEBA_DROPPING))
Feld[oldx][oldy] = get_next_element(Feld[oldx][oldy]);
else
Feld[oldx][oldy] = EL_EMPTY;
Feld[newx][newy] = EL_EMPTY;
MovPos[oldx][oldy] = MovDir[oldx][oldy] = MovDelay[oldx][oldy] = 0;
MovPos[newx][newy] = MovDir[newx][newy] = MovDelay[newx][newy] = 0;
- GfxAction[oldx][oldy] = GfxAction[newx][newy] = GFX_ACTION_DEFAULT;
+ GfxAction[oldx][oldy] = GfxAction[newx][newy] = ACTION_DEFAULT;
- DrawNewLevelField(oldx, oldy);
- DrawNewLevelField(newx, newy);
+ DrawLevelField(oldx, oldy);
+ DrawLevelField(newx, newy);
}
void DrawDynamite(int x, int y)
{
int sx = SCREENX(x), sy = SCREENY(y);
-#if 0
- int graphic = el2gfx(Feld[x][y]);
-#else
int graphic = el2img(Feld[x][y]);
-#endif
int frame;
if (!IN_SCR_FIELD(sx, sy) || IS_PLAYER(x, y))
return;
- if (Store[x][y])
-#if 0
- DrawGraphic(sx, sy, el2gfx(Store[x][y]));
-#else
- DrawNewGraphic(sx, sy, el2img(Store[x][y]), 0);
-#endif
-
- if (Feld[x][y] == EL_DYNAMITE_ACTIVE)
- {
- if ((frame = (96 - MovDelay[x][y]) / 12) > 6)
- frame = 6;
- }
- else
- {
- if ((frame = ((96 - MovDelay[x][y]) / 6) % 8) > 3)
- frame = 7 - frame;
- }
+ if (IS_WALKABLE_INSIDE(Back[x][y]))
+ return;
-#if 1
- frame = getNewGraphicAnimationFrame(graphic, 96 - MovDelay[x][y]);
-#endif
+ if (Back[x][y])
+ DrawGraphic(sx, sy, el2img(Back[x][y]), 0);
+ else if (Store[x][y])
+ DrawGraphic(sx, sy, el2img(Store[x][y]), 0);
- /*
- printf("-> %d: %d [%d]\n", graphic, frame, MovDelay[x][y]);
- */
+ frame = getGraphicAnimationFrame(graphic, GfxFrame[x][y]);
-#if 0
- if (game.emulation == EMU_SUPAPLEX)
- DrawGraphic(sx, sy, GFX_SP_DISK_RED);
- else if (Store[x][y])
- DrawGraphicThruMask(sx, sy, graphic + frame);
+#if 1
+ if (Back[x][y] || Store[x][y])
+ DrawGraphicThruMask(sx, sy, graphic, frame);
else
- DrawGraphic(sx, sy, graphic + frame);
+ DrawGraphic(sx, sy, graphic, frame);
#else
if (game.emulation == EMU_SUPAPLEX)
- DrawNewGraphic(sx, sy, IMG_SP_DISK_RED, 0);
+ DrawGraphic(sx, sy, IMG_SP_DISK_RED, frame);
else if (Store[x][y])
- DrawNewGraphicThruMask(sx, sy, graphic, frame);
+ DrawGraphicThruMask(sx, sy, graphic, frame);
else
- DrawNewGraphic(sx, sy, graphic, frame);
+ DrawGraphic(sx, sy, graphic, frame);
#endif
}
void CheckDynamite(int x, int y)
{
- if (MovDelay[x][y]) /* dynamite is still waiting to explode */
+ if (MovDelay[x][y] != 0) /* dynamite is still waiting to explode */
{
MovDelay[x][y]--;
- if (MovDelay[x][y])
- {
- if (!(MovDelay[x][y] % 6))
- PlaySoundLevelAction(x, y, SND_ACTION_ACTIVE);
-
- if (IS_ACTIVE_BOMB(Feld[x][y]))
- {
- int delay = (Feld[x][y] == EL_DYNAMITE_ACTIVE ? 12 : 6);
- if (!(MovDelay[x][y] % delay))
- DrawDynamite(x, y);
- }
+ if (MovDelay[x][y] != 0)
+ {
+ DrawDynamite(x, y);
+ PlaySoundLevelActionIfLoop(x, y, ACTION_ACTIVE);
return;
}
}
- if (Feld[x][y] == EL_DYNAMITE_ACTIVE)
+#if 1
+ StopSoundLevelActionIfLoop(x, y, ACTION_ACTIVE);
+#else
+ if (Feld[x][y] == EL_DYNAMITE_ACTIVE ||
+ Feld[x][y] == EL_SP_DISK_RED_ACTIVE)
StopSound(SND_DYNAMITE_ACTIVE);
else
StopSound(SND_DYNABOMB_ACTIVE);
+#endif
Bang(x, y);
}
{
int center_element = Feld[ex][ey];
+ /* remove things displayed in background while burning dynamite */
+ if (!IS_INDESTRUCTIBLE(Back[ex][ey]))
+ Back[ex][ey] = 0;
+
if (IS_MOVING(ex, ey) || IS_BLOCKED(ex, ey))
{
/* put moving element to center field (and let it explode there) */
Feld[ex][ey] = center_element;
}
- for (y=ey-1; y<=ey+1; y++) for(x=ex-1; x<=ex+1; x++)
+ for (y = ey - 1; y <= ey + 1; y++) for(x = ex - 1; x <= ex + 1; x++)
{
int element;
RemoveMovingField(x, y);
}
- if (IS_MASSIVE(element) || element == EL_FLAMES)
+#if 1
+ if (IS_EXPLOSION_PROOF(element))
+ continue;
+#else
+ if ((IS_INDESTRUCTIBLE(element) &&
+ (game.engine_version < VERSION_IDENT(2,2,0) ||
+ (!IS_WALKABLE_OVER(element) && !IS_WALKABLE_UNDER(element)))) ||
+ element == EL_FLAMES)
continue;
+#endif
if (IS_PLAYER(x, y) && SHIELD_ON(PLAYERINFO(x, y)))
{
continue;
}
+ /* save walkable background elements while explosion on same tile */
+ if (IS_INDESTRUCTIBLE(element))
+ Back[x][y] = element;
+
+ /* ignite explodable elements reached by other explosion */
if (element == EL_EXPLOSION)
element = Store2[x][y];
{
switch(StorePlayer[ex][ey])
{
- case EL_PLAYER2:
+ case EL_PLAYER_2:
Store[x][y] = EL_EMERALD_RED;
break;
- case EL_PLAYER3:
+ case EL_PLAYER_3:
Store[x][y] = EL_EMERALD;
break;
- case EL_PLAYER4:
+ case EL_PLAYER_4:
Store[x][y] = EL_EMERALD_PURPLE;
break;
- case EL_PLAYER1:
+ case EL_PLAYER_1:
default:
Store[x][y] = EL_EMERALD_YELLOW;
break;
Store[x][y] = EL_BD_DIAMOND;
else if (center_element == EL_SP_ELECTRON)
Store[x][y] = EL_SP_INFOTRON;
- else if (center_element == EL_YAMYAM)
- Store[x][y] = level.yam_content[game.yam_content_nr][x-ex+1][y-ey+1];
else if (center_element == EL_AMOEBA_TO_DIAMOND)
Store[x][y] = level.amoeba_content;
+ else if (center_element == EL_YAMYAM)
+ Store[x][y] =
+ level.yamyam_content[game.yamyam_content_nr][x - ex + 1][y - ey + 1];
+ else if (IS_CUSTOM_ELEMENT(center_element))
+ Store[x][y] =
+ CUSTOM_ELEMENT_INFO(center_element).content[x - ex + 1][y - ey + 1];
else if (element == EL_WALL_EMERALD)
Store[x][y] = EL_EMERALD;
else if (element == EL_WALL_DIAMOND)
Store[x][y] = EL_PEARL;
else if (element == EL_WALL_CRYSTAL)
Store[x][y] = EL_CRYSTAL;
- else if (!IS_PFORTE(Store[x][y]))
+ else
Store[x][y] = EL_EMPTY;
if (x != ex || y != ey ||
if (AmoebaNr[x][y] &&
(element == EL_AMOEBA_FULL ||
element == EL_BD_AMOEBA ||
- element == EL_AMOEBA_CREATING))
+ element == EL_AMOEBA_GROWING))
{
AmoebaCnt[AmoebaNr[x][y]]--;
AmoebaCnt2[AmoebaNr[x][y]]--;
}
Feld[x][y] = EL_EXPLOSION;
+ GfxElement[x][y] = EL_UNDEFINED;
MovDir[x][y] = MovPos[x][y] = 0;
AmoebaNr[x][y] = 0;
- Frame[x][y] = 1;
+ ExplodePhase[x][y] = 1;
Stop[x][y] = TRUE;
}
if (center_element == EL_YAMYAM)
- game.yam_content_nr = (game.yam_content_nr + 1) % level.num_yam_contents;
+ game.yamyam_content_nr =
+ (game.yamyam_content_nr + 1) % level.num_yamyam_contents;
return;
}
x = ex;
y = ey;
- Frame[x][y] = (phase < last_phase ? phase + 1 : 0);
+ ExplodePhase[x][y] = (phase < last_phase ? phase + 1 : 0);
if (phase == first_phase_after_start)
{
if (IS_PLAYER(x, y))
KillHeroUnlessProtected(x, y);
- else if (IS_EXPLOSIVE(element))
+ else if (CAN_EXPLODE(element))
{
Feld[x][y] = Store2[x][y];
Store2[x][y] = 0;
element = Feld[x][y] = Store[x][y];
Store[x][y] = Store2[x][y] = 0;
+
+ if (Back[x][y] && IS_INDESTRUCTIBLE(Back[x][y]))
+ element = Feld[x][y] = Back[x][y];
+ Back[x][y] = 0;
+
MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0;
InitField(x, y, FALSE);
- if (CAN_MOVE(element) || COULD_MOVE(element))
+ if (CAN_MOVE(element))
InitMovDir(x, y);
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
if (IS_PLAYER(x, y) && !PLAYERINFO(x,y)->present)
StorePlayer[x][y] = 0;
}
- else if (!(phase % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+ else if (phase >= delay && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
{
-#if 0
- int graphic = GFX_EXPLOSION;
-
- if (game.emulation == EMU_SUPAPLEX)
- graphic = (Store[x][y] == EL_SP_INFOTRON ?
- GFX_SP_EXPLODE_INFOTRON :
- GFX_SP_EXPLODE_EMPTY);
-
- graphic += (phase / delay - 1);
-#else
- int graphic = IMG_EXPLOSION;
- int frame = (phase / delay - 1);
-
- if (game.emulation == EMU_SUPAPLEX)
- graphic = (Store[x][y] == EL_SP_INFOTRON ?
- IMG_SP_EXPLOSION_INFOTRON :
- IMG_SP_EXPLOSION);
-#endif
+ int stored = Store[x][y];
+ int graphic = (game.emulation != EMU_SUPAPLEX ? IMG_EXPLOSION :
+ stored == EL_SP_INFOTRON ? IMG_SP_EXPLOSION_INFOTRON :
+ IMG_SP_EXPLOSION);
+ int frame = getGraphicAnimationFrame(graphic, phase - delay);
if (phase == delay)
- ErdreichAnbroeckeln(SCREENX(x), SCREENY(y));
+ DrawLevelFieldCrumbledSand(x, y);
- if (IS_PFORTE(Store[x][y]))
+ if (IS_WALKABLE_OVER(Back[x][y]) && Back[x][y] != EL_EMPTY)
{
- DrawNewLevelElement(x, y, Store[x][y]);
-#if 0
- DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic);
-#else
- DrawNewGraphicThruMask(SCREENX(x), SCREENY(y), graphic, frame);
-#endif
+ DrawLevelElement(x, y, Back[x][y]);
+ DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic, frame);
}
- else
-#if 0
- DrawGraphic(SCREENX(x), SCREENY(y), graphic);
-#else
- DrawNewGraphic(SCREENX(x), SCREENY(y), graphic, frame);
-#endif
+ else if (IS_WALKABLE_UNDER(Back[x][y]))
+ {
+ DrawGraphic(SCREENX(x), SCREENY(y), graphic, frame);
+ DrawLevelElementThruMask(x, y, Back[x][y]);
+ }
+ else if (!IS_WALKABLE_INSIDE(Back[x][y]))
+ DrawGraphic(SCREENX(x), SCREENY(y), graphic, frame);
}
}
if (IS_ACTIVE_BOMB(Feld[ex][ey]))
{
- player = &stored_player[Feld[ex][ey] - EL_DYNABOMB_PLAYER1_ACTIVE];
+ player = &stored_player[Feld[ex][ey] - EL_DYNABOMB_PLAYER_1_ACTIVE];
dynabomb_size = player->dynabomb_size;
dynabomb_xl = player->dynabomb_xl;
player->dynabombs_left++;
int y = ey + j * xy[i % 4][1];
int element;
- if (!IN_LEV_FIELD(x, y) || IS_MASSIVE(Feld[x][y]))
+ if (!IN_LEV_FIELD(x, y) || IS_INDESTRUCTIBLE(Feld[x][y]))
break;
element = Feld[x][y];
RaiseScoreElement(element);
Explode(x, y, EX_PHASE_START, EX_NORMAL);
break;
- case EL_DYNABOMB_PLAYER1_ACTIVE:
- case EL_DYNABOMB_PLAYER2_ACTIVE:
- case EL_DYNABOMB_PLAYER3_ACTIVE:
- case EL_DYNABOMB_PLAYER4_ACTIVE:
- case EL_DYNABOMB_NR:
- case EL_DYNABOMB_SZ:
- case EL_DYNABOMB_XL:
+ case EL_DYNABOMB_PLAYER_1_ACTIVE:
+ case EL_DYNABOMB_PLAYER_2_ACTIVE:
+ case EL_DYNABOMB_PLAYER_3_ACTIVE:
+ case EL_DYNABOMB_PLAYER_4_ACTIVE:
+ case EL_DYNABOMB_INCREASE_NUMBER:
+ case EL_DYNABOMB_INCREASE_SIZE:
+ case EL_DYNABOMB_INCREASE_POWER:
DynaExplode(x, y);
break;
case EL_PENGUIN:
}
}
-void Blurb(int x, int y)
+void SplashAcid(int x, int y)
{
int element = Feld[x][y];
- if (element != EL_ACID_SPLASHING_LEFT &&
- element != EL_ACID_SPLASHING_RIGHT) /* start */
+ if (element != EL_ACID_SPLASH_LEFT &&
+ element != EL_ACID_SPLASH_RIGHT)
{
PlaySoundLevel(x, y, SND_ACID_SPLASHING);
+
if (IN_LEV_FIELD(x-1, y) && IS_FREE(x-1, y) &&
(!IN_LEV_FIELD(x-1, y-1) ||
!CAN_FALL(MovingOrBlocked2Element(x-1, y-1))))
- {
- Feld[x-1][y] = EL_ACID_SPLASHING_LEFT;
- }
+ Feld[x-1][y] = EL_ACID_SPLASH_LEFT;
+
if (IN_LEV_FIELD(x+1, y) && IS_FREE(x+1, y) &&
(!IN_LEV_FIELD(x+1, y-1) ||
!CAN_FALL(MovingOrBlocked2Element(x+1, y-1))))
- {
- Feld[x+1][y] = EL_ACID_SPLASHING_RIGHT;
- }
- }
- else /* go on */
- {
-#if 0
- int graphic =
- (element == EL_ACID_SPLASHING_LEFT ? GFX_BLURB_LEFT : GFX_BLURB_RIGHT);
-#else
- int graphic = (element == EL_ACID_SPLASHING_LEFT ?
- IMG_ACID_SPLASHING_LEFT :
- IMG_ACID_SPLASHING_RIGHT);
-#endif
-
- if (!MovDelay[x][y]) /* initialize animation counter */
- MovDelay[x][y] = 9;
-
- if (MovDelay[x][y]) /* continue animation */
- {
- MovDelay[x][y]--;
- if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
-#if 0
- DrawGraphic(SCREENX(x), SCREENY(y), graphic+4-MovDelay[x][y]/2);
-#else
- {
- int frame = getNewGraphicAnimationFrame(graphic, 8 - MovDelay[x][y]);
-
- DrawNewGraphic(SCREENX(x), SCREENY(y), graphic, frame);
- }
-#endif
-
- if (!MovDelay[x][y])
- {
- Feld[x][y] = EL_EMPTY;
- DrawNewLevelField(x, y);
- }
- }
+ Feld[x+1][y] = EL_ACID_SPLASH_RIGHT;
}
}
-static void ToggleBeltSwitch(int x, int y)
+static void InitBeltMovement()
{
static int belt_base_element[4] =
{
- EL_CONVEYOR_BELT1_LEFT,
- EL_CONVEYOR_BELT2_LEFT,
- EL_CONVEYOR_BELT3_LEFT,
- EL_CONVEYOR_BELT4_LEFT
+ EL_CONVEYOR_BELT_1_LEFT,
+ EL_CONVEYOR_BELT_2_LEFT,
+ EL_CONVEYOR_BELT_3_LEFT,
+ EL_CONVEYOR_BELT_4_LEFT
};
static int belt_base_active_element[4] =
{
- EL_CONVEYOR_BELT1_LEFT_ACTIVE,
- EL_CONVEYOR_BELT2_LEFT_ACTIVE,
- EL_CONVEYOR_BELT3_LEFT_ACTIVE,
- EL_CONVEYOR_BELT4_LEFT_ACTIVE
+ EL_CONVEYOR_BELT_1_LEFT_ACTIVE,
+ EL_CONVEYOR_BELT_2_LEFT_ACTIVE,
+ EL_CONVEYOR_BELT_3_LEFT_ACTIVE,
+ EL_CONVEYOR_BELT_4_LEFT_ACTIVE
};
- static int belt_base_switch_element[4] =
+
+ int x, y, i, j;
+
+ /* set frame order for belt animation graphic according to belt direction */
+ for (i=0; i<4; i++)
{
- EL_CONVEYOR_BELT1_SWITCH_LEFT,
- EL_CONVEYOR_BELT2_SWITCH_LEFT,
- EL_CONVEYOR_BELT3_SWITCH_LEFT,
- EL_CONVEYOR_BELT4_SWITCH_LEFT
- };
+ int belt_nr = i;
+
+ for (j=0; j<3; j++)
+ {
+ int element = belt_base_active_element[belt_nr] + j;
+ int graphic = el2img(element);
+
+ if (game.belt_dir[i] == MV_LEFT)
+ graphic_info[graphic].anim_mode &= ~ANIM_REVERSE;
+ else
+ graphic_info[graphic].anim_mode |= ANIM_REVERSE;
+ }
+ }
+
+ for(y=0; y<lev_fieldy; y++)
+ {
+ for(x=0; x<lev_fieldx; x++)
+ {
+ int element = Feld[x][y];
+
+ for (i=0; i<4; i++)
+ {
+ if (IS_BELT(element) && game.belt_dir[i] != MV_NO_MOVING)
+ {
+ int e_belt_nr = getBeltNrFromBeltElement(element);
+ int belt_nr = i;
+
+ if (e_belt_nr == belt_nr)
+ {
+ int belt_part = Feld[x][y] - belt_base_element[belt_nr];
+
+ Feld[x][y] = belt_base_active_element[belt_nr] + belt_part;
+ }
+ }
+ }
+ }
+ }
+}
+
+static void ToggleBeltSwitch(int x, int y)
+{
+ static int belt_base_element[4] =
+ {
+ EL_CONVEYOR_BELT_1_LEFT,
+ EL_CONVEYOR_BELT_2_LEFT,
+ EL_CONVEYOR_BELT_3_LEFT,
+ EL_CONVEYOR_BELT_4_LEFT
+ };
+ static int belt_base_active_element[4] =
+ {
+ EL_CONVEYOR_BELT_1_LEFT_ACTIVE,
+ EL_CONVEYOR_BELT_2_LEFT_ACTIVE,
+ EL_CONVEYOR_BELT_3_LEFT_ACTIVE,
+ EL_CONVEYOR_BELT_4_LEFT_ACTIVE
+ };
+ static int belt_base_switch_element[4] =
+ {
+ EL_CONVEYOR_BELT_1_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_2_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_3_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_4_SWITCH_LEFT
+ };
static int belt_move_dir[4] =
{
MV_LEFT,
int graphic = el2img(element);
if (belt_dir == MV_LEFT)
- new_graphic_info[graphic].anim_mode &= ~ANIM_REVERSE;
+ graphic_info[graphic].anim_mode &= ~ANIM_REVERSE;
else
- new_graphic_info[graphic].anim_mode |= ANIM_REVERSE;
+ graphic_info[graphic].anim_mode |= ANIM_REVERSE;
}
for (yy=0; yy<lev_fieldy; yy++)
if (e_belt_nr == belt_nr)
{
Feld[xx][yy] = belt_base_switch_element[belt_nr] + belt_dir_nr;
- DrawNewLevelField(xx, yy);
+ DrawLevelField(xx, yy);
}
}
else if (IS_BELT(element) && belt_dir != MV_NO_MOVING)
int belt_part = Feld[xx][yy] - belt_base_element[belt_nr];
Feld[xx][yy] = belt_base_active_element[belt_nr] + belt_part;
- DrawNewLevelField(xx, yy);
+ DrawLevelField(xx, yy);
}
}
else if (IS_BELT_ACTIVE(element) && belt_dir == MV_NO_MOVING)
int belt_part = Feld[xx][yy] - belt_base_active_element[belt_nr];
Feld[xx][yy] = belt_base_element[belt_nr] + belt_part;
- DrawNewLevelField(xx, yy);
+ DrawLevelField(xx, yy);
}
}
}
element == EL_SWITCHGATE_SWITCH_DOWN)
{
Feld[xx][yy] = EL_SWITCHGATE_SWITCH_UP + game.switchgate_pos;
- DrawNewLevelField(xx, yy);
+ DrawLevelField(xx, yy);
}
else if (element == EL_SWITCHGATE_OPEN ||
element == EL_SWITCHGATE_OPENING)
{
Feld[xx][yy] = EL_SWITCHGATE_CLOSING;
+#if 1
+ PlaySoundLevelAction(xx, yy, ACTION_CLOSING);
+#else
PlaySoundLevel(xx, yy, SND_SWITCHGATE_CLOSING);
+#endif
}
else if (element == EL_SWITCHGATE_CLOSED ||
element == EL_SWITCHGATE_CLOSING)
{
Feld[xx][yy] = EL_SWITCHGATE_OPENING;
+#if 1
+ PlaySoundLevelAction(xx, yy, ACTION_OPENING);
+#else
PlaySoundLevel(xx, yy, SND_SWITCHGATE_OPENING);
+#endif
}
}
}
game.light_time_left > 0)
{
Feld[x][y] = EL_LIGHT_SWITCH_ACTIVE;
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
}
else if (element == EL_LIGHT_SWITCH_ACTIVE &&
game.light_time_left == 0)
{
Feld[x][y] = EL_LIGHT_SWITCH;
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
}
else if (element == EL_INVISIBLE_STEELWALL ||
element == EL_INVISIBLE_WALL ||
if (game.light_time_left > 0)
Feld[x][y] = getInvisibleActiveFromInvisibleElement(element);
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
}
else if (element == EL_INVISIBLE_STEELWALL_ACTIVE ||
element == EL_INVISIBLE_WALL_ACTIVE ||
if (game.light_time_left == 0)
Feld[x][y] = getInvisibleFromInvisibleActiveElement(element);
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
}
}
}
return;
object_hit = (!IS_FREE(x, y+1) && (!IS_MOVING(x, y+1) ||
- MovDir[x][y+1]!=MV_DOWN ||
- MovPos[x][y+1]<=TILEY/2));
+ MovDir[x][y+1] != MV_DOWN ||
+ MovPos[x][y+1] <= TILEY / 2));
if (object_hit)
smashed = MovingOrBlocked2Element(x, y+1);
}
if (!lastline && smashed == EL_ACID) /* element falls into acid */
{
- Blurb(x, y);
+ SplashAcid(x, y);
return;
}
+ if (lastline || object_hit)
+ {
+ ResetGfxAnimation(x, y);
+ DrawLevelField(x, y);
+ }
+
if ((element == EL_BOMB ||
element == EL_SP_DISK_ORANGE ||
element == EL_DX_SUPABOMB) &&
- (lastline || object_hit)) /* element is bomb */
+ (lastline || object_hit)) /* element is bomb */
{
Bang(x, y);
return;
Bang(x, y+1);
else
{
- Feld[x][y] = EL_AMOEBA_CREATING;
+ Feld[x][y] = EL_AMOEBA_GROWING;
Store[x][y] = EL_AMOEBA_WET;
+
+ ResetRandomAnimationValue(x, y);
}
return;
}
if (!lastline && object_hit) /* check which object was hit */
{
- if (CAN_CHANGE(element) &&
- (smashed == EL_MAGIC_WALL || smashed == EL_BD_MAGIC_WALL))
+ if (CAN_PASS_MAGIC_WALL(element) &&
+ (smashed == EL_MAGIC_WALL ||
+ smashed == EL_BD_MAGIC_WALL))
{
int xx, yy;
int activated_magic_wall =
SND_BD_MAGIC_WALL_ACTIVATING));
}
- if (IS_PLAYER(x, y+1))
+ if (IS_PLAYER(x, y + 1))
{
KillHeroUnlessProtected(x, y+1);
return;
}
else if (smashed == EL_PENGUIN)
{
- Bang(x, y+1);
+ Bang(x, y + 1);
return;
}
else if (element == EL_BD_DIAMOND)
{
if (IS_ENEMY(smashed) && IS_BD_ELEMENT(smashed))
{
- Bang(x, y+1);
+ Bang(x, y + 1);
return;
}
}
- else if ((element == EL_SP_INFOTRON || element == EL_SP_ZONK) &&
- (smashed == EL_SP_SNIKSNAK || smashed == EL_SP_ELECTRON ||
+ else if ((element == EL_SP_INFOTRON ||
+ element == EL_SP_ZONK) &&
+ (smashed == EL_SP_SNIKSNAK ||
+ smashed == EL_SP_ELECTRON ||
smashed == EL_SP_DISK_ORANGE))
{
- Bang(x, y+1);
+ Bang(x, y + 1);
return;
}
else if (element == EL_ROCK ||
element == EL_BD_ROCK)
{
if (IS_ENEMY(smashed) ||
- smashed == EL_BOMB || smashed == EL_SP_DISK_ORANGE ||
+ smashed == EL_BOMB ||
+ smashed == EL_SP_DISK_ORANGE ||
smashed == EL_DX_SUPABOMB ||
- smashed == EL_SATELLITE || smashed == EL_PIG ||
- smashed == EL_DRAGON || smashed == EL_MOLE)
+ smashed == EL_SATELLITE ||
+ smashed == EL_PIG ||
+ smashed == EL_DRAGON ||
+ smashed == EL_MOLE)
{
- Bang(x, y+1);
+ Bang(x, y + 1);
return;
}
- else if (!IS_MOVING(x, y+1))
+ else if (!IS_MOVING(x, y + 1))
{
- if (smashed == EL_LAMP || smashed == EL_LAMP_ACTIVE)
+ if (smashed == EL_LAMP ||
+ smashed == EL_LAMP_ACTIVE)
{
- Bang(x, y+1);
+ Bang(x, y + 1);
return;
}
else if (smashed == EL_NUT)
{
- Feld[x][y+1] = EL_CRACKINGNUT;
- PlaySoundLevel(x, y, SND_NUT_CRACKING);
+ Feld[x][y+1] = EL_NUT_BREAKING;
+ PlaySoundLevel(x, y, SND_NUT_BREAKING);
RaiseScoreElement(EL_NUT);
return;
}
Feld[x][y+1] == EL_BD_MAGIC_WALL_ACTIVE))
{
if (Feld[x][y+1] == EL_MAGIC_WALL_ACTIVE)
- PlaySoundLevel(x, y, SND_MAGIC_WALL_CHANGING);
+ PlaySoundLevel(x, y, SND_MAGIC_WALL_FILLING);
else if (Feld[x][y+1] == EL_BD_MAGIC_WALL_ACTIVE)
- PlaySoundLevel(x, y, SND_BD_MAGIC_WALL_CHANGING);
+ PlaySoundLevel(x, y, SND_BD_MAGIC_WALL_FILLING);
return;
}
/* play sound of object that hits the ground */
if (lastline || object_hit)
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_IMPACT);
+ PlaySoundLevelElementAction(x, y, element, ACTION_IMPACT);
}
void TurnRound(int x, int y)
int element = Feld[x][y];
int old_move_dir = MovDir[x][y];
- int left_dir = turn[old_move_dir].left;
+ int left_dir = turn[old_move_dir].left;
int right_dir = turn[old_move_dir].right;
- int back_dir = turn[old_move_dir].back;
+ int back_dir = turn[old_move_dir].back;
- int left_dx = move_xy[left_dir].x, left_dy = move_xy[left_dir].y;
- int right_dx = move_xy[right_dir].x, right_dy = move_xy[right_dir].y;
- int move_dx = move_xy[old_move_dir].x, move_dy = move_xy[old_move_dir].y;
- int back_dx = move_xy[back_dir].x, back_dy = move_xy[back_dir].y;
+ int left_dx = move_xy[left_dir].x, left_dy = move_xy[left_dir].y;
+ int right_dx = move_xy[right_dir].x, right_dy = move_xy[right_dir].y;
+ int move_dx = move_xy[old_move_dir].x, move_dy = move_xy[old_move_dir].y;
+ int back_dx = move_xy[back_dir].x, back_dy = move_xy[back_dir].y;
- int left_x = x+left_dx, left_y = y+left_dy;
- int right_x = x+right_dx, right_y = y+right_dy;
- int move_x = x+move_dx, move_y = y+move_dy;
+ int left_x = x + left_dx, left_y = y + left_dy;
+ int right_x = x + right_dx, right_y = y + right_dy;
+ int move_x = x + move_dx, move_y = y + move_dy;
if (element == EL_BUG || element == EL_BD_BUTTERFLY)
{
if (IN_LEV_FIELD(left_x, left_y) &&
(IS_FREE_OR_PLAYER(left_x, left_y) ||
- IS_MAMPF2(Feld[left_x][left_y])))
+ IS_FOOD_DARK_YAMYAM(Feld[left_x][left_y])))
can_turn_left = TRUE;
if (IN_LEV_FIELD(right_x, right_y) &&
(IS_FREE_OR_PLAYER(right_x, right_y) ||
- IS_MAMPF2(Feld[right_x][right_y])))
+ IS_FOOD_DARK_YAMYAM(Feld[right_x][right_y])))
can_turn_right = TRUE;
if (can_turn_left && can_turn_right)
int rnd = RND(rnd_value);
if (IN_LEV_FIELD(left_x, left_y) &&
- (IS_FREE(left_x, left_y) || IS_GEM(Feld[left_x][left_y])))
+ (IS_FREE(left_x, left_y) || IS_FOOD_PIG(Feld[left_x][left_y])))
can_turn_left = TRUE;
if (IN_LEV_FIELD(right_x, right_y) &&
- (IS_FREE(right_x, right_y) || IS_GEM(Feld[right_x][right_y])))
+ (IS_FREE(right_x, right_y) || IS_FOOD_PIG(Feld[right_x][right_y])))
can_turn_right = TRUE;
if (IN_LEV_FIELD(move_x, move_y) &&
- (IS_FREE(move_x, move_y) || IS_GEM(Feld[move_x][move_y])))
+ (IS_FREE(move_x, move_y) || IS_FOOD_PIG(Feld[move_x][move_y])))
can_move_on = TRUE;
if (can_turn_left &&
MovDir[x][y] = back_dir;
if (!IS_FREE(x+move_xy[MovDir[x][y]].x, y+move_xy[MovDir[x][y]].y) &&
- !IS_GEM(Feld[x+move_xy[MovDir[x][y]].x][y+move_xy[MovDir[x][y]].y]))
+ !IS_FOOD_PIG(Feld[x+move_xy[MovDir[x][y]].x][y+move_xy[MovDir[x][y]].y]))
MovDir[x][y] = old_move_dir;
MovDelay[x][y] = 0;
MovDir[x][y] = game.balloon_dir;
MovDelay[x][y] = 0;
}
- else if (element == EL_SPRING_MOVING)
+ else if (element == EL_SPRING)
{
- if (!IN_LEV_FIELD(move_x, move_y) || !IS_FREE(move_x, move_y) ||
- (IN_LEV_FIELD(x, y+1) && IS_FREE(x, y+1)))
- {
- Feld[x][y] = EL_SPRING;
+ if ((MovDir[x][y] == MV_LEFT || MovDir[x][y] == MV_RIGHT) &&
+ (!IN_LEV_FIELD(move_x, move_y) || !IS_FREE(move_x, move_y) ||
+ (IN_LEV_FIELD(x, y + 1) && IS_FREE(x, y + 1))))
MovDir[x][y] = MV_NO_MOVING;
- }
+
MovDelay[x][y] = 0;
}
- else if (element == EL_ROBOT || element == EL_SATELLITE || element == EL_PENGUIN)
+ else if (element == EL_ROBOT ||
+ element == EL_SATELLITE ||
+ element == EL_PENGUIN)
{
int attr_x = -1, attr_y = -1;
}
}
- if (element == EL_ROBOT && ZX>=0 && ZY>=0)
+ if (element == EL_ROBOT && ZX >= 0 && ZY >= 0)
{
attr_x = ZX;
attr_y = ZY;
Feld[newx][newy] == EL_ACID ||
(element == EL_PENGUIN &&
(Feld[newx][newy] == EL_EXIT_OPEN ||
- IS_MAMPF3(Feld[newx][newy])))))
+ IS_FOOD_PENGUIN(Feld[newx][newy])))))
return;
MovDir[x][y] =
Feld[newx][newy] == EL_ACID ||
(element == EL_PENGUIN &&
(Feld[newx][newy] == EL_EXIT_OPEN ||
- IS_MAMPF3(Feld[newx][newy])))))
+ IS_FOOD_PENGUIN(Feld[newx][newy])))))
return;
MovDir[x][y] = old_move_dir;
void StartMoving(int x, int y)
{
+ boolean use_spring_bug = (game.engine_version < VERSION_IDENT(2,2,0));
+ boolean started_moving = FALSE; /* some elements can fall _and_ move */
int element = Feld[x][y];
if (Stop[x][y])
return;
- GfxAction[x][y] = GFX_ACTION_DEFAULT;
+ GfxAction[x][y] = ACTION_DEFAULT;
- if (CAN_FALL(element) && y<lev_fieldy-1)
+ if (CAN_FALL(element) && y < lev_fieldy - 1)
{
if ((x>0 && IS_PLAYER(x-1, y)) || (x<lev_fieldx-1 && IS_PLAYER(x+1, y)))
if (JustBeingPushed(x, y))
if (IS_FREE(x, y+1))
{
InitMovingField(x, y, MV_DOWN);
+ started_moving = TRUE;
+
Feld[x][y] = EL_QUICKSAND_EMPTYING;
Store[x][y] = EL_ROCK;
+#if 1
+ PlaySoundLevelAction(x, y, ACTION_EMPTYING);
+#else
PlaySoundLevel(x, y, SND_QUICKSAND_EMPTYING);
+#endif
}
else if (Feld[x][y+1] == EL_QUICKSAND_EMPTY)
{
Feld[x][y+1] = EL_QUICKSAND_FULL;
Store[x][y+1] = Store[x][y];
Store[x][y] = 0;
- PlaySoundLevel(x, y, SND_QUICKSAND_SLIPPING);
+#if 1
+ PlaySoundLevelAction(x, y, ACTION_FILLING);
+#else
+ PlaySoundLevel(x, y, SND_QUICKSAND_FILLING);
+#endif
}
}
else if ((element == EL_ROCK || element == EL_BD_ROCK) &&
Feld[x][y+1] == EL_QUICKSAND_EMPTY)
{
InitMovingField(x, y, MV_DOWN);
+ started_moving = TRUE;
+
Feld[x][y] = EL_QUICKSAND_FILLING;
Store[x][y] = element;
+#if 1
+ PlaySoundLevelAction(x, y, ACTION_FILLING);
+#else
PlaySoundLevel(x, y, SND_QUICKSAND_FILLING);
+#endif
}
else if (element == EL_MAGIC_WALL_FULL)
{
if (IS_FREE(x, y+1))
{
InitMovingField(x, y, MV_DOWN);
+ started_moving = TRUE;
+
Feld[x][y] = EL_MAGIC_WALL_EMPTYING;
Store[x][y] = EL_CHANGED(Store[x][y]);
}
if (IS_FREE(x, y+1))
{
InitMovingField(x, y, MV_DOWN);
+ started_moving = TRUE;
+
Feld[x][y] = EL_BD_MAGIC_WALL_EMPTYING;
Store[x][y] = EL_CHANGED2(Store[x][y]);
}
Store[x][y] = 0;
}
}
- else if (CAN_CHANGE(element) &&
+ else if (CAN_PASS_MAGIC_WALL(element) &&
(Feld[x][y+1] == EL_MAGIC_WALL_ACTIVE ||
Feld[x][y+1] == EL_BD_MAGIC_WALL_ACTIVE))
{
InitMovingField(x, y, MV_DOWN);
+ started_moving = TRUE;
+
Feld[x][y] =
(Feld[x][y+1] == EL_MAGIC_WALL_ACTIVE ? EL_MAGIC_WALL_FILLING :
EL_BD_MAGIC_WALL_FILLING);
Store[x][y] = element;
}
+#if 0
else if (CAN_SMASH(element) && Feld[x][y+1] == EL_ACID)
+#else
+ else if (CAN_FALL(element) && Feld[x][y+1] == EL_ACID)
+#endif
{
- Blurb(x, y);
+ SplashAcid(x, y);
+
InitMovingField(x, y, MV_DOWN);
+ started_moving = TRUE;
+
Store[x][y] = EL_ACID;
+#if 0
+ /* !!! TEST !!! better use "_FALLING" etc. !!! */
+ GfxAction[x][y+1] = ACTION_ACTIVE;
+#endif
}
else if (CAN_SMASH(element) && Feld[x][y+1] == EL_BLOCKED &&
JustStopped[x][y])
{
Impact(x, y);
}
+ else if (IS_FREE(x, y+1) && element == EL_SPRING && use_spring_bug)
+ {
+ if (MovDir[x][y] == MV_NO_MOVING)
+ {
+ InitMovingField(x, y, MV_DOWN);
+ started_moving = TRUE;
+ }
+ }
else if (IS_FREE(x, y+1))
{
+ if (JustStopped[x][y]) /* prevent animation from being restarted */
+ MovDir[x][y] = MV_DOWN;
+
InitMovingField(x, y, MV_DOWN);
+ started_moving = TRUE;
}
else if (element == EL_AMOEBA_DROP)
{
- Feld[x][y] = EL_AMOEBA_CREATING;
+ Feld[x][y] = EL_AMOEBA_GROWING;
Store[x][y] = EL_AMOEBA_WET;
}
/* Store[x][y+1] must be zero, because:
left = !(right = RND(2));
InitMovingField(x, y, left ? MV_LEFT : MV_RIGHT);
+ started_moving = TRUE;
}
}
else if (IS_BELT_ACTIVE(Feld[x][y+1]))
if ((belt_dir == MV_LEFT && left_is_free) ||
(belt_dir == MV_RIGHT && right_is_free))
+ {
InitMovingField(x, y, belt_dir);
+ started_moving = TRUE;
+
+ GfxAction[x][y] = ACTION_DEFAULT;
+ }
}
}
- else if (CAN_MOVE(element))
+
+ /* not "else if" because of EL_SPRING */
+ if (CAN_MOVE(element) && !started_moving)
{
int newx, newy;
- if ((element == EL_SATELLITE || element == EL_BALLOON ||
- element == EL_SPRING_MOVING)
+ if ((element == EL_SATELLITE ||
+ element == EL_BALLOON ||
+ element == EL_SPRING)
&& JustBeingPushed(x, y))
return;
+#if 0
+#if 0
+ if (element == EL_SPRING && MovDir[x][y] == MV_DOWN)
+ Feld[x][y + 1] = EL_EMPTY; /* was set to EL_BLOCKED above */
+#else
+ if (element == EL_SPRING && MovDir[x][y] != MV_NO_MOVING)
+ {
+ Moving2Blocked(x, y, &newx, &newy);
+ if (Feld[newx][newy] == EL_BLOCKED)
+ Feld[newx][newy] = EL_EMPTY; /* was set to EL_BLOCKED above */
+ }
+#endif
+#endif
+
if (!MovDelay[x][y]) /* start new movement phase */
{
- /* all objects that can change their move direction after each step */
- /* (MAMPFER, MAMPFER2 and PACMAN go straight until they hit a wall */
+ /* all objects that can change their move direction after each step
+ (YAMYAM, DARK_YAMYAM and PACMAN go straight until they hit a wall */
- if (element!=EL_YAMYAM && element!=EL_DARK_YAMYAM && element!=EL_PACMAN)
+ if (element != EL_YAMYAM &&
+ element != EL_DARK_YAMYAM &&
+ element != EL_PACMAN)
{
TurnRound(x, y);
element == EL_SP_SNIKSNAK ||
element == EL_SP_ELECTRON ||
element == EL_MOLE))
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
}
}
MovDelay[x][y]--;
if (element == EL_ROBOT ||
- element == EL_YAMYAM || element == EL_DARK_YAMYAM)
+ element == EL_YAMYAM ||
+ element == EL_DARK_YAMYAM)
{
- int phase = MovDelay[x][y] % 8;
-
- if (phase > 3)
- phase = 7 - phase;
-
- if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
-#if 0
- DrawGraphic(SCREENX(x), SCREENY(y), el2gfx(element) + phase);
-#else
- {
- int graphic = el2img(element);
- int frame = getNewGraphicAnimationFrame(graphic, MovDelay[x][y] % 8);
-
- DrawNewGraphic(SCREENX(x), SCREENY(y), graphic, frame);
- }
-#endif
-
- if (MovDelay[x][y] % 4 == 3)
- {
- if (element == EL_YAMYAM)
- PlaySoundLevel(x, y, SND_YAMYAM_WAITING);
- else if (element == EL_DARK_YAMYAM)
- PlaySoundLevel(x, y, SND_DARK_YAMYAM_WAITING);
- }
+ DrawLevelElementAnimationIfNeeded(x, y, element);
+ PlaySoundLevelAction(x, y, ACTION_WAITING);
}
else if (element == EL_SP_ELECTRON)
-#if 0
- DrawGraphicAnimation(x, y, GFX2_SP_ELECTRON, 8, 2, ANIM_LOOP);
-#else
- DrawNewGraphicAnimation(x, y, IMG_SP_ELECTRON);
-#endif
+ DrawLevelElementAnimationIfNeeded(x, y, element);
else if (element == EL_DRAGON)
{
int i;
int dir = MovDir[x][y];
int dx = (dir == MV_LEFT ? -1 : dir == MV_RIGHT ? +1 : 0);
int dy = (dir == MV_UP ? -1 : dir == MV_DOWN ? +1 : 0);
-#if 0
- int graphic = (dir == MV_LEFT ? GFX_FLAMMEN_LEFT :
- dir == MV_RIGHT ? GFX_FLAMMEN_RIGHT :
- dir == MV_UP ? GFX_FLAMMEN_UP :
- dir == MV_DOWN ? GFX_FLAMMEN_DOWN : GFX_LEERRAUM);
- int phase = FrameCounter % 2;
-#else
- int graphic = (dir == MV_LEFT ? IMG_FLAMES_LEFT1 :
- dir == MV_RIGHT ? IMG_FLAMES_RIGHT1 :
- dir == MV_UP ? IMG_FLAMES_UP1 :
- dir == MV_DOWN ? IMG_FLAMES_DOWN1 : IMG_EMPTY);
- int frame = getNewGraphicAnimationFrame(graphic, -1);
-#endif
+ int graphic = (dir == MV_LEFT ? IMG_FLAMES_1_LEFT :
+ dir == MV_RIGHT ? IMG_FLAMES_1_RIGHT :
+ dir == MV_UP ? IMG_FLAMES_1_UP :
+ dir == MV_DOWN ? IMG_FLAMES_1_DOWN : IMG_EMPTY);
+ int frame = getGraphicAnimationFrame(graphic, -1);
for (i=1; i<=3; i++)
{
int sx = SCREENX(xx), sy = SCREENY(yy);
int flame_graphic = graphic + (i - 1);
- if (!IN_LEV_FIELD(xx, yy) ||
- IS_SOLID(Feld[xx][yy]) || Feld[xx][yy] == EL_EXPLOSION)
+ if (!IN_LEV_FIELD(xx, yy) || IS_DRAGONFIRE_PROOF(Feld[xx][yy]))
break;
if (MovDelay[x][y])
{
int flamed = MovingOrBlocked2Element(xx, yy);
- if (IS_ENEMY(flamed) || IS_EXPLOSIVE(flamed))
+ if (IS_ENEMY(flamed) || CAN_EXPLODE(flamed))
Bang(xx, yy);
else
RemoveMovingField(xx, yy);
Feld[xx][yy] = EL_FLAMES;
if (IN_SCR_FIELD(sx, sy))
-#if 0
- DrawGraphic(sx, sy, graphic + phase*3 + i-1);
-#else
- DrawNewGraphic(sx, sy, flame_graphic, frame);
-#endif
+ DrawGraphic(sx, sy, flame_graphic, frame);
}
else
{
if (Feld[xx][yy] == EL_FLAMES)
Feld[xx][yy] = EL_EMPTY;
- DrawNewLevelField(xx, yy);
+ DrawLevelField(xx, yy);
}
}
}
if (MovDelay[x][y]) /* element still has to wait some time */
{
- PlaySoundLevelAction(x, y, SND_ACTION_WAITING);
+ PlaySoundLevelAction(x, y, ACTION_WAITING);
return;
}
IN_LEV_FIELD(newx, newy) &&
MovDir[x][y] == MV_DOWN && Feld[newx][newy] == EL_ACID)
{
- Blurb(x, y);
+ SplashAcid(x, y);
Store[x][y] = EL_ACID;
}
else if (element == EL_PENGUIN && IN_LEV_FIELD(newx, newy))
if (Feld[newx][newy] == EL_EXIT_OPEN)
{
Feld[x][y] = EL_EMPTY;
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
- PlaySoundLevel(newx, newy, SND_PENGUIN_PASSING_EXIT);
+ PlaySoundLevel(newx, newy, SND_PENGUIN_PASSING);
if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
-#if 0
- DrawGraphicThruMask(SCREENX(newx), SCREENY(newy), el2gfx(element));
-#else
- DrawNewGraphicThruMask(SCREENX(newx), SCREENY(newy), el2img(element),
- 0);
-#endif
+ DrawGraphicThruMask(SCREENX(newx),SCREENY(newy), el2img(element), 0);
local_player->friends_still_needed--;
if (!local_player->friends_still_needed &&
return;
}
- else if (IS_MAMPF3(Feld[newx][newy]))
+ else if (IS_FOOD_PENGUIN(Feld[newx][newy]))
{
if (DigField(local_player, newx, newy, 0, 0, DF_DIG) == MF_MOVING)
- DrawNewLevelField(newx, newy);
+ DrawLevelField(newx, newy);
else
MovDir[x][y] = MV_NO_MOVING;
}
if (IS_PLAYER(x, y))
DrawPlayerField(x, y);
else
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
return;
}
}
else if (element == EL_PIG && IN_LEV_FIELD(newx, newy))
{
- if (IS_GEM(Feld[newx][newy]))
+ if (IS_FOOD_PIG(Feld[newx][newy]))
{
if (IS_MOVING(newx, newy))
RemoveMovingField(newx, newy);
else
{
Feld[newx][newy] = EL_EMPTY;
- DrawNewLevelField(newx, newy);
+ DrawLevelField(newx, newy);
}
- PlaySoundLevel(x, y, SND_PIG_EATING);
+ PlaySoundLevel(x, y, SND_PIG_DIGGING);
}
else if (!IS_FREE(newx, newy))
{
if (IS_PLAYER(x, y))
DrawPlayerField(x, y);
else
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
return;
}
}
if (IS_PLAYER(x, y))
DrawPlayerField(x, y);
else
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
return;
}
else
if (IS_PLAYER(x, y))
DrawPlayerField(x, y);
else
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
PlaySoundLevel(x, y, SND_DRAGON_ATTACKING);
else
{
Feld[newx][newy] = EL_EMPTY;
- DrawNewLevelField(newx, newy);
+ DrawLevelField(newx, newy);
}
- PlaySoundLevel(x, y, SND_YAMYAM_EATING);
+ PlaySoundLevel(x, y, SND_YAMYAM_DIGGING);
}
else if (element == EL_DARK_YAMYAM && IN_LEV_FIELD(newx, newy) &&
- IS_MAMPF2(Feld[newx][newy]))
+ IS_FOOD_DARK_YAMYAM(Feld[newx][newy]))
{
if (AmoebaNr[newx][newy])
{
else
{
Feld[newx][newy] = EL_EMPTY;
- DrawNewLevelField(newx, newy);
+ DrawLevelField(newx, newy);
}
- PlaySoundLevel(x, y, SND_DARK_YAMYAM_EATING);
+ PlaySoundLevel(x, y, SND_DARK_YAMYAM_DIGGING);
}
else if ((element == EL_PACMAN || element == EL_MOLE)
&& IN_LEV_FIELD(newx, newy) && IS_AMOEBOID(Feld[newx][newy]))
if (element == EL_MOLE)
{
Feld[newx][newy] = EL_AMOEBA_SHRINKING;
- PlaySoundLevel(x, y, SND_MOLE_EATING);
+ PlaySoundLevel(x, y, SND_MOLE_DIGGING);
MovDelay[newx][newy] = 0; /* start amoeba shrinking delay */
return; /* wait for shrinking amoeba */
}
else /* element == EL_PACMAN */
{
Feld[newx][newy] = EL_EMPTY;
- DrawNewLevelField(newx, newy);
- PlaySoundLevel(x, y, SND_PACMAN_EATING);
+ DrawLevelField(newx, newy);
+ PlaySoundLevel(x, y, SND_PACMAN_DIGGING);
}
}
else if (element == EL_MOLE && IN_LEV_FIELD(newx, newy) &&
if (element == EL_BUG || element == EL_SPACESHIP ||
element == EL_SP_SNIKSNAK)
-#if 0
DrawLevelField(x, y);
-#else
- DrawNewLevelField(x, y);
-#endif
else if (element == EL_BUG || element == EL_SPACESHIP ||
element == EL_SP_SNIKSNAK || element == EL_MOLE)
-#if 0
DrawLevelField(x, y);
-#else
- DrawNewLevelField(x, y);
-#endif
else if (element == EL_BD_BUTTERFLY || element == EL_BD_FIREFLY)
-#if 0
- DrawGraphicAnimation(x, y, el2gfx(element), 2, 4, ANIM_LOOP);
-#else
- DrawNewGraphicAnimation(x, y, el2img(element));
-#endif
+ DrawLevelElementAnimationIfNeeded(x, y, element);
else if (element == EL_SATELLITE)
-#if 0
- DrawGraphicAnimation(x, y, GFX_SONDE_START, 8, 2, ANIM_LOOP);
-#else
- DrawNewGraphicAnimation(x, y, IMG_SATELLITE);
-#endif
+ DrawLevelElementAnimationIfNeeded(x, y, element);
else if (element == EL_SP_ELECTRON)
-#if 0
- DrawGraphicAnimation(x, y, GFX2_SP_ELECTRON, 8, 2, ANIM_LOOP);
-#else
- DrawNewGraphicAnimation(x, y, IMG_SP_ELECTRON);
-#endif
+ DrawLevelElementAnimationIfNeeded(x, y, element);
if (DONT_TOUCH(element))
TestIfBadThingTouchesHero(x, y);
- PlaySoundLevelAction(x, y, SND_ACTION_WAITING);
+ PlaySoundLevelAction(x, y, ACTION_WAITING);
return;
}
InitMovingField(x, y, MovDir[x][y]);
- PlaySoundLevelAction(x, y, SND_ACTION_MOVING);
+ PlaySoundLevelAction(x, y, ACTION_MOVING);
}
if (MovDir[x][y])
int direction = MovDir[x][y];
int dx = (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0);
int dy = (direction == MV_UP ? -1 : direction == MV_DOWN ? +1 : 0);
- int horiz_move = (dx!=0);
+ int horiz_move = (dx != 0);
int newx = x + dx, newy = y + dy;
int step = (horiz_move ? dx : dy) * TILEX / 8;
- if (element == EL_AMOEBA_DROP || element == EL_AMOEBA_DRIPPING)
+ if (element == EL_AMOEBA_DROP || element == EL_AMOEBA_DROPPING)
step /= 2;
else if (element == EL_QUICKSAND_FILLING ||
element == EL_QUICKSAND_EMPTYING)
else if (CAN_FALL(element) && horiz_move &&
y < lev_fieldy-1 && IS_BELT_ACTIVE(Feld[x][y+1]))
step /= 2;
- else if (element == EL_SPRING_MOVING)
- step*=2;
+ else if (element == EL_SPRING && horiz_move)
+ step *= 2;
#if OLD_GAME_BEHAVIOUR
else if (CAN_FALL(element) && horiz_move && !IS_SP_ELEMENT(element))
};
Feld[x][y] = EL_SAND;
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
for(i=0; i<4; i++)
{
yy = y + xy[i][1];
if (IN_LEV_FIELD(xx, yy) && Feld[xx][yy] == EL_SAND)
- DrawNewLevelField(xx, yy); /* for "ErdreichAnbroeckeln()" */
+ DrawLevelField(xx, yy); /* for "crumbled sand" */
}
}
Feld[x][y] = EL_BD_MAGIC_WALL_DEAD;
element = Feld[newx][newy] = Store[x][y];
}
- else if (element == EL_AMOEBA_DRIPPING)
+ else if (element == EL_AMOEBA_DROPPING)
{
Feld[x][y] = get_next_element(element);
element = Feld[newx][newy] = Store[x][y];
MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0;
MovDelay[newx][newy] = 0;
+ /* copy animation control values to new field */
+ GfxFrame[newx][newy] = GfxFrame[x][y];
GfxAction[newx][newy] = GfxAction[x][y]; /* keep action one frame */
- GfxAction[x][y] = GFX_ACTION_DEFAULT;
+ GfxRandom[newx][newy] = GfxRandom[x][y]; /* keep same random value */
+ ResetGfxAnimation(x, y); /* reset animation values for old field */
+
+#if 1
+#if 0
if (!CAN_MOVE(element))
MovDir[newx][newy] = 0;
+#else
+ /*
+ if (CAN_FALL(element) && MovDir[newx][newy] == MV_DOWN)
+ MovDir[newx][newy] = 0;
+ */
+
+ if (!CAN_MOVE(element) ||
+ (element == EL_SPRING && MovDir[newx][newy] == MV_DOWN))
+ MovDir[newx][newy] = 0;
+#endif
+#endif
- DrawNewLevelField(x, y);
- DrawNewLevelField(newx, newy);
+ DrawLevelField(x, y);
+ DrawLevelField(newx, newy);
Stop[newx][newy] = TRUE;
JustStopped[newx][newy] = 3;
}
else /* still moving on */
{
- if (GfxAction[x][y] == GFX_ACTION_DEFAULT)
- GfxAction[x][y] = GFX_ACTION_MOVING;
-
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
}
}
if (AmoebaNr[x][y] == group_nr &&
(Feld[x][y] == EL_AMOEBA_DEAD ||
Feld[x][y] == EL_BD_AMOEBA ||
- Feld[x][y] == EL_AMOEBA_CREATING))
+ Feld[x][y] == EL_AMOEBA_GROWING))
{
AmoebaNr[x][y] = 0;
Feld[x][y] = new_element;
InitField(x, y, FALSE);
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
done = TRUE;
}
}
if (DelayReached(&sound_delay, sound_delay_value))
{
+#if 1
+ PlaySoundLevelElementAction(x, y, Store[x][y], ACTION_GROWING);
+#else
if (Store[x][y] == EL_BD_AMOEBA)
- PlaySoundLevel(x, y, SND_BD_AMOEBA_CREATING);
+ PlaySoundLevel(x, y, SND_BD_AMOEBA_GROWING);
else
- PlaySoundLevel(x, y, SND_AMOEBA_CREATING);
+ PlaySoundLevel(x, y, SND_AMOEBA_GROWING);
+#endif
sound_delay_value = 30;
}
}
{
MovDelay[x][y]--;
if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
-#if 0
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_AMOEBING + 3 - MovDelay[x][y]/2);
-#else
{
- int frame = getNewGraphicAnimationFrame(IMG_AMOEBA_CREATING,
- 6 - MovDelay[x][y]);
+ int frame = getGraphicAnimationFrame(IMG_AMOEBA_GROWING,
+ 6 - MovDelay[x][y]);
- DrawNewGraphic(SCREENX(x), SCREENY(y), IMG_AMOEBA_CREATING, frame);
+ DrawGraphic(SCREENX(x), SCREENY(y), IMG_AMOEBA_GROWING, frame);
}
-#endif
if (!MovDelay[x][y])
{
Feld[x][y] = Store[x][y];
Store[x][y] = 0;
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
}
}
}
{
MovDelay[x][y]--;
if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
-#if 0
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_AMOEBING + MovDelay[x][y]/2);
-#else
{
- int frame = getNewGraphicAnimationFrame(IMG_AMOEBA_SHRINKING,
- 6 - MovDelay[x][y]);
+ int frame = getGraphicAnimationFrame(IMG_AMOEBA_SHRINKING,
+ 6 - MovDelay[x][y]);
- DrawNewGraphic(SCREENX(x), SCREENY(y), IMG_AMOEBA_SHRINKING, frame);
+ DrawGraphic(SCREENX(x), SCREENY(y), IMG_AMOEBA_SHRINKING, frame);
}
-#endif
if (!MovDelay[x][y])
{
Feld[x][y] = EL_EMPTY;
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
/* don't let mole enter this field in this cycle;
(give priority to objects falling to this field from above) */
{
int i;
int element = Feld[ax][ay];
+ int graphic = el2img(element);
int newax = ax, neway = ay;
static int xy[4][2] =
{
if (!level.amoeba_speed)
{
Feld[ax][ay] = EL_AMOEBA_DEAD;
- DrawNewLevelField(ax, ay);
+ DrawLevelField(ax, ay);
return;
}
+ if (IS_ANIMATED(graphic))
+ DrawLevelGraphicAnimationIfNeeded(ax, ay, graphic);
+
if (!MovDelay[ax][ay]) /* start making new amoeba field */
MovDelay[ax][ay] = RND(FRAMES_PER_SECOND * 25 / (1 + level.amoeba_speed));
if (i == 4 && (!waiting_for_player || game.emulation == EMU_BOULDERDASH))
{
Feld[ax][ay] = EL_AMOEBA_DEAD;
- DrawNewLevelField(ax, ay);
+ DrawLevelField(ax, ay);
AmoebaCnt[AmoebaNr[ax][ay]]--;
if (AmoebaCnt[AmoebaNr[ax][ay]] <= 0) /* amoeba is completely dead */
if (element != EL_AMOEBA_WET || neway < ay || !IS_FREE(newax, neway) ||
(neway == lev_fieldy - 1 && newax != ax))
{
- Feld[newax][neway] = EL_AMOEBA_CREATING; /* creation of new amoeba */
+ Feld[newax][neway] = EL_AMOEBA_GROWING; /* creation of new amoeba */
Store[newax][neway] = element;
}
else if (neway == ay)
{
Feld[newax][neway] = EL_AMOEBA_DROP; /* drop left/right of amoeba */
- PlaySoundLevel(newax, neway, SND_AMOEBA_DROP_CREATING);
+#if 1
+ PlaySoundLevelAction(newax, neway, ACTION_GROWING);
+#else
+ PlaySoundLevel(newax, neway, SND_AMOEBA_GROWING);
+#endif
}
else
{
InitMovingField(ax, ay, MV_DOWN); /* drop dripping from amoeba */
- Feld[ax][ay] = EL_AMOEBA_DRIPPING;
+ Feld[ax][ay] = EL_AMOEBA_DROPPING;
Store[ax][ay] = EL_AMOEBA_DROP;
ContinueMoving(ax, ay);
return;
}
- DrawNewLevelField(newax, neway);
+ DrawLevelField(newax, neway);
}
void Life(int ax, int ay)
static int life[4] = { 2, 3, 3, 3 }; /* parameters for "game of life" */
int life_time = 40;
int element = Feld[ax][ay];
+ int graphic = el2img(element);
boolean changed = FALSE;
+ if (IS_ANIMATED(graphic))
+ DrawLevelGraphicAnimationIfNeeded(ax, ay, graphic);
+
if (Stop[ax][ay])
return;
continue;
if (((Feld[x][y] == element ||
- (element == EL_GAMEOFLIFE && IS_PLAYER(x, y))) &&
+ (element == EL_GAME_OF_LIFE && IS_PLAYER(x, y))) &&
!Stop[x][y]) ||
(IS_FREE(x, y) && Stop[x][y]))
nachbarn++;
{
Feld[xx][yy] = EL_EMPTY;
if (!Stop[xx][yy])
- DrawNewLevelField(xx, yy);
+ DrawLevelField(xx, yy);
Stop[xx][yy] = TRUE;
changed = TRUE;
}
if (nachbarn >= life[2] && nachbarn <= life[3])
{
Feld[xx][yy] = element;
- MovDelay[xx][yy] = (element == EL_GAMEOFLIFE ? 0 : life_time-1);
+ MovDelay[xx][yy] = (element == EL_GAME_OF_LIFE ? 0 : life_time-1);
if (!Stop[xx][yy])
- DrawNewLevelField(xx, yy);
+ DrawLevelField(xx, yy);
Stop[xx][yy] = TRUE;
changed = TRUE;
}
}
if (changed)
- PlaySoundLevel(ax, ay, element == EL_GAMEOFLIFE ? SND_GAMEOFLIFE_CREATING :
- SND_BIOMAZE_CREATING);
+ PlaySoundLevel(ax, ay, element == EL_BIOMAZE ? SND_BIOMAZE_GROWING :
+ SND_GAME_OF_LIFE_GROWING);
}
-void RobotWheel(int x, int y)
+static void InitRobotWheel(int x, int y)
{
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = level.time_wheel * FRAMES_PER_SECOND;
-
- if (MovDelay[x][y]) /* wait some time before next frame */
- {
- MovDelay[x][y]--;
- if (MovDelay[x][y])
- {
- if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
-#if 0
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_ABLENK+MovDelay[x][y]%4);
-#else
- {
- int frame = getNewGraphicAnimationFrame(IMG_ROBOT_WHEEL_ACTIVE, -1);
+ MovDelay[x][y] = level.time_wheel * FRAMES_PER_SECOND;
+}
- DrawNewGraphic(SCREENX(x), SCREENY(y), IMG_ROBOT_WHEEL_ACTIVE, frame);
- }
-#endif
- if (!(MovDelay[x][y]%4))
- PlaySoundLevel(x, y, SND_ROBOT_WHEEL_ACTIVE);
- return;
- }
- }
+static void RunRobotWheel(int x, int y)
+{
+ PlaySoundLevel(x, y, SND_ROBOT_WHEEL_ACTIVE);
+}
- Feld[x][y] = EL_ROBOT_WHEEL;
- DrawNewLevelField(x, y);
+static void StopRobotWheel(int x, int y)
+{
if (ZX == x && ZY == y)
ZX = ZY = -1;
}
-void TimegateWheel(int x, int y)
+static void InitTimegateWheel(int x, int y)
{
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = level.time_wheel * FRAMES_PER_SECOND;
+ MovDelay[x][y] = level.time_wheel * FRAMES_PER_SECOND;
+}
- if (MovDelay[x][y]) /* wait some time before next frame */
+static void RunTimegateWheel(int x, int y)
+{
+ PlaySoundLevel(x, y, SND_TIMEGATE_SWITCH_ACTIVE);
+}
+
+void CheckExit(int x, int y)
+{
+ if (local_player->gems_still_needed > 0 ||
+ local_player->sokobanfields_still_needed > 0 ||
+ local_player->lights_still_needed > 0)
{
- MovDelay[x][y]--;
- if (MovDelay[x][y])
- {
- if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
-#if 0
- DrawGraphic(SCREENX(x), SCREENY(y),
- GFX_TIMEGATE_SWITCH + MovDelay[x][y]%4);
-#else
- {
- int frame = getNewGraphicAnimationFrame(IMG_TIMEGATE_SWITCH_ACTIVE, -1);
+ int element = Feld[x][y];
+ int graphic = el2img(element);
- DrawNewGraphic(SCREENX(x), SCREENY(y), IMG_TIMEGATE_SWITCH_ACTIVE, frame);
- }
-#endif
- if (!(MovDelay[x][y]%4))
- PlaySoundLevel(x, y, SND_TIMEGATE_SWITCH_ACTIVE);
- return;
- }
+ if (IS_ANIMATED(graphic))
+ DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
+
+ return;
}
- Feld[x][y] = EL_TIMEGATE_SWITCH;
- DrawNewLevelField(x, y);
- if (ZX == x && ZY == y)
- ZX = ZY = -1;
+ Feld[x][y] = EL_EXIT_OPENING;
+
+ PlaySoundLevelNearest(x, y, SND_CLASS_EXIT_OPENING);
}
-void Blubber(int x, int y)
+void CheckExitSP(int x, int y)
{
-#if 0
- if (y > 0 && IS_MOVING(x, y - 1) && MovDir[x][y - 1] == MV_DOWN)
- DrawNewLevelField(x, y - 1);
- else
- DrawGraphicAnimation(x, y, GFX_GEBLUBBER, 4, 10, ANIM_LOOP);
-#else
- DrawNewGraphicAnimation(x, y, IMG_ACID);
-#endif
+ if (local_player->gems_still_needed > 0)
+ {
+ int element = Feld[x][y];
+ int graphic = el2img(element);
+
+ if (IS_ANIMATED(graphic))
+ DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
+
+ return;
+ }
+
+ Feld[x][y] = EL_SP_EXIT_OPEN;
+
+ PlaySoundLevelNearest(x, y, SND_CLASS_SP_EXIT_OPENING);
}
-void NussKnacken(int x, int y)
+static void CloseAllOpenTimegates()
{
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = 7;
+ int x, y;
- if (MovDelay[x][y]) /* wait some time before next frame */
+ for (y=0; y<lev_fieldy; y++)
{
- MovDelay[x][y]--;
- if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
-#if 0
- DrawGraphic(SCREENX(x), SCREENY(y),
- GFX_CRACKINGNUT + 3 - MovDelay[x][y]/2);
-#else
+ for (x=0; x<lev_fieldx; x++)
{
- int frame = getNewGraphicAnimationFrame(IMG_NUT_CRACKING,
- 6 - MovDelay[x][y]);
+ int element = Feld[x][y];
- DrawNewGraphic(SCREENX(x), SCREENY(y), IMG_NUT_CRACKING, frame);
- }
+ if (element == EL_TIMEGATE_OPEN || element == EL_TIMEGATE_OPENING)
+ {
+ Feld[x][y] = EL_TIMEGATE_CLOSING;
+#if 1
+ PlaySoundLevelAction(x, y, ACTION_CLOSING);
+#else
+ PlaySoundLevel(x, y, SND_TIMEGATE_CLOSING);
#endif
-
- if (!MovDelay[x][y])
- {
- Feld[x][y] = EL_EMERALD;
- DrawNewLevelField(x, y);
+ }
}
}
}
-void BreakingPearl(int x, int y)
+void EdelsteinFunkeln(int x, int y)
{
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = 9;
+ if (!IN_SCR_FIELD(SCREENX(x), SCREENY(y)) || IS_MOVING(x, y))
+ return;
- if (MovDelay[x][y]) /* wait some time before next frame */
+ if (Feld[x][y] == EL_BD_DIAMOND)
+ return;
+
+ if (MovDelay[x][y] == 0) /* next animation frame */
+ MovDelay[x][y] = 11 * !SimpleRND(500);
+
+ if (MovDelay[x][y] != 0) /* wait some time before next frame */
{
MovDelay[x][y]--;
- if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
-#if 0
- DrawGraphic(SCREENX(x), SCREENY(y),
- GFX_PEARL_BREAKING + 4 - MovDelay[x][y]/2);
-#else
- {
- int frame = getNewGraphicAnimationFrame(IMG_PEARL_BREAKING,
- 8 - MovDelay[x][y]);
-
- DrawNewGraphic(SCREENX(x), SCREENY(y), IMG_PEARL_BREAKING, frame);
- }
-#endif
-
- if (!MovDelay[x][y])
- {
- Feld[x][y] = EL_EMPTY;
- DrawNewLevelField(x, y);
- }
- }
-}
-
-void SiebAktivieren(int x, int y, int type)
-{
-#if 0
- int graphic = (type == 1 ? GFX_MAGIC_WALL_FULL : GFX_MAGIC_WALL_BD_FULL) + 3;
-
- DrawGraphicAnimation(x, y, graphic, 4, 4, ANIM_REVERSE);
-#else
- int graphic = (type == 1 ? IMG_MAGIC_WALL_FULL : IMG_BD_MAGIC_WALL_FULL);
-
- DrawNewGraphicAnimation(x, y, graphic);
-#endif
-}
-
-void AusgangstuerPruefen(int x, int y)
-{
- if (local_player->gems_still_needed > 0 ||
- local_player->sokobanfields_still_needed > 0 ||
- local_player->lights_still_needed > 0)
- return;
-
- Feld[x][y] = EL_EXIT_OPENING;
-
- PlaySoundLevel(x < LEVELX(BX1) ? LEVELX(BX1) :
- (x > LEVELX(BX2) ? LEVELX(BX2) : x),
- y < LEVELY(BY1) ? LEVELY(BY1) :
- (y > LEVELY(BY2) ? LEVELY(BY2) : y),
- SND_EXIT_OPENING);
-}
-
-void AusgangstuerPruefen_SP(int x, int y)
-{
- if (local_player->gems_still_needed > 0)
- return;
-
- Feld[x][y] = EL_SP_EXIT_OPEN;
-
- PlaySoundLevel(x < LEVELX(BX1) ? LEVELX(BX1) :
- (x > LEVELX(BX2) ? LEVELX(BX2) : x),
- y < LEVELY(BY1) ? LEVELY(BY1) :
- (y > LEVELY(BY2) ? LEVELY(BY2) : y),
- SND_SP_EXIT_OPENING);
-}
-
-void AusgangstuerOeffnen(int x, int y)
-{
- int delay = 6;
-
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = 5 * delay;
-
- if (MovDelay[x][y]) /* wait some time before next frame */
- {
- int tuer;
-
- MovDelay[x][y]--;
- tuer = MovDelay[x][y]/delay;
- if (!(MovDelay[x][y]%delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
-#if 0
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_AUSGANG_AUF-tuer);
-#else
- {
- int frame = getNewGraphicAnimationFrame(IMG_EXIT_OPENING,
- 29 - MovDelay[x][y]);
-
- DrawNewGraphic(SCREENX(x), SCREENY(y), IMG_EXIT_OPENING, frame);
- }
-#endif
-
- if (!MovDelay[x][y])
- {
- Feld[x][y] = EL_EXIT_OPEN;
- DrawNewLevelField(x, y);
- }
- }
-}
-
-void AusgangstuerBlinken(int x, int y)
-{
-#if 0
- DrawGraphicAnimation(x, y, GFX_AUSGANG_AUF, 4, 4, ANIM_PINGPONG);
-#else
- DrawNewGraphicAnimation(x, y, IMG_EXIT_OPEN);
-#endif
-}
-
-void OpenSwitchgate(int x, int y)
-{
- int delay = 6;
-
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = 5 * delay;
-
- if (MovDelay[x][y]) /* wait some time before next frame */
- {
- int phase;
-
- MovDelay[x][y]--;
- phase = MovDelay[x][y] / delay;
- if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
-#if 0
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_SWITCHGATE_OPEN - phase);
-#else
- {
- int frame = getNewGraphicAnimationFrame(IMG_SWITCHGATE_OPENING,
- 29 - MovDelay[x][y]);
-
- DrawNewGraphic(SCREENX(x), SCREENY(y), IMG_SWITCHGATE_OPENING, frame);
- }
-#endif
-
- if (!MovDelay[x][y])
- {
- Feld[x][y] = EL_SWITCHGATE_OPEN;
- DrawNewLevelField(x, y);
- }
- }
-}
-
-void CloseSwitchgate(int x, int y)
-{
- int delay = 6;
-
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = 5 * delay;
-
- if (MovDelay[x][y]) /* wait some time before next frame */
- {
- int phase;
-
- MovDelay[x][y]--;
- phase = MovDelay[x][y] / delay;
- if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
-#if 0
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_SWITCHGATE_CLOSED + phase);
-#else
- {
- int frame = getNewGraphicAnimationFrame(IMG_SWITCHGATE_CLOSING,
- 29 - MovDelay[x][y]);
-
- DrawNewGraphic(SCREENX(x), SCREENY(y), IMG_SWITCHGATE_CLOSING, frame);
- }
-#endif
-
- if (!MovDelay[x][y])
- {
- Feld[x][y] = EL_SWITCHGATE_CLOSED;
- DrawNewLevelField(x, y);
- }
- }
-}
-
-void OpenTimegate(int x, int y)
-{
- int delay = 6;
-
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = 5 * delay;
-
- if (MovDelay[x][y]) /* wait some time before next frame */
- {
- int phase;
- MovDelay[x][y]--;
- phase = MovDelay[x][y] / delay;
- if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
-#if 0
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_TIMEGATE_OPEN - phase);
-#else
- {
- int frame = getNewGraphicAnimationFrame(IMG_TIMEGATE_OPENING,
- 29 - MovDelay[x][y]);
+ if (setup.direct_draw && MovDelay[x][y])
+ SetDrawtoField(DRAW_BUFFERED);
- DrawNewGraphic(SCREENX(x), SCREENY(y), IMG_TIMEGATE_OPENING, frame);
- }
-#endif
+ DrawLevelElementAnimation(x, y, Feld[x][y]);
- if (!MovDelay[x][y])
+ if (MovDelay[x][y] != 0)
{
- Feld[x][y] = EL_TIMEGATE_OPEN;
- DrawNewLevelField(x, y);
- }
- }
-}
-
-void CloseTimegate(int x, int y)
-{
- int delay = 6;
-
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = 5 * delay;
+ int frame = getGraphicAnimationFrame(IMG_TWINKLE_WHITE,
+ 10 - MovDelay[x][y]);
- if (MovDelay[x][y]) /* wait some time before next frame */
- {
- int phase;
+ DrawGraphicThruMask(SCREENX(x), SCREENY(y), IMG_TWINKLE_WHITE, frame);
- MovDelay[x][y]--;
- phase = MovDelay[x][y] / delay;
- if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
-#if 0
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_TIMEGATE_CLOSED + phase);
-#else
- {
- int frame = getNewGraphicAnimationFrame(IMG_TIMEGATE_CLOSING,
- 29 - MovDelay[x][y]);
-
- DrawNewGraphic(SCREENX(x), SCREENY(y), IMG_TIMEGATE_CLOSING, frame);
- }
-#endif
-
- if (!MovDelay[x][y])
- {
- Feld[x][y] = EL_TIMEGATE_CLOSED;
- DrawNewLevelField(x, y);
- }
- }
-}
-
-static void CloseAllOpenTimegates()
-{
- int x, y;
-
- for (y=0; y<lev_fieldy; y++)
- {
- for (x=0; x<lev_fieldx; x++)
- {
- int element = Feld[x][y];
-
- if (element == EL_TIMEGATE_OPEN || element == EL_TIMEGATE_OPENING)
+ if (setup.direct_draw)
{
- Feld[x][y] = EL_TIMEGATE_CLOSING;
- PlaySoundLevel(x, y, SND_TIMEGATE_CLOSING);
- }
- }
- }
-}
-
-void EdelsteinFunkeln(int x, int y)
-{
- if (!IN_SCR_FIELD(SCREENX(x), SCREENY(y)) || IS_MOVING(x, y))
- return;
+ int dest_x, dest_y;
- if (Feld[x][y] == EL_BD_DIAMOND)
-#if 0
- DrawGraphicAnimation(x, y, GFX_EDELSTEIN_BD, 4, 4, ANIM_REVERSE);
-#else
- DrawNewGraphicAnimation(x, y, IMG_BD_DIAMOND);
-#endif
- else
- {
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = 11 * !SimpleRND(500);
-
- if (MovDelay[x][y]) /* wait some time before next frame */
- {
- MovDelay[x][y]--;
-
- if (setup.direct_draw && MovDelay[x][y])
- SetDrawtoField(DRAW_BUFFERED);
-
-#if 0
- DrawGraphic(SCREENX(x), SCREENY(y), el2gfx(Feld[x][y]));
-#else
- DrawNewGraphic(SCREENX(x), SCREENY(y), el2img(Feld[x][y]), 0);
-#endif
+ dest_x = FX + SCREENX(x) * TILEX;
+ dest_y = FY + SCREENY(y) * TILEY;
- if (MovDelay[x][y])
- {
- int phase = (MovDelay[x][y]-1)/2;
-
- if (phase > 2)
- phase = 4-phase;
-
-#if 0
- DrawGraphicThruMask(SCREENX(x), SCREENY(y), GFX_FUNKELN_WEISS + phase);
-#else
- {
- int frame = getNewGraphicAnimationFrame(IMG_TWINKLE_WHITE,
- 10 - MovDelay[x][y]);
-
- DrawNewGraphicThruMask(SCREENX(x), SCREENY(y), IMG_TWINKLE_WHITE,
- frame);
- }
-#endif
-
- if (setup.direct_draw)
- {
- int dest_x, dest_y;
-
- dest_x = FX + SCREENX(x) * TILEX;
- dest_y = FY + SCREENY(y) * TILEY;
-
- BlitBitmap(drawto_field, window,
- dest_x, dest_y, TILEX, TILEY, dest_x, dest_y);
- SetDrawtoField(DRAW_DIRECT);
- }
+ BlitBitmap(drawto_field, window,
+ dest_x, dest_y, TILEX, TILEY, dest_x, dest_y);
+ SetDrawtoField(DRAW_DIRECT);
}
}
}
if (MovDelay[x][y]) /* wait some time before next frame */
{
- int phase;
-
MovDelay[x][y]--;
- phase = 2 - MovDelay[x][y] / delay;
-#if 0
- if (!(MovDelay[x][y]%delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x), SCREENY(y),
- (MovDir[x][y] == MV_LEFT ? GFX_MAUER_LEFT :
- MovDir[x][y] == MV_RIGHT ? GFX_MAUER_RIGHT :
- MovDir[x][y] == MV_UP ? GFX_MAUER_UP :
- GFX_MAUER_DOWN ) + phase);
-#else
+
if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
{
int graphic = el_dir2img(Feld[x][y], MovDir[x][y]);
- int frame = getNewGraphicAnimationFrame(graphic, 17 - MovDelay[x][y]);
+ int frame = getGraphicAnimationFrame(graphic, 17 - MovDelay[x][y]);
- DrawNewGraphic(SCREENX(x), SCREENY(y), graphic, frame);
+ DrawGraphic(SCREENX(x), SCREENY(y), graphic, frame);
}
-#endif
if (!MovDelay[x][y])
{
if (MovDir[x][y] == MV_LEFT)
{
- if (IN_LEV_FIELD(x - 1, y) && IS_MAUER(Feld[x - 1][y]))
- DrawNewLevelField(x - 1, y);
+ if (IN_LEV_FIELD(x - 1, y) && IS_WALL(Feld[x - 1][y]))
+ DrawLevelField(x - 1, y);
}
else if (MovDir[x][y] == MV_RIGHT)
{
- if (IN_LEV_FIELD(x + 1, y) && IS_MAUER(Feld[x + 1][y]))
- DrawNewLevelField(x + 1, y);
+ if (IN_LEV_FIELD(x + 1, y) && IS_WALL(Feld[x + 1][y]))
+ DrawLevelField(x + 1, y);
}
else if (MovDir[x][y] == MV_UP)
{
- if (IN_LEV_FIELD(x, y - 1) && IS_MAUER(Feld[x][y - 1]))
- DrawNewLevelField(x, y - 1);
+ if (IN_LEV_FIELD(x, y - 1) && IS_WALL(Feld[x][y - 1]))
+ DrawLevelField(x, y - 1);
}
else
{
- if (IN_LEV_FIELD(x, y + 1) && IS_MAUER(Feld[x][y + 1]))
- DrawNewLevelField(x, y + 1);
+ if (IN_LEV_FIELD(x, y + 1) && IS_WALL(Feld[x][y + 1]))
+ DrawLevelField(x, y + 1);
}
Feld[x][y] = Store[x][y];
Store[x][y] = 0;
MovDir[x][y] = MV_NO_MOVING;
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
}
}
}
void MauerAbleger(int ax, int ay)
{
int element = Feld[ax][ay];
+ int graphic = el2img(element);
boolean oben_frei = FALSE, unten_frei = FALSE;
boolean links_frei = FALSE, rechts_frei = FALSE;
boolean oben_massiv = FALSE, unten_massiv = FALSE;
boolean links_massiv = FALSE, rechts_massiv = FALSE;
boolean new_wall = FALSE;
+ if (IS_ANIMATED(graphic))
+ DrawLevelGraphicAnimationIfNeeded(ax, ay, graphic);
+
if (!MovDelay[ax][ay]) /* start building new wall */
MovDelay[ax][ay] = 6;
if (IN_LEV_FIELD(ax+1, ay) && IS_FREE(ax+1, ay))
rechts_frei = TRUE;
- if (element == EL_WALL_GROWING_Y || element == EL_WALL_GROWING_XY)
+ if (element == EL_EXPANDABLE_WALL_VERTICAL ||
+ element == EL_EXPANDABLE_WALL_ANY)
{
if (oben_frei)
{
- Feld[ax][ay-1] = EL_WALL_GROWING_ACTIVE;
+ Feld[ax][ay-1] = EL_EXPANDABLE_WALL_GROWING;
Store[ax][ay-1] = element;
MovDir[ax][ay-1] = MV_UP;
if (IN_SCR_FIELD(SCREENX(ax), SCREENY(ay-1)))
-#if 0
- DrawGraphic(SCREENX(ax), SCREENY(ay-1), GFX_MAUER_UP);
-#else
- DrawNewGraphic(SCREENX(ax), SCREENY(ay - 1),
- IMG_WALL_GROWING_ACTIVE_UP, 0);
-#endif
+ DrawGraphic(SCREENX(ax), SCREENY(ay - 1),
+ IMG_EXPANDABLE_WALL_GROWING_UP, 0);
new_wall = TRUE;
}
if (unten_frei)
{
- Feld[ax][ay+1] = EL_WALL_GROWING_ACTIVE;
+ Feld[ax][ay+1] = EL_EXPANDABLE_WALL_GROWING;
Store[ax][ay+1] = element;
MovDir[ax][ay+1] = MV_DOWN;
if (IN_SCR_FIELD(SCREENX(ax), SCREENY(ay+1)))
-#if 0
- DrawGraphic(SCREENX(ax), SCREENY(ay+1), GFX_MAUER_DOWN);
-#else
- DrawNewGraphic(SCREENX(ax), SCREENY(ay + 1),
- IMG_WALL_GROWING_ACTIVE_DOWN, 0);
-#endif
+ DrawGraphic(SCREENX(ax), SCREENY(ay + 1),
+ IMG_EXPANDABLE_WALL_GROWING_DOWN, 0);
new_wall = TRUE;
}
}
- if (element == EL_WALL_GROWING_X || element == EL_WALL_GROWING_XY ||
- element == EL_WALL_GROWING)
+ if (element == EL_EXPANDABLE_WALL_HORIZONTAL ||
+ element == EL_EXPANDABLE_WALL_ANY ||
+ element == EL_EXPANDABLE_WALL)
{
if (links_frei)
{
- Feld[ax-1][ay] = EL_WALL_GROWING_ACTIVE;
+ Feld[ax-1][ay] = EL_EXPANDABLE_WALL_GROWING;
Store[ax-1][ay] = element;
MovDir[ax-1][ay] = MV_LEFT;
if (IN_SCR_FIELD(SCREENX(ax-1), SCREENY(ay)))
-#if 0
- DrawGraphic(SCREENX(ax-1), SCREENY(ay), GFX_MAUER_LEFT);
-#else
- DrawNewGraphic(SCREENX(ax - 1), SCREENY(ay),
- IMG_WALL_GROWING_ACTIVE_LEFT, 0);
-#endif
+ DrawGraphic(SCREENX(ax - 1), SCREENY(ay),
+ IMG_EXPANDABLE_WALL_GROWING_LEFT, 0);
new_wall = TRUE;
}
if (rechts_frei)
{
- Feld[ax+1][ay] = EL_WALL_GROWING_ACTIVE;
+ Feld[ax+1][ay] = EL_EXPANDABLE_WALL_GROWING;
Store[ax+1][ay] = element;
MovDir[ax+1][ay] = MV_RIGHT;
if (IN_SCR_FIELD(SCREENX(ax+1), SCREENY(ay)))
-#if 0
- DrawGraphic(SCREENX(ax+1), SCREENY(ay), GFX_MAUER_RIGHT);
-#else
- DrawNewGraphic(SCREENX(ax + 1), SCREENY(ay),
- IMG_WALL_GROWING_ACTIVE_RIGHT, 0);
-#endif
+ DrawGraphic(SCREENX(ax + 1), SCREENY(ay),
+ IMG_EXPANDABLE_WALL_GROWING_RIGHT, 0);
new_wall = TRUE;
}
}
- if (element == EL_WALL_GROWING && (links_frei || rechts_frei))
- DrawNewLevelField(ax, ay);
+ if (element == EL_EXPANDABLE_WALL && (links_frei || rechts_frei))
+ DrawLevelField(ax, ay);
- if (!IN_LEV_FIELD(ax, ay-1) || IS_MAUER(Feld[ax][ay-1]))
+ if (!IN_LEV_FIELD(ax, ay-1) || IS_WALL(Feld[ax][ay-1]))
oben_massiv = TRUE;
- if (!IN_LEV_FIELD(ax, ay+1) || IS_MAUER(Feld[ax][ay+1]))
+ if (!IN_LEV_FIELD(ax, ay+1) || IS_WALL(Feld[ax][ay+1]))
unten_massiv = TRUE;
- if (!IN_LEV_FIELD(ax-1, ay) || IS_MAUER(Feld[ax-1][ay]))
+ if (!IN_LEV_FIELD(ax-1, ay) || IS_WALL(Feld[ax-1][ay]))
links_massiv = TRUE;
- if (!IN_LEV_FIELD(ax+1, ay) || IS_MAUER(Feld[ax+1][ay]))
+ if (!IN_LEV_FIELD(ax+1, ay) || IS_WALL(Feld[ax+1][ay]))
rechts_massiv = TRUE;
if (((oben_massiv && unten_massiv) ||
- element == EL_WALL_GROWING_X || element == EL_WALL_GROWING) &&
+ element == EL_EXPANDABLE_WALL_HORIZONTAL ||
+ element == EL_EXPANDABLE_WALL) &&
((links_massiv && rechts_massiv) ||
- element == EL_WALL_GROWING_Y))
+ element == EL_EXPANDABLE_WALL_VERTICAL))
Feld[ax][ay] = EL_WALL;
if (new_wall)
- PlaySoundLevel(ax, ay, SND_WALL_GROWING);
+#if 1
+ PlaySoundLevelAction(ax, ay, ACTION_GROWING);
+#else
+ PlaySoundLevel(ax, ay, SND_EXPANDABLE_WALL_GROWING);
+#endif
}
void CheckForDragon(int x, int y)
if (IN_LEV_FIELD(xx, yy) && Feld[xx][yy] == EL_FLAMES)
{
Feld[xx][yy] = EL_EMPTY;
- DrawNewLevelField(xx, yy);
+ DrawLevelField(xx, yy);
}
else
break;
}
}
-static void CheckBuggyBase(int x, int y)
+static void InitBuggyBase(int x, int y)
{
int element = Feld[x][y];
+ int activating_delay = FRAMES_PER_SECOND / 4;
+
+ MovDelay[x][y] =
+ (element == EL_SP_BUGGY_BASE ?
+ 2 * FRAMES_PER_SECOND + RND(5 * FRAMES_PER_SECOND) - activating_delay :
+ element == EL_SP_BUGGY_BASE_ACTIVATING ?
+ activating_delay :
+ element == EL_SP_BUGGY_BASE_ACTIVE ?
+ 1 * FRAMES_PER_SECOND + RND(1 * FRAMES_PER_SECOND) : 1);
+}
- if (element == EL_SP_BUGGY_BASE)
+static void WarnBuggyBase(int x, int y)
+{
+ int i;
+ static int xy[4][2] =
{
- if (!MovDelay[x][y]) /* wait some time before activating base */
- MovDelay[x][y] = 2 * FRAMES_PER_SECOND + RND(5 * FRAMES_PER_SECOND);
-
- if (MovDelay[x][y])
- {
- MovDelay[x][y]--;
- if (MovDelay[x][y] < 5 && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
-#if 0
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_SP_BUG_WARNING);
-#else
- DrawNewGraphic(SCREENX(x), SCREENY(y), IMG_SP_BUGGY_BASE, 0);
-#endif
- if (MovDelay[x][y])
- return;
+ { 0, -1 },
+ { -1, 0 },
+ { +1, 0 },
+ { 0, +1 }
+ };
- Feld[x][y] = EL_SP_BUGGY_BASE_ACTIVE;
- }
- }
- else if (element == EL_SP_BUGGY_BASE_ACTIVE)
+ for (i=0; i<4; i++)
{
- if (!MovDelay[x][y]) /* start activating buggy base */
- MovDelay[x][y] = 1 * FRAMES_PER_SECOND + RND(1 * FRAMES_PER_SECOND);
+ int xx = x + xy[i][0], yy = y + xy[i][1];
- if (MovDelay[x][y])
+ if (IS_PLAYER(xx, yy))
{
- MovDelay[x][y]--;
- if (MovDelay[x][y])
- {
- int i;
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
-
- if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
-#if 0
- DrawGraphic(SCREENX(x),SCREENY(y), GFX_SP_BUG_ACTIVE + SimpleRND(4));
-#else
- {
- int graphic = IMG_SP_BUGGY_BASE_ACTIVE;
- int frame = getNewGraphicAnimationFrame(graphic, SimpleRND(100));
+ PlaySoundLevel(x, y, SND_SP_BUGGY_BASE_ACTIVE);
- DrawNewGraphic(SCREENX(x), SCREENY(y), graphic, frame);
- }
-#endif
+ break;
+ }
+ }
+}
- for (i=0; i<4; i++)
- {
- int xx = x + xy[i][0], yy = y + xy[i][1];
+static void InitTrap(int x, int y)
+{
+ MovDelay[x][y] = 2 * FRAMES_PER_SECOND + RND(5 * FRAMES_PER_SECOND);
+}
- if (IS_PLAYER(xx, yy))
- {
- PlaySoundLevel(x, y, SND_SP_BUGGY_BASE_ACTIVE);
- break;
- }
- }
+static void ActivateTrap(int x, int y)
+{
+ PlaySoundLevel(x, y, SND_TRAP_ACTIVATING);
+}
- return;
- }
+static void ChangeActiveTrap(int x, int y)
+{
+ int graphic = IMG_TRAP_ACTIVE;
- Feld[x][y] = EL_SP_BUGGY_BASE;
- DrawNewLevelField(x, y);
- }
- }
+ /* if new animation frame was drawn, correct crumbled sand border */
+ if (IS_NEW_FRAME(GfxFrame[x][y], graphic))
+ DrawLevelFieldCrumbledSand(x, y);
}
-static void CheckTrap(int x, int y)
+static void ChangeElement(int x, int y)
{
int element = Feld[x][y];
- if (element == EL_TRAP)
- {
- if (!MovDelay[x][y]) /* wait some time before activating trap */
- MovDelay[x][y] = 2 * FRAMES_PER_SECOND + RND(5 * FRAMES_PER_SECOND);
-
- if (MovDelay[x][y])
- {
- MovDelay[x][y]--;
- if (MovDelay[x][y])
- return;
+ if (IS_MOVING(x, y)) /* never change a running system :-) */
+ return;
- Feld[x][y] = EL_TRAP_ACTIVE;
- PlaySoundLevel(x, y, SND_TRAP_ACTIVATING);
- }
- }
- else if (element == EL_TRAP_ACTIVE)
+ if (MovDelay[x][y] == 0) /* initialize element change */
{
- int delay = 4;
- int num_frames = 8;
-
- if (!MovDelay[x][y]) /* start activating trap */
- MovDelay[x][y] = num_frames * delay;
+ MovDelay[x][y] = changing_element[element].change_delay + 1;
- if (MovDelay[x][y])
+ if (IS_CUSTOM_ELEMENT(element) &&
+ HAS_CHANGE_EVENT(element, CE_DELAY_RANDOM))
{
- MovDelay[x][y]--;
+ int i = element - EL_CUSTOM_START;
+ int max_random_delay = level.custom_element[i].change.delay_random;
+ int delay_frames = level.custom_element[i].change.delay_frames;
- if (MovDelay[x][y])
- {
- if (!(MovDelay[x][y] % delay))
- {
- int phase = MovDelay[x][y]/delay;
+ MovDelay[x][y] += RND(max_random_delay * delay_frames);
+ }
- if (phase >= num_frames/2)
- phase = num_frames - phase;
+ ResetGfxAnimation(x, y);
+ ResetRandomAnimationValue(x, y);
- if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- {
-#if 0
- DrawGraphic(SCREENX(x),SCREENY(y), GFX_TRAP_INACTIVE + phase - 1);
-#else
- int graphic = IMG_TRAP_ACTIVE;
- int frame = getNewGraphicAnimationFrame(graphic,
- 31 - MovDelay[x][y]);
+ if (changing_element[element].pre_change_function)
+ changing_element[element].pre_change_function(x, y);
+ }
- DrawNewGraphic(SCREENX(x),SCREENY(y), graphic, frame);
-#endif
- ErdreichAnbroeckeln(SCREENX(x), SCREENY(y));
- }
- }
+ MovDelay[x][y]--;
- return;
- }
+ if (MovDelay[x][y] != 0) /* continue element change */
+ {
+ if (IS_ANIMATED(el2img(element)))
+ DrawLevelElementAnimationIfNeeded(x, y, element);
- Feld[x][y] = EL_TRAP;
- DrawNewLevelField(x, y);
- }
+ if (changing_element[element].change_function)
+ changing_element[element].change_function(x, y);
}
-}
-
-static void DrawBeltAnimation(int x, int y, int element)
-{
- int belt_nr = getBeltNrFromBeltActiveElement(element);
- int belt_dir = game.belt_dir[belt_nr];
-
- if (belt_dir != MV_NO_MOVING)
+ else /* finish element change */
{
-#if 0
- int delay = 2;
- int mode = ANIM_LOOP | (belt_dir == MV_LEFT ? 0 : ANIM_REVERSE);
- int graphic = el2gfx(element) + (belt_dir == MV_LEFT ? 0 : 7);
+ Feld[x][y] = changing_element[element].next_element;
- DrawGraphicAnimation(x, y, graphic, 8, delay, mode);
-#else
- int graphic = el2img(element);
+ ResetGfxAnimation(x, y);
+ ResetRandomAnimationValue(x, y);
- DrawNewGraphicAnimation(x, y, graphic);
+#if 1
+ InitField(x, y, FALSE);
+ if (CAN_MOVE(element))
+ InitMovDir(x, y);
#endif
+ DrawLevelField(x, y);
- if (!(FrameCounter % 2))
- PlaySoundLevel(x, y, SND_CONVEYOR_BELT_ACTIVE);
+ if (changing_element[element].post_change_function)
+ changing_element[element].post_change_function(x, y);
}
}
{
static byte stored_player_action[MAX_PLAYERS];
static int num_stored_actions = 0;
-#if 0
- static boolean save_tape_entry = FALSE;
-#endif
boolean moved = FALSE, snapped = FALSE, bombed = FALSE;
int left = player_action & JOY_LEFT;
int right = player_action & JOY_RIGHT;
if (player_action)
{
-#if 0
- save_tape_entry = TRUE;
-#endif
- player->frame_reset_delay = 0;
-
if (button1)
snapped = SnapField(player, dx, dy);
else
}
}
-#if 0
- if (tape.recording && (moved || snapped || bombed))
- {
- if (bombed && !moved)
- player_action &= JOY_BUTTON;
-
- stored_player_action[player->index_nr] = player_action;
- save_tape_entry = TRUE;
- }
- else if (tape.playing && snapped)
- SnapField(player, 0, 0); /* stop snapping */
-#else
stored_player_action[player->index_nr] = player_action;
-#endif
}
else
{
SnapField(player, 0, 0);
CheckGravityMovement(player);
-#if 1
- if (player->MovPos == 0) /* needed for tape.playing */
- player->is_moving = FALSE;
-#endif
+ if (player->MovPos == 0)
+ {
#if 0
- if (player->MovPos == 0) /* needed for tape.playing */
- player->last_move_dir = MV_NO_MOVING;
-
- /* !!! CHECK THIS AGAIN !!!
- (Seems to be needed for some EL_ROBOT stuff, but breaks
- tapes when walking through pipes!)
- */
+ printf("Trying... Player frame reset\n");
+#endif
- /* it seems that "player->last_move_dir" is misused as some sort of
- "player->is_just_moving_in_this_moment", which is needed for the
- robot stuff (robots don't kill players when they are moving)
- */
-#endif
+ InitPlayerGfxAnimation(player, ACTION_DEFAULT, player->MovDir);
+ }
- if (++player->frame_reset_delay > player->move_delay_value)
- player->Frame = 0;
+ if (player->MovPos == 0) /* needed for tape.playing */
+ player->is_moving = FALSE;
}
-#if 0
- if (tape.recording && num_stored_actions >= MAX_PLAYERS && save_tape_entry)
- {
- TapeRecordAction(stored_player_action);
- num_stored_actions = 0;
- save_tape_entry = FALSE;
- }
-#else
if (tape.recording && num_stored_actions >= MAX_PLAYERS)
{
TapeRecordAction(stored_player_action);
num_stored_actions = 0;
}
-#endif
-
-#if 0
- if (tape.playing && !tape.pausing && !player_action &&
- tape.counter < tape.length)
- {
- int jx = player->jx, jy = player->jy;
- int next_joy =
- tape.pos[tape.counter].action[player->index_nr] & (JOY_LEFT|JOY_RIGHT);
-
- if ((next_joy == JOY_LEFT || next_joy == JOY_RIGHT) &&
- (player->MovDir != JOY_UP && player->MovDir != JOY_DOWN))
- {
- 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_SATELLITE ? 2 :
- (el == EL_BALLOON || el == EL_SPRING) ? 0 : 10);
-
- if (tape.delay_played + push_delay >= tape.pos[tape.counter].delay)
- {
- player->MovDir = next_joy;
- player->Frame = FrameCounter % 4;
- player->Pushing = TRUE;
- }
- }
- }
- }
-#endif
}
void GameActions()
{
static unsigned long action_delay = 0;
unsigned long action_delay_value;
- int sieb_x = 0, sieb_y = 0;
- int i, x, y, element;
+ int magic_wall_x = 0, magic_wall_y = 0;
+ int i, x, y, element, graphic;
byte *recorded_player_action;
byte summarized_player_action = 0;
- if (game_status != PLAYING)
+ if (game_status != GAME_MODE_PLAYING)
return;
action_delay_value =
HandleNetworking();
#endif
- if (game_status != PLAYING)
+ if (game_status != GAME_MODE_PLAYING)
return;
if (!network_player_action_received)
if (stored_player[i].programmed_action)
actual_player_action = stored_player[i].programmed_action;
- if (recorded_player_action)
- actual_player_action = recorded_player_action[i];
-
- PlayerActions(&stored_player[i], actual_player_action);
- ScrollFigure(&stored_player[i], SCROLL_GO_ON);
- }
-
- network_player_action_received = FALSE;
-
- ScrollScreen(NULL, SCROLL_GO_ON);
-
-
-
-#ifdef DEBUG
-#if 0
- if (TimeFrames == 0 && local_player->active)
- {
- extern unsigned int last_RND();
-
- printf("DEBUG: %03d last RND was %d \t [state checksum is %d]\n",
- TimePlayed, last_RND(), getStateCheckSum(TimePlayed));
- }
-#endif
-#endif
-
-#ifdef DEBUG
-#if 0
- if (GameFrameDelay >= 500)
- printf("FrameCounter == %d\n", FrameCounter);
-#endif
-#endif
+ if (recorded_player_action)
+ actual_player_action = recorded_player_action[i];
+
+ PlayerActions(&stored_player[i], actual_player_action);
+ ScrollFigure(&stored_player[i], SCROLL_GO_ON);
+ }
+ network_player_action_received = FALSE;
+ ScrollScreen(NULL, SCROLL_GO_ON);
+#if 0
FrameCounter++;
TimeFrames++;
+ for (i=0; i<MAX_PLAYERS; i++)
+ stored_player[i].Frame++;
+#endif
+
for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
{
Stop[x][y] = FALSE;
if (JustStopped[x][y] > 0)
JustStopped[x][y]--;
+ GfxFrame[x][y]++;
+
#if DEBUG
if (IS_BLOCKED(x, y))
{
for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
{
element = Feld[x][y];
+ graphic = el2img(element);
+
+#if 0
+ if (element == -1)
+ {
+ printf("::: %d,%d: %d [%d]\n", x, y, element, FrameCounter);
+
+ element = graphic = 0;
+ }
+#endif
+
+ if (graphic_info[graphic].anim_global_sync)
+ GfxFrame[x][y] = FrameCounter;
+
+ if (ANIM_MODE(graphic) == ANIM_RANDOM &&
+ IS_NEXT_FRAME(GfxFrame[x][y], graphic))
+ ResetRandomAnimationValue(x, y);
+
+ SetRandomAnimationValue(x, y);
+
+#if 1
+ PlaySoundLevelActionIfLoop(x, y, GfxAction[x][y]);
+#endif
if (IS_INACTIVE(element))
+ {
+ if (IS_ANIMATED(graphic))
+ DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
+
continue;
+ }
if (!IS_MOVING(x, y) && (CAN_FALL(element) || CAN_MOVE(element)))
{
StartMoving(x, y);
+ if (IS_ANIMATED(graphic) &&
+ !IS_MOVING(x, y) &&
+ !Stop[x][y])
+ DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
+
if (IS_GEM(element) || element == EL_SP_INFOTRON)
EdelsteinFunkeln(x, y);
}
+ else if ((element == EL_ACID ||
+ element == EL_EXIT_OPEN ||
+ element == EL_SP_EXIT_OPEN ||
+ element == EL_SP_TERMINAL ||
+ element == EL_SP_TERMINAL_ACTIVE ||
+ element == EL_EXTRA_TIME ||
+ element == EL_SHIELD_NORMAL ||
+ element == EL_SHIELD_DEADLY) &&
+ IS_ANIMATED(graphic))
+ DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
else if (IS_MOVING(x, y))
ContinueMoving(x, y);
else if (IS_ACTIVE_BOMB(element))
CheckDynamite(x, y);
#if 0
else if (element == EL_EXPLOSION && !game.explosions_delayed)
- Explode(x, y, Frame[x][y], EX_NORMAL);
+ Explode(x, y, ExplodePhase[x][y], EX_NORMAL);
#endif
- else if (element == EL_AMOEBA_CREATING)
+ else if (element == EL_AMOEBA_GROWING)
AmoebeWaechst(x, y);
else if (element == EL_AMOEBA_SHRINKING)
AmoebaDisappearing(x, y);
AmoebeAbleger(x, y);
#endif
- else if (element == EL_GAMEOFLIFE || element == EL_BIOMAZE)
+ else if (element == EL_GAME_OF_LIFE || element == EL_BIOMAZE)
Life(x, y);
- else if (element == EL_ROBOT_WHEEL_ACTIVE)
- RobotWheel(x, y);
- else if (element == EL_TIMEGATE_SWITCH_ACTIVE)
- TimegateWheel(x, y);
- else if (element == EL_ACID)
- Blubber(x, y);
- else if (element == EL_ACID_SPLASHING_LEFT ||
- element == EL_ACID_SPLASHING_RIGHT)
- Blurb(x, y);
- else if (element == EL_CRACKINGNUT)
- NussKnacken(x, y);
- else if (element == EL_PEARL_BREAKING)
- BreakingPearl(x, y);
else if (element == EL_EXIT_CLOSED)
- AusgangstuerPruefen(x, y);
+ CheckExit(x, y);
else if (element == EL_SP_EXIT_CLOSED)
- AusgangstuerPruefen_SP(x, y);
- else if (element == EL_EXIT_OPENING)
- AusgangstuerOeffnen(x, y);
- else if (element == EL_EXIT_OPEN)
- AusgangstuerBlinken(x, y);
- else if (element == EL_SP_EXIT_OPEN)
- ; /* !!! ADD SOME (OPTIONAL) ANIMATIONS HERE !!! */
- else if (element == EL_WALL_GROWING_ACTIVE)
+ CheckExitSP(x, y);
+ else if (element == EL_EXPANDABLE_WALL_GROWING)
MauerWaechst(x, y);
- else if (element == EL_WALL_GROWING ||
- element == EL_WALL_GROWING_X ||
- element == EL_WALL_GROWING_Y ||
- element == EL_WALL_GROWING_XY)
+ else if (element == EL_EXPANDABLE_WALL ||
+ element == EL_EXPANDABLE_WALL_HORIZONTAL ||
+ element == EL_EXPANDABLE_WALL_VERTICAL ||
+ element == EL_EXPANDABLE_WALL_ANY)
MauerAbleger(x, y);
else if (element == EL_FLAMES)
CheckForDragon(x, y);
- else if (element == EL_SP_BUGGY_BASE || element == EL_SP_BUGGY_BASE_ACTIVE)
- CheckBuggyBase(x, y);
- else if (element == EL_TRAP || element == EL_TRAP_ACTIVE)
- CheckTrap(x, y);
- else if (element == EL_SP_TERMINAL)
-#if 0
- DrawGraphicAnimation(x, y, GFX2_SP_TERMINAL, 7, 12, ANIM_LOOP);
-#else
- DrawNewGraphicAnimation(x, y, IMG_SP_TERMINAL);
-#endif
- else if (element == EL_SP_TERMINAL_ACTIVE)
- {
-#if 0
- DrawGraphicAnimation(x, y, GFX2_SP_TERMINAL_ACTIVE, 7, 4, ANIM_LOOP);
-#else
- DrawNewGraphicAnimation(x, y, IMG_SP_TERMINAL_ACTIVE);
-#endif
-
-#if 0
- if (!(FrameCounter % 4))
- PlaySoundLevel(x, y, SND_SP_TERMINAL_ACTIVE);
-#endif
- }
- else if (IS_BELT_ACTIVE(element))
- DrawBeltAnimation(x, y, element);
- else if (element == EL_SWITCHGATE_OPENING)
- OpenSwitchgate(x, y);
- else if (element == EL_SWITCHGATE_CLOSING)
- CloseSwitchgate(x, y);
- else if (element == EL_TIMEGATE_OPENING)
- OpenTimegate(x, y);
- else if (element == EL_TIMEGATE_CLOSING)
- CloseTimegate(x, y);
- else if (element == EL_EXTRA_TIME)
#if 0
- DrawGraphicAnimation(x, y, GFX_EXTRA_TIME, 6, 4, ANIM_LOOP);
-#else
- DrawNewGraphicAnimation(x, y, IMG_EXTRA_TIME);
-#endif
- else if (element == EL_SHIELD_NORMAL)
- {
-#if 0
- DrawGraphicAnimation(x, y, GFX_SHIELD_PASSIVE, 6, 4, ANIM_LOOP);
-#else
- DrawNewGraphicAnimation(x, y, IMG_SHIELD_NORMAL);
+ else if (IS_AUTO_CHANGING(element))
+ ChangeElement(x, y);
#endif
+ else if (element == EL_EXPLOSION)
+ ; /* drawing of correct explosion animation is handled separately */
+ else if (IS_ANIMATED(graphic) && !IS_AUTO_CHANGING(element))
+ DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
-#if 0
- if (!(FrameCounter % 4))
- PlaySoundLevel(x, y, SND_SHIELD_PASSIVE_ACTIVATED);
-#endif
- }
- else if (element == EL_SHIELD_DEADLY)
- {
-#if 0
- DrawGraphicAnimation(x, y, GFX_SHIELD_ACTIVE, 6, 4, ANIM_LOOP);
-#else
- DrawNewGraphicAnimation(x, y, IMG_SHIELD_DEADLY);
+#if 1
+ /* this may take place after moving, therefore element may have changed */
+ if (IS_AUTO_CHANGING(Feld[x][y]))
+ ChangeElement(x, y);
#endif
-#if 0
- if (!(FrameCounter % 4))
- PlaySoundLevel(x, y, SND_SHIELD_DEADLY_ACTIVE);
-#endif
- }
+ if (IS_BELT_ACTIVE(element))
+ PlaySoundLevelAction(x, y, ACTION_ACTIVE);
if (game.magic_wall_active)
{
- boolean sieb = FALSE;
int jx = local_player->jx, jy = local_player->jy;
- if (element == EL_MAGIC_WALL_FULL ||
- element == EL_MAGIC_WALL_ACTIVE ||
- element == EL_MAGIC_WALL_EMPTYING)
- {
- SiebAktivieren(x, y, 1);
- sieb = TRUE;
- }
- else if (element == EL_BD_MAGIC_WALL_FULL ||
- element == EL_BD_MAGIC_WALL_ACTIVE ||
- element == EL_BD_MAGIC_WALL_EMPTYING)
- {
- SiebAktivieren(x, y, 2);
- sieb = TRUE;
- }
-
/* play the element sound at the position nearest to the player */
- if (sieb && ABS(x-jx)+ABS(y-jy) < ABS(sieb_x-jx)+ABS(sieb_y-jy))
+ if ((element == EL_MAGIC_WALL_FULL ||
+ element == EL_MAGIC_WALL_ACTIVE ||
+ element == EL_MAGIC_WALL_EMPTYING ||
+ element == EL_BD_MAGIC_WALL_FULL ||
+ element == EL_BD_MAGIC_WALL_ACTIVE ||
+ element == EL_BD_MAGIC_WALL_EMPTYING) &&
+ ABS(x-jx) + ABS(y-jy) < ABS(magic_wall_x-jx) + ABS(magic_wall_y-jy))
{
- sieb_x = x;
- sieb_y = y;
+ magic_wall_x = x;
+ magic_wall_y = y;
}
}
}
(element == EL_EMPTY ||
element == EL_SAND ||
element == EL_QUICKSAND_EMPTY ||
- element == EL_ACID_SPLASHING_LEFT ||
- element == EL_ACID_SPLASHING_RIGHT))
+ element == EL_ACID_SPLASH_LEFT ||
+ element == EL_ACID_SPLASH_RIGHT))
{
if ((IN_LEV_FIELD(x, y-1) && Feld[x][y-1] == EL_AMOEBA_WET) ||
(IN_LEV_FIELD(x-1, y) && Feld[x-1][y] == EL_AMOEBA_WET) ||
if (ExplodeField[x][y])
Explode(x, y, EX_PHASE_START, ExplodeField[x][y]);
else if (element == EL_EXPLOSION)
- Explode(x, y, Frame[x][y], EX_NORMAL);
+ Explode(x, y, ExplodePhase[x][y], EX_NORMAL);
ExplodeField[x][y] = EX_NO_EXPLOSION;
}
{
if (!(game.magic_wall_time_left % 4))
{
- int element = Feld[sieb_x][sieb_y];
+ int element = Feld[magic_wall_x][magic_wall_y];
if (element == EL_BD_MAGIC_WALL_FULL ||
element == EL_BD_MAGIC_WALL_ACTIVE ||
element == EL_BD_MAGIC_WALL_EMPTYING)
- PlaySoundLevel(sieb_x, sieb_y, SND_BD_MAGIC_WALL_ACTIVE);
+ PlaySoundLevel(magic_wall_x, magic_wall_y, SND_BD_MAGIC_WALL_ACTIVE);
else
- PlaySoundLevel(sieb_x, sieb_y, SND_MAGIC_WALL_ACTIVE);
+ PlaySoundLevel(magic_wall_x, magic_wall_y, SND_MAGIC_WALL_ACTIVE);
}
if (game.magic_wall_time_left > 0)
element == EL_MAGIC_WALL_FULL)
{
Feld[x][y] = EL_MAGIC_WALL_DEAD;
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
}
else if (element == EL_BD_MAGIC_WALL_ACTIVE ||
element == EL_BD_MAGIC_WALL_FULL)
{
Feld[x][y] = EL_BD_MAGIC_WALL_DEAD;
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
}
}
if (SHIELD_ON(player))
{
- if (player->shield_active_time_left)
+ if (player->shield_deadly_time_left)
PlaySoundLevel(player->jx, player->jy, SND_SHIELD_DEADLY_ACTIVE);
- else if (player->shield_passive_time_left)
+ else if (player->shield_normal_time_left)
PlaySoundLevel(player->jx, player->jy, SND_SHIELD_NORMAL_ACTIVE);
}
}
if (SHIELD_ON(player))
{
- player->shield_passive_time_left--;
+ player->shield_normal_time_left--;
- if (player->shield_active_time_left > 0)
- player->shield_active_time_left--;
+ if (player->shield_deadly_time_left > 0)
+ player->shield_deadly_time_left--;
}
}
TimeLeft--;
if (TimeLeft <= 10 && setup.time_limit)
- PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MAX_RIGHT);
+ PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MIDDLE);
- DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FS_SMALL, FC_YELLOW);
+ DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FONT_TEXT_2);
if (!TimeLeft && setup.time_limit)
for (i=0; i<MAX_PLAYERS; i++)
KillHero(&stored_player[i]);
}
else if (level.time == 0 && !AllPlayersGone) /* level without time limit */
- DrawText(DX_TIME, DY_TIME, int2str(TimePlayed, 3), FS_SMALL, FC_YELLOW);
+ DrawText(DX_TIME, DY_TIME, int2str(TimePlayed, 3), FONT_TEXT_2);
}
DrawAllPlayers();
redraw_mask |= REDRAW_FPS;
}
+
+#if 0
+ if (stored_player[0].jx != stored_player[0].last_jx ||
+ stored_player[0].jy != stored_player[0].last_jy)
+ printf("::: %d, %d, %d, %d, %d\n",
+ stored_player[0].MovDir,
+ stored_player[0].MovPos,
+ stored_player[0].GfxPos,
+ stored_player[0].Frame,
+ stored_player[0].StepFrame);
+#endif
+
+#if 1
+ FrameCounter++;
+ TimeFrames++;
+
+ for (i=0; i<MAX_PLAYERS; i++)
+ {
+ int move_frames =
+ MOVE_DELAY_NORMAL_SPEED / stored_player[i].move_delay_value;
+
+ stored_player[i].Frame += move_frames;
+
+ if (stored_player[i].MovPos != 0)
+ stored_player[i].StepFrame += move_frames;
+ }
+#endif
}
static boolean AllPlayersInSight(struct PlayerInfo *player, int x, int y)
{
x = (dx == 1 ? BX1 : BX2);
for (y=BY1; y<=BY2; y++)
- DrawNewScreenField(x, y);
+ DrawScreenField(x, y);
}
if (dy)
{
y = (dy == 1 ? BY1 : BY2);
for (x=BX1; x<=BX2; x++)
- DrawNewScreenField(x, y);
+ DrawScreenField(x, y);
}
redraw_mask |= REDRAW_FIELD;
if (field_under_player_is_free &&
!player_is_moving_to_valid_field &&
- !IS_TUBE(Feld[jx][jy]))
+ !IS_WALKABLE_INSIDE(Feld[jx][jy]))
player->programmed_action = MV_DOWN;
}
}
+/*
+ MoveFigureOneStep()
+ -----------------------------------------------------------------------------
+ dx, dy: direction (non-diagonal) to try to move the player to
+ real_dx, real_dy: direction as read from input device (can be diagonal)
+*/
+
boolean MoveFigureOneStep(struct PlayerInfo *player,
int dx, int dy, int real_dx, int real_dy)
{
{
if (element == EL_ACID && dx == 0 && dy == 1)
{
- Blurb(jx, jy);
- Feld[jx][jy] = EL_PLAYER1;
+ SplashAcid(jx, jy);
+ Feld[jx][jy] = EL_PLAYER_1;
InitMovingField(jx, jy, MV_DOWN);
Store[jx][jy] = EL_ACID;
ContinueMoving(jx, jy);
int original_move_delay_value = player->move_delay_value;
#if DEBUG
- printf("THIS SHOULD ONLY HAPPEN WITH PRE-1.2 LEVEL TAPES.\n");
+ printf("THIS SHOULD ONLY HAPPEN WITH PRE-1.2 LEVEL TAPES. [%ld]\n",
+ tape.counter);
#endif
/* scroll remaining steps with finest movement resolution */
}
}
+#if 0
+#if 1
+ InitPlayerGfxAnimation(player, ACTION_DEFAULT);
+#else
if (!(moved & MF_MOVING) && !player->Pushing)
player->Frame = 0;
- else
- player->Frame = (player->Frame + 1) % 4;
+#endif
+#endif
+
+ player->StepFrame = 0;
if (moved & MF_MOVING)
{
else if (old_jx == jx && old_jy != jy)
player->MovDir = (old_jy < jy ? MV_DOWN : MV_UP);
- DrawNewLevelField(jx, jy); /* for "ErdreichAnbroeckeln()" */
+ DrawLevelField(jx, jy); /* for "crumbled sand" */
player->last_move_dir = player->MovDir;
player->is_moving = TRUE;
if (player->MovPos == 0)
{
- if (IS_QUICK_GATE(Feld[last_jx][last_jy]))
+ if (IS_PASSABLE(Feld[last_jx][last_jy]))
{
/* continue with normal speed after quickly moving through gate */
HALVE_PLAYER_SPEED(player);
{
struct PlayerInfo *player = PLAYERINFO(good_x, good_y);
- if (player->shield_active_time_left > 0)
+ if (player->shield_deadly_time_left > 0)
Bang(kill_x, kill_y);
else if (!PLAYER_PROTECTED(good_x, good_y))
KillHero(player);
;
#endif
- if (player->shield_active_time_left > 0)
+ if (player->shield_deadly_time_left > 0)
Bang(bad_x, bad_y);
else if (!PLAYER_PROTECTED(kill_x, kill_y))
KillHero(player);
continue;
element = Feld[x][y];
- if (IS_AMOEBOID(element) || element == EL_GAMEOFLIFE ||
- element == EL_AMOEBA_CREATING || element == EL_AMOEBA_DROP)
+ if (IS_AMOEBOID(element) || element == EL_GAME_OF_LIFE ||
+ element == EL_AMOEBA_GROWING || element == EL_AMOEBA_DROP)
{
kill_x = x;
kill_y = y;
if (!player->active)
return;
- if (IS_PFORTE(Feld[jx][jy]))
- Feld[jx][jy] = EL_EMPTY;
+ /* remove accessible field at the player's position */
+ Feld[jx][jy] = EL_EMPTY;
/* deactivate shield (else Bang()/Explode() would not work right) */
- player->shield_passive_time_left = 0;
- player->shield_active_time_left = 0;
+ player->shield_normal_time_left = 0;
+ player->shield_deadly_time_left = 0;
Bang(jx, jy);
BuryHero(player);
if (!player->active)
return;
- PlaySoundLevel(jx, jy, SND_PLAYER_DYING);
+ PlaySoundLevel(jx, jy, SND_CLASS_PLAYER_DYING);
PlaySoundLevel(jx, jy, SND_GAME_LOSING);
player->GameOver = TRUE;
ExitY = ZY = jy;
}
+/*
+ checkDiagonalPushing()
+ -----------------------------------------------------------------------------
+ check if diagonal input device direction results in pushing of object
+ (by checking if the alternative direction is walkable, diggable, ...)
+*/
+
+static boolean checkDiagonalPushing(struct PlayerInfo *player,
+ int x, int y, int real_dx, int real_dy)
+{
+ int jx, jy, dx, dy, xx, yy;
+
+ if (real_dx == 0 || real_dy == 0) /* no diagonal direction => push */
+ return TRUE;
+
+ /* diagonal direction: check alternative direction */
+ jx = player->jx;
+ jy = player->jy;
+ dx = x - jx;
+ dy = y - jy;
+ xx = jx + (dx == 0 ? real_dx : 0);
+ yy = jy + (dy == 0 ? real_dy : 0);
+
+ return (!IN_LEV_FIELD(xx, yy) || IS_SOLID_FOR_PUSHING(Feld[xx][yy]));
+}
+
+/*
+ DigField()
+ -----------------------------------------------------------------------------
+ x, y: field next to player (non-diagonal) to try to dig to
+ real_dx, real_dy: direction as read from input device (can be diagonal)
+*/
+
int DigField(struct PlayerInfo *player,
int x, int y, int real_dx, int real_dy, int mode)
{
dy == +1 ? MV_DOWN : MV_NO_MOVING);
int element;
+ if (player->MovPos == 0)
+ {
+ player->is_digging = FALSE;
+ player->is_collecting = FALSE;
+ }
+
if (player->MovPos == 0)
player->Pushing = FALSE;
{
player->Switching = FALSE;
player->push_delay = 0;
+
return MF_NO_ACTION;
}
if (IS_MOVING(x, y) || IS_PLAYER(x, y))
return MF_NO_ACTION;
- if (IS_TUBE(Feld[jx][jy]))
+#if 0
+ if (IS_TUBE(Feld[jx][jy]) || IS_TUBE(Back[jx][jy]))
+#else
+ if (IS_TUBE(Feld[jx][jy]) ||
+ (IS_TUBE(Back[jx][jy]) && game.engine_version >= VERSION_IDENT(2,2,0)))
+#endif
{
int i = 0;
+ int tube_element = (IS_TUBE(Feld[jx][jy]) ? Feld[jx][jy] : Back[jx][jy]);
int tube_leave_directions[][2] =
{
- { EL_TUBE_ALL, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
+ { EL_TUBE_ANY, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
{ EL_TUBE_VERTICAL, MV_UP | MV_DOWN },
{ EL_TUBE_HORIZONTAL, MV_LEFT | MV_RIGHT },
{ EL_TUBE_VERTICAL_LEFT, MV_LEFT | MV_UP | MV_DOWN },
{ -1, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN }
};
- while (tube_leave_directions[i][0] != Feld[jx][jy])
+ while (tube_leave_directions[i][0] != tube_element)
{
i++;
if (tube_leave_directions[i][0] == -1) /* should not happen */
element = Feld[x][y];
+#if 1
+ if (mode == DF_SNAP && !IS_SNAPPABLE(element) &&
+ game.engine_version >= VERSION_IDENT(2,2,0))
+ return MF_NO_ACTION;
+#endif
+
switch (element)
{
case EL_EMPTY:
case EL_TRAP:
case EL_SP_BASE:
case EL_SP_BUGGY_BASE:
+ case EL_SP_BUGGY_BASE_ACTIVATING:
RemoveField(x, y);
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_DIGGING);
+#if 1
+ if (mode != DF_SNAP && element != EL_EMPTY)
+ {
+ GfxElement[x][y] = (CAN_BE_CRUMBLED(element) ? EL_SAND : element);
+ player->is_digging = TRUE;
+ }
+#endif
+ PlaySoundLevelElementAction(x, y, element, ACTION_DIGGING);
break;
case EL_EMERALD:
case EL_PEARL:
case EL_CRYSTAL:
RemoveField(x, y);
+#if 1
+ if (mode != DF_SNAP)
+ {
+ GfxElement[x][y] = element;
+ player->is_collecting = TRUE;
+ }
+#endif
local_player->gems_still_needed -= (element == EL_DIAMOND ? 3 :
element == EL_PEARL ? 5 :
element == EL_CRYSTAL ? 8 : 1);
local_player->gems_still_needed = 0;
RaiseScoreElement(element);
DrawText(DX_EMERALDS, DY_EMERALDS,
- int2str(local_player->gems_still_needed, 3),
- FS_SMALL, FC_YELLOW);
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_COLLECTING);
+ int2str(local_player->gems_still_needed, 3), FONT_TEXT_2);
+ PlaySoundLevelElementAction(x, y, element, ACTION_COLLECTING);
break;
case EL_SPEED_PILL:
if (level.time > 0)
{
TimeLeft += 10;
- DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FS_SMALL, FC_YELLOW);
+ DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FONT_TEXT_2);
}
- PlaySoundStereo(SND_EXTRA_TIME_COLLECTING, SOUND_MAX_RIGHT);
+ PlaySoundStereo(SND_EXTRA_TIME_COLLECTING, SOUND_MIDDLE);
break;
case EL_SHIELD_NORMAL:
RemoveField(x, y);
- player->shield_passive_time_left += 10;
+ player->shield_normal_time_left += 10;
PlaySoundLevel(x, y, SND_SHIELD_NORMAL_COLLECTING);
break;
case EL_SHIELD_DEADLY:
RemoveField(x, y);
- player->shield_passive_time_left += 10;
- player->shield_active_time_left += 10;
+ player->shield_normal_time_left += 10;
+ player->shield_deadly_time_left += 10;
PlaySoundLevel(x, y, SND_SHIELD_DEADLY_COLLECTING);
break;
case EL_SP_DISK_RED:
RemoveField(x, y);
player->dynamite++;
+ player->use_disk_red_graphic = (element == EL_SP_DISK_RED);
RaiseScoreElement(EL_DYNAMITE);
- DrawText(DX_DYNAMITE, DY_DYNAMITE,
- int2str(local_player->dynamite, 3),
- FS_SMALL, FC_YELLOW);
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_COLLECTING);
+ DrawText(DX_DYNAMITE, DY_DYNAMITE, int2str(local_player->dynamite, 3),
+ FONT_TEXT_2);
+ PlaySoundLevelElementAction(x, y, element, ACTION_COLLECTING);
break;
- case EL_DYNABOMB_NR:
+ case EL_DYNABOMB_INCREASE_NUMBER:
RemoveField(x, y);
player->dynabomb_count++;
player->dynabombs_left++;
RaiseScoreElement(EL_DYNAMITE);
- PlaySoundLevel(x, y, SND_DYNABOMB_NR_COLLECTING);
+ PlaySoundLevel(x, y, SND_DYNABOMB_INCREASE_NUMBER_COLLECTING);
break;
- case EL_DYNABOMB_SZ:
+ case EL_DYNABOMB_INCREASE_SIZE:
RemoveField(x, y);
player->dynabomb_size++;
RaiseScoreElement(EL_DYNAMITE);
- PlaySoundLevel(x, y, SND_DYNABOMB_SZ_COLLECTING);
+ PlaySoundLevel(x, y, SND_DYNABOMB_INCREASE_SIZE_COLLECTING);
break;
- case EL_DYNABOMB_XL:
+ case EL_DYNABOMB_INCREASE_POWER:
RemoveField(x, y);
player->dynabomb_xl = TRUE;
RaiseScoreElement(EL_DYNAMITE);
- PlaySoundLevel(x, y, SND_DYNABOMB_XL_COLLECTING);
+ PlaySoundLevel(x, y, SND_DYNABOMB_INCREASE_POWER_COLLECTING);
break;
- case EL_KEY1:
- case EL_KEY2:
- case EL_KEY3:
- case EL_KEY4:
+ case EL_KEY_1:
+ case EL_KEY_2:
+ case EL_KEY_3:
+ case EL_KEY_4:
{
- int key_nr = element - EL_KEY1;
+ int key_nr = element - EL_KEY_1;
+ int graphic = el2edimg(element);
RemoveField(x, y);
player->key[key_nr] = TRUE;
RaiseScoreElement(element);
- DrawNewMiniGraphicExt(drawto, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS,
- GFX_SCHLUESSEL1 + key_nr);
- DrawNewMiniGraphicExt(window, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS,
- GFX_SCHLUESSEL1 + key_nr);
- PlaySoundLevel(x, y, SND_KEY_COLLECTING);
+ DrawMiniGraphicExt(drawto, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS,
+ graphic);
+ DrawMiniGraphicExt(window, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS,
+ graphic);
+ PlaySoundLevel(x, y, SND_CLASS_KEY_COLLECTING);
break;
}
- case EL_EM_KEY1:
- case EL_EM_KEY2:
- case EL_EM_KEY3:
- case EL_EM_KEY4:
+ case EL_EM_KEY_1:
+ case EL_EM_KEY_2:
+ case EL_EM_KEY_3:
+ case EL_EM_KEY_4:
{
- int key_nr = element - EL_EM_KEY1;
+ int key_nr = element - EL_EM_KEY_1;
+ int graphic = el2edimg(EL_KEY_1 + key_nr);
RemoveField(x, y);
player->key[key_nr] = TRUE;
RaiseScoreElement(element);
- DrawNewMiniGraphicExt(drawto, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS,
- GFX_SCHLUESSEL1 + key_nr);
- DrawNewMiniGraphicExt(window, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS,
- GFX_SCHLUESSEL1 + key_nr);
- PlaySoundLevel(x, y, SND_KEY_COLLECTING);
+ DrawMiniGraphicExt(drawto, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS,
+ graphic);
+ DrawMiniGraphicExt(window, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS,
+ graphic);
+ PlaySoundLevel(x, y, SND_CLASS_KEY_COLLECTING);
break;
}
Feld[x][y] = EL_ROBOT_WHEEL_ACTIVE;
ZX = x;
ZY = y;
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
PlaySoundLevel(x, y, SND_ROBOT_WHEEL_ACTIVATING);
return MF_ACTION;
break;
}
break;
- case EL_CONVEYOR_BELT1_SWITCH_LEFT:
- case EL_CONVEYOR_BELT1_SWITCH_MIDDLE:
- case EL_CONVEYOR_BELT1_SWITCH_RIGHT:
- case EL_CONVEYOR_BELT2_SWITCH_LEFT:
- case EL_CONVEYOR_BELT2_SWITCH_MIDDLE:
- case EL_CONVEYOR_BELT2_SWITCH_RIGHT:
- case EL_CONVEYOR_BELT3_SWITCH_LEFT:
- case EL_CONVEYOR_BELT3_SWITCH_MIDDLE:
- case EL_CONVEYOR_BELT3_SWITCH_RIGHT:
- case EL_CONVEYOR_BELT4_SWITCH_LEFT:
- case EL_CONVEYOR_BELT4_SWITCH_MIDDLE:
- case EL_CONVEYOR_BELT4_SWITCH_RIGHT:
+ case EL_CONVEYOR_BELT_1_SWITCH_LEFT:
+ case EL_CONVEYOR_BELT_1_SWITCH_MIDDLE:
+ case EL_CONVEYOR_BELT_1_SWITCH_RIGHT:
+ case EL_CONVEYOR_BELT_2_SWITCH_LEFT:
+ case EL_CONVEYOR_BELT_2_SWITCH_MIDDLE:
+ case EL_CONVEYOR_BELT_2_SWITCH_RIGHT:
+ case EL_CONVEYOR_BELT_3_SWITCH_LEFT:
+ case EL_CONVEYOR_BELT_3_SWITCH_MIDDLE:
+ case EL_CONVEYOR_BELT_3_SWITCH_RIGHT:
+ case EL_CONVEYOR_BELT_4_SWITCH_LEFT:
+ case EL_CONVEYOR_BELT_4_SWITCH_MIDDLE:
+ case EL_CONVEYOR_BELT_4_SWITCH_RIGHT:
if (!player->Switching)
{
player->Switching = TRUE;
ToggleBeltSwitch(x, y);
- PlaySoundLevel(x, y, SND_CONVEYOR_BELT_SWITCH_ACTIVATING);
+ PlaySoundLevel(x, y, SND_CLASS_CONVEYOR_BELT_SWITCH_ACTIVATING);
}
return MF_ACTION;
break;
{
player->Switching = TRUE;
ToggleSwitchgateSwitch(x, y);
- PlaySoundLevel(x, y, SND_SWITCHGATE_SWITCH_ACTIVATING);
+ PlaySoundLevel(x, y, SND_CLASS_SWITCHGATE_SWITCH_ACTIVATING);
}
return MF_ACTION;
break;
return MF_ACTION;
break;
- case EL_BALLOON_SEND_LEFT:
- case EL_BALLOON_SEND_RIGHT:
- case EL_BALLOON_SEND_UP:
- case EL_BALLOON_SEND_DOWN:
- case EL_BALLOON_SEND_ANY_DIRECTION:
- if (element == EL_BALLOON_SEND_ANY_DIRECTION)
+ case EL_BALLOON_SWITCH_LEFT:
+ case EL_BALLOON_SWITCH_RIGHT:
+ case EL_BALLOON_SWITCH_UP:
+ case EL_BALLOON_SWITCH_DOWN:
+ case EL_BALLOON_SWITCH_ANY:
+ if (element == EL_BALLOON_SWITCH_ANY)
game.balloon_dir = move_direction;
else
- game.balloon_dir = (element == EL_BALLOON_SEND_LEFT ? MV_LEFT :
- element == EL_BALLOON_SEND_RIGHT ? MV_RIGHT :
- element == EL_BALLOON_SEND_UP ? MV_UP :
- element == EL_BALLOON_SEND_DOWN ? MV_DOWN :
+ game.balloon_dir = (element == EL_BALLOON_SWITCH_LEFT ? MV_LEFT :
+ element == EL_BALLOON_SWITCH_RIGHT ? MV_RIGHT :
+ element == EL_BALLOON_SWITCH_UP ? MV_UP :
+ element == EL_BALLOON_SWITCH_DOWN ? MV_DOWN :
MV_NO_MOVING);
- PlaySoundLevel(x, y, SND_BALLOON_SWITCH_ACTIVATING);
+ PlaySoundLevel(x, y, SND_CLASS_BALLOON_SWITCH_ACTIVATING);
return MF_ACTION;
break;
case EL_SPRING:
if (mode == DF_SNAP)
return MF_NO_ACTION;
+
/* no "break" -- fall through to next case */
+
/* the following elements can be pushed by "snapping" */
case EL_BD_ROCK:
if (dy)
player->Pushing = TRUE;
+#if 0
+ if (element == EL_ROCK)
+ printf("::: wanna push [%d] [%d]\n",
+ FrameCounter, player->push_delay_value);
+#endif
+
if (!IN_LEV_FIELD(x+dx, y+dy) || !IS_FREE(x+dx, y+dy))
return MF_NO_ACTION;
- if (real_dy)
- {
- if (IN_LEV_FIELD(jx, jy+real_dy) && !IS_SOLID(Feld[jx][jy+real_dy]))
- return MF_NO_ACTION;
- }
+ if (!checkDiagonalPushing(player, x, y, real_dx, real_dy))
+ return MF_NO_ACTION;
if (player->push_delay == 0)
player->push_delay = FrameCounter;
#if 0
if (!FrameReached(&player->push_delay, player->push_delay_value) &&
- !tape.playing && element != EL_SPRING)
+ !tape.playing &&
+ element != EL_SPRING)
return MF_NO_ACTION;
#else
if (!FrameReached(&player->push_delay, player->push_delay_value) &&
else
{
RemoveField(x, y);
- Feld[x+dx][y+dy] = element;
+ Feld[x + dx][y + dy] = element;
}
if (element == EL_SPRING)
{
- Feld[x+dx][y+dy] = EL_SPRING_MOVING;
- MovDir[x+dx][y+dy] = move_direction;
+ Feld[x + dx][y + dy] = EL_SPRING;
+ MovDir[x + dx][y + dy] = move_direction;
}
player->push_delay_value = (element == EL_SPRING ? 0 : 2 + RND(8));
- DrawNewLevelField(x + dx, y + dy);
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_PUSHING);
+ DrawLevelField(x + dx, y + dy);
+ PlaySoundLevelElementAction(x, y, element, ACTION_PUSHING);
break;
- case EL_GATE1:
- case EL_GATE2:
- case EL_GATE3:
- case EL_GATE4:
- if (!player->key[element - EL_GATE1])
+ case EL_GATE_1:
+ case EL_GATE_2:
+ case EL_GATE_3:
+ case EL_GATE_4:
+ if (!player->key[element - EL_GATE_1])
return MF_NO_ACTION;
break;
- case EL_GATE1_GRAY:
- case EL_GATE2_GRAY:
- case EL_GATE3_GRAY:
- case EL_GATE4_GRAY:
- if (!player->key[element - EL_GATE1_GRAY])
+ case EL_GATE_1_GRAY:
+ case EL_GATE_2_GRAY:
+ case EL_GATE_3_GRAY:
+ case EL_GATE_4_GRAY:
+ if (!player->key[element - EL_GATE_1_GRAY])
return MF_NO_ACTION;
break;
- case EL_EM_GATE1:
- case EL_EM_GATE2:
- case EL_EM_GATE3:
- case EL_EM_GATE4:
- if (!player->key[element - EL_EM_GATE1])
+ case EL_EM_GATE_1:
+ case EL_EM_GATE_2:
+ case EL_EM_GATE_3:
+ case EL_EM_GATE_4:
+ if (!player->key[element - EL_EM_GATE_1])
return MF_NO_ACTION;
if (!IN_LEV_FIELD(x + dx, y + dy) || !IS_FREE(x + dx, y + dy))
return MF_NO_ACTION;
player->programmed_action = move_direction;
DOUBLE_PLAYER_SPEED(player);
- PlaySoundLevel(x, y, SND_GATE_PASSING);
+ PlaySoundLevel(x, y, SND_CLASS_GATE_PASSING);
break;
- case EL_EM_GATE1_GRAY:
- case EL_EM_GATE2_GRAY:
- case EL_EM_GATE3_GRAY:
- case EL_EM_GATE4_GRAY:
- if (!player->key[element - EL_EM_GATE1_GRAY])
+ case EL_EM_GATE_1_GRAY:
+ case EL_EM_GATE_2_GRAY:
+ case EL_EM_GATE_3_GRAY:
+ case EL_EM_GATE_4_GRAY:
+ if (!player->key[element - EL_EM_GATE_1_GRAY])
return MF_NO_ACTION;
if (!IN_LEV_FIELD(x + dx, y + dy) || !IS_FREE(x + dx, y + dy))
return MF_NO_ACTION;
player->programmed_action = move_direction;
DOUBLE_PLAYER_SPEED(player);
+#if 1
+ PlaySoundLevelAction(x, y, ACTION_PASSING);
+#else
PlaySoundLevel(x, y, SND_GATE_PASSING);
+#endif
break;
case EL_SWITCHGATE_OPEN:
player->programmed_action = move_direction;
DOUBLE_PLAYER_SPEED(player);
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_PASSING);
+ PlaySoundLevelElementAction(x, y, element, ACTION_PASSING);
break;
- case EL_SP_PORT1_LEFT:
- case EL_SP_PORT2_LEFT:
- case EL_SP_PORT1_RIGHT:
- case EL_SP_PORT2_RIGHT:
- case EL_SP_PORT1_UP:
- case EL_SP_PORT2_UP:
- case EL_SP_PORT1_DOWN:
- case EL_SP_PORT2_DOWN:
- case EL_SP_PORT_X:
- case EL_SP_PORT_Y:
- case EL_SP_PORT_XY:
+ case EL_SP_PORT_LEFT:
+ case EL_SP_PORT_RIGHT:
+ case EL_SP_PORT_UP:
+ case EL_SP_PORT_DOWN:
+ case EL_SP_PORT_HORIZONTAL:
+ case EL_SP_PORT_VERTICAL:
+ case EL_SP_PORT_ANY:
+ case EL_SP_GRAVITY_PORT_LEFT:
+ case EL_SP_GRAVITY_PORT_RIGHT:
+ case EL_SP_GRAVITY_PORT_UP:
+ case EL_SP_GRAVITY_PORT_DOWN:
if ((dx == -1 &&
- element != EL_SP_PORT1_LEFT &&
- element != EL_SP_PORT2_LEFT &&
- element != EL_SP_PORT_X &&
- element != EL_SP_PORT_XY) ||
+ element != EL_SP_PORT_LEFT &&
+ element != EL_SP_GRAVITY_PORT_LEFT &&
+ element != EL_SP_PORT_HORIZONTAL &&
+ element != EL_SP_PORT_ANY) ||
(dx == +1 &&
- element != EL_SP_PORT1_RIGHT &&
- element != EL_SP_PORT2_RIGHT &&
- element != EL_SP_PORT_X &&
- element != EL_SP_PORT_XY) ||
+ element != EL_SP_PORT_RIGHT &&
+ element != EL_SP_GRAVITY_PORT_RIGHT &&
+ element != EL_SP_PORT_HORIZONTAL &&
+ element != EL_SP_PORT_ANY) ||
(dy == -1 &&
- element != EL_SP_PORT1_UP &&
- element != EL_SP_PORT2_UP &&
- element != EL_SP_PORT_Y &&
- element != EL_SP_PORT_XY) ||
+ element != EL_SP_PORT_UP &&
+ element != EL_SP_GRAVITY_PORT_UP &&
+ element != EL_SP_PORT_VERTICAL &&
+ element != EL_SP_PORT_ANY) ||
(dy == +1 &&
- element != EL_SP_PORT1_DOWN &&
- element != EL_SP_PORT2_DOWN &&
- element != EL_SP_PORT_Y &&
- element != EL_SP_PORT_XY) ||
+ element != EL_SP_PORT_DOWN &&
+ element != EL_SP_GRAVITY_PORT_DOWN &&
+ element != EL_SP_PORT_VERTICAL &&
+ element != EL_SP_PORT_ANY) ||
!IN_LEV_FIELD(x + dx, y + dy) ||
!IS_FREE(x + dx, y + dy))
return MF_NO_ACTION;
player->programmed_action = move_direction;
DOUBLE_PLAYER_SPEED(player);
- PlaySoundLevel(x, y, SND_SP_PORT_PASSING);
+ PlaySoundLevel(x, y, SND_CLASS_SP_PORT_PASSING);
break;
- case EL_TUBE_ALL:
+ case EL_TUBE_ANY:
case EL_TUBE_VERTICAL:
case EL_TUBE_HORIZONTAL:
case EL_TUBE_VERTICAL_LEFT:
int i = 0;
int tube_enter_directions[][2] =
{
- { EL_TUBE_ALL, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
+ { EL_TUBE_ANY, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
{ EL_TUBE_VERTICAL, MV_UP | MV_DOWN },
{ EL_TUBE_HORIZONTAL, MV_LEFT | MV_RIGHT },
{ EL_TUBE_VERTICAL_LEFT, MV_RIGHT | MV_UP | MV_DOWN },
if (!(tube_enter_directions[i][1] & move_direction))
return MF_NO_ACTION; /* tube has no opening in this direction */
- PlaySoundLevel(x, y, SND_TUBE_PASSING);
+ PlaySoundLevel(x, y, SND_CLASS_TUBE_PASSING);
}
break;
return MF_NO_ACTION;
if (element == EL_EXIT_OPEN)
- PlaySoundLevel(x, y, SND_EXIT_PASSING);
+ PlaySoundLevel(x, y, SND_CLASS_EXIT_PASSING);
else
- PlaySoundLevel(x, y, SND_SP_EXIT_PASSING);
+ PlaySoundLevel(x, y, SND_CLASS_SP_EXIT_PASSING);
break;
case EL_LAMP:
Feld[x][y] = EL_LAMP_ACTIVE;
local_player->lights_still_needed--;
- DrawNewLevelField(x, y);
+ DrawLevelField(x, y);
PlaySoundLevel(x, y, SND_LAMP_ACTIVATING);
return MF_ACTION;
break;
case EL_TIME_ORB_FULL:
Feld[x][y] = EL_TIME_ORB_EMPTY;
TimeLeft += 10;
- DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FS_SMALL, FC_YELLOW);
- DrawNewLevelField(x, y);
- PlaySoundStereo(SND_TIME_ORB_FULL_COLLECTING, SOUND_MAX_RIGHT);
+ DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FONT_TEXT_2);
+ DrawLevelField(x, y);
+ PlaySoundStereo(SND_TIME_ORB_FULL_COLLECTING, SOUND_MIDDLE);
return MF_ACTION;
break;
|| !IS_SB_ELEMENT(element))))
return MF_NO_ACTION;
- if (dx && real_dy)
- {
- if (IN_LEV_FIELD(jx, jy+real_dy) && !IS_SOLID(Feld[jx][jy+real_dy]))
- return MF_NO_ACTION;
- }
- else if (dy && real_dx)
- {
- if (IN_LEV_FIELD(jx+real_dx, jy) && !IS_SOLID(Feld[jx+real_dx][jy]))
- return MF_NO_ACTION;
- }
+ if (!checkDiagonalPushing(player, x, y, real_dx, real_dy))
+ return MF_NO_ACTION;
if (player->push_delay == 0)
player->push_delay = FrameCounter;
Feld[x+dx][y+dy] = EL_SOKOBAN_FIELD_FULL;
local_player->sokobanfields_still_needed--;
if (element == EL_SOKOBAN_OBJECT)
- PlaySoundLevel(x, y, SND_SOKOBAN_FIELD_FILLING);
+#if 1
+ PlaySoundLevelAction(x+dx, y+dy, ACTION_FILLING);
+#else
+ PlaySoundLevel(x, y, SND_CLASS_SOKOBAN_FIELD_FILLING);
+#endif
else
+#if 1
+ PlaySoundLevelAction(x+dx, y+dy, ACTION_PUSHING);
+#else
PlaySoundLevel(x, y, SND_SOKOBAN_OBJECT_PUSHING);
+#endif
}
else
{
Feld[x+dx][y+dy] = EL_SOKOBAN_OBJECT;
if (element == EL_SOKOBAN_FIELD_FULL)
+#if 1
+ PlaySoundLevelAction(x+dx, y+dy, ACTION_EMPTYING);
+#else
PlaySoundLevel(x, y, SND_SOKOBAN_FIELD_EMPTYING);
+#endif
else
+#if 1
+ PlaySoundLevelAction(x+dx, y+dy, ACTION_PUSHING);
+#else
PlaySoundLevel(x, y, SND_SOKOBAN_OBJECT_PUSHING);
+#endif
}
}
else
{
RemoveField(x, y);
Feld[x+dx][y+dy] = element;
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_PUSHING);
+ PlaySoundLevelElementAction(x, y, element, ACTION_PUSHING);
}
player->push_delay_value = (element == EL_BALLOON ? 0 : 2);
- DrawNewLevelField(x, y);
- DrawNewLevelField(x + dx, y + dy);
+ DrawLevelField(x, y);
+ DrawLevelField(x + dx, y + dy);
if (IS_SB_ELEMENT(element) &&
local_player->sokobanfields_still_needed == 0 &&
game.emulation == EMU_SOKOBAN)
{
player->LevelSolved = player->GameOver = TRUE;
- PlaySoundLevel(x, y, SND_SOKOBAN_GAME_SOLVING);
+ PlaySoundLevel(x, y, SND_GAME_SOKOBAN_SOLVING);
}
break;
break;
default:
+
+ if (IS_WALKABLE(element))
+ {
+ break;
+ }
+ else if (IS_DIGGABLE(element))
+ {
+ RemoveField(x, y);
+#if 1
+ if (mode != DF_SNAP)
+ {
+ GfxElement[x][y] =
+ (CAN_BE_CRUMBLED(element) ? EL_SAND : GFX_ELEMENT(element));
+ player->is_digging = TRUE;
+ }
+#endif
+ PlaySoundLevelElementAction(x, y, element, ACTION_DIGGING);
+
+ break;
+ }
+ else if (IS_COLLECTIBLE(element))
+ {
+ RemoveField(x, y);
+#if 1
+ if (mode != DF_SNAP)
+ {
+ GfxElement[x][y] = element;
+ player->is_collecting = TRUE;
+ }
+#endif
+ PlaySoundLevelElementAction(x, y, element, ACTION_COLLECTING);
+
+ break;
+ }
+ else if (IS_PUSHABLE(element))
+ {
+ if (mode == DF_SNAP)
+ return MF_NO_ACTION;
+
+ if (CAN_FALL(element) && dy)
+ return MF_NO_ACTION;
+
+ player->Pushing = TRUE;
+
+ if (!IN_LEV_FIELD(x+dx, y+dy) || !IS_FREE(x+dx, y+dy))
+ return MF_NO_ACTION;
+
+ if (!checkDiagonalPushing(player, x, y, real_dx, real_dy))
+ return MF_NO_ACTION;
+
+ if (player->push_delay == 0)
+ player->push_delay = FrameCounter;
+
+ if (!FrameReached(&player->push_delay, player->push_delay_value) &&
+ !(tape.playing && tape.file_version < FILE_VERSION_2_0))
+ return MF_NO_ACTION;
+
+ RemoveField(x, y);
+ Feld[x + dx][y + dy] = element;
+
+ player->push_delay_value = 2 + RND(8);
+
+ DrawLevelField(x + dx, y + dy);
+ PlaySoundLevelElementAction(x, y, element, ACTION_PUSHING);
+
+ break;
+ }
+
return MF_NO_ACTION;
}
player->push_delay = 0;
+ if (Feld[x][y] != element) /* really digged/collected something */
+ player->is_collecting = !player->is_digging;
+
return MF_MOVING;
}
int jx = player->jx, jy = player->jy;
int x = jx + dx, y = jy + dy;
+ if (player->MovPos && game.engine_version >= VERSION_IDENT(2,2,0))
+ return FALSE;
+
if (!player->active || !IN_LEV_FIELD(x, y))
return FALSE;
player->Pushing = FALSE;
player->snapped = FALSE;
+
+ if (player->MovPos == 0)
+ {
+ player->is_digging = FALSE;
+ player->is_collecting = FALSE;
+ }
+
return FALSE;
}
dy < 0 ? MV_UP :
dy > 0 ? MV_DOWN : MV_NO_MOVING);
- if (!DigField(player, x, y, 0, 0, DF_SNAP))
+ if (DigField(player, x, y, 0, 0, DF_SNAP) == MF_NO_ACTION)
return FALSE;
player->snapped = TRUE;
- DrawNewLevelField(x, y);
+ player->is_digging = FALSE;
+ player->is_collecting = FALSE;
+
+ DrawLevelField(x, y);
BackToFront();
return TRUE;
IS_ACTIVE_BOMB(element) || element == EL_EXPLOSION)
return FALSE;
+#if 0
+ if (element != EL_EMPTY)
+ return FALSE;
+#endif
+
if (element != EL_EMPTY)
+ {
+#if 0
Store[jx][jy] = element;
+#else
+ Back[jx][jy] = element;
+#endif
+ }
+
+ MovDelay[jx][jy] = 96;
+
+ ResetGfxAnimation(jx, jy);
+ ResetRandomAnimationValue(jx, jy);
if (player->dynamite)
{
- Feld[jx][jy] = EL_DYNAMITE_ACTIVE;
- MovDelay[jx][jy] = 96;
+ Feld[jx][jy] = (player->use_disk_red_graphic ? EL_SP_DISK_RED_ACTIVE :
+ EL_DYNAMITE_ACTIVE);
player->dynamite--;
+
DrawText(DX_DYNAMITE, DY_DYNAMITE, int2str(local_player->dynamite, 3),
- FS_SMALL, FC_YELLOW);
+ FONT_TEXT_2);
if (IN_SCR_FIELD(SCREENX(jx), SCREENY(jy)))
{
-#if 0
- if (game.emulation == EMU_SUPAPLEX)
- DrawGraphic(SCREENX(jx), SCREENY(jy), GFX_SP_DISK_RED);
- else
- DrawGraphicThruMask(SCREENX(jx), SCREENY(jy), GFX_DYNAMIT);
+#if 1
+ DrawGraphicThruMask(SCREENX(jx), SCREENY(jy), el2img(Feld[jx][jy]), 0);
#else
if (game.emulation == EMU_SUPAPLEX)
- DrawNewGraphic(SCREENX(jx), SCREENY(jy), IMG_SP_DISK_RED, 0);
+ DrawGraphic(SCREENX(jx), SCREENY(jy), IMG_SP_DISK_RED, 0);
else
- DrawNewGraphicThruMask(SCREENX(jx), SCREENY(jy),
- IMG_DYNAMITE_ACTIVE, 0);
+ DrawGraphicThruMask(SCREENX(jx), SCREENY(jy), IMG_DYNAMITE_ACTIVE, 0);
#endif
}
- PlaySoundLevel(jx, jy, SND_DYNAMITE_DROPPING);
+ PlaySoundLevelAction(jx, jy, ACTION_DROPPING);
}
else
{
Feld[jx][jy] =
- EL_DYNABOMB_PLAYER1_ACTIVE + (player->element_nr - EL_PLAYER1);
- MovDelay[jx][jy] = 96;
+ EL_DYNABOMB_PLAYER_1_ACTIVE + (player->element_nr - EL_PLAYER_1);
player->dynabombs_left--;
+
if (IN_SCR_FIELD(SCREENX(jx), SCREENY(jy)))
-#if 0
- DrawGraphicThruMask(SCREENX(jx), SCREENY(jy), GFX_DYNABOMB);
-#else
- DrawNewGraphicThruMask(SCREENX(jx), SCREENY(jy),
- el2img(Feld[jx][jy]), 0);
-#endif
+ DrawGraphicThruMask(SCREENX(jx), SCREENY(jy), el2img(Feld[jx][jy]), 0);
- PlaySoundLevel(jx, jy, SND_DYNABOMB_DROPPING);
+ PlaySoundLevelAction(jx, jy, ACTION_DROPPING);
}
return TRUE;
}
-void PlaySoundLevel(int x, int y, int nr)
+/* ------------------------------------------------------------------------- */
+/* game sound playing functions */
+/* ------------------------------------------------------------------------- */
+
+static int *loop_sound_frame = NULL;
+static int *loop_sound_volume = NULL;
+
+void InitPlaySoundLevel()
+{
+ int num_sounds = getSoundListSize();
+
+ if (loop_sound_frame != NULL)
+ free(loop_sound_frame);
+
+ if (loop_sound_volume != NULL)
+ free(loop_sound_volume);
+
+ loop_sound_frame = checked_calloc(num_sounds * sizeof(int));
+ loop_sound_volume = checked_calloc(num_sounds * sizeof(int));
+}
+
+static void PlaySoundLevel(int x, int y, int nr)
{
- static int loop_sound_frame[NUM_SOUND_FILES];
- static int loop_sound_volume[NUM_SOUND_FILES];
int sx = SCREENX(x), sy = SCREENY(y);
int volume, stereo_position;
int max_distance = 8;
PlaySoundExt(nr, volume, stereo_position, type);
}
-void PlaySoundLevelAction(int x, int y, int sound_action)
+static void PlaySoundLevelNearest(int x, int y, int sound_action)
+{
+ PlaySoundLevel(x < LEVELX(BX1) ? LEVELX(BX1) :
+ x > LEVELX(BX2) ? LEVELX(BX2) : x,
+ y < LEVELY(BY1) ? LEVELY(BY1) :
+ y > LEVELY(BY2) ? LEVELY(BY2) : y,
+ sound_action);
+}
+
+static void PlaySoundLevelAction(int x, int y, int action)
+{
+ PlaySoundLevelElementAction(x, y, Feld[x][y], action);
+}
+
+static void PlaySoundLevelElementAction(int x, int y, int element, int action)
{
- PlaySoundLevelElementAction(x, y, Feld[x][y], sound_action);
+ int sound_effect = element_info[element].sound[action];
+
+ if (sound_effect != SND_UNDEFINED)
+ PlaySoundLevel(x, y, sound_effect);
}
-void PlaySoundLevelElementAction(int x, int y, int element, int sound_action)
+static void PlaySoundLevelActionIfLoop(int x, int y, int action)
{
- int sound_effect = element_action_sound[element][sound_action];
+ int sound_effect = element_info[Feld[x][y]].sound[action];
- if (sound_effect != -1)
+ if (sound_effect != SND_UNDEFINED && IS_LOOP_SOUND(sound_effect))
PlaySoundLevel(x, y, sound_effect);
}
+static void StopSoundLevelActionIfLoop(int x, int y, int action)
+{
+ int sound_effect = element_info[Feld[x][y]].sound[action];
+
+ if (sound_effect != SND_UNDEFINED && IS_LOOP_SOUND(sound_effect))
+ StopSoundExt(sound_effect, SND_CTRL_STOP_SOUND);
+}
+
void RaiseScore(int value)
{
local_player->score += value;
- DrawText(DX_SCORE, DY_SCORE, int2str(local_player->score, 5),
- FS_SMALL, FC_YELLOW);
+ DrawText(DX_SCORE, DY_SCORE, int2str(local_player->score, 5), FONT_TEXT_2);
}
void RaiseScoreElement(int element)
case EL_EMERALD_YELLOW:
case EL_EMERALD_RED:
case EL_EMERALD_PURPLE:
- RaiseScore(level.score[SC_EDELSTEIN]);
+ RaiseScore(level.score[SC_EMERALD]);
break;
case EL_DIAMOND:
- RaiseScore(level.score[SC_DIAMANT]);
+ RaiseScore(level.score[SC_DIAMOND]);
break;
case EL_BUG:
case EL_BD_BUTTERFLY:
- RaiseScore(level.score[SC_KAEFER]);
+ RaiseScore(level.score[SC_BUG]);
break;
case EL_SPACESHIP:
case EL_BD_FIREFLY:
- RaiseScore(level.score[SC_FLIEGER]);
+ RaiseScore(level.score[SC_SPACESHIP]);
break;
case EL_YAMYAM:
case EL_DARK_YAMYAM:
- RaiseScore(level.score[SC_MAMPFER]);
+ RaiseScore(level.score[SC_YAMYAM]);
break;
case EL_ROBOT:
RaiseScore(level.score[SC_ROBOT]);
RaiseScore(level.score[SC_PACMAN]);
break;
case EL_NUT:
- RaiseScore(level.score[SC_KOKOSNUSS]);
+ RaiseScore(level.score[SC_NUT]);
break;
case EL_DYNAMITE:
- RaiseScore(level.score[SC_DYNAMIT]);
+ RaiseScore(level.score[SC_DYNAMITE]);
break;
- case EL_KEY1:
- case EL_KEY2:
- case EL_KEY3:
- case EL_KEY4:
- RaiseScore(level.score[SC_SCHLUESSEL]);
+ case EL_KEY_1:
+ case EL_KEY_2:
+ case EL_KEY_3:
+ case EL_KEY_4:
+ RaiseScore(level.score[SC_KEY]);
break;
default:
break;
else
#endif
{
- game_status = MAINMENU;
+ game_status = GAME_MODE_MAIN;
DrawMainMenu();
}
}
for (i=0; i<NUM_GAME_BUTTONS; i++)
{
- Bitmap *gd_bitmap = pix[PIX_DOOR];
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
struct GadgetInfo *gi;
int button_type;
boolean checked;
}
}
+void FreeGameButtons()
+{
+ int i;
+
+ for (i=0; i<NUM_GAME_BUTTONS; i++)
+ FreeGadget(game_gadget[i]);
+}
+
static void MapGameButtons()
{
int i;
{
int id = gi->custom_id;
- if (game_status != PLAYING)
+ if (game_status != GAME_MODE_PLAYING)
return;
switch (id)