Files
PlaneBuilding/scripts/modules/objects/Propeller.lua
T

127 lines
4.0 KiB
Lua

local module = {}
local dens = game.Workspace.AirDensity * -game.Workspace.CompensateDensity.Value
local bias = 0.2
local propeller_power_mod = 0.1
local propeller_cut_mod = 5/2
local propeller_reaction_mod = 0.05
game.Workspace.CompensateDensity.Changed:Connect(function()
dens = game.Workspace.AirDensity * -game.Workspace.CompensateDensity.Value
end)
_G.Events.Command.Event:Connect(function(message)
local value = message:match("setprop%((.-)%)")
if not value then return end
if tonumber(value) then
game.Workspace.CompensateDensity = tonumber(value)
_G.Events.Notification:Fire("Set Prop Density","PropBias.Value = "..value)
else
_G.Events.Notification:Fire("Set Prop Density","Invalid number.")
end
end)
local function setup(this,propeller,context)
local angle = _G.GetValue(propeller,"Trim",30)
for _,child in pairs(propeller:GetChildren()) do
if child.Name == "Blade" then
local welds = child:GetJoints()
local joint = child:FindFirstChild("Weld")
if not child:FindFirstChild("Weld") then
local c0 = propeller.PrimaryPart.CFrame:ToObjectSpace(child.CFrame)
joint = Instance.new("Motor6D")
joint.Name = "Weld"
joint.Parent = child
joint.Part0 = propeller.PrimaryPart
joint.Part1 = child
joint.C0 = c0
end
local flip = 0
if angle < 0 then flip = 180 end
local axis = (propeller:GetAttribute("Axis") or Vector3.new(0,0,1)) * (math.rad(-angle+flip))
local rotation = CFrame.Angles(axis.X,axis.Y,axis.Z)
joint.C1 = rotation
for _,weld in pairs(welds) do if weld:IsA("WeldConstraint") then weld:Destroy() end end
end
end
end
function module.new(this,propeller,context)
local size = propeller:GetExtentsSize()
this.scale = size.X * size.Z * 1.5
this.length = size.X
this.power = _G.GetValue(propeller,"Force",1000) * this.scale * 0.01
this.direction = _G.GetValue(propeller,"Direction",CFrame.identity)
this.rotor = propeller:FindFirstChild("Spin") or propeller:FindFirstChild("Hinge")
this.trim = _G.GetValue(propeller,"Trim",30)
this.blur = propeller:FindFirstChild("Blur")
if not this.rotor then error("Missing rotor") end
this.force = _G.GetInstance(propeller,"VectorForce")
this.sound = _G.GetInstance(this.rotor,"PropSound")
this.sound:Play()
setup(this,propeller,context)
return this
end
function module.update(this,propeller,context)
print("upd")
setup(this,propeller,context)
end
function module.idle(this,engine) return true end
local a = 300
local function limit(f)
return math.tanh(f/a)*a
end
local begin = tick()
module.run = _G.Protect(function(this,propeller,context)
local angular_velocity = ((this.rotor.CFrame.Rotation * this.direction):PointToObjectSpace(this.rotor.AssemblyAngularVelocity)).X
local linear_velocity = angular_velocity * math.sin(math.rad(this.trim))
local air_velocity = this.rotor.CFrame.Rotation:PointToObjectSpace(this.rotor.AssemblyLinearVelocity).X
local real_velocity = limit((linear_velocity * propeller_cut_mod * this.length) - air_velocity)
local rpm = (angular_velocity/(math.pi*2))*60
local multiplier = (this.sound:GetAttribute("Multiplier") or 1) * 0.01
this.force.Force = Vector3.new(0,0,-real_velocity*this.power*propeller_power_mod*dens)
this.rotor:ApplyAngularImpulse(
(this.rotor.CFrame.Rotation * this.direction).RightVector
* -angular_velocity
* math.cos(math.rad(this.trim))
* propeller_reaction_mod)
context.replicate(this,propeller,module,math.abs(rpm*dens*multiplier))
return true
end)
module.replication_delta = 0.1
function module.replicate(this,propeller,context,value)
this.sound.PlaybackSpeed = math.clamp(value,0.1,1.5)
this.sound.Volume = math.clamp(value,0,this.sound:GetAttribute("Max") or 1)
if this.blur then
this.blur.Transparency = math.clamp(1-value,0.3,1)
end
for _,blade in pairs(propeller:GetChildren()) do
if blade.Name == "Blade" then
blade.Transparency = math.clamp(value,0,0.7)
end
end
end
module.messages = {
trim = function(this,object,context,value)
end
}
module.messages.default = module.messages.trim
module.manifest = {
"Propeller",
"Turbine",
"LargePropeller",
"BiPropeller",
"Jet"
}
return module