variable for type's fieldname?

Blitz3D Forums/Blitz3D Beginners Area/variable for type's fieldname?

is there some way of accessing a field in a type by using a variable name

instead of:

t.trigger=new trigger
t\xposition = 1

what if i had 'xposition' in a variable?

t\{fieldname} = value

is there any way to do this?

it would make data loading so much easier, because you could write nice files like this:

[newobject]=triggerarea
triggerid=4
x=10
z=10
width=5
depth=5

and be able to add new fields without having to add lines to your loading routine. even with a nice file structure like this, currently my load routine has to have at least 1 or 2 lines to handle each and every field. it's really clumsy. (where are perl hashes when you need them most??)

i don't want to get away from using types, but i guess if i had to i could use the 'soups' routines in the code archives. it's just that i anticipate a performance hit from the string manipulation going on during runtime.

anyone have any ideas?

I've read through this 3 times and I still don't understand the issue...

I think he wants some sort of eval function for use with type fields.
(Not that I can see the point of it).

I've been looking for this too.

My game will use some sort of INI-files, where there are blocks of data, while each block contains several lines of data (or parameters) like this:

[Sector]
Name              = Sol system
Description       = This sector is the best know sector
PositionX         = 250
PositionY         = 250
Race              = Terrans

[Sector]
Name              = Barnards star
Description       = This sector is an agricultural one
PositionX         = 200
PositionY         = 180
Race              = Aliens


When I'm reading this file, I check for a data-block (= "[Sector]").
When such a line is found, I read all following lines until there's an empty line.

But the issue is reading each line (I can do it already, but in a clumsy way).

For every line I read from the file, I split the word before the equal sign and the one after the sign into two variables: the first one is "ParameterName" and the second is "ParameterValue".
Then I try to find a match for the parametername (with a select case statement), where I put the value in the correct field of a type.

But it would be easier if I could use the content of the variable "ParameterName" as the fieldname.

Now I do this (NOTE: I use arrays of types to store my data):
        Select ParameterName$
            Case "Name"
                ArraySectors(SectorNumber)\Name$ = ParameterValue$
            Case "Description"
                ArraySectors(SectorNumber)\Description$ = ParameterValue$
            Case "PositionX"
                ArraySectors(SectorNumber)\PositionX% = ParameterValue$
            Case "PositionY"
                ArraySectors(SectorNumber)\PositionY% = ParameterValue$
            Case "Race"
                ArraySectors(SectorNumber)\Race$ = ParameterValue$
        End Select


If I just could use something like this:
ArraySectors(SectorNumber)\ParameterName$ = ParameterValue$


then it would be simpler (of course the type must have the field where the ParameterName would point to).

The above line would use the content of the variable "ParameterName" (example: "Name") as the field-pointer (or how would you call it) and put the value (content) of "ParameterValue" in the Name-field of the type.

Can't you just use an array within a type?
ArraySectors(SectorNumber)\ParameterName[pm] = ParameterValue

Notice the square brackets (not parenthesis)...
Type atype
	Field normalfield
	Field anarray[50]
End Type

typeinstance.atype = New atype
typeinstance\normalfield = 5
typeinstance\anarray[4] = 27

Print typeinstance\normalfield
For iter = 1 To 10
	Print typeinstance\anarray[iter]
Next

WaitKey()


I'm not sure if that would be possible. When the compiler compiles your program, it replaces variable names with memory pointers. The compiler checkes to make sure the fields exists at compile time. I guess you could make a system where such a thing would be possible, but that would greatly slow down the use of types. Better to have the slowdown at the beginning of your program parsing the parameters than during the program where your types are being accessed n times per second.

Yeah, Tom's right. I had a similar idea whereby a value was read, then another value was loaded based on the read variable. Because it was unknown at Compilation time, I got an error.


Can't you just use an array within a type?



Actually no, I can't do that.
Each index of the array represents a sector (solar system) within my game, and I use the types in those arrays to hold all data about a sector.

