Page 1 of 1

Map problem

Posted: Tue Sep 14, 2010 4:08 pm
by Jago
So, I'm creating a shooting game which reads all its weapons from a script an then uses a structured map to store the wepon information. Problem is that the information doesn't seem to go into the map. When I print out weapons attributes, it's just zero after zero. Can anybody help? Here's the structure and map declaration:

Code: Select all

Structure Weapon
	name.s
	
	damage.f
	
	shootSpeed.i
	
	bullets.i
	bulletSpeed.f
	bulletSize.i
	
	range.f
	
	angScatter.i
	speedScatter.i
	rangeScatter.i
	
	cStart.i
	cEnd.i
	
	List special.c()
EndStructure

Global NewMap weapons.Weapon()
And here's the script parser:

Code: Select all

Procedure loadWeapons(path.s)
	
	If ReadFile(0,path)
		
		While Not Eof(0)
			
			tag.s = Trim(ReadString(0))
			
			
			If Trim(LCase(StringField(tag,1,"="))) = "[weapon]"
				
				name.s = Trim(StringField(tag,2,"="))
				
				weapons(name)\name = name
	
				Repeat
					
					line.s = ReadString(0)

					attr.s = Trim(LCase(StringField(line,1,"=")))
					value.i = Val(Trim(StringField(line,2,"=")))
					
					Print(attr + "  ")
					Print(Str(value))
					PrintN("")
					
					Select attr
						Case "damage"
							weapons()\damage = ValF(Trim(StringField(line,2,"=")))
						Case "sspeed"
							weapons()\shootSpeed = value
						Case "bspeed"
							weapons()\bulletSpeed = ValF(Trim(StringField(line,2,"=")))
						Case "bullets"
							weapons()\bullets = value
						Case "bsize"
							weapons()\bulletSize = value
						Case "ascatter"
							weapons()\angScatter = value
						Case "sscatter"
							weapons()\speedScatter = value
						Case "range"
							weapons()\range = ValF(Trim(StringField(line,2,"=")))
						Case "rscatter"
							weapons()\rangeScatter = value
						Case "cstart"
							values.s = StringField(line,2,"=")
							
							r.c = Val(StringField(values,1,","))
							g.c = Val(StringField(values,2,","))
							b.c = Val(StringField(values,3,","))
							
							weapons()\cStart = RGB(r,g,b)
						Case "cend"
							values.s = StringField(line,2,"=")
							
							r.c = Val(StringField(values,1,","))
							g.c = Val(StringField(values,2,","))
							b.c = Val(StringField(values,3,","))
							
							weapons()\cEnd = RGB(r,g,b)
						Case "special"
							values.s = LCase(StringField(line,2,"="))
							valueCount.c = CountString(values,",") + 1
							
							For i = 1 To valueCount
								AddElement(weapons()\special())
								
								Select Trim(StringField(values,i,","))
									Case "explode"
										weapons()\special() = #S_EXPLODE
									Case "penetrate"
										weapons()\special() = #S_PENETRATE
									Case "ignite"
										weapons()\special() = #S_IGNITE
									Case "slow"
										weapons()\special() = #S_SLOW
								EndSelect
							Next i
					EndSelect

					
				Until line = "[End]"
				
			EndIf
			
		Wend
		
		CloseFile(0)
	EndIf
	
EndProcedure
And an example weapon:

Code: Select all

[weapon] = Pistol
	damage = 10
	sSpeed = 500
	bSpeed = 500
	bullets = 1
	aScatter = 5
	sScatter = 0
	range = 300
[End]

Re: Map problem

Posted: Tue Sep 14, 2010 4:32 pm
by #NULL
it seems to work here.

Code: Select all

Structure Weapon
  name.s
  
  damage.f
  
  shootSpeed.i
  
  bullets.i
  bulletSpeed.f
  bulletSize.i
  
  range.f
  
  angScatter.i
  speedScatter.i
  rangeScatter.i
  
  cStart.i
  cEnd.i
  
  List special.c()
EndStructure

Global NewMap weapons.Weapon()


