GCDW Impact Bug, or "Why does grass refuse to be shot?"

Hi, I’m writing in today to write about a problem with the GDCW base. I’ve been developing a weapon since December and the bullets worked just fine, worked on all surfaces. Five months and an update later, I come back to see that I can shoot every material except grass. When a bullet is on the path to hit the ground, it freezes in mid-air, the impact decals start multiplying and causes some fps lag and blowing up the console before disappearing. If needed, I can make a video showing this. The console errors in question are as followed:


 [ERROR] addons/super scope 6/lua/entities/scopesphere/init.lua:149: attempt to index a nil value
  1. unknown - addons/super scope 6/lua/entities/scopesphere/init.lua:149


[ERROR] addons/super scope 6/lua/effects/scope_impact1/init.lua:46: attempt to index a nil value
  1. unknown - addons/super scope 6/lua/effects/scope_impact1/init.lua:46



Here are the chunks those lines are in:


 [Scopeshere init Lines 148-155]

		local Dot = self.Entity:GetUp():DotProduct(tr.HitNormal)
		if (Dot*math.Rand(0.04,1)*mats[tr.MatType][1])>-0.04 then		// If it doesnt hit head on, <--
			self.Flightvector = (self.Flightvector:Length()*(1+Dot*1.2)) * (self.Entity:GetUp()+(tr.HitNormal*Dot*-0.8)+(VectorRand()*0.1))
			self.Entity:SetAngles(self.Flightvector:Angle() + Angle(90,0,0))
			self.Entity:SetPos(tr.HitPos+tr.HitNormal)
			self.Entity:NextThink( CurTime() )
			return true
			end	



 [Scope_Impact init Lines 33-58]

function EFFECT:Init(data)
self.Pos 		= data:GetOrigin()		// Pos determines the global position of the effect			//

self.DirVec 		= data:GetNormal()		// DirVec determines the direction of impact for the effect		//
self.PenVec 		= data:GetStart()		// PenVec determines the direction of the round for penetrations	//
self.Scale 		= data:GetScale()		// Scale determines how large the effect is				//
self.Radius 		= data:GetRadius() or 1		// Radius determines what type of effect to create, default is Concrete	//

self.Emitter 		= ParticleEmitter( self.Pos )	// Emitter must be there so you don't get an error			//


	self.Mat=math.ceil(self.Radius) print( self.Mat )
 
	if     mats[self.Mat][1]==1 then	self:Dust()  <-- 
	elseif mats[self.Mat][1]==2 then	self:Dirt()
	elseif mats[self.Mat][1]==3 then	self:Sand()
	elseif mats[self.Mat][1]==4 then	self:Metal()
	elseif mats[self.Mat][1]==5 then	self:Smoke()
	elseif mats[self.Mat][1]==6 then	self:Wood()
	elseif mats[self.Mat][1]==7 then	self:Glass()
	elseif mats[self.Mat][1]==8 then	self:Blood()
	elseif mats[self.Mat][1]==9 then	self:YellowBlood()
	else 					self:Smoke()
	end

end


A similar thread with this problem was made about three weeks ago, with code_gs asking the person to put print( self.Mat ) after it was declared. Unfortunately, the thread kinda stopped there.

If it helps, the number that prints inbetween both errors is 85. If I haven’t done this correctly, I apologize. If there’s anything else I should put in this post, let me know and I’ll edit them in ASAP.

The mats table doesn’t have the material you are trying to read from it so it is returning nil.

What do you suppose I should do, then? Is there a new material I can replace it with?

Why are you using integers instead of the enumerations? The numbers the enumerations represent can and have changed before. Try using MAT_GRASS etc instead of just numbers.

I’m just going by what was there before. -snip-

Edit: After realizing that MAT_GRASS was missing in local mats list and feeling like an idiot, I managed to make progress: Now the impact effect plays, as well as the sound, but I still get console spam regarding this attempting to index a nil value:


if (Dot*math.Rand(0.04,1)*mats[tr.MatType][1])>-0.04 then

I’ve solved it! I’m going to post what I did in case people with the same issue google it and come across this thread:

I noticed there was a special instruction for shots hitting the water;



				if tr.MatType==83 then				//83 is wata
				local effectdata = EffectData()
				effectdata:SetOrigin( tr.HitPos )
				effectdata:SetNormal( tr.HitNormal )		// In case you hit sideways water?
				effectdata:SetScale( 15*self.EffectSize )	// Big splash for big bullets
				util.Effect( "watersplash", effectdata )
				self.Entity:Remove()
				return true
				end


And I decided to add a copy replacing the water MatType with the grass (85) and add the impact effect. Lo and behold, it works just fine. (The same had to be applied to snow, (74))

So essentially, the workaround looks like this:


                        if tr.MatType==85 then				//83 is wata
				local effectdata = EffectData()
				effectdata:SetOrigin( tr.HitPos )
				effectdata:SetNormal( tr.HitNormal )		// In case you hit sideways water?
				effectdata:SetScale(3*self.EffectSize )	// Big splash for big bullets
				util.Effect("scope_impact2",effectdata)
			        util.ScreenShake(tr.HitPos, 10, 5, 0.1, 200 )
			        util.Decal("scorch", tr.HitPos + tr.HitNormal, tr.HitPos - tr.HitNormal)
				self.Entity:Remove()
				return true
				end


You still shouldn’t be using the integers themselves, as they WILL break as new enumerations are added / removed from the game. The enumerations exist for a reason.