Subversion Repositories spacemission

Rev

Rev 44 | Rev 63 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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