Subversion Repositories spacemission

Rev

Rev 28 | Rev 31 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. unit LevMain;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, MMSystem,
  7.   Dialogs, StdCtrls, ExtCtrls, Menus, DIB, DXClass, DXSprite, DXDraws,
  8.   DXSounds, Spin, ComCtrls{$IF CompilerVersion >= 23.0}, System.UITypes,
  9.   WinAPI.DirectDraw{$ENDIF}, DirectX, ComLevelReader;
  10.  
  11. type
  12.   TMainForm = class(TDXForm)
  13.     MainMenu: TMainMenu;
  14.     Spiel: TMenuItem;
  15.     Beenden: TMenuItem;
  16.     Hilfe: TMenuItem;
  17.     Leer1: TMenuItem;
  18.     Level: TMenuItem;
  19.     Informationen: TMenuItem;
  20.     Enemy1: TRadioButton;
  21.     Enemy2: TRadioButton;
  22.     Enemy3: TRadioButton;
  23.     Enemy4: TRadioButton;
  24.     Enemy5: TRadioButton;
  25.     Enemy6: TRadioButton;
  26.     Enemy7: TRadioButton;
  27.     ScrollBar: TScrollBar;
  28.     Bevel1: TBevel;
  29.     Bevel2: TBevel;
  30.     SelLabel: TLabel;
  31.     SelPanel: TPanel;
  32.     Bevel3: TBevel;
  33.     SLabel1a: TLabel;
  34.     SLabel2a: TLabel;
  35.     SLabel1b: TLabel;
  36.     SLabel2b: TLabel;
  37.     SLabel0: TLabel;
  38.     Neu: TMenuItem;
  39.     Image1: TImage;
  40.     SLabel3a: TLabel;
  41.     SLabel3b: TLabel;
  42.     SLabel4a: TLabel;
  43.     SLabel4b: TLabel;
  44.     LivesLabel: TLabel;
  45.     StatusBar: TStatusBar;
  46.     N1: TMenuItem;
  47.     Spielfelderweitern1: TMenuItem;
  48.     SidePanel: TPanel;
  49.     LivesEdit: TSpinEdit;
  50.     AlleLeveldateienaktualisieren1: TMenuItem;
  51.     procedure DXDrawFinalize(Sender: TObject);
  52.     procedure DXDrawInitialize(Sender: TObject);
  53.     procedure FormCreate(Sender: TObject);
  54.     procedure DXTimerTimer(Sender: TObject; LagCount: Integer);
  55.     procedure BeendenClick(Sender: TObject);
  56.     procedure FormDestroy(Sender: TObject);
  57.     procedure LevelClick(Sender: TObject);
  58.     procedure FormShow(Sender: TObject);
  59.     procedure InformationenClick(Sender: TObject);
  60.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  61.     procedure DXDrawMouseDown(Sender: TObject; Button: TMouseButton;
  62.       Shift: TShiftState; X, Y: Integer);
  63.     procedure EnemyClick(Sender: TObject);
  64.     procedure NeuClick(Sender: TObject);
  65.     procedure DXDrawMouseMove(Sender: TObject; Shift: TShiftState; X,
  66.       Y: Integer);
  67.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  68.     procedure Spielfelderweitern1Click(Sender: TObject);
  69.     procedure ScrollBarScroll(Sender: TObject; ScrollCode: TScrollCode;
  70.       var ScrollPos: Integer);
  71.     procedure AlleLeveldateienaktualisieren1Click(Sender: TObject);
  72.   public
  73.     { VCL-Ersatz }
  74.     spriteengine: tdxspriteengine;
  75.     dxtimer: tdxtimer;
  76.     imagelist: tdximagelist;
  77.     dxdraw: tdxdraw;
  78.     { Variablen }
  79.     FMenuItem: integer;
  80.     LevData: TLevelData;
  81.     ScrollP: integer;
  82.     AltScrollPos: integer;
  83.     Boss: boolean;
  84.     LevChanged: boolean;
  85.     NumEnemys: integer;
  86.     function SelectedEnemyType: TEnemyType;
  87.     { Level-Routinen }
  88.     procedure EnemyCreateSprite(x, y: integer; AEnemyType: TEnemyType; ALives: integer);
  89.     procedure DestroyLevel;
  90.     procedure RefreshFromLevData;
  91.     procedure AnzeigeAct;
  92.     { Initialisiations-Routinen }
  93.     procedure DXInit;
  94.     procedure ProgramInit;
  95.     { Farb-Routinen }
  96.     function ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
  97.     procedure PalleteAnim(Col: TRGBQuad; Time: Integer);
  98.   end;
  99.  
  100. var
  101.   MainForm: TMainForm;
  102.  
  103. implementation
  104.  
  105. uses
  106.   Global, LevSplash, LevSpeicherung, ComInfo, LevOptions;
  107.  
  108. const
  109.   RasterW = 48;
  110.   RasterH = 32;
  111.  
  112. {$R *.DFM}
  113.  
  114. type
  115.   TBackground = class(TBackgroundSprite)
  116.   strict protected
  117.     procedure DoMove(MoveCount: Integer); override;
  118.   end;
  119.  
  120.   TEnemy = class(TImageSprite)
  121.   strict private
  122.     FLives: integer;
  123.     FEnemyType: TEnemyType;
  124.     FXCor: integer;
  125.     FCorInit: boolean;
  126.   strict protected
  127.     procedure DoMove(MoveCount: Integer); override;
  128.   public
  129.     constructor Create(AParent: TSprite; AEnemyType: TEnemyType; ALives: Integer); reintroduce;
  130.   end;
  131.  
  132. { TBackground }
  133.  
  134. procedure TBackground.DoMove(MoveCount: Integer);
  135. begin
  136.   X := -(MainForm.ScrollP * RasterW);
  137. end;
  138.  
  139. { TEnemy }
  140.  
  141. procedure TEnemy.DoMove(MoveCount: Integer);
  142. begin
  143.   if not FCorInit then
  144.   begin
  145.     FXCor := trunc(x) + (MainForm.ScrollP * RasterW);
  146.     FCorInit := true;
  147.   end;
  148.   if MainForm.LevData.IndexOfEnemy(FXCor, integer(round(Y)), FEnemyType, FLives) = -1 then dead;
  149.   X := FXCor - (MainForm.ScrollP * RasterW);
  150. end;
  151.  
  152. constructor TEnemy.Create(AParent: TSprite; AEnemyType: TEnemyType; ALives: Integer);
  153. begin
  154.   inherited Create(AParent);
  155.   if AEnemyType = etEnemyAttacker then Image := MainForm.ImageList.Items.Find('Enemy-Attacker');
  156.   if AEnemyType = etEnemyAttacker2 then Image := MainForm.ImageList.Items.Find('Enemy-Attacker2');
  157.   if AEnemyType = etEnemyAttacker3 then Image := MainForm.ImageList.Items.Find('Enemy-Attacker3');
  158.   if AEnemyType = etEnemyMeteor then Image := MainForm.ImageList.Items.Find('Enemy-Meteor');
  159.   if AEnemyType = etEnemyUFO then Image := MainForm.ImageList.Items.Find('Enemy-Disk');
  160.   if AEnemyType = etEnemyUFO2 then Image := MainForm.ImageList.Items.Find('Enemy-Disk2');
  161.   if AEnemyType = etEnemyBoss then Image := MainForm.ImageList.Items.Find('Enemy-Boss');
  162.  
  163.   if AEnemyType = etEnemyMeteor then FLives := 0 else FLives := ALives;
  164.   FEnemyType := AEnemyType;
  165.   Width := Image.Width;
  166.   Height := Image.Height;
  167.   PixelCheck := True;
  168. end;
  169.  
  170. { TMainForm }
  171.  
  172. procedure TMainForm.DXInit;
  173. begin
  174.   Imagelist.Items.LoadFromFile(FDirectory+'DirectX\Graphic.dxg');
  175.   ImageList.Items.MakeColorTable;
  176.   DXDraw.ColorTable := ImageList.Items.ColorTable;
  177.   DXDraw.DefColorTable := ImageList.Items.ColorTable;
  178.   DXDraw.UpdatePalette;
  179.   DXDraw.Initialize;
  180. end;
  181.  
  182. procedure TMainForm.FormCreate(Sender: TObject);
  183. resourcestring
  184.   SFileError = 'Die Datei kann von SpaceMission nicht geöffnet werden!';
  185. begin
  186.   { VCL-Ersatz start }
  187.   dxtimer := tdxtimer.create(self);
  188.   dxtimer.Interval := 100;
  189.   dxtimer.ActiveOnly := false;
  190.   dxtimer.Enabled := false;
  191.   dxtimer.OnTimer := DxTimerTimer;
  192.  
  193.   dxdraw := tdxdraw.Create(self);
  194.   dxdraw.Parent := self;
  195.   dxdraw.Left := 0;
  196.   dxdraw.Top := 0;
  197.   dxdraw.Width := SidePanel.Left;
  198.   dxdraw.Height := ScrollBar.Top;
  199.   dxdraw.AutoInitialize := False;
  200.   dxdraw.AutoSize := False;
  201.   dxdraw.Color := clBlack;
  202.   (*
  203.   dxdraw.Display.BitCount := 24;
  204.   dxdraw.Display.FixedBitCount := False;
  205.   dxdraw.Display.FixedRatio := False;
  206.   dxdraw.Display.FixedSize := False;
  207.   dxdraw.Display.Height := 600;
  208.   dxdraw.Display.Width := 800;
  209.   *)
  210.   dxdraw.Options := [doAllowReboot, doWaitVBlank, doAllowPalette256, doCenter, {doRetainedMode,} doHardware, doSelectDriver];
  211.   dxdraw.OnFinalize := DXDrawFinalize;
  212.   dxdraw.OnInitialize := DXDrawInitialize;
  213.   dxdraw.ParentShowHint := False;
  214.   dxdraw.ShowHint := False;
  215.   dxdraw.TabOrder := 0;
  216.   dxdraw.OnMouseDown := DXDrawMouseDown;
  217.   dxdraw.OnMouseMove := DXDrawMouseMove;
  218.  
  219.   spriteengine := tdxspriteengine.create(self);
  220.   spriteengine.DXDraw := dxdraw;
  221.  
  222.   imagelist := tdximagelist.create(self);
  223.   imagelist.DXDraw := dxdraw;
  224.  
  225.   { VCL-Ersatz ende }
  226.  
  227.   Enemy1.Checked := true;
  228.   EnemyClick(Enemy1);
  229.   // Leeres Level am Anfang braucht keine Beenden-Bestätigung.
  230.   // LevChanged := true;
  231.  
  232.   //Application.Title := 'SpaceMission '+ProgramVersion+' - Leveleditor';
  233.   Caption := 'SpaceMission '+ProgramVersion+' - Leveleditor';
  234.   DXInit;
  235.   LevData := TLevelData.create;
  236.   ProgramInit;
  237.   DestroyLevel;
  238.   if (paramcount > 0) and (fileexists(paramstr(1))) then
  239.   begin
  240.     try
  241.       LevData.Load(paramstr(1));
  242.     except
  243.       on E: Exception do
  244.       begin
  245.         showmessage(SFileError + ' ' +E.Message);
  246.         DestroyLevel;
  247.       end;
  248.     end;
  249.     RefreshFromLevData;
  250.     LevChanged := false;
  251.     AnzeigeAct;
  252.   end;
  253. end;
  254.  
  255. procedure TMainForm.FormDestroy(Sender: TObject);
  256. begin
  257.   LevData.Free;
  258.   //spriteengine.Free;
  259.   dxtimer.Free;
  260.   imagelist.Free;
  261.   dxdraw.free;
  262. end;
  263.  
  264. procedure TMainForm.BeendenClick(Sender: TObject);
  265. begin
  266.   close;
  267. end;
  268.  
  269. procedure TMainForm.DXDrawInitialize(Sender: TObject);
  270. begin
  271.   DXTimer.Enabled := True;
  272. end;
  273.  
  274. procedure TMainForm.DXDrawFinalize(Sender: TObject);
  275. begin
  276.   DXTimer.Enabled := False;
  277. end;
  278.  
  279. procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
  280. begin
  281.   if not DXDraw.CanDraw then exit;
  282.   LagCount := 1000 div 60;
  283.   SpriteEngine.Move(LagCount);
  284.   SpriteEngine.Dead;
  285.   DxDraw.Surface.Fill(0);
  286.   SpriteEngine.Draw;
  287.   DXDraw.Flip;
  288. end;
  289.  
  290. function TMainForm.ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
  291. begin
  292.   with Result do
  293.   begin
  294.     rgbRed := Src.rgbRed+((Dest.rgbRed-Src.rgbRed)*Percent div 256);
  295.     rgbGreen := Src.rgbGreen+((Dest.rgbGreen-Src.rgbGreen)*Percent div 256);
  296.     rgbBlue := Src.rgbBlue+((Dest.rgbBlue-Src.rgbBlue)*Percent div 256);
  297.     rgbReserved := 0;
  298.   end;
  299. end;
  300.  
  301. procedure TMainForm.PalleteAnim(Col: TRGBQuad; Time: Integer);
  302. var
  303.   i: Integer;
  304.   t, t2: DWORD;
  305.   ChangePalette: Boolean;
  306.   c: Integer;
  307. begin
  308.   if DXDraw.Initialized then
  309.   begin
  310.     c := DXDraw.Surface.ColorMatch(RGB(Col.rgbRed, Col.rgbGreen, Col.rgbBlue));
  311.     ChangePalette := False;
  312.     if DXDraw.CanPaletteAnimation then
  313.     begin
  314.       t := GetTickCount;
  315.       while Abs(GetTickCount-t)<Time do
  316.       begin
  317.         t2 := Trunc(Abs(GetTickCount-t)/Time*255);
  318.         for i := 0 to 255 do
  319.           DXDraw.ColorTable[i] := ComposeColor(Col, DXDraw.DefColorTable[i], t2);
  320.         DXDraw.UpdatePalette;
  321.         ChangePalette := True;
  322.       end;
  323.     end else
  324.       Sleep(Time);
  325.     for i := 0 to 4 do
  326.     begin
  327.       DXDraw.Surface.Fill(c);
  328.       DXDraw.Flip;
  329.     end;
  330.     if ChangePalette then
  331.     begin
  332.       DXDraw.ColorTable := DXDraw.DefColorTable;
  333.       DXDraw.UpdatePalette;
  334.     end;
  335.     DXDraw.Surface.Fill(c);
  336.     DXDraw.Flip;
  337.   end;
  338. end;
  339.  
  340. procedure TMainForm.ProgramInit;
  341. {var
  342.   i, j: Integer;}
  343. begin
  344.   sleep(500);
  345.   //PlayerSprite
  346.   with TBackground.Create(SpriteEngine.Engine) do
  347.   begin
  348.     SetMapSize(1, 1);
  349.     Image := mainform.ImageList.Items.Find('Star3');
  350.     Z := -13;
  351.     Y := 40;
  352.     Tile := True;
  353.   end;
  354.   with TBackground.Create(SpriteEngine.Engine) do
  355.   begin
  356.     SetMapSize(1, 1);
  357.     Image := mainform.ImageList.Items.Find('Star2');
  358.     Z := -12;
  359.     Y := 30;
  360.     Tile := True;
  361.   end;
  362.   with TBackground.Create(SpriteEngine.Engine) do
  363.   begin
  364.     SetMapSize(1, 1);
  365.     Image := mainform.ImageList.Items.Find('Star1');
  366.     Z := -11;
  367.     Y := 10;
  368.     Tile := True;
  369.   end;
  370.   with TBackground.Create(SpriteEngine.Engine) do
  371.   begin
  372.     SetMapSize(1, 1);
  373.     Image := mainform.ImageList.Items.Find('Matrix');
  374.     Z := -10;
  375.     Tile := True;
  376.   end;
  377.   {with TBackground.Create(SpriteEngine.Engine) do
  378.   begin
  379.     SetMapSize(200, 10);
  380.     Y := 10;
  381.     Z := -13;
  382.     FSpeed := 1 / 2;
  383.     Tile := True;
  384.     for i := 0 to MapHeight-1 do
  385.     begin
  386.       for j := 0 to MapWidth-1 do
  387.       begin
  388.         Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 8);
  389.         if Random(100)<95 then Chips[j, i] := -1;
  390.       end;
  391.     end;
  392.   end;
  393.   with TBackground.Create(SpriteEngine.Engine) do
  394.   begin
  395.     SetMapSize(200, 10);
  396.     Y := 30;
  397.     Z := -12;
  398.     FSpeed := 1;
  399.     Tile := True;
  400.     for i := 0 to MapHeight-1 do
  401.     begin
  402.       for j := 0 to MapWidth-1 do
  403.       begin
  404.         Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 4);
  405.         if Random(100)<95 then Chips[j, i] := -1;
  406.       end;
  407.     end;
  408.   end;
  409.   with TBackground.Create(SpriteEngine.Engine) do
  410.   begin
  411.     SetMapSize(200, 10);
  412.     Y := 40;
  413.     Z := -11;
  414.     FSpeed := 2;
  415.     Tile := True;
  416.     for i := 0 to MapHeight-1 do
  417.     begin
  418.       for j := 0 to MapWidth-1 do
  419.       begin
  420.         Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 2);
  421.         if Random(100)<95 then Chips[j, i] := -1;
  422.       end;
  423.     end;
  424.   end;}
  425.   PalleteAnim(RGBQuad(0, 0, 0), 300);
  426.   mainform.Visible := true;
  427. end;
  428.  
  429. procedure TMainForm.RefreshFromLevData;
  430. var
  431.   i: integer;
  432. begin
  433.   MainForm.ScrollBar.Max := MainForm.LevData.LevelEditorLength;
  434.   for i := 0 to MainForm.LevData.CountEnemies - 1 do
  435.   begin
  436.     MainForm.EnemyCreateSprite(
  437.       MainForm.LevData.EnemyAdventTable[i].x,
  438.       MainForm.LevData.EnemyAdventTable[i].y,
  439.       MainForm.LevData.EnemyAdventTable[i].enemyType,
  440.       MainForm.LevData.EnemyAdventTable[i].lifes
  441.     );
  442.   end;
  443.   MainForm.NumEnemys := MainForm.LevData.CountEnemies;
  444.   MainForm.Boss := MainForm.LevData.HasBoss;
  445.   AnzeigeAct;
  446. end;
  447.  
  448. procedure TMainForm.LevelClick(Sender: TObject);
  449. begin
  450.   speicherungform.showmodal;
  451. end;
  452.  
  453. procedure TMainForm.FormShow(Sender: TObject);
  454. begin
  455.   SplashForm.Hide;
  456.   SplashForm.Free;
  457.  
  458.   dxtimer.Enabled := true;
  459.   dxtimer.ActiveOnly := true;
  460. end;
  461.  
  462. procedure TMainForm.InformationenClick(Sender: TObject);
  463. begin
  464.   mainform.dxtimer.enabled := false;
  465.   InfoForm.showmodal;
  466.   mainform.dxtimer.enabled := true;
  467. end;
  468.  
  469. procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
  470. begin
  471.   SpriteEngine.Engine.Clear;
  472.   DXTimer.Enabled := False;
  473. end;
  474.  
  475. procedure TMainForm.DXDrawMouseDown(Sender: TObject; Button: TMouseButton;
  476.   Shift: TShiftState; X, Y: Integer);
  477. var
  478.   i, j, k, l, ex, ey: integer;
  479.   ok, breaked: boolean;
  480. begin
  481.   ex := trunc(x/RasterW) * RasterW;
  482.   ey := trunc(y/RasterH) * RasterH;
  483.   EnemyCreateSprite(ex, ey, SelectedEnemyType, LivesEdit.Value);
  484.   breaked := false;
  485.   { Setzen }
  486.   if Button = mbLeft then
  487.   begin
  488.     ok := true;
  489.     if (SelectedEnemyType = etEnemyBoss) and boss then
  490.       ok := false // boss already exists
  491.     else
  492.     begin
  493.       for i := 1 to NumEnemyTypes do
  494.       begin
  495.         for j := 0 to 999 do
  496.         begin
  497.           if boss then
  498.           begin
  499.             for k := 0 to 3 do
  500.             begin
  501.               for l := 0 to 1 do
  502.               begin
  503.                 if LevData.IndexOfEnemy(ex + ((ScrollP - k) * RasterW), ey - (RasterH * l), etEnemyBoss, j) <> -1 then
  504.                 begin
  505.                   ok := false;
  506.                   break;
  507.                 end;
  508.               end;
  509.               if not ok then break;
  510.             end;
  511.             if not ok then break;
  512.           end;
  513.           if LevData.IndexOfEnemy(ex + (ScrollP * RasterW), ey, TEnemyType(i), j) <> -1 then
  514.           begin
  515.             ok := false;
  516.             break;
  517.           end;
  518.         end;
  519.         if not ok then break;
  520.       end;
  521.     end;
  522.     if ok then
  523.     begin
  524.       if SelectedEnemyType <> etEnemyMeteor then
  525.         LevData.AddEnemy(ex + (ScrollP * RasterW), ey, SelectedEnemyType, LivesEdit.Value)
  526.       else
  527.         LevData.AddEnemy(ex + (ScrollP * RasterW), ey, SelectedEnemyType, 0);
  528.       inc(NumEnemys);
  529.       if SelectedEnemyType = etEnemyBoss then boss := true;
  530.     end
  531.     else beep;
  532.   end
  533.   { Löschen }
  534.   else if Button = mbRight then
  535.   begin
  536.     for i := 1 to NumEnemyTypes do
  537.     begin
  538.       for j := 0 to 999 do
  539.       begin
  540.         if boss and (TEnemyType(i) = etEnemyBoss) then
  541.         begin
  542.           for k := 0 to 3 do
  543.           begin
  544.             for l := 0 to 1 do
  545.             begin
  546.               if LevData.IndexOfEnemy(ex + ((ScrollP - k) * RasterW), ey - (RasterH * l), TEnemyType(i), j) <> -1 then
  547.               begin
  548.                 LevData.DeleteEnemy(ex + ((ScrollP - k) * RasterW), ey - (RasterH * l), TEnemyType(i), j);
  549.                 Boss := false;
  550.                 dec(NumEnemys);
  551.                 breaked := true;
  552.                 break;
  553.               end;
  554.             end;
  555.             if breaked then break;
  556.           end;
  557.         end;
  558.         if LevData.IndexOfEnemy(ex + (ScrollP * RasterW), ey, TEnemyType(i), j) <> -1 then
  559.         begin
  560.           LevData.DeleteEnemy(ex + (ScrollP * RasterW), ey, TEnemyType(i), j);
  561.           if TEnemyType(i) = etEnemyBoss then Boss := false;
  562.           dec(NumEnemys);
  563.           breaked := true;
  564.           break;
  565.         end;
  566.       end;
  567.       if breaked then break;
  568.     end;
  569.   end;
  570.   LevChanged := true;
  571.   AnzeigeAct;
  572. end;
  573.  
  574. procedure TMainForm.EnemyClick(Sender: TObject);
  575. var
  576.   et: TEnemyType;
  577. begin
  578.   et := SelectedEnemyType;
  579.   Image1.Left := -(87 * (Ord(et) - 1)) + 1;
  580.   LivesEdit.Enabled := et <> etEnemyMeteor;
  581.   LivesLabel.Enabled := et <> etEnemyMeteor;
  582. end;
  583.  
  584. procedure TMainForm.EnemyCreateSprite(x, y: integer; AEnemyType: TEnemyType; ALives: integer);
  585. var
  586.   Enemy: TSprite;
  587. begin
  588.   Enemy := TEnemy.Create(SpriteEngine.Engine, AEnemyType, ALives);
  589.   Enemy.x := x;
  590.   Enemy.y := y;
  591. end;
  592.  
  593. procedure TMainForm.DestroyLevel;
  594. begin
  595.   ScrollBar.Position := 0; // this doesn't call ScrollBarScroll()
  596.   ScrollP := 0;
  597.   LevData.Clear;
  598.   ScrollBar.Max := LevData.LevelEditorLength;
  599.   NumEnemys := 0;
  600.   Boss := false;
  601.   LevChanged := true;
  602.   LivesEdit.Value := 1;
  603.   Enemy1.Checked := true;
  604.   EnemyClick(Enemy1);
  605.   AnzeigeAct;
  606. end;
  607.  
  608. procedure TMainForm.AlleLeveldateienaktualisieren1Click(Sender: TObject);
  609. var
  610.   i: integer;
  611. begin
  612.   // Just for internal/development purposes
  613.   for i := 1 to 9999 do
  614.   begin
  615.     if FileExists('Levels\Level '+IntToStr(i)+'.lev') then
  616.     begin
  617.       LevData.Load('Levels\Level '+IntToStr(i)+'.lev');
  618.       LevData.Save('Levels\Level '+IntToStr(i)+'.lev');
  619.     end;
  620.   end;
  621. end;
  622.  
  623. procedure TMainForm.AnzeigeAct;
  624. begin
  625.   SLabel1b.Caption := inttostr(NumEnemys);
  626.   if Boss then SLabel2b.Caption := 'Ja' else SLabel2b.Caption := 'Nein';
  627.   SLabel3b.Caption := inttostr(ScrollBar.Max);
  628.   if LevChanged then
  629.   begin
  630.     SLabel4a.Font.Color := $00000096;
  631.     SLabel4b.Font.Color := $00000096;
  632.     SLabel4b.Caption := 'Nein';
  633.   end
  634.   else
  635.   begin
  636.     SLabel4a.Font.Color := $00009600;
  637.     SLabel4b.Font.Color := $00009600;
  638.     SLabel4b.Caption := 'Ja';
  639.   end;
  640. end;
  641.  
  642. procedure TMainForm.NeuClick(Sender: TObject);
  643. begin
  644.   if MessageDlg('Level wirklich löschen?', mtConfirmation, mbYesNoCancel, 0) = mrYes then
  645.     DestroyLevel;
  646. end;
  647.  
  648. procedure TMainForm.DXDrawMouseMove(Sender: TObject; Shift: TShiftState; X,
  649.   Y: Integer);
  650. resourcestring
  651.   status_info = 'Zeigen Sie mit dem Mauszeiger auf eine Einheit, um deren Eigenschaften anzuzeigen...';
  652.   status_lives = 'Leben: ';
  653.   status_nolives = 'Einheit hat keine Lebensangabe';
  654. var
  655.   ex, ey, i, j, k, l: integer;
  656.   lifes: integer;
  657.   enemyType: TEnemyType;
  658.   enemyName: string;
  659.   breaked: boolean;
  660. begin
  661.   if sender <> DxDraw then
  662.   begin
  663.     StatusBar.SimpleText := ' ' + status_info;
  664.     exit;
  665.   end;
  666.   ex := trunc(x/RasterW) * RasterW;
  667.   ey := trunc(y/RasterH) * RasterH;
  668.   lifes := -1;
  669.   enemyType := etUnknown;
  670.   breaked := false;
  671.   for i := 1 to NumEnemyTypes do
  672.   begin
  673.     for j := 0 to 999 do
  674.     begin
  675.       if boss and (TEnemyType(i) = etEnemyBoss) then
  676.       begin
  677.         for k := 0 to 3 do
  678.         begin
  679.           for l := 0 to 1 do
  680.           begin
  681.             if LevData.IndexOfEnemy(ex + ((ScrollP - k) * RasterW), ey - (RasterH * l), TEnemyType(i), j) <> -1 then
  682.             begin
  683.               lifes := j;
  684.               breaked := true;
  685.               break;
  686.             end;
  687.           end;
  688.           if breaked then break;
  689.         end;
  690.       end;
  691.       if (breaked = false) and (LevData.IndexOfEnemy(ex + (ScrollP * RasterW), ey, TEnemyType(i), j) <> -1) then
  692.       begin
  693.         lifes := j;
  694.         enemyType := TEnemyType(i);
  695.         breaked := true;
  696.         break;
  697.       end;
  698.     end;
  699.     if breaked then break;
  700.   end;
  701.   if lifes <> -1 then
  702.   begin
  703.     if Ord(enemyType) = 1 then enemyName := Enemy1.Caption
  704.     else if Ord(enemyType) = 2 then enemyName := Enemy2.Caption
  705.     else if Ord(enemyType) = 3 then enemyName := Enemy3.Caption
  706.     else if Ord(enemyType) = 4 then enemyName := Enemy4.Caption
  707.     else if Ord(enemyType) = 5 then enemyName := Enemy5.Caption
  708.     else if Ord(enemyType) = 6 then enemyName := Enemy6.Caption
  709.     else if Ord(enemyType) = 7 then enemyName := Enemy7.Caption
  710.     else enemyName := '???';
  711.     if lifes > 0 then
  712.       StatusBar.SimpleText := ' ' + enemyName + ' - ' + status_lives + inttostr(lifes)
  713.     else
  714.       StatusBar.SimpleText := ' ' + enemyName + ' - ' + status_nolives;
  715.   end
  716.   else
  717.     StatusBar.SimpleText := ' ' + status_info;
  718. end;
  719.  
  720. procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  721. begin
  722.   if Assigned(LevData) and LevChanged and (LevData.CountEnemies>0) then
  723.     CanClose := MessageDlg('Beenden ohne abspeichern?', mtConfirmation, mbYesNoCancel, 0) = mrYes;
  724. end;
  725.  
  726. procedure TMainForm.Spielfelderweitern1Click(Sender: TObject);
  727. begin
  728.   LevelForm.Aktualisieren;
  729.   LevelForm.showmodal;
  730. end;
  731.  
  732. procedure TMainForm.ScrollBarScroll(Sender: TObject;
  733.   ScrollCode: TScrollCode; var ScrollPos: Integer);
  734. begin
  735.   ScrollP := ScrollPos;
  736. end;
  737.  
  738. function TMainForm.SelectedEnemyType: TEnemyType;
  739. begin
  740.   if Enemy1.Checked then result := etEnemyAttacker
  741.   else if Enemy2.Checked then result := etEnemyAttacker2
  742.   else if Enemy3.Checked then result := etEnemyAttacker3
  743.   else if Enemy4.Checked then result := etEnemyMeteor
  744.   else if Enemy5.Checked then result := etEnemyUFO
  745.   else if Enemy6.Checked then result := etEnemyUFO2
  746.   else if Enemy7.Checked then result := etEnemyBoss
  747.   else result := etUnknown;
  748. end;
  749.  
  750. end.
  751.  
  752.