GADGET_ID_MOVE_DELAY_RND_DOWN,
GADGET_ID_MOVE_DELAY_RND_TEXT,
GADGET_ID_MOVE_DELAY_RND_UP,
+ GADGET_ID_STEP_DELAY_FIX_DOWN,
+ GADGET_ID_STEP_DELAY_FIX_TEXT,
+ GADGET_ID_STEP_DELAY_FIX_UP,
+ GADGET_ID_STEP_DELAY_RND_DOWN,
+ GADGET_ID_STEP_DELAY_RND_TEXT,
+ GADGET_ID_STEP_DELAY_RND_UP,
GADGET_ID_EXPLOSION_DELAY_DOWN,
GADGET_ID_EXPLOSION_DELAY_TEXT,
GADGET_ID_EXPLOSION_DELAY_UP,
// selectbox identifiers
GADGET_ID_TIME_OR_STEPS,
+ GADGET_ID_TIME_SCORE_BASE,
GADGET_ID_GAME_ENGINE_TYPE,
GADGET_ID_LEVELSET_SAVE_MODE,
GADGET_ID_WIND_DIRECTION,
// checkbuttons/radiobuttons for level/element properties
GADGET_ID_AUTO_COUNT_GEMS,
+ GADGET_ID_RATE_TIME_OVER_SCORE,
GADGET_ID_USE_LEVELSET_ARTWORK,
GADGET_ID_COPY_LEVEL_TEMPLATE,
GADGET_ID_RANDOM_PERCENTAGE,
GADGET_ID_SB_OBJECTS_NEEDED,
GADGET_ID_AUTO_EXIT_SOKOBAN,
GADGET_ID_SOLVED_BY_ONE_PLAYER,
+ GADGET_ID_FINISH_DIG_COLLECT,
+ GADGET_ID_KEEP_WALKABLE_CE,
GADGET_ID_CONTINUOUS_SNAPPING,
GADGET_ID_BLOCK_SNAP_FIELD,
GADGET_ID_BLOCK_LAST_FIELD,
ED_COUNTER_ID_DROP_DELAY_RND,
ED_COUNTER_ID_MOVE_DELAY_FIX,
ED_COUNTER_ID_MOVE_DELAY_RND,
+ ED_COUNTER_ID_STEP_DELAY_FIX,
+ ED_COUNTER_ID_STEP_DELAY_RND,
ED_COUNTER_ID_EXPLOSION_DELAY,
ED_COUNTER_ID_IGNITION_DELAY,
ED_COUNTER_ID_GROUP_CONTENT,
enum
{
ED_SELECTBOX_ID_TIME_OR_STEPS,
+ ED_SELECTBOX_ID_TIME_SCORE_BASE,
ED_SELECTBOX_ID_GAME_ENGINE_TYPE,
ED_SELECTBOX_ID_LEVELSET_SAVE_MODE,
ED_SELECTBOX_ID_WIND_DIRECTION,
enum
{
ED_CHECKBUTTON_ID_AUTO_COUNT_GEMS,
+ ED_CHECKBUTTON_ID_RATE_TIME_OVER_SCORE,
ED_CHECKBUTTON_ID_USE_LEVELSET_ARTWORK,
ED_CHECKBUTTON_ID_COPY_LEVEL_TEMPLATE,
ED_CHECKBUTTON_ID_RANDOM_RESTRICTED,
ED_CHECKBUTTON_ID_SB_OBJECTS_NEEDED,
ED_CHECKBUTTON_ID_AUTO_EXIT_SOKOBAN,
ED_CHECKBUTTON_ID_SOLVED_BY_ONE_PLAYER,
+ ED_CHECKBUTTON_ID_FINISH_DIG_COLLECT,
+ ED_CHECKBUTTON_ID_KEEP_WALKABLE_CE,
ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING,
ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD,
ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD,
};
#define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_AUTO_COUNT_GEMS
-#define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_AUTO_COUNT_GEMS
+#define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RATE_TIME_OVER_SCORE
#define ED_CHECKBUTTON_ID_LEVELSET_FIRST ED_CHECKBUTTON_ID_USE_LEVELSET_ARTWORK
#define ED_CHECKBUTTON_ID_LEVELSET_LAST ED_CHECKBUTTON_ID_COPY_LEVEL_TEMPLATE
GADGET_ID_LEVEL_TIMESCORE_DOWN, GADGET_ID_LEVEL_TIMESCORE_UP,
GADGET_ID_LEVEL_TIMESCORE_TEXT, GADGET_ID_NONE,
&level.score[SC_TIME_BONUS],
- "score for each second/step left:", NULL, NULL
+ "score for time or steps left:", NULL, NULL
},
{
- ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(12),
+ ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(13),
0, 9999,
GADGET_ID_LEVEL_RANDOM_SEED_DOWN, GADGET_ID_LEVEL_RANDOM_SEED_UP,
GADGET_ID_LEVEL_RANDOM_SEED_TEXT, GADGET_ID_NONE,
NULL, "+random", NULL
},
{
- ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(12),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(6),
+ 0, 999,
+ GADGET_ID_STEP_DELAY_FIX_DOWN, GADGET_ID_STEP_DELAY_FIX_UP,
+ GADGET_ID_STEP_DELAY_FIX_TEXT, GADGET_ID_NONE,
+ &custom_element.step_delay_fixed,
+ NULL, "step delay", NULL
+ },
+ {
+ -1, ED_ELEMENT_SETTINGS_YPOS(6),
+ 0, 999,
+ GADGET_ID_STEP_DELAY_RND_DOWN, GADGET_ID_STEP_DELAY_RND_UP,
+ GADGET_ID_STEP_DELAY_RND_TEXT, GADGET_ID_STEP_DELAY_FIX_UP,
+ &custom_element.step_delay_random,
+ NULL, "+random", NULL
+ },
+ {
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(13),
0, 999,
GADGET_ID_EXPLOSION_DELAY_DOWN, GADGET_ID_EXPLOSION_DELAY_UP,
GADGET_ID_EXPLOSION_DELAY_TEXT, GADGET_ID_NONE,
NULL, "explosion delay", NULL
},
{
- ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(13),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(14),
0, 999,
GADGET_ID_IGNITION_DELAY_DOWN, GADGET_ID_IGNITION_DELAY_UP,
GADGET_ID_IGNITION_DELAY_TEXT, GADGET_ID_NONE,
{ -1, NULL }
};
+static struct ValueTextInfo options_time_score_base[] =
+{
+ { 1, "per second/step" },
+ { 10, "per 10 seconds/steps" },
+
+ { -1, NULL }
+};
+
static struct ValueTextInfo options_game_engine_type[] =
{
{ GAME_ENGINE_TYPE_RND, "Rocks'n'Diamonds" },
{ CE_HEADLINE_SPECIAL_EVENTS, "[mouse events]" },
{ CE_CLICKED_BY_MOUSE, "clicked by mouse" },
{ CE_PRESSED_BY_MOUSE, "pressed by mouse" },
+ { CE_UNDEFINED, " " },
+ { CE_HEADLINE_SPECIAL_EVENTS, "[static states]" },
+ { CE_NEXT_TO_PLAYER, "next to player" },
{ -1, NULL }
};
{ CE_HEADLINE_SPECIAL_EVENTS, "[mouse events]" },
{ CE_MOUSE_CLICKED_ON_X, "mouse clicked on" },
{ CE_MOUSE_PRESSED_ON_X, "mouse pressed on" },
+ { CE_UNDEFINED, " " },
+ { CE_HEADLINE_SPECIAL_EVENTS, "[static states]" },
+ { CE_PLAYER_NEXT_TO_X, "player next to" },
+ { CE_NEXT_TO_X, "next to" },
{ -1, NULL }
};
NULL, NULL, "(0 => no limit)", "time or step limit"
},
{
- ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(11),
+ -1, ED_LEVEL_SETTINGS_YPOS(10),
+ GADGET_ID_TIME_SCORE_BASE, GADGET_ID_LEVEL_TIMESCORE_UP,
+ -1,
+ options_time_score_base,
+ &level.time_score_base,
+ NULL, NULL, NULL, "time score for 1 or 10 seconds/steps"
+ },
+ {
+ ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(12),
GADGET_ID_GAME_ENGINE_TYPE, GADGET_ID_NONE,
-1,
options_game_engine_type,
NULL, " can", ":", "leave behind or change element"
},
{
- -1, ED_ELEMENT_SETTINGS_YPOS(7),
+ -1, ED_ELEMENT_SETTINGS_YPOS(8),
GADGET_ID_CUSTOM_SMASH_TARGETS, GADGET_ID_CUSTOM_CAN_SMASH,
-1,
options_smash_targets,
NULL, "can smash", NULL, "elements that can be smashed"
},
{
- ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(8),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(9),
GADGET_ID_CUSTOM_SLIPPERY_TYPE, GADGET_ID_NONE,
-1,
options_slippery_type,
NULL, "slippery", NULL, "where other elements fall down"
},
{
- ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(9),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(10),
GADGET_ID_CUSTOM_DEADLINESS, GADGET_ID_NONE,
-1,
options_deadliness,
NULL, "deadly when", NULL, "deadliness of element"
},
{
- ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(10),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(11),
GADGET_ID_CUSTOM_EXPLOSION_TYPE, GADGET_ID_NONE,
-1,
options_explosion_type,
NULL, NULL,
"automatically count gems needed", "set counter to number of gems"
},
+ {
+ ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(11),
+ GADGET_ID_RATE_TIME_OVER_SCORE, GADGET_ID_NONE,
+ &level.rate_time_over_score,
+ NULL, NULL,
+ "rate time/steps used over score", "sort high scores by playing time/steps"
+ },
{
ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(7),
GADGET_ID_USE_LEVELSET_ARTWORK, GADGET_ID_NONE,
NULL, NULL,
"only one player must enter exit", "level solved by first player in exit"
},
+ {
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3),
+ GADGET_ID_FINISH_DIG_COLLECT, GADGET_ID_NONE,
+ &level.finish_dig_collect,
+ NULL, NULL,
+ "CE action on finished dig/collect", "only finished dig/collect triggers CE"
+ },
+ {
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4),
+ GADGET_ID_KEEP_WALKABLE_CE, GADGET_ID_NONE,
+ &level.keep_walkable_ce,
+ NULL, NULL,
+ "keep walkable CE changed to player", "keep CE changing to player if walkable"
+ },
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9),
GADGET_ID_CONTINUOUS_SNAPPING, GADGET_ID_NONE,
NULL, "element can move with some pattern"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(7),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8),
GADGET_ID_CUSTOM_CAN_FALL, GADGET_ID_NONE,
&custom_element_properties[EP_CAN_FALL],
NULL, NULL,
"can fall", "element can fall down"
},
{
- -1, ED_ELEMENT_SETTINGS_YPOS(7),
+ -1, ED_ELEMENT_SETTINGS_YPOS(8),
GADGET_ID_CUSTOM_CAN_SMASH, GADGET_ID_CUSTOM_CAN_FALL,
&custom_element_properties[EP_CAN_SMASH],
NULL, " ",
NULL, "element can smash other elements"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9),
GADGET_ID_CUSTOM_SLIPPERY, GADGET_ID_NONE,
&custom_element_properties[EP_SLIPPERY],
NULL, NULL,
NULL, "other elements can fall down from it"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10),
GADGET_ID_CUSTOM_DEADLY, GADGET_ID_NONE,
&custom_element_properties[EP_DEADLY],
NULL, NULL,
NULL, "element can kill the player"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(11),
GADGET_ID_CUSTOM_CAN_EXPLODE, GADGET_ID_NONE,
&custom_element_properties[EP_CAN_EXPLODE],
NULL, NULL,
NULL, "element can explode"
},
{
- ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(11),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(12),
GADGET_ID_CUSTOM_EXPLODE_FIRE, GADGET_ID_NONE,
&custom_element_properties[EP_EXPLODES_BY_FIRE],
NULL, NULL,
"by fire", "element can explode by fire/explosion"
},
{
- -1, ED_ELEMENT_SETTINGS_YPOS(11),
+ -1, ED_ELEMENT_SETTINGS_YPOS(12),
GADGET_ID_CUSTOM_EXPLODE_SMASH, GADGET_ID_CUSTOM_EXPLODE_FIRE,
&custom_element_properties[EP_EXPLODES_SMASHED],
NULL, " ",
"smashed", "element can explode when smashed"
},
{
- -1, ED_ELEMENT_SETTINGS_YPOS(11),
+ -1, ED_ELEMENT_SETTINGS_YPOS(12),
GADGET_ID_CUSTOM_EXPLODE_IMPACT, GADGET_ID_CUSTOM_EXPLODE_SMASH,
&custom_element_properties[EP_EXPLODES_IMPACT],
NULL, " ",
// ---------- custom content (when exploding) -------------------------------
{
- -1, ED_AREA_3X3_SETTINGS_YPOS(10),
+ -1, ED_AREA_3X3_SETTINGS_YPOS(11),
0, ED_AREA_3X3_SETTINGS_YOFF,
GADGET_ID_CUSTOM_CONTENT, GADGET_ID_NONE, // align three rows
&custom_element.content.e[0][0], 3, 3,
static int num_editor_hl_group = ARRAY_SIZE(editor_hl_group);
static int num_editor_el_group = ARRAY_SIZE(editor_el_group);
+static int editor_hl_empty_space[] =
+{
+ EL_INTERNAL_CASCADE_ES_ACTIVE,
+ EL_CHAR('E'),
+ EL_CHAR('S'),
+ EL_EMPTY,
+};
+
+static int editor_el_empty_space[] =
+{
+ EL_EMPTY_SPACE_1,
+ EL_EMPTY_SPACE_2,
+ EL_EMPTY_SPACE_3,
+ EL_EMPTY_SPACE_4,
+
+ EL_EMPTY_SPACE_5,
+ EL_EMPTY_SPACE_6,
+ EL_EMPTY_SPACE_7,
+ EL_EMPTY_SPACE_8,
+
+ EL_EMPTY_SPACE_9,
+ EL_EMPTY_SPACE_10,
+ EL_EMPTY_SPACE_11,
+ EL_EMPTY_SPACE_12,
+
+ EL_EMPTY_SPACE_13,
+ EL_EMPTY_SPACE_14,
+ EL_EMPTY_SPACE_15,
+ EL_EMPTY_SPACE_16
+};
+static int *editor_hl_empty_space_ptr = editor_hl_empty_space;
+static int *editor_el_empty_space_ptr = editor_el_empty_space;
+static int num_editor_hl_empty_space = ARRAY_SIZE(editor_hl_empty_space);
+static int num_editor_el_empty_space = ARRAY_SIZE(editor_el_empty_space);
+
static int editor_hl_reference[] =
{
EL_INTERNAL_CASCADE_REF_ACTIVE,
&editor_hl_group_ptr, &num_editor_hl_group,
&editor_el_group_ptr, &num_editor_el_group
},
+ {
+ &setup_editor_el_custom,
+ &setup.editor_cascade.el_es,
+ &editor_hl_empty_space_ptr, &num_editor_hl_empty_space,
+ &editor_el_empty_space_ptr, &num_editor_el_empty_space
+ },
{
&setup_editor_el_custom,
&setup.editor_cascade.el_ref,
static char *getElementDescriptionFilenameExt(char *basename)
{
- char *elements_subdir = "elements";
+ char *elements_subdir = ELEMENTS_DIRECTORY;
static char *elements_subdir2 = NULL;
static char *filename = NULL;
if (filename != NULL)
return filename;
+ // 3rd try: look for generic fallback text file for any element
+ filename = getElementDescriptionFilenameExt(FALLBACK_TEXT_FILENAME);
+ if (filename != NULL)
+ return filename;
+
return NULL;
}
int element = (*editor_elements_info[i].element_list)[j];
if (element >= NUM_FILE_ELEMENTS)
- Error(ERR_WARN, "editor element %d is runtime element", element);
+ Warn("editor element %d is runtime element", element);
if (strEqual(getElementInfoText(element), INFOTEXT_UNKNOWN_ELEMENT))
- Error(ERR_WARN, "no element description text for element %d", element);
+ Warn("no element description text for element %d", element);
}
}
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
}
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
}
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
}
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
right_gadget_border[id] =
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
right_gadget_border[id] =
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
right_gadget_border[id] =
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
}
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
}
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
right_gadget_border[id] =
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
right_gadget_border[id] =
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
right_gadget_border[id] =
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
}
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
right_gadget_border[id] =
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
right_gadget_border[id] =
num_editor_gadgets = NUM_EDITOR_GADGETS;
- // printf("::: allocating %d gadgets ...\n", num_editor_gadgets);
+ // Debug("editor", "allocating %d gadgets ...\n", num_editor_gadgets);
level_editor_gadget =
checked_calloc(num_editor_gadgets * sizeof(struct GadgetInfo *));
{
int i;
- // printf("::: freeing %d gadgets ...\n", num_editor_gadgets);
+ // Debug("editor", "freeing %d gadgets ...\n", num_editor_gadgets);
for (i = 0; i < num_editor_gadgets; i++)
{
return TRUE;
}
- if (!Request("This level is read only! "
+ if (!Request("This level is read-only! "
"Save into personal level set?", REQ_ASK))
return FALSE;
// set "change by direct action" selectbox help value
custom_element_change.direct_action =
- (HAS_CHANGE_EVENT(element, CE_TOUCHED_BY_PLAYER) ? CE_TOUCHED_BY_PLAYER :
+ (HAS_CHANGE_EVENT(element, CE_NEXT_TO_PLAYER) ? CE_NEXT_TO_PLAYER :
+ HAS_CHANGE_EVENT(element, CE_TOUCHED_BY_PLAYER) ? CE_TOUCHED_BY_PLAYER :
HAS_CHANGE_EVENT(element, CE_PRESSED_BY_PLAYER) ? CE_PRESSED_BY_PLAYER :
HAS_CHANGE_EVENT(element, CE_SWITCHED_BY_PLAYER) ? CE_SWITCHED_BY_PLAYER :
HAS_CHANGE_EVENT(element, CE_SNAPPED_BY_PLAYER) ? CE_SNAPPED_BY_PLAYER :
// set "change by other element action" selectbox help value
custom_element_change.other_action =
- (HAS_CHANGE_EVENT(element, CE_PLAYER_TOUCHES_X) ? CE_PLAYER_TOUCHES_X :
+ (HAS_CHANGE_EVENT(element, CE_PLAYER_NEXT_TO_X) ? CE_PLAYER_NEXT_TO_X :
+ HAS_CHANGE_EVENT(element, CE_PLAYER_TOUCHES_X) ? CE_PLAYER_TOUCHES_X :
HAS_CHANGE_EVENT(element, CE_PLAYER_PRESSES_X) ? CE_PLAYER_PRESSES_X :
HAS_CHANGE_EVENT(element, CE_PLAYER_SWITCHES_X) ? CE_PLAYER_SWITCHES_X :
HAS_CHANGE_EVENT(element, CE_PLAYER_SNAPS_X) ? CE_PLAYER_SNAPS_X :
HAS_CHANGE_EVENT(element, CE_PLAYER_DIGS_X) ? CE_PLAYER_DIGS_X :
HAS_CHANGE_EVENT(element, CE_PLAYER_COLLECTS_X) ? CE_PLAYER_COLLECTS_X :
HAS_CHANGE_EVENT(element, CE_PLAYER_DROPS_X) ? CE_PLAYER_DROPS_X :
+ HAS_CHANGE_EVENT(element, CE_NEXT_TO_X) ? CE_NEXT_TO_X :
HAS_CHANGE_EVENT(element, CE_TOUCHING_X) ? CE_TOUCHING_X :
HAS_CHANGE_EVENT(element, CE_HITTING_X) ? CE_HITTING_X :
HAS_CHANGE_EVENT(element, CE_DIGGING_X) ? CE_DIGGING_X :
custom_element = element_info[element]; // needed for description
}
+static void CopyEmptyElementPropertiesToEditor(int element)
+{
+ custom_element = element_info[element];
+}
+
static void CopyClassicElementPropertiesToEditor(int element)
{
- if (ELEM_IS_PLAYER(element) || COULD_MOVE_INTO_ACID(element))
+ if (IS_PLAYER_ELEMENT(element) || COULD_MOVE_INTO_ACID(element))
custom_element_properties[EP_CAN_MOVE_INTO_ACID] =
getMoveIntoAcidProperty(&level, element);
CopyCustomElementPropertiesToEditor(element);
else if (IS_GROUP_ELEMENT(element))
CopyGroupElementPropertiesToEditor(element);
+ else if (IS_EMPTY_ELEMENT(element))
+ CopyEmptyElementPropertiesToEditor(element);
else
CopyClassicElementPropertiesToEditor(element);
}
// ---------- element settings: advanced (custom elements) ------------------
// set player change event from checkbox and selectbox
+ custom_element_change_events[CE_NEXT_TO_PLAYER] = FALSE;
custom_element_change_events[CE_TOUCHED_BY_PLAYER] = FALSE;
custom_element_change_events[CE_PRESSED_BY_PLAYER] = FALSE;
custom_element_change_events[CE_SWITCHED_BY_PLAYER] = FALSE;
custom_element_change_events[CE_BY_DIRECT_ACTION];
// set other element action change event from checkbox and selectbox
+ custom_element_change_events[CE_PLAYER_NEXT_TO_X] = FALSE;
custom_element_change_events[CE_PLAYER_TOUCHES_X] = FALSE;
custom_element_change_events[CE_PLAYER_PRESSES_X] = FALSE;
custom_element_change_events[CE_PLAYER_SWITCHES_X] = FALSE;
custom_element_change_events[CE_PLAYER_DIGS_X] = FALSE;
custom_element_change_events[CE_PLAYER_COLLECTS_X] = FALSE;
custom_element_change_events[CE_PLAYER_DROPS_X] = FALSE;
+ custom_element_change_events[CE_NEXT_TO_X] = FALSE;
custom_element_change_events[CE_TOUCHING_X] = FALSE;
custom_element_change_events[CE_HITTING_X] = FALSE;
custom_element_change_events[CE_DIGGING_X] = FALSE;
InitElementPropertiesGfxElement();
}
+static void CopyEmptyElementPropertiesToGame(int element)
+{
+ // mark that this empty element has been modified
+ custom_element.modified_settings = TRUE;
+ level.changed = TRUE;
+
+ if (level.use_custom_template)
+ AskToCopyAndModifyLevelTemplate();
+
+ element_info[element] = custom_element;
+
+ // needed here to restore runtime value "element_info[element].gfx_element"
+ InitElementPropertiesGfxElement();
+}
+
static void CopyClassicElementPropertiesToGame(int element)
{
- if (ELEM_IS_PLAYER(element) || COULD_MOVE_INTO_ACID(element))
+ if (IS_PLAYER_ELEMENT(element) || COULD_MOVE_INTO_ACID(element))
setMoveIntoAcidProperty(&level, element,
custom_element_properties[EP_CAN_MOVE_INTO_ACID]);
CopyCustomElementPropertiesToGame(element);
else if (IS_GROUP_ELEMENT(element))
CopyGroupElementPropertiesToGame(element);
+ else if (IS_EMPTY_ELEMENT(element))
+ CopyEmptyElementPropertiesToGame(element);
else
CopyClassicElementPropertiesToGame(element);
}
for (i = 0; i < NUM_FILE_ELEMENTS; i++)
if (getElementDescriptionFilename(i) == NULL && !IS_OBSOLETE(i))
- Error(ERR_WARN, "no element description file for element '%s'",
- EL_NAME(i));
+ Warn("no element description file for element '%s'", EL_NAME(i));
}
#endif
int i;
// draw two config tabulators for player elements
- if (ELEM_IS_PLAYER(properties_element))
+ if (IS_PLAYER_ELEMENT(properties_element))
id_last = ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_2;
// draw two config and one "change" tabulator for custom elements
// use "config 1" and "config 2" instead of "config" for players and CEs
if (i == ED_TEXTBUTTON_ID_PROPERTIES_CONFIG &&
- (ELEM_IS_PLAYER(properties_element) ||
+ (IS_PLAYER_ELEMENT(properties_element) ||
IS_CUSTOM_ELEMENT(properties_element)))
continue;
if (IS_GEM(element) ||
IS_CUSTOM_ELEMENT(element) ||
IS_GROUP_ELEMENT(element) ||
+ IS_EMPTY_ELEMENT(element) ||
IS_BALLOON_ELEMENT(element) ||
IS_ENVELOPE(element) ||
IS_MM_MCDUFFIN(element) ||
IS_DF_LASER(element) ||
- ELEM_IS_PLAYER(element) ||
+ IS_PLAYER_ELEMENT(element) ||
HAS_EDITOR_CONTENT(element) ||
CAN_GROW(element) ||
COULD_MOVE_INTO_ACID(element) ||
DrawAndroidElementArea(properties_element);
}
- if (ELEM_IS_PLAYER(properties_element))
+ if (IS_PLAYER_ELEMENT(properties_element))
{
int player_nr = GET_PLAYER_NR(properties_element);
// draw checkbutton gadgets
MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY);
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_FINISH_DIG_COLLECT);
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_KEEP_WALKABLE_CE);
// draw counter gadgets
MapCounterButtons(ED_COUNTER_ID_INVENTORY_SIZE);
MapCheckbuttonGadget(ED_CHECKBUTTON_ID_EM_EXPLODES_BY_FIRE);
if (COULD_MOVE_INTO_ACID(properties_element) &&
- !ELEM_IS_PLAYER(properties_element) &&
+ !IS_PLAYER_ELEMENT(properties_element) &&
(!IS_CUSTOM_ELEMENT(properties_element) ||
edit_mode_properties == ED_MODE_PROPERTIES_CONFIG_2))
{
checkbutton_info[ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID].x =
ED_ELEMENT_SETTINGS_XPOS(IS_CUSTOM_ELEMENT(properties_element) ? 1 : 0);
checkbutton_info[ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID].y =
- ED_ELEMENT_SETTINGS_YPOS(IS_CUSTOM_ELEMENT(properties_element) ? 6 :
+ ED_ELEMENT_SETTINGS_YPOS(IS_CUSTOM_ELEMENT(properties_element) ? 7 :
IS_BALLOON_ELEMENT(properties_element) ||
HAS_EDITOR_CONTENT(properties_element) ? 1 : 0);
draw_footer_line = TRUE;
}
+ else if (IS_EMPTY_ELEMENT(properties_element))
+ {
+ // draw stickybutton gadget
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_STICK_ELEMENT);
+
+ // draw checkbutton gadgets
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC);
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1);
+
+ // draw textbutton gadgets
+ MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1);
+
+ // draw drawing area gadgets
+ MapDrawingArea(ED_DRAWING_ID_CUSTOM_GRAPHIC);
+
+ draw_footer_line = TRUE;
+ }
// draw little footer border line above CE/GE use/save template gadgets
if (draw_footer_line)
edit_mode_properties = ED_MODE_PROPERTIES_CONFIG_2;
if (edit_mode_properties > ED_MODE_PROPERTIES_CONFIG &&
- !ELEM_IS_PLAYER(properties_element) &&
+ !IS_PLAYER_ELEMENT(properties_element) &&
!IS_CUSTOM_ELEMENT(properties_element))
edit_mode_properties = ED_MODE_PROPERTIES_CONFIG;
if (edit_mode_properties == ED_MODE_PROPERTIES_CONFIG &&
- (ELEM_IS_PLAYER(properties_element) ||
+ (IS_PLAYER_ELEMENT(properties_element) ||
IS_CUSTOM_ELEMENT(properties_element)))
edit_mode_properties = ED_MODE_PROPERTIES_CONFIG_1;
mode == CB_BRUSH_TO_CLIPBOARD_SMALL)
SDL_SetClipboardText(text);
else
- printf("%s", text);
+ Print("%s", text); // print brush data to console and log file
return;
}
ptr++;
}
+ // remap some (historic, now obsolete) elements
+ element = getMappedElement(element);
+
if (element >= NUM_FILE_ELEMENTS)
element = EL_UNKNOWN;
lev_fieldx = level.fieldx = brush_width;
lev_fieldy = level.fieldy = brush_height;
+ boolean use_em_engine = TRUE;
+ boolean use_sp_engine = TRUE;
+ boolean use_mm_engine = TRUE;
+
+ for (x = 0; x < MAX_LEV_FIELDX; x++)
+ {
+ for (y = 0; y < MAX_LEV_FIELDY; y++)
+ {
+ int element = Tile[x][y];
+
+ if (!IS_EM_ELEMENT(element) && !IS_PLAYER_ELEMENT(element))
+ use_em_engine = FALSE;
+
+ if (!IS_SP_ELEMENT(element))
+ use_sp_engine = FALSE;
+
+ if (!IS_MM_ELEMENT(element) && element != EL_EMPTY)
+ use_mm_engine = FALSE;
+ }
+ }
+
+ level.game_engine_type = (use_em_engine ? GAME_ENGINE_TYPE_EM :
+ use_sp_engine ? GAME_ENGINE_TYPE_SP :
+ use_mm_engine ? GAME_ENGINE_TYPE_MM :
+ GAME_ENGINE_TYPE_RND);
+
+ // update element selection list
+ ReinitializeElementList();
+ ModifyEditorElementList();
+
SetBorderElement();
DrawEditModeWindow();
CopyLevelToUndoBuffer(UNDO_ACCUMULATE);
}
+static void DrawAreaElementHighlight(boolean highlighted)
+{
+ DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
+
+ if (!highlighted)
+ return;
+
+ int x, y;
+
+ for (x = 0; x < ed_fieldx; x++)
+ {
+ for (y = 0; y < ed_fieldy; y++)
+ {
+ int lx = x + level_xpos;
+ int ly = y + level_ypos;
+
+ if (!IN_LEV_FIELD(lx, ly))
+ continue;
+
+ if (Tile[lx][ly] != new_element1)
+ continue;
+
+ int sx = SX + x * ed_tilesize;
+ int sy = SY + y * ed_tilesize;
+ int from_sx = sx;
+ int from_sy = sy;
+ int to_sx = sx + ed_tilesize - 1;
+ int to_sy = sy + ed_tilesize - 1;
+
+ DrawSimpleWhiteLine(drawto, from_sx, from_sy, to_sx, from_sy);
+ DrawSimpleWhiteLine(drawto, to_sx, from_sy, to_sx, to_sy);
+ DrawSimpleWhiteLine(drawto, to_sx, to_sy, from_sx, to_sy);
+ DrawSimpleWhiteLine(drawto, from_sx, to_sy, from_sx, from_sy);
+ }
+ }
+}
+
static void CopyLevelTemplateToUserLevelSet(char *levelset_subdir)
{
char *template_filename_old = getLocalLevelTemplateFilename();
{
SetDrawModeHiRes(new_element);
- if (ELEM_IS_PLAYER(new_element))
+ if (IS_PLAYER_ELEMENT(new_element))
{
// remove player at old position
for (y = 0; y < lev_fieldy; y++)
{
int old_element = Tile[x][y];
- if (ELEM_IS_PLAYER(old_element))
+ if (IS_PLAYER_ELEMENT(old_element))
{
int replaced_with_element =
(old_element == EL_SOKOBAN_FIELD_PLAYER &&
if (levelset_save_mode == LEVELSET_SAVE_MODE_UPDATE &&
leveldir_current->readonly)
{
- Request("This level set is read only!", REQ_CONFIRM);
+ Request("This level set is read-only!", REQ_CONFIRM);
return;
}
boolean template_related_changes_found = FALSE;
int i;
- // check if any custom or group elements have been changed
+ // check if any custom, group or empty elements have been changed
for (i = 0; i < NUM_FILE_ELEMENTS; i++)
- if ((IS_CUSTOM_ELEMENT(i) || IS_GROUP_ELEMENT(i)) &&
+ if ((IS_CUSTOM_ELEMENT(i) ||
+ IS_GROUP_ELEMENT(i) ||
+ IS_EMPTY_ELEMENT(i)) &&
element_info[i].modified_settings)
template_related_changes_found = TRUE;
}
else
{
- ChangeEditModeWindow(last_edit_mode);
+ ChangeEditModeWindow(ED_MODE_DRAWING);
ClickOnGadget(level_editor_gadget[last_level_drawing_function],
MB_LEFTBUTTON);
}
else
{
- ChangeEditModeWindow(last_edit_mode);
+ ChangeEditModeWindow(ED_MODE_DRAWING);
}
break;
}
#ifdef DEBUG
else if (gi->event.type == GD_EVENT_PRESSED)
- printf("default: HandleControlButtons: GD_EVENT_PRESSED(%d)\n", id);
+ Debug("editor", "default: HandleControlButtons: GD_EVENT_PRESSED(%d)", id);
else if (gi->event.type == GD_EVENT_RELEASED)
- printf("default: HandleControlButtons: GD_EVENT_RELEASED(%d)\n", id);
+ Debug("editor", "default: HandleControlButtons: GD_EVENT_RELEASED(%d)", id);
else if (gi->event.type == GD_EVENT_MOVING)
- printf("default: HandleControlButtons: GD_EVENT_MOVING(%d)\n", id);
+ Debug("editor", "default: HandleControlButtons: GD_EVENT_MOVING(%d)", id);
else
- printf("default: HandleControlButtons: ? (id == %d)\n", id);
+ Debug("editor", "default: HandleControlButtons: ? (id == %d)", id);
#endif
break;
}
ClickOnGadget(level_editor_gadget[i], button);
}
-void HandleLevelEditorIdle(void)
+static void HandleLevelEditorIdle_Properties(void)
{
int element_border = graphic_info[IMG_EDITOR_ELEMENT_BORDER].border_size;
int x = editor.settings.element_graphic.x + element_border;
unsigned int action_delay_value = GameFrameDelay;
int i;
- if (edit_mode != ED_MODE_PROPERTIES)
- return;
-
if (!DelayReached(&action_delay, action_delay_value))
return;
FrameCounter++; // increase animation frame counter
}
+static void HandleLevelEditorIdle_Drawing(void)
+{
+ static boolean last_highlighted = FALSE;
+ boolean highlighted = (GetKeyModState() & KMOD_Alt);
+
+ if (highlighted != last_highlighted)
+ {
+ DrawAreaElementHighlight(highlighted);
+
+ last_highlighted = highlighted;
+
+ redraw_mask |= REDRAW_FIELD;
+ }
+}
+
+void HandleLevelEditorIdle(void)
+{
+ if (edit_mode == ED_MODE_PROPERTIES)
+ HandleLevelEditorIdle_Properties();
+ else if (edit_mode == ED_MODE_DRAWING)
+ HandleLevelEditorIdle_Drawing();
+}
+
static void ClearEditorGadgetInfoText(void)
{
DrawBackground(INFOTEXT_XPOS, INFOTEXT_YPOS, INFOTEXT_XSIZE, INFOTEXT_YSIZE);