--@name suspension builder 0.1 --@author loh kakoito --@shared if SERVER then --Settings local elasticConst = 30000 local elasticDamp = 2000 local elasticAddLength = 0 local suspenionArm = 300 local baseMass = 700 local wheelMass = 65 local wheelModel = "models/sprops/trans/wheel_b/t_wheel30.mdl" local steerPlatesModel = "models/sprops/rectangles_thin/size_1_5/rect_6x12x1_5.mdl" --######## local base = chip():isWeldedTo() base:setAngles(Angle(0,90,0)) base:setMass(baseMass) base:setNocollideAll(true) local errorSound = "buttons/button10.wav" local hintSound = "buttons/button15.wav" local plates = {} hook.add('ClientInitialized', 'init', function(Player) if Player == owner() then net.start("info") net.writeEntity(base) net.writeString(wheelModel) net.send(Player) init() end end) function SendClientNotification (message, type, duration) net.start('send_client_notification') net.writeInt(type, 8) net.writeFloat(duration) net.writeString(message) net.send() sounds.create(chip(), type == NOTIFY.HINT and hintSound or errorSound):play() end function init() print("Arrows to move it") print("Enter to send settings and spawn") SendClientNotification('Arrows to move it', NOTIFY.HINT, 7) SendClientNotification('Enter to send settings and spawn', NOTIFY.HINT, 7) end local Positions = {} local Angles = {} local i = 0 function CreateProps() i = i + 1 local steerPlate = prop.create(base:localToWorld(Vector(i > 2 and -10 or 10, 100 + (i%2 == 0 and 10 or -10) , 40)), base:getAngles(), steerPlatesModel, true) steerPlate:setNocollideAll(true) steerPlate:enableGravity(false) local wheel = prop.create(Positions[i], Angles[i], wheelModel, true) wheel:setMass(wheelMass) sounds.create(chip(), "buttons/button24.wav"):play() --wheel:enableSphere(true) constraint.rope(i, wheel, base, nil, nil, Vector(0), base:worldToLocal(wheel:localToWorld(Vector(suspenionArm,-suspenionArm,0))), nil, nil, nil, nil, nil, true) constraint.rope(i, wheel, base, nil, nil, Vector(0), base:worldToLocal(wheel:localToWorld(Vector(-suspenionArm,-suspenionArm,0))), nil, nil, nil, nil, nil, true) constraint.ballsocketadv(wheel, steerPlate, nil, nil, Vector(0), Vector(0), nil, nil, Vector(-180, -0.1, -0.1), Vector(180, 0.1, 0.1), Vector(0), true, true) constraint.ballsocketadv(steerPlate, wheel, nil, nil, Vector(0), Vector(0), nil, nil, Vector(-180, 0.1, 0.1), Vector(180, -0.1, -0.1), Vector(0), true, true) if elasticAddLength ~= 0 then constraint.elastic(i, wheel, base, nil, nil, Vector(0), base:worldToLocal(wheel:localToWorld(Vector(0,0,80))), elasticConst, elasticDamp, nil, nil, false) constraint.setElasticLength(i, wheel, elasticAddLength + 80) else constraint.elastic(i, wheel, base, nil, nil, Vector(0), base:worldToLocal(wheel:localToWorld(Vector(0,0,0))), elasticConst, elasticDamp, nil, nil, false) --constraint.elastic(i, wheel, base, nil, nil, Vector(0), base:worldToLocal(wheel:localToWorld(Vector(0,0,0))), elasticConst, 100, nil, nil, true) end end function Build() timer.create("create", 0.5, 4, CreateProps) SendClientNotification("Use 'Make Spherical' tool on the wheels then dupe and delete the chip", NOTIFY.HINT, 15) print("Use 'Make Spherical' tool on the wheels then dupe and delete the chip") end net.receive("settings", function() for i = 1, 4 do Positions[i] = net.readVector() Angles[i] = net.readAngle() end Build() end) end if CLIENT and player() == owner() then local Fwd = 0 local Bck = 0 local Lft = 0 local Rgh = 0 local Ctrl = 0 local Enter = 0 local Alternative = 0 local KP_PLUS = 0 local KP_MINUS = 0 hook.add('inputPressed', 'KeyPress', function(key) if key == KEY.UPARROW then Fwd = 1 elseif key == KEY.DOWNARROW then Bck = 1 elseif key == KEY.LEFTARROW then Lft = 1 elseif key == KEY.RIGHTARROW then Rgh = 1 elseif key == KEY.CTRL then Ctrl = 1 elseif key == KEY.ENTER then Enter = 1 elseif key == KEY.KP_PLUS then KP_PLUS = 1 elseif key == KEY.KP_MINUS then KP_MINUS = 1 elseif key == KEY.SHIFT then Alternative = 1 end end) hook.add('inputReleased', 'KeyRelease', function(key) if key == KEY.UPARROW then Fwd = 0 elseif key == KEY.DOWNARROW then Bck = 0 elseif key == KEY.LEFTARROW then Lft = 0 elseif key == KEY.RIGHTARROW then Rgh = 0 elseif key == KEY.CTRL then Ctrl = 0 elseif key == KEY.ENTER then Enter = 0 SendSettings() elseif key == KEY.KP_PLUS then KP_PLUS = 0 elseif key == KEY.KP_MINUS then KP_MINUS = 0 elseif key == KEY.SHIFT then Alternative = 0 end end) local wheelModel = "" local base local wheels = {} local ready = false local addPos = Vector(0) local addX = 0 local deadEnd = false local holoSpeed = 0.1 function Build() bHolo = holograms.create(base:getPos(), base:getAngles(), "models/holograms/hq_icosphere.mdl") bHolo:setColor(Color(255,0,0,100)) bHolo:setScale(Vector(0.2)) for i = 1, 4 do local LeftOrRight = i%2 == 0 and 1 or -1 local BackOrForw = i>2 and -1 or 1 wheels[i] = holograms.create(bHolo:localToWorld(Vector(50*BackOrForw,30*LeftOrRight,0)), Angle(0,90 * LeftOrRight,0), wheelModel) end end net.receive("info", function() net.readEntity(function(ent) base = ent end) wheelModel = net.readString() Build() end) net.receive('send_client_notification', function () local type = net.readInt(8) local duration = net.readFloat() local message = net.readString() notification.addLegacy(message, type, duration) end) function SendSettings() if #wheels > 0 and deadEnd == false then net.start("settings") for i = 1, 4 do net.writeVector(wheels[i]:getPos()) net.writeAngle(wheels[i]:getAngles()) end net.send() holograms.removeAll() end deadEnd = true end hook.add("think", "runtime", function() if #wheels > 0 and deadEnd == false then for i = 1, 4 do local LeftOrRight = i%2 == 0 and 1 or -1 local BackOrForw = i>2 and -1 or 1 if Alternative == 1 then addX = addX + (Fwd - Bck) * (Ctrl == 1 and holoSpeed / 10 or holoSpeed) else addPos = addPos + Vector(Fwd - Bck, Lft - Rgh, 0) * (Ctrl == 1 and holoSpeed / 10 or holoSpeed) addPos[2] = math.max(addPos[2], 0) addPos[1] = math.max(addPos[1], 0) end bHolo:setPos(base:localToWorld(Vector(addX,0,0))) wheels[i]:setPos(bHolo:localToWorld(Vector(addPos[1]*BackOrForw,addPos[2]*LeftOrRight,0))) end end end) end