EL_CHAR('I'),
EL_CHAR('I'),
+ EL_PEARL,
+ EL_CRYSTAL,
+ EL_WALL_PEARL,
+ EL_WALL_CRYSTAL,
+
EL_BELT1_LEFT,
EL_BELT1_MIDDLE,
EL_BELT1_RIGHT,
EL_EXTRA_TIME,
EL_LEERRAUM,
+ EL_CHAR('D'),
+ EL_CHAR('X'),
+ EL_CHAR('-'),
+ EL_CHAR(' '),
+
+ EL_CHAR('B'),
+ EL_CHAR('O'),
+ EL_CHAR('U'),
+ EL_CHAR('L'),
+
+ EL_CHAR('-'),
+ EL_CHAR('D'),
+ EL_CHAR('E'),
+ EL_CHAR('R'),
+
+ EL_CHAR('D'),
+ EL_CHAR('A'),
+ EL_CHAR('S'),
+ EL_CHAR('H'),
+
+ EL_SPRING,
+ EL_TUBE_RIGHT_DOWN,
+ EL_TUBE_HORIZ_DOWN,
+ EL_TUBE_LEFT_DOWN,
+
+ EL_TUBE_HORIZONTAL,
+ EL_TUBE_VERT_RIGHT,
+ EL_TUBE_CROSS,
+ EL_TUBE_VERT_LEFT,
+
+ EL_TUBE_VERTICAL,
+ EL_TUBE_RIGHT_UP,
+ EL_TUBE_HORIZ_UP,
+ EL_TUBE_LEFT_UP,
+
+ EL_TRAP_INACTIVE,
+ EL_LEERRAUM,
+ EL_LEERRAUM,
+ EL_LEERRAUM,
+
/*
EL_CHAR('D'),
EL_CHAR('Y'),
switch (LEVELCLASS(leveldir_current))
{
case LEVELCLASS_TUTORIAL:
- strcpy(level.author, PROGRAM_AUTHOR_STRING);
- break;
+ strcpy(level.author, PROGRAM_AUTHOR_STRING);
+ break;
case LEVELCLASS_CONTRIBUTION:
- strncpy(level.author, leveldir_current->name,MAX_LEVEL_AUTHOR_LEN);
- level.author[MAX_LEVEL_AUTHOR_LEN] = '\0';
- break;
+ strncpy(level.author, leveldir_current->name,MAX_LEVEL_AUTHOR_LEN);
+ level.author[MAX_LEVEL_AUTHOR_LEN] = '\0';
+ break;
case LEVELCLASS_USER:
- strncpy(level.author, getRealName(), MAX_LEVEL_AUTHOR_LEN);
- level.author[MAX_LEVEL_AUTHOR_LEN] = '\0';
- break;
+ strncpy(level.author, getRealName(), MAX_LEVEL_AUTHOR_LEN);
+ level.author[MAX_LEVEL_AUTHOR_LEN] = '\0';
+ break;
default:
- /* keep default value */
- break;
+ /* keep default value */
+ break;
}
}
}
ldi->next = NULL;
}
+static void setLevelDirInfoToDefaultsFromParent(struct LevelDirInfo *ldi,
+ struct LevelDirInfo *parent)
+{
+ if (parent == NULL)
+ {
+ setLevelDirInfoToDefaults(ldi);
+ return;
+ }
+
+ /* first copy all values from the parent structure ... */
+ *ldi = *parent;
+
+ /* ... then set all fields to default that cannot be inherited from parent.
+ This is especially important for all those fields that can be set from
+ the 'levelinfo.conf' config file, because the function 'setSetupInfo()'
+ calls 'free()' for all already set token values which requires that no
+ other structure's pointer may point to them!
+ */
+
+ ldi->filename = NULL;
+ ldi->fullpath = NULL;
+ ldi->basepath = NULL;
+ ldi->name = getStringCopy(ANONYMOUS_NAME);
+ ldi->name_short = NULL;
+ ldi->name_sorting = NULL;
+ ldi->author = getStringCopy(parent->author);
+ ldi->imported_from = getStringCopy(parent->imported_from);
+
+ ldi->level_group = FALSE;
+ ldi->parent_link = FALSE;
+
+ ldi->node_parent = parent;
+ ldi->node_group = NULL;
+ ldi->next = NULL;
+}
+
static void setSetupInfoToDefaults(struct SetupInfo *si)
{
int i;
int i;
checkSetupFileListIdentifier(setup_file_list, LEVELINFO_COOKIE);
- setLevelDirInfoToDefaults(leveldir_new);
-
- leveldir_new->node_parent = node_parent;
+ setLevelDirInfoToDefaultsFromParent(leveldir_new, node_parent);
/* set all structure fields according to the token/value pairs */
ldi = *leveldir_new;
/* forward declaration for internal use */
static void CloseAllOpenTimegates(void);
static void CheckGravityMovement(struct PlayerInfo *);
-static void KillHeroUnlessShield(struct PlayerInfo *);
+static void KillHeroUnlessProtected(int, int);
static void MapGameButtons();
static void HandleGameButtons(struct GadgetInfo *);
if (element == EL_EXPLODING)
element = Store2[x][y];
- if (IS_PLAYER(ex, ey) && !SHIELD_ON(PLAYERINFO(ex, ey)))
+ if (IS_PLAYER(ex, ey) && !PLAYER_PROTECTED(ex, ey))
{
switch(StorePlayer[ex][ey])
{
Store[x][y] = EL_EDELSTEIN_ROT;
else if (element == EL_ERZ_EDEL_LILA)
Store[x][y] = EL_EDELSTEIN_LILA;
+ else if (element == EL_WALL_PEARL)
+ Store[x][y] = EL_PEARL;
+ else if (element == EL_WALL_CRYSTAL)
+ Store[x][y] = EL_CRYSTAL;
else if (!IS_PFORTE(Store[x][y]))
Store[x][y] = EL_LEERRAUM;
int element = Store2[x][y];
if (IS_PLAYER(x, y))
- KillHeroUnlessShield(PLAYERINFO(x, y));
+ KillHeroUnlessProtected(x, y);
else if (IS_EXPLOSIVE(element))
{
Feld[x][y] = Store2[x][y];
Bang(x, y);
return;
}
+ else if (element == EL_PEARL)
+ {
+ Feld[x][y] = EL_PEARL_BREAKING;
+ PlaySoundLevel(x, y, SND_KNACK);
+ return;
+ }
if (element == EL_TROPFEN && (lastline || object_hit)) /* acid drop */
{
if (object_hit && IS_PLAYER(x, y+1))
- KillHeroUnlessShield(PLAYERINFO(x, y+1));
+ KillHeroUnlessProtected(x, y+1);
else if (object_hit && smashed == EL_PINGUIN)
Bang(x, y+1);
else
if (IS_PLAYER(x, y+1))
{
- KillHeroUnlessShield(PLAYERINFO(x, y+1));
+ KillHeroUnlessProtected(x, y+1);
return;
}
else if (smashed == EL_PINGUIN)
RaiseScoreElement(EL_KOKOSNUSS);
return;
}
+ else if (smashed == EL_PEARL)
+ {
+ Feld[x][y+1] = EL_PEARL_BREAKING;
+ PlaySoundLevel(x, y, SND_KNACK);
+ return;
+ }
else if (smashed == EL_DIAMANT)
{
Feld[x][y+1] = EL_LEERRAUM;
Moving2Blocked(x, y, &newx, &newy); /* get next screen position */
if (IS_ENEMY(element) && IS_PLAYER(newx, newy) &&
- !SHIELD_ON(PLAYERINFO(newx, newy)))
+ !PLAYER_PROTECTED(newx, newy))
{
#if 1
{
MovDelay[x][y]--;
if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_CRACKINGNUT+3-MovDelay[x][y]/2);
+ DrawGraphic(SCREENX(x), SCREENY(y),
+ GFX_CRACKINGNUT + 3 - MovDelay[x][y]/2);
if (!MovDelay[x][y])
{
}
}
+void BreakingPearl(int x, int y)
+{
+ if (!MovDelay[x][y]) /* next animation frame */
+ MovDelay[x][y] = 9;
+
+ if (MovDelay[x][y]) /* wait some time before next frame */
+ {
+ MovDelay[x][y]--;
+ if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+ DrawGraphic(SCREENX(x), SCREENY(y),
+ GFX_PEARL_BREAKING + 4 - MovDelay[x][y]/2);
+
+ if (!MovDelay[x][y])
+ {
+ Feld[x][y] = EL_LEERRAUM;
+ DrawLevelField(x, y);
+ }
+ }
+}
+
void SiebAktivieren(int x, int y, int typ)
{
int graphic = (typ == 1 ? GFX_SIEB_VOLL : GFX_SIEB2_VOLL) + 3;
if (element == EL_SP_BUG)
{
- if (!MovDelay[x][y]) /* start activating buggy base */
+ 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]) /* wait some time before activating base */
+ if (MovDelay[x][y])
{
MovDelay[x][y]--;
if (MovDelay[x][y] < 5 && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
if (!MovDelay[x][y]) /* start activating buggy base */
MovDelay[x][y] = 1 * FRAMES_PER_SECOND + RND(1 * FRAMES_PER_SECOND);
- if (MovDelay[x][y]) /* wait some time before activating base */
+ if (MovDelay[x][y])
{
MovDelay[x][y]--;
if (MovDelay[x][y])
}
}
+static void CheckTrap(int x, int y)
+{
+ int element = Feld[x][y];
+
+ if (element == EL_TRAP_INACTIVE)
+ {
+ 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;
+
+ Feld[x][y] = EL_TRAP_ACTIVE;
+ }
+ }
+ else if (element == EL_TRAP_ACTIVE)
+ {
+ int delay = 4;
+ int num_frames = 8;
+
+ if (!MovDelay[x][y]) /* start activating trap */
+ MovDelay[x][y] = num_frames * delay;
+
+ if (MovDelay[x][y])
+ {
+ MovDelay[x][y]--;
+
+ if (MovDelay[x][y])
+ {
+ if (!(MovDelay[x][y] % delay))
+ {
+ int phase = MovDelay[x][y]/delay;
+
+ if (phase >= num_frames/2)
+ phase = num_frames - phase;
+
+ if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+ {
+ DrawGraphic(SCREENX(x),SCREENY(y), GFX_TRAP_INACTIVE + phase - 1);
+ ErdreichAnbroeckeln(SCREENX(x), SCREENY(y));
+ }
+ }
+
+ return;
+ }
+
+ Feld[x][y] = EL_TRAP_INACTIVE;
+ DrawLevelField(x, y);
+ }
+ }
+}
+
static void DrawBeltAnimation(int x, int y, int element)
{
int belt_nr = getBeltNrFromElement(element);
Blurb(x, y);
else if (element == EL_CRACKINGNUT)
NussKnacken(x, y);
+ else if (element == EL_PEARL_BREAKING)
+ BreakingPearl(x, y);
else if (element == EL_AUSGANG_ZU)
AusgangstuerPruefen(x, y);
else if (element == EL_AUSGANG_ACT)
CheckForDragon(x, y);
else if (element == EL_SP_BUG || element == EL_SP_BUG_ACTIVE)
CheckBuggyBase(x, y);
+ else if (element == EL_TRAP_INACTIVE || element == EL_TRAP_ACTIVE)
+ CheckTrap(x, y);
else if (element == EL_SP_TERMINAL)
DrawGraphicAnimation(x, y, GFX2_SP_TERMINAL, 7, 12, ANIM_NORMAL);
else if (element == EL_SP_TERMINAL_ACTIVE)
BuryHero(player);
}
else
- {
-#if 1
TestIfBadThingHitsHero(new_jx, new_jy);
-#else
- if (player->shield_time_left == 0)
- KillHero(player);
-#endif
- }
return MF_MOVING;
}
if (player->shield_active_time_left > 0)
Bang(killx, killy);
- else if (player->shield_passive_time_left == 0)
+ else if (!PLAYER_PROTECTED(goodx, goody))
KillHero(player);
}
else
if (player->shield_active_time_left > 0)
Bang(badx, bady);
- else if (player->shield_passive_time_left == 0)
+ else if (!PLAYER_PROTECTED(killx, killy))
KillHero(player);
}
else
BuryHero(player);
}
-static void KillHeroUnlessShield(struct PlayerInfo *player)
+static void KillHeroUnlessProtected(int x, int y)
{
- if (!SHIELD_ON(player))
- KillHero(player);
+ if (!PLAYER_PROTECTED(x, y))
+ KillHero(PLAYERINFO(x, y));
}
void BuryHero(struct PlayerInfo *player)
if (IS_MOVING(x, y) || IS_PLAYER(x, y))
return MF_NO_ACTION;
+ if (IS_TUBE(Feld[jx][jy]))
+ {
+ int i = 0;
+ int tube_leave_directions[][2] =
+ {
+ { EL_TUBE_CROSS, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
+ { EL_TUBE_VERTICAL, MV_UP | MV_DOWN },
+ { EL_TUBE_HORIZONTAL, MV_LEFT | MV_RIGHT },
+ { EL_TUBE_VERT_LEFT, MV_LEFT | MV_UP | MV_DOWN },
+ { EL_TUBE_VERT_RIGHT, MV_RIGHT | MV_UP | MV_DOWN },
+ { EL_TUBE_HORIZ_UP, MV_LEFT | MV_RIGHT | MV_UP },
+ { EL_TUBE_HORIZ_DOWN, MV_LEFT | MV_RIGHT | MV_DOWN },
+ { EL_TUBE_LEFT_UP, MV_LEFT | MV_UP },
+ { EL_TUBE_LEFT_DOWN, MV_LEFT | MV_DOWN },
+ { EL_TUBE_RIGHT_UP, MV_RIGHT | MV_UP },
+ { EL_TUBE_RIGHT_DOWN, MV_RIGHT | MV_DOWN },
+ { -1, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN }
+ };
+
+ while (tube_leave_directions[i][0] != Feld[jx][jy])
+ {
+ i++;
+ if (tube_leave_directions[i][0] == -1) /* should not happen */
+ break;
+ }
+
+ if (!(tube_leave_directions[i][1] & move_direction))
+ return MF_NO_ACTION; /* tube has no opening in this direction */
+ }
+
element = Feld[x][y];
switch (element)
case EL_ERDREICH:
case EL_SAND_INVISIBLE:
+ case EL_TRAP_INACTIVE:
Feld[x][y] = EL_LEERRAUM;
PlaySoundLevel(x, y, SND_SCHLURF);
break;
case EL_EDELSTEIN_LILA:
case EL_DIAMANT:
case EL_SP_INFOTRON:
+ case EL_PEARL:
+ case EL_CRYSTAL:
RemoveField(x, y);
- local_player->gems_still_needed -= (element == EL_DIAMANT ? 3 : 1);
+ local_player->gems_still_needed -= (element == EL_DIAMANT ? 3 :
+ element == EL_PEARL ? 5 :
+ element == EL_CRYSTAL ? 8 : 1);
if (local_player->gems_still_needed < 0)
local_player->gems_still_needed = 0;
RaiseScoreElement(element);
DOUBLE_PLAYER_SPEED(player);
PlaySoundLevel(x, y, SND_GATE);
+ break;
+
+ case EL_TUBE_CROSS:
+ case EL_TUBE_VERTICAL:
+ case EL_TUBE_HORIZONTAL:
+ case EL_TUBE_VERT_LEFT:
+ case EL_TUBE_VERT_RIGHT:
+ case EL_TUBE_HORIZ_UP:
+ case EL_TUBE_HORIZ_DOWN:
+ case EL_TUBE_LEFT_UP:
+ case EL_TUBE_LEFT_DOWN:
+ case EL_TUBE_RIGHT_UP:
+ case EL_TUBE_RIGHT_DOWN:
+ {
+ int i = 0;
+ int tube_enter_directions[][2] =
+ {
+ { EL_TUBE_CROSS, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
+ { EL_TUBE_VERTICAL, MV_UP | MV_DOWN },
+ { EL_TUBE_HORIZONTAL, MV_LEFT | MV_RIGHT },
+ { EL_TUBE_VERT_LEFT, MV_RIGHT | MV_UP | MV_DOWN },
+ { EL_TUBE_VERT_RIGHT, MV_LEFT | MV_UP | MV_DOWN },
+ { EL_TUBE_HORIZ_UP, MV_LEFT | MV_RIGHT | MV_DOWN },
+ { EL_TUBE_HORIZ_DOWN, MV_LEFT | MV_RIGHT | MV_UP },
+ { EL_TUBE_LEFT_UP, MV_RIGHT | MV_DOWN },
+ { EL_TUBE_LEFT_DOWN, MV_RIGHT | MV_UP },
+ { EL_TUBE_RIGHT_UP, MV_LEFT | MV_DOWN },
+ { EL_TUBE_RIGHT_DOWN, MV_LEFT | MV_UP },
+ { -1, MV_NO_MOVING }
+ };
+ while (tube_enter_directions[i][0] != element)
+ {
+ i++;
+ if (tube_enter_directions[i][0] == -1) /* should not happen */
+ break;
+ }
+
+ if (!(tube_enter_directions[i][1] & move_direction))
+ return MF_NO_ACTION; /* tube has no opening in this direction */
+ }
break;
case EL_AUSGANG_ZU:
case EL_SONDE:
case EL_SP_DISK_YELLOW:
case EL_BALLOON:
+ case EL_SPRING:
if (mode == DF_SNAP)
return MF_NO_ACTION;
EL_SWITCHGATE_OPEN,
EL_SWITCHGATE_CLOSED,
EL_TIMEGATE_OPEN,
- EL_TIMEGATE_CLOSED
+ EL_TIMEGATE_CLOSED,
+ EL_TUBE_CROSS,
+ EL_TUBE_VERTICAL,
+ EL_TUBE_HORIZONTAL,
+ EL_TUBE_VERT_LEFT,
+ EL_TUBE_VERT_RIGHT,
+ EL_TUBE_HORIZ_UP,
+ EL_TUBE_HORIZ_DOWN,
+ EL_TUBE_LEFT_UP,
+ EL_TUBE_LEFT_DOWN,
+ EL_TUBE_RIGHT_UP,
+ EL_TUBE_RIGHT_DOWN
};
static int ep_pforte_num = sizeof(ep_pforte)/sizeof(int);
EL_EMC_WALL_5,
EL_EMC_WALL_6,
EL_EMC_WALL_7,
- EL_EMC_WALL_8
+ EL_EMC_WALL_8,
+ EL_CRYSTAL,
+ EL_WALL_PEARL,
+ EL_WALL_CRYSTAL,
+ EL_TUBE_CROSS,
+ EL_TUBE_VERTICAL,
+ EL_TUBE_HORIZONTAL,
+ EL_TUBE_VERT_LEFT,
+ EL_TUBE_VERT_RIGHT,
+ EL_TUBE_HORIZ_UP,
+ EL_TUBE_HORIZ_DOWN,
+ EL_TUBE_LEFT_UP,
+ EL_TUBE_LEFT_DOWN,
+ EL_TUBE_RIGHT_UP,
+ EL_TUBE_RIGHT_DOWN
};
static int ep_solid_num = sizeof(ep_solid)/sizeof(int);
EL_EMC_STEEL_WALL_1,
EL_EMC_STEEL_WALL_2,
EL_EMC_STEEL_WALL_3,
- EL_EMC_STEEL_WALL_4
+ EL_EMC_STEEL_WALL_4,
+ EL_CRYSTAL,
+ EL_TUBE_CROSS,
+ EL_TUBE_VERTICAL,
+ EL_TUBE_HORIZONTAL,
+ EL_TUBE_VERT_LEFT,
+ EL_TUBE_VERT_RIGHT,
+ EL_TUBE_HORIZ_UP,
+ EL_TUBE_HORIZ_DOWN,
+ EL_TUBE_LEFT_UP,
+ EL_TUBE_LEFT_DOWN,
+ EL_TUBE_RIGHT_UP,
+ EL_TUBE_RIGHT_DOWN
};
static int ep_massive_num = sizeof(ep_massive)/sizeof(int);
EL_SP_CHIP_UPPER,
EL_SP_CHIP_LOWER,
EL_SPEED_PILL,
- EL_STEEL_SLANTED
+ EL_STEEL_SLANTED,
+ EL_PEARL,
+ EL_CRYSTAL
};
static int ep_slippery_num = sizeof(ep_slippery)/sizeof(int);
EL_ZEIT_LEER,
EL_SP_ZONK,
EL_SP_INFOTRON,
- EL_SP_DISK_ORANGE
+ EL_SP_DISK_ORANGE,
+ EL_PEARL,
+ EL_CRYSTAL,
+ EL_SPRING
};
static int ep_can_fall_num = sizeof(ep_can_fall)/sizeof(int);
EL_ZEIT_LEER,
EL_SP_ZONK,
EL_SP_INFOTRON,
- EL_SP_DISK_ORANGE
+ EL_SP_DISK_ORANGE,
+ EL_PEARL,
+ EL_CRYSTAL
};
static int ep_can_smash_num = sizeof(ep_can_smash)/sizeof(int);
EL_SP_SNIKSNAK,
EL_SP_ELECTRON,
EL_SP_BUG_ACTIVE,
+ EL_TRAP_ACTIVE,
EL_LANDMINE
};
static int ep_dont_go_to_num = sizeof(ep_dont_go_to)/sizeof(int);
EL_EDELSTEIN_GELB,
EL_EDELSTEIN_ROT,
EL_EDELSTEIN_LILA,
- EL_DIAMANT
+ EL_DIAMANT,
+ EL_PEARL,
+ EL_CRYSTAL
};
static int ep_mampf2_num = sizeof(ep_mampf2)/sizeof(int);
EL_EDELSTEIN_GELB,
EL_EDELSTEIN_ROT,
EL_EDELSTEIN_LILA,
- EL_DIAMANT
+ EL_DIAMANT,
+ EL_PEARL,
+ EL_CRYSTAL
};
static int ep_mampf3_num = sizeof(ep_mampf3)/sizeof(int);
EL_SP_ZONK,
EL_SP_DISK_ORANGE,
EL_SP_DISK_YELLOW,
- EL_BALLOON
+ EL_BALLOON,
+ EL_SPRING
};
static int ep_pushable_num = sizeof(ep_pushable)/sizeof(int);
EL_ERDREICH,
EL_SP_BASE,
EL_SP_BUG,
+ EL_TRAP_INACTIVE,
EL_SAND_INVISIBLE
};
static int ep_eatable_num = sizeof(ep_eatable)/sizeof(int);
EL_SP_PORT2_DOWN,
EL_SP_PORT_X,
EL_SP_PORT_Y,
- EL_SP_PORT_XY
+ EL_SP_PORT_XY,
+ EL_TUBE_CROSS,
+ EL_TUBE_VERTICAL,
+ EL_TUBE_HORIZONTAL,
+ EL_TUBE_VERT_LEFT,
+ EL_TUBE_VERT_RIGHT,
+ EL_TUBE_HORIZ_UP,
+ EL_TUBE_HORIZ_DOWN,
+ EL_TUBE_LEFT_UP,
+ EL_TUBE_LEFT_DOWN,
+ EL_TUBE_RIGHT_UP,
+ EL_TUBE_RIGHT_DOWN
};
static int ep_over_player_num = sizeof(ep_over_player)/sizeof(int);
};
static int ep_belt_switch_num = sizeof(ep_belt_switch)/sizeof(int);
+ static int ep_tube[] =
+ {
+ EL_TUBE_CROSS,
+ EL_TUBE_VERTICAL,
+ EL_TUBE_HORIZONTAL,
+ EL_TUBE_VERT_LEFT,
+ EL_TUBE_VERT_RIGHT,
+ EL_TUBE_HORIZ_UP,
+ EL_TUBE_HORIZ_DOWN,
+ EL_TUBE_LEFT_UP,
+ EL_TUBE_LEFT_DOWN,
+ EL_TUBE_RIGHT_UP,
+ EL_TUBE_RIGHT_DOWN
+ };
+ static int ep_tube_num = sizeof(ep_tube)/sizeof(int);
+
static long ep1_bit[] =
{
EP_BIT_AMOEBALIVE,
static long ep2_bit[] =
{
EP_BIT_BELT,
- EP_BIT_BELT_SWITCH
+ EP_BIT_BELT_SWITCH,
+ EP_BIT_TUBE
};
static int *ep1_array[] =
{
static int *ep2_array[] =
{
ep_belt,
- ep_belt_switch
+ ep_belt_switch,
+ ep_tube
};
static int *ep1_num[] =
{
static int *ep2_num[] =
{
&ep_belt_num,
- &ep_belt_switch_num
+ &ep_belt_switch_num,
+ &ep_tube_num
};
static int num_properties1 = sizeof(ep1_num)/sizeof(int *);
static int num_properties2 = sizeof(ep2_num)/sizeof(int *);
"letter ''",
"letter ''",
"letter ''",
- "growing wall (horizontally)", /* 200 */
- "growing wall (vertically)",
+ "growing wall (horizontal)", /* 200 */
+ "growing wall (vertical)",
"growing wall (all directions)",
"unused",
"unused",
"yellow disk",
"terminal",
"red disk", /* 230 */
- "port (vertically)",
- "port (horizontally)",
+ "port (vertical)",
+ "port (horizontal)",
"port (all directions)",
"electron",
"buggy base",
"normal wall",
"normal wall",
"normal wall",
+ "tube (all directions)",
+ "tube (vertical)",
+ "tube (horizontal)",
+ "tube (vertical & left)",
+ "tube (vertical & right)",
+ "tube (horizontal & up)",
+ "tube (horizontal & down)", /* 350 */
+ "tube (left & up)",
+ "tube (left & down)",
+ "tube (right & up)",
+ "tube (right & down)",
+ "spring",
+ "trap",
"-"
/*
/* values for 'Elementeigenschaften2' */
#define EP_BIT_BELT (1 << 0)
#define EP_BIT_BELT_SWITCH (1 << 1)
+#define EP_BIT_TUBE (1 << 2)
#define IS_AMOEBALIVE(e) (Elementeigenschaften1[e] & EP_BIT_AMOEBALIVE)
#define IS_AMOEBOID(e) (Elementeigenschaften1[e] & EP_BIT_AMOEBOID)
#define IS_ACTIVE_BOMB(e) (Elementeigenschaften1[e] & EP_BIT_ACTIVE_BOMB)
#define IS_BELT(e) (Elementeigenschaften2[e] & EP_BIT_BELT)
#define IS_BELT_SWITCH(e) (Elementeigenschaften2[e] & EP_BIT_BELT_SWITCH)
+#define IS_TUBE(e) (Elementeigenschaften2[e] & EP_BIT_TUBE)
#define IS_PLAYER(x,y) (ELEM_IS_PLAYER(StorePlayer[x][y]))
#define PLAYERINFO(x,y) (&stored_player[StorePlayer[x][y]-EL_SPIELER1])
#define SHIELD_ON(p) ((p)->shield_passive_time_left > 0)
+#define PROTECTED_FIELD(x,y) (IS_TUBE(Feld[x][y]))
+#define PLAYER_PROTECTED(x,y) (SHIELD_ON(PLAYERINFO(x, y)) || \
+ PROTECTED_FIELD(x, y))
/* Pixmaps with graphic file */
#define PIX_BACK 0
#define EL_EMC_WALL_7 342
#define EL_EMC_WALL_8 343
+#define EL_TUBE_CROSS 344
+#define EL_TUBE_VERTICAL 345
+#define EL_TUBE_HORIZONTAL 346
+#define EL_TUBE_VERT_LEFT 347
+#define EL_TUBE_VERT_RIGHT 348
+#define EL_TUBE_HORIZ_UP 349
+#define EL_TUBE_HORIZ_DOWN 350
+#define EL_TUBE_LEFT_UP 351
+#define EL_TUBE_LEFT_DOWN 352
+#define EL_TUBE_RIGHT_UP 353
+#define EL_TUBE_RIGHT_DOWN 354
+#define EL_SPRING 355
+#define EL_TRAP_INACTIVE 356
/* "real" (and therefore drawable) runtime elements */
#define EL_FIRST_RUNTIME_EL 500
#define EL_SWITCHGATE_CLOSING 518
#define EL_TIMEGATE_OPENING 519
#define EL_TIMEGATE_CLOSING 520
+#define EL_PEARL_BREAKING 521
+#define EL_TRAP_ACTIVE 522
/* "unreal" (and therefore not drawable) runtime elements */
#define EL_BLOCKED 600
#define GFX_ARROW_RED_DOWN (GFX_START_ROCKSMORE + 1 * MORE_PER_LINE + 3)
#define GFX_SCROLLBAR_BLUE (GFX_START_ROCKSMORE + 2 * MORE_PER_LINE + 0)
#define GFX_SCROLLBAR_RED (GFX_START_ROCKSMORE + 2 * MORE_PER_LINE + 1)
+#define GFX_PEARL (GFX_START_ROCKSMORE + 3 * MORE_PER_LINE + 0)
+#define GFX_CRYSTAL (GFX_START_ROCKSMORE + 3 * MORE_PER_LINE + 1)
+#define GFX_WALL_PEARL (GFX_START_ROCKSMORE + 3 * MORE_PER_LINE + 2)
+#define GFX_WALL_CRYSTAL (GFX_START_ROCKSMORE + 3 * MORE_PER_LINE + 3)
+#define GFX_PEARL_BREAKING (GFX_START_ROCKSMORE + 4 * MORE_PER_LINE + 0)
+#define GFX_SPRING (GFX_START_ROCKSMORE + 5 * MORE_PER_LINE + 0)
+#define GFX_TUBE_RIGHT_DOWN (GFX_START_ROCKSMORE + 5 * MORE_PER_LINE + 1)
+#define GFX_TUBE_HORIZ_DOWN (GFX_START_ROCKSMORE + 5 * MORE_PER_LINE + 2)
+#define GFX_TUBE_LEFT_DOWN (GFX_START_ROCKSMORE + 5 * MORE_PER_LINE + 3)
+#define GFX_TUBE_HORIZONTAL (GFX_START_ROCKSMORE + 6 * MORE_PER_LINE + 0)
+#define GFX_TUBE_VERT_RIGHT (GFX_START_ROCKSMORE + 6 * MORE_PER_LINE + 1)
+#define GFX_TUBE_CROSS (GFX_START_ROCKSMORE + 6 * MORE_PER_LINE + 2)
+#define GFX_TUBE_VERT_LEFT (GFX_START_ROCKSMORE + 6 * MORE_PER_LINE + 3)
+#define GFX_TUBE_VERTICAL (GFX_START_ROCKSMORE + 7 * MORE_PER_LINE + 0)
+#define GFX_TUBE_RIGHT_UP (GFX_START_ROCKSMORE + 7 * MORE_PER_LINE + 1)
+#define GFX_TUBE_HORIZ_UP (GFX_START_ROCKSMORE + 7 * MORE_PER_LINE + 2)
+#define GFX_TUBE_LEFT_UP (GFX_START_ROCKSMORE + 7 * MORE_PER_LINE + 3)
+
+#define GFX_TRAP_INACTIVE (GFX_START_ROCKSMORE + 0 * MORE_PER_LINE + 4)
+#define GFX_TRAP_ACTIVE (GFX_START_ROCKSMORE + 0 * MORE_PER_LINE + 7)
/* graphics from "RocksFont" */
#define GFX_CHAR_START (GFX_START_ROCKSFONT)
#define GFX_CHAR_END (GFX_CHAR_START + 79)
/* new elements which still have no graphic */
-#define GFX_PEARL GFX_CHAR_FRAGE
-#define GFX_CRYSTAL GFX_CHAR_FRAGE
-#define GFX_WALL_PEARL GFX_CHAR_FRAGE
-#define GFX_WALL_CRYSTAL GFX_CHAR_FRAGE
#define GFX_DOOR_WHITE GFX_CHAR_FRAGE
#define GFX_DOOR_WHITE_GRAY GFX_CHAR_FRAGE
#define GFX_KEY_WHITE GFX_CHAR_FRAGE
char *getStringCopy(char *s)
{
- char *s_copy = checked_malloc(strlen(s) + 1);
+ char *s_copy;
+
+ if (s == NULL)
+ return NULL;
+
+ s_copy = checked_malloc(strlen(s) + 1);
strcpy(s_copy, s);
return s_copy;
*x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
*y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
}
+ else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
+ {
+ graphic -= GFX_START_ROCKSMORE;
+ *pixmap = pix[PIX_MORE];
+ *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
+ *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
+ }
else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
{
graphic -= GFX_START_ROCKSFONT;
element = Feld[ux][uy];
- if (element == EL_ERDREICH || element == EL_LANDMINE)
+ if (element == EL_ERDREICH ||
+ element == EL_LANDMINE ||
+ element == EL_TRAP_INACTIVE ||
+ element == EL_TRAP_ACTIVE)
{
if (!IN_SCR_FIELD(x, y))
return;
else
element = Feld[uxx][uyy];
- if (element == EL_ERDREICH || element == EL_LANDMINE)
+ if (element == EL_ERDREICH ||
+ element == EL_LANDMINE ||
+ element == EL_TRAP_INACTIVE ||
+ element == EL_TRAP_ACTIVE)
continue;
if (i == 1 || i == 2)
uyy = uy + xy[i][1];
if (!IN_LEV_FIELD(uxx, uyy) ||
- (Feld[uxx][uyy] != EL_ERDREICH && Feld[uxx][uyy] != EL_LANDMINE) ||
+ (Feld[uxx][uyy] != EL_ERDREICH &&
+ Feld[uxx][uyy] != EL_LANDMINE &&
+ Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
+ Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
!IN_SCR_FIELD(xx, yy))
continue;
MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
MICRO_TILEX, MICRO_TILEY, xpos, ypos);
}
+ else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
+ {
+ graphic -= GFX_START_ROCKSMORE;
+ XCopyArea(display, pix[PIX_MORE], drawto, gc,
+ MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE) *MICRO_TILEX,
+ MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE) *MICRO_TILEY,
+ MICRO_TILEX, MICRO_TILEY, xpos, ypos);
+ }
else
XCopyArea(display, pix[PIX_BACK], drawto, gc,
MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
+ case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
+ case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
+ case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
+ case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
+ case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
+ case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
+ case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
+ case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
+ case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
+ case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
+ case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
+ case EL_SPRING: return GFX_SPRING;
+ case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
+ case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
default:
{