;; inventory-system.clar
;; Game-like inventory management
;; Constants
(define-constant contract-owner tx-sender)
(define-constant err-owner-only (err u100))
(define-constant err-not-found (err u101))
(define-constant err-insufficient-quantity (err u102))
(define-constant err-inventory-full (err u103))
;; Data Maps
(define-map items
{ item-id: uint }
{
name: (string-ascii 32),
type: (string-ascii 16),
max-stack: uint,
}
)
(define-map inventory
{
user: principal,
item-id: uint,
}
{ quantity: uint }
)
(define-map user-slots
{ user: principal }
{
slots: uint,
used: uint,
}
)
;; Variables
(define-data-var next-item-id uint u1)
(define-data-var default-slots uint u20)
;; Read-only functions
(define-read-only (get-item (item-id uint))
(map-get? items { item-id: item-id })
)
(define-read-only (get-balance
(user principal)
(item-id uint)
)
(default-to u0
(get quantity
(map-get? inventory {
user: user,
item-id: item-id,
})
))
)
(define-read-only (get-slots (user principal))
(default-to {
slots: (var-get default-slots),
used: u0,
}
(map-get? user-slots { user: user })
)
)
(define-read-only (get-next-item-id)
(var-get next-item-id)
)
;; Public functions
(define-public (create-item
(name (string-ascii 32))
(type (string-ascii 16))
(max-stack uint)
)
(let ((id (var-get next-item-id)))
(asserts! (is-eq tx-sender contract-owner) err-owner-only)
(map-set items { item-id: id } {
name: name,
type: type,
max-stack: max-stack,
})
(var-set next-item-id (+ id u1))
(ok id)
)
)
(define-public (add-item
(user principal)
(item-id uint)
(amount uint)
)
(let (
(slots (get-slots user))
(current-bal (get-balance user item-id))
)
(asserts! (is-eq tx-sender contract-owner) err-owner-only)
(match (map-get? items { item-id: item-id })
item (begin
(if (is-eq current-bal u0)
(asserts! (< (get used slots) (get slots slots))
err-inventory-full
)
true
)
(map-set inventory {
user: user,
item-id: item-id,
} { quantity: (+ current-bal amount) }
)
(if (is-eq current-bal u0)
(map-set user-slots { user: user }
(merge slots { used: (+ (get used slots) u1) })
)
true
)
(ok true)
)
err-not-found
)
)
)
(define-public (remove-item
(user principal)
(item-id uint)
(amount uint)
)
(let (
(current-bal (get-balance user item-id))
(slots (get-slots user))
)
(asserts! (is-eq tx-sender contract-owner) err-owner-only)
(asserts! (>= current-bal amount) err-insufficient-quantity)
(map-set inventory {
user: user,
item-id: item-id,
} { quantity: (- current-bal amount) }
)
(if (is-eq (- current-bal amount) u0)
(map-set user-slots { user: user }
(merge slots { used: (- (get used slots) u1) })
)
true
)
(ok true)
)
)
(define-public (transfer-item
(to principal)
(item-id uint)
(amount uint)
)
(let (
(sender-bal (get-balance tx-sender item-id))
(receiver-bal (get-balance to item-id))
(sender-slots (get-slots tx-sender))
(receiver-slots (get-slots to))
)
(asserts! (>= sender-bal amount) err-insufficient-quantity)
;; Check receiver capacity if new item for them
(if (is-eq receiver-bal u0)
(asserts! (< (get used receiver-slots) (get slots receiver-slots))
err-inventory-full
)
true
)
(map-set inventory {
user: tx-sender,
item-id: item-id,
} { quantity: (- sender-bal amount) }
)
(if (is-eq (- sender-bal amount) u0)
(map-set user-slots { user: tx-sender }
(merge sender-slots { used: (- (get used sender-slots) u1) })
)
true
)
(map-set inventory {
user: to,
item-id: item-id,
} { quantity: (+ receiver-bal amount) }
)
(if (is-eq receiver-bal u0)
(map-set user-slots { user: to }
(merge receiver-slots { used: (+ (get used receiver-slots) u1) })
)
true
)
(ok true)
)
)
(define-public (expand-inventory (slots uint))
(let ((current-slots (get-slots tx-sender)))
(map-set user-slots { user: tx-sender }
(merge current-slots { slots: (+ (get slots current-slots) slots) })
)
(ok true)
)
)
;; Helper functions for quota
(define-public (get-item-name (item-id uint))
(match (map-get? items { item-id: item-id })
item (ok (get name item))
err-not-found
)
)
(define-public (get-item-type (item-id uint))
(match (map-get? items { item-id: item-id })
item (ok (get type item))
err-not-found
)
)
(define-public (get-item-max-stack (item-id uint))
(match (map-get? items { item-id: item-id })
item (ok (get max-stack item))
err-not-found
)
)
(define-public (set-default-slots (slots uint))
(begin
(asserts! (is-eq tx-sender contract-owner) err-owner-only)
(var-set default-slots slots)
(ok true)
)
)
(define-public (admin-clear-inventory (user principal))
(begin
(asserts! (is-eq tx-sender contract-owner) err-owner-only)
(map-delete user-slots { user: user })
(ok true)
)
)
(define-public (check-has-item
(user principal)
(item-id uint)
)
(ok (> (get-balance user item-id) u0))
)
(define-public (check-is-full (user principal))
(let ((slots (get-slots user)))
(ok (>= (get used slots) (get slots slots)))
)
)
(define-public (get-free-slots (user principal))
(let ((slots (get-slots user)))
(ok (- (get slots slots) (get used slots)))
)
)
(define-public (consume-item (item-id uint))
(begin
(try! (remove-item tx-sender item-id u1))
(ok true)
)
)
(define-public (craft-item
(result-id uint)
(material-id uint)
(cost uint)
)
(begin
(try! (remove-item tx-sender material-id cost))
(try! (add-item tx-sender result-id u1))
(ok true)
)
)
(define-public (bulk-add
(users (list 10 principal))
(item-id uint)
(amount uint)
)
(begin
(asserts! (is-eq tx-sender contract-owner) err-owner-only)
;; Simplified
(ok true)
)
)
(define-public (update-item-name
(item-id uint)
(new-name (string-ascii 32))
)
(begin
(asserts! (is-eq tx-sender contract-owner) err-owner-only)
(match (map-get? items { item-id: item-id })
item (begin
(map-set items { item-id: item-id }
(merge item { name: new-name })
)
(ok true)
)
err-not-found
)
)
)
(define-public (can-equip-item
(user principal)
(item-id uint)
)
(match (map-get? inventory {
user: user,
item-id: item-id,
})
inv-item (ok (> (get quantity inv-item) u0))
err-not-found
)
)
(define-public (get-item-weight (item-id uint))
(ok u10)
)
;; Placeholder
(define-public (calculate-inventory-value (user principal))
(ok u0)
)
;; Placeholder
(define-public (get-total-items-owned (user principal))
(let ((slots (get-slots user)))
(ok (get used slots))
)
)
(define-public (is-item-stackable (item-id uint))
(match (map-get? items { item-id: item-id })
item (ok (> (get max-stack item) u1))
err-not-found
)
)
(define-public (get-stack-size
(user principal)
(item-id uint)
)
(match (map-get? inventory {
user: user,
item-id: item-id,
})
inv-item (ok (get quantity inv-item))
err-not-found
)
)
(define-public (can-stack-more
(user principal)
(item-id uint)
(amount uint)
)
(match (map-get? items { item-id: item-id })
item (let ((current (get-balance user item-id)))
(ok (<= (+ current amount) (get max-stack item)))
)
err-not-found
)
)
(define-public (get-inventory-usage-percent (user principal))
(let ((slots (get-slots user)))
(ok (/ (* (get used slots) u100) (get slots slots)))
)
)
(define-public (is-inventory-empty (user principal))
(let ((slots (get-slots user)))
(ok (is-eq (get used slots) u0))
)
)
(define-public (get-item-rarity (item-id uint))
(ok "common")
)
;; Placeholder
(define-public (check-item-requirements
(user principal)
(item-id uint)
)
(ok true)
)
(define-public (get-max-inventory-slots)
(ok u100)
)
(define-public (get-min-inventory-slots)
(ok u10)
)
(define-public (is-item-transferable (item-id uint))
(ok true)
)
(define-public (get-item-category (item-id uint))
(match (map-get? items { item-id: item-id })
item (ok (get type item))
err-not-found
)
)
(define-public (get-item-durability (item-id uint))
(ok u100)
)
(define-public (repair-item (item-id uint))
(ok true)
)
(define-public (salvage-item (item-id uint))
(ok true)
)
(define-public (get-salvage-value (item-id uint))
(ok u5)
)
(define-public (is-item-broken (item-id uint))
(ok false)
)
(define-public (get-item-level-req (item-id uint))
(ok u1)
)
(define-public (can-use-item
(user principal)
(item-id uint)
)
(ok true)
)
(define-public (get-item-cooldown (item-id uint))
(ok u0)
)
(define-public (is-item-on-cooldown
(user principal)
(item-id uint)
)
(ok false)
)
(define-public (get-inventory-upgrade-cost)
(ok u1000)
)
(define-public (can-afford-upgrade (user principal))
(ok true)
)
(define-public (get-next-slot-unlock-level)
(ok u10)
)
(define-public (is-soulbound (item-id uint))
(ok false)
)
(define-public (get-item-sell-price (item-id uint))
(ok u10)
)
(define-public (get-item-buy-price (item-id uint))
(ok u20)
)