From: Holger Schemel Date: Fri, 26 Mar 2004 09:45:37 +0000 (+0100) Subject: rnd-20040326-1-src X-Git-Tag: 3.1.0^2~33 X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=commitdiff_plain;h=f5665efaa42ea2570819237740046ff1360c4ef6 rnd-20040326-1-src * added option to make growing elements grow into anything diggable (for the various amoeba types, biomaze and "game of life") --- diff --git a/ChangeLog b/ChangeLog index dcea920b..f9d9f79e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ +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 diff --git a/src/conftime.h b/src/conftime.h index 999c4b9f..e0478752 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2004-03-25 03:08]" +#define COMPILE_DATE_STRING "[2004-03-26 10:44]" diff --git a/src/editor.c b/src/editor.c index 97904719..98b8375c 100644 --- a/src/editor.c +++ b/src/editor.c @@ -499,37 +499,38 @@ #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) @@ -699,36 +700,37 @@ #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 @@ -1961,6 +1963,13 @@ static struct 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, @@ -2219,7 +2228,7 @@ static struct /* ---------- 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 @@ -5319,9 +5328,8 @@ static void MapCheckbuttonGadget(int id) 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; @@ -6945,6 +6953,7 @@ static boolean checkPropertiesConfig(int element) 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; @@ -6976,8 +6985,9 @@ static void DrawPropertiesConfig() 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; @@ -7017,7 +7027,7 @@ static void DrawPropertiesConfig() (!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); @@ -7031,6 +7041,14 @@ static void DrawPropertiesConfig() 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; diff --git a/src/files.c b/src/files.c index f44c2ca3..c07a04c5 100644 --- a/src/files.c +++ b/src/files.c @@ -29,7 +29,7 @@ #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 */ @@ -163,6 +163,7 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) 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 */ @@ -705,6 +706,7 @@ static int LoadLevel_HEAD(FILE *file, int chunk_size, struct LevelInfo *level) 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); @@ -2444,6 +2446,7 @@ static void SaveLevel_HEAD(FILE *file, struct LevelInfo *level) 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); } diff --git a/src/game.c b/src/game.c index 05460294..b1254556 100644 --- a/src/game.c +++ b/src/game.c @@ -111,6 +111,9 @@ ((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))) @@ -996,9 +999,10 @@ static inline void InitField_WithBug2(int x, int y, boolean init_game) /* 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) @@ -3416,12 +3420,16 @@ void DynaExplode(int ex, int ey) 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 } } } @@ -6449,6 +6457,15 @@ void AmoebeAbleger(int ax, int ay) 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) @@ -6456,6 +6473,7 @@ void AmoebeAbleger(int ax, int ay) newax = x; neway = y; } +#endif if (newax == ax && neway == ay) return; @@ -6474,6 +6492,16 @@ void AmoebeAbleger(int ax, int ay) 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) @@ -6482,6 +6510,7 @@ void AmoebeAbleger(int ax, int ay) neway = y; break; } +#endif else if (IS_PLAYER(x, y)) waiting_for_player = TRUE; } @@ -6619,6 +6648,20 @@ void Life(int ax, int ay) 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 */ @@ -6632,6 +6675,7 @@ void Life(int ax, int ay) changed = TRUE; } } +#endif } if (changed) @@ -8315,6 +8359,21 @@ void GameActions() #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 || @@ -8329,6 +8388,7 @@ void GameActions() (IN_LEV_FIELD(x, y+1) && Feld[x][y+1] == EL_AMOEBA_WET)) Feld[x][y] = EL_AMOEBA_DROP; } +#endif random = random * 129 + 1; } @@ -8702,6 +8762,7 @@ static void CheckGravityMovement(struct PlayerInfo *player) 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 @@ -8746,6 +8807,7 @@ static void CheckGravityMovement(struct PlayerInfo *player) (IN_LEV_FIELD(jx, jy + 1) && (IS_FREE(jx, jy + 1))); #endif + #if 0 boolean player_is_moving_to_valid_field = ( @@ -10380,12 +10442,12 @@ int DigField(struct PlayerInfo *player, 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; @@ -11050,11 +11112,20 @@ boolean DropElement(struct PlayerInfo *player) 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); } diff --git a/src/init.c b/src/init.c index 3b04676d..715a57fd 100644 --- a/src/init.c +++ b/src/init.c @@ -1585,6 +1585,7 @@ static int get_special_property_bit(int element, int property_bit_nr) { 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 }, @@ -1733,6 +1734,7 @@ void InitElementPropertiesStatic() 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, @@ -2261,6 +2263,7 @@ void InitElementPropertiesStatic() EL_PLAYER_3, EL_PLAYER_4, EL_SP_MURPHY, + EL_SOKOBAN_FIELD_PLAYER, -1 }; @@ -2322,6 +2325,9 @@ void InitElementPropertiesStatic() 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, @@ -2405,7 +2411,11 @@ void InitElementPropertiesStatic() 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 }; @@ -2836,6 +2846,18 @@ void InitElementPropertiesStatic() -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, @@ -3057,6 +3079,7 @@ void InitElementPropertiesStatic() { 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 }, diff --git a/src/main.h b/src/main.h index c58dbfbe..b125603a 100644 --- a/src/main.h +++ b/src/main.h @@ -113,43 +113,44 @@ #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 @@ -358,6 +359,7 @@ #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) @@ -401,6 +403,12 @@ #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) @@ -1461,6 +1469,7 @@ struct LevelInfo 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 */