nodes: 0, module; 1, function_definition; 2, function_name:_visible_units; 3, parameters; 4, block; 5, identifier:self; 6, expression_statement; 7, comment:# Sort the units by elevation, then owned (eg refinery) above world (ie 16); 8, comment:# (eg geiser), small above big, and otherwise arbitrary but stable.; 9, for_statement; 10, comment:"""A generator of visible units and their positions as `Point`s, sorted."""; 11, identifier:u; 12, call; 13, block; 14, identifier:sorted; 15, argument_list; 16, expression_statement; 17, attribute; 18, keyword_argument; 19, yield; 20, attribute; 21, identifier:units; 22, identifier:key; 23, lambda; 24, expression_list; 25, attribute; 26, identifier:raw_data; 27, lambda_parameters; 28, tuple; 29, identifier:u; 30, call; 31, attribute; 32, identifier:observation; 33, identifier:u; 34, attribute; 35, comparison_operator:u.owner != 16; 36, unary_operator; 37, attribute; 38, attribute; 39, argument_list; 40, identifier:self; 41, identifier:_obs; 42, attribute; 43, identifier:z; 44, attribute; 45, integer:16; 46, attribute; 47, identifier:u; 48, identifier:tag; 49, attribute; 50, identifier:build; 51, attribute; 52, identifier:u; 53, identifier:pos; 54, identifier:u; 55, identifier:owner; 56, identifier:u; 57, identifier:radius; 58, identifier:point; 59, identifier:Point; 60, identifier:u; 61, identifier:pos
code: def _visible_units(self):
      """A generator of visible units and their positions as `Point`s, sorted."""
      # Sort the units by elevation, then owned (eg refinery) above world (ie 16)
      # (eg geiser), small above big, and otherwise arbitrary but stable.
      for u in sorted(self._obs.observation.raw_data.units,
                      key=lambda u: (u.pos.z, u.owner != 16, -u.radius, u.tag)):
        yield u, point.Point.build(u.pos)