1;;---------------------------------------------------------------------------- 2;; arms.scm - armament types 3;; 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. 8;; 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 26;; gifc-cap : 27;; gifc : 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) 32;; 33;; 34;;---------------------------------------------------------------------------- 35 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))) 39 40(define (armour-ap mult) 41 (floor (* mult default-armour-apmod))) 42 43(kern-mk-sprite-set 'ss_arms 32 32 9 8 0 0 "arms.png") 44 45;;------------------------------------------------------------------------- 46;; Temp ifc for mutable attack types 47;;------------------------------------------------------------------------- 48 49(define temp-ifc-state (list 0)) 50 51(define (temp-ifc-set tempifc) 52 (set-car! temp-ifc-state tempifc)) 53 54(define temp-ifc 55 (ifc '() 56 (method 'hit-loc 57 (lambda (kmissile kuser ktarget kplace x y dam) 58 ((car temp-ifc-state) kmissile kuser ktarget kplace x y dam) 59 )))) 60 61(define temp-cannonball-state (list -1 -1)) 62 63(define (temp-cannonball-init x y) 64 (set-car! temp-cannonball-state x) 65 (set-car! (cdr temp-cannonball-state) y) 66 ) 67 68;;-------------------------------------------------------------------------- 69;; Curried constructors 70;; 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;;-------------------------------------------------------------------------- 75 76(define obj-ifc-cap (ifc-cap obj-ifc)) 77 78(define (mk-melee-arms-type tag name sprite to-hit-bonus damage deflect AP_cost AP_mod slots 79 num-hands range weight 80 stratt_mod dexatt_mod 81 damage_mod avoid_mod) 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)) 85 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)) 92 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)) 99 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)) 103 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)) 106 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)) 110 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)) 114 115;; ============================================================================ 116;; Missiles for Projectile Weapons & Spells 117;; ============================================================================ 118 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 ) 136 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) 142 (ifc '() 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 146 x 147 y))))) 148 (if (notnull? targets) 149 (hit (car targets)))))))) 150 151 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)) 156 157(define lightningbolt-ifc 158 (ifc '() 159 (method 'enter 160 (lambda (kmissile kplace x y) 161 ((car temp-ifc-state) kmissile nil nil kplace x y 0) 162 )) 163 )) 164 165(define (on-hit-nontarget ktarget loc dam proc) 166 (for-each proc 167 (if (> dam -1) 168 (filter (lambda (obj) (not (equal? obj ktarget))) 169 (kern-get-objects-at loc)) 170 (kern-get-objects-at loc) 171 )) 172) 173 174(define (on-hit-target ktarget dam proc) 175 (if (> dam -1) 176 (proc ktarget) 177 )) 178 179;; fireball-hit -- when a fireball hits it burns all characters and leaves a 180;; fire 181(define fireball-ifc 182 (ifc '() 183 (method 'hit-loc 184 (lambda (kmissile kuser ktarget kplace x y dam) 185 (let* ( 186 (havemana (> (kern-char-get-mana kuser) 0)) 187 (usedmana (if (and havemana (equal? (kern-dice-roll "1d15") 1)) 188 ( 189 begin 190 (kern-char-set-mana kuser (- (kern-char-get-mana kuser) 1)) 191 #t 192 ) 193 #f)) 194 (setfire (and usedmana (equal? (kern-dice-roll "1d3") 1))) 195 (loc (mk-loc kplace x y)) 196 (hurt (> dam 0)) 197 (targdamage (cond 198 (usedmana (if hurt "2d5+3" "2d4+2")) 199 (havemana (if hurt "2d4+2" "2d3+2")) 200 (else (if hurt "1d4-1" "1d2-1")) 201 )) 202 (othdamage (cond 203 (usedmana "2d3+2") 204 (havemana "1d4") 205 (else "0") 206 )) 207 ) 208 (if (and setfire (terrain-ok-for-field? loc)) 209 (kern-obj-put-at (kern-mk-field F_fire (kern-dice-roll "1d5")) loc)) 210 (if (not havemana) 211 (kern-log-msg "Attack fizzles!")) 212 (on-hit-target ktarget dam 213 (lambda (obj) (generic-burn obj targdamage)) 214 ) 215 (if havemana 216 (on-hit-nontarget ktarget loc dam 217 (lambda (obj) (generic-burn obj othdamage))) 218 ) 219 )) 220 ))) 221 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))) 227 228(define (prismatic-slip ktarget power) 229 (if (and (kern-obj-is-char? ktarget) 230 (contest-of-skill power 231 (occ-ability-dexdefend ktarget))) 232 (slip ktarget))) 233 234(define prismatic-bolt-ifc 235 (ifc '() 236 (method 'hit-loc 237 (lambda (kmissile kuser ktarget kplace x y dam) 238 (let* ( 239 (havemana (> (kern-char-get-mana kuser) 0)) 240 (usedmana (if (and havemana (equal? (kern-dice-roll "1d15") 1)) 241 ( 242 begin 243 (kern-char-set-mana kuser (- (kern-char-get-mana kuser) 1)) 244 #t 245 ) 246 #f)) 247 (magpower (if havemana 248 (if usedmana (max 7 (occ-ability-blackmagic kuser)) 5) 249 0)) 250 (loc (mk-loc kplace x y)) 251 (hit (> dam -1)) 252 (hurt (> dam 0)) 253 (havetarget (not (eqv? ktarget '()))) 254 (pristype (kern-dice-roll "1d100")) 255 (proclist 256 257 (cond ((< pristype 10) 258 (list nil 259 (lambda (obj) (powers-paralyse kuser obj magpower)) 260 (lambda (obj) (powers-paralyse kuser obj (- magpower 3))))) 261 262 ((< pristype 20) 263 (list nil 264 (lambda (obj) (prismatic-acid obj magpower)) 265 (lambda (obj) (prismatic-acid obj (- magpower 3))))) 266 267 ((< pristype 30) 268 (list nil 269 (lambda (obj) (powers-poison-effect kuser obj (+ magpower 3))) 270 (lambda (obj) (powers-poison-effect kuser obj (- magpower 2))))) 271 272 ((< pristype 40) 273 (list nil 274 (lambda (obj) (generic-burn obj "2d3+2")) 275 (lambda (obj) (generic-burn obj "1d5")))) 276 277 ((< pristype 50) 278 (list nil 279 (lambda (obj) (apply-lightning obj)) 280 (lambda (obj) (apply-lightning obj)))) 281 282 ((< pristype 60) 283 (list nil 284 (lambda (obj) (prismatic-slip obj (+ magpower 5))) 285 (lambda (obj) (prismatic-slip obj (+ magpower 2))))) 286 287 ((< pristype 70) 288 (list 289 (lambda (loc) (powers-field-energy-weak kuser loc magpower)) 290 nil nil)) 291 292 ((< pristype 80) 293 (list 294 (lambda (loc) (powers-field-fire-weak kuser loc magpower)) 295 nil nil)) 296 297 ((< pristype 90) 298 (list 299 (lambda (loc) (powers-field-poison-weak kuser loc magpower)) 300 nil nil)) 301 302 ((< pristype 101) 303 (list 304 (lambda (loc) (powers-field-sleep-weak kuser loc magpower)) 305 nil nil)) 306 ))) 307 (if (not havemana) 308 (kern-log-msg "Attack fizzles!") 309 (begin 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))) 316 ) 317 ) 318 )) 319 ))) 320 321(define warhead-ifc 322 (ifc nil 323 (method 'hit-loc 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)))))) 327 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) 337 338(define flaming-oil-ifc 339 (ifc obj-ifc 340 (method 'hit-loc 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)))))) 344 345(define vial-of-slime-ifc 346 (ifc obj-ifc 347 (method 'hit-loc 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))) 352 (cond ((null? loc) 353 (kern-obj-dec-ref knpc) 354 0) 355 (else 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)))))))) 359 360(define smoke-bomb-ifc 361 (ifc obj-ifc 362 (method 'hit-loc 363 (lambda (kmissile kuser ktarget kplace x y dam) 364 (fields-smoke-apply kplace x y 10) 365 )))) 366 367(define (mk-drop-proj-ifc type-tag prob) 368 (ifc obj-ifc 369 (method 'hit-loc 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) 376 )))) 377 ))) 378 379;; todo: handle possibility that magicaxe doesnt have a wielder? 380(define magicaxe-ifc 381 (ifc obj-ifc 382 (method 'hit-loc 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!") 386 ) 387 )) 388) 389 390 391(define missile-arms-types 392 (list 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) 398 mmode-missile #f ) 399 (list 't_bolt_p "bolt" s_bolt (mk-drop-proj-ifc 't_bolt 5) 400 mmode-missile #f ) 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 ) 403 404 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 ) 416 417 418 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) 423 mmode-missile #f ) 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) 427 mmode-missile #f ) 428 (list 't_thrown_boulder_p "hurled boulder" s_thrown_boulder (mk-drop-proj-ifc 't_thrown_boulder 80) 429 mmode-missile #f ) 430 431 (list 't_slime_vial_p "vial of slime" s_thrown_green_potion vial-of-slime-ifc mmode-missile #f ) 432 433 )) 434 435(map (lambda (type) (apply mk-missile-arms-type type)) missile-arms-types) 436 437 438(define ammo-arms-types 439 (list 440 ;; =========================================================================================== 441 ;; tag | name | sprite | gifc | movement_mode 442 ;; =========================================================================================== 443 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 ) 448 )) 449 450 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) 456 457;; ============================================================================ 458;; Projectile Weapons 459;; ============================================================================ 460 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) 466 467(define proj-ifc 468 (ifc obj-ifc 469 (method 'on-attack 470 (lambda (kuser) 471 (println "oa") 472 (kern-sound-play-at sound-missile (kern-obj-get-location kuser)) 473 ) 474 )) 475) 476 477(define projectile-arms-types 478 (list 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) 484 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) 489 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) 494 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) 501 )) 502 503;; ============================================================================ 504;; Thrown Weapons 505;; ============================================================================ 506 507 508(define thrown-arms-types 509 (list 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 ) 515 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 ) 518 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 ) 522 )) 523 524(map (lambda (type) (apply mk-thrown-arms-type type)) thrown-arms-types) 525 526;; Inventory sprites 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) 539 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) 545 mat_blue_to_green) 546(kern-mk-sprite 's_hum_halberd ss_arms 4 64 #f 0) 547 548(define melee-arms-types 549 (list 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 ) 562 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 ) 578 )) 579 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) 586 587(define armor-types 588 (list 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 ) 595 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 ) 598 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 ) 601 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 ) 605 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 ) 608 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 ) 611 )) 612 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) 615 616(define shield-types 617 (list 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 ) 624 )) 625 626 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) 631 632;;---------------------------------------------------------------------------- 633;; Spiked Armor 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) 637 638(kern-mk-arms-type 't_spiked_helm "spiked helm" s_spiked_helm 639 "0" "1d4" "3" "0" 640 slot-helm 1 1 (weap-ap 2) -0 641 nil nil #f #f 642 2 ;; weight 643 nil obj-ifc-cap obj-ifc 644 30 10 20 0.9 mmode-smallobj) 645 646(kern-mk-arms-type 't_spiked_shield "spiked shield" s_spiked_shield 647 "0" "1d5" "0" "5" 648 slot-shield 1 1 (weap-ap 2) -0 649 nil nil #f #f 650 3 ;; weight 651 nil obj-ifc-cap obj-ifc 652 40 20 20 0.8 mmode-largeobj) 653 654;;-------------------------------------------------------------------------- 655;; Special arms types 656;; 657;; These don't fit into the mold for any standard arms type. 658;;-------------------------------------------------------------------------- 659 660(define flaming-sword-ifc 661 (ifc obj-ifc 662 (method 'hit-loc 663 (lambda (kmissile kuser ktarget kplace x y dam) 664 (cond ((equal? dam 0) 665 (generic-burn ktarget "1d5-2")) 666 ((> dam 0) 667 (generic-burn ktarget "2d4")) 668 )) 669 ))) 670 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) 673 674 675(kern-mk-arms-type 't_cannon ; tag 676 "cannon" ; name 677 nil ; sprite 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 687 t_cannonball_p ;; 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 691 0 ;; weight : unused 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 695 0 0 0 1.0 696 mmode-largeobj 697 ) 698 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 707 t_spear 708 t_thrown_rock t_thrown_boulder )) 709; t_lt_crossbow is quick to load, and can be used in melee 710 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 )) 714 715(define (arms-type-is-blockable? karms) 716 (display "arms-type-is-bloackable?")(newline) 717 (in-list? karms blockable-arms-types)) 718 719(define (arms-type-needs-ammo? karms) 720 (in-list? karms arms-types-needing-ammo)) 721 722;;---------------------------------------------------------------------------- 723;; Test paper doll sprites: add a gob to the staff arms type with a "readied" 724;; sprite. 725;;---------------------------------------------------------------------------- 726(kern-type-set-gob t_staff 727 (kern-sprite-blit-over s_hum_staff_gold 728 s_hum_staffglo_blue)) 729 730(kern-type-set-gob t_halberd s_hum_halberd) 731 732;;-------------------------------------------------------------------------- 733;; Cannon mounting for shipboard combat (and maybe anywhere else we can think of later) 734;;-------------------------------------------------------------------------- 735 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)))) 746 (list ix iy #t)) 747 (else (arms-searchline-iter (+ ix dx) (+ iy dy))) 748 )) 749 (let* ((target (arms-searchline-iter (+ x dx) (+ y dy))) 750 (tx (car target)) 751 (ty (cadr target)) 752 (havet (caddr target)) 753 ) 754 (if havet 755 (temp-cannonball-init -1 -1) 756 (temp-cannonball-init tx ty) 757 ) 758 (list tx ty) 759 ))) 760 761(define localcannonball-ifc 762 (ifc '() 763 (method 'hit-loc 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)) 767 ( 768 begin 769 (kern-log-msg (kern-obj-get-name ktarget) " hit by cannonball!") 770 (kern-obj-apply-damage ktarget "cannon" (kern-dice-roll "1d10+4")) 771 ) 772 ) 773 )) 774 ))) 775 776(mk-missile-arms-type 't_localcannonball "cannonball" s_cannonball localcannonball-ifc mmode-cannon #f) 777 778(define cannon-ifc 779 (ifc '() 780 (method 'xamine 781 (lambda (kcannon kuser) 782 (let ((ready (cadr (gob kcannon)))) 783 (kern-log-msg "The cannon is " 784 (cond ((equal? ready 2) 785 "ready to fire") 786 ((equal? ready 1) 787 "loaded but unready") 788 (else "unloaded"))) 789 result-ok 790 )) 791 ) 792 (method 'handle 793 (lambda (kcannon kuser) 794 (let ((ready (cadr (gob kcannon))) 795 (facing (car (gob kcannon)))) 796 (kern-obj-dec-ap kuser speed-human) 797 (cond 798 ((equal? ready 2) 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))) 807 ) 808 (bind kcannon (list facing 0))) 809 ((equal? ready 1) 810 (kern-log-msg "Cannon ready to fire") 811 (bind kcannon (list facing 2))) 812 (else 813 (kern-log-msg "Cannon loaded") 814 (bind kcannon (list facing 1))) 815 ) 816 )) 817 ) 818 (method 'init 819 (lambda (kcannon) 820 (kern-obj-set-facing kcannon (car (gob kcannon))) 821 (kern-obj-set-pclass kcannon pclass-boulder) 822 )) 823 )) 824 825(mk-obj-type 't_cannonobj "cannon" s_cannon layer-mechanism cannon-ifc) 826 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)) 831 kcannon)) 832 833;; Weapons that aren't affected by acid 834(define arms-immune-to-acid 835 (list t_flaming_sword 836 t_shield_4 837 t_armor_plate_4 838 t_armor_chain_4 839 t_armor_leather_2 840 t_armor_leather_4 841 t_iron_helm_4 842 t_chain_coif_4 843 t_leather_helm_2 844 t_leather_helm_4 845 t_sword_2 846 t_sword_4 847 t_eldritch_blade 848 t_mystic_sword 849 t_magic_axe 850 t_doom_staff 851 t_stun_wand)) 852