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); }
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); }
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); }
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); }
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); }
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]); }
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); }
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); }
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); } }
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]); }
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); }
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); }
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); }
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); }
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); }
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); }
protected static float select_state(building u) { return(select_state((data)(vec4)u)); }
protected static float prior_direction(building u) { return(prior_direction((data)(vec4)u)); }
protected static void set_selected(ref building u, bool selected) { data d = (data)(vec4)u; set_selected(ref d, selected); u = (building)(vec4)d; }
protected static bool selected(building u) { return(selected((data)(vec4)u)); }
protected static bool Something(building u) { return(u.direction > 0); }
public static float ExplosionFrame(float s, building building_here) { return((s + 255 * (building_here.direction - Dir.StationaryDead)) * 6); }
protected static bool IsCenter(building b) { return(b.part_x == _1 && b.part_y == _1); }