New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Structure Block and Structure Void #6045
base: minor-next
Are you sure you want to change the base?
Conversation
The values can be basically anything. The usual way is to put them at the bottom and increase the FIRST_UNUSED_TYPE_ID constant (or whatever it's called, I forget) to accommodate. However, putting them in a gap will also work.
You haven't registered them in |
After having implemented block states and serialization/deserialization. I'm getting this error when using the block:
It seems these mappings are taken directly from bedrock data though. Have I used an incorrect constant ? |
I have found the issue, I was using 0 and 1 for values instead of constant strings from |
I think this is ready for an initial review. I've added a plugin to test in the pr description :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These functions should not be nullable
src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php
Outdated
Show resolved
Hide resolved
src/data/bedrock/block/convert/BlockStateToObjectDeserializer.php
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some phpstan and style correction need to be adresses, but the logic looks good
I've done all the changes I wanted to do for this PR, the two blocks are added and the structure block can be interacted with and changes to structure settings are saved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is trying to do multiple things at once. Most of the Structure Void stuff is fine, but the majority of the PR is Structure Block stuff which I find has been implemented poorly. Please split the two blocks into separate PRs.
if ($player instanceof Player) { | ||
if (!$player->isCreative(true)) return false; | ||
// the 0 is dubious but any value works | ||
$pk = ContainerOpenPacket::blockInv(0, WindowTypes::STRUCTURE_EDITOR, BlockPosition::fromVector3($this->getPosition())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not like this. Packets shouldn't be directly baked into the core code like this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I create an Inventory extending BlockInventory and TemporaryInventory with no slots then ? Sounds odd
5 => self::EXPORT, | ||
default => throw new \ValueError("Unknown structure block type " . $type), | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should not be visible in the API. The general way to handle these would be a map in pocketmine\data\bedrock
.
self::INVALID => 4, | ||
self::EXPORT => 5, | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same again here.
|
||
enum StructureVoidType{ | ||
case VOID; | ||
case AIR; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the difference between these two types?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the minecraft wiki:
It exists as a data value of structure voids. It acts similarly to structure voids. When holding a structure air or structure void, it becomes visible. Structure air and structure voids can stack together, the icon of the stack is the icon of whichever block was most recently added to the stack. Transparent blocks can be placed on them just like with structure voids. In the inventory, structure air is called structure void. If you give yourself a structure air then whenever you hold a structure void it will look like a structure air in your hand in both third and first person. Structure air are copied by structure blocks. This makes structure air very useful so always use structure air for your creative builds instead of structure voids. Note: structure air becomes structure voids when placed by hand, but if placed with /setblock ~ ~ ~ structure_void ["structure_void_type":"air"] it will stay as a structure air.
I was not able to completely verify this information, the difference that matters in this pr is that vanilla minecraft will forbid you from placing structure airs, and in this pr you can place them fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And you can't stack two different types in the pr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wiki entry is gibberish that conveys no actual information. That's why I asked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The difference is that structure air will replace whatever block is at that position with an air block, while structure void will just leave it be
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's exactly what normal air does ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depends on the structure block settings iirc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meaning what?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about the Remove Blocks setting, but it doesn't help (its just another weird setting).
After testing on 1.20.41.02, I was unable to find a useful difference between structure air and structure void. I was able to reproduce normal behavior with both:
Structure voids can be placed as part of a structure and are ignored when the structure file is loaded. This results in the blocks at the location where the structure is placed being maintained and not being overridden.
This is exactly what happened :
For example, if a player saves a 2 block high structure with air at the top and a structure void at the bottom, and loads it into a 2 block high area of stone, the top block becomes air but the bottom stays stone.
What did not happen:
- "Structure air are copied by structure blocks."
TL;DR I was not able to find any difference in the structure block usage. I left a comment on the wiki page
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you try pasting structures underwater with this? I wonder if there's a difference in the water displacement behaviour.
/** | ||
* @return $this | ||
*/ | ||
public function setXMirror(bool $xMirror) : self{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, why is this mutable?
/** | ||
* @return $this | ||
*/ | ||
public function setYMirror(bool $yMirror) : self{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And again here
2 => self::BY_BLOCK, | ||
default => throw new \ValueError("Unknown structure animation mode " . $mode), | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should be handled in pocketmine\data
self::BY_LAYER => 1, | ||
self::BY_BLOCK => 2, | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and again here
Thank you for the complete review, I will make a separate PR for the structure void. |
Introduction
This pull request is looking to implement the structure void, and possibly the structure block as it is closely related.
I personally don't have the knowledge required to implement the full structure block, but I would like to get it working at least as an inanimate place-able block.
Relevant issues
Changes
This is a non-disruptive addition of blocks.
Tasks
Left for a future PR:
Bugs
air
variant of structure voids gets placed as avoid
variant in vanillaNotes
I have used arbitrary values inBlockTypeIds.php
, as there is a gap there I am not sure if it should have used a different number inside the gap.I have used blast resistance values as indicated in the minecraft wiki, the block is indestructible, does it really matter ?Right now, both blocks appear as update blocks to the client. I am not sure why, is the block state mandatory for them to appear correctly ?Tests
Structure Void
/give <player> structure_void
Structure Block
plugin.yml
Main.php
Place a structure block and stand on top of it, then execute the /test command and check that the parameters have been updated.
Problem: if $block->setType is not called the block will not visibly update (it calls setBlock). I am not sure how to go about this.Plugins should call setBlock themselves after changing block properties.