Subversion Repositories spacemission

Rev

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