From 5986dd78078b5a7b77e8c8fcbbd2d6f332e039cd Mon Sep 17 00:00:00 2001 From: firigion Date: Mon, 1 Feb 2021 04:25:11 -0300 Subject: [PATCH 01/11] adde drain command and support to flood commands for -g flag --- world-edit.sc | 63 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/world-edit.sc b/world-edit.sc index 868982e..9128b01 100644 --- a/world-edit.sc +++ b/world-edit.sc @@ -60,6 +60,10 @@ base_commands_map = [ ['flood ', ['flood_fill', null], [1, 'help_cmd_flood', 'help_cmd_flood_tooltip', null]], ['flood f ', _(block,flags)->flood_fill(block,null,flags), false], ['flood f ', 'flood_fill', false], + ['drain', ['_drain', 25, null], false], + ['drain ', ['_drain', null], [1, 'help_cmd_drain', 'help_cmd_drain_tooltip', null]], + ['drain f ', _(flag)->_drain(25, flag), false], + ['drain f ', '_drain', false], ['brush clear', ['brush', 'clear', null], [-1, 'help_cmd_brush_clear', null, null]], ['brush list', ['brush', 'list', null], [-1, 'help_cmd_brush_list', null, null]], ['brush info', ['brush', 'info', null], [-1, 'help_cmd_brush_info', null, null]], @@ -842,6 +846,7 @@ global_lang_keys = global_default_lang = { 'action_stack' -> 'stack', 'action_expand' -> 'expand', 'action_paste' -> 'paste', + 'action_drain' -> 'drain', }; task(_()->write_file('langs/en_us','json',global_default_lang)); // Make a template for translators. Async cause why not. Maybe make an async section at the bottom? @@ -1098,7 +1103,7 @@ flood(pos, args, flags) -> ( _sq_distance(pos, start) <= radius*radius ); - _flood_generic(block, axis, start, flags); + _flood_generic(block, axis, start, _parse_flags(flags)); ); line(pos, args, flags) -> ( @@ -1625,13 +1630,13 @@ flood_fill(block, axis, flags) -> _flood_tester(pos, outer(min_pos), outer(max_pos)) -> ( all(pos, _ >= min_pos:_i) && all(pos, _ <= max_pos:_i) ); - _flood_generic(block, axis, start, flags); + _flood_generic(block, axis, start, _parse_flags(flags)); ); _flood_generic(block, axis, start, flags) -> ( - + print(flags); // Define function to request neighbours perpendiular to axis if( axis==null, flood_neighbours(block) -> map(neighbours(block), pos(_)), @@ -1641,12 +1646,25 @@ _flood_generic(block, axis, start, flags) -> ); interior_block = block(start); + + _is_interior(block, outer(interior_block)) -> block==interior_block; + // If flag -g is set, treat greenery as interior + if(flags~'g', + if( + interior_block == 'air', + print('is_air'); + _is_interior(block) -> (air(block) || has(global_air_greenery, str(block))), + interior_block == 'water', + _is_interior(block) -> (block=='water' || has(global_water_greenery, str(block))), + ) + ); + if(_flood_tester(start), set_block(start, block, null, flags, {}), return()); visited = {start->null}; queue = [start]; - while(length(queue)>0, 10000, + while(length(queue)>0, 100000, current_pos = queue:0; delete(queue, 0); @@ -1655,9 +1673,9 @@ _flood_generic(block, axis, start, flags) -> current_neighbour = _; // check neighbours, add the non visited ones to the visited set if(!has(visited, current_neighbour), - visited:current_neighbour = null; + visited += current_neighbour; // if the block is not too far and is interior, delete it and add to queue to check neighbours later - if( block(_)==interior_block && _flood_tester(_), + if( _is_interior(block(_)) && _flood_tester(_), queue:length(queue) = current_neighbour; set_block(current_neighbour, block, null, flags, {}) ); @@ -1668,6 +1686,39 @@ _flood_generic(block, axis, start, flags) -> add_to_history('action_flood', player()) ); +_drain(radius, flags) -> ( + player = player(); + + if( (start_bl = block(pos(player))) == 'lava' || start_bl == 'water', + + flags = _parse_flags(flags); + start = pos(start_bl); + + // check if inside selection, if there is a selection + if( length(global_selection) < 2, + no_selection = true, + // else, there is a selection + no_selection = false; + [pos1,pos2]=_get_current_selection(player); + min_pos = map(pos1, min(_, pos2:_i)); + max_pos = map(pos1, max(_, pos2:_i)); + // test if inside selection + _is_inside_selection(pos, outer(min_pos), outer(max_pos)) -> ( + all(pos, _ >= min_pos:_i) && all(pos, _ <= max_pos:_i) + ); + ); + + if(!no_selection &&_is_inside_selection(player~'pos'), + _flood_tester(pos)->_is_inside_selection(pos), + _flood_tester(pos, outer(start), outer(radius)) -> (_sq_distance(pos, start) <= radius*radius) + ); + _flood_generic('air', null, start, flags); + + add_to_history('action_drain', player) + ); +); + + rotate(centre, degrees, axis)->( player=player(); [pos1,pos2]=_get_current_selection(player); From e97cc71ea012abe59358b1f3b6fa6033b4f3ee60 Mon Sep 17 00:00:00 2001 From: firigion Date: Mon, 1 Feb 2021 12:42:25 -0300 Subject: [PATCH 02/11] Added support for liquid brushes. Fixed bugs related to selection --- world-edit.sc | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/world-edit.sc b/world-edit.sc index 9128b01..cc81ecf 100644 --- a/world-edit.sc +++ b/world-edit.sc @@ -327,7 +327,8 @@ global_clipboard = []; global_debug_rendering = false; global_reach = 4.5; - +global_default_trace_type = 'blocks'; +global_liquid_trace_type = 'liquids'; //Extra boilerplate @@ -458,7 +459,7 @@ selection_move(amount, direction) -> point2 = _get_marker_position(global_selection:'to'); p = player(); if (p == null && direction == null, _error(player, 'move_selection_no_player_error')); - translation_vector = if(direction == null, get_look_direction(p)*amount, pos_offset([0,0,0],direction, amount)); + translation_vector = if(direction == null, p~'look'*amount, pos_offset([0,0,0],direction, amount)); clear_markers(global_selection:'from', global_selection:'to'); point1 = point1 + translation_vector; point2 = point2 + translation_vector; @@ -492,17 +493,26 @@ __on_tick() -> if (p = player(), // put your catchall checks here global_highlighted_marker = null; - reach = if( (held = p~'holds':0)==global_wand, global_reach, has(global_brushes, held), global_brush_reach); + reach = if( + (held = p~'holds':0)==global_wand, global_reach, + has(global_brushes, held), brush=true; global_brush_reach + ); + if(brush && length(global_selection)<2, clear_selection()); new_cursor = if ( reach && p~'gamemode'!='spectator', + // support for tracing liquids with brushes + global_trace_type = if(has(global_liquid_brush, held), global_liquid_trace_type, global_default_trace_type); + // get traced block if (marker = _trace_marker(p, global_reach), global_highlighted_marker = marker; _get_marker_position(marker) , _get_player_look_at_block(p, reach) ) ); + // delete old marker if new one isn't the same if (global_cursor && new_cursor != global_cursor, draw_shape('box', 0, 'from', global_cursor, 'to', global_cursor+1, 'fill', 0xffffff22); ); + // render new marker or refresh old one if (new_cursor, draw_shape('box', 50, 'from', new_cursor, 'to', new_cursor+1, 'fill', 0xffffff22); ); @@ -510,7 +520,6 @@ __on_tick() -> ) ); - __on_player_swings_hand(player, hand) -> ( if(player~'holds':0==global_wand, @@ -622,7 +631,7 @@ _render_selection_tick() -> _get_player_look_at_block(player, range) -> ( - block = query(player, 'trace', range, 'blocks'); + block = query(player, 'trace', range, global_trace_type); if (block, pos(block) , @@ -669,7 +678,7 @@ _set_or_give_wand(wand) -> ( ) ); -global_flags = ['w','a','e','h','u','b','p','d','s','g']; +global_flags = ['w','a','e','h','u','b','p','d','s','g','l']; //FLAGS: //w waterlog block if previous block was water(logged) too @@ -682,7 +691,7 @@ global_flags = ['w','a','e','h','u','b','p','d','s','g']; //d "dry" out the pasted structure (remove water and waterlogged) //s keep block states of replaced block, if new block matches //g when replacing air or water, some greenery gets repalced too - +//l when used in a brush, the brush will trace for liquids as well as blocks _parse_flags(flags) ->( if(!flags, return({})); @@ -918,6 +927,7 @@ _error(player, key, ... replace)-> // Brush global_brushes = {}; +global_liquid_brush = {}; global_brush_reach = 100; brush(action, flags, ...args) -> ( @@ -928,7 +938,8 @@ brush(action, flags, ...args) -> ( if( action=='clear', if(has(global_brushes, held_item), - delete(global_brushes, held_item), + delete(global_brushes, held_item); + delete(global_liquid_brush, held_item), _error(player, 'no_brush_error', held_item) ), action=='list', //TODO imprvove list with interactiveness @@ -957,7 +968,8 @@ brush(action, flags, ...args) -> ( ); global_brushes:held_item = [action, args, flags]; - if(action=='feature', print(player, format('d Beware, placing features is very experimental and doesn\'t have support for the undo function'))) + if(action=='feature', print(player, format('d Beware, placing features is very experimental and doesn\'t have support for the undo function'))); + if(action=='drain' || _parse_flags(flags)~'l', global_liquid_brush+=held_item) // to change trace method ) ); @@ -1636,7 +1648,6 @@ flood_fill(block, axis, flags) -> _flood_generic(block, axis, start, flags) -> ( - print(flags); // Define function to request neighbours perpendiular to axis if( axis==null, flood_neighbours(block) -> map(neighbours(block), pos(_)), From 3a5c064c97fadbd3042777e902ca1dc31c5e2d9a Mon Sep 17 00:00:00 2001 From: firigion Date: Mon, 1 Feb 2021 13:19:21 -0300 Subject: [PATCH 03/11] added drain brush --- world-edit.sc | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/world-edit.sc b/world-edit.sc index cc81ecf..60eff3e 100644 --- a/world-edit.sc +++ b/world-edit.sc @@ -152,6 +152,10 @@ base_commands_map = [ ['brush prism_star f ', _(block, outer_radius, inner_radius, height, n_points, axis, rotation, replacement, flags) -> brush('prism_star', flags, block, outer_radius, inner_radius, height, n_points, axis, rotation, replacement), false], ['brush feature ', _(feature) -> brush('feature', null, feature), [-1, 'help_cmd_brush_feature', 'help_cmd_brush_generic', null]], + ['brush drain', _()->brush('drain', null, 30), false], + ['brush drain ', _(radius)->brush('drain', null, radius), [0, 'help_cmd_brush_drain', 'help_cmd_brush_generic', null]], + ['brush drain f ', _(flag)->brush('drain', flag, 30), false], + ['brush drain f ', _(radius, flag)->brush('drain', flag, radius), [0, 'help_cmd_brush_drain', 'help_cmd_brush_generic', null]], ['shape cube ', _(block, size_int) -> cube(player()~'pos', [block, size_int, null], null), false], ['shape cube f ', _(block, size_int, flags) -> cube(player()~'pos', [block, size_int, null], flags), false], @@ -1292,6 +1296,11 @@ feature(pos, args, flags) -> ( plop(pos, what) ); +drain(pos, args, flags) -> ( + [radius] = args; + _drain_generic(pos, radius, flags) +); + //Command processing functions global_water_greenery = {'seagrass', 'tall_seagrass', 'kelp_plant'}; @@ -1697,13 +1706,14 @@ _flood_generic(block, axis, start, flags) -> add_to_history('action_flood', player()) ); -_drain(radius, flags) -> ( - player = player(); +_drain(radius, flags) -> _drain_generic(player()~'pos', radius, flags); - if( (start_bl = block(pos(player))) == 'lava' || start_bl == 'water', +_drain_generic(pos, radius, flags) -> ( + player = player(); + if( (start_bl = block(pos)) == 'lava' || start_bl == 'water', flags = _parse_flags(flags); - start = pos(start_bl); + start = pos; // check if inside selection, if there is a selection if( length(global_selection) < 2, @@ -1719,9 +1729,9 @@ _drain(radius, flags) -> ( ); ); - if(!no_selection &&_is_inside_selection(player~'pos'), + if(!no_selection && _is_inside_selection(player~'pos'), _flood_tester(pos)->_is_inside_selection(pos), - _flood_tester(pos, outer(start), outer(radius)) -> (_sq_distance(pos, start) <= radius*radius) + _flood_tester(pos, outer(start), outer(radius)) -> _sq_distance(pos, start) <= radius*radius ); _flood_generic('air', null, start, flags); From 08fb231c186656aa175ccb6e406c99edb3a7d61c Mon Sep 17 00:00:00 2001 From: firigion Date: Mon, 1 Feb 2021 23:58:07 -0300 Subject: [PATCH 04/11] Fixed a bug with some situations not working --- world-edit.sc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/world-edit.sc b/world-edit.sc index 60eff3e..e33f73a 100644 --- a/world-edit.sc +++ b/world-edit.sc @@ -60,9 +60,9 @@ base_commands_map = [ ['flood ', ['flood_fill', null], [1, 'help_cmd_flood', 'help_cmd_flood_tooltip', null]], ['flood f ', _(block,flags)->flood_fill(block,null,flags), false], ['flood f ', 'flood_fill', false], - ['drain', ['_drain', 25, null], false], + ['drain', ['_drain', null, null], false], ['drain ', ['_drain', null], [1, 'help_cmd_drain', 'help_cmd_drain_tooltip', null]], - ['drain f ', _(flag)->_drain(25, flag), false], + ['drain f ', _(flag)->_drain(null, flag), false], ['drain f ', '_drain', false], ['brush clear', ['brush', 'clear', null], [-1, 'help_cmd_brush_clear', null, null]], ['brush list', ['brush', 'list', null], [-1, 'help_cmd_brush_list', null, null]], @@ -1729,8 +1729,9 @@ _drain_generic(pos, radius, flags) -> ( ); ); - if(!no_selection && _is_inside_selection(player~'pos'), + if( !no_selection && radius==null && _is_inside_selection(pos), _flood_tester(pos)->_is_inside_selection(pos), + if(radius==null, radius=25); _flood_tester(pos, outer(start), outer(radius)) -> _sq_distance(pos, start) <= radius*radius ); _flood_generic('air', null, start, flags); From 3ed9618c19ed9066ee9709d08ad18ebc77ee62bb Mon Sep 17 00:00:00 2001 From: Firigion <64820010+Firigion@users.noreply.github.com> Date: Fri, 5 Feb 2021 12:32:13 -0300 Subject: [PATCH 05/11] Added help for drain and missing help strings --- world-edit.sc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/world-edit.sc b/world-edit.sc index e33f73a..1cb3be4 100644 --- a/world-edit.sc +++ b/world-edit.sc @@ -42,9 +42,9 @@ base_commands_map = [ ['move ', ['move',null], [-1, 'help_cmd_move', null, null]], ['move f ', 'move', false], //TODO flags help ['copy clear_clipboard',_()->(global_clipboard=[];_print(player(),'clear_clipboard',player())),[-1,'help_cmd_clear_clipboard',null,null]], - ['copy',['_copy',null, false],[-1,'help_cmd_copy',null,null]], + ['copy',['_copy',null, false],false], ['copy force',['_copy',null, true],false], - ['copy ',['_copy', false],false], + ['copy ',['_copy', false],[-1,'help_cmd_copy','help_cmd_copy_tooldtip',null]], ['copy force',['_copy', true],false], ['paste',['paste', null, null],[-1,'help_cmd_paste',null,null]], ['paste f ',_(flags)->paste(null, flags),false],//todo flags help @@ -778,6 +778,14 @@ global_lang_keys = global_default_lang = { 'help_cmd_expand' -> 'l Expands sel [magn] from pos', //This is not understandable 'help_cmd_expand_tooltip' -> 'g Expands the selection [magnitude] from [pos]', 'help_cmd_move' -> 'l Moves selection to ', + 'help_cmd_clear_clipboard' -> 'l Clears current clipboard', + 'help_cmd_copy' -> 'l Copy current selection to clipboard', + 'help_cmd_copy_tooldtip' -> 'g Uses [pos] or player position as origin for the copied structure', + 'help_cmd_paste' -> 'l Paste clipboard', + 'help_cmd_drain' -> 'l Drains liquid you are standing on', + 'help_cmd_drain_tooltip' -> 'g Acts in a radius or withing the selection', + 'help_cmd_flood' -> 'l Perferoms a 3D flood fill out of [block]', + 'help_cmd_flood_tooltip' -> 'g Use [axis] to make a flat fill', 'help_cmd_brush_clear' -> 'l Unregisters current item as brush', 'help_cmd_brush_list' -> 'l Lists all currently regiestered brushes and their actions', 'help_cmd_brush_info' -> 'l Gives detailed info of currently held brush', @@ -859,7 +867,7 @@ global_lang_keys = global_default_lang = { 'action_stack' -> 'stack', 'action_expand' -> 'expand', 'action_paste' -> 'paste', - 'action_drain' -> 'drain', + 'action_drain' -> 'drain', }; task(_()->write_file('langs/en_us','json',global_default_lang)); // Make a template for translators. Async cause why not. Maybe make an async section at the bottom? From ef3dac115c3e6ccb27c6400b76ef7cceadea85d0 Mon Sep 17 00:00:00 2001 From: Firigion <64820010+Firigion@users.noreply.github.com> Date: Fri, 5 Feb 2021 12:36:27 -0300 Subject: [PATCH 06/11] Updated docu with drain and -l flag --- docs/Documentation.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/Documentation.md b/docs/Documentation.md index f68cb54..c268a9c 100644 --- a/docs/Documentation.md +++ b/docs/Documentation.md @@ -64,6 +64,7 @@ Left clicking again will reselect the whole box. - `/world-edit paste [pos]` -> Pastes selection relative to player position or to `[pos]`, if given. Be careful incase you didnt' choose a wise spot making the selection. - `/world-edit flood ` -> Performs a flood fill (fill connex volume) within the selection and starting at the player's position. Can both "fill" used to be air or replace some other block. - `/world-edit flood [axis]` -> Flood fill will happen only perpendicular to iven axis. Setting axis to `y`, for isntance, will fill the horizontal plane. + - `/world-edit drain [radius]` -> Drains the liquid the player is standing on. By default, it does so on a given radius, ut you can set that with the optional parameter. If you don't specify a radius and are standing in a seleciton, it will drain within the selection only. It supports the `-g` flag, try it! - `/world-edit walls [sides] [replacement]` -> Creates walls on the sides specified around the selection, defalts to ony vertical walls (`xz`). - `/world-edit outline [replacement]` -> Outlines the selection with ``. - `/world-edit shape ...` -> Generates a shape centered arround the palyer. See brushes for all options and parameters. @@ -83,6 +84,7 @@ The available actions for brushes are: - `prism_star [axis] [rotation] [replacement]` -> generates a star whouse points touch a circle of radius `outer_radius` with `vertices` ammount of points. Said star is the base for a prism of height `height` along `axis`. Optionally, it can be rotated from it's base orientation. - `line [length] [replacement]` -> creates a line out of `block` between the player and the clicked block, replacing only blocks that match `replacement` (block or tag), if given. If `length` is given, the length of the line is fixed and it only uses the clicked block to get the direction of the line. - `flood [axis]` -> creates a flood fill starting in the target block and modifying all the connex blocks to become `block`, always staying within `radius` blocks of the starting point. The flood happens in the plane perpendicular to `axis`, if given. +- `drain ` -> Drains the liquids connected to the liquid block you click, up to `` blocks away. - `paste` -> pastes the current clipboard, using the targeted block as origin. - `feature ` -> places a feature (decoration) in the targeted location. Can fail, if natural feature would fail. DOES NOT SUPPORT `undo` functionality. @@ -107,3 +109,4 @@ Available flags: - `-s` -> Preserves block states when seting blocks - `-g` -> When replacing air or water, greenery corresponding to each medium will be replaced too - `-h` -> When creating a shape, makes it hollow + - `-l` -> When used to register a brush, the brush will targer liquids as well as blocks, instead of going right through them to the block behind. From 7f4e1a150b074ec618e23cfd4ec9b1a210329817 Mon Sep 17 00:00:00 2001 From: firigion Date: Tue, 9 Feb 2021 17:22:34 -0300 Subject: [PATCH 07/11] Added angel block --- docs/Documentation.md | 1 + world-edit.sc | 61 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/docs/Documentation.md b/docs/Documentation.md index c268a9c..f5e554f 100644 --- a/docs/Documentation.md +++ b/docs/Documentation.md @@ -68,6 +68,7 @@ Left clicking again will reselect the whole box. - `/world-edit walls [sides] [replacement]` -> Creates walls on the sides specified around the selection, defalts to ony vertical walls (`xz`). - `/world-edit outline [replacement]` -> Outlines the selection with ``. - `/world-edit shape ...` -> Generates a shape centered arround the palyer. See brushes for all options and parameters. + - `/world-edit angel [new|clear]` -> Angel block: click in mid air to place a (stone) block you can the build off. Without arguments, it gives the player the item registered as angel block. With `new`, it will register the currently held item as angel block item. With `clear` clears the current angel block item; you will have to register a new one to use it. #### Brushes diff --git a/world-edit.sc b/world-edit.sc index 1cb3be4..4e7f1ca 100644 --- a/world-edit.sc +++ b/world-edit.sc @@ -31,6 +31,9 @@ base_commands_map = [ ['redo all', ['redo', 0], [-1, 'help_cmd_redo_all', null, null]], ['wand', ['_set_or_give_wand',null], [-1, 'help_cmd_wand', null, null]], ['wand ', '_set_or_give_wand', [-1, 'help_cmd_wand_2', null, null]], + ['angel', '_give_angel_block_item', [-1, 'help_cmd_angel_give', null, null]], + ['angel new', '_set_angel_block_item', [-1, 'help_cmd_angel_new', null, null]], + ['angel clear', '_clear_angel_block_item', [-1, 'help_cmd_angel_clear', null, null]], ['rotate ', 'rotate', [-1, 'help_cmd_rotate', 'help_cmd_rotate_tooltip', null]],//will replace old stuff if need be ['stack', ['stack',1,null,null], false], ['stack ', ['stack',null,null], false], @@ -344,6 +347,7 @@ global_cursor = null; global_highlighted_marker = null; global_selection = {}; // holds ids of two official corners of the selection global_markers = {}; +global_angel_block = null; _help(page) -> ( @@ -498,7 +502,8 @@ __on_tick() -> // put your catchall checks here global_highlighted_marker = null; reach = if( - (held = p~'holds':0)==global_wand, global_reach, + (held = p~'holds':0)==global_wand, global_reach, + held==global_angel_block, brush=true; global_reach, // brush=true is used so that the selection doesn't linger, need to make this better has(global_brushes, held), brush=true; global_brush_reach ); if(brush && length(global_selection)<2, clear_selection()); @@ -561,7 +566,11 @@ __on_player_uses_item(player, item_tuple, hand) -> ), has(global_brushes, held), // TODO: make it so that if brush is a block, placing is not processed pos = _get_player_look_at_block(player, global_brush_reach); - _brush_action(pos, held) + _brush_action(pos, held), + + held==global_angel_block, + pos = _get_player_look_at_block(player, global_reach); + _place_angel_block(pos) ) ); @@ -659,7 +668,10 @@ _get_current_selection(player)-> _set_or_give_wand(wand) -> ( p = player(); if(wand,//checking if player specified a wand to be added - if((['tools', 'combat']~item_category(wand:0)) != null, + if( + (['tools', 'combat']~item_category(wand:0)) != null || + wand==global_angel_block || + has(global_brushes, wand), global_wand = wand; _print(p, 'new_wand', wand:0); return(), @@ -802,6 +814,9 @@ global_lang_keys = global_default_lang = { 'help_cmd_brush_flood' -> 'l Register brush to perfrm flood fill out of [block] starting on right clicked block', 'help_cmd_brush_paste' -> 'l Register brush to paste current clipboard with origin on targeted block', 'help_cmd_brush_feature' -> 'l Register brush to plop feature', + 'help_cmd_angel_give' -> 'l Gives player the current angel block item', + 'help_cmd_angel_clear' -> 'l Clears item currently registered as angel block', + 'help_cmd_angel_new' -> 'l Registers held item as angel block item', 'filled' -> 'gi Filled %d blocks', // blocks number 'no_undo_history' -> 'w No undo history to show for player %s', // player @@ -831,7 +846,7 @@ global_lang_keys = global_default_lang = { 'move_selection_no_player_error' -> 'r To move selection in the direction of the player, you need to have a player', 'no_selection_error' -> 'r Missing selection for operation for player %s', //player 'new_wand' -> 'wi %s is now the app\'s wand, use it with care.', //wand item - 'invalid_wand' -> 'r Wand has to be a tool or weapon', + 'invalid_wand' -> 'r Wand has to be a tool or weapon that is not already a brush or angel block', 'new_brush' -> 'wi %s is now a brush with action %s', 'brush_info' -> 'w %s has action %s bound to it with parameters %s and flags %s', @@ -841,6 +856,7 @@ global_lang_keys = global_default_lang = { 'brush_extra_info' -> 'ig For detailed info on a brush use /world-edit brush info', 'brush_new_reach' -> 'w Brush reach was set to %d blocks', 'brush_reach' -> 'w Brush reach is currently %d blocks', + 'bad_brush_error' -> 'r Wand or angel block items can\'t be brushes', 'structure_list' -> 'w List of structures:', 'saved_structure' -> 'w Saved structure as %s.nbt', //structure name @@ -849,6 +865,13 @@ global_lang_keys = global_default_lang = { 'structure_delete_success' -> 'gi Successfully deleted %s.nbt', //structure name 'structure_delete_fail' -> 'ri Failed to delete %s.nbt, no such file exists', //structure name 'structure_load_fail' -> 'ri Failed to load %s.nbt, no such file exists', //structure name + + 'angel_block_new' -> 'w Clicking with %s will now palce an angel block', //new angel block item + 'angel_block_given' -> 'w Gave yourself angel block item: %s', + 'angel_block_clear' -> 'w Unregistered angel block item', + 'angel_block_none_error' -> 'r There\'s no angel block defined! Use \'angel new\' to register one', + 'angel_block_bad_item' -> 'r Angel block can\'t be something that is already assigned to another action', + //Block-setting actions 'action_cube'-> 'cube', 'action_cuboid' -> 'cuboid', @@ -868,6 +891,7 @@ global_lang_keys = global_default_lang = { 'action_expand' -> 'expand', 'action_paste' -> 'paste', 'action_drain' -> 'drain', + 'action_angel' -> 'angel_block', }; task(_()->write_file('langs/en_us','json',global_default_lang)); // Make a template for translators. Async cause why not. Maybe make an async section at the bottom? @@ -945,7 +969,7 @@ global_brush_reach = 100; brush(action, flags, ...args) -> ( player = player(); held_item = player~'holds':0; - if(held_item==global_wand, _error(player, 'bad_wand_brush_error')); + if(held_item==global_wand || held_item==global_angel_block, _error(player, 'bad_brush_error')); if( action=='clear', @@ -1393,6 +1417,29 @@ print_history()->( ) ); +_give_angel_block_item() -> ( + if(global_angel_block, + run(str('/give %s %s', player()~'command_name', global_angel_block)); + _print(player(), 'angel_block_given', global_angel_block), + _error(player(), 'angel_block_none_error') + ); +); +_set_angel_block_item() -> ( + if( (item = player()~'holds':0) == global_wand || has(global_brushes, item), + _error(player(), 'angel_block_bad_item'), + global_angel_block = item; + _print(player(), 'angel_block_new', global_angel_block) + ); +); +_clear_angel_block_item() -> ( + p = player(); + if(global_angel_block, + global_angel_block=null; + _print(p, 'angel_block_clear'), + _error(p, 'angel_block_none_error') + ) +); + //Command functions undo(moves)->( @@ -1645,6 +1692,10 @@ set_in_selection(block,replacement,flags)-> add_to_history('action_set', player) ); +_place_angel_block(pos) -> ( + if(air(pos), set_block(pos, 'stone', null, null, {})); + add_to_history('action_angel', player()) +); flood_fill(block, axis, flags) -> ( From c48214ab841c8598e919abf85be73cccfe3c3b83 Mon Sep 17 00:00:00 2001 From: firigion Date: Tue, 9 Feb 2021 21:21:49 -0300 Subject: [PATCH 08/11] Added framework for items with actions and updated contributing.md --- CONTRIBUTING.md | 65 ++++++++++++++++++++++++++++++++--------- world-edit.sc | 77 ++++++++++++++++++++++++++++++++----------------- 2 files changed, 102 insertions(+), 40 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eb9d263..a1bbad3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -79,10 +79,11 @@ existing code, so you know what to do right off the bat, but here is the tl;dr, e copy/move entities as well b copy/move biomes as well (handled by set_block) a don't paste air - h create hollow shapes + h create hollow shapes d "dry" out the pasted structure (remove water and waterlogged) s keep block states of replaced block, if new block matches g when replacing air or water, some greenery gets repalced too + l when registering a brush with this flag, the brush will trace for liquids as well as blocks ``` Biomes are handled by the `set_block` function, but you need to input the previous biome as a map in the `extra` argument: `{'biome' -> biome}`, where the variable `biome` is the biome at the position you copied from. No need to @@ -122,18 +123,18 @@ add your commands into the `base_command_map` instead with the following format: - `[command_for_carpet, interpretation_for_carpet, false] (will hide it from help menu)` - `[command_for_carpet, interpretation_for_carpet, [optional_arguments_since, description, description_tooltip, description_action]]` -Explained in words: In the list, you add the command for carpet ("syntax") (eg `'fill '`) as the first element. -The second element is the "interpretation" for Carpet (what will that do, basically the other side of a regular commands -map), and then the third item is either `false` (to prevent it from appearing in help menu, for example, `help` can be -hidden since `help [page]` is basically the same) or another list with the info for the help menu, which you can find below. - -- `command_for_carpet`: As mentioned, it is the command "syntax" that will be passed to Carpet, the equivalent to the - first side of a regular commands map -- `interpretation_for_carpet`: As mentioned, it is how Carpet will process that command, the equivalent to the other side - of a regular commands map -- `optional_arguments_since`: The position of the first argument to make visibly optional (`` to `[arg]`). Can be - used to merge multiple commands in help menu (e.g. `help` and `help ` into `help [page]`). If the command shouldn't - have any optional arguments, use `-1` +In words: the first two arguments are the usual key and value arguments in the `__config():'commands'` map when defining custom commands +with scarpet the regular way. For example, they can be `'fill '` and `'fill_with_blocks'`, where the latter is a user-defined +function. The third element in the list is what defines the representation of the command in the help menu. Use `false` to hide the command +from the help menu (not every variation of a command needs it's individual entry), or see below for more info. + +- `command_for_carpet`: it's the command "syntax" that will be passed to Carpet, the equivalent to the + key in regular commands map +- `interpretation_for_carpet`: it's how Carpet will process that command, the equivalent to value argument of a regular commands map +- `optional_arguments_since`: the index of the first optional argument in the command out of all arguments given. optional arguemtns will + be printed as `[arg]`, and mandaroty ones as `` For isntance, setting it to `0` will make all arguments optional, while setting it to + `2` means the first two arguments are mandatory. Set it to `-1` if all arguments are mandatory. This can be used to merge multiple commands + into one help entry (for isntance, `help [page]` represents both the `help` and `help ` commands). - `description`: The description of the command in the help menu. Must be a translation string (see [Messages](#messages)) or a lambda (if you need arguments in the translation, `_()->_translate('string', ...args)`). (it can technically be `null`, but the idea is to add a description) @@ -141,13 +142,49 @@ hidden since `help [page]` is basically the same) or another list with the info it must be a translation string or a lambda (if you need arguments in the translation) - `description_action` An optional action to run when the player clicks the description. Can be `null`. If present, it must start with either `!` (to specify it will _run_ the action) or `?` (to specify it will _suggest_ the action). The command - is automatically prefixed with `/worldedit ` (and a space) + is automatically prefixed with `/world-edit ` (and a space) The command suggestion will be derived from `command_for_carpet`: everything before the first `<`. You should try to fit each entry in a single line (when viewed in the help menu) for proper pagination (until something is done). +#### Items with new functionality + +Some items have built-in functionality, like the wand, but the user has the ability to add more items with actions associated +with them (like brushes and angel block, for instance). If you want to add a new item functionality (say, building wand, for +example), then you need to take care of a few things, to avoid one item having many actions associated with it: + * When registering an item for a new action, call `new_action_item(item, action)`. This will check if the item is already + registered for another action and call `_error()` if it is. Remember, that `exit`s, so there no need for an extra, that function + does the check for you. + * When unregistering an item (not replacing it with a new one, like the wand does, actualy deleting it), call + `remove_action_item(item, action)`, which will check that the requested item indeed has that action registered to it. It also + `exit`s if it fails. For isntance, `brush` uses it like this: + ```C++ + if( + action=='clear', + remove_action_item(held_item, 'brush'); // delete old item from global_items_with_actions + delete(global_brushes, held_item); // deregister item as brush + ... + ``` + * For these two functions to work properly, you any new action you add needs a few things: + 1. add your action's name to the `global_lang_keys` so it can be translated + 2. add your action's code name to `global_item_action_translation_key` so it can be requested from `global_lang_keys` (for example, + the angel block's code name is `'angel'`, with a translation key `'action_item_angel'`, which gives the text `'angel block item'`) + 3. if your new action has a default tool or item (like the wand does), add it to `global_items_with_actions` along with it's action + * If registering a new item to your action just replaces the previous one, rather than adding a brand new one (think wand vs brush: one + replaces the old wand with a new one, while the other adds a new brush, leaving the old one suntouched), take good care to manually + delete the old item from `global_items_with_actions` just before adding the new one. Angel block for example does it like this: + ```C++ + _set_angel_block_item() -> ( + new_action_item(item = player()~'holds':0, 'angel'); // add new item + delete(global_items_with_actions, global_angel_block); // delete old one + global_angel_block = item; // register new item as angel block + ... + ``` + This is extremely important so that old deregistered items can be reused for new actions by the player. + + #### Other functions If you're doing something that changes the player's stored data, please ensure that: diff --git a/world-edit.sc b/world-edit.sc index 4e7f1ca..ec4c541 100644 --- a/world-edit.sc +++ b/world-edit.sc @@ -348,6 +348,7 @@ global_highlighted_marker = null; global_selection = {}; // holds ids of two official corners of the selection global_markers = {}; global_angel_block = null; +global_items_with_actions = {global_wand -> 'wand'}; _help(page) -> ( @@ -668,25 +669,27 @@ _get_current_selection(player)-> _set_or_give_wand(wand) -> ( p = player(); if(wand,//checking if player specified a wand to be added - if( - (['tools', 'combat']~item_category(wand:0)) != null || - wand==global_angel_block || - has(global_brushes, wand), + wand = wand:0; //because it comes as a [item, count, nbt] tuple + if( (['tools', 'combat']~item_category(wand)) != null, + new_action_item(wand, 'wand'); + delete(global_items_with_actions, global_wand); global_wand = wand; - _print(p, 'new_wand', wand:0); + _print(p, 'new_wand', wand); return(), //else, can't set as wand _error(p, 'invalid_wand') ) );//else, if just ran '/world-edit wand' with no extra args //give player wand if hand is empty - if(held_item_tuple = p~'holds' == null, + if( (held_item_tuple = p~'holds') == null, slot = inventory_set(p, p~'selected_slot', 1, global_wand); return() ); //else, set current held item as wand, if valid held_item = held_item_tuple:0; if( (['tools', 'combat']~item_category(held_item)) != null, + new_action_item(held_item, 'wand'); + delete(global_items_with_actions, global_wand); global_wand = held_item; _print(p, 'new_wand', held_item), //else, can't set as wand @@ -846,7 +849,7 @@ global_lang_keys = global_default_lang = { 'move_selection_no_player_error' -> 'r To move selection in the direction of the player, you need to have a player', 'no_selection_error' -> 'r Missing selection for operation for player %s', //player 'new_wand' -> 'wi %s is now the app\'s wand, use it with care.', //wand item - 'invalid_wand' -> 'r Wand has to be a tool or weapon that is not already a brush or angel block', + 'invalid_wand' -> 'r Wand has to be a tool or weapon', 'new_brush' -> 'wi %s is now a brush with action %s', 'brush_info' -> 'w %s has action %s bound to it with parameters %s and flags %s', @@ -866,12 +869,18 @@ global_lang_keys = global_default_lang = { 'structure_delete_fail' -> 'ri Failed to delete %s.nbt, no such file exists', //structure name 'structure_load_fail' -> 'ri Failed to load %s.nbt, no such file exists', //structure name - 'angel_block_new' -> 'w Clicking with %s will now palce an angel block', //new angel block item + 'angel_block_new' -> 'w Clicking with %s will now palce an angel block', //new angel block item 'angel_block_given' -> 'w Gave yourself angel block item: %s', 'angel_block_clear' -> 'w Unregistered angel block item', 'angel_block_none_error' -> 'r There\'s no angel block defined! Use \'angel new\' to register one', 'angel_block_bad_item' -> 'r Angel block can\'t be something that is already assigned to another action', + 'action_item_not_existing_error' -> 'r %s is not registered as %s', //item, action + 'action_item_existing_error' -> 'r %s is already registered as %s. Unregister it first, or choose another item.', //item, action + 'action_item_angel' -> 'angel block item', + 'action_item_wand' -> 'wand', + 'action_item_brush' -> 'brush', + //Block-setting actions 'action_cube'-> 'cube', 'action_cuboid' -> 'cuboid', @@ -969,15 +978,13 @@ global_brush_reach = 100; brush(action, flags, ...args) -> ( player = player(); held_item = player~'holds':0; - if(held_item==global_wand || held_item==global_angel_block, _error(player, 'bad_brush_error')); if( action=='clear', - if(has(global_brushes, held_item), - delete(global_brushes, held_item); - delete(global_liquid_brush, held_item), - _error(player, 'no_brush_error', held_item) - ), + remove_action_item(held_item, 'brush'); + delete(global_brushes, held_item); + delete(global_liquid_brush, held_item), + action=='list', //TODO imprvove list with interactiveness if(global_brushes, _print(player, 'brush_list_header'); @@ -999,8 +1006,9 @@ brush(action, flags, ...args) -> ( _print(player, 'brush_reach', global_brush_reach) ), // else, register new brush with given action - if(has(global_brushes, held_item), - _print(player, 'brush_replaced', held_item) + if((registered = global_items_with_actions:held_item) == 'brush', + _print(player, 'brush_replaced', held_item), + new_action_item(held_item, 'brush') ); global_brushes:held_item = [action, args, flags]; @@ -1425,19 +1433,36 @@ _give_angel_block_item() -> ( ); ); _set_angel_block_item() -> ( - if( (item = player()~'holds':0) == global_wand || has(global_brushes, item), - _error(player(), 'angel_block_bad_item'), - global_angel_block = item; - _print(player(), 'angel_block_new', global_angel_block) - ); + new_action_item(item = player()~'holds':0, 'angel'); + delete(global_items_with_actions, global_angel_block); + global_angel_block = item; + _print(player(), 'angel_block_new', global_angel_block) ); _clear_angel_block_item() -> ( p = player(); - if(global_angel_block, - global_angel_block=null; - _print(p, 'angel_block_clear'), - _error(p, 'angel_block_none_error') - ) + remove_action_item(global_angel_block, 'angel'); + global_angel_block=null; + _print(p, 'angel_block_clear') +); + +global_item_action_translation_key = { + 'brush' -> 'action_item_brush', + 'wand' -> 'action_item_wand', + 'angel' -> 'action_item_angel', +}; + +new_action_item(item, action) -> ( + if(has(global_items_with_actions, item), + _error(player(), 'action_item_existing_error', item, _translate(global_item_action_translation_key:(global_items_with_actions:item)) ), + global_items_with_actions:item = action; + ); +); + +remove_action_item(item, action) -> ( + if( (registered = global_items_with_actions:item) != null && registered == action, + delete(global_items_with_actions, item), + _error(player(), 'action_item_not_existing_error', item, _translate(global_item_action_translation_key:action)) + ); ); //Command functions From 21eac4c3173a672c77f25a0348469ff9e80edaec Mon Sep 17 00:00:00 2001 From: firigion Date: Mon, 15 Feb 2021 22:11:37 -0300 Subject: [PATCH 09/11] Made it so that flood can happen outside selection by adding optional radius argument --- docs/Documentation.md | 20 ++++---- world-edit.sc | 112 ++++++++++++++++++++---------------------- 2 files changed, 63 insertions(+), 69 deletions(-) diff --git a/docs/Documentation.md b/docs/Documentation.md index f5e554f..d3efad8 100644 --- a/docs/Documentation.md +++ b/docs/Documentation.md @@ -44,11 +44,6 @@ Left clicking again will reselect the whole box. - `/world-edit paste` -> Pastes selection relative to player position. Be careful incase you didnt' choose a wise spot when making the selection. - `/world-edit paste ` -> Pastes selection relative to `pos` - - `/world-edit flood ` -> Performs a flood fill (fill connex volume) within the selection and starting at the - player's position. Can both "fill" - what used to be air or replace some other block. - - `/world-edit flood ` -> Flood fill will happen only perpendicular to an axis. Setting axis to `y`, for - instance, will fill the horizontal plane. - `/world-edit structure list` -> Lists all available structures. Currently, they are all in the same file as the lang files, this may change soon. You can add other structure files, and they will load properly - `/world-edit structure load ` -> Loads a structure relative to `pos`, or relative to player @@ -60,15 +55,20 @@ Left clicking again will reselect the whole box. structure blocks.`force` will override an existing structure with the same name. Gives an error if no clipboard is present. Will also copy entities. - `/world-edit structure delete ` -> Deletes a structure file called `name`. - - `/world-edit copy [pos]` -> Copies selection to clipboard setting the origin of the structure at `[pos]`, if given, or the curren player position, if not. By default, will not override the existing clipboard (can be changed by adding keyword `force`), and will also take the positions relative to position of player. + - `/world-edit copy [pos]` -> Copies selection to clipboard setting the origin of the structure at `[pos]`, if given, or the curren player position, if not. By default, + will not override the existing clipboard (can be changed by adding keyword `force`), and will also take the positions relative to position of player. - `/world-edit paste [pos]` -> Pastes selection relative to player position or to `[pos]`, if given. Be careful incase you didnt' choose a wise spot making the selection. - - `/world-edit flood ` -> Performs a flood fill (fill connex volume) within the selection and starting at the player's position. Can both "fill" used to be air or replace some other block. - - `/world-edit flood [axis]` -> Flood fill will happen only perpendicular to iven axis. Setting axis to `y`, for isntance, will fill the horizontal plane. - - `/world-edit drain [radius]` -> Drains the liquid the player is standing on. By default, it does so on a given radius, ut you can set that with the optional parameter. If you don't specify a radius and are standing in a seleciton, it will drain within the selection only. It supports the `-g` flag, try it! + - `/world-edit flood [axis] [radius]` -> Performs a flood fill (fill connex volume) starting at the player's position. Flood will be limited by the current selection, + unless `[radius]` is given, in which case it will happen within a sphere. `[axis]` has to be `x`, `y` or `z` to performa flat flood fill within the plane perpendicular to + the given axis, or `none` to perform a 3D flood fill (default behaviour). Use this with `` set to air to delete stuff. + - `/world-edit drain [radius]` -> Drains the liquid the player is standing on. By default, it does so on a given radius, but you can set that with the optional parameter. If + you don't specify a radius and are standing in a seleciton, it will drain within the selection only. It supports the `-g` flag, try it! - `/world-edit walls [sides] [replacement]` -> Creates walls on the sides specified around the selection, defalts to ony vertical walls (`xz`). - `/world-edit outline [replacement]` -> Outlines the selection with ``. - `/world-edit shape ...` -> Generates a shape centered arround the palyer. See brushes for all options and parameters. - - `/world-edit angel [new|clear]` -> Angel block: click in mid air to place a (stone) block you can the build off. Without arguments, it gives the player the item registered as angel block. With `new`, it will register the currently held item as angel block item. With `clear` clears the current angel block item; you will have to register a new one to use it. + - `/world-edit angel [new|clear]` -> Angel block: click in mid air to place a (stone) block you can the build off. Without arguments, it gives the player the item registered + as angel block. With `new`, it will register the currently held item as angel block item. With `clear` clears the current angel block item; you will have to register a new one + to use it. #### Brushes diff --git a/world-edit.sc b/world-edit.sc index ec4c541..ac4c113 100644 --- a/world-edit.sc +++ b/world-edit.sc @@ -59,10 +59,16 @@ base_commands_map = [ ['selection move', _() -> selection_move(1, null), false], ['selection move ', _(n)->selection_move(n, null), false], ['selection move ', 'selection_move',false], - ['flood ', ['flood_fill', null, null], false], - ['flood ', ['flood_fill', null], [1, 'help_cmd_flood', 'help_cmd_flood_tooltip', null]], - ['flood f ', _(block,flags)->flood_fill(block,null,flags), false], - ['flood f ', 'flood_fill', false], + ['flood ', ['flood_fill', null, null, null], false], + ['flood ', ['flood_fill', null, null], false], + ['flood none', ['flood_fill', null, null, null], false], + ['flood ', ['flood_fill', null], [1, 'help_cmd_flood', 'help_cmd_flood_tooltip', null]], + ['flood none ', _(block, radius) -> flood_fill(block, null, radius, null), false], + ['flood f ', _(block,flag) -> flood_fill(block, null, null, flag), false], + ['flood f ', _(block, axis, flag) -> flood_fill(block, axis, null, flag), false], + ['flood none f ', _(block, flag) -> flood_fill(block, null, null, flag), false], + ['flood f ', 'flood_fill', false], + ['flood none f ', _(block, radius, flag) -> flood_fill(block, null, radius, flag), false], ['drain', ['_drain', null, null], false], ['drain ', ['_drain', null], [1, 'help_cmd_drain', 'help_cmd_drain_tooltip', null]], ['drain f ', _(flag)->_drain(null, flag), false], @@ -106,11 +112,15 @@ base_commands_map = [ ['brush cone ', _(block, radius, height, axis, replacement) -> brush('cone', null, block, radius, height, axis, replacement), [2, 'help_cmd_brush_cone', 'help_cmd_brush_generic', null]], ['brush cone f ', _(block, radius, height, axis, replacement, flags) -> brush('cone', flags, block, radius, height, axis, replacement), false], + ['brush flood ', _(block) -> brush('flood', null, block, null, null), false], + ['brush flood f ', _(block, flags) -> brush('flood', flags, block, null, null), false], ['brush flood ', _(block, radius) -> brush('flood', null, block, radius, null), false], ['brush flood f ', _(block, radius, flags) -> brush('flood', flags, block, radius, null), false], ['brush flood ', _(block, radius, axis) -> brush('flood', null, block, radius, axis), - [2, 'help_cmd_brush_flood', 'help_cmd_brush_generic', null]], + [1, 'help_cmd_brush_flood', 'help_cmd_brush_generic', null]], ['brush flood f ', _(block, radius, axis, flags) -> brush('flood', flags, block, radius, axis), false], + ['brush flood none', _(block, radius) -> brush('flood', null, block, radius, null), false], + ['brush flood none f ', _(block, radius, flags) -> brush('flood', flags, block, radius, null), false], ['brush line ', _(block) -> brush('line', null, block, null, null), false], ['brush line f ', _(block, flags) -> brush('line', flags, block, null, null), false], ['brush line ', _(block, length) -> brush('line', null, block, length, null), false], @@ -1148,20 +1158,6 @@ _define_flat_distance_squared(axis, radius, size) -> ( ); ); -flood(pos, args, flags) -> ( - - start = pos; - [block, radius, axis] = args; - if(block(start)==block, return()); - - // test if inside sphere - _flood_tester(pos, outer(start), outer(radius)) -> ( - _sq_distance(pos, start) <= radius*radius - ); - - _flood_generic(block, axis, start, _parse_flags(flags)); -); - line(pos, args, flags) -> ( [block, length, replacement] = args; @@ -1336,6 +1332,12 @@ feature(pos, args, flags) -> ( plop(pos, what) ); +flood(pos, args, flags) -> ( + [block, radius, axis] = args; + _flood_fill(block, pos, axis, radius, flags); + add_to_history('action_flood', player()) +); + drain(pos, args, flags) -> ( [radius] = args; _drain_generic(pos, radius, flags) @@ -1343,7 +1345,7 @@ drain(pos, args, flags) -> ( //Command processing functions -global_water_greenery = {'seagrass', 'tall_seagrass', 'kelp_plant'}; +global_water_greenery = {'seagrass', 'tall_seagrass', 'kelp_plant', 'kelp'}; global_air_greenery = {'grass', 'tall_grass', 'fern', 'large_fern'}; set_block(pos, block, replacement, flags, extra)->(//use this function to set blocks @@ -1722,25 +1724,44 @@ _place_angel_block(pos) -> ( add_to_history('action_angel', player()) ); -flood_fill(block, axis, flags) -> +flood_fill(block, axis, radius, flags) -> ( + _flood_fill(block, player()~'pos', axis, radius, flags); + add_to_history('action_flood', player()) +); + +_flood_fill(block, pos, axis, radius, flags) -> ( player = player(); - start = player~'pos'; + start = pos; if(block(start)==block, return()); - [pos1,pos2]=_get_current_selection(player); - min_pos = map(pos1, min(_, pos2:_i)); - max_pos = map(pos1, max(_, pos2:_i)); - // test if inside selection - _flood_tester(pos, outer(min_pos), outer(max_pos)) -> ( - all(pos, _ >= min_pos:_i) && all(pos, _ <= max_pos:_i) + flags = _parse_flags(flags); + + // check if inside selection, if there is a selection + if( length(global_selection) < 2, + no_selection = true, + // else, there is a selection + no_selection = false; + [pos1,pos2]=_get_current_selection(player); + min_pos = map(pos1, min(_, pos2:_i)); + max_pos = map(pos1, max(_, pos2:_i)); + // test if inside selection + _is_inside_selection(pos, outer(min_pos), outer(max_pos)) -> ( + all(pos, _ >= min_pos:_i) && all(pos, _ <= max_pos:_i) + ); + ); + + if( !no_selection && radius==null && _is_inside_selection(start), + _flood_tester(pos)->_is_inside_selection(pos), + if(radius==null, radius=25); + _flood_tester(pos, outer(start), outer(radius)) -> _sq_distance(pos, start) <= radius*radius ); - _flood_generic(block, axis, start, _parse_flags(flags)); + _flood_generic(block, axis, start,flags); ); _flood_generic(block, axis, start, flags) -> -( +( // Define function to request neighbours perpendiular to axis if( axis==null, flood_neighbours(block) -> map(neighbours(block), pos(_)), @@ -1786,41 +1807,14 @@ _flood_generic(block, axis, start, flags) -> ); ); ); - - add_to_history('action_flood', player()) ); _drain(radius, flags) -> _drain_generic(player()~'pos', radius, flags); _drain_generic(pos, radius, flags) -> ( - player = player(); if( (start_bl = block(pos)) == 'lava' || start_bl == 'water', - - flags = _parse_flags(flags); - start = pos; - - // check if inside selection, if there is a selection - if( length(global_selection) < 2, - no_selection = true, - // else, there is a selection - no_selection = false; - [pos1,pos2]=_get_current_selection(player); - min_pos = map(pos1, min(_, pos2:_i)); - max_pos = map(pos1, max(_, pos2:_i)); - // test if inside selection - _is_inside_selection(pos, outer(min_pos), outer(max_pos)) -> ( - all(pos, _ >= min_pos:_i) && all(pos, _ <= max_pos:_i) - ); - ); - - if( !no_selection && radius==null && _is_inside_selection(pos), - _flood_tester(pos)->_is_inside_selection(pos), - if(radius==null, radius=25); - _flood_tester(pos, outer(start), outer(radius)) -> _sq_distance(pos, start) <= radius*radius - ); - _flood_generic('air', null, start, flags); - - add_to_history('action_drain', player) + _flood_fill('air', pos, null, radius, flags); + add_to_history('action_drain', player()) ); ); From 58661c0adcbc42573232cfd665f08a8845d5ebd2 Mon Sep 17 00:00:00 2001 From: Firigion <64820010+Firigion@users.noreply.github.com> Date: Sat, 20 Mar 2021 18:30:22 -0300 Subject: [PATCH 10/11] Typos --- CONTRIBUTING.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a1bbad3..56013be 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -153,11 +153,11 @@ is done). Some items have built-in functionality, like the wand, but the user has the ability to add more items with actions associated with them (like brushes and angel block, for instance). If you want to add a new item functionality (say, building wand, for -example), then you need to take care of a few things, to avoid one item having many actions associated with it: +example), then you need to take care of a few things, to avoid one item having multiple actions associated with it: * When registering an item for a new action, call `new_action_item(item, action)`. This will check if the item is already - registered for another action and call `_error()` if it is. Remember, that `exit`s, so there no need for an extra, that function - does the check for you. - * When unregistering an item (not replacing it with a new one, like the wand does, actualy deleting it), call + registered for another action and call `_error()` if it is. Remember, that `exit`s, so there no need for an extra `return()` + call or anything, that function does the check for you. + * When unregistering an item (not replacing it with a new one, like the wand does, actually deleting it), call `remove_action_item(item, action)`, which will check that the requested item indeed has that action registered to it. It also `exit`s if it fails. For isntance, `brush` uses it like this: ```C++ @@ -171,9 +171,9 @@ example), then you need to take care of a few things, to avoid one item having m 1. add your action's name to the `global_lang_keys` so it can be translated 2. add your action's code name to `global_item_action_translation_key` so it can be requested from `global_lang_keys` (for example, the angel block's code name is `'angel'`, with a translation key `'action_item_angel'`, which gives the text `'angel block item'`) - 3. if your new action has a default tool or item (like the wand does), add it to `global_items_with_actions` along with it's action + 3. if your new action has a default tool or item (like the wand does), add it to `global_items_with_actions` along with its action * If registering a new item to your action just replaces the previous one, rather than adding a brand new one (think wand vs brush: one - replaces the old wand with a new one, while the other adds a new brush, leaving the old one suntouched), take good care to manually + replaces the old wand with a new one, while the other adds a new brush, leaving the old ones untouched), take good care to manually delete the old item from `global_items_with_actions` just before adding the new one. Angel block for example does it like this: ```C++ _set_angel_block_item() -> ( From 191c2386b33542a2e5060193dd32828d19f559f1 Mon Sep 17 00:00:00 2001 From: Firigion <64820010+Firigion@users.noreply.github.com> Date: Sun, 21 Mar 2021 13:35:11 -0300 Subject: [PATCH 11/11] Requested edits --- world-edit.sc | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/world-edit.sc b/world-edit.sc index 7658093..b044d10 100644 --- a/world-edit.sc +++ b/world-edit.sc @@ -1271,13 +1271,6 @@ global_brush_shapes={ ); add_to_history('action_line',player()) ), - 'flood'->_(pos, args, flags)->( - start = pos; - [block, radius, axis] = args; - if(block(start)==block, return()); - _flood_generic(block, axis, start, _(pos, outer(start), outer(radius)) -> _euclidean_sq(pos, start) <= radius*radius, flags); - ), - 'flood'->_(pos, args, flags) -> ( [block, radius, axis] = args; @@ -1946,13 +1939,13 @@ _flood_fill(block, pos, axis, radius, flags) -> if( !no_selection && radius==null && _is_inside_selection(start), _flood_tester(pos)->_is_inside_selection(pos), if(radius==null, radius=25); - _flood_tester(pos, outer(start), outer(radius)) -> _sq_distance(pos, start) <= radius*radius + _flood_tester(pos, outer(start), outer(radius)) -> _euclidean_sq(pos, start) <= radius*radius ); _flood_generic(block, axis, start,flags); ); -_sq_distance(p1, p2) -> reduce(p1-p2, _a + _*_, 0); +_euclidean_sq(p1, p2) -> reduce(p1-p2, _a + _*_, 0); _flood_generic(block, axis, start, flags) -> ( // Define function to request neighbours perpendiular to axis