Jump to content

List(of T)


Recoil

Recommended Posts

I am running into an issue adding my maps to a List(of Maps).  I have bypassed the MaxMaps requirement, so this wil create maps as they are needed, and not limit the program to a set number.  If I can figure this issue out, it may help figure out why I ahve to have a set limit, and add/insert for my MapTokens.

First my map class:

Public Class Maps

#Region "Properties"

    Public Property Name As String

    Public Property Revision As Long

    Public Property Tileset As Long

    Public Property MapType As MapTypes

    Public Property North As Integer

    Public Property South As Integer

    Public Property West As Integer

    Public Property East As Integer

    Public Property MaxX As Byte

    Public Property MaxY As Byte

    Public Property Tiles As Tiles(,)

    Public Property Token As List(Of MapTokens)

#End Region

    Public Sub New()

        Name = "Empty"
        Revision = 0
        Tileset = 0
        MapType = 0
        North = 0
        South = 0
        West = 0
        East = 0
        MaxX = Options.MaxMapX
        MaxY = Options.MaxMapY

        Token = New List(Of MapTokens)

        For x = 1 To MaxMapTokens
            Token.Add(New MapTokens)
            Token.Insert(x, New MapTokens)
        Next

        ReDim Tiles(0 To MaxX, 0 To MaxY)

        For x = 0 To MaxX

            For y = 0 To MaxY
                Tiles(x, y) = New Tiles()
                Tiles(x, y).Tile.Add(New TileData())
            Next

        Next

    End Sub

End Class

Global declaration:

Public Map As List(Of Maps)

When the app is running, I have a button to add a new map to the directory:


    Private Sub btnAddNewMap_Click(sender As Object, e As EventArgs) Handles btnAddNewMap.Click

        If MsgBox("Create a new map?", vbYesNo, GameName) = vbYes Then

            Dim i As Integer = cboMapWarp.Items.Count

            CreatingNewMap = True

            CheckMap(i)

        End If

    End Sub

