unit uGeneralData;
////////////////////////////////
// версия 1,0
////////////////////////////////
// модуль глобальных игровых
// переменных, классов и т. п.
////////////////////////////////

interface

uses OMEGA;

const DFld='..\data\';  //путь к папке данных

type
{===========================================================================}
{===========================================================================}
{===========================================================================}
     tScene=(sLoad,sMenu,sOption,sAbout,sGame);  //сцены
{===========================================================================}
     tGameScene=                                 //игровые сцены
                 (sInto,              //введение
                 sIntroduction,       //обучение
                 sTraining,           //тренировка
                 sPlot,               //сюжет
                 sComparison,         //сравнение
                 sSearchElements,     //поиск элементов
                 sEncryption,         //шифрование
                 sDecoding,           //дешифровка
                 sFillingCards,       //заполнение карт
                 sCoordination,       //координация карт
                 sEndTask);           //информация по завершению задания
{===========================================================================}
{===========      игровые типы      ========================================}
{===========================================================================}
     tCmplxLvl=(Easy,Normal,Hard); //уровни сложности заданий
{===========================================================================}
     tPlayer=object                                   //тип игрока
      name:string;                                    //имя
      Experience,MaxExp,ExpLvl:integer;               //опыт и максимальный опыт и уровень опыта
      Accuracy,MaxAcr,AcrLvl:integer;                 //точность и макс. точн. и уровень точности
      Speed,MaxSpd,SpdLvl:integer;                    //скорость и макс. скорость и уровень скорости


      procedure Init(nm:string;mx1,mx2,mx3:integer);  //инициализируем игрока
      procedure Process;
      procedure Generate(size:integer);               //случайно изменяем характеристики, size - параетр
                                                      //максимального роста
     end;
{===========================================================================}
{===========================================================================}
{===========================================================================}
     tSprite=object                                       //спрайты
      texture:PTexture;                                   //текстура

      wx,hx:integer;                                      //высота и ширина
      alpha:byte;                                         //прозрачность
      tcolor:integer;                                     //прозрачный цвет

      patch,mpatch:string;                                //путь к текстуре и маске
      name:string;                                        //имя

      procedure Draw(x,y,angle,flags:integer);            //рисуем спрайт
      procedure Draw2(x,y,w,h,alph,angle,flags:integer);  //рисуем спрайт со своими параметрами
     end;
{===========================================================================}
     tCard=object                               //Карта заданий
      sizex,sizey:integer;                      //размеры в точках
      x,y:integer;                              //координаты

      data:array [1..100,1..100,1..2] of boolean;  //массив данных
      startx,starty,qx,qy:integer;                 //некоторые переменные карты для произвольного пользования

      rendr:boolean;                            //текстура рендрилась

      texture:PTexture;                         //текстура для рендринга
      arspr:array [1..12] of tSprite;           //спрайты для отрисовки

      procedure Draw;                           //отрисовка
      procedure Init;                           //инициализация
     end;
{===========================================================================}
     tRecurces=object                           //ресурсы
      Spr:array [1..200] of tSprite;            //спрайты
      QSpr:integer;                             //номер текущей незанятой ячейки

      procedure AddSpr(patch:string);            //добавляем в ресурсы спрайт
      function FindSpr(name:string):integer;     //поис ресурса по имени
     end;
{===========================================================================}
{===========================================================================}
{===========================================================================}
procedure LoadOptions(patch:string); //процедура загрузки параметров окна
procedure DataInit;                  //инициализация игровых данных
function SceneName:string;           //получаем имя сцены, игровой сцены и уровня сложности

var ScrW,ScrH:integer; //разрешение окна
    WindowName:String; //имя окна

    scene:tScene;                 //текущая сцена
    gscene:tGameScene;            //текущая игровая сцена

    Res:tRecurces;                //игровые ресурсы

    erorname:string;              //описание ошибки

    cursor:PTexture;              //курсор меню
    font:PFont2D;                 //шрифт для надписей

implementation

uses uMenu,uLoad,uGame;
{===========================================================================}
{====      сначала просто процедуры        =================================}
{===========================================================================}

procedure LoadOptions(patch:string);
var DF:textfile;
begin

assignfile(DF,patch);
reset(DF);
//грузим разрешение и имя окна
readln(DF,ScrW,ScrH);
readln(DF,WindowName);
closeFile(DF);

end;

procedure DataInit;
var DF:textfile;
    i,t:integer;
    p:string;
begin

//грузим шрифт
font:=text_loadfontfromfile('..\data\font.bmp','..\data\font.bmp.ofi');
//грузим текстуру курсора
Tex_LoadMaskFromFile('..\data\sprite\mcursor.bmp');
cursor:=tex_loadfromfile('..\data\sprite\cursor.bmp',-1,TEX_DEFAULT_2D or TEX_USEMASK);
Tex_FreeMask;

//задаём текущие пустую ячейку в ресурсах
res.QSpr:=1;

//загрузка всех спрайтов идёт с помощью скрипта
assignfile(DF,DFld+'sprite\load_script.txt');
reset(DF);
readln(DF,i);  //читаем кол-во эл-тов
for t:=1 to i do begin      //загружаем спрайты
 readln(DF,p);
 res.AddSpr(DFld+p);
