X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Feditor.c;h=52df4dfacefce6feeb3f311cf2cb39f4ac3f60ec;hb=84c888496c5bf6f9e649882d77400c47634e177a;hp=8d8d9c629d2e3aaeb72d231f45ed0ca00c02d171;hpb=41e90530481fced8d11cd1f55c78bc07d66e5120;p=rocksndiamonds.git diff --git a/src/editor.c b/src/editor.c index 8d8d9c62..52df4dfa 100644 --- a/src/editor.c +++ b/src/editor.c @@ -688,6 +688,7 @@ enum GADGET_ID_DF_LASER_GREEN, GADGET_ID_DF_LASER_BLUE, GADGET_ID_ROTATE_MM_BALL_CONTENT, + GADGET_ID_EXPLODE_MM_BALL, GADGET_ID_CUSTOM_INDESTRUCTIBLE, GADGET_ID_CUSTOM_CAN_EXPLODE, GADGET_ID_CUSTOM_EXPLODE_FIRE, @@ -1002,6 +1003,7 @@ enum ED_CHECKBUTTON_ID_DF_LASER_GREEN, ED_CHECKBUTTON_ID_DF_LASER_BLUE, ED_CHECKBUTTON_ID_ROTATE_MM_BALL_CONTENT, + ED_CHECKBUTTON_ID_EXPLODE_MM_BALL, ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC, ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1, ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE, @@ -3387,6 +3389,13 @@ static struct NULL, NULL, "randomly rotate created content", "randomly rotate newly created content" }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(6), + GADGET_ID_EXPLODE_MM_BALL, GADGET_ID_NONE, + &level.explode_mm_ball, + NULL, NULL, + "explode ball instead of melting", "use explosion to release ball content" + }, // ---------- element settings: configure 1 (custom elements) --------------- @@ -3964,6 +3973,7 @@ static boolean getDrawModeHiRes(void); static int getTabulatorBarWidth(void); static int getTabulatorBarHeight(void); static Pixel getTabulatorBarColor(void); +static int numHiresTiles(int); static int num_editor_gadgets = 0; // dynamically determined @@ -5733,9 +5743,18 @@ static void InitDynamicEditorElementList(int **elements, int *num_elements) // find all elements used in current level for (y = 0; y < lev_fieldy; y++) + { for (x = 0; x < lev_fieldx; x++) - if (Tile[x][y] < NUM_FILE_ELEMENTS) // should always be true + { + if (Tile[x][y] >= NUM_FILE_ELEMENTS) // should never happen + continue; + + if (IS_MM_WALL(Tile[x][y])) + element_found[map_mm_wall_element(Tile[x][y])] = TRUE; + else element_found[Tile[x][y]] = TRUE; + } + } *num_elements = 0; @@ -5755,14 +5774,18 @@ static void InitDynamicEditorElementList(int **elements, int *num_elements) *num_elements = 0; - // add all elements used in current level (non-custom/group elements) + // add all elements used in current level (non-custom/group/empty elements) for (i = 0; i < NUM_FILE_ELEMENTS; i++) - if (element_found[i] && !(IS_CUSTOM_ELEMENT(i) || IS_GROUP_ELEMENT(i))) + if (element_found[i] && !(IS_CUSTOM_ELEMENT(i) || + IS_GROUP_ELEMENT(i) || + IS_EMPTY_ELEMENT(i))) (*elements)[(*num_elements)++] = i; - // add all elements used in current level (custom/group elements) + // add all elements used in current level (custom/group/empty elements) for (i = 0; i < NUM_FILE_ELEMENTS; i++) - if (element_found[i] && (IS_CUSTOM_ELEMENT(i) || IS_GROUP_ELEMENT(i))) + if (element_found[i] && (IS_CUSTOM_ELEMENT(i) || + IS_GROUP_ELEMENT(i) || + IS_EMPTY_ELEMENT(i))) (*elements)[(*num_elements)++] = i; while (*num_elements % 4) // pad with empty elements, if needed @@ -9738,13 +9761,16 @@ static void DrawPropertiesInfo(void) { -1, NULL } }; char *filename = getElementDescriptionFilename(properties_element); - char *percentage_text = "In this level: "; + char *num_elements_text = "In this level: "; + char *num_similar_text = "Similar tiles: "; char *properties_text = "Standard properties: "; char *description_text = "Description:"; char *no_description_text = "No description available."; char *none_text = "None"; float percentage; - int num_elements_in_level; + int num_elements_in_level = 0; + int num_similar_in_level = 0; + int num_hires_tiles_in_level = 0; int num_standard_properties = 0; int font1_nr = FONT_TEXT_1; int font2_nr = FONT_TEXT_2; @@ -9753,7 +9779,8 @@ static void DrawPropertiesInfo(void) int font2_height = getFontHeight(font2_nr); int line1_height = font1_height + ED_GADGET_LINE_DISTANCE; int font2_yoffset = (font1_height - font2_height) / 2; - int percentage_text_len = strlen(percentage_text) * font1_width; + int num_elements_text_len = strlen(num_elements_text) * font1_width; + int num_similar_text_len = strlen(num_similar_text) * font1_width; int properties_text_len = strlen(properties_text) * font1_width; int xpos = ED_ELEMENT_SETTINGS_X(0); int ypos = ED_ELEMENT_SETTINGS_Y(0) + ED_GADGET_SMALL_DISTANCE; @@ -9772,22 +9799,66 @@ static void DrawPropertiesInfo(void) // ----- print number of elements / percentage of this element in level - num_elements_in_level = 0; - for (y = 0; y < lev_fieldy; y++) + for (y = 0; y < lev_fieldy; y++) + { for (x = 0; x < lev_fieldx; x++) + { if (Tile[x][y] == properties_element) + { num_elements_in_level++; + } + else if (IS_MM_WALL(Tile[x][y]) && + map_mm_wall_element(Tile[x][y]) == properties_element) + { + num_hires_tiles_in_level += numHiresTiles(Tile[x][y]); + } + } + } + percentage = num_elements_in_level * 100.0 / (lev_fieldx * lev_fieldy); - DrawTextS(xpos, ypos, font1_nr, percentage_text); + DrawTextS(xpos, ypos, font1_nr, num_elements_text); - if (num_elements_in_level > 0) - DrawTextF(xpos + percentage_text_len, ypos + font2_yoffset, font2_nr, + if (num_hires_tiles_in_level > 0) + DrawTextF(xpos + num_elements_text_len, ypos + font2_yoffset, font2_nr, + "%d wall tiles", num_hires_tiles_in_level); + else if (num_elements_in_level > 0) + DrawTextF(xpos + num_elements_text_len, ypos + font2_yoffset, font2_nr, "%d (%.2f %%)", num_elements_in_level, percentage); else - DrawTextF(xpos + percentage_text_len, ypos + font2_yoffset, font2_nr, + DrawTextF(xpos + num_elements_text_len, ypos + font2_yoffset, font2_nr, none_text); + // ----- print number of similar elements / percentage of them in level + + for (y = 0; y < lev_fieldy; y++) + { + for (x = 0; x < lev_fieldx; x++) + { + if (strEqual(element_info[Tile[x][y]].class_name, + element_info[properties_element].class_name)) + { + num_similar_in_level++; + } + } + } + + if (num_similar_in_level != num_elements_in_level) + { + ypos += 1 * MAX(font1_height, font2_height); + + percentage = num_similar_in_level * 100.0 / (lev_fieldx * lev_fieldy); + + DrawTextS(xpos, ypos, font1_nr, num_similar_text); + + if (num_similar_in_level > 0) + DrawTextF(xpos + num_similar_text_len, ypos + font2_yoffset, font2_nr, + "%d (%.2f %%)", num_similar_in_level, percentage); + else + DrawTextF(xpos + num_similar_text_len, ypos + font2_yoffset, font2_nr, + none_text); + } + ypos += 2 * MAX(font1_height, font2_height); // ----- print standard properties of this element @@ -10148,6 +10219,7 @@ static void DrawPropertiesConfig(void) MapCounterButtons(ED_COUNTER_ID_MM_BALL_CONTENT); MapSelectboxGadget(ED_SELECTBOX_ID_MM_BALL_CHOICE_MODE); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_ROTATE_MM_BALL_CONTENT); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_EXPLODE_MM_BALL); DrawMMBallContentArea(); } @@ -11126,7 +11198,7 @@ static void MergeAndCloseNeighbourElements(int x1, int y1, int *element1, SetElementSimple(x2, y2, *element2, change_level); } -static void SetElementIntelliDraw(int x, int y, int new_element, +static void SetElementIntelliDraw(int x, int y, int dx, int dy, int new_element, boolean change_level, int button) { struct XY *xy = xy_directions; @@ -11898,7 +11970,10 @@ static void SetElementIntelliDraw(int x, int y, int new_element, } } - SetElementSimple(x, y, new_element, change_level); + if (IS_MM_WALL_EDITOR(new_element)) + SetElementSimpleExt(x, y, dx, dy, new_element, change_level); + else + SetElementSimple(x, y, new_element, change_level); last_x = x; last_y = y; @@ -11912,7 +11987,7 @@ static void ResetIntelliDraw(void) for (y = 0; y < lev_fieldy; y++) IntelliDrawBuffer[x][y] = Tile[x][y]; - SetElementIntelliDraw(-1, -1, EL_UNDEFINED, FALSE, -1); + SetElementIntelliDraw(-1, -1, -1, -1, EL_UNDEFINED, FALSE, -1); } static boolean draw_mode_hires = FALSE; @@ -11927,6 +12002,23 @@ static boolean isHiresDrawElement(int element) return (IS_MM_WALL_EDITOR(element) || element == EL_EMPTY); } +static int numHiresTiles(int element) +{ + if (!IS_MM_WALL(element)) + return 1; + + int bits = MM_WALL_BITS(element); + int num_bits = 0; + + while (bits) + { + bits &= bits - 1; + num_bits++; + } + + return num_bits; +} + static void SetDrawModeHiRes(int element) { draw_mode_hires = @@ -11954,8 +12046,8 @@ static void SetElementExt(int x, int y, int dx, int dy, int element, { if (element < 0) SetElementSimple(x, y, Tile[x][y], change_level); - else if (GetKeyModState() & KMOD_Shift && !IS_MM_WALL_EDITOR(element)) - SetElementIntelliDraw(x, y, element, change_level, button); + else if (GetKeyModState() & KMOD_Shift) + SetElementIntelliDraw(x, y, dx, dy, element, change_level, button); else SetElementSimpleExt(x, y, dx, dy, element, change_level); } @@ -12996,6 +13088,10 @@ static void CopyLevelTemplateToUserLevelSet(char *levelset_subdir) static void HandleDrawingAreas(struct GadgetInfo *gi) { static boolean started_inside_drawing_area = FALSE; + static int last_sx = -1; + static int last_sy = -1; + static int last_sx2 = -1; + static int last_sy2 = -1; int id = gi->custom_id; int type_id = gi->custom_type_id; boolean button_press_event; @@ -13059,10 +13155,6 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (!button_press_event && !button_release_event) { - static int last_sx = -1; - static int last_sy = -1; - static int last_sx2 = -1; - static int last_sy2 = -1; int old_element = (IN_LEV_FIELD(lx, ly) ? Tile[lx][ly] : EL_UNDEFINED); boolean hires_drawing = (level.game_engine_type == GAME_ENGINE_TYPE_MM && isHiresTileElement(old_element) && @@ -13072,13 +13164,13 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if ((sx == last_sx && sy == last_sy && !hires_drawing) || (sx2 == last_sx2 && sy2 == last_sy2)) return; - - last_sx = sx; - last_sy = sy; - last_sx2 = sx2; - last_sy2 = sy2; } + last_sx = sx; + last_sy = sy; + last_sx2 = sx2; + last_sy2 = sy2; + if (button_press_event) started_inside_drawing_area = inside_drawing_area;