X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=4a3f9d39c8feb62bcd728cfe9e7b2ca2acb309cb;hb=d8865c54181a9375cc0ee0b967d8a709f4044ef8;hp=06de1e48621fab80bf5e0595823c6814083eefd2;hpb=de94c39950b38b1dd99f387cda61cb650214b59e;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 06de1e48..4a3f9d39 100644 --- a/src/game.c +++ b/src/game.c @@ -25,14 +25,14 @@ #define USE_NEW_AMOEBA_CODE FALSE /* EXPERIMENTAL STUFF */ -#define USE_NEW_STUFF ( * 1) +#define USE_NEW_STUFF ( 1) #define USE_NEW_SP_SLIPPERY (USE_NEW_STUFF * 1) #define USE_NEW_COLLECT_COUNT (USE_NEW_STUFF * 1) #define USE_NEW_PLAYER_ANIM (USE_NEW_STUFF * 1) #define USE_NEW_ALL_SLIPPERY (USE_NEW_STUFF * 1) #define USE_NEW_PLAYER_SPEED (USE_NEW_STUFF * 1) - +#define USE_NEW_DELAYED_ACTION (USE_NEW_STUFF * 1) /* for DigField() */ #define DF_NO_PUSH 0 @@ -1263,6 +1263,9 @@ static void InitGameEngine() ei->change->change_function = ch_delay->change_function; ei->change->post_change_function = ch_delay->post_change_function; + ei->change->can_change = TRUE; + ei->change->can_change_or_has_action = TRUE; + ei->has_change_event[CE_DELAY] = TRUE; SET_PROPERTY(ch_delay->element, EP_CAN_CHANGE, TRUE); @@ -1930,7 +1933,7 @@ void InitGame() for (yy = 0; yy < 3; yy++) for (xx = 0; xx < 3; xx++) { - content = element_info[element].content[xx][yy]; + content = element_info[element].content.e[xx][yy]; is_player = ELEM_IS_PLAYER(content); if (is_player && (found_rating < 2 || element < found_element)) @@ -1947,7 +1950,9 @@ void InitGame() for (i = 0; i < element_info[element].num_change_pages; i++) { - content= element_info[element].change_page[i].target_content[xx][yy]; + content = + element_info[element].change_page[i].target_content.e[xx][yy]; + is_player = ELEM_IS_PLAYER(content); if (is_player && (found_rating < 1 || element < found_element)) @@ -3063,10 +3068,10 @@ void Explode(int ex, int ey, int phase, int mode) else if (center_element == EL_AMOEBA_TO_DIAMOND) Store[x][y] = level.amoeba_content; else if (center_element == EL_YAMYAM) - Store[x][y] = level.yamyam_content[game.yamyam_content_nr][xx][yy]; + Store[x][y] = level.yamyam_content[game.yamyam_content_nr].e[xx][yy]; else if (IS_CUSTOM_ELEMENT(center_element) && - element_info[center_element].content[xx][yy] != EL_EMPTY) - Store[x][y] = element_info[center_element].content[xx][yy]; + element_info[center_element].content.e[xx][yy] != EL_EMPTY) + Store[x][y] = element_info[center_element].content.e[xx][yy]; else if (element == EL_WALL_EMERALD) Store[x][y] = EL_EMERALD; else if (element == EL_WALL_DIAMOND) @@ -3084,7 +3089,7 @@ void Explode(int ex, int ey, int phase, int mode) else if (element == EL_WALL_CRYSTAL) Store[x][y] = EL_CRYSTAL; else if (IS_CUSTOM_ELEMENT(element) && !CAN_EXPLODE(element)) - Store[x][y] = element_info[element].content[1][1]; + Store[x][y] = element_info[element].content.e[1][1]; else Store[x][y] = EL_EMPTY; @@ -6591,19 +6596,17 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) action_mode, action_arg_number, action_arg_number_min, action_arg_number_max); - /* (for explicit player choice, set invalid value to "no player") */ int action_arg_player_bits = - (action_arg == CA_ARG_PLAYER_ANY ? action_arg - CA_ARG_PLAYER : + (action_arg == CA_ARG_PLAYER_ANY ? PLAYER_BITS_ANY : action_arg >= CA_ARG_PLAYER_1 && action_arg <= CA_ARG_PLAYER_4 ? action_arg - CA_ARG_PLAYER : action_arg >= CA_ARG_1 && - action_arg <= CA_ARG_PLAYER_4 ? (1 << (action_arg - 1)) : + action_arg <= CA_ARG_PLAYER_4 ? (1 << (action_arg - CA_ARG_1)) : action_arg_element >= EL_PLAYER_1 && action_arg_element <= EL_PLAYER_4 ? (1 << (action_arg_element - EL_PLAYER_1)) : - 0); + PLAYER_BITS_ANY); - /* (for implicit player choice, set invalid value to "all players") */ int trigger_player_bits = (change->actual_trigger_player >= EL_PLAYER_1 && change->actual_trigger_player <= EL_PLAYER_4 ? @@ -6963,7 +6966,7 @@ static boolean ChangeElementNow(int x, int y, int element, int page) boolean is_destructible; int ex = x + xx - 1; int ey = y + yy - 1; - int content_element = change->target_content[xx][yy]; + int content_element = change->target_content.e[xx][yy]; int e; can_replace[xx][yy] = TRUE; @@ -7035,7 +7038,7 @@ static boolean ChangeElementNow(int x, int y, int element, int page) ChangeEvent[ex][ey] = ChangeEvent[x][y]; - content_element = change->target_content[xx][yy]; + content_element = change->target_content.e[xx][yy]; target_element = GET_TARGET_ELEMENT(content_element, change); ChangeElementNowExt(change, ex, ey, target_element); @@ -7049,7 +7052,10 @@ static boolean ChangeElementNow(int x, int y, int element, int page) } if (something_has_changed) + { PlayLevelSoundElementAction(x, y, element, ACTION_CHANGING); + PlayLevelSoundElementAction(x, y, element, ACTION_PAGE_1 + page); + } } } else @@ -7059,6 +7065,7 @@ static boolean ChangeElementNow(int x, int y, int element, int page) ChangeElementNowExt(change, x, y, target_element); PlayLevelSoundElementAction(x, y, element, ACTION_CHANGING); + PlayLevelSoundElementAction(x, y, element, ACTION_PAGE_1 + page); } /* this uses direct change before indirect change */ @@ -7067,6 +7074,8 @@ static boolean ChangeElementNow(int x, int y, int element, int page) return TRUE; } +#if USE_NEW_DELAYED_ACTION + static void ChangeElement(int x, int y, int page) { int element = MovingOrBlocked2Element(x, y); @@ -7157,6 +7166,87 @@ static void ChangeElement(int x, int y, int page) } } +#else + +static void ChangeElement(int x, int y, int page) +{ + int element = MovingOrBlocked2Element(x, y); + struct ElementInfo *ei = &element_info[element]; + struct ElementChangeInfo *change = &ei->change_page[page]; + +#ifdef DEBUG + if (!CAN_CHANGE(element) && !CAN_CHANGE(Back[x][y])) + { + printf("\n\n"); + printf("ChangeElement(): %d,%d: element = %d ('%s')\n", + x, y, element, element_info[element].token_name); + printf("ChangeElement(): This should never happen!\n"); + printf("\n\n"); + } +#endif + + /* this can happen with classic bombs on walkable, changing elements */ + if (!CAN_CHANGE(element)) + { +#if 0 + if (!CAN_CHANGE(Back[x][y])) /* prevent permanent repetition */ + ChangeDelay[x][y] = 0; +#endif + + return; + } + + if (ChangeDelay[x][y] == 0) /* initialize element change */ + { + ChangeDelay[x][y] = GET_CHANGE_DELAY(change) + 1; + + ResetGfxAnimation(x, y); + ResetRandomAnimationValue(x, y); + + if (change->pre_change_function) + change->pre_change_function(x, y); + } + + ChangeDelay[x][y]--; + + if (ChangeDelay[x][y] != 0) /* continue element change */ + { + int graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); + + if (IS_ANIMATED(graphic)) + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); + + if (change->change_function) + change->change_function(x, y); + } + else /* finish element change */ + { + if (ChangePage[x][y] != -1) /* remember page from delayed change */ + { + page = ChangePage[x][y]; + ChangePage[x][y] = -1; + + change = &ei->change_page[page]; + } + + if (IS_MOVING(x, y)) /* never change a running system ;-) */ + { + ChangeDelay[x][y] = 1; /* try change after next move step */ + ChangePage[x][y] = page; /* remember page to use for change */ + + return; + } + + if (ChangeElementNow(x, y, element, page)) + { + if (change->post_change_function) + change->post_change_function(x, y); + } + } +} + +#endif + static boolean CheckTriggeredElementChangeExt(int trigger_element, int trigger_event, int trigger_player, @@ -7208,12 +7298,18 @@ static boolean CheckTriggeredElementChangeExt(int trigger_element, ChangeEvent[x][y] = trigger_event; ChangeElement(x, y, p); } -#if 1 +#if USE_NEW_DELAYED_ACTION else if (change->has_action) + { ExecuteCustomElementAction(x, y, element, p); + PlayLevelSoundElementAction(x, y, element, ACTION_PAGE_1 + p); + } #else if (change->has_action) + { ExecuteCustomElementAction(x, y, element, p); + PlayLevelSoundElementAction(x, y, element, ACTION_PAGE_1 + p); + } #endif } } @@ -7281,12 +7377,18 @@ static boolean CheckElementChangeExt(int x, int y, change_done = TRUE; } -#if 1 +#if USE_NEW_DELAYED_ACTION else if (change->has_action) + { ExecuteCustomElementAction(x, y, element, p); + PlayLevelSoundElementAction(x, y, element, ACTION_PAGE_1 + p); + } #else if (change->has_action) + { ExecuteCustomElementAction(x, y, element, p); + PlayLevelSoundElementAction(x, y, element, ACTION_PAGE_1 + p); + } #endif } }