color FragmentShader(VertexOut vertex, Field <dirward> Dirward, PointSampler Texture) { color output = color.TransparentBlack; dirward here = Dirward[Here]; vec2 subcell_pos = get_subcell_pos(vertex, Dirward.Size); if (ValidDirward(here)) { // Draw guid coloring vec2 guid = fmod(here.geo_id * 1293.4184145f, 1.0f); output.r += guid.x; output.g += guid.y; output.a = 1f; output.rgb *= output.a; } // Draw polarity only if (ValidDirward(here)) { return((color)(here.polarity > .5 ? vec(1, 0, 0, 1) : vec(0, 1, 0, 1))); } return(output); }
void swap(ref dirward a, ref dirward b) { dirward _ = a; a = b; b = _; }
dirward FragmentShader(VertexOut vertex, Field <dirward> Dirward) { dirward dirward_here = Dirward[Here]; dirward_here.importance = _0; return(dirward_here); }
dirward FragmentShader(VertexOut vertex, Field <dirward> Dirward, Field <geo> Geo, Field <geo> ShiftedGeo, Field <geo_info> Info, Field <geo_info> ShiftedInfo, [Dir.Vals] float dir) { geo geo_here = Geo[Here], geo_shift = ShiftedGeo[Here]; if (geo_here.dir == _0) { return(dirward.Nothing); } geo_info info_here = Info[Here], info_shift = ShiftedInfo[Here]; if (geo_here.pos_storage != geo_shift.pos_storage) { return(Dirward[Here]); } float dist_here = unpack_val(info_here.xy), dist_shift = unpack_val(info_shift.xy), circum = unpack_val(info_here.zw); float diff = dist_here - dist_shift; float clockwise = 0, counterclockwise = 0; if (diff > 0) { clockwise = diff; counterclockwise = circum - diff; } else { clockwise = circum + diff; counterclockwise = -diff; } dirward output = dirward.Nothing; output.polarity = clockwise > counterclockwise ? 0 : 1; output.polarity_set = _true; return(output); }
dirward FragmentShader(VertexOut vertex, Field <dirward> Dirward, Field <geo> Geo) { geo here = Geo[Here], right = Geo[RightOne], up = Geo[UpOne], left = Geo[LeftOne], down = Geo[DownOne]; dirward dirward_here = Dirward[Here], dirward_right = Dirward[RightOne], dirward_up = Dirward[UpOne], dirward_left = Dirward[LeftOne], dirward_down = Dirward[DownOne]; if (here.dir == _0) { return(dirward.Nothing); } if (dirward_here.polarity_set == _false) { if (right.pos_storage == here.pos_storage && dirward_right.polarity_set == _true) { dirward_here.polarity = dirward_right.polarity; dirward_here.polarity_set = _true; } if (left.pos_storage == here.pos_storage && dirward_left.polarity_set == _true) { dirward_here.polarity = dirward_left.polarity; dirward_here.polarity_set = _true; } if (up.pos_storage == here.pos_storage && dirward_up.polarity_set == _true) { dirward_here.polarity = dirward_up.polarity; dirward_here.polarity_set = _true; } if (down.pos_storage == here.pos_storage && dirward_down.polarity_set == _true) { dirward_here.polarity = dirward_down.polarity; dirward_here.polarity_set = _true; } } return(dirward_here); }
bool GetDirward(ref dirward dirward_here, float dir, ref vec2 Destination, ref vec2 pos_here, Field <dirward> DirwardRight, Field <dirward> DirwardLeft, Field <dirward> DirwardUp, Field <dirward> DirwardDown) { if (dir == Dir.Right) { dirward_here = DirwardRight[Here]; return(Destination.x > pos_here.x + Float(dirward_here.dist_to_wall)); } else if (dir == Dir.Left) { dirward_here = DirwardLeft[Here]; return(Destination.x < pos_here.x - Float(dirward_here.dist_to_wall)); } else if (dir == Dir.Up) { dirward_here = DirwardUp[Here]; return(Destination.y > pos_here.y + Float(dirward_here.dist_to_wall)); } else if (dir == Dir.Down) { dirward_here = DirwardDown[Here]; return(Destination.y < pos_here.y - Float(dirward_here.dist_to_wall)); } return(false); }
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; } } }
/* * protected static bool selected(building u) * { * float val = u.prior_direction_and_select; * return val >= SelectState.Selected; * } * * protected static void set_selected(ref building u, bool selected) * { * u.prior_direction_and_select = prior_direction(u) + (selected ? SelectState.Selected : _0); * } * * protected static float prior_direction(building u) * { * float val = u.prior_direction_and_select; * if (val >= SelectState.Selected) val -= SelectState.Selected; * return val; * } * * protected static void set_prior_direction(ref building u, float dir) * { * u.prior_direction_and_select = dir + (selected(u) ? SelectState.Selected : _0); * } */ protected static bool ValidDirward(dirward d) { return(d != dirward.Nothing); }
dirward FragmentShader(VertexOut vertex, Field <tile> Tiles, Field <geo> Geo, Field <dirward> Dirward, [Dir.Vals] float dir) { tile here = Tiles[Here]; geo geo_here = Geo[Here], geo_right = Geo[RightOne], geo_up = Geo[UpOne], geo_left = Geo[LeftOne], geo_down = Geo[DownOne], geo_up_right = Geo[UpRight], geo_up_left = Geo[UpLeft], geo_down_right = Geo[DownRight], geo_down_left = Geo[DownLeft]; dirward dirward_here = Dirward[Here], dirward_right = Dirward[RightOne], dirward_up = Dirward[UpOne], dirward_left = Dirward[LeftOne], dirward_down = Dirward[DownOne], dirward_up_right = Dirward[UpRight], dirward_up_left = Dirward[UpLeft], dirward_down_right = Dirward[DownRight], dirward_down_left = Dirward[DownLeft]; if (IsBlockingTile(here)) { return(dirward.Nothing); } dirward output = dirward.Nothing; dirward forward = dirward.Nothing, forward_right = dirward.Nothing, forward_left = dirward.Nothing, rightward = dirward.Nothing, leftward = dirward.Nothing; geo geo_forward = geo.Nothing, geo_forward_right = geo.Nothing, geo_forward_left = geo.Nothing, geo_rightward = geo.Nothing, geo_leftward = geo.Nothing; // Get the surrounding dirward info and store it relative to the direction we consider forward if (dir == Dir.Up) { forward = dirward_up; forward_right = dirward_up_right; forward_left = dirward_up_left; rightward = dirward_right; leftward = dirward_left; geo_forward = geo_up; geo_forward_right = geo_up_right; geo_forward_left = geo_up_left; geo_rightward = geo_right; geo_leftward = geo_left; } else if (dir == Dir.Right) { forward = dirward_right; forward_right = dirward_down_right; forward_left = dirward_up_right; rightward = dirward_down; leftward = dirward_up; geo_forward = geo_right; geo_forward_right = geo_down_right; geo_forward_left = geo_up_right; geo_rightward = geo_down; geo_leftward = geo_up; } else if (dir == Dir.Down) { forward = dirward_down; forward_right = dirward_down_left; forward_left = dirward_down_right; rightward = dirward_left; leftward = dirward_right; geo_forward = geo_down; geo_forward_right = geo_down_left; geo_forward_left = geo_down_right; geo_rightward = geo_left; geo_leftward = geo_right; } else if (dir == Dir.Left) { forward = dirward_left; forward_right = dirward_up_left; forward_left = dirward_down_left; rightward = dirward_up; leftward = dirward_down; geo_forward = geo_left; geo_forward_right = geo_up_left; geo_forward_left = geo_down_left; geo_rightward = geo_up; geo_leftward = geo_down; } if (geo_here.dir > 0 && IsBlockingTile(Tiles[dir_to_vec(dir)])) { output = dirward_here; output.geo_id = geo_here.geo_id; output.dist_to_wall = _0; } else if (ValidDirward(forward) && forward.geo_id == geo_forward.geo_id) { output = forward; output.dist_to_wall += _1; } else if (ValidDirward(forward_right) && forward_right.geo_id == geo_forward_right.geo_id) { output = forward_right; output.dist_to_wall += _1; } else if (ValidDirward(forward_left) && forward_left.geo_id == geo_forward_left.geo_id) { output = forward_left; output.dist_to_wall += _1; } //else if (ValidDirward(rightward) && rightward.geo_id == geo_rightward.geo_id) { output = rightward; output.dist_to_wall += _0; } //else if (ValidDirward(leftward) && leftward.geo_id == geo_leftward.geo_id) { output = leftward; output.dist_to_wall += _0; } return(output); }