26ed99fda6
Build and deploy / Build (push) Has been cancelled
Build and deploy / Update Contributors (push) Has been cancelled
Build and deploy / Deploy (push) Has been cancelled
121 lines
3.6 KiB
Go
121 lines
3.6 KiB
Go
package recipe
|
|
|
|
import (
|
|
"github.com/df-mc/dragonfly/server/item"
|
|
"github.com/df-mc/dragonfly/server/world"
|
|
)
|
|
|
|
// DecoratedPotRecipe is a dynamic recipe for crafting decorated pots. The output depends on which
|
|
// pottery sherds or bricks are used in the crafting grid.
|
|
type DecoratedPotRecipe struct {
|
|
block string
|
|
}
|
|
|
|
// NewDecoratedPotRecipe creates a new decorated pot recipe.
|
|
func NewDecoratedPotRecipe() DecoratedPotRecipe {
|
|
return DecoratedPotRecipe{block: "crafting_table"}
|
|
}
|
|
|
|
// potDecoration is a local interface to check if an item can be used as a pot decoration
|
|
// without importing the block package (which would create an import cycle).
|
|
type potDecoration interface {
|
|
world.Item
|
|
PotDecoration() bool
|
|
}
|
|
|
|
// Match checks if the given input items match the decorated pot recipe pattern.
|
|
// The pattern requires exactly 4 PotDecoration items (bricks or pottery sherds) in a diamond/plus shape:
|
|
// - Slot 1 (top centre)
|
|
// - Slot 3 (middle left)
|
|
// - Slot 5 (middle right)
|
|
// - Slot 7 (bottom centre)
|
|
// All other slots must be empty.
|
|
func (r DecoratedPotRecipe) Match(input []Item) (output []item.Stack, ok bool) {
|
|
// For a 3x3 crafting grid, we need exactly 9 slots
|
|
if len(input) != 9 {
|
|
return nil, false
|
|
}
|
|
|
|
// Define the slots for the diamond pattern (0-indexed)
|
|
// Layout: 0 1 2
|
|
// 3 4 5
|
|
// 6 7 8
|
|
// We need items at: 1 (top), 3 (left), 5 (right), 7 (bottom)
|
|
// Odd indices should have items, even indices should be empty
|
|
|
|
decorations := [4]world.Item{}
|
|
decorationIndex := 0
|
|
for i := range input {
|
|
it := input[i]
|
|
if i%2 == 0 {
|
|
// Even slots (0, 2, 4, 6, 8) should be empty
|
|
if !it.Empty() {
|
|
return nil, false
|
|
}
|
|
} else {
|
|
// Odd slots (1, 3, 5, 7) should have items
|
|
if it.Empty() {
|
|
return nil, false
|
|
}
|
|
|
|
// Extract the actual item from the Item interface
|
|
var actualItem item.Stack
|
|
if v, ok := it.(item.Stack); ok {
|
|
actualItem = v
|
|
} else {
|
|
// ItemTag or other types are not valid for decorated pots
|
|
return nil, false
|
|
}
|
|
|
|
// Check if the item implements PotDecoration
|
|
decoration, ok := actualItem.Item().(potDecoration)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
decorations[decorationIndex] = decoration
|
|
decorationIndex++
|
|
}
|
|
}
|
|
|
|
// Create the decorated pot by encoding the decorations into NBT
|
|
// We'll use world.BlockByName to get the DecoratedPot block and set its decorations
|
|
// The decorations are ordered: [top, left, right, bottom] in the crafting grid
|
|
// For the pot NBT: [back, left, front, right] based on facing direction
|
|
|
|
// Get a decorated pot block instance
|
|
pot, ok := world.BlockByName("minecraft:decorated_pot", map[string]any{"direction": int32(2)})
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
|
|
// The pot will be decoded with the decorations through NBT when placed
|
|
// For now, we'll create a pot with the decorations in the correct order
|
|
// DecoratedPot.DecodeNBT expects sherds in order: [back, left, front, right]
|
|
sherds := []any{}
|
|
// Order: top -> back, left -> left, bottom -> front, right -> right
|
|
for _, idx := range []int{0, 1, 3, 2} { // top, left, bottom, right
|
|
name, _ := decorations[idx].EncodeItem()
|
|
sherds = append(sherds, name)
|
|
}
|
|
|
|
// Decode the pot with the sherds NBT data using type assertion
|
|
if nbtDecoder, ok := pot.(interface {
|
|
DecodeNBT(map[string]any) any
|
|
}); ok {
|
|
decodedPot := nbtDecoder.DecodeNBT(map[string]any{
|
|
"id": "DecoratedPot",
|
|
"sherds": sherds,
|
|
})
|
|
if potItem, ok := decodedPot.(world.Item); ok {
|
|
return []item.Stack{item.NewStack(potItem, 1)}, true
|
|
}
|
|
}
|
|
|
|
return nil, false
|
|
}
|
|
|
|
// Block returns the block used to craft this recipe.
|
|
func (r DecoratedPotRecipe) Block() string {
|
|
return r.block
|
|
}
|