Author Topic: Tile Based World Maker! (FIXED update 7)  (Read 5134 times)

0 Members and 1 Guest are viewing this topic.

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Tile Based World Maker! (FIXED update 7)
« on: November 23, 2021, 09:06:35 pm »
So I was fiddling with making a Program to create maps for a game and thought I might share it and see if you guys would want to create some custom maps?

Plus it could use some stress testing.

The interface is mouse based. Click and release, NOT CLICK AND DRAG.(although you can add to the map by clicking and dragging with left and right buttons, but not the middle button.)

To use, you click on a tile, then click the tile either in the BASE, DECO, or AUTOMATIC areas.

Left button allows selection of a tile from the tile list area to be placed in the BASE, DECO, or AUTOMATIC area.
Right button cancels the selection

In the Map grid:
Left button adds the DECO tile to the map.
Right button clears the DECO and restores the BASE tile.
Middle button places the AUTOMATIC area on the map. Now this has an issue if you click and drag, and it will cause errors.Fixed

The AUTOMATIC area allows you to pre-make a 3x3 area that can be used over and over. Right clicking in the AUTOMATIC area erases it.

The yellow box on the "Mini Map" shows what area you are currently working in. right now the Mini Map only shows the BASE tiles no DECO tiles. This may not change due to the Mini Map being a 256x256 render of the full map which is 8192x8192.(32:1 ratio)
(FYI: DECO is short for Decorations)

There are currently 960 tiles to choose from.
this is due to the limitations of image format sizes, BMP max out at roughly 32k px. and my imaging software maxes the PNG out at roughly 30k. (I will need to come up with a round about way to make it capable of larger sets)
Only the first 8 tiles can be used for the BASE.

Maps can be saved(and loaded!) with up to 32 character long names, leaving the name blank names it "DEFUALT" no spaces allowed. Extension is automatically set to ".MAP".  Can only save to the program directory at the moment.


I think that is it, tell me what you think!
(this requires a MFI file, so be sure to download it.)

Fixed an issue where the decorations would not draw correctly when you moved on the map.(11\24\2021)
Fixed an issue where the decorations displayed outside the map grid area(11\24\2021)
Added the ability to place SINGLE tiles straight to the map area. (as recommended by Bplus)
Added a 3rd layer to the placement of tiles for more depth.
Fixed issue with erasing decorations after moving in the map.(11/27/2021)

Video Demo:(outdated)
https://youtu.be/0K6pmuGXY-Q


« Last Edit: December 12, 2021, 02:36:09 pm by Cobalt »
Granted after becoming radioactive I only have a half-life!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Tile Based World Maker! (update 1)
« Reply #1 on: November 24, 2021, 11:52:32 am »
Seems to me the simplest thing would be to click a tile and click it onto map or Auto thing. Well it sticks to Auto thing but not the map??? And can't do anything with Auto thing?

I think if you want this to catch on you need the above fixed and an explanation of how to put an .MFI file together.

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Tile Based World Maker! (update 1)
« Reply #2 on: November 24, 2021, 01:11:57 pm »
And can't do anything with Auto thing?

What do you mean?

Seems to me the simplest thing would be to click a tile and click it onto map.

I have been tossing around this idea too. Just haven't committed to it yet.

Well it sticks to Auto thing but not the map???

If its not loaded into the DECO box it wont place on the map.
« Last Edit: November 24, 2021, 01:46:33 pm by Cobalt »
Granted after becoming radioactive I only have a half-life!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Tile Based World Maker! (update 2)
« Reply #3 on: November 24, 2021, 01:56:02 pm »
What do you mean?

I have been tossing around this idea too. Just haven't committed to it yet.

