X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Finit.c;h=6917ee0b1aabc04799fb382eff7feb95d0b7cdeb;hb=830ab4d58b00129ff57c9600dc99a2494af8841c;hp=e0d97ccab822c581e225aa93bba967f701084be4;hpb=7993378f9ae3ba83d8d420be8a7f5c81859e1750;p=rocksndiamonds.git diff --git a/src/init.c b/src/init.c index e0d97cca..6917ee0b 100644 --- a/src/init.c +++ b/src/init.c @@ -1569,6 +1569,157 @@ static void ReinitializeMusic() InitGameModeMusicInfo(); /* game mode music mapping */ } +static int get_special_property_bit(int element, int property_bit_nr) +{ + struct PropertyBitInfo + { + int element; + int bit_nr; + }; + + static struct PropertyBitInfo pb_can_move_into_acid[] = + { + /* the player may be able fall into acid when gravity is activated */ + { EL_PLAYER_1, 0 }, + { EL_PLAYER_2, 0 }, + { EL_PLAYER_3, 0 }, + { EL_PLAYER_4, 0 }, + { EL_SP_MURPHY, 0 }, + + /* all element that can move may be able to also move into acid */ + { EL_BUG, 1 }, + { EL_BUG_LEFT, 1 }, + { EL_BUG_RIGHT, 1 }, + { EL_BUG_UP, 1 }, + { EL_BUG_DOWN, 1 }, + { EL_SPACESHIP, 2 }, + { EL_SPACESHIP_LEFT, 2 }, + { EL_SPACESHIP_RIGHT, 2 }, + { EL_SPACESHIP_UP, 2 }, + { EL_SPACESHIP_DOWN, 2 }, + { EL_BD_BUTTERFLY, 3 }, + { EL_BD_BUTTERFLY_LEFT, 3 }, + { EL_BD_BUTTERFLY_RIGHT, 3 }, + { EL_BD_BUTTERFLY_UP, 3 }, + { EL_BD_BUTTERFLY_DOWN, 3 }, + { EL_BD_FIREFLY, 4 }, + { EL_BD_FIREFLY_LEFT, 4 }, + { EL_BD_FIREFLY_RIGHT, 4 }, + { EL_BD_FIREFLY_UP, 4 }, + { EL_BD_FIREFLY_DOWN, 4 }, + { EL_YAMYAM, 5 }, + { EL_DARK_YAMYAM, 6 }, + { EL_ROBOT, 7 }, + { EL_PACMAN, 8 }, + { EL_PACMAN_LEFT, 8 }, + { EL_PACMAN_RIGHT, 8 }, + { EL_PACMAN_UP, 8 }, + { EL_PACMAN_DOWN, 8 }, + { EL_MOLE, 9 }, + { EL_MOLE_LEFT, 9 }, + { EL_MOLE_RIGHT, 9 }, + { EL_MOLE_UP, 9 }, + { EL_MOLE_DOWN, 9 }, + { EL_PENGUIN, 10 }, + { EL_PIG, 11 }, + { EL_DRAGON, 12 }, + { EL_SATELLITE, 13 }, + { EL_SP_SNIKSNAK, 14 }, + { EL_SP_ELECTRON, 15 }, + { EL_BALLOON, 16 }, + { EL_SPRING, 17 }, + + { -1, -1 }, + }; + + static struct PropertyBitInfo pb_dont_collide_with[] = + { + { EL_SP_SNIKSNAK, 0 }, + { EL_SP_ELECTRON, 1 }, + + { -1, -1 }, + }; + + static struct + { + int bit_nr; + struct PropertyBitInfo *pb_info; + } pb_definition[] = + { + { EP_CAN_MOVE_INTO_ACID, pb_can_move_into_acid }, + { EP_DONT_COLLIDE_WITH, pb_dont_collide_with }, + + { -1, NULL }, + }; + + struct PropertyBitInfo *pb_info = NULL; + int i; + + for (i = 0; pb_definition[i].bit_nr != -1; i++) + if (pb_definition[i].bit_nr == property_bit_nr) + pb_info = pb_definition[i].pb_info; + + if (pb_info == NULL) + return -1; + + for (i = 0; pb_info[i].element != -1; i++) + if (pb_info[i].element == element) + return pb_info[i].bit_nr; + + return -1; +} + +#if 1 +void setBitfieldProperty(int *bitfield, int property_bit_nr, int element, + boolean property_value) +{ + int bit_nr = get_special_property_bit(element, property_bit_nr); + + if (bit_nr > -1) + { + if (property_value) + *bitfield |= (1 << bit_nr); + else + *bitfield &= ~(1 << bit_nr); + } +} + +boolean getBitfieldProperty(int *bitfield, int property_bit_nr, int element) +{ + int bit_nr = get_special_property_bit(element, property_bit_nr); + + if (bit_nr > -1) + return ((*bitfield & (1 << bit_nr)) != 0); + + return FALSE; +} + +#else + +void setMoveIntoAcidProperty(struct LevelInfo *level, int element, boolean set) +{ + int bit_nr = get_special_property_bit(element, EP_CAN_MOVE_INTO_ACID); + + if (bit_nr > -1) + { + level->can_move_into_acid_bits &= ~(1 << bit_nr); + + if (set) + level->can_move_into_acid_bits |= (1 << bit_nr); + } +} + +boolean getMoveIntoAcidProperty(struct LevelInfo *level, int element) +{ + int bit_nr = get_special_property_bit(element, EP_CAN_MOVE_INTO_ACID); + + if (bit_nr > -1) + return ((level->can_move_into_acid_bits & (1 << bit_nr)) != 0); + + return FALSE; +} +#endif + void InitElementPropertiesStatic() { static int ep_diggable[] = @@ -1826,6 +1977,7 @@ void InitElementPropertiesStatic() static int ep_can_move[] = { + /* same elements as in 'pb_can_move_into_acid' */ EL_BUG, EL_SPACESHIP, EL_BD_BUTTERFLY, @@ -2082,7 +2234,7 @@ void InitElementPropertiesStatic() -1 }; - static int ep_can_explode_dyna[] = + static int ep_can_explode_cross[] = { -1 }; @@ -2678,6 +2830,12 @@ void InitElementPropertiesStatic() -1 }; + static int ep_can_turn_each_move[] = + { + /* !!! do something !!! */ + -1 + }; + static int ep_active_bomb[] = { EL_DYNAMITE_ACTIVE, @@ -2874,7 +3032,7 @@ void InitElementPropertiesStatic() { ep_droppable, EP_DROPPABLE }, { ep_can_explode_1x1, EP_CAN_EXPLODE_1X1 }, { ep_pushable, EP_PUSHABLE }, - { ep_can_explode_dyna, EP_CAN_EXPLODE_DYNA }, + { ep_can_explode_cross, EP_CAN_EXPLODE_CROSS }, { ep_protected, EP_PROTECTED }, { ep_player, EP_PLAYER }, @@ -2898,6 +3056,7 @@ void InitElementPropertiesStatic() { ep_amoeboid, EP_AMOEBOID }, { ep_amoebalive, EP_AMOEBALIVE }, { ep_has_content, EP_HAS_CONTENT }, + { ep_can_turn_each_move, EP_CAN_TURN_EACH_MOVE }, { ep_active_bomb, EP_ACTIVE_BOMB }, { ep_inactive, EP_INACTIVE }, @@ -2935,13 +3094,11 @@ void InitElementPropertiesStatic() EL_PACMAN_LEFT, EL_PACMAN_RIGHT, EL_PACMAN_UP, EL_PACMAN_DOWN }, -#if 1 { EL_MOLE, EL_MOLE_LEFT, EL_MOLE_RIGHT, EL_MOLE_UP, EL_MOLE_DOWN }, -#endif { -1, -1, -1, -1, -1 @@ -3038,6 +3195,12 @@ void InitElementPropertiesEngine(int engine_version) InitElementPropertiesStatic(); #endif + /* important: after initialization in InitElementPropertiesStatic(), the + elements are not again initialized to a default value; therefore all + changes have to make sure that they leave the element with a defined + property (which means that conditional property changes must be set to + a reliable default value before) */ + /* set all special, combined or engine dependent element properties */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) { @@ -3047,8 +3210,7 @@ void InitElementPropertiesEngine(int engine_version) #endif /* ---------- INACTIVE ------------------------------------------------- */ - if (i >= EL_CHAR_START && i <= EL_CHAR_END) - SET_PROPERTY(i, EP_INACTIVE, TRUE); + SET_PROPERTY(i, EP_INACTIVE, (i >= EL_CHAR_START && i <= EL_CHAR_END)); /* ---------- WALKABLE, PASSABLE, ACCESSIBLE --------------------------- */ SET_PROPERTY(i, EP_WALKABLE, (IS_WALKABLE_OVER(i) || @@ -3100,9 +3262,11 @@ void InitElementPropertiesEngine(int engine_version) !IS_DIGGABLE(i) && !IS_COLLECTIBLE(i))); +#if 1 /* ---------- PROTECTED ------------------------------------------------ */ if (IS_ACCESSIBLE_INSIDE(i)) SET_PROPERTY(i, EP_PROTECTED, TRUE); +#endif /* ---------- DRAGONFIRE_PROOF ----------------------------------------- */ @@ -3135,6 +3299,8 @@ void InitElementPropertiesEngine(int engine_version) if (IS_CUSTOM_ELEMENT(i)) { + /* these are additional properties which are initially false when set */ + /* ---------- DONT_COLLIDE_WITH / DONT_RUN_INTO ---------------------- */ if (DONT_TOUCH(i)) SET_PROPERTY(i, EP_DONT_COLLIDE_WITH, TRUE); @@ -3161,7 +3327,7 @@ void InitElementPropertiesEngine(int engine_version) /* ---------- CAN_EXPLODE_3X3 ------------------------------------------ */ SET_PROPERTY(i, EP_CAN_EXPLODE_3X3, (CAN_EXPLODE(i) && !CAN_EXPLODE_1X1(i) && - !CAN_EXPLODE_DYNA(i))); + !CAN_EXPLODE_CROSS(i))); /* ---------- CAN_EXPLODE_BY_DRAGONFIRE -------------------------------- */ SET_PROPERTY(i, EP_CAN_EXPLODE_BY_DRAGONFIRE, CAN_EXPLODE_BY_FIRE(i)); @@ -3171,7 +3337,23 @@ void InitElementPropertiesEngine(int engine_version) i == EL_BLACK_ORB)); /* ---------- COULD_MOVE_INTO_ACID ------------------------------------- */ - SET_PROPERTY(i, EP_COULD_MOVE_INTO_ACID, (CAN_MOVE(i) && i != EL_SPRING)); + SET_PROPERTY(i, EP_COULD_MOVE_INTO_ACID, (ELEM_IS_PLAYER(i) || + CAN_MOVE(i) || + IS_CUSTOM_ELEMENT(i))); + + /* ---------- MAYBE_DONT_COLLIDE_WITH ---------------------------------- */ + SET_PROPERTY(i, EP_MAYBE_DONT_COLLIDE_WITH, (i == EL_SP_SNIKSNAK || + i == EL_SP_ELECTRON)); + + /* ---------- CAN_MOVE_INTO_ACID --------------------------------------- */ + if (COULD_MOVE_INTO_ACID(i) && !IS_CUSTOM_ELEMENT(i)) + SET_PROPERTY(i, EP_CAN_MOVE_INTO_ACID, + getMoveIntoAcidProperty(&level, i)); + + /* ---------- DONT_COLLIDE_WITH ---------------------------------------- */ + if (MAYBE_DONT_COLLIDE_WITH(i)) + SET_PROPERTY(i, EP_DONT_COLLIDE_WITH, + getDontCollideWithProperty(&level, i)); /* ---------- SP_PORT -------------------------------------------------- */ SET_PROPERTY(i, EP_SP_PORT, (IS_SP_ELEMENT(i) && @@ -3182,7 +3364,7 @@ void InitElementPropertiesEngine(int engine_version) printf("::: %d, %d, %d -> %d\n", CAN_EXPLODE_1X1(i), CAN_EXPLODE_3X3(i), - CAN_EXPLODE_DYNA(i), + CAN_EXPLODE_CROSS(i), CAN_EXPLODE(i)); #endif @@ -3265,7 +3447,7 @@ void InitElementPropertiesEngine(int engine_version) } /* set some other uninitialized values of custom elements in older levels */ - if (engine_version < VERSION_IDENT(3,0,9,0)) + if (engine_version < VERSION_IDENT(3,1,0,0)) { for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) { @@ -3273,10 +3455,20 @@ void InitElementPropertiesEngine(int engine_version) element_info[element].access_direction = MV_ALL_DIRECTIONS; - element_info[element].explosion_delay = 18; + element_info[element].explosion_delay = 17; element_info[element].ignition_delay = 8; } } + +#if 0 + /* set element properties that were handled incorrectly in older levels */ + if (engine_version < VERSION_IDENT(3,1,0,0)) + { + SET_PROPERTY(EL_SP_SNIKSNAK, EP_DONT_COLLIDE_WITH, FALSE); + SET_PROPERTY(EL_SP_ELECTRON, EP_DONT_COLLIDE_WITH, FALSE); + } +#endif + #endif /* this is needed because some graphics depend on element properties */ @@ -3284,69 +3476,6 @@ void InitElementPropertiesEngine(int engine_version) InitElementGraphicInfo(); } -int get_special_property_bit(int element, int base_property_bit) -{ - static struct - { - int element; - int bit_nr; - } pb_can_move_into_acid[] = - { - { EL_BUG, 0 }, - { EL_BUG_LEFT, 0 }, - { EL_BUG_RIGHT, 0 }, - { EL_BUG_UP, 0 }, - { EL_BUG_DOWN, 0 }, - { EL_SPACESHIP, 0 }, - { EL_SPACESHIP_LEFT, 0 }, - { EL_SPACESHIP_RIGHT, 0 }, - { EL_SPACESHIP_UP, 0 }, - { EL_SPACESHIP_DOWN, 0 }, - { EL_BD_BUTTERFLY, 1 }, - { EL_BD_BUTTERFLY_LEFT, 1 }, - { EL_BD_BUTTERFLY_RIGHT, 1 }, - { EL_BD_BUTTERFLY_UP, 1 }, - { EL_BD_BUTTERFLY_DOWN, 1 }, - { EL_BD_FIREFLY, 1 }, - { EL_BD_FIREFLY_LEFT, 1 }, - { EL_BD_FIREFLY_RIGHT, 1 }, - { EL_BD_FIREFLY_UP, 1 }, - { EL_BD_FIREFLY_DOWN, 1 }, - { EL_YAMYAM, 2 }, - { EL_DARK_YAMYAM, 2 }, - { EL_ROBOT, 3 }, - { EL_PACMAN, 4 }, - { EL_PACMAN_LEFT, 4 }, - { EL_PACMAN_RIGHT, 4 }, - { EL_PACMAN_UP, 4 }, - { EL_PACMAN_DOWN, 4 }, - { EL_MOLE, 4 }, - { EL_MOLE_LEFT, 4 }, - { EL_MOLE_RIGHT, 4 }, - { EL_MOLE_UP, 4 }, - { EL_MOLE_DOWN, 4 }, - { EL_PENGUIN, 5 }, - { EL_PIG, 6 }, - { EL_DRAGON, 6 }, - { EL_SATELLITE, 7 }, - { EL_SP_SNIKSNAK, 8 }, - { EL_SP_ELECTRON, 8 }, - { EL_BALLOON, 9 }, - - { -1, 0 }, - }; - int i; - - if (base_property_bit != EP_CAN_MOVE_INTO_ACID) - return -1; - - for (i = 0; pb_can_move_into_acid[i].element != -1; i++) - if (pb_can_move_into_acid[i].element == element) - return pb_can_move_into_acid[i].bit_nr; - - return -1; -} - static void InitGlobal() { global.autoplay_leveldir = NULL;