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 :confused:
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 );

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.

Why you’re asking?

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
    local trueAim = aimVector + realSpread
    local trace = {}
        trace.start = fireFrom
        trace.endpos = trace.start + ( trueAim * 1000000 )
        trace.filter = self.Owner
        trace.mask = MASK_SHOT

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

    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 > 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 < ( 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 )

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


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.

[lua]trace.mask = MASK_SHOT[/lua]

Your examples are useless, at least I’m offering some code unlike claiming to be an awesome coder for HZ.