Skip to content

Commit 28f9742

Browse files
authoredJan 12, 2024
Create gmod_missile_fun_v1.lua
0 parents  commit 28f9742

File tree

1 file changed

+115
-0
lines changed

1 file changed

+115
-0
lines changed
 

‎gmod_missile_fun_v1.lua

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
if SERVER then
2+
local function GetInterceptDirection(origin, targetPosition, missileSpeed, targetVelocity)
3+
local los = targetPosition - origin
4+
local distance = los:Length()
5+
local alpha = math.acos(los:Dot(targetVelocity) / (distance * targetVelocity:Length()))
6+
local vt = targetVelocity:Length()
7+
local vRatio = vt / missileSpeed
8+
9+
local a = 1 - (vRatio * vRatio)
10+
local b = 2 * vRatio * distance * math.cos(alpha)
11+
local c = -distance * distance
12+
13+
local discriminant = b * b - 4 * a * c
14+
15+
if discriminant < 0 then
16+
return Vector(0, 0, 0), false
17+
end
18+
19+
local root1 = (-b + math.sqrt(discriminant)) / (2 * a)
20+
local root2 = (-b - math.sqrt(discriminant)) / (2 * a)
21+
22+
local interceptVectorMagnitude = math.max(root1, root2)
23+
local time = interceptVectorMagnitude / missileSpeed
24+
local estimatedPos = targetPosition + targetVelocity * time
25+
local result = (estimatedPos - origin):GetNormalized()
26+
27+
return result, true
28+
end
29+
30+
local function SpawnRocketEntity(ply)
31+
if IsValid(ply) then
32+
local pos = ply:GetPos()
33+
local ang = ply:EyeAngles()
34+
local dir = ang:Forward()
35+
pos = pos + dir * 300
36+
pos.z = pos.z + 250
37+
38+
local ent = ents.Create("prop_physics")
39+
ent:SetModel("models/props_junk/PropaneCanister001a.mdl")
40+
ent:SetPos(pos)
41+
ent:Spawn()
42+
43+
util.SpriteTrail(ent, 0, Color(0, 0, 0), false, 15, 1, 4, 1 / (15 + 1) * 0.5, "trails/smoke.vmt")
44+
45+
local physObj = ent:GetPhysicsObject()
46+
if IsValid(physObj) then
47+
physObj:SetInertia(Vector(0.1, 0.1, 0.1))
48+
end
49+
50+
local cone = ents.Create("prop_physics")
51+
cone:SetModel("models/props_junk/TrafficCone001a.mdl")
52+
cone:Spawn()
53+
cone:SetCollisionGroup(COLLISION_GROUP_WORLD)
54+
55+
local timeCounter = 0
56+
local lastPos = ent:GetPos()
57+
local missileSpeeds = {}
58+
59+
timer.Create("RocketPushTimer" .. tostring(ent:EntIndex()), 0.05, 0, function()
60+
if IsValid(ent) then
61+
if IsValid(physObj) then
62+
timeCounter = timeCounter + 50
63+
if timeCounter < 3000 then
64+
physObj:ApplyForceCenter(Vector(0, 0, 10000))
65+
else
66+
local currentPos = ent:GetPos()
67+
table.insert(missileSpeeds, (currentPos - lastPos):Length() / 0.05)
68+
if #missileSpeeds > 20 then -- keep the last 20 speed measurements
69+
table.remove(missileSpeeds, 1)
70+
end
71+
local missileSpeed = 0
72+
for _, speed in ipairs(missileSpeeds) do
73+
missileSpeed = missileSpeed + speed
74+
end
75+
missileSpeed = missileSpeed / #missileSpeeds
76+
77+
local targetPos = ply:GetPos()
78+
local playerVelocity = ply:GetVelocity()
79+
local distance = ent:GetPos():Distance(targetPos)
80+
81+
local forceDir, interceptPossible = GetInterceptDirection(ent:GetPos(), targetPos, missileSpeed, playerVelocity)
82+
83+
if interceptPossible then
84+
physObj:ApplyForceCenter(forceDir * 15000)
85+
end
86+
87+
cone:SetPos(targetPos + Vector(0, 0, 50))
88+
89+
if distance < 150 then
90+
local effectdata = EffectData()
91+
effectdata:SetOrigin(ent:GetPos())
92+
util.Effect("Explosion", effectdata)
93+
util.Effect("cball_explode", effectdata)
94+
ent:EmitSound("ambient/explosions/explode_4.wav")
95+
ent:Remove()
96+
97+
if IsValid(cone) then
98+
cone:Remove()
99+
end
100+
end
101+
end
102+
lastPos = ent:GetPos()
103+
end
104+
else
105+
timer.Remove("RocketPushTimer" .. tostring(ent:EntIndex()))
106+
end
107+
end)
108+
end
109+
end
110+
111+
local scriptPlayer = Entity(1)
112+
timer.Create("SpawnRocketTimer", 1, 4, function()
113+
SpawnRocketEntity(scriptPlayer)
114+
end)
115+
end

0 commit comments

Comments
 (0)
Please sign in to comment.