unit Lives;

interface
uses
  Model, Map, MForm, Math, SysUtils;


function whatroll(x2, x1, y2, y1 :real) : integer;
function roll(i: word): boolean;
function moveobj(MX, MY, R,X,Y : real; N:byte; var RX, RY : real; NoMap : boolean): boolean;
function MoveToCel(I : word): boolean;
procedure whatmodelroll(i : word);

var
  PinP : boolean;
  Bot  : word;

implementation

function colissionMap(X,Y, B : real): boolean;
begin
  if  (X > B*3)
  and (Y > B*3)
  and (X < (L.X-B)*3)
  and (Y < (L.Y-B)*3)
  then
  result:=true
  else
  result:=false;
end;

function colissionC(X,Y,R, CX,CY, SX,SY: real): boolean;
begin
  if  (X+R > CX - SX/2)
  and (X-R < CX + SX/2)
  and (Y+R > CY - SY/2)
  and (Y-R < CY + SY/2)
  then
  result:=true
  else
  result:=false;
end;

function colissionR(X,Y,R, CX,CY,CR : real): boolean;
begin
  result:=false;
  if colissionC(X,Y,R, CX,CY,CR,CR) then
    begin
      X:=X-CX;
      Y:=Y-CY;
      CR:=CR+R;
      if  (Y > -sqrt(sqr(CR)-sqr(X)))
      and (Y <  sqrt(sqr(CR)-sqr(X)))
      then
      result:=true
    end;
end;

function collisionD(X,Y,R : real; I : word ): boolean;
begin
  if Model.EtDecO[DecO[i].Et].C=2 then
  result:= colissionC(X,Y,R,Model.DecO[i].F.Position.X, Model.DecO[i].F.Position.Y,
            Model.EtDecO[Deco[i].Et].R,Model.EtDecO[Deco[i].Et].R)
  else
  result:= colissionR(X,Y,R,Model.DecO[i].F.Position.X, Model.DecO[i].F.Position.Y,
           Model.EtDecO[Deco[i].Et].R);
end;

function colission(X,Y,R : real; N: byte; NoMap: boolean): boolean;
var
  i : word;
  B : real;
begin
  result:=true;
  if NoMap then B:=0 else B:=3.5;
  if (colissionMap(X,Y,B))  then
  begin
    result:=false;
    for i:=1 to Map.L.MofC do
    if colissionC(X,Y,R,
         L.Cube[i].Position.X, L.Cube[i].Position.Y,
         L.Cube[i].Scale.X, L.Cube[i].Scale.Y)
    then
    result:=true;

    if not result then
    for i:=1 to Model.MofCrb do
    if colissionC(X,Y,R,
         Model.Corob[I].F.Position.X, Model.Corob[I].F.Position.Y,
         2, 2)
    then
    result:=true;

    if not result then
    for i:=1 to Model.MofT do
    if colissionC(X,Y,R,
         Model.Truba[I].F.Position.X, Model.Truba[I].F.Position.Y,
         2, 2)
    then
    result:=true;

    if not result then
    for i:=1 to Model.MofD do
    if collisionD(X,Y,R,I)
    then
    result:=true;

    if not result then
    for i:=1 to Model.MofP do
    if (I<>N)
    and (colissionR(X,Y,R,
         Model.Pers[i].A.Position.X, Model.Pers[i].A.Position.Y,
         Model.EtLiveObj[Pers[i].Et].R))
    then
      begin
        result:=true;
        PinP:=true;
        Bot:=i;
      end;

 end
end;

function asmroll(x1, y1 :real) : real;
asm
  FLD Y1
  FLD X1
  FPATAN
  FWAIT
end;

function whatroll(x2, x1, y2, y1 :real) : integer;
begin
  result:=round(asmroll(x1-x2,y1-y2)*57.32);
end;

procedure whatmodelroll(i : word);
var
 x1, x2, y1, y2 : real;
begin
  x1:=Model.Pers[i].A.Position.X;
  y1:=Model.Pers[i].A.Position.Y;

  x2:=Model.Pers[i].MP.X;
  y2:=Model.Pers[i].MP.Y;

  Model.Pers[i].MA:=whatroll(x1,x2,y1,y2);
//  if Model.Pers[i].MA>360 then Model.Pers[i].MA:=0;
//  if Model.Pers[i].MA<-360 then Model.Pers[i].MA:=0;
  //Model.Pers[i].MA:=Model.Pers[i].MA+90;
end;


function roll(i : word): boolean;
begin
  result:=false;
  if (Model.Pers[i].A.RollAngle>Model.Pers[i].MA-4)
  and (Model.Pers[i].A.RollAngle<Model.Pers[i].MA+4)
  then
  result:=true
  else
    begin
      if (Model.Pers[i].A.RollAngle<-90)
      and (Model.Pers[i].MA>90)
      then
      Model.Pers[i].A.RollAngle:=Model.Pers[i].A.RollAngle-5
      else
      if (Model.Pers[i].A.RollAngle>90)
      and (Model.Pers[i].MA<-90)
      then
      Model.Pers[i].A.RollAngle:=Model.Pers[i].A.RollAngle+5
      else
      if  (Model.Pers[i].A.RollAngle>Model.Pers[i].MA)
      and (Model.Pers[i].A.RollAngle>Model.Pers[i].MA)
      then
      Model.Pers[i].A.RollAngle:=Model.Pers[i].A.RollAngle-5
      else
      if Model.Pers[i].A.RollAngle<Model.Pers[i].MA then
      Model.Pers[i].A.RollAngle:=Model.Pers[i].A.RollAngle+5;
    end;
end;

function moveobj(MX, MY, R,X,Y : real; N:byte; var RX, RY : real; NoMap : boolean): boolean;
begin
  result:=false;
  if colission(X+MX, Y+MY, R+0.3, N, NoMap) then
  result:=true;

  if not colission(X+MX, Y, R+0.3, N, NoMap) then
  RX:=X+MX;

  if not colission(X, Y+MY, R+0.3, N, NoMap) then
  RY:=Y+MY;

end;

function MoveToCel(I : word): boolean;
begin
  result:=false;
  if  (Model.Pers[i].A.Position.X>Model.Pers[i].MP.X-1)
  and (Model.Pers[i].A.Position.X<Model.Pers[i].MP.X+1)
  and (Model.Pers[i].A.Position.Y>Model.Pers[i].MP.Y-1)
  and (Model.Pers[i].A.Position.Y<Model.Pers[i].MP.Y+1)
  then
  Model.Pers[i].Moved:=false
  else
      result:=true;
end;

end.
