Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Feature] Adding New Layers
#1
This tutorial will guide you through adding more layers to a vanilla MS4(3.68) and try and give an explanation as to what is doing what.

*Adding this will require you to delete all your maps. If you want to save them then you will need to create a converter. I am not telling you how to create a converter.

So when I go to add something new, regardless of what it is I like to start in the server Big Grin.

Server Side

The next thing I like to do is add whatever I am adding to the UDT which needs it. A UDT is a User Defined Type. That's all those Type PlayerRec, Type UserRec, TypePlayerInvRec and so on. These are all in modTypes, duh.

modTypes
Under the TileRec UDT add in the new layers you want. I am going to add in two new ones. Mine looks like this now.

Code:
Type TileRec
    Ground As Integer
    Mask As Integer
    Mask2 As Integer
    Anim As Integer
    Anim2 As Integer
    Fringe As Integer
    Type As Byte
    Data1 As Integer
    Data2 As Integer
    Data3 As Integer
End Type
So honestly, the next place to go I don't really know xD so I am going to use the search option(Ctrl + F) and type in Ground and press search till something obvious comes up. Seems as if our next place is:

modHandleData
If you don't know, modHandleData does exactly what it's name says. Handles data. All the incoming packets from the client are sorted here and then just done whatever with.

So find the HandleMapData sub.
In this sub you will have to add your new layers in which you added to the TileRec UDT in the last step. Why? Because later you will edit the client side which sends the data to the server, it needs to be received somehow. Anyways, you can see the code that looks like this:

Code:
Map(MapNum).Tile(x, y).Ground = Val(Parse(n))
            Map(MapNum).Tile(x, y).Mask = Val(Parse(n + 1))
            Map(MapNum).Tile(x, y).Anim = Val(Parse(n + 2))
            Map(MapNum).Tile(x, y).Fringe = Val(Parse(n + 3))
            Map(MapNum).Tile(x, y).Type = Val(Parse(n + 4))
            Map(MapNum).Tile(x, y).Data1 = Val(Parse(n + 5))
            Map(MapNum).Tile(x, y).Data2 = Val(Parse(n + 6))
            Map(MapNum).Tile(x, y).Data3 = Val(Parse(n + 7))

            n = n + 8
It's probably pretty obvious what you need to do here right? I like to keep things organized myself, so instead of being lazy and adding them to the bottom I added them to the same spots that the UDT has them sorted out. I advise you do the same. If you are adding more than two layers ensure you change all the n + # to the correct ones, don't forget the n = n + #. Mine looks like this now.

Code:
Map(MapNum).Tile(x, y).Ground = Val(Parse(n))
            Map(MapNum).Tile(x, y).Mask = Val(Parse(n + 1))
            Map(MapNum).Tile(x, y).Mask2 = Val(Parse(n + 2))
            Map(MapNum).Tile(x, y).Anim = Val(Parse(n + 3))
            Map(MapNum).Tile(x, y).Anim2 = Val(Parse(n + 4))
            Map(MapNum).Tile(x, y).Fringe = Val(Parse(n + 5))
            Map(MapNum).Tile(x, y).Type = Val(Parse(n + 6))
            Map(MapNum).Tile(x, y).Data1 = Val(Parse(n + 7))
            Map(MapNum).Tile(x, y).Data2 = Val(Parse(n + 8))
            Map(MapNum).Tile(x, y).Data3 = Val(Parse(n + 9))
            
            n = n + 10
Wow this is fun haha. We are learning something I hope? Next step...

modServerTCP
Find the MapCache_Create sub.
Find this line:

Code:
MapData = MapData & SEP_CHAR & .Ground & SEP_CHAR & .Mask & SEP_CHAR & .Anim & SEP_CHAR & .Fringe & SEP_CHAR & .Type & SEP_CHAR & .Data1 & SEP_CHAR & .Data2 & SEP_CHAR & .Data3
Once again, you will need to add your new layers names in here someplace. As previous, I recommend keeping everything in the same order. So add your new layers in here. Mine looks like this.

Code:
MapData = MapData & SEP_CHAR & .Ground & SEP_CHAR & .Mask & SEP_CHAR & .Mask2 & SEP_CHAR & .Anim & SEP_CHAR & .Anim2 & SEP_CHAR & .Fringe & SEP_CHAR & .Type & SEP_CHAR & .Data1 & SEP_CHAR & .Data2 & SEP_CHAR & .Data3
Notice how it is all in order. This is important when sending/receiving packets.

Client Side

modTypes
Add your new types to the UDT. Keep them in the same order as the server!

modHandleData
Find the HandleMapData sub.
You should already know how to do this part. Add your new layers in here. Once again, keep it in order. Don't forget to change the n + # and n = n + # to their new appropriate values.

modClientTCP
Sub SendMap.
Remember this:

Code:
Packet = Packet & SEP_CHAR & .Ground & SEP_CHAR & .Mask & SEP_CHAR & .Anim & SEP_CHAR & .Fringe & SEP_CHAR & .Type & SEP_CHAR & .Data1 & SEP_CHAR & .Data2 & SEP_CHAR & .Data3
Make it work. Keep it in order! xD.

frmMirage
Add however many new options to the map editor as you need. I only need two so I am putting a new option called optMask2 and one called optAnim2.

modGameEditors
Find the MapEditorMouseDown sub.
If you look at it it should be pretty obvious what needs to happen.

Code:
With Map.Tile(CurX, CurY)
                If frmMirage.optGround.Value Then .Ground = EditorTileY * TILESHEET_WIDTH + EditorTileX
                If frmMirage.optMask.Value Then .Mask = EditorTileY * TILESHEET_WIDTH + EditorTileX
                If frmMirage.optAnim.Value Then .Anim = EditorTileY * TILESHEET_WIDTH + EditorTileX
                If frmMirage.optFringe.Value Then .Fringe = EditorTileY * TILESHEET_WIDTH + EditorTileX
                Call BltMap
            End With
Add in your new layers to this section. I have a new layer called Mask2 and one called Anim2 so I would add these lines.

Code:
If frmMirage.optMask2.Value Then .Mask2 = EditorTileY * TILESHEET_WIDTH + EditorTileX
If frmMirage.optAnim2.Value Then .Anim2 = EditorTileY * TILESHEET_WIDTH + EditorTileX
Scroll down some till you find this:

Code:
If Button = 2 Then
        If frmMirage.optLayers.Value Then
            With Map.Tile(CurX, CurY)
                If frmMirage.optGround.Value Then .Ground = 0
                If frmMirage.optMask.Value Then .Mask = 0
                If frmMirage.optAnim.Value Then .Anim = 0
                If frmMirage.optFringe.Value Then .Fringe = 0
                Call BltMap
            End With
        Else
This section checks if you are pressing the right click button on the mouse, or Button 2. You need to do basically the same thing here as you did in the last step, just without so much stuff. Got it? Good. Now scroll down past a few other subs until you find...

Sub MapEditorClearLayer
Add your new layers in here so they can get cleared properly if you press the clear button.

modDirectDraw7
This module handles all the games drawing procedures. This includes drawing layers to the game screen Wink. Scroll down till you find...

Sub BltMapTile.
I am going to explain something here quickly, I honestly don't know exactly why (maybe somebody could tell me haha) but the way Mirage draws things to the screen is in an order of first to last. The last things are drawn above everything before it. Get it? So if you look at the BltMapTile sub you can see that first the ground is drawn, then the Mask. So since I am just adding a new mask layer (Mask2) I will add it underneath the code for the first mask layer. Follow? This will allow for the Mask2 layer to be drawn over the regular, default Mask layer.

Code:
If .Mask > 0 Then
                    If TempTile(X, Y).DoorOpen = NO Then
                        rec.Top = (.Mask \ TILESHEET_WIDTH) * PIC_Y
                        rec.Bottom = rec.Top + PIC_Y
                        rec.Left = Int(.Mask Mod TILESHEET_WIDTH) * PIC_X
                        rec.Right = rec.Left + PIC_X
                        Call DDS_BackBuffer.BltFast(X * PIC_X, Y * PIC_Y, DDS_Tile, rec, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)
                    End If
                End If
I am going to add my new layer, Mask2 right underneath this code. So now this part in my BltMapTile sub looks like this:

Code:
If .Mask > 0 Then
                    If TempTile(X, Y).DoorOpen = NO Then
                        rec.Top = (.Mask \ TILESHEET_WIDTH) * PIC_Y
                        rec.Bottom = rec.Top + PIC_Y
                        rec.Left = Int(.Mask Mod TILESHEET_WIDTH) * PIC_X
                        rec.Right = rec.Left + PIC_X
                        Call DDS_BackBuffer.BltFast(X * PIC_X, Y * PIC_Y, DDS_Tile, rec, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)
                    End If
                End If
                
                If .Mask2 > 0 Then
                    If TempTile(X, Y).DoorOpen = NO Then
                        rec.Top = (.Mask2 \ TILESHEET_WIDTH) * PIC_Y
                        rec.Bottom = rec.Top + PIC_Y
                        rec.Left = Int(.Mask2 Mod TILESHEET_WIDTH) * PIC_X
                        rec.Right = rec.Left + PIC_X
                        Call DDS_BackBuffer.BltFast(X * PIC_X, Y * PIC_Y, DDS_Tile, rec, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)
                    End If
                End If
It's pretty straight forward and shouldn't be too difficult. The same goes for the Anim layers. Just duplicate the current one and change the names accordingly. One more thing though, if you are adding an extra fringe layer then you will have to find...

Sub BltMapFringeTile
This sub is where all the Fringe layers are drawn so if you want to add another Fringe layer you would go about doing the same thing here as you did with the previous mask layer.

Now you are ready to test it! Delete all the maps in your client folder and your server folder. Start the server. Start the client. Enjoy.

This is my first tutorial for MS4. Horrah. I tested this and it works. Post if you have any problems or questions.
Reply


Messages In This Thread

Forum Jump:


Users browsing this thread: 1 Guest(s)