Subversion Repositories spacemission

Rev

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

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