Procedure loadWeapons(path.s)
  
  PrintN("parsing: "+GetCurrentDirectory()+path)
  PrintN("")
  
  If ReadFile(0,path)
    
    While Not Eof(0)
      
      tag.s = Trim(ReadString(0))
      
      
      If Trim(LCase(StringField(tag,1,"="))) = "[weapon]"
        
        name.s = Trim(StringField(tag,2,"="))
        
        weapons(name)\name = name
        
        Repeat
          
          line.s = ReadString(0)
          
          attr.s = Trim(LCase(StringField(line,1,"=")))
          value.i = Val(Trim(StringField(line,2,"=")))
          
          Print(attr + "  ")
          Print(Str(value))
          PrintN("")
          
          Select attr
            Case "damage"
              weapons()\damage = ValF(Trim(StringField(line,2,"=")))
            Case "sspeed"
              weapons()\shootSpeed = value
            Case "bspeed"
              weapons()\bulletSpeed = ValF(Trim(StringField(line,2,"=")))
            Case "bullets"
              weapons()\bullets = value
            Case "bsize"
              weapons()\bulletSize = value
            Case "ascatter"
              weapons()\angScatter = value
            Case "sscatter"
              weapons()\speedScatter = value
            Case "range"
              weapons()\range = ValF(Trim(StringField(line,2,"=")))
            Case "rscatter"
              weapons()\rangeScatter = value
            Case "cstart"
              values.s = StringField(line,2,"=")
              
              r.c = Val(StringField(values,1,","))
              g.c = Val(StringField(values,2,","))
              b.c = Val(StringField(values,3,","))
              
              weapons()\cStart = RGB(r,g,b)
            Case "cend"
              values.s = StringField(line,2,"=")
              
              r.c = Val(StringField(values,1,","))
              g.c = Val(StringField(values,2,","))
              b.c = Val(StringField(values,3,","))
              
              weapons()\cEnd = RGB(r,g,b)
            Case "special"
              values.s = LCase(StringField(line,2,"="))
              valueCount.c = CountString(values,",") + 1
              
              For i = 1 To valueCount
                AddElement(weapons()\special())
                
                Select Trim(StringField(values,i,","))
                  Case "explode"
                    weapons()\special() = 101;#S_EXPLODE
                  Case "penetrate"
                    weapons()\special() = 102;#S_PENETRATE
                  Case "ignite"
                    weapons()\special() = 103;#S_IGNITE
                  Case "slow"
                    weapons()\special() = 104;#S_SLOW
                EndSelect
              Next i
          EndSelect
          
          
        Until line = "[End]"
        
      EndIf
      
    Wend
    
    CloseFile(0)
  EndIf
  
EndProcedure


OpenConsole()
loadWeapons("parse.txt")

PrintN("--------")
ForEach weapons()
  PrintN(MapKey(weapons()))
  PrintN("    "+    weapons()\name )
  PrintN("    "+Str(weapons()\damage))
  PrintN("    "+Str(weapons()\shootSpeed))
  PrintN("    "+"...")
Next
PrintN("--------")

Input()

console shows the following:

Code: Select all

parsing: D:\Dokumente und Einstellungen\martin\Desktop\parse.txt

damage  10
sspeed  500
bspeed  500
bullets  1
ascatter  5
sscatter  0
range  300
[end]  0
--------
Pistol
    Pistol
    10
    500
    ...
--------
does your ReadFile() succeed? wrong path maybe?

Re: Map problem

Posted: Tue Sep 14, 2010 4:42 pm
by Jago
ReadFile() does succeed, and the parser prints out correct info during the process, but after that when I try to print out the info from the map there's nothing except the map key.

Re: Map problem

Posted: Tue Sep 14, 2010 5:36 pm
by Trond
but after that when I try to print out the info from the map there's nothing except the map key.
So essentially your problem is with the printing. Show us the faulty code.

Re: Map problem

Posted: Tue Sep 14, 2010 5:54 pm
by Jago
Trond wrote:So essentially your problem is with the printing. Show us the faulty code.
Don't think so, because the settings don't work in the game either. But here's the code anyway:

Code: Select all

Procedure printWeapons()
	ClearConsole()
	ForEach weapons()
		PrintN("Name: " + MapKey(weapons()))
		PrintN("Damage: " + Str(weapons()\damage))
		PrintN("Shoot speed: " + Str(weapons()\shootSpeed))
		PrintN("Bullet speed: " + Str(weapons()\bulletSpeed))
		PrintN("Bullet count: " + Str(weapons()\bullets))
		PrintN("Bullet size: " + Str(weapons()\bulletSize))
		PrintN("Angle scatter: " + Str(weapons()\angScatter))
		PrintN("Speed scatter: " + Str(weapons()\speedScatter))
		PrintN("Range: " + Str(weapons()\range))
		PrintN("Range scatter: " + Str(weapons()\rangeScatter))
		PrintN("Color start: " + Str(Red(weapons()\cStart)) + "," + Str(Green(weapons()\cStart)) + "," + Str(Blue(weapons()\cStart)))
		PrintN("Color end: " + Str(Red(weapons()\cEnd)) + "," + Str(Green(weapons()\cEnd)) + "," + Str(Blue(weapons()\cEnd)))
		PrintN("")
	Next
EndProcedure

Re: Map problem

Posted: Tue Sep 14, 2010 6:08 pm
by Trond
Ok, can you post a code that compiles without modification and shows the problem?

Re: Map problem

Posted: Tue Sep 14, 2010 8:33 pm
by Jago
Here's the whole source for the game so far plus the weapons script. http://up.servut.us/25380

Re: Map problem

Posted: Tue Sep 14, 2010 8:51 pm
by Trond
Here's your problem:
You use Trim() to trim space characters, but your weapon attributes are indented with tab characters.

The reason why it worked with the example weapon was that it was indented with space characters (maybe converted by the forum software).

My suggestion is to use the Preference library, which handles ini-like files more easily.

Re: Map problem

Posted: Wed Sep 15, 2010 7:05 am
by Jago
Thanks for your help. I couldn't have ever figured that out.

Re: Map problem

Posted: Wed Sep 15, 2010 9:41 am
by Trond
Here's how to figure out such problems (which are quite common): Add a dot before and after every printed value. Extra blank characters then become apparent.

I discovered this particular problem by changing this:

Code: Select all

Print(attr + "  ")
into this:

Code: Select all

Print("." + attr + ".  ")