[#3] Skript Challenge - Area Fill - Winners announced!

  • Welcome to skUnity!

    Welcome to skUnity! This is a forum where members of the Skript community can communicate and interact. Skript Resource Creators can post their Resources for all to see and use.

    If you haven't done so already, feel free to join our official Discord server to expand your level of interaction with the comminuty!

    Now, what are you waiting for? Join the community now!

Status
Not open for further replies.

BaeFell

I'm Poppy
Staff member
Admin
skUnity Legend
Nov 27, 2016
1,023
241
73
discord.gg
Discord Username
BaeFell
Hi everyone,

Welcome to another Skript Challenge!

So here's the third one! If you have any suggestions for #4 or general improvements, let me know :emoji_slight_smile:

This Skript Challenge is kinda mathematical, but mostly around being smart with how your script works. The task is to create a way for me to fill an area. The area fill must be suitable for any size or shape area. The areas will be completely closed in (so no holes in walls etc). Example:

THIunfK.jpg

Filled:
c8AiSLQ.jpg
There are no holes in the walls, floor or ceiling (apart from an open door but they're classed as a block). But also note the odd shape. This is just an example, areas can be very complex.

The rules are as follows (note: rules may change between challenge):
- Your code must be in [code]<code>[/code] tags so that I can easily read it.
- You can use addons, but, you're not allowed to use a feature from an addon which does this (don't think any do) and the addon must of been released publicly prior to the creation of this thread.
- You cannot use a feature like "fill area from location of player" or whatever.
- You can use another user's code, but please don't edit your messages. I can see all message history and you'll not be counted at all.
Remember: this one is about quality, not just length. So trying to cut variable names from someone elses code will lose points!
- WebAPI's or using an external source (outside of Skript), to get your result in not allowed. All submissions must actually do the conversions themselves.
- You can use an addon to place blocks, but not to fill the area.
- You must list all addons used. I will be testing on Spigot 1.11.2.

I might add a rule after a submission has been made, it's up to me whether or not that submission is valid. I can deny any submission for any reason.

Challenge details (specifics about this challenge):
- Your code must work with any size or shape area. Areas are not square and sometimes spin off into rooms.
- You must provide a way for me to know where you're starting from. So for example: using a command + location of player, right click on sign + location of player, right click on sign + event-location


Tips:
- Make it easy for me to change the block which is filling. Constantly repeating "set {_block} to 1", isn't going to be good.
- Be smart about how I can get out if the area is being filled
- Try not to crash my server

I have done this before and the code works well. It uses no addons and is 31 lines long (including some if checks etc).

How answers will be judged:
Unlike others, the winner for this one, will be judged based on quality. I and others (who I'm yet to pick), will go around and find the best answers. I'm not sure on the specifics of how the scoring will work, the final judgement and most other things, but I've got a week to figure that out!

Important
If you don't understand how your answer will be judged here is an explanation:
Better code quality = more points. I'm very anti-addon with some things. If you're using an addon for what can be done normally in Skript, then you're not Skripting right. Variable names, code structure, use of functions and code readability matters for this challenge. I'm specifically looking for the best code, not the smallest, but you shouldn't have code that is far too long, otherwise it's unlikely to be efficient.

The closing date is 7 days from now -> 4th of March - have fun!
(I might forget to do the winners, but should close after 7 days).
 
  • Like
Reactions: Sam
Usage:
Type command at location of player

Function:
5 Lines plus optional wait
code_language.skript:
function fill(loc: location, block: itemtype):
    loop blocks in radius 1 around {_loc}:
        if loop-block is air:
            set loop-block to {_block}
            wait a second
            fill(location of loop-block, {_block})

Example code:
code_language.skript:
function fill(loc: location, block: itemtype):
    loop blocks in radius 1 around {_loc}:
        if loop-block is air:
            set loop-block to {_block}
            wait a second
            fill(location of loop-block, {_block})
command /bae:
    trigger:
        fill(location of player, light green stained clay)

Video:
code_language.skript:
function fill(loc: location, block: itemtype):
    loop blocks in radius 1 around {_loc}:
        if loop-block is air:
            set loop-block to {_block}
            if {stop} is not set:
                wait a second
                fill(location of loop-block, {_block})
 
Hiya!

I considered going more ham with this and making it really in-depth, but I figure simplicity is good if it works. This is 14 lines of actual Skript, no add-ons, has a built-in failsafe for if people provide an item type that isn't a block, and allows you to tell it a configurable amount of outwards iterations it will do between each tick delay. All it's missing is a way for the player to get out of the area if they're in the floodfill zone, which could be done in a few ways (I may come back and improve upon it to add something like that, though I'm pretty happy with its current state, and I imagine this as a tool for admins who have access to things like spectator mode anyways).

Executes from you.

code_language.skript:
function floodFill(root: location, block: item, iterationsBetweenDelay: integer, iterationNum: number = 0):
    if {_iterationNum} is {_iterationsBetweenDelay}:
        wait 1 tick
        set {_iterationNum} to 0
    loop blocks in radius 1 of {_root}'s location:
        loop-block is air
        set loop-block to {_block}
        if loop-block is air:
            stop
        floodFill(loop-value, {_block}, {_iterationsBetweenDelay}, {_iterationNum} + 1)

command /floodfill <item> [<integer=10>]:
    usage: /floodfill <block type> <iterations between delay>
    trigger:
        floodFill(player's location, arg-1, arg-2)
 
code_language.skript:
command /TryThisCommand:
    permission: try.this.command
    trigger:
        message "Don't move"
        loop all blocks in radius 4 around player's location:
            set loop-block to air
            wait 0.001 seconds
            set block below player to glass block
        loop all blocks in radius 2 around player's location:
            if loop-block is air:
                set loop-block to glass block
        loop all blocks in radius 1 around player's location:
            if loop-block is glass block:
                set loop-block to air
        set block below player to glass block
        set block above player to air
        wait 3 seconds
        thrust player upwards at speed 1
        wait 0.2 seconds
        thrust player forwards at speed 1
        message "The End"

I used Skellett as an addon
 
Last edited by a moderator:
  • Like
Reactions: LimeGlass
Commands:
/areaFill <Item> <Radius> [<Delay>] - Start filling from your location
/areaFill cancel - Cancel or roll back filling

Features
:
- Delayed filling
- Filling radius
- Cancel or roll back filling (/areaFill cancel)

Requirements:
- Skript 2.2+

code_language.skript:
function areaFill(startLocation: location, location: location, block: itemtype, radius: number, delay: timespan):
    loop blocks in radius 1 of {_location}:
        if {areaFill.cancel} is not set:
            if distance between {_startLocation} and loop-block is smaller than {_radius} + 1:
                if loop-block is air:
                    set loop-block to {_block}
                    add location of loop-block to {areaFill.placed::*}
                    wait {_delay}
                    areaFill({_startLocation}, loop-block, {_block}, {_radius}, {_delay})

command /areaFill <text> [<number>] [<timespan=10 tick>]:
    permission: op
    usage: &c/areaFill <Cancel|Undo|Block> [<Radius>] [<Delay>]
    trigger:
        if arg 1 is not "cancel":
            if arg 1 parsed as itemtype is set:
                if arg 2 is set:
                    clear {areaFill.placed::*}
                    delete {areaFill.cancel}
                    areaFill(block at player, block at player, arg 1 parsed as itemtype, arg 2, arg 3)
                    send "&aFilling started!"
                    send "&2Block: &b%arg 1%"
                    send "&2Radius: &b%arg 2%"
                    send "&2Delay: &b%arg 3%"
                else:
                    send "&c/areaFill %arg 1% <Radius> [<Delay>]"
            else:
                send "&c/areaFill <Cancel|Undo|Block> [<Radius>] [<Delay>]"
        else:
            set {areaFill.cancel} to true
            loop {areaFill.placed::*}:
                delete block at loop-value
            clear {areaFill.placed::*}
            send "&cFilling canceled or rolled back!"

LyYEm0.png
 
Last edited by a moderator:
  • Like
Reactions: bertek41
code_language.skript:
function a(location:location):
    set {_0} to random number between 2 and 20
    loop blocks in radius 1 around {_location}:
        loop {_0} times:
            wait tick
        loop-block = air
        a(location of loop-block)
        set block at location at loop-block to any_wool_block
command a:
    trigger:
        a(location of block at player)
 
How to use:
Use the command /fill <block> inside the area, the script will automatically fill the area with your chosen block type and will teleport you outside of the area.
If you somehow forget to completely close the area off, and this happens to you:
tMzxWKd.png

Then you would always have the option to cancel the process, by using this command "/fill stop".

code_language.skript:
function fill(loc: location, p: player, loc2: location, b: material):
    wait 1 tick
    {fill} is true
    if block at {_loc2} is not air:
        add 1 to {_loc2}'s y-coordinate
    else:
        teleport {_p} to {_loc2}
    loop blocks in radius 1 around {_loc}:
        loop-block is air
        set loop-block to {_b}
        fill(loop-block's location, {_p}, {_loc2}, {_b})

command /fill [<text=dirt>]:
    trigger:
        if arg-1 is "stop":
            set {fill} to false
        else:
            set {fill} to true
            fill(player's location, player, player's location, arg-1 parsed as material)
 
Hiya!

I considered going more ham with this and making it really in-depth, but I figure simplicity is good if it works. This is 14 lines of actual Skript, no add-ons, has a built-in failsafe for if people provide an item type that isn't a block, and allows you to tell it a configurable amount of outwards iterations it will do between each tick delay. All it's missing is a way for the player to get out of the area if they're in the floodfill zone, which could be done in a few ways (I may come back and improve upon it to add something like that, though I'm pretty happy with its current state, and I imagine this as a tool for admins who have access to things like spectator mode anyways).

Executes from you.

code_language.skript:
function floodFill(root: location, block: item, iterationsBetweenDelay: integer, iterationNum: number = 0):
    if {_iterationNum} is {_iterationsBetweenDelay}:
        wait 1 tick
        set {_iterationNum} to 0
    loop blocks in radius 1 of {_root}'s location:
        loop-block is air
        set loop-block to {_block}
        if loop-block is air:
            stop
        floodFill(loop-value, {_block}, {_iterationsBetweenDelay}, {_iterationNum} + 1)

command /floodfill <item> [<integer=10>]:
    usage: /floodfill <block type> <iterations between delay>
    trigger:
        floodFill(player's location, arg-1, arg-2)
You should ad that you will be teleported out of the area, and also that you can let it go instant instead of every second
 
Usage:
Type command at location of player

Function:
5 Lines plus optional wait
code_language.skript:
function fill(loc: location, block: itemtype):
    loop blocks in radius 1 around {_loc}:
        if loop-block is air:
            set loop-block to {_block}
            wait a second
            fill(location of loop-block, {_block})

Example code:
code_language.skript:
function fill(loc: location, block: itemtype):
    loop blocks in radius 1 around {_loc}:
        if loop-block is air:
            set loop-block to {_block}
            wait a second
            fill(location of loop-block, {_block})
command /bae:
    trigger:
        fill(location of player, light green stained clay)

Video:
code_language.skript:
function fill(loc: location, block: itemtype):
    loop blocks in radius 1 around {_loc}:
        if loop-block is air:
            set loop-block to {_block}
            if {stop} is not set:
                wait a second
                fill(location of loop-block, {_block})
Try it in empty 3d triangle. It will probably not work if looping area is cube, not circle. In this way It should work only in cubic areas
 
code_language.skript:
options:
    filter: air
    block: sponge

function text2Loc(location:string,world:world = "world") :: location:
    set {_location::*} to {_location} parsed as "x: %number%, y: %number%, z: %number%"
    return location({_location::1}, {_location::2}, {_location::3}, {_world})

function chunkLoad(location:location,block:block):
    stop #to do...

function b(location:location):
    add {_location} to {_locations::*}
    add chunk of {_location} to {_chunks::*}
    set {_location} to chunk of {_location}
    set {_chunks::%{_location}%::*} to text2Loc("%{_locations::*}%")
    set {_location} to now
    execute console command "tps"
    while {_chunks::*} is set:
        loop {_chunks::*}:
            {_locations::*} isn't set:
                loop {_chunks::%loop-value%::*}:
                    add text2Loc("%loop-value-2%") to {_locations::*}
            while {_locations::*} is set:
                loop {_locations::*}:
                    loop blocks in radius 1 around loop-value-2:
                        loop-block = {@filter}
                        if chunk of loop-block = loop-value-1:
                            wait tick
                            set loop-block to {@block}
                            add 1 to {_blocks}
                            chunkLoad(location at loop-block,loop-block)
                            add location at loop-block to {_locations::*}
                        else if "%{_chunks::*}%" contains "%chunk of loop-block%":
                            add location of loop-block to {_chunks::%chunk of loop-block%::*}
                        else:
                            add chunk of loop-block to {_chunks::*}
                            add location of loop-block to {_chunks::%chunk of loop-block%::*}
                    remove loop-value-2 from {_locations::*}
                wait tick
            broadcast "<green>%loop-value-1% complite!"
            delete {_chunks::%loop-value%::*}
            remove loop-value from {_chunks::*}
            wait second
    execute console command "tps"
    broadcast "<green>all complite! blocks:""%{_blocks}%"" and time:""%difference between now and {_location}%"""

command b:
    trigger:
b(location)
p.s. in theory load one chunk
 
It's time to announce the Winners of the 3rd Skript Challenge! Finally...
@BaeFell has given me the honour of deciding the winners (probably because he forgot again...). As such, it is my honour to announce the following 3 winners.

The selection process was quite simple, as most of the submissions a) didn't work properly, or achieve the needed result and b) were mostly based off of @LimeGlass's submission.

In no particular order, the winners are.

@LimeGlass - First Submission, Lowest amount of lines, Small and Simple and easily repeatable.
@Mr_Simba - Much like LimeGlass, but with extra detail in the included failsafe.
@Blueyescat - With added detail in the form of his arguments, added cancellation ability and more.

Congratulations to all the winners, and thank you to everyone else who submitted!
Just some helpful advice for future events;
1. Try to be original, there are always more than one way of achieving a goal. If you make the most longest and craziest response, then so be it. It's awesome in its own right.
2. While we're not against building off of others', at least add something new to it (ie; a stop feature)
3. Make sure it actually does what is required... There's one submission here that didn't even get close to the wanted result.

Thats all! Thanks a lot!

(Winners: Your badges will be given in due time, make sure to annoy @BaeFell if you haven't gotten it by next week)

(This was posted here, since @BaeFell forgot to give me permission to post in the proper place...)
 
  • Like
Reactions: Uzumaki and BaeFell
Status
Not open for further replies.