Advertisement
mixster

mixster

Sep 29th, 2008
309
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 33.87 KB | None | 0 0
  1. program ScaRPG;
  2. const
  3.   FPS = 30; // Fine tune to improve performance
  4.   debugScript = True; // Set to true to output debugging data
  5. type
  6.   TMap = record
  7.     tpTiles: array of array of array of TPoint;
  8.     att: array of array of Integer;
  9.     x, y, z, p: Integer;
  10.   end;
  11.   TNPC = record
  12.     s, m: TPoint;
  13.     sTalk: string;
  14.   end;
  15.   TChar = record
  16.     s, m, d: TPoint;
  17.   end;
  18.   TStat = record
  19.     att, def, spd, hp: Integer;
  20.   end;
  21.   TBattleChar = record
  22.     id, lvl, bHp, xp, atb: Integer;
  23.     ind, cur: TStat;
  24.     moves: TIntegerArray;
  25.   end;
  26.   TMoveList = array of record
  27.     tMo, level: Integer;
  28.   end;
  29.   TSpecies = record
  30.     base: TStat;
  31.     xp: Integer;
  32.     posMoves: TMoveList;
  33.     name: string;
  34.   end;
  35.   TMove = record
  36.     power, acc: Integer;
  37.     name: string;
  38.   end;
  39.   TItem = record
  40.     power, owned: Integer;
  41.     name: string;
  42.   end;
  43. var
  44.   frmMain: TForm;
  45.   imgMain: TImage;
  46.   lblTalk, lblParty, lblEnemies, lblMoves, lblTargets, lblMenu, lblInfo: TLabel;
  47.   shpMove, shpTarget, shpMenu: TShape;
  48.   tmrEngine: TTimer;
  49.   dlgOpen: TOpenDialog;
  50.   tiles, sprites: Integer;
  51.   mapMain: TMap;
  52.   chrMain: TChar;
  53.   npcMain: array of TNPC;
  54.   bcParty, bcEnemies: array of TBattleChar;
  55.   stSRLMon: array of TSpecies;
  56.   moMoves: array of TMove;
  57.   tiItems: array of TItem;
  58.   battling, selTarg: Boolean;
  59.   encCount: Integer;
  60.  
  61. procedure Debug(s: string);
  62. begin
  63.   if debugScript then
  64.     Writeln(s);
  65. end;
  66.  
  67. procedure DebugI(i: Integer);
  68. begin
  69.   Debug(IntToStr(i));
  70. end;
  71.  
  72. procedure DebugTP(t: TPoint);
  73. begin
  74.   Debug(IntToStr(t.x) + ',' + IntToStr(t.y));
  75. end;
  76.  
  77. procedure Engine(sender: TObject); forward;
  78.  
  79. // GenerateMap - Uses information in "mapMain" to assemble a 3D map onto a 2D canvas in a small amount of time
  80. procedure GenerateMap;
  81. var
  82.   bmpLay, bmpBuf, a, b, c, s, mapX, mapY, startX, startY, copyXO, copyYO: Integer;
  83. begin
  84.   bmpLay := BitmapFromString(544, 544, '');
  85.   bmpBuf := BitmapFromString(544, 544, '');
  86.  
  87.   copyXO := Round(chrMain.d.x * (32 / 3)) + 32;
  88.   copyYO := Round(chrMain.d.y * (32 / 3)) + 32;
  89.   startX := chrMain.m.x - 8;
  90.   startY := chrMain.m.y - 8;
  91.  
  92.   with mapMain do
  93.   begin
  94.     for a := 0 to z - 1 do
  95.     begin
  96.       FastDrawClear(bmpLay, 16448505);
  97.       for b := startY to startY + 17 do
  98.       begin
  99.         if not InRange(b, 0, y - 1) then
  100.           Continue;
  101.         mapY := b - chrMain.m.y;
  102.         for c := startX to startX + 17 do
  103.         begin
  104.           if not InRange(c, 0, x - 1) then
  105.             Continue;
  106.           mapX := c - chrMain.m.x;
  107.           CopyCanvas(GetBitmapCanvas(tiles), GetBitmapCanvas(bmpLay), tpTiles[a][b][c].x * 32, tpTiles[a][b][c].y * 32, (tpTiles[a][b][c].x * 32) + 32, (tpTiles[a][b][c].y * 32) + 32, (c - startX) * 32, (b - startY) * 32, ((c - startX) * 32) + 32, ((b - startY) * 32) + 32);
  108.         end;
  109.       end;
  110.       SetTransparentColor(bmpLay, 16448505);
  111.       FastDrawTransparent(0, 0, bmpLay, bmpBuf);
  112.       if a = p then
  113.       begin
  114.         FastDrawClear(bmpLay, 0);
  115.         with chrMain do
  116.         begin
  117.           CopyCanvas(GetBitmapCanvas(sprites), GetBitmapCanvas(bmpLay), s.x * 32, s.y * 32, (s.x * 32) + 32, (s.y * 32) + 32, 224 + copyXO, 224 + copyYO, 256 + copyXO, 256 + copyYO);
  118.         end;
  119.         if High(npcMain) >= 0 then
  120.           for s := 0 to High(npcMain) do
  121.             with npcMain[s] do
  122.             begin
  123.               If InRange(m.x, chrMain.m.x - 8, chrMain.m.x + 9) and InRange(m.y, chrMain.m.y - 8, chrMain.m.y + 9) then
  124.                 CopyCanvas(GetBitmapCanvas(sprites), GetBitmapCanvas(bmpLay), s.x * 32, s.y * 32, (s.x * 32) + 32, (s.y * 32) + 32, (m.x - startX) * 32, (m.y - startY) * 32, ((m.x - startX) * 32) + 32, ((m.y - startY) * 32) + 32);
  125.             end;
  126.         SetTransparentColor(bmpLay, 0);
  127.         FastDrawTransparent(0, 0, bmpLay, bmpBuf);
  128.       end;
  129.     end;
  130.   end;
  131.   try
  132.     SafeCopyCanvas(GetBitmapCanvas(bmpBuf), imgMain.Canvas, copyXO, copyYO, copyXO + 480, copyYO + 480, 0, 0, 480, 480);
  133.   except
  134.     Writeln('Map drawing failed - exiting');
  135.   end;
  136.   FreeBitmap(bmpBuf);
  137.   FreeBitmap(bmpLay);
  138. end;
  139.  
  140. procedure GenerateStats(bcChars: array of TBattleChar; maxHp: Boolean); forward;
  141.  
  142. // RandomizeMap - Takes in info as a range and generates comepletely random content with it, including enemies and party members
  143. procedure RandomizeMap(xs, ys, zs, ss, xe, ye, ze, se: Integer);
  144. var
  145.   mx, my, a, b, c: Integer;
  146.   tsaRandTalk: TStringArray;
  147. begin
  148.   tsaRandTalk := ['Hai der', 'Howdy partner', 'Hi', 'SEX', 'How much wood could chuck norris chuck', 'I won''t kill you if you touch my penis'];
  149.   GetBitmapSize(tiles, mx, my);
  150.   with mapMain do
  151.   begin
  152.     x := RandomRange(xs, xe);
  153.     y := RandomRange(ys, ye);
  154.     z := RandomRange(zs, ze);
  155.     p := z - 1;
  156.     SetArrayLength(tpTiles, z);
  157.     for a := 0 to z - 1 do
  158.     begin
  159.       SetArrayLength(tpTiles[a], y);
  160.       SetArrayLength(att, y);
  161.       for b := 0 to y - 1 do
  162.       begin
  163.         SetArrayLength(tpTiles[a][b], x);
  164.         SetArrayLength(att[b], x);
  165.         for c := 0 to x - 1 do
  166.         begin
  167.           tpTiles[a][b][c].x := Random(mx div 32);
  168.           tpTiles[a][b][c].y := Random(my div 32);
  169.         end;
  170.       end;
  171.     end;
  172.   end;
  173.   with chrMain do
  174.   begin
  175.     m.x := mapMain.x div 2;
  176.     m.y := mapMain.y div 2;
  177.   end;
  178.   GetBitmapSize(tiles, mx, my);
  179.   SetArrayLength(npcMain, RandomRange(ss, se));
  180.   for a := 0 to High(npcMain) do
  181.     with npcMain[a] do
  182.     begin
  183.       s.x := Random(mx div 128) * 3;
  184.       s.y := Random(my div 32);
  185.       m.x := Random(mapMain.x);
  186.       m.y := Random(mapMain.y);
  187.       sTalk := tsaRandTalk[Random(High(tsaRandTalk))];
  188.       mapMain.att[m.y][m.x] := 1;
  189.     end;
  190.   SetArrayLength(moMoves, RandomRange(155,255));
  191.   for a := 0 to High(moMoves) do
  192.     with moMoves[a] do
  193.     begin
  194.       for b := 0 to RandomRange(3, 6) do
  195.         name := name + Chr(RandomRange(32, 127));
  196.       power := (RandomRange(50, 150) + RandomRange(50, 150)) div 2;
  197.       acc := RandomRange(40, 100);
  198.     end;
  199.   SetArrayLength(stSRLMon, RandomRange(155, 255));
  200.   for a := 0 to High(stSRLMon) do
  201.     with stSRLMon[a] do
  202.     begin
  203.       for b := 0 to RandomRange(3, 6) do
  204.         name := name + Chr(RandomRange(32, 127));
  205.       base.hp := RandomRange(75, 150);
  206.       base.att := RandomRange(75, 150);
  207.       base.def := RandomRange(75, 150);
  208.       base.spd := RandomRange(75, 150);
  209.       xp := RandomRange(50, 250);
  210.       SetArrayLength(posMoves, 100);
  211.       for b := 0 to High(posMoves) do
  212.         with posMoves[b] do
  213.         begin
  214.           tMo := Random(High(moMoves) + 1);
  215.           level := b;
  216.         end;
  217.     end;
  218.   if High(bcParty) <= 2 then
  219.   SetArrayLength(bcParty, 4);
  220.   for a := 0 to High(bcParty) do
  221.     with bcParty[a] do
  222.     begin
  223.       if lvl = 0 then
  224.       begin
  225.         id := Random(High(stSRLMon));
  226.         ind.hp := 200;
  227.         ind.att := 200;
  228.         ind.def := 200;
  229.         ind.spd := 500;
  230.         lvl := 5;
  231.         moves := [stSRLMon[id].posMoves[0].tmo, stSRLMon[id].posMoves[1].tmo, stSRLMon[id].posMoves[2].tmo, stSRLMon[id].posMoves[3].tmo, stSRLMon[id].posMoves[4].tmo];
  232.       end;
  233.     end;
  234.   GenerateStats(bcParty, True);
  235.   SetArrayLength(tiItems, RandomRange(10, 20));
  236.   for a := 0 to High(tiItems) do
  237.     with tiItems[a] do
  238.     begin
  239.       power := Random(90) + 10;
  240.       for b := 0 to RandomRange(3, 6) do
  241.         name := name + Chr(RandomRange(32, 127));
  242.       if Random(10) <= 3 then
  243.         owned := Random(5);
  244.     end;
  245.   encCount := Random(100);
  246. end;
  247.  
  248. // OffScreen - Takes characters movement and will return true is char will end up offscreen
  249. function OffScreen: Boolean;
  250. begin
  251.   with chrMain do
  252.     case s.x of
  253.       3: Result := m.y >= mapMain.y - 1;
  254.       9: Result := m.x >= mapMain.x - 1;
  255.       0: Result := m.y <= 0;
  256.       6: Result := m.x <= 0;
  257.     end;
  258. end;
  259.  
  260. // Collision - Sees if the characters movement will cause a collision with an attribute such as blocked tile
  261. function Collision(attribute: Integer): Boolean;
  262. begin
  263.   with chrMain do
  264.     case s.x of
  265.       3: if m.y < mapMain.y then
  266.         Result := mapMain.att[m.y + 1][m.x] = attribute;
  267.       9: if m.x < mapMain.x then
  268.         Result := mapMain.att[m.y][m.x + 1] = attribute;
  269.       0: if m.y > 0 then
  270.         Result := mapMain.att[m.y - 1][m.x] = attribute;
  271.       6: if m.x > 0 then
  272.         Result := mapMain.att[m.y][m.x - 1] = attribute;
  273.     end;
  274. end;
  275.  
  276. // TalkCollision - Returns a TPoint of an npc the character is facing used to find which NPC it is by comparing positions
  277. function TalkCollision: TPoint;
  278. begin
  279.   Result.x := 0;
  280.   Result.y := 0;
  281.   case chrMain.s.x of
  282.     0: Dec(Result.y);
  283.     6: Dec(Result.x);
  284.     3: Inc(Result.y);
  285.     9: Inc(Result.x);
  286.   end;
  287.   IncEx(Result.x, chrMain.m.x);
  288.   IncEx(Result.y, chrMain.m.y);
  289. end;
  290.  
  291. procedure PrepareBattle; forward;
  292.  
  293. // HandleMove - Timer procedure that handles the smooth movement of the character
  294. procedure HandleMove(sender: TObject);
  295. begin
  296.   with chrMain do
  297.   begin
  298.     if tmrEngine.Interval = 1000 / FPS then
  299.     begin
  300.       if Collision(1) or OffScreen then
  301.       begin
  302.         tmrEngine.OnTimer := @Engine;
  303.         d.y := 0;
  304.         d.x := 0;
  305.         GenerateMap;
  306.         Exit;
  307.       end
  308.       else if Collision(2) then
  309.         Dec(encCount);
  310.       tmrEngine.Interval := (1000 / FPS) * 4;
  311.     end
  312.     else if d.y < 0 then
  313.       Dec(d.y)
  314.     else if d.x < 0 then
  315.       Dec(d.x)
  316.     else if d.y > 0 then
  317.       Inc(d.y)
  318.     else if d.x > 0 then
  319.       Inc(d.x);
  320.  
  321.     Inc(s.x);
  322.     if (not (InRange(d.y, -2, 2))) or (not (InRange(d.x, -2, 2))) then
  323.     begin
  324.       DecEx(s.x, 3);
  325.       if d.y < 0 then
  326.         Dec(m.y)
  327.       else if d.y > 0 then
  328.         Inc(m.y)
  329.       else if d.x < 0 then
  330.         Dec(m.x)
  331.       else
  332.         Inc(m.x);
  333.       d.y := 0;
  334.       d.x := 0;
  335.       tmrEngine.OnTimer := @Engine;
  336.       tmrEngine.Interval := 1000 / FPS;
  337.       Writeln('P:' + IntToStr(chrMain.m.x) + ',' + IntToStr(chrMain.m.y) + ' - E:' + IntToStr(encCount));
  338.     end;
  339.   end;
  340.   GenerateMap;
  341.   if (encCount <= 0) and (chrMain.d.x = 0) and (chrMain.d.y = 0) then
  342.     PrepareBattle;
  343. end;
  344.  
  345. function GetKeyDown: char; forward;
  346.  
  347. // HandleTalk - Procedure to see if facing a NPC and if so to launch the chat
  348. procedure HandleTalk(sender: TObject);
  349. var
  350.   s: Integer;
  351.   p: TPoint;
  352. begin
  353.   with imgMain do
  354.     if Tag = 0 then
  355.     begin
  356.       if not Collision(1) then
  357.       begin
  358.         tmrEngine.OnTimer := @Engine;
  359.         Exit;
  360.       end
  361.       else
  362.       begin
  363.         p := TalkCollision;
  364.         for s := 0 to High(npcMain) do
  365.           if (p.x = npcMain[s].m.x) and (p.y = npcMain[s].m.y) then
  366.           begin
  367.             lblTalk.Caption := npcMain[s].sTalk;
  368.             Break;
  369.           end;
  370.       end;
  371.       if lblTalk.Caption = '' then
  372.       begin
  373.         tmrEngine.OnTimer := @Engine;
  374.         Exit;
  375.       end;
  376.       Tag := 1;
  377.       Canvas.RoundRect(1, 415, 479, 479, 20, 20);
  378.       lblTalk.Visible := True;
  379.     end
  380.     else if GetKeyDown = 'e' then
  381.     begin
  382.       tmrEngine.OnTimer := @Engine;
  383.       lblTalk.Caption := '';
  384.       lblTalk.Visible := False;
  385.       GenerateMap;
  386.       Tag := 0;
  387.     end;
  388. end;
  389.  
  390. // GetKeyDown - Returns a general range character that is down
  391. function GetKeyDown: char;
  392. var
  393.   i: Integer;
  394.   s: string;
  395. begin
  396.   for i := 32 to 127 do
  397.     if IsKeyDown(Chr(i)) then
  398.       if IsKeyDown(Chr(i)) then
  399.         s := s + Chr(i);
  400.   if Length(s) > 0 then
  401.     Result := s[Length(s)]
  402.   else
  403.     Result := Chr(1);
  404. end;
  405.  
  406. // GenerateStats - Takes in a party (own or enemies) and then makes their stats through a formula and will max out hp if maxHp is true
  407. procedure GenerateStats(bcChars: array of TBattleChar; maxHp: Boolean);
  408. var
  409.   i: Integer;
  410. begin
  411.   for i := 0 to High(bcChars) do
  412.     with bcChars[i] do
  413.     begin
  414.       cur.hp := Trunc(((((2 * stSRLMon[id].base.hp) + ind.hp) * lvl) / 100) + lvl + 10);
  415.       cur.att := Trunc(((((2 * stSRLMon[id].base.att) + ind.att) * lvl) / 100) + 5);
  416.       cur.def := Trunc(((((2 * stSRLMon[id].base.def) + ind.def) * lvl) / 100) + 5);
  417.       cur.spd := Trunc(((((2 * stSRLMon[id].base.spd) + ind.spd) * lvl) / 100) + 5);
  418.       if maxHp then
  419.         bHp := cur.hp;
  420.       atb := Random(1001);
  421.     end;
  422. end;
  423.  
  424. // HandleXP - Will award xp to the party based on a formula and how much damage was done to the enemies
  425. function HandleXp: Integer;
  426. var
  427.   i: Integer;
  428. begin
  429.   for i := 0 to High(bcEnemies) do
  430.     with bcEnemies[i] do
  431.       IncEx(bcEnemies[0].xp, Trunc((((stSRLMon[id].xp * lvl) div 12) div cur.hp) * (cur.hp - bHp)));
  432.  
  433.   bcEnemies[0].xp := bcEnemies[0].xp div (High(bcParty) + 1);
  434.   for i := 0 to High(bcParty) do
  435.     with bcParty[i] do
  436.     begin
  437.       IncEx(xp, bcEnemies[0].xp);
  438.       if xp >= Trunc(Pow(3 * lvl, 3) / 4) then
  439.       begin
  440.         DecEx(xp,Trunc(Pow(3 * lvl, 3) / 4));
  441.         Inc(lvl);
  442.       end;
  443.     end;
  444.   Result := bcEnemies[0].xp;
  445. end;
  446.  
  447. // SetupBattleLabels - Puts in the appropriate information to the labels on the battle screen
  448. procedure SetupBattleLabels;
  449. var
  450.   i: Integer;
  451. begin
  452.   lblParty.Caption :=  '';
  453.   for i := 0 to High(bcParty) do
  454.     with bcParty[i] do
  455.       lblParty.Caption := lblParty.Caption + stSRLMon[id].Name + ': L: ' + IntToStr(lvl) + '; HP ' + IntToStr(bHp) + '/' + IntToStr(cur.hp) + '; A: ' + IntToStr(cur.att) + '; D: ' + IntToStr(cur.def) + '; S: ' + IntToStr(cur.spd) + '; ATB: ' + IntToStr(atb) + '; XP: ' + IntToStr(xp) + '/' + IntToStr(Trunc(Pow(3 * lvl, 3) / 4)) + #13;
  456.   lblEnemies.Caption := '';
  457.   for i := 0 to High(bcEnemies) do
  458.     with bcEnemies[i] do
  459.       lblEnemies.Caption := lblEnemies.Caption + stSRLMon[id].Name + ': L: ' + IntToStr(lvl) + '; HP ' + IntToStr(bHp) + '/' + IntToStr(cur.hp) + '; A: ' + IntToStr(cur.att) + '; D: ' + IntToStr(cur.def) + '; S: ' + IntToStr(cur.spd) + '; ATB: ' + IntToStr(atb) + #13;
  460. end;
  461.  
  462. procedure BattleEngine(Sender: TObject); forward;
  463.  
  464. // PrepareBattle - Sets up all the necessary stuff for the battle
  465. procedure PrepareBattle;
  466. var
  467.   i, a, r: Integer;
  468.   pM: TIntegerArray;
  469. begin
  470.   battling := True;
  471.   SetArrayLength(bcEnemies, 0);
  472.   SetArrayLength(bcEnemies, High(bcParty) + Random(3) - 1);
  473.   for i := 0 to High(bcParty) do
  474.     IncEx(a, bcParty[i].lvl);
  475.   a := a div (High(bcParty) + 1);
  476.   for i := 0 to High(bcEnemies) do
  477.     with bcEnemies[i] do
  478.     begin
  479.       id := Random(High(stSRLMon) + 1);
  480.       lvl := a + Random(3) - 1;
  481.       ind.hp := RandomRange(75, 125);
  482.       ind.att := RandomRange(75, 125);
  483.       ind.def := RandomRange(75, 125);
  484.       ind.spd := RandomRange(75, 125);
  485.       for a := High(stSRLMon[id].posMoves) downto 0 do
  486.         if stSRLMon[id].posMoves[a].level <= lvl then
  487.         begin
  488.           SetArrayLength(pM, High(pM) + 2);
  489.           pM[High(pM)] := a;
  490.         end;
  491.       if High(pM) > 9 then
  492.         SetArrayLength(pM, 10);
  493.       for a := 0 to 5 do
  494.       begin
  495.         if High(pM) = -1 then
  496.           Break;
  497.         r := Random(High(pM) + 1);
  498.         SetArrayLength(moves, High(moves) + 2);
  499.         moves[High(moves)] := pM[r];
  500.         Swap(pM[r], pM[High(pM)]);
  501.         SetArrayLength(pM, High(pM));
  502.       end;
  503.     end;
  504.   GenerateStats(bcParty, False);
  505.   GenerateStats(bcEnemies, True);
  506.   lblParty.Visible := True;
  507.   lblEnemies.Visible := True;
  508.   imgMain.Canvas.Rectangle(0, 0, 480, 480);
  509.   SetupBattleLabels;
  510.   tmrEngine.Interval := 64;
  511.   tmrEngine.OnTimer := @BattleEngine;
  512. end;
  513.  
  514. // ApplyDamage - plugs numbers to decide on how much damage will be dealt and random miss chance
  515. procedure ApplyDamage(var bcFrom, bcUpon: TBattleChar; tmoId: Integer);
  516. var
  517.   damage: Integer;
  518. begin
  519.   with bcFrom do
  520.     damage := ((((((((2 * lvl) div 5) + 2) * cur.att * moMoves[moves[tmoId]].Power) div bcUpon.cur.def) div 50) + 2) * RandomRange(217, 255)) div 255;
  521.   if Random(100) + 1 > moMoves[bcFrom.moves[tmoId]].Acc then
  522.     damage := 0;
  523.   DecEx(bcUpon.bHp, damage);
  524.   DecEx(bcFrom.atb, 1000);
  525.   if bcUpon.bHp <= 0 then
  526.     bcUpon.bHp := 0;
  527. end;
  528.  
  529. // HandleEnd - Gives out xp and tells the user whether won or lost and sets a new encounter number
  530. procedure HandleEnd(victory: Boolean);
  531. var
  532.   i: Integer;
  533. begin
  534.   battling := False;
  535.   if victory then
  536.     lblMoves.Caption := 'Well done, you won!'
  537.   else
  538.     lblMoves.Caption := 'Oh no, defeated!';
  539.   lblMoves.Caption := lblMoves.Caption + ' SRLMon gained ' + IntToStr(HandleXP) + ' xp';
  540.   lblMoves.Visible := True;
  541.   if not victory then
  542.     for i := 0 to High(bcParty) do
  543.       with bcParty[i] do
  544.       begin
  545.         lblMoves.Caption:= lblMoves.Caption + ', but lost ' + IntToStr(Trunc((Pow(3 * lvl, 3) div 4) div 10)) + ' xp';
  546.         DecEx(bcParty[i].xp, Trunc((Pow(3 * lvl, 3) div 4) div 10));
  547.       end;
  548.   encCount := (Random(100) + Random(100) + Random(100)) div 3;
  549. end;
  550.  
  551. // BattleAI - basic AI that will decide on which move to use depending on current HP - near dead enemies fight better
  552. procedure BattleAI(var bcEnemy: TBattleChar);
  553. var
  554.   hpPcnt, i: Integer;
  555.   m: TPoint;
  556. begin
  557.   with bcEnemy do
  558.   begin
  559.     hpPcnt := Trunc((bHp div cur.hp) * 100);
  560.     if hpPcnt >= 70 then
  561.     begin
  562.       m.x := Random(High(moves) + 1);
  563.       for i := High(bcParty) downto 0 do
  564.         if bcParty[i].bHp > 0 then
  565.         begin
  566.           m.y := Random(i + 1);
  567.           Break;
  568.         end;
  569.     end
  570.     else if hpPcnt >= 40 then
  571.     begin
  572.       if RBool then
  573.       begin
  574.         m.x := Random(High(moves) + 1);
  575.         m.y := 99;
  576.         for i := 0 to High(bcParty) do
  577.           if (bcParty[i].bHp < m.y) and (bcParty[i].bHp > 0) then
  578.             m.y := i;
  579.       end
  580.       else
  581.       begin
  582.         for i := 0 to High(moves) do
  583.           if moMoves[moves[i]].Power > moMoves[moves[m.x]].Power then
  584.             m.x := i;
  585.         for i := High(bcParty) downto 0 do
  586.         if bcParty[i].bHp > 0 then
  587.         begin
  588.           m.y := Random(i + 1);
  589.           Break;
  590.         end;
  591.       end;
  592.     end
  593.     else
  594.     begin
  595.       for i := 0 to High(moves) do
  596.         if moMoves[moves[i]].Power > moMoves[moves[m.x]].Power then
  597.           m.x := i;
  598.       for i := 0 to High(bcParty) do
  599.         if (bcParty[i].bHp < bcParty[m.y].bHp) and (bcParty[i].bHp > 0) then
  600.           m.y := i;
  601.     end;
  602.   end;
  603.   ApplyDamage(bcEnemy, bcParty[m.y], m.x);
  604.   if bcParty[m.y].bHp <= 0 then
  605.   begin
  606.     bcParty[m.y].cur.spd := 0;
  607.     bcParty[m.y].atb := 0;
  608.     for i := High(bcParty) downto 0 do
  609.       if (bcParty[i].bHp > 0) and (m.y < i) then
  610.         Swap(bcParty[i], bcParty[m.y]);
  611.   end;
  612.   if bcParty[0].bHp <= 0 then
  613.     HandleEnd(False);
  614. end;
  615.  
  616. // ToggleInput - Easy way to display or hide move and target selection
  617. procedure ToggleInput(show: Boolean);
  618. begin
  619.   lblMoves.Visible := show;
  620.   lblTargets.Visible := show;
  621.   shpMove.Visible := show;
  622.   shpTarget.Visible := show;
  623. end;
  624.  
  625. // HandleTurn - Selects which party member is attacking, applies the damage then checks for enemies death and will see if victory has been obtained
  626. procedure HandleTurn(mo, ta: Integer);
  627. var
  628.   i, p: Integer;
  629. begin
  630.   for i := 0 to High(bcParty) do
  631.     if bcParty[i].atb > 1000 then
  632.     begin
  633.       p := i;
  634.       Break;
  635.     end;
  636.   ApplyDamage(bcParty[p], bcEnemies[ta], mo);
  637.   if bcEnemies[ta].bHp <= 0 then
  638.   begin
  639.     bcEnemies[ta].cur.spd := 0;
  640.     bcEnemies[ta].atb := 0;
  641.     for i := High(bcEnemies) downto 0 do
  642.       if (bcEnemies[i].bHp > 0) and (ta < i) then
  643.         Swap(bcEnemies[i], bcEnemies[ta]);
  644.   end;
  645.   ToggleInput(False);
  646.   if bcEnemies[0].bHp = 0 then
  647.     HandleEnd(True);
  648.   lblMoves.Tag := 0;
  649.   lblTargets.Tag := 0;
  650.   selTarg := False;
  651.   tmrEngine.Enabled := True;
  652.   frmMain.OnKeyPress := nil;
  653. end;
  654.  
  655. // HandleTurnItem - Handles the dispense of items
  656. procedure HandleTurnItem(item, ally: Integer);
  657. var
  658.   i, p: Integer;
  659.   its: TIntegerArray;
  660. begin
  661.   for i := 0 to High(tiItems) do
  662.     with tiItems[i] do
  663.       if owned > 0 then
  664.       begin
  665.         SetArrayLength(its, GetArrayLength(its) + 1);
  666.         its[High(its)] := i;
  667.       end;
  668.   for i := 0 to High(bcParty) do
  669.     if bcParty[i].atb > 1000 then
  670.     begin
  671.       p := i;
  672.       Break;
  673.     end;
  674.   with bcParty[ally] do
  675.   begin
  676.     IncEx(bHp, tiItems[its[item]].power);
  677.     if bHp > cur.hp then
  678.       bHp := cur.hp;
  679.   end;
  680.   bcParty[p].atb := 500;
  681.   Dec(tiItems[its[item]].owned);
  682.   ToggleInput(False);
  683.   lblMoves.Tag := 0;
  684.   lblTargets.Tag := 0;
  685.   encCount := 0;
  686.   selTarg := False;
  687.   tmrEngine.Enabled := True;
  688.   frmMain.OnKeyPress := nil;
  689. end;
  690.  
  691. procedure HandleItem(Sender: TObject; var Key: Char); forward;
  692.  
  693. // PrepareItems - Displays available items when launched
  694. procedure PrepareItems;
  695. var
  696.   a: Integer;
  697. begin
  698.   lblTargets.Caption := '';
  699.   for a := 0 to High(tiItems) do
  700.     with tiItems[a] do
  701.       if owned > 0 then
  702.         lblTargets.Caption := lblTargets.Caption + name + ': Power :' + IntToStr(power) + '; Quantity :' + IntToStr(owned) + #13;
  703. end;
  704.  
  705. // PrepareItemTargets - Sets up allies as the targets for an item
  706. procedure PrepareItemTargets;
  707. var
  708.   i: Integer;
  709. begin
  710.   lblTargets.Caption := '';
  711.   for i := 0 to High(bcParty) do
  712.     with bcParty[i] do
  713.       if bHp > 0 then
  714.         lblTargets.Caption := lblTargets.Caption + stSRLMon[id].Name + ': HP ' + IntToStr(bHp) + '/' + IntToStr(cur.hp) + #13;
  715. end;
  716.  
  717. // HandleInput - OnKey event that does what's needed depending on the key
  718. procedure HandleInput(Sender: TObject; var Key: Char);
  719. var
  720.   i: Integer;
  721. begin
  722.   if not battling then
  723.     Exit;
  724.   if not selTarg then
  725.   begin
  726.     with lblMoves do
  727.     begin
  728.       i := Tag;
  729.       case Key of
  730.         'w': Tag := Tag - 1;
  731.         's': Tag := Tag + 1;
  732.         'q': selTarg := True;
  733.       end;
  734.       if (Tag = Round(Height div 13.0) - 1) and selTarg then
  735.       begin
  736.         PrepareItems;
  737.         frmMain.OnKeyPress := @HandleItem;
  738.         selTarg := False;
  739.       end;
  740.       if i = Tag then
  741.         Exit;
  742.       if Tag < 0 then
  743.         Tag := Round(Height div 13.0) - 1
  744.       else if Tag > Round(Height div 13.0) - 1 then
  745.         Tag := 0;
  746.       shpMove.Top := 198 + (Tag * 13);
  747.     end;
  748.   end
  749.   else
  750.   begin
  751.     with lblTargets do
  752.     begin
  753.       i := Tag;
  754.       case Key of
  755.         'w': Tag := Tag - 1;
  756.         's': Tag := Tag + 1;
  757.         'e': selTarg := False;
  758.         'q': HandleTurn(lblMoves.Tag, Tag);
  759.       end;
  760.       if i = Tag then
  761.         Exit;
  762.       if Tag < 0 then
  763.         Tag := Round(Height div 13.0) - 1
  764.       else if Tag > Round(Height div 13.0) - 1 then
  765.         Tag := 0;
  766.       shpTarget.Top := 198 + (Tag * 13);
  767.     end;
  768.   end;
  769. end;
  770.  
  771. // HandleItem - Does what's needed dependant on input for using an item
  772. procedure HandleItem(Sender: TObject; var Key: Char);
  773. var
  774.   i: Integer;
  775. begin
  776.   if not selTarg then
  777.   begin
  778.     with lblTargets do
  779.     begin
  780.       i := Tag;
  781.       case Key of
  782.         'w': Tag := Tag - 1;
  783.         's': Tag := Tag + 1;
  784.         'e': begin
  785.           frmMain.OnKeyPress := @HandleInput;
  786.           lblTargets.Caption := '';
  787.           for i := 0 to High(bcEnemies) do
  788.             with bcEnemies[i] do
  789.               if bHp > 0 then
  790.                 lblTargets.Caption := lblTargets.Caption + stSRLMon[id].Name + ': HP: ' + IntToStr(bHp) + '/' + IntToStr(cur.hp) + ';' + #13;
  791.         end;
  792.         'q': begin
  793.           PrepareItemTargets;
  794.           selTarg := True;
  795.           encCount := Tag;
  796.           Tag := 0;
  797.         end;
  798.       end;
  799.       if i = Tag then
  800.         Exit;
  801.       if Tag < 0 then
  802.         Tag := Round(Height div 13.0) - 1
  803.       else if Tag > Round(Height div 13.0) - 1 then
  804.         Tag := 0;
  805.       shpTarget.Top := 198 + (Tag * 13);
  806.     end;
  807.   end
  808.   else
  809.   begin
  810.     with lblTargets do
  811.     begin
  812.       i := Tag;
  813.       case Key of
  814.         'w': Tag := Tag - 1;
  815.         's': Tag := Tag + 1;
  816.         'e': selTarg := False;
  817.         'q': HandleTurnItem(encCount, Tag);
  818.       end;
  819.       if i = Tag then
  820.         Exit;
  821.       if Tag < 0 then
  822.         Tag := Round(Height div 13.0) - 1
  823.       else if Tag > Round(Height div 13.0) - 1 then
  824.         Tag := 0;
  825.       shpTarget.Top := 198 + (Tag * 13);
  826.     end;
  827.   end;
  828. end;
  829.  
  830. // PrepareInput - Changes from battle engine to a key based input for move and target selection
  831. procedure PrepareInput(bcAlly: TBattleChar);
  832. var
  833.   i: Integer;
  834. begin
  835.   lblMoves.Caption := '';
  836.   for i := 0 to High(bcAlly.moves) do
  837.     with moMoves[bcAlly.moves[i]] do
  838.       lblMoves.Caption :=  lblMoves.Caption + Name + ': P: ' + IntToStr(Power) + '; A: ' + IntToStr(Acc) + ';' + #13;
  839.   lblMoves.Caption := lblMoves.Caption + 'Items';
  840.   lblTargets.Caption := '';
  841.   for i := 0 to High(bcEnemies) do
  842.     with bcEnemies[i] do
  843.       if bHp > 0 then
  844.         lblTargets.Caption := lblTargets.Caption + stSRLMon[id].Name + ': HP: ' + IntToStr(bHp) + '/' + IntToStr(cur.hp) + ';' + #13;
  845.   ToggleInput(True);
  846.   shpMove.Top := 198;
  847.   shpTarget.Top := 198;
  848.   tmrEngine.Enabled := False;
  849.   frmMain.OnKeyPress := @HandleInput;
  850. end;
  851.  
  852. procedure BattleEngine(Sender: TObject);
  853. var
  854.   i: Integer;
  855. begin
  856.   if not battling then
  857.   begin
  858.     if GetKeyDown = 'e' then
  859.     begin
  860.       tmrEngine.OnTimer := @Engine;
  861.       lblParty.Visible := False;
  862.       lblEnemies.Visible := False;
  863.       lblMoves.Visible := False;
  864.       GenerateMap;
  865.     end;
  866.     Exit;
  867.   end;
  868.   SetupBattleLabels;
  869.   for i := 0 to High(bcParty) do
  870.   begin
  871.     if bcParty[i].atb > 1000 then
  872.     begin
  873.       PrepareInput(bcParty[i]);
  874.       Continue;
  875.     end;
  876.     IncEx(bcParty[i].atb, bcParty[i].cur.spd);
  877.   end;
  878.   for i := 0 to High(bcEnemies) do
  879.   begin
  880.     if bcEnemies[i].atb > 1000 then
  881.     begin
  882.       BattleAI(bcEnemies[i]);
  883.       Continue;
  884.     end;
  885.     IncEx(bcEnemies[i].atb, bcEnemies[i].cur.spd);
  886.   end;
  887. end;
  888.  
  889. procedure HandleMenu(Sender: TObject; var Key: Char); forward;
  890.  
  891. // PrepareMenu - Paints the menu and sets all the labels to display etc.
  892. procedure PrepareMenu;
  893. begin
  894.   tmrEngine.Enabled := False;
  895.   frmMain.OnKeyPress := @HandleMenu;
  896.   imgMain.Canvas.RoundRect(40, 40, 440, 440, 50, 50);
  897.   imgMain.Canvas.RoundRect(190, 50, 430, 430, 25, 25);
  898.   lblMenu.Caption := 'Stats' + #13 + 'Items' + #13 + 'Help';
  899.   lblMenu.Tag := 0;
  900.   lblInfo.Tag := -1;
  901.   lblMenu.Visible := True;
  902.   lblInfo.Visible := True;
  903.   shpMenu.Visible := True;
  904. end;
  905.  
  906. // UpdateMenu - shows info depending on what selected from menu
  907. procedure UpdateMenu;
  908. var
  909.   i: Integer;
  910. begin
  911.   lblInfo.Caption := '';
  912.   case lblMenu.Tag of
  913.     0: begin
  914.       for i := 0 to High(bcParty) do
  915.         with bcParty[i] do
  916.           lblInfo.Caption := lblInfo.Caption + stSRLMon[id].Name +': ' + IntToStr(bHp) + '/' + IntToStr(cur.hp) + #13 + 'Att: ' + IntToStr(cur.att) + '; Def: ' + IntToStr(cur.def) + '; Spd: ' + IntToStr(cur.spd) + #13 + 'Lvl: ' + IntToSTr(lvl) + 'xp: ' + IntToStr(xp) + '/' + IntToStr(Trunc(Pow(3 * lvl, 3) div 4)) + #13 + #13;
  917.     end;
  918.     1: begin
  919.       for i := 0 to High(tiItems) do
  920.         with tiItems[i] do
  921.           if owned > 0 then
  922.             lblInfo.Caption := lblInfo.Caption + name + ': Power :' + IntToStr(power) + '; Quantity :' + IntToStr(owned) + #13;
  923.     end;
  924.     2: lblInfo.Caption := 'Keys' + #13 + '"wasd" to move' + #13 + '"q" for action' + #13 + '"e" for cancel' + #13 + '"r" for menu';
  925.   end;
  926. end;
  927.  
  928. // ExitMenu - Sets everything to hide and redraws the map
  929. procedure ExitMenu;
  930. begin
  931.   lblMenu.Caption := '';
  932.   lblInfo.Caption := '';
  933.   lblMenu.Tag := 0;
  934.   lblMenu.Visible := False;
  935.   lblInfo.Visible := False;
  936.   shpMenu.Visible := False;
  937.   tmrEngine.Enabled := True;
  938.   frmMain.OnKeyPress := nil;
  939.   GenerateMap;
  940. end;
  941.  
  942. // HandleMenu - Key based input that alters information shown/exits the menu
  943. procedure HandleMenu(Sender: TObject; var Key: Char);
  944. var
  945.   i: Integer;
  946. begin
  947.   with lblMenu do
  948.   begin
  949.     i := Tag;
  950.     case Key of
  951.       'w': Tag := Tag - 1;
  952.       's': Tag := Tag + 1;
  953.       'q': UpdateMenu;
  954.       'e': ExitMenu;
  955.     end;
  956.     if Tag > (Height div 13) - 1 then
  957.       Tag := 0
  958.     else if Tag < 0 then
  959.       Tag := (Height div 13) - 1;
  960.     if i <> Tag then
  961.       shpMenu.Top := 69 + (Tag * 13);
  962.   end;
  963. end;
  964.  
  965. // Engine - Main movement engine that detects user input and deals with appropriately
  966. procedure Engine(sender: TObject);
  967. begin
  968.   with chrMain do
  969.   begin
  970.     case GetKeyDown of
  971.       'w': begin
  972.         d.y := -1;
  973.         s.x := 0;
  974.       end;
  975.       'a': begin
  976.         d.x := -1;
  977.         s.x := 6;
  978.       end;
  979.       's': begin
  980.         d.y := 1;
  981.         s.x := 3;
  982.       end;
  983.       'd': begin
  984.         d.x := 1;
  985.         s.x := 9;
  986.       end;
  987.       'q': tmrEngine.OnTimer := @HandleTalk;
  988.       'b': begin
  989.         tmrEngine.OnTimer := @BattleEngine;
  990.         PrepareBattle;
  991.       end;
  992.       'r': PrepareMenu;
  993.     end;
  994.  
  995.     if (d.y <> 0) or (d.x <> 0) then
  996.       tmrEngine.OnTimer := @HandleMove;
  997.   end;
  998. end;
  999.  
  1000. // ExplodeInt - Like other languages explodes except breaks it down into Integers
  1001. function ExplodeInt(str, del: string): TIntegerArray;
  1002. var
  1003.   i: Integer;
  1004. begin
  1005.   repeat
  1006.     i := Pos(del, str);
  1007.     SetArrayLength(Result, High(Result) + 2);
  1008.     if i <= 0 then
  1009.       Break;
  1010.     Result[High(Result)] := StrToIntDef(Copy(str, 1, i - 1), 0);
  1011.     Delete(str, 1, i);
  1012.   until false;
  1013.   Result[High(Result)] := StrToIntDef(Copy(str, 1, Length(str)), 0);
  1014. end;
  1015.  
  1016. // OpenMap - Loads the selected map into mapMain then draws the map
  1017. procedure OpenMap;
  1018. var
  1019.   titMap, titAtt: TIntegerArray;
  1020.   a, b, c: Integer;
  1021. begin
  1022.   if not dlgOpen.Execute then
  1023.   begin
  1024.     if (mapMain.x = 1) and (mapMain.y = 1) then
  1025.       TerminateScript;
  1026.     Exit;
  1027.   end;
  1028.  
  1029.   with mapMain do
  1030.   begin
  1031.     x := StrToIntDef(ReadINI('Layout', 'Width', dlgOpen.FileName), 15);
  1032.     y := StrToIntDef(ReadINI('Layout', 'Height', dlgOpen.FileName), 15);
  1033.     z := StrToIntDef(ReadINI('Layout', 'Depth', dlgOpen.FileName), 15);
  1034.     p := z - 2;
  1035.     if p < 0 then
  1036.       p := 0;
  1037.  
  1038.     SetArrayLength(tpTiles, 0);
  1039.     SetArrayLength(tpTiles, z);
  1040.     SetArrayLength(att, 0);
  1041.     SetArrayLength(att, y);
  1042.     for a := 0 to z - 1 do
  1043.     begin
  1044.       SetArrayLength(tpTiles[a], 0);
  1045.       SetArrayLength(tpTiles[a], y);
  1046.       for b := 0 to y - 1 do
  1047.       begin
  1048.         SetArrayLength(tpTiles[a][b], 0);
  1049.         SetArrayLength(tpTiles[a][b], x);
  1050.         titMap := ExplodeInt(ReadINI('Layer' + IntToStr(a), 'Row' + IntToStr(b), dlgOpen.FileName), ',');
  1051.         if a = 0 then
  1052.         begin
  1053.           SetArrayLength(att[b], 0);
  1054.           SetArrayLength(att[b], x);
  1055.           SetArrayLength(titAtt, 0);
  1056.           titAtt := ExplodeInt(ReadINI('Attrib', 'Row' + IntToStr(b), dlgOpen.FileName), ',');
  1057.         end;
  1058.         for c := 0 to x - 1 do
  1059.         begin
  1060.           try
  1061.             if a = 0 then
  1062.               att[b][c] := titAtt[c];
  1063.           except
  1064.             Writeln('Attributes section of map may be corrupt - redownload if problem occurs');
  1065.             Debug('Att[' + IntToStr(b) + '][' + IntToStr(c) +'] - H(titAtt[' + IntToStr(High(titAtt)) + ']);');
  1066.           end;
  1067.           try
  1068.             tpTiles[a][b][c].x := titMap[c * 2];
  1069.             tpTiles[a][b][c].y := titMap[c * 2 + 1];
  1070.           except
  1071.             Writeln('Tile section of map may be corrupt - redownload if problem occurs');
  1072.           end;
  1073.         end;
  1074.         SetArrayLength(titMap, 0);
  1075.       end;
  1076.     end;
  1077.   end;
  1078.  
  1079.   chrMain.m.x := 2;
  1080.   chrMain.m.y := 2;
  1081.   GenerateMap;
  1082. end;
  1083.  
  1084. // SetupForm - Sets up all the form objects
  1085. procedure SetupForm;
  1086. var
  1087.   sW, sH: Integer;
  1088. begin
  1089.   GetClientDimensions(sW, sH);
  1090.   frmMain := CreateForm;
  1091.  
  1092.   dlgOpen := TOpenDialog.Create(frmMain);
  1093.   dlgOpen.Filter := 'maps| *.ini';
  1094.  
  1095.   with frmMain do
  1096.   begin
  1097.     Caption := 'ScaRPG by mixster';
  1098.     ClientWidth := 500;
  1099.     ClientHeight := 500;
  1100.     Left := (sW - Width) div 2;
  1101.     Top := (sH - Height) div 2;
  1102.   end;
  1103.   imgMain := TImage.Create(frmMain);
  1104.   with imgMain do
  1105.   begin
  1106.     Parent := frmMain;
  1107.     Width := 480;
  1108.     Height := 480;
  1109.     Left := 10;
  1110.     Top := 10;
  1111.     GenerateMap;
  1112.   end;
  1113.   lblTalk := TLabel.Create(frmMain);
  1114.   with lblTalk do
  1115.   begin
  1116.     Parent := frmMain;
  1117.     Left := 18;
  1118.     Top := 432;
  1119.     Visible := False;
  1120.     Transparent := True;
  1121.   end;
  1122.   lblParty := TLabel.Create(frmMain);
  1123.   with lblParty do
  1124.   begin
  1125.     Parent := frmMain;
  1126.     Left := 18;
  1127.     Top := 380;
  1128.     Visible := False;
  1129.     Transparent := True;
  1130.   end;
  1131.   lblEnemies := TLabel.Create(frmMain);
  1132.   with lblEnemies do
  1133.   begin
  1134.     Parent := frmMain;
  1135.     Left := 18;
  1136.     Top := 18;
  1137.     Visible := False;
  1138.     Transparent := True;
  1139.   end;
  1140.   shpMove := TShape.Create(frmMain);
  1141.   with shpMove do
  1142.   begin
  1143.     Parent := frmMain;
  1144.     Width := 222;
  1145.     Height := 14;
  1146.     Left := 17;
  1147.     Top := 198;
  1148.     Visible := False;
  1149.     Shape := stRoundRect;
  1150.   end;
  1151.   shpTarget := TShape.Create(frmMain);
  1152.   with shpTarget do
  1153.   begin
  1154.     Parent := frmMain;
  1155.     Width := 222;
  1156.     Height := 14;
  1157.     Left := 239;
  1158.     Top := 198;
  1159.     Visible := False;
  1160.     Shape := stRoundRect;
  1161.   end;
  1162.   lblMoves := TLabel.Create(frmMain);
  1163.   with lblMoves do
  1164.   begin
  1165.     Parent := frmMain;
  1166.     Left := 18;
  1167.     Top := 199;
  1168.     Visible := False;
  1169.     Transparent := True;
  1170.   end;
  1171.   lblTargets := TLabel.Create(frmMain);
  1172.   with lblTargets do
  1173.   begin
  1174.     Parent := frmMain;
  1175.     Left := 240;
  1176.     Top := 199;
  1177.     Visible := False;
  1178.     Transparent := True;
  1179.   end;
  1180.   shpMenu := TShape.Create(frmMain);
  1181.   with shpMenu do
  1182.   begin
  1183.     Parent := frmMain;
  1184.     Left := 69;
  1185.     Top := 69;
  1186.     Width := 111;
  1187.     Height := 14;
  1188.     Visible := False;
  1189.     Shape := stRoundRect;
  1190.   end;
  1191.   lblMenu := TLabel.Create(frmMain);
  1192.   with lblMenu do
  1193.   begin
  1194.     Parent := frmMain;
  1195.     Left := 70;
  1196.     Top := 70;
  1197.     Visible := False;
  1198.     Transparent := True;
  1199.   end;
  1200.   lblInfo := TLabel.Create(frmMain);
  1201.   with lblInfo do
  1202.   begin
  1203.     Parent := frmMain;
  1204.     Left := 205;
  1205.     Top := 70;
  1206.     Visible := False;
  1207.     Transparent := True;
  1208.   end;
  1209.   tmrEngine := TTimer.Create(frmMain);
  1210.   with tmrEngine do
  1211.   begin
  1212.     Interval := 1000 div FPS;
  1213.     OnTimer := @Engine;
  1214.   end;
  1215.   OpenMap;
  1216.   frmMain.ShowModal;
  1217. end;
  1218.  
  1219. var
  1220.   v: TVariantArray;
  1221. begin
  1222.   tiles := LoadBitmap(ScriptPath + 'Tiles.bmp');
  1223.   sprites := LoadBitmap(ScriptPath + 'Sprites.bmp');
  1224.   RandomizeMap(1, 1, 1, 0, 1, 1, 1, 0);
  1225.   encCount := 15;
  1226.   ThreadSafeCall('SetupForm', v);
  1227.   FreeForm(frmMain);
  1228.   FreeBitmap(sprites);
  1229.   FreeBitmap(tiles);
  1230. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement