+2004-03-26
+ * added option to make growing elements grow into anything diggable
+ (for the various amoeba types, biomaze and "game of life")
+
2004-03-24
* fixed bug with movable elements not moving after left behind by CEs
+ * changed gravity movement to anything diggable, not only sand/base
+ * optionally allowing passing to walkable element, not only empty space
+ * added option "can pass to walkable element" for players
+ * finally fixed gravity movement (hopefully)
2004-03-23
* fixed bug with movable elements not moving anymore after falling down
-#define COMPILE_DATE_STRING "[2004-03-25 03:08]"
+#define COMPILE_DATE_STRING "[2004-03-26 10:44]"
#define GADGET_ID_STICK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 5)
#define GADGET_ID_EM_SLIPPERY_GEMS (GADGET_ID_CHECKBUTTON_FIRST + 6)
#define GADGET_ID_USE_SPRING_BUG (GADGET_ID_CHECKBUTTON_FIRST + 7)
-#define GADGET_ID_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 8)
-#define GADGET_ID_SP_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 9)
-#define GADGET_ID_INSTANT_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 10)
-#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 11)
-#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 12)
-#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 13)
-#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 14)
-#define GADGET_ID_CUSTOM_EXPLODE_RESULT (GADGET_ID_CHECKBUTTON_FIRST + 15)
-#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 16)
-#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 17)
-#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 18)
-#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 19)
-#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 20)
-#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 21)
-#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 22)
-#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 23)
-#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 24)
-#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 25)
-#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 26)
-#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 27)
-#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 28)
-#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 29)
-#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 30)
-#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 31)
-#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 32)
-#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 33)
-#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 34)
-#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 35)
+#define GADGET_ID_GROW_INTO_DIGGABLE (GADGET_ID_CHECKBUTTON_FIRST + 8)
+#define GADGET_ID_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 9)
+#define GADGET_ID_SP_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 10)
+#define GADGET_ID_INSTANT_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 11)
+#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 12)
+#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 13)
+#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 14)
+#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 15)
+#define GADGET_ID_CUSTOM_EXPLODE_RESULT (GADGET_ID_CHECKBUTTON_FIRST + 16)
+#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 17)
+#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 18)
+#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 19)
+#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 20)
+#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 21)
+#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 22)
+#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 23)
+#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 24)
+#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 25)
+#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 26)
+#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 27)
+#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 28)
+#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 29)
+#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 30)
+#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 31)
+#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 32)
+#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 33)
+#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 34)
+#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 35)
+#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 36)
/* gadgets for buttons in element list */
-#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 36)
+#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 37)
#define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \
ED_NUM_ELEMENTLIST_BUTTONS - 1)
#define ED_CHECKBUTTON_ID_STICK_ELEMENT 3
#define ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS 4
#define ED_CHECKBUTTON_ID_USE_SPRING_BUG 5
-#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 6
-#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 7
-#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 8
-#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 9
-#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 10
-#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 11
-#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 12
-#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 13
-#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 14
-#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 15
-#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 16
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 17
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 18
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 19
-#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 20
-#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 21
-#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_RESULT 22
-#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 23
-#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 24
-#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 25
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 26
-#define ED_CHECKBUTTON_ID_CHANGE_DELAY 27
-#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 28
-#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 29
-#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 30
-#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 31
-#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 32
-#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 33
-
-#define ED_NUM_CHECKBUTTONS 34
+#define ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE 6
+#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 7
+#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 8
+#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 9
+#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 10
+#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 11
+#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 12
+#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 13
+#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 14
+#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 15
+#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 16
+#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 17
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 18
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 19
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 20
+#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 21
+#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 22
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_RESULT 23
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 24
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 25
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 26
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 27
+#define ED_CHECKBUTTON_ID_CHANGE_DELAY 28
+#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 29
+#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 30
+#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 31
+#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 32
+#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 33
+#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 34
+
+#define ED_NUM_CHECKBUTTONS 35
#define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_DOUBLE_SPEED
#define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED
NULL,
"use spring pushing bug", "use odd spring pushing behaviour"
},
+ {
+ ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(0),
+ GADGET_ID_GROW_INTO_DIGGABLE, GADGET_ID_NONE,
+ &level.grow_into_diggable,
+ NULL,
+ "can grow into anything diggable", "grow into more than just sand"
+ },
{
ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(1),
GADGET_ID_BLOCK_LAST_FIELD, GADGET_ID_NONE,
/* ---------- amoeba content --------------------------------------------- */
{
- ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(2),
+ ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(3),
1, 1,
GADGET_ID_AMOEBA_CONTENT, GADGET_ID_NONE,
"content:", NULL, NULL
int x_right = gi->x + gi->width + xoffset_right;
int y; /* set after gadget position was modified */
- /* set position for "stickybutton" and "can move into acid" gadgets */
- if (id == ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID)
- ModifyGadget(gi, GDI_Y, SY + checkbutton_info[id].y, GDI_END);
+ /* set position for gadgets with dynamically determined vertical position */
+ ModifyGadget(gi, GDI_Y, SY + checkbutton_info[id].y, GDI_END);
y = gi->y + yoffset;
IS_ENVELOPE(element) ||
ELEM_IS_PLAYER(element) ||
HAS_CONTENT(element) ||
+ CAN_GROW(element) ||
COULD_MOVE_INTO_ACID(element) ||
MAYBE_DONT_COLLIDE_WITH(element))
return TRUE;
counterbutton_info[counter_id].y =
ED_SETTINGS_YPOS((HAS_CONTENT(properties_element) ? 1 : 0) +
- (MAYBE_DONT_COLLIDE_WITH(properties_element) ? 1 : 0)+
- (COULD_MOVE_INTO_ACID(properties_element) ? 1 : 0));
+ (CAN_GROW(properties_element) ? 1 : 0) +
+ (COULD_MOVE_INTO_ACID(properties_element) ? 1 : 0) +
+ (MAYBE_DONT_COLLIDE_WITH(properties_element) ? 1 :0));
counterbutton_info[counter_id].value = elements_with_counter[i].value;
counterbutton_info[counter_id].text_right= elements_with_counter[i].text;
(!IS_CUSTOM_ELEMENT(properties_element) ||
edit_mode_properties == ED_MODE_PROPERTIES_CONFIG_2))
{
- /* set position for special checkbutton for "can move into acid" */
+ /* set position for checkbutton for "can move into acid" */
checkbutton_info[ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID].y =
ED_SETTINGS_YPOS(IS_CUSTOM_ELEMENT(properties_element) ? 6 :
HAS_CONTENT(properties_element) ? 1 : 0);
if (properties_element == EL_SPRING)
MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_SPRING_BUG);
+ if (CAN_GROW(properties_element))
+ {
+ checkbutton_info[ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE].y =
+ ED_SETTINGS_YPOS(HAS_CONTENT(properties_element) ? 1 : 0);
+
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE);
+ }
+
if (IS_ENVELOPE(properties_element))
{
int counter1_id = ED_COUNTER_ID_ENVELOPE_XSIZE;
#define CHUNK_SIZE_NONE -1 /* do not write chunk size */
#define FILE_VERS_CHUNK_SIZE 8 /* size of file version chunk */
#define LEVEL_HEADER_SIZE 80 /* size of level file header */
-#define LEVEL_HEADER_UNUSED 2 /* unused level header bytes */
+#define LEVEL_HEADER_UNUSED 1 /* unused level header bytes */
#define LEVEL_CHUNK_CNT2_SIZE 160 /* size of level CNT2 chunk */
#define LEVEL_CHUNK_CNT2_UNUSED 11 /* unused CNT2 chunk bytes */
#define LEVEL_CHUNK_CNT3_HEADER 16 /* size of level CNT3 header */
level->sp_block_last_field = TRUE;
level->instant_relocation = FALSE;
level->can_pass_to_walkable = FALSE;
+ level->grow_into_diggable = TRUE;
level->can_move_into_acid_bits = ~0; /* everything can move into acid */
level->dont_collide_with_bits = ~0; /* always deadly when colliding */
level->instant_relocation = (getFile8Bit(file) == 1 ? TRUE : FALSE);
level->can_pass_to_walkable = (getFile8Bit(file) == 1 ? TRUE : FALSE);
+ level->grow_into_diggable = (getFile8Bit(file) == 1 ? TRUE : FALSE);
ReadUnusedBytesFromFile(file, LEVEL_HEADER_UNUSED);
putFile8Bit(file, (level->instant_relocation ? 1 : 0));
putFile8Bit(file, (level->can_pass_to_walkable ? 1 : 0));
+ putFile8Bit(file, (level->grow_into_diggable ? 1 : 0));
WriteUnusedBytesToFile(file, LEVEL_HEADER_UNUSED);
}
((e) == EL_TRIGGER_ELEMENT ? (ch)->actual_trigger_element : \
(e) == EL_TRIGGER_PLAYER ? (ch)->actual_trigger_player : (e))
+#define CAN_GROW_INTO(e) \
+ (e == EL_SAND || (IS_DIGGABLE(e) && level.grow_into_diggable))
+
#define ELEMENT_CAN_ENTER_FIELD_BASE_X(x, y, condition) \
(IN_LEV_FIELD(x, y) && (IS_FREE(x, y) || \
(condition)))
/* this case is in fact a combination of not less than three bugs:
first, it calls InitMovDir() for elements that can move, although this is
already done by InitField(); then, it checks the element that was at this
- field _before_ the call to InitField() (which can change it)
-
- */
+ field _before_ the call to InitField() (which can change it); lastly, it
+ was not called for "mole with direction" elements, which were treated as
+ "cannot move" due to (fixed) wrong element initialization in "src/init.c"
+ */
}
inline void DrawGameValue_Emeralds(int value)
Explode(x, y, EX_PHASE_START, EX_TYPE_BORDER);
+#if 1
+ if (element != EL_EMPTY && element != EL_EXPLOSION &&
+ !CAN_GROW_INTO(element) && !dynabomb_xl)
+ break;
+#else
/* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
- if (element != EL_EMPTY &&
- element != EL_SAND &&
- element != EL_EXPLOSION &&
- !dynabomb_xl)
+ if (element != EL_EMPTY && element != EL_EXPLOSION &&
+ element != EL_SAND && !dynabomb_xl)
break;
+#endif
}
}
}
if (!IN_LEV_FIELD(x, y))
return;
+#if 1
+ if (IS_FREE(x, y) ||
+ CAN_GROW_INTO(Feld[x][y]) ||
+ Feld[x][y] == EL_QUICKSAND_EMPTY)
+ {
+ newax = x;
+ neway = y;
+ }
+#else
/* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
if (IS_FREE(x, y) ||
Feld[x][y] == EL_SAND || Feld[x][y] == EL_QUICKSAND_EMPTY)
newax = x;
neway = y;
}
+#endif
if (newax == ax && neway == ay)
return;
if (!IN_LEV_FIELD(x, y))
continue;
+#if 1
+ if (IS_FREE(x, y) ||
+ CAN_GROW_INTO(Feld[x][y]) ||
+ Feld[x][y] == EL_QUICKSAND_EMPTY)
+ {
+ newax = x;
+ neway = y;
+ break;
+ }
+#else
/* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
if (IS_FREE(x, y) ||
Feld[x][y] == EL_SAND || Feld[x][y] == EL_QUICKSAND_EMPTY)
neway = y;
break;
}
+#endif
else if (IS_PLAYER(x, y))
waiting_for_player = TRUE;
}
changed = TRUE;
}
}
+#if 1
+ else if (IS_FREE(xx, yy) || CAN_GROW_INTO(Feld[xx][yy]))
+ { /* free border field */
+ if (nachbarn >= life[2] && nachbarn <= life[3])
+ {
+ Feld[xx][yy] = element;
+ MovDelay[xx][yy] = (element == EL_GAME_OF_LIFE ? 0 : life_time-1);
+ if (!Stop[xx][yy])
+ DrawLevelField(xx, yy);
+ Stop[xx][yy] = TRUE;
+ changed = TRUE;
+ }
+ }
+#else
/* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
else if (IS_FREE(xx, yy) || Feld[xx][yy] == EL_SAND)
{ /* free border field */
changed = TRUE;
}
}
+#endif
}
if (changed)
#endif
element = Feld[x][y];
+#if 1
+ if (!IS_PLAYER(x,y) &&
+ (element == EL_EMPTY ||
+ CAN_GROW_INTO(element) ||
+ element == EL_QUICKSAND_EMPTY ||
+ 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) ||
+ (IN_LEV_FIELD(x+1, y) && Feld[x+1][y] == EL_AMOEBA_WET) ||
+ (IN_LEV_FIELD(x, y+1) && Feld[x][y+1] == EL_AMOEBA_WET))
+ Feld[x][y] = EL_AMOEBA_DROP;
+ }
+#else
/* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
if (!IS_PLAYER(x,y) &&
(element == EL_EMPTY ||
(IN_LEV_FIELD(x, y+1) && Feld[x][y+1] == EL_AMOEBA_WET))
Feld[x][y] = EL_AMOEBA_DROP;
}
+#endif
random = random * 129 + 1;
}
int move_dir_horizontal = player->action & MV_HORIZONTAL;
int move_dir_vertical = player->action & MV_VERTICAL;
#endif
+
#if 1
boolean player_is_snapping = player->effective_action & JOY_BUTTON_1;
#else
(IN_LEV_FIELD(jx, jy + 1) &&
(IS_FREE(jx, jy + 1)));
#endif
+
#if 0
boolean player_is_moving_to_valid_field =
(
return MF_NO_ACTION; /* player cannot walk here due to gravity */
#endif
- if (element >= EL_GATE_1 && element <= EL_GATE_4)
+ if (IS_GATE(element))
{
if (!player->key[element - EL_GATE_1])
return MF_NO_ACTION;
}
- else if (element >= EL_GATE_1_GRAY && element <= EL_GATE_4_GRAY)
+ else if (IS_GATE_GRAY(element))
{
if (!player->key[element - EL_GATE_1_GRAY])
return MF_NO_ACTION;
Changed[jx][jy] = 0; /* allow another change */
#endif
+#if 1
+ /* !!! TEST ONLY !!! */
+ CheckElementChangePlayer(jx, jy, new_element, CE_DROPPED_BY_PLAYER,
+ player->index_bit, drop_side);
+ CheckTriggeredElementChangePlayer(jx, jy, new_element,
+ CE_OTHER_GETS_DROPPED,
+ player->index_bit, drop_side);
+#else
CheckTriggeredElementChangePlayer(jx, jy, new_element,
CE_OTHER_GETS_DROPPED,
player->index_bit, drop_side);
CheckElementChangePlayer(jx, jy, new_element, CE_DROPPED_BY_PLAYER,
player->index_bit, drop_side);
+#endif
TestIfElementTouchesCustomElement(jx, jy);
}
{ EL_PLAYER_3, 0 },
{ EL_PLAYER_4, 0 },
{ EL_SP_MURPHY, 0 },
+ { EL_SOKOBAN_FIELD_PLAYER, 0 },
/* all element that can move may be able to also move into acid */
{ EL_BUG, 1 },
EL_INVISIBLE_SAND_ACTIVE,
/* !!! currently not diggable, but handled by 'ep_dont_run_into' !!! */
+ /* (if amoeba can grow into anything diggable, maybe keep these out) */
#if 0
EL_LANDMINE,
EL_TRAP_ACTIVE,
EL_PLAYER_3,
EL_PLAYER_4,
EL_SP_MURPHY,
+ EL_SOKOBAN_FIELD_PLAYER,
-1
};
EL_EXIT_OPEN,
EL_STEELWALL,
EL_PLAYER_1,
+ EL_PLAYER_2,
+ EL_PLAYER_3,
+ EL_PLAYER_4,
EL_BD_FIREFLY,
EL_BD_FIREFLY_1,
EL_BD_FIREFLY_2,
EL_SOKOBAN_OBJECT,
EL_SOKOBAN_FIELD_EMPTY,
EL_SOKOBAN_FIELD_FULL,
+ EL_SOKOBAN_FIELD_PLAYER,
EL_PLAYER_1,
+ EL_PLAYER_2,
+ EL_PLAYER_3,
+ EL_PLAYER_4,
EL_INVISIBLE_STEELWALL,
-1
};
-1
};
+ static int ep_can_grow[] =
+ {
+ EL_BD_AMOEBA,
+ EL_AMOEBA_DROP,
+ EL_AMOEBA_WET,
+ EL_AMOEBA_DRY,
+ EL_AMOEBA_FULL,
+ EL_GAME_OF_LIFE,
+ EL_BIOMAZE,
+ -1
+ };
+
static int ep_active_bomb[] =
{
EL_DYNAMITE_ACTIVE,
{ ep_amoebalive, EP_AMOEBALIVE },
{ ep_has_content, EP_HAS_CONTENT },
{ ep_can_turn_each_move, EP_CAN_TURN_EACH_MOVE },
+ { ep_can_grow, EP_CAN_GROW },
{ ep_active_bomb, EP_ACTIVE_BOMB },
{ ep_inactive, EP_INACTIVE },
#define EP_AMOEBALIVE 51
#define EP_HAS_CONTENT 52
#define EP_CAN_TURN_EACH_MOVE 53
-#define EP_ACTIVE_BOMB 54
-#define EP_INACTIVE 55
+#define EP_CAN_GROW 54
+#define EP_ACTIVE_BOMB 55
+#define EP_INACTIVE 56
/* values for special configurable properties (depending on level settings) */
-#define EP_EM_SLIPPERY_WALL 56
+#define EP_EM_SLIPPERY_WALL 57
/* values for special graphics properties (no effect on game engine) */
-#define EP_GFX_CRUMBLED 57
+#define EP_GFX_CRUMBLED 58
/* values for derived properties (determined from properties above) */
-#define EP_ACCESSIBLE_OVER 58
-#define EP_ACCESSIBLE_INSIDE 59
-#define EP_ACCESSIBLE_UNDER 60
-#define EP_WALKABLE 61
-#define EP_PASSABLE 62
-#define EP_ACCESSIBLE 63
-#define EP_COLLECTIBLE 64
-#define EP_SNAPPABLE 65
-#define EP_WALL 66
-#define EP_SOLID_FOR_PUSHING 67
-#define EP_DRAGONFIRE_PROOF 68
-#define EP_EXPLOSION_PROOF 69
-#define EP_CAN_SMASH 70
-#define EP_CAN_EXPLODE 71
-#define EP_CAN_EXPLODE_3X3 72
-#define EP_SP_PORT 73
-#define EP_CAN_EXPLODE_BY_DRAGONFIRE 74
-#define EP_CAN_EXPLODE_BY_EXPLOSION 75
-#define EP_COULD_MOVE_INTO_ACID 76
-#define EP_MAYBE_DONT_COLLIDE_WITH 77
+#define EP_ACCESSIBLE_OVER 59
+#define EP_ACCESSIBLE_INSIDE 60
+#define EP_ACCESSIBLE_UNDER 61
+#define EP_WALKABLE 62
+#define EP_PASSABLE 63
+#define EP_ACCESSIBLE 64
+#define EP_COLLECTIBLE 65
+#define EP_SNAPPABLE 66
+#define EP_WALL 67
+#define EP_SOLID_FOR_PUSHING 68
+#define EP_DRAGONFIRE_PROOF 69
+#define EP_EXPLOSION_PROOF 70
+#define EP_CAN_SMASH 71
+#define EP_CAN_EXPLODE 72
+#define EP_CAN_EXPLODE_3X3 73
+#define EP_SP_PORT 74
+#define EP_CAN_EXPLODE_BY_DRAGONFIRE 75
+#define EP_CAN_EXPLODE_BY_EXPLOSION 76
+#define EP_COULD_MOVE_INTO_ACID 77
+#define EP_MAYBE_DONT_COLLIDE_WITH 78
/* values for internal purpose only (level editor) */
-#define EP_EXPLODE_RESULT 78
-#define EP_WALK_TO_OBJECT 79
-#define EP_DEADLY 80
+#define EP_EXPLODE_RESULT 79
+#define EP_WALK_TO_OBJECT 80
+#define EP_DEADLY 81
-#define NUM_ELEMENT_PROPERTIES 81
+#define NUM_ELEMENT_PROPERTIES 82
#define NUM_EP_BITFIELDS ((NUM_ELEMENT_PROPERTIES + 31) / 32)
#define EP_BITFIELD_BASE 0
#define IS_AMOEBALIVE(e) HAS_PROPERTY(e, EP_AMOEBALIVE)
#define HAS_CONTENT(e) HAS_PROPERTY(e, EP_HAS_CONTENT)
#define CAN_TURN_EACH_MOVE(e) HAS_PROPERTY(e, EP_CAN_TURN_EACH_MOVE)
+#define CAN_GROW(e) HAS_PROPERTY(e, EP_CAN_GROW)
#define IS_ACTIVE_BOMB(e) HAS_PROPERTY(e, EP_ACTIVE_BOMB)
#define IS_INACTIVE(e) HAS_PROPERTY(e, EP_INACTIVE)
#define IS_ENVELOPE(e) ((e) >= EL_ENVELOPE_1 && \
(e) <= EL_ENVELOPE_4)
+#define IS_GATE(e) ((e) >= EL_GATE_1 && \
+ (e) <= EL_GATE_4)
+
+#define IS_GATE_GRAY(e) ((e) >= EL_GATE_1_GRAY && \
+ (e) <= EL_GATE_4_GRAY)
+
#define IS_EM_GATE(e) ((e) >= EL_EM_GATE_1 && \
(e) <= EL_EM_GATE_4)
boolean use_spring_bug; /* for compatibility with old levels */
boolean instant_relocation; /* no visual delay when relocating player */
boolean can_pass_to_walkable; /* player can pass to empty or walkable tile */
+ boolean grow_into_diggable; /* amoeba can grow into anything diggable */
/* ('int' instead of 'boolean' because used as selectbox value in editor) */
int use_step_counter; /* count steps instead of seconds for level */