~melchizedek6809/WolkenWelten

b2bf2b917c7882b5a676032c580bffb2f4f00d89 — Ben (Win10) a month ago d5b27fe
Greatly improved the item/inventory system
M client/src/mods/gui.nuj => client/src/mods/gui.nuj +8 -1
@@ 143,7 143,8 @@
              [widget/parse/rest type [cdr v]]]]]]

[defun widget/parse [v]
  [cons '-> [cons [list 'widget/new [widget/type/get [car v]]] [widget/parse/rest [car v] [cdr v]]]]]
  [cons '-> [cons [list 'widget/new [widget/type/get [car v]]]
                  [widget/parse/rest [car v] [cdr v]]]]]

[defmacro widget args
          [widget/parse [car args]]]


@@ 177,3 178,9 @@
  [say [if [<= end-count start-count]
           [ansi-rainbow msg]
           [ansi-red msg]]]]

[defmacro widget/remove! l
          [cons 'do [map l [λ [w]
                               `[when ~w
                                  [widget/parent! ~w #nil]
                                  [set! ~w #nil]]]]]]

M client/src/mods/hook.nuj => client/src/mods/hook.nuj +6 -5
@@ 1,4 1,3 @@
[def hook/shot/timeout 0]
[def hook/rope #nil]
[def hook/ropes [array/allocate 32]]
[def hook/max-length 96.0]


@@ 6,7 5,7 @@
[def hook/winch-speed 0.2]

[defun hook/valid? []
  [if [rope/valid? hook/rope]
  [if [and hook/rope [rope/valid? hook/rope]]
      #t
      [do [player/dont-move! #f]
          [set! hook/rope #nil]


@@ 24,9 23,11 @@

[defun hook/shoot! []
  [player/close-glider!]
  [when [> [time/milliseconds] hook/shot/timeout]
    [set! hook/shot/timeout [+ 200 [time/milliseconds]]]
    [message/send 0 [list :hook-shoot [player-pos] [player-rot]]]]]
  [action-every 200
                [if [hook/valid?]
                    [sfx-play sfx-hookReturn]
                    [sfx-play sfx-hookFire]]
                [message/send 0 [list :hook-shoot [player-pos] [player-rot]]]]]

[defhandler :hook-rope [client-id msg]
  [def player [cadr msg]]

M client/src/mods/input.nuj => client/src/mods/input.nuj +3 -7
@@ 20,23 20,19 @@
       "Make the player do a primary action"
       [if [cons-mode?]
           [player-blockbreak! input/primary-did-count]
           [if blockchooser/active
               [player-do-primary! input/primary-did-count]
               [pear/shoot!]]]
           [inventory/primary! input/primary-did-count]]
       [set! input/primary-did #t]]

[defun player-secondary! []
  "Make the player do a secondary action"
  [if blockchooser/active
      [blockchooser/place!]
      [pear/shoot! #t]]
      [inventory/secondary!]]
  [set! input/secondary-did #t]]

[defun player-tertiary! []
       "Make the player do a tertiary action"
       [when [zero? input/tertiary-did-count]
             [set! blockchooser/active [not blockchooser/active]]
             [blockchooser/refresh]]
       [inventory/tertiary!]
       #;[item-tertiary! 0 input/tertiary-did-count]
       [set! input/tertiary-did #t]]


M client/src/mods/inventory.nuj => client/src/mods/inventory.nuj +87 -9
@@ 6,16 6,55 @@

[array/set! inventory 3 [make-instance <grenade>]]
[array/set! inventory 2 [make-instance <bomb>]]
[array/set! inventory 1 [make-instance <pear>]]

[def inventory/macro-panel/sprite #nil]
[def inventory/macro-panel/name #nil]

[defun inventory/get-active []
  [array/ref inventory inventory/selection]]

[defun inventory/widgets/refresh []
  [when macro-panel
    [when-not inventory/macro-panel/name
              [set! inventory/macro-panel/name
                [widget [ :label
                          :parent macro-panel
                          :width -1
                          :height 48
                          :label "asd"]]]]
    [when-not inventory/macro-panel/sprite
              [set! inventory/macro-panel/sprite
                [widget [ :sprite
                          :parent macro-panel
                          :x 24
                          :y 32
                          :width 64
                          :height 64
                          :val 257]]]]
    [def item [inventory/get-active]]
    [widget/label! inventory/macro-panel/name [if item [_ item :name] ""]]
    [widget/val! inventory/macro-panel/sprite [if item [_ item :gui-sprite] 0]]]]

[defun inventory/widgets/remove []
  [widget/remove! inventory/macro-panel/sprite
                  inventory/macro-panel/name]]

[defun inventory/panel/update! []
  [if blockchooser/active
      [inventory/widgets/remove]
      [inventory/widgets/refresh]]
  [for [i 0 [array/length inventory]]
    [def item [array/ref inventory i]]
    [def slot [array/ref inventory/panel/widget/slots i]]

    [widget/outline! [widget/parent slot] [== i inventory/selection]]

    [when item
      [widget/val! slot [_ item :gui-sprite]]]]]
    [widget/outline! [widget/parent [tree/get slot :slot]] [== i inventory/selection]]
    [if item
        [do [widget/val! [tree/get slot :slot] [_ item :gui-sprite]]
            [def q [_ item :get-quantity]]
          [when q
            [widget/label! [tree/get slot :quantity] [string q]]]]
        [do [widget/val! [tree/get slot :slot] 0]
            [widget/label! [tree/get slot :quantity] ""]]]]]

[defun inventory/panel/init! []
  [set! inventory/panel/widget [widget [ :panel


@@ 32,15 71,22 @@
                        :y 0
                        :width 64
                        :height 64]]]

    [array/set! inventory/panel/widget/slots i
                [widget [ :sprite
    [def sprite [widget [ :sprite
                          :parent slot
                          :x 0
                          :y 0
                          :width -1
                          :height -1
                          :val 0]]]]
                          :val 0]]]
    [array/set! inventory/panel/widget/slots i
                @[ :slot sprite
                   :quantity [widget [ :label
                                       :parent sprite
                                       :x -1
                                       :y -1
                                       :width 32
                                       :height 20
                                       :label ""]]]]]
  [inventory/panel/update!]]

[defun inventory/toggle! []


@@ 73,4 119,36 @@
[defun inventory/w/init! []
  [inventory/panel/init!]]

[defun inventory/find [item]
  [def ret -1]
  [for [i 0 [array/length inventory]]
    [when [== [array/ref inventory i] item]
      [set! ret i]
      [set! i [array/length inventory]]]]
  ret]

[defun inventory/remove! [item]
  [def i [inventory/find item]]
  [when [< i 0]
    [throw [list :invalid-item "Couldn't find that item so we can't remove it" item [current-lambda]]]]
  [array/set! inventory i #nil]]

[defun inventory/primary! [did-count]
  [def item [inventory/get-active]]
  [if [and item [_ item :primary]] #t
      [player-do-primary! did-count]]]

[defun inventory/secondary! []
  [def item [inventory/get-active]]
  [and item [_ item :secondary]]]

[defun inventory/tertiary! []
  [when [zero? input/tertiary-did-count]
    [def item [inventory/get-active]]
    [if [and item [_ item :tertiary]]
        #t
        [do [set! blockchooser/active [not blockchooser/active]]
            [inventory/panel/update!]
            [blockchooser/refresh]]]]]

[event-bind on-join :inventory inventory/w/init!]

M client/src/mods/macro-panel.nuj => client/src/mods/macro-panel.nuj +2 -1
@@ 7,6 7,7 @@
                                        :height 128
                                        :val 8
                                        :x -1
                                        :y -1]]]]]
                                        :y -1]]]]
  [inventory/panel/update!]]

[event-bind on-join :blockchooser macro-panel/init!]

M client/src/mods/pear.nuj => client/src/mods/pear.nuj +2 -7
@@ 1,7 1,2 @@
[def pear/shot/timeout 0]

[defun pear/shoot! [mega?]
  [def name [if mega? :mega-pear-shoot :pear-shoot]]
       [when [> [time/milliseconds] pear/shot/timeout]
             [set! pear/shot/timeout [+ 200 [time/milliseconds]]]
             [message/send 0 [list name [player-pos] [player-rot]]]]]
[defun pear/shoot! [name]
  [message/send 0 [list name [player-pos] [player-rot]]]]

M client/src/mods/z_blockchooser.nuj => client/src/mods/z_blockchooser.nuj +2 -6
@@ 13,12 13,8 @@
  [cons-mode/block! blockchooser/selection]]

[defun blockchooser/remove/widgets []
  [when blockchooser/w/label
    [widget/parent! blockchooser/w/label #nil]
    [set! blockchooser/w/label #nil]]
  [when blockchooser/w/sprite
    [widget/parent! blockchooser/w/sprite #nil]
    [set! blockchooser/w/label #nil]]]
  [widget/remove! blockchooser/w/label
                  blockchooser/w/sprite]]

[defun blockchooser/refresh []
  [if blockchooser/active

M client/src/nujel/nujel.c => client/src/nujel/nujel.c +21 -9
@@ 343,20 343,30 @@ static lVal *wwlnfRecoil(lClosure *c, lVal *v){
	return NULL;
}

static lVal *wwlnfPlayerHP(lClosure *c, lVal *v){
	(void)c;
	const int hp = castToInt(lCar(v),-1024);
	if(hp > -1024){ player->hp = MIN(player->maxhp,hp); }
static lVal *wwlnfPlayerHPGet(lClosure *c, lVal *v){
	(void)c; (void)v;
	return lValInt(player->hp);
}

static lVal *wwlnfPlayerMaxHP(lClosure *c, lVal *v){
static lVal *wwlnfPlayerHPSet(lClosure *c, lVal *v){
	(void)c;
	const int maxhp = castToInt(lCar(v),-1024);
	if(maxhp > -1024){ player->maxhp = MAX(1,maxhp); }
	const int hp = requireInt(c, lCar(v));
	player->hp = hp;
	return NULL;
}

static lVal *wwlnfPlayerMaxHPGet(lClosure *c, lVal *v){
	(void)c; (void)v;
	return lValInt(player->maxhp);
}

static lVal *wwlnfPlayerMaxHPSet(lClosure *c, lVal *v){
	(void)c;
	const int maxhp = requireInt(c, lCar(v));
	player->maxhp = maxhp;
	return NULL;
}

static lVal *wwlnfAimingPred(lClosure *c, lVal *v){
	(void)c;(void)v;
	return lValBool(characterIsAiming(player));


@@ 544,8 554,10 @@ static void lispAddClientNFuncs(lClosure *c){
	lAddNativeFunc(c,"player-flags!",  "(flags)",           "Set players flags",                                              wwlnfPlayerSetFlags);
	lAddNativeFunc(c,"player-name",    "[]",                "Get the players name",                                           wwlnfPlayerNameGet);
	lAddNativeFunc(c,"player-name!",   "[s]",               "Set players name to s",                                          wwlnfPlayerNameSet);
	lAddNativeFunc(c,"player-hp",      "(&hp)",             "Set the players health to &HP, returns the current value.",      wwlnfPlayerHP);
	lAddNativeFunc(c,"player-maxhp",   "(&mhp)",            "Set the players max health to &MHP, returns the current value.", wwlnfPlayerMaxHP);
	lAddNativeFunc(c,"player-hp",      "(&hp)",             "Get the players health",                                         wwlnfPlayerHPGet);
	lAddNativeFunc(c,"player-hp!",     "[hp]",              "Set the players health to HP",                                   wwlnfPlayerHPSet);
	lAddNativeFunc(c,"player-maxhp",   "[]",                "Get the players max health",                                     wwlnfPlayerMaxHPGet);
	lAddNativeFunc(c,"player-maxhp!",  "[mhp]",             "Set the players max health to MHP",                              wwlnfPlayerMaxHPSet);
	lAddNativeFunc(c,"player-jump!",   "(velocity)",        "Jump with VELOCITY!",                                            wwlnfPlayerJump);
	lAddNativeFunc(c,"player-sneak!",  "()",                "Sneak for a while",                                              wwlnfPlayerSneak);
	lAddNativeFunc(c,"player-walk!",   "(velocity)",        "Walk forward with VELOCITY",                                     wwlnfPlayerWalk);

M common/src/mods/_init.nuj => common/src/mods/_init.nuj +7 -0
@@ 1,5 1,7 @@
; Contains definitions needed in the other .nuj files

[def action/timeout 0]

[def on-init          @[]]
[def on-spawn         @[]]
[def on-join          @[]]


@@ 52,3 54,8 @@
  [try display/error
       [for-in [h [tree/values event]]
               [apply h values]]]]

[defmacro action-every [ms . form]
          `[when [or server? [> [time/milliseconds] action/timeout]]
             [set! action/timeout [+ ~ms [time/milliseconds]]]
             ~@form]]

M common/src/mods/item.nuj => common/src/mods/item.nuj +44 -2
@@ 1,6 1,21 @@
[defmacro item-use-up [timeout . action]
          `[do [def q [tree/get this :quantity]]
               [when [> q 0]
                 [action-every ~timeout
                               [tree/set! this :quantity [- q 1]]
                               [when [== q 1]
                                 [inventory/remove! this]]
                               [inventory/panel/update!]
                               ~@action]]]]

[defobject <item> #nil]
[defproperty <item> :name "Unknown item"]
[defproperty <item> :entity #nil]
[defmethod <item> :primary [] #f]
[defmethod <item> :secondary [] #f]
[defmethod <item> :tertiary [] #f]
[defmethod <item> :get-quantity [] #nil]
[defmethod <item> :set-quantity [] #nil]

[defmethod <item> :serialize []
           [str/write [-> [tree/dup this]
                          [tree/set! :classname [list quote [tree/get this :classname]]]


@@ 9,14 24,41 @@
[defmethod <item> :gui-sprite [] 258]
[defmethod <item> :gui-count [] 44]

[defobject <grenade> <item>]
[defobject <stackable-item> <item>]
[defproperty <stackable-item> 0]
[defmethod <stackable-item> :get-quantity []
           [tree/get this :quantity]]

[defmethod <stackable-item> :set-quantity [new-quantity]
           [tree/set! this :quantity new-quantity]]

[defobject <pear> <item>]
[defmethod <pear> :name [] "Pear"]
[defmethod <pear> :gui-sprite [] 258]
[defmethod <pear> :secondary [] [action-every 1000
                                              [player-hp! [player-maxhp]]
                                              [sfx-play sfx-hoo]
                                              [say [ansi-green "Yum!"]]]]

[defobject <grenade> <stackable-item>]
[defproperty <grenade> :quantity 50]
[defproperty <grenade> :power 3]
[defmethod <grenade> :gui-sprite []
           256]
[defmethod <grenade> :name [] "Grenade"]
[defmethod <grenade> :primary []
           [item-use-up 20 [pear/shoot! :pear-shoot]]]

[defmethod <grenade> :tertiary [] [say [ansi-green "Can do!"]] #f]

[defmethod <grenade> :collision []
           [def ent [tree/get this :entity]]
           [explode [entity/pos ent] [tree/get this :power]]
           [entity/delete ent]]

[defobject <bomb> <grenade>]
[defmethod <bomb> :name [] "Bomb"]
[defmethod <bomb> :gui-sprite [] 257]
[defmethod <bomb> :primary []
           [item-use-up 200 [pear/shoot! :mega-pear-shoot]]]
[defmethod <bomb> :tertiary [] [say [ansi-red "Can't do that!"]] #t]