Subversion Repositories spacemission

Compare Revisions

Regard whitespace Rev 1 → Rev HEAD

/LevMain.pas
5,7 → 5,8
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, MMSystem,
Dialogs, StdCtrls, ExtCtrls, Menus, DIB, DXClass, DXSprite, DXDraws,
DXSounds, Spin, ComCtrls, PjVersionInfo;
DXSounds, Spin, ComCtrls{$IF CompilerVersion >= 23.0}, System.UITypes,
WinAPI.DirectDraw{$ENDIF}, DirectX, ComLevelReader, Global, IOUtils;
 
type
TMainForm = class(TDXForm)
13,11 → 14,9
Spiel: TMenuItem;
Beenden: TMenuItem;
Hilfe: TMenuItem;
Mitarbeiter: TMenuItem;
Leer1: TMenuItem;
Level: TMenuItem;
Informationen: TMenuItem;
Leer2: TMenuItem;
Enemy1: TRadioButton;
Enemy2: TRadioButton;
Enemy3: TRadioButton;
43,12 → 42,20
SLabel4a: TLabel;
SLabel4b: TLabel;
LivesLabel: TLabel;
Quelltext1: TMenuItem;
StatusBar: TStatusBar;
N1: TMenuItem;
Spielfelderweitern1: TMenuItem;
LivesEdt: TEdit;
Lives: TUpDown;
SidePanel: TPanel;
LivesEdit: TSpinEdit;
AlleLeveldateienaktualisieren1: TMenuItem;
N2: TMenuItem;
Leveltesten1: TMenuItem;
Hilfe1: TMenuItem;
N3: TMenuItem;
AufUpdatesprfen1: TMenuItem;
N4: TMenuItem;
WasgibtesNeues1: TMenuItem;
Enemy8: TRadioButton;
procedure DXDrawFinalize(Sender: TObject);
procedure DXDrawInitialize(Sender: TObject);
procedure FormCreate(Sender: TObject);
55,7 → 62,6
procedure DXTimerTimer(Sender: TObject; LagCount: Integer);
procedure BeendenClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure MitarbeiterClick(Sender: TObject);
procedure LevelClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure InformationenClick(Sender: TObject);
63,40 → 69,40
procedure DXDrawMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure EnemyClick(Sender: TObject);
procedure EnemyAdd(x, y, art, lives: integer);
procedure NeuClick(Sender: TObject);
procedure DXDrawMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure Quelltext1Click(Sender: TObject);
procedure Spielfelderweitern1Click(Sender: TObject);
procedure ScrollBarScroll(Sender: TObject; ScrollCode: TScrollCode;
var ScrollPos: Integer);
procedure LivesClick(Sender: TObject; Button: TUDBtnType);
procedure LivesEdtKeyPress(Sender: TObject; var Key: Char);
procedure LivesEdtChange(Sender: TObject);
procedure AlleLeveldateienaktualisieren1Click(Sender: TObject);
procedure Leveltesten1Click(Sender: TObject);
procedure HilfeTopicClick(Sender: TObject);
procedure AufUpdatesprfen1Click(Sender: TObject);
private
function GetTestlevelFilename: string;
public
{ VCL-Ersatz }
spriteengine: tdxspriteengine;
versioninfo: tpjversioninfo;
dxtimer: tdxtimer;
imagelist: tdximagelist;
dxdraw: tdxdraw;
{ Variablen }
FDirectory: string;
FEngineVersion: string;
FMenuItem: integer;
Enemys: TStrings;
ArtChecked: integer;
LiveEdit: integer;
LevData: TLevelData;
ScrollP: integer;
AltScrollPos: integer;
Boss: boolean;
LevChanged: boolean;
NumEnemys: integer;
function SelectedEnemyType: TEnemyType;
{ Grafik-Routinen }
function GetSpriteGraphic(Sprite: TSpaceMissionGraphicSprite): TPictureCollectionItem;
{ Level-Routinen }
procedure EnemyCreate(x, y: integer);
procedure EnemyCreateSprite(x, y: integer; AEnemyType: TEnemyType; ALives: integer);
procedure DestroyLevel;
procedure RefreshFromLevData;
procedure AnzeigeAct;
{ Initialisiations-Routinen }
procedure DXInit;
104,107 → 110,99
{ Farb-Routinen }
function ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
procedure PalleteAnim(Col: TRGBQuad; Time: Integer);
{ Sonstiges }
procedure LivesChange(newval: integer);
end;
 
var
MainForm: TMainForm;
 
const
FCompVersion = '1.0';
 
