How to have dynamic sized arrays in types

Blitz3D Forums/Blitz3D Programming/How to have dynamic sized arrays in types

PowerPC603(Posted 2005) [#1]
Hi,

I'm creating a spacesim (like Freelancer).
I've got about 50 tradable wares in the game and therefore I only create 50 instances of a type called TWareType.
This type has the name, description and required cargospace per unit for each kind of tradable ware.

Each spacestation can then have a link (pointer) to these TWareTypes, but the problem is that B3D only supports static arrays within types (you have to set the size upfront with a constant).

Each station must be able to hold different amounts of tradable wares, so that one station could sell ore for example, and the other cannot.

Would it be wise to set the array to a preset maximum (100 or so), and just set the neccessary indexes to point to such a TWareType (and leave the others empty = they point to nothing), or is there another way?

Having a station with an array which can hold 100 wares, when only 10 are used, is in my opinion a waste of memory.

I also want the ability to let the player add his own tradable wares (let players MOD the game a little), the current setup allows this already (it loads all stuff from a datafile in plain ASCII).
But then the player will be limited to only create 100 different ware types, because a station can hold only 100 different waretypes.

In BMax (I ported my code to B3D, as I will be beginning to create 3D models soon) I could add as many wares as required, because the arrays could be resized during runtime.

So in short:
Station 1 could hold 5 ware types (ore, silicon, water, food and toxic waste), while station 2 could hold 17 wares, station 3 only has 2 wares, and so on.
This will be declared in that datafile as well, so the user would be able to add wares to any station.

Is there a way to achieve this?


John Pickford(Posted 2005) [#2]
Create a 'ware' type and have a linked list attached to each station. That way you can hang as many off each station as you like.


PowerPC603(Posted 2005) [#3]
How do I create a linked list inside a type?

Just having 2 variables, where the first points to the first TWareType and the second that points to the last TWareType, isn't really an option, because a station could hold only 2 waretypes, the second one and perhaps the 30th one.
If the 2 vars would point to those 2nd and 30th TWareType, then that station would hold all TWareTypes that come in between too.

Or do you mean, create a TWare type (not a TWareType), let this TWare type have only 3 fields (previous, next and value (= pointer to the TWareType)) and "link" them together, setting up the "previous" and "next" fields as required, to form a chain of TWare type-instances?

And let the station have a pointer to the first TWare type-instance (the start of the chain)?

Edit: Why didn't I think of that?
I remember someone doing this, while reading your post (and replying here).

I've never done this before myself, but thanks that's a great way.
Now all I have to do, is create the system to do all this.
Thanks.


PowerPC603(Posted 2005) [#4]
It already works (I can already add tradable wares to any station):
Type TWare
	Field prev.TWare
	Field nex.TWare
	Field value.TWareType
	Field price%
End Type

Type TStation
	Field Name$
	Field WareList.TWare ; This pointer specifies the start of a custom linked list of tradable wares (the list can be as long as needed)
End Type



Function AddWareToStation(Station.TStation, WareTypeName$, price%)
	; Find the last TWare (the last TWare instance of the chain)
	Local LastTWare.TWare = FindLastTWare(Station)
	Local TempTWare.TWare

	; If the station already has a ware, do the first part (add a ware to the chain), else the second part (create the first ware)
	If Station\WareList <> Null Then
		; Temporarily store the address of the last TWare in the chain (is needed to set the "prev" field for a new TWare
		TempTWare = LastTWare

		; Set the "nex" field of the last TWare to point to a new TWare
		LastTWare\nex = New TWare
		; Get the address of the newly added TWare
		LastTWare = LastTWare\nex

		; Set fields for this new TWare
		LastTWare\prev = TempTWare
		; Set the price for the new TWare
		LastTWare\price% = price
		; Let the TWare point to a specific TWareType
		LastTWare\value = FindTWareType(WareTypeName$)
	Else
		; Let the WareList field point to a new TWare
		Station\WareList = New TWare
		; Set the price for this new TWare
		Station\WareList\price% = price
		; Let the TWare point to a specific TWareType
		Station\WareList\value = FindTWareType(WareTypeName$)
	EndIf
End Function

Function FindLastTWare.TWare(Station.TStation)
	Local a.TWare

	If Station\WareList <> Null Then
		a = Station\WareList

		While a\nex <> Null
			a = a\nex
		Wend
	EndIf

	Return a
End Function


Is this good coding?