import('math', '_euclidean_sq', '_euclidean'); global_renderers = m( l('structures', m( l('active', false), l('handler', '__structure_renderer'), l('tasks', m()), l('range', 3), l('max_pieces', 6) )), l('chunks', m( l('active', false), l('handler', '__chunk_renderer'), l('tasks', m()), l('range', 6) )), l('shapes', m( l('active', false), l('handler', '__shape_renderer'), l('tasks', m()), l('range', 8) )), 'portals' -> { 'active' -> false, 'handler' -> '__portal_renderer', 'tasks' -> {} } ); __command() -> ''; monument() -> __toggle('monument', 'structures'); fortress() -> __toggle('fortress', 'structures'); mansion() -> __toggle('mansion', 'structures'); jungle_pyramid() -> __toggle('jungle_pyramid', 'structures'); desert_pyramid() -> __toggle('desert_pyramid', 'structures'); endcity() -> __toggle('endcity', 'structures'); igloo() -> __toggle('igloo', 'structures'); shipwreck() -> __toggle('shipwreck', 'structures'); swamp_hut() -> __toggle('swamp_hut', 'structures'); stronghold() -> __toggle('stronghold', 'structures'); ocean_ruin() -> __toggle('ocean_ruin', 'structures'); buried_treasure() -> __toggle('buried_treasure', 'structures'); pillager_outpost() -> __toggle('pillager_outpost', 'structures'); mineshaft() -> __toggle('mineshaft', 'structures'); village() -> __toggle('village', 'structures'); nether_fossil() -> __toggle('nether_fossil', 'structures'); bastion_remnant() -> __toggle('bastion_remnant', 'structures'); ruined_portal() -> __toggle('ruined_portal', 'structures'); slime_chunks() -> __toggle('slime_chunks', 'chunks'); portal_coordinates() -> __toggle('coords', 'portals'); portal_links() -> __toggle('links', 'portals'); clear() -> for(global_renderers, global_renderers:_:'tasks' = m() ); __toggle(feature, renderer) -> ( p = player(); config = global_renderers:renderer; if( has(config:'tasks':feature), delete(config:'tasks':feature); 'disabled '+feature+' overlays'; , config:'tasks' += feature; if (!config:'active', call(config:'handler', p~'name')); 'enabled '+feature+' overlays'; ) ); __should_run(renderer, player_name) -> ( config = global_renderers:renderer; if (length(config:'tasks')==0, config:'active' = false; return(l(null, null))); p = player(player_name); if (!p, config:'active' = false; clear(); return(l(null, null))); config:'active' = true; l(p, config); ); __structure_renderer(player_name) -> ( l(p, config) = __should_run('structures', player_name); if (!p, return()); in_dimension(p, ppos = pos(p); starts = m(); r = config:'range'; for(range(-r,r), cx =_; for (range(-r,r), cz = _; ref_pos = ppos + l(16*cx,0,16*cz); for(filter(structure_references(ref_pos), has(config:'tasks':_)), name = _; for(structure_references(ref_pos, name), starts += l(_, name); ) ) ) ); for (starts, l(position, name) = _; structure_data = structures(position):name; if (!structure_data, continue()); // messed up references - shouldn't happen structure_pieces = structures(position, name):'pieces'; if (!structure_pieces, continue()); // messed up references - shouldn't happen l(from, to) = structure_data; total_size = _euclidean(from, to); density = max(10, total_size/10); draw_shape('box', 15, 'from', from, 'to', to+1, 'color', 0x00FFFFFF, 'line', 3, 'fill', 0x00FFFF12); structure_pieces = slice(sort_key(structure_pieces, _euclidean_sq((_:2+_:3)/2,ppos)), 0, config:'max_pieces'); for (structure_pieces, l(piece, direction, from, to) = _; r = 255 - floor(128 * _i/config:'max_pieces'); g = r; b = 255; a = 255; color = 256*(b+256*(g+256*r)); // leaving out a draw_shape('box', 15, 'from', from, 'to', to+1, 'color', color+a); draw_shape('box', 15, 'from', from, 'to', to+1, 'color', 0xffffff00, 'fill', 0xffffff22); ) ) ); schedule(10, '__structure_renderer', player_name); ); __chunk_renderer(player_name) -> ( l(p, config) = __should_run('chunks', player_name); if (!p, return()); in_dimension( p, // get lower corner of the chunk ppos = map(pos(p)/16, floor(_))*16; ppos:1 = 0; rang = config:'range'; for(range(-rang,rang), cx =_; for (range(-rang,rang), cz = _; ref_pos = ppos + l(16*cx,0,16*cz); if(has(config:'tasks':'slime_chunks') && in_slime_chunk(ref_pos), player_distance = _euclidean(ppos, ref_pos); top_00 = ref_pos + l(0, top('terrain', ref_pos)+10, 0); top_11 = ref_pos + l(16, top('terrain', ref_pos+l(15,0,15))+10, 16); top_10 = ref_pos + l(16, top('terrain', ref_pos+l(15, 0, 0))+10, 0); top_01 = ref_pos + l(0, top('terrain', ref_pos+l(0, 0, 15))+10, 16); r = 30; g = 220; b = 30; a = max(0, 255-player_distance); color = a+256*(b+256*(g+256*r)); draw_shape(l( l('line', 15, 'from', top_00, 'to', top_10, 'color', color, 'line', 3), l('line', 15, 'from', top_10, 'to', top_11, 'color', color, 'line', 3), l('line', 15, 'from', top_11, 'to', top_01, 'color', color, 'line', 3), l('line', 15, 'from', top_01, 'to', top_00, 'color', color, 'line', 3), l('line', 15, 'from', top_00, 'to', top_11, 'color', color, 'line', 3), l('line', 15, 'from', top_01, 'to', top_10, 'color', color, 'line', 3) )); ) ) ) ); schedule(10, '__chunk_renderer', player_name); ); __portal_renderer(player_name) -> ( l(p, config) = __should_run('portals', player_name); if (!p, return()); dim = p~'dimension'; shapes = []; shape_duration = 6; ppos = pos(p); py = ppos:1; if (dim == 'overworld', // nether_pos = [ppos:0/8, py, ppos:2/8]; if (has(config:'tasks':'coords'), ow_x = 8*floor(nether_pos:0); ow_z = 8*floor(nether_pos:2); for (range(-5,6), dx = _; for (range(-5,6), dz = _; x = ow_x + 8*dx; z = ow_z + 8*dz; nx = x / 8; nz = z / 8; shapes += ['line', shape_duration, 'from', [x,0,z], 'to', [x,255,z], 'line', 2]; shapes += ['box', shape_duration, 'from', [x,0,z], 'to', [x+8,255,z+8], 'color', 0x00000000, 'fill', 0xffffff05]; shapes += ['label', shape_duration, 'pos', [x+4, 1,z+4], 'text', [nx, floor(py), nz], 'follow', p, 'snap', 'y']; ) ); ); if (has(config:'tasks':'links'), in_dimension('the_nether', portals = map(poi(nether_pos, 16, 'nether_portal', 'any', true), [x,y,z]=_:2; [[x,y,z], [8*x,y,8*z]]); if (portals, sorted_portals = __sort_portals(nether_pos, portals); offset = p~'look' + [0,p~'eye_height',0]; for(sorted_portals, [pos, display] = _; color = if(_i, 0x00999999, 0x990099ff); to_rel = display-ppos; shapes += ['line', shape_duration, 'line', 5, 'from', [0,0.5,0], 'to', to_rel, 'color', color,'follow', p]; to_dist = _euclidean([0,0,0],to_rel); if (to_dist > 3, direction = to_rel / to_dist; shapes += ['label', shape_duration, 'pos', [0,0.5,0]+(2+1*_i)*direction, 'text', pos, 'color', color, 'follow', p]; ) ) ) ) ); , dim == 'the_nether', look = query(p, 'trace', 10, 'blocks', 'exact'); if (look, ly = look:1; ow_pos = [8*look:0, look:1, 8*look:2]; nx = floor(8*look:0)/8; nz = floor(8*look:2)/8; shapes += ['box', shape_duration, 'from', [nx, ly-1, nz], 'to', [nx+0.125, ly+1, nz+0.125]]; if (has(config:'tasks':'coords'), shapes += ['label', shape_duration, 'pos', look-ppos+[0,0.25,0], 'follow', p, 'text', map(ow_pos,floor(_))]; ); if (has(config:'tasks':'links'), in_dimension('overworld', portals = map(poi(ow_pos, 128, 'nether_portal', 'any', true), [x,y,z]=_:2; [[x,y,z], [x/8,y,z/8]]); if (portals, sorted_portals = __sort_portals(ow_pos, portals); for(sorted_portals, [pos, display] = _; color = if(_i, 0x00999999, 0x990099ff); to_rel = display-ppos; shapes += ['line', shape_duration, 'line', 5, 'from', look-ppos+[0,1.0,0], 'to', to_rel, 'color', color, 'follow', p]; to_dist = _euclidean([0,0,0],to_rel); if (to_dist > 3, direction = to_rel / to_dist; shapes += ['label', shape_duration, 'pos', look-ppos+[0,1.1,0]+(0.2+0.5*_i)*direction, 'text', pos, 'color', color, 'follow', p] ); ) ) ) ) ) ); if (shapes, in_dimension(p, draw_shape(shapes))); schedule(5, '__portal_renderer', player_name); ); __sort_portals(ref_pos, portals) -> ( point_map = {}; for (portals, point_map:(_:0) = _:1); sorted_portals = sort_key(keys(point_map), _euclidean_sq(ref_pos, _)+0.0001*(_:1)); output_locations = []; seen_portals = {}; for (sorted_portals, [x,y,z] = _; if ( !has(seen_portals, [x,y+1,z]) && !has(seen_portals, [x,y-1,z]), output_locations += _; ); seen_portals += _; ); base_portals = []; seen_bases = {}; for (output_locations, [x,y,z] = _; while(has(seen_portals, [x,y,z]), 256, y += -1); y += 1; seen_bases += [x,y,z]; if (!has(seen_bases, [x-1,y,z]) && !has(seen_bases, [x+1,y,z]) && !has(seen_bases, [x,y,z-1]) && !has(seen_bases, [x,y,z+1]), base_portals += [x,y,z]; ) ); map(base_portals, [_, point_map:_]); );