# Shooting trough Walls

How can i make my simple SWep shooting trough walls or ignore walls? (whatever is easier)

Just run a traceline and deal N damage to the enemy it reaches.

Penetration is usually done via recursion.

When you create a bullet, you add a Callback function. That function is basically where the bullet hits along with other info. If it his a wall, and the wall is thin enough to penetrate based on the type of the bullet you’d essentially have the “player shoot another bullet / firebullets” using the same information, but instead of the bullet being generated at the player shoot position, you have it continue not from the hit position, but from the other side of the wall.

Obviously when using recursion you can have it continue forever, so ensure you have a distance where it won’t generate anymore bullets, have a max penetration, or ideally calculate stored energy and only penetrate until the energy is depleted.

Hope that helps.

actually it doesn’t help cause im a lua noob
what is a callback function?

that doesn’t really help at all, how is he supposed to get the width of the wall?

I’m pretty sure the old madcow base has world penetration, pop that open and take a look.

I don’t have my script anymore, but how i did it in like 2009 or 10 idr. was i’d run a trace, if it hit the world, i’d go a few units forward( on the same trajectory as the trace angle ). then run another trace, at the new position, same angle, if the trace hit the world again, i’d do nothing. If it didn’t, i’d create the bullet at the new point, fire it at the same angle. make sense?

keep in mind that is really not the ideal way to do this i’m just saying how i did it back in the day

Off topic: XP_Static, whats your steam name?

Width of the wall, is essentially getting the Normal of the trace, start pos + normal * x then going in reverse as traces don’t detect in / out. You have to go out then go back to get the width ( following the trajectory ).

A callback is when you define the bullet table you add:

[lua] Callback = function( attacker, tr, dmginfo )
return self:BulletCallback( attacker, tr, dmginfo );
end;[/lua]

Edit: To clarify, you then do stuff in that function such as generate a new bullet if the bullet is able to penetrate ( if it has enough energy, you need to code this ). Some people use a number, how many walls can it penetrate regardless of width. Some people use energy and say x units of energy is used per x width of each specific material type. There’s a bunch of different ways, but with recursion there needs to be an end otherwise you’ll have issues.

sounds complicated. what about completely ignore walls? is this easier?

My swep base code

[lua]function SWEP:CSShootBullet( dmg, recoil, numbul, cone, fireFrom, aimVector, distanceLeft, showTracerOverride )
numbul = numbul or 1
cone = cone or 0.01
distanceLeft = distanceLeft or self.MaxPenetration
fireFrom = fireFrom or self.Owner:GetShootPos()
aimVector = aimVector or self.Owner:GetAimVector()

``````for i = 1, numbul do
local showTracer = showTracerOverride or 0

if not showTracerOverride then
self.bulletNumber = self.bulletNumber + 1

if self.bulletNumber == self.TracerRarity then
self.bulletNumber = 0
showTracer = 1
end
end

local trueAim = aimVector + realSpread
local trace = {}
trace.start = fireFrom
trace.endpos = trace.start + ( trueAim * 1000000 )
trace.filter = self.Owner

local traceRes = util.TraceLine( trace )
local dir = traceRes.HitPos - trace.start
dir:Normalize()

local hitPosition = traceRes.HitPos

local bullet = {}
bullet.Num         = 1
bullet.Src         = fireFrom                -- Source
bullet.Dir         = dir                    -- Dir of bullet
bullet.Spread     = Vector( 0, 0, 0 )        -- Aim Cone
bullet.Tracer    = showTracer            -- Show a tracer on every x bullets
bullet.Force    = 5                        -- Amount of force to give to phys objects
bullet.Damage    = dmg

self.Owner:FireBullets( bullet )

distanceLeft = distanceLeft - hitPosition:Distance( fireFrom )

if distanceLeft &gt; 0 and not traceRes.Entity or not IsValid( traceRes.Entity ) or not traceRes.Entity:IsPlayer() then
for i = 1, self.MaxPenetration_Depth do
if distanceLeft &lt; ( i * 1000 ) then break else
local testPos = hitPosition + ( trueAim * i * 5 )

if util.IsInWorld( testPos ) then
self:CSShootBullet( dmg * .75, recoil, 1, 0, testPos, aimVector, distanceLeft - ( i * 1000 ), showTracer )
self:CSShootBullet( dmg * .75, recoil, 1, 0, testPos + ( trueAim * 5 ), aimVector * -1, -100, showTracer )

break
end
end
end
end
end

self.Weapon:SendWeaponAnim( ACT_VM_PRIMARYATTACK )         -- View model animation
self.Owner:MuzzleFlash()                                -- Crappy muzzle light
self.Owner:SetAnimation( PLAYER_ATTACK1 )                -- 3rd Person Animation
``````

end[/lua]

That looks exactly like perp code, which ends up generating TONS of bullets. By simply having 1 fence between you and your target, 1 bullet to the foot will kill on a weapon that has damage set to 5 or something small. I fixed that bug on HZ PERP because it was a serious problem. I wouldn’t recommend using that, it’s a poor example.

I am 100% certain that this code doesn’t make a large amount of bullets from shooting through a fence.