Print Page | Close Window

Scrolling Maps

Printed From: Mirage Source
Category: Tutorials
Forum Name: Submitted Tutorials
Forum Discription: Tutorial submissions for MSE are posted here, waiting for approval
URL: http://ms.shannaracorp.com/backup-forums/forum_posts.asp?TID=119
Printed Date: 20 December 2006 at 6:03pm
Software Version: Web Wiz Forums 8.01 - http://www.webwizforums.com


Topic: Scrolling Maps
Posted By: Sync
Subject: Scrolling Maps
Date Posted: 11 February 2006 at 2:19pm
Originally posted by Misunderstood

BACKUP YOUR SOURCE!!!        &nb sp;   BACKUP YOUR SOURCE!!!

Difficulty: Hard 5/5
Originaly made by Verrigan, edited and converted to mse by Me, misunderstood.
     
(I have changed the way it blts and such so it doesnt blt all 9 maps like last time, just what you need(well for the most part)...
Now it just finds tiles that are within the mapwidth of you, so half of the map to the left, half to the right, half up, half down, + 1 extra tile on all sides as fluff so it looks smooth when scrolling(thats why the Px/yoffset is there in the backbuffers rec when blting, it moves it based on the players offset.
It now stops scrolling if there is not a map in the direction your heading.

This tutorial will show you how to modify a vanilla copy of MSE to put in seamless scrolling maps. This has only been tested on vanilla MSE, and is not guaranteed to work on your game, especially if you have modified your map sizes.

This particular code allows for animation across maps, but has a tiny bug that pops up from time to time that causes the player to jump back a bit. I was unable to find and fix this bug at the time of writing this tutorial, but if a fix is found, it will be posted here.

The intent of these modifications is to make it seem like your game has never-ending maps. It will blt the surrounding maps around the map the player is currently on. To do this, the player must have the map downloaded. (This does not provide code to automatically download the maps, and does not verify that the player has the correct revision of the surrounding maps.)

This code does not send NPC/Item/Player data from the surrounding maps. (As you can see, we are only modifying the client side of the house.) I do not have any intention of coding this any time soon.

Anyways... On to the tutorial.  :-P

Files to Modify

    * modDatabase.bas
    * modConstants.bas
    * modDirectX.bas
    * modGameLogic.bas
    * modGlobals.bas[/list:u]
    * modHandledata.bas
      ModHandleData is where the game handles all incoming/outgoing packets.

      In Sub HandleData()
      Replace this code:
             
' Make sure they aren't walking
              Player(i).Moving = 0
              Player(i).XOffset = 0
              Player(i).YOffset = 0

      with this code:
             
' Make sure they aren't walking
              If i <> MyIndex Then
                  Player(i).Moving = 0
                  Player(i).XOffset = 0
                  Player(i).YOffset = 0
              End If


      Replace this code:
        
If LCase(Parse(0)) = "mapdone" Then
              Map = SaveMap

      with this code:
        
If LCase(Parse(0)) = "mapdone" Then
              Map = SaveMap
              Call LoadSurroundingMaps


      [size=10pt]modGlobals.bas
      ModGlobals holds all the information for different globally defined variables.

      Under this code:
     
Public Map As MapRec

      add this code:
     
Public SMaps() As MapRec


      [size=10pt]modConstants
      ModConstants holds all the constants for the game, wow surprise surprise.
      Add this anywhere, like the bottom.
     
Public Const SurroundingNorth = 0
Public Const SurroundingEast = 2
Public Const SurroundingSouth = 4
Public Const SurroundingWest = 6
Public Const SurroundingNorthEast = 1
Public Const SurroundingSouthEast = 3
Public Const SurroundingSouthWest = 5
Public Const SurroundingNorthWest = 7


      [size=10pt]modDatabase.bas
      ModDatabase handles loading data for the client.

      Add the following code, you should probably add it under the loadmap sub.:
Sub iLoadMap(MapNum As Long, ByVal Size As Byte)
    Dim FileName As String
    Dim f As Long
   
    FileName = App.Path & MAP_PATH & "map" & MapNum & MAP_EXT
   
    If FileExist(FileName, True) Then
        f = FreeFile
        Open FileName For Binary As #f
             Get #f, , SMaps(Size)
        Close #f
    End If
End Sub

Sub LoadSurroundingMaps()
    Dim MapNum As Long
    Dim BlankMap As MapRec
    Dim i As Byte

    ReDim SMaps(7)
    MapNum = Map.Up
    If MapNum > 0 Then
        Call iLoadMap(MapNum, 0)
    Else
        SMaps(0) = BlankMap
    End If
    MapNum = Map.Right
    If MapNum > 0 Then
        Call iLoadMap(MapNum, 2)
    Else
        SMaps(2) = BlankMap
    End If
    MapNum = Map.Down
    If MapNum > 0 Then
        Call iLoadMap(MapNum, 4)
    Else
        SMaps(4) = BlankMap
    End If
    MapNum = Map.Left
    If MapNum > 0 Then
        Call iLoadMap(MapNum, 6)
    Else
        SMaps(6) = BlankMap
    End If
    MapNum = SMaps(0).Right
    If MapNum = 0 And SMaps(2).Up > 0 Then MapNum = SMaps(2).Up
    If MapNum > 0 Then
        Call iLoadMap(MapNum, 1)
    Else
        SMaps(1) = BlankMap
    End If
    MapNum = SMaps(2).Down
    If MapNum = 0 And SMaps(4).Right > 0 Then MapNum = SMaps(4).Right
    If MapNum > 0 Then
        Call iLoadMap(MapNum, 3)
    Else
        SMaps(3) = BlankMap
    End If
    MapNum = SMaps(4).Left
    If MapNum = 0 And SMaps(6).Down > 0 Then MapNum = SMaps(6).Down
    If MapNum > 0 Then
        Call iLoadMap(MapNum, 5)
    Else
        SMaps(5) = BlankMap
    End If
    MapNum = SMaps(6).Up
    If MapNum = 0 And SMaps(0).Left > 0 Then MapNum = SMaps(0).Left
    If MapNum > 0 Then
        Call iLoadMap(MapNum, 7)
    Else
        SMaps(7) = BlankMap
    End If
End Sub


      [size=10pt]modDirectX.bas
      ModDirectX handles all the DirectX settings for the game.

      In Sub InitSurfaces()
      Replace this code:
        
With DDSD_Backbuffer
        .lFlags = DDSD_CAPS Or DDSD_HEIGHT Or DDSD_WIDTH
        .ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN Or DDSCAPS_SYSTEMMEMORY
        .lWidth = (MAX_MAPX + 1) * PIC_X
        .lHeight = (MAX_MAPY + 1) * PIC_Y
    End With
    Set DD_BackBuffer = DD.CreateSurface(DDSD_Backbuffer)

      with this code:
       
With DDSD_Backbuffer
        .lFlags = DDSD_CAPS Or DDSD_HEIGHT Or DDSD_WIDTH
        .ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN Or DDSCAPS_SYSTEMMEMORY
        .lWidth = (MAX_MAPX + 3) * PIC_X
        .lHeight = (MAX_MAPY + 3) * PIC_Y
    End With
    Set DD_BackBuffer = DD.CreateSurface(DDSD_Backbuffer)


[size=10pt]modGameLogic.bas
      ModGameLogic handles all the logic of the game, such as drawing graphics to the picscreen, map editing, etc.

      In Sub GameLoop()
      Under this code:
     
Sub GameLoop()
      Dim Tick As Long
      Dim TickFPS As Long
      Dim FPS As Long
      Dim x As Long
      Dim y As Long
      Dim i As Long
      Dim rec_back As RECT

      add this code:
    
Dim MapXOffset As Integer, MapYOffset As Integer
      Dim PXOffset As Long, PYOffset As Long

      Under this code:
        
Do While InGame
              Tick = GetTickCount

      add this code:
        'For scrolling/Seamless
        MapXOffset = Int(MAX_MAPX / 2) - GetPlayerX(MyIndex)
        MapYOffset = Int(MAX_MAPY / 2) - GetPlayerY(MyIndex)
        PXOffset = Player(MyIndex).XOffset + PIC_X
        PYOffset = Player(MyIndex).YOffset + PIC_Y
       
        If Map.Up = 0 Then
             If MapYOffset > 0 Or (MapYOffset = 0 And GetPlayerDir(MyIndex) = DIR_DOWN) Then
                 MapYOffset = 0
                 PYOffset = 32
             End If
        End If
        If Map.Down = 0 Then
             If MapYOffset < 0 Or (MapYOffset = 0 And GetPlayerDir(MyIndex) = DIR_UP) Then
                 MapYOffset = 0
                 PYOffset = 32
             End If
        End If
        If Map.Left = 0 Then
             If MapXOffset > 0 Or (MapXOffset = 0 And GetPlayerDir(MyIndex) = DIR_RIGHT) Then
                 MapXOffset = 0
                 PXOffset = 32
             End If
        End If
        If Map.Right = 0 Then
             If MapXOffset < 0 Or (MapXOffset = 0 And GetPlayerDir(MyIndex) = DIR_LEFT) Then
                 MapXOffset = 0
                 PXOffset = 32
             End If
         End If


      Change the calls to these functions
      -Call BltTile
      -Call BltItem
      -Call BltNpc
      -Call BltPlayer
      -Call BltFringeTile
      -Call BltPlayerName
      So that you add , MapXOffset, MapYOffset to the end of the passed parameters
      Example:
     
Call BltTile(x, y, MapXOffset, MapYOffset)


      Now we need to make sure it blts enough so we can use the players offset later.(just 1 more ring of tiles around the normal map area)
      Change this code:
     
' Blit out tiles layers ground/anim1/anim2
              For y = 0 To MAX_MAPY
                  For x = 0 To MAX_MAPX

      To this code:
     
' Blit out tiles layers ground/anim1/anim2
        For y = -1 To MAX_MAPY + 1
             For x = -1 To MAX_MAPX + 1


      Change this code:
     
' Blit out tile layer fringe
              For y = 0 To MAX_MAPY
                  For x = 0 To MAX_MAPX

      To this code:
     
' Blit out tile layer fringe
        For y = -1 To MAX_MAPY + 1
             For x = -1 To MAX_MAPX + 1


      Under this code:
             
' Blit out tile layer fringe
             For y = -1 To MAX_MAPY + 1
                 For x = -1 To MAX_MAPX + 1
                      Call BltFringeTile(x, y)
                  Next x
              Next y

      add this code:
             
'If in editor, we need to put a line around the map so we can see where we
              'are able to edit.
        If InEditor Then
             'Call DD_BackBuffer.SetFillColor(RGB(255, 255, 255))
             x = MapXOffset * PIC_X
             y = MapYOffset * PIC_Y
             Call DD_BackBuffer.SetForeColor(RGB(255, 255, 255))
             'Top Side
             rec.top = 32 + y
             rec.Bottom = rec.top + 1
             rec.Left = 32 + x
             rec.Right = rec.Left + (PIC_X * (MAX_MAPX + 1))
             If rec.Left + rec.Right > (MAX_MAPX + 3) * PIC_X Then rec.Right = (MAX_MAPX + 3) * PIC_X
             If rec.Left < 0 Then rec.Left = PXOffset

             Call DD_BackBuffer.BltColorFill(rec, RGB(255, 255, 255))
            
             'Left Side
             rec.top = 32 + y
             rec.Bottom = rec.top + (PIC_Y * (MAX_MAPY + 1))
             rec.Left = 32 + x
             rec.Right = rec.Left + 1
             If rec.top + rec.Bottom > (MAX_MAPY + 3) * PIC_Y Then rec.Bottom = (MAX_MAPY + 3) * PIC_Y
             If rec.top < 0 Then rec.top = PYOffset
             Call DD_BackBuffer.BltColorFill(rec, RGB(255, 255, 255))
            
             'Right Side
             rec.top = 32 + y
             rec.Bottom = rec.top + (PIC_Y * (MAX_MAPY + 1))
             rec.Left = ((MAX_MAPX + 1) * PIC_X) + x + 31
             rec.Right = rec.Left + 1
             If rec.top + rec.Bottom > (MAX_MAPY + 3) * PIC_Y Then rec.Bottom = (MAX_MAPY + 3) * PIC_Y
             If rec.top < 0 Then rec.top = PYOffset
             Call DD_BackBuffer.BltColorFill(rec, RGB(255, 255, 255))
            
             'Bottom Side
             rec.top = ((MAX_MAPY + 1) * PIC_Y) + y + 31
             rec.Bottom = rec.top + 1
             rec.Left = 32 + x
             rec.Right = rec.Left + (PIC_X * (MAX_MAPX + 1))
             If rec.Left + rec.Right > (MAX_MAPX + 3) * PIC_X Then rec.Right = (MAX_MAPX + 3) * PIC_X
             If rec.Left < 0 Then rec.Left = PXOffset
             Call DD_BackBuffer.BltColorFill(rec, RGB(255, 255, 255))
        End If


      Replace this code:
             
' Blit out attribs if in editor
              If InEditor Then
                  For y = 0 To MAX_MAPY
                      For x = 0 To MAX_MAPX
                            With Map.Tile(x, y)
                                If .Type = TILE_TYPE_BLOCKED Then Call DrawText(TexthDC, x * PIC_X + 8, y * PIC_Y + 8, "B", QBColor(BrightRed))
                                If .Type = TILE_TYPE_WARP Then Call DrawText(TexthDC, x * PIC_X + 8, y * PIC_Y + 8, "W", QBColor(BrightBlue))
                                If .Type = TILE_TYPE_ITEM Then Call DrawText(TexthDC, x * PIC_X + 8, y * PIC_Y + 8, "I", QBColor(White))
                                If .Type = TILE_TYPE_NPCAVOID Then Call DrawText(TexthDC, x * PIC_X + 8, y * PIC_Y + 8, "N", QBColor(White))
                                If .Type = TILE_TYPE_KEY Then Call DrawText(TexthDC, x * PIC_X + 8, y * PIC_Y + 8, "K", QBColor(White))
                                If .Type = TILE_TYPE_KEYOPEN Then Call DrawText(TexthDC, x * PIC_X + 8, y * PIC_Y + 8, "O", QBColor(White))
                            End With
                      Next x
                  Next y
              End If

      with this code:
             
' Blit out attribs if in editor
        If InEditor Then
             For y = 0 To MAX_MAPY
                 For x = 0 To MAX_MAPX
                     With Map.Tile(x, y)
                          If .Type = TILE_TYPE_BLOCKED Then Call DrawText(TexthDC, PXOffset + x * PIC_X + 8, PYOffset + y * PIC_Y + 8, "B", QBColor(BrightRed))
                          If .Type = TILE_TYPE_WARP Then Call DrawText(TexthDC, PXOffset + x * PIC_X + 8, PYOffset + y * PIC_Y + 8, "W", QBColor(BrightBlue))
                          If .Type = TILE_TYPE_ITEM Then Call DrawText(TexthDC, PXOffset + x * PIC_X + 8, PYOffset + y * PIC_Y + 8, "I", QBColor(White))
                          If .Type = TILE_TYPE_NPCAVOID Then Call DrawText(TexthDC, PXOffset + x * PIC_X + 8, PYOffset + y * PIC_Y + 8, "N", QBColor(White))
                          If .Type = TILE_TYPE_KEY Then Call DrawText(TexthDC, PXOffset + x * PIC_X + 8, PYOffset + y * PIC_Y + 8, "K", QBColor(White))
                          If .Type = TILE_TYPE_KEYOPEN Then Call DrawText(TexthDC, PXOffset + x * PIC_X + 8, PYOffset + y * PIC_Y + 8, "O", QBColor(White))
                     End With
                 Next x
             Next y
        End If


      Change this code:
             
' Blit the text they are putting in
              Call DrawText(TexthDC, 0, (MAX_MAPY + 1) * PIC_Y - 20, MyText, RGB(255, 255, 255))
             
              ' Draw map name
              If Map.Moral = MAP_MORAL_NONE Then
                  Call DrawText(TexthDC, Int((MAX_MAPX + 1) * PIC_X / 2) - (Int(Len(Trim(Map.Name)) / 2) * 8), 1, Trim(Map.Name), QBColor(BrightRed))
              Else
                  Call DrawText(TexthDC, Int((MAX_MAPX + 1) * PIC_X / 2) - (Int(Len(Trim(Map.Name)) / 2) * 8), 1, Trim(Map.Name), QBColor(White))
              End If
             
              ' Check if we are getting a map, and if we are tell them so
              'If GettingMap = True Then
              '    Call DrawText(TexthDC, 50, 50, "Receiving Map...", QBColor(BrightCyan))
              'End If


      With this code:
              
' Blit the text they are putting in
        Call DrawText(TexthDC, PXOffset, PYOffset + (MAX_MAPY + 1) * PIC_Y - 20, MyText, RGB(255, 255, 255))
       
        ' Draw map name
        If Map.Moral = MAP_MORAL_NONE Then
             Call DrawText(TexthDC, PXOffset + Int((MAX_MAPX + 1) * PIC_X / 2) - (Int(Len(Trim(Map.Name)) / 2) * 8), PYOffset + 1, Trim(Map.Name), QBColor(BrightRed))
        Else
             Call DrawText(TexthDC, PXOffset + Int((MAX_MAPX + 1) * PIC_X / 2) - (Int(Len(Trim(Map.Name)) / 2) * 8), PYOffset + 1, Trim(Map.Name), QBColor(White))
        End If
       
        ' Check if we are getting a map, and if we are tell them so
        'If GettingMap = True Then
        '    Call DrawText(TexthDC, 50, 50, "Receiving Map...", QBColor(BrightCyan))
        'End If


      Replace this code:
             
' Get the rect for the back buffer to blit from
        With rec
             .top = 0
             .Bottom = .top + (MAX_MAPY + 1) * PIC_Y
             .Left = 0
             .Right = .Left + (MAX_MAPX + 1) * PIC_X
        End With

      with this code:
            
' Get the rect for the back buffer to blit from
        With rec
             .top = PYOffset
             .Bottom = .top + (MAX_MAPY + 1) * PIC_Y
             .Left = PXOffset
             .Right = .Left + (MAX_MAPX + 1) * PIC_X
        End With


      Replace Sub BltTile() with this code:
     
Public Sub BltTile(ByVal x As Long, ByVal y As Long, ByVal XOffset As Integer, ByVal YOffset As Integer)
'*********************************************************** *****
'* WHEN        WHO        WHAT
'* ----        ---        ----
'* 07/12/2005  Shannara   Optimized function.
'* 12/16/2005  Mis        Scrolling
'*********************************************************** *****

Dim Ground As Long
Dim Anim1 As Long
Dim Anim2 As Long
Dim RealX As Integer, RealY As Integer, MapNum As Integer

    RealY = y - YOffset
    RealX = x - XOffset
    If RealX >= 0 And RealX <= MAX_MAPX Then
        'Normal Map Dont do anything to x
        If RealY >= 0 And RealY <= MAX_MAPY Then
             'Dont do anything to the y
             MapNum = -1 ' Main map
        ElseIf RealY > MAX_MAPY Then
             RealY = RealY - (MAX_MAPY + 1)
             MapNum = SurroundingSouth
        ElseIf RealY < 0 Then
             RealY = (MAX_MAPY + 1) + RealY
             MapNum = SurroundingNorth
        End If
    ElseIf RealX > MAX_MAPX Then
        RealX = RealX - (MAX_MAPX + 1)
        If RealY >= 0 And RealY <= MAX_MAPY Then
             'Dont do anything to the y
             MapNum = SurroundingEast
        ElseIf RealY > MAX_MAPY Then
             RealY = RealY - (MAX_MAPY + 1)
             MapNum = SurroundingSouthEast
        ElseIf RealY < 0 Then
             RealY = (MAX_MAPY + 1) + RealY
             MapNum = SurroundingNorthEast
        End If
    ElseIf RealX < 0 Then
        RealX = RealX + (MAX_MAPX + 1)
        If RealY >= 0 And RealY <= MAX_MAPY Then
             'Dont do anything to the y
             MapNum = SurroundingWest
        ElseIf RealY > MAX_MAPY Then
             RealY = RealY - (MAX_MAPY + 1)
             MapNum = SurroundingSouthWest
        ElseIf RealY < 0 Then
             RealY = (MAX_MAPY + 1) + RealY
             MapNum = SurroundingNorthWest
        End If
    End If
    If MapNum = -1 Then
        With Map.Tile(RealX, RealY)
             Ground = .Ground
             Anim1 = .Mask
             Anim2 = .Anim
        End With
    Else
        With SMaps(MapNum).Tile(RealX, RealY)
             Ground = .Ground
             Anim1 = .Mask
             Anim2 = .Anim
        End With
    End If
    x = x + 1
    y = y + 1

    With rec
        .top = Int(Ground / 7) * PIC_Y
        .Bottom = .top + PIC_Y
        .Left = (Ground - Int(Ground / 7) * 7) * PIC_X
        .Right = .Left + PIC_X
    End With
    Call DD_BackBuffer.BltFast(x * PIC_X, y * PIC_Y, DD_TileSurf, rec, DDBLTFAST_WAIT)
   
    If (MapAnim = 0) Or (Anim2 <= 0) Then
        ' Is there an animation tile to plot?
        If Anim1 > 0 And (MapNum <> -1 Or TempTile(RealX, RealY).DoorOpen = NO) Then
             With rec
                 .top = Int(Anim1 / 7) * PIC_Y
                 .Bottom = .top + PIC_Y
                 .Left = (Anim1 - Int(Anim1 / 7) * 7) * PIC_X
                 .Right = .Left + PIC_X
             End With
             Call DD_BackBuffer.BltFast(x * PIC_X, y * PIC_Y, DD_TileSurf, rec, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)
        End If
    Else
        ' Is there a second animation tile to plot?
        If Anim2 > 0 Then
             With rec
                 .top = Int(Anim2 / 7) * PIC_Y
                 .Bottom = .top + PIC_Y
                 .Left = (Anim2 - Int(Anim2 / 7) * 7) * PIC_X
                 .Right = .Left + PIC_X
             End With
             Call DD_BackBuffer.BltFast(x * PIC_X, y * PIC_Y, DD_TileSurf, rec, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)
        End If
    End If
End Sub


      Replace Sub BltItem() with this code:
     
Public Sub BltItem(ByVal ItemNum As Long, ByVal XOffset As Integer, ByVal YOffset As Integer)
'*********************************************************** *****
'* WHEN        WHO        WHAT
'* ----        ---        ----
'* 07/12/2005  Shannara   Optimized function.
'* 12/16/2005  Mis        Scrolling
'*********************************************************** *****
Dim x As Integer, y As Integer
    x = MapItem(ItemNum).x - XOffset + 1
    y = MapItem(ItemNum).y - YOffset + 1
    If x > 0 And x <= MAX_MAPX + 1 And y > 0 And y <= MAX_MAPY + 1 Then
   
        With rec
             .top = Item(MapItem(ItemNum).Num).Pic * PIC_Y
             .Bottom = .top + PIC_Y
             .Left = 0
             .Right = .Left + PIC_X
        End With
       
        Call DD_BackBuffer.BltFast(x * PIC_X, y * PIC_Y, DD_ItemSurf, rec, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)
    End If
End Sub
]    

      Replace Sub BltFringeTile() with this code:
    
Public Sub BltFringeTile(ByVal x As Long, ByVal y As Long, ByVal XOffset As Integer, ByVal YOffset As Integer)
'*********************************************************** *****
'* WHEN        WHO        WHAT
'* ----        ---        ----
'* 07/12/2005  Shannara   Optimized function.
'* 12/16/2005  Mis        Scrolling
'*********************************************************** *****

Dim Fringe As Long
Dim RealX As Integer, RealY As Integer, MapNum As Integer

    RealY = y - YOffset
    RealX = x - XOffset
    If RealX >= 0 And RealX <= MAX_MAPX Then
        'Normal Map Dont do anything to x
        If RealY >= 0 And RealY <= MAX_MAPY Then
             'Dont do anything to the y
             MapNum = -1 ' Main map
        ElseIf RealY > MAX_MAPY Then
             RealY = RealY - (MAX_MAPY + 1)
             MapNum = SurroundingSouth
        ElseIf RealY < 0 Then
             RealY = (MAX_MAPY + 1) + RealY
             MapNum = SurroundingNorth
        End If
    ElseIf RealX > MAX_MAPX Then
        RealX = RealX - (MAX_MAPX + 1)
        If RealY >= 0 And RealY <= MAX_MAPY Then
             'Dont do anything to the y
             MapNum = SurroundingEast
        ElseIf RealY > MAX_MAPY Then
             RealY = RealY - (MAX_MAPY + 1)
             MapNum = SurroundingSouthEast
        ElseIf RealY < 0 Then
             RealY = (MAX_MAPY + 1) + RealY
             MapNum = SurroundingNorthEast
        End If
    ElseIf RealX < 0 Then
        RealX = RealX + (MAX_MAPX + 1)
        If RealY >= 0 And RealY <= MAX_MAPY Then
             'Dont do anything to the y
             MapNum = SurroundingWest
        ElseIf RealY > MAX_MAPY Then
             RealY = RealY - (MAX_MAPY + 1)
             MapNum = SurroundingSouthWest
        ElseIf RealY < 0 Then
             RealY = (MAX_MAPY + 1) + RealY
             MapNum = SurroundingNorthWest
        End If
    End If
    If MapNum = -1 Then
        Fringe = Map.Tile(RealX, RealY).Fringe
    Else
        Fringe = SMaps(MapNum).Tile(RealX, RealY).Fringe
    End If
    x = x + 1
    y = y + 1

    If Fringe > 0 Then
        With rec
             .top = Int(Fringe / 7) * PIC_Y
             .Bottom = .top + PIC_Y
             .Left = (Fringe - Int(Fringe / 7) * 7) * PIC_X
             .Right = .Left + PIC_X
        End With
        Call DD_BackBuffer.BltFast(x * PIC_X, y * PIC_Y, DD_TileSurf, rec, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)
    End If
End Sub


      In Sub BltPlayer()
      Add the follow parameters to the end
     
, Byval XOffset as Integer, byval YOffset as Integer

      Under this code:
     
Dim x As Long, y As Long

      add this code:
     
    If Index <> MyIndex Then
        x = GetPlayerX(Index) + XOffset + 1
        y = GetPlayerY(Index) + YOffset + 1
    Else
        If XOffset = 0 Then
             x = GetPlayerX(Index) + 1
        Else
             x = Int(MAX_MAPX / 2) + 1
        End If
        If YOffset = 0 Then
             y = GetPlayerY(Index) + 1
        Else
             y = Int(MAX_MAPY / 2) + 1
        End If
    End If
    If x > 0 And x <= MAX_MAPX + 1 And y > 0 And y <= MAX_MAPY + 1 Then

     
      And Change these lines:
     
x = GetPlayerX(index) * PIC_X + Player(Index).XOffset
        y = GetPlayerY(index) * PIC_Y + Player(Index).YOffset - 4

      to this:
     
x = x * PIC_X + Player(Index).XOffset
        y = y * PIC_Y + Player(Index).YOffset - 4

     
      Before Exit Sub add End if

      Replace Sub BltPlayerName() with this code:
     
Sub BltPlayerName(ByVal Index As Long, ByVal XOffset As Integer, ByVal YOffset As Integer)
Dim TextX As Long
Dim TextY As Long
Dim Color As Long
   
    If Index <> MyIndex Then
        TextX = GetPlayerX(Index) + XOffset + 1
        TextY = GetPlayerY(Index) + YOffset + 1
    Else
        If XOffset = 0 Then
             TextX = GetPlayerX(Index) + 1
        Else
             TextX = Int(MAX_MAPX / 2) + 1
        End If
        If YOffset = 0 Then
             TextY = GetPlayerY(Index) + 1
        Else
             TextY = Int(MAX_MAPY / 2) + 1
        End If
    End If
    If TextX > 0 And TextX <= MAX_MAPX + 1 And TextY > 0 And TextY <= MAX_MAPY + 1 Then
        ' Check access level
        If GetPlayerPK(Index) = NO Then
             Select Case GetPlayerAccess(Index)
                 Case 0
                     Color = QBColor(Brown)
                 Case 1
                     Color = QBColor(DarkGrey)
                 Case 2
                     Color = QBColor(Cyan)
                 Case 3
                     Color = QBColor(Blue)
                 Case 4
                     Color = QBColor(Pink)
             End Select
        Else
             Color = QBColor(BrightRed)
        End If
       
        ' Draw name
        TextX = TextX * PIC_X + Player(Index).XOffset + Int(PIC_X / 2) - ((Len(GetPlayerName(Index)) / 2) * 8)
        TextY = TextY * PIC_Y + Player(Index).YOffset - Int(PIC_Y / 2) - 4
        Call DrawText(TexthDC, TextX, TextY, GetPlayerName(Index), Color)
    End If
End Sub


      In Sub BltNpc()
      Add the follow parameters to the end
     
, Byval XOffset as Integer, byval YOffset as Integer

      Under this code:
     
Dim x As Long, y As Long

      add this code:
     
x = MapNpc(MapNpcNum).x + XOffset + 1
    y = MapNpc(MapNpcNum).y + YOffset + 1
    If x > 0 And x <= MAX_MAPX + 1 And y > 0 And y <= MAX_MAPY + 1 Then


      Change this code:
        
x = .x * PIC_X + .XOffset
         y = .y * PIC_Y + .YOffset - 4

      withthis code:
     
x = x * PIC_X + .XOffset
         y = y * PIC_Y + .YOffset - 4

     
      Before Exit Sub add End If

      In Sub ProcessMovement()
      Under this code:
     
Sub ProcessMovement(ByVal Index As Long)

      add this code:
        
if GettingMap Then Exit Sub


      In Sub CanMove()
      Replace the following code 4 times (4 different areas, up, down, right, left):
                 
' Check if they can warp to a new map
                  If Map.Up > 0 Then
                      Call SendPlayerRequestNewMap
                      GettingMap = True
                  End If
                  CanMove = False
                  Exit Function

      with this code:
                 
' Check if they can warp to a new map
                  If Map.Up > 0 Then
                    Call SendPlayerRequestNewMap
                    GettingMap = True
                  Else
                    CanMove = False
                  End If
                  Exit Function

      In Sub CheckMovement()
      Replace this code:
                     
Select Case GetPlayerDir(MyIndex)
                            Case DIR_UP
                                  Call SendPlayerMove
                                  Player(MyIndex).YOffset = PIC_Y
                                  Call SetPlayerY(MyIndex, GetPlayerY(MyIndex) - 1)
                     
                            Case DIR_DOWN
                                  Call SendPlayerMove
                                  Player(MyIndex).YOffset = PIC_Y * -1
                                  Call SetPlayerY(MyIndex, GetPlayerY(MyIndex) + 1)
                     
                            Case DIR_LEFT
                                  Call SendPlayerMove
                                  Player(MyIndex).XOffset = PIC_X
                                  Call SetPlayerX(MyIndex, GetPlayerX(MyIndex) - 1)
                     
                            Case DIR_RIGHT
                                  Call SendPlayerMove
                                  Player(MyIndex).XOffset = PIC_X * -1
                                  Call SetPlayerX(MyIndex, GetPlayerX(MyIndex) + 1)
                      End Select

      with this code:
                     
Select Case GetPlayerDir(MyIndex)
                            Case DIR_UP
                                Player(MyIndex).YOffset = PIC_Y
                                If Not GettingMap Then
                                    Call SendPlayerMove
                                    Call SetPlayerY(MyIndex, GetPlayerY(MyIndex) - 1)
                                End If