Can't remember how to do Types within types

BlitzPlus Forums/BlitzPlus Programming/Can't remember how to do Types within types

okee(Posted 2016) [#1]
I'm using Blitzplus to knock up a quick editor
I used to know how to do types within types but
doesn't seem to work the way I thought it did years ago

so basically if I have a type that has another type within it
Can i add multiple types to one instance of the main type
and have it associated with it

If I have a ship and i want to add a different weapon for each one
I thought i could add each weapon and then they would be associated with that ship
but it seems to output all 4 weapons for each ship
Not sure if the setup is incorrect or output









; type test
Graphics 1024,768

SetBuffer BackBuffer()

fntArial=LoadFont("Arial",20,False,False,False) 

SetFont fntArial 

; ship type
Type TShip
	Field Model$
	Field Weapons.TWeapon
End Type

; weapon each ship has
Type TWeapon
	Field WType$
	Field Name$
	Field Power
End Type

SetupShips()

While Not KeyHit(1) 
	Cls
	OutputData()
	Flip
Wend

; print to screen to test
Function OutputData()
	
	Local y = 10
	; print list of ships and weapons
	For Ship.TShip = Each TShip
		Text 10,y,"Ship type: " + Ship\Model$	  	
		y = y +15
		For Ship\Weapons = Each TWeapon
			Text 30,y,"Weapon Type: " + Ship\Weapons\wtype$ + " -- " +	"Weapon Name: " + Ship\Weapons\Name$ + " -- Weapon Power: " + Ship\Weapons\Power   	
			y = y +15
		Next	
	Next
	
	; output just the last ship
	s.Tship = Last TShip
		Text 10,y,"Ship type: " + s\Model$
		y = y +15
		For s\Weapons = Each TWeapon
			Text 30,y,"Weapon Type: " + s\Weapons\wtype$ + " -- " +	"Weapon Name: " + s\Weapons\Name$ + " -- Weapon Power: " + s\Weapons\Power   	
			y = y +15
		Next

	
End Function

; create the ships and add weapons
Function SetupShips()
	
	Local x
	Restore shipData
	
	; create 4 ships
	For x = 1 To 4
		Ship.TShip = New TShip
		Read Ship\Model$
	Next
	
	Restore weaponData
	
; testing by adding 4 weapons to the last ship
;	s.TShip = Last TShip
;	For x = 1 To 4
;		s\weapons.Tweapon = New TWeapon
;		Read s\weapons\WType
;		Read s\Weapons\Name
;		Read s\Weapons\Power
;	Next	
	
	
	; add 1 weapon to each ship
	; thought it would then just show 1 weapon per ship on output
	; but it's showing 4 for each
	For Ship.Tship = Each TShip
	
		Ship\Weapons.Tweapon = New TWeapon
		Read Ship\Weapons\WType
		Read Ship\Weapons\Name
		Read Ship\Weapons\Power
	
	Next
		


End Function		

.shipData
Data "Transporter", "Fighter","Cruiser", "Supply"

.weaponData
Data "Cannon", "Big cannon", 400
Data "Blaster", "laser Blaster", 100
Data "zapper", "Ion Zapper", 200
Data "None", "none", 0





Zethrax(Posted 2016) [#2]
Note that the code below was tested in Blitz3D. As far as I'm aware it should work the same in BlitzPlus.

If you want a single weapon or multiple weapons stored in separate fields then you'd do it like this:-

; ship type
Type TShip
	Field Model$
	Field Weapons.TWeapon
End Type

; weapon each ship has
Type TWeapon
	Field WType$
	Field Name$
	Field Power
End Type

ship.TShip = New TShip

; Use either of the methods below to create a weapon object and store its pointer in the ship object
;weapon.TWeapon = New TWeapon : ship\Weapons = weapon
ship\Weapons = New TWeapon

ship\Weapons\Name$ = "Cannon"

Print ship\Weapons\Name$

WaitKey
End


If you want multiple weapons stored as an indexable array then you'd do it like this:-

Const NUM_SHIP_WEAPONS = 2
Const MAX_SHIP_WEAPONS_INDEX = NUM_SHIP_WEAPONS - 1

; Ship weapon IDs.
Const SHIP_WEAPON_CANNON = 0
Const SHIP_WEAPON_HARPOON = 1


; ship type
Type TShip
	Field Model$
	Field Weapons.TWeapon[ MAX_SHIP_WEAPONS_INDEX ] ; Create a local array for the weapons.
End Type

; weapon each ship has
Type TWeapon
	Field WType$
	Field Name$
	Field Power
End Type

ship.TShip = New TShip

; Use either of the methods below to create a weapon object and store its pointer in the ship object
;weapon.TWeapon = New TWeapon : ship\Weapons[ SHIP_WEAPON_CANNON ] = weapon
;weapon.TWeapon = New TWeapon : ship\Weapons[ SHIP_WEAPON_HARPOON ] = weapon
ship\Weapons[ SHIP_WEAPON_CANNON ] = New TWeapon
ship\Weapons[ SHIP_WEAPON_HARPOON ] = New TWeapon

ship\Weapons[ SHIP_WEAPON_CANNON ]\Name$ = "Cannon"
ship\Weapons[ SHIP_WEAPON_HARPOON ]\Name$ = "Harpoon"

For i = 0 To MAX_SHIP_WEAPONS_INDEX
	Print ship\Weapons[ i ]\Name$
Next

WaitKey
End


If you want to be able to update the weapons polymorphically without having to care about the type of weapon then just use a Select Case setup:-

Function UpdateAllShipWeapons( ship.TShip )
	For weapon_id = 0 To MAX_SHIP_WEAPONS_INDEX
		UpdateShipWeapon( ship.TShip, weapon_id )
	Next
End Function


Function UpdateShipWeapon( ship.TShip, weapon_id )
	Select weapon_id
		Case SHIP_WEAPON_CANNON
			; Update code for the cannon goes here.
		Case SHIP_WEAPON_HARPOON
			; Update code for the harpoon goes here.
	End Select
End Function



okee(Posted 2016) [#3]
using the following code, simplified

; type test
Graphics 1024,768

SetBuffer BackBuffer()

fntArial=LoadFont("Arial",20,False,False,False) 

SetFont fntArial 

; ship type
Type TShip
	Field Model$
	Field Weapons.TWeapon
End Type

; weapon each ship has
Type TWeapon

	Field Name$

End Type

; create first ship
ship.TShip = New Tship
ship\model = "Ship A"
    ;create a wepaon for the ship
ship\weapons = New TWeapon
ship\Weapons\Name$ = "Weapon A1"

; create second ship
ship.TShip = New Tship
ship\model = "Ship B"

   ;create 2 weapons for this ship
ship\weapons = New TWeapon
ship\Weapons\Name$ = "Weapon B1"

ship\weapons = New TWeapon
ship\Weapons\Name$ = "Weapon B2"


While Not KeyHit(1) 
	Cls
	OutputData()
	
	Flip
Wend

; print to screen to test
Function OutputData()
	
	Local y = 10
	; print list of ships and weapons
	For Ship.Tship = Each TShip
		; print the ship model (parent type)
		Text 10,y,"Ship type: " + Ship\Model$	  	
		y = y +15
		; print all the weapons for that particular model (should only be 1 for each
		For Ship\Weapons = Each TWeapon
			Text 30,y,"Weapon Name: " + Ship\Weapons\Name$   	
			y = y +15
		Next	
	Next
	
End Function



I get the following result


Ship type: Ship A
Weapon Name: Weapon A1
Weapon Name: Weapon B1
Weapon Name: Weapon B2
Ship type: Ship B
Weapon Name: Weapon A1
Weapon Name: Weapon B1
Weapon Name: Weapon B2




whereas i thought it should be


Ship type: Ship A
Weapon Name: Weapon A1

Ship type: Ship B
Weapon Name: Weapon B1
Weapon Name: Weapon B2




Dan(Posted 2016) [#4]
As far as i know, you cant assign type in type directly, in blitzbasic.

To learn types, imagine you are editing a text file with notepad.

Type name is the filename.

Each line of text (in one filename) is a new type entry.
(each line contains the fields values, separated by comma)

So:
In your simplified example,you are displaying each TWeapon.txt which is NOT assigned to Tship.txt


Midimaster(Posted 2016) [#5]
in BlitzBasic you have no LIST of objects like in BlitzMax. There is only a common list for all members of a type. So if you use FOR/EACH you will always get all Weapons of all Ships.

If you can, change to BlitzMax. It is also free, but much more comfortable....

If you need BlitzPlus:
You have to invent a "LIST" type to have individual sub-list in each Ship. This could be done f.e. by an array, which contains the pointer to the corresponding weapons:

SetBuffer BackBuffer()

fntArial=LoadFont("Arial",20,False,False,False) 

SetFont fntArial 

; ship type
Type TShip
	Field Model$
	Field Weapon.TWeapon[9]
End Type

; weapon each ship has
Type TWeapon
	Field Name$
End Type

; create first ship
ship.TShip = New Tship
ship\model = "Ship A"

;create a wepaon for the ship
Weapon.TWeapon= New TWeapon
Weapon\Name$ = "Weapon A1"
Ship\Weapon[1]=Weapon


; create second ship
ship.TShip = New Tship
ship\model = "Ship B"

Weapon.TWeapon= New TWeapon
Weapon\Name$ = "Weapon B1"
Ship\Weapon[1]=Weapon

Weapon.TWeapon= New TWeapon
Weapon\Name$ = "Weapon B2"
Ship\Weapon[2]=Weapon


While Not KeyHit(1) 
	Cls
	OutputData()
	
	Flip
Wend

; print to screen to test
Function OutputData()
	
	Local y = 10
	; print list of ships and weapons
		For Weapon.TWeapon = Each TWeapon
			Text 30,y,"Weapon Name: " + Weapon\Name$   	
			y = y +15
		Next	

	For Ship.Tship = Each TShip
		; print the ship model (parent type)
		Text 10,y,"Ship type: " + Ship\Model$	  	
		y = y +15
		; print all the weapons for that particular model (should only be 1 for each
		For i%=0 To 8

				If Int(ship\Weapon[i])<>0
					Text 30,y,"Ship ARRAY Weapon Name: " + ship\Weapon[i]\Name
					y = y +15
				EndIf 
		Next
	Next
End Function



Bobysait(Posted 2016) [#6]
In it can help, here is a code using a small database for storing models to copy

Using a small linked-list stuff to manage multiple weapons per ship
It's both more complicated and easier at the same time.
It's based on MMO database, so it's how it "could have been done" for storing a big database and handling lots of objects without consuming too much RAM.




okee(Posted 2016) [#7]
Thanks for the examples lads, will test out these methods

 If you can, change to BlitzMax. It is also free, but much more comfortable....


Believe me I'd love to but just end up banging my head against a wall with the docs