implementation
 
uses
LevSplash, LevSpeicherung, LevText, LevInfo, LevSource, LevOptions;
LevSplash, LevSpeicherung, ComInfo, LevOptions, ShellAPI, ComHilfe;
 
const
FileError = 'Die Datei kann von SpaceMission nicht geöffnet werden!';
status_info = ' Zeigen Sie mit dem Mauszeiger auf eine Einheit, um deren Eigenschaften anzuzeigen...';
status_lives = ' Leben: ';
status_nolives = ' Einheit hat keine Lebensangabe';
RasterW = 48;
RasterH = 32;
 
{$R *.DFM}
 
{$R WindowsXP.res}
resourcestring
status_info = 'Zeigen Sie mit dem Mauszeiger auf eine Einheit, um deren Eigenschaften anzuzeigen...';
 
type
TBackground = class(TBackgroundSprite)
protected
strict protected
procedure DoMove(MoveCount: Integer); override;
end;
 
TEnemy = class(TImageSprite)
private
Lives: integer;
Art: integer;
XCor: integer;
CorInit: boolean;
protected
TEnemyOrItem = class(TImageSprite)
strict private
FLives: integer;
FEnemyType: TEnemyType;
FXCor: integer;
FCorInit: boolean;
strict protected
procedure DoMove(MoveCount: Integer); override;
public
constructor Create(AParent: TSprite); override;
constructor Create(AParent: TSprite; AEnemyType: TEnemyType; ALives: Integer); reintroduce;
end;
 
procedure TMainForm.DXInit;
{ TBackground }
 
procedure TBackground.DoMove(MoveCount: Integer);
begin
Imagelist.Items.LoadFromFile(FDirectory+'DirectX\Graphic.dxg');
ImageList.Items.MakeColorTable;
DXDraw.ColorTable := ImageList.Items.ColorTable;
DXDraw.DefColorTable := ImageList.Items.ColorTable;
DXDraw.UpdatePalette;
DXDraw.Initialize;
X := -(MainForm.ScrollP * LevEditRasterW);
end;
 
procedure TEnemy.DoMove(MoveCount: Integer);
{ TEnemy }
 
procedure TEnemyOrItem.DoMove(MoveCount: Integer);
begin
if not CorInit then
if not FCorInit then
begin
XCor := trunc(x) + (MainForm.ScrollP * RasterW);
CorInit := true;
FXCor := trunc(x) + (MainForm.ScrollP * LevEditRasterW);
FCorInit := true;
end;
if MainForm.Enemys.IndexOf(floattostr(XCor)+'-'+floattostr(y)+':'+
inttostr(Art)+'('+inttostr(Lives)+')') = -1 then dead;
X := XCor - (MainForm.ScrollP * RasterW);
if MainForm.LevData.IndexOfEnemy(FXCor, integer(round(Y)), FEnemyType, FLives) = -1 then dead;
X := FXCor - (MainForm.ScrollP * LevEditRasterW);
end;
 
procedure TBackground.DoMove(MoveCount: Integer);
constructor TEnemyOrItem.Create(AParent: TSprite; AEnemyType: TEnemyType; ALives: Integer);
begin
X := -(MainForm.ScrollP * RasterW);
end;
inherited Create(AParent);
if AEnemyType = etEnemyAttacker then Image := MainForm.GetSpriteGraphic(smgEnemyAttacker);
if AEnemyType = etEnemyAttacker2 then Image := MainForm.GetSpriteGraphic(smgEnemyAttacker2);
if AEnemyType = etEnemyAttacker3 then Image := MainForm.GetSpriteGraphic(smgEnemyAttacker3);
if AEnemyType = etEnemyMeteor then Image := MainForm.GetSpriteGraphic(smgEnemyMeteor);
if AEnemyType = etEnemyUFO then Image := MainForm.GetSpriteGraphic(smgEnemyDisk);
if AEnemyType = etEnemyUFO2 then Image := MainForm.GetSpriteGraphic(smgEnemyDisk2);
if AEnemyType = etEnemyBoss then Image := MainForm.GetSpriteGraphic(smgEnemyBoss);
if AEnemyType = etItemMedikit then Image := MainForm.GetSpriteGraphic(smgItemMedikit);
 
