1 ;;----------------------------------------------------------------------------
2 ;; arms.scm - armament types
4 ;; The basic primitive for creating an armament type is the kern-mk-arms-type
5 ;; procedure. This procedure takes a lot of parameters (listed below in
6 ;; order). A lot of the parameters are boiler-plate for whole classes of
7 ;; weapons, so I added some "curried" wrapper calls below.
9 ;; tag : the symbol for the type in the script (variable-name)
10 ;; name : the string name used by the game
11 ;; sprite : sprite for the type
12 ;; to-hit : to-hit attack bonus (dice expr)
13 ;; damage : attack damage (dice expr)
14 ;; armor : damage reduced when hit (dice expr)
15 ;; deflect : bonus to deflect attack (dice expr)
16 ;; slots : slots it will fit in (e.g., hands)
17 ;; hands : number of slots required to ready it
18 ;; range : range it will fire
19 ;; rap : required action points to attack with it
20 ;; AP_mod : modifier to max AP per round for the wielder
21 ;; missile : nil or the armament type it fires
22 ;; thrown : true or false
23 ;; ubiq : true if it needs ammo in inventory, false otherwise
24 ;; weight : weight of arms
25 ;; fire-sound : string name of sound file to play when it's fired
28 ;; stratt_mod : percentage of str based attack bonus used
29 ;; dexatt_mod : percentage of dex based attack bonus used
30 ;; damage_mod : percentage of damage bonus used
31 ;; avoid_mod : multiplier for avoidance bonus (1.0 = no effect)
34 ;;----------------------------------------------------------------------------
36 ;; This keeps weapons proportional to the default cost, for a one line change between turn systems
37 (define (weap-ap mult)
38 (floor (* mult default-weapon-rap)))
40 (define (armour-ap mult)
41 (floor (* mult default-armour-apmod)))
43 (kern-mk-sprite-set 'ss_arms 32 32 9 8 0 0 "arms.png")
45 ;;-------------------------------------------------------------------------
46 ;; Temp ifc for mutable attack types
47 ;;-------------------------------------------------------------------------
49 (define temp-ifc-state (list 0))
51 (define (temp-ifc-set tempifc)
52 (set-car! temp-ifc-state tempifc))
57 (lambda (kmissile kuser ktarget kplace x y dam)
58 ((car temp-ifc-state) kmissile kuser ktarget kplace x y dam)
61 (define temp-cannonball-state (list -1 -1))
63 (define (temp-cannonball-init x y)
64 (set-car! temp-cannonball-state x)
65 (set-car! (cdr temp-cannonball-state) y)
68 ;;--------------------------------------------------------------------------
69 ;; Curried constructors
71 ;; These are for creating the standard classes of armaments. They simplify
72 ;; things by filling in the blanks for all the boilerplate parameters of
73 ;; the primitive kern-mk-arms-type procedure.
74 ;;--------------------------------------------------------------------------
76 (define obj-ifc-cap (ifc-cap obj-ifc))
78 (define (mk-melee-arms-type tag name sprite to-hit-bonus damage deflect AP_cost AP_mod slots
79 num-hands range weight
82 (kern-mk-arms-type tag name sprite to-hit-bonus damage "0" deflect slots
83 num-hands range AP_cost AP_mod nil nil #f #f weight nil
84 obj-ifc-cap obj-ifc stratt_mod dexatt_mod damage_mod avoid_mod mmode-smallobj))
86 ;; Curried constructor: missile weapon (add missile, ubiq flag to melee)
87 (define (mk-projectile-arms-type tag name sprite to-hit-bonus damage deflect AP_cost AP_mod
88 slots num-hands range projectile ammo ubiq weight
89 stratt_mod dexatt_mod damage_mod avoid_mod ifc)
90 (kern-mk-arms-type tag name sprite to-hit-bonus damage "0" deflect slots
91 num-hands range AP_cost AP_mod projectile ammo #f ubiq weight nil (ifc-cap ifc) ifc stratt_mod dexatt_mod damage_mod avoid_mod mmode-smallobj))
93 ;; Curried constructor: thrown weapon (add field to melee)
94 (define (mk-thrown-arms-type tag name sprite to-hit-bonus damage deflect AP_cost AP_mod slots
95 num-hands range missile ubiq ifc weight
96 stratt_mod dexatt_mod damage_mod avoid_mod)
97 (kern-mk-arms-type tag name sprite to-hit-bonus damage "0" deflect slots
98 num-hands range AP_cost AP_mod missile nil #t ubiq weight nil (ifc-cap ifc) ifc stratt_mod dexatt_mod damage_mod avoid_mod mmode-smallobj))
100 (define (mk-ammo-arms-type tag name sprite ifc mmode)
101 (kern-mk-arms-type tag name sprite "0" "0" "0" "0" slot-nil 0 0 0 0 nil nil #f #f
102 0 nil (ifc-cap ifc) ifc 20 60 20 1.0 mmode))
104 (define (mk-missile-arms-type tag name sprite ifc mmode beam)
105 (kern-mk-missile-type tag name sprite (ifc-cap ifc) ifc mmode beam beam))
107 (define (mk-armor-type tag name sprite to-hit armor slots equiptime AP_mod weight avoid_mod)
108 (kern-mk-arms-type tag name sprite to-hit "0" armor "0" slots 1 0 equiptime AP_mod nil nil #f #f
109 weight nil obj-ifc-cap obj-ifc 20 60 20 avoid_mod mmode-largeobj))
111 (define (mk-shield-type tag name sprite to-hit deflect AP_mod slots weight avoid_mod)
112 (kern-mk-arms-type tag name sprite to-hit "0" "0" deflect slots 1 0 default-weapon-rap AP_mod nil nil #f #f
113 weight nil obj-ifc-cap obj-ifc 20 60 20 avoid_mod mmode-largeobj))
115 ;; ============================================================================
116 ;; Missiles for Projectile Weapons & Spells
117 ;; ============================================================================
119 (kern-mk-sprite 's_sling_stone ss_arms 1 0 #f 0 )
120 (kern-mk-sprite 's_warhead ss_arms 1 1 #f 0 )
121 (kern-mk-sprite 's_cannonball ss_arms 1 2 #f 0 )
122 (kern-mk-sprite 's_fireball ss_arms 1 3 #f 0 )
123 (kern-mk-sprite 's_deathball ss_arms 1 4 #f 0 )
124 (kern-mk-sprite 's_arrow ss_arms 1 8 #f 495 )
125 (kern-mk-sprite 's_bolt ss_arms 1 80 #f 495 )
126 (kern-mk-sprite 's_arrowobj ss_arms 1 68 #f 0 )
127 (kern-mk-sprite 's_arrowstack ss_arms 1 69 #f 0 )
128 (kern-mk-sprite 's_boltobj ss_arms 1 70 #f 0 )
129 (kern-mk-sprite 's_boltstack ss_arms 1 71 #f 0 )
130 (kern-mk-sprite 's_poison_bolt ss_arms 1 16 #f 170 )
131 (kern-mk-sprite 's_acid_bolt ss_arms 1 20 #f 170 )
132 (kern-mk-sprite 's_thrownweb ss_arms 1 31 #f 0 )
133 (kern-mk-sprite 's_prismatic_bolt ss_arms 4 100 #f 0 )
134 (kern-mk-sprite 's_squat_bubbly_green_potion ss_arms 1 30 #f 0 )
135 (kern-mk-sprite 's_thrown_green_potion ss_arms 4 104 #f 0 )
137 ;; ----------------------------------------------------------------------------
138 ;; mk-missile-ifc -- automate missile ifc creation. 'pred?' takes an object as
139 ;; a parameter and returns true iff the 'hit' proc should be applied to it.
140 ;; ----------------------------------------------------------------------------
141 (define (mk-missile-ifc hit)
143 (method 'hit-loc (lambda (kmissile kuser ktarget kplace x y dam)
144 (let ((targets (filter obj-is-char?
145 (kern-get-objects-at (mk-loc kplace
148 (if (notnull? targets)
149 (hit (car targets))))))))
152 (define poison-bolt-ifc (mk-missile-ifc apply-poison))
153 (define deathball-ifc (mk-missile-ifc magical-kill))
154 (define stunball-ifc (mk-missile-ifc paralyze))
155 (define acid-bolt-ifc (mk-missile-ifc apply-acid))
157 (define lightningbolt-ifc
160 (lambda (kmissile kplace x y)
161 ((car temp-ifc-state) kmissile nil nil kplace x y 0)
165 (define (on-hit-nontarget ktarget loc dam proc)
168 (filter (lambda (obj) (not (equal? obj ktarget)))
169 (kern-get-objects-at loc))
170 (kern-get-objects-at loc)
174 (define (on-hit-target ktarget dam proc)
179 ;; fireball-hit -- when a fireball hits it burns all characters and leaves a
184 (lambda (kmissile kuser ktarget kplace x y dam)
186 (havemana (> (kern-char-get-mana kuser) 0))
187 (usedmana (if (and havemana (equal? (kern-dice-roll "1d15") 1))
190 (kern-char-set-mana kuser (- (kern-char-get-mana kuser) 1))
194 (setfire (and usedmana (equal? (kern-dice-roll "1d3") 1)))
195 (loc (mk-loc kplace x y))
198 (usedmana (if hurt "2d5+3" "2d4+2"))
199 (havemana (if hurt "2d4+2" "2d3+2"))
200 (else (if hurt "1d4-1" "1d2-1"))
208 (if (and setfire (terrain-ok-for-field? loc))
209 (kern-obj-put-at (kern-mk-field F_fire (kern-dice-roll "1d5")) loc))
211 (kern-log-msg "Attack fizzles!"))
212 (on-hit-target ktarget dam
213 (lambda (obj) (generic-burn obj targdamage))
216 (on-hit-nontarget ktarget loc dam
217 (lambda (obj) (generic-burn obj othdamage)))
222 (define (prismatic-acid ktarget power)
223 (if (and (kern-obj-is-char? ktarget)
224 (contest-of-skill power
225 (occ-ability-dexdefend ktarget)))
226 (apply-acid ktarget)))
228 (define (prismatic-slip ktarget power)
229 (if (and (kern-obj-is-char? ktarget)
230 (contest-of-skill power
231 (occ-ability-dexdefend ktarget)))
234 (define prismatic-bolt-ifc
237 (lambda (kmissile kuser ktarget kplace x y dam)
239 (havemana (> (kern-char-get-mana kuser) 0))
240 (usedmana (if (and havemana (equal? (kern-dice-roll "1d15") 1))
243 (kern-char-set-mana kuser (- (kern-char-get-mana kuser) 1))
247 (magpower (if havemana
248 (if usedmana (max 7 (occ-ability-blackmagic kuser)) 5)
250 (loc (mk-loc kplace x y))
253 (havetarget (not (eqv? ktarget '())))
254 (pristype (kern-dice-roll "1d100"))
257 (cond ((< pristype 10)
259 (lambda (obj) (powers-paralyse kuser obj magpower))
260 (lambda (obj) (powers-paralyse kuser obj (- magpower 3)))))
264 (lambda (obj) (prismatic-acid obj magpower))
265 (lambda (obj) (prismatic-acid obj (- magpower 3)))))
269 (lambda (obj) (powers-poison-effect kuser obj (+ magpower 3)))
270 (lambda (obj) (powers-poison-effect kuser obj (- magpower 2)))))
274 (lambda (obj) (generic-burn obj "2d3+2"))
275 (lambda (obj) (generic-burn obj "1d5"))))
279 (lambda (obj) (apply-lightning obj))
280 (lambda (obj) (apply-lightning obj))))
284 (lambda (obj) (prismatic-slip obj (+ magpower 5)))
285 (lambda (obj) (prismatic-slip obj (+ magpower 2)))))
289 (lambda (loc) (powers-field-energy-weak kuser loc magpower))
294 (lambda (loc) (powers-field-fire-weak kuser loc magpower))
299 (lambda (loc) (powers-field-poison-weak kuser loc magpower))
304 (lambda (loc) (powers-field-sleep-weak kuser loc magpower))
308 (kern-log-msg "Attack fizzles!")
310 (if (not (null? (car proclist)))
311 ((car proclist) loc))
312 (if (not (null? (cadr proclist)))
313 (on-hit-target ktarget dam (cadr proclist)))
314 (if (not (null? (caddr proclist)))
315 (on-hit-nontarget ktarget loc dam (caddr proclist)))
324 (lambda (kmissile kuser ktarget kplace x y dam)
325 (kern-obj-put-at (kern-mk-obj F_fire 1)
326 (mk-loc kplace x y))))))
328 (kern-mk-sprite 's_flaming_oil ss_arms 4 96 #f 0)
329 (kern-mk-sprite 's_oil_potion ss_arms 1 5 #f 0)
330 (kern-mk-sprite 's_spear ss_arms 1 88 #f 495 )
331 (kern-mk-sprite 's_spearobj ss_arms 1 6 #f 0)
332 (kern-mk-sprite 's_throwing_axe ss_arms 1 29 #f 0)
333 (kern-mk-sprite 's_thrown_axe ss_arms 8 72 #f 0)
334 (kern-mk-sprite 's_thrown_boulder ss_arms 1 7 #f 0)
335 (kern-mk-sprite 's_smoke_bomb ss_arms 4 112 #f 0)
336 (kern-mk-sprite 's_smoke_potion ss_arms 1 108 #f 0)
338 (define flaming-oil-ifc
341 (lambda (kmissile kuser ktarget kplace x y dam)
342 (kern-obj-put-at (kern-mk-obj F_fire 1)
343 (mk-loc kplace x y))))))
345 (define vial-of-slime-ifc
348 (lambda (kmissile kuser ktarget kplace x y dam)
349 (let* ((lvl (kern-dice-roll "1d3+5"))
350 (knpc (spawn-npc 'green-slime lvl))
351 (loc (pick-loc (mk-loc kplace x y) knpc)))
353 (kern-obj-dec-ref knpc)
356 (kern-being-set-base-faction knpc (kern-being-get-base-faction kuser))
357 (kern-obj-set-temporary knpc #t)
358 (kern-obj-put-at knpc loc))))))))
360 (define smoke-bomb-ifc
363 (lambda (kmissile kuser ktarget kplace x y dam)
364 (fields-smoke-apply kplace x y 10)
367 (define (mk-drop-proj-ifc type-tag prob)
370 (lambda (kmissile kuser ktarget kplace x y dam)
371 (if (< (kern-dice-roll "1d100") prob)
372 (let ((dropobj (kern-mk-obj (eval type-tag) 1))
373 (loc (mk-loc kplace x y)))
374 (if (can-be-dropped? dropobj loc cant)
375 (kern-obj-put-at dropobj loc)
379 ;; todo: handle possibility that magicaxe doesnt have a wielder?
383 (lambda (kmissile kuser ktarget kplace x y dam)
384 (kern-fire-missile (eval 't_returning_axe_p) (mk-loc kplace x y) (kern-obj-get-location kuser))
385 (kern-log-msg "Magic axe returns!")
391 (define missile-arms-types
393 ;; ==================================================================================================
394 ;; tag | name | sprite | gifc | movement_mode | beam
395 ;; ====================================================================================================
396 (list 't_slingstone "sling stone" s_sling_stone obj-ifc mmode-missile #f)
397 (list 't_arrow_p "arrow" s_arrow (mk-drop-proj-ifc 't_arrow 5)
399 (list 't_bolt_p "bolt" s_bolt (mk-drop-proj-ifc 't_bolt 5)
401 (list 't_warhead_p "warhead" s_warhead warhead-ifc mmode-missile #f )
402 (list 't_cannonball_p "cannonball" s_cannonball obj-ifc mmode-missile #f )
405 (list 't_poison_bolt "poison bolt" s_poison_bolt poison-bolt-ifc mmode-missile #f )
406 (list 't_acid_bolt "acid bolt" s_acid_bolt acid-bolt-ifc mmode-missile #f )
407 (list 't_fireball "fireball" s_fireball fireball-ifc mmode-missile #f )
408 (list 't_deathball "deathball" s_deathball deathball-ifc mmode-missile #f )
409 (list 't_slimeglob "slime glob" s_acid_bolt obj-ifc mmode-missile #f )
410 (list 't_mfireball "fireball" s_fireball temp-ifc mmode-missile #f )
411 (list 't_mpoison_bolt "poison bolt" s_poison_bolt temp-ifc mmode-missile #f )
412 (list 't_prismatic_bolt "prismatic bolt" s_prismatic_bolt prismatic-bolt-ifc mmode-missile #f )
413 (list 't_stunball "stun ball" s_lightning stunball-ifc mmode-missile #f )
414 (list 't_lightning_bolt "lightning bolt" s_lightning lightningbolt-ifc mmode-missile #t )
415 (list 't_magicarrow_p "arrow" s_arrow obj-ifc mmode-missile #f )
419 (list 't_mweb "web" s_thrownweb temp-ifc mmode-missile #f )
420 (list 't_oil_p "flaming oil" s_flaming_oil flaming-oil-ifc mmode-missile #f )
421 (list 't_smoke_bomb_p "smoke bomb" s_smoke_bomb smoke-bomb-ifc mmode-missile #f )
422 (list 't_spear_p "spear" s_spear (mk-drop-proj-ifc 't_spear 25)
424 (list 't_thrown_axe_p "thrown axe" s_thrown_axe magicaxe-ifc mmode-missile #f )
425 (list 't_returning_axe_p "thrown axe" s_thrown_axe obj-ifc mmode-return #f )
426 (list 't_thrown_rock_p "thrown rock" s_cannonball (mk-drop-proj-ifc 't_thrown_rock 80)
428 (list 't_thrown_boulder_p "hurled boulder" s_thrown_boulder (mk-drop-proj-ifc 't_thrown_boulder 80)
431 (list 't_slime_vial_p "vial of slime" s_thrown_green_potion vial-of-slime-ifc mmode-missile #f )
435 (map (lambda (type) (apply mk-missile-arms-type type)) missile-arms-types)
438 (define ammo-arms-types
440 ;; ===========================================================================================
441 ;; tag | name | sprite | gifc | movement_mode
442 ;; ===========================================================================================
444 (list 't_arrow "arrow" s_arrowobj obj-ifc mmode-smallobj )
445 (list 't_bolt "bolt" s_boltobj obj-ifc mmode-smallobj )
446 (list 't_warhead "warhead" s_warhead warhead-ifc mmode-smallobj )
447 (list 't_cannonball "cannonball" s_cannonball obj-ifc mmode-smallobj )
451 ;; If we don't create these missile types now, we won't be able to refer to
452 ;; them below in the projectile-arms-types table. For example, t_bow needs to
453 ;; refer to t_arrow. But the interpreter won't recognize t_arrow as a variable
454 ;; name until we call this procedure to create the t_arrow type.
455 (map (lambda (type) (apply mk-ammo-arms-type type)) ammo-arms-types)
457 ;; ============================================================================
458 ;; Projectile Weapons
459 ;; ============================================================================
461 (kern-mk-sprite 's_sling ss_arms 1 24 #f 0)
462 (kern-mk-sprite 's_bow ss_arms 1 25 #f 0)
463 (kern-mk-sprite 's_crossbow ss_arms 1 26 #f 0)
464 (kern-mk-sprite 's_doom_staff ss_arms 1 27 #f 0)
465 (kern-mk-sprite 's_stun_wand ss_arms 1 28 #f 0)
472 (kern-sound-play-at sound-missile (kern-obj-get-location kuser))
477 (define projectile-arms-types
479 ;; =========================================================================================================================================================================================
480 ;; tag | name | sprite | to-hit | damage | to-def | AP_cost | AP_mod | slots | hnds | rng | missile | ammo | ubiq | weight | stratt | dexatt | dammod | avoid | ifc
481 ;; =========================================================================================================================================================================================
482 (list 't_sling "sling" s_sling "1d2-2" "1d4" "-1" (weap-ap 1) 0 slot-weapon 1 4 t_slingstone nil #t 0 10 60 30 0.9 proj-ifc)
483 (list 't_sling_4 "+4 sling" s_sling "+3" "1d4+4" "+0" (weap-ap 1) 0 slot-weapon 1 6 t_slingstone nil #t 0 10 60 30 0.9 proj-ifc)
485 (list 't_self_bow "self bow" s_bow "+1" "1d6" "-2" (weap-ap 0.8) 0 slot-weapon 2 4 t_arrow_p t_arrow #f 2 10 70 20 0.9 proj-ifc)
486 (list 't_bow "bow" s_bow "1d3-2" "2d4" "-2" (weap-ap 1) 0 slot-weapon 2 5 t_arrow_p t_arrow #f 2 10 70 20 0.9 proj-ifc)
487 (list 't_long_bow "longbow" s_bow "1d3-2" "2d6+1" "-2" (weap-ap 1.2) 0 slot-weapon 2 6 t_arrow_p t_arrow #f 2 10 70 20 0.9 proj-ifc)
488 (list 't_great_bow "great bow" s_bow "1d3-2" "2d6+3" "-2" (weap-ap 1.34) 0 slot-weapon 2 7 t_arrow_p t_arrow #f 2 10 70 20 0.9 proj-ifc)
490 (list 't_lt_crossbow "light crossbow" s_crossbow "1d4-2" "2d5" "-1" (weap-ap 1) 0 slot-weapon 2 5 t_bolt_p t_bolt #f 3 0 80 0 0.95 proj-ifc)
491 (list 't_crossbow "crossbow" s_crossbow "1d4-2" "4d4" "-1" (weap-ap 1) 0 slot-weapon 2 6 t_bolt_p t_bolt #f 3 0 80 0 0.95 proj-ifc)
492 (list 't_hvy_crossbow "heavy crossbow" s_crossbow "1d4-2" "4d6+2" "-1" (weap-ap 2) 0 slot-weapon 2 7 t_bolt_p t_bolt #f 3 0 80 0 0.95 proj-ifc)
493 (list 't_trpl_crossbow "triple crossbow" s_crossbow "1d4-2" "2d5" "-1" (weap-ap 0.67) 0 slot-weapon 2 5 t_bolt_p t_bolt #f 3 0 80 0 0.95 proj-ifc)
495 (list 't_doom_staff "doom staff" s_doom_staff "1d4" "1d2" "+2" (weap-ap 1) 0 slot-weapon 2 5 t_fireball nil #t 2 0 50 0 1.0 proj-ifc)
496 (list 't_acid_spray "acid spray" nil "-7" "1d6" "+0" (weap-ap 1) 0 slot-nil 2 2 t_slimeglob nil #t 0 10 50 20 1.0 proj-ifc)
497 (list 't_fire_glob "fire glob" nil "-8" "1d6" "+0" (weap-ap 1) 0 slot-nil 2 2 t_fireball nil #t 0 10 50 20 1.0 proj-ifc)
498 (list 't_stun_wand "stun wand" s_stun_wand "-2" "1d4" "-1" (weap-ap 1) 0 slot-weapon 1 6 t_stunball nil #t 2 0 80 0 1.0 proj-ifc)
499 (list 't_acid_wand "acid wand" s_stun_wand "-2" "1d4" "-1" (weap-ap 1) 0 slot-weapon 1 6 t_acid_bolt nil #t 2 0 80 0 1.0 proj-ifc)
500 (list 't_prismatic_gaze "prismatic gaze" nil "1d4" "0" "+0" (weap-ap 1) 0 slot-nil 1 3 t_prismatic_bolt nil #t 0 0 0 0 0.85 proj-ifc)
503 ;; ============================================================================
505 ;; ============================================================================
508 (define thrown-arms-types
510 ;; =================================================================================================================================================================================================================
511 ;; tag | name | sprite | to-hit | dmg | to-def | AP_cost | AP_mod | slots | hnds | rng | missile | ubiq | ifc | weight | stratt | dexatt | dammod | avoid
512 ;; =================================================================================================================================================================================================================
513 (list 't_thrown_rock "small rock" s_cannonball "-2" "1d2" "-2" (weap-ap 1.33) 0 slot-weapon 1 4 t_thrown_rock_p #t obj-ifc 1 20 20 0 0.9 )
514 (list 't_thrown_boulder "loose boulder" s_thrown_boulder "-2" "3d4+1" "-2" (weap-ap 2) 0 slot-weapon 2 5 t_thrown_boulder_p #f obj-ifc 10 40 20 60 0.9 )
516 (list 't_spear "spear" s_spearobj "+1" "1d8+1" "+1" (weap-ap 1) 0 slot-weapon 1 4 t_spear_p #f obj-ifc 2 30 60 40 1.0 )
517 (list 't_magic_axe "magical axe" s_throwing_axe "+2" "2d4+2" "+0" (weap-ap 1) 0 slot-weapon 1 4 t_thrown_axe_p #t obj-ifc 2 30 60 40 1.0 )
519 (list 't_oil "flaming oil" s_oil_potion "-1" "1d6" "-2" (weap-ap 1.2) 0 slot-weapon 1 4 t_oil_p #f flaming-oil-ifc 1 20 30 0 0.9 )
520 (list 't_slime_vial "vial of slime" s_squat_bubbly_green_potion "-1" "1d2" "-2" (weap-ap 1.2) 0 slot-weapon 1 4 t_slime_vial_p #f vial-of-slime-ifc 1 20 30 0 1.0 )
521 (list 't_smoke_bomb "smoke bomb" s_smoke_potion "-1" "1" "-2" (weap-ap 1.2) 0 slot-weapon 1 6 t_smoke_bomb_p #f smoke-bomb-ifc 1 20 30 0 0.9 )
524 (map (lambda (type) (apply mk-thrown-arms-type type)) thrown-arms-types)
527 (kern-mk-sprite 's_axe ss_arms 1 29 #f 0)
528 (kern-mk-sprite 's_dagger ss_arms 1 32 #f 0)
529 (kern-mk-sprite 's_mace ss_arms 1 33 #f 0)
530 (kern-mk-sprite 's_sword ss_arms 1 34 #f 0)
531 (kern-mk-sprite 's_2h_axe ss_arms 1 35 #f 0)
532 (kern-mk-sprite 's_2h_sword ss_arms 1 36 #f 0)
533 (kern-mk-sprite 's_morning_star ss_arms 1 37 #f 0)
534 (kern-mk-sprite 's_halberd ss_arms 1 38 #f 0)
535 (kern-mk-sprite 's_staff ss_arms 1 39 #f 0)
536 (kern-mk-sprite 's_eldritch_blade ss_arms 2 40 #f 0)
537 (kern-mk-sprite 's_mystic_sword ss_arms 2 42 #f 0)
538 (kern-mk-sprite 's_flaming_sword ss_arms 2 44 #f 0)
540 ;; Paper-doll sprites
541 (kern-mk-sprite 's_hum_staff_gold ss_arms 4 56 #f 0)
542 (kern-mk-sprite 's_hum_staffglo_blue ss_arms 4 60 #f 0)
543 (kern-sprite-apply-matrix (kern-sprite-clone s_hum_staffglo_blue
544 's_hum_staffglo_green)
546 (kern-mk-sprite 's_hum_halberd ss_arms 4 64 #f 0)
548 (define melee-arms-types
550 ;; ===================================================================================================================================================
551 ;; tag | name | sprite | to-hit | damage | to-def | AP_cost | AP_mod | slots | hnds | rng | weight | dxmod | stmod | dammod | avoid
552 ;; ===================================================================================================================================================
553 (list 't_hands "bare hands" nil "1d2" "1d2" "1d2" (weap-ap 0.67) 0 slot-nil 1 1 0 50 20 10 1.0 )
554 (list 't_F_fangs "fangs" nil "1d2" "1d4" "+0" (weap-ap 0.67) 0 slot-nil 1 1 0 50 20 30 1.0 )
555 (list 't_fangs "fangs" nil "1d2" "1d6" "+0" (weap-ap 1) 0 slot-nil 1 1 0 50 20 30 1.0 )
556 (list 't_G_fangs "great fangs" nil "1d2" "1d10" "+0" (weap-ap 1.34) 0 slot-nil 1 1 0 50 20 30 1.0 )
557 (list 't_horns "horns" nil "1d2" "1d8" "1d2" (weap-ap 0.67) 0 slot-nil 1 1 0 30 40 60 1.0 )
558 (list 't_stinger "stinger" nil "1d2" "1d2" "+0" (weap-ap 0.67) 0 slot-nil 1 1 0 50 20 10 1.0 )
559 (list 't_tentacles "tentacles" nil "1d3" "4d4" "4d2" (weap-ap 1) 0 slot-nil 1 1 0 70 20 60 1.0 )
560 (list 't_beak "beak" nil "+0" "2d4" "+0" (weap-ap 1) 0 slot-nil 1 1 0 50 30 30 1.0 )
561 (list 't_pincers "pincers" nil "-1" "4d4" "4d2" (weap-ap 1.2) 0 slot-nil 1 1 0 50 30 30 1.0 )
563 (list 't_dagger "dagger" s_dagger "1d4" "1d4" "1d2" (weap-ap 0.8) 0 slot-weapon 1 1 0 80 10 10 1.0 )
564 (list 't_dagger_4 "+4 dagger" s_dagger "1d4+4" "1d4+4" "1d2+4" (weap-ap 0.8) 0 slot-weapon 1 1 0 80 10 10 1.0 )
565 (list 't_mace "mace" s_mace "1d4" "1d6+2" "+0" (weap-ap 1) 0 slot-weapon 1 1 3 20 60 80 0.95 )
566 (list 't_axe "axe" s_axe "1d2" "2d4+2" "+0" (weap-ap 1.2) 0 slot-weapon 1 1 3 30 50 90 0.95 )
567 (list 't_sword "sword" s_sword "1d2" "1d8+1" "1d2" (weap-ap 1) 0 slot-weapon 1 1 2 50 20 70 1.0 )
568 (list 't_sword_2 "+2 sword" s_sword "1d2+2" "1d8+3" "1d2+2" (weap-ap 1) 0 slot-weapon 1 1 2 50 20 70 1.0 )
569 (list 't_sword_4 "+4 sword" s_sword "1d2+4" "1d8+5" "1d2+4" (weap-ap 1) 0 slot-weapon 1 1 2 50 20 70 1.0 )
570 (list 't_2H_axe "2H axe" s_2h_axe "+0" "4d4+4" "-2" (weap-ap 1.34) 0 slot-weapon 2 1 4 20 60 100 0.9 )
571 (list 't_2H_sword "2H sword" s_2h_sword "+0" "2d8+2" "+1" (weap-ap 1.2) 0 slot-weapon 2 1 4 40 40 90 0.95 )
572 (list 't_morning_star "morning star" s_morning_star "1d2+2" "1d6+1" "-1" (weap-ap 1) 0 slot-weapon 1 2 3 20 40 70 0.9 )
573 (list 't_morning_star_2 "+2 morning star" s_morning_star "1d2+4" "1d6+3" "+2" (weap-ap 1) 0 slot-weapon 1 2 3 20 40 70 0.9 )
574 (list 't_halberd "halberd" s_halberd "1d3+1" "2d8-2" "1d2" (weap-ap 1) 0 slot-weapon 2 2 4 30 30 100 0.9 )
575 (list 't_staff "staff" s_staff "1d3" "1d4" "1d3" (weap-ap 0.8) 0 slot-weapon 2 2 2 60 30 40 1.0 )
576 (list 't_eldritch_blade "eldritch blade" s_eldritch_blade "+2" "3d7+5" "+0" (weap-ap 1.34) 0 slot-weapon 2 1 2 50 20 70 1.0 )
577 (list 't_mystic_sword "mystic sword" s_mystic_sword "+3" "1d10+5" "+2" (weap-ap 1) 0 slot-weapon 1 1 1 60 20 70 1.0 )
580 (kern-mk-sprite 's_leather_helm ss_arms 1 48 #f 0)
581 (kern-mk-sprite 's_chain_coif ss_arms 1 49 #f 0)
582 (kern-mk-sprite 's_iron_helm ss_arms 1 50 #f 0)
583 (kern-mk-sprite 's_leather_armor ss_arms 1 51 #f 0)
584 (kern-mk-sprite 's_chain_armor ss_arms 1 52 #f 0)
585 (kern-mk-sprite 's_plate_armor ss_arms 1 53 #f 0)
589 ;; ===============================================================================================================
590 ;; tag | name | sprite | to-hit | armor | slots | equip_AP | AP_mod | weight | avoid
591 ;; ===============================================================================================================
592 (list 't_leather_helm "leather helm" s_leather_helm "-1" "1d2" slot-helm (weap-ap 1) -0 0 1.0 )
593 (list 't_leather_helm_2 "+2 leather helm" s_leather_helm "+0" "1d2+2" slot-helm (weap-ap 1) -0 0 1.0 )
594 (list 't_leather_helm_4 "+4 leather helm" s_leather_helm "+0" "1d2+4" slot-helm (weap-ap 1) -0 0 1.0 )
596 (list 't_chain_coif "chain coif" s_chain_coif "-1" "1d3" slot-helm (weap-ap 1) (armour-ap -1) 1 0.9 )
597 (list 't_chain_coif_4 "+4 chain coif" s_chain_coif "+0" "1d3+4" slot-helm (weap-ap 1) (armour-ap -1) 1 0.9 )
599 (list 't_iron_helm "iron helm" s_iron_helm "-1" "1d4" slot-helm (weap-ap 1) (armour-ap -2) 2 0.9 )
600 (list 't_iron_helm_4 "+4 iron helm" s_iron_helm "+0" "1d4+4" slot-helm (weap-ap 1) (armour-ap -2) 2 0.9 )
602 (list 't_armor_leather "leather armor" s_leather_armor "-1" "1d4" slot-armor (weap-ap 2) (armour-ap -1) 2 0.85 )
603 (list 't_armor_leather_2 "+2 leather armor" s_leather_armor "+0" "1d4+2" slot-armor (weap-ap 2) (armour-ap -1) 2 0.85 )
604 (list 't_armor_leather_4 "+4 leather armor" s_leather_armor "+0" "1d4+4" slot-armor (weap-ap 2) (armour-ap -1) 2 0.9 )
606 (list 't_armor_chain "chain armor" s_chain_armor "-2" "2d4" slot-armor (weap-ap 2) (armour-ap -5) 4 0.7 )
607 (list 't_armor_chain_4 "+4 chain armor" s_chain_armor "+0" "2d4+4" slot-armor (weap-ap 2) (armour-ap -5) 4 0.8 )
609 (list 't_armor_plate "plate armor" s_plate_armor "-4" "4d4" slot-armor (weap-ap 5) (armour-ap -10) 8 0.6 )
610 (list 't_armor_plate_4 "+4 plate armor" s_plate_armor "+0" "4d4+4" slot-armor (weap-ap 5) (armour-ap -10) 8 0.7 )
613 (kern-mk-sprite 's_shield ss_arms 1 54 #f 0)
614 (kern-mk-sprite 's_scratched_shield ss_arms 1 55 #f 0)
618 ;; ============================================================================================================
619 ;; tag | name | sprite | to-hit | deflect | AP_mod | slots | weight | avoid
620 ;; ============================================================================================================
621 (list 't_shield "small shield" s_shield "-1" "5" -0 slot-shield 2 0.9 )
622 (list 't_shield_4 "+4 small shield" s_shield "+0" "9" -0 slot-shield 2 0.95 )
623 (list 't_scratched_shield "scratched shield" s_scratched_shield "+0" "7" -0 slot-shield 2 0.9 )
627 (map (lambda (type) (apply mk-projectile-arms-type type)) projectile-arms-types)
628 (map (lambda (type) (apply mk-melee-arms-type type)) melee-arms-types)
629 (map (lambda (type) (apply mk-armor-type type)) armor-types)
630 (map (lambda (type) (apply mk-shield-type type)) shield-types)
632 ;;----------------------------------------------------------------------------
634 ;;----------------------------------------------------------------------------
635 (kern-mk-sprite 's_spiked_helm ss_arms 1 46 #f 0)
636 (kern-mk-sprite 's_spiked_shield ss_arms 1 47 #f 0)
638 (kern-mk-arms-type 't_spiked_helm "spiked helm" s_spiked_helm
640 slot-helm 1 1 (weap-ap 2) -0
643 nil obj-ifc-cap obj-ifc
644 30 10 20 0.9 mmode-smallobj)
646 (kern-mk-arms-type 't_spiked_shield "spiked shield" s_spiked_shield
648 slot-shield 1 1 (weap-ap 2) -0
651 nil obj-ifc-cap obj-ifc
652 40 20 20 0.8 mmode-largeobj)
654 ;;--------------------------------------------------------------------------
655 ;; Special arms types
657 ;; These don't fit into the mold for any standard arms type.
658 ;;--------------------------------------------------------------------------
660 (define flaming-sword-ifc
663 (lambda (kmissile kuser ktarget kplace x y dam)
664 (cond ((equal? dam 0)
665 (generic-burn ktarget "1d5-2"))
667 (generic-burn ktarget "2d4"))
671 (kern-mk-arms-type 't_flaming_sword "flaming sword" s_flaming_sword "1d2" "1d8+2" "0" "1d2" slot-weapon 1 1 (weap-ap 1) 0 nil nil #f #f 2 nil
672 (ifc-cap flaming-sword-ifc) flaming-sword-ifc 50 20 70 1.0 mmode-smallobj)
675 (kern-mk-arms-type 't_cannon ; tag
678 "+1" ;; to-hit : to-hit attack bonus (dice expr)
679 "1d10+4" ;; damage : attack damage (dice expr)
680 "0" ;; armor : added to armor class (dice expr)
681 "0" ;; deflect : damage deflected when hit (dice expr)
682 slot-nil ;; slots : slots it will fit in (e.g., hands)
683 0 ;; hands : number of slots required to ready it
684 6 ;; range : range it will fire
685 (weap-ap 2.0) ;; rap : required action points to attack with it
686 0 ;; AP_mod : modifier to max AP per round for the wielder
688 nil ;; missile : nil or the armament type it fires
689 #f ;; thrown : true or false
690 #t ;; ubiq : true if it needs ammo in inventory, false otherwise
692 sound-cannon-fire ;; fire-sound : string name of sound file to play when it's fired
693 0 ;; ifc-cap : integer bitmap describing interface slots
694 nil ;; get-handler : script ifc
699 ;;----------------------------------------------------------------------------
700 ;; This list of "blockable" arms types is used by combat ai. An arms type is
701 ;; "blockable" if an adjacent enemy can interfere with its usage.
702 ;;----------------------------------------------------------------------------
703 (define blockable-arms-types
704 (list t_sling t_sling_4
705 t_self_bow t_bow t_long_bow t_great_bow
706 t_hvy_crossbow t_trpl_crossbow
708 t_thrown_rock t_thrown_boulder ))
709 ; t_lt_crossbow is quick to load, and can be used in melee
711 (define arms-types-needing-ammo
712 (list t_self_bow t_bow t_long_bow t_great_bow
713 t_lt_crossbow t_crossbow t_hvy_crossbow t_trpl_crossbow ))
715 (define (arms-type-is-blockable? karms)
716 (display "arms-type-is-bloackable?")(newline)
717 (in-list? karms blockable-arms-types))
719 (define (arms-type-needs-ammo? karms)
720 (in-list? karms arms-types-needing-ammo))
722 ;;----------------------------------------------------------------------------
723 ;; Test paper doll sprites: add a gob to the staff arms type with a "readied"
725 ;;----------------------------------------------------------------------------
726 (kern-type-set-gob t_staff
727 (kern-sprite-blit-over s_hum_staff_gold
728 s_hum_staffglo_blue))
730 (kern-type-set-gob t_halberd s_hum_halberd)
732 ;;--------------------------------------------------------------------------
733 ;; Cannon mounting for shipboard combat (and maybe anywhere else we can think of later)
734 ;;--------------------------------------------------------------------------
736 ;; uglyhack find target location or set up 'safe' location to simulate cannonball leaving play area
737 (define (arms-searchline place x y dx dy)
738 (let* ((wid (kern-place-get-width place))
739 (hgt (kern-place-get-height place)))
740 (define (arms-searchline-iter ix iy)
741 (cond ((< ix 0) (list 0 iy #f))
742 ((< iy 0) (list ix 0 #f))
743 ((>= ix wid) (list (- wid 1) iy #f))
744 ((>= iy hgt) (list ix (- wid 1) #f))
745 ((not (null? (get-being-at (mk-loc place ix iy))))
747 (else (arms-searchline-iter (+ ix dx) (+ iy dy)))
749 (let* ((target (arms-searchline-iter (+ x dx) (+ y dy)))
752 (havet (caddr target))
755 (temp-cannonball-init -1 -1)
756 (temp-cannonball-init tx ty)
761 (define localcannonball-ifc
764 (lambda (kmissile kuser ktarget kplace x y dam)
765 (let ((ktarget (get-being-at (mk-loc kplace x y))))
766 (if (not (null? ktarget))
769 (kern-log-msg (kern-obj-get-name ktarget) " hit by cannonball!")
770 (kern-obj-apply-damage ktarget "cannon" (kern-dice-roll "1d10+4"))
776 (mk-missile-arms-type 't_localcannonball "cannonball" s_cannonball localcannonball-ifc mmode-cannon #f)
781 (lambda (kcannon kuser)
782 (let ((ready (cadr (gob kcannon))))
783 (kern-log-msg "The cannon is "
784 (cond ((equal? ready 2)
787 "loaded but unready")
793 (lambda (kcannon kuser)
794 (let ((ready (cadr (gob kcannon)))
795 (facing (car (gob kcannon))))
796 (kern-obj-dec-ap kuser speed-human)
799 (let* ((loc (kern-obj-get-location kcannon))
800 (aimdir (direction-to-lvect facing))
801 (targetloc (arms-searchline (car loc)
802 (cadr loc) (caddr loc)
803 (car aimdir) (cadr aimdir))))
804 (kern-sound-play sound-cannon-fire)
805 (kern-log-msg "BOOOM")
806 (kern-fire-missile t_localcannonball loc (mk-loc (car loc) (car targetloc) (cadr targetloc)))
808 (bind kcannon (list facing 0)))
810 (kern-log-msg "Cannon ready to fire")
811 (bind kcannon (list facing 2)))
813 (kern-log-msg "Cannon loaded")
814 (bind kcannon (list facing 1)))
820 (kern-obj-set-facing kcannon (car (gob kcannon)))
821 (kern-obj-set-pclass kcannon pclass-boulder)
825 (mk-obj-type 't_cannonobj "cannon" s_cannon layer-mechanism cannon-ifc)
827 (define (arms-mk-cannon facing)
828 (let ((kcannon (kern-mk-obj t_cannonobj 1)))
829 (kern-obj-set-facing kcannon facing)
830 (bind kcannon (list facing 0))
833 ;; Weapons that aren't affected by acid
834 (define arms-immune-to-acid
835 (list t_flaming_sword