// (c) 1995-2014 by Artsoft Entertainment
// Holger Schemel
// info@artsoft.org
-// http://www.artsoft.org/
+// https://www.artsoft.org/
// ----------------------------------------------------------------------------
// editor.c
// ============================================================================
GADGET_ID_PICK_ELEMENT,
GADGET_ID_UNDO,
- GADGET_ID_INFO,
+ GADGET_ID_CONF,
GADGET_ID_SAVE,
GADGET_ID_CLEAR,
GADGET_ID_TEST,
GADGET_ID_INVENTORY_SIZE_DOWN,
GADGET_ID_INVENTORY_SIZE_TEXT,
GADGET_ID_INVENTORY_SIZE_UP,
+ GADGET_ID_MM_BALL_CONTENT_DOWN,
+ GADGET_ID_MM_BALL_CONTENT_TEXT,
+ GADGET_ID_MM_BALL_CONTENT_UP,
GADGET_ID_CUSTOM_SCORE_DOWN,
GADGET_ID_CUSTOM_SCORE_TEXT,
GADGET_ID_CUSTOM_SCORE_UP,
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,
GADGET_ID_ARTWORK_ELEMENT,
GADGET_ID_EXPLOSION_ELEMENT,
GADGET_ID_INVENTORY_CONTENT,
+ GADGET_ID_MM_BALL_CONTENT,
GADGET_ID_CUSTOM_GRAPHIC,
GADGET_ID_CUSTOM_CONTENT,
GADGET_ID_CUSTOM_MOVE_ENTER,
// 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,
GADGET_ID_PLAYER_SPEED,
+ GADGET_ID_MM_BALL_CHOICE_MODE,
GADGET_ID_CUSTOM_WALK_TO_ACTION,
GADGET_ID_CUSTOM_EXPLOSION_TYPE,
GADGET_ID_CUSTOM_DEADLINESS,
// textbutton identifiers
- GADGET_ID_LEVELINFO_LEVEL,
- GADGET_ID_LEVELINFO_LEVELSET,
- GADGET_ID_LEVELINFO_EDITOR,
+ GADGET_ID_LEVELCONFIG_LEVEL,
+ GADGET_ID_LEVELCONFIG_LEVELSET,
+ GADGET_ID_LEVELCONFIG_EDITOR,
GADGET_ID_PROPERTIES_INFO,
GADGET_ID_PROPERTIES_CONFIG,
GADGET_ID_PROPERTIES_CONFIG_1,
// 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_USE_TIME_ORB_BUG,
GADGET_ID_USE_LIFE_BUGS,
GADGET_ID_RANDOM_BALL_CONTENT,
- GADGET_ID_INITIAL_BALL_STATE,
+ GADGET_ID_INITIAL_BALL_ACTIVE,
GADGET_ID_GROW_INTO_DIGGABLE,
GADGET_ID_SB_FIELDS_NEEDED,
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,
GADGET_ID_DF_LASER_RED,
GADGET_ID_DF_LASER_GREEN,
GADGET_ID_DF_LASER_BLUE,
+ GADGET_ID_ROTATE_MM_BALL_CONTENT,
+ GADGET_ID_EXPLODE_MM_BALL,
GADGET_ID_CUSTOM_INDESTRUCTIBLE,
GADGET_ID_CUSTOM_CAN_EXPLODE,
GADGET_ID_CUSTOM_EXPLODE_FIRE,
ED_COUNTER_ID_ENVELOPE_XSIZE,
ED_COUNTER_ID_ENVELOPE_YSIZE,
ED_COUNTER_ID_INVENTORY_SIZE,
+ ED_COUNTER_ID_MM_BALL_CONTENT,
ED_COUNTER_ID_CUSTOM_SCORE,
ED_COUNTER_ID_CUSTOM_GEMCOUNT,
ED_COUNTER_ID_CUSTOM_VALUE_FIX,
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,
ED_SELECTBOX_ID_PLAYER_SPEED,
+ ED_SELECTBOX_ID_MM_BALL_CHOICE_MODE,
ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE,
ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER,
ED_SELECTBOX_ID_CUSTOM_ACCESS_PROTECTED,
// values for textbutton gadgets
enum
{
- ED_TEXTBUTTON_ID_LEVELINFO_LEVEL,
- ED_TEXTBUTTON_ID_LEVELINFO_LEVELSET,
- ED_TEXTBUTTON_ID_LEVELINFO_EDITOR,
+ ED_TEXTBUTTON_ID_LEVELCONFIG_LEVEL,
+ ED_TEXTBUTTON_ID_LEVELCONFIG_LEVELSET,
+ ED_TEXTBUTTON_ID_LEVELCONFIG_EDITOR,
ED_TEXTBUTTON_ID_PROPERTIES_INFO,
ED_TEXTBUTTON_ID_PROPERTIES_CONFIG,
ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_1,
ED_NUM_TEXTBUTTONS
};
-#define ED_TAB_BUTTON_ID_LEVELINFO_FIRST ED_TEXTBUTTON_ID_LEVELINFO_LEVEL
-#define ED_TAB_BUTTON_ID_LEVELINFO_LAST ED_TEXTBUTTON_ID_LEVELINFO_EDITOR
+#define ED_TAB_BUTTON_ID_LEVELCONFIG_FIRST ED_TEXTBUTTON_ID_LEVELCONFIG_LEVEL
+#define ED_TAB_BUTTON_ID_LEVELCONFIG_LAST ED_TEXTBUTTON_ID_LEVELCONFIG_EDITOR
#define ED_TAB_BUTTON_ID_PROPERTIES_FIRST ED_TEXTBUTTON_ID_PROPERTIES_INFO
#define ED_TAB_BUTTON_ID_PROPERTIES_LAST ED_TEXTBUTTON_ID_PROPERTIES_CHANGE
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_USE_TIME_ORB_BUG,
ED_CHECKBUTTON_ID_USE_LIFE_BUGS,
ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT,
- ED_CHECKBUTTON_ID_INITIAL_BALL_STATE,
+ ED_CHECKBUTTON_ID_INITIAL_BALL_ACTIVE,
ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE,
ED_CHECKBUTTON_ID_SB_FIELDS_NEEDED,
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,
ED_CHECKBUTTON_ID_DF_LASER_RED,
ED_CHECKBUTTON_ID_DF_LASER_GREEN,
ED_CHECKBUTTON_ID_DF_LASER_BLUE,
+ ED_CHECKBUTTON_ID_ROTATE_MM_BALL_CONTENT,
+ ED_CHECKBUTTON_ID_EXPLODE_MM_BALL,
ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC,
ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1,
ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE,
};
#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
ED_DRAWING_ID_ARTWORK_ELEMENT,
ED_DRAWING_ID_EXPLOSION_ELEMENT,
ED_DRAWING_ID_INVENTORY_CONTENT,
+ ED_DRAWING_ID_MM_BALL_CONTENT,
ED_DRAWING_ID_CUSTOM_GRAPHIC,
ED_DRAWING_ID_CUSTOM_CONTENT,
ED_DRAWING_ID_CUSTOM_MOVE_ENTER,
// screens in the level editor
#define ED_MODE_DRAWING 0
-#define ED_MODE_INFO 1
+#define ED_MODE_LEVELCONFIG 1
#define ED_MODE_PROPERTIES 2
#define ED_MODE_PALETTE 3
// sub-screens in the global settings section
-#define ED_MODE_LEVELINFO_LEVEL ED_TEXTBUTTON_ID_LEVELINFO_LEVEL
-#define ED_MODE_LEVELINFO_LEVELSET ED_TEXTBUTTON_ID_LEVELINFO_LEVELSET
-#define ED_MODE_LEVELINFO_EDITOR ED_TEXTBUTTON_ID_LEVELINFO_EDITOR
+#define ED_MODE_LEVELCONFIG_LEVEL ED_TEXTBUTTON_ID_LEVELCONFIG_LEVEL
+#define ED_MODE_LEVELCONFIG_LEVELSET ED_TEXTBUTTON_ID_LEVELCONFIG_LEVELSET
+#define ED_MODE_LEVELCONFIG_EDITOR ED_TEXTBUTTON_ID_LEVELCONFIG_EDITOR
// sub-screens in the element properties section
#define ED_MODE_PROPERTIES_INFO ED_TEXTBUTTON_ID_PROPERTIES_INFO
"undo/redo last operation", 'u'
},
{
- IMG_GFX_EDITOR_BUTTON_CONF, GADGET_ID_INFO,
+ IMG_GFX_EDITOR_BUTTON_CONF, GADGET_ID_CONF,
&editor.button.conf, GD_TYPE_NORMAL_BUTTON,
- "properties of level", 'I'
+ "level and editor settings", 'I'
},
{
IMG_GFX_EDITOR_BUTTON_SAVE, GADGET_ID_SAVE,
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,
&level.initial_inventory_size[0],
NULL, NULL, "number of inventory elements"
},
+ {
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3),
+ MIN_ELEMENTS_IN_GROUP, MAX_MM_BALL_CONTENTS,
+ GADGET_ID_MM_BALL_CONTENT_DOWN, GADGET_ID_MM_BALL_CONTENT_UP,
+ GADGET_ID_MM_BALL_CONTENT_TEXT, GADGET_ID_NONE,
+ &level.num_mm_ball_contents,
+ NULL, NULL, "number of content elements"
+ },
// ---------- element settings: configure 1 (custom elements) ---------------
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,
int gadget_id;
int xsize, ysize;
char *value;
- char *text_above, *infotext;
+ char *text_above, *text_above_cropped, *infotext;
} textarea_info[ED_NUM_TEXTAREAS] =
{
{
GADGET_ID_ENVELOPE_INFO,
MAX_ENVELOPE_XSIZE, MAX_ENVELOPE_YSIZE,
NULL,
- "Envelope Content:", "Envelope Content"
+ "Envelope Content:", "Envelope Content (cropped):", "Envelope Content"
}
};
{ -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" },
#endif
{ CE_VALUE_GETS_ZERO, "CE value gets 0" },
{ CE_SCORE_GETS_ZERO, "CE score gets 0" },
+ { CE_UNDEFINED, " " },
+ { 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_SCORE_CHANGES_OF_X, "CE score changes of" },
{ CE_VALUE_GETS_ZERO_OF_X, "CE value gets 0 of" },
{ CE_SCORE_GETS_ZERO_OF_X, "CE score gets 0 of" },
+ { CE_UNDEFINED, " " },
+ { 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 }
};
static struct ValueTextInfo options_change_trigger_page[] =
{
- { (1 << 0), "1" },
- { (1 << 1), "2" },
- { (1 << 2), "3" },
- { (1 << 3), "4" },
- { (1 << 4), "5" },
- { (1 << 5), "6" },
- { (1 << 6), "7" },
- { (1 << 7), "8" },
- { (1 << 8), "9" },
- { (1 << 9), "10" },
- { (1 << 10), "11" },
- { (1 << 11), "12" },
- { (1 << 12), "13" },
- { (1 << 13), "14" },
- { (1 << 14), "15" },
- { (1 << 15), "16" },
- { (1 << 16), "17" },
- { (1 << 17), "18" },
- { (1 << 18), "19" },
- { (1 << 19), "20" },
- { (1 << 20), "21" },
- { (1 << 21), "22" },
- { (1 << 22), "23" },
- { (1 << 23), "24" },
- { (1 << 24), "25" },
- { (1 << 25), "26" },
- { (1 << 26), "27" },
- { (1 << 27), "28" },
- { (1 << 28), "29" },
- { (1 << 29), "30" },
- { (1 << 30), "31" },
- { (1 << 31), "32" },
+ { (1u << 0), "1" },
+ { (1u << 1), "2" },
+ { (1u << 2), "3" },
+ { (1u << 3), "4" },
+ { (1u << 4), "5" },
+ { (1u << 5), "6" },
+ { (1u << 6), "7" },
+ { (1u << 7), "8" },
+ { (1u << 8), "9" },
+ { (1u << 9), "10" },
+ { (1u << 10), "11" },
+ { (1u << 11), "12" },
+ { (1u << 12), "13" },
+ { (1u << 13), "14" },
+ { (1u << 14), "15" },
+ { (1u << 15), "16" },
+ { (1u << 16), "17" },
+ { (1u << 17), "18" },
+ { (1u << 18), "19" },
+ { (1u << 19), "20" },
+ { (1u << 20), "21" },
+ { (1u << 21), "22" },
+ { (1u << 22), "23" },
+ { (1u << 23), "24" },
+ { (1u << 24), "25" },
+ { (1u << 25), "26" },
+ { (1u << 26), "27" },
+ { (1u << 27), "28" },
+ { (1u << 28), "29" },
+ { (1u << 29), "30" },
+ { (1u << 30), "31" },
+ { (1u << 31), "32" },
{ CH_PAGE_ANY, "any" },
{ -1, NULL }
{ CA_SET_LEVEL_SCORE, "set score" },
{ CA_SET_LEVEL_GEMS, "set gems" },
{ CA_SET_LEVEL_WIND, "set wind dir." },
- { CA_SET_LEVEL_RANDOM_SEED, "set rand. seed" },
+ { CA_SET_LEVEL_RANDOM_SEED, "set random seed" },
{ CA_UNDEFINED, " " },
{ CA_HEADLINE_PLAYER_ACTIONS, "[player]" },
{ CA_MOVE_PLAYER, "move player" },
+ { CA_MOVE_PLAYER_NEW, "move player new" },
{ CA_EXIT_PLAYER, "exit player" },
{ CA_KILL_PLAYER, "kill player" },
{ CA_SET_PLAYER_KEYS, "set keys" },
{ ANIM_LINEAR, "linear" },
{ ANIM_PINGPONG, "pingpong" },
{ ANIM_PINGPONG2, "pingpong 2" },
+ { ANIM_LEVEL_NR, "level number" },
{ -1, NULL }
};
{ CA_EXIT_PLAYER, 0, options_action_arg_player, },
{ CA_KILL_PLAYER, 0, options_action_arg_player, },
{ CA_MOVE_PLAYER, 0, options_action_arg_direction, },
+ { CA_MOVE_PLAYER_NEW, 0, options_action_arg_direction, },
{ CA_RESTART_LEVEL, 0, options_action_arg_none, },
{ CA_SHOW_ENVELOPE, 0, options_action_arg_envelope, },
{ CA_SET_LEVEL_TIME, 3, options_action_arg_number, },
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,
&level.initial_player_stepsize[0],
NULL, "initial player speed:", NULL, "initial player speed"
},
+ {
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4),
+ GADGET_ID_MM_BALL_CHOICE_MODE, GADGET_ID_NONE,
+ -1,
+ options_group_choice_mode,
+ &level.mm_ball_choice_mode,
+ NULL, "choice type:", NULL, "type of content choice"
+ },
// ---------- element settings: configure 1 (custom elements) ---------------
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,
{
ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(13),
GADGET_ID_ACTION_TYPE, GADGET_ID_NONE,
- -1,
+ 15,
options_action_type,
&custom_element_change.action_type,
NULL, NULL, NULL, "action on specified condition"
{
ED_LEVEL_TABS_XPOS(0), ED_LEVEL_TABS_YPOS(0),
- GADGET_ID_LEVELINFO_LEVEL, GADGET_ID_NONE,
+ GADGET_ID_LEVELCONFIG_LEVEL, GADGET_ID_NONE,
8, "Level",
- NULL, NULL, NULL, "Configure level properties"
+ NULL, NULL, NULL, "Configure level settings"
},
{
-1, -1,
- GADGET_ID_LEVELINFO_LEVELSET, GADGET_ID_LEVELINFO_LEVEL,
+ GADGET_ID_LEVELCONFIG_LEVELSET, GADGET_ID_LEVELCONFIG_LEVEL,
8, "Levelset",
NULL, NULL, NULL, "Update this or create new level set"
},
{
-1, -1,
- GADGET_ID_LEVELINFO_EDITOR, GADGET_ID_LEVELINFO_LEVELSET,
+ GADGET_ID_LEVELCONFIG_EDITOR, GADGET_ID_LEVELCONFIG_LEVELSET,
8, "Editor",
- NULL, NULL, NULL, "Configure editor properties"
+ NULL, NULL, NULL, "Configure editor settings"
},
// ---------- element settings (tabs) ---------------------------------------
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,
},
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
- GADGET_ID_INITIAL_BALL_STATE, GADGET_ID_NONE,
- &level.ball_state_initial,
+ GADGET_ID_INITIAL_BALL_ACTIVE, GADGET_ID_NONE,
+ &level.ball_active_initial,
NULL, NULL,
"magic ball initially activated", "activate magic ball after level start"
},
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, NULL,
"blue", "use blue color components in laser"
},
+ {
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5),
+ GADGET_ID_ROTATE_MM_BALL_CONTENT, GADGET_ID_NONE,
+ &level.rotate_mm_ball_content,
+ NULL, NULL,
+ "randomly rotate created content", "randomly rotate newly created content"
+ },
+ {
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(6),
+ GADGET_ID_EXPLODE_MM_BALL, GADGET_ID_NONE,
+ &level.explode_mm_ball,
+ NULL, NULL,
+ "explode ball instead of melting", "use explosion to release ball content"
+ },
// ---------- element settings: configure 1 (custom elements) ---------------
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, " ",
int gadget_id_align;
int *value;
int area_xsize, area_ysize;
- char *text_left, *text_right, *text_below, *infotext;
+ char *text_left, *text_right, *text_above, *text_below, *infotext;
} drawingarea_info[ED_NUM_DRAWING_AREAS] =
{
// ---------- level playfield content ---------------------------------------
GADGET_ID_DRAWING_LEVEL, GADGET_ID_NONE,
NULL,
-1, -1, // these values are not constant, but can change at runtime
- NULL, NULL, NULL, NULL
+ NULL, NULL, NULL, NULL, NULL
},
// ---------- yam yam content -----------------------------------------------
ED_AREA_YAMYAM_CONTENT_XOFF(0), ED_AREA_YAMYAM_CONTENT_YOFF(0),
GADGET_ID_YAMYAM_CONTENT_0, GADGET_ID_NONE,
&level.yamyam_content[0].e[0][0], 3, 3,
- NULL, NULL, "1", NULL
+ NULL, NULL, NULL, "1", NULL
},
{
ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS,
ED_AREA_YAMYAM_CONTENT_XOFF(1), ED_AREA_YAMYAM_CONTENT_YOFF(1),
GADGET_ID_YAMYAM_CONTENT_1, GADGET_ID_NONE,
&level.yamyam_content[1].e[0][0], 3, 3,
- NULL, NULL, "2", NULL
+ NULL, NULL, NULL, "2", NULL
},
{
ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS,
ED_AREA_YAMYAM_CONTENT_XOFF(2), ED_AREA_YAMYAM_CONTENT_YOFF(2),
GADGET_ID_YAMYAM_CONTENT_2, GADGET_ID_NONE,
&level.yamyam_content[2].e[0][0], 3, 3,
- NULL, NULL, "3", NULL
+ NULL, NULL, NULL, "3", NULL
},
{
ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS,
ED_AREA_YAMYAM_CONTENT_XOFF(3), ED_AREA_YAMYAM_CONTENT_YOFF(3),
GADGET_ID_YAMYAM_CONTENT_3, GADGET_ID_NONE,
&level.yamyam_content[3].e[0][0], 3, 3,
- NULL, NULL, "4", NULL
+ NULL, NULL, NULL, "4", NULL
},
{
ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS,
ED_AREA_YAMYAM_CONTENT_XOFF(4), ED_AREA_YAMYAM_CONTENT_YOFF(4),
GADGET_ID_YAMYAM_CONTENT_4, GADGET_ID_NONE,
&level.yamyam_content[4].e[0][0], 3, 3,
- NULL, NULL, "5", NULL
+ NULL, NULL, NULL, "5", NULL
},
{
ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS,
ED_AREA_YAMYAM_CONTENT_XOFF(5), ED_AREA_YAMYAM_CONTENT_YOFF(5),
GADGET_ID_YAMYAM_CONTENT_5, GADGET_ID_NONE,
&level.yamyam_content[5].e[0][0], 3, 3,
- NULL, NULL, "6", NULL
+ NULL, NULL, NULL, "6", NULL
},
{
ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS,
ED_AREA_YAMYAM_CONTENT_XOFF(6), ED_AREA_YAMYAM_CONTENT_YOFF(6),
GADGET_ID_YAMYAM_CONTENT_6, GADGET_ID_NONE,
&level.yamyam_content[6].e[0][0], 3, 3,
- NULL, NULL, "7", NULL
+ NULL, NULL, NULL, "7", NULL
},
{
ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS,
ED_AREA_YAMYAM_CONTENT_XOFF(7), ED_AREA_YAMYAM_CONTENT_YOFF(7),
GADGET_ID_YAMYAM_CONTENT_7, GADGET_ID_NONE,
&level.yamyam_content[7].e[0][0], 3, 3,
- NULL, NULL, "8", NULL
+ NULL, NULL, NULL, "8", NULL
},
// ---------- magic ball content --------------------------------------------
ED_AREA_MAGIC_BALL_CONTENT_XOFF(0), ED_AREA_MAGIC_BALL_CONTENT_YOFF(0),
GADGET_ID_MAGIC_BALL_CONTENT_0, GADGET_ID_NONE,
&level.ball_content[0].e[0][0], 3, 3,
- NULL, NULL, "1", NULL
+ NULL, NULL, NULL, "1", NULL
},
{
ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS,
ED_AREA_MAGIC_BALL_CONTENT_XOFF(1), ED_AREA_MAGIC_BALL_CONTENT_YOFF(1),
GADGET_ID_MAGIC_BALL_CONTENT_1, GADGET_ID_NONE,
&level.ball_content[1].e[0][0], 3, 3,
- NULL, NULL, "2", NULL
+ NULL, NULL, NULL, "2", NULL
},
{
ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS,
ED_AREA_MAGIC_BALL_CONTENT_XOFF(2), ED_AREA_MAGIC_BALL_CONTENT_YOFF(2),
GADGET_ID_MAGIC_BALL_CONTENT_2, GADGET_ID_NONE,
&level.ball_content[2].e[0][0], 3, 3,
- NULL, NULL, "3", NULL
+ NULL, NULL, NULL, "3", NULL
},
{
ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS,
ED_AREA_MAGIC_BALL_CONTENT_XOFF(3), ED_AREA_MAGIC_BALL_CONTENT_YOFF(3),
GADGET_ID_MAGIC_BALL_CONTENT_3, GADGET_ID_NONE,
&level.ball_content[3].e[0][0], 3, 3,
- NULL, NULL, "4", NULL
+ NULL, NULL, NULL, "4", NULL
},
{
ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS,
ED_AREA_MAGIC_BALL_CONTENT_XOFF(4), ED_AREA_MAGIC_BALL_CONTENT_YOFF(4),
GADGET_ID_MAGIC_BALL_CONTENT_4, GADGET_ID_NONE,
&level.ball_content[4].e[0][0], 3, 3,
- NULL, NULL, "5", NULL
+ NULL, NULL, NULL, "5", NULL
},
{
ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS,
ED_AREA_MAGIC_BALL_CONTENT_XOFF(5), ED_AREA_MAGIC_BALL_CONTENT_YOFF(5),
GADGET_ID_MAGIC_BALL_CONTENT_5, GADGET_ID_NONE,
&level.ball_content[5].e[0][0], 3, 3,
- NULL, NULL, "6", NULL
+ NULL, NULL, NULL, "6", NULL
},
{
ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS,
ED_AREA_MAGIC_BALL_CONTENT_XOFF(6), ED_AREA_MAGIC_BALL_CONTENT_YOFF(6),
GADGET_ID_MAGIC_BALL_CONTENT_6, GADGET_ID_NONE,
&level.ball_content[6].e[0][0], 3, 3,
- NULL, NULL, "7", NULL
+ NULL, NULL, NULL, "7", NULL
},
{
ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS,
ED_AREA_MAGIC_BALL_CONTENT_XOFF(7), ED_AREA_MAGIC_BALL_CONTENT_YOFF(7),
GADGET_ID_MAGIC_BALL_CONTENT_7, GADGET_ID_NONE,
&level.ball_content[7].e[0][0], 3, 3,
- NULL, NULL, "8", NULL
+ NULL, NULL, NULL, "8", NULL
},
// ---------- android content -----------------------------------------------
{
- ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(5),
+ ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(6),
ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_ANDROID_CONTENT, GADGET_ID_NONE,
&level.android_clone_element[0], MAX_ANDROID_ELEMENTS, 1,
- "elements:", NULL, NULL, "elements android can clone"
+ NULL, NULL, "elements:", NULL, "elements android can clone"
},
// ---------- amoeba content ------------------------------------------------
ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_AMOEBA_CONTENT, GADGET_ID_NONE,
&level.amoeba_content, 1, 1,
- "content:", NULL, NULL, "amoeba content"
+ "content:", NULL, NULL, NULL, "amoeba content"
},
// ---------- level start element -------------------------------------------
0, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_START_ELEMENT, GADGET_ID_USE_START_ELEMENT,
&level.start_element[0], 1, 1,
- NULL, NULL, NULL, "level start element"
+ NULL, NULL, NULL, NULL, "level start element"
},
// ---------- player artwork element ----------------------------------------
0, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_ARTWORK_ELEMENT, GADGET_ID_USE_ARTWORK_ELEMENT,
&level.artwork_element[0], 1, 1,
- NULL, NULL, NULL, "element for player artwork"
+ NULL, NULL, NULL, NULL, "element for player artwork"
},
// ---------- player explosion element --------------------------------------
0, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_EXPLOSION_ELEMENT, GADGET_ID_USE_EXPLOSION_ELEMENT,
&level.explosion_element[0], 1, 1,
- NULL, NULL, NULL, "element for player explosion"
+ NULL, NULL, NULL, NULL, "element for player explosion"
},
// ---------- player initial inventory --------------------------------------
0, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_INVENTORY_CONTENT, GADGET_ID_USE_INITIAL_INVENTORY,
&level.initial_inventory_content[0][0], MAX_INITIAL_INVENTORY_SIZE, 1,
- NULL, NULL, NULL, "content for initial inventory"
+ NULL, NULL, NULL, NULL, "content for initial inventory"
+ },
+
+ // ---------- gray ball content -----------------------------------------
+
+ {
+ ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(2),
+ ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF,
+ GADGET_ID_MM_BALL_CONTENT, GADGET_ID_NONE,
+ &level.mm_ball_content[0], MAX_MM_BALL_CONTENTS, 1,
+ "content:", NULL, NULL, NULL, "content for gray ball"
},
// ---------- element settings: configure 1 (custom elements) ---------------
-1, ED_AREA_1X1_SETTINGS_YPOS(1),
0, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_CUSTOM_GRAPHIC, GADGET_ID_CUSTOM_USE_GRAPHIC,
- &custom_element.gfx_element_initial,1, 1,
- NULL, NULL, NULL, "custom graphic element"
+ &custom_element.gfx_element_initial, 1, 1,
+ NULL, NULL, NULL, NULL, "custom graphic element"
},
// ---------- element settings: configure 2 (custom elements) ---------------
// ---------- 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,
- "content:", NULL, NULL, NULL
+ "content:", NULL, NULL, NULL, NULL
},
// ---------- custom enter and leave element (when moving) ------------------
ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_CUSTOM_MOVE_ENTER, GADGET_ID_NONE,
&custom_element.move_enter_element, 1, 1,
- "can dig:", " ", NULL, "element that can be digged/collected"
+ "can dig:", " ", NULL, NULL, "element that can be digged/collected"
},
{
-1, ED_AREA_1X1_SETTINGS_YPOS(3),
0, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_CUSTOM_MOVE_LEAVE, GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE,
&custom_element.move_leave_element, 1, 1,
- NULL, NULL, NULL, "element that will be left behind"
+ NULL, NULL, NULL, NULL, "element that will be left behind"
},
// ---------- element settings: advanced (custom elements) ------------------
0, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_CUSTOM_CHANGE_TARGET, GADGET_ID_CUSTOM_CAN_CHANGE,
&custom_element_change.target_element, 1, 1,
- NULL, "after/when:", NULL, "new target element after change"
+ NULL, "after/when:", NULL, NULL, "new target element after change"
},
// ---------- custom change content (extended change target) ----------------
0, ED_AREA_3X3_SETTINGS_YOFF,
GADGET_ID_CUSTOM_CHANGE_CONTENT, GADGET_ID_NONE, // align three rows
&custom_element_change.target_content.e[0][0], 3, 3,
- NULL, NULL, NULL, "new extended elements after change"
+ NULL, NULL, NULL, NULL, "new extended elements after change"
},
// ---------- custom change trigger (element causing change) ----------------
0, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_CUSTOM_CHANGE_TRIGGER, GADGET_ID_CHANGE_OTHER_ACTION,
&custom_element_change.initial_trigger_element, 1, 1,
- NULL, NULL, NULL, "other element triggering change"
+ NULL, NULL, NULL, NULL, "other element triggering change"
},
// ---------- custom change action (element used for action) ----------------
0, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_CUSTOM_CHANGE_ACTION, GADGET_ID_ACTION_ARG,
&custom_element_change.action_element, 1, 1,
- NULL, NULL, NULL, "element used as action parameter"
+ NULL, NULL, NULL, NULL, "element used as action parameter"
},
// ---------- group element content -----------------------------------------
ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_GROUP_CONTENT, GADGET_ID_NONE,
&group_element_info.element[0], MAX_ELEMENTS_IN_GROUP, 1,
- "content:", NULL, NULL, NULL
+ "content:", NULL, NULL, NULL, NULL
},
// ---------- random background (for random painting) -----------------------
0, ED_AREA_1X1_LSETTINGS_YOFF,
GADGET_ID_RANDOM_BACKGROUND, GADGET_ID_RANDOM_RESTRICTED,
&random_placement_background_element, 1, 1,
- NULL, NULL, NULL, "random placement background"
+ NULL, NULL, NULL, NULL, "random placement background"
},
};
static int ed_tilesize = DEFAULT_EDITOR_TILESIZE;
static int ed_tilesize_default = DEFAULT_EDITOR_TILESIZE;
-#define IN_ED_FIELD(x,y) IN_FIELD(x, y, ed_fieldx, ed_fieldy)
+#define IN_ED_FIELD(x, y) IN_FIELD(x, y, ed_fieldx, ed_fieldy)
// drawing elements on the three mouse buttons
static int new_element1 = EL_WALL;
static void RedrawDrawingElements(void);
static void DrawDrawingWindowExt(boolean);
static void DrawDrawingWindow(void);
-static void DrawLevelInfoWindow(void);
+static void DrawLevelConfigWindow(void);
static void DrawPropertiesWindow(void);
static void DrawPaletteWindow(void);
static void UpdateCustomElementGraphicGadgets(void);
static int getTabulatorBarWidth(void);
static int getTabulatorBarHeight(void);
static Pixel getTabulatorBarColor(void);
+static int numHiresTiles(int);
static int num_editor_gadgets = 0; // dynamically determined
static boolean draw_with_brush = FALSE;
static int properties_element = 0;
-static short FieldBackup[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+static short TileBackup[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
static short UndoBuffer[NUM_UNDO_STEPS][MAX_LEV_FIELDX][MAX_LEV_FIELDY];
static short IntelliDrawBuffer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
static int undo_buffer_position = 0;
static int redo_buffer_steps = 0;
static int edit_mode;
-static int edit_mode_levelinfo;
+static int edit_mode_levelconfig;
static int edit_mode_properties;
static int element_shift = 0;
EL_EMC_MAGIC_BALL,
EL_EMC_MAGIC_BALL_SWITCH,
- EL_SPRING,
- EL_EMC_SPRING_BUMPER,
-
EL_EMC_LENSES,
EL_EMC_MAGNIFIER,
- EL_EMPTY,
- EL_EMPTY,
+
+ EL_SPRING_LEFT,
+ EL_SPRING,
+ EL_SPRING_RIGHT,
+ EL_EMC_SPRING_BUMPER,
EL_BALLOON,
EL_YAMYAM_UP,
EL_MM_WOODEN_GRID_FIXED_1,
EL_MM_WOODEN_GRID_FIXED_2,
EL_MM_WOODEN_GRID_FIXED_3,
- EL_MM_WOODEN_GRID_FIXED_4
+ EL_MM_WOODEN_GRID_FIXED_4,
+
+ EL_MM_ENVELOPE_1,
+ EL_MM_ENVELOPE_2,
+ EL_MM_ENVELOPE_3,
+ EL_MM_ENVELOPE_4
};
static int *editor_hl_mirror_magic_ptr = editor_hl_mirror_magic;
static int *editor_el_mirror_magic_ptr = editor_el_mirror_magic;
EL_DF_MIRROR_START,
EL_DF_MIRROR_ROTATING_START,
+ EL_DF_MIRROR_FIXED_START,
EL_DF_CELL,
- EL_DF_MINE,
EL_DF_FIBRE_OPTIC_RED_1,
EL_DF_FIBRE_OPTIC_YELLOW_1,
EL_DF_STEEL_WALL,
EL_DF_WOODEN_WALL,
EL_DF_REFRACTOR,
- EL_EMPTY
+ EL_DF_MINE,
+
+ EL_DF_SLOPE_1,
+ EL_DF_SLOPE_2,
+ EL_DF_SLOPE_3,
+ EL_DF_SLOPE_4
};
static int *editor_hl_deflektor_ptr = editor_hl_deflektor;
static int *editor_el_deflektor_ptr = editor_el_deflektor;
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 struct XY xy_directions[] =
+{
+ { -1, 0 },
+ { +1, 0 },
+ { 0, -1 },
+ { 0, +1 }
+};
+
// ----------------------------------------------------------------------------
// functions
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;
}
// find all elements used in current level
for (y = 0; y < lev_fieldy; y++)
+ {
for (x = 0; x < lev_fieldx; x++)
- if (Feld[x][y] < NUM_FILE_ELEMENTS) // should always be true
- element_found[Feld[x][y]] = TRUE;
+ {
+ if (Tile[x][y] >= NUM_FILE_ELEMENTS) // should never happen
+ continue;
+
+ if (IS_MM_WALL(Tile[x][y]))
+ element_found[map_mm_wall_element(Tile[x][y])] = TRUE;
+ else
+ element_found[Tile[x][y]] = TRUE;
+ }
+ }
*num_elements = 0;
*num_elements = 0;
- // add all elements used in current level (non-custom/group elements)
+ // add all elements used in current level (non-custom/group/empty elements)
for (i = 0; i < NUM_FILE_ELEMENTS; i++)
- if (element_found[i] && !(IS_CUSTOM_ELEMENT(i) || IS_GROUP_ELEMENT(i)))
+ if (element_found[i] && !(IS_CUSTOM_ELEMENT(i) ||
+ IS_GROUP_ELEMENT(i) ||
+ IS_EMPTY_ELEMENT(i)))
(*elements)[(*num_elements)++] = i;
- // add all elements used in current level (custom/group elements)
+ // add all elements used in current level (custom/group/empty elements)
for (i = 0; i < NUM_FILE_ELEMENTS; i++)
- if (element_found[i] && (IS_CUSTOM_ELEMENT(i) || IS_GROUP_ELEMENT(i)))
+ if (element_found[i] && (IS_CUSTOM_ELEMENT(i) ||
+ IS_GROUP_ELEMENT(i) ||
+ IS_EMPTY_ELEMENT(i)))
(*elements)[(*num_elements)++] = i;
while (*num_elements % 4) // pad with empty elements, if needed
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);
}
}
// determine size of element list
for (i = 0; editor_elements_info[i].setup_value != NULL; i++)
{
- boolean found_inactive_cascade = FALSE;
-
if (*editor_elements_info[i].setup_value)
{
+ boolean found_inactive_cascade = FALSE;
+
if (setup.editor.el_headlines)
{
// required for correct padding of palette headline buttons
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;
}
int graphic;
struct GraphicInfo *gd;
int gd_x1, gd_x2, gd_y1, gd_y2;
- unsigned int event_mask;
+ unsigned int event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED;
char infotext[max_infotext_len + 1];
- event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED;
-
if (i == ED_COUNTER_ID_SELECT_LEVEL)
{
graphic = (j == 0 ?
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] =
for (i = 0; i < ED_NUM_DRAWING_AREAS; i++)
{
struct GadgetInfo *gi;
- unsigned int event_mask;
int id = drawingarea_info[i].gadget_id;
int x = SX + ED_AREA_SETTINGS_X(drawingarea_info[i]);
int y = SY + ED_AREA_SETTINGS_Y(drawingarea_info[i]);
int area_ysize = drawingarea_info[i].area_ysize;
int item_size = (id == GADGET_ID_DRAWING_LEVEL ?
ed_tilesize : ED_DRAWINGAREA_TILE_SIZE);
-
- event_mask =
+ unsigned int event_mask =
GD_EVENT_PRESSED | GD_EVENT_RELEASED | GD_EVENT_MOVING |
GD_EVENT_OFF_BORDERS | GD_EVENT_PIXEL_PRECISE;
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
right_gadget_border[id] =
int gd_x2 = gd->src_x + gd->active_xoffset;
int gd_y2 = gd->src_y + gd->active_yoffset;
struct GadgetInfo *gi;
- unsigned int event_mask;
+ unsigned int event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING;
char infotext[MAX_OUTPUT_LINESIZE + 1];
int id = textinput_info[i].gadget_id;
int x, y;
y = ED_SETTINGS_Y(textinput_info[i].y);
}
- event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING;
-
sprintf(infotext, "Enter %s", textinput_info[i].infotext);
infotext[max_infotext_len] = '\0';
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
}
int gd_x2 = gd->src_x + gd->active_xoffset;
int gd_y2 = gd->src_y + gd->active_yoffset;
struct GadgetInfo *gi;
- unsigned int event_mask;
+ unsigned int event_mask = GD_EVENT_TEXT_LEAVING;
char infotext[MAX_OUTPUT_LINESIZE + 1];
int id = textarea_info[i].gadget_id;
int area_xsize = textarea_info[i].xsize;
int area_ysize = textarea_info[i].ysize;
- event_mask = GD_EVENT_TEXT_LEAVING;
-
sprintf(infotext, "Enter %s", textarea_info[i].infotext);
infotext[max_infotext_len] = '\0';
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
}
int gd_y2 = gd->src_y + gd->active_yoffset;
int selectbox_button_xsize = gd2->width;
struct GadgetInfo *gi;
- unsigned int event_mask;
char infotext[MAX_OUTPUT_LINESIZE + 1];
int id = selectbox_info[i].gadget_id;
int x = SX + ED_SETTINGS_X(selectbox_info[i].x);
int y = SY + ED_SETTINGS_Y(selectbox_info[i].y);
+ unsigned int event_mask =
+ GD_EVENT_RELEASED | GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING;
if (selectbox_info[i].size == -1) // dynamically determine size
{
selectbox_info[i].size++; // add one character empty space
}
- event_mask = GD_EVENT_RELEASED |
- GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING;
-
// determine horizontal position to the right of specified gadget
if (selectbox_info[i].gadget_id_align != GADGET_ID_NONE)
x = (right_gadget_border[selectbox_info[i].gadget_id_align] +
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
right_gadget_border[id] =
{
int id = textbutton_info[i].gadget_id;
int is_tab_button =
- ((id >= GADGET_ID_LEVELINFO_LEVEL && id <= GADGET_ID_LEVELINFO_EDITOR) ||
+ ((id >= GADGET_ID_LEVELCONFIG_LEVEL && id <= GADGET_ID_LEVELCONFIG_EDITOR) ||
(id >= GADGET_ID_PROPERTIES_INFO && id <= GADGET_ID_PROPERTIES_CHANGE));
int graphic =
(is_tab_button ? IMG_EDITOR_TABBUTTON : IMG_EDITOR_TEXTBUTTON);
int border_xsize = gd->border_size + gd->draw_xoffset;
int border_ysize = gd->border_size;
struct GadgetInfo *gi;
- unsigned int event_mask;
+ unsigned int event_mask = GD_EVENT_RELEASED;
char infotext[MAX_OUTPUT_LINESIZE + 1];
int x = SX + ED_SETTINGS_X(textbutton_info[i].x);
int y = SY + ED_SETTINGS_Y(textbutton_info[i].y);
if (textbutton_info[i].size == -1) // dynamically determine size
textbutton_info[i].size = strlen(textbutton_info[i].text);
- event_mask = GD_EVENT_RELEASED;
-
sprintf(infotext, "%s", textbutton_info[i].infotext);
infotext[max_infotext_len] = '\0';
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
right_gadget_border[id] =
static void CreateGraphicbuttonGadgets(void)
{
struct GadgetInfo *gi;
- unsigned int event_mask;
int i;
// create buttons for scrolling of drawing area and element list
int gd_y1 = gd->src_y;
int gd_x2 = gd->src_x + gd->pressed_xoffset;
int gd_y2 = gd->src_y + gd->pressed_yoffset;
-
- event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED;
+ unsigned int event_mask = GD_EVENT_RELEASED;
// determine horizontal position to the right of specified gadget
if (graphicbutton_info[i].gadget_id_align != GADGET_ID_NONE)
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
right_gadget_border[id] =
int gd_y2 = gd->src_y + gd->pressed_yoffset;
struct GadgetInfo *gi;
int items_max, items_visible, item_position;
- unsigned int event_mask;
+ unsigned int event_mask = GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS;
if (i == ED_SCROLLBAR_ID_LIST_VERTICAL)
{
}
}
- event_mask = GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS;
-
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
GDI_IMAGE_ID, graphic,
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
}
static void CreateCheckbuttonGadgets(void)
{
struct GadgetInfo *gi;
- unsigned int event_mask;
int i;
- event_mask = GD_EVENT_PRESSED;
-
for (i = 0; i < ED_NUM_CHECKBUTTONS; i++)
{
int id = checkbutton_info[i].gadget_id;
int gd_y2a = gd->src_y + gd->active_yoffset + gd->pressed_yoffset;
int x = SX + ED_SETTINGS_X(checkbutton_info[i].x);
int y = SY + ED_SETTINGS_Y(checkbutton_info[i].y);
+ unsigned int event_mask = GD_EVENT_PRESSED;
// determine horizontal position to the right of specified gadget
if (checkbutton_info[i].gadget_id_align != GADGET_ID_NONE)
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
level_editor_gadget[id] = gi;
right_gadget_border[id] =
int gd_x2a = gd->src_x + gd->active_xoffset + gd->pressed_xoffset;
int gd_y2a = gd->src_y + gd->active_yoffset + gd->pressed_yoffset;
struct GadgetInfo *gi;
- unsigned int event_mask;
int i;
- event_mask = GD_EVENT_PRESSED;
-
for (i = 0; i < ED_NUM_RADIOBUTTONS; i++)
{
int id = radiobutton_info[i].gadget_id;
int x = SX + ED_SETTINGS_X(radiobutton_info[i].x);
int y = SY + ED_SETTINGS_Y(radiobutton_info[i].y);
+ unsigned int event_mask = GD_EVENT_PRESSED;
int checked =
(*radiobutton_info[i].value == radiobutton_info[i].checked_value);
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 *));
use_permanent_palette = !editor.palette.show_as_separate_screen;
+ InitGadgetScreenBorders(-1, INFOTEXT_YPOS);
+
ReinitializeElementList();
CreateControlButtons();
{
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++)
{
int xoffset_below = getTextWidth(drawingarea_info[id].text_below, font_nr);
int x_left = gi->x - xoffset_left;
int x_right = gi->x + gi->width + ED_DRAWINGAREA_TEXT_DISTANCE;
+ int x_above = gi->x - ED_DRAWINGAREA_BORDER_SIZE;
int x_below = gi->x + (gi->width - xoffset_below) / 2;
int y_side = gi->y + (gi->height - font_height) / 2;
+ int y_above = gi->y - font_height - ED_DRAWINGAREA_TEXT_DISTANCE;
int y_below = gi->y + gi->height + ED_DRAWINGAREA_TEXT_DISTANCE;
if (drawingarea_info[id].text_left)
if (drawingarea_info[id].text_right)
DrawText(x_right, y_side, drawingarea_info[id].text_right, font_nr);
+ if (drawingarea_info[id].text_above)
+ DrawText(x_above, y_above, drawingarea_info[id].text_above, font_nr);
+
if (drawingarea_info[id].text_below)
DrawText(x_below, y_below, drawingarea_info[id].text_below, font_nr);
int yoffset_above = font_height + ED_GADGET_LINE_DISTANCE;
int x_above = ED_SETTINGS_X(textarea_info[id].x);
int y_above = ED_SETTINGS_Y(textarea_info[id].y) - yoffset_above;
+ char *text_above = textarea_info[id].text_above;
- if (textarea_info[id].text_above)
- DrawTextS(x_above, y_above, font_nr, textarea_info[id].text_above);
+ if (gi->textarea.cropped && textarea_info[id].text_above_cropped)
+ text_above = textarea_info[id].text_above_cropped;
+
+ if (text_above)
+ DrawTextS(x_above, y_above, font_nr, text_above);
ModifyGadget(gi, GDI_TEXT_VALUE, textarea_info[id].value, GDI_END);
// set position for gadgets with dynamically determined position
if (checkbutton_info[id].x != -1) // do not change dynamic positions
- ModifyGadget(gi, GDI_X, SX + ED_SETTINGS_X(checkbutton_info[id].x),GDI_END);
+ ModifyGadget(gi, GDI_X, SX + ED_SETTINGS_X(checkbutton_info[id].x), GDI_END);
ModifyGadget(gi, GDI_Y, SY + ED_SETTINGS_Y(checkbutton_info[id].y), GDI_END);
x_left = gi->x - xoffset_left;
MapOrUnmapLevelEditorToolboxCustomGadgets(TRUE);
}
+static void MapLevelEditorToolboxCustomGadgetsIfNeeded(void)
+{
+ if (IS_CUSTOM_ELEMENT(properties_element) ||
+ IS_GROUP_ELEMENT(properties_element) ||
+ IS_EMPTY_ELEMENT(properties_element))
+ MapLevelEditorToolboxCustomGadgets();
+}
+
static void UnmapLevelEditorToolboxCustomGadgets(void)
{
MapOrUnmapLevelEditorToolboxCustomGadgets(FALSE);
RedrawDrawingElements();
}
- if (edit_mode == ED_MODE_INFO)
- DrawLevelInfoWindow();
+ if (edit_mode == ED_MODE_LEVELCONFIG)
+ DrawLevelConfigWindow();
else if (edit_mode == ED_MODE_PROPERTIES)
DrawPropertiesWindow();
else if (edit_mode == ED_MODE_PALETTE)
for (y = 0; y < lev_fieldy; y++)
for (x = 0; x < lev_fieldx; x++)
- if (Feld[x][y] != level.field[x][y])
+ if (Tile[x][y] != level.field[x][y])
field_changed = TRUE;
return (level.changed || field_changed);
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;
leveldir_current =
getTreeInfoFromIdentifier(leveldir_first, getLoginName());
+ // this may happen if "setup.internal.create_user_levelset" is FALSE
+ // or if file "levelinfo.conf" is missing in personal user level set
+ if (leveldir_current == NULL)
+ {
+ Request("Cannot find personal level set?!", REQ_CONFIRM);
+
+ leveldir_current = leveldir_former;
+
+ return FALSE;
+ }
+
// find unused level number
for (new_level_nr = leveldir_current->first_level; ; new_level_nr++)
{
return TRUE;
}
-static void ModifyLevelInfoForSavingIntoPersonalLevelSet(char *former_name)
+static void ModifyLevelConfigForSavingIntoPersonalLevelSet(char *former_name)
{
static char *filename_levelinfo = NULL, *mod_name = NULL;
FILE *file;
for (x = 0; x < lev_fieldx; x++)
for (y = 0; y < lev_fieldy; y++)
- if (Feld[x][y] == element_from)
- Feld[x][y] = element_to;
+ if (Tile[x][y] == element_from)
+ Tile[x][y] = element_to;
}
static boolean CopyCustomElement(int element_old, int element_new,
return FALSE;
}
+ else if (IS_EMPTY_ELEMENT(element_old) && !IS_EMPTY_ELEMENT(element_new))
+ {
+ Request("Please choose empty element!", REQ_CONFIRM);
+
+ return FALSE;
+ }
else
{
level.changed = TRUE;
// 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 :
HAS_CHANGE_EVENT(element, CE_SCORE_CHANGES) ? CE_SCORE_CHANGES :
HAS_CHANGE_EVENT(element, CE_VALUE_GETS_ZERO) ? CE_VALUE_GETS_ZERO :
HAS_CHANGE_EVENT(element, CE_SCORE_GETS_ZERO) ? CE_SCORE_GETS_ZERO :
+ HAS_CHANGE_EVENT(element, CE_CLICKED_BY_MOUSE) ? CE_CLICKED_BY_MOUSE :
+ HAS_CHANGE_EVENT(element, CE_PRESSED_BY_MOUSE) ? CE_PRESSED_BY_MOUSE :
custom_element_change.direct_action);
// 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 :
HAS_CHANGE_EVENT(element, CE_SCORE_CHANGES_OF_X) ? CE_SCORE_CHANGES_OF_X :
HAS_CHANGE_EVENT(element, CE_VALUE_GETS_ZERO_OF_X) ? CE_VALUE_GETS_ZERO_OF_X :
HAS_CHANGE_EVENT(element, CE_SCORE_GETS_ZERO_OF_X) ? CE_SCORE_GETS_ZERO_OF_X :
+ HAS_CHANGE_EVENT(element, CE_MOUSE_CLICKED_ON_X) ? CE_MOUSE_CLICKED_ON_X :
+ HAS_CHANGE_EVENT(element, CE_MOUSE_PRESSED_ON_X) ? CE_MOUSE_PRESSED_ON_X :
custom_element_change.other_action);
}
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_SCORE_CHANGES] = FALSE;
custom_element_change_events[CE_VALUE_GETS_ZERO] = FALSE;
custom_element_change_events[CE_SCORE_GETS_ZERO] = FALSE;
+ custom_element_change_events[CE_CLICKED_BY_MOUSE] = FALSE;
+ custom_element_change_events[CE_PRESSED_BY_MOUSE] = FALSE;
custom_element_change_events[custom_element_change.direct_action] =
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;
custom_element_change_events[CE_SCORE_CHANGES_OF_X] = FALSE;
custom_element_change_events[CE_VALUE_GETS_ZERO_OF_X] = FALSE;
custom_element_change_events[CE_SCORE_GETS_ZERO_OF_X] = FALSE;
+ custom_element_change_events[CE_MOUSE_CLICKED_ON_X] = FALSE;
+ custom_element_change_events[CE_MOUSE_PRESSED_ON_X] = FALSE;
custom_element_change_events[custom_element_change.other_action] =
custom_element_change_events[CE_BY_OTHER_ACTION];
// copy change events also to special level editor variable
custom_element = element_info[element];
custom_element_change = *element_info[element].change;
+
+ // needed here to restore runtime value "element_info[element].gfx_element"
+ InitElementPropertiesGfxElement();
}
static void CopyGroupElementPropertiesToGame(int element)
element_info[element] = custom_element;
*element_info[element].group = group_element_info;
+
+ // needed here to restore runtime value "element_info[element].gfx_element"
+ 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
ed_tilesize = setup.auto_setup.editor_zoom_tilesize;
ed_tilesize_default = DEFAULT_EDITOR_TILESIZE;
+ // make sure that tile size is always a power of 2
+ ed_tilesize = (1 << log_2(ed_tilesize));
+
if (level.game_engine_type == GAME_ENGINE_TYPE_MM)
{
ed_tilesize = DEFAULT_EDITOR_TILESIZE_MM;
// draw all toolbox gadgets to editor doors
MapControlButtons();
+ // when returning from test game to properties page, redraw toolbox gadgets
+ if (edit_mode == ED_MODE_PROPERTIES)
+ {
+ UnmapLevelEditorToolboxDrawingGadgets();
+ UnmapLevelEditorToolboxCustomGadgets();
+
+ MapLevelEditorToolboxCustomGadgetsIfNeeded();
+ }
+
// draw all palette gadgets to editor doors
ModifyEditorElementList();
RedrawDrawingElements();
FadeSoundsAndMusic();
- if (CheckIfGlobalBorderOrPlayfieldViewportHasChanged())
+ if (CheckFadeAll())
fade_mask = REDRAW_ALL;
FadeOut(fade_mask);
if (level_editor_test_game)
{
- CopyPlayfield(level.field, Feld);
- CopyPlayfield(FieldBackup, level.field);
+ CopyPlayfield(level.field, Tile);
+ CopyPlayfield(TileBackup, level.field);
level_editor_test_game = FALSE;
}
else
{
edit_mode = ED_MODE_DRAWING;
- edit_mode_levelinfo = ED_MODE_LEVELINFO_LEVEL;
+ edit_mode_levelconfig = ED_MODE_LEVELCONFIG_LEVEL;
edit_mode_properties = ED_MODE_PROPERTIES_INFO;
ResetUndoBuffer();
if (suppressBorderElement())
{
- ed_xsize = max_ed_fieldx;
- ed_ysize = max_ed_fieldy;
+ ed_xsize = lev_fieldx;
+ ed_ysize = lev_fieldy;
}
// check if we need any scrollbars
static Pixel getTabulatorBarColor(void)
{
- struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_LEVELINFO_LEVEL];
+ struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_LEVELCONFIG_LEVEL];
struct GadgetDesign *gd = &gd_gi1->alt_design[GD_BUTTON_UNPRESSED];
int gd_x = gd->x + gd_gi1->border.width / 2;
int gd_y = gd->y + gd_gi1->height - 1;
return GetPixel(gd->bitmap, gd_x, gd_y);
}
-static void DrawLevelInfoTabulatorGadgets(void)
+static void DrawLevelConfigTabulatorGadgets(void)
{
- struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_LEVELINFO_LEVEL];
+ struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_LEVELCONFIG_LEVEL];
Pixel tab_color = getTabulatorBarColor();
- int id_first = ED_TAB_BUTTON_ID_LEVELINFO_FIRST;
- int id_last = ED_TAB_BUTTON_ID_LEVELINFO_LAST;
+ int id_first = ED_TAB_BUTTON_ID_LEVELCONFIG_FIRST;
+ int id_last = ED_TAB_BUTTON_ID_LEVELCONFIG_LAST;
int i;
for (i = id_first; i <= id_last; i++)
{
int gadget_id = textbutton_info[i].gadget_id;
struct GadgetInfo *gi = level_editor_gadget[gadget_id];
- boolean active = (i != edit_mode_levelinfo);
+ boolean active = (i != edit_mode_levelconfig);
// draw background line below tabulator button
ClearRectangleOnBackground(drawto, gi->x, gi->y + gi->height, gi->width, 1);
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;
TRUE, FALSE, FALSE);
}
-static void DrawLevelInfoLevel(void)
+static void DrawLevelConfigLevel(void)
{
int i;
return leveldir_current->subdir;
}
-static void DrawLevelInfoLevelSet_DirectoryInfo(void)
+static void DrawLevelConfigLevelSet_DirectoryInfo(void)
{
char *directory_text = "Level set directory:";
char *directory_name = getLevelSubdirFromSaveMode(levelset_save_mode);
PrintInfoText(directory_name, font2_nr, x, y);
}
-static void DrawLevelInfoLevelSet(void)
+static void DrawLevelConfigLevelSet(void)
{
boolean artwork_exists = checkIfCustomArtworkExistsForCurrentLevelSet();
boolean template_exists = fileExists(getLocalLevelTemplateFilename());
MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_LEVELSET);
// draw info text
- DrawLevelInfoLevelSet_DirectoryInfo();
+ DrawLevelConfigLevelSet_DirectoryInfo();
}
-static void DrawLevelInfoEditor(void)
+static void DrawLevelConfigEditor(void)
{
int i;
MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_2);
}
-static void DrawLevelInfoWindow(void)
+static void DrawLevelConfigWindow(void)
{
char *text = "Global Settings";
int font_nr = FONT_TITLE_1;
DrawText(sx, sy, text, font_nr);
- DrawLevelInfoTabulatorGadgets();
+ DrawLevelConfigTabulatorGadgets();
- if (edit_mode_levelinfo == ED_MODE_LEVELINFO_LEVEL)
- DrawLevelInfoLevel();
- else if (edit_mode_levelinfo == ED_MODE_LEVELINFO_LEVELSET)
- DrawLevelInfoLevelSet();
- else if (edit_mode_levelinfo == ED_MODE_LEVELINFO_EDITOR)
- DrawLevelInfoEditor();
+ if (edit_mode_levelconfig == ED_MODE_LEVELCONFIG_LEVEL)
+ DrawLevelConfigLevel();
+ else if (edit_mode_levelconfig == ED_MODE_LEVELCONFIG_LEVELSET)
+ DrawLevelConfigLevelSet();
+ else if (edit_mode_levelconfig == ED_MODE_LEVELCONFIG_EDITOR)
+ DrawLevelConfigEditor();
}
static void DrawCustomContentArea(void)
DrawText(x, y + 2 * tilesize, "active", font_nr);
}
-static void DrawAndroidElementArea(int element)
+static void DrawAndroidElementArea(void)
{
int id = ED_DRAWING_ID_ANDROID_CONTENT;
int num_elements = level.num_android_clone_elements;
MapDrawingArea(id);
}
-static void DrawGroupElementArea(int element)
+static void DrawGroupElementArea(void)
{
int id = ED_DRAWING_ID_GROUP_CONTENT;
int num_elements = group_element_info.num_elements;
MapDrawingArea(id);
}
+static void DrawMMBallContentArea(void)
+{
+ int id = ED_DRAWING_ID_MM_BALL_CONTENT;
+ int num_elements = level.num_mm_ball_contents;
+ int border_size = ED_DRAWINGAREA_BORDER_SIZE;
+ int sx = SX + ED_AREA_SETTINGS_X(drawingarea_info[id]) - border_size;
+ int sy = SY + ED_AREA_SETTINGS_Y(drawingarea_info[id]) - border_size;
+ int xsize = MAX_MM_BALL_CONTENTS;
+ int ysize = 1;
+
+ if (drawingarea_info[id].text_left != NULL)
+ sx += getTextWidthForDrawingArea(drawingarea_info[id].text_left);
+
+ UnmapDrawingArea(id);
+
+ ModifyEditorDrawingArea(id, num_elements, 1);
+
+ // delete content areas in case of reducing number of them
+ DrawBackground(sx, sy,
+ xsize * ED_DRAWINGAREA_TILE_SIZE + 2 * border_size,
+ ysize * ED_DRAWINGAREA_TILE_SIZE + 2 * border_size);
+
+ MapDrawingArea(id);
+}
+
static void DrawEnvelopeTextArea(int envelope_nr)
{
int id = ED_TEXTAREA_ID_ENVELOPE_INFO;
struct GadgetInfo *gi = level_editor_gadget[textarea_info[id].gadget_id];
UnmapGadget(gi);
- DrawBackground(gi->x, gi->y, gi->width, gi->height);
+
+ DrawBackground(gi->x, gi->y,
+ gi->textarea.crop_width, gi->textarea.crop_height);
if (envelope_nr != -1)
textarea_info[id].value = level.envelope[envelope_nr].text;
{ -1, NULL }
};
char *filename = getElementDescriptionFilename(properties_element);
- char *percentage_text = "In this level: ";
+ char *num_elements_text = "In this level: ";
+ char *num_similar_text = "Similar tiles: ";
char *properties_text = "Standard properties: ";
char *description_text = "Description:";
char *no_description_text = "No description available.";
char *none_text = "None";
float percentage;
- int num_elements_in_level;
+ int num_elements_in_level = 0;
+ int num_similar_in_level = 0;
+ int num_hires_tiles_in_level = 0;
int num_standard_properties = 0;
int font1_nr = FONT_TEXT_1;
int font2_nr = FONT_TEXT_2;
int font2_height = getFontHeight(font2_nr);
int line1_height = font1_height + ED_GADGET_LINE_DISTANCE;
int font2_yoffset = (font1_height - font2_height) / 2;
- int percentage_text_len = strlen(percentage_text) * font1_width;
+ int num_elements_text_len = strlen(num_elements_text) * font1_width;
+ int num_similar_text_len = strlen(num_similar_text) * font1_width;
int properties_text_len = strlen(properties_text) * font1_width;
int xpos = ED_ELEMENT_SETTINGS_X(0);
int ypos = ED_ELEMENT_SETTINGS_Y(0) + ED_GADGET_SMALL_DISTANCE;
// ----- print number of elements / percentage of this element in level
- num_elements_in_level = 0;
- for (y = 0; y < lev_fieldy; y++)
+ for (y = 0; y < lev_fieldy; y++)
+ {
for (x = 0; x < lev_fieldx; x++)
- if (Feld[x][y] == properties_element)
+ {
+ if (Tile[x][y] == properties_element)
+ {
num_elements_in_level++;
+ }
+ else if (IS_MM_WALL(Tile[x][y]) &&
+ map_mm_wall_element(Tile[x][y]) == properties_element)
+ {
+ num_hires_tiles_in_level += numHiresTiles(Tile[x][y]);
+ }
+ }
+ }
+
percentage = num_elements_in_level * 100.0 / (lev_fieldx * lev_fieldy);
- DrawTextS(xpos, ypos, font1_nr, percentage_text);
+ DrawTextS(xpos, ypos, font1_nr, num_elements_text);
- if (num_elements_in_level > 0)
- DrawTextF(xpos + percentage_text_len, ypos + font2_yoffset, font2_nr,
+ if (num_hires_tiles_in_level > 0)
+ DrawTextF(xpos + num_elements_text_len, ypos + font2_yoffset, font2_nr,
+ "%d wall tiles", num_hires_tiles_in_level);
+ else if (num_elements_in_level > 0)
+ DrawTextF(xpos + num_elements_text_len, ypos + font2_yoffset, font2_nr,
"%d (%.2f %%)", num_elements_in_level, percentage);
else
- DrawTextF(xpos + percentage_text_len, ypos + font2_yoffset, font2_nr,
+ DrawTextF(xpos + num_elements_text_len, ypos + font2_yoffset, font2_nr,
none_text);
+ // ----- print number of similar elements / percentage of them in level
+
+ for (y = 0; y < lev_fieldy; y++)
+ {
+ for (x = 0; x < lev_fieldx; x++)
+ {
+ if (strEqual(element_info[Tile[x][y]].class_name,
+ element_info[properties_element].class_name))
+ {
+ num_similar_in_level++;
+ }
+ }
+ }
+
+ if (num_similar_in_level != num_elements_in_level)
+ {
+ ypos += 1 * MAX(font1_height, font2_height);
+
+ percentage = num_similar_in_level * 100.0 / (lev_fieldx * lev_fieldy);
+
+ DrawTextS(xpos, ypos, font1_nr, num_similar_text);
+
+ if (num_similar_in_level > 0)
+ DrawTextF(xpos + num_similar_text_len, ypos + font2_yoffset, font2_nr,
+ "%d (%.2f %%)", num_similar_in_level, percentage);
+ else
+ DrawTextF(xpos + num_similar_text_len, ypos + font2_yoffset, font2_nr,
+ none_text);
+ }
+
ypos += 2 * MAX(font1_height, font2_height);
// ----- print standard properties of this element
#define TEXT_DURATION "Duration when activated"
#define TEXT_DELAY_ON "Delay before activating"
#define TEXT_DELAY_OFF "Delay before deactivating"
+#define TEXT_DELAY_CHANGING "Delay before changing"
#define TEXT_DELAY_EXPLODING "Delay before exploding"
#define TEXT_DELAY_MOVING "Delay before moving"
#define TEXT_BALL_DELAY "Element generation delay"
{ EL_NUT, &level.score[SC_NUT], TEXT_CRACKING },
{ EL_DYNAMITE, &level.score[SC_DYNAMITE], TEXT_COLLECTING },
{ EL_EM_DYNAMITE, &level.score[SC_DYNAMITE], TEXT_COLLECTING },
- { EL_DYNABOMB_INCREASE_NUMBER,&level.score[SC_DYNAMITE],TEXT_COLLECTING },
- { EL_DYNABOMB_INCREASE_SIZE, &level.score[SC_DYNAMITE],TEXT_COLLECTING },
- { EL_DYNABOMB_INCREASE_POWER, &level.score[SC_DYNAMITE],TEXT_COLLECTING },
+ { EL_DYNABOMB_INCREASE_NUMBER,&level.score[SC_DYNAMITE], TEXT_COLLECTING },
+ { EL_DYNABOMB_INCREASE_SIZE, &level.score[SC_DYNAMITE], TEXT_COLLECTING },
+ { EL_DYNABOMB_INCREASE_POWER, &level.score[SC_DYNAMITE], TEXT_COLLECTING },
{ EL_SHIELD_NORMAL, &level.score[SC_SHIELD], TEXT_COLLECTING },
{ EL_SHIELD_DEADLY, &level.score[SC_SHIELD], TEXT_COLLECTING },
{ EL_EXTRA_TIME, &level.extra_time_score, TEXT_COLLECTING },
{ EL_EMC_LENSES, &level.lenses_score, TEXT_COLLECTING },
{ EL_EMC_MAGNIFIER, &level.magnify_score, TEXT_COLLECTING },
{ EL_SPRING, &level.slurp_score, TEXT_SLURPING },
+ { EL_SPRING_LEFT, &level.slurp_score, TEXT_SLURPING },
+ { EL_SPRING_RIGHT, &level.slurp_score, TEXT_SLURPING },
{ EL_EMC_LENSES, &level.lenses_time, TEXT_DURATION },
{ EL_EMC_MAGNIFIER, &level.magnify_time, TEXT_DURATION },
{ EL_MM_FUSE_ACTIVE, &level.mm_time_fuse, TEXT_DELAY_OFF },
{ EL_MM_BOMB, &level.mm_time_bomb, TEXT_DELAY_EXPLODING },
- { EL_MM_GRAY_BALL, &level.mm_time_ball, TEXT_DELAY_ON },
+ { EL_MM_GRAY_BALL, &level.mm_time_ball, TEXT_DELAY_CHANGING },
{ EL_MM_STEEL_BLOCK, &level.mm_time_block, TEXT_DELAY_MOVING },
{ EL_MM_WOODEN_BLOCK, &level.mm_time_block, TEXT_DELAY_MOVING },
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_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) ||
{
for (y = 0; y < lev_fieldy; y++)
{
- int element = Feld[x][y];
+ int element = Tile[x][y];
+
+ switch (element)
+ {
+ case EL_EMERALD:
+ case EL_EMERALD_YELLOW:
+ case EL_EMERALD_RED:
+ case EL_EMERALD_PURPLE:
+ case EL_BD_DIAMOND:
+ case EL_WALL_EMERALD:
+ case EL_WALL_EMERALD_YELLOW:
+ case EL_WALL_EMERALD_RED:
+ case EL_WALL_EMERALD_PURPLE:
+ case EL_WALL_BD_DIAMOND:
+ case EL_NUT:
+ case EL_SP_INFOTRON:
+ case EL_MM_KETTLE:
+ case EL_DF_CELL:
+ level.gems_needed++;
+ break;
+
+ case EL_DIAMOND:
+ case EL_WALL_DIAMOND:
+ level.gems_needed += 3;
+ break;
+
+ case EL_PEARL:
+ case EL_WALL_PEARL:
+ level.gems_needed += 5;
+ break;
+
+ case EL_CRYSTAL:
+ case EL_WALL_CRYSTAL:
+ level.gems_needed += 8;
+ break;
- if (IS_GEM(element) ||
- element == EL_MM_KETTLE ||
- element == EL_DF_CELL)
- level.gems_needed++;
+ default:
+ break;
+ }
}
}
DrawMagicBallContentAreas();
MapCheckbuttonGadget(ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT);
- MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INITIAL_BALL_STATE);
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INITIAL_BALL_ACTIVE);
}
else if (properties_element == EL_EMC_ANDROID)
- DrawAndroidElementArea(properties_element);
+ DrawAndroidElementArea();
+ else if (properties_element == EL_MM_GRAY_BALL)
+ {
+ MapCounterButtons(ED_COUNTER_ID_MM_BALL_CONTENT);
+ MapSelectboxGadget(ED_SELECTBOX_ID_MM_BALL_CHOICE_MODE);
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_ROTATE_MM_BALL_CONTENT);
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_EXPLODE_MM_BALL);
+
+ DrawMMBallContentArea();
+ }
}
- 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);
if (MAYBE_DONT_COLLIDE_WITH(properties_element))
MapCheckbuttonGadget(ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH);
- if (properties_element == EL_SPRING)
+ if (properties_element == EL_SPRING ||
+ properties_element == EL_SPRING_LEFT ||
+ properties_element == EL_SPRING_RIGHT)
MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_SPRING_BUG);
if (properties_element == EL_TIME_ORB_FULL)
if (IS_BALLOON_ELEMENT(properties_element))
MapSelectboxGadget(ED_SELECTBOX_ID_WIND_DIRECTION);
- if (IS_ENVELOPE(properties_element))
+ if (IS_ENVELOPE(properties_element) ||
+ IS_MM_ENVELOPE(properties_element))
{
int counter1_id = ED_COUNTER_ID_ENVELOPE_XSIZE;
int counter2_id = ED_COUNTER_ID_ENVELOPE_YSIZE;
int button1_id = ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP;
int button2_id = ED_CHECKBUTTON_ID_ENVELOPE_CENTERED;
- int envelope_nr = properties_element - EL_ENVELOPE_1;
+ int envelope_nr = ENVELOPE_NR(properties_element);
counterbutton_info[counter1_id].value = &level.envelope[envelope_nr].xsize;
counterbutton_info[counter2_id].value = &level.envelope[envelope_nr].ysize;
MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1);
// draw drawing area gadgets
- DrawGroupElementArea(properties_element);
+ DrawGroupElementArea();
// draw text input gadgets
MapTextInputGadget(ED_TEXTINPUT_ID_ELEMENT_NAME);
draw_footer_line = TRUE;
}
-
- // draw little footer border line above CE/GE use/save template gadgets
- if (draw_footer_line)
+ else if (IS_EMPTY_ELEMENT(properties_element))
{
- struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_PROPERTIES_INFO];
- struct GadgetDesign *gd = &gd_gi1->alt_design[GD_BUTTON_UNPRESSED];
- int gd_x = gd->x + gd_gi1->border.width / 2;
- int gd_y = gd->y + gd_gi1->height - 1;
- Pixel tab_color = GetPixel(gd->bitmap, gd_x, gd_y);
+ // 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)
+ {
+ struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_PROPERTIES_INFO];
+ struct GadgetDesign *gd = &gd_gi1->alt_design[GD_BUTTON_UNPRESSED];
+ int gd_x = gd->x + gd_gi1->border.width / 2;
+ int gd_y = gd->y + gd_gi1->height - 1;
+ Pixel tab_color = GetPixel(gd->bitmap, gd_x, gd_y);
if (tab_color != BLACK_PIXEL) // black => transparent
FillRectangle(drawto,
int font_height = getFontHeight(font_nr);
int max_text_width = SXSIZE - x - ED_ELEMENT_SETTINGS_X(0);
int max_chars_per_line = max_text_width / font_width;
- char buffer[max_chars_per_line + 1];
if (strlen(element_name) <= max_chars_per_line)
DrawTextS(x, y, font_nr, element_name);
else
{
+ char buffer[max_chars_per_line + 1];
int next_pos = max_chars_per_line;
strncpy(buffer, element_name, max_chars_per_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;
UnmapLevelEditorToolboxDrawingGadgets();
UnmapLevelEditorToolboxCustomGadgets();
- if (IS_CUSTOM_ELEMENT(properties_element) ||
- IS_GROUP_ELEMENT(properties_element))
- MapLevelEditorToolboxCustomGadgets();
+ MapLevelEditorToolboxCustomGadgetsIfNeeded();
SetMainBackgroundImage(IMG_BACKGROUND_EDITOR);
ClearField();
static int getClosedTube(int x, int y)
{
- static int xy[4][2] =
- {
- { -1, 0 },
- { +1, 0 },
- { 0, -1 },
- { 0, +1 }
- };
+ struct XY *xy = xy_directions;
int element_old = IntelliDrawBuffer[x][y];
int direction_old = getOpenDirectionFromTube(element_old);
int direction_new = MV_NONE;
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
int dir = MV_DIR_FROM_BIT(i);
int dir_opposite = MV_DIR_OPPOSITE(dir);
static int getClosedBelt(int x, int y)
{
- static int xy[4][2] =
- {
- { -1, 0 },
- { +1, 0 },
- { 0, -1 },
- { 0, +1 }
- };
+ struct XY *xy = xy_directions;
int element_old = IntelliDrawBuffer[x][y];
int nr = getBeltNrFromBeltElement(element_old);
int direction_old = getOpenDirectionFromBelt(element_old);
for (i = MV_BIT_LEFT; i <= MV_BIT_RIGHT; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
int dir = MV_DIR_FROM_BIT(i);
int dir_opposite = MV_DIR_OPPOSITE(dir);
static int getClosedPool(int x, int y)
{
- static int xy[4][2] =
- {
- { -1, 0 },
- { +1, 0 },
- { 0, -1 },
- { 0, +1 }
- };
+ struct XY *xy = xy_directions;
int element_old = IntelliDrawBuffer[x][y];
int direction_old = getOpenDirectionFromPool(element_old);
int direction_new = MV_NONE;
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
int dir = MV_DIR_FROM_BIT(i);
int dir_opposite = MV_DIR_OPPOSITE(dir);
static int getClosedPillar(int x, int y)
{
- static int xy[4][2] =
- {
- { -1, 0 },
- { +1, 0 },
- { 0, -1 },
- { 0, +1 }
- };
+ struct XY *xy = xy_directions;
int element_old = IntelliDrawBuffer[x][y];
int direction_old = getOpenDirectionFromPillar(element_old);
int direction_new = MV_NONE;
for (i = MV_BIT_UP; i <= MV_BIT_DOWN; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
int dir = MV_DIR_FROM_BIT(i);
int dir_opposite = MV_DIR_OPPOSITE(dir);
static int getClosedSteel2(int x, int y)
{
- static int xy[4][2] =
- {
- { -1, 0 },
- { +1, 0 },
- { 0, -1 },
- { 0, +1 }
- };
+ struct XY *xy = xy_directions;
int element_old = IntelliDrawBuffer[x][y];
int direction_old = getOpenDirectionFromSteel2(element_old);
int direction_new = MV_NONE;
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
int dir = MV_DIR_FROM_BIT(i);
int dir_opposite = MV_DIR_OPPOSITE(dir);
static int getClosedChip(int x, int y)
{
- static int xy[4][2] =
- {
- { -1, 0 },
- { +1, 0 },
- { 0, -1 },
- { 0, +1 }
- };
+ struct XY *xy = xy_directions;
int element_old = IntelliDrawBuffer[x][y];
int direction_old = getOpenDirectionFromChip(element_old);
int direction_new = MV_NONE;
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
int dir = MV_DIR_FROM_BIT(i);
int dir_opposite = MV_DIR_OPPOSITE(dir);
{
int sx = x - level_xpos;
int sy = y - level_ypos;
- int old_element = Feld[x][y];
+ int old_element = Tile[x][y];
int new_element = element;
unsigned int new_bitmask = (getDrawModeHiRes() ? (dx + 1) << (dy * 2) : 0x0f);
boolean draw_masked = FALSE;
IntelliDrawBuffer[x][y] = element;
if (change_level)
- Feld[x][y] = element;
+ Tile[x][y] = element;
if (IN_ED_FIELD(sx, sy))
{
SetElementSimple(x2, y2, *element2, change_level);
}
-static void SetElementIntelliDraw(int x, int y, int new_element,
+static void SetElementIntelliDraw(int x, int y, int dx, int dy, int new_element,
boolean change_level, int button)
{
- static int xy[4][2] =
- {
- { -1, 0 },
- { +1, 0 },
- { 0, -1 },
- { 0, +1 }
- };
+ struct XY *xy = xy_directions;
static int last_x = -1;
static int last_y = -1;
- int old_element = IntelliDrawBuffer[x][y];
if (new_element == EL_UNDEFINED)
{
return;
}
+ int old_element = IntelliDrawBuffer[x][y];
+
if (IS_TUBE(new_element))
{
int last_element_new = EL_UNDEFINED;
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) &&
IS_TUBE(IntelliDrawBuffer[last_x][last_y]))
for (i = MV_BIT_LEFT; i <= MV_BIT_RIGHT; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) &&
IS_BELT(IntelliDrawBuffer[last_x][last_y]))
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) &&
IS_ACID_POOL_OR_ACID(IntelliDrawBuffer[last_x][last_y]))
for (i = MV_BIT_UP; i <= MV_BIT_DOWN; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) &&
IS_EMC_PILLAR(IntelliDrawBuffer[last_x][last_y]))
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) &&
IS_DC_STEELWALL_2(IntelliDrawBuffer[last_x][last_y]))
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) &&
IS_SP_CHIP(IntelliDrawBuffer[last_x][last_y]))
for (i = 0; i < NUM_DIRECTIONS; i++)
{
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ int xx = x + xy[i].x;
+ int yy = y + xy[i].y;
if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) &&
IS_IN_GROUP_EL(IntelliDrawBuffer[last_x][last_y], new_element))
EL_DF_RECEIVER_DOWN,
EL_DF_RECEIVER_LEFT
},
+ {
+ EL_DF_SLOPE_1,
+ EL_DF_SLOPE_4,
+ EL_DF_SLOPE_3,
+ EL_DF_SLOPE_2
+ },
{
-1,
EL_DF_MIRROR_ROTATING_3,
EL_DF_MIRROR_ROTATING_2
},
+ {
+ EL_DF_MIRROR_FIXED_1,
+ EL_DF_MIRROR_FIXED_16,
+ EL_DF_MIRROR_FIXED_15,
+ EL_DF_MIRROR_FIXED_14,
+ EL_DF_MIRROR_FIXED_13,
+ EL_DF_MIRROR_FIXED_12,
+ EL_DF_MIRROR_FIXED_11,
+ EL_DF_MIRROR_FIXED_10,
+ EL_DF_MIRROR_FIXED_9,
+ EL_DF_MIRROR_FIXED_8,
+ EL_DF_MIRROR_FIXED_7,
+ EL_DF_MIRROR_FIXED_6,
+ EL_DF_MIRROR_FIXED_5,
+ EL_DF_MIRROR_FIXED_4,
+ EL_DF_MIRROR_FIXED_3,
+ EL_DF_MIRROR_FIXED_2
+ },
{
-1,
}
}
- SetElementSimple(x, y, new_element, change_level);
+ if (IS_MM_WALL_EDITOR(new_element))
+ SetElementSimpleExt(x, y, dx, dy, new_element, change_level);
+ else
+ SetElementSimple(x, y, new_element, change_level);
last_x = x;
last_y = y;
for (x = 0; x < lev_fieldx; x++)
for (y = 0; y < lev_fieldy; y++)
- IntelliDrawBuffer[x][y] = Feld[x][y];
+ IntelliDrawBuffer[x][y] = Tile[x][y];
- SetElementIntelliDraw(-1, -1, EL_UNDEFINED, FALSE, -1);
+ SetElementIntelliDraw(-1, -1, -1, -1, EL_UNDEFINED, FALSE, -1);
}
static boolean draw_mode_hires = FALSE;
+static boolean isHiresTileElement(int element)
+{
+ return (IS_MM_WALL(element) || element == EL_EMPTY);
+}
+
+static boolean isHiresDrawElement(int element)
+{
+ return (IS_MM_WALL_EDITOR(element) || element == EL_EMPTY);
+}
+
+static int numHiresTiles(int element)
+{
+ if (IS_MM_WALL(element))
+ return get_number_of_bits(MM_WALL_BITS(element));
+
+ return 1;
+}
+
static void SetDrawModeHiRes(int element)
{
draw_mode_hires =
(level.game_engine_type == GAME_ENGINE_TYPE_MM &&
- (IS_MM_WALL_EDITOR(element) || element == EL_EMPTY));
+ isHiresDrawElement(element));
}
static boolean getDrawModeHiRes(void)
boolean change_level, int button)
{
if (element < 0)
- SetElementSimple(x, y, Feld[x][y], change_level);
- else if (GetKeyModState() & KMOD_Shift && !IS_MM_WALL_EDITOR(element))
- SetElementIntelliDraw(x, y, element, change_level, button);
+ SetElementSimple(x, y, Tile[x][y], change_level);
+ else if (GetKeyModState() & KMOD_Shift)
+ SetElementIntelliDraw(x, y, dx, dy, element, change_level, button);
else
SetElementSimpleExt(x, y, dx, dy, element, change_level);
}
int ly = ly2 / 2;
int dx = lx2 % 2;
int dy = ly2 % 2;
- int element = Feld[lx][ly];
+ int element = Tile[lx][ly];
unsigned int bitmask = (dx + 1) << (dy * 2);
if (IS_MM_WALL(element))
DrawArcExt(from_x, from_y, to_x2, to_y2, element, change_level);
DrawArcExt(from_x, from_y, mirror_to_x2, to_y2, element, change_level);
DrawArcExt(from_x, from_y, to_x2, mirror_to_y2, element, change_level);
- DrawArcExt(from_x, from_y, mirror_to_x2, mirror_to_y2, element,change_level);
+ DrawArcExt(from_x, from_y, mirror_to_x2, mirror_to_y2, element, change_level);
}
#endif
#define CB_BRUSH_TO_CLIPBOARD 7
#define CB_BRUSH_TO_CLIPBOARD_SMALL 8
#define CB_UPDATE_BRUSH_POSITION 9
+#define CB_FLIP_BRUSH_X 10
+#define CB_FLIP_BRUSH_Y 11
+#define CB_FLIP_BRUSH_XY 12
#define MAX_CB_PART_SIZE 10
#define MAX_CB_LINE_SIZE (MAX_LEV_FIELDX + 1) // text plus newline
MAX_CB_NUM_LINES * \
MAX_CB_PART_SIZE)
+static int getFlippedTileExt(int map[], int element)
+{
+ int i;
+
+ for (i = 0; map[i] != -1; i++)
+ if (map[i] == element)
+ return map[i ^ 1]; // get flipped element by flipping LSB of index
+
+ return element;
+}
+
+static int getFlippedTileX(int element)
+{
+ int map[] =
+ {
+ EL_BD_BUTTERFLY_LEFT, EL_BD_BUTTERFLY_RIGHT,
+ EL_BD_FIREFLY_LEFT, EL_BD_FIREFLY_RIGHT,
+ EL_BUG_LEFT, EL_BUG_RIGHT,
+ EL_SPACESHIP_LEFT, EL_SPACESHIP_RIGHT,
+ EL_PACMAN_LEFT, EL_PACMAN_RIGHT,
+ EL_ARROW_LEFT, EL_ARROW_RIGHT,
+ EL_MOLE_LEFT, EL_MOLE_RIGHT,
+ EL_BALLOON_SWITCH_LEFT, EL_BALLOON_SWITCH_RIGHT,
+ EL_YAMYAM_LEFT, EL_YAMYAM_RIGHT,
+ EL_SP_PORT_LEFT, EL_SP_PORT_RIGHT,
+ EL_SP_GRAVITY_PORT_LEFT, EL_SP_GRAVITY_PORT_RIGHT,
+ EL_SP_GRAVITY_ON_PORT_LEFT, EL_SP_GRAVITY_ON_PORT_RIGHT,
+ EL_SP_GRAVITY_OFF_PORT_LEFT, EL_SP_GRAVITY_OFF_PORT_RIGHT,
+ EL_CONVEYOR_BELT_1_LEFT, EL_CONVEYOR_BELT_1_RIGHT,
+ EL_CONVEYOR_BELT_2_LEFT, EL_CONVEYOR_BELT_2_RIGHT,
+ EL_CONVEYOR_BELT_3_LEFT, EL_CONVEYOR_BELT_3_RIGHT,
+ EL_CONVEYOR_BELT_4_LEFT, EL_CONVEYOR_BELT_4_RIGHT,
+ EL_SPRING_LEFT, EL_SPRING_RIGHT,
+ EL_SP_CHIP_LEFT, EL_SP_CHIP_RIGHT,
+ EL_TUBE_VERTICAL_LEFT, EL_TUBE_VERTICAL_RIGHT,
+ EL_TUBE_LEFT_UP, EL_TUBE_RIGHT_UP,
+ EL_TUBE_LEFT_DOWN, EL_TUBE_RIGHT_DOWN,
+ EL_DC_STEELWALL_1_LEFT, EL_DC_STEELWALL_1_RIGHT,
+ EL_DC_STEELWALL_1_TOPLEFT, EL_DC_STEELWALL_1_TOPRIGHT,
+ EL_DC_STEELWALL_1_BOTTOMLEFT, EL_DC_STEELWALL_1_BOTTOMRIGHT,
+ EL_DC_STEELWALL_1_TOPLEFT_2, EL_DC_STEELWALL_1_TOPRIGHT_2,
+ EL_DC_STEELWALL_1_BOTTOMLEFT_2, EL_DC_STEELWALL_1_BOTTOMRIGHT_2,
+ EL_DC_STEELWALL_2_LEFT, EL_DC_STEELWALL_2_RIGHT,
+ EL_ACID_POOL_TOPLEFT, EL_ACID_POOL_TOPRIGHT,
+ EL_ACID_POOL_BOTTOMLEFT, EL_ACID_POOL_BOTTOMRIGHT,
+
+ -1
+ };
+
+ return getFlippedTileExt(map, element);
+}
+
+static int getFlippedTileY(int element)
+{
+ int map[] =
+ {
+ EL_BD_BUTTERFLY_UP, EL_BD_BUTTERFLY_DOWN,
+ EL_BD_FIREFLY_UP, EL_BD_FIREFLY_DOWN,
+ EL_BUG_UP, EL_BUG_DOWN,
+ EL_SPACESHIP_UP, EL_SPACESHIP_DOWN,
+ EL_PACMAN_UP, EL_PACMAN_DOWN,
+ EL_ARROW_UP, EL_ARROW_DOWN,
+ EL_MOLE_UP, EL_MOLE_DOWN,
+ EL_BALLOON_SWITCH_UP, EL_BALLOON_SWITCH_DOWN,
+ EL_YAMYAM_UP, EL_YAMYAM_DOWN,
+ EL_SP_PORT_UP, EL_SP_PORT_DOWN,
+ EL_SP_GRAVITY_PORT_UP, EL_SP_GRAVITY_PORT_DOWN,
+ EL_SP_GRAVITY_ON_PORT_UP, EL_SP_GRAVITY_ON_PORT_DOWN,
+ EL_SP_GRAVITY_OFF_PORT_UP, EL_SP_GRAVITY_OFF_PORT_DOWN,
+ EL_SP_CHIP_TOP, EL_SP_CHIP_BOTTOM,
+ EL_TUBE_HORIZONTAL_UP, EL_TUBE_HORIZONTAL_DOWN,
+ EL_TUBE_LEFT_UP, EL_TUBE_LEFT_DOWN,
+ EL_TUBE_RIGHT_UP, EL_TUBE_RIGHT_DOWN,
+ EL_DC_STEELWALL_1_TOP, EL_DC_STEELWALL_1_BOTTOM,
+ EL_DC_STEELWALL_1_TOPLEFT, EL_DC_STEELWALL_1_BOTTOMLEFT,
+ EL_DC_STEELWALL_1_TOPRIGHT, EL_DC_STEELWALL_1_BOTTOMRIGHT,
+ EL_DC_STEELWALL_1_TOPLEFT_2, EL_DC_STEELWALL_1_BOTTOMLEFT_2,
+ EL_DC_STEELWALL_1_TOPRIGHT_2, EL_DC_STEELWALL_1_BOTTOMRIGHT_2,
+ EL_DC_STEELWALL_2_TOP, EL_DC_STEELWALL_2_BOTTOM,
+ EL_EMC_WALL_1, EL_EMC_WALL_3,
+
+ -1
+ };
+
+ return getFlippedTileExt(map, element);
+}
+
+static int getFlippedTileXY(int element)
+{
+ int map[] =
+ {
+ EL_BD_BUTTERFLY_LEFT, EL_BD_BUTTERFLY_UP,
+ EL_BD_BUTTERFLY_RIGHT, EL_BD_BUTTERFLY_DOWN,
+ EL_BD_FIREFLY_LEFT, EL_BD_FIREFLY_UP,
+ EL_BD_FIREFLY_RIGHT, EL_BD_FIREFLY_DOWN,
+ EL_BUG_LEFT, EL_BUG_UP,
+ EL_BUG_RIGHT, EL_BUG_DOWN,
+ EL_SPACESHIP_LEFT, EL_SPACESHIP_UP,
+ EL_SPACESHIP_RIGHT, EL_SPACESHIP_DOWN,
+ EL_PACMAN_LEFT, EL_PACMAN_UP,
+ EL_PACMAN_RIGHT, EL_PACMAN_DOWN,
+ EL_ARROW_LEFT, EL_ARROW_UP,
+ EL_ARROW_RIGHT, EL_ARROW_DOWN,
+ EL_MOLE_LEFT, EL_MOLE_UP,
+ EL_MOLE_RIGHT, EL_MOLE_DOWN,
+ EL_BALLOON_SWITCH_LEFT, EL_BALLOON_SWITCH_UP,
+ EL_BALLOON_SWITCH_RIGHT, EL_BALLOON_SWITCH_DOWN,
+ EL_YAMYAM_LEFT, EL_YAMYAM_UP,
+ EL_YAMYAM_RIGHT, EL_YAMYAM_DOWN,
+ EL_SP_PORT_LEFT, EL_SP_PORT_UP,
+ EL_SP_PORT_RIGHT, EL_SP_PORT_DOWN,
+ EL_SP_GRAVITY_PORT_LEFT, EL_SP_GRAVITY_PORT_UP,
+ EL_SP_GRAVITY_PORT_RIGHT, EL_SP_GRAVITY_PORT_DOWN,
+ EL_SP_GRAVITY_ON_PORT_LEFT, EL_SP_GRAVITY_ON_PORT_UP,
+ EL_SP_GRAVITY_ON_PORT_RIGHT, EL_SP_GRAVITY_ON_PORT_DOWN,
+ EL_SP_GRAVITY_OFF_PORT_LEFT, EL_SP_GRAVITY_OFF_PORT_UP,
+ EL_SP_GRAVITY_OFF_PORT_RIGHT, EL_SP_GRAVITY_OFF_PORT_DOWN,
+ EL_SP_CHIP_LEFT, EL_SP_CHIP_TOP,
+ EL_SP_CHIP_RIGHT, EL_SP_CHIP_BOTTOM,
+ EL_TUBE_VERTICAL, EL_TUBE_HORIZONTAL,
+ EL_TUBE_VERTICAL_LEFT, EL_TUBE_HORIZONTAL_UP,
+ EL_TUBE_VERTICAL_RIGHT, EL_TUBE_HORIZONTAL_DOWN,
+ EL_TUBE_LEFT_DOWN, EL_TUBE_RIGHT_UP,
+ EL_DC_STEELWALL_1_LEFT, EL_DC_STEELWALL_1_TOP,
+ EL_DC_STEELWALL_1_RIGHT, EL_DC_STEELWALL_1_BOTTOM,
+ EL_DC_STEELWALL_1_HORIZONTAL, EL_DC_STEELWALL_1_VERTICAL,
+ EL_DC_STEELWALL_1_TOPRIGHT, EL_DC_STEELWALL_1_BOTTOMLEFT,
+ EL_DC_STEELWALL_1_TOPRIGHT_2, EL_DC_STEELWALL_1_BOTTOMLEFT_2,
+ EL_DC_STEELWALL_2_LEFT, EL_DC_STEELWALL_2_TOP,
+ EL_DC_STEELWALL_2_RIGHT, EL_DC_STEELWALL_2_BOTTOM,
+ EL_DC_STEELWALL_2_HORIZONTAL, EL_DC_STEELWALL_2_VERTICAL,
+ EL_EXPANDABLE_WALL_HORIZONTAL, EL_EXPANDABLE_WALL_VERTICAL,
+ EL_EXPANDABLE_STEELWALL_HORIZONTAL, EL_EXPANDABLE_STEELWALL_VERTICAL,
+
+ -1
+ };
+
+ return getFlippedTileExt(map, element);
+}
+
+static int getFlippedTile(int element, int mode)
+{
+ if (IS_MM_ELEMENT(element))
+ {
+ // get MM game element
+ element = map_element_RND_to_MM(element);
+
+ // get flipped game element
+ element = (mode == CB_FLIP_BRUSH_X ? getFlippedTileX_MM(element) :
+ mode == CB_FLIP_BRUSH_Y ? getFlippedTileY_MM(element) :
+ mode == CB_FLIP_BRUSH_XY ? getFlippedTileXY_MM(element) :
+ element);
+
+ // get RND game element again
+ element = map_element_MM_to_RND(element);
+ }
+ else
+ {
+ // get flipped game element
+ element = (mode == CB_FLIP_BRUSH_X ? getFlippedTileX(element) :
+ mode == CB_FLIP_BRUSH_Y ? getFlippedTileY(element) :
+ mode == CB_FLIP_BRUSH_XY ? getFlippedTileXY(element) :
+ element);
+ }
+
+ return element;
+}
+
+static void SwapFlippedTiles(short *tile1, short *tile2, int mode)
+{
+ // flip tiles
+ short tile1_flipped = getFlippedTile(*tile1, mode);
+ short tile2_flipped = getFlippedTile(*tile2, mode);
+
+ // swap tiles
+ *tile1 = tile2_flipped;
+ *tile2 = tile1_flipped;
+}
+
static void DrawBrushElement(int sx, int sy, int element, boolean change_level)
{
DrawLineElement(sx, sy, element, change_level);
char text[MAX_CB_TEXT_SIZE + 1] = "";
int width = (draw_with_brush ? brush_width : lev_fieldx);
int height = (draw_with_brush ? brush_height : lev_fieldy);
+ char *format = "%s%03d";
+
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++)
+ if ((draw_with_brush ? brush_buffer[x][y] : Tile[x][y]) > 999)
+ format = "%s%04d";
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
- int element = (draw_with_brush ? brush_buffer[x][y] : Feld[x][y]);
- int element_mapped = element;
+ int element = (draw_with_brush ? brush_buffer[x][y] : Tile[x][y]);
char *prefix = (mode == CB_DUMP_BRUSH ||
mode == CB_BRUSH_TO_CLIPBOARD ? "`" : "¸");
- if (IS_CUSTOM_ELEMENT(element))
- element_mapped = EL_CUSTOM_START;
- else if (IS_GROUP_ELEMENT(element))
- element_mapped = EL_GROUP_START;
- else if (element >= NUM_FILE_ELEMENTS)
- element_mapped = EL_UNKNOWN;
+ if (element >= NUM_FILE_ELEMENTS)
+ element = EL_UNKNOWN;
// copy brush to level sketch text buffer for the R'n'D forum:
- // - large tiles: `xxx (0x60 ASCII)
- // - small tiles: ¸xxx (0xb8 ISO-8859-1, 0xc2b8 UTF-8)
- snprintf(part, MAX_CB_PART_SIZE + 1, "%s%03d", prefix, element_mapped);
+ // - large tiles: `xxx or `xxxx (0x60 ASCII)
+ // - small tiles: ¸xxx or ¸xxxx (0xb8 ISO-8859-1, 0xc2b8 UTF-8)
+ snprintf(part, MAX_CB_PART_SIZE + 1, format, prefix, element);
strcat(text, part);
}
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;
}
char *clipboard_text = SDL_GetClipboardText();
char *ptr = clipboard_text;
+ boolean allow_new_row = FALSE;
boolean stop = FALSE;
while (*ptr && !stop)
{
boolean prefix_found = FALSE;
+ boolean start_new_row = FALSE;
// level sketch element number prefixes (may be multi-byte characters)
char *prefix_list[] = { "`", "¸" };
}
}
- // continue with next character if prefix not found
- if (!prefix_found)
- {
- ptr++; // !!! FIX THIS for real UTF-8 handling !!!
-
- continue;
- }
-
- // continue with next character if prefix not found
- if (strlen(ptr) < 3)
- break;
-
- if (ptr[0] >= '0' && ptr[0] <= '9' &&
+ // check if prefix found and followed by (at least) three digits
+ if (prefix_found &&
+ strlen(ptr) >= 3 &&
+ ptr[0] >= '0' && ptr[0] <= '9' &&
ptr[1] >= '0' && ptr[1] <= '9' &&
ptr[2] >= '0' && ptr[2] <= '9')
{
ptr += 3;
+ // level sketch element number might consist of four digits
+ if (ptr[0] >= '0' && ptr[0] <= '9')
+ {
+ element = element * 10 + (ptr[0] - '0');
+ ptr++;
+ }
+
+ // remap some (historic, now obsolete) elements
+ element = getMappedElement(element);
+
if (element >= NUM_FILE_ELEMENTS)
element = EL_UNKNOWN;
x++;
- if (x >= MAX_LEV_FIELDX || *ptr == '\n')
- {
- x = 0;
- y++;
+ if (x >= MAX_LEV_FIELDX)
+ start_new_row = TRUE;
- if (y >= MAX_LEV_FIELDY)
- stop = TRUE;
- }
+ allow_new_row = TRUE;
+ }
+ else
+ {
+ if ((*ptr == '\n' || *ptr == '\r') && allow_new_row)
+ start_new_row = TRUE;
+
+ ptr++; // !!! FIX THIS for real UTF-8 handling !!!
+ }
+
+ if (start_new_row)
+ {
+ x = 0;
+ y++;
+
+ if (y >= MAX_LEV_FIELDY)
+ stop = TRUE;
+
+ allow_new_row = FALSE;
}
}
for (x = 0; x < MAX_LEV_FIELDX; x++)
for (y = 0; y < MAX_LEV_FIELDY; y++)
- Feld[x][y] = brush_buffer[x][y];
+ Tile[x][y] = brush_buffer[x][y];
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();
{
for (x = 0; x < brush_width; x++)
{
- brush_buffer[x][y] = Feld[from_lx + x][from_ly + y];
+ brush_buffer[x][y] = Tile[from_lx + x][from_ly + y];
if (button != 1)
DrawBrushElement(from_x + x, from_y + y, new_element, TRUE);
delete_old_brush = TRUE;
}
+ else if (mode == CB_FLIP_BRUSH_X)
+ {
+ for (y = 0; y < brush_height; y++)
+ for (x = 0; x < (brush_width + 1) / 2; x++)
+ SwapFlippedTiles(&brush_buffer[x][y],
+ &brush_buffer[brush_width - x - 1][y], mode);
+
+ CopyBrushExt(last_cursor_x, last_cursor_y, 0, 0, 0, CB_BRUSH_TO_CURSOR);
+ }
+ else if (mode == CB_FLIP_BRUSH_Y)
+ {
+ for (y = 0; y < (brush_height + 1) / 2; y++)
+ for (x = 0; x < brush_width; x++)
+ SwapFlippedTiles(&brush_buffer[x][y],
+ &brush_buffer[x][brush_height - y - 1], mode);
+
+ CopyBrushExt(last_cursor_x, last_cursor_y, 0, 0, 0, CB_BRUSH_TO_CURSOR);
+ }
+ else if (mode == CB_FLIP_BRUSH_XY)
+ {
+ CopyBrushExt(0, 0, 0, 0, 0, CB_DELETE_OLD_CURSOR);
+
+ for (y = 0; y < MAX(brush_width, brush_height); y++)
+ for (x = 0; x <= y; x++)
+ SwapFlippedTiles(&brush_buffer[x][y],
+ &brush_buffer[y][x], mode);
+
+ swap_numbers(&brush_width, &brush_height);
+
+ CopyBrushExt(last_cursor_x, last_cursor_y, 0, 0, 0, CB_BRUSH_TO_CURSOR);
+ }
if (mode == CB_UPDATE_BRUSH_POSITION)
{
CopyBrushExt(0, 0, 0, 0, 0, CB_DELETE_OLD_CURSOR);
}
+static void FlipBrushX(void)
+{
+ CopyBrushExt(0, 0, 0, 0, 0, CB_FLIP_BRUSH_X);
+}
+
+static void FlipBrushY(void)
+{
+ CopyBrushExt(0, 0, 0, 0, 0, CB_FLIP_BRUSH_Y);
+}
+
+static void RotateBrush(void)
+{
+ CopyBrushExt(0, 0, 0, 0, 0, CB_FLIP_BRUSH_XY);
+ CopyBrushExt(0, 0, 0, 0, 0, CB_FLIP_BRUSH_X);
+}
+
void DumpBrush(void)
{
CopyBrushExt(0, 0, 0, 0, 0, CB_DUMP_BRUSH);
CopyBrushExt(0, 0, 0, 0, 0, CB_BRUSH_TO_CLIPBOARD_SMALL);
}
+void UndoLevelEditorOperation(void)
+{
+ ClickOnGadget(level_editor_gadget[GADGET_ID_UNDO], -1);
+}
+
+void RedoLevelEditorOperation(void)
+{
+ ClickOnGadget(level_editor_gadget[GADGET_ID_UNDO], 3);
+}
+
static void FloodFill(int from_x, int from_y, int fill_element)
{
- FloodFillLevel(from_x, from_y, fill_element, Feld, lev_fieldx, lev_fieldy);
+ FloodFillLevel(from_x, from_y, fill_element, Tile, lev_fieldx, lev_fieldy);
}
static void FloodFillWall_MM(int from_sx2, int from_sy2, int fill_element)
int from_y = from_sy2 + 2 * level_ypos;
int max_fillx = lev_fieldx * 2;
int max_filly = lev_fieldy * 2;
- short FillFeld[max_fillx][max_filly];
+ short Fill[max_fillx][max_filly];
int x, y;
for (x = 0; x < max_fillx; x++)
for (y = 0; y < max_filly; y++)
- FillFeld[x][y] = getLevelElementHiRes(x, y);
+ Fill[x][y] = getLevelElementHiRes(x, y);
FloodFillLevelExt(from_x, from_y, fill_element, max_fillx, max_filly,
- FillFeld, max_fillx, max_filly);
+ Fill, max_fillx, max_filly);
for (x = 0; x < max_fillx; x++)
for (y = 0; y < max_filly; y++)
- if (FillFeld[x][y] == fill_element)
- SetLevelElementHiRes(x, y, FillFeld[x][y]);
+ if (Fill[x][y] == fill_element)
+ SetLevelElementHiRes(x, y, Fill[x][y]);
}
// values for DrawLevelText() modes
static int start_sx;
static int last_sx, last_sy;
static boolean typing = FALSE;
- int letter_element = EL_CHAR_ASCII0 + letter;
+ int letter_element;
int lx = 0, ly = 0;
// map lower case letters to upper case and convert special characters
break;
case TEXT_SETCURSOR:
- DrawEditorElement(last_sx, last_sy, Feld[lx][ly]);
+ DrawEditorElement(last_sx, last_sy, Tile[lx][ly]);
DrawAreaBorder(sx, sy, sx, sy);
StartTextInput(SX + sx * ed_tilesize, SY + sy * ed_tilesize,
ed_tilesize, ed_tilesize);
new_element1 <= EL_STEEL_CHAR_END)
letter_element = letter_element - EL_CHAR_START + EL_STEEL_CHAR_START;
- delete_buffer[sx - start_sx] = Feld[lx][ly];
- Feld[lx][ly] = letter_element;
+ delete_buffer[sx - start_sx] = Tile[lx][ly];
+ Tile[lx][ly] = letter_element;
if (sx + 1 < ed_fieldx && lx + 1 < lev_fieldx)
DrawLevelText(sx + 1, sy, 0, TEXT_SETCURSOR);
case TEXT_BACKSPACE:
if (sx > start_sx)
{
- Feld[lx - 1][ly] = delete_buffer[sx - start_sx - 1];
- DrawEditorElement(sx - 1, sy, Feld[lx - 1][ly]);
+ Tile[lx - 1][ly] = delete_buffer[sx - start_sx - 1];
+ DrawEditorElement(sx - 1, sy, Tile[lx - 1][ly]);
DrawLevelText(sx - 1, sy, 0, TEXT_SETCURSOR);
}
break;
case TEXT_END:
CopyLevelToUndoBuffer(UNDO_IMMEDIATE);
- DrawEditorElement(sx, sy, Feld[lx][ly]);
+ DrawEditorElement(sx, sy, Tile[lx][ly]);
StopTextInput();
typing = FALSE;
break;
int ly = sy + level_ypos;
if (element == -1)
- DrawEditorElement(sx, sy, Feld[lx][ly]);
+ DrawEditorElement(sx, sy, Tile[lx][ly]);
else
DrawAreaBorder(sx, sy, sx, sy);
}
for (x = 0; x < lev_fieldx; x++)
for (y = 0; y < lev_fieldy; y++)
- UndoBuffer[undo_buffer_position][x][y] = Feld[x][y];
+ UndoBuffer[undo_buffer_position][x][y] = Tile[x][y];
// check if drawing operation forces change of border style
CheckLevelBorderElement(TRUE);
{
free_position[x][y] =
(random_placement_background_restricted ?
- Feld[x][y] == random_placement_background_element :
- Feld[x][y] != new_element);
+ Tile[x][y] == random_placement_background_element :
+ Tile[x][y] != new_element);
if (free_position[x][y])
num_free_positions++;
for (x = 0; x < lev_fieldx; x++)
for (y = 0; y < lev_fieldy; y++)
- FieldBackup[x][y] = Feld[x][y];
+ TileBackup[x][y] = Tile[x][y];
for (x = 0; x < lev_fieldx; x++)
for (y = 0; y < lev_fieldy; y++)
- Feld[x][y] =
- FieldBackup[(x + wrap_dx) % lev_fieldx][(y + wrap_dy) % lev_fieldy];
+ Tile[x][y] =
+ TileBackup[(x + wrap_dx) % lev_fieldx][(y + wrap_dy) % lev_fieldy];
DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
CopyLevelToUndoBuffer(UNDO_ACCUMULATE);
}
+static void DrawAreaElementHighlight(boolean highlighted,
+ boolean highlighted_similar)
+{
+ 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++)
+ {
+ boolean highlight = FALSE;
+ int lx = x + level_xpos;
+ int ly = y + level_ypos;
+
+ if (!IN_LEV_FIELD(lx, ly))
+ continue;
+
+ // check if element is the same
+ if (Tile[lx][ly] == new_element1)
+ highlight = TRUE;
+
+ // check if element is similar
+ if (highlighted_similar &&
+ strEqual(element_info[Tile[lx][ly]].class_name,
+ element_info[new_element1].class_name))
+ highlight = TRUE;
+
+ // check if element is matching MM style wall
+ if (IS_MM_WALL(Tile[lx][ly]) &&
+ map_mm_wall_element(Tile[lx][ly]) == new_element1)
+ highlight = TRUE;
+
+ if (!highlight)
+ continue;
+
+ if (IS_MM_WALL(Tile[lx][ly]) && !highlighted_similar)
+ {
+ int i;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (!(MM_WALL_BITS(Tile[lx][ly]) & (1 << i)))
+ continue;
+
+ int xx = x * 2 + (i % 2);
+ int yy = y * 2 + (i / 2);
+ int sx = SX + xx * ed_tilesize / 2;
+ int sy = SY + yy * ed_tilesize / 2;
+ int from_sx = sx;
+ int from_sy = sy;
+ int to_sx = sx + ed_tilesize / 2 - 1;
+ int to_sy = sy + ed_tilesize / 2 - 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);
+ }
+ }
+ else
+ {
+ 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();
static void HandleDrawingAreas(struct GadgetInfo *gi)
{
static boolean started_inside_drawing_area = FALSE;
- static int last_sx = -1, last_sy = -1;
- static int last_sx2 = -1, last_sy2 = -1;
+ static int last_sx = -1;
+ static int last_sy = -1;
+ static int last_sx2 = -1;
+ static int last_sy2 = -1;
int id = gi->custom_id;
int type_id = gi->custom_type_id;
boolean button_press_event;
int dx = sx2 % 2;
int dy = sy2 % 2;
int lx = 0, ly = 0;
- int min_lx = 0, min_ly = 0;
- int max_lx = lev_fieldx - 1, max_ly = lev_fieldy - 1;
int x, y;
button_press_event = (gi->event.type == GD_EVENT_PRESSED);
if (draw_level)
{
+ int min_lx = 0, min_ly = 0;
+ int max_lx = lev_fieldx - 1, max_ly = lev_fieldy - 1;
+
// get positions inside level field
lx = sx + level_xpos;
ly = sy + level_ypos;
sy2 = sy * 2 + dy;
}
- if (button_release_event)
- {
- last_sx = -1;
- last_sy = -1;
- last_sx2 = -1;
- last_sy2 = -1;
- }
- else if (!button_press_event)
+ if (!button_press_event && !button_release_event)
{
+ int old_element = (IN_LEV_FIELD(lx, ly) ? Tile[lx][ly] : EL_UNDEFINED);
+ boolean hires_drawing = (level.game_engine_type == GAME_ENGINE_TYPE_MM &&
+ isHiresTileElement(old_element) &&
+ isHiresDrawElement(new_element));
+
// prevent handling events for every pixel position when moving mouse
- if ((sx == last_sx && sy == last_sy &&
- !IS_MM_WALL_EDITOR(new_element) && new_element != EL_EMPTY) ||
+ if ((sx == last_sx && sy == last_sy && !hires_drawing) ||
(sx2 == last_sx2 && sy2 == last_sy2))
return;
}
if (!IS_VALID_BUTTON(button))
return;
- if (!button && !button_release_event)
- return;
-
// handle info callback for each invocation of action callback
gi->callback_info(gi);
if (edit_mode == ED_MODE_DRAWING && draw_with_brush &&
!inside_drawing_area)
DeleteBrushFromCursor();
- }
- if (!button || button_release_event)
break;
+ }
if (draw_with_brush)
{
{
SetDrawModeHiRes(new_element);
- if (new_element == EL_PLAYER_1)
+ if (IS_PLAYER_ELEMENT(new_element) || IS_MM_MCDUFFIN(new_element))
{
// remove player at old position
for (y = 0; y < lev_fieldy; y++)
+ {
for (x = 0; x < lev_fieldx; x++)
- if (Feld[x][y] == EL_PLAYER_1)
+ {
+ int old_element = Tile[x][y];
+
+ if (IS_PLAYER_ELEMENT(old_element) &&
+ IS_PLAYER_ELEMENT(new_element))
+ {
+ int replaced_with_element =
+ (old_element == EL_SOKOBAN_FIELD_PLAYER &&
+ new_element == EL_PLAYER_1 ? EL_SOKOBAN_FIELD_EMPTY :
+
+ old_element == EL_SOKOBAN_FIELD_PLAYER &&
+ new_element == old_element ? EL_SOKOBAN_FIELD_EMPTY :
+
+ new_element == EL_SOKOBAN_FIELD_PLAYER &&
+ old_element == EL_PLAYER_1 ? EL_EMPTY :
+
+ new_element >= EL_PLAYER_1 &&
+ new_element <= EL_PLAYER_4 &&
+ new_element == old_element ? EL_EMPTY :
+
+ old_element);
+
+ SetElement(x, y, replaced_with_element);
+ }
+ else if (IS_MM_MCDUFFIN(old_element) &&
+ IS_MM_MCDUFFIN(new_element))
+ {
+ // remove McDuffin at old position
SetElement(x, y, EL_EMPTY);
+ }
+ }
+ }
}
SetElementButton(lx, ly, dx, dy, new_element, button);
if (button_release_event)
CopyLevelToUndoBuffer(UNDO_IMMEDIATE);
- if (button)
- {
- SetDrawModeHiRes(new_element);
+ SetDrawModeHiRes(new_element);
- if (getDrawModeHiRes())
- {
- sx = sx2;
- sy = sy2;
- }
+ if (getDrawModeHiRes())
+ {
+ sx = sx2;
+ sy = sy2;
+ }
- if (!button_press_event)
- DrawLine(last_sx, last_sy, sx, sy, new_element, TRUE);
+ if (!button_press_event)
+ DrawLine(last_sx, last_sy, sx, sy, new_element, TRUE);
- last_sx = sx;
- last_sy = sy;
- }
+ last_sx = sx;
+ last_sy = sy;
}
break;
break;
case GADGET_ID_FLOOD_FILL:
- if (button_press_event && Feld[lx][ly] != new_element)
+ if (button_press_event && Tile[lx][ly] != new_element)
{
if (IS_MM_WALL_EDITOR(new_element))
FloodFillWall_MM(sx2, sy2, new_element);
ClickOnGadget(level_editor_gadget[last_drawing_function],
MB_LEFTBUTTON);
else if (draw_level)
- PickDrawingElement(button, Feld[lx][ly]);
+ PickDrawingElement(button, Tile[lx][ly]);
else
{
int pos = sx * drawingarea_info[type_id].area_ysize + sy;
break;
case ED_COUNTER_ID_ANDROID_CONTENT:
- DrawAndroidElementArea(properties_element);
+ DrawAndroidElementArea();
break;
case ED_COUNTER_ID_GROUP_CONTENT:
- DrawGroupElementArea(properties_element);
+ DrawGroupElementArea();
CopyGroupElementPropertiesToGame(properties_element);
break;
DrawPlayerInitialInventoryArea(properties_element);
break;
+ case ED_COUNTER_ID_MM_BALL_CONTENT:
+ DrawMMBallContentArea();
+ break;
+
case ED_COUNTER_ID_ENVELOPE_XSIZE:
case ED_COUNTER_ID_ENVELOPE_YSIZE:
DrawEnvelopeTextArea(-1);
if (type_id == ED_SELECTBOX_ID_LEVELSET_SAVE_MODE)
{
- DrawLevelInfoWindow();
+ DrawLevelConfigWindow();
}
else if (type_id == ED_SELECTBOX_ID_SELECT_CHANGE_PAGE)
{
int type_id = gi->custom_type_id;
int i;
- if (type_id >= ED_TAB_BUTTON_ID_LEVELINFO_FIRST &&
- type_id <= ED_TAB_BUTTON_ID_LEVELINFO_LAST)
+ if (type_id >= ED_TAB_BUTTON_ID_LEVELCONFIG_FIRST &&
+ type_id <= ED_TAB_BUTTON_ID_LEVELCONFIG_LAST)
{
- edit_mode_levelinfo = gi->custom_type_id;
+ edit_mode_levelconfig = gi->custom_type_id;
- DrawLevelInfoWindow();
+ DrawLevelConfigWindow();
}
else if (type_id >= ED_TAB_BUTTON_ID_PROPERTIES_FIRST &&
type_id <= ED_TAB_BUTTON_ID_PROPERTIES_LAST)
boolean new_template = !fileExists(getLocalLevelTemplateFilename());
// backup original "level.field" (needed to track playfield changes)
- CopyPlayfield(level.field, FieldBackup);
+ CopyPlayfield(level.field, TileBackup);
// "SaveLevelTemplate()" uses "level.field", so copy editor playfield
- CopyPlayfield(Feld, level.field);
+ CopyPlayfield(Tile, level.field);
if (new_template ||
Request("Save this template and kill the old?", REQ_ASK))
Request("Template saved!", REQ_CONFIRM);
// restore original "level.field" (needed to track playfield changes)
- CopyPlayfield(FieldBackup, level.field);
+ CopyPlayfield(TileBackup, level.field);
}
else if (type_id == ED_TEXTBUTTON_ID_SAVE_LEVELSET)
{
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);
button == 2 ? ed_tilesize_default :
button == 3 ? ed_tilesize / 2 : ed_tilesize);
+ // when using touch device, cycle through all zoom tilesizes
+ if (runtime.uses_touch_device && ed_tilesize > TILESIZE)
+ ed_tilesize = MICRO_TILESIZE;
+
// limit zoom level by upper and lower bound
ed_tilesize = MIN(MAX(MICRO_TILESIZE, ed_tilesize), TILESIZE);
break;
case GADGET_ID_UNDO:
- if (button == 1 && GetKeyModState() & (KMOD_Shift|KMOD_Control))
+ if (button < 0) // keep button value (even if modifier keys are pressed)
+ button = -button;
+ else if (button == 1 && GetKeyModState() & (KMOD_Shift | KMOD_Control))
button = 3;
if (button == 1 && undo_buffer_steps == 0)
for (x = 0; x < lev_fieldx; x++)
for (y = 0; y < lev_fieldy; y++)
- Feld[x][y] = UndoBuffer[undo_buffer_position][x][y];
+ Tile[x][y] = UndoBuffer[undo_buffer_position][x][y];
// check if undo operation forces change of border style
CheckLevelBorderElement(FALSE);
break;
- case GADGET_ID_INFO:
- if (edit_mode != ED_MODE_INFO)
+ case GADGET_ID_CONF:
+ if (edit_mode != ED_MODE_LEVELCONFIG)
{
last_edit_mode = edit_mode;
- ChangeEditModeWindow(ED_MODE_INFO);
+ ChangeEditModeWindow(ED_MODE_LEVELCONFIG);
}
else
{
- ChangeEditModeWindow(last_edit_mode);
+ ChangeEditModeWindow(ED_MODE_DRAWING);
}
break;
for (x = 0; x < MAX_LEV_FIELDX; x++)
for (y = 0; y < MAX_LEV_FIELDY; y++)
- Feld[x][y] = (button == 1 ? EL_EMPTY : new_element);
+ Tile[x][y] = (button == 1 ? EL_EMPTY : new_element);
CopyLevelToUndoBuffer(GADGET_ID_CLEAR);
Request("Save this level and kill the old?", REQ_ASK))
{
if (leveldir_former->readonly)
- ModifyLevelInfoForSavingIntoPersonalLevelSet(leveldir_former->name);
+ ModifyLevelConfigForSavingIntoPersonalLevelSet(leveldir_former->name);
SetAutomaticNumberOfGemsNeeded();
- CopyPlayfield(Feld, level.field);
+ CopyPlayfield(Tile, level.field);
SaveLevel(level_nr);
level.changed = FALSE;
if (LevelChanged())
level.game_version = GAME_VERSION_ACTUAL;
- CopyPlayfield(level.field, FieldBackup);
- CopyPlayfield(Feld, level.field);
+ CopyPlayfield(level.field, TileBackup);
+ CopyPlayfield(Tile, level.field);
CopyNativeLevel_RND_to_Native(&level);
id <= GADGET_ID_ELEMENTLIST_LAST)
{
int element_position = id - GADGET_ID_ELEMENTLIST_FIRST;
- int new_element = editor_elements[element_position + element_shift];
+
+ new_element = editor_elements[element_position + element_shift];
if (IS_EDITOR_CASCADE(new_element))
{
}
#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;
}
void HandleLevelEditorKeyInput(Key key)
{
char letter = getCharFromKey(key);
- int button = MB_LEFTBUTTON;
if (drawing_function == GADGET_ID_TEXT &&
DrawLevelText(0, 0, 0, TEXT_QUERY_TYPING) == TRUE)
DrawLevelText(0, 0, 0, TEXT_NEWLINE);
else if (key == KSYM_Escape)
DrawLevelText(0, 0, 0, TEXT_END);
+
+ return;
}
- else if (button_status == MB_RELEASED)
+
+ int id = GADGET_ID_NONE;
+ int new_element_shift = element_shift;
+ int step = ED_ELEMENTLIST_BUTTONS_VERT - 1;
+ int button = MB_LEFTBUTTON;
+ int i;
+
+ switch (key)
{
- int id = GADGET_ID_NONE;
- int new_element_shift = element_shift;
- int step = ED_ELEMENTLIST_BUTTONS_VERT - 1;
- int i;
+ case KSYM_Left:
+ id = GADGET_ID_SCROLL_LEFT;
+ break;
+ case KSYM_Right:
+ id = GADGET_ID_SCROLL_RIGHT;
+ break;
+ case KSYM_Up:
+ id = GADGET_ID_SCROLL_UP;
+ break;
+ case KSYM_Down:
+ id = GADGET_ID_SCROLL_DOWN;
+ break;
- switch (key)
- {
- case KSYM_Left:
- id = GADGET_ID_SCROLL_LEFT;
- break;
- case KSYM_Right:
- id = GADGET_ID_SCROLL_RIGHT;
- break;
- case KSYM_Up:
- id = GADGET_ID_SCROLL_UP;
- break;
- case KSYM_Down:
- id = GADGET_ID_SCROLL_DOWN;
- break;
+ case KSYM_Page_Up:
+ case KSYM_Page_Down:
+ step *= (key == KSYM_Page_Up ? -1 : +1);
+ element_shift += step * ED_ELEMENTLIST_BUTTONS_HORIZ;
- case KSYM_Page_Up:
- case KSYM_Page_Down:
- step *= (key == KSYM_Page_Up ? -1 : +1);
- element_shift += step * ED_ELEMENTLIST_BUTTONS_HORIZ;
+ if (element_shift < 0)
+ element_shift = 0;
+ if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS)
+ element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS;
- if (element_shift < 0)
- element_shift = 0;
- if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS)
- element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS;
+ ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL],
+ GDI_SCROLLBAR_ITEM_POSITION,
+ element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END);
- ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL],
- GDI_SCROLLBAR_ITEM_POSITION,
- element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END);
+ ModifyEditorElementList();
- ModifyEditorElementList();
+ break;
- break;
+ case KSYM_Home:
+ case KSYM_End:
+ element_shift = (key == KSYM_Home ? 0 :
+ num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS);
- case KSYM_Home:
- case KSYM_End:
- element_shift = (key == KSYM_Home ? 0 :
- num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS);
+ ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL],
+ GDI_SCROLLBAR_ITEM_POSITION,
+ element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END);
- ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL],
- GDI_SCROLLBAR_ITEM_POSITION,
- element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END);
+ ModifyEditorElementList();
- ModifyEditorElementList();
+ break;
- break;
+ case KSYM_Insert:
+ case KSYM_Delete:
- case KSYM_Insert:
- case KSYM_Delete:
+ // this is needed to prevent interference with running "True X-Mouse"
+ if (GetKeyModStateFromEvents() & KMOD_Control)
+ break;
- // this is needed to prevent interference with running "True X-Mouse"
- if (GetKeyModStateFromEvents() & KMOD_Control)
+ // check for last or next editor cascade block in element list
+ for (i = 0; i < num_editor_elements; i++)
+ {
+ if ((key == KSYM_Insert && i == element_shift) ||
+ (key == KSYM_Delete && new_element_shift > element_shift))
break;
- // check for last or next editor cascade block in element list
- for (i = 0; i < num_editor_elements; i++)
- {
- if ((key == KSYM_Insert && i == element_shift) ||
- (key == KSYM_Delete && new_element_shift > element_shift))
- break;
+ // jump to next cascade block (or to start of element list)
+ if (i == 0 || IS_EDITOR_CASCADE(editor_elements[i]))
+ new_element_shift = i;
+ }
- // jump to next cascade block (or to start of element list)
- if (i == 0 || IS_EDITOR_CASCADE(editor_elements[i]))
- new_element_shift = i;
- }
+ if (i < num_editor_elements)
+ element_shift = new_element_shift;
- if (i < num_editor_elements)
- element_shift = new_element_shift;
+ if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS)
+ element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS;
- if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS)
- element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS;
+ ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL],
+ GDI_SCROLLBAR_ITEM_POSITION,
+ element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END);
- ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL],
- GDI_SCROLLBAR_ITEM_POSITION,
- element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END);
+ ModifyEditorElementList();
- ModifyEditorElementList();
+ break;
- break;
+ case KSYM_Escape:
+ if (edit_mode == ED_MODE_DRAWING)
+ RequestExitLevelEditor(setup.ask_on_escape_editor, TRUE);
+ else if (edit_mode == ED_MODE_LEVELCONFIG)
+ HandleControlButtons(level_editor_gadget[GADGET_ID_CONF]);
+ else if (edit_mode == ED_MODE_PROPERTIES)
+ HandleControlButtons(level_editor_gadget[GADGET_ID_PROPERTIES]);
+ else if (edit_mode == ED_MODE_PALETTE)
+ HandleControlButtons(level_editor_gadget[GADGET_ID_PALETTE]);
+ else // should never happen
+ ChangeEditModeWindow(ED_MODE_DRAWING);
- case KSYM_Escape:
- if (edit_mode == ED_MODE_DRAWING)
- {
- RequestExitLevelEditor(setup.ask_on_escape_editor, TRUE);
- }
- else if (edit_mode == ED_MODE_INFO)
- {
- HandleControlButtons(level_editor_gadget[GADGET_ID_INFO]);
- }
- else if (edit_mode == ED_MODE_PROPERTIES)
- {
- HandleControlButtons(level_editor_gadget[GADGET_ID_PROPERTIES]);
- }
- else if (edit_mode == ED_MODE_PALETTE)
- {
- HandleControlButtons(level_editor_gadget[GADGET_ID_PALETTE]);
- }
- else // should never happen
- {
- ChangeEditModeWindow(ED_MODE_DRAWING);
- }
+ break;
- break;
+ default:
+ break;
+ }
- default:
- break;
- }
+ if (id != GADGET_ID_NONE)
+ ClickOnGadget(level_editor_gadget[id], button);
+ else if (letter == '1' || letter == '?')
+ ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_LEFT], button);
+ else if (letter == '2')
+ ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_MIDDLE], button);
+ else if (letter == '3')
+ ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_RIGHT], button);
+ else if (letter == '.')
+ ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS], button);
+ else if (letter == 'U')
+ ClickOnGadget(level_editor_gadget[GADGET_ID_UNDO], 3);
+ else if (letter == '-' || key == KSYM_KP_Subtract)
+ ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 3);
+ else if (letter == '0' || key == KSYM_KP_0)
+ ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 2);
+ else if (letter == '+' || key == KSYM_KP_Add ||
+ letter == '=') // ("Shift-=" is "+" on US keyboards)
+ ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 1);
+ else if (key == KSYM_Return ||
+ key == KSYM_space ||
+ key == setup.shortcut.toggle_pause)
+ ClickOnGadget(level_editor_gadget[GADGET_ID_TEST], button);
+ else
+ for (i = 0; i < ED_NUM_CTRL_BUTTONS; i++)
+ if (letter && letter == controlbutton_info[i].shortcut)
+ if (!anyTextGadgetActive())
+ ClickOnGadget(level_editor_gadget[i], button);
- if (id != GADGET_ID_NONE)
- ClickOnGadget(level_editor_gadget[id], button);
- else if (letter == '1' || letter == '?')
- ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_LEFT], button);
- else if (letter == '2')
- ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_MIDDLE], button);
- else if (letter == '3')
- ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_RIGHT], button);
- else if (letter == '.')
- ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS], button);
- else if (letter == 'U')
- ClickOnGadget(level_editor_gadget[GADGET_ID_UNDO], 3);
- else if (letter == '-' || key == KSYM_KP_Subtract)
- ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 3);
- else if (letter == '0' || key == KSYM_KP_0)
- ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 2);
- else if (letter == '+' || key == KSYM_KP_Add ||
- letter == '=') // ("Shift-=" is "+" on US keyboards)
- ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 1);
- else if (key == KSYM_Return ||
- key == KSYM_space ||
- key == setup.shortcut.toggle_pause)
- ClickOnGadget(level_editor_gadget[GADGET_ID_TEST], button);
- else
- for (i = 0; i < ED_NUM_CTRL_BUTTONS; i++)
- if (letter && letter == controlbutton_info[i].shortcut)
- if (!anyTextGadgetActive())
- ClickOnGadget(level_editor_gadget[i], button);
+ if (draw_with_brush)
+ {
+ if (letter == 'x')
+ FlipBrushX();
+ else if (letter == 'y')
+ FlipBrushY();
+ else if (letter == 'z')
+ RotateBrush();
}
}
-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;
int y = editor.settings.element_graphic.y + element_border;
- static unsigned int action_delay = 0;
- unsigned int action_delay_value = GameFrameDelay;
+ static DelayCounter action_delay = { 0 };
int i;
- if (edit_mode != ED_MODE_PROPERTIES)
- return;
+ action_delay.value = GameFrameDelay;
- if (!DelayReached(&action_delay, action_delay_value))
+ if (!DelayReached(&action_delay))
return;
for (i = 0; i < ED_NUM_SELECTBOX; i++)
FrameCounter++; // increase animation frame counter
}
+static void HandleLevelEditorIdle_Drawing(void)
+{
+ static boolean last_highlighted = FALSE;
+ static boolean last_highlighted_similar = FALSE;
+ boolean highlighted = (GetKeyModState() & KMOD_Alt);
+ boolean highlighted_similar = (GetKeyModState() & KMOD_Shift);
+
+ if (highlighted != last_highlighted ||
+ (highlighted && highlighted_similar != last_highlighted_similar))
+ {
+ DrawAreaElementHighlight(highlighted, highlighted_similar);
+
+ redraw_mask |= REDRAW_FIELD;
+ }
+
+ last_highlighted = highlighted;
+ last_highlighted_similar = highlighted_similar;
+}
+
+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);
void PrintEditorGadgetInfoText(struct GadgetInfo *gi)
{
char infotext[MAX_OUTPUT_LINESIZE + 1];
- char shortcut[MAX_OUTPUT_LINESIZE + 1];
int max_infotext_len = getMaxInfoTextLength();
if (gi == NULL || strlen(gi->info_text) == 0)
if (key)
{
+ char shortcut[MAX_OUTPUT_LINESIZE + 1];
+
if (gi->custom_id == GADGET_ID_SINGLE_ITEMS)
sprintf(shortcut, " ('.' or '%c')", key);
else if (gi->custom_id == GADGET_ID_PICK_ELEMENT)
static void HandleDrawingAreaInfo(struct GadgetInfo *gi)
{
- static int start_lx, start_ly;
int id = gi->custom_id;
int type_id = gi->custom_type_id;
int sx = gi->event.x;
int actual_drawing_function = drawing_function;
int max_infotext_len = getMaxInfoTextLength();
char infotext[MAX_OUTPUT_LINESIZE + 1];
- char *text;
infotext[0] = '\0'; // start with empty info text
sy = ly - level_ypos;
}
- if (IN_ED_FIELD(sx,sy) && IN_LEV_FIELD(lx, ly))
+ if (IN_ED_FIELD(sx, sy) && IN_LEV_FIELD(lx, ly))
{
if (button_status) // if (gi->state == GD_BUTTON_PRESSED)
{
+ static int start_lx = 0;
+ static int start_ly = 0;
+ char *text;
+
if (gi->event.type == GD_EVENT_PRESSED)
{
start_lx = lx;
ABS(lx - start_lx) + 1, ABS(ly - start_ly) + 1);
}
else if (actual_drawing_function == GADGET_ID_PICK_ELEMENT)
- strncpy(infotext, getElementInfoText(Feld[lx][ly]), max_infotext_len);
+ strncpy(infotext, getElementInfoText(Tile[lx][ly]), max_infotext_len);
else
sprintf(infotext, "Level position: %d, %d", lx, ly);
}