Skip to content

Commit

Permalink
Merge pull request #261 from GMLambda/physcannon-update-3
Browse files Browse the repository at this point in the history
Gravity Gun update
  • Loading branch information
ZehMatt authored May 1, 2024
2 parents dc2750e + ea083d8 commit 61388a8
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 25 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- Improved: Lambda no longer override the localization already existing in the game.
- Improved: d2_coast_03: Give more supplies, hope this can help player fight with multiple gunships better.
- Improved: d2_coast_03: Mission critical NPCs now have protection to prevent dying from a car accident.
- Improved: The gravity gun punt has now an energy effect.
- Fixed: Pickup SMG grenade showing wrong icon.
- Fixed: d2_coast_03: G-Man and Oddssa stay in the balcony forever.
- Fixed: d2_coast_03: Blocked a exploit where player can use it to skip the final scene.
Expand Down
111 changes: 111 additions & 0 deletions entities/effects/lambda_physcannon_impact.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
local MAT_PHYSBEAM = Material("sprites/physbeam.vmt")
local EFFECT_TIME = 0.01
function EFFECT:Init(data)
local pos = data:GetOrigin()
local ent = data:GetEntity()
if not IsValid(ent) then return end
if ent:GetClass() ~= "weapon_physcannon" then return end
self.SourceEntity = ent
self.TargetPos = pos
self.DieTime = CurTime() + EFFECT_TIME
self.Color = ent:GetWeaponColor()
self.HasLight = false
local efSparks = EffectData()
efSparks:SetOrigin(pos)
efSparks:SetMagnitude(2)
efSparks:SetScale(2)
util.Effect("Sparks", efSparks)
local glowConvar = GetConVar("lambda_physcannon_glow")
if glowConvar:GetInt() > 0 then
self.EnableLights = true
else
self.EnableLights = false
end
end

function EFFECT:GetStartPos()
local ent = self.SourceEntity
local wepPos
local owner = ent:GetOwner()
if ent:GetOwner() == LocalPlayer() then
local vm = owner:GetViewModel()
if not IsValid(vm) then return end
local wepCenter = vm:GetAttachment(1)
wepPos = ent:FormatViewModelAttachment(wepCenter.Pos, true)
wepPos = wepPos - (wepCenter.Ang:Forward() * 10)
else
local wepCenter = ent:GetAttachment(1)
wepPos = wepCenter.Pos
end

return wepPos
end

function EFFECT:Think()
local ent = self.SourceEntity
if not IsValid(ent) then return false end
if ent:GetClass() ~= "weapon_physcannon" then return false end
local owner = ent:GetOwner()
if not IsValid(owner) then return false end
if CurTime() > self.DieTime then return false end
-- Emit light.
if self.EnableLights and self.HasLight == false then
local targetPos = self.TargetPos
local startPos = self:GetStartPos()
local dist = startPos:Distance(targetPos)
local color = self.Color
for i = 1, 3 do
local p = i / 3
local pos = LerpVector(p, startPos, targetPos)
local index = bit.rshift(i, 16) + i
local dlight = DynamicLight(index)
dlight.dietime = self.DieTime
dlight.pos = pos
dlight.r = color.r
dlight.g = color.g
dlight.b = color.b
dlight.brightness = 2
dlight.decay = 500
dlight.size = dist
end

self.HasLight = true
end

return true
end

function EFFECT:RenderBeam(startPos, endPos, seed)
local numSegments = 20
local frequency = 5 -- Adjust the frequency of the sine wave
local color = self.Color
local curTime = CurTime()
local range = 5
render.StartBeam(numSegments)
for i = 0, numSegments - 1 do
local t = i / numSegments
local pos = LerpVector(t, startPos, endPos)
if i > 0 then
local yOffset = math.sin(i + (seed * 10) + curTime * frequency) * range
local xOffset = math.cos(i + (seed * 20) + seed + curTime * frequency) * range
local zOffset = math.sin(i + (seed * 30) + seed + curTime * frequency * 0.5) * range
pos.x = pos.x + xOffset
pos.y = pos.y + yOffset
pos.z = pos.z + zOffset
pos = pos + VectorRand() * 0.2
end

render.AddBeam(pos, 5 + (math.random() * 5), 1, color)
end

render.EndBeam()
end

function EFFECT:Render()
local wepPos = self:GetStartPos()
render.SetMaterial(MAT_PHYSBEAM)
local targetPos = self.TargetPos
for n = 1, 5 do
self:RenderBeam(wepPos, targetPos, n)
end
end
60 changes: 38 additions & 22 deletions entities/weapons/weapon_physcannon.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1042,17 +1042,32 @@ function SWEP:GetLightBrightness()
brightness = 0.5
end

