-
Notifications
You must be signed in to change notification settings - Fork 1
Wand / Brushes / mcstructures #8
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
Open
MakiTazo
wants to merge
6
commits into
iciency:main
Choose a base branch
from
MakiTazo:wand-stack
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
211e082
Fixed wand and added /stack command
MakiTazo 7c1da98
Fixed wand to avoid vanilla wooden axe
MakiTazo 89b0568
Fixed wand verification
MakiTazo a398c54
Added Brushes / Added mcstructure loading
MakiTazo 9c5e588
Updated
MakiTazo 32cdfb4
Updated
MakiTazo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,284 @@ | ||
| from endstone.inventory import ItemStack | ||
| from endstone.nbt import StringTag, CompoundTag, IntTag | ||
| from endstone_worldedit.utils import command_executor | ||
| import math | ||
|
|
||
| command = { | ||
| "brush": { | ||
| "description": "Binds a brush to the current item player is holding.", | ||
| "usages": [ | ||
| "/brush sphere <radius: int> <block: block> [-h: bool]", | ||
| "/brush cylinder <radius: int> <height: int> <block: block> [-h: bool]", | ||
| "/brush cube <radius: int> <block: block> [-h: bool]", | ||
| "/brush none" | ||
| ], | ||
| "permissions": ["worldedit.command.brush"] | ||
| } | ||
| } | ||
|
|
||
| @command_executor("brush") | ||
| def handler(plugin, sender, args): | ||
| if len(args) < 1: | ||
| sender.send_message("Usage: /brush <sphere|cylinder|cube|none> [args...]") | ||
| return False | ||
|
|
||
| brush_type = args[0].lower() | ||
| if brush_type == "none": | ||
| item = sender.inventory.item_in_main_hand | ||
| if item and item.nbt and "worldedit" in item.nbt and item.nbt["worldedit"].value == "brush": | ||
| item.nbt = CompoundTag() | ||
| sender.send_message("Brush unbound from current item.") | ||
| else: | ||
| sender.send_message("No brush bound to current item.") | ||
| return True | ||
|
|
||
| if brush_type not in ("sphere", "cylinder", "cube"): | ||
| sender.send_message("Invalid brush type. Use: sphere, cylinder, cube, or none.") | ||
| return False | ||
|
|
||
| hollow = False | ||
| filtered_args = [] | ||
| for arg in args[1:]: | ||
| if arg.lower() == "true": | ||
| hollow = True | ||
| elif arg.lower() == "false": | ||
| continue | ||
| else: | ||
| filtered_args.append(arg) | ||
|
|
||
| if brush_type == "sphere": | ||
| if len(filtered_args) < 2: | ||
| sender.send_message("Usage: /brush sphere <radius: int> <block: string> [-h]") | ||
| return False | ||
| try: | ||
| radius = int(filtered_args[0]) | ||
| except ValueError: | ||
| sender.send_message("Radius must be an integer.") | ||
| return False | ||
| if radius < 1: | ||
| sender.send_message("Radius must be a positive integer.") | ||
| return False | ||
| block_type = filtered_args[1] | ||
| _bind_brush_to_item(sender, brush_type, radius, block_type, hollow) | ||
|
|
||
| elif brush_type == "cylinder": | ||
| if len(filtered_args) < 3: | ||
| sender.send_message("Usage: /brush cylinder <radius: int> <height: int> <block: string> [-h]") | ||
| return False | ||
| try: | ||
| radius = int(filtered_args[0]) | ||
| height = int(filtered_args[1]) | ||
| except ValueError: | ||
| sender.send_message("Radius and height must be integers.") | ||
| return False | ||
| if radius < 1 or height < 1: | ||
| sender.send_message("Radius and height must be positive integers.") | ||
| return False | ||
| block_type = filtered_args[2] | ||
| _bind_brush_to_item(sender, brush_type, radius, block_type, hollow, height) | ||
|
|
||
| elif brush_type == "cube": | ||
| if len(filtered_args) < 2: | ||
| sender.send_message("Usage: /brush cube <radius: int> <block: string> [-h]") | ||
| return False | ||
| try: | ||
| radius = int(filtered_args[0]) | ||
| except ValueError: | ||
| sender.send_message("Radius must be an integer.") | ||
| return False | ||
| if radius < 1: | ||
| sender.send_message("Radius must be a positive integer.") | ||
| return False | ||
| block_type = filtered_args[1] | ||
| _bind_brush_to_item(sender, brush_type, radius, block_type, hollow) | ||
|
|
||
| return True | ||
|
|
||
| def _bind_brush_to_item(sender, brush_type, radius, block_type, hollow, height=None): | ||
| item = sender.inventory.item_in_main_hand | ||
| if not item or item.type == "minecraft:air": | ||
| sender.send_message("You must be holding an item.") | ||
| return False | ||
|
|
||
| if not block_type.startswith("minecraft:"): | ||
| block_type = f"minecraft:{block_type}" | ||
|
|
||
| brush_compound = CompoundTag({ | ||
| "type": StringTag(brush_type), | ||
| "radius": IntTag(radius), | ||
| "block": StringTag(block_type), | ||
| "hollow": StringTag("true" if hollow else "false"), | ||
| "mask": StringTag("none") | ||
| }) | ||
| if height is not None: | ||
| brush_compound["height"] = IntTag(height) | ||
|
|
||
| nbt = CompoundTag({ | ||
| "worldedit": StringTag("brush"), | ||
| "brush": brush_compound | ||
| }) | ||
|
|
||
| item.nbt = nbt | ||
|
|
||
| meta = item.item_meta | ||
| meta.display_name = f"§bBrush ({brush_type})" | ||
| lore = [ | ||
| f"§7Type: {brush_type}", | ||
| f"§7Radius: {radius}", | ||
| f"§7Block: {block_type}", | ||
| f"§7Hollow: {hollow}", | ||
| f"§7Mask: none" | ||
| ] | ||
| if height is not None: | ||
| lore.insert(2, f"§7Height: {height}") | ||
| meta.lore = lore | ||
| item.set_item_meta(meta) | ||
| slot = sender.inventory.held_item_slot | ||
| sender.inventory.set_item(slot, None) | ||
| sender.inventory.set_item(slot, item) | ||
|
|
||
| msg = f"{brush_type.capitalize()} brush bound to current item (radius: {radius}, block: {block_type}, hollow: {hollow})" | ||
| if height is not None: | ||
| msg = f"{brush_type.capitalize()} brush bound to current item (radius: {radius}, height: {height}, block: {block_type}, hollow: {hollow})" | ||
| sender.send_message(msg) | ||
| return True | ||
|
|
||
| def execute_brush(plugin, player, block, brush_data): | ||
| brush_type = brush_data["type"].value | ||
| radius = brush_data["radius"].value | ||
| block_type = brush_data["block"].value | ||
| hollow = brush_data["hollow"].value == "true" | ||
| mask = None | ||
| if "mask" in brush_data and brush_data["mask"].value != "none": | ||
| mask = brush_data["mask"].value | ||
| if "height" in brush_data: | ||
| height = brush_data["height"].value | ||
| else: | ||
| height = 1 | ||
|
|
||
| player_uuid = player.unique_id | ||
| dimension = player.dimension | ||
| cx, cy, cz = block.x, block.y, block.z | ||
| blocks_to_change = [] | ||
| if brush_type == "sphere": | ||
| for x in range(cx - radius, cx + radius + 1): | ||
| for y in range(cy - radius, cy + radius + 1): | ||
| for z in range(cz - radius, cz + radius + 1): | ||
| distance = math.sqrt((x - cx) ** 2 + (y - cy) ** 2 + (z - cz) ** 2) | ||
| if hollow: | ||
| if not (radius - 1 < distance <= radius): | ||
| continue | ||
| elif distance > radius: | ||
| continue | ||
| if mask: | ||
| try: | ||
| existing = dimension.get_block_at(x, y, z) | ||
| if str(existing.type) != mask: | ||
| continue | ||
| except RuntimeError: | ||
| continue | ||
| if block_type.startswith("minecraft:"): | ||
| blocks_to_change.append((x, y, z, block_type, None)) | ||
| else: | ||
| blocks_to_change.append((x, y, z, f"minecraft:{block_type}", None)) | ||
|
|
||
|
qodo-code-review[bot] marked this conversation as resolved.
|
||
| elif brush_type == "cylinder": | ||
| for y in range(cy, cy + height): | ||
| for x in range(cx - radius, cx + radius + 1): | ||
| for z in range(cz - radius, cz + radius + 1): | ||
| distance = math.sqrt((x - cx) ** 2 + (z - cz) ** 2) | ||
| if hollow: | ||
| if not (radius - 1 < distance <= radius): | ||
| continue | ||
| elif distance > radius: | ||
| continue | ||
|
|
||
| if mask: | ||
| try: | ||
| existing = dimension.get_block_at(x, y, z) | ||
| if existing.type != mask: | ||
| continue | ||
| except RuntimeError: | ||
| continue | ||
|
|
||
| if block_type.startswith("minecraft:"): | ||
| blocks_to_change.append((x, y, z, block_type, None)) | ||
| else: | ||
| blocks_to_change.append((x, y, z, f"minecraft:{block_type}", None)) | ||
|
|
||
| elif brush_type == "cube": | ||
| for x in range(cx - radius, cx + radius + 1): | ||
| for y in range(cy - radius, cy + radius + 1): | ||
| for z in range(cz - radius, cz + radius + 1): | ||
| if hollow: | ||
| is_surface = (x == cx - radius or x == cx + radius or | ||
| y == cy - radius or y == cy + radius or | ||
| z == cz - radius or z == cz + radius) | ||
| if not is_surface: | ||
| continue | ||
|
|
||
| if mask: | ||
| try: | ||
| existing = dimension.get_block_at(x, y, z) | ||
| if existing.type != mask: | ||
| continue | ||
| except RuntimeError: | ||
| continue | ||
|
|
||
| if block_type.startswith("minecraft:"): | ||
| blocks_to_change.append((x, y, z, block_type, None)) | ||
| else: | ||
| blocks_to_change.append((x, y, z, f"minecraft:{block_type}", None)) | ||
|
|
||
| if not blocks_to_change: | ||
| player.send_message("No blocks to change.") | ||
| return | ||
|
|
||
| undo_entry = [] | ||
| for x, y, z, _, _ in blocks_to_change: | ||
| try: | ||
| b = dimension.get_block_at(x, y, z) | ||
| undo_entry.append((x, y, z, b.type, b.data)) | ||
| except RuntimeError: | ||
| continue | ||
|
|
||
| if player_uuid not in plugin.undo_history: | ||
| plugin.undo_history[player_uuid] = [] | ||
| plugin.undo_history[player_uuid].append(undo_entry) | ||
| plugin.redo_history[player_uuid] = [] | ||
| if len(blocks_to_change) > plugin.plugin_config["async-threshold"]: | ||
| plugin.tasks[player_uuid] = {"dimension": dimension, "blocks": blocks_to_change} | ||
| player.send_message(f"Placing {len(blocks_to_change)} blocks asynchronously...") | ||
| else: | ||
| for x, y, z, bt, _ in blocks_to_change: | ||
| try: | ||
| b = dimension.get_block_at(x, y, z) | ||
| b.set_type(bt) | ||
| except RuntimeError: | ||
| continue | ||
| player.send_message(f"Brush placed {len(blocks_to_change)} blocks.") | ||
|
|
||
| def _get_target_block(player, max_distance=100): | ||
| """Raycast from player's eyes to find the first solid block they're looking at.""" | ||
| loc = player.location | ||
| direction = loc.direction | ||
| dimension = player.dimension | ||
| x, y, z = loc.x, loc.y + 1.62, loc.z | ||
| dx = direction.x | ||
| dy = direction.y | ||
| dz = direction.z | ||
| step = 0.5 | ||
| for i in range(int(max_distance / step)): | ||
| x += dx * step | ||
| y += dy * step | ||
| z += dz * step | ||
| block_x = int(math.floor(x)) | ||
| block_y = int(math.floor(y)) | ||
| block_z = int(math.floor(z)) | ||
| try: | ||
| block = dimension.get_block_at(block_x, block_y, block_z) | ||
| if block.type != "minecraft:air": | ||
| return block | ||
| except RuntimeError: | ||
| return None | ||
| return None | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
2. Item nbt overwritten
🐞 Bug☼ ReliabilityAgent Prompt
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools