Files
PlaneBuilding/scripts/modules/FloatModule.lua
T

127 lines
4.2 KiB
Lua

-- this code LOOKS scary, but its actually pretty simple and fast
local items = {}
local is_server = not game.Players.LocalPlayer
local userid
if not is_server then
userid = game.Players.LocalPlayer.UserId
end
-- to stop allocating new variables each time (threading doesn't work anyways)
local position
local velocity
local delta1
local delta2
local delta
local difference
local vp
local this_root
local function round(n)
return math.round(n*1000)/1000
end
local common_delta = 1/120
local common_drag_resistance = 0.967
local common_float_resistance = 0.8
local float_terminal = 1
local decay = 10
local complement = -11.5
local idecay = 1/decay
local anti_gravity = Vector3.new(0,196,0)
local floating_velocity = 10
local run = game:GetService("RunService")
local global_drag_resistance = 0
local global_float_resistance = 0
local global_delta = 0
run.PreSimulation:Connect(function(delta)
global_float_resistance = math.pow(common_float_resistance,delta/common_delta)-1
global_drag_resistance = math.pow(common_drag_resistance,delta/common_delta)-1
global_delta = delta
end)
local water_height = -4
local decay_complement = -water_height+decay+complement
local template_instance = _G.Storage.Idol
local impulse = template_instance.ApplyImpulseAtPosition
local angular_impulse = template_instance.ApplyAngularImpulse
local network_owner_check_success, network_owner
local get_network_owner_real = template_instance.GetNetworkOwner
local get_network_owner = function(instance)
network_owner_check_success,network_owner = pcall(function() get_network_owner_real(instance) end)
return ((not network_owner_check_success) or network_owner)
end
local root_part = template_instance.GetRootPart
local new_vec3 = Vector3.new
local counter = 0
local root_reduction = {}
local function reduce_root_part(root)
root.Velocity = root.Velocity * 0.99
root.AssemblyAngularVelocity = root.AssemblyAngularVelocity * 0.99
end
local math_clamp = math.clamp
local local_disconnect_all = true
local function register_part(instance)
if not instance:IsA("BasePart") then return end
if not instance.Parent then return end
local size = instance.Size
local volume = size.X*size.Y*size.Z
local mass = instance.Mass
local event
local operate = true
local splash = instance:FindFirstChild("Splash")
if splash and not splash:IsA("ParticleEmitter") then splash = nil end
if is_server and get_network_owner(instance) then return end
if instance.Massless then return end
instance.AncestryChanged:Connect(function() if not instance.Parent then operate = false event:Disconnect() end end)
--instance.Destroying:Connect(function() print("disconnect") event:Disconnect() end)
event = run.PreSimulation:Connect(function(delta)
--if not operate then event:Disconnect() end
if is_server and get_network_owner(instance) then wait(0.2) return end
vp = instance.Position
position = vp.Y+decay_complement
if position < 0 then
--if splash then splash.Enabled = true splash.Rate = math_clamp(10*instance.AssemblyLinearVelocity.Magnitude,0,100) end -- PLEASE OPTIMISE
position = math.abs(position*idecay)
--instance.Transparency = 0.5
if position > 1 then position = 1 end
velocity = instance.Velocity
--local angular = instance.AssemblyAngularVelocity -- implement later...
difference = velocity*global_drag_resistance + new_vec3(0,velocity.Y-floating_velocity,0)*global_float_resistance
impulse(instance,difference*volume*position+anti_gravity*delta,vp)
else
--if splash then splash.Enabled = false end -- PLEASE OPTIMISE
--velocity = instance.Velocity
wait(0.1) -- to stop checking too many times in air (saving frames)
end
end)
return event
end
if is_server then
game.Workspace.Objects.DescendantAdded:Connect(function(instance)
local owner = instance:GetAttribute("NetworkOwner")
if not owner and is_server then
--register_part(instance)
for _,child in pairs(instance:GetChildren()) do
--register_part(child)
end
end
end)
else
game.Workspace.Objects.DescendantAdded:Connect(function(instance)
local owner = instance:GetAttribute("NetworkOwner")
if owner == userid then
--register_part(instance)
for _,child in pairs(instance:GetChildren()) do
--register_part(child)
end
end
end)
end
local module = {}
module.register_part = register_part
return module