From b21faa39ac22e1987db2bc6158374388e0090dfe Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Wed, 2 Jul 2003 01:04:23 +0200 Subject: [PATCH] rnd-20030702-1-src --- src/conftime.h | 2 +- src/editor.c | 87 ++++++++++++++++++++++----------- src/files.c | 2 + src/game.c | 130 ++++++++++++++++++++++++++++++++++--------------- src/main.h | 25 ++++++---- 5 files changed, 167 insertions(+), 79 deletions(-) diff --git a/src/conftime.h b/src/conftime.h index 951b1d60..36ed663d 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2003-07-01 18:18]" +#define COMPILE_DATE_STRING "[2003-07-02 01:03]" diff --git a/src/editor.c b/src/editor.c index 702fed4d..c235a7c6 100644 --- a/src/editor.c +++ b/src/editor.c @@ -336,9 +336,12 @@ #define GADGET_ID_CHANGE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 48) #define GADGET_ID_CHANGE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 49) #define GADGET_ID_CHANGE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 50) +#define GADGET_ID_CHANGE_CONT_RND_DOWN (GADGET_ID_COUNTER_FIRST + 51) +#define GADGET_ID_CHANGE_CONT_RND_TEXT (GADGET_ID_COUNTER_FIRST + 52) +#define GADGET_ID_CHANGE_CONT_RND_UP (GADGET_ID_COUNTER_FIRST + 53) /* drawing area identifiers */ -#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 51) +#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 54) #define GADGET_ID_DRAWING_LEVEL (GADGET_ID_DRAWING_AREA_FIRST + 0) #define GADGET_ID_ELEMENT_CONTENT_0 (GADGET_ID_DRAWING_AREA_FIRST + 1) @@ -377,7 +380,7 @@ #define GADGET_ID_CUSTOM_ACCESS_LAYER (GADGET_ID_SELECTBOX_FIRST + 8) #define GADGET_ID_CHANGE_TIME_UNITS (GADGET_ID_SELECTBOX_FIRST + 9) #define GADGET_ID_CHANGE_PLAYER_ACTION (GADGET_ID_SELECTBOX_FIRST + 10) -#define GADGET_ID_CHANGE_IMPACT_ACTION (GADGET_ID_SELECTBOX_FIRST + 11) +#define GADGET_ID_CHANGE_COLLIDE_ACTION (GADGET_ID_SELECTBOX_FIRST + 11) #define GADGET_ID_CHANGE_OTHER_ACTION (GADGET_ID_SELECTBOX_FIRST + 12) #define GADGET_ID_CHANGE_POWER (GADGET_ID_SELECTBOX_FIRST + 13) @@ -433,13 +436,14 @@ #define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 21) #define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 22) #define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 23) -#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 24) -#define GADGET_ID_CHANGE_BY_PLAYER (GADGET_ID_CHECKBUTTON_FIRST + 25) -#define GADGET_ID_CHANGE_IMPACT_SMASHED (GADGET_ID_CHECKBUTTON_FIRST + 26) -#define GADGET_ID_CHANGE_BY_OTHER (GADGET_ID_CHECKBUTTON_FIRST + 27) +#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 24) +#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 25) +#define GADGET_ID_CHANGE_BY_PLAYER (GADGET_ID_CHECKBUTTON_FIRST + 26) +#define GADGET_ID_CHANGE_BY_COLLISION (GADGET_ID_CHECKBUTTON_FIRST + 27) +#define GADGET_ID_CHANGE_BY_OTHER (GADGET_ID_CHECKBUTTON_FIRST + 28) /* gadgets for buttons in element list */ -#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 28) +#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 29) #define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \ ED_NUM_ELEMENTLIST_BUTTONS - 1) @@ -468,8 +472,9 @@ #define ED_COUNTER_ID_MOVE_DELAY_RND 14 #define ED_COUNTER_ID_CHANGE_DELAY_FIX 15 #define ED_COUNTER_ID_CHANGE_DELAY_RND 16 +#define ED_COUNTER_ID_CHANGE_CONT_RND 17 -#define ED_NUM_COUNTERBUTTONS 17 +#define ED_NUM_COUNTERBUTTONS 18 #define ED_COUNTER_ID_LEVEL_FIRST ED_COUNTER_ID_LEVEL_XSIZE #define ED_COUNTER_ID_LEVEL_LAST ED_COUNTER_ID_LEVEL_RANDOM @@ -478,7 +483,7 @@ #define ED_COUNTER_ID_CUSTOM_LAST ED_COUNTER_ID_MOVE_DELAY_RND #define ED_COUNTER_ID_CHANGE_FIRST ED_COUNTER_ID_CHANGE_DELAY_FIX -#define ED_COUNTER_ID_CHANGE_LAST ED_COUNTER_ID_CHANGE_DELAY_RND +#define ED_COUNTER_ID_CHANGE_LAST ED_COUNTER_ID_CHANGE_CONT_RND /* values for scrollbutton gadgets */ #define ED_SCROLLBUTTON_ID_AREA_UP 0 @@ -524,7 +529,7 @@ #define ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER 8 #define ED_SELECTBOX_ID_CHANGE_TIME_UNITS 9 #define ED_SELECTBOX_ID_CHANGE_PLAYER_ACTION 10 -#define ED_SELECTBOX_ID_CHANGE_IMPACT_ACTION 11 +#define ED_SELECTBOX_ID_CHANGE_COLLIDE_ACTION 11 #define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION 12 #define ED_SELECTBOX_ID_CHANGE_POWER 13 @@ -567,12 +572,13 @@ #define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 19 #define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 20 #define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 21 -#define ED_CHECKBUTTON_ID_CHANGE_DELAY 22 -#define ED_CHECKBUTTON_ID_CHANGE_BY_PLAYER 23 -#define ED_CHECKBUTTON_ID_CHANGE_IMPACT_SMASHED 24 -#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER 25 +#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 22 +#define ED_CHECKBUTTON_ID_CHANGE_DELAY 23 +#define ED_CHECKBUTTON_ID_CHANGE_BY_PLAYER 24 +#define ED_CHECKBUTTON_ID_CHANGE_BY_COLLISION 25 +#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER 26 -#define ED_NUM_CHECKBUTTONS 26 +#define ED_NUM_CHECKBUTTONS 27 #define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_DOUBLE_SPEED #define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED @@ -841,7 +847,15 @@ static struct GADGET_ID_CHANGE_DELAY_RND_TEXT, &custom_element.change.delay_random, NULL, "+random", NULL - } + }, + { + ED_SETTINGS_XPOS(3), ED_SETTINGS_YPOS(12), + 0, 100, + GADGET_ID_CHANGE_CONT_RND_DOWN, GADGET_ID_CHANGE_CONT_RND_UP, + GADGET_ID_CHANGE_CONT_RND_TEXT, + &custom_element.change.random, + NULL, "use random change:", NULL + }, }; static struct @@ -975,17 +989,20 @@ static struct ValueTextInfo options_change_player_action[] = }; static int value_change_player_action = 0; -static struct ValueTextInfo options_change_impact_action[] = +static struct ValueTextInfo options_change_collide_action[] = { + { CE_COLLISION, "on collision" }, { CE_IMPACT, "on impact" }, { CE_SMASHED, "when smashed" }, { -1, NULL } }; -static int value_change_impact_action = 0; +static int value_change_collide_action = 0; static struct ValueTextInfo options_change_other_action[] = { { CE_OTHER_COLLECTING, "collecting" }, + { CE_OTHER_TOUCHING, "touching" }, + { CE_OTHER_PRESSING, "pressing" }, { CE_OTHER_PUSHING, "pushing" }, { CE_OTHER_CHANGING, "change of" }, { CE_OTHER_EXPLODING, "explosion of" }, @@ -1106,10 +1123,10 @@ static struct }, { ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(6), - GADGET_ID_CHANGE_IMPACT_ACTION, + GADGET_ID_CHANGE_COLLIDE_ACTION, -1, - options_change_impact_action, - &value_change_impact_action, + options_change_collide_action, + &value_change_collide_action, NULL, NULL, "change after impact or smash" }, { @@ -1154,7 +1171,7 @@ static struct 11, "Advanced", "Advanced element configuration" }, { - ED_SETTINGS_XPOS(0) + 262, ED_SETTINGS_YPOS(12), + ED_SETTINGS_XPOS(0) + 262, ED_SETTINGS_YPOS(13), GADGET_ID_SAVE_AS_TEMPLATE, -1, "Save as template", "Save current settings as new template" }, @@ -1409,8 +1426,8 @@ static struct }, { ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(6), - GADGET_ID_CHANGE_IMPACT_SMASHED, - &custom_element_change_events[CE_IMPACT_SMASHED], + GADGET_ID_CHANGE_BY_COLLISION, + &custom_element_change_events[CE_BY_COLLISION], NULL, "element changes by impact or smash" }, { @@ -1438,7 +1455,13 @@ static struct "only use complete change", "only use complete extended content" }, { - ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(12), + ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(12), + GADGET_ID_CHANGE_USE_RANDOM, + &custom_element.change.use_random_change, + NULL, "use random value for new content" + }, + { + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(13), GADGET_ID_CUSTOM_USE_TEMPLATE, &custom_element.use_template, "use template", "use template for custom properties" @@ -3662,16 +3685,19 @@ static void CopyCustomElementPropertiesToEditor(int element) CE_PRESSED_BY_PLAYER); /* set change by impact/smash selectbox help value */ - value_change_impact_action = + value_change_collide_action = (HAS_CHANGE_EVENT(element, CE_SMASHED) ? CE_SMASHED : HAS_CHANGE_EVENT(element, CE_IMPACT) ? CE_IMPACT : - CE_IMPACT); + HAS_CHANGE_EVENT(element, CE_COLLISION) ? CE_COLLISION : + CE_COLLISION); /* set change by other element action selectbox help value */ value_change_other_action = (HAS_CHANGE_EVENT(element, CE_OTHER_EXPLODING) ? CE_OTHER_EXPLODING : HAS_CHANGE_EVENT(element, CE_OTHER_CHANGING) ? CE_OTHER_CHANGING : HAS_CHANGE_EVENT(element, CE_OTHER_PUSHING) ? CE_OTHER_PUSHING : + HAS_CHANGE_EVENT(element, CE_OTHER_PRESSING) ? CE_OTHER_PRESSING : + HAS_CHANGE_EVENT(element, CE_OTHER_TOUCHING) ? CE_OTHER_TOUCHING : HAS_CHANGE_EVENT(element, CE_OTHER_COLLECTING) ? CE_OTHER_COLLECTING : CE_OTHER_COLLECTING); } @@ -3729,13 +3755,16 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_change_events[CE_BY_PLAYER]; /* set player change event from checkbox and selectbox */ + custom_element_change_events[CE_COLLISION] = FALSE; custom_element_change_events[CE_IMPACT] = FALSE; custom_element_change_events[CE_SMASHED] = FALSE; - custom_element_change_events[value_change_impact_action] = - custom_element_change_events[CE_IMPACT_SMASHED]; + custom_element_change_events[value_change_collide_action] = + custom_element_change_events[CE_BY_COLLISION]; /* set other element action change event from checkbox and selectbox */ custom_element_change_events[CE_OTHER_COLLECTING] = FALSE; + custom_element_change_events[CE_OTHER_TOUCHING] = FALSE; + custom_element_change_events[CE_OTHER_PRESSING] = FALSE; custom_element_change_events[CE_OTHER_PUSHING] = FALSE; custom_element_change_events[CE_OTHER_CHANGING] = FALSE; custom_element_change_events[CE_OTHER_EXPLODING] = FALSE; diff --git a/src/files.c b/src/files.c index 16260cc7..a86507f3 100644 --- a/src/files.c +++ b/src/files.c @@ -132,6 +132,8 @@ static void setLevelInfoToDefaults() element_info[element].change.use_content = FALSE; element_info[element].change.only_complete = FALSE; + element_info[element].change.use_random_change = FALSE; + element_info[element].change.random = 0; element_info[element].change.power = CP_NON_DESTRUCTIVE; element_info[element].change.explode = FALSE; diff --git a/src/game.c b/src/game.c index d837dad2..6326b223 100644 --- a/src/game.c +++ b/src/game.c @@ -163,8 +163,10 @@ static void CloseAllOpenTimegates(void); static void CheckGravityMovement(struct PlayerInfo *); static void KillHeroUnlessProtected(int, int); -static void CheckTriggeredElementChange(int, int); -static void CheckPlayerElementChange(int, int, int, int); +static void TestIfPlayerTouchesCustomElement(int, int); + +static boolean CheckTriggeredElementChange(int, int); +static boolean CheckElementChange(int, int, int, int); static void ChangeElementNow(int, int, int); static void PlaySoundLevel(int, int, int); @@ -1711,11 +1713,6 @@ static void RemoveField(int x, int y) MovDir[x][y] = 0; MovDelay[x][y] = 0; -#if 0 - Store[x][y] = 0; - Store2[x][y] = 0; -#endif - AmoebaNr[x][y] = 0; ChangeDelay[x][y] = 0; Pushed[x][y] = FALSE; @@ -1746,7 +1743,6 @@ void RemoveMovingField(int x, int y) return; } -#if 1 if (element == EL_BLOCKED && (Feld[oldx][oldy] == EL_QUICKSAND_EMPTYING || Feld[oldx][oldy] == EL_MAGIC_WALL_EMPTYING || @@ -1757,31 +1753,10 @@ void RemoveMovingField(int x, int y) RemoveField(oldx, oldy); RemoveField(newx, newy); -#if 1 Store[oldx][oldy] = Store2[oldx][oldy] = 0; -#endif if (next_element != EL_UNDEFINED) Feld[oldx][oldy] = next_element; -#else - if (element == EL_BLOCKED && - (Feld[oldx][oldy] == EL_QUICKSAND_EMPTYING || - Feld[oldx][oldy] == EL_MAGIC_WALL_EMPTYING || - Feld[oldx][oldy] == EL_BD_MAGIC_WALL_EMPTYING || - Feld[oldx][oldy] == EL_AMOEBA_DROPPING)) - Feld[oldx][oldy] = get_next_element(Feld[oldx][oldy]); - else - Feld[oldx][oldy] = EL_EMPTY; - - Store[oldx][oldy] = Store2[oldx][oldy] = 0; - - Feld[newx][newy] = EL_EMPTY; - MovPos[oldx][oldy] = MovDir[oldx][oldy] = MovDelay[oldx][oldy] = 0; - MovPos[newx][newy] = MovDir[newx][newy] = MovDelay[newx][newy] = 0; - ChangeDelay[oldx][oldy] = ChangeDelay[newx][newy] = 0; - Pushed[oldx][oldy] = Pushed[newx][newy] = FALSE; - GfxAction[oldx][oldy] = GfxAction[newx][newy] = ACTION_DEFAULT; -#endif DrawLevelField(oldx, oldy); DrawLevelField(newx, newy); @@ -2620,6 +2595,14 @@ void Impact(int x, int y) PlaySoundLevel(x, y, SND_PEARL_BREAKING); return; } +#if 1 + else if (impact && CheckElementChange(x, y, element, ACTION_IMPACT)) + { + PlaySoundLevelElementAction(x, y, element, ACTION_IMPACT); + + return; + } +#else else if (impact && CAN_CHANGE(element) && HAS_CHANGE_EVENT(element, CE_IMPACT)) { @@ -2629,6 +2612,7 @@ void Impact(int x, int y) return; } +#endif if (impact && element == EL_AMOEBA_DROP) { @@ -2753,11 +2737,21 @@ void Impact(int x, int y) { ToggleLightSwitch(x, y + 1); } - else if (CAN_CHANGE(smashed) && - HAS_CHANGE_EVENT(smashed, CE_SMASHED)) +#if 1 + else + { + CheckElementChange(x, y + 1, smashed, CE_SMASHED); + } +#else + else if (CAN_CHANGE(smashed) && HAS_CHANGE_EVENT(smashed, CE_SMASHED)) { ChangeElementNow(x, y + 1, smashed); } +#endif + } + else + { + CheckElementChange(x, y + 1, smashed, CE_SMASHED); } } } @@ -3974,6 +3968,7 @@ void ContinueMoving(int x, int y) int dy = (direction == MV_UP ? -1 : direction == MV_DOWN ? +1 : 0); int horiz_move = (dx != 0); int newx = x + dx, newy = y + dy; + int nextx = newx + dx, nexty = newy + dy; int step = (horiz_move ? dx : dy) * TILEX / MOVE_DELAY_NORMAL_SPEED; #if 1 boolean pushed = Pushed[x][y]; @@ -4201,6 +4196,20 @@ void ContinueMoving(int x, int y) if (CAN_SMASH(element) && direction == MV_DOWN && (newy == lev_fieldy - 1 || !IS_FREE(x, newy + 1))) Impact(x, newy); +#endif + +#if 0 + if (!IN_LEV_FIELD(nextx, nexty) || !IS_FREE(nextx, nexty)) + CheckTriggeredElementChange(element, CE_COLLISION); +#else +#if 1 + if (!IN_LEV_FIELD(nextx, nexty) || !IS_FREE(nextx, nexty)) + CheckElementChange(newx, newy, element, CE_COLLISION); +#else + if ((!IN_LEV_FIELD(nextx, nexty) || !IS_FREE(nextx, nexty)) && + CAN_CHANGE(element) && HAS_CHANGE_EVENT(element, CE_COLLISION)) + ChangeElementNow(newx, newy, element); +#endif #endif } else /* still moving on */ @@ -5203,12 +5212,17 @@ static void ChangeElementNow(int x, int y, int element) if (!change->only_complete || complete_change) { + if (change->only_complete && change->use_random_change && + RND(change->random) != 0) + return; + for (yy = 0; yy < 3; yy++) for(xx = 0; xx < 3 ; xx++) { int ex = x + xx - 1; int ey = y + yy - 1; - if (can_change[xx][yy]) + if (can_change[xx][yy] && (!change->use_random_change || + RND(change->random) == 0)) { ChangeElementNowExt(ex, ey, change->content[xx][yy]); @@ -5227,7 +5241,11 @@ static void ChangeElementNow(int x, int y, int element) static void ChangeElement(int x, int y) { +#if 1 + int element = MovingOrBlocked2Element(x, y); +#else int element = Feld[x][y]; +#endif struct ElementChangeInfo *change = &element_info[element].change; if (ChangeDelay[x][y] == 0) /* initialize element change */ @@ -5306,12 +5324,13 @@ static void ChangeElement(int x, int y) } } -static void CheckTriggeredElementChange(int trigger_element, int trigger_event) +static boolean CheckTriggeredElementChange(int trigger_element, + int trigger_event) { int i, x, y; if (!(trigger_events[trigger_element] & CH_EVENT_BIT(trigger_event))) - return; + return FALSE; for (i=0; iactive) RemoveHero(player); @@ -6368,6 +6394,31 @@ void ScrollScreen(struct PlayerInfo *player, int mode) ScreenMovDir = MV_NO_MOVING; } +void TestIfPlayerTouchesCustomElement(int x, int y) +{ + static int xy[4][2] = + { + { 0, -1 }, + { -1, 0 }, + { +1, 0 }, + { 0, +1 } + }; + boolean center_is_player = (IS_PLAYER(x, y)); + int i; + + for (i=0; i<4; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + + if (center_is_player && IN_LEV_FIELD(xx, yy)) + { + CheckTriggeredElementChange(Feld[xx][yy], CE_OTHER_TOUCHING); + CheckElementChange(xx, yy, Feld[xx][yy], CE_TOUCHED_BY_PLAYER); + } + } +} + void TestIfGoodThingHitsBadThing(int good_x, int good_y, int good_move_dir) { int i, kill_x = -1, kill_y = -1; @@ -7206,13 +7257,14 @@ int DigField(struct PlayerInfo *player, player->push_delay_value = GET_NEW_PUSH_DELAY(element); CheckTriggeredElementChange(element, CE_OTHER_PUSHING); - CheckPlayerElementChange(x, y, element, CE_PUSHED_BY_PLAYER); + CheckElementChange(x, y, element, CE_PUSHED_BY_PLAYER); break; } else { - CheckPlayerElementChange(x, y, element, CE_PRESSED_BY_PLAYER); + CheckTriggeredElementChange(element, CE_OTHER_PRESSING); + CheckElementChange(x, y, element, CE_PRESSED_BY_PLAYER); } return MF_NO_ACTION; diff --git a/src/main.h b/src/main.h index 1108cbf7..4340d7c6 100644 --- a/src/main.h +++ b/src/main.h @@ -159,19 +159,22 @@ #define CE_TOUCHED_BY_PLAYER 1 #define CE_PRESSED_BY_PLAYER 2 #define CE_PUSHED_BY_PLAYER 3 -#define CE_IMPACT 4 -#define CE_SMASHED 5 -#define CE_OTHER_COLLECTING 6 -#define CE_OTHER_PUSHING 7 -#define CE_OTHER_CHANGING 8 -#define CE_OTHER_EXPLODING 9 +#define CE_COLLISION 4 +#define CE_IMPACT 5 +#define CE_SMASHED 6 +#define CE_OTHER_COLLECTING 7 +#define CE_OTHER_TOUCHING 8 +#define CE_OTHER_PRESSING 9 +#define CE_OTHER_PUSHING 10 +#define CE_OTHER_CHANGING 11 +#define CE_OTHER_EXPLODING 12 /* values for internal purpose only (level editor) */ -#define CE_BY_PLAYER 10 -#define CE_IMPACT_SMASHED 11 -#define CE_BY_OTHER 12 +#define CE_BY_PLAYER 13 +#define CE_BY_COLLISION 14 +#define CE_BY_OTHER 15 -#define NUM_CHANGE_EVENTS 13 +#define NUM_CHANGE_EVENTS 16 #define CE_BITMASK_DEFAULT 0 @@ -1182,6 +1185,8 @@ struct ElementChangeInfo int content[3][3]; /* new elements after extended change */ boolean use_content; /* use extended change content */ boolean only_complete; /* only use complete content */ + boolean use_random_change; /* use random value for setting content */ + int random; /* random value for setting content */ int power; /* power of extended change */ boolean explode; /* explode instead of change */ -- 2.34.1