From 37a06df577bbfd00f4b361f92cacb0d97036ba93 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Thu, 12 Jan 2006 02:49:16 +0100 Subject: [PATCH] rnd-20060112-1-src * added android (can clone elements) from EMC engine to R'n'D engine * added selectbox for initial player speed to player settings in editor * version 3.1.2 created that is basically version 3.1.1, but with a major bug fixed that prevented editing your own private levels * version 3.1.2 released * added magic ball (creates elements) from EMC engine to R'n'D engine * uploaded fixed pre-release version 3.2.0-6 binary and source code * fixed bug when using "CE can leave behind " * added new change condition "(after/when) creation of " * added new change condition "(after/when) digging " * fixed bug accessing invalid gadget that caused crashes under Windows * deactivated new possibility for multiple CE changes per frame * uploaded pre-release (test) version 3.2.0-6 binary and source code * added animation types "ce_value" and "ce_score" to graphicsinfo.conf * fixed bug with not keeping CE value for moving CEs with only action * changed CE action selectboxes in editor to be only reset when needed * added option "use artwork from element" for custom player artwork * added option "use explosion from element" for player explosions * added cascaded element lists in the level editor * added persistence for cascaded element lists by "editorcascade.conf" * added dynamic element list with all elements used in current level * added possibility for multiple CE changes per frame (experimental) * uploaded pre-release (test) version 3.2.0-5 binary and source code * changed "score for each 10 seconds/steps left" to "1 second/step" * added own score for collecting "extra time" instead of sharing it * added change events "switched by player" and "player switches " * added change events "snapped by player" and "player snaps " * added "set player artwork: " to CE action options * added change event "move of " * added "set player shield: off / normal / deadly" to CE action options * added new player option "use level start element" in level editor to set the correct focus at level start to elements from which the player is created later (this did not work before for cascaded CE changes resulting in creation of the player; it is now also possible to create the player from a yam yam which is smashed at level start) * added "set player speed: frozen (not moving)" to CE action options * added "move player: l/r/u/d/trigger/-trigger" to CE action options * added new player option "block snap field" (enabled by default) to make it possible to show a snapping animation like in Emerald Mine * added dynamic selectboxes to custom element action settings in editor * added "CE value" counter for custom elements (instead of "CE count") * added option to use the last "CE value" after custom element change * added option to use the "CE value" of other elements in CE actions * fixed odd behaviour when pressing time orb in levels w/o time limit * added checkbox "use time orb bug" for older levels that use this bug * added missing configuration settings for the following elements: - EL_TIMEGATE_SWITCH (time of open time gate) - EL_LIGHT_SWITCH_ACTIVE (time of light switched on) - EL_SHIELD_NORMAL (time of shield duration) - EL_SHIELD_DEADLY (time of shield duration) - EL_EXTRA_TIME (time added to level time) - EL_TIME_ORB_FULL (time added to level time) * added "wind direction" as a movement pattern for custom elements * added initial wind direction for balloon / custom elements to editor * added functionality for EL_BALLOON_SWITCH_NONE to R'n'D game engine * added parameters for "game of life" and "biomaze" elements to editor * added level file chunk "CONF" for generic level and element settings * uploaded pre-release (test) version 3.2.0-4 binary and source code * skip empty level sets (with "levels: 0"; may be artwork base sets) * added sound action ".page[1]" to ".page[32]" for each CE change page * added image config suffix ".clone_from" to copy whole image settings * fixed bug with invalid ("undefined") CE settings in old level files * fixed graphical bug with smashing elements falling faster than player * fixed major bug which prevented private levels from being edited * fixed bug with precedence of general and special font definitions * fixed graphical bug with player animation when player moves slowly * uploaded pre-release (test) version 3.2.0-3 binary and source code * fixed bug which prevented "global.num_toons: 0" from working * major code cleanup (removed all these annoying "#if 0" blocks) * added custom element actions for CE change page in level editor * fixed music initialization bug in init.c (thanks to David Binderman) * fixed mouse wheel "button" bug in editor (thanks to Tomi Belan) (this bug must probably be fixed at other places, too) * fixed buggy '#include "SDL.h"' statements in src/libgame/sdl.h (should be '#include ' instead) * fixed bug which prevented "walkable from no direction" from working (due to compatibility code overwriting this setting after loading) --- ChangeLog | 144 + src/Makefile | 2 +- src/cartoons.c | 13 +- src/conf_e2g.c | 124 +- src/conf_fnt.c | 4 - src/conf_gfx.c | 132 +- src/conf_gfx.h | 2460 +++++++------- src/conftime.h | 2 +- src/editor.c | 2858 +++++++++------- src/events.c | 74 +- src/files.c | 1676 ++++++---- src/files.h | 3 + src/game.c | 6820 +++++++++++++++------------------------ src/game.h | 14 +- src/game_em/cave.c | 2 + src/game_em/convert.c | 234 +- src/game_em/main_em.h | 1 + src/game_em/synchro_2.c | 4 + src/init.c | 1072 +++--- src/init.h | 7 - src/libgame/gadgets.c | 82 +- src/libgame/image.c | 21 +- src/libgame/misc.c | 480 +-- src/libgame/misc.h | 17 +- src/libgame/pcx.c | 75 - src/libgame/sdl.c | 21 - src/libgame/sdl.h | 10 +- src/libgame/setup.c | 208 +- src/libgame/sound.c | 136 +- src/libgame/system.c | 71 +- src/libgame/system.h | 38 +- src/libgame/toons.c | 23 +- src/libgame/toons.h | 23 +- src/libgame/x11.c | 21 - src/main.c | 276 +- src/main.h | 933 ++++-- src/netserv.c | 14 - src/network.c | 8 +- src/screens.c | 357 +- src/screens.h | 2 + src/tape.c | 319 +- src/tape.h | 2 +- src/tools.c | 442 +-- src/tools.h | 7 + 44 files changed, 9018 insertions(+), 10214 deletions(-) diff --git a/ChangeLog b/ChangeLog index b3ae71e4..75d50dff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,147 @@ +XXXX-XX-XX + * added android (can clone elements) from EMC engine to R'n'D engine + + +2006-01-11 + * added selectbox for initial player speed to player settings in editor + +2006-01-11 + * version 3.1.2 created that is basically version 3.1.1, but with a + major bug fixed that prevented editing your own private levels + * version 3.1.2 released + +2006-01-09 + * added magic ball (creates elements) from EMC engine to R'n'D engine + +2006-01-07 + * uploaded fixed pre-release version 3.2.0-6 binary and source code + +2006-01-07 + * fixed bug when using "CE can leave behind " + * added new change condition "(after/when) creation of " + * added new change condition "(after/when) digging " + * fixed bug accessing invalid gadget that caused crashes under Windows + * deactivated new possibility for multiple CE changes per frame + +2006-01-04 + * uploaded pre-release (test) version 3.2.0-6 binary and source code + +2006-01-02 + * added animation types "ce_value" and "ce_score" to graphicsinfo.conf + * fixed bug with not keeping CE value for moving CEs with only action + * changed CE action selectboxes in editor to be only reset when needed + +2006-01-01 + * added option "use artwork from element" for custom player artwork + * added option "use explosion from element" for player explosions + +2005-12-30 + * added cascaded element lists in the level editor + * added persistence for cascaded element lists by "editorcascade.conf" + * added dynamic element list with all elements used in current level + * added possibility for multiple CE changes per frame (experimental) + +2005-12-28 + * uploaded pre-release (test) version 3.2.0-5 binary and source code + +2005-12-27 + * changed "score for each 10 seconds/steps left" to "1 second/step" + * added own score for collecting "extra time" instead of sharing it + * added change events "switched by player" and "player switches " + * added change events "snapped by player" and "player snaps " + * added "set player artwork: " to CE action options + * added change event "move of " + +2005-12-22 + * added "set player shield: off / normal / deadly" to CE action options + * added new player option "use level start element" in level editor + to set the correct focus at level start to elements from which the + player is created later (this did not work before for cascaded CE + changes resulting in creation of the player; it is now also possible + to create the player from a yam yam which is smashed at level start) + +2005-12-20 + * added "set player speed: frozen (not moving)" to CE action options + * added "move player: l/r/u/d/trigger/-trigger" to CE action options + +2005-12-17 + * added new player option "block snap field" (enabled by default) to + make it possible to show a snapping animation like in Emerald Mine + +2005-12-16 + * added dynamic selectboxes to custom element action settings in editor + * added "CE value" counter for custom elements (instead of "CE count") + * added option to use the last "CE value" after custom element change + * added option to use the "CE value" of other elements in CE actions + * fixed odd behaviour when pressing time orb in levels w/o time limit + * added checkbox "use time orb bug" for older levels that use this bug + +2005-12-15 + * added missing configuration settings for the following elements: + - EL_TIMEGATE_SWITCH (time of open time gate) + - EL_LIGHT_SWITCH_ACTIVE (time of light switched on) + - EL_SHIELD_NORMAL (time of shield duration) + - EL_SHIELD_DEADLY (time of shield duration) + - EL_EXTRA_TIME (time added to level time) + - EL_TIME_ORB_FULL (time added to level time) + +2005-12-14 + * added "wind direction" as a movement pattern for custom elements + * added initial wind direction for balloon / custom elements to editor + * added functionality for EL_BALLOON_SWITCH_NONE to R'n'D game engine + +2005-12-13 + * added parameters for "game of life" and "biomaze" elements to editor + +2005-12-12 + * added level file chunk "CONF" for generic level and element settings + +2005-12-11 + * uploaded pre-release (test) version 3.2.0-4 binary and source code + +2005-12-11 + * skip empty level sets (with "levels: 0"; may be artwork base sets) + * added sound action ".page[1]" to ".page[32]" for each CE change page + +2005-12-10 + * added image config suffix ".clone_from" to copy whole image settings + * fixed bug with invalid ("undefined") CE settings in old level files + +2005-12-05 + * fixed graphical bug with smashing elements falling faster than player + +2005-12-03 + * fixed major bug which prevented private levels from being edited + * fixed bug with precedence of general and special font definitions + +2005-12-02 + * fixed graphical bug with player animation when player moves slowly + +2005-11-29 + * uploaded pre-release (test) version 3.2.0-3 binary and source code + +2005-11-28 + * fixed bug which prevented "global.num_toons: 0" from working + +2005-11-27 + * major code cleanup (removed all these annoying "#if 0" blocks) + +2005-11-26 + * added custom element actions for CE change page in level editor + +2005-11-19 + * fixed music initialization bug in init.c (thanks to David Binderman) + * fixed mouse wheel "button" bug in editor (thanks to Tomi Belan) + (this bug must probably be fixed at other places, too) + +2005-10-16 + * fixed buggy '#include "SDL.h"' statements in src/libgame/sdl.h + (should be '#include ' instead) + +2005-08-20 + * fixed bug which prevented "walkable from no direction" from working + (due to compatibility code overwriting this setting after loading) + 2005-08-15 * fixed bug on Mac OS X (use of reserved name "Random") in EM engine diff --git a/src/Makefile b/src/Makefile index 973fdead..4cd0223f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -125,7 +125,7 @@ CONFIG_GAME_DIR = $(CONFIG_RO_GAME_DIR) $(CONFIG_RW_GAME_DIR) CONFIG = $(CONFIG_GAME_DIR) $(CONFIG_SCORE_ENTRIES) $(JOYSTICK) -# DEBUG = -DDEBUG -g +DEBUG = -DDEBUG -g # PROFILING = $(PROFILING_FLAGS) # OPTIONS = $(DEBUG) -Wall # only for debugging purposes diff --git a/src/cartoons.c b/src/cartoons.c index fc465fac..9b6626b6 100644 --- a/src/cartoons.c +++ b/src/cartoons.c @@ -59,16 +59,7 @@ static void PrepareBackbuffer() boolean ToonNeedsRedraw() { -#if 1 return TRUE; -#else - return (game_status == GAME_MODE_INFO || - game_status == GAME_MODE_LEVELS || - game_status == GAME_MODE_SETUP || - (game_status == GAME_MODE_MAIN && - ((redraw_mask & REDRAW_MICROLEVEL) || - (redraw_mask & REDRAW_MICROLABEL)))); -#endif } void InitToons() @@ -76,10 +67,10 @@ void InitToons() int num_toons = MAX_NUM_TOONS; int i; - if (global.num_toons > 0 && global.num_toons < MAX_NUM_TOONS) + if (global.num_toons >= 0 && global.num_toons < MAX_NUM_TOONS) num_toons = global.num_toons; - for (i=0; i < num_toons; i++) + for (i = 0; i < num_toons; i++) { int graphic = IMG_TOON_1 + i; struct FileInfo *image = getImageListEntryFromImageID(graphic); diff --git a/src/conf_e2g.c b/src/conf_e2g.c index 491ed8f8..25057950 100644 --- a/src/conf_e2g.c +++ b/src/conf_e2g.c @@ -1057,18 +1057,50 @@ element_to_graphic[] = EL_EM_GATE_1_GRAY, -1, -1, FALSE, IMG_EM_GATE_1_GRAY }, + { + EL_EM_GATE_1_GRAY_ACTIVE, -1, -1, FALSE, + IMG_EM_GATE_1_GRAY_ACTIVE + }, + { + EL_EM_GATE_1_GRAY, ACTION_ACTIVE, -1, FALSE, + IMG_EM_GATE_1_GRAY_ACTIVE + }, { EL_EM_GATE_2_GRAY, -1, -1, FALSE, IMG_EM_GATE_2_GRAY }, + { + EL_EM_GATE_2_GRAY_ACTIVE, -1, -1, FALSE, + IMG_EM_GATE_2_GRAY_ACTIVE + }, + { + EL_EM_GATE_2_GRAY, ACTION_ACTIVE, -1, FALSE, + IMG_EM_GATE_2_GRAY_ACTIVE + }, { EL_EM_GATE_3_GRAY, -1, -1, FALSE, IMG_EM_GATE_3_GRAY }, + { + EL_EM_GATE_3_GRAY_ACTIVE, -1, -1, FALSE, + IMG_EM_GATE_3_GRAY_ACTIVE + }, + { + EL_EM_GATE_3_GRAY, ACTION_ACTIVE, -1, FALSE, + IMG_EM_GATE_3_GRAY_ACTIVE + }, { EL_EM_GATE_4_GRAY, -1, -1, FALSE, IMG_EM_GATE_4_GRAY }, + { + EL_EM_GATE_4_GRAY_ACTIVE, -1, -1, FALSE, + IMG_EM_GATE_4_GRAY_ACTIVE + }, + { + EL_EM_GATE_4_GRAY, ACTION_ACTIVE, -1, FALSE, + IMG_EM_GATE_4_GRAY_ACTIVE + }, { EL_EXIT_CLOSED, -1, -1, FALSE, IMG_EXIT_CLOSED @@ -1701,18 +1733,50 @@ element_to_graphic[] = EL_GATE_1_GRAY, -1, -1, FALSE, IMG_GATE_1_GRAY }, + { + EL_GATE_1_GRAY_ACTIVE, -1, -1, FALSE, + IMG_GATE_1_GRAY_ACTIVE + }, + { + EL_GATE_1_GRAY, ACTION_ACTIVE, -1, FALSE, + IMG_GATE_1_GRAY_ACTIVE + }, { EL_GATE_2_GRAY, -1, -1, FALSE, IMG_GATE_2_GRAY }, + { + EL_GATE_2_GRAY_ACTIVE, -1, -1, FALSE, + IMG_GATE_2_GRAY_ACTIVE + }, + { + EL_GATE_2_GRAY, ACTION_ACTIVE, -1, FALSE, + IMG_GATE_2_GRAY_ACTIVE + }, { EL_GATE_3_GRAY, -1, -1, FALSE, IMG_GATE_3_GRAY }, + { + EL_GATE_3_GRAY_ACTIVE, -1, -1, FALSE, + IMG_GATE_3_GRAY_ACTIVE + }, + { + EL_GATE_3_GRAY, ACTION_ACTIVE, -1, FALSE, + IMG_GATE_3_GRAY_ACTIVE + }, { EL_GATE_4_GRAY, -1, -1, FALSE, IMG_GATE_4_GRAY }, + { + EL_GATE_4_GRAY_ACTIVE, -1, -1, FALSE, + IMG_GATE_4_GRAY_ACTIVE + }, + { + EL_GATE_4_GRAY, ACTION_ACTIVE, -1, FALSE, + IMG_GATE_4_GRAY_ACTIVE + }, { EL_GAME_OF_LIFE, -1, -1, FALSE, IMG_GAME_OF_LIFE @@ -2693,34 +2757,66 @@ element_to_graphic[] = EL_EMC_GATE_5, -1, -1, FALSE, IMG_EMC_GATE_5 }, + { + EL_EMC_GATE_6, -1, -1, FALSE, + IMG_EMC_GATE_6 + }, + { + EL_EMC_GATE_7, -1, -1, FALSE, + IMG_EMC_GATE_7 + }, + { + EL_EMC_GATE_8, -1, -1, FALSE, + IMG_EMC_GATE_8 + }, { EL_EMC_GATE_5_GRAY, -1, -1, FALSE, IMG_EMC_GATE_5_GRAY }, { - EL_EMC_GATE_6, -1, -1, FALSE, - IMG_EMC_GATE_6 + EL_EMC_GATE_5_GRAY_ACTIVE, -1, -1, FALSE, + IMG_EMC_GATE_5_GRAY_ACTIVE + }, + { + EL_EMC_GATE_5_GRAY, ACTION_ACTIVE, -1, FALSE, + IMG_EMC_GATE_5_GRAY_ACTIVE }, { EL_EMC_GATE_6_GRAY, -1, -1, FALSE, IMG_EMC_GATE_6_GRAY }, { - EL_EMC_GATE_7, -1, -1, FALSE, - IMG_EMC_GATE_7 + EL_EMC_GATE_6_GRAY_ACTIVE, -1, -1, FALSE, + IMG_EMC_GATE_6_GRAY_ACTIVE + }, + { + EL_EMC_GATE_6_GRAY, ACTION_ACTIVE, -1, FALSE, + IMG_EMC_GATE_6_GRAY_ACTIVE }, { EL_EMC_GATE_7_GRAY, -1, -1, FALSE, IMG_EMC_GATE_7_GRAY }, { - EL_EMC_GATE_8, -1, -1, FALSE, - IMG_EMC_GATE_8 + EL_EMC_GATE_7_GRAY_ACTIVE, -1, -1, FALSE, + IMG_EMC_GATE_7_GRAY_ACTIVE + }, + { + EL_EMC_GATE_7_GRAY, ACTION_ACTIVE, -1, FALSE, + IMG_EMC_GATE_7_GRAY_ACTIVE }, { EL_EMC_GATE_8_GRAY, -1, -1, FALSE, IMG_EMC_GATE_8_GRAY }, + { + EL_EMC_GATE_8_GRAY_ACTIVE, -1, -1, FALSE, + IMG_EMC_GATE_8_GRAY_ACTIVE + }, + { + EL_EMC_GATE_8_GRAY, ACTION_ACTIVE, -1, FALSE, + IMG_EMC_GATE_8_GRAY_ACTIVE + }, { EL_EMC_ANDROID, -1, -1, FALSE, IMG_EMC_ANDROID @@ -2777,6 +2873,10 @@ element_to_graphic[] = EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1, FALSE, IMG_EMC_MAGIC_BALL_ACTIVE }, + { + EL_EMC_MAGIC_BALL, ACTION_DROPPING, -1, FALSE, + IMG_EMC_MAGIC_BALL_DROPPING + }, { EL_EMC_MAGIC_BALL_SWITCH, -1, -1, FALSE, IMG_EMC_MAGIC_BALL_SWITCH @@ -2869,6 +2969,10 @@ element_to_graphic[] = EL_EMC_FAKE_GRASS, -1, -1, TRUE, IMG_EMC_FAKE_GRASS_CRUMBLED }, + { + EL_EMC_FAKE_GRASS_ACTIVE, -1, -1, FALSE, + IMG_EMC_FAKE_GRASS_ACTIVE + }, { EL_EMC_FAKE_GRASS, ACTION_ACTIVE, -1, FALSE, IMG_EMC_FAKE_GRASS_ACTIVE @@ -2877,6 +2981,10 @@ element_to_graphic[] = EL_EMC_FAKE_GRASS, ACTION_ACTIVE, -1, TRUE, IMG_EMC_FAKE_GRASS_ACTIVE_CRUMBLED }, + { + EL_EMC_FAKE_GRASS_ACTIVE, -1, -1, TRUE, + IMG_EMC_FAKE_GRASS_ACTIVE_CRUMBLED + }, { EL_EMC_FAKE_ACID, -1, -1, FALSE, IMG_EMC_FAKE_ACID @@ -2885,6 +2993,10 @@ element_to_graphic[] = EL_EMC_DRIPPER, -1, -1, FALSE, IMG_EMC_DRIPPER }, + { + EL_EMC_DRIPPER_ACTIVE, -1, -1, FALSE, + IMG_EMC_DRIPPER_ACTIVE + }, { EL_EMC_DRIPPER, ACTION_ACTIVE, -1, FALSE, IMG_EMC_DRIPPER_ACTIVE diff --git a/src/conf_fnt.c b/src/conf_fnt.c index b00d432f..404adc6f 100644 --- a/src/conf_fnt.c +++ b/src/conf_fnt.c @@ -47,10 +47,6 @@ font_to_graphic[] = FONT_TITLE_1, -1, IMG_FONT_TITLE_1 }, - { - FONT_TITLE_1, GFX_SPECIAL_ARG_LEVELS, - IMG_FONT_TITLE_1_LEVELS - }, { FONT_TITLE_2, -1, IMG_FONT_TITLE_2 diff --git a/src/conf_gfx.c b/src/conf_gfx.c index 9aa3e6bb..d288f54f 100644 --- a/src/conf_gfx.c +++ b/src/conf_gfx.c @@ -59,6 +59,7 @@ struct ConfigTypeInfo image_config_suffix[] = { ".post_delay_random", ARG_UNDEFINED, TYPE_INTEGER }, { ".name", ARG_UNDEFINED, TYPE_STRING }, { ".scale_up_factor", ARG_UNDEFINED, TYPE_INTEGER }, + { ".clone_from", ARG_UNDEFINED, TYPE_TOKEN }, { NULL, NULL, 0 } }; @@ -1368,6 +1369,10 @@ struct ConfigInfo image_config[] = { "em_gate_1_gray.EDITOR", "RocksSP.pcx" }, { "em_gate_1_gray.EDITOR.xpos", "12" }, { "em_gate_1_gray.EDITOR.ypos", "11" }, + { "em_gate_1_gray.active", "RocksSP.pcx" }, + { "em_gate_1_gray.active.xpos", "0" }, + { "em_gate_1_gray.active.ypos", "7" }, + { "em_gate_1_gray.active.frames", "1" }, { "em_gate_2_gray", "RocksSP.pcx" }, { "em_gate_2_gray.xpos", "5" }, { "em_gate_2_gray.ypos", "7" }, @@ -1375,6 +1380,10 @@ struct ConfigInfo image_config[] = { "em_gate_2_gray.EDITOR", "RocksSP.pcx" }, { "em_gate_2_gray.EDITOR.xpos", "13" }, { "em_gate_2_gray.EDITOR.ypos", "11" }, + { "em_gate_2_gray.active", "RocksSP.pcx" }, + { "em_gate_2_gray.active.xpos", "1" }, + { "em_gate_2_gray.active.ypos", "7" }, + { "em_gate_2_gray.active.frames", "1" }, { "em_gate_3_gray", "RocksSP.pcx" }, { "em_gate_3_gray.xpos", "6" }, { "em_gate_3_gray.ypos", "7" }, @@ -1382,6 +1391,10 @@ struct ConfigInfo image_config[] = { "em_gate_3_gray.EDITOR", "RocksSP.pcx" }, { "em_gate_3_gray.EDITOR.xpos", "14" }, { "em_gate_3_gray.EDITOR.ypos", "11" }, + { "em_gate_3_gray.active", "RocksSP.pcx" }, + { "em_gate_3_gray.active.xpos", "2" }, + { "em_gate_3_gray.active.ypos", "7" }, + { "em_gate_3_gray.active.frames", "1" }, { "em_gate_4_gray", "RocksSP.pcx" }, { "em_gate_4_gray.xpos", "7" }, { "em_gate_4_gray.ypos", "7" }, @@ -1389,6 +1402,10 @@ struct ConfigInfo image_config[] = { "em_gate_4_gray.EDITOR", "RocksSP.pcx" }, { "em_gate_4_gray.EDITOR.xpos", "15" }, { "em_gate_4_gray.EDITOR.ypos", "11" }, + { "em_gate_4_gray.active", "RocksSP.pcx" }, + { "em_gate_4_gray.active.xpos", "3" }, + { "em_gate_4_gray.active.ypos", "7" }, + { "em_gate_4_gray.active.frames", "1" }, { "exit_closed", "RocksElements.pcx" }, { "exit_closed.xpos", "0" }, @@ -2076,6 +2093,10 @@ struct ConfigInfo image_config[] = { "gate_1_gray.EDITOR", "RocksElements.pcx" }, { "gate_1_gray.EDITOR.xpos", "8" }, { "gate_1_gray.EDITOR.ypos", "14" }, + { "gate_1_gray.active", "RocksElements.pcx" }, + { "gate_1_gray.active.xpos", "4" }, + { "gate_1_gray.active.ypos", "2" }, + { "gate_1_gray.active.frames", "1" }, { "gate_2_gray", "RocksElements.pcx" }, { "gate_2_gray.xpos", "9" }, { "gate_2_gray.ypos", "2" }, @@ -2083,6 +2104,10 @@ struct ConfigInfo image_config[] = { "gate_2_gray.EDITOR", "RocksElements.pcx" }, { "gate_2_gray.EDITOR.xpos", "9" }, { "gate_2_gray.EDITOR.ypos", "14" }, + { "gate_2_gray.active", "RocksElements.pcx" }, + { "gate_2_gray.active.xpos", "5" }, + { "gate_2_gray.active.ypos", "2" }, + { "gate_2_gray.active.frames", "1" }, { "gate_3_gray", "RocksElements.pcx" }, { "gate_3_gray.xpos", "10" }, { "gate_3_gray.ypos", "2" }, @@ -2090,6 +2115,10 @@ struct ConfigInfo image_config[] = { "gate_3_gray.EDITOR", "RocksElements.pcx" }, { "gate_3_gray.EDITOR.xpos", "10" }, { "gate_3_gray.EDITOR.ypos", "14" }, + { "gate_3_gray.active", "RocksElements.pcx" }, + { "gate_3_gray.active.xpos", "6" }, + { "gate_3_gray.active.ypos", "2" }, + { "gate_3_gray.active.frames", "1" }, { "gate_4_gray", "RocksElements.pcx" }, { "gate_4_gray.xpos", "11" }, { "gate_4_gray.ypos", "2" }, @@ -2097,6 +2126,10 @@ struct ConfigInfo image_config[] = { "gate_4_gray.EDITOR", "RocksElements.pcx" }, { "gate_4_gray.EDITOR.xpos", "11" }, { "gate_4_gray.EDITOR.ypos", "14" }, + { "gate_4_gray.active", "RocksElements.pcx" }, + { "gate_4_gray.active.xpos", "7" }, + { "gate_4_gray.active.ypos", "2" }, + { "gate_4_gray.active.frames", "1" }, { "game_of_life", "RocksElements.pcx" }, { "game_of_life.xpos", "8" }, @@ -3356,6 +3389,18 @@ struct ConfigInfo image_config[] = { "emc_gate_5.xpos", "0" }, { "emc_gate_5.ypos", "6" }, { "emc_gate_5.frames", "1" }, + { "emc_gate_6", "RocksEMC.pcx" }, + { "emc_gate_6.xpos", "1" }, + { "emc_gate_6.ypos", "6" }, + { "emc_gate_6.frames", "1" }, + { "emc_gate_7", "RocksEMC.pcx" }, + { "emc_gate_7.xpos", "2" }, + { "emc_gate_7.ypos", "6" }, + { "emc_gate_7.frames", "1" }, + { "emc_gate_8", "RocksEMC.pcx" }, + { "emc_gate_8.xpos", "3" }, + { "emc_gate_8.ypos", "6" }, + { "emc_gate_8.frames", "1" }, { "emc_gate_5_gray", "RocksEMC.pcx" }, { "emc_gate_5_gray.xpos", "4" }, { "emc_gate_5_gray.ypos", "7" }, @@ -3363,10 +3408,10 @@ struct ConfigInfo image_config[] = { "emc_gate_5_gray.EDITOR", "RocksEMC.pcx" }, { "emc_gate_5_gray.EDITOR.xpos", "0" }, { "emc_gate_5_gray.EDITOR.ypos", "7" }, - { "emc_gate_6", "RocksEMC.pcx" }, - { "emc_gate_6.xpos", "1" }, - { "emc_gate_6.ypos", "6" }, - { "emc_gate_6.frames", "1" }, + { "emc_gate_5_gray.active", "RocksEMC.pcx" }, + { "emc_gate_5_gray.active.xpos", "0" }, + { "emc_gate_5_gray.active.ypos", "6" }, + { "emc_gate_5_gray.active.frames", "1" }, { "emc_gate_6_gray", "RocksEMC.pcx" }, { "emc_gate_6_gray.xpos", "4" }, { "emc_gate_6_gray.ypos", "7" }, @@ -3374,10 +3419,10 @@ struct ConfigInfo image_config[] = { "emc_gate_6_gray.EDITOR", "RocksEMC.pcx" }, { "emc_gate_6_gray.EDITOR.xpos", "1" }, { "emc_gate_6_gray.EDITOR.ypos", "7" }, - { "emc_gate_7", "RocksEMC.pcx" }, - { "emc_gate_7.xpos", "2" }, - { "emc_gate_7.ypos", "6" }, - { "emc_gate_7.frames", "1" }, + { "emc_gate_6_gray.active", "RocksEMC.pcx" }, + { "emc_gate_6_gray.active.xpos", "1" }, + { "emc_gate_6_gray.active.ypos", "6" }, + { "emc_gate_6_gray.active.frames", "1" }, { "emc_gate_7_gray", "RocksEMC.pcx" }, { "emc_gate_7_gray.xpos", "4" }, { "emc_gate_7_gray.ypos", "7" }, @@ -3385,10 +3430,10 @@ struct ConfigInfo image_config[] = { "emc_gate_7_gray.EDITOR", "RocksEMC.pcx" }, { "emc_gate_7_gray.EDITOR.xpos", "2" }, { "emc_gate_7_gray.EDITOR.ypos", "7" }, - { "emc_gate_8", "RocksEMC.pcx" }, - { "emc_gate_8.xpos", "3" }, - { "emc_gate_8.ypos", "6" }, - { "emc_gate_8.frames", "1" }, + { "emc_gate_7_gray.active", "RocksEMC.pcx" }, + { "emc_gate_7_gray.active.xpos", "2" }, + { "emc_gate_7_gray.active.ypos", "6" }, + { "emc_gate_7_gray.active.frames", "1" }, { "emc_gate_8_gray", "RocksEMC.pcx" }, { "emc_gate_8_gray.xpos", "4" }, { "emc_gate_8_gray.ypos", "7" }, @@ -3396,11 +3441,16 @@ struct ConfigInfo image_config[] = { "emc_gate_8_gray.EDITOR", "RocksEMC.pcx" }, { "emc_gate_8_gray.EDITOR.xpos", "3" }, { "emc_gate_8_gray.EDITOR.ypos", "7" }, + { "emc_gate_8_gray.active", "RocksEMC.pcx" }, + { "emc_gate_8_gray.active.xpos", "3" }, + { "emc_gate_8_gray.active.ypos", "6" }, + { "emc_gate_8_gray.active.frames", "1" }, { "emc_android", "RocksEMC.pcx" }, { "emc_android.xpos", "0" }, { "emc_android.ypos", "8" }, { "emc_android.frames", "8" }, + { "emc_android.delay", "2" }, { "emc_grass", "RocksEMC.pcx" }, { "emc_grass.xpos", "0" }, @@ -3463,18 +3513,21 @@ struct ConfigInfo image_config[] = { "emc_magic_ball.xpos", "0" }, { "emc_magic_ball.ypos", "9" }, { "emc_magic_ball.frames", "1" }, - { "emc_magic_ball.active", "RocksEMC.pcx" }, { "emc_magic_ball.active.xpos", "0" }, { "emc_magic_ball.active.ypos", "9" }, { "emc_magic_ball.active.frames", "16" }, { "emc_magic_ball.active.frames_per_line", "8" }, + { "emc_magic_ball.dropping", "RocksElements.pcx" }, + { "emc_magic_ball.dropping.xpos", "0" }, + { "emc_magic_ball.dropping.ypos", "4" }, + { "emc_magic_ball.dropping.frames", "8" }, + { "emc_magic_ball.dropping.anim_mode", "linear" }, { "emc_magic_ball_switch", "RocksEMC.pcx" }, { "emc_magic_ball_switch.xpos", "8" }, { "emc_magic_ball_switch.ypos", "10" }, { "emc_magic_ball_switch.frames", "1" }, - { "emc_magic_ball_switch.active", "RocksEMC.pcx" }, { "emc_magic_ball_switch.active.xpos", "8" }, { "emc_magic_ball_switch.active.ypos", "9" }, @@ -3831,35 +3884,44 @@ struct ConfigInfo image_config[] = { "menu.button_left.xpos", "8" }, { "menu.button_left.ypos", "8" }, { "menu.button_left.frames", "1" }, - { "menu.button_right", "RocksDC.pcx" }, - { "menu.button_right.xpos", "9" }, - { "menu.button_right.ypos", "8" }, - { "menu.button_right.frames", "1" }, - { "menu.button_up", "RocksDC.pcx" }, - { "menu.button_up.xpos", "10" }, - { "menu.button_up.ypos", "8" }, - { "menu.button_up.frames", "1" }, - { "menu.button_down", "RocksDC.pcx" }, - { "menu.button_down.xpos", "11" }, - { "menu.button_down.ypos", "8" }, - { "menu.button_down.frames", "1" }, { "menu.button_left.active", "RocksDC.pcx" }, { "menu.button_left.active.xpos", "8" }, { "menu.button_left.active.ypos", "9" }, { "menu.button_left.active.frames", "1" }, + { "menu.button_right", "RocksDC.pcx" }, + { "menu.button_right.xpos", "9" }, + { "menu.button_right.ypos", "8" }, + { "menu.button_right.frames", "1" }, { "menu.button_right.active", "RocksDC.pcx" }, { "menu.button_right.active.xpos", "9" }, { "menu.button_right.active.ypos", "9" }, { "menu.button_right.active.frames", "1" }, + { "menu.button_up", "RocksDC.pcx" }, + { "menu.button_up.xpos", "10" }, + { "menu.button_up.ypos", "8" }, + { "menu.button_up.frames", "1" }, { "menu.button_up.active", "RocksDC.pcx" }, { "menu.button_up.active.xpos", "10" }, { "menu.button_up.active.ypos", "9" }, { "menu.button_up.active.frames", "1" }, + { "menu.button_down", "RocksDC.pcx" }, + { "menu.button_down.xpos", "11" }, + { "menu.button_down.ypos", "8" }, + { "menu.button_down.frames", "1" }, { "menu.button_down.active", "RocksDC.pcx" }, { "menu.button_down.active.xpos", "11" }, { "menu.button_down.active.ypos", "9" }, { "menu.button_down.active.frames", "1" }, + { "menu.button_enter_menu", UNDEFINED_FILENAME }, + { "menu.button_enter_menu.clone_from", "menu.button_right" }, + { "menu.button_enter_menu.active", UNDEFINED_FILENAME }, + { "menu.button_enter_menu.active.clone_from", "menu.button_right.active" }, + { "menu.button_leave_menu", UNDEFINED_FILENAME }, + { "menu.button_leave_menu.clone_from", "menu.button_left" }, + { "menu.button_leave_menu.active", UNDEFINED_FILENAME }, + { "menu.button_leave_menu.active.clone_from", "menu.button_left.active" }, + { "menu.scrollbar", "RocksDC.pcx" }, { "menu.scrollbar.xpos", "8" }, { "menu.scrollbar.ypos", "10" }, @@ -3895,11 +3957,6 @@ struct ConfigInfo image_config[] = { "font.title_1.y", "480" }, { "font.title_1.width", "32" }, { "font.title_1.height", "32" }, - { "font.title_1.LEVELS", "RocksFontBig.pcx" }, - { "font.title_1.LEVELS.x", "0" }, - { "font.title_1.LEVELS.y", "320" }, - { "font.title_1.LEVELS.width", "32" }, - { "font.title_1.LEVELS.height", "32" }, { "font.title_2", "RocksFontSmall.pcx" }, { "font.title_2.x", "0" }, { "font.title_2.y", "0" }, @@ -4125,6 +4182,15 @@ struct ConfigInfo image_config[] = { "editor.element_border_input.xpos", "0" }, { "editor.element_border_input.ypos", "0" }, + { "editor.cascade_list", "RocksDoor.pcx" }, + { "editor.cascade_list.x", "708" }, + { "editor.cascade_list.y", "80" }, + { "editor.cascade_list.frames", "1" }, + { "editor.cascade_list.active", "RocksDoor.pcx" }, + { "editor.cascade_list.active.x", "740" }, + { "editor.cascade_list.active.y", "80" }, + { "editor.cascade_list.active.frames", "1" }, + { "background.envelope_1", "RocksScreen.pcx" }, { "background.envelope_1.x", "0" }, { "background.envelope_1.y", "0" }, @@ -4161,6 +4227,10 @@ struct ConfigInfo image_config[] = { "background.EDITOR", UNDEFINED_FILENAME }, { "background.INFO", UNDEFINED_FILENAME }, { "background.INFO[ELEMENTS]", UNDEFINED_FILENAME }, + { "background.INFO[MUSIC]", UNDEFINED_FILENAME }, + { "background.INFO[CREDITS]", UNDEFINED_FILENAME }, + { "background.INFO[PROGRAM]", UNDEFINED_FILENAME }, + { "background.INFO[LEVELSET]", UNDEFINED_FILENAME }, { "background.SETUP", UNDEFINED_FILENAME }, { "background.DOOR", UNDEFINED_FILENAME }, diff --git a/src/conf_gfx.h b/src/conf_gfx.h index 2d2cc45f..02a7bb63 100644 --- a/src/conf_gfx.h +++ b/src/conf_gfx.h @@ -279,1225 +279,1247 @@ #define IMG_EM_GATE_4 258 #define IMG_EM_GATE_1_GRAY 259 #define IMG_EM_GATE_1_GRAY_EDITOR 260 -#define IMG_EM_GATE_2_GRAY 261 -#define IMG_EM_GATE_2_GRAY_EDITOR 262 -#define IMG_EM_GATE_3_GRAY 263 -#define IMG_EM_GATE_3_GRAY_EDITOR 264 -#define IMG_EM_GATE_4_GRAY 265 -#define IMG_EM_GATE_4_GRAY_EDITOR 266 -#define IMG_EXIT_CLOSED 267 -#define IMG_EXIT_OPENING 268 -#define IMG_EXIT_OPEN 269 -#define IMG_EXIT_CLOSING 270 -#define IMG_BALLOON 271 -#define IMG_BALLOON_MOVING 272 -#define IMG_BALLOON_PUSHING 273 -#define IMG_BALLOON_SWITCH_LEFT 274 -#define IMG_BALLOON_SWITCH_RIGHT 275 -#define IMG_BALLOON_SWITCH_UP 276 -#define IMG_BALLOON_SWITCH_DOWN 277 -#define IMG_BALLOON_SWITCH_ANY 278 -#define IMG_BALLOON_SWITCH_NONE 279 -#define IMG_SPRING 280 -#define IMG_EMC_STEELWALL_1 281 -#define IMG_EMC_STEELWALL_2 282 -#define IMG_EMC_STEELWALL_3 283 -#define IMG_EMC_STEELWALL_4 284 -#define IMG_EMC_WALL_1 285 -#define IMG_EMC_WALL_2 286 -#define IMG_EMC_WALL_3 287 -#define IMG_EMC_WALL_4 288 -#define IMG_EMC_WALL_5 289 -#define IMG_EMC_WALL_6 290 -#define IMG_EMC_WALL_7 291 -#define IMG_EMC_WALL_8 292 -#define IMG_INVISIBLE_STEELWALL 293 -#define IMG_INVISIBLE_STEELWALL_EDITOR 294 -#define IMG_INVISIBLE_STEELWALL_ACTIVE 295 -#define IMG_INVISIBLE_WALL 296 -#define IMG_INVISIBLE_WALL_EDITOR 297 -#define IMG_INVISIBLE_WALL_ACTIVE 298 -#define IMG_INVISIBLE_SAND 299 -#define IMG_INVISIBLE_SAND_EDITOR 300 -#define IMG_INVISIBLE_SAND_ACTIVE 301 -#define IMG_INVISIBLE_SAND_ACTIVE_CRUMBLED 302 -#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_LEFT 303 -#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_RIGHT 304 -#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_UP 305 -#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_DOWN 306 -#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_LEFT_CRUMBLED 307 -#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_RIGHT_CRUMBLED 308 -#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_UP_CRUMBLED 309 -#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_DOWN_CRUMBLED 310 -#define IMG_CONVEYOR_BELT_1_MIDDLE 311 -#define IMG_CONVEYOR_BELT_1_MIDDLE_ACTIVE 312 -#define IMG_CONVEYOR_BELT_1_LEFT 313 -#define IMG_CONVEYOR_BELT_1_LEFT_ACTIVE 314 -#define IMG_CONVEYOR_BELT_1_RIGHT 315 -#define IMG_CONVEYOR_BELT_1_RIGHT_ACTIVE 316 -#define IMG_CONVEYOR_BELT_1_SWITCH_LEFT 317 -#define IMG_CONVEYOR_BELT_1_SWITCH_MIDDLE 318 -#define IMG_CONVEYOR_BELT_1_SWITCH_RIGHT 319 -#define IMG_CONVEYOR_BELT_2_MIDDLE 320 -#define IMG_CONVEYOR_BELT_2_MIDDLE_ACTIVE 321 -#define IMG_CONVEYOR_BELT_2_LEFT 322 -#define IMG_CONVEYOR_BELT_2_LEFT_ACTIVE 323 -#define IMG_CONVEYOR_BELT_2_RIGHT 324 -#define IMG_CONVEYOR_BELT_2_RIGHT_ACTIVE 325 -#define IMG_CONVEYOR_BELT_2_SWITCH_LEFT 326 -#define IMG_CONVEYOR_BELT_2_SWITCH_MIDDLE 327 -#define IMG_CONVEYOR_BELT_2_SWITCH_RIGHT 328 -#define IMG_CONVEYOR_BELT_3_MIDDLE 329 -#define IMG_CONVEYOR_BELT_3_MIDDLE_ACTIVE 330 -#define IMG_CONVEYOR_BELT_3_LEFT 331 -#define IMG_CONVEYOR_BELT_3_LEFT_ACTIVE 332 -#define IMG_CONVEYOR_BELT_3_RIGHT 333 -#define IMG_CONVEYOR_BELT_3_RIGHT_ACTIVE 334 -#define IMG_CONVEYOR_BELT_3_SWITCH_LEFT 335 -#define IMG_CONVEYOR_BELT_3_SWITCH_MIDDLE 336 -#define IMG_CONVEYOR_BELT_3_SWITCH_RIGHT 337 -#define IMG_CONVEYOR_BELT_4_MIDDLE 338 -#define IMG_CONVEYOR_BELT_4_MIDDLE_ACTIVE 339 -#define IMG_CONVEYOR_BELT_4_LEFT 340 -#define IMG_CONVEYOR_BELT_4_LEFT_ACTIVE 341 -#define IMG_CONVEYOR_BELT_4_RIGHT 342 -#define IMG_CONVEYOR_BELT_4_RIGHT_ACTIVE 343 -#define IMG_CONVEYOR_BELT_4_SWITCH_LEFT 344 -#define IMG_CONVEYOR_BELT_4_SWITCH_MIDDLE 345 -#define IMG_CONVEYOR_BELT_4_SWITCH_RIGHT 346 -#define IMG_SWITCHGATE_SWITCH_UP 347 -#define IMG_SWITCHGATE_SWITCH_DOWN 348 -#define IMG_LIGHT_SWITCH 349 -#define IMG_LIGHT_SWITCH_ACTIVE 350 -#define IMG_TIMEGATE_SWITCH 351 -#define IMG_TIMEGATE_SWITCH_ACTIVE 352 -#define IMG_ENVELOPE_1 353 -#define IMG_ENVELOPE_1_COLLECTING 354 -#define IMG_ENVELOPE_2 355 -#define IMG_ENVELOPE_2_COLLECTING 356 -#define IMG_ENVELOPE_3 357 -#define IMG_ENVELOPE_3_COLLECTING 358 -#define IMG_ENVELOPE_4 359 -#define IMG_ENVELOPE_4_COLLECTING 360 -#define IMG_SIGN_EXCLAMATION 361 -#define IMG_SIGN_STOP 362 -#define IMG_LANDMINE 363 -#define IMG_STEELWALL_SLIPPERY 364 -#define IMG_EXTRA_TIME 365 -#define IMG_SHIELD_NORMAL 366 -#define IMG_SHIELD_NORMAL_ACTIVE 367 -#define IMG_SHIELD_DEADLY 368 -#define IMG_SHIELD_DEADLY_ACTIVE 369 -#define IMG_SWITCHGATE_CLOSED 370 -#define IMG_SWITCHGATE_OPENING 371 -#define IMG_SWITCHGATE_OPEN 372 -#define IMG_SWITCHGATE_CLOSING 373 -#define IMG_TIMEGATE_CLOSED 374 -#define IMG_TIMEGATE_OPENING 375 -#define IMG_TIMEGATE_OPEN 376 -#define IMG_TIMEGATE_CLOSING 377 -#define IMG_PEARL 378 -#define IMG_PEARL_BREAKING 379 -#define IMG_CRYSTAL 380 -#define IMG_WALL_PEARL 381 -#define IMG_WALL_CRYSTAL 382 -#define IMG_TUBE_RIGHT_DOWN 383 -#define IMG_TUBE_HORIZONTAL_DOWN 384 -#define IMG_TUBE_LEFT_DOWN 385 -#define IMG_TUBE_HORIZONTAL 386 -#define IMG_TUBE_VERTICAL_RIGHT 387 -#define IMG_TUBE_ANY 388 -#define IMG_TUBE_VERTICAL_LEFT 389 -#define IMG_TUBE_VERTICAL 390 -#define IMG_TUBE_RIGHT_UP 391 -#define IMG_TUBE_HORIZONTAL_UP 392 -#define IMG_TUBE_LEFT_UP 393 -#define IMG_TRAP 394 -#define IMG_TRAP_ACTIVE 395 -#define IMG_DX_SUPABOMB 396 -#define IMG_KEY_1 397 -#define IMG_KEY_1_EDITOR 398 -#define IMG_KEY_2 399 -#define IMG_KEY_2_EDITOR 400 -#define IMG_KEY_3 401 -#define IMG_KEY_3_EDITOR 402 -#define IMG_KEY_4 403 -#define IMG_KEY_4_EDITOR 404 -#define IMG_GATE_1 405 -#define IMG_GATE_2 406 -#define IMG_GATE_3 407 -#define IMG_GATE_4 408 -#define IMG_GATE_1_GRAY 409 -#define IMG_GATE_1_GRAY_EDITOR 410 -#define IMG_GATE_2_GRAY 411 -#define IMG_GATE_2_GRAY_EDITOR 412 -#define IMG_GATE_3_GRAY 413 -#define IMG_GATE_3_GRAY_EDITOR 414 -#define IMG_GATE_4_GRAY 415 -#define IMG_GATE_4_GRAY_EDITOR 416 -#define IMG_GAME_OF_LIFE 417 -#define IMG_BIOMAZE 418 -#define IMG_PACMAN 419 -#define IMG_PACMAN_RIGHT 420 -#define IMG_PACMAN_UP 421 -#define IMG_PACMAN_LEFT 422 -#define IMG_PACMAN_DOWN 423 -#define IMG_PACMAN_TURNING_FROM_RIGHT 424 -#define IMG_PACMAN_TURNING_FROM_UP 425 -#define IMG_PACMAN_TURNING_FROM_LEFT 426 -#define IMG_PACMAN_TURNING_FROM_DOWN 427 -#define IMG_LAMP 428 -#define IMG_LAMP_EDITOR 429 -#define IMG_LAMP_ACTIVE 430 -#define IMG_TIME_ORB_FULL 431 -#define IMG_TIME_ORB_EMPTY 432 -#define IMG_EMERALD_YELLOW 433 -#define IMG_EMERALD_YELLOW_MOVING 434 -#define IMG_EMERALD_YELLOW_FALLING 435 -#define IMG_EMERALD_RED 436 -#define IMG_EMERALD_RED_MOVING 437 -#define IMG_EMERALD_RED_FALLING 438 -#define IMG_EMERALD_PURPLE 439 -#define IMG_EMERALD_PURPLE_MOVING 440 -#define IMG_EMERALD_PURPLE_FALLING 441 -#define IMG_WALL_EMERALD_YELLOW 442 -#define IMG_WALL_EMERALD_RED 443 -#define IMG_WALL_EMERALD_PURPLE 444 -#define IMG_WALL_BD_DIAMOND 445 -#define IMG_EXPANDABLE_WALL 446 -#define IMG_EXPANDABLE_WALL_HORIZONTAL 447 -#define IMG_EXPANDABLE_WALL_HORIZONTAL_EDITOR 448 -#define IMG_EXPANDABLE_WALL_VERTICAL 449 -#define IMG_EXPANDABLE_WALL_VERTICAL_EDITOR 450 -#define IMG_EXPANDABLE_WALL_ANY 451 -#define IMG_EXPANDABLE_WALL_ANY_EDITOR 452 -#define IMG_EXPANDABLE_WALL_GROWING_LEFT 453 -#define IMG_EXPANDABLE_WALL_GROWING_RIGHT 454 -#define IMG_EXPANDABLE_WALL_GROWING_UP 455 -#define IMG_EXPANDABLE_WALL_GROWING_DOWN 456 -#define IMG_BLACK_ORB 457 -#define IMG_SPEED_PILL 458 -#define IMG_DARK_YAMYAM 459 -#define IMG_DYNABOMB 460 -#define IMG_DYNABOMB_ACTIVE 461 -#define IMG_DYNABOMB_PLAYER_1 462 -#define IMG_DYNABOMB_PLAYER_1_ACTIVE 463 -#define IMG_DYNABOMB_PLAYER_2 464 -#define IMG_DYNABOMB_PLAYER_2_ACTIVE 465 -#define IMG_DYNABOMB_PLAYER_3 466 -#define IMG_DYNABOMB_PLAYER_3_ACTIVE 467 -#define IMG_DYNABOMB_PLAYER_4 468 -#define IMG_DYNABOMB_PLAYER_4_ACTIVE 469 -#define IMG_DYNABOMB_INCREASE_NUMBER 470 -#define IMG_DYNABOMB_INCREASE_SIZE 471 -#define IMG_DYNABOMB_INCREASE_POWER 472 -#define IMG_PIG 473 -#define IMG_PIG_DOWN 474 -#define IMG_PIG_UP 475 -#define IMG_PIG_LEFT 476 -#define IMG_PIG_RIGHT 477 -#define IMG_PIG_MOVING_DOWN 478 -#define IMG_PIG_MOVING_UP 479 -#define IMG_PIG_MOVING_LEFT 480 -#define IMG_PIG_MOVING_RIGHT 481 -#define IMG_PIG_DIGGING_DOWN 482 -#define IMG_PIG_DIGGING_UP 483 -#define IMG_PIG_DIGGING_LEFT 484 -#define IMG_PIG_DIGGING_RIGHT 485 -#define IMG_DRAGON 486 -#define IMG_DRAGON_DOWN 487 -#define IMG_DRAGON_UP 488 -#define IMG_DRAGON_LEFT 489 -#define IMG_DRAGON_RIGHT 490 -#define IMG_DRAGON_MOVING_DOWN 491 -#define IMG_DRAGON_MOVING_UP 492 -#define IMG_DRAGON_MOVING_LEFT 493 -#define IMG_DRAGON_MOVING_RIGHT 494 -#define IMG_DRAGON_ATTACKING_DOWN 495 -#define IMG_DRAGON_ATTACKING_UP 496 -#define IMG_DRAGON_ATTACKING_LEFT 497 -#define IMG_DRAGON_ATTACKING_RIGHT 498 -#define IMG_MOLE 499 -#define IMG_MOLE_DOWN 500 -#define IMG_MOLE_UP 501 -#define IMG_MOLE_LEFT 502 -#define IMG_MOLE_RIGHT 503 -#define IMG_MOLE_MOVING_DOWN 504 -#define IMG_MOLE_MOVING_UP 505 -#define IMG_MOLE_MOVING_LEFT 506 -#define IMG_MOLE_MOVING_RIGHT 507 -#define IMG_MOLE_DIGGING_DOWN 508 -#define IMG_MOLE_DIGGING_UP 509 -#define IMG_MOLE_DIGGING_LEFT 510 -#define IMG_MOLE_DIGGING_RIGHT 511 -#define IMG_PENGUIN 512 -#define IMG_PENGUIN_EDITOR 513 -#define IMG_PENGUIN_DOWN 514 -#define IMG_PENGUIN_UP 515 -#define IMG_PENGUIN_LEFT 516 -#define IMG_PENGUIN_RIGHT 517 -#define IMG_PENGUIN_MOVING_DOWN 518 -#define IMG_PENGUIN_MOVING_UP 519 -#define IMG_PENGUIN_MOVING_LEFT 520 -#define IMG_PENGUIN_MOVING_RIGHT 521 -#define IMG_SATELLITE 522 -#define IMG_FLAMES_1_LEFT 523 -#define IMG_FLAMES_2_LEFT 524 -#define IMG_FLAMES_3_LEFT 525 -#define IMG_FLAMES_1_RIGHT 526 -#define IMG_FLAMES_2_RIGHT 527 -#define IMG_FLAMES_3_RIGHT 528 -#define IMG_FLAMES_1_UP 529 -#define IMG_FLAMES_2_UP 530 -#define IMG_FLAMES_3_UP 531 -#define IMG_FLAMES_1_DOWN 532 -#define IMG_FLAMES_2_DOWN 533 -#define IMG_FLAMES_3_DOWN 534 -#define IMG_STONEBLOCK 535 -#define IMG_PLAYER_1 536 -#define IMG_PLAYER_1_EDITOR 537 -#define IMG_PLAYER_1_DOWN 538 -#define IMG_PLAYER_1_UP 539 -#define IMG_PLAYER_1_LEFT 540 -#define IMG_PLAYER_1_RIGHT 541 -#define IMG_PLAYER_1_MOVING_DOWN 542 -#define IMG_PLAYER_1_MOVING_UP 543 -#define IMG_PLAYER_1_MOVING_LEFT 544 -#define IMG_PLAYER_1_MOVING_RIGHT 545 -#define IMG_PLAYER_1_DIGGING_DOWN 546 -#define IMG_PLAYER_1_DIGGING_UP 547 -#define IMG_PLAYER_1_DIGGING_LEFT 548 -#define IMG_PLAYER_1_DIGGING_RIGHT 549 -#define IMG_PLAYER_1_COLLECTING_DOWN 550 -#define IMG_PLAYER_1_COLLECTING_UP 551 -#define IMG_PLAYER_1_COLLECTING_LEFT 552 -#define IMG_PLAYER_1_COLLECTING_RIGHT 553 -#define IMG_PLAYER_1_PUSHING_DOWN 554 -#define IMG_PLAYER_1_PUSHING_UP 555 -#define IMG_PLAYER_1_PUSHING_LEFT 556 -#define IMG_PLAYER_1_PUSHING_RIGHT 557 -#define IMG_PLAYER_1_SNAPPING_DOWN 558 -#define IMG_PLAYER_1_SNAPPING_UP 559 -#define IMG_PLAYER_1_SNAPPING_LEFT 560 -#define IMG_PLAYER_1_SNAPPING_RIGHT 561 -#define IMG_PLAYER_2 562 -#define IMG_PLAYER_2_EDITOR 563 -#define IMG_PLAYER_2_DOWN 564 -#define IMG_PLAYER_2_UP 565 -#define IMG_PLAYER_2_LEFT 566 -#define IMG_PLAYER_2_RIGHT 567 -#define IMG_PLAYER_2_MOVING_DOWN 568 -#define IMG_PLAYER_2_MOVING_UP 569 -#define IMG_PLAYER_2_MOVING_LEFT 570 -#define IMG_PLAYER_2_MOVING_RIGHT 571 -#define IMG_PLAYER_2_DIGGING_DOWN 572 -#define IMG_PLAYER_2_DIGGING_UP 573 -#define IMG_PLAYER_2_DIGGING_LEFT 574 -#define IMG_PLAYER_2_DIGGING_RIGHT 575 -#define IMG_PLAYER_2_COLLECTING_DOWN 576 -#define IMG_PLAYER_2_COLLECTING_UP 577 -#define IMG_PLAYER_2_COLLECTING_LEFT 578 -#define IMG_PLAYER_2_COLLECTING_RIGHT 579 -#define IMG_PLAYER_2_PUSHING_DOWN 580 -#define IMG_PLAYER_2_PUSHING_UP 581 -#define IMG_PLAYER_2_PUSHING_LEFT 582 -#define IMG_PLAYER_2_PUSHING_RIGHT 583 -#define IMG_PLAYER_2_SNAPPING_DOWN 584 -#define IMG_PLAYER_2_SNAPPING_UP 585 -#define IMG_PLAYER_2_SNAPPING_LEFT 586 -#define IMG_PLAYER_2_SNAPPING_RIGHT 587 -#define IMG_PLAYER_3 588 -#define IMG_PLAYER_3_EDITOR 589 -#define IMG_PLAYER_3_DOWN 590 -#define IMG_PLAYER_3_UP 591 -#define IMG_PLAYER_3_LEFT 592 -#define IMG_PLAYER_3_RIGHT 593 -#define IMG_PLAYER_3_MOVING_DOWN 594 -#define IMG_PLAYER_3_MOVING_UP 595 -#define IMG_PLAYER_3_MOVING_LEFT 596 -#define IMG_PLAYER_3_MOVING_RIGHT 597 -#define IMG_PLAYER_3_DIGGING_DOWN 598 -#define IMG_PLAYER_3_DIGGING_UP 599 -#define IMG_PLAYER_3_DIGGING_LEFT 600 -#define IMG_PLAYER_3_DIGGING_RIGHT 601 -#define IMG_PLAYER_3_COLLECTING_DOWN 602 -#define IMG_PLAYER_3_COLLECTING_UP 603 -#define IMG_PLAYER_3_COLLECTING_LEFT 604 -#define IMG_PLAYER_3_COLLECTING_RIGHT 605 -#define IMG_PLAYER_3_PUSHING_DOWN 606 -#define IMG_PLAYER_3_PUSHING_UP 607 -#define IMG_PLAYER_3_PUSHING_LEFT 608 -#define IMG_PLAYER_3_PUSHING_RIGHT 609 -#define IMG_PLAYER_3_SNAPPING_DOWN 610 -#define IMG_PLAYER_3_SNAPPING_UP 611 -#define IMG_PLAYER_3_SNAPPING_LEFT 612 -#define IMG_PLAYER_3_SNAPPING_RIGHT 613 -#define IMG_PLAYER_4 614 -#define IMG_PLAYER_4_EDITOR 615 -#define IMG_PLAYER_4_DOWN 616 -#define IMG_PLAYER_4_UP 617 -#define IMG_PLAYER_4_LEFT 618 -#define IMG_PLAYER_4_RIGHT 619 -#define IMG_PLAYER_4_MOVING_DOWN 620 -#define IMG_PLAYER_4_MOVING_UP 621 -#define IMG_PLAYER_4_MOVING_LEFT 622 -#define IMG_PLAYER_4_MOVING_RIGHT 623 -#define IMG_PLAYER_4_DIGGING_DOWN 624 -#define IMG_PLAYER_4_DIGGING_UP 625 -#define IMG_PLAYER_4_DIGGING_LEFT 626 -#define IMG_PLAYER_4_DIGGING_RIGHT 627 -#define IMG_PLAYER_4_COLLECTING_DOWN 628 -#define IMG_PLAYER_4_COLLECTING_UP 629 -#define IMG_PLAYER_4_COLLECTING_LEFT 630 -#define IMG_PLAYER_4_COLLECTING_RIGHT 631 -#define IMG_PLAYER_4_PUSHING_DOWN 632 -#define IMG_PLAYER_4_PUSHING_UP 633 -#define IMG_PLAYER_4_PUSHING_LEFT 634 -#define IMG_PLAYER_4_PUSHING_RIGHT 635 -#define IMG_PLAYER_4_SNAPPING_DOWN 636 -#define IMG_PLAYER_4_SNAPPING_UP 637 -#define IMG_PLAYER_4_SNAPPING_LEFT 638 -#define IMG_PLAYER_4_SNAPPING_RIGHT 639 -#define IMG_DEFAULT_EXPLODING 640 -#define IMG_TWINKLE_BLUE 641 -#define IMG_TWINKLE_WHITE 642 -#define IMG_STEELWALL_TOPLEFT 643 -#define IMG_STEELWALL_TOPRIGHT 644 -#define IMG_STEELWALL_BOTTOMLEFT 645 -#define IMG_STEELWALL_BOTTOMRIGHT 646 -#define IMG_STEELWALL_HORIZONTAL 647 -#define IMG_STEELWALL_VERTICAL 648 -#define IMG_STEELWALL_TOPLEFT_EDITOR 649 -#define IMG_STEELWALL_TOPRIGHT_EDITOR 650 -#define IMG_STEELWALL_BOTTOMLEFT_EDITOR 651 -#define IMG_STEELWALL_BOTTOMRIGHT_EDITOR 652 -#define IMG_STEELWALL_HORIZONTAL_EDITOR 653 -#define IMG_STEELWALL_VERTICAL_EDITOR 654 -#define IMG_INVISIBLE_STEELWALL_TOPLEFT 655 -#define IMG_INVISIBLE_STEELWALL_TOPRIGHT 656 -#define IMG_INVISIBLE_STEELWALL_BOTTOMLEFT 657 -#define IMG_INVISIBLE_STEELWALL_BOTTOMRIGHT 658 -#define IMG_INVISIBLE_STEELWALL_HORIZONTAL 659 -#define IMG_INVISIBLE_STEELWALL_VERTICAL 660 -#define IMG_INVISIBLE_STEELWALL_TOPLEFT_EDITOR 661 -#define IMG_INVISIBLE_STEELWALL_TOPRIGHT_EDITOR 662 -#define IMG_INVISIBLE_STEELWALL_BOTTOMLEFT_EDITOR 663 -#define IMG_INVISIBLE_STEELWALL_BOTTOMRIGHT_EDITOR 664 -#define IMG_INVISIBLE_STEELWALL_HORIZONTAL_EDITOR 665 -#define IMG_INVISIBLE_STEELWALL_VERTICAL_EDITOR 666 -#define IMG_ARROW_LEFT 667 -#define IMG_ARROW_RIGHT 668 -#define IMG_ARROW_UP 669 -#define IMG_ARROW_DOWN 670 -#define IMG_UNKNOWN 671 -#define IMG_TRIGGER_ELEMENT 672 -#define IMG_TRIGGER_PLAYER 673 -#define IMG_EMC_KEY_5 674 -#define IMG_EMC_KEY_6 675 -#define IMG_EMC_KEY_7 676 -#define IMG_EMC_KEY_8 677 -#define IMG_EMC_GATE_5 678 -#define IMG_EMC_GATE_5_GRAY 679 -#define IMG_EMC_GATE_5_GRAY_EDITOR 680 -#define IMG_EMC_GATE_6 681 -#define IMG_EMC_GATE_6_GRAY 682 -#define IMG_EMC_GATE_6_GRAY_EDITOR 683 -#define IMG_EMC_GATE_7 684 -#define IMG_EMC_GATE_7_GRAY 685 -#define IMG_EMC_GATE_7_GRAY_EDITOR 686 -#define IMG_EMC_GATE_8 687 -#define IMG_EMC_GATE_8_GRAY 688 -#define IMG_EMC_GATE_8_GRAY_EDITOR 689 -#define IMG_EMC_ANDROID 690 -#define IMG_EMC_GRASS 691 -#define IMG_EMC_GRASS_CRUMBLED 692 -#define IMG_EMC_GRASS_DIGGING_LEFT 693 -#define IMG_EMC_GRASS_DIGGING_RIGHT 694 -#define IMG_EMC_GRASS_DIGGING_UP 695 -#define IMG_EMC_GRASS_DIGGING_DOWN 696 -#define IMG_EMC_GRASS_DIGGING_LEFT_CRUMBLED 697 -#define IMG_EMC_GRASS_DIGGING_RIGHT_CRUMBLED 698 -#define IMG_EMC_GRASS_DIGGING_UP_CRUMBLED 699 -#define IMG_EMC_GRASS_DIGGING_DOWN_CRUMBLED 700 -#define IMG_EMC_MAGIC_BALL 701 -#define IMG_EMC_MAGIC_BALL_ACTIVE 702 -#define IMG_EMC_MAGIC_BALL_SWITCH 703 -#define IMG_EMC_MAGIC_BALL_SWITCH_ACTIVE 704 -#define IMG_EMC_SPRING_BUMPER 705 -#define IMG_EMC_SPRING_BUMPER_ACTIVE 706 -#define IMG_EMC_PLANT 707 -#define IMG_EMC_PLANT_CRUMBLED 708 -#define IMG_EMC_LENSES 709 -#define IMG_EMC_MAGNIFIER 710 -#define IMG_EMC_WALL_9 711 -#define IMG_EMC_WALL_10 712 -#define IMG_EMC_WALL_11 713 -#define IMG_EMC_WALL_12 714 -#define IMG_EMC_WALL_13 715 -#define IMG_EMC_WALL_14 716 -#define IMG_EMC_WALL_15 717 -#define IMG_EMC_WALL_16 718 -#define IMG_EMC_WALL_SLIPPERY_1 719 -#define IMG_EMC_WALL_SLIPPERY_2 720 -#define IMG_EMC_WALL_SLIPPERY_3 721 -#define IMG_EMC_WALL_SLIPPERY_4 722 -#define IMG_EMC_FAKE_GRASS 723 -#define IMG_EMC_FAKE_GRASS_CRUMBLED 724 -#define IMG_EMC_FAKE_GRASS_ACTIVE 725 -#define IMG_EMC_FAKE_GRASS_ACTIVE_CRUMBLED 726 -#define IMG_EMC_FAKE_ACID 727 -#define IMG_EMC_DRIPPER 728 -#define IMG_EMC_DRIPPER_EDITOR 729 -#define IMG_EMC_DRIPPER_ACTIVE 730 -#define IMG_CHAR_SPACE 731 -#define IMG_CHAR_EXCLAM 732 -#define IMG_CHAR_QUOTEDBL 733 -#define IMG_CHAR_NUMBERSIGN 734 -#define IMG_CHAR_DOLLAR 735 -#define IMG_CHAR_PERCENT 736 -#define IMG_CHAR_AMPERSAND 737 -#define IMG_CHAR_APOSTROPHE 738 -#define IMG_CHAR_PARENLEFT 739 -#define IMG_CHAR_PARENRIGHT 740 -#define IMG_CHAR_ASTERISK 741 -#define IMG_CHAR_PLUS 742 -#define IMG_CHAR_COMMA 743 -#define IMG_CHAR_MINUS 744 -#define IMG_CHAR_PERIOD 745 -#define IMG_CHAR_SLASH 746 -#define IMG_CHAR_0 747 -#define IMG_CHAR_1 748 -#define IMG_CHAR_2 749 -#define IMG_CHAR_3 750 -#define IMG_CHAR_4 751 -#define IMG_CHAR_5 752 -#define IMG_CHAR_6 753 -#define IMG_CHAR_7 754 -#define IMG_CHAR_8 755 -#define IMG_CHAR_9 756 -#define IMG_CHAR_COLON 757 -#define IMG_CHAR_SEMICOLON 758 -#define IMG_CHAR_LESS 759 -#define IMG_CHAR_EQUAL 760 -#define IMG_CHAR_GREATER 761 -#define IMG_CHAR_QUESTION 762 -#define IMG_CHAR_AT 763 -#define IMG_CHAR_A 764 -#define IMG_CHAR_B 765 -#define IMG_CHAR_C 766 -#define IMG_CHAR_D 767 -#define IMG_CHAR_E 768 -#define IMG_CHAR_F 769 -#define IMG_CHAR_G 770 -#define IMG_CHAR_H 771 -#define IMG_CHAR_I 772 -#define IMG_CHAR_J 773 -#define IMG_CHAR_K 774 -#define IMG_CHAR_L 775 -#define IMG_CHAR_M 776 -#define IMG_CHAR_N 777 -#define IMG_CHAR_O 778 -#define IMG_CHAR_P 779 -#define IMG_CHAR_Q 780 -#define IMG_CHAR_R 781 -#define IMG_CHAR_S 782 -#define IMG_CHAR_T 783 -#define IMG_CHAR_U 784 -#define IMG_CHAR_V 785 -#define IMG_CHAR_W 786 -#define IMG_CHAR_X 787 -#define IMG_CHAR_Y 788 -#define IMG_CHAR_Z 789 -#define IMG_CHAR_BRACKETLEFT 790 -#define IMG_CHAR_BACKSLASH 791 -#define IMG_CHAR_BRACKETRIGHT 792 -#define IMG_CHAR_ASCIICIRCUM 793 -#define IMG_CHAR_UNDERSCORE 794 -#define IMG_CHAR_COPYRIGHT 795 -#define IMG_CHAR_AUMLAUT 796 -#define IMG_CHAR_OUMLAUT 797 -#define IMG_CHAR_UUMLAUT 798 -#define IMG_CHAR_DEGREE 799 -#define IMG_CHAR_TRADEMARK 800 -#define IMG_CHAR_CURSOR 801 -#define IMG_CUSTOM_1 802 -#define IMG_CUSTOM_1_EDITOR 803 -#define IMG_CUSTOM_2 804 -#define IMG_CUSTOM_2_EDITOR 805 -#define IMG_CUSTOM_3 806 -#define IMG_CUSTOM_3_EDITOR 807 -#define IMG_CUSTOM_4 808 -#define IMG_CUSTOM_4_EDITOR 809 -#define IMG_CUSTOM_5 810 -#define IMG_CUSTOM_5_EDITOR 811 -#define IMG_CUSTOM_6 812 -#define IMG_CUSTOM_6_EDITOR 813 -#define IMG_CUSTOM_7 814 -#define IMG_CUSTOM_7_EDITOR 815 -#define IMG_CUSTOM_8 816 -#define IMG_CUSTOM_8_EDITOR 817 -#define IMG_CUSTOM_9 818 -#define IMG_CUSTOM_9_EDITOR 819 -#define IMG_CUSTOM_10 820 -#define IMG_CUSTOM_10_EDITOR 821 -#define IMG_CUSTOM_11 822 -#define IMG_CUSTOM_11_EDITOR 823 -#define IMG_CUSTOM_12 824 -#define IMG_CUSTOM_12_EDITOR 825 -#define IMG_CUSTOM_13 826 -#define IMG_CUSTOM_13_EDITOR 827 -#define IMG_CUSTOM_14 828 -#define IMG_CUSTOM_14_EDITOR 829 -#define IMG_CUSTOM_15 830 -#define IMG_CUSTOM_15_EDITOR 831 -#define IMG_CUSTOM_16 832 -#define IMG_CUSTOM_16_EDITOR 833 -#define IMG_CUSTOM_17 834 -#define IMG_CUSTOM_17_EDITOR 835 -#define IMG_CUSTOM_18 836 -#define IMG_CUSTOM_18_EDITOR 837 -#define IMG_CUSTOM_19 838 -#define IMG_CUSTOM_19_EDITOR 839 -#define IMG_CUSTOM_20 840 -#define IMG_CUSTOM_20_EDITOR 841 -#define IMG_CUSTOM_21 842 -#define IMG_CUSTOM_21_EDITOR 843 -#define IMG_CUSTOM_22 844 -#define IMG_CUSTOM_22_EDITOR 845 -#define IMG_CUSTOM_23 846 -#define IMG_CUSTOM_23_EDITOR 847 -#define IMG_CUSTOM_24 848 -#define IMG_CUSTOM_24_EDITOR 849 -#define IMG_CUSTOM_25 850 -#define IMG_CUSTOM_25_EDITOR 851 -#define IMG_CUSTOM_26 852 -#define IMG_CUSTOM_26_EDITOR 853 -#define IMG_CUSTOM_27 854 -#define IMG_CUSTOM_27_EDITOR 855 -#define IMG_CUSTOM_28 856 -#define IMG_CUSTOM_28_EDITOR 857 -#define IMG_CUSTOM_29 858 -#define IMG_CUSTOM_29_EDITOR 859 -#define IMG_CUSTOM_30 860 -#define IMG_CUSTOM_30_EDITOR 861 -#define IMG_CUSTOM_31 862 -#define IMG_CUSTOM_31_EDITOR 863 -#define IMG_CUSTOM_32 864 -#define IMG_CUSTOM_32_EDITOR 865 -#define IMG_CUSTOM_33 866 -#define IMG_CUSTOM_33_EDITOR 867 -#define IMG_CUSTOM_34 868 -#define IMG_CUSTOM_34_EDITOR 869 -#define IMG_CUSTOM_35 870 -#define IMG_CUSTOM_35_EDITOR 871 -#define IMG_CUSTOM_36 872 -#define IMG_CUSTOM_36_EDITOR 873 -#define IMG_CUSTOM_37 874 -#define IMG_CUSTOM_37_EDITOR 875 -#define IMG_CUSTOM_38 876 -#define IMG_CUSTOM_38_EDITOR 877 -#define IMG_CUSTOM_39 878 -#define IMG_CUSTOM_39_EDITOR 879 -#define IMG_CUSTOM_40 880 -#define IMG_CUSTOM_40_EDITOR 881 -#define IMG_CUSTOM_41 882 -#define IMG_CUSTOM_41_EDITOR 883 -#define IMG_CUSTOM_42 884 -#define IMG_CUSTOM_42_EDITOR 885 -#define IMG_CUSTOM_43 886 -#define IMG_CUSTOM_43_EDITOR 887 -#define IMG_CUSTOM_44 888 -#define IMG_CUSTOM_44_EDITOR 889 -#define IMG_CUSTOM_45 890 -#define IMG_CUSTOM_45_EDITOR 891 -#define IMG_CUSTOM_46 892 -#define IMG_CUSTOM_46_EDITOR 893 -#define IMG_CUSTOM_47 894 -#define IMG_CUSTOM_47_EDITOR 895 -#define IMG_CUSTOM_48 896 -#define IMG_CUSTOM_48_EDITOR 897 -#define IMG_CUSTOM_49 898 -#define IMG_CUSTOM_49_EDITOR 899 -#define IMG_CUSTOM_50 900 -#define IMG_CUSTOM_50_EDITOR 901 -#define IMG_CUSTOM_51 902 -#define IMG_CUSTOM_51_EDITOR 903 -#define IMG_CUSTOM_52 904 -#define IMG_CUSTOM_52_EDITOR 905 -#define IMG_CUSTOM_53 906 -#define IMG_CUSTOM_53_EDITOR 907 -#define IMG_CUSTOM_54 908 -#define IMG_CUSTOM_54_EDITOR 909 -#define IMG_CUSTOM_55 910 -#define IMG_CUSTOM_55_EDITOR 911 -#define IMG_CUSTOM_56 912 -#define IMG_CUSTOM_56_EDITOR 913 -#define IMG_CUSTOM_57 914 -#define IMG_CUSTOM_57_EDITOR 915 -#define IMG_CUSTOM_58 916 -#define IMG_CUSTOM_58_EDITOR 917 -#define IMG_CUSTOM_59 918 -#define IMG_CUSTOM_59_EDITOR 919 -#define IMG_CUSTOM_60 920 -#define IMG_CUSTOM_60_EDITOR 921 -#define IMG_CUSTOM_61 922 -#define IMG_CUSTOM_61_EDITOR 923 -#define IMG_CUSTOM_62 924 -#define IMG_CUSTOM_62_EDITOR 925 -#define IMG_CUSTOM_63 926 -#define IMG_CUSTOM_63_EDITOR 927 -#define IMG_CUSTOM_64 928 -#define IMG_CUSTOM_64_EDITOR 929 -#define IMG_CUSTOM_65 930 -#define IMG_CUSTOM_65_EDITOR 931 -#define IMG_CUSTOM_66 932 -#define IMG_CUSTOM_66_EDITOR 933 -#define IMG_CUSTOM_67 934 -#define IMG_CUSTOM_67_EDITOR 935 -#define IMG_CUSTOM_68 936 -#define IMG_CUSTOM_68_EDITOR 937 -#define IMG_CUSTOM_69 938 -#define IMG_CUSTOM_69_EDITOR 939 -#define IMG_CUSTOM_70 940 -#define IMG_CUSTOM_70_EDITOR 941 -#define IMG_CUSTOM_71 942 -#define IMG_CUSTOM_71_EDITOR 943 -#define IMG_CUSTOM_72 944 -#define IMG_CUSTOM_72_EDITOR 945 -#define IMG_CUSTOM_73 946 -#define IMG_CUSTOM_73_EDITOR 947 -#define IMG_CUSTOM_74 948 -#define IMG_CUSTOM_74_EDITOR 949 -#define IMG_CUSTOM_75 950 -#define IMG_CUSTOM_75_EDITOR 951 -#define IMG_CUSTOM_76 952 -#define IMG_CUSTOM_76_EDITOR 953 -#define IMG_CUSTOM_77 954 -#define IMG_CUSTOM_77_EDITOR 955 -#define IMG_CUSTOM_78 956 -#define IMG_CUSTOM_78_EDITOR 957 -#define IMG_CUSTOM_79 958 -#define IMG_CUSTOM_79_EDITOR 959 -#define IMG_CUSTOM_80 960 -#define IMG_CUSTOM_80_EDITOR 961 -#define IMG_CUSTOM_81 962 -#define IMG_CUSTOM_81_EDITOR 963 -#define IMG_CUSTOM_82 964 -#define IMG_CUSTOM_82_EDITOR 965 -#define IMG_CUSTOM_83 966 -#define IMG_CUSTOM_83_EDITOR 967 -#define IMG_CUSTOM_84 968 -#define IMG_CUSTOM_84_EDITOR 969 -#define IMG_CUSTOM_85 970 -#define IMG_CUSTOM_85_EDITOR 971 -#define IMG_CUSTOM_86 972 -#define IMG_CUSTOM_86_EDITOR 973 -#define IMG_CUSTOM_87 974 -#define IMG_CUSTOM_87_EDITOR 975 -#define IMG_CUSTOM_88 976 -#define IMG_CUSTOM_88_EDITOR 977 -#define IMG_CUSTOM_89 978 -#define IMG_CUSTOM_89_EDITOR 979 -#define IMG_CUSTOM_90 980 -#define IMG_CUSTOM_90_EDITOR 981 -#define IMG_CUSTOM_91 982 -#define IMG_CUSTOM_91_EDITOR 983 -#define IMG_CUSTOM_92 984 -#define IMG_CUSTOM_92_EDITOR 985 -#define IMG_CUSTOM_93 986 -#define IMG_CUSTOM_93_EDITOR 987 -#define IMG_CUSTOM_94 988 -#define IMG_CUSTOM_94_EDITOR 989 -#define IMG_CUSTOM_95 990 -#define IMG_CUSTOM_95_EDITOR 991 -#define IMG_CUSTOM_96 992 -#define IMG_CUSTOM_96_EDITOR 993 -#define IMG_CUSTOM_97 994 -#define IMG_CUSTOM_97_EDITOR 995 -#define IMG_CUSTOM_98 996 -#define IMG_CUSTOM_98_EDITOR 997 -#define IMG_CUSTOM_99 998 -#define IMG_CUSTOM_99_EDITOR 999 -#define IMG_CUSTOM_100 1000 -#define IMG_CUSTOM_100_EDITOR 1001 -#define IMG_CUSTOM_101 1002 -#define IMG_CUSTOM_101_EDITOR 1003 -#define IMG_CUSTOM_102 1004 -#define IMG_CUSTOM_102_EDITOR 1005 -#define IMG_CUSTOM_103 1006 -#define IMG_CUSTOM_103_EDITOR 1007 -#define IMG_CUSTOM_104 1008 -#define IMG_CUSTOM_104_EDITOR 1009 -#define IMG_CUSTOM_105 1010 -#define IMG_CUSTOM_105_EDITOR 1011 -#define IMG_CUSTOM_106 1012 -#define IMG_CUSTOM_106_EDITOR 1013 -#define IMG_CUSTOM_107 1014 -#define IMG_CUSTOM_107_EDITOR 1015 -#define IMG_CUSTOM_108 1016 -#define IMG_CUSTOM_108_EDITOR 1017 -#define IMG_CUSTOM_109 1018 -#define IMG_CUSTOM_109_EDITOR 1019 -#define IMG_CUSTOM_110 1020 -#define IMG_CUSTOM_110_EDITOR 1021 -#define IMG_CUSTOM_111 1022 -#define IMG_CUSTOM_111_EDITOR 1023 -#define IMG_CUSTOM_112 1024 -#define IMG_CUSTOM_112_EDITOR 1025 -#define IMG_CUSTOM_113 1026 -#define IMG_CUSTOM_113_EDITOR 1027 -#define IMG_CUSTOM_114 1028 -#define IMG_CUSTOM_114_EDITOR 1029 -#define IMG_CUSTOM_115 1030 -#define IMG_CUSTOM_115_EDITOR 1031 -#define IMG_CUSTOM_116 1032 -#define IMG_CUSTOM_116_EDITOR 1033 -#define IMG_CUSTOM_117 1034 -#define IMG_CUSTOM_117_EDITOR 1035 -#define IMG_CUSTOM_118 1036 -#define IMG_CUSTOM_118_EDITOR 1037 -#define IMG_CUSTOM_119 1038 -#define IMG_CUSTOM_119_EDITOR 1039 -#define IMG_CUSTOM_120 1040 -#define IMG_CUSTOM_120_EDITOR 1041 -#define IMG_CUSTOM_121 1042 -#define IMG_CUSTOM_121_EDITOR 1043 -#define IMG_CUSTOM_122 1044 -#define IMG_CUSTOM_122_EDITOR 1045 -#define IMG_CUSTOM_123 1046 -#define IMG_CUSTOM_123_EDITOR 1047 -#define IMG_CUSTOM_124 1048 -#define IMG_CUSTOM_124_EDITOR 1049 -#define IMG_CUSTOM_125 1050 -#define IMG_CUSTOM_125_EDITOR 1051 -#define IMG_CUSTOM_126 1052 -#define IMG_CUSTOM_126_EDITOR 1053 -#define IMG_CUSTOM_127 1054 -#define IMG_CUSTOM_127_EDITOR 1055 -#define IMG_CUSTOM_128 1056 -#define IMG_CUSTOM_128_EDITOR 1057 -#define IMG_CUSTOM_129 1058 -#define IMG_CUSTOM_129_EDITOR 1059 -#define IMG_CUSTOM_130 1060 -#define IMG_CUSTOM_130_EDITOR 1061 -#define IMG_CUSTOM_131 1062 -#define IMG_CUSTOM_131_EDITOR 1063 -#define IMG_CUSTOM_132 1064 -#define IMG_CUSTOM_132_EDITOR 1065 -#define IMG_CUSTOM_133 1066 -#define IMG_CUSTOM_133_EDITOR 1067 -#define IMG_CUSTOM_134 1068 -#define IMG_CUSTOM_134_EDITOR 1069 -#define IMG_CUSTOM_135 1070 -#define IMG_CUSTOM_135_EDITOR 1071 -#define IMG_CUSTOM_136 1072 -#define IMG_CUSTOM_136_EDITOR 1073 -#define IMG_CUSTOM_137 1074 -#define IMG_CUSTOM_137_EDITOR 1075 -#define IMG_CUSTOM_138 1076 -#define IMG_CUSTOM_138_EDITOR 1077 -#define IMG_CUSTOM_139 1078 -#define IMG_CUSTOM_139_EDITOR 1079 -#define IMG_CUSTOM_140 1080 -#define IMG_CUSTOM_140_EDITOR 1081 -#define IMG_CUSTOM_141 1082 -#define IMG_CUSTOM_141_EDITOR 1083 -#define IMG_CUSTOM_142 1084 -#define IMG_CUSTOM_142_EDITOR 1085 -#define IMG_CUSTOM_143 1086 -#define IMG_CUSTOM_143_EDITOR 1087 -#define IMG_CUSTOM_144 1088 -#define IMG_CUSTOM_144_EDITOR 1089 -#define IMG_CUSTOM_145 1090 -#define IMG_CUSTOM_145_EDITOR 1091 -#define IMG_CUSTOM_146 1092 -#define IMG_CUSTOM_146_EDITOR 1093 -#define IMG_CUSTOM_147 1094 -#define IMG_CUSTOM_147_EDITOR 1095 -#define IMG_CUSTOM_148 1096 -#define IMG_CUSTOM_148_EDITOR 1097 -#define IMG_CUSTOM_149 1098 -#define IMG_CUSTOM_149_EDITOR 1099 -#define IMG_CUSTOM_150 1100 -#define IMG_CUSTOM_150_EDITOR 1101 -#define IMG_CUSTOM_151 1102 -#define IMG_CUSTOM_151_EDITOR 1103 -#define IMG_CUSTOM_152 1104 -#define IMG_CUSTOM_152_EDITOR 1105 -#define IMG_CUSTOM_153 1106 -#define IMG_CUSTOM_153_EDITOR 1107 -#define IMG_CUSTOM_154 1108 -#define IMG_CUSTOM_154_EDITOR 1109 -#define IMG_CUSTOM_155 1110 -#define IMG_CUSTOM_155_EDITOR 1111 -#define IMG_CUSTOM_156 1112 -#define IMG_CUSTOM_156_EDITOR 1113 -#define IMG_CUSTOM_157 1114 -#define IMG_CUSTOM_157_EDITOR 1115 -#define IMG_CUSTOM_158 1116 -#define IMG_CUSTOM_158_EDITOR 1117 -#define IMG_CUSTOM_159 1118 -#define IMG_CUSTOM_159_EDITOR 1119 -#define IMG_CUSTOM_160 1120 -#define IMG_CUSTOM_160_EDITOR 1121 -#define IMG_CUSTOM_161 1122 -#define IMG_CUSTOM_161_EDITOR 1123 -#define IMG_CUSTOM_162 1124 -#define IMG_CUSTOM_162_EDITOR 1125 -#define IMG_CUSTOM_163 1126 -#define IMG_CUSTOM_163_EDITOR 1127 -#define IMG_CUSTOM_164 1128 -#define IMG_CUSTOM_164_EDITOR 1129 -#define IMG_CUSTOM_165 1130 -#define IMG_CUSTOM_165_EDITOR 1131 -#define IMG_CUSTOM_166 1132 -#define IMG_CUSTOM_166_EDITOR 1133 -#define IMG_CUSTOM_167 1134 -#define IMG_CUSTOM_167_EDITOR 1135 -#define IMG_CUSTOM_168 1136 -#define IMG_CUSTOM_168_EDITOR 1137 -#define IMG_CUSTOM_169 1138 -#define IMG_CUSTOM_169_EDITOR 1139 -#define IMG_CUSTOM_170 1140 -#define IMG_CUSTOM_170_EDITOR 1141 -#define IMG_CUSTOM_171 1142 -#define IMG_CUSTOM_171_EDITOR 1143 -#define IMG_CUSTOM_172 1144 -#define IMG_CUSTOM_172_EDITOR 1145 -#define IMG_CUSTOM_173 1146 -#define IMG_CUSTOM_173_EDITOR 1147 -#define IMG_CUSTOM_174 1148 -#define IMG_CUSTOM_174_EDITOR 1149 -#define IMG_CUSTOM_175 1150 -#define IMG_CUSTOM_175_EDITOR 1151 -#define IMG_CUSTOM_176 1152 -#define IMG_CUSTOM_176_EDITOR 1153 -#define IMG_CUSTOM_177 1154 -#define IMG_CUSTOM_177_EDITOR 1155 -#define IMG_CUSTOM_178 1156 -#define IMG_CUSTOM_178_EDITOR 1157 -#define IMG_CUSTOM_179 1158 -#define IMG_CUSTOM_179_EDITOR 1159 -#define IMG_CUSTOM_180 1160 -#define IMG_CUSTOM_180_EDITOR 1161 -#define IMG_CUSTOM_181 1162 -#define IMG_CUSTOM_181_EDITOR 1163 -#define IMG_CUSTOM_182 1164 -#define IMG_CUSTOM_182_EDITOR 1165 -#define IMG_CUSTOM_183 1166 -#define IMG_CUSTOM_183_EDITOR 1167 -#define IMG_CUSTOM_184 1168 -#define IMG_CUSTOM_184_EDITOR 1169 -#define IMG_CUSTOM_185 1170 -#define IMG_CUSTOM_185_EDITOR 1171 -#define IMG_CUSTOM_186 1172 -#define IMG_CUSTOM_186_EDITOR 1173 -#define IMG_CUSTOM_187 1174 -#define IMG_CUSTOM_187_EDITOR 1175 -#define IMG_CUSTOM_188 1176 -#define IMG_CUSTOM_188_EDITOR 1177 -#define IMG_CUSTOM_189 1178 -#define IMG_CUSTOM_189_EDITOR 1179 -#define IMG_CUSTOM_190 1180 -#define IMG_CUSTOM_190_EDITOR 1181 -#define IMG_CUSTOM_191 1182 -#define IMG_CUSTOM_191_EDITOR 1183 -#define IMG_CUSTOM_192 1184 -#define IMG_CUSTOM_192_EDITOR 1185 -#define IMG_CUSTOM_193 1186 -#define IMG_CUSTOM_193_EDITOR 1187 -#define IMG_CUSTOM_194 1188 -#define IMG_CUSTOM_194_EDITOR 1189 -#define IMG_CUSTOM_195 1190 -#define IMG_CUSTOM_195_EDITOR 1191 -#define IMG_CUSTOM_196 1192 -#define IMG_CUSTOM_196_EDITOR 1193 -#define IMG_CUSTOM_197 1194 -#define IMG_CUSTOM_197_EDITOR 1195 -#define IMG_CUSTOM_198 1196 -#define IMG_CUSTOM_198_EDITOR 1197 -#define IMG_CUSTOM_199 1198 -#define IMG_CUSTOM_199_EDITOR 1199 -#define IMG_CUSTOM_200 1200 -#define IMG_CUSTOM_200_EDITOR 1201 -#define IMG_CUSTOM_201 1202 -#define IMG_CUSTOM_201_EDITOR 1203 -#define IMG_CUSTOM_202 1204 -#define IMG_CUSTOM_202_EDITOR 1205 -#define IMG_CUSTOM_203 1206 -#define IMG_CUSTOM_203_EDITOR 1207 -#define IMG_CUSTOM_204 1208 -#define IMG_CUSTOM_204_EDITOR 1209 -#define IMG_CUSTOM_205 1210 -#define IMG_CUSTOM_205_EDITOR 1211 -#define IMG_CUSTOM_206 1212 -#define IMG_CUSTOM_206_EDITOR 1213 -#define IMG_CUSTOM_207 1214 -#define IMG_CUSTOM_207_EDITOR 1215 -#define IMG_CUSTOM_208 1216 -#define IMG_CUSTOM_208_EDITOR 1217 -#define IMG_CUSTOM_209 1218 -#define IMG_CUSTOM_209_EDITOR 1219 -#define IMG_CUSTOM_210 1220 -#define IMG_CUSTOM_210_EDITOR 1221 -#define IMG_CUSTOM_211 1222 -#define IMG_CUSTOM_211_EDITOR 1223 -#define IMG_CUSTOM_212 1224 -#define IMG_CUSTOM_212_EDITOR 1225 -#define IMG_CUSTOM_213 1226 -#define IMG_CUSTOM_213_EDITOR 1227 -#define IMG_CUSTOM_214 1228 -#define IMG_CUSTOM_214_EDITOR 1229 -#define IMG_CUSTOM_215 1230 -#define IMG_CUSTOM_215_EDITOR 1231 -#define IMG_CUSTOM_216 1232 -#define IMG_CUSTOM_216_EDITOR 1233 -#define IMG_CUSTOM_217 1234 -#define IMG_CUSTOM_217_EDITOR 1235 -#define IMG_CUSTOM_218 1236 -#define IMG_CUSTOM_218_EDITOR 1237 -#define IMG_CUSTOM_219 1238 -#define IMG_CUSTOM_219_EDITOR 1239 -#define IMG_CUSTOM_220 1240 -#define IMG_CUSTOM_220_EDITOR 1241 -#define IMG_CUSTOM_221 1242 -#define IMG_CUSTOM_221_EDITOR 1243 -#define IMG_CUSTOM_222 1244 -#define IMG_CUSTOM_222_EDITOR 1245 -#define IMG_CUSTOM_223 1246 -#define IMG_CUSTOM_223_EDITOR 1247 -#define IMG_CUSTOM_224 1248 -#define IMG_CUSTOM_224_EDITOR 1249 -#define IMG_CUSTOM_225 1250 -#define IMG_CUSTOM_225_EDITOR 1251 -#define IMG_CUSTOM_226 1252 -#define IMG_CUSTOM_226_EDITOR 1253 -#define IMG_CUSTOM_227 1254 -#define IMG_CUSTOM_227_EDITOR 1255 -#define IMG_CUSTOM_228 1256 -#define IMG_CUSTOM_228_EDITOR 1257 -#define IMG_CUSTOM_229 1258 -#define IMG_CUSTOM_229_EDITOR 1259 -#define IMG_CUSTOM_230 1260 -#define IMG_CUSTOM_230_EDITOR 1261 -#define IMG_CUSTOM_231 1262 -#define IMG_CUSTOM_231_EDITOR 1263 -#define IMG_CUSTOM_232 1264 -#define IMG_CUSTOM_232_EDITOR 1265 -#define IMG_CUSTOM_233 1266 -#define IMG_CUSTOM_233_EDITOR 1267 -#define IMG_CUSTOM_234 1268 -#define IMG_CUSTOM_234_EDITOR 1269 -#define IMG_CUSTOM_235 1270 -#define IMG_CUSTOM_235_EDITOR 1271 -#define IMG_CUSTOM_236 1272 -#define IMG_CUSTOM_236_EDITOR 1273 -#define IMG_CUSTOM_237 1274 -#define IMG_CUSTOM_237_EDITOR 1275 -#define IMG_CUSTOM_238 1276 -#define IMG_CUSTOM_238_EDITOR 1277 -#define IMG_CUSTOM_239 1278 -#define IMG_CUSTOM_239_EDITOR 1279 -#define IMG_CUSTOM_240 1280 -#define IMG_CUSTOM_240_EDITOR 1281 -#define IMG_CUSTOM_241 1282 -#define IMG_CUSTOM_241_EDITOR 1283 -#define IMG_CUSTOM_242 1284 -#define IMG_CUSTOM_242_EDITOR 1285 -#define IMG_CUSTOM_243 1286 -#define IMG_CUSTOM_243_EDITOR 1287 -#define IMG_CUSTOM_244 1288 -#define IMG_CUSTOM_244_EDITOR 1289 -#define IMG_CUSTOM_245 1290 -#define IMG_CUSTOM_245_EDITOR 1291 -#define IMG_CUSTOM_246 1292 -#define IMG_CUSTOM_246_EDITOR 1293 -#define IMG_CUSTOM_247 1294 -#define IMG_CUSTOM_247_EDITOR 1295 -#define IMG_CUSTOM_248 1296 -#define IMG_CUSTOM_248_EDITOR 1297 -#define IMG_CUSTOM_249 1298 -#define IMG_CUSTOM_249_EDITOR 1299 -#define IMG_CUSTOM_250 1300 -#define IMG_CUSTOM_250_EDITOR 1301 -#define IMG_CUSTOM_251 1302 -#define IMG_CUSTOM_251_EDITOR 1303 -#define IMG_CUSTOM_252 1304 -#define IMG_CUSTOM_252_EDITOR 1305 -#define IMG_CUSTOM_253 1306 -#define IMG_CUSTOM_253_EDITOR 1307 -#define IMG_CUSTOM_254 1308 -#define IMG_CUSTOM_254_EDITOR 1309 -#define IMG_CUSTOM_255 1310 -#define IMG_CUSTOM_255_EDITOR 1311 -#define IMG_CUSTOM_256 1312 -#define IMG_CUSTOM_256_EDITOR 1313 -#define IMG_GROUP_1 1314 -#define IMG_GROUP_1_EDITOR 1315 -#define IMG_GROUP_2 1316 -#define IMG_GROUP_2_EDITOR 1317 -#define IMG_GROUP_3 1318 -#define IMG_GROUP_3_EDITOR 1319 -#define IMG_GROUP_4 1320 -#define IMG_GROUP_4_EDITOR 1321 -#define IMG_GROUP_5 1322 -#define IMG_GROUP_5_EDITOR 1323 -#define IMG_GROUP_6 1324 -#define IMG_GROUP_6_EDITOR 1325 -#define IMG_GROUP_7 1326 -#define IMG_GROUP_7_EDITOR 1327 -#define IMG_GROUP_8 1328 -#define IMG_GROUP_8_EDITOR 1329 -#define IMG_GROUP_9 1330 -#define IMG_GROUP_9_EDITOR 1331 -#define IMG_GROUP_10 1332 -#define IMG_GROUP_10_EDITOR 1333 -#define IMG_GROUP_11 1334 -#define IMG_GROUP_11_EDITOR 1335 -#define IMG_GROUP_12 1336 -#define IMG_GROUP_12_EDITOR 1337 -#define IMG_GROUP_13 1338 -#define IMG_GROUP_13_EDITOR 1339 -#define IMG_GROUP_14 1340 -#define IMG_GROUP_14_EDITOR 1341 -#define IMG_GROUP_15 1342 -#define IMG_GROUP_15_EDITOR 1343 -#define IMG_GROUP_16 1344 -#define IMG_GROUP_16_EDITOR 1345 -#define IMG_GROUP_17 1346 -#define IMG_GROUP_17_EDITOR 1347 -#define IMG_GROUP_18 1348 -#define IMG_GROUP_18_EDITOR 1349 -#define IMG_GROUP_19 1350 -#define IMG_GROUP_19_EDITOR 1351 -#define IMG_GROUP_20 1352 -#define IMG_GROUP_20_EDITOR 1353 -#define IMG_GROUP_21 1354 -#define IMG_GROUP_21_EDITOR 1355 -#define IMG_GROUP_22 1356 -#define IMG_GROUP_22_EDITOR 1357 -#define IMG_GROUP_23 1358 -#define IMG_GROUP_23_EDITOR 1359 -#define IMG_GROUP_24 1360 -#define IMG_GROUP_24_EDITOR 1361 -#define IMG_GROUP_25 1362 -#define IMG_GROUP_25_EDITOR 1363 -#define IMG_GROUP_26 1364 -#define IMG_GROUP_26_EDITOR 1365 -#define IMG_GROUP_27 1366 -#define IMG_GROUP_27_EDITOR 1367 -#define IMG_GROUP_28 1368 -#define IMG_GROUP_28_EDITOR 1369 -#define IMG_GROUP_29 1370 -#define IMG_GROUP_29_EDITOR 1371 -#define IMG_GROUP_30 1372 -#define IMG_GROUP_30_EDITOR 1373 -#define IMG_GROUP_31 1374 -#define IMG_GROUP_31_EDITOR 1375 -#define IMG_GROUP_32 1376 -#define IMG_GROUP_32_EDITOR 1377 -#define IMG_EMC_OBJECT 1378 -#define IMG_EMC_SPRITE 1379 -#define IMG_TOON_1 1380 -#define IMG_TOON_2 1381 -#define IMG_TOON_3 1382 -#define IMG_TOON_4 1383 -#define IMG_TOON_5 1384 -#define IMG_TOON_6 1385 -#define IMG_TOON_7 1386 -#define IMG_TOON_8 1387 -#define IMG_TOON_9 1388 -#define IMG_TOON_10 1389 -#define IMG_TOON_11 1390 -#define IMG_TOON_12 1391 -#define IMG_TOON_13 1392 -#define IMG_TOON_14 1393 -#define IMG_TOON_15 1394 -#define IMG_TOON_16 1395 -#define IMG_TOON_17 1396 -#define IMG_TOON_18 1397 -#define IMG_TOON_19 1398 -#define IMG_TOON_20 1399 -#define IMG_MENU_CALIBRATE_RED 1400 -#define IMG_MENU_CALIBRATE_BLUE 1401 -#define IMG_MENU_CALIBRATE_YELLOW 1402 -#define IMG_MENU_BUTTON 1403 -#define IMG_MENU_BUTTON_ACTIVE 1404 -#define IMG_MENU_BUTTON_LEFT 1405 -#define IMG_MENU_BUTTON_RIGHT 1406 -#define IMG_MENU_BUTTON_UP 1407 -#define IMG_MENU_BUTTON_DOWN 1408 -#define IMG_MENU_BUTTON_LEFT_ACTIVE 1409 -#define IMG_MENU_BUTTON_RIGHT_ACTIVE 1410 -#define IMG_MENU_BUTTON_UP_ACTIVE 1411 -#define IMG_MENU_BUTTON_DOWN_ACTIVE 1412 -#define IMG_MENU_SCROLLBAR 1413 -#define IMG_MENU_SCROLLBAR_ACTIVE 1414 -#define IMG_FONT_INITIAL_1 1415 -#define IMG_FONT_INITIAL_2 1416 -#define IMG_FONT_INITIAL_3 1417 -#define IMG_FONT_INITIAL_4 1418 -#define IMG_FONT_TITLE_1 1419 -#define IMG_FONT_TITLE_1_LEVELS 1420 -#define IMG_FONT_TITLE_2 1421 -#define IMG_FONT_MENU_1 1422 -#define IMG_FONT_MENU_2 1423 -#define IMG_FONT_TEXT_1 1424 -#define IMG_FONT_TEXT_1_LEVELS 1425 -#define IMG_FONT_TEXT_1_PREVIEW 1426 -#define IMG_FONT_TEXT_1_SCORES 1427 -#define IMG_FONT_TEXT_1_ACTIVE_SCORES 1428 -#define IMG_FONT_TEXT_2 1429 -#define IMG_FONT_TEXT_2_LEVELS 1430 -#define IMG_FONT_TEXT_2_PREVIEW 1431 -#define IMG_FONT_TEXT_2_SCORES 1432 -#define IMG_FONT_TEXT_2_ACTIVE_SCORES 1433 -#define IMG_FONT_TEXT_3 1434 -#define IMG_FONT_TEXT_3_LEVELS 1435 -#define IMG_FONT_TEXT_3_PREVIEW 1436 -#define IMG_FONT_TEXT_3_SCORES 1437 -#define IMG_FONT_TEXT_3_ACTIVE_SCORES 1438 -#define IMG_FONT_TEXT_4 1439 -#define IMG_FONT_TEXT_4_LEVELS 1440 -#define IMG_FONT_TEXT_4_SCORES 1441 -#define IMG_FONT_TEXT_4_ACTIVE_SCORES 1442 -#define IMG_FONT_ENVELOPE_1 1443 -#define IMG_FONT_ENVELOPE_2 1444 -#define IMG_FONT_ENVELOPE_3 1445 -#define IMG_FONT_ENVELOPE_4 1446 -#define IMG_FONT_INPUT_1 1447 -#define IMG_FONT_INPUT_1_MAIN 1448 -#define IMG_FONT_INPUT_1_ACTIVE 1449 -#define IMG_FONT_INPUT_1_ACTIVE_MAIN 1450 -#define IMG_FONT_INPUT_1_ACTIVE_SETUP 1451 -#define IMG_FONT_INPUT_2 1452 -#define IMG_FONT_INPUT_2_ACTIVE 1453 -#define IMG_FONT_OPTION_OFF 1454 -#define IMG_FONT_OPTION_ON 1455 -#define IMG_FONT_VALUE_1 1456 -#define IMG_FONT_VALUE_2 1457 -#define IMG_FONT_VALUE_OLD 1458 -#define IMG_FONT_LEVEL_NUMBER 1459 -#define IMG_FONT_TAPE_RECORDER 1460 -#define IMG_FONT_GAME_INFO 1461 -#define IMG_GLOBAL_BORDER 1462 -#define IMG_GLOBAL_DOOR 1463 -#define IMG_EDITOR_ELEMENT_BORDER 1464 -#define IMG_EDITOR_ELEMENT_BORDER_INPUT 1465 -#define IMG_BACKGROUND_ENVELOPE_1 1466 -#define IMG_BACKGROUND_ENVELOPE_2 1467 -#define IMG_BACKGROUND_ENVELOPE_3 1468 -#define IMG_BACKGROUND_ENVELOPE_4 1469 -#define IMG_BACKGROUND 1470 -#define IMG_BACKGROUND_MAIN 1471 -#define IMG_BACKGROUND_LEVELS 1472 -#define IMG_BACKGROUND_SCORES 1473 -#define IMG_BACKGROUND_EDITOR 1474 -#define IMG_BACKGROUND_INFO 1475 -#define IMG_BACKGROUND_INFO_ELEMENTS 1476 -#define IMG_BACKGROUND_SETUP 1477 -#define IMG_BACKGROUND_DOOR 1478 +#define IMG_EM_GATE_1_GRAY_ACTIVE 261 +#define IMG_EM_GATE_2_GRAY 262 +#define IMG_EM_GATE_2_GRAY_EDITOR 263 +#define IMG_EM_GATE_2_GRAY_ACTIVE 264 +#define IMG_EM_GATE_3_GRAY 265 +#define IMG_EM_GATE_3_GRAY_EDITOR 266 +#define IMG_EM_GATE_3_GRAY_ACTIVE 267 +#define IMG_EM_GATE_4_GRAY 268 +#define IMG_EM_GATE_4_GRAY_EDITOR 269 +#define IMG_EM_GATE_4_GRAY_ACTIVE 270 +#define IMG_EXIT_CLOSED 271 +#define IMG_EXIT_OPENING 272 +#define IMG_EXIT_OPEN 273 +#define IMG_EXIT_CLOSING 274 +#define IMG_BALLOON 275 +#define IMG_BALLOON_MOVING 276 +#define IMG_BALLOON_PUSHING 277 +#define IMG_BALLOON_SWITCH_LEFT 278 +#define IMG_BALLOON_SWITCH_RIGHT 279 +#define IMG_BALLOON_SWITCH_UP 280 +#define IMG_BALLOON_SWITCH_DOWN 281 +#define IMG_BALLOON_SWITCH_ANY 282 +#define IMG_BALLOON_SWITCH_NONE 283 +#define IMG_SPRING 284 +#define IMG_EMC_STEELWALL_1 285 +#define IMG_EMC_STEELWALL_2 286 +#define IMG_EMC_STEELWALL_3 287 +#define IMG_EMC_STEELWALL_4 288 +#define IMG_EMC_WALL_1 289 +#define IMG_EMC_WALL_2 290 +#define IMG_EMC_WALL_3 291 +#define IMG_EMC_WALL_4 292 +#define IMG_EMC_WALL_5 293 +#define IMG_EMC_WALL_6 294 +#define IMG_EMC_WALL_7 295 +#define IMG_EMC_WALL_8 296 +#define IMG_INVISIBLE_STEELWALL 297 +#define IMG_INVISIBLE_STEELWALL_EDITOR 298 +#define IMG_INVISIBLE_STEELWALL_ACTIVE 299 +#define IMG_INVISIBLE_WALL 300 +#define IMG_INVISIBLE_WALL_EDITOR 301 +#define IMG_INVISIBLE_WALL_ACTIVE 302 +#define IMG_INVISIBLE_SAND 303 +#define IMG_INVISIBLE_SAND_EDITOR 304 +#define IMG_INVISIBLE_SAND_ACTIVE 305 +#define IMG_INVISIBLE_SAND_ACTIVE_CRUMBLED 306 +#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_LEFT 307 +#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_RIGHT 308 +#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_UP 309 +#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_DOWN 310 +#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_LEFT_CRUMBLED 311 +#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_RIGHT_CRUMBLED 312 +#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_UP_CRUMBLED 313 +#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_DOWN_CRUMBLED 314 +#define IMG_CONVEYOR_BELT_1_MIDDLE 315 +#define IMG_CONVEYOR_BELT_1_MIDDLE_ACTIVE 316 +#define IMG_CONVEYOR_BELT_1_LEFT 317 +#define IMG_CONVEYOR_BELT_1_LEFT_ACTIVE 318 +#define IMG_CONVEYOR_BELT_1_RIGHT 319 +#define IMG_CONVEYOR_BELT_1_RIGHT_ACTIVE 320 +#define IMG_CONVEYOR_BELT_1_SWITCH_LEFT 321 +#define IMG_CONVEYOR_BELT_1_SWITCH_MIDDLE 322 +#define IMG_CONVEYOR_BELT_1_SWITCH_RIGHT 323 +#define IMG_CONVEYOR_BELT_2_MIDDLE 324 +#define IMG_CONVEYOR_BELT_2_MIDDLE_ACTIVE 325 +#define IMG_CONVEYOR_BELT_2_LEFT 326 +#define IMG_CONVEYOR_BELT_2_LEFT_ACTIVE 327 +#define IMG_CONVEYOR_BELT_2_RIGHT 328 +#define IMG_CONVEYOR_BELT_2_RIGHT_ACTIVE 329 +#define IMG_CONVEYOR_BELT_2_SWITCH_LEFT 330 +#define IMG_CONVEYOR_BELT_2_SWITCH_MIDDLE 331 +#define IMG_CONVEYOR_BELT_2_SWITCH_RIGHT 332 +#define IMG_CONVEYOR_BELT_3_MIDDLE 333 +#define IMG_CONVEYOR_BELT_3_MIDDLE_ACTIVE 334 +#define IMG_CONVEYOR_BELT_3_LEFT 335 +#define IMG_CONVEYOR_BELT_3_LEFT_ACTIVE 336 +#define IMG_CONVEYOR_BELT_3_RIGHT 337 +#define IMG_CONVEYOR_BELT_3_RIGHT_ACTIVE 338 +#define IMG_CONVEYOR_BELT_3_SWITCH_LEFT 339 +#define IMG_CONVEYOR_BELT_3_SWITCH_MIDDLE 340 +#define IMG_CONVEYOR_BELT_3_SWITCH_RIGHT 341 +#define IMG_CONVEYOR_BELT_4_MIDDLE 342 +#define IMG_CONVEYOR_BELT_4_MIDDLE_ACTIVE 343 +#define IMG_CONVEYOR_BELT_4_LEFT 344 +#define IMG_CONVEYOR_BELT_4_LEFT_ACTIVE 345 +#define IMG_CONVEYOR_BELT_4_RIGHT 346 +#define IMG_CONVEYOR_BELT_4_RIGHT_ACTIVE 347 +#define IMG_CONVEYOR_BELT_4_SWITCH_LEFT 348 +#define IMG_CONVEYOR_BELT_4_SWITCH_MIDDLE 349 +#define IMG_CONVEYOR_BELT_4_SWITCH_RIGHT 350 +#define IMG_SWITCHGATE_SWITCH_UP 351 +#define IMG_SWITCHGATE_SWITCH_DOWN 352 +#define IMG_LIGHT_SWITCH 353 +#define IMG_LIGHT_SWITCH_ACTIVE 354 +#define IMG_TIMEGATE_SWITCH 355 +#define IMG_TIMEGATE_SWITCH_ACTIVE 356 +#define IMG_ENVELOPE_1 357 +#define IMG_ENVELOPE_1_COLLECTING 358 +#define IMG_ENVELOPE_2 359 +#define IMG_ENVELOPE_2_COLLECTING 360 +#define IMG_ENVELOPE_3 361 +#define IMG_ENVELOPE_3_COLLECTING 362 +#define IMG_ENVELOPE_4 363 +#define IMG_ENVELOPE_4_COLLECTING 364 +#define IMG_SIGN_EXCLAMATION 365 +#define IMG_SIGN_STOP 366 +#define IMG_LANDMINE 367 +#define IMG_STEELWALL_SLIPPERY 368 +#define IMG_EXTRA_TIME 369 +#define IMG_SHIELD_NORMAL 370 +#define IMG_SHIELD_NORMAL_ACTIVE 371 +#define IMG_SHIELD_DEADLY 372 +#define IMG_SHIELD_DEADLY_ACTIVE 373 +#define IMG_SWITCHGATE_CLOSED 374 +#define IMG_SWITCHGATE_OPENING 375 +#define IMG_SWITCHGATE_OPEN 376 +#define IMG_SWITCHGATE_CLOSING 377 +#define IMG_TIMEGATE_CLOSED 378 +#define IMG_TIMEGATE_OPENING 379 +#define IMG_TIMEGATE_OPEN 380 +#define IMG_TIMEGATE_CLOSING 381 +#define IMG_PEARL 382 +#define IMG_PEARL_BREAKING 383 +#define IMG_CRYSTAL 384 +#define IMG_WALL_PEARL 385 +#define IMG_WALL_CRYSTAL 386 +#define IMG_TUBE_RIGHT_DOWN 387 +#define IMG_TUBE_HORIZONTAL_DOWN 388 +#define IMG_TUBE_LEFT_DOWN 389 +#define IMG_TUBE_HORIZONTAL 390 +#define IMG_TUBE_VERTICAL_RIGHT 391 +#define IMG_TUBE_ANY 392 +#define IMG_TUBE_VERTICAL_LEFT 393 +#define IMG_TUBE_VERTICAL 394 +#define IMG_TUBE_RIGHT_UP 395 +#define IMG_TUBE_HORIZONTAL_UP 396 +#define IMG_TUBE_LEFT_UP 397 +#define IMG_TRAP 398 +#define IMG_TRAP_ACTIVE 399 +#define IMG_DX_SUPABOMB 400 +#define IMG_KEY_1 401 +#define IMG_KEY_1_EDITOR 402 +#define IMG_KEY_2 403 +#define IMG_KEY_2_EDITOR 404 +#define IMG_KEY_3 405 +#define IMG_KEY_3_EDITOR 406 +#define IMG_KEY_4 407 +#define IMG_KEY_4_EDITOR 408 +#define IMG_GATE_1 409 +#define IMG_GATE_2 410 +#define IMG_GATE_3 411 +#define IMG_GATE_4 412 +#define IMG_GATE_1_GRAY 413 +#define IMG_GATE_1_GRAY_EDITOR 414 +#define IMG_GATE_1_GRAY_ACTIVE 415 +#define IMG_GATE_2_GRAY 416 +#define IMG_GATE_2_GRAY_EDITOR 417 +#define IMG_GATE_2_GRAY_ACTIVE 418 +#define IMG_GATE_3_GRAY 419 +#define IMG_GATE_3_GRAY_EDITOR 420 +#define IMG_GATE_3_GRAY_ACTIVE 421 +#define IMG_GATE_4_GRAY 422 +#define IMG_GATE_4_GRAY_EDITOR 423 +#define IMG_GATE_4_GRAY_ACTIVE 424 +#define IMG_GAME_OF_LIFE 425 +#define IMG_BIOMAZE 426 +#define IMG_PACMAN 427 +#define IMG_PACMAN_RIGHT 428 +#define IMG_PACMAN_UP 429 +#define IMG_PACMAN_LEFT 430 +#define IMG_PACMAN_DOWN 431 +#define IMG_PACMAN_TURNING_FROM_RIGHT 432 +#define IMG_PACMAN_TURNING_FROM_UP 433 +#define IMG_PACMAN_TURNING_FROM_LEFT 434 +#define IMG_PACMAN_TURNING_FROM_DOWN 435 +#define IMG_LAMP 436 +#define IMG_LAMP_EDITOR 437 +#define IMG_LAMP_ACTIVE 438 +#define IMG_TIME_ORB_FULL 439 +#define IMG_TIME_ORB_EMPTY 440 +#define IMG_EMERALD_YELLOW 441 +#define IMG_EMERALD_YELLOW_MOVING 442 +#define IMG_EMERALD_YELLOW_FALLING 443 +#define IMG_EMERALD_RED 444 +#define IMG_EMERALD_RED_MOVING 445 +#define IMG_EMERALD_RED_FALLING 446 +#define IMG_EMERALD_PURPLE 447 +#define IMG_EMERALD_PURPLE_MOVING 448 +#define IMG_EMERALD_PURPLE_FALLING 449 +#define IMG_WALL_EMERALD_YELLOW 450 +#define IMG_WALL_EMERALD_RED 451 +#define IMG_WALL_EMERALD_PURPLE 452 +#define IMG_WALL_BD_DIAMOND 453 +#define IMG_EXPANDABLE_WALL 454 +#define IMG_EXPANDABLE_WALL_HORIZONTAL 455 +#define IMG_EXPANDABLE_WALL_HORIZONTAL_EDITOR 456 +#define IMG_EXPANDABLE_WALL_VERTICAL 457 +#define IMG_EXPANDABLE_WALL_VERTICAL_EDITOR 458 +#define IMG_EXPANDABLE_WALL_ANY 459 +#define IMG_EXPANDABLE_WALL_ANY_EDITOR 460 +#define IMG_EXPANDABLE_WALL_GROWING_LEFT 461 +#define IMG_EXPANDABLE_WALL_GROWING_RIGHT 462 +#define IMG_EXPANDABLE_WALL_GROWING_UP 463 +#define IMG_EXPANDABLE_WALL_GROWING_DOWN 464 +#define IMG_BLACK_ORB 465 +#define IMG_SPEED_PILL 466 +#define IMG_DARK_YAMYAM 467 +#define IMG_DYNABOMB 468 +#define IMG_DYNABOMB_ACTIVE 469 +#define IMG_DYNABOMB_PLAYER_1 470 +#define IMG_DYNABOMB_PLAYER_1_ACTIVE 471 +#define IMG_DYNABOMB_PLAYER_2 472 +#define IMG_DYNABOMB_PLAYER_2_ACTIVE 473 +#define IMG_DYNABOMB_PLAYER_3 474 +#define IMG_DYNABOMB_PLAYER_3_ACTIVE 475 +#define IMG_DYNABOMB_PLAYER_4 476 +#define IMG_DYNABOMB_PLAYER_4_ACTIVE 477 +#define IMG_DYNABOMB_INCREASE_NUMBER 478 +#define IMG_DYNABOMB_INCREASE_SIZE 479 +#define IMG_DYNABOMB_INCREASE_POWER 480 +#define IMG_PIG 481 +#define IMG_PIG_DOWN 482 +#define IMG_PIG_UP 483 +#define IMG_PIG_LEFT 484 +#define IMG_PIG_RIGHT 485 +#define IMG_PIG_MOVING_DOWN 486 +#define IMG_PIG_MOVING_UP 487 +#define IMG_PIG_MOVING_LEFT 488 +#define IMG_PIG_MOVING_RIGHT 489 +#define IMG_PIG_DIGGING_DOWN 490 +#define IMG_PIG_DIGGING_UP 491 +#define IMG_PIG_DIGGING_LEFT 492 +#define IMG_PIG_DIGGING_RIGHT 493 +#define IMG_DRAGON 494 +#define IMG_DRAGON_DOWN 495 +#define IMG_DRAGON_UP 496 +#define IMG_DRAGON_LEFT 497 +#define IMG_DRAGON_RIGHT 498 +#define IMG_DRAGON_MOVING_DOWN 499 +#define IMG_DRAGON_MOVING_UP 500 +#define IMG_DRAGON_MOVING_LEFT 501 +#define IMG_DRAGON_MOVING_RIGHT 502 +#define IMG_DRAGON_ATTACKING_DOWN 503 +#define IMG_DRAGON_ATTACKING_UP 504 +#define IMG_DRAGON_ATTACKING_LEFT 505 +#define IMG_DRAGON_ATTACKING_RIGHT 506 +#define IMG_MOLE 507 +#define IMG_MOLE_DOWN 508 +#define IMG_MOLE_UP 509 +#define IMG_MOLE_LEFT 510 +#define IMG_MOLE_RIGHT 511 +#define IMG_MOLE_MOVING_DOWN 512 +#define IMG_MOLE_MOVING_UP 513 +#define IMG_MOLE_MOVING_LEFT 514 +#define IMG_MOLE_MOVING_RIGHT 515 +#define IMG_MOLE_DIGGING_DOWN 516 +#define IMG_MOLE_DIGGING_UP 517 +#define IMG_MOLE_DIGGING_LEFT 518 +#define IMG_MOLE_DIGGING_RIGHT 519 +#define IMG_PENGUIN 520 +#define IMG_PENGUIN_EDITOR 521 +#define IMG_PENGUIN_DOWN 522 +#define IMG_PENGUIN_UP 523 +#define IMG_PENGUIN_LEFT 524 +#define IMG_PENGUIN_RIGHT 525 +#define IMG_PENGUIN_MOVING_DOWN 526 +#define IMG_PENGUIN_MOVING_UP 527 +#define IMG_PENGUIN_MOVING_LEFT 528 +#define IMG_PENGUIN_MOVING_RIGHT 529 +#define IMG_SATELLITE 530 +#define IMG_FLAMES_1_LEFT 531 +#define IMG_FLAMES_2_LEFT 532 +#define IMG_FLAMES_3_LEFT 533 +#define IMG_FLAMES_1_RIGHT 534 +#define IMG_FLAMES_2_RIGHT 535 +#define IMG_FLAMES_3_RIGHT 536 +#define IMG_FLAMES_1_UP 537 +#define IMG_FLAMES_2_UP 538 +#define IMG_FLAMES_3_UP 539 +#define IMG_FLAMES_1_DOWN 540 +#define IMG_FLAMES_2_DOWN 541 +#define IMG_FLAMES_3_DOWN 542 +#define IMG_STONEBLOCK 543 +#define IMG_PLAYER_1 544 +#define IMG_PLAYER_1_EDITOR 545 +#define IMG_PLAYER_1_DOWN 546 +#define IMG_PLAYER_1_UP 547 +#define IMG_PLAYER_1_LEFT 548 +#define IMG_PLAYER_1_RIGHT 549 +#define IMG_PLAYER_1_MOVING_DOWN 550 +#define IMG_PLAYER_1_MOVING_UP 551 +#define IMG_PLAYER_1_MOVING_LEFT 552 +#define IMG_PLAYER_1_MOVING_RIGHT 553 +#define IMG_PLAYER_1_DIGGING_DOWN 554 +#define IMG_PLAYER_1_DIGGING_UP 555 +#define IMG_PLAYER_1_DIGGING_LEFT 556 +#define IMG_PLAYER_1_DIGGING_RIGHT 557 +#define IMG_PLAYER_1_COLLECTING_DOWN 558 +#define IMG_PLAYER_1_COLLECTING_UP 559 +#define IMG_PLAYER_1_COLLECTING_LEFT 560 +#define IMG_PLAYER_1_COLLECTING_RIGHT 561 +#define IMG_PLAYER_1_PUSHING_DOWN 562 +#define IMG_PLAYER_1_PUSHING_UP 563 +#define IMG_PLAYER_1_PUSHING_LEFT 564 +#define IMG_PLAYER_1_PUSHING_RIGHT 565 +#define IMG_PLAYER_1_SNAPPING_DOWN 566 +#define IMG_PLAYER_1_SNAPPING_UP 567 +#define IMG_PLAYER_1_SNAPPING_LEFT 568 +#define IMG_PLAYER_1_SNAPPING_RIGHT 569 +#define IMG_PLAYER_2 570 +#define IMG_PLAYER_2_EDITOR 571 +#define IMG_PLAYER_2_DOWN 572 +#define IMG_PLAYER_2_UP 573 +#define IMG_PLAYER_2_LEFT 574 +#define IMG_PLAYER_2_RIGHT 575 +#define IMG_PLAYER_2_MOVING_DOWN 576 +#define IMG_PLAYER_2_MOVING_UP 577 +#define IMG_PLAYER_2_MOVING_LEFT 578 +#define IMG_PLAYER_2_MOVING_RIGHT 579 +#define IMG_PLAYER_2_DIGGING_DOWN 580 +#define IMG_PLAYER_2_DIGGING_UP 581 +#define IMG_PLAYER_2_DIGGING_LEFT 582 +#define IMG_PLAYER_2_DIGGING_RIGHT 583 +#define IMG_PLAYER_2_COLLECTING_DOWN 584 +#define IMG_PLAYER_2_COLLECTING_UP 585 +#define IMG_PLAYER_2_COLLECTING_LEFT 586 +#define IMG_PLAYER_2_COLLECTING_RIGHT 587 +#define IMG_PLAYER_2_PUSHING_DOWN 588 +#define IMG_PLAYER_2_PUSHING_UP 589 +#define IMG_PLAYER_2_PUSHING_LEFT 590 +#define IMG_PLAYER_2_PUSHING_RIGHT 591 +#define IMG_PLAYER_2_SNAPPING_DOWN 592 +#define IMG_PLAYER_2_SNAPPING_UP 593 +#define IMG_PLAYER_2_SNAPPING_LEFT 594 +#define IMG_PLAYER_2_SNAPPING_RIGHT 595 +#define IMG_PLAYER_3 596 +#define IMG_PLAYER_3_EDITOR 597 +#define IMG_PLAYER_3_DOWN 598 +#define IMG_PLAYER_3_UP 599 +#define IMG_PLAYER_3_LEFT 600 +#define IMG_PLAYER_3_RIGHT 601 +#define IMG_PLAYER_3_MOVING_DOWN 602 +#define IMG_PLAYER_3_MOVING_UP 603 +#define IMG_PLAYER_3_MOVING_LEFT 604 +#define IMG_PLAYER_3_MOVING_RIGHT 605 +#define IMG_PLAYER_3_DIGGING_DOWN 606 +#define IMG_PLAYER_3_DIGGING_UP 607 +#define IMG_PLAYER_3_DIGGING_LEFT 608 +#define IMG_PLAYER_3_DIGGING_RIGHT 609 +#define IMG_PLAYER_3_COLLECTING_DOWN 610 +#define IMG_PLAYER_3_COLLECTING_UP 611 +#define IMG_PLAYER_3_COLLECTING_LEFT 612 +#define IMG_PLAYER_3_COLLECTING_RIGHT 613 +#define IMG_PLAYER_3_PUSHING_DOWN 614 +#define IMG_PLAYER_3_PUSHING_UP 615 +#define IMG_PLAYER_3_PUSHING_LEFT 616 +#define IMG_PLAYER_3_PUSHING_RIGHT 617 +#define IMG_PLAYER_3_SNAPPING_DOWN 618 +#define IMG_PLAYER_3_SNAPPING_UP 619 +#define IMG_PLAYER_3_SNAPPING_LEFT 620 +#define IMG_PLAYER_3_SNAPPING_RIGHT 621 +#define IMG_PLAYER_4 622 +#define IMG_PLAYER_4_EDITOR 623 +#define IMG_PLAYER_4_DOWN 624 +#define IMG_PLAYER_4_UP 625 +#define IMG_PLAYER_4_LEFT 626 +#define IMG_PLAYER_4_RIGHT 627 +#define IMG_PLAYER_4_MOVING_DOWN 628 +#define IMG_PLAYER_4_MOVING_UP 629 +#define IMG_PLAYER_4_MOVING_LEFT 630 +#define IMG_PLAYER_4_MOVING_RIGHT 631 +#define IMG_PLAYER_4_DIGGING_DOWN 632 +#define IMG_PLAYER_4_DIGGING_UP 633 +#define IMG_PLAYER_4_DIGGING_LEFT 634 +#define IMG_PLAYER_4_DIGGING_RIGHT 635 +#define IMG_PLAYER_4_COLLECTING_DOWN 636 +#define IMG_PLAYER_4_COLLECTING_UP 637 +#define IMG_PLAYER_4_COLLECTING_LEFT 638 +#define IMG_PLAYER_4_COLLECTING_RIGHT 639 +#define IMG_PLAYER_4_PUSHING_DOWN 640 +#define IMG_PLAYER_4_PUSHING_UP 641 +#define IMG_PLAYER_4_PUSHING_LEFT 642 +#define IMG_PLAYER_4_PUSHING_RIGHT 643 +#define IMG_PLAYER_4_SNAPPING_DOWN 644 +#define IMG_PLAYER_4_SNAPPING_UP 645 +#define IMG_PLAYER_4_SNAPPING_LEFT 646 +#define IMG_PLAYER_4_SNAPPING_RIGHT 647 +#define IMG_DEFAULT_EXPLODING 648 +#define IMG_TWINKLE_BLUE 649 +#define IMG_TWINKLE_WHITE 650 +#define IMG_STEELWALL_TOPLEFT 651 +#define IMG_STEELWALL_TOPRIGHT 652 +#define IMG_STEELWALL_BOTTOMLEFT 653 +#define IMG_STEELWALL_BOTTOMRIGHT 654 +#define IMG_STEELWALL_HORIZONTAL 655 +#define IMG_STEELWALL_VERTICAL 656 +#define IMG_STEELWALL_TOPLEFT_EDITOR 657 +#define IMG_STEELWALL_TOPRIGHT_EDITOR 658 +#define IMG_STEELWALL_BOTTOMLEFT_EDITOR 659 +#define IMG_STEELWALL_BOTTOMRIGHT_EDITOR 660 +#define IMG_STEELWALL_HORIZONTAL_EDITOR 661 +#define IMG_STEELWALL_VERTICAL_EDITOR 662 +#define IMG_INVISIBLE_STEELWALL_TOPLEFT 663 +#define IMG_INVISIBLE_STEELWALL_TOPRIGHT 664 +#define IMG_INVISIBLE_STEELWALL_BOTTOMLEFT 665 +#define IMG_INVISIBLE_STEELWALL_BOTTOMRIGHT 666 +#define IMG_INVISIBLE_STEELWALL_HORIZONTAL 667 +#define IMG_INVISIBLE_STEELWALL_VERTICAL 668 +#define IMG_INVISIBLE_STEELWALL_TOPLEFT_EDITOR 669 +#define IMG_INVISIBLE_STEELWALL_TOPRIGHT_EDITOR 670 +#define IMG_INVISIBLE_STEELWALL_BOTTOMLEFT_EDITOR 671 +#define IMG_INVISIBLE_STEELWALL_BOTTOMRIGHT_EDITOR 672 +#define IMG_INVISIBLE_STEELWALL_HORIZONTAL_EDITOR 673 +#define IMG_INVISIBLE_STEELWALL_VERTICAL_EDITOR 674 +#define IMG_ARROW_LEFT 675 +#define IMG_ARROW_RIGHT 676 +#define IMG_ARROW_UP 677 +#define IMG_ARROW_DOWN 678 +#define IMG_UNKNOWN 679 +#define IMG_TRIGGER_ELEMENT 680 +#define IMG_TRIGGER_PLAYER 681 +#define IMG_EMC_KEY_5 682 +#define IMG_EMC_KEY_6 683 +#define IMG_EMC_KEY_7 684 +#define IMG_EMC_KEY_8 685 +#define IMG_EMC_GATE_5 686 +#define IMG_EMC_GATE_6 687 +#define IMG_EMC_GATE_7 688 +#define IMG_EMC_GATE_8 689 +#define IMG_EMC_GATE_5_GRAY 690 +#define IMG_EMC_GATE_5_GRAY_EDITOR 691 +#define IMG_EMC_GATE_5_GRAY_ACTIVE 692 +#define IMG_EMC_GATE_6_GRAY 693 +#define IMG_EMC_GATE_6_GRAY_EDITOR 694 +#define IMG_EMC_GATE_6_GRAY_ACTIVE 695 +#define IMG_EMC_GATE_7_GRAY 696 +#define IMG_EMC_GATE_7_GRAY_EDITOR 697 +#define IMG_EMC_GATE_7_GRAY_ACTIVE 698 +#define IMG_EMC_GATE_8_GRAY 699 +#define IMG_EMC_GATE_8_GRAY_EDITOR 700 +#define IMG_EMC_GATE_8_GRAY_ACTIVE 701 +#define IMG_EMC_ANDROID 702 +#define IMG_EMC_GRASS 703 +#define IMG_EMC_GRASS_CRUMBLED 704 +#define IMG_EMC_GRASS_DIGGING_LEFT 705 +#define IMG_EMC_GRASS_DIGGING_RIGHT 706 +#define IMG_EMC_GRASS_DIGGING_UP 707 +#define IMG_EMC_GRASS_DIGGING_DOWN 708 +#define IMG_EMC_GRASS_DIGGING_LEFT_CRUMBLED 709 +#define IMG_EMC_GRASS_DIGGING_RIGHT_CRUMBLED 710 +#define IMG_EMC_GRASS_DIGGING_UP_CRUMBLED 711 +#define IMG_EMC_GRASS_DIGGING_DOWN_CRUMBLED 712 +#define IMG_EMC_MAGIC_BALL 713 +#define IMG_EMC_MAGIC_BALL_ACTIVE 714 +#define IMG_EMC_MAGIC_BALL_DROPPING 715 +#define IMG_EMC_MAGIC_BALL_SWITCH 716 +#define IMG_EMC_MAGIC_BALL_SWITCH_ACTIVE 717 +#define IMG_EMC_SPRING_BUMPER 718 +#define IMG_EMC_SPRING_BUMPER_ACTIVE 719 +#define IMG_EMC_PLANT 720 +#define IMG_EMC_PLANT_CRUMBLED 721 +#define IMG_EMC_LENSES 722 +#define IMG_EMC_MAGNIFIER 723 +#define IMG_EMC_WALL_9 724 +#define IMG_EMC_WALL_10 725 +#define IMG_EMC_WALL_11 726 +#define IMG_EMC_WALL_12 727 +#define IMG_EMC_WALL_13 728 +#define IMG_EMC_WALL_14 729 +#define IMG_EMC_WALL_15 730 +#define IMG_EMC_WALL_16 731 +#define IMG_EMC_WALL_SLIPPERY_1 732 +#define IMG_EMC_WALL_SLIPPERY_2 733 +#define IMG_EMC_WALL_SLIPPERY_3 734 +#define IMG_EMC_WALL_SLIPPERY_4 735 +#define IMG_EMC_FAKE_GRASS 736 +#define IMG_EMC_FAKE_GRASS_CRUMBLED 737 +#define IMG_EMC_FAKE_GRASS_ACTIVE 738 +#define IMG_EMC_FAKE_GRASS_ACTIVE_CRUMBLED 739 +#define IMG_EMC_FAKE_ACID 740 +#define IMG_EMC_DRIPPER 741 +#define IMG_EMC_DRIPPER_EDITOR 742 +#define IMG_EMC_DRIPPER_ACTIVE 743 +#define IMG_CHAR_SPACE 744 +#define IMG_CHAR_EXCLAM 745 +#define IMG_CHAR_QUOTEDBL 746 +#define IMG_CHAR_NUMBERSIGN 747 +#define IMG_CHAR_DOLLAR 748 +#define IMG_CHAR_PERCENT 749 +#define IMG_CHAR_AMPERSAND 750 +#define IMG_CHAR_APOSTROPHE 751 +#define IMG_CHAR_PARENLEFT 752 +#define IMG_CHAR_PARENRIGHT 753 +#define IMG_CHAR_ASTERISK 754 +#define IMG_CHAR_PLUS 755 +#define IMG_CHAR_COMMA 756 +#define IMG_CHAR_MINUS 757 +#define IMG_CHAR_PERIOD 758 +#define IMG_CHAR_SLASH 759 +#define IMG_CHAR_0 760 +#define IMG_CHAR_1 761 +#define IMG_CHAR_2 762 +#define IMG_CHAR_3 763 +#define IMG_CHAR_4 764 +#define IMG_CHAR_5 765 +#define IMG_CHAR_6 766 +#define IMG_CHAR_7 767 +#define IMG_CHAR_8 768 +#define IMG_CHAR_9 769 +#define IMG_CHAR_COLON 770 +#define IMG_CHAR_SEMICOLON 771 +#define IMG_CHAR_LESS 772 +#define IMG_CHAR_EQUAL 773 +#define IMG_CHAR_GREATER 774 +#define IMG_CHAR_QUESTION 775 +#define IMG_CHAR_AT 776 +#define IMG_CHAR_A 777 +#define IMG_CHAR_B 778 +#define IMG_CHAR_C 779 +#define IMG_CHAR_D 780 +#define IMG_CHAR_E 781 +#define IMG_CHAR_F 782 +#define IMG_CHAR_G 783 +#define IMG_CHAR_H 784 +#define IMG_CHAR_I 785 +#define IMG_CHAR_J 786 +#define IMG_CHAR_K 787 +#define IMG_CHAR_L 788 +#define IMG_CHAR_M 789 +#define IMG_CHAR_N 790 +#define IMG_CHAR_O 791 +#define IMG_CHAR_P 792 +#define IMG_CHAR_Q 793 +#define IMG_CHAR_R 794 +#define IMG_CHAR_S 795 +#define IMG_CHAR_T 796 +#define IMG_CHAR_U 797 +#define IMG_CHAR_V 798 +#define IMG_CHAR_W 799 +#define IMG_CHAR_X 800 +#define IMG_CHAR_Y 801 +#define IMG_CHAR_Z 802 +#define IMG_CHAR_BRACKETLEFT 803 +#define IMG_CHAR_BACKSLASH 804 +#define IMG_CHAR_BRACKETRIGHT 805 +#define IMG_CHAR_ASCIICIRCUM 806 +#define IMG_CHAR_UNDERSCORE 807 +#define IMG_CHAR_COPYRIGHT 808 +#define IMG_CHAR_AUMLAUT 809 +#define IMG_CHAR_OUMLAUT 810 +#define IMG_CHAR_UUMLAUT 811 +#define IMG_CHAR_DEGREE 812 +#define IMG_CHAR_TRADEMARK 813 +#define IMG_CHAR_CURSOR 814 +#define IMG_CUSTOM_1 815 +#define IMG_CUSTOM_1_EDITOR 816 +#define IMG_CUSTOM_2 817 +#define IMG_CUSTOM_2_EDITOR 818 +#define IMG_CUSTOM_3 819 +#define IMG_CUSTOM_3_EDITOR 820 +#define IMG_CUSTOM_4 821 +#define IMG_CUSTOM_4_EDITOR 822 +#define IMG_CUSTOM_5 823 +#define IMG_CUSTOM_5_EDITOR 824 +#define IMG_CUSTOM_6 825 +#define IMG_CUSTOM_6_EDITOR 826 +#define IMG_CUSTOM_7 827 +#define IMG_CUSTOM_7_EDITOR 828 +#define IMG_CUSTOM_8 829 +#define IMG_CUSTOM_8_EDITOR 830 +#define IMG_CUSTOM_9 831 +#define IMG_CUSTOM_9_EDITOR 832 +#define IMG_CUSTOM_10 833 +#define IMG_CUSTOM_10_EDITOR 834 +#define IMG_CUSTOM_11 835 +#define IMG_CUSTOM_11_EDITOR 836 +#define IMG_CUSTOM_12 837 +#define IMG_CUSTOM_12_EDITOR 838 +#define IMG_CUSTOM_13 839 +#define IMG_CUSTOM_13_EDITOR 840 +#define IMG_CUSTOM_14 841 +#define IMG_CUSTOM_14_EDITOR 842 +#define IMG_CUSTOM_15 843 +#define IMG_CUSTOM_15_EDITOR 844 +#define IMG_CUSTOM_16 845 +#define IMG_CUSTOM_16_EDITOR 846 +#define IMG_CUSTOM_17 847 +#define IMG_CUSTOM_17_EDITOR 848 +#define IMG_CUSTOM_18 849 +#define IMG_CUSTOM_18_EDITOR 850 +#define IMG_CUSTOM_19 851 +#define IMG_CUSTOM_19_EDITOR 852 +#define IMG_CUSTOM_20 853 +#define IMG_CUSTOM_20_EDITOR 854 +#define IMG_CUSTOM_21 855 +#define IMG_CUSTOM_21_EDITOR 856 +#define IMG_CUSTOM_22 857 +#define IMG_CUSTOM_22_EDITOR 858 +#define IMG_CUSTOM_23 859 +#define IMG_CUSTOM_23_EDITOR 860 +#define IMG_CUSTOM_24 861 +#define IMG_CUSTOM_24_EDITOR 862 +#define IMG_CUSTOM_25 863 +#define IMG_CUSTOM_25_EDITOR 864 +#define IMG_CUSTOM_26 865 +#define IMG_CUSTOM_26_EDITOR 866 +#define IMG_CUSTOM_27 867 +#define IMG_CUSTOM_27_EDITOR 868 +#define IMG_CUSTOM_28 869 +#define IMG_CUSTOM_28_EDITOR 870 +#define IMG_CUSTOM_29 871 +#define IMG_CUSTOM_29_EDITOR 872 +#define IMG_CUSTOM_30 873 +#define IMG_CUSTOM_30_EDITOR 874 +#define IMG_CUSTOM_31 875 +#define IMG_CUSTOM_31_EDITOR 876 +#define IMG_CUSTOM_32 877 +#define IMG_CUSTOM_32_EDITOR 878 +#define IMG_CUSTOM_33 879 +#define IMG_CUSTOM_33_EDITOR 880 +#define IMG_CUSTOM_34 881 +#define IMG_CUSTOM_34_EDITOR 882 +#define IMG_CUSTOM_35 883 +#define IMG_CUSTOM_35_EDITOR 884 +#define IMG_CUSTOM_36 885 +#define IMG_CUSTOM_36_EDITOR 886 +#define IMG_CUSTOM_37 887 +#define IMG_CUSTOM_37_EDITOR 888 +#define IMG_CUSTOM_38 889 +#define IMG_CUSTOM_38_EDITOR 890 +#define IMG_CUSTOM_39 891 +#define IMG_CUSTOM_39_EDITOR 892 +#define IMG_CUSTOM_40 893 +#define IMG_CUSTOM_40_EDITOR 894 +#define IMG_CUSTOM_41 895 +#define IMG_CUSTOM_41_EDITOR 896 +#define IMG_CUSTOM_42 897 +#define IMG_CUSTOM_42_EDITOR 898 +#define IMG_CUSTOM_43 899 +#define IMG_CUSTOM_43_EDITOR 900 +#define IMG_CUSTOM_44 901 +#define IMG_CUSTOM_44_EDITOR 902 +#define IMG_CUSTOM_45 903 +#define IMG_CUSTOM_45_EDITOR 904 +#define IMG_CUSTOM_46 905 +#define IMG_CUSTOM_46_EDITOR 906 +#define IMG_CUSTOM_47 907 +#define IMG_CUSTOM_47_EDITOR 908 +#define IMG_CUSTOM_48 909 +#define IMG_CUSTOM_48_EDITOR 910 +#define IMG_CUSTOM_49 911 +#define IMG_CUSTOM_49_EDITOR 912 +#define IMG_CUSTOM_50 913 +#define IMG_CUSTOM_50_EDITOR 914 +#define IMG_CUSTOM_51 915 +#define IMG_CUSTOM_51_EDITOR 916 +#define IMG_CUSTOM_52 917 +#define IMG_CUSTOM_52_EDITOR 918 +#define IMG_CUSTOM_53 919 +#define IMG_CUSTOM_53_EDITOR 920 +#define IMG_CUSTOM_54 921 +#define IMG_CUSTOM_54_EDITOR 922 +#define IMG_CUSTOM_55 923 +#define IMG_CUSTOM_55_EDITOR 924 +#define IMG_CUSTOM_56 925 +#define IMG_CUSTOM_56_EDITOR 926 +#define IMG_CUSTOM_57 927 +#define IMG_CUSTOM_57_EDITOR 928 +#define IMG_CUSTOM_58 929 +#define IMG_CUSTOM_58_EDITOR 930 +#define IMG_CUSTOM_59 931 +#define IMG_CUSTOM_59_EDITOR 932 +#define IMG_CUSTOM_60 933 +#define IMG_CUSTOM_60_EDITOR 934 +#define IMG_CUSTOM_61 935 +#define IMG_CUSTOM_61_EDITOR 936 +#define IMG_CUSTOM_62 937 +#define IMG_CUSTOM_62_EDITOR 938 +#define IMG_CUSTOM_63 939 +#define IMG_CUSTOM_63_EDITOR 940 +#define IMG_CUSTOM_64 941 +#define IMG_CUSTOM_64_EDITOR 942 +#define IMG_CUSTOM_65 943 +#define IMG_CUSTOM_65_EDITOR 944 +#define IMG_CUSTOM_66 945 +#define IMG_CUSTOM_66_EDITOR 946 +#define IMG_CUSTOM_67 947 +#define IMG_CUSTOM_67_EDITOR 948 +#define IMG_CUSTOM_68 949 +#define IMG_CUSTOM_68_EDITOR 950 +#define IMG_CUSTOM_69 951 +#define IMG_CUSTOM_69_EDITOR 952 +#define IMG_CUSTOM_70 953 +#define IMG_CUSTOM_70_EDITOR 954 +#define IMG_CUSTOM_71 955 +#define IMG_CUSTOM_71_EDITOR 956 +#define IMG_CUSTOM_72 957 +#define IMG_CUSTOM_72_EDITOR 958 +#define IMG_CUSTOM_73 959 +#define IMG_CUSTOM_73_EDITOR 960 +#define IMG_CUSTOM_74 961 +#define IMG_CUSTOM_74_EDITOR 962 +#define IMG_CUSTOM_75 963 +#define IMG_CUSTOM_75_EDITOR 964 +#define IMG_CUSTOM_76 965 +#define IMG_CUSTOM_76_EDITOR 966 +#define IMG_CUSTOM_77 967 +#define IMG_CUSTOM_77_EDITOR 968 +#define IMG_CUSTOM_78 969 +#define IMG_CUSTOM_78_EDITOR 970 +#define IMG_CUSTOM_79 971 +#define IMG_CUSTOM_79_EDITOR 972 +#define IMG_CUSTOM_80 973 +#define IMG_CUSTOM_80_EDITOR 974 +#define IMG_CUSTOM_81 975 +#define IMG_CUSTOM_81_EDITOR 976 +#define IMG_CUSTOM_82 977 +#define IMG_CUSTOM_82_EDITOR 978 +#define IMG_CUSTOM_83 979 +#define IMG_CUSTOM_83_EDITOR 980 +#define IMG_CUSTOM_84 981 +#define IMG_CUSTOM_84_EDITOR 982 +#define IMG_CUSTOM_85 983 +#define IMG_CUSTOM_85_EDITOR 984 +#define IMG_CUSTOM_86 985 +#define IMG_CUSTOM_86_EDITOR 986 +#define IMG_CUSTOM_87 987 +#define IMG_CUSTOM_87_EDITOR 988 +#define IMG_CUSTOM_88 989 +#define IMG_CUSTOM_88_EDITOR 990 +#define IMG_CUSTOM_89 991 +#define IMG_CUSTOM_89_EDITOR 992 +#define IMG_CUSTOM_90 993 +#define IMG_CUSTOM_90_EDITOR 994 +#define IMG_CUSTOM_91 995 +#define IMG_CUSTOM_91_EDITOR 996 +#define IMG_CUSTOM_92 997 +#define IMG_CUSTOM_92_EDITOR 998 +#define IMG_CUSTOM_93 999 +#define IMG_CUSTOM_93_EDITOR 1000 +#define IMG_CUSTOM_94 1001 +#define IMG_CUSTOM_94_EDITOR 1002 +#define IMG_CUSTOM_95 1003 +#define IMG_CUSTOM_95_EDITOR 1004 +#define IMG_CUSTOM_96 1005 +#define IMG_CUSTOM_96_EDITOR 1006 +#define IMG_CUSTOM_97 1007 +#define IMG_CUSTOM_97_EDITOR 1008 +#define IMG_CUSTOM_98 1009 +#define IMG_CUSTOM_98_EDITOR 1010 +#define IMG_CUSTOM_99 1011 +#define IMG_CUSTOM_99_EDITOR 1012 +#define IMG_CUSTOM_100 1013 +#define IMG_CUSTOM_100_EDITOR 1014 +#define IMG_CUSTOM_101 1015 +#define IMG_CUSTOM_101_EDITOR 1016 +#define IMG_CUSTOM_102 1017 +#define IMG_CUSTOM_102_EDITOR 1018 +#define IMG_CUSTOM_103 1019 +#define IMG_CUSTOM_103_EDITOR 1020 +#define IMG_CUSTOM_104 1021 +#define IMG_CUSTOM_104_EDITOR 1022 +#define IMG_CUSTOM_105 1023 +#define IMG_CUSTOM_105_EDITOR 1024 +#define IMG_CUSTOM_106 1025 +#define IMG_CUSTOM_106_EDITOR 1026 +#define IMG_CUSTOM_107 1027 +#define IMG_CUSTOM_107_EDITOR 1028 +#define IMG_CUSTOM_108 1029 +#define IMG_CUSTOM_108_EDITOR 1030 +#define IMG_CUSTOM_109 1031 +#define IMG_CUSTOM_109_EDITOR 1032 +#define IMG_CUSTOM_110 1033 +#define IMG_CUSTOM_110_EDITOR 1034 +#define IMG_CUSTOM_111 1035 +#define IMG_CUSTOM_111_EDITOR 1036 +#define IMG_CUSTOM_112 1037 +#define IMG_CUSTOM_112_EDITOR 1038 +#define IMG_CUSTOM_113 1039 +#define IMG_CUSTOM_113_EDITOR 1040 +#define IMG_CUSTOM_114 1041 +#define IMG_CUSTOM_114_EDITOR 1042 +#define IMG_CUSTOM_115 1043 +#define IMG_CUSTOM_115_EDITOR 1044 +#define IMG_CUSTOM_116 1045 +#define IMG_CUSTOM_116_EDITOR 1046 +#define IMG_CUSTOM_117 1047 +#define IMG_CUSTOM_117_EDITOR 1048 +#define IMG_CUSTOM_118 1049 +#define IMG_CUSTOM_118_EDITOR 1050 +#define IMG_CUSTOM_119 1051 +#define IMG_CUSTOM_119_EDITOR 1052 +#define IMG_CUSTOM_120 1053 +#define IMG_CUSTOM_120_EDITOR 1054 +#define IMG_CUSTOM_121 1055 +#define IMG_CUSTOM_121_EDITOR 1056 +#define IMG_CUSTOM_122 1057 +#define IMG_CUSTOM_122_EDITOR 1058 +#define IMG_CUSTOM_123 1059 +#define IMG_CUSTOM_123_EDITOR 1060 +#define IMG_CUSTOM_124 1061 +#define IMG_CUSTOM_124_EDITOR 1062 +#define IMG_CUSTOM_125 1063 +#define IMG_CUSTOM_125_EDITOR 1064 +#define IMG_CUSTOM_126 1065 +#define IMG_CUSTOM_126_EDITOR 1066 +#define IMG_CUSTOM_127 1067 +#define IMG_CUSTOM_127_EDITOR 1068 +#define IMG_CUSTOM_128 1069 +#define IMG_CUSTOM_128_EDITOR 1070 +#define IMG_CUSTOM_129 1071 +#define IMG_CUSTOM_129_EDITOR 1072 +#define IMG_CUSTOM_130 1073 +#define IMG_CUSTOM_130_EDITOR 1074 +#define IMG_CUSTOM_131 1075 +#define IMG_CUSTOM_131_EDITOR 1076 +#define IMG_CUSTOM_132 1077 +#define IMG_CUSTOM_132_EDITOR 1078 +#define IMG_CUSTOM_133 1079 +#define IMG_CUSTOM_133_EDITOR 1080 +#define IMG_CUSTOM_134 1081 +#define IMG_CUSTOM_134_EDITOR 1082 +#define IMG_CUSTOM_135 1083 +#define IMG_CUSTOM_135_EDITOR 1084 +#define IMG_CUSTOM_136 1085 +#define IMG_CUSTOM_136_EDITOR 1086 +#define IMG_CUSTOM_137 1087 +#define IMG_CUSTOM_137_EDITOR 1088 +#define IMG_CUSTOM_138 1089 +#define IMG_CUSTOM_138_EDITOR 1090 +#define IMG_CUSTOM_139 1091 +#define IMG_CUSTOM_139_EDITOR 1092 +#define IMG_CUSTOM_140 1093 +#define IMG_CUSTOM_140_EDITOR 1094 +#define IMG_CUSTOM_141 1095 +#define IMG_CUSTOM_141_EDITOR 1096 +#define IMG_CUSTOM_142 1097 +#define IMG_CUSTOM_142_EDITOR 1098 +#define IMG_CUSTOM_143 1099 +#define IMG_CUSTOM_143_EDITOR 1100 +#define IMG_CUSTOM_144 1101 +#define IMG_CUSTOM_144_EDITOR 1102 +#define IMG_CUSTOM_145 1103 +#define IMG_CUSTOM_145_EDITOR 1104 +#define IMG_CUSTOM_146 1105 +#define IMG_CUSTOM_146_EDITOR 1106 +#define IMG_CUSTOM_147 1107 +#define IMG_CUSTOM_147_EDITOR 1108 +#define IMG_CUSTOM_148 1109 +#define IMG_CUSTOM_148_EDITOR 1110 +#define IMG_CUSTOM_149 1111 +#define IMG_CUSTOM_149_EDITOR 1112 +#define IMG_CUSTOM_150 1113 +#define IMG_CUSTOM_150_EDITOR 1114 +#define IMG_CUSTOM_151 1115 +#define IMG_CUSTOM_151_EDITOR 1116 +#define IMG_CUSTOM_152 1117 +#define IMG_CUSTOM_152_EDITOR 1118 +#define IMG_CUSTOM_153 1119 +#define IMG_CUSTOM_153_EDITOR 1120 +#define IMG_CUSTOM_154 1121 +#define IMG_CUSTOM_154_EDITOR 1122 +#define IMG_CUSTOM_155 1123 +#define IMG_CUSTOM_155_EDITOR 1124 +#define IMG_CUSTOM_156 1125 +#define IMG_CUSTOM_156_EDITOR 1126 +#define IMG_CUSTOM_157 1127 +#define IMG_CUSTOM_157_EDITOR 1128 +#define IMG_CUSTOM_158 1129 +#define IMG_CUSTOM_158_EDITOR 1130 +#define IMG_CUSTOM_159 1131 +#define IMG_CUSTOM_159_EDITOR 1132 +#define IMG_CUSTOM_160 1133 +#define IMG_CUSTOM_160_EDITOR 1134 +#define IMG_CUSTOM_161 1135 +#define IMG_CUSTOM_161_EDITOR 1136 +#define IMG_CUSTOM_162 1137 +#define IMG_CUSTOM_162_EDITOR 1138 +#define IMG_CUSTOM_163 1139 +#define IMG_CUSTOM_163_EDITOR 1140 +#define IMG_CUSTOM_164 1141 +#define IMG_CUSTOM_164_EDITOR 1142 +#define IMG_CUSTOM_165 1143 +#define IMG_CUSTOM_165_EDITOR 1144 +#define IMG_CUSTOM_166 1145 +#define IMG_CUSTOM_166_EDITOR 1146 +#define IMG_CUSTOM_167 1147 +#define IMG_CUSTOM_167_EDITOR 1148 +#define IMG_CUSTOM_168 1149 +#define IMG_CUSTOM_168_EDITOR 1150 +#define IMG_CUSTOM_169 1151 +#define IMG_CUSTOM_169_EDITOR 1152 +#define IMG_CUSTOM_170 1153 +#define IMG_CUSTOM_170_EDITOR 1154 +#define IMG_CUSTOM_171 1155 +#define IMG_CUSTOM_171_EDITOR 1156 +#define IMG_CUSTOM_172 1157 +#define IMG_CUSTOM_172_EDITOR 1158 +#define IMG_CUSTOM_173 1159 +#define IMG_CUSTOM_173_EDITOR 1160 +#define IMG_CUSTOM_174 1161 +#define IMG_CUSTOM_174_EDITOR 1162 +#define IMG_CUSTOM_175 1163 +#define IMG_CUSTOM_175_EDITOR 1164 +#define IMG_CUSTOM_176 1165 +#define IMG_CUSTOM_176_EDITOR 1166 +#define IMG_CUSTOM_177 1167 +#define IMG_CUSTOM_177_EDITOR 1168 +#define IMG_CUSTOM_178 1169 +#define IMG_CUSTOM_178_EDITOR 1170 +#define IMG_CUSTOM_179 1171 +#define IMG_CUSTOM_179_EDITOR 1172 +#define IMG_CUSTOM_180 1173 +#define IMG_CUSTOM_180_EDITOR 1174 +#define IMG_CUSTOM_181 1175 +#define IMG_CUSTOM_181_EDITOR 1176 +#define IMG_CUSTOM_182 1177 +#define IMG_CUSTOM_182_EDITOR 1178 +#define IMG_CUSTOM_183 1179 +#define IMG_CUSTOM_183_EDITOR 1180 +#define IMG_CUSTOM_184 1181 +#define IMG_CUSTOM_184_EDITOR 1182 +#define IMG_CUSTOM_185 1183 +#define IMG_CUSTOM_185_EDITOR 1184 +#define IMG_CUSTOM_186 1185 +#define IMG_CUSTOM_186_EDITOR 1186 +#define IMG_CUSTOM_187 1187 +#define IMG_CUSTOM_187_EDITOR 1188 +#define IMG_CUSTOM_188 1189 +#define IMG_CUSTOM_188_EDITOR 1190 +#define IMG_CUSTOM_189 1191 +#define IMG_CUSTOM_189_EDITOR 1192 +#define IMG_CUSTOM_190 1193 +#define IMG_CUSTOM_190_EDITOR 1194 +#define IMG_CUSTOM_191 1195 +#define IMG_CUSTOM_191_EDITOR 1196 +#define IMG_CUSTOM_192 1197 +#define IMG_CUSTOM_192_EDITOR 1198 +#define IMG_CUSTOM_193 1199 +#define IMG_CUSTOM_193_EDITOR 1200 +#define IMG_CUSTOM_194 1201 +#define IMG_CUSTOM_194_EDITOR 1202 +#define IMG_CUSTOM_195 1203 +#define IMG_CUSTOM_195_EDITOR 1204 +#define IMG_CUSTOM_196 1205 +#define IMG_CUSTOM_196_EDITOR 1206 +#define IMG_CUSTOM_197 1207 +#define IMG_CUSTOM_197_EDITOR 1208 +#define IMG_CUSTOM_198 1209 +#define IMG_CUSTOM_198_EDITOR 1210 +#define IMG_CUSTOM_199 1211 +#define IMG_CUSTOM_199_EDITOR 1212 +#define IMG_CUSTOM_200 1213 +#define IMG_CUSTOM_200_EDITOR 1214 +#define IMG_CUSTOM_201 1215 +#define IMG_CUSTOM_201_EDITOR 1216 +#define IMG_CUSTOM_202 1217 +#define IMG_CUSTOM_202_EDITOR 1218 +#define IMG_CUSTOM_203 1219 +#define IMG_CUSTOM_203_EDITOR 1220 +#define IMG_CUSTOM_204 1221 +#define IMG_CUSTOM_204_EDITOR 1222 +#define IMG_CUSTOM_205 1223 +#define IMG_CUSTOM_205_EDITOR 1224 +#define IMG_CUSTOM_206 1225 +#define IMG_CUSTOM_206_EDITOR 1226 +#define IMG_CUSTOM_207 1227 +#define IMG_CUSTOM_207_EDITOR 1228 +#define IMG_CUSTOM_208 1229 +#define IMG_CUSTOM_208_EDITOR 1230 +#define IMG_CUSTOM_209 1231 +#define IMG_CUSTOM_209_EDITOR 1232 +#define IMG_CUSTOM_210 1233 +#define IMG_CUSTOM_210_EDITOR 1234 +#define IMG_CUSTOM_211 1235 +#define IMG_CUSTOM_211_EDITOR 1236 +#define IMG_CUSTOM_212 1237 +#define IMG_CUSTOM_212_EDITOR 1238 +#define IMG_CUSTOM_213 1239 +#define IMG_CUSTOM_213_EDITOR 1240 +#define IMG_CUSTOM_214 1241 +#define IMG_CUSTOM_214_EDITOR 1242 +#define IMG_CUSTOM_215 1243 +#define IMG_CUSTOM_215_EDITOR 1244 +#define IMG_CUSTOM_216 1245 +#define IMG_CUSTOM_216_EDITOR 1246 +#define IMG_CUSTOM_217 1247 +#define IMG_CUSTOM_217_EDITOR 1248 +#define IMG_CUSTOM_218 1249 +#define IMG_CUSTOM_218_EDITOR 1250 +#define IMG_CUSTOM_219 1251 +#define IMG_CUSTOM_219_EDITOR 1252 +#define IMG_CUSTOM_220 1253 +#define IMG_CUSTOM_220_EDITOR 1254 +#define IMG_CUSTOM_221 1255 +#define IMG_CUSTOM_221_EDITOR 1256 +#define IMG_CUSTOM_222 1257 +#define IMG_CUSTOM_222_EDITOR 1258 +#define IMG_CUSTOM_223 1259 +#define IMG_CUSTOM_223_EDITOR 1260 +#define IMG_CUSTOM_224 1261 +#define IMG_CUSTOM_224_EDITOR 1262 +#define IMG_CUSTOM_225 1263 +#define IMG_CUSTOM_225_EDITOR 1264 +#define IMG_CUSTOM_226 1265 +#define IMG_CUSTOM_226_EDITOR 1266 +#define IMG_CUSTOM_227 1267 +#define IMG_CUSTOM_227_EDITOR 1268 +#define IMG_CUSTOM_228 1269 +#define IMG_CUSTOM_228_EDITOR 1270 +#define IMG_CUSTOM_229 1271 +#define IMG_CUSTOM_229_EDITOR 1272 +#define IMG_CUSTOM_230 1273 +#define IMG_CUSTOM_230_EDITOR 1274 +#define IMG_CUSTOM_231 1275 +#define IMG_CUSTOM_231_EDITOR 1276 +#define IMG_CUSTOM_232 1277 +#define IMG_CUSTOM_232_EDITOR 1278 +#define IMG_CUSTOM_233 1279 +#define IMG_CUSTOM_233_EDITOR 1280 +#define IMG_CUSTOM_234 1281 +#define IMG_CUSTOM_234_EDITOR 1282 +#define IMG_CUSTOM_235 1283 +#define IMG_CUSTOM_235_EDITOR 1284 +#define IMG_CUSTOM_236 1285 +#define IMG_CUSTOM_236_EDITOR 1286 +#define IMG_CUSTOM_237 1287 +#define IMG_CUSTOM_237_EDITOR 1288 +#define IMG_CUSTOM_238 1289 +#define IMG_CUSTOM_238_EDITOR 1290 +#define IMG_CUSTOM_239 1291 +#define IMG_CUSTOM_239_EDITOR 1292 +#define IMG_CUSTOM_240 1293 +#define IMG_CUSTOM_240_EDITOR 1294 +#define IMG_CUSTOM_241 1295 +#define IMG_CUSTOM_241_EDITOR 1296 +#define IMG_CUSTOM_242 1297 +#define IMG_CUSTOM_242_EDITOR 1298 +#define IMG_CUSTOM_243 1299 +#define IMG_CUSTOM_243_EDITOR 1300 +#define IMG_CUSTOM_244 1301 +#define IMG_CUSTOM_244_EDITOR 1302 +#define IMG_CUSTOM_245 1303 +#define IMG_CUSTOM_245_EDITOR 1304 +#define IMG_CUSTOM_246 1305 +#define IMG_CUSTOM_246_EDITOR 1306 +#define IMG_CUSTOM_247 1307 +#define IMG_CUSTOM_247_EDITOR 1308 +#define IMG_CUSTOM_248 1309 +#define IMG_CUSTOM_248_EDITOR 1310 +#define IMG_CUSTOM_249 1311 +#define IMG_CUSTOM_249_EDITOR 1312 +#define IMG_CUSTOM_250 1313 +#define IMG_CUSTOM_250_EDITOR 1314 +#define IMG_CUSTOM_251 1315 +#define IMG_CUSTOM_251_EDITOR 1316 +#define IMG_CUSTOM_252 1317 +#define IMG_CUSTOM_252_EDITOR 1318 +#define IMG_CUSTOM_253 1319 +#define IMG_CUSTOM_253_EDITOR 1320 +#define IMG_CUSTOM_254 1321 +#define IMG_CUSTOM_254_EDITOR 1322 +#define IMG_CUSTOM_255 1323 +#define IMG_CUSTOM_255_EDITOR 1324 +#define IMG_CUSTOM_256 1325 +#define IMG_CUSTOM_256_EDITOR 1326 +#define IMG_GROUP_1 1327 +#define IMG_GROUP_1_EDITOR 1328 +#define IMG_GROUP_2 1329 +#define IMG_GROUP_2_EDITOR 1330 +#define IMG_GROUP_3 1331 +#define IMG_GROUP_3_EDITOR 1332 +#define IMG_GROUP_4 1333 +#define IMG_GROUP_4_EDITOR 1334 +#define IMG_GROUP_5 1335 +#define IMG_GROUP_5_EDITOR 1336 +#define IMG_GROUP_6 1337 +#define IMG_GROUP_6_EDITOR 1338 +#define IMG_GROUP_7 1339 +#define IMG_GROUP_7_EDITOR 1340 +#define IMG_GROUP_8 1341 +#define IMG_GROUP_8_EDITOR 1342 +#define IMG_GROUP_9 1343 +#define IMG_GROUP_9_EDITOR 1344 +#define IMG_GROUP_10 1345 +#define IMG_GROUP_10_EDITOR 1346 +#define IMG_GROUP_11 1347 +#define IMG_GROUP_11_EDITOR 1348 +#define IMG_GROUP_12 1349 +#define IMG_GROUP_12_EDITOR 1350 +#define IMG_GROUP_13 1351 +#define IMG_GROUP_13_EDITOR 1352 +#define IMG_GROUP_14 1353 +#define IMG_GROUP_14_EDITOR 1354 +#define IMG_GROUP_15 1355 +#define IMG_GROUP_15_EDITOR 1356 +#define IMG_GROUP_16 1357 +#define IMG_GROUP_16_EDITOR 1358 +#define IMG_GROUP_17 1359 +#define IMG_GROUP_17_EDITOR 1360 +#define IMG_GROUP_18 1361 +#define IMG_GROUP_18_EDITOR 1362 +#define IMG_GROUP_19 1363 +#define IMG_GROUP_19_EDITOR 1364 +#define IMG_GROUP_20 1365 +#define IMG_GROUP_20_EDITOR 1366 +#define IMG_GROUP_21 1367 +#define IMG_GROUP_21_EDITOR 1368 +#define IMG_GROUP_22 1369 +#define IMG_GROUP_22_EDITOR 1370 +#define IMG_GROUP_23 1371 +#define IMG_GROUP_23_EDITOR 1372 +#define IMG_GROUP_24 1373 +#define IMG_GROUP_24_EDITOR 1374 +#define IMG_GROUP_25 1375 +#define IMG_GROUP_25_EDITOR 1376 +#define IMG_GROUP_26 1377 +#define IMG_GROUP_26_EDITOR 1378 +#define IMG_GROUP_27 1379 +#define IMG_GROUP_27_EDITOR 1380 +#define IMG_GROUP_28 1381 +#define IMG_GROUP_28_EDITOR 1382 +#define IMG_GROUP_29 1383 +#define IMG_GROUP_29_EDITOR 1384 +#define IMG_GROUP_30 1385 +#define IMG_GROUP_30_EDITOR 1386 +#define IMG_GROUP_31 1387 +#define IMG_GROUP_31_EDITOR 1388 +#define IMG_GROUP_32 1389 +#define IMG_GROUP_32_EDITOR 1390 +#define IMG_EMC_OBJECT 1391 +#define IMG_EMC_SPRITE 1392 +#define IMG_TOON_1 1393 +#define IMG_TOON_2 1394 +#define IMG_TOON_3 1395 +#define IMG_TOON_4 1396 +#define IMG_TOON_5 1397 +#define IMG_TOON_6 1398 +#define IMG_TOON_7 1399 +#define IMG_TOON_8 1400 +#define IMG_TOON_9 1401 +#define IMG_TOON_10 1402 +#define IMG_TOON_11 1403 +#define IMG_TOON_12 1404 +#define IMG_TOON_13 1405 +#define IMG_TOON_14 1406 +#define IMG_TOON_15 1407 +#define IMG_TOON_16 1408 +#define IMG_TOON_17 1409 +#define IMG_TOON_18 1410 +#define IMG_TOON_19 1411 +#define IMG_TOON_20 1412 +#define IMG_MENU_CALIBRATE_RED 1413 +#define IMG_MENU_CALIBRATE_BLUE 1414 +#define IMG_MENU_CALIBRATE_YELLOW 1415 +#define IMG_MENU_BUTTON 1416 +#define IMG_MENU_BUTTON_ACTIVE 1417 +#define IMG_MENU_BUTTON_LEFT 1418 +#define IMG_MENU_BUTTON_LEFT_ACTIVE 1419 +#define IMG_MENU_BUTTON_RIGHT 1420 +#define IMG_MENU_BUTTON_RIGHT_ACTIVE 1421 +#define IMG_MENU_BUTTON_UP 1422 +#define IMG_MENU_BUTTON_UP_ACTIVE 1423 +#define IMG_MENU_BUTTON_DOWN 1424 +#define IMG_MENU_BUTTON_DOWN_ACTIVE 1425 +#define IMG_MENU_BUTTON_ENTER_MENU 1426 +#define IMG_MENU_BUTTON_ENTER_MENU_ACTIVE 1427 +#define IMG_MENU_BUTTON_LEAVE_MENU 1428 +#define IMG_MENU_BUTTON_LEAVE_MENU_ACTIVE 1429 +#define IMG_MENU_SCROLLBAR 1430 +#define IMG_MENU_SCROLLBAR_ACTIVE 1431 +#define IMG_FONT_INITIAL_1 1432 +#define IMG_FONT_INITIAL_2 1433 +#define IMG_FONT_INITIAL_3 1434 +#define IMG_FONT_INITIAL_4 1435 +#define IMG_FONT_TITLE_1 1436 +#define IMG_FONT_TITLE_2 1437 +#define IMG_FONT_MENU_1 1438 +#define IMG_FONT_MENU_2 1439 +#define IMG_FONT_TEXT_1 1440 +#define IMG_FONT_TEXT_1_LEVELS 1441 +#define IMG_FONT_TEXT_1_PREVIEW 1442 +#define IMG_FONT_TEXT_1_SCORES 1443 +#define IMG_FONT_TEXT_1_ACTIVE_SCORES 1444 +#define IMG_FONT_TEXT_2 1445 +#define IMG_FONT_TEXT_2_LEVELS 1446 +#define IMG_FONT_TEXT_2_PREVIEW 1447 +#define IMG_FONT_TEXT_2_SCORES 1448 +#define IMG_FONT_TEXT_2_ACTIVE_SCORES 1449 +#define IMG_FONT_TEXT_3 1450 +#define IMG_FONT_TEXT_3_LEVELS 1451 +#define IMG_FONT_TEXT_3_PREVIEW 1452 +#define IMG_FONT_TEXT_3_SCORES 1453 +#define IMG_FONT_TEXT_3_ACTIVE_SCORES 1454 +#define IMG_FONT_TEXT_4 1455 +#define IMG_FONT_TEXT_4_LEVELS 1456 +#define IMG_FONT_TEXT_4_SCORES 1457 +#define IMG_FONT_TEXT_4_ACTIVE_SCORES 1458 +#define IMG_FONT_ENVELOPE_1 1459 +#define IMG_FONT_ENVELOPE_2 1460 +#define IMG_FONT_ENVELOPE_3 1461 +#define IMG_FONT_ENVELOPE_4 1462 +#define IMG_FONT_INPUT_1 1463 +#define IMG_FONT_INPUT_1_MAIN 1464 +#define IMG_FONT_INPUT_1_ACTIVE 1465 +#define IMG_FONT_INPUT_1_ACTIVE_MAIN 1466 +#define IMG_FONT_INPUT_1_ACTIVE_SETUP 1467 +#define IMG_FONT_INPUT_2 1468 +#define IMG_FONT_INPUT_2_ACTIVE 1469 +#define IMG_FONT_OPTION_OFF 1470 +#define IMG_FONT_OPTION_ON 1471 +#define IMG_FONT_VALUE_1 1472 +#define IMG_FONT_VALUE_2 1473 +#define IMG_FONT_VALUE_OLD 1474 +#define IMG_FONT_LEVEL_NUMBER 1475 +#define IMG_FONT_TAPE_RECORDER 1476 +#define IMG_FONT_GAME_INFO 1477 +#define IMG_GLOBAL_BORDER 1478 +#define IMG_GLOBAL_DOOR 1479 +#define IMG_EDITOR_ELEMENT_BORDER 1480 +#define IMG_EDITOR_ELEMENT_BORDER_INPUT 1481 +#define IMG_EDITOR_CASCADE_LIST 1482 +#define IMG_EDITOR_CASCADE_LIST_ACTIVE 1483 +#define IMG_BACKGROUND_ENVELOPE_1 1484 +#define IMG_BACKGROUND_ENVELOPE_2 1485 +#define IMG_BACKGROUND_ENVELOPE_3 1486 +#define IMG_BACKGROUND_ENVELOPE_4 1487 +#define IMG_BACKGROUND 1488 +#define IMG_BACKGROUND_MAIN 1489 +#define IMG_BACKGROUND_LEVELS 1490 +#define IMG_BACKGROUND_SCORES 1491 +#define IMG_BACKGROUND_EDITOR 1492 +#define IMG_BACKGROUND_INFO 1493 +#define IMG_BACKGROUND_INFO_ELEMENTS 1494 +#define IMG_BACKGROUND_INFO_MUSIC 1495 +#define IMG_BACKGROUND_INFO_CREDITS 1496 +#define IMG_BACKGROUND_INFO_PROGRAM 1497 +#define IMG_BACKGROUND_INFO_LEVELSET 1498 +#define IMG_BACKGROUND_SETUP 1499 +#define IMG_BACKGROUND_DOOR 1500 -#define NUM_IMAGE_FILES 1479 +#define NUM_IMAGE_FILES 1501 #endif /* CONF_GFX_H */ diff --git a/src/conftime.h b/src/conftime.h index 06aa9f53..e4d2f768 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2006-01-11 22:26]" +#define COMPILE_DATE_STRING "[2006-01-12 02:30]" diff --git a/src/editor.c b/src/editor.c index 8c1302cc..f6ca7e10 100644 --- a/src/editor.c +++ b/src/editor.c @@ -156,13 +156,13 @@ /* yamyam content */ #define ED_AREA_YAMYAM_CONTENT_XPOS(n) (2 * MINI_TILEX + \ 5 * ((n) % 4) * MINI_TILEX) -#define ED_AREA_YAMYAM_CONTENT_YPOS(n) (17 * MINI_TILEY + \ +#define ED_AREA_YAMYAM_CONTENT_YPOS(n) (11 * ED_SETTINGS_YOFFSET + \ 6 * ((n) / 4) * MINI_TILEY) /* magic ball content */ #define ED_AREA_MAGIC_BALL_CONTENT_XPOS(n) (2 * MINI_TILEX + \ 5 * ((n) % 4) * MINI_TILEX) -#define ED_AREA_MAGIC_BALL_CONTENT_YPOS(n) (17 * MINI_TILEY + \ +#define ED_AREA_MAGIC_BALL_CONTENT_YPOS(n) (12 * ED_SETTINGS_YOFFSET + \ 6 * ((n) / 4) * MINI_TILEY) /* values for scrolling gadgets for drawing area */ @@ -277,7 +277,7 @@ #define ED_TEXTBUTTON_XSIZE ED_WIN_COUNT_XSIZE #define ED_TEXTBUTTON_YSIZE ED_WIN_COUNT_YSIZE -/* values for ClearEditorGadgetInfoText() and HandleGadgetInfoText() */ +/* values for ClearEditorGadgetInfoText() and HandleEditorGadgetInfoText() */ #define INFOTEXT_XPOS SX #define INFOTEXT_YPOS (SY + SYSIZE - MINI_TILEX + 2) #define INFOTEXT_XSIZE SXSIZE @@ -354,60 +354,78 @@ #define GADGET_ID_ELEMENT_VALUE2_DOWN (GADGET_ID_COUNTER_FIRST + 24) #define GADGET_ID_ELEMENT_VALUE2_TEXT (GADGET_ID_COUNTER_FIRST + 25) #define GADGET_ID_ELEMENT_VALUE2_UP (GADGET_ID_COUNTER_FIRST + 26) -#define GADGET_ID_YAMYAM_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 27) -#define GADGET_ID_YAMYAM_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 28) -#define GADGET_ID_YAMYAM_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 29) -#define GADGET_ID_ENVELOPE_XSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 30) -#define GADGET_ID_ENVELOPE_XSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 31) -#define GADGET_ID_ENVELOPE_XSIZE_UP (GADGET_ID_COUNTER_FIRST + 32) -#define GADGET_ID_ENVELOPE_YSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 33) -#define GADGET_ID_ENVELOPE_YSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 34) -#define GADGET_ID_ENVELOPE_YSIZE_UP (GADGET_ID_COUNTER_FIRST + 35) -#define GADGET_ID_CUSTOM_SCORE_DOWN (GADGET_ID_COUNTER_FIRST + 36) -#define GADGET_ID_CUSTOM_SCORE_TEXT (GADGET_ID_COUNTER_FIRST + 37) -#define GADGET_ID_CUSTOM_SCORE_UP (GADGET_ID_COUNTER_FIRST + 38) -#define GADGET_ID_CUSTOM_GEMCOUNT_DOWN (GADGET_ID_COUNTER_FIRST + 39) -#define GADGET_ID_CUSTOM_GEMCOUNT_TEXT (GADGET_ID_COUNTER_FIRST + 40) -#define GADGET_ID_CUSTOM_GEMCOUNT_UP (GADGET_ID_COUNTER_FIRST + 41) -#define GADGET_ID_PUSH_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 42) -#define GADGET_ID_PUSH_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 43) -#define GADGET_ID_PUSH_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 44) -#define GADGET_ID_PUSH_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 45) -#define GADGET_ID_PUSH_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 46) -#define GADGET_ID_PUSH_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 47) -#define GADGET_ID_DROP_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 48) -#define GADGET_ID_DROP_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 49) -#define GADGET_ID_DROP_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 50) -#define GADGET_ID_DROP_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 51) -#define GADGET_ID_DROP_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 52) -#define GADGET_ID_DROP_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 53) -#define GADGET_ID_MOVE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 54) -#define GADGET_ID_MOVE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 55) -#define GADGET_ID_MOVE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 56) -#define GADGET_ID_MOVE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 57) -#define GADGET_ID_MOVE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 58) -#define GADGET_ID_MOVE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 59) -#define GADGET_ID_EXPLOSION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 60) -#define GADGET_ID_EXPLOSION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 61) -#define GADGET_ID_EXPLOSION_DELAY_UP (GADGET_ID_COUNTER_FIRST + 62) -#define GADGET_ID_IGNITION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 63) -#define GADGET_ID_IGNITION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 64) -#define GADGET_ID_IGNITION_DELAY_UP (GADGET_ID_COUNTER_FIRST + 65) -#define GADGET_ID_CHANGE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 66) -#define GADGET_ID_CHANGE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 67) -#define GADGET_ID_CHANGE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 68) -#define GADGET_ID_CHANGE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 69) -#define GADGET_ID_CHANGE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 70) -#define GADGET_ID_CHANGE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 71) -#define GADGET_ID_CHANGE_CONT_RND_DOWN (GADGET_ID_COUNTER_FIRST + 72) -#define GADGET_ID_CHANGE_CONT_RND_TEXT (GADGET_ID_COUNTER_FIRST + 73) -#define GADGET_ID_CHANGE_CONT_RND_UP (GADGET_ID_COUNTER_FIRST + 74) -#define GADGET_ID_GROUP_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 75) -#define GADGET_ID_GROUP_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 76) -#define GADGET_ID_GROUP_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 77) +#define GADGET_ID_ELEMENT_VALUE3_DOWN (GADGET_ID_COUNTER_FIRST + 27) +#define GADGET_ID_ELEMENT_VALUE3_TEXT (GADGET_ID_COUNTER_FIRST + 28) +#define GADGET_ID_ELEMENT_VALUE3_UP (GADGET_ID_COUNTER_FIRST + 29) +#define GADGET_ID_ELEMENT_VALUE4_DOWN (GADGET_ID_COUNTER_FIRST + 30) +#define GADGET_ID_ELEMENT_VALUE4_TEXT (GADGET_ID_COUNTER_FIRST + 31) +#define GADGET_ID_ELEMENT_VALUE4_UP (GADGET_ID_COUNTER_FIRST + 32) +#define GADGET_ID_YAMYAM_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 33) +#define GADGET_ID_YAMYAM_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 34) +#define GADGET_ID_YAMYAM_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 35) +#define GADGET_ID_BALL_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 36) +#define GADGET_ID_BALL_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 37) +#define GADGET_ID_BALL_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 38) +#define GADGET_ID_ANDROID_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 39) +#define GADGET_ID_ANDROID_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 40) +#define GADGET_ID_ANDROID_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 41) +#define GADGET_ID_ENVELOPE_XSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 42) +#define GADGET_ID_ENVELOPE_XSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 43) +#define GADGET_ID_ENVELOPE_XSIZE_UP (GADGET_ID_COUNTER_FIRST + 44) +#define GADGET_ID_ENVELOPE_YSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 45) +#define GADGET_ID_ENVELOPE_YSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 46) +#define GADGET_ID_ENVELOPE_YSIZE_UP (GADGET_ID_COUNTER_FIRST + 47) +#define GADGET_ID_CUSTOM_SCORE_DOWN (GADGET_ID_COUNTER_FIRST + 48) +#define GADGET_ID_CUSTOM_SCORE_TEXT (GADGET_ID_COUNTER_FIRST + 49) +#define GADGET_ID_CUSTOM_SCORE_UP (GADGET_ID_COUNTER_FIRST + 50) +#define GADGET_ID_CUSTOM_GEMCOUNT_DOWN (GADGET_ID_COUNTER_FIRST + 51) +#define GADGET_ID_CUSTOM_GEMCOUNT_TEXT (GADGET_ID_COUNTER_FIRST + 52) +#define GADGET_ID_CUSTOM_GEMCOUNT_UP (GADGET_ID_COUNTER_FIRST + 53) +#define GADGET_ID_CUSTOM_VALUE_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 54) +#define GADGET_ID_CUSTOM_VALUE_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 55) +#define GADGET_ID_CUSTOM_VALUE_FIX_UP (GADGET_ID_COUNTER_FIRST + 56) +#define GADGET_ID_CUSTOM_VALUE_RND_DOWN (GADGET_ID_COUNTER_FIRST + 57) +#define GADGET_ID_CUSTOM_VALUE_RND_TEXT (GADGET_ID_COUNTER_FIRST + 58) +#define GADGET_ID_CUSTOM_VALUE_RND_UP (GADGET_ID_COUNTER_FIRST + 59) +#define GADGET_ID_PUSH_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 60) +#define GADGET_ID_PUSH_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 61) +#define GADGET_ID_PUSH_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 62) +#define GADGET_ID_PUSH_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 63) +#define GADGET_ID_PUSH_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 64) +#define GADGET_ID_PUSH_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 65) +#define GADGET_ID_DROP_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 66) +#define GADGET_ID_DROP_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 67) +#define GADGET_ID_DROP_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 68) +#define GADGET_ID_DROP_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 69) +#define GADGET_ID_DROP_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 70) +#define GADGET_ID_DROP_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 71) +#define GADGET_ID_MOVE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 72) +#define GADGET_ID_MOVE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 73) +#define GADGET_ID_MOVE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 74) +#define GADGET_ID_MOVE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 75) +#define GADGET_ID_MOVE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 76) +#define GADGET_ID_MOVE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 77) +#define GADGET_ID_EXPLOSION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 78) +#define GADGET_ID_EXPLOSION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 79) +#define GADGET_ID_EXPLOSION_DELAY_UP (GADGET_ID_COUNTER_FIRST + 80) +#define GADGET_ID_IGNITION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 81) +#define GADGET_ID_IGNITION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 82) +#define GADGET_ID_IGNITION_DELAY_UP (GADGET_ID_COUNTER_FIRST + 83) +#define GADGET_ID_CHANGE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 84) +#define GADGET_ID_CHANGE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 85) +#define GADGET_ID_CHANGE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 86) +#define GADGET_ID_CHANGE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 87) +#define GADGET_ID_CHANGE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 88) +#define GADGET_ID_CHANGE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 89) +#define GADGET_ID_CHANGE_CONT_RND_DOWN (GADGET_ID_COUNTER_FIRST + 90) +#define GADGET_ID_CHANGE_CONT_RND_TEXT (GADGET_ID_COUNTER_FIRST + 91) +#define GADGET_ID_CHANGE_CONT_RND_UP (GADGET_ID_COUNTER_FIRST + 92) +#define GADGET_ID_GROUP_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 93) +#define GADGET_ID_GROUP_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 94) +#define GADGET_ID_GROUP_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 95) /* drawing area identifiers */ -#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 78) +#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 96) #define GADGET_ID_DRAWING_LEVEL (GADGET_ID_DRAWING_AREA_FIRST + 0) #define GADGET_ID_YAMYAM_CONTENT_0 (GADGET_ID_DRAWING_AREA_FIRST + 1) @@ -426,19 +444,23 @@ #define GADGET_ID_MAGIC_BALL_CONTENT_5 (GADGET_ID_DRAWING_AREA_FIRST + 14) #define GADGET_ID_MAGIC_BALL_CONTENT_6 (GADGET_ID_DRAWING_AREA_FIRST + 15) #define GADGET_ID_MAGIC_BALL_CONTENT_7 (GADGET_ID_DRAWING_AREA_FIRST + 16) -#define GADGET_ID_AMOEBA_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 17) -#define GADGET_ID_CUSTOM_GRAPHIC (GADGET_ID_DRAWING_AREA_FIRST + 18) -#define GADGET_ID_CUSTOM_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 19) -#define GADGET_ID_CUSTOM_MOVE_ENTER (GADGET_ID_DRAWING_AREA_FIRST + 20) -#define GADGET_ID_CUSTOM_MOVE_LEAVE (GADGET_ID_DRAWING_AREA_FIRST + 21) -#define GADGET_ID_CUSTOM_CHANGE_TARGET (GADGET_ID_DRAWING_AREA_FIRST + 22) -#define GADGET_ID_CUSTOM_CHANGE_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 23) -#define GADGET_ID_CUSTOM_CHANGE_TRIGGER (GADGET_ID_DRAWING_AREA_FIRST + 24) -#define GADGET_ID_GROUP_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 25) -#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 26) +#define GADGET_ID_ANDROID_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 17) +#define GADGET_ID_AMOEBA_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 18) +#define GADGET_ID_START_ELEMENT (GADGET_ID_DRAWING_AREA_FIRST + 19) +#define GADGET_ID_ARTWORK_ELEMENT (GADGET_ID_DRAWING_AREA_FIRST + 20) +#define GADGET_ID_EXPLOSION_ELEMENT (GADGET_ID_DRAWING_AREA_FIRST + 21) +#define GADGET_ID_CUSTOM_GRAPHIC (GADGET_ID_DRAWING_AREA_FIRST + 22) +#define GADGET_ID_CUSTOM_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 23) +#define GADGET_ID_CUSTOM_MOVE_ENTER (GADGET_ID_DRAWING_AREA_FIRST + 24) +#define GADGET_ID_CUSTOM_MOVE_LEAVE (GADGET_ID_DRAWING_AREA_FIRST + 25) +#define GADGET_ID_CUSTOM_CHANGE_TARGET (GADGET_ID_DRAWING_AREA_FIRST + 26) +#define GADGET_ID_CUSTOM_CHANGE_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 27) +#define GADGET_ID_CUSTOM_CHANGE_TRIGGER (GADGET_ID_DRAWING_AREA_FIRST + 28) +#define GADGET_ID_GROUP_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 29) +#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 30) /* text input identifiers */ -#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 27) +#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 31) #define GADGET_ID_LEVEL_NAME (GADGET_ID_TEXT_INPUT_FIRST + 0) #define GADGET_ID_LEVEL_AUTHOR (GADGET_ID_TEXT_INPUT_FIRST + 1) @@ -454,31 +476,36 @@ #define GADGET_ID_TIME_OR_STEPS (GADGET_ID_SELECTBOX_FIRST + 0) #define GADGET_ID_GAME_ENGINE_TYPE (GADGET_ID_SELECTBOX_FIRST + 1) -#define GADGET_ID_CUSTOM_WALK_TO_ACTION (GADGET_ID_SELECTBOX_FIRST + 2) -#define GADGET_ID_CUSTOM_EXPLOSION_TYPE (GADGET_ID_SELECTBOX_FIRST + 3) -#define GADGET_ID_CUSTOM_DEADLINESS (GADGET_ID_SELECTBOX_FIRST + 4) -#define GADGET_ID_CUSTOM_MOVE_PATTERN (GADGET_ID_SELECTBOX_FIRST + 5) -#define GADGET_ID_CUSTOM_MOVE_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 6) -#define GADGET_ID_CUSTOM_MOVE_STEPSIZE (GADGET_ID_SELECTBOX_FIRST + 7) -#define GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE (GADGET_ID_SELECTBOX_FIRST + 8) -#define GADGET_ID_CUSTOM_SMASH_TARGETS (GADGET_ID_SELECTBOX_FIRST + 9) -#define GADGET_ID_CUSTOM_SLIPPERY_TYPE (GADGET_ID_SELECTBOX_FIRST + 10) -#define GADGET_ID_CUSTOM_ACCESS_TYPE (GADGET_ID_SELECTBOX_FIRST + 11) -#define GADGET_ID_CUSTOM_ACCESS_LAYER (GADGET_ID_SELECTBOX_FIRST + 12) -#define GADGET_ID_CUSTOM_ACCESS_PROTECTED (GADGET_ID_SELECTBOX_FIRST + 13) -#define GADGET_ID_CUSTOM_ACCESS_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 14) -#define GADGET_ID_CHANGE_TIME_UNITS (GADGET_ID_SELECTBOX_FIRST + 15) -#define GADGET_ID_CHANGE_DIRECT_ACTION (GADGET_ID_SELECTBOX_FIRST + 16) -#define GADGET_ID_CHANGE_OTHER_ACTION (GADGET_ID_SELECTBOX_FIRST + 17) -#define GADGET_ID_CHANGE_SIDE (GADGET_ID_SELECTBOX_FIRST + 18) -#define GADGET_ID_CHANGE_PLAYER (GADGET_ID_SELECTBOX_FIRST + 19) -#define GADGET_ID_CHANGE_PAGE (GADGET_ID_SELECTBOX_FIRST + 20) -#define GADGET_ID_CHANGE_REPLACE_WHEN (GADGET_ID_SELECTBOX_FIRST + 21) -#define GADGET_ID_SELECT_CHANGE_PAGE (GADGET_ID_SELECTBOX_FIRST + 22) -#define GADGET_ID_GROUP_CHOICE_MODE (GADGET_ID_SELECTBOX_FIRST + 23) +#define GADGET_ID_WIND_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 2) +#define GADGET_ID_PLAYER_SPEED (GADGET_ID_SELECTBOX_FIRST + 3) +#define GADGET_ID_CUSTOM_WALK_TO_ACTION (GADGET_ID_SELECTBOX_FIRST + 4) +#define GADGET_ID_CUSTOM_EXPLOSION_TYPE (GADGET_ID_SELECTBOX_FIRST + 5) +#define GADGET_ID_CUSTOM_DEADLINESS (GADGET_ID_SELECTBOX_FIRST + 6) +#define GADGET_ID_CUSTOM_MOVE_PATTERN (GADGET_ID_SELECTBOX_FIRST + 7) +#define GADGET_ID_CUSTOM_MOVE_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 8) +#define GADGET_ID_CUSTOM_MOVE_STEPSIZE (GADGET_ID_SELECTBOX_FIRST + 9) +#define GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE (GADGET_ID_SELECTBOX_FIRST + 10) +#define GADGET_ID_CUSTOM_SMASH_TARGETS (GADGET_ID_SELECTBOX_FIRST + 11) +#define GADGET_ID_CUSTOM_SLIPPERY_TYPE (GADGET_ID_SELECTBOX_FIRST + 12) +#define GADGET_ID_CUSTOM_ACCESS_TYPE (GADGET_ID_SELECTBOX_FIRST + 13) +#define GADGET_ID_CUSTOM_ACCESS_LAYER (GADGET_ID_SELECTBOX_FIRST + 14) +#define GADGET_ID_CUSTOM_ACCESS_PROTECTED (GADGET_ID_SELECTBOX_FIRST + 15) +#define GADGET_ID_CUSTOM_ACCESS_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 16) +#define GADGET_ID_CHANGE_TIME_UNITS (GADGET_ID_SELECTBOX_FIRST + 17) +#define GADGET_ID_CHANGE_DIRECT_ACTION (GADGET_ID_SELECTBOX_FIRST + 18) +#define GADGET_ID_CHANGE_OTHER_ACTION (GADGET_ID_SELECTBOX_FIRST + 19) +#define GADGET_ID_CHANGE_SIDE (GADGET_ID_SELECTBOX_FIRST + 20) +#define GADGET_ID_CHANGE_PLAYER (GADGET_ID_SELECTBOX_FIRST + 21) +#define GADGET_ID_CHANGE_PAGE (GADGET_ID_SELECTBOX_FIRST + 22) +#define GADGET_ID_CHANGE_REPLACE_WHEN (GADGET_ID_SELECTBOX_FIRST + 23) +#define GADGET_ID_ACTION_TYPE (GADGET_ID_SELECTBOX_FIRST + 24) +#define GADGET_ID_ACTION_MODE (GADGET_ID_SELECTBOX_FIRST + 25) +#define GADGET_ID_ACTION_ARG (GADGET_ID_SELECTBOX_FIRST + 26) +#define GADGET_ID_SELECT_CHANGE_PAGE (GADGET_ID_SELECTBOX_FIRST + 27) +#define GADGET_ID_GROUP_CHOICE_MODE (GADGET_ID_SELECTBOX_FIRST + 28) /* textbutton identifiers */ -#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 24) +#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 29) #define GADGET_ID_PROPERTIES_INFO (GADGET_ID_TEXTBUTTON_FIRST + 0) #define GADGET_ID_PROPERTIES_CONFIG (GADGET_ID_TEXTBUTTON_FIRST + 1) @@ -524,41 +551,49 @@ #define GADGET_ID_STICK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 4) #define GADGET_ID_EM_SLIPPERY_GEMS (GADGET_ID_CHECKBUTTON_FIRST + 5) #define GADGET_ID_USE_SPRING_BUG (GADGET_ID_CHECKBUTTON_FIRST + 6) -#define GADGET_ID_GROW_INTO_DIGGABLE (GADGET_ID_CHECKBUTTON_FIRST + 7) -#define GADGET_ID_DOUBLE_SPEED (GADGET_ID_CHECKBUTTON_FIRST + 8) -#define GADGET_ID_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 9) -#define GADGET_ID_SP_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 10) -#define GADGET_ID_INSTANT_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 11) -#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 12) -#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 13) -#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 14) -#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 15) -#define GADGET_ID_CUSTOM_INDESTRUCTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 16) -#define GADGET_ID_CUSTOM_CAN_EXPLODE (GADGET_ID_CHECKBUTTON_FIRST + 17) -#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 18) -#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 19) -#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 20) -#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 21) -#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 22) -#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 23) -#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 24) -#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 25) -#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 26) -#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 27) -#define GADGET_ID_CUSTOM_GRAV_REACHABLE (GADGET_ID_CHECKBUTTON_FIRST + 28) -#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 29) -#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 30) -#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 31) -#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 32) -#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 33) -#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 34) -#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 35) -#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 36) -#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 37) -#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 38) +#define GADGET_ID_USE_TIME_ORB_BUG (GADGET_ID_CHECKBUTTON_FIRST + 7) +#define GADGET_ID_RANDOM_BALL_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 8) +#define GADGET_ID_INITIAL_BALL_STATE (GADGET_ID_CHECKBUTTON_FIRST + 9) +#define GADGET_ID_GROW_INTO_DIGGABLE (GADGET_ID_CHECKBUTTON_FIRST + 10) +#define GADGET_ID_BLOCK_SNAP_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 11) +#define GADGET_ID_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 12) +#define GADGET_ID_SP_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 13) +#define GADGET_ID_INSTANT_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 14) +#define GADGET_ID_USE_START_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 15) +#define GADGET_ID_USE_ARTWORK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 16) +#define GADGET_ID_USE_EXPLOSION_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 17) +#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 18) +#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 19) +#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 20) +#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 21) +#define GADGET_ID_CUSTOM_INDESTRUCTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 22) +#define GADGET_ID_CUSTOM_CAN_EXPLODE (GADGET_ID_CHECKBUTTON_FIRST + 23) +#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 24) +#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 25) +#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 26) +#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 27) +#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 28) +#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 29) +#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 30) +#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 31) +#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 32) +#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 33) +#define GADGET_ID_CUSTOM_GRAV_REACHABLE (GADGET_ID_CHECKBUTTON_FIRST + 34) +#define GADGET_ID_CUSTOM_USE_LAST_VALUE (GADGET_ID_CHECKBUTTON_FIRST + 35) +#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 36) +#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 37) +#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 38) +#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 39) +#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 40) +#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 41) +#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 42) +#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 43) +#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 44) +#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 45) +#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 46) /* gadgets for buttons in element list */ -#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 39) +#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 47) #define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \ ED_NUM_ELEMENTLIST_BUTTONS - 1) @@ -579,25 +614,31 @@ #define ED_COUNTER_ID_LEVEL_RANDOM 6 #define ED_COUNTER_ID_ELEMENT_VALUE1 7 #define ED_COUNTER_ID_ELEMENT_VALUE2 8 -#define ED_COUNTER_ID_YAMYAM_CONTENT 9 -#define ED_COUNTER_ID_ENVELOPE_XSIZE 10 -#define ED_COUNTER_ID_ENVELOPE_YSIZE 11 -#define ED_COUNTER_ID_CUSTOM_SCORE 12 -#define ED_COUNTER_ID_CUSTOM_GEMCOUNT 13 -#define ED_COUNTER_ID_PUSH_DELAY_FIX 14 -#define ED_COUNTER_ID_PUSH_DELAY_RND 15 -#define ED_COUNTER_ID_DROP_DELAY_FIX 16 -#define ED_COUNTER_ID_DROP_DELAY_RND 17 -#define ED_COUNTER_ID_MOVE_DELAY_FIX 18 -#define ED_COUNTER_ID_MOVE_DELAY_RND 19 -#define ED_COUNTER_ID_EXPLOSION_DELAY 20 -#define ED_COUNTER_ID_IGNITION_DELAY 21 -#define ED_COUNTER_ID_GROUP_CONTENT 22 -#define ED_COUNTER_ID_CHANGE_DELAY_FIX 23 -#define ED_COUNTER_ID_CHANGE_DELAY_RND 24 -#define ED_COUNTER_ID_CHANGE_CONT_RND 25 - -#define ED_NUM_COUNTERBUTTONS 26 +#define ED_COUNTER_ID_ELEMENT_VALUE3 9 +#define ED_COUNTER_ID_ELEMENT_VALUE4 10 +#define ED_COUNTER_ID_YAMYAM_CONTENT 11 +#define ED_COUNTER_ID_BALL_CONTENT 12 +#define ED_COUNTER_ID_ANDROID_CONTENT 13 +#define ED_COUNTER_ID_ENVELOPE_XSIZE 14 +#define ED_COUNTER_ID_ENVELOPE_YSIZE 15 +#define ED_COUNTER_ID_CUSTOM_SCORE 16 +#define ED_COUNTER_ID_CUSTOM_GEMCOUNT 17 +#define ED_COUNTER_ID_CUSTOM_VALUE_FIX 18 +#define ED_COUNTER_ID_CUSTOM_VALUE_RND 19 +#define ED_COUNTER_ID_PUSH_DELAY_FIX 20 +#define ED_COUNTER_ID_PUSH_DELAY_RND 21 +#define ED_COUNTER_ID_DROP_DELAY_FIX 22 +#define ED_COUNTER_ID_DROP_DELAY_RND 23 +#define ED_COUNTER_ID_MOVE_DELAY_FIX 24 +#define ED_COUNTER_ID_MOVE_DELAY_RND 25 +#define ED_COUNTER_ID_EXPLOSION_DELAY 26 +#define ED_COUNTER_ID_IGNITION_DELAY 27 +#define ED_COUNTER_ID_GROUP_CONTENT 28 +#define ED_COUNTER_ID_CHANGE_DELAY_FIX 29 +#define ED_COUNTER_ID_CHANGE_DELAY_RND 30 +#define ED_COUNTER_ID_CHANGE_CONT_RND 31 + +#define ED_NUM_COUNTERBUTTONS 32 #define ED_COUNTER_ID_LEVEL_FIRST ED_COUNTER_ID_LEVEL_XSIZE #define ED_COUNTER_ID_LEVEL_LAST ED_COUNTER_ID_LEVEL_RANDOM @@ -656,33 +697,38 @@ /* values for selectbox gadgets */ #define ED_SELECTBOX_ID_TIME_OR_STEPS 0 #define ED_SELECTBOX_ID_GAME_ENGINE_TYPE 1 -#define ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE 2 -#define ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER 3 -#define ED_SELECTBOX_ID_CUSTOM_ACCESS_PROTECTED 4 -#define ED_SELECTBOX_ID_CUSTOM_ACCESS_DIRECTION 5 -#define ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION 6 -#define ED_SELECTBOX_ID_CUSTOM_MOVE_PATTERN 7 -#define ED_SELECTBOX_ID_CUSTOM_MOVE_DIRECTION 8 -#define ED_SELECTBOX_ID_CUSTOM_MOVE_STEPSIZE 9 -#define ED_SELECTBOX_ID_CUSTOM_MOVE_LEAVE_TYPE 10 -#define ED_SELECTBOX_ID_CUSTOM_SMASH_TARGETS 11 -#define ED_SELECTBOX_ID_CUSTOM_SLIPPERY_TYPE 12 -#define ED_SELECTBOX_ID_CUSTOM_DEADLINESS 13 -#define ED_SELECTBOX_ID_CUSTOM_EXPLOSION_TYPE 14 -#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS 15 -#define ED_SELECTBOX_ID_CHANGE_DIRECT_ACTION 16 -#define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION 17 -#define ED_SELECTBOX_ID_CHANGE_SIDE 18 -#define ED_SELECTBOX_ID_CHANGE_PLAYER 19 -#define ED_SELECTBOX_ID_CHANGE_PAGE 20 -#define ED_SELECTBOX_ID_CHANGE_REPLACE_WHEN 21 -#define ED_SELECTBOX_ID_SELECT_CHANGE_PAGE 22 -#define ED_SELECTBOX_ID_GROUP_CHOICE_MODE 23 - -#define ED_NUM_SELECTBOX 24 +#define ED_SELECTBOX_ID_WIND_DIRECTION 2 +#define ED_SELECTBOX_ID_PLAYER_SPEED 3 +#define ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE 4 +#define ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER 5 +#define ED_SELECTBOX_ID_CUSTOM_ACCESS_PROTECTED 6 +#define ED_SELECTBOX_ID_CUSTOM_ACCESS_DIRECTION 7 +#define ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION 8 +#define ED_SELECTBOX_ID_CUSTOM_MOVE_PATTERN 9 +#define ED_SELECTBOX_ID_CUSTOM_MOVE_DIRECTION 10 +#define ED_SELECTBOX_ID_CUSTOM_MOVE_STEPSIZE 11 +#define ED_SELECTBOX_ID_CUSTOM_MOVE_LEAVE_TYPE 12 +#define ED_SELECTBOX_ID_CUSTOM_SMASH_TARGETS 13 +#define ED_SELECTBOX_ID_CUSTOM_SLIPPERY_TYPE 14 +#define ED_SELECTBOX_ID_CUSTOM_DEADLINESS 15 +#define ED_SELECTBOX_ID_CUSTOM_EXPLOSION_TYPE 16 +#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS 17 +#define ED_SELECTBOX_ID_CHANGE_DIRECT_ACTION 18 +#define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION 19 +#define ED_SELECTBOX_ID_CHANGE_SIDE 20 +#define ED_SELECTBOX_ID_CHANGE_PLAYER 21 +#define ED_SELECTBOX_ID_CHANGE_PAGE 22 +#define ED_SELECTBOX_ID_CHANGE_REPLACE_WHEN 23 +#define ED_SELECTBOX_ID_ACTION_TYPE 24 +#define ED_SELECTBOX_ID_ACTION_MODE 25 +#define ED_SELECTBOX_ID_ACTION_ARG 26 +#define ED_SELECTBOX_ID_SELECT_CHANGE_PAGE 27 +#define ED_SELECTBOX_ID_GROUP_CHOICE_MODE 28 + +#define ED_NUM_SELECTBOX 29 #define ED_SELECTBOX_ID_LEVEL_FIRST ED_SELECTBOX_ID_TIME_OR_STEPS -#define ED_SELECTBOX_ID_LEVEL_LAST ED_SELECTBOX_ID_GAME_ENGINE_TYPE +#define ED_SELECTBOX_ID_LEVEL_LAST ED_SELECTBOX_ID_WIND_DIRECTION #define ED_SELECTBOX_ID_CUSTOM1_FIRST ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE #define ED_SELECTBOX_ID_CUSTOM1_LAST ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION @@ -729,40 +775,48 @@ #define ED_CHECKBUTTON_ID_STICK_ELEMENT 2 #define ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS 3 #define ED_CHECKBUTTON_ID_USE_SPRING_BUG 4 -#define ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE 5 -#define ED_CHECKBUTTON_ID_DOUBLE_SPEED 6 -#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 7 -#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 8 -#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 9 -#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 10 -#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 11 -#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 12 -#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 13 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 14 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 15 -#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 16 -#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 17 -#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 18 -#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 19 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 20 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 21 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 22 -#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 23 -#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 24 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 25 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 26 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 27 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 28 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 29 -#define ED_CHECKBUTTON_ID_CHANGE_DELAY 30 -#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 31 -#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 32 -#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 33 -#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 34 -#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 35 -#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 36 - -#define ED_NUM_CHECKBUTTONS 37 +#define ED_CHECKBUTTON_ID_USE_TIME_ORB_BUG 5 +#define ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT 6 +#define ED_CHECKBUTTON_ID_INITIAL_BALL_STATE 7 +#define ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE 8 +#define ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD 9 +#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 10 +#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 11 +#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 12 +#define ED_CHECKBUTTON_ID_USE_START_ELEMENT 13 +#define ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT 14 +#define ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT 15 +#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 16 +#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 17 +#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 18 +#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 19 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 20 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 21 +#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 22 +#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 23 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 24 +#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 25 +#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 26 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 27 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 28 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 29 +#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 30 +#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 31 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 32 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 33 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 34 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 35 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 36 +#define ED_CHECKBUTTON_ID_CHANGE_DELAY 37 +#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 38 +#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 39 +#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 40 +#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 41 +#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 42 +#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 43 +#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 44 + +#define ED_NUM_CHECKBUTTONS 45 #define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_INITIAL_GRAVITY #define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED @@ -775,7 +829,7 @@ #define ED_CHECKBUTTON_ID_CUSTOM_LAST ED_CHECKBUTTON_ID_CUSTOM2_LAST #define ED_CHECKBUTTON_ID_CHANGE_FIRST ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE -#define ED_CHECKBUTTON_ID_CHANGE_LAST ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM +#define ED_CHECKBUTTON_ID_CHANGE_LAST ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION /* values for radiobutton gadgets */ #define ED_RADIOBUTTON_ID_PERCENTAGE 0 @@ -804,18 +858,22 @@ #define ED_DRAWING_ID_MAGIC_BALL_CONTENT_5 14 #define ED_DRAWING_ID_MAGIC_BALL_CONTENT_6 15 #define ED_DRAWING_ID_MAGIC_BALL_CONTENT_7 16 -#define ED_DRAWING_ID_AMOEBA_CONTENT 17 -#define ED_DRAWING_ID_CUSTOM_GRAPHIC 18 -#define ED_DRAWING_ID_CUSTOM_CONTENT 19 -#define ED_DRAWING_ID_CUSTOM_MOVE_ENTER 20 -#define ED_DRAWING_ID_CUSTOM_MOVE_LEAVE 21 -#define ED_DRAWING_ID_CUSTOM_CHANGE_TARGET 22 -#define ED_DRAWING_ID_CUSTOM_CHANGE_CONTENT 23 -#define ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER 24 -#define ED_DRAWING_ID_GROUP_CONTENT 25 -#define ED_DRAWING_ID_RANDOM_BACKGROUND 26 - -#define ED_NUM_DRAWING_AREAS 27 +#define ED_DRAWING_ID_ANDROID_CONTENT 17 +#define ED_DRAWING_ID_AMOEBA_CONTENT 18 +#define ED_DRAWING_ID_START_ELEMENT 19 +#define ED_DRAWING_ID_ARTWORK_ELEMENT 20 +#define ED_DRAWING_ID_EXPLOSION_ELEMENT 21 +#define ED_DRAWING_ID_CUSTOM_GRAPHIC 22 +#define ED_DRAWING_ID_CUSTOM_CONTENT 23 +#define ED_DRAWING_ID_CUSTOM_MOVE_ENTER 24 +#define ED_DRAWING_ID_CUSTOM_MOVE_LEAVE 25 +#define ED_DRAWING_ID_CUSTOM_CHANGE_TARGET 26 +#define ED_DRAWING_ID_CUSTOM_CHANGE_CONTENT 27 +#define ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER 28 +#define ED_DRAWING_ID_GROUP_CONTENT 29 +#define ED_DRAWING_ID_RANDOM_BACKGROUND 30 + +#define ED_NUM_DRAWING_AREAS 31 /* @@ -856,7 +914,7 @@ /* values for elements with count for collecting */ #define MIN_COLLECT_COUNT 0 -#define MAX_COLLECT_COUNT 100 +#define MAX_COLLECT_COUNT 255 /* values for random placement */ #define RANDOM_USE_PERCENTAGE 0 @@ -987,7 +1045,7 @@ static struct 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 10 sec/steps left:", NULL, NULL + "score for each second/step left:", NULL, NULL }, { ED_LEVEL_SETTINGS_XPOS(0), ED_COUNTER2_YPOS(8), @@ -1016,6 +1074,22 @@ static struct NULL, /* will be set when used */ NULL, NULL, NULL }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + MIN_SCORE, MAX_SCORE, + GADGET_ID_ELEMENT_VALUE3_DOWN, GADGET_ID_ELEMENT_VALUE3_UP, + GADGET_ID_ELEMENT_VALUE3_TEXT, GADGET_ID_NONE, + NULL, /* will be set when used */ + NULL, NULL, NULL + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + MIN_SCORE, MAX_SCORE, + GADGET_ID_ELEMENT_VALUE4_DOWN, GADGET_ID_ELEMENT_VALUE4_UP, + GADGET_ID_ELEMENT_VALUE4_TEXT, GADGET_ID_NONE, + NULL, /* will be set when used */ + NULL, NULL, NULL + }, { ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), MIN_ELEMENT_CONTENTS, MAX_ELEMENT_CONTENTS, @@ -1024,6 +1098,22 @@ static struct &level.num_yamyam_contents, NULL, NULL, "number of content areas" }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), + MIN_ELEMENT_CONTENTS, MAX_ELEMENT_CONTENTS, + GADGET_ID_BALL_CONTENT_DOWN, GADGET_ID_BALL_CONTENT_UP, + GADGET_ID_BALL_CONTENT_TEXT, GADGET_ID_NONE, + &level.num_ball_contents, + NULL, NULL, "number of content areas" + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), + MIN_ANDROID_ELEMENTS, MAX_ANDROID_ELEMENTS, + GADGET_ID_ANDROID_CONTENT_DOWN, GADGET_ID_ANDROID_CONTENT_UP, + GADGET_ID_ANDROID_CONTENT_TEXT, GADGET_ID_NONE, + &level.num_android_clone_elements, + NULL, NULL, "number of clonable elements" + }, { ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), MIN_ENVELOPE_XSIZE, MAX_ENVELOPE_XSIZE, @@ -1048,16 +1138,32 @@ static struct MIN_SCORE, MAX_SCORE, GADGET_ID_CUSTOM_SCORE_DOWN, GADGET_ID_CUSTOM_SCORE_UP, GADGET_ID_CUSTOM_SCORE_TEXT, GADGET_ID_NONE, - &custom_element.collect_score, - NULL, "score", " " + &custom_element.collect_score_initial, + NULL, "CE score", " " }, { -1, ED_ELEMENT_SETTINGS_YPOS(6), MIN_COLLECT_COUNT, MAX_COLLECT_COUNT, GADGET_ID_CUSTOM_GEMCOUNT_DOWN, GADGET_ID_CUSTOM_GEMCOUNT_UP, GADGET_ID_CUSTOM_GEMCOUNT_TEXT, GADGET_ID_CUSTOM_SCORE_UP, - &custom_element.collect_count, - NULL, "count", NULL + &custom_element.collect_count_initial, + NULL, "CE count", NULL + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(12), + 0, 9999, + GADGET_ID_CUSTOM_VALUE_FIX_DOWN, GADGET_ID_CUSTOM_VALUE_FIX_UP, + GADGET_ID_CUSTOM_VALUE_FIX_TEXT, GADGET_ID_NONE, + &custom_element.ce_value_fixed_initial, + NULL, "CE value", NULL + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(12), + 0, 9999, + GADGET_ID_CUSTOM_VALUE_RND_DOWN, GADGET_ID_CUSTOM_VALUE_RND_UP, + GADGET_ID_CUSTOM_VALUE_RND_TEXT, GADGET_ID_CUSTOM_VALUE_FIX_UP, + &custom_element.ce_value_random_initial, + NULL, "+random", NULL }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(7), @@ -1146,7 +1252,7 @@ static struct GADGET_ID_CHANGE_DELAY_FIX_DOWN, GADGET_ID_CHANGE_DELAY_FIX_UP, GADGET_ID_CHANGE_DELAY_FIX_TEXT, GADGET_ID_NONE, &custom_element_change.delay_fixed, - NULL, "delay", NULL, + NULL, "CE delay", NULL, }, { -1, ED_ELEMENT_SETTINGS_YPOS(2), @@ -1232,6 +1338,30 @@ static struct ValueTextInfo options_game_engine_type[] = { -1, NULL } }; +static struct ValueTextInfo options_wind_direction[] = +{ + { MV_START_NONE, "none" }, + { MV_START_LEFT, "left" }, + { MV_START_RIGHT, "right" }, + { MV_START_UP, "up" }, + { MV_START_DOWN, "down" }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_player_speed[] = +{ + { 0, "frozen" }, + { 1, "very slow" }, + { 2, "slow" }, + { 4, "normal" }, + { 8, "fast" }, + { 16, "very fast" }, + { 32, "ultrafast" }, + + { -1, NULL } +}; + static struct ValueTextInfo options_access_type[] = { { EP_WALKABLE, "walkable" }, @@ -1259,7 +1389,7 @@ static struct ValueTextInfo options_access_protected[] = static struct ValueTextInfo options_access_direction[] = { - { MV_NO_DIRECTIONS, "no direction" }, + { MV_NO_DIRECTION, "no direction" }, { MV_LEFT, "left" }, { MV_RIGHT, "right" }, { MV_UP, "up" }, @@ -1299,6 +1429,7 @@ static struct ValueTextInfo options_move_pattern[] = { MV_HORIZONTAL, "horizontal" }, { MV_VERTICAL, "vertical" }, { MV_ALL_DIRECTIONS, "all directions" }, + { MV_WIND_DIRECTION, "wind direction" }, { MV_TOWARDS_PLAYER, "towards player" }, { MV_AWAY_FROM_PLAYER, "away from player" }, { MV_ALONG_LEFT_SIDE, "along left side" }, @@ -1337,9 +1468,7 @@ static struct ValueTextInfo options_move_stepsize[] = { 4, "normal" }, { 8, "fast" }, { 16, "very fast" }, -#if 1 { 32, "even faster" }, -#endif { -1, NULL } }; @@ -1388,9 +1517,6 @@ static struct ValueTextInfo options_explosion_type[] = { EXPLODES_3X3, "3x3" }, { EXPLODES_CROSS, "3+3" }, { EXPLODES_1X1, "1x1" }, -#if 0 - { EP_INDESTRUCTIBLE, "indestructible" }, -#endif { -1, NULL } }; @@ -1407,24 +1533,21 @@ static struct ValueTextInfo options_change_direct_action[] = { { CE_TOUCHED_BY_PLAYER, "touched by player" }, { CE_PRESSED_BY_PLAYER, "pressed by player" }, + { CE_SWITCHED_BY_PLAYER, "switched by player" }, + { CE_SNAPPED_BY_PLAYER, "snapped by player" }, { CE_PUSHED_BY_PLAYER, "pushed by player" }, { CE_ENTERED_BY_PLAYER, "entered by player" }, { CE_LEFT_BY_PLAYER, "left by player" }, { CE_DROPPED_BY_PLAYER, "dropped/thrown by player" }, { CE_SWITCHED, "switched" }, -#if 1 { CE_HITTING_SOMETHING, "hitting something" }, { CE_HIT_BY_SOMETHING, "hit by something" }, -#else - { CE_HITTING_SOMETHING, "collision" }, -#endif - #if 0 { CE_BLOCKED, "blocked" }, #endif - { CE_IMPACT, "impact (on something)" }, { CE_SMASHED, "smashed (from above)" }, + { CE_VALUE_GETS_ZERO, "CE value gets 0" }, { -1, NULL } }; @@ -1433,6 +1556,8 @@ static struct ValueTextInfo options_change_other_action[] = { { CE_PLAYER_TOUCHES_X, "player touches" }, { CE_PLAYER_PRESSES_X, "player presses" }, + { CE_PLAYER_SWITCHES_X, "player switches" }, + { CE_PLAYER_SNAPS_X, "player snaps" }, { CE_PLAYER_PUSHES_X, "player pushes" }, { CE_PLAYER_ENTERS_X, "player enters" }, { CE_PLAYER_LEAVES_X, "player leaves" }, @@ -1440,13 +1565,15 @@ static struct ValueTextInfo options_change_other_action[] = { CE_PLAYER_COLLECTS_X, "player collects" }, { CE_PLAYER_DROPS_X, "player drops/throws" }, { CE_TOUCHING_X, "touching" }, -#if 1 { CE_HITTING_X, "hitting" }, + { CE_DIGGING_X, "digging" }, { CE_HIT_BY_X, "hit by" }, -#endif { CE_SWITCH_OF_X, "switch of" }, { CE_CHANGE_OF_X, "change by page of" }, { CE_EXPLOSION_OF_X, "explosion of" }, + { CE_MOVE_OF_X, "move of" }, + { CE_CREATION_OF_X, "creation of" }, + { CE_VALUE_GETS_ZERO_OF_X, "CE value gets 0 of" }, { -1, NULL } }; @@ -1526,6 +1653,234 @@ static struct ValueTextInfo options_change_replace_when[] = { -1, NULL } }; +static struct ValueTextInfo options_action_type[] = +{ + { CA_NO_ACTION, "no action" }, + { CA_UNDEFINED, " " }, + { CA_HEADLINE_LEVEL_ACTIONS, "[level actions]" }, + { CA_RESTART_LEVEL, "restart level" }, + { CA_SHOW_ENVELOPE, "show envelope" }, + { CA_SET_LEVEL_TIME, "set time" }, + { CA_SET_LEVEL_SCORE, "set score" }, + { CA_SET_LEVEL_GEMS, "set needed gems" }, + { CA_SET_LEVEL_GRAVITY, "set gravity" }, + { CA_SET_LEVEL_WIND, "set wind dir." }, + { CA_UNDEFINED, " " }, + { CA_HEADLINE_PLAYER_ACTIONS, "[player actions]" }, + { CA_MOVE_PLAYER, "move player" }, + { CA_EXIT_PLAYER, "exit player" }, + { CA_KILL_PLAYER, "kill player" }, + { CA_SET_PLAYER_KEYS, "set keys" }, + { CA_SET_PLAYER_SPEED, "set speed" }, + { CA_SET_PLAYER_SHIELD, "set shield" }, + { CA_SET_PLAYER_ARTWORK, "set artwork" }, + { CA_UNDEFINED, " " }, + { CA_HEADLINE_CE_ACTIONS, "[CE actions]" }, + { CA_SET_CE_SCORE, "set CE score" }, + { CA_SET_CE_VALUE, "set CE value" }, + { CA_UNDEFINED, " " }, + { CA_HEADLINE_ENGINE_ACTIONS, "[engine actions]" }, + { CA_SET_ENGINE_SCAN_MODE, "set scan mode" }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_action_mode_none[] = +{ + { CA_ARG_UNDEFINED, " " }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_action_mode_assign[] = +{ + { CA_MODE_SET, "=" }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_action_mode_add_remove[] = +{ + { CA_MODE_ADD, "+" }, + { CA_MODE_SUBTRACT, "-" }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_action_mode_calculate[] = +{ + { CA_MODE_SET, "=" }, + { CA_MODE_ADD, "+" }, + { CA_MODE_SUBTRACT, "-" }, + { CA_MODE_MULTIPLY, "*" }, + { CA_MODE_DIVIDE, "/" }, + { CA_MODE_MODULO, "%" }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_action_arg_none[] = +{ + { CA_ARG_UNDEFINED, " " }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_action_arg_player[] = +{ + { CA_ARG_PLAYER_HEADLINE, "[player]" }, + { CA_ARG_PLAYER_1, "1" }, + { CA_ARG_PLAYER_2, "2" }, + { CA_ARG_PLAYER_3, "3" }, + { CA_ARG_PLAYER_4, "4" }, + { CA_ARG_PLAYER_ANY, "any" }, + { CA_ARG_PLAYER_TRIGGER, "trigger" }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_action_arg_number[] = +{ + { CA_ARG_NUMBER_HEADLINE, "[number]" }, + { CA_ARG_0, "0" }, + { CA_ARG_1, "1" }, + { CA_ARG_2, "2" }, + { CA_ARG_3, "3" }, + { CA_ARG_4, "4" }, + { CA_ARG_5, "5" }, + { CA_ARG_10, "10" }, + { CA_ARG_100, "100" }, + { CA_ARG_1000, "1000" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_NUMBER_MIN, "min" }, + { CA_ARG_NUMBER_MAX, "max" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_NUMBER_RESET, "reset" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_NUMBER_CE_DELAY, "CE delay" }, + { CA_ARG_NUMBER_CE_SCORE, "CE score" }, + { CA_ARG_NUMBER_CE_VALUE, "CE value" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_NUMBER_LEVEL_TIME, "time" }, + { CA_ARG_NUMBER_LEVEL_GEMS, "gems" }, + { CA_ARG_NUMBER_LEVEL_SCORE, "score" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_ELEMENT_HEADLINE, "[CE value" }, + { CA_ARG_ELEMENT_HEADLINE, " of" }, + { CA_ARG_ELEMENT_HEADLINE, " element]" }, + { CA_ARG_ELEMENT_TARGET, "target" }, + { CA_ARG_ELEMENT_TRIGGER, "trigger" }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_action_arg_envelope[] = +{ + { CA_ARG_NUMBER_HEADLINE, "[number]" }, + { CA_ARG_1, "1" }, + { CA_ARG_2, "2" }, + { CA_ARG_3, "3" }, + { CA_ARG_4, "4" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_ELEMENT_HEADLINE, "[element]" }, + { CA_ARG_ELEMENT_TARGET, "target" }, + { CA_ARG_ELEMENT_TRIGGER, "trigger" }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_action_arg_key[] = +{ + { CA_ARG_NUMBER_HEADLINE, "[number]" }, + { CA_ARG_1, "1" }, + { CA_ARG_2, "2" }, + { CA_ARG_3, "3" }, + { CA_ARG_4, "4" }, + { CA_ARG_5, "5" }, + { CA_ARG_6, "6" }, + { CA_ARG_7, "7" }, + { CA_ARG_8, "8" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_ELEMENT_HEADLINE, "[element]" }, + { CA_ARG_ELEMENT_TARGET, "target" }, + { CA_ARG_ELEMENT_TRIGGER, "trigger" }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_action_arg_speed[] = +{ + { CA_ARG_SPEED_HEADLINE, "[speed]" }, + { CA_ARG_SPEED_NOT_MOVING, "frozen" }, + { CA_ARG_SPEED_VERY_SLOW, "very slow" }, + { CA_ARG_SPEED_SLOW, "slow" }, + { CA_ARG_SPEED_NORMAL, "normal" }, + { CA_ARG_SPEED_FAST, "fast" }, + { CA_ARG_SPEED_VERY_FAST, "very fast" }, + { CA_ARG_SPEED_EVEN_FASTER, "ultrafast" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_SPEED_SLOWER, "slower" }, + { CA_ARG_SPEED_FASTER, "faster" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_SPEED_RESET, "reset" }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_action_arg_shield[] = +{ + { CA_ARG_SHIELD_HEADLINE, "[shield]" }, + { CA_ARG_SHIELD_OFF, "off" }, + { CA_ARG_SHIELD_NORMAL, "normal" }, + { CA_ARG_SHIELD_DEADLY, "deadly" }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_action_arg_artwork[] = +{ + { CA_ARG_ELEMENT_HEADLINE, "[element]" }, + { CA_ARG_ELEMENT_TARGET, "target" }, + { CA_ARG_ELEMENT_TRIGGER, "trigger" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_ELEMENT_RESET, "reset" }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_action_arg_gravity[] = +{ + { CA_ARG_GRAVITY_HEADLINE, "[gravity]" }, + { CA_ARG_GRAVITY_ON, "on" }, + { CA_ARG_GRAVITY_OFF, "off" }, + { CA_ARG_GRAVITY_TOGGLE, "toggle" }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_action_arg_direction[] = +{ + { CA_ARG_DIRECTION_HEADLINE, "[dir.]" }, + { CA_ARG_DIRECTION_NONE, "none" }, + { CA_ARG_DIRECTION_LEFT, "left" }, + { CA_ARG_DIRECTION_RIGHT, "right" }, + { CA_ARG_DIRECTION_UP, "up" }, + { CA_ARG_DIRECTION_DOWN, "down" }, + { CA_ARG_DIRECTION_TRIGGER, "trigger" }, + { CA_ARG_DIRECTION_TRIGGER_BACK, "-trigger" }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_action_arg_scan_mode[] = +{ + { CA_ARG_SCAN_MODE_HEADLINE, "[mode]" }, + { CA_ARG_SCAN_MODE_NORMAL, "normal" }, + { CA_ARG_SCAN_MODE_REVERSE, "reverse" }, + + { -1, NULL } +}; + static char options_change_page_strings[MAX_CHANGE_PAGES][10]; static struct ValueTextInfo options_change_page[MAX_CHANGE_PAGES + 1] = { @@ -1543,6 +1898,44 @@ static struct ValueTextInfo options_group_choice_mode[] = { -1, NULL } }; +static struct ValueTextInfo *action_arg_modes[] = +{ + options_action_mode_none, + options_action_mode_assign, + options_action_mode_add_remove, + options_action_mode_calculate, +}; + +static struct +{ + int value; + int mode; + struct ValueTextInfo *options; +} +action_arg_options[] = +{ + { CA_NO_ACTION, 0, options_action_arg_none, }, + { 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_RESTART_LEVEL, 0, options_action_arg_none, }, + { CA_SHOW_ENVELOPE, 0, options_action_arg_envelope, }, + { CA_SET_LEVEL_TIME, 3, options_action_arg_number, }, + { CA_SET_LEVEL_GEMS, 3, options_action_arg_number, }, + { CA_SET_LEVEL_SCORE, 3, options_action_arg_number, }, + { CA_SET_LEVEL_GRAVITY, 1, options_action_arg_gravity, }, + { CA_SET_LEVEL_WIND, 1, options_action_arg_direction, }, + { CA_SET_PLAYER_KEYS, 2, options_action_arg_key, }, + { CA_SET_PLAYER_SPEED, 1, options_action_arg_speed, }, + { CA_SET_PLAYER_SHIELD, 1, options_action_arg_shield, }, + { CA_SET_PLAYER_ARTWORK, 1, options_action_arg_artwork, }, + { CA_SET_CE_SCORE, 3, options_action_arg_number, }, + { CA_SET_CE_VALUE, 3, options_action_arg_number, }, + { CA_SET_ENGINE_SCAN_MODE, 1, options_action_arg_scan_mode, }, + + { -1, FALSE, NULL } +}; + static struct { int x, y; @@ -1572,8 +1965,27 @@ static struct &level.game_engine_type, "game engine:", NULL, "game engine" }, + { + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(12), + GADGET_ID_WIND_DIRECTION, GADGET_ID_NONE, + -1, + options_wind_direction, + &level.wind_direction_initial, + "initial wind direction:", NULL, "initial wind direction" + }, - /* ---------- element settings: configure 1 (custom elements) ----------- */ + /* ---------- element settings: configure (several elements) ------------- */ + + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), + GADGET_ID_PLAYER_SPEED, GADGET_ID_NONE, + -1, + options_player_speed, + &level.initial_player_stepsize, + "initial player speed:", NULL, "initial player speed" + }, + + /* ---------- element settings: configure 1 (custom elements) ------------ */ { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(3), @@ -1616,7 +2028,7 @@ static struct NULL, NULL, "diggable/collectible/pushable" }, - /* ---------- element settings: configure 2 (custom elements) ----------- */ + /* ---------- element settings: configure 2 (custom elements) ------------ */ { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(1), @@ -1715,7 +2127,7 @@ static struct -1, options_change_trigger_side, &custom_element_change.trigger_side, - "at", "side", "element side that causes change" + "at", "side", "element side triggering change" }, { ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(7), @@ -1741,6 +2153,30 @@ static struct &custom_element_change.replace_when, "replace when", NULL, "which elements can be replaced" }, + { + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(13), + GADGET_ID_ACTION_TYPE, GADGET_ID_NONE, + -1, + options_action_type, + &custom_element_change.action_type, + NULL, NULL, "action on specified condition" + }, + { + -1, ED_ELEMENT_SETTINGS_YPOS(13), + GADGET_ID_ACTION_MODE, GADGET_ID_ACTION_TYPE, + -1, + options_action_mode_none, + &custom_element_change.action_mode, + NULL, NULL, "action operator" + }, + { + -1, ED_ELEMENT_SETTINGS_YPOS(13), + GADGET_ID_ACTION_ARG, GADGET_ID_ACTION_MODE, + -1, + options_action_arg_none, + &custom_element_change.action_arg, + NULL, NULL, "action parameter" + }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(14), GADGET_ID_SELECT_CHANGE_PAGE, GADGET_ID_NONE, @@ -1772,7 +2208,6 @@ static struct char *text_left, *text_right, *infotext; } textbutton_info[ED_NUM_TEXTBUTTONS] = { -#if 1 { ED_ELEMENT_SETTINGS_XPOS(0), ED_COUNTER_YPOS(1), GADGET_ID_PROPERTIES_INFO, GADGET_ID_NONE, @@ -1803,26 +2238,6 @@ static struct 8, "Change", NULL, NULL, "Custom element change configuration" }, -#else - { - ED_ELEMENT_SETTINGS_XPOS(0), ED_COUNTER_YPOS(1), - GADGET_ID_PROPERTIES_INFO, GADGET_ID_NONE, - 11, "Information", - NULL, NULL, "Show information about element" - }, - { - ED_ELEMENT_SETTINGS_XPOS(0) + 166, ED_COUNTER_YPOS(1), - GADGET_ID_PROPERTIES_CONFIG, GADGET_ID_NONE, - 11, "Configure", - NULL, NULL, "Configure element properties" - }, - { - ED_ELEMENT_SETTINGS_XPOS(0) + 332, ED_COUNTER_YPOS(1), - GADGET_ID_PROPERTIES_CHANGE, GADGET_ID_NONE, - 11, "Advanced", - NULL, NULL, "Advanced element configuration" - }, -#endif { -1, ED_ELEMENT_SETTINGS_YPOS(2), GADGET_ID_SAVE_AS_TEMPLATE, GADGET_ID_CUSTOM_USE_TEMPLATE, @@ -2041,6 +2456,27 @@ static struct NULL, "use spring pushing bug", "use odd spring pushing behaviour" }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_USE_TIME_ORB_BUG, GADGET_ID_NONE, + &level.use_time_orb_bug, + NULL, + "use time orb bug", "use odd time orb behaviour" + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_RANDOM_BALL_CONTENT, GADGET_ID_NONE, + &level.ball_random, + NULL, + "create single random element", "only create one element from content" + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_INITIAL_BALL_STATE, GADGET_ID_NONE, + &level.ball_state_initial, + NULL, + "magic ball initially activated", "activate magic ball after level start" + }, { ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), GADGET_ID_GROW_INTO_DIGGABLE, GADGET_ID_NONE, @@ -2049,42 +2485,63 @@ static struct "can grow into anything diggable", "grow into more than just sand" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), - GADGET_ID_DOUBLE_SPEED, GADGET_ID_NONE, - &level.double_speed, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(6), + GADGET_ID_BLOCK_SNAP_FIELD, GADGET_ID_NONE, + &level.block_snap_field, NULL, - "double speed movement", "set initial movement speed of player" + "block snapped field when snapping", "use snapping delay to show animation" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), GADGET_ID_BLOCK_LAST_FIELD, GADGET_ID_NONE, &level.block_last_field, NULL, "block last field when moving", "player blocks last field when moving" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), GADGET_ID_SP_BLOCK_LAST_FIELD, GADGET_ID_NONE, &level.sp_block_last_field, NULL, "block last field when moving", "player blocks last field when moving" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), GADGET_ID_INSTANT_RELOCATION, GADGET_ID_NONE, &level.instant_relocation, NULL, "no scrolling when relocating", "player gets relocated without delay" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(7), + GADGET_ID_USE_START_ELEMENT, GADGET_ID_NONE, + &level.use_start_element[0], + NULL, + "use level start element:", "start level at this element's position" + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8), + GADGET_ID_USE_ARTWORK_ELEMENT, GADGET_ID_NONE, + &level.use_artwork_element[0], + NULL, + "use artwork from element:", "use player artwork from other element" + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), + GADGET_ID_USE_EXPLOSION_ELEMENT, GADGET_ID_NONE, + &level.use_explosion_element[0], + NULL, + "use explosion from element:", "use explosion properties from element" + }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), GADGET_ID_CAN_PASS_TO_WALKABLE, GADGET_ID_NONE, &level.can_pass_to_walkable, NULL, "can pass to walkable element", "player can pass to empty or walkable" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), GADGET_ID_CAN_FALL_INTO_ACID, GADGET_ID_NONE, &custom_element_properties[EP_CAN_MOVE_INTO_ACID], NULL, @@ -2137,6 +2594,12 @@ static struct &custom_element_properties[EP_GRAVITY_REACHABLE], NULL, "reachable despite gravity", "player can walk/dig despite gravity" }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(13), + GADGET_ID_CUSTOM_USE_LAST_VALUE, GADGET_ID_NONE, + &custom_element.use_last_ce_value, + NULL, "use last CE value after change", "use last CE value after change" + }, { ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), GADGET_ID_CUSTOM_WALK_TO_OBJECT, GADGET_ID_NONE, @@ -2213,7 +2676,7 @@ static struct ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), GADGET_ID_CUSTOM_CAN_CHANGE, GADGET_ID_NONE, &custom_element_change.can_change, - NULL, "element changes to:", "element can change to other element" + NULL, "element changes to:", "change element on specified condition" }, { ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(2), @@ -2257,135 +2720,178 @@ static struct &custom_element_change.use_random_replace, NULL, NULL, "use percentage for random replace" }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(13), + GADGET_ID_CHANGE_HAS_ACTION, GADGET_ID_NONE, + &custom_element_change.has_action, + NULL, NULL, "execute action on specified condition" + }, }; static struct { int x, y; - int area_xsize, area_ysize; int gadget_id; int gadget_id_align; - char *text_left, *text_right, *text_below; + int *value; + int area_xsize, area_ysize; + char *text_left, *text_right, *text_below, *infotext; } drawingarea_info[ED_NUM_DRAWING_AREAS] = { /* ---------- level playfield content ------------------------------------ */ { - 0, 0, - MAX_ED_FIELDX, MAX_ED_FIELDY, + 0, 0, GADGET_ID_DRAWING_LEVEL, GADGET_ID_NONE, - NULL, NULL, NULL + NULL, MAX_ED_FIELDX, MAX_ED_FIELDY, + NULL, NULL, NULL, NULL }, /* ---------- yam yam content -------------------------------------------- */ { ED_AREA_YAMYAM_CONTENT_XPOS(0), ED_AREA_YAMYAM_CONTENT_YPOS(0), - 3, 3, GADGET_ID_YAMYAM_CONTENT_0, GADGET_ID_NONE, - NULL, NULL, "1" + &level.yamyam_content[0].e[0][0], 3, 3, + NULL, NULL, "1", NULL }, { ED_AREA_YAMYAM_CONTENT_XPOS(1), ED_AREA_YAMYAM_CONTENT_YPOS(1), - 3, 3, GADGET_ID_YAMYAM_CONTENT_1, GADGET_ID_NONE, - NULL, NULL, "2" + &level.yamyam_content[1].e[0][0], 3, 3, + NULL, NULL, "2", NULL }, { ED_AREA_YAMYAM_CONTENT_XPOS(2), ED_AREA_YAMYAM_CONTENT_YPOS(2), - 3, 3, GADGET_ID_YAMYAM_CONTENT_2, GADGET_ID_NONE, - NULL, NULL, "3" + &level.yamyam_content[2].e[0][0], 3, 3, + NULL, NULL, "3", NULL }, { ED_AREA_YAMYAM_CONTENT_XPOS(3), ED_AREA_YAMYAM_CONTENT_YPOS(3), - 3, 3, GADGET_ID_YAMYAM_CONTENT_3, GADGET_ID_NONE, - NULL, NULL, "4" + &level.yamyam_content[3].e[0][0], 3, 3, + NULL, NULL, "4", NULL }, { ED_AREA_YAMYAM_CONTENT_XPOS(4), ED_AREA_YAMYAM_CONTENT_YPOS(4), - 3, 3, GADGET_ID_YAMYAM_CONTENT_4, GADGET_ID_NONE, - NULL, NULL, "5" + &level.yamyam_content[4].e[0][0], 3, 3, + NULL, NULL, "5", NULL }, { ED_AREA_YAMYAM_CONTENT_XPOS(5), ED_AREA_YAMYAM_CONTENT_YPOS(5), - 3, 3, GADGET_ID_YAMYAM_CONTENT_5, GADGET_ID_NONE, - NULL, NULL, "6" + &level.yamyam_content[5].e[0][0], 3, 3, + NULL, NULL, "6", NULL }, { ED_AREA_YAMYAM_CONTENT_XPOS(6), ED_AREA_YAMYAM_CONTENT_YPOS(6), - 3, 3, GADGET_ID_YAMYAM_CONTENT_6, GADGET_ID_NONE, - NULL, NULL, "7" + &level.yamyam_content[6].e[0][0], 3, 3, + NULL, NULL, "7", NULL }, { ED_AREA_YAMYAM_CONTENT_XPOS(7), ED_AREA_YAMYAM_CONTENT_YPOS(7), - 3, 3, GADGET_ID_YAMYAM_CONTENT_7, GADGET_ID_NONE, - NULL, NULL, "8" + &level.yamyam_content[7].e[0][0], 3, 3, + NULL, NULL, "8", NULL }, /* ---------- magic ball content ----------------------------------------- */ { ED_AREA_MAGIC_BALL_CONTENT_XPOS(0), ED_AREA_MAGIC_BALL_CONTENT_YPOS(0), - 3, 3, GADGET_ID_MAGIC_BALL_CONTENT_0, GADGET_ID_NONE, - NULL, NULL, "1" + &level.ball_content[0].e[0][0], 3, 3, + NULL, NULL, "1", NULL }, { ED_AREA_MAGIC_BALL_CONTENT_XPOS(1), ED_AREA_MAGIC_BALL_CONTENT_YPOS(1), - 3, 3, GADGET_ID_MAGIC_BALL_CONTENT_1, GADGET_ID_NONE, - NULL, NULL, "2" + &level.ball_content[1].e[0][0], 3, 3, + NULL, NULL, "2", NULL }, { ED_AREA_MAGIC_BALL_CONTENT_XPOS(2), ED_AREA_MAGIC_BALL_CONTENT_YPOS(2), - 3, 3, GADGET_ID_MAGIC_BALL_CONTENT_2, GADGET_ID_NONE, - NULL, NULL, "3" + &level.ball_content[2].e[0][0], 3, 3, + NULL, NULL, "3", NULL }, { ED_AREA_MAGIC_BALL_CONTENT_XPOS(3), ED_AREA_MAGIC_BALL_CONTENT_YPOS(3), - 3, 3, GADGET_ID_MAGIC_BALL_CONTENT_3, GADGET_ID_NONE, - NULL, NULL, "4" + &level.ball_content[3].e[0][0], 3, 3, + NULL, NULL, "4", NULL }, { ED_AREA_MAGIC_BALL_CONTENT_XPOS(4), ED_AREA_MAGIC_BALL_CONTENT_YPOS(4), - 3, 3, GADGET_ID_MAGIC_BALL_CONTENT_4, GADGET_ID_NONE, - NULL, NULL, "5" + &level.ball_content[4].e[0][0], 3, 3, + NULL, NULL, "5", NULL }, { ED_AREA_MAGIC_BALL_CONTENT_XPOS(5), ED_AREA_MAGIC_BALL_CONTENT_YPOS(5), - 3, 3, GADGET_ID_MAGIC_BALL_CONTENT_5, GADGET_ID_NONE, - NULL, NULL, "6" + &level.ball_content[5].e[0][0], 3, 3, + NULL, NULL, "6", NULL }, { ED_AREA_MAGIC_BALL_CONTENT_XPOS(6), ED_AREA_MAGIC_BALL_CONTENT_YPOS(6), - 3, 3, GADGET_ID_MAGIC_BALL_CONTENT_6, GADGET_ID_NONE, - NULL, NULL, "7" + &level.ball_content[6].e[0][0], 3, 3, + NULL, NULL, "7", NULL }, { ED_AREA_MAGIC_BALL_CONTENT_XPOS(7), ED_AREA_MAGIC_BALL_CONTENT_YPOS(7), - 3, 3, GADGET_ID_MAGIC_BALL_CONTENT_7, GADGET_ID_NONE, - NULL, NULL, "8" + &level.ball_content[7].e[0][0], 3, 3, + NULL, NULL, "8", NULL + }, + + /* ---------- android content -------------------------------------------- */ + + { + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(5), + GADGET_ID_ANDROID_CONTENT, GADGET_ID_NONE, + &level.android_clone_element[0], MAX_ANDROID_ELEMENTS, 1, + "elements:", NULL, NULL, "elements android can clone" }, /* ---------- amoeba content --------------------------------------------- */ { ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(3), - 1, 1, GADGET_ID_AMOEBA_CONTENT, GADGET_ID_NONE, - "content:", NULL, NULL + &level.amoeba_content, 1, 1, + "content:", NULL, NULL, "amoeba content" + }, + + /* ---------- level start element ---------------------------------------- */ + + { + -1, ED_AREA_1X1_SETTINGS_YPOS(7), + GADGET_ID_START_ELEMENT, GADGET_ID_USE_START_ELEMENT, + &level.start_element[0], 1, 1, + NULL, NULL, NULL, "level start element" + }, + + /* ---------- player artwork element ------------------------------------- */ + + { + -1, ED_AREA_1X1_SETTINGS_YPOS(8), + GADGET_ID_ARTWORK_ELEMENT, GADGET_ID_USE_ARTWORK_ELEMENT, + &level.artwork_element[0], 1, 1, + NULL, NULL, NULL, "element for player artwork" + }, + + /* ---------- player explosion element ----------------------------------- */ + + { + -1, ED_AREA_1X1_SETTINGS_YPOS(9), + GADGET_ID_EXPLOSION_ELEMENT, GADGET_ID_USE_EXPLOSION_ELEMENT, + &level.explosion_element[0], 1, 1, + NULL, NULL, NULL, "element for player explosion" }, /* ---------- element settings: configure 1 (custom elements) ----------- */ @@ -2394,9 +2900,9 @@ static struct { -1, ED_AREA_1X1_SETTINGS_YPOS(1), - 1, 1, GADGET_ID_CUSTOM_GRAPHIC, GADGET_ID_CUSTOM_USE_GRAPHIC, - NULL, NULL, NULL + &custom_element.gfx_element, 1, 1, + NULL, NULL, NULL, "custom graphic element" }, /* ---------- element settings: configure 2 (custom elements) ----------- */ @@ -2405,24 +2911,24 @@ static struct { -1, ED_AREA_3X3_SETTINGS_YPOS(10), - 3, 3, GADGET_ID_CUSTOM_CONTENT, GADGET_ID_NONE, /* align three rows */ - "content:", NULL, NULL + &custom_element.content.e[0][0], 3, 3, + "content:", NULL, NULL, NULL }, /* ---------- custom enter and leave element (when moving) --------------- */ { ED_AREA_1X1_SETTINGS_XPOS(1), ED_AREA_1X1_SETTINGS_YPOS(3), - 1, 1, GADGET_ID_CUSTOM_MOVE_ENTER, GADGET_ID_NONE, - "can dig:", " ", NULL + &custom_element.move_enter_element, 1, 1, + "can dig:", " ", NULL, "element that can be digged/collected" }, { -1, ED_AREA_1X1_SETTINGS_YPOS(3), - 1, 1, GADGET_ID_CUSTOM_MOVE_LEAVE, GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE, - NULL, NULL, NULL + &custom_element.move_leave_element, 1, 1, + NULL, NULL, NULL, "element that will be left behind" }, /* ---------- element settings: advanced (custom elements) --------------- */ @@ -2431,45 +2937,45 @@ static struct { -1, ED_AREA_1X1_SETTINGS_YPOS(1), - 1, 1, GADGET_ID_CUSTOM_CHANGE_TARGET, GADGET_ID_CUSTOM_CAN_CHANGE, - NULL, "after/when:", NULL + &custom_element_change.target_element, 1, 1, + NULL, "after/when:", NULL, "new target element after change" }, /* ---------- custom change content (extended change target) ------------- */ { -1, ED_AREA_3X3_SETTINGS_YPOS(10), - 3, 3, GADGET_ID_CUSTOM_CHANGE_CONTENT, GADGET_ID_NONE, /* align three rows */ - NULL, NULL, NULL + &custom_element_change.target_content.e[0][0], 3, 3, + NULL, NULL, NULL, "new extended elements after change" }, /* ---------- custom change trigger (element causing change) ------------- */ { -1, ED_AREA_1X1_SETTINGS_YPOS(5), - 1, 1, GADGET_ID_CUSTOM_CHANGE_TRIGGER, GADGET_ID_CHANGE_OTHER_ACTION, - NULL, NULL, NULL + &custom_element_change.trigger_element, 1, 1, + NULL, NULL, NULL, "other element triggering change" }, /* ---------- group element content -------------------------------------- */ { ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(4), - MAX_ELEMENTS_IN_GROUP, 1, GADGET_ID_GROUP_CONTENT, GADGET_ID_NONE, - "content:", NULL, NULL + &group_element_info.element[0], MAX_ELEMENTS_IN_GROUP, 1, + "content:", NULL, NULL, NULL }, /* ---------- random background (for random painting) -------------------- */ { -1, ED_ELEMENT_SETTINGS_YPOS(14), - 1, 1, GADGET_ID_RANDOM_BACKGROUND, GADGET_ID_RANDOM_RESTRICTED, - NULL, NULL, NULL + &random_placement_background_element, 1, 1, + NULL, NULL, NULL, "random placement background" }, }; @@ -2493,17 +2999,20 @@ static int new_element1 = EL_WALL; static int new_element2 = EL_EMPTY; static int new_element3 = EL_SAND; +#define IS_VALID_BUTTON(button) (button >= 1 && button <= 3) #define BUTTON_ELEMENT(button) ((button) == 1 ? new_element1 : \ (button) == 2 ? new_element2 : \ (button) == 3 ? new_element3 : EL_EMPTY) #define BUTTON_STEPSIZE(button) ((button) == 1 ? 1 : (button) == 2 ? 5 : 10) /* forward declaration for internal use */ -static void ModifyEditorCounter(int, int); +static void ModifyEditorCounterValue(int, int); static void ModifyEditorCounterLimits(int, int, int); -static void ModifyEditorSelectbox(int, int); +static void ModifyEditorSelectboxValue(int, int); +static void ModifyEditorSelectboxOptions(int, struct ValueTextInfo *); static void ModifyEditorDrawingArea(int, int, int); static void ModifyEditorElementList(); +static void AdjustElementListScrollbar(); static void RedrawDrawingElements(); static void DrawDrawingWindow(); static void DrawLevelInfoWindow(); @@ -2522,6 +3031,7 @@ static void HandleRadiobuttons(struct GadgetInfo *); static void HandleCheckbuttons(struct GadgetInfo *); static void HandleControlButtons(struct GadgetInfo *); static void HandleDrawingAreaInfo(struct GadgetInfo *); +static void PrintEditorGadgetInfoText(struct GadgetInfo *); static struct GadgetInfo *level_editor_gadget[NUM_EDITOR_GADGETS]; static int right_gadget_border[NUM_EDITOR_GADGETS]; @@ -2543,6 +3053,12 @@ static int element_shift = 0; static int editor_hl_boulderdash[] = { + EL_INTERNAL_CASCADE_BD_ACTIVE, + EL_CHAR('B'), + EL_CHAR('D'), + EL_EMPTY, + +#if 0 EL_CHAR('B'), EL_CHAR('O'), EL_CHAR('U'), @@ -2557,6 +3073,7 @@ static int editor_hl_boulderdash[] = EL_CHAR('A'), EL_CHAR('S'), EL_CHAR('H'), +#endif }; static int editor_el_boulderdash[] = @@ -2593,6 +3110,12 @@ static int num_editor_el_boulderdash = SIZEOF_ARRAY_INT(editor_el_boulderdash); static int editor_hl_emerald_mine[] = { + EL_INTERNAL_CASCADE_EM_ACTIVE, + EL_CHAR('E'), + EL_CHAR('M'), + EL_EMPTY, + +#if 0 EL_CHAR('E'), EL_CHAR('M'), EL_CHAR('E'), @@ -2607,6 +3130,7 @@ static int editor_hl_emerald_mine[] = EL_CHAR('I'), EL_CHAR('N'), EL_CHAR('E'), +#endif }; static int editor_el_emerald_mine[] = @@ -2671,17 +3195,10 @@ static int editor_el_emerald_mine[] = EL_AMOEBA_WET, EL_AMOEBA_DRY, -#if 1 EL_EM_KEY_1, EL_EM_KEY_2, EL_EM_KEY_3, EL_EM_KEY_4, -#else - EL_EM_KEY_1_FILE, - EL_EM_KEY_2_FILE, - EL_EM_KEY_3_FILE, - EL_EM_KEY_4_FILE, -#endif EL_EM_GATE_1, EL_EM_GATE_2, @@ -2700,6 +3217,12 @@ static int num_editor_el_emerald_mine=SIZEOF_ARRAY_INT(editor_el_emerald_mine); static int editor_hl_emerald_mine_club[] = { + EL_INTERNAL_CASCADE_EMC_ACTIVE, + EL_CHAR('E'), + EL_CHAR('M'), + EL_CHAR('C'), + +#if 0 EL_CHAR('E'), EL_CHAR('M'), EL_CHAR('E'), @@ -2719,6 +3242,7 @@ static int editor_hl_emerald_mine_club[] = EL_CHAR('L'), EL_CHAR('U'), EL_CHAR('B'), +#endif }; static int editor_el_emerald_mine_club[] = @@ -2768,18 +3292,10 @@ static int editor_el_emerald_mine_club[] = EL_EMC_WALL_11, EL_EMC_WALL_12, -#if RELEASE_312 - EL_EMPTY, -#else EL_EMC_ANDROID, -#endif EL_BALLOON, EL_BALLOON_SWITCH_ANY, -#if RELEASE_312 - EL_EMPTY, -#else EL_BALLOON_SWITCH_NONE, -#endif EL_BALLOON_SWITCH_LEFT, EL_BALLOON_SWITCH_RIGHT, @@ -2788,32 +3304,18 @@ static int editor_el_emerald_mine_club[] = EL_EMC_GRASS, EL_EMC_PLANT, -#if RELEASE_312 - EL_EMPTY, - EL_EMPTY, -#else EL_EMC_LENSES, EL_EMC_MAGNIFIER, -#endif -#if RELEASE_312 - EL_EMPTY, - EL_EMPTY, -#else EL_EMC_MAGIC_BALL, EL_EMC_MAGIC_BALL_SWITCH, -#endif EL_SPRING, -#if RELEASE_312 - EL_EMPTY, -#else EL_EMC_SPRING_BUMPER, -#endif -#if RELEASE_312 - EL_EMPTY, -#else +#if 0 EL_EMC_DRIPPER, +#else + EL_EMPTY, #endif EL_EMC_FAKE_GRASS, EL_EMPTY, @@ -2826,10 +3328,17 @@ static int num_editor_el_emerald_mine_club=SIZEOF_ARRAY_INT(editor_el_emerald_mi static int editor_hl_more[] = { + EL_INTERNAL_CASCADE_RND_ACTIVE, + EL_CHAR('R'), + EL_CHAR('N'), + EL_CHAR('D'), + +#if 0 EL_CHAR('M'), EL_CHAR('O'), EL_CHAR('R'), EL_CHAR('E'), +#endif }; static int editor_el_more[] = @@ -2921,6 +3430,12 @@ static int num_editor_el_more = SIZEOF_ARRAY_INT(editor_el_more); static int editor_hl_sokoban[] = { + EL_INTERNAL_CASCADE_SB_ACTIVE, + EL_CHAR('S'), + EL_CHAR('B'), + EL_EMPTY, + +#if 0 EL_CHAR('S'), EL_CHAR('O'), EL_CHAR('K'), @@ -2930,6 +3445,7 @@ static int editor_hl_sokoban[] = EL_CHAR('B'), EL_CHAR('A'), EL_CHAR('N'), +#endif }; static int editor_el_sokoban[] = @@ -2946,6 +3462,12 @@ static int num_editor_el_sokoban = SIZEOF_ARRAY_INT(editor_el_sokoban); static int editor_hl_supaplex[] = { + EL_INTERNAL_CASCADE_SP_ACTIVE, + EL_CHAR('S'), + EL_CHAR('P'), + EL_EMPTY, + +#if 0 EL_CHAR('S'), EL_CHAR('U'), EL_CHAR('P'), @@ -2955,6 +3477,7 @@ static int editor_hl_supaplex[] = EL_CHAR('L'), EL_CHAR('E'), EL_CHAR('X'), +#endif }; static int editor_el_supaplex[] = @@ -3020,6 +3543,12 @@ static int num_editor_el_supaplex = SIZEOF_ARRAY_INT(editor_el_supaplex); static int editor_hl_diamond_caves[] = { + EL_INTERNAL_CASCADE_DC_ACTIVE, + EL_CHAR('D'), + EL_CHAR('C'), + EL_CHAR('2'), + +#if 0 EL_CHAR('D'), EL_CHAR('I'), EL_CHAR('A'), @@ -3039,6 +3568,7 @@ static int editor_hl_diamond_caves[] = EL_CHAR(' '), EL_CHAR('I'), EL_CHAR('I'), +#endif }; static int editor_el_diamond_caves[] = @@ -3115,6 +3645,12 @@ static int num_editor_el_diamond_caves = SIZEOF_ARRAY_INT(editor_el_diamond_cave static int editor_hl_dx_boulderdash[] = { + EL_INTERNAL_CASCADE_DX_ACTIVE, + EL_CHAR('D'), + EL_CHAR('X'), + EL_EMPTY, + +#if 0 EL_CHAR('D'), EL_CHAR('X'), EL_CHAR('-'), @@ -3134,6 +3670,7 @@ static int editor_hl_dx_boulderdash[] = EL_CHAR('A'), EL_CHAR('S'), EL_CHAR('H'), +#endif }; static int editor_el_dx_boulderdash[] = @@ -3165,10 +3702,17 @@ static int num_editor_el_dx_boulderdash = SIZEOF_ARRAY_INT(editor_el_dx_boulderd static int editor_hl_chars[] = { + EL_INTERNAL_CASCADE_CHARS_ACTIVE, + EL_CHAR('T'), + EL_CHAR('X'), + EL_CHAR('T'), + +#if 0 EL_CHAR('T'), EL_CHAR('E'), EL_CHAR('X'), EL_CHAR('T'), +#endif }; static int editor_el_chars[] = @@ -3270,6 +3814,12 @@ static int num_editor_el_chars = SIZEOF_ARRAY_INT(editor_el_chars); static int editor_hl_custom[] = { + EL_INTERNAL_CASCADE_CE_ACTIVE, + EL_CHAR('C'), + EL_CHAR('E'), + EL_EMPTY, + +#if 0 EL_CHAR('C'), EL_CHAR('U'), EL_CHAR('S'), @@ -3289,6 +3839,7 @@ static int editor_hl_custom[] = EL_CHAR('N'), EL_CHAR('T'), EL_CHAR('S'), +#endif }; static int editor_el_custom[] = @@ -3451,19 +4002,8 @@ static int editor_el_custom[] = EL_CUSTOM_START + 124, EL_CUSTOM_START + 125, EL_CUSTOM_START + 126, - EL_CUSTOM_START + 127 -}; -static int *editor_hl_custom_ptr = editor_hl_custom; -static int *editor_el_custom_ptr = editor_el_custom; -static int num_editor_hl_custom = SIZEOF_ARRAY_INT(editor_hl_custom); -static int num_editor_el_custom = SIZEOF_ARRAY_INT(editor_el_custom); - -static int editor_hl_custom_more[] = -{ -}; + EL_CUSTOM_START + 127, -static int editor_el_custom_more[] = -{ EL_CUSTOM_START + 128, EL_CUSTOM_START + 129, EL_CUSTOM_START + 130, @@ -3622,31 +4162,26 @@ static int editor_el_custom_more[] = EL_CUSTOM_START + 252, EL_CUSTOM_START + 253, EL_CUSTOM_START + 254, - EL_CUSTOM_START + 255 -}; -static int *editor_hl_custom_more_ptr = editor_hl_custom_more; -static int *editor_el_custom_more_ptr = editor_el_custom_more; -static int num_editor_hl_custom_more = SIZEOF_ARRAY_INT(editor_hl_custom_more); -static int num_editor_el_custom_more = SIZEOF_ARRAY_INT(editor_el_custom_more); - -static int editor_hl_custom_special[] = -{ -}; + EL_CUSTOM_START + 255, -static int editor_el_custom_special[] = -{ EL_TRIGGER_ELEMENT, EL_TRIGGER_PLAYER, EL_EMPTY, EL_EMPTY }; -static int *editor_hl_custom_special_ptr = editor_hl_custom_special; -static int *editor_el_custom_special_ptr = editor_el_custom_special; -static int num_editor_hl_custom_special = SIZEOF_ARRAY_INT(editor_hl_custom_special); -static int num_editor_el_custom_special = SIZEOF_ARRAY_INT(editor_el_custom_special); +static int *editor_hl_custom_ptr = editor_hl_custom; +static int *editor_el_custom_ptr = editor_el_custom; +static int num_editor_hl_custom = SIZEOF_ARRAY_INT(editor_hl_custom); +static int num_editor_el_custom = SIZEOF_ARRAY_INT(editor_el_custom); static int editor_hl_group[] = { + EL_INTERNAL_CASCADE_GE_ACTIVE, + EL_CHAR('G'), + EL_CHAR('E'), + EL_EMPTY, + +#if 0 EL_CHAR('G'), EL_CHAR('R'), EL_CHAR('O'), @@ -3666,6 +4201,7 @@ static int editor_hl_group[] = EL_CHAR('N'), EL_CHAR('T'), EL_CHAR('S'), +#endif }; static int editor_el_group[] = @@ -3688,19 +4224,8 @@ static int editor_el_group[] = EL_GROUP_START + 12, EL_GROUP_START + 13, EL_GROUP_START + 14, - EL_GROUP_START + 15 -}; -static int *editor_hl_group_ptr = editor_hl_group; -static int *editor_el_group_ptr = editor_el_group; -static int num_editor_hl_group = SIZEOF_ARRAY_INT(editor_hl_group); -static int num_editor_el_group = SIZEOF_ARRAY_INT(editor_el_group); + EL_GROUP_START + 15, -static int editor_hl_group_more[] = -{ -}; - -static int editor_el_group_more[] = -{ EL_GROUP_START + 16, EL_GROUP_START + 17, EL_GROUP_START + 18, @@ -3721,13 +4246,19 @@ static int editor_el_group_more[] = EL_GROUP_START + 30, EL_GROUP_START + 31 }; -static int *editor_hl_group_more_ptr = editor_hl_group_more; -static int *editor_el_group_more_ptr = editor_el_group_more; -static int num_editor_hl_group_more = SIZEOF_ARRAY_INT(editor_hl_group_more); -static int num_editor_el_group_more = SIZEOF_ARRAY_INT(editor_el_group_more); +static int *editor_hl_group_ptr = editor_hl_group; +static int *editor_el_group_ptr = editor_el_group; +static int num_editor_hl_group = SIZEOF_ARRAY_INT(editor_hl_group); +static int num_editor_el_group = SIZEOF_ARRAY_INT(editor_el_group); static int editor_hl_user_defined[] = { + EL_INTERNAL_CASCADE_USER_ACTIVE, + EL_CHAR('M'), + EL_CHAR('Y'), + EL_EMPTY, + +#if 0 EL_CHAR('U'), EL_CHAR('S'), EL_CHAR('E'), @@ -3742,6 +4273,7 @@ static int editor_hl_user_defined[] = EL_CHAR('N'), EL_CHAR('E'), EL_CHAR('D'), +#endif }; static int *editor_hl_user_defined_ptr = editor_hl_user_defined; @@ -3749,6 +4281,19 @@ static int *editor_el_user_defined_ptr = NULL; static int num_editor_hl_user_defined=SIZEOF_ARRAY_INT(editor_hl_user_defined); static int num_editor_el_user_defined = 0; +static int editor_hl_dynamic[] = +{ + EL_INTERNAL_CASCADE_DYNAMIC_ACTIVE, + EL_CHAR('U'), + EL_CHAR('S'), + EL_CHAR('E'), +}; + +static int *editor_hl_dynamic_ptr = editor_hl_dynamic; +static int *editor_el_dynamic_ptr = NULL; +static int num_editor_hl_dynamic = SIZEOF_ARRAY_INT(editor_hl_dynamic); +static int num_editor_el_dynamic = 0; + static int editor_hl_empty[] = { }; static int editor_el_empty[ED_NUM_ELEMENTLIST_BUTTONS]; @@ -3765,6 +4310,7 @@ static int num_editor_elements = 0; /* dynamically determined */ static struct { boolean *setup_value; + boolean *setup_cascade_value; int **headline_list; int *headline_list_size; @@ -3778,294 +4324,96 @@ editor_elements_info[] = { { &setup.editor.el_boulderdash, + &setup.editor_cascade.el_bd, &editor_hl_boulderdash_ptr, &num_editor_hl_boulderdash, &editor_el_boulderdash_ptr, &num_editor_el_boulderdash }, { &setup.editor.el_emerald_mine, + &setup.editor_cascade.el_em, &editor_hl_emerald_mine_ptr, &num_editor_hl_emerald_mine, &editor_el_emerald_mine_ptr, &num_editor_el_emerald_mine }, { &setup.editor.el_emerald_mine_club, + &setup.editor_cascade.el_emc, &editor_hl_emerald_mine_club_ptr, &num_editor_hl_emerald_mine_club, &editor_el_emerald_mine_club_ptr, &num_editor_el_emerald_mine_club }, { &setup.editor.el_more, + &setup.editor_cascade.el_rnd, &editor_hl_more_ptr, &num_editor_hl_more, &editor_el_more_ptr, &num_editor_el_more }, { &setup.editor.el_sokoban, + &setup.editor_cascade.el_sb, &editor_hl_sokoban_ptr, &num_editor_hl_sokoban, &editor_el_sokoban_ptr, &num_editor_el_sokoban }, { &setup.editor.el_supaplex, + &setup.editor_cascade.el_sp, &editor_hl_supaplex_ptr, &num_editor_hl_supaplex, &editor_el_supaplex_ptr, &num_editor_el_supaplex }, { &setup.editor.el_diamond_caves, + &setup.editor_cascade.el_dc, &editor_hl_diamond_caves_ptr, &num_editor_hl_diamond_caves, &editor_el_diamond_caves_ptr, &num_editor_el_diamond_caves }, { &setup.editor.el_dx_boulderdash, + &setup.editor_cascade.el_dx, &editor_hl_dx_boulderdash_ptr, &num_editor_hl_dx_boulderdash, &editor_el_dx_boulderdash_ptr, &num_editor_el_dx_boulderdash }, { &setup.editor.el_chars, + &setup.editor_cascade.el_chars, &editor_hl_chars_ptr, &num_editor_hl_chars, &editor_el_chars_ptr, &num_editor_el_chars }, { &setup.editor.el_custom, + &setup.editor_cascade.el_ce, &editor_hl_custom_ptr, &num_editor_hl_custom, &editor_el_custom_ptr, &num_editor_el_custom }, - { - &setup.editor.el_custom_more, - &editor_hl_custom_more_ptr, &num_editor_hl_custom_more, - &editor_el_custom_more_ptr, &num_editor_el_custom_more - }, - { - &setup.editor.el_custom, - &editor_hl_custom_special_ptr, &num_editor_hl_custom_special, - &editor_el_custom_special_ptr, &num_editor_el_custom_special - }, { &setup.editor.el_custom, + &setup.editor_cascade.el_ge, &editor_hl_group_ptr, &num_editor_hl_group, &editor_el_group_ptr, &num_editor_el_group }, - { - &setup.editor.el_custom_more, - &editor_hl_group_more_ptr, &num_editor_hl_group_more, - &editor_el_group_more_ptr, &num_editor_el_group_more - }, { &setup.editor.el_user_defined, + &setup.editor_cascade.el_user, &editor_hl_user_defined_ptr, &num_editor_hl_user_defined, &editor_el_user_defined_ptr, &num_editor_el_user_defined }, { + &setup.editor.el_dynamic, + &setup.editor_cascade.el_dynamic, + &editor_hl_dynamic_ptr, &num_editor_hl_dynamic, + &editor_el_dynamic_ptr, &num_editor_el_dynamic, + }, + { + &use_el_empty, &use_el_empty, &editor_hl_empty_ptr, &num_editor_hl_empty, &editor_el_empty_ptr, &num_editor_el_empty, }, { + NULL, NULL, NULL, NULL, NULL, NULL } }; -#if 0 - -static struct -{ - short element; - short element_mapped; -} -forum_sketch_element_mapping[] = -{ - { EL_WALL_SLIPPERY, EL_WALL }, - { EL_EXPANDABLE_WALL, EL_WALL }, - { EL_EXPANDABLE_WALL_HORIZONTAL, EL_WALL }, - { EL_EXPANDABLE_WALL_VERTICAL, EL_WALL }, - { EL_EXPANDABLE_WALL_ANY, EL_WALL }, - { EL_WALL_EMERALD, EL_WALL }, - { EL_WALL_DIAMOND, EL_WALL }, - { EL_WALL_BD_DIAMOND, EL_WALL }, - { EL_WALL_EMERALD_YELLOW, EL_WALL }, - { EL_WALL_EMERALD_RED, EL_WALL }, - { EL_WALL_EMERALD_PURPLE, EL_WALL }, - { EL_ACID_POOL_TOPLEFT, EL_WALL }, - { EL_ACID_POOL_TOPRIGHT, EL_WALL }, - { EL_ACID_POOL_BOTTOMLEFT, EL_WALL }, - { EL_ACID_POOL_BOTTOM, EL_WALL }, - { EL_ACID_POOL_BOTTOMRIGHT, EL_WALL }, - { EL_BD_WALL, EL_WALL }, - - { EL_BD_ROCK, EL_ROCK }, - - { EL_SP_ZONK, EL_ROCK }, - { EL_SP_BASE, EL_SAND }, - { EL_SP_MURPHY, EL_PLAYER_1 }, - { EL_SP_INFOTRON, EL_EMERALD }, - { EL_SP_HARDWARE_GRAY, EL_STEELWALL }, - { EL_SP_EXIT_CLOSED, EL_EXIT_OPEN }, - { EL_SP_DISK_ORANGE, EL_BOMB }, - { EL_SP_DISK_RED, EL_BOMB }, - { EL_SP_DISK_YELLOW, EL_BOMB }, - { EL_SP_PORT_RIGHT, EL_GATE_1_GRAY }, - { EL_SP_PORT_DOWN, EL_GATE_1_GRAY }, - { EL_SP_PORT_LEFT, EL_GATE_1_GRAY }, - { EL_SP_PORT_UP, EL_GATE_1_GRAY }, - { EL_SP_GRAVITY_PORT_RIGHT, EL_GATE_1_GRAY }, - { EL_SP_GRAVITY_PORT_DOWN, EL_GATE_1_GRAY }, - { EL_SP_GRAVITY_PORT_LEFT, EL_GATE_1_GRAY }, - { EL_SP_GRAVITY_PORT_UP, EL_GATE_1_GRAY }, - { EL_SP_PORT_VERTICAL, EL_GATE_1_GRAY }, - { EL_SP_PORT_HORIZONTAL, EL_GATE_1_GRAY }, - { EL_SP_PORT_ANY, EL_GATE_1_GRAY }, - { EL_SP_SNIKSNAK, EL_BUG }, - { EL_SP_ELECTRON, EL_SPACESHIP }, - { EL_SP_CHIP_SINGLE, EL_WALL }, - { EL_SP_CHIP_LEFT, EL_WALL }, - { EL_SP_CHIP_RIGHT, EL_WALL }, - { EL_SP_CHIP_TOP, EL_WALL }, - { EL_SP_CHIP_BOTTOM, EL_WALL }, - { EL_SP_HARDWARE_BASE_1, EL_STEELWALL }, - { EL_SP_HARDWARE_GREEN, EL_STEELWALL }, - { EL_SP_HARDWARE_BLUE, EL_STEELWALL }, - { EL_SP_HARDWARE_RED, EL_STEELWALL }, - { EL_SP_HARDWARE_YELLOW, EL_STEELWALL }, - { EL_SP_HARDWARE_BASE_2, EL_STEELWALL }, - { EL_SP_HARDWARE_BASE_3, EL_STEELWALL }, - { EL_SP_HARDWARE_BASE_3, EL_STEELWALL }, - { EL_SP_HARDWARE_BASE_4, EL_STEELWALL }, - { EL_SP_HARDWARE_BASE_5, EL_STEELWALL }, - { EL_SP_HARDWARE_BASE_6, EL_STEELWALL }, - - { EL_STEELWALL_SLIPPERY, EL_STEELWALL }, - - { EL_EXIT_CLOSED, EL_EXIT_OPEN }, - - { EL_DIAMOND, EL_EMERALD }, - { EL_BD_DIAMOND, EL_EMERALD }, - { EL_EMERALD_YELLOW, EL_EMERALD }, - { EL_EMERALD_RED, EL_EMERALD }, - { EL_EMERALD_PURPLE, EL_EMERALD }, - - { EL_AMOEBA_DEAD, EL_AMOEBA }, - { EL_AMOEBA_DROP, EL_AMOEBA }, - { EL_AMOEBA_WET, EL_AMOEBA }, - { EL_AMOEBA_DRY, EL_AMOEBA }, - { EL_AMOEBA_FULL, EL_AMOEBA }, - { EL_BD_AMOEBA, EL_AMOEBA }, - { EL_AMOEBA_TO_DIAMOND, EL_AMOEBA }, - - { EL_DYNAMITE_ACTIVE, EL_DYNAMITE }, - - { EL_GATE_2_GRAY, EL_GATE_1_GRAY }, - { EL_GATE_3_GRAY, EL_GATE_1_GRAY }, - { EL_GATE_4_GRAY, EL_GATE_1_GRAY }, - - { EL_EM_KEY_1, EL_KEY_1 }, - { EL_EM_KEY_2, EL_KEY_2 }, - { EL_EM_KEY_3, EL_KEY_3 }, - { EL_EM_KEY_4, EL_KEY_4 }, - - { EL_EM_GATE_1, EL_GATE_1 }, - { EL_EM_GATE_2, EL_GATE_2 }, - { EL_EM_GATE_3, EL_GATE_3 }, - { EL_EM_GATE_4, EL_GATE_4 }, - - { EL_EM_GATE_1_GRAY, EL_GATE_1_GRAY }, - { EL_EM_GATE_2_GRAY, EL_GATE_1_GRAY }, - { EL_EM_GATE_3_GRAY, EL_GATE_1_GRAY }, - { EL_EM_GATE_4_GRAY, EL_GATE_1_GRAY }, - - { EL_INVISIBLE_SAND, EL_EMPTY }, - { EL_INVISIBLE_WALL, EL_EMPTY }, - { EL_INVISIBLE_STEELWALL, EL_EMPTY }, - - { EL_PACMAN, EL_YAMYAM }, - { EL_DARK_YAMYAM, EL_YAMYAM }, - - { EL_BD_MAGIC_WALL, EL_MAGIC_WALL }, - - { EL_DYNABOMB_INCREASE_NUMBER, EL_BOMB }, - { EL_DYNABOMB_INCREASE_SIZE, EL_BOMB }, - { EL_DYNABOMB_INCREASE_POWER, EL_BOMB }, - { EL_BLACK_ORB, EL_BOMB }, - { EL_DX_SUPABOMB, EL_BOMB }, - - { EL_SOKOBAN_OBJECT, EL_KEY_1 }, - { EL_SOKOBAN_FIELD_EMPTY, EL_GATE_1_GRAY }, - { EL_SOKOBAN_FIELD_FULL, EL_GATE_1 }, - { EL_SOKOBAN_FIELD_PLAYER, EL_PLAYER_1 }, - - { EL_BD_BUTTERFLY_RIGHT, EL_BD_BUTTERFLY }, - { EL_BD_BUTTERFLY_UP, EL_BD_BUTTERFLY }, - { EL_BD_BUTTERFLY_LEFT, EL_BD_BUTTERFLY }, - { EL_BD_BUTTERFLY_DOWN, EL_BD_BUTTERFLY }, - - { EL_BD_FIREFLY_RIGHT, EL_BD_FIREFLY }, - { EL_BD_FIREFLY_UP, EL_BD_FIREFLY }, - { EL_BD_FIREFLY_LEFT, EL_BD_FIREFLY }, - { EL_BD_FIREFLY_DOWN, EL_BD_FIREFLY }, - - { EL_PLAYER_2, EL_PLAYER_1 }, - { EL_PLAYER_3, EL_PLAYER_1 }, - { EL_PLAYER_4, EL_PLAYER_1 }, - - { EL_BUG_RIGHT, EL_BUG }, - { EL_BUG_UP, EL_BUG }, - { EL_BUG_LEFT, EL_BUG }, - { EL_BUG_DOWN, EL_BUG }, - - { EL_SPACESHIP_RIGHT, EL_SPACESHIP }, - { EL_SPACESHIP_UP, EL_SPACESHIP }, - { EL_SPACESHIP_LEFT, EL_SPACESHIP }, - { EL_SPACESHIP_DOWN, EL_SPACESHIP }, - - { EL_PACMAN_RIGHT, EL_YAMYAM }, - { EL_PACMAN_UP, EL_YAMYAM }, - { EL_PACMAN_LEFT, EL_YAMYAM }, - { EL_PACMAN_DOWN, EL_YAMYAM }, - - { -1, -1 } -}; - -static struct -{ - short element; - char *element_string; -} -forum_sketch_element_strings[] = -{ - { EL_PLAYER_1, "p" }, - { EL_EMPTY, "_" }, - { EL_SAND, "s" }, - { EL_ROCK, "b" }, - { EL_EMERALD, "e" }, - { EL_BUG, "u" }, - { EL_SPACESHIP, "h" }, - { EL_BD_FIREFLY, "f" }, - { EL_BD_BUTTERFLY, "b" }, - { EL_AMOEBA, "a" }, - { EL_YAMYAM, "y" }, - { EL_WALL, "w" }, - { EL_STEELWALL, "t" }, - { EL_MAGIC_WALL, "m" }, - { EL_EXIT_OPEN, "x" }, - { EL_DYNAMITE, "d" }, - { EL_KEY_1, "1" }, - { EL_KEY_2, "2" }, - { EL_KEY_3, "3" }, - { EL_KEY_4, "4" }, - { EL_GATE_1, "5" }, - { EL_GATE_2, "6" }, - { EL_GATE_3, "7" }, - { EL_GATE_4, "8" }, - { EL_GATE_1_GRAY, "9" }, - { EL_BOMB, "@" }, - { EL_ROBOT, "r" }, - { EL_ROBOT_WHEEL, "0" }, - { EL_NUT, "n" }, - { EL_CUSTOM_1, "c" }, - { EL_CHAR_QUESTION, "?" }, - - { -1, NULL } -}; - -#endif - /* ----------------------------------------------------------------------------- @@ -4099,64 +4447,129 @@ static int getRightGadgetBorder(struct GadgetInfo *gi, char *text) return (gi->x + gi->width + getTextWidthForGadget(text)); } -static char *getElementInfoText(int element) -{ - char *info_text = NULL; +static char *getElementInfoText(int element) +{ + char *info_text = NULL; + +#if 1 + if (element < MAX_NUM_ELEMENTS) +#else + if (element < NUM_FILE_ELEMENTS) +#endif + { + if (strlen(element_info[element].description) > 0) + info_text = element_info[element].description; + else if (element_info[element].custom_description != NULL) + info_text = element_info[element].custom_description; + else if (element_info[element].editor_description != NULL) + info_text = element_info[element].editor_description; + } + + if (info_text == NULL) + info_text = INFOTEXT_UNKNOWN_ELEMENT; + + return info_text; +} + +static void InitDynamicEditorElementList(int **elements, int *num_elements) +{ + boolean element_found[NUM_FILE_ELEMENTS]; + int i, x, y; + + /* initialize list of used elements to "not used" */ + for (i = 0; i < NUM_FILE_ELEMENTS; i++) + element_found[i] = FALSE; + + /* 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; + + *num_elements = 0; + + /* count number of elements used in current level */ + for (i = 0; i < NUM_FILE_ELEMENTS; i++) + if (element_found[i]) + (*num_elements)++; + + /* add space for up to 3 more elements for padding that may be needed */ + *num_elements += 3; + + /* free memory for old list of elements, if needed */ + checked_free(*elements); - if (element < NUM_FILE_ELEMENTS) - { - if (strlen(element_info[element].description) > 0) - info_text = element_info[element].description; - else if (element_info[element].custom_description != NULL) - info_text = element_info[element].custom_description; - else if (element_info[element].editor_description != NULL) - info_text = element_info[element].editor_description; - } + /* allocate memory for new list of elements */ + *elements = checked_malloc(*num_elements * sizeof(int)); - if (info_text == NULL) - info_text = INFOTEXT_UNKNOWN_ELEMENT; + *num_elements = 0; - return info_text; + /* add all elements used in current level (non-custom/group elements) */ + for (i = 0; i < NUM_FILE_ELEMENTS; i++) + if (element_found[i] && !(IS_CUSTOM_ELEMENT(i) || IS_GROUP_ELEMENT(i))) + (*elements)[(*num_elements)++] = i; + + /* add all elements used in current level (custom/group elements) */ + for (i = 0; i < NUM_FILE_ELEMENTS; i++) + if (element_found[i] && (IS_CUSTOM_ELEMENT(i) || IS_GROUP_ELEMENT(i))) + (*elements)[(*num_elements)++] = i; + + while (*num_elements % 4) /* pad with empty elements, if needed */ + (*elements)[(*num_elements)++] = EL_EMPTY; } static void ReinitializeElementList() { - static boolean initialized = FALSE; + static boolean initialization_needed = TRUE; int pos = 0; int i, j; + if (initialization_needed) + { + LoadSetup_EditorCascade(); /* load last editor cascade state */ + + /* initialize editor cascade element from saved cascade state */ + for (i = 0; editor_elements_info[i].setup_value != NULL; i++) + { + int *cascade_element = &(*editor_elements_info[i].headline_list)[0]; + boolean cascade_value = *editor_elements_info[i].setup_cascade_value; + + if (IS_EDITOR_CASCADE(*cascade_element)) + *cascade_element = + (cascade_value ? EL_CASCADE_ACTIVE(*cascade_element) : + EL_CASCADE_INACTIVE(*cascade_element)); + } + + initialization_needed = FALSE; + } + checked_free(editor_elements); -#if 0 - if (!initialized) -#else - /* reload user defined element list for each invocation of level editor */ -#endif - { - /* initialize optional user defined element list */ - LoadUserDefinedEditorElementList(&editor_el_user_defined_ptr, - &num_editor_el_user_defined); + /* reload optional user defined element list for each invocation of editor */ + LoadUserDefinedEditorElementList(&editor_el_user_defined_ptr, + &num_editor_el_user_defined); - /* initialize list of empty elements (used for padding, if needed) */ - for (i = 0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++) - editor_el_empty[i] = EL_EMPTY; + /* initialize dynamic level element list for each invocation of editor */ + InitDynamicEditorElementList(&editor_el_dynamic_ptr, + &num_editor_el_dynamic); - /* do some sanity checks for each element from element list */ - for (i = 0; editor_elements_info[i].setup_value != NULL; i++) + /* initialize list of empty elements (used for padding, if needed) */ + for (i = 0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++) + editor_el_empty[i] = EL_EMPTY; + + /* do some sanity checks for each element from element list */ + for (i = 0; editor_elements_info[i].setup_value != NULL; i++) + { + for (j = 0; j < *editor_elements_info[i].element_list_size; j++) { - for (j = 0; j < *editor_elements_info[i].element_list_size; j++) - { - int element = (*editor_elements_info[i].element_list)[j]; + int element = (*editor_elements_info[i].element_list)[j]; - if (element >= NUM_FILE_ELEMENTS) - Error(ERR_WARN, "editor element %d is runtime element", element); + if (element >= NUM_FILE_ELEMENTS) + Error(ERR_WARN, "editor element %d is runtime element", element); - if (strcmp(getElementInfoText(element), INFOTEXT_UNKNOWN_ELEMENT) == 0) - Error(ERR_WARN, "no element description for element %d", element); - } + if (strcmp(getElementInfoText(element), INFOTEXT_UNKNOWN_ELEMENT) == 0) + Error(ERR_WARN, "no element description for element %d", element); } - - initialized = TRUE; } num_editor_elements = 0; @@ -4165,11 +4578,26 @@ static void ReinitializeElementList() /* 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) { if (setup.editor.el_headlines) + { num_editor_elements += *editor_elements_info[i].headline_list_size; + for (j = 0; j < *editor_elements_info[i].headline_list_size; j++) + { + int element = (*editor_elements_info[i].headline_list)[j]; + + if (IS_EDITOR_CASCADE_INACTIVE(element)) + found_inactive_cascade = TRUE; + } + } + + if (found_inactive_cascade) + continue; + num_editor_elements += *editor_elements_info[i].element_list_size; } } @@ -4188,22 +4616,33 @@ static void ReinitializeElementList() /* fill 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) { if (setup.editor.el_headlines) + { for (j = 0; j < *editor_elements_info[i].headline_list_size; j++) - editor_elements[pos++] = (*editor_elements_info[i].headline_list)[j]; + { + int element = (*editor_elements_info[i].headline_list)[j]; + + editor_elements[pos++] = element; + + if (IS_EDITOR_CASCADE_INACTIVE(element)) + found_inactive_cascade = TRUE; + } + } + + if (found_inactive_cascade) + continue; for (j = 0; j < *editor_elements_info[i].element_list_size; j++) editor_elements[pos++] = (*editor_elements_info[i].element_list)[j]; } } - /* correct position of element list scrollbar */ - 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; + /* (this function is also called before editor gadgets are initialized!) */ + AdjustElementListScrollbar(); } void PrintEditorElementList() @@ -4213,10 +4652,25 @@ void PrintEditorElementList() for (i = 0; editor_elements_info[i].setup_value != stop; i++) { + int cascade_element = (*editor_elements_info[i].headline_list)[0]; + + if (IS_EDITOR_CASCADE(cascade_element)) + { + int cascade_element_show = EL_CASCADE_INACTIVE(cascade_element); + char *headline = element_info[cascade_element_show].editor_description; + + printf_line_with_prefix("# ", "-", 77); + printf("# %s\n", headline); + printf_line_with_prefix("# ", "-", 77); + } + for (j = 0; j < *editor_elements_info[i].headline_list_size; j++) { int element = (*editor_elements_info[i].headline_list)[j]; + if (IS_EDITOR_CASCADE(element)) + element = EL_CHAR_MINUS; + printf("# %s\n", element_info[element].token_name); } @@ -4276,6 +4730,10 @@ static void DrawElementBorder(int dest_x, int dest_y, int width, int height, int src_x, src_y; int num_mini_tilex = width / MINI_TILEX + 1; int num_mini_tiley = height / MINI_TILEY + 1; + int from_x = dest_x - MINI_TILEX / 2; + int from_y = dest_y - MINI_TILEY / 2; + int to_x = from_x + num_mini_tilex * MINI_TILEX - 1; + int to_y = from_y + num_mini_tiley * MINI_TILEY - 1; int x, y; getMiniGraphicSource(border_graphic, &src_bitmap, &src_x, &src_y); @@ -4283,10 +4741,14 @@ static void DrawElementBorder(int dest_x, int dest_y, int width, int height, for (y = 0; y < num_mini_tiley; y++) for (x = 0; x < num_mini_tilex; x++) BlitBitmap(src_bitmap, drawto, src_x, src_y, MINI_TILEX, MINI_TILEY, - dest_x - MINI_TILEX / 2 + x * MINI_TILEX, - dest_y - MINI_TILEY / 2 + y * MINI_TILEY); + from_x + x * MINI_TILEX, from_y + y * MINI_TILEY); ClearRectangle(drawto, dest_x - 1, dest_y - 1, width + 2, height + 2); + + DrawSimpleBlackLine(drawto, from_x, from_y, to_x, from_y); + DrawSimpleBlackLine(drawto, to_x, from_y, to_x, to_y); + DrawSimpleBlackLine(drawto, to_x, to_y, from_x, to_y); + DrawSimpleBlackLine(drawto, from_x, to_y, from_x, from_y); } static void DrawDrawingArea(int id) @@ -4294,64 +4756,16 @@ static void DrawDrawingArea(int id) struct GadgetInfo *gi = level_editor_gadget[drawingarea_info[id].gadget_id]; int x, y; - if (id == ED_DRAWING_ID_RANDOM_BACKGROUND) - DrawMiniGraphicExt(drawto, gi->x, gi->y, - el2edimg(random_placement_background_element)); - else if (id == ED_DRAWING_ID_AMOEBA_CONTENT) - DrawMiniGraphicExt(drawto, gi->x, gi->y, el2edimg(level.amoeba_content)); - else if (id == ED_DRAWING_ID_CUSTOM_GRAPHIC) - DrawMiniGraphicExt(drawto, gi->x, gi->y, - el2edimg(custom_element.gfx_element)); - else if (id == ED_DRAWING_ID_CUSTOM_CONTENT) - for (y = 0; y < 3; y++) - for (x = 0; x < 3; x++) - DrawMiniGraphicExt(drawto, - gi->x + x * MINI_TILEX, gi->y + y * MINI_TILEY, - el2edimg(custom_element.content[x][y])); - else if (id == ED_DRAWING_ID_CUSTOM_MOVE_ENTER) - DrawMiniGraphicExt(drawto, gi->x, gi->y, - el2edimg(custom_element.move_enter_element)); - else if (id == ED_DRAWING_ID_CUSTOM_MOVE_LEAVE) - DrawMiniGraphicExt(drawto, gi->x, gi->y, - el2edimg(custom_element.move_leave_element)); - else if (id == ED_DRAWING_ID_CUSTOM_CHANGE_TARGET) - DrawMiniGraphicExt(drawto, gi->x, gi->y, - el2edimg(custom_element_change.target_element)); - else if (id == ED_DRAWING_ID_CUSTOM_CHANGE_CONTENT) - for (y = 0; y < 3; y++) - for (x = 0; x < 3; x++) - DrawMiniGraphicExt(drawto, - gi->x + x * MINI_TILEX, gi->y + y * MINI_TILEY, - el2edimg(custom_element_change.target_content[x][y])); - else if (id == ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER) - DrawMiniGraphicExt(drawto, gi->x, gi->y, - el2edimg(custom_element_change.trigger_element)); - else if (id == ED_DRAWING_ID_GROUP_CONTENT) - for (x = 0; x < group_element_info.num_elements; x++) - DrawMiniGraphicExt(drawto, gi->x + x * MINI_TILEX, gi->y, - el2edimg(group_element_info.element[x])); - else if (id >= ED_DRAWING_ID_YAMYAM_CONTENT_0 && - id <= ED_DRAWING_ID_YAMYAM_CONTENT_7) - { - int nr = id - ED_DRAWING_ID_YAMYAM_CONTENT_0; - - for (y = 0; y < 3; y++) - for (x = 0; x < 3; x++) - DrawMiniGraphicExt(drawto, - gi->x + x * MINI_TILEX, gi->y + y * MINI_TILEY, - el2edimg(level.yamyam_content[nr][x][y])); - } - else if (id >= ED_DRAWING_ID_MAGIC_BALL_CONTENT_0 && - id <= ED_DRAWING_ID_MAGIC_BALL_CONTENT_7) - { - int nr = id - ED_DRAWING_ID_MAGIC_BALL_CONTENT_0; + int *value = drawingarea_info[id].value; + int area_xsize = drawingarea_info[id].area_xsize; + int area_ysize = drawingarea_info[id].area_ysize; - for (y = 0; y < 3; y++) - for (x = 0; x < 3; x++) - DrawMiniGraphicExt(drawto, - gi->x + x * MINI_TILEX, gi->y + y * MINI_TILEY, - el2edimg(level.ball_content[nr][x][y])); - } + for (x = 0; x < area_xsize; x++) + for (y = 0; y < area_ysize; y++) + DrawMiniGraphicExt(drawto, + gi->x + x * MINI_TILEX, + gi->y + y * MINI_TILEY, + el2edimg(value[x * area_ysize + y])); } static void ScrollMiniLevel(int from_x, int from_y, int scroll) @@ -5377,7 +5791,11 @@ void FreeLevelEditorGadgets() int i; for (i = 0; i < NUM_EDITOR_GADGETS; i++) + { FreeGadget(level_editor_gadget[i]); + + level_editor_gadget[i] = NULL; + } } static void MapCounterButtons(int id) @@ -5388,34 +5806,39 @@ static void MapCounterButtons(int id) struct GadgetInfo *gi_down = level_editor_gadget[gadget_id_down]; struct GadgetInfo *gi_text = level_editor_gadget[gadget_id_text]; struct GadgetInfo *gi_up = level_editor_gadget[gadget_id_up]; -#if 0 - char infotext[MAX_OUTPUT_LINESIZE + 1]; - int max_infotext_len = getMaxInfoTextLength(); - int xoffset_left = 0; - int yoffset_left = ED_BORDER_SIZE; - int xoffset_right = getCounterGadgetWidth(); - int yoffset_right = ED_BORDER_SIZE; -#else int xoffset_left = getTextWidthForGadget(counterbutton_info[id].text_left); int xoffset_right = ED_GADGET_TEXT_DISTANCE; int yoffset_above = MINI_TILEX + ED_GADGET_DISTANCE; int yoffset = ED_BORDER_SIZE; int x_left = gi_down->x - xoffset_left; +#if 1 + int x_right; /* set after gadget position was modified */ +#else int x_right = gi_up->x + gi_up->width + xoffset_right; +#endif int y_above = gi_down->y - yoffset_above; int x = gi_down->x; int y; /* set after gadget position was modified */ -#endif - /* set position for "value1/value2" counter gadgets (score in most cases) */ - if (id == ED_COUNTER_ID_ELEMENT_VALUE1 || - id == ED_COUNTER_ID_ELEMENT_VALUE2) + /* counter limits must be changed first to prevent value truncation */ + ModifyEditorCounterLimits(id, counterbutton_info[id].min_value, + counterbutton_info[id].max_value); + + /* right text position might have changed after setting position above */ + x_right = gi_up->x + gi_up->width + xoffset_right; + + ModifyEditorCounterValue(id, *counterbutton_info[id].value); + + /* set position for "value[1,2,3,4]" counter gadgets (score in most cases) */ + if (id >= ED_COUNTER_ID_ELEMENT_VALUE1 && + id <= ED_COUNTER_ID_ELEMENT_VALUE4) { ModifyGadget(gi_down, GDI_Y, SY + counterbutton_info[id].y, GDI_END); ModifyGadget(gi_text, GDI_Y, SY + counterbutton_info[id].y, GDI_END); ModifyGadget(gi_up, GDI_Y, SY + counterbutton_info[id].y, GDI_END); } + /* vertical position might have changed after setting position above */ y = gi_up->y + yoffset; if (counterbutton_info[id].text_above) @@ -5427,8 +5850,6 @@ static void MapCounterButtons(int id) if (counterbutton_info[id].text_right) DrawText(x_right, y, counterbutton_info[id].text_right, FONT_TEXT_1); - ModifyEditorCounter(id, *counterbutton_info[id].value); - MapGadget(gi_down); MapGadget(gi_text); MapGadget(gi_up); @@ -5452,9 +5873,8 @@ static void MapControlButtons() /* map buttons to select level */ counter_id = ED_COUNTER_ID_SELECT_LEVEL; - ModifyEditorCounterLimits(counter_id, - leveldir_current->first_level, - leveldir_current->last_level); + counterbutton_info[counter_id].min_value = leveldir_current->first_level; + counterbutton_info[counter_id].max_value = leveldir_current->last_level; MapCounterButtons(counter_id); } @@ -5539,7 +5959,7 @@ static void MapSelectboxGadget(int id) if (selectbox_info[id].text_right) DrawText(x_right, y, selectbox_info[id].text_right, FONT_TEXT_1); - ModifyEditorSelectbox(id, *selectbox_info[id].value); + ModifyEditorSelectboxValue(id, *selectbox_info[id].value); MapGadget(gi); } @@ -5806,11 +6226,12 @@ static boolean LevelContainsPlayer() return TRUE; /* !!! CURRENTLY DEACTIVATED !!! */ - for (y = 0; y < lev_fieldy; y++) - for (x = 0; x < lev_fieldx; x++) - if (Feld[x][y] == EL_PLAYER_1 || - Feld[x][y] == EL_SP_MURPHY) - player_found = TRUE; + for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) + { + if (Feld[x][y] == EL_PLAYER_1 || + Feld[x][y] == EL_SP_MURPHY) + player_found = TRUE; + } return player_found; } @@ -5840,42 +6261,59 @@ static int setSelectboxValue(int selectbox_id, int new_value) return new_index_value; } -static void copy_custom_element_settings(int element_from, int element_to) +static void setSelectboxSpecialActionVariablesIfNeeded() { -#if 0 - struct ElementInfo ei_to_old = element_info[element_to]; - struct ElementInfo *ei_from = &element_info[element_from]; - struct ElementInfo *ei_to = &element_info[element_to]; int i; - /* ---------- copy whole element structure ---------- */ - *ei_to = *ei_from; + /* change action mode and arg variables according to action type variable */ + for (i = 0; action_arg_options[i].value != -1; i++) + { + if (action_arg_options[i].value == custom_element_change.action_type) + { + int mode = action_arg_options[i].mode; - /* ---------- restore structure pointers which cannot be copied ---------- */ - ei_to->token_name = ei_to_old.token_name; - ei_to->class_name = ei_to_old.class_name; - ei_to->editor_description = ei_to_old.editor_description; - ei_to->custom_description = ei_to_old.custom_description; - ei_to->change_page = ei_to_old.change_page; - ei_to->change = ei_to_old.change; - ei_to->group = ei_to_old.group; + /* only change if corresponding selectbox has changed */ + if (selectbox_info[ED_SELECTBOX_ID_ACTION_MODE].options != + action_arg_modes[mode]) + custom_element_change.action_mode = -1; - /* ---------- copy element base properties ---------- */ - Properties[element_to][EP_BITFIELD_BASE] = - Properties[element_from][EP_BITFIELD_BASE]; + /* only change if corresponding selectbox has changed */ + if (selectbox_info[ED_SELECTBOX_ID_ACTION_ARG].options != + action_arg_options[i].options) + custom_element_change.action_arg = -1; - /* ---------- reinitialize and copy change pages ---------- */ - setElementChangePages(ei_to, ei_to->num_change_pages); + break; + } + } +} - for (i=0; i < ei_to->num_change_pages; i++) - ei_to->change_page[i] = ei_from->change_page[i]; +static void setSelectboxSpecialActionOptions() +{ + int i; - /* ---------- copy group element info ---------- */ - if (ei_from->group != NULL && ei_to->group != NULL) /* group or internal */ - *ei_to->group = *ei_from->group; + /* change action mode and arg selectbox according to action type selectbox */ + for (i = 0; action_arg_options[i].value != -1; i++) + { + if (action_arg_options[i].value == custom_element_change.action_type) + { + int mode = action_arg_options[i].mode; -#else + ModifyEditorSelectboxOptions(ED_SELECTBOX_ID_ACTION_MODE, + action_arg_modes[mode]); + ModifyEditorSelectboxValue(ED_SELECTBOX_ID_ACTION_MODE, + custom_element_change.action_mode); + + ModifyEditorSelectboxOptions(ED_SELECTBOX_ID_ACTION_ARG, + action_arg_options[i].options); + ModifyEditorSelectboxValue(ED_SELECTBOX_ID_ACTION_ARG, + custom_element_change.action_arg); + break; + } + } +} +static void copy_custom_element_settings(int element_from, int element_to) +{ struct ElementInfo *ei_from = &element_info[element_from]; struct ElementInfo *ei_to = &element_info[element_to]; int i, x, y; @@ -5895,8 +6333,12 @@ static void copy_custom_element_settings(int element_from, int element_to) ei_to->access_direction = ei_from->access_direction; - ei_to->collect_score = ei_from->collect_score; - ei_to->collect_count = ei_from->collect_count; + ei_to->collect_score_initial = ei_from->collect_score_initial; + ei_to->collect_count_initial = ei_from->collect_count_initial; + + ei_to->ce_value_fixed_initial = ei_from->ce_value_fixed_initial; + ei_to->ce_value_random_initial = ei_from->ce_value_random_initial; + ei_to->use_last_ce_value = ei_from->use_last_ce_value; ei_to->push_delay_fixed = ei_from->push_delay_fixed; ei_to->push_delay_random = ei_from->push_delay_random; @@ -5917,7 +6359,7 @@ static void copy_custom_element_settings(int element_from, int element_to) for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - ei_to->content[x][y] = ei_from->content[x][y]; + ei_to->content.e[x][y] = ei_from->content.e[x][y]; ei_to->explosion_type = ei_from->explosion_type; ei_to->explosion_delay = ei_from->explosion_delay; @@ -5937,8 +6379,6 @@ static void copy_custom_element_settings(int element_from, int element_to) if (ei_from->group != NULL && ei_to->group != NULL) /* group or internal */ *ei_to->group = *ei_from->group; -#endif - /* mark this custom element as modified */ ei_to->modified_settings = TRUE; } @@ -5954,8 +6394,8 @@ static void replace_custom_element_in_settings(int element_from, for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - if (ei->content[x][y] == element_from) - ei->content[x][y] = element_to; + if (ei->content.e[x][y] == element_from) + ei->content.e[x][y] = element_to; for (j = 0; j < ei->num_change_pages; j++) { @@ -5969,8 +6409,8 @@ static void replace_custom_element_in_settings(int element_from, for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - if (change->target_content[x][y] == element_from) - change->target_content[x][y] = element_to; + if (change->target_content.e[x][y] == element_from) + change->target_content.e[x][y] = element_to; } if (ei->group != NULL) /* group or internal */ @@ -6080,6 +6520,9 @@ static void CopyCustomElementPropertiesToEditor(int element) custom_element = element_info[element]; custom_element_change = *element_info[element].change; + /* needed to initially set selectbox options for special action options */ + setSelectboxSpecialActionOptions(); + /* needed to initially set selectbox value variables to reliable defaults */ for (i = 0; i < ED_NUM_SELECTBOX; i++) setSelectboxValue(i, *selectbox_info[i].value); @@ -6146,49 +6589,14 @@ static void CopyCustomElementPropertiesToEditor(int element) DONT_COLLIDE_WITH(element) || DONT_RUN_INTO(element)); -#if 0 - /* set explosion type selectbox help value */ - custom_element.explosion_type = - ( -#if 0 - IS_INDESTRUCTIBLE(element) ? EP_INDESTRUCTIBLE : -#endif - CAN_EXPLODE_1X1(element) ? EP_CAN_EXPLODE_1X1 : - CAN_EXPLODE_3X3(element) ? EP_CAN_EXPLODE_3X3 : - CAN_EXPLODE_CROSS(element) ? EP_CAN_EXPLODE_CROSS : - custom_element.explosion_type); - custom_element_properties[EP_CAN_EXPLODE_AT_ALL] = - ( -#if 0 - IS_INDESTRUCTIBLE(element) || -#endif - CAN_EXPLODE_1X1(element) || - CAN_EXPLODE_3X3(element) || - CAN_EXPLODE_CROSS(element)); -#endif - -#if 0 - /* special case: sub-settings dependent from main setting */ -#if 0 - custom_element.can_explode_by_fire = CAN_EXPLODE_BY_FIRE(element); - custom_element.can_explode_smashed = CAN_EXPLODE_SMASHED(element); - custom_element.can_explode_impact = CAN_EXPLODE_IMPACT(element); -#else - if (CAN_EXPLODE_BY_FIRE(element)) - custom_element.can_explode_by_fire = TRUE; - if (CAN_EXPLODE_SMASHED(element)) - custom_element.can_explode_smashed = TRUE; - if (CAN_EXPLODE_IMPACT(element)) - custom_element.can_explode_impact = TRUE; -#endif -#endif - /* ---------- element settings: advanced (custom elements) --------------- */ /* 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_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_PUSHED_BY_PLAYER) ? CE_PUSHED_BY_PLAYER : HAS_CHANGE_EVENT(element, CE_ENTERED_BY_PLAYER) ? CE_ENTERED_BY_PLAYER : HAS_CHANGE_EVENT(element, CE_LEFT_BY_PLAYER) ? CE_LEFT_BY_PLAYER : @@ -6199,12 +6607,15 @@ static void CopyCustomElementPropertiesToEditor(int element) HAS_CHANGE_EVENT(element, CE_BLOCKED) ? CE_BLOCKED : HAS_CHANGE_EVENT(element, CE_IMPACT) ? CE_IMPACT : HAS_CHANGE_EVENT(element, CE_SMASHED) ? CE_SMASHED : + HAS_CHANGE_EVENT(element, CE_VALUE_GETS_ZERO) ? CE_VALUE_GETS_ZERO : 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_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_PUSHES_X) ? CE_PLAYER_PUSHES_X : HAS_CHANGE_EVENT(element, CE_PLAYER_ENTERS_X) ? CE_PLAYER_ENTERS_X : HAS_CHANGE_EVENT(element, CE_PLAYER_LEAVES_X) ? CE_PLAYER_LEAVES_X : @@ -6213,10 +6624,14 @@ static void CopyCustomElementPropertiesToEditor(int element) HAS_CHANGE_EVENT(element, CE_PLAYER_DROPS_X) ? CE_PLAYER_DROPS_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_HIT_BY_X) ? CE_HIT_BY_X : HAS_CHANGE_EVENT(element, CE_SWITCH_OF_X) ? CE_SWITCH_OF_X : HAS_CHANGE_EVENT(element, CE_CHANGE_OF_X) ? CE_CHANGE_OF_X : HAS_CHANGE_EVENT(element, CE_EXPLOSION_OF_X) ? CE_EXPLOSION_OF_X : + HAS_CHANGE_EVENT(element, CE_MOVE_OF_X) ? CE_MOVE_OF_X : + HAS_CHANGE_EVENT(element, CE_CREATION_OF_X) ? CE_CREATION_OF_X : + HAS_CHANGE_EVENT(element, CE_VALUE_GETS_ZERO_OF_X) ? CE_VALUE_GETS_ZERO_OF_X : custom_element_change.other_action); } @@ -6228,7 +6643,6 @@ static void CopyGroupElementPropertiesToEditor(int element) static void CopyClassicElementPropertiesToEditor(int element) { -#if 1 if (ELEM_IS_PLAYER(element) || COULD_MOVE_INTO_ACID(element)) custom_element_properties[EP_CAN_MOVE_INTO_ACID] = getMoveIntoAcidProperty(&level, element); @@ -6236,17 +6650,6 @@ static void CopyClassicElementPropertiesToEditor(int element) if (MAYBE_DONT_COLLIDE_WITH(element)) custom_element_properties[EP_DONT_COLLIDE_WITH] = getDontCollideWithProperty(&level, element); -#else - - if (COULD_MOVE_INTO_ACID(element)) - { - int bit_nr = get_special_property_bit(element, EP_CAN_MOVE_INTO_ACID); - - if (bit_nr > -1) - custom_element_properties[EP_CAN_MOVE_INTO_ACID] = - ((level.can_move_into_acid_bits & (1 << bit_nr)) != 0); - } -#endif } static void CopyElementPropertiesToEditor(int element) @@ -6263,9 +6666,6 @@ static void CopyCustomElementPropertiesToGame(int element) { int i; int access_type_and_layer; -#if 0 - boolean can_explode; -#endif /* mark that this custom element has been modified */ custom_element.modified_settings = TRUE; @@ -6331,53 +6731,13 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_properties[custom_element.deadliness] = custom_element_properties[EP_DEADLY]; -#if 0 - /* set explosion type property from checkbox and selectbox */ -#if 0 - custom_element_properties[EP_INDESTRUCTIBLE] = FALSE; -#endif - custom_element_properties[EP_CAN_EXPLODE_1X1] = FALSE; - custom_element_properties[EP_CAN_EXPLODE_3X3] = FALSE; - custom_element_properties[EP_CAN_EXPLODE_CROSS] = FALSE; - custom_element_properties[EP_CAN_EXPLODE_BY_FIRE] = FALSE; - custom_element_properties[EP_CAN_EXPLODE_SMASHED] = FALSE; - custom_element_properties[EP_CAN_EXPLODE_IMPACT] = FALSE; - custom_element_properties[custom_element.explosion_type] = - custom_element_properties[EP_CAN_EXPLODE_AT_ALL]; -#endif - -#if 0 - /* special case: sub-settings dependent from main setting */ -#if 0 - can_explode = (custom_element_properties[EP_CAN_EXPLODE_1X1] || - custom_element_properties[EP_CAN_EXPLODE_3X3] || - custom_element_properties[EP_CAN_EXPLODE_CROSS]); - custom_element_properties[EP_CAN_EXPLODE_BY_FIRE] = - (can_explode && custom_element.can_explode_by_fire); - custom_element_properties[EP_CAN_EXPLODE_SMASHED] = - (can_explode && custom_element.can_explode_smashed); - custom_element_properties[EP_CAN_EXPLODE_IMPACT] = - (can_explode && custom_element.can_explode_impact); -#else - if (custom_element_properties[EP_CAN_EXPLODE_1X1] || - custom_element_properties[EP_CAN_EXPLODE_3X3] || - custom_element_properties[EP_CAN_EXPLODE_CROSS]) - { - custom_element_properties[EP_CAN_EXPLODE_BY_FIRE] = - custom_element.can_explode_by_fire; - custom_element_properties[EP_CAN_EXPLODE_SMASHED] = - custom_element.can_explode_smashed; - custom_element_properties[EP_CAN_EXPLODE_IMPACT] = - custom_element.can_explode_impact; - } -#endif -#endif - /* ---------- element settings: advanced (custom elements) --------------- */ /* set player change event from checkbox and selectbox */ 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_SNAPPED_BY_PLAYER] = FALSE; custom_element_change_events[CE_PUSHED_BY_PLAYER] = FALSE; custom_element_change_events[CE_ENTERED_BY_PLAYER] = FALSE; custom_element_change_events[CE_LEFT_BY_PLAYER] = FALSE; @@ -6388,12 +6748,15 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_change_events[CE_BLOCKED] = FALSE; custom_element_change_events[CE_IMPACT] = FALSE; custom_element_change_events[CE_SMASHED] = FALSE; + custom_element_change_events[CE_VALUE_GETS_ZERO] = 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_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_SNAPS_X] = FALSE; custom_element_change_events[CE_PLAYER_PUSHES_X] = FALSE; custom_element_change_events[CE_PLAYER_ENTERS_X] = FALSE; custom_element_change_events[CE_PLAYER_LEAVES_X] = FALSE; @@ -6402,10 +6765,14 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_change_events[CE_PLAYER_DROPS_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_HIT_BY_X] = FALSE; custom_element_change_events[CE_SWITCH_OF_X] = FALSE; custom_element_change_events[CE_CHANGE_OF_X] = FALSE; custom_element_change_events[CE_EXPLOSION_OF_X] = FALSE; + custom_element_change_events[CE_MOVE_OF_X] = FALSE; + custom_element_change_events[CE_CREATION_OF_X] = FALSE; + custom_element_change_events[CE_VALUE_GETS_ZERO_OF_X] = FALSE; custom_element_change_events[custom_element_change.other_action] = custom_element_change_events[CE_BY_OTHER_ACTION]; @@ -6432,7 +6799,6 @@ static void CopyGroupElementPropertiesToGame(int element) static void CopyClassicElementPropertiesToGame(int element) { -#if 1 if (ELEM_IS_PLAYER(element) || COULD_MOVE_INTO_ACID(element)) setMoveIntoAcidProperty(&level, element, custom_element_properties[EP_CAN_MOVE_INTO_ACID]); @@ -6440,21 +6806,6 @@ static void CopyClassicElementPropertiesToGame(int element) if (MAYBE_DONT_COLLIDE_WITH(element)) setDontCollideWithProperty(&level, element, custom_element_properties[EP_DONT_COLLIDE_WITH]); -#else - - if (COULD_MOVE_INTO_ACID(element)) - { - int bit_nr = get_special_property_bit(element, EP_CAN_MOVE_INTO_ACID); - - if (bit_nr > -1) - { - level.can_move_into_acid_bits &= ~(1 << bit_nr); - - if (custom_element_properties[EP_CAN_MOVE_INTO_ACID]) - level.can_move_into_acid_bits |= (1 << bit_nr); - } - } -#endif } static void CopyElementPropertiesToGame(int element) @@ -6494,11 +6845,6 @@ void DrawLevelEd() BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, DOOR_GFX_PAGEX6, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY); -#if 0 - /* draw mouse button brush elements */ - RedrawDrawingElements(); -#endif - /* draw bigger door */ DrawSpecialEditorDoor(); @@ -6508,10 +6854,8 @@ void DrawLevelEd() redraw_mask |= REDRAW_ALL; + ReinitializeElementList(); /* update dynamic level element list */ ReinitializeElementListButtons(); /* custom element may look different */ -#if 0 - ModifyEditorElementList(); /* may be needed for custom elements */ -#endif UnmapTapeButtons(); MapControlButtons(); @@ -6629,7 +6973,27 @@ static void AdjustEditorScrollbar(int id) GDI_SCROLLBAR_ITEM_POSITION, item_position, GDI_END); } -static void ModifyEditorCounter(int counter_id, int new_value) +static void AdjustElementListScrollbar() +{ + struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL]; + int items_max, items_visible, item_position; + + /* correct position of element list scrollbar */ + 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; + + items_max = num_editor_elements / ED_ELEMENTLIST_BUTTONS_HORIZ; + items_visible = ED_ELEMENTLIST_BUTTONS_VERT; + item_position = element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ; + + ModifyGadget(gi, GDI_SCROLLBAR_ITEMS_MAX, items_max, + GDI_SCROLLBAR_ITEMS_VISIBLE, items_visible, + GDI_SCROLLBAR_ITEM_POSITION, item_position, GDI_END); +} + +static void ModifyEditorCounterValue(int counter_id, int new_value) { int *counter_value = counterbutton_info[counter_id].value; int gadget_id = counterbutton_info[counter_id].gadget_id_text; @@ -6647,9 +7011,19 @@ static void ModifyEditorCounterLimits(int counter_id, int min, int max) struct GadgetInfo *gi = level_editor_gadget[gadget_id]; ModifyGadget(gi, GDI_NUMBER_MIN, min, GDI_NUMBER_MAX, max, GDI_END); + + if (counter_id >= ED_COUNTER_ID_ELEMENT_VALUE1 && + counter_id <= ED_COUNTER_ID_ELEMENT_VALUE4) + { + int gadget_id_up = counterbutton_info[counter_id].gadget_id_up; + struct GadgetInfo *gi_up = level_editor_gadget[gadget_id_up]; + + ModifyGadget(gi, GDI_TEXT_SIZE, (max < 10 ? 1 : 3), GDI_END); + ModifyGadget(gi_up, GDI_X, gi->x + gi->width + ED_GADGET_DISTANCE,GDI_END); + } } -static void ModifyEditorSelectbox(int selectbox_id, int new_value) +static void ModifyEditorSelectboxValue(int selectbox_id, int new_value) { int gadget_id = selectbox_info[selectbox_id].gadget_id; struct GadgetInfo *gi = level_editor_gadget[gadget_id]; @@ -6658,11 +7032,27 @@ static void ModifyEditorSelectbox(int selectbox_id, int new_value) ModifyGadget(gi, GDI_SELECTBOX_INDEX, new_index_value, GDI_END); } +static void ModifyEditorSelectboxOptions(int selectbox_id, + struct ValueTextInfo *options) +{ + int gadget_id = selectbox_info[selectbox_id].gadget_id; + struct GadgetInfo *gi = level_editor_gadget[gadget_id]; + + selectbox_info[selectbox_id].options = options; + + /* set index to zero -- list may be shorter now (correct later, if needed) */ + ModifyGadget(gi, GDI_SELECTBOX_INDEX, 0, + GDI_SELECTBOX_OPTIONS, options, GDI_END); +} + static void ModifyEditorDrawingArea(int drawingarea_id, int xsize, int ysize) { int gadget_id = drawingarea_info[drawingarea_id].gadget_id; struct GadgetInfo *gi = level_editor_gadget[gadget_id]; + drawingarea_info[drawingarea_id].area_xsize = xsize; + drawingarea_info[drawingarea_id].area_ysize = ysize; + ModifyGadget(gi, GDI_AREA_SIZE, xsize, ysize, GDI_END); } @@ -6678,8 +7068,10 @@ static void ModifyEditorElementList() int element = editor_elements[element_shift + i]; UnmapGadget(gi); + getMiniGraphicSource(el2edimg(element), &gd->bitmap, &gd->x, &gd->y); ModifyGadget(gi, GDI_INFO_TEXT, getElementInfoText(element), GDI_END); + MapGadget(gi); } } @@ -6752,10 +7144,15 @@ static void DrawLevelInfoWindow() ClearWindow(); UnmapLevelEditorWindowGadgets(); +#if 0 + DrawTextSCentered(ED_SETTINGS1_YPOS, FONT_TITLE_1, "Level Settings"); + DrawTextSCentered(ED_SETTINGS2_YPOS, FONT_TITLE_1, "Editor Settings"); +#else DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS1_YPOS, "Level Settings", FONT_TITLE_1); DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS2_YPOS, "Editor Settings", FONT_TITLE_1); +#endif /* draw counter gadgets */ for (i = ED_COUNTER_ID_LEVEL_FIRST; i <= ED_COUNTER_ID_LEVEL_LAST; i++) @@ -6854,12 +7251,59 @@ static void DrawMagicBallContentAreas() int y = SY + ED_AREA_MAGIC_BALL_CONTENT_YPOS(0) + ED_BORDER_AREA_YSIZE; int i; - for (i = 0; i < NUM_MAGIC_BALL_CONTENTS; i++) - MapDrawingArea(ED_DRAWING_ID_MAGIC_BALL_CONTENT_0 + i); + /* display counter to choose number of element content areas */ + MapCounterButtons(ED_COUNTER_ID_BALL_CONTENT); + + for (i = 0; i < MAX_ELEMENT_CONTENTS; i++) + { + int id = ED_DRAWING_ID_MAGIC_BALL_CONTENT_0 + i; + + if (i < level.num_ball_contents) + { + MapDrawingArea(id); + } + else + { + int font_height = getFontHeight(FONT_TEXT_1); + + UnmapDrawingArea(id); + + /* delete content areas in case of reducing number of them */ + DrawBackground(SX + drawingarea_info[id].x - MINI_TILEX / 2, + SY + drawingarea_info[id].y - MINI_TILEY / 2, + 4 * MINI_TILEX, + 4 * MINI_TILEY + ED_GADGET_TEXT_DISTANCE + font_height); + } + } + + DrawText(x, y + 0 * MINI_TILEY, "generated", FONT_TEXT_1); + DrawText(x, y + 1 * MINI_TILEY, "when", FONT_TEXT_1); + DrawText(x, y + 2 * MINI_TILEY, "active", FONT_TEXT_1); +} + +static void DrawAndroidElementArea(int element) +{ + int num_elements = level.num_android_clone_elements; + int id = ED_DRAWING_ID_ANDROID_CONTENT; + int sx = SX + drawingarea_info[id].x - MINI_TILEX / 2; + int sy = SY + drawingarea_info[id].y - MINI_TILEY / 2; + int xsize = MAX_ANDROID_ELEMENTS; + int ysize = 1; + + /* display counter to choose number of element areas */ + MapCounterButtons(ED_COUNTER_ID_ANDROID_CONTENT); + + if (drawingarea_info[id].text_left != NULL) + sx += getTextWidthForDrawingArea(drawingarea_info[id].text_left); + + UnmapDrawingArea(id); - DrawText(x, y + 0 * MINI_TILEY, "generated", FONT_TEXT_1); - DrawText(x, y + 1 * MINI_TILEY, "when", FONT_TEXT_1); - DrawText(x, y + 2 * MINI_TILEY, "active", FONT_TEXT_1); + ModifyEditorDrawingArea(id, num_elements, 1); + + /* delete content areas in case of reducing number of them */ + DrawBackground(sx, sy, (xsize + 1) * MINI_TILEX, (ysize + 1) * MINI_TILEY); + + MapDrawingArea(id); } static void DrawGroupElementArea(int element) @@ -6946,8 +7390,6 @@ static boolean PrintInfoText(char *text, int font_nr, int start_line) return TRUE; } -#if 1 - static int PrintElementDescriptionFromFile(char *filename, int start_line) { int font_nr = FONT_TEXT_2; @@ -6964,97 +7406,6 @@ static int PrintElementDescriptionFromFile(char *filename, int start_line) max_lines_per_screen); } -#else - -static int PrintElementDescriptionFromFile(char *filename, int start_line) -{ - int font_nr = FONT_TEXT_2; - int font_width = getFontWidth(font_nr); - int font_height = getFontHeight(font_nr); - int pad_x = ED_ELEMENT_SETTINGS_XPOS(0); - int pad_y = ED_ELEMENT_SETTINGS_YPOS(0) + ED_BORDER_SIZE; - int sx = SX + pad_x; - int sy = SY + pad_y; - int max_chars_per_line = (SXSIZE - 2 * pad_x) / font_width; - int max_lines_per_screen = (SYSIZE - pad_y) / font_height - 1; - int current_line = start_line; - char line[MAX_LINE_LEN]; - char buffer[max_chars_per_line + 1]; - int buffer_len; - FILE *file; - - if (current_line >= max_lines_per_screen) - return 0; - - if (filename == NULL) - return 0; - - if (!(file = fopen(filename, MODE_READ))) - return 0; - - buffer[0] = '\0'; - buffer_len = 0; - - while (!feof(file) && current_line < max_lines_per_screen) - { - char *line_ptr; - boolean last_line_was_empty = TRUE; - - /* read next line of input file */ - if (!fgets(line, MAX_LINE_LEN, file)) - break; - - /* skip comments (lines directly beginning with '#') */ - if (line[0] == '#') - continue; - - /* cut trailing newline from input line */ - for (line_ptr = line; *line_ptr; line_ptr++) - { - if (*line_ptr == '\n' || *line_ptr == '\r') - { - *line_ptr = '\0'; - break; - } - } - - if (strlen(line) == 0) /* special case: force empty line */ - strcpy(line, "\n"); - - line_ptr = line; - - while (*line_ptr && current_line < max_lines_per_screen) - { - boolean buffer_filled = RenderLineToBuffer(&line_ptr, - buffer, &buffer_len, - last_line_was_empty, - max_chars_per_line); - if (buffer_filled) - { - DrawText(sx, sy + current_line * font_height, buffer, font_nr); - current_line++; - - last_line_was_empty = (buffer_len == 0); - - buffer[0] = '\0'; - buffer_len = 0; - } - } - } - - fclose(file); - - if (buffer_len > 0 && current_line < max_lines_per_screen) - { - DrawText(sx, sy + current_line * font_height, buffer, font_nr); - current_line++; - } - - return (current_line - start_line); -} - -#endif - static void DrawPropertiesTabulatorGadgets() { struct GadgetInfo *gd_gi = level_editor_gadget[GADGET_ID_PROPERTIES_INFO]; @@ -7152,7 +7503,9 @@ static void DrawPropertiesInfo() /* pre-defined properties */ { EP_CAN_PASS_MAGIC_WALL, "- can pass magic walls" }, { EP_SWITCHABLE, "- can be switched" }, - { EP_HAS_CONTENT, "- can contain other elements" }, +#if 0 + { EP_HAS_EDITOR_CONTENT, "- can contain other elements" }, +#endif { -1, NULL } }; @@ -7240,6 +7593,11 @@ static void DrawPropertiesInfo() #define TEXT_BALL_DELAY "Element generation delay" #define TEXT_MOVE_SPEED "Speed of android moving" #define TEXT_CLONE_SPEED "Speed of android cloning" +#define TEXT_GAME_OF_LIFE_1 "Min neighbours to survive" +#define TEXT_GAME_OF_LIFE_2 "Max neighbours to survive" +#define TEXT_GAME_OF_LIFE_3 "Min neighbours to create" +#define TEXT_GAME_OF_LIFE_4 "Max neighbours to create" +#define TEXT_TIME_BONUS "Extra time to solve level" static struct { @@ -7294,22 +7652,15 @@ static struct { 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.score[SC_TIME_BONUS], TEXT_COLLECTING }, + { EL_EXTRA_TIME, &level.extra_time_score, TEXT_COLLECTING }, { EL_KEY_1, &level.score[SC_KEY], TEXT_COLLECTING }, { EL_KEY_2, &level.score[SC_KEY], TEXT_COLLECTING }, { EL_KEY_3, &level.score[SC_KEY], TEXT_COLLECTING }, { EL_KEY_4, &level.score[SC_KEY], TEXT_COLLECTING }, -#if 1 { EL_EM_KEY_1, &level.score[SC_KEY], TEXT_COLLECTING }, { EL_EM_KEY_2, &level.score[SC_KEY], TEXT_COLLECTING }, { EL_EM_KEY_3, &level.score[SC_KEY], TEXT_COLLECTING }, { EL_EM_KEY_4, &level.score[SC_KEY], TEXT_COLLECTING }, -#else - { EL_EM_KEY_1_FILE, &level.score[SC_KEY], TEXT_COLLECTING }, - { EL_EM_KEY_2_FILE, &level.score[SC_KEY], TEXT_COLLECTING }, - { EL_EM_KEY_3_FILE, &level.score[SC_KEY], TEXT_COLLECTING }, - { EL_EM_KEY_4_FILE, &level.score[SC_KEY], TEXT_COLLECTING }, -#endif { EL_EMC_KEY_5, &level.score[SC_KEY], TEXT_COLLECTING }, { EL_EMC_KEY_6, &level.score[SC_KEY], TEXT_COLLECTING }, { EL_EMC_KEY_7, &level.score[SC_KEY], TEXT_COLLECTING }, @@ -7319,8 +7670,26 @@ static struct { EL_AMOEBA_FULL, &level.amoeba_speed, TEXT_AMOEBA_SPEED }, { EL_BD_AMOEBA, &level.amoeba_speed, TEXT_AMOEBA_SPEED }, { EL_MAGIC_WALL, &level.time_magic_wall, TEXT_DURATION }, + { EL_BD_MAGIC_WALL, &level.time_magic_wall, TEXT_DURATION }, { EL_ROBOT_WHEEL, &level.time_wheel, TEXT_DURATION }, +#if 1 + { EL_TIMEGATE_SWITCH, &level.time_timegate, TEXT_DURATION }, + { EL_LIGHT_SWITCH_ACTIVE, &level.time_light, TEXT_DURATION }, + { EL_SHIELD_NORMAL, &level.shield_normal_time, TEXT_DURATION }, + { EL_SHIELD_DEADLY, &level.shield_deadly_time, TEXT_DURATION }, + { EL_EXTRA_TIME, &level.extra_time, TEXT_TIME_BONUS }, + { EL_TIME_ORB_FULL, &level.time_orb_time, TEXT_TIME_BONUS }, + { EL_GAME_OF_LIFE, &level.game_of_life[0], TEXT_GAME_OF_LIFE_1 }, + { EL_GAME_OF_LIFE, &level.game_of_life[1], TEXT_GAME_OF_LIFE_2 }, + { EL_GAME_OF_LIFE, &level.game_of_life[2], TEXT_GAME_OF_LIFE_3 }, + { EL_GAME_OF_LIFE, &level.game_of_life[3], TEXT_GAME_OF_LIFE_4 }, + { EL_BIOMAZE, &level.biomaze[0], TEXT_GAME_OF_LIFE_1 }, + { EL_BIOMAZE, &level.biomaze[1], TEXT_GAME_OF_LIFE_2 }, + { EL_BIOMAZE, &level.biomaze[2], TEXT_GAME_OF_LIFE_3 }, + { EL_BIOMAZE, &level.biomaze[3], TEXT_GAME_OF_LIFE_4 }, +#endif + #if 1 { EL_EMC_ANDROID, &level.android_move_time, TEXT_MOVE_SPEED }, { EL_EMC_ANDROID, &level.android_clone_time, TEXT_CLONE_SPEED }, @@ -7344,7 +7713,7 @@ static boolean checkPropertiesConfig(int element) IS_GROUP_ELEMENT(element) || IS_ENVELOPE(element) || ELEM_IS_PLAYER(element) || - HAS_CONTENT(element) || + HAS_EDITOR_CONTENT(element) || CAN_GROW(element) || COULD_MOVE_INTO_ACID(element) || MAYBE_DONT_COLLIDE_WITH(element)) @@ -7359,7 +7728,7 @@ static boolean checkPropertiesConfig(int element) static void DrawPropertiesConfig() { - int max_num_element_counters = 2; + int max_num_element_counters = 4; int num_element_counters = 0; int i; @@ -7378,18 +7747,29 @@ static void DrawPropertiesConfig() int counter_id = ED_COUNTER_ID_ELEMENT_VALUE1 + num_element_counters; counterbutton_info[counter_id].y = - ED_ELEMENT_SETTINGS_YPOS((HAS_CONTENT(properties_element) ? 1 : 0) + - (CAN_GROW(properties_element) ? 1 : 0) + - (COULD_MOVE_INTO_ACID(properties_element) ? 1 : 0) + - (MAYBE_DONT_COLLIDE_WITH(properties_element) ? 1 : 0)+ - num_element_counters); + ED_ELEMENT_SETTINGS_YPOS( + (HAS_EDITOR_CONTENT(properties_element) ? 1 : 0) + + (CAN_GROW(properties_element) ? 1 : 0) + + (COULD_MOVE_INTO_ACID(properties_element) ? 1 : 0) + + (MAYBE_DONT_COLLIDE_WITH(properties_element) ? 1 : 0) + + (properties_element == EL_EMC_MAGIC_BALL ? 2 : 0) + + num_element_counters); counterbutton_info[counter_id].value = elements_with_counter[i].value; counterbutton_info[counter_id].text_right= elements_with_counter[i].text; - /* !!! CHANGE THIS FOR CERTAIN ELEMENTS !!! */ - counterbutton_info[counter_id].min_value = MIN_SCORE; - counterbutton_info[counter_id].max_value = MAX_SCORE; + if (properties_element == EL_GAME_OF_LIFE || + properties_element == EL_BIOMAZE) + { + counterbutton_info[counter_id].min_value = 0; /* min neighbours */ + counterbutton_info[counter_id].max_value = 8; /* max neighbours */ + } + else + { + /* !!! CHANGE THIS FOR CERTAIN ELEMENTS !!! */ + counterbutton_info[counter_id].min_value = MIN_SCORE; + counterbutton_info[counter_id].max_value = MAX_SCORE; + } MapCounterButtons(counter_id); @@ -7399,7 +7779,7 @@ static void DrawPropertiesConfig() } } - if (HAS_CONTENT(properties_element)) + if (HAS_EDITOR_CONTENT(properties_element)) { /* draw stickybutton gadget */ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_STICK_ELEMENT); @@ -7408,20 +7788,53 @@ static void DrawPropertiesConfig() MapDrawingArea(ED_DRAWING_ID_AMOEBA_CONTENT); else if (properties_element == EL_YAMYAM) DrawYamYamContentAreas(); - } + else if (properties_element == EL_EMC_MAGIC_BALL) + { + DrawMagicBallContentAreas(); - if (properties_element == EL_EMC_MAGIC_BALL) - DrawMagicBallContentAreas(); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INITIAL_BALL_STATE); + } + else if (properties_element == EL_EMC_ANDROID) + DrawAndroidElementArea(properties_element); + } if (ELEM_IS_PLAYER(properties_element)) { + int player_nr = GET_PLAYER_NR(properties_element); + + /* these properties can be set for every player individually */ + drawingarea_info[ED_DRAWING_ID_START_ELEMENT].value = + &level.start_element[player_nr]; + drawingarea_info[ED_DRAWING_ID_ARTWORK_ELEMENT].value = + &level.artwork_element[player_nr]; + drawingarea_info[ED_DRAWING_ID_EXPLOSION_ELEMENT].value = + &level.explosion_element[player_nr]; + + /* these properties can be set for every player individually */ + checkbutton_info[ED_CHECKBUTTON_ID_USE_START_ELEMENT].value = + &level.use_start_element[player_nr]; + checkbutton_info[ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT].value = + &level.use_artwork_element[player_nr]; + checkbutton_info[ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT].value = + &level.use_explosion_element[player_nr]; + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID); MapCheckbuttonGadget(properties_element == EL_SP_MURPHY ? ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD : ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INSTANT_RELOCATION); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_START_ELEMENT); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE); - MapCheckbuttonGadget(ED_CHECKBUTTON_ID_DOUBLE_SPEED); + + MapDrawingArea(ED_DRAWING_ID_START_ELEMENT); + MapDrawingArea(ED_DRAWING_ID_ARTWORK_ELEMENT); + MapDrawingArea(ED_DRAWING_ID_EXPLOSION_ELEMENT); + + MapSelectboxGadget(ED_SELECTBOX_ID_PLAYER_SPEED); } if (IS_GEM(properties_element)) @@ -7437,7 +7850,7 @@ static void DrawPropertiesConfig() 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 : - HAS_CONTENT(properties_element) ? 1 : 0); + HAS_EDITOR_CONTENT(properties_element) ? 1 : 0); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID); } @@ -7448,10 +7861,18 @@ static void DrawPropertiesConfig() if (properties_element == EL_SPRING) MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_SPRING_BUG); + if (properties_element == EL_TIME_ORB_FULL) + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_TIME_ORB_BUG); + +#if 0 + if (properties_element == EL_BALLOON) + MapSelectboxGadget(ED_SELECTBOX_ID_WIND_DIRECTION); +#endif + if (CAN_GROW(properties_element)) { checkbutton_info[ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE].y = - ED_ELEMENT_SETTINGS_YPOS(HAS_CONTENT(properties_element) ? 1 : 0); + ED_ELEMENT_SETTINGS_YPOS(HAS_EDITOR_CONTENT(properties_element) ? 1 : 0); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE); } @@ -7572,6 +7993,9 @@ static void DrawPropertiesChange() { int i; + /* needed to initially set selectbox options for special action options */ + setSelectboxSpecialActionOptions(); + /* draw stickybutton gadget */ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_STICK_ELEMENT); @@ -7604,7 +8028,18 @@ static void DrawPropertiesChange() DrawPropertiesChangeDrawingAreas(); } -static void DrawElementName(int x, int y, int element) +static void DrawEditorElementAnimation(int x, int y) +{ + int graphic = el2img(properties_element); + int frame = (ANIM_MODE(graphic) == ANIM_CE_VALUE ? + custom_element.ce_value_fixed_initial : + ANIM_MODE(graphic) == ANIM_CE_SCORE ? + custom_element.collect_score_initial : FrameCounter); + + DrawGraphicAnimationExt(drawto, x, y, graphic, frame, NO_MASKING); +} + +static void DrawEditorElementName(int x, int y, int element) { char *element_name = getElementInfoText(element); int font_nr = FONT_TEXT_1; @@ -7678,21 +8113,37 @@ static void DrawPropertiesWindow() SetMainBackgroundImage(IMG_BACKGROUND_EDITOR); ClearWindow(); +#if 0 + DrawTextSCentered(ED_SETTINGS1_YPOS, FONT_TITLE_1, "Element Settings"); +#else DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS1_YPOS, "Element Settings", FONT_TITLE_1); +#endif + +#if 1 + FrameCounter = 0; /* restart animation frame counter */ +#endif DrawElementBorder(SX + xstart * MINI_TILEX, SY + ystart * MINI_TILEY + MINI_TILEY / 2, TILEX, TILEY, FALSE); +#if 1 + DrawEditorElementAnimation(SX + xstart * MINI_TILEX, + SY + ystart * MINI_TILEY + MINI_TILEY / 2); +#else DrawGraphicAnimationExt(drawto, SX + xstart * MINI_TILEX, SY + ystart * MINI_TILEY + MINI_TILEY / 2, el2img(properties_element), -1, NO_MASKING); +#endif +#if 0 FrameCounter = 0; /* restart animation frame counter */ +#endif - DrawElementName((xstart + 3) * MINI_TILEX + 1, (ystart + 1) * MINI_TILEY + 1, - properties_element); + DrawEditorElementName((xstart + 3) * MINI_TILEX + 1, + (ystart + 1) * MINI_TILEY + 1, + properties_element); DrawPropertiesTabulatorGadgets(); @@ -7868,6 +8319,7 @@ static void DrawArc(int from_x, int from_y, int to_x, int to_y, } #define DRAW_CIRCLES_BUTTON_AVAILABLE 0 + #if DRAW_CIRCLES_BUTTON_AVAILABLE static void DrawCircle(int from_x, int from_y, int to_x, int to_y, int element, boolean change_level) @@ -7955,35 +8407,6 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, int element = brush_buffer[x][y]; int element_mapped = element; -#if 0 - char *element_string = "?"; - int k; - - for (k = 0; forum_sketch_element_mapping[k].element != -1; k++) - { - if (forum_sketch_element_mapping[k].element == element) - { - element_mapped = forum_sketch_element_mapping[k].element_mapped; - break; - } - } - - if (IS_CUSTOM_ELEMENT(element)) - element_mapped = EL_CUSTOM_1; - - for (k = 0; forum_sketch_element_strings[k].element != -1; k++) - { - if (forum_sketch_element_strings[k].element == element_mapped) - { - element_string = forum_sketch_element_strings[k].element_string; - break; - } - } - - printf("`%s", element_string); - -#else - if (IS_CUSTOM_ELEMENT(element)) element_mapped = EL_CUSTOM_START; else if (IS_GROUP_ELEMENT(element)) @@ -7992,7 +8415,6 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, element_mapped = EL_UNKNOWN; printf("%c%03d", (mode == CB_DUMP_BRUSH ? '`' : '¸'), element_mapped); -#endif } printf("\n"); @@ -8454,6 +8876,11 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (!started_inside_drawing_area) return; +#if 1 + if (!IS_VALID_BUTTON(button)) + return; +#endif + if (!button && !button_release_event) return; @@ -8518,6 +8945,9 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) } else { + int type_id = gi->custom_type_id; + int pos = sx * drawingarea_info[type_id].area_ysize + sy; + if (item_xsize == MINI_TILEX && item_ysize == MINI_TILEY) DrawMiniGraphicExt(drawto, gi->x + sx * MINI_TILEX, @@ -8529,71 +8959,19 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) gi->y + sy * TILEY, el2img(new_element), 0); - if (id == GADGET_ID_AMOEBA_CONTENT) - level.amoeba_content = new_element; - else if (id == GADGET_ID_CUSTOM_GRAPHIC) - { + if (id == GADGET_ID_CUSTOM_GRAPHIC) new_element = GFX_ELEMENT(new_element); - custom_element.gfx_element = new_element; - - CopyElementPropertiesToGame(properties_element); - - UpdateCustomElementGraphicGadgets(); - - FrameCounter = 0; /* restart animation frame counter */ - } - else if (id == GADGET_ID_CUSTOM_CONTENT) - { - custom_element.content[sx][sy] = new_element; - - CopyCustomElementPropertiesToGame(properties_element); - } - else if (id == GADGET_ID_CUSTOM_MOVE_ENTER) - { - custom_element.move_enter_element = new_element; - - CopyCustomElementPropertiesToGame(properties_element); - } - else if (id == GADGET_ID_CUSTOM_MOVE_LEAVE) - { - custom_element.move_leave_element = new_element; - CopyCustomElementPropertiesToGame(properties_element); - } - else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET) - { - custom_element_change.target_element = new_element; - - CopyCustomElementPropertiesToGame(properties_element); - } - else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT) - { - custom_element_change.target_content[sx][sy] = new_element; + drawingarea_info[type_id].value[pos] = new_element; - CopyCustomElementPropertiesToGame(properties_element); - } - else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) - { - custom_element_change.trigger_element = new_element; + CopyElementPropertiesToGame(properties_element); - CopyCustomElementPropertiesToGame(properties_element); - } - else if (id == GADGET_ID_GROUP_CONTENT) + if (id == GADGET_ID_CUSTOM_GRAPHIC) { - group_element_info.element[sx] = new_element; + UpdateCustomElementGraphicGadgets(); - CopyGroupElementPropertiesToGame(properties_element); + FrameCounter = 0; /* restart animation frame counter */ } - else if (id == GADGET_ID_RANDOM_BACKGROUND) - random_placement_background_element = new_element; - else if (id >= GADGET_ID_YAMYAM_CONTENT_0 && - id <= GADGET_ID_YAMYAM_CONTENT_7) - level.yamyam_content[id - GADGET_ID_YAMYAM_CONTENT_0][sx][sy] = - new_element; - else if (id >= GADGET_ID_MAGIC_BALL_CONTENT_0 && - id <= GADGET_ID_MAGIC_BALL_CONTENT_7) - level.ball_content[id - GADGET_ID_MAGIC_BALL_CONTENT_0][sx][sy] = - new_element; } break; @@ -8692,39 +9070,12 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) MB_LEFTBUTTON); else if (draw_level) PickDrawingElement(button, Feld[lx][ly]); - else if (id == GADGET_ID_AMOEBA_CONTENT) - PickDrawingElement(button, level.amoeba_content); - else if (id == GADGET_ID_CUSTOM_GRAPHIC) - PickDrawingElement(button, custom_element.gfx_element); - else if (id == GADGET_ID_CUSTOM_CONTENT) - PickDrawingElement(button, custom_element.content[sx][sy]); - else if (id == GADGET_ID_CUSTOM_MOVE_ENTER) - PickDrawingElement(button, custom_element.move_enter_element); - else if (id == GADGET_ID_CUSTOM_MOVE_LEAVE) - PickDrawingElement(button, custom_element.move_leave_element); - else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET) - PickDrawingElement(button, custom_element_change.target_element); - else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT) - PickDrawingElement(button, custom_element_change.target_content[sx][sy]); - else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) - PickDrawingElement(button, custom_element_change.trigger_element); - else if (id == GADGET_ID_GROUP_CONTENT) - PickDrawingElement(button, group_element_info.element[sx]); - else if (id == GADGET_ID_RANDOM_BACKGROUND) - PickDrawingElement(button, random_placement_background_element); - else if (id >= GADGET_ID_YAMYAM_CONTENT_0 && - id <= GADGET_ID_YAMYAM_CONTENT_7) - { - int i = id - GADGET_ID_YAMYAM_CONTENT_0; - - PickDrawingElement(button, level.yamyam_content[i][sx][sy]); - } - else if (id >= GADGET_ID_MAGIC_BALL_CONTENT_0 && - id <= GADGET_ID_MAGIC_BALL_CONTENT_7) + else { - int i = id - GADGET_ID_MAGIC_BALL_CONTENT_0; + int type_id = gi->custom_type_id; + int pos = sx * drawingarea_info[type_id].area_ysize + sy; - PickDrawingElement(button, level.ball_content[i][sx][sy]); + PickDrawingElement(button, drawingarea_info[type_id].value[pos]); } break; @@ -8756,7 +9107,7 @@ static void HandleCounterButtons(struct GadgetInfo *gi) REQ_ASK)) { if (gadget_id == counterbutton_info[counter_id].gadget_id_text) - ModifyEditorCounter(counter_id, *counter_value); + ModifyEditorCounterValue(counter_id, *counter_value); return; } @@ -8765,7 +9116,7 @@ static void HandleCounterButtons(struct GadgetInfo *gi) if (gadget_id == counterbutton_info[counter_id].gadget_id_text) *counter_value = gi->textinput.number_value; else - ModifyEditorCounter(counter_id, *counter_value + step); + ModifyEditorCounterValue(counter_id, *counter_value + step); if (counter_id == ED_COUNTER_ID_SELECT_LEVEL) { @@ -8783,6 +9134,14 @@ static void HandleCounterButtons(struct GadgetInfo *gi) DrawYamYamContentAreas(); break; + case ED_COUNTER_ID_BALL_CONTENT: + DrawMagicBallContentAreas(); + break; + + case ED_COUNTER_ID_ANDROID_CONTENT: + DrawAndroidElementArea(properties_element); + break; + case ED_COUNTER_ID_GROUP_CONTENT: DrawGroupElementArea(properties_element); CopyGroupElementPropertiesToGame(properties_element); @@ -8840,9 +9199,10 @@ static void HandleTextAreaGadgets(struct GadgetInfo *gi) static void HandleSelectboxGadgets(struct GadgetInfo *gi) { int type_id = gi->custom_type_id; + int value_old = *selectbox_info[type_id].value; + int value_new = selectbox_info[type_id].options[gi->selectbox.index].value; - *selectbox_info[type_id].value = - selectbox_info[type_id].options[gi->selectbox.index].value; + *selectbox_info[type_id].value = value_new; if (type_id == ED_SELECTBOX_ID_SELECT_CHANGE_PAGE) { @@ -8856,6 +9216,22 @@ static void HandleSelectboxGadgets(struct GadgetInfo *gi) type_id <= ED_SELECTBOX_ID_CHANGE_LAST) || (type_id == ED_SELECTBOX_ID_GROUP_CHOICE_MODE)) { + if (type_id == ED_SELECTBOX_ID_ACTION_TYPE) + { + /* when changing action type, also check action mode and action arg */ + if (value_old != value_new) + { +#if 1 + setSelectboxSpecialActionVariablesIfNeeded(); +#else + custom_element_change.action_mode = -1; + custom_element_change.action_arg = -1; +#endif + } + + DrawPropertiesChange(); + } + CopyElementPropertiesToGame(properties_element); level.changed = TRUE; @@ -9024,6 +9400,14 @@ static void HandleControlButtons(struct GadgetInfo *gi) int new_element = BUTTON_ELEMENT(button); int x, y; +#if 0 + /* MAKES PROBLEMS WITH ELEMENT LIST SCROLLBAR AND IS PROBABLY NOT NEEDED */ + /* !!! CHECK WHAT HAPPENS WHEN MOUSE WHEEL IS USED OVER ELEMENT LIST !!! */ + + if (!IS_VALID_BUTTON(button)) + return; +#endif + if (edit_mode == ED_MODE_DRAWING && drawing_function == GADGET_ID_TEXT) DrawLevelText(0, 0, 0, TEXT_END); @@ -9331,13 +9715,9 @@ static void HandleControlButtons(struct GadgetInfo *gi) DrawCompleteVideoDisplay(); - if (setup.autorecord) - TapeStartRecording(); - level_editor_test_game = TRUE; - game_status = GAME_MODE_PLAYING; - InitGame(); + StartGameActions(FALSE, setup.autorecord, NEW_RANDOMIZE); } break; @@ -9352,6 +9732,37 @@ static void HandleControlButtons(struct GadgetInfo *gi) int element_position = id - GADGET_ID_ELEMENTLIST_FIRST; int new_element = editor_elements[element_position + element_shift]; + if (IS_EDITOR_CASCADE(new_element)) + { + int i; + + for (i = 0; editor_elements_info[i].setup_value != NULL; i++) + { + int *cascade_element= &(*editor_elements_info[i].headline_list)[0]; + boolean *cascade_value=editor_elements_info[i].setup_cascade_value; + + if (*cascade_element == new_element) + { + *cascade_element = EL_CASCADE_TOGGLE(*cascade_element); + *cascade_value = IS_EDITOR_CASCADE_ACTIVE(*cascade_element); + + /* update element selection list */ + ReinitializeElementList(); + ModifyEditorElementList(); + + /* update cascading gadget info text */ + PrintEditorGadgetInfoText(level_editor_gadget[id]); + + /* save current editor cascading state */ + SaveSetup_EditorCascade(); + + break; + } + } + + break; + } + if (last_custom_copy_mode != -1) { if (CopyCustomElement(properties_element, new_element, @@ -9489,10 +9900,15 @@ void HandleLevelEditorIdle() if (!DelayReached(&action_delay, action_delay_value)) return; +#if 1 + DrawEditorElementAnimation(SX + xpos * TILEX, + SY + ypos * TILEY + MINI_TILEY / 2); +#else DrawGraphicAnimationExt(drawto, SX + xpos * TILEX, SY + ypos * TILEY + MINI_TILEY / 2, el2img(properties_element), -1, NO_MASKING); +#endif MarkTileDirty(xpos, ypos); MarkTileDirty(xpos, ypos + 1); @@ -9505,25 +9921,66 @@ void ClearEditorGadgetInfoText() 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 || gi->info_text == NULL) + return; + + strncpy(infotext, gi->info_text, max_infotext_len); + infotext[max_infotext_len] = '\0'; + + if (gi->custom_id < ED_NUM_CTRL_BUTTONS) + { + int key = control_info[gi->custom_id].shortcut; + + if (key) + { + if (gi->custom_id == GADGET_ID_SINGLE_ITEMS) /* special case 1 */ + sprintf(shortcut, " ('.' or '%c')", key); + else if (gi->custom_id == GADGET_ID_PICK_ELEMENT) /* special case 2 */ + sprintf(shortcut, " ('%c' or 'Ctrl')", key); + else if (gi->custom_id == GADGET_ID_TEST) /* special case 3 */ + sprintf(shortcut, " ('Enter' or 'Shift-%c')", key); + else /* normal case */ + sprintf(shortcut, " ('%s%c')", + (key >= 'A' && key <= 'Z' ? "Shift-" : ""), key); + + if (strlen(infotext) + strlen(shortcut) <= max_infotext_len) + strcat(infotext, shortcut); + } + } + + DrawText(INFOTEXT_XPOS, INFOTEXT_YPOS, infotext, FONT_TEXT_2); +} + void HandleEditorGadgetInfoText(void *ptr) { struct GadgetInfo *gi = (struct GadgetInfo *)ptr; +#if 0 char infotext[MAX_OUTPUT_LINESIZE + 1]; char shortcut[MAX_OUTPUT_LINESIZE + 1]; int max_infotext_len = getMaxInfoTextLength(); +#endif if (game_status != GAME_MODE_EDITOR) return; ClearEditorGadgetInfoText(); - if (gi->event.type == GD_EVENT_INFO_LEAVING) + if (gi == NULL || gi->event.type == GD_EVENT_INFO_LEAVING) return; /* misuse this function to delete brush cursor, if needed */ if (edit_mode == ED_MODE_DRAWING && draw_with_brush) DeleteBrushFromCursor(); +#if 1 + PrintEditorGadgetInfoText(gi); +#else if (gi == NULL || gi->info_text == NULL) return; @@ -9552,12 +10009,14 @@ void HandleEditorGadgetInfoText(void *ptr) } DrawText(INFOTEXT_XPOS, INFOTEXT_YPOS, infotext, FONT_TEXT_2); +#endif } 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 sy = gi->event.y; int lx = sx + level_xpos; @@ -9653,35 +10112,16 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) break; } -#if 1 if (actual_drawing_function == GADGET_ID_PICK_ELEMENT) sprintf(infotext, "%s: %d, %d", text, lx, ly); else sprintf(infotext, "%s: %d, %d", text, ABS(lx - start_lx) + 1, ABS(ly - start_ly) + 1); -#else - if (actual_drawing_function == GADGET_ID_PICK_ELEMENT) - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, - "%s: %d, %d", infotext, lx, ly); - else - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, - "%s: %d, %d", infotext, - ABS(lx - start_lx) + 1, ABS(ly - start_ly) + 1); -#endif } -#if 1 else if (actual_drawing_function == GADGET_ID_PICK_ELEMENT) strncpy(infotext, getElementInfoText(Feld[lx][ly]), max_infotext_len); else sprintf(infotext, "Level position: %d, %d", lx, ly); -#else - else if (actual_drawing_function == GADGET_ID_PICK_ELEMENT) - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, - "%s", getElementInfoText(Feld[lx][ly])); - else - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, - "Level position: %d, %d", lx, ly); -#endif } /* misuse this function to draw brush cursor, if needed */ @@ -9695,67 +10135,29 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) } else if (actual_drawing_function == GADGET_ID_PICK_ELEMENT) { - int element = EL_EMPTY; - - if (id == GADGET_ID_AMOEBA_CONTENT) - element = level.amoeba_content; - else if (id == GADGET_ID_CUSTOM_GRAPHIC) - element = custom_element.gfx_element; - else if (id == GADGET_ID_CUSTOM_CONTENT) - element = custom_element.content[sx][sy]; - else if (id == GADGET_ID_CUSTOM_MOVE_ENTER) - element = custom_element.move_enter_element; - else if (id == GADGET_ID_CUSTOM_MOVE_LEAVE) - element = custom_element.move_leave_element; - else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET) - element = custom_element_change.target_element; - else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT) - element = custom_element_change.target_content[sx][sy]; - else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) - element = custom_element_change.trigger_element; - else if (id == GADGET_ID_GROUP_CONTENT) - element = group_element_info.element[sx]; - else if (id == GADGET_ID_RANDOM_BACKGROUND) - element = random_placement_background_element; - else if (id >= GADGET_ID_YAMYAM_CONTENT_0 && - id <= GADGET_ID_YAMYAM_CONTENT_7) - element = level.yamyam_content[id - GADGET_ID_YAMYAM_CONTENT_0][sx][sy]; - else if (id >= GADGET_ID_MAGIC_BALL_CONTENT_0 && - id <= GADGET_ID_MAGIC_BALL_CONTENT_7) - element = level.ball_content[id -GADGET_ID_MAGIC_BALL_CONTENT_0][sx][sy]; + int pos = sx * drawingarea_info[type_id].area_ysize + sy; + int element = drawingarea_info[type_id].value[pos]; strncpy(infotext, getElementInfoText(element), max_infotext_len); } else { - if (id == GADGET_ID_AMOEBA_CONTENT) - strcpy(infotext, "Amoeba content"); - else if (id == GADGET_ID_CUSTOM_GRAPHIC) - strcpy(infotext, "Custom graphic element"); - else if (id == GADGET_ID_CUSTOM_CONTENT) - sprintf(infotext, "Custom element content position: %d, %d", sx, sy); - else if (id == GADGET_ID_CUSTOM_MOVE_ENTER) - strcpy(infotext, "Element that can be digged/collected"); - else if (id == GADGET_ID_CUSTOM_MOVE_LEAVE) - strcpy(infotext, "Element that will be left behind"); - else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET) - strcpy(infotext, "New element after change"); - else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT) - strcpy(infotext, "New extended elements after change"); - else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER) - strcpy(infotext, "Other element triggering change"); + if (id == GADGET_ID_CUSTOM_CONTENT) + sprintf(infotext, "custom element content position: %d, %d", sx, sy); else if (id == GADGET_ID_GROUP_CONTENT) - sprintf(infotext, "Group element position: %d", sx + 1); - else if (id == GADGET_ID_RANDOM_BACKGROUND) - strcpy(infotext, "Random placement background"); + sprintf(infotext, "group element position: %d", sx + 1); else if (id >= GADGET_ID_YAMYAM_CONTENT_0 && id <= GADGET_ID_YAMYAM_CONTENT_7) - sprintf(infotext, "Content area %d position: %d, %d", + sprintf(infotext, "content area %d position: %d, %d", id - GADGET_ID_YAMYAM_CONTENT_0 + 1, sx, sy); else if (id >= GADGET_ID_MAGIC_BALL_CONTENT_0 && id <= GADGET_ID_MAGIC_BALL_CONTENT_7) - sprintf(infotext, "Content area %d position: %d, %d", + sprintf(infotext, "content area %d position: %d, %d", id - GADGET_ID_MAGIC_BALL_CONTENT_0 + 1, sx, sy); + else if (id == GADGET_ID_ANDROID_CONTENT) + sprintf(infotext, "android element position: %d", sx + 1); + else if (drawingarea_info[type_id].infotext != NULL) + strcpy(infotext, drawingarea_info[type_id].infotext); } infotext[max_infotext_len] = '\0'; diff --git a/src/events.c b/src/events.c index debb368b..410c34c2 100644 --- a/src/events.c +++ b/src/events.c @@ -104,10 +104,8 @@ static boolean NextValidEvent(Event *event) if (FilterMouseMotionEvents(event)) handle_this_event = TRUE; -#if 1 if (SkipPressedMouseMotionEvent(event)) handle_this_event = FALSE; -#endif if (handle_this_event) return TRUE; @@ -322,11 +320,6 @@ void HandleButtonEvent(ButtonEvent *event) else button_status = MB_RELEASED; -#if 0 - printf("::: button %s\n", event->type == EVENT_BUTTONPRESS ? - "pressed" : "released"); -#endif - HandleButton(event->x, event->y, button_status); } @@ -335,17 +328,11 @@ void HandleMotionEvent(MotionEvent *event) if (!PointerInWindow(window)) return; /* window and pointer are on different screens */ -#if 1 if (button_status == MB_RELEASED && game_status != GAME_MODE_EDITOR) return; -#endif motion_status = TRUE; -#if 0 - printf("::: %d, %d\n", event->x, event->y); -#endif - HandleButton(event->x, event->y, button_status); } @@ -448,6 +435,7 @@ void HandleButton(int mx, int my, int button) break; case GAME_MODE_EDITOR: + HandleLevelEditorIdle(); break; case GAME_MODE_INFO: @@ -696,19 +684,7 @@ void HandleKey(Key key, int key_status) if (game_status == GAME_MODE_MAIN && key == setup.shortcut.toggle_pause) { - if (setup.autorecord) - TapeStartRecording(); - -#if defined(NETWORK_AVALIABLE) - if (options.network) - SendToServer_StartPlaying(); - else -#endif - { - game_status = GAME_MODE_PLAYING; - StopAnimation(); - InitGame(); - } + StartGameActions(options.network, setup.autorecord, NEW_RANDOMIZE); return; } @@ -880,32 +856,6 @@ void HandleKey(Key key, int key_status) } break; -#if 0 - case KSYM_a: - if (ScrollStepSize == TILEX/8) - ScrollStepSize = TILEX/4; - else - ScrollStepSize = TILEX/8; - printf("ScrollStepSize == %d\n", ScrollStepSize); - break; -#endif - -#if 0 - case KSYM_m: - if (MoveSpeed == 8) - { - MoveSpeed = 4; - ScrollStepSize = TILEX/4; - } - else - { - MoveSpeed = 8; - ScrollStepSize = TILEX/8; - } - printf("MoveSpeed == %d\n", MoveSpeed); - break; -#endif - case KSYM_f: ScrollStepSize = TILEX/8; printf("ScrollStepSize == %d (1/8)\n", ScrollStepSize); @@ -930,26 +880,6 @@ void HandleKey(Key key, int key_status) printf("::: currently using game engine version %d\n", game.engine_version); break; - -#if 0 - - case KSYM_z: - { - int i; - - for (i = 0; i < MAX_PLAYERS; i++) - { - printf("Player %d:\n", i); - printf(" jx == %d, jy == %d\n", - stored_player[i].jx, stored_player[i].jy); - printf(" last_jx == %d, last_jy == %d\n", - stored_player[i].last_jx, stored_player[i].last_jy); - } - printf("\n"); - } - - break; -#endif #endif default: diff --git a/src/files.c b/src/files.c index 93ab6bc8..39ecf24b 100644 --- a/src/files.c +++ b/src/files.c @@ -40,14 +40,338 @@ #define TAPE_HEADER_SIZE 20 /* size of tape file header */ #define TAPE_HEADER_UNUSED 3 /* unused tape header bytes */ -#define LEVEL_CHUNK_CNT3_SIZE(x) (LEVEL_CHUNK_CNT3_HEADER + (x)) -#define LEVEL_CHUNK_CUS3_SIZE(x) (2 + (x) * LEVEL_CPART_CUS3_SIZE) -#define LEVEL_CHUNK_CUS4_SIZE(x) (48 + 48 + (x) * 48) +#define LEVEL_CHUNK_CNT3_SIZE(x) (LEVEL_CHUNK_CNT3_HEADER + (x)) +#define LEVEL_CHUNK_CUS3_SIZE(x) (2 + (x) * LEVEL_CPART_CUS3_SIZE) +#define LEVEL_CHUNK_CUS4_SIZE(x) (96 + (x) * 48) /* file identifier strings */ -#define LEVEL_COOKIE_TMPL "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_x.x" -#define TAPE_COOKIE_TMPL "ROCKSNDIAMONDS_TAPE_FILE_VERSION_x.x" -#define SCORE_COOKIE "ROCKSNDIAMONDS_SCORE_FILE_VERSION_1.2" +#define LEVEL_COOKIE_TMPL "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_x.x" +#define TAPE_COOKIE_TMPL "ROCKSNDIAMONDS_TAPE_FILE_VERSION_x.x" +#define SCORE_COOKIE "ROCKSNDIAMONDS_SCORE_FILE_VERSION_1.2" + +/* values for "CONF" chunk */ +#define CONF_MASK_1_BYTE 0x00 +#define CONF_MASK_2_BYTE 0x40 +#define CONF_MASK_4_BYTE 0x80 +#define CONF_MASK_MULTI_BYTES 0xc0 + +#define CONF_MASK_BYTES 0xc0 +#define CONF_MASK_TOKEN 0x3f + +#define CONF_LAST_ENTRY (CONF_MASK_1_BYTE | 0) + +#define CONF_VALUE_INTEGER_1 (CONF_MASK_1_BYTE | 1) +#define CONF_VALUE_INTEGER_2 (CONF_MASK_1_BYTE | 2) +#define CONF_VALUE_INTEGER_3 (CONF_MASK_1_BYTE | 3) +#define CONF_VALUE_INTEGER_4 (CONF_MASK_1_BYTE | 4) +#define CONF_VALUE_INTEGER_5 (CONF_MASK_1_BYTE | 5) +#define CONF_VALUE_INTEGER_6 (CONF_MASK_1_BYTE | 6) +#define CONF_VALUE_INTEGER_7 (CONF_MASK_1_BYTE | 7) +#define CONF_VALUE_INTEGER_8 (CONF_MASK_1_BYTE | 8) +#define CONF_VALUE_BOOLEAN_1 (CONF_MASK_1_BYTE | 9) +#define CONF_VALUE_BOOLEAN_2 (CONF_MASK_1_BYTE | 10) +#define CONF_VALUE_BOOLEAN_3 (CONF_MASK_1_BYTE | 11) +#define CONF_VALUE_BOOLEAN_4 (CONF_MASK_1_BYTE | 12) +#define CONF_VALUE_BOOLEAN_5 (CONF_MASK_1_BYTE | 13) +#define CONF_VALUE_BOOLEAN_6 (CONF_MASK_1_BYTE | 14) +#define CONF_VALUE_BOOLEAN_7 (CONF_MASK_1_BYTE | 15) +#define CONF_VALUE_BOOLEAN_8 (CONF_MASK_1_BYTE | 16) + +#define CONF_VALUE_ELEMENT_1 (CONF_MASK_2_BYTE | 1) +#define CONF_VALUE_ELEMENT_2 (CONF_MASK_2_BYTE | 2) +#define CONF_VALUE_ELEMENT_3 (CONF_MASK_2_BYTE | 3) +#define CONF_VALUE_ELEMENT_4 (CONF_MASK_2_BYTE | 4) +#define CONF_VALUE_ELEMENT_5 (CONF_MASK_2_BYTE | 5) +#define CONF_VALUE_ELEMENT_6 (CONF_MASK_2_BYTE | 6) +#define CONF_VALUE_ELEMENT_7 (CONF_MASK_2_BYTE | 7) +#define CONF_VALUE_ELEMENT_8 (CONF_MASK_2_BYTE | 8) + +#define CONF_VALUE_ELEMENTS (CONF_MASK_MULTI_BYTES | 1) +#define CONF_VALUE_CONTENTS (CONF_MASK_MULTI_BYTES | 2) + +#define CONF_VALUE_INTEGER(x) ((x) >= CONF_VALUE_INTEGER_1 && \ + (x) <= CONF_VALUE_INTEGER_8) + +#define CONF_VALUE_BOOLEAN(x) ((x) >= CONF_VALUE_BOOLEAN_1 && \ + (x) <= CONF_VALUE_BOOLEAN_8) + +#define CONF_VALUE_NUM_BYTES(x) ((x) == CONF_MASK_1_BYTE ? 1 : \ + (x) == CONF_MASK_2_BYTE ? 2 : \ + (x) == CONF_MASK_4_BYTE ? 4 : 0) + +#define CONF_CONTENT_NUM_ELEMENTS (3 * 3) +#define CONF_CONTENT_NUM_BYTES (CONF_CONTENT_NUM_ELEMENTS * 2) +#define CONF_ELEMENT_NUM_BYTES (2) + +#define CONF_ENTITY_NUM_BYTES(t) ((t) == CONF_VALUE_ELEMENTS ? \ + CONF_ELEMENT_NUM_BYTES : \ + (t) == CONF_VALUE_CONTENTS ? \ + CONF_CONTENT_NUM_BYTES : 1) + +#define CONF_ELEMENT_BYTE_POS(i) ((i) * CONF_ELEMENT_NUM_BYTES) +#define CONF_ELEMENTS_ELEMENT(b,i) ((b[CONF_ELEMENT_BYTE_POS(i)] << 8) | \ + (b[CONF_ELEMENT_BYTE_POS(i) + 1])) + +#define CONF_CONTENT_ELEMENT_POS(c,x,y) ((c) * CONF_CONTENT_NUM_ELEMENTS + \ + (y) * 3 + (x)) +#define CONF_CONTENT_BYTE_POS(c,x,y) (CONF_CONTENT_ELEMENT_POS(c,x,y) * \ + CONF_ELEMENT_NUM_BYTES) +#define CONF_CONTENTS_ELEMENT(b,c,x,y) ((b[CONF_CONTENT_BYTE_POS(c,x,y)]<< 8)|\ + (b[CONF_CONTENT_BYTE_POS(c,x,y) + 1])) + +static struct LevelInfo li; + +static struct +{ + int element; /* element for which data is to be stored */ + int type; /* type of data to be stored */ + + /* (mandatory) */ + void *value; /* variable that holds the data to be stored */ + int default_value; /* initial default value for this variable */ + + /* (optional) */ + void *num_entities; /* number of entities for multi-byte data */ + int default_num_entities; /* default number of entities for this data */ + int max_num_entities; /* maximal number of entities for this data */ +} element_conf[] = +{ + /* ---------- 1-byte values ---------------------------------------------- */ + + { + EL_EMC_ANDROID, CONF_VALUE_INTEGER_1, + &li.android_move_time, 10 + }, + { + EL_EMC_ANDROID, CONF_VALUE_INTEGER_2, + &li.android_clone_time, 10 + }, + { + EL_EMC_LENSES, CONF_VALUE_INTEGER_1, + &li.lenses_score, 10 + }, + { + EL_EMC_LENSES, CONF_VALUE_INTEGER_2, + &li.lenses_time, 10 + }, + { + EL_EMC_MAGNIFIER, CONF_VALUE_INTEGER_1, + &li.magnify_score, 10 + }, + { + EL_EMC_MAGNIFIER, CONF_VALUE_INTEGER_2, + &li.magnify_time, 10 + }, + { + EL_ROBOT, CONF_VALUE_INTEGER_1, + &li.slurp_score, 10 + }, + { + EL_GAME_OF_LIFE, CONF_VALUE_INTEGER_1, + &li.game_of_life[0], 2 + }, + { + EL_GAME_OF_LIFE, CONF_VALUE_INTEGER_2, + &li.game_of_life[1], 3 + }, + { + EL_GAME_OF_LIFE, CONF_VALUE_INTEGER_3, + &li.game_of_life[2], 3 + }, + { + EL_GAME_OF_LIFE, CONF_VALUE_INTEGER_4, + &li.game_of_life[3], 3 + }, + { + EL_BIOMAZE, CONF_VALUE_INTEGER_1, + &li.biomaze[0], 2 + }, + { + EL_BIOMAZE, CONF_VALUE_INTEGER_2, + &li.biomaze[1], 3 + }, + { + EL_BIOMAZE, CONF_VALUE_INTEGER_3, + &li.biomaze[2], 3 + }, + { + EL_BIOMAZE, CONF_VALUE_INTEGER_4, + &li.biomaze[3], 3 + }, + { + EL_BALLOON, CONF_VALUE_INTEGER_1, + &li.wind_direction_initial, MV_NONE + }, + { + EL_TIMEGATE_SWITCH, CONF_VALUE_INTEGER_1, + &li.time_timegate, 10 + }, + { + EL_LIGHT_SWITCH_ACTIVE, CONF_VALUE_INTEGER_1, + &li.time_light, 10 + }, + { + EL_SHIELD_NORMAL, CONF_VALUE_INTEGER_1, + &li.shield_normal_time, 10 + }, + { + EL_SHIELD_DEADLY, CONF_VALUE_INTEGER_1, + &li.shield_deadly_time, 10 + }, + { + EL_EXTRA_TIME, CONF_VALUE_INTEGER_1, + &li.extra_time, 10 + }, + { + EL_EXTRA_TIME, CONF_VALUE_INTEGER_2, + &li.extra_time_score, 10 + }, + { + EL_TIME_ORB_FULL, CONF_VALUE_INTEGER_1, + &li.time_orb_time, 10 + }, + { + EL_TIME_ORB_FULL, CONF_VALUE_BOOLEAN_1, + &li.use_time_orb_bug, FALSE + }, + { + EL_PLAYER_1, CONF_VALUE_BOOLEAN_1, + &li.block_snap_field, TRUE + }, + { + EL_PLAYER_1, CONF_VALUE_BOOLEAN_2, + &li.use_start_element[0], FALSE + }, + { + EL_PLAYER_2, CONF_VALUE_BOOLEAN_2, + &li.use_start_element[1], FALSE + }, + { + EL_PLAYER_3, CONF_VALUE_BOOLEAN_2, + &li.use_start_element[2], FALSE + }, + { + EL_PLAYER_4, CONF_VALUE_BOOLEAN_2, + &li.use_start_element[3], FALSE + }, + { + EL_PLAYER_1, CONF_VALUE_BOOLEAN_3, + &li.use_artwork_element[0], FALSE + }, + { + EL_PLAYER_2, CONF_VALUE_BOOLEAN_3, + &li.use_artwork_element[1], FALSE + }, + { + EL_PLAYER_3, CONF_VALUE_BOOLEAN_3, + &li.use_artwork_element[2], FALSE + }, + { + EL_PLAYER_4, CONF_VALUE_BOOLEAN_3, + &li.use_artwork_element[3], FALSE + }, + { + EL_PLAYER_1, CONF_VALUE_BOOLEAN_4, + &li.use_explosion_element[0], FALSE + }, + { + EL_PLAYER_2, CONF_VALUE_BOOLEAN_4, + &li.use_explosion_element[1], FALSE + }, + { + EL_PLAYER_3, CONF_VALUE_BOOLEAN_4, + &li.use_explosion_element[2], FALSE + }, + { + EL_PLAYER_4, CONF_VALUE_BOOLEAN_4, + &li.use_explosion_element[3], FALSE + }, + { + EL_PLAYER_1, CONF_VALUE_INTEGER_1, + &li.initial_player_stepsize, STEPSIZE_NORMAL + }, + { + EL_EMC_MAGIC_BALL, CONF_VALUE_INTEGER_1, + &li.ball_time, 10 + }, + { + EL_EMC_MAGIC_BALL, CONF_VALUE_BOOLEAN_1, + &li.ball_random, FALSE + }, + { + EL_EMC_MAGIC_BALL, CONF_VALUE_BOOLEAN_2, + &li.ball_state_initial, FALSE + }, + + /* ---------- 2-byte values ---------------------------------------------- */ + + { + EL_PLAYER_1, CONF_VALUE_ELEMENT_1, + &li.start_element[0], EL_PLAYER_1 + }, + { + EL_PLAYER_2, CONF_VALUE_ELEMENT_1, + &li.start_element[1], EL_PLAYER_2 + }, + { + EL_PLAYER_3, CONF_VALUE_ELEMENT_1, + &li.start_element[2], EL_PLAYER_3 + }, + { + EL_PLAYER_4, CONF_VALUE_ELEMENT_1, + &li.start_element[3], EL_PLAYER_4 + }, + { + EL_PLAYER_1, CONF_VALUE_ELEMENT_2, + &li.artwork_element[0], EL_PLAYER_1 + }, + { + EL_PLAYER_2, CONF_VALUE_ELEMENT_2, + &li.artwork_element[1], EL_PLAYER_2 + }, + { + EL_PLAYER_3, CONF_VALUE_ELEMENT_2, + &li.artwork_element[2], EL_PLAYER_3 + }, + { + EL_PLAYER_4, CONF_VALUE_ELEMENT_2, + &li.artwork_element[3], EL_PLAYER_4 + }, + { + EL_PLAYER_1, CONF_VALUE_ELEMENT_3, + &li.explosion_element[0], EL_PLAYER_1 + }, + { + EL_PLAYER_2, CONF_VALUE_ELEMENT_3, + &li.explosion_element[1], EL_PLAYER_2 + }, + { + EL_PLAYER_3, CONF_VALUE_ELEMENT_3, + &li.explosion_element[2], EL_PLAYER_3 + }, + { + EL_PLAYER_4, CONF_VALUE_ELEMENT_3, + &li.explosion_element[3], EL_PLAYER_4 + }, + + /* ---------- multi-byte values ------------------------------------------ */ + + { + EL_EMC_MAGIC_BALL, CONF_VALUE_CONTENTS, + &li.ball_content, EL_EMPTY, + &li.num_ball_contents, 4, MAX_ELEMENT_CONTENTS + }, + { + EL_EMC_ANDROID, CONF_VALUE_ELEMENTS, + &li.android_clone_element[0], EL_EMPTY, + &li.num_android_clone_elements, 1, MAX_ANDROID_ELEMENTS + }, + + { + -1, -1, + NULL, -1, + }, +}; static struct { @@ -71,6 +395,56 @@ filetype_id_list[] = /* level file functions */ /* ========================================================================= */ +static void setLevelInfoToDefaultsFromConfigList(struct LevelInfo *level) +{ + int i; + + li = *level; /* copy level information into temporary buffer */ + + for (i = 0; element_conf[i].element != -1; i++) + { + int default_value = element_conf[i].default_value; + int type = element_conf[i].type; + int bytes = type & CONF_MASK_BYTES; + + if (bytes == CONF_MASK_MULTI_BYTES) + { + int default_num_entities = element_conf[i].default_num_entities; + int max_num_entities = element_conf[i].max_num_entities; + + *(int *)(element_conf[i].num_entities) = default_num_entities; + + if (type == CONF_VALUE_ELEMENTS) + { + int *element_array = (int *)(element_conf[i].value); + int j; + + for (j = 0; j < max_num_entities; j++) + element_array[j] = default_value; + } + else if (type == CONF_VALUE_CONTENTS) + { + struct Content *content = (struct Content *)(element_conf[i].value); + int c, x, y; + + for (c = 0; c < max_num_entities; c++) + for (y = 0; y < 3; y++) + for (x = 0; x < 3; x++) + content[c].e[x][y] = default_value; + } + } + else /* constant size configuration data (1, 2 or 4 bytes) */ + { + if (CONF_VALUE_BOOLEAN(type)) + *(boolean *)(element_conf[i].value) = default_value; + else + *(int *) (element_conf[i].value) = default_value; + } + } + + *level = li; /* copy temporary buffer back to level information */ +} + void setElementChangePages(struct ElementInfo *ei, int change_pages) { int change_page_size = sizeof(struct ElementChangeInfo); @@ -103,7 +477,7 @@ void setElementChangeInfoToDefaults(struct ElementChangeInfo *change) change->delay_fixed = 0; change->delay_random = 0; - change->delay_frames = 1; + change->delay_frames = FRAMES_PER_SECOND; change->trigger_element = EL_EMPTY_SPACE; @@ -114,9 +488,14 @@ void setElementChangeInfoToDefaults(struct ElementChangeInfo *change) change->random_percentage = 100; change->replace_when = CP_WHEN_EMPTY; + change->has_action = FALSE; + change->action_type = CA_NO_ACTION; + change->action_mode = CA_MODE_UNDEFINED; + change->action_arg = CA_ARG_UNDEFINED; + for (x = 0; x < 3; x++) for (y = 0; y < 3; y++) - change->target_content[x][y] = EL_EMPTY_SPACE; + change->target_content.e[x][y] = EL_EMPTY_SPACE; change->direct_action = 0; change->other_action = 0; @@ -131,6 +510,11 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) static boolean clipboard_elements_initialized = FALSE; int i, j, x, y; +#if 1 + InitElementPropertiesStatic(); +#endif + + setLevelInfoToDefaultsFromConfigList(level); setLevelInfoToDefaults_EM(); level->native_em_level = &native_em_level; @@ -158,50 +542,67 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) level->time_magic_wall = 10; level->time_wheel = 10; +#if 0 level->time_light = 10; level->time_timegate = 10; +#endif level->amoeba_content = EL_DIAMOND; + level->game_of_life[0] = 2; + level->game_of_life[1] = 3; + level->game_of_life[2] = 3; + level->game_of_life[3] = 3; + + level->biomaze[0] = 2; + level->biomaze[1] = 3; + level->biomaze[2] = 3; + level->biomaze[3] = 3; + +#if 0 level->double_speed = FALSE; +#endif level->initial_gravity = FALSE; level->em_slippery_gems = FALSE; level->instant_relocation = FALSE; level->can_pass_to_walkable = FALSE; level->grow_into_diggable = TRUE; + level->block_snap_field = TRUE; + level->block_last_field = FALSE; /* EM does not block by default */ level->sp_block_last_field = TRUE; /* SP blocks the last field */ -#if 0 /* !!! THIS IS NOT A LEVEL SETTING => LOGIC MOVED TO "game.c" !!! */ - level->block_delay = 8; /* when blocking, block 8 frames */ - level->sp_block_delay = 9; /* SP indeed blocks 9 frames, not 8 */ -#endif - level->can_move_into_acid_bits = ~0; /* everything can move into acid */ level->dont_collide_with_bits = ~0; /* always deadly when colliding */ level->use_spring_bug = FALSE; + level->use_time_orb_bug = FALSE; + level->use_step_counter = FALSE; /* values for the new EMC elements */ +#if 0 level->android_move_time = 10; level->android_clone_time = 10; - level->ball_random = FALSE; - level->ball_state_initial = FALSE; level->ball_time = 10; level->lenses_score = 10; - level->magnify_score = 10; - level->slurp_score = 10; level->lenses_time = 10; + level->magnify_score = 10; level->magnify_time = 10; - level->wind_direction_initial = MV_NO_MOVING; - for (i = 0; i < NUM_MAGIC_BALL_CONTENTS; i++) + level->slurp_score = 10; + level->wind_direction_initial = MV_NONE; + level->ball_random = FALSE; + level->ball_state_initial = FALSE; + for (i = 0; i < MAX_ELEMENT_CONTENTS; i++) for (x = 0; x < 3; x++) for (y = 0; y < 3; y++) - level->ball_content[i][x][y] = EL_EMPTY; + level->ball_content[i].e[x][y] = EL_EMPTY; +#endif +#if 0 for (i = 0; i < 16; i++) level->android_array[i] = FALSE; +#endif level->use_custom_template = FALSE; @@ -221,13 +622,13 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) } for (i = 0; i < LEVEL_SCORE_ELEMENTS; i++) - level->score[i] = 10; + level->score[i] = (i == SC_TIME_BONUS ? 1 : 10); level->num_yamyam_contents = STD_ELEMENT_CONTENTS; for (i = 0; i < MAX_ELEMENT_CONTENTS; i++) for (x = 0; x < 3; x++) for (y = 0; y < 3; y++) - level->yamyam_content[i][x][y] = + level->yamyam_content[i].e[x][y] = (i < STD_ELEMENT_CONTENTS ? EL_ROCK : EL_EMPTY); level->field[0][0] = EL_PLAYER_1; @@ -236,83 +637,90 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) for (i = 0; i < MAX_NUM_ELEMENTS; i++) { int element = i; + struct ElementInfo *ei = &element_info[element]; /* never initialize clipboard elements after the very first time */ if (IS_CLIPBOARD_ELEMENT(element) && clipboard_elements_initialized) continue; - setElementChangePages(&element_info[element], 1); - setElementChangeInfoToDefaults(element_info[element].change); + setElementChangePages(ei, 1); + setElementChangeInfoToDefaults(ei->change); if (IS_CUSTOM_ELEMENT(element) || IS_GROUP_ELEMENT(element) || IS_INTERNAL_ELEMENT(element)) { for (j = 0; j < MAX_ELEMENT_NAME_LEN + 1; j++) - element_info[element].description[j] = '\0'; + ei->description[j] = '\0'; - if (element_info[element].custom_description != NULL) - strncpy(element_info[element].description, - element_info[element].custom_description,MAX_ELEMENT_NAME_LEN); + if (ei->custom_description != NULL) + strncpy(ei->description, ei->custom_description,MAX_ELEMENT_NAME_LEN); else - strcpy(element_info[element].description, - element_info[element].editor_description); + strcpy(ei->description, ei->editor_description); - element_info[element].use_gfx_element = FALSE; - element_info[element].gfx_element = EL_EMPTY_SPACE; + ei->use_gfx_element = FALSE; + ei->gfx_element = EL_EMPTY_SPACE; - element_info[element].modified_settings = FALSE; + ei->modified_settings = FALSE; } if (IS_CUSTOM_ELEMENT(element) || IS_INTERNAL_ELEMENT(element)) { - element_info[element].access_direction = MV_ALL_DIRECTIONS; + ei->access_direction = MV_ALL_DIRECTIONS; + + ei->collect_score_initial = 10; /* special default */ + ei->collect_count_initial = 1; /* special default */ - element_info[element].collect_score = 10; /* special default */ - element_info[element].collect_count = 1; /* special default */ + ei->ce_value_fixed_initial = 0; + ei->ce_value_random_initial = 0; + ei->use_last_ce_value = FALSE; - element_info[element].push_delay_fixed = -1; /* initialize later */ - element_info[element].push_delay_random = -1; /* initialize later */ - element_info[element].drop_delay_fixed = 0; - element_info[element].drop_delay_random = 0; - element_info[element].move_delay_fixed = 0; - element_info[element].move_delay_random = 0; + ei->push_delay_fixed = -1; /* initialize later */ + ei->push_delay_random = -1; /* initialize later */ + ei->drop_delay_fixed = 0; + ei->drop_delay_random = 0; + ei->move_delay_fixed = 0; + ei->move_delay_random = 0; - element_info[element].move_pattern = MV_ALL_DIRECTIONS; - element_info[element].move_direction_initial = MV_START_AUTOMATIC; - element_info[element].move_stepsize = TILEX / 8; + ei->move_pattern = MV_ALL_DIRECTIONS; + ei->move_direction_initial = MV_START_AUTOMATIC; + ei->move_stepsize = TILEX / 8; - element_info[element].move_enter_element = EL_EMPTY_SPACE; - element_info[element].move_leave_element = EL_EMPTY_SPACE; - element_info[element].move_leave_type = LEAVE_TYPE_UNLIMITED; + ei->move_enter_element = EL_EMPTY_SPACE; + ei->move_leave_element = EL_EMPTY_SPACE; + ei->move_leave_type = LEAVE_TYPE_UNLIMITED; - element_info[element].slippery_type = SLIPPERY_ANY_RANDOM; + ei->slippery_type = SLIPPERY_ANY_RANDOM; - element_info[element].explosion_type = EXPLODES_3X3; - element_info[element].explosion_delay = 16; - element_info[element].ignition_delay = 8; + ei->explosion_type = EXPLODES_3X3; + ei->explosion_delay = 16; + ei->ignition_delay = 8; for (x = 0; x < 3; x++) for (y = 0; y < 3; y++) - element_info[element].content[x][y] = EL_EMPTY_SPACE; + ei->content.e[x][y] = EL_EMPTY_SPACE; - element_info[element].access_type = 0; - element_info[element].access_layer = 0; - element_info[element].access_protected = 0; - element_info[element].walk_to_action = 0; - element_info[element].smash_targets = 0; - element_info[element].deadliness = 0; + ei->access_type = 0; + ei->access_layer = 0; + ei->access_protected = 0; + ei->walk_to_action = 0; + ei->smash_targets = 0; + ei->deadliness = 0; - element_info[element].can_explode_by_fire = FALSE; - element_info[element].can_explode_smashed = FALSE; - element_info[element].can_explode_impact = FALSE; + ei->can_explode_by_fire = FALSE; + ei->can_explode_smashed = FALSE; + ei->can_explode_impact = FALSE; - element_info[element].current_change_page = 0; + ei->current_change_page = 0; +#if 0 + /* !!! now done in InitElementPropertiesStatic() (see above) !!! */ + /* !!! (else properties set there will be overwritten here) !!! */ /* start with no properties at all */ for (j = 0; j < NUM_EP_BITFIELDS; j++) Properties[element][j] = EP_BITMASK_DEFAULT; +#endif /* now set default properties */ SET_PROPERTY(element, EP_CAN_MOVE_INTO_ACID, TRUE); @@ -321,18 +729,21 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) if (IS_GROUP_ELEMENT(element) || IS_INTERNAL_ELEMENT(element)) { + struct ElementGroupInfo *group; + /* initialize memory for list of elements in group */ - if (element_info[element].group == NULL) - element_info[element].group = - checked_malloc(sizeof(struct ElementGroupInfo)); + if (ei->group == NULL) + ei->group = checked_malloc(sizeof(struct ElementGroupInfo)); + + group = ei->group; for (j = 0; j < MAX_ELEMENTS_IN_GROUP; j++) - element_info[element].group->element[j] = EL_EMPTY_SPACE; + group->element[j] = EL_EMPTY_SPACE; /* default: only one element in group */ - element_info[element].group->num_elements = 1; + group->num_elements = 1; - element_info[element].group->choice_mode = ANIM_RANDOM; + group->choice_mode = ANIM_RANDOM; } } @@ -564,48 +975,6 @@ static int getFiletypeFromID(char *filetype_id) return filetype; } -#if 0 -static void OLD_determineLevelFileInfo_Filename(struct LevelFileInfo *lfi) -{ - /* special case: level number is negative => check for level template file */ - if (lfi->nr < 0) - { - setLevelFileInfo_SingleLevelFilename(lfi, LEVEL_FILE_TYPE_RND); - - return; - } - - if (leveldir_current->level_filename != NULL) - { - int filetype = getFiletypeFromID(leveldir_current->level_filetype); - - /* check for file name/pattern specified in "levelinfo.conf" */ - setLevelFileInfo_SingleLevelFilename(lfi, filetype); - - if (fileExists(lfi->filename)) - return; - } - - /* check for native Rocks'n'Diamonds level file */ - setLevelFileInfo_SingleLevelFilename(lfi, LEVEL_FILE_TYPE_RND); - if (fileExists(lfi->filename)) - return; - - /* check for classic Emerald Mine level file */ - setLevelFileInfo_SingleLevelFilename(lfi, LEVEL_FILE_TYPE_EM); - if (fileExists(lfi->filename)) - return; - - /* check for various packed level file formats */ - setLevelFileInfo_PackedLevelFilename(lfi, LEVEL_FILE_TYPE_UNKNOWN); - if (fileExists(lfi->filename)) - return; - - /* no known level file found -- try to use default values */ - setLevelFileInfo_SingleLevelFilename(lfi, LEVEL_FILE_TYPE_UNKNOWN); -} -#endif - static void determineLevelFileInfo_Filename(struct LevelFileInfo *lfi) { int nr = lfi->nr; @@ -684,7 +1053,6 @@ static void determineLevelFileInfo_Filetype(struct LevelFileInfo *lfi) lfi->type = getFileTypeFromBasename(lfi->basename); } -#if 1 static void setLevelFileInfo(struct LevelFileInfo *level_file_info, int nr) { /* always start with reliable default values */ @@ -696,24 +1064,6 @@ static void setLevelFileInfo(struct LevelFileInfo *level_file_info, int nr) determineLevelFileInfo_Filetype(level_file_info); } -#else - -static struct LevelFileInfo *getLevelFileInfo(int nr) -{ - static struct LevelFileInfo level_file_info; - - /* always start with reliable default values */ - setFileInfoToDefaults(&level_file_info); - - level_file_info.nr = nr; /* set requested level number */ - - determineLevelFileInfo_Filename(&level_file_info); - determineLevelFileInfo_Filetype(&level_file_info); - - return &level_file_info; -} -#endif - /* ------------------------------------------------------------------------- */ /* functions for loading R'n'D level */ /* ------------------------------------------------------------------------- */ @@ -722,7 +1072,6 @@ int getMappedElement(int element) { /* remap some (historic, now obsolete) elements */ -#if 1 switch (element) { case EL_PLAYER_OBSOLETE: @@ -765,18 +1114,6 @@ int getMappedElement(int element) } break; } -#else - if (element >= NUM_FILE_ELEMENTS) - { - Error(ERR_WARN, "invalid level element %d", element); - - element = EL_UNKNOWN; - } - else if (element == EL_PLAYER_OBSOLETE) - element = EL_PLAYER_1; - else if (element == EL_KEY_OBSOLETE) - element = EL_KEY_1; -#endif return element; } @@ -836,13 +1173,16 @@ static int LoadLevel_HEAD(FILE *file, int chunk_size, struct LevelInfo *level) for (i = 0; i < STD_ELEMENT_CONTENTS; i++) for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - level->yamyam_content[i][x][y] = getMappedElement(getFile8Bit(file)); + level->yamyam_content[i].e[x][y] = getMappedElement(getFile8Bit(file)); level->amoeba_speed = getFile8Bit(file); level->time_magic_wall = getFile8Bit(file); level->time_wheel = getFile8Bit(file); level->amoeba_content = getMappedElement(getFile8Bit(file)); - level->double_speed = (getFile8Bit(file) == 1 ? TRUE : FALSE); + + level->initial_player_stepsize = (getFile8Bit(file) == 1 ? STEPSIZE_FAST : + STEPSIZE_NORMAL); + level->initial_gravity = (getFile8Bit(file) == 1 ? TRUE : FALSE); level->encoding_16bit_field = (getFile8Bit(file) == 1 ? TRUE : FALSE); level->em_slippery_gems = (getFile8Bit(file) == 1 ? TRUE : FALSE); @@ -940,7 +1280,7 @@ static int LoadLevel_CONT(FILE *file, int chunk_size, struct LevelInfo *level) for (i = 0; i < MAX_ELEMENT_CONTENTS; i++) for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - level->yamyam_content[i][x][y] = + level->yamyam_content[i].e[x][y] = getMappedElement(level->encoding_16bit_field ? getFile16BitBE(file) : getFile8Bit(file)); return chunk_size; @@ -976,7 +1316,7 @@ static int LoadLevel_CNT2(FILE *file, int chunk_size, struct LevelInfo *level) for (i = 0; i < num_contents; i++) for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - level->yamyam_content[i][x][y] = content_array[i][x][y]; + level->yamyam_content[i].e[x][y] = content_array[i][x][y]; } else if (element == EL_BD_AMOEBA) { @@ -1091,6 +1431,7 @@ static int LoadLevel_CUS3(FILE *file, int chunk_size, struct LevelInfo *level) for (i = 0; i < num_changed_custom_elements; i++) { int element = getFile16BitBE(file); + struct ElementInfo *ei = &element_info[element]; unsigned long event_bits; if (!IS_CUSTOM_ELEMENT(element)) @@ -1101,70 +1442,66 @@ static int LoadLevel_CUS3(FILE *file, int chunk_size, struct LevelInfo *level) } for (j = 0; j < MAX_ELEMENT_NAME_LEN; j++) - element_info[element].description[j] = getFile8Bit(file); - element_info[element].description[MAX_ELEMENT_NAME_LEN] = 0; + ei->description[j] = getFile8Bit(file); + ei->description[MAX_ELEMENT_NAME_LEN] = 0; Properties[element][EP_BITFIELD_BASE] = getFile32BitBE(file); /* some free bytes for future properties and padding */ ReadUnusedBytesFromFile(file, 7); - element_info[element].use_gfx_element = getFile8Bit(file); - element_info[element].gfx_element = - getMappedElement(getFile16BitBE(file)); + ei->use_gfx_element = getFile8Bit(file); + ei->gfx_element = getMappedElement(getFile16BitBE(file)); - element_info[element].collect_score = getFile8Bit(file); - element_info[element].collect_count = getFile8Bit(file); + ei->collect_score_initial = getFile8Bit(file); + ei->collect_count_initial = getFile8Bit(file); - element_info[element].push_delay_fixed = getFile16BitBE(file); - element_info[element].push_delay_random = getFile16BitBE(file); - element_info[element].move_delay_fixed = getFile16BitBE(file); - element_info[element].move_delay_random = getFile16BitBE(file); + ei->push_delay_fixed = getFile16BitBE(file); + ei->push_delay_random = getFile16BitBE(file); + ei->move_delay_fixed = getFile16BitBE(file); + ei->move_delay_random = getFile16BitBE(file); - element_info[element].move_pattern = getFile16BitBE(file); - element_info[element].move_direction_initial = getFile8Bit(file); - element_info[element].move_stepsize = getFile8Bit(file); + ei->move_pattern = getFile16BitBE(file); + ei->move_direction_initial = getFile8Bit(file); + ei->move_stepsize = getFile8Bit(file); for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - element_info[element].content[x][y] = - getMappedElement(getFile16BitBE(file)); + ei->content.e[x][y] = getMappedElement(getFile16BitBE(file)); event_bits = getFile32BitBE(file); for (j = 0; j < NUM_CHANGE_EVENTS; j++) if (event_bits & (1 << j)) - element_info[element].change->has_event[j] = TRUE; + ei->change->has_event[j] = TRUE; - element_info[element].change->target_element = - getMappedElement(getFile16BitBE(file)); + ei->change->target_element = getMappedElement(getFile16BitBE(file)); - element_info[element].change->delay_fixed = getFile16BitBE(file); - element_info[element].change->delay_random = getFile16BitBE(file); - element_info[element].change->delay_frames = getFile16BitBE(file); + ei->change->delay_fixed = getFile16BitBE(file); + ei->change->delay_random = getFile16BitBE(file); + ei->change->delay_frames = getFile16BitBE(file); - element_info[element].change->trigger_element = - getMappedElement(getFile16BitBE(file)); + ei->change->trigger_element = getMappedElement(getFile16BitBE(file)); - element_info[element].change->explode = getFile8Bit(file); - element_info[element].change->use_target_content = getFile8Bit(file); - element_info[element].change->only_if_complete = getFile8Bit(file); - element_info[element].change->use_random_replace = getFile8Bit(file); + ei->change->explode = getFile8Bit(file); + ei->change->use_target_content = getFile8Bit(file); + ei->change->only_if_complete = getFile8Bit(file); + ei->change->use_random_replace = getFile8Bit(file); - element_info[element].change->random_percentage = getFile8Bit(file); - element_info[element].change->replace_when = getFile8Bit(file); + ei->change->random_percentage = getFile8Bit(file); + ei->change->replace_when = getFile8Bit(file); for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - element_info[element].change->target_content[x][y] = + ei->change->target_content.e[x][y] = getMappedElement(getFile16BitBE(file)); - element_info[element].slippery_type = getFile8Bit(file); + ei->slippery_type = getFile8Bit(file); /* some free bytes for future properties and padding */ ReadUnusedBytesFromFile(file, LEVEL_CPART_CUS3_UNUSED); /* mark that this custom element has been modified */ - element_info[element].modified_settings = TRUE; + ei->modified_settings = TRUE; } return chunk_size; @@ -1177,6 +1514,8 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level) int element; int i, j, x, y; + /* ---------- custom element base property values (96 bytes) ------------- */ + element = getFile16BitBE(file); if (!IS_CUSTOM_ELEMENT(element)) @@ -1198,23 +1537,22 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level) ei->num_change_pages = getFile8Bit(file); - /* some free bytes for future base property values and padding */ - ReadUnusedBytesFromFile(file, 5); - chunk_size_expected = LEVEL_CHUNK_CUS4_SIZE(ei->num_change_pages); if (chunk_size_expected != chunk_size) { - ReadUnusedBytesFromFile(file, chunk_size - 48); + ReadUnusedBytesFromFile(file, chunk_size - 43); return chunk_size_expected; } - /* read custom property values */ + ei->ce_value_fixed_initial = getFile16BitBE(file); + ei->ce_value_random_initial = getFile16BitBE(file); + ei->use_last_ce_value = getFile8Bit(file); ei->use_gfx_element = getFile8Bit(file); ei->gfx_element = getMappedElement(getFile16BitBE(file)); - ei->collect_score = getFile8Bit(file); - ei->collect_count = getFile8Bit(file); + ei->collect_score_initial = getFile8Bit(file); + ei->collect_count_initial = getFile8Bit(file); ei->drop_delay_fixed = getFile8Bit(file); ei->push_delay_fixed = getFile8Bit(file); @@ -1232,7 +1570,7 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level) for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - ei->content[x][y] = getMappedElement(getFile16BitBE(file)); + ei->content.e[x][y] = getMappedElement(getFile16BitBE(file)); ei->move_enter_element = getMappedElement(getFile16BitBE(file)); ei->move_leave_element = getMappedElement(getFile16BitBE(file)); @@ -1250,7 +1588,7 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level) /* some free bytes for future custom property values and padding */ ReadUnusedBytesFromFile(file, 1); - /* read change property values */ + /* ---------- change page property values (48 bytes) --------------------- */ setElementChangePages(ei, ei->num_change_pages); @@ -1262,8 +1600,9 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level) /* always start with reliable default values */ setElementChangeInfoToDefaults(change); + /* bits 0 - 31 of "has_event[]" ... */ event_bits = getFile32BitBE(file); - for (j = 0; j < NUM_CHANGE_EVENTS; j++) + for (j = 0; j < MIN(NUM_CHANGE_EVENTS, 32); j++) if (event_bits & (1 << j)) change->has_event[j] = TRUE; @@ -1285,27 +1624,28 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level) for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - change->target_content[x][y] = getMappedElement(getFile16BitBE(file)); + change->target_content.e[x][y]= getMappedElement(getFile16BitBE(file)); change->can_change = getFile8Bit(file); change->trigger_side = getFile8Bit(file); -#if 1 change->trigger_player = getFile8Bit(file); change->trigger_page = getFile8Bit(file); change->trigger_page = (change->trigger_page == CH_PAGE_ANY_FILE ? CH_PAGE_ANY : (1 << change->trigger_page)); - /* some free bytes for future change property values and padding */ - ReadUnusedBytesFromFile(file, 6); + change->has_action = getFile8Bit(file); + change->action_type = getFile8Bit(file); + change->action_mode = getFile8Bit(file); + change->action_arg = getFile16BitBE(file); -#else - - /* some free bytes for future change property values and padding */ - ReadUnusedBytesFromFile(file, 8); -#endif + /* ... bits 32 - 39 of "has_event[]" (not nice, but downward compatible) */ + event_bits = getFile8Bit(file); + for (j = 32; j < NUM_CHANGE_EVENTS; j++) + if (event_bits & (1 << (j - 32))) + change->has_event[j] = TRUE; } /* mark this custom element as modified */ @@ -1358,6 +1698,118 @@ static int LoadLevel_GRP1(FILE *file, int chunk_size, struct LevelInfo *level) return chunk_size; } +static int LoadLevel_CONF(FILE *file, int chunk_size, struct LevelInfo *level) +{ + int real_chunk_size = 0; + int i; + + while (!feof(file)) + { + int element = getFile16BitBE(file); + int type = getFile8Bit(file); + int bytes = type & CONF_MASK_BYTES; + boolean element_found = FALSE; + + real_chunk_size += 3; + + li = *level; /* copy level information into temporary buffer */ + + if (bytes == CONF_MASK_MULTI_BYTES) + { + int num_bytes = getFile16BitBE(file); + byte *buffer = checked_malloc(num_bytes); + + ReadBytesFromFile(file, buffer, num_bytes); + + for (i = 0; element_conf[i].element != -1; i++) + { + if (element_conf[i].element == element && + element_conf[i].type == type) + { + int num_entities = num_bytes / CONF_ENTITY_NUM_BYTES(type); + int max_num_entities = element_conf[i].max_num_entities; + + if (num_entities > max_num_entities) + { + Error(ERR_WARN, + "truncating number of entities for element %d from %d to %d", + element, num_entities, max_num_entities); + + num_entities = max_num_entities; + } + + *(int *)(element_conf[i].num_entities) = num_entities; + + element_found = TRUE; + + if (type == CONF_VALUE_ELEMENTS) + { + int *element_array = (int *)(element_conf[i].value); + int j; + + for (j = 0; j < num_entities; j++) + element_array[j] = + getMappedElement(CONF_ELEMENTS_ELEMENT(buffer, j)); + } + else if (type == CONF_VALUE_CONTENTS) + { + struct Content *content= (struct Content *)(element_conf[i].value); + int c, x, y; + + for (c = 0; c < num_entities; c++) + for (y = 0; y < 3; y++) + for (x = 0; x < 3; x++) + content[c].e[x][y] = + getMappedElement(CONF_CONTENTS_ELEMENT(buffer, c, x, y)); + } + else + element_found = FALSE; + + break; + } + } + + checked_free(buffer); + + real_chunk_size += 2 + num_bytes; + } + else /* constant size configuration data (1, 2 or 4 bytes) */ + { + int value = (bytes == CONF_MASK_1_BYTE ? getFile8Bit (file) : + bytes == CONF_MASK_2_BYTE ? getFile16BitBE(file) : + bytes == CONF_MASK_4_BYTE ? getFile32BitBE(file) : 0); + + for (i = 0; element_conf[i].element != -1; i++) + { + if (element_conf[i].element == element && + element_conf[i].type == type) + { + if (CONF_VALUE_BOOLEAN(type)) + *(boolean *)(element_conf[i].value) = value; + else + *(int *) (element_conf[i].value) = value; + + element_found = TRUE; + + break; + } + } + + real_chunk_size += CONF_VALUE_NUM_BYTES(bytes); + } + + *level = li; /* copy temporary buffer back to level information */ + + if (!element_found) + Error(ERR_WARN, "cannot load CONF value for element %d", element); + + if (type == CONF_LAST_ENTRY || real_chunk_size >= chunk_size) + break; + } + + return real_chunk_size; +} + static void LoadLevelFromFileInfo_RND(struct LevelInfo *level, struct LevelFileInfo *level_file_info) { @@ -1449,6 +1901,8 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level, { "CUS3", -1, LoadLevel_CUS3 }, { "CUS4", -1, LoadLevel_CUS4 }, { "GRP1", -1, LoadLevel_GRP1 }, + { "CONF", -1, LoadLevel_CONF }, + { NULL, 0, NULL } }; @@ -1891,7 +2345,7 @@ static void OLD_LoadLevelFromFileInfo_EM(struct LevelInfo *level, for (i = 0; i < level->num_yamyam_contents; i++) for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - level->yamyam_content[i][x][y] = + level->yamyam_content[i].e[x][y] = map_em_element_yam(header[i * 9 + y * 3 + x]); level->amoeba_speed = (header[52] * 256 + header[53]) % 256; @@ -1918,7 +2372,7 @@ static void OLD_LoadLevelFromFileInfo_EM(struct LevelInfo *level, level->field[x][y] = EL_PLAYER_2; } -#else +#endif void CopyNativeLevel_RND_to_EM(struct LevelInfo *level) { @@ -1960,7 +2414,7 @@ void CopyNativeLevel_RND_to_EM(struct LevelInfo *level) for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) lev->eater_array[i][y * 3 + x] = - map_element_RND_to_EM(level->yamyam_content[i][x][y]); + map_element_RND_to_EM(level->yamyam_content[i].e[x][y]); lev->amoeba_time = level->amoeba_speed; lev->wonderwall_time_initial = level->time_magic_wall; @@ -1971,6 +2425,7 @@ void CopyNativeLevel_RND_to_EM(struct LevelInfo *level) lev->ball_random = level->ball_random; lev->ball_state_initial = level->ball_state_initial; lev->ball_time = level->ball_time; + lev->num_ball_arrays = level->num_ball_contents; lev->lenses_score = level->lenses_score; lev->magnify_score = level->magnify_score; @@ -1978,16 +2433,24 @@ void CopyNativeLevel_RND_to_EM(struct LevelInfo *level) lev->lenses_time = level->lenses_time; lev->magnify_time = level->magnify_time; - lev->wind_direction_initial = level->wind_direction_initial; - for (i = 0; i < NUM_MAGIC_BALL_CONTENTS; i++) + lev->wind_direction_initial = + map_direction_RND_to_EM(level->wind_direction_initial); + lev->wind_cnt_initial = (level->wind_direction_initial != MV_NONE ? + lev->wind_time : 0); + + for (i = 0; i < MAX_ELEMENT_CONTENTS; i++) for (j = 0; j < 8; j++) lev->ball_array[i][j] = map_element_RND_to_EM(level-> - ball_content[i][ball_xy[j][0]][ball_xy[j][1]]); + ball_content[i].e[ball_xy[j][0]][ball_xy[j][1]]); + + map_android_clone_elements_RND_to_EM(level); +#if 0 for (i = 0; i < 16; i++) lev->android_array[i] = FALSE; /* !!! YET TO COME !!! */ +#endif /* first fill the complete playfield with the default border element */ for (y = 0; y < EM_MAX_CAVE_HEIGHT; y++) @@ -2014,6 +2477,16 @@ void CopyNativeLevel_RND_to_EM(struct LevelInfo *level) /* initialize player positions and delete players from the playfield */ for (y = 0; y < lev->height; y++) for (x = 0; x < lev->width; x++) { +#if 1 + /* !!! CURRENTLY ONLY SUPPORT FOR ONE PLAYER !!! */ + if (ELEM_IS_PLAYER(level->field[x][y])) + { + ply1->x_initial = x + 1; + ply1->y_initial = y + 1; + level_em->cave[x + 1][y + 1] = map_element_RND_to_EM(EL_EMPTY); + } +#else + /* !!! ADD SUPPORT FOR MORE THAN ONE PLAYER !!! */ if (level->field[x][y] == EL_PLAYER_1) { ply1->x_initial = x + 1; @@ -2026,6 +2499,7 @@ void CopyNativeLevel_RND_to_EM(struct LevelInfo *level) ply2->y_initial = y + 1; level_em->cave[x + 1][y + 1] = map_element_RND_to_EM(EL_EMPTY); } +#endif } } @@ -2072,7 +2546,7 @@ void CopyNativeLevel_EM_to_RND(struct LevelInfo *level) for (i = 0; i < level->num_yamyam_contents; i++) for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - level->yamyam_content[i][x][y] = + level->yamyam_content[i].e[x][y] = map_element_EM_to_RND(lev->eater_array[i][y * 3 + x]); level->amoeba_speed = lev->amoeba_time; @@ -2084,6 +2558,7 @@ void CopyNativeLevel_EM_to_RND(struct LevelInfo *level) level->ball_random = lev->ball_random; level->ball_state_initial = lev->ball_state_initial; level->ball_time = lev->ball_time; + level->num_ball_contents = lev->num_ball_arrays; level->lenses_score = lev->lenses_score; level->magnify_score = lev->magnify_score; @@ -2091,15 +2566,21 @@ void CopyNativeLevel_EM_to_RND(struct LevelInfo *level) level->lenses_time = lev->lenses_time; level->magnify_time = lev->magnify_time; - level->wind_direction_initial = lev->wind_direction_initial; - for (i = 0; i < NUM_MAGIC_BALL_CONTENTS; i++) + level->wind_direction_initial = + map_direction_EM_to_RND(lev->wind_direction_initial); + + for (i = 0; i < MAX_ELEMENT_CONTENTS; i++) for (j = 0; j < 8; j++) - level->ball_content[i][ball_xy[j][0]][ball_xy[j][1]] = + level->ball_content[i].e[ball_xy[j][0]][ball_xy[j][1]] = map_element_EM_to_RND(lev->ball_array[i][j]); + map_android_clone_elements_EM_to_RND(level); + +#if 0 for (i = 0; i < 16; i++) level->android_array[i] = FALSE; /* !!! YET TO COME !!! */ +#endif /* convert the playfield (some elements need special treatment) */ for (y = 0; y < level->fieldy; y++) for (x = 0; x < level->fieldx; x++) @@ -2128,8 +2609,6 @@ static void LoadLevelFromFileInfo_EM(struct LevelInfo *level, level->no_valid_file = TRUE; } -#endif - void CopyNativeLevel_RND_to_Native(struct LevelInfo *level) { if (level->game_engine_type == GAME_ENGINE_TYPE_EM) @@ -2301,7 +2780,7 @@ static void LoadLevelFromFileStream_SP(FILE *file, struct LevelInfo *level, for (i = 0; i < level->num_yamyam_contents; i++) for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - level->yamyam_content[i][x][y] = EL_EMPTY; + level->yamyam_content[i].e[x][y] = EL_EMPTY; } static void LoadLevelFromFileInfo_SP(struct LevelInfo *level, @@ -2545,157 +3024,107 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename) if (leveldir_current == NULL) /* only when dumping level */ return; -#if 0 - printf("::: sort_priority: %d\n", leveldir_current->sort_priority); -#endif - - /* determine correct game engine version of current level */ -#if 1 - if (!leveldir_current->latest_engine) -#else - if (IS_LEVELCLASS_CONTRIB(leveldir_current) || - IS_LEVELCLASS_PRIVATE(leveldir_current) || - IS_LEVELCLASS_UNDEFINED(leveldir_current)) -#endif + if (leveldir_current->latest_engine) { -#if 0 - printf("\n::: This level is private or contributed: '%s'\n", filename); -#endif + /* ---------- use latest game engine ----------------------------------- */ -#if 0 - printf("\n::: Use the stored game engine version for this level\n"); -#endif - - /* For all levels which are not forced to use the latest game engine - version (normally user contributed, private and undefined levels), - use the version of the game engine the levels were created for. - - Since 2.0.1, the game engine version is now directly stored - in the level file (chunk "VERS"), so there is no need anymore - to set the game version from the file version (except for old, - pre-2.0 levels, where the game version is still taken from the - file format version used to store the level -- see above). */ + /* For all levels which are forced to use the latest game engine version + (normally all but user contributed, private and undefined levels), set + the game engine version to the actual version; this allows for actual + corrections in the game engine to take effect for existing, converted + levels (from "classic" or other existing games) to make the emulation + of the corresponding game more accurate, while (hopefully) not breaking + existing levels created from other players. */ -#if 1 - /* player was faster than enemies in 1.0.0 and before */ - if (level->file_version == FILE_VERSION_1_0) - level->double_speed = TRUE; -#else - /* do some special adjustments to support older level versions */ - if (level->file_version == FILE_VERSION_1_0) - { - Error(ERR_WARN, "level file '%s' has version number 1.0", filename); - Error(ERR_WARN, "using high speed movement for player"); + level->game_version = GAME_VERSION_ACTUAL; - /* player was faster than monsters in (pre-)1.0 levels */ - level->double_speed = TRUE; - } -#endif + /* Set special EM style gems behaviour: EM style gems slip down from + normal, steel and growing wall. As this is a more fundamental change, + it seems better to set the default behaviour to "off" (as it is more + natural) and make it configurable in the level editor (as a property + of gem style elements). Already existing converted levels (neither + private nor contributed levels) are changed to the new behaviour. */ - /* default behaviour for EM style gems was "slippery" only in 2.0.1 */ - if (level->game_version == VERSION_IDENT(2,0,1,0)) + if (level->file_version < FILE_VERSION_2_0) level->em_slippery_gems = TRUE; - /* springs could be pushed over pits before (pre-release version) 2.2.0 */ - if (level->game_version < VERSION_IDENT(2,2,0,0)) - level->use_spring_bug = TRUE; + return; + } - /* only few elements were able to actively move into acid before 3.1.0 */ - /* trigger settings did not exist before 3.1.0; set to default "any" */ - if (level->game_version < VERSION_IDENT(3,1,0,0)) - { - int i, j; + /* ---------- use game engine the level was created with ----------------- */ - /* correct "can move into acid" settings (all zero in old levels) */ + /* For all levels which are not forced to use the latest game engine + version (normally user contributed, private and undefined levels), + use the version of the game engine the levels were created for. - level->can_move_into_acid_bits = 0; /* nothing can move into acid */ - level->dont_collide_with_bits = 0; /* nothing is deadly when colliding */ + Since 2.0.1, the game engine version is now directly stored + in the level file (chunk "VERS"), so there is no need anymore + to set the game version from the file version (except for old, + pre-2.0 levels, where the game version is still taken from the + file format version used to store the level -- see above). */ - setMoveIntoAcidProperty(level, EL_ROBOT, TRUE); - setMoveIntoAcidProperty(level, EL_SATELLITE, TRUE); - setMoveIntoAcidProperty(level, EL_PENGUIN, TRUE); - setMoveIntoAcidProperty(level, EL_BALLOON, TRUE); + /* player was faster than enemies in 1.0.0 and before */ + if (level->file_version == FILE_VERSION_1_0) + level->initial_player_stepsize = STEPSIZE_FAST; - for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) - SET_PROPERTY(EL_CUSTOM_START + i, EP_CAN_MOVE_INTO_ACID, TRUE); + /* default behaviour for EM style gems was "slippery" only in 2.0.1 */ + if (level->game_version == VERSION_IDENT(2,0,1,0)) + level->em_slippery_gems = TRUE; - /* correct trigger settings (stored as zero == "none" in old levels) */ + /* springs could be pushed over pits before (pre-release version) 2.2.0 */ + if (level->game_version < VERSION_IDENT(2,2,0,0)) + level->use_spring_bug = TRUE; - for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) - { - int element = EL_CUSTOM_START + i; - struct ElementInfo *ei = &element_info[element]; + if (level->game_version < VERSION_IDENT(3,2,0,5)) + { + /* time orb caused limited time in endless time levels before 3.2.0-5 */ + level->use_time_orb_bug = TRUE; - for (j = 0; j < ei->num_change_pages; j++) - { - struct ElementChangeInfo *change = &ei->change_page[j]; + /* default behaviour for snapping was "no snap delay" before 3.2.0-5 */ + level->block_snap_field = FALSE; - change->trigger_player = CH_PLAYER_ANY; - change->trigger_page = CH_PAGE_ANY; - } - } - } + /* extra time score was same value as time left score before 3.2.0-5 */ + level->extra_time_score = level->score[SC_TIME_BONUS]; -#if 0 /* !!! MOVED TO "game.c", BECAUSE CAN CHANGE INSIDE LEVEL EDITOR !!! */ -#if 1 /* USE_NEW_BLOCK_STYLE */ - /* blocking the last field when moving was corrected in version 3.1.1 */ - if (level->game_version < VERSION_IDENT(3,1,1,0)) - { -#if 0 - printf("::: %d\n", level->block_last_field); -#endif + /* time bonus score was given for 10 s instead of 1 s before 3.2.0-5 */ + level->score[SC_TIME_BONUS] /= 10; + } - /* even "not blocking" was blocking the last field for one frame */ - level->block_delay = (level->block_last_field ? 7 : 1); - level->sp_block_delay = (level->sp_block_last_field ? 7 : 1); + /* only few elements were able to actively move into acid before 3.1.0 */ + /* trigger settings did not exist before 3.1.0; set to default "any" */ + if (level->game_version < VERSION_IDENT(3,1,0,0)) + { + int i, j; - level->block_last_field = TRUE; - level->sp_block_last_field = TRUE; - } -#endif -#endif + /* correct "can move into acid" settings (all zero in old levels) */ - } - else /* always use the latest game engine version */ - { -#if 0 - printf("\n::: ALWAYS USE LATEST ENGINE FOR THIS LEVEL: [%d] '%s'\n", - leveldir_current->sort_priority, filename); -#endif + level->can_move_into_acid_bits = 0; /* nothing can move into acid */ + level->dont_collide_with_bits = 0; /* nothing is deadly when colliding */ -#if 0 - printf("\n::: Use latest game engine version for this level.\n"); -#endif + setMoveIntoAcidProperty(level, EL_ROBOT, TRUE); + setMoveIntoAcidProperty(level, EL_SATELLITE, TRUE); + setMoveIntoAcidProperty(level, EL_PENGUIN, TRUE); + setMoveIntoAcidProperty(level, EL_BALLOON, TRUE); - /* For all levels which are forced to use the latest game engine version - (normally all but user contributed, private and undefined levels), set - the game engine version to the actual version; this allows for actual - corrections in the game engine to take effect for existing, converted - levels (from "classic" or other existing games) to make the emulation - of the corresponding game more accurate, while (hopefully) not breaking - existing levels created from other players. */ + for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) + SET_PROPERTY(EL_CUSTOM_START + i, EP_CAN_MOVE_INTO_ACID, TRUE); -#if 0 - printf("::: changing engine from %d to %d\n", - level->game_version, GAME_VERSION_ACTUAL); -#endif + /* correct trigger settings (stored as zero == "none" in old levels) */ - level->game_version = GAME_VERSION_ACTUAL; + for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) + { + int element = EL_CUSTOM_START + i; + struct ElementInfo *ei = &element_info[element]; - /* Set special EM style gems behaviour: EM style gems slip down from - normal, steel and growing wall. As this is a more fundamental change, - it seems better to set the default behaviour to "off" (as it is more - natural) and make it configurable in the level editor (as a property - of gem style elements). Already existing converted levels (neither - private nor contributed levels) are changed to the new behaviour. */ + for (j = 0; j < ei->num_change_pages; j++) + { + struct ElementChangeInfo *change = &ei->change_page[j]; - if (level->file_version < FILE_VERSION_2_0) - level->em_slippery_gems = TRUE; + change->trigger_player = CH_PLAYER_ANY; + change->trigger_page = CH_PAGE_ANY; + } + } } - -#if 0 - printf("::: => %d\n", level->game_version); -#endif } static void LoadLevel_InitElements(struct LevelInfo *level, char *filename) @@ -2703,7 +3132,8 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename) int i, j, x, y; /* map custom element change events that have changed in newer versions - (these following values were accidentally changed in version 3.0.1) */ + (these following values were accidentally changed in version 3.0.1) + (this seems to be needed only for 'ab_levelset3' and 'ab_levelset4') */ if (level->game_version <= VERSION_IDENT(3,0,0,0)) { for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) @@ -2711,7 +3141,7 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename) int element = EL_CUSTOM_START + i; /* order of checking and copying events to be mapped is important */ - for (j = CE_BY_OTHER_ACTION; j >= CE_BY_PLAYER_OBSOLETE; j--) + for (j = CE_BY_OTHER_ACTION; j >= CE_VALUE_GETS_ZERO; j--) { if (HAS_CHANGE_EVENT(element, j - 2)) { @@ -2732,21 +3162,6 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename) } } - /* some custom element change events get mapped since version 3.0.3 */ - for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) - { - int element = EL_CUSTOM_START + i; - - if (HAS_CHANGE_EVENT(element, CE_BY_PLAYER_OBSOLETE) || - HAS_CHANGE_EVENT(element, CE_BY_COLLISION_OBSOLETE)) - { - SET_CHANGE_EVENT(element, CE_BY_PLAYER_OBSOLETE, FALSE); - SET_CHANGE_EVENT(element, CE_BY_COLLISION_OBSOLETE, FALSE); - - SET_CHANGE_EVENT(element, CE_BY_DIRECT_ACTION, TRUE); - } - } - /* initialize "can_change" field for old levels with only one change page */ if (level->game_version <= VERSION_IDENT(3,0,2,0)) { @@ -2760,22 +3175,50 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename) } /* correct custom element values (for old levels without these options) */ - for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) + if (level->game_version < VERSION_IDENT(3,1,1,0)) { - int element = EL_CUSTOM_START + i; - struct ElementInfo *ei = &element_info[element]; + for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) + { + int element = EL_CUSTOM_START + i; + struct ElementInfo *ei = &element_info[element]; - if (ei->access_direction == MV_NO_MOVING) - ei->access_direction = MV_ALL_DIRECTIONS; + if (ei->access_direction == MV_NO_DIRECTION) + ei->access_direction = MV_ALL_DIRECTIONS; - for (j = 0; j < ei->num_change_pages; j++) +#if 0 + for (j = 0; j < ei->num_change_pages; j++) + { + struct ElementChangeInfo *change = &ei->change_page[j]; + + if (change->trigger_side == CH_SIDE_NONE) + change->trigger_side = CH_SIDE_ANY; + } +#endif + } + } + +#if 1 + /* correct custom element values (fix invalid values for all versions) */ + if (1) + { + for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) { - struct ElementChangeInfo *change = &ei->change_page[j]; + int element = EL_CUSTOM_START + i; + struct ElementInfo *ei = &element_info[element]; - if (change->trigger_side == CH_SIDE_NONE) - change->trigger_side = CH_SIDE_ANY; + for (j = 0; j < ei->num_change_pages; j++) + { + struct ElementChangeInfo *change = &ei->change_page[j]; + + if (change->trigger_player == CH_PLAYER_NONE) + change->trigger_player = CH_PLAYER_ANY; + + if (change->trigger_side == CH_SIDE_NONE) + change->trigger_side = CH_SIDE_ANY; + } } } +#endif /* initialize "can_explode" field for old levels which did not store this */ /* !!! CHECK THIS -- "<= 3,1,0,0" IS PROBABLY WRONG !!! */ @@ -2810,39 +3253,14 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename) } } -#if 0 - /* set default push delay values (corrected since version 3.0.7-1) */ - if (level->game_version < VERSION_IDENT(3,0,7,1)) - { - game.default_push_delay_fixed = 2; - game.default_push_delay_random = 8; - } - else - { - game.default_push_delay_fixed = 8; - game.default_push_delay_random = 8; - } - - /* set uninitialized push delay values of custom elements in older levels */ - for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) - { - int element = EL_CUSTOM_START + i; - - if (element_info[element].push_delay_fixed == -1) - element_info[element].push_delay_fixed = game.default_push_delay_fixed; - if (element_info[element].push_delay_random == -1) - element_info[element].push_delay_random = game.default_push_delay_random; - } -#endif - /* map elements that have changed in newer versions */ level->amoeba_content = getMappedElementByVersion(level->amoeba_content, level->game_version); for (i = 0; i < MAX_ELEMENT_CONTENTS; i++) for (x = 0; x < 3; x++) for (y = 0; y < 3; y++) - level->yamyam_content[i][x][y] = - getMappedElementByVersion(level->yamyam_content[i][x][y], + level->yamyam_content[i].e[x][y] = + getMappedElementByVersion(level->yamyam_content[i].e[x][y], level->game_version); /* initialize element properties for level editor etc. */ @@ -2855,37 +3273,9 @@ static void LoadLevel_InitPlayfield(struct LevelInfo *level, char *filename) /* map elements that have changed in newer versions */ for (y = 0; y < level->fieldy; y++) - { for (x = 0; x < level->fieldx; x++) - { - int element = level->field[x][y]; - -#if 1 - element = getMappedElementByVersion(element, level->game_version); -#else - if (level->game_version <= VERSION_IDENT(2,2,0,0)) - { - /* map game font elements */ - element = (element == EL_CHAR('[') ? EL_CHAR_AUMLAUT : - element == EL_CHAR('\\') ? EL_CHAR_OUMLAUT : - element == EL_CHAR(']') ? EL_CHAR_UUMLAUT : - element == EL_CHAR('^') ? EL_CHAR_COPYRIGHT : element); - } - - if (level->game_version < VERSION_IDENT(3,0,0,0)) - { - /* map Supaplex gravity tube elements */ - element = (element == EL_SP_GRAVITY_PORT_LEFT ? EL_SP_PORT_LEFT : - element == EL_SP_GRAVITY_PORT_RIGHT ? EL_SP_PORT_RIGHT : - element == EL_SP_GRAVITY_PORT_UP ? EL_SP_PORT_UP : - element == EL_SP_GRAVITY_PORT_DOWN ? EL_SP_PORT_DOWN : - element); - } -#endif - - level->field[x][y] = element; - } - } + level->field[x][y] = getMappedElementByVersion(level->field[x][y], + level->game_version); /* copy elements to runtime playfield array */ for (x = 0; x < MAX_LEV_FIELDX; x++) @@ -2902,7 +3292,6 @@ static void LoadLevel_InitPlayfield(struct LevelInfo *level, char *filename) void LoadLevelTemplate(int nr) { -#if 1 char *filename; setLevelFileInfo(&level_template.file_info, nr); @@ -2910,34 +3299,14 @@ void LoadLevelTemplate(int nr) LoadLevelFromFileInfo(&level_template, &level_template.file_info); -#else - -#if 1 - struct LevelFileInfo *level_file_info = getLevelFileInfo(nr); - char *filename = level_file_info->filename; - - LoadLevelFromFileInfo(&level_template, level_file_info); -#else - char *filename = getDefaultLevelFilename(nr); - - LoadLevelFromFilename_RND(&level_template, filename); -#endif -#endif - -#if 1 LoadLevel_InitVersion(&level_template, filename); LoadLevel_InitElements(&level_template, filename); -#else - LoadLevel_InitVersion(&level, filename); - LoadLevel_InitElements(&level, filename); -#endif ActivateLevelTemplate(); } void LoadLevel(int nr) { -#if 1 char *filename; setLevelFileInfo(&level.file_info, nr); @@ -2945,30 +3314,12 @@ void LoadLevel(int nr) LoadLevelFromFileInfo(&level, &level.file_info); -#else - -#if 1 - struct LevelFileInfo *level_file_info = getLevelFileInfo(nr); - char *filename = level_file_info->filename; - - LoadLevelFromFileInfo(&level, level_file_info); -#else - char *filename = getLevelFilename(nr); - - LoadLevelFromFilename_RND(&level, filename); -#endif -#endif - if (level.use_custom_template) LoadLevelTemplate(-1); -#if 1 LoadLevel_InitVersion(&level, filename); LoadLevel_InitElements(&level, filename); LoadLevel_InitPlayfield(&level, filename); -#else - LoadLevel_InitLevel(&level, filename); -#endif } static void SaveLevel_VERS(FILE *file, struct LevelInfo *level) @@ -2997,13 +3348,13 @@ static void SaveLevel_HEAD(FILE *file, struct LevelInfo *level) for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) putFile8Bit(file, (level->encoding_16bit_yamyam ? EL_EMPTY : - level->yamyam_content[i][x][y])); + level->yamyam_content[i].e[x][y])); putFile8Bit(file, level->amoeba_speed); putFile8Bit(file, level->time_magic_wall); putFile8Bit(file, level->time_wheel); putFile8Bit(file, (level->encoding_16bit_amoeba ? EL_EMPTY : level->amoeba_content)); - putFile8Bit(file, (level->double_speed ? 1 : 0)); + putFile8Bit(file, (level->initial_player_stepsize == STEPSIZE_FAST ? 1 : 0)); putFile8Bit(file, (level->initial_gravity ? 1 : 0)); putFile8Bit(file, (level->encoding_16bit_field ? 1 : 0)); putFile8Bit(file, (level->em_slippery_gems ? 1 : 0)); @@ -3061,9 +3412,9 @@ static void SaveLevel_CONT(FILE *file, struct LevelInfo *level) for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) if (level->encoding_16bit_field) - putFile16BitBE(file, level->yamyam_content[i][x][y]); + putFile16BitBE(file, level->yamyam_content[i].e[x][y]); else - putFile8Bit(file, level->yamyam_content[i][x][y]); + putFile8Bit(file, level->yamyam_content[i].e[x][y]); } #endif @@ -3082,7 +3433,7 @@ static void SaveLevel_CNT2(FILE *file, struct LevelInfo *level, int element) for (i = 0; i < MAX_ELEMENT_CONTENTS; i++) for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - content_array[i][x][y] = level->yamyam_content[i][x][y]; + content_array[i][x][y] = level->yamyam_content[i].e[x][y]; } else if (element == EL_BD_AMOEBA) { @@ -3204,63 +3555,64 @@ static void SaveLevel_CUS3(FILE *file, struct LevelInfo *level, for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) { int element = EL_CUSTOM_START + i; + struct ElementInfo *ei = &element_info[element]; - if (element_info[element].modified_settings) + if (ei->modified_settings) { if (check < num_changed_custom_elements) { putFile16BitBE(file, element); for (j = 0; j < MAX_ELEMENT_NAME_LEN; j++) - putFile8Bit(file, element_info[element].description[j]); + putFile8Bit(file, ei->description[j]); putFile32BitBE(file, Properties[element][EP_BITFIELD_BASE]); /* some free bytes for future properties and padding */ WriteUnusedBytesToFile(file, 7); - putFile8Bit(file, element_info[element].use_gfx_element); - putFile16BitBE(file, element_info[element].gfx_element); + putFile8Bit(file, ei->use_gfx_element); + putFile16BitBE(file, ei->gfx_element); - putFile8Bit(file, element_info[element].collect_score); - putFile8Bit(file, element_info[element].collect_count); + putFile8Bit(file, ei->collect_score_initial); + putFile8Bit(file, ei->collect_count_initial); - putFile16BitBE(file, element_info[element].push_delay_fixed); - putFile16BitBE(file, element_info[element].push_delay_random); - putFile16BitBE(file, element_info[element].move_delay_fixed); - putFile16BitBE(file, element_info[element].move_delay_random); + putFile16BitBE(file, ei->push_delay_fixed); + putFile16BitBE(file, ei->push_delay_random); + putFile16BitBE(file, ei->move_delay_fixed); + putFile16BitBE(file, ei->move_delay_random); - putFile16BitBE(file, element_info[element].move_pattern); - putFile8Bit(file, element_info[element].move_direction_initial); - putFile8Bit(file, element_info[element].move_stepsize); + putFile16BitBE(file, ei->move_pattern); + putFile8Bit(file, ei->move_direction_initial); + putFile8Bit(file, ei->move_stepsize); for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - putFile16BitBE(file, element_info[element].content[x][y]); + putFile16BitBE(file, ei->content.e[x][y]); - putFile32BitBE(file, element_info[element].change->events); + putFile32BitBE(file, ei->change->events); - putFile16BitBE(file, element_info[element].change->target_element); + putFile16BitBE(file, ei->change->target_element); - putFile16BitBE(file, element_info[element].change->delay_fixed); - putFile16BitBE(file, element_info[element].change->delay_random); - putFile16BitBE(file, element_info[element].change->delay_frames); + putFile16BitBE(file, ei->change->delay_fixed); + putFile16BitBE(file, ei->change->delay_random); + putFile16BitBE(file, ei->change->delay_frames); - putFile16BitBE(file, element_info[element].change->trigger_element); + putFile16BitBE(file, ei->change->trigger_element); - putFile8Bit(file, element_info[element].change->explode); - putFile8Bit(file, element_info[element].change->use_target_content); - putFile8Bit(file, element_info[element].change->only_if_complete); - putFile8Bit(file, element_info[element].change->use_random_replace); + putFile8Bit(file, ei->change->explode); + putFile8Bit(file, ei->change->use_target_content); + putFile8Bit(file, ei->change->only_if_complete); + putFile8Bit(file, ei->change->use_random_replace); - putFile8Bit(file, element_info[element].change->random_percentage); - putFile8Bit(file, element_info[element].change->replace_when); + putFile8Bit(file, ei->change->random_percentage); + putFile8Bit(file, ei->change->replace_when); for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - putFile16BitBE(file, element_info[element].change->content[x][y]); + putFile16BitBE(file, ei->change->content.e[x][y]); - putFile8Bit(file, element_info[element].slippery_type); + putFile8Bit(file, ei->slippery_type); /* some free bytes for future properties and padding */ WriteUnusedBytesToFile(file, LEVEL_CPART_CUS3_UNUSED); @@ -3280,6 +3632,8 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element) struct ElementInfo *ei = &element_info[element]; int i, j, x, y; + /* ---------- custom element base property values (96 bytes) ------------- */ + putFile16BitBE(file, element); for (i = 0; i < MAX_ELEMENT_NAME_LEN; i++) @@ -3290,16 +3644,15 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element) putFile8Bit(file, ei->num_change_pages); - /* some free bytes for future base property values and padding */ - WriteUnusedBytesToFile(file, 5); - - /* write custom property values */ + putFile16BitBE(file, ei->ce_value_fixed_initial); + putFile16BitBE(file, ei->ce_value_random_initial); + putFile8Bit(file, ei->use_last_ce_value); putFile8Bit(file, ei->use_gfx_element); putFile16BitBE(file, ei->gfx_element); - putFile8Bit(file, ei->collect_score); - putFile8Bit(file, ei->collect_count); + putFile8Bit(file, ei->collect_score_initial); + putFile8Bit(file, ei->collect_count_initial); putFile8Bit(file, ei->drop_delay_fixed); putFile8Bit(file, ei->push_delay_fixed); @@ -3317,7 +3670,7 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element) for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - putFile16BitBE(file, ei->content[x][y]); + putFile16BitBE(file, ei->content.e[x][y]); putFile16BitBE(file, ei->move_enter_element); putFile16BitBE(file, ei->move_leave_element); @@ -3335,17 +3688,18 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element) /* some free bytes for future custom property values and padding */ WriteUnusedBytesToFile(file, 1); - /* write change property values */ + /* ---------- change page property values (48 bytes) --------------------- */ for (i = 0; i < ei->num_change_pages; i++) { struct ElementChangeInfo *change = &ei->change_page[i]; - unsigned long event_bits = 0; + unsigned long event_bits; - for (j = 0; j < NUM_CHANGE_EVENTS; j++) + /* bits 0 - 31 of "has_event[]" ... */ + event_bits = 0; + for (j = 0; j < MIN(NUM_CHANGE_EVENTS, 32); j++) if (change->has_event[j]) event_bits |= (1 << j); - putFile32BitBE(file, event_bits); putFile16BitBE(file, change->target_element); @@ -3366,25 +3720,27 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element) for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - putFile16BitBE(file, change->target_content[x][y]); + putFile16BitBE(file, change->target_content.e[x][y]); putFile8Bit(file, change->can_change); putFile8Bit(file, change->trigger_side); -#if 1 putFile8Bit(file, change->trigger_player); putFile8Bit(file, (change->trigger_page == CH_PAGE_ANY ? CH_PAGE_ANY_FILE : log_2(change->trigger_page))); - /* some free bytes for future change property values and padding */ - WriteUnusedBytesToFile(file, 6); + putFile8Bit(file, change->has_action); + putFile8Bit(file, change->action_type); + putFile8Bit(file, change->action_mode); + putFile16BitBE(file, change->action_arg); -#else - - /* some free bytes for future change property values and padding */ - WriteUnusedBytesToFile(file, 8); -#endif + /* ... bits 32 - 39 of "has_event[]" (not nice, but downward compatible) */ + event_bits = 0; + for (j = 32; j < NUM_CHANGE_EVENTS; j++) + if (change->has_event[j]) + event_bits |= (1 << (j - 32)); + putFile8Bit(file, event_bits); } } @@ -3413,9 +3769,125 @@ static void SaveLevel_GRP1(FILE *file, struct LevelInfo *level, int element) putFile16BitBE(file, group->element[i]); } +static int SaveLevel_CONF_Value(FILE *file, int pos) +{ + int default_value = element_conf[pos].default_value; + int element = element_conf[pos].element; + int type = element_conf[pos].type; + int bytes = type & CONF_MASK_BYTES; + void *value_ptr = element_conf[pos].value; + int value = (CONF_VALUE_BOOLEAN(type) ? *(boolean *)value_ptr : + *(int *)value_ptr); + int num_bytes = 0; + boolean modified = FALSE; + + /* check if any settings have been modified before saving them */ + if (value != default_value) + modified = TRUE; + + if (!modified) /* do not save unmodified default settings */ + return 0; + + if (bytes == CONF_MASK_MULTI_BYTES) + Error(ERR_EXIT, "SaveLevel_CONF_Value: cannot save multi-byte values"); + + num_bytes += putFile16BitBE(file, element); + num_bytes += putFile8Bit(file, type); + num_bytes += (bytes == CONF_MASK_1_BYTE ? putFile8Bit (file, value) : + bytes == CONF_MASK_2_BYTE ? putFile16BitBE(file, value) : + bytes == CONF_MASK_4_BYTE ? putFile32BitBE(file, value) : 0); + + return num_bytes; +} + +static int SaveLevel_CONF_Elements(FILE *file, int pos) +{ + int *element_array = (int *)(element_conf[pos].value); + int num_elements = *(int *)element_conf[pos].num_entities; + int default_value = element_conf[pos].default_value; + int element = element_conf[pos].element; + int type = element_conf[pos].type; + int num_bytes = 0; + boolean modified = FALSE; + int i; + + /* check if any settings have been modified before saving them */ + for (i = 0; i < num_elements; i++) + if (element_array[i] != default_value) + modified = TRUE; + + if (!modified) /* do not save unmodified default settings */ + return 0; + + num_bytes += putFile16BitBE(file, element); + num_bytes += putFile8Bit(file, type); + num_bytes += putFile16BitBE(file, num_elements * CONF_ELEMENT_NUM_BYTES); + + for (i = 0; i < num_elements; i++) + num_bytes += putFile16BitBE(file, element_array[i]); + + return num_bytes; +} + +static int SaveLevel_CONF_Contents(FILE *file, int pos) +{ + struct Content *content = (struct Content *)(element_conf[pos].value); + int num_contents = *(int *)element_conf[pos].num_entities; + int default_value = element_conf[pos].default_value; + int element = element_conf[pos].element; + int type = element_conf[pos].type; + int num_bytes = 0; + boolean modified = FALSE; + int i, x, y; + + /* check if any settings have been modified before saving them */ + for (i = 0; i < num_contents; i++) + for (y = 0; y < 3; y++) + for (x = 0; x < 3; x++) + if (content[i].e[x][y] != default_value) + modified = TRUE; + + if (!modified) /* do not save unmodified default settings */ + return 0; + + num_bytes += putFile16BitBE(file, element); + num_bytes += putFile8Bit(file, type); + num_bytes += putFile16BitBE(file, num_contents * CONF_CONTENT_NUM_BYTES); + + for (i = 0; i < num_contents; i++) + for (y = 0; y < 3; y++) + for (x = 0; x < 3; x++) + num_bytes += putFile16BitBE(file, content[i].e[x][y]); + + return num_bytes; +} + +static int SaveLevel_CONF(FILE *file, struct LevelInfo *level) +{ + int chunk_size = 0; + int i; + + li = *level; /* copy level information into temporary buffer */ + + for (i = 0; element_conf[i].element != -1; i++) + { + int type = element_conf[i].type; + int bytes = type & CONF_MASK_BYTES; + + if (bytes != CONF_MASK_MULTI_BYTES) + chunk_size += SaveLevel_CONF_Value(file, i); + else if (type == CONF_VALUE_ELEMENTS) + chunk_size += SaveLevel_CONF_Elements(file, i); + else if (type == CONF_VALUE_CONTENTS) + chunk_size += SaveLevel_CONF_Contents(file, i); + } + + return chunk_size; +} + static void SaveLevelFromFilename(struct LevelInfo *level, char *filename) { - int body_chunk_size; + int body_chunk_size, conf_chunk_size; int i, x, y; FILE *file; @@ -3440,7 +3912,7 @@ static void SaveLevelFromFilename(struct LevelInfo *level, char *filename) for (i = 0; i < level->num_yamyam_contents; i++) for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) - if (level->yamyam_content[i][x][y] > 255) + if (level->yamyam_content[i].e[x][y] > 255) level->encoding_16bit_yamyam = TRUE; /* check amoeba content for 16-bit elements */ @@ -3524,6 +3996,15 @@ static void SaveLevelFromFilename(struct LevelInfo *level, char *filename) } } + conf_chunk_size = SaveLevel_CONF(NULL, level); /* get chunk size */ + + /* check for non-default configuration settings to be saved in CONF chunk */ + if (conf_chunk_size > 0) + { + putFileChunkBE(file, "CONF", conf_chunk_size); + SaveLevel_CONF(file, level); + } + fclose(file); SetFilePermissions(filename, PERMS_PRIVATE); @@ -3573,7 +4054,7 @@ void DumpLevel(struct LevelInfo *level) printf("Amoeba speed: %d\n", level->amoeba_speed); printf("\n"); printf("Initial gravity: %s\n", (level->initial_gravity ? "yes" : "no")); - printf("Double speed movement: %s\n", (level->double_speed ? "yes" : "no")); + printf("Initial player stepsize: %d\n", level->initial_player_stepsize); printf("EM style slippery gems: %s\n", (level->em_slippery_gems ? "yes" : "no")); printf("Player blocks last field: %s\n", (level->block_last_field ? "yes" : "no")); printf("SP player blocks last field: %s\n", (level->sp_block_last_field ? "yes" : "no")); @@ -3700,7 +4181,7 @@ static int LoadTape_BODY(FILE *file, int chunk_size, struct TapeInfo *tape) for (j = 0; j < MAX_PLAYERS; j++) { - tape->pos[i].action[j] = MV_NO_MOVING; + tape->pos[i].action[j] = MV_NONE; if (tape->player_participates[j]) tape->pos[i].action[j] = getFile8Bit(file); @@ -3747,7 +4228,7 @@ static int LoadTape_BODY(FILE *file, int chunk_size, struct TapeInfo *tape) /* delay part */ for (j = 0; j < MAX_PLAYERS; j++) - tape->pos[i].action[j] = MV_NO_MOVING; + tape->pos[i].action[j] = MV_NONE; tape->pos[i].delay--; i++; @@ -3779,10 +4260,6 @@ void LoadTapeFromFilename(char *filename) { tape.no_valid_file = TRUE; -#if 0 - Error(ERR_WARN, "cannot read tape '%s' -- using empty tape", filename); -#endif - return; } @@ -4037,21 +4514,12 @@ void DumpTape(struct TapeInfo *tape) { int i, j; -#if 1 if (tape->no_valid_file) { Error(ERR_WARN, "cannot dump -- no valid tape file found"); return; } -#else - if (TAPE_IS_EMPTY(*tape)) - { - Error(ERR_WARN, "no tape available for level %d", tape->level_nr); - - return; - } -#endif printf_line("-", 79); printf("Tape of Level %03d (file version %08d, game version %08d)\n", @@ -4218,12 +4686,30 @@ void SaveScore(int nr) #define SETUP_TOKEN_EDITOR_EL_DX_BOULDERDASH 7 #define SETUP_TOKEN_EDITOR_EL_CHARS 8 #define SETUP_TOKEN_EDITOR_EL_CUSTOM 9 -#define SETUP_TOKEN_EDITOR_EL_CUSTOM_MORE 10 -#define SETUP_TOKEN_EDITOR_EL_HEADLINES 11 -#define SETUP_TOKEN_EDITOR_EL_USER_DEFINED 12 +#define SETUP_TOKEN_EDITOR_EL_HEADLINES 10 +#define SETUP_TOKEN_EDITOR_EL_USER_DEFINED 11 +#define SETUP_TOKEN_EDITOR_EL_DYNAMIC 12 #define NUM_EDITOR_SETUP_TOKENS 13 +/* editor cascade setup */ +#define SETUP_TOKEN_EDITOR_CASCADE_BD 0 +#define SETUP_TOKEN_EDITOR_CASCADE_EM 1 +#define SETUP_TOKEN_EDITOR_CASCADE_EMC 2 +#define SETUP_TOKEN_EDITOR_CASCADE_RND 3 +#define SETUP_TOKEN_EDITOR_CASCADE_SB 4 +#define SETUP_TOKEN_EDITOR_CASCADE_SP 5 +#define SETUP_TOKEN_EDITOR_CASCADE_DC 6 +#define SETUP_TOKEN_EDITOR_CASCADE_DX 7 +#define SETUP_TOKEN_EDITOR_CASCADE_TEXT 8 +#define SETUP_TOKEN_EDITOR_CASCADE_CE 9 +#define SETUP_TOKEN_EDITOR_CASCADE_GE 10 +#define SETUP_TOKEN_EDITOR_CASCADE_USER 11 +#define SETUP_TOKEN_EDITOR_CASCADE_GENERIC 12 +#define SETUP_TOKEN_EDITOR_CASCADE_DYNAMIC 13 + +#define NUM_EDITOR_CASCADE_SETUP_TOKENS 14 + /* shortcut setup */ #define SETUP_TOKEN_SHORTCUT_SAVE_GAME 0 #define SETUP_TOKEN_SHORTCUT_LOAD_GAME 1 @@ -4265,6 +4751,7 @@ void SaveScore(int nr) static struct SetupInfo si; static struct SetupEditorInfo sei; +static struct SetupEditorCascadeInfo seci; static struct SetupShortcutInfo ssi; static struct SetupInputInfo sii; static struct SetupSystemInfo syi; @@ -4309,9 +4796,27 @@ static struct TokenInfo editor_setup_tokens[] = { TYPE_SWITCH, &sei.el_dx_boulderdash,"editor.el_dx_boulderdash" }, { TYPE_SWITCH, &sei.el_chars, "editor.el_chars" }, { TYPE_SWITCH, &sei.el_custom, "editor.el_custom" }, - { TYPE_SWITCH, &sei.el_custom_more, "editor.el_custom_more" }, { TYPE_SWITCH, &sei.el_headlines, "editor.el_headlines" }, { TYPE_SWITCH, &sei.el_user_defined, "editor.el_user_defined" }, + { TYPE_SWITCH, &sei.el_dynamic, "editor.el_dynamic" }, +}; + +static struct TokenInfo editor_cascade_setup_tokens[] = +{ + { TYPE_SWITCH, &seci.el_bd, "editor.cascade.el_bd" }, + { TYPE_SWITCH, &seci.el_em, "editor.cascade.el_em" }, + { TYPE_SWITCH, &seci.el_emc, "editor.cascade.el_emc" }, + { TYPE_SWITCH, &seci.el_rnd, "editor.cascade.el_rnd" }, + { TYPE_SWITCH, &seci.el_sb, "editor.cascade.el_sb" }, + { TYPE_SWITCH, &seci.el_sp, "editor.cascade.el_sp" }, + { TYPE_SWITCH, &seci.el_dc, "editor.cascade.el_dc" }, + { TYPE_SWITCH, &seci.el_dx, "editor.cascade.el_dx" }, + { TYPE_SWITCH, &seci.el_chars, "editor.cascade.el_chars" }, + { TYPE_SWITCH, &seci.el_ce, "editor.cascade.el_ce" }, + { TYPE_SWITCH, &seci.el_ge, "editor.cascade.el_ge" }, + { TYPE_SWITCH, &seci.el_user, "editor.cascade.el_user" }, + { TYPE_SWITCH, &seci.el_generic, "editor.cascade.el_generic" }, + { TYPE_SWITCH, &seci.el_dynamic, "editor.cascade.el_dynamic" }, }; static struct TokenInfo shortcut_setup_tokens[] = @@ -4409,10 +4914,10 @@ static void setSetupInfoToDefaults(struct SetupInfo *si) si->editor.el_dx_boulderdash = TRUE; si->editor.el_chars = TRUE; si->editor.el_custom = TRUE; - si->editor.el_custom_more = FALSE; si->editor.el_headlines = TRUE; si->editor.el_user_defined = FALSE; + si->editor.el_dynamic = TRUE; si->shortcut.save_game = DEFAULT_KEY_SAVE_GAME; si->shortcut.load_game = DEFAULT_KEY_LOAD_GAME; @@ -4444,6 +4949,25 @@ static void setSetupInfoToDefaults(struct SetupInfo *si) si->options.verbose = FALSE; } +static void setSetupInfoToDefaults_EditorCascade(struct SetupInfo *si) +{ + si->editor_cascade.el_bd = TRUE; + si->editor_cascade.el_em = TRUE; + si->editor_cascade.el_emc = TRUE; + si->editor_cascade.el_rnd = TRUE; + si->editor_cascade.el_sb = TRUE; + si->editor_cascade.el_sp = TRUE; + si->editor_cascade.el_dc = TRUE; + si->editor_cascade.el_dx = TRUE; + + si->editor_cascade.el_chars = FALSE; + si->editor_cascade.el_ce = FALSE; + si->editor_cascade.el_ge = FALSE; + si->editor_cascade.el_user = FALSE; + si->editor_cascade.el_generic = FALSE; + si->editor_cascade.el_dynamic = FALSE; +} + static void decodeSetupFileHash(SetupFileHash *setup_file_hash) { int i, pnr; @@ -4506,6 +5030,22 @@ static void decodeSetupFileHash(SetupFileHash *setup_file_hash) setup.options = soi; } +static void decodeSetupFileHash_EditorCascade(SetupFileHash *setup_file_hash) +{ + int i; + + if (!setup_file_hash) + return; + + /* editor cascade setup */ + seci = setup.editor_cascade; + for (i = 0; i < NUM_EDITOR_CASCADE_SETUP_TOKENS; i++) + setSetupInfo(editor_cascade_setup_tokens, i, + getHashEntry(setup_file_hash, + editor_cascade_setup_tokens[i].text)); + setup.editor_cascade = seci; +} + void LoadSetup() { char *filename = getSetupFilename(); @@ -4536,6 +5076,27 @@ void LoadSetup() Error(ERR_WARN, "using default setup values"); } +void LoadSetup_EditorCascade() +{ + char *filename = getPath2(getSetupDir(), EDITORCASCADE_FILENAME); + SetupFileHash *setup_file_hash = NULL; + + /* always start with reliable default values */ + setSetupInfoToDefaults_EditorCascade(&setup); + + setup_file_hash = loadSetupFileHash(filename); + + if (setup_file_hash) + { + checkSetupFileHashIdentifier(setup_file_hash, getCookie("SETUP")); + decodeSetupFileHash_EditorCascade(setup_file_hash); + + freeSetupFileHash(setup_file_hash); + } + + free(filename); +} + void SaveSetup() { char *filename = getSetupFilename(); @@ -4608,6 +5169,37 @@ void SaveSetup() SetFilePermissions(filename, PERMS_PRIVATE); } +void SaveSetup_EditorCascade() +{ + char *filename = getPath2(getSetupDir(), EDITORCASCADE_FILENAME); + FILE *file; + int i; + + InitUserDataDirectory(); + + if (!(file = fopen(filename, MODE_WRITE))) + { + Error(ERR_WARN, "cannot write editor cascade state file '%s'", filename); + free(filename); + return; + } + + fprintf(file, "%s\n", getFormattedSetupEntry(TOKEN_STR_FILE_IDENTIFIER, + getCookie("SETUP"))); + fprintf(file, "\n"); + + seci = setup.editor_cascade; + fprintf(file, "\n"); + for (i = 0; i < NUM_EDITOR_SETUP_TOKENS; i++) + fprintf(file, "%s\n", getSetupLine(editor_cascade_setup_tokens, "", i)); + + fclose(file); + + SetFilePermissions(filename, PERMS_PRIVATE); + + free(filename); +} + void LoadCustomElementDescriptions() { char *filename = getCustomArtworkConfigFilename(ARTWORK_TYPE_GRAPHICS); @@ -4709,6 +5301,10 @@ void LoadUserDefinedEditorElementList(int **elements, int *num_elements) /* add space for up to 3 more elements for padding that may be needed */ *num_elements += 3; + /* free memory for old list of elements, if needed */ + checked_free(*elements); + + /* allocate memory for new list of elements */ *elements = checked_malloc(*num_elements * sizeof(int)); *num_elements = 0; @@ -4757,7 +5353,6 @@ void LoadUserDefinedEditorElementList(int **elements, int *num_elements) freeSetupFileHash(element_hash); #if 0 - /* TEST-ONLY */ for (i = 0; i < *num_elements; i++) printf("editor: element '%s' [%d]\n", element_info[(*elements)[i]].token_name, (*elements)[i]); @@ -4922,18 +5517,10 @@ void LoadMusicInfo() new = &music_file_info; -#if 0 - printf("::: num_music == %d\n", num_music); -#endif - for (i = 0; i < num_music; i++) { music = getMusicListEntry(i); -#if 0 - printf("::: %d [%08x]\n", i, music->filename); -#endif - if (music->filename == NULL) continue; @@ -5032,7 +5619,6 @@ void LoadMusicInfo() } #if 0 - /* TEST-ONLY */ for (next = music_file_info; next != NULL; next = next->next) printf("::: title == '%s'\n", next->title); #endif @@ -5273,7 +5859,6 @@ void LoadHelpAnimInfo() freeSetupFileHash(direction_hash); #if 0 - /* TEST ONLY */ for (i = 0; i < num_list_entries; i++) printf("::: %d, %d, %d => %d\n", helpanim_info[i].element, @@ -5309,7 +5894,6 @@ void LoadHelpTextInfo() } #if 0 - /* TEST ONLY */ BEGIN_HASH_ITERATION(helptext_info, itr) { printf("::: '%s' => '%s'\n", diff --git a/src/files.h b/src/files.h index 9a0cf0ff..ead1f24f 100644 --- a/src/files.h +++ b/src/files.h @@ -54,6 +54,9 @@ void SaveScore(int); void LoadSetup(); void SaveSetup(); +void LoadSetup_EditorCascade(); +void SaveSetup_EditorCascade(); + void LoadCustomElementDescriptions(); void LoadSpecialMenuDesignSettings(); void LoadUserDefinedEditorElementList(int **, int *); diff --git a/src/game.c b/src/game.c index b0d7ec6b..d2e58439 100644 --- a/src/game.c +++ b/src/game.c @@ -21,43 +21,21 @@ #include "tape.h" #include "network.h" -/* this switch controls how rocks move horizontally */ -#define OLD_GAME_BEHAVIOUR FALSE - /* EXPERIMENTAL STUFF */ #define USE_NEW_AMOEBA_CODE FALSE /* EXPERIMENTAL STUFF */ -#define USE_NEW_STUFF (TRUE * 1) - -#define USE_NEW_MOVE_STYLE (TRUE * USE_NEW_STUFF * 1) -#define USE_NEW_MOVE_DELAY (TRUE * USE_NEW_STUFF * 1) -#define USE_NEW_PUSH_DELAY (TRUE * USE_NEW_STUFF * 1) -#define USE_NEW_BLOCK_STYLE (TRUE * USE_NEW_STUFF * 1) -#define USE_NEW_SP_SLIPPERY (TRUE * USE_NEW_STUFF * 1) -#define USE_NEW_RANDOMIZE (TRUE * USE_NEW_STUFF * 1) - -#define USE_CAN_MOVE_NOT_MOVING (TRUE * USE_NEW_STUFF * 1) -#define USE_PREVIOUS_MOVE_DIR (TRUE * USE_NEW_STUFF * 1) - -#define USE_PUSH_BUGFIX (TRUE * USE_NEW_STUFF * 1) -#if 0 -#define USE_BLOCK_DELAY_BUGFIX (TRUE * USE_NEW_STUFF * 1) -#endif -#define USE_GRAVITY_BUGFIX_NEW (TRUE * USE_NEW_STUFF * 1) -#define USE_GRAVITY_BUGFIX_OLD (TRUE * USE_NEW_STUFF * 0) - -#define USE_PENGUIN_COLLECT_BUGFIX (TRUE * USE_NEW_STUFF * 1) - -#define USE_IMPACT_BUGFIX (TRUE * USE_NEW_STUFF * 1) - -#define USE_HITTING_SOMETHING_BUGFIX (TRUE * USE_NEW_STUFF * 1) -#define USE_HIT_BY_SOMETHING_BUGFIX (TRUE * USE_NEW_STUFF * 1) - -#define USE_DROP_BUGFIX (TRUE * USE_NEW_STUFF * 1) - -#define USE_CHANGE_TO_TRIGGERED (TRUE * USE_NEW_STUFF * 1) - +#define USE_NEW_STUFF ( 1) + +#define USE_NEW_SP_SLIPPERY (USE_NEW_STUFF * 1) +#define USE_NEW_CUSTOM_VALUE (USE_NEW_STUFF * 1) +#define USE_NEW_PLAYER_ANIM (USE_NEW_STUFF * 1) +#define USE_NEW_ALL_SLIPPERY (USE_NEW_STUFF * 1) +#define USE_NEW_PLAYER_SPEED (USE_NEW_STUFF * 1) +#define USE_NEW_DELAYED_ACTION (USE_NEW_STUFF * 1) +#define USE_NEW_SNAP_DELAY (USE_NEW_STUFF * 1) +#define USE_ONLY_ONE_CHANGE_PER_FRAME (USE_NEW_STUFF * 1) +#define USE_QUICKSAND_IMPACT_BUGFIX (USE_NEW_STUFF * 0) /* for DigField() */ #define DF_NO_PUSH 0 @@ -73,13 +51,14 @@ #define SCROLL_INIT 0 #define SCROLL_GO_ON 1 -/* for Explode() */ +/* for Bang()/Explode() */ #define EX_PHASE_START 0 #define EX_TYPE_NONE 0 #define EX_TYPE_NORMAL (1 << 0) #define EX_TYPE_CENTER (1 << 1) #define EX_TYPE_BORDER (1 << 2) #define EX_TYPE_CROSS (1 << 3) +#define EX_TYPE_DYNA (1 << 4) #define EX_TYPE_SINGLE_TILE (EX_TYPE_CENTER | EX_TYPE_BORDER) /* special positions in the game control window (relative to control window) */ @@ -117,16 +96,25 @@ #define INITIAL_MOVE_DELAY_ON 0 /* values for player movement speed (which is in fact a delay value) */ +#define MOVE_DELAY_MIN_SPEED 32 #define MOVE_DELAY_NORMAL_SPEED 8 #define MOVE_DELAY_HIGH_SPEED 4 +#define MOVE_DELAY_MAX_SPEED 1 +#if 0 #define DOUBLE_MOVE_DELAY(x) (x = (x <= MOVE_DELAY_HIGH_SPEED ? x * 2 : x)) #define HALVE_MOVE_DELAY(x) (x = (x >= MOVE_DELAY_HIGH_SPEED ? x / 2 : x)) +#else +#define DOUBLE_MOVE_DELAY(x) (x = (x < MOVE_DELAY_MIN_SPEED ? x * 2 : x)) +#define HALVE_MOVE_DELAY(x) (x = (x > MOVE_DELAY_MAX_SPEED ? x / 2 : x)) +#endif #define DOUBLE_PLAYER_SPEED(p) (HALVE_MOVE_DELAY((p)->move_delay_value)) #define HALVE_PLAYER_SPEED(p) (DOUBLE_MOVE_DELAY((p)->move_delay_value)) /* values for other actions */ #define MOVE_STEPSIZE_NORMAL (TILEX / MOVE_DELAY_NORMAL_SPEED) +#define MOVE_STEPSIZE_MIN (1) +#define MOVE_STEPSIZE_MAX (TILEX) #define GET_DX_FROM_DIR(d) ((d) == MV_LEFT ? -1 : (d) == MV_RIGHT ? 1 : 0) #define GET_DY_FROM_DIR(d) ((d) == MV_UP ? -1 : (d) == MV_DOWN ? 1 : 0) @@ -141,14 +129,17 @@ RND(element_info[e].move_delay_random)) #define GET_MAX_MOVE_DELAY(e) ( (element_info[e].move_delay_fixed) + \ (element_info[e].move_delay_random)) +#define GET_NEW_CUSTOM_VALUE(e) ( (element_info[e].ce_value_fixed_initial) +\ + RND(element_info[e].ce_value_random_initial)) +#define GET_CHANGE_DELAY(c) ( ((c)->delay_fixed * (c)->delay_frames) + \ + RND((c)->delay_random * (c)->delay_frames)) +#define GET_CE_DELAY_VALUE(c) ( ((c)->delay_fixed) + \ + RND((c)->delay_random)) #define GET_TARGET_ELEMENT(e, ch) \ ((e) == EL_TRIGGER_ELEMENT ? (ch)->actual_trigger_element : \ (e) == EL_TRIGGER_PLAYER ? (ch)->actual_trigger_player : (e)) -#define GET_VALID_PLAYER_ELEMENT(e) \ - ((e) >= EL_PLAYER_1 && (e) <= EL_PLAYER_4 ? (e) : EL_PLAYER_1) - #define CAN_GROW_INTO(e) \ ((e) == EL_SAND || (IS_DIGGABLE(e) && level.grow_into_diggable)) @@ -177,35 +168,15 @@ IS_PLAYER(x, y) && \ !PLAYER_ENEMY_PROTECTED(x, y)))) -#if 0 -#define ELEMENT_CAN_ENTER_FIELD_GENERIC(e, x, y, condition) \ - (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) || \ - (condition) || \ - (DONT_COLLIDE_WITH(e) && \ - IS_PLAYER(x, y) && \ - !PLAYER_ENEMY_PROTECTED(x, y)))) -#endif - #define ELEMENT_CAN_ENTER_FIELD(e, x, y) \ ELEMENT_CAN_ENTER_FIELD_BASE_4(e, x, y, 0) -#if 1 #define SATELLITE_CAN_ENTER_FIELD(x, y) \ ELEMENT_CAN_ENTER_FIELD_BASE_2(EL_SATELLITE, x, y, 0) -#else -#define SATELLITE_CAN_ENTER_FIELD(x, y) \ - ELEMENT_CAN_ENTER_FIELD_BASE_X(x, y, Feld[x][y] == EL_ACID) -#endif - -#if 0 -#define ENEMY_CAN_ENTER_FIELD(e, x, y) (IN_LEV_FIELD(x, y) && IS_FREE(x, y)) -#endif #define ENEMY_CAN_ENTER_FIELD(e, x, y) \ ELEMENT_CAN_ENTER_FIELD_BASE_2(e, x, y, 0) -#if 1 - #define YAMYAM_CAN_ENTER_FIELD(e, x, y) \ ELEMENT_CAN_ENTER_FIELD_BASE_3(e, x, y, Feld[x][y] == EL_DIAMOND) @@ -230,57 +201,6 @@ #define SPRING_CAN_ENTER_FIELD(e, x, y) \ ELEMENT_CAN_ENTER_FIELD_BASE_2(e, x, y, 0) -#else - -#define YAMYAM_CAN_ENTER_FIELD(e, x, y) \ - (IN_LEV_FIELD(x, y) && (IS_FREE_OR_PLAYER(x, y) || \ - (CAN_MOVE_INTO_ACID(e) && \ - Feld[x][y] == EL_ACID) || \ - Feld[x][y] == EL_DIAMOND)) - -#define DARK_YAMYAM_CAN_ENTER_FIELD(e, x, y) \ - (IN_LEV_FIELD(x, y) && (IS_FREE_OR_PLAYER(x, y) || \ - (CAN_MOVE_INTO_ACID(e) && \ - Feld[x][y] == EL_ACID) || \ - IS_FOOD_DARK_YAMYAM(Feld[x][y]))) - -#define PACMAN_CAN_ENTER_FIELD(e, x, y) \ - (IN_LEV_FIELD(x, y) && (IS_FREE_OR_PLAYER(x, y) || \ - (CAN_MOVE_INTO_ACID(e) && \ - Feld[x][y] == EL_ACID) || \ - IS_AMOEBOID(Feld[x][y]))) - -#define PIG_CAN_ENTER_FIELD(e, x, y) \ - (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) || \ - (CAN_MOVE_INTO_ACID(e) && \ - Feld[x][y] == EL_ACID) || \ - IS_FOOD_PIG(Feld[x][y]))) - -#define PENGUIN_CAN_ENTER_FIELD(e, x, y) \ - (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) || \ - (CAN_MOVE_INTO_ACID(e) && \ - Feld[x][y] == EL_ACID) || \ - IS_FOOD_PENGUIN(Feld[x][y]) || \ - Feld[x][y] == EL_EXIT_OPEN)) - -#define DRAGON_CAN_ENTER_FIELD(e, x, y) \ - (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) || \ - (CAN_MOVE_INTO_ACID(e) && \ - Feld[x][y] == EL_ACID))) - -#define MOLE_CAN_ENTER_FIELD(e, x, y, condition) \ - (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) || \ - (CAN_MOVE_INTO_ACID(e) && \ - Feld[x][y] == EL_ACID) || \ - (condition))) - -#define SPRING_CAN_ENTER_FIELD(e, x, y) \ - (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) || \ - (CAN_MOVE_INTO_ACID(e) && \ - Feld[x][y] == EL_ACID))) - -#endif - #define GROUP_NR(e) ((e) - EL_GROUP_START) #define MOVE_ENTER_EL(e) (element_info[e].move_enter_element) #define IS_IN_GROUP(e, nr) (element_info[e].in_group[nr] == TRUE) @@ -289,16 +209,9 @@ #define IS_EQUAL_OR_IN_GROUP(e, ge) \ (IS_GROUP_ELEMENT(ge) ? IS_IN_GROUP(e, GROUP_NR(ge)) : (e) == (ge)) -#if 0 -#define CE_ENTER_FIELD_COND(e, x, y) \ - (!IS_PLAYER(x, y) && \ - (Feld[x][y] == EL_ACID || \ - IS_EQUAL_OR_IN_GROUP(Feld[x][y], MOVE_ENTER_EL(e)))) -#else #define CE_ENTER_FIELD_COND(e, x, y) \ (!IS_PLAYER(x, y) && \ IS_EQUAL_OR_IN_GROUP(Feld[x][y], MOVE_ENTER_EL(e))) -#endif #define CUSTOM_ELEMENT_CAN_ENTER_FIELD(e, x, y) \ ELEMENT_CAN_ENTER_FIELD_BASE_4(e, x, y, CE_ENTER_FIELD_COND(e, x, y)) @@ -324,6 +237,9 @@ /* forward declaration for internal use */ +static void CreateField(int, int, int); + +static void SetPlayerWaiting(struct PlayerInfo *, boolean); static void AdvanceFrameAndPlayerCounters(int); static boolean MovePlayerOneStep(struct PlayerInfo *, int, int, int, int); @@ -337,8 +253,8 @@ static void InitBeltMovement(void); static void CloseAllOpenTimegates(void); static void CheckGravityMovement(struct PlayerInfo *); static void CheckGravityMovementWhenNotMoving(struct PlayerInfo *); -static void KillHeroUnlessEnemyProtected(int, int); -static void KillHeroUnlessExplosionProtected(int, int); +static void KillPlayerUnlessEnemyProtected(int, int); +static void KillPlayerUnlessExplosionProtected(int, int); static void TestIfPlayerTouchesCustomElement(int, int); static void TestIfElementTouchesCustomElement(int, int); @@ -347,29 +263,25 @@ static void TestIfElementHitsCustomElement(int, int, int); static void TestIfElementSmashesCustomElement(int, int, int); #endif -static void ChangeElement(int, int, int); +static void HandleElementChange(int, int, int); static boolean CheckTriggeredElementChangeExt(int, int, int, int, int,int,int); #define CheckTriggeredElementChange(x, y, e, ev) \ - CheckTriggeredElementChangeExt(x, y, e, ev, CH_PLAYER_ANY, \ - CH_SIDE_ANY, -1) + CheckTriggeredElementChangeExt(x,y,e,ev, CH_PLAYER_ANY,CH_SIDE_ANY, -1) #define CheckTriggeredElementChangeByPlayer(x, y, e, ev, p, s) \ CheckTriggeredElementChangeExt(x, y, e, ev, p, s, -1) #define CheckTriggeredElementChangeBySide(x, y, e, ev, s) \ CheckTriggeredElementChangeExt(x, y, e, ev, CH_PLAYER_ANY, s, -1) #define CheckTriggeredElementChangeByPage(x, y, e, ev, p) \ - CheckTriggeredElementChangeExt(x, y, e, ev, CH_PLAYER_ANY, \ - CH_SIDE_ANY, p) + CheckTriggeredElementChangeExt(x,y,e,ev, CH_PLAYER_ANY, CH_SIDE_ANY, p) -static boolean CheckElementChangeExt(int, int, int, int, int, int, int, int); +static boolean CheckElementChangeExt(int, int, int, int, int, int, int); #define CheckElementChange(x, y, e, te, ev) \ - CheckElementChangeExt(x, y, e, te, ev, CH_PLAYER_ANY, CH_SIDE_ANY, -1) + CheckElementChangeExt(x, y, e, te, ev, CH_PLAYER_ANY, CH_SIDE_ANY) #define CheckElementChangeByPlayer(x, y, e, ev, p, s) \ - CheckElementChangeExt(x, y, e, EL_EMPTY, ev, p, s, CH_PAGE_ANY) + CheckElementChangeExt(x, y, e, EL_EMPTY, ev, p, s) #define CheckElementChangeBySide(x, y, e, te, ev, s) \ - CheckElementChangeExt(x, y, e, te, ev, CH_PLAYER_ANY, s, CH_PAGE_ANY) -#define CheckElementChangeByPage(x, y, e, te, ev, p) \ - CheckElementChangeExt(x, y, e, te, ev, CH_PLAYER_ANY, CH_SIDE_ANY, p) + CheckElementChangeExt(x, y, e, te, ev, CH_PLAYER_ANY, s) static void PlayLevelSound(int, int, int); static void PlayLevelSoundNearest(int, int, int); @@ -392,19 +304,22 @@ static struct GadgetInfo *game_gadget[NUM_GAME_BUTTONS]; /* ------------------------------------------------------------------------- */ /* forward declaration for changer functions */ -static void InitBuggyBase(int x, int y); -static void WarnBuggyBase(int x, int y); +static void InitBuggyBase(int, int); +static void WarnBuggyBase(int, int); -static void InitTrap(int x, int y); -static void ActivateTrap(int x, int y); -static void ChangeActiveTrap(int x, int y); +static void InitTrap(int, int); +static void ActivateTrap(int, int); +static void ChangeActiveTrap(int, int); -static void InitRobotWheel(int x, int y); -static void RunRobotWheel(int x, int y); -static void StopRobotWheel(int x, int y); +static void InitRobotWheel(int, int); +static void RunRobotWheel(int, int); +static void StopRobotWheel(int, int); -static void InitTimegateWheel(int x, int y); -static void RunTimegateWheel(int x, int y); +static void InitTimegateWheel(int, int); +static void RunTimegateWheel(int, int); + +static void InitMagicBallDelay(int, int); +static void ActivateMagicBall(int, int); struct ChangingElementInfo { @@ -571,6 +486,14 @@ static struct ChangingElementInfo change_delay_list[] = RunTimegateWheel, NULL }, + { + EL_EMC_MAGIC_BALL_ACTIVE, + EL_EMC_MAGIC_BALL_ACTIVE, + 0, + InitMagicBallDelay, + NULL, + ActivateMagicBall + }, { EL_UNDEFINED, @@ -678,7 +601,7 @@ access_direction_list[] = { EL_SP_GRAVITY_OFF_PORT_UP, MV_DOWN }, { EL_SP_GRAVITY_OFF_PORT_DOWN, MV_UP }, - { EL_UNDEFINED, MV_NO_MOVING } + { EL_UNDEFINED, MV_NONE } }; static boolean trigger_events[MAX_NUM_ELEMENTS][NUM_CHANGE_EVENTS]; @@ -690,6 +613,80 @@ static boolean trigger_events[MAX_NUM_ELEMENTS][NUM_CHANGE_EVENTS]; #define CE_PAGE(e, ce) (element_info[e].event_page[ce]) +/* static variables for playfield scan mode (scanning forward or backward) */ +static int playfield_scan_start_x = 0; +static int playfield_scan_start_y = 0; +static int playfield_scan_delta_x = 1; +static int playfield_scan_delta_y = 1; + +#define SCAN_PLAYFIELD(x, y) for ((y) = playfield_scan_start_y; \ + (y) >= 0 && (y) <= lev_fieldy - 1; \ + (y) += playfield_scan_delta_y) \ + for ((x) = playfield_scan_start_x; \ + (x) >= 0 && (x) <= lev_fieldx - 1; \ + (x) += playfield_scan_delta_x) \ + +static void InitPlayfieldScanModeVars() +{ + if (game.use_reverse_scan_direction) + { + playfield_scan_start_x = lev_fieldx - 1; + playfield_scan_start_y = lev_fieldy - 1; + + playfield_scan_delta_x = -1; + playfield_scan_delta_y = -1; + } + else + { + playfield_scan_start_x = 0; + playfield_scan_start_y = 0; + + playfield_scan_delta_x = 1; + playfield_scan_delta_y = 1; + } +} + +static void InitPlayfieldScanMode(int mode) +{ + game.use_reverse_scan_direction = + (mode == CA_ARG_SCAN_MODE_REVERSE ? TRUE : FALSE); + + InitPlayfieldScanModeVars(); +} + +static int get_move_delay_from_stepsize(int move_stepsize) +{ + move_stepsize = + MIN(MAX(MOVE_STEPSIZE_MIN, move_stepsize), MOVE_STEPSIZE_MAX); + + /* make sure that stepsize value is always a power of 2 */ + move_stepsize = (1 << log_2(move_stepsize)); + + return TILEX / move_stepsize; +} + +static void SetPlayerMoveSpeed(struct PlayerInfo *player, int move_stepsize, + boolean init_game) +{ + int move_delay = get_move_delay_from_stepsize(move_stepsize); + boolean cannot_move = (move_stepsize == STEPSIZE_NOT_MOVING ? TRUE : FALSE); + + /* do no immediately change move delay -- the player might just be moving */ + player->move_delay_value_next = move_delay; + + /* information if player can move must be set separately */ + player->cannot_move = cannot_move; + + if (init_game) + { + player->move_delay = game.initial_move_delay; + player->move_delay_value = game.initial_move_delay_value; + + player->move_delay_value_next = -1; + + player->move_delay_reset_counter = 0; + } +} void GetPlayerConfig() { @@ -753,7 +750,7 @@ static int getBeltDirFromBeltSwitchElement(int element) static int belt_move_dir[3] = { MV_LEFT, - MV_NO_MOVING, + MV_NONE, MV_RIGHT }; @@ -776,7 +773,7 @@ static void InitPlayerField(int x, int y, int element, boolean init_game) } else { - stored_player[0].use_murphy_graphic = TRUE; + stored_player[0].use_murphy = TRUE; } Feld[x][y] = EL_PLAYER_1; @@ -794,9 +791,6 @@ static void InitPlayerField(int x, int y, int element, boolean init_game) level.sp_block_last_field : level.block_last_field); -#if USE_NEW_BLOCK_STYLE -#if 1 - /* ---------- initialize player's last field block delay --------------- */ /* always start with reliable default value (no adjustment needed) */ @@ -810,49 +804,6 @@ static void InitPlayerField(int x, int y, int element, boolean init_game) if (game.use_block_last_field_bug) player->block_delay_adjustment = (player->block_last_field ? -1 : 1); -#if 0 - /* blocking the last field when moving was corrected in version 3.1.1 */ - if (game.use_block_last_field_bug) - { - /* even "not blocking" was blocking the last field for one frame */ - level.block_delay = (level.block_last_field ? 7 : 1); - level.sp_block_delay = (level.sp_block_last_field ? 7 : 1); - - level.block_last_field = TRUE; - level.sp_block_last_field = TRUE; - } -#endif - -#if 0 /* !!! THIS IS NOT A LEVEL SETTING => REMOVED !!! */ - level.block_delay = 8; /* when blocking, block 8 frames */ - level.sp_block_delay = 9; /* SP indeed blocks 9 frames, not 8 */ -#endif - -#if 0 - printf("::: %d, %d\n", level.block_delay, level.sp_block_delay); -#endif - -#else - -#if 1 - player->block_delay = (player->block_last_field ? - (element == EL_SP_MURPHY ? - level.sp_block_delay : - level.block_delay) : 0); -#else - player->block_delay = (element == EL_SP_MURPHY ? - (player->block_last_field ? 7 : 1) : - (player->block_last_field ? 7 : 1)); -#endif - -#endif - -#if 0 - printf("::: block_last_field == %d, block_delay = %d\n", - player->block_last_field, player->block_delay); -#endif -#endif - if (!options.network || player->connected) { player->active = TRUE; @@ -991,27 +942,6 @@ static void InitField(int x, int y, boolean init_game) GfxDir[x][y] = MovDir[x][y] = 1 << RND(4); break; -#if 0 - case EL_SP_EMPTY: - Feld[x][y] = EL_EMPTY; - break; -#endif - -#if 0 - case EL_EM_KEY_1_FILE: - Feld[x][y] = EL_EM_KEY_1; - break; - case EL_EM_KEY_2_FILE: - Feld[x][y] = EL_EM_KEY_2; - break; - case EL_EM_KEY_3_FILE: - Feld[x][y] = EL_EM_KEY_3; - break; - case EL_EM_KEY_4_FILE: - Feld[x][y] = EL_EM_KEY_4; - break; -#endif - case EL_CONVEYOR_BELT_1_SWITCH_LEFT: case EL_CONVEYOR_BELT_1_SWITCH_MIDDLE: case EL_CONVEYOR_BELT_1_SWITCH_RIGHT: @@ -1052,9 +982,32 @@ static void InitField(int x, int y, boolean init_game) game.light_time_left = level.time_light * FRAMES_PER_SECOND; break; + case EL_EMC_MAGIC_BALL: + if (game.ball_state) + Feld[x][y] = EL_EMC_MAGIC_BALL_ACTIVE; + break; + + case EL_EMC_MAGIC_BALL_SWITCH: + if (game.ball_state) + Feld[x][y] = EL_EMC_MAGIC_BALL_SWITCH_ACTIVE; + break; + default: +#if 1 + if (IS_CUSTOM_ELEMENT(element)) + { + if (CAN_MOVE(element)) + InitMovDir(x, y); + +#if USE_NEW_CUSTOM_VALUE + if (!element_info[element].use_last_ce_value || init_game) + CustomValue[x][y] = GET_NEW_CUSTOM_VALUE(Feld[x][y]); +#endif + } +#else if (IS_CUSTOM_ELEMENT(element) && CAN_MOVE(element)) InitMovDir(x, y); +#endif else if (IS_GROUP_ELEMENT(element)) { struct ElementGroupInfo *group = element_info[element].group; @@ -1079,6 +1032,25 @@ static void InitField(int x, int y, boolean init_game) } break; } + +#if 1 + if (!init_game) + CheckTriggeredElementChange(x, y, element, CE_CREATION_OF_X); +#endif + +#if 0 + +#if USE_NEW_CUSTOM_VALUE + +#if 1 + CustomValue[x][y] = GET_NEW_CUSTOM_VALUE(Feld[x][y]); +#else + CustomValue[x][y] = element_info[Feld[x][y]].custom_value_initial; +#endif + +#endif + +#endif } static inline void InitField_WithBug1(int x, int y, boolean init_game) @@ -1128,9 +1100,15 @@ inline void DrawGameValue_Keys(int key[MAX_NUM_KEYS]) /* currently only 4 of 8 possible keys are displayed */ for (i = 0; i < STD_NUM_KEYS; i++) + { if (key[i]) DrawMiniGraphicExt(drawto, DX_KEYS + i * MINI_TILEX, DY_KEYS, el2edimg(EL_KEY_1 + i)); + else + BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, + DOOR_GFX_PAGEX5 + XX_KEYS + i * MINI_TILEX, YY_KEYS, + MINI_TILEX, MINI_TILEY, DX_KEYS + i * MINI_TILEX, DY_KEYS); + } } inline void DrawGameValue_Score(int value) @@ -1253,17 +1231,6 @@ static void resolve_group_element(int group_element, int recursion_depth) element_info[element].in_group[group_nr] = TRUE; } } - -#if 0 - if (recursion_depth == 0 && group_element <= EL_GROUP_4) - { - printf("::: group %d: %d resolved elements\n", - group_element - EL_GROUP_START, group->num_elements_resolved); - for (i = 0; i < group->num_elements_resolved; i++) - printf("::: - %d ['%s']\n", group->element_resolved[i], - element_info[group->element_resolved[i]].token_name); - } -#endif } @@ -1277,7 +1244,7 @@ static void resolve_group_element(int group_element, int recursion_depth) static void InitGameEngine() { - int i, j, k, l; + int i, j, k, l, x, y; /* set game engine from tape file when re-playing, else from level file */ game.engine_version = (tape.playing ? tape.engine_version : @@ -1349,8 +1316,43 @@ static void InitGameEngine() game.use_block_last_field_bug = (game.engine_version < VERSION_IDENT(3,1,1,0)); + /* + Summary of bugfix/change: + Changed behaviour of CE changes with multiple changes per single frame. + + Fixed/changed in version: + 3.2.0-6 + + Description: + Before 3.2.0-6, only one single CE change was allowed in each engine frame. + This resulted in race conditions where CEs seem to behave strange in some + situations (where triggered CE changes were just skipped because there was + already a CE change on that tile in the playfield in that engine frame). + Since 3.2.0-6, this was changed to allow up to MAX_NUM_CHANGES_PER_FRAME. + (The number of changes per frame must be limited in any case, because else + it is easily possible to define CE changes that would result in an infinite + loop, causing the whole game to freeze. The MAX_NUM_CHANGES_PER_FRAME value + should be set large enough so that it would only be reached in cases where + the corresponding CE change conditions run into a loop. Therefore, it seems + to be reasonable to set MAX_NUM_CHANGES_PER_FRAME to the same value as the + maximal number of change pages for custom elements.) + + Affected levels/tapes: + Probably many. + */ + +#if USE_ONLY_ONE_CHANGE_PER_FRAME + game.max_num_changes_per_frame = 1; +#else + game.max_num_changes_per_frame = + (game.engine_version < VERSION_IDENT(3,2,0,6) ? 1 : 32); +#endif + /* ---------------------------------------------------------------------- */ + /* default scan direction: scan playfield from top/left to bottom/right */ + InitPlayfieldScanMode(CA_ARG_SCAN_MODE_NORMAL); + /* dynamically adjust element properties according to game engine version */ InitElementPropertiesEngine(game.engine_version); @@ -1373,25 +1375,20 @@ static void InitGameEngine() /* ---------- initialize player's initial move delay --------------------- */ -#if USE_NEW_MOVE_DELAY +#if 1 /* dynamically adjust player properties according to level information */ game.initial_move_delay_value = - (level.double_speed ? MOVE_DELAY_HIGH_SPEED : MOVE_DELAY_NORMAL_SPEED); - - /* dynamically adjust player properties according to game engine version */ - game.initial_move_delay = (game.engine_version <= VERSION_IDENT(2,0,1,0) ? - game.initial_move_delay_value : 0); + get_move_delay_from_stepsize(level.initial_player_stepsize); #else - /* dynamically adjust player properties according to game engine version */ - game.initial_move_delay = - (game.engine_version <= VERSION_IDENT(2,0,1,0) ? INITIAL_MOVE_DELAY_ON : - INITIAL_MOVE_DELAY_OFF); - /* dynamically adjust player properties according to level information */ game.initial_move_delay_value = (level.double_speed ? MOVE_DELAY_HIGH_SPEED : MOVE_DELAY_NORMAL_SPEED); #endif + /* dynamically adjust player properties according to game engine version */ + game.initial_move_delay = (game.engine_version <= VERSION_IDENT(2,0,1,0) ? + game.initial_move_delay_value : 0); + /* ---------- initialize player's initial push delay --------------------- */ /* dynamically adjust player properties according to game engine version */ @@ -1438,14 +1435,29 @@ static void InitGameEngine() ei->change->change_function = ch_delay->change_function; ei->change->post_change_function = ch_delay->post_change_function; + ei->change->can_change = TRUE; + ei->change->can_change_or_has_action = TRUE; + ei->has_change_event[CE_DELAY] = TRUE; -#if 1 SET_PROPERTY(ch_delay->element, EP_CAN_CHANGE, TRUE); -#endif + SET_PROPERTY(ch_delay->element, EP_CAN_CHANGE_OR_HAS_ACTION, TRUE); + } + + /* ---------- initialize internal run-time variables ------------- */ + + for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) + { + struct ElementInfo *ei = &element_info[EL_CUSTOM_START + i]; + + for (j = 0; j < ei->num_change_pages; j++) + { + ei->change_page[j].can_change_or_has_action = + (ei->change_page[j].can_change | + ei->change_page[j].has_action); + } } -#if 1 /* add change events from custom element configuration */ for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) { @@ -1453,7 +1465,7 @@ static void InitGameEngine() for (j = 0; j < ei->num_change_pages; j++) { - if (!ei->change_page[j].can_change) + if (!ei->change_page[j].can_change_or_has_action) continue; for (k = 0; k < NUM_CHANGE_EVENTS; k++) @@ -1470,19 +1482,6 @@ static void InitGameEngine() } } -#else - - /* add change events from custom element configuration */ - for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) - { - int element = EL_CUSTOM_START + i; - - /* only add custom elements that change after fixed/random frame delay */ - if (CAN_CHANGE(element) && HAS_CHANGE_EVENT(element, CE_DELAY)) - element_info[element].has_change_event[CE_DELAY] = TRUE; - } -#endif - /* ---------- initialize run-time trigger player and element ------------- */ for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) @@ -1493,6 +1492,8 @@ static void InitGameEngine() { ei->change_page[j].actual_trigger_element = EL_EMPTY; ei->change_page[j].actual_trigger_player = EL_PLAYER_1; + ei->change_page[j].actual_trigger_side = CH_SIDE_NONE; + ei->change_page[j].actual_trigger_ce_value = 0; } } @@ -1503,7 +1504,6 @@ static void InitGameEngine() for (j = 0; j < NUM_CHANGE_EVENTS; j++) trigger_events[i][j] = FALSE; -#if 1 /* add trigger events from element change event properties */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) { @@ -1511,7 +1511,7 @@ static void InitGameEngine() for (j = 0; j < ei->num_change_pages; j++) { - if (!ei->change_page[j].can_change) + if (!ei->change_page[j].can_change_or_has_action) continue; if (ei->change_page[j].has_event[CE_BY_OTHER_ACTION]) @@ -1537,14 +1537,6 @@ static void InitGameEngine() } } } -#else - /* add trigger events from element change event properties */ - for (i = 0; i < MAX_NUM_ELEMENTS; i++) - if (HAS_CHANGE_EVENT(i, CE_BY_OTHER_ACTION)) - for (j = 0; j < NUM_CHANGE_EVENTS; j++) - if (element_info[i].change->has_event[j]) - trigger_events[element_info[i].change->trigger_element][j] = TRUE; -#endif /* ---------- initialize push delay -------------------------------------- */ @@ -1574,16 +1566,11 @@ static void InitGameEngine() { if (IS_SP_ELEMENT(i)) { -#if USE_NEW_MOVE_STYLE /* set SP push delay to just enough to push under a falling zonk */ int delay = (game.engine_version >= VERSION_IDENT(3,1,1,0) ? 8 : 6); element_info[i].push_delay_fixed = delay; element_info[i].push_delay_random = 0; -#else - element_info[i].push_delay_fixed = 6; /* just enough to escape ... */ - element_info[i].push_delay_random = 0; /* ... from falling zonk */ -#endif } } } @@ -1603,26 +1590,23 @@ static void InitGameEngine() element_info[e].move_stepsize = move_stepsize_list[i].move_stepsize; } -#if 0 - /* ---------- initialize move dig/leave ---------------------------------- */ + /* ---------- initialize collect score ----------------------------------- */ + /* initialize collect score values for custom elements from initial value */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) - { - element_info[i].can_leave_element = FALSE; - element_info[i].can_leave_element_last = FALSE; - } -#endif + if (IS_CUSTOM_ELEMENT(i)) + element_info[i].collect_score = element_info[i].collect_score_initial; - /* ---------- initialize gem count --------------------------------------- */ + /* ---------- initialize collect count ----------------------------------- */ - /* initialize gem count values for each element */ + /* initialize collect count values for non-custom elements */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) if (!IS_CUSTOM_ELEMENT(i)) - element_info[i].collect_count = 0; + element_info[i].collect_count_initial = 0; - /* add gem count values for all elements from pre-defined list */ + /* add collect count values for all elements from pre-defined list */ for (i = 0; collect_count_list[i].element != EL_UNDEFINED; i++) - element_info[collect_count_list[i].element].collect_count = + element_info[collect_count_list[i].element].collect_count_initial = collect_count_list[i].count; /* ---------- initialize access direction -------------------------------- */ @@ -1636,8 +1620,63 @@ static void InitGameEngine() for (i = 0; access_direction_list[i].element != EL_UNDEFINED; i++) element_info[access_direction_list[i].element].access_direction = access_direction_list[i].direction; -} - + + /* ---------- initialize explosion content ------------------------------- */ + for (i = 0; i < MAX_NUM_ELEMENTS; i++) + { + if (IS_CUSTOM_ELEMENT(i)) + continue; + + for (y = 0; y < 3; y++) for (x = 0; x < 3; x++) + { + /* (content for EL_YAMYAM set at run-time with game.yamyam_content_nr) */ + + element_info[i].content.e[x][y] = + (i == EL_PLAYER_1 ? EL_EMERALD_YELLOW : + i == EL_PLAYER_2 ? EL_EMERALD_RED : + i == EL_PLAYER_3 ? EL_EMERALD : + i == EL_PLAYER_4 ? EL_EMERALD_PURPLE : + i == EL_MOLE ? EL_EMERALD_RED : + i == EL_PENGUIN ? EL_EMERALD_PURPLE : + i == EL_BUG ? (x == 1 && y == 1 ? EL_DIAMOND : EL_EMERALD) : + i == EL_BD_BUTTERFLY ? EL_BD_DIAMOND : + i == EL_SP_ELECTRON ? EL_SP_INFOTRON : + i == EL_AMOEBA_TO_DIAMOND ? level.amoeba_content : + i == EL_WALL_EMERALD ? EL_EMERALD : + i == EL_WALL_DIAMOND ? EL_DIAMOND : + i == EL_WALL_BD_DIAMOND ? EL_BD_DIAMOND : + i == EL_WALL_EMERALD_YELLOW ? EL_EMERALD_YELLOW : + i == EL_WALL_EMERALD_RED ? EL_EMERALD_RED : + i == EL_WALL_EMERALD_PURPLE ? EL_EMERALD_PURPLE : + i == EL_WALL_PEARL ? EL_PEARL : + i == EL_WALL_CRYSTAL ? EL_CRYSTAL : + EL_EMPTY); + } + } +} + +int get_num_special_action(int element, int action_first, int action_last) +{ + int num_special_action = 0; + int i, j; + + for (i = action_first; i <= action_last; i++) + { + boolean found = FALSE; + + for (j = 0; j < NUM_DIRECTIONS; j++) + if (el_act_dir2img(element, i, j) != + el_act_dir2img(element, ACTION_DEFAULT, j)) + found = TRUE; + + if (found) + num_special_action++; + else + break; + } + + return num_special_action; +} /* ============================================================================= @@ -1652,20 +1691,10 @@ void InitGame() boolean emulate_bd = TRUE; /* unless non-BOULDERDASH elements found */ boolean emulate_sb = TRUE; /* unless non-SOKOBAN elements found */ boolean emulate_sp = TRUE; /* unless non-SUPAPLEX elements found */ - int i, j, k, x, y; + int i, j, x, y; InitGameEngine(); -#if 0 -#if DEBUG -#if USE_NEW_AMOEBA_CODE - printf("Using new amoeba code.\n"); -#else - printf("Using old amoeba code.\n"); -#endif -#endif -#endif - /* don't play tapes over network */ network_playing = (options.network && !tape.playing); @@ -1698,15 +1727,18 @@ void InitGame() player->dynabombs_left = 0; player->dynabomb_xl = FALSE; - player->MovDir = MV_NO_MOVING; + player->MovDir = MV_NONE; player->MovPos = 0; player->GfxPos = 0; - player->GfxDir = MV_NO_MOVING; + player->GfxDir = MV_NONE; player->GfxAction = ACTION_DEFAULT; player->Frame = 0; player->StepFrame = 0; - player->use_murphy_graphic = FALSE; + player->use_murphy = FALSE; + player->artwork_element = + (level.use_artwork_element[i] ? level.artwork_element[i] : + player->element_nr); player->block_last_field = FALSE; /* initialized in InitPlayerField() */ player->block_delay_adjustment = 0; /* initialized in InitPlayerField() */ @@ -1717,7 +1749,7 @@ void InitGame() player->step_counter = 0; - player->last_move_dir = MV_NO_MOVING; + player->last_move_dir = MV_NONE; player->is_waiting = FALSE; player->is_moving = FALSE; @@ -1743,61 +1775,37 @@ void InitGame() player->special_action_bored = ACTION_DEFAULT; player->special_action_sleeping = ACTION_DEFAULT; - player->num_special_action_bored = 0; - player->num_special_action_sleeping = 0; - - /* determine number of special actions for bored and sleeping animation */ - for (j = ACTION_BORING_1; j <= ACTION_BORING_LAST; j++) - { - boolean found = FALSE; - - for (k = 0; k < NUM_DIRECTIONS; k++) - if (el_act_dir2img(player->element_nr, j, k) != - el_act_dir2img(player->element_nr, ACTION_DEFAULT, k)) - found = TRUE; - - if (found) - player->num_special_action_bored++; - else - break; - } - for (j = ACTION_SLEEPING_1; j <= ACTION_SLEEPING_LAST; j++) - { - boolean found = FALSE; - - for (k = 0; k < NUM_DIRECTIONS; k++) - if (el_act_dir2img(player->element_nr, j, k) != - el_act_dir2img(player->element_nr, ACTION_DEFAULT, k)) - found = TRUE; - - if (found) - player->num_special_action_sleeping++; - else - break; - } + /* set number of special actions for bored and sleeping animation */ + player->num_special_action_bored = + get_num_special_action(player->artwork_element, + ACTION_BORING_1, ACTION_BORING_LAST); + player->num_special_action_sleeping = + get_num_special_action(player->artwork_element, + ACTION_SLEEPING_1, ACTION_SLEEPING_LAST); player->switch_x = -1; player->switch_y = -1; -#if USE_DROP_BUGFIX player->drop_x = -1; player->drop_y = -1; -#endif player->show_envelope = 0; +#if 1 + SetPlayerMoveSpeed(player, level.initial_player_stepsize, TRUE); +#else player->move_delay = game.initial_move_delay; player->move_delay_value = game.initial_move_delay_value; + player->move_delay_value_next = -1; + player->move_delay_reset_counter = 0; -#if USE_NEW_PUSH_DELAY + player->cannot_move = FALSE; +#endif + player->push_delay = -1; /* initialized when pushing starts */ player->push_delay_value = game.initial_push_delay_value; -#else - player->push_delay = 0; - player->push_delay_value = game.initial_push_delay_value; -#endif player->drop_delay = 0; @@ -1822,7 +1830,7 @@ void InitGame() #if defined(NETWORK_AVALIABLE) /* initial null action */ if (network_playing) - SendToServer_MovePlayer(MV_NO_MOVING); + SendToServer_MovePlayer(MV_NONE); #endif ZX = ZY = -1; @@ -1834,7 +1842,7 @@ void InitGame() TimeLeft = level.time; TapeTime = 0; - ScreenMovDir = MV_NO_MOVING; + ScreenMovDir = MV_NONE; ScreenMovPos = 0; ScreenGfxPos = 0; @@ -1848,68 +1856,79 @@ void InitGame() game.light_time_left = 0; game.timegate_time_left = 0; game.switchgate_pos = 0; - game.balloon_dir = MV_NO_MOVING; + game.wind_direction = level.wind_direction_initial; game.gravity = level.initial_gravity; game.explosions_delayed = TRUE; + game.lenses_time_left = 0; + game.magnify_time_left = 0; + + game.ball_state = level.ball_state_initial; + game.ball_content_nr = 0; + game.envelope_active = FALSE; for (i = 0; i < NUM_BELTS; i++) { - game.belt_dir[i] = MV_NO_MOVING; + game.belt_dir[i] = MV_NONE; game.belt_dir_nr[i] = 3; /* not moving, next moving left */ } for (i = 0; i < MAX_NUM_AMOEBA; i++) AmoebaCnt[i] = AmoebaCnt2[i] = 0; - for (x = 0; x < lev_fieldx; x++) +#if 1 + SCAN_PLAYFIELD(x, y) +#else + for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++) +#endif { - for (y = 0; y < lev_fieldy; y++) - { - Feld[x][y] = level.field[x][y]; - MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0; - ChangeDelay[x][y] = 0; - ChangePage[x][y] = -1; - Store[x][y] = Store2[x][y] = StorePlayer[x][y] = Back[x][y] = 0; - AmoebaNr[x][y] = 0; - WasJustMoving[x][y] = 0; - WasJustFalling[x][y] = 0; - CheckCollision[x][y] = 0; - Stop[x][y] = FALSE; - Pushed[x][y] = FALSE; + Feld[x][y] = level.field[x][y]; + MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0; + ChangeDelay[x][y] = 0; + ChangePage[x][y] = -1; +#if USE_NEW_CUSTOM_VALUE + CustomValue[x][y] = 0; /* initialized in InitField() */ +#endif + Store[x][y] = Store2[x][y] = StorePlayer[x][y] = Back[x][y] = 0; + AmoebaNr[x][y] = 0; + WasJustMoving[x][y] = 0; + WasJustFalling[x][y] = 0; + CheckCollision[x][y] = 0; + Stop[x][y] = FALSE; + Pushed[x][y] = FALSE; - Changed[x][y] = FALSE; - ChangeEvent[x][y] = -1; + ChangeCount[x][y] = 0; + ChangeEvent[x][y] = -1; - ExplodePhase[x][y] = 0; - ExplodeDelay[x][y] = 0; - ExplodeField[x][y] = EX_TYPE_NONE; + ExplodePhase[x][y] = 0; + ExplodeDelay[x][y] = 0; + ExplodeField[x][y] = EX_TYPE_NONE; - RunnerVisit[x][y] = 0; - PlayerVisit[x][y] = 0; + RunnerVisit[x][y] = 0; + PlayerVisit[x][y] = 0; - GfxFrame[x][y] = 0; - GfxRandom[x][y] = INIT_GFX_RANDOM(); - GfxElement[x][y] = EL_UNDEFINED; - GfxAction[x][y] = ACTION_DEFAULT; - GfxDir[x][y] = MV_NO_MOVING; - } + GfxFrame[x][y] = 0; + GfxRandom[x][y] = INIT_GFX_RANDOM(); + GfxElement[x][y] = EL_UNDEFINED; + GfxAction[x][y] = ACTION_DEFAULT; + GfxDir[x][y] = MV_NONE; } - for (y = 0; y < lev_fieldy; y++) +#if 1 + SCAN_PLAYFIELD(x, y) +#else + for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) +#endif { - for (x = 0; x < lev_fieldx; x++) - { - if (emulate_bd && !IS_BD_ELEMENT(Feld[x][y])) - emulate_bd = FALSE; - if (emulate_sb && !IS_SB_ELEMENT(Feld[x][y])) - emulate_sb = FALSE; - if (emulate_sp && !IS_SP_ELEMENT(Feld[x][y])) - emulate_sp = FALSE; + if (emulate_bd && !IS_BD_ELEMENT(Feld[x][y])) + emulate_bd = FALSE; + if (emulate_sb && !IS_SB_ELEMENT(Feld[x][y])) + emulate_sb = FALSE; + if (emulate_sp && !IS_SP_ELEMENT(Feld[x][y])) + emulate_sp = FALSE; - InitField(x, y, TRUE); - } + InitField(x, y, TRUE); } InitBeltMovement(); @@ -1918,6 +1937,26 @@ void InitGame() emulate_sb ? EMU_SOKOBAN : emulate_sp ? EMU_SUPAPLEX : EMU_NONE); +#if USE_NEW_ALL_SLIPPERY + /* initialize type of slippery elements */ + for (i = 0; i < MAX_NUM_ELEMENTS; i++) + { + if (!IS_CUSTOM_ELEMENT(i)) + { + /* default: elements slip down either to the left or right randomly */ + element_info[i].slippery_type = SLIPPERY_ANY_RANDOM; + + /* SP style elements prefer to slip down on the left side */ + if (game.engine_version >= VERSION_IDENT(3,1,1,0) && IS_SP_ELEMENT(i)) + element_info[i].slippery_type = SLIPPERY_ANY_LEFT_RIGHT; + + /* BD style elements prefer to slip down on the left side */ + if (game.emulation == EMU_BOULDERDASH) + element_info[i].slippery_type = SLIPPERY_ANY_LEFT_RIGHT; + } + } +#endif + /* initialize explosion and ignition delay */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) { @@ -1933,13 +1972,8 @@ void InitGame() element_info[i].explosion_delay = last_phase - 1; element_info[i].ignition_delay = half_phase; -#if 0 - if (i == EL_BLACK_ORB) - element_info[i].ignition_delay = 0; -#else if (i == EL_BLACK_ORB) element_info[i].ignition_delay = 1; -#endif } #if 0 @@ -1953,7 +1987,7 @@ void InitGame() /* correct non-moving belts to start moving left */ for (i = 0; i < NUM_BELTS; i++) - if (game.belt_dir[i] == MV_NO_MOVING) + if (game.belt_dir[i] == MV_NONE) game.belt_dir_nr[i] = 3; /* not moving, next moving left */ /* check if any connected player was not found in playfield */ @@ -1981,10 +2015,10 @@ void InitGame() player->element_nr = some_player->element_nr; #endif -#if USE_NEW_BLOCK_STYLE + player->artwork_element = some_player->artwork_element; + player->block_last_field = some_player->block_last_field; player->block_delay_adjustment = some_player->block_delay_adjustment; -#endif StorePlayer[jx][jy] = player->element_nr; player->jx = player->last_jx = jx; @@ -2091,14 +2125,30 @@ void InitGame() int start_x = 0, start_y = 0; int found_rating = 0; int found_element = EL_UNDEFINED; + int player_nr = local_player->index_nr; +#if 1 + SCAN_PLAYFIELD(x, y) +#else for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) +#endif { int element = Feld[x][y]; int content; int xx, yy; boolean is_player; + if (level.use_start_element[player_nr] && + level.start_element[player_nr] == element && + found_rating < 4) + { + start_x = x; + start_y = y; + + found_rating = 4; + found_element = element; + } + if (!IS_CUSTOM_ELEMENT(element)) continue; @@ -2106,6 +2156,7 @@ void InitGame() { for (i = 0; i < element_info[element].num_change_pages; i++) { + /* check for player created from custom element as single target */ content = element_info[element].change_page[i].target_element; is_player = ELEM_IS_PLAYER(content); @@ -2122,7 +2173,8 @@ void InitGame() for (yy = 0; yy < 3; yy++) for (xx = 0; xx < 3; xx++) { - content = element_info[element].content[xx][yy]; + /* check for player created from custom element as explosion content */ + content = element_info[element].content.e[xx][yy]; is_player = ELEM_IS_PLAYER(content); if (is_player && (found_rating < 2 || element < found_element)) @@ -2139,7 +2191,10 @@ void InitGame() for (i = 0; i < element_info[element].num_change_pages; i++) { - content= element_info[element].change_page[i].target_content[xx][yy]; + /* check for player created from custom element as extended target */ + content = + element_info[element].change_page[i].target_content.e[xx][yy]; + is_player = ELEM_IS_PLAYER(content); if (is_player && (found_rating < 1 || element < found_element)) @@ -2164,7 +2219,6 @@ void InitGame() } else { -#if 1 scroll_x = (local_player->jx < SBX_Left + MIDPOSX ? SBX_Left : local_player->jx > SBX_Right + MIDPOSX ? SBX_Right : local_player->jx - MIDPOSX); @@ -2172,21 +2226,10 @@ void InitGame() scroll_y = (local_player->jy < SBY_Upper + MIDPOSY ? SBY_Upper : local_player->jy > SBY_Lower + MIDPOSY ? SBY_Lower : local_player->jy - MIDPOSY); -#else - scroll_x = SBX_Left; - scroll_y = SBY_Upper; - if (local_player->jx >= SBX_Left + MIDPOSX) - scroll_x = (local_player->jx <= SBX_Right + MIDPOSX ? - local_player->jx - MIDPOSX : - SBX_Right); - if (local_player->jy >= SBY_Upper + MIDPOSY) - scroll_y = (local_player->jy <= SBY_Lower + MIDPOSY ? - local_player->jy - MIDPOSY : - SBY_Lower); -#endif } - CloseDoor(DOOR_CLOSE_1); + if (!game.restart_level) + CloseDoor(DOOR_CLOSE_1); /* !!! FIX THIS (START) !!! */ if (level.game_engine_type == GAME_ENGINE_TYPE_EM) @@ -2210,43 +2253,47 @@ void InitGame() } /* !!! FIX THIS (END) !!! */ - /* copy default game door content to main double buffer */ - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, - DOOR_GFX_PAGEX5, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY); + if (!game.restart_level) + { + /* copy default game door content to main double buffer */ + BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, + DOOR_GFX_PAGEX5, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY); + } DrawGameDoorValues(); - UnmapGameButtons(); - UnmapTapeButtons(); - game_gadget[SOUND_CTRL_ID_MUSIC]->checked = setup.sound_music; - game_gadget[SOUND_CTRL_ID_LOOPS]->checked = setup.sound_loops; - game_gadget[SOUND_CTRL_ID_SIMPLE]->checked = setup.sound_simple; - MapGameButtons(); - MapTapeButtons(); + if (!game.restart_level) + { + UnmapGameButtons(); + UnmapTapeButtons(); + game_gadget[SOUND_CTRL_ID_MUSIC]->checked = setup.sound_music; + game_gadget[SOUND_CTRL_ID_LOOPS]->checked = setup.sound_loops; + game_gadget[SOUND_CTRL_ID_SIMPLE]->checked = setup.sound_simple; + MapGameButtons(); + MapTapeButtons(); - /* copy actual game door content to door double buffer for OpenDoor() */ - BlitBitmap(drawto, bitmap_db_door, - DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1); + /* copy actual game door content to door double buffer for OpenDoor() */ + BlitBitmap(drawto, bitmap_db_door, + DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1); - OpenDoor(DOOR_OPEN_ALL); + OpenDoor(DOOR_OPEN_ALL); - PlaySoundStereo(SND_GAME_STARTING, SOUND_MIDDLE); + PlaySoundStereo(SND_GAME_STARTING, SOUND_MIDDLE); - if (setup.sound_music) - PlayLevelMusic(); + if (setup.sound_music) + PlayLevelMusic(); - KeyboardAutoRepeatOffUnlessAutoplay(); + KeyboardAutoRepeatOffUnlessAutoplay(); - if (options.debug) - { - for (i = 0; i < MAX_PLAYERS; i++) - printf("Player %d %sactive.\n", - i + 1, (stored_player[i].active ? "" : "not ")); + if (options.debug) + { + for (i = 0; i < MAX_PLAYERS; i++) + printf("Player %d %sactive.\n", + i + 1, (stored_player[i].active ? "" : "not ")); + } } -#if 0 - printf("::: starting game [%d]\n", FrameCounter); -#endif + game.restart_level = FALSE; } void UpdateEngineValues(int actual_scroll_x, int actual_scroll_y) @@ -2342,7 +2389,7 @@ void InitMovDir(int x, int y) if (move_direction_initial == MV_START_PREVIOUS) { - if (MovDir[x][y] != MV_NO_MOVING) + if (MovDir[x][y] != MV_NONE) return; move_direction_initial = MV_START_AUTOMATIC; @@ -2368,11 +2415,9 @@ void InitMovDir(int x, int y) else if (move_pattern == MV_ALONG_LEFT_SIDE || move_pattern == MV_ALONG_RIGHT_SIDE) { -#if 1 /* use random direction as default start direction */ if (game.engine_version >= VERSION_IDENT(3,1,0,0)) MovDir[x][y] = 1 << RND(4); -#endif for (i = 0; i < NUM_DIRECTIONS; i++) { @@ -2458,13 +2503,8 @@ void GameWon() if (local_player->MovPos) return; -#if 1 if (tape.auto_play) /* tape might already be stopped here */ tape.auto_play_level_solved = TRUE; -#else - if (tape.playing && tape.auto_play) - tape.auto_play_level_solved = TRUE; -#endif local_player->LevelSolved = FALSE; @@ -2480,12 +2520,17 @@ void GameWon() { if (!tape.playing && !setup.sound_loops) PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MIDDLE); - if (TimeLeft > 0 && !(TimeLeft % 10)) - RaiseScore(level.score[SC_TIME_BONUS]); - if (TimeLeft > 100 && !(TimeLeft % 10)) + + if (TimeLeft > 100 && TimeLeft % 10 == 0) + { TimeLeft -= 10; + RaiseScore(level.score[SC_TIME_BONUS] * 10); + } else + { TimeLeft--; + RaiseScore(level.score[SC_TIME_BONUS]); + } DrawGameValue_Time(TimeLeft); @@ -2508,12 +2553,17 @@ void GameWon() { if (!tape.playing && !setup.sound_loops) PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MIDDLE); - if (TimePlayed < 999 && !(TimePlayed % 10)) - RaiseScore(level.score[SC_TIME_BONUS]); - if (TimePlayed < 900 && !(TimePlayed % 10)) + + if (TimePlayed < 900 && TimePlayed % 10 == 0) + { TimePlayed += 10; + RaiseScore(level.score[SC_TIME_BONUS] * 10); + } else + { TimePlayed++; + RaiseScore(level.score[SC_TIME_BONUS]); + } DrawGameValue_Time(TimePlayed); @@ -2540,7 +2590,7 @@ void GameWon() PlayLevelSoundElementAction(ExitX, ExitY, element, ACTION_CLOSING); } - /* Hero disappears */ + /* player disappears */ if (ExitX >= 0 && ExitY >= 0) DrawLevelField(ExitX, ExitY); @@ -2722,43 +2772,29 @@ void InitMovingField(int x, int y, int direction) if (!WasJustMoving[x][y] || direction != MovDir[x][y]) ResetGfxAnimation(x, y); -#if USE_CAN_MOVE_NOT_MOVING - MovDir[x][y] = direction; GfxDir[x][y] = direction; GfxAction[x][y] = (direction == MV_DOWN && CAN_FALL(element) ? ACTION_FALLING : ACTION_MOVING); + /* this is needed for CEs with property "can move" / "not moving" */ + if (getElementMoveStepsize(x, y) != 0) /* moving or being moved */ { if (Feld[newx][newy] == EL_EMPTY) Feld[newx][newy] = EL_BLOCKED; MovDir[newx][newy] = MovDir[x][y]; + +#if USE_NEW_CUSTOM_VALUE + CustomValue[newx][newy] = CustomValue[x][y]; +#endif + GfxFrame[newx][newy] = GfxFrame[x][y]; GfxRandom[newx][newy] = GfxRandom[x][y]; GfxAction[newx][newy] = GfxAction[x][y]; GfxDir[newx][newy] = GfxDir[x][y]; } - -#else - - MovDir[newx][newy] = MovDir[x][y] = direction; - GfxDir[x][y] = direction; - - if (Feld[newx][newy] == EL_EMPTY) - Feld[newx][newy] = EL_BLOCKED; - - if (direction == MV_DOWN && CAN_FALL(element)) - GfxAction[x][y] = ACTION_FALLING; - else - GfxAction[x][y] = ACTION_MOVING; - - GfxFrame[newx][newy] = GfxFrame[x][y]; - GfxRandom[newx][newy] = GfxRandom[x][y]; - GfxAction[newx][newy] = GfxAction[x][y]; - GfxDir[newx][newy] = GfxDir[x][y]; -#endif } void Moving2Blocked(int x, int y, int *goes_to_x, int *goes_to_y) @@ -2835,6 +2871,10 @@ static void RemoveField(int x, int y) MovDir[x][y] = 0; MovDelay[x][y] = 0; +#if USE_NEW_CUSTOM_VALUE + CustomValue[x][y] = 0; +#endif + AmoebaNr[x][y] = 0; ChangeDelay[x][y] = 0; ChangePage[x][y] = -1; @@ -2846,7 +2886,7 @@ static void RemoveField(int x, int y) GfxElement[x][y] = EL_UNDEFINED; GfxAction[x][y] = ACTION_DEFAULT; - GfxDir[x][y] = MV_NO_MOVING; + GfxDir[x][y] = MV_NONE; } void RemoveMovingField(int x, int y) @@ -2861,10 +2901,7 @@ void RemoveMovingField(int x, int y) if (IS_MOVING(x, y)) { Moving2Blocked(x, y, &newx, &newy); -#if 0 - if (Feld[newx][newy] != EL_BLOCKED) - return; -#else + if (Feld[newx][newy] != EL_BLOCKED) { /* element is moving, but target field is not free (blocked), but @@ -2879,7 +2916,6 @@ void RemoveMovingField(int x, int y) return; } -#endif } else if (element == EL_BLOCKED) { @@ -2926,19 +2962,10 @@ void DrawDynamite(int x, int y) frame = getGraphicAnimationFrame(graphic, GfxFrame[x][y]); -#if 1 if (Back[x][y] || Store[x][y]) DrawGraphicThruMask(sx, sy, graphic, frame); else DrawGraphic(sx, sy, graphic, frame); -#else - if (game.emulation == EMU_SUPAPLEX) - DrawGraphic(sx, sy, IMG_SP_DISK_RED, frame); - else if (Store[x][y]) - DrawGraphicThruMask(sx, sy, graphic, frame); - else - DrawGraphic(sx, sy, graphic, frame); -#endif } void CheckDynamite(int x, int y) @@ -2956,15 +2983,7 @@ void CheckDynamite(int x, int y) } } -#if 1 StopLevelSoundActionIfLoop(x, y, ACTION_ACTIVE); -#else - if (Feld[x][y] == EL_DYNAMITE_ACTIVE || - Feld[x][y] == EL_SP_DISK_RED_ACTIVE) - StopSound(SND_DYNAMITE_ACTIVE); - else - StopSound(SND_DYNABOMB_ACTIVE); -#endif Bang(x, y); } @@ -2980,7 +2999,6 @@ void DrawRelocatePlayer(struct PlayerInfo *player) if (level.instant_relocation) { -#if 1 int offset = (setup.scroll_delay ? 3 : 0); if (!IN_VIS_FIELD(SCREENX(jx), SCREENY(jy))) @@ -3011,74 +3029,11 @@ void DrawRelocatePlayer(struct PlayerInfo *player) if (scroll_y < SBY_Upper || scroll_y > SBY_Lower) scroll_y = (scroll_y < SBY_Upper ? SBY_Upper : SBY_Lower); } -#else - scroll_x += (local_player->jx - old_jx); - scroll_y += (local_player->jy - old_jy); - - /* don't scroll over playfield boundaries */ - if (scroll_x < SBX_Left || scroll_x > SBX_Right) - scroll_x = (scroll_x < SBX_Left ? SBX_Left : SBX_Right); - - /* don't scroll over playfield boundaries */ - if (scroll_y < SBY_Upper || scroll_y > SBY_Lower) - scroll_y = (scroll_y < SBY_Upper ? SBY_Upper : SBY_Lower); -#endif RedrawPlayfield(TRUE, 0,0,0,0); } else { -#if 1 -#if 0 - int offset = (setup.scroll_delay ? 3 : 0); -#endif - int scroll_xx = -999, scroll_yy = -999; - - ScrollScreen(NULL, SCROLL_GO_ON); /* scroll last frame to full tile */ - - while (scroll_xx != scroll_x || scroll_yy != scroll_y) - { - int dx = 0, dy = 0; - int fx = FX, fy = FY; - - scroll_xx = (local_player->jx < SBX_Left + MIDPOSX ? SBX_Left : - local_player->jx > SBX_Right + MIDPOSX ? SBX_Right : - local_player->jx - MIDPOSX); - - scroll_yy = (local_player->jy < SBY_Upper + MIDPOSY ? SBY_Upper : - local_player->jy > SBY_Lower + MIDPOSY ? SBY_Lower : - local_player->jy - MIDPOSY); - - dx = (scroll_xx < scroll_x ? +1 : scroll_xx > scroll_x ? -1 : 0); - dy = (scroll_yy < scroll_y ? +1 : scroll_yy > scroll_y ? -1 : 0); - -#if 1 - if (dx == 0 && dy == 0) /* no scrolling needed at all */ - break; -#else - if (scroll_xx == scroll_x && scroll_yy == scroll_y) - break; -#endif - - scroll_x -= dx; - scroll_y -= dy; - - fx += dx * TILEX / 2; - fy += dy * TILEY / 2; - - ScrollLevel(dx, dy); - DrawAllPlayers(); - - /* scroll in two steps of half tile size to make things smoother */ - BlitBitmap(drawto_field, window, fx, fy, SXSIZE, SYSIZE, SX, SY); - FlushDisplay(); - Delay(wait_delay_value); - - /* scroll second step to align at full tile size */ - BackToFront(); - Delay(wait_delay_value); - } -#else int scroll_xx = -999, scroll_yy = -999; ScrollScreen(NULL, SCROLL_GO_ON); /* scroll last frame to full tile */ @@ -3099,13 +3054,8 @@ void DrawRelocatePlayer(struct PlayerInfo *player) dx = (scroll_xx < scroll_x ? +1 : scroll_xx > scroll_x ? -1 : 0); dy = (scroll_yy < scroll_y ? +1 : scroll_yy > scroll_y ? -1 : 0); -#if 1 if (dx == 0 && dy == 0) /* no scrolling needed at all */ break; -#else - if (scroll_xx == scroll_x && scroll_yy == scroll_y) - break; -#endif scroll_x -= dx; scroll_y -= dy; @@ -3125,7 +3075,6 @@ void DrawRelocatePlayer(struct PlayerInfo *player) BackToFront(); Delay(wait_delay_value); } -#endif DrawPlayer(player); BackToFront(); @@ -3135,12 +3084,9 @@ void DrawRelocatePlayer(struct PlayerInfo *player) void RelocatePlayer(int jx, int jy, int el_player_raw) { -#if 1 - int el_player = GET_VALID_PLAYER_ELEMENT(el_player_raw); -#else - int el_player = (el_player_raw == EL_SP_MURPHY ? EL_PLAYER_1 :el_player_raw); -#endif - struct PlayerInfo *player = &stored_player[el_player - EL_PLAYER_1]; + int el_player = GET_PLAYER_ELEMENT(el_player_raw); + int player_nr = GET_PLAYER_NR(el_player); + struct PlayerInfo *player = &stored_player[player_nr]; boolean ffwd_delay = (tape.playing && tape.fast_forward); boolean no_delay = (tape.warp_forward); int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay); @@ -3153,25 +3099,10 @@ void RelocatePlayer(int jx, int jy, int el_player_raw) int move_dir_horiz = (jx < old_jx ? MV_LEFT : jx > old_jx ? MV_RIGHT : 0); int move_dir_vert = (jy < old_jy ? MV_UP : jy > old_jy ? MV_DOWN : 0); -#if 1 int enter_side_horiz = MV_DIR_OPPOSITE(move_dir_horiz); int enter_side_vert = MV_DIR_OPPOSITE(move_dir_vert); int leave_side_horiz = move_dir_horiz; int leave_side_vert = move_dir_vert; -#else - static int trigger_sides[4][2] = - { - /* enter side leave side */ - { CH_SIDE_RIGHT, CH_SIDE_LEFT }, /* moving left */ - { CH_SIDE_LEFT, CH_SIDE_RIGHT }, /* moving right */ - { CH_SIDE_BOTTOM, CH_SIDE_TOP }, /* moving up */ - { CH_SIDE_TOP, CH_SIDE_BOTTOM } /* moving down */ - }; - int enter_side_horiz = trigger_sides[MV_DIR_BIT(move_dir_horiz)][0]; - int enter_side_vert = trigger_sides[MV_DIR_BIT(move_dir_vert)][0]; - int leave_side_horiz = trigger_sides[MV_DIR_BIT(move_dir_horiz)][1]; - int leave_side_vert = trigger_sides[MV_DIR_BIT(move_dir_vert)][1]; -#endif int enter_side = enter_side_horiz | enter_side_vert; int leave_side = leave_side_horiz | leave_side_vert; @@ -3194,11 +3125,7 @@ void RelocatePlayer(int jx, int jy, int el_player_raw) ScrollPlayer(player, SCROLL_GO_ON); ScrollScreen(NULL, SCROLL_GO_ON); -#if USE_NEW_MOVE_DELAY AdvanceFrameAndPlayerCounters(player->index_nr); -#else - FrameCounter++; -#endif DrawPlayer(player); @@ -3212,7 +3139,6 @@ void RelocatePlayer(int jx, int jy, int el_player_raw) player->is_moving = FALSE; } -#if 1 if (IS_CUSTOM_ELEMENT(old_element)) CheckElementChangeByPlayer(old_jx, old_jy, old_element, CE_LEFT_BY_PLAYER, @@ -3221,7 +3147,6 @@ void RelocatePlayer(int jx, int jy, int el_player_raw) CheckTriggeredElementChangeByPlayer(old_jx, old_jy, old_element, CE_PLAYER_LEAVES_X, player->index_bit, leave_side); -#endif Feld[jx][jy] = el_player; InitPlayerField(jx, jy, el_player, TRUE); @@ -3232,69 +3157,29 @@ void RelocatePlayer(int jx, int jy, int el_player_raw) InitField(jx, jy, FALSE); } -#if 1 if (player == local_player) /* only visually relocate local player */ DrawRelocatePlayer(player); -#endif -#if 1 - TestIfHeroTouchesBadThing(jx, jy); + TestIfPlayerTouchesBadThing(jx, jy); TestIfPlayerTouchesCustomElement(jx, jy); -#endif -#if 0 - printf("::: %d,%d: %d\n", jx, jy-1, Changed[jx][jy-1]); -#endif + if (IS_CUSTOM_ELEMENT(element)) + CheckElementChangeByPlayer(jx, jy, element, CE_ENTERED_BY_PLAYER, + player->index_bit, enter_side); -#if 0 -#if 0 - /* needed to allow change of walkable custom element by entering player */ - if (!(Changed[jx][jy] & CH_EVENT_BIT(CE_ENTERED_BY_PLAYER))) - Changed[jx][jy] = 0; /* allow another change (but prevent loop) */ -#else - /* needed to allow change of walkable custom element by entering player */ - Changed[jx][jy] = 0; /* allow another change */ -#endif -#endif - -#if 0 - printf("::: player entering %d, %d from %s ...\n", jx, jy, - enter_side == MV_LEFT ? "left" : - enter_side == MV_RIGHT ? "right" : - enter_side == MV_UP ? "top" : - enter_side == MV_DOWN ? "bottom" : "oops! no idea!"); -#endif - -#if 1 - if (IS_CUSTOM_ELEMENT(element)) - CheckElementChangeByPlayer(jx, jy, element, CE_ENTERED_BY_PLAYER, - player->index_bit, enter_side); - - CheckTriggeredElementChangeByPlayer(jx, jy, element, - CE_PLAYER_ENTERS_X, + CheckTriggeredElementChangeByPlayer(jx, jy, element, CE_PLAYER_ENTERS_X, player->index_bit, enter_side); -#endif } void Explode(int ex, int ey, int phase, int mode) { int x, y; -#if 0 - int num_phase = 9; -#endif + int last_phase; + int border_element; /* !!! eliminate this variable !!! */ int delay = (game.emulation == EMU_SUPAPLEX ? 3 : 2); -#if 1 - int last_phase; -#else - int last_phase = num_phase * delay; - int half_phase = (num_phase / 2) * delay; - int first_phase_after_start = EX_PHASE_START + 1; -#endif - int border_element; - if (game.explosions_delayed) { ExplodeField[ex][ey] = mode; @@ -3304,10 +3189,7 @@ void Explode(int ex, int ey, int phase, int mode) if (phase == EX_PHASE_START) /* initialize 'Store[][]' field */ { int center_element = Feld[ex][ey]; - -#if 0 - printf("::: start explosion %d,%d [%d]\n", ex, ey, FrameCounter); -#endif + int artwork_element, explosion_element; /* set these values later */ #if 0 /* --- This is only really needed (and now handled) in "Impact()". --- */ @@ -3318,14 +3200,12 @@ void Explode(int ex, int ey, int phase, int mode) return; #endif -#if 1 +#if 0 + /* !!! at this place, the center element may be EL_BLOCKED !!! */ if (mode == EX_TYPE_NORMAL || mode == EX_TYPE_CENTER || mode == EX_TYPE_CROSS) - PlayLevelSoundAction(ex, ey, ACTION_EXPLODING); -#else - if (mode == EX_TYPE_NORMAL || mode == EX_TYPE_CENTER) - PlayLevelSoundAction(ex, ey, ACTION_EXPLODING); + PlayLevelSoundElementAction(ex, ey, artwork_element, ACTION_EXPLODING); #endif /* remove things displayed in background while burning dynamite */ @@ -3340,17 +3220,34 @@ void Explode(int ex, int ey, int phase, int mode) Feld[ex][ey] = center_element; } -#if 1 + /* now "center_element" is finally determined -- set related values now */ + artwork_element = center_element; /* for custom player artwork */ + explosion_element = center_element; /* for custom player artwork */ + + if (IS_PLAYER(ex, ey)) + { + int player_nr = GET_PLAYER_NR(StorePlayer[ex][ey]); + + artwork_element = stored_player[player_nr].artwork_element; + + if (level.use_explosion_element[player_nr]) + { + explosion_element = level.explosion_element[player_nr]; + artwork_element = explosion_element; + } + } #if 1 - last_phase = element_info[center_element].explosion_delay + 1; -#else - last_phase = element_info[center_element].explosion_delay; + if (mode == EX_TYPE_NORMAL || + mode == EX_TYPE_CENTER || + mode == EX_TYPE_CROSS) + PlayLevelSoundElementAction(ex, ey, artwork_element, ACTION_EXPLODING); #endif -#if 0 - printf("::: %d -> %d\n", center_element, last_phase); -#endif +#if 1 + last_phase = element_info[explosion_element].explosion_delay + 1; +#else + last_phase = element_info[center_element].explosion_delay + 1; #endif for (y = ey - 1; y <= ey + 1; y++) for (x = ex - 1; x <= ex + 1; x++) @@ -3359,24 +3256,10 @@ void Explode(int ex, int ey, int phase, int mode) int yy = y - ey + 1; int element; -#if 1 -#if 1 if (!IN_LEV_FIELD(x, y) || (mode & EX_TYPE_SINGLE_TILE && (x != ex || y != ey)) || (mode == EX_TYPE_CROSS && (x != ex && y != ey))) continue; -#else - if (!IN_LEV_FIELD(x, y) || - (mode != EX_TYPE_NORMAL && (x != ex || y != ey))) - continue; -#endif -#else - if (!IN_LEV_FIELD(x, y) || - ((mode != EX_TYPE_NORMAL || - center_element == EL_AMOEBA_TO_DIAMOND) && - (x != ex || y != ey))) - continue; -#endif element = Feld[x][y]; @@ -3388,32 +3271,11 @@ void Explode(int ex, int ey, int phase, int mode) RemoveMovingField(x, y); } -#if 1 - -#if 0 - if (IS_EXPLOSION_PROOF(element)) - continue; -#else /* indestructible elements can only explode in center (but not flames) */ -#if 1 if ((IS_EXPLOSION_PROOF(element) && (x != ex || y != ey || mode == EX_TYPE_BORDER)) || element == EL_FLAMES) continue; -#else - if ((IS_EXPLOSION_PROOF(element) && (x != ex || y != ey)) || - element == EL_FLAMES) - continue; -#endif -#endif - -#else - if ((IS_INDESTRUCTIBLE(element) && - (game.engine_version < VERSION_IDENT(2,2,0,0) || - (!IS_WALKABLE_OVER(element) && !IS_WALKABLE_UNDER(element)))) || - element == EL_FLAMES) - continue; -#endif /* no idea why this was changed from 3.0.8 to 3.1.0 -- this causes buggy behaviour, for example when touching a yamyam that explodes to rocks @@ -3430,50 +3292,22 @@ void Explode(int ex, int ey, int phase, int mode) if (IS_ACTIVE_BOMB(element)) { /* re-activate things under the bomb like gate or penguin */ -#if 1 Feld[x][y] = (Back[x][y] ? Back[x][y] : EL_EMPTY); Back[x][y] = 0; -#else - Feld[x][y] = (Store[x][y] ? Store[x][y] : EL_EMPTY); - Store[x][y] = 0; -#endif - -#if 0 - printf("::: %d,%d: %d %s [%d, %d]\n", x, y, Feld[x][y], - element_info[Feld[x][y]].token_name, - Store[x][y], Store2[x][y]); -#endif } continue; } /* save walkable background elements while explosion on same tile */ -#if 0 - if (IS_INDESTRUCTIBLE(element)) - Back[x][y] = element; -#else -#if 1 -#if 1 if (IS_WALKABLE(element) && IS_INDESTRUCTIBLE(element) && (x != ex || y != ey || mode == EX_TYPE_BORDER)) Back[x][y] = element; -#else - if (IS_WALKABLE(element) && IS_INDESTRUCTIBLE(element) && - (x != ex || y != ey)) - Back[x][y] = element; -#endif -#else - if (IS_WALKABLE(element) && IS_INDESTRUCTIBLE(element)) - Back[x][y] = element; -#endif -#endif /* ignite explodable elements reached by other explosion */ if (element == EL_EXPLOSION) element = Store2[x][y]; -#if 1 if (AmoebaNr[x][y] && (element == EL_AMOEBA_FULL || element == EL_BD_AMOEBA || @@ -3484,10 +3318,14 @@ void Explode(int ex, int ey, int phase, int mode) } RemoveField(x, y); -#endif if (IS_PLAYER(ex, ey) && !PLAYER_EXPLOSION_PROTECTED(ex, ey)) { +#if 1 + int player_nr = StorePlayer[ex][ey] - EL_PLAYER_1; + + Store[x][y] = EL_PLAYER_IS_EXPLODING_1 + player_nr; +#else switch(StorePlayer[ex][ey]) { case EL_PLAYER_2: @@ -3504,15 +3342,33 @@ void Explode(int ex, int ey, int phase, int mode) Store[x][y] = EL_PLAYER_IS_EXPLODING_1; break; } +#endif -#if 1 - if (PLAYERINFO(ex, ey)->use_murphy_graphic) + if (PLAYERINFO(ex, ey)->use_murphy) Store[x][y] = EL_EMPTY; + } +#if 1 + /* !!! check this case -- currently needed for rnd_rado_negundo_v, + !!! levels 015 018 019 020 021 022 023 026 027 028 !!! */ + else if (ELEM_IS_PLAYER(center_element)) + Store[x][y] = EL_EMPTY; + else if (center_element == EL_YAMYAM) + Store[x][y] = level.yamyam_content[game.yamyam_content_nr].e[xx][yy]; + else if (element_info[center_element].content.e[xx][yy] != EL_EMPTY) + Store[x][y] = element_info[center_element].content.e[xx][yy]; +#if 1 + /* needed because EL_BD_BUTTERFLY is not defined as "CAN_EXPLODE" + (killing EL_BD_BUTTERFLY with dynamite would result in BD diamond + otherwise) -- FIX THIS !!! */ + else if (!CAN_EXPLODE(element) && element != EL_BD_BUTTERFLY) + Store[x][y] = element_info[element].content.e[1][1]; #else - if (game.emulation == EMU_SUPAPLEX) - Store[x][y] = EL_EMPTY; + else if (!CAN_EXPLODE(element)) + Store[x][y] = element_info[element].content.e[1][1]; #endif - } + else + Store[x][y] = EL_EMPTY; +#else else if (center_element == EL_MOLE) Store[x][y] = EL_EMERALD_RED; else if (center_element == EL_PENGUIN) @@ -3526,10 +3382,10 @@ void Explode(int ex, int ey, int phase, int mode) else if (center_element == EL_AMOEBA_TO_DIAMOND) Store[x][y] = level.amoeba_content; else if (center_element == EL_YAMYAM) - Store[x][y] = level.yamyam_content[game.yamyam_content_nr][xx][yy]; + Store[x][y] = level.yamyam_content[game.yamyam_content_nr].e[xx][yy]; else if (IS_CUSTOM_ELEMENT(center_element) && - element_info[center_element].content[xx][yy] != EL_EMPTY) - Store[x][y] = element_info[center_element].content[xx][yy]; + element_info[center_element].content.e[xx][yy] != EL_EMPTY) + Store[x][y] = element_info[center_element].content.e[xx][yy]; else if (element == EL_WALL_EMERALD) Store[x][y] = EL_EMERALD; else if (element == EL_WALL_DIAMOND) @@ -3547,57 +3403,20 @@ void Explode(int ex, int ey, int phase, int mode) else if (element == EL_WALL_CRYSTAL) Store[x][y] = EL_CRYSTAL; else if (IS_CUSTOM_ELEMENT(element) && !CAN_EXPLODE(element)) - Store[x][y] = element_info[element].content[1][1]; + Store[x][y] = element_info[element].content.e[1][1]; else Store[x][y] = EL_EMPTY; +#endif if (x != ex || y != ey || mode == EX_TYPE_BORDER || center_element == EL_AMOEBA_TO_DIAMOND) Store2[x][y] = element; -#if 0 - printf("::: %d,%d: %d %s\n", x, y, Store2[x][y], - element_info[Store2[x][y]].token_name); -#endif - -#if 0 - if (AmoebaNr[x][y] && - (element == EL_AMOEBA_FULL || - element == EL_BD_AMOEBA || - element == EL_AMOEBA_GROWING)) - { - AmoebaCnt[AmoebaNr[x][y]]--; - AmoebaCnt2[AmoebaNr[x][y]]--; - } - -#if 1 - RemoveField(x, y); -#else - MovDir[x][y] = MovPos[x][y] = 0; - GfxDir[x][y] = MovDir[x][y]; - AmoebaNr[x][y] = 0; -#endif -#endif - Feld[x][y] = EL_EXPLOSION; -#if 1 - GfxElement[x][y] = center_element; -#else - GfxElement[x][y] = EL_UNDEFINED; -#endif + GfxElement[x][y] = artwork_element; ExplodePhase[x][y] = 1; -#if 1 ExplodeDelay[x][y] = last_phase; -#endif - -#if 0 -#if 1 - GfxFrame[x][y] = 0; /* animation does not start until next frame */ -#else - GfxFrame[x][y] = -1; /* animation does not start until next frame */ -#endif -#endif Stop[x][y] = TRUE; } @@ -3606,11 +3425,6 @@ void Explode(int ex, int ey, int phase, int mode) game.yamyam_content_nr = (game.yamyam_content_nr + 1) % level.num_yamyam_contents; -#if 0 - printf("::: %d,%d: %d %s [%d]\n", ex + 1, ey, Feld[ex + 1][ey], - element_info[Feld[ex + 1][ey]].token_name, Store2[ex + 1][ey]); -#endif - return; } @@ -3620,18 +3434,10 @@ void Explode(int ex, int ey, int phase, int mode) x = ex; y = ey; -#if 1 if (phase == 1) GfxFrame[x][y] = 0; /* restart explosion animation */ -#endif - -#if 0 - printf(":X: phase == %d [%d]\n", phase, GfxFrame[x][y]); -#endif -#if 1 last_phase = ExplodeDelay[x][y]; -#endif ExplodePhase[x][y] = (phase < last_phase ? phase + 1 : 0); @@ -3639,6 +3445,7 @@ void Explode(int ex, int ey, int phase, int mode) /* activate this even in non-DEBUG version until cause for crash in getGraphicAnimationFrame() (see below) is found and eliminated */ + #endif #if 1 @@ -3653,133 +3460,46 @@ void Explode(int ex, int ey, int phase, int mode) } #endif -#if 1 - border_element = Store2[x][y]; -#if 1 if (IS_PLAYER(x, y) && !PLAYER_EXPLOSION_PROTECTED(x, y)) border_element = StorePlayer[x][y]; -#else - if (IS_PLAYER(x, y)) - border_element = StorePlayer[x][y]; -#endif - -#if 0 - printf("::: %d,%d: %d %s [%d]\n", x, y, border_element, - element_info[border_element].token_name, Store2[x][y]); -#endif - -#if 0 - printf("::: phase == %d\n", phase); -#endif if (phase == element_info[border_element].ignition_delay || phase == last_phase) { boolean border_explosion = FALSE; -#if 1 -#if 1 if (IS_PLAYER(x, y) && PLAYERINFO(x, y)->present && !PLAYER_EXPLOSION_PROTECTED(x, y)) -#else - if (IS_PLAYER(x, y) && PLAYERINFO(x, y)->present) -#endif -#else - if (IS_PLAYER(x, y)) -#endif { - KillHeroUnlessExplosionProtected(x, y); + KillPlayerUnlessExplosionProtected(x, y); border_explosion = TRUE; - -#if 0 - if (phase == last_phase) - printf("::: IS_PLAYER\n"); -#endif } else if (CAN_EXPLODE_BY_EXPLOSION(border_element)) { -#if 0 - printf("::: %d,%d: %d %s\n", x, y, border_element, - element_info[border_element].token_name); -#endif - Feld[x][y] = Store2[x][y]; Store2[x][y] = 0; Bang(x, y); border_explosion = TRUE; - -#if 0 - if (phase == last_phase) - printf("::: CAN_EXPLODE_BY_EXPLOSION\n"); -#endif } else if (border_element == EL_AMOEBA_TO_DIAMOND) { AmoebeUmwandeln(x, y); Store2[x][y] = 0; border_explosion = TRUE; - -#if 0 - if (phase == last_phase) - printf("::: EL_AMOEBA_TO_DIAMOND [%d, %d] [%d]\n", - element_info[border_element].explosion_delay, - element_info[border_element].ignition_delay, - phase); -#endif } -#if 1 /* if an element just explodes due to another explosion (chain-reaction), do not immediately end the new explosion when it was the last frame of the explosion (as it would be done in the following "if"-statement!) */ if (border_explosion && phase == last_phase) return; -#endif - } - -#else - - if (phase == first_phase_after_start) - { - int element = Store2[x][y]; - - if (element == EL_BLACK_ORB) - { - Feld[x][y] = Store2[x][y]; - Store2[x][y] = 0; - Bang(x, y); - } - } - else if (phase == half_phase) - { - int element = Store2[x][y]; - - if (IS_PLAYER(x, y)) - KillHeroUnlessExplosionProtected(x, y); - else if (CAN_EXPLODE_BY_EXPLOSION(element)) - { - Feld[x][y] = Store2[x][y]; - Store2[x][y] = 0; - Bang(x, y); - } - else if (element == EL_AMOEBA_TO_DIAMOND) - AmoebeUmwandeln(x, y); } -#endif if (phase == last_phase) { int element; -#if 0 - printf("::: done: phase == %d\n", phase); -#endif - -#if 0 - printf("::: explosion %d,%d done [%d]\n", x, y, FrameCounter); -#endif - element = Feld[x][y] = Store[x][y]; Store[x][y] = Store2[x][y] = 0; GfxElement[x][y] = EL_UNDEFINED; @@ -3787,12 +3507,18 @@ void Explode(int ex, int ey, int phase, int mode) /* player can escape from explosions and might therefore be still alive */ if (element >= EL_PLAYER_IS_EXPLODING_1 && element <= EL_PLAYER_IS_EXPLODING_4) - Feld[x][y] = (stored_player[element - EL_PLAYER_IS_EXPLODING_1].active ? - EL_EMPTY : - element == EL_PLAYER_IS_EXPLODING_1 ? EL_EMERALD_YELLOW : - element == EL_PLAYER_IS_EXPLODING_2 ? EL_EMERALD_RED : - element == EL_PLAYER_IS_EXPLODING_3 ? EL_EMERALD : - EL_EMERALD_PURPLE); + { + int player_nr = element - EL_PLAYER_IS_EXPLODING_1; + int explosion_element = EL_PLAYER_1 + player_nr; + int xx = MIN(MAX(0, x - stored_player[player_nr].jx + 1), 2); + int yy = MIN(MAX(0, y - stored_player[player_nr].jy + 1), 2); + + if (level.use_explosion_element[player_nr]) + explosion_element = level.explosion_element[player_nr]; + + Feld[x][y] = (stored_player[player_nr].active ? EL_EMPTY : + element_info[explosion_element].content.e[xx][yy]); + } /* restore probably existing indestructible background element */ if (Back[x][y] && IS_INDESTRUCTIBLE(Back[x][y])) @@ -3800,26 +3526,16 @@ void Explode(int ex, int ey, int phase, int mode) Back[x][y] = 0; MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0; - GfxDir[x][y] = MV_NO_MOVING; + GfxDir[x][y] = MV_NONE; ChangeDelay[x][y] = 0; ChangePage[x][y] = -1; -#if 1 - InitField_WithBug2(x, y, FALSE); -#else - InitField(x, y, FALSE); -#if 1 - /* !!! not needed !!! */ -#if 1 - if (game.engine_version < VERSION_IDENT(3,1,0,0) && - CAN_MOVE(Feld[x][y]) && Feld[x][y] != EL_MOLE) - InitMovDir(x, y); -#else - if (CAN_MOVE(element)) - InitMovDir(x, y); -#endif -#endif +#if USE_NEW_CUSTOM_VALUE + CustomValue[x][y] = 0; #endif + + InitField_WithBug2(x, y, FALSE); + DrawLevelField(x, y); TestIfElementTouchesCustomElement(x, y); @@ -3833,40 +3549,10 @@ void Explode(int ex, int ey, int phase, int mode) if (ELEM_IS_PLAYER(element)) RelocatePlayer(x, y, element); } -#if 1 else if (IN_SCR_FIELD(SCREENX(x), SCREENY(y))) -#else - else if (phase >= delay && IN_SCR_FIELD(SCREENX(x), SCREENY(y))) -#endif { -#if 1 int graphic = el_act2img(GfxElement[x][y], ACTION_EXPLODING); -#else - int stored = Store[x][y]; - int graphic = (game.emulation != EMU_SUPAPLEX ? IMG_EXPLOSION : - stored == EL_SP_INFOTRON ? IMG_SP_EXPLOSION_INFOTRON : - IMG_SP_EXPLOSION); -#endif -#if 1 int frame = getGraphicAnimationFrame(graphic, GfxFrame[x][y]); -#else - int frame = getGraphicAnimationFrame(graphic, phase - delay); -#endif - -#if 0 - printf("::: phase == %d [%d]\n", phase, GfxFrame[x][y]); -#endif - -#if 0 - printf("::: %d / %d [%d - %d]\n", - GfxFrame[x][y], phase - delay, phase, delay); -#endif - -#if 0 - printf("::: %d ['%s'] -> %d\n", GfxElement[x][y], - element_info[GfxElement[x][y]].token_name, - graphic); -#endif if (phase == delay) DrawLevelFieldCrumbledSand(x, y); @@ -3930,61 +3616,35 @@ void DynaExplode(int ex, int ey) Explode(x, y, EX_PHASE_START, EX_TYPE_BORDER); -#if 1 -#if 1 if (element != EL_EMPTY && element != EL_EXPLOSION && !IS_DIGGABLE(element) && !dynabomb_xl) break; -#else - if (element != EL_EMPTY && element != EL_EXPLOSION && - !CAN_GROW_INTO(element) && !dynabomb_xl) - break; -#endif -#else - /* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */ - if (element != EL_EMPTY && element != EL_EXPLOSION && - element != EL_SAND && !dynabomb_xl) - break; -#endif } } } void Bang(int x, int y) { -#if 1 int element = MovingOrBlocked2Element(x, y); -#else - int element = Feld[x][y]; -#endif + int explosion_type = EX_TYPE_NORMAL; -#if 1 if (IS_PLAYER(x, y) && !PLAYER_EXPLOSION_PROTECTED(x, y)) -#else - if (IS_PLAYER(x, y)) -#endif { struct PlayerInfo *player = PLAYERINFO(x, y); - element = Feld[x][y] = (player->use_murphy_graphic ? EL_SP_MURPHY : + element = Feld[x][y] = (player->use_murphy ? EL_SP_MURPHY : player->element_nr); - } -#if 0 -#if 1 - PlayLevelSoundAction(x, y, ACTION_EXPLODING); -#else - if (game.emulation == EMU_SUPAPLEX) - PlayLevelSound(x, y, SND_SP_ELEMENT_EXPLODING); - else - PlayLevelSound(x, y, SND_ELEMENT_EXPLODING); -#endif -#endif + if (level.use_explosion_element[player->index_nr]) + { + int explosion_element = level.explosion_element[player->index_nr]; -#if 0 - if (IS_PLAYER(x, y)) /* remove objects that might cause smaller explosion */ - element = EL_EMPTY; -#endif + if (element_info[explosion_element].explosion_type == EXPLODES_CROSS) + explosion_type = EX_TYPE_CROSS; + else if (element_info[explosion_element].explosion_type == EXPLODES_1X1) + explosion_type = EX_TYPE_CENTER; + } + } switch(element) { @@ -3998,8 +3658,8 @@ void Bang(int x, int y) case EL_PACMAN: case EL_MOLE: RaiseScoreElement(element); - Explode(x, y, EX_PHASE_START, EX_TYPE_NORMAL); break; + case EL_DYNABOMB_PLAYER_1_ACTIVE: case EL_DYNABOMB_PLAYER_2_ACTIVE: case EL_DYNABOMB_PLAYER_3_ACTIVE: @@ -4007,47 +3667,35 @@ void Bang(int x, int y) case EL_DYNABOMB_INCREASE_NUMBER: case EL_DYNABOMB_INCREASE_SIZE: case EL_DYNABOMB_INCREASE_POWER: - DynaExplode(x, y); + explosion_type = EX_TYPE_DYNA; break; + case EL_PENGUIN: case EL_LAMP: case EL_LAMP_ACTIVE: -#if 1 case EL_AMOEBA_TO_DIAMOND: -#endif - if (IS_PLAYER(x, y)) - Explode(x, y, EX_PHASE_START, EX_TYPE_NORMAL); - else - Explode(x, y, EX_PHASE_START, EX_TYPE_CENTER); + if (!IS_PLAYER(x, y)) /* penguin and player may be at same field */ + explosion_type = EX_TYPE_CENTER; break; + default: -#if 1 if (element_info[element].explosion_type == EXPLODES_CROSS) -#else - if (CAN_EXPLODE_CROSS(element)) -#endif -#if 1 - Explode(x, y, EX_PHASE_START, EX_TYPE_CROSS); -#else - DynaExplode(x, y); -#endif -#if 1 + explosion_type = EX_TYPE_CROSS; else if (element_info[element].explosion_type == EXPLODES_1X1) -#else - else if (CAN_EXPLODE_1X1(element)) -#endif - Explode(x, y, EX_PHASE_START, EX_TYPE_CENTER); - else - Explode(x, y, EX_PHASE_START, EX_TYPE_NORMAL); + explosion_type = EX_TYPE_CENTER; break; } + if (explosion_type == EX_TYPE_DYNA) + DynaExplode(x, y); + else + Explode(x, y, EX_PHASE_START, explosion_type); + CheckTriggeredElementChange(x, y, element, CE_EXPLOSION_OF_X); } void SplashAcid(int x, int y) { -#if 1 if (IN_LEV_FIELD(x - 1, y - 1) && IS_FREE(x - 1, y - 1) && (!IN_LEV_FIELD(x - 1, y - 2) || !CAN_FALL(MovingOrBlocked2Element(x - 1, y - 2)))) @@ -4059,30 +3707,6 @@ void SplashAcid(int x, int y) Feld[x + 1][y - 1] = EL_ACID_SPLASH_RIGHT; PlayLevelSound(x, y, SND_ACID_SPLASHING); -#else - /* input: position of element entering acid (obsolete) */ - - int element = Feld[x][y]; - - if (!IN_LEV_FIELD(x, y + 1) || Feld[x][y + 1] != EL_ACID) - return; - - if (element != EL_ACID_SPLASH_LEFT && - element != EL_ACID_SPLASH_RIGHT) - { - PlayLevelSound(x, y, SND_ACID_SPLASHING); - - if (IN_LEV_FIELD(x - 1, y) && IS_FREE(x - 1, y) && - (!IN_LEV_FIELD(x - 1, y - 1) || - !CAN_FALL(MovingOrBlocked2Element(x - 1, y - 1)))) - Feld[x - 1][y] = EL_ACID_SPLASH_LEFT; - - if (IN_LEV_FIELD(x + 1, y) && IS_FREE(x + 1, y) && - (!IN_LEV_FIELD(x + 1, y - 1) || - !CAN_FALL(MovingOrBlocked2Element(x + 1, y - 1)))) - Feld[x + 1][y] = EL_ACID_SPLASH_RIGHT; - } -#endif } static void InitBeltMovement() @@ -4121,25 +3745,26 @@ static void InitBeltMovement() } } - for (y = 0; y < lev_fieldy; y++) +#if 1 + SCAN_PLAYFIELD(x, y) +#else + for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) +#endif { - for (x = 0; x < lev_fieldx; x++) - { - int element = Feld[x][y]; + int element = Feld[x][y]; - for (i = 0; i < NUM_BELTS; i++) + for (i = 0; i < NUM_BELTS; i++) + { + if (IS_BELT(element) && game.belt_dir[i] != MV_NONE) { - if (IS_BELT(element) && game.belt_dir[i] != MV_NO_MOVING) - { - int e_belt_nr = getBeltNrFromBeltElement(element); - int belt_nr = i; + int e_belt_nr = getBeltNrFromBeltElement(element); + int belt_nr = i; - if (e_belt_nr == belt_nr) - { - int belt_part = Feld[x][y] - belt_base_element[belt_nr]; + if (e_belt_nr == belt_nr) + { + int belt_part = Feld[x][y] - belt_base_element[belt_nr]; - Feld[x][y] = belt_base_active_element[belt_nr] + belt_part; - } + Feld[x][y] = belt_base_active_element[belt_nr] + belt_part; } } } @@ -4172,9 +3797,9 @@ static void ToggleBeltSwitch(int x, int y) static int belt_move_dir[4] = { MV_LEFT, - MV_NO_MOVING, + MV_NONE, MV_RIGHT, - MV_NO_MOVING, + MV_NONE, }; int element = Feld[x][y]; @@ -4204,45 +3829,46 @@ static void ToggleBeltSwitch(int x, int y) graphic_info[graphic].anim_mode |= ANIM_REVERSE; } - for (yy = 0; yy < lev_fieldy; yy++) +#if 1 + SCAN_PLAYFIELD(xx, yy) +#else + for (yy = 0; yy < lev_fieldy; yy++) for (xx = 0; xx < lev_fieldx; xx++) +#endif { - for (xx = 0; xx < lev_fieldx; xx++) + int element = Feld[xx][yy]; + + if (IS_BELT_SWITCH(element)) { - int element = Feld[xx][yy]; + int e_belt_nr = getBeltNrFromBeltSwitchElement(element); - if (IS_BELT_SWITCH(element)) + if (e_belt_nr == belt_nr) { - int e_belt_nr = getBeltNrFromBeltSwitchElement(element); - - if (e_belt_nr == belt_nr) - { - Feld[xx][yy] = belt_base_switch_element[belt_nr] + belt_dir_nr; - DrawLevelField(xx, yy); - } + Feld[xx][yy] = belt_base_switch_element[belt_nr] + belt_dir_nr; + DrawLevelField(xx, yy); } - else if (IS_BELT(element) && belt_dir != MV_NO_MOVING) - { - int e_belt_nr = getBeltNrFromBeltElement(element); + } + else if (IS_BELT(element) && belt_dir != MV_NONE) + { + int e_belt_nr = getBeltNrFromBeltElement(element); - if (e_belt_nr == belt_nr) - { - int belt_part = Feld[xx][yy] - belt_base_element[belt_nr]; + if (e_belt_nr == belt_nr) + { + int belt_part = Feld[xx][yy] - belt_base_element[belt_nr]; - Feld[xx][yy] = belt_base_active_element[belt_nr] + belt_part; - DrawLevelField(xx, yy); - } + Feld[xx][yy] = belt_base_active_element[belt_nr] + belt_part; + DrawLevelField(xx, yy); } - else if (IS_BELT_ACTIVE(element) && belt_dir == MV_NO_MOVING) - { - int e_belt_nr = getBeltNrFromBeltActiveElement(element); + } + else if (IS_BELT_ACTIVE(element) && belt_dir == MV_NONE) + { + int e_belt_nr = getBeltNrFromBeltActiveElement(element); - if (e_belt_nr == belt_nr) - { - int belt_part = Feld[xx][yy] - belt_base_active_element[belt_nr]; + if (e_belt_nr == belt_nr) + { + int belt_part = Feld[xx][yy] - belt_base_active_element[belt_nr]; - Feld[xx][yy] = belt_base_element[belt_nr] + belt_part; - DrawLevelField(xx, yy); - } + Feld[xx][yy] = belt_base_element[belt_nr] + belt_part; + DrawLevelField(xx, yy); } } } @@ -4254,38 +3880,33 @@ static void ToggleSwitchgateSwitch(int x, int y) game.switchgate_pos = !game.switchgate_pos; - for (yy = 0; yy < lev_fieldy; yy++) - { - for (xx = 0; xx < lev_fieldx; xx++) - { - int element = Feld[xx][yy]; - - if (element == EL_SWITCHGATE_SWITCH_UP || - element == EL_SWITCHGATE_SWITCH_DOWN) - { - Feld[xx][yy] = EL_SWITCHGATE_SWITCH_UP + game.switchgate_pos; - DrawLevelField(xx, yy); - } - else if (element == EL_SWITCHGATE_OPEN || - element == EL_SWITCHGATE_OPENING) - { - Feld[xx][yy] = EL_SWITCHGATE_CLOSING; -#if 1 - PlayLevelSoundAction(xx, yy, ACTION_CLOSING); -#else - PlayLevelSound(xx, yy, SND_SWITCHGATE_CLOSING); -#endif - } - else if (element == EL_SWITCHGATE_CLOSED || - element == EL_SWITCHGATE_CLOSING) - { - Feld[xx][yy] = EL_SWITCHGATE_OPENING; #if 1 - PlayLevelSoundAction(xx, yy, ACTION_OPENING); + SCAN_PLAYFIELD(xx, yy) #else - PlayLevelSound(xx, yy, SND_SWITCHGATE_OPENING); + for (yy = 0; yy < lev_fieldy; yy++) for (xx = 0; xx < lev_fieldx; xx++) #endif - } + { + int element = Feld[xx][yy]; + + if (element == EL_SWITCHGATE_SWITCH_UP || + element == EL_SWITCHGATE_SWITCH_DOWN) + { + Feld[xx][yy] = EL_SWITCHGATE_SWITCH_UP + game.switchgate_pos; + DrawLevelField(xx, yy); + } + else if (element == EL_SWITCHGATE_OPEN || + element == EL_SWITCHGATE_OPENING) + { + Feld[xx][yy] = EL_SWITCHGATE_CLOSING; + + PlayLevelSoundAction(xx, yy, ACTION_CLOSING); + } + else if (element == EL_SWITCHGATE_CLOSED || + element == EL_SWITCHGATE_CLOSING) + { + Feld[xx][yy] = EL_SWITCHGATE_OPENING; + + PlayLevelSoundAction(xx, yy, ACTION_OPENING); } } } @@ -4310,50 +3931,167 @@ static void RedrawAllLightSwitchesAndInvisibleElements() { int x, y; - for (y = 0; y < lev_fieldy; y++) +#if 1 + SCAN_PLAYFIELD(x, y) +#else + for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) +#endif { - for (x = 0; x < lev_fieldx; x++) + int element = Feld[x][y]; + + if (element == EL_LIGHT_SWITCH && + game.light_time_left > 0) { - int element = Feld[x][y]; + Feld[x][y] = EL_LIGHT_SWITCH_ACTIVE; + DrawLevelField(x, y); + } + else if (element == EL_LIGHT_SWITCH_ACTIVE && + game.light_time_left == 0) + { + Feld[x][y] = EL_LIGHT_SWITCH; + DrawLevelField(x, y); + } + else if (element == EL_EMC_DRIPPER && + game.light_time_left > 0) + { + Feld[x][y] = EL_EMC_DRIPPER_ACTIVE; + DrawLevelField(x, y); + } + else if (element == EL_EMC_DRIPPER_ACTIVE && + game.light_time_left == 0) + { + Feld[x][y] = EL_EMC_DRIPPER; + DrawLevelField(x, y); + } + else if (element == EL_INVISIBLE_STEELWALL || + element == EL_INVISIBLE_WALL || + element == EL_INVISIBLE_SAND) + { + if (game.light_time_left > 0) + Feld[x][y] = getInvisibleActiveFromInvisibleElement(element); - if (element == EL_LIGHT_SWITCH && - game.light_time_left > 0) - { - Feld[x][y] = EL_LIGHT_SWITCH_ACTIVE; - DrawLevelField(x, y); - } - else if (element == EL_LIGHT_SWITCH_ACTIVE && - game.light_time_left == 0) - { - Feld[x][y] = EL_LIGHT_SWITCH; - DrawLevelField(x, y); - } - else if (element == EL_INVISIBLE_STEELWALL || - element == EL_INVISIBLE_WALL || - element == EL_INVISIBLE_SAND) - { - if (game.light_time_left > 0) - Feld[x][y] = getInvisibleActiveFromInvisibleElement(element); + DrawLevelField(x, y); - DrawLevelField(x, y); + /* uncrumble neighbour fields, if needed */ + if (element == EL_INVISIBLE_SAND) + DrawLevelFieldCrumbledSandNeighbours(x, y); + } + else if (element == EL_INVISIBLE_STEELWALL_ACTIVE || + element == EL_INVISIBLE_WALL_ACTIVE || + element == EL_INVISIBLE_SAND_ACTIVE) + { + if (game.light_time_left == 0) + Feld[x][y] = getInvisibleFromInvisibleActiveElement(element); - /* uncrumble neighbour fields, if needed */ - if (element == EL_INVISIBLE_SAND) - DrawLevelFieldCrumbledSandNeighbours(x, y); - } - else if (element == EL_INVISIBLE_STEELWALL_ACTIVE || - element == EL_INVISIBLE_WALL_ACTIVE || - element == EL_INVISIBLE_SAND_ACTIVE) - { - if (game.light_time_left == 0) - Feld[x][y] = getInvisibleFromInvisibleActiveElement(element); + DrawLevelField(x, y); - DrawLevelField(x, y); + /* re-crumble neighbour fields, if needed */ + if (element == EL_INVISIBLE_SAND) + DrawLevelFieldCrumbledSandNeighbours(x, y); + } + } +} - /* re-crumble neighbour fields, if needed */ - if (element == EL_INVISIBLE_SAND) - DrawLevelFieldCrumbledSandNeighbours(x, y); - } +static void RedrawAllInvisibleElementsForLenses() +{ + int x, y; + +#if 1 + SCAN_PLAYFIELD(x, y) +#else + for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) +#endif + { + int element = Feld[x][y]; + + if (element == EL_EMC_DRIPPER && + game.lenses_time_left > 0) + { + Feld[x][y] = EL_EMC_DRIPPER_ACTIVE; + DrawLevelField(x, y); + } + else if (element == EL_EMC_DRIPPER_ACTIVE && + game.lenses_time_left == 0) + { + Feld[x][y] = EL_EMC_DRIPPER; + DrawLevelField(x, y); + } + else if (element == EL_INVISIBLE_STEELWALL || + element == EL_INVISIBLE_WALL || + element == EL_INVISIBLE_SAND) + { + if (game.lenses_time_left > 0) + Feld[x][y] = getInvisibleActiveFromInvisibleElement(element); + + DrawLevelField(x, y); + + /* uncrumble neighbour fields, if needed */ + if (element == EL_INVISIBLE_SAND) + DrawLevelFieldCrumbledSandNeighbours(x, y); + } + else if (element == EL_INVISIBLE_STEELWALL_ACTIVE || + element == EL_INVISIBLE_WALL_ACTIVE || + element == EL_INVISIBLE_SAND_ACTIVE) + { + if (game.lenses_time_left == 0) + Feld[x][y] = getInvisibleFromInvisibleActiveElement(element); + + DrawLevelField(x, y); + + /* re-crumble neighbour fields, if needed */ + if (element == EL_INVISIBLE_SAND) + DrawLevelFieldCrumbledSandNeighbours(x, y); + } + } +} + +static void RedrawAllInvisibleElementsForMagnifier() +{ + int x, y; + +#if 1 + SCAN_PLAYFIELD(x, y) +#else + for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) +#endif + { + int element = Feld[x][y]; + + if (element == EL_EMC_FAKE_GRASS && + game.magnify_time_left > 0) + { + Feld[x][y] = EL_EMC_FAKE_GRASS_ACTIVE; + DrawLevelField(x, y); + } + else if (element == EL_EMC_FAKE_GRASS_ACTIVE && + game.magnify_time_left == 0) + { + Feld[x][y] = EL_EMC_FAKE_GRASS; + DrawLevelField(x, y); + } + else if (IS_GATE_GRAY(element) && + game.magnify_time_left > 0) + { + Feld[x][y] = (IS_RND_GATE_GRAY(element) ? + element - EL_GATE_1_GRAY + EL_GATE_1_GRAY_ACTIVE : + IS_EM_GATE_GRAY(element) ? + element - EL_EM_GATE_1_GRAY + EL_EM_GATE_1_GRAY_ACTIVE : + IS_EMC_GATE_GRAY(element) ? + element - EL_EMC_GATE_5_GRAY + EL_EMC_GATE_5_GRAY_ACTIVE : + element); + DrawLevelField(x, y); + } + else if (IS_GATE_GRAY_ACTIVE(element) && + game.magnify_time_left == 0) + { + Feld[x][y] = (IS_RND_GATE_GRAY_ACTIVE(element) ? + element - EL_GATE_1_GRAY_ACTIVE + EL_GATE_1_GRAY : + IS_EM_GATE_GRAY_ACTIVE(element) ? + element - EL_EM_GATE_1_GRAY_ACTIVE + EL_EM_GATE_1_GRAY : + IS_EMC_GATE_GRAY_ACTIVE(element) ? + element - EL_EMC_GATE_5_GRAY_ACTIVE + EL_EMC_GATE_5_GRAY : + element); + DrawLevelField(x, y); } } } @@ -4375,28 +4113,29 @@ static void ActivateTimegateSwitch(int x, int y) game.timegate_time_left = level.time_timegate * FRAMES_PER_SECOND; - for (yy = 0; yy < lev_fieldy; yy++) +#if 1 + SCAN_PLAYFIELD(xx, yy) +#else + for (yy = 0; yy < lev_fieldy; yy++) for (xx = 0; xx < lev_fieldx; xx++) +#endif { - for (xx = 0; xx < lev_fieldx; xx++) - { - int element = Feld[xx][yy]; + int element = Feld[xx][yy]; - if (element == EL_TIMEGATE_CLOSED || - element == EL_TIMEGATE_CLOSING) - { - Feld[xx][yy] = EL_TIMEGATE_OPENING; - PlayLevelSound(xx, yy, SND_TIMEGATE_OPENING); - } - - /* - else if (element == EL_TIMEGATE_SWITCH_ACTIVE) - { - Feld[xx][yy] = EL_TIMEGATE_SWITCH; - DrawLevelField(xx, yy); - } - */ + if (element == EL_TIMEGATE_CLOSED || + element == EL_TIMEGATE_CLOSING) + { + Feld[xx][yy] = EL_TIMEGATE_OPENING; + PlayLevelSound(xx, yy, SND_TIMEGATE_OPENING); + } + /* + else if (element == EL_TIMEGATE_SWITCH_ACTIVE) + { + Feld[xx][yy] = EL_TIMEGATE_SWITCH; + DrawLevelField(xx, yy); } + */ + } Feld[x][y] = EL_TIMEGATE_SWITCH_ACTIVE; @@ -4410,10 +4149,6 @@ void Impact(int x, int y) int element = Feld[x][y]; int smashed = EL_STEELWALL; -#if 0 - printf("IMPACT!\n"); -#endif - if (!last_line) /* check if element below was hit */ { if (Feld[x][y + 1] == EL_PLAYER_IS_LEAVING) @@ -4423,15 +4158,23 @@ void Impact(int x, int y) MovDir[x][y + 1] != MV_DOWN || MovPos[x][y + 1] <= TILEY / 2)); -#if 0 - object_hit = !IS_FREE(x, y + 1); -#endif - /* do not smash moving elements that left the smashed field in time */ if (game.engine_version >= VERSION_IDENT(2,2,0,7) && IS_MOVING(x, y + 1) && ABS(MovPos[x][y + 1] + getElementMoveStepsize(x, y + 1)) >= TILEX) object_hit = FALSE; +#if USE_QUICKSAND_IMPACT_BUGFIX + if (Feld[x][y + 1] == EL_QUICKSAND_EMPTYING && object_hit == FALSE) + { + RemoveMovingField(x, y + 1); + Feld[x][y + 1] = EL_QUICKSAND_EMPTY; + Feld[x][y + 2] = EL_ROCK; + DrawLevelField(x, y + 2); + + object_hit = TRUE; + } +#endif + if (object_hit) smashed = MovingOrBlocked2Element(x, y + 1); @@ -4476,7 +4219,7 @@ void Impact(int x, int y) if (impact && element == EL_AMOEBA_DROP) { if (object_hit && IS_PLAYER(x, y + 1)) - KillHeroUnlessEnemyProtected(x, y + 1); + KillPlayerUnlessEnemyProtected(x, y + 1); else if (object_hit && smashed == EL_PENGUIN) Bang(x, y + 1); else @@ -4501,10 +4244,13 @@ void Impact(int x, int y) EL_BD_MAGIC_WALL_ACTIVE); /* activate magic wall / mill */ - for (yy = 0; yy < lev_fieldy; yy++) - for (xx = 0; xx < lev_fieldx; xx++) - if (Feld[xx][yy] == smashed) - Feld[xx][yy] = activated_magic_wall; +#if 1 + SCAN_PLAYFIELD(xx, yy) +#else + for (yy = 0; yy < lev_fieldy; yy++) for (xx = 0; xx < lev_fieldx; xx++) +#endif + if (Feld[xx][yy] == smashed) + Feld[xx][yy] = activated_magic_wall; game.magic_wall_time_left = level.time_magic_wall * FRAMES_PER_SECOND; game.magic_wall_active = TRUE; @@ -4518,7 +4264,7 @@ void Impact(int x, int y) { if (CAN_SMASH_PLAYER(element)) { - KillHeroUnlessEnemyProtected(x, y + 1); + KillPlayerUnlessEnemyProtected(x, y + 1); return; } } @@ -4549,13 +4295,6 @@ void Impact(int x, int y) Bang(x, y + 1); return; } -#if 0 - else if (CAN_SMASH_ENEMIES(element) && IS_CLASSIC_ENEMY(smashed)) - { - Bang(x, y + 1); - return; - } -#endif else if (CAN_SMASH_EVERYTHING(element)) { if (IS_CLASSIC_ENEMY(smashed) || @@ -4615,18 +4354,10 @@ void Impact(int x, int y) CheckElementChange(x, y + 1, smashed, element, CE_SMASHED); -#if 1 - /* !!! TEST ONLY !!! */ - CheckElementChangeBySide(x, y + 1, smashed, element, - CE_SWITCHED, CH_SIDE_TOP); - CheckTriggeredElementChangeBySide(x, y + 1, smashed, - CE_SWITCH_OF_X, CH_SIDE_TOP); -#else - CheckTriggeredElementChangeBySide(x, y + 1, smashed, - CE_SWITCH_OF_X, CH_SIDE_TOP); CheckElementChangeBySide(x, y + 1, smashed, element, CE_SWITCHED, CH_SIDE_TOP); -#endif + CheckTriggeredElementChangeBySide(x, y + 1, smashed, CE_SWITCH_OF_X, + CH_SIDE_TOP); } } else @@ -4658,7 +4389,7 @@ inline static void TurnRoundExt(int x, int y) { static struct { - int x, y; + int dx, dy; } move_xy[] = { { 0, 0 }, @@ -4693,10 +4424,10 @@ inline static void TurnRoundExt(int x, int y) int right_dir = turn[old_move_dir].right; int back_dir = turn[old_move_dir].back; - int left_dx = move_xy[left_dir].x, left_dy = move_xy[left_dir].y; - int right_dx = move_xy[right_dir].x, right_dy = move_xy[right_dir].y; - int move_dx = move_xy[old_move_dir].x, move_dy = move_xy[old_move_dir].y; - int back_dx = move_xy[back_dir].x, back_dy = move_xy[back_dir].y; + int left_dx = move_xy[left_dir].dx, left_dy = move_xy[left_dir].dy; + int right_dx = move_xy[right_dir].dx, right_dy = move_xy[right_dir].dy; + int move_dx = move_xy[old_move_dir].dx, move_dy = move_xy[old_move_dir].dy; + int back_dx = move_xy[back_dir].dx, back_dy = move_xy[back_dir].dy; int left_x = x + left_dx, left_y = y + left_dy; int right_x = x + right_dx, right_y = y + right_dy; @@ -4718,9 +4449,7 @@ inline static void TurnRoundExt(int x, int y) else if (element == EL_BD_BUTTERFLY) /* && MovDir[x][y] == left_dir) */ MovDelay[x][y] = 1; } -#if 0 - else if (element == EL_SPACESHIP || element == EL_BD_FIREFLY || - element == EL_SP_SNIKSNAK || element == EL_SP_ELECTRON) + else if (element == EL_SPACESHIP || element == EL_BD_FIREFLY) { TestIfBadThingTouchesOtherBadThing(x, y); @@ -4729,42 +4458,23 @@ inline static void TurnRoundExt(int x, int y) else if (!ENEMY_CAN_ENTER_FIELD(element, move_x, move_y)) MovDir[x][y] = right_dir; - if ((element == EL_SPACESHIP || - element == EL_SP_SNIKSNAK || - element == EL_SP_ELECTRON) - && MovDir[x][y] != old_move_dir) + if (element == EL_SPACESHIP && MovDir[x][y] != old_move_dir) MovDelay[x][y] = 9; else if (element == EL_BD_FIREFLY) /* && MovDir[x][y] == right_dir) */ MovDelay[x][y] = 1; } -#else - else if (element == EL_SPACESHIP || element == EL_BD_FIREFLY) + else if (element == EL_SP_SNIKSNAK || element == EL_SP_ELECTRON) { TestIfBadThingTouchesOtherBadThing(x, y); - if (ENEMY_CAN_ENTER_FIELD(element, left_x, left_y)) + if (ELEMENT_CAN_ENTER_FIELD_BASE_4(element, left_x, left_y, 0)) MovDir[x][y] = left_dir; - else if (!ENEMY_CAN_ENTER_FIELD(element, move_x, move_y)) - MovDir[x][y] = right_dir; - - if (element == EL_SPACESHIP && MovDir[x][y] != old_move_dir) - MovDelay[x][y] = 9; - else if (element == EL_BD_FIREFLY) /* && MovDir[x][y] == right_dir) */ - MovDelay[x][y] = 1; - } - else if (element == EL_SP_SNIKSNAK || element == EL_SP_ELECTRON) - { - TestIfBadThingTouchesOtherBadThing(x, y); - - if (ELEMENT_CAN_ENTER_FIELD_BASE_4(element, left_x, left_y, 0)) - MovDir[x][y] = left_dir; - else if (!ELEMENT_CAN_ENTER_FIELD_BASE_4(element, move_x, move_y, 0)) + else if (!ELEMENT_CAN_ENTER_FIELD_BASE_4(element, move_x, move_y, 0)) MovDir[x][y] = right_dir; if (MovDir[x][y] != old_move_dir) MovDelay[x][y] = 9; } -#endif else if (element == EL_YAMYAM) { boolean can_turn_left = YAMYAM_CAN_ENTER_FIELD(element, left_x, left_y); @@ -4870,18 +4580,12 @@ inline static void TurnRoundExt(int x, int y) else MovDir[x][y] = back_dir; - xx = x + move_xy[MovDir[x][y]].x; - yy = y + move_xy[MovDir[x][y]].y; + xx = x + move_xy[MovDir[x][y]].dx; + yy = y + move_xy[MovDir[x][y]].dy; -#if 1 - /* !!! this bugfix breaks at least BD2K3, level 010 !!! [re-recorded] */ if (!IN_LEV_FIELD(xx, yy) || (!IS_FREE(xx, yy) && !IS_FOOD_PIG(Feld[xx][yy]))) MovDir[x][y] = old_move_dir; -#else - if (!IS_FREE(xx, yy) && !IS_FOOD_PIG(Feld[xx][yy])) - MovDir[x][y] = old_move_dir; -#endif MovDelay[x][y] = 0; } @@ -4893,11 +4597,6 @@ inline static void TurnRoundExt(int x, int y) int rnd_value = 24; int rnd = RND(rnd_value); -#if 0 - if (FrameCounter < 1 && x == 0 && y == 29) - printf(":2: %d/%d: %d [%d]\n", x, y, MovDir[x][y], FrameCounter); -#endif - if (can_move_on && rnd > rnd_value / 8) MovDir[x][y] = old_move_dir; else if (can_turn_left && can_turn_right) @@ -4909,28 +4608,11 @@ inline static void TurnRoundExt(int x, int y) else MovDir[x][y] = back_dir; - xx = x + move_xy[MovDir[x][y]].x; - yy = y + move_xy[MovDir[x][y]].y; - -#if 0 - if (FrameCounter < 1 && x == 0 && y == 29) - printf(":3: %d/%d: %d (%d/%d: %d) [%d]\n", x, y, MovDir[x][y], - xx, yy, Feld[xx][yy], - FrameCounter); -#endif + xx = x + move_xy[MovDir[x][y]].dx; + yy = y + move_xy[MovDir[x][y]].dy; -#if 1 if (!IN_LEV_FIELD_AND_IS_FREE(xx, yy)) MovDir[x][y] = old_move_dir; -#else - if (!IS_FREE(xx, yy)) - MovDir[x][y] = old_move_dir; -#endif - -#if 0 - if (FrameCounter < 1 && x == 0 && y == 29) - printf(":4: %d/%d: %d [%d]\n", x, y, MovDir[x][y], FrameCounter); -#endif MovDelay[x][y] = 0; } @@ -4963,21 +4645,15 @@ inline static void TurnRoundExt(int x, int y) } else if (element == EL_BALLOON) { - MovDir[x][y] = game.balloon_dir; + MovDir[x][y] = game.wind_direction; MovDelay[x][y] = 0; } else if (element == EL_SPRING) { -#if 0 - if (MovDir[x][y] & MV_HORIZONTAL && - !SPRING_CAN_ENTER_FIELD(element, move_x, move_y)) - MovDir[x][y] = MV_NO_MOVING; -#else if (MovDir[x][y] & MV_HORIZONTAL && (!SPRING_CAN_ENTER_FIELD(element, move_x, move_y) || SPRING_CAN_ENTER_FIELD(element, x, y + 1))) - MovDir[x][y] = MV_NO_MOVING; -#endif + MovDir[x][y] = MV_NONE; MovDelay[x][y] = 0; } @@ -5013,13 +4689,9 @@ inline static void TurnRoundExt(int x, int y) } } -#if 1 if (element == EL_ROBOT && ZX >= 0 && ZY >= 0 && (Feld[ZX][ZY] == EL_ROBOT_WHEEL_ACTIVE || game.engine_version < VERSION_IDENT(3,1,0,0))) -#else - if (element == EL_ROBOT && ZX >= 0 && ZY >= 0) -#endif { attr_x = ZX; attr_y = ZY; @@ -5050,7 +4722,7 @@ inline static void TurnRoundExt(int x, int y) } } - MovDir[x][y] = MV_NO_MOVING; + MovDir[x][y] = MV_NONE; if (attr_x < x) MovDir[x][y] |= (AllPlayersGone ? MV_RIGHT : MV_LEFT); else if (attr_x > x) @@ -5144,10 +4816,8 @@ inline static void TurnRoundExt(int x, int y) boolean can_turn_right = CUSTOM_ELEMENT_CAN_ENTER_FIELD(element, right_x,right_y); -#if USE_CAN_MOVE_NOT_MOVING - if (element_info[element].move_stepsize == 0) /* not moving */ + if (element_info[element].move_stepsize == 0) /* "not moving" */ return; -#endif if (move_pattern == MV_TURNING_LEFT) MovDir[x][y] = left_dir; @@ -5189,6 +4859,11 @@ inline static void TurnRoundExt(int x, int y) MovDir[x][y] = move_pattern; MovDelay[x][y] = GET_NEW_MOVE_DELAY(element); } + else if (move_pattern & MV_WIND_DIRECTION) + { + MovDir[x][y] = game.wind_direction; + MovDelay[x][y] = GET_NEW_MOVE_DELAY(element); + } else if (move_pattern == MV_ALONG_LEFT_SIDE) { if (CUSTOM_ELEMENT_CAN_ENTER_FIELD(element, left_x, left_y)) @@ -5242,7 +4917,7 @@ inline static void TurnRoundExt(int x, int y) } } - MovDir[x][y] = MV_NO_MOVING; + MovDir[x][y] = MV_NONE; if (attr_x < x) MovDir[x][y] |= (move_away ? MV_RIGHT : MV_LEFT); else if (attr_x > x) @@ -5259,15 +4934,13 @@ inline static void TurnRoundExt(int x, int y) boolean first_horiz = RND(2); int new_move_dir = MovDir[x][y]; -#if USE_CAN_MOVE_NOT_MOVING - if (element_info[element].move_stepsize == 0) /* not moving */ + if (element_info[element].move_stepsize == 0) /* "not moving" */ { first_horiz = (ABS(attr_x - x) >= ABS(attr_y - y)); MovDir[x][y] &= (first_horiz ? MV_HORIZONTAL : MV_VERTICAL); return; } -#endif MovDir[x][y] = new_move_dir & (first_horiz ? MV_HORIZONTAL : MV_VERTICAL); @@ -5290,7 +4963,7 @@ inline static void TurnRoundExt(int x, int y) move_pattern == MV_WHEN_DROPPED) { if (!CUSTOM_ELEMENT_CAN_ENTER_FIELD(element, move_x, move_y)) - MovDir[x][y] = MV_NO_MOVING; + MovDir[x][y] = MV_NONE; MovDelay[x][y] = 0; } @@ -5318,7 +4991,7 @@ inline static void TurnRoundExt(int x, int y) }; boolean hunter_mode = (move_pattern == MV_MAZE_HUNTER); int move_preference = -1000000; /* start with very low preference */ - int new_move_dir = MV_NO_MOVING; + int new_move_dir = MV_NONE; int start_test = RND(4); int i; @@ -5362,13 +5035,7 @@ inline static void TurnRoundExt(int x, int y) MovDir[x][y] = new_move_dir; if (old_move_dir != new_move_dir) - { -#if 1 MovDelay[x][y] = GET_NEW_MOVE_DELAY(element); -#else - MovDelay[x][y] = 9; -#endif - } } } @@ -5376,26 +5043,15 @@ static void TurnRound(int x, int y) { int direction = MovDir[x][y]; -#if 0 - GfxDir[x][y] = MovDir[x][y]; -#endif - TurnRoundExt(x, y); -#if 1 GfxDir[x][y] = MovDir[x][y]; -#endif if (direction != MovDir[x][y]) GfxFrame[x][y] = 0; -#if 1 if (MovDelay[x][y]) GfxAction[x][y] = ACTION_TURNING_FROM_LEFT + MV_DIR_BIT(direction); -#else - if (MovDelay[x][y]) - GfxAction[x][y] = ACTION_WAITING; -#endif } static boolean JustBeingPushed(int x, int y) @@ -5421,23 +5077,14 @@ static boolean JustBeingPushed(int x, int y) void StartMoving(int x, int y) { -#if 0 - boolean use_spring_bug = (game.engine_version < VERSION_IDENT(2,2,0,0)); -#endif boolean started_moving = FALSE; /* some elements can fall _and_ move */ int element = Feld[x][y]; if (Stop[x][y]) return; -#if 1 if (MovDelay[x][y] == 0) GfxAction[x][y] = ACTION_DEFAULT; -#else - /* !!! this should be handled more generic (not only for mole) !!! */ - if (element != EL_MOLE && GfxAction[x][y] != ACTION_DIGGING) - GfxAction[x][y] = ACTION_DEFAULT; -#endif if (CAN_FALL(element) && y < lev_fieldy - 1) { @@ -5455,11 +5102,8 @@ void StartMoving(int x, int y) Feld[x][y] = EL_QUICKSAND_EMPTYING; Store[x][y] = EL_ROCK; -#if 1 + PlayLevelSoundAction(x, y, ACTION_EMPTYING); -#else - PlayLevelSound(x, y, SND_QUICKSAND_EMPTYING); -#endif } else if (Feld[x][y + 1] == EL_QUICKSAND_EMPTY) { @@ -5477,11 +5121,8 @@ void StartMoving(int x, int y) Feld[x][y + 1] = EL_QUICKSAND_FULL; Store[x][y + 1] = Store[x][y]; Store[x][y] = 0; -#if 1 + PlayLevelSoundAction(x, y, ACTION_FILLING); -#else - PlayLevelSound(x, y, SND_QUICKSAND_FILLING); -#endif } } else if ((element == EL_ROCK || element == EL_BD_ROCK) && @@ -5492,11 +5133,8 @@ void StartMoving(int x, int y) Feld[x][y] = EL_QUICKSAND_FILLING; Store[x][y] = element; -#if 1 + PlayLevelSoundAction(x, y, ACTION_FILLING); -#else - PlayLevelSound(x, y, SND_QUICKSAND_FILLING); -#endif } else if (element == EL_MAGIC_WALL_FULL) { @@ -5566,11 +5204,7 @@ void StartMoving(int x, int y) EL_BD_MAGIC_WALL_FILLING); Store[x][y] = element; } -#if 0 - else if (CAN_SMASH(element) && Feld[x][y + 1] == EL_ACID) -#else else if (CAN_FALL(element) && Feld[x][y + 1] == EL_ACID) -#endif { SplashAcid(x, y + 1); @@ -5578,16 +5212,10 @@ void StartMoving(int x, int y) started_moving = TRUE; Store[x][y] = EL_ACID; -#if 0 - /* !!! TEST !!! better use "_FALLING" etc. !!! */ - GfxAction[x][y + 1] = ACTION_ACTIVE; -#endif } -#if 1 else if ((game.engine_version >= VERSION_IDENT(3,1,0,0) && CheckCollision[x][y] && !IS_FREE(x, y + 1)) || -#if USE_IMPACT_BUGFIX (game.engine_version >= VERSION_IDENT(3,0,7,0) && CAN_FALL(element) && WasJustFalling[x][y] && (Feld[x][y + 1] == EL_BLOCKED || IS_PLAYER(x, y + 1))) || @@ -5595,27 +5223,6 @@ void StartMoving(int x, int y) (game.engine_version < VERSION_IDENT(2,2,0,7) && CAN_FALL(element) && WasJustMoving[x][y] && !Pushed[x][y + 1] && (Feld[x][y + 1] == EL_BLOCKED))) -#else - (game.engine_version >= VERSION_IDENT(3,0,7,0) && - CAN_SMASH(element) && WasJustFalling[x][y] && - (Feld[x][y + 1] == EL_BLOCKED || IS_PLAYER(x, y + 1))) || - - (game.engine_version < VERSION_IDENT(2,2,0,7) && - CAN_SMASH(element) && WasJustMoving[x][y] && !Pushed[x][y + 1] && - (Feld[x][y + 1] == EL_BLOCKED))) -#endif - -#else -#if 1 - else if (game.engine_version < VERSION_IDENT(2,2,0,7) && - CAN_SMASH(element) && Feld[x][y + 1] == EL_BLOCKED && - WasJustMoving[x][y] && !Pushed[x][y + 1]) -#else - else if (CAN_SMASH(element) && Feld[x][y + 1] == EL_BLOCKED && - WasJustMoving[x][y]) -#endif -#endif - { /* this is needed for a special case not covered by calling "Impact()" from "ContinueMoving()": if an element moves to a tile directly below @@ -5627,23 +5234,13 @@ void StartMoving(int x, int y) element; also, the case of the player being the element to smash was simply not covered here... :-/ ) */ -#if 0 - WasJustMoving[x][y] = 0; - WasJustFalling[x][y] = 0; -#endif - CheckCollision[x][y] = 0; -#if 0 - if (IS_PLAYER(x, y + 1)) - printf("::: we ARE now killing the player [%d]\n", FrameCounter); -#endif - Impact(x, y); } else if (IS_FREE(x, y + 1) && element == EL_SPRING && level.use_spring_bug) { - if (MovDir[x][y] == MV_NO_MOVING) + if (MovDir[x][y] == MV_NONE) { InitMovingField(x, y, MV_DOWN); started_moving = TRUE; @@ -5662,23 +5259,10 @@ void StartMoving(int x, int y) Feld[x][y] = EL_AMOEBA_GROWING; Store[x][y] = EL_AMOEBA_WET; } - /* Store[x][y + 1] must be zero, because: - (EL_QUICKSAND_FULL -> EL_ROCK): Store[x][y + 1] == EL_QUICKSAND_EMPTY - */ -#if 0 -#if OLD_GAME_BEHAVIOUR - else if (IS_SLIPPERY(Feld[x][y + 1]) && !Store[x][y + 1]) -#else - else if (IS_SLIPPERY(Feld[x][y + 1]) && !Store[x][y + 1] && - !IS_FALLING(x, y + 1) && !WasJustMoving[x][y + 1] && - element != EL_DX_SUPABOMB) -#endif -#else else if (((IS_SLIPPERY(Feld[x][y + 1]) && !IS_PLAYER(x, y + 1)) || (IS_EM_SLIPPERY_WALL(Feld[x][y + 1]) && IS_GEM(element))) && !IS_FALLING(x, y + 1) && !WasJustMoving[x][y + 1] && element != EL_DX_SUPABOMB && element != EL_SP_DISK_ORANGE) -#endif { boolean can_fall_left = (x > 0 && IS_FREE(x - 1, y) && (IS_FREE(x - 1, y + 1) || @@ -5688,11 +5272,26 @@ void StartMoving(int x, int y) Feld[x + 1][y + 1] == EL_ACID)); boolean can_fall_any = (can_fall_left || can_fall_right); boolean can_fall_both = (can_fall_left && can_fall_right); + int slippery_type = element_info[Feld[x][y + 1]].slippery_type; - if (can_fall_any && IS_CUSTOM_ELEMENT(Feld[x][y + 1])) +#if USE_NEW_ALL_SLIPPERY + if (can_fall_any && slippery_type != SLIPPERY_ANY_RANDOM) { - int slippery_type = element_info[Feld[x][y + 1]].slippery_type; + if (slippery_type == SLIPPERY_ANY_LEFT_RIGHT && can_fall_both) + can_fall_right = FALSE; + else if (slippery_type == SLIPPERY_ANY_RIGHT_LEFT && can_fall_both) + can_fall_left = FALSE; + else if (slippery_type == SLIPPERY_ONLY_LEFT) + can_fall_right = FALSE; + else if (slippery_type == SLIPPERY_ONLY_RIGHT) + can_fall_left = FALSE; + can_fall_any = (can_fall_left || can_fall_right); + can_fall_both = FALSE; + } +#else + if (can_fall_any && IS_CUSTOM_ELEMENT(Feld[x][y + 1])) + { if (slippery_type == SLIPPERY_ONLY_LEFT) can_fall_right = FALSE; else if (slippery_type == SLIPPERY_ONLY_RIGHT) @@ -5705,7 +5304,10 @@ void StartMoving(int x, int y) can_fall_any = (can_fall_left || can_fall_right); can_fall_both = (can_fall_left && can_fall_right); } +#endif +#if USE_NEW_ALL_SLIPPERY +#else #if USE_NEW_SP_SLIPPERY /* !!! better use the same properties as for custom elements here !!! */ else if (game.engine_version >= VERSION_IDENT(3,1,1,0) && @@ -5715,8 +5317,19 @@ void StartMoving(int x, int y) can_fall_both = FALSE; } #endif +#endif -#if 1 +#if USE_NEW_ALL_SLIPPERY + if (can_fall_both) + { + if (element == EL_BD_ROCK || element == EL_BD_DIAMOND) + can_fall_right = FALSE; /* slip down on left side */ + else + can_fall_left = !(can_fall_right = RND(2)); + + can_fall_both = FALSE; + } +#else if (can_fall_both) { if (game.emulation == EMU_BOULDERDASH || @@ -5731,13 +5344,6 @@ void StartMoving(int x, int y) if (can_fall_any) { -#if 0 - if (can_fall_both && - (game.emulation != EMU_BOULDERDASH && - element != EL_BD_ROCK && element != EL_BD_DIAMOND)) - can_fall_left = !(can_fall_right = RND(2)); -#endif - /* if not determined otherwise, prefer left side for slipping down */ InitMovingField(x, y, can_fall_left ? MV_LEFT : MV_RIGHT); started_moving = TRUE; @@ -5757,17 +5363,13 @@ void StartMoving(int x, int y) if ((belt_dir == MV_LEFT && left_is_free) || (belt_dir == MV_RIGHT && right_is_free)) { -#if 1 int nextx = (belt_dir == MV_LEFT ? x - 1 : x + 1); -#endif InitMovingField(x, y, belt_dir); started_moving = TRUE; -#if 1 Pushed[x][y] = TRUE; Pushed[nextx][y] = TRUE; -#endif GfxAction[x][y] = ACTION_DEFAULT; } @@ -5780,7 +5382,7 @@ void StartMoving(int x, int y) /* not "else if" because of elements that can fall and move (EL_SPRING) */ #if 0 - if (CAN_MOVE(element) && !started_moving && MovDir[x][y] != MV_NO_MOVING) + if (CAN_MOVE(element) && !started_moving && MovDir[x][y] != MV_NONE) #else if (CAN_MOVE(element) && !started_moving) #endif @@ -5790,7 +5392,7 @@ void StartMoving(int x, int y) #if 0 #if DEBUG - if (MovDir[x][y] == MV_NO_MOVING) + if (MovDir[x][y] == MV_NONE) { printf("StartMoving(): %d,%d: element %d ['%s'] not moving\n", x, y, element, element_info[element].token_name); @@ -5801,80 +5403,20 @@ void StartMoving(int x, int y) Moving2Blocked(x, y, &newx, &newy); -#if 1 if (IS_PUSHABLE(element) && JustBeingPushed(x, y)) return; -#else - if ((element == EL_SATELLITE || - element == EL_BALLOON || - element == EL_SPRING) - && JustBeingPushed(x, y)) - return; -#endif - -#if 1 -#if 1 if (game.engine_version >= VERSION_IDENT(3,1,0,0) && CheckCollision[x][y] && !IN_LEV_FIELD_AND_IS_FREE(newx, newy)) -#else - if (game.engine_version >= VERSION_IDENT(3,1,0,0) && - WasJustMoving[x][y] && IN_LEV_FIELD(newx, newy) && - (Feld[newx][newy] == EL_BLOCKED || IS_PLAYER(newx, newy))) -#endif { -#if 0 - printf("::: element %d '%s' WasJustMoving %d [%d, %d, %d, %d]\n", - element, element_info[element].token_name, - WasJustMoving[x][y], - HAS_ANY_CHANGE_EVENT(element, CE_HITTING_SOMETHING), - HAS_ANY_CHANGE_EVENT(element, CE_HIT_BY_SOMETHING), - HAS_ANY_CHANGE_EVENT(element, CE_HITTING_X), - HAS_ANY_CHANGE_EVENT(element, CE_HIT_BY_X)); -#endif - -#if 1 WasJustMoving[x][y] = 0; -#endif - CheckCollision[x][y] = 0; TestIfElementHitsCustomElement(x, y, MovDir[x][y]); -#if 0 - if (Feld[x][y] != element) /* element has changed */ - { - element = Feld[x][y]; - move_pattern = element_info[element].move_pattern; - - if (!CAN_MOVE(element)) - return; - } -#else if (Feld[x][y] != element) /* element has changed */ return; -#endif - } -#endif - -#if 0 -#if 0 - if (element == EL_SPRING && MovDir[x][y] == MV_DOWN) - Feld[x][y + 1] = EL_EMPTY; /* was set to EL_BLOCKED above */ -#else - if (element == EL_SPRING && MovDir[x][y] != MV_NO_MOVING) - { - Moving2Blocked(x, y, &newx, &newy); - if (Feld[newx][newy] == EL_BLOCKED) - Feld[newx][newy] = EL_EMPTY; /* was set to EL_BLOCKED above */ } -#endif -#endif - -#if 0 - if (FrameCounter < 1 && x == 0 && y == 29) - printf(":1: %d/%d: %d [%d]\n", x, y, MovDir[x][y], FrameCounter); -#endif if (!MovDelay[x][y]) /* start new movement phase */ { @@ -5893,11 +5435,6 @@ void StartMoving(int x, int y) { TurnRound(x, y); -#if 0 - if (FrameCounter < 1 && x == 0 && y == 29) - printf(":9: %d: %d [%d]\n", y, MovDir[x][y], FrameCounter); -#endif - if (MovDelay[x][y] && (element == EL_BUG || element == EL_SPACESHIP || element == EL_SP_SNIKSNAK || @@ -5911,42 +5448,11 @@ void StartMoving(int x, int y) { MovDelay[x][y]--; -#if 0 - if (element == EL_YAMYAM) - { - printf("::: %d\n", - el_act_dir2img(EL_YAMYAM, ACTION_WAITING, MV_LEFT)); - DrawLevelElementAnimation(x, y, element); - } -#endif - - if (MovDelay[x][y]) /* element still has to wait some time */ - { -#if 0 - /* !!! PLACE THIS SOMEWHERE AFTER "TurnRound()" !!! */ - ResetGfxAnimation(x, y); -#endif - -#if 0 - if (GfxAction[x][y] != ACTION_WAITING) - printf("::: %d: %d != ACTION_WAITING\n", element, GfxAction[x][y]); - - GfxAction[x][y] = ACTION_WAITING; -#endif - } - if (element == EL_ROBOT || -#if 0 - element == EL_PACMAN || -#endif element == EL_YAMYAM || element == EL_DARK_YAMYAM) { -#if 0 - DrawLevelElementAnimation(x, y, element); -#else DrawLevelElementAnimationIfNeeded(x, y, element); -#endif PlayLevelSoundAction(x, y, ACTION_WAITING); } else if (element == EL_SP_ELECTRON) @@ -5963,10 +5469,6 @@ void StartMoving(int x, int y) dir == MV_DOWN ? IMG_FLAMES_1_DOWN : IMG_EMPTY); int frame = getGraphicAnimationFrame(graphic, GfxFrame[x][y]); -#if 0 - printf("::: %d, %d\n", GfxAction[x][y], GfxFrame[x][y]); -#endif - GfxAction[x][y] = ACTION_ATTACKING; if (IS_PLAYER(x, y)) @@ -6006,16 +5508,10 @@ void StartMoving(int x, int y) RemoveMovingField(xx, yy); #endif -#if 0 - if (ChangeDelay[xx][yy]) - printf("::: !!! [%d]\n", (IS_MOVING(xx, yy) || - Feld[xx][yy] == EL_BLOCKED)); -#endif - -#if 1 ChangeDelay[xx][yy] = 0; -#endif + Feld[xx][yy] = EL_FLAMES; + if (IN_SCR_FIELD(sx, sy)) { DrawLevelFieldCrumbledSand(xx, yy); @@ -6037,13 +5533,6 @@ void StartMoving(int x, int y) return; } - -#if 0 - /* special case of "moving" animation of waiting elements (FIX THIS !!!); - for all other elements GfxAction will be set by InitMovingField() */ - if (element == EL_BD_BUTTERFLY || element == EL_BD_FIREFLY) - GfxAction[x][y] = ACTION_MOVING; -#endif } /* now make next step */ @@ -6054,38 +5543,15 @@ void StartMoving(int x, int y) IN_LEV_FIELD(newx, newy) && IS_PLAYER(newx, newy) && !PLAYER_ENEMY_PROTECTED(newx, newy)) { -#if 1 - TestIfBadThingRunsIntoHero(x, y, MovDir[x][y]); + TestIfBadThingRunsIntoPlayer(x, y, MovDir[x][y]); return; -#else - /* player killed by element which is deadly when colliding with */ - MovDir[x][y] = 0; - KillHero(PLAYERINFO(newx, newy)); - return; -#endif - } -#if 1 -#if 1 + else if (CAN_MOVE_INTO_ACID(element) && IN_LEV_FIELD(newx, newy) && Feld[newx][newy] == EL_ACID && (MovDir[x][y] == MV_DOWN || game.engine_version >= VERSION_IDENT(3,1,0,0))) -#else - else if (CAN_MOVE_INTO_ACID(element) && MovDir[x][y] == MV_DOWN && - IN_LEV_FIELD(newx, newy) && Feld[newx][newy] == EL_ACID) -#endif -#else - - else if ((element == EL_PENGUIN || - element == EL_ROBOT || - element == EL_SATELLITE || - element == EL_BALLOON || - IS_CUSTOM_ELEMENT(element)) && - IN_LEV_FIELD(newx, newy) && - MovDir[x][y] == MV_DOWN && Feld[newx][newy] == EL_ACID) -#endif { SplashAcid(newx, newy); Store[x][y] = EL_ACID; @@ -6094,13 +5560,8 @@ void StartMoving(int x, int y) { if (Feld[newx][newy] == EL_EXIT_OPEN) { -#if 1 RemoveField(x, y); DrawLevelField(x, y); -#else - Feld[x][y] = EL_EMPTY; - DrawLevelField(x, y); -#endif PlayLevelSound(newx, newy, SND_PENGUIN_PASSING); if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy))) @@ -6118,7 +5579,7 @@ void StartMoving(int x, int y) if (DigField(local_player, x, y, newx, newy, 0,0, DF_DIG) == MF_MOVING) DrawLevelField(newx, newy); else - GfxDir[x][y] = MovDir[x][y] = MV_NO_MOVING; + GfxDir[x][y] = MovDir[x][y] = MV_NONE; } else if (!IS_FREE(newx, newy)) { @@ -6156,32 +5617,11 @@ void StartMoving(int x, int y) return; } } - -#if 1 - - /* - else if (move_pattern & MV_MAZE_RUNNER_STYLE && IN_LEV_FIELD(newx, newy)) - */ - else if (IS_CUSTOM_ELEMENT(element) && - CUSTOM_ELEMENT_CAN_ENTER_FIELD(element, newx, newy) - -#if 0 - && - !IS_FREE(newx, newy) -#endif - -) + CUSTOM_ELEMENT_CAN_ENTER_FIELD(element, newx, newy)) { int new_element = Feld[newx][newy]; -#if 0 - printf("::: '%s' digs '%s' [%d]\n", - element_info[element].token_name, - element_info[Feld[newx][newy]].token_name, - StorePlayer[newx][newy]); -#endif - if (!IS_FREE(newx, newy)) { int action = (IS_DIGGABLE(new_element) ? ACTION_DIGGING : @@ -6217,29 +5657,20 @@ void StartMoving(int x, int y) PlayLevelSoundAction(x, y, action); } -#if 1 -#if 1 Store[newx][newy] = EL_EMPTY; +#if 1 + /* this makes it possible to leave the removed element again */ if (IS_EQUAL_OR_IN_GROUP(new_element, MOVE_ENTER_EL(element))) - { -#if USE_CHANGE_TO_TRIGGERED + Store[newx][newy] = new_element; +#else + if (IS_EQUAL_OR_IN_GROUP(new_element, MOVE_ENTER_EL(element))) + { int move_leave_element = element_info[element].move_leave_element; + /* this makes it possible to leave the removed element again */ Store[newx][newy] = (move_leave_element == EL_TRIGGER_ELEMENT ? new_element : move_leave_element); -#else - Store[newx][newy] = element_info[element].move_leave_element; -#endif } -#else - Store[newx][newy] = EL_EMPTY; - if (IS_EQUAL_OR_IN_GROUP(new_element, MOVE_ENTER_EL(element)) || - element_info[element].move_leave_type == LEAVE_TYPE_UNLIMITED) - Store[newx][newy] = element_info[element].move_leave_element; -#endif -#else - if (IS_EQUAL_OR_IN_GROUP(new_element, MOVE_ENTER_EL(element))) - element_info[element].can_leave_element = TRUE; #endif if (move_pattern & MV_MAZE_RUNNER_STYLE) @@ -6248,9 +5679,6 @@ void StartMoving(int x, int y) PlayerVisit[x][y] /= 8; /* expire player visit path */ } } - -#endif - else if (element == EL_DRAGON && IN_LEV_FIELD(newx, newy)) { if (!IS_FREE(newx, newy)) @@ -6279,10 +5707,8 @@ void StartMoving(int x, int y) element1 != EL_DRAGON && element2 != EL_DRAGON && element1 != EL_FLAMES && element2 != EL_FLAMES) { -#if 1 ResetGfxAnimation(x, y); GfxAction[x][y] = ACTION_ATTACKING; -#endif if (IS_PLAYER(x, y)) DrawPlayerField(x, y); @@ -6344,12 +5770,15 @@ void StartMoving(int x, int y) #if 0 /* !!! test !!! */ if (IS_MOVING(newx, newy) || IS_BLOCKED(newx, newy)) + { + RemoveMovingField(newx, newy); + } #else if (IS_MOVING(newx, newy)) -#endif { RemoveMovingField(newx, newy); } +#endif else { Feld[newx][newy] = EL_EMPTY; @@ -6403,19 +5832,13 @@ void StartMoving(int x, int y) TurnRound(x, y); #if 0 + /* !!! NEW "CE_BLOCKED" STUFF !!! -- DOES NOT WORK YET... !!! */ if (move_pattern & MV_ANY_DIRECTION && move_pattern == MovDir[x][y]) { int blocking_element = (IN_LEV_FIELD(newx, newy) ? Feld[newx][newy] : BorderElement); -#if 0 - printf("::: '%s' is blocked by '%s'! [%d,%d -> %d,%d]\n", - element_info[element].token_name, - element_info[blocking_element].token_name, - x, y, newx, newy); -#endif - CheckElementChangeBySide(x, y, element, blocking_element, CE_BLOCKED, MovDir[x][y]); @@ -6423,31 +5846,11 @@ void StartMoving(int x, int y) } #endif -#if 1 if (GFX_ELEMENT(element) != EL_SAND) /* !!! FIX THIS (crumble) !!! */ DrawLevelElementAnimation(x, y, element); -#else - if (element == EL_BUG || - element == EL_SPACESHIP || - element == EL_SP_SNIKSNAK) - DrawLevelField(x, y); - else if (element == EL_MOLE) - DrawLevelField(x, y); - else if (element == EL_BD_BUTTERFLY || - element == EL_BD_FIREFLY) - DrawLevelElementAnimationIfNeeded(x, y, element); - else if (element == EL_SATELLITE) - DrawLevelElementAnimationIfNeeded(x, y, element); - else if (element == EL_SP_ELECTRON) - DrawLevelElementAnimationIfNeeded(x, y, element); -#endif if (DONT_TOUCH(element)) - TestIfBadThingTouchesHero(x, y); - -#if 0 - PlayLevelSoundAction(x, y, ACTION_WAITING); -#endif + TestIfBadThingTouchesPlayer(x, y); return; } @@ -6461,42 +5864,24 @@ void StartMoving(int x, int y) ContinueMoving(x, y); } -void dummy() -{ -} - void ContinueMoving(int x, int y) { int element = Feld[x][y]; - int stored = Store[x][y]; struct ElementInfo *ei = &element_info[element]; int direction = MovDir[x][y]; int dx = (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0); int dy = (direction == MV_UP ? -1 : direction == MV_DOWN ? +1 : 0); int newx = x + dx, newy = y + dy; -#if 0 - int nextx = newx + dx, nexty = newy + dy; -#endif -#if 1 + int stored = Store[x][y]; + int stored_new = Store[newx][newy]; boolean pushed_by_player = (Pushed[x][y] && IS_PLAYER(x, y)); boolean pushed_by_conveyor = (Pushed[x][y] && !IS_PLAYER(x, y)); -#else - boolean pushed_by_player = Pushed[x][y]; -#endif boolean last_line = (newy == lev_fieldy - 1); MovPos[x][y] += getElementMoveStepsize(x, y); -#if 0 - if (pushed_by_player && IS_PLAYER(x, y)) - { - /* special case: moving object pushed by player */ - MovPos[x][y] = SIGN(MovPos[x][y]) * (TILEX - ABS(PLAYERINFO(x,y)->MovPos)); - } -#else if (pushed_by_player) /* special case: moving object pushed by player */ MovPos[x][y] = SIGN(MovPos[x][y]) * (TILEX - ABS(PLAYERINFO(x,y)->MovPos)); -#endif if (ABS(MovPos[x][y]) < TILEX) { @@ -6511,12 +5896,10 @@ void ContinueMoving(int x, int y) Feld[newx][newy] = element; MovPos[x][y] = 0; /* force "not moving" for "crumbled sand" */ -#if 1 if (Store[x][y] == EL_ACID) /* element is moving into acid pool */ { element = Feld[newx][newy] = EL_ACID; } -#endif else if (element == EL_MOLE) { Feld[x][y] = EL_SAND; @@ -6546,6 +5929,10 @@ void ContinueMoving(int x, int y) if (!game.magic_wall_active) Feld[x][y] = EL_MAGIC_WALL_DEAD; element = Feld[newx][newy] = Store[x][y]; + +#if USE_NEW_CUSTOM_VALUE + InitField(newx, newy, FALSE); +#endif } else if (element == EL_BD_MAGIC_WALL_FILLING) { @@ -6560,6 +5947,10 @@ void ContinueMoving(int x, int y) if (!game.magic_wall_active) Feld[x][y] = EL_BD_MAGIC_WALL_DEAD; element = Feld[newx][newy] = Store[x][y]; + +#if USE_NEW_CUSTOM_VALUE + InitField(newx, newy, FALSE); +#endif } else if (element == EL_AMOEBA_DROPPING) { @@ -6576,48 +5967,48 @@ void ContinueMoving(int x, int y) Back[x][y] = Back[newx][newy] = 0; } -#if 0 - else if (Store[x][y] == EL_ACID) - { - element = Feld[newx][newy] = EL_ACID; - } -#endif -#if 0 - else if (IS_CUSTOM_ELEMENT(element) && !IS_PLAYER(x, y) && - ei->move_leave_element != EL_EMPTY && - (ei->move_leave_type == LEAVE_TYPE_UNLIMITED || - Store[x][y] != EL_EMPTY)) - { - /* some elements can leave other elements behind after moving */ - - Feld[x][y] = ei->move_leave_element; - InitField(x, y, FALSE); - - if (GFX_CRUMBLED(Feld[x][y])) - DrawLevelFieldCrumbledSandNeighbours(x, y); - } -#endif Store[x][y] = EL_EMPTY; MovPos[x][y] = 0; MovDir[x][y] = 0; MovDelay[x][y] = 0; + MovDelay[newx][newy] = 0; +#if 1 + if (CAN_CHANGE_OR_HAS_ACTION(element)) +#else if (CAN_CHANGE(element)) +#endif { /* copy element change control values to new field */ ChangeDelay[newx][newy] = ChangeDelay[x][y]; ChangePage[newx][newy] = ChangePage[x][y]; - Changed[newx][newy] = Changed[x][y]; + ChangeCount[newx][newy] = ChangeCount[x][y]; ChangeEvent[newx][newy] = ChangeEvent[x][y]; + +#if 0 +#if USE_NEW_CUSTOM_VALUE + CustomValue[newx][newy] = CustomValue[x][y]; +#endif +#endif } +#if 1 +#if USE_NEW_CUSTOM_VALUE + CustomValue[newx][newy] = CustomValue[x][y]; +#endif +#endif + ChangeDelay[x][y] = 0; ChangePage[x][y] = -1; - Changed[x][y] = FALSE; + ChangeCount[x][y] = 0; ChangeEvent[x][y] = -1; +#if USE_NEW_CUSTOM_VALUE + CustomValue[x][y] = 0; +#endif + /* copy animation control values to new field */ GfxFrame[newx][newy] = GfxFrame[x][y]; GfxRandom[newx][newy] = GfxRandom[x][y]; /* keep same random value */ @@ -6626,26 +6017,19 @@ void ContinueMoving(int x, int y) Pushed[x][y] = Pushed[newx][newy] = FALSE; -#if 0 - /* do this after checking for left-behind element */ - ResetGfxAnimation(x, y); /* reset animation values for old field */ -#endif - -#if 1 /* some elements can leave other elements behind after moving */ -#if 1 if (IS_CUSTOM_ELEMENT(element) && ei->move_leave_element != EL_EMPTY && (ei->move_leave_type == LEAVE_TYPE_UNLIMITED || stored != EL_EMPTY) && (!IS_PLAYER(x, y) || IS_WALKABLE(ei->move_leave_element))) -#else - if (IS_CUSTOM_ELEMENT(element) && ei->move_leave_element != EL_EMPTY && - (ei->move_leave_type == LEAVE_TYPE_UNLIMITED || stored != EL_EMPTY) && - !IS_PLAYER(x, y)) -#endif { int move_leave_element = ei->move_leave_element; -#if USE_CHANGE_TO_TRIGGERED +#if 1 + /* this makes it possible to leave the removed element again */ + if (ei->move_leave_element == EL_TRIGGER_ELEMENT) + move_leave_element = stored; +#else + /* this makes it possible to leave the removed element again */ if (ei->move_leave_type == LEAVE_TYPE_LIMITED && ei->move_leave_element == EL_TRIGGER_ELEMENT) move_leave_element = stored; @@ -6653,10 +6037,8 @@ void ContinueMoving(int x, int y) Feld[x][y] = move_leave_element; -#if USE_PREVIOUS_MOVE_DIR if (element_info[Feld[x][y]].move_direction_initial == MV_START_PREVIOUS) MovDir[x][y] = direction; -#endif InitField(x, y, FALSE); @@ -6666,63 +6048,16 @@ void ContinueMoving(int x, int y) if (ELEM_IS_PLAYER(move_leave_element)) RelocatePlayer(x, y, move_leave_element); } -#endif - -#if 0 - /* some elements can leave other elements behind after moving */ - if (IS_CUSTOM_ELEMENT(element) && !IS_PLAYER(x, y) && - ei->move_leave_element != EL_EMPTY && - (ei->move_leave_type == LEAVE_TYPE_UNLIMITED || - ei->can_leave_element_last)) - { - Feld[x][y] = ei->move_leave_element; - InitField(x, y, FALSE); - - if (GFX_CRUMBLED(Feld[x][y])) - DrawLevelFieldCrumbledSandNeighbours(x, y); - } - - ei->can_leave_element_last = ei->can_leave_element; - ei->can_leave_element = FALSE; -#endif -#if 1 /* do this after checking for left-behind element */ ResetGfxAnimation(x, y); /* reset animation values for old field */ -#endif - -#if 0 - /* 2.1.1 (does not work correctly for spring) */ - if (!CAN_MOVE(element)) - MovDir[newx][newy] = 0; -#else - -#if 0 - /* (does not work for falling objects that slide horizontally) */ - if (CAN_FALL(element) && MovDir[newx][newy] == MV_DOWN) - MovDir[newx][newy] = 0; -#else - /* - if (!CAN_MOVE(element) || - (element == EL_SPRING && MovDir[newx][newy] == MV_DOWN)) - MovDir[newx][newy] = 0; - */ -#if 0 - if (!CAN_MOVE(element) || - (CAN_FALL(element) && direction == MV_DOWN)) - GfxDir[x][y] = MovDir[newx][newy] = 0; -#else if (!CAN_MOVE(element) || (CAN_FALL(element) && direction == MV_DOWN && (element == EL_SPRING || element_info[element].move_pattern == MV_WHEN_PUSHED || element_info[element].move_pattern == MV_WHEN_DROPPED))) GfxDir[x][y] = MovDir[newx][newy] = 0; -#endif - -#endif -#endif DrawLevelField(x, y); DrawLevelField(newx, newy); @@ -6735,21 +6070,10 @@ void ContinueMoving(int x, int y) !(element_info[element].move_pattern & direction)) TurnRound(newx, newy); -#if 1 /* prevent elements on conveyor belt from moving on in last direction */ if (pushed_by_conveyor && CAN_FALL(element) && direction & MV_HORIZONTAL) - { -#if 0 - if (CAN_MOVE(element)) - InitMovDir(newx, newy); - else - MovDir[newx][newy] = 0; -#else MovDir[newx][newy] = 0; -#endif - } -#endif if (!pushed_by_player) { @@ -6767,7 +6091,7 @@ void ContinueMoving(int x, int y) if (DONT_TOUCH(element)) /* object may be nasty to player or others */ { - TestIfBadThingTouchesHero(newx, newy); + TestIfBadThingTouchesPlayer(newx, newy); TestIfBadThingTouchesFriend(newx, newy); if (!IS_CUSTOM_ELEMENT(element)) @@ -6776,147 +6100,38 @@ void ContinueMoving(int x, int y) else if (element == EL_PENGUIN) TestIfFriendTouchesBadThing(newx, newy); -#if USE_NEW_MOVE_STYLE -#if 0 - if (CAN_FALL(element) && direction == MV_DOWN && - !last_line && IS_PLAYER(x, newy + 1)) - printf("::: we would now kill the player [%d]\n", FrameCounter); -#endif - /* give the player one last chance (one more frame) to move away */ if (CAN_FALL(element) && direction == MV_DOWN && (last_line || (!IS_FREE(x, newy + 1) && (!IS_PLAYER(x, newy + 1) || game.engine_version < VERSION_IDENT(3,1,1,0))))) Impact(x, newy); -#else - if (CAN_FALL(element) && direction == MV_DOWN && - (last_line || !IS_FREE(x, newy + 1))) - Impact(x, newy); -#endif - -#if 1 -#if USE_PUSH_BUGFIX -#if 1 if (pushed_by_player && !game.use_change_when_pushing_bug) -#else - if (pushed_by_player && game.engine_version >= VERSION_IDENT(3,1,0,0)) -#endif -#else - if (pushed_by_player) -#endif - { -#if 1 - int dig_side = MV_DIR_OPPOSITE(direction); -#else - static int trigger_sides[4] = - { - CH_SIDE_RIGHT, /* moving left */ - CH_SIDE_LEFT, /* moving right */ - CH_SIDE_BOTTOM, /* moving up */ - CH_SIDE_TOP, /* moving down */ - }; - int dig_side = trigger_sides[MV_DIR_BIT(direction)]; -#endif + int push_side = MV_DIR_OPPOSITE(direction); struct PlayerInfo *player = PLAYERINFO(x, y); CheckElementChangeByPlayer(newx, newy, element, CE_PUSHED_BY_PLAYER, - player->index_bit, dig_side); + player->index_bit, push_side); CheckTriggeredElementChangeByPlayer(newx,newy, element, CE_PLAYER_PUSHES_X, - player->index_bit, dig_side); + player->index_bit, push_side); } -#endif - -#if 1 - TestIfElementTouchesCustomElement(x, y); /* empty or new element */ -#endif -#if 0 - if (ChangePage[newx][newy] != -1) /* delayed change */ - ChangeElement(newx, newy, ChangePage[newx][newy]); -#endif + CheckTriggeredElementChangeBySide(x, y, element, CE_MOVE_OF_X, direction); -#if 1 + TestIfElementTouchesCustomElement(x, y); /* empty or new element */ TestIfElementHitsCustomElement(newx, newy, direction); - -#else - - if (!IN_LEV_FIELD(nextx, nexty) || !IS_FREE(nextx, nexty)) - { - int hitting_element = Feld[newx][newy]; - - /* !!! fix side (direction) orientation here and elsewhere !!! */ - CheckElementChangeBySide(newx, newy, hitting_element, CE_HITTING_SOMETHING, - direction); - -#if 0 - if (IN_LEV_FIELD(nextx, nexty)) - { - int opposite_direction = MV_DIR_OPPOSITE(direction); - int hitting_side = direction; - int touched_side = opposite_direction; - int touched_element = MovingOrBlocked2Element(nextx, nexty); - boolean object_hit = (!IS_MOVING(nextx, nexty) || - MovDir[nextx][nexty] != direction || - ABS(MovPos[nextx][nexty]) <= TILEY / 2); - - if (object_hit) - { - int i; - - CheckElementChangeBySide(nextx, nexty, touched_element, - CE_HIT_BY_SOMETHING, opposite_direction); - - if (IS_CUSTOM_ELEMENT(hitting_element) && - HAS_ANY_CHANGE_EVENT(hitting_element, CE_HITTING_X)) - { - for (i = 0; i < element_info[hitting_element].num_change_pages; i++) - { - struct ElementChangeInfo *change = - &element_info[hitting_element].change_page[i]; - - if (change->can_change && - change->has_event[CE_HITTING_X] && - change->trigger_side & touched_side && - change->trigger_element == touched_element) - { - CheckElementChangeByPage(newx, newy, hitting_element, - touched_element, CE_HITTING_X, i); - break; - } - } - } - - if (IS_CUSTOM_ELEMENT(touched_element) && - HAS_ANY_CHANGE_EVENT(touched_element, CE_HIT_BY_X)) - { - for (i = 0; i < element_info[touched_element].num_change_pages; i++) - { - struct ElementChangeInfo *change = - &element_info[touched_element].change_page[i]; - - if (change->can_change && - change->has_event[CE_HIT_BY_X] && - change->trigger_side & hitting_side && - change->trigger_element == hitting_element) - { - CheckElementChangeByPage(nextx, nexty, touched_element, - hitting_element, CE_HIT_BY_X,i); - break; - } - } - } - } - } -#endif - } -#endif - TestIfPlayerTouchesCustomElement(newx, newy); TestIfElementTouchesCustomElement(newx, newy); + +#if 1 + if (IS_CUSTOM_ELEMENT(element) && ei->move_enter_element != EL_EMPTY && + IS_EQUAL_OR_IN_GROUP(stored_new, ei->move_enter_element)) + CheckElementChangeBySide(newx, newy, element, stored_new, CE_DIGGING_X, + MV_DIR_OPPOSITE(direction)); +#endif } int AmoebeNachbarNr(int ax, int ay) @@ -6985,13 +6200,14 @@ void AmoebenVereinigen(int ax, int ay) AmoebaCnt2[new_group_nr] += AmoebaCnt2[old_group_nr]; AmoebaCnt2[old_group_nr] = 0; - for (yy = 0; yy < lev_fieldy; yy++) +#if 1 + SCAN_PLAYFIELD(xx, yy) +#else + for (yy = 0; yy < lev_fieldy; yy++) for (xx = 0; xx < lev_fieldx; xx++) +#endif { - for (xx = 0; xx < lev_fieldx; xx++) - { - if (AmoebaNr[xx][yy] == old_group_nr) - AmoebaNr[xx][yy] = new_group_nr; - } + if (AmoebaNr[xx][yy] == old_group_nr) + AmoebaNr[xx][yy] = new_group_nr; } } } @@ -7014,17 +6230,19 @@ void AmoebeUmwandeln(int ax, int ay) } #endif - for (y = 0; y < lev_fieldy; y++) +#if 1 + SCAN_PLAYFIELD(x, y) +#else + for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) +#endif { - for (x = 0; x < lev_fieldx; x++) + if (Feld[x][y] == EL_AMOEBA_DEAD && AmoebaNr[x][y] == group_nr) { - if (Feld[x][y] == EL_AMOEBA_DEAD && AmoebaNr[x][y] == group_nr) - { - AmoebaNr[x][y] = 0; - Feld[x][y] = EL_AMOEBA_TO_DIAMOND; - } + AmoebaNr[x][y] = 0; + Feld[x][y] = EL_AMOEBA_TO_DIAMOND; } } + PlayLevelSound(ax, ay, (IS_GEM(level.amoeba_content) ? SND_AMOEBA_TURNING_TO_GEM : SND_AMOEBA_TURNING_TO_ROCK)); @@ -7074,21 +6292,22 @@ void AmoebeUmwandelnBD(int ax, int ay, int new_element) } #endif - for (y = 0; y < lev_fieldy; y++) +#if 1 + SCAN_PLAYFIELD(x, y) +#else + for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) +#endif { - for (x = 0; x < lev_fieldx; x++) + if (AmoebaNr[x][y] == group_nr && + (Feld[x][y] == EL_AMOEBA_DEAD || + Feld[x][y] == EL_BD_AMOEBA || + Feld[x][y] == EL_AMOEBA_GROWING)) { - if (AmoebaNr[x][y] == group_nr && - (Feld[x][y] == EL_AMOEBA_DEAD || - Feld[x][y] == EL_BD_AMOEBA || - Feld[x][y] == EL_AMOEBA_GROWING)) - { - AmoebaNr[x][y] = 0; - Feld[x][y] = new_element; - InitField(x, y, FALSE); - DrawLevelField(x, y); - done = TRUE; - } + AmoebaNr[x][y] = 0; + Feld[x][y] = new_element; + InitField(x, y, FALSE); + DrawLevelField(x, y); + done = TRUE; } } @@ -7109,14 +6328,7 @@ void AmoebeWaechst(int x, int y) if (DelayReached(&sound_delay, sound_delay_value)) { -#if 1 PlayLevelSoundElementAction(x, y, Store[x][y], ACTION_GROWING); -#else - if (Store[x][y] == EL_BD_AMOEBA) - PlayLevelSound(x, y, SND_BD_AMOEBA_GROWING); - else - PlayLevelSound(x, y, SND_AMOEBA_GROWING); -#endif sound_delay_value = 30; } } @@ -7220,7 +6432,6 @@ void AmoebeAbleger(int ax, int ay) if (!IN_LEV_FIELD(x, y)) return; -#if 1 if (IS_FREE(x, y) || CAN_GROW_INTO(Feld[x][y]) || Feld[x][y] == EL_QUICKSAND_EMPTY) @@ -7228,15 +6439,6 @@ void AmoebeAbleger(int ax, int ay) newax = x; neway = y; } -#else - /* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */ - if (IS_FREE(x, y) || - Feld[x][y] == EL_SAND || Feld[x][y] == EL_QUICKSAND_EMPTY) - { - newax = x; - neway = y; - } -#endif if (newax == ax && neway == ay) return; @@ -7255,7 +6457,6 @@ void AmoebeAbleger(int ax, int ay) if (!IN_LEV_FIELD(x, y)) continue; -#if 1 if (IS_FREE(x, y) || CAN_GROW_INTO(Feld[x][y]) || Feld[x][y] == EL_QUICKSAND_EMPTY) @@ -7264,27 +6465,13 @@ void AmoebeAbleger(int ax, int ay) neway = y; break; } -#else - /* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */ - if (IS_FREE(x, y) || - Feld[x][y] == EL_SAND || Feld[x][y] == EL_QUICKSAND_EMPTY) - { - newax = x; - neway = y; - break; - } -#endif else if (IS_PLAYER(x, y)) waiting_for_player = TRUE; } if (newax == ax && neway == ay) /* amoeba cannot grow */ { -#if 1 if (i == 4 && (!waiting_for_player || element == EL_BD_AMOEBA)) -#else - if (i == 4 && (!waiting_for_player || game.emulation == EMU_BOULDERDASH)) -#endif { Feld[ax][ay] = EL_AMOEBA_DEAD; DrawLevelField(ax, ay); @@ -7339,11 +6526,8 @@ void AmoebeAbleger(int ax, int ay) else if (neway == ay) { Feld[newax][neway] = EL_AMOEBA_DROP; /* drop left/right of amoeba */ -#if 1 + PlayLevelSoundAction(newax, neway, ACTION_GROWING); -#else - PlayLevelSound(newax, neway, SND_AMOEBA_GROWING); -#endif } else { @@ -7360,10 +6544,14 @@ void AmoebeAbleger(int ax, int ay) void Life(int ax, int ay) { int x1, y1, x2, y2; +#if 0 static int life[4] = { 2, 3, 3, 3 }; /* parameters for "game of life" */ +#endif int life_time = 40; int element = Feld[ax][ay]; int graphic = el2img(element); + int *life_parameter = (element == EL_GAME_OF_LIFE ? level.game_of_life : + level.biomaze); boolean changed = FALSE; if (IS_ANIMATED(graphic)) @@ -7406,7 +6594,8 @@ void Life(int ax, int ay) if (xx == ax && yy == ay) /* field in the middle */ { - if (nachbarn < life[0] || nachbarn > life[1]) + if (nachbarn < life_parameter[0] || + nachbarn > life_parameter[1]) { Feld[xx][yy] = EL_EMPTY; if (!Stop[xx][yy]) @@ -7415,24 +6604,10 @@ void Life(int ax, int ay) changed = TRUE; } } -#if 1 else if (IS_FREE(xx, yy) || CAN_GROW_INTO(Feld[xx][yy])) { /* free border field */ - if (nachbarn >= life[2] && nachbarn <= life[3]) - { - Feld[xx][yy] = element; - MovDelay[xx][yy] = (element == EL_GAME_OF_LIFE ? 0 : life_time-1); - if (!Stop[xx][yy]) - DrawLevelField(xx, yy); - Stop[xx][yy] = TRUE; - changed = TRUE; - } - } -#else - /* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */ - else if (IS_FREE(xx, yy) || Feld[xx][yy] == EL_SAND) - { /* free border field */ - if (nachbarn >= life[2] && nachbarn <= life[3]) + if (nachbarn >= life_parameter[2] && + nachbarn <= life_parameter[3]) { Feld[xx][yy] = element; MovDelay[xx][yy] = (element == EL_GAME_OF_LIFE ? 0 : life_time-1); @@ -7442,7 +6617,6 @@ void Life(int ax, int ay) changed = TRUE; } } -#endif } if (changed) @@ -7468,12 +6642,7 @@ static void StopRobotWheel(int x, int y) static void InitTimegateWheel(int x, int y) { -#if 1 ChangeDelay[x][y] = level.time_timegate * FRAMES_PER_SECOND; -#else - /* another brainless, "type style" bug ... :-( */ - ChangeDelay[x][y] = level.time_wheel * FRAMES_PER_SECOND; -#endif } static void RunTimegateWheel(int x, int y) @@ -7481,6 +6650,47 @@ static void RunTimegateWheel(int x, int y) PlayLevelSound(x, y, SND_TIMEGATE_SWITCH_ACTIVE); } +static void InitMagicBallDelay(int x, int y) +{ +#if 1 + ChangeDelay[x][y] = (level.ball_time + 1) * 8 + 1; +#else + ChangeDelay[x][y] = level.ball_time * FRAMES_PER_SECOND + 1; +#endif +} + +static void ActivateMagicBall(int bx, int by) +{ + int x, y; + + if (level.ball_random) + { + int pos_border = RND(8); /* select one of the eight border elements */ + int pos_content = (pos_border > 3 ? pos_border + 1 : pos_border); + int xx = pos_content % 3; + int yy = pos_content / 3; + + x = bx - 1 + xx; + y = by - 1 + yy; + + if (IN_LEV_FIELD(x, y) && Feld[x][y] == EL_EMPTY) + CreateField(x, y, level.ball_content[game.ball_content_nr].e[xx][yy]); + } + else + { + for (y = by - 1; y <= by + 1; y++) for (x = bx - 1; x <= bx + 1; x++) + { + int xx = x - bx + 1; + int yy = y - by + 1; + + if (IN_LEV_FIELD(x, y) && Feld[x][y] == EL_EMPTY) + CreateField(x, y, level.ball_content[game.ball_content_nr].e[xx][yy]); + } + } + + game.ball_content_nr = (game.ball_content_nr + 1) % level.num_ball_contents; +} + void CheckExit(int x, int y) { if (local_player->gems_still_needed > 0 || @@ -7529,21 +6739,19 @@ static void CloseAllOpenTimegates() { int x, y; - for (y = 0; y < lev_fieldy; y++) - { - for (x = 0; x < lev_fieldx; x++) - { - int element = Feld[x][y]; - - if (element == EL_TIMEGATE_OPEN || element == EL_TIMEGATE_OPENING) - { - Feld[x][y] = EL_TIMEGATE_CLOSING; #if 1 - PlayLevelSoundAction(x, y, ACTION_CLOSING); + SCAN_PLAYFIELD(x, y) #else - PlayLevelSound(x, y, SND_TIMEGATE_CLOSING); + for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) #endif - } + { + int element = Feld[x][y]; + + if (element == EL_TIMEGATE_OPEN || element == EL_TIMEGATE_OPENING) + { + Feld[x][y] = EL_TIMEGATE_CLOSING; + + PlayLevelSoundAction(x, y, ACTION_CLOSING); } } } @@ -7634,7 +6842,7 @@ void MauerWaechst(int x, int y) Feld[x][y] = Store[x][y]; Store[x][y] = 0; - GfxDir[x][y] = MovDir[x][y] = MV_NO_MOVING; + GfxDir[x][y] = MovDir[x][y] = MV_NONE; DrawLevelField(x, y); } } @@ -7744,11 +6952,7 @@ void MauerAbleger(int ax, int ay) Feld[ax][ay] = EL_WALL; if (new_wall) -#if 1 PlayLevelSoundAction(ax, ay, ACTION_GROWING); -#else - PlayLevelSound(ax, ay, SND_EXPANDABLE_WALL_GROWING); -#endif } void CheckForDragon(int x, int y) @@ -7857,213 +7061,566 @@ static void ChangeActiveTrap(int x, int y) DrawLevelFieldCrumbledSand(x, y); } -static void ChangeElementNowExt(int x, int y, int target_element) +static int getSpecialActionElement(int element, int number, int base_element) { - int previous_move_direction = MovDir[x][y]; -#if 1 - boolean add_player = (ELEM_IS_PLAYER(target_element) && - IS_WALKABLE(Feld[x][y])); -#else - boolean add_player = (ELEM_IS_PLAYER(target_element) && - IS_WALKABLE(Feld[x][y]) && - !IS_MOVING(x, y)); -#endif + return (element != EL_EMPTY ? element : + number != -1 ? base_element + number - 1 : + EL_EMPTY); +} - /* check if element under player changes from accessible to unaccessible - (needed for special case of dropping element which then changes) */ - if (IS_PLAYER(x, y) && !PLAYER_EXPLOSION_PROTECTED(x, y) && - IS_ACCESSIBLE(Feld[x][y]) && !IS_ACCESSIBLE(target_element)) - { -#if 0 - printf("::: BOOOM! [%d, '%s']\n", target_element, - element_info[target_element].token_name); -#endif +static int getModifiedActionNumber(int value_old, int operator, int operand, + int value_min, int value_max) +{ + int value_new = (operator == CA_MODE_SET ? operand : + operator == CA_MODE_ADD ? value_old + operand : + operator == CA_MODE_SUBTRACT ? value_old - operand : + operator == CA_MODE_MULTIPLY ? value_old * operand : + operator == CA_MODE_DIVIDE ? value_old / MAX(1, operand) : + operator == CA_MODE_MODULO ? value_old % MAX(1, operand) : + value_old); - Bang(x, y); + return (value_new < value_min ? value_min : + value_new > value_max ? value_max : + value_new); +} + +static void ExecuteCustomElementAction(int x, int y, int element, int page) +{ + struct ElementInfo *ei = &element_info[element]; + struct ElementChangeInfo *change = &ei->change_page[page]; + int action_type = change->action_type; + int action_mode = change->action_mode; + int action_arg = change->action_arg; + int i; + + if (!change->has_action) return; - } -#if 1 - if (!add_player) -#endif - { -#if 1 - if (IS_MOVING(x, y) || IS_BLOCKED(x, y)) - RemoveMovingField(x, y); - else - RemoveField(x, y); + /* ---------- determine action paramater values -------------------------- */ + + int level_time_value = + (level.time > 0 ? TimeLeft : + TimePlayed); + + int action_arg_element = + (action_arg == CA_ARG_PLAYER_TRIGGER ? change->actual_trigger_player : + action_arg == CA_ARG_ELEMENT_TRIGGER ? change->actual_trigger_element : + action_arg == CA_ARG_ELEMENT_TARGET ? change->target_element : + EL_EMPTY); + + int action_arg_direction = + (action_arg >= CA_ARG_DIRECTION_LEFT && + action_arg <= CA_ARG_DIRECTION_DOWN ? action_arg - CA_ARG_DIRECTION : + action_arg == CA_ARG_DIRECTION_TRIGGER ? + change->actual_trigger_side : + action_arg == CA_ARG_DIRECTION_TRIGGER_BACK ? + MV_DIR_OPPOSITE(change->actual_trigger_side) : + MV_NONE); + + int action_arg_number_min = + (action_type == CA_SET_PLAYER_SPEED ? STEPSIZE_NOT_MOVING : + CA_ARG_MIN); + + int action_arg_number_max = + (action_type == CA_SET_PLAYER_SPEED ? STEPSIZE_EVEN_FASTER : + action_type == CA_SET_LEVEL_GEMS ? 999 : + action_type == CA_SET_LEVEL_TIME ? 9999 : + action_type == CA_SET_LEVEL_SCORE ? 99999 : + action_type == CA_SET_CE_SCORE ? 9999 : + action_type == CA_SET_CE_VALUE ? 9999 : + CA_ARG_MAX); + + int action_arg_number_reset = + (action_type == CA_SET_PLAYER_SPEED ? level.initial_player_stepsize : + action_type == CA_SET_LEVEL_GEMS ? level.gems_needed : + action_type == CA_SET_LEVEL_TIME ? level.time : + action_type == CA_SET_LEVEL_SCORE ? 0 : + action_type == CA_SET_CE_SCORE ? 0 : +#if 1 + action_type == CA_SET_CE_VALUE ? GET_NEW_CUSTOM_VALUE(element) : +#else + action_type == CA_SET_CE_VALUE ? ei->custom_value_initial : +#endif + 0); + + int action_arg_number = + (action_arg <= CA_ARG_MAX ? action_arg : + action_arg >= CA_ARG_SPEED_NOT_MOVING && + action_arg <= CA_ARG_SPEED_EVEN_FASTER ? (action_arg - CA_ARG_SPEED) : + action_arg == CA_ARG_SPEED_RESET ? action_arg_number_reset : + action_arg == CA_ARG_NUMBER_MIN ? action_arg_number_min : + action_arg == CA_ARG_NUMBER_MAX ? action_arg_number_max : + action_arg == CA_ARG_NUMBER_RESET ? action_arg_number_reset : + action_arg == CA_ARG_NUMBER_CE_SCORE ? ei->collect_score : +#if USE_NEW_CUSTOM_VALUE + action_arg == CA_ARG_NUMBER_CE_VALUE ? CustomValue[x][y] : +#else + action_arg == CA_ARG_NUMBER_CE_VALUE ? ei->custom_value_initial : +#endif + action_arg == CA_ARG_NUMBER_CE_DELAY ? GET_CE_DELAY_VALUE(change) : + action_arg == CA_ARG_NUMBER_LEVEL_TIME ? level_time_value : + action_arg == CA_ARG_NUMBER_LEVEL_GEMS ? local_player->gems_still_needed : + action_arg == CA_ARG_NUMBER_LEVEL_SCORE ? local_player->score : + action_arg == CA_ARG_ELEMENT_TARGET ? GET_NEW_CUSTOM_VALUE(change->target_element) : + action_arg == CA_ARG_ELEMENT_TRIGGER ? change->actual_trigger_ce_value : + -1); + + int action_arg_number_old = + (action_type == CA_SET_LEVEL_GEMS ? local_player->gems_still_needed : + action_type == CA_SET_LEVEL_TIME ? TimeLeft : + action_type == CA_SET_LEVEL_SCORE ? local_player->score : + action_type == CA_SET_CE_SCORE ? ei->collect_score : + action_type == CA_SET_CE_VALUE ? CustomValue[x][y] : + 0); + + int action_arg_number_new = + getModifiedActionNumber(action_arg_number_old, + action_mode, action_arg_number, + action_arg_number_min, action_arg_number_max); + + int trigger_player_bits = + (change->actual_trigger_player >= EL_PLAYER_1 && + change->actual_trigger_player <= EL_PLAYER_4 ? + (1 << (change->actual_trigger_player - EL_PLAYER_1)) : + PLAYER_BITS_ANY); + + int action_arg_player_bits = + (action_arg >= CA_ARG_PLAYER_1 && + action_arg <= CA_ARG_PLAYER_4 ? action_arg - CA_ARG_PLAYER : + action_arg == CA_ARG_PLAYER_TRIGGER ? trigger_player_bits : + PLAYER_BITS_ANY); + + /* ---------- execute action -------------------------------------------- */ + + switch(action_type) + { + case CA_NO_ACTION: + { + return; + } - Feld[x][y] = target_element; -#else - RemoveField(x, y); - Feld[x][y] = target_element; -#endif + /* ---------- level actions ------------------------------------------- */ - ResetGfxAnimation(x, y); - ResetRandomAnimationValue(x, y); + case CA_RESTART_LEVEL: + { + game.restart_level = TRUE; - if (element_info[Feld[x][y]].move_direction_initial == MV_START_PREVIOUS) - MovDir[x][y] = previous_move_direction; + break; + } -#if 1 - InitField_WithBug1(x, y, FALSE); -#else - InitField(x, y, FALSE); - if (CAN_MOVE(Feld[x][y])) - InitMovDir(x, y); -#endif + case CA_SHOW_ENVELOPE: + { + int element = getSpecialActionElement(action_arg_element, + action_arg_number, EL_ENVELOPE_1); - DrawLevelField(x, y); + if (IS_ENVELOPE(element)) + local_player->show_envelope = element; - if (GFX_CRUMBLED(Feld[x][y])) - DrawLevelFieldCrumbledSandNeighbours(x, y); - } + break; + } -#if 0 - Changed[x][y] |= ChangeEvent[x][y]; /* ignore same changes in this frame */ -#endif + case CA_SET_LEVEL_TIME: + { + if (level.time > 0) /* only modify limited time value */ + { + TimeLeft = action_arg_number_new; -#if 0 - TestIfBadThingTouchesHero(x, y); - TestIfPlayerTouchesCustomElement(x, y); - TestIfElementTouchesCustomElement(x, y); -#endif + DrawGameValue_Time(TimeLeft); - /* "Changed[][]" not set yet to allow "entered by player" change one time */ - if (ELEM_IS_PLAYER(target_element)) - RelocatePlayer(x, y, target_element); + if (!TimeLeft && setup.time_limit) + for (i = 0; i < MAX_PLAYERS; i++) + KillPlayer(&stored_player[i]); + } -#if 1 - Changed[x][y] = TRUE; /* ignore all further changes in this frame */ -#else - Changed[x][y] |= ChangeEvent[x][y]; /* ignore same changes in this frame */ -#endif + break; + } -#if 1 - TestIfBadThingTouchesHero(x, y); - TestIfPlayerTouchesCustomElement(x, y); - TestIfElementTouchesCustomElement(x, y); -#endif -} + case CA_SET_LEVEL_SCORE: + { + local_player->score = action_arg_number_new; -static boolean ChangeElementNow(int x, int y, int element, int page) -{ - struct ElementChangeInfo *change = &element_info[element].change_page[page]; - int target_element; - int old_element = Feld[x][y]; + DrawGameValue_Score(local_player->score); - /* always use default change event to prevent running into a loop */ - if (ChangeEvent[x][y] == -1) - ChangeEvent[x][y] = CE_DELAY; + break; + } - if (ChangeEvent[x][y] == CE_DELAY) - { - /* reset actual trigger element and player */ - change->actual_trigger_element = EL_EMPTY; - change->actual_trigger_player = EL_PLAYER_1; - } + case CA_SET_LEVEL_GEMS: + { + local_player->gems_still_needed = action_arg_number_new; -#if 1 - /* do not change any elements that have already changed in this frame */ - if (Changed[x][y]) - return FALSE; -#else - /* do not change already changed elements with same change event */ - if (Changed[x][y] & ChangeEvent[x][y]) - return FALSE; -#endif + DrawGameValue_Emeralds(local_player->gems_still_needed); -#if 1 - Changed[x][y] = TRUE; /* ignore all further changes in this frame */ -#else - Changed[x][y] |= ChangeEvent[x][y]; /* ignore same changes in this frame */ -#endif + break; + } -#if 0 - /* !!! indirect change before direct change !!! */ - CheckTriggeredElementChangeByPage(x, y, Feld[x][y], CE_CHANGE_OF_X, page); -#endif + case CA_SET_LEVEL_GRAVITY: + { + game.gravity = (action_arg == CA_ARG_GRAVITY_OFF ? FALSE : + action_arg == CA_ARG_GRAVITY_ON ? TRUE : + action_arg == CA_ARG_GRAVITY_TOGGLE ? !game.gravity : + game.gravity); + break; + } - if (change->explode) - { - Bang(x, y); + case CA_SET_LEVEL_WIND: + { + game.wind_direction = action_arg_direction; - return TRUE; - } + break; + } - if (change->use_target_content) - { - boolean complete_replace = TRUE; - boolean can_replace[3][3]; - int xx, yy; + /* ---------- player actions ------------------------------------------ */ - for (yy = 0; yy < 3; yy++) for (xx = 0; xx < 3 ; xx++) + case CA_MOVE_PLAYER: { - boolean is_empty; - boolean is_walkable; - boolean is_diggable; - boolean is_collectible; - boolean is_removable; - boolean is_destructible; - int ex = x + xx - 1; - int ey = y + yy - 1; - int content_element = change->target_content[xx][yy]; - int e; + /* automatically move to the next field in specified direction */ + for (i = 0; i < MAX_PLAYERS; i++) + if (trigger_player_bits & (1 << i)) + stored_player[i].programmed_action = action_arg_direction; - can_replace[xx][yy] = TRUE; + break; + } - if (ex == x && ey == y) /* do not check changing element itself */ - continue; + case CA_EXIT_PLAYER: + { + for (i = 0; i < MAX_PLAYERS; i++) + if (action_arg_player_bits & (1 << i)) + stored_player[i].LevelSolved = stored_player[i].GameOver = TRUE; - if (content_element == EL_EMPTY_SPACE) - { - can_replace[xx][yy] = FALSE; /* do not replace border with space */ + break; + } - continue; - } + case CA_KILL_PLAYER: + { + for (i = 0; i < MAX_PLAYERS; i++) + if (action_arg_player_bits & (1 << i)) + KillPlayer(&stored_player[i]); - if (!IN_LEV_FIELD(ex, ey)) - { - can_replace[xx][yy] = FALSE; - complete_replace = FALSE; + break; + } - continue; - } + case CA_SET_PLAYER_KEYS: + { + int key_state = (action_mode == CA_MODE_ADD ? TRUE : FALSE); + int element = getSpecialActionElement(action_arg_element, + action_arg_number, EL_KEY_1); -#if 0 - if (Changed[ex][ey]) /* do not change already changed elements */ + if (IS_KEY(element)) { - can_replace[xx][yy] = FALSE; - complete_replace = FALSE; + for (i = 0; i < MAX_PLAYERS; i++) + { + if (trigger_player_bits & (1 << i)) + { + stored_player[i].key[KEY_NR(element)] = key_state; - continue; + DrawGameValue_Keys(stored_player[i].key); + + redraw_mask |= REDRAW_DOOR_1; + } + } } -#endif - e = Feld[ex][ey]; + break; + } - if (IS_MOVING(ex, ey) || IS_BLOCKED(ex, ey)) - e = MovingOrBlocked2Element(ex, ey); + case CA_SET_PLAYER_SPEED: + { + for (i = 0; i < MAX_PLAYERS; i++) + { + if (trigger_player_bits & (1 << i)) + { + int move_stepsize = TILEX / stored_player[i].move_delay_value; -#if 1 + if (action_arg == CA_ARG_SPEED_FASTER && + stored_player[i].cannot_move) + { + action_arg_number = STEPSIZE_VERY_SLOW; + } + else if (action_arg == CA_ARG_SPEED_SLOWER || + action_arg == CA_ARG_SPEED_FASTER) + { + action_arg_number = 2; + action_mode = (action_arg == CA_ARG_SPEED_SLOWER ? CA_MODE_DIVIDE : + CA_MODE_MULTIPLY); + } -#if 0 - is_empty = (IS_FREE(ex, ey) || - (IS_PLAYER(ex, ey) && IS_WALKABLE(content_element)) || - (IS_WALKABLE(e) && ELEM_IS_PLAYER(content_element) && - !IS_MOVING(ex, ey) && !IS_BLOCKED(ex, ey))); -#else + move_stepsize = + getModifiedActionNumber(move_stepsize, + action_mode, + action_arg_number, + action_arg_number_min, + action_arg_number_max); -#if 0 - is_empty = (IS_FREE(ex, ey) || - (IS_PLAYER(ex, ey) && IS_WALKABLE(content_element))); +#if 1 + SetPlayerMoveSpeed(&stored_player[i], move_stepsize, FALSE); #else - is_empty = (IS_FREE(ex, ey) || - (IS_FREE_OR_PLAYER(ex, ey) && IS_WALKABLE(content_element))); + /* make sure that value is power of 2 */ + move_stepsize = (1 << log_2(move_stepsize)); + + /* do no immediately change -- the player might just be moving */ + stored_player[i].move_delay_value_next = TILEX / move_stepsize; + + stored_player[i].cannot_move = + (action_arg == CA_ARG_SPEED_NOT_MOVING ? TRUE : FALSE); +#endif + } + } + + break; + } + + case CA_SET_PLAYER_SHIELD: + { + for (i = 0; i < MAX_PLAYERS; i++) + { + if (trigger_player_bits & (1 << i)) + { + if (action_arg == CA_ARG_SHIELD_OFF) + { + stored_player[i].shield_normal_time_left = 0; + stored_player[i].shield_deadly_time_left = 0; + } + else if (action_arg == CA_ARG_SHIELD_NORMAL) + { + stored_player[i].shield_normal_time_left = 999999; + } + else if (action_arg == CA_ARG_SHIELD_DEADLY) + { + stored_player[i].shield_normal_time_left = 999999; + stored_player[i].shield_deadly_time_left = 999999; + } + } + } + + break; + } + + case CA_SET_PLAYER_ARTWORK: + { + for (i = 0; i < MAX_PLAYERS; i++) + { + if (trigger_player_bits & (1 << i)) + { + int artwork_element = action_arg_element; + + if (action_arg == CA_ARG_ELEMENT_RESET) + artwork_element = + (level.use_artwork_element[i] ? level.artwork_element[i] : + stored_player[i].element_nr); + + stored_player[i].artwork_element = artwork_element; + + SetPlayerWaiting(&stored_player[i], FALSE); + + /* set number of special actions for bored and sleeping animation */ + stored_player[i].num_special_action_bored = + get_num_special_action(artwork_element, + ACTION_BORING_1, ACTION_BORING_LAST); + stored_player[i].num_special_action_sleeping = + get_num_special_action(artwork_element, + ACTION_SLEEPING_1, ACTION_SLEEPING_LAST); + } + } + + break; + } + + /* ---------- CE actions ---------------------------------------------- */ + + case CA_SET_CE_SCORE: + { + ei->collect_score = action_arg_number_new; + + break; + } + + case CA_SET_CE_VALUE: + { +#if USE_NEW_CUSTOM_VALUE + int last_custom_value = CustomValue[x][y]; + + CustomValue[x][y] = action_arg_number_new; + +#if 0 + printf("::: Count == %d\n", CustomValue[x][y]); +#endif + + if (CustomValue[x][y] == 0 && last_custom_value > 0) + { +#if 0 + printf("::: CE_VALUE_GETS_ZERO\n"); +#endif + + CheckElementChange(x, y, element, EL_UNDEFINED, CE_VALUE_GETS_ZERO); + CheckTriggeredElementChange(x, y, element, CE_VALUE_GETS_ZERO_OF_X); + } +#endif + + break; + } + + /* ---------- engine actions ------------------------------------------ */ + + case CA_SET_ENGINE_SCAN_MODE: + { + InitPlayfieldScanMode(action_arg); + + break; + } + + default: + break; + } +} + +static void CreateFieldExt(int x, int y, int element, boolean is_change) +{ + int previous_move_direction = MovDir[x][y]; +#if USE_NEW_CUSTOM_VALUE + int last_ce_value = CustomValue[x][y]; #endif + boolean add_player = (ELEM_IS_PLAYER(element) && + IS_WALKABLE(Feld[x][y])); + + /* check if element under player changes from accessible to unaccessible + (needed for special case of dropping element which then changes) */ + if (IS_PLAYER(x, y) && !PLAYER_EXPLOSION_PROTECTED(x, y) && + IS_ACCESSIBLE(Feld[x][y]) && !IS_ACCESSIBLE(element)) + { + Bang(x, y); + + return; + } + + if (!add_player) + { + if (IS_MOVING(x, y) || IS_BLOCKED(x, y)) + RemoveMovingField(x, y); + else + RemoveField(x, y); + + Feld[x][y] = element; + + ResetGfxAnimation(x, y); + ResetRandomAnimationValue(x, y); + + if (element_info[Feld[x][y]].move_direction_initial == MV_START_PREVIOUS) + MovDir[x][y] = previous_move_direction; +#if USE_NEW_CUSTOM_VALUE + if (element_info[Feld[x][y]].use_last_ce_value) + CustomValue[x][y] = last_ce_value; #endif + InitField_WithBug1(x, y, FALSE); + + DrawLevelField(x, y); + + if (GFX_CRUMBLED(Feld[x][y])) + DrawLevelFieldCrumbledSandNeighbours(x, y); + } + + /* "ChangeCount" not set yet to allow "entered by player" change one time */ + if (ELEM_IS_PLAYER(element)) + RelocatePlayer(x, y, element); + + if (is_change) + ChangeCount[x][y]++; /* count number of changes in the same frame */ + + TestIfBadThingTouchesPlayer(x, y); + TestIfPlayerTouchesCustomElement(x, y); + TestIfElementTouchesCustomElement(x, y); +} + +static void CreateField(int x, int y, int element) +{ + CreateFieldExt(x, y, element, FALSE); +} + +static void CreateElementFromChange(int x, int y, int element) +{ + CreateFieldExt(x, y, element, TRUE); +} + +static boolean ChangeElement(int x, int y, int element, int page) +{ + struct ElementChangeInfo *change = &element_info[element].change_page[page]; + int target_element; + int old_element = Feld[x][y]; + + /* always use default change event to prevent running into a loop */ + if (ChangeEvent[x][y] == -1) + ChangeEvent[x][y] = CE_DELAY; + + if (ChangeEvent[x][y] == CE_DELAY) + { + /* reset actual trigger element, trigger player and action element */ + change->actual_trigger_element = EL_EMPTY; + change->actual_trigger_player = EL_PLAYER_1; + change->actual_trigger_side = CH_SIDE_NONE; + change->actual_trigger_ce_value = 0; + } + + /* do not change elements more than a specified maximum number of changes */ + if (ChangeCount[x][y] >= game.max_num_changes_per_frame) + return FALSE; + + ChangeCount[x][y]++; /* count number of changes in the same frame */ + + if (change->explode) + { + Bang(x, y); + + return TRUE; + } + + if (change->use_target_content) + { + boolean complete_replace = TRUE; + boolean can_replace[3][3]; + int xx, yy; + + for (yy = 0; yy < 3; yy++) for (xx = 0; xx < 3 ; xx++) + { + boolean is_empty; + boolean is_walkable; + boolean is_diggable; + boolean is_collectible; + boolean is_removable; + boolean is_destructible; + int ex = x + xx - 1; + int ey = y + yy - 1; + int content_element = change->target_content.e[xx][yy]; + int e; + + can_replace[xx][yy] = TRUE; + + if (ex == x && ey == y) /* do not check changing element itself */ + continue; + + if (content_element == EL_EMPTY_SPACE) + { + can_replace[xx][yy] = FALSE; /* do not replace border with space */ + + continue; + } + + if (!IN_LEV_FIELD(ex, ey)) + { + can_replace[xx][yy] = FALSE; + complete_replace = FALSE; + + continue; + } + + e = Feld[ex][ey]; + + if (IS_MOVING(ex, ey) || IS_BLOCKED(ex, ey)) + e = MovingOrBlocked2Element(ex, ey); + + is_empty = (IS_FREE(ex, ey) || + (IS_FREE_OR_PLAYER(ex, ey) && IS_WALKABLE(content_element))); + is_walkable = (is_empty || IS_WALKABLE(e)); is_diggable = (is_empty || IS_DIGGABLE(e)); is_collectible = (is_empty || IS_COLLECTIBLE(e)); @@ -8081,23 +7638,6 @@ static boolean ChangeElementNow(int x, int y, int element, int page) if (!can_replace[xx][yy]) complete_replace = FALSE; -#else - empty_for_element = (IS_FREE(ex, ey) || (IS_FREE_OR_PLAYER(ex, ey) && - IS_WALKABLE(content_element))); -#if 1 - half_destructible = (empty_for_element || IS_DIGGABLE(e)); -#else - half_destructible = (IS_FREE(ex, ey) || IS_DIGGABLE(e)); -#endif - - if ((change->replace_when <= CP_WHEN_EMPTY && !empty_for_element) || - (change->replace_when <= CP_WHEN_DIGGABLE && !half_destructible) || - (change->replace_when <= CP_WHEN_DESTRUCTIBLE && IS_INDESTRUCTIBLE(e))) - { - can_replace[xx][yy] = FALSE; - complete_replace = FALSE; - } -#endif } if (!change->only_if_complete || complete_replace) @@ -8122,10 +7662,10 @@ static boolean ChangeElementNow(int x, int y, int element, int page) ChangeEvent[ex][ey] = ChangeEvent[x][y]; - content_element = change->target_content[xx][yy]; + content_element = change->target_content.e[xx][yy]; target_element = GET_TARGET_ELEMENT(content_element, change); - ChangeElementNowExt(ex, ey, target_element); + CreateElementFromChange(ex, ey, target_element); something_has_changed = TRUE; @@ -8136,45 +7676,50 @@ static boolean ChangeElementNow(int x, int y, int element, int page) } if (something_has_changed) + { PlayLevelSoundElementAction(x, y, element, ACTION_CHANGING); + PlayLevelSoundElementAction(x, y, element, ACTION_PAGE_1 + page); + } } } else { target_element = GET_TARGET_ELEMENT(change->target_element, change); - ChangeElementNowExt(x, y, target_element); + CreateElementFromChange(x, y, target_element); PlayLevelSoundElementAction(x, y, element, ACTION_CHANGING); + PlayLevelSoundElementAction(x, y, element, ACTION_PAGE_1 + page); } -#if 1 /* this uses direct change before indirect change */ CheckTriggeredElementChangeByPage(x, y, old_element, CE_CHANGE_OF_X, page); -#endif return TRUE; } -static void ChangeElement(int x, int y, int page) +#if USE_NEW_DELAYED_ACTION + +static void HandleElementChange(int x, int y, int page) { int element = MovingOrBlocked2Element(x, y); struct ElementInfo *ei = &element_info[element]; struct ElementChangeInfo *change = &ei->change_page[page]; #ifdef DEBUG - if (!CAN_CHANGE(element) && !CAN_CHANGE(Back[x][y])) + if (!CAN_CHANGE_OR_HAS_ACTION(element) && + !CAN_CHANGE_OR_HAS_ACTION(Back[x][y])) { printf("\n\n"); - printf("ChangeElement(): %d,%d: element = %d ('%s')\n", + printf("HandleElementChange(): %d,%d: element = %d ('%s')\n", x, y, element, element_info[element].token_name); - printf("ChangeElement(): This should never happen!\n"); + printf("HandleElementChange(): This should never happen!\n"); printf("\n\n"); } #endif /* this can happen with classic bombs on walkable, changing elements */ - if (!CAN_CHANGE(element)) + if (!CAN_CHANGE_OR_HAS_ACTION(element)) { #if 0 if (!CAN_CHANGE(Back[x][y])) /* prevent permanent repetition */ @@ -8186,27 +7731,32 @@ static void ChangeElement(int x, int y, int page) if (ChangeDelay[x][y] == 0) /* initialize element change */ { - ChangeDelay[x][y] = ( change->delay_fixed * change->delay_frames + - RND(change->delay_random * change->delay_frames)) + 1; + ChangeDelay[x][y] = GET_CHANGE_DELAY(change) + 1; - ResetGfxAnimation(x, y); - ResetRandomAnimationValue(x, y); + if (change->can_change) + { + ResetGfxAnimation(x, y); + ResetRandomAnimationValue(x, y); - if (change->pre_change_function) - change->pre_change_function(x, y); + if (change->pre_change_function) + change->pre_change_function(x, y); + } } ChangeDelay[x][y]--; if (ChangeDelay[x][y] != 0) /* continue element change */ { - int graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); + if (change->can_change) + { + int graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); - if (IS_ANIMATED(graphic)) - DrawLevelGraphicAnimationIfNeeded(x, y, graphic); + if (IS_ANIMATED(graphic)) + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); - if (change->change_function) - change->change_function(x, y); + if (change->change_function) + change->change_function(x, y); + } } else /* finish element change */ { @@ -8218,11 +7768,7 @@ static void ChangeElement(int x, int y, int page) change = &ei->change_page[page]; } -#if 0 - if (IS_MOVING(x, y) && !change->explode) -#else if (IS_MOVING(x, y)) /* never change a running system ;-) */ -#endif { ChangeDelay[x][y] = 1; /* try change after next move step */ ChangePage[x][y] = page; /* remember page to use for change */ @@ -8230,84 +7776,187 @@ static void ChangeElement(int x, int y, int page) return; } - if (ChangeElementNow(x, y, element, page)) + if (change->can_change) { - if (change->post_change_function) - change->post_change_function(x, y); + if (ChangeElement(x, y, element, page)) + { + if (change->post_change_function) + change->post_change_function(x, y); + } } + + if (change->has_action) + ExecuteCustomElementAction(x, y, element, page); } } -static boolean CheckTriggeredElementChangeExt(int lx, int ly, - int trigger_element, - int trigger_event, - int trigger_player, - int trigger_side, - int trigger_page) -{ - int i, j, x, y; - int trigger_page_bits = (trigger_page < 0 ? CH_PAGE_ANY : 1 << trigger_page); +#else - if (!(trigger_events[trigger_element][trigger_event])) - return FALSE; +static void HandleElementChange(int x, int y, int page) +{ + int element = MovingOrBlocked2Element(x, y); + struct ElementInfo *ei = &element_info[element]; + struct ElementChangeInfo *change = &ei->change_page[page]; - for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) +#ifdef DEBUG + if (!CAN_CHANGE(element) && !CAN_CHANGE(Back[x][y])) { - int element = EL_CUSTOM_START + i; - - boolean change_element = FALSE; - int page = 0; + printf("\n\n"); + printf("HandleElementChange(): %d,%d: element = %d ('%s')\n", + x, y, element, element_info[element].token_name); + printf("HandleElementChange(): This should never happen!\n"); + printf("\n\n"); + } +#endif - if (!CAN_CHANGE(element) || !HAS_ANY_CHANGE_EVENT(element, trigger_event)) + /* this can happen with classic bombs on walkable, changing elements */ + if (!CAN_CHANGE(element)) + { +#if 0 + if (!CAN_CHANGE(Back[x][y])) /* prevent permanent repetition */ + ChangeDelay[x][y] = 0; +#endif + + return; + } + + if (ChangeDelay[x][y] == 0) /* initialize element change */ + { + ChangeDelay[x][y] = GET_CHANGE_DELAY(change) + 1; + + ResetGfxAnimation(x, y); + ResetRandomAnimationValue(x, y); + + if (change->pre_change_function) + change->pre_change_function(x, y); + } + + ChangeDelay[x][y]--; + + if (ChangeDelay[x][y] != 0) /* continue element change */ + { + int graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); + + if (IS_ANIMATED(graphic)) + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); + + if (change->change_function) + change->change_function(x, y); + } + else /* finish element change */ + { + if (ChangePage[x][y] != -1) /* remember page from delayed change */ + { + page = ChangePage[x][y]; + ChangePage[x][y] = -1; + + change = &ei->change_page[page]; + } + + if (IS_MOVING(x, y)) /* never change a running system ;-) */ + { + ChangeDelay[x][y] = 1; /* try change after next move step */ + ChangePage[x][y] = page; /* remember page to use for change */ + + return; + } + + if (ChangeElement(x, y, element, page)) + { + if (change->post_change_function) + change->post_change_function(x, y); + } + } +} + +#endif + +static boolean CheckTriggeredElementChangeExt(int trigger_x, int trigger_y, + int trigger_element, + int trigger_event, + int trigger_player, + int trigger_side, + int trigger_page) +{ + boolean change_done_any = FALSE; + int trigger_page_bits = (trigger_page < 0 ? CH_PAGE_ANY : 1 << trigger_page); + int i; + + if (!(trigger_events[trigger_element][trigger_event])) + return FALSE; + + for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) + { + int element = EL_CUSTOM_START + i; + boolean change_done = FALSE; + int p; + + if (!CAN_CHANGE_OR_HAS_ACTION(element) || + !HAS_ANY_CHANGE_EVENT(element, trigger_event)) continue; - for (j = 0; j < element_info[element].num_change_pages; j++) + for (p = 0; p < element_info[element].num_change_pages; p++) { - struct ElementChangeInfo *change = &element_info[element].change_page[j]; + struct ElementChangeInfo *change = &element_info[element].change_page[p]; - if (change->can_change && + if (change->can_change_or_has_action && change->has_event[trigger_event] && change->trigger_side & trigger_side && change->trigger_player & trigger_player && change->trigger_page & trigger_page_bits && IS_EQUAL_OR_IN_GROUP(trigger_element, change->trigger_element)) { -#if 0 - if (!(change->has_event[trigger_event])) - printf("::: !!! %d triggers %d: using wrong page %d [event %d]\n", - trigger_element-EL_CUSTOM_START+1, i+1, j, trigger_event); -#endif - - change_element = TRUE; - page = j; - change->actual_trigger_element = trigger_element; change->actual_trigger_player = EL_PLAYER_1 + log_2(trigger_player); + change->actual_trigger_side = trigger_side; + change->actual_trigger_ce_value = CustomValue[trigger_x][trigger_y]; - break; - } - } - - if (!change_element) - continue; + if ((change->can_change && !change_done) || change->has_action) + { + int x, y; - for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) - { -#if 0 - if (x == lx && y == ly) /* do not change trigger element itself */ - continue; +#if 1 + SCAN_PLAYFIELD(x, y) +#else + for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) #endif + { + if (Feld[x][y] == element) + { + if (change->can_change && !change_done) + { + ChangeDelay[x][y] = 1; + ChangeEvent[x][y] = trigger_event; + + HandleElementChange(x, y, p); + } +#if USE_NEW_DELAYED_ACTION + else if (change->has_action) + { + ExecuteCustomElementAction(x, y, element, p); + PlayLevelSoundElementAction(x, y, element, ACTION_PAGE_1 + p); + } +#else + if (change->has_action) + { + ExecuteCustomElementAction(x, y, element, p); + PlayLevelSoundElementAction(x, y, element, ACTION_PAGE_1 + p); + } +#endif + } + } - if (Feld[x][y] == element) - { - ChangeDelay[x][y] = 1; - ChangeEvent[x][y] = trigger_event; - ChangeElement(x, y, page); + if (change->can_change) + { + change_done = TRUE; + change_done_any = TRUE; + } + } } } } - return TRUE; + return change_done_any; } static boolean CheckElementChangeExt(int x, int y, @@ -8315,10 +7964,13 @@ static boolean CheckElementChangeExt(int x, int y, int trigger_element, int trigger_event, int trigger_player, - int trigger_side, - int trigger_page) + int trigger_side) { - if (!CAN_CHANGE(element) || !HAS_ANY_CHANGE_EVENT(element, trigger_event)) + boolean change_done = FALSE; + int p; + + if (!CAN_CHANGE_OR_HAS_ACTION(element) || + !HAS_ANY_CHANGE_EVENT(element, trigger_event)) return FALSE; if (Feld[x][y] == EL_BLOCKED) @@ -8327,96 +7979,102 @@ static boolean CheckElementChangeExt(int x, int y, element = Feld[x][y]; } -#if 1 if (Feld[x][y] != element) /* check if element has already changed */ - { -#if 0 - printf("::: %d ('%s') != %d ('%s') [%d]\n", - Feld[x][y], element_info[Feld[x][y]].token_name, - element, element_info[element].token_name, - trigger_event); -#endif - return FALSE; - } -#endif -#if 1 - if (trigger_page < 0) + for (p = 0; p < element_info[element].num_change_pages; p++) { - boolean change_element = FALSE; - int i; + struct ElementChangeInfo *change = &element_info[element].change_page[p]; - for (i = 0; i < element_info[element].num_change_pages; i++) + boolean check_trigger_element = + (trigger_event == CE_TOUCHING_X || + trigger_event == CE_HITTING_X || + trigger_event == CE_HIT_BY_X); + + if (change->can_change_or_has_action && + change->has_event[trigger_event] && + change->trigger_side & trigger_side && + change->trigger_player & trigger_player && + (!check_trigger_element || + IS_EQUAL_OR_IN_GROUP(trigger_element, change->trigger_element))) { - struct ElementChangeInfo *change = &element_info[element].change_page[i]; + change->actual_trigger_element = trigger_element; + change->actual_trigger_player = EL_PLAYER_1 + log_2(trigger_player); + change->actual_trigger_side = trigger_side; + change->actual_trigger_ce_value = CustomValue[x][y]; - if (change->can_change && - change->has_event[trigger_event] && - change->trigger_side & trigger_side && - change->trigger_player & trigger_player) + /* special case: trigger element not at (x,y) position for some events */ + if (check_trigger_element) { - change_element = TRUE; - trigger_page = i; + static struct + { + int dx, dy; + } move_xy[] = + { + { 0, 0 }, + { -1, 0 }, + { +1, 0 }, + { 0, 0 }, + { 0, -1 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, +1 } + }; - change->actual_trigger_element = trigger_element; - change->actual_trigger_player = EL_PLAYER_1 + log_2(trigger_player); + int xx = x + move_xy[MV_DIR_OPPOSITE(trigger_side)].dx; + int yy = y + move_xy[MV_DIR_OPPOSITE(trigger_side)].dy; - break; + change->actual_trigger_ce_value = CustomValue[xx][yy]; } - } - if (!change_element) - return FALSE; - } - else - { - struct ElementInfo *ei = &element_info[element]; - struct ElementChangeInfo *change = &ei->change_page[trigger_page]; + if (change->can_change && !change_done) + { + ChangeDelay[x][y] = 1; + ChangeEvent[x][y] = trigger_event; - change->actual_trigger_element = trigger_element; - change->actual_trigger_player = EL_PLAYER_1; /* unused */ - } + HandleElementChange(x, y, p); + change_done = TRUE; + } +#if USE_NEW_DELAYED_ACTION + else if (change->has_action) + { + ExecuteCustomElementAction(x, y, element, p); + PlayLevelSoundElementAction(x, y, element, ACTION_PAGE_1 + p); + } #else - - /* !!! this check misses pages with same event, but different side !!! */ - - if (trigger_page < 0) - trigger_page = element_info[element].event_page_nr[trigger_event]; - - if (!(element_info[element].change_page[trigger_page].trigger_side & trigger_side)) - return FALSE; + if (change->has_action) + { + ExecuteCustomElementAction(x, y, element, p); + PlayLevelSoundElementAction(x, y, element, ACTION_PAGE_1 + p); + } #endif + } + } - ChangeDelay[x][y] = 1; - ChangeEvent[x][y] = trigger_event; - ChangeElement(x, y, trigger_page); - - return TRUE; + return change_done; } static void PlayPlayerSound(struct PlayerInfo *player) { int jx = player->jx, jy = player->jy; - int element = player->element_nr; + int sound_element = player->artwork_element; int last_action = player->last_action_waiting; int action = player->action_waiting; if (player->is_waiting) { if (action != last_action) - PlayLevelSoundElementAction(jx, jy, element, action); + PlayLevelSoundElementAction(jx, jy, sound_element, action); else - PlayLevelSoundElementActionIfLoop(jx, jy, element, action); + PlayLevelSoundElementActionIfLoop(jx, jy, sound_element, action); } else { if (action != last_action) - StopSound(element_info[element].sound[last_action]); + StopSound(element_info[sound_element].sound[last_action]); if (last_action == ACTION_SLEEPING) - PlayLevelSoundElementAction(jx, jy, element, ACTION_AWAKENING); + PlayLevelSoundElementAction(jx, jy, sound_element, ACTION_AWAKENING); } } @@ -8483,7 +8141,7 @@ static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting) last_special_action < ACTION_SLEEPING_1 + num_special_action - 1 ? last_special_action + 1 : ACTION_SLEEPING); int special_graphic = - el_act_dir2img(player->element_nr, special_action, move_dir); + el_act_dir2img(player->artwork_element, special_action, move_dir); player->anim_delay_counter = graphic_info[special_graphic].anim_delay_fixed + @@ -8515,7 +8173,7 @@ static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting) int special_action = ACTION_BORING_1 + SimpleRND(player->num_special_action_bored); int special_graphic = - el_act_dir2img(player->element_nr, special_action, move_dir); + el_act_dir2img(player->artwork_element, special_action, move_dir); player->anim_delay_counter = graphic_info[special_graphic].anim_delay_fixed + @@ -8558,13 +8216,8 @@ static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting) } } -#if 1 static byte PlayerActions(struct PlayerInfo *player, byte player_action) { -#if 0 - static byte stored_player_action[MAX_PLAYERS]; - static int num_stored_actions = 0; -#endif boolean moved = FALSE, snapped = FALSE, dropped = FALSE; int left = player_action & JOY_LEFT; int right = player_action & JOY_RIGHT; @@ -8575,34 +8228,11 @@ static byte PlayerActions(struct PlayerInfo *player, byte player_action) int dx = (left ? -1 : right ? 1 : 0); int dy = (up ? -1 : down ? 1 : 0); -#if 0 - stored_player_action[player->index_nr] = 0; - num_stored_actions++; -#endif - -#if 0 - printf("::: player %d [%d]\n", player->index_nr, FrameCounter); -#endif - if (!player->active || tape.pausing) return 0; -#if 0 - printf("::: [%d %d %d %d] [%d %d]\n", - left, right, up, down, button1, button2); -#endif - if (player_action) { -#if 0 - printf("::: player %d acts [%d]\n", player->index_nr, FrameCounter); -#endif - -#if 0 - /* !!! TEST !!! */ - if (player->MovPos == 0) - CheckGravityMovement(player); -#endif if (button1) snapped = SnapField(player, dx, dy); else @@ -8624,18 +8254,10 @@ static byte PlayerActions(struct PlayerInfo *player, byte player_action) SetPlayerWaiting(player, FALSE); -#if 1 return player_action; -#else - stored_player_action[player->index_nr] = player_action; -#endif } else { -#if 0 - printf("::: player %d waits [%d]\n", player->index_nr, FrameCounter); -#endif - /* no actions for this player (no input at player's configured device) */ DigField(player, 0, 0, 0, 0, 0, 0, DF_NO_PUSH); @@ -8652,93 +8274,7 @@ static byte PlayerActions(struct PlayerInfo *player, byte player_action) return 0; } - -#if 0 - if (tape.recording && num_stored_actions >= MAX_PLAYERS) - { - printf("::: player %d recorded [%d]\n", player->index_nr, FrameCounter); - - TapeRecordAction(stored_player_action); - num_stored_actions = 0; - } -#endif -} - -#else - -static void PlayerActions(struct PlayerInfo *player, byte player_action) -{ - static byte stored_player_action[MAX_PLAYERS]; - static int num_stored_actions = 0; - boolean moved = FALSE, snapped = FALSE, dropped = FALSE; - int left = player_action & JOY_LEFT; - int right = player_action & JOY_RIGHT; - int up = player_action & JOY_UP; - int down = player_action & JOY_DOWN; - int button1 = player_action & JOY_BUTTON_1; - int button2 = player_action & JOY_BUTTON_2; - int dx = (left ? -1 : right ? 1 : 0); - int dy = (up ? -1 : down ? 1 : 0); - - stored_player_action[player->index_nr] = 0; - num_stored_actions++; - - printf("::: player %d [%d]\n", player->index_nr, FrameCounter); - - if (!player->active || tape.pausing) - return; - - if (player_action) - { - printf("::: player %d acts [%d]\n", player->index_nr, FrameCounter); - - if (button1) - snapped = SnapField(player, dx, dy); - else - { - if (button2) - dropped = DropElement(player); - - moved = MovePlayer(player, dx, dy); - } - - if (tape.single_step && tape.recording && !tape.pausing) - { - if (button1 || (dropped && !moved)) - { - TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); - SnapField(player, 0, 0); /* stop snapping */ - } - } - - stored_player_action[player->index_nr] = player_action; - } - else - { - printf("::: player %d waits [%d]\n", player->index_nr, FrameCounter); - - /* no actions for this player (no input at player's configured device) */ - - DigField(player, 0, 0, 0, 0, 0, 0, DF_NO_PUSH); - SnapField(player, 0, 0); - CheckGravityMovementWhenNotMoving(player); - - if (player->MovPos == 0) - InitPlayerGfxAnimation(player, ACTION_DEFAULT, player->MovDir); - - if (player->MovPos == 0) /* needed for tape.playing */ - player->is_moving = FALSE; - } - - if (tape.recording && num_stored_actions >= MAX_PLAYERS) - { - printf("::: player %d recorded [%d]\n", player->index_nr, FrameCounter); - - TapeRecordAction(stored_player_action); - num_stored_actions = 0; - } } -#endif void AdvanceFrameAndPlayerCounters(int player_nr) { @@ -8752,27 +8288,36 @@ void AdvanceFrameAndPlayerCounters(int player_nr) for (i = 0; i < MAX_PLAYERS; i++) { boolean advance_player_counters = (player_nr == -1 || player_nr == i); - int move_frames = - MOVE_DELAY_NORMAL_SPEED / stored_player[i].move_delay_value; + int move_delay_value = stored_player[i].move_delay_value; + int move_frames = MOVE_DELAY_NORMAL_SPEED / move_delay_value; if (!advance_player_counters) /* not all players may be affected */ continue; +#if USE_NEW_PLAYER_ANIM + if (move_frames == 0) /* less than one move per game frame */ + { + int stepsize = TILEX / move_delay_value; + int delay = move_delay_value / MOVE_DELAY_NORMAL_SPEED; + int count = (stored_player[i].is_moving ? + ABS(stored_player[i].MovPos) / stepsize : FrameCounter); + + if (count % delay == 0) + move_frames = 1; + } +#endif + stored_player[i].Frame += move_frames; if (stored_player[i].MovPos != 0) stored_player[i].StepFrame += move_frames; -#if USE_NEW_MOVE_DELAY if (stored_player[i].move_delay > 0) stored_player[i].move_delay--; -#endif -#if USE_NEW_PUSH_DELAY /* due to bugs in previous versions, counter must count up, not down */ if (stored_player[i].push_delay != -1) stored_player[i].push_delay++; -#endif if (stored_player[i].drop_delay > 0) stored_player[i].drop_delay--; @@ -8787,9 +8332,7 @@ void GameActions() int i, x, y, element, graphic; byte *recorded_player_action; byte summarized_player_action = 0; -#if 1 byte tape_action[MAX_PLAYERS]; -#endif if (game_status != GAME_MODE_PLAYING) return; @@ -8802,42 +8345,30 @@ void GameActions() /* ---------- main game synchronization point ---------- */ + InitPlayfieldScanModeVars(); + WaitUntilDelayReached(&game_frame_delay, game_frame_delay_value); if (network_playing && !network_player_action_received) { - /* -#ifdef DEBUG - printf("DEBUG: try to get network player actions in time\n"); -#endif - */ + /* try to get network player actions in time */ #if defined(NETWORK_AVALIABLE) /* last chance to get network player actions without main loop delay */ HandleNetworking(); #endif + /* game was quit by network peer */ if (game_status != GAME_MODE_PLAYING) return; if (!network_player_action_received) - { - /* -#ifdef DEBUG - printf("DEBUG: failed to get network player actions in time\n"); -#endif - */ - return; - } + return; /* failed to get network player actions in time */ } if (tape.pausing) return; -#if 0 - printf("::: getting new tape action [%d]\n", FrameCounter); -#endif - recorded_player_action = (tape.playing ? TapePlayAction() : NULL); #if 1 @@ -8846,16 +8377,6 @@ void GameActions() return; #endif -#if 0 - printf("::: %d\n", stored_player[0].action); -#endif - -#if 0 - if (recorded_player_action != NULL) - for (i = 0; i < MAX_PLAYERS; i++) - stored_player[i].action = recorded_player_action[i]; -#endif - for (i = 0; i < MAX_PLAYERS; i++) { summarized_player_action |= stored_player[i].action; @@ -8872,13 +8393,10 @@ void GameActions() if (!options.network && !setup.team_mode) local_player->effective_action = summarized_player_action; -#if 1 if (recorded_player_action != NULL) for (i = 0; i < MAX_PLAYERS; i++) stored_player[i].effective_action = recorded_player_action[i]; -#endif -#if 1 for (i = 0; i < MAX_PLAYERS; i++) { tape_action[i] = stored_player[i].effective_action; @@ -8890,7 +8408,6 @@ void GameActions() /* only save actions from input devices, but not programmed actions */ if (tape.recording) TapeRecordAction(tape_action); -#endif for (i = 0; i < MAX_PLAYERS; i++) { @@ -8907,42 +8424,9 @@ void GameActions() CheckGravityMovement(&stored_player[i]); #endif -#if 1 /* overwrite programmed action with tape action */ if (stored_player[i].programmed_action) actual_player_action = stored_player[i].programmed_action; -#endif - -#if 0 - if (stored_player[i].programmed_action) - printf("::: %d\n", stored_player[i].programmed_action); -#endif - - if (recorded_player_action) - { -#if 0 - if (stored_player[i].programmed_action && - stored_player[i].programmed_action != recorded_player_action[i]) - printf("::: %d: %d <-> %d\n", i, - stored_player[i].programmed_action, recorded_player_action[i]); -#endif - -#if 0 - actual_player_action = recorded_player_action[i]; -#endif - } - -#if 0 - /* overwrite tape action with programmed action */ - if (stored_player[i].programmed_action) - actual_player_action = stored_player[i].programmed_action; -#endif - -#if 0 - if (i == 0) - printf("::: action: %d: %x [%d]\n", - stored_player[i].MovPos, actual_player_action, FrameCounter); -#endif #if 1 PlayerActions(&stored_player[i], actual_player_action); @@ -8956,24 +8440,10 @@ void GameActions() ScrollPlayer(&stored_player[i], SCROLL_GO_ON); } -#if 0 - if (tape.recording) - TapeRecordAction(tape_action); -#endif - network_player_action_received = FALSE; ScrollScreen(NULL, SCROLL_GO_ON); -#if 0 - FrameCounter++; - TimeFrames++; - - for (i = 0; i < MAX_PLAYERS; i++) - stored_player[i].Frame++; -#endif - -#if 1 /* for backwards compatibility, the following code emulates a fixed bug that occured when pushing elements (causing elements that just made their last pushing step to already (if possible) make their first falling step in the @@ -8982,11 +8452,7 @@ void GameActions() used also in newer levels, but in this case the buggy pushing code is only affecting the "spring" element and no other elements */ -#if 1 if (game.engine_version < VERSION_IDENT(2,2,0,7) || level.use_spring_bug) -#else - if (game.engine_version < VERSION_IDENT(2,2,0,7)) -#endif { for (i = 0; i < MAX_PLAYERS; i++) { @@ -8994,15 +8460,10 @@ void GameActions() int x = player->jx; int y = player->jy; -#if 1 if (player->active && player->is_pushing && player->is_moving && IS_MOVING(x, y) && (game.engine_version < VERSION_IDENT(2,2,0,7) || Feld[x][y] == EL_SPRING)) -#else - if (player->active && player->is_pushing && player->is_moving && - IS_MOVING(x, y)) -#endif { ContinueMoving(x, y); @@ -9014,14 +8475,16 @@ void GameActions() } } } -#endif +#if 1 + SCAN_PLAYFIELD(x, y) +#else for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) +#endif { - Changed[x][y] = FALSE; + ChangeCount[x][y] = 0; ChangeEvent[x][y] = -1; -#if USE_NEW_BLOCK_STYLE /* this must be handled before main playfield loop */ if (Feld[x][y] == EL_PLAYER_IS_LEAVING) { @@ -9029,6 +8492,19 @@ void GameActions() if (MovDelay[x][y] <= 0) RemoveField(x, y); } + +#if USE_NEW_SNAP_DELAY + if (Feld[x][y] == EL_ELEMENT_SNAPPING) + { + MovDelay[x][y]--; + if (MovDelay[x][y] <= 0) + { + RemoveField(x, y); + DrawLevelField(x, y); + + TestIfElementTouchesCustomElement(x, y); /* for empty space */ + } + } #endif #if DEBUG @@ -9051,7 +8527,6 @@ void GameActions() GfxFrame[x][y]++; -#if 1 /* reset finished pushing action (not done in ContinueMoving() to allow continous pushing animation for elements with zero push delay) */ if (GfxAction[x][y] == ACTION_PUSHING && !IS_MOVING(x, y)) @@ -9059,7 +8534,6 @@ void GameActions() ResetGfxAnimation(x, y); DrawLevelField(x, y); } -#endif #if DEBUG if (IS_BLOCKED(x, y)) @@ -9078,26 +8552,46 @@ void GameActions() #endif } +#if 1 + SCAN_PLAYFIELD(x, y) +#else for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) +#endif { element = Feld[x][y]; -#if 1 graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); -#else - graphic = el2img(element); -#endif #if 0 - if (element == -1) - { - printf("::: %d,%d: %d [%d]\n", x, y, element, FrameCounter); + printf("::: %d,%d\n", x, y); - element = graphic = 0; - } + if (element == EL_ROCK) + printf("::: Yo man! Rocks can fall!\n"); #endif if (graphic_info[graphic].anim_global_sync) GfxFrame[x][y] = FrameCounter; + else if (ANIM_MODE(graphic) == ANIM_CE_VALUE) + { + int old_gfx_frame = GfxFrame[x][y]; + + GfxFrame[x][y] = CustomValue[x][y]; + +#if 1 + if (GfxFrame[x][y] != old_gfx_frame) +#endif + DrawLevelGraphicAnimation(x, y, graphic); + } + else if (ANIM_MODE(graphic) == ANIM_CE_SCORE) + { + int old_gfx_frame = GfxFrame[x][y]; + + GfxFrame[x][y] = element_info[element].collect_score; + +#if 1 + if (GfxFrame[x][y] != old_gfx_frame) +#endif + DrawLevelGraphicAnimation(x, y, graphic); + } if (ANIM_MODE(graphic) == ANIM_RANDOM && IS_NEXT_FRAME(GfxFrame[x][y], graphic)) @@ -9105,9 +8599,7 @@ void GameActions() SetRandomAnimationValue(x, y); -#if 1 PlayLevelSoundActionIfLoop(x, y, GfxAction[x][y]); -#endif if (IS_INACTIVE(element)) { @@ -9117,64 +8609,52 @@ void GameActions() continue; } -#if 1 /* this may take place after moving, so 'element' may have changed */ -#if 0 - if (IS_CHANGING(x, y)) -#else if (IS_CHANGING(x, y) && (game.engine_version < VERSION_IDENT(3,0,7,1) || !Stop[x][y])) -#endif { + int page = element_info[element].event_page_nr[CE_DELAY]; +#if 0 + HandleElementChange(x, y, ChangePage[x][y] != -1 ? ChangePage[x][y] : page); +#else + +#if 0 + printf("::: ChangeDelay == %d\n", ChangeDelay[x][y]); +#endif + #if 0 - ChangeElement(x, y, ChangePage[x][y] != -1 ? ChangePage[x][y] : - element_info[element].event_page_nr[CE_DELAY]); + if (element == EL_CUSTOM_255) + printf("::: ChangeDelay == %d\n", ChangeDelay[x][y]); +#endif + +#if 1 + HandleElementChange(x, y, page); #else - ChangeElement(x, y, element_info[element].event_page_nr[CE_DELAY]); + if (CAN_CHANGE(element)) + HandleElementChange(x, y, page); + + if (HAS_ACTION(element)) + ExecuteCustomElementAction(x, y, element, page); +#endif + #endif element = Feld[x][y]; graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); } -#endif if (!IS_MOVING(x, y) && (CAN_FALL(element) || CAN_MOVE(element))) { StartMoving(x, y); -#if 1 element = Feld[x][y]; graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); -#if 0 - if (element == EL_MOLE) - printf("::: %d, %d, %d [%d]\n", - IS_ANIMATED(graphic), IS_MOVING(x, y), Stop[x][y], - GfxAction[x][y]); -#endif -#if 0 - if (element == EL_YAMYAM) - printf("::: %d, %d, %d\n", - IS_ANIMATED(graphic), IS_MOVING(x, y), Stop[x][y]); -#endif -#endif if (IS_ANIMATED(graphic) && !IS_MOVING(x, y) && !Stop[x][y]) - { DrawLevelGraphicAnimationIfNeeded(x, y, graphic); -#if 0 - if (element == EL_BUG) - printf("::: %d, %d\n", graphic, GfxFrame[x][y]); -#endif - -#if 0 - if (element == EL_MOLE) - printf("::: %d, %d\n", graphic, GfxFrame[x][y]); -#endif - } - if (IS_GEM(element) || element == EL_SP_INFOTRON) EdelsteinFunkeln(x, y); } @@ -9192,10 +8672,6 @@ void GameActions() ContinueMoving(x, y); else if (IS_ACTIVE_BOMB(element)) CheckDynamite(x, y); -#if 0 - else if (element == EL_EXPLOSION && !game.explosions_delayed) - Explode(x, y, ExplodePhase[x][y], EX_TYPE_NORMAL); -#endif else if (element == EL_AMOEBA_GROWING) AmoebeWaechst(x, y); else if (element == EL_AMOEBA_SHRINKING) @@ -9221,19 +8697,23 @@ void GameActions() MauerAbleger(x, y); else if (element == EL_FLAMES) CheckForDragon(x, y); -#if 0 - else if (IS_AUTO_CHANGING(element)) - ChangeElement(x, y); -#endif else if (element == EL_EXPLOSION) ; /* drawing of correct explosion animation is handled separately */ + else if (element == EL_ELEMENT_SNAPPING) + { +#if 1 + graphic = el_act_dir2img(GfxElement[x][y], GfxAction[x][y],GfxDir[x][y]); + + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); +#endif + } else if (IS_ANIMATED(graphic) && !IS_CHANGING(x, y)) DrawLevelGraphicAnimationIfNeeded(x, y, graphic); #if 0 - /* this may take place after moving, so 'element' may have changed */ - if (IS_AUTO_CHANGING(Feld[x][y])) - ChangeElement(x, y); + if (element == EL_CUSTOM_255 || + element == EL_CUSTOM_256) + DrawLevelGraphicAnimation(x, y, graphic); #endif if (IS_BELT_ACTIVE(element)) @@ -9260,24 +8740,16 @@ void GameActions() #if USE_NEW_AMOEBA_CODE /* new experimental amoeba growth stuff */ -#if 1 if (!(FrameCounter % 8)) -#endif { static unsigned long random = 1684108901; for (i = 0; i < level.amoeba_speed * 28 / 8; i++) { -#if 0 - x = (random >> 10) % lev_fieldx; - y = (random >> 20) % lev_fieldy; -#else x = RND(lev_fieldx); y = RND(lev_fieldy); -#endif element = Feld[x][y]; -#if 1 if (!IS_PLAYER(x,y) && (element == EL_EMPTY || CAN_GROW_INTO(element) || @@ -9291,22 +8763,6 @@ void GameActions() (IN_LEV_FIELD(x, y+1) && Feld[x][y+1] == EL_AMOEBA_WET)) Feld[x][y] = EL_AMOEBA_DROP; } -#else - /* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */ - if (!IS_PLAYER(x,y) && - (element == EL_EMPTY || - element == EL_SAND || - element == EL_QUICKSAND_EMPTY || - element == EL_ACID_SPLASH_LEFT || - element == EL_ACID_SPLASH_RIGHT)) - { - if ((IN_LEV_FIELD(x, y-1) && Feld[x][y-1] == EL_AMOEBA_WET) || - (IN_LEV_FIELD(x-1, y) && Feld[x-1][y] == EL_AMOEBA_WET) || - (IN_LEV_FIELD(x+1, y) && Feld[x+1][y] == EL_AMOEBA_WET) || - (IN_LEV_FIELD(x, y+1) && Feld[x][y+1] == EL_AMOEBA_WET)) - Feld[x][y] = EL_AMOEBA_DROP; - } -#endif random = random * 129 + 1; } @@ -9319,7 +8775,11 @@ void GameActions() { game.explosions_delayed = FALSE; +#if 1 + SCAN_PLAYFIELD(x, y) +#else for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) +#endif { element = Feld[x][y]; @@ -9353,7 +8813,11 @@ void GameActions() game.magic_wall_time_left--; if (!game.magic_wall_time_left) { +#if 1 + SCAN_PLAYFIELD(x, y) +#else for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) +#endif { element = Feld[x][y]; @@ -9392,6 +8856,22 @@ void GameActions() CloseAllOpenTimegates(); } + if (game.lenses_time_left > 0) + { + game.lenses_time_left--; + + if (game.lenses_time_left == 0) + RedrawAllInvisibleElementsForLenses(); + } + + if (game.magnify_time_left > 0) + { + game.magnify_time_left--; + + if (game.magnify_time_left == 0) + RedrawAllInvisibleElementsForMagnifier(); + } + for (i = 0; i < MAX_PLAYERS; i++) { struct PlayerInfo *player = &stored_player[i]; @@ -9438,7 +8918,7 @@ void GameActions() if (!TimeLeft && setup.time_limit) for (i = 0; i < MAX_PLAYERS; i++) - KillHero(&stored_player[i]); + KillPlayer(&stored_player[i]); } else if (level.time == 0 && !AllPlayersGone) /* level w/o time limit */ DrawGameValue_Time(TimePlayed); @@ -9470,57 +8950,18 @@ void GameActions() redraw_mask |= REDRAW_FPS; } -#if 0 - if (stored_player[0].jx != stored_player[0].last_jx || - stored_player[0].jy != stored_player[0].last_jy) - printf("::: %d, %d, %d, %d, %d\n", - stored_player[0].MovDir, - stored_player[0].MovPos, - stored_player[0].GfxPos, - stored_player[0].Frame, - stored_player[0].StepFrame); -#endif - -#if USE_NEW_MOVE_DELAY AdvanceFrameAndPlayerCounters(-1); /* advance counters for all players */ -#else - FrameCounter++; - TimeFrames++; - - for (i = 0; i < MAX_PLAYERS; i++) - { - int move_frames = - MOVE_DELAY_NORMAL_SPEED / stored_player[i].move_delay_value; - - stored_player[i].Frame += move_frames; - - if (stored_player[i].MovPos != 0) - stored_player[i].StepFrame += move_frames; - -#if USE_NEW_MOVE_DELAY - if (stored_player[i].move_delay > 0) - stored_player[i].move_delay--; -#endif - - if (stored_player[i].drop_delay > 0) - stored_player[i].drop_delay--; - } -#endif -#if 1 if (local_player->show_envelope != 0 && local_player->MovPos == 0) { ShowEnvelope(local_player->show_envelope - EL_ENVELOPE_1); local_player->show_envelope = 0; } -#endif -#if USE_NEW_RANDOMIZE /* use random number generator in every frame to make it less predictable */ if (game.engine_version >= VERSION_IDENT(3,1,1,0)) RND(1); -#endif } static boolean AllPlayersInSight(struct PlayerInfo *player, int x, int y) @@ -9592,51 +9033,12 @@ void ScrollLevel(int dx, int dy) redraw_mask |= REDRAW_FIELD; } -#if 0 -static boolean canEnterSupaplexPort(int x, int y, int dx, int dy) -{ - int nextx = x + dx, nexty = y + dy; - int element = Feld[x][y]; - - if ((dx == -1 && - element != EL_SP_PORT_LEFT && - element != EL_SP_GRAVITY_PORT_LEFT && - element != EL_SP_PORT_HORIZONTAL && - element != EL_SP_PORT_ANY) || - (dx == +1 && - element != EL_SP_PORT_RIGHT && - element != EL_SP_GRAVITY_PORT_RIGHT && - element != EL_SP_PORT_HORIZONTAL && - element != EL_SP_PORT_ANY) || - (dy == -1 && - element != EL_SP_PORT_UP && - element != EL_SP_GRAVITY_PORT_UP && - element != EL_SP_PORT_VERTICAL && - element != EL_SP_PORT_ANY) || - (dy == +1 && - element != EL_SP_PORT_DOWN && - element != EL_SP_GRAVITY_PORT_DOWN && - element != EL_SP_PORT_VERTICAL && - element != EL_SP_PORT_ANY) || - !IN_LEV_FIELD(nextx, nexty) || - !IS_FREE(nextx, nexty)) - return FALSE; - - return TRUE; -} -#endif - static boolean canFallDown(struct PlayerInfo *player) { int jx = player->jx, jy = player->jy; return (IN_LEV_FIELD(jx, jy + 1) && (IS_FREE(jx, jy + 1) || -#if USE_NEW_BLOCK_STYLE -#if USE_GRAVITY_BUGFIX_OLD - Feld[jx][jy + 1] == EL_PLAYER_IS_LEAVING || -#endif -#endif (Feld[jx][jy + 1] == EL_ACID && player->can_fall_into_acid)) && IS_WALKABLE_FROM(Feld[jx][jy], MV_DOWN) && !IS_WALKABLE_INSIDE(Feld[jx][jy])); @@ -9665,166 +9067,37 @@ static boolean canMoveToValidFieldWithGravity(int x, int y, int move_dir) int dy = (move_dir & MV_UP ? -1 : move_dir & MV_DOWN ? +1 : 0); int newx = x + dx; int newy = y + dy; -#if 0 - int nextx = newx + dx; - int nexty = newy + dy; -#endif -#if 1 - return (IN_LEV_FIELD(newx, newy) && !IS_FREE_OR_PLAYER(newx, newy) && - IS_GRAVITY_REACHABLE(Feld[newx][newy]) && -#if 0 - (!IS_SP_PORT(Feld[newx][newy]) || move_dir == MV_UP) && -#endif - (IS_DIGGABLE(Feld[newx][newy]) || - IS_WALKABLE_FROM(Feld[newx][newy], opposite_dir) || - canPassField(newx, newy, move_dir))); -#else -#if 1 return (IN_LEV_FIELD(newx, newy) && !IS_FREE_OR_PLAYER(newx, newy) && IS_GRAVITY_REACHABLE(Feld[newx][newy]) && (IS_DIGGABLE(Feld[newx][newy]) || IS_WALKABLE_FROM(Feld[newx][newy], opposite_dir) || canPassField(newx, newy, move_dir))); -#else -#if 1 - return (IN_LEV_FIELD(newx, newy) && !IS_FREE_OR_PLAYER(newx, newy) && - (IS_DIGGABLE_WITH_GRAVITY(Feld[newx][newy]) || - IS_WALKABLE_FROM(Feld[newx][newy], opposite_dir) || - canPassField(newx, newy, move_dir))); -#else - return (IN_LEV_FIELD(newx, newy) && !IS_FREE_OR_PLAYER(newx, newy) && - (IS_DIGGABLE(Feld[newx][newy]) || - IS_WALKABLE_FROM(Feld[newx][newy], opposite_dir) || - (IS_PASSABLE_FROM(Feld[newx][newy], opposite_dir) && - !CAN_MOVE(Feld[newx][newy]) && - IN_LEV_FIELD(nextx, nexty) && !IS_PLAYER(nextx, nexty) && - IS_WALKABLE_FROM(Feld[nextx][nexty], move_dir) && - (level.can_pass_to_walkable || IS_FREE(nextx, nexty))))); -#endif -#endif -#endif } static void CheckGravityMovement(struct PlayerInfo *player) { if (game.gravity && !player->programmed_action) { -#if 1 int move_dir_horizontal = player->effective_action & MV_HORIZONTAL; int move_dir_vertical = player->effective_action & MV_VERTICAL; -#else - int move_dir_horizontal = player->action & MV_HORIZONTAL; - int move_dir_vertical = player->action & MV_VERTICAL; -#endif - -#if 1 boolean player_is_snapping = player->effective_action & JOY_BUTTON_1; -#else - boolean player_is_snapping = player->action & JOY_BUTTON_1; -#endif - int jx = player->jx, jy = player->jy; - boolean player_is_moving_to_valid_field = (!player_is_snapping && (canMoveToValidFieldWithGravity(jx, jy, move_dir_horizontal) || canMoveToValidFieldWithGravity(jx, jy, move_dir_vertical))); + boolean player_can_fall_down = canFallDown(player); -#if 0 - int move_dir = - (player->last_move_dir & MV_HORIZONTAL ? - (move_dir_vertical ? move_dir_vertical : move_dir_horizontal) : - (move_dir_horizontal ? move_dir_horizontal : move_dir_vertical)); -#endif - -#if 0 - int opposite_dir = MV_DIR_OPPOSITE(move_dir); - int dx = (move_dir & MV_LEFT ? -1 : move_dir & MV_RIGHT ? +1 : 0); - int dy = (move_dir & MV_UP ? -1 : move_dir & MV_DOWN ? +1 : 0); - int new_jx = jx + dx, new_jy = jy + dy; - int nextx = new_jx + dx, nexty = new_jy + dy; -#endif - -#if 1 - -#if 1 - boolean player_can_fall_down = canFallDown(player); -#else - boolean player_can_fall_down = - (IN_LEV_FIELD(jx, jy + 1) && - (IS_FREE(jx, jy + 1) || - (Feld[jx][jy + 1] == EL_ACID && player->can_fall_into_acid))); -#endif - -#else - boolean player_can_fall_down = - (IN_LEV_FIELD(jx, jy + 1) && - (IS_FREE(jx, jy + 1))); -#endif - -#if 0 - boolean player_is_moving_to_valid_field = - ( -#if 1 - !player_is_snapping && -#endif - -#if 1 - IN_LEV_FIELD(new_jx, new_jy) && - (IS_DIGGABLE(Feld[new_jx][new_jy]) || - (IS_SP_PORT(Feld[new_jx][new_jy]) && - element_info[Feld[new_jx][new_jy]].access_direction & opposite_dir && - IN_LEV_FIELD(nextx, nexty) && - element_info[Feld[nextx][nexty]].access_direction & move_dir)) -#else - IN_LEV_FIELD(new_jx, new_jy) && - (Feld[new_jx][new_jy] == EL_SP_BASE || - Feld[new_jx][new_jy] == EL_SAND || - (IS_SP_PORT(Feld[new_jx][new_jy]) && - canEnterSupaplexPort(new_jx, new_jy, dx, dy))) - /* !!! extend EL_SAND to anything diggable !!! */ -#endif - ); -#endif - -#if 0 - boolean player_is_standing_on_valid_field = - (IS_WALKABLE_INSIDE(Feld[jx][jy]) || - (IS_WALKABLE(Feld[jx][jy]) && !ACCESS_FROM(Feld[jx][jy], MV_DOWN))); -#endif - -#if 0 - printf("::: checking gravity NOW [%d, %d, %d] [%d] [%d / %d] ...\n", - player_can_fall_down, - player_is_standing_on_valid_field, - player_is_moving_to_valid_field, - (player_is_moving_to_valid_field ? Feld[new_jx][new_jy] : -1), - player->effective_action, - player->can_fall_into_acid); -#endif - - if (player_can_fall_down && -#if 0 - !player_is_standing_on_valid_field && -#endif - !player_is_moving_to_valid_field) - { -#if 0 - printf("::: setting programmed_action to MV_DOWN [%d,%d - %d] ...\n", - jx, jy, FrameCounter); -#endif - - player->programmed_action = MV_DOWN; - } - } -} + if (player_can_fall_down && + !player_is_moving_to_valid_field) + player->programmed_action = MV_DOWN; + } +} static void CheckGravityMovementWhenNotMoving(struct PlayerInfo *player) { -#if 1 return CheckGravityMovement(player); -#endif if (game.gravity && !player->programmed_action) { @@ -9851,26 +9124,11 @@ static void CheckGravityMovementWhenNotMoving(struct PlayerInfo *player) boolean MovePlayerOneStep(struct PlayerInfo *player, int dx, int dy, int real_dx, int real_dy) { -#if 0 - static int trigger_sides[4][2] = - { - /* enter side leave side */ - { CH_SIDE_RIGHT, CH_SIDE_LEFT }, /* moving left */ - { CH_SIDE_LEFT, CH_SIDE_RIGHT }, /* moving right */ - { CH_SIDE_BOTTOM, CH_SIDE_TOP }, /* moving up */ - { CH_SIDE_TOP, CH_SIDE_BOTTOM } /* moving down */ - }; - int move_direction = (dx == -1 ? MV_LEFT : - dx == +1 ? MV_RIGHT : - dy == -1 ? MV_UP : - dy == +1 ? MV_DOWN : MV_NO_MOVING); - int enter_side = trigger_sides[MV_DIR_BIT(move_direction)][0]; - int leave_side = trigger_sides[MV_DIR_BIT(move_direction)][1]; -#endif int jx = player->jx, jy = player->jy; int new_jx = jx + dx, new_jy = jy + dy; int element; int can_move; + boolean player_can_move = !player->cannot_move; if (!player->active || (!dx && !dy)) return MF_NO_ACTION; @@ -9878,21 +9136,38 @@ boolean MovePlayerOneStep(struct PlayerInfo *player, player->MovDir = (dx < 0 ? MV_LEFT : dx > 0 ? MV_RIGHT : dy < 0 ? MV_UP : - dy > 0 ? MV_DOWN : MV_NO_MOVING); + dy > 0 ? MV_DOWN : MV_NONE); if (!IN_LEV_FIELD(new_jx, new_jy)) return MF_NO_ACTION; + if (!player_can_move) + { +#if 1 + if (player->MovPos == 0) + { + player->is_moving = FALSE; + player->is_digging = FALSE; + player->is_collecting = FALSE; + player->is_snapping = FALSE; + player->is_pushing = FALSE; + } +#else + DigField(player, 0, 0, 0, 0, 0, 0, DF_NO_PUSH); + SnapField(player, 0, 0); +#endif + +#if 0 + return MF_NO_ACTION; +#endif + } + if (!options.network && !AllPlayersInSight(player, new_jx, new_jy)) return MF_NO_ACTION; -#if 0 - element = MovingOrBlocked2Element(new_jx, new_jy); -#else element = MovingOrBlocked2ElementIfNotLeaving(new_jx, new_jy); -#endif - if (DONT_RUN_INTO(element)) + if (player_can_move && DONT_RUN_INTO(element)) { if (element == EL_ACID && dx == 0 && dy == 1) { @@ -9901,10 +9176,10 @@ boolean MovePlayerOneStep(struct PlayerInfo *player, InitMovingField(jx, jy, MV_DOWN); Store[jx][jy] = EL_ACID; ContinueMoving(jx, jy); - BuryHero(player); + BuryPlayer(player); } else - TestIfHeroRunsIntoBadThing(jx, jy, player->MovDir); + TestIfPlayerRunsIntoBadThing(jx, jy, player->MovDir); return MF_MOVING; } @@ -9924,36 +9199,21 @@ boolean MovePlayerOneStep(struct PlayerInfo *player, player->jy = new_jy; StorePlayer[new_jx][new_jy] = player->element_nr; + if (player->move_delay_value_next != -1) + { + player->move_delay_value = player->move_delay_value_next; + player->move_delay_value_next = -1; + } + player->MovPos = (dx > 0 || dy > 0 ? -1 : 1) * (TILEX - TILEX / player->move_delay_value); player->step_counter++; -#if 0 - player->drop_delay = 0; -#endif - PlayerVisit[jx][jy] = FrameCounter; ScrollPlayer(player, SCROLL_INIT); -#if 0 - if (IS_CUSTOM_ELEMENT(Feld[jx][jy])) - { - CheckTriggeredElementChangeBySide(jx, jy, Feld[jx][jy], CE_PLAYER_LEAVES_X, - leave_side); - CheckElementChangeBySide(jx,jy, Feld[jx][jy],CE_LEFT_BY_PLAYER,leave_side); - } - - if (IS_CUSTOM_ELEMENT(Feld[new_jx][new_jy])) - { - CheckTriggeredElementChangeBySide(new_jx, new_jy, Feld[new_jx][new_jy], - CE_PLAYER_ENTERS_X, enter_side); - CheckElementChangeBySide(new_jx, new_jy, Feld[new_jx][new_jy], - CE_ENTERED_BY_PLAYER, enter_side); - } -#endif - return MF_MOVING; } @@ -9963,7 +9223,6 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) int old_jx = jx, old_jy = jy; int moved = MF_NO_ACTION; -#if 1 if (!player->active) return FALSE; @@ -9980,54 +9239,14 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) return FALSE; } -#else - if (!player->active || (!dx && !dy)) - return FALSE; -#endif - -#if 0 - if (!FrameReached(&player->move_delay, player->move_delay_value) && - !tape.playing) - return FALSE; -#else - -#if 1 - -#if 0 - printf("::: %d <= %d < %d ?\n", player->move_delay, FrameCounter, - player->move_delay + player->move_delay_value); -#endif -#if USE_NEW_MOVE_DELAY if (player->move_delay > 0) -#else - if (!FrameReached(&player->move_delay, player->move_delay_value)) -#endif - { -#if 0 - printf("::: can NOT move\n"); -#endif - - return FALSE; - } -#else - if (!FrameReached(&player->move_delay, player->move_delay_value) && - !(tape.playing && tape.file_version < FILE_VERSION_2_0)) return FALSE; -#endif - -#endif -#if 0 - printf("::: COULD move now\n"); -#endif - -#if USE_NEW_MOVE_DELAY player->move_delay = -1; /* set to "uninitialized" value */ -#endif /* store if player is automatically moved to next field */ - player->is_auto_moving = (player->programmed_action != MV_NO_MOVING); + player->is_auto_moving = (player->programmed_action != MV_NONE); /* remove the last programmed player action */ player->programmed_action = 0; @@ -10052,11 +9271,7 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) ScrollPlayer(player, SCROLL_GO_ON); ScrollScreen(NULL, SCROLL_GO_ON); -#if USE_NEW_MOVE_DELAY AdvanceFrameAndPlayerCounters(player->index_nr); -#else - FrameCounter++; -#endif DrawAllPlayers(); BackToFront(); @@ -10148,23 +9363,10 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) } } -#if 0 -#if 1 - InitPlayerGfxAnimation(player, ACTION_DEFAULT); -#else - if (!(moved & MF_MOVING) && !player->is_pushing) - player->Frame = 0; -#endif -#endif - player->StepFrame = 0; if (moved & MF_MOVING) { -#if 0 - printf("::: REALLY moves now\n"); -#endif - if (old_jx != jx && old_jy == jy) player->MovDir = (old_jx < jx ? MV_RIGHT : MV_LEFT); else if (old_jx == jx && old_jy != jy) @@ -10174,101 +9376,36 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) player->last_move_dir = player->MovDir; player->is_moving = TRUE; -#if 1 player->is_snapping = FALSE; -#endif - -#if 1 player->is_switching = FALSE; -#endif - player->is_dropping = FALSE; - - -#if 0 - /* !!! ENABLE THIS FOR OLD VERSIONS !!! */ - -#if 1 - if (game.engine_version < VERSION_IDENT(3,1,0,0)) -#endif - { - int move_direction = player->MovDir; -#if 1 - int enter_side = MV_DIR_OPPOSITE(move_direction); - int leave_side = move_direction; -#else - static int trigger_sides[4][2] = - { - /* enter side leave side */ - { CH_SIDE_RIGHT, CH_SIDE_LEFT }, /* moving left */ - { CH_SIDE_LEFT, CH_SIDE_RIGHT }, /* moving right */ - { CH_SIDE_BOTTOM, CH_SIDE_TOP }, /* moving up */ - { CH_SIDE_TOP, CH_SIDE_BOTTOM } /* moving down */ - }; - int enter_side = trigger_sides[MV_DIR_BIT(move_direction)][0]; - int leave_side = trigger_sides[MV_DIR_BIT(move_direction)][1]; -#endif - int old_element = Feld[old_jx][old_jy]; - int new_element = Feld[jx][jy]; - -#if 1 - /* !!! TEST ONLY !!! */ - if (IS_CUSTOM_ELEMENT(old_element)) - CheckElementChangeByPlayer(old_jx, old_jy, old_element, - CE_LEFT_BY_PLAYER, - player->index_bit, leave_side); - - CheckTriggeredElementChangeByPlayer(old_jx, old_jy, old_element, - CE_PLAYER_LEAVES_X, - player->index_bit, leave_side); - - if (IS_CUSTOM_ELEMENT(new_element)) - CheckElementChangeByPlayer(jx, jy, new_element, CE_ENTERED_BY_PLAYER, - player->index_bit, enter_side); - - CheckTriggeredElementChangeByPlayer(jx, jy, new_element, - CE_PLAYER_ENTERS_X, - player->index_bit, enter_side); -#endif - - } -#endif - - } else { CheckGravityMovementWhenNotMoving(player); - /* - player->last_move_dir = MV_NO_MOVING; - */ player->is_moving = FALSE; -#if USE_NEW_MOVE_STYLE - /* player is ALLOWED to move, but CANNOT move (something blocks his way) */ - /* ensure that the player is also allowed to move in the next frame */ - /* (currently, the player is forced to wait eight frames before he can try - again!!!) */ + /* at this point, the player is allowed to move, but cannot move right now + (e.g. because of something blocking the way) -- ensure that the player + is also allowed to move in the next frame (in old versions before 3.1.1, + the player was forced to wait again for eight frames before next try) */ if (game.engine_version >= VERSION_IDENT(3,1,1,0)) player->move_delay = 0; /* allow direct movement in the next frame */ -#endif } -#if USE_NEW_MOVE_DELAY if (player->move_delay == -1) /* not yet initialized by DigField() */ player->move_delay = player->move_delay_value; -#endif if (game.engine_version < VERSION_IDENT(3,0,7,0)) { - TestIfHeroTouchesBadThing(jx, jy); + TestIfPlayerTouchesBadThing(jx, jy); TestIfPlayerTouchesCustomElement(jx, jy); } if (!player->active) - RemoveHero(player); + RemovePlayer(player); return moved; } @@ -10279,28 +9416,22 @@ void ScrollPlayer(struct PlayerInfo *player, int mode) int last_jx = player->last_jx, last_jy = player->last_jy; int move_stepsize = TILEX / player->move_delay_value; - if (!player->active || !player->MovPos) +#if USE_NEW_PLAYER_SPEED + if (!player->active) + return; + + if (player->MovPos == 0 && mode == SCROLL_GO_ON) /* player not moving */ + return; +#else + if (!player->active || player->MovPos == 0) return; +#endif if (mode == SCROLL_INIT) { player->actual_frame_counter = FrameCounter; player->GfxPos = move_stepsize * (player->MovPos / move_stepsize); -#if 0 - printf("::: %06d: %d,%d: %d (%d) [%d]\n", - FrameCounter, - last_jx, last_jy, Feld[last_jx][last_jy], EL_EXPLOSION, - player->block_delay); -#endif - -#if USE_NEW_BLOCK_STYLE - -#if 0 - if (player->block_delay <= 0) - printf("::: ALERT! block_delay == %d\n", player->block_delay); -#endif - if ((player->block_last_field || player->block_delay_adjustment > 0) && Feld[last_jx][last_jy] == EL_EMPTY) { @@ -10312,84 +9443,59 @@ void ScrollPlayer(struct PlayerInfo *player, int mode) { last_field_block_delay += player->move_delay_value; -#if USE_GRAVITY_BUGFIX_NEW /* when blocking enabled, prevent moving up despite gravity */ if (game.gravity && player->MovDir == MV_UP) block_delay_adjustment = -1; -#endif } /* add block delay adjustment (also possible when not blocking) */ last_field_block_delay += block_delay_adjustment; -#if 0 -#if USE_BLOCK_DELAY_BUGFIX - /* when blocking enabled, correct block delay for fast movement */ - if (player->block_last_field && - player->move_delay_value < MOVE_DELAY_NORMAL_SPEED) - last_field_block_delay = - player->move_delay_value + player->block_delay_adjustment; -#endif -#endif - -#if 0 -#if USE_GRAVITY_BUGFIX_NEW - /* when blocking enabled, correct block delay for gravity movement */ - if (player->block_last_field && - game.gravity && player->MovDir == MV_UP) - last_field_block_delay = player->move_delay_value - 1; -#endif -#endif - Feld[last_jx][last_jy] = EL_PLAYER_IS_LEAVING; MovDelay[last_jx][last_jy] = last_field_block_delay + 1; } + +#if USE_NEW_PLAYER_SPEED + if (player->MovPos != 0) /* player has not yet reached destination */ + return; #else -#if USE_NEW_MOVE_STYLE - if ((game.engine_version < VERSION_IDENT(3,1,1,0) || - player->block_last_field) && - Feld[last_jx][last_jy] == EL_EMPTY) - Feld[last_jx][last_jy] = EL_PLAYER_IS_LEAVING; -#else - if (Feld[last_jx][last_jy] == EL_EMPTY) - Feld[last_jx][last_jy] = EL_PLAYER_IS_LEAVING; -#endif + return; #endif + } + else if (!FrameReached(&player->actual_frame_counter, 1)) + return; #if 0 - DrawPlayer(player); + printf("::: player->MovPos: %d -> %d\n", + player->MovPos, + player->MovPos + (player->MovPos > 0 ? -1 : 1) * move_stepsize); #endif - return; - } - else if (!FrameReached(&player->actual_frame_counter, 1)) - return; +#if USE_NEW_PLAYER_SPEED + if (player->MovPos != 0) + { + player->MovPos += (player->MovPos > 0 ? -1 : 1) * move_stepsize; + player->GfxPos = move_stepsize * (player->MovPos / move_stepsize); + /* before DrawPlayer() to draw correct player graphic for this case */ + if (player->MovPos == 0) + CheckGravityMovement(player); + } +#else player->MovPos += (player->MovPos > 0 ? -1 : 1) * move_stepsize; player->GfxPos = move_stepsize * (player->MovPos / move_stepsize); -#if USE_NEW_BLOCK_STYLE -#else - if (!player->block_last_field && - Feld[last_jx][last_jy] == EL_PLAYER_IS_LEAVING) -#if 1 - RemoveField(last_jx, last_jy); -#else - Feld[last_jx][last_jy] = EL_EMPTY; -#endif -#endif - /* before DrawPlayer() to draw correct player graphic for this case */ if (player->MovPos == 0) CheckGravityMovement(player); - -#if 0 - DrawPlayer(player); /* needed here only to cleanup last field */ #endif if (player->MovPos == 0) /* player reached destination field */ { -#if 1 +#if 0 + printf("::: player reached destination field\n"); +#endif + if (player->move_delay_reset_counter > 0) { player->move_delay_reset_counter--; @@ -10403,27 +9509,6 @@ void ScrollPlayer(struct PlayerInfo *player, int mode) player->move_delay = 0; } } -#else - if (IS_PASSABLE(Feld[last_jx][last_jy])) - { - /* continue with normal speed after quickly moving through gate */ - HALVE_PLAYER_SPEED(player); - - /* be able to make the next move without delay */ - player->move_delay = 0; - } -#endif - -#if USE_NEW_BLOCK_STYLE -#else - if (player->block_last_field && - Feld[last_jx][last_jy] == EL_PLAYER_IS_LEAVING) -#if 1 - RemoveField(last_jx, last_jy); -#else - Feld[last_jx][last_jy] = EL_EMPTY; -#endif -#endif player->last_jx = jx; player->last_jy = jy; @@ -10433,43 +9518,23 @@ void ScrollPlayer(struct PlayerInfo *player, int mode) Feld[jx][jy] == EL_SP_EXIT_OPENING) /* <-- special case */ { DrawPlayer(player); /* needed here only to cleanup last field */ - RemoveHero(player); + RemovePlayer(player); if (local_player->friends_still_needed == 0 || IS_SP_ELEMENT(Feld[jx][jy])) player->LevelSolved = player->GameOver = TRUE; } -#if 1 - /* !!! ENABLE THIS FOR NEW VERSIONS !!! */ /* this breaks one level: "machine", level 000 */ -#if 0 - if (game.engine_version >= VERSION_IDENT(3,1,0,0)) -#endif { int move_direction = player->MovDir; -#if 1 int enter_side = MV_DIR_OPPOSITE(move_direction); int leave_side = move_direction; -#else - static int trigger_sides[4][2] = - { - /* enter side leave side */ - { CH_SIDE_RIGHT, CH_SIDE_LEFT }, /* moving left */ - { CH_SIDE_LEFT, CH_SIDE_RIGHT }, /* moving right */ - { CH_SIDE_BOTTOM, CH_SIDE_TOP }, /* moving up */ - { CH_SIDE_TOP, CH_SIDE_BOTTOM } /* moving down */ - }; - int enter_side = trigger_sides[MV_DIR_BIT(move_direction)][0]; - int leave_side = trigger_sides[MV_DIR_BIT(move_direction)][1]; -#endif int old_jx = last_jx; int old_jy = last_jy; int old_element = Feld[old_jx][old_jy]; int new_element = Feld[jx][jy]; -#if 1 - /* !!! TEST ONLY !!! */ if (IS_CUSTOM_ELEMENT(old_element)) CheckElementChangeByPlayer(old_jx, old_jy, old_element, CE_LEFT_BY_PLAYER, @@ -10486,26 +9551,23 @@ void ScrollPlayer(struct PlayerInfo *player, int mode) CheckTriggeredElementChangeByPlayer(jx, jy, new_element, CE_PLAYER_ENTERS_X, player->index_bit, enter_side); -#endif + CheckTriggeredElementChangeBySide(jx, jy, player->element_nr, + CE_MOVE_OF_X, move_direction); } -#endif if (game.engine_version >= VERSION_IDENT(3,0,7,0)) { - TestIfHeroTouchesBadThing(jx, jy); + TestIfPlayerTouchesBadThing(jx, jy); TestIfPlayerTouchesCustomElement(jx, jy); -#if 1 -#if 1 + /* needed because pushed element has not yet reached its destination, so it would trigger a change event at its previous field location */ if (!player->is_pushing) -#endif TestIfElementTouchesCustomElement(jx, jy); /* for empty space */ -#endif if (!player->active) - RemoveHero(player); + RemovePlayer(player); } if (level.use_step_counter) @@ -10525,7 +9587,7 @@ void ScrollPlayer(struct PlayerInfo *player, int mode) if (!TimeLeft && setup.time_limit) for (i = 0; i < MAX_PLAYERS; i++) - KillHero(&stored_player[i]); + KillPlayer(&stored_player[i]); } else if (level.time == 0 && !AllPlayersGone) /* level w/o time limit */ DrawGameValue_Time(TimePlayed); @@ -10562,7 +9624,7 @@ void ScrollScreen(struct PlayerInfo *player, int mode) redraw_mask |= REDRAW_FIELD; } else - ScreenMovDir = MV_NO_MOVING; + ScreenMovDir = MV_NONE; } void TestIfPlayerTouchesCustomElement(int x, int y) @@ -10616,20 +9678,11 @@ void TestIfPlayerTouchesCustomElement(int x, int y) else continue; /* center and border element do not touch */ -#if 1 - /* !!! TEST ONLY !!! */ CheckElementChangeByPlayer(xx, yy, border_element, CE_TOUCHED_BY_PLAYER, player->index_bit, border_side); CheckTriggeredElementChangeByPlayer(xx, yy, border_element, CE_PLAYER_TOUCHES_X, player->index_bit, border_side); -#else - CheckTriggeredElementChangeByPlayer(xx, yy, border_element, - CE_PLAYER_TOUCHES_X, - player->index_bit, border_side); - CheckElementChangeByPlayer(xx, yy, border_element, CE_TOUCHED_BY_PLAYER, - player->index_bit, border_side); -#endif } else if (IS_PLAYER(xx, yy)) { @@ -10641,21 +9694,11 @@ void TestIfPlayerTouchesCustomElement(int x, int y) continue; /* center and border element do not touch */ } -#if 1 - /* !!! TEST ONLY !!! */ CheckElementChangeByPlayer(x, y, center_element, CE_TOUCHED_BY_PLAYER, player->index_bit, center_side); CheckTriggeredElementChangeByPlayer(x, y, center_element, CE_PLAYER_TOUCHES_X, player->index_bit, center_side); -#else - CheckTriggeredElementChangeByPlayer(x, y, center_element, - CE_PLAYER_TOUCHES_X, - player->index_bit, center_side); - CheckElementChangeByPlayer(x, y, center_element, CE_TOUCHED_BY_PLAYER, - player->index_bit, center_side); -#endif - break; } } @@ -10686,10 +9729,8 @@ void TestIfElementTouchesCustomElement(int x, int y) MV_LEFT | MV_RIGHT }; boolean change_center_element = FALSE; - int center_element_change_page = 0; int center_element = Feld[x][y]; /* should always be non-moving! */ - int border_trigger_element = EL_UNDEFINED; - int i, j; + int i; for (i = 0; i < NUM_DIRECTIONS; i++) { @@ -10712,73 +9753,14 @@ void TestIfElementTouchesCustomElement(int x, int y) continue; /* center and border element do not touch */ /* check for change of center element (but change it only once) */ - if (IS_CUSTOM_ELEMENT(center_element) && - HAS_ANY_CHANGE_EVENT(center_element, CE_TOUCHING_X) && - !change_center_element) - { - for (j = 0; j < element_info[center_element].num_change_pages; j++) - { - struct ElementChangeInfo *change = - &element_info[center_element].change_page[j]; - - if (change->can_change && - change->has_event[CE_TOUCHING_X] && - change->trigger_side & border_side && -#if 1 - IS_EQUAL_OR_IN_GROUP(border_element, change->trigger_element) -#else - change->trigger_element == border_element -#endif - ) - { - change_center_element = TRUE; - center_element_change_page = j; - border_trigger_element = border_element; - - break; - } - } - } + if (!change_center_element) + change_center_element = + CheckElementChangeBySide(x, y, center_element, border_element, + CE_TOUCHING_X, border_side); /* check for change of border element */ - if (IS_CUSTOM_ELEMENT(border_element) && - HAS_ANY_CHANGE_EVENT(border_element, CE_TOUCHING_X)) - { - for (j = 0; j < element_info[border_element].num_change_pages; j++) - { - struct ElementChangeInfo *change = - &element_info[border_element].change_page[j]; - - if (change->can_change && - change->has_event[CE_TOUCHING_X] && - change->trigger_side & center_side && -#if 1 - IS_EQUAL_OR_IN_GROUP(center_element, change->trigger_element) -#else - change->trigger_element == center_element -#endif - ) - { -#if 0 - printf("::: border_element %d, %d\n", x, y); -#endif - - CheckElementChangeByPage(xx, yy, border_element, center_element, - CE_TOUCHING_X, j); - break; - } - } - } - } - - if (change_center_element) - { -#if 0 - printf("::: center_element %d, %d\n", x, y); -#endif - - CheckElementChangeByPage(x, y, center_element, border_trigger_element, - CE_TOUCHING_X, center_element_change_page); + CheckElementChangeBySide(xx, yy, border_element, center_element, + CE_TOUCHING_X, center_side); } } @@ -10789,119 +9771,40 @@ void TestIfElementHitsCustomElement(int x, int y, int direction) int hitx = x + dx, hity = y + dy; int hitting_element = Feld[x][y]; int touched_element; -#if 0 - boolean object_hit = (IN_LEV_FIELD(hitx, hity) && - !IS_FREE(hitx, hity) && - (!IS_MOVING(hitx, hity) || - MovDir[hitx][hity] != direction || - ABS(MovPos[hitx][hity]) <= TILEY / 2)); -#endif if (IN_LEV_FIELD(hitx, hity) && IS_FREE(hitx, hity)) return; -#if 0 - if (IN_LEV_FIELD(hitx, hity) && !object_hit) - return; -#endif - touched_element = (IN_LEV_FIELD(hitx, hity) ? MovingOrBlocked2Element(hitx, hity) : EL_STEELWALL); -#if !USE_HITTING_SOMETHING_BUGFIX - /* "hitting something" is also true when hitting the playfield border */ - CheckElementChangeBySide(x, y, hitting_element, touched_element, - CE_HITTING_SOMETHING, direction); -#endif - if (IN_LEV_FIELD(hitx, hity)) { int opposite_direction = MV_DIR_OPPOSITE(direction); int hitting_side = direction; int touched_side = opposite_direction; -#if 0 - int touched_element = MovingOrBlocked2Element(hitx, hity); -#endif -#if 1 boolean object_hit = (!IS_MOVING(hitx, hity) || MovDir[hitx][hity] != direction || ABS(MovPos[hitx][hity]) <= TILEY / 2); object_hit = TRUE; -#endif if (object_hit) { - int i; + CheckElementChangeBySide(x, y, hitting_element, touched_element, + CE_HITTING_X, touched_side); -#if !USE_HIT_BY_SOMETHING_BUGFIX - CheckElementChangeBySide(hitx, hity, touched_element, hitting_element, - CE_HIT_BY_SOMETHING, opposite_direction); -#endif + CheckElementChangeBySide(hitx, hity, touched_element, + hitting_element, CE_HIT_BY_X, hitting_side); - if (IS_CUSTOM_ELEMENT(hitting_element) && - HAS_ANY_CHANGE_EVENT(hitting_element, CE_HITTING_X)) - { - for (i = 0; i < element_info[hitting_element].num_change_pages; i++) - { - struct ElementChangeInfo *change = - &element_info[hitting_element].change_page[i]; - - if (change->can_change && - change->has_event[CE_HITTING_X] && - change->trigger_side & touched_side && - -#if 1 - IS_EQUAL_OR_IN_GROUP(touched_element, change->trigger_element) -#else - change->trigger_element == touched_element -#endif - ) - { - CheckElementChangeByPage(x, y, hitting_element, touched_element, - CE_HITTING_X, i); - break; - } - } - } - - if (IS_CUSTOM_ELEMENT(touched_element) && - HAS_ANY_CHANGE_EVENT(touched_element, CE_HIT_BY_X)) - { - for (i = 0; i < element_info[touched_element].num_change_pages; i++) - { - struct ElementChangeInfo *change = - &element_info[touched_element].change_page[i]; - - if (change->can_change && - change->has_event[CE_HIT_BY_X] && - change->trigger_side & hitting_side && -#if 1 - IS_EQUAL_OR_IN_GROUP(hitting_element, change->trigger_element) -#else - change->trigger_element == hitting_element -#endif - ) - { - CheckElementChangeByPage(hitx, hity, touched_element, - hitting_element, CE_HIT_BY_X, i); - break; - } - } - } - -#if USE_HIT_BY_SOMETHING_BUGFIX CheckElementChangeBySide(hitx, hity, touched_element, hitting_element, CE_HIT_BY_SOMETHING, opposite_direction); -#endif } } -#if USE_HITTING_SOMETHING_BUGFIX /* "hitting something" is also true when hitting the playfield border */ CheckElementChangeBySide(x, y, hitting_element, touched_element, CE_HITTING_SOMETHING, direction); -#endif } #if 0 @@ -10957,56 +9860,11 @@ void TestIfElementSmashesCustomElement(int x, int y, int direction) CheckElementChangeBySide(hitx, hity, touched_element, hitting_element, CE_SMASHED_BY_SOMETHING, opposite_direction); - if (IS_CUSTOM_ELEMENT(hitting_element) && - HAS_ANY_CHANGE_EVENT(hitting_element, CE_OTHER_IS_SMASHING)) - { - for (i = 0; i < element_info[hitting_element].num_change_pages; i++) - { - struct ElementChangeInfo *change = - &element_info[hitting_element].change_page[i]; - - if (change->can_change && - change->has_event[CE_OTHER_IS_SMASHING] && - change->trigger_side & touched_side && - -#if 1 - IS_EQUAL_OR_IN_GROUP(touched_element, change->trigger_element) -#else - change->trigger_element == touched_element -#endif - ) - { - CheckElementChangeByPage(x, y, hitting_element, touched_element, - CE_OTHER_IS_SMASHING, i); - break; - } - } - } - - if (IS_CUSTOM_ELEMENT(touched_element) && - HAS_ANY_CHANGE_EVENT(touched_element, CE_OTHER_GETS_SMASHED)) - { - for (i = 0; i < element_info[touched_element].num_change_pages; i++) - { - struct ElementChangeInfo *change = - &element_info[touched_element].change_page[i]; + CheckElementChangeBySide(x, y, hitting_element, touched_element, + CE_OTHER_IS_SMASHING, touched_side); - if (change->can_change && - change->has_event[CE_OTHER_GETS_SMASHED] && - change->trigger_side & hitting_side && -#if 1 - IS_EQUAL_OR_IN_GROUP(hitting_element, change->trigger_element) -#else - change->trigger_element == hitting_element -#endif - ) - { - CheckElementChangeByPage(hitx, hity, touched_element, - hitting_element, CE_OTHER_GETS_SMASHED,i); - break; - } - } - } + CheckElementChangeBySide(hitx, hity, touched_element, hitting_element, + CE_OTHER_GETS_SMASHED, hitting_side); } } } @@ -11042,13 +9900,9 @@ void TestIfGoodThingHitsBadThing(int good_x, int good_y, int good_move_dir) continue; test_move_dir = - (IS_MOVING(test_x, test_y) ? MovDir[test_x][test_y] : MV_NO_MOVING); + (IS_MOVING(test_x, test_y) ? MovDir[test_x][test_y] : MV_NONE); -#if 0 - test_element = Feld[test_x][test_y]; -#else test_element = MovingOrBlocked2ElementIfNotLeaving(test_x, test_y); -#endif /* 1st case: good thing is moving towards DONT_RUN_INTO style bad thing; 2nd case: DONT_TOUCH style bad thing does not move away from good thing @@ -11070,18 +9924,11 @@ void TestIfGoodThingHitsBadThing(int good_x, int good_y, int good_move_dir) { struct PlayerInfo *player = PLAYERINFO(good_x, good_y); -#if 1 if (player->shield_deadly_time_left > 0 && !IS_INDESTRUCTIBLE(bad_element)) Bang(kill_x, kill_y); else if (!PLAYER_ENEMY_PROTECTED(good_x, good_y)) - KillHero(player); -#else - if (player->shield_deadly_time_left > 0) - Bang(kill_x, kill_y); - else if (!PLAYER_ENEMY_PROTECTED(good_x, good_y)) - KillHero(player); -#endif + KillPlayer(player); } else Bang(good_x, good_y); @@ -11127,7 +9974,7 @@ void TestIfBadThingHitsGoodThing(int bad_x, int bad_y, int bad_move_dir) continue; test_move_dir = - (IS_MOVING(test_x, test_y) ? MovDir[test_x][test_y] : MV_NO_MOVING); + (IS_MOVING(test_x, test_y) ? MovDir[test_x][test_y] : MV_NONE); test_element = Feld[test_x][test_y]; @@ -11170,52 +10017,45 @@ void TestIfBadThingHitsGoodThing(int bad_x, int bad_y, int bad_move_dir) { struct PlayerInfo *player = PLAYERINFO(kill_x, kill_y); -#if 1 if (player->shield_deadly_time_left > 0 && !IS_INDESTRUCTIBLE(bad_element)) Bang(bad_x, bad_y); else if (!PLAYER_ENEMY_PROTECTED(kill_x, kill_y)) - KillHero(player); -#else - if (player->shield_deadly_time_left > 0) - Bang(bad_x, bad_y); - else if (!PLAYER_ENEMY_PROTECTED(kill_x, kill_y)) - KillHero(player); -#endif + KillPlayer(player); } else Bang(kill_x, kill_y); } } -void TestIfHeroTouchesBadThing(int x, int y) +void TestIfPlayerTouchesBadThing(int x, int y) { - TestIfGoodThingHitsBadThing(x, y, MV_NO_MOVING); + TestIfGoodThingHitsBadThing(x, y, MV_NONE); } -void TestIfHeroRunsIntoBadThing(int x, int y, int move_dir) +void TestIfPlayerRunsIntoBadThing(int x, int y, int move_dir) { TestIfGoodThingHitsBadThing(x, y, move_dir); } -void TestIfBadThingTouchesHero(int x, int y) +void TestIfBadThingTouchesPlayer(int x, int y) { - TestIfBadThingHitsGoodThing(x, y, MV_NO_MOVING); + TestIfBadThingHitsGoodThing(x, y, MV_NONE); } -void TestIfBadThingRunsIntoHero(int x, int y, int move_dir) +void TestIfBadThingRunsIntoPlayer(int x, int y, int move_dir) { TestIfBadThingHitsGoodThing(x, y, move_dir); } void TestIfFriendTouchesBadThing(int x, int y) { - TestIfGoodThingHitsBadThing(x, y, MV_NO_MOVING); + TestIfGoodThingHitsBadThing(x, y, MV_NONE); } void TestIfBadThingTouchesFriend(int x, int y) { - TestIfBadThingHitsGoodThing(x, y, MV_NO_MOVING); + TestIfBadThingHitsGoodThing(x, y, MV_NONE); } void TestIfBadThingTouchesOtherBadThing(int bad_x, int bad_y) @@ -11252,7 +10092,7 @@ void TestIfBadThingTouchesOtherBadThing(int bad_x, int bad_y) Bang(bad_x, bad_y); } -void KillHero(struct PlayerInfo *player) +void KillPlayer(struct PlayerInfo *player) { int jx = player->jx, jy = player->jy; @@ -11267,40 +10107,36 @@ void KillHero(struct PlayerInfo *player) player->shield_deadly_time_left = 0; Bang(jx, jy); - BuryHero(player); + BuryPlayer(player); } -static void KillHeroUnlessEnemyProtected(int x, int y) +static void KillPlayerUnlessEnemyProtected(int x, int y) { if (!PLAYER_ENEMY_PROTECTED(x, y)) - KillHero(PLAYERINFO(x, y)); + KillPlayer(PLAYERINFO(x, y)); } -static void KillHeroUnlessExplosionProtected(int x, int y) +static void KillPlayerUnlessExplosionProtected(int x, int y) { if (!PLAYER_EXPLOSION_PROTECTED(x, y)) - KillHero(PLAYERINFO(x, y)); + KillPlayer(PLAYERINFO(x, y)); } -void BuryHero(struct PlayerInfo *player) +void BuryPlayer(struct PlayerInfo *player) { int jx = player->jx, jy = player->jy; if (!player->active) return; -#if 1 - PlayLevelSoundElementAction(jx, jy, player->element_nr, ACTION_DYING); -#else - PlayLevelSound(jx, jy, SND_CLASS_PLAYER_DYING); -#endif + PlayLevelSoundElementAction(jx, jy, player->artwork_element, ACTION_DYING); PlayLevelSound(jx, jy, SND_GAME_LOSING); player->GameOver = TRUE; - RemoveHero(player); + RemovePlayer(player); } -void RemoveHero(struct PlayerInfo *player) +void RemovePlayer(struct PlayerInfo *player) { int jx = player->jx, jy = player->jy; int i, found = FALSE; @@ -11311,6 +10147,9 @@ void RemoveHero(struct PlayerInfo *player) if (!ExplodeField[jx][jy]) StorePlayer[jx][jy] = 0; + if (player->is_moving) + DrawLevelField(player->last_jx, player->last_jy); + for (i = 0; i < MAX_PLAYERS; i++) if (stored_player[i].active) found = TRUE; @@ -11322,6 +10161,27 @@ void RemoveHero(struct PlayerInfo *player) ExitY = ZY = jy; } +#if USE_NEW_SNAP_DELAY +static void setFieldForSnapping(int x, int y, int element, int direction) +{ + struct ElementInfo *ei = &element_info[element]; + int direction_bit = MV_DIR_BIT(direction); + int graphic_snapping = ei->direction_graphic[ACTION_SNAPPING][direction_bit]; + int action = (graphic_snapping != IMG_EMPTY_SPACE ? ACTION_SNAPPING : + IS_DIGGABLE(element) ? ACTION_DIGGING : ACTION_COLLECTING); + + Feld[x][y] = EL_ELEMENT_SNAPPING; + MovDelay[x][y] = MOVE_DELAY_NORMAL_SPEED + 1 - 1; + + ResetGfxAnimation(x, y); + + GfxElement[x][y] = element; + GfxAction[x][y] = action; + GfxDir[x][y] = direction; + GfxFrame[x][y] = -1; +} +#endif + /* ============================================================================= checkDiagonalPushing() @@ -11363,33 +10223,21 @@ int DigField(struct PlayerInfo *player, int oldx, int oldy, int x, int y, int real_dx, int real_dy, int mode) { -#if 0 - boolean use_spring_bug = (game.engine_version < VERSION_IDENT(2,2,0,0)); -#endif boolean is_player = (IS_PLAYER(oldx, oldy) || mode != DF_DIG); boolean player_was_pushing = player->is_pushing; + boolean player_can_enter = (!player->cannot_move || mode == DF_SNAP); int jx = oldx, jy = oldy; int dx = x - jx, dy = y - jy; int nextx = x + dx, nexty = y + dy; - int move_direction = (dx == -1 ? MV_LEFT : + int move_direction = (dx == -1 ? MV_LEFT : dx == +1 ? MV_RIGHT : - dy == -1 ? MV_UP : - dy == +1 ? MV_DOWN : MV_NO_MOVING); + dy == -1 ? MV_UP : + dy == +1 ? MV_DOWN : MV_NONE); int opposite_direction = MV_DIR_OPPOSITE(move_direction); -#if 1 int dig_side = MV_DIR_OPPOSITE(move_direction); -#else - static int trigger_sides[4] = - { - CH_SIDE_RIGHT, /* moving left */ - CH_SIDE_LEFT, /* moving right */ - CH_SIDE_BOTTOM, /* moving up */ - CH_SIDE_TOP, /* moving down */ - }; - int dig_side = trigger_sides[MV_DIR_BIT(move_direction)]; -#endif int old_element = Feld[jx][jy]; int element; + int collect_count; if (is_player) /* function can also be called by EL_PENGUIN */ { @@ -11405,11 +10253,7 @@ int DigField(struct PlayerInfo *player, if (mode == DF_NO_PUSH) /* player just stopped pushing */ { player->is_switching = FALSE; -#if USE_NEW_PUSH_DELAY player->push_delay = -1; -#else - player->push_delay = 0; -#endif return MF_NO_ACTION; } @@ -11418,50 +10262,13 @@ int DigField(struct PlayerInfo *player, if (IS_MOVING(x, y) || IS_PLAYER(x, y)) return MF_NO_ACTION; -#if 0 - -#if 0 - if (IS_TUBE(Feld[jx][jy]) || IS_TUBE(Back[jx][jy])) -#else - if (IS_TUBE(Feld[jx][jy]) || - (IS_TUBE(Back[jx][jy]) && game.engine_version >= VERSION_IDENT(2,2,0,0))) -#endif - { - int i = 0; - int tube_element = (IS_TUBE(Feld[jx][jy]) ? Feld[jx][jy] : Back[jx][jy]); - int tube_leave_directions[][2] = - { - { EL_TUBE_ANY, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN }, - { EL_TUBE_VERTICAL, MV_UP | MV_DOWN }, - { EL_TUBE_HORIZONTAL, MV_LEFT | MV_RIGHT }, - { EL_TUBE_VERTICAL_LEFT, MV_LEFT | MV_UP | MV_DOWN }, - { EL_TUBE_VERTICAL_RIGHT, MV_RIGHT | MV_UP | MV_DOWN }, - { EL_TUBE_HORIZONTAL_UP, MV_LEFT | MV_RIGHT | MV_UP }, - { EL_TUBE_HORIZONTAL_DOWN, MV_LEFT | MV_RIGHT | MV_DOWN }, - { EL_TUBE_LEFT_UP, MV_LEFT | MV_UP }, - { EL_TUBE_LEFT_DOWN, MV_LEFT | MV_DOWN }, - { EL_TUBE_RIGHT_UP, MV_RIGHT | MV_UP }, - { EL_TUBE_RIGHT_DOWN, MV_RIGHT | MV_DOWN }, - { -1, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN } - }; - - while (tube_leave_directions[i][0] != tube_element) - { - i++; - if (tube_leave_directions[i][0] == -1) /* should not happen */ - break; - } - - if (!(tube_leave_directions[i][1] & move_direction)) - return MF_NO_ACTION; /* tube has no opening in this direction */ - } - -#else - if (IS_TUBE(Back[jx][jy]) && game.engine_version >= VERSION_IDENT(2,2,0,0)) old_element = Back[jx][jy]; -#endif + /* in case of element dropped at player position, check background */ + else if (Back[jx][jy] != EL_EMPTY && + game.engine_version >= VERSION_IDENT(2,2,0,0)) + old_element = Back[jx][jy]; if (IS_WALKABLE(old_element) && !ACCESS_FROM(old_element, move_direction)) return MF_NO_ACTION; /* field has no opening in this direction */ @@ -11470,808 +10277,583 @@ int DigField(struct PlayerInfo *player, return MF_NO_ACTION; /* field has no opening in this direction */ element = Feld[x][y]; +#if USE_NEW_CUSTOM_VALUE + +#if 1 + collect_count = element_info[element].collect_count_initial; +#else + collect_count = CustomValue[x][y]; +#endif + +#else + collect_count = element_info[element].collect_count_initial; +#endif + +#if 0 + if (element != EL_BLOCKED && + CustomValue[x][y] != element_info[element].collect_count_initial) + printf("::: %d: %d != %d\n", + element, + CustomValue[x][y], + element_info[element].collect_count_initial); +#endif if (!is_player && !IS_COLLECTIBLE(element)) /* penguin cannot collect it */ return MF_NO_ACTION; if (mode == DF_SNAP && !IS_SNAPPABLE(element) && game.engine_version >= VERSION_IDENT(2,2,0,0)) + { + CheckElementChangeByPlayer(x, y, element, CE_SNAPPED_BY_PLAYER, + player->index_bit, dig_side); + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_SNAPS_X, + player->index_bit, dig_side); + + if (Feld[x][y] != element) /* field changed by snapping */ + return MF_ACTION; + return MF_NO_ACTION; + } -#if 1 if (game.gravity && is_player && !player->is_auto_moving && canFallDown(player) && move_direction != MV_DOWN && !canMoveToValidFieldWithGravity(jx, jy, move_direction)) return MF_NO_ACTION; /* player cannot walk here due to gravity */ -#endif -#if 0 - if (element == EL_EMPTY_SPACE && - game.gravity && !player->is_auto_moving && - canFallDown(player) && move_direction != MV_DOWN) - return MF_NO_ACTION; /* player cannot walk here due to gravity */ -#endif - - switch (element) + if (player_can_enter && + IS_WALKABLE(element) && ACCESS_FROM(element, opposite_direction)) { -#if 0 - case EL_SP_PORT_LEFT: - case EL_SP_PORT_RIGHT: - case EL_SP_PORT_UP: - case EL_SP_PORT_DOWN: - case EL_SP_PORT_HORIZONTAL: - case EL_SP_PORT_VERTICAL: - case EL_SP_PORT_ANY: - case EL_SP_GRAVITY_PORT_LEFT: - case EL_SP_GRAVITY_PORT_RIGHT: - case EL_SP_GRAVITY_PORT_UP: - case EL_SP_GRAVITY_PORT_DOWN: -#if 1 - if (!canEnterSupaplexPort(x, y, dx, dy)) + int sound_element = SND_ELEMENT(element); + int sound_action = ACTION_WALKING; + + if (IS_RND_GATE(element)) + { + if (!player->key[RND_GATE_NR(element)]) return MF_NO_ACTION; -#else - if ((dx == -1 && - element != EL_SP_PORT_LEFT && - element != EL_SP_GRAVITY_PORT_LEFT && - element != EL_SP_PORT_HORIZONTAL && - element != EL_SP_PORT_ANY) || - (dx == +1 && - element != EL_SP_PORT_RIGHT && - element != EL_SP_GRAVITY_PORT_RIGHT && - element != EL_SP_PORT_HORIZONTAL && - element != EL_SP_PORT_ANY) || - (dy == -1 && - element != EL_SP_PORT_UP && - element != EL_SP_GRAVITY_PORT_UP && - element != EL_SP_PORT_VERTICAL && - element != EL_SP_PORT_ANY) || - (dy == +1 && - element != EL_SP_PORT_DOWN && - element != EL_SP_GRAVITY_PORT_DOWN && - element != EL_SP_PORT_VERTICAL && - element != EL_SP_PORT_ANY) || - !IN_LEV_FIELD(nextx, nexty) || - !IS_FREE(nextx, nexty)) + } + else if (IS_RND_GATE_GRAY(element)) + { + if (!player->key[RND_GATE_GRAY_NR(element)]) return MF_NO_ACTION; -#endif + } + else if (IS_RND_GATE_GRAY_ACTIVE(element)) + { + if (!player->key[RND_GATE_GRAY_ACTIVE_NR(element)]) + return MF_NO_ACTION; + } + else if (element == EL_EXIT_OPEN || + element == EL_SP_EXIT_OPEN || + element == EL_SP_EXIT_OPENING) + { + sound_action = ACTION_PASSING; /* player is passing exit */ + } + else if (element == EL_EMPTY) + { + sound_action = ACTION_MOVING; /* nothing to walk on */ + } + + /* play sound from background or player, whatever is available */ + if (element_info[sound_element].sound[sound_action] != SND_UNDEFINED) + PlayLevelSoundElementAction(x, y, sound_element, sound_action); + else + PlayLevelSoundElementAction(x, y, player->artwork_element, sound_action); + } + else if (player_can_enter && + IS_PASSABLE(element) && canPassField(x, y, move_direction)) + { + if (!ACCESS_FROM(element, opposite_direction)) + return MF_NO_ACTION; /* field not accessible from this direction */ + + if (CAN_MOVE(element)) /* only fixed elements can be passed! */ + return MF_NO_ACTION; + if (IS_EM_GATE(element)) + { + if (!player->key[EM_GATE_NR(element)]) + return MF_NO_ACTION; + } + else if (IS_EM_GATE_GRAY(element)) + { + if (!player->key[EM_GATE_GRAY_NR(element)]) + return MF_NO_ACTION; + } + else if (IS_EM_GATE_GRAY_ACTIVE(element)) + { + if (!player->key[EM_GATE_GRAY_ACTIVE_NR(element)]) + return MF_NO_ACTION; + } + else if (IS_SP_PORT(element)) + { if (element == EL_SP_GRAVITY_PORT_LEFT || element == EL_SP_GRAVITY_PORT_RIGHT || element == EL_SP_GRAVITY_PORT_UP || element == EL_SP_GRAVITY_PORT_DOWN) game.gravity = !game.gravity; + else if (element == EL_SP_GRAVITY_ON_PORT_LEFT || + element == EL_SP_GRAVITY_ON_PORT_RIGHT || + element == EL_SP_GRAVITY_ON_PORT_UP || + element == EL_SP_GRAVITY_ON_PORT_DOWN) + game.gravity = TRUE; + else if (element == EL_SP_GRAVITY_OFF_PORT_LEFT || + element == EL_SP_GRAVITY_OFF_PORT_RIGHT || + element == EL_SP_GRAVITY_OFF_PORT_UP || + element == EL_SP_GRAVITY_OFF_PORT_DOWN) + game.gravity = FALSE; + } - /* automatically move to the next field with double speed */ - player->programmed_action = move_direction; -#if 1 - if (player->move_delay_reset_counter == 0) - { - player->move_delay_reset_counter = 2; /* two double speed steps */ + /* automatically move to the next field with double speed */ + player->programmed_action = move_direction; - DOUBLE_PLAYER_SPEED(player); - } -#else - player->move_delay_reset_counter = 2; + if (player->move_delay_reset_counter == 0) + { + player->move_delay_reset_counter = 2; /* two double speed steps */ DOUBLE_PLAYER_SPEED(player); -#endif - -#if 0 - printf("::: passing port %d,%d [%d]\n", x, y, FrameCounter); -#endif - - PlayLevelSound(x, y, SND_CLASS_SP_PORT_PASSING); - break; -#endif - -#if 0 - case EL_TUBE_ANY: - case EL_TUBE_VERTICAL: - case EL_TUBE_HORIZONTAL: - case EL_TUBE_VERTICAL_LEFT: - case EL_TUBE_VERTICAL_RIGHT: - case EL_TUBE_HORIZONTAL_UP: - case EL_TUBE_HORIZONTAL_DOWN: - case EL_TUBE_LEFT_UP: - case EL_TUBE_LEFT_DOWN: - case EL_TUBE_RIGHT_UP: - case EL_TUBE_RIGHT_DOWN: - { - int i = 0; - int tube_enter_directions[][2] = - { - { EL_TUBE_ANY, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN }, - { EL_TUBE_VERTICAL, MV_UP | MV_DOWN }, - { EL_TUBE_HORIZONTAL, MV_LEFT | MV_RIGHT }, - { EL_TUBE_VERTICAL_LEFT, MV_RIGHT | MV_UP | MV_DOWN }, - { EL_TUBE_VERTICAL_RIGHT, MV_LEFT | MV_UP | MV_DOWN }, - { EL_TUBE_HORIZONTAL_UP, MV_LEFT | MV_RIGHT | MV_DOWN }, - { EL_TUBE_HORIZONTAL_DOWN, MV_LEFT | MV_RIGHT | MV_UP }, - { EL_TUBE_LEFT_UP, MV_RIGHT | MV_DOWN }, - { EL_TUBE_LEFT_DOWN, MV_RIGHT | MV_UP }, - { EL_TUBE_RIGHT_UP, MV_LEFT | MV_DOWN }, - { EL_TUBE_RIGHT_DOWN, MV_LEFT | MV_UP }, - { -1, MV_NO_MOVING } - }; - - while (tube_enter_directions[i][0] != element) - { - i++; - if (tube_enter_directions[i][0] == -1) /* should not happen */ - break; - } - - if (!(tube_enter_directions[i][1] & move_direction)) - return MF_NO_ACTION; /* tube has no opening in this direction */ - - PlayLevelSound(x, y, SND_CLASS_TUBE_WALKING); - } - break; -#endif - - default: - -#if 1 - if (IS_WALKABLE(element) && ACCESS_FROM(element, opposite_direction)) -#else - if (IS_WALKABLE(element)) -#endif - { - int sound_element = SND_ELEMENT(element); - int sound_action = ACTION_WALKING; - -#if 0 - if (!ACCESS_FROM(element, opposite_direction)) - return MF_NO_ACTION; /* field not accessible from this direction */ -#endif - -#if 0 - if (element == EL_EMPTY_SPACE && - game.gravity && !player->is_auto_moving && - canFallDown(player) && move_direction != MV_DOWN) - return MF_NO_ACTION; /* player cannot walk here due to gravity */ -#endif - - if (IS_RND_GATE(element)) - { - if (!player->key[RND_GATE_NR(element)]) - return MF_NO_ACTION; - } - else if (IS_RND_GATE_GRAY(element)) - { - if (!player->key[RND_GATE_GRAY_NR(element)]) - return MF_NO_ACTION; - } - else if (element == EL_EXIT_OPEN || - element == EL_SP_EXIT_OPEN || - element == EL_SP_EXIT_OPENING) - { - sound_action = ACTION_PASSING; /* player is passing exit */ - } - else if (element == EL_EMPTY) - { - sound_action = ACTION_MOVING; /* nothing to walk on */ - } - - /* play sound from background or player, whatever is available */ - if (element_info[sound_element].sound[sound_action] != SND_UNDEFINED) - PlayLevelSoundElementAction(x, y, sound_element, sound_action); - else - PlayLevelSoundElementAction(x, y, player->element_nr, sound_action); - - break; - } -#if 1 - else if (IS_PASSABLE(element) && canPassField(x, y, move_direction)) -#else - else if (IS_PASSABLE(element)) -#endif - { -#if 0 - if (!canPassField(x, y, move_direction)) - return MF_NO_ACTION; -#else - -#if 0 -#if 1 - if (!IN_LEV_FIELD(nextx, nexty) || IS_PLAYER(nextx, nexty) || - !IS_WALKABLE_FROM(Feld[nextx][nexty], move_direction) || - (!level.can_pass_to_walkable && !IS_FREE(nextx, nexty))) - return MF_NO_ACTION; -#else - if (!IN_LEV_FIELD(nextx, nexty) || !IS_FREE(nextx, nexty)) - return MF_NO_ACTION; -#endif -#endif + } -#if 1 - if (!ACCESS_FROM(element, opposite_direction)) - return MF_NO_ACTION; /* field not accessible from this direction */ -#else - if (IS_CUSTOM_ELEMENT(element) && - !ACCESS_FROM(element, opposite_direction)) - return MF_NO_ACTION; /* field not accessible from this direction */ -#endif + PlayLevelSoundAction(x, y, ACTION_PASSING); + } + else if (player_can_enter && IS_DIGGABLE(element)) + { + RemoveField(x, y); -#if 1 - if (CAN_MOVE(element)) /* only fixed elements can be passed! */ - return MF_NO_ACTION; -#endif + if (mode != DF_SNAP) + { + GfxElement[x][y] = GFX_ELEMENT(element); + player->is_digging = TRUE; + } -#endif + PlayLevelSoundElementAction(x, y, element, ACTION_DIGGING); - if (IS_EM_GATE(element)) - { - if (!player->key[EM_GATE_NR(element)]) - return MF_NO_ACTION; - } - else if (IS_EM_GATE_GRAY(element)) - { - if (!player->key[EM_GATE_GRAY_NR(element)]) - return MF_NO_ACTION; - } - else if (IS_SP_PORT(element)) - { - if (element == EL_SP_GRAVITY_PORT_LEFT || - element == EL_SP_GRAVITY_PORT_RIGHT || - element == EL_SP_GRAVITY_PORT_UP || - element == EL_SP_GRAVITY_PORT_DOWN) - game.gravity = !game.gravity; - else if (element == EL_SP_GRAVITY_ON_PORT_LEFT || - element == EL_SP_GRAVITY_ON_PORT_RIGHT || - element == EL_SP_GRAVITY_ON_PORT_UP || - element == EL_SP_GRAVITY_ON_PORT_DOWN) - game.gravity = TRUE; - else if (element == EL_SP_GRAVITY_OFF_PORT_LEFT || - element == EL_SP_GRAVITY_OFF_PORT_RIGHT || - element == EL_SP_GRAVITY_OFF_PORT_UP || - element == EL_SP_GRAVITY_OFF_PORT_DOWN) - game.gravity = FALSE; - } - - /* automatically move to the next field with double speed */ - player->programmed_action = move_direction; -#if 1 - if (player->move_delay_reset_counter == 0) - { - player->move_delay_reset_counter = 2; /* two double speed steps */ + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_DIGS_X, + player->index_bit, dig_side); - DOUBLE_PLAYER_SPEED(player); - } + if (mode == DF_SNAP) + { +#if USE_NEW_SNAP_DELAY + if (level.block_snap_field) + setFieldForSnapping(x, y, element, move_direction); + else + TestIfElementTouchesCustomElement(x, y); /* for empty space */ #else - player->move_delay_reset_counter = 2; - - DOUBLE_PLAYER_SPEED(player); + TestIfElementTouchesCustomElement(x, y); /* for empty space */ #endif - PlayLevelSoundAction(x, y, ACTION_PASSING); + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_SNAPS_X, + player->index_bit, dig_side); + } + } + else if (player_can_enter && IS_COLLECTIBLE(element)) + { + RemoveField(x, y); - break; - } - else if (IS_DIGGABLE(element)) - { - RemoveField(x, y); + if (is_player && mode != DF_SNAP) + { + GfxElement[x][y] = element; + player->is_collecting = TRUE; + } - if (mode != DF_SNAP) - { -#if 1 - GfxElement[x][y] = GFX_ELEMENT(element); -#else - GfxElement[x][y] = - (GFX_CRUMBLED(element) ? EL_SAND : GFX_ELEMENT(element)); -#endif - player->is_digging = TRUE; - } + if (element == EL_SPEED_PILL) + { + player->move_delay_value = MOVE_DELAY_HIGH_SPEED; + } + else if (element == EL_EXTRA_TIME && level.time > 0) + { + TimeLeft += level.extra_time; + DrawGameValue_Time(TimeLeft); + } + else if (element == EL_SHIELD_NORMAL || element == EL_SHIELD_DEADLY) + { + player->shield_normal_time_left += level.shield_normal_time; + if (element == EL_SHIELD_DEADLY) + player->shield_deadly_time_left += level.shield_deadly_time; + } + else if (element == EL_DYNAMITE || element == EL_SP_DISK_RED) + { + if (player->inventory_size < MAX_INVENTORY_SIZE) + player->inventory_element[player->inventory_size++] = element; - PlayLevelSoundElementAction(x, y, element, ACTION_DIGGING); + DrawGameValue_Dynamite(local_player->inventory_size); + } + else if (element == EL_DYNABOMB_INCREASE_NUMBER) + { + player->dynabomb_count++; + player->dynabombs_left++; + } + else if (element == EL_DYNABOMB_INCREASE_SIZE) + { + player->dynabomb_size++; + } + else if (element == EL_DYNABOMB_INCREASE_POWER) + { + player->dynabomb_xl = TRUE; + } + else if (IS_KEY(element)) + { + player->key[KEY_NR(element)] = TRUE; - CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_DIGS_X, - player->index_bit, dig_side); + DrawGameValue_Keys(player->key); -#if 1 - if (mode == DF_SNAP) - TestIfElementTouchesCustomElement(x, y); /* for empty space */ -#endif + redraw_mask |= REDRAW_DOOR_1; + } + else if (IS_ENVELOPE(element)) + { + player->show_envelope = element; + } + else if (element == EL_EMC_LENSES) + { + game.lenses_time_left = level.lenses_time * FRAMES_PER_SECOND; - break; - } - else if (IS_COLLECTIBLE(element)) - { - RemoveField(x, y); + RedrawAllInvisibleElementsForLenses(); + } + else if (element == EL_EMC_MAGNIFIER) + { + game.magnify_time_left = level.magnify_time * FRAMES_PER_SECOND; - if (is_player && mode != DF_SNAP) - { - GfxElement[x][y] = element; - player->is_collecting = TRUE; - } + RedrawAllInvisibleElementsForMagnifier(); + } + else if (IS_DROPPABLE(element) || + IS_THROWABLE(element)) /* can be collected and dropped */ + { + int i; - if (element == EL_SPEED_PILL) - player->move_delay_value = MOVE_DELAY_HIGH_SPEED; - else if (element == EL_EXTRA_TIME && level.time > 0) - { - TimeLeft += 10; - DrawGameValue_Time(TimeLeft); - } - else if (element == EL_SHIELD_NORMAL || element == EL_SHIELD_DEADLY) - { - player->shield_normal_time_left += 10; - if (element == EL_SHIELD_DEADLY) - player->shield_deadly_time_left += 10; - } - else if (element == EL_DYNAMITE || element == EL_SP_DISK_RED) - { + if (collect_count == 0) + player->inventory_infinite_element = element; + else + for (i = 0; i < collect_count; i++) if (player->inventory_size < MAX_INVENTORY_SIZE) player->inventory_element[player->inventory_size++] = element; - DrawGameValue_Dynamite(local_player->inventory_size); - } - else if (element == EL_DYNABOMB_INCREASE_NUMBER) - { - player->dynabomb_count++; - player->dynabombs_left++; - } - else if (element == EL_DYNABOMB_INCREASE_SIZE) - { - player->dynabomb_size++; - } - else if (element == EL_DYNABOMB_INCREASE_POWER) - { - player->dynabomb_xl = TRUE; - } - else if (IS_KEY(element)) - { - player->key[KEY_NR(element)] = TRUE; - - DrawGameValue_Keys(player->key); - - redraw_mask |= REDRAW_DOOR_1; - } - else if (IS_ENVELOPE(element)) - { -#if 1 - player->show_envelope = element; -#else - ShowEnvelope(element - EL_ENVELOPE_1); -#endif - } - else if (IS_DROPPABLE(element) || - IS_THROWABLE(element)) /* can be collected and dropped */ - { - int i; - - if (element_info[element].collect_count == 0) - player->inventory_infinite_element = element; - else - for (i = 0; i < element_info[element].collect_count; i++) - if (player->inventory_size < MAX_INVENTORY_SIZE) - player->inventory_element[player->inventory_size++] = element; - - DrawGameValue_Dynamite(local_player->inventory_size); - } - else if (element_info[element].collect_count > 0) - { - local_player->gems_still_needed -= - element_info[element].collect_count; - if (local_player->gems_still_needed < 0) - local_player->gems_still_needed = 0; - - DrawGameValue_Emeralds(local_player->gems_still_needed); - } - - RaiseScoreElement(element); - PlayLevelSoundElementAction(x, y, element, ACTION_COLLECTING); - - if (is_player) - CheckTriggeredElementChangeByPlayer(x, y, element, - CE_PLAYER_COLLECTS_X, - player->index_bit, dig_side); - -#if 1 - if (mode == DF_SNAP) - TestIfElementTouchesCustomElement(x, y); /* for empty space */ -#endif - - break; - } - else if (IS_PUSHABLE(element)) - { - if (mode == DF_SNAP && element != EL_BD_ROCK) - return MF_NO_ACTION; + DrawGameValue_Dynamite(local_player->inventory_size); + } + else if (collect_count > 0) + { + local_player->gems_still_needed -= collect_count; + if (local_player->gems_still_needed < 0) + local_player->gems_still_needed = 0; - if (CAN_FALL(element) && dy) - return MF_NO_ACTION; + DrawGameValue_Emeralds(local_player->gems_still_needed); + } - if (CAN_FALL(element) && IN_LEV_FIELD(x, y + 1) && IS_FREE(x, y + 1) && - !(element == EL_SPRING && level.use_spring_bug)) - return MF_NO_ACTION; + RaiseScoreElement(element); + PlayLevelSoundElementAction(x, y, element, ACTION_COLLECTING); -#if 1 - if (CAN_MOVE(element) && GET_MAX_MOVE_DELAY(element) == 0 && - ((move_direction & MV_VERTICAL && - ((element_info[element].move_pattern & MV_LEFT && - IN_LEV_FIELD(x - 1, y) && IS_FREE(x - 1, y)) || - (element_info[element].move_pattern & MV_RIGHT && - IN_LEV_FIELD(x + 1, y) && IS_FREE(x + 1, y)))) || - (move_direction & MV_HORIZONTAL && - ((element_info[element].move_pattern & MV_UP && - IN_LEV_FIELD(x, y - 1) && IS_FREE(x, y - 1)) || - (element_info[element].move_pattern & MV_DOWN && - IN_LEV_FIELD(x, y + 1) && IS_FREE(x, y + 1)))))) - return MF_NO_ACTION; -#endif + if (is_player) + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_COLLECTS_X, + player->index_bit, dig_side); -#if 1 - /* do not push elements already moving away faster than player */ - if (CAN_MOVE(element) && MovDir[x][y] == move_direction && - ABS(getElementMoveStepsize(x, y)) > MOVE_STEPSIZE_NORMAL) - return MF_NO_ACTION; + if (mode == DF_SNAP) + { +#if USE_NEW_SNAP_DELAY + if (level.block_snap_field) + setFieldForSnapping(x, y, element, move_direction); + else + TestIfElementTouchesCustomElement(x, y); /* for empty space */ #else - if (element == EL_SPRING && MovDir[x][y] != MV_NO_MOVING) - return MF_NO_ACTION; + TestIfElementTouchesCustomElement(x, y); /* for empty space */ #endif -#if 1 + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_SNAPS_X, + player->index_bit, dig_side); + } + } + else if (player_can_enter && IS_PUSHABLE(element)) + { + if (mode == DF_SNAP && element != EL_BD_ROCK) + return MF_NO_ACTION; -#if 1 - if (game.engine_version >= VERSION_IDENT(3,1,0,0)) - { - if (player->push_delay_value == -1 || !player_was_pushing) - player->push_delay_value = GET_NEW_PUSH_DELAY(element); - } - else if (game.engine_version >= VERSION_IDENT(3,0,7,1)) - { - if (player->push_delay_value == -1) - player->push_delay_value = GET_NEW_PUSH_DELAY(element); - } -#else - if (game.engine_version >= VERSION_IDENT(3,0,7,1)) - { - if (player->push_delay_value == -1 || !player_was_pushing) - player->push_delay_value = GET_NEW_PUSH_DELAY(element); - } -#endif - else if (game.engine_version >= VERSION_IDENT(2,2,0,7)) - { - if (!player->is_pushing) - player->push_delay_value = GET_NEW_PUSH_DELAY(element); - } + if (CAN_FALL(element) && dy) + return MF_NO_ACTION; - /* - if (game.engine_version >= VERSION_IDENT(2,2,0,7) && - (game.engine_version < VERSION_IDENT(3,0,7,1) || - !player_is_pushing)) - player->push_delay_value = GET_NEW_PUSH_DELAY(element); - */ -#else - if (!player->is_pushing && - game.engine_version >= VERSION_IDENT(2,2,0,7)) - player->push_delay_value = GET_NEW_PUSH_DELAY(element); -#endif + if (CAN_FALL(element) && IN_LEV_FIELD(x, y + 1) && IS_FREE(x, y + 1) && + !(element == EL_SPRING && level.use_spring_bug)) + return MF_NO_ACTION; -#if 0 - printf("::: push delay: %ld -> %ld [%d, %d] [%d / %d] [%d '%s': %d]\n", - player->push_delay, player->push_delay_value, - FrameCounter, game.engine_version, - player_was_pushing, player->is_pushing, - element, element_info[element].token_name, - GET_NEW_PUSH_DELAY(element)); -#endif + if (CAN_MOVE(element) && GET_MAX_MOVE_DELAY(element) == 0 && + ((move_direction & MV_VERTICAL && + ((element_info[element].move_pattern & MV_LEFT && + IN_LEV_FIELD(x - 1, y) && IS_FREE(x - 1, y)) || + (element_info[element].move_pattern & MV_RIGHT && + IN_LEV_FIELD(x + 1, y) && IS_FREE(x + 1, y)))) || + (move_direction & MV_HORIZONTAL && + ((element_info[element].move_pattern & MV_UP && + IN_LEV_FIELD(x, y - 1) && IS_FREE(x, y - 1)) || + (element_info[element].move_pattern & MV_DOWN && + IN_LEV_FIELD(x, y + 1) && IS_FREE(x, y + 1)))))) + return MF_NO_ACTION; - player->is_pushing = TRUE; + /* do not push elements already moving away faster than player */ + if (CAN_MOVE(element) && MovDir[x][y] == move_direction && + ABS(getElementMoveStepsize(x, y)) > MOVE_STEPSIZE_NORMAL) + return MF_NO_ACTION; - if (!(IN_LEV_FIELD(nextx, nexty) && - (IS_FREE(nextx, nexty) || - (Feld[nextx][nexty] == EL_SOKOBAN_FIELD_EMPTY && - IS_SB_ELEMENT(element))))) - return MF_NO_ACTION; + if (game.engine_version >= VERSION_IDENT(3,1,0,0)) + { + if (player->push_delay_value == -1 || !player_was_pushing) + player->push_delay_value = GET_NEW_PUSH_DELAY(element); + } + else if (game.engine_version >= VERSION_IDENT(3,0,7,1)) + { + if (player->push_delay_value == -1) + player->push_delay_value = GET_NEW_PUSH_DELAY(element); + } + else if (game.engine_version >= VERSION_IDENT(2,2,0,7)) + { + if (!player->is_pushing) + player->push_delay_value = GET_NEW_PUSH_DELAY(element); + } - if (!checkDiagonalPushing(player, x, y, real_dx, real_dy)) - return MF_NO_ACTION; + player->is_pushing = TRUE; -#if USE_NEW_PUSH_DELAY + if (!(IN_LEV_FIELD(nextx, nexty) && + (IS_FREE(nextx, nexty) || + (Feld[nextx][nexty] == EL_SOKOBAN_FIELD_EMPTY && + IS_SB_ELEMENT(element))))) + return MF_NO_ACTION; -#if 0 - if ( (player->push_delay == -1) != (player->push_delay2 == 0) ) - printf("::: ALERT: %d, %d [%d / %d]\n", - player->push_delay, player->push_delay2, - FrameCounter, FrameCounter / 50); -#endif + if (!checkDiagonalPushing(player, x, y, real_dx, real_dy)) + return MF_NO_ACTION; - if (player->push_delay == -1) /* new pushing; restart delay */ - player->push_delay = 0; -#else - if (player->push_delay == 0) /* new pushing; restart delay */ - player->push_delay = FrameCounter; -#endif + if (player->push_delay == -1) /* new pushing; restart delay */ + player->push_delay = 0; -#if USE_NEW_PUSH_DELAY -#if 0 - if ( (player->push_delay > 0) != (!xxx_fr) ) - printf("::: PUSH BUG! %d, (%d -> %d) %d [%d / %d]\n", - player->push_delay, - xxx_pdv2, player->push_delay2, player->push_delay_value, - FrameCounter, FrameCounter / 50); -#endif + if (player->push_delay < player->push_delay_value && + !(tape.playing && tape.file_version < FILE_VERSION_2_0) && + element != EL_SPRING && element != EL_BALLOON) + { + /* make sure that there is no move delay before next try to push */ + if (game.engine_version >= VERSION_IDENT(3,0,7,1)) + player->move_delay = 0; -#if 0 - if (player->push_delay > 0 && - !(tape.playing && tape.file_version < FILE_VERSION_2_0) && - element != EL_SPRING && element != EL_BALLOON) -#else - /* !!! */ - if (player->push_delay < player->push_delay_value && - !(tape.playing && tape.file_version < FILE_VERSION_2_0) && - element != EL_SPRING && element != EL_BALLOON) -#endif + return MF_NO_ACTION; + } -#else - if (!FrameReached(&player->push_delay, player->push_delay_value) && - !(tape.playing && tape.file_version < FILE_VERSION_2_0) && - element != EL_SPRING && element != EL_BALLOON) -#endif - { - /* make sure that there is no move delay before next try to push */ -#if USE_NEW_MOVE_DELAY - if (game.engine_version >= VERSION_IDENT(3,0,7,1)) - player->move_delay = 0; -#else - if (game.engine_version >= VERSION_IDENT(3,0,7,1)) - player->move_delay = INITIAL_MOVE_DELAY_OFF; -#endif + if (IS_SB_ELEMENT(element)) + { + if (element == EL_SOKOBAN_FIELD_FULL) + { + Back[x][y] = EL_SOKOBAN_FIELD_EMPTY; + local_player->sokobanfields_still_needed++; + } - return MF_NO_ACTION; - } + if (Feld[nextx][nexty] == EL_SOKOBAN_FIELD_EMPTY) + { + Back[nextx][nexty] = EL_SOKOBAN_FIELD_EMPTY; + local_player->sokobanfields_still_needed--; + } -#if 0 - printf("::: NOW PUSHING... [%d]\n", FrameCounter); -#endif + Feld[x][y] = EL_SOKOBAN_OBJECT; - if (IS_SB_ELEMENT(element)) - { - if (element == EL_SOKOBAN_FIELD_FULL) - { - Back[x][y] = EL_SOKOBAN_FIELD_EMPTY; - local_player->sokobanfields_still_needed++; - } + if (Back[x][y] == Back[nextx][nexty]) + PlayLevelSoundAction(x, y, ACTION_PUSHING); + else if (Back[x][y] != 0) + PlayLevelSoundElementAction(x, y, EL_SOKOBAN_FIELD_FULL, + ACTION_EMPTYING); + else + PlayLevelSoundElementAction(nextx, nexty, EL_SOKOBAN_FIELD_EMPTY, + ACTION_FILLING); - if (Feld[nextx][nexty] == EL_SOKOBAN_FIELD_EMPTY) - { - Back[nextx][nexty] = EL_SOKOBAN_FIELD_EMPTY; - local_player->sokobanfields_still_needed--; - } + if (local_player->sokobanfields_still_needed == 0 && + game.emulation == EMU_SOKOBAN) + { + player->LevelSolved = player->GameOver = TRUE; + PlayLevelSound(x, y, SND_GAME_SOKOBAN_SOLVING); + } + } + else + PlayLevelSoundElementAction(x, y, element, ACTION_PUSHING); - Feld[x][y] = EL_SOKOBAN_OBJECT; + InitMovingField(x, y, move_direction); + GfxAction[x][y] = ACTION_PUSHING; - if (Back[x][y] == Back[nextx][nexty]) - PlayLevelSoundAction(x, y, ACTION_PUSHING); - else if (Back[x][y] != 0) - PlayLevelSoundElementAction(x, y, EL_SOKOBAN_FIELD_FULL, - ACTION_EMPTYING); - else - PlayLevelSoundElementAction(nextx, nexty, EL_SOKOBAN_FIELD_EMPTY, - ACTION_FILLING); + if (mode == DF_SNAP) + ContinueMoving(x, y); + else + MovPos[x][y] = (dx != 0 ? dx : dy); - if (local_player->sokobanfields_still_needed == 0 && - game.emulation == EMU_SOKOBAN) - { - player->LevelSolved = player->GameOver = TRUE; - PlayLevelSound(x, y, SND_GAME_SOKOBAN_SOLVING); - } - } - else - PlayLevelSoundElementAction(x, y, element, ACTION_PUSHING); + Pushed[x][y] = TRUE; + Pushed[nextx][nexty] = TRUE; - InitMovingField(x, y, move_direction); - GfxAction[x][y] = ACTION_PUSHING; + if (game.engine_version < VERSION_IDENT(2,2,0,7)) + player->push_delay_value = GET_NEW_PUSH_DELAY(element); + else + player->push_delay_value = -1; /* get new value later */ - if (mode == DF_SNAP) - ContinueMoving(x, y); - else - MovPos[x][y] = (dx != 0 ? dx : dy); + /* check for element change _after_ element has been pushed */ + if (game.use_change_when_pushing_bug) + { + CheckElementChangeByPlayer(x, y, element, CE_PUSHED_BY_PLAYER, + player->index_bit, dig_side); + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PUSHES_X, + player->index_bit, dig_side); + } + } + else if (IS_SWITCHABLE(element)) + { + if (PLAYER_SWITCHING(player, x, y)) + { + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PRESSES_X, + player->index_bit, dig_side); - Pushed[x][y] = TRUE; - Pushed[nextx][nexty] = TRUE; + return MF_ACTION; + } - if (game.engine_version < VERSION_IDENT(2,2,0,7)) - player->push_delay_value = GET_NEW_PUSH_DELAY(element); - else - player->push_delay_value = -1; /* get new value later */ + player->is_switching = TRUE; + player->switch_x = x; + player->switch_y = y; -#if USE_PUSH_BUGFIX - /* now: check for element change _after_ element has been pushed! */ -#if 1 - if (game.use_change_when_pushing_bug) -#else - if (game.engine_version < VERSION_IDENT(3,1,0,0)) -#endif - { - CheckElementChangeByPlayer(x, y, element, CE_PUSHED_BY_PLAYER, - player->index_bit, dig_side); - CheckTriggeredElementChangeByPlayer(x,y, element, CE_PLAYER_PUSHES_X, - player->index_bit, dig_side); - } + PlayLevelSoundElementAction(x, y, element, ACTION_ACTIVATING); -#else + if (element == EL_ROBOT_WHEEL) + { + Feld[x][y] = EL_ROBOT_WHEEL_ACTIVE; + ZX = x; + ZY = y; -#if 1 - /* check for element change _after_ element has been pushed! */ -#else + DrawLevelField(x, y); + } + else if (element == EL_SP_TERMINAL) + { + int xx, yy; #if 1 - /* !!! TEST ONLY !!! */ - CheckElementChangeByPlayer(x, y, element, CE_PUSHED_BY_PLAYER, - player->index_bit, dig_side); - CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PUSHES_X, - player->index_bit, dig_side); + SCAN_PLAYFIELD(xx, yy) #else - CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PUSHES_X, - player->index_bit, dig_side); - CheckElementChangeByPlayer(x, y, element, CE_PUSHED_BY_PLAYER, - player->index_bit, dig_side); -#endif -#endif - + for (yy = 0; yy < lev_fieldy; yy++) for (xx = 0; xx < lev_fieldx; xx++) #endif - - break; - } - else if (IS_SWITCHABLE(element)) { - if (PLAYER_SWITCHING(player, x, y)) - { - CheckTriggeredElementChangeByPlayer(x,y, element, - CE_PLAYER_PRESSES_X, - player->index_bit, dig_side); - - return MF_ACTION; - } - - player->is_switching = TRUE; - player->switch_x = x; - player->switch_y = y; + if (Feld[xx][yy] == EL_SP_DISK_YELLOW) + Bang(xx, yy); + else if (Feld[xx][yy] == EL_SP_TERMINAL) + Feld[xx][yy] = EL_SP_TERMINAL_ACTIVE; + } + } + else if (IS_BELT_SWITCH(element)) + { + ToggleBeltSwitch(x, y); + } + else if (element == EL_SWITCHGATE_SWITCH_UP || + element == EL_SWITCHGATE_SWITCH_DOWN) + { + ToggleSwitchgateSwitch(x, y); + } + else if (element == EL_LIGHT_SWITCH || + element == EL_LIGHT_SWITCH_ACTIVE) + { + ToggleLightSwitch(x, y); + } + else if (element == EL_TIMEGATE_SWITCH) + { + ActivateTimegateSwitch(x, y); + } + else if (element == EL_BALLOON_SWITCH_LEFT || + element == EL_BALLOON_SWITCH_RIGHT || + element == EL_BALLOON_SWITCH_UP || + element == EL_BALLOON_SWITCH_DOWN || + element == EL_BALLOON_SWITCH_NONE || + element == EL_BALLOON_SWITCH_ANY) + { + game.wind_direction = (element == EL_BALLOON_SWITCH_LEFT ? MV_LEFT : + element == EL_BALLOON_SWITCH_RIGHT ? MV_RIGHT : + element == EL_BALLOON_SWITCH_UP ? MV_UP : + element == EL_BALLOON_SWITCH_DOWN ? MV_DOWN : + element == EL_BALLOON_SWITCH_NONE ? MV_NONE : + move_direction); + } + else if (element == EL_LAMP) + { + Feld[x][y] = EL_LAMP_ACTIVE; + local_player->lights_still_needed--; - PlayLevelSoundElementAction(x, y, element, ACTION_ACTIVATING); + ResetGfxAnimation(x, y); + DrawLevelField(x, y); + } + else if (element == EL_TIME_ORB_FULL) + { + Feld[x][y] = EL_TIME_ORB_EMPTY; - if (element == EL_ROBOT_WHEEL) - { - Feld[x][y] = EL_ROBOT_WHEEL_ACTIVE; - ZX = x; - ZY = y; + if (level.time > 0 || level.use_time_orb_bug) + { + TimeLeft += level.time_orb_time; + DrawGameValue_Time(TimeLeft); + } - DrawLevelField(x, y); - } - else if (element == EL_SP_TERMINAL) - { - int xx, yy; + ResetGfxAnimation(x, y); + DrawLevelField(x, y); + } + else if (element == EL_EMC_MAGIC_BALL_SWITCH || + element == EL_EMC_MAGIC_BALL_SWITCH_ACTIVE) + { + int xx, yy; - for (yy = 0; yy < lev_fieldy; yy++) for (xx=0; xx < lev_fieldx; xx++) - { - if (Feld[xx][yy] == EL_SP_DISK_YELLOW) - Bang(xx, yy); - else if (Feld[xx][yy] == EL_SP_TERMINAL) - Feld[xx][yy] = EL_SP_TERMINAL_ACTIVE; - } - } - else if (IS_BELT_SWITCH(element)) - { - ToggleBeltSwitch(x, y); - } - else if (element == EL_SWITCHGATE_SWITCH_UP || - element == EL_SWITCHGATE_SWITCH_DOWN) - { - ToggleSwitchgateSwitch(x, y); - } - else if (element == EL_LIGHT_SWITCH || - element == EL_LIGHT_SWITCH_ACTIVE) - { - ToggleLightSwitch(x, y); + game.ball_state = !game.ball_state; -#if 0 - PlayLevelSound(x, y, element == EL_LIGHT_SWITCH ? - SND_LIGHT_SWITCH_ACTIVATING : - SND_LIGHT_SWITCH_DEACTIVATING); +#if 1 + SCAN_PLAYFIELD(xx, yy) +#else + for (yy = 0; yy < lev_fieldy; yy++) for (xx = 0; xx < lev_fieldx; xx++) #endif - } - else if (element == EL_TIMEGATE_SWITCH) - { - ActivateTimegateSwitch(x, y); - } - else if (element == EL_BALLOON_SWITCH_LEFT || - element == EL_BALLOON_SWITCH_RIGHT || - element == EL_BALLOON_SWITCH_UP || - element == EL_BALLOON_SWITCH_DOWN || - element == EL_BALLOON_SWITCH_ANY) + { + int e = Feld[xx][yy]; + + if (game.ball_state) { - if (element == EL_BALLOON_SWITCH_ANY) - game.balloon_dir = move_direction; - else - game.balloon_dir = (element == EL_BALLOON_SWITCH_LEFT ? MV_LEFT : - element == EL_BALLOON_SWITCH_RIGHT ? MV_RIGHT : - element == EL_BALLOON_SWITCH_UP ? MV_UP : - element == EL_BALLOON_SWITCH_DOWN ? MV_DOWN : - MV_NO_MOVING); + if (e == EL_EMC_MAGIC_BALL) + CreateField(xx, yy, EL_EMC_MAGIC_BALL_ACTIVE); + else if (e == EL_EMC_MAGIC_BALL_SWITCH) + CreateField(xx, yy, EL_EMC_MAGIC_BALL_SWITCH_ACTIVE); } - else if (element == EL_LAMP) + else { - Feld[x][y] = EL_LAMP_ACTIVE; - local_player->lights_still_needed--; - - ResetGfxAnimation(x, y); - DrawLevelField(x, y); + if (e == EL_EMC_MAGIC_BALL_ACTIVE) + CreateField(xx, yy, EL_EMC_MAGIC_BALL); + else if (e == EL_EMC_MAGIC_BALL_SWITCH_ACTIVE) + CreateField(xx, yy, EL_EMC_MAGIC_BALL_SWITCH); } - else if (element == EL_TIME_ORB_FULL) - { - Feld[x][y] = EL_TIME_ORB_EMPTY; - TimeLeft += 10; - DrawGameValue_Time(TimeLeft); + } + } - ResetGfxAnimation(x, y); - DrawLevelField(x, y); + CheckTriggeredElementChangeByPlayer(x, y, element, CE_SWITCH_OF_X, + player->index_bit, dig_side); -#if 0 - PlaySoundStereo(SND_TIME_ORB_FULL_COLLECTING, SOUND_MIDDLE); -#endif - } + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_SWITCHES_X, + player->index_bit, dig_side); - CheckTriggeredElementChangeByPlayer(x, y, element, - CE_SWITCH_OF_X, - player->index_bit, dig_side); + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PRESSES_X, + player->index_bit, dig_side); - CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PRESSES_X, - player->index_bit, dig_side); + return MF_ACTION; + } + else + { + if (!PLAYER_SWITCHING(player, x, y)) + { + player->is_switching = TRUE; + player->switch_x = x; + player->switch_y = y; - return MF_ACTION; - } - else - { - if (!PLAYER_SWITCHING(player, x, y)) - { - player->is_switching = TRUE; - player->switch_x = x; - player->switch_y = y; + CheckElementChangeByPlayer(x, y, element, CE_SWITCHED, + player->index_bit, dig_side); + CheckTriggeredElementChangeByPlayer(x, y, element, CE_SWITCH_OF_X, + player->index_bit, dig_side); -#if 1 - /* !!! TEST ONLY !!! */ - CheckElementChangeByPlayer(x, y, element, CE_SWITCHED, - player->index_bit, dig_side); - CheckTriggeredElementChangeByPlayer(x, y, element, - CE_SWITCH_OF_X, - player->index_bit, dig_side); -#else - CheckTriggeredElementChangeByPlayer(x, y, element, - CE_SWITCH_OF_X, - player->index_bit, dig_side); - CheckElementChangeByPlayer(x, y, element, CE_SWITCHED, - player->index_bit, dig_side); -#endif - } + CheckElementChangeByPlayer(x, y, element, CE_SWITCHED_BY_PLAYER, + player->index_bit, dig_side); + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_SWITCHES_X, + player->index_bit, dig_side); + } -#if 1 - /* !!! TEST ONLY !!! (this breaks "machine", level 000) */ - CheckElementChangeByPlayer(x, y, element, CE_PRESSED_BY_PLAYER, - player->index_bit, dig_side); - CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PRESSES_X, - player->index_bit, dig_side); -#else - CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PRESSES_X, - player->index_bit, dig_side); - CheckElementChangeByPlayer(x, y, element, CE_PRESSED_BY_PLAYER, - player->index_bit, dig_side); -#endif - } + CheckElementChangeByPlayer(x, y, element, CE_PRESSED_BY_PLAYER, + player->index_bit, dig_side); + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PRESSES_X, + player->index_bit, dig_side); - return MF_NO_ACTION; + return MF_NO_ACTION; } -#if USE_NEW_PUSH_DELAY player->push_delay = -1; -#else - player->push_delay = 0; -#endif -#if USE_PENGUIN_COLLECT_BUGFIX if (is_player) /* function can also be called by EL_PENGUIN */ -#endif { if (Feld[x][y] != element) /* really digged/collected something */ player->is_collecting = !player->is_digging; @@ -12284,18 +10866,13 @@ boolean SnapField(struct PlayerInfo *player, int dx, int dy) { int jx = player->jx, jy = player->jy; int x = jx + dx, y = jy + dy; - int snap_direction = (dx == -1 ? MV_LEFT : + int snap_direction = (dx == -1 ? MV_LEFT : dx == +1 ? MV_RIGHT : - dy == -1 ? MV_UP : - dy == +1 ? MV_DOWN : MV_NO_MOVING); + dy == -1 ? MV_UP : + dy == +1 ? MV_DOWN : MV_NONE); -#if 0 - if (player->MovPos != 0) - return FALSE; -#else if (player->MovPos != 0 && game.engine_version >= VERSION_IDENT(2,2,0,0)) return FALSE; -#endif if (!player->active || !IN_LEV_FIELD(x, y)) return FALSE; @@ -12325,9 +10902,7 @@ boolean SnapField(struct PlayerInfo *player, int dx, int dy) player->MovDir = snap_direction; -#if 1 if (player->MovPos == 0) -#endif { player->is_moving = FALSE; player->is_digging = FALSE; @@ -12341,26 +10916,18 @@ boolean SnapField(struct PlayerInfo *player, int dx, int dy) player->is_snapping = TRUE; -#if 1 if (player->MovPos == 0) -#endif { player->is_moving = FALSE; player->is_digging = FALSE; player->is_collecting = FALSE; } -#if 1 if (player->MovPos != 0) /* prevent graphic bugs in versions < 2.2.0 */ DrawLevelField(player->last_jx, player->last_jy); -#endif DrawLevelField(x, y); -#if 0 - BackToFront(); -#endif - return TRUE; } @@ -12369,18 +10936,7 @@ boolean DropElement(struct PlayerInfo *player) int old_element, new_element; int dropx = player->jx, dropy = player->jy; int drop_direction = player->MovDir; -#if 1 int drop_side = drop_direction; -#else - static int trigger_sides[4] = - { - CH_SIDE_LEFT, /* dropping left */ - CH_SIDE_RIGHT, /* dropping right */ - CH_SIDE_TOP, /* dropping up */ - CH_SIDE_BOTTOM, /* dropping down */ - }; - int drop_side = trigger_sides[MV_DIR_BIT(drop_direction)]; -#endif int drop_element = (player->inventory_size > 0 ? player->inventory_element[player->inventory_size - 1] : player->inventory_infinite_element != EL_UNDEFINED ? @@ -12389,14 +10945,12 @@ boolean DropElement(struct PlayerInfo *player) EL_DYNABOMB_PLAYER_1_ACTIVE + player->index_nr : EL_UNDEFINED); -#if USE_DROP_BUGFIX /* do not drop an element on top of another element; when holding drop key pressed without moving, dropped element must move away before the next element can be dropped (this is especially important if the next element is dynamite, which can be placed on background for historical reasons) */ if (PLAYER_DROPPING(player, dropx, dropy) && Feld[dropx][dropy] != EL_EMPTY) return MF_ACTION; -#endif if (IS_THROWABLE(drop_element)) { @@ -12415,30 +10969,16 @@ boolean DropElement(struct PlayerInfo *player) return FALSE; /* check if player has anything that can be dropped */ -#if 1 if (new_element == EL_UNDEFINED) return FALSE; -#else - if (player->inventory_size == 0 && - player->inventory_infinite_element == EL_UNDEFINED && - player->dynabombs_left == 0) - return FALSE; -#endif /* check if anything can be dropped at the current position */ if (IS_ACTIVE_BOMB(old_element) || old_element == EL_EXPLOSION) return FALSE; /* collected custom elements can only be dropped on empty fields */ -#if 1 if (IS_CUSTOM_ELEMENT(new_element) && old_element != EL_EMPTY) return FALSE; -#else - if (player->inventory_size > 0 && - IS_CUSTOM_ELEMENT(player->inventory_element[player->inventory_size - 1]) - && old_element != EL_EMPTY) - return FALSE; -#endif if (old_element != EL_EMPTY) Back[dropx][dropy] = old_element; /* store old element on this field */ @@ -12453,10 +10993,6 @@ boolean DropElement(struct PlayerInfo *player) { player->inventory_size--; -#if 0 - new_element = player->inventory_element[player->inventory_size]; -#endif - DrawGameValue_Dynamite(local_player->inventory_size); if (new_element == EL_DYNAMITE) @@ -12473,25 +11009,14 @@ boolean DropElement(struct PlayerInfo *player) PlayLevelSoundAction(dropx, dropy, ACTION_DROPPING); -#if 1 /* needed if previous element just changed to "empty" in the last frame */ - Changed[dropx][dropy] = FALSE; /* allow another change */ -#endif + ChangeCount[dropx][dropy] = 0; /* allow at least one more change */ -#if 1 - /* !!! TEST ONLY !!! */ CheckElementChangeByPlayer(dropx, dropy, new_element, CE_DROPPED_BY_PLAYER, player->index_bit, drop_side); CheckTriggeredElementChangeByPlayer(dropx, dropy, new_element, CE_PLAYER_DROPS_X, player->index_bit, drop_side); -#else - CheckTriggeredElementChangeByPlayer(dropx, dropy, new_element, - CE_PLAYER_DROPS_X, - player->index_bit, drop_side); - CheckElementChangeByPlayer(dropx, dropy, new_element, CE_DROPPED_BY_PLAYER, - player->index_bit, drop_side); -#endif TestIfElementTouchesCustomElement(dropx, dropy); } @@ -12499,10 +11024,6 @@ boolean DropElement(struct PlayerInfo *player) { player->dynabombs_left--; -#if 0 - new_element = EL_DYNABOMB_PLAYER_1_ACTIVE + player->index_nr; -#endif - Feld[dropx][dropy] = new_element; if (IN_SCR_FIELD(SCREENX(dropx), SCREENY(dropy))) @@ -12512,29 +11033,14 @@ boolean DropElement(struct PlayerInfo *player) PlayLevelSoundAction(dropx, dropy, ACTION_DROPPING); } - - -#if 1 - if (Feld[dropx][dropy] == new_element) /* uninitialized unless CE change */ - { -#if 1 InitField_WithBug1(dropx, dropy, FALSE); -#else - InitField(dropx, dropy, FALSE); - if (CAN_MOVE(Feld[dropx][dropy])) - InitMovDir(dropx, dropy); -#endif - } new_element = Feld[dropx][dropy]; /* element might have changed */ if (IS_CUSTOM_ELEMENT(new_element) && CAN_MOVE(new_element) && element_info[new_element].move_pattern == MV_WHEN_DROPPED) { -#if 0 - int move_stepsize = element_info[new_element].move_stepsize; -#endif int move_direction, nextx, nexty; if (element_info[new_element].move_direction_initial == MV_START_AUTOMATIC) @@ -12544,60 +11050,15 @@ boolean DropElement(struct PlayerInfo *player) nextx = dropx + GET_DX_FROM_DIR(move_direction); nexty = dropy + GET_DY_FROM_DIR(move_direction); -#if 1 - Changed[dropx][dropy] = FALSE; /* allow another change */ + ChangeCount[dropx][dropy] = 0; /* allow at least one more change */ CheckCollision[dropx][dropy] = 2; -#else - - if (IN_LEV_FIELD_AND_IS_FREE(nextx, nexty)) - { -#if 0 - WasJustMoving[dropx][dropy] = 3; -#else -#if 1 - InitMovingField(dropx, dropy, move_direction); - ContinueMoving(dropx, dropy); -#endif -#endif - } -#if 0 - /* !!! commented out from 3.1.0-4 to 3.1.0-5 !!! */ - else - { - Changed[dropx][dropy] = FALSE; /* allow another change */ - -#if 1 - TestIfElementHitsCustomElement(dropx, dropy, move_direction); -#else - CheckElementChangeBySide(dropx, dropy, new_element, touched_element, - CE_HITTING_SOMETHING, move_direction); -#endif - } -#endif - -#endif - -#if 0 - player->drop_delay = 2 * TILEX / move_stepsize + 1; -#endif } -#if 0 - player->drop_delay = 8 + 8 + 8; -#endif - -#if 1 player->drop_delay = GET_NEW_DROP_DELAY(drop_element); -#endif - -#endif - player->is_dropping = TRUE; -#if USE_DROP_BUGFIX player->drop_x = dropx; player->drop_y = dropy; -#endif return TRUE; } @@ -12724,11 +11185,6 @@ void PlayLevelSound_EM(int x, int y, int element_em, int sample) { int element = (element_em > -1 ? map_element_EM_to_RND(element_em) : 0); -#if 0 - if (sample == SAMPLE_bug) - printf("::: PlayLevelSound_EM: %d, %d: %d\n", x, y, sample); -#endif - switch (sample) { case SAMPLE_blank: @@ -12945,7 +11401,7 @@ void RaiseScoreElement(int element) RaiseScore(level.score[SC_SHIELD]); break; case EL_EXTRA_TIME: - RaiseScore(level.score[SC_TIME_BONUS]); + RaiseScore(level.extra_time_score); break; case EL_KEY_1: case EL_KEY_2: @@ -12987,19 +11443,13 @@ void RequestQuitGame(boolean ask_if_really_quit) } else { - -#if 1 if (tape.playing && tape.deactivate_display) TapeDeactivateDisplayOff(TRUE); -#endif OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK); -#if 1 if (tape.playing && tape.deactivate_display) TapeDeactivateDisplayOn(); -#endif - } } diff --git a/src/game.h b/src/game.h index 4bca9fd6..9d736792 100644 --- a/src/game.h +++ b/src/game.h @@ -68,16 +68,16 @@ void ScrollLevel(int, int); void TestIfGoodThingHitsBadThing(int, int, int); void TestIfBadThingHitsGoodThing(int, int, int); -void TestIfHeroTouchesBadThing(int, int); -void TestIfHeroRunsIntoBadThing(int, int, int); -void TestIfBadThingTouchesHero(int, int); -void TestIfBadThingRunsIntoHero(int, int, int); +void TestIfPlayerTouchesBadThing(int, int); +void TestIfPlayerRunsIntoBadThing(int, int, int); +void TestIfBadThingTouchesPlayer(int, int); +void TestIfBadThingRunsIntoPlayer(int, int, int); void TestIfFriendTouchesBadThing(int, int); void TestIfBadThingTouchesFriend(int, int); void TestIfBadThingTouchesOtherBadThing(int, int); -void KillHero(struct PlayerInfo *); -void BuryHero(struct PlayerInfo *); -void RemoveHero(struct PlayerInfo *); +void KillPlayer(struct PlayerInfo *); +void BuryPlayer(struct PlayerInfo *); +void RemovePlayer(struct PlayerInfo *); boolean SnapField(struct PlayerInfo *, int, int); boolean DropElement(struct PlayerInfo *); diff --git a/src/game_em/cave.c b/src/game_em/cave.c index 22ea317e..a811d03e 100644 --- a/src/game_em/cave.c +++ b/src/game_em/cave.c @@ -42,6 +42,8 @@ void setLevelInfoToDefaults_EM(void) lev.wonderwall_state_initial = 0; lev.wonderwall_time_initial = 0; + lev.num_ball_arrays = 8; + for (i = 0; i < TILE_MAX; i++) lev.android_array[i] = Xblank; diff --git a/src/game_em/convert.c b/src/game_em/convert.c index 6287eea2..3c714c6e 100644 --- a/src/game_em/convert.c +++ b/src/game_em/convert.c @@ -638,163 +638,173 @@ void convert_em_level(unsigned char *src, int file_version) if (temp & 1) { - lev.android_array[Xemerald] = - lev.android_array[Xemerald_pause] = - lev.android_array[Xemerald_fall] = - lev.android_array[Yemerald_sB] = - lev.android_array[Yemerald_eB] = - lev.android_array[Yemerald_wB] = Xemerald; + lev.android_array[Xemerald] = Xemerald; + lev.android_array[Xemerald_pause] = Xemerald; + lev.android_array[Xemerald_fall] = Xemerald; + lev.android_array[Yemerald_sB] = Xemerald; + lev.android_array[Yemerald_eB] = Xemerald; + lev.android_array[Yemerald_wB] = Xemerald; } if (temp & 2) { - lev.android_array[Xdiamond] = - lev.android_array[Xdiamond_pause] = - lev.android_array[Xdiamond_fall] = - lev.android_array[Ydiamond_sB] = - lev.android_array[Ydiamond_eB] = - lev.android_array[Ydiamond_wB] = Xdiamond; + lev.android_array[Xdiamond] = Xdiamond; + lev.android_array[Xdiamond_pause] = Xdiamond; + lev.android_array[Xdiamond_fall] = Xdiamond; + lev.android_array[Ydiamond_sB] = Xdiamond; + lev.android_array[Ydiamond_eB] = Xdiamond; + lev.android_array[Ydiamond_wB] = Xdiamond; } if (temp & 4) { - lev.android_array[Xstone] = - lev.android_array[Xstone_pause] = - lev.android_array[Xstone_fall] = - lev.android_array[Ystone_sB] = - lev.android_array[Ystone_eB] = - lev.android_array[Ystone_wB] = Xstone; + lev.android_array[Xstone] = Xstone; + lev.android_array[Xstone_pause] = Xstone; + lev.android_array[Xstone_fall] = Xstone; + lev.android_array[Ystone_sB] = Xstone; + lev.android_array[Ystone_eB] = Xstone; + lev.android_array[Ystone_wB] = Xstone; } if (temp & 8) { - lev.android_array[Xbomb] = - lev.android_array[Xbomb_pause] = - lev.android_array[Xbomb_fall] = - lev.android_array[Ybomb_sB] = - lev.android_array[Ybomb_eB] = - lev.android_array[Ybomb_wB] = Xbomb; + lev.android_array[Xbomb] = Xbomb; + lev.android_array[Xbomb_pause] = Xbomb; + lev.android_array[Xbomb_fall] = Xbomb; + lev.android_array[Ybomb_sB] = Xbomb; + lev.android_array[Ybomb_eB] = Xbomb; + lev.android_array[Ybomb_wB] = Xbomb; } if (temp & 16) { - lev.android_array[Xnut] = - lev.android_array[Xnut_pause] = - lev.android_array[Xnut_fall] = - lev.android_array[Ynut_sB] = - lev.android_array[Ynut_eB] = - lev.android_array[Ynut_wB] = Xnut; + lev.android_array[Xnut] = Xnut; + lev.android_array[Xnut_pause] = Xnut; + lev.android_array[Xnut_fall] = Xnut; + lev.android_array[Ynut_sB] = Xnut; + lev.android_array[Ynut_eB] = Xnut; + lev.android_array[Ynut_wB] = Xnut; } if (temp & 32) { - lev.android_array[Xtank_n] = - lev.android_array[Xtank_gon] = - lev.android_array[Ytank_nB] = - lev.android_array[Ytank_n_e] = - lev.android_array[Ytank_n_w] = Xtank_n; - - lev.android_array[Xtank_e] = - lev.android_array[Xtank_goe] = - lev.android_array[Ytank_eB] = - lev.android_array[Ytank_e_s] = - lev.android_array[Ytank_e_n] = Xtank_e; - - lev.android_array[Xtank_s] = - lev.android_array[Xtank_gos] = - lev.android_array[Ytank_sB] = - lev.android_array[Ytank_s_w] = - lev.android_array[Ytank_s_e] = Xtank_s; - - lev.android_array[Xtank_w] = - lev.android_array[Xtank_gow] = - lev.android_array[Ytank_wB] = - lev.android_array[Ytank_w_n] = - lev.android_array[Ytank_w_s] = Xtank_w; + lev.android_array[Xtank_n] = Xtank_n; + lev.android_array[Xtank_gon] = Xtank_n; + lev.android_array[Ytank_nB] = Xtank_n; + lev.android_array[Ytank_n_e] = Xtank_n; + lev.android_array[Ytank_n_w] = Xtank_n; + + lev.android_array[Xtank_e] = Xtank_e; + lev.android_array[Xtank_goe] = Xtank_e; + lev.android_array[Ytank_eB] = Xtank_e; + lev.android_array[Ytank_e_s] = Xtank_e; + lev.android_array[Ytank_e_n] = Xtank_e; + + lev.android_array[Xtank_s] = Xtank_s; + lev.android_array[Xtank_gos] = Xtank_s; + lev.android_array[Ytank_sB] = Xtank_s; + lev.android_array[Ytank_s_w] = Xtank_s; + lev.android_array[Ytank_s_e] = Xtank_s; + + lev.android_array[Xtank_w] = Xtank_w; + lev.android_array[Xtank_gow] = Xtank_w; + lev.android_array[Ytank_wB] = Xtank_w; + lev.android_array[Ytank_w_n] = Xtank_w; + lev.android_array[Ytank_w_s] = Xtank_w; } if (temp & 64) { - lev.android_array[Xeater_n] = lev.android_array[Yeater_nB] = Xeater_n; - lev.android_array[Xeater_e] = lev.android_array[Yeater_eB] = Xeater_e; - lev.android_array[Xeater_s] = lev.android_array[Yeater_sB] = Xeater_s; - lev.android_array[Xeater_w] = lev.android_array[Yeater_wB] = Xeater_w; + lev.android_array[Xeater_n] = Xeater_n; + lev.android_array[Yeater_nB] = Xeater_n; + + lev.android_array[Xeater_e] = Xeater_e; + lev.android_array[Yeater_eB] = Xeater_e; + + lev.android_array[Xeater_s] = Xeater_s; + lev.android_array[Yeater_sB] = Xeater_s; + + lev.android_array[Xeater_w] = Xeater_w; + lev.android_array[Yeater_wB] = Xeater_w; } if (temp & 128) { - lev.android_array[Xbug_n] = - lev.android_array[Xbug_gon] = - lev.android_array[Ybug_nB] = - lev.android_array[Ybug_n_e] = - lev.android_array[Ybug_n_w] = Xbug_gon; - - lev.android_array[Xbug_e] = - lev.android_array[Xbug_goe] = - lev.android_array[Ybug_eB] = - lev.android_array[Ybug_e_s] = - lev.android_array[Ybug_e_n] = Xbug_goe; - - lev.android_array[Xbug_s] = - lev.android_array[Xbug_gos] = - lev.android_array[Ybug_sB] = - lev.android_array[Ybug_s_w] = - lev.android_array[Ybug_s_e] = Xbug_gos; - - lev.android_array[Xbug_w] = - lev.android_array[Xbug_gow] = - lev.android_array[Ybug_wB] = - lev.android_array[Ybug_w_n] = - lev.android_array[Ybug_w_s] = Xbug_gow; + lev.android_array[Xbug_n] = Xbug_gon; + lev.android_array[Xbug_gon] = Xbug_gon; + lev.android_array[Ybug_nB] = Xbug_gon; + lev.android_array[Ybug_n_e] = Xbug_gon; + lev.android_array[Ybug_n_w] = Xbug_gon; + + lev.android_array[Xbug_e] = Xbug_goe; + lev.android_array[Xbug_goe] = Xbug_goe; + lev.android_array[Ybug_eB] = Xbug_goe; + lev.android_array[Ybug_e_s] = Xbug_goe; + lev.android_array[Ybug_e_n] = Xbug_goe; + + lev.android_array[Xbug_s] = Xbug_gos; + lev.android_array[Xbug_gos] = Xbug_gos; + lev.android_array[Ybug_sB] = Xbug_gos; + lev.android_array[Ybug_s_w] = Xbug_gos; + lev.android_array[Ybug_s_e] = Xbug_gos; + + lev.android_array[Xbug_w] = Xbug_gow; + lev.android_array[Xbug_gow] = Xbug_gow; + lev.android_array[Ybug_wB] = Xbug_gow; + lev.android_array[Ybug_w_n] = Xbug_gow; + lev.android_array[Ybug_w_s] = Xbug_gow; } if (temp & 256) { - lev.android_array[Xalien] = lev.android_array[Xalien_pause] = - lev.android_array[Yalien_nB] = lev.android_array[Yalien_eB] = - lev.android_array[Yalien_sB] = lev.android_array[Yalien_wB] = Xalien; + lev.android_array[Xalien] = Xalien; + lev.android_array[Xalien_pause] = Xalien; + lev.android_array[Yalien_nB] = Xalien; + lev.android_array[Yalien_eB] = Xalien; + lev.android_array[Yalien_sB] = Xalien; + lev.android_array[Yalien_wB] = Xalien; } if (temp & 512) { - lev.android_array[Xspring] = - lev.android_array[Xspring_pause] = - lev.android_array[Xspring_e] = - lev.android_array[Yspring_eB] = - lev.android_array[Yspring_kill_eB] = - lev.android_array[Xspring_w] = - lev.android_array[Yspring_wB] = - lev.android_array[Yspring_kill_wB] = - lev.android_array[Xspring_fall] = - lev.android_array[Yspring_sB] = Xspring; + lev.android_array[Xspring] = Xspring; + lev.android_array[Xspring_pause] = Xspring; + lev.android_array[Xspring_e] = Xspring; + lev.android_array[Yspring_eB] = Xspring; + lev.android_array[Yspring_kill_eB] = Xspring; + lev.android_array[Xspring_w] = Xspring; + lev.android_array[Yspring_wB] = Xspring; + lev.android_array[Yspring_kill_wB] = Xspring; + lev.android_array[Xspring_fall] = Xspring; + lev.android_array[Yspring_sB] = Xspring; } if (temp & 1024) { - lev.android_array[Yballoon_nB] = - lev.android_array[Yballoon_eB] = - lev.android_array[Yballoon_sB] = - lev.android_array[Yballoon_wB] = - lev.android_array[Xballoon] = Xballoon; + lev.android_array[Yballoon_nB] = Xballoon; + lev.android_array[Yballoon_eB] = Xballoon; + lev.android_array[Yballoon_sB] = Xballoon; + lev.android_array[Yballoon_wB] = Xballoon; + lev.android_array[Xballoon] = Xballoon; } if (temp & 2048) { - lev.android_array[Xdripper] = - lev.android_array[XdripperB] = - lev.android_array[Xamoeba_1] = - lev.android_array[Xamoeba_2] = - lev.android_array[Xamoeba_3] = - lev.android_array[Xamoeba_4] = - lev.android_array[Xamoeba_5] = - lev.android_array[Xamoeba_6] = - lev.android_array[Xamoeba_7] = - lev.android_array[Xamoeba_8] = Xdrip_eat; + lev.android_array[Xdripper] = Xdrip_eat; + lev.android_array[XdripperB] = Xdrip_eat; + lev.android_array[Xamoeba_1] = Xdrip_eat; + lev.android_array[Xamoeba_2] = Xdrip_eat; + lev.android_array[Xamoeba_3] = Xdrip_eat; + lev.android_array[Xamoeba_4] = Xdrip_eat; + lev.android_array[Xamoeba_5] = Xdrip_eat; + lev.android_array[Xamoeba_6] = Xdrip_eat; + lev.android_array[Xamoeba_7] = Xdrip_eat; + lev.android_array[Xamoeba_8] = Xdrip_eat; } if (temp & 4096) { - lev.android_array[Xdynamite] = Xdynamite; + lev.android_array[Xdynamite] = Xdynamite; } for (temp = 1; temp < 2047; temp++) @@ -929,8 +939,8 @@ void prepare_em_level(void) lev.wheel_x = lev.wheel_x_initial; lev.wheel_y = lev.wheel_y_initial; - lev.wind_cnt = lev.wind_cnt_initial; lev.wind_direction = lev.wind_direction_initial; + lev.wind_cnt = lev.wind_cnt_initial; lev.wonderwall_state = lev.wonderwall_state_initial; lev.wonderwall_time = lev.wonderwall_time_initial; @@ -947,7 +957,7 @@ void prepare_em_level(void) ply1.anim = 0; ply1.oldx = ply1.x = ply1.x_initial; ply1.oldy = ply1.y = ply1.y_initial; - ply1.last_move_dir = MV_NO_MOVING; + ply1.last_move_dir = MV_NONE; ply1.joy_n = ply1.joy_e = ply1.joy_s = ply1.joy_w = 0; ply1.joy_snap = ply1.joy_drop = 0; ply1.joy_stick = ply1.joy_spin = 0; @@ -960,7 +970,7 @@ void prepare_em_level(void) ply2.anim = 0; ply2.oldx = ply2.x = ply2.x_initial; ply2.oldy = ply2.y = ply2.y_initial; - ply2.last_move_dir = MV_NO_MOVING; + ply2.last_move_dir = MV_NONE; ply2.joy_n = ply2.joy_e = ply2.joy_s = ply2.joy_w = 0; ply2.joy_snap = ply1.joy_drop = 0; ply2.joy_stick = ply2.joy_spin = 0; diff --git a/src/game_em/main_em.h b/src/game_em/main_em.h index 17cb9f73..5da62d3b 100644 --- a/src/game_em/main_em.h +++ b/src/game_em/main_em.h @@ -593,6 +593,7 @@ struct LEVEL unsigned short eater_array[8][9]; /* eater data */ unsigned short ball_array[8][8]; /* ball data */ unsigned short android_array[TILE_MAX];/* android clone table */ + unsigned int num_ball_arrays; /* number of ball data arrays used */ }; struct PLAYER diff --git a/src/game_em/synchro_2.c b/src/game_em/synchro_2.c index 3dff9e62..119d86a5 100644 --- a/src/game_em/synchro_2.c +++ b/src/game_em/synchro_2.c @@ -4517,7 +4517,11 @@ void synchro_2(void) } } +#if 1 + lev.ball_pos = (lev.ball_pos + 1) % lev.num_ball_arrays; +#else lev.ball_pos = (lev.ball_pos + 1) & 7; +#endif goto loop; /* --------------------------------------------------------------------- */ diff --git a/src/init.c b/src/init.c index 1f580732..708ab4a6 100644 --- a/src/init.c +++ b/src/init.c @@ -77,180 +77,6 @@ static int copy_properties[][5] = } }; -static void InitTileClipmasks() -{ -#if 0 -#if defined(TARGET_X11) - XGCValues clip_gc_values; - unsigned long clip_gc_valuemask; - -#if defined(TARGET_X11_NATIVE) - -#if 0 - GC copy_clipmask_gc; - - static struct - { - int start; - int count; - } - tile_needs_clipping[] = - { - { GFX_SPIELER1_UP, 4 }, - { GFX_SPIELER1_DOWN, 4 }, - { GFX_SPIELER1_LEFT, 4 }, - { GFX_SPIELER1_RIGHT, 4 }, - { GFX_SPIELER1_PUSH_LEFT, 4 }, - { GFX_SPIELER1_PUSH_RIGHT, 4 }, - { GFX_SPIELER2_UP, 4 }, - { GFX_SPIELER2_DOWN, 4 }, - { GFX_SPIELER2_LEFT, 4 }, - { GFX_SPIELER2_RIGHT, 4 }, - { GFX_SPIELER2_PUSH_LEFT, 4 }, - { GFX_SPIELER2_PUSH_RIGHT, 4 }, - { GFX_SPIELER3_UP, 4 }, - { GFX_SPIELER3_DOWN, 4 }, - { GFX_SPIELER3_LEFT, 4 }, - { GFX_SPIELER3_RIGHT, 4 }, - { GFX_SPIELER3_PUSH_LEFT, 4 }, - { GFX_SPIELER3_PUSH_RIGHT, 4 }, - { GFX_SPIELER4_UP, 4 }, - { GFX_SPIELER4_DOWN, 4 }, - { GFX_SPIELER4_LEFT, 4 }, - { GFX_SPIELER4_RIGHT, 4 }, - { GFX_SPIELER4_PUSH_LEFT, 4 }, - { GFX_SPIELER4_PUSH_RIGHT, 4 }, - { GFX_SP_MURPHY, 1 }, - { GFX_MURPHY_GO_LEFT, 3 }, - { GFX_MURPHY_GO_RIGHT, 3 }, - { GFX_MURPHY_SNAP_UP, 1 }, - { GFX_MURPHY_SNAP_DOWN, 1 }, - { GFX_MURPHY_SNAP_RIGHT, 1 }, - { GFX_MURPHY_SNAP_LEFT, 1 }, - { GFX_MURPHY_PUSH_RIGHT, 1 }, - { GFX_MURPHY_PUSH_LEFT, 1 }, - { GFX_GEBLUBBER, 4 }, - { GFX_DYNAMIT, 7 }, - { GFX_DYNABOMB, 4 }, - { GFX_EXPLOSION, 8 }, - { GFX_SOKOBAN_OBJEKT, 1 }, - { GFX_FUNKELN_BLAU, 3 }, - { GFX_FUNKELN_WEISS, 3 }, - { GFX2_SHIELD_PASSIVE, 3 }, - { GFX2_SHIELD_ACTIVE, 3 }, - { -1, 0 } - }; -#endif - -#endif /* TARGET_X11_NATIVE */ -#endif /* TARGET_X11 */ - - int i; - - /* initialize pixmap array for special X11 tile clipping to Pixmap 'None' */ - for (i = 0; i < NUM_TILES; i++) - tile_clipmask[i] = None; - -#if defined(TARGET_X11) - /* This stuff is needed because X11 (XSetClipOrigin(), to be precise) is - often very slow when preparing a masked XCopyArea() for big Pixmaps. - To prevent this, create small (tile-sized) mask Pixmaps which will then - be set much faster with XSetClipOrigin() and speed things up a lot. */ - - clip_gc_values.graphics_exposures = False; - clip_gc_valuemask = GCGraphicsExposures; - tile_clip_gc = XCreateGC(display, window->drawable, - clip_gc_valuemask, &clip_gc_values); - -#if 0 - for (i = 0; i < NUM_BITMAPS; i++) - { - if (pix[i]->clip_mask) - { - clip_gc_values.graphics_exposures = False; - clip_gc_values.clip_mask = pix[i]->clip_mask; - clip_gc_valuemask = GCGraphicsExposures | GCClipMask; - pix[i]->stored_clip_gc = XCreateGC(display, window->drawable, - clip_gc_valuemask, &clip_gc_values); - } - } -#endif - -#if defined(TARGET_X11_NATIVE) - -#if 0 - /* create graphic context structures needed for clipping */ - clip_gc_values.graphics_exposures = False; - clip_gc_valuemask = GCGraphicsExposures; - copy_clipmask_gc = XCreateGC(display, pix[PIX_BACK]->clip_mask, - clip_gc_valuemask, &clip_gc_values); - - /* create only those clipping Pixmaps we really need */ - for (i = 0; tile_needs_clipping[i].start >= 0; i++) - { - int j; - - for (j = 0; j < tile_needs_clipping[i].count; j++) - { - int tile = tile_needs_clipping[i].start + j; - int graphic = tile; - int src_x, src_y; - Bitmap *src_bitmap; - Pixmap src_pixmap; - - getGraphicSource(graphic, &src_bitmap, &src_x, &src_y); - src_pixmap = src_bitmap->clip_mask; - - tile_clipmask[tile] = XCreatePixmap(display, window->drawable, - TILEX, TILEY, 1); - - XCopyArea(display, src_pixmap, tile_clipmask[tile], copy_clipmask_gc, - src_x, src_y, TILEX, TILEY, 0, 0); - } - } - - XFreeGC(display, copy_clipmask_gc); -#endif - -#endif /* TARGET_X11_NATIVE */ -#endif /* TARGET_X11 */ -#endif -} - -void FreeTileClipmasks() -{ -#if 0 -#if defined(TARGET_X11) - int i; - - for (i = 0; i < NUM_TILES; i++) - { - if (tile_clipmask[i] != None) - { - XFreePixmap(display, tile_clipmask[i]); - tile_clipmask[i] = None; - } - } - - if (tile_clip_gc) - XFreeGC(display, tile_clip_gc); - tile_clip_gc = None; - -#if 0 - for (i = 0; i < NUM_BITMAPS; i++) - { - if (pix[i] != NULL && pix[i]->stored_clip_gc) - { - XFreeGC(display, pix[i]->stored_clip_gc); - pix[i]->stored_clip_gc = None; - } - } -#endif - -#endif /* TARGET_X11 */ -#endif -} - void FreeGadgets() { FreeLevelEditorGadgets(); @@ -283,6 +109,14 @@ inline void InitElementSmallImagesScaledUp(int graphic) void InitElementSmallImages() { + static int special_graphics[] = + { + IMG_EDITOR_ELEMENT_BORDER, + IMG_EDITOR_ELEMENT_BORDER_INPUT, + IMG_EDITOR_CASCADE_LIST, + IMG_EDITOR_CASCADE_LIST_ACTIVE, + -1 + }; struct PropertyMapping *property_mapping = getImageListPropertyMapping(); int num_property_mappings = getImageListPropertyMappingSize(); int i; @@ -296,22 +130,12 @@ void InitElementSmallImages() InitElementSmallImagesScaledUp(element_to_special_graphic[i].graphic); /* initialize images from dynamic configuration (may be elements or other) */ -#if 1 for (i = 0; i < num_property_mappings; i++) InitElementSmallImagesScaledUp(property_mapping[i].artwork_index); -#else - /* !!! THIS DOES NOT WORK -- "artwork_index" is graphic, not element !!! */ - /* !!! ALSO, non-element graphics might need scaling-up !!! */ - for (i = 0; i < num_property_mappings; i++) - if (property_mapping[i].artwork_index < MAX_NUM_ELEMENTS) - InitElementSmallImagesScaledUp(property_mapping[i].artwork_index); -#endif -#if 0 - /* !!! FIX THIS (CHANGE TO USING NORMAL ELEMENT GRAPHIC DEFINITIONS) !!! */ - for (i = IMG_EMC_OBJECT; i <= IMG_EMC_SPRITE; i++) - InitElementSmallImagesScaledUp(i); -#endif + /* initialize special images from above list (non-element images) */ + for (i = 0; special_graphics[i] > -1; i++) + InitElementSmallImagesScaledUp(special_graphics[i]); } #if 1 @@ -358,13 +182,8 @@ void InitFontGraphicInfo() /* ---------- initialize font graphic definitions ---------- */ /* always start with reliable default values (normal font graphics) */ -#if 1 for (i = 0; i < NUM_FONTS; i++) font_info[i].graphic = IMG_FONT_INITIAL_1; -#else - for (i = 0; i < NUM_FONTS; i++) - font_info[i].graphic = FONT_INITIAL_1; -#endif /* initialize normal font/graphic mapping from static configuration */ for (i = 0; font_to_graphic[i].font_nr > -1; i++) @@ -392,12 +211,25 @@ void InitFontGraphicInfo() /* initialize special font/graphic mapping from static configuration */ for (i = 0; font_to_graphic[i].font_nr > -1; i++) { - int font_nr = font_to_graphic[i].font_nr; - int special = font_to_graphic[i].special; - int graphic = font_to_graphic[i].graphic; + int font_nr = font_to_graphic[i].font_nr; + int special = font_to_graphic[i].special; + int graphic = font_to_graphic[i].graphic; + int base_graphic = font2baseimg(font_nr); if (special >= 0 && special < NUM_SPECIAL_GFX_ARGS) { + boolean base_redefined = + getImageListEntryFromImageID(base_graphic)->redefined; + boolean special_redefined = + getImageListEntryFromImageID(graphic)->redefined; + + /* if the base font ("font.title_1", for example) has been redefined, + but not the special font ("font.title_1.LEVELS", for example), do not + use an existing (in this case considered obsolete) special font + anymore, but use the automatically determined default font */ + if (base_redefined && !special_redefined) + continue; + font_info[font_nr].special_graphic[special] = graphic; font_info[font_nr].special_bitmap_id[special] = num_font_bitmaps; num_font_bitmaps++; @@ -632,6 +464,16 @@ void InitElementGraphicInfo() #endif #if 1 + /* set hardcoded definitions for some internal elements without graphic */ + for (i = 0; i < MAX_NUM_ELEMENTS; i++) + { + if (IS_EDITOR_CASCADE_INACTIVE(i)) + element_info[i].graphic[ACTION_DEFAULT] = IMG_EDITOR_CASCADE_LIST; + else if (IS_EDITOR_CASCADE_ACTIVE(i)) + element_info[i].graphic[ACTION_DEFAULT] = IMG_EDITOR_CASCADE_LIST_ACTIVE; + } +#endif + /* now set all undefined/invalid graphics to -1 to set to default after it */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) { @@ -659,9 +501,7 @@ void InitElementGraphicInfo() } } } -#endif -#if 1 /* adjust graphics with 2nd tile for movement according to direction (do this before correcting '-1' values to minimize calculations) */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) @@ -689,18 +529,6 @@ void InitElementGraphicInfo() g->offset_y != 0); boolean front_is_left_or_upper = (src_x_front < src_x_back || src_y_front < src_y_back); -#if 0 - boolean second_tile_is_back = - ((move_dir == MV_BIT_LEFT && front_is_left_or_upper) || - (move_dir == MV_BIT_UP && front_is_left_or_upper)); - boolean second_tile_is_front = - ((move_dir == MV_BIT_RIGHT && front_is_left_or_upper) || - (move_dir == MV_BIT_DOWN && front_is_left_or_upper)); - boolean second_tile_should_be_front = - (g->second_tile_is_start == 0); - boolean second_tile_should_be_back = - (g->second_tile_is_start == 1); -#endif boolean swap_movement_tiles_always = (g->swap_double_tiles == 1); boolean swap_movement_tiles_autodetected = (!frames_are_ordered_diagonally && @@ -710,17 +538,6 @@ void InitElementGraphicInfo() (move_dir == MV_BIT_DOWN && front_is_left_or_upper))); Bitmap *dummy; -#if 0 - printf("::: CHECKING element %d ('%s'), '%s', dir %d [(%d -> %d, %d), %d => %d]\n", - i, element_info[i].token_name, - element_action_info[act].suffix, move_dir, - g->swap_double_tiles, - swap_movement_tiles_never, - swap_movement_tiles_always, - swap_movement_tiles_autodetected, - swap_movement_tiles); -#endif - /* swap frontside and backside graphic tile coordinates, if needed */ if (swap_movement_tiles_always || swap_movement_tiles_autodetected) { @@ -738,16 +555,11 @@ void InitElementGraphicInfo() /* do not swap front and backside tiles again after correction */ g->swap_double_tiles = 0; - -#if 0 - printf(" CORRECTED\n"); -#endif } } } } } -#endif /* now set all '-1' values to element specific default values */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) @@ -879,16 +691,6 @@ void InitElementGraphicInfo() if (element_info[i].direction_crumbled[act][dir] == -1) element_info[i].direction_crumbled[act][dir] = default_action_direction_crumbled; - -#if 0 - if (i == EL_EMC_GRASS && - act == ACTION_DIGGING && - dir == MV_BIT_DOWN) - printf("::: direction_crumbled == %d, %d, %d\n", - element_info[i].direction_crumbled[act][dir], - default_action_direction_crumbled, - element_info[i].crumbled[act]); -#endif } /* no graphic for this specific action -- use default action graphic */ @@ -910,7 +712,6 @@ void InitElementGraphicInfo() } } -#if 1 /* set animation mode to "none" for each graphic with only 1 frame */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) { @@ -936,7 +737,6 @@ void InitElementGraphicInfo() } } } -#endif #if 0 #if DEBUG @@ -1000,24 +800,46 @@ void InitElementSpecialGraphicInfo() element_info[element].special_graphic[special] = graphic; } -#if 1 /* now set all undefined/invalid graphics to default */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) for (j = 0; j < NUM_SPECIAL_GFX_ARGS; j++) if (graphic_info[element_info[i].special_graphic[j]].bitmap == NULL) element_info[i].special_graphic[j] = element_info[i].graphic[ACTION_DEFAULT]; -#endif } -static int get_element_from_token(char *token) +static int get_graphic_parameter_value(char *value_raw, char *suffix, int type) { int i; + int x = 0; + if (type != TYPE_TOKEN) + return get_parameter_value(value_raw, suffix, type); + + if (strcmp(value_raw, ARG_UNDEFINED) == 0) + return ARG_UNDEFINED_VALUE; + + /* !!! OPTIMIZE THIS BY USING HASH !!! */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) - if (strcmp(element_info[i].token_name, token) == 0) + if (strcmp(element_info[i].token_name, value_raw) == 0) return i; + /* !!! OPTIMIZE THIS BY USING HASH !!! */ + for (i = 0; image_config[i].token != NULL; i++) + { + int len_config_value = strlen(image_config[i].value); + + if (strcmp(&image_config[i].value[len_config_value - 4], ".pcx") != 0 && + strcmp(&image_config[i].value[len_config_value - 4], ".wav") != 0 && + strcmp(image_config[i].value, UNDEFINED_FILENAME) != 0) + continue; + + if (strcmp(image_config[i].token, value_raw) == 0) + return x; + + x++; + } + return -1; } @@ -1037,73 +859,31 @@ static int get_scaled_graphic_height(int graphic) return original_height * scale_up_factor; } -static void set_graphic_parameters(int graphic, int graphic_copy_from) +static void set_graphic_parameters(int graphic) { - struct FileInfo *image = getImageListEntryFromImageID(graphic_copy_from); + struct FileInfo *image = getImageListEntryFromImageID(graphic); char **parameter_raw = image->parameter; - Bitmap *src_bitmap = getBitmapFromImageID(graphic_copy_from); + Bitmap *src_bitmap = getBitmapFromImageID(graphic); int parameter[NUM_GFX_ARGS]; int anim_frames_per_row = 1, anim_frames_per_col = 1; int anim_frames_per_line = 1; int i; -#if 1 -#if 1 - - /* !!! NEW ARTWORK FALLBACK CODE !!! NEARLY UNTESTED !!! */ /* if fallback to default artwork is done, also use the default parameters */ if (image->fallback_to_default) - { -#if 0 - printf("::: FALLBACK for %d\n", graphic_copy_from); -#endif - parameter_raw = image->default_parameter; - } - -#else - - /* !!! ARTWORK FALLBACK CODE !!! NEARLY UNTESTED !!! */ - /* (better try to set a "fallback -> use default parameters" flag) */ - if (src_bitmap) - { - int len_source_filename = strlen(src_bitmap->source_filename); - int len_default_filename = strlen(image->default_filename); - int pos_basename = len_source_filename - len_default_filename; - char *source_basename = &src_bitmap->source_filename[pos_basename]; - -#if 0 - printf("::: src_bitmap->source_filename -> '%s'\n", - src_bitmap->source_filename); - printf("::: image->default_filename -> '%s'\n", - image->default_filename); - printf("::: image->filename -> '%s'\n", - image->filename); -#endif - - /* check if there was a fallback to the default artwork file */ - if (strcmp(image->filename, image->default_filename) != 0 && - pos_basename >= 0 && - strcmp(source_basename, image->default_filename) == 0) - parameter_raw = image->default_parameter; - } -#endif -#endif /* get integer values from string parameters */ for (i = 0; i < NUM_GFX_ARGS; i++) - { - parameter[i] = - get_parameter_value(image_config_suffix[i].token, parameter_raw[i], - image_config_suffix[i].type); - - if (image_config_suffix[i].type == TYPE_TOKEN) - parameter[i] = get_element_from_token(parameter_raw[i]); - } + parameter[i] = get_graphic_parameter_value(parameter_raw[i], + image_config_suffix[i].token, + image_config_suffix[i].type); graphic_info[graphic].bitmap = src_bitmap; /* start with reliable default values */ + graphic_info[graphic].src_image_width = 0; + graphic_info[graphic].src_image_height = 0; graphic_info[graphic].src_x = 0; graphic_info[graphic].src_y = 0; graphic_info[graphic].width = TILEX; @@ -1117,6 +897,7 @@ static void set_graphic_parameters(int graphic, int graphic_copy_from) graphic_info[graphic].diggable_like = -1; /* do not use clone element */ graphic_info[graphic].border_size = TILEX / 8; /* "CRUMBLED" border size */ graphic_info[graphic].scale_up_factor = 1; /* default: no scaling up */ + graphic_info[graphic].clone_from = -1; /* do not use clone graphic */ graphic_info[graphic].anim_delay_fixed = 0; graphic_info[graphic].anim_delay_random = 0; graphic_info[graphic].post_delay_fixed = 0; @@ -1149,11 +930,14 @@ static void set_graphic_parameters(int graphic, int graphic_copy_from) if (src_bitmap) { /* get final bitmap size (with scaling, but without small images) */ - int src_bitmap_width = get_scaled_graphic_width(graphic); - int src_bitmap_height = get_scaled_graphic_height(graphic); + int src_image_width = get_scaled_graphic_width(graphic); + int src_image_height = get_scaled_graphic_height(graphic); + + anim_frames_per_row = src_image_width / graphic_info[graphic].width; + anim_frames_per_col = src_image_height / graphic_info[graphic].height; - anim_frames_per_row = src_bitmap_width / graphic_info[graphic].width; - anim_frames_per_col = src_bitmap_height / graphic_info[graphic].height; + graphic_info[graphic].src_image_width = src_image_width; + graphic_info[graphic].src_image_height = src_image_height; } /* correct x or y offset dependent of vertical or horizontal frame order */ @@ -1276,6 +1060,49 @@ static void set_graphic_parameters(int graphic, int graphic_copy_from) /* this is only used for drawing envelope graphics */ graphic_info[graphic].draw_masked = parameter[GFX_ARG_DRAW_MASKED]; + + /* optional graphic for cloning all graphics settings */ + if (parameter[GFX_ARG_CLONE_FROM] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].clone_from = parameter[GFX_ARG_CLONE_FROM]; +} + +static void set_cloned_graphic_parameters(int graphic) +{ + int fallback_graphic = IMG_CHAR_EXCLAM; + int max_num_images = getImageListSize(); + int clone_graphic = graphic_info[graphic].clone_from; + int num_references_followed = 1; + + while (graphic_info[clone_graphic].clone_from != -1 && + num_references_followed < max_num_images) + { + clone_graphic = graphic_info[clone_graphic].clone_from; + + num_references_followed++; + } + + if (num_references_followed >= max_num_images) + { + Error(ERR_RETURN_LINE, "-"); + Error(ERR_RETURN, "warning: error found in config file:"); + Error(ERR_RETURN, "- config file: '%s'", getImageConfigFilename()); + Error(ERR_RETURN, "- config token: '%s'", getTokenFromImageID(graphic)); + Error(ERR_RETURN, "error: loop discovered when resolving cloned graphics"); + Error(ERR_RETURN, "custom graphic rejected for this element/action"); + + if (graphic == fallback_graphic) + Error(ERR_EXIT, "fatal error: no fallback graphic available"); + + Error(ERR_RETURN, "fallback done to 'char_exclam' for this graphic"); + Error(ERR_RETURN_LINE, "-"); + + graphic_info[graphic] = graphic_info[fallback_graphic]; + } + else + { + graphic_info[graphic] = graphic_info[clone_graphic]; + graphic_info[graphic].clone_from = clone_graphic; + } } static void InitGraphicInfo() @@ -1296,10 +1123,6 @@ static void InitGraphicInfo() graphic_info = checked_calloc(num_images * sizeof(struct GraphicInfo)); -#if 0 - printf("::: graphic_info: %d entries\n", num_images); -#endif - #if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) if (clipmasks_initialized) { @@ -1316,6 +1139,15 @@ static void InitGraphicInfo() } #endif + /* first set all graphic paramaters ... */ + for (i = 0; i < num_images; i++) + set_graphic_parameters(i); + + /* ... then copy these parameters for cloned graphics */ + for (i = 0; i < num_images; i++) + if (graphic_info[i].clone_from != -1) + set_cloned_graphic_parameters(i); + for (i = 0; i < num_images; i++) { Bitmap *src_bitmap; @@ -1323,76 +1155,60 @@ static void InitGraphicInfo() int first_frame, last_frame; int src_bitmap_width, src_bitmap_height; -#if 0 - printf("::: image: '%s' [%d]\n", image->token, i); -#endif - -#if 0 - printf("::: image # %d: '%s' ['%s']\n", - i, image->token, - getTokenFromImageID(i)); -#endif - - set_graphic_parameters(i, i); - /* now check if no animation frames are outside of the loaded image */ if (graphic_info[i].bitmap == NULL) continue; /* skip check for optional images that are undefined */ /* get final bitmap size (with scaling, but without small images) */ - src_bitmap_width = get_scaled_graphic_width(i); - src_bitmap_height = get_scaled_graphic_height(i); + src_bitmap_width = graphic_info[i].src_image_width; + src_bitmap_height = graphic_info[i].src_image_height; + + /* check if first animation frame is inside specified bitmap */ first_frame = 0; getGraphicSource(i, first_frame, &src_bitmap, &src_x, &src_y); + if (src_x < 0 || src_y < 0 || src_x + TILEX > src_bitmap_width || src_y + TILEY > src_bitmap_height) { Error(ERR_RETURN_LINE, "-"); Error(ERR_RETURN, "warning: error found in config file:"); - Error(ERR_RETURN, "- config file: '%s'", - getImageConfigFilename()); - Error(ERR_RETURN, "- config token: '%s'", - getTokenFromImageID(i)); - Error(ERR_RETURN, "- image file: '%s'", - src_bitmap->source_filename); + Error(ERR_RETURN, "- config file: '%s'", getImageConfigFilename()); + Error(ERR_RETURN, "- config token: '%s'", getTokenFromImageID(i)); + Error(ERR_RETURN, "- image file: '%s'", src_bitmap->source_filename); Error(ERR_RETURN, - "error: first animation frame out of bounds (%d, %d)", - src_x, src_y); + "error: first animation frame out of bounds (%d, %d) [%d, %d]", + src_x, src_y, src_bitmap_width, src_bitmap_height); Error(ERR_RETURN, "custom graphic rejected for this element/action"); -#if 0 - Error(ERR_RETURN, "scale_up_factor == %d", scale_up_factor); -#endif - if (i == fallback_graphic) Error(ERR_EXIT, "fatal error: no fallback graphic available"); Error(ERR_RETURN, "fallback done to 'char_exclam' for this graphic"); Error(ERR_RETURN_LINE, "-"); - set_graphic_parameters(i, fallback_graphic); + graphic_info[i] = graphic_info[fallback_graphic]; } + /* check if last animation frame is inside specified bitmap */ + last_frame = graphic_info[i].anim_frames - 1; getGraphicSource(i, last_frame, &src_bitmap, &src_x, &src_y); + if (src_x < 0 || src_y < 0 || src_x + TILEX > src_bitmap_width || src_y + TILEY > src_bitmap_height) { Error(ERR_RETURN_LINE, "-"); Error(ERR_RETURN, "warning: error found in config file:"); - Error(ERR_RETURN, "- config file: '%s'", - getImageConfigFilename()); - Error(ERR_RETURN, "- config token: '%s'", - getTokenFromImageID(i)); - Error(ERR_RETURN, "- image file: '%s'", - src_bitmap->source_filename); + Error(ERR_RETURN, "- config file: '%s'", getImageConfigFilename()); + Error(ERR_RETURN, "- config token: '%s'", getTokenFromImageID(i)); + Error(ERR_RETURN, "- image file: '%s'", src_bitmap->source_filename); Error(ERR_RETURN, - "error: last animation frame (%d) out of bounds (%d, %d)", - last_frame, src_x, src_y); + "error: last animation frame (%d) out of bounds (%d, %d) [%d, %d]", + last_frame, src_x, src_y, src_bitmap_width, src_bitmap_height); Error(ERR_RETURN, "custom graphic rejected for this element/action"); if (i == fallback_graphic) @@ -1401,7 +1217,7 @@ static void InitGraphicInfo() Error(ERR_RETURN, "fallback done to 'char_exclam' for this graphic"); Error(ERR_RETURN_LINE, "-"); - set_graphic_parameters(i, fallback_graphic); + graphic_info[i] = graphic_info[fallback_graphic]; } #if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) @@ -1542,7 +1358,6 @@ static void InitElementSoundInfo() } } -#if 1 /* copy sound settings to some elements that are only stored in level file in native R'n'D levels, but are used by game engine in native EM levels */ for (i = 0; copy_properties[i][0] != -1; i++) @@ -1550,7 +1365,6 @@ static void InitElementSoundInfo() for (act = 0; act < NUM_ACTIONS; act++) element_info[copy_properties[i][j]].sound[act] = element_info[copy_properties[i][0]].sound[act]; -#endif } static void InitGameModeSoundInfo() @@ -1579,7 +1393,6 @@ static void InitGameModeSoundInfo() menu.sound[i] = menu.sound[GAME_MODE_DEFAULT]; #if 0 - /* TEST ONLY */ for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++) if (menu.sound[i] != -1) printf("::: menu.sound[%d] == %d\n", i, menu.sound[i]); @@ -1594,7 +1407,8 @@ static void set_sound_parameters(int sound, char **parameter_raw) /* get integer values from string parameters */ for (i = 0; i < NUM_SND_ARGS; i++) parameter[i] = - get_parameter_value(sound_config_suffix[i].token, parameter_raw[i], + get_parameter_value(parameter_raw[i], + sound_config_suffix[i].token, sound_config_suffix[i].type); /* explicit loop mode setting in configuration overrides default value */ @@ -1610,10 +1424,6 @@ static void set_sound_parameters(int sound, char **parameter_raw) static void InitSoundInfo() { -#if 0 - struct PropertyMapping *property_mapping = getSoundListPropertyMapping(); - int num_property_mappings = getSoundListPropertyMappingSize(); -#endif int *sound_effect_properties; int num_sounds = getSoundListSize(); int i, j; @@ -1657,11 +1467,6 @@ static void InitSoundInfo() } } -#if 0 - if (strcmp(sound->token, "custom_42") == 0) - printf("::: '%s' -> %d\n", sound->token, sound_info[i].loop); -#endif - /* associate elements and some selected sound actions */ for (j = 0; j < MAX_NUM_ELEMENTS; j++) @@ -1686,77 +1491,6 @@ static void InitSoundInfo() } free(sound_effect_properties); - -#if 0 - /* !!! MOVED TO "InitElementSoundInfo()" !!! */ - /* !!! everything defined here gets overwritten there !!! */ - - /* copy sound settings to some elements that are only stored in level file - in native R'n'D levels, but are used by game engine in native EM levels */ - for (i = 0; i < NUM_ACTIONS; i++) - for (j = 0; copy_properties[j][0] != -1; j++) - for (k = 1; k <= 4; k++) - element_info[copy_properties[j][k]].sound[i] = - element_info[copy_properties[j][0]].sound[i]; - - printf("::: bug -> %d\n", element_info[EL_BUG].sound[ACTION_MOVING]); - printf("::: bug_r -> %d\n", element_info[EL_BUG_RIGHT].sound[ACTION_MOVING]); -#endif - -#if 0 - /* !!! now handled in InitElementSoundInfo() !!! */ - /* initialize element/sound mapping from dynamic configuration */ - for (i = 0; i < num_property_mappings; i++) - { - int element = property_mapping[i].base_index; - int action = property_mapping[i].ext1_index; - int sound = property_mapping[i].artwork_index; - - if (action < 0) - action = ACTION_DEFAULT; - - printf("::: %d: %d, %d, %d ['%s']\n", - i, element, action, sound, element_info[element].token_name); - - element_info[element].sound[action] = sound; - } -#endif - -#if 0 - /* TEST ONLY */ - { - int element = EL_CUSTOM_11; - int j = 0; - - while (element_action_info[j].suffix) - { - printf("element %d, sound action '%s' == %d\n", - element, element_action_info[j].suffix, - element_info[element].sound[j]); - j++; - } - } - - PlaySoundLevelElementAction(0,0, EL_CUSTOM_11, ACTION_PUSHING); -#endif - -#if 0 - /* TEST ONLY */ - { - int element = EL_SAND; - int sound_action = ACTION_DIGGING; - int j = 0; - - while (element_action_info[j].suffix) - { - if (element_action_info[j].value == sound_action) - printf("element %d, sound action '%s' == %d\n", - element, element_action_info[j].suffix, - element_info[element].sound[sound_action]); - j++; - } - } -#endif } static void InitGameModeMusicInfo() @@ -1834,7 +1568,6 @@ static void InitGameModeMusicInfo() menu.music[i] = menu.music[GAME_MODE_DEFAULT]; #if 0 - /* TEST ONLY */ for (i = 0; i < MAX_LEVELS; i++) if (levelset.music[i] != -1) printf("::: levelset.music[%d] == %d\n", i, levelset.music[i]); @@ -1852,7 +1585,8 @@ static void set_music_parameters(int music, char **parameter_raw) /* get integer values from string parameters */ for (i = 0; i < NUM_MUS_ARGS; i++) parameter[i] = - get_parameter_value(music_config_suffix[i].token, parameter_raw[i], + get_parameter_value(parameter_raw[i], + music_config_suffix[i].token, music_config_suffix[i].type); /* explicit loop mode setting in configuration overrides default value */ @@ -1947,7 +1681,7 @@ static int get_special_property_bit(int element, int property_bit_nr) { EL_SP_MURPHY, 0 }, { EL_SOKOBAN_FIELD_PLAYER, 0 }, - /* all element that can move may be able to also move into acid */ + /* all elements that can move may be able to also move into acid */ { EL_BUG, 1 }, { EL_BUG_LEFT, 1 }, { EL_BUG_RIGHT, 1 }, @@ -1989,6 +1723,7 @@ static int get_special_property_bit(int element, int property_bit_nr) { EL_SP_ELECTRON, 15 }, { EL_BALLOON, 16 }, { EL_SPRING, 17 }, + { EL_EMC_ANDROID, 18 }, { -1, -1 }, }; @@ -2030,7 +1765,6 @@ static int get_special_property_bit(int element, int property_bit_nr) return -1; } -#if 1 void setBitfieldProperty(int *bitfield, int property_bit_nr, int element, boolean property_value) { @@ -2055,32 +1789,6 @@ boolean getBitfieldProperty(int *bitfield, int property_bit_nr, int element) return FALSE; } -#else - -void setMoveIntoAcidProperty(struct LevelInfo *level, int element, boolean set) -{ - int bit_nr = get_special_property_bit(element, EP_CAN_MOVE_INTO_ACID); - - if (bit_nr > -1) - { - level->can_move_into_acid_bits &= ~(1 << bit_nr); - - if (set) - level->can_move_into_acid_bits |= (1 << bit_nr); - } -} - -boolean getMoveIntoAcidProperty(struct LevelInfo *level, int element) -{ - int bit_nr = get_special_property_bit(element, EP_CAN_MOVE_INTO_ACID); - - if (bit_nr > -1) - return ((level->can_move_into_acid_bits & (1 << bit_nr)) != 0); - - return FALSE; -} -#endif - void InitElementPropertiesStatic() { static int ep_diggable[] = @@ -2102,6 +1810,7 @@ void InitElementPropertiesStatic() EL_SP_BUGGY_BASE_ACTIVE, EL_EMC_PLANT, #endif + -1 }; @@ -2144,6 +1853,7 @@ void InitElementPropertiesStatic() EL_SPEED_PILL, EL_EMC_LENSES, EL_EMC_MAGNIFIER, + -1 }; @@ -2174,6 +1884,7 @@ void InitElementPropertiesStatic() EL_SP_BUGGY_BASE_ACTIVE, EL_EMC_PLANT, #endif + -1 }; @@ -2192,6 +1903,7 @@ void InitElementPropertiesStatic() EL_PACMAN, EL_SP_SNIKSNAK, EL_SP_ELECTRON, + -1 }; @@ -2201,6 +1913,7 @@ void InitElementPropertiesStatic() EL_SPACESHIP, EL_BD_BUTTERFLY, EL_BD_FIREFLY, + -1 }; @@ -2266,6 +1979,10 @@ void InitElementPropertiesStatic() EL_GATE_2_GRAY, EL_GATE_3_GRAY, EL_GATE_4_GRAY, + EL_GATE_1_GRAY_ACTIVE, + EL_GATE_2_GRAY_ACTIVE, + EL_GATE_3_GRAY_ACTIVE, + EL_GATE_4_GRAY_ACTIVE, EL_EM_GATE_1, EL_EM_GATE_2, EL_EM_GATE_3, @@ -2274,6 +1991,10 @@ void InitElementPropertiesStatic() EL_EM_GATE_2_GRAY, EL_EM_GATE_3_GRAY, EL_EM_GATE_4_GRAY, + EL_EM_GATE_1_GRAY_ACTIVE, + EL_EM_GATE_2_GRAY_ACTIVE, + EL_EM_GATE_3_GRAY_ACTIVE, + EL_EM_GATE_4_GRAY_ACTIVE, EL_EMC_GATE_5, EL_EMC_GATE_6, EL_EMC_GATE_7, @@ -2282,6 +2003,10 @@ void InitElementPropertiesStatic() EL_EMC_GATE_6_GRAY, EL_EMC_GATE_7_GRAY, EL_EMC_GATE_8_GRAY, + EL_EMC_GATE_5_GRAY_ACTIVE, + EL_EMC_GATE_6_GRAY_ACTIVE, + EL_EMC_GATE_7_GRAY_ACTIVE, + EL_EMC_GATE_8_GRAY_ACTIVE, EL_SWITCHGATE_OPEN, EL_SWITCHGATE_OPENING, EL_SWITCHGATE_CLOSED, @@ -2309,6 +2034,7 @@ void InitElementPropertiesStatic() EL_TUBE_LEFT_DOWN, EL_TUBE_RIGHT_UP, EL_TUBE_RIGHT_DOWN, + -1 }; @@ -2350,6 +2076,9 @@ void InitElementPropertiesStatic() EL_EMC_WALL_SLIPPERY_2, EL_EMC_WALL_SLIPPERY_3, EL_EMC_WALL_SLIPPERY_4, + EL_EMC_MAGIC_BALL, + EL_EMC_MAGIC_BALL_ACTIVE, + -1 }; @@ -2379,6 +2108,7 @@ void InitElementPropertiesStatic() EL_BALLOON, EL_SPRING, EL_EMC_ANDROID, + -1 }; @@ -2407,6 +2137,7 @@ void InitElementPropertiesStatic() EL_CRYSTAL, EL_SPRING, EL_DX_SUPABOMB, + -1 }; @@ -2432,6 +2163,7 @@ void InitElementPropertiesStatic() EL_CRYSTAL, EL_SPRING, EL_DX_SUPABOMB, + -1 }; @@ -2440,6 +2172,7 @@ void InitElementPropertiesStatic() EL_ROCK, EL_BD_ROCK, EL_SP_ZONK, + -1 }; @@ -2448,6 +2181,7 @@ void InitElementPropertiesStatic() EL_ROCK, EL_BD_ROCK, EL_SP_ZONK, + -1 }; @@ -2484,6 +2218,7 @@ void InitElementPropertiesStatic() #if 0 EL_BLACK_ORB, #endif + -1 }; @@ -2499,6 +2234,7 @@ void InitElementPropertiesStatic() EL_PIG, EL_DRAGON, EL_MOLE, + -1 }; @@ -2507,6 +2243,7 @@ void InitElementPropertiesStatic() EL_BOMB, EL_SP_DISK_ORANGE, EL_DX_SUPABOMB, + -1 }; @@ -2526,14 +2263,14 @@ void InitElementPropertiesStatic() EL_GATE_2_GRAY, EL_GATE_3_GRAY, EL_GATE_4_GRAY, + EL_GATE_1_GRAY_ACTIVE, + EL_GATE_2_GRAY_ACTIVE, + EL_GATE_3_GRAY_ACTIVE, + EL_GATE_4_GRAY_ACTIVE, EL_PENGUIN, EL_PIG, EL_DRAGON, -#if 0 /* USE_GRAVITY_BUGFIX_OLD */ - EL_PLAYER_IS_LEAVING, /* needed for gravity + "block last field" */ -#endif - -1 }; @@ -2550,6 +2287,7 @@ void InitElementPropertiesStatic() EL_TUBE_LEFT_DOWN, EL_TUBE_RIGHT_UP, EL_TUBE_RIGHT_DOWN, + -1 }; @@ -2568,6 +2306,10 @@ void InitElementPropertiesStatic() EL_EM_GATE_2_GRAY, EL_EM_GATE_3_GRAY, EL_EM_GATE_4_GRAY, + EL_EM_GATE_1_GRAY_ACTIVE, + EL_EM_GATE_2_GRAY_ACTIVE, + EL_EM_GATE_3_GRAY_ACTIVE, + EL_EM_GATE_4_GRAY_ACTIVE, EL_EMC_GATE_5, EL_EMC_GATE_6, EL_EMC_GATE_7, @@ -2576,8 +2318,13 @@ void InitElementPropertiesStatic() EL_EMC_GATE_6_GRAY, EL_EMC_GATE_7_GRAY, EL_EMC_GATE_8_GRAY, + EL_EMC_GATE_5_GRAY_ACTIVE, + EL_EMC_GATE_6_GRAY_ACTIVE, + EL_EMC_GATE_7_GRAY_ACTIVE, + EL_EMC_GATE_8_GRAY_ACTIVE, EL_SWITCHGATE_OPEN, EL_TIMEGATE_OPEN, + -1 }; @@ -2602,6 +2349,7 @@ void InitElementPropertiesStatic() EL_SP_GRAVITY_OFF_PORT_RIGHT, EL_SP_GRAVITY_OFF_PORT_UP, EL_SP_GRAVITY_OFF_PORT_DOWN, + -1 }; @@ -2637,6 +2385,7 @@ void InitElementPropertiesStatic() EL_SP_DISK_YELLOW, EL_BALLOON, EL_EMC_ANDROID, + -1 }; @@ -2669,6 +2418,10 @@ void InitElementPropertiesStatic() EL_EM_GATE_2_GRAY, EL_EM_GATE_3_GRAY, EL_EM_GATE_4_GRAY, + EL_EM_GATE_1_GRAY_ACTIVE, + EL_EM_GATE_2_GRAY_ACTIVE, + EL_EM_GATE_3_GRAY_ACTIVE, + EL_EM_GATE_4_GRAY_ACTIVE, EL_EMC_GATE_5, EL_EMC_GATE_6, EL_EMC_GATE_7, @@ -2677,6 +2430,10 @@ void InitElementPropertiesStatic() EL_EMC_GATE_6_GRAY, EL_EMC_GATE_7_GRAY, EL_EMC_GATE_8_GRAY, + EL_EMC_GATE_5_GRAY_ACTIVE, + EL_EMC_GATE_6_GRAY_ACTIVE, + EL_EMC_GATE_7_GRAY_ACTIVE, + EL_EMC_GATE_8_GRAY_ACTIVE, EL_SWITCHGATE_OPEN, EL_TIMEGATE_OPEN, @@ -2700,6 +2457,7 @@ void InitElementPropertiesStatic() EL_SP_GRAVITY_OFF_PORT_RIGHT, EL_SP_GRAVITY_OFF_PORT_UP, EL_SP_GRAVITY_OFF_PORT_DOWN, + -1 }; @@ -2741,6 +2499,7 @@ void InitElementPropertiesStatic() /* elements that can explode only by explosion */ EL_BLACK_ORB, + -1 }; @@ -2771,6 +2530,7 @@ void InitElementPropertiesStatic() EL_SP_GRAVITY_OFF_PORT_UP, EL_SP_GRAVITY_OFF_PORT_DOWN, EL_EMC_GRASS, + -1 }; @@ -2783,6 +2543,7 @@ void InitElementPropertiesStatic() EL_SP_MURPHY, EL_SOKOBAN_FIELD_PLAYER, EL_TRIGGER_PLAYER, + -1 }; @@ -2796,6 +2557,7 @@ void InitElementPropertiesStatic() EL_EMERALD_RED, EL_EMERALD_PURPLE, EL_DIAMOND, + -1 }; @@ -2825,9 +2587,12 @@ void InitElementPropertiesStatic() EL_BALLOON_SWITCH_UP, EL_BALLOON_SWITCH_DOWN, EL_BALLOON_SWITCH_ANY, + EL_BALLOON_SWITCH_NONE, EL_LAMP, EL_TIME_ORB_FULL, EL_EMC_MAGIC_BALL_SWITCH, + EL_EMC_MAGIC_BALL_SWITCH_ACTIVE, + -1 }; @@ -2861,6 +2626,7 @@ void InitElementPropertiesStatic() EL_BD_AMOEBA, EL_CHAR_QUESTION, EL_UNKNOWN, + -1 }; @@ -2935,6 +2701,7 @@ void InitElementPropertiesStatic() EL_SP_BUGGY_BASE_ACTIVE, EL_SP_EXIT_OPENING, EL_SP_EXIT_CLOSING, + -1 }; @@ -2951,6 +2718,7 @@ void InitElementPropertiesStatic() EL_PLAYER_3, EL_PLAYER_4, EL_INVISIBLE_STEELWALL, + -1 }; @@ -2962,6 +2730,7 @@ void InitElementPropertiesStatic() EL_EMERALD_RED, EL_EMERALD_PURPLE, EL_DIAMOND, + -1 }; @@ -2989,6 +2758,7 @@ void InitElementPropertiesStatic() EL_DIAMOND, EL_PEARL, EL_CRYSTAL, + -1 }; @@ -3002,6 +2772,7 @@ void InitElementPropertiesStatic() EL_DIAMOND, EL_PEARL, EL_CRYSTAL, + -1 }; @@ -3013,6 +2784,7 @@ void InitElementPropertiesStatic() EL_EMERALD_RED, EL_EMERALD_PURPLE, EL_DIAMOND, + -1 }; @@ -3027,6 +2799,10 @@ void InitElementPropertiesStatic() EL_GATE_2_GRAY, EL_GATE_3_GRAY, EL_GATE_4_GRAY, + EL_GATE_1_GRAY_ACTIVE, + EL_GATE_2_GRAY_ACTIVE, + EL_GATE_3_GRAY_ACTIVE, + EL_GATE_4_GRAY_ACTIVE, EL_EM_GATE_1, EL_EM_GATE_2, EL_EM_GATE_3, @@ -3035,6 +2811,10 @@ void InitElementPropertiesStatic() EL_EM_GATE_2_GRAY, EL_EM_GATE_3_GRAY, EL_EM_GATE_4_GRAY, + EL_EM_GATE_1_GRAY_ACTIVE, + EL_EM_GATE_2_GRAY_ACTIVE, + EL_EM_GATE_3_GRAY_ACTIVE, + EL_EM_GATE_4_GRAY_ACTIVE, EL_EXIT_CLOSED, EL_EXIT_OPENING, EL_EXIT_OPEN, @@ -3083,6 +2863,7 @@ void InitElementPropertiesStatic() EL_EMC_WALL_6, EL_EMC_WALL_7, EL_EMC_WALL_8, + -1 }; @@ -3211,6 +2992,10 @@ void InitElementPropertiesStatic() EL_GATE_2_GRAY, EL_GATE_3_GRAY, EL_GATE_4_GRAY, + EL_GATE_1_GRAY_ACTIVE, + EL_GATE_2_GRAY_ACTIVE, + EL_GATE_3_GRAY_ACTIVE, + EL_GATE_4_GRAY_ACTIVE, EL_EM_GATE_1, EL_EM_GATE_2, EL_EM_GATE_3, @@ -3219,6 +3004,10 @@ void InitElementPropertiesStatic() EL_EM_GATE_2_GRAY, EL_EM_GATE_3_GRAY, EL_EM_GATE_4_GRAY, + EL_EM_GATE_1_GRAY_ACTIVE, + EL_EM_GATE_2_GRAY_ACTIVE, + EL_EM_GATE_3_GRAY_ACTIVE, + EL_EM_GATE_4_GRAY_ACTIVE, EL_SWITCHGATE_OPEN, EL_SWITCHGATE_OPENING, EL_SWITCHGATE_CLOSED, @@ -3238,6 +3027,7 @@ void InitElementPropertiesStatic() EL_TUBE_LEFT_DOWN, EL_TUBE_RIGHT_UP, EL_TUBE_RIGHT_DOWN, + -1 }; @@ -3254,6 +3044,7 @@ void InitElementPropertiesStatic() EL_PACMAN, EL_SP_SNIKSNAK, EL_SP_ELECTRON, + -1 }; @@ -3271,6 +3062,7 @@ void InitElementPropertiesStatic() EL_CONVEYOR_BELT_4_LEFT, EL_CONVEYOR_BELT_4_MIDDLE, EL_CONVEYOR_BELT_4_RIGHT, + -1 }; @@ -3288,6 +3080,7 @@ void InitElementPropertiesStatic() EL_CONVEYOR_BELT_4_LEFT_ACTIVE, EL_CONVEYOR_BELT_4_MIDDLE_ACTIVE, EL_CONVEYOR_BELT_4_RIGHT_ACTIVE, + -1 }; @@ -3305,6 +3098,7 @@ void InitElementPropertiesStatic() EL_CONVEYOR_BELT_4_SWITCH_LEFT, EL_CONVEYOR_BELT_4_SWITCH_MIDDLE, EL_CONVEYOR_BELT_4_SWITCH_RIGHT, + -1 }; @@ -3321,6 +3115,7 @@ void InitElementPropertiesStatic() EL_TUBE_VERTICAL_LEFT, EL_TUBE_VERTICAL_RIGHT, EL_TUBE_ANY, + -1 }; @@ -3334,6 +3129,10 @@ void InitElementPropertiesStatic() EL_GATE_2_GRAY, EL_GATE_3_GRAY, EL_GATE_4_GRAY, + EL_GATE_1_GRAY_ACTIVE, + EL_GATE_2_GRAY_ACTIVE, + EL_GATE_3_GRAY_ACTIVE, + EL_GATE_4_GRAY_ACTIVE, EL_EM_GATE_1, EL_EM_GATE_2, EL_EM_GATE_3, @@ -3342,6 +3141,10 @@ void InitElementPropertiesStatic() EL_EM_GATE_2_GRAY, EL_EM_GATE_3_GRAY, EL_EM_GATE_4_GRAY, + EL_EM_GATE_1_GRAY_ACTIVE, + EL_EM_GATE_2_GRAY_ACTIVE, + EL_EM_GATE_3_GRAY_ACTIVE, + EL_EM_GATE_4_GRAY_ACTIVE, EL_EMC_GATE_5, EL_EMC_GATE_6, EL_EMC_GATE_7, @@ -3350,6 +3153,11 @@ void InitElementPropertiesStatic() EL_EMC_GATE_6_GRAY, EL_EMC_GATE_7_GRAY, EL_EMC_GATE_8_GRAY, + EL_EMC_GATE_5_GRAY_ACTIVE, + EL_EMC_GATE_6_GRAY_ACTIVE, + EL_EMC_GATE_7_GRAY_ACTIVE, + EL_EMC_GATE_8_GRAY_ACTIVE, + -1 }; @@ -3360,6 +3168,7 @@ void InitElementPropertiesStatic() EL_AMOEBA_DRY, EL_AMOEBA_FULL, EL_BD_AMOEBA, + -1 }; @@ -3369,16 +3178,25 @@ void InitElementPropertiesStatic() EL_AMOEBA_DRY, EL_AMOEBA_FULL, EL_BD_AMOEBA, + -1 }; - static int ep_has_content[] = + static int ep_has_editor_content[] = { + EL_PLAYER_1, + EL_PLAYER_2, + EL_PLAYER_3, + EL_PLAYER_4, + EL_SP_MURPHY, EL_YAMYAM, EL_AMOEBA_WET, EL_AMOEBA_DRY, EL_AMOEBA_FULL, EL_BD_AMOEBA, + EL_EMC_MAGIC_BALL, + EL_EMC_ANDROID, + -1 }; @@ -3397,6 +3215,7 @@ void InitElementPropertiesStatic() EL_AMOEBA_FULL, EL_GAME_OF_LIFE, EL_BIOMAZE, + -1 }; @@ -3408,6 +3227,7 @@ void InitElementPropertiesStatic() EL_DYNABOMB_PLAYER_3_ACTIVE, EL_DYNABOMB_PLAYER_4_ACTIVE, EL_SP_DISK_RED_ACTIVE, + -1 }; @@ -3443,6 +3263,10 @@ void InitElementPropertiesStatic() EL_GATE_2_GRAY, EL_GATE_3_GRAY, EL_GATE_4_GRAY, + EL_GATE_1_GRAY_ACTIVE, + EL_GATE_2_GRAY_ACTIVE, + EL_GATE_3_GRAY_ACTIVE, + EL_GATE_4_GRAY_ACTIVE, EL_EM_GATE_1, EL_EM_GATE_2, EL_EM_GATE_3, @@ -3451,6 +3275,10 @@ void InitElementPropertiesStatic() EL_EM_GATE_2_GRAY, EL_EM_GATE_3_GRAY, EL_EM_GATE_4_GRAY, + EL_EM_GATE_1_GRAY_ACTIVE, + EL_EM_GATE_2_GRAY_ACTIVE, + EL_EM_GATE_3_GRAY_ACTIVE, + EL_EM_GATE_4_GRAY_ACTIVE, EL_EMC_GATE_5, EL_EMC_GATE_6, EL_EMC_GATE_7, @@ -3459,6 +3287,10 @@ void InitElementPropertiesStatic() EL_EMC_GATE_6_GRAY, EL_EMC_GATE_7_GRAY, EL_EMC_GATE_8_GRAY, + EL_EMC_GATE_5_GRAY_ACTIVE, + EL_EMC_GATE_6_GRAY_ACTIVE, + EL_EMC_GATE_7_GRAY_ACTIVE, + EL_EMC_GATE_8_GRAY_ACTIVE, EL_DYNAMITE, EL_INVISIBLE_STEELWALL, EL_INVISIBLE_WALL, @@ -3580,6 +3412,7 @@ void InitElementPropertiesStatic() EL_EMC_WALL_14, EL_EMC_WALL_15, EL_EMC_WALL_16, + -1 }; @@ -3594,6 +3427,47 @@ void InitElementPropertiesStatic() EL_LANDMINE, EL_TRAP, EL_TRAP_ACTIVE, + + -1 + }; + + static int ep_editor_cascade_active[] = + { + EL_INTERNAL_CASCADE_BD_ACTIVE, + EL_INTERNAL_CASCADE_EM_ACTIVE, + EL_INTERNAL_CASCADE_EMC_ACTIVE, + EL_INTERNAL_CASCADE_RND_ACTIVE, + EL_INTERNAL_CASCADE_SB_ACTIVE, + EL_INTERNAL_CASCADE_SP_ACTIVE, + EL_INTERNAL_CASCADE_DC_ACTIVE, + EL_INTERNAL_CASCADE_DX_ACTIVE, + EL_INTERNAL_CASCADE_CHARS_ACTIVE, + EL_INTERNAL_CASCADE_CE_ACTIVE, + EL_INTERNAL_CASCADE_GE_ACTIVE, + EL_INTERNAL_CASCADE_USER_ACTIVE, + EL_INTERNAL_CASCADE_GENERIC_ACTIVE, + EL_INTERNAL_CASCADE_DYNAMIC_ACTIVE, + + -1 + }; + + static int ep_editor_cascade_inactive[] = + { + EL_INTERNAL_CASCADE_BD, + EL_INTERNAL_CASCADE_EM, + EL_INTERNAL_CASCADE_EMC, + EL_INTERNAL_CASCADE_RND, + EL_INTERNAL_CASCADE_SB, + EL_INTERNAL_CASCADE_SP, + EL_INTERNAL_CASCADE_DC, + EL_INTERNAL_CASCADE_DX, + EL_INTERNAL_CASCADE_CHARS, + EL_INTERNAL_CASCADE_CE, + EL_INTERNAL_CASCADE_GE, + EL_INTERNAL_CASCADE_USER, + EL_INTERNAL_CASCADE_GENERIC, + EL_INTERNAL_CASCADE_DYNAMIC, + -1 }; @@ -3603,68 +3477,71 @@ void InitElementPropertiesStatic() int property; } element_properties[] = { - { ep_diggable, EP_DIGGABLE }, - { ep_collectible_only, EP_COLLECTIBLE_ONLY }, - { ep_dont_run_into, EP_DONT_RUN_INTO }, - { ep_dont_collide_with, EP_DONT_COLLIDE_WITH }, - { ep_dont_touch, EP_DONT_TOUCH }, - { ep_indestructible, EP_INDESTRUCTIBLE }, - { ep_slippery, EP_SLIPPERY }, - { ep_can_change, EP_CAN_CHANGE }, - { ep_can_move, EP_CAN_MOVE }, - { ep_can_fall, EP_CAN_FALL }, - { ep_can_smash_player, EP_CAN_SMASH_PLAYER }, - { ep_can_smash_enemies, EP_CAN_SMASH_ENEMIES }, - { ep_can_smash_everything, EP_CAN_SMASH_EVERYTHING }, - { ep_explodes_by_fire, EP_EXPLODES_BY_FIRE }, - { ep_explodes_smashed, EP_EXPLODES_SMASHED }, - { ep_explodes_impact, EP_EXPLODES_IMPACT }, - { ep_walkable_over, EP_WALKABLE_OVER }, - { ep_walkable_inside, EP_WALKABLE_INSIDE }, - { ep_walkable_under, EP_WALKABLE_UNDER }, - { ep_passable_over, EP_PASSABLE_OVER }, - { ep_passable_inside, EP_PASSABLE_INSIDE }, - { ep_passable_under, EP_PASSABLE_UNDER }, - { ep_droppable, EP_DROPPABLE }, - { ep_explodes_1x1_old, EP_EXPLODES_1X1_OLD }, - { ep_pushable, EP_PUSHABLE }, - { ep_explodes_cross_old, EP_EXPLODES_CROSS_OLD }, - { ep_protected, EP_PROTECTED }, - { ep_throwable, EP_THROWABLE }, - { ep_can_explode, EP_CAN_EXPLODE }, - { ep_gravity_reachable, EP_GRAVITY_REACHABLE }, - - { ep_player, EP_PLAYER }, - { ep_can_pass_magic_wall, EP_CAN_PASS_MAGIC_WALL }, - { ep_switchable, EP_SWITCHABLE }, - { ep_bd_element, EP_BD_ELEMENT }, - { ep_sp_element, EP_SP_ELEMENT }, - { ep_sb_element, EP_SB_ELEMENT }, - { ep_gem, EP_GEM }, - { ep_food_dark_yamyam, EP_FOOD_DARK_YAMYAM }, - { ep_food_penguin, EP_FOOD_PENGUIN }, - { ep_food_pig, EP_FOOD_PIG }, - { ep_historic_wall, EP_HISTORIC_WALL }, - { ep_historic_solid, EP_HISTORIC_SOLID }, - { ep_classic_enemy, EP_CLASSIC_ENEMY }, - { ep_belt, EP_BELT }, - { ep_belt_active, EP_BELT_ACTIVE }, - { ep_belt_switch, EP_BELT_SWITCH }, - { ep_tube, EP_TUBE }, - { ep_keygate, EP_KEYGATE }, - { ep_amoeboid, EP_AMOEBOID }, - { ep_amoebalive, EP_AMOEBALIVE }, - { ep_has_content, EP_HAS_CONTENT }, - { ep_can_turn_each_move, EP_CAN_TURN_EACH_MOVE }, - { ep_can_grow, EP_CAN_GROW }, - { ep_active_bomb, EP_ACTIVE_BOMB }, - { ep_inactive, EP_INACTIVE }, - - { ep_em_slippery_wall, EP_EM_SLIPPERY_WALL }, - - { ep_gfx_crumbled, EP_GFX_CRUMBLED }, - - { NULL, -1 } + { ep_diggable, EP_DIGGABLE }, + { ep_collectible_only, EP_COLLECTIBLE_ONLY }, + { ep_dont_run_into, EP_DONT_RUN_INTO }, + { ep_dont_collide_with, EP_DONT_COLLIDE_WITH }, + { ep_dont_touch, EP_DONT_TOUCH }, + { ep_indestructible, EP_INDESTRUCTIBLE }, + { ep_slippery, EP_SLIPPERY }, + { ep_can_change, EP_CAN_CHANGE }, + { ep_can_move, EP_CAN_MOVE }, + { ep_can_fall, EP_CAN_FALL }, + { ep_can_smash_player, EP_CAN_SMASH_PLAYER }, + { ep_can_smash_enemies, EP_CAN_SMASH_ENEMIES }, + { ep_can_smash_everything, EP_CAN_SMASH_EVERYTHING }, + { ep_explodes_by_fire, EP_EXPLODES_BY_FIRE }, + { ep_explodes_smashed, EP_EXPLODES_SMASHED }, + { ep_explodes_impact, EP_EXPLODES_IMPACT }, + { ep_walkable_over, EP_WALKABLE_OVER }, + { ep_walkable_inside, EP_WALKABLE_INSIDE }, + { ep_walkable_under, EP_WALKABLE_UNDER }, + { ep_passable_over, EP_PASSABLE_OVER }, + { ep_passable_inside, EP_PASSABLE_INSIDE }, + { ep_passable_under, EP_PASSABLE_UNDER }, + { ep_droppable, EP_DROPPABLE }, + { ep_explodes_1x1_old, EP_EXPLODES_1X1_OLD }, + { ep_pushable, EP_PUSHABLE }, + { ep_explodes_cross_old, EP_EXPLODES_CROSS_OLD }, + { ep_protected, EP_PROTECTED }, + { ep_throwable, EP_THROWABLE }, + { ep_can_explode, EP_CAN_EXPLODE }, + { ep_gravity_reachable, EP_GRAVITY_REACHABLE }, + + { ep_player, EP_PLAYER }, + { ep_can_pass_magic_wall, EP_CAN_PASS_MAGIC_WALL }, + { ep_switchable, EP_SWITCHABLE }, + { ep_bd_element, EP_BD_ELEMENT }, + { ep_sp_element, EP_SP_ELEMENT }, + { ep_sb_element, EP_SB_ELEMENT }, + { ep_gem, EP_GEM }, + { ep_food_dark_yamyam, EP_FOOD_DARK_YAMYAM }, + { ep_food_penguin, EP_FOOD_PENGUIN }, + { ep_food_pig, EP_FOOD_PIG }, + { ep_historic_wall, EP_HISTORIC_WALL }, + { ep_historic_solid, EP_HISTORIC_SOLID }, + { ep_classic_enemy, EP_CLASSIC_ENEMY }, + { ep_belt, EP_BELT }, + { ep_belt_active, EP_BELT_ACTIVE }, + { ep_belt_switch, EP_BELT_SWITCH }, + { ep_tube, EP_TUBE }, + { ep_keygate, EP_KEYGATE }, + { ep_amoeboid, EP_AMOEBOID }, + { ep_amoebalive, EP_AMOEBALIVE }, + { ep_has_editor_content, EP_HAS_EDITOR_CONTENT }, + { ep_can_turn_each_move, EP_CAN_TURN_EACH_MOVE }, + { ep_can_grow, EP_CAN_GROW }, + { ep_active_bomb, EP_ACTIVE_BOMB }, + { ep_inactive, EP_INACTIVE }, + + { ep_em_slippery_wall, EP_EM_SLIPPERY_WALL }, + + { ep_gfx_crumbled, EP_GFX_CRUMBLED }, + + { ep_editor_cascade_active, EP_EDITOR_CASCADE_ACTIVE }, + { ep_editor_cascade_inactive, EP_EDITOR_CASCADE_INACTIVE }, + + { NULL, -1 } }; int i, j, k; @@ -3690,38 +3567,6 @@ void InitElementPropertiesStatic() void InitElementPropertiesEngine(int engine_version) { -#if 0 - static int active_properties[] = - { - EP_AMOEBALIVE, - EP_AMOEBOID, - EP_PFORTE, - EP_DONT_COLLIDE_WITH, - EP_MAUER, - EP_CAN_FALL, - EP_CAN_SMASH, - EP_CAN_PASS_MAGIC_WALL, - EP_CAN_MOVE, - EP_DONT_TOUCH, - EP_DONT_RUN_INTO, - EP_GEM, - EP_EXPLODES_BY_FIRE, - EP_PUSHABLE, - EP_PLAYER, - EP_HAS_CONTENT, - EP_DIGGABLE, - EP_PASSABLE_INSIDE, - EP_OVER_PLAYER, - EP_ACTIVE_BOMB, - - EP_BELT, - EP_BELT_ACTIVE, - EP_BELT_SWITCH, - EP_WALKABLE_UNDER, - EP_EM_SLIPPERY_WALL, - }; -#endif - static int no_wall_properties[] = { EP_DIGGABLE, @@ -3753,10 +3598,6 @@ void InitElementPropertiesEngine(int engine_version) int i, j; -#if 0 - InitElementPropertiesStatic(); -#endif - /* important: after initialization in InitElementPropertiesStatic(), the elements are not again initialized to a default value; therefore all changes have to make sure that they leave the element with a defined @@ -3766,11 +3607,6 @@ void InitElementPropertiesEngine(int engine_version) /* set all special, combined or engine dependent element properties */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) { -#if 0 - for (j = EP_ACCESSIBLE_OVER; j < NUM_ELEMENT_PROPERTIES; j++) - SET_PROPERTY(i, j, FALSE); -#endif - /* ---------- INACTIVE ------------------------------------------------- */ SET_PROPERTY(i, EP_INACTIVE, (i >= EL_CHAR_START && i <= EL_CHAR_END)); @@ -3825,12 +3661,6 @@ void InitElementPropertiesEngine(int engine_version) !IS_DIGGABLE(i) && !IS_COLLECTIBLE(i))); -#if 0 - /* ---------- PROTECTED ------------------------------------------------ */ - if (IS_ACCESSIBLE_INSIDE(i)) - SET_PROPERTY(i, EP_PROTECTED, TRUE); -#endif - /* ---------- DRAGONFIRE_PROOF ----------------------------------------- */ if (IS_HISTORIC_SOLID(i) || i == EL_EXPLOSION) @@ -3845,20 +3675,9 @@ void InitElementPropertiesEngine(int engine_version) else if (engine_version < VERSION_IDENT(2,2,0,0)) SET_PROPERTY(i, EP_EXPLOSION_PROOF, IS_INDESTRUCTIBLE(i)); else -#if 1 SET_PROPERTY(i, EP_EXPLOSION_PROOF, (IS_INDESTRUCTIBLE(i) && (!IS_WALKABLE(i) || IS_PROTECTED(i)))); -#else -#if 1 - SET_PROPERTY(i, EP_EXPLOSION_PROOF, (IS_INDESTRUCTIBLE(i) && - !IS_WALKABLE_OVER(i) && - !IS_WALKABLE_UNDER(i))); -#else - SET_PROPERTY(i, EP_EXPLOSION_PROOF, (IS_INDESTRUCTIBLE(i) && - IS_PROTECTED(i))); -#endif -#endif if (IS_CUSTOM_ELEMENT(i)) { @@ -3882,25 +3701,6 @@ void InitElementPropertiesEngine(int engine_version) CAN_SMASH_ENEMIES(i) || CAN_SMASH_EVERYTHING(i))); -#if 0 - /* ---------- CAN_EXPLODE ---------------------------------------------- */ - SET_PROPERTY(i, EP_CAN_EXPLODE, (CAN_EXPLODE_BY_FIRE(i) || - CAN_EXPLODE_SMASHED(i) || - CAN_EXPLODE_IMPACT(i))); -#endif - -#if 0 - /* ---------- CAN_EXPLODE_3X3 ------------------------------------------ */ -#if 0 - SET_PROPERTY(i, EP_CAN_EXPLODE_3X3, (!CAN_EXPLODE_1X1(i) && - !CAN_EXPLODE_CROSS(i))); -#else - SET_PROPERTY(i, EP_CAN_EXPLODE_3X3, (CAN_EXPLODE(i) && - !CAN_EXPLODE_1X1(i) && - !CAN_EXPLODE_CROSS(i))); -#endif -#endif - /* ---------- CAN_EXPLODE_BY_FIRE -------------------------------------- */ SET_PROPERTY(i, EP_CAN_EXPLODE_BY_FIRE, (CAN_EXPLODE(i) && EXPLODES_BY_FIRE(i))); @@ -3949,6 +3749,16 @@ void InitElementPropertiesEngine(int engine_version) if (element_info[i].change_page[j].can_change) SET_PROPERTY(i, EP_CAN_CHANGE, TRUE); + /* ---------- HAS_ACTION ----------------------------------------------- */ + SET_PROPERTY(i, EP_HAS_ACTION, FALSE); /* default: has no action */ + for (j = 0; j < element_info[i].num_change_pages; j++) + if (element_info[i].change_page[j].has_action) + SET_PROPERTY(i, EP_HAS_ACTION, TRUE); + + /* ---------- CAN_CHANGE_OR_HAS_ACTION --------------------------------- */ + SET_PROPERTY(i, EP_CAN_CHANGE_OR_HAS_ACTION, (CAN_CHANGE(i) || + HAS_ACTION(i))); + /* ---------- GFX_CRUMBLED --------------------------------------------- */ #if 1 SET_PROPERTY(i, EP_GFX_CRUMBLED, @@ -3959,26 +3769,11 @@ void InitElementPropertiesEngine(int engine_version) SET_PROPERTY(i, EP_GFX_CRUMBLED, element_info[i].crumbled[ACTION_DEFAULT] != IMG_EMPTY); #endif - } - -#if 0 - /* determine inactive elements (used for engine main loop optimization) */ - for (i = 0; i < MAX_NUM_ELEMENTS; i++) - { - boolean active = FALSE; - for (j = 0; i < NUM_ELEMENT_PROPERTIES; j++) - { - if (HAS_PROPERTY(i, j)) - active = TRUE; - } - -#if 0 - if (!active) - SET_PROPERTY(i, EP_INACTIVE, TRUE); -#endif + /* ---------- EDITOR_CASCADE ------------------------------------------- */ + SET_PROPERTY(i, EP_EDITOR_CASCADE, (IS_EDITOR_CASCADE_ACTIVE(i) || + IS_EDITOR_CASCADE_INACTIVE(i))); } -#endif /* dynamically adjust element properties according to game engine version */ { @@ -4004,7 +3799,6 @@ void InitElementPropertiesEngine(int engine_version) engine_version > VERSION_IDENT(2,0,1,0))); } -#if 1 /* set default push delay values (corrected since version 3.0.7-1) */ if (engine_version < VERSION_IDENT(3,0,7,1)) { @@ -4049,8 +3843,6 @@ void InitElementPropertiesEngine(int engine_version) SET_PROPERTY(EL_SP_SNIKSNAK, EP_DONT_COLLIDE_WITH, FALSE); SET_PROPERTY(EL_SP_ELECTRON, EP_DONT_COLLIDE_WITH, FALSE); } -#endif - #endif /* this is needed because some graphics depend on element properties */ @@ -4139,6 +3931,10 @@ void Execute_Command(char *command) printf("# (The entries below are default and therefore commented out.)\n"); printf("\n"); + /* this is needed to be able to check element list for cascade elements */ + InitElementPropertiesStatic(); + InitElementPropertiesEngine(GAME_VERSION_ACTUAL); + PrintEditorElementList(); exit(0); @@ -4231,24 +4027,6 @@ void Execute_Command(char *command) while (*str_ptr != ' ' && *str_ptr != '\t' && *str_ptr != '\0') str_ptr++; } - -#if 0 - printf("level set == '%s'\n", global.autoplay_leveldir); - - if (global.autoplay_all) - printf("play all levels\n"); - else - { - printf("play the following levels:"); - - for (i = 0; i < MAX_TAPES_PER_SET; i++) - if (global.autoplay_level[i]) - printf(" %03d", i); - - printf("\n"); - } -#endif - } else if (strncmp(command, "convert ", 8) == 0) { @@ -4280,6 +4058,11 @@ static void InitSetup() options.verbose = TRUE; } +static void InitGameInfo() +{ + game.restart_level = FALSE; +} + static void InitPlayerInfo() { int i; @@ -4415,7 +4198,7 @@ static void InitArtworkConfig() for (i = 0; i < NUM_MUSIC_PREFIXES; i++) music_id_prefix[i] = music_prefix_info[i].prefix; - music_id_prefix[MAX_LEVELS] = NULL; + music_id_prefix[NUM_MUSIC_PREFIXES] = NULL; for (i = 0; i < NUM_ACTIONS; i++) action_id_suffix[i] = element_action_info[i].suffix; @@ -4516,8 +4299,6 @@ void InitGfx() DrawInitText(PROGRAM_COPYRIGHT_STRING, 50, FC_RED); DrawInitText("Loading graphics:", 120, FC_GREEN); - - InitTileClipmasks(); } void InitGfxBackground() @@ -4554,9 +4335,7 @@ void InitLevelArtworkInfo() static void InitImages() { -#if 1 setLevelArtworkDir(artwork.gfx_first); -#endif #if 0 printf("::: InitImages for '%s' ['%s', '%s'] ['%s', '%s']\n", @@ -4580,10 +4359,8 @@ static void InitSound(char *identifier) if (identifier == NULL) identifier = artwork.snd_current->identifier; -#if 1 /* set artwork path to send it to the sound server process */ setLevelArtworkDir(artwork.snd_first); -#endif InitReloadCustomSounds(identifier); ReinitializeSounds(); @@ -4594,10 +4371,8 @@ static void InitMusic(char *identifier) if (identifier == NULL) identifier = artwork.mus_current->identifier; -#if 1 /* set artwork path to send it to the sound server process */ setLevelArtworkDir(artwork.mus_first); -#endif InitReloadCustomMusic(identifier); ReinitializeMusic(); @@ -4710,12 +4485,7 @@ static char *getNewArtworkIdentifier(int type) artwork_current_identifier) != 0) artwork_new_identifier = artwork_current_identifier; -#if 1 *(ARTWORK_CURRENT_IDENTIFIER_PTR(artwork, type))= artwork_current_identifier; -#else - /* newer versions of gcc do not like this anymore :-/ */ - *(&(ARTWORK_CURRENT_IDENTIFIER(artwork, type))) = artwork_current_identifier; -#endif #if 0 if (type == ARTWORK_TYPE_GRAPHICS) @@ -4768,14 +4538,6 @@ void ReloadCustomArtwork(int force_reload) InitImages(); -#if 0 - printf("... '%s'\n", - leveldir_current->graphics_set); -#endif - - FreeTileClipmasks(); - InitTileClipmasks(); - redraw_screen = TRUE; } @@ -4838,6 +4600,7 @@ void OpenAll() InitSetup(); + InitGameInfo(); InitPlayerInfo(); InitArtworkInfo(); /* needed before loading gfx, sound & music */ InitArtworkConfig(); /* needed before forking sound child process */ @@ -4904,7 +4667,6 @@ void CloseAllAndExit(int exit_value) #endif FreeAllImages(); - FreeTileClipmasks(); #if defined(TARGET_SDL) if (network_server) /* terminate network server */ diff --git a/src/init.h b/src/init.h index 08f999e3..e3f88585 100644 --- a/src/init.h +++ b/src/init.h @@ -16,7 +16,6 @@ #include "main.h" -#if 1 #define setMoveIntoAcidProperty(l, e, v) \ (setBitfieldProperty(&(l)->can_move_into_acid_bits, \ EP_CAN_MOVE_INTO_ACID, e, v)) @@ -33,12 +32,6 @@ void setBitfieldProperty(int *, int, int, boolean); boolean getBitfieldProperty(int *, int, int); -#else - -void setMoveIntoAcidProperty(struct LevelInfo *, int, boolean); -boolean getMoveIntoAcidProperty(struct LevelInfo *, int); -#endif - void InitElementPropertiesStatic(void); void InitElementPropertiesEngine(int); diff --git a/src/libgame/gadgets.c b/src/libgame/gadgets.c index 5ac104c8..1b368c56 100644 --- a/src/libgame/gadgets.c +++ b/src/libgame/gadgets.c @@ -64,21 +64,6 @@ static int getNewGadgetID() return id; } -#if 0 -void DUMP_GADGET_MAP_STATE() -{ - struct GadgetInfo *gi = gadget_list_first_entry; - - while (gi != NULL) - { - printf("-XXX-1-> '%s': %s\n", - gi->info_text, (gi->mapped ? "mapped" : "not mapped")); - - gi = gi->next; - } -} -#endif - static struct GadgetInfo *getGadgetInfoFromMousePosition(int mx, int my) { struct GadgetInfo *gi; @@ -178,12 +163,16 @@ static void default_callback_action(void *ptr) static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) { + struct GadgetDesign *gd; int state = (pressed ? GD_BUTTON_PRESSED : GD_BUTTON_UNPRESSED); - struct GadgetDesign *gd = (!gi->active ? &gi->alt_design[state] : - gi->checked ? &gi->alt_design[state] : - &gi->design[state]); boolean redraw_selectbox = FALSE; + if (gi == NULL) + return; + + gd = (!gi->active ? &gi->alt_design[state] : + gi->checked ? &gi->alt_design[state] : &gi->design[state]); + switch (gi->type) { case GD_TYPE_NORMAL_BUTTON: @@ -701,6 +690,9 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) { int tag = first_tag; + if (gi == NULL) + return; + while (tag != GDI_END) { switch(tag) @@ -1164,6 +1156,9 @@ void ModifyGadget(struct GadgetInfo *gi, int first_tag, ...) void RedrawGadget(struct GadgetInfo *gi) { + if (gi == NULL) + return; + if (gi->mapped) DrawGadget(gi, gi->state, gi->direct_draw); } @@ -1452,14 +1447,9 @@ boolean HandleGadgets(int mx, int my, int button) insideSelectboxLine(new_gi, mx, my)); /* if mouse button pressed outside text or selectbox gadget, deactivate it */ -#if 1 if (anyTextGadgetActive() && (gadget_pressed_off_borders || (gadget_pressed_inside_select_line && !mouse_inside_select_area))) -#else - if (anyTextGadgetActive() && - button != 0 && !motion_status && new_gi != last_gi) -#endif { struct GadgetInfo *gi = last_gi; boolean gadget_changed = (gi->event_mask & GD_EVENT_TEXT_LEAVING); @@ -1483,13 +1473,8 @@ boolean HandleGadgets(int mx, int my, int button) gi->event.type = GD_EVENT_TEXT_LEAVING; -#if 1 if (gadget_changed && !(gi->type & GD_TYPE_SELECTBOX)) gi->callback_action(gi); -#else - if (gi->event_mask & GD_EVENT_TEXT_LEAVING) - gi->callback_action(gi); -#endif last_gi = NULL; @@ -1513,19 +1498,8 @@ boolean HandleGadgets(int mx, int my, int button) /* when handling selectbox, set additional state values */ if (gadget_released_inside && (last_gi->type & GD_TYPE_SELECTBOX)) { - struct GadgetInfo *gi = last_gi; - -#if 1 - gadget_released_inside_select_line = insideSelectboxLine(gi, mx, my); - gadget_released_inside_select_area = insideSelectboxArea(gi, mx, my); -#else - gadget_released_inside_select_line = - (mx >= gi->x && mx < gi->x + gi->width && - my >= gi->y && my < gi->y + gi->height); - gadget_released_inside_select_area = - (mx >= gi->selectbox.x && mx < gi->selectbox.x + gi->selectbox.width && - my >= gi->selectbox.y && my < gi->selectbox.y + gi->selectbox.height); -#endif + gadget_released_inside_select_line = insideSelectboxLine(last_gi, mx, my); + gadget_released_inside_select_area = insideSelectboxArea(last_gi, mx, my); } else { @@ -1548,7 +1522,6 @@ boolean HandleGadgets(int mx, int my, int button) /* if mouse button released, no gadget needs to be handled anymore */ if (gadget_released) { -#if 1 if (gi->type & GD_TYPE_SELECTBOX && (mouse_released_where_pressed || !gadget_released_inside_select_area)) /* selectbox stays open */ @@ -1557,12 +1530,6 @@ boolean HandleGadgets(int mx, int my, int button) pressed_mx = 0; pressed_my = 0; } -#else - if (gi->type & GD_TYPE_SELECTBOX && - (gadget_released_inside_select_line || - gadget_released_off_borders)) /* selectbox stays open */ - gi->selectbox.stay_open = TRUE; -#endif else if (!(gi->type & GD_TYPE_TEXT_INPUT || gi->type & GD_TYPE_TEXT_AREA)) /* text input stays open */ last_gi = NULL; @@ -1847,21 +1814,12 @@ boolean HandleGadgets(int mx, int my, int button) if (gi->type & GD_TYPE_SELECTBOX) { -#if 1 if (mouse_released_where_pressed || !gadget_released_inside_select_area) /* selectbox stays open */ { deactivate_gadget = FALSE; gadget_changed = FALSE; } -#else - if (gadget_released_inside_select_line || - gadget_released_off_borders) /* selectbox stays open */ - { - deactivate_gadget = FALSE; - gadget_changed = FALSE; - } -#endif else if (gi->selectbox.index != gi->selectbox.current_index) gi->selectbox.index = gi->selectbox.current_index; else @@ -1876,15 +1834,10 @@ boolean HandleGadgets(int mx, int my, int button) gi->state = GD_BUTTON_UNPRESSED; gi->event.type = GD_EVENT_RELEASED; -#if 1 if ((gi->event_mask & GD_EVENT_RELEASED) && gadget_changed) { gi->callback_action(gi); } -#else - if ((gi->event_mask & GD_EVENT_RELEASED) && deactivate_gadget) - gi->callback_action(gi); -#endif } if (gadget_released_off_borders) @@ -1968,13 +1921,8 @@ boolean HandleGadgetsKeyInput(Key key) last_gi = NULL; } -#if 1 if (gadget_changed) gi->callback_action(gi); -#else - if (gi->event_mask & GD_EVENT_TEXT_RETURN) - gi->callback_action(gi); -#endif } else if (gi->type & GD_TYPE_TEXT_INPUT) /* only valid for text input */ { diff --git a/src/libgame/image.c b/src/libgame/image.c index 09ec64f6..719c662a 100644 --- a/src/libgame/image.c +++ b/src/libgame/image.c @@ -31,13 +31,6 @@ Image *newImage(unsigned int width, unsigned int height, unsigned int depth) unsigned int bytes_per_pixel = (depth + 7) / 8; int i; -#if 0 - if (depth > 8) - Error(ERR_EXIT, "images with more than 256 colors are not supported"); - - depth = 8; -#endif - image = checked_calloc(sizeof(Image)); image->data = checked_calloc(width * height * bytes_per_pixel); image->width = width; @@ -836,7 +829,7 @@ static void *Load_PCX(char *filename) ImageInfo *img_info; #if 0 - printf("loading PCX file '%s'\n", filename); + printf("::: loading PCX file '%s'\n", filename); #endif img_info = checked_calloc(sizeof(ImageInfo)); @@ -1036,7 +1029,7 @@ void InitImageList(struct ConfigInfo *config_list, int num_file_list_entries, void ReloadCustomImages() { #if 0 - printf("DEBUG: reloading images '%s' ...\n", artwork.gfx_current_identifier); + printf("::: reloading images '%s' ...\n", artwork.gfx_current_identifier); #endif LoadArtworkConfig(image_info); @@ -1054,16 +1047,6 @@ void CreateImageWithSmallImages(int pos, int zoom_factor) img_info->contains_small_images = TRUE; img_info->scaled_up = TRUE; - -#if 0 - if (zoom_factor) - printf("CreateImageWithSmallImages: '%s' zoomed by factor %d\n", - img_info->source_filename, zoom_factor); -#endif - -#if 0 - printf("CreateImageWithSmallImages: '%s' done\n", img_info->source_filename); -#endif } void FreeAllImages() diff --git a/src/libgame/misc.c b/src/libgame/misc.c index 3881d202..bcd8197c 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -52,6 +52,12 @@ void printf_line(char *line_string, int line_length) fprintf_line(stdout, line_string, line_length); } +void printf_line_with_prefix(char *prefix, char *line_string, int line_length) +{ + fprintf(stdout, "%s", prefix); + fprintf_line(stdout, line_string, line_length); +} + /* int2str() returns a number converted to a string; the used memory is static, but will be overwritten by later calls, @@ -206,14 +212,6 @@ static void sleep_milliseconds(unsigned long milliseconds_delay) { boolean do_busy_waiting = (milliseconds_delay < 5 ? TRUE : FALSE); -#if 0 -#if defined(PLATFORM_MSDOS) - /* don't use select() to perform waiting operations under DOS - environment; always use a busy loop for waiting instead */ - do_busy_waiting = TRUE; -#endif -#endif - if (do_busy_waiting) { /* we want to wait only a few ms -- if we assume that we have a @@ -741,10 +739,8 @@ void GetOptions(char *argv[], void (*print_usage_function)(void)) if (option_arg == next_option) options_left++; -#if 1 /* when doing batch processing, always enable verbose mode (warnings) */ options.verbose = TRUE; -#endif } else if (*option == '-') { @@ -935,6 +931,25 @@ inline void swap_number_pairs(int *x1, int *y1, int *x2, int *y2) *y2 = help_y; } +/* the "put" variants of the following file access functions check for the file + pointer being != NULL and return the number of bytes they have or would have + written; this allows for chunk writing functions to first determine the size + of the (not yet written) chunk, write the correct chunk size and finally + write the chunk itself */ + +int getFile8BitInteger(FILE *file) +{ + return fgetc(file); +} + +int putFile8BitInteger(FILE *file, int value) +{ + if (file != NULL) + fputc(value, file); + + return 1; +} + int getFile16BitInteger(FILE *file, int byte_order) { if (byte_order == BYTE_ORDER_BIG_ENDIAN) @@ -945,18 +960,23 @@ int getFile16BitInteger(FILE *file, int byte_order) (fgetc(file) << 8)); } -void putFile16BitInteger(FILE *file, int value, int byte_order) +int putFile16BitInteger(FILE *file, int value, int byte_order) { - if (byte_order == BYTE_ORDER_BIG_ENDIAN) + if (file != NULL) { - fputc((value >> 8) & 0xff, file); - fputc((value >> 0) & 0xff, file); - } - else /* BYTE_ORDER_LITTLE_ENDIAN */ - { - fputc((value >> 0) & 0xff, file); - fputc((value >> 8) & 0xff, file); + if (byte_order == BYTE_ORDER_BIG_ENDIAN) + { + fputc((value >> 8) & 0xff, file); + fputc((value >> 0) & 0xff, file); + } + else /* BYTE_ORDER_LITTLE_ENDIAN */ + { + fputc((value >> 0) & 0xff, file); + fputc((value >> 8) & 0xff, file); + } } + + return 2; } int getFile32BitInteger(FILE *file, int byte_order) @@ -973,22 +993,27 @@ int getFile32BitInteger(FILE *file, int byte_order) (fgetc(file) << 24)); } -void putFile32BitInteger(FILE *file, int value, int byte_order) +int putFile32BitInteger(FILE *file, int value, int byte_order) { - if (byte_order == BYTE_ORDER_BIG_ENDIAN) + if (file != NULL) { - fputc((value >> 24) & 0xff, file); - fputc((value >> 16) & 0xff, file); - fputc((value >> 8) & 0xff, file); - fputc((value >> 0) & 0xff, file); - } - else /* BYTE_ORDER_LITTLE_ENDIAN */ - { - fputc((value >> 0) & 0xff, file); - fputc((value >> 8) & 0xff, file); - fputc((value >> 16) & 0xff, file); - fputc((value >> 24) & 0xff, file); + if (byte_order == BYTE_ORDER_BIG_ENDIAN) + { + fputc((value >> 24) & 0xff, file); + fputc((value >> 16) & 0xff, file); + fputc((value >> 8) & 0xff, file); + fputc((value >> 0) & 0xff, file); + } + else /* BYTE_ORDER_LITTLE_ENDIAN */ + { + fputc((value >> 0) & 0xff, file); + fputc((value >> 8) & 0xff, file); + fputc((value >> 16) & 0xff, file); + fputc((value >> 24) & 0xff, file); + } } + + return 4; } boolean getFileChunk(FILE *file, char *chunk_name, int *chunk_size, @@ -1045,6 +1070,22 @@ void putFileVersion(FILE *file, int version) fputc(version_build, file); } +void ReadBytesFromFile(FILE *file, byte *buffer, unsigned long bytes) +{ + int i; + + for(i = 0; i < bytes && !feof(file); i++) + buffer[i] = fgetc(file); +} + +void WriteBytesToFile(FILE *file, byte *buffer, unsigned long bytes) +{ + int i; + + for(i = 0; i < bytes; i++) + fputc(buffer[i], file); +} + void ReadUnusedBytesFromFile(FILE *file, unsigned long bytes) { while (bytes-- && !feof(file)) @@ -1484,10 +1525,6 @@ void addNodeToList(ListNode **node_first, char *key, void *content) { ListNode *node_new = newListNode(); -#if 0 - printf("LIST: adding node with key '%s'\n", key); -#endif - node_new->key = getStringCopy(key); node_new->content = content; node_new->next = *node_first; @@ -1500,17 +1537,8 @@ void deleteNodeFromList(ListNode **node_first, char *key, if (node_first == NULL || *node_first == NULL) return; -#if 0 - printf("[CHECKING LIST KEY '%s' == '%s']\n", - (*node_first)->key, key); -#endif - if (strcmp((*node_first)->key, key) == 0) { -#if 0 - printf("[DELETING LIST ENTRY]\n"); -#endif - free((*node_first)->key); if (destructor_function) destructor_function((*node_first)->content); @@ -1560,10 +1588,6 @@ boolean fileExists(char *filename) if (filename == NULL) return FALSE; -#if 0 - printf("checking file '%s'\n", filename); -#endif - return (access(filename, F_OK) == 0); } @@ -1720,7 +1744,7 @@ static boolean string_has_parameter(char *s, char *s_contained) return string_has_parameter(substring, s_contained); } -int get_parameter_value(char *suffix, char *value_raw, int type) +int get_parameter_value(char *value_raw, char *suffix, int type) { char *value = getStringToLower(value_raw); int result = 0; /* probably a save default value */ @@ -1730,18 +1754,20 @@ int get_parameter_value(char *suffix, char *value_raw, int type) result = (strcmp(value, "left") == 0 ? MV_LEFT : strcmp(value, "right") == 0 ? MV_RIGHT : strcmp(value, "up") == 0 ? MV_UP : - strcmp(value, "down") == 0 ? MV_DOWN : MV_NO_MOVING); + strcmp(value, "down") == 0 ? MV_DOWN : MV_NONE); } else if (strcmp(suffix, ".anim_mode") == 0) { - result = (string_has_parameter(value, "none") ? ANIM_NONE : - string_has_parameter(value, "loop") ? ANIM_LOOP : - string_has_parameter(value, "linear") ? ANIM_LINEAR : - string_has_parameter(value, "pingpong") ? ANIM_PINGPONG : - string_has_parameter(value, "pingpong2") ? ANIM_PINGPONG2 : - string_has_parameter(value, "random") ? ANIM_RANDOM : - string_has_parameter(value, "horizontal") ? ANIM_HORIZONTAL : - string_has_parameter(value, "vertical") ? ANIM_VERTICAL : + result = (string_has_parameter(value, "none") ? ANIM_NONE : + string_has_parameter(value, "loop") ? ANIM_LOOP : + string_has_parameter(value, "linear") ? ANIM_LINEAR : + string_has_parameter(value, "pingpong") ? ANIM_PINGPONG : + string_has_parameter(value, "pingpong2") ? ANIM_PINGPONG2 : + string_has_parameter(value, "random") ? ANIM_RANDOM : + string_has_parameter(value, "ce_value") ? ANIM_CE_VALUE : + string_has_parameter(value, "ce_score") ? ANIM_CE_SCORE : + string_has_parameter(value, "horizontal") ? ANIM_HORIZONTAL : + string_has_parameter(value, "vertical") ? ANIM_VERTICAL : ANIM_DEFAULT); if (string_has_parameter(value, "reverse")) @@ -1771,7 +1797,7 @@ int get_auto_parameter_value(char *token, char *value_raw) if (suffix == NULL) suffix = token; - return get_parameter_value(suffix, value_raw, TYPE_INTEGER); + return get_parameter_value(value_raw, suffix, TYPE_INTEGER); } static void FreeCustomArtworkList(struct ArtworkListInfo *, @@ -1890,11 +1916,6 @@ static boolean token_suffix_match(char *token, char *suffix, int start_pos) int len_token = strlen(token); int len_suffix = strlen(suffix); -#if 0 - if (IS_PARENT_PROCESS()) - printf(":::::::::: check '%s' for '%s' ::::::::::\n", token, suffix); -#endif - if (start_pos < 0) /* compare suffix from end of string */ start_pos += len_token; @@ -1937,16 +1958,6 @@ static void read_token_parameters(SetupFileHash *setup_file_hash, /* mark config file token as well known from default config */ setHashEntry(setup_file_hash, file_list_entry->token, known_token_value); } -#if 0 - else - { - if (strcmp(file_list_entry->filename, - file_list_entry->default_filename) != 0) - printf("___ resetting '%s' to default\n", file_list_entry->token); - - setString(&file_list_entry->filename, file_list_entry->default_filename); - } -#endif /* check for config tokens that can be build by base token and suffixes */ for (i = 0; suffix_list[i].token != NULL; i++) @@ -1976,11 +1987,6 @@ static void add_dynamic_file_list_entry(struct FileInfo **list, struct FileInfo *new_list_entry; int parameter_array_size = num_suffix_list_entries * sizeof(char *); -#if 0 - if (IS_PARENT_PROCESS()) - printf("===> found dynamic definition '%s'\n", token); -#endif - (*num_list_entries)++; *list = checked_realloc(*list, *num_list_entries * sizeof(struct FileInfo)); new_list_entry = &(*list)[*num_list_entries - 1]; @@ -2042,10 +2048,6 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info, if (filename == NULL) return; -#if 0 - printf("::: LoadArtworkConfigFromFilename: '%s'\n", filename); -#endif - if ((setup_file_hash = loadSetupFileHash(filename)) == NULL) return; @@ -2064,7 +2066,6 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info, /* at this point, we do not need the setup file hash anymore -- free it */ freeSetupFileHash(setup_file_hash); -#if 1 /* map deprecated to current tokens (using prefix match and replace) */ BEGIN_HASH_ITERATION(valid_file_hash, itr) { @@ -2085,7 +2086,6 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info, } } END_HASH_ITERATION(valid_file_hash, itr) -#endif /* read parameters for all known config file tokens */ for (i = 0; i < num_file_list_entries; i++) @@ -2143,16 +2143,6 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info, parameter_suffix_found = TRUE; } -#if 0 - if (IS_PARENT_PROCESS()) - { - if (parameter_suffix_found) - printf("---> skipping token '%s' (parameter token)\n", token); - else - printf("---> examining token '%s': search prefix ...\n", token); - } -#endif - if (parameter_suffix_found) continue; @@ -2491,25 +2481,14 @@ static void deleteArtworkListEntry(struct ArtworkListInfo *artwork_info, { char *filename = (*listnode)->source_filename; -#if 0 - printf("[decrementing reference counter of artwork '%s']\n", filename); -#endif - if (--(*listnode)->num_references <= 0) - { -#if 0 - printf("[deleting artwork '%s']\n", filename); -#endif - deleteNodeFromList(&artwork_info->content_list, filename, artwork_info->free_artwork); - } *listnode = NULL; } } -#if 1 static void replaceArtworkListEntry(struct ArtworkListInfo *artwork_info, struct ListNodeInfo **listnode, struct FileInfo *file_list_entry) @@ -2525,12 +2504,6 @@ static void replaceArtworkListEntry(struct ArtworkListInfo *artwork_info, char *basename = file_list_entry->filename; char *filename = getCustomArtworkFilename(basename, artwork_info->type); -#if 0 - if (strcmp(file_list_entry->token, "background.DOOR") == 0) - printf("::: replaceArtworkListEntry: '%s' => '%s'\n", - basename, filename); -#endif - if (filename == NULL) { Error(ERR_WARN, "cannot find artwork file '%s'", basename); @@ -2591,110 +2564,6 @@ static void replaceArtworkListEntry(struct ArtworkListInfo *artwork_info, return; } -#if 0 - if (strcmp(file_list_entry->token, "background.DOOR") == 0) - printf("::: replaceArtworkListEntry: LOAD IT'\n"); -#endif - -#if 0 - printf("::: %s: '%s'\n", init_text[artwork_info->type], basename); -#endif - - DrawInitText(init_text[artwork_info->type], 120, FC_GREEN); - DrawInitText(basename, 150, FC_YELLOW); - - if ((*listnode = artwork_info->load_artwork(filename)) != NULL) - { -#if 0 - printf("[adding new artwork '%s']\n", filename); -#endif - - (*listnode)->num_references = 1; - addNodeToList(&artwork_info->content_list, (*listnode)->source_filename, - *listnode); - } - else - { - int error_mode = ERR_WARN; - -#if 1 - /* we can get away without sounds and music, but not without graphics */ - if (artwork_info->type == ARTWORK_TYPE_GRAPHICS) - error_mode = ERR_EXIT; -#endif - - Error(error_mode, "cannot load artwork file '%s'", basename); - return; - } -} - -#else - -static void replaceArtworkListEntry(struct ArtworkListInfo *artwork_info, - struct ListNodeInfo **listnode, - char *basename) -{ - char *init_text[] = - { - "Loading graphics:", - "Loading sounds:", - "Loading music:" - }; - - ListNode *node; - char *filename = getCustomArtworkFilename(basename, artwork_info->type); - - if (filename == NULL) - { - int error_mode = ERR_WARN; - -#if 1 - /* !!! NEW ARTWORK FALLBACK CODE !!! NEARLY UNTESTED !!! */ - /* before failing, try fallback to default artwork */ -#else - /* we can get away without sounds and music, but not without graphics */ - if (*listnode == NULL && artwork_info->type == ARTWORK_TYPE_GRAPHICS) - error_mode = ERR_EXIT; -#endif - - Error(error_mode, "cannot find artwork file '%s'", basename); - return; - } - - /* check if the old and the new artwork file are the same */ - if (*listnode && strcmp((*listnode)->source_filename, filename) == 0) - { - /* The old and new artwork are the same (have the same filename and path). - This usually means that this artwork does not exist in this artwork set - and a fallback to the existing artwork is done. */ - -#if 0 - printf("[artwork '%s' already exists (same list entry)]\n", filename); -#endif - - return; - } - - /* delete existing artwork file entry */ - deleteArtworkListEntry(artwork_info, listnode); - - /* check if the new artwork file already exists in the list of artworks */ - if ((node = getNodeFromKey(artwork_info->content_list, filename)) != NULL) - { -#if 0 - printf("[artwork '%s' already exists (other list entry)]\n", filename); -#endif - - *listnode = (struct ListNodeInfo *)node->content; - (*listnode)->num_references++; - - return; - } - -#if 0 - printf("::: %s: '%s'\n", init_text[artwork_info->type], basename); -#endif - DrawInitText(init_text[artwork_info->type], 120, FC_GREEN); DrawInitText(basename, 150, FC_YELLOW); @@ -2712,19 +2581,15 @@ static void replaceArtworkListEntry(struct ArtworkListInfo *artwork_info, { int error_mode = ERR_WARN; -#if 1 /* we can get away without sounds and music, but not without graphics */ if (artwork_info->type == ARTWORK_TYPE_GRAPHICS) error_mode = ERR_EXIT; -#endif Error(error_mode, "cannot load artwork file '%s'", basename); return; } } -#endif -#if 1 static void LoadCustomArtwork(struct ArtworkListInfo *artwork_info, struct ListNodeInfo **listnode, struct FileInfo *file_list_entry) @@ -2733,12 +2598,6 @@ static void LoadCustomArtwork(struct ArtworkListInfo *artwork_info, printf("GOT CUSTOM ARTWORK FILE '%s'\n", filename); #endif -#if 0 - if (strcmp(file_list_entry->token, "background.DOOR") == 0) - printf("::: -> '%s' -> '%s'\n", - file_list_entry->token, file_list_entry->filename); -#endif - if (strcmp(file_list_entry->filename, UNDEFINED_FILENAME) == 0) { deleteArtworkListEntry(artwork_info, listnode); @@ -2748,86 +2607,6 @@ static void LoadCustomArtwork(struct ArtworkListInfo *artwork_info, replaceArtworkListEntry(artwork_info, listnode, file_list_entry); } -#else - -static void LoadCustomArtwork(struct ArtworkListInfo *artwork_info, - struct ListNodeInfo **listnode, - char *basename) -{ -#if 0 - printf("GOT CUSTOM ARTWORK FILE '%s'\n", filename); -#endif - - if (strcmp(basename, UNDEFINED_FILENAME) == 0) - { - deleteArtworkListEntry(artwork_info, listnode); - return; - } - - replaceArtworkListEntry(artwork_info, listnode, basename); -} -#endif - -#if 1 -static void LoadArtworkToList(struct ArtworkListInfo *artwork_info, - struct ListNodeInfo **listnode, - struct FileInfo *file_list_entry) -{ -#if 0 - if (artwork_info->artwork_list == NULL || - list_pos >= artwork_info->num_file_list_entries) - return; -#endif - -#if 0 - printf("loading artwork '%s' ... [%d]\n", - file_list_entry->filename, getNumNodes(artwork_info->content_list)); -#endif - -#if 1 - LoadCustomArtwork(artwork_info, listnode, file_list_entry); -#else - LoadCustomArtwork(artwork_info, &artwork_info->artwork_list[list_pos], - basename); -#endif - -#if 0 - printf("loading artwork '%s' done [%d]\n", - basename, getNumNodes(artwork_info->content_list)); -#endif -} - -#else - -static void LoadArtworkToList(struct ArtworkListInfo *artwork_info, - struct ListNodeInfo **listnode, - char *basename, int list_pos) -{ -#if 0 - if (artwork_info->artwork_list == NULL || - list_pos >= artwork_info->num_file_list_entries) - return; -#endif - -#if 0 - printf("loading artwork '%s' ... [%d]\n", - basename, getNumNodes(artwork_info->content_list)); -#endif - -#if 1 - LoadCustomArtwork(artwork_info, listnode, basename); -#else - LoadCustomArtwork(artwork_info, &artwork_info->artwork_list[list_pos], - basename); -#endif - -#if 0 - printf("loading artwork '%s' done [%d]\n", - basename, getNumNodes(artwork_info->content_list)); -#endif -} -#endif - void ReloadCustomArtworkList(struct ArtworkListInfo *artwork_info) { struct FileInfo *file_list = artwork_info->file_list; @@ -2837,86 +2616,13 @@ void ReloadCustomArtworkList(struct ArtworkListInfo *artwork_info) artwork_info->num_dynamic_file_list_entries; int i; -#if 0 - printf("DEBUG: reloading %d static artwork files ...\n", - num_file_list_entries); -#endif - for (i = 0; i < num_file_list_entries; i++) - { -#if 0 - if (strcmp(file_list[i].token, "background.DOOR") == 0) - printf("::: '%s' -> '%s'\n", file_list[i].token, file_list[i].filename); -#endif - -#if 1 - LoadArtworkToList(artwork_info, &artwork_info->artwork_list[i], + LoadCustomArtwork(artwork_info, &artwork_info->artwork_list[i], &file_list[i]); -#else - LoadArtworkToList(artwork_info, &artwork_info->artwork_list[i], - file_list[i].filename, i); -#endif - -#if 0 - if (strcmp(file_list[i].token, "background.DOOR") == 0) - { - Bitmap *bitmap = getBitmapFromImageID(i); - - printf("::: BITMAP: %08lx\n", bitmap); - -#if 0 - BlitBitmap(bitmap, window, 0, 0, 100, 280, 0, 0); -#endif - } -#endif - -#if 0 - /* !!! NEW ARTWORK FALLBACK CODE !!! NEARLY UNTESTED !!! */ - if (artwork_info->artwork_list[i] == NULL && - strcmp(file_list[i].filename, UNDEFINED_FILENAME) != 0 && - strcmp(file_list[i].default_filename, file_list[i].filename) != 0 && - strcmp(file_list[i].default_filename, UNDEFINED_FILENAME) != 0) - { - Error(ERR_WARN, "trying default artwork file '%s'", - file_list[i].default_filename); - - LoadArtworkToList(artwork_info, &artwork_info->artwork_list[i], - file_list[i].default_filename, i); - - /* even the fallback to default artwork was not successful -- fail now */ - if (artwork_info->artwork_list[i] == NULL && - artwork_info->type == ARTWORK_TYPE_GRAPHICS) - Error(ERR_EXIT, "cannot find artwork file '%s' or default file '%s'", - file_list[i].filename, file_list[i].default_filename); - - file_list[i].fallback_to_default = TRUE; - } -#endif - } - -#if 0 - printf("DEBUG: reloading %d dynamic artwork files ...\n", - num_dynamic_file_list_entries); -#endif for (i = 0; i < num_dynamic_file_list_entries; i++) - { -#if 1 - LoadArtworkToList(artwork_info, &artwork_info->dynamic_artwork_list[i], + LoadCustomArtwork(artwork_info, &artwork_info->dynamic_artwork_list[i], &dynamic_file_list[i]); -#else - LoadArtworkToList(artwork_info, &artwork_info->dynamic_artwork_list[i], - dynamic_file_list[i].filename, i); -#endif - -#if 0 - printf("::: '%s', '0x%08x'\n", - dynamic_file_list[i].filename, - dynamic_file_list[i].default_filename); -#endif - - /* dynamic artwork does not have default filename! */ - } #if 0 dumpList(artwork_info->content_list); @@ -2945,21 +2651,11 @@ void FreeCustomArtworkLists(struct ArtworkListInfo *artwork_info) if (artwork_info == NULL) return; -#if 0 - printf("%s: FREEING ARTWORK ...\n", - IS_CHILD_PROCESS() ? "CHILD" : "PARENT"); -#endif - FreeCustomArtworkList(artwork_info, &artwork_info->artwork_list, &artwork_info->num_file_list_entries); FreeCustomArtworkList(artwork_info, &artwork_info->dynamic_artwork_list, &artwork_info->num_dynamic_file_list_entries); - -#if 0 - printf("%s: FREEING ARTWORK -- DONE\n", - IS_CHILD_PROCESS() ? "CHILD" : "PARENT"); -#endif } diff --git a/src/libgame/misc.h b/src/libgame/misc.h index b89be4e8..c69d5f5c 100644 --- a/src/libgame/misc.h +++ b/src/libgame/misc.h @@ -69,6 +69,7 @@ void fprintf_line(FILE *, char *, int); void printf_line(char *, int); +void printf_line_with_prefix(char *, char *, int); char *int2str(int, int); char *i_to_a(unsigned int); int log_2(unsigned int); @@ -118,19 +119,26 @@ void checked_free(void *); inline void swap_numbers(int *, int *); inline void swap_number_pairs(int *, int *, int *, int *); +int getFile8BitInteger(FILE *); +int putFile8BitInteger(FILE *, int); int getFile16BitInteger(FILE *, int); -void putFile16BitInteger(FILE *, int, int); +int putFile16BitInteger(FILE *, int, int); int getFile32BitInteger(FILE *, int); -void putFile32BitInteger(FILE *, int, int); +int putFile32BitInteger(FILE *, int, int); + boolean getFileChunk(FILE *, char *, int *, int); void putFileChunk(FILE *, char *, int, int); int getFileVersion(FILE *); void putFileVersion(FILE *, int); + +void ReadBytesFromFile(FILE *, byte *, unsigned long); +void WriteBytesToFile(FILE *, byte *, unsigned long); + void ReadUnusedBytesFromFile(FILE *, unsigned long); void WriteUnusedBytesToFile(FILE *, unsigned long); -#define getFile8Bit(f) fgetc(f) -#define putFile8Bit(f,x) fputc(x, f) +#define getFile8Bit(f) getFile8BitInteger(f) +#define putFile8Bit(f,x) putFile8BitInteger(f,x) #define getFile16BitBE(f) getFile16BitInteger(f,BYTE_ORDER_BIG_ENDIAN) #define getFile16BitLE(f) getFile16BitInteger(f,BYTE_ORDER_LITTLE_ENDIAN) #define putFile16BitBE(f,x) putFile16BitInteger(f,x,BYTE_ORDER_BIG_ENDIAN) @@ -139,6 +147,7 @@ void WriteUnusedBytesToFile(FILE *, unsigned long); #define getFile32BitLE(f) getFile32BitInteger(f,BYTE_ORDER_LITTLE_ENDIAN) #define putFile32BitBE(f,x) putFile32BitInteger(f,x,BYTE_ORDER_BIG_ENDIAN) #define putFile32BitLE(f,x) putFile32BitInteger(f,x,BYTE_ORDER_LITTLE_ENDIAN) + #define getFileChunkBE(f,s,x) getFileChunk(f,s,x,BYTE_ORDER_BIG_ENDIAN) #define getFileChunkLE(f,s,x) getFileChunk(f,s,x,BYTE_ORDER_LITTLE_ENDIAN) #define putFileChunkBE(f,s,x) putFileChunk(f,s,x,BYTE_ORDER_BIG_ENDIAN) diff --git a/src/libgame/pcx.c b/src/libgame/pcx.c index 5fdf6f3e..8bf4d6c1 100644 --- a/src/libgame/pcx.c +++ b/src/libgame/pcx.c @@ -53,52 +53,6 @@ struct PCX_Header /* global PCX error value */ int errno_pcx = PCX_Success; -#if 0 -static byte *PCX_ReadBitmap(Image *image, byte *buffer_ptr, byte *buffer_last) -{ - /* Run Length Encoding: If the two high bits are set, - * then the low 6 bits contain a repeat count, and the byte to - * repeat is the next byte in the file. If the two high bits are - * not set, then this is the byte to write. - */ - - unsigned int bytes_per_pixel = (image->depth + 7) / 8; - register byte *bitmap_ptr, *bitmap_last; - register byte value, count; - - bitmap_ptr = image->data; - bitmap_last = bitmap_ptr + (image->width * image->height * bytes_per_pixel); - - while (bitmap_ptr < bitmap_last && buffer_ptr < buffer_last) - { - value = *buffer_ptr++; - - if ((value & 0xc0) == 0xc0) /* this is a repeat count byte */ - { - count = value & 0x3f; /* extract repeat count from byte */ - value = *buffer_ptr++; /* next byte is value to repeat */ - - for (; count && bitmap_ptr < bitmap_last; count--) - *bitmap_ptr++ = value; - - if (count) /* repeat count spans end of bitmap */ - return NULL; - } - else - *bitmap_ptr++ = value; - - image->rgb.color_used[value] = TRUE; - } - - /* check if end of buffer was reached before end of bitmap */ - if (bitmap_ptr < bitmap_last) - return NULL; - - /* return current buffer position for next decoding function */ - return buffer_ptr; -} -#endif - static boolean PCX_ReadBitmap(FILE *file, struct PCX_Header *pcx, Image *image) { int width = image->width; @@ -203,35 +157,6 @@ static boolean PCX_ReadBitmap(FILE *file, struct PCX_Header *pcx, Image *image) return TRUE; } -#if 0 -static byte *PCX_ReadColormap(Image *image,byte *buffer_ptr, byte *buffer_last) -{ - int i, magic; - - /* read colormap magic byte */ - magic = *buffer_ptr++; - - /* check magic colormap header byte */ - if (magic != PCX_256COLORS_MAGIC) - return NULL; - - /* check if enough bytes left for a complete colormap */ - if (buffer_ptr + PCX_COLORMAP_SIZE > buffer_last) - return NULL; - - /* read 256 colors from PCX colormap */ - for (i = 0; i < PCX_MAXCOLORS; i++) - { - image->rgb.red[i] = *buffer_ptr++ << 8; - image->rgb.green[i] = *buffer_ptr++ << 8; - image->rgb.blue[i] = *buffer_ptr++ << 8; - } - - /* return current buffer position for next decoding function */ - return buffer_ptr; -} -#endif - static boolean PCX_ReadColormap(FILE *file,struct PCX_Header *pcx,Image *image) { int pcx_depth = pcx->bits_per_pixel * pcx->color_planes; diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c index b127c784..e27c822e 100644 --- a/src/libgame/sdl.c +++ b/src/libgame/sdl.c @@ -248,11 +248,6 @@ inline void SDLFillRectangle(Bitmap *dst_bitmap, int x, int y, { Bitmap *real_dst_bitmap = (dst_bitmap == window ? backbuffer : dst_bitmap); SDL_Rect rect; -#if 0 - unsigned int color_r = (color >> 16) & 0xff; - unsigned int color_g = (color >> 8) & 0xff; - unsigned int color_b = (color >> 0) & 0xff; -#endif #ifdef FULLSCREEN_BUG if (dst_bitmap == backbuffer || dst_bitmap == window) @@ -267,13 +262,7 @@ inline void SDLFillRectangle(Bitmap *dst_bitmap, int x, int y, rect.w = width; rect.h = height; -#if 1 SDL_FillRect(real_dst_bitmap->surface, &rect, color); -#else - SDL_FillRect(real_dst_bitmap->surface, &rect, - SDL_MapRGB(real_dst_bitmap->surface->format, - color_r, color_g, color_b)); -#endif if (dst_bitmap == window) SDL_UpdateRect(backbuffer->surface, x, y, width, height); @@ -284,11 +273,6 @@ inline void SDLDrawSimpleLine(Bitmap *dst_bitmap, int from_x, int from_y, { SDL_Surface *surface = dst_bitmap->surface; SDL_Rect rect; -#if 0 - unsigned int color_r = (color >> 16) & 0xff; - unsigned int color_g = (color >> 8) & 0xff; - unsigned int color_b = (color >> 0) & 0xff; -#endif if (from_x > to_x) swap_numbers(&from_x, &to_x); @@ -309,12 +293,7 @@ inline void SDLDrawSimpleLine(Bitmap *dst_bitmap, int from_x, int from_y, } #endif -#if 1 SDL_FillRect(surface, &rect, color); -#else - SDL_FillRect(surface, &rect, - SDL_MapRGB(surface->format, color_r, color_g, color_b)); -#endif } inline void SDLDrawLine(Bitmap *dst_bitmap, int from_x, int from_y, diff --git a/src/libgame/sdl.h b/src/libgame/sdl.h index fc05cb70..9c8e9b58 100644 --- a/src/libgame/sdl.h +++ b/src/libgame/sdl.h @@ -14,11 +14,11 @@ #ifndef SDL_H #define SDL_H -#include "SDL.h" -#include "SDL_image.h" -#include "SDL_mixer.h" -#include "SDL_net.h" -#include "SDL_thread.h" +#include +#include +#include +#include +#include /* definitions needed for "system.c" */ diff --git a/src/libgame/setup.c b/src/libgame/setup.c index 3b9438e6..4fc58a40 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -938,13 +938,8 @@ void dumpTreeInfo(TreeInfo *node, int depth) for (i = 0; i < (depth + 1) * 3; i++) printf(" "); -#if 1 printf("subdir == '%s' ['%s', '%s'] [%d])\n", node->subdir, node->fullpath, node->basepath, node->in_user_dir); -#else - printf("subdir == '%s' (%s) [%s] (%d)\n", - node->subdir, node->name, node->identifier, node->sort_priority); -#endif if (node->node_group != NULL) dumpTreeInfo(node->node_group, depth + 1); @@ -1396,7 +1391,6 @@ char *removeHashEntry(SetupFileHash *hash, char *token) } #if 0 -#ifdef DEBUG static void printSetupFileHash(SetupFileHash *hash) { BEGIN_HASH_ITERATION(hash, itr) @@ -1407,7 +1401,6 @@ static void printSetupFileHash(SetupFileHash *hash) END_HASH_ITERATION(hash, itr) } #endif -#endif static void *loadSetupFileData(char *filename, boolean use_hash) { @@ -1698,7 +1691,6 @@ static void setTreeInfoToDefaultsFromParent(TreeInfo *ldi, TreeInfo *parent) return; } -#if 1 /* copy all values from the parent structure */ ldi->type = parent->type; @@ -1751,47 +1743,6 @@ static void setTreeInfoToDefaultsFromParent(TreeInfo *ldi, TreeInfo *parent) ldi->handicap = TRUE; ldi->skip_levels = FALSE; } - -#else - - /* first copy all values from the parent structure ... */ - *ldi = *parent; - - /* ... then set all fields to default that cannot be inherited from parent. - This is especially important for all those fields that can be set from - the 'levelinfo.conf' config file, because the function 'setSetupInfo()' - calls 'free()' for all already set token values which requires that no - other structure's pointer may point to them! - */ - - ldi->subdir = NULL; - ldi->fullpath = NULL; - ldi->basepath = NULL; - ldi->identifier = NULL; - ldi->name = getStringCopy(ANONYMOUS_NAME); - ldi->name_sorting = NULL; - ldi->author = getStringCopy(parent->author); - - ldi->imported_from = getStringCopy(parent->imported_from); - ldi->imported_by = getStringCopy(parent->imported_by); - ldi->class_desc = getStringCopy(parent->class_desc); - - ldi->graphics_set = NULL; - ldi->sounds_set = NULL; - ldi->music_set = NULL; - ldi->graphics_path = NULL; - ldi->sounds_path = NULL; - ldi->music_path = NULL; - - ldi->level_group = FALSE; - ldi->parent_link = FALSE; - - ldi->node_top = parent->node_top; - ldi->node_parent = parent; - ldi->node_group = NULL; - ldi->next = NULL; - -#endif } static void freeTreeInfo(TreeInfo *ldi) @@ -1915,7 +1866,6 @@ static void createParentTreeInfoNode(TreeInfo *node_parent) ti_new->node_parent = node_parent; ti_new->parent_link = TRUE; -#if 1 setString(&ti_new->identifier, node_parent->identifier); setString(&ti_new->name, ".. (parent directory)"); setString(&ti_new->name_sorting, ti_new->name); @@ -1927,19 +1877,6 @@ static void createParentTreeInfoNode(TreeInfo *node_parent) ti_new->latest_engine = node_parent->latest_engine; setString(&ti_new->class_desc, getLevelClassDescription(ti_new)); -#else - ti_new->identifier = getStringCopy(node_parent->identifier); - ti_new->name = ".. (parent directory)"; - ti_new->name_sorting = getStringCopy(ti_new->name); - - ti_new->subdir = ".."; - ti_new->fullpath = getStringCopy(node_parent->fullpath); - - ti_new->sort_priority = node_parent->sort_priority; - ti_new->latest_engine = node_parent->latest_engine; - - ti_new->class_desc = getLevelClassDescription(ti_new); -#endif pushTreeInfo(&node_parent->node_group, ti_new); } @@ -1997,16 +1934,8 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first, getHashEntry(setup_file_hash, levelinfo_tokens[i].text)); *leveldir_new = ldi; -#if 1 if (strcmp(leveldir_new->name, ANONYMOUS_NAME) == 0) setString(&leveldir_new->name, leveldir_new->subdir); -#else - if (strcmp(leveldir_new->name, ANONYMOUS_NAME) == 0) - { - free(leveldir_new->name); - leveldir_new->name = getStringCopy(leveldir_new->subdir); - } -#endif DrawInitText(leveldir_new->name, 150, FC_YELLOW); @@ -2027,21 +1956,17 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first, leveldir_new->fullpath = getPath2(node_parent->fullpath, directory_name); } +#if 0 if (leveldir_new->levels < 1) leveldir_new->levels = 1; +#endif leveldir_new->last_level = leveldir_new->first_level + leveldir_new->levels - 1; -#if 1 leveldir_new->in_user_dir = (strcmp(leveldir_new->basepath, options.level_directory) != 0); -#else - leveldir_new->in_user_dir = - (leveldir_new->basepath == options.level_directory ? FALSE : TRUE); -#endif -#if 1 /* adjust some settings if user's private level directory was detected */ if (leveldir_new->sort_priority == LEVELCLASS_UNDEFINED && leveldir_new->in_user_dir && @@ -2053,28 +1978,30 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first, leveldir_new->readonly = FALSE; } -#else - /* adjust sort priority if user's private level directory was detected */ - if (leveldir_new->sort_priority == LEVELCLASS_UNDEFINED && - leveldir_new->in_user_dir && - strcmp(leveldir_new->subdir, getLoginName()) == 0) - leveldir_new->sort_priority = LEVELCLASS_PRIVATE_START; -#endif - leveldir_new->user_defined = (leveldir_new->in_user_dir && IS_LEVELCLASS_PRIVATE(leveldir_new)); leveldir_new->color = LEVELCOLOR(leveldir_new); -#if 1 + setString(&leveldir_new->class_desc, getLevelClassDescription(leveldir_new)); -#else - leveldir_new->class_desc = getLevelClassDescription(leveldir_new); -#endif leveldir_new->handicap_level = /* set handicap to default value */ (leveldir_new->user_defined || !leveldir_new->handicap ? leveldir_new->last_level : leveldir_new->first_level); +#if 1 + if (leveldir_new->levels < 1 && !leveldir_new->level_group) + { + /* skip level sets without levels (which are probably artwork base sets) */ + + freeSetupFileHash(setup_file_hash); + free(directory_path); + free(filename); + + return FALSE; + } +#endif + pushTreeInfo(node_first, leveldir_new); freeSetupFileHash(setup_file_hash); @@ -2249,16 +2176,8 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first, getHashEntry(setup_file_hash, levelinfo_tokens[i].text)); *artwork_new = ldi; -#if 1 if (strcmp(artwork_new->name, ANONYMOUS_NAME) == 0) setString(&artwork_new->name, artwork_new->subdir); -#else - if (strcmp(artwork_new->name, ANONYMOUS_NAME) == 0) - { - free(artwork_new->name); - artwork_new->name = getStringCopy(artwork_new->subdir); - } -#endif #if 0 DrawInitText(artwork_new->name, 150, FC_YELLOW); @@ -2282,86 +2201,42 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first, artwork_new->fullpath = getPath2(node_parent->fullpath, directory_name); } -#if 1 artwork_new->in_user_dir = (strcmp(artwork_new->basepath, OPTIONS_ARTWORK_DIRECTORY(type)) != 0); -#else - artwork_new->in_user_dir = - (artwork_new->basepath == OPTIONS_ARTWORK_DIRECTORY(type) ? FALSE : TRUE); -#endif /* (may use ".sort_priority" from "setup_file_hash" above) */ artwork_new->color = ARTWORKCOLOR(artwork_new); -#if 1 + setString(&artwork_new->class_desc, getLevelClassDescription(artwork_new)); -#else - artwork_new->class_desc = getLevelClassDescription(artwork_new); -#endif if (setup_file_hash == NULL) /* (after determining ".user_defined") */ { -#if 0 - if (artwork_new->name != NULL) - { - free(artwork_new->name); - artwork_new->name = NULL; - } -#endif - -#if 0 - if (artwork_new->identifier != NULL) - { - free(artwork_new->identifier); - artwork_new->identifier = NULL; - } -#endif - if (strcmp(artwork_new->subdir, ".") == 0) { if (artwork_new->user_defined) { -#if 1 setString(&artwork_new->identifier, "private"); -#else - artwork_new->identifier = getStringCopy("private"); -#endif artwork_new->sort_priority = ARTWORKCLASS_PRIVATE; } else { -#if 1 setString(&artwork_new->identifier, "classic"); -#else - artwork_new->identifier = getStringCopy("classic"); -#endif artwork_new->sort_priority = ARTWORKCLASS_CLASSICS; } /* set to new values after changing ".sort_priority" */ artwork_new->color = ARTWORKCOLOR(artwork_new); -#if 1 + setString(&artwork_new->class_desc, getLevelClassDescription(artwork_new)); -#else - artwork_new->class_desc = getLevelClassDescription(artwork_new); -#endif } else { -#if 1 setString(&artwork_new->identifier, artwork_new->subdir); -#else - artwork_new->identifier = getStringCopy(artwork_new->subdir); -#endif } -#if 1 setString(&artwork_new->name, artwork_new->identifier); setString(&artwork_new->name_sorting, artwork_new->name); -#else - artwork_new->name = getStringCopy(artwork_new->identifier); - artwork_new->name_sorting = getStringCopy(artwork_new->name); -#endif } DrawInitText(artwork_new->name, 150, FC_YELLOW); @@ -2439,7 +2314,6 @@ static TreeInfo *getDummyArtworkInfo(int type) setTreeInfoToDefaults(artwork_new, type); -#if 1 setString(&artwork_new->subdir, UNDEFINED_FILENAME); setString(&artwork_new->fullpath, UNDEFINED_FILENAME); setString(&artwork_new->basepath, UNDEFINED_FILENAME); @@ -2447,17 +2321,6 @@ static TreeInfo *getDummyArtworkInfo(int type) setString(&artwork_new->identifier, UNDEFINED_FILENAME); setString(&artwork_new->name, UNDEFINED_FILENAME); setString(&artwork_new->name_sorting, UNDEFINED_FILENAME); -#else - artwork_new->subdir = getStringCopy(UNDEFINED_FILENAME); - artwork_new->fullpath = getStringCopy(UNDEFINED_FILENAME); - artwork_new->basepath = getStringCopy(UNDEFINED_FILENAME); - - checked_free(artwork_new->name); - - artwork_new->identifier = getStringCopy(UNDEFINED_FILENAME); - artwork_new->name = getStringCopy(UNDEFINED_FILENAME); - artwork_new->name_sorting = getStringCopy(UNDEFINED_FILENAME); -#endif return artwork_new; } @@ -2550,12 +2413,6 @@ void LoadArtworkInfoFromLevelInfo(ArtworkDirTree **artwork_node, char *path = getPath2(getLevelDirFromTreeInfo(level_node), ARTWORK_DIRECTORY((*artwork_node)->type)); -#if 0 - if (!level_node->parent_link) - printf("CHECKING '%s' ['%s', '%s'] ...\n", path, - level_node->subdir, level_node->name); -#endif - if (!level_node->parent_link) { TreeInfo *topnode_last = *artwork_node; @@ -2662,29 +2519,10 @@ static void SaveUserLevelInfo() /* always start with reliable default values */ setTreeInfoToDefaults(level_info, TREE_TYPE_LEVEL_DIR); -#if 1 setString(&level_info->name, getLoginName()); setString(&level_info->author, getRealName()); level_info->levels = 100; level_info->first_level = 1; -#if 0 - level_info->sort_priority = LEVELCLASS_PRIVATE_START; - level_info->readonly = FALSE; - setString(&level_info->graphics_set, GFX_CLASSIC_SUBDIR); - setString(&level_info->sounds_set, SND_CLASSIC_SUBDIR); - setString(&level_info->music_set, MUS_CLASSIC_SUBDIR); -#endif -#else - ldi.name = getStringCopy(getLoginName()); - ldi.author = getStringCopy(getRealName()); - ldi.levels = 100; - ldi.first_level = 1; - ldi.sort_priority = LEVELCLASS_PRIVATE_START; - ldi.readonly = FALSE; - ldi.graphics_set = getStringCopy(GFX_CLASSIC_SUBDIR); - ldi.sounds_set = getStringCopy(SND_CLASSIC_SUBDIR); - ldi.music_set = getStringCopy(MUS_CLASSIC_SUBDIR); -#endif token_value_position = TOKEN_VALUE_POSITION_SHORT; @@ -2694,7 +2532,6 @@ static void SaveUserLevelInfo() ldi = *level_info; for (i = 0; i < NUM_LEVELINFO_TOKENS; i++) { -#if 1 if (i == LEVELINFO_TOKEN_NAME || i == LEVELINFO_TOKEN_AUTHOR || i == LEVELINFO_TOKEN_LEVELS || @@ -2704,15 +2541,6 @@ static void SaveUserLevelInfo() /* just to make things nicer :) */ if (i == LEVELINFO_TOKEN_AUTHOR) fprintf(file, "\n"); -#else - if (i != LEVELINFO_TOKEN_IDENTIFIER && - i != LEVELINFO_TOKEN_NAME_SORTING && - i != LEVELINFO_TOKEN_IMPORTED_FROM && - i != LEVELINFO_TOKEN_IMPORTED_BY && - i != LEVELINFO_TOKEN_FILENAME && - i != LEVELINFO_TOKEN_FILETYPE) - fprintf(file, "%s\n", getSetupLine(levelinfo_tokens, "", i)); -#endif } token_value_position = TOKEN_VALUE_POSITION_DEFAULT; diff --git a/src/libgame/sound.c b/src/libgame/sound.c index 6eb1de14..a4b31c06 100644 --- a/src/libgame/sound.c +++ b/src/libgame/sound.c @@ -70,25 +70,6 @@ #define SAME_SOUND_NR(x,y) ((x).nr == (y).nr) #define SAME_SOUND_DATA(x,y) ((x).data_ptr == (y).data_ptr) -#if 0 -struct SoundHeader_SUN -{ - unsigned long magic; - unsigned long hdr_size; - unsigned long data_size; - unsigned long encoding; - unsigned long sample_rate; - unsigned long channels; -}; - -struct SoundHeader_8SVX -{ - char magic_FORM[4]; - unsigned long chunk_size; - char magic_8SVX[4]; -}; -#endif - #if defined(AUDIO_UNIX_NATIVE) struct SoundHeader_WAV { @@ -151,16 +132,8 @@ typedef struct SoundControl SoundControl; static struct ArtworkListInfo *sound_info = NULL; static struct ArtworkListInfo *music_info = NULL; -#if 0 -static SoundInfo **Sound = NULL; -#endif - static MusicInfo **Music_NoConf = NULL; -#if 0 -static int num_sounds = 0; -#endif - static int num_music_noconf = 0; static int stereo_volume[SOUND_MAX_LEFT2RIGHT + 1]; @@ -271,11 +244,6 @@ static boolean ForkAudioProcess(void) if (audio.mixer_pid == 0) /* we are the child process */ audio.mixer_pid = getpid(); -#if 0 - printf("PID: %d [%s]\n", getpid(),(IS_CHILD_PROCESS() ? "child" : "parent")); - Delay(10000 * 0); -#endif - if (IS_CHILD_PROCESS()) Mixer_Main(); /* this function never returns */ else @@ -831,22 +799,6 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) int num_sounds = getSoundListSize(); int num_music = getMusicListSize(); -#if 0 - if (IS_MUSIC(snd_ctrl)) - printf("NEW MUSIC %d ARRIVED [%d/%d] [%d ACTIVE CHANNELS]\n", - snd_ctrl.nr, num_music, num_music_noconf, mixer_active_channels); - else - printf("NEW SOUND %d ARRIVED [%d] [%d ACTIVE CHANNELS]\n", - snd_ctrl.nr, num_sounds, mixer_active_channels); -#endif - -#if 0 - /* !!! TEST ONLY !!! */ - if (IS_MUSIC(snd_ctrl)) - snd_ctrl.nr = 0; -#endif - -#if 1 if (IS_MUSIC(snd_ctrl)) { if (snd_ctrl.nr >= num_music) /* invalid music */ @@ -871,32 +823,6 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) snd_info = getSoundInfoEntryFromSoundID(snd_ctrl.nr); } - /* - if (snd_ctrl.nr >= (IS_MUSIC(snd_ctrl) ? num_music : num_sounds)) - return; - */ -#else - if (IS_MUSIC(snd_ctrl)) - { - if (num_music_noconf == 0) - return; - - snd_ctrl.nr = snd_ctrl.nr % num_music_noconf; - } - else if (snd_ctrl.nr >= num_sounds) - return; -#endif - -#if 0 -#if 1 - snd_info = (IS_MUSIC(snd_ctrl) ? getMusicInfoEntryFromMusicID(snd_ctrl.nr) : - getSoundInfoEntryFromSoundID(snd_ctrl.nr)); -#else - snd_info = (IS_MUSIC(snd_ctrl) ? Music_NoConf[snd_ctrl.nr] : - getSoundInfoEntryFromSoundID(snd_ctrl.nr)); -#endif -#endif - if (snd_info == NULL) return; @@ -910,10 +836,6 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) /* play music samples on a dedicated music channel */ if (IS_MUSIC(snd_ctrl)) { -#if 0 - printf("::: slot %d, ptr 0x%08x\n", snd_ctrl.nr, snd_ctrl.data_ptr); -#endif - Mixer_StopMusicChannel(); mixer[audio.music_channel] = snd_ctrl; @@ -927,10 +849,6 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl)) k++; -#if 0 - printf("SOUND %d [CURRENTLY PLAYING %d TIMES]\n", snd_ctrl.nr, k); -#endif - /* reset expiration delay for already playing loop sounds */ if (k > 0 && IS_LOOP(snd_ctrl)) { @@ -938,10 +856,6 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) { if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl)) { -#if 0 - printf("RESETTING EXPIRATION FOR SOUND %d\n", snd_ctrl.nr); -#endif - if (IS_FADING(mixer[i])) Mixer_UnFadeChannel(i); @@ -951,21 +865,12 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) Mixer_SetChannelProperties(i); Mixer_ResetChannelExpiration(i); - -#if 0 - printf("RESETTING VOLUME/STEREO FOR SOUND %d TO %d/%d\n", - snd_ctrl.nr, snd_ctrl.volume, snd_ctrl.stereo_position); -#endif } } return; } -#if 0 - printf("PLAYING NEW SOUND %d\n", snd_ctrl.nr); -#endif - /* don't play sound more than n times simultaneously (with n == 2 for now) */ if (k >= 2) { @@ -1052,16 +957,8 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) /* add the new sound to the mixer */ for (i = audio.first_sound_channel; i < audio.num_channels; i++) { -#if 0 - printf("CHECKING CHANNEL %d FOR SOUND %d ...\n", i, snd_ctrl.nr); -#endif - if (!mixer[i].active) { -#if 0 - printf("ADDING NEW SOUND %d TO MIXER\n", snd_ctrl.nr); -#endif - #if defined(AUDIO_UNIX_NATIVE) if (snd_info->data_len == 0) { @@ -1408,11 +1305,9 @@ static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl) mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME; /* might be needed for u-law /dev/audio */ -#if 1 for (j = 0; j < sample_size; j++) playing_buffer[j] = linear_to_ulaw(premix_first_buffer[j]); -#endif /* delete completed sound entries from the mixer */ if (mixer[i].playing_pos >= mixer[i].data_len) @@ -1638,10 +1533,6 @@ static void *Load_WAV(char *filename) if (!audio.sound_available) return NULL; -#if 0 - printf("loading WAV file '%s'\n", filename); -#endif - snd_info = checked_calloc(sizeof(SoundInfo)); #if defined(TARGET_SDL) @@ -1926,25 +1817,13 @@ void LoadCustomMusic_NoConf(void) if (music_already_used) continue; -#if 0 - if (FileIsSound(basename) || FileIsMusic(basename)) - printf("DEBUG: loading music '%s' ...\n", basename); -#endif - if (draw_init_text) DrawInitText(basename, 150, FC_YELLOW); filename = getPath2(music_directory, basename); -#if 1 if (FileIsMusic(basename)) mus_info = Load_WAV_or_MOD(filename); -#else - if (FileIsSound(basename)) - mus_info = Load_WAV(filename); - else if (FileIsMusic(basename)) - mus_info = Load_MOD(filename); -#endif free(filename); @@ -2107,11 +1986,6 @@ void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries, sound_info->load_artwork = Load_WAV; sound_info->free_artwork = FreeSound; - -#if 0 - num_sounds = sound_info->num_file_list_entries; - Sound = (SoundInfo **)sound_info->artwork_list; -#endif } void InitMusicList(struct ConfigInfo *config_list, int num_file_list_entries, @@ -2309,30 +2183,24 @@ void StopSoundExt(int nr, int state) static void ReloadCustomSounds() { #if 0 - printf("DEBUG: reloading sounds '%s' ...\n", artwork.snd_current_identifier); + printf("::: reloading sounds '%s' ...\n", artwork.snd_current_identifier); #endif LoadArtworkConfig(sound_info); ReloadCustomArtworkList(sound_info); - -#if 0 - num_sounds = getSoundListSize(); -#endif } static void ReloadCustomMusic() { #if 0 - printf("DEBUG: reloading music '%s' ...\n", artwork.mus_current_identifier); + printf("::: reloading music '%s' ...\n", artwork.mus_current_identifier); #endif LoadArtworkConfig(music_info); ReloadCustomArtworkList(music_info); -#if 1 /* load all music files from directory not defined in "musicinfo.conf" */ LoadCustomMusic_NoConf(); -#endif } void InitReloadCustomSounds(char *set_identifier) diff --git a/src/libgame/system.c b/src/libgame/system.c index 8e65d970..cd24b134 100644 --- a/src/libgame/system.c +++ b/src/libgame/system.c @@ -213,29 +213,6 @@ static void DrawBitmapFromTile(Bitmap *bitmap, Bitmap *tile, void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask) { - /* !!! THIS DOES NOT WORK !!! REPLACED BITMAPS MAY HAVE SAME ADDRESS !!! */ -#if 0 - static Bitmap *main_bitmap_tile = NULL; - static Bitmap *door_bitmap_tile = NULL; - - if (mask == REDRAW_FIELD) - { - if (background_bitmap_tile == main_bitmap_tile) - return; /* main background tile has not changed */ - - main_bitmap_tile = background_bitmap_tile; - } - else if (mask == REDRAW_DOOR_1) - { - if (background_bitmap_tile == door_bitmap_tile) - return; /* main background tile has not changed */ - - door_bitmap_tile = background_bitmap_tile; - } - else /* should not happen */ - return; -#endif - if (background_bitmap_tile != NULL) gfx.background_bitmap_mask |= mask; else @@ -444,13 +421,8 @@ inline boolean DrawingDeactivated(int x, int y, int width, int height) inline boolean DrawingOnBackground(int x, int y) { -#if 1 return (CheckDrawingArea(x, y, 1, 1, gfx.background_bitmap_mask) && CheckDrawingArea(x, y, 1, 1, gfx.draw_background_mask)); -#else - return ((gfx.draw_background_mask & gfx.background_bitmap_mask) && - CheckDrawingArea(x, y, 1, 1, gfx.draw_background_mask)); -#endif } inline void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap, @@ -487,12 +459,6 @@ inline void ClearRectangleOnBackground(Bitmap *bitmap, int x, int y, ClearRectangle(bitmap, x, y, width, height); } -#if 0 -#ifndef TARGET_SDL -static GC last_clip_gc = 0; /* needed for XCopyArea() through clip mask */ -#endif -#endif - inline void SetClipMask(Bitmap *bitmap, GC clip_gc, Pixmap clip_pixmap) { #if defined(TARGET_X11) @@ -501,9 +467,6 @@ inline void SetClipMask(Bitmap *bitmap, GC clip_gc, Pixmap clip_pixmap) bitmap->clip_gc = clip_gc; XSetClipMask(display, bitmap->clip_gc, clip_pixmap); } -#if 0 - last_clip_gc = clip_gc; -#endif #endif } @@ -515,9 +478,6 @@ inline void SetClipOrigin(Bitmap *bitmap, GC clip_gc, int clip_x, int clip_y) bitmap->clip_gc = clip_gc; XSetClipOrigin(display, bitmap->clip_gc, clip_x, clip_y); } -#if 0 - last_clip_gc = clip_gc; -#endif #endif } @@ -555,6 +515,16 @@ inline void BlitBitmapOnBackground(Bitmap *src_bitmap, Bitmap *dst_bitmap, dst_x, dst_y); } +inline void DrawSimpleBlackLine(Bitmap *bitmap, int from_x, int from_y, + int to_x, int to_y) +{ +#if defined(TARGET_SDL) + SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, BLACK_PIXEL); +#else + X11DrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, BLACK_PIXEL); +#endif +} + inline void DrawSimpleWhiteLine(Bitmap *bitmap, int from_x, int from_y, int to_x, int to_y) { @@ -900,20 +870,6 @@ void CreateBitmapWithSmallBitmaps(Bitmap *old_bitmap, int zoom_factor) if (zoom_factor != 8) FreeBitmap(tmp_bitmap_8); -#if 0 - -#if defined(TARGET_SDL) - /* !!! what about the old old_bitmap->surface ??? FIX ME !!! */ - old_bitmap->surface = new_bitmap->surface; - new_bitmap->surface = NULL; -#else - /* !!! see above !!! */ - old_bitmap->drawable = new_bitmap->drawable; - new_bitmap->drawable = None; -#endif - -#else - /* replace image with extended image (containing normal, 1/2 and 1/8 size) */ #if defined(TARGET_SDL) swap_bitmap.surface = old_bitmap->surface; @@ -923,8 +879,6 @@ void CreateBitmapWithSmallBitmaps(Bitmap *old_bitmap, int zoom_factor) swap_bitmap.drawable = old_bitmap->drawable; old_bitmap->drawable = new_bitmap->drawable; new_bitmap->drawable = swap_bitmap.drawable; -#endif - #endif old_bitmap->width = new_bitmap->width; @@ -974,7 +928,9 @@ static const char *cursor_image_playfield[] = /* hot spot */ "0,0" + #else + /* pixels */ " X ", "X.X ", @@ -1165,6 +1121,7 @@ inline void PeekEvent(Event *event) inline Key GetEventKey(KeyEvent *event, boolean with_modifiers) { #if defined(TARGET_SDL) + #if 0 printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n", (int)event->keysym.unicode, @@ -1178,7 +1135,9 @@ inline Key GetEventKey(KeyEvent *event, boolean with_modifiers) return event->keysym.unicode; else return event->keysym.sym; + #else + #if 0 printf("with modifiers == '0x%04x', without modifiers == '0x%04x'\n", (int)XLookupKeysym(event, event->state), diff --git a/src/libgame/system.h b/src/libgame/system.h index 0b210ed0..bc434d36 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -100,7 +100,7 @@ #define BUTTON_2 5 /* values for move directions and special "button" key bitmasks */ -#define MV_NO_MOVING 0 +#define MV_NONE 0 #define MV_LEFT (1 << MV_BIT_LEFT) #define MV_RIGHT (1 << MV_BIT_RIGHT) #define MV_UP (1 << MV_BIT_UP) @@ -110,7 +110,7 @@ #define MV_VERTICAL (MV_UP | MV_DOWN) #define MV_ALL_DIRECTIONS (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN) #define MV_ANY_DIRECTION (MV_ALL_DIRECTIONS) -#define MV_NO_DIRECTIONS (MV_NO_MOVING) +#define MV_NO_DIRECTION (MV_NONE) #define KEY_BUTTON_1 (1 << BUTTON_1) #define KEY_BUTTON_2 (1 << BUTTON_2) @@ -125,7 +125,7 @@ #define MV_DIR_OPPOSITE(x) ((x) == MV_LEFT ? MV_RIGHT : \ (x) == MV_RIGHT ? MV_LEFT : \ (x) == MV_UP ? MV_DOWN : \ - (x) == MV_DOWN ? MV_UP : MV_NO_MOVING) + (x) == MV_DOWN ? MV_UP : MV_NONE) /* values for animation mode (frame order and direction) */ @@ -135,11 +135,13 @@ #define ANIM_PINGPONG (1 << 2) #define ANIM_PINGPONG2 (1 << 3) #define ANIM_RANDOM (1 << 4) -#define ANIM_REVERSE (1 << 5) +#define ANIM_CE_VALUE (1 << 5) +#define ANIM_CE_SCORE (1 << 6) +#define ANIM_REVERSE (1 << 7) /* values for special (non game element) animation modes */ -#define ANIM_HORIZONTAL (1 << 6) -#define ANIM_VERTICAL (1 << 7) +#define ANIM_HORIZONTAL (1 << 8) +#define ANIM_VERTICAL (1 << 9) #define ANIM_DEFAULT ANIM_LOOP @@ -248,6 +250,7 @@ #define SETUP_FILENAME "setup.conf" #define LEVELSETUP_FILENAME "levelsetup.conf" #define EDITORSETUP_FILENAME "editorsetup.conf" +#define EDITORCASCADE_FILENAME "editorcascade.conf" #define HELPANIM_FILENAME "helpanim.conf" #define HELPTEXT_FILENAME "helptext.conf" #define LEVELINFO_FILENAME "levelinfo.conf" @@ -262,6 +265,7 @@ #define SETUP_FILENAME "setup.cnf" #define LEVELSETUP_FILENAME "lvlsetup.cnf" #define EDITORSETUP_FILENAME "edsetup.cnf" +#define EDITORCASCADE_FILENAME "edcascad.conf" #define HELPANIM_FILENAME "helpanim.cnf" #define HELPTEXT_FILENAME "helptext.cnf" #define LEVELINFO_FILENAME "lvlinfo.cnf" @@ -586,12 +590,30 @@ struct SetupEditorInfo boolean el_dx_boulderdash; boolean el_chars; boolean el_custom; - boolean el_custom_more; boolean el_user_defined; + boolean el_dynamic; boolean el_headlines; }; +struct SetupEditorCascadeInfo +{ + boolean el_bd; + boolean el_em; + boolean el_emc; + boolean el_rnd; + boolean el_sb; + boolean el_sp; + boolean el_dc; + boolean el_dx; + boolean el_chars; + boolean el_ce; + boolean el_ge; + boolean el_user; + boolean el_generic; + boolean el_dynamic; +}; + struct SetupShortcutInfo { Key save_game; @@ -636,6 +658,7 @@ struct SetupInfo boolean override_level_music; struct SetupEditorInfo editor; + struct SetupEditorCascadeInfo editor_cascade; struct SetupShortcutInfo shortcut; struct SetupInputInfo input[MAX_PLAYERS]; struct SetupSystemInfo system; @@ -888,6 +911,7 @@ inline void BlitBitmapMasked(Bitmap *, Bitmap *, int, int, int, int, int, int); inline boolean DrawingOnBackground(int, int); inline void BlitBitmapOnBackground(Bitmap *, Bitmap *, int, int, int, int, int, int); +inline void DrawSimpleBlackLine(Bitmap *, int, int, int, int); inline void DrawSimpleWhiteLine(Bitmap *, int, int, int, int); inline void DrawLines(Bitmap *, struct XY *, int, Pixel); inline Pixel GetPixel(Bitmap *, int, int); diff --git a/src/libgame/toons.c b/src/libgame/toons.c index 2d0a3550..6f4fd2f7 100644 --- a/src/libgame/toons.c +++ b/src/libgame/toons.c @@ -48,11 +48,7 @@ int getAnimationFrame(int num_frames, int delay, int mode, int start_frame, } else if (mode & ANIM_PINGPONG) /* oscillate (border frames once) */ { -#if 1 int max_anim_frames = (num_frames > 1 ? 2 * num_frames - 2 : 1); -#else - int max_anim_frames = 2 * num_frames - 2; -#endif frame = (sync_frame % (delay * max_anim_frames)) / delay; frame = (frame < num_frames ? frame : max_anim_frames - frame); @@ -73,6 +69,10 @@ int getAnimationFrame(int num_frames, int delay, int mode, int start_frame, else frame = gfx.anim_random_frame % num_frames; } + else if (mode & (ANIM_CE_VALUE | ANIM_CE_SCORE)) + { + frame = sync_frame % num_frames; + } if (mode & ANIM_REVERSE) /* use reverse animation direction */ frame = num_frames - frame - 1; @@ -92,7 +92,7 @@ static int get_toon_direction(char *direction_string_raw) strcmp(direction_string, "right") == 0 ? MV_RIGHT : strcmp(direction_string, "up") == 0 ? MV_UP : strcmp(direction_string, "down") == 0 ? MV_DOWN : - MV_NO_MOVING); + MV_NONE); free(direction_string); @@ -127,7 +127,6 @@ void DrawAnim(Bitmap *toon_bitmap, GC toon_clip_gc, { int buf_x = DOOR_GFX_PAGEX3, buf_y = DOOR_GFX_PAGEY1; -#if 1 /* special method to avoid flickering interference with BackToFront() */ BlitBitmap(backbuffer, screen_info.save_buffer, dest_x-pad_x, dest_y-pad_y, width+2*pad_x, height+2*pad_y, buf_x, buf_y); @@ -141,16 +140,6 @@ void DrawAnim(Bitmap *toon_bitmap, GC toon_clip_gc, BlitBitmap(screen_info.save_buffer, backbuffer, buf_x, buf_y, width+2*pad_x, height+2*pad_y, dest_x-pad_x, dest_y-pad_y); -#else - /* normal method, causing flickering interference with BackToFront() */ - BlitBitmap(backbuffer, screen_info.save_buffer, dest_x-pad_x, dest_y-pad_y, - width+2*pad_x, height+2*pad_y, buf_x, buf_y); - SetClipOrigin(toon_bitmap,toon_clip_gc, buf_x-src_x+pad_x,buf_y-src_y+pad_y); - BlitBitmapMasked(toon_bitmap, screen_info.save_buffer, - src_x, src_y, width, height, buf_x+pad_x, buf_y+pad_y); - BlitBitmap(screen_info.save_buffer, window, buf_x, buf_y, - width+2*pad_x, height+2*pad_y, dest_x-pad_x, dest_y-pad_y); -#endif FlushDisplay(); } @@ -321,7 +310,7 @@ void HandleAnimation(int mode) static int toon_nr = 0; int draw_mode; - if (!setup.toons) + if (!setup.toons || screen_info.num_toons == 0) return; /* this may happen after reloading graphics and redefining "num_toons" */ diff --git a/src/libgame/toons.h b/src/libgame/toons.h index 31345837..4d3e0be8 100644 --- a/src/libgame/toons.h +++ b/src/libgame/toons.h @@ -35,27 +35,8 @@ struct ToonScreenInfo struct ToonInfo { -#if 0 - int graphic; - int width, height; - int src_x, src_y; - int anim_frames; - int step_delay; - int step_offset; - int anim_mode; - int direction; - int position; - - int anim_delay; - int anim_start_frame; - Bitmap *bitmap; /* dynamically initialized */ - - char *direction_str; - char *position_str; - -#else - Bitmap *bitmap; + int src_x, src_y; int width, height; int anim_frames; @@ -64,9 +45,9 @@ struct ToonInfo int anim_mode; int step_offset; int step_delay; + char *direction; char *position; -#endif }; diff --git a/src/libgame/x11.c b/src/libgame/x11.c index f03e961c..30aaa1bc 100644 --- a/src/libgame/x11.c +++ b/src/libgame/x11.c @@ -93,9 +93,6 @@ static DrawWindow *X11InitWindow() Pixmap icon_pixmap, iconmask_pixmap; unsigned int icon_width, icon_height; int icon_hot_x, icon_hot_y; -#if 0 - char icon_filename[256]; -#endif XSizeHints size_hints; XWMHints wm_hints; XClassHint class_hints; @@ -111,16 +108,6 @@ static DrawWindow *X11InitWindow() const int width = video.width, height = video.height; int i; -#if 0 -#if !defined(PLATFORM_MSDOS) - static struct IconFileInfo icon_pic = - { - "rocks_icon.xbm", - "rocks_iconmask.xbm" - }; -#endif -#endif - screen_width = XDisplayWidth(display, screen); screen_height = XDisplayHeight(display, screen); @@ -140,10 +127,6 @@ static DrawWindow *X11InitWindow() XChangeProperty(display, new_window->drawable, proto_atom, XA_ATOM, 32, PropModePrepend, (unsigned char *) &delete_atom, 1); -#if 0 - sprintf(icon_filename, "%s/%s", options.graphics_directory, - icon_pic.picture_filename); -#endif if (XReadBitmapFile(display, new_window->drawable, getCustomImageFilename(program.x11_icon_filename), &icon_width, &icon_height, &icon_pixmap, @@ -151,10 +134,6 @@ static DrawWindow *X11InitWindow() Error(ERR_EXIT, "cannot read icon bitmap file '%s'", program.x11_icon_filename); -#if 0 - sprintf(icon_filename, "%s/%s", options.graphics_directory, - icon_pic.picturemask_filename); -#endif if (XReadBitmapFile(display, new_window->drawable, getCustomImageFilename(program.x11_iconmask_filename), &icon_width, &icon_height, &iconmask_pixmap, diff --git a/src/main.c b/src/main.c index f2db9290..258ac504 100644 --- a/src/main.c +++ b/src/main.c @@ -19,14 +19,7 @@ #include "events.h" #include "config.h" -#if 0 -GC tile_clip_gc; -Bitmap *pix[NUM_BITMAPS]; -#endif Bitmap *bitmap_db_field, *bitmap_db_door; -#if 0 -Pixmap tile_clipmask[NUM_TILES]; -#endif DrawBuffer *fieldbuffer; DrawBuffer *drawto_field; @@ -50,13 +43,14 @@ short MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short ChangeDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short ChangePage[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; +short CustomValue[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short Back[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; boolean Pushed[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; -boolean Changed[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; +short ChangeCount[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short ChangeEvent[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short WasJustMoving[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short WasJustFalling[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; @@ -83,7 +77,7 @@ int scroll_x, scroll_y; int FX = SX, FY = SY; int ScrollStepSize; -int ScreenMovDir = MV_NO_MOVING, ScreenMovPos = 0; +int ScreenMovDir = MV_NONE, ScreenMovPos = 0; int ScreenGfxPos = 0; int BorderElement = EL_STEELWALL; int GameFrameDelay = GAME_FRAME_DELAY; @@ -1762,27 +1756,27 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] = { "balloon_switch_left", "balloon_switch", - "send balloon to the left" + "wind switch (left)" }, { "balloon_switch_right", "balloon_switch", - "send balloon to the right" + "wind switch (right)" }, { "balloon_switch_up", "balloon_switch", - "send balloon up" + "wind switch (up)" }, { "balloon_switch_down", "balloon_switch", - "send balloon down" + "wind switch (down)" }, { "balloon_switch_any", "balloon_switch", - "send balloon in pressed direction" + "wind switch (any direction)" }, { "emc_steelwall_1", @@ -3462,7 +3456,7 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] = { "balloon_switch_none", "balloon_switch", - "stop moving balloon" + "wind switch (off)" }, { "emc_gate_5", @@ -3636,12 +3630,12 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] = }, { "emc_fake_grass", - "fake grass", + "fake_grass", "fake grass" }, { "emc_fake_acid", - "fake acid", + "fake_acid", "fake acid" }, { @@ -3880,6 +3874,77 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] = "-" }, + { + "emc_fake_grass.active", + "fake_grass", + "-" + }, + { + "gate_1_gray.active", + "gate", + "" + }, + { + "gate_2_gray.active", + "gate", + "" + }, + { + "gate_3_gray.active", + "gate", + "" + }, + { + "gate_4_gray.active", + "gate", + "" + }, + { + "em_gate_1_gray.active", + "gate", + "" + }, + { + "em_gate_2_gray.active", + "gate", + "" + }, + { + "em_gate_3_gray.active", + "gate", + "" + }, + { + "em_gate_4_gray.active", + "gate", + "" + }, + { + "emc_gate_5_gray.active", + "gate", + "", + }, + { + "emc_gate_6_gray.active", + "gate", + "", + }, + { + "emc_gate_7_gray.active", + "gate", + "", + }, + { + "emc_gate_8_gray.active", + "gate", + "", + }, + { + "emc_dripper.active", + "dripper", + "dripper" + }, + /* ----------------------------------------------------------------------- */ /* "unreal" (and therefore not drawable) runtime elements */ /* ----------------------------------------------------------------------- */ @@ -3974,6 +4039,11 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] = "-", "-" }, + { + "element.snapping", + "-", + "-" + }, /* ----------------------------------------------------------------------- */ /* dummy elements (never used as game elements, only used as graphics) */ @@ -4124,6 +4194,146 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] = "internal", "-" }, + { + "internal_cascade_bd", + "internal", + "show Boulder Dash elements" + }, + { + "internal_cascade_bd.active", + "internal", + "hide Boulder Dash elements" + }, + { + "internal_cascade_em", + "internal", + "show Emerald Mine elements" + }, + { + "internal_cascade_em.active", + "internal", + "hide Emerald Mine elements" + }, + { + "internal_cascade_emc", + "internal", + "show Emerald Mine Club elements" + }, + { + "internal_cascade_emc.active", + "internal", + "hide Emerald Mine Club elements" + }, + { + "internal_cascade_rnd", + "internal", + "show Rocks'n'Diamonds elements" + }, + { + "internal_cascade_rnd.active", + "internal", + "hide Rocks'n'Diamonds elements" + }, + { + "internal_cascade_sb", + "internal", + "show Sokoban elements" + }, + { + "internal_cascade_sb.active", + "internal", + "hide Sokoban elements" + }, + { + "internal_cascade_sp", + "internal", + "show Supaplex elements" + }, + { + "internal_cascade_sp.active", + "internal", + "hide Supaplex elements" + }, + { + "internal_cascade_dc", + "internal", + "show Diamond Caves II elements" + }, + { + "internal_cascade_dc.active", + "internal", + "hide Diamond Caves II elements" + }, + { + "internal_cascade_dx", + "internal", + "show DX Boulderdash elements" + }, + { + "internal_cascade_dx.active", + "internal", + "hide DX Boulderdash elements" + }, + { + "internal_cascade_chars", + "internal", + "show text elements" + }, + { + "internal_cascade_chars.active", + "internal", + "hide text elements" + }, + { + "internal_cascade_ce", + "internal", + "show custom elements" + }, + { + "internal_cascade_ce.active", + "internal", + "hide custom elements" + }, + { + "internal_cascade_ge", + "internal", + "show group elements" + }, + { + "internal_cascade_ge.active", + "internal", + "hide group elements" + }, + { + "internal_cascade_user", + "internal", + "show user defined elements" + }, + { + "internal_cascade_user.active", + "internal", + "hide user defined elements" + }, + { + "internal_cascade_generic", + "internal", + "show elements" + }, + { + "internal_cascade_generic.active", + "internal", + "hide elements" + }, + { + "internal_cascade_dynamic", + "internal", + "show elements used in this level" + }, + { + "internal_cascade_dynamic.active", + "internal", + "hide elements used in this level" + }, /* keyword to stop parser: "ELEMENT_INFO_END" <-- do not change! */ @@ -4193,6 +4403,38 @@ struct ElementActionInfo element_action_info[NUM_ACTIONS + 1 + 1] = { ".slurped_by_spring", ACTION_SLURPED_BY_SPRING, FALSE }, { ".twinkling", ACTION_TWINKLING, FALSE }, { ".splashing", ACTION_SPLASHING, FALSE }, + { ".page[1]", ACTION_PAGE_1, FALSE }, + { ".page[2]", ACTION_PAGE_2, FALSE }, + { ".page[3]", ACTION_PAGE_3, FALSE }, + { ".page[4]", ACTION_PAGE_4, FALSE }, + { ".page[5]", ACTION_PAGE_5, FALSE }, + { ".page[6]", ACTION_PAGE_6, FALSE }, + { ".page[7]", ACTION_PAGE_7, FALSE }, + { ".page[8]", ACTION_PAGE_8, FALSE }, + { ".page[9]", ACTION_PAGE_9, FALSE }, + { ".page[10]", ACTION_PAGE_10, FALSE }, + { ".page[11]", ACTION_PAGE_11, FALSE }, + { ".page[12]", ACTION_PAGE_12, FALSE }, + { ".page[13]", ACTION_PAGE_13, FALSE }, + { ".page[14]", ACTION_PAGE_14, FALSE }, + { ".page[15]", ACTION_PAGE_15, FALSE }, + { ".page[16]", ACTION_PAGE_16, FALSE }, + { ".page[17]", ACTION_PAGE_17, FALSE }, + { ".page[18]", ACTION_PAGE_18, FALSE }, + { ".page[19]", ACTION_PAGE_19, FALSE }, + { ".page[20]", ACTION_PAGE_20, FALSE }, + { ".page[21]", ACTION_PAGE_21, FALSE }, + { ".page[22]", ACTION_PAGE_22, FALSE }, + { ".page[23]", ACTION_PAGE_23, FALSE }, + { ".page[24]", ACTION_PAGE_24, FALSE }, + { ".page[25]", ACTION_PAGE_25, FALSE }, + { ".page[26]", ACTION_PAGE_26, FALSE }, + { ".page[27]", ACTION_PAGE_27, FALSE }, + { ".page[28]", ACTION_PAGE_28, FALSE }, + { ".page[29]", ACTION_PAGE_29, FALSE }, + { ".page[30]", ACTION_PAGE_30, FALSE }, + { ".page[31]", ACTION_PAGE_31, FALSE }, + { ".page[32]", ACTION_PAGE_32, FALSE }, { ".other", ACTION_OTHER, FALSE }, /* empty suffix always matches -- check as last entry in InitSoundInfo() */ diff --git a/src/main.h b/src/main.h index 2de55a4e..86a7ea1d 100644 --- a/src/main.h +++ b/src/main.h @@ -29,141 +29,148 @@ #include "conf_snd.h" /* include auto-generated data structure definitions */ #include "conf_mus.h" /* include auto-generated data structure definitions */ -#define IMG_UNDEFINED (-1) -#define IMG_EMPTY IMG_EMPTY_SPACE -#define IMG_SP_EMPTY IMG_SP_EMPTY_SPACE -#define IMG_EXPLOSION IMG_DEFAULT_EXPLODING -#define IMG_CHAR_START IMG_CHAR_SPACE -#define IMG_CUSTOM_START IMG_CUSTOM_1 - -#define SND_UNDEFINED (-1) -#define MUS_UNDEFINED (-1) - -#define WIN_XSIZE 672 -#define WIN_YSIZE 560 - -#define SCR_FIELDX 17 -#define SCR_FIELDY 17 -#define MAX_BUF_XSIZE (SCR_FIELDX + 2) -#define MAX_BUF_YSIZE (SCR_FIELDY + 2) -#define MIN_LEV_FIELDX 3 -#define MIN_LEV_FIELDY 3 -#define STD_LEV_FIELDX 64 -#define STD_LEV_FIELDY 32 -#define MAX_LEV_FIELDX 128 -#define MAX_LEV_FIELDY 128 - -#define SCREENX(a) ((a) - scroll_x) -#define SCREENY(a) ((a) - scroll_y) -#define LEVELX(a) ((a) + scroll_x) -#define LEVELY(a) ((a) + scroll_y) +#define IMG_UNDEFINED (-1) +#define IMG_EMPTY IMG_EMPTY_SPACE +#define IMG_SP_EMPTY IMG_SP_EMPTY_SPACE +#define IMG_EXPLOSION IMG_DEFAULT_EXPLODING +#define IMG_CHAR_START IMG_CHAR_SPACE +#define IMG_CUSTOM_START IMG_CUSTOM_1 + +#define SND_UNDEFINED (-1) +#define MUS_UNDEFINED (-1) + +#define WIN_XSIZE 672 +#define WIN_YSIZE 560 + +#define SCR_FIELDX 17 +#define SCR_FIELDY 17 +#define MAX_BUF_XSIZE (SCR_FIELDX + 2) +#define MAX_BUF_YSIZE (SCR_FIELDY + 2) +#define MIN_LEV_FIELDX 3 +#define MIN_LEV_FIELDY 3 +#define STD_LEV_FIELDX 64 +#define STD_LEV_FIELDY 32 +#define MAX_LEV_FIELDX 128 +#define MAX_LEV_FIELDY 128 + +#define SCREENX(a) ((a) - scroll_x) +#define SCREENY(a) ((a) - scroll_y) +#define LEVELX(a) ((a) + scroll_x) +#define LEVELY(a) ((a) + scroll_y) #define IN_VIS_FIELD(x,y) ((x)>=0 && (x)=0 &&(y)=BX1 && (x)<=BX2 && (y)>=BY1 &&(y)<=BY2) #define IN_LEV_FIELD(x,y) ((x)>=0 && (x)=0 &&(y)has_event[c]) -#define CH_ANY_EVENT_VAR(e,c) (element_info[e].has_change_event[c]) - -#define PAGE_HAS_CHANGE_EVENT(p,c) ((p)->has_event[c]) -#define HAS_CHANGE_EVENT(e,c) (IS_CUSTOM_ELEMENT(e) && \ - CH_EVENT_VAR(e,c)) -#define HAS_ANY_CHANGE_EVENT(e,c) (IS_CUSTOM_ELEMENT(e) && \ - CH_ANY_EVENT_VAR(e,c)) - -#define SET_CHANGE_EVENT(e,c,v) (IS_CUSTOM_ELEMENT(e) ? \ - CH_EVENT_VAR(e,c) = (v) : 0) -#define SET_ANY_CHANGE_EVENT(e,c,v) (IS_CUSTOM_ELEMENT(e) ? \ - CH_ANY_EVENT_VAR(e,c) = (v) : 0) - -#else - -#define CH_EVENT_BIT(c) (1 << (c)) -#define CH_EVENT_VAR(e) (element_info[e].change->events) -#define CH_ANY_EVENT_VAR(e) (element_info[e].change_events) - -#define HAS_CHANGE_EVENT(e,c) (IS_CUSTOM_ELEMENT(e) && \ - (CH_EVENT_VAR(e) & CH_EVENT_BIT(c)) != 0) -#define HAS_ANY_CHANGE_EVENT(e,c) (IS_CUSTOM_ELEMENT(e) && \ - (CH_ANY_EVENT_VAR(e) & CH_EVENT_BIT(c)) != 0) -#define SET_CHANGE_EVENT(e,c,v) (IS_CUSTOM_ELEMENT(e) ? \ - ((v) ? \ - (CH_EVENT_VAR(e) |= CH_EVENT_BIT(c)) : \ - (CH_EVENT_VAR(e) &= ~CH_EVENT_BIT(c))) : 0) -#define SET_ANY_CHANGE_EVENT(e,c,v) (IS_CUSTOM_ELEMENT(e) ? \ - ((v) ? \ - (CH_ANY_EVENT_VAR(e) |= CH_EVENT_BIT(c)) : \ - (CH_ANY_EVENT_VAR(e) &= ~CH_EVENT_BIT(c))) : 0) -#endif +#define CE_DELAY 0 +#define CE_TOUCHED_BY_PLAYER 1 +#define CE_PRESSED_BY_PLAYER 2 +#define CE_PUSHED_BY_PLAYER 3 +#define CE_DROPPED_BY_PLAYER 4 +#define CE_HITTING_SOMETHING 5 +#define CE_IMPACT 6 +#define CE_SMASHED 7 +#define CE_TOUCHING_X 8 +#define CE_CHANGE_OF_X 9 +#define CE_EXPLOSION_OF_X 10 +#define CE_PLAYER_TOUCHES_X 11 +#define CE_PLAYER_PRESSES_X 12 +#define CE_PLAYER_PUSHES_X 13 +#define CE_PLAYER_COLLECTS_X 14 +#define CE_PLAYER_DROPS_X 15 +#define CE_VALUE_GETS_ZERO 16 +#define CE_VALUE_GETS_ZERO_OF_X 17 +#define CE_BY_OTHER_ACTION 18 +#define CE_BY_DIRECT_ACTION 19 +#define CE_PLAYER_DIGS_X 20 +#define CE_ENTERED_BY_PLAYER 21 +#define CE_LEFT_BY_PLAYER 22 +#define CE_PLAYER_ENTERS_X 23 +#define CE_PLAYER_LEAVES_X 24 +#define CE_SWITCHED 25 +#define CE_SWITCH_OF_X 26 +#define CE_HIT_BY_SOMETHING 27 +#define CE_HITTING_X 28 +#define CE_HIT_BY_X 29 +#define CE_BLOCKED 30 +#define CE_SWITCHED_BY_PLAYER 31 +#define CE_PLAYER_SWITCHES_X 32 +#define CE_SNAPPED_BY_PLAYER 33 +#define CE_PLAYER_SNAPS_X 34 +#define CE_MOVE_OF_X 35 +#define CE_DIGGING_X 36 +#define CE_CREATION_OF_X 37 + +#define NUM_CHANGE_EVENTS 38 + +#define CE_BITMASK_DEFAULT 0 + +#define CH_EVENT_VAR(e,c) (element_info[e].change->has_event[c]) +#define CH_ANY_EVENT_VAR(e,c) (element_info[e].has_change_event[c]) + +#define PAGE_HAS_CHANGE_EVENT(p,c) ((p)->has_event[c]) +#define HAS_CHANGE_EVENT(e,c) (IS_CUSTOM_ELEMENT(e) && \ + CH_EVENT_VAR(e,c)) +#define HAS_ANY_CHANGE_EVENT(e,c) (IS_CUSTOM_ELEMENT(e) && \ + CH_ANY_EVENT_VAR(e,c)) + +#define SET_CHANGE_EVENT(e,c,v) (IS_CUSTOM_ELEMENT(e) ? \ + CH_EVENT_VAR(e,c) = (v) : 0) +#define SET_ANY_CHANGE_EVENT(e,c,v) (IS_CUSTOM_ELEMENT(e) ? \ + CH_ANY_EVENT_VAR(e,c) = (v) : 0) + +/* values for player bitmasks */ +#define PLAYER_BITS_NONE 0 +#define PLAYER_BITS_1 (1 << 0) +#define PLAYER_BITS_2 (1 << 1) +#define PLAYER_BITS_3 (1 << 2) +#define PLAYER_BITS_4 (1 << 3) +#define PLAYER_BITS_ANY (PLAYER_BITS_1 | \ + PLAYER_BITS_2 | \ + PLAYER_BITS_3 | \ + PLAYER_BITS_4) +#define PLAYER_BITS_TRIGGER (1 << 4) + +/* values for move directions (bits 0 - 3: basic move directions) */ +#define MV_BIT_PREVIOUS 4 +#define MV_BIT_TRIGGER 5 +#define MV_BIT_TRIGGER_BACK 6 +#define MV_BIT_NORMAL MV_BIT_TRIGGER +#define MV_BIT_REVERSE MV_BIT_TRIGGER_BACK + +#define MV_PREVIOUS (1 << MV_BIT_PREVIOUS) +#define MV_TRIGGER (1 << MV_BIT_TRIGGER) +#define MV_TRIGGER_BACK (1 << MV_BIT_TRIGGER_BACK) +#define MV_NORMAL (1 << MV_BIT_NORMAL) +#define MV_REVERSE (1 << MV_BIT_REVERSE) + +/* values for move stepsize */ +#define STEPSIZE_NOT_MOVING 0 +#define STEPSIZE_VERY_SLOW 1 +#define STEPSIZE_SLOW 2 +#define STEPSIZE_NORMAL 4 +#define STEPSIZE_FAST 8 +#define STEPSIZE_VERY_FAST 16 +#define STEPSIZE_EVEN_FASTER 32 +#define STEPSIZE_SLOWER 50 /* (symbolic value only) */ +#define STEPSIZE_FASTER 200 /* (symbolic value only) */ +#define STEPSIZE_RESET 100 /* (symbolic value only) */ /* values for change side for custom elements */ -#define CH_SIDE_NONE MV_NO_MOVING -#define CH_SIDE_LEFT MV_LEFT -#define CH_SIDE_RIGHT MV_RIGHT -#define CH_SIDE_TOP MV_UP -#define CH_SIDE_BOTTOM MV_DOWN -#define CH_SIDE_LEFT_RIGHT MV_HORIZONTAL -#define CH_SIDE_TOP_BOTTOM MV_VERTICAL -#define CH_SIDE_ANY MV_ANY_DIRECTION +#define CH_SIDE_NONE MV_NONE +#define CH_SIDE_LEFT MV_LEFT +#define CH_SIDE_RIGHT MV_RIGHT +#define CH_SIDE_TOP MV_UP +#define CH_SIDE_BOTTOM MV_DOWN +#define CH_SIDE_LEFT_RIGHT MV_HORIZONTAL +#define CH_SIDE_TOP_BOTTOM MV_VERTICAL +#define CH_SIDE_ANY MV_ANY_DIRECTION /* values for change player for custom elements */ -#define CH_PLAYER_NONE 0 -#define CH_PLAYER_1 (1 << 0) -#define CH_PLAYER_2 (1 << 1) -#define CH_PLAYER_3 (1 << 2) -#define CH_PLAYER_4 (1 << 3) -#define CH_PLAYER_ANY (CH_PLAYER_1 | CH_PLAYER_2 | CH_PLAYER_3 | \ - CH_PLAYER_4) +#define CH_PLAYER_NONE PLAYER_BITS_NONE +#define CH_PLAYER_1 PLAYER_BITS_1 +#define CH_PLAYER_2 PLAYER_BITS_2 +#define CH_PLAYER_3 PLAYER_BITS_3 +#define CH_PLAYER_4 PLAYER_BITS_4 +#define CH_PLAYER_ANY PLAYER_BITS_ANY /* values for change page for custom elements */ -#define CH_PAGE_ANY_FILE (0xff) -#define CH_PAGE_ANY (0xffffffff) +#define CH_PAGE_ANY_FILE (0xff) +#define CH_PAGE_ANY (0xffffffff) /* values for change power for custom elements */ -#define CP_WHEN_EMPTY 0 -#define CP_WHEN_DIGGABLE 1 -#define CP_WHEN_DESTRUCTIBLE 2 -#define CP_WHEN_COLLECTIBLE 3 -#define CP_WHEN_REMOVABLE 4 -#define CP_WHEN_WALKABLE 5 +#define CP_WHEN_EMPTY 0 +#define CP_WHEN_DIGGABLE 1 +#define CP_WHEN_DESTRUCTIBLE 2 +#define CP_WHEN_COLLECTIBLE 3 +#define CP_WHEN_REMOVABLE 4 +#define CP_WHEN_WALKABLE 5 + +/* values for change actions for custom elements */ +#define CA_NO_ACTION 0 +#define CA_EXIT_PLAYER 1 +#define CA_KILL_PLAYER 2 +#define CA_MOVE_PLAYER 3 +#define CA_RESTART_LEVEL 4 +#define CA_SHOW_ENVELOPE 5 +#define CA_SET_LEVEL_TIME 6 +#define CA_SET_LEVEL_GEMS 7 +#define CA_SET_LEVEL_SCORE 8 +#define CA_SET_LEVEL_WIND 9 +#define CA_SET_LEVEL_GRAVITY 10 +#define CA_SET_PLAYER_KEYS 11 +#define CA_SET_PLAYER_SPEED 12 +#define CA_SET_PLAYER_SHIELD 13 +#define CA_SET_PLAYER_ARTWORK 14 +#define CA_SET_CE_SCORE 15 +#define CA_SET_CE_VALUE 16 +#define CA_SET_ENGINE_SCAN_MODE 17 + +#define CA_HEADLINE_LEVEL_ACTIONS 250 +#define CA_HEADLINE_PLAYER_ACTIONS 251 +#define CA_HEADLINE_CE_ACTIONS 252 +#define CA_HEADLINE_ENGINE_ACTIONS 253 +#define CA_UNDEFINED 255 + +/* values for change action mode for custom elements */ +#define CA_MODE_UNDEFINED 0 +#define CA_MODE_SET 1 +#define CA_MODE_ADD 2 +#define CA_MODE_SUBTRACT 3 +#define CA_MODE_MULTIPLY 4 +#define CA_MODE_DIVIDE 5 +#define CA_MODE_MODULO 6 + +/* values for change action parameters for custom elements */ +#define CA_ARG_MIN 0 +#define CA_ARG_0 0 +#define CA_ARG_1 1 +#define CA_ARG_2 2 +#define CA_ARG_3 3 +#define CA_ARG_4 4 +#define CA_ARG_5 5 +#define CA_ARG_6 6 +#define CA_ARG_7 7 +#define CA_ARG_8 8 +#define CA_ARG_9 9 +#define CA_ARG_10 10 +#define CA_ARG_100 100 +#define CA_ARG_1000 1000 +#define CA_ARG_MAX 9999 +#define CA_ARG_PLAYER 10000 +#define CA_ARG_PLAYER_1 (CA_ARG_PLAYER + PLAYER_BITS_1) +#define CA_ARG_PLAYER_2 (CA_ARG_PLAYER + PLAYER_BITS_2) +#define CA_ARG_PLAYER_3 (CA_ARG_PLAYER + PLAYER_BITS_3) +#define CA_ARG_PLAYER_4 (CA_ARG_PLAYER + PLAYER_BITS_4) +#define CA_ARG_PLAYER_ANY (CA_ARG_PLAYER + PLAYER_BITS_ANY) +#define CA_ARG_PLAYER_TRIGGER (CA_ARG_PLAYER + PLAYER_BITS_TRIGGER) +#define CA_ARG_PLAYER_HEADLINE (CA_ARG_PLAYER + 999) +#define CA_ARG_NUMBER 11000 +#define CA_ARG_NUMBER_MIN (CA_ARG_NUMBER + 0) +#define CA_ARG_NUMBER_MAX (CA_ARG_NUMBER + 1) +#define CA_ARG_NUMBER_RESET (CA_ARG_NUMBER + 2) +#define CA_ARG_NUMBER_CE_SCORE (CA_ARG_NUMBER + 3) +#define CA_ARG_NUMBER_CE_VALUE (CA_ARG_NUMBER + 4) +#define CA_ARG_NUMBER_CE_DELAY (CA_ARG_NUMBER + 5) +#define CA_ARG_NUMBER_LEVEL_TIME (CA_ARG_NUMBER + 6) +#define CA_ARG_NUMBER_LEVEL_GEMS (CA_ARG_NUMBER + 7) +#define CA_ARG_NUMBER_LEVEL_SCORE (CA_ARG_NUMBER + 8) +#define CA_ARG_NUMBER_HEADLINE (CA_ARG_NUMBER + 999) +#define CA_ARG_ELEMENT 12000 +#define CA_ARG_ELEMENT_RESET (CA_ARG_ELEMENT + 0) +#define CA_ARG_ELEMENT_TARGET (CA_ARG_ELEMENT + 1) +#define CA_ARG_ELEMENT_TRIGGER (CA_ARG_ELEMENT + 2) +#define CA_ARG_ELEMENT_HEADLINE (CA_ARG_ELEMENT + 999) +#define CA_ARG_SPEED 13000 +#define CA_ARG_SPEED_NOT_MOVING (CA_ARG_SPEED + STEPSIZE_NOT_MOVING) +#define CA_ARG_SPEED_VERY_SLOW (CA_ARG_SPEED + STEPSIZE_VERY_SLOW) +#define CA_ARG_SPEED_SLOW (CA_ARG_SPEED + STEPSIZE_SLOW) +#define CA_ARG_SPEED_NORMAL (CA_ARG_SPEED + STEPSIZE_NORMAL) +#define CA_ARG_SPEED_FAST (CA_ARG_SPEED + STEPSIZE_FAST) +#define CA_ARG_SPEED_VERY_FAST (CA_ARG_SPEED + STEPSIZE_VERY_FAST) +#define CA_ARG_SPEED_EVEN_FASTER (CA_ARG_SPEED + STEPSIZE_EVEN_FASTER) +#define CA_ARG_SPEED_SLOWER (CA_ARG_SPEED + STEPSIZE_SLOWER) +#define CA_ARG_SPEED_FASTER (CA_ARG_SPEED + STEPSIZE_FASTER) +#define CA_ARG_SPEED_RESET (CA_ARG_SPEED + STEPSIZE_RESET) +#define CA_ARG_SPEED_HEADLINE (CA_ARG_SPEED + 999) +#define CA_ARG_GRAVITY 14000 +#define CA_ARG_GRAVITY_OFF (CA_ARG_GRAVITY + 0) +#define CA_ARG_GRAVITY_ON (CA_ARG_GRAVITY + 1) +#define CA_ARG_GRAVITY_TOGGLE (CA_ARG_GRAVITY + 2) +#define CA_ARG_GRAVITY_HEADLINE (CA_ARG_GRAVITY + 999) +#define CA_ARG_DIRECTION 15000 +#define CA_ARG_DIRECTION_NONE (CA_ARG_DIRECTION + MV_NONE) +#define CA_ARG_DIRECTION_LEFT (CA_ARG_DIRECTION + MV_LEFT) +#define CA_ARG_DIRECTION_RIGHT (CA_ARG_DIRECTION + MV_RIGHT) +#define CA_ARG_DIRECTION_UP (CA_ARG_DIRECTION + MV_UP) +#define CA_ARG_DIRECTION_DOWN (CA_ARG_DIRECTION + MV_DOWN) +#define CA_ARG_DIRECTION_TRIGGER (CA_ARG_DIRECTION + MV_TRIGGER) +#define CA_ARG_DIRECTION_TRIGGER_BACK (CA_ARG_DIRECTION + MV_TRIGGER_BACK) +#define CA_ARG_DIRECTION_HEADLINE (CA_ARG_DIRECTION + 999) +#define CA_ARG_SHIELD 16000 +#define CA_ARG_SHIELD_OFF (CA_ARG_SHIELD + 0) +#define CA_ARG_SHIELD_NORMAL (CA_ARG_SHIELD + 1) +#define CA_ARG_SHIELD_DEADLY (CA_ARG_SHIELD + 2) +#define CA_ARG_SHIELD_HEADLINE (CA_ARG_SHIELD + 999) +#define CA_ARG_SCAN_MODE 17000 +#define CA_ARG_SCAN_MODE_NORMAL (CA_ARG_SCAN_MODE + MV_NORMAL) +#define CA_ARG_SCAN_MODE_REVERSE (CA_ARG_SCAN_MODE + MV_REVERSE) +#define CA_ARG_SCAN_MODE_HEADLINE (CA_ARG_SCAN_MODE + 999) +#define CA_ARG_UNDEFINED 65535 /* values for custom move patterns (bits 0 - 3: basic move directions) */ -#define MV_BIT_TOWARDS_PLAYER 4 -#define MV_BIT_AWAY_FROM_PLAYER 5 -#define MV_BIT_ALONG_LEFT_SIDE 6 -#define MV_BIT_ALONG_RIGHT_SIDE 7 -#define MV_BIT_TURNING_LEFT 8 -#define MV_BIT_TURNING_RIGHT 9 -#define MV_BIT_WHEN_PUSHED 10 -#define MV_BIT_MAZE_RUNNER 11 -#define MV_BIT_MAZE_HUNTER 12 -#define MV_BIT_WHEN_DROPPED 13 -#define MV_BIT_TURNING_LEFT_RIGHT 14 -#define MV_BIT_TURNING_RIGHT_LEFT 15 -#define MV_BIT_TURNING_RANDOM 16 +#define MV_BIT_TOWARDS_PLAYER 4 +#define MV_BIT_AWAY_FROM_PLAYER 5 +#define MV_BIT_ALONG_LEFT_SIDE 6 +#define MV_BIT_ALONG_RIGHT_SIDE 7 +#define MV_BIT_TURNING_LEFT 8 +#define MV_BIT_TURNING_RIGHT 9 +#define MV_BIT_WHEN_PUSHED 10 +#define MV_BIT_MAZE_RUNNER 11 +#define MV_BIT_MAZE_HUNTER 12 +#define MV_BIT_WHEN_DROPPED 13 +#define MV_BIT_TURNING_LEFT_RIGHT 14 +#define MV_BIT_TURNING_RIGHT_LEFT 15 +#define MV_BIT_TURNING_RANDOM 16 +#define MV_BIT_WIND_DIRECTION 17 /* values for custom move patterns */ -#define MV_TOWARDS_PLAYER (1 << MV_BIT_TOWARDS_PLAYER) -#define MV_AWAY_FROM_PLAYER (1 << MV_BIT_AWAY_FROM_PLAYER) -#define MV_ALONG_LEFT_SIDE (1 << MV_BIT_ALONG_LEFT_SIDE) -#define MV_ALONG_RIGHT_SIDE (1 << MV_BIT_ALONG_RIGHT_SIDE) -#define MV_TURNING_LEFT (1 << MV_BIT_TURNING_LEFT) -#define MV_TURNING_RIGHT (1 << MV_BIT_TURNING_RIGHT) -#define MV_WHEN_PUSHED (1 << MV_BIT_WHEN_PUSHED) -#define MV_MAZE_RUNNER (1 << MV_BIT_MAZE_RUNNER) -#define MV_MAZE_HUNTER (1 << MV_BIT_MAZE_HUNTER) -#define MV_MAZE_RUNNER_STYLE (MV_MAZE_RUNNER | MV_MAZE_HUNTER) -#define MV_WHEN_DROPPED (1 << MV_BIT_WHEN_DROPPED) -#define MV_TURNING_LEFT_RIGHT (1 << MV_BIT_TURNING_LEFT_RIGHT) -#define MV_TURNING_RIGHT_LEFT (1 << MV_BIT_TURNING_RIGHT_LEFT) -#define MV_TURNING_RANDOM (1 << MV_BIT_TURNING_RANDOM) - -/* values for initial move direction (bits 0 - 3: basic move directions) */ -#define MV_START_BIT_PREVIOUS 4 +#define MV_TOWARDS_PLAYER (1 << MV_BIT_TOWARDS_PLAYER) +#define MV_AWAY_FROM_PLAYER (1 << MV_BIT_AWAY_FROM_PLAYER) +#define MV_ALONG_LEFT_SIDE (1 << MV_BIT_ALONG_LEFT_SIDE) +#define MV_ALONG_RIGHT_SIDE (1 << MV_BIT_ALONG_RIGHT_SIDE) +#define MV_TURNING_LEFT (1 << MV_BIT_TURNING_LEFT) +#define MV_TURNING_RIGHT (1 << MV_BIT_TURNING_RIGHT) +#define MV_WHEN_PUSHED (1 << MV_BIT_WHEN_PUSHED) +#define MV_MAZE_RUNNER (1 << MV_BIT_MAZE_RUNNER) +#define MV_MAZE_HUNTER (1 << MV_BIT_MAZE_HUNTER) +#define MV_MAZE_RUNNER_STYLE (MV_MAZE_RUNNER | MV_MAZE_HUNTER) +#define MV_WHEN_DROPPED (1 << MV_BIT_WHEN_DROPPED) +#define MV_TURNING_LEFT_RIGHT (1 << MV_BIT_TURNING_LEFT_RIGHT) +#define MV_TURNING_RIGHT_LEFT (1 << MV_BIT_TURNING_RIGHT_LEFT) +#define MV_TURNING_RANDOM (1 << MV_BIT_TURNING_RANDOM) +#define MV_WIND_DIRECTION (1 << MV_BIT_WIND_DIRECTION) /* values for initial move direction */ -#define MV_START_AUTOMATIC (MV_NO_MOVING) -#define MV_START_LEFT (MV_LEFT) -#define MV_START_RIGHT (MV_RIGHT) -#define MV_START_UP (MV_UP) -#define MV_START_DOWN (MV_DOWN) -#define MV_START_RANDOM (MV_ALL_DIRECTIONS) -#define MV_START_PREVIOUS (1 << MV_START_BIT_PREVIOUS) +#define MV_START_NONE (MV_NONE) +#define MV_START_AUTOMATIC (MV_NONE) +#define MV_START_LEFT (MV_LEFT) +#define MV_START_RIGHT (MV_RIGHT) +#define MV_START_UP (MV_UP) +#define MV_START_DOWN (MV_DOWN) +#define MV_START_RANDOM (MV_ALL_DIRECTIONS) +#define MV_START_PREVIOUS (MV_PREVIOUS) /* values for elements left behind by custom elements */ -#define LEAVE_TYPE_UNLIMITED 0 -#define LEAVE_TYPE_LIMITED 1 +#define LEAVE_TYPE_UNLIMITED 0 +#define LEAVE_TYPE_LIMITED 1 /* values for slippery property for custom elements */ -#define SLIPPERY_ANY_RANDOM 0 -#define SLIPPERY_ANY_LEFT_RIGHT 1 -#define SLIPPERY_ANY_RIGHT_LEFT 2 -#define SLIPPERY_ONLY_LEFT 3 -#define SLIPPERY_ONLY_RIGHT 4 +#define SLIPPERY_ANY_RANDOM 0 +#define SLIPPERY_ANY_LEFT_RIGHT 1 +#define SLIPPERY_ANY_RIGHT_LEFT 2 +#define SLIPPERY_ONLY_LEFT 3 +#define SLIPPERY_ONLY_RIGHT 4 /* values for explosion type for custom elements */ -#define EXPLODES_3X3 0 -#define EXPLODES_1X1 1 -#define EXPLODES_CROSS 2 +#define EXPLODES_3X3 0 +#define EXPLODES_1X1 1 +#define EXPLODES_CROSS 2 /* macros for configurable properties */ #define IS_DIGGABLE(e) HAS_PROPERTY(e, EP_DIGGABLE) @@ -393,7 +533,7 @@ #define IS_KEYGATE(e) HAS_PROPERTY(e, EP_KEYGATE) #define IS_AMOEBOID(e) HAS_PROPERTY(e, EP_AMOEBOID) #define IS_AMOEBALIVE(e) HAS_PROPERTY(e, EP_AMOEBALIVE) -#define HAS_CONTENT(e) HAS_PROPERTY(e, EP_HAS_CONTENT) +#define HAS_EDITOR_CONTENT(e) HAS_PROPERTY(e, EP_HAS_EDITOR_CONTENT) #define CAN_TURN_EACH_MOVE(e) HAS_PROPERTY(e, EP_CAN_TURN_EACH_MOVE) #define CAN_GROW(e) HAS_PROPERTY(e, EP_CAN_GROW) #define IS_ACTIVE_BOMB(e) HAS_PROPERTY(e, EP_ACTIVE_BOMB) @@ -425,6 +565,16 @@ #define COULD_MOVE_INTO_ACID(e) HAS_PROPERTY(e, EP_COULD_MOVE_INTO_ACID) #define MAYBE_DONT_COLLIDE_WITH(e) HAS_PROPERTY(e, EP_MAYBE_DONT_COLLIDE_WITH) +#define IS_EDITOR_CASCADE(e) HAS_PROPERTY(e, EP_EDITOR_CASCADE) +#define IS_EDITOR_CASCADE_ACTIVE(e) \ + HAS_PROPERTY(e, EP_EDITOR_CASCADE_ACTIVE) +#define IS_EDITOR_CASCADE_INACTIVE(e) \ + HAS_PROPERTY(e, EP_EDITOR_CASCADE_INACTIVE) + +#define HAS_ACTION(e) HAS_PROPERTY(e, EP_HAS_ACTION) +#define CAN_CHANGE_OR_HAS_ACTION(e) \ + HAS_PROPERTY(e, EP_CAN_CHANGE_OR_HAS_ACTION) + /* special macros used in game engine */ #define IS_CUSTOM_ELEMENT(e) ((e) >= EL_CUSTOM_START && \ (e) <= EL_CUSTOM_END) @@ -475,16 +625,28 @@ #define IS_RND_GATE_GRAY(e) ((e) >= EL_GATE_1_GRAY && \ (e) <= EL_GATE_4_GRAY) +#define IS_RND_GATE_GRAY_ACTIVE(e) ((e) >= EL_GATE_1_GRAY_ACTIVE && \ + (e) <= EL_GATE_4_GRAY_ACTIVE) #define IS_EM_GATE_GRAY(e) ((e) >= EL_EM_GATE_1_GRAY && \ (e) <= EL_EM_GATE_4_GRAY) +#define IS_EM_GATE_GRAY_ACTIVE(e) ((e) >= EL_EM_GATE_1_GRAY_ACTIVE && \ + (e) <= EL_EM_GATE_4_GRAY_ACTIVE) #define IS_EMC_GATE_GRAY(e) ((e) >= EL_EMC_GATE_5_GRAY && \ (e) <= EL_EMC_GATE_8_GRAY) +#define IS_EMC_GATE_GRAY_ACTIVE(e) ((e) >= EL_EMC_GATE_5_GRAY_ACTIVE && \ + (e) <= EL_EMC_GATE_8_GRAY_ACTIVE) #define IS_GATE_GRAY(e) (IS_RND_GATE_GRAY(e) || \ IS_EM_GATE_GRAY(e) || \ IS_EMC_GATE_GRAY(e)) +#define IS_GATE_GRAY_ACTIVE(e) (IS_RND_GATE_GRAY_ACTIVE(e) || \ + IS_EM_GATE_GRAY_ACTIVE(e) || \ + IS_EMC_GATE_GRAY_ACTIVE(e)) #define RND_GATE_GRAY_NR(e) ((e) - EL_GATE_1_GRAY) +#define RND_GATE_GRAY_ACTIVE_NR(e) ((e) - EL_GATE_1_GRAY_ACTIVE) #define EM_GATE_GRAY_NR(e) ((e) - EL_EM_GATE_1_GRAY) +#define EM_GATE_GRAY_ACTIVE_NR(e) ((e) - EL_EM_GATE_1_GRAY_ACTIVE) #define EMC_GATE_GRAY_NR(e) ((e) - EL_EMC_GATE_5_GRAY + 4) +#define EMC_GATE_GRAY_ACTIVE_NR(e) ((e) - EL_EMC_GATE_5_GRAY_ACTIVE + 4) #define GATE_GRAY_NR(e) (IS_RND_GATE_GRAY(e) ? RND_GATE_GRAY_NR(e) : \ IS_EM_GATE_GRAY(e) ? EM_GATE_GRAY_NR(e) : \ IS_EMC_GATE_GRAY(e) ? EMC_GATE_GRAY_NR(e) : 0) @@ -527,8 +689,6 @@ #define PLAYERINFO(x,y) (&stored_player[StorePlayer[x][y]-EL_PLAYER_1]) #define SHIELD_ON(p) ((p)->shield_normal_time_left > 0) -#if 1 - #define ENEMY_PROTECTED_FIELD(x,y) (IS_PROTECTED(Feld[x][y]) || \ IS_PROTECTED(Back[x][y])) #define EXPLOSION_PROTECTED_FIELD(x,y) (IS_EXPLOSION_PROOF(Feld[x][y])) @@ -537,16 +697,6 @@ #define PLAYER_EXPLOSION_PROTECTED(x,y) (SHIELD_ON(PLAYERINFO(x, y)) || \ EXPLOSION_PROTECTED_FIELD(x, y)) -#else - -#define PROTECTED_FIELD(x,y) (IS_ACCESSIBLE_INSIDE(Feld[x][y]) && \ - IS_INDESTRUCTIBLE(Feld[x][y])) -#define PLAYER_ENEMY_PROTECTED(x,y) (SHIELD_ON(PLAYERINFO(x, y)) || \ - PROTECTED_FIELD(x, y)) -#define PLAYER_EXPLOSION_PROTECTED(x,y) (SHIELD_ON(PLAYERINFO(x, y)) || \ - PROTECTED_FIELD(x, y)) -#endif - #define PLAYER_SWITCHING(p,x,y) ((p)->is_switching && \ (p)->switch_x == (x) && (p)->switch_y == (y)) @@ -555,6 +705,11 @@ #define PLAYER_NR_GFX(g,i) ((g) + i * (IMG_PLAYER_2 - IMG_PLAYER_1)) +#define GET_PLAYER_ELEMENT(e) ((e) >= EL_PLAYER_1 && (e) <= EL_PLAYER_4 ? \ + (e) : EL_PLAYER_1) + +#define GET_PLAYER_NR(e) (GET_PLAYER_ELEMENT(e) - EL_PLAYER_1) + #define ANIM_FRAMES(g) (graphic_info[g].anim_frames) #define ANIM_DELAY(g) (graphic_info[g].anim_delay) #define ANIM_MODE(g) (graphic_info[g].anim_mode) @@ -566,6 +721,12 @@ #define IS_LOOP_SOUND(s) (sound_info[s].loop) +#define EL_CASCADE_ACTIVE(e) (IS_EDITOR_CASCADE_INACTIVE(e) ? (e) + 1 : (e)) +#define EL_CASCADE_INACTIVE(e) (IS_EDITOR_CASCADE_ACTIVE(e) ? (e) - 1 : (e)) +#define EL_CASCADE_TOGGLE(e) (IS_EDITOR_CASCADE_INACTIVE(e) ? (e) + 1 : \ + IS_EDITOR_CASCADE_ACTIVE(e) ? (e) - 1 : (e)) + +#define EL_NAME(e) (element_info[e].token_name) /* fundamental game speed values */ #define ONE_SECOND_DELAY 1000 /* delay value for one second */ @@ -597,12 +758,13 @@ #define MAX_CHANGE_PAGES 32 #define MIN_ELEMENTS_IN_GROUP 1 #define MAX_ELEMENTS_IN_GROUP 16 +#define MIN_ANDROID_ELEMENTS 1 +#define MAX_ANDROID_ELEMENTS 16 /* values for elements with content */ #define MIN_ELEMENT_CONTENTS 1 #define STD_ELEMENT_CONTENTS 4 #define MAX_ELEMENT_CONTENTS 8 -#define NUM_MAGIC_BALL_CONTENTS 8 #define LEVEL_SCORE_ELEMENTS 16 /* level elements with score */ @@ -1120,9 +1282,23 @@ #define EL_BD_MAGIC_WALL_EMPTYING (EL_FIRST_RUNTIME_REAL + 42) #define EL_MAGIC_WALL_DEAD (EL_FIRST_RUNTIME_REAL + 43) #define EL_BD_MAGIC_WALL_DEAD (EL_FIRST_RUNTIME_REAL + 44) +#define EL_EMC_FAKE_GRASS_ACTIVE (EL_FIRST_RUNTIME_REAL + 45) +#define EL_GATE_1_GRAY_ACTIVE (EL_FIRST_RUNTIME_REAL + 46) +#define EL_GATE_2_GRAY_ACTIVE (EL_FIRST_RUNTIME_REAL + 47) +#define EL_GATE_3_GRAY_ACTIVE (EL_FIRST_RUNTIME_REAL + 48) +#define EL_GATE_4_GRAY_ACTIVE (EL_FIRST_RUNTIME_REAL + 49) +#define EL_EM_GATE_1_GRAY_ACTIVE (EL_FIRST_RUNTIME_REAL + 50) +#define EL_EM_GATE_2_GRAY_ACTIVE (EL_FIRST_RUNTIME_REAL + 51) +#define EL_EM_GATE_3_GRAY_ACTIVE (EL_FIRST_RUNTIME_REAL + 52) +#define EL_EM_GATE_4_GRAY_ACTIVE (EL_FIRST_RUNTIME_REAL + 53) +#define EL_EMC_GATE_5_GRAY_ACTIVE (EL_FIRST_RUNTIME_REAL + 54) +#define EL_EMC_GATE_6_GRAY_ACTIVE (EL_FIRST_RUNTIME_REAL + 55) +#define EL_EMC_GATE_7_GRAY_ACTIVE (EL_FIRST_RUNTIME_REAL + 56) +#define EL_EMC_GATE_8_GRAY_ACTIVE (EL_FIRST_RUNTIME_REAL + 57) +#define EL_EMC_DRIPPER_ACTIVE (EL_FIRST_RUNTIME_REAL + 58) /* "unreal" (and therefore not drawable) runtime elements */ -#define EL_FIRST_RUNTIME_UNREAL (EL_FIRST_RUNTIME_REAL + 45) +#define EL_FIRST_RUNTIME_UNREAL (EL_FIRST_RUNTIME_REAL + 59) #define EL_BLOCKED (EL_FIRST_RUNTIME_UNREAL + 0) #define EL_EXPLOSION (EL_FIRST_RUNTIME_UNREAL + 1) @@ -1142,9 +1318,10 @@ #define EL_QUICKSAND_FILLING (EL_FIRST_RUNTIME_UNREAL + 15) #define EL_MAGIC_WALL_FILLING (EL_FIRST_RUNTIME_UNREAL + 16) #define EL_BD_MAGIC_WALL_FILLING (EL_FIRST_RUNTIME_UNREAL + 17) +#define EL_ELEMENT_SNAPPING (EL_FIRST_RUNTIME_UNREAL + 18) /* dummy elements (never used as game elements, only used as graphics) */ -#define EL_FIRST_DUMMY (EL_FIRST_RUNTIME_UNREAL + 18) +#define EL_FIRST_DUMMY (EL_FIRST_RUNTIME_UNREAL + 19) #define EL_STEELWALL_TOPLEFT (EL_FIRST_DUMMY + 0) #define EL_STEELWALL_TOPRIGHT (EL_FIRST_DUMMY + 1) @@ -1180,12 +1357,41 @@ #define EL_INTERNAL_CLIPBOARD_GROUP (EL_FIRST_INTERNAL + 2) #define EL_INTERNAL_DUMMY (EL_FIRST_INTERNAL + 3) +#define EL_INTERNAL_CASCADE_BD (EL_FIRST_INTERNAL + 4) +#define EL_INTERNAL_CASCADE_BD_ACTIVE (EL_FIRST_INTERNAL + 5) +#define EL_INTERNAL_CASCADE_EM (EL_FIRST_INTERNAL + 6) +#define EL_INTERNAL_CASCADE_EM_ACTIVE (EL_FIRST_INTERNAL + 7) +#define EL_INTERNAL_CASCADE_EMC (EL_FIRST_INTERNAL + 8) +#define EL_INTERNAL_CASCADE_EMC_ACTIVE (EL_FIRST_INTERNAL + 9) +#define EL_INTERNAL_CASCADE_RND (EL_FIRST_INTERNAL + 10) +#define EL_INTERNAL_CASCADE_RND_ACTIVE (EL_FIRST_INTERNAL + 11) +#define EL_INTERNAL_CASCADE_SB (EL_FIRST_INTERNAL + 12) +#define EL_INTERNAL_CASCADE_SB_ACTIVE (EL_FIRST_INTERNAL + 13) +#define EL_INTERNAL_CASCADE_SP (EL_FIRST_INTERNAL + 14) +#define EL_INTERNAL_CASCADE_SP_ACTIVE (EL_FIRST_INTERNAL + 15) +#define EL_INTERNAL_CASCADE_DC (EL_FIRST_INTERNAL + 16) +#define EL_INTERNAL_CASCADE_DC_ACTIVE (EL_FIRST_INTERNAL + 17) +#define EL_INTERNAL_CASCADE_DX (EL_FIRST_INTERNAL + 18) +#define EL_INTERNAL_CASCADE_DX_ACTIVE (EL_FIRST_INTERNAL + 19) +#define EL_INTERNAL_CASCADE_CHARS (EL_FIRST_INTERNAL + 20) +#define EL_INTERNAL_CASCADE_CHARS_ACTIVE (EL_FIRST_INTERNAL + 21) +#define EL_INTERNAL_CASCADE_CE (EL_FIRST_INTERNAL + 22) +#define EL_INTERNAL_CASCADE_CE_ACTIVE (EL_FIRST_INTERNAL + 23) +#define EL_INTERNAL_CASCADE_GE (EL_FIRST_INTERNAL + 24) +#define EL_INTERNAL_CASCADE_GE_ACTIVE (EL_FIRST_INTERNAL + 25) +#define EL_INTERNAL_CASCADE_USER (EL_FIRST_INTERNAL + 26) +#define EL_INTERNAL_CASCADE_USER_ACTIVE (EL_FIRST_INTERNAL + 27) +#define EL_INTERNAL_CASCADE_GENERIC (EL_FIRST_INTERNAL + 28) +#define EL_INTERNAL_CASCADE_GENERIC_ACTIVE (EL_FIRST_INTERNAL + 29) +#define EL_INTERNAL_CASCADE_DYNAMIC (EL_FIRST_INTERNAL + 30) +#define EL_INTERNAL_CASCADE_DYNAMIC_ACTIVE (EL_FIRST_INTERNAL + 31) + #define EL_INTERNAL_CLIPBOARD_START (EL_FIRST_INTERNAL + 0) #define EL_INTERNAL_CLIPBOARD_END (EL_FIRST_INTERNAL + 2) #define EL_INTERNAL_START (EL_FIRST_INTERNAL + 0) -#define EL_INTERNAL_END (EL_FIRST_INTERNAL + 3) +#define EL_INTERNAL_END (EL_FIRST_INTERNAL + 31) -#define MAX_NUM_ELEMENTS (EL_FIRST_INTERNAL + 4) +#define MAX_NUM_ELEMENTS (EL_FIRST_INTERNAL + 32) /* values for graphics/sounds action types */ @@ -1241,9 +1447,41 @@ #define ACTION_SLURPED_BY_SPRING 49 #define ACTION_TWINKLING 50 #define ACTION_SPLASHING 51 -#define ACTION_OTHER 52 - -#define NUM_ACTIONS 53 +#define ACTION_PAGE_1 52 +#define ACTION_PAGE_2 53 +#define ACTION_PAGE_3 54 +#define ACTION_PAGE_4 55 +#define ACTION_PAGE_5 56 +#define ACTION_PAGE_6 57 +#define ACTION_PAGE_7 58 +#define ACTION_PAGE_8 59 +#define ACTION_PAGE_9 60 +#define ACTION_PAGE_10 61 +#define ACTION_PAGE_11 62 +#define ACTION_PAGE_12 63 +#define ACTION_PAGE_13 64 +#define ACTION_PAGE_14 65 +#define ACTION_PAGE_15 66 +#define ACTION_PAGE_16 67 +#define ACTION_PAGE_17 68 +#define ACTION_PAGE_18 69 +#define ACTION_PAGE_19 70 +#define ACTION_PAGE_20 71 +#define ACTION_PAGE_21 72 +#define ACTION_PAGE_22 73 +#define ACTION_PAGE_23 74 +#define ACTION_PAGE_24 75 +#define ACTION_PAGE_25 76 +#define ACTION_PAGE_26 77 +#define ACTION_PAGE_27 78 +#define ACTION_PAGE_28 79 +#define ACTION_PAGE_29 80 +#define ACTION_PAGE_30 81 +#define ACTION_PAGE_31 82 +#define ACTION_PAGE_32 83 +#define ACTION_OTHER 84 + +#define NUM_ACTIONS 85 #define ACTION_BORING_LAST ACTION_BORING_10 #define ACTION_SLEEPING_LAST ACTION_SLEEPING_3 @@ -1304,8 +1542,9 @@ #define GFX_ARG_POST_DELAY_RANDOM 35 #define GFX_ARG_NAME 36 #define GFX_ARG_SCALE_UP_FACTOR 37 +#define GFX_ARG_CLONE_FROM 38 -#define NUM_GFX_ARGS 38 +#define NUM_GFX_ARGS 39 /* values for sound configuration suffixes */ @@ -1387,17 +1626,14 @@ /* program information and versioning definitions */ - -#define RELEASE_312 TRUE - #define PROGRAM_VERSION_MAJOR 3 -#define PROGRAM_VERSION_MINOR 1 -#define PROGRAM_VERSION_PATCH 2 -#define PROGRAM_VERSION_BUILD 0 +#define PROGRAM_VERSION_MINOR 2 +#define PROGRAM_VERSION_PATCH 0 +#define PROGRAM_VERSION_BUILD 7 #define PROGRAM_TITLE_STRING "Rocks'n'Diamonds" #define PROGRAM_AUTHOR_STRING "Holger Schemel" -#define PROGRAM_COPYRIGHT_STRING "Copyright ©1995-2006 by Holger Schemel" +#define PROGRAM_COPYRIGHT_STRING "Copyright ©1995-2005 by Holger Schemel" #define ICON_TITLE_STRING PROGRAM_TITLE_STRING #define COOKIE_PREFIX "ROCKSNDIAMONDS" @@ -1494,6 +1730,11 @@ struct HiScore int Score; }; +struct Content +{ + int e[3][3]; +}; + struct PlayerInfo { boolean present; /* player present in level playfield */ @@ -1518,7 +1759,8 @@ struct PlayerInfo int GfxAction; - boolean use_murphy_graphic; + boolean use_murphy; + int artwork_element; boolean block_last_field; int block_delay_adjustment; /* needed for different engine versions */ @@ -1542,6 +1784,8 @@ struct PlayerInfo boolean is_bored; boolean is_sleeping; + boolean cannot_move; + int frame_counter_bored; int frame_counter_sleeping; @@ -1560,23 +1804,13 @@ struct PlayerInfo int show_envelope; -#if 1 /* USE_NEW_MOVE_DELAY */ int move_delay; int move_delay_value; -#else - unsigned long move_delay; - int move_delay_value; -#endif - + int move_delay_value_next; int move_delay_reset_counter; -#if 1 /* USE_NEW_PUSH_DELAY */ int push_delay; int push_delay_value; -#else - unsigned long push_delay; - unsigned long push_delay_value; -#endif unsigned long actual_frame_counter; @@ -1642,17 +1876,38 @@ struct LevelInfo int score[LEVEL_SCORE_ELEMENTS]; - int yamyam_content[MAX_ELEMENT_CONTENTS][3][3]; + struct Content yamyam_content[MAX_ELEMENT_CONTENTS]; int num_yamyam_contents; int amoeba_speed; int amoeba_content; + int game_of_life[4]; + int biomaze[4]; + int time_magic_wall; int time_wheel; int time_light; int time_timegate; + int shield_normal_time; + int shield_deadly_time; + + int extra_time; + int time_orb_time; + + int extra_time_score; + + int start_element[MAX_PLAYERS]; + boolean use_start_element[MAX_PLAYERS]; + + int artwork_element[MAX_PLAYERS]; + boolean use_artwork_element[MAX_PLAYERS]; + + int explosion_element[MAX_PLAYERS]; + boolean use_explosion_element[MAX_PLAYERS]; + +#if 1 /* values for the new EMC elements */ int android_move_time; int android_clone_time; @@ -1665,28 +1920,34 @@ struct LevelInfo int lenses_time; int magnify_time; int wind_direction_initial; - int ball_content[NUM_MAGIC_BALL_CONTENTS][3][3]; + + struct Content ball_content[MAX_ELEMENT_CONTENTS]; + int num_ball_contents; + +#if 0 boolean android_array[16]; +#endif + int num_android_clone_elements; + int android_clone_element[MAX_ANDROID_ELEMENTS]; +#endif int can_move_into_acid_bits; /* bitfield to store property for elements */ int dont_collide_with_bits; /* bitfield to store property for elements */ - boolean double_speed; + int initial_player_stepsize; /* initial player speed */ + boolean initial_gravity; boolean em_slippery_gems; /* EM style "gems slip from wall" behaviour */ boolean use_spring_bug; /* for compatibility with old levels */ + boolean use_time_orb_bug; /* for compatibility with old levels */ boolean instant_relocation; /* no visual delay when relocating player */ boolean can_pass_to_walkable; /* player can pass to empty or walkable tile */ boolean grow_into_diggable; /* amoeba can grow into anything diggable */ + boolean block_snap_field; /* snapping blocks field to show animation */ boolean block_last_field; /* player blocks previous field while moving */ boolean sp_block_last_field; /* player blocks previous field while moving */ -#if 0 /* !!! THIS IS NOT A LEVEL SETTING => LOGIC MOVED TO "game.c" !!! */ - int block_delay; /* delay for blocking previous field */ - int sp_block_delay; /* delay for blocking previous field */ -#endif - /* ('int' instead of 'boolean' because used as selectbox value in editor) */ int use_step_counter; /* count steps instead of seconds for level */ @@ -1752,6 +2013,8 @@ struct GameInfo /* (for the latest engine version, these flags should always be "FALSE") */ boolean use_change_when_pushing_bug; boolean use_block_last_field_bug; + boolean max_num_changes_per_frame; + boolean use_reverse_scan_direction; /* variable within running game */ int yamyam_content_nr; @@ -1762,16 +2025,27 @@ struct GameInfo int belt_dir[4]; int belt_dir_nr[4]; int switchgate_pos; - int balloon_dir; + int wind_direction; boolean gravity; boolean explosions_delayed; boolean envelope_active; +#if 1 + /* values for the new EMC elements */ + int lenses_time_left; + int magnify_time_left; + boolean ball_state; + int ball_content_nr; +#endif + /* values for player idle animation (no effect on engine) */ int player_boring_delay_fixed; int player_boring_delay_random; int player_sleeping_delay_fixed; int player_sleeping_delay_random; + + /* values for special game initialization control */ + boolean restart_level; }; struct GlobalInfo @@ -1794,25 +2068,21 @@ struct ElementChangeInfo { boolean can_change; /* use or ignore this change info */ -#if 1 boolean has_event[NUM_CHANGE_EVENTS]; /* change events */ -#else - unsigned long events; /* change events */ -#endif int trigger_player; /* player triggering change */ int trigger_side; /* side triggering change */ int trigger_page; /* page triggering change */ - short target_element; /* target element after change */ + int target_element; /* target element after change */ int delay_fixed; /* added frame delay before changed (fixed) */ int delay_random; /* added frame delay before changed (random) */ int delay_frames; /* either 1 (frames) or 50 (seconds; 50 fps) */ - short trigger_element; /* element triggering change */ + int trigger_element; /* element triggering change */ - int target_content[3][3]; /* elements for extended change target */ + struct Content target_content;/* elements for extended change target */ boolean use_target_content; /* use extended change target */ boolean only_if_complete; /* only use complete target content */ boolean use_random_replace; /* use random value for replacing elements */ @@ -1821,6 +2091,11 @@ struct ElementChangeInfo boolean explode; /* explode instead of change */ + boolean has_action; /* execute action on specified condition */ + int action_type; /* type of action */ + int action_mode; /* mode of action */ + int action_arg; /* parameter of action */ + /* ---------- internal values used at runtime when playing ---------- */ /* functions that are called before, while and after the change of an @@ -1830,7 +2105,11 @@ struct ElementChangeInfo void (*post_change_function)(int x, int y); short actual_trigger_element; /* element that actually triggered change */ + int actual_trigger_side; /* element side that triggered the change */ int actual_trigger_player; /* player which actually triggered change */ + int actual_trigger_ce_value; /* CE value of element that triggered change */ + + boolean can_change_or_has_action; /* can_change | has_action */ /* ---------- internal values used in level editor ---------- */ @@ -1841,7 +2120,7 @@ struct ElementChangeInfo struct ElementGroupInfo { int num_elements; /* number of elements in this group */ - short element[MAX_ELEMENTS_IN_GROUP]; /* list of elements in this group */ + int element[MAX_ELEMENTS_IN_GROUP]; /* list of elements in this group */ int choice_mode; /* how to choose element from group */ @@ -1892,12 +2171,16 @@ struct ElementInfo /* ---------- special element property values ---------- */ boolean use_gfx_element; /* use custom graphic element */ - short gfx_element; /* optional custom graphic element */ + int gfx_element; /* optional custom graphic element */ int access_direction; /* accessible from which direction */ - int collect_score; /* score value for collecting */ - int collect_count; /* count value for collecting */ + int collect_score_initial; /* initial score value for collecting */ + int collect_count_initial; /* initial count value for collecting */ + + int ce_value_fixed_initial; /* initial value for custom variable (fix) */ + int ce_value_random_initial; /* initial value for custom variable (rnd) */ + boolean use_last_ce_value; /* use value from element before change */ int push_delay_fixed; /* constant delay before pushing */ int push_delay_random; /* additional random delay before pushing */ @@ -1916,7 +2199,7 @@ struct ElementInfo int slippery_type; /* how/where other elements slip away */ - int content[3][3]; /* new elements after explosion */ + struct Content content; /* new elements after explosion */ int explosion_type; /* type of explosion, like 3x3, 3+3 or 1x1 */ int explosion_delay; /* duration of explosion of this element */ @@ -1932,21 +2215,14 @@ struct ElementInfo /* ---------- internal values used at runtime when playing ---------- */ -#if 1 boolean has_change_event[NUM_CHANGE_EVENTS]; -#else - unsigned long change_events; /* bitfield for combined change events */ -#endif int event_page_nr[NUM_CHANGE_EVENTS]; /* page number for each event */ struct ElementChangeInfo *event_page[NUM_CHANGE_EVENTS]; /* page for event */ boolean in_group[NUM_GROUP_ELEMENTS]; -#if 0 - boolean can_leave_element; /* element can leave other element behind */ - boolean can_leave_element_last; -#endif + int collect_score; /* runtime score value for collecting */ /* ---------- internal values used in level editor ---------- */ @@ -1978,6 +2254,9 @@ struct FontInfo struct GraphicInfo { Bitmap *bitmap; + int src_image_width; /* scaled bitmap size, but w/o small images */ + int src_image_height; /* scaled bitmap size, but w/o small images */ + int src_x, src_y; /* start position of animation frames */ int width, height; /* width/height of each animation frame */ int offset_x, offset_y; /* x/y offset to next animation frame */ @@ -1994,6 +2273,7 @@ struct GraphicInfo int diggable_like; /* element for cloning digging graphics */ int border_size; /* border size for "crumbled" graphics */ int scale_up_factor; /* optional factor for scaling image up */ + int clone_from; /* graphic for cloning *all* settings */ int anim_delay_fixed; /* optional delay values for bored and */ int anim_delay_random; /* sleeping player animations (animation */ @@ -2081,10 +2361,6 @@ struct HelpAnimInfo }; -#if 0 -extern GC tile_clip_gc; -extern Bitmap *pix[]; -#endif extern Bitmap *bitmap_db_field, *bitmap_db_door; extern Pixmap tile_clipmask[]; extern DrawBuffer *fieldbuffer; @@ -2110,13 +2386,14 @@ extern short MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short ChangeDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short ChangePage[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; +extern short CustomValue[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short Back[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern boolean Pushed[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; -extern boolean Changed[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; +extern short ChangeCount[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short ChangeEvent[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short WasJustMoving[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short WasJustFalling[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; diff --git a/src/netserv.c b/src/netserv.c index 69226533..991fbba6 100644 --- a/src/netserv.c +++ b/src/netserv.c @@ -203,7 +203,6 @@ static void AddPlayer(int fd) nxn = 1; -#if 1 while (again) { again = FALSE; @@ -221,19 +220,6 @@ static void AddPlayer(int fd) v = v->next; } } -#else - again: - v = player->next; - while (v) - { - if (v->number == nxn) - { - nxn++; - goto again; - } - v = v->next; - } -#endif player->number = nxn; #if !defined(TARGET_SDL) diff --git a/src/network.c b/src/network.c index 575e846b..104b83f9 100644 --- a/src/network.c +++ b/src/network.c @@ -500,12 +500,12 @@ static void Handle_OP_START_PLAYING() { LevelDirTree *new_leveldir; int new_level_nr; - int dummy; /* !!! HAS NO MEANING ANYMORE !!! */ + int dummy; unsigned long new_random_seed; char *new_leveldir_identifier; new_level_nr = (buffer[2] << 8) + buffer[3]; - dummy = (buffer[4] << 8) + buffer[5]; + dummy = (buffer[4] << 8) + buffer[5]; /* (obsolete) */ new_random_seed = (buffer[6] << 24) | (buffer[7] << 16) | (buffer[8] << 8) | (buffer[9]); new_leveldir_identifier = (char *)&buffer[10]; @@ -532,6 +532,9 @@ static void Handle_OP_START_PLAYING() LoadTape(level_nr); LoadLevel(level_nr); +#if 1 + StartGameActions(FALSE, setup.autorecord, new_random_seed); +#else if (setup.autorecord) TapeStartRecording(); @@ -542,6 +545,7 @@ static void Handle_OP_START_PLAYING() game_status = GAME_MODE_PLAYING; InitGame(); +#endif } static void Handle_OP_PAUSE_PLAYING() diff --git a/src/screens.c b/src/screens.c index 7d783a9b..6a6a2e94 100644 --- a/src/screens.c +++ b/src/screens.c @@ -60,6 +60,8 @@ #define MAX_MENU_ENTRIES_ON_SCREEN (SCR_FIELDY - 2) #define MENU_SCREEN_START_YPOS 2 #define MENU_SCREEN_VALUE_XPOS 14 +#define MENU_TITLE1_YPOS 8 +#define MENU_TITLE2_YPOS 46 /* buttons and scrollbars identifiers */ #define SCREEN_CTRL_ID_SCROLL_UP 0 @@ -115,28 +117,29 @@ static Bitmap *scrollbar_bitmap[NUM_SCROLLBAR_BITMAPS]; #endif -static void drawCursorExt(int xpos, int ypos, int color, int graphic) +static void drawCursorExt(int xpos, int ypos, int color, int g) { static int cursor_array[SCR_FIELDY]; if (xpos == 0) { - if (graphic != 0) - cursor_array[ypos] = graphic; + if (g != 0) + cursor_array[ypos] = g; else - graphic = cursor_array[ypos]; + g = cursor_array[ypos]; } if (color == FC_RED) - graphic = (graphic == IMG_MENU_BUTTON_LEFT ? IMG_MENU_BUTTON_LEFT_ACTIVE : - graphic == IMG_MENU_BUTTON_RIGHT ? IMG_MENU_BUTTON_RIGHT_ACTIVE: - IMG_MENU_BUTTON_ACTIVE); + g = (g == IMG_MENU_BUTTON_LEFT ? IMG_MENU_BUTTON_LEFT_ACTIVE : + g == IMG_MENU_BUTTON_RIGHT ? IMG_MENU_BUTTON_RIGHT_ACTIVE : + g == IMG_MENU_BUTTON_LEAVE_MENU ? IMG_MENU_BUTTON_LEAVE_MENU_ACTIVE : + g == IMG_MENU_BUTTON_ENTER_MENU ? IMG_MENU_BUTTON_ENTER_MENU_ACTIVE : + IMG_MENU_BUTTON_ACTIVE); ypos += MENU_SCREEN_START_YPOS; DrawBackground(mSX + xpos * TILEX, mSY + ypos * TILEY, TILEX, TILEY); - DrawGraphicThruMaskExt(drawto, mSX + xpos * TILEX, mSY + ypos * TILEY, - graphic, 0); + DrawGraphicThruMaskExt(drawto, mSX + xpos * TILEX, mSY + ypos * TILEY, g, 0); } static void initCursor(int ypos, int graphic) @@ -202,8 +205,8 @@ static void PlayMenuMusic() void DrawHeadline() { - DrawTextSCentered(8, FONT_TITLE_1, PROGRAM_TITLE_STRING); - DrawTextSCentered(46, FONT_TITLE_2, PROGRAM_COPYRIGHT_STRING); + DrawTextSCentered(MENU_TITLE1_YPOS, FONT_TITLE_1, PROGRAM_TITLE_STRING); + DrawTextSCentered(MENU_TITLE2_YPOS, FONT_TITLE_2, PROGRAM_COPYRIGHT_STRING); } static void ToggleFullscreenIfNeeded() @@ -234,6 +237,11 @@ void DrawMainMenu() { static LevelDirTree *leveldir_last_valid = NULL; char *name_text = (!options.network && setup.team_mode ? "Team:" : "Name:"); +#if 1 + char *level_text = "Levelset"; +#else + char *level_text = "Level:"; +#endif int name_width, level_width; int i; @@ -292,28 +300,59 @@ void DrawMainMenu() DrawHeadline(); - DrawText(mSX + 32, mSY + 2*32, name_text, FONT_MENU_1); - DrawText(mSX + 32, mSY + 3*32, "Level:", FONT_MENU_1); - DrawText(mSX + 32, mSY + 4*32, "Hall Of Fame", FONT_MENU_1); - DrawText(mSX + 32, mSY + 5*32, "Level Creator", FONT_MENU_1); - DrawText(mSX + 32, mSY + 6*32, "Info Screen", FONT_MENU_1); - DrawText(mSX + 32, mSY + 7*32, "Start Game", FONT_MENU_1); - DrawText(mSX + 32, mSY + 8*32, "Setup", FONT_MENU_1); - DrawText(mSX + 32, mSY + 9*32, "Quit", FONT_MENU_1); + DrawText(mSX + 32, mSY + 2 * 32, name_text, FONT_MENU_1); + DrawText(mSX + 32, mSY + 3 * 32, level_text, FONT_MENU_1); + DrawText(mSX + 32, mSY + 4 * 32, "Hall Of Fame", FONT_MENU_1); + DrawText(mSX + 32, mSY + 5 * 32, "Level Creator", FONT_MENU_1); + DrawText(mSX + 32, mSY + 6 * 32, "Info Screen", FONT_MENU_1); + DrawText(mSX + 32, mSY + 7 * 32, "Start Game", FONT_MENU_1); + DrawText(mSX + 32, mSY + 8 * 32, "Setup", FONT_MENU_1); + DrawText(mSX + 32, mSY + 9 * 32, "Quit", FONT_MENU_1); /* calculated after (possible) reload of custom artwork */ - name_width = getTextWidth(name_text, FONT_MENU_1); - level_width = getTextWidth("Level:", FONT_MENU_1); + name_width = getTextWidth(name_text, FONT_MENU_1); +#if 1 + level_width = 9 * getFontWidth(FONT_MENU_1); +#else + level_width = getTextWidth(level_text, FONT_MENU_1); +#endif - DrawText(mSX + 32 + name_width, mSY + 2*32, setup.player_name, FONT_INPUT_1); - DrawText(mSX + level_width + 5 * 32, mSY + 3*32, int2str(level_nr,3), + DrawText(mSX + 32 + name_width, mSY + 2 * 32, setup.player_name, + FONT_INPUT_1); +#if 1 + DrawText(mSX + level_width + 2 * 32, mSY + 3 * 32, int2str(level_nr, 3), FONT_VALUE_1); +#else + DrawText(mSX + level_width + 5 * 32, mSY + 3 * 32, int2str(level_nr, 3), + FONT_VALUE_1); +#endif DrawMicroLevel(MICROLEVEL_XPOS, MICROLEVEL_YPOS, TRUE); - DrawTextF(mSX + 32 + level_width - 2, mSY + 3*32 + 1, FONT_TEXT_3, "%d-%d", +#if 1 + +#if 1 + { + int text_height = getFontHeight(FONT_TEXT_3); + int ypos2 = -SY + 3 * 32 + 16; + int ypos1 = ypos2 - text_height; + + DrawTextF(mSX + level_width + 6 * 32, mSY + ypos1, FONT_TEXT_3, + "%03d", leveldir_current->first_level); + DrawTextF(mSX + level_width + 6 * 32, mSY + ypos2, FONT_TEXT_3, + "%03d", leveldir_current->last_level); + } +#else + DrawTextF(mSX + level_width + 6 * 32, mSY + 3 * 32 + 1, FONT_TEXT_3, + "%d", leveldir_current->levels); +#endif + +#else + DrawTextF(mSX + 32 + level_width - 2, mSY + 3 * 32 + 1, FONT_TEXT_3, "%d-%d", leveldir_current->first_level, leveldir_current->last_level); +#endif +#if 0 if (leveldir_current->readonly) { DrawTextS(mSX + level_width + 9 * 32 - 2, @@ -321,13 +360,19 @@ void DrawMainMenu() DrawTextS(mSX + level_width + 9 * 32 - 2, mSY + 3 * 32 + 1 + 7, FONT_TEXT_3, "ONLY"); } +#endif for (i = 0; i < 8; i++) - initCursor(i, (i == 1 || i == 4 || i == 6 ? IMG_MENU_BUTTON_RIGHT : + initCursor(i, (i == 1 || i == 4 || i == 6 ? IMG_MENU_BUTTON_ENTER_MENU : IMG_MENU_BUTTON)); - drawCursorXY(level_width/32 + 4, 1, IMG_MENU_BUTTON_LEFT); - drawCursorXY(level_width/32 + 8, 1, IMG_MENU_BUTTON_RIGHT); +#if 1 + drawCursorXY(level_width / 32 + 1, 1, IMG_MENU_BUTTON_LEFT); + drawCursorXY(level_width / 32 + 5, 1, IMG_MENU_BUTTON_RIGHT); +#else + drawCursorXY(level_width / 32 + 4, 1, IMG_MENU_BUTTON_LEFT); + drawCursorXY(level_width / 32 + 8, 1, IMG_MENU_BUTTON_RIGHT); +#endif DrawTextSCentered(326, FONT_TITLE_2, "A Game by Artsoft Entertainment"); @@ -418,7 +463,6 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) if (new_level_nr > leveldir_current->last_level) new_level_nr = leveldir_current->last_level; -#if 1 if (setup.handicap && new_level_nr > leveldir_current->handicap_level) { /* skipping levels is only allowed when trying to skip single level */ @@ -431,10 +475,6 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) new_level_nr = leveldir_current->handicap_level; } -#else - if (setup.handicap && new_level_nr > leveldir_current->handicap_level) - new_level_nr = leveldir_current->handicap_level; -#endif if (new_level_nr != old_level_nr) { @@ -511,30 +551,20 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) } else if (y == 5) { - if (setup.autorecord) - TapeStartRecording(); - -#if defined(NETWORK_AVALIABLE) - if (options.network) - SendToServer_StartPlaying(); - else -#endif - { - game_status = GAME_MODE_PLAYING; - StopAnimation(); - InitGame(); - } + StartGameActions(options.network, setup.autorecord, NEW_RANDOMIZE); } else if (y == 6) { game_status = GAME_MODE_SETUP; setup_mode = SETUP_MODE_MAIN; + DrawSetupScreen(); } else if (y == 7) { SaveLevelSetup_LastSeries(); SaveLevelSetup_SeriesInfo(); + if (Request("Do you really want to quit ?", REQ_ASK | REQ_STAY_CLOSED)) game_status = GAME_MODE_QUIT; } @@ -614,7 +644,11 @@ static void DrawInfoScreen_Main() ClearWindow(); +#if 1 + DrawTextSCentered(mSY - SY + 16, FONT_TITLE_1, "Info Screen"); +#else DrawText(mSX + 16, mSY + 16, "Info Screen", FONT_TITLE_1); +#endif info_info = info_info_main; num_info_info = 0; @@ -627,9 +661,9 @@ static void DrawInfoScreen_Main() DrawText(mSX + 32, mSY + ypos * 32, info_info[i].text, font_nr); if (info_info[i].type & TYPE_ENTER_MENU) - initCursor(i, IMG_MENU_BUTTON_RIGHT); + initCursor(i, IMG_MENU_BUTTON_ENTER_MENU); else if (info_info[i].type & TYPE_LEAVE_MENU) - initCursor(i, IMG_MENU_BUTTON_LEFT); + initCursor(i, IMG_MENU_BUTTON_LEAVE_MENU); else if (info_info[i].type & ~TYPE_SKIP_ENTRY) initCursor(i, IMG_MENU_BUTTON); @@ -746,7 +780,6 @@ void DrawInfoScreen_HelpAnim(int start, int max_anims, boolean init) for (i = 0; i < MAX_INFO_ELEMENTS_ON_SCREEN; i++) infoscreen_step[i] = infoscreen_frame[i] = 0; - SetMainBackgroundImage(IMG_BACKGROUND_INFO); ClearWindow(); DrawHeadline(); @@ -854,11 +887,7 @@ static char *getHelpText(int element, int action, int direction) void DrawInfoScreen_HelpText(int element, int action, int direction, int ypos) { -#if 0 - int font_nr = FONT_TEXT_2; -#else int font_nr = FONT_LEVEL_NUMBER; -#endif int font_width = getFontWidth(font_nr); int sx = mSX + MINI_TILEX + TILEX + MINI_TILEX; int sy = mSY + 65 + 2 * 32 + 1; @@ -892,6 +921,8 @@ void DrawInfoScreen_HelpText(int element, int action, int direction, int ypos) void DrawInfoScreen_Elements() { + SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_ELEMENTS); + LoadHelpAnimInfo(); LoadHelpTextInfo(); @@ -967,6 +998,8 @@ void HandleInfoScreen_Elements(int button) void DrawInfoScreen_Music() { + SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_MUSIC); + ClearWindow(); DrawHeadline(); @@ -1099,6 +1132,8 @@ void DrawInfoScreen_Credits() int ystart = 150, ystep = 30; int ybottom = SYSIZE - 20; + SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_CREDITS); + FadeSoundsAndMusic(); ClearWindow(); @@ -1147,6 +1182,8 @@ void DrawInfoScreen_Program() int ystart = 150, ystep = 30; int ybottom = SYSIZE - 20; + SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_PROGRAM); + ClearWindow(); DrawHeadline(); @@ -1210,11 +1247,7 @@ void DrawInfoScreen_LevelSet() int ystart = 150; int ybottom = SYSIZE - 20; char *filename = getLevelSetInfoFilename(); -#if 0 - int font_nr = FONT_TEXT_2; -#else int font_nr = FONT_LEVEL_NUMBER; -#endif int font_width = getFontWidth(font_nr); int font_height = getFontHeight(font_nr); int pad_x = 32; @@ -1224,6 +1257,8 @@ void DrawInfoScreen_LevelSet() int max_chars_per_line = (SXSIZE - 2 * pad_x) / font_width; int max_lines_per_screen = (SYSIZE - pad_y) / font_height - 1; + SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_LEVELSET); + ClearWindow(); DrawHeadline(); @@ -1412,19 +1447,38 @@ static void drawChooseTreeList(int first_entry, int num_page_entries, char buffer[SCR_FIELDX * 2]; int max_buffer_len = (SCR_FIELDX - 2) * 2; char *title_string = NULL; +#if 0 + int xoffset_sets = 16; +#endif + int yoffset_sets = MENU_TITLE1_YPOS; +#if 0 int xoffset_setup = 16; +#endif int yoffset_setup = 16; +#if 1 +#if 0 + int xoffset = (ti->type == TREE_TYPE_LEVEL_DIR ? xoffset_sets : + xoffset_setup); +#endif + int yoffset = (ti->type == TREE_TYPE_LEVEL_DIR ? yoffset_sets : + yoffset_setup); +#else int xoffset = (ti->type == TREE_TYPE_LEVEL_DIR ? 0 : xoffset_setup); int yoffset = (ti->type == TREE_TYPE_LEVEL_DIR ? 0 : yoffset_setup); +#endif int last_game_status = game_status; /* save current game status */ title_string = - (ti->type == TREE_TYPE_LEVEL_DIR ? "Level Directories" : + (ti->type == TREE_TYPE_LEVEL_DIR ? "Level Sets" : ti->type == TREE_TYPE_GRAPHICS_DIR ? "Custom Graphics" : ti->type == TREE_TYPE_SOUNDS_DIR ? "Custom Sounds" : ti->type == TREE_TYPE_MUSIC_DIR ? "Custom Music" : ""); +#if 1 + DrawTextSCentered(mSY - SY + yoffset, FONT_TITLE_1, title_string); +#else DrawText(SX + xoffset, SY + yoffset, title_string, FONT_TITLE_1); +#endif /* force LEVELS font on artwork setup screen */ game_status = GAME_MODE_LEVELS; @@ -1443,15 +1497,15 @@ static void drawChooseTreeList(int first_entry, int num_page_entries, node_first = getTreeInfoFirstGroupEntry(ti); node = getTreeInfoFromPos(node_first, entry_pos); - strncpy(buffer, node->name , max_buffer_len); + strncpy(buffer, node->name, max_buffer_len); buffer[max_buffer_len] = '\0'; DrawText(mSX + 32, mSY + ypos * 32, buffer, FONT_TEXT_1 + node->color); if (node->parent_link) - initCursor(i, IMG_MENU_BUTTON_LEFT); + initCursor(i, IMG_MENU_BUTTON_LEAVE_MENU); else if (node->level_group) - initCursor(i, IMG_MENU_BUTTON_RIGHT); + initCursor(i, IMG_MENU_BUTTON_ENTER_MENU); else initCursor(i, IMG_MENU_BUTTON); } @@ -1465,6 +1519,11 @@ static void drawChooseTreeInfo(int entry_pos, TreeInfo *ti) { TreeInfo *node, *node_first; int x, last_redraw_mask = redraw_mask; +#if 1 + int ypos = MENU_TITLE2_YPOS; +#else + int ypos = 40; +#endif if (ti->type != TREE_TYPE_LEVEL_DIR) return; @@ -1472,16 +1531,16 @@ static void drawChooseTreeInfo(int entry_pos, TreeInfo *ti) node_first = getTreeInfoFirstGroupEntry(ti); node = getTreeInfoFromPos(node_first, entry_pos); - DrawBackground(SX + 32, SY + 32, SXSIZE - 64, 32); + DrawBackground(SX, SY + ypos, SXSIZE, getFontHeight(FONT_TITLE_2)); if (node->parent_link) - DrawTextFCentered(40, FONT_TITLE_2, "leave group \"%s\"", + DrawTextFCentered(ypos, FONT_TITLE_2, "leave group \"%s\"", node->class_desc); else if (node->level_group) - DrawTextFCentered(40, FONT_TITLE_2, "enter group \"%s\"", + DrawTextFCentered(ypos, FONT_TITLE_2, "enter group \"%s\"", node->class_desc); else if (ti->type == TREE_TYPE_LEVEL_DIR) - DrawTextFCentered(40, FONT_TITLE_2, "%3d levels (%s)", + DrawTextFCentered(ypos, FONT_TITLE_2, "%3d levels (%s)", node->levels, node->class_desc); /* let BackToFront() redraw only what is needed */ @@ -1760,8 +1819,15 @@ static void drawHallOfFameList(int first_entry, int highlight_position) SetMainBackgroundImage(IMG_BACKGROUND_SCORES); ClearWindow(); - DrawText(mSX + 80, mSY + 8, "Hall Of Fame", FONT_TITLE_1); - DrawTextFCentered(46, FONT_TITLE_2, "HighScores of Level %d", level_nr); +#if 1 + DrawTextSCentered(MENU_TITLE1_YPOS, FONT_TITLE_1, "Hall Of Fame"); + DrawTextFCentered(MENU_TITLE2_YPOS, FONT_TITLE_2, + "HighScores of Level %d", level_nr); +#else + DrawText(mSX + 80, mSY + MENU_TITLE1_YPOS, "Hall Of Fame", FONT_TITLE_1); + DrawTextFCentered(MENU_TITLE2_YPOS, FONT_TITLE_2, + "HighScores of Level %d", level_nr); +#endif for (i = 0; i < NUM_MENU_ENTRIES_ON_SCREEN; i++) { @@ -1977,19 +2043,23 @@ static struct TokenInfo setup_info_editor[] = #if 0 { TYPE_STRING, NULL, "Offer Special Elements:"}, #endif + +#if 0 +#else { TYPE_SWITCH, &setup.editor.el_boulderdash, "BoulderDash:" }, { TYPE_SWITCH, &setup.editor.el_emerald_mine, "Emerald Mine:" }, - { TYPE_SWITCH, &setup.editor.el_emerald_mine_club,"E.M. Club:" }, - { TYPE_SWITCH, &setup.editor.el_more, "More:" }, + { TYPE_SWITCH, &setup.editor.el_emerald_mine_club,"E.M.C.:" }, + { TYPE_SWITCH, &setup.editor.el_more, "R'n'D:" }, { TYPE_SWITCH, &setup.editor.el_sokoban, "Sokoban:" }, { TYPE_SWITCH, &setup.editor.el_supaplex, "Supaplex:" }, - { TYPE_SWITCH, &setup.editor.el_diamond_caves, "Diamd. Caves:" }, - { TYPE_SWITCH, &setup.editor.el_dx_boulderdash,"DX Boulderd.:" }, + { TYPE_SWITCH, &setup.editor.el_diamond_caves, "DC II:" }, + { TYPE_SWITCH, &setup.editor.el_dx_boulderdash,"DX BD:" }, +#endif { TYPE_SWITCH, &setup.editor.el_chars, "Characters:" }, { TYPE_SWITCH, &setup.editor.el_custom, "Custom:" }, - { TYPE_SWITCH, &setup.editor.el_custom_more, "More Custom:" }, { TYPE_SWITCH, &setup.editor.el_headlines, "Headlines:" }, { TYPE_SWITCH, &setup.editor.el_user_defined, "User defined:" }, + { TYPE_SWITCH, &setup.editor.el_dynamic, "Dynamic:" }, { TYPE_EMPTY, NULL, "" }, { TYPE_LEAVE_MENU, execSetupMain, "Back" }, @@ -2217,7 +2287,11 @@ static void DrawSetupScreen_Generic() title_string = "Setup Shortcuts"; } +#if 1 + DrawTextSCentered(mSY - SY + 16, FONT_TITLE_1, title_string); +#else DrawText(mSX + 16, mSY + 16, title_string, FONT_TITLE_1); +#endif num_setup_info = 0; for (i = 0; setup_info[i].type != 0 && i < NUM_MENU_ENTRIES_ON_SCREEN; i++) @@ -2233,21 +2307,15 @@ static void DrawSetupScreen_Generic() (value_ptr == &setup.fullscreen && !video.fullscreen_available)) setup_info[i].type |= TYPE_GHOSTED; -#if 0 - if (setup_info[i].type & TYPE_STRING || - (setup_info[i].type & TYPE_SWITCH && setup_mode == SETUP_MODE_EDITOR)) - font_nr = FONT_MENU_2; -#else if (setup_info[i].type & TYPE_STRING) font_nr = FONT_MENU_2; -#endif DrawText(mSX + 32, mSY + ypos * 32, setup_info[i].text, font_nr); if (setup_info[i].type & TYPE_ENTER_MENU) - initCursor(i, IMG_MENU_BUTTON_RIGHT); + initCursor(i, IMG_MENU_BUTTON_ENTER_MENU); else if (setup_info[i].type & TYPE_LEAVE_MENU) - initCursor(i, IMG_MENU_BUTTON_LEFT); + initCursor(i, IMG_MENU_BUTTON_LEAVE_MENU); else if (setup_info[i].type & ~TYPE_SKIP_ENTRY) initCursor(i, IMG_MENU_BUTTON); @@ -2257,6 +2325,11 @@ static void DrawSetupScreen_Generic() num_setup_info++; } +#if 0 + DrawTextSCentered(SYSIZE - 20, FONT_TEXT_4, + "Joysticks deactivated in setup menu"); +#endif + FadeToFront(); InitAnimation(); HandleSetupScreen_Generic(0, 0, 0, 0, MB_MENU_INITIALIZE); @@ -2357,22 +2430,28 @@ void DrawSetupScreen_Input() { ClearWindow(); - DrawText(mSX+16, mSY+16, "Setup Input", FONT_TITLE_1); +#if 1 + DrawTextSCentered(mSY - SY + 16, FONT_TITLE_1, "Setup Input"); +#else + DrawText(mSX + 16, mSY + 16, "Setup Input", FONT_TITLE_1); +#endif - initCursor(0, IMG_MENU_BUTTON); - initCursor(1, IMG_MENU_BUTTON); - initCursor(2, IMG_MENU_BUTTON_RIGHT); - initCursor(13, IMG_MENU_BUTTON_LEFT); + initCursor(0, IMG_MENU_BUTTON); + initCursor(1, IMG_MENU_BUTTON); + initCursor(2, IMG_MENU_BUTTON_ENTER_MENU); + initCursor(13, IMG_MENU_BUTTON_LEAVE_MENU); drawCursorXY(10, 0, IMG_MENU_BUTTON_LEFT); drawCursorXY(12, 0, IMG_MENU_BUTTON_RIGHT); - DrawText(mSX+32, mSY+2*32, "Player:", FONT_MENU_1); - DrawText(mSX+32, mSY+3*32, "Device:", FONT_MENU_1); - DrawText(mSX+32, mSY+15*32, "Back", FONT_MENU_1); + DrawText(mSX + 32, mSY + 2 * 32, "Player:", FONT_MENU_1); + DrawText(mSX + 32, mSY + 3 * 32, "Device:", FONT_MENU_1); + DrawText(mSX + 32, mSY + 15 * 32, "Back", FONT_MENU_1); #if 0 DeactivateJoystickForCalibration(); +#endif +#if 1 DrawTextSCentered(SYSIZE - 20, FONT_TEXT_4, "Joysticks deactivated on this screen"); #endif @@ -2430,50 +2509,48 @@ static void drawPlayerSetupInputInfo(int player_nr) custom_key = setup.input[player_nr].key; - DrawText(mSX+11*32, mSY+2*32, int2str(player_nr +1, 1), FONT_INPUT_1_ACTIVE); -#if 1 + DrawText(mSX + 11 * 32, mSY + 2 * 32, int2str(player_nr + 1, 1), + FONT_INPUT_1_ACTIVE); + ClearRectangleOnBackground(drawto, mSX + 8 * TILEX, mSY + 2 * TILEY, TILEX, TILEY); DrawGraphicThruMaskExt(drawto, mSX + 8 * TILEX, mSY + 2 * TILEY, PLAYER_NR_GFX(IMG_PLAYER_1, player_nr), 0); -#else - DrawGraphicThruMask(8, 2, PLAYER_NR_GFX(IMG_PLAYER_1, player_nr), 0); -#endif if (setup.input[player_nr].use_joystick) { char *device_name = setup.input[player_nr].joy.device_name; - DrawText(mSX+8*32, mSY+3*32, + DrawText(mSX + 8 * 32, mSY + 3 * 32, joystick_name[getJoystickNrFromDeviceName(device_name)], FONT_VALUE_1); - DrawText(mSX+32, mSY+4*32, "Calibrate", FONT_MENU_1); + DrawText(mSX + 32, mSY + 4 * 32, "Calibrate", FONT_MENU_1); } else { - DrawText(mSX+8*32, mSY+3*32, "Keyboard ", FONT_VALUE_1); - DrawText(mSX+32, mSY+4*32, "Customize", FONT_MENU_1); + DrawText(mSX + 8 * 32, mSY + 3 * 32, "Keyboard ", FONT_VALUE_1); + DrawText(mSX + 1 * 32, mSY + 4 * 32, "Customize", FONT_MENU_1); } - DrawText(mSX+32, mSY+5*32, "Actual Settings:", FONT_MENU_1); + DrawText(mSX + 32, mSY + 5 * 32, "Actual Settings:", FONT_MENU_1); drawCursorXY(1, 4, IMG_MENU_BUTTON_LEFT); drawCursorXY(1, 5, IMG_MENU_BUTTON_RIGHT); drawCursorXY(1, 6, IMG_MENU_BUTTON_UP); drawCursorXY(1, 7, IMG_MENU_BUTTON_DOWN); - DrawText(mSX+2*32, mSY+6*32, ":", FONT_VALUE_OLD); - DrawText(mSX+2*32, mSY+7*32, ":", FONT_VALUE_OLD); - DrawText(mSX+2*32, mSY+8*32, ":", FONT_VALUE_OLD); - DrawText(mSX+2*32, mSY+9*32, ":", FONT_VALUE_OLD); - DrawText(mSX+32, mSY+10*32, "Snap Field:", FONT_VALUE_OLD); - DrawText(mSX+32, mSY+12*32, "Drop Element:", FONT_VALUE_OLD); + DrawText(mSX + 2 * 32, mSY + 6 * 32, ":", FONT_VALUE_OLD); + DrawText(mSX + 2 * 32, mSY + 7 * 32, ":", FONT_VALUE_OLD); + DrawText(mSX + 2 * 32, mSY + 8 * 32, ":", FONT_VALUE_OLD); + DrawText(mSX + 2 * 32, mSY + 9 * 32, ":", FONT_VALUE_OLD); + DrawText(mSX + 1 * 32, mSY + 10 * 32, "Snap Field:", FONT_VALUE_OLD); + DrawText(mSX + 1 * 32, mSY + 12 * 32, "Drop Element:", FONT_VALUE_OLD); for (i = 0; i < 6; i++) { int ypos = 6 + i + (i > 3 ? i-3 : 0); - DrawText(mSX + 3*32, mSY + ypos*32, + DrawText(mSX + 3 * 32, mSY + ypos * 32, " ", FONT_VALUE_1); - DrawText(mSX + 3*32, mSY + ypos*32, + DrawText(mSX + 3 * 32, mSY + ypos * 32, (setup.input[player_nr].use_joystick ? custom[i].text : getKeyNameFromKey(*custom[i].key)), FONT_VALUE_1); @@ -2623,17 +2700,22 @@ void CustomizeKeyboard(int player_nr) custom_key = setup.input[player_nr].key; ClearWindow(); + +#if 1 + DrawTextSCentered(mSY - SY + 16, FONT_TITLE_1, "Keyboard Input"); +#else DrawText(mSX + 16, mSY + 16, "Keyboard Input", FONT_TITLE_1); +#endif BackToFront(); InitAnimation(); step_nr = 0; - DrawText(mSX, mSY + (2+2*step_nr)*32, + DrawText(mSX, mSY + (2 + 2 * step_nr) * 32, customize_step[step_nr].text, FONT_INPUT_1_ACTIVE); - DrawText(mSX, mSY + (2+2*step_nr+1)*32, + DrawText(mSX, mSY + (2 + 2 * step_nr + 1) * 32, "Key:", FONT_INPUT_1_ACTIVE); - DrawText(mSX + 4*32, mSY + (2+2*step_nr+1)*32, + DrawText(mSX + 4 * 32, mSY + (2 + 2 * step_nr + 1) * 32, getKeyNameFromKey(*customize_step[step_nr].key), FONT_VALUE_OLD); while (!finished) @@ -2673,32 +2755,32 @@ void CustomizeKeyboard(int player_nr) /* got new key binding */ *customize_step[step_nr].key = key; - DrawText(mSX + 4*32, mSY + (2+2*step_nr+1)*32, + DrawText(mSX + 4 * 32, mSY + (2 + 2 * step_nr + 1) * 32, " ", FONT_VALUE_1); - DrawText(mSX + 4*32, mSY + (2+2*step_nr+1)*32, + DrawText(mSX + 4 * 32, mSY + (2 + 2 * step_nr + 1) * 32, getKeyNameFromKey(key), FONT_VALUE_1); step_nr++; /* un-highlight last query */ - DrawText(mSX, mSY+(2+2*(step_nr-1))*32, - customize_step[step_nr-1].text, FONT_MENU_1); - DrawText(mSX, mSY+(2+2*(step_nr-1)+1)*32, + DrawText(mSX, mSY + (2 + 2 * (step_nr - 1)) * 32, + customize_step[step_nr - 1].text, FONT_MENU_1); + DrawText(mSX, mSY + (2 + 2 * (step_nr - 1) + 1) * 32, "Key:", FONT_MENU_1); /* press 'Enter' to leave */ if (step_nr == 6) { - DrawText(mSX + 16, mSY + 15*32+16, + DrawText(mSX + 16, mSY + 15 * 32 + 16, "Press Enter", FONT_TITLE_1); break; } /* query next key binding */ - DrawText(mSX, mSY+(2+2*step_nr)*32, + DrawText(mSX, mSY + (2 + 2 * step_nr) * 32, customize_step[step_nr].text, FONT_INPUT_1_ACTIVE); - DrawText(mSX, mSY+(2+2*step_nr+1)*32, + DrawText(mSX, mSY + (2 + 2 * step_nr + 1) * 32, "Key:", FONT_INPUT_1_ACTIVE); - DrawText(mSX + 4*32, mSY+(2+2*step_nr+1)*32, + DrawText(mSX + 4 * 32, mSY + (2 + 2 * step_nr + 1) * 32, getKeyNameFromKey(*customize_step[step_nr].key), FONT_VALUE_OLD); } @@ -2761,13 +2843,13 @@ static boolean CalibrateJoystickMain(int player_nr) } } - DrawText(mSX, mSY + 6 * 32, " ROTATE JOYSTICK ", FONT_TITLE_1); - DrawText(mSX, mSY + 7 * 32, "IN ALL DIRECTIONS", FONT_TITLE_1); - DrawText(mSX + 16, mSY + 9 * 32, " IF ALL BALLS ", FONT_TITLE_1); - DrawText(mSX, mSY + 10 * 32, " ARE YELLOW, ", FONT_TITLE_1); - DrawText(mSX, mSY + 11 * 32, " CENTER JOYSTICK ", FONT_TITLE_1); - DrawText(mSX, mSY + 12 * 32, " AND ", FONT_TITLE_1); - DrawText(mSX, mSY + 13 * 32, "PRESS ANY BUTTON!", FONT_TITLE_1); + DrawTextSCentered(mSY - SY + 6 * 32, FONT_TITLE_1, "Rotate joystick"); + DrawTextSCentered(mSY - SY + 7 * 32, FONT_TITLE_1, "in all directions"); + DrawTextSCentered(mSY - SY + 9 * 32, FONT_TITLE_1, "if all balls"); + DrawTextSCentered(mSY - SY + 10 * 32, FONT_TITLE_1, "are marked,"); + DrawTextSCentered(mSY - SY + 11 * 32, FONT_TITLE_1, "center joystick"); + DrawTextSCentered(mSY - SY + 12 * 32, FONT_TITLE_1, "and"); + DrawTextSCentered(mSY - SY + 13 * 32, FONT_TITLE_1, "press any button!"); joy_value = Joystick(player_nr); last_x = (joy_value & JOY_LEFT ? -1 : joy_value & JOY_RIGHT ? +1 : 0); @@ -3082,6 +3164,9 @@ void HandleGameActions() } else { + if (game.restart_level) + StartGameActions(options.network, setup.autorecord, NEW_RANDOMIZE); + if (local_player->LevelSolved) GameWon(); @@ -3096,6 +3181,30 @@ void HandleGameActions() } } +void StartGameActions(boolean init_network_game, boolean record_tape, + long random_seed) +{ + if (record_tape) + TapeStartRecording(random_seed); + +#if defined(NETWORK_AVALIABLE) + if (init_network_game) + { + SendToServer_StartPlaying(); + + return; + } +#endif + + StopAnimation(); + + game_status = GAME_MODE_PLAYING; + + InitRND(random_seed); + + InitGame(); +} + /* ---------- new screen button stuff -------------------------------------- */ /* graphic position and size values for buttons and scrollbars */ diff --git a/src/screens.h b/src/screens.h index 949267f0..58ea5ddb 100644 --- a/src/screens.h +++ b/src/screens.h @@ -32,6 +32,8 @@ void HandleSetupScreen(int, int, int, int, int); void HandleTypeName(int, Key); void HandleGameActions(void); +void StartGameActions(boolean, boolean, long); + void CreateScreenGadgets(); void FreeScreenGadgets(); diff --git a/src/tape.c b/src/tape.c index 172af415..e8fb1b7e 100644 --- a/src/tape.c +++ b/src/tape.c @@ -345,102 +345,6 @@ void DrawVideoDisplay(unsigned long state, unsigned long value) }, }; -#if 0 - if (state & VIDEO_STATE_FFWD_OFF) - { -#if 1 - int cx = DOOR_GFX_PAGEX3, cy = DOOR_GFX_PAGEY2; - - if (value != VIDEO_DISPLAY_SYMBOL_ONLY) - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, - cx + VIDEO_LABEL_XPOS, - cy + VIDEO_LABEL_YPOS, - VIDEO_LABEL_XSIZE, - VIDEO_LABEL_YSIZE, - VX + VIDEO_LABEL_XPOS, - VY + VIDEO_LABEL_YPOS); - - cx = DOOR_GFX_PAGEX3; - cy = DOOR_GFX_PAGEY2; - - if (value != VIDEO_DISPLAY_LABEL_ONLY) - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, - cx + VIDEO_FFWD_SYMBOL_XPOS, - cy + VIDEO_SYMBOL_YPOS, - VIDEO_FFWD_SYMBOL_XSIZE, - VIDEO_FFWD_SYMBOL_YSIZE, - VX + VIDEO_SYMBOL_XPOS, - VY + VIDEO_SYMBOL_YPOS); -#else - int cx = DOOR_GFX_PAGEX3, cy = DOOR_GFX_PAGEY2; - - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, - cx + VIDEO_PLAY_SYMBOL_XPOS - 9, - cy + VIDEO_PLAY_SYMBOL_YPOS, - VIDEO_PLAY_SYMBOL_XSIZE - 2, - VIDEO_PLAY_SYMBOL_YSIZE, - VX + VIDEO_PLAY_SYMBOL_XPOS - 9, - VY + VIDEO_PLAY_SYMBOL_YPOS); -#endif - } -#endif - -#if 0 - if (state & VIDEO_STATE_PBEND_OFF) - { -#if 1 - int cx = DOOR_GFX_PAGEX3, cy = DOOR_GFX_PAGEY2; - - if (value != VIDEO_DISPLAY_SYMBOL_ONLY) - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, - cx + VIDEO_LABEL_XPOS, - cy + VIDEO_LABEL_YPOS, - VIDEO_LABEL_XSIZE, - VIDEO_LABEL_YSIZE, - VX + VIDEO_LABEL_XPOS, - VY + VIDEO_LABEL_YPOS); - - cx = DOOR_GFX_PAGEX3; - cy = DOOR_GFX_PAGEY2; - - if (value != VIDEO_DISPLAY_LABEL_ONLY) - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, - cx + VIDEO_PBEND_SYMBOL_XPOS, - cy + VIDEO_SYMBOL_YPOS, - VIDEO_PBEND_SYMBOL_XSIZE, - VIDEO_PBEND_SYMBOL_YSIZE, - VX + VIDEO_PBEND_SYMBOL_XPOS, - VY + VIDEO_SYMBOL_YPOS); -#else - int cx = DOOR_GFX_PAGEX3, cy = DOOR_GFX_PAGEY2; - - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, - cx + VIDEO_REC_LABEL_XPOS, - cy + VIDEO_REC_LABEL_YPOS, - VIDEO_PBEND_LABEL_XSIZE, - VIDEO_PBEND_LABEL_YSIZE, - VX + VIDEO_REC_LABEL_XPOS, - VY + VIDEO_REC_LABEL_YPOS); -#endif - } -#endif - -#if 0 - if (state & VIDEO_STATE_1STEP_OFF) - { - int cx = DOOR_GFX_PAGEX3, cy = DOOR_GFX_PAGEY2; - - if (value != VIDEO_DISPLAY_LABEL_ONLY) - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, - cx + VIDEO_1STEP_SYMBOL_XPOS, - cy + VIDEO_SYMBOL_YPOS, - VIDEO_1STEP_SYMBOL_XSIZE, - VIDEO_1STEP_SYMBOL_YSIZE, - VX + VIDEO_1STEP_SYMBOL_XPOS, - VY + VIDEO_SYMBOL_YPOS); - } -#endif - for (k = 0; k < NUM_TAPE_FUNCTION_STATES; k++) /* on or off states */ { for (i = 0; i < NUM_TAPE_FUNCTIONS; i++) /* record, play, ... */ @@ -476,102 +380,6 @@ void DrawVideoDisplay(unsigned long state, unsigned long value) } } -#if 0 - if (state & VIDEO_STATE_FFWD_ON) - { -#if 1 - int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY1; - - if (value != VIDEO_DISPLAY_SYMBOL_ONLY) - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, - cx + VIDEO_FFWD_LABEL_XPOS, - cy + VIDEO_FFWD_LABEL_YPOS, - VIDEO_LABEL_XSIZE, - VIDEO_LABEL_YSIZE, - VX + VIDEO_LABEL_XPOS, - VY + VIDEO_LABEL_YPOS); - - cx = DOOR_GFX_PAGEX6; - cy = DOOR_GFX_PAGEY1; - - if (value != VIDEO_DISPLAY_LABEL_ONLY) - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, - cx + VIDEO_FFWD_SYMBOL_XPOS, - cy + VIDEO_FFWD_SYMBOL_YPOS, - VIDEO_FFWD_SYMBOL_XSIZE, - VIDEO_FFWD_SYMBOL_YSIZE, - VX + VIDEO_SYMBOL_XPOS, - VY + VIDEO_SYMBOL_YPOS); -#else - int cx = DOOR_GFX_PAGEX4, cy = DOOR_GFX_PAGEY2; - - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, - cx + VIDEO_PLAY_SYMBOL_XPOS, - cy + VIDEO_PLAY_SYMBOL_YPOS, - VIDEO_PLAY_SYMBOL_XSIZE - 2, - VIDEO_PLAY_SYMBOL_YSIZE, - VX + VIDEO_PLAY_SYMBOL_XPOS - 9, - VY + VIDEO_PLAY_SYMBOL_YPOS); -#endif - } -#endif - -#if 0 - if (state & VIDEO_STATE_PBEND_ON) - { -#if 1 - int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY1; - - if (value != VIDEO_DISPLAY_SYMBOL_ONLY) - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, - cx + VIDEO_PBEND_LABEL_XPOS, - cy + VIDEO_PBEND_LABEL_YPOS, - VIDEO_LABEL_XSIZE, - VIDEO_LABEL_YSIZE, - VX + VIDEO_LABEL_XPOS, - VY + VIDEO_LABEL_YPOS); - - cx = DOOR_GFX_PAGEX6; - cy = DOOR_GFX_PAGEY1; - - if (value != VIDEO_DISPLAY_LABEL_ONLY) - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, - cx + VIDEO_PBEND_SYMBOL_XPOS, - cy + VIDEO_PBEND_SYMBOL_YPOS, - VIDEO_PBEND_SYMBOL_XSIZE, - VIDEO_PBEND_SYMBOL_YSIZE, - VX + VIDEO_SYMBOL_XPOS, - VY + VIDEO_SYMBOL_YPOS); -#else - int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY1; - - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, - cx + VIDEO_PBEND_LABEL_XPOS, - cy + VIDEO_PBEND_LABEL_YPOS, - VIDEO_PBEND_LABEL_XSIZE, - VIDEO_PBEND_LABEL_YSIZE, - VX + VIDEO_REC_LABEL_XPOS, - VY + VIDEO_REC_LABEL_YPOS); -#endif - } -#endif - -#if 0 - if (state & VIDEO_STATE_1STEP_ON) - { - int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY1; - - if (value != VIDEO_DISPLAY_LABEL_ONLY) - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, - cx + VIDEO_1STEP_SYMBOL_XPOS, - cy + VIDEO_1STEP_SYMBOL_YPOS, - VIDEO_1STEP_SYMBOL_XSIZE, - VIDEO_1STEP_SYMBOL_YSIZE, - VX + VIDEO_1STEP_SYMBOL_XPOS, - VY + VIDEO_SYMBOL_YPOS); - } -#endif - if (state & VIDEO_STATE_DATE_ON) { int tag = value % 100; @@ -597,16 +405,7 @@ void DrawVideoDisplay(unsigned long state, unsigned long value) int2str(sec, 2), FONT_TAPE_RECORDER); } -#if 1 redraw_mask |= REDRAW_DOOR_2; -#else - if (state & VIDEO_STATE_DATE) - redraw_mask |= REDRAW_VIDEO_1; - if ((state & ~VIDEO_STATE_DATE) & VIDEO_STATE) - redraw_mask |= REDRAW_VIDEO_2; - if (state & VIDEO_PRESS) - redraw_mask |= REDRAW_VIDEO_3; -#endif } void DrawCompleteVideoDisplay() @@ -684,11 +483,6 @@ void TapeErase() TapeSetDate(); -#if 0 - printf("::: tape.engine_version = level.game_version = %d \n", - level.game_version); -#endif - for (i = 0; i < MAX_PLAYERS; i++) tape.player_participates[i] = FALSE; } @@ -711,13 +505,19 @@ static void TapeRewind() InitRND(tape.random_seed); } -void TapeStartRecording() +static void TapeSetRandomSeed(long random_seed) +{ + tape.random_seed = InitRND(random_seed); +} + +void TapeStartRecording(long random_seed) { if (!TAPE_IS_STOPPED(tape)) TapeStop(); TapeErase(); TapeRewind(); + TapeSetRandomSeed(random_seed); tape.recording = TRUE; @@ -732,7 +532,7 @@ void TapeStartRecording() static void TapeStartGameRecording() { - TapeStartRecording(); + TapeStartRecording(NEW_RANDOMIZE); #if defined(NETWORK_AVALIABLE) if (options.network) @@ -776,11 +576,6 @@ void TapeHaltRecording() void TapeStopRecording() { -#if 0 - if (!tape.recording) - return; -#endif - TapeHaltRecording(); tape.recording = FALSE; @@ -794,13 +589,8 @@ void TapeRecordAction(byte action[MAX_PLAYERS]) { int i; -#if 1 - if (!tape.recording) /* record action even when tape is paused! */ + if (!tape.recording) /* (record action even when tape is paused) */ return; -#else - if (!tape.recording || tape.pausing) - return; -#endif if (tape.counter >= MAX_TAPE_LEN - 1) { @@ -808,10 +598,6 @@ void TapeRecordAction(byte action[MAX_PLAYERS]) return; } -#if 0 - printf("::: %05d: recording action: %d\n", FrameCounter, action[0]); -#endif - if (tape.pos[tape.counter].delay > 0) /* already stored action */ { boolean changed_events = FALSE; @@ -831,11 +617,6 @@ void TapeRecordAction(byte action[MAX_PLAYERS]) if (tape.pos[tape.counter].delay == 0) /* store new action */ { - -#if 0 - printf("::: %05d: new sequence\n", FrameCounter); -#endif - for (i = 0; i < MAX_PLAYERS; i++) tape.pos[tape.counter].action[i] = action[i]; @@ -847,11 +628,6 @@ void TapeTogglePause(boolean toggle_manual) { int state = 0; -#if 0 - if (!tape.recording && !tape.playing) - return; -#endif - if (tape.pause_before_death) state |= VIDEO_STATE_PBEND_OFF; else if (tape.fast_forward) @@ -872,11 +648,6 @@ void TapeTogglePause(boolean toggle_manual) DrawVideoDisplay(state, 0); -#if 0 - if (tape.pausing) - DrawVideoDisplay(VIDEO_STATE_PAUSE_ON, 0); -#endif - if (tape.warp_forward) { TapeStopWarpForward(); @@ -886,9 +657,6 @@ void TapeTogglePause(boolean toggle_manual) tape.quick_resume = FALSE; TapeAppendRecording(); -#if 0 - TapeTogglePause(toggle_manual); -#endif } } } @@ -925,11 +693,6 @@ static void TapeStartGamePlaying() void TapeStopPlaying() { -#if 0 - if (!tape.playing) - return; -#endif - tape.playing = FALSE; tape.pausing = FALSE; @@ -1022,22 +785,11 @@ byte *TapePlayAction() tape.delay_played = 0; } -#if 0 - printf("::: %05d: replaying action: %d\n", FrameCounter, action[0]); -#endif - return action; } void TapeStop() { -#if 0 - if (tape.recording) - printf("::: stopped recording: %d\n", FrameCounter); - else if (tape.playing) - printf("::: stopped playing: %d\n\n", FrameCounter); -#endif - TapeStopRecording(); TapeStopPlaying(); @@ -1073,7 +825,6 @@ static void TapeStartWarpForward() { tape.warp_forward = TRUE; -#if 1 if (!tape.fast_forward && !tape.pause_before_death) { tape.pausing = FALSE; @@ -1081,15 +832,6 @@ static void TapeStartWarpForward() TapeDeactivateDisplayOn(); } -#else - if (!tape.fast_forward || tape.pause_before_death) - { - tape.pausing = FALSE; - tape.deactivate_display = TRUE; - - TapeDeactivateDisplayOn(); - } -#endif if (tape.fast_forward || tape.pause_before_death) DrawVideoDisplay(VIDEO_STATE_WARP_ON, VIDEO_DISPLAY_SYMBOL_ONLY); @@ -1106,16 +848,6 @@ static void TapeStopWarpForward() TapeDeactivateDisplayOff(game_status == GAME_MODE_PLAYING); -#if 0 -#if 1 - if (game_status == GAME_MODE_PLAYING) -#endif - { - RedrawPlayfield(TRUE, 0,0,0,0); - DrawGameDoorValues(); - } -#endif - if (tape.pause_before_death) state |= VIDEO_STATE_WARP_OFF | VIDEO_STATE_PBEND_ON; else if (tape.fast_forward) @@ -1297,12 +1029,15 @@ void AutoPlayTape() continue; } +#if 0 + /* ACTIVATE THIS FOR LOADING/TESTING OF LEVELS ONLY */ + printf("(only testing level)\n"); + continue; +#endif + LoadSolutionTape(level_nr); -#if 1 + if (tape.no_valid_file) -#else - if (TAPE_IS_EMPTY(tape)) -#endif { num_tape_missing++; if (level_nr >= 0 && level_nr < MAX_TAPES_PER_SET) @@ -1531,15 +1266,6 @@ static void HandleTapeButtons(struct GadgetInfo *gi) else /* WARP FORWARD PLAY -> PLAY */ { TapeStopWarpForward(); - -#if 0 - if (tape.pause_before_death) - DrawVideoDisplay(VIDEO_STATE_WARP_OFF | VIDEO_STATE_PLAY_ON, 0); - else if (tape.fast_forward) - DrawVideoDisplay(VIDEO_STATE_WARP_OFF | VIDEO_STATE_FFWD_ON, 0); - else - DrawVideoDisplay(VIDEO_STATE_WARP_OFF | VIDEO_STATE_PBEND_ON, 0); -#endif } } else if (tape.recording) @@ -1588,28 +1314,17 @@ static void HandleTapeButtons(struct GadgetInfo *gi) else if (!tape.pause_before_death) /* FFWD PLAY -> AUTO PAUSE */ { tape.pause_before_death = TRUE; -#if 1 DrawVideoDisplay(VIDEO_STATE_FFWD_OFF | VIDEO_STATE_PBEND_ON, 0); -#else - DrawVideoDisplay(VIDEO_STATE_PBEND_ON, VIDEO_DISPLAY_LABEL_ONLY); -#endif } else /* AUTO PAUSE -> NORMAL PLAY */ { -#if 1 if (tape.warp_forward) TapeStopWarpForward(); -#else - tape.warp_forward = FALSE; -#endif + tape.fast_forward = FALSE; tape.pause_before_death = FALSE; -#if 1 DrawVideoDisplay(VIDEO_STATE_PBEND_OFF | VIDEO_STATE_PLAY_ON, 0); -#else - DrawVideoDisplay(VIDEO_STATE_FFWD_OFF | VIDEO_STATE_PBEND_OFF, 0); -#endif } } break; diff --git a/src/tape.h b/src/tape.h index 4bddf23b..3cb2038a 100644 --- a/src/tape.h +++ b/src/tape.h @@ -98,7 +98,7 @@ void DrawCompleteVideoDisplay(void); void TapeDeactivateDisplayOn(); void TapeDeactivateDisplayOff(boolean); -void TapeStartRecording(void); +void TapeStartRecording(long); void TapeHaltRecording(void); void TapeStopRecording(void); void TapeRecordAction(byte *); diff --git a/src/tools.c b/src/tools.c index eedf5d60..27c2a9f8 100644 --- a/src/tools.c +++ b/src/tools.c @@ -85,6 +85,7 @@ void DumpTile(int x, int y) printf(" MovDir: %d\n", MovDir[x][y]); printf(" MovDelay: %d\n", MovDelay[x][y]); printf(" ChangeDelay: %d\n", ChangeDelay[x][y]); + printf(" CustomValue: %d\n", CustomValue[x][y]); printf(" GfxElement: %d\n", GfxElement[x][y]); printf(" GfxAction: %d\n", GfxAction[x][y]); printf(" GfxFrame: %d\n", GfxFrame[x][y]); @@ -256,8 +257,8 @@ void BackToFront() { BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY); -#ifdef DEBUG #if 0 +#ifdef DEBUG printf("redrawing all (ScreenGfxPos == %d) because %s\n", ScreenGfxPos, (setup.soft_scrolling ? @@ -281,32 +282,7 @@ void BackToFront() BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY); if (redraw_mask & REDRAW_DOOR_2) - { -#if 0 - if ((redraw_mask & REDRAW_DOOR_2) == REDRAW_DOOR_2) -#endif - BlitBitmap(backbuffer, window, VX, VY, VXSIZE, VYSIZE, VX, VY); -#if 0 - else - { - if (redraw_mask & REDRAW_VIDEO_1) - BlitBitmap(backbuffer, window, - VX + VIDEO_DISPLAY1_XPOS, VY + VIDEO_DISPLAY1_YPOS, - VIDEO_DISPLAY_XSIZE, VIDEO_DISPLAY_YSIZE, - VX + VIDEO_DISPLAY1_XPOS, VY + VIDEO_DISPLAY1_YPOS); - if (redraw_mask & REDRAW_VIDEO_2) - BlitBitmap(backbuffer, window, - VX + VIDEO_DISPLAY2_XPOS, VY + VIDEO_DISPLAY2_YPOS, - VIDEO_DISPLAY_XSIZE, VIDEO_DISPLAY_YSIZE, - VX + VIDEO_DISPLAY2_XPOS, VY + VIDEO_DISPLAY2_YPOS); - if (redraw_mask & REDRAW_VIDEO_3) - BlitBitmap(backbuffer, window, - VX + VIDEO_CONTROL_XPOS, VY + VIDEO_CONTROL_YPOS, - VIDEO_CONTROL_XSIZE, VIDEO_CONTROL_YSIZE, - VX + VIDEO_CONTROL_XPOS, VY + VIDEO_CONTROL_YPOS); - } -#endif - } + BlitBitmap(backbuffer, window, VX, VY, VXSIZE, VYSIZE, VX, VY); if (redraw_mask & REDRAW_DOOR_3) BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY); @@ -425,6 +401,12 @@ void FadeToFront() BackToFront(); } +void SetMainBackgroundImageIfDefined(int graphic) +{ + if (graphic_info[graphic].bitmap) + SetMainBackgroundImage(graphic); +} + void SetMainBackgroundImage(int graphic) { SetMainBackgroundBitmap(graphic == IMG_UNDEFINED ? NULL : @@ -528,28 +510,18 @@ inline void getGraphicSourceExt(int graphic, int frame, Bitmap **bitmap, if (g->offset_y == 0) /* frames are ordered horizontally */ { int max_width = g->anim_frames_per_line * g->width; -#if 1 int pos = (src_y / g->height) * max_width + src_x + frame * g->offset_x; *x = pos % max_width; *y = src_y % g->height + pos / max_width * g->height; -#else - *x = (src_x + frame * g->offset_x) % max_width; - *y = src_y + (src_x + frame * g->offset_x) / max_width * g->height; -#endif } else if (g->offset_x == 0) /* frames are ordered vertically */ { int max_height = g->anim_frames_per_line * g->height; -#if 1 int pos = (src_x / g->width) * max_height + src_y + frame * g->offset_y; *x = src_x % g->width + pos / max_height * g->width; *y = pos % max_height; -#else - *x = src_x + (src_y + frame * g->offset_y) / max_height * g->width; - *y = (src_y + frame * g->offset_y) % max_height; -#endif } else /* frames are ordered diagonally */ { @@ -810,12 +782,6 @@ inline static void DrawGraphicShiftedDouble(int x, int y, int dx, int dy, MarkTileDirty(x2, y2); } - -#if 0 - printf("::: DONE DrawGraphicShiftedDouble"); - BackToFront(); - Delay(1000); -#endif } static void DrawGraphicShifted(int x, int y, int dx, int dy, @@ -940,11 +906,7 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame) int sx = SCREENX(x), sy = SCREENY(y); int element; int width, height, cx, cy, i; -#if 1 int crumbled_border_size = graphic_info[graphic].border_size; -#else - int snip = TILEX / 8; /* number of border pixels from "crumbled graphic" */ -#endif static int xy[4][2] = { { 0, -1 }, @@ -953,12 +915,6 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame) { 0, +1 } }; -#if 0 - if (x == 0 && y == 7) - printf("::: %d, %d [%d]\n", GfxElement[x][y], Feld[x][y], - crumbled_border_size); -#endif - if (!IN_LEV_FIELD(x, y)) return; @@ -977,24 +933,13 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame) int xx = x + xy[i][0]; int yy = y + xy[i][1]; -#if 1 element = (IN_LEV_FIELD(xx, yy) ? TILE_GFX_ELEMENT(xx, yy) : BorderElement); -#else - element = (IN_LEV_FIELD(xx, yy) ? Feld[xx][yy] : BorderElement); -#endif /* check if neighbour field is of same type */ if (GFX_CRUMBLED(element) && !IS_MOVING(xx, yy)) continue; -#if 0 - if (Feld[x][y] == EL_CUSTOM_START + 123) - printf("::: crumble [%d] THE CHAOS ENGINE (%d, %d): %d, %d\n", - i, Feld[x][y], element, - GFX_CRUMBLED(element), IS_MOVING(x, y)); -#endif - if (i == 1 || i == 2) { width = crumbled_border_size; @@ -1018,10 +963,6 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame) } else /* crumble neighbour fields */ { -#if 0 - getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y); -#endif - for (i = 0; i < 4; i++) { int xx = x + xy[i][0]; @@ -1035,6 +976,11 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame) IS_MOVING(xx, yy)) continue; +#if 1 + if (Feld[xx][yy] == EL_ELEMENT_SNAPPING) + continue; +#endif + element = TILE_GFX_ELEMENT(xx, yy); if (!GFX_CRUMBLED(element)) @@ -1048,11 +994,13 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame) #endif #if 1 + graphic = el_act2crm(element, ACTION_DEFAULT); +#else graphic = el_act2crm(Feld[xx][yy], ACTION_DEFAULT); +#endif crumbled_border_size = graphic_info[graphic].border_size; getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y); -#endif if (i == 1 || i == 2) { @@ -1079,30 +1027,34 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame) void DrawLevelFieldCrumbledSand(int x, int y) { -#if 1 int graphic; if (!IN_LEV_FIELD(x, y)) return; - graphic = el_act2crm(Feld[x][y], ACTION_DEFAULT); +#if 1 + if (Feld[x][y] == EL_ELEMENT_SNAPPING && + GFX_CRUMBLED(GfxElement[x][y])) + { + DrawLevelFieldCrumbledSandDigging(x, y, GfxDir[x][y], GfxFrame[x][y]); + return; + } +#endif - DrawLevelFieldCrumbledSandExt(x, y, graphic, 0); +#if 1 + graphic = el_act2crm(TILE_GFX_ELEMENT(x, y), ACTION_DEFAULT); #else - DrawLevelFieldCrumbledSandExt(x, y, IMG_SAND_CRUMBLED, 0); + graphic = el_act2crm(Feld[x][y], ACTION_DEFAULT); #endif + + DrawLevelFieldCrumbledSandExt(x, y, graphic, 0); } void DrawLevelFieldCrumbledSandDigging(int x, int y, int direction, int step_frame) { -#if 1 int graphic1 = el_act_dir2img(GfxElement[x][y], ACTION_DIGGING, direction); int graphic2 = el_act_dir2crm(GfxElement[x][y], ACTION_DIGGING, direction); -#else - int graphic1 = el_act_dir2img(EL_SAND, ACTION_DIGGING, direction); - int graphic2 = el_act_dir2img(EL_SAND_CRUMBLED, ACTION_DIGGING, direction); -#endif int frame1 = getGraphicAnimationFrame(graphic1, step_frame); int frame2 = getGraphicAnimationFrame(graphic2, step_frame); int sx = SCREENX(x), sy = SCREENY(y); @@ -1359,13 +1311,8 @@ void DrawEnvelopeBackground(int envelope_nr, int startx, int starty, void AnimateEnvelope(int envelope_nr, int anim_mode, int action) { int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr; -#if 1 Bitmap *src_bitmap = graphic_info[graphic].bitmap; int mask_mode = (src_bitmap != NULL ? BLIT_MASKED : BLIT_ON_BACKGROUND); -#else - boolean draw_masked = graphic_info[graphic].draw_masked; - int mask_mode = (draw_masked ? BLIT_MASKED : BLIT_ON_BACKGROUND); -#endif boolean ffwd_delay = (tape.playing && tape.fast_forward); boolean no_delay = (tape.warp_forward); unsigned long anim_delay = 0; @@ -1561,8 +1508,6 @@ static void DrawMicroLevelLabelExt(int mode) max_len_label_text = SXSIZE / getFontWidth(font_nr); -#if 1 - for (i = 0; i < max_len_label_text; i++) label_text[i] = ' '; label_text[max_len_label_text] = '\0'; @@ -1575,12 +1520,6 @@ static void DrawMicroLevelLabelExt(int mode) DrawText(lxpos, lypos, label_text, font_nr); } -#else - - DrawBackground(SX, MICROLABEL2_YPOS, SXSIZE, getFontHeight(font_nr)); - -#endif - strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name : mode == MICROLABEL_LEVEL_AUTHOR_HEAD ? "created by" : @@ -1764,13 +1703,9 @@ void DrawLevelGraphicAnimation(int x, int y, int graphic) void DrawLevelElementAnimation(int x, int y, int element) { -#if 1 int graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]); DrawGraphicAnimation(SCREENX(x), SCREENY(y), graphic); -#else - DrawGraphicAnimation(SCREENX(x), SCREENY(y), el2img(element)); -#endif } inline void DrawLevelGraphicAnimationIfNeeded(int x, int y, int graphic) @@ -1785,8 +1720,13 @@ inline void DrawLevelGraphicAnimationIfNeeded(int x, int y, int graphic) DrawGraphicAnimation(sx, sy, graphic); +#if 1 + if (GFX_CRUMBLED(TILE_GFX_ELEMENT(x, y))) + DrawLevelFieldCrumbledSand(x, y); +#else if (GFX_CRUMBLED(Feld[x][y])) DrawLevelFieldCrumbledSand(x, y); +#endif } void DrawLevelElementAnimationIfNeeded(int x, int y, int element) @@ -1810,7 +1750,7 @@ void DrawLevelElementAnimationIfNeeded(int x, int y, int element) static int getPlayerGraphic(struct PlayerInfo *player, int move_dir) { - if (player->use_murphy_graphic) + if (player->use_murphy) { /* this works only because currently only one player can be "murphy" ... */ static int last_horizontal_dir = MV_LEFT; @@ -1829,7 +1769,7 @@ static int getPlayerGraphic(struct PlayerInfo *player, int move_dir) return graphic; } else - return el_act_dir2img(player->element_nr, player->GfxAction, move_dir); + return el_act_dir2img(player->artwork_element, player->GfxAction,move_dir); } static boolean equalGraphics(int graphic1, int graphic2) @@ -1867,13 +1807,6 @@ void DrawPlayer(struct PlayerInfo *player) int jx = player->jx; int jy = player->jy; int move_dir = player->MovDir; -#if 0 - int last_jx = player->last_jx; - int last_jy = player->last_jy; - int next_jx = jx + (jx - last_jx); - int next_jy = jy + (jy - last_jy); - boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE); -#else int dx = (move_dir == MV_LEFT ? -1 : move_dir == MV_RIGHT ? +1 : 0); int dy = (move_dir == MV_UP ? -1 : move_dir == MV_DOWN ? +1 : 0); int last_jx = (player->is_moving ? jx - dx : jx); @@ -1881,7 +1814,6 @@ void DrawPlayer(struct PlayerInfo *player) int next_jx = jx + dx; int next_jy = jy + dy; boolean player_is_moving = (player->MovPos ? TRUE : FALSE); -#endif int sx = SCREENX(jx), sy = SCREENY(jy); int sxx = 0, syy = 0; int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy]; @@ -1921,11 +1853,7 @@ void DrawPlayer(struct PlayerInfo *player) /* draw things in the field the player is leaving, if needed */ /* ----------------------------------------------------------------------- */ -#if 1 if (player->is_moving) -#else - if (player_is_moving) -#endif { if (Back[last_jx][last_jy] && IS_DRAWABLE(last_element)) { @@ -1980,6 +1908,10 @@ void DrawPlayer(struct PlayerInfo *player) { GfxElement[jx][jy] = EL_UNDEFINED; + /* make sure that pushed elements are drawn with correct frame rate */ + if (player->is_pushing && player->is_moving) + GfxFrame[jx][jy] = player->StepFrame; + DrawLevelField(jx, jy); } } @@ -1988,8 +1920,6 @@ void DrawPlayer(struct PlayerInfo *player) /* draw player himself */ /* ----------------------------------------------------------------------- */ -#if 1 - graphic = getPlayerGraphic(player, move_dir); /* in the case of changed player action or direction, prevent the current @@ -1997,29 +1927,6 @@ void DrawPlayer(struct PlayerInfo *player) if (player->Frame == 0 && equalGraphics(graphic, last_player_graphic)) player->Frame = last_player_frame; -#else - - if (player->use_murphy_graphic) - { - static int last_horizontal_dir = MV_LEFT; - - if (move_dir == MV_LEFT || move_dir == MV_RIGHT) - last_horizontal_dir = move_dir; - - graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, move_dir); - - if (graphic == IMG_SP_MURPHY) /* undefined => use special graphic */ - { - int direction = (player->is_snapping ? move_dir : last_horizontal_dir); - - graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, direction); - } - } - else - graphic = el_act_dir2img(player->element_nr, player->GfxAction, move_dir); - -#endif - frame = getGraphicAnimationFrame(graphic, player->Frame); if (player->GfxPos) @@ -2056,21 +1963,11 @@ void DrawPlayer(struct PlayerInfo *player) #if 1 if (player->is_pushing && player->is_moving) -#else - if (player->is_pushing && player_is_moving) -#endif { -#if 1 int px = SCREENX(jx), py = SCREENY(jy); int pxx = (TILEX - ABS(sxx)) * dx; int pyy = (TILEY - ABS(syy)) * dy; -#else - int px = SCREENX(next_jx), py = SCREENY(next_jy); - int pxx = sxx; - int pyy = syy; -#endif -#if 1 int graphic; int frame; @@ -2086,35 +1983,8 @@ void DrawPlayer(struct PlayerInfo *player) /* masked drawing is needed for EMC style (double) movement graphics */ DrawGraphicShiftedThruMask(px, py, pxx, pyy, graphic, frame, NO_CUTTING); - -#else - if (Back[next_jx][next_jy]) - DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]); - - if ((pxx || pyy) && element == EL_SOKOBAN_OBJECT) - DrawGraphicShiftedThruMask(px, py, pxx, pyy, IMG_SOKOBAN_OBJECT, 0, - NO_CUTTING); - else - { - int element = MovingOrBlocked2Element(next_jx, next_jy); - int graphic = el_act_dir2img(element, ACTION_PUSHING, move_dir); -#if 1 - int frame = getGraphicAnimationFrame(graphic, player->StepFrame); -#else - int frame = getGraphicAnimationFrame(graphic, player->Frame); -#endif - -#if 1 - /* masked drawing is needed for EMC style (double) movement graphics */ - DrawGraphicShiftedThruMask(px, py, pxx, pyy, graphic, frame, - NO_CUTTING); -#else - DrawGraphicShifted(px, py, pxx, pyy, graphic, frame, - NO_CUTTING, NO_MASKING); -#endif - } -#endif } +#endif /* ----------------------------------------------------------------------- */ /* draw things in front of player (active dynamite or dynabombs) */ @@ -2155,7 +2025,6 @@ void DrawPlayer(struct PlayerInfo *player) DrawLevelFieldThruMask(last_jx, last_jy); } -#if 1 /* do not redraw accessible elements if the player is just pushing them */ if (!player_is_moving || !player->is_pushing) { @@ -2166,22 +2035,6 @@ void DrawPlayer(struct PlayerInfo *player) DrawLevelFieldThruMask(jx, jy); } -#else - -#if 0 - /* !!! I have forgotton what this should be good for !!! */ - /* !!! causes player being visible when pushing from within tubes !!! */ - if (!player->is_pushing) -#endif - { - /* ... and the field the player is entering */ - if (IS_ACCESSIBLE_INSIDE(element)) - DrawLevelField(jx, jy); - else if (IS_ACCESSIBLE_UNDER(element)) - DrawLevelFieldThruMask(jx, jy); - } -#endif - if (setup.direct_draw) { int dst_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX; @@ -2272,21 +2125,15 @@ boolean Request(char *text, unsigned int req_state) } } -#if 1 if (game_status == GAME_MODE_PLAYING && level.game_engine_type == GAME_ENGINE_TYPE_EM) BlitScreenToBitmap_EM(backbuffer); -#endif -#if 1 /* disable deactivated drawing when quick-loading level tape recording */ if (tape.playing && tape.deactivate_display) TapeDeactivateDisplayOff(TRUE); -#endif -#if 1 SetMouseCursor(CURSOR_DEFAULT); -#endif #if defined(NETWORK_AVALIABLE) /* pause network game while waiting for request to answer */ @@ -2381,10 +2228,6 @@ boolean Request(char *text, unsigned int req_state) OpenDoor(DOOR_OPEN_1); -#if 0 - ClearEventQueue(); -#endif - if (!(req_state & REQUEST_WAIT_FOR_INPUT)) { SetDrawBackgroundMask(REDRAW_FIELD); @@ -2401,10 +2244,6 @@ boolean Request(char *text, unsigned int req_state) SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1); -#if 0 - SetMouseCursor(CURSOR_DEFAULT); -#endif - while (result < 0) { if (PendingEvent()) @@ -2546,11 +2385,9 @@ boolean Request(char *text, unsigned int req_state) SendToServer_ContinuePlaying(); #endif -#if 1 /* restore deactivated drawing when quick-loading level tape recording */ if (tape.playing && tape.deactivate_display) TapeDeactivateDisplayOn(); -#endif return result; } @@ -2642,11 +2479,6 @@ unsigned int MoveDoor(unsigned int door_state) { stepsize = 20; /* must be choosen to always draw last frame */ door_delay_value = 0; - -#if 0 - StopSound(SND_DOOR_OPENING); - StopSound(SND_DOOR_CLOSING); -#endif } if (global.autoplay_leveldir) @@ -2847,14 +2679,6 @@ unsigned int MoveDoor(unsigned int door_state) } } -#if 0 - if (setup.quick_doors) - { - StopSound(SND_DOOR_OPENING); - StopSound(SND_DOOR_CLOSING); - } -#endif - if (door_state & DOOR_ACTION_1) door1 = door_state & DOOR_ACTION_1; if (door_state & DOOR_ACTION_2) @@ -3067,8 +2891,6 @@ static void HandleToolButtons(struct GadgetInfo *gi) request_gadget_id = gi->custom_id; } -#if 1 - static struct Mapping_EM_to_RND_object { int element_em; @@ -4936,7 +4758,64 @@ int map_element_EM_to_RND(int element_em) return EL_UNKNOWN; } -#else +void map_android_clone_elements_RND_to_EM(struct LevelInfo *level) +{ + struct LevelInfo_EM *level_em = level->native_em_level; + struct LEVEL *lev = level_em->lev; + int i, j; + + for (i = 0; i < level->num_android_clone_elements; i++) + { + int element_rnd = level->android_clone_element[i]; + int element_em = map_element_RND_to_EM(element_rnd); + + for (j = 0; em_object_mapping_list[j].element_em != -1; j++) + if (em_object_mapping_list[j].element_rnd == element_rnd) + lev->android_array[em_object_mapping_list[j].element_em] = element_em; + } +} + +void map_android_clone_elements_EM_to_RND(struct LevelInfo *level) +{ + struct LevelInfo_EM *level_em = level->native_em_level; + struct LEVEL *lev = level_em->lev; + int i, j; + + level->num_android_clone_elements = 0; + + for (i = 0; i < TILE_MAX; i++) + { + int element_em = lev->android_array[i]; + int element_rnd; + boolean element_found = FALSE; + + if (element_em == Xblank) + continue; + + element_rnd = map_element_EM_to_RND(element_em); + + for (j = 0; j < level->num_android_clone_elements; j++) + if (level->android_clone_element[j] == element_rnd) + element_found = TRUE; + + if (!element_found) + { + level->android_clone_element[level->num_android_clone_elements++] = + element_rnd; + + if (level->num_android_clone_elements == MAX_ANDROID_ELEMENTS) + break; + } + } + + if (level->num_android_clone_elements == 0) + { + level->num_android_clone_elements = 1; + level->android_clone_element[0] = EL_EMPTY; + } +} + +#if 0 int map_element_RND_to_EM(int element_rnd) { @@ -5570,6 +5449,24 @@ int map_element_EM_to_RND(int element_em) #endif +int map_direction_RND_to_EM(int direction) +{ + return (direction == MV_UP ? 0 : + direction == MV_RIGHT ? 1 : + direction == MV_DOWN ? 2 : + direction == MV_LEFT ? 3 : + -1); +} + +int map_direction_EM_to_RND(int direction) +{ + return (direction == 0 ? MV_UP : + direction == 1 ? MV_RIGHT : + direction == 2 ? MV_DOWN : + direction == 3 ? MV_LEFT : + MV_NONE); +} + int get_next_element(int element) { switch(element) @@ -5591,7 +5488,7 @@ int el_act_dir2img(int element, int action, int direction) { element = GFX_ELEMENT(element); - if (direction == MV_NO_MOVING) + if (direction == MV_NONE) return element_info[element].graphic[action]; direction = MV_DIR_BIT(direction); @@ -5602,7 +5499,7 @@ int el_act_dir2img(int element, int action, int direction) int el_act_dir2img(int element, int action, int direction) { element = GFX_ELEMENT(element); - direction = MV_DIR_BIT(direction); /* default: MV_NO_MOVING => MV_DOWN */ + direction = MV_DIR_BIT(direction); /* default: MV_NONE => MV_DOWN */ /* direction_graphic[][] == graphic[] for undefined direction graphics */ return element_info[element].direction_graphic[action][direction]; @@ -5614,7 +5511,7 @@ static int el_act_dir2crm(int element, int action, int direction) { element = GFX_ELEMENT(element); - if (direction == MV_NO_MOVING) + if (direction == MV_NONE) return element_info[element].crumbled[action]; direction = MV_DIR_BIT(direction); @@ -5625,7 +5522,7 @@ static int el_act_dir2crm(int element, int action, int direction) static int el_act_dir2crm(int element, int action, int direction) { element = GFX_ELEMENT(element); - direction = MV_DIR_BIT(direction); /* default: MV_NO_MOVING => MV_DOWN */ + direction = MV_DIR_BIT(direction); /* default: MV_NONE => MV_DOWN */ /* direction_graphic[][] == graphic[] for undefined direction graphics */ return element_info[element].direction_crumbled[action][direction]; @@ -5679,6 +5576,11 @@ int el2preimg(int element) return element_info[element].special_graphic[GFX_SPECIAL_ARG_PREVIEW]; } +int font2baseimg(int font_nr) +{ + return font_info[font_nr].special_graphic[GFX_SPECIAL_ARG_DEFAULT]; +} + int getGameFrameDelay_EM(int native_em_game_frame_delay) { int game_frame_delay_value; @@ -5725,7 +5627,7 @@ void InitGraphicInfo_EM(void) object_mapping[i].element_rnd = EL_UNKNOWN; object_mapping[i].is_backside = FALSE; object_mapping[i].action = ACTION_DEFAULT; - object_mapping[i].direction = MV_NO_MOVING; + object_mapping[i].direction = MV_NONE; } /* always start with reliable default values */ @@ -5735,7 +5637,7 @@ void InitGraphicInfo_EM(void) { player_mapping[p][i].element_rnd = EL_UNKNOWN; player_mapping[p][i].action = ACTION_DEFAULT; - player_mapping[p][i].direction = MV_NO_MOVING; + player_mapping[p][i].direction = MV_NONE; } } @@ -5984,7 +5886,6 @@ void InitGraphicInfo_EM(void) getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x, &src_y, g->double_movement && is_backside); -#if 1 g_em->bitmap = src_bitmap; g_em->src_x = src_x; g_em->src_y = src_y; @@ -6002,13 +5903,6 @@ void InitGraphicInfo_EM(void) g_em->has_crumbled_graphics = FALSE; g_em->preserve_background = FALSE; -#endif - -#if 0 - if (effective_element == EL_EMC_GRASS && - effective_action == ACTION_DIGGING) - printf("::: %d\n", crumbled); -#endif #if 0 if (has_crumbled_graphics && crumbled == IMG_EMPTY_SPACE) @@ -6031,7 +5925,6 @@ void InitGraphicInfo_EM(void) g_em->crumbled_border_size = graphic_info[crumbled].border_size; } -#if 1 if (!g->double_movement && (effective_action == ACTION_FALLING || effective_action == ACTION_MOVING || effective_action == ACTION_PUSHING)) @@ -6081,77 +5974,6 @@ void InitGraphicInfo_EM(void) g_em->height = TILEY - cy * step; } -#if 0 - if (effective_action == ACTION_SMASHED_BY_ROCK && - element_info[effective_element].graphic[effective_action] == - element_info[effective_element].graphic[ACTION_DEFAULT]) - { - int move_dir = MV_DOWN; - int dx = (move_dir == MV_LEFT ? -1 : move_dir == MV_RIGHT ? 1 : 0); - int dy = (move_dir == MV_UP ? -1 : move_dir == MV_DOWN ? 1 : 0); - int num_steps = 8; - int cx = ABS(dx) * (TILEX / num_steps); - int cy = ABS(dy) * (TILEY / num_steps); - int step_frame = j + 1; - int step = (is_backside ? step_frame : num_steps - step_frame); - - graphic = (el_act_dir2img(EL_ROCK, ACTION_FALLING, MV_DOWN)); - g = &graphic_info[graphic]; - sync_frame = j; - frame = getAnimationFrame(g->anim_frames, - g->anim_delay, - g->anim_mode, - g->anim_start_frame, - sync_frame); - getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x, &src_y, - g->double_movement && is_backside); - - g_em->bitmap = src_bitmap; - g_em->src_x = src_x; - g_em->src_y = src_y; - g_em->src_offset_x = 0; - g_em->src_offset_y = 0; - g_em->dst_offset_x = 0; - g_em->dst_offset_y = 0; - - if (is_backside) /* tile where movement starts */ - { - if (dx < 0 || dy < 0) - { - g_em->src_offset_x = cx * step; - g_em->src_offset_y = cy * step; - } - else - { - g_em->dst_offset_x = cx * step; - g_em->dst_offset_y = cy * step; - } - } - else /* tile where movement ends */ - { - if (dx < 0 || dy < 0) - { - g_em->dst_offset_x = cx * step; - g_em->dst_offset_y = cy * step; - } - else - { - g_em->src_offset_x = cx * step; - g_em->src_offset_y = cy * step; - } - } - - g_em->width = TILEX - cx * step; - g_em->height = TILEY - cy * step; - -#if 0 - printf("::: -> '%s'\n", element_info[effective_element].token_name); -#endif - } -#endif - -#endif - /* create unique graphic identifier to decide if tile must be redrawn */ /* bit 31 - 16 (16 bit): EM style element bit 15 - 12 ( 4 bit): EM style frame @@ -6223,7 +6045,6 @@ void InitGraphicInfo_EM(void) } } -#if 1 for (i = 0; i < TILE_MAX; i++) { for (j = 0; j < 8; j++) @@ -6253,7 +6074,6 @@ void InitGraphicInfo_EM(void) } } } -#endif for (p = 0; p < 2; p++) { @@ -6267,7 +6087,7 @@ void InitGraphicInfo_EM(void) { int effective_element = element; int effective_action = action; - int graphic = (direction == MV_NO_MOVING ? + int graphic = (direction == MV_NONE ? el_act2img(effective_element, effective_action) : el_act_dir2img(effective_element, effective_action, direction)); @@ -6291,7 +6111,6 @@ void InitGraphicInfo_EM(void) getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x,&src_y, FALSE); -#if 1 g_em->bitmap = src_bitmap; g_em->src_x = src_x; g_em->src_y = src_y; @@ -6301,7 +6120,6 @@ void InitGraphicInfo_EM(void) g_em->dst_offset_y = 0; g_em->width = TILEX; g_em->height = TILEY; -#endif #if DEBUG_EM_GFX if (g_em->bitmap != debug_bitmap || diff --git a/src/tools.h b/src/tools.h index f41b0f83..0168369e 100644 --- a/src/tools.h +++ b/src/tools.h @@ -65,6 +65,7 @@ void RedrawPlayfield(boolean, int, int, int, int); void BackToFront(); void FadeToFront(); void ClearWindow(); +void SetMainBackgroundImageIfDefined(int); void SetMainBackgroundImage(int); void SetDoorBackgroundImage(int); void DrawBackground(int, int, int, int); @@ -138,6 +139,11 @@ void FreeToolButtons(); int map_element_RND_to_EM(int); int map_element_EM_to_RND(int); +int map_direction_RND_to_EM(int); +int map_direction_EM_to_RND(int); + +void map_android_clone_elements_RND_to_EM(struct LevelInfo *); +void map_android_clone_elements_EM_to_RND(struct LevelInfo *); int get_next_element(int); int el_act_dir2img(int, int, int); @@ -147,6 +153,7 @@ int el2baseimg(int); int el2img(int); int el2edimg(int); int el2preimg(int); +int font2baseimg(int); unsigned int InitRND(long); void InitGraphicInfo_EM(void); -- 2.34.1