extra FragmentShader(VertexOut vertex, Field <data> Data, Field <unit> Unit, Field <extra> Extra, vec2 Destination, [Player.Vals] float player, [SelectionFilter.Vals] float filter) { data data_here = Data[Here]; unit unit_here = Unit[Here]; extra extra_here = Extra[Here]; if (player == unit_here.player && selected(data_here) && SelectionFilter.FilterHasUnit(filter, unit_here.type)) { extra_here = extra.Nothing; } return(extra_here); }
extra FragmentShader(VertexOut vertex, Field <data> Data, Field <extra> Extra, Field <geo> Geo, Field <geo> AntiGeo) { data data_here = Data[Here]; extra extra_here = Extra[Here]; geo geo_here = Geo[Here]; if (data_here.change >= SetPolarity.Counterclockwise) { extra_here.geo_id = geo_here.geo_id; extra_here.polarity_set = _true; extra_here.polarity = Polarity.Counterclockwise; } else if (data_here.change >= SetPolarity.Clockwise) { extra_here.geo_id = geo_here.geo_id; extra_here.polarity_set = _true; extra_here.polarity = Polarity.Clockwise; } return(extra_here); }
void NaivePathfind(VertexOut vertex, Field <data> Current, Field <data> Previous, Field <vec4> TargetData, Field <extra> Extra, Field <vec4> RandomField, Field <geo> Geo, Field <geo> AntiGeo, Field <dirward> DirwardRight, Field <dirward> DirwardLeft, Field <dirward> DirwardUp, Field <dirward> DirwardDown, unit data, ref data here) { // Get geodesic info (of both polarities) geo geo_here = Geo[Here], antigeo_here = AntiGeo[Here]; // Unpack packed info vec4 target = TargetData[Here]; vec2 CurPos = floor((vertex.TexCoords * TargetData.Size + vec(.5f, .5f))); vec2 Destination = floor(unpack_vec2((vec4)target)); // Get nearby units data right = Current[RightOne], up = Current[UpOne], left = Current[LeftOne], down = Current[DownOne]; data prev_right = Previous[RightOne], prev_up = Previous[UpOne], prev_left = Previous[LeftOne], prev_down = Previous[DownOne]; extra extra_here = Extra[Here]; // Calculate primary and secondary direction to travel (dir1 and dir2 respectively) float dir1 = Dir.None, dir2 = Dir.None; if (Destination.x > CurPos.x + .75f) { dir1 = Dir.Right; } if (Destination.x < CurPos.x - .75f) { dir1 = Dir.Left; } if (Destination.y > CurPos.y + .75f) { dir1 = Dir.Up; } if (Destination.y < CurPos.y - .75f) { dir1 = Dir.Down; } vec2 diff = Destination - CurPos; vec2 mag = abs(diff); float prior_dir = Dir.None; bool blocked1 = false; if (mag.x > mag.y && Destination.x > CurPos.x + 1) { dir1 = Dir.Right; blocked1 = Something(right) || Something(prev_right) && prior_dir != Dir.Left; } if (mag.y > mag.x && Destination.y > CurPos.y + 1) { dir1 = Dir.Up; blocked1 = Something(up) || Something(prev_up) && prior_dir != Dir.Down; } if (mag.x > mag.y && Destination.x < CurPos.x - 1) { dir1 = Dir.Left; blocked1 = Something(left) || Something(prev_left) && prior_dir != Dir.Right; } if (mag.y > mag.x && Destination.y < CurPos.y - 1) { dir1 = Dir.Down; blocked1 = Something(down) || Something(prev_down) && prior_dir != Dir.Up; } bool blocked2 = false; if (dir1 == Dir.Right || dir1 == Dir.Left) { if (Destination.y > CurPos.y + 0) { dir2 = Dir.Up; blocked2 = Something(up) || Something(prev_up) && prior_dir != Dir.Down; } else if (Destination.y < CurPos.y - 0) { dir2 = Dir.Down; blocked2 = Something(down) || Something(prev_down) && prior_dir != Dir.Up; } } if (dir1 == Dir.Up || dir1 == Dir.Down) { if (Destination.x > CurPos.x + 0) { dir2 = Dir.Right; blocked2 = Something(right) || Something(prev_right) && prior_dir != Dir.Left; } else if (Destination.x < CurPos.x - 0) { dir2 = Dir.Left; blocked2 = Something(left) || Something(prev_left) && prior_dir != Dir.Right; } } // Get current coordinate vec2 pos_here = vertex.TexCoords * Geo.Size; // Get dirward extensions for each direction, as well as whether we need to cross over an obstacle to get to where we want to go in that direction. dirward dirward_here1 = dirward.Nothing; dirward dirward_here2 = dirward.Nothing; bool other_side1 = GetDirward(ref dirward_here1, dir1, ref Destination, ref pos_here, DirwardRight, DirwardLeft, DirwardUp, DirwardDown); bool other_side2 = GetDirward(ref dirward_here2, dir2, ref Destination, ref pos_here, DirwardRight, DirwardLeft, DirwardUp, DirwardDown); // Get polarity based on the dirward extensions float polarity1 = dirward_here1.polarity, polarity2 = dirward_here2.polarity, chosen_polarity = Polarity.Undefined; // If this unit has already picked a polarity for this geodesic area, then we will stick with that polarity if (extra_here.geo_id == geo_here.geo_id && extra_here.polarity_set == _true) { polarity1 = extra_here.polarity; polarity2 = extra_here.polarity; } // Get geodesic info associated with primary and secondary direction (geo1 for dir1 and geo2 for dir2) geo geo1 = polarity1 == Polarity.Counterclockwise ? antigeo_here : geo_here, geo2 = polarity2 == Polarity.Counterclockwise ? antigeo_here : geo_here; // Check if we should follow the geodesic we are on vec2 geo_id = geo1.geo_id; bool use_simple_pathing = false; if (geo1.dir > 0 && ValidDirward(dirward_here1) && other_side1 && dirward_here1.geo_id == geo_id && (/*geo1.dist == _0 ||*/ blocked1 || extra_here.polarity_set == _true && extra_here.geo_id == geo1.geo_id)) { dir1 = geo1.dir; chosen_polarity = polarity1; } else if (geo2.dir > 0 && ValidDirward(dirward_here2) && other_side2 && dirward_here2.geo_id == geo_id && (/*geo2.dist == _0 || */ blocked2 || extra_here.polarity_set == _true && extra_here.geo_id == geo2.geo_id)) { dir1 = geo2.dir; chosen_polarity = other_side1 && ValidDirward(dirward_here1) ? polarity1 : polarity2; } else { // If not, then use Simple Pathing use_simple_pathing = true; } // If geodesic pathfinding has us running into something... if (!use_simple_pathing && (Something(Current[dir_to_vec(dir1)]) || geo1.dist > _0) && geo1.dist < 1) { // Turn inward toward the obstacles, if that direction is open float alt_dir; if (chosen_polarity == Polarity.Clockwise) { alt_dir = RotateLeft(dir1); } else { alt_dir = RotateRight(dir1); } if (!Something(Current[dir_to_vec(alt_dir)]) && !Something(Previous[dir_to_vec(alt_dir)])) { dir1 = alt_dir; } } if (use_simple_pathing) { // Go toward the cardinal direction that is furthest away. If something is in your way, go perpendicularly, assuming you also need to go in that direction. if ((mag.x > mag.y || diff.y > 0 && Something(up) || diff.y < 0 && Something(down)) && Destination.x > CurPos.x + 1 && !Something(right)) { dir1 = Dir.Right; } if ((mag.y > mag.x || diff.x > 0 && Something(right) || diff.x < 0 && Something(left)) && Destination.y > CurPos.y + 1 && !Something(up)) { dir1 = Dir.Up; } if ((mag.x > mag.y || diff.y > 0 && Something(up) || diff.y < 0 && Something(down)) && Destination.x < CurPos.x - 1 && !Something(left)) { dir1 = Dir.Left; } if ((mag.y > mag.x || diff.x > 0 && Something(right) || diff.x < 0 && Something(left)) && Destination.y < CurPos.y - 1 && !Something(down)) { dir1 = Dir.Down; } } // If something is in the way of the direction we want to go... if (IsValid(dir1) && Something(Current[dir_to_vec(dir1)])) { // ...and we are using geodesic pathfinding and have a determined polarity... if (chosen_polarity != Polarity.Undefined && !use_simple_pathing) { // ... then if some up or right from us has polarity set, let's follow their polarity (to avoid traffic jams) extra extra_right = Extra[RightOne], extra_up = Extra[UpOne]; // If someone right of us has polarity set, follow them if (extra_right.polarity_set == _true) { chosen_polarity = extra_right.polarity; } // If someone above us has polarity set, follow them if (extra_up.polarity_set == _true) { chosen_polarity = extra_up.polarity; } use_simple_pathing = false; } // ... and occasionally choose random direction instead (assuming we aren't surrounded) vec4 rnd = RandomField[Here]; if (rnd.x < .1f && !(Something(right) && Something(left) && Something(up) && Something(down))) { dir1 = RndFint(rnd.y, Dir.Right, Dir.Down); } } // Final sanity check on direction we want to follow if (IsValid(dir1)) { here.direction = dir1; // If we are choosing a polarity then we need to store it if (chosen_polarity != Polarity.Undefined && !use_simple_pathing) { // The polarity is stored in "extra", not "data", so we create a signal pumped into this "data" that will be used to modify the "extra" on a subsequent pass. here.change += chosen_polarity == Polarity.Counterclockwise ? SetPolarity.Counterclockwise : SetPolarity.Clockwise; } } else { // If we don't have a valid direction and we're attack-moving, then we probably arrived at our destination, so let's guard for now. if (here.action == UnitAction.Attacking) { here.action = UnitAction.Guard; } } }