예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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;
                }
            }
        }