if self:GetEffectState() == EFFECT_HOLDING then
local efState = self:GetEffectState()
if efState == EFFECT_HOLDING then
brightness = brightness * (2.5 + (math.sin(CurTime() * 100) * 0.12))
elseif efState == EFFECT_LAUNCH then
brightness = brightness * 2.5
end

return brightness
end

function SWEP:StopLights()
if self.ProjectedTexture ~= nil and IsValid(self.ProjectedTexture) then
self.ProjectedTexture:Remove()
self.ProjectedTexture = nil
end
end

function SWEP:UpdateGlow()
if self:IsEffectActive(EF_NODRAW) == true then return end
local glowMode = physcannon_glow_mode
if glowMode == 0 then return end
if glowMode == 0 then
self:StopLights()

return
end

local curTime = CurTime()
if curTime < self.NextGlowUpdate then return end
local lightPos = self:GetLightPosition()
Expand Down Expand Up @@ -1653,14 +1668,14 @@ function SWEP:DoEffectLaunch(pos)
ef:SetOrigin(endPos)
ef:SetEntity(self)
if CLIENT and IsFirstTimePredicted() then
util.Effect("PhyscannonImpact", ef)
util.Effect("lambda_physcannon_impact", ef)
elseif SERVER then
util.Effect("PhyscannonImpact", ef)
util.Effect("lambda_physcannon_impact", ef)
end

if CLIENT then
local blast = self.EffectParameters[PHYSCANNON_BLAST]
blast.Scale:Init(8.0, 64, 0.1)
blast.Scale:Init(8.0, 128, 0.3)
blast.Alpha:Init(255, 0, 0.2)
blast.Visible = true
end
Expand Down Expand Up @@ -1895,26 +1910,27 @@ local render_StartBeam = render and render.StartBeam or nil
local render_EndBeam = render and render.EndBeam or nil
function SWEP:DrawBeam(startPos, endPos, width, color)
color = color or Color(255, 255, 255, 255)
local len = endPos - startPos
local split = len / BEAM_SEGMENTS
local frequency = 5
local curTime = CurTime()
local range = 1
for n = 0, BEAM_GROUPS - 1 do
local seed = n
render_StartBeam(BEAM_SEGMENTS)
for i = 0, BEAM_SEGMENTS - 1 do
local offset = Vector(0, 0, 0)
local pos
if i == 0 then
pos = startPos
elseif i == BEAM_SEGMENTS - 1 then
pos = endPos
else
local t = CurTime() * 15
local p = (t + (n * n)) + (i / BEAM_SEGMENTS - 1) * math.pi
local randVec = Vector(1, 1, 1)
randVec.x = randVec.x * util.SharedRandom("beam_posx" .. tostring(i), -0.1, 0.1)
randVec.y = randVec.y * util.SharedRandom("beam_posy" .. tostring(i), -0.1, 0.1)
randVec.z = randVec.z * util.SharedRandom("beam_posz" .. tostring(i), -0.1, 0.1)
offset = Vector(1, 1, 1) * math.sin(p) + (randVec * ((n / BEAM_GROUPS) - 0.5))
pos = startPos + (i * split) + offset
local p = i / (BEAM_SEGMENTS - 1)
local pos = LerpVector(p, startPos, endPos)
local randVec = Vector(1, 1, 1)
randVec.x = randVec.x * util.SharedRandom("beam_posx" .. tostring(i), -0.1, 0.1)
randVec.y = randVec.y * util.SharedRandom("beam_posy" .. tostring(i), -0.1, 0.1)
randVec.z = randVec.z * util.SharedRandom("beam_posz" .. tostring(i), -0.1, 0.1)
if i > 0 then
local yOffset = math.sin(i + (seed * 10) + curTime * frequency) * range
local xOffset = math.cos(i + (seed * 20) + seed + curTime * frequency) * range
local zOffset = math.sin(i + (seed * 30) + seed + curTime * frequency * 0.5) * range
pos.x = pos.x + xOffset
pos.y = pos.y + yOffset
pos.z = pos.z + zOffset
pos = pos + VectorRand() * 0.2
end

local texcoord = util.SharedRandom("beam_tex" .. tostring(i), 0.5, 1)
Expand Down
3 changes: 0 additions & 3 deletions gamemode/sh_entity_extend.lua
Original file line number Diff line number Diff line change
Expand Up @@ -397,12 +397,9 @@ end

function ENTITY_META:CanTakeDamage()
local data = self:GetInternalVariable("m_takedamage")

if data ~= nil then
-- DAMAGE_NO
return data ~= 0
else
if self:IsNPC() == false and self:IsPlayer() == false and self:IsVehicle() == false then return false end
end

return true
Expand Down

0 comments on commit 61388a8

Please sign in to comment.