1; (define (troll-display . args) 2; (display (kern-get-ticks)) 3; (display ":") 4; (apply display args)) 5; (define (troll-newline) (newline)) 6 7(define (troll-display . args) ) 8(define (troll-newline) ) 9(define troll-melee-weapon t_horns) 10 11;;---------------------------------------------------------------------------- 12;; Troll AI 13;;---------------------------------------------------------------------------- 14(define (troll-is-critical? ktroll) 15 (< (kern-char-get-hp ktroll) 5)) 16 17(define (troll-wander ktroll) 18 (troll-display "troll-wander")(troll-newline) 19 (wander ktroll)) 20 21(define (troll-flee ktroll) 22 (troll-display "troll-flee")(troll-newline) 23 (flee ktroll)) 24 25(define (troll-foes-in-weapon-range ktroll karms kfoes) 26 (troll-display "troll-foes-in-weapon-range")(troll-newline) 27 (all-in-range (kern-obj-get-location ktroll) 28 (kern-arms-type-get-range karms) 29 kfoes)) 30 31(define (weaker? a b) 32 (< (kern-char-get-hp a) (kern-char-get-hp b))) 33 34(define (troll-pick-target ktroll foes) 35 (troll-display "troll-pick-target")(troll-newline) 36 (foldr (lambda (a b) (if (weaker? a b) a b)) 37 (car foes) 38 (cdr foes))) 39 40(define (troll-pathfind-foe ktroll foes) 41 (troll-display "troll-pathfind-foe")(troll-newline) 42 (let ((ktarg (troll-pick-target ktroll foes))) 43 (if (notnull? ktarg) 44 (pathfind ktroll (kern-obj-get-location ktarg))))) 45 46(define (troll-attack ktroll karms foes) 47 (troll-display "troll-attack")(troll-newline) 48 (kern-char-attack ktroll 49 karms 50 (troll-pick-target ktroll 51 foes))) 52 53;; Given an "origin" location and a list of locations, find the location in the 54;; list closest to the coordinates. 55(define (loc-closest origin lst) 56 (if (null? lst) nil 57 (foldr (lambda (a b) (if (loc-closer? a b origin) a b)) 58 (car lst) 59 (cdr lst)))) 60 61(define (troll-stronger? ktroll foes) 62 (> (kern-char-get-strength ktroll) 63 (foldr (lambda (a b) (+ a (kern-char-get-strength b))) 64 0 65 foes))) 66 67(define (troll-has-ranged-weapon? ktroll) 68 (in-inventory? ktroll troll-ranged-weapon)) 69 70;; troll-get-ammo -- give troll a boulder and convert terrain to grass 71(define (troll-get-terrain-ammo ktroll coords) 72 (troll-display "troll-get-terrain-ammo")(troll-newline) 73 (kern-obj-add-to-inventory ktroll troll-ranged-weapon 1) 74 (kern-place-set-terrain coords t_grass) 75 (kern-map-repaint) 76 (kern-obj-dec-ap ktroll troll-ripup-boulder-ap) 77 ) 78 79;; ---------------------------------------------------------------------------- 80;; troll-get-loose-ammo -- search the objects at the location for ammo and give 81;; it to the th character 82;; ---------------------------------------------------------------------------- 83(define (troll-get-loose-ammo ktroll loc) 84 (troll-display "troll-get-loose-ammo")(troll-newline) 85 (kobj-get-at ktroll loc troll-ranged-weapon)) 86 87;; ---------------------------------------------------------------------------- 88;; troll-terrain-is-ammo -- true iff the given location's terrain can be 89;; converted by a troll into ammo 90;; ---------------------------------------------------------------------------- 91(define (troll-terrain-is-ammo? coords) 92 (eqv? t_boulder (kern-place-get-terrain coords))) 93 94;; ---------------------------------------------------------------------------- 95;; troll-find-nearest-ammo -- return the closest location with ammo objects or 96;; with terrain that can be converted to ammo objects. 97;; ---------------------------------------------------------------------------- 98(define (troll-find-nearest-ammo ktroll) 99 (troll-display "troll-find-nearest-ammo")(troll-newline) 100 (define (scanobjlst lst) 101 (foldr (lambda (a b) 102 (or a (eqv? (kern-obj-get-type b) troll-ranged-weapon))) 103 #f 104 lst)) 105 (define (check lst loc) 106 (if (troll-terrain-is-ammo? loc) 107 (cons loc lst) 108 (if (scanobjlst (kern-get-objects-at loc)) 109 (cons loc lst) 110 lst))) 111 (let* ((loc (kern-obj-get-location ktroll)) 112 (rad (kern-obj-get-vision-radius ktroll)) 113 (coords (profile foldr-rect (loc-place loc) 114 (- (loc-x loc) (/ rad 2)) 115 (- (loc-y loc) (/ rad 2)) 116 (* 1 rad) 117 (* 1 rad) 118 check 119 nil))) 120 (troll-display coords)(troll-newline) 121 (profile loc-closest loc coords))) 122 123(define (troll-find-nearest-ammo2 ktroll) 124 (troll-display "troll-find-nearest-ammo2")(troll-newline) 125 (let* ((loc (kern-obj-get-location ktroll)) 126 (rad (kern-obj-get-vision-radius ktroll)) 127 (coords (profile kern-search-rect (loc-place loc) 128 (- (loc-x loc) (/ rad 2)) 129 (- (loc-y loc) (/ rad 2)) 130 (* 1 rad) 131 (* 1 rad) 132 t_boulder 133 troll-ranged-weapon))) 134 (profile loc-closest loc coords))) 135 136(define (troll-find-nearest-ammo3 ktroll) 137 (troll-display "troll-find-nearest-ammo3")(troll-newline) 138 (define (scanobjlst lst) 139 (foldr (lambda (a b) 140 (or a (eqv? (kern-obj-get-type b) troll-ranged-weapon))) 141 #f 142 lst)) 143 (define (check lst loc) 144 (if (troll-terrain-is-ammo? loc) 145 (cons loc lst) 146 (if (scanobjlst (kern-get-objects-at loc)) 147 (cons loc lst) 148 lst))) 149 (let* ((loc (kern-obj-get-location ktroll)) 150 (rad (kern-obj-get-vision-radius ktroll)) 151 (coords (profile kern-fold-rect (loc-place loc) 152 (- (loc-x loc) (/ rad 2)) 153 (- (loc-y loc) (/ rad 2)) 154 (* 1 rad) 155 (* 1 rad) 156 check 157 nil))) 158 (troll-display coords)(troll-newline) 159 (profile loc-closest loc coords))) 160 161(define (troll-find-nearest-ammo4 ktroll) 162 (troll-display "troll-find-nearest-ammo4")(troll-newline) 163 (let* ((loc (kern-obj-get-location ktroll)) 164 (rad (kern-obj-get-vision-radius ktroll)) 165 (terrain-coords (profile kern-search-rect-for-terrain (loc-place loc) 166 (- (loc-x loc) (/ rad 2)) 167 (- (loc-y loc) (/ rad 2)) 168 (* 1 rad) 169 (* 1 rad) 170 t_boulder)) 171 (closest-terrain (profile loc-closest loc terrain-coords)) 172 (obj-coords (profile kern-search-rect-for-obj-type (loc-place loc) 173 (- (loc-x loc) (/ rad 2)) 174 (- (loc-y loc) (/ rad 2)) 175 (* 1 rad) 176 (* 1 rad) 177 troll-ranged-weapon)) 178 (closest-obj (profile loc-closest loc obj-coords))) 179 (cond ((null? closest-obj) closest-terrain) 180 ((null? closest-terrain) closest-obj) 181 (else 182 (if (loc-closer? closest-obj closest-terrain loc) 183 closest-obj 184 closest-terrain))))) 185 186;; ---------------------------------------------------------------------------- 187;; troll-get-ammo -- given the location of an ammo object or terrain that can 188;; be converted to ammo, have the troll get the ammo 189;; ---------------------------------------------------------------------------- 190(define (troll-get-ammo ktroll loc) 191 (troll-display "troll-get-ammo")(troll-newline) 192 (if (troll-terrain-is-ammo? loc) 193 (troll-get-terrain-ammo ktroll loc) 194 (troll-get-loose-ammo ktroll loc))) 195 196;; ---------------------------------------------------------------------------- 197;; troll-hunt-for-ammo2 -- find the nearest available ammo and pathfind to it 198;; or pick it up. Returns false iff none available. 199;; ---------------------------------------------------------------------------- 200(define (troll-hunt-for-ammo ktroll) 201 (troll-display "troll-hunt-for-ammo")(troll-newline) 202 (let ((nearest (profile troll-find-nearest-ammo2 ktroll)) 203 (kloc (kern-obj-get-location ktroll))) 204 (troll-display "nearest=")(troll-display nearest)(troll-newline) 205 (if (null? nearest) 206 #f 207 (begin 208 (do-or-goto ktroll nearest troll-get-ammo) 209 #t)))) 210 211(define (troll-display-objs lst) 212 (if (null? lst) 213 (troll-newline) 214 (begin 215 (troll-display (kern-obj-get-name (car lst))) 216 (troll-display " ") 217 (troll-display-objs (cdr lst))))) 218 219(define (troll-no-hostiles ktroll) 220 (troll-display "troll-no-hostiles")(troll-newline) 221 (troll-wander ktroll)) 222 223(define troll-taunts 224 (list 225 "[primal howl]" 226 "[hateful roar]" 227 "[raging bellow]" 228 )) 229 230(define (troll-taunt ktroll ktarg) 231 (taunt ktroll ktarg troll-taunts) 232 (npcg-set-taunted! (gob ktroll) #t)) 233 234(define (troll-hostiles ktroll foes) 235 (troll-display "troll-hostiles")(troll-newline) 236 (if (troll-is-critical? ktroll) 237 (troll-flee ktroll) 238 (let ((melee-targs (troll-foes-in-weapon-range ktroll 239 troll-melee-weapon 240 foes))) 241 (troll-display "troll-ai:melee-targs=") 242 (troll-display melee-targs) 243 (troll-newline) 244 (or (npcg-taunted? (gob ktroll)) 245 (troll-taunt ktroll (car foes))) 246 (if (null? melee-targs) 247 (if (troll-has-ranged-weapon? ktroll) 248 (let 249 ((ranged-foes 250 (troll-foes-in-weapon-range ktroll 251 troll-ranged-weapon 252 foes))) 253 (troll-display "troll-ai:ranged-foes=") 254 (troll-display ranged-foes) 255 (troll-newline) 256 (if (null? ranged-foes) 257 (troll-pathfind-foe ktroll foes) 258 (troll-attack ktroll troll-ranged-weapon 259 ranged-foes))) 260 (or (troll-hunt-for-ammo ktroll) 261 (troll-pathfind-foe ktroll foes))) 262 (if (troll-stronger? ktroll melee-targs) 263 (troll-attack ktroll troll-melee-weapon melee-targs) 264 (evade ktroll melee-targs)))))) 265 266;; ---------------------------------------------------------------------------- 267;; troll-ai -- combat ai for a troll npc. Called repeatedly by the kernel on 268;; the troll's turn until the troll is out of ap. 269;; ---------------------------------------------------------------------------- 270(define (troll-ai ktroll) 271 (troll-display "troll-ai")(troll-newline) 272 (let ((foes (all-visible-hostiles ktroll))) 273 (if (null? foes) 274 (troll-wander ktroll) 275 (troll-hostiles ktroll foes)) 276 #t)) 277