From c4fa66eaa78cc9381f03aca44aa06da994f6f44d Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Tue, 1 Jul 2003 02:11:21 +0200 Subject: [PATCH] rnd-20030701-1-src --- src/conftime.h | 2 +- src/editor.c | 268 ++++++++++++++++++++++++++++++++++--------------- src/files.c | 34 +++++-- src/game.c | 194 ++++++++++++++++++++++++++++++----- src/main.h | 108 +++++++++++--------- 5 files changed, 445 insertions(+), 161 deletions(-) diff --git a/src/conftime.h b/src/conftime.h index aca25e24..4f9a05d3 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2003-06-29 17:38]" +#define COMPILE_DATE_STRING "[2003-07-01 01:49]" diff --git a/src/editor.c b/src/editor.c index d4b4102a..702fed4d 100644 --- a/src/editor.c +++ b/src/editor.c @@ -125,6 +125,10 @@ #define ED_AREA_ELEM_CONTENT5_XPOS (30 * MINI_TILEX + MINI_TILEX / 2) #define ED_AREA_ELEM_CONTENT5_YPOS (ED_SETTINGS_YPOS(7) + \ ED_GADGET_DISTANCE) +/* extended custom change target */ +#define ED_AREA_ELEM_CONTENT6_XPOS (29 * MINI_TILEX) +#define ED_AREA_ELEM_CONTENT6_YPOS (ED_SETTINGS_YPOS(10) + \ + ED_GADGET_DISTANCE - MINI_TILEY) /* values for random placement background drawing area */ #define ED_AREA_RANDOM_BACKGROUND_XPOS (29 * MINI_TILEX) @@ -293,9 +297,9 @@ #define GADGET_ID_LEVEL_RANDOM_DOWN (GADGET_ID_COUNTER_FIRST + 9) #define GADGET_ID_LEVEL_RANDOM_TEXT (GADGET_ID_COUNTER_FIRST + 10) #define GADGET_ID_LEVEL_RANDOM_UP (GADGET_ID_COUNTER_FIRST + 11) -#define GADGET_ID_LEVEL_COLLECT_DOWN (GADGET_ID_COUNTER_FIRST + 12) -#define GADGET_ID_LEVEL_COLLECT_TEXT (GADGET_ID_COUNTER_FIRST + 13) -#define GADGET_ID_LEVEL_COLLECT_UP (GADGET_ID_COUNTER_FIRST + 14) +#define GADGET_ID_LEVEL_GEMSLIMIT_DOWN (GADGET_ID_COUNTER_FIRST + 12) +#define GADGET_ID_LEVEL_GEMSLIMIT_TEXT (GADGET_ID_COUNTER_FIRST + 13) +#define GADGET_ID_LEVEL_GEMSLIMIT_UP (GADGET_ID_COUNTER_FIRST + 14) #define GADGET_ID_LEVEL_TIMELIMIT_DOWN (GADGET_ID_COUNTER_FIRST + 15) #define GADGET_ID_LEVEL_TIMELIMIT_TEXT (GADGET_ID_COUNTER_FIRST + 16) #define GADGET_ID_LEVEL_TIMELIMIT_UP (GADGET_ID_COUNTER_FIRST + 17) @@ -308,12 +312,12 @@ #define GADGET_ID_ELEMENT_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 24) #define GADGET_ID_ELEMENT_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 25) #define GADGET_ID_ELEMENT_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 26) -#define GADGET_ID_COLLECT_SCORE_DOWN (GADGET_ID_COUNTER_FIRST + 27) -#define GADGET_ID_COLLECT_SCORE_TEXT (GADGET_ID_COUNTER_FIRST + 28) -#define GADGET_ID_COLLECT_SCORE_UP (GADGET_ID_COUNTER_FIRST + 29) -#define GADGET_ID_COLLECT_GEMCOUNT_DOWN (GADGET_ID_COUNTER_FIRST + 30) -#define GADGET_ID_COLLECT_GEMCOUNT_TEXT (GADGET_ID_COUNTER_FIRST + 31) -#define GADGET_ID_COLLECT_GEMCOUNT_UP (GADGET_ID_COUNTER_FIRST + 32) +#define GADGET_ID_CUSTOM_SCORE_DOWN (GADGET_ID_COUNTER_FIRST + 27) +#define GADGET_ID_CUSTOM_SCORE_TEXT (GADGET_ID_COUNTER_FIRST + 28) +#define GADGET_ID_CUSTOM_SCORE_UP (GADGET_ID_COUNTER_FIRST + 29) +#define GADGET_ID_CUSTOM_GEMCOUNT_DOWN (GADGET_ID_COUNTER_FIRST + 30) +#define GADGET_ID_CUSTOM_GEMCOUNT_TEXT (GADGET_ID_COUNTER_FIRST + 31) +#define GADGET_ID_CUSTOM_GEMCOUNT_UP (GADGET_ID_COUNTER_FIRST + 32) #define GADGET_ID_PUSH_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 33) #define GADGET_ID_PUSH_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 34) #define GADGET_ID_PUSH_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 35) @@ -349,11 +353,12 @@ #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_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) +#define GADGET_ID_CUSTOM_CHANGE_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 13) +#define GADGET_ID_CUSTOM_CHANGE_TRIGGER (GADGET_ID_DRAWING_AREA_FIRST + 14) +#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 15) /* text input identifiers */ -#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 15) +#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 16) #define GADGET_ID_LEVEL_NAME (GADGET_ID_TEXT_INPUT_FIRST + 0) #define GADGET_ID_LEVEL_AUTHOR (GADGET_ID_TEXT_INPUT_FIRST + 1) @@ -374,9 +379,10 @@ #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_OTHER_ACTION (GADGET_ID_SELECTBOX_FIRST + 12) +#define GADGET_ID_CHANGE_POWER (GADGET_ID_SELECTBOX_FIRST + 13) /* textbutton identifiers */ -#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 13) +#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 14) #define GADGET_ID_PROPERTIES_INFO (GADGET_ID_TEXTBUTTON_FIRST + 0) #define GADGET_ID_PROPERTIES_CONFIG (GADGET_ID_TEXTBUTTON_FIRST + 1) @@ -424,13 +430,16 @@ #define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 18) #define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 19) #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) +#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) /* gadgets for buttons in element list */ -#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 25) +#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 28) #define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \ ED_NUM_ELEMENTLIST_BUTTONS - 1) @@ -445,14 +454,14 @@ #define ED_COUNTER_ID_SELECT_LEVEL 0 #define ED_COUNTER_ID_LEVEL_XSIZE 1 #define ED_COUNTER_ID_LEVEL_YSIZE 2 -#define ED_COUNTER_ID_LEVEL_COLLECT 3 +#define ED_COUNTER_ID_LEVEL_GEMSLIMIT 3 #define ED_COUNTER_ID_LEVEL_TIMELIMIT 4 #define ED_COUNTER_ID_LEVEL_TIMESCORE 5 #define ED_COUNTER_ID_LEVEL_RANDOM 6 #define ED_COUNTER_ID_ELEMENT_SCORE 7 #define ED_COUNTER_ID_ELEMENT_CONTENT 8 -#define ED_COUNTER_ID_COLLECT_SCORE 9 -#define ED_COUNTER_ID_COLLECT_GEMCOUNT 10 +#define ED_COUNTER_ID_CUSTOM_SCORE 9 +#define ED_COUNTER_ID_CUSTOM_GEMCOUNT 10 #define ED_COUNTER_ID_PUSH_DELAY_FIX 11 #define ED_COUNTER_ID_PUSH_DELAY_RND 12 #define ED_COUNTER_ID_MOVE_DELAY_FIX 13 @@ -465,7 +474,7 @@ #define ED_COUNTER_ID_LEVEL_FIRST ED_COUNTER_ID_LEVEL_XSIZE #define ED_COUNTER_ID_LEVEL_LAST ED_COUNTER_ID_LEVEL_RANDOM -#define ED_COUNTER_ID_CUSTOM_FIRST ED_COUNTER_ID_COLLECT_SCORE +#define ED_COUNTER_ID_CUSTOM_FIRST ED_COUNTER_ID_CUSTOM_SCORE #define ED_COUNTER_ID_CUSTOM_LAST ED_COUNTER_ID_MOVE_DELAY_RND #define ED_COUNTER_ID_CHANGE_FIRST ED_COUNTER_ID_CHANGE_DELAY_FIX @@ -517,14 +526,15 @@ #define ED_SELECTBOX_ID_CHANGE_PLAYER_ACTION 10 #define ED_SELECTBOX_ID_CHANGE_IMPACT_ACTION 11 #define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION 12 +#define ED_SELECTBOX_ID_CHANGE_POWER 13 -#define ED_NUM_SELECTBOX 13 +#define ED_NUM_SELECTBOX 14 #define ED_SELECTBOX_ID_CUSTOM_FIRST ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION #define ED_SELECTBOX_ID_CUSTOM_LAST ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER #define ED_SELECTBOX_ID_CHANGE_FIRST ED_SELECTBOX_ID_CHANGE_TIME_UNITS -#define ED_SELECTBOX_ID_CHANGE_LAST ED_SELECTBOX_ID_CHANGE_OTHER_ACTION +#define ED_SELECTBOX_ID_CHANGE_LAST ED_SELECTBOX_ID_CHANGE_POWER /* values for textbutton gadgets */ #define ED_TEXTBUTTON_ID_PROPERTIES_INFO 0 @@ -554,12 +564,15 @@ #define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 16 #define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 17 #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_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_NUM_CHECKBUTTONS 23 +#define ED_NUM_CHECKBUTTONS 26 #define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_DOUBLE_SPEED #define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED @@ -711,8 +724,8 @@ static struct { ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(3), 0, 999, - GADGET_ID_LEVEL_COLLECT_DOWN, GADGET_ID_LEVEL_COLLECT_UP, - GADGET_ID_LEVEL_COLLECT_TEXT, + GADGET_ID_LEVEL_GEMSLIMIT_DOWN, GADGET_ID_LEVEL_GEMSLIMIT_UP, + GADGET_ID_LEVEL_GEMSLIMIT_TEXT, &level.gems_needed, "number of emeralds to collect", NULL, NULL }, @@ -765,17 +778,17 @@ static struct { ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(3), MIN_SCORE, MAX_SCORE, - GADGET_ID_COLLECT_SCORE_DOWN, GADGET_ID_COLLECT_SCORE_UP, - GADGET_ID_COLLECT_SCORE_TEXT, - &custom_element.collect_score, + GADGET_ID_CUSTOM_SCORE_DOWN, GADGET_ID_CUSTOM_SCORE_UP, + GADGET_ID_CUSTOM_SCORE_TEXT, + &custom_element.score, NULL, "collect score", NULL }, { ED_SETTINGS_XPOS(13) + 10, ED_SETTINGS_YPOS(3), MIN_GEM_COUNT, MAX_GEM_COUNT, - GADGET_ID_COLLECT_GEMCOUNT_DOWN, GADGET_ID_COLLECT_GEMCOUNT_UP, - GADGET_ID_COLLECT_GEMCOUNT_TEXT, - &custom_element.collect_gem_count, + GADGET_ID_CUSTOM_GEMCOUNT_DOWN, GADGET_ID_CUSTOM_GEMCOUNT_UP, + GADGET_ID_CUSTOM_GEMCOUNT_TEXT, + &custom_element.gem_count, NULL, "gems", NULL }, { @@ -856,6 +869,23 @@ static struct } }; +static struct ValueTextInfo options_access_type[] = +{ + { EP_WALKABLE, "walk" }, + { EP_PASSABLE, "pass" }, + { -1, NULL } +}; +static int value_access_type = 0; + +static struct ValueTextInfo options_access_layer[] = +{ + { EP_ACCESSIBLE_OVER, "over" }, + { EP_ACCESSIBLE_INSIDE, "inside" }, + { EP_ACCESSIBLE_UNDER, "under" }, + { -1, NULL } +}; +static int value_access_layer = 0; + static struct ValueTextInfo options_walk_to_action[] = { { EP_DIGGABLE, "diggable" }, @@ -903,23 +933,6 @@ static struct ValueTextInfo options_move_stepsize[] = { -1, NULL } }; -static struct ValueTextInfo options_consistency[] = -{ - { EP_CAN_EXPLODE, "can explode" }, - { EP_INDESTRUCTIBLE, "indestructible" }, - { -1, NULL } -}; -static int value_consistency = 0; - -static struct ValueTextInfo options_deadliness[] = -{ - { EP_DONT_RUN_INTO, "running into" }, - { EP_DONT_COLLIDE_WITH, "colliding with" }, - { EP_DONT_TOUCH, "touching" }, - { -1, NULL } -}; -static int value_deadliness = 0; - static struct ValueTextInfo options_smash_targets[] = { { EP_CAN_SMASH_PLAYER, "player" }, @@ -929,22 +942,22 @@ static struct ValueTextInfo options_smash_targets[] = }; static int value_smash_targets = 0; -static struct ValueTextInfo options_access_type[] = +static struct ValueTextInfo options_deadliness[] = { - { EP_WALKABLE, "walk" }, - { EP_PASSABLE, "pass" }, + { EP_DONT_RUN_INTO, "running into" }, + { EP_DONT_COLLIDE_WITH, "colliding with" }, + { EP_DONT_TOUCH, "touching" }, { -1, NULL } }; -static int value_access_type = 0; +static int value_deadliness = 0; -static struct ValueTextInfo options_access_layer[] = +static struct ValueTextInfo options_consistency[] = { - { EP_ACCESSIBLE_OVER, "over" }, - { EP_ACCESSIBLE_INSIDE, "inside" }, - { EP_ACCESSIBLE_UNDER, "under" }, + { EP_CAN_EXPLODE, "can explode" }, + { EP_INDESTRUCTIBLE, "indestructible" }, { -1, NULL } }; -static int value_access_layer = 0; +static int value_consistency = 0; static struct ValueTextInfo options_time_units[] = { @@ -980,6 +993,14 @@ static struct ValueTextInfo options_change_other_action[] = }; static int value_change_other_action = 0; +static struct ValueTextInfo options_change_power[] = +{ + { CP_NON_DESTRUCTIVE, "non-destructive" }, + { CP_HALF_DESTRUCTIVE, "half-destructive" }, + { CP_FULL_DESTRUCTIVE, "full-destructive" }, + { -1, NULL } +}; + static struct { int x, y; @@ -1099,6 +1120,14 @@ static struct &value_change_other_action, NULL, "other element:", "type of other element action" }, + { + ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(10), + GADGET_ID_CHANGE_POWER, + -1, + options_change_power, + &custom_element.change.power, + "power:", NULL, "power of extended change" + }, }; static struct @@ -1390,6 +1419,24 @@ static struct &custom_element_change_events[CE_BY_OTHER], NULL, "element changes by other element" }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(8), + GADGET_ID_CHANGE_USE_EXPLOSION, + &custom_element.change.explode, + "explode instead of change", "element explodes instead of change" + }, + { + ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(9), + GADGET_ID_CHANGE_USE_CONTENT, + &custom_element.change.use_content, + "use extended change target:", "element changes to more elements" + }, + { + ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(11), + GADGET_ID_CHANGE_ONLY_COMPLETE, + &custom_element.change.only_complete, + "only use complete change", "only use complete extended content" + }, { ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(12), GADGET_ID_CUSTOM_USE_TEMPLATE, @@ -2806,7 +2853,7 @@ static void CreateDrawingAreas() level_editor_gadget[id] = gi; - /* ... one areas for custom element explosion content ... */ + /* ... one area for custom element explosion content ... */ id = GADGET_ID_CUSTOM_CONTENT; gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_CUSTOM_TYPE_ID, i, @@ -2845,6 +2892,26 @@ static void CreateDrawingAreas() level_editor_gadget[id] = gi; + /* ... one area for extended custom element change target content ... */ + id = GADGET_ID_CUSTOM_CHANGE_CONTENT; + gi = CreateGadget(GDI_CUSTOM_ID, id, + GDI_CUSTOM_TYPE_ID, i, + GDI_X, SX + ED_AREA_ELEM_CONTENT6_XPOS, + GDI_Y, SX + ED_AREA_ELEM_CONTENT6_YPOS, + GDI_WIDTH, 3 * MINI_TILEX, + GDI_HEIGHT, 3 * 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; + /* ... one for each custom element change trigger element ... */ id = GADGET_ID_CUSTOM_CHANGE_TRIGGER; gi = CreateGadget(GDI_CUSTOM_ID, id, @@ -4110,11 +4177,36 @@ static void DrawCustomChangeTargetArea() DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY, TRUE); DrawMiniGraphicExt(drawto, gi->x, gi->y, - el2edimg(custom_element.change.successor)); + el2edimg(custom_element.change.target_element)); MapDrawingArea(GADGET_ID_CUSTOM_CHANGE_TARGET); } +static void DrawCustomChangeContentArea() +{ + struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CHANGE_CONTENT]; + int area_sx = SX + ED_AREA_ELEM_CONTENT6_XPOS; + int area_sy = SY + ED_AREA_ELEM_CONTENT6_YPOS; + int x, y; + + 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, 3 * MINI_TILEX, 3 * MINI_TILEY, TRUE); + + for (y=0; y<3; y++) + for (x=0; x<3; x++) + DrawMiniGraphicExt(drawto, gi->x + x * MINI_TILEX,gi->y + y * MINI_TILEY, + el2edimg(custom_element.change.content[x][y])); + + MapDrawingArea(GADGET_ID_CUSTOM_CHANGE_CONTENT); +} + static void DrawCustomChangeTriggerArea() { struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CHANGE_TRIGGER]; @@ -4700,6 +4792,7 @@ static void DrawPropertiesAdvanced() /* draw drawing area gadgets */ DrawCustomGraphicElementArea(); DrawCustomChangeTargetArea(); + DrawCustomChangeContentArea(); DrawCustomChangeTriggerArea(); } @@ -5548,7 +5641,12 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) } else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET) { - custom_element.change.successor = new_element; + custom_element.change.target_element = new_element; + element_info[properties_element] = custom_element; + } + else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT) + { + custom_element.change.content[sx][sy] = new_element; element_info[properties_element] = custom_element; } else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) @@ -5667,7 +5765,9 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) else if (id == GADGET_ID_CUSTOM_CONTENT) PickDrawingElement(button, custom_element.content[sx][sy]); else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET) - PickDrawingElement(button, custom_element.change.successor); + PickDrawingElement(button, custom_element.change.target_element); + else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT) + PickDrawingElement(button, custom_element.change.content[sx][sy]); else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) PickDrawingElement(button, custom_element.change.trigger); else if (id == GADGET_ID_RANDOM_BACKGROUND) @@ -6399,30 +6499,33 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) else if (actual_drawing_function == GADGET_ID_PICK_ELEMENT) { if (id == GADGET_ID_AMOEBA_CONTENT) - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, - "%s", getElementInfoText(level.amoeba_content)); + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", + getElementInfoText(level.amoeba_content)); else if (id == GADGET_ID_CUSTOM_GRAPHIC) - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, - "%s", getElementInfoText(custom_element.use_gfx_element)); + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", + getElementInfoText(custom_element.gfx_element)); else if (id == GADGET_ID_CUSTOM_CONTENT) - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, - "%s", getElementInfoText(custom_element.content[sx][sy])); + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", + getElementInfoText(custom_element.content[sx][sy])); else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET) - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, - "%s", getElementInfoText(custom_element.change.successor)); + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", + getElementInfoText(custom_element.change.target_element)); + else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", + getElementInfoText(custom_element.change.content[sx][sy])); else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, - "%s", getElementInfoText(custom_element.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)); + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", + getElementInfoText(random_placement_background_element)); else if (id >= GADGET_ID_ELEMENT_CONTENT_0 && id <= GADGET_ID_ELEMENT_CONTENT_7) { int i = id - GADGET_ID_ELEMENT_CONTENT_0; - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, - "%s", getElementInfoText(level.yamyam_content[i][sx][sy])); + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s", + getElementInfoText(level.yamyam_content[i][sx][sy])); } } else @@ -6439,6 +6542,9 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) 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_CONTENT) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, + "New extended elements after change"); else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "Other element triggering change"); diff --git a/src/files.c b/src/files.c index 19f536d9..16260cc7 100644 --- a/src/files.c +++ b/src/files.c @@ -99,9 +99,14 @@ static void setLevelInfoToDefaults() { int element = EL_CUSTOM_START + i; + element_info[element].use_template = FALSE; + element_info[element].use_gfx_element = FALSE; element_info[element].gfx_element = EL_EMPTY_SPACE; + element_info[element].score = 0; + element_info[element].gem_count = 0; + element_info[element].push_delay_fixed = 2; /* special default */ element_info[element].push_delay_random = 8; /* special default */ element_info[element].move_delay_fixed = 0; @@ -116,9 +121,24 @@ static void setLevelInfoToDefaults() element_info[element].content[x][y] = EL_EMPTY_SPACE; element_info[element].change.events = CE_BITMASK_DEFAULT; + element_info[element].change.delay_fixed = 0; element_info[element].change.delay_random = 0; - element_info[element].change.successor = EL_EMPTY_SPACE; + element_info[element].change.delay_frames = -1; /* use default */ + + element_info[element].change.trigger = EL_EMPTY_SPACE; + + element_info[element].change.target_element = EL_EMPTY_SPACE; + + element_info[element].change.use_content = FALSE; + element_info[element].change.only_complete = FALSE; + element_info[element].change.power = CP_NON_DESTRUCTIVE; + + element_info[element].change.explode = FALSE; + + for(x=0; x<3; x++) + for(y=0; y<3; y++) + element_info[element].change.content[x][y] = EL_EMPTY_SPACE; /* start with no properties at all */ for (j=0; j < NUM_EP_BITFIELDS; j++) @@ -385,10 +405,10 @@ static int LoadLevel_CUS2(FILE *file, int chunk_size, struct LevelInfo *level) for (i=0; i < num_changed_custom_elements; i++) { int element = getFile16BitBE(file); - int custom_element_successor = getFile16BitBE(file); + int custom_target_element = getFile16BitBE(file); if (IS_CUSTOM_ELEMENT(element)) - element_info[element].change.successor = custom_element_successor; + element_info[element].change.target_element = custom_target_element; else Error(ERR_WARN, "invalid custom element number %d", element); } @@ -778,12 +798,12 @@ static void SaveLevel_CUS2(FILE *file, struct LevelInfo *level, { int element = EL_CUSTOM_START + i; - if (element_info[element].change.successor != EL_EMPTY_SPACE) + if (element_info[element].change.target_element != EL_EMPTY_SPACE) { if (check < num_changed_custom_elements) { putFile16BitBE(file, element); - putFile16BitBE(file, element_info[element].change.successor); + putFile16BitBE(file, element_info[element].change.target_element); } check++; @@ -791,7 +811,7 @@ static void SaveLevel_CUS2(FILE *file, struct LevelInfo *level, } if (check != num_changed_custom_elements) /* should not happen */ - Error(ERR_WARN, "inconsistent number of custom element successors"); + Error(ERR_WARN, "inconsistent number of custom target elements"); } void SaveLevel(int level_nr) @@ -843,7 +863,7 @@ void SaveLevel(int level_nr) /* check for non-standard custom elements and calculate "CUS2" chunk size */ for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) - if (element_info[EL_CUSTOM_START + i].change.successor != EL_EMPTY_SPACE) + if (element_info[EL_CUSTOM_START + i].change.target_element != EL_EMPTY) num_changed_custom_elements2++; putFileChunkBE(file, "RND1", CHUNK_SIZE_UNDEFINED); diff --git a/src/game.c b/src/game.c index b51a1873..436d82ba 100644 --- a/src/game.c +++ b/src/game.c @@ -165,7 +165,7 @@ static void KillHeroUnlessProtected(int, int); static void CheckTriggeredElementChange(int, int); static void CheckPlayerElementChange(int, int, int, int); -static void ChangeElementDoIt(int, int, int); +static void ChangeElementNow(int, int, int); static void PlaySoundLevel(int, int, int); static void PlaySoundLevelNearest(int, int, int); @@ -202,8 +202,8 @@ static void RunTimegateWheel(int x, int y); struct ChangingElementInfo { - int base_element; - int next_element; + int element; + int target_element; int change_delay; void (*pre_change_function)(int x, int y); void (*change_function)(int x, int y); @@ -375,7 +375,7 @@ struct int element; int gem_count; } -collect_gem_count_list[] = +gem_count_list[] = { { EL_EMERALD, 1 }, { EL_BD_DIAMOND, 1 }, @@ -390,10 +390,10 @@ collect_gem_count_list[] = { EL_UNDEFINED, 0 }, }; -static struct ChangingElementInfo changing_element[MAX_NUM_ELEMENTS]; +static boolean changing_element[MAX_NUM_ELEMENTS]; static unsigned long trigger_events[MAX_NUM_ELEMENTS]; -#define IS_AUTO_CHANGING(e) (changing_element[e].base_element != EL_UNDEFINED) +#define IS_AUTO_CHANGING(e) (changing_element[e]) #define IS_JUST_CHANGING(x, y) (ChangeDelay[x][y] != 0) #define IS_CHANGING(x, y) (IS_AUTO_CHANGING(Feld[x][y]) || \ IS_JUST_CHANGING(x, y)) @@ -742,42 +742,75 @@ static void InitGameEngine() /* initialize changing elements information */ for (i=0; ibase_element; + struct ElementChangeInfo *change = &element_info[element].change; + +#if 1 + change->target_element = ce->target_element; + change->delay_fixed = ce->change_delay; + change->pre_change_function = ce->pre_change_function; + change->change_function = ce->change_function; + change->post_change_function = ce->post_change_function; + changing_element[element] = TRUE; +#else changing_element[element].base_element = ce->base_element; changing_element[element].next_element = ce->next_element; changing_element[element].change_delay = ce->change_delay; changing_element[element].pre_change_function = ce->pre_change_function; changing_element[element].change_function = ce->change_function; changing_element[element].post_change_function = ce->post_change_function; +#endif } /* add changing elements from custom element configuration */ for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) { int element = EL_CUSTOM_START + i; +#if 0 struct ElementChangeInfo *change = &element_info[element].change; +#endif /* only add custom elements that change after fixed/random frame delay */ if (!CAN_CHANGE(element) || !HAS_CHANGE_EVENT(element, CE_DELAY)) continue; +#if 1 + changing_element[element] = TRUE; +#else changing_element[element].base_element = element; - changing_element[element].next_element = change->successor; + changing_element[element].next_element = change->target_element; changing_element[element].change_delay = (change->delay_fixed * change->delay_frames); +#endif } /* ---------- initialize trigger events ---------------------------------- */ @@ -818,12 +851,12 @@ static void InitGameEngine() /* initialize gem count values for each element */ for (i=0; iexplode) + { + Bang(x, y); + return; + } + + if (change->use_content) + { + boolean complete_change = TRUE; + boolean can_change[3][3]; + int xx, yy; + + for (yy = 0; yy < 3; yy++) for(xx = 0; xx < 3 ; xx++) + { + boolean half_destructible; + int ex = x + xx - 1; + int ey = y + yy - 1; + int e; + + can_change[xx][yy] = TRUE; + + if (ex == x && ey == y) /* do not check changing element itself */ + continue; + + if (change->content[xx][yy] == EL_EMPTY_SPACE) + { + can_change[xx][yy] = FALSE; /* do not change empty borders */ + + continue; + } + + if (!IN_LEV_FIELD(ex, ey)) + { + can_change[xx][yy] = FALSE; + complete_change = FALSE; + + continue; + } + + e = Feld[ex][ey]; + + half_destructible = (IS_FREE(ex, ey) || IS_DIGGABLE(e)); + + if ((change->power <= CP_NON_DESTRUCTIVE && !IS_FREE(ex, ey)) || + (change->power <= CP_HALF_DESTRUCTIVE && !half_destructible) || + (change->power <= CP_FULL_DESTRUCTIVE && IS_INDESTRUCTIBLE(e))) + { + can_change[xx][yy] = FALSE; + complete_change = FALSE; + } + } + + if (!change->only_complete || complete_change) + { + 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]) + { + ChangeElementNowExt(ex, ey, change->content[xx][yy]); + + /* for symmetry reasons, stop newly created border elements */ + if (ex != x || ey != y) + Stop[ex][ey] = TRUE; + } + } + + return; + } + } + + ChangeElementNowExt(x, y, change->target_element); +} + static void ChangeElement(int x, int y) { int element = Feld[x][y]; + struct ElementChangeInfo *change = &element_info[element].change; if (ChangeDelay[x][y] == 0) /* initialize element change */ { +#if 1 + ChangeDelay[x][y] = ( change->delay_fixed * change->delay_frames + + RND(change->delay_random * change->delay_frames)) + 1; +#else ChangeDelay[x][y] = changing_element[element].change_delay + 1; if (IS_CUSTOM_ELEMENT(element) && HAS_CHANGE_EVENT(element, CE_DELAY)) @@ -5064,12 +5188,18 @@ static void ChangeElement(int x, int y) ChangeDelay[x][y] += RND(max_random_delay * delay_frames); } +#endif ResetGfxAnimation(x, y); ResetRandomAnimationValue(x, y); +#if 1 + if (change->pre_change_function) + change->pre_change_function(x, y); +#else if (changing_element[element].pre_change_function) changing_element[element].pre_change_function(x, y); +#endif } ChangeDelay[x][y]--; @@ -5081,12 +5211,19 @@ static void ChangeElement(int x, int y) if (IS_ANIMATED(graphic)) DrawLevelGraphicAnimationIfNeeded(x, y, graphic); +#if 1 + if (change->change_function) + change->change_function(x, y); +#else if (changing_element[element].change_function) changing_element[element].change_function(x, y); +#endif } else /* finish element change */ { +#if 0 int next_element = changing_element[element].next_element; +#endif if (IS_MOVING(x, y)) /* never change a running system ;-) */ { @@ -5095,13 +5232,20 @@ static void ChangeElement(int x, int y) return; } +#if 1 + ChangeElementNow(x, y, element); + + if (change->post_change_function) + change->post_change_function(x, y); +#else if (next_element != EL_UNDEFINED) - ChangeElementDoIt(x, y, next_element); + ChangeElementNow(x, y, next_element); else - ChangeElementDoIt(x, y, element_info[element].change.successor); + ChangeElementNow(x, y, element_info[element].change.target_element); if (changing_element[element].post_change_function) changing_element[element].post_change_function(x, y); +#endif } } @@ -5135,12 +5279,8 @@ static void CheckPlayerElementChange(int x, int y, int element, if (!CAN_CHANGE(element) || !HAS_CHANGE_EVENT(element, trigger_event)) return; -#if 1 ChangeDelay[x][y] = 1; ChangeElement(x, y); -#else - ChangeElementDoIt(x, y, element_info[element].change.successor); -#endif } static void PlayerActions(struct PlayerInfo *player, byte player_action) @@ -6904,10 +7044,10 @@ int DigField(struct PlayerInfo *player, el2edimg(EL_KEY_1 + key_nr)); redraw_mask |= REDRAW_DOOR_1; } - else if (element_info[element].collect_gem_count > 0) + else if (element_info[element].gem_count > 0) { local_player->gems_still_needed -= - element_info[element].collect_gem_count; + element_info[element].gem_count; if (local_player->gems_still_needed < 0) local_player->gems_still_needed = 0; @@ -7326,7 +7466,7 @@ void RaiseScoreElement(int element) RaiseScore(level.score[SC_KEY]); break; default: - RaiseScore(element_info[element].collect_score); + RaiseScore(element_info[element].score); break; } } diff --git a/src/main.h b/src/main.h index 4a3cee3c..1108cbf7 100644 --- a/src/main.h +++ b/src/main.h @@ -89,57 +89,57 @@ #define EP_PUSHABLE 24 /* values for special configurable properties (depending on level settings) */ -#define EP_EM_SLIPPERY_WALL 25 +#define EP_EM_SLIPPERY_WALL 32 /* values for special graphics properties (no effect on game engine) */ -#define EP_CAN_BE_CRUMBLED 26 +#define EP_CAN_BE_CRUMBLED 33 /* values for pre-defined properties */ -#define EP_PLAYER 27 -#define EP_CAN_PASS_MAGIC_WALL 28 -#define EP_SWITCHABLE 29 -#define EP_BD_ELEMENT 30 -#define EP_SP_ELEMENT 31 -#define EP_SB_ELEMENT 32 -#define EP_GEM 33 -#define EP_FOOD_DARK_YAMYAM 34 -#define EP_FOOD_PENGUIN 35 -#define EP_FOOD_PIG 36 -#define EP_HISTORIC_WALL 37 -#define EP_HISTORIC_SOLID 38 -#define EP_CLASSIC_ENEMY 39 -#define EP_BELT 40 -#define EP_BELT_ACTIVE 41 -#define EP_BELT_SWITCH 42 -#define EP_TUBE 43 -#define EP_KEYGATE 44 -#define EP_AMOEBOID 45 -#define EP_AMOEBALIVE 46 -#define EP_HAS_CONTENT 47 -#define EP_ACTIVE_BOMB 48 -#define EP_INACTIVE 49 +#define EP_PLAYER 34 +#define EP_CAN_PASS_MAGIC_WALL 35 +#define EP_SWITCHABLE 36 +#define EP_BD_ELEMENT 37 +#define EP_SP_ELEMENT 38 +#define EP_SB_ELEMENT 39 +#define EP_GEM 40 +#define EP_FOOD_DARK_YAMYAM 41 +#define EP_FOOD_PENGUIN 42 +#define EP_FOOD_PIG 43 +#define EP_HISTORIC_WALL 44 +#define EP_HISTORIC_SOLID 45 +#define EP_CLASSIC_ENEMY 46 +#define EP_BELT 47 +#define EP_BELT_ACTIVE 48 +#define EP_BELT_SWITCH 49 +#define EP_TUBE 50 +#define EP_KEYGATE 51 +#define EP_AMOEBOID 52 +#define EP_AMOEBALIVE 53 +#define EP_HAS_CONTENT 54 +#define EP_ACTIVE_BOMB 55 +#define EP_INACTIVE 56 /* values for derived properties (determined from properties above) */ -#define EP_ACCESSIBLE_OVER 50 -#define EP_ACCESSIBLE_INSIDE 51 -#define EP_ACCESSIBLE_UNDER 52 -#define EP_WALKABLE 53 -#define EP_PASSABLE 54 -#define EP_ACCESSIBLE 55 -#define EP_SNAPPABLE 56 -#define EP_WALL 57 -#define EP_SOLID_FOR_PUSHING 58 -#define EP_DRAGONFIRE_PROOF 59 -#define EP_EXPLOSION_PROOF 60 -#define EP_CAN_SMASH 61 -#define EP_CAN_EXPLODE 62 +#define EP_ACCESSIBLE_OVER 57 +#define EP_ACCESSIBLE_INSIDE 58 +#define EP_ACCESSIBLE_UNDER 59 +#define EP_WALKABLE 60 +#define EP_PASSABLE 61 +#define EP_ACCESSIBLE 62 +#define EP_SNAPPABLE 63 +#define EP_WALL 64 +#define EP_SOLID_FOR_PUSHING 65 +#define EP_DRAGONFIRE_PROOF 66 +#define EP_EXPLOSION_PROOF 67 +#define EP_CAN_SMASH 68 +#define EP_CAN_EXPLODE 69 /* values for internal purpose only (level editor) */ -#define EP_EXPLODE_RESULT 63 -#define EP_WALK_TO_OBJECT 64 -#define EP_DEADLY 65 +#define EP_EXPLODE_RESULT 70 +#define EP_WALK_TO_OBJECT 71 +#define EP_DEADLY 72 -#define NUM_ELEMENT_PROPERTIES 66 +#define NUM_ELEMENT_PROPERTIES 73 #define NUM_EP_BITFIELDS ((NUM_ELEMENT_PROPERTIES + 31) / 32) #define EP_BITFIELD_BASE 0 @@ -185,6 +185,11 @@ (CH_EVENT_VAR(e) |= CH_EVENT_BIT(c)) : \ (CH_EVENT_VAR(e) &= ~CH_EVENT_BIT(c))) : 0) +/* values for change power for custom elements */ +#define CP_NON_DESTRUCTIVE 0 +#define CP_HALF_DESTRUCTIVE 1 +#define CP_FULL_DESTRUCTIVE 2 + /* macros for configurable properties */ #define IS_DIGGABLE(e) HAS_PROPERTY(e, EP_DIGGABLE) @@ -1172,7 +1177,20 @@ struct ElementChangeInfo short trigger; /* custom element triggering change */ - short successor; /* new custom element after change */ + short target_element; /* target element after change */ + + int content[3][3]; /* new elements after extended change */ + boolean use_content; /* use extended change content */ + boolean only_complete; /* only use complete content */ + int power; /* power of extended change */ + + boolean explode; /* explode instead of change */ + + /* functions that are called before, while and after the change of an + element -- currently only used for non-custom elements */ + void (*pre_change_function)(int x, int y); + void (*change_function)(int x, int y); + void (*post_change_function)(int x, int y); }; struct ElementInfo @@ -1201,8 +1219,8 @@ struct ElementInfo boolean use_gfx_element; short gfx_element; /* optional custom graphic element */ - int collect_score; /* score value for collecting */ - int collect_gem_count; /* gem count value for collecting */ + int score; /* score value for collecting */ + int gem_count; /* gem count value for collecting */ int push_delay_fixed; /* constant frame delay for pushing */ int push_delay_random; /* additional random frame delay for pushing */ -- 2.34.1