Skip to content

Comments

THE FUKIN SECONDARY FIRE FOR THE TERMS#19

Open
Regun2 wants to merge 2 commits intoStrawWagen:mainfrom
Regun2:termhunter_secfire
Open

THE FUKIN SECONDARY FIRE FOR THE TERMS#19
Regun2 wants to merge 2 commits intoStrawWagen:mainfrom
Regun2:termhunter_secfire

Conversation

@Regun2
Copy link
Contributor

@Regun2 Regun2 commented Feb 5, 2026

im finally able to do stuff again after being busy with personal stuff.

they use it when in danger :)
@Regun2
Copy link
Contributor Author

Regun2 commented Feb 5, 2026

this is probably very ehhhh code

@Regun2
Copy link
Contributor Author

Regun2 commented Feb 5, 2026

the AR2 ball was the most annoying to get working properly

Copy link
Owner

@StrawWagen StrawWagen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better than no secondary fire support but not ready yet, and using some shortcuts that seriously compromise performance

Comment on lines +691 to +708
-- Specific logic for Half-Life 2 weapons
if class == "weapon_smg1" then
-- SMG Grenade: Good for mid-range. Don't use too close (self damage) or too far.
-- Increased chance in emergency
if distSq > (300*300) and distSq < (1500*1500) then
return math.random(1, 100) <= 20 -- 20% chance in emergency
end
elseif class == "weapon_ar2" then
-- Energy Ball: Good for long range and flushing enemies.
if distSq > (400*400) and distSq < (2000*2000) then
return math.random(1, 100) <= 15 -- 15% chance in emergency
end
elseif class == "weapon_shotgun" then
-- Double Barrel: Devastating at close range.
if distSq < (300*300) then
return math.random(1, 100) <= 50 -- 50% chance when close and in danger
end
end
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should ask the actual luawep entity for a method
eg, luawep:IsCloseEnoughToSecondaryFire

Comment on lines +733 to +748
-- START TRUE SECONDARY FIRE SUPPORT
-- Check if we should override primary fire with secondary fire
if not self:IsControlledByPlayer() and self:CanWeaponSecondaryAttack() and self:AI_ShouldUseSecondary(wep) then
self:WeaponSecondaryAttack()

-- Add a small delay after secondary fire before we can primary fire again
-- This prevents instant double attacks and mimics recoil/recovery
local delay = 1.0
if wep:GetClass() == "weapon_shotgun_term" or wep:GetClass() == "weapon_shotgun" then
delay = 1.5 -- Double barrel takes longer
end

self.m_WeaponData.Primary.NextShootTime = CurTime() + delay
return true, "Fired_Secondary_Override"
end
-- END TRUE SECONDARY FIRE SUPPORT
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put this in the shooting_handler task

myTbl = myTbl or entMeta.GetTable( self )
if not myTbl then return false end -- Should not happen if self is valid, but safety first

wepsTbl = wepsTbl or entMeta.GetTable( wep ) -- LOGIC FIX: Use 'wep' not 'self'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI slop comment, should be removed, doesn't make code more readable

if not IsValid( wep ) then boring( wep ) return end
wepsTbl = wepsTbl or entMeta.GetTable( self )

-- SAFETY FIX: Initialize tables early to prevent nil indexing later
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI slop comment, this is actually an optimisation to reduce _index calls

Comment on lines +1776 to +1842
-- Fix for projectile ownership and self-collision (SMG Grenade)
hook.Add("OnEntityCreated", "Terminator_ProjectileFixes", function(ent)
-- Wait a tick for initialization
timer.Simple(0, function()
if not IsValid(ent) then return end

local class = ent:GetClass()

-- Detect common secondary projectiles
if class == "grenade_ar2" or class == "prop_combine_ball" or class == "rpg_missile" or class == "obj_vj_grenade" then

local owner = ent:GetOwner()
local bot = nil

-- Scenario A: Owner is set to the Weapon (common in scripted weapons)
if IsValid(owner) and owner:IsWeapon() then
local parent = owner:GetOwner()
if IsValid(parent) and parent.isTerminatorHunterBased then
bot = parent
end
-- Scenario B: Owner is already the Bot (ideal, but check collision)
elseif IsValid(owner) and owner.isTerminatorHunterBased then
bot = owner
-- Scenario C: Owner is nil. Check strict proximity to a firing Terminator.
elseif not IsValid(owner) then
local pos = ent:GetPos()
for _, v in ipairs(ents.FindInSphere(pos, 70)) do
if v.isTerminatorHunterBased and v:GetActiveWeapon():GetLastShootTime() > CurTime() - 0.5 then
bot = v
break
end
end
end

if IsValid(bot) then
-- Ensure kill credit goes to the bot, not the weapon or nil
ent:SetOwner(bot)
ent.Owner = bot -- Some SWEPs check this Lua field

-- Extra fix for Combine Ball logic in engine
if class == "prop_combine_ball" then
-- Trigger the engine input to set owner, which handles internal dissolved pointers
ent:Fire("SetOwner", "!activator", 0, bot)
end

-- Prevent SMG grenade (and others) from exploding instantly on the bot's face
-- We use NoCollide to ensure the physics engine ignores the bot for this projectile
constraint.NoCollide(ent, bot, 0, 0)

-- Specific fix for grenade_ar2 which is very sensitive
if class == "grenade_ar2" then
local phys = ent:GetPhysicsObject()
if IsValid(phys) then
-- Ensure it has forward velocity so it clears the bounding box
local vel = phys:GetVelocity()
local aim = bot:GetAimVector()

-- If velocity is too low or weird, force it forward
if vel:Length() < 500 then
phys:SetVelocity(aim * 1000)
end
end
end
end
end
end)
end)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be handled inside every weapon override, the entities are already available to modify and mess with there. it shouldn't be a monolith inside this expensive hook.

Comment on lines +1844 to +1859
-- Hook to forcibly attribute damage from these projectiles to the Terminator
-- This catches cases where the engine resets the attacker or uses the inflictor as attacker
hook.Add("EntityTakeDamage", "Terminator_ProjectileDamageCredit", function(target, dmginfo)
local inflictor = dmginfo:GetInflictor()
if not IsValid(inflictor) then return end

local class = inflictor:GetClass()
if class == "prop_combine_ball" or class == "grenade_ar2" then
local owner = inflictor:GetOwner()

-- If the projectile is owned by a terminator, ensure the damage is credited to them
if IsValid(owner) and owner.isTerminatorHunterBased then
dmginfo:SetAttacker(owner)
end
end
end)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kinda fair, but it should probably be in each weapon's folder.
also try using the "entity as hook name" trick for it too because this is an expensive hook that doesn't need to be active all the time
eg, hook.Add( "EntityTakeDamage", ar2BallEntity,

Comment on lines +710 to +713
-- Generic fallback for scripted weapons that have secondary ammo
if wep:GetMaxClip2() > 0 and wep:Clip2() > 0 then
return math.random(1, 100) <= 10
end
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good fallback, try testing it on multiple ( 10+ ) sweps though, sweps are so stupid

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants