From be9e6048e6fcba37f417be341a4438a3ecff342c Mon Sep 17 00:00:00 2001 From: Aikiro42 Date: Sun, 21 Sep 2025 21:00:27 +0800 Subject: [PATCH 1/2] feat!: remove terrain-ignoring hitscans - I can't get hitscans to damage through terrain yet. I'll reimplement this when I finally figure it out. --- .../project45gunfire/project45gunfire.lua | 2 -- .../project45gunfire.weaponability | 11 ++----- .../project45-neo-gaussrifle.activeitem | 1 - .../project45-neo-phasma.activeitem | 1 - .../project45-tcf-kineticarbiter.activeitem | 1 - scripts/project45/hitscanLib.lua | 29 +++++++------------ 6 files changed, 12 insertions(+), 33 deletions(-) diff --git a/items/active/weapons/ranged/abilities/project45gunfire/project45gunfire.lua b/items/active/weapons/ranged/abilities/project45gunfire/project45gunfire.lua index 6e817666..207ef38f 100644 --- a/items/active/weapons/ranged/abilities/project45gunfire/project45gunfire.lua +++ b/items/active/weapons/ranged/abilities/project45gunfire/project45gunfire.lua @@ -550,8 +550,6 @@ function Project45GunFire:firing() -- state if self:jam() then return end - -- don't fire when muzzle collides with terrain - -- if not self.projectileParameters.hitscanIgnoresTerrain and world.lineTileCollision(mcontroller.position(), self:firePosition()) then if self:muzzleObstructed() then self:stopFireLoop() self.isFiring = false diff --git a/items/active/weapons/ranged/abilities/project45gunfire/project45gunfire.weaponability b/items/active/weapons/ranged/abilities/project45gunfire/project45gunfire.weaponability index 3450ebcc..dc696b5a 100644 --- a/items/active/weapons/ranged/abilities/project45gunfire/project45gunfire.weaponability +++ b/items/active/weapons/ranged/abilities/project45gunfire/project45gunfire.weaponability @@ -188,10 +188,7 @@ "punchThrough": 0, // number of entities to register before stopping the scan "fullChargePunchThrough": 0, - - // "ignoresTerrain": false, // pierces through terrain if true - // "ignoresTerrainOnFullCharge": false, - + "hitscanFadeTime": 0.1, // how long the hitscan line fades away "hitscanWidth": 1, // visual width of hitscan line in pixels // "hitscanColor": [255,255,200], // color of hitscan projectile; also dictates muzzle flash color @@ -262,11 +259,7 @@ // if the beam passes through less entities it keeps going until it hits terrain "punchThrough": 3, "fullChargePunchThrough": 3, - - // whether the beam fires through terrain or not - // "ignoresTerrain": false, - // "ignoresTerrainOnFullCharge": false, - + "beamWidth": 5, // width of beam - beams that are too wide can look weird "beamInnerWidth": 3, // width of inner white beam - just for vfx "beamJitter": 1, // how much the beam width changes as it's shot - just a vfx diff --git a/items/active/weapons/ranged/project45/project45-neo-gaussrifle/project45-neo-gaussrifle.activeitem b/items/active/weapons/ranged/project45/project45-neo-gaussrifle/project45-neo-gaussrifle.activeitem index 1f2b75c6..739fd1d7 100644 --- a/items/active/weapons/ranged/project45/project45-neo-gaussrifle/project45-neo-gaussrifle.activeitem +++ b/items/active/weapons/ranged/project45/project45-neo-gaussrifle/project45-neo-gaussrifle.activeitem @@ -171,7 +171,6 @@ "hitscanParameters": { "hitscanWidth": 8, "hitscanBrightness": 0.3, - "ignoresTerrainOnFullCharge": true, "fullChargePunchThrough": 3 } /* diff --git a/items/active/weapons/ranged/project45/project45-neo-phasma/project45-neo-phasma.activeitem b/items/active/weapons/ranged/project45/project45-neo-phasma/project45-neo-phasma.activeitem index 602603e1..8eeac56e 100644 --- a/items/active/weapons/ranged/project45/project45-neo-phasma/project45-neo-phasma.activeitem +++ b/items/active/weapons/ranged/project45/project45-neo-phasma/project45-neo-phasma.activeitem @@ -167,7 +167,6 @@ "hitscanWidth": 3, "hitscanBrightness": 0.3, "hitscanFadeTime": 0.3, - "ignoresTerrainOnFullCharge": false, "vfxParameters": { "mode": "lightning", "segments": 8, diff --git a/items/active/weapons/ranged/project45/special/project45-tcf-kineticarbiter/project45-tcf-kineticarbiter.activeitem b/items/active/weapons/ranged/project45/special/project45-tcf-kineticarbiter/project45-tcf-kineticarbiter.activeitem index 178b55bd..97eecd3a 100644 --- a/items/active/weapons/ranged/project45/special/project45-tcf-kineticarbiter/project45-tcf-kineticarbiter.activeitem +++ b/items/active/weapons/ranged/project45/special/project45-tcf-kineticarbiter/project45-tcf-kineticarbiter.activeitem @@ -187,7 +187,6 @@ "hitscanParameters": { "hitscanWidth": 8, "hitscanBrightness": 0.3, - "ignoresTerrainOnFullCharge": true, "fullChargePunchThrough": 3 }, diff --git a/scripts/project45/hitscanLib.lua b/scripts/project45/hitscanLib.lua index bc25bfc7..7f0be3fa 100644 --- a/scripts/project45/hitscanLib.lua +++ b/scripts/project45/hitscanLib.lua @@ -13,13 +13,11 @@ function hitscanLib:fireChainBeam() self:prepareStanceInCycle(self.stances.firing) local punchThrough = self.beamParameters.punchThrough or 0 - local ignoresTerrain = self.beamParameters.ignoresTerrain if self.chargeTime + self.overchargeTime > 0 and self.chargeTimer >= self.chargeTime + self.overchargeTime then punchThrough = self.beamParameters.fullChargePunchThrough or punchThrough - ignoresTerrain = self.beamParameters.ignoresTerrainOnFullCharge or ignoresTerrain end self:startFireLoop() @@ -59,7 +57,7 @@ function hitscanLib:fireChainBeam() self.isFiring = true self.ammoRechargeDelayTimer = self.ammoRechargeDelayTime -- TODO: make parameters dymamic - chainScanResults = self:chainScan(self.beamParameters.range, ignoresTerrain, punchThrough, self.beamParameters.scanUntilCursor) + chainScanResults = self:chainScan(self.beamParameters.range, punchThrough, self.beamParameters.scanUntilCursor) chain = chainScanResults[1] activeItem.setScriptedAnimationParameter("beamChain", chain) hitEntityIds = chainScanResults[2] @@ -252,18 +250,16 @@ function hitscanLib:fireChain() -- TODO: make chainScan arguments dynamic local punchThrough = self.hitscanParameters.punchThrough or 0 - local ignoresTerrain = self.hitscanParameters.ignoresTerrain if self.chargeTime + self.overchargeTime > 0 and self.chargeTimer >= self.chargeTime + self.overchargeTime then punchThrough = self.hitscanParameters.fullChargePunchThrough or punchThrough - ignoresTerrain = self.hitscanParameters.ignoresTerrainOnFullCharge or ignoresTerrain end self.ammoRechargeDelayTimer = self.ammoRechargeDelayTime - local chainScanResults = self:chainScan(self.hitscanParameters.range, ignoresTerrain, punchThrough, self.hitscanParameters.scanUntilCursor) + local chainScanResults = self:chainScan(self.hitscanParameters.range, punchThrough, self.hitscanParameters.scanUntilCursor) local chain = chainScanResults[1] local hitEntityIds = chainScanResults[2] -- chain projectiles only fire one chain @@ -401,8 +397,8 @@ function hitscanLib:fireChain() end -function hitscanLib:chainScan(scanLength, ignoresTerrain, punchThrough, scanUntilCursor) - local firstHit = self:hitscan(true, 0, scanLength, ignoresTerrain, 0, scanUntilCursor, 0, self:firePosition(), true) +function hitscanLib:chainScan(scanLength, punchThrough, scanUntilCursor) + local firstHit = self:hitscan(true, 0, scanLength, 0, scanUntilCursor, 0, self:firePosition(), true) local chainScanLengthLimit = scanLength / 2 local chain = {firstHit[1], firstHit[2]} local firstHitEntityIds = firstHit[3] @@ -432,7 +428,7 @@ function hitscanLib:chainScan(scanLength, ignoresTerrain, punchThrough, scanUnti if not alreadyHit[candidateId] and world.entityCanDamage(entity.id(), candidateId) and world.entityDamageTeam(candidateId) ~= "ghostly" - and (ignoresTerrain or not world.lineCollision(chain[#chain], world.entityPosition(candidateId))) + and (not world.lineCollision(chain[#chain], world.entityPosition(candidateId))) then nextEntityId = candidateId break @@ -469,13 +465,11 @@ function hitscanLib:fireHitscan(projectileType) local punchThrough = self.hitscanParameters.punchThrough or 0 - local ignoresTerrain = self.hitscanParameters.ignoresTerrain if self.chargeTime + self.overchargeTime > 0 and self.chargeTimer >= self.chargeTime + self.overchargeTime then punchThrough = self.hitscanParameters.fullChargePunchThrough or punchThrough - ignoresTerrain = self.hitscanParameters.ignoresTerrainOnFullCharge or ignoresTerrain end local hitscanInfos = {} @@ -487,7 +481,7 @@ function hitscanLib:fireHitscan(projectileType) local hitReg = self:hitscan( false, nil, self.hitscanParameters.range, - ignoresTerrain, punchThrough, self.hitscanParameters.scanUntilCursor, + punchThrough, self.hitscanParameters.scanUntilCursor, self.spread, nil, nil, self.hitscanParameters.smartScanParameters) @@ -712,13 +706,11 @@ function hitscanLib:fireBeam() self:prepareStanceInCycle(self.stances.firing) local punchThrough = self.beamParameters.punchThrough or 0 - local ignoresTerrain = self.beamParameters.ignoresTerrain if self.chargeTime + self.overchargeTime > 0 and self.chargeTimer >= self.chargeTime + self.overchargeTime then punchThrough = self.beamParameters.fullChargePunchThrough or punchThrough - ignoresTerrain = self.beamParameters.ignoresTerrainOnFullCharge or ignoresTerrain end self:startFireLoop() @@ -755,7 +747,7 @@ function hitscanLib:fireBeam() do self.isFiring = true - hitreg = self:hitscan(true, nil, self.beamParameters.range, ignoresTerrain, punchThrough, self.beamParameters.scanUntilCursor) + hitreg = self:hitscan(true, nil, self.beamParameters.range, punchThrough, self.beamParameters.scanUntilCursor) beamStart = hitreg[1] beamEnd = hitreg[2] @@ -901,7 +893,7 @@ function hitscanLib:fireBeam() self.isFiring = false self.muzzleProjectileFired = false - hitreg = self:hitscan(true, nil, self.beamParameters.range, ignoresTerrain, punchThrough, self.beamParameters.scanUntilCursor) + hitreg = self:hitscan(true, nil, self.beamParameters.range, punchThrough, self.beamParameters.scanUntilCursor) beamEnd = hitreg[2] table.insert(self.projectileStack, { @@ -933,7 +925,7 @@ end -- Utility function that scans for an entity to damage. -- @return {hitscan_line_origin, hitscan_line_destination, entity_id[]} -function hitscanLib:hitscan(isLaser, degAdd, scanLength, ignoresTerrain, punchThrough, scanUntilCursor, spread, hitscanLineOrigin, chain, smartScanParameters) +function hitscanLib:hitscan(isLaser, degAdd, scanLength, punchThrough, scanUntilCursor, spread, hitscanLineOrigin, chain, smartScanParameters) -- initialize hitscan parameters scanLength = scanLength or 100 @@ -986,7 +978,7 @@ function hitscanLib:hitscan(isLaser, degAdd, scanLength, ignoresTerrain, punchTh -- using scan length and origin, determine hitscan endpoint local hitscanLineDestination = smartTargetPosition or vec2.add(hitscanLineOrigin, vec2.mul(self:aimVector(spread or self.spread or 0, degAdd or 0), scanLength)) - local fullHitscanLineDestination = not ignoresTerrain and world.lineCollision(hitscanLineOrigin, hitscanLineDestination, {"Block", "Dynamic"}) or hitscanLineDestination + local fullHitscanLineDestination = world.lineCollision(hitscanLineOrigin, hitscanLineDestination, {"Block", "Dynamic"}) or hitscanLineDestination -- chain: {"targeted" | "spread" | nil} -- determine hit entities @@ -1047,7 +1039,6 @@ function hitscanLib:updateLaser() nil, self.laser.range, nil, - nil, self.laser.renderUntilCursor, 0, nil, From c0511e43c19b8904753bce074f85927fc2d11684 Mon Sep 17 00:00:00 2001 From: Aikiro42 Date: Sun, 21 Sep 2025 21:04:29 +0800 Subject: [PATCH 2/2] docs: add branch changelog --- docs/branch-changelogs/change.remove-ignore-terrain.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/branch-changelogs/change.remove-ignore-terrain.md diff --git a/docs/branch-changelogs/change.remove-ignore-terrain.md b/docs/branch-changelogs/change.remove-ignore-terrain.md new file mode 100644 index 00000000..bceb933d --- /dev/null +++ b/docs/branch-changelogs/change.remove-ignore-terrain.md @@ -0,0 +1,5 @@ +# Changes +- The Kinetic Arbiter and Gauss Rifle no longer ignore terrain when shooting at full charge. + +# Changes (Modders) +- Terrain-ignoring hitscans have been removed. I've yet to figure out how to make this really work; this feature will be re-added in the future once I figure it out. \ No newline at end of file