增加堆叠限制和排序
This commit is contained in:
parent
b8f625d7c8
commit
02e4cad427
|
@ -3,6 +3,7 @@ package builtin
|
||||||
import (
|
import (
|
||||||
"github.com/kercylan98/minotaur/game"
|
"github.com/kercylan98/minotaur/game"
|
||||||
"github.com/kercylan98/minotaur/utils/huge"
|
"github.com/kercylan98/minotaur/utils/huge"
|
||||||
|
"github.com/kercylan98/minotaur/utils/super"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -10,7 +11,6 @@ func NewItemContainer[ItemID comparable, Item game.Item[ItemID]](options ...Item
|
||||||
itemContainer := &ItemContainer[ItemID, Item]{
|
itemContainer := &ItemContainer[ItemID, Item]{
|
||||||
items: map[int64]*ItemContainerMember[ItemID, Item]{},
|
items: map[int64]*ItemContainerMember[ItemID, Item]{},
|
||||||
itemIdGuidRef: map[ItemID]map[int64]bool{},
|
itemIdGuidRef: map[ItemID]map[int64]bool{},
|
||||||
stackLimits: map[ItemID]*huge.Int{},
|
|
||||||
}
|
}
|
||||||
for _, option := range options {
|
for _, option := range options {
|
||||||
option(itemContainer)
|
option(itemContainer)
|
||||||
|
@ -25,16 +25,18 @@ type ItemContainer[ItemID comparable, Item game.Item[ItemID]] struct {
|
||||||
expandSize int
|
expandSize int
|
||||||
items map[int64]*ItemContainerMember[ItemID, Item]
|
items map[int64]*ItemContainerMember[ItemID, Item]
|
||||||
itemIdGuidRef map[ItemID]map[int64]bool
|
itemIdGuidRef map[ItemID]map[int64]bool
|
||||||
sort []*itemContainerSort[ItemID]
|
sort []*int64
|
||||||
stackLimits map[ItemID]*huge.Int
|
maxSort int
|
||||||
|
vacancy []int
|
||||||
|
stackLimit map[ItemID]*huge.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slf *ItemContainer[ItemID, Item]) GetSize() int {
|
func (slf *ItemContainer[ItemID, Item]) GetSize() int {
|
||||||
return slf.size + slf.expandSize
|
return slf.size
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slf *ItemContainer[ItemID, Item]) GetSizeLimit() int {
|
func (slf *ItemContainer[ItemID, Item]) GetSizeLimit() int {
|
||||||
return slf.sizeLimit
|
return slf.sizeLimit + slf.expandSize
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slf *ItemContainer[ItemID, Item]) SetExpandSize(size int) {
|
func (slf *ItemContainer[ItemID, Item]) SetExpandSize(size int) {
|
||||||
|
@ -50,8 +52,26 @@ func (slf *ItemContainer[ItemID, Item]) GetItem(guid int64) (game.ItemContainerM
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slf *ItemContainer[ItemID, Item]) GetItems() []game.ItemContainerMember[ItemID, Item] {
|
func (slf *ItemContainer[ItemID, Item]) GetItems() []game.ItemContainerMember[ItemID, Item] {
|
||||||
//TODO implement me
|
var result = make([]game.ItemContainerMember[ItemID, Item], 0, len(slf.sort))
|
||||||
panic("implement me")
|
for _, guid := range slf.sort {
|
||||||
|
if guid == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result = append(result, slf.items[*guid])
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *ItemContainer[ItemID, Item]) GetItemsFull() []game.ItemContainerMember[ItemID, Item] {
|
||||||
|
var result = make([]game.ItemContainerMember[ItemID, Item], len(slf.sort), len(slf.sort))
|
||||||
|
for i, guid := range slf.sort {
|
||||||
|
if guid == nil {
|
||||||
|
result[i] = nil
|
||||||
|
} else {
|
||||||
|
result[i] = slf.items[*guid]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slf *ItemContainer[ItemID, Item]) GetItemsMap() map[int64]game.ItemContainerMember[ItemID, Item] {
|
func (slf *ItemContainer[ItemID, Item]) GetItemsMap() map[int64]game.ItemContainerMember[ItemID, Item] {
|
||||||
|
@ -78,6 +98,9 @@ func (slf *ItemContainer[ItemID, Item]) AddItem(item Item, count *huge.Int) erro
|
||||||
for guid := range slf.itemIdGuidRef[item.GetID()] {
|
for guid := range slf.itemIdGuidRef[item.GetID()] {
|
||||||
member := slf.items[guid]
|
member := slf.items[guid]
|
||||||
if member.GetItem().IsSame(item) {
|
if member.GetItem().IsSame(item) {
|
||||||
|
if stackLimit := slf.stackLimit[item.GetID()]; stackLimit != nil && member.count.Copy().Add(count).GreaterThan(stackLimit) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
member.count.Add(count)
|
member.count.Add(count)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -90,6 +113,22 @@ func (slf *ItemContainer[ItemID, Item]) AddItem(item Item, count *huge.Int) erro
|
||||||
item: item,
|
item: item,
|
||||||
guid: guid,
|
guid: guid,
|
||||||
count: count.Copy(),
|
count: count.Copy(),
|
||||||
|
sort: super.If(len(slf.vacancy) == 0,
|
||||||
|
func() int {
|
||||||
|
sort := len(slf.sort)
|
||||||
|
slf.sort = append(slf.sort, &guid)
|
||||||
|
if sort > slf.maxSort {
|
||||||
|
slf.maxSort = sort
|
||||||
|
}
|
||||||
|
return sort
|
||||||
|
}(),
|
||||||
|
func() int {
|
||||||
|
sort := slf.vacancy[0]
|
||||||
|
slf.vacancy = slf.vacancy[1:]
|
||||||
|
slf.sort[sort] = &guid
|
||||||
|
return sort
|
||||||
|
}(),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
guids, exist := slf.itemIdGuidRef[item.GetID()]
|
guids, exist := slf.itemIdGuidRef[item.GetID()]
|
||||||
if !exist {
|
if !exist {
|
||||||
|
@ -110,7 +149,14 @@ func (slf *ItemContainer[ItemID, Item]) DeductItem(guid int64, count *huge.Int)
|
||||||
member.count.Sub(count)
|
member.count.Sub(count)
|
||||||
if member.count.EqualTo(huge.IntZero) {
|
if member.count.EqualTo(huge.IntZero) {
|
||||||
slf.size--
|
slf.size--
|
||||||
|
slf.sort[member.sort] = nil
|
||||||
|
slf.vacancy = append(slf.vacancy, member.sort)
|
||||||
delete(slf.items, guid)
|
delete(slf.items, guid)
|
||||||
|
sizeLimit := slf.GetSizeLimit()
|
||||||
|
for slf.sort[slf.maxSort] == nil && slf.maxSort > sizeLimit {
|
||||||
|
slf.sort = append(slf.sort[0:slf.maxSort], slf.sort[slf.maxSort+1:]...)
|
||||||
|
slf.maxSort--
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
|
@ -129,6 +175,13 @@ func (slf *ItemContainer[ItemID, Item]) DeductItem(guid int64, count *huge.Int)
|
||||||
if len(guids) == 0 {
|
if len(guids) == 0 {
|
||||||
delete(slf.itemIdGuidRef, member.GetID())
|
delete(slf.itemIdGuidRef, member.GetID())
|
||||||
}
|
}
|
||||||
|
slf.sort[member.sort] = nil
|
||||||
|
slf.vacancy = append(slf.vacancy, member.sort)
|
||||||
|
sizeLimit := slf.GetSizeLimit()
|
||||||
|
for slf.sort[slf.maxSort] == nil && slf.maxSort > sizeLimit {
|
||||||
|
slf.sort = append(slf.sort[0:slf.maxSort], slf.sort[slf.maxSort+1:]...)
|
||||||
|
slf.maxSort--
|
||||||
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
member.count.Sub(need)
|
member.count.Sub(need)
|
||||||
|
|
|
@ -13,11 +13,10 @@ func NewItemContainerMember[ItemID comparable, I game.Item[ItemID]](guid int64,
|
||||||
}
|
}
|
||||||
|
|
||||||
type ItemContainerMember[ItemID comparable, I game.Item[ItemID]] struct {
|
type ItemContainerMember[ItemID comparable, I game.Item[ItemID]] struct {
|
||||||
item I
|
item I
|
||||||
guid int64
|
guid int64
|
||||||
sort int
|
sort int
|
||||||
count *huge.Int
|
count *huge.Int
|
||||||
bakCount *huge.Int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slf *ItemContainerMember[ItemID, I]) GetID() ItemID {
|
func (slf *ItemContainerMember[ItemID, I]) GetID() ItemID {
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package builtin
|
package builtin
|
||||||
|
|
||||||
import "github.com/kercylan98/minotaur/game"
|
import (
|
||||||
|
"github.com/kercylan98/minotaur/game"
|
||||||
|
"github.com/kercylan98/minotaur/utils/huge"
|
||||||
|
)
|
||||||
|
|
||||||
type ItemContainerOption[ItemID comparable, Item game.Item[ItemID]] func(container *ItemContainer[ItemID, Item])
|
type ItemContainerOption[ItemID comparable, Item game.Item[ItemID]] func(container *ItemContainer[ItemID, Item])
|
||||||
|
|
||||||
|
@ -13,3 +16,16 @@ func WithItemContainerSizeLimit[ItemID comparable, Item game.Item[ItemID]](sizeL
|
||||||
container.sizeLimit = sizeLimit
|
container.sizeLimit = sizeLimit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithItemContainerStackLimit 通过设置特定物品堆叠数量创建容器
|
||||||
|
func WithItemContainerStackLimit[ItemID comparable, Item game.Item[ItemID]](id ItemID, stackLimit *huge.Int) ItemContainerOption[ItemID, Item] {
|
||||||
|
return func(container *ItemContainer[ItemID, Item]) {
|
||||||
|
if stackLimit.LessThanOrEqualTo(huge.IntZero) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if container.stackLimit == nil {
|
||||||
|
container.stackLimit = map[ItemID]*huge.Int{}
|
||||||
|
}
|
||||||
|
container.stackLimit[id] = stackLimit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,18 +10,24 @@ type ItemContainer[ItemID comparable, I Item[ItemID]] interface {
|
||||||
GetSizeLimit() int
|
GetSizeLimit() int
|
||||||
// SetExpandSize 设置拓展非堆叠数量上限
|
// SetExpandSize 设置拓展非堆叠数量上限
|
||||||
SetExpandSize(size int)
|
SetExpandSize(size int)
|
||||||
|
|
||||||
// GetItem 获取物品
|
// GetItem 获取物品
|
||||||
GetItem(guid int64) (ItemContainerMember[ItemID, I], error)
|
GetItem(guid int64) (ItemContainerMember[ItemID, I], error)
|
||||||
// GetItems 获取所有物品
|
// GetItems 获取所有非空物品
|
||||||
|
// - 物品顺序为容器内顺序
|
||||||
|
// - 空的容器空间将被忽略
|
||||||
GetItems() []ItemContainerMember[ItemID, I]
|
GetItems() []ItemContainerMember[ItemID, I]
|
||||||
|
// GetItemsFull 获取所有物品
|
||||||
|
// - 物品顺序为容器内顺序
|
||||||
|
// - 空的容器空间将被设置为nil
|
||||||
|
// - 当容器非堆叠物品上限为0时,最后一个非空物品之后的所有空物品都将被忽略
|
||||||
|
// - 当容器非堆叠物品未达到上限时,其余空间将使用nil填充
|
||||||
|
GetItemsFull() []ItemContainerMember[ItemID, I]
|
||||||
// GetItemsMap 获取所有物品
|
// GetItemsMap 获取所有物品
|
||||||
GetItemsMap() map[int64]ItemContainerMember[ItemID, I]
|
GetItemsMap() map[int64]ItemContainerMember[ItemID, I]
|
||||||
// ExistItem 物品是否存在
|
// ExistItem 物品是否存在
|
||||||
ExistItem(guid int64) bool
|
ExistItem(guid int64) bool
|
||||||
// ExistItemWithID 是否存在特定ID的物品
|
// ExistItemWithID 是否存在特定ID的物品
|
||||||
ExistItemWithID(id ItemID) bool
|
ExistItemWithID(id ItemID) bool
|
||||||
|
|
||||||
// AddItem 添加物品
|
// AddItem 添加物品
|
||||||
AddItem(item I, count *huge.Int) error
|
AddItem(item I, count *huge.Int) error
|
||||||
// DeductItem 扣除特定物品数量,当数量为0将被移除,数量不足时将不进行任何改变
|
// DeductItem 扣除特定物品数量,当数量为0将被移除,数量不足时将不进行任何改变
|
||||||
|
|
Loading…
Reference in New Issue