constructor TEnemy.Create(AParent: TSprite);
begin
inherited Create(AParent);
if MainForm.ArtChecked = 1 then Image := MainForm.ImageList.Items.Find('Enemy-Attacker');
if MainForm.ArtChecked = 2 then Image := MainForm.ImageList.Items.Find('Enemy-Attacker2');
if MainForm.ArtChecked = 3 then Image := MainForm.ImageList.Items.Find('Enemy-Attacker3');
if MainForm.ArtChecked = 4 then Image := MainForm.ImageList.Items.Find('Enemy-Meteor');
if MainForm.ArtChecked = 5 then Image := MainForm.ImageList.Items.Find('Enemy-Disk');
if MainForm.ArtChecked = 6 then Image := MainForm.ImageList.Items.Find('Enemy-Disk2');
if MainForm.ArtChecked = 7 then Image := MainForm.ImageList.Items.Find('Enemy-Boss');
if MainForm.ArtChecked = 4 then Lives := 0 else Lives := MainForm.LiveEdit;
Art := MainForm.ArtChecked;
if not EnemyTypeHasLives(AEnemyType) then
FLives := 0
else
FLives := ALives;
FEnemyType := AEnemyType;
Width := Image.Width;
Height := Image.Height;
PixelCheck := True;
end;
 
{ TMainForm }
 
procedure TMainForm.DXInit;
begin
Imagelist.Items.LoadFromFile(OwnDirectory+DxgFile);
ImageList.Items.MakeColorTable;
DXDraw.ColorTable := ImageList.Items.ColorTable;
DXDraw.DefColorTable := ImageList.Items.ColorTable;
DXDraw.UpdatePalette;
DXDraw.Initialize;
end;
 
procedure TMainForm.FormCreate(Sender: TObject);
var
Ergebnis: string;
daten: textfile;
i: integer;
punkt: integer;
ok: boolean;
resourcestring
SFileError = 'Die Datei kann von SpaceMission nicht geöffnet werden!';
SCaption = 'SpaceMission %s - Level-Editor';
begin
{ VCL-Ersatz start }
 
versioninfo := tpjversioninfo.create(self);
 
dxtimer := tdxtimer.create(self);
dxtimer.Interval := 100;
dxtimer.ActiveOnly := false;
215,11 → 213,12
dxdraw.Parent := self;
dxdraw.Left := 0;
dxdraw.Top := 0;
dxdraw.Width := 640;
dxdraw.Height := 480;
dxdraw.Width := SidePanel.Left;
dxdraw.Height := ScrollBar.Top;
dxdraw.AutoInitialize := False;
dxdraw.AutoSize := False;
dxdraw.Color := clBlack;
(*
dxdraw.Display.BitCount := 24;
dxdraw.Display.FixedBitCount := False;
dxdraw.Display.FixedRatio := False;
226,7 → 225,8
dxdraw.Display.FixedSize := False;
dxdraw.Display.Height := 600;
dxdraw.Display.Width := 800;
dxdraw.Options := [doAllowReboot, doWaitVBlank, doAllowPalette256, doCenter, doRetainedMode, doHardware, doSelectDriver];
*)
dxdraw.Options := [doAllowReboot, doWaitVBlank, doAllowPalette256, doCenter, {doRetainedMode,} doHardware, doSelectDriver];
dxdraw.OnFinalize := DXDrawFinalize;
dxdraw.OnInitialize := DXDrawInitialize;
dxdraw.ParentShowHint := False;
243,57 → 243,54
 
{ VCL-Ersatz ende }
 
ArtChecked := 1;
LiveEdit := 1;
StatusBar.SimpleText := ' ' + status_info;
 
LivesEdit.MinValue := 1;
LivesEdit.MaxValue := MaxPossibleEnemyLives;
LivesEdit.Value := 1;
 
Enemy1.Checked := true;
EnemyClick(Enemy1);
// Leeres Level am Anfang braucht keine Beenden-Bestätigung.
// LevChanged := true;
punkt := 0;
FDirectory := extractfilepath(paramstr(0));
versioninfo.filename := paramstr(0);
for i := 1 to length(versioninfo.ProductVersion) do
begin
if copy(versioninfo.ProductVersion, i, 1) = '.' then inc(punkt);
if punkt < 2 then fengineversion :=
fengineversion+copy(versioninfo.ProductVersion, i, 1);
end;
//Application.Title := 'SpaceMission '+FEngineVersion+' - Leveleditor';
Caption := 'SpaceMission '+FEngineVersion+' - Leveleditor';
 