Doing the reverse is even more complex (for my game anyways).
Besides, when I'm reading station- and planet-data, I'm using 2-D arrays (and for commodities being sold there even 3-D arrays), so that's not an option.

@ TomToad: Thanks for clearing that up.
Now I see why it cannot be done (in Blitz anyway).

I wouldn't try to do this with types. IMO, it would be a better choice to use XML to store the data - thus allowing you to add/remove things easily without having to mess with loading and saving routines every time you want to try something different.

galactic Allegiance uses a complex Type structure, read from a file when a new 'sector' (solar system) As an example, here's an extract from the sector builder:

;SKYBOX

Skybox=CreateSphere(20)
ScaleMesh skybox,(shldlong+1)/2,(shldlong+1)/2,(shldlong+1)/2
FlipMesh skybox
EntityOrder skybox,1

If flight_mode$="Space" Then skytext=LoadTexture ("Sectors"+Current_Sector$+"\box.bmp")

If flight_mode$="Atmosphere"
skytext=LoadTexture ("Sectors"+Current_Sector$+""+locality$+"\box.bmp")
EndIf


EntityTexture skybox,skytext
FreeTexture skytext
EntityParent skybox,ship

If wire=1 Then EntityAlpha skybox,0

EntityPickMode skybox,0



If flight_mode$="Space"
	;CREATE PLANET & MOONS

	MoonTexture=LoadTexture("Visual\3D\LUNARtxt.jpg")

	PlanetTexture=LoadTexture("Sectors"+Current_Sector$+""+Locality$+"\PLANETtxt.jpg")

			SectorPlanetData=OpenFile("Sectors"+Current_Sector$+""+Locality$+"\PlanetData.txt")
			PlanetClass$=ReadLine(SectorPlanetData)
			PlanetRadius=ReadLine(SectorPlanetData)
			PlanetRings=ReadLine(SectorPlanetData)
			PlanetMoons=ReadLine(SectorPlanetData)
			NewTarget.RadarTargets=New RadarTargets

	PlanetMesh=CreateSphere(50)
	ScaleMesh PlanetMesh,(PlanetRadius/20),(PlanetRadius/19),(PlanetRadius/20)
	EntityTexture PlanetMesh,PlanetTexture
	FreeTexture PlanetTexture

	EntityType PlanetMesh,9,False

	EntityPickMode PlanetMesh,1
	EntityRadius PlanetMesh,(PlanetRadius/20),(PlanetRadius/19)

	NameEntity PlanetMesh,Locality$

	NewTarget\Name$=(Locality$+" - "+PlanetClass$)
	NewTarget\TargetType$="PLANET"
	NewTarget\TargetColourRed=160
	NewTarget\TargetColourGreen=160
	NewTarget\TargetColourBlue=160
	NewTarget\TargetEntityHandle=PlanetMesh
	
	
		If PlanetMoons>0

			spread#=(360/PlanetMoons)

				For g=1 To PlanetMoons
				
					MoonData$=ReadLine(SectorPlanetData)

						NewMoon.Moonstype=New MoonsType
						NewMoon\Mesh=CreateSphere(20)
						NewMoon\Name$=MoonData$
						NewMoon\ParentPlanet$=Locality$
						ScaleMesh NewMoon\Mesh,50,50,50
						EntityTexture NewMoon\Mesh,MoonTexture
					
							RotateEntity NewMoon\Mesh,0,(spread#*g)-180,0
							MoveEntity NewMoon\Mesh,0,Rand(-50,50),Rand(PlanetRadius/5,PlanetRadius/4)
							EntityParent NewMoon\Mesh,PlanetMesh,1
					
							EntityType NewMoon\Mesh,10,False
					
							EntityPickMode NewMoon\Mesh,1
							EntityRadius NewMoon\Mesh,50
					
					NewTarget.RadarTargets=New RadarTargets

					NewTarget\Name$=(NewMoon\Name$)
					NewTarget\TargetType$="SATELLITE"
					NewTarget\TargetColourRed=100
					NewTarget\TargetColourGreen=100
					NewTarget\TargetColourBlue=100

					NameEntity NewMoon\Mesh,NewMoon\Name$

					NewTarget\TargetEntityhandle=NewMoon\Mesh

				Next
			
		EndIf
	

			PlanetStructs=ReadLine(SectorPlanetData)
			PlanetX=ReadLine(SectorPlanetData)
			PlanetY=ReadLine(SectorPlanetData)
			PlanetZ=ReadLine(SectorPlanetData)

			CloseFile (SectorPlanetData)
	
			If wire=0 And PlanetRings=1
				RingSprite=LoadSprite("Sectors"+Current_Sector$+""+Locality$+"\RING.jpg")
				SpriteViewMode RingSprite,2
				EntityFX RingSprite,16
				EntityAlpha RingSprite,0.8
				ScaleSprite RingSprite,(PlanetRadius/9),(PlanetRadius/7)
				TurnEntity RingSprite,80,0,0
				PositionEntity RingSprite,EntityX(PlanetMesh),EntityY(PlanetMesh),EntityZ(PlanetMesh)
				EntityParent RingSprite,PlanetMesh
			EndIf
			
	PositionEntity PlanetMesh,PlanetX,PlanetY,PlanetZ

	FreeTexture MoonTexture

EndIf




;STAR


SectorStarData=OpenFile("Sectors"+Current_Sector$+"\Stars.txt")

	StarName$=ReadLine(SectorStarData)
	StarClass$=ReadLine(SectorStarData)
	StarLightRed=ReadLine(SectorStarData)
	StarLightGreen=ReadLine(SectorStarData)
	StarLightBlue=ReadLine(SectorStarData)

CloseFile(SectorStarData)



If wire=0
	SunSprite=LoadSprite("Sectors"+Current_Sector$+""+StarName$+".bmp")
	ScaleSprite SunSprite,5,5
	EntityOrder SunSprite,1
	EntityFX SunSprite,8
	sunsphere=CreateSphere(3)
	EntityOrder sunsphere,1
	EntityAlpha sunsphere,0
	EntityParent sunsphere,sunsprite
EndIf

If wire=1
	SunSprite=CreateSphere(15)
	ScaleEntity SunSprite,5,5,5
	EntityOrder SunSprite,1
EndIf

Sunlight=CreateLight(1)
LightColor Sunlight,StarLightRed,StarLightGreen,StarLightBlue

MoveEntity SunSprite,-35,85,45
PointEntity sunlight,sunsprite
MoveEntity sunlight,-35,85,45

PointEntity Sunlight,ship

EntityParent SunSprite,skybox
EntityAlpha SunSprite,1

NameEntity SunSprite,StarName$

EntityParent Sunlight,SunSprite

;RESOLVING FOR STAR ON RADAR

newtarget.RadarTargets= New radartargets
NewTarget\Name$=(StarName$)
NewTarget\TargetType$="STAR"
NewTarget\TargetColourRed=255
NewTarget\TargetColourGreen=220
NewTarget\TargetColourBlue=50

If wire=0
NewTarget\TargetEntityhandle=sunsphere
EndIf

If wire=1
NewTarget\TargetEntityhandle=sunsprite
EndIf








If flight_mode$="Space"

			;STRUCTURES
		SectorStructData=OpenFile("Sectors"+Current_Sector$+""+Locality$+"\Structure.txt")
		
		For f=1 To PlanetStructs

			NewStruct.Buildings=New Buildings
			NewStruct\StructType$=ReadLine (SectorStructData)
			NewStruct\StructName$=ReadLine (SectorStructData)
			NewStruct\Allegiance$=ReadLine (SectorStructData)
			NewStruct\X=ReadLine (SectorStructData)
			NewStruct\Y=ReadLine (SectorStructData)
			NewStruct\Z=ReadLine (SectorStructData)
			NewStruct\Armour=ReadLine (SectorStructData)
			NewStruct\Shield=ReadLine (SectorStructData)
			NewStruct\Weapon$=ReadLine (SectorStructData)
			NewStruct\Mesh=LoadMesh("Visual\3D"+NewStruct\StructType$+".b3d")
	
			NewStruct\PartoPlanet=ReadLine(SectorStructData)
			NewStruct\Rotate=ReadLine(SectorStructData)
	
			;POSITION SHIP

			If NewStruct\StructName$=Docking_Name$ 
				shipstartX#=(NewStruct\X)
				shipstartY#=(NewStruct\Y)
				shipstartZ#=(NewStruct\Z+topspeed#)
			EndIf


	
			structexture=LoadTexture("Visual\3D"+NewStruct\StructType$+"txt.bmp")

		EntityPickMode NewStruct\Mesh,2


		If wire=0 Then EntityTexture NewStruct\Mesh,structexture
	
		FreeTexture structexture
	
		NameEntity NewStruct\Mesh,NewStruct\StructName$

		NewTarget.RadarTargets=New RadarTargets
		NewTarget\Name$=(Locality$+"-"+NewStruct\StructName$)
		NewTarget\TargetType$="STRUCTURE"
		NewTarget\TargetColourRed=110
		NewTarget\TargetColourGreen=130
		NewTarget\TargetColourBlue=250
		NewTarget\TargetEntityHandle=NewStruct\Mesh
		NewTarget\Allegiance$=NewStruct\Allegiance$

	EntityType NewStruct\Mesh,10,False

		PositionEntity NewStruct\Mesh,NewStruct\X,NewStruct\Y,NewStruct\Z
		If NewStruct\ParToPlanet=1 Then EntityParent NewStruct\Mesh,PlanetMesh





		Next
	
			CloseFile (sectorstructdata)

EndIf













If flight_mode$="Atmosphere"

atmosdat=OpenFile("Sectors"+Current_Sector$+""+Locality$+"\Atmosphere Data.txt")
ambred=ReadLine(atmosdat)
ambgreen=ReadLine(atmosdat)
ambblue=ReadLine(atmosdat)

GStructs=ReadLine(atmosdat)

CloseFile(atmosdat)

;STRUCTURES
GroundStructData=OpenFile("Sectors"+Current_Sector$+""+Locality$+"\Ground Structure.txt")
For f=1 To GStructs

	NewStruct.Buildings=New Buildings
	NewStruct\StructType$=ReadLine (GroundStructData)
	NewStruct\StructName$=ReadLine (GroundStructData)
	NewStruct\Allegiance$=ReadLine (GroundStructData)
	NewStruct\X=ReadLine (GroundStructData)
	NewStruct\Y=ReadLine (GroundStructData)
	NewStruct\Z=ReadLine (GroundStructData)
	NewStruct\Armour=ReadLine (GroundStructData)
	NewStruct\Shield=ReadLine (GroundStructData)
	NewStruct\Weapon$=ReadLine (GroundStructData)
	
	CloseFile (GroundStructData)
	
					;POSITION SHIP

			If NewStruct\StructName$=Docking_Name$
				shipstartX#=(NewStruct\X)
				shipstartY#=(NewStruct\Y)
				shipstartZ#=(NewStruct\Z+topspeed#)
			EndIf

	
	NewStruct\Mesh=LoadMesh("Visual\3D"+NewStruct\StructType$+".b3d")
	
	structexture=LoadTexture("Visual\3D"+NewStruct\StructType$+"txt.bmp")

		EntityPickMode NewStruct\Mesh,2

	If wire=0 Then EntityTexture NewStruct\Mesh,structexture
	FreeTexture structexture
	
	NameEntity NewStruct\Mesh,NewStruct\StructName$

	NewTarget.RadarTargets=New RadarTargets
		NewTarget\Name$=(Locality$+"-"+NewStruct\StructName$)
		NewTarget\TargetType$="STRUCTURE"
		NewTarget\TargetColourRed=110
		NewTarget\TargetColourGreen=130
		NewTarget\TargetColourBlue=250
		NewTarget\TargetEntityHandle=NewStruct\Mesh
		NewTarget\Allegiance$=NewStruct\Allegiance$

	EntityType NewStruct\Mesh,10,False

PositionEntity NewStruct\Mesh,NewStruct\X,NewStruct\Y,NewStruct\Z

Next


EndIf











If flight_mode$="Space"
;Asteroid Field

Max_Sector_Roids=Rand(7,30)

For f = 1 To Max_Sector_Roids

setup_roid.sector_roid=New sector_roid


debris=Rand(20,40)
composition=100-debris
setup_roid\ICE=Rand(0,70)
composition=(composition-(setup_roid\ICE))
setup_roid\METAL_ORE=Rand(0,composition)
composition=(composition-(setup_roid\METAL_ORE))
setup_roid\MINERAL=Rand(0,composition)
composition=(composition-(setup_roid\MINERAL))
setup_roid\PRECIOUS_METALS=Rand(0,composition)
composition=composition-((setup_roid\PRECIOUS_METALS))
setup_roid\HYDROCARBONS=Rand(0,composition)
composition=composition-((setup_roid\HYDROCARBONS))
setup_roid\RADIOACTIVES=Rand(0,composition)
composition=composition-((setup_roid\RADIOACTIVES))
setup_roid\DEBRIS=composition+debris

roid_seg=Rand(3,9)
setup_roid\mesh=CreateSphere(roid_seg)
roidtxt=Rand(1,7)
setup_roid\texture=LoadTexture("Visual\3D\roid"+roidtxt+"txt.bmp")

setup_roid\PosX=Rnd(-50000,50000)
setup_roid\PosY=Rnd(-10000,10000)
setup_roid\PosZ=Rnd(-50000,50000)

PositionEntity setup_roid\mesh,setup_roid\posX,setup_roid\PosY,setup_roid\PosZ
TurnEntity setup_roid\mesh,Rand(0,360),Rand(0,360),Rand(0,360)
scalerX#=Rnd(3,12)
scalerY#=Rnd(3,8)
scalerZ#=Rnd(3,10)
ScaleMesh setup_roid\mesh,scalerX#,scalerY#,scalerZ#

EntityType setup_roid\mesh,7

EntityPickMode setup_roid\mesh,2

If wire=0 Then EntityTexture setup_roid\mesh,setup_roid\texture
FreeTexture setup_roid\texture

setup_roid\name$="ASTEROID"

NameEntity setup_roid\mesh,Upper$((Left$(locality$,2)))+(scalerX#)+(scalerY#)+(scalerZ#)

	If Ast_Rotacol=1

			NewTarget.RadarTargets=New RadarTargets
		
			NewTarget\Name$=(EntityName$(setup_roid\mesh))
			NewTarget\TargetType$="ASTEROID"
			NewTarget\TargetColourRed=130
			NewTarget\TargetColourGreen=120
			NewTarget\TargetColourBlue=50
			NewTarget\TargetEntityHandle=setup_roid\Mesh
	EndIf


Next


EndIf





; RADAR INITIAL TARGET DETAILS

RadarSorter.RadarTargets=First RadarTargets
TargetEntity=RadarSorter\TargetEntityHandle


;CREATE TERRAIN

If flight_mode$="Atmosphere"

Terrain=LoadTerrain("Sectors"+current_sector$+""+locality$+"\Terrain.JPG")
TerrainDetail terrain,8000,True
Terrain_Texture=LoadTexture("Sectors"+current_sector$+""+locality$+"\Terrain Texture.JPG")

ScaleTexture Terrain_Texture,512,512
ScaleEntity terrain,512,4096,512

PositionEntity terrain,-131072,((0-50)-(TerrainY#(Terrain,EntityX#(ship,1),0,EntityZ#(ship,1)))),-131072,1
EntityType Terrain,15

EntityTexture Terrain,Terrain_Texture

FreeTexture Terrain_Texture


EndIf