# determine locations and angles relative to monster and player locations # Triangulate.tz (c) 2010 Jacob Schrum. # See Simulation.tz for more copyright information @use Abstract. @define BOUNDING_BOX_BUFFER 3. Abstract : Triangulate { + variables: math (object). theta-starts (list). current-theta (int). + to archive: return 1. + to dearchive: # Hopefully the controller is dearchived first self give-math of (controller get-math). if math : return 1. else return 0. + to is-surrounded by objs (list) point-at loc (vector): box (list). # returns {left, right, bottom, top} box = (self bounding-box given objs). if loc::x < box{0} : return 0. if loc::x > box{1} : return 0. if loc::z < box{2} : return 0. if loc::z > box{3} : return 0. # otherwise the point is inside the bounding box return 1. + to fill-theta-starts with-sub-pops number-of-subpops (int) monsters-per-sub monsters-from-each-subpop (int): i (int). # Figure out theta-starts for start-surrounding theta-starts = {}. for i = 0, i < (number-of-subpops * monsters-from-each-subpop), i++ : { push (i * ((2 * PI) / (number-of-subpops * monsters-from-each-subpop))) onto theta-starts. } current-theta = 0. + to next-theta-location: current-theta = (current-theta + 1) % |theta-starts|. return theta-starts{current-theta}. + to give-math of m (object): math = m. + to get-object-locations given objs (list) living-only filter = 1 (int): locations (list). temp-loc (vector). i (int). for i = 0, i < |objs|, i++ : { temp-loc = (objs{i} get-location). # Only include location if monster is alive (not hidden beneath plane) if ((temp-loc::y > -1) || !filter) : push temp-loc onto locations. } return locations. # objs: list of Monsters # - returns list whose contents represent the edges of a box + to bounding-box given objs (list): locs (list). left (double). right (double). top (double). bottom (double). v (vector). i (int). locs = (self get-object-locations given objs). v = (locs{0}). left = v::x. right = left. top = v::z. bottom = top. for i = 1, i < |locs|, i++ : { v = (locs{i}). if v::x < left : left = v::x. if v::x > right : right = v::x. if v::z < bottom : bottom = v::z. if v::z > top : top = v::z. } return {(left - BOUNDING_BOX_BUFFER), (right + BOUNDING_BOX_BUFFER), (bottom - BOUNDING_BOX_BUFFER), (top + BOUNDING_BOX_BUFFER)}. + to get-center-of-mass given objs (list): center (vector). locs (list). i (int). center = (0,0,0). locs = (self get-object-locations given objs). for i = 0, i < |locs|, i++ : { center += locs{i}. } if |locs| > 0 : center = center / |locs|. return center. + to get-angle-to-center from loc (vector) facing direction (vector) given objs (list): center (vector). center = (self get-center-of-mass given objs). if center == loc : return 0. else { return (math signed-angle-difference between direction and (center - loc)). } + to get-nearest-object to loc (vector) given objs (list): locations (list). minVal (double). minPos (int). distance (double). i (int). temp-loc (vector). locations = (self get-object-locations given objs living-only 0). minVal = INFINITY. minPos = -1. for i = 0, i < |locations|, i++ : { temp-loc = locations{i}. if (temp-loc::y > -1) : { distance = |(temp-loc - loc)|. if distance < minVal : { minVal = distance. minPos = i. } } } if minPos == -1 : return 0. return (objs{minPos}). + to get-nearest-object-location to loc (vector) given objs (list): obj (object). obj = (self get-nearest-object to loc given objs). if obj : return (obj get-location). else return loc. + to get-distance-to-nearest-object from loc (vector) given objs (list): return |(loc - (self get-nearest-object-location to loc given objs))|. + to get-angle-to-nearest-object from loc (vector) facing direction (vector) given objs (list): object-location (vector). object-location = (self get-nearest-object-location to loc given objs). if object-location == loc : return 0. else { return (math signed-angle-difference between direction and (object-location - loc)). } # Objects relative to player + to get-nearest-monster-in-front to loc (vector) given monsters (list): temp-list (list). i (int). temp-list = {}. for i = 0, i < |monsters|, i++ : { if ((monsters{i}) in-front-of-player) : { push (monsters{i}) onto temp-list. } } return (self get-nearest-object to loc given temp-list). + to get-nearest-monster-location-in-front to loc (vector) given monsters (list): mon (object). mon = (self get-nearest-monster-in-front to loc given monsters). if mon : return (mon get-location). else return loc. + to get-angle-to-nearest-monster-in-front from loc (vector) facing direction (vector) given monsters (list): monster-location (vector). monster-location = (self get-nearest-monster-location-in-front to loc given monsters). if monster-location == loc : return 0. else { return (math signed-angle-difference between direction and (monster-location - loc)). } # Monsters relative to other monsters + to get-signed-neg-difference-in-heading-from-heading-rear of monster1 (int) to monster2 (int) given monsters (list): if (monsters{ monster2 } get-deaths) > 0 : return 0. return (-1 * (math signed-angle-difference between (- ((monsters{ monster1 }) get-facing)) and ((monsters{ monster2 }) get-facing))). + to get-signed-neg-angle-from-rear of monster1 (int) to monster2 (int) given monsters (list): if (monsters{ monster2 } get-deaths) > 0 : return 0. return (-1 * (math signed-angle-difference between (- ((monsters{ monster1 }) get-facing)) and (self get-vector-between-monsters from monster1 to monster2 given monsters))). + to get-vector-between-monsters from monster1 (int) to monster2 (int) given monsters (list): if (monsters{ monster2 } get-deaths) > 0 : return (0,0,0). return ((monsters{ monster2 } get-location) - (monsters{ monster1 } get-location)). + to get-distance-to-monster-nearest to monsterPos (int) given monsters (list): if (monsters{ monsterPos } get-deaths) > 0 : return 0. return (self get-distance-to-nearest-object from (monsters{ monsterPos } get-location) given monsters). + to get-angle-to-monster-nearest to monsterPos (int) given monsters (list): if (monsters{ monsterPos } get-deaths) > 0 : return 0. return (self get-angle-to-nearest-object from (monsters{ monsterPos } get-location) facing (monsters{ monsterPos } get-facing) given monsters). }