예제 #1
0
        color FragmentShader(VertexOut vertex, Field <building> Buildings, Field <unit> Units, PointSampler Texture, PointSampler Explosion,
                             [Player.Vals] float player,
                             float s)
        {
            color output = color.TransparentBlack;

            building building_here = Buildings[Here];
            unit     unit_here     = Units[Here];

            if (!IsBuilding(unit_here))
            {
                return(output);
            }

            vec2 subcell_pos = get_subcell_pos(vertex, Buildings.Size);

            if (Something(building_here))
            {
                if (building_here.direction >= Dir.StationaryDead)
                {
                    float frame = ExplosionSpriteSheet.ExplosionFrame(s, building_here);
                    if (frame < ExplosionSpriteSheet.AnimLength)
                    {
                        output += ExplosionSprite(building_here, unit_here, subcell_pos, frame, Explosion);
                    }
                }
                else
                {
                    float frame = 0;
                    output += Sprite(player, building_here, unit_here, subcell_pos, frame, Texture);
                }
            }

            return(output);
        }
예제 #2
0
        float BuildingDirection(VertexOut vertex, Field <vec4> TargetData, building here)
        {
            float dir = Dir.Right;

            vec4 target = TargetData[Here];

            // Unpack packed info
            vec2 CurPos      = vertex.TexCoords * TargetData.Size;
            vec2 Destination = unpack_vec2((vec4)target);

            vec2 diff = Destination - CurPos;
            vec2 mag  = abs(diff);

            if (mag.x > mag.y && diff.x > 0)
            {
                dir = Dir.Right;
            }
            if (mag.x > mag.y && diff.x < 0)
            {
                dir = Dir.Left;
            }
            if (mag.y > mag.x && diff.y > 0)
            {
                dir = Dir.Up;
            }
            if (mag.y > mag.x && diff.y < 0)
            {
                dir = Dir.Down;
            }

            return(dir);
        }
예제 #3
0
        protected static RelativeIndex center_dir(building b)
        {
            vec2 part = vec(b.part_x, b.part_y);

            part = -255 * (part - vec(_1, _1));

            return((RelativeIndex)part);
        }
예제 #4
0
        building FragmentShader(VertexOut vertex, Field <unit> Unit, Field <building> Building)
        {
            building building_here = Building[Here];
            unit     unit_here     = Unit[Here];

            if (Something(building_here) && IsBuilding(unit_here) && IsCenter(building_here))
            {
                if (building_here.direction >= Dir.StationaryDead)
                {
                    building_here.direction += _1;
                    return(building_here);
                }

                building
                    right      = Building[RightOne],
                    up         = Building[UpOne],
                    left       = Building[LeftOne],
                    down       = Building[DownOne],
                    up_right   = Building[UpRight],
                    up_left    = Building[UpLeft],
                    down_right = Building[DownRight],
                    down_left  = Building[DownLeft];

                // If any part of the building is dying, then the center (and consequently the whole building) should be marked as dead.
                if (right.direction == Dir.StationaryDying ||
                    up.direction == Dir.StationaryDying ||
                    left.direction == Dir.StationaryDying ||
                    down.direction == Dir.StationaryDying ||
                    up_right.direction == Dir.StationaryDying ||
                    up_left.direction == Dir.StationaryDying ||
                    down_right.direction == Dir.StationaryDying ||
                    down_left.direction == Dir.StationaryDying)
                {
                    building_here.direction = Dir.StationaryDead;
                }

                // Select this center if any part of the building is selected
                if (!selected(building_here))
                {
                    bool is_selected =
                        selected(right) ||
                        selected(up) ||
                        selected(left) ||
                        selected(down) ||
                        selected(up_right) ||
                        selected(up_left) ||
                        selected(down_right) ||
                        selected(down_left);

                    set_selected(ref building_here, is_selected);
                }
            }

            return(building_here);
        }
예제 #5
0
        building FragmentShader(VertexOut vertex, Field <unit> Units, Field <building> Building, [Player.Vals] float player)
        {
            unit     unit_here     = Units[Here];
            building building_here = Building[Here];

            if (Something(building_here) && IsBuilding(unit_here) && unit_here.player == player)
            {
                building_here.direction = Dir.StationaryDead;
            }

            return(building_here);
        }
예제 #6
0
        protected color ExplosionSprite(building u, unit d, vec2 pos, float frame, PointSampler Texture)
        {
            if (pos.x > 1 || pos.y > 1 || pos.x < 0 || pos.y < 0)
            {
                return(color.TransparentBlack);
            }

            pos   += 255 * vec(u.part_x, u.part_y);
            pos.x += floor(frame) * ExplosionSpriteSheet.DimX;
            pos   *= ExplosionSpriteSheet.SpriteSize;

            return(Texture[pos]);
        }
예제 #7
0
        vec4 FragmentShader(VertexOut vertex, Field <unit> Unit, Field <building> Building, Field <vec4> TargetData)
        {
            building building_here = Building[Here];
            unit     unit_here     = Unit[Here];
            vec4     target        = TargetData[Here];

            if (Something(building_here) && IsBuilding(unit_here))
            {
                target = TargetData[center_dir(building_here)];
            }

            return(target);
        }
예제 #8
0
        color FragmentShader(VertexOut vertex, Field <BuildingDist> BuildingDistances, Field <building> Data, Field <unit> Unit, float blend, float radius, [Player.Vals] float player)
        {
            BuildingDist info = BuildingDistances[Here];

            if (info.dist > _15)
            {
                return(color.TransparentBlack);
            }

            vec2 subcell_pos = get_subcell_pos(vertex, BuildingDistances.Size);

            // Get the building data by following the offset
            vec2     offset = Float(info.diff - Pathfinding_ToSpecial.CenterOffset);
            var      index  = new RelativeIndex(offset.x, offset.y);
            building b      = Data[index];
            unit     u      = Unit[index];

            // Get the distance from here to the building center
            float l = length(255 * (info.diff - Pathfinding_ToSpecial.CenterOffset) - (subcell_pos - vec(.5f, .5f)));

            // Draw pixel
            if (fake_selected(b) && u.player == player)
            {
                if (l > .8f * radius && l < radius * 1.15f)
                {
                    color clr = SelectedUnitColor.Get(get_player(info)) * .75f;
                    clr.a = 1;
                    return(clr * blend);
                }

                if (l < radius)
                {
                    color clr = BuildingMarkerColors.Get(get_player(info), get_type(info)) * 1f;
                    clr.a = 1;
                    return(clr * blend);
                }
            }
            else
            {
                if (l < radius)
                {
                    color clr = BuildingMarkerColors.Get(get_player(info), get_type(info));
                    return(clr * blend);
                }
            }

            return(color.TransparentBlack);
        }
예제 #9
0
        building FragmentShader(VertexOut vertex, Field <building> Data, Field <unit> Units)
        {
            building here      = Data[Here];
            unit     unit_here = Units[Here];

            if (IsBuilding(unit_here) && !IsCenter(here) &&
                !IsCenter(Data[RightOne]) && !IsCenter(Data[LeftOne]) && !IsCenter(Data[UpOne]) && !IsCenter(Data[DownOne]) &&
                !IsCenter(Data[UpRight]) && !IsCenter(Data[UpLeft]) && !IsCenter(Data[DownRight]) && !IsCenter(Data[DownLeft]))
            {
                return(building.Nothing);
            }
            else
            {
                return(here);
            }
        }
예제 #10
0
        protected color Sprite(float player, building b, unit u, vec2 pos, float frame, PointSampler Texture)
        {
            if (pos.x > 1 || pos.y > 1 || pos.x < 0 || pos.y < 0)
            {
                return(color.TransparentBlack);
            }

            bool  draw_selected   = u.player == player && fake_selected(b);
            float selected_offset = draw_selected ? 3 : 0;

            pos   += Float(vec(b.part_x, b.part_y));
            pos.x += Float(u.player) * BuildingSpriteSheet.BuildingDimX;
            pos.y += selected_offset + BuildingSpriteSheet.SubsheetDimY * Float(UnitType.BuildingIndex(u.type));
            pos   *= BuildingSpriteSheet.SpriteSize;

            return(Texture[pos]);
        }
예제 #11
0
        building FragmentShader(VertexOut vertex, Field <unit> Unit, Field <building> Building)
        {
            building building_here = Building[Here];
            unit     unit_here     = Unit[Here];

            if (Something(building_here) && IsBuilding(unit_here))
            {
                building center = Building[center_dir(building_here)];

                if (!Something(center))
                {
                    return(building.Nothing);
                }

                set_selected_fake(ref building_here, fake_selected(center));
            }

            return(building_here);
        }
예제 #12
0
        building FragmentShader(VertexOut vertex, Field <unit> Unit, Field <building> Building)
        {
            building building_here = Building[Here];
            unit     unit_here     = Unit[Here];

            if (Something(building_here) && IsBuilding(unit_here))
            {
                building center = Building[center_dir(building_here)];

                if (!Something(center))
                {
                    return(building.Nothing);
                }

                building_here.prior_direction_and_select = center.prior_direction_and_select;
                building_here.direction = center.direction;
            }

            return(building_here);
        }