end;
closefile(DF);

//переходим на сцену Load
LoadInit;
scene:=sLoad;

end;

function SceneName:string;  //получить имя текущей сцены и игровой сцены
var str:string;
begin

case scene of
 sLoad:str:='sLoad';
 sMenu:str:='sMenu';
 sOption:str:='sOptions';
 sAbout:str:='sAbout';
 sGame:str:='sGame';
end;

if scene=sGame then begin
 case gscene of
  sInto:str:=str+' - sInto';
  sIntroduction:str:=str+' - sIntroduction';
  sTraining:str:=str+' - sTraining';
  sPlot:str:=str+' - sPlot';
  sComparison:str:=str+' - sComparison';
  sSearchElements:str:=str+' - sSearchElements';
  sEncryption:str:=str+' - sEncryption';
  sDecoding:str:=str+' - sDecoding';
  sFillingCards:str:=str+' - sFillingCards';
  sCoordination:str:=str+' - sCoordination';
  sEndTask:str:=str+' - sEndTask';
 end;
 case CmplxLvl of
  Easy:str:=str+' - Easy';
  Normal:str:=str+' - Normal';
  Hard:str:=str+' - Hard';
 end;
end;


SceneName:=str;

end;

{==============================================================}
{===================    tPlayer   =============================}
{==============================================================}

procedure TPlayer.Init(nm:string;mx1,mx2,mx3:integer);   //создаём нового игрока
begin

name:=nm; //имя

Experience:=0; //опыт
MaxExp:=mx1;   //опыт для перехода на следующий уровень
Accuracy:=0;   //точность, т.е. колво допущеных ошибок, при правильном выполнении задания точность уменьшается
MaxAcr:=mx2;   //для перехода на след уровень, большой уровень точности - это плохо, т.к. за точностью подрозумевается колво ошибок
Speed:=0;      //скорость выполнения, при выполнении задания быстрее заданого промежутка, избыток прибавляется, при опоздании уменьшается пропорционально уровню ошибок текущего задания
MaxSpd:=mx3;   //ну тут понятно

ExpLvl:=1;     //задаём текущий уровень
AcrLvl:=1;
SpdLvl:=1;

end;

procedure TPlayer.Process;
begin
//в случае,если текущий опыт превышает максимальный для этого уровня
//повышаем уровень и остаток опыта переносим на след. уровень
if Experience>=MaxExp then
begin
 ExpLvl:=ExpLvl+1;
 Experience:=Experience-MaxExp;
end;
//тоже для точности
if Accuracy>=MaxAcr then
begin
 AcrLvl:=AcrLvl+1;
 Accuracy:=Accuracy-MaxAcr;
end;
//тоже для скорости
if Speed>=MaxSpd then
begin
 SpdLvl:=SpdLvl+1;
 Speed:=Speed-MaxSpd;
end;

end;

procedure TPlayer.Generate(size:integer);
begin

end;
{==============================================================}
{===================    tSprite   =============================}
{==============================================================}

procedure tSprite.Draw(x,y,angle,flags:integer);
begin
//рисуем спрайт по параметрам спрайта
SSprite_Draw(texture,x,y,wx,hx,alpha,angle,flags);

end;

procedure tSprite.Draw2(x,y,w,h,alph,angle,flags:integer);
begin
//рисуем спрайт польностью по своим параметрам
SSprite_Draw(texture,x,y,w,h,alph,angle,flags);

end;

{==============================================================}
{===================    tCard   ===============================}
{==============================================================}

procedure tCard.Draw;
var i1,i2:integer;
begin

//оптимизация до внесения деталей
{for i1:=1 to sizex do
 for i2:=1 to sizey do
  arspr[3].Draw(x+16+i1*16,y+16+i2*16,0,1);

for i1:=1 to (sizex div 2)+1 do
 arspr[2].Draw(x+i1*32,y,0,1);

for i1:=1 to (sizex div 2)+2 do
 arspr[2].Draw(x-32+i1*32,y+sizey*16+32,0,1);

for i1:=1 to (sizey div 2)+1 do
 arspr[2].Draw(x+sizex*16+32,y+i1*32,0,1);

for i1:=1 to (sizey div 2) do
 arspr[2].Draw(x,y+i1*32,0,1);}
/////////////////////////////////

//сначала был рендр в текстуру с дальнейшей отрисовкой текстуры
//но рендр ишёл как-то не так, результат был смещен
//эта проблема не решилась сразу и
//карта стала вновь рендрится как совокупность отдельных элементов
//так же при рендре в текстуры остаётся тёмный край
//т. к. я не знаю, как сделать прозрачность для texture
//при рендренге в текстуру и дальнейшем использование отрендренной текстуры
//достигается значительное увиличение колва кадров в секунду

{if not rendr then begin
                   Tex_BeginRenderIn(texture,false,true,true);}
                   arspr[1].Draw(x,y,0,1);
                   arspr[3].Draw2(x+32,y,sizex*16+24,sizey*16+56,255,0,1);
                   arspr[2].Draw2(x,y+32,32,sizey*16+24,255,0,1);

                   for i1:=1 to sizex do
                    for i2:=1 to sizey do
                     if data[i1,i2,2] then Pr2D_Rect(x+17+i1*16,y+17+i2*16,12,12,$0000dd,255,PR_FILL );

                   for i1:=1 to (sizey div 2) do begin
                    arspr[6].Draw(x+32,y+i1*32,0,1);
                    arspr[6].Draw(x+sizex*16,y+i1*32,180,1);
                   end;

                   for i1:=1 to (sizey div 2) do
                    arspr[7].Draw2(x+64,y+i1*32,sizex*16-64,32,255,0,1);

                   for i1:=1 to (sizex div 2)-1 do
                    for i2:=1 to (sizey div 2) do
                     arspr[8].Draw(x+32+i1*32,y+i2*32,0,1);
/////////////////////////////////
                   {for i1:=1 to (sizex div 2)-2 do
                    for i2:=1 to (sizey div 2) do
                     arspr[7].Draw(x+32+i1*32,y+i2*32,0,1);}
/////////////////////////////////
                   for i1:=1 to sizex do
                    for i2:=1 to sizey do
                     if data[i1,i2,1] then arspr[4].Draw(x+16+i1*16,y+16+i2*16,0,1)
                                      else arspr[5].Draw(x+16+i1*16,y+16+i2*16,0,1);

{                   Tex_EndRenderIn;
                   rendr:=true;
                   SSprite_Draw(texture,x,y,sizex*16+56,sizey*16+56);
                  end else
 SSprite_Draw(texture,x,y,sizex*16+56,sizey*16+56);}

end;

procedure tCard.Init;    //инит вызывать только после присваивания размера карте!!!
begin

arspr[1]:=res.spr[res.findspr('cardtl')];
arspr[2]:=res.spr[res.findspr('cardends')];
arspr[3]:=res.spr[res.findspr('cardf')];
arspr[4]:=res.spr[res.findspr('cardhole')];
arspr[5]:=res.spr[res.findspr('cardnhole')];
arspr[6]:=res.spr[res.findspr('cardflgr')];
arspr[7]:=res.spr[res.findspr('cardfgr')];
arspr[8]:=res.spr[res.findspr('cardvertgr')];
{arspr[9]:=res.spr[res.findspr('cardtoplcpt')];
arspr[10]:=res.spr[res.findspr('cardtoprcpt')];
arspr[11]:=res.spr[res.findspr('cardtopcpt')];}

{startx:=1;
starty:=1;}

{rendr:=false;

texture:=Tex_CreateZero(sizex*16+56,sizey*16+56,TEX_DEFAULT_2D);}

end;

{==============================================================}
{===================    tRecurces    ==========================}
{==============================================================}

function tRecurces.FindSpr(name:string):integer;
var i:integer;
    t:boolean;
begin
//индикатор - ти нашили спрайт с таким именем
t:=false;
//ищем спрайт с требуемым именем
//и если нашли, выходим
For i:=1 to QSpr do
 if Spr[i].name=name then begin
  FindSpr:=i;
  t:=true;
  Break;
 end;

//если не нашли спрайт, выходим из игры
//а то полетит всё с ошибкой
if not t then begin
 erorname:=name;
 OE_Quit;
end;
//в дальнейшем можно узнать имя не найденого спрайта в файле eror.txt

end;

procedure tRecurces.AddSpr(patch:string);     //загружаем в ресурсы спрайт
var DF:textfile;               //файл данных спрайта
    bt:boolean;                //была ли загружена маска
    t1,t2,t3,t4:integer;       //высота, ширина, прозрачный цвет и альфа спрайта
    p1,p2,str:string;          //текстура, маска и имя спрайта
begin

assignfile(DF,DFld+patch);     //получаем данные из файла
reset(DF);
readln(DF,t1,t2,t3,t4);
readln(DF,p1);
readln(DF,p2);
readln(DF,str);
closefile(DF);

if p2<>'nil' then    //если нету для этой т-ры маски, то второй путь равен nil
 begin
  Tex_LoadMaskFromFile(PChar(DFld+p2)); //если второй путь не равен nil, то загружаем маску
  bt:=true;
 end else bt:=false;   //или не загружаем

if bt then Spr[QSpr].Texture:=tex_loadfromfile(pChar(DFld+p1),t3,TEX_DEFAULT_2D or TEX_USEMASK)//если маску грузили, пишем об этом
      else Spr[QSpr].Texture:=tex_loadfromfile(pChar(DFld+p1),t3,TEX_DEFAULT_2D);//иначе не пишем

//присваеваем полученые значения
Spr[QSpr].wx:=t1;
Spr[QSpr].hx:=t2;
Spr[QSpr].tcolor:=t3;
Spr[QSpr].alpha:=t4;
Spr[QSpr].name:=str;
Spr[QSpr].patch:=p1;
Spr[QSpr].mpatch:=p2;

QSpr:=QSpr+1;          //пишем след. пустую ячейку

Tex_FreeMask;          //очищаем маску

end;


end.
