-- LUA Script - precede every function and global member with lowercase name of script + '_main' local Q = require "scriptbank\\quatlib" local U = require "scriptbank\\utillib" local P = require "scriptbank\\physlib" local rad = math.rad local deg = math.deg local atan = math.atan2 local modf = math.modf local abs = math.abs function my_boat_init( e ) Include( "utillib.lua" ) Include( "quatlib.lua" ) Include( "physlib.lua" ) local obj = g_Entity[ e ].obj SetObjectDamping( obj, 0.5, 0.5 ) end local my_boat = {} local controlEnt = nil local timeLastFrame = nil local timeDiff = 0 local hoverHeight = 36 local liftFactor = 20 local maxLift = 14 local minLift = 0 local liftPoints = { { xo = -50, zo = 0 }, -- left { xo = -50, zo = 100 }, -- front left { xo = 0, zo = 100 }, -- front1 { xo = 0, zo = 50 }, -- front2 { xo = 50, zo = 100 }, -- front right { xo = 0, zo = 0 }, -- centre { xo = 50, zo = 0 }, -- right { xo = 50, zo = -100 }, -- right rear { xo = 0, zo = -100 }, -- rear1 { xo = 0, zo = -50 }, -- rear2 { xo = -50, zo = -100 } -- rear left } local function doLift( h, x, y, z, xa, ya, za, timeDiff ) local ux, uy, uz = U.Rotate3D ( 0, 1, 0, xa, ya, za ) local lift --if uy < 0.5 then return end local wh = GetWaterHeight() for i = 1, #liftPoints do local lp = liftPoints[ i ] local xo, yo, zo = U.Rotate3D ( lp.xo, 0, lp.zo, xa, ya, za ) local hd = ( y + yo ) - wh lift = ( h.lFact * ( h.height - hd ) / h.height ) * timeDiff if lift > maxLift then lift = maxLift end if lift < minLift then lift = minLift end h.liftVals[ i ] = lift PushObject( h.obj, ux * lift, uy * lift, uz * lift, xo, yo, zo ) end end local playerPos1 = { xo = 0, yo = 75, zo = -300 } local playerPos2 = { xo = 0, yo = 50, zo = -150 } -- steering wheel local sw_offs = { x = 22.2, y = 34.2, z = 5 } local swPitch = 7.5 local pitchQ = Q.FromEuler( rad( swPitch ), 0, 0 ) -- exhaust local ex_offs = { x = 81.5, y = 15.5, z = -88 } local rotate = 0 local function AttachPlayer( pp, x, y, z, xa, ya, za ) local xo, yo, zo = U.Rotate3D( pp.xo, pp.yo, pp.zo, xa, ya, za ) cx, cy, cz = x + xo, y + yo, z + zo SetCameraPosition ( 0, cx, cy, cz ) SetCameraAngle ( 0, deg( xa ) + 15, deg( ya ), deg( za ) ) xo, yo, zo = U.Rotate3D( 0, 200, -50, xa, ya, za ) SetFreezePosition( x + xo, y + yo, z + zo ) SetFreezeAngle( 0, deg( ya ), 0 ) TransportToFreezePosition() end local function CheckForCollision( obj ) local colList = P.GetObjectCollisionDetails( obj ) local lastObj = 0 if colList ~= nil then for i, v in ipairs( colList ) do if v.obj ~= lastObj then lastObj = v.obj PlaySoundIfSilent( P.ObjectToEntity( v.obj ), 0 ) end end end end local EPressed = false function my_boat_main( e ) local h = my_boat[ e ] if h == nil then local Ent = g_Entity[ e ] local x, y, z, xa, ya, za = GetObjectPosAng( Ent.obj ) my_boat[ e ] = { state = 'init', timer = math.huge, obj = Ent.obj, turnAng = 0, speed = 80, height = hoverHeight, lFact = liftFactor, liftVals = {}, pp = playerPos2 } return end local timeNow = g_Time if h.state == 'init' then h.state = 'start' h.timer = timeNow + 1000 end if controlEnt == nil then controlEnt = e end if controlEnt == e then if timeLastFrame == nil then timeLastFrame = timeNow timeDiff = 1 else timeDiff = ( timeNow - timeLastFrame ) / 20 timeLastFrame = timeNow end end if h.state == 'start' then local x, y, z, xa, ya, za = GetObjectPosAng( h.obj ) xa, ya, za = rad( xa ), rad( ya ), rad ( za ) doLift( h, x, y, z, xa, ya, za, timeDiff ) -- forward thrust local vx, vy, vz = U.Rotate3D ( 0, 0, 1, xa, ya, za ) local px, py, pz = U.Rotate3D ( 0, 0, -100, xa, ya, za ) if h.inCab then if g_KeyPressE == 1 then if not EPressed then EPressed = true SetCameraOverride( 0 ) SetPlayerWeapons( 1 ) h.inCab = false SetObjectDamping( h.obj, 0.5, 0.5 ) h.height = hoverHeight StopSound( e, 0 ) RemoveObjectCollisionCheck( h.obj ) Show( GetGamePlayerControlThirdpersonCharactere() ) end else EPressed = false end if g_KeyPressR == 1 then if not RPressed then RPressed = true if h.pp == playerPos1 then --Hide( h.steeringMan.Ent ) --Show( h.steering.Ent ) h.pp = playerPos2 else --Show( h.steeringMan.Ent ) --Hide( h.steering.Ent ) h.pp = playerPos1 end end else RPressed = false end if g_KeyPressW == 1 then PlaySoundIfSilent( e, 1 ) PushObject( h.obj, vx * timeDiff * h.speed, vy * timeDiff * h.speed, vz * timeDiff * h.speed, px, py, pz ) elseif g_KeyPressS == 1 then PlaySoundIfSilent( e, 1 ) PushObject( h.obj, vx * timeDiff * -h.speed, vy * timeDiff * h.speed, vz * timeDiff * -h.speed, -px, py, -pz ) else StopSound( e, 1 ) end AttachPlayer( h.pp, x, y, z, xa, ya, za ) -- turning thrust vx, vy, vz = U.Rotate3D ( 1, 0, 0, xa, ya, za ) px, py, pz = U.Rotate3D ( 0, 0, -150, xa, ya, za ) if g_KeyPressA == 1 then if h.turnAng > -15 then h.turnAng = h.turnAng - 0.1 * timeDiff end elseif g_KeyPressD == 1 then if h.turnAng < 15 then h.turnAng = h.turnAng + 0.1 *timeDiff end else if h.turnAng <= -0.4 then h.turnAng = h.turnAng + 0.4 *timeDiff elseif h.turnAng >= 0.4 then h.turnAng = h.turnAng - 0.4 *timeDiff else h.turnAng = 0 end end local pa = -h.turnAng * timeDiff if pa ~= 0 then PushObject( h.obj, pa * vx, 0, pa * vz, px, py, pz ) end CheckForCollision( h.obj ) else if U.PlayerLookingNear( e, 200, 180 ) then Prompt( "E to drive me" ) if g_KeyPressE == 1 then if not EPressed then h.height = hoverHeight LoopNon3DSound( e, 0 ) EPressed = true SetPlayerWeapons( 0 ) SetCameraOverride( 3 ) h.inCab = true if h.pp == playerPos1 then --Show( h.steeringMan.Ent ) --Hide( h.steering.Ent ) end SetObjectDamping( h.obj, 0.1, 0.3 ) AddObjectCollisionCheck( h.obj ) Hide( GetGamePlayerControlThirdpersonCharactere() ) h.lFact = 19 end else EPressed = false end end end end end