-
Notifications
You must be signed in to change notification settings - Fork 155
creative items changes #1014
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
base: master
Are you sure you want to change the base?
creative items changes #1014
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,8 @@ import ( | |
_ "embed" | ||
"fmt" | ||
"github.com/df-mc/dragonfly/server/internal/nbtconv" | ||
"slices" | ||
|
||
// The following four imports are essential for this package: They make sure this package is loaded after | ||
// all these imports. This ensures that all blocks and items are registered before the creative items are | ||
// registered in the init function in this package. | ||
|
@@ -13,16 +15,6 @@ import ( | |
"github.com/sandertv/gophertunnel/minecraft/nbt" | ||
) | ||
|
||
// Item represents a registered item in the creative inventory. It holds a stack of the item and a group that | ||
// the item is part of. | ||
type Item struct { | ||
// Stack is the stack of the item that is registered in the creative inventory. | ||
Stack item.Stack | ||
// Group is the name of the group that the item is part of. If two groups are registered with the same | ||
// name, the item will always reside in the first group that was registered. | ||
Group string | ||
} | ||
|
||
// Group represents a group of items in the creative inventory. Each group has a category, a name and an icon. | ||
// If either the name or icon is empty, the group is considered an 'anonymous group' and will not group its | ||
// contents together in the creative inventory. | ||
|
@@ -34,12 +26,25 @@ type Group struct { | |
Name string | ||
// Icon is the item that will be displayed as the icon of the group in the creative inventory. | ||
Icon item.Stack | ||
// Items are all items that are that belong to this Group. | ||
Items []item.Stack | ||
} | ||
|
||
// Groups returns a list with all groups that have been registered as a creative group. These groups will be | ||
// accessible by players in-game who have creative mode enabled. | ||
func Groups() []Group { | ||
return creativeGroups | ||
groups := slices.Clone(creativeGroups) | ||
for _, it := range items { | ||
if it.GroupIndex >= int32(len(groups)) { | ||
panic(fmt.Errorf("invalid group index %v for item %v", it.GroupIndex, it.Name)) | ||
} | ||
st, ok := itemStackFromEntry(it) | ||
if !ok { | ||
continue | ||
} | ||
groups[it.GroupIndex].Items = append(groups[it.GroupIndex].Items, st) | ||
} | ||
return groups | ||
} | ||
|
||
// RegisterGroup registers a group as a creative group, exposing it in the creative inventory. It can then | ||
|
@@ -48,27 +53,15 @@ func RegisterGroup(group Group) { | |
creativeGroups = append(creativeGroups, group) | ||
} | ||
|
||
// Items returns a list with all items that have been registered as a creative item. These items will | ||
// be accessible by players in-game who have creative mode enabled. | ||
func Items() []Item { | ||
return creativeItemStacks | ||
} | ||
|
||
// RegisterItem registers an item as a creative item, exposing it in the creative inventory. | ||
func RegisterItem(item Item) { | ||
creativeItemStacks = append(creativeItemStacks, item) | ||
} | ||
|
||
var ( | ||
//go:embed creative_items.nbt | ||
creativeItemData []byte | ||
|
||
// creativeGroups holds a list of all groups that were registered to the creative inventory using | ||
// RegisterGroup. | ||
creativeGroups []Group | ||
// creativeItemStacks holds a list of all item stacks that were registered to the creative inventory using | ||
// RegisterItem. | ||
creativeItemStacks []Item | ||
// items holds a list of all item stacks that were registered to the creative inventory. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They are not item stacks at this point |
||
items []creativeItemEntry | ||
) | ||
|
||
// creativeGroupEntry holds data of a creative group as present in the creative inventory. | ||
|
@@ -97,6 +90,7 @@ func init() { | |
if err := nbt.Unmarshal(creativeItemData, &m); err != nil { | ||
panic(err) | ||
} | ||
items = m.Items | ||
for i, group := range m.Groups { | ||
name := group.Name | ||
if name == "" { | ||
|
@@ -106,16 +100,6 @@ func init() { | |
c := Category{category(group.Category)} | ||
RegisterGroup(Group{Category: c, Name: name, Icon: st}) | ||
} | ||
for _, data := range m.Items { | ||
if data.GroupIndex >= int32(len(creativeGroups)) { | ||
panic(fmt.Errorf("invalid group index %v for item %v", data.GroupIndex, data.Name)) | ||
} | ||
st, ok := itemStackFromEntry(data) | ||
if !ok { | ||
continue | ||
} | ||
RegisterItem(Item{st, creativeGroups[data.GroupIndex].Name}) | ||
} | ||
} | ||
|
||
func itemStackFromEntry(data creativeItemEntry) (item.Stack, bool) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -159,15 +159,29 @@ func (h *ItemStackRequestHandler) handleCreativeCraft(a *protocol.CraftCreativeS | |
if !c.GameMode().CreativeInventory() { | ||
return fmt.Errorf("can only craft creative items in gamemode creative/spectator") | ||
} | ||
index := a.CreativeItemNetworkID - 1 | ||
if int(index) >= len(creative.Items()) { | ||
return fmt.Errorf("creative item with network ID %v does not exist", index) | ||
index := int(a.CreativeItemNetworkID - 1) | ||
|
||
it, err := itemByIndex(s.conf.CreativeGroups, index) | ||
if err != nil { | ||
return err | ||
} | ||
it := creative.Items()[index].Stack | ||
|
||
it = it.Grow(it.MaxCount() - 1) | ||
return h.createResults(s, tx, it) | ||
} | ||
|
||
// itemByIndex returns creative item by index. | ||
func itemByIndex(groups []creative.Group, index int) (item.Stack, error) { | ||
Comment on lines
+173
to
+174
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Name and documentation could be better here, document how it works and the case where it returns an error |
||
offset := 0 | ||
for _, group := range groups { | ||
if offset+len(group.Items) > index { | ||
return group.Items[index-offset], nil | ||
} | ||
offset += len(group.Items) | ||
} | ||
return item.Stack{}, fmt.Errorf("creative item with network ID %v does not exist", index) | ||
} | ||
|
||
// craftingSize gets the crafting size based on the opened container ID. | ||
func (s *Session) craftingSize() uint32 { | ||
if s.openedContainerID.Load() == 1 { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,7 +20,6 @@ import ( | |
"github.com/sandertv/gophertunnel/minecraft/protocol/packet" | ||
"math" | ||
"net" | ||
"slices" | ||
"time" | ||
_ "unsafe" // Imported for compiler directives. | ||
) | ||
|
@@ -834,30 +833,27 @@ func stacksToIngredientItems(inputs []recipe.Item) []protocol.ItemDescriptorCoun | |
} | ||
|
||
// creativeContent returns all creative groups, and creative inventory items as protocol item stacks. | ||
func creativeContent() ([]protocol.CreativeGroup, []protocol.CreativeItem) { | ||
groups := make([]protocol.CreativeGroup, 0, len(creative.Groups())) | ||
for _, group := range creative.Groups() { | ||
func creativeContent(creativeGroups []creative.Group) ([]protocol.CreativeGroup, []protocol.CreativeItem) { | ||
groups := make([]protocol.CreativeGroup, 0, len(creativeGroups)) | ||
it := make([]protocol.CreativeItem, 0, len(creativeGroups)*10) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are you multiplying by 10? |
||
|
||
var itemIdx uint32 | ||
for index, group := range creativeGroups { | ||
groups = append(groups, protocol.CreativeGroup{ | ||
Category: int32(group.Category.Uint8()), | ||
Name: group.Name, | ||
Icon: deleteDamage(stackFromItem(group.Icon)), | ||
}) | ||
} | ||
|
||
it := make([]protocol.CreativeItem, 0, len(creative.Items())) | ||
for index, i := range creative.Items() { | ||
group := slices.IndexFunc(creative.Groups(), func(group creative.Group) bool { | ||
return group.Name == i.Group | ||
}) | ||
if group < 0 { | ||
continue | ||
for _, stack := range group.Items { | ||
itemIdx++ | ||
it = append(it, protocol.CreativeItem{ | ||
CreativeItemNetworkID: itemIdx, | ||
Item: deleteDamage(stackFromItem(stack)), | ||
GroupIndex: uint32(index), | ||
}) | ||
} | ||
it = append(it, protocol.CreativeItem{ | ||
CreativeItemNetworkID: uint32(index) + 1, | ||
Item: deleteDamage(stackFromItem(i.Stack)), | ||
GroupIndex: uint32(group), | ||
}) | ||
} | ||
|
||
return groups, it | ||
} | ||
|
||
|
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.
Not sure why this was removed, as I said on discord:
I dont really know how we should do this, we need a way for people to register their own groups but also inject into vanilla groups