From 6ee3c137f499f7a288b95b9455efcafa1aa0e774 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Fri, 2 May 2003 21:07:21 +0200 Subject: [PATCH] rnd-20030502-2-src --- src/conftime.h | 2 +- src/editor.c | 58 ++++++++------ src/files.c | 13 +-- src/game.c | 210 ++++++++++++++++++++++++++++++++++++++++++------- src/main.h | 45 ++++++++++- 5 files changed, 263 insertions(+), 65 deletions(-) diff --git a/src/conftime.h b/src/conftime.h index 36600591..a1c7eb1e 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2003-05-02 17:40]" +#define COMPILE_DATE_STRING "[2003-05-02 20:55]" diff --git a/src/editor.c b/src/editor.c index 6a054d19..a726f913 100644 --- a/src/editor.c +++ b/src/editor.c @@ -566,8 +566,8 @@ static int random_placement_background_element = EL_SAND; static boolean random_placement_background_restricted = FALSE; static boolean stick_element_properties_window = FALSE; static boolean custom_element_properties[NUM_ELEMENT_PROPERTIES]; -static boolean custom_element_changes[42]; -static int custom_element_change_delay[2]; +static boolean custom_element_change_events[NUM_CHANGE_EVENTS]; +static struct CustomElementChangeInfo custom_element_change; static struct { @@ -656,16 +656,16 @@ static struct 0, 999, GADGET_ID_CHANGE_DELAY_FIX_DOWN, GADGET_ID_CHANGE_DELAY_FIX_UP, GADGET_ID_CHANGE_DELAY_FIX_TEXT, - &custom_element_change_delay[0], - NULL, "frames (fixed)" + &custom_element_change.delay_fixed, + NULL, "seconds (fixed)" }, { ED_COUNT_CHANGE_DELAY_XPOS, ED_COUNTER_YPOS2(6), 0, 999, GADGET_ID_CHANGE_DELAY_RND_DOWN, GADGET_ID_CHANGE_DELAY_RND_UP, GADGET_ID_CHANGE_DELAY_RND_TEXT, - &custom_element_change_delay[1], - NULL, "frames (random)" + &custom_element_change.delay_random, + NULL, "seconds (random)" } }; @@ -974,13 +974,13 @@ static struct { ED_SETTINGS_XPOS2, ED_COUNTER_YPOS2(5), GADGET_ID_CHANGE_DELAY_FIXED, - &custom_element_changes[0], + &custom_element_change_events[CE_DELAY_FIXED], "delay of", "element changes after fixed delay" }, { ED_SETTINGS_XPOS2, ED_COUNTER_YPOS2(6), GADGET_ID_CHANGE_DELAY_RANDOM, - &custom_element_changes[1], + &custom_element_change_events[CE_DELAY_RANDOM], "delay of", "element changes after random delay" } }; @@ -2911,16 +2911,28 @@ static void CopyCustomElementPropertiesToEditor(int element) { int i; + i = properties_element - EL_CUSTOM_START; + custom_element_change = level.custom_element[i].change; + for (i=0; i < NUM_ELEMENT_PROPERTIES; i++) custom_element_properties[i] = HAS_PROPERTY(element, i); + + for (i=0; i < NUM_CHANGE_EVENTS; i++) + custom_element_change_events[i] = HAS_CHANGE_EVENT(element, i); } static void CopyCustomElementPropertiesToGame(int element) { int i; + i = properties_element - EL_CUSTOM_START; + level.custom_element[i].change = custom_element_change; + for (i=0; i < NUM_ELEMENT_PROPERTIES; i++) SET_PROPERTY(element, i, custom_element_properties[i]); + + for (i=0; i < NUM_CHANGE_EVENTS; i++) + SET_CHANGE_EVENT(element, i, custom_element_change_events[i]); } void DrawLevelEd() @@ -3324,7 +3336,7 @@ static void DrawCustomChangedArea() int area_y = ypos / MINI_TILEY; int area_sx = SX + xpos; int area_sy = SY + ypos; - int element = properties_element - EL_CUSTOM_START; + int i = properties_element - EL_CUSTOM_START; if (!IS_CUSTOM_ELEMENT(properties_element)) { @@ -3334,7 +3346,7 @@ static void DrawCustomChangedArea() return; } - ElementContent[0][0][0] = level.custom_element_successor[element]; + ElementContent[0][0][0] = level.custom_element[i].change.successor; DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY); DrawMiniElement(area_x, area_y, ElementContent[0][0][0]); @@ -3903,14 +3915,14 @@ static void DrawPropertiesAdvanced() { char infotext[MAX_OUTPUT_LINESIZE + 1]; int max_infotext_len = getMaxInfoTextLength(); - int xoffset_above = 0; - int yoffset_above = -(MINI_TILEX + ED_GADGET_DISTANCE); int xoffset_right = getCounterGadgetWidth(); int yoffset_right = ED_BORDER_SIZE; int xoffset_right2 = ED_CHECKBUTTON_XSIZE + 2 * ED_GADGET_DISTANCE; int yoffset_right2 = ED_BORDER_SIZE; int i, x, y; + CopyCustomElementPropertiesToEditor(properties_element); + /* draw stickybutton gadget */ i = ED_CHECKBUTTON_ID_STICK_ELEMENT; x = checkbutton_info[i].x + xoffset_right2; @@ -3924,16 +3936,6 @@ static void DrawPropertiesAdvanced() /* draw counter gadgets */ for (i=ED_COUNTER_ID_CHANGE_FIRST; i<=ED_COUNTER_ID_CHANGE_LAST; i++) { - if (counterbutton_info[i].infotext_above) - { - x = counterbutton_info[i].x + xoffset_above; - y = counterbutton_info[i].y + yoffset_above; - - sprintf(infotext, "%s:", counterbutton_info[i].infotext_above); - infotext[max_infotext_len] = '\0'; - DrawTextF(x, y, FONT_TEXT_1, infotext); - } - if (counterbutton_info[i].infotext_right) { x = counterbutton_info[i].x + xoffset_right; @@ -4754,7 +4756,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) { int i = properties_element - EL_CUSTOM_START; - level.custom_element_successor[i] = new_element; + level.custom_element[i].change.successor = new_element; } else if (id == GADGET_ID_RANDOM_BACKGROUND) random_placement_background_element = new_element; @@ -4922,6 +4924,10 @@ static void HandleCounterButtons(struct GadgetInfo *gi) default: break; } + + if (counter_id >= ED_COUNTER_ID_CHANGE_FIRST && + counter_id <= ED_COUNTER_ID_CHANGE_LAST) + CopyCustomElementPropertiesToGame(properties_element); } static void HandleTextInputGadgets(struct GadgetInfo *gi) @@ -4965,8 +4971,10 @@ static void HandleCheckbuttons(struct GadgetInfo *gi) *checkbutton_info[type_id].value ^= TRUE; - if (type_id >= ED_CHECKBUTTON_ID_CUSTOM_FIRST && - type_id <= ED_CHECKBUTTON_ID_CUSTOM_LAST) + if ((type_id >= ED_CHECKBUTTON_ID_CUSTOM_FIRST && + type_id <= ED_CHECKBUTTON_ID_CUSTOM_LAST) || + (type_id >= ED_CHECKBUTTON_ID_CHANGE_FIRST && + type_id <= ED_CHECKBUTTON_ID_CHANGE_LAST)) CopyCustomElementPropertiesToGame(properties_element); } diff --git a/src/files.c b/src/files.c index 1321fe9c..c94e1a5c 100644 --- a/src/files.c +++ b/src/files.c @@ -97,7 +97,10 @@ static void setLevelInfoToDefaults() for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) { - level.custom_element_successor[i] = EL_EMPTY_SPACE; + level.custom_element[i].change.events = CE_BITMASK_DEFAULT; + level.custom_element[i].change.successor = EL_EMPTY_SPACE; + level.custom_element[i].change.delay_fixed = 0; + level.custom_element[i].change.delay_random = 0; /* start with no properties at all */ #if 1 @@ -372,7 +375,7 @@ static int LoadLevel_CUS2(FILE *file, int chunk_size, struct LevelInfo *level) int i = element - EL_CUSTOM_START; if (IS_CUSTOM_ELEMENT(element)) - level->custom_element_successor[i] = custom_element_successor; + level->custom_element[i].change.successor = custom_element_successor; else Error(ERR_WARN, "invalid custom element number %d", element); } @@ -762,12 +765,12 @@ static void SaveLevel_CUS2(FILE *file, struct LevelInfo *level, { int element = EL_CUSTOM_START + i; - if (level->custom_element_successor[i] != EL_EMPTY_SPACE) + if (level->custom_element[i].change.successor != EL_EMPTY_SPACE) { if (check < num_changed_custom_elements) { putFile16BitBE(file, element); - putFile16BitBE(file, level->custom_element_successor[i]); + putFile16BitBE(file, level->custom_element[i].change.successor); } check++; @@ -827,7 +830,7 @@ void SaveLevel(int level_nr) /* check for non-standard custom elements and calculate "CUS2" chunk size */ for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) - if (level.custom_element_successor[i] != EL_EMPTY_SPACE) + if (level.custom_element[i].change.successor != EL_EMPTY_SPACE) num_changed_custom_elements2++; putFileChunkBE(file, "RND1", CHUNK_SIZE_UNDEFINED); diff --git a/src/game.c b/src/game.c index 55658d80..38445772 100644 --- a/src/game.c +++ b/src/game.c @@ -154,38 +154,144 @@ struct ChangingElementInfo static struct ChangingElementInfo changing_element_list[] = { - { EL_NUT_BREAKING, EL_EMERALD, 6, NULL, NULL, NULL }, - { EL_PEARL_BREAKING, EL_EMPTY, 8, NULL, NULL, NULL }, - { EL_EXIT_OPENING, EL_EXIT_OPEN, 29, NULL, NULL, NULL }, - - { EL_SWITCHGATE_OPENING, EL_SWITCHGATE_OPEN, 29, NULL, NULL, NULL }, - { EL_SWITCHGATE_CLOSING, EL_SWITCHGATE_CLOSED, 29, NULL, NULL, NULL }, - - { EL_TIMEGATE_OPENING, EL_TIMEGATE_OPEN, 29, NULL, NULL, NULL }, - { EL_TIMEGATE_CLOSING, EL_TIMEGATE_CLOSED, 29, NULL, NULL, NULL }, - - { EL_ACID_SPLASH_LEFT, EL_EMPTY, 8, NULL, NULL, NULL }, - { EL_ACID_SPLASH_RIGHT, EL_EMPTY, 8, NULL, NULL, NULL }, - - { EL_SP_BUGGY_BASE, EL_SP_BUGGY_BASE_ACTIVATING, 0, - InitBuggyBase, NULL, NULL }, - { EL_SP_BUGGY_BASE_ACTIVATING,EL_SP_BUGGY_BASE_ACTIVE, 0, - InitBuggyBase, NULL, NULL }, - { EL_SP_BUGGY_BASE_ACTIVE, EL_SP_BUGGY_BASE, 0, - InitBuggyBase, WarnBuggyBase, NULL }, - - { EL_TRAP, EL_TRAP_ACTIVE, 0, - InitTrap, NULL, ActivateTrap }, - { EL_TRAP_ACTIVE, EL_TRAP, 31, - NULL, ChangeActiveTrap, NULL }, - - { EL_ROBOT_WHEEL_ACTIVE, EL_ROBOT_WHEEL, 0, - InitRobotWheel, RunRobotWheel, StopRobotWheel }, + { + EL_NUT_BREAKING, + EL_EMERALD, + 6, + NULL, + NULL, + NULL + }, + { + EL_PEARL_BREAKING, + EL_EMPTY, + 8, + NULL, + NULL, + NULL + }, + { + EL_EXIT_OPENING, + EL_EXIT_OPEN, + 29, + NULL, + NULL, + NULL + }, + { + EL_SWITCHGATE_OPENING, + EL_SWITCHGATE_OPEN, + 29, + NULL, + NULL, + NULL + }, + { + EL_SWITCHGATE_CLOSING, + EL_SWITCHGATE_CLOSED, + 29, + NULL, + NULL, + NULL + }, + { + EL_TIMEGATE_OPENING, + EL_TIMEGATE_OPEN, + 29, + NULL, + NULL, + NULL + }, + { + EL_TIMEGATE_CLOSING, + EL_TIMEGATE_CLOSED, + 29, + NULL, + NULL, + NULL + }, - { EL_TIMEGATE_SWITCH_ACTIVE, EL_TIMEGATE_SWITCH, 0, - InitTimegateWheel, RunTimegateWheel, NULL }, + { + EL_ACID_SPLASH_LEFT, + EL_EMPTY, + 8, + NULL, + NULL, + NULL + }, + { + EL_ACID_SPLASH_RIGHT, + EL_EMPTY, + 8, + NULL, + NULL, + NULL + }, + { + EL_SP_BUGGY_BASE, + EL_SP_BUGGY_BASE_ACTIVATING, + 0, + InitBuggyBase, + NULL, + NULL + }, + { + EL_SP_BUGGY_BASE_ACTIVATING, + EL_SP_BUGGY_BASE_ACTIVE, + 0, + InitBuggyBase, + NULL, + NULL + }, + { + EL_SP_BUGGY_BASE_ACTIVE, + EL_SP_BUGGY_BASE, + 0, + InitBuggyBase, + WarnBuggyBase, + NULL + }, + { + EL_TRAP, + EL_TRAP_ACTIVE, + 0, + InitTrap, + NULL, + ActivateTrap + }, + { + EL_TRAP_ACTIVE, + EL_TRAP, + 31, + NULL, + ChangeActiveTrap, + NULL + }, + { + EL_ROBOT_WHEEL_ACTIVE, + EL_ROBOT_WHEEL, + 0, + InitRobotWheel, + RunRobotWheel, + StopRobotWheel + }, + { + EL_TIMEGATE_SWITCH_ACTIVE, + EL_TIMEGATE_SWITCH, + 0, + InitTimegateWheel, + RunTimegateWheel, + NULL + }, - { EL_UNDEFINED, EL_UNDEFINED, -1, NULL } + { + EL_UNDEFINED, + EL_UNDEFINED, + -1, + NULL, + NULL, + NULL + } }; static struct ChangingElementInfo changing_element[MAX_NUM_ELEMENTS]; @@ -561,6 +667,7 @@ static void InitGameEngine() changing_element[i].post_change_function = NULL; } + /* add changing elements from pre-defined list */ i = 0; while (changing_element_list[i].base_element != EL_UNDEFINED) { @@ -576,6 +683,30 @@ static void InitGameEngine() i++; } + + /* add changing elements from custom element configuration */ + for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) + { + struct CustomElementChangeInfo *change = &level.custom_element[i].change; + int element = EL_CUSTOM_START + i; + + /* only add custom elements that change after fixed/random frame delay */ + if (!IS_CHANGEABLE(element) || + (!HAS_CHANGE_EVENT(element, CE_DELAY_FIXED) && + !HAS_CHANGE_EVENT(element, CE_DELAY_RANDOM))) + continue; + + changing_element[element].base_element = element; + changing_element[element].next_element = change->successor; + changing_element[i].change_delay = 0; + + if (HAS_CHANGE_EVENT(element, CE_DELAY_FIXED)) + changing_element[element].change_delay += + change->delay_fixed * FRAMES_PER_SECOND; + + if (HAS_CHANGE_EVENT(element, CE_DELAY_RANDOM)); + /* random frame delay added at runtime for each element individually */ + } } @@ -4422,10 +4553,22 @@ static void ChangeElement(int x, int y) { int element = Feld[x][y]; + if (IS_MOVING(x, y)) /* never change moving elements */ + return; + if (MovDelay[x][y] == 0) /* initialize element change */ { MovDelay[x][y] = changing_element[element].change_delay + 1; + if (IS_CUSTOM_ELEMENT(element) && + HAS_CHANGE_EVENT(element, CE_DELAY_RANDOM)) + { + int i = element - EL_CUSTOM_START; + int max_random_delay = level.custom_element[i].change.delay_random; + + MovDelay[x][y] += RND(max_random_delay * FRAMES_PER_SECOND); + } + ResetGfxAnimation(x, y); ResetRandomAnimationValue(x, y); @@ -4729,13 +4872,20 @@ 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 (IS_ANIMATED(graphic)) DrawLevelGraphicAnimationIfNeeded(x, y, graphic); +#if 1 + if (IS_AUTO_CHANGING(element)) + ChangeElement(x, y); +#endif + if (IS_BELT_ACTIVE(element)) PlaySoundLevelAction(x, y, ACTION_ACTIVE); diff --git a/src/main.h b/src/main.h index c92fe607..3f9f9177 100644 --- a/src/main.h +++ b/src/main.h @@ -141,12 +141,34 @@ #define EP_BITMASK_DEFAULT 0 #define PROPERTY_BIT(p) (1 << ((p) % 32)) -#define PROPERTY_VAR(e, p) (Properties[e][(p) / 32]) -#define HAS_PROPERTY(e, p) ((PROPERTY_VAR(e, p) & PROPERTY_BIT(p)) != 0) -#define SET_PROPERTY(e, p, v) ((v) ? \ +#define PROPERTY_VAR(e,p) (Properties[e][(p) / 32]) +#define HAS_PROPERTY(e,p) ((PROPERTY_VAR(e, p) & PROPERTY_BIT(p)) != 0) +#define SET_PROPERTY(e,p,v) ((v) ? \ (PROPERTY_VAR(e,p) |= PROPERTY_BIT(p)) : \ (PROPERTY_VAR(e,p) &= ~PROPERTY_BIT(p))) + +/* values for change events for custom elements */ +#define CE_DELAY_FIXED 0 +#define CE_DELAY_RANDOM 1 + +#define NUM_CHANGE_EVENTS 2 + +#define CE_BITMASK_DEFAULT 0 + +#define CUSTOM_ELEMENT_INFO(e) (level.custom_element[(e) - EL_CUSTOM_START]) + +#define CH_EVENT_BIT(c) (1 << (c)) +#define CH_EVENT_VAR(e) (CUSTOM_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 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) + + /* macros for configurable properties */ #define IS_DIGGABLE(e) HAS_PROPERTY(e, EP_DIGGABLE) #define IS_COLLECTIBLE(e) HAS_PROPERTY(e, EP_COLLECTIBLE) @@ -1033,6 +1055,21 @@ struct PlayerInfo int shield_deadly_time_left; }; +struct CustomElementChangeInfo +{ + unsigned long events; /* bitfield for change events */ + + short successor; /* new custom element after change */ + + int delay_fixed; /* added frame delay before changed (fixed) */ + int delay_random; /* added frame delay before changed (random) */ +}; + +struct CustomElementInfo +{ + struct CustomElementChangeInfo change; +}; + struct LevelInfo { int file_version; /* file format version the level is stored with */ @@ -1061,7 +1098,7 @@ struct LevelInfo boolean gravity; boolean em_slippery_gems; /* EM style "gems slip from wall" behaviour */ - short custom_element_successor[NUM_CUSTOM_ELEMENTS]; + struct CustomElementInfo custom_element[NUM_CUSTOM_ELEMENTS]; boolean no_level_file; }; -- 2.34.1