388 lines
5.5 KiB
Markdown
388 lines
5.5 KiB
Markdown
---
|
|
title: Scripted Brushes
|
|
type: docs
|
|
weight: 1
|
|
---
|
|
|
|
Scripted brushes allow creating complex, programmable brush operations through JSON asset definitions.
|
|
|
|
**Package:** `com.hypixel.hytale.builtin.buildertools.scriptedbrushes`
|
|
|
|
## Architecture
|
|
|
|
```
|
|
Scripted Brushes
|
|
├── Assets
|
|
│ └── ScriptedBrushAsset - Brush definitions
|
|
├── Operations
|
|
│ ├── BrushOperation - Base operation class
|
|
│ ├── SequenceBrushOperation - Sequential operations
|
|
│ └── GlobalBrushOperation - Global modifiers
|
|
├── Categories
|
|
│ ├── Shape Operations - Set, fill, shape
|
|
│ ├── Mask Operations - Mask, history mask
|
|
│ ├── Flow Control - Loops, jumps, conditions
|
|
│ ├── Material Operations - Pattern, replace
|
|
│ └── Transform Operations - Offset, dimensions
|
|
├── Config
|
|
│ ├── BrushConfig - Runtime configuration
|
|
│ └── BrushConfigEditStore - Edit state
|
|
└── Commands
|
|
└── BrushConfigCommand - /brushconfig
|
|
```
|
|
|
|
## ScriptedBrushAsset
|
|
|
|
Brush definitions loaded from JSON:
|
|
|
|
**Asset Location:** `BuilderTools/Brushes/`
|
|
|
|
```yaml
|
|
# BuilderTools/Brushes/terrain_sphere.json
|
|
{
|
|
"Id": "terrain_sphere",
|
|
"Operations": [
|
|
{
|
|
"Type": "Shape",
|
|
"Shape": "Sphere"
|
|
},
|
|
{
|
|
"Type": "Dimensions",
|
|
"Width": 5,
|
|
"Height": 5,
|
|
"Depth": 5
|
|
},
|
|
{
|
|
"Type": "Material",
|
|
"Pattern": "[Rock_Stone]"
|
|
},
|
|
{
|
|
"Type": "Set"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Asset Access
|
|
|
|
```java
|
|
// Get brush asset
|
|
ScriptedBrushAsset brush = ScriptedBrushAsset.get("terrain_sphere");
|
|
|
|
// Get operations
|
|
List<BrushOperation> operations = brush.getOperations();
|
|
|
|
// Load into executor
|
|
brush.loadIntoExecutor(executor);
|
|
```
|
|
|
|
## Operation Types
|
|
|
|
### Shape Operations
|
|
|
|
| Operation | Description |
|
|
|-----------|-------------|
|
|
| `Set` | Apply blocks at positions |
|
|
| `Shape` | Define brush shape (Sphere, Cube, Cylinder) |
|
|
| `Delete` | Remove blocks |
|
|
| `Smooth` | Smooth terrain |
|
|
| `Erode` | Erode terrain |
|
|
| `Lift` | Raise terrain |
|
|
| `Melt` | Melt terrain |
|
|
|
|
```yaml
|
|
{
|
|
"Type": "Shape",
|
|
"Shape": "Sphere" // Sphere, Cube, Cylinder
|
|
}
|
|
```
|
|
|
|
### Dimension Operations
|
|
|
|
```yaml
|
|
{
|
|
"Type": "Dimensions",
|
|
"Width": 10,
|
|
"Height": 5,
|
|
"Depth": 10
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "RandomizeDimensions",
|
|
"MinWidth": 3,
|
|
"MaxWidth": 7,
|
|
"MinHeight": 3,
|
|
"MaxHeight": 7
|
|
}
|
|
```
|
|
|
|
### Material Operations
|
|
|
|
```yaml
|
|
{
|
|
"Type": "Material",
|
|
"Pattern": "[50%Rock_Stone, 50%Rock_Shale]"
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "BlockPattern",
|
|
"Pattern": "[Rock_Stone]"
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "Replace",
|
|
"From": "[Grass]",
|
|
"To": "[Dirt]"
|
|
}
|
|
```
|
|
|
|
### Mask Operations
|
|
|
|
```yaml
|
|
{
|
|
"Type": "Mask",
|
|
"Mask": "[!Air]"
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "AppendMask",
|
|
"Mask": "[!Water]"
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "HistoryMask"
|
|
// Only affect previously modified blocks
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "UseBrushMask"
|
|
// Use mask from tool arguments
|
|
}
|
|
```
|
|
|
|
### Offset Operations
|
|
|
|
```yaml
|
|
{
|
|
"Type": "Offset",
|
|
"X": 0,
|
|
"Y": 5,
|
|
"Z": 0
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "RandomOffset",
|
|
"MinX": -2,
|
|
"MaxX": 2,
|
|
"MinY": 0,
|
|
"MaxY": 5,
|
|
"MinZ": -2,
|
|
"MaxZ": 2
|
|
}
|
|
```
|
|
|
|
### Flow Control
|
|
|
|
#### Loops
|
|
|
|
```yaml
|
|
{
|
|
"Type": "Loop",
|
|
"Count": 5,
|
|
"StartIndex": 2,
|
|
"EndIndex": 6
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "LoopRandom",
|
|
"MinCount": 3,
|
|
"MaxCount": 8
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "CircleOffsetAndLoop",
|
|
"Radius": 5,
|
|
"Count": 8
|
|
}
|
|
```
|
|
|
|
#### Conditionals
|
|
|
|
```yaml
|
|
{
|
|
"Type": "JumpIfBlockType",
|
|
"BlockType": "Air",
|
|
"Index": 10,
|
|
"ElseIndex": 5
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "JumpIfClickType",
|
|
"ClickType": "Primary",
|
|
"Index": 3
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "JumpIfCompare",
|
|
"Variable": "height",
|
|
"Operator": ">",
|
|
"Value": 5,
|
|
"Index": 8
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "JumpToIndex",
|
|
"Index": 0
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "Exit"
|
|
// Stop brush execution
|
|
}
|
|
```
|
|
|
|
### Special Operations
|
|
|
|
```yaml
|
|
{
|
|
"Type": "Echo",
|
|
"Message": "Brush applied!"
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "RunCommand",
|
|
"Command": "/fill [Stone]"
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "PastePrefab",
|
|
"PrefabId": "tree_oak"
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "HeightmapLayer",
|
|
"Layer": 0
|
|
}
|
|
```
|
|
|
|
### Save/Load Operations
|
|
|
|
```yaml
|
|
{
|
|
"Type": "LoadOperationsFromAsset",
|
|
"AssetId": "common_setup"
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "SaveBrushConfig",
|
|
"Key": "my_config"
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "LoadBrushConfig",
|
|
"Key": "my_config"
|
|
}
|
|
```
|
|
|
|
## Global Operations
|
|
|
|
Operations that affect the entire brush:
|
|
|
|
```yaml
|
|
{
|
|
"Type": "Debug",
|
|
"Enabled": true
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "DisableHoldInteraction"
|
|
// Only trigger on click, not hold
|
|
}
|
|
```
|
|
|
|
```yaml
|
|
{
|
|
"Type": "IgnoreExistingBrushData"
|
|
}
|
|
```
|
|
|
|
## Brush Config Command
|
|
|
|
Manage brush configurations via command:
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `/brushconfig` | Base brush config command |
|
|
| `/brushconfig load <id>` | Load brush config |
|
|
| `/brushconfig list` | List available brushes |
|
|
| `/brushconfig clear` | Clear current config |
|
|
| `/brushconfig exit` | Exit brush mode |
|
|
| `/brushconfig debugstep` | Step through operations |
|
|
|
|
## API Usage
|
|
|
|
### Load Brush
|
|
|
|
```java
|
|
ScriptedBrushAsset brush = ScriptedBrushAsset.get("terrain_sphere");
|
|
```
|
|
|
|
### Execute Brush
|
|
|
|
```java
|
|
BrushConfigCommandExecutor executor = new BrushConfigCommandExecutor();
|
|
brush.loadIntoExecutor(executor);
|
|
// Execute operations sequentially
|
|
```
|
|
|
|
### Access Operations
|
|
|
|
```java
|
|
List<BrushOperation> operations = brush.getOperations();
|
|
for (BrushOperation op : operations) {
|
|
if (op instanceof SequenceBrushOperation) {
|
|
// Sequential operation
|
|
} else if (op instanceof GlobalBrushOperation) {
|
|
// Global modifier
|
|
}
|
|
}
|
|
```
|