X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=33386d84ad1c9543b85798f4970e4473005db006;hb=914431754efb7c8c3321a68f8b828b471cf15e3c;hp=4b4a44cfee1868d6113e12a2b17c9f947db8499d;hpb=0838017832a108ba365ea0efb851fc8c4d5f3aa5;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 4b4a44cf..33386d84 100644 --- a/src/game.c +++ b/src/game.c @@ -133,76 +133,83 @@ #define GAME_CONTROL_LEVEL_NUMBER 0 #define GAME_CONTROL_GEMS 1 -#define GAME_CONTROL_INVENTORY 2 -#define GAME_CONTROL_KEY_1 3 -#define GAME_CONTROL_KEY_2 4 -#define GAME_CONTROL_KEY_3 5 -#define GAME_CONTROL_KEY_4 6 -#define GAME_CONTROL_KEY_5 7 -#define GAME_CONTROL_KEY_6 8 -#define GAME_CONTROL_KEY_7 9 -#define GAME_CONTROL_KEY_8 10 -#define GAME_CONTROL_KEY_WHITE 11 -#define GAME_CONTROL_KEY_WHITE_COUNT 12 -#define GAME_CONTROL_SCORE 13 -#define GAME_CONTROL_TIME 14 -#define GAME_CONTROL_TIME_HH 15 -#define GAME_CONTROL_TIME_MM 16 -#define GAME_CONTROL_TIME_SS 17 -#define GAME_CONTROL_DROP_NEXT_1 18 -#define GAME_CONTROL_DROP_NEXT_2 19 -#define GAME_CONTROL_DROP_NEXT_3 20 -#define GAME_CONTROL_DROP_NEXT_4 21 -#define GAME_CONTROL_DROP_NEXT_5 22 -#define GAME_CONTROL_DROP_NEXT_6 23 -#define GAME_CONTROL_DROP_NEXT_7 24 -#define GAME_CONTROL_DROP_NEXT_8 25 -#define GAME_CONTROL_SHIELD_NORMAL 26 -#define GAME_CONTROL_SHIELD_NORMAL_TIME 27 -#define GAME_CONTROL_SHIELD_DEADLY 28 -#define GAME_CONTROL_SHIELD_DEADLY_TIME 29 -#define GAME_CONTROL_EXIT 30 -#define GAME_CONTROL_EM_EXIT 31 -#define GAME_CONTROL_SP_EXIT 32 -#define GAME_CONTROL_STEEL_EXIT 33 -#define GAME_CONTROL_EM_STEEL_EXIT 34 -#define GAME_CONTROL_EMC_MAGIC_BALL 35 -#define GAME_CONTROL_EMC_MAGIC_BALL_SWITCH 36 -#define GAME_CONTROL_EMC_MAGIC_BALL_TIME 37 -#define GAME_CONTROL_LIGHT_SWITCH 38 -#define GAME_CONTROL_LIGHT_SWITCH_TIME 39 -#define GAME_CONTROL_TIMEGATE_SWITCH 40 -#define GAME_CONTROL_TIMEGATE_SWITCH_TIME 41 -#define GAME_CONTROL_SWITCHGATE_SWITCH 42 -#define GAME_CONTROL_EMC_LENSES 43 -#define GAME_CONTROL_EMC_LENSES_TIME 44 -#define GAME_CONTROL_EMC_MAGNIFIER 45 -#define GAME_CONTROL_EMC_MAGNIFIER_TIME 46 -#define GAME_CONTROL_BALLOON_SWITCH 47 -#define GAME_CONTROL_DYNABOMB_NUMBER 48 -#define GAME_CONTROL_DYNABOMB_SIZE 49 -#define GAME_CONTROL_DYNABOMB_POWER 50 -#define GAME_CONTROL_PENGUINS 51 -#define GAME_CONTROL_SOKOBAN_OBJECTS 52 -#define GAME_CONTROL_SOKOBAN_FIELDS 53 -#define GAME_CONTROL_ROBOT_WHEEL 54 -#define GAME_CONTROL_CONVEYOR_BELT_1 55 -#define GAME_CONTROL_CONVEYOR_BELT_1_SWITCH 56 -#define GAME_CONTROL_CONVEYOR_BELT_2 57 -#define GAME_CONTROL_CONVEYOR_BELT_2_SWITCH 58 -#define GAME_CONTROL_CONVEYOR_BELT_3 59 -#define GAME_CONTROL_CONVEYOR_BELT_3_SWITCH 60 -#define GAME_CONTROL_CONVEYOR_BELT_4 61 -#define GAME_CONTROL_CONVEYOR_BELT_4_SWITCH 62 -#define GAME_CONTROL_MAGIC_WALL 63 -#define GAME_CONTROL_MAGIC_WALL_TIME 64 -#define GAME_CONTROL_BD_MAGIC_WALL 65 -#define GAME_CONTROL_DC_MAGIC_WALL 66 -#define GAME_CONTROL_PLAYER_NAME 67 -#define GAME_CONTROL_LEVEL_NAME 68 -#define GAME_CONTROL_LEVEL_AUTHOR 69 - -#define NUM_GAME_CONTROLS 70 +#define GAME_CONTROL_INVENTORY_COUNT 2 +#define GAME_CONTROL_INVENTORY_FIRST_1 3 +#define GAME_CONTROL_INVENTORY_FIRST_2 4 +#define GAME_CONTROL_INVENTORY_FIRST_3 5 +#define GAME_CONTROL_INVENTORY_FIRST_4 6 +#define GAME_CONTROL_INVENTORY_FIRST_5 7 +#define GAME_CONTROL_INVENTORY_FIRST_6 8 +#define GAME_CONTROL_INVENTORY_FIRST_7 9 +#define GAME_CONTROL_INVENTORY_FIRST_8 10 +#define GAME_CONTROL_INVENTORY_LAST_1 11 +#define GAME_CONTROL_INVENTORY_LAST_2 12 +#define GAME_CONTROL_INVENTORY_LAST_3 13 +#define GAME_CONTROL_INVENTORY_LAST_4 14 +#define GAME_CONTROL_INVENTORY_LAST_5 15 +#define GAME_CONTROL_INVENTORY_LAST_6 16 +#define GAME_CONTROL_INVENTORY_LAST_7 17 +#define GAME_CONTROL_INVENTORY_LAST_8 18 +#define GAME_CONTROL_KEY_1 19 +#define GAME_CONTROL_KEY_2 20 +#define GAME_CONTROL_KEY_3 21 +#define GAME_CONTROL_KEY_4 22 +#define GAME_CONTROL_KEY_5 23 +#define GAME_CONTROL_KEY_6 24 +#define GAME_CONTROL_KEY_7 25 +#define GAME_CONTROL_KEY_8 26 +#define GAME_CONTROL_KEY_WHITE 27 +#define GAME_CONTROL_KEY_WHITE_COUNT 28 +#define GAME_CONTROL_SCORE 29 +#define GAME_CONTROL_TIME 30 +#define GAME_CONTROL_TIME_HH 31 +#define GAME_CONTROL_TIME_MM 32 +#define GAME_CONTROL_TIME_SS 33 +#define GAME_CONTROL_SHIELD_NORMAL 34 +#define GAME_CONTROL_SHIELD_NORMAL_TIME 35 +#define GAME_CONTROL_SHIELD_DEADLY 36 +#define GAME_CONTROL_SHIELD_DEADLY_TIME 37 +#define GAME_CONTROL_EXIT 38 +#define GAME_CONTROL_EM_EXIT 39 +#define GAME_CONTROL_SP_EXIT 40 +#define GAME_CONTROL_STEEL_EXIT 41 +#define GAME_CONTROL_EM_STEEL_EXIT 42 +#define GAME_CONTROL_EMC_MAGIC_BALL 43 +#define GAME_CONTROL_EMC_MAGIC_BALL_SWITCH 44 +#define GAME_CONTROL_LIGHT_SWITCH 45 +#define GAME_CONTROL_LIGHT_SWITCH_TIME 46 +#define GAME_CONTROL_TIMEGATE_SWITCH 47 +#define GAME_CONTROL_TIMEGATE_SWITCH_TIME 48 +#define GAME_CONTROL_SWITCHGATE_SWITCH 49 +#define GAME_CONTROL_EMC_LENSES 50 +#define GAME_CONTROL_EMC_LENSES_TIME 51 +#define GAME_CONTROL_EMC_MAGNIFIER 52 +#define GAME_CONTROL_EMC_MAGNIFIER_TIME 53 +#define GAME_CONTROL_BALLOON_SWITCH 54 +#define GAME_CONTROL_DYNABOMB_NUMBER 55 +#define GAME_CONTROL_DYNABOMB_SIZE 56 +#define GAME_CONTROL_DYNABOMB_POWER 57 +#define GAME_CONTROL_PENGUINS 58 +#define GAME_CONTROL_SOKOBAN_OBJECTS 59 +#define GAME_CONTROL_SOKOBAN_FIELDS 60 +#define GAME_CONTROL_ROBOT_WHEEL 61 +#define GAME_CONTROL_CONVEYOR_BELT_1 62 +#define GAME_CONTROL_CONVEYOR_BELT_1_SWITCH 63 +#define GAME_CONTROL_CONVEYOR_BELT_2 64 +#define GAME_CONTROL_CONVEYOR_BELT_2_SWITCH 65 +#define GAME_CONTROL_CONVEYOR_BELT_3 66 +#define GAME_CONTROL_CONVEYOR_BELT_3_SWITCH 67 +#define GAME_CONTROL_CONVEYOR_BELT_4 68 +#define GAME_CONTROL_CONVEYOR_BELT_4_SWITCH 69 +#define GAME_CONTROL_MAGIC_WALL 70 +#define GAME_CONTROL_MAGIC_WALL_TIME 71 +#define GAME_CONTROL_BD_MAGIC_WALL 72 +#define GAME_CONTROL_DC_MAGIC_WALL 73 +#define GAME_CONTROL_PLAYER_NAME 74 +#define GAME_CONTROL_LEVEL_NAME 75 +#define GAME_CONTROL_LEVEL_AUTHOR 76 + +#define NUM_GAME_CONTROLS 77 int game_control_value[NUM_GAME_CONTROLS]; int last_game_control_value[NUM_GAME_CONTROLS]; @@ -228,10 +235,90 @@ static struct GameControlInfo game_controls[] = TYPE_INTEGER, }, { - GAME_CONTROL_INVENTORY, - &game.panel.inventory, + GAME_CONTROL_INVENTORY_COUNT, + &game.panel.inventory_count, TYPE_INTEGER, }, + { + GAME_CONTROL_INVENTORY_FIRST_1, + &game.panel.inventory_first_1, + TYPE_ELEMENT, + }, + { + GAME_CONTROL_INVENTORY_FIRST_2, + &game.panel.inventory_first_2, + TYPE_ELEMENT, + }, + { + GAME_CONTROL_INVENTORY_FIRST_3, + &game.panel.inventory_first_3, + TYPE_ELEMENT, + }, + { + GAME_CONTROL_INVENTORY_FIRST_4, + &game.panel.inventory_first_4, + TYPE_ELEMENT, + }, + { + GAME_CONTROL_INVENTORY_FIRST_5, + &game.panel.inventory_first_5, + TYPE_ELEMENT, + }, + { + GAME_CONTROL_INVENTORY_FIRST_6, + &game.panel.inventory_first_6, + TYPE_ELEMENT, + }, + { + GAME_CONTROL_INVENTORY_FIRST_7, + &game.panel.inventory_first_7, + TYPE_ELEMENT, + }, + { + GAME_CONTROL_INVENTORY_FIRST_8, + &game.panel.inventory_first_8, + TYPE_ELEMENT, + }, + { + GAME_CONTROL_INVENTORY_LAST_1, + &game.panel.inventory_last_1, + TYPE_ELEMENT, + }, + { + GAME_CONTROL_INVENTORY_LAST_2, + &game.panel.inventory_last_2, + TYPE_ELEMENT, + }, + { + GAME_CONTROL_INVENTORY_LAST_3, + &game.panel.inventory_last_3, + TYPE_ELEMENT, + }, + { + GAME_CONTROL_INVENTORY_LAST_4, + &game.panel.inventory_last_4, + TYPE_ELEMENT, + }, + { + GAME_CONTROL_INVENTORY_LAST_5, + &game.panel.inventory_last_5, + TYPE_ELEMENT, + }, + { + GAME_CONTROL_INVENTORY_LAST_6, + &game.panel.inventory_last_6, + TYPE_ELEMENT, + }, + { + GAME_CONTROL_INVENTORY_LAST_7, + &game.panel.inventory_last_7, + TYPE_ELEMENT, + }, + { + GAME_CONTROL_INVENTORY_LAST_8, + &game.panel.inventory_last_8, + TYPE_ELEMENT, + }, { GAME_CONTROL_KEY_1, &game.panel.key[0], @@ -307,46 +394,6 @@ static struct GameControlInfo game_controls[] = &game.panel.time_ss, TYPE_INTEGER, }, - { - GAME_CONTROL_DROP_NEXT_1, - &game.panel.drop_next_1, - TYPE_ELEMENT, - }, - { - GAME_CONTROL_DROP_NEXT_2, - &game.panel.drop_next_2, - TYPE_ELEMENT, - }, - { - GAME_CONTROL_DROP_NEXT_3, - &game.panel.drop_next_3, - TYPE_ELEMENT, - }, - { - GAME_CONTROL_DROP_NEXT_4, - &game.panel.drop_next_4, - TYPE_ELEMENT, - }, - { - GAME_CONTROL_DROP_NEXT_5, - &game.panel.drop_next_5, - TYPE_ELEMENT, - }, - { - GAME_CONTROL_DROP_NEXT_6, - &game.panel.drop_next_6, - TYPE_ELEMENT, - }, - { - GAME_CONTROL_DROP_NEXT_7, - &game.panel.drop_next_7, - TYPE_ELEMENT, - }, - { - GAME_CONTROL_DROP_NEXT_8, - &game.panel.drop_next_8, - TYPE_ELEMENT, - }, { GAME_CONTROL_SHIELD_NORMAL, &game.panel.shield_normal, @@ -402,11 +449,6 @@ static struct GameControlInfo game_controls[] = &game.panel.emc_magic_ball_switch, TYPE_ELEMENT, }, - { - GAME_CONTROL_EMC_MAGIC_BALL_TIME, - &game.panel.emc_magic_ball_time, - TYPE_INTEGER, - }, { GAME_CONTROL_LIGHT_SWITCH, &game.panel.light_switch, @@ -1728,53 +1770,118 @@ static inline void InitField_WithBug2(int x, int y, boolean init_game) #if 1 +static int get_key_element_from_nr(int key_nr) +{ + int key_base_element = (key_nr >= STD_NUM_KEYS ? EL_EMC_KEY_5 - STD_NUM_KEYS : + level.game_engine_type == GAME_ENGINE_TYPE_EM ? + EL_EM_KEY_1 : EL_KEY_1); + + return key_base_element + key_nr; +} + +static int get_next_drop_element(struct PlayerInfo *player) +{ + return (player->inventory_size > 0 ? + player->inventory_element[player->inventory_size - 1] : + player->inventory_infinite_element != EL_UNDEFINED ? + player->inventory_infinite_element : + player->dynabombs_left > 0 ? + EL_DYNABOMB_PLAYER_1_ACTIVE + player->index_nr : + EL_UNDEFINED); +} + +static int get_drop_element_from_pos(struct PlayerInfo *player, int pos) +{ + /* pos >= 0: get element from bottom of the stack; + pos < 0: get element from top of the stack */ + + if (pos < 0) + { + int min_inventory_size = -pos; + int inventory_pos = player->inventory_size - min_inventory_size; + int min_dynabombs_left = min_inventory_size - player->inventory_size; + + return (player->inventory_size >= min_inventory_size ? + player->inventory_element[inventory_pos] : + player->inventory_infinite_element != EL_UNDEFINED ? + player->inventory_infinite_element : + player->dynabombs_left >= min_dynabombs_left ? + EL_DYNABOMB_PLAYER_1_ACTIVE + player->index_nr : + EL_UNDEFINED); + } + else + { + int min_dynabombs_left = pos + 1; + int min_inventory_size = pos + 1 - player->dynabombs_left; + int inventory_pos = pos - player->dynabombs_left; + + return (player->inventory_infinite_element != EL_UNDEFINED ? + player->inventory_infinite_element : + player->dynabombs_left >= min_dynabombs_left ? + EL_DYNABOMB_PLAYER_1_ACTIVE + player->index_nr : + player->inventory_size >= min_inventory_size ? + player->inventory_element[inventory_pos] : + EL_UNDEFINED); + } +} + void InitGameControlValues() { int i; - for (i = 0; i < NUM_GAME_CONTROLS; i++) - game_control_value[i] = last_game_control_value[i] = -1; - for (i = 0; game_controls[i].nr != -1; i++) { int nr = game_controls[i].nr; int type = game_controls[i].type; struct TextPosInfo *pos = game_controls[i].pos; + /* force update of game controls after initialization */ game_control_value[nr] = last_game_control_value[nr] = -1; /* determine panel value width for later calculation of alignment */ if (type == TYPE_INTEGER || type == TYPE_STRING) - pos->width = pos->chars * getFontWidth(pos->font); + { + pos->width = pos->size * getFontWidth(pos->font); + pos->height = getFontHeight(pos->font); + } + else if (type == TYPE_ELEMENT) + { + pos->width = pos->size; + pos->height = pos->size; + } } } void UpdateGameControlValues() { - int i, j; + int i, k; + int time = (level.time == 0 ? TimePlayed : TimeLeft); + int score = (local_player->LevelSolved ? local_player->score_final : + local_player->score); game_control_value[GAME_CONTROL_LEVEL_NUMBER] = level_nr; game_control_value[GAME_CONTROL_GEMS] = local_player->gems_still_needed; - game_control_value[GAME_CONTROL_INVENTORY] = 0; + game_control_value[GAME_CONTROL_INVENTORY_COUNT] = 0; for (i = 0; i < MAX_NUM_KEYS; i++) - game_control_value[GAME_CONTROL_KEY_1 + i] = 0; - game_control_value[GAME_CONTROL_KEY_WHITE] = 0; + game_control_value[GAME_CONTROL_KEY_1 + i] = EL_EMPTY; + game_control_value[GAME_CONTROL_KEY_WHITE] = EL_EMPTY; game_control_value[GAME_CONTROL_KEY_WHITE_COUNT] = 0; if (game.centered_player_nr == -1) { for (i = 0; i < MAX_PLAYERS; i++) { - for (j = 0; j < MAX_NUM_KEYS; j++) - if (stored_player[i].key[j]) - game_control_value[GAME_CONTROL_KEY_1 + j] = 1; + for (k = 0; k < MAX_NUM_KEYS; k++) + if (stored_player[i].key[k]) + game_control_value[GAME_CONTROL_KEY_1 + k] = + get_key_element_from_nr(k); - game_control_value[GAME_CONTROL_INVENTORY] += + game_control_value[GAME_CONTROL_INVENTORY_COUNT] += stored_player[i].inventory_size; if (stored_player[i].num_white_keys > 0) - game_control_value[GAME_CONTROL_KEY_WHITE] = 1; + game_control_value[GAME_CONTROL_KEY_WHITE] = EL_DC_KEY_WHITE; game_control_value[GAME_CONTROL_KEY_WHITE_COUNT] += stored_player[i].num_white_keys; @@ -1784,77 +1891,104 @@ void UpdateGameControlValues() { int player_nr = game.centered_player_nr; - for (i = 0; i < MAX_NUM_KEYS; i++) - if (stored_player[player_nr].key[i]) - game_control_value[GAME_CONTROL_KEY_1 + i] = 1; + for (k = 0; k < MAX_NUM_KEYS; k++) + if (stored_player[player_nr].key[k]) + game_control_value[GAME_CONTROL_KEY_1 + k] = + get_key_element_from_nr(k); - game_control_value[GAME_CONTROL_INVENTORY] += + game_control_value[GAME_CONTROL_INVENTORY_COUNT] += stored_player[player_nr].inventory_size; if (stored_player[player_nr].num_white_keys > 0) - game_control_value[GAME_CONTROL_KEY_WHITE] = 1; + game_control_value[GAME_CONTROL_KEY_WHITE] = EL_DC_KEY_WHITE; game_control_value[GAME_CONTROL_KEY_WHITE_COUNT] += stored_player[player_nr].num_white_keys; } - game_control_value[GAME_CONTROL_SCORE] = (local_player->LevelSolved ? - local_player->score_final : - local_player->score); + for (i = 0; i < 8; i++) + { + game_control_value[GAME_CONTROL_INVENTORY_FIRST_1 + i] = + get_drop_element_from_pos(local_player, i); + game_control_value[GAME_CONTROL_INVENTORY_LAST_1 + i] = + get_drop_element_from_pos(local_player, -i - 1); + } - game_control_value[GAME_CONTROL_TIME] = (level.time == 0 ? - TimePlayed : - TimeLeft); + game_control_value[GAME_CONTROL_SCORE] = score; - game_control_value[GAME_CONTROL_TIME_HH] = TapeTime / 3600; - game_control_value[GAME_CONTROL_TIME_MM] = (TapeTime / 60) % 60; - game_control_value[GAME_CONTROL_TIME_SS] = TapeTime % 60; + game_control_value[GAME_CONTROL_TIME] = time; - for (i = 0; i < 8; i++) - game_control_value[GAME_CONTROL_DROP_NEXT_1 + i] = 0; + game_control_value[GAME_CONTROL_TIME_HH] = time / 3600; + game_control_value[GAME_CONTROL_TIME_MM] = (time / 60) % 60; + game_control_value[GAME_CONTROL_TIME_SS] = time % 60; game_control_value[GAME_CONTROL_SHIELD_NORMAL] = - (local_player->shield_normal_time_left > 0 ? 1 : 0); + (local_player->shield_normal_time_left > 0 ? EL_SHIELD_NORMAL_ACTIVE : + EL_EMPTY); game_control_value[GAME_CONTROL_SHIELD_NORMAL_TIME] = local_player->shield_normal_time_left; game_control_value[GAME_CONTROL_SHIELD_DEADLY] = - (local_player->shield_deadly_time_left > 0 ? 1 : 0); + (local_player->shield_deadly_time_left > 0 ? EL_SHIELD_DEADLY_ACTIVE : + EL_EMPTY); game_control_value[GAME_CONTROL_SHIELD_DEADLY_TIME] = local_player->shield_deadly_time_left; - game_control_value[GAME_CONTROL_EXIT] = 0; - game_control_value[GAME_CONTROL_EM_EXIT] = 0; - game_control_value[GAME_CONTROL_SP_EXIT] = 0; - game_control_value[GAME_CONTROL_STEEL_EXIT] = 0; - game_control_value[GAME_CONTROL_EM_STEEL_EXIT] = 0; + if (local_player->gems_still_needed > 0 || + local_player->sokobanfields_still_needed > 0 || + local_player->lights_still_needed > 0) + { + game_control_value[GAME_CONTROL_EXIT] = EL_EXIT_CLOSED; + game_control_value[GAME_CONTROL_EM_EXIT] = EL_EM_EXIT_CLOSED; + game_control_value[GAME_CONTROL_SP_EXIT] = EL_SP_EXIT_CLOSED; + game_control_value[GAME_CONTROL_STEEL_EXIT] = EL_STEEL_EXIT_CLOSED; + game_control_value[GAME_CONTROL_EM_STEEL_EXIT] = EL_EM_STEEL_EXIT_CLOSED; + } + else + { + game_control_value[GAME_CONTROL_EXIT] = EL_EXIT_OPEN; + game_control_value[GAME_CONTROL_EM_EXIT] = EL_EM_EXIT_OPEN; + game_control_value[GAME_CONTROL_SP_EXIT] = EL_SP_EXIT_OPEN; + game_control_value[GAME_CONTROL_STEEL_EXIT] = EL_STEEL_EXIT_OPEN; + game_control_value[GAME_CONTROL_EM_STEEL_EXIT] = EL_EM_STEEL_EXIT_OPEN; + } - game_control_value[GAME_CONTROL_EMC_MAGIC_BALL] = 0; - game_control_value[GAME_CONTROL_EMC_MAGIC_BALL_SWITCH] = 0; - game_control_value[GAME_CONTROL_EMC_MAGIC_BALL_TIME] = 0; + /* !!! TODO !!! */ + game_control_value[GAME_CONTROL_EMC_MAGIC_BALL] = EL_UNDEFINED; + game_control_value[GAME_CONTROL_EMC_MAGIC_BALL_SWITCH] = EL_UNDEFINED; - game_control_value[GAME_CONTROL_LIGHT_SWITCH] = 0; + game_control_value[GAME_CONTROL_LIGHT_SWITCH] = + (game.light_time_left > 0 ? EL_LIGHT_SWITCH_ACTIVE : EL_LIGHT_SWITCH); game_control_value[GAME_CONTROL_LIGHT_SWITCH_TIME] = game.light_time_left; - game_control_value[GAME_CONTROL_TIMEGATE_SWITCH] = 0; + game_control_value[GAME_CONTROL_TIMEGATE_SWITCH] = + (game.timegate_time_left > 0 ? EL_TIMEGATE_OPEN : EL_TIMEGATE_CLOSED); game_control_value[GAME_CONTROL_TIMEGATE_SWITCH_TIME] = game.timegate_time_left; - game_control_value[GAME_CONTROL_SWITCHGATE_SWITCH] = 0; + /* !!! TODO !!! */ + game_control_value[GAME_CONTROL_SWITCHGATE_SWITCH] = EL_UNDEFINED; - game_control_value[GAME_CONTROL_EMC_LENSES] = 0; + game_control_value[GAME_CONTROL_EMC_LENSES] = + (game.lenses_time_left > 0 ? EL_EMC_LENSES : EL_EMPTY); game_control_value[GAME_CONTROL_EMC_LENSES_TIME] = game.lenses_time_left; - game_control_value[GAME_CONTROL_EMC_MAGNIFIER] = 0; + game_control_value[GAME_CONTROL_EMC_MAGNIFIER] = + (game.magnify_time_left > 0 ? EL_EMC_MAGNIFIER : EL_EMPTY); game_control_value[GAME_CONTROL_EMC_MAGNIFIER_TIME] = game.magnify_time_left; - game_control_value[GAME_CONTROL_BALLOON_SWITCH] = 0; + game_control_value[GAME_CONTROL_BALLOON_SWITCH] = + (game.wind_direction == MV_LEFT ? EL_BALLOON_SWITCH_LEFT : + game.wind_direction == MV_RIGHT ? EL_BALLOON_SWITCH_RIGHT : + game.wind_direction == MV_UP ? EL_BALLOON_SWITCH_UP : + game.wind_direction == MV_DOWN ? EL_BALLOON_SWITCH_DOWN : + EL_BALLOON_SWITCH_NONE); game_control_value[GAME_CONTROL_DYNABOMB_NUMBER] = local_player->dynabomb_count; game_control_value[GAME_CONTROL_DYNABOMB_SIZE] = local_player->dynabomb_size; game_control_value[GAME_CONTROL_DYNABOMB_POWER] = - local_player->dynabomb_xl; + (local_player->dynabomb_xl ? EL_DYNABOMB_INCREASE_POWER : EL_EMPTY); game_control_value[GAME_CONTROL_PENGUINS] = local_player->friends_still_needed; @@ -1864,22 +1998,25 @@ void UpdateGameControlValues() game_control_value[GAME_CONTROL_SOKOBAN_FIELDS] = local_player->sokobanfields_still_needed; - game_control_value[GAME_CONTROL_ROBOT_WHEEL] = 0; - - game_control_value[GAME_CONTROL_CONVEYOR_BELT_1] = 0; - game_control_value[GAME_CONTROL_CONVEYOR_BELT_1_SWITCH] = 0; - game_control_value[GAME_CONTROL_CONVEYOR_BELT_2] = 0; - game_control_value[GAME_CONTROL_CONVEYOR_BELT_2_SWITCH] = 0; - game_control_value[GAME_CONTROL_CONVEYOR_BELT_3] = 0; - game_control_value[GAME_CONTROL_CONVEYOR_BELT_3_SWITCH] = 0; - game_control_value[GAME_CONTROL_CONVEYOR_BELT_4] = 0; - game_control_value[GAME_CONTROL_CONVEYOR_BELT_4_SWITCH] = 0; - - game_control_value[GAME_CONTROL_MAGIC_WALL] = 0; + /* !!! TODO !!! */ + game_control_value[GAME_CONTROL_ROBOT_WHEEL] = EL_UNDEFINED; + + /* !!! TODO !!! */ + game_control_value[GAME_CONTROL_CONVEYOR_BELT_1] = EL_UNDEFINED; + game_control_value[GAME_CONTROL_CONVEYOR_BELT_1_SWITCH] = EL_UNDEFINED; + game_control_value[GAME_CONTROL_CONVEYOR_BELT_2] = EL_UNDEFINED; + game_control_value[GAME_CONTROL_CONVEYOR_BELT_2_SWITCH] = EL_UNDEFINED; + game_control_value[GAME_CONTROL_CONVEYOR_BELT_3] = EL_UNDEFINED; + game_control_value[GAME_CONTROL_CONVEYOR_BELT_3_SWITCH] = EL_UNDEFINED; + game_control_value[GAME_CONTROL_CONVEYOR_BELT_4] = EL_UNDEFINED; + game_control_value[GAME_CONTROL_CONVEYOR_BELT_4_SWITCH] = EL_UNDEFINED; + + /* !!! TODO !!! */ + game_control_value[GAME_CONTROL_MAGIC_WALL] = EL_UNDEFINED; game_control_value[GAME_CONTROL_MAGIC_WALL_TIME] = game.magic_wall_time_left; - game_control_value[GAME_CONTROL_BD_MAGIC_WALL] = 0; - game_control_value[GAME_CONTROL_DC_MAGIC_WALL] = 0; + game_control_value[GAME_CONTROL_BD_MAGIC_WALL] = EL_UNDEFINED; + game_control_value[GAME_CONTROL_DC_MAGIC_WALL] = EL_UNDEFINED; game_control_value[GAME_CONTROL_PLAYER_NAME] = 0; game_control_value[GAME_CONTROL_LEVEL_NAME] = 0; @@ -1890,6 +2027,8 @@ void DisplayGameControlValues() { int i; + game_status = GAME_MODE_PSEUDO_PANEL; + for (i = 0; game_controls[i].nr != -1; i++) { int nr = game_controls[i].nr; @@ -1897,7 +2036,7 @@ void DisplayGameControlValues() struct TextPosInfo *pos = game_controls[i].pos; int value = game_control_value[nr]; int last_value = last_game_control_value[nr]; - int chars = pos->chars; + int size = pos->size; int font = pos->font; if (value == last_value) @@ -1916,24 +2055,24 @@ void DisplayGameControlValues() { if (nr == GAME_CONTROL_LEVEL_NUMBER || nr == GAME_CONTROL_TIME) { - boolean use_dynamic_chars = (pos->chars == -1 ? TRUE : FALSE); + boolean use_dynamic_size = (size == -1 ? TRUE : FALSE); - if (use_dynamic_chars) /* use dynamic number of chars */ + if (use_dynamic_size) /* use dynamic number of digits */ { int value_change = (nr == GAME_CONTROL_LEVEL_NUMBER ? 100 : 1000); - int chars1 = (nr == GAME_CONTROL_LEVEL_NUMBER ? 2 : 3); - int chars2 = chars1 + 1; + int size1 = (nr == GAME_CONTROL_LEVEL_NUMBER ? 2 : 3); + int size2 = size1 + 1; int font1 = pos->font; int font2 = pos->font_alt; - chars = (value < value_change ? chars1 : chars2); - font = (value < value_change ? font1 : font2); + size = (value < value_change ? size1 : size2); + font = (value < value_change ? font1 : font2); - /* clear background if value just changed its size (dynamic chars) */ + /* clear background if value just changed its size (dynamic digits) */ if ((last_value < value_change) != (value < value_change)) { - int width1 = chars1 * getFontWidth(font1); - int width2 = chars2 * getFontWidth(font2); + int width1 = size1 * getFontWidth(font1); + int width2 = size2 * getFontWidth(font2); int max_width = MAX(width1, width2); int max_height = MAX(getFontHeight(font1), getFontHeight(font2)); @@ -1944,30 +2083,29 @@ void DisplayGameControlValues() } } - pos->width = chars * getFontWidth(font); + pos->width = size * getFontWidth(font); } - DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, chars), font); + DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, size), font); } else if (type == TYPE_ELEMENT) { - if (nr >= GAME_CONTROL_KEY_1 && nr <= GAME_CONTROL_KEY_8) + int dst_x = PANEL_XPOS(pos); + int dst_y = PANEL_YPOS(pos); + + if (value == EL_UNDEFINED || value == EL_EMPTY) { - int key_nr = nr - GAME_CONTROL_KEY_1; - int src_x = DOOR_GFX_PAGEX5 + 18 + (key_nr % STD_NUM_KEYS) * MINI_TILEX; - int src_y = DOOR_GFX_PAGEY1 + 123; - int dst_x = PANEL_XPOS(pos); - int dst_y = PANEL_YPOS(pos); - int element = (key_nr >= STD_NUM_KEYS ? EL_EMC_KEY_5 - STD_NUM_KEYS : - level.game_engine_type == GAME_ENGINE_TYPE_EM ? - EL_EM_KEY_1 : EL_KEY_1) + key_nr; - int graphic = el2edimg(element); + int src_x = DOOR_GFX_PAGEX5 + ALIGNED_TEXT_XPOS(pos); + int src_y = DOOR_GFX_PAGEY1 + ALIGNED_TEXT_YPOS(pos); - if (value) - DrawMiniGraphicExt(drawto, dst_x, dst_y, graphic); - else - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, src_x, src_y, - MINI_TILEX, MINI_TILEY, dst_x, dst_y); + BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, src_x, src_y, + size, size, dst_x, dst_y); + } + else + { + int graphic = el2panelimg(value); + + DrawSizedGraphicExt(drawto, dst_x, dst_y, graphic, size); } } else if (type == TYPE_STRING) @@ -1978,14 +2116,18 @@ void DisplayGameControlValues() if (s != NULL) { - char *s_cut = getStringCopyN(s, pos->chars); + char *s_cut = getStringCopyN(s, size); - DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), s_cut, pos->font); + DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), s_cut, font); free(s_cut); } } + + redraw_mask |= REDRAW_DOOR_1; } + + game_status = GAME_MODE_PLAYING; } void DrawGameValue_Emeralds(int value) @@ -1997,7 +2139,7 @@ void DrawGameValue_Emeralds(int value) int font_nr = FONT_TEXT_2; #endif int font_width = getFontWidth(font_nr); - int chars = pos->chars; + int chars = pos->size; #if 1 return; /* !!! USE NEW STUFF !!! */ @@ -2013,14 +2155,14 @@ void DrawGameValue_Emeralds(int value) void DrawGameValue_Dynamite(int value) { - struct TextPosInfo *pos = &game.panel.inventory; + struct TextPosInfo *pos = &game.panel.inventory_count; #if 1 int font_nr = pos->font; #else int font_nr = FONT_TEXT_2; #endif int font_width = getFontWidth(font_nr); - int chars = pos->chars; + int chars = pos->size; #if 1 return; /* !!! USE NEW STUFF !!! */ @@ -2043,7 +2185,7 @@ void DrawGameValue_Score(int value) int font_nr = FONT_TEXT_2; #endif int font_width = getFontWidth(font_nr); - int chars = pos->chars; + int chars = pos->size; #if 1 return; /* !!! USE NEW STUFF !!! */ @@ -2063,7 +2205,7 @@ void DrawGameValue_Time(int value) static int last_value = -1; int chars1 = 3; int chars2 = 4; - int chars = pos->chars; + int chars = pos->size; #if 1 int font1_nr = pos->font; int font2_nr = pos->font_alt; @@ -2113,7 +2255,7 @@ void DrawGameValue_Level(int value) struct TextPosInfo *pos = &game.panel.level_number; int chars1 = 2; int chars2 = 3; - int chars = pos->chars; + int chars = pos->size; #if 1 int font1_nr = pos->font; int font2_nr = pos->font_alt; @@ -2261,7 +2403,7 @@ void DrawGameValue_Dynamite(int value) int font_nr = FONT_TEXT_2; int xpos = (3 * 14 - 3 * getFontWidth(font_nr)) / 2; - if (PANEL_DEACTIVATED(game.panel.inventory)) + if (PANEL_DEACTIVATED(game.panel.inventory_count)) return; DrawText(DX_DYNAMITE + xpos, DY_DYNAMITE, int2str(value, 3), font_nr); @@ -2846,6 +2988,13 @@ static void InitGameEngine() recursion_loop_depth = 0; recursion_loop_detected = FALSE; recursion_loop_element = EL_UNDEFINED; + + /* ---------- initialize graphics engine ---------------------------------- */ + game.scroll_delay_value = + (game.forced_scroll_delay_value != -1 ? game.forced_scroll_delay_value : + setup.scroll_delay ? setup.scroll_delay_value : 0); + game.scroll_delay_value = + MIN(MAX(MIN_SCROLL_DELAY, game.scroll_delay_value), MAX_SCROLL_DELAY); } int get_num_special_action(int element, int action_first, int action_last) @@ -3374,7 +3523,8 @@ void InitGame() content = element_info[element].change_page[i].target_element; is_player = ELEM_IS_PLAYER(content); - if (is_player && (found_rating < 3 || element < found_element)) + if (is_player && (found_rating < 3 || + (found_rating == 3 && element < found_element))) { start_x = x; start_y = y; @@ -3391,7 +3541,8 @@ void InitGame() content = element_info[element].content.e[xx][yy]; is_player = ELEM_IS_PLAYER(content); - if (is_player && (found_rating < 2 || element < found_element)) + if (is_player && (found_rating < 2 || + (found_rating == 2 && element < found_element))) { start_x = x + xx - 1; start_y = y + yy - 1; @@ -3411,7 +3562,8 @@ void InitGame() is_player = ELEM_IS_PLAYER(content); - if (is_player && (found_rating < 1 || element < found_element)) + if (is_player && (found_rating < 1 || + (found_rating == 1 && element < found_element))) { start_x = x + xx - 1; start_y = y + yy - 1; @@ -3442,6 +3594,9 @@ void InitGame() local_player->jy - MIDPOSY); } + /* do not use PLAYING mask for fading out from main screen */ + game_status = GAME_MODE_MAIN; + StopAnimation(); if (!game.restart_level) @@ -3451,7 +3606,7 @@ void InitGame() if (level_editor_test_game) FadeSkipNextFadeIn(); else - FadeSetStartItem(); + FadeSetEnterScreen(); #else if (level_editor_test_game) fading = fading_none; @@ -3466,6 +3621,8 @@ void InitGame() FadeOut(REDRAW_FIELD); #endif + game_status = GAME_MODE_PLAYING; + /* !!! FIX THIS (START) !!! */ if (level.game_engine_type == GAME_ENGINE_TYPE_EM) { @@ -4491,7 +4648,7 @@ void DrawRelocateScreen(int old_x, int old_y, int x, int y, int move_dir, if (quick_relocation) { - int offset = (setup.scroll_delay ? 3 : 0); + int offset = game.scroll_delay_value; if (!IN_VIS_FIELD(SCREENX(x), SCREENY(y)) || center_screen) { @@ -12114,7 +12271,7 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) #endif { int old_scroll_x = scroll_x, old_scroll_y = scroll_y; - int offset = (setup.scroll_delay ? 3 : 0); + int offset = game.scroll_delay_value; if (!IN_VIS_FIELD(SCREENX(jx), SCREENY(jy))) { @@ -14000,6 +14157,9 @@ boolean DropElement(struct PlayerInfo *player) int dropx = player->jx, dropy = player->jy; int drop_direction = player->MovDir; int drop_side = drop_direction; +#if 1 + int drop_element = get_next_drop_element(player); +#else int drop_element = (player->inventory_size > 0 ? player->inventory_element[player->inventory_size - 1] : player->inventory_infinite_element != EL_UNDEFINED ? @@ -14007,6 +14167,7 @@ boolean DropElement(struct PlayerInfo *player) player->dynabombs_left > 0 ? EL_DYNABOMB_PLAYER_1_ACTIVE + player->index_nr : EL_UNDEFINED); +#endif player->is_dropping_pressed = TRUE;