예제 #13
0
        building FragmentShader(VertexOut vertex, Field <building> Data, Field <unit> Units)
        {
            building here = Data[Here];

            if (IsBuilding(Units[RightOne]) && IsCenter(Data[RightOne]))
            {
                here.part_x = _0; here.part_y = _1;
            }
            if (IsBuilding(Units[LeftOne]) && IsCenter(Data[LeftOne]))
            {
                here.part_x = _2; here.part_y = _1;
            }
            if (IsBuilding(Units[UpOne]) && IsCenter(Data[UpOne]))
            {
                here.part_x = _1; here.part_y = _0;
            }
            if (IsBuilding(Units[DownOne]) && IsCenter(Data[DownOne]))
            {
                here.part_x = _1; here.part_y = _2;
            }

            if (IsBuilding(Units[UpRight]) && IsCenter(Data[UpRight]))
            {
                here.part_x = _0; here.part_y = _0;
            }
            if (IsBuilding(Units[DownRight]) && IsCenter(Data[DownRight]))
            {
                here.part_x = _0; here.part_y = _2;
            }
            if (IsBuilding(Units[UpLeft]) && IsCenter(Data[UpLeft]))
            {
                here.part_x = _2; here.part_y = _0;
            }
            if (IsBuilding(Units[DownLeft]) && IsCenter(Data[DownLeft]))
            {
                here.part_x = _2; here.part_y = _2;
            }

            return(here);
        }
예제 #14
0
        building FragmentShader(VertexOut vertex, Field <unit> Unit, Field <building> Building)
        {
            building building_here = Building[Here];
            unit     unit_here     = Unit[Here];

            if (Something(building_here) && IsBuilding(unit_here) && IsCenter(building_here))
            {
                if (!Something(Building[RightOne]) ||
                    !Something(Building[UpOne]) ||
                    !Something(Building[LeftOne]) ||
                    !Something(Building[DownOne]) ||
                    !Something(Building[UpRight]) ||
                    !Something(Building[UpLeft]) ||
                    !Something(Building[DownRight]) ||
                    !Something(Building[DownLeft]))
                {
                    return(building.Nothing);
                }
            }

            return(building_here);
        }
예제 #15
0
        building FragmentShader(VertexOut vertex, Field <unit> Unit, Field <building> Building)
        {
            building building_here = Building[Here];
            unit     unit_here     = Unit[Here];

            if (Something(building_here) && IsBuilding(unit_here) && IsCenter(building_here))
            {
                building
                    right      = Building[RightOne],
                    up         = Building[UpOne],
                    left       = Building[LeftOne],
                    down       = Building[DownOne],
                    up_right   = Building[UpRight],
                    up_left    = Building[UpLeft],
                    down_right = Building[DownRight],
                    down_left  = Building[DownLeft];

                // Select this center if any part of the building is selected
                if (!fake_selected(building_here))
                {
                    bool is_fake_selected =
                        fake_selected(right) ||
                        fake_selected(up) ||
                        fake_selected(left) ||
                        fake_selected(down) ||
                        fake_selected(up_right) ||
                        fake_selected(up_left) ||
                        fake_selected(down_right) ||
                        fake_selected(down_left);

                    set_selected_fake(ref building_here, is_fake_selected);
                }
            }

            return(building_here);
        }
