From 1903a68d7b7917ed45655391ecf5aaf995124eff Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sat, 14 Jun 2003 03:02:14 +0200 Subject: [PATCH] rnd-20030614-1-src --- src/conftime.h | 2 +- src/editor.c | 190 +++++++++++++++++++++++++++++++++++++------------ src/events.c | 1 + src/game.c | 104 +++++++++++++++++++++------ src/main.c | 8 ++- src/main.h | 42 +++++++---- 6 files changed, 264 insertions(+), 83 deletions(-) diff --git a/src/conftime.h b/src/conftime.h index f453ceee..a416ad13 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2003-06-10 23:15]" +#define COMPILE_DATE_STRING "[2003-06-14 02:58]" diff --git a/src/editor.c b/src/editor.c index afd0a884..72042752 100644 --- a/src/editor.c +++ b/src/editor.c @@ -105,26 +105,26 @@ n * ED_COUNTER_YDISTANCE - 2) /* values for element content drawing areas */ +/* amoeba content */ #define ED_AREA_ELEM_CONTENT_XPOS ( 2 * MINI_TILEX) #define ED_AREA_ELEM_CONTENT_YPOS (22 * MINI_TILEY) +/* custom change target */ #define ED_AREA_ELEM_CONTENT2_XPOS (20 * MINI_TILEX) #define ED_AREA_ELEM_CONTENT2_YPOS (ED_SETTINGS_YPOS(2) + \ ED_GADGET_DISTANCE) - +/* optional custom graphic */ #define ED_AREA_ELEM_CONTENT3_XPOS (24 * MINI_TILEX) #define ED_AREA_ELEM_CONTENT3_YPOS (ED_SETTINGS_YPOS(1) + \ ED_GADGET_DISTANCE) - -#if 1 +/* custom element content */ #define ED_AREA_ELEM_CONTENT4_XPOS (29 * MINI_TILEX) #define ED_AREA_ELEM_CONTENT4_YPOS (ED_SETTINGS_YPOS(2) + \ ED_GADGET_DISTANCE - MINI_TILEY) -#else -#define ED_AREA_ELEM_CONTENT4_XPOS (17 * MINI_TILEX) -#define ED_AREA_ELEM_CONTENT4_YPOS (ED_SETTINGS_YPOS(11) + \ - ED_GADGET_DISTANCE - MINI_TILEY) -#endif +/* custom change trigger element */ +#define ED_AREA_ELEM_CONTENT5_XPOS (29 * MINI_TILEX) +#define ED_AREA_ELEM_CONTENT5_YPOS (ED_SETTINGS_YPOS(7) + \ + ED_GADGET_DISTANCE) /* values for random placement background drawing area */ #define ED_AREA_RANDOM_BACKGROUND_XPOS (29 * MINI_TILEX) @@ -345,11 +345,12 @@ #define GADGET_ID_AMOEBA_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 9) #define GADGET_ID_CUSTOM_GRAPHIC (GADGET_ID_DRAWING_AREA_FIRST + 10) #define GADGET_ID_CUSTOM_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 11) -#define GADGET_ID_CUSTOM_CHANGED (GADGET_ID_DRAWING_AREA_FIRST + 12) -#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 13) +#define GADGET_ID_CUSTOM_CHANGE_TARGET (GADGET_ID_DRAWING_AREA_FIRST + 12) +#define GADGET_ID_CUSTOM_CHANGE_TRIGGER (GADGET_ID_DRAWING_AREA_FIRST + 13) +#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 14) /* text input identifiers */ -#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 14) +#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 15) #define GADGET_ID_LEVEL_NAME (GADGET_ID_TEXT_INPUT_FIRST + 0) #define GADGET_ID_LEVEL_AUTHOR (GADGET_ID_TEXT_INPUT_FIRST + 1) @@ -367,10 +368,11 @@ #define GADGET_ID_CUSTOM_WALKABLE_LAYER (GADGET_ID_SELECTBOX_FIRST + 7) #define GADGET_ID_CHANGE_TIME_UNITS (GADGET_ID_SELECTBOX_FIRST + 8) #define GADGET_ID_CHANGE_PLAYER_ACTION (GADGET_ID_SELECTBOX_FIRST + 9) -#define GADGET_ID_CHANGE_CAUSE (GADGET_ID_SELECTBOX_FIRST + 10) +#define GADGET_ID_CHANGE_IMPACT_ACTION (GADGET_ID_SELECTBOX_FIRST + 10) +#define GADGET_ID_CHANGE_OTHER_ACTION (GADGET_ID_SELECTBOX_FIRST + 11) /* textbutton identifiers */ -#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 11) +#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 12) #define GADGET_ID_PROPERTIES_INFO (GADGET_ID_TEXTBUTTON_FIRST + 0) #define GADGET_ID_PROPERTIES_CONFIG (GADGET_ID_TEXTBUTTON_FIRST + 1) @@ -420,9 +422,11 @@ #define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 20) #define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 21) #define GADGET_ID_CHANGE_BY_PLAYER (GADGET_ID_CHECKBUTTON_FIRST + 22) +#define GADGET_ID_CHANGE_IMPACT_SMASHED (GADGET_ID_CHECKBUTTON_FIRST + 23) +#define GADGET_ID_CHANGE_BY_OTHER (GADGET_ID_CHECKBUTTON_FIRST + 24) /* gadgets for buttons in element list */ -#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 23) +#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 25) #define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \ ED_NUM_ELEMENTLIST_BUTTONS - 1) @@ -505,15 +509,16 @@ #define ED_SELECTBOX_ID_CUSTOM_WALKABLE_LAYER 7 #define ED_SELECTBOX_ID_CHANGE_TIME_UNITS 8 #define ED_SELECTBOX_ID_CHANGE_PLAYER_ACTION 9 -#define ED_SELECTBOX_ID_CHANGE_CAUSE 10 +#define ED_SELECTBOX_ID_CHANGE_IMPACT_ACTION 10 +#define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION 11 -#define ED_NUM_SELECTBOX 11 +#define ED_NUM_SELECTBOX 12 #define ED_SELECTBOX_ID_CUSTOM_FIRST ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION #define ED_SELECTBOX_ID_CUSTOM_LAST ED_SELECTBOX_ID_CUSTOM_WALKABLE_LAYER #define ED_SELECTBOX_ID_CHANGE_FIRST ED_SELECTBOX_ID_CHANGE_TIME_UNITS -#define ED_SELECTBOX_ID_CHANGE_LAST ED_SELECTBOX_ID_CHANGE_CAUSE +#define ED_SELECTBOX_ID_CHANGE_LAST ED_SELECTBOX_ID_CHANGE_OTHER_ACTION /* values for textbutton gadgets */ #define ED_TEXTBUTTON_ID_PROPERTIES_INFO 0 @@ -545,8 +550,10 @@ #define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 18 #define ED_CHECKBUTTON_ID_CHANGE_DELAY 19 #define ED_CHECKBUTTON_ID_CHANGE_BY_PLAYER 20 +#define ED_CHECKBUTTON_ID_CHANGE_IMPACT_SMASHED 21 +#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER 22 -#define ED_NUM_CHECKBUTTONS 21 +#define ED_NUM_CHECKBUTTONS 23 #define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_DOUBLE_SPEED #define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED @@ -555,7 +562,7 @@ #define ED_CHECKBUTTON_ID_CUSTOM_LAST ED_CHECKBUTTON_ID_CUSTOM_WALKABLE #define ED_CHECKBUTTON_ID_CHANGE_FIRST ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC -#define ED_CHECKBUTTON_ID_CHANGE_LAST ED_CHECKBUTTON_ID_CHANGE_BY_PLAYER +#define ED_CHECKBUTTON_ID_CHANGE_LAST ED_CHECKBUTTON_ID_CHANGE_BY_OTHER /* values for radiobutton gadgets */ #define ED_RADIOBUTTON_ID_PERCENTAGE 0 @@ -909,22 +916,29 @@ static struct ValueTextInfo options_time_units[] = static struct ValueTextInfo options_change_player_action[] = { - { CE_PRESSED_BY_PLAYER, "pressed" }, { CE_TOUCHED_BY_PLAYER, "touched" }, + { CE_PRESSED_BY_PLAYER, "pressed" }, + { CE_PUSHED_BY_PLAYER, "pushed" }, { -1, NULL } }; static int value_change_player_action = 0; -static struct ValueTextInfo options_change_cause[] = +static struct ValueTextInfo options_change_impact_action[] = { - { 1, "specified delay" }, - { 2, "impact (active)" }, - { 3, "impact (passive)" }, - { 4, "touched by player" }, - { 5, "pressed by player" }, + { CE_IMPACT, "on impact" }, + { CE_SMASHED, "when smashed" }, { -1, NULL } }; -static int value_change_cause = 0; +static int value_change_impact_action = 0; + +static struct ValueTextInfo options_change_other_action[] = +{ + { CE_OTHER_COLLECTING, "collecting" }, + { CE_OTHER_PUSHING, "pushing" }, + { CE_OTHER_CHANGING, "change of" }, + { -1, NULL } +}; +static int value_change_other_action = 0; static struct { @@ -1017,12 +1031,20 @@ static struct NULL, "by player", "type of player contact" }, { - ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(10), - GADGET_ID_CHANGE_CAUSE, + ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(6), + GADGET_ID_CHANGE_IMPACT_ACTION, + -1, + options_change_impact_action, + &value_change_impact_action, + NULL, NULL, "change after impact or smash" + }, + { + ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(7), + GADGET_ID_CHANGE_OTHER_ACTION, -1, - options_change_cause, - &value_change_cause, - "test:", NULL, "test-selectbox entry" + options_change_other_action, + &value_change_other_action, + NULL, "other element:", "type of other element action" }, }; @@ -1298,6 +1320,18 @@ static struct &custom_element_change_events[CE_BY_PLAYER], NULL, "element changes by player contact" }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(6), + GADGET_ID_CHANGE_IMPACT_SMASHED, + &custom_element_change_events[CE_IMPACT_SMASHED], + NULL, "element changes by impact or smash" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(7), + GADGET_ID_CHANGE_BY_OTHER, + &custom_element_change_events[CE_BY_OTHER], + NULL, "element changes by other element" + }, }; @@ -2729,7 +2763,7 @@ static void CreateDrawingAreas() level_editor_gadget[id] = gi; /* ... one for each custom element change target element ... */ - id = GADGET_ID_CUSTOM_CHANGED; + id = GADGET_ID_CUSTOM_CHANGE_TARGET; gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_X, SX + ED_AREA_ELEM_CONTENT2_XPOS, GDI_Y, SY + ED_AREA_ELEM_CONTENT2_YPOS, @@ -2747,8 +2781,26 @@ static void CreateDrawingAreas() level_editor_gadget[id] = gi; - /* ... and one for random placement background restrictions */ + /* ... one for each custom element change trigger element ... */ + id = GADGET_ID_CUSTOM_CHANGE_TRIGGER; + gi = CreateGadget(GDI_CUSTOM_ID, id, + GDI_X, SX + ED_AREA_ELEM_CONTENT5_XPOS, + GDI_Y, SY + ED_AREA_ELEM_CONTENT5_YPOS, + GDI_WIDTH, MINI_TILEX, + GDI_HEIGHT, MINI_TILEY, + GDI_TYPE, GD_TYPE_DRAWING_AREA, + GDI_ITEM_SIZE, MINI_TILEX, MINI_TILEY, + GDI_EVENT_MASK, event_mask, + GDI_CALLBACK_INFO, HandleDrawingAreaInfo, + GDI_CALLBACK_ACTION, HandleDrawingAreas, + GDI_END); + if (gi == NULL) + Error(ERR_EXIT, "cannot create gadget"); + + level_editor_gadget[id] = gi; + + /* ... and one for random placement background restrictions */ id = GADGET_ID_RANDOM_BACKGROUND; gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_X, SX + ED_AREA_RANDOM_BACKGROUND_XPOS, @@ -3469,9 +3521,16 @@ static void CopyCustomElementPropertiesToEditor(int element) /* set change by player selectbox help value */ value_change_player_action = - (HAS_CHANGE_EVENT(element, CE_TOUCHED_BY_PLAYER) ? CE_TOUCHED_BY_PLAYER : + (HAS_CHANGE_EVENT(element, CE_PUSHED_BY_PLAYER) ? CE_PUSHED_BY_PLAYER : HAS_CHANGE_EVENT(element, CE_PRESSED_BY_PLAYER) ? CE_PRESSED_BY_PLAYER : + HAS_CHANGE_EVENT(element, CE_TOUCHED_BY_PLAYER) ? CE_TOUCHED_BY_PLAYER : CE_PRESSED_BY_PLAYER); + + /* set change by impact/smash selectbox help value */ + value_change_impact_action = + (HAS_CHANGE_EVENT(element, CE_SMASHED) ? CE_SMASHED : + HAS_CHANGE_EVENT(element, CE_IMPACT) ? CE_IMPACT : + CE_IMPACT); } static void CopyCustomElementPropertiesToGame(int element) @@ -3515,10 +3574,16 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_properties[EP_WALKABLE]; /* set player change event from checkbox and selectbox */ - custom_element.change.events &= ~CE_PRESSED_BY_PLAYER; custom_element.change.events &= ~CE_TOUCHED_BY_PLAYER; + custom_element.change.events &= ~CE_PRESSED_BY_PLAYER; + custom_element.change.events &= ~CE_PUSHED_BY_PLAYER; custom_element.change.events |= value_change_player_action; + /* set player change event from checkbox and selectbox */ + custom_element.change.events &= ~CE_IMPACT; + custom_element.change.events &= ~CE_SMASHED; + custom_element.change.events |= value_change_impact_action; + for (i=0; i < NUM_ELEMENT_PROPERTIES; i++) SET_PROPERTY(element, i, custom_element_properties[i]); @@ -3936,9 +4001,9 @@ static void DrawCustomContentArea() MapDrawingArea(GADGET_ID_CUSTOM_CONTENT); } -static void DrawCustomChangedArea() +static void DrawCustomChangeTargetArea() { - struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CHANGED]; + struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CHANGE_TARGET]; int xpos = ED_AREA_ELEM_CONTENT2_XPOS; int ypos = ED_AREA_ELEM_CONTENT2_YPOS; int area_sx = SX + xpos; @@ -3956,7 +4021,30 @@ static void DrawCustomChangedArea() DrawMiniGraphicExt(drawto, gi->x, gi->y, el2edimg(custom_element.change.successor)); - MapDrawingArea(GADGET_ID_CUSTOM_CHANGED); + MapDrawingArea(GADGET_ID_CUSTOM_CHANGE_TARGET); +} + +static void DrawCustomChangeTriggerArea() +{ + struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CHANGE_TRIGGER]; + int xpos = ED_AREA_ELEM_CONTENT5_XPOS; + int ypos = ED_AREA_ELEM_CONTENT5_YPOS; + int area_sx = SX + xpos; + int area_sy = SY + ypos; + + if (!IS_CUSTOM_ELEMENT(properties_element)) + { + /* this should never happen */ + Error(ERR_WARN, "element %d is no custom element", properties_element); + + return; + } + + DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY, TRUE); + DrawMiniGraphicExt(drawto, gi->x, gi->y, + el2edimg(custom_element.change.trigger)); + + MapDrawingArea(GADGET_ID_CUSTOM_CHANGE_TRIGGER); } static void DrawElementContentAreas() @@ -4520,7 +4608,8 @@ static void DrawPropertiesAdvanced() /* draw drawing area gadgets */ DrawCustomGraphicElementArea(); - DrawCustomChangedArea(); + DrawCustomChangeTargetArea(); + DrawCustomChangeTriggerArea(); } static void DrawElementName(int x, int y, int element) @@ -5362,11 +5451,16 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) custom_element.content[sx][sy] = new_element; element_info[properties_element] = custom_element; } - else if (id == GADGET_ID_CUSTOM_CHANGED) + else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET) { custom_element.change.successor = new_element; element_info[properties_element] = custom_element; } + else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) + { + custom_element.change.trigger = new_element; + element_info[properties_element] = custom_element; + } else if (id == GADGET_ID_RANDOM_BACKGROUND) random_placement_background_element = new_element; else if (id >= GADGET_ID_ELEMENT_CONTENT_0 && @@ -5477,8 +5571,10 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) PickDrawingElement(button, custom_element.gfx_element); else if (id == GADGET_ID_CUSTOM_CONTENT) PickDrawingElement(button, custom_element.content[sx][sy]); - else if (id == GADGET_ID_CUSTOM_CHANGED) + else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET) PickDrawingElement(button, custom_element.change.successor); + else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) + PickDrawingElement(button, custom_element.change.trigger); else if (id == GADGET_ID_RANDOM_BACKGROUND) PickDrawingElement(button, random_placement_background_element); else if (id >= GADGET_ID_ELEMENT_CONTENT_0 && @@ -6207,9 +6303,12 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) else if (id == GADGET_ID_CUSTOM_CONTENT) DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", getElementInfoText(custom_element.content[sx][sy])); - else if (id == GADGET_ID_CUSTOM_CHANGED) + else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET) DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", getElementInfoText(custom_element.change.successor)); + else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "%s", getElementInfoText(custom_element.change.trigger)); else if (id == GADGET_ID_RANDOM_BACKGROUND) DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", getElementInfoText(random_placement_background_element)); @@ -6233,9 +6332,12 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) else if (id == GADGET_ID_CUSTOM_CONTENT) DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "Custom element content position: %d, %d", sx, sy); - else if (id == GADGET_ID_CUSTOM_CHANGED) + else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET) DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "New element after change"); + else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "Other element triggering change"); else if (id == GADGET_ID_RANDOM_BACKGROUND) DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "Random placement background"); diff --git a/src/events.c b/src/events.c index 619a7f13..5dbf4cd6 100644 --- a/src/events.c +++ b/src/events.c @@ -432,6 +432,7 @@ void HandleButton(int mx, int my, int button) printf(" MovPos[%d][%d] == %d\n", x,y, MovPos[x][y]); printf(" MovDir[%d][%d] == %d\n", x,y, MovDir[x][y]); printf(" MovDelay[%d][%d] == %d\n", x,y, MovDelay[x][y]); + printf(" ChangeDelay[%d][%d] == %d\n", x,y, ChangeDelay[x][y]); printf(" GfxElement[%d][%d] == %d\n", x,y, GfxElement[x][y]); printf("\n"); } diff --git a/src/game.c b/src/game.c index abd3bd4b..d0ffb3d2 100644 --- a/src/game.c +++ b/src/game.c @@ -835,6 +835,7 @@ void InitGame() { Feld[x][y] = Ur[x][y]; MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0; + ChangeDelay[x][y] = 0; Store[x][y] = Store2[x][y] = StorePlayer[x][y] = Back[x][y] = 0; AmoebaNr[x][y] = 0; JustStopped[x][y] = 0; @@ -1530,6 +1531,7 @@ static void RemoveField(int x, int y) MovPos[x][y] = 0; MovDir[x][y] = 0; MovDelay[x][y] = 0; + ChangeDelay[x][y] = 0; } void RemoveMovingField(int x, int y) @@ -1566,6 +1568,7 @@ void RemoveMovingField(int x, int y) 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; GfxAction[oldx][oldy] = GfxAction[newx][newy] = ACTION_DEFAULT; DrawLevelField(oldx, oldy); @@ -1846,7 +1849,7 @@ void Explode(int ex, int ey, int phase, int mode) element = Feld[x][y] = Back[x][y]; Back[x][y] = 0; - MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0; + MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = ChangeDelay[x][y] = 0; InitField(x, y, FALSE); if (CAN_MOVE(element)) InitMovDir(x, y); @@ -2358,7 +2361,7 @@ void Impact(int x, int y) Bang(x, y); return; } - else if (element == EL_PEARL) + else if (impact && element == EL_PEARL) { Feld[x][y] = EL_PEARL_BREAKING; PlaySoundLevel(x, y, SND_PEARL_BREAKING); @@ -2467,7 +2470,11 @@ void Impact(int x, int y) Bang(x, y + 1); return; } +#if 1 + else if (!IS_MOVING(x, y + 1) && !IS_BLOCKED(x, y + 1)) +#else else if (!IS_MOVING(x, y + 1)) +#endif { if (smashed == EL_LAMP || smashed == EL_LAMP_ACTIVE) @@ -2490,7 +2497,11 @@ void Impact(int x, int y) } else if (smashed == EL_DIAMOND) { +#if 1 + Feld[x][y+1] = EL_DIAMOND_BREAKING; +#else Feld[x][y+1] = EL_EMPTY; +#endif PlaySoundLevel(x, y, SND_DIAMOND_BREAKING); return; } @@ -3282,7 +3293,7 @@ void StartMoving(int x, int y) started_moving = TRUE; } } - else if (IS_FREE(x, y+1)) + else if (IS_FREE(x, y+1) || Feld[x][y+1] == EL_DIAMOND_BREAKING) { if (JustStopped[x][y]) /* prevent animation from being restarted */ MovDir[x][y] = MV_DOWN; @@ -3764,6 +3775,7 @@ void ContinueMoving(int x, int y) { Feld[x][y] = EL_EMPTY; Feld[newx][newy] = element; + MovPos[x][y] = 0; /* force "not moving" for "crumbled sand" */ if (element == EL_MOLE) { @@ -3843,6 +3855,9 @@ void ContinueMoving(int x, int y) MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0; MovDelay[newx][newy] = 0; + /* copy element change control values to new field */ + ChangeDelay[newx][newy] = ChangeDelay[x][y]; + /* copy animation control values to new field */ GfxFrame[newx][newy] = GfxFrame[x][y]; GfxAction[newx][newy] = GfxAction[x][y]; /* keep action one frame */ @@ -4381,7 +4396,7 @@ void Life(int ax, int ay) static void InitRobotWheel(int x, int y) { - MovDelay[x][y] = level.time_wheel * FRAMES_PER_SECOND; + ChangeDelay[x][y] = level.time_wheel * FRAMES_PER_SECOND; } static void RunRobotWheel(int x, int y) @@ -4397,7 +4412,7 @@ static void StopRobotWheel(int x, int y) static void InitTimegateWheel(int x, int y) { - MovDelay[x][y] = level.time_wheel * FRAMES_PER_SECOND; + ChangeDelay[x][y] = level.time_wheel * FRAMES_PER_SECOND; } static void RunTimegateWheel(int x, int y) @@ -4723,7 +4738,7 @@ static void InitBuggyBase(int x, int y) int element = Feld[x][y]; int activating_delay = FRAMES_PER_SECOND / 4; - MovDelay[x][y] = + ChangeDelay[x][y] = (element == EL_SP_BUGGY_BASE ? 2 * FRAMES_PER_SECOND + RND(5 * FRAMES_PER_SECOND) - activating_delay : element == EL_SP_BUGGY_BASE_ACTIVATING ? @@ -4758,7 +4773,7 @@ static void WarnBuggyBase(int x, int y) static void InitTrap(int x, int y) { - MovDelay[x][y] = 2 * FRAMES_PER_SECOND + RND(5 * FRAMES_PER_SECOND); + ChangeDelay[x][y] = 2 * FRAMES_PER_SECOND + RND(5 * FRAMES_PER_SECOND); } static void ActivateTrap(int x, int y) @@ -4779,19 +4794,16 @@ static void ChangeElement(int x, int y) { int element = Feld[x][y]; - if (IS_MOVING(x, y)) /* never change a running system :-) */ - return; - - if (MovDelay[x][y] == 0) /* initialize element change */ + if (ChangeDelay[x][y] == 0) /* initialize element change */ { - MovDelay[x][y] = changing_element[element].change_delay + 1; + ChangeDelay[x][y] = changing_element[element].change_delay + 1; if (IS_CUSTOM_ELEMENT(element) && HAS_CHANGE_EVENT(element, CE_DELAY)) { int max_random_delay = element_info[element].change.delay_random; int delay_frames = element_info[element].change.delay_frames; - MovDelay[x][y] += RND(max_random_delay * delay_frames); + ChangeDelay[x][y] += RND(max_random_delay * delay_frames); } ResetGfxAnimation(x, y); @@ -4801,30 +4813,68 @@ static void ChangeElement(int x, int y) changing_element[element].pre_change_function(x, y); } - MovDelay[x][y]--; + ChangeDelay[x][y]--; - if (MovDelay[x][y] != 0) /* continue element change */ + if (ChangeDelay[x][y] != 0) /* continue element change */ { - if (IS_ANIMATED(el2img(element))) - DrawLevelElementAnimationIfNeeded(x, y, element); + int graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]); + + if (IS_ANIMATED(graphic)) + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); if (changing_element[element].change_function) changing_element[element].change_function(x, y); } else /* finish element change */ { + if (IS_MOVING(x, y)) /* never change a running system ;-) */ + { + ChangeDelay[x][y] = 1; /* try change after next move step */ + + return; + } + + RemoveField(x, y); Feld[x][y] = changing_element[element].next_element; ResetGfxAnimation(x, y); ResetRandomAnimationValue(x, y); -#if 1 InitField(x, y, FALSE); - if (CAN_MOVE(element)) + if (CAN_MOVE(Feld[x][y])) InitMovDir(x, y); -#endif + DrawLevelField(x, y); + if (CAN_BE_CRUMBLED(Feld[x][y])) + { + int sx = SCREENX(x), sy = SCREENY(y); + static int xy[4][2] = + { + { 0, -1 }, + { -1, 0 }, + { +1, 0 }, + { 0, +1 } + }; + int i; + + for(i=0; i<4; i++) + { + int xx = x + xy[i][0]; + int yy = y + xy[i][1]; + int sxx = sx + xy[i][0]; + int syy = sy + xy[i][1]; + + if (!IN_LEV_FIELD(xx, yy) || + !IN_SCR_FIELD(sxx, syy) || + !CAN_BE_CRUMBLED(Feld[xx][yy]) || + IS_MOVING(xx, yy)) + continue; + + DrawLevelField(xx, yy); + } + } + if (changing_element[element].post_change_function) changing_element[element].post_change_function(x, y); } @@ -5060,6 +5110,16 @@ void GameActions() continue; } +#if 1 + /* this may take place after moving, so 'element' may have changed */ + if (IS_AUTO_CHANGING(element)) + { + ChangeElement(x, y); + element = Feld[x][y]; + graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]); + } +#endif + if (!IS_MOVING(x, y) && (CAN_FALL(element) || CAN_MOVE(element))) { StartMoving(x, y); @@ -5145,8 +5205,8 @@ void GameActions() else if (IS_ANIMATED(graphic) && !IS_AUTO_CHANGING(element)) DrawLevelGraphicAnimationIfNeeded(x, y, graphic); -#if 1 - /* this may take place after moving, therefore element may have changed */ +#if 0 + /* this may take place after moving, so 'element' may have changed */ if (IS_AUTO_CHANGING(Feld[x][y])) ChangeElement(x, y); #endif diff --git a/src/main.c b/src/main.c index a9387025..a14350b8 100644 --- a/src/main.c +++ b/src/main.c @@ -44,6 +44,7 @@ short Ur[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; +short ChangeDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; @@ -2797,7 +2798,12 @@ struct ElementInfo element_info[MAX_NUM_ELEMENTS + 1] = "-" }, { - "acid_splash_left", + "nut_breaking", + "-", + "-" + }, + { + "diamond_breaking", "-", "-" }, diff --git a/src/main.h b/src/main.h index ec1f8f6d..594f1b82 100644 --- a/src/main.h +++ b/src/main.h @@ -155,13 +155,21 @@ /* values for change events for custom elements */ #define CE_DELAY 0 -#define CE_PRESSED_BY_PLAYER 1 -#define CE_TOUCHED_BY_PLAYER 2 +#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 /* values for internal purpose only (level editor) */ -#define CE_BY_PLAYER 3 +#define CE_BY_PLAYER 9 +#define CE_IMPACT_SMASHED 10 +#define CE_BY_OTHER 11 -#define NUM_CHANGE_EVENTS 4 +#define NUM_CHANGE_EVENTS 12 #define CE_BITMASK_DEFAULT 0 @@ -749,19 +757,20 @@ #define EL_BLOCKED (EL_FIRST_RUNTIME_UNREAL + 0) #define EL_EXPLOSION (EL_FIRST_RUNTIME_UNREAL + 1) #define EL_NUT_BREAKING (EL_FIRST_RUNTIME_UNREAL + 2) -#define EL_ACID_SPLASH_LEFT (EL_FIRST_RUNTIME_UNREAL + 3) -#define EL_ACID_SPLASH_RIGHT (EL_FIRST_RUNTIME_UNREAL + 4) -#define EL_AMOEBA_GROWING (EL_FIRST_RUNTIME_UNREAL + 5) -#define EL_AMOEBA_SHRINKING (EL_FIRST_RUNTIME_UNREAL + 6) -#define EL_EXPANDABLE_WALL_GROWING (EL_FIRST_RUNTIME_UNREAL + 7) -#define EL_FLAMES (EL_FIRST_RUNTIME_UNREAL + 8) -#define EL_PLAYER_IS_LEAVING (EL_FIRST_RUNTIME_UNREAL + 9) -#define EL_QUICKSAND_FILLING (EL_FIRST_RUNTIME_UNREAL + 10) -#define EL_MAGIC_WALL_FILLING (EL_FIRST_RUNTIME_UNREAL + 11) -#define EL_BD_MAGIC_WALL_FILLING (EL_FIRST_RUNTIME_UNREAL + 12) +#define EL_DIAMOND_BREAKING (EL_FIRST_RUNTIME_UNREAL + 3) +#define EL_ACID_SPLASH_LEFT (EL_FIRST_RUNTIME_UNREAL + 4) +#define EL_ACID_SPLASH_RIGHT (EL_FIRST_RUNTIME_UNREAL + 5) +#define EL_AMOEBA_GROWING (EL_FIRST_RUNTIME_UNREAL + 6) +#define EL_AMOEBA_SHRINKING (EL_FIRST_RUNTIME_UNREAL + 7) +#define EL_EXPANDABLE_WALL_GROWING (EL_FIRST_RUNTIME_UNREAL + 8) +#define EL_FLAMES (EL_FIRST_RUNTIME_UNREAL + 9) +#define EL_PLAYER_IS_LEAVING (EL_FIRST_RUNTIME_UNREAL + 10) +#define EL_QUICKSAND_FILLING (EL_FIRST_RUNTIME_UNREAL + 11) +#define EL_MAGIC_WALL_FILLING (EL_FIRST_RUNTIME_UNREAL + 12) +#define EL_BD_MAGIC_WALL_FILLING (EL_FIRST_RUNTIME_UNREAL + 13) /* dummy elements (never used as game elements, only used as graphics) */ -#define EL_FIRST_DUMMY (EL_FIRST_RUNTIME_UNREAL + 13) +#define EL_FIRST_DUMMY (EL_FIRST_RUNTIME_UNREAL + 14) #define EL_STEELWALL_TOPLEFT (EL_FIRST_DUMMY + 0) #define EL_STEELWALL_TOPRIGHT (EL_FIRST_DUMMY + 1) @@ -1151,6 +1160,8 @@ struct ElementChangeInfo int delay_random; /* added frame delay before changed (random) */ int delay_frames; /* either 1 (frames) or 50 (seconds; 50 fps) */ + short trigger; /* custom element triggering change */ + short successor; /* new custom element after change */ }; @@ -1279,6 +1290,7 @@ extern short Ur[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; +extern short ChangeDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; -- 2.34.1