That goes through to:


    Public Sub CheckMap(ByVal mapNum As Long)

        ' Loads an empty map in memory so there is no null error.
        ClearMap(mapNum)

        ' Check if the map exists.
        If Not FileExist(Application.StartupPath & "\Data Files\Campaigns\" & CampaignName & "\Maps\" & "Map" & mapNum & MapExt) Then

            MakeNewMap(mapNum)

        End If

        ' Set our control max values.
        DmScreen.scrlMapWarpMap.Maximum = MapCount
        DmScreen.nudNorth.Maximum = MapCount
        DmScreen.nudEast.Maximum = MapCount
        DmScreen.nudSouth.Maximum = MapCount
        DmScreen.nudWest.Maximum = MapCount

    End Sub

Here is how I HAVE to make a new map with both Add & Insert, otherwise I get out of range exceptions:


    Private Sub MakeNewMap(ByVal mapNum As Long)

        ' If not let's create the next map in our index.
        MapCount += 1

        ' Open up a space in our list.
        Map.Add(New Maps)

        ' Insert a blank map in that space.
        Map.Insert(mapNum, New Maps)

        ' Save the newly create map.
        SaveMap(mapNum)

    End Sub

That works for making a new map, but my Map.Count is always twice the number of maps I have.

And here on initial load I am checking the maps:

    Friend Sub CheckMaps()

        ' Check each file in the directory.
        For Each MapFile In Directory.GetFiles(Application.StartupPath & "\Data Files\Campaigns\" & CampaignName & "\Maps\") 'Map" & i & MapExt)

            ' If it has the MapExt then add it to our count.
            If MapFile.EndsWith(MapExt) Then
                
                MapCount += 1
                
            End If

        Next

        ' Create new initial list of maps.
        Map = New List(Of Maps)
        
        ' Check if we are first starting a new campaign and there are no maps.
        If MapCount = 0 Then

            MakeNewMap(1)

            ' We are going to count again below for ALL the maps.
            Map.Clear()

        End If

        ' Create the initial list of map names for cboMapWarp.
        MapNameList = New List(Of String)()
        MapNameList.Clear()
        MapNameList.Add("None")
        
        For x = 1 To MapCount

            ' Open up a space in our list.
            Map.Add(New Maps)

            ' Insert a blank map in that space.
            Map.Insert(x, New Maps)

            ' Open each map file, check the name, add it to our list of map names.
            CheckMapName(x)

        Next

        ' TODO: By the time I get here Map.Count is twice the number of maps I have...?
        MessageBox.Show(Map.Count)

    End Sub

At the bottom of that I have to Add & Insert a map index into the list.  And even starting out my Map.Count is always twice the number of maps I actually have in the folder.

Inserting alone cases out of range exceptions.  However, when I simply Add I get an out of range exception when I am checking the map name to put in a list that populates a combobox:


    Private Sub CheckMapName(ByVal mapNum As Long)

        Dim fileName As String = Application.StartupPath & "\Data Files\Campaigns\" & CampaignName & "\Maps\" & "Map" & mapNum & MapExt
        Dim f As Long = FreeFile()

        FileOpen(f, fileName, OpenMode.Binary, OpenAccess.Read, OpenShare.Default)
        FileGetObject(f, Map(mapNum).Name) ' ERRORS HERE...

        ' Add the name in our list of map names.
        MapNameList.Add(mapNum & ":  " & Map(mapNum).Name)

        FileClose(f)

    End Sub

While everything here works, my Map.Count is always double.  Likewise, even though I have a max on the map tokens, the actual count of the List(of MapTokens) is always twice as much as the number of tokens I have.  I am unable to get anything to work without both Adding/Inserting.

Link to comment
Share on other sites

You can't follow up List.Add with List.Insert. --  List.Add does not make space for your next item, it literally adds your item to the list. So when you follow that up with insert, you add an extra map leading to your map count being double what you expect.

That is the initial problem, you work that out and everything will be easier to solve/debug.

Link to comment
Share on other sites

I actually have to put in insert just to make it work for some reason, and I know that is why my count is double.  It is the weirdest issue I have ever had working with a list.  But I am also converting things on top of an already built engine that was designed to run differently than what I am trying to make it do.

I have made some slight changes.  I am going to try and get rid of all the inserts and work my way up from there.

Link to comment
Share on other sites

Alright, this is what is going on now:

A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll

Additional information: Index was out of range. Must be non-negative and less than the size of the collection.

That happens at...:

FilePutObject(f, Map(mapNum).Name)

...when I am creating a new map, and saving it...that is without all the inserts, and also without checking the names of the maps to add to a list.

This is telling me that there is no enough space in the list indices to save a blank map.

Now if there is already premade maps in the directory, it will go through...but will not create any new maps, unless I add, then insert a new map, otherwise it is goin to keep throwing out of range exceptions, when there is no range to except on.

Just reaching out here if anyone has any ideas that are different than what I have already figured out.  This isn't really the easiest thing to work out.

Link to comment
Share on other sites

Good. Whatever you were doing was a band-aid to this larger problem. Wait for that error to occur and hover over mapnum, tell me what the value of that is. Then hover over Maps and tell me the indicies and what is in each index of the Maps list.

Link to comment
Share on other sites

On initial startup, I am doing this now, which is cleaner, but still does the same thing as I was doing before:

Friend Sub CheckMaps()

        ' Create the initial list of map names for cboMapWarp.
        MapNameList = New List(Of String)()
        MapNameList.Clear()
        MapNameList.Add("None")

        ' Create new initial list of maps.
        Map = New List(Of Maps)
        
        ' Check each file in the directory.
        For Each MapFile In Directory.GetFiles(Application.StartupPath & "\Data Files\Campaigns\" & CampaignName & "\Maps\") 'Map" & i & MapExt)

            ' If it has the MapExt then add it to our count.
            If MapFile.EndsWith(MapExt) Then

                MapCount += 1

                ' Open up a space in our list.
                Map.Add(New Maps) ' - By itself causes out of range exception: CheckMap -> FileGetObject(f, Map(mapNum).Name)

            End If

        Next

        ' Check if we are first starting a new campaign and there are no maps.
        If MapCount = 0 Then

            MakeNewMap(1)

        End If
        
    End Sub

On a new campaign, there are no maps in the directory, so I have to make one:

    Private Sub MakeNewMap(ByVal mapNum As Long)

        ' If not let's create the next map in our index.
        MapCount += 1

        ' Open up a space in our list.
        Map.Add(New Maps)

        ' Save the newly create map.
        SaveMap(mapNum)

    End Sub

I am getting my error on the bottom of this:

    Private Sub SaveMap(ByVal mapNum As Long)

        ' Note: Do not use this method outside of this module...use SetSaveMap instead.

        Dim fileName As String = Application.StartupPath & "\Data Files\Campaigns\" & CampaignName & "\Maps\" & "Map" & mapNum & MapExt
        Dim f As Long
        Dim x As Long
        Dim y As Long

        f = FreeFile()
        FileOpen(f, fileName, OpenMode.Binary, OpenAccess.Write, OpenShare.Default)

        FilePutObject(f, Map(mapNum).Name)

A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll

Additional information: Index was out of range. Must be non-negative and less than the size of the collection.

Auto Locals:

Map : Count=1

f : 1

mapnum : 1

The filename is correct, it creates Map1.map in the directory when it has this error...so I restart, and on loading Map1.map, it errors on load, on the same Map(mapNum).Name when it is getting it.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...