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]