Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        void swap(ref dirward a, ref dirward b)
        {
            dirward _ = a;

            a = b;
            b = _;
        }
Ejemplo n.º 3
0
        dirward FragmentShader(VertexOut vertex, Field <dirward> Dirward)
        {
            dirward dirward_here = Dirward[Here];

            dirward_here.importance = _0;

            return(dirward_here);
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
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;
                }
            }
        }
Ejemplo n.º 8
0
        /*
         * 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);
        }
Ejemplo n.º 9
0
        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);
        }