Official Everybody Edits Forums

Do you think I could just leave this part blank and it'd be okay? We're just going to replace the whole thing with a header image anyway, right?

You are not logged in.

#1 2017-08-03 03:57:38

|Molten|x|Blitz|
Member
Joined: 2017-07-27
Posts: 3

Replace group of blocks

I'm not the best at making bots, far from it to be exact; I was wondering if there was a simple way to replace a big group of block (world border, boss border, blocks in an art piece etc...) quickly without having to send "b" a ton of times and selecting the co-ordinates.
As I said, I'm not amazing, so I've probably overlooked something really simple.
Thanks :3


Make a signature they said; it will be simple they said

Offline

#2 2017-08-03 07:04:48, last edited by Swarth100 (2017-08-03 07:08:44)

Swarth100
Member
Joined: 2015-07-18
Posts: 305

Re: Replace group of blocks

|Molten|x|Blitz| wrote:

I'm not the best at making bots, far from it to be exact; I was wondering if there was a simple way to replace a big group of block (world border, boss border, blocks in an art piece etc...) quickly without having to send "b" a ton of times and selecting the co-ordinates.
As I said, I'm not amazing, so I've probably overlooked something really simple.
Thanks :3

As of now there is no way to replace more than a single block with a b command.

What I do though suggest is to create yourself a custom wrapper for block updates. You can either spawn a new thread or use a background worker to act as Observers over a specific Block data structure (I personally use a PQueue).
Adding to the data structure (which could be done via custom-functions which generate "really big groups of blocks") triggers the async updates.

Note: If you're quite new to bot making, remember to take into account server-sided packet drops and your personal latency; it might be wise to introduce delays in the thread which updates blocks.

Offline

Wooted by:

#3 2017-08-03 15:43:59

Tomahawk
Forum Mod
From: UK
Joined: 2015-02-18
Posts: 2,718

Re: Replace group of blocks

^ Well that was obscure... It's almost as if you were trying to discourage him.

...

Blitz, how much do you know about the mapdata in "init"? I mean about decoding it and then keeping an updated list of what blocks are in the world?

Because once your bot knows the position and ID of every block, replacing a certain ID with another becomes possible and easy.

This thread talks about the mapdata, and the modified version of InitParse I wrote may help you. You'll need to do further coding to record blocks placed in the world after the bot has joined.


One bot to rule them all, one bot to find them. One bot to bring them all... and with this cliché blind them.

Offline

Wooted by: (2)

#4 2017-08-03 17:36:23, last edited by LukeM (2017-08-03 18:00:04)

LukeM
Member
From: England
Joined: 2016-06-03
Posts: 3,004
Website

Re: Replace group of blocks

Just thought I would suggest a few possible ways of doing this, just incase you didnt know you could do them:

There are two main ways of storing the world, one is in multi dimensional array(s), and the other is in lists.

The main advantage of lists is that its very easy to do things like this, as you can just loop through the array using a foreach loop, then just send a block for each:

// Using Linq it can be a (sort of) one liner :D
// blocks = List<Block>, Block has x, y, layer, id

// PlaceBlock with delay, just to make code neater, and not have millions of Thread.Sleeps
public void PlaceBlock(int layer, int x, int y, int id) {
	con.send('b', layer, x, y, id);
	Thread.Sleep([block delay]);
}

// Where the ids match, place a block in the same position with the new ID
blocks.Where(b => b.id == [target ID]).ForEach(b => PlaceBlock(b.layer, b.x, b.y, [replacement ID]));

// As others have said, you may want to use async, but it should be fine to just use sleep in most cases

The other way is to do it with arrays, this is sometimes easier to manage, and usually more efficient, but can be harder to do some things, and is slightly more messy for things like this. You can still do something similar though, just replacing the one liner with this:

// blocks = Block[,,] (x, y, layer)

// For each block in the world, if the ids match, place a block in the same position with the new ID
foreach (Block b in blocks)
	if (b.id == [target ID])
		PlaceBlock(b.layer, b.x, b.y, [replacement ID]);

// If you dont store the position in Block however (e.g. if you just store an int) you have to do something like this:
for (int x = 0; x < blocks.GetLength(0); x++)
	for (int y = 0; y < blocks.GetLength(1); y++)
		for (int layer = 0; layer < blocks.GetLength(2); layer++)
			if (blocks[x, y, layer] == [target ID])
				PlaceBlock(layer, x, y, [replacement ID]);

Note: Written without using an IDE, or any testing, so although im pretty sure the logic is correct, there may still be a few errors

Edit: just realised you might have only wanted connected blocks, in that case, the only real way is to use a flood fill algorithm, and you only really want to use the arrays method for that, as the List method would be really slow

Offline

Wooted by:
LukeM1501778183670883

Board footer

Powered by FluxBB

[ Started around 1664645527.2671 - Generated in 0.050 seconds, 12 queries executed - Memory usage: 1.41 MiB (Peak: 1.52 MiB) ]