func (inv *Inventory) UnmarshalNbt(tag *nbt.Compound) (err os.Error) { itemList, ok := tag.Lookup("Items").(*nbt.List) if !ok { return os.NewError("bad inventory - not a list") } for _, slotTagITag := range itemList.Value { slotTag, ok := slotTagITag.(*nbt.Compound) if !ok { return os.NewError("inventory slot not a compound") } var slotIdTag *nbt.Byte if slotIdTag, ok = slotTag.Lookup("Slot").(*nbt.Byte); !ok { return os.NewError("Slot ID not a byte") } slotId := types.SlotId(slotIdTag.Value) if err = inv.SlotUnmarshalNbt(slotTag, slotId); err != nil { return } } return nil }
// Click handles window clicks from a user with special handling for crafting. func (inv *CraftingInventory) Click(click *Click) (txState types.TxState) { if click.SlotId == 0 { // Player may only *take* the *whole* stack from the output slot. txState = inv.Inventory.TakeOnlyClick(click) } else { // Player may interact with the input slots like any other slot. txState = inv.Inventory.Click(click) } if txState == types.TxStateRejected { return } if click.SlotId == 0 { // Player took items from the output slot. Subtract 1 count from each // non-empty input slot. for i := 1; i < len(inv.slots); i++ { inv.slots[i].Decrement() inv.slotUpdate(&inv.slots[i], types.SlotId(i)) } } // Match recipe and set output slot. inv.slots[0] = inv.recipes.Match(inv.width, inv.height, inv.slots[1:]) inv.slotUpdate(&inv.slots[0], 0) return }
// TakeAllItems empties the inventory, and returns all items that were inside // it inside a slice of Slots. func (inv *Inventory) TakeAllItems() (items []Slot) { items = make([]Slot, 0, len(inv.slots)-1) for i := range inv.slots { curSlot := &inv.slots[i] if curSlot.Count > 0 { var taken Slot taken.Swap(curSlot) items = append(items, taken) inv.slotUpdate(curSlot, types.SlotId(i)) } } return }
// PutItem attempts to put the given item into the inventory. func (inv *Inventory) PutItem(item *Slot) { // TODO optimize this algorithm, maybe by maintaining a map of non-full // slots containing an item of various item type IDs. Additionally, it // should prefer to put stackable items into stacks of the same type, // rather than in empty slots. for slotIndex := range inv.slots { if item.Count <= 0 { break } slot := &inv.slots[slotIndex] if slot.Add(item) { inv.slotUpdate(slot, types.SlotId(slotIndex)) } } }
package gamerules import ( "os" "chunkymonkey/types" "nbt" ) const ( furnaceSlotReagent = types.SlotId(0) furnaceSlotFuel = types.SlotId(1) furnaceSlotOutput = types.SlotId(2) furnaceNumSlots = 3 reactionDuration = types.Ticks(185) maxFuelPrg = 255 ) type FurnaceInventory struct { Inventory burnTimeMax types.Ticks burnTime types.Ticks cookTime types.Ticks lastCurFuel types.PrgBarValue lastReactionRemaining types.PrgBarValue ticksSinceUpdate int } // NewFurnaceInventory creates a furnace inventory.
func (inv *Inventory) NumSlots() types.SlotId { return types.SlotId(len(inv.slots)) }