if you've played fortnite, whenever you break a build (like a wall, floor, or stair) anything that was connected to that build (i call them tiles) also break since they're not connected to anything anymore. I'm trying to do this in minecraft. Currently, to detect connecting tiles, i have a "roots" and "shoots" system. I "root" tile has the flag "build.shoots" and each "shoot" tile has the flag "build.roots". Currently, it's working the way i want it to. but im having trouble figuring out the next step. For example, whenever a tile that's in between a root and a nonroot (vertically), even though there's no tile connecting the remaining root and shoots, the flags indicate that the remaining shoot belongs to the root and vice versa.
#(nimsy) how to make a domino effect when breaking tiles?
182 messages · Page 1 of 1 (latest)
(nimsy) how to make a domino effect when breaking tiles?
Hi I'm AutoThreadBot! Don't mind me, I'll just be adding the helper team to this thread so they can see it. A human will get to you soon.
You can block this bot if you don't want to see these messages, I won't mind.
<@&525394568410038282>
!haste
Help us help you by pasting your script to https://paste.denizenscript.com/New/Script and linking it back here.
Content of Denizen Script Paste #106819: Unnamed Denizen Script Paste... pasted 2023/03/03 18:43:02 UTC-08:00, Paste length: 23163 characters across 548 lines, Content: #TODO: DOMINO BREAK SYSTEM (via flags)##add roots to all tiles
here's my script
Yo idk if this thread is being ignored or not
Why not just do a custom flood fill?
Start from the broken block, and moving up and out, find each fortnite tile, and keep going until they either connect with the ground, or don't
If they do, break, if not, breakn't
i was doing that for a while
but the problem is up and out doesn't work
lemme give u a scenario
if i broke a simple structure like this, it would work
but lets say i break the circled tile
nothing else should break, because it's connected to another root
Right, did you miss the breakn't step?
?
ok but how would i do this?
wouldn't i need a while or something?
because who knows how many branches of tiles there are
If any part of the structure is touching a non build able material, you can stop the loop. It's touching the ground, no need to keep checking
yeah but that's the problem
What's the problem?
right now, when i break the tile in the middle, the bottom tile still thinks the top tile is connected to it and vice versa
Why? When you flood fill, the two structures you fill into are two seperate structures
what's flood fill?
I mean it in a generic sense. You have a block, you get the six surrounding blocks. Then for each block, you get it's six surrounding blocks, and deduplicate the list. so on and so forth
yeah but im confused on how the itteration should work
So you just keep doing that, but in your case, you're checking your tiles instead of individual blocks.
wouldn't it be a while?
A while loop? Ya
it's more complicated than this tho
how would i check if it's connected to the ground or not?
i mean i already have a proc for it, but im saying how would i check that a tile that's in the air is indirectly connected to a tile that's connected to the ground?
also, how should i go about my connecting tiles system? should i use flags or just calculate it on the whim?
if a tile is on the air, and there's no tile directly below it, then it's not connected to the one on the ground. each tile only needs to worry about the one directly around it. as far as you're connecting tiles system? it would be easier to calculate it on the fly.
so just forget about the whole tile flagging system?
yeah, that's overcomplicated and not necessary. I already described this earlier, you should only need to check a few locations in every 5x5x5 tile to determine if one of your structures is there or not. You don't need to flag them
can i not just do something like
- define nearby_tiles <[center].find_blocks_flagged[build.structure].within[5].parse[flag[build.structure]].deduplicate.exclude[<[tile]>]>
wait
- define nearby_tiles <[center].find_blocks_flagged[build.structure].within[5].parse[flag[build.structure]].deduplicate.exclude[<[tile]>]>
- define connecting_tiles <[nearby_tiles].filter[intersects[<[tile]>]]>
like that
but i fear if i do that for every tile, it'll be pretty heavy
How were you thinking you'd identify the tiles, jump? Match them manually block-for-block?
she said id just have to check a few locations
can people build normally in this world
no
so...
would i have to put each branch in a while loop?
oh god
this is giving me a headache
i forgot there could literally be branches of branches
and so on
like this
yea i think the flag system would be much easier jump
rather than calculating it on the fly
actually, now that i think of it, i dont think it'd make a difference
it'd still be hard either way
Each tile has a block/a couple blocks in a location that doesn't overlap with another tile. So he only need to check one or two locations per 5x5x5 area to determine if one of his tiles was there.
Ya, pretty much that
but the problem is, not all tiles are 5x5x5
Wdym?
When I say 5x5x5, I mean that if a tile is in a location, it fills that location.
I'm not talking about it's actual footprint in the world
You couldn't put down stairs and a pyramid in the same spot, for example.
yea but their centers are also 5x0x5 and 5x5x0 respectively
Literally no idea what you're trying to say here
whatever
forget about the whole "checking to see if there are any direclty connected tiles to that tiles"
i already know how to do that
my brain just hurts thinking about the while system
??? Why?
i did it before, but i dont think i did it right
Gotcha, so you're primed to do it a certain way, that makes sense.
nono im open to anything
im just saying like
it would bea foreach in a foreach in a foreach infinitely until there's nothing to foreach
If you ever run into a situation where you think you have infinite loops, then that means something isn't in the loop that should be.
well it wouldn't be infinite
im just saying we don't know/shouldn't know when it stops
and that's why it has to be a while
Yes, when you've checked each tile, and there's no more connections
ye
how can i type that though?
because wouldn't i need a while for each branch?
and each branch can have sub branches and so on?
- Get tile
- If touching ground, all touching tiles are good
- Get all surrounding tiles
- If no surrounding tiles, break every touching tile
- Go to step 1
If you throw this part into a task, then you can just run it for each tile. So it can be simplified even more to "For each tile, run grounded_or_sibling", if any of the runs return true, break structure
ok so
for step 1
assuming <[center]> and <[tile]> belong to the tile we just removed (by hand)
Sure
- define nearby_tiles <[center].find_blocks_flagged[build.structure].within[5].parse[flag[build.structure]].deduplicate.exclude[<[tile]>]>
- define connected_tiles <[nearby_tiles].filter[intersects[<[tile]>]].filter[center.y.equals[OR_MORE].than[<[center].y>]]>
<[connected_tiles]> would be the original branching out tiles
these
Okay, following
step 2
- define branched_tiles:->:<[c_tile]>
this list would represent all the branched tiles from each of those tiles circled above
Uhm, sure, you can do that
i edited
Ah, ya, that makes sense
ok now
But also, remember that each initial branch off of the center tile is it's own structure, initially.
yea
Because left, right and down might connect to the floor somewhere else, but above never would.
yea but what if the initial branches eventually reconnect?
So adding all the connected branch tiles to a single list gets rid of the distinction
Then that's fine
starting from here
i changed definitions
i changed this to initial_branched_tiles instead, and ill be using connected_tiles for the tiles that are connected to the initial_branched_tiles to clear up confusion
fuck
this is hard to sorta explain without being in a call or something ngl
- foreach <[initial_branch_tiles]> as:i_tile:
- define branched_tiles <list[]>
- define center <[i_tile].center.flag[build.center]>
- define type <[center].flag[build.type]>
- define branched_tiles <[branched_tiles].include[<[i_tile]>]>
#if root, everything connected to this structure is fine
- if <proc[is_root].context[<[center]>|<[type]>]>:
- foreach next
I mean, I explained it to you, you're the one who would write it.
this is what i have so far
next up is the while
What does "is_root" do?
checks if it's connected to the ground
Ah, gotcha
honestly i might have to make a proc for finding connected tiles via the intersects method too, but im thinking of maybe using a flag system instead to make it a bit lighter
- foreach <[initial_branch_tiles]> as:i_tile:
- define has_root False
- define branched_tiles <list[]>
- define center <[i_tile].center.flag[build.center]>
- define type <[center].flag[build.type]>
- define branched_tiles <[branched_tiles].include[<[i_tile]>]>
#if root, everything connected to this structure is fine
- if <proc[is_root].context[<[center]>|<[type]>]>:
- foreach next
- define nearby_tiles <[center].find_blocks_flagged[build.structure].within[5].parse[flag[build.structure]].deduplicate>
- define connected_tiles <[nearby_tiles].filter[intersects[<[i_tile]>]]>
- while <[connected_tiles].any> && !<player.has_flag[test]>:
- define branched_tiles <[branched_tiles].include[<[connected_tiles]>]>
- define new_connected_tiles <list[]>
- foreach <[connected_tiles]> as:c_tile:
- define center <[c_tile].center.flag[build.center]>
- define type <[center].flag[build.type]>
#if it's a root, then everything is chilling
- if <proc[is_root].context[<[center]>|<[type]>]>:
- define has_root True
- while stop
#this time, the nearby tiles will INCLUDE its own tile
- define nearby_tiles <[center].find_blocks_flagged[build.structure].within[5].parse[flag[build.structure]].deduplicate>
- define next_tiles <[nearby_tiles].filter[intersects[<[c_tile]>]]>
- define connected_tiles <[connected_tiles].include[<[next_tiles]>]>
- define connected_tiles <[connected_tiles].deduplicate>
- if <[has_root]>:
- foreach next
- narrate "remove <[branched_tiles].size> tiles"
!haste
Help us help you by pasting your script to https://paste.denizenscript.com/New/Script and linking it back here.
alright @crystal turtle https://paste.denizenscript.com/View/106948
Content of Denizen Script Paste #106948: Unnamed Denizen Script Paste... pasted 2023/03/05 15:21:44 UTC-08:00, Paste length: 1713 characters across 44 lines, Content: - foreach <[initial_branch_tiles]> as:i_tile:
i really dont know if this is right
bro
the second i tried using the script, my PC started sounding like a fucking jet engine 😂
as i expected, something is wrong lol
i think it might be because it's reusing previous tiles too
yup. Give me a second, I'll clean this up for you which might help you get a clearer idea
Alright, here ```yaml
#get_tile is a proc that takes a location, and returns the 5x5x5 tile that it's in.
#get_surrounding_tiles takes a tile and returns each tile on the six cardinals.
- define broken_tile <proc[get_tile].context[<[initial_break_location]>]>
- define branches <proc[get_surrounding_tiles].context[<[broken_tile]>]>
#There's only six branches (or less) for each cardinal
#direction, so we use a foreach, and go through each one.
-
foreach <[branches]> as:starting_tile:
#The tiles to check are a list of tiles that we need to get siblings of.
#Each tile in this list gets checked once, and removed.- define tiles_to_check <list[<[starting_tile]>]>
#The structure is a list of every tile in a single continous structure.
#When you determine that a group of tiles needs to be broken, you'll go through this list. - define structure <list[<[starting_tile]>]>
#The two above lists are emptied at the start of each while loop,
#so that way previous tiles from other branches don't bleed into this one.- while <[tiles_to_check].any>:
#Just grab the tile on top of the pile. It doesn't matter the order
#in which we check, we'll get to them all eventually, unless the
#strucure is touching the ground, in which case it doesn't really
#matter.- define tile <[tiles_to_check].last>
#If the tile is touching the ground, then skip this branch. The
#tiles_to_check and structure lists get flushed out and we start
#on the next branch. When we next the foreach, we are
#also breaking out of the while, so we don't need to worry about
#keeping track (like you had with has_root) - foreach next if:<proc[is_root].context[<[tile]>]>
#If the tile ISN'T touching the ground, then first, we remove it
#from the tiles to check list, because obvi we've already checked
#it. - define tiles_to_check:<-:<[tile]>
#Next, we get every surrounding tile, but only if they're not already
#in the structure list. That means that we don't keep rechecking tiles
#we've already checked. - define surrounding_tiles <proc[get_surrounding_tiles].context[<[tile]>].exclude[<[structure]>]>
#We add all these new tiles to the structure, and since we already excluded
#the previous list of tiles in the structure, we don't need to deduplicate. - define structure:|:<[surrounding_tiles]>
#Since these are all new tiles, we need to check them as well. - define tiles_to_check:|:<[surrounding_tiles]>
#If we get to this point, then that means we didn't skip out early with foreach.
#That means we know it's not touching ground anywhere, so now we want to break
#each tile. So we go through the structure list, and break each one (however you handle that.)
- define tile <[tiles_to_check].last>
- foreach <[structure]> as:tile:
- run break_tile def.tile:<[tile]>```
- define tiles_to_check <list[<[starting_tile]>]>
So obviously, a lot of this is abstracted. For two reasons, I don't want to make you have to do something that breaks your previous system (like you using flags over checking locations manually), but also because it makes it a lot easier to follow along with what you're actually trying to accomplish, at a high level.
yea idk why this was such a hard concept for me to grasp
ill try it out rn, sorry for the wait
also ty for this spacing trick, didn't know about it
finally got it to work jump
i had to sneak in 1 extra line in there after i finally found the culprit that flooded my console with errors
added this before the root check
- foreach next if:!<[tile].center.has_flag[build.center]>
that way, if it was removed, (since i remove the flags when i remove the tile), it means that branch was already destroyed
my only concern now is performance issues
!haste
Help us help you by pasting your script to https://paste.denizenscript.com/New/Script and linking it back here.
Content of Denizen Script Paste #106958: Unnamed Denizen Script Paste... pasted 2023/03/05 22:39:46 UTC-08:00, Paste length: 24361 characters across 558 lines, Content: build_tiles: type: task
here's the whole thing now
did uhh
you test this?
I'm not certain, but i don't think ! works with the if arg
It does iirc
ye it does
i mean i just copied what jumpslat had already sent
I mean, best way to check performance is to run it, and check it with spark or some sort of profiler.
Thread Closing Reminder
Has your issue been resolved, or your question been answered?
If so, please use the </resolved:1028673926114594866> command to close your thread.
Or </invalid:1028673926898909185> if it's not possible to resolve.
If not yet resolved, please reply below to tell us what you still need.
(Note that if there is no reply for a few days, this thread will eventually close itself.)
@slate turret