X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Finit.c;h=ed480b14b4aca78fbb7eb8b797988e0941b57724;hb=b876f418a4aaf55280b4b5da38c175997be01360;hp=853588131e640718f8e6a5a81f073f7505d4367b;hpb=1c636a51bb573815d24a27dcc20b3283d89d1b8b;p=rocksndiamonds.git diff --git a/src/init.c b/src/init.c index 85358813..ed480b14 100644 --- a/src/init.c +++ b/src/init.c @@ -1569,6 +1569,94 @@ static void ReinitializeMusic() InitGameModeMusicInfo(); /* game mode music mapping */ } +static int get_special_property_bit(int element, int base_property_bit) +{ + static struct + { + int element; + int bit_nr; + } pb_can_move_into_acid[] = + { + /* all element that can move */ + { 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 }, + { EL_SPRING, 10 }, + + { -1, -1 }, + }; + 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; +} + +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 &= ~(1 << bit_nr); + + if (set) + level->can_move_into_acid |= (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 & (1 << bit_nr)) != 0); + + return FALSE; +} + void InitElementPropertiesStatic() { static int ep_diggable[] = @@ -1826,6 +1914,7 @@ void InitElementPropertiesStatic() static int ep_can_move[] = { + /* same elements as in 'pb_can_move_into_acid' */ EL_BUG, EL_SPACESHIP, EL_BD_BUTTERFLY, @@ -1945,6 +2034,9 @@ void InitElementPropertiesStatic() EL_SP_DISK_YELLOW, EL_SP_SNIKSNAK, EL_SP_ELECTRON, +#if 0 + EL_BLACK_ORB, +#endif -1 }; @@ -2086,6 +2178,16 @@ void InitElementPropertiesStatic() static int ep_protected[] = { + EL_EM_GATE_1, + EL_EM_GATE_2, + EL_EM_GATE_3, + EL_EM_GATE_4, + EL_EM_GATE_1_GRAY, + EL_EM_GATE_2_GRAY, + EL_EM_GATE_3_GRAY, + EL_EM_GATE_4_GRAY, + EL_SWITCHGATE_OPEN, + EL_TIMEGATE_OPEN, -1 }; @@ -2922,6 +3024,11 @@ void InitElementPropertiesStatic() EL_PACMAN_LEFT, EL_PACMAN_RIGHT, EL_PACMAN_UP, EL_PACMAN_DOWN }, + { + EL_MOLE, + EL_MOLE_LEFT, EL_MOLE_RIGHT, + EL_MOLE_UP, EL_MOLE_DOWN + }, { -1, -1, -1, -1, -1 @@ -3008,6 +3115,7 @@ void InitElementPropertiesEngine(int engine_version) EP_ACTIVE_BOMB, EP_ACCESSIBLE, + -1 }; @@ -3017,6 +3125,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++) { @@ -3026,8 +3140,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) || @@ -3079,6 +3192,12 @@ 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 ----------------------------------------- */ if (IS_HISTORIC_SOLID(i) || i == EL_EXPLOSION) @@ -3087,21 +3206,31 @@ void InitElementPropertiesEngine(int engine_version) SET_PROPERTY(i, EP_DRAGONFIRE_PROOF, (IS_CUSTOM_ELEMENT(i) && IS_INDESTRUCTIBLE(i))); - /* ---------- PROTECTED ------------------------------------------------ */ - if (IS_ACCESSIBLE_INSIDE(i)) - SET_PROPERTY(i, EP_PROTECTED, TRUE); - /* ---------- EXPLOSION_PROOF ------------------------------------------ */ if (i == EL_FLAMES) SET_PROPERTY(i, EP_EXPLOSION_PROOF, TRUE); else if (engine_version < VERSION_IDENT(2,2,0,0)) SET_PROPERTY(i, EP_EXPLOSION_PROOF, IS_INDESTRUCTIBLE(i)); else +#if 1 + SET_PROPERTY(i, EP_EXPLOSION_PROOF, (IS_INDESTRUCTIBLE(i) && + (!IS_WALKABLE(i) || + IS_PROTECTED(i)))); +#else +#if 1 + SET_PROPERTY(i, EP_EXPLOSION_PROOF, (IS_INDESTRUCTIBLE(i) && + !IS_WALKABLE_OVER(i) && + !IS_WALKABLE_UNDER(i))); +#else SET_PROPERTY(i, EP_EXPLOSION_PROOF, (IS_INDESTRUCTIBLE(i) && IS_PROTECTED(i))); +#endif +#endif 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); @@ -3130,6 +3259,21 @@ void InitElementPropertiesEngine(int engine_version) !CAN_EXPLODE_1X1(i) && !CAN_EXPLODE_DYNA(i))); + /* ---------- CAN_EXPLODE_BY_DRAGONFIRE -------------------------------- */ + SET_PROPERTY(i, EP_CAN_EXPLODE_BY_DRAGONFIRE, CAN_EXPLODE_BY_FIRE(i)); + + /* ---------- CAN_EXPLODE_BY_EXPLOSION --------------------------------- */ + SET_PROPERTY(i, EP_CAN_EXPLODE_BY_EXPLOSION, (CAN_EXPLODE_BY_FIRE(i) || + i == EL_BLACK_ORB)); + + /* ---------- COULD_MOVE_INTO_ACID ------------------------------------- */ + SET_PROPERTY(i, EP_COULD_MOVE_INTO_ACID, (CAN_MOVE(i) || + IS_CUSTOM_ELEMENT(i))); + + /* ---------- CAN_MOVE_INTO_ACID --------------------------------------- */ + if (!IS_CUSTOM_ELEMENT(i)) + SET_PROPERTY(i, EP_CAN_MOVE_INTO_ACID,getMoveIntoAcidProperty(&level,i)); + /* ---------- SP_PORT -------------------------------------------------- */ SET_PROPERTY(i, EP_SP_PORT, (IS_SP_ELEMENT(i) && IS_PASSABLE_INSIDE(i))); @@ -3220,6 +3364,20 @@ void InitElementPropertiesEngine(int engine_version) if (element_info[element].push_delay_random == -1) element_info[element].push_delay_random = game.default_push_delay_random; } + + /* set some other uninitialized values of custom elements in older levels */ + if (engine_version < VERSION_IDENT(3,0,9,0)) + { + for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) + { + int element = EL_CUSTOM_START + i; + + element_info[element].access_direction = MV_ALL_DIRECTIONS; + + element_info[element].explosion_delay = 18; + element_info[element].ignition_delay = 8; + } + } #endif /* this is needed because some graphics depend on element properties */