//Application.Title := Format(SCaption, [ProgramVersion]);
Caption := Format(SCaption, [ProgramVersion]);
DXInit;
if (paramcount > 0) and (fileexists(paramstr(1))) then
LevData := TLevelData.create;
ProgramInit;
DestroyLevel;
if (paramcount > 0) and (fileexists(paramstr(1))) and (ExtractFileExt(paramstr(1)).ToLower = '.lev') then
begin
AssignFile(daten, paramstr(1));
Reset(daten);
ok := true;
ReadLN(daten, Ergebnis);
if Ergebnis <> '; SpaceMission '+FCompVersion then ok := false;
ReadLN(daten, Ergebnis);
if ergebnis <> '; LEV-File' then ok := false;
if not ok then
try
LevData.RasterErzwingen := true;
LevData.LoadFromFile(paramstr(1));
except
on E: Exception do
begin
showmessage(FileError);
CloseFile(daten);
ProgramInit;
exit;
showmessage(SFileError + ' ' +E.Message);
DestroyLevel;
end;
{ Laden }
CloseFile(daten);
exit;
end;
if fileexists(fdirectory+'Bilder\Auswahl.bmp') then
Image1.Picture.LoadFromFile(fdirectory+'Bilder\Auswahl.bmp');
{else
SelPanel.visible := false;}
ProgramInit;
RefreshFromLevData;
LevChanged := false;
AnzeigeAct;
end;
end;
 
procedure TMainForm.FormDestroy(Sender: TObject);
var
tmp: string;
begin
Enemys.Free;
//spriteengine.Free;
versioninfo.free;
dxtimer.Free;
imagelist.Free;
dxdraw.free;
FreeAndNil(dxdraw);
FreeAndNil(LevData);
//FreeAndNil(spriteengine);
FreeAndNil(dxtimer);
FreeAndNil(imagelist);
tmp := GetTestlevelFilename;
 
// SpaceMission.exe only loads a file once, so we can delete any test level
if FileExists(tmp) then DeleteFile(GetTestlevelFilename);
end;
 
procedure TMainForm.BeendenClick(Sender: TObject);
303,12 → 300,12
 
procedure TMainForm.DXDrawInitialize(Sender: TObject);
begin
DXTimer.Enabled := True;
if Assigned(DXTimer) then DXTimer.Enabled := True;
end;
 
procedure TMainForm.DXDrawFinalize(Sender: TObject);
begin
DXTimer.Enabled := False;
if Assigned(DXTimer) then DXTimer.Enabled := False;
end;
 
procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
376,13 → 373,12
{var
i, j: Integer;}
begin
Enemys := TStringList.create;
sleep(500);
//PlayerSprite
with TBackground.Create(SpriteEngine.Engine) do
begin
SetMapSize(1, 1);
Image := mainform.ImageList.Items.Find('Star3');
Image := MainForm.GetSpriteGraphic(smgStar3);
Z := -13;
Y := 40;
Tile := True;
390,7 → 386,7
with TBackground.Create(SpriteEngine.Engine) do
begin
SetMapSize(1, 1);
Image := mainform.ImageList.Items.Find('Star2');
Image := MainForm.GetSpriteGraphic(smgStar2);
Z := -12;
Y := 30;
Tile := True;
398,7 → 394,7
with TBackground.Create(SpriteEngine.Engine) do
begin
SetMapSize(1, 1);
Image := mainform.ImageList.Items.Find('Star1');
Image := MainForm.GetSpriteGraphic(smgStar1);
Z := -11;
Y := 10;
Tile := True;
406,7 → 402,7
with TBackground.Create(SpriteEngine.Engine) do
begin
SetMapSize(1, 1);
Image := mainform.ImageList.Items.Find('Matrix');
Image := MainForm.GetSpriteGraphic(smgMatrix);
Z := -10;
Tile := True;
end;
462,18 → 458,23
mainform.Visible := true;
end;
 
procedure TMainForm.MitarbeiterClick(Sender: TObject);
procedure TMainForm.RefreshFromLevData;
var
i: integer;
begin
if not fileexists(mainform.fdirectory+'Texte\Mitwirkende.txt') then
MainForm.ScrollBar.Max := MainForm.LevData.LevelEditorLength;
for i := 0 to MainForm.LevData.CountEnemies - 1 do
begin
MessageDLG('Die Datei "Texte\Mitwirkende.txt" ist nicht mehr vorhanden. Die Aktion wird abgebrochen!',
mtWarning, [mbOK], 0);
end
else
begin
TextForm.memo1.lines.loadfromfile(mainform.FDirectory+'Texte\Mitwirkende.txt');
TextForm.showmodal;
MainForm.EnemyCreateSprite(
MainForm.LevData.EnemyAdventTable[i].x,
MainForm.LevData.EnemyAdventTable[i].y,
MainForm.LevData.EnemyAdventTable[i].enemyType,
MainForm.LevData.EnemyAdventTable[i].lifes
);
end;
MainForm.NumEnemys := MainForm.LevData.CountEnemies;
MainForm.Boss := MainForm.LevData.HasBoss;
AnzeigeAct;
end;
 
