Source Code

;; hogger.clar - Represents Hogger as an NPC

(define-constant err-unauthorized (err u401))

(define-constant contract (as-contract tx-sender))

(define-data-var last-known-health uint u1000000)
(define-data-var last-health-update-block uint u0)
(define-data-var max-health uint u1000000)
(define-data-var regen-rate uint u100) ;; Health regenerated per block
(define-data-var is-currently-defeated bool false)
(define-data-var current-epoch uint u0)

;; Constants for health and regen rate increases
(define-constant health-increase-per-epoch u100000) ;; 10% of initial max health
(define-constant regen-rate-increase-per-epoch u10)

;; --- Authorization check
(define-private (is-dao-or-extension)
    (or (is-eq tx-sender 'SP2D5BGGJ956A635JG7CJQ59FTRFRB0893514EZPJ.dungeon-master) 
        (contract-call? 'SP2D5BGGJ956A635JG7CJQ59FTRFRB0893514EZPJ.dungeon-master is-extension contract-caller))
)

(define-read-only (is-authorized)
    (ok (asserts! (is-dao-or-extension) err-unauthorized))
)

;; Calculate current health
(define-read-only (calculate-current-health)
    (if (var-get is-currently-defeated)
        u0
        (let
            (
                (blocks-passed (- block-height (var-get last-health-update-block)))
                (regen-amount (* blocks-passed (var-get regen-rate)))
                (health-with-regen (+ (var-get last-known-health) regen-amount))
            )
            (min health-with-regen (var-get max-health))
        )
    )
)

;; Damage Hogger
(define-public (take-damage (damage uint))
    (begin
        (try! (is-authorized))
        (print {event: "take-damage", damage: damage, current-health: (calculate-current-health)})
        (if (var-get is-currently-defeated)
            (ok u0)
            (let
                (
                    (current-health (calculate-current-health))
                    (new-health (if (> current-health damage) (- current-health damage) u0))
                )
                (var-set last-known-health new-health)
                (var-set last-health-update-block block-height)
                (if (is-eq new-health u0)
                    (var-set is-currently-defeated true)
                    false
                )
                (print {event: "damage-result", new-health: new-health, is-defeated: (is-eq new-health u0)})
                (ok new-health)
            )
        )
    )
)

;; Reset Hogger's health and increase stats (called at the start of a new epoch)
(define-public (reset-for-new-epoch)
    (begin
        (try! (is-authorized))
        (print {event: "reset-for-new-epoch", current-epoch: (var-get current-epoch)})
        (var-set current-epoch (+ (var-get current-epoch) u1))
        (var-set max-health (+ (var-get max-health) health-increase-per-epoch))
        (var-set regen-rate (+ (var-get regen-rate) regen-rate-increase-per-epoch))
        (var-set last-known-health (var-get max-health))
        (var-set last-health-update-block block-height)
        (var-set is-currently-defeated false)
        (print {event: "reset-complete", new-epoch: (var-get current-epoch), new-max-health: (var-get max-health), new-regen-rate: (var-get regen-rate)})
        (ok true)
    )
)

;; Getters
(define-read-only (get-health)
    (calculate-current-health)
)

(define-read-only (is-defeated)
    (var-get is-currently-defeated)
)

;; Util functions
(define-private (min (a uint) (b uint))
  (if (< a b) a b)
)

Functions (8)

FunctionAccessArgs
is-dao-or-extensionprivate
is-authorizedread-only
calculate-current-healthread-only
take-damagepublicdamage: uint
reset-for-new-epochpublic
get-healthread-only
is-defeatedread-only
minprivatea: uint, b: uint