From cb97a0d81529dc81696e5df8e17083b30dfe633e Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sat, 28 Feb 2004 14:23:13 +0100 Subject: [PATCH] rnd-20040228-1-src --- src/conftime.h | 2 +- src/editor.c | 125 ++++++++++-------- src/files.c | 65 +++++++-- src/game.c | 319 +++++++++++++++++++-------------------------- src/libgame/misc.c | 19 +++ src/libgame/misc.h | 1 + src/main.h | 23 +++- 7 files changed, 305 insertions(+), 249 deletions(-) diff --git a/src/conftime.h b/src/conftime.h index db9eba15..1fc08875 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2004-02-27 02:21]" +#define COMPILE_DATE_STRING "[2004-02-28 01:51]" diff --git a/src/editor.c b/src/editor.c index 18ef65c8..8f921bc6 100644 --- a/src/editor.c +++ b/src/editor.c @@ -455,9 +455,9 @@ #define GADGET_ID_CHANGE_TIME_UNITS (GADGET_ID_SELECTBOX_FIRST + 13) #define GADGET_ID_CHANGE_DIRECT_ACTION (GADGET_ID_SELECTBOX_FIRST + 14) #define GADGET_ID_CHANGE_OTHER_ACTION (GADGET_ID_SELECTBOX_FIRST + 15) -#define GADGET_ID_CHANGE_SIDES (GADGET_ID_SELECTBOX_FIRST + 16) -#define GADGET_ID_CHANGE_PLAYERS (GADGET_ID_SELECTBOX_FIRST + 17) -#define GADGET_ID_CHANGE_PAGES (GADGET_ID_SELECTBOX_FIRST + 18) +#define GADGET_ID_CHANGE_SIDE (GADGET_ID_SELECTBOX_FIRST + 16) +#define GADGET_ID_CHANGE_PLAYER (GADGET_ID_SELECTBOX_FIRST + 17) +#define GADGET_ID_CHANGE_PAGE (GADGET_ID_SELECTBOX_FIRST + 18) #define GADGET_ID_CHANGE_POWER (GADGET_ID_SELECTBOX_FIRST + 19) #define GADGET_ID_SELECT_CHANGE_PAGE (GADGET_ID_SELECTBOX_FIRST + 20) #define GADGET_ID_GROUP_CHOICE_MODE (GADGET_ID_SELECTBOX_FIRST + 21) @@ -643,9 +643,9 @@ #define ED_SELECTBOX_ID_CHANGE_TIME_UNITS 13 #define ED_SELECTBOX_ID_CHANGE_DIRECT_ACTION 14 #define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION 15 -#define ED_SELECTBOX_ID_CHANGE_SIDES 16 -#define ED_SELECTBOX_ID_CHANGE_PLAYERS 17 -#define ED_SELECTBOX_ID_CHANGE_PAGES 18 +#define ED_SELECTBOX_ID_CHANGE_SIDE 16 +#define ED_SELECTBOX_ID_CHANGE_PLAYER 17 +#define ED_SELECTBOX_ID_CHANGE_PAGE 18 #define ED_SELECTBOX_ID_CHANGE_POWER 19 #define ED_SELECTBOX_ID_SELECT_CHANGE_PAGE 20 #define ED_SELECTBOX_ID_GROUP_CHOICE_MODE 21 @@ -1138,6 +1138,7 @@ static struct ValueTextInfo options_access_type[] = { { EP_WALKABLE, "walkable" }, { EP_PASSABLE, "passable" }, + { -1, NULL } }; @@ -1146,6 +1147,7 @@ static struct ValueTextInfo options_access_layer[] = { EP_ACCESSIBLE_OVER, "over" }, { EP_ACCESSIBLE_INSIDE, "inside" }, { EP_ACCESSIBLE_UNDER, "under" }, + { -1, NULL } }; @@ -1153,6 +1155,7 @@ static struct ValueTextInfo options_access_protected[] = { { 0, "unprotected" }, { 1, "protected" }, + { -1, NULL } }; @@ -1173,6 +1176,7 @@ static struct ValueTextInfo options_access_direction[] = { MV_VERTICAL | MV_LEFT, "vertical + left" }, { MV_VERTICAL | MV_RIGHT, "vertical + right" }, { MV_ALL_DIRECTIONS, "all directions" }, + { -1, NULL } }; @@ -1182,6 +1186,7 @@ static struct ValueTextInfo options_walk_to_action[] = { EP_COLLECTIBLE_ONLY, "collectible" }, { EP_DROPPABLE, "collectible & droppable" }, { EP_PUSHABLE, "pushable" }, + { -1, NULL } }; @@ -1207,6 +1212,7 @@ static struct ValueTextInfo options_move_pattern[] = { MV_WHEN_DROPPED, "when dropped" }, { MV_MAZE_RUNNER, "maze runner style" }, { MV_MAZE_HUNTER, "maze hunter style" }, + { -1, NULL } }; @@ -1219,6 +1225,7 @@ static struct ValueTextInfo options_move_direction[] = { MV_START_DOWN, "down" }, { MV_START_RANDOM, "random" }, { MV_START_PREVIOUS, "previous" }, + { -1, NULL } }; @@ -1229,6 +1236,7 @@ static struct ValueTextInfo options_move_stepsize[] = { 4, "normal" }, { 8, "fast" }, { 16, "very fast" }, + { -1, NULL } }; @@ -1236,6 +1244,7 @@ static struct ValueTextInfo options_move_leave_type[] = { { LEAVE_TYPE_UNLIMITED, "leave behind" }, { LEAVE_TYPE_LIMITED, "change it to" }, + { -1, NULL } }; @@ -1246,6 +1255,7 @@ static struct ValueTextInfo options_smash_targets[] = { EP_CAN_SMASH_ENEMIES, "enemies" }, #endif { EP_CAN_SMASH_EVERYTHING, "everything" }, + { -1, NULL } }; @@ -1256,6 +1266,7 @@ static struct ValueTextInfo options_slippery_type[] = { SLIPPERY_ANY_RIGHT_LEFT, "right, left" }, { SLIPPERY_ONLY_LEFT, "only left" }, { SLIPPERY_ONLY_RIGHT, "only right" }, + { -1, NULL } }; @@ -1264,6 +1275,7 @@ static struct ValueTextInfo options_deadliness[] = { EP_DONT_RUN_INTO, "running into" }, { EP_DONT_COLLIDE_WITH, "colliding with" }, { EP_DONT_TOUCH, "touching" }, + { -1, NULL } }; @@ -1273,6 +1285,7 @@ static struct ValueTextInfo options_consistency[] = { EP_CAN_EXPLODE_DYNA, "can explode 3+3" }, { EP_CAN_EXPLODE_1X1, "can explode 1x1" }, { EP_INDESTRUCTIBLE, "indestructible" }, + { -1, NULL } }; @@ -1280,6 +1293,7 @@ static struct ValueTextInfo options_time_units[] = { { 1, "frames" }, { FRAMES_PER_SECOND, "seconds" }, + { -1, NULL } }; @@ -1300,6 +1314,7 @@ static struct ValueTextInfo options_change_direct_action[] = #endif { CE_IMPACT, "impact (on something)" }, { CE_SMASHED, "smashed (from above)" }, + { -1, NULL } }; @@ -1319,12 +1334,13 @@ static struct ValueTextInfo options_change_other_action[] = { CE_OTHER_GETS_HIT, "hit by ..." }, #endif { CE_OTHER_IS_SWITCHING, "switch of ..." }, - { CE_OTHER_IS_CHANGING, "change of" }, + { CE_OTHER_IS_CHANGING, "change by page of" }, { CE_OTHER_IS_EXPLODING, "explosion of" }, + { -1, NULL } }; -static struct ValueTextInfo options_change_sides[] = +static struct ValueTextInfo options_change_trigger_side[] = { { CH_SIDE_LEFT, "left" }, { CH_SIDE_RIGHT, "right" }, @@ -1333,54 +1349,57 @@ static struct ValueTextInfo options_change_sides[] = { CH_SIDE_LEFT_RIGHT, "left/right" }, { CH_SIDE_TOP_BOTTOM, "top/bottom" }, { CH_SIDE_ANY, "any" }, + { -1, NULL } }; static struct ValueTextInfo options_change_trigger_player[] = { - { 0, "any" }, - { 1, "1" }, - { 2, "2" }, - { 3, "3" }, - { 4, "4" }, + { CH_PLAYER_1, "1" }, + { CH_PLAYER_2, "2" }, + { CH_PLAYER_3, "3" }, + { CH_PLAYER_4, "4" }, + { CH_PLAYER_ANY, "any" }, + { -1, NULL } }; static struct ValueTextInfo options_change_trigger_page[] = { - { 0, "any" }, - { 1, "1" }, - { 2, "2" }, - { 3, "3" }, - { 4, "4" }, - { 5, "5" }, - { 6, "6" }, - { 7, "7" }, - { 8, "8" }, - { 9, "9" }, - { 10, "10" }, - { 11, "11" }, - { 12, "12" }, - { 13, "13" }, - { 14, "14" }, - { 15, "15" }, - { 16, "16" }, - { 17, "17" }, - { 18, "18" }, - { 19, "19" }, - { 20, "20" }, - { 21, "21" }, - { 22, "22" }, - { 23, "23" }, - { 24, "24" }, - { 25, "25" }, - { 26, "26" }, - { 27, "27" }, - { 28, "28" }, - { 29, "29" }, - { 30, "30" }, - { 31, "31" }, - { 32, "32" }, + { (1 << 0), "1" }, + { (1 << 1), "2" }, + { (1 << 2), "3" }, + { (1 << 3), "4" }, + { (1 << 4), "5" }, + { (1 << 5), "6" }, + { (1 << 6), "7" }, + { (1 << 7), "8" }, + { (1 << 8), "9" }, + { (1 << 9), "10" }, + { (1 << 10), "11" }, + { (1 << 11), "12" }, + { (1 << 12), "13" }, + { (1 << 13), "14" }, + { (1 << 14), "15" }, + { (1 << 15), "16" }, + { (1 << 16), "17" }, + { (1 << 17), "18" }, + { (1 << 18), "19" }, + { (1 << 19), "20" }, + { (1 << 20), "21" }, + { (1 << 21), "22" }, + { (1 << 22), "23" }, + { (1 << 23), "24" }, + { (1 << 24), "25" }, + { (1 << 25), "26" }, + { (1 << 26), "27" }, + { (1 << 27), "28" }, + { (1 << 28), "29" }, + { (1 << 29), "30" }, + { (1 << 30), "31" }, + { (1 << 31), "32" }, + { CH_PAGE_ANY, "any" }, + { -1, NULL } }; @@ -1389,6 +1408,7 @@ static struct ValueTextInfo options_change_power[] = { CP_NON_DESTRUCTIVE, "empty" }, { CP_HALF_DESTRUCTIVE, "diggable" }, { CP_FULL_DESTRUCTIVE, "destructible" }, + { -1, NULL } }; @@ -1405,6 +1425,7 @@ static struct ValueTextInfo options_group_choice_mode[] = { ANIM_LINEAR, "linear" }, { ANIM_PINGPONG, "pingpong" }, { ANIM_PINGPONG2, "pingpong 2" }, + { -1, NULL } }; @@ -1557,15 +1578,15 @@ static struct }, { ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(6), - GADGET_ID_CHANGE_SIDES, GADGET_ID_NONE, + GADGET_ID_CHANGE_SIDE, GADGET_ID_NONE, -1, - options_change_sides, - &custom_element_change.sides, + options_change_trigger_side, + &custom_element_change.trigger_side, "... at", "side", "element side that causes change" }, { ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(7), - GADGET_ID_CHANGE_PLAYERS, GADGET_ID_NONE, + GADGET_ID_CHANGE_PLAYER, GADGET_ID_NONE, -1, options_change_trigger_player, &custom_element_change.trigger_player, @@ -1573,7 +1594,7 @@ static struct }, { ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(7), - GADGET_ID_CHANGE_PAGES, GADGET_ID_CHANGE_PLAYERS, + GADGET_ID_CHANGE_PAGE, GADGET_ID_CHANGE_PLAYER, -1, options_change_trigger_page, &custom_element_change.trigger_page, @@ -5479,7 +5500,7 @@ static void copy_custom_element_settings(int element_from, int element_to) change_to->can_change = change_from->can_change; - change_to->sides = change_from->sides; + change_to->trigger_side = change_from->trigger_side; } #endif diff --git a/src/files.c b/src/files.c index c8580105..5fd205cb 100644 --- a/src/files.c +++ b/src/files.c @@ -92,7 +92,10 @@ void setElementChangeInfoToDefaults(struct ElementChangeInfo *change) change->can_change = FALSE; change->events = CE_BITMASK_DEFAULT; - change->sides = CH_SIDE_ANY; + + change->trigger_player = CH_PLAYER_ANY; + change->trigger_side = CH_SIDE_ANY; + change->trigger_page = CH_PAGE_ANY; change->target_element = EL_EMPTY_SPACE; @@ -1069,13 +1072,23 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level) change->can_change = getFile8Bit(file); - change->sides = 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)); - if (change->sides == CH_SIDE_NONE) /* correct empty sides field */ - change->sides = CH_SIDE_ANY; + /* some free bytes for future change property values and padding */ + ReadUnusedBytesFromFile(file, 6); + +#else /* some free bytes for future change property values and padding */ ReadUnusedBytesFromFile(file, 8); +#endif } /* mark this custom element as modified */ @@ -2042,7 +2055,7 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename) if (level->game_version < VERSION_IDENT(3,0,9,0)) { - int i; + int i, j; level->can_move_into_acid = 0; /* nothing can move into acid */ @@ -2053,6 +2066,20 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename) for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) SET_PROPERTY(EL_CUSTOM_START + i, EP_CAN_MOVE_INTO_ACID, TRUE); + + for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) + { + int element = EL_CUSTOM_START + i; + struct ElementInfo *ei = &element_info[element]; + + for (j = 0; j < ei->num_change_pages; j++) + { + struct ElementChangeInfo *change = &ei->change_page[j]; + + change->trigger_player = CH_PLAYER_ANY; + change->trigger_page = CH_PAGE_ANY; + } + } } } else @@ -2158,13 +2185,22 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename) } } - /* correct field access direction (for old levels without this option) */ + /* correct custom element fields (for old levels without these options) */ for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) { int element = EL_CUSTOM_START + i; + struct ElementInfo *ei = &element_info[element]; - if (element_info[element].access_direction == MV_NO_MOVING) - element_info[element].access_direction = MV_ALL_DIRECTIONS; + if (ei->access_direction == MV_NO_MOVING) + ei->access_direction = MV_ALL_DIRECTIONS; + + 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; + } } #if 0 @@ -2671,10 +2707,21 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element) putFile8Bit(file, change->can_change); - putFile8Bit(file, change->sides); + 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); + +#else /* some free bytes for future change property values and padding */ WriteUnusedBytesToFile(file, 8); +#endif } } diff --git a/src/game.c b/src/game.c index bf4b1bf8..7ff1a5e4 100644 --- a/src/game.c +++ b/src/game.c @@ -249,15 +249,26 @@ static void TestIfElementTouchesCustomElement(int, int); static void TestIfElementHitsCustomElement(int, int, int); static void ChangeElement(int, int, int); + static boolean CheckTriggeredElementChangeExt(int, int, int, int, int,int,int); -static boolean CheckTriggeredElementSideChange(int, int, int, int, int); -static boolean CheckTriggeredElementPlayerChange(int, int, int, int, int, int); -static boolean CheckTriggeredElementPageChange(int, int, int, int, int); -static boolean CheckTriggeredElementChange(int, int, int, int); +#define CheckTriggeredElementChange(x, y, e, ev) \ + CheckTriggeredElementChangeExt(x, y, e, ev, -1, CH_SIDE_ANY, -1) +#define CheckTriggeredElementChangePlayer(x, y, e, ev, p, s) \ + CheckTriggeredElementChangeExt(x, y, e, ev, p, s, -1) +#define CheckTriggeredElementChangeSide(x, y, e, ev, s) \ + CheckTriggeredElementChangeExt(x, y, e, ev, -1, s, -1) +#define CheckTriggeredElementChangePage(x, y, e, ev, p) \ + CheckTriggeredElementChangeExt(x, y, e, ev, -1, CH_SIDE_ANY, p) + static boolean CheckElementChangeExt(int, int, int, int, int, int, int); -static boolean CheckElementSideChange(int, int, int, int, int, int); -static boolean CheckElementPlayerChange(int, int, int, int, int, int, int); -static boolean CheckElementChange(int, int, int, int); +#define CheckElementChange(x, y, e, ev) \ + CheckElementChangeExt(x, y, e, ev, -1, CH_SIDE_ANY, -1) +#define CheckElementChangePlayer(x, y, e, ev, p, s) \ + CheckElementChangeExt(x, y, e, ev, p, s, -1) +#define CheckElementChangeSide(x, y, e, ev, s) \ + CheckElementChangeExt(x, y, e, ev, -1, s, -1) +#define CheckElementChangePage(x, y, e, ev, p) \ + CheckElementChangeExt(x, y, e, ev, -1, CH_SIDE_ANY, p) static void PlayLevelSound(int, int, int); static void PlayLevelSoundNearest(int, int, int); @@ -1341,6 +1352,7 @@ void InitGame() struct PlayerInfo *player = &stored_player[i]; player->index_nr = i; + player->index_bit = (1 << i); player->element_nr = EL_PLAYER_1 + i; player->present = FALSE; @@ -3775,10 +3787,9 @@ void Impact(int x, int y) { CheckElementChange(x, y + 1, smashed, CE_SMASHED); - CheckTriggeredElementSideChange(x, y + 1, smashed, CH_SIDE_TOP, - CE_OTHER_IS_SWITCHING); - CheckElementSideChange(x, y + 1, smashed, CH_SIDE_TOP, - CE_SWITCHED, -1); + CheckTriggeredElementChangeSide(x, y + 1, smashed, + CE_OTHER_IS_SWITCHING, CH_SIDE_TOP); + CheckElementChangeSide(x, y + 1, smashed, CE_SWITCHED, CH_SIDE_TOP); } } else @@ -5635,8 +5646,8 @@ void ContinueMoving(int x, int y) int hitting_element = Feld[newx][newy]; /* !!! fix side (direction) orientation here and elsewhere !!! */ - CheckElementSideChange(newx, newy, hitting_element, - direction, CE_HITTING_SOMETHING, -1); + CheckElementChangeSide(newx, newy, hitting_element, CE_HITTING_SOMETHING, + direction); #if 0 if (IN_LEV_FIELD(nextx, nexty)) @@ -5653,8 +5664,8 @@ void ContinueMoving(int x, int y) { int i; - CheckElementSideChange(nextx, nexty, touched_element, - opposite_direction, CE_HIT_BY_SOMETHING, -1); + CheckElementChangeSide(nextx, nexty, touched_element, + CE_HIT_BY_SOMETHING, opposite_direction); if (IS_CUSTOM_ELEMENT(hitting_element) && HAS_ANY_CHANGE_EVENT(hitting_element, CE_OTHER_IS_HITTING)) @@ -5666,11 +5677,11 @@ void ContinueMoving(int x, int y) if (change->can_change && change->events & CH_EVENT_BIT(CE_OTHER_IS_HITTING) && - change->sides & touched_side && + change->trigger_side & touched_side && change->trigger_element == touched_element) { - CheckElementSideChange(newx, newy, hitting_element, - CH_SIDE_ANY, CE_OTHER_IS_HITTING, i); + CheckElementChangePage(newx, newy, hitting_element, + CE_OTHER_IS_HITTING, i); break; } } @@ -5686,11 +5697,11 @@ void ContinueMoving(int x, int y) if (change->can_change && change->events & CH_EVENT_BIT(CE_OTHER_GETS_HIT) && - change->sides & hitting_side && + change->trigger_side & hitting_side && change->trigger_element == hitting_element) { - CheckElementSideChange(nextx, nexty, touched_element, - CH_SIDE_ANY, CE_OTHER_GETS_HIT, i); + CheckElementChangePage(nextx, nexty, touched_element, + CE_OTHER_GETS_HIT, i); break; } } @@ -6662,7 +6673,7 @@ static boolean ChangeElementNow(int x, int y, int element, int page) Changed[x][y] |= ChangeEvent[x][y]; /* ignore same changes in this frame */ - CheckTriggeredElementPageChange(x,y, Feld[x][y], CE_OTHER_IS_CHANGING, page); + CheckTriggeredElementChangePage(x,y, Feld[x][y], CE_OTHER_IS_CHANGING, page); if (change->explode) { @@ -6838,9 +6849,9 @@ static void ChangeElement(int x, int y, int page) static boolean CheckTriggeredElementChangeExt(int lx, int ly, int trigger_element, - int trigger_side, int trigger_event, int trigger_player, + int trigger_side, int trigger_page) { int i, j, x, y; @@ -6863,16 +6874,11 @@ static boolean CheckTriggeredElementChangeExt(int lx, int ly, struct ElementChangeInfo *change = &element_info[element].change_page[j]; if (change->can_change && -#if 1 change->events & CH_EVENT_BIT(trigger_event) && -#endif - change->sides & trigger_side && -#if 1 - IS_EQUAL_OR_IN_GROUP(trigger_element, change->trigger_element) -#else - change->trigger_element == trigger_element -#endif - ) + change->trigger_side & trigger_side && + change->trigger_player & trigger_player && + change->trigger_page & (1 << trigger_page) && + IS_EQUAL_OR_IN_GROUP(trigger_element, change->trigger_element)) { #if 0 if (!(change->events & CH_EVENT_BIT(trigger_event))) @@ -6909,43 +6915,12 @@ static boolean CheckTriggeredElementChangeExt(int lx, int ly, return TRUE; } -static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element, - int trigger_event) -{ - return CheckTriggeredElementChangeExt(lx, ly, trigger_element, CH_SIDE_ANY, - trigger_event, -1, -1); -} - -static boolean CheckTriggeredElementSideChange(int lx, int ly, - int trigger_element, - int trigger_side, - int trigger_event) -{ - return CheckTriggeredElementChangeExt(lx, ly, trigger_element, trigger_side, - trigger_event, -1, -1); -} - -static boolean CheckTriggeredElementPlayerChange(int lx, int ly, - int trigger_element, - int trigger_player, - int trigger_side, - int trigger_event) -{ - return CheckTriggeredElementChangeExt(lx, ly, trigger_element, trigger_side, - trigger_event, trigger_player, -1); -} - -static boolean CheckTriggeredElementPageChange(int lx, int ly, - int trigger_element, - int trigger_event, - int trigger_page) -{ - return CheckTriggeredElementChangeExt(lx, ly, trigger_element, CH_SIDE_ANY, - trigger_event, -1, trigger_page); -} - -static boolean CheckElementChangeExt(int x, int y, int element, int player, - int side, int trigger_event, int page) +static boolean CheckElementChangeExt(int x, int y, + int element, + int trigger_event, + int trigger_player, + int trigger_side, + int trigger_page) { if (!CAN_CHANGE(element) || !HAS_ANY_CHANGE_EVENT(element, trigger_event)) return FALSE; @@ -6957,7 +6932,7 @@ static boolean CheckElementChangeExt(int x, int y, int element, int player, } #if 1 - if (page < 0) + if (trigger_page < 0) { boolean change_element = FALSE; int i; @@ -6968,10 +6943,11 @@ static boolean CheckElementChangeExt(int x, int y, int element, int player, if (change->can_change && change->events & CH_EVENT_BIT(trigger_event) && - change->sides & side) + change->trigger_side & trigger_side && + change->trigger_player & trigger_player) { change_element = TRUE; - page = i; + trigger_page = i; break; } @@ -6985,45 +6961,20 @@ static boolean CheckElementChangeExt(int x, int y, int element, int player, /* !!! this check misses pages with same event, but different side !!! */ - if (page < 0) - page = element_info[element].event_page_nr[trigger_event]; + if (trigger_page < 0) + trigger_page = element_info[element].event_page_nr[trigger_event]; - if (!(element_info[element].change_page[page].sides & side)) + if (!(element_info[element].change_page[trigger_page].trigger_side & trigger_side)) return FALSE; #endif ChangeDelay[x][y] = 1; ChangeEvent[x][y] = CH_EVENT_BIT(trigger_event); - ChangeElement(x, y, page); + ChangeElement(x, y, trigger_page); return TRUE; } -static boolean CheckElementChange(int x, int y, int element, int trigger_event) -{ - return CheckElementChangeExt(x, y, element, -1, CH_SIDE_ANY, trigger_event, - -1); -} - -static boolean CheckElementSideChange(int x, int y, int element, - int trigger_side, - int trigger_event, - int page) -{ - return CheckElementChangeExt(x, y, element, -1, trigger_side, trigger_event, - page); -} - -static boolean CheckElementPlayerChange(int x, int y, int element, - int trigger_player, - int trigger_side, - int trigger_event, - int page) -{ - return CheckElementChangeExt(x, y, element, trigger_player, trigger_side, - trigger_event, page); -} - static void PlayPlayerSound(struct PlayerInfo *player) { int jx = player->jx, jy = player->jy; @@ -8127,7 +8078,7 @@ boolean MovePlayerOneStep(struct PlayerInfo *player, int dx, int dy, int real_dx, int real_dy) { #if 0 - static int change_sides[4][2] = + static int trigger_sides[4][2] = { /* enter side leave side */ { CH_SIDE_RIGHT, CH_SIDE_LEFT }, /* moving left */ @@ -8139,8 +8090,8 @@ boolean MovePlayerOneStep(struct PlayerInfo *player, dx == +1 ? MV_RIGHT : dy == -1 ? MV_UP : dy == +1 ? MV_DOWN : MV_NO_MOVING); - int enter_side = change_sides[MV_DIR_BIT(move_direction)][0]; - int leave_side = change_sides[MV_DIR_BIT(move_direction)][1]; + 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; @@ -8213,18 +8164,17 @@ boolean MovePlayerOneStep(struct PlayerInfo *player, #if 0 if (IS_CUSTOM_ELEMENT(Feld[jx][jy])) { - CheckTriggeredElementSideChange(jx, jy, Feld[jx][jy], leave_side, - CE_OTHER_GETS_LEFT); - CheckElementSideChange(jx, jy, Feld[jx][jy], leave_side, - CE_LEFT_BY_PLAYER, -1); + CheckTriggeredElementChangeSide(jx, jy, Feld[jx][jy], CE_OTHER_GETS_LEFT, + leave_side); + CheckElementChangeSide(jx, jy, Feld[jx][jy], CE_LEFT_BY_PLAYER,leave_side); } if (IS_CUSTOM_ELEMENT(Feld[new_jx][new_jy])) { - CheckTriggeredElementSideChange(new_jx, new_jy, Feld[new_jx][new_jy], - enter_side, CE_OTHER_GETS_ENTERED); - CheckElementSideChange(new_jx, new_jy, Feld[new_jx][new_jy], enter_side, - CE_ENTERED_BY_PLAYER, -1); + CheckTriggeredElementChangeSide(new_jx, new_jy, Feld[new_jx][new_jy], + CE_OTHER_GETS_ENTERED, enter_side); + CheckElementChangeSide(new_jx, new_jy, Feld[new_jx][new_jy], + CE_ENTERED_BY_PLAYER, enter_side); } #endif @@ -8417,7 +8367,7 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) #if 1 { - static int change_sides[4][2] = + static int trigger_sides[4][2] = { /* enter side leave side */ { CH_SIDE_RIGHT, CH_SIDE_LEFT }, /* moving left */ @@ -8426,27 +8376,27 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) { CH_SIDE_TOP, CH_SIDE_BOTTOM } /* moving down */ }; int move_direction = player->MovDir; - int enter_side = change_sides[MV_DIR_BIT(move_direction)][0]; - int leave_side = change_sides[MV_DIR_BIT(move_direction)][1]; + int enter_side = trigger_sides[MV_DIR_BIT(move_direction)][0]; + int leave_side = trigger_sides[MV_DIR_BIT(move_direction)][1]; #if 1 if (IS_CUSTOM_ELEMENT(Feld[old_jx][old_jy])) { - CheckTriggeredElementPlayerChange(old_jx, old_jy, Feld[old_jx][old_jy], - player->index_nr, leave_side, - CE_OTHER_GETS_LEFT); - CheckElementPlayerChange(old_jx, old_jy, Feld[old_jx][old_jy], - player->index_nr, leave_side, - CE_LEFT_BY_PLAYER, -1); + CheckTriggeredElementChangePlayer(old_jx, old_jy, Feld[old_jx][old_jy], + CE_OTHER_GETS_LEFT, + player->index_bit, leave_side); + CheckElementChangePlayer(old_jx, old_jy, Feld[old_jx][old_jy], + CE_LEFT_BY_PLAYER, + player->index_bit, leave_side); } if (IS_CUSTOM_ELEMENT(Feld[jx][jy])) { - CheckTriggeredElementPlayerChange(jx, jy, Feld[jx][jy], - player->index_nr, enter_side, - CE_OTHER_GETS_ENTERED); - CheckElementPlayerChange(jx, jy, Feld[jx][jy], player->index_nr, - enter_side, CE_ENTERED_BY_PLAYER, -1); + CheckTriggeredElementChangePlayer(jx, jy, Feld[jx][jy], + CE_OTHER_GETS_ENTERED, + player->index_bit, enter_side); + CheckElementChangePlayer(jx, jy, Feld[jx][jy], CE_ENTERED_BY_PLAYER, + player->index_bit, enter_side); } #endif @@ -8619,7 +8569,7 @@ void TestIfPlayerTouchesCustomElement(int x, int y) { +1, 0 }, { 0, +1 } }; - static int change_sides[4][2] = + static int trigger_sides[4][2] = { /* center side border side */ { CH_SIDE_TOP, CH_SIDE_BOTTOM }, /* check top */ @@ -8641,8 +8591,8 @@ void TestIfPlayerTouchesCustomElement(int x, int y) { int xx = x + xy[i][0]; int yy = y + xy[i][1]; - int center_side = change_sides[i][0]; - int border_side = change_sides[i][1]; + int center_side = trigger_sides[i][0]; + int border_side = trigger_sides[i][1]; int border_element; if (!IN_LEV_FIELD(xx, yy)) @@ -8661,11 +8611,11 @@ void TestIfPlayerTouchesCustomElement(int x, int y) else continue; /* center and border element do not touch */ - CheckTriggeredElementPlayerChange(xx, yy, border_element, - player->index_nr, border_side, - CE_OTHER_GETS_TOUCHED); - CheckElementPlayerChange(xx, yy, border_element, player->index_nr, - border_side, CE_TOUCHED_BY_PLAYER, -1); + CheckTriggeredElementChangePlayer(xx, yy, border_element, + CE_OTHER_GETS_TOUCHED, + player->index_bit, border_side); + CheckElementChangePlayer(xx, yy, border_element, CE_TOUCHED_BY_PLAYER, + player->index_bit, border_side); } else if (IS_PLAYER(xx, yy)) { @@ -8677,11 +8627,11 @@ void TestIfPlayerTouchesCustomElement(int x, int y) continue; /* center and border element do not touch */ } - CheckTriggeredElementPlayerChange(x, y, center_element, - player->index_nr, center_side, - CE_OTHER_GETS_TOUCHED); - CheckElementPlayerChange(x, y, center_element, player->index_nr, - center_side, CE_TOUCHED_BY_PLAYER, -1); + CheckTriggeredElementChangePlayer(x, y, center_element, + CE_OTHER_GETS_TOUCHED, + player->index_bit, center_side); + CheckElementChangePlayer(x, y, center_element, CE_TOUCHED_BY_PLAYER, + player->index_bit, center_side); break; } @@ -8697,7 +8647,7 @@ void TestIfElementTouchesCustomElement(int x, int y) { +1, 0 }, { 0, +1 } }; - static int change_sides[4][2] = + static int trigger_sides[4][2] = { /* center side border side */ { CH_SIDE_TOP, CH_SIDE_BOTTOM }, /* check top */ @@ -8721,8 +8671,8 @@ void TestIfElementTouchesCustomElement(int x, int y) { int xx = x + xy[i][0]; int yy = y + xy[i][1]; - int center_side = change_sides[i][0]; - int border_side = change_sides[i][1]; + int center_side = trigger_sides[i][0]; + int border_side = trigger_sides[i][1]; int border_element; if (!IN_LEV_FIELD(xx, yy)) @@ -8749,7 +8699,7 @@ void TestIfElementTouchesCustomElement(int x, int y) if (change->can_change && change->events & CH_EVENT_BIT(CE_OTHER_IS_TOUCHING) && - change->sides & border_side && + change->trigger_side & border_side && #if 1 IS_EQUAL_OR_IN_GROUP(border_element, change->trigger_element) #else @@ -8776,7 +8726,7 @@ void TestIfElementTouchesCustomElement(int x, int y) if (change->can_change && change->events & CH_EVENT_BIT(CE_OTHER_IS_TOUCHING) && - change->sides & center_side && + change->trigger_side & center_side && #if 1 IS_EQUAL_OR_IN_GROUP(center_element, change->trigger_element) #else @@ -8784,8 +8734,8 @@ void TestIfElementTouchesCustomElement(int x, int y) #endif ) { - CheckElementSideChange(xx, yy, border_element, CH_SIDE_ANY, - CE_OTHER_IS_TOUCHING, j); + CheckElementChangePage(xx, yy, border_element, CE_OTHER_IS_TOUCHING, + j); break; } } @@ -8793,8 +8743,8 @@ void TestIfElementTouchesCustomElement(int x, int y) } if (change_center_element) - CheckElementSideChange(x, y, center_element, CH_SIDE_ANY, - CE_OTHER_IS_TOUCHING, center_element_change_page); + CheckElementChangePage(x, y, center_element, CE_OTHER_IS_TOUCHING, + center_element_change_page); } void TestIfElementHitsCustomElement(int x, int y, int direction) @@ -8819,8 +8769,8 @@ void TestIfElementHitsCustomElement(int x, int y, int direction) return; #endif - CheckElementSideChange(x, y, hitting_element, - direction, CE_HITTING_SOMETHING, -1); + CheckElementChangeSide(x, y, hitting_element, CE_HITTING_SOMETHING, + direction); if (IN_LEV_FIELD(hitx, hity)) { @@ -8840,8 +8790,8 @@ void TestIfElementHitsCustomElement(int x, int y, int direction) { int i; - CheckElementSideChange(hitx, hity, touched_element, - opposite_direction, CE_HIT_BY_SOMETHING, -1); + CheckElementChangeSide(hitx, hity, touched_element, CE_HIT_BY_SOMETHING, + opposite_direction); if (IS_CUSTOM_ELEMENT(hitting_element) && HAS_ANY_CHANGE_EVENT(hitting_element, CE_OTHER_IS_HITTING)) @@ -8853,7 +8803,7 @@ void TestIfElementHitsCustomElement(int x, int y, int direction) if (change->can_change && change->events & CH_EVENT_BIT(CE_OTHER_IS_HITTING) && - change->sides & touched_side && + change->trigger_side & touched_side && #if 1 IS_EQUAL_OR_IN_GROUP(touched_element, change->trigger_element) @@ -8862,8 +8812,8 @@ void TestIfElementHitsCustomElement(int x, int y, int direction) #endif ) { - CheckElementSideChange(x, y, hitting_element, - CH_SIDE_ANY, CE_OTHER_IS_HITTING, i); + CheckElementChangePage(x, y, hitting_element, CE_OTHER_IS_HITTING, + i); break; } } @@ -8879,7 +8829,7 @@ void TestIfElementHitsCustomElement(int x, int y, int direction) if (change->can_change && change->events & CH_EVENT_BIT(CE_OTHER_GETS_HIT) && - change->sides & hitting_side && + change->trigger_side & hitting_side && #if 1 IS_EQUAL_OR_IN_GROUP(hitting_element, change->trigger_element) #else @@ -8887,8 +8837,8 @@ void TestIfElementHitsCustomElement(int x, int y, int direction) #endif ) { - CheckElementSideChange(hitx, hity, touched_element, - CH_SIDE_ANY, CE_OTHER_GETS_HIT, i); + CheckElementChangePage(hitx, hity, touched_element, + CE_OTHER_GETS_HIT, i); break; } } @@ -9228,7 +9178,7 @@ int DigField(struct PlayerInfo *player, int oldx, int oldy, int x, int y, int real_dx, int real_dy, int mode) { - static int change_sides[4] = + static int trigger_sides[4] = { CH_SIDE_RIGHT, /* moving left */ CH_SIDE_LEFT, /* moving right */ @@ -9246,7 +9196,7 @@ int DigField(struct PlayerInfo *player, dy == -1 ? MV_UP : dy == +1 ? MV_DOWN : MV_NO_MOVING); int opposite_direction = MV_DIR_OPPOSITE(move_direction); - int dig_side = change_sides[MV_DIR_BIT(move_direction)]; + int dig_side = trigger_sides[MV_DIR_BIT(move_direction)]; int old_element = Feld[jx][jy]; int element; @@ -9535,9 +9485,8 @@ int DigField(struct PlayerInfo *player, PlayLevelSoundElementAction(x, y, element, ACTION_DIGGING); - CheckTriggeredElementPlayerChange(x, y, element, - player->index_nr, CH_SIDE_ANY, - CE_OTHER_GETS_DIGGED); + CheckTriggeredElementChangePlayer(x, y, element, CE_OTHER_GETS_DIGGED, + player->index_bit, CH_SIDE_ANY); #if 1 if (mode == DF_SNAP) @@ -9632,9 +9581,9 @@ int DigField(struct PlayerInfo *player, RaiseScoreElement(element); PlayLevelSoundElementAction(x, y, element, ACTION_COLLECTING); - CheckTriggeredElementPlayerChange(x, y, element, player->index_nr, - CH_SIDE_ANY, - CE_OTHER_GETS_COLLECTED); + CheckTriggeredElementChangePlayer(x, y, element, + CE_OTHER_GETS_COLLECTED, + player->index_bit, CH_SIDE_ANY); #if 1 if (mode == DF_SNAP) @@ -9790,10 +9739,10 @@ int DigField(struct PlayerInfo *player, else player->push_delay_value = -1; /* get new value later */ - CheckTriggeredElementPlayerChange(x, y, element, player->index_nr, - dig_side, CE_OTHER_GETS_PUSHED); - CheckElementPlayerChange(x, y, element, player->index_nr, dig_side, - CE_PUSHED_BY_PLAYER, -1); + CheckTriggeredElementChangePlayer(x, y, element, CE_OTHER_GETS_PUSHED, + player->index_bit, dig_side); + CheckElementChangePlayer(x, y, element, CE_PUSHED_BY_PLAYER, + player->index_bit, dig_side); break; } @@ -9897,16 +9846,17 @@ int DigField(struct PlayerInfo *player, player->switch_x = x; player->switch_y = y; - CheckTriggeredElementPlayerChange(x, y, element, player->index_nr, - dig_side, CE_OTHER_IS_SWITCHING); - CheckElementPlayerChange(x, y, element, player->index_nr, dig_side, - CE_SWITCHED, -1); + CheckTriggeredElementChangePlayer(x, y, element, + CE_OTHER_IS_SWITCHING, + player->index_bit, dig_side); + CheckElementChangePlayer(x, y, element, CE_SWITCHED, + player->index_bit, dig_side); } - CheckTriggeredElementPlayerChange(x, y, element, player->index_nr, - dig_side, CE_OTHER_GETS_PRESSED); - CheckElementPlayerChange(x, y, element, player->index_nr, dig_side, - CE_PRESSED_BY_PLAYER, -1); + CheckTriggeredElementChangePlayer(x, y, element, CE_OTHER_GETS_PRESSED, + player->index_bit, dig_side); + CheckElementChangePlayer(x, y, element, CE_PRESSED_BY_PLAYER, + player->index_bit, dig_side); } return MF_NO_ACTION; @@ -10045,10 +9995,11 @@ boolean DropElement(struct PlayerInfo *player) Changed[jx][jy] = 0; /* allow another change */ #endif - CheckTriggeredElementPlayerChange(jx, jy, new_element, player->index_nr, - CH_SIDE_ANY, CE_OTHER_GETS_DROPPED); - CheckElementPlayerChange(jx, jy, new_element, player->index_nr, - CH_SIDE_ANY, CE_DROPPED_BY_PLAYER, -1); + CheckTriggeredElementChangePlayer(jx, jy, new_element, + CE_OTHER_GETS_DROPPED, + player->index_bit, CH_SIDE_ANY); + CheckElementChangePlayer(jx, jy, new_element, CE_DROPPED_BY_PLAYER, + player->index_bit, CH_SIDE_ANY); TestIfElementTouchesCustomElement(jx, jy); } @@ -10113,8 +10064,8 @@ boolean DropElement(struct PlayerInfo *player) #if 1 TestIfElementHitsCustomElement(jx, jy, direction); #else - CheckElementSideChange(jx, jy, new_element, - direction, CE_HITTING_SOMETHING, -1); + CheckElementChangeSide(jx, jy, new_element, CE_HITTING_SOMETHING, + direction); #endif } diff --git a/src/libgame/misc.c b/src/libgame/misc.c index 3612ba04..3b447821 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -52,6 +52,7 @@ void printf_line(char *line_string, int line_length) 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, so if you want to save the result, copy it to a private string buffer; @@ -82,6 +83,7 @@ char *int2str(int number, int size) } } + /* something similar to "int2str()" above, but allocates its own memory and has a different interface; we cannot use "itoa()", because this seems to be already defined when cross-compiling to the win32 target */ @@ -103,6 +105,23 @@ char *i_to_a(unsigned int i) } +/* calculate base-2 logarithm of argument (rounded down to integer; + this function returns the number of the highest bit set in argument) */ + +int log_2(unsigned int x) +{ + int e = 0; + + while ((1 << e) < x) + { + x -= (1 << e); /* for rounding down (rounding up: remove this line) */ + e++; + } + + return e; +} + + /* ------------------------------------------------------------------------- */ /* counter functions */ /* ------------------------------------------------------------------------- */ diff --git a/src/libgame/misc.h b/src/libgame/misc.h index 1a29394c..2f3a957a 100644 --- a/src/libgame/misc.h +++ b/src/libgame/misc.h @@ -71,6 +71,7 @@ void fprintf_line(FILE *, char *, int); void printf_line(char *, int); char *int2str(int, int); char *i_to_a(unsigned int); +int log_2(unsigned int); void InitCounter(void); unsigned long Counter(void); diff --git a/src/main.h b/src/main.h index 490af4fa..370d2891 100644 --- a/src/main.h +++ b/src/main.h @@ -211,7 +211,7 @@ (CH_EVENT_VAR(e) |= CH_EVENT_BIT(c)) : \ (CH_EVENT_VAR(e) &= ~CH_EVENT_BIT(c))) : 0) -/* values for change sides for custom elements */ +/* 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 @@ -221,6 +221,19 @@ #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) + +/* values for change page for custom elements */ +#define CH_PAGE_ANY_FILE (0xff) +#define CH_PAGE_ANY (0xffffffff) + /* values for change power for custom elements */ #define CP_NON_DESTRUCTIVE 0 #define CP_HALF_DESTRUCTIVE 1 @@ -1279,7 +1292,10 @@ struct PlayerInfo boolean connected; /* player connected (locally or via network) */ boolean active; /* player present and connected */ - int index_nr, client_nr, element_nr; + int index_nr; /* player number (0 to 3) */ + int index_bit; /* player number bit (1 << 0 to 1 << 3) */ + int element_nr; /* element (EL_PLAYER_1 to EL_PLAYER_4) */ + int client_nr; /* network client identifier */ byte action; /* action from local input device */ byte effective_action; /* action acknowledged from network server @@ -1506,8 +1522,9 @@ struct ElementChangeInfo boolean can_change; /* use or ignore this change info */ unsigned long events; /* change events */ - int sides; /* change sides */ + 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 */ -- 2.34.1