procedure TMainForm.LevelClick(Sender: TObject);
481,18 → 482,82
speicherungform.showmodal;
end;
 
procedure TMainForm.Leveltesten1Click(Sender: TObject);
var
sav: TSaveData;
tmp: string;
begin
KillTask(SpaceMissionExe);
 
sav := TSaveData.Create;
try
sav.Score := 0;
sav.Life := 6;
if Assigned(SpeicherungForm) then
sav.Level := SpeicherungForm.LevelNumber.Value
else
sav.Level := 1;
sav.GameMode := gmLevels;
sav.LevelData := TlevelData.Create;
sav.LevelData.Assign(LevData);
tmp := GetTestlevelFilename;
sav.SaveToFile(tmp);
ShellExecute(Handle, 'open', PChar(OwnDirectory+SpaceMissionExe), PChar('"'+tmp+'"'), PChar(OwnDirectory), SW_NORMAL); // do not localize
finally
FreeAndNil(sav);
end;
end;
 
procedure TMainForm.FormShow(Sender: TObject);
begin
if Assigned(SplashForm) then
begin
SplashForm.Hide;
SplashForm.Free;
FreeAndNil(SplashForm);
end;
 
dxtimer.Enabled := true;
dxtimer.ActiveOnly := true;
end;
 
function TMainForm.GetSpriteGraphic(
Sprite: TSpaceMissionGraphicSprite): TPictureCollectionItem;
begin
if (Sprite<>smgNone) and (imagelist.Items.Count >= Ord(Sprite)) then
result := imagelist.Items.Items[Ord(Sprite)-1]
else
result := nil;
end;
 
function TMainForm.GetTestlevelFilename: string;
begin
result := IncludeTrailingPathDelimiter(TPath.GetTempPath) + 'SpaceMissionTest.sav'; // do not localize
end;
 
