Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- if _G.rope then
- for k,v in pairs(rope.ActiveRopes) do
- for k,v in pairs(v.points) do
- if v.type == 2 then
- v.obj:SetDieTime(0)
- else
- SafeRemoveEntity(v.ent)
- end
- end
- end
- end
- rope = {}
- rope.ActiveRopes = {}
- local tempvec = Vector()
- local tempvecn = Vector()
- local sqrt = math.sqrt
- local x,y,z = 0,0,0
- local ox,oy,oz = 0,0,0
- local len = 0
- local THINKTIME = 0
- local DELTA = 1
- local SPEED = 100
- local function calc(a, b)
- ---local offset = a.obj:GetPos() - b.obj:GetPos()
- --local len = offset:Length()
- local apos = a.obj:GetPos()
- local bpos = b.obj:GetPos()
- local avel = a.obj:GetVelocity()
- local bvel = b.obj:GetVelocity()
- ox = apos.x - bpos.x
- oy = apos.y - bpos.y
- oz = apos.z - bpos.z
- len = (ox*ox) + (oy*oy) + (oz*oz)
- --force = (a.obj:GetVelocity() - b.obj:GetVelocity()) * -200
- x = (avel.x - bvel.x) * -100
- y = (avel.y - bvel.y) * -100
- z = (avel.z - bvel.z) * -100
- if len ~= 0 then
- --force = force + offset:GetNormalized() * (len) * (-7000)
- len = sqrt(len)
- x = x + ((ox / len) * (len) * (-10000) * DELTA)
- y = y + ((oy / len) * (len) * (-10000) * DELTA)
- z = z + ((oz / len) * (len) * (-10000) * DELTA)
- end
- if a.type == 1 then
- x = (x * 0.1 / 100)
- y = (y * 0.1 / 100)
- z = (z * 0.1 / 100)
- tempvec.x = x
- tempvec.y = y
- tempvec.z = z
- tempvecn.x = -x
- tempvecn.y = -y
- tempvecn.z = -z
- a.obj:ApplyForceCenter(tempvec)
- b.obj:ApplyForceCenter(tempvecn) -- does unm create a new vector?????
- elseif a.type == 2 then
- x = (x * 0.1 / 50)
- y = (y * 0.1 / 50)
- z = (z * 0.1 / 50)
- tempvec.x = avel.x + x
- tempvec.y = avel.y + y
- tempvec.z = avel.z + z
- tempvecn.x = bvel.x - x
- tempvecn.y = bvel.y - y
- tempvecn.z = bvel.z - z
- a.obj:SetVelocity(tempvec)
- b.obj:SetVelocity(tempvecn)
- end
- end
- local a
- local b
- local vec
- local T = 0
- local last
- function rope.Think()
- DELTA = math.Clamp(FrameTime() * 30, 0, 0.4)
- --local T = SysTime()
- --last = last or T
- --if last < T then
- for key, rope in pairs(rope.ActiveRopes) do
- for i = 2, #rope.points do
- calc(rope.points[i - 1], rope.points[i])
- end
- end
- --DELTA = (T-last) * SPEED
- --last = T + THINKTIME
- --end
- for key, rope in pairs(rope.ActiveRopes) do
- for i, var in pairs(rope.attachments) do
- local point = rope.points[i]
- if point then
- point.obj:SetPos(type(var) == "function" and var() or var)
- point.obj:SetVelocity(vector_origin)
- end
- end
- end
- end
- local color_white = color_white
- local sprite_mat = Material("particle/particle_sphere")
- function rope.Draw()
- for key, rope in pairs(rope.ActiveRopes) do
- local count = #rope.points
- render.SetMaterial(rope.mat or sprite_mat)
- render.StartBeam(count)
- for i = 1, count do
- render.AddBeam(rope.points[i].obj:GetPos(), 1, (i/count), color_white)
- end
- render.EndBeam()
- render.SetMaterial(sprite_mat)
- end
- end
- function rope.Create(points, attachments, mat, ent_type)
- ent_type = ent_type or 2
- points = points or 128
- mat = mat or Material("trails/laser")
- attachments = attachments or {[1] = function() return LocalPlayer():EyePos() end, [#points] = function() return Vector(0,0,0) end}
- local data = {}
- data.mat = mat
- data.points = {}
- data.attachments = attachments
- local pos = select(2, next(attachments))
- pos = type(pos) == "function" and pos() or pos
- for i = 1, points do
- local obj
- if ent_type == 2 then
- rope.emitter = rope.emitter or ParticleEmitter(Vector())
- ent = rope.emitter:Add("particle/snow", pos)
- ent:SetVelocity(VectorRand())
- ent:SetDieTime(1000)
- ent:SetLifeTime(0)
- ent:SetStartSize(0)
- ent:SetEndSize(0)
- ent:SetGravity(physenv.GetGravity())
- ent:SetCollide(true)
- ent:SetAirResistance(100)
- elseif ent_type == 1 then
- ent = ents.CreateClientProp()
- ent:SetCollisionGroup(COLLISION_GROUP_INTERACTIVE_DEBRIS)
- ent:Spawn()
- ent:PhysicsInitSphere(1)
- local phys = ent:GetPhysicsObject()
- phys:SetMass(1)
- phys:SetMaterial("jeeptire")
- phys:SetDamping(0.2, 0)
- phys:EnableGravity(true)
- ent:SetVelocity(VectorRand())
- ent = phys
- end
- ent:SetPos(pos)
- data.points[i] = {
- obj = ent,
- type = ent_type
- }
- end
- data.id = table.insert(rope.ActiveRopes, data)
- data.Remove = function()
- table.remove(rope.ActiveRopes, data.id)
- end
- return data
- end
- timer.Create("rope", 0, 0, rope.Think)
- -- hacky optimization
- -- allows only the last draw call
- local function setup_suppress()
- local last_framenumber = 0
- local current_frame = 0
- local current_frame_count = 0
- return function()
- local frame_number = FrameNumber()
- if frame_number == last_framenumber then
- current_frame = current_frame + 1
- else
- last_framenumber = frame_number
- if current_frame_count ~= current_frame then
- current_frame_count = current_frame
- end
- current_frame = 1
- end
- return current_frame < current_frame_count
- end
- end
- -- hacky optimization
- local uh = setup_suppress()
- hook.Add("PostDrawTranslucentRenderables", "rope", function()
- if uh() then return end
- rope.Think()
- rope.Draw()
- end)
- local chess = chess
- rope.Create(64, {[1] = function() return me:EyePos() end, [64] = function() return chess:EyePos() end}, nil, 1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement