artemx32

veh_ventus

Jun 2nd, 2026
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.82 KB | None | 0 0
  1. --@name vehicle_ventus
  2. --@author artybyte
  3. --@shared
  4. --@model models/hunter/blocks/cube2x2x2.mdl
  5.  
  6. function IsNAN(n)
  7.     return n ~= n
  8. end
  9.  
  10. if CLIENT then    
  11.      
  12.     --@include ventus.txt
  13.     local ventus = require('ventus.txt')
  14.     local inner_camera = false
  15.    
  16.     ventus.use_joystick = false
  17.     ventus.int_camera = false
  18.     ventus.cam_key_pressed = false
  19.    
  20.     local function init_3ps_cam()
  21.         hook.add('calcview', 'artybyte_veh_view', function()
  22.             if not render.isHUDActive() then return end
  23.            
  24.             -- Get the chair/seat entity your chip is linked to
  25.             local seat = player():getVehicle()-- your seat entity reference here
  26.            
  27.             -- Make sure we're in the vehicle
  28.             if not seat or not player():inVehicle() then
  29.                 return
  30.             end
  31.            
  32.         local eyeAngles = seat:getParent():worldToLocalAngles(player():getEyeAngles())
  33.        
  34.         -- Convert angles to forward vector (but ignore roll/pitch for horizontal orbit)
  35.         local forward = eyeAngles:getForward()
  36.         local cameraPos = seat:getParent():localToWorld(  -forward * 500 + Vector(0, 0, 100) )
  37.        
  38.         local view = {
  39.             origin = cameraPos,
  40.             angles = ((seat:getParent():getPos() - cameraPos):getAngle()),
  41.             fov = 77,
  42.             drawviewer = true
  43.         }
  44.            
  45.             return view
  46.         end )
  47.     end
  48.    
  49.     local function deinit_3ps_cam()
  50.         hook.remove('calcview', 'artybyte_veh_view')
  51.     end
  52.    
  53.     hook.add('think', 'artybyte_veh_ventus_think_cl', function( )
  54.  
  55.         if ventus.cam_key_pressed ~= input.isKeyDown(KEY.V) then
  56.             ventus.cam_key_pressed = input.isKeyDown(KEY.V)
  57.            
  58.             if ventus.cam_key_pressed then
  59.                 ventus.int_camera = not ventus.int_camera
  60.             end
  61.            
  62.             if ventus.int_camera then
  63.                 init_3ps_cam()
  64.             else
  65.                 deinit_3ps_cam()
  66.             end
  67.         end
  68.        
  69.     end )
  70.    
  71.     net.receive('gmveh_ventus', function( )
  72.         local t = net.readTable()
  73.        
  74.         ventus.ignition = t.ignition
  75.        
  76.         ventus.cyclic_FB = t.cyclicFB
  77.         ventus.cyclic_LR = t.cyclicLR
  78.        
  79.         ventus.throttle_up_down = t.throttleUD
  80.        
  81.         ventus.rear_rotor_blades_ang = t.steerLR
  82.     end )
  83. end
  84.  
  85.  
  86. if SERVER then
  87.     local VEH = { }
  88.     VEH.DriverChairLocalPos = Vector(34.16, 13.90, -14.68)
  89.     VEH.DriverChairLocalAng = Angle(0, -90, 5)
  90.     VEH.CamAngles = Angle()
  91.     VEH.TractionVector = Vector()
  92.     VEH.mass = 1200
  93.     VEH.ignition = false
  94.     VEH.data = { ignition = false, cyclicFB = 0, cyclicLR = 0, throttleUD = 0, steerLR = 0 }
  95.     VEH.starter_counter = 0
  96.     VEH.last_force_pos = Vector(0, 0, 0)
  97.    
  98.     VEH.cl_nets = {
  99.         throttle = 0,
  100.         blade_L_up = Vector(),
  101.         blade_R_up = Vector(),
  102.         rear_rotor_ang = 0,
  103.         blade_L_ang = 0,
  104.         blade_R_ang = 0
  105.     }
  106.    
  107.     local A = 1
  108.    
  109.     net.receive('gmveh_ventus_cyclic', function( )
  110.         local t = net.readTable()
  111.         VEH.cl_nets = t
  112.     end )
  113.  
  114.     VEH.HUD = prop.createComponent(
  115.     chip():localToWorld(VEH.DriverChairLocalPos),
  116.     chip():getAngles(),
  117.     'starfall_hud',
  118.     'models/holograms/hq_tube_thick.mdl',
  119.     true
  120.     )
  121.     VEH.HUD:setParent(chip())
  122.     VEH.HUD:setColor(Color(0,0,0,0))
  123.  
  124.     VEH.DriverChair = prop.createSeat(chip():localToWorld(VEH.DriverChairLocalPos), chip():localToWorldAngles(VEH.DriverChairLocalAng), 'models/nova/jeep_seat.mdl', true)
  125.     VEH.DriverChair:setParent(chip())
  126.     VEH.DriverChair:setColor(Color(0,0,0,0))
  127.    
  128.  
  129.     --VEH.testholo = hologram.create(chip():getPos(), chip():localToWorldAngles(Angle()), 'models/holograms/hq_sphere.mdl')
  130.     --VEH.testholo:setScale(Vector(3, 3, 3))
  131.    
  132.     chip():setMass(VEH.mass)
  133.    
  134.     chip():setColor(Color(0,0,0,0))
  135.    
  136.     VEH.HUD:linkComponent(VEH.DriverChair)
  137.     VEH.HUD:linkComponent(chip())
  138.    
  139.     hook.add('think', 'artybyte_veh_ventus_think', function()
  140.        
  141.         local Driver = VEH.DriverChair:getDriver()
  142.        
  143.         if Driver ~= nil then
  144.             if isValid(Driver) then
  145.                
  146.                 local w, a, s, d =
  147.                 Driver:keyDown(IN_KEY.FORWARD),
  148.                 Driver:keyDown(IN_KEY.MOVELEFT),
  149.                 Driver:keyDown(IN_KEY.BACK),
  150.                 Driver:keyDown(IN_KEY.MOVERIGHT)
  151.                
  152.                 local ignition = Driver:keyDown(IN_KEY.RELOAD)
  153.                
  154.                 local lmb, rmb = Driver:keyDown(IN_KEY.ATTACK), Driver:keyDown(IN_KEY.ATTACK2)
  155.                
  156.                 local shift, space = Driver:keyDown(IN_KEY.SPEED), Driver:keyDown(IN_KEY.JUMP)
  157.                
  158.                 local fb = ( w and 1 or 0 ) - ( s and 1 or 0 )
  159.                 local lr = ( a and 1 or 0 ) - ( d and 1 or 0 )
  160.                 local ud = ( shift and 1 or 0 ) - ( space and 1 or 0 )  
  161.                 local steer =  ( lmb and 1 or 0 ) - ( rmb and 1 or 0 )
  162.                
  163.                 if ignition and not VEH.data.ignition then
  164.                     VEH.starter_counter = VEH.starter_counter + 1
  165.                    
  166.                     if VEH.starter_counter > 5 then
  167.                         VEH.starter_counter = 0
  168.                         chip():emitSound('buttons/lightswitch2.wav', 155, 255, 1, 0)
  169.                         chip():setColor(Color(255,0,0,0))
  170.                         if math.random(1, 50) == 4 then
  171.                             VEH.data.ignition = true
  172.                             chip():setColor(Color(0,0,0,0))
  173.                         end
  174.                     end
  175.                 else
  176.                     chip():setColor(Color(0,0,0,0))
  177.                 end
  178.                
  179.                 if ignition ~= VEH.ignition then
  180.                     VEH.ignition = ignition
  181.                     if ignition then
  182.                         if VEH.data.ignition then
  183.                             VEH.data.ignition = false
  184.                             chip():setColor(Color(0,0,0,0))
  185.                         end
  186.                     end
  187.                 end
  188.                
  189.                 VEH.data.cyclicFB =         math.lerp(0.05, VEH.data.cyclicFB, lr)
  190.                 VEH.data.cyclicLR =         math.lerp(0.05, VEH.data.cyclicLR, -fb)
  191.                 VEH.data.throttleUD =       math.lerp(0.05, VEH.data.throttleUD, -ud)
  192.                 --VEH.data.throttleUD = math.clamp(VEH.data.throttleUD - ud*0.02, -1, 1)
  193.                 VEH.data.steerLR =          math.lerp(0.05, VEH.data.steerLR, -steer)
  194.                
  195.                 local physics = chip():getPhysicsObject()
  196.                
  197.                 local blades_dir = (( ( VEH.cl_nets.blade_L_up ) + ( VEH.cl_nets.blade_R_up ) ) /2 ):getNormalized()
  198.                
  199.                 blades_dir.x = math.round(blades_dir.x, 2)
  200.                 blades_dir.y = math.round(blades_dir.y, 2)
  201.                 blades_dir.z = math.round(blades_dir.z, 2)
  202.                
  203.                 if IsNAN(VEH.TractionVector.x) then VEH.TractionVector.x = 0 end
  204.                 if IsNAN(VEH.TractionVector.y) then VEH.TractionVector.y = 0 end
  205.                 if IsNAN(VEH.TractionVector.z) then VEH.TractionVector.z = 0 end
  206.                
  207.                 local force_up_pos = chip():localToWorld(Vector(0, 0, 75 + 9))
  208.                 local last_up_pos = VEH.last_force_pos
  209.                
  210.                 local up_pos_delta = force_up_pos - last_up_pos
  211.                
  212.                 VEH.WindResistance = -physics:getVelocity()*0.05
  213.                
  214.                 -- MAIN rotor
  215.                 physics:applyForceOffset(VEH.TractionVector, force_up_pos - up_pos_delta)
  216.                
  217.                 local hor_rot = physics:getAngleVelocity().z
  218.                
  219.                 local brake_hor_rot = ( - hor_rot*0.1 * ( 1 - math.abs(VEH.cl_nets.tail_rotor_axis) ) ) * VEH.cl_nets.throttle
  220.                
  221.                 -- TAIL rotor
  222.                 physics:applyForceOffset(chip():getRight() * chip():getMass() * ( 0.037 * ( -VEH.cl_nets.tail_rotor_axis + brake_hor_rot ) ) * VEH.cl_nets.throttle, chip():localToWorld(Vector(-304.7, 14.33, 51.91 + 9)))
  223.  
  224.                 -- tail rotor force local point
  225.                
  226.                 -- wind resistance. slowing down helicopter on speed.
  227.                
  228.                 physics:applyForceOffset(VEH.WindResistance * physics:getMass() * 0.004, force_up_pos)
  229.                
  230.  
  231.                 local cyclic_nonzero = Vector(fb, 0, lr):getNormalized():getLength()
  232.                
  233.                 --local targetTractionVector = ((chip():getUp()*0.2) * (blades_dir*(0.03 + ud*0.25)) + (blades_dir*VEH.cl_nets.throttle*0.2)) * VEH.cl_nets.throttle * chip():getMass() * 60
  234.                 local targetTractionVector = (( blades_dir * VEH.cl_nets.throttle * ( 0.16 + (VEH.data.throttleUD*0.05) ) ) ) * VEH.cl_nets.throttle * chip():getMass() * 60
  235.                
  236.                 --                                  0.05, 0.075
  237.                 -- very important to smooth swashplate raw resulting vector between blades to make flight stable.
  238.                 VEH.TractionVector = math.lerpVector( 0.05, VEH.TractionVector, targetTractionVector )
  239.                
  240.                 --VEH.testholo:setPos(chip():getPos() + VEH.TractionVector * 3.0)
  241.                
  242.                 A = A + 1
  243.                
  244.                 if A == 3 then
  245.                     net.start('gmveh_ventus')
  246.                         net.writeTable(
  247.                             VEH.data
  248.                         )
  249.                     net.send()
  250.                    
  251.                     A = 1
  252.                 end
  253.                
  254.                 VEH.last_force_pos = chip():localToWorld(Vector(0, 0, 75 + 9))
  255.             end
  256.         end
  257.            
  258.     end )
  259. end
Advertisement
Add Comment
Please, Sign In to add comment