procedure TMainForm.HilfeTopicClick(Sender: TObject);
// Please keep this code in-sync with GamMain.pas
var
bakTimerEnabled: boolean;
begin
bakTimerEnabled := dxtimer.Enabled;
try
dxtimer.Enabled := false;
HilfeForm.Caption := TMenuItem(Sender).Caption;
HilfeForm.Caption := StringReplace(HilfeForm.Caption, '&&', #1, [rfReplaceAll]);
HilfeForm.Caption := StringReplace(HilfeForm.Caption, '&', '', [rfReplaceAll]);
HilfeForm.Caption := StringReplace(HilfeForm.Caption, #1, '&', [rfReplaceAll]);
HilfeForm.ShowMarkDownHelp(OwnDirectory+TMenuItem(Sender).Hint);
HilfeForm.ShowModal;
finally
dxtimer.Enabled := bakTimerEnabled;
end;
end;
 
procedure TMainForm.InformationenClick(Sender: TObject);
begin
mainform.dxtimer.enabled := false;
InfoForm.showmodal;
mainform.dxtimer.enabled := true;
end;
 
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
504,31 → 569,33
procedure TMainForm.DXDrawMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
i, j, k, l, ex, ey: integer;
i: TEnemyType;
j, k, l, ex, ey: integer;
ok, breaked: boolean;
begin
ex := trunc(x/RasterW) * RasterW;
ey := trunc(y/RasterH) * RasterH;
EnemyCreate(ex, ey);
ex := trunc(x/LevEditRasterW) * LevEditRasterW;
ey := trunc(y/LevEditRasterH) * LevEditRasterH;
EnemyCreateSprite(ex, ey, SelectedEnemyType, LivesEdit.Value);
breaked := false;
{ Setzen }
if Button = mbLeft then
begin
ok := true;
if (ArtChecked = 7) and boss then ok := false
if (SelectedEnemyType = etEnemyBoss) and boss then
ok := false // boss already exists
else
begin
for i := 1 to 7 do
for i := Low(TEnemyType) to High(TEnemyType) do
begin
for j := 0 to 999 do
for j := 0 to MaxPossibleEnemyLives do
begin
if boss then
begin
for k := 0 to 3 do
for k := 0 to BossWidth-1 do
begin
for l := 0 to 1 do
for l := 0 to BossHeight-2 do
begin
if Enemys.IndexOf(floattostr(ex + ((ScrollP - k) * RasterW))+'-'+floattostr(ey - (RasterH * l))+':7('+inttostr(j)+')') <> -1 then
if LevData.IndexOfEnemy(ex + ((ScrollP - k) * LevEditRasterW), ey - (LevEditRasterH * l), etEnemyBoss, j) <> -1 then
begin
ok := false;
break;
538,8 → 605,7
end;
if not ok then break;
end;
if Enemys.IndexOf(floattostr(ex + (ScrollP * RasterW))+'-'+floattostr(ey)+':'+
inttostr(i)+'('+inttostr(j)+')') <> -1 then
if LevData.IndexOfEnemy(ex + (ScrollP * LevEditRasterW), ey, i, j) <> -1 then
begin
ok := false;
break;
550,14 → 616,12
end;
if ok then
begin
if ArtChecked <> 4 then
Enemys.Add(floattostr(ex + (ScrollP * RasterW))+'-'+floattostr(ey)+':'+
inttostr(ArtChecked)+'('+inttostr(LiveEdit)+')')
if EnemyTypeHasLives(SelectedEnemyType) then
LevData.AddEnemy(ex + (ScrollP * LevEditRasterW), ey, SelectedEnemyType, LivesEdit.Value)
else
Enemys.Add(floattostr(ex + (ScrollP * RasterW))+'-'+floattostr(ey)+':'+
inttostr(ArtChecked)+'(0)');
LevData.AddEnemy(ex + (ScrollP * LevEditRasterW), ey, SelectedEnemyType, 0);
inc(NumEnemys);
if ArtChecked = 7 then boss := true;
if SelectedEnemyType = etEnemyBoss then boss := true;
end
else beep;
end
564,19 → 628,19
{ Löschen }
else if Button = mbRight then
begin
for i := 1 to 7 do
for i := Low(TEnemyType) to High(TEnemyType) do
begin
for j := 0 to 999 do
for j := 0 to MaxPossibleEnemyLives do
begin
if boss and (i = 7) then
if boss and (i = etEnemyBoss) then
begin
for k := 0 to 3 do
for k := 0 to BossWidth - 1 do
begin
for l := 0 to 1 do
for l := 0 to BossHeight - 1 do
begin
if Enemys.IndexOf(floattostr(ex + ((ScrollP - k) * RasterW))+'-'+floattostr(ey - (RasterH * l))+':'+inttostr(i)+'('+inttostr(j)+')') <> -1 then
if LevData.IndexOfEnemy(ex + ((ScrollP - k) * LevEditRasterW), ey - (LevEditRasterH * l), i, j) <> -1 then
begin
Enemys.Delete(Enemys.IndexOf(floattostr(ex + ((ScrollP - k) * RasterW))+'-'+floattostr(ey - (RasterH * l))+':'+inttostr(i)+'('+inttostr(j)+')'));
LevData.DeleteEnemy(ex + ((ScrollP - k) * LevEditRasterW), ey - (LevEditRasterH * l), i, j);
Boss := false;
dec(NumEnemys);
breaked := true;
586,12 → 650,10
if breaked then break;
end;
end;
if Enemys.IndexOf(floattostr(ex + (ScrollP * RasterW))+'-'+floattostr(ey)+':'+
inttostr(i)+'('+inttostr(j)+')') <> -1 then
if LevData.IndexOfEnemy(ex + (ScrollP * LevEditRasterW), ey, i, j) <> -1 then
begin
Enemys.Delete(Enemys.IndexOf(floattostr(ex + (ScrollP * RasterW))+'-'+floattostr(ey)+
':'+inttostr(i)+'('+inttostr(j)+')'));
if i = 7 then Boss := false;
LevData.DeleteEnemy(ex + (ScrollP * LevEditRasterW), ey, i, j);
if i = etEnemyBoss then Boss := false;
dec(NumEnemys);
breaked := true;
break;
605,26 → 667,20
end;
 
procedure TMainForm.EnemyClick(Sender: TObject);
var
et: TEnemyType;
begin
if sender = Enemy1 then ArtChecked := 1;
if sender = Enemy2 then ArtChecked := 2;
if sender = Enemy3 then ArtChecked := 3;
if sender = Enemy4 then ArtChecked := 4;
if sender = Enemy5 then ArtChecked := 5;
if sender = Enemy6 then ArtChecked := 6;
if sender = Enemy7 then ArtChecked := 7;
Image1.Left := -(87 * (ArtChecked - 1)) + 1;
Lives.Enabled := sender <> Enemy4;
LivesLabel.Enabled := sender <> Enemy4;
if sender = Enemy4 then LivesEdt.Font.Color := clBtnShadow // andere farbe?
else LivesEdt.Font.Color := clWindowText;
et := SelectedEnemyType;
Image1.Left := -(87 * (Ord(et) - 1)) + 1;
LivesEdit.Enabled := EnemyTypeHasLives(et);
LivesLabel.Enabled := EnemyTypeHasLives(et);
end;
 
procedure TMainForm.EnemyCreate(x, y: integer);
procedure TMainForm.EnemyCreateSprite(x, y: integer; AEnemyType: TEnemyType; ALives: integer);
var
Enemy: TSprite;
begin
Enemy := TEnemy.Create(SpriteEngine.Engine);
Enemy := TEnemyOrItem.Create(SpriteEngine.Engine, AEnemyType, ALives);
Enemy.x := x;
Enemy.y := y;
end;
631,76 → 687,107
 
procedure TMainForm.DestroyLevel;
begin
ScrollBar.Position := 0;
Enemys.Clear;
ScrollBar.Position := 0; // this doesn't call ScrollBarScroll()
ScrollP := 0;
LevData.Clear;
ScrollBar.Max := LevData.LevelEditorLength;
NumEnemys := 0;
Boss := false;
LevChanged := true;
Lives.Position := 1;
LivesChange(Lives.Position);
LivesEdit.Value := 1;
Enemy1.Checked := true;
EnemyClick(Enemy1);
AnzeigeAct;
end;
 
procedure TMainForm.AlleLeveldateienaktualisieren1Click(Sender: TObject);
var
i: integer;
begin
// Just for internal/development purposes
for i := 1 to MaxPossibleLevels do
begin
if FileExists('Levels\Level '+IntToStr(i)+'.lev') then
begin
LevData.RasterErzwingen := true;
LevData.LoadFromFile('Levels\Level '+IntToStr(i)+'.lev');
LevData.SaveToFile('Levels\Level '+IntToStr(i)+'.lev');
end;
end;
end;
 
procedure TMainForm.AnzeigeAct;
resourcestring
SYes = 'Ja';
SNo = 'Nein';
begin
SLabel1b.Caption := inttostr(NumEnemys);
if Boss then SLabel2b.Caption := 'Ja' else SLabel2b.Caption := 'Nein';
if Boss then SLabel2b.Caption := SYes else SLabel2b.Caption := SNo;
SLabel3b.Caption := inttostr(ScrollBar.Max);
if LevChanged then
begin
SLabel4a.Font.Color := $00000096;
SLabel4b.Font.Color := $00000096;
SLabel4b.Caption := 'Nein';
SLabel4b.Caption := SNo;
end
else
begin
SLabel4a.Font.Color := $00009600;
SLabel4b.Font.Color := $00009600;
SLabel4b.Caption := 'Ja';
SLabel4b.Caption := SYes;
end;
end;
 
procedure TMainForm.EnemyAdd(x, y, art, lives: integer);
procedure TMainForm.AufUpdatesprfen1Click(Sender: TObject);
begin
Enemys.Add(inttostr(x)+'-'+inttostr(y)+':'+inttostr(art)+'('+inttostr(lives)+')');
CheckForUpdates('spacemission', ProgramVersion); // do not localize
end;
 
procedure TMainForm.NeuClick(Sender: TObject);
resourcestring
SReallyDeleteLevel = 'Level wirklich löschen?';
begin
if MessageDlg('Level wirklich löschen?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
if MessageDlg(SReallyDeleteLevel, mtConfirmation, mbYesNoCancel, 0) = mrYes then
DestroyLevel;
end;
 
procedure TMainForm.DXDrawMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
resourcestring
status_lives = 'Leben: ';
status_nolives = 'Einheit hat keine Lebensangabe';
SUnknownEnemyType = '???';
var
ex, ey, i, j, k, l, wert: integer;
i: TEnemyType;
ex, ey, j, k, l: integer;
lifes: integer;
enemyType: TEnemyType;
enemyName: string;
breaked: boolean;
begin
if sender <> DxDraw then
begin
StatusBar.SimpleText := status_info;
StatusBar.SimpleText := ' ' + status_info;
exit;
end;
ex := trunc(x/RasterW) * RasterW;
ey := trunc(y/RasterH) * RasterH;
wert := -1;
ex := trunc(x/LevEditRasterW) * LevEditRasterW;
ey := trunc(y/LevEditRasterH) * LevEditRasterH;
lifes := -1;
enemyType := etUnknown;
breaked := false;
for i := 1 to 7 do
for i := Low(TEnemyType) to High(TEnemyType) do
begin
for j := 0 to 999 do
for j := 0 to MaxPossibleEnemyLives do
begin
if boss and (i = 7) then
if boss and (i = etEnemyBoss) then
begin
for k := 0 to 3 do
for k := 0 to BossWidth - 1 do
begin
for l := 0 to 1 do
for l := 0 to BossHeight - 1 do
begin
if Enemys.IndexOf(floattostr(ex + ((ScrollP - k) * RasterW))+'-'+floattostr(ey - (RasterH * l))+':'+inttostr(i)+'('+inttostr(j)+')') <> -1 then
if LevData.IndexOfEnemy(ex + ((ScrollP - k) * LevEditRasterW), ey - (LevEditRasterH * l), i, j) <> -1 then
begin
wert := j;
lifes := j;
breaked := true;
break;
end;
708,10 → 795,10
if breaked then break;
end;
end;
if (breaked = false) and (Enemys.IndexOf(floattostr(ex + (ScrollP * RasterW))+'-'+floattostr(ey)+':'+
inttostr(i)+'('+inttostr(j)+')') <> -1) then
if (breaked = false) and (LevData.IndexOfEnemy(ex + (ScrollP * LevEditRasterW), ey, i, j) <> -1) then
begin
wert := j;
lifes := j;
enemyType := i;
breaked := true;
break;
end;
718,29 → 805,34
end;
if breaked then break;
end;
if wert <> -1 then
if lifes <> -1 then
begin
if wert > 0 then
StatusBar.SimpleText := status_lives + inttostr(wert)
if Ord(enemyType) = 1 then enemyName := Enemy1.Caption
else if Ord(enemyType) = 2 then enemyName := Enemy2.Caption
else if Ord(enemyType) = 3 then enemyName := Enemy3.Caption
else if Ord(enemyType) = 4 then enemyName := Enemy4.Caption
else if Ord(enemyType) = 5 then enemyName := Enemy5.Caption
else if Ord(enemyType) = 6 then enemyName := Enemy6.Caption
else if Ord(enemyType) = 7 then enemyName := Enemy7.Caption
else if Ord(enemyType) = 8 then enemyName := Enemy8.Caption
else enemyName := SUnknownEnemyType;
if lifes > 0 then
StatusBar.SimpleText := ' ' + enemyName + ' - ' + status_lives + inttostr(lifes)
else
StatusBar.SimpleText := status_nolives;
StatusBar.SimpleText := ' ' + enemyName + ' - ' + status_nolives;
end
else
StatusBar.SimpleText := status_info;
StatusBar.SimpleText := ' ' + status_info;
end;
 
procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
resourcestring
SExitWithoutSave = 'Beenden ohne abspeichern?';
begin
if LevChanged then
CanClose := MessageDlg('Beenden ohne abspeichern?', mtConfirmation, [mbYes, mbNo], 0) = mrYes;
if Assigned(LevData) and LevChanged and (LevData.CountEnemies>0) then
CanClose := MessageDlg(SExitWithoutSave, mtConfirmation, mbYesNoCancel, 0) = mrYes;
end;
 
procedure TMainForm.Quelltext1Click(Sender: TObject);
begin
SourceForm.Aktualisieren;
SourceForm.showmodal;
end;
 
procedure TMainForm.Spielfelderweitern1Click(Sender: TObject);
begin
LevelForm.Aktualisieren;
753,28 → 845,18
ScrollP := ScrollPos;
end;
 
procedure TMainForm.LivesChange(newval: integer);
function TMainForm.SelectedEnemyType: TEnemyType;
begin
LiveEdit := newval;
livesedt.Text := inttostr(LiveEdit);
lives.Position := newval;
if Enemy1.Checked then result := etEnemyAttacker
else if Enemy2.Checked then result := etEnemyAttacker2
else if Enemy3.Checked then result := etEnemyAttacker3
else if Enemy4.Checked then result := etEnemyMeteor
else if Enemy5.Checked then result := etEnemyUFO
else if Enemy6.Checked then result := etEnemyUFO2
else if Enemy7.Checked then result := etEnemyBoss
else if Enemy8.Checked then result := etItemMedikit
else result := etUnknown;
end;
 
procedure TMainForm.LivesClick(Sender: TObject; Button: TUDBtnType);
begin
LivesChange(lives.Position);
end;
 
procedure TMainForm.LivesEdtKeyPress(Sender: TObject; var Key: Char);
begin
if not (Key in [#13, #08, '0'..'9']) then
Key := #0;
end;
 
procedure TMainForm.LivesEdtChange(Sender: TObject);
begin
LivesChange(strtoint(livesedt.text));
end;
 
end.