This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Lego Stax's profile picture

CClear

Started by Lego Stax, 29 November 2015 - 10:20 PM
Lego Stax #1
Posted 29 November 2015 - 11:20 PM
I must be a real fan of clearing utilities.

Since 1.7.10 doesn't support /fill and WorldPorter does not have a clear function at the moment, I quickly coded this one up. All it does is remove all blocks from the specified space.

Arguments:
cclear <x1> <y1> <z1> <x2> <y2> <z2>

Download:
pastebin get MS3JJSZT cclear
Or
packman install cclear

Hopefully someone finds this useful.

Spoiler100th post! Yay!
Edited on 11 August 2016 - 07:49 PM
Blue #2
Posted 01 December 2015 - 03:51 PM
While it may not be the most complex command block code out there,it's certainly useful.
Creator #3
Posted 01 December 2015 - 04:23 PM
How fast is the program?
Lego Stax #4
Posted 01 December 2015 - 11:16 PM
While it may not be the most complex command block code out there,it's certainly useful.

That was the aim! :)/>

How fast is the program?

It's not very fast because it iterates with /setblock as that is the only 1.7 Minecraft command that allows for block modification in the world. (I believe)
Bomb Bloke #5
Posted 01 December 2015 - 11:26 PM
You can go a bit faster by switching out commands.exec() (which has to wait for the command result so it can return it) with commands.execAsync() (which doesn't; it returns a command ID instead, and an event with that ID and the result later goes into the queue, in case you care).

Catch is that if you fire off too many commands too quickly the API will eventually crash your script as a form of flood control. Making a script that regulates its command rate can be a bit tricky, but you may be able to get away with just switching one function with the other - you'll just run into problems if the user attempts to clear too large an area at once.
Lego Stax #6
Posted 02 December 2015 - 03:51 AM
You can go a bit faster by switching out commands.exec() (which has to wait for the command result so it can return it) with commands.execAsync() (which doesn't; it returns a command ID instead, and an event with that ID and the result later goes into the queue, in case you care).

Catch is that if you fire off too many commands too quickly the API will eventually crash your script as a form of flood control. Making a script that regulates its command rate can be a bit tricky, but you may be able to get away with just switching one function with the other - you'll just run into problems if the user attempts to clear too large an area at once.

sleep() should work with commands.execAsync() right? Perhaps 0.1 or 0.2 seconds? I'll do some testing later when I have time.
Bomb Bloke #7
Posted 02 December 2015 - 04:47 AM
Sleeping for however long every however many commands should indeed work, but I suspect that the actual values involved would vary depending on the power of the computer running Minecraft. Dunno. There's also a bit of a problem in that sleep() may decide to go forever while commands are running.

I've taken a liking to this kind of structure:

local curCommands, maxCommands = 0, 230

local function doCommand(...)
	while curCommands > maxCommands do os.pullEvent("task_complete") end
	curCommands = curCommands + 1
	commands.execAsync(...)
end

local function regularScript()
	-- Your actual script contents go in here, or at least the bits that perform commands.
	
	-- Any time you want to call commands.execAsync(),
	-- call doCommand() instead.
end

parallel.waitForAny(regularScript, 
	function()
		while true do
			os.pullEvent("task_complete")
			curCommands = curCommands - 1
		end
	end)

Any time you queue a command to be performed, curCommands goes up. Any time a command completes, curCommands goes down. If the queue of commands approaches a dangerous level then doCommand() starts yielding, in such a way that it slows the script down to match the pace Minecraft is actually completing commands at.

Edit:

Another thing you may wish to consider is the handling of your loops.

When the user enters in their co-ords, you aren't checking that x1 < x2, y1 < y2, etc. I suggest checking and sorting these values, as your loops won't run backwards.

On the other hand, you may want to force the loop running on the y-axis to go backwards. Deleting layers from top to bottom ensures all fluids and sand/gravel get cleared out properly, whereas they may otherwise fall from the upper (yet to be cleared) layers into the lower (supposedly cleared) layers while the script's in action.
Edited on 02 December 2015 - 04:09 AM
Lego Stax #8
Posted 02 December 2015 - 02:24 PM
-snip-

I never thought about dynamically changing the number of commands run asynchronously to prevent command flood. Stellar idea! Thank you so much! This will definitely get implemented when I have the time. :)/>

Finals are coming up soon and a bunch of large projects at school are due right now. <_</>