{$N+}unit sun;

interface

uses
  loadz;

procedure sunlight(hour: byte);
procedure sunosv(x, y, degree: byte; px, py: shortint);
procedure clearshadows;

implementation

uses
  svet, MyCRT;

const
  PIZDECIMA = 100;
  MAX_DEGREE = 90;

var
  stena: boolean;


procedure sunluch(degree: integer; startx, starty: byte; px, py: shortint; shadow_width: byte);
var
  zx, zy: single;
  count: byte;
  otnx, otny: real;
  posx, posy: integer;
  dlina_teni: byte;
begin
  zx := 0;
  zy := 0;
  otny := MAX_DEGREE / degree;
  otnx := MAX_DEGREE / degree;
  if otny < 1 then
    otnx := MAX_DEGREE / (MAX_DEGREE - degree);
  if otny > 1 then
  begin
    stena := false;
    dlina_teni := 0;
    posx := startx;
    posy := starty;
      for count := 1 to PIZDECIMA do
      begin
        posx := posx + px;
        zy := zy + (1/otny);
        if zy > 1 then
        begin
          posy := posy + py;
          zy := zy - 1;
        end;
        if (posx < 0) or (posx > RESOLUTION_X) or (posy < 0) or (posy > RESOLUTION_Y) then
          exit;
        if stena then
          inc(dlina_teni);
        if dlina_teni > shadow_width then
        begin
          stena := false;
          dlina_teni := 0;
        end;
        if (IsBoldForSun(posx, posy)) or (IsInHouse(posx, posy)) then
        begin
          stena := true;
          dlina_teni := 0;
        end;
        cur_lev.map[posx, posy].shadow := stena;
      end;
  end
  else if otnx > 1 then
  begin
    stena := false;
    dlina_teni := 0;
    posx := startx;
    posy := starty;
    for count := 1 to PIZDECIMA do
    begin
      posy := posy + py;
      zx := zx + (1/otnx);
     if zx > 1 then
      begin
        posx := posx + px;
        zx := zx - 1;
      end;
      if (posx < 0) or (posx > RESOLUTION_X) or (posy < 0) or (posy > RESOLUTION_Y) then
        exit;
      if stena then
        inc(dlina_teni);
      if dlina_teni > shadow_width then
      begin
        stena := false;
        dlina_teni := 0;
      end;
      if (IsBoldForSun(posx, posy)) or (IsInHouse(posx, posy)) then
      begin
        stena := true;
        dlina_teni := 0;
      end;
      cur_lev.map[posx, posy].shadow := stena;
    end;
  end;
end;

function Sgn(x: integer): integer;
begin
  if (x = 0) then
    Sgn := 0
  else if x > 0 then
    Sgn := 1
  else
    Sgn := -1;
end;

function CastRay(x, y, r: byte; angle: integer): TCoord;
var
  c: TCoord;
begin
  c.x := round(x + r * Cosinus[angle div 5]);
  c.y := round(y - r * Sinus[angle div 5]);
  if c.x < 1 then
    c.x := 1
  else if c.x > RESOLUTION_X then
    c.x := RESOLUTION_X;
  if c.y < 1 then
    c.y := 1
  else if c.y > RESOLUTION_Y then
    c.y := RESOLUTION_Y;
  Result := c;
end;

function shadow_width: byte;
begin
  shadow_width := 0;
  case data.hours of
    8: shadow_width := 7;
    9: shadow_width := 6;
    10: shadow_width := 5;
    11: shadow_width := 4;
    12: shadow_width := 3;
    13: shadow_width := 3;
    14: shadow_width := 4;
    15: shadow_width := 5;
    16: shadow_width := 6;
    17: shadow_width := 7;
    18: shadow_width := 8;
    19: shadow_width := 9;
  end;
end;

procedure sunlight(hour: byte);
var
  hren: byte;
begin
  hren := RESOLUTION_X div 7;
  case hour of
    8: sunosv(RESOLUTION_X, 0, 45, -1, 1);
    9: sunosv(RESOLUTION_X, RESOLUTION_Y div 2, 10, -1, 1);
    10: sunosv(RESOLUTION_X, RESOLUTION_Y, 45, -1, -1);
    11: sunosv(hren * 6 + 3, RESOLUTION_Y, 30, -1, -1);
    12: sunosv(hren * 5 + 3, RESOLUTION_Y, 15, -1, -1);
    13: sunosv(hren * 4 + 3, RESOLUTION_Y, 30, -1, -1);
    14: sunosv(hren * 3 + 3, RESOLUTION_Y, 5, 1, -1);
    15: sunosv(hren * 2 + 3, RESOLUTION_Y, 30, 1, -1);
    16: sunosv(hren + 3, RESOLUTION_Y, 40, 1, -1);
    17: sunosv(0, RESOLUTION_Y, 45, 1, -1);
    18: sunosv(0, RESOLUTION_Y div 2, 5, 1, 1);
    19: sunosv(0, 0, 45, 1, 1);
  end;
end;


procedure clearshadows;
var
  x, y: byte;
begin
  for y := 1 to RESOLUTION_Y do
    for x := 1 to RESOLUTION_X do
      cur_lev.map[x, y].shadow := false;
end;



procedure sunosv(x, y, degree: byte; px, py: shortint);
var
  x1, y1: byte;
  c: byte;
begin
    clearshadows;
    c := degree;
    for y1 := 2 to RESOLUTION_Y - 1 do
    begin
      sunluch(c, x, y1, px, py, shadow_width);
      sunluch(c, RESOLUTION_X + 1 - x, y1, px, py, shadow_width);
    end;
    for x1 := 2 to RESOLUTION_X - 1 do
    begin
      sunluch(c, x1, y, px, py, shadow_width);
      sunluch(c, x1, RESOLUTION_Y + 1 - y, px, py, shadow_width);
    end;
    cur_lev.street := true;
end;


end.