Well I read a little more of OP instructions and the Auto thing is controlled by middle button but on my mouse that is a wheel, no middle button, so there goes Auto thing :(

I would think it would go like this:
Click a Tile, it's highlighted

Click to your hearts content the map to put that tile. Select another tile repeat...

Advanced:
Select a section of the map and copy to paste over another section of the map to duplicate tiles in that section of map.

or Select a section of map and paste highlighted tile into all those places

or Select a section of map and paste highlighted tile into all those places that don't have tiles yet.

That way you could tile worlds a little bit faster than a tile at a time.

Just some ideas...



Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Tile Based World Maker! (update 2)
« Reply #4 on: November 24, 2021, 02:12:47 pm »
Well I read a little more of OP instructions and the Auto thing is controlled by middle button but on my mouse that is a wheel, no middle button, so there goes Auto thing :(

So on your mouse you can't depress the wheel to generate a click? Mine has the wheel but I can press on it to act like a button as well. Which is pretty much how every mouse I've had that used a scroll wheel, over the past 15-20 years, has worked. didn't know they made them otherwise. I might look into a hot key to use with the left button then. Perhaps CTRL.
Granted after becoming radioactive I only have a half-life!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Tile Based World Maker! (update 3)
« Reply #5 on: November 24, 2021, 02:57:49 pm »
Just standard issue Logitech mouse?

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Tile Based World Maker! (update 3)
« Reply #6 on: November 24, 2021, 04:37:20 pm »
Just standard issue Logitech mouse?

I literally cannot find any information on any Logitech mice that do not have the scroll wheel button.
Even the earliest models from the mid 90s had the button according to what I've just been reading.

But that, now that I'm thinking about it, is the original reason you could not just take the tile straight to the map area was because I originally was going to only use the LEFT and RIGHT buttons and you had to toggle between the auto build and the single placement. Then I thought 'why not just use the middle button for auto build placement?'. but never went back to being able to pick and place directly.

But the more I work with it, the more I am finding that I need to be able to place at least 3 layers worth of tiles, not just 2. and need to be able to split the tiles\sprites up better.

There is still a little screen real estate that I could add toggles too. And I'm not to sure just what good the mini map is doing really. so it may go the way of the dodo.
Granted after becoming radioactive I only have a half-life!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Tile Based World Maker! (update 3)
« Reply #7 on: November 24, 2021, 05:20:23 pm »
Well I'll be... never tried clicking anything with the scroll wheel before, guess it works.

And tiles work fine too, once they are in DECO thing.



Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Tile Based World Maker! (update 4)
« Reply #8 on: November 25, 2021, 11:05:17 pm »
Unfortunately the last modification breaks compatibility with previously created maps.
Granted after becoming radioactive I only have a half-life!

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Tile Based World Maker! (MAJOR update 6)
« Reply #9 on: December 05, 2021, 08:03:22 pm »
Ok, so there has been some MAJOR changes made to World Builder!

There is now a "Tile Tips" display by the mouse when you are hovering over the map area.
This displays: If the tile is Walkable
                    : The tile IDs for Base, Deco, and Layer 3
                    : If there is a Dialog, Chest, or Doorway special associated with the tile

You can now add Dialog, Chest, and Doorway specials to tiles!
Hold the Left Ctrl key and right click on a tile to bring up the options dialog.

Dialog- can be upto 255 characters long. Pressing ENTER will place a new line character in the dialog.
            (this is used within the world explorer program's dialog display function)

Chest- A small sample list of items(and images) can be picked from. The max count is 9999, and the item can be Trapped
           The item doesn't have to be in a 'chest' so-to-speak, as it could be a hidden item on the tile that has to be searched for, or a
           visible item just laying on the ground the player could pick up.

Doorway- This tell the game to 'teleport' the player to a new location on a specified map. It could be a building interior, cave,
                 town\castle, or just a new world map.

As suggested by @bplus :
You can now select a section of the map then Copy and Paste. (Experimental, seems functional 12\5\2021)
Holding the Left Shift then Left Click and drag on the map to select the tiles you want copied.
Holding the Right Shift then Left Click where you want to paste what was copied.
Pressing ESC will clear the current selection allowing for a new selection. This does not clear the copied data, so you can still Paste what you had copied until you make a new selection.


While these changes have changed the save file greatly, I believe I have found a way to still load previously made maps without losing data. Now this too is Experimental and may not work. Basic Trials have been successful though.(back up old .MAP files before hand to be safe)fixed, working correctly(12\7\2021)[now that the forum is back up for me to post the fix!]

Major error with the save(and load) routine, caused by 1 missing line(in both). There is no fix for maps already saved I'm afraid. Unless you know exactly how many dialogs+chests+doorways  are supposed to be in the map, and have a decent HEX editor to pop that INTEGER value into the correct location of the save file.(Lines added and fixed: 12\7\2021)

To Manually fix this issue, you must put the 2-byte value of the number of;Dialogs+Chests+Doorways; starting at location 655364

Minor bug: Tile tips fail to show Dialog, Chest, and Doorway status when loading a map(as of 12\7\2021)
The MFI has been updated with the Item sprites.(12/5/2021)


edit: error with the MFI file corrected. was showing 2.11mb instead of 537kb
* WorldBuilderBeta.MFI (Filesize: 536.18 KB, Downloads: 216)
« Last Edit: December 12, 2021, 02:36:56 pm by Cobalt »
Granted after becoming radioactive I only have a half-life!

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Tile Based World Maker! (FIXED update 7)
« Reply #10 on: December 12, 2021, 03:16:21 pm »
Found a whole slue of bugs from just one seemingly minor one. Things that catastrophically broke saved map loading. But they seem repaired, and were associated with the conversion process used when loading previously saved maps. Its funny how one(1) missed line can snow ball into an avalanche of issues. On top of adding a few features...

The whole layering system has been changed, there are now 9 possible layers for tiles:
0-Base tile: this is what all tiles default to, where the player can walk.
1 to 8- Decoration tiles: trees, weeds, crops, wells,doors,walls,beds,book shelves, ect. ect.

Layers can be set with the Option box above the mini-map or with the corresponding key on the keyboard (0-8). Layer 0 is still reserved for base tiles 0-7(for now!)
If you have a tile selected you can not change the layer until you place it somewhere, BUT you can use the keyboard to change placement layer with the tile still selected.

When creating a Doorway, if you leave the MAP blank it will teleport the player to the specified X and Y locations on the current map, if you specify the current map, it will save it then reload it, basically wasting time.

A new option and tool is the Manual Manipulation! this allows you to change the tiles on each layer at the same time, by typing in the tile ID directly. This can make 'hiding' something under other tiles easier.

That is pretty much it on the new and fixed side of things. A couple of ideas have presented themselves recently though.

One was an Idea presented by @STxAxTIC and @luke over on discord. This involved using real world maps of areas of the earth to pre-generate some of the map. While an interesting idea, that I may look into, it is honestly beyond the scope of this projects goal. The optimal map would be at a scale of 1-pixel to 1-meter(or yard) for the simplest conversion. If anybody can find that type of map a sample would be appreciated, for a possible future version 2.0 upgrade.

Another idea I am looking at is a change of the tile selection layout, by splitting up the tile list into Multiple lists. So each list would contain a more specific set of tiles;
Landscape tiles-Grass, sand, stone, trees & plants, Rocks, ect. ect.
Decoration tiles-Statues, fences, Fountains, ect. ect.
Household tiles-Beds, Tables, chairs, sinks, ect. ect.

This would allow for a larger tile base and easier selection of tiles. Lets face it scrolling through nearly 1000 tiles takes a while...
This change would be fairly easy to implement, but very time consuming to perform.

Code: QB64: [Select]
  1. 'World Builder V1.0
  2. '2021 Unikorn Produckions
  3. 'Cobalt
  4. 'with feature suggestions from Bplus
  5. 'Other reviews\suggestions welcome.
  6.  
  7. TYPE World_Tiles
  8.  Walkable AS _BYTE
  9.  Has_Dialog AS _BYTE
  10.  Has_Chest AS _BYTE
  11.  Has_Door AS _BYTE
  12.  
  13. TYPE Special_Tiles
  14.  Is_Dialog AS INTEGER 'Denotes any situation where dialog occurs; signs, graves, notes, NPCs
  15.  Is_Chest AS INTEGER 'Denotes any situation where player gains; money, items, ect
  16.  Is_Door AS INTEGER 'denotes a location where the map changes to the inside of a building or new location.
  17.  
  18. TYPE Item_Data
  19.  N AS STRING * 24
  20.  
  21. TYPE Program_Data
  22.  Selected_Base AS INTEGER
  23.  Selected_Deco AS INTEGER
  24.  Toggle_Walk AS _BYTE
  25.  Toggle_Layer_2 AS _BYTE
  26.  Toggle_Layer_3 AS _BYTE
  27.  Current_Layer AS _BYTE 'layer that tiles are being applied to
  28.  Walk_Block AS _BYTE 'toggles if the tile is walkable
  29.  Automatic AS INTEGER
  30.  List_Start AS INTEGER
  31.  Clicked_tile AS INTEGER
  32.  Mouse_over_R AS _BYTE 'Red value mouse is over
  33.  Mouse_over_G AS _BYTE 'Green Value Mouse is over
  34.  Mouse_over_B AS _BYTE 'Blue Value Mouse is over
  35.  World_X AS INTEGER 'current top left pos of map displayed
  36.  World_Y AS INTEGER
  37.  Last_File AS STRING * 32 'last file name Saved or Loaded
  38.  Quit AS _BYTE
  39.  AutoSave_Notice AS _BYTE
  40.  LCtrl_Down AS _BYTE 'is control key held down?
  41.  LShft_Down AS _BYTE 'Is the Left Shift Key held down? used to select & copy map area
  42.  RShft_Down AS _BYTE 'Is the Right Shift Key held down? used to paste copied map area(if any)
  43.  Special_Count AS INTEGER 'number of dialogs, chests, and Doors on map
  44.  Dialog_ID AS INTEGER 'the current number of Dialog tiles
  45.  Chest_ID AS INTEGER 'the current number of Chest tiles
  46.  Door_ID AS INTEGER 'the current number of Door tiles
  47.  Has_Selection AS _BYTE 'triggers whether or not the selection box shows
  48.  Selecting_Area AS _BYTE 'Triggered when user begins to select area
  49.  TmpStartX AS _BYTE 'top left corner of selection
  50.  TmpStartY AS _BYTE
  51.  TmpEndX AS _BYTE 'Bottom right corner of selection
  52.  TmpEndY AS _BYTE
  53.  Copied AS _BYTE 'is there a valid map copy in memory?
  54.  Copied_X AS _BYTE 'X size of copied area
  55.  Copied_Y AS _BYTE 'Y size of copied area
  56.  
  57. TYPE Chest_Data
  58.  Item_ID AS _BYTE
  59.  Count AS INTEGER
  60.  Trapped AS _BYTE
  61.  
  62. TYPE Door_Data
  63.  New_Loc_X AS _UNSIGNED _BYTE
  64.  New_Loc_Y AS _UNSIGNED _BYTE
  65.  New_Map AS STRING * 32
  66.  Facing AS _BYTE
  67.  
  68. SCREEN _NEWIMAGE(900, 640, 32)
  69. _DELAY .25
  70. _TITLE "World Builder V1.0"
  71.  
  72. CONST TRUE = -1, FALSE = NOT TRUE, Max_Tile = 960, MaxItems = 35
  73. CONST Key_Right = 19712, Key_Left = 19200, Key_Up = 18432, Key_Down = 20480
  74. CONST LCtrl = 100306, LShft = 100304, Rshft = 100303
  75.  
  76. CONST VerInfo = &HC0BA1102
  77. CONST OldVer = &HC0BA1101
  78.  
  79. DIM SHARED Layer(16) AS LONG, World(255, 255) AS World_Tiles, P AS Program_Data
  80. DIM SHARED TileLayer(255, 255, 8) AS INTEGER
  81. DIM SHARED Specials(3072) AS Special_Tiles, Dialogs(1024) AS STRING * 255
  82. DIM SHARED Chests(1024) AS Chest_Data, DoorWays(1024) AS Door_Data
  83. DIM SHARED Auto(2, 2) AS INTEGER, AST AS LONG, I(1024) AS Item_Data
  84. DIM SHARED Facing$(3), TempWorldCopy(15, 15) AS World_Tiles, TempLayerCopy(15, 15, 8) AS INTEGER
  85.  
  86. DATA "Nothing","Coins","Gems","Dagger","Book","Scroll","Bag","Sack","Rope","Envolope","Sword","Knife","Package","Lore Stone"
  87. DATA "Health Potion","Cure Potion","Rotten Potato","Smelly Sock","Stained Paper","Seeds","Pumpkins","Apples","Beans","Rice"
  88. DATA "Darts","Water Skin","Barrel","Iron Ingot","Gold Ingot","Wheel","Board","Key Ring","Jar","Mug","Bottle"
  89. ON TIMER(AST, 180) Auto_Save
  90.  
  91. FOR i%% = 1 TO MaxItems
  92.  READ I(i%%).N
  93. NEXT i%%
  94. Facing$(0) = "Down"
  95. Facing$(1) = "Left"
  96. Facing$(2) = "Right"
  97. Facing$(3) = "Up"
  98. Init_World_Maker
  99.  
  100.  Nul%% = _MOUSEINPUT
  101.  Check_Mouse_Over _MOUSEX, _MOUSEY
  102.  Check_Input
  103.  Mouse_Logic
  104.  '------------------Display Update--------------------------
  105.  Display_Tiles
  106.  Display_Map_Area 0, 0, Layer(1)
  107.  Display_Selected_Box
  108.  _PUTIMAGE , Layer(3), Layer(1)
  109.  Place_Mini_Map_Area_box
  110.  Display_Tile_Selection_Arrows
  111.  Display_Mini_Map_Arrows
  112.  Display_Load_Save_Buttons
  113.  Place_Toggle_Xs
  114.  Place_Current_Layer
  115.  IF P.AutoSave_Notice THEN AutoSave_Notice 'tell player map was autosaved
  116.  IF P.Clicked_tile THEN _PUTIMAGE (_MOUSEX - 15, _MOUSEY - 15), Layer(2), Layer(1), (0 + 32 * (P.Clicked_tile - 1), 0)-STEP(31, 31)
  117.  
  118.  IF (_MOUSEX > 31 AND _MOUSEX < 560) AND (_MOUSEY > 71 AND _MOUSEY < 600) THEN 'tile data 'tool' tip
  119.   IF P.Mouse_over_R > 0 AND P.Mouse_over_B > 0 THEN
  120.    Mouse_Over_Data _MOUSEX, _MOUSEY, P.World_X + P.Mouse_over_R - 1, P.World_Y + P.Mouse_over_B - 1
  121.   ELSE
  122.    _PRINTSTRING (620, 560), STR$(P.Mouse_over_R) + STR$(P.Mouse_over_B), Layer(1)
  123.   END IF
  124.  
  125.  
  126.  IF P.Has_Selection AND NOT _MOUSEBUTTON(1) THEN P.Has_Selection = Check_Selection_Valid 'confirm the selection was valid
  127.  '                                                                                        unless mousebutton down
  128.  IF P.Has_Selection THEN 'draw the selection box if valid selection area
  129.   _DEST Layer(1)
  130.   IF SBlink%% THEN L1% = 255: L2% = 32767 - 255 ELSE L2% = 255: L1% = 32767 - 255
  131.   LINE ((P.TmpStartX) * 33 + 31, (P.TmpStartY) * 33 + 71)-STEP(33 + P.TmpEndX * 33, 33 + P.TmpEndY * 33), _RGB32(160, 0, 0), B , L1% 'selection box start points
  132.   LINE ((P.TmpStartX) * 33 + 31, (P.TmpStartY) * 33 + 71)-STEP(33 + P.TmpEndX * 33, 33 + P.TmpEndY * 33), _RGB32(224, 224, 0), B , L2% 'selection box start points
  133.  _PRINTSTRING (620, 540), STR$(P.Mouse_over_R) + STR$(P.Mouse_over_B), Layer(1)
  134.  _PUTIMAGE , Layer(1), Layer(0)
  135.  ClearLayer Layer(1)
  136.  '-----------------------------------------------------------
  137.  S%% = S%% + 1
  138.  IF S%% = 8 THEN SBlink%% = NOT SBlink%%: S%% = 0
  139.  _LIMIT 60
  140.  Mouse_Clear
  141.  IF INKEY$ = CHR$(27) AND NOT P.Has_Selection THEN Exitflag%% = TRUE
  142.  IF P.Quit THEN Exitflag%% = TRUE
  143. LOOP UNTIL Exitflag%% = TRUE
  144. TIMER(AST) OFF
  145. '_DELAY 1
  146. 'SYSTEM
  147.  
  148.  
  149. SUB Mouse_Clear
  150.  DO: Nul%% = _MOUSEINPUT: LOOP WHILE Nul%%
  151.  
  152. SUB Mouse_Logic
  153.  '------------------------------Mouse Logic statements--------------------------------------
  154.  IF _MOUSEBUTTON(1) AND P.Mouse_over_R THEN
  155.   IF P.Clicked_tile = 0 THEN
  156.    IF NOT P.LShft_Down THEN 'if shift is down user is selecting an area to copy
  157.     IF NOT P.RShft_Down THEN 'if right shift is down user is placing a map copy
  158.      IF (_MOUSEX > 15 AND _MOUSEX < 659) AND (_MOUSEY > 15 AND _MOUSEY < 49) THEN 'only make selection when over the tile list
  159.       _MOUSEHIDE
  160.       P.Clicked_tile = P.List_Start + P.Mouse_over_R
  161.      ELSEIF (_MOUSEX > 31 AND _MOUSEX < 560) AND (_MOUSEY > 71 AND _MOUSEY < 600) THEN 'Placing a tile or auto on the map
  162.       IF P.Selected_Deco < 8 THEN
  163.        TileLayer(P.World_X + P.Mouse_over_R - 1, P.World_Y + P.Mouse_over_B - 1, P.Current_Layer) = P.Selected_Deco 'base tile placement(0-7 are base tiles)
  164.        World(P.World_X + P.Mouse_over_R - 1, P.World_Y + P.Mouse_over_B - 1).Walkable = TRUE
  165.       ELSEIF P.Current_Layer > 0 THEN 'can only place decorations on layers 1-8
  166.        TileLayer(P.World_X + P.Mouse_over_R - 1, P.World_Y + P.Mouse_over_B - 1, P.Current_Layer) = P.Selected_Deco
  167.        World(P.World_X + P.Mouse_over_R - 1, P.World_Y + P.Mouse_over_B - 1).Walkable = P.Toggle_Walk
  168.       ELSE
  169.        Display_Layer0_Error
  170.       END IF
  171.      END IF
  172.  
  173.      IF P.Mouse_over_R = 23 AND ((P.List_Start + 20) < Max_Tile) THEN P.List_Start = P.List_Start + 1: _DELAY .05
  174.      IF P.Mouse_over_R = 24 AND P.List_Start > 0 THEN P.List_Start = P.List_Start - 1: _DELAY .05
  175.      IF P.Mouse_over_R = 25 THEN Build_MAP: Place_Mini_Map: _DELAY .15
  176.      IF P.Mouse_over_R = 26 AND P.World_X >= 8 THEN P.World_X = P.World_X - 8: _DELAY .15: P.Has_Selection = FALSE
  177.      IF P.Mouse_over_R = 27 AND P.World_X < 240 THEN P.World_X = P.World_X + 8: _DELAY .15: P.Has_Selection = FALSE
  178.      IF P.Mouse_over_R = 28 AND P.World_Y >= 8 THEN P.World_Y = P.World_Y - 8: _DELAY .15: P.Has_Selection = FALSE
  179.      IF P.Mouse_over_R = 29 AND P.World_Y < 240 THEN P.World_Y = P.World_Y + 8: _DELAY .15: P.Has_Selection = FALSE
  180.      IF P.Mouse_over_R = 30 THEN New_Map
  181.      IF P.Mouse_over_R = 31 THEN Save_Map
  182.      IF P.Mouse_over_R = 32 THEN Load_Map
  183.      IF P.Mouse_over_R = 33 THEN P.Quit = TRUE
  184.      IF P.Mouse_over_R = 34 THEN P.Toggle_Walk = NOT P.Toggle_Walk: _DELAY .15 'tile walkable or non walkable
  185.      IF P.Mouse_over_R = 35 AND P.Current_Layer < 8 THEN P.Current_Layer = P.Current_Layer + 1: _DELAY .15 '
  186.      IF P.Mouse_over_R = 36 AND P.Current_Layer THEN P.Current_Layer = P.Current_Layer - 1: _DELAY .15 '
  187.     ELSEIF P.Copied THEN
  188.      'make sure user clicks in the map area.
  189.      IF (_MOUSEX > 31 AND _MOUSEX < 560) AND (_MOUSEY > 71 AND _MOUSEY < 600) THEN Paste_Map_Area P.Mouse_over_R - 1, P.Mouse_over_B - 1
  190.     END IF
  191.    ELSE
  192.     IF NOT P.Selecting_Area THEN
  193.      P.TmpStartX = P.Mouse_over_R - 1: P.TmpStartY = P.Mouse_over_B - 1: P.Selecting_Area = TRUE 'get the starting tile
  194.     ELSE
  195.      P.TmpEndX = P.Mouse_over_R - 1 - P.TmpStartX: P.TmpEndY = P.Mouse_over_B - 1 - P.TmpStartY 'allows click and drag selection(I hope)
  196.      IF P.TmpEndX >= 0 THEN P.Has_Selection = TRUE ELSE P.Has_Selection = FALSE
  197.     END IF
  198.    END IF
  199.   ELSEIF (_MOUSEX > 31 AND _MOUSEX < 560) AND (_MOUSEY > 71 AND _MOUSEY < 600) THEN 'Placing a tile directly to map area
  200.    'suggested Function by Bplus (a good idea for 1 off tile placement too! )
  201.    IF P.Current_Layer THEN 'layer 2 toggle is marked
  202.     TileLayer(P.World_X + P.Mouse_over_R - 1, P.World_Y + P.Mouse_over_B - 1, P.Current_Layer) = P.Clicked_tile - 1
  203.     World(P.World_X + P.Mouse_over_R - 1, P.World_Y + P.Mouse_over_B - 1).Walkable = P.Toggle_Walk
  204.     P.Clicked_tile = 0
  205.     _DELAY .1
  206.    ELSE
  207.     Display_Layer0_Error
  208.    END IF
  209.   ELSEIF (_MOUSEX > 787 AND _MOUSEX < 885) AND (_MOUSEY > 15 AND _MOUSEY < 116) THEN 'Placing a tile in the Auto Build area
  210.    Place_Auto_Tile
  211.   ELSEIF P.Mouse_over_R = 21 THEN
  212.    IF P.Clicked_tile <= 8 THEN
  213.     P.Selected_Base = P.Clicked_tile - 1 'only first 8 tiles(0-7) can be base
  214.     Change_Map_Base
  215.     P.Clicked_tile = 0
  216.    END IF
  217.   ELSEIF P.Mouse_over_R = 22 THEN
  218.    IF P.Selected_Base <> P.Clicked_tile - 1 THEN
  219.     P.Selected_Deco = P.Clicked_tile - 1 'deco can not be base
  220.     P.Clicked_tile = 0
  221.    END IF
  222.   END IF
  223.  
  224.   IF P.Clicked_tile THEN
  225.    P.Clicked_tile = 0
  226.    _DELAY .1
  227.   ELSEIF P.Mouse_over_R THEN
  228.    IF (_MOUSEX > 787 AND _MOUSEX < 885) AND (_MOUSEY > 15 AND _MOUSEY < 116) THEN 'reset the auto build area
  229.     Erase_Auto_Build
  230.    ELSEIF (_MOUSEX > 31 AND _MOUSEX < 560) AND (_MOUSEY > 71 AND _MOUSEY < 600) THEN 'remove a deco from the map
  231.     IF P.LCtrl_Down THEN 'unless user is holding Left ctrl key down
  232.      Popup_Menu 1
  233.     ELSE
  234.      TileLayer(P.World_X + P.Mouse_over_R - 1, P.World_Y + P.Mouse_over_B - 1, 0) = P.Selected_Base 'restore the base
  235.      FOR l% = 1 TO 8
  236.       TileLayer(P.World_X + P.Mouse_over_R - 1, P.World_Y + P.Mouse_over_B - 1, l%) = -1 'erase any DECOrations
  237.      NEXT l%
  238.     END IF
  239.    END IF
  240.   END IF
  241.  
  242.  IF _MOUSEBUTTON(3) THEN 'place the Auto Build area to map
  243.   IF (_MOUSEX > 31 AND _MOUSEX < 560) AND (_MOUSEY > 71 AND _MOUSEY < 600) THEN 'Placing a tile or auto on the map
  244.    IF P.Mouse_over_R THEN
  245.     IF P.Current_Layer THEN
  246.      Place_Auto_Build
  247.     ELSE 'Display error box, cannot place on layer 0
  248.      Display_Layer0_Error
  249.     END IF
  250.    END IF
  251.   END IF
  252.  '------------------------------------------------------------------------------------------
  253.  
  254. SUB Display_Map_Area (x%, y%, L&)
  255.  'display Map tile location numbers
  256.  FOR I% = 0 TO 15
  257.   Xo% = 48 - (8 * LEN(LTRIM$(STR$(x% + I% + P.World_X)))) \ 2
  258.   Yo% = 16 - (8 * LEN(LTRIM$(STR$(y% + I% + P.World_Y)))) \ 2
  259.   _PRINTSTRING (Xo% + 33 * I%, 58), LTRIM$(STR$(x% + I% + P.World_X)), L& 'x id
  260.   _PRINTSTRING (Yo%, 82 + 33 * I%), LTRIM$(STR$(y% + I% + P.World_Y)), L& 'y id
  261.  NEXT I%
  262.  'display base
  263.  FOR Iy% = 0 TO 15
  264.   FOR Ix% = 0 TO 15
  265.    Show_Tile 32 + 33 * Ix%, 72 + 33 * Iy%, TileLayer(x% + Ix% + P.World_X, y% + Iy% + P.World_Y, 0), 1, L&
  266.   NEXT Ix%
  267.  NEXT Iy%
  268.  'display Deco(ration)
  269.  FOR Il% = 0 TO 8
  270.   FOR Iy% = 0 TO 15
  271.    FOR Ix% = 0 TO 15
  272.     IF TileLayer(x% + Ix% + P.World_X, y% + Iy% + P.World_Y, Il%) THEN Show_Tile 32 + 33 * Ix%, 72 + 33 * Iy%, TileLayer(x% + Ix% + P.World_X, y% + Iy% + P.World_Y, Il%), 1, L&
  273.    NEXT Ix%
  274.   NEXT Iy%
  275.  NEXT Il%
  276.  
  277. SUB Change_Map_Base
  278.  FOR Y% = 0 TO 255
  279.   FOR X% = 0 TO 255
  280.    TileLayer(X%, Y%, 0) = P.Selected_Base
  281.   NEXT X%
  282.  NEXT Y%
  283.  
  284. SUB Build_Click_Layer
  285.  _DEST Layer(4)
  286.  'tile selection area
  287.  FOR I~%% = 0 TO 19
  288.   LINE (17 + I~%% * 32, 17)-STEP(31, 31), _RGB32(1 + I~%%, 0, 0), BF
  289.  NEXT I~%%
  290.  LINE (689, 17)-STEP(31, 31), _RGB32(21, 0, 0), BF 'selected base
  291.  LINE (737, 17)-STEP(31, 31), _RGB32(22, 0, 0), BF 'selected deco
  292.  LINE (661, 17)-STEP(15, 31), _RGB32(23, 0, 0), BF 'move tiles left(increase)
  293.  LINE (0, 17)-STEP(15, 31), _RGB32(24, 0, 0), BF 'Move tiles Right(decrease)
  294.  'mini map arrows+refresh
  295.  LINE (600, 392)-STEP(64, 18), _RGB32(25, 0, 0), BF 'Refresh
  296.  LINE (583, 244)-STEP(15, 31), _RGB32(26, 0, 0), BF 'move left
  297.  LINE (861, 244)-STEP(15, 31), _RGB32(27, 0, 0), BF 'Move Right
  298.  LINE (714, 114)-STEP(31, 15), _RGB32(28, 0, 0), BF 'move up
  299.  LINE (714, 390)-STEP(31, 15), _RGB32(29, 0, 0), BF 'Move down
  300.  
  301.  LINE (660, 460)-STEP(127, 31), _RGB32(30, 0, 0), BF 'new map
  302.  LINE (600, 500)-STEP(63, 15), _RGB32(31, 0, 0), BF 'save button
  303.  LINE (680, 500)-STEP(63, 15), _RGB32(32, 0, 0), BF 'load button
  304.  LINE (760, 500)-STEP(63, 15), _RGB32(33, 0, 0), BF 'Quit Button
  305.  
  306.  LINE (580, 54)-STEP(14, 14), _RGB32(34, 0, 0), BF 'walkable toggle
  307.  LINE (676, 72)-STEP(16, 9), _RGB32(35, 0, 0), BF 'layer up arrow
  308.  LINE (676, 82)-STEP(16, 9), _RGB32(36, 0, 0), BF 'layer down arrow
  309.  
  310.  'auto build area(Green denotes X cord, Blue denotes Y cord)
  311.  FOR Ay% = 0 TO 2
  312.   FOR Ax% = 0 TO 2
  313.    LINE (786 + Ax% * 33, 17 + Ay% * 33)-STEP(31, 31), _RGB32(1, 1 + Ax%, 1 + Ay%), BF
  314.   NEXT Ax%
  315.  NEXT Ay%
  316.  'main map area (red denotes X cord, Blue denotes Y cord)
  317.  FOR Iy% = 0 TO 15
  318.   FOR Ix% = 0 TO 15
  319.    LINE (32 + Ix% * 33, 72 + Iy% * 33)-STEP(31, 31), _RGB32(1 + Ix%, 0, 1 + Iy%), BF
  320.   NEXT Ix%
  321.  NEXT Iy%
  322.  _DEST Layer(0)
  323.  
  324. SUB Init_World_Maker
  325.  Layer(0) = _DISPLAY
  326.  Layer(1) = _NEWIMAGE(900, 640, 32) 'composite layer
  327.  ' Layer(2) = _LOADIMAGE("linear_tiles.bmp", 32) 'world tiles
  328.  Layer(3) = _NEWIMAGE(900, 640, 32) 'window setup
  329.  Layer(4) = _NEWIMAGE(900, 640, 32) 'Click layer
  330.  ' Layer(5) = _LOADIMAGE("arrows.bmp", 32) 'arrow tiles
  331.  Layer(6) = _NEWIMAGE(8192, 8192, 32) 'temp map for Mini Map display
  332.  Layer(7) = _NEWIMAGE(900, 640, 32) 'save\load window
  333.  
  334.  MFI_Loader "WorldBuilderBeta.MFI"
  335.  _CLEARCOLOR _RGB32(0), Layer(2)
  336.  _CLEARCOLOR _RGB32(0), Layer(5)
  337.  P.World_X = 0: P.World_Y = 0
  338.  
  339.  New_Map
  340.  
  341.  'Build Construction Screen
  342.  _DEST Layer(3)
  343.  Display_Tile_list_Section
  344.  Display_Auto_Build_Deco
  345.  Display_Selected_Base
  346.  Display_Selected_Deco
  347.  Display_Toggles
  348.  Display_Current_layer
  349.  Display_Mini_Map
  350.  Build_MAP
  351.  Place_Mini_Map
  352.  '-------------------------
  353.  _DEST Layer(0)
  354.  Build_Click_Layer
  355.  _SOURCE Layer(4)
  356.  P.Last_File = ""
  357.  P.Toggle_Walk = TRUE
  358.  P.Current_Layer = 0
  359.  TIMER(AST) ON
  360.  
  361. SUB Display_Tile_Selection_Arrows
  362.  IF P.List_Start > 0 THEN
  363.   IF P.Mouse_over_R <> 24 THEN
  364.    _PUTIMAGE (0, 17), Layer(5), Layer(1), (0, 32)-STEP(15, 31) 'left arrow(decending) Unlit
  365.   ELSE
  366.    _PUTIMAGE (0, 17), Layer(5), Layer(1), (0, 0)-STEP(15, 31) 'left arrow(decending) Lit
  367.   END IF
  368.  IF P.List_Start < Max_Tile - 20 AND P.Mouse_over_R <> 23 THEN
  369.   _PUTIMAGE (660, 17), Layer(5), Layer(1), (16, 32)-STEP(15, 31) 'right arrow(increasing) UnLit
  370.   _PUTIMAGE (660, 17), Layer(5), Layer(1), (16, 0)-STEP(15, 31) 'right arrow(increasing) Lit
  371.  
  372.  
  373. SUB Check_Mouse_Over (X%, Y%)
  374.  Test~& = POINT(X%, Y%) 'save a few cycles by just doing this once
  375.  IF _RED32(Test~&) THEN 'only bother if there is a red value(click areas all include a red base value of atleast 1)
  376.   P.Mouse_over_R = _RED32(Test~&) 'all click events
  377.   P.Mouse_over_G = _GREEN32(Test~&) 'for the auto build area
  378.   P.Mouse_over_B = _BLUE32(Test~&) 'for the map area
  379.   P.Mouse_over_R = 0
  380.   P.Mouse_over_G = 0
  381.   P.Mouse_over_B = 0
  382.  
  383. SUB Place_Auto_Tile
  384.  Auto(P.Mouse_over_G - 1, P.Mouse_over_B - 1) = P.Clicked_tile - 1
  385.  P.Clicked_tile = 0
  386.  
  387. SUB Mouse_ButtonDown_Hold
  388.  DO
  389.   nul%% = _MOUSEINPUT
  390.   ' _LIMIT 60
  391.  
  392. SUB Erase_Auto_Build
  393.  FOR Ay% = 0 TO 2
  394.   FOR Ax% = 0 TO 2
  395.    Auto(Ax%, Ay%) = 0
  396.   NEXT Ax%
  397.  NEXT Ay%
  398.  
  399. SUB Place_Auto_Build
  400.  FOR Ay% = 0 TO 2
  401.   FOR Ax% = 0 TO 2
  402.    IF Auto(Ax%, Ay%) THEN 'dont place blank tiles
  403.     IF P.Mouse_over_R - 1 + Ax% <= 15 AND P.Mouse_over_B - 1 + Ay% <= 15 THEN 'only place if tiles show in map area
  404.      TileLayer(P.World_X + P.Mouse_over_R - 1 + Ax%, P.World_Y + P.Mouse_over_B - 1 + Ay%, P.Current_Layer) = Auto(Ax%, Ay%)
  405.      World(P.World_X + P.Mouse_over_R - 1 + Ax%, P.World_Y + P.Mouse_over_B - 1 + Ay%).Walkable = FALSE
  406.     END IF
  407.    END IF
  408.   NEXT Ax%
  409.  NEXT Ay%
  410.  
  411. SUB Build_MAP
  412.  FOR L% = 0 TO 8
  413.   FOR Y% = 0 TO 255
  414.    FOR X% = 0 TO 255
  415.     IF TileLayer(X%, Y%, L%) >= 0 THEN Show_Tile X% * 32, Y% * 32, TileLayer(X%, Y%, L%), 1, Layer(6)
  416.    NEXT X%
  417.   NEXT Y%
  418.  NEXT L%
  419.  
  420. SUB Place_Mini_Map
  421.  _PUTIMAGE (602, 132)-STEP(255, 255), Layer(6), Layer(3)
  422.  
  423. SUB Place_Mini_Map_Area_box
  424.  _PUTIMAGE (602 + P.World_X, 132 + P.World_Y)-STEP(15, 15), Layer(5), Layer(1), (0, 64)-STEP(31, 31)
  425.  
  426. SUB Display_Mini_Map_Arrows
  427.  IF P.Mouse_over_R <> 26 THEN
  428.   _PUTIMAGE (583, 244), Layer(5), Layer(1), (0, 32)-STEP(15, 31) 'left arrow Unlit
  429.   _PUTIMAGE (583, 244), Layer(5), Layer(1), (0, 0)-STEP(15, 31) 'left arrow lit
  430.  IF P.Mouse_over_R <> 27 THEN
  431.   _PUTIMAGE (861, 244), Layer(5), Layer(1), (16, 32)-STEP(15, 31) 'right arrow UnLit
  432.   _PUTIMAGE (861, 244), Layer(5), Layer(1), (16, 0)-STEP(15, 31) 'right arrow Lit
  433.  IF P.Mouse_over_R <> 28 THEN
  434.   _PUTIMAGE (714, 114), Layer(5), Layer(1), (32, 32)-STEP(31, 15) 'up arrow Unlit
  435.   _PUTIMAGE (714, 114), Layer(5), Layer(1), (32, 0)-STEP(31, 15) 'up arrow lit
  436.  IF P.Mouse_over_R <> 29 THEN
  437.   _PUTIMAGE (714, 390), Layer(5), Layer(1), (32, 48)-STEP(31, 15) 'down arrow UnLit
  438.   _PUTIMAGE (714, 390), Layer(5), Layer(1), (32, 16)-STEP(31, 15) 'down arrow Lit
  439.  IF P.Mouse_over_R <> 25 THEN
  440.   _PUTIMAGE (600, 392)-STEP(64, 18), Layer(5), Layer(1), (32, 64)-STEP(15, 15) 'unlit(orange)
  441.   _PUTIMAGE (600, 392)-STEP(64, 18), Layer(5), Layer(1), (0, 64)-STEP(31, 31) 'lit(yellow)
  442.  
  443. SUB Place_Toggle_Xs
  444.  IF P.Toggle_Walk THEN
  445.   _PUTIMAGE (580, 55), Layer(5), Layer(1), (48, 64)-STEP(15, 15) 'place X
  446.  
  447. SUB Place_Current_Layer
  448.  _DEST Layer(1)
  449.  _PRINTSTRING (631, 74), LTRIM$(STR$(P.Current_Layer)), Layer(1)
  450.  COLOR _RGB32(255)
  451.  
  452. SUB New_Map
  453.  P.Selected_Deco = 0
  454.  Erase_Auto_Build
  455.  Reset_Map
  456.  P.Last_File = ""
  457.  Build_MAP
  458.  Place_Mini_Map
  459.  
  460. SUB AutoSave_Notice
  461.  STATIC Tim!
  462.  IF Tim! = 0 THEN Tim! = TIMER
  463.  IF Tim! + 3 > TIMER THEN
  464.   _PRINTSTRING (0, 620), "Auto saved...", Layer(1)
  465.   Tim! = 0
  466.   P.AutoSave_Notice = FALSE
  467.  
  468. SUB Mouse_Over_Data (Mx%, My%, Wx%, Wy%)
  469.  _DEST Layer(1)
  470.  COLOR _RGBA32(224, 224, 224, 192)
  471.  IF World(Wx%, Wy%).Has_Dialog THEN Extra%% = Extra%% + 1
  472.  IF World(Wx%, Wy%).Has_Chest THEN Extra%% = Extra%% + 1
  473.  IF World(Wx%, Wy%).Has_Door THEN Extra%% = Extra%% + 1
  474.  
  475.  FOR l%% = 0 TO 8
  476.   T$ = T$ + STR$(TileLayer(Wx%, Wy%, l%%))
  477.  NEXT l%%
  478.  LINE (8 + Mx%, 16 + My%)-STEP(10 + 8 * LEN(T$), 32 + 16 * Extra%%), _RGBA32(80, 80, 80, 104), BF
  479.  IF World(Wx%, Wy%).Walkable THEN W$ = "Walkable: YES" ELSE W$ = "Walkable: NO"
  480.  _PRINTSTRING (8 + Mx% + 5, 16 + My% + 2), W$
  481.  _PRINTSTRING (8 + Mx% + 5, 16 + My% + 18), T$
  482.  IF World(Wx%, Wy%).Has_Dialog THEN _PRINTSTRING (8 + Mx% + 5, 16 + My% + 34 + 16 * Ext%%), "Dialog " + STR$(Return_Special(0)): Ext%% = Ext%% + 1
  483.  IF World(Wx%, Wy%).Has_Chest THEN _PRINTSTRING (8 + Mx% + 5, 16 + My% + 34 + 16 * Ext%%), "Chest " + STR$(Return_Special(1)): Ext%% = Ext%% + 1
  484.  IF World(Wx%, Wy%).Has_Door THEN _PRINTSTRING (8 + Mx% + 5, 16 + My% + 34 + 16 * Ext%%), "Doorway " + STR$(Return_Special(2))
  485.  COLOR _RGB32(255)
  486.  _DEST Layer(0)
  487.  
  488. SUB Check_Input
  489.  IF _KEYDOWN(LCtrl) THEN P.LCtrl_Down = TRUE ELSE P.LCtrl_Down = FALSE
  490.  IF _KEYDOWN(LShft) THEN P.LShft_Down = TRUE: P.Copied = FALSE ELSE P.LShft_Down = FALSE: P.Selecting_Area = FALSE: IF Check_Selection_Valid AND (NOT P.Copied) THEN Copy_Map_Area
  491.  IF _KEYDOWN(Rshft) THEN P.RShft_Down = TRUE ELSE P.RShft_Down = FALSE
  492.  IF _KEYDOWN(27) THEN P.Has_Selection = FALSE 'remove selection
  493.  FOR i% = 0 TO 8
  494.   IF _KEYDOWN(48 + i%) THEN P.Current_Layer = i%
  495.  NEXT i%
  496.  
  497. SUB Popup_Menu (opt%%)
  498.  Mx% = _MOUSEX
  499.  My% = _MOUSEY
  500.  SELECT CASE opt%%
  501.   CASE 1
  502.    tmp& = _COPYIMAGE(Layer(0))
  503.    _DEST Layer(1)
  504.    _DELAY .1
  505.    DO
  506.     nul%% = _MOUSEINPUT
  507.     _PUTIMAGE , tmp&, Layer(1)
  508.     LINE (Mx% - 1, My% - 1)-STEP(97, 129), _RGBA32(64, 64, 64, 232), B
  509.     LINE (Mx%, My%)-STEP(95, 127), _RGBA32(160, 160, 160, 232), BF
  510.  
  511.     IF _MOUSEX > Mx% + 4 AND _MOUSEX < Mx% + 99 AND _MOUSEY > My% + 4 AND _MOUSEY < My% + 20 THEN 'highlight add dialog option
  512.      Selection%% = 1
  513.     ELSEIF _MOUSEX > Mx% + 4 AND _MOUSEX < Mx% + 99 AND _MOUSEY > My% + 24 AND _MOUSEY < My% + 40 THEN 'highlight add chest option
  514.      Selection%% = 2
  515.     ELSEIF _MOUSEX > Mx% + 4 AND _MOUSEX < Mx% + 99 AND _MOUSEY > My% + 44 AND _MOUSEY < My% + 60 THEN 'highlight add door option
  516.      Selection%% = 3
  517.     ELSEIF _MOUSEX > Mx% + 4 AND _MOUSEX < Mx% + 99 AND _MOUSEY > My% + 64 AND _MOUSEY < My% + 80 THEN 'highlight add door option
  518.      Selection%% = 4
  519.     ELSEIF _MOUSEX > Mx% + 4 AND _MOUSEX < Mx% + 99 AND _MOUSEY > My% + 104 AND _MOUSEY < My% + 120 THEN 'highlight close option
  520.      Selection%% = 5
  521.     ELSE
  522.      Selection%% = 0
  523.     END IF
  524.  
  525.     IF Selection%% = 1 THEN COLOR _RGB32(224, 224, 32) ELSE COLOR _RGB32(255)
  526.     _PRINTSTRING (Mx% + 4, My% + 4), "Add Dialog", Layer(1)
  527.     IF Selection%% = 2 THEN COLOR _RGB32(224, 224, 32) ELSE COLOR _RGB32(255)
  528.     _PRINTSTRING (Mx% + 4, My% + 24), "Add Chest", Layer(1)
  529.     IF Selection%% = 3 THEN COLOR _RGB32(224, 224, 32) ELSE COLOR _RGB32(255)
  530.     _PRINTSTRING (Mx% + 4, My% + 44), "Add Doorway", Layer(1)
  531.     IF Selection%% = 4 THEN COLOR _RGB32(224, 224, 32) ELSE COLOR _RGB32(255)
  532.     _PRINTSTRING (Mx% + 4, My% + 64), "Manipulate", Layer(1)
  533.     _PRINTSTRING (Mx% + 4, My% + 80), "     Layers", Layer(1)
  534.     IF Selection%% = 5 THEN COLOR _RGB32(224, 224, 32) ELSE COLOR _RGB32(255)
  535.     _PRINTSTRING (Mx% + 4, My% + 104), "Close... ", Layer(1)
  536.  
  537.      SELECT CASE Selection%%
  538.       CASE 1
  539.        Create_Dialog
  540.        ExitFlag%% = TRUE
  541.       CASE 2
  542.        Fill_Chest
  543.        ExitFlag%% = TRUE
  544.       CASE 3
  545.        Add_DoorWay
  546.        ExitFlag%% = TRUE
  547.       CASE 4
  548.        Change_Layers
  549.        ExitFlag%% = TRUE
  550.       CASE 5
  551.        ExitFlag%% = TRUE
  552.      END SELECT
  553.      _DELAY .15
  554.     END IF
  555.  
  556.     _PUTIMAGE , Layer(1), Layer(0)
  557.     IF INKEY$ = CHR$(27) THEN ExitFlag%% = TRUE
  558.     Mouse_Clear
  559.    LOOP UNTIL ExitFlag%%
  560.  _FREEIMAGE tmp&
  561.  
  562. SUB Create_Dialog
  563.  _DELAY .1
  564.  _PUTIMAGE , Layer(0), Layer(1) 'back up the screen then draw the window on top
  565.  LINE (220, 220)-STEP(299, 249), _RGBA32(64, 64, 64, 96), BF
  566.  LINE (199, 199)-STEP(301, 251), _RGB32(32), BF
  567.  LINE (200, 200)-STEP(299, 249), _RGB32(92), BF
  568.  LINE (201, 201)-STEP(297, 15), _RGB32(144), BF
  569.  _PRINTSTRING (350 - 12 * 4, 203), "Dialog Maker", Layer(1)
  570.  _PRINTSTRING (204, 224), "Dialog... ", Layer(1)
  571.  LINE (204, 240)-STEP(291, 181), _RGB32(160), BF
  572.  LINE (229, 429)-STEP(47, 17), _RGB32(32), B
  573.  LINE (230, 430)-STEP(45, 15), _RGB32(128), BF
  574.  LINE (389, 429)-STEP(67, 17), _RGB32(32), B
  575.  LINE (390, 430)-STEP(65, 15), _RGB32(128), BF
  576.  tmp& = _COPYIMAGE(Layer(1))
  577.  
  578.  'check for existing dialog in this location
  579.  IF World(P.World_X + P.Mouse_over_R - 1, P.World_Y + P.Mouse_over_B - 1).Has_Dialog THEN D$ = RTRIM$(Dialogs(Specials(Return_Special(0)).Is_Dialog))
  580.  
  581.  DO
  582.   nul%% = _MOUSEINPUT
  583.   _PUTIMAGE , tmp&, Layer(1)
  584.  
  585.   IF _MOUSEX > 230 AND _MOUSEX < 275 AND _MOUSEY > 430 AND _MOUSEY < 445 THEN 'highlight OK option
  586.    Selection%% = 1
  587.   ELSEIF _MOUSEX > 390 AND _MOUSEX < 455 AND _MOUSEY > 430 AND _MOUSEY < 445 THEN 'highlight Cancel option
  588.    Selection%% = 2
  589.   ELSE
  590.    Selection%% = 0
  591.   END IF
  592.  
  593.   IF Selection%% = 1 THEN COLOR _RGB32(224, 224, 32) ELSE COLOR _RGB32(255)
  594.   _PRINTSTRING (244, 430), "OK", Layer(1)
  595.   IF Selection%% = 2 THEN COLOR _RGB32(224, 224, 32) ELSE COLOR _RGB32(255)
  596.   _PRINTSTRING (400, 430), "Cancel", Layer(1)
  597.   COLOR _RGB32(255)
  598.  
  599.   KBD& = _KEYHIT
  600.   IF KBD& > 0 THEN
  601.    SELECT CASE KBD&
  602.     CASE 27 'esc (acts like cancel)
  603.      ExitFlag%% = TRUE
  604.     CASE 8 'back space
  605.      IF LEN(D$) THEN D$ = LEFT$(D$, LEN(D$) - 1)
  606.     CASE 13 'insert line break (chr(1)) adds 2 characters " "
  607.      IF LEN(D$) < 254 THEN D$ = D$ + CHR$(1) + " "
  608.     CASE 32 TO 127 '
  609.      IF LEN(D$) < 255 THEN D$ = D$ + CHR$(KBD&)
  610.    END SELECT
  611.   END IF
  612.  
  613.    SELECT CASE Selection%%
  614.     CASE 1 'OK
  615.      P.Dialog_ID = P.Dialog_ID + 1
  616.      P.Special_Count = P.Special_Count + 1
  617.      Specials(P.Special_Count).Xloc = P.Mouse_over_R - 1
  618.      Specials(P.Special_Count).Yloc = P.Mouse_over_B - 1
  619.      Specials(P.Special_Count).Is_Dialog = P.Dialog_ID
  620.      Dialogs(P.Dialog_ID) = D$
  621.      World(P.World_X + P.Mouse_over_R - 1, P.World_Y + P.Mouse_over_B - 1).Has_Dialog = TRUE
  622.      ExitFlag%% = TRUE
  623.     CASE 2 'Cancel
  624.      ExitFlag%% = TRUE
  625.    END SELECT
  626.    _DELAY .15
  627.   END IF
  628.  
  629.  
  630.   Row%% = LEN(D$) \ 36
  631.   IF L%% THEN Col%% = L%% ELSE Col%% = LEN(D$) MOD 36
  632.   IF Blink%% THEN _PRINTSTRING (206 + 8 * Col%%, 242 + 16 * Row%%), "_", Layer(1)
  633.   Bt%% = Bt%% + 1 'blink timer
  634.   IF Bt%% = 8 THEN Blink%% = NOT Blink%%: Bt%% = 0
  635.  
  636.   IF D$ <> "" THEN L%% = Display_Dialog_InBox(36, D$)
  637.   _PUTIMAGE , Layer(1), Layer(0)
  638.   Mouse_Clear
  639.   _LIMIT 60
  640.  LOOP UNTIL ExitFlag%%
  641.  
  642.  _FREEIMAGE tmp&
  643.  
  644.  
  645. FUNCTION Display_Dialog_InBox%% (MaxLen%%, Txt$)
  646.  STATIC Line$(10) 'max 10 lines of text
  647.  Temp$ = Txt$
  648.  DO
  649.   IF LEN(Temp$) > MaxLen%% THEN 'only bother if line is too long
  650.    T$ = MID$(Temp$, 1, MaxLen%%) 'get the starting text for a line
  651.    FOR i%% = MaxLen%% TO 1 STEP -1 'lets find a space toward the end
  652.     IF MID$(T$, i%%, 1) = " " THEN stp%% = i%%: i%% = 0
  653.    NEXT i%%
  654.    T$ = MID$(T$, 1, stp%% - 1) 'get the line minus the space
  655.    Temp$ = LTRIM$(MID$(Temp$, stp%% + 1)) 'reduce the text including the space
  656.    Line$(c%%) = T$ 'store the found line
  657.    c%% = c%% + 1 'next line
  658.   ELSE
  659.    Done%% = TRUE
  660.   END IF
  661.  LOOP UNTIL Done%%
  662.  Line$(c%%) = Temp$
  663.  FOR i%% = 0 TO c%%
  664.   _PRINTSTRING (206, 242 + 16 * i%%), Line$(i%%), Layer(1)
  665.  NEXT i%%
  666.  Display_Dialog_InBox = LEN(Line$(c%%))
  667.  
  668. SUB Fill_Chest
  669.  _DELAY .1
  670.  _PUTIMAGE , Layer(0), Layer(1) 'back up the screen then draw the window on top
  671.  _DEST Layer(1)
  672.  '---------------------Setup PopUp Window------------------------
  673.  LINE (140, 170)-STEP(399, 299), _RGBA32(64, 64, 64, 96), BF
  674.  LINE (119, 149)-STEP(401, 301), _RGB32(32), BF
  675.  LINE (120, 150)-STEP(399, 299), _RGB32(128), BF
  676.  LINE (121, 151)-STEP(397, 15), _RGB32(192), BF
  677.  _PRINTSTRING (325 - 12 * 4, 153), "Chest Maker", Layer(1)
  678.  _PRINTSTRING (158, 174), "Item...", Layer(1)
  679.  LINE (124, 190)-STEP(199, 229), _RGB32(224), BF
  680.  LINE (123, 189)-STEP(201, 231), _RGB32(92), B
  681.  'up arrow
  682.  LINE (307, 190)-STEP(16, 15), _RGB32(32), B
  683.  LINE (308, 191)-STEP(14, 13), _RGB32(112), BF
  684.  LINE (309, 200)-STEP(12, 0), _RGB32(224): LINE -(315, 194), _RGB32(224): LINE -(309, 200), _RGB32(224): PAINT (315, 197), _RGB32(224), _RGB32(224)
  685.  'Down arrow
  686.  LINE (307, 404)-STEP(16, 15), _RGB32(32), B
  687.  LINE (308, 405)-STEP(14, 13), _RGB32(112), BF
  688.  LINE (309, 410)-STEP(12, 0), _RGB32(224): LINE -(315, 416), _RGB32(224): LINE -(309, 410), _RGB32(224): PAINT (315, 413), _RGB32(224), _RGB32(224)
  689.  'Column
  690.  FOR i%% = 0 TO 15 STEP 2
  691.   LINE (307 + i%%, 206)-(307 + i%%, 403), _RGB32(160), , 43690
  692.   LINE (308 + i%%, 206)-(308 + i%%, 403), _RGB32(160), , 21845
  693.  NEXT i%%
  694.  LINE (307 + i%%, 206)-(307 + i%%, 403), _RGB32(160), , 43690
  695.  
  696.  _PRINTSTRING (338, 192), "Count", Layer(1)
  697.  LINE (386, 190)-STEP(116, 19), _RGB32(224), BF
  698.  'up arrow
  699.  LINE (486, 190)-STEP(16, 9), _RGB32(32), B
  700.  LINE (487, 191)-STEP(14, 7), _RGB32(112), BF
  701.  LINE (489, 197)-STEP(10, 0), _RGB32(224): LINE -(494, 192), _RGB32(224): LINE -(489, 197), _RGB32(224): PAINT (495, 195), _RGB32(224), _RGB32(224)
  702.  'down arrow
  703.  LINE (486, 200)-STEP(16, 9), _RGB32(32), B
  704.  LINE (487, 201)-STEP(14, 7), _RGB32(112), BF
  705.  LINE (489, 203)-STEP(10, 0), _RGB32(224): LINE -(494, 208), _RGB32(224): LINE -(489, 203), _RGB32(224): PAINT (495, 205), _RGB32(224), _RGB32(224)
  706.  
  707.  _PRINTSTRING (338, 222), "Trapped", Layer(1)
  708.  LINE (408, 220)-STEP(17, 17), _RGB32(16), BF
  709.  LINE (410, 222)-STEP(13, 13), _RGB32(144), BF
  710.  LINE (209, 429)-STEP(47, 17), _RGB32(32), B
  711.  LINE (210, 430)-STEP(45, 15), _RGB32(160), BF
  712.  LINE (369, 429)-STEP(67, 17), _RGB32(32), B
  713.  LINE (370, 430)-STEP(65, 15), _RGB32(160), BF
  714.  
  715.  LINE (358, 258)-STEP(131, 19), _RGB32(92), BF
  716.  LINE (359, 259)-STEP(129, 17), _RGB32(32), BF
  717.  LINE (360, 260)-STEP(127, 15), _RGB32(224), BF
  718.  LINE (359, 279)-STEP(129, 129), _RGB32(80), B
  719.  LINE (360, 280)-STEP(127, 127), _RGB32(144), BF
  720.  
  721.  tmp& = _COPYIMAGE(Layer(1))
  722.  ItemLoc% = 1
  723.  Hilite%% = 0
  724.  Item%% = 1
  725.  'check for existing chest in this location
  726.  Tag% = Specials(Return_Special(1)).Is_Chest
  727.  Item%% = Chests(Tag%).Item_ID
  728.  Count% = Chests(Tag%).Count
  729.  Trapped%% = Chests(Tag%).Trapped
  730.  '----------------------------------------------------------------
  731.  DO
  732.   nul%% = _MOUSEINPUT
  733.   _PUTIMAGE , tmp&, Layer(1)
  734.  
  735.   IF _MOUSEX > 210 AND _MOUSEX < 255 AND _MOUSEY > 430 AND _MOUSEY < 445 THEN 'highlight OK option
  736.    Selection%% = 1
  737.   ELSEIF _MOUSEX > 370 AND _MOUSEX < 435 AND _MOUSEY > 430 AND _MOUSEY < 445 THEN 'highlight Cancel option
  738.    Selection%% = 2
  739.   ELSEIF _MOUSEX > 408 AND _MOUSEX < 426 AND _MOUSEY > 220 AND _MOUSEY < 238 THEN 'trapped toggle
  740.    Selection%% = 3
  741.    LINE (408, 220)-STEP(17, 17), _RGB32(225, 225, 0), BF
  742.    LINE (410, 222)-STEP(13, 13), _RGB32(144), BF
  743.   ELSEIF _MOUSEX > 486 AND _MOUSEX < 502 AND _MOUSEY > 190 AND _MOUSEY < 200 THEN 'count up
  744.    Selection%% = 4
  745.    LINE (489, 197)-STEP(10, 0), _RGB32(224, 224, 16): LINE -(494, 192), _RGB32(224, 224, 16): LINE -(489, 197), _RGB32(224, 224, 16): PAINT (495, 195), _RGB32(224, 224, 16), _RGB32(224, 224, 16)
  746.   ELSEIF _MOUSEX > 486 AND _MOUSEX < 502 AND _MOUSEY > 201 AND _MOUSEY < 210 THEN ' count down
  747.    Selection%% = 5
  748.    LINE (489, 203)-STEP(10, 0), _RGB32(224, 224, 16): LINE -(494, 208), _RGB32(224, 224, 16): LINE -(489, 203), _RGB32(224, 224, 16): PAINT (495, 205), _RGB32(224, 224, 16), _RGB32(224, 224, 16)
  749.   ELSEIF _MOUSEX > 307 AND _MOUSEX < 324 AND _MOUSEY > 190 AND _MOUSEY < 206 THEN ' Item Up
  750.    Selection%% = 6
  751.    LINE (309, 200)-STEP(12, 0), _RGB32(224, 224, 16): LINE -(315, 194), _RGB32(224, 224, 16): LINE -(309, 200), _RGB32(224, 224, 16): PAINT (315, 197), _RGB32(224, 224, 16), _RGB32(224, 224, 16)
  752.   ELSEIF _MOUSEX > 307 AND _MOUSEX < 324 AND _MOUSEY > 404 AND _MOUSEY < 420 THEN ' Item down
  753.    Selection%% = 7
  754.    LINE (309, 410)-STEP(12, 0), _RGB32(224, 224, 16): LINE -(315, 416), _RGB32(224, 224, 16): LINE -(309, 410), _RGB32(224, 224, 16): PAINT (315, 413), _RGB32(224, 224, 16), _RGB32(224, 224, 16)
  755.   ELSEIF _MOUSEX > 386 AND _MOUSEX < 470 AND _MOUSEY > 190 AND _MOUSEY < 210 THEN ' Count input
  756.    Selection%% = 8
  757.   ELSE
  758.    Selection%% = 0
  759.   END IF
  760.  
  761.   FOR i%% = 0 TO 14
  762.    IF _MOUSEX > 125 AND _MOUSEX < 300 AND _MOUSEY > 193 + 15 * i%% AND _MOUSEY < 206 + 15 * i%% THEN Selection%% = 9 + i%%
  763.   NEXT i%%
  764.  
  765.   IF Selection%% = 1 THEN COLOR _RGB32(224, 224, 32) ELSE COLOR _RGB32(255)
  766.   _PRINTSTRING (224, 430), "OK", Layer(1)
  767.   IF Selection%% = 2 THEN COLOR _RGB32(224, 224, 32) ELSE COLOR _RGB32(255)
  768.   _PRINTSTRING (380, 430), "Cancel", Layer(1)
  769.   COLOR _RGB32(255)
  770.  
  771.   KBD& = _KEYHIT
  772.   IF KBD& > 0 THEN
  773.    SELECT CASE KBD&
  774.     CASE 27 'esc (acts like cancel)
  775.      ExitFlag%% = TRUE
  776.     CASE 8 'back space (only if user clicks in COUNT box)
  777.      IF LEN(C$) AND Cinput%% THEN C$ = LEFT$(C$, LEN(C$) - 1)
  778.     CASE 48 TO 57 '0-9 (only if user clicks in COUNT box)
  779.      IF LEN(C$) < 4 AND Cinput%% THEN C$ = C$ + CHR$(KBD&)
  780.      Count% = VAL(C$)
  781.     CASE Key_Up
  782.      IF ItemLoc% > 1 AND Linput%% THEN
  783.       ItemLoc% = ItemLoc% - 1
  784.      ELSEIF Linput%% AND Hilite%% > 0 THEN
  785.       Hilite%% = Hilite%% - 1
  786.      END IF
  787.      Item%% = Hilite%% + ItemLoc%
  788.     CASE Key_Down
  789.      IF ItemLoc% + 14 < MaxItems AND Linput%% THEN
  790.       ItemLoc% = ItemLoc% + 1
  791.      ELSEIF Linput%% AND Hilite%% < 14 THEN
  792.       IF Item%% THEN Hilite%% = Hilite%% + 1
  793.      END IF
  794.      Item%% = Hilite%% + ItemLoc%
  795.    END SELECT
  796.   END IF
  797.  
  798.    SELECT CASE Selection%%
  799.     CASE 1 'OK
  800.      World(P.World_X + P.Mouse_over_R - 1, P.World_Y + P.Mouse_over_B - 1).Has_Chest = TRUE
  801.      P.Chest_ID = P.Chest_ID + 1
  802.      P.Special_Count = P.Special_Count + 1
  803.      Specials(P.Special_Count).Xloc = P.Mouse_over_R - 1
  804.      Specials(P.Special_Count).Yloc = P.Mouse_over_B - 1
  805.      Specials(P.Special_Count).Is_Chest = P.Chest_ID
  806.      Chests(P.Chest_ID).Item_ID = Item%%
  807.      Chests(P.Chest_ID).Count = Count%
  808.      Chests(P.Chest_ID).Trapped = Trapped%%
  809.      ExitFlag%% = TRUE
  810.     CASE 2 'Cancel
  811.      ExitFlag%% = TRUE
  812.     CASE 3
  813.      Trapped%% = NOT Trapped%%
  814.      Cinput%% = FALSE
  815.      Linput%% = FALSE
  816.     CASE 4
  817.      IF Count% < 9998 THEN Count% = Count% + 1
  818.      Cinput%% = FALSE
  819.      Linput%% = FALSE
  820.     CASE 5
  821.      IF Count% > 1 THEN Count% = Count% - 1
  822.      Cinput%% = FALSE
  823.      Linput%% = FALSE
  824.     CASE 6
  825.      IF ItemLoc% > 1 THEN
  826.       ItemLoc% = ItemLoc% - 1
  827.       IF Item%% THEN Hilite%% = Hilite%% + 1
  828.      END IF
  829.      Cinput%% = FALSE
  830.      Linput%% = FALSE
  831.     CASE 7
  832.      IF ItemLoc% + 14 < MaxItems THEN
  833.       ItemLoc% = ItemLoc% + 1
  834.       IF Item%% THEN Hilite%% = Hilite%% - 1
  835.      END IF
  836.      Cinput%% = FALSE
  837.      Linput%% = FALSE
  838.     CASE 8
  839.      Cinput%% = NOT Cinput%%
  840.      Linput%% = FALSE
  841.     CASE 9 TO 23 'select item
  842.      Item%% = Selection%% - 9 + ItemLoc%
  843.      Hilite%% = Selection%% - 9
  844.      Cinput%% = FALSE
  845.      Linput%% = TRUE
  846.    END SELECT
  847.    _DELAY .15
  848.   END IF
  849.  
  850.  
  851.   IF Trapped%% THEN _PUTIMAGE (410, 222), Layer(5), Layer(1), (48, 64)-STEP(15, 15) 'place X
  852.   COLOR _RGB32(16)
  853.   _PRINTSTRING (390, 192), LTRIM$(STR$(Count%)), Layer(1)
  854.   IF Blink%% AND Cinput%% THEN _PRINTSTRING (390 + 8 * LEN(LTRIM$(STR$(Count%))), 192), "_", Layer(1)
  855.   IF Hilite%% >= 0 AND Hilite%% < 15 THEN 'hilite selected item if in display
  856.    LINE (124, 192 + 15 * Hilite%%)-STEP(174, 15), _RGBA32(0, 24, 192, 64), BF
  857.   END IF
  858.   FOR i%% = 0 TO 14
  859.    _PRINTSTRING (128, 192 + 15 * i%%), I(i%% + ItemLoc%).N, Layer(1)
  860.   NEXT i%%
  861.   IF Item%% THEN
  862.    _PRINTSTRING (361, 260), I(Item%%).N, Layer(1)
  863.    _PUTIMAGE (360, 280)-STEP(127, 127), Layer(8), Layer(1), (64 * (Item%% - 1), 0)-STEP(63, 63)
  864.   END IF
  865.   COLOR _RGB32(255)
  866.  
  867.   Bt%% = Bt%% + 1 'blink timer
  868.   IF Bt%% = 8 THEN Blink%% = NOT Blink%%: Bt%% = 0
  869.   _PUTIMAGE , Layer(1), Layer(0)
  870.   Mouse_Clear
  871.   _LIMIT 60
  872.  LOOP UNTIL ExitFlag%%
  873.  
  874.  _FREEIMAGE tmp&
  875.  
  876. SUB Add_DoorWay
  877.  _DEST Layer(1)
  878.  LINE (170, 220)-STEP(299, 199), _RGBA32(64, 64, 64, 96), BF
  879.  LINE (151, 201)-STEP(299, 199), _RGB32(128), BF
  880.  LINE (152, 202)-STEP(298, 18), _RGB32(0, 16, 192), BF 'title bar
  881.  _PRINTSTRING (300 - 8 * 9, 204), "Create Doorway", Layer(1)
  882.  LINE (169, 259)-STEP(251, 21), _RGB32(80), B 'File name box
  883.  LINE (170, 260)-STEP(249, 19), _RGB32(224), BF '"   "   "
  884.  _PRINTSTRING (170, 240), "File Name of New Map", Layer(1)
  885.  _PRINTSTRING (232, 288), "Starting Location", Layer(1)
  886.  _PRINTSTRING (180, 310), "X-", Layer(1)
  887.  LINE (199, 307)-STEP(65, 21), _RGB32(80), B 'X location
  888.  LINE (200, 308)-STEP(63, 19), _RGB32(224), BF '"   "   "
  889.  _PRINTSTRING (320, 310), "Y-", Layer(1)
  890.  LINE (339, 307)-STEP(65, 21), _RGB32(80), B 'Y location
  891.  LINE (340, 308)-STEP(63, 19), _RGB32(224), BF '"   "   "
  892.  _PRINTSTRING (210, 338), "Facing:", Layer(1)
  893.  LINE (274, 335)-STEP(81, 21), _RGB32(80), B 'Facing Direction
  894.  LINE (275, 336)-STEP(79, 19), _RGB32(224), BF '"   "   "
  895.  'Down arrow
  896.  LINE (337, 338)-STEP(16, 15), _RGB32(32), B
  897.  LINE (338, 339)-STEP(14, 13), _RGB32(180), BF
  898.  LINE (339, 343)-STEP(12, 0), _RGB32(96): LINE -(345, 349), _RGB32(96): LINE -(339, 343), _RGB32(96): PAINT (345, 345), _RGB32(64), _RGB32(96)
  899.  
  900.  LINE (312, 367)-STEP(79, 19), _RGB32(64), B 'Cancel button
  901.  LINE (313, 368)-STEP(77, 17), _RGB32(160), BF 'Cancel button
  902.  LINE (212, 367)-STEP(71, 19), _RGB32(64), B 'OK button
  903.  LINE (213, 368)-STEP(69, 17), _RGB32(160), BF 'OK button
  904.  Temp& = _COPYIMAGE(Layer(1))
  905.  COLOR _RGB32(16, 16, 16)
  906.  'check for existing Door in this location
  907.  IF World(P.World_X + P.Mouse_over_R - 1, P.World_Y + P.Mouse_over_B - 1).Has_Door THEN
  908.   Tag% = Specials(Return_Special(2)).Is_Door
  909.   XL$ = LTRIM$(STR$(DoorWays(Tag%).New_Loc_X))
  910.   YL$ = LTRIM$(STR$(DoorWays(Tag%).New_Loc_Y))
  911.   F$ = RTRIM$(DoorWays(Tag%).New_Map)
  912.   FI%% = DoorWays(Tag%).Facing
  913.  DO
  914.   _PUTIMAGE , Temp&, Layer(1)
  915.   Nul%% = _MOUSEINPUT
  916.   IF NOT DropList%% THEN
  917.    IF _MOUSEX > 312 AND _MOUSEX < 392 AND _MOUSEY > 367 AND _MOUSEY < 387 THEN
  918.     LINE (313, 368)-STEP(77, 17), _RGB32(96), BF 'Cancel button
  919.     Selection%% = 2
  920.    ELSEIF _MOUSEX > 212 AND _MOUSEX < 282 AND _MOUSEY > 367 AND _MOUSEY < 387 THEN
  921.     LINE (213, 368)-STEP(69, 17), _RGB32(96), BF: over%% = 2 'OK button
  922.     Selection%% = 1
  923.    ELSEIF _MOUSEX > 171 AND _MOUSEX < 320 AND _MOUSEY > 260 AND _MOUSEY < 280 THEN 'File input
  924.     Selection%% = 3
  925.    ELSEIF _MOUSEX > 199 AND _MOUSEX < 263 AND _MOUSEY > 308 AND _MOUSEY < 328 THEN 'X Location input
  926.     Selection%% = 4
  927.    ELSEIF _MOUSEX > 333 AND _MOUSEX < 397 AND _MOUSEY > 308 AND _MOUSEY < 328 THEN 'Y location input
  928.     Selection%% = 5
  929.  
  930.    ELSEIF _MOUSEX > 338 AND _MOUSEX < 353 AND _MOUSEY > 339 AND _MOUSEY < 353 THEN 'drop down Facing list
  931.     LINE (338, 339)-STEP(14, 13), _RGB32(144), BF
  932.     LINE (339, 343)-STEP(12, 0), _RGB32(224, 224, 16): LINE -(345, 349), _RGB32(224, 224, 16): LINE -(339, 343), _RGB32(224, 224, 16): PAINT (345, 345), _RGB32(224, 224, 16), _RGB32(224, 224, 16)
  933.     Selection%% = 6
  934.    ELSE
  935.     Selection%% = 0
  936.    END IF
  937.   ELSE
  938.    FOR i%% = 0 TO 3
  939.     IF _MOUSEX > 276 AND _MOUSEX < 340 AND _MOUSEY > 338 + 15 * i%% AND _MOUSEY < 354 + 15 * i%% THEN
  940.      Selection%% = 7 + i%%
  941.      HlF%% = i%%
  942.      i%% = 4
  943.     ELSE
  944.      Selection%% = 0
  945.      HlF%% = -1
  946.     END IF
  947.    NEXT i%%
  948.   END IF
  949.  
  950.   KBD& = _KEYHIT
  951.   IF KBD& > 0 THEN
  952.    SELECT CASE KBD&
  953.     CASE 27 'esc
  954.      ExitFlag%% = TRUE
  955.     CASE 8 'back space
  956.      IF Finput%% AND LEN(F$) THEN F$ = LEFT$(F$, LEN(F$) - 1)
  957.      IF CinputX%% AND LEN(XL$) THEN XL$ = LEFT$(XL$, LEN(XL$) - 1) 'X start location input
  958.      IF CinputY%% AND LEN(YL$) THEN YL$ = LEFT$(YL$, LEN(YL$) - 1) 'Y start location input
  959.     CASE 33 TO 127 'no spaces allowed
  960.      IF Finput%% AND LEN(F$) < 32 THEN F$ = F$ + CHR$(KBD&)
  961.      IF CinputX%% AND LEN(XL$) < 3 THEN XL$ = XL$ + CHR$(KBD&)
  962.      IF CinputY%% AND LEN(YL$) < 3 THEN YL$ = YL$ + CHR$(KBD&)
  963.      IF VAL(XL$) > 254 THEN XL$ = "254"
  964.      IF VAL(YL$) > 254 THEN YL$ = "254"
  965.    END SELECT
  966.   END IF
  967.  
  968.    SELECT CASE Selection%%
  969.     CASE 1 'Ok
  970.      World(P.World_X + P.Mouse_over_R - 1, P.World_Y + P.Mouse_over_B - 1).Has_Door = TRUE
  971.      P.Door_ID = P.Door_ID + 1
  972.      P.Special_Count = P.Special_Count + 1
  973.      Specials(P.Special_Count).Xloc = P.Mouse_over_R - 1
  974.      Specials(P.Special_Count).Yloc = P.Mouse_over_B - 1
  975.      Specials(P.Special_Count).Is_Door = P.Door_ID
  976.      DoorWays(P.Door_ID).New_Loc_X = VAL(XL$)
  977.      DoorWays(P.Door_ID).New_Loc_Y = VAL(YL$)
  978.      DoorWays(P.Door_ID).New_Map = F$
  979.      DoorWays(P.Door_ID).Facing = FI%%
  980.      ExitFlag%% = TRUE
  981.     CASE 2 'Cancel
  982.      ExitFlag%% = TRUE
  983.     CASE 3 'Enter map name
  984.      Finput%% = TRUE
  985.      CinputX%% = FALSE
  986.      CinputY%% = FALSE
  987.      DropList%% = FALSE
  988.     CASE 4 'Enter X starting location
  989.      Finput%% = FALSE
  990.      CinputX%% = TRUE
  991.      CinputY%% = FALSE
  992.      DropList%% = FALSE
  993.     CASE 5 'Enter Y starting location
  994.      Finput%% = FALSE
  995.      CinputX%% = FALSE
  996.      CinputY%% = TRUE
  997.      DropList%% = FALSE
  998.     CASE 6 'Enter Facing Direction
  999.      Finput%% = FALSE
  1000.      CinputX%% = FALSE
  1001.      CinputY%% = FALSE
  1002.      DropList%% = TRUE
  1003.     CASE 7 TO 10 'Select facing direction
  1004.      DropList%% = FALSE
  1005.      FI%% = HlF%% 'Facing Indicator =  Hilited Facing direction
  1006.     CASE ELSE 'Cancel Facing Drop down list.
  1007.      IF DropList%% THEN DropList%% = FALSE
  1008.    END SELECT
  1009.    _DELAY .1
  1010.   END IF
  1011.  
  1012.   _PRINTSTRING (330, 370), "Cancel", Layer(1)
  1013.   _PRINTSTRING (240, 370), "OK", Layer(1)
  1014.   _PRINTSTRING (174, 263), F$ + ".MAP", Layer(1)
  1015.   _PRINTSTRING (280, 338), Facing$(FI%%), Layer(1)
  1016.   IF VAL(XL$) = 0 THEN Dx% = 1 ELSE Dx% = VAL(XL$) 'value check on start locations, 0 is invalid so adjust to 1
  1017.   IF VAL(YL$) = 0 THEN Dy% = 1 ELSE Dy% = VAL(YL$) '  "    "    "
  1018.  
  1019.   _PRINTSTRING (202, 310), LTRIM$(STR$(Dx%)), Layer(1)
  1020.   _PRINTSTRING (342, 310), LTRIM$(STR$(Dy%)), Layer(1)
  1021.   IF Blink%% AND Finput%% THEN _PRINTSTRING (174 + 8 * LEN(F$), 263), "_", Layer(1)
  1022.   IF Blink%% AND CinputX%% THEN _PRINTSTRING (202 + 8 * LEN(XL$), 310), "_", Layer(1)
  1023.   IF Blink%% AND CinputY%% THEN _PRINTSTRING (342 + 8 * LEN(YL$), 310), "_", Layer(1)
  1024.  
  1025.   IF DropList%% THEN
  1026.    LINE (274, 335)-STEP(83, 72), _RGBA32(80, 80, 80, 80), BF 'Facing Direction
  1027.    LINE (275, 336)-STEP(79, 68), _RGB32(224), BF '"   "   "
  1028.    FOR i%% = 0 TO 3
  1029.     IF Selection%% AND HlF%% = i%% THEN LINE (275, 336 + 17 * i%%)-STEP(79, 16), _RGBA32(10, 10, 180, 80), BF 'Facing Direction hilite
  1030.     _PRINTSTRING (280, 339 + 16 * i%%), Facing$(i%%), Layer(1)
  1031.    NEXT i%%
  1032.   END IF
  1033.  
  1034.   _PUTIMAGE , Layer(1), Layer(0)
  1035.   Mouse_Clear
  1036.   Bt%% = Bt%% + 1 'blink timer
  1037.   IF Bt%% = 8 THEN Blink%% = NOT Blink%%: Bt%% = 0
  1038.   _LIMIT 60
  1039.  LOOP UNTIL ExitFlag%%
  1040.  _FREEIMAGE Temp&
  1041.  COLOR _RGB32(255)
  1042.  
  1043. SUB Copy_Map_Area
  1044.  'Experimental: Copy a section of the map to be pasted else where
  1045.  'Suggested by Bplus
  1046.  
  1047.  '-------------Erase Temp Area---------------
  1048.  FOR l% = 1 TO 7
  1049.   FOR y% = 0 TO 15
  1050.    FOR x% = 0 TO 15
  1051.     TempLayerCopy(x%, y%, 0) = P.Selected_Base
  1052.     TempLayerCopy(x%, y%, l%) = -1
  1053.     TempWorldCopy(x%, y%).Walkable = 0
  1054.     TempWorldCopy(x%, y%).Has_Dialog = 0
  1055.     TempWorldCopy(x%, y%).Has_Chest = 0
  1056.     TempWorldCopy(x%, y%).Has_Door = 0
  1057.    NEXT x%
  1058.   NEXT y%
  1059.  NEXT l%
  1060.  '--------------------------------------------
  1061.  FOR l%% = 0 TO 8
  1062.   FOR Iy%% = 0 TO P.TmpStartY + P.TmpEndY
  1063.    FOR Ix%% = 0 TO P.TmpStartX + P.TmpEndX
  1064.     TempWorldCopy(Ix%%, Iy%%) = World(P.World_X + P.TmpStartX + Ix%%, P.World_Y + P.TmpStartY + Iy%%) 'copy the extra data
  1065.     TempLayerCopy(Ix%%, Iy%%, l%%) = TileLayer(P.World_X + P.TmpStartX + Ix%%, P.World_Y + P.TmpStartY + Iy%%, l%%) 'copy the tile data
  1066.    NEXT Ix%%
  1067.   NEXT Iy%%
  1068.  NEXT l%%
  1069.  P.Copied = TRUE
  1070.  P.Copied_X = P.TmpEndX 'Size of the copied area
  1071.  P.Copied_Y = P.TmpEndY
  1072.  
  1073. SUB Paste_Map_Area (Start_X%%, Start_Y%%)
  1074.  'Experimental: Paste a section of the map copied from else where
  1075.  'Suggested by Bplus
  1076.  FOR l%% = 0 TO 8
  1077.   FOR Iy%% = 0 TO P.Copied_Y
  1078.    FOR Ix%% = 0 TO P.Copied_X
  1079.     IF TempLayerCopy(Ix%%, Iy%%, l%%) <> 0 THEN 'paste if there is tiledata to paste(non-0)
  1080.      TileLayer(P.World_X + P.TmpStartX + Ix%%, P.World_Y + P.TmpStartY + Iy%%, l%%) = TempLayerCopy(Ix%%, Iy%%, l%%)
  1081.      World(Start_X%% + P.World_X + Ix%%, Start_Y%% + P.World_Y + Iy%%) = TempWorldCopy(Ix%%, Iy%%)
  1082.     END IF
  1083.    NEXT Ix%%
  1084.   NEXT Iy%%
  1085.  NEXT l%%
  1086.  
  1087. FUNCTION Check_Selection_Valid%%
  1088.  Result%% = TRUE
  1089.  'end x and y must be greater than start x and y for selection to be valid
  1090.  IF P.TmpStartX + P.TmpEndX <= P.TmpStartX AND P.TmpStartY + P.TmpEndY <= P.TmpStartY THEN Result%% = FALSE
  1091.  Check_Selection_Valid = Result%%
  1092.  
  1093. SUB Reset_Map
  1094.  'Erases all map related data
  1095.  FOR y% = 0 TO 255
  1096.   FOR x% = 0 TO 255
  1097.    TileLayer(x%, y%, 0) = 0
  1098.    World(x%, y%).Walkable = TRUE
  1099.    World(x%, y%).Has_Dialog = FALSE
  1100.    World(x%, y%).Has_Chest = FALSE
  1101.    World(x%, y%).Has_Door = FALSE
  1102.   NEXT x%
  1103.  NEXT y%
  1104.  FOR l% = 1 TO 8
  1105.   FOR y% = 0 TO 255
  1106.    FOR x% = 0 TO 255
  1107.     TileLayer(x%, y%, l%) = -1
  1108.    NEXT x%
  1109.   NEXT y%
  1110.  NEXT l%
  1111.  P.World_X = 0
  1112.  P.World_Y = 0
  1113.  P.List_Start = 0
  1114.  P.Toggle_Walk = TRUE
  1115.  P.Current_Layer = 0
  1116.  P.Has_Selection = FALSE
  1117.  P.Special_Count = FALSE
  1118.  P.Selected_Base = 0
  1119.  P.Selected_Deco = 0
  1120.  P.Dialog_ID = 0
  1121.  P.Chest_ID = 0
  1122.  P.Door_ID = 0
  1123.  FOR i% = 1 TO 3072 'erase specials
  1124.   Specials(i%) = Specials(0)
  1125.  NEXT i%
  1126.  FOR i% = 1 TO 1024 'erase dialogs, chests, and doorways
  1127.   Dialogs(i%) = ""
  1128.   Chests(i%) = Chests(0)
  1129.   DoorWays(i%) = DoorWays(0)
  1130.  NEXT i%
  1131.  
  1132. SUB Display_Layer0_Error
  1133.  tmp& = _COPYIMAGE(Layer(0))
  1134.  _DEST tmp&
  1135.  LINE (310, 210)-STEP(200, 100), _RGBA32(32, 32, 32, 64), BF
  1136.  LINE (300, 200)-STEP(200, 100), _RGB32(192), BF
  1137.  LINE (300, 200)-STEP(200, 100), _RGB32(96), B
  1138.  _PRINTSTRING (340, 226), "Cannot place on", tmp&
  1139.  _PRINTSTRING (344, 242), "layer 0 (base)", tmp&
  1140.  LINE (374, 279)-STEP(47, 17), _RGB32(32), B
  1141.  LINE (375, 280)-STEP(45, 15), _RGB32(128), BF
  1142.  _PRINTSTRING (390, 281), "OK", tmp&
  1143.  _DEST Layer(1)
  1144.  DO
  1145.   nul%% = _MOUSEINPUT
  1146.   _PUTIMAGE , tmp&, Layer(1)
  1147.   IF _MOUSEX > 375 AND _MOUSEX < 421 AND _MOUSEY > 280 AND _MOUSEY < 296 THEN Selection%% = 1 ELSE Selection%% = 0
  1148.   IF Selection%% = 1 THEN COLOR _RGB32(224, 224, 32) ELSE COLOR _RGB32(255)
  1149.   _PRINTSTRING (390, 281), "OK", Layer(1)
  1150.   IF _MOUSEBUTTON(1) AND Selection%% = 1 THEN Exitflag%% = TRUE
  1151.   _PUTIMAGE , Layer(1), Layer(0)
  1152.   _LIMIT 60
  1153.   Mouse_Clear
  1154.  LOOP UNTIL Exitflag%%
  1155.  _FREEIMAGE tmp&
  1156.  
  1157. SUB Change_Layers
  1158.  DIM Layer_Values(8) AS INTEGER
  1159.  _DEST Layer(1)
  1160.  LINE (160, 210)-STEP(299, 239), _RGBA32(32, 32, 32, 96), BF
  1161.  LINE (150, 200)-STEP(299, 239), _RGB32(96), BF
  1162.  LINE (150, 200)-STEP(299, 239), _RGB32(32), B
  1163.  LINE (151, 201)-STEP(297, 15), _RGB32(0, 8, 240), BF
  1164.  _PRINTSTRING (300 - 8 * 12.5, 202), "Manual Layer Manipulation", Layer(1)
  1165.  _PRINTSTRING (159, 226), "Base", Layer(1)
  1166.  
  1167.  FOR I%% = 0 TO 8
  1168.   LINE (199, 225 + 20 * I%%)-STEP(59, 16), _RGB32(240), BF
  1169.   IF I%% THEN _PRINTSTRING (164, 226 + 20 * I%%), STR$(I%%), Layer(1)
  1170.   LINE (244, 225 + 20 * I%%)-STEP(14, 8), _RGB32(32), B 'up arrow
  1171.   LINE (245, 226 + 20 * I%%)-STEP(12, 6), _RGB32(112), BF
  1172.   LINE (247, 231 + 20 * I%%)-STEP(8, 0), _RGB32(224): LINE -(251, 227 + 20 * I%%), _RGB32(224): LINE -(247, 231 + 20 * I%%), _RGB32(224): PAINT (251, 229 + 20 * I%%), _RGB32(224), _RGB32(224)
  1173.   LINE (244, 233 + 20 * I%%)-STEP(14, 8), _RGB32(32), B 'down arrow
  1174.   LINE (245, 234 + 20 * I%%)-STEP(12, 6), _RGB32(112), BF
  1175.   LINE (247, 235 + 20 * I%%)-STEP(8, 0), _RGB32(224): LINE -(251, 239 + 20 * I%%), _RGB32(224): LINE -(247, 235 + 20 * I%%), _RGB32(224): PAINT (251, 237 + 20 * I%%), _RGB32(224), _RGB32(224)
  1176.   Layer_Values(I%%) = TileLayer(P.World_X + P.Mouse_over_R - 1, P.World_Y + P.Mouse_over_B - 1, I%%) 'go ahead and get the tile values here
  1177.  NEXT I%%
  1178.  
  1179.  LINE (290, 240)-STEP(65, 65), _RGB32(8), BF 'base preview
  1180.  LINE (290, 330)-STEP(65, 65), _RGB32(8), BF 'tiles preview
  1181.  LINE (370, 280)-STEP(65, 65), _RGB32(8), BF 'final preview
  1182.  _PRINTSTRING (306, 225), "Base", Layer(1)
  1183.  _PRINTSTRING (306, 316), "Deco", Layer(1)
  1184.  _PRINTSTRING (380, 264), "On Map", Layer(1)
  1185.  
  1186.  LINE (312, 411)-STEP(79, 19), _RGB32(64), B 'Cancel button
  1187.  LINE (313, 412)-STEP(77, 17), _RGB32(160), BF 'Cancel button
  1188.  LINE (212, 411)-STEP(71, 19), _RGB32(64), B 'OK button
  1189.  LINE (213, 412)-STEP(69, 17), _RGB32(160), BF 'OK button
  1190.  tmp& = _COPYIMAGE(Layer(1))
  1191.  _DELAY .1
  1192.  Mouse_Clear
  1193.  DO
  1194.   nul%% = _MOUSEINPUT
  1195.   _PUTIMAGE , tmp&, Layer(1)
  1196.  
  1197.   IF _MOUSEX > 213 AND _MOUSEX < 282 AND _MOUSEY > 412 AND _MOUSEY < 429 THEN 'highlight OK option
  1198.    Selection%% = 1
  1199.   ELSEIF _MOUSEX > 324 AND _MOUSEX < 392 AND _MOUSEY > 412 AND _MOUSEY < 429 THEN 'highlight Cancel option
  1200.    Selection%% = 2
  1201.   ELSE
  1202.    Selection%% = 0
  1203.   END IF
  1204.   FOR I%% = 0 TO 8 'input boxes
  1205.    IF _MOUSEX > 199 AND _MOUSEX < 243 AND _MOUSEY > 225 + 20 * I%% AND _MOUSEY < 241 + 20 * I%% THEN Selection%% = 3 + I%%
  1206.   NEXT I%%
  1207.   FOR I%% = 0 TO 8 'up arrows
  1208.    IF _MOUSEX > 244 AND _MOUSEX < 259 AND _MOUSEY > 225 + 20 * I%% AND _MOUSEY < 232 + 20 * I%% THEN Selection%% = 12 + I%%
  1209.   NEXT I%%
  1210.   FOR I%% = 0 TO 8 'down arrows
  1211.    IF _MOUSEX > 244 AND _MOUSEX < 259 AND _MOUSEY > 234 + 20 * I%% AND _MOUSEY < 241 + 20 * I%% THEN Selection%% = 21 + I%%
  1212.   NEXT I%%
  1213.  
  1214.    SELECT CASE Selection%%
  1215.     CASE 1 ' ok
  1216.      FOR I%% = 0 TO 8
  1217.       TileLayer(P.World_X + P.Mouse_over_R - 1, P.World_Y + P.Mouse_over_B - 1, I%%) = Layer_Values(I%%)
  1218.      NEXT I%%
  1219.      ExitFlag%% = TRUE
  1220.     CASE 2 'cancel
  1221.      ExitFlag%% = TRUE
  1222.     CASE 3 TO 11 'manual input boxes
  1223.      ManualInput%% = Selection%% - 2 'set the flag to which box is being inputed into.
  1224.     CASE 12 TO 20 'up arrow increase
  1225.      IF Layer_Values(Selection%% - 12) < Max_Tile THEN Layer_Values(Selection%% - 12) = Layer_Values(Selection%% - 12) + 1
  1226.      IF Selection%% - 12 = 0 THEN
  1227.       IF Layer_Values(0) > 7 THEN Layer_Values(0) = 7
  1228.      END IF
  1229.      ManualInput%% = FALSE
  1230.     CASE 21 TO 29 'down arrow decrease
  1231.      IF Layer_Values(Selection%% - 21) >= 0 THEN Layer_Values(Selection%% - 21) = Layer_Values(Selection%% - 21) - 1
  1232.      IF Selection%% - 21 = 0 THEN
  1233.       IF Layer_Values(0) < 0 THEN Layer_Values(0) = 0
  1234.      END IF
  1235.      ManualInput%% = FALSE
  1236.    END SELECT
  1237.    _DELAY .1
  1238.   END IF
  1239.  
  1240.   KBD& = _KEYHIT
  1241.   IF KBD& > 0 AND ManualInput%% THEN
  1242.    C$ = LTRIM$(STR$(Layer_Values(ManualInput%% - 1)))
  1243.    SELECT CASE KBD&
  1244.     CASE 27 'esc (acts like cancel)
  1245.      ExitFlag%% = TRUE
  1246.     CASE 8 'back space
  1247.      IF LEN(C$) THEN C$ = LEFT$(C$, LEN(C$) - 1)
  1248.     CASE 48 TO 57 '0-9
  1249.      IF C$ = "-1" THEN C$ = ""
  1250.      IF LEN(C$) < 3 THEN C$ = C$ + CHR$(KBD&)
  1251.      IF VAL(C$) > Max_Tile THEN C$ = LTRIM$(STR$(Max_Tile))
  1252.    END SELECT
  1253.    Layer_Values(ManualInput%% - 1) = VAL(C$)
  1254.   END IF
  1255.  
  1256.   IF Selection%% = 1 THEN COLOR _RGB32(224, 224, 32) ELSE COLOR _RGB32(255)
  1257.   _PRINTSTRING (240, 413), "OK", Layer(1)
  1258.   IF Selection%% = 2 THEN COLOR _RGB32(224, 224, 32) ELSE COLOR _RGB32(255)
  1259.   _PRINTSTRING (330, 413), "Cancel", Layer(1)
  1260.   COLOR _RGB32(16)
  1261.   FOR I%% = 0 TO 8 'display tile data numbers, if any
  1262.    IF Layer_Values(I%%) >= 0 THEN
  1263.     _PRINTSTRING (204, 226 + 20 * I%%), LTRIM$(STR$(Layer_Values(I%%))), Layer(1)
  1264.    ELSE
  1265.     _PRINTSTRING (204, 226 + 20 * I%%), "None", Layer(1)
  1266.    END IF
  1267.   NEXT I%%
  1268.  
  1269.   IF Blink%% AND ManualInput%% THEN
  1270.    IF Layer_Values(ManualInput%% - 1) >= 0 THEN
  1271.     _PRINTSTRING (204 + 8 * LEN(LTRIM$(STR$(Layer_Values(ManualInput%% - 1)))), 226 + 20 * (ManualInput%% - 1)), "_", Layer(1)
  1272.    ELSE
  1273.     _PRINTSTRING (204, 226 + 20 * (ManualInput%% - 1)), "_", Layer(1)
  1274.    END IF
  1275.   END IF
  1276.   COLOR _RGB32(255)
  1277.   _PRINTSTRING (670, 600), STR$(Selection%%) + STR$(ManualInput%%), Layer(1)
  1278.   Show_Tile 291, 241, Layer_Values(0), .5, Layer(1) 'base preview
  1279.   Show_Tile 371, 281, Layer_Values(0), .5, Layer(1) 'composite preview
  1280.   FOR I%% = 1 TO 8 'DECOration preview
  1281.    IF Layer_Values(I%%) >= 0 THEN Show_Tile 291, 331, Layer_Values(I%%), .5, Layer(1)
  1282.    IF Layer_Values(I%%) >= 0 THEN Show_Tile 371, 281, Layer_Values(I%%), .5, Layer(1) 'composite preview
  1283.   NEXT I%%
  1284.   Bt%% = Bt%% + 1 'blink timer
  1285.   IF Bt%% = 8 THEN Blink%% = NOT Blink%%: Bt%% = 0
  1286.   _PUTIMAGE , Layer(1), Layer(0)
  1287.   _LIMIT 60
  1288.   Mouse_Clear
  1289.   IF INKEY$ = CHR$(27) THEN ExitFlag%% = TRUE
  1290.  LOOP UNTIL ExitFlag%%
  1291.  _FREEIMAGE tmp&
  1292.  
  1293.  
  1294. FUNCTION Return_Special% (Kind~%%)
  1295.  Result% = FALSE
  1296.  FOR i% = 1 TO P.Special_Count
  1297.   SELECT CASE Kind~%%
  1298.    CASE 0 'dialog
  1299.     IF Specials(i%).Xloc = P.Mouse_over_R - 1 AND Specials(i%).Yloc = P.Mouse_over_B - 1 AND Specials(i%).Is_Dialog THEN Result% = i%
  1300.    CASE 1 'chest
  1301.     IF Specials(i%).Xloc = P.Mouse_over_R - 1 AND Specials(i%).Yloc = P.Mouse_over_B - 1 AND Specials(i%).Is_Chest THEN Result% = i%
  1302.    CASE 2 'door
  1303.     IF Specials(i%).Xloc = P.Mouse_over_R - 1 AND Specials(i%).Yloc = P.Mouse_over_B - 1 AND Specials(i%).Is_Door THEN Result% = i%
  1304.   IF Result% THEN i% = P.Special_Count + 1 'no need to check further so tell loop its done.
  1305.  NEXT i%
  1306.  Return_Special = Result%
  1307.  
  1308. REM'$include:'Displays.BI'
  1309. SUB Show_Tile (X%, Y%, ID%, Scale!, L&)
  1310.  Sx% = 32 / Scale! - 1
  1311.  Sy% = 32 / Scale! - 1
  1312.  _PUTIMAGE (X%, Y%)-STEP(Sx%, Sy%), Layer(2), L&, (0 + 32 * ID%, 0)-STEP(31, 31)
  1313.  
  1314. SUB Display_Tile_list_Section
  1315.  '--------------Tile sheet selection display-------------------
  1316.  _PRINTSTRING (16 + 320 - 32, 0), "Tile List", Layer(3)
  1317.  LINE (15, 15)-STEP(644, 35), _RGB32(224), B
  1318.  LINE (14, 14)-STEP(646, 37), _RGB32(128), B
  1319.  '-------------------------------------------------------------
  1320.  
  1321. SUB Display_Mini_Map
  1322.  _PRINTSTRING (600, 112), "Mini Map", Layer(3)
  1323.  LINE (600, 130)-STEP(259, 259), _RGB32(224), B
  1324.  LINE (599, 129)-STEP(261, 261), _RGB32(160), B
  1325.  _PRINTSTRING (604, 394), "Refresh", Layer(3)
  1326.  
  1327. SUB Display_Auto_Build_Deco
  1328.  '------------------Auto Placement of premade deco-------------
  1329.  _PRINTSTRING (800, 0), "Automatic", Layer(3)
  1330.  LINE (783, 14)-STEP(103, 103), _RGB32(128), B 'top left
  1331.  LINE (784, 15)-STEP(101, 101), _RGB32(224), B
  1332.  LINE (786, 49)-STEP(98, 0), _RGB32(96)
  1333.  LINE (786, 82)-STEP(98, 0), _RGB32(96)
  1334.  LINE (818, 16)-STEP(0, 98), _RGB32(96)
  1335.  LINE (851, 16)-STEP(0, 98), _RGB32(96)
  1336.  '--------------------------------------------------------------
  1337.  
  1338. SUB Display_Selected_Base
  1339.  '---------------Selected Map Base Tile--------------------
  1340.  _PRINTSTRING (688, 0), "Base", Layer(3)
  1341.  LINE (686, 14)-STEP(37, 37), _RGB32(128), B
  1342.  LINE (687, 15)-STEP(35, 35), _RGB32(224), B
  1343.  '-------------------------------------------------------------
  1344.  
  1345. SUB Display_Selected_Deco
  1346.  '---------------Selected Deco Tile----------------------------
  1347.  _PRINTSTRING (736, 0), "Deco", Layer(3)
  1348.  LINE (734, 14)-STEP(37, 37), _RGB32(128), B
  1349.  LINE (735, 15)-STEP(35, 35), _RGB32(224), B
  1350.  '-------------------------------------------------------------
  1351.  
  1352. SUB Display_Toggles
  1353.  LINE (580, 54)-STEP(14, 14), _RGB32(92), B
  1354.  _PRINTSTRING (602, 54), "Walkable"
  1355.  
  1356. SUB Display_Current_layer
  1357.  LINE (628, 71)-STEP(65, 21), _RGB32(128), B
  1358.  LINE (629, 72)-STEP(63, 19), _RGB32(192), BF
  1359.  _PRINTSTRING (580, 74), "Layer"
  1360.  'up arrow
  1361.  LINE (676, 72)-STEP(16, 9), _RGB32(32), B
  1362.  LINE (677, 73)-STEP(14, 7), _RGB32(112), BF
  1363.  LINE (679, 80)-STEP(10, 0), _RGB32(224): LINE -(684, 75), _RGB32(224): LINE -(679, 80), _RGB32(224): PAINT (685, 77), _RGB32(224), _RGB32(224)
  1364.  'down arrow
  1365.  LINE (676, 82)-STEP(16, 9), _RGB32(32), B
  1366.  LINE (677, 83)-STEP(14, 7), _RGB32(112), BF
  1367.  LINE (679, 85)-STEP(10, 0), _RGB32(224): LINE -(684, 90), _RGB32(224): LINE -(679, 85), _RGB32(224): PAINT (685, 87), _RGB32(224), _RGB32(224)
  1368.  
  1369. SUB Display_Load_Save_Buttons
  1370.  IF P.Mouse_over_R <> 30 THEN
  1371.   _PUTIMAGE (660, 460)-STEP(127, 31), Layer(5), Layer(1), (0, 96)-STEP(63, 15) 'new map
  1372.   _PUTIMAGE (660, 460)-STEP(127, 31), Layer(5), Layer(1), (0, 112)-STEP(63, 15) 'new map
  1373.  IF P.Mouse_over_R <> 31 THEN
  1374.   _PUTIMAGE (600, 500)-STEP(63, 15), Layer(5), Layer(1), (0, 96)-STEP(63, 15) 'save
  1375.   _PUTIMAGE (600, 500)-STEP(63, 15), Layer(5), Layer(1), (0, 112)-STEP(63, 15) 'save
  1376.  IF P.Mouse_over_R <> 32 THEN
  1377.   _PUTIMAGE (680, 500)-STEP(63, 15), Layer(5), Layer(1), (0, 96)-STEP(63, 15) 'load
  1378.   _PUTIMAGE (680, 500)-STEP(63, 15), Layer(5), Layer(1), (0, 113)-STEP(63, 15) 'load
  1379.  IF P.Mouse_over_R <> 33 THEN
  1380.   _PUTIMAGE (760, 500)-STEP(63, 15), Layer(5), Layer(1), (0, 96)-STEP(63, 15) 'quit
  1381.   _PUTIMAGE (760, 500)-STEP(63, 15), Layer(5), Layer(1), (0, 112)-STEP(63, 15) 'quit
  1382.  _PRINTSTRING (696, 468), "New Map", Layer(1)
  1383.  _PRINTSTRING (616, 501), "Save", Layer(1)
  1384.  _PRINTSTRING (694, 501), "Load", Layer(1)
  1385.  _PRINTSTRING (776, 501), "Quit", Layer(1)
  1386.  
  1387. SUB Display_Tiles
  1388.  Show_Tile 689, 17, P.Selected_Base, 1, Layer(1)
  1389.  IF (P.Selected_Deco <> P.Selected_Base) AND P.Selected_Deco THEN Show_Tile 737, 17, P.Selected_Deco, 1, Layer(1) 'Deco can not match Base
  1390.  FOR Ay% = 0 TO 2
  1391.   FOR Ax% = 0 TO 2
  1392.    IF Auto(Ax%, Ay%) THEN Show_Tile 786 + Ax% * 33, 17 + Ay% * 33, Auto(Ax%, Ay%), 1, Layer(1) '0 is not valid for deco
  1393.   NEXT Ax%
  1394.  NEXT Ay%
  1395.  _PUTIMAGE (17, 17)-STEP(639, 31), Layer(2), Layer(1), (0 + 32 * P.List_Start, 0)-STEP(639, 31)
  1396.  
  1397. SUB Display_Selected_Box
  1398.  '---------------Selected Tile Box--------------------
  1399.  IF (P.Mouse_over_R < 21 AND P.Mouse_over_R > 0) AND (P.Mouse_over_B = 0 AND P.Mouse_over_G = 0) THEN _PUTIMAGE (17 + (P.Mouse_over_R - 1) * 32, 17), Layer(5), Layer(1), (0, 64)-STEP(31, 31)
  1400.  '-------------------------------------------------------------
  1401.  '---------------Selected Auto Box--------------------
  1402.  IF P.Mouse_over_G THEN _PUTIMAGE (786 + (P.Mouse_over_G - 1) * 33, 17 + (P.Mouse_over_B - 1) * 33), Layer(5), Layer(1), (0, 64)-STEP(31, 31)
  1403.  '-------------------------------------------------------------
  1404.  '---------------Selected Map Tile Box--------------------
  1405.  IF P.Mouse_over_B AND P.Mouse_over_G = 0 THEN _PUTIMAGE (32 + (P.Mouse_over_R - 1) * 33, 72 + (P.Mouse_over_B - 1) * 33), Layer(5), Layer(1), (0, 64)-STEP(31, 31)
  1406.  '-------------------------------------------------------------
  1407.  
  1408. SUB ClearLayer (L&)
  1409.  _DEST L&
  1410.  CLS
  1411.  
  1412. SUB ClearLayerTrans (L&)
  1413.  _DEST L&
  1414.  CLS , 0
  1415.  
  1416. REM'$include:'SaveLoad.bi'
  1417. SUB Save_Map
  1418.  Temp& = _COPYIMAGE(Layer(0))
  1419.  _DEST Layer(7)
  1420.  LINE (320, 220)-STEP(299, 199), _RGBA32(64, 64, 64, 96), BF
  1421.  LINE (301, 201)-STEP(299, 199), _RGB32(128), BF
  1422.  LINE (302, 202)-STEP(298, 18), _RGB32(0, 16, 192), BF 'title bar
  1423.  _PRINTSTRING (450 - 8 * 4, 204), "Save As...", Layer(7)
  1424.  LINE (319, 259)-STEP(251, 21), _RGB32(80), B 'File name box
  1425.  LINE (320, 260)-STEP(249, 19), _RGB32(16), BF '"   "   "
  1426.  _PRINTSTRING (320, 240), "File Name", Layer(7)
  1427.  LINE (362, 347)-STEP(79, 19), _RGB32(64), B 'Cancel button
  1428.  LINE (363, 348)-STEP(77, 17), _RGB32(160), BF 'Cancel button
  1429.  LINE (462, 347)-STEP(71, 19), _RGB32(64), B 'OK button
  1430.  LINE (463, 348)-STEP(69, 17), _RGB32(160), BF 'OK button
  1431.  _DEST Layer(1)
  1432.  IF LTRIM$(P.Last_File) <> "" THEN f$ = RTRIM$(P.Last_File) 'use what ever name was used last(if any)
  1433.  DO
  1434.   Nul%% = _MOUSEINPUT
  1435.   KBD& = _KEYHIT
  1436.   IF KBD& > 0 THEN
  1437.    SELECT CASE KBD&
  1438.     CASE 27 'esc
  1439.      ExitFlag%% = TRUE
  1440.     CASE 8 'back space
  1441.      IF LEN(f$) THEN f$ = LEFT$(f$, LEN(f$) - 1)
  1442.     CASE 13 'enter
  1443.      ExitFlag%% = TRUE
  1444.      Save_it f$
  1445.     CASE 33 TO 127 'no spaces allowed
  1446.      IF LEN(f$) < 32 THEN f$ = f$ + CHR$(KBD&)
  1447.    END SELECT
  1448.   END IF
  1449.   _PUTIMAGE , Temp&, Layer(1)
  1450.   _PUTIMAGE , Layer(7), Layer(1)
  1451.   IF _MOUSEX > 362 AND _MOUSEX < 442 AND _MOUSEY > 347 AND _MOUSEY < 367 THEN
  1452.    LINE (363, 348)-STEP(77, 17), _RGB32(96), BF 'Cancel button
  1453.    IF _MOUSEBUTTON(1) THEN ExitFlag%% = TRUE 'no save
  1454.   END IF
  1455.   IF _MOUSEX > 462 AND _MOUSEX < 532 AND _MOUSEY > 347 AND _MOUSEY < 367 THEN
  1456.    LINE (463, 348)-STEP(69, 17), _RGB32(96), BF: over%% = 2 'OK button
  1457.     ExitFlag%% = TRUE
  1458.     Save_it f$
  1459.    END IF
  1460.   END IF
  1461.   _PRINTSTRING (380, 350), "Cancel", Layer(1)
  1462.   _PRINTSTRING (490, 350), "OK", Layer(1)
  1463.   _PRINTSTRING (324, 263), f$ + ".MAP", Layer(1)
  1464.   IF Blink%% THEN _PRINTSTRING (324 + 8 * LEN(f$), 263), "_", Layer(1)
  1465.   _PUTIMAGE , Layer(1), Layer(0)
  1466.   Mouse_Clear
  1467.   Bt%% = Bt%% + 1 'blink timer
  1468.   IF Bt%% = 8 THEN Blink%% = NOT Blink%%: Bt%% = 0
  1469.   _LIMIT 60
  1470.  LOOP UNTIL ExitFlag%%
  1471.  _DEST Layer(0)
  1472.  _FREEIMAGE Temp&
  1473.  P.Last_File = f$
  1474.  
  1475.  
  1476. SUB Save_it (File$)
  1477.  F = FREEFILE
  1478.  IF File$ = "" THEN File$ = "Defualt"
  1479.  File$ = LTRIM$(RTRIM$(File$)) 'no spaces allowed
  1480.  OPEN File$ + ".MAP" FOR BINARY AS #F 'Save
  1481.  P.Special_Count = 7
  1482.  Ver~& = VerInfo
  1483.  PUT #F, , Ver~&
  1484.  PUT #F, , World()
  1485.  PUT #F, , TileLayer()
  1486.  PUT #F, , P.Special_Count
  1487.  PUT #F, , Specials()
  1488.  PUT #F, , P.Dialog_ID
  1489.  FOR i% = 1 TO P.Dialog_ID
  1490.   PUT #F, , Dialogs(i%)
  1491.  NEXT i%
  1492.  PUT #F, , P.Chest_ID
  1493.  PUT #F, , Chests()
  1494.  PUT #F, , P.Door_ID
  1495.  PUT #F, , DoorWays()
  1496.  CLOSE #F
  1497.  
  1498. SUB Auto_Save
  1499.  Save_it "AutoSave"
  1500.  P.AutoSave_Notice = TRUE
  1501.  
  1502. SUB Load_Map
  1503.  Temp& = _COPYIMAGE(Layer(0))
  1504.  _DEST Layer(7)
  1505.  LINE (320, 220)-STEP(299, 199), _RGBA32(64, 64, 64, 96), BF
  1506.  LINE (301, 201)-STEP(299, 199), _RGB32(128), BF
  1507.  LINE (302, 202)-STEP(298, 18), _RGB32(0, 16, 192), BF 'title bar
  1508.  _PRINTSTRING (450 - 8 * 5, 204), "Load Map...", Layer(7)
  1509.  LINE (319, 259)-STEP(251, 21), _RGB32(80), B 'File name box
  1510.  LINE (320, 260)-STEP(249, 19), _RGB32(16), BF '"   "   "
  1511.  _PRINTSTRING (320, 240), "File Name", Layer(7)
  1512.  LINE (362, 347)-STEP(79, 19), _RGB32(64), B 'Cancel button
  1513.  LINE (363, 348)-STEP(77, 17), _RGB32(160), BF 'Cancel button
  1514.  LINE (462, 347)-STEP(71, 19), _RGB32(64), B 'OK button
  1515.  LINE (463, 348)-STEP(69, 17), _RGB32(160), BF 'OK button
  1516.  _DEST Layer(1)
  1517.  IF LTRIM$(P.Last_File) <> "" THEN f$ = RTRIM$(P.Last_File) 'use what ever name was used last(if any)
  1518.  DO
  1519.   Nul%% = _MOUSEINPUT
  1520.   KBD& = _KEYHIT
  1521.   IF KBD& > 0 THEN
  1522.    SELECT CASE KBD&
  1523.     CASE 27 'esc
  1524.      ExitFlag%% = TRUE
  1525.     CASE 8 'back space
  1526.      IF LEN(f$) THEN f$ = LEFT$(f$, LEN(f$) - 1)
  1527.     CASE 13 'enter
  1528.      ExitFlag%% = TRUE
  1529.      Load_it f$
  1530.      Build_MAP
  1531.      Place_Mini_Map
  1532.     CASE 33 TO 127 'no spaces allowed
  1533.      IF LEN(f$) < 32 THEN f$ = f$ + CHR$(KBD&)
  1534.    END SELECT
  1535.   END IF
  1536.   _PUTIMAGE , Temp&, Layer(1)
  1537.   _PUTIMAGE , Layer(7), Layer(1)
  1538.   IF _MOUSEX > 362 AND _MOUSEX < 442 AND _MOUSEY > 347 AND _MOUSEY < 367 THEN
  1539.    LINE (363, 348)-STEP(77, 17), _RGB32(96), BF 'Cancel button
  1540.    IF _MOUSEBUTTON(1) THEN ExitFlag%% = TRUE 'no load
  1541.   END IF
  1542.   IF _MOUSEX > 462 AND _MOUSEX < 532 AND _MOUSEY > 347 AND _MOUSEY < 367 THEN
  1543.    LINE (463, 348)-STEP(69, 17), _RGB32(96), BF: over%% = 2 'OK button
  1544.     ExitFlag%% = TRUE
  1545.     Load_it f$
  1546.     Build_MAP
  1547.    END IF
  1548.   END IF
  1549.   _PRINTSTRING (380, 350), "Cancel", Layer(1)
  1550.   _PRINTSTRING (490, 350), "OK", Layer(1)
  1551.   _PRINTSTRING (324, 263), f$ + ".MAP", Layer(1)
  1552.   IF Blink%% THEN _PRINTSTRING (324 + 8 * LEN(f$), 263), "_", Layer(1)
  1553.   _PUTIMAGE , Layer(1), Layer(0)
  1554.   Mouse_Clear
  1555.   Bt%% = Bt%% + 1 'blink timer
  1556.   IF Bt%% = 8 THEN Blink%% = NOT Blink%%: Bt%% = 0
  1557.   _LIMIT 60
  1558.  LOOP UNTIL ExitFlag%%
  1559.  _DEST Layer(0)
  1560.  _FREEIMAGE Temp&
  1561.  P.Last_File = f$
  1562.  
  1563. SUB Load_it (File$)
  1564.  F = FREEFILE
  1565.  IF File$ = "" THEN File$ = "Defualt"
  1566.  File$ = LTRIM$(RTRIM$(File$)) 'no spaces allowed
  1567.  Erase_Auto_Build
  1568.  Reset_Map
  1569.  OPEN File$ + ".MAP" FOR BINARY AS #F 'Save
  1570.  GET #F, , VerCheck&
  1571.  IF VerCheck& <> VerInfo THEN 'Old style Map needs converted
  1572.   IF VerCheck& = OldVer THEN
  1573.    FOR Y~%% = 0 TO 255 'load the second setup (ver0.9 with verification)
  1574.     FOR X~%% = 0 TO 255
  1575.      GET #F, , TileLayer(X~%%, Y~%%, 0)
  1576.      GET #F, , TileLayer(X~%%, Y~%%, 1)
  1577.      GET #F, , TileLayer(X~%%, Y~%%, 2)
  1578.      GET #F, , World(X~%%, Y~%%).Walkable
  1579.      GET #F, , World(X~%%, Y~%%).Has_Dialog
  1580.      GET #F, , World(X~%%, Y~%%).Has_Chest
  1581.      GET #F, , World(X~%%, Y~%%).Has_Door
  1582.      IF TileLayer(X~%%, Y~%%, 1) = 0 THEN TileLayer(X~%%, Y~%%, 1) = -1
  1583.      IF TileLayer(X~%%, Y~%%, 2) = 0 THEN TileLayer(X~%%, Y~%%, 2) = -1
  1584.     NEXT X~%%
  1585.    NEXT Y~%%
  1586.    GET #F, , P.Special_Count
  1587.    GET #F, , Specials()
  1588.    GET #F, , P.Dialog_ID
  1589.    FOR i% = 1 TO P.Dialog_ID
  1590.     GET #F, , Dialogs(i%)
  1591.    NEXT i%
  1592.    GET #F, , P.Chest_ID
  1593.    GET #F, , Chests()
  1594.    GET #F, , P.Door_ID
  1595.    GET #F, , DoorWays()
  1596.   ELSE
  1597.    SEEK #F, 1 'reset file location for conversion
  1598.    FOR Y~%% = 0 TO 255 'load the first setup (V1.0Beta 11/30/21-NO VerID)
  1599.     FOR X~%% = 0 TO 255
  1600.      GET #F, , TileLayer(X~%%, Y~%%, 0)
  1601.      GET #F, , TileLayer(X~%%, Y~%%, 1)
  1602.      GET #F, , TileLayer(X~%%, Y~%%, 2)
  1603.      GET #F, , World(X~%%, Y~%%).Walkable
  1604.     NEXT X~%%
  1605.    NEXT Y~%%
  1606.   END IF
  1607.  ELSE 'No conversion needed
  1608.   GET #F, , World()
  1609.   GET #F, , TileLayer()
  1610.   GET #F, , P.Special_Count
  1611.   GET #F, , Specials()
  1612.   GET #F, , P.Dialog_ID
  1613.   FOR i% = 1 TO P.Dialog_ID
  1614.    GET #F, , Dialogs(i%)
  1615.   NEXT i%
  1616.   GET #F, , P.Chest_ID
  1617.   GET #F, , Chests()
  1618.   GET #F, , P.Door_ID
  1619.   GET #F, , DoorWays()
  1620.  CLOSE #F
  1621.  
  1622. REM'$include:'MFILoader.bi'
  1623. SUB MFI_Loader (FN$)
  1624.  DIM Size(128) AS LONG, FOffset(128) AS LONG
  1625.  GET #1, , c~%% 'retrieve number of files
  1626.  FOR I~%% = 1 TO c~%%
  1627.   GET #1, , FOffset(I~%%)
  1628.   GET #1, , Size(I~%%)
  1629.   FOffset&(I~%%) = FOffset&(I~%%) + 1
  1630.  NEXT I~%%
  1631.  
  1632.  Layer(2) = LoadGFX(FOffset(1), Size(1)) 'tiles
  1633.  Layer(5) = LoadGFX(FOffset(2), Size(2)) 'Buttons
  1634.  Layer(8) = LoadGFX(FOffset(3), Size(3)) 'items
  1635.  
  1636.  CLOSE #1
  1637.  IF _FILEEXISTS("temp.dat") THEN KILL "temp.dat"
  1638.  
  1639. SUB LoadData (Foff&, Size&)
  1640.  IF _FILEEXISTS("temp.dat") THEN KILL "temp.dat"
  1641.  OPEN "temp.dat" FOR BINARY AS #3
  1642.  dat$ = SPACE$(Size&)
  1643.  GET #1, Foff&, dat$
  1644.  PUT #3, , dat$
  1645.  CLOSE #3
  1646.  
  1647. REM '$include:'MFI_Loader2.bi'
  1648.  
  1649. FUNCTION LoadGFX& (Foff&, Size&)
  1650.  IF _FILEEXISTS("temp.dat") THEN KILL "temp.dat"
  1651.  OPEN "temp.dat" FOR BINARY AS #3
  1652.  dat$ = SPACE$(Size&)
  1653.  GET #1, Foff&, dat$
  1654.  PUT #3, , dat$
  1655.  CLOSE #3
  1656.  LoadGFX& = _LOADIMAGE("temp.dat", 32)
  1657.  

The MFI file is the same as above, but is just posted here too as to keep the updated code and MFI together. but no need to re-download if you already have it from above.
* WorldBuilderBeta.MFI (Filesize: 536.18 KB, Downloads: 175)
Granted after becoming radioactive I only have a half-life!