1152 lines
39 KiB
Plaintext
1152 lines
39 KiB
Plaintext
unit MapEditor;
|
|
|
|
interface
|
|
|
|
uses
|
|
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
|
|
Dialogs, ExtCtrls, Menus, XPMan, IniFiles, StdCtrls, Spin, ImgList, ComCtrls,
|
|
pngimage, Map, Tileset, About, Misc, BlockEditor;
|
|
|
|
type
|
|
|
|
TPointer = packed record
|
|
First: Byte;
|
|
Second: Byte;
|
|
end;
|
|
|
|
TPokemon = packed record
|
|
Level: Byte;
|
|
Number: Byte;
|
|
end;
|
|
|
|
TLandWildPkmn = packed record
|
|
Rate: Byte;
|
|
Pkmn: array [0..9] of TPokemon;
|
|
end;
|
|
|
|
TWaterWildPkmn = packed record
|
|
Rate: Byte;
|
|
Pkmn: array [0..9] of TPokemon;
|
|
end;
|
|
|
|
TMapEditorForm = class(TForm)
|
|
XPManifest1: TXPManifest;
|
|
MainMenu1: TMainMenu;
|
|
File1: TMenuItem;
|
|
LoadRom1: TMenuItem;
|
|
SaveRom1: TMenuItem;
|
|
SaveRomAs1: TMenuItem;
|
|
N1: TMenuItem;
|
|
LoadMap1: TMenuItem;
|
|
SaveMap1: TMenuItem;
|
|
N2: TMenuItem;
|
|
Exit1: TMenuItem;
|
|
Settings1: TMenuItem;
|
|
Grid1: TMenuItem;
|
|
N4: TMenuItem;
|
|
Palette1: TMenuItem;
|
|
Morning1: TMenuItem;
|
|
Day1: TMenuItem;
|
|
Night1: TMenuItem;
|
|
Darkness1: TMenuItem;
|
|
Indoor1: TMenuItem;
|
|
Tools: TMenuItem;
|
|
BlockEditor1: TMenuItem;
|
|
ReconstructMap1: TMenuItem;
|
|
ReBuildEvents1: TMenuItem;
|
|
N3: TMenuItem;
|
|
SaveMapPic1: TMenuItem;
|
|
SaveTilesetPic1: TMenuItem;
|
|
TryMap1: TMenuItem;
|
|
Help1: TMenuItem;
|
|
About1: TMenuItem;
|
|
SaveMapDialog: TSaveDialog;
|
|
OpenRomDialog: TOpenDialog;
|
|
SaveRomDialog: TSaveDialog;
|
|
OpenMapDialog: TOpenDialog;
|
|
PageControl1: TPageControl;
|
|
TabSheet1: TTabSheet;
|
|
MapScrollBox: TScrollBox;
|
|
MapBox: TPaintBox;
|
|
BlockPaletteScrollBox: TScrollBox;
|
|
BlockPalette: TPaintBox;
|
|
TabSheet2: TTabSheet;
|
|
NoEventsLabel: TLabel;
|
|
EventScrollBox: TScrollBox;
|
|
SignpostImage: TImage;
|
|
PeopleImage: TImage;
|
|
WarpImage: TImage;
|
|
EventBox: TPaintBox;
|
|
TriggerImage: TImage;
|
|
TabSheet3: TTabSheet;
|
|
NoWildPkmnLabel: TLabel;
|
|
LandGroup1: TGroupBox;
|
|
LandPkmnLevel: TSpinEdit;
|
|
LandPkmnBox: TListBox;
|
|
LandPkmnCombo: TComboBox;
|
|
StatusBar1: TStatusBar;
|
|
ImageList1: TImageList;
|
|
MapSelectPanel: TPanel;
|
|
MapSelectCombo: TComboBox;
|
|
Label5: TLabel;
|
|
shpHighlight: TShape;
|
|
TabSheet4: TTabSheet;
|
|
Edit1: TMenuItem;
|
|
Undo1: TMenuItem;
|
|
LandLevelBox: TListBox;
|
|
LandPkmnGroup: TGroupBox;
|
|
LandLevelGroup: TGroupBox;
|
|
LandReplaceBtn: TButton;
|
|
WaterGroup1: TGroupBox;
|
|
WaterPkmnBox: TListBox;
|
|
WaterLevelBox: TListBox;
|
|
WaterPkmnGroup: TGroupBox;
|
|
WaterPkmnCombo: TComboBox;
|
|
WaterLevelGroup: TGroupBox;
|
|
WaterPkmnLevel: TSpinEdit;
|
|
WaterReplaceBtn: TButton;
|
|
LandRateTrack: TTrackBar;
|
|
LandRateGroup: TGroupBox;
|
|
Less1: TLabel;
|
|
More1: TLabel;
|
|
LandPercent: TLabel;
|
|
WaterRateGroup: TGroupBox;
|
|
Less2: TLabel;
|
|
More2: TLabel;
|
|
WaterPercent: TLabel;
|
|
WaterRateTrack: TTrackBar;
|
|
OffsetLabel1: TLabel;
|
|
LandOffset1: TLabel;
|
|
OffsetLabel2: TLabel;
|
|
WaterOffset1: TLabel;
|
|
procedure BlockEditor1Click(Sender: TObject);
|
|
procedure Grid1Click(Sender: TObject);
|
|
procedure About1Click(Sender: TObject);
|
|
procedure BlockPaletteMouseMove(Sender: TObject; Shift: TShiftState; X,
|
|
Y: Integer);
|
|
procedure BlockPaletteMouseDown(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
procedure MapBoxMouseUp(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
procedure MapBoxMouseMove(Sender: TObject; Shift: TShiftState; X,
|
|
Y: Integer);
|
|
procedure MapBoxMouseDown(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
procedure MapSelectComboChange(Sender: TObject);
|
|
procedure MapBoxPaint(Sender: TObject);
|
|
procedure BlockPalettePaint(Sender: TObject);
|
|
procedure TilesetComboDrawItem(Control: TWinControl; Index: Integer;
|
|
Rect: TRect; State: TOwnerDrawState);
|
|
procedure SpinEdit1Change(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure LoadRom1Click(Sender: TObject);
|
|
|
|
|
|
//saves currently open map, event and pokemon data to rom (in memory) and writes to file
|
|
procedure SaveRom(FileName: string);
|
|
|
|
//loads specified map, tileset for map, map's events and pokemon
|
|
procedure LoadMap(MapIndex: byte);
|
|
//loads specified tileset
|
|
procedure LoadTileset(TilesetNumber: Byte);
|
|
//loads wild pokemon data for specified map
|
|
procedure LoadPokemon(MapIndex: Byte);
|
|
|
|
//saves currently loaded map, map's events and pokemon
|
|
procedure SaveMap;
|
|
//draws tileset blocks from MapData into Canvas
|
|
procedure DrawMap(Canvas: TCanvas);
|
|
//draws the tileset blocks on Canvas
|
|
procedure DrawBlocks(Canvas: TCanvas);
|
|
//refreshes the wild pokemon data controls in Wild Pokemon tab
|
|
procedure UpdatePokemon;
|
|
procedure SavePokemon;
|
|
|
|
function IsOutsideOfMapBounds(X, Y: Integer): Boolean;
|
|
procedure Exit1Click(Sender: TObject);
|
|
procedure SaveRom1Click(Sender: TObject);
|
|
procedure LandReplaceBtnClick(Sender: TObject);
|
|
procedure WaterReplaceBtnClick(Sender: TObject);
|
|
procedure LandPkmnBoxClick(Sender: TObject);
|
|
procedure WaterPkmnBoxClick(Sender: TObject);
|
|
procedure WaterRateTrackExit(Sender: TObject);
|
|
procedure LandRateTrackExit(Sender: TObject);
|
|
|
|
private
|
|
{ Private declarations }
|
|
public
|
|
{ Public declarations }
|
|
end;
|
|
|
|
var
|
|
MapEditorForm: TMapEditorForm;
|
|
LoadedTileset: Byte = 0;
|
|
LoadedMap: string = '';
|
|
LoadedMapBank: Byte;
|
|
LoadedMapNum: Byte;
|
|
SelBlock, SelPic, MapStart, TilesetStart, PokemonStart, Blocks: Integer;
|
|
LoadedMapHeader: TMapHeader;
|
|
Rom: TMemoryStream = nil;
|
|
MapData: array of Byte;
|
|
BlockPics: array [0..255] of TBitmap;
|
|
Painting,DraggingEvent: Boolean;
|
|
Tiles: TBitmap;
|
|
MapModified: boolean;
|
|
RomModified: boolean;
|
|
DragOldX,DragOldY: Integer;
|
|
TilesetCache: array [0..23] of TBitmap;
|
|
ConnectionData: array [$00..$03] of TConnectionData;
|
|
ConnectedMapHeaders: array [$00..$03] of TMapHeader;
|
|
TopMapData: array of Byte;
|
|
BottomMapData: array of Byte;
|
|
LeftMapData: array of Byte;
|
|
RightMapData: array of Byte;
|
|
Pointer: TPointer;
|
|
LandWildPkmn: TLandWildPkmn;
|
|
WaterWildPkmn: TWaterWildPkmn;
|
|
Location: string;
|
|
|
|
implementation
|
|
|
|
{$R *.dfm}
|
|
|
|
procedure TMapEditorForm.FormCreate(Sender: TObject);
|
|
begin
|
|
ControlStyle := ControlStyle + [csOpaque];
|
|
MapScrollBox.ControlStyle := MapScrollBox.ControlStyle + [csOpaque];
|
|
MapBox.ControlStyle := MapBox.ControlStyle + [csOpaque];
|
|
|
|
// Create the tileset graphic
|
|
Tiles := TBitmap.Create;
|
|
Tiles.Width := 16*16;
|
|
Tiles.Height := 16*6;
|
|
Tiles.PixelFormat := pf24bit;
|
|
|
|
// Import for drawing grid.
|
|
MapBox.Canvas.Brush.Style := bsClear;
|
|
EventBox.Canvas.Brush.Style := bsClear;
|
|
BlockPalette.Canvas.Brush.Style := bsClear;
|
|
end;
|
|
|
|
procedure TMapEditorForm.Grid1Click(Sender: TObject);
|
|
begin
|
|
//if grid is checked then it will be hidden
|
|
if Grid1.Checked then
|
|
Grid1.Checked := False
|
|
else
|
|
//if grid is unchecked then it will be shown
|
|
Grid1.Checked := True;
|
|
//PokemonIni.WriteBool('Settings','Grid',Grid1.Checked);
|
|
//show the grid if needed
|
|
if MapStart > 0 then
|
|
begin
|
|
DrawMap(MapBox.Canvas);
|
|
//DrawEvents(MainForm.EventBox.Canvas);
|
|
DrawBlocks(BlockPalette.Canvas);
|
|
end;
|
|
end;
|
|
|
|
procedure TMapEditorForm.LoadRom1Click(Sender: TObject);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if OpenRomDialog.Execute then
|
|
begin
|
|
// Check if memory stream is null.
|
|
if Rom = nil then
|
|
Rom := TMemoryStream.Create;
|
|
|
|
// Load TMemoryStream from file.
|
|
Rom.LoadFromFile(OpenRomDialog.FileName);
|
|
|
|
ReadMapPallets;
|
|
|
|
// Load up tileset combos.
|
|
for I := 0 to 23 do
|
|
begin
|
|
TilesetCache[I] := TBitmap.Create;
|
|
TilesetCache[I].Width := 128;
|
|
TilesetCache[I].Height := 48;
|
|
TilesetCache[I].PixelFormat := pf24bit;
|
|
ReadTilesetGraphics(GetTilesetHeader(I), TilesetCache[I]);
|
|
end;
|
|
|
|
MapModified := False;
|
|
RomModified := False;
|
|
BlockEditor1.Enabled := False;
|
|
ReBuildEvents1.Enabled := False;
|
|
ReconstructMap1.Enabled := False;
|
|
SaveRom1.Enabled := True;
|
|
SaveRomAs1.Enabled := True;
|
|
//ReadAreaNames;
|
|
//ScanMapHeaders;
|
|
ReadMapHeaderLocations;
|
|
MapSelectPanel.Show;
|
|
StatusBar1.Panels[1].Text := 'ROM Loaded...';
|
|
//LoadMap(0);
|
|
MapSelectCombo.ItemIndex := 0;
|
|
MapSelectComboChange(Sender);
|
|
end;
|
|
end;
|
|
|
|
procedure TMapEditorForm.SpinEdit1Change(Sender: TObject);
|
|
begin
|
|
//ReadTilesetGraphics(GetTilesetHeader(SpinEdit1.Value), Tiles);
|
|
//TilePalette.Picture.Graphic := Tiles;
|
|
end;
|
|
|
|
procedure TMapEditorForm.TilesetComboDrawItem(Control: TWinControl;
|
|
Index: Integer; Rect: TRect; State: TOwnerDrawState);
|
|
begin
|
|
with TComboBox(Control).Canvas do
|
|
begin
|
|
FillRect(Rect);
|
|
TextOut(Rect.Left,Rect.Top,'Tileset ' + IntToStr(Index) + ':');
|
|
Draw((Rect.Right - Rect.Left) div 2 - 64, Rect.Top + 13, TilesetCache[Index]);
|
|
end;
|
|
end;
|
|
|
|
procedure TMapEditorForm.LoadTileset(TilesetNumber: Byte);
|
|
label LoadingDone;
|
|
var
|
|
X, Y, Block, TileX, TileY: Integer;
|
|
TileNumber: Byte;
|
|
Temp: TBitmap;
|
|
TilesetHdr: TTilesetHeader;
|
|
begin
|
|
//if the tileset needed is already loaded, just exit
|
|
//if LoadedTileset = TilesetNumber then Exit;
|
|
|
|
TilesetHdr := GetTilesetHeader(TilesetNumber);
|
|
TilesetStart := GBPtrToFilePos(TilesetHdr.BankNumber,TilesetHdr.TilesetArrangementPointer);
|
|
|
|
if (TilesetStart = 0) or (GBPtrToFilePos(TilesetHdr.BankNumber,TilesetHdr.TilesetGraphicsPointer) = 0) then
|
|
begin
|
|
MessageDlg('Tileset information in rom seem to be corrupted. Loading will be cancelled.',mtError,[mbOK],0);
|
|
Abort;
|
|
end;
|
|
|
|
Temp := TBitmap.Create;
|
|
Temp.Width := 16*16;
|
|
Temp.Height := 16*6;
|
|
Temp.PixelFormat := pf24bit;
|
|
|
|
//Temp.LoadFromFile(ExtractFilePath(Application.ExeName) + 'Tileset' + IntToStr(TilesetNumber) + '.dib');
|
|
ReadTilesetGraphics(GetTilesetHeader(TilesetNumber),Temp);
|
|
Tiles.Canvas.StretchDraw(Tiles.Canvas.ClipRect,Temp);
|
|
|
|
//start loading
|
|
StatusBar1.Panels[0].Text := 'Loading Tileset ' + IntToStr(TilesetNumber) + ' please wait...';
|
|
|
|
//start reading the block data from rom & rendering the tiles
|
|
Rom.Position := TilesetStart;
|
|
Blocks := 255;
|
|
for Block := 0 to 255 do
|
|
begin
|
|
for Y := 0 to 3 do
|
|
for X := 0 to 3 do
|
|
begin
|
|
Rom.Read(TileNumber,1);
|
|
//create bitmap for block if not already existing
|
|
if BlockPics[Block] = nil then
|
|
begin
|
|
BlockPics[Block] := TBitmap.Create;
|
|
BlockPics[Block].Width := 32;
|
|
BlockPics[Block].Height := 32;
|
|
BlockPics[Block].PixelFormat := pf24bit;
|
|
end;
|
|
//calculate x and y coordinate where to copy tile from, the tileset picture has 16 tiles per line
|
|
TileY := TileNumber div 16;
|
|
TileX := TileNumber mod 16;
|
|
//draw tile to block picture
|
|
BlockPics[Block].Canvas.CopyRect(Rect(X*8,Y*8,X*8+8,Y*8+8),Tiles.Canvas,Rect(TileX*8,TileY*8,TileX*8+8,TileY*8+8));
|
|
end;
|
|
end;
|
|
|
|
BlockPalette.Height := 32 * Blocks;
|
|
BlockPaletteScrollBox.Show;
|
|
SelBlock := 1;
|
|
LoadedTileset := TilesetNumber;
|
|
|
|
//updates blocks because tileset is changed
|
|
DrawBlocks(BlockPalette.Canvas);
|
|
|
|
//enable editing blocks
|
|
BlockEditor1.Enabled := True;
|
|
StatusBar1.Panels[0].Text := 'Tileset ' + inttostr(TilesetNumber) + ' loaded.';
|
|
end;
|
|
|
|
procedure TMapEditorForm.About1Click(Sender: TObject);
|
|
begin
|
|
with TAboutDialog.Create(nil) do
|
|
begin
|
|
ShowModal;
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TMapEditorForm.BlockEditor1Click(Sender: TObject);
|
|
begin
|
|
with TBlockEditorForm.Create(nil) do
|
|
begin
|
|
ShowModal;
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TMapEditorForm.BlockPaletteMouseDown(Sender: TObject;
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
SelBlock := (Y div 32);
|
|
end;
|
|
|
|
procedure TMapEditorForm.BlockPaletteMouseMove(Sender: TObject;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
StatusBar1.Panels[0].Text := 'Block: $' + IntToHex(Y div 32 , 2) + ' Offset: $' + IntToHex(TilesetStart + ((Y div 32) * 16),0);
|
|
end;
|
|
|
|
procedure TMapEditorForm.BlockPalettePaint(Sender: TObject);
|
|
begin
|
|
DrawBlocks(BlockPalette.Canvas);
|
|
end;
|
|
|
|
procedure TMapEditorForm.DrawBlocks(Canvas: TCanvas);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Canvas.Brush.Style := bsClear;
|
|
//go through the block pictures and draw then on BlockPalette
|
|
for I := 0 to Blocks -1 do
|
|
begin
|
|
Canvas.Draw(0, I * 32, BlockPics[I]);
|
|
if Grid1.Checked then
|
|
Canvas.Rectangle(0, I * 32, 32 + 32, I * 32 + 32);
|
|
end;
|
|
//allow saving tileset picture
|
|
SaveTilesetPic1.Enabled := True;
|
|
end;
|
|
|
|
procedure TMapEditorForm.DrawMap(Canvas: TCanvas);
|
|
var
|
|
X, Y: Integer;
|
|
MaxX, MaxY: Integer;
|
|
StartTileConnect, StartWriteConnect: Integer;
|
|
StartHeightWidthDifference: Integer;
|
|
StartX, StartY, EndX, EndY: Integer;
|
|
|
|
begin
|
|
Canvas.Brush.Style := bsClear;
|
|
|
|
MaxX := Canvas.ClipRect.Right div 32;
|
|
MaxY := Canvas.ClipRect.Bottom div 32;
|
|
|
|
if MaxX >= LoadedMapHeader.Width then MaxX := LoadedMapHeader.Width-1;
|
|
if MaxY >= LoadedMapHeader.Height then MaxY := LoadedMapHeader.Height-1;
|
|
|
|
for X := Canvas.ClipRect.Left div 32 to MaxX + 6 do
|
|
for Y := Canvas.ClipRect.Top div 32 to MaxY + 6 do
|
|
begin
|
|
if (X >= 3) and (Y >= 3) and (X <= MaxX + 3) and (Y <= MaxY + 3) then
|
|
begin
|
|
if (MapData[(Y-3) * LoadedMapHeader.Width + (X-3)] <= Blocks) then
|
|
Canvas.Draw(X * 32, Y * 32, BlockPics[MapData[(Y-3) * LoadedMapHeader.Width + (X-3)]])
|
|
else
|
|
begin
|
|
// Invalid blocks detected
|
|
Canvas.Brush.Style := bsSolid;
|
|
Canvas.Rectangle(X * 32, Y * 32, X * 32 + 32, Y * 32 + 32);
|
|
Canvas.Brush.Style := bsClear;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
Canvas.Draw(X * 32, Y * 32, BlockPics[LoadedMapHeader.BorderBlock]);
|
|
|
|
// Top
|
|
if (LoadedMapHeader.ConnectionDataControl and $08) = $08 then
|
|
begin
|
|
StartTileConnect := (LoadedMapHeader.ConnectionData[0].MapDataPointer - $4000) - (ConnectedMapHeaders[0].DataPointer - $4000);
|
|
StartWriteConnect := LoadedMapHeader.ConnectionData[0].MapLocationRamPointer - $C6E8;
|
|
StartX := StartWriteConnect;
|
|
StartY := 0;
|
|
EndX := (LoadedMapHeader.ConnectionData[0].WidthHeightVisiblePart - 1) + StartWriteConnect;
|
|
EndY := StartY + 3;
|
|
|
|
if (X >= StartX) and (Y >= StartY) and (X <= EndX) and (Y < EndY) then
|
|
begin
|
|
StartHeightWidthDifference := ConnectedMapHeaders[0].Width - LoadedMapHeader.ConnectionData[0].WidthHeightVisiblePart;
|
|
Canvas.Draw(X * 32, Y * 32, BlockPics[TopMapData[StartTileConnect + (Y * StartHeightWidthDifference) + (Y * LoadedMapHeader.ConnectionData[0].WidthHeightVisiblePart + (X - StartWriteConnect))]]);
|
|
end;
|
|
end;
|
|
|
|
// Bottom
|
|
if (LoadedMapHeader.ConnectionDataControl and $04) = $04 then
|
|
begin
|
|
StartTileConnect := (LoadedMapHeader.ConnectionData[1].MapDataPointer - $4000) - (ConnectedMapHeaders[1].DataPointer - $4000);
|
|
StartWriteConnect := LoadedMapHeader.ConnectionData[1].MapLocationRamPointer - $C6E8;
|
|
StartX := StartWriteConnect - ((LoadedMapHeader.Width + 6) * (LoadedMapHeader.Height + 3));
|
|
StartY := StartWriteConnect div (LoadedMapHeader.Width + 6);
|
|
EndX := StartX + (LoadedMapHeader.ConnectionData[1].WidthHeightVisiblePart - 1);
|
|
EndY := StartY + 3;
|
|
|
|
if (X >= StartX) and (Y >= StartY) and (X <= EndX) and (Y < EndY) then
|
|
begin
|
|
StartHeightWidthDifference := ConnectedMapHeaders[1].Width - LoadedMapHeader.ConnectionData[1].WidthHeightVisiblePart;
|
|
Canvas.Draw(X * 32, Y * 32, BlockPics[BottomMapData[StartTileConnect + ((Y - StartY) * StartHeightWidthDifference) + ((Y - StartY) * LoadedMapHeader.ConnectionData[1].WidthHeightVisiblePart + (X - StartX))]]);
|
|
end;
|
|
end;
|
|
|
|
// Left
|
|
if (LoadedMapHeader.ConnectionDataControl and $02) = $02 then
|
|
begin
|
|
StartTileConnect := (LoadedMapHeader.ConnectionData[2].MapDataPointer - $4000) - (ConnectedMapHeaders[2].DataPointer - $4000);
|
|
StartWriteConnect := LoadedMapHeader.ConnectionData[2].MapLocationRamPointer - $C6E8;
|
|
StartX := 0;
|
|
StartY := StartWriteConnect div (LoadedMapHeader.Width + 6);
|
|
EndX := (StartX + 3) - 1;
|
|
EndY := StartY + LoadedMapHeader.ConnectionData[2].WidthHeightVisiblePart;
|
|
|
|
if (X >= StartX) and (Y >= StartY) and (X <= EndX) and (Y < EndY) then
|
|
begin
|
|
StartHeightWidthDifference := ConnectedMapHeaders[2].Width - LoadedMapHeader.ConnectionData[2].WidthHeightVisiblePart;
|
|
Canvas.Draw(X * 32, Y * 32, BlockPics[LeftMapData[StartTileConnect + ((Y - StartY) * StartHeightWidthDifference) + ((Y - StartY) * LoadedMapHeader.ConnectionData[2].WidthHeightVisiblePart + (X - StartX))]]);
|
|
end;
|
|
end;
|
|
|
|
// Right
|
|
if (LoadedMapHeader.ConnectionDataControl and $01) = $01 then
|
|
begin
|
|
StartTileConnect := (LoadedMapHeader.ConnectionData[3].MapDataPointer - $4000) - (ConnectedMapHeaders[3].DataPointer - $4000);
|
|
StartWriteConnect := LoadedMapHeader.ConnectionData[3].MapLocationRamPointer - $C6E8;
|
|
|
|
StartX := LoadedMapHeader.Width+3;
|
|
StartY := StartWriteConnect div (LoadedMapHeader.Width + 6);
|
|
EndX := (StartX + 3) - 1;
|
|
EndY := StartY + LoadedMapHeader.ConnectionData[3].WidthHeightVisiblePart;
|
|
|
|
if (X >= StartX) and (Y >= StartY) and (X <= EndX) and (Y < EndY) then
|
|
begin
|
|
StartHeightWidthDifference := ConnectedMapHeaders[3].Width - LoadedMapHeader.ConnectionData[3].WidthHeightVisiblePart;
|
|
Canvas.Draw(X * 32, Y * 32, BlockPics[RightMapData[StartTileConnect + ((Y - StartY) * StartHeightWidthDifference) + ((Y - StartY) * LoadedMapHeader.ConnectionData[3].WidthHeightVisiblePart + (X - StartX))]]);
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
if Grid1.Checked then
|
|
Canvas.Rectangle(X * 32, Y * 32, X * 32 + 32, Y * 32 + 32);
|
|
end;
|
|
end;
|
|
|
|
procedure TMapEditorForm.LoadMap(MapIndex: byte);
|
|
var
|
|
TempMapHeader: TMapHeader;
|
|
TempMapStart: Integer;
|
|
TempMapIndex: Byte;
|
|
begin
|
|
|
|
//first check if we need to save previously loaded map
|
|
if MapModified then
|
|
case MessageDlg('Save changes?',mtConfirmation,mbYesNoCancel,0) of
|
|
mrYes: SaveMap;
|
|
mrCancel: Abort;
|
|
end;
|
|
|
|
LoadedMapHeader := GetMapHeader(MapIndex);
|
|
|
|
if (LoadedMapHeader.Width * LoadedMapHeader.Height = 0) then
|
|
begin
|
|
MessageDlg('There seems be error in map header. Map will not be loaded.',mtWarning,[mbOK],0);
|
|
Abort;
|
|
end;
|
|
|
|
DebugString('LoadMap', IntToStr(Map.BankLocations[MapIndex]));
|
|
|
|
// load palettes
|
|
if (MapIndex >= 0) and (MapIndex <= 10) then
|
|
begin
|
|
Palette[0] := WordToColor(RawMapPalettes[MapIndex+1][0]);
|
|
Palette[1] := WordToColor(RawMapPalettes[MapIndex+1][1]);
|
|
Palette[2] := WordToColor(RawMapPalettes[MapIndex+1][2]);
|
|
Palette[3] := WordToColor(RawMapPalettes[MapIndex+1][3]);
|
|
end
|
|
else
|
|
begin
|
|
// default
|
|
Palette[0] := WordToColor(RawMapPalettes[0][0]);
|
|
Palette[1] := WordToColor(RawMapPalettes[0][1]);
|
|
Palette[2] := WordToColor(RawMapPalettes[0][2]);
|
|
Palette[3] := WordToColor(RawMapPalettes[0][3]);
|
|
end;
|
|
|
|
// Load the tileset
|
|
LoadTileset(LoadedMapHeader.TilesetNumber);
|
|
|
|
// Set the pointer to the map data
|
|
MapStart := GBPtrToFilePos(Map.BankLocations[MapIndex], LoadedMapHeader.DataPointer);
|
|
|
|
// Make sure ROM is big enough
|
|
if Rom.Size - Rom.Position < LoadedMapHeader.Width * LoadedMapHeader.Height then
|
|
begin
|
|
MessageDlg('Map is too big to be read from file.', mtWarning, [mbOK], 0);
|
|
Abort;
|
|
end;
|
|
|
|
// Resize the map, and read the map data.
|
|
SetLength(MapData, LoadedMapHeader.Width * LoadedMapHeader.Height);
|
|
//read map data to array
|
|
Rom.Position := MapStart;
|
|
Rom.Read(MapData[0], LoadedMapHeader.Width * LoadedMapHeader.Height);
|
|
|
|
// Load Top connection data
|
|
if (LoadedMapHeader.ConnectionDataControl and $08) = $08 then
|
|
begin
|
|
TempMapIndex := LoadedMapHeader.ConnectionData[0].MapNumber;
|
|
TempMapHeader := GetMapHeader(TempMapIndex);
|
|
TempMapStart := GBPtrToFilePos(Map.BankLocations[TempMapIndex],
|
|
TempMapHeader.DataPointer);
|
|
ConnectedMapHeaders[0] := TempMapHeader;
|
|
SetLength(TopMapData, TempMapHeader.Width * TempMapHeader.Height);
|
|
Rom.Position := TempMapStart;
|
|
Rom.Read(TopMapData[0], TempMapHeader.Width * TempMapHeader.Height);
|
|
end;
|
|
|
|
// Load Bottom connection data
|
|
if (LoadedMapHeader.ConnectionDataControl and $04) = $04 then
|
|
begin
|
|
TempMapIndex := LoadedMapHeader.ConnectionData[1].MapNumber;
|
|
TempMapHeader := GetMapHeader(TempMapIndex);
|
|
TempMapStart := GBPtrToFilePos(Map.BankLocations[TempMapIndex],
|
|
TempMapHeader.DataPointer);
|
|
ConnectedMapHeaders[1] := TempMapHeader;
|
|
SetLength(BottomMapData, TempMapHeader.Width * TempMapHeader.Height);
|
|
Rom.Position := TempMapStart;
|
|
Rom.Read(BottomMapData[0], TempMapHeader.Width * TempMapHeader.Height);
|
|
end;
|
|
|
|
// Load Left connection data
|
|
if (LoadedMapHeader.ConnectionDataControl and $02) = $02 then
|
|
begin
|
|
TempMapIndex := LoadedMapHeader.ConnectionData[2].MapNumber;
|
|
TempMapHeader := GetMapHeader(TempMapIndex);
|
|
TempMapStart := GBPtrToFilePos(Map.BankLocations[TempMapIndex],
|
|
TempMapHeader.DataPointer);
|
|
ConnectedMapHeaders[2] := TempMapHeader;
|
|
SetLength(LeftMapData, TempMapHeader.Width * TempMapHeader.Height);
|
|
Rom.Position := TempMapStart;
|
|
Rom.Read(LeftMapData[0], TempMapHeader.Width * TempMapHeader.Height);
|
|
end;
|
|
|
|
// Load Right connection data
|
|
if (LoadedMapHeader.ConnectionDataControl and $01) = $01 then
|
|
begin
|
|
TempMapIndex := LoadedMapHeader.ConnectionData[3].MapNumber;
|
|
TempMapHeader := GetMapHeader(TempMapIndex);
|
|
TempMapStart := GBPtrToFilePos(Map.BankLocations[TempMapIndex],
|
|
TempMapHeader.DataPointer);
|
|
ConnectedMapHeaders[3] := TempMapHeader;
|
|
SetLength(RightMapData, TempMapHeader.Width * TempMapHeader.Height);
|
|
Rom.Position := TempMapStart;
|
|
Rom.Read(RightMapData[0], TempMapHeader.Width * TempMapHeader.Height);
|
|
end;
|
|
|
|
//give MapBox right size
|
|
MapBox.Height := LoadedMapHeader.Height * 32 + (6 * 32); //Pad with 6 Blocks
|
|
MapBox.Width := LoadedMapHeader.Width * 32 + (6 * 32); //Pad with 6 Blocks
|
|
|
|
//Show map
|
|
MapScrollBox.Hide;
|
|
MapScrollBox.Show;
|
|
MapScrollBox.ScrollInView(MapBox);
|
|
MapBox.Refresh;
|
|
|
|
//TODO: Load events and pokemon
|
|
LoadedMapBank := Map.BankLocations[MapIndex];
|
|
LoadedMapNum := MapIndex;
|
|
|
|
MapModified := False;
|
|
SaveMapPic1.Enabled := True;
|
|
|
|
LoadPokemon(MapIndex);
|
|
//hide event properties
|
|
//WarpForm.Hide;
|
|
//SignpostForm.Hide;
|
|
//PeopleForm.Hide;
|
|
end;
|
|
|
|
procedure TMapEditorForm.LoadPokemon(MapIndex: Byte);
|
|
var
|
|
First: string;
|
|
Second: string;
|
|
begin
|
|
PokemonStart := 0;
|
|
LandWildPkmn.Rate := $00;
|
|
WaterWildPkmn.Rate := $00;
|
|
LandPkmnBox.Clear;
|
|
WaterPkmnBox.Clear;
|
|
|
|
Rom.Position := $CEEB + (MapIndex * 2);
|
|
Rom.Read(Pointer,SizeOf(Pointer));
|
|
|
|
First := IntToStr(Pointer.Second + $80);
|
|
Second := IntToStr(Pointer.First);
|
|
Location := IntToHex(StrToInt(First),2) + IntToHex(StrToInt(Second),2);
|
|
Rom.Position := StrToInt('$' + Location);
|
|
Rom.Read(LandWildPkmn,SizeOf(TLandWildPkmn));
|
|
LandOffset1.Caption := '$' + Location;
|
|
if (LandWildPkmn.Rate <> $00) then
|
|
begin
|
|
PokemonStart := StrToInt('$' + Location);
|
|
Rom.Position := StrToInt('$' + Location) + SizeOf(TLandWildPkmn);
|
|
Rom.Read(WaterWildPkmn,SizeOf(TWaterWildPkmn));
|
|
WaterOffset1.Caption := '$' + IntToHex(StrToInt('$' + Location) + SizeOf(TLandWildPkmn),4);
|
|
end
|
|
else
|
|
begin
|
|
WaterOffset1.Caption := '$' + IntToHex(StrToInt('$' + Location) + $01,4);
|
|
Rom.Position := StrToInt('$' + Location) + $01;
|
|
Rom.Read(WaterWildPkmn,SizeOf(TWaterWildPkmn));
|
|
if WaterWildPkmn.Rate <> $00 then
|
|
begin
|
|
PokemonStart := StrToInt('$' + Location) + $01;
|
|
end;
|
|
end;
|
|
|
|
if (LandWildPkmn.Rate = $00) and (WaterWildPkmn.Rate = $00) then
|
|
begin
|
|
NoWildPkmnLabel.Show;
|
|
Exit;
|
|
end;
|
|
if LandWildPkmn.Rate <> $00 then
|
|
begin
|
|
LandPkmnBox.Enabled := True;
|
|
LandPkmnCombo.Enabled := True;
|
|
LandPkmnLevel.Enabled := True;
|
|
LandRateTrack.Enabled := True;
|
|
LandReplaceBtn.Enabled := True;
|
|
end
|
|
else
|
|
begin
|
|
LandPkmnBox.Enabled := False;
|
|
LandPkmnCombo.Enabled := False;
|
|
LandPkmnLevel.Enabled := False;
|
|
LandRateTrack.Enabled := False;
|
|
LandReplaceBtn.Enabled := False;
|
|
end;
|
|
if WaterWildPkmn.Rate <> $00 then
|
|
begin
|
|
WaterPkmnBox.Enabled := True;
|
|
WaterPkmnCombo.Enabled := True;
|
|
WaterPkmnLevel.Enabled := True;
|
|
WaterRateTrack.Enabled := True;
|
|
WaterReplaceBtn.Enabled := True;
|
|
end
|
|
else
|
|
begin
|
|
WaterPkmnBox.Enabled := False;
|
|
WaterPkmnCombo.Enabled := False;
|
|
WaterPkmnLevel.Enabled := False;
|
|
WaterRateTrack.Enabled := False;
|
|
WaterReplaceBtn.Enabled := False;
|
|
end;
|
|
NoWildPkmnLabel.Hide;
|
|
LandRateTrack.Position := LandWildPkmn.Rate;
|
|
LandPercent.Caption := IntToStr(LandWildPkmn.Rate) + '%';
|
|
WaterRateTrack.Position := WaterWildPkmn.Rate;
|
|
WaterPercent.Caption := IntToStr(WaterWildPkmn.Rate) + '%';
|
|
UpdatePokemon;
|
|
end;
|
|
|
|
procedure TMapEditorForm.UpdatePokemon;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
LandPkmnBox.Clear;
|
|
WaterPkmnBox.Clear;
|
|
LandLevelBox.Clear;
|
|
WaterLevelBox.Clear;
|
|
if LandWildPkmn.Rate <> $00 then
|
|
begin
|
|
for I := 0 to 9 do
|
|
begin
|
|
LandPkmnBox.AddItem(LandPkmnCombo.Items[LandWildPkmn.Pkmn[I].Number],LandPkmnBox);
|
|
LandLevelBox.AddItem(IntToStr(LandWildPkmn.Pkmn[I].Level),LandLevelBox);
|
|
end;
|
|
end;
|
|
if WaterWildPkmn.Rate <> $00 then
|
|
begin
|
|
for I := 0 to 9 do
|
|
begin
|
|
WaterPkmnBox.AddItem(WaterPkmnCombo.Items[WaterWildPkmn.Pkmn[I].Number],WaterPkmnBox);
|
|
WaterLevelBox.AddItem(IntToStr(WaterWildPkmn.Pkmn[I].Level),WaterLevelBox);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TMapEditorForm.MapBoxMouseDown(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
StartTileConnect, StartWriteConnect: Integer;
|
|
StartX, StartY, EndX, EndY: Integer;
|
|
BlockX, BlockY: Integer;
|
|
begin
|
|
|
|
BlockX := X div 32;
|
|
BlockY := Y div 32;
|
|
|
|
if IsOutsideOfMapBounds(X, Y) = false then
|
|
begin
|
|
//change block if mouse button is left
|
|
if Button = mbLeft then
|
|
begin
|
|
MapModified := True;
|
|
MapData[SelPic] := SelBlock;
|
|
MapBox.Canvas.Draw((X div 32) * 32, (Y div 32) * 32, BlockPics[SelBlock]);
|
|
//if gid is sellected, add it
|
|
if Grid1.Checked then
|
|
MapBox.Canvas.Rectangle(X div 32 * 32, Y div 32 * 32,
|
|
X div 32 * 32 + 32, Y div 32 * 32 + 32);
|
|
//enable painting for OnMouseMove
|
|
Painting := True;
|
|
end
|
|
else
|
|
begin
|
|
//other buttons will select the block at cursor
|
|
if (MapData[SelPic] <= Blocks) then
|
|
begin
|
|
BlockPaletteScrollBox.VertScrollBar.Position := 32 * MapData[SelPic];
|
|
SelBlock := MapData[SelPic];
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
// check if we are over a top connection
|
|
if (LoadedMapHeader.ConnectionDataControl and $08) = $08 then
|
|
begin
|
|
StartTileConnect := (LoadedMapHeader.ConnectionData[0].MapDataPointer - $4000) - (ConnectedMapHeaders[0].DataPointer - $4000);
|
|
StartWriteConnect := LoadedMapHeader.ConnectionData[0].MapLocationRamPointer - $C6E8;
|
|
StartX := StartWriteConnect;
|
|
StartY := 0;
|
|
EndX := (LoadedMapHeader.ConnectionData[0].WidthHeightVisiblePart - 1) + StartWriteConnect;
|
|
EndY := StartY + 3;
|
|
if (BlockX >= StartX) and (BlockY >= StartY) and (BlockX <= EndX) and (BlockY < EndY) then
|
|
begin
|
|
MapSelectCombo.ItemIndex := LoadedMapHeader.ConnectionData[0].MapNumber;
|
|
MapSelectComboChange(Sender);
|
|
end;
|
|
end;
|
|
|
|
// check if we are over a bottom connection
|
|
if (LoadedMapHeader.ConnectionDataControl and $04) = $04 then
|
|
begin
|
|
StartTileConnect := (LoadedMapHeader.ConnectionData[1].MapDataPointer - $4000) - (ConnectedMapHeaders[1].DataPointer - $4000);
|
|
StartWriteConnect := LoadedMapHeader.ConnectionData[1].MapLocationRamPointer - $C6E8;
|
|
StartX := StartWriteConnect - ((LoadedMapHeader.Width + 6) * (LoadedMapHeader.Height + 3));
|
|
StartY := StartWriteConnect div (LoadedMapHeader.Width + 6);
|
|
EndX := StartX + (LoadedMapHeader.ConnectionData[1].WidthHeightVisiblePart - 1);
|
|
EndY := StartY + 3;
|
|
if (BlockX >= StartX) and (BlockY >= StartY) and (BlockX <= EndX) and (BlockY < EndY) then
|
|
begin
|
|
MapSelectCombo.ItemIndex := LoadedMapHeader.ConnectionData[1].MapNumber;
|
|
MapSelectComboChange(Sender);
|
|
end;
|
|
end;
|
|
|
|
// Left
|
|
if (LoadedMapHeader.ConnectionDataControl and $02) = $02 then
|
|
begin
|
|
StartTileConnect := (LoadedMapHeader.ConnectionData[2].MapDataPointer - $4000) - (ConnectedMapHeaders[2].DataPointer - $4000);
|
|
StartWriteConnect := LoadedMapHeader.ConnectionData[2].MapLocationRamPointer - $C6E8;
|
|
StartX := 0;
|
|
StartY := StartWriteConnect div (LoadedMapHeader.Width + 6);
|
|
EndX := (StartX + 3) - 1;
|
|
EndY := StartY + LoadedMapHeader.ConnectionData[2].WidthHeightVisiblePart;
|
|
if (BlockX >= StartX) and (BlockY >= StartY) and (BlockX <= EndX) and (BlockY < EndY) then
|
|
begin
|
|
MapSelectCombo.ItemIndex := LoadedMapHeader.ConnectionData[2].MapNumber;
|
|
MapSelectComboChange(Sender);
|
|
end;
|
|
end;
|
|
|
|
// Right
|
|
if (LoadedMapHeader.ConnectionDataControl and $01) = $01 then
|
|
begin
|
|
StartTileConnect := (LoadedMapHeader.ConnectionData[3].MapDataPointer - $4000) - (ConnectedMapHeaders[3].DataPointer - $4000);
|
|
StartWriteConnect := LoadedMapHeader.ConnectionData[3].MapLocationRamPointer - $C6E8;
|
|
StartX := LoadedMapHeader.Width+3;
|
|
StartY := StartWriteConnect div (LoadedMapHeader.Width + 6);
|
|
EndX := (StartX + 3) - 1;
|
|
EndY := StartY + LoadedMapHeader.ConnectionData[3].WidthHeightVisiblePart;
|
|
if (BlockX >= StartX) and (BlockY >= StartY) and (BlockX <= EndX) and (BlockY < EndY) then
|
|
begin
|
|
MapSelectCombo.ItemIndex := LoadedMapHeader.ConnectionData[3].MapNumber;
|
|
MapSelectComboChange(Sender);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TMapEditorForm.MapBoxMouseMove(Sender: TObject; Shift: TShiftState; X,
|
|
Y: Integer);
|
|
var
|
|
StartTileConnect, StartWriteConnect: Integer;
|
|
StartX, StartY, EndX, EndY: Integer;
|
|
BlockX, BlockY: Integer;
|
|
begin
|
|
|
|
BlockX := X div 32;
|
|
BlockY := Y div 32;
|
|
|
|
//Get block number where cursor is
|
|
SelPic := ((Y div 32)-3) * LoadedMapHeader.Width + ((X div 32)-3);
|
|
|
|
//don't do anything with wrong coordinates
|
|
if (X < 0) or (Y < 0) or (SelPic >= (LoadedMapHeader.Width+3) * (LoadedMapHeader.Height+3)) then Exit;
|
|
|
|
shpHighlight.Width := 32+1;
|
|
shpHighlight.Height := 32+1;
|
|
shpHighlight.Top := MapBox.Top + ((Y div 32) * 32);
|
|
shpHighlight.Left := MapBox.Left + (X div 32) * 32;
|
|
|
|
if IsOutsideOfMapBounds(X, Y) = True then
|
|
begin
|
|
shpHighlight.Brush.Color := $80FF;
|
|
StatusBar1.Panels[0].Text := 'Border Tile (Read Only)';
|
|
MapBox.Cursor := crDrag;
|
|
|
|
// check if we are over a top connection
|
|
if (LoadedMapHeader.ConnectionDataControl and $08) = $08 then
|
|
begin
|
|
StartTileConnect := (LoadedMapHeader.ConnectionData[0].MapDataPointer - $4000) - (ConnectedMapHeaders[0].DataPointer - $4000);
|
|
StartWriteConnect := LoadedMapHeader.ConnectionData[0].MapLocationRamPointer - $C6E8;
|
|
StartX := StartWriteConnect;
|
|
StartY := 0;
|
|
EndX := (LoadedMapHeader.ConnectionData[0].WidthHeightVisiblePart - 1) + StartWriteConnect;
|
|
EndY := StartY + 3;
|
|
if (BlockX >= StartX) and (BlockY >= StartY) and (BlockX <= EndX) and (BlockY < EndY) then
|
|
begin
|
|
shpHighlight.Left := (StartX*32)-MapBox.Canvas.ClipRect.Left;
|
|
shpHighlight.Top := (StartY*32)-MapBox.Canvas.ClipRect.Top;
|
|
shpHighlight.Width := (LoadedMapHeader.ConnectionData[0].WidthHeightVisiblePart*32)+1;
|
|
shpHighlight.Height := (3*32)+1;
|
|
StatusBar1.Panels[0].Text := 'Connected Map #: ' + IntToStr(LoadedMapHeader.ConnectionData[0].MapNumber);
|
|
MapBox.Cursor := crHandPoint;
|
|
end;
|
|
end;
|
|
|
|
// check if we are over a bottom connection
|
|
if (LoadedMapHeader.ConnectionDataControl and $04) = $04 then
|
|
begin
|
|
StartTileConnect := (LoadedMapHeader.ConnectionData[1].MapDataPointer - $4000) - (ConnectedMapHeaders[1].DataPointer - $4000);
|
|
StartWriteConnect := LoadedMapHeader.ConnectionData[1].MapLocationRamPointer - $C6E8;
|
|
StartX := StartWriteConnect - ((LoadedMapHeader.Width + 6) * (LoadedMapHeader.Height + 3));
|
|
StartY := StartWriteConnect div (LoadedMapHeader.Width + 6);
|
|
EndX := StartX + (LoadedMapHeader.ConnectionData[1].WidthHeightVisiblePart - 1);
|
|
EndY := StartY + 3;
|
|
if (BlockX >= StartX) and (BlockY >= StartY) and (BlockX <= EndX) and (BlockY < EndY) then
|
|
begin
|
|
shpHighlight.Left := (StartX * 32) - MapBox.Canvas.ClipRect.Left;
|
|
shpHighlight.Top := (StartY * 32) - MapBox.Canvas.ClipRect.Top;
|
|
shpHighlight.Width := (LoadedMapHeader.ConnectionData[1].WidthHeightVisiblePart * 32)+1;
|
|
shpHighlight.Height := (3*32)+1;
|
|
StatusBar1.Panels[0].Text := 'Connected Map #: ' + IntToStr(LoadedMapHeader.ConnectionData[1].MapNumber);
|
|
MapBox.Cursor := crHandPoint;
|
|
end;
|
|
end;
|
|
|
|
// Left
|
|
if (LoadedMapHeader.ConnectionDataControl and $02) = $02 then
|
|
begin
|
|
StartTileConnect := (LoadedMapHeader.ConnectionData[2].MapDataPointer - $4000) - (ConnectedMapHeaders[2].DataPointer - $4000);
|
|
StartWriteConnect := LoadedMapHeader.ConnectionData[2].MapLocationRamPointer - $C6E8;
|
|
StartX := 0;
|
|
StartY := StartWriteConnect div (LoadedMapHeader.Width + 6);
|
|
EndX := (StartX + 3) - 1;
|
|
EndY := StartY + LoadedMapHeader.ConnectionData[2].WidthHeightVisiblePart;
|
|
if (BlockX >= StartX) and (BlockY >= StartY) and (BlockX <= EndX) and (BlockY < EndY) then
|
|
begin
|
|
shpHighlight.Left := (StartX * 32) - MapBox.Canvas.ClipRect.Left;
|
|
shpHighlight.Top := (StartY * 32) - MapBox.Canvas.ClipRect.Top;
|
|
shpHighlight.Width := (3*32)+1;
|
|
shpHighlight.Height := (LoadedMapHeader.ConnectionData[2].WidthHeightVisiblePart * 32)+1;
|
|
StatusBar1.Panels[0].Text := 'Connected Map #: ' + IntToStr(LoadedMapHeader.ConnectionData[2].MapNumber);
|
|
MapBox.Cursor := crHandPoint;
|
|
end;
|
|
end;
|
|
|
|
// Right
|
|
if (LoadedMapHeader.ConnectionDataControl and $01) = $01 then
|
|
begin
|
|
StartTileConnect := (LoadedMapHeader.ConnectionData[3].MapDataPointer - $4000) - (ConnectedMapHeaders[3].DataPointer - $4000);
|
|
StartWriteConnect := LoadedMapHeader.ConnectionData[3].MapLocationRamPointer - $C6E8;
|
|
StartX := LoadedMapHeader.Width+3;
|
|
StartY := StartWriteConnect div (LoadedMapHeader.Width + 6);
|
|
EndX := (StartX + 3) - 1;
|
|
EndY := StartY + LoadedMapHeader.ConnectionData[3].WidthHeightVisiblePart;
|
|
if (BlockX >= StartX) and (BlockY >= StartY) and (BlockX <= EndX) and (BlockY < EndY) then
|
|
begin
|
|
shpHighlight.Left := (StartX * 32) - MapBox.Canvas.ClipRect.Left;
|
|
shpHighlight.Top := (StartY * 32) - MapBox.Canvas.ClipRect.Top;
|
|
shpHighlight.Width := (3*32)+1;
|
|
shpHighlight.Height := (LoadedMapHeader.ConnectionData[3].WidthHeightVisiblePart * 32)+1;
|
|
StatusBar1.Panels[0].Text := 'Connected Map #: ' + IntToStr(LoadedMapHeader.ConnectionData[3].MapNumber);
|
|
MapBox.Cursor := crHandPoint;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
StatusBar1.Panels[0].Text := 'X: ' + IntToStr((X div 32)-3) +
|
|
' Y: ' + IntToStr((Y div 32)-3) +
|
|
' Block: $' + IntToHex(MapData[SelPic], 2) +
|
|
' Offset: $' + IntToHex(MapStart + SelPic, 2);
|
|
shpHighlight.Brush.Color := clLime;
|
|
MapBox.Cursor := crDrag;
|
|
end;
|
|
|
|
//If mouse left button is pressed block is changed
|
|
if Painting then
|
|
begin
|
|
MapData[SelPic] := SelBlock;
|
|
MapBox.Canvas.Draw(X div 32 * 32,Y div 32 * 32,BlockPics[SelBlock]);
|
|
//if grid is selected, add it
|
|
if Grid1.Checked then
|
|
MapBox.Canvas.Rectangle(X div 32 * 32, Y div 32 * 32,
|
|
X div 32 * 32 + 32, Y div 32 * 32 + 32);
|
|
end;
|
|
end;
|
|
|
|
procedure TMapEditorForm.MapBoxMouseUp(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
Painting := False;
|
|
end;
|
|
|
|
procedure TMapEditorForm.MapBoxPaint(Sender: TObject);
|
|
begin
|
|
DrawMap(MapBox.Canvas);
|
|
end;
|
|
|
|
procedure TMapEditorForm.MapSelectComboChange(Sender: TObject);
|
|
begin
|
|
LoadMap(MapSelectCombo.ItemIndex);
|
|
//Tab := PageControl1.ActivePageIndex;
|
|
//PageControl1.ActivePageIndex := Tab;
|
|
//MapBoxPaint(nil);
|
|
//MapBox.Invalidate;
|
|
//MapScrollBox.Refresh;
|
|
end;
|
|
|
|
function TMapEditorForm.IsOutsideOfMapBounds(X, Y: Integer): Boolean;
|
|
begin
|
|
if ((Y div 32) - 3 < 0) or ((X div 32) - 3 < 0)
|
|
or ((X div 32) - 3 >= LoadedMapHeader.Width) or ((Y div 32) - 3 >= LoadedMapHeader.Height) then
|
|
Result := True
|
|
else
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TMapEditorForm.Exit1Click(Sender: TObject);
|
|
begin
|
|
Close;
|
|
end;
|
|
|
|
procedure TMapEditorForm.SaveRom1Click(Sender: TObject);
|
|
begin
|
|
SaveRom(OpenRomDialog.FileName);
|
|
end;
|
|
|
|
procedure TMapEditorForm.SaveRom(FileName: string);
|
|
begin
|
|
if MapStart > 0 then
|
|
SaveMap;
|
|
//if (EventsAddr>0) then
|
|
// SaveEvents;
|
|
if PokemonStart > 0 then
|
|
SavePokemon;
|
|
Rom.SaveToFile(FileName);
|
|
RomModified := False;
|
|
end;
|
|
|
|
procedure TMapEditorForm.SaveMap;
|
|
begin
|
|
//write map data
|
|
Rom.Position := MapStart;
|
|
Rom.Write(MapData[0],LoadedMapHeader.Width * LoadedMapHeader.Height);
|
|
//save other stuff
|
|
//SaveEvents;
|
|
//SavePokemon;
|
|
MapModified := False;
|
|
RomModified := True;
|
|
end;
|
|
|
|
procedure TMapEditorForm.SavePokemon;
|
|
begin
|
|
if PokemonStart = 0 then
|
|
Exit;
|
|
|
|
if LandWildPkmn.Rate <> $00 then
|
|
begin
|
|
Rom.Position := PokemonStart;
|
|
Rom.Write(LandWildPkmn,SizeOf(TLandWildPkmn));
|
|
end;
|
|
if WaterWildPkmn.Rate <> $00 then
|
|
begin
|
|
if LandWildPkmn.Rate = $00 then
|
|
begin
|
|
Rom.Position := PokemonStart;
|
|
Rom.Write(WaterWildPkmn,SizeOf(TWaterWildPkmn));
|
|
end
|
|
else
|
|
begin
|
|
Rom.Position := PokemonStart + SizeOf(TLandWildPkmn);
|
|
Rom.Write(WaterWildPkmn,SizeOf(TWaterWildPkmn));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TMapEditorForm.LandReplaceBtnClick(Sender: TObject);
|
|
begin
|
|
LandWildPkmn.Pkmn[LandPkmnBox.ItemIndex].Number := LandPkmnCombo.ItemIndex;
|
|
LandWildPkmn.Pkmn[LandPkmnBox.ItemIndex].Level := LandPkmnLevel.Value;
|
|
UpdatePokemon;
|
|
MapModified := True;
|
|
end;
|
|
|
|
procedure TMapEditorForm.WaterReplaceBtnClick(Sender: TObject);
|
|
begin
|
|
WaterWildPkmn.Pkmn[WaterPkmnBox.ItemIndex].Number := WaterPkmnCombo.ItemIndex;
|
|
WaterWildPkmn.Pkmn[WaterPkmnBox.ItemIndex].Level := WaterPkmnLevel.Value;
|
|
UpdatePokemon;
|
|
MapModified := True;
|
|
end;
|
|
|
|
procedure TMapEditorForm.LandPkmnBoxClick(Sender: TObject);
|
|
begin
|
|
LandPkmnCombo.ItemIndex := LandWildPkmn.Pkmn[LandPkmnBox.ItemIndex].Number;
|
|
LandPkmnLevel.Value := LandWildPkmn.Pkmn[LandPkmnBox.ItemIndex].Level;
|
|
end;
|
|
|
|
procedure TMapEditorForm.WaterPkmnBoxClick(Sender: TObject);
|
|
begin
|
|
WaterPkmnCombo.ItemIndex := WaterWildPkmn.Pkmn[WaterPkmnBox.ItemIndex].Number;
|
|
WaterPkmnLevel.Value := WaterWildPkmn.Pkmn[WaterPkmnBox.ItemIndex].Level;
|
|
end;
|
|
|
|
procedure TMapEditorForm.LandRateTrackExit(Sender: TObject);
|
|
begin
|
|
LandWildPkmn.Rate := LandRateTrack.Position;
|
|
LandPercent.Caption := IntToStr(LandRateTrack.Position) + '%';
|
|
MapModified := True;
|
|
end;
|
|
|
|
procedure TMapEditorForm.WaterRateTrackExit(Sender: TObject);
|
|
begin
|
|
WaterWildPkmn.Rate := WaterRateTrack.Position;
|
|
WaterPercent.Caption := IntToStr(WaterRateTrack.Position) + '%';
|
|
MapModified := True;
|
|
end;
|
|
|
|
end.
|