예제 #16
0
        data FragmentShader(VertexOut vertex, Field <vec4> TargetData, Field <unit> Unit, Field <extra> Extra, Field <data> Data, Field <data> PrevData, Field <vec4> PathToOtherTeams, Field <vec4> RandomField, Field <magic> Magic,
                            Field <geo> Geo, Field <geo> AntiGeo,
                            Field <dirward> DirwardRight, Field <dirward> DirwardLeft, Field <dirward> DirwardUp, Field <dirward> DirwardDown)
        {
            data  data_here  = Data[Here];
            magic magic_here = Magic[Here];

            if (Something(data_here))
            {
                data path = data.Nothing;

                // Get info for this unit
                unit unit_here = Unit[Here];

                // Remove if dead unit
                if (unit_here.anim == Anim.Die && IsUnit(unit_here))
                {
                    return(data.Nothing);
                }

                // Remove if dead building
                building b = (building)(vec4)data_here;
                if (IsBuilding(unit_here))
                {
                    // If this building is alive
                    if (data_here.direction == Dir.Stationary)
                    {
                        // If this is a building that has been hit enough times to explode
                        if (unit_here.hit_count >= _5)
                        {
                            data_here.direction = Dir.StationaryDying;
                        }
                    }
                    else
                    {
                        // Otherwise remove it if the explosion animation is done
                        float frame = ExplosionSpriteSheet.ExplosionFrame(0, b);

                        if (frame >= ExplosionSpriteSheet.AnimLength)
                        {
                            return(data.Nothing);
                        }
                    }
                }

                // Units that are done being raised should switch to attacking.
                if (IsUnit(unit_here) && unit_here.anim == Anim.DoRaise)
                {
                    data_here.action = UnitAction.Attacking;
                }

                // Units that are about to be incinerated or are being raised can't move.
                if (IsUnit(unit_here) && (magic_here.kill == _true || unit_here.anim == Anim.StartRaise))
                {
                    data_here.action = UnitAction.Stopped;
                    return(data_here);
                }

                // Buildings can't move.
                if (IsBuilding(unit_here))
                {
                    if (IsCenter((building)(vec4)data_here))
                    {
                        // Set the building direction toward its "target".
                        set_prior_direction(ref data_here, BuildingDirection(vertex, TargetData, (building)(vec4)data_here));
                    }
                    return(data_here);
                }

                // Get nearby paths to other teams
                vec4
                    _value_right = PathToOtherTeams[RightOne],
                    _value_up    = PathToOtherTeams[UpOne],
                    _value_left  = PathToOtherTeams[LeftOne],
                    _value_down  = PathToOtherTeams[DownOne];

                // Get specific paths to enemies of this particular unit
                float value_right = 1, value_left = 1, value_up = 1, value_down = 1;
                if (unit_here.team == Team.One)
                {
                    value_right = _value_right.x;
                    value_left  = _value_left.x;
                    value_up    = _value_up.x;
                    value_down  = _value_down.x;
                }
                else if (unit_here.team == Team.Two)
                {
                    value_right = _value_right.y;
                    value_left  = _value_left.y;
                    value_up    = _value_up.y;
                    value_down  = _value_down.y;
                }
                else if (unit_here.team == Team.Three)
                {
                    value_right = _value_right.z;
                    value_left  = _value_left.z;
                    value_up    = _value_up.z;
                    value_down  = _value_down.z;
                }
                else if (unit_here.team == Team.Four)
                {
                    value_right = _value_right.w;
                    value_left  = _value_left.w;
                    value_up    = _value_up.w;
                    value_down  = _value_down.w;
                }

                float auto_attack_cutoff = _12;
                if (unit_here.type == UnitType.DragonLord)
                {
                    auto_attack_cutoff = _2;
                }
                if (unit_here.type == UnitType.Necromancer)
                {
                    auto_attack_cutoff = _2;
                }

                float min      = 256;
                float hold_dir = data_here.direction;
                if (data_here.action == UnitAction.Attacking || data_here.action == UnitAction.Guard)
                {
                    if (value_right < min)
                    {
                        data_here.direction = Dir.Right; min = value_right;
                    }
                    if (value_up < min)
                    {
                        data_here.direction = Dir.Up; min = value_up;
                    }
                    if (value_left < min)
                    {
                        data_here.direction = Dir.Left; min = value_left;
                    }
                    if (value_down < min)
                    {
                        data_here.direction = Dir.Down; min = value_down;
                    }
                }

                if (min > auto_attack_cutoff)
                {
                    // Not within auto attack range, so fallback to previous direction.
                    data_here.direction = hold_dir;
                }
                else
                {
                    // If we're within auto attack range and we're a necromancer, we should run away.
                    // Necromancers are cowards.
                    if (unit_here.type == UnitType.Necromancer)
                    {
                        TurnAround(ref data_here);
                    }
                }

                // If we are guarding and a unit is close, switch to attacking
                if (min < auto_attack_cutoff && data_here.action == UnitAction.Guard)
                {
                    data_here.action = UnitAction.Attacking;
                }

                // If we aren't attacking, or if a unit is too far away
                if (min > auto_attack_cutoff && data_here.action == UnitAction.Attacking || data_here.action == UnitAction.Moving)
                {
                    NaivePathfind(vertex, Data, PrevData, TargetData, Extra, RandomField,
                                  Geo, AntiGeo,
                                  DirwardRight, DirwardLeft, DirwardUp, DirwardDown,
                                  unit_here, ref data_here);
                }
            }

            return(data_here);
        }
예제 #17
0
 protected static float select_state(building u)
 {
     return(select_state((data)(vec4)u));
 }
예제 #18
0
 protected static float prior_direction(building u)
 {
     return(prior_direction((data)(vec4)u));
 }
예제 #19
0
 protected static void set_selected(ref building u, bool selected)
 {
     data d = (data)(vec4)u; set_selected(ref d, selected); u = (building)(vec4)d;
 }
예제 #20
0
 protected static bool selected(building u)
 {
     return(selected((data)(vec4)u));
 }
예제 #21
0
 protected static bool Something(building u)
 {
     return(u.direction > 0);
 }
예제 #22
0
 public static float ExplosionFrame(float s, building building_here)
 {
     return((s + 255 * (building_here.direction - Dir.StationaryDead)) * 6);
 }
예제 #23
0
 protected static bool IsCenter(building b)
 {
     return(b.part_x == _1 && b.part_y == _1);
 }