Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local config = {
- -- Control Panel for Blackhole v5 Alpha release 4. This script is for dummies!
- -- If you want the nerdy mumbo jumbo, head to `BHv5_Alpha_MAIN` and `BHv5A_Core`
- -- Also, DONT DELETE THE COMMAS!!!
- -- More details on `v5A_Documentation_READ` --
- hole = script.Parent ,
- gravitationalConstant = 1000 --[[ Gravitational strength, 1000 is default ]] ,
- updateInterval = 0 --[[ Time in seconds to run calculations, 0 is real-time ]] ,
- damping = 0.7 --[[ Another knob to amplify or dampen gravitational strength ]] ,
- rangeFactor = 500 --[[ Radius where gravity attracts objects for BodyForce-based gravity ]] ,
- transparencySteps = {0.25, 0.5, 0.75} --[[ Transparencies which objects undergo before getting absorbed ]] ,
- dematerializeDuration = 0.01 --[[ Time in seconds to go through `transparencySteps` to fade out of existance ]] ,
- partMaterialTransform = Enum.Material.Neon --[[ Material objects go through while getting absorbed ]] ,
- partColor = BrickColor.new(0) --[[ Color objects go through while getting absorbed (white is default) ]] ,
- absorption = true --[[ Allow absorption? ]] ,
- sizeProportion = 42 --[[ Factor on how fast the blackhole will grow (smaller is faster. I know, its weird) ]] ,
- rangeProportion = 125 --[[ Factor on how fast the range will grow (bigger is faster. I should fix this...) ]] ,
- growth = true --[[ Allow the blackhole to grow? ]] ,
- killPlayers = true --[[ Self-explanitory ]] ,
- collision = false --[[ Allow objects to pass through eachother while getting absorbed? Affects performance, by the way ]] ,
- fixedPosition = true --[[ Anchor objects while getting absorbed? Also affects performance ]] ,
- toggleMicroGravity = false --[[ Disable world gravity? You can go to settings, but you can use this if youre feeling lazy ]] ,
- -- Beta Parameters --
- infinityHandler = true --[[ Prevent objects from getting infinite speed? Highly recommended you keep this on ]] ,
- paradoxHandler = false --[[ Pevent blackholes from annihilating itself when it touches another of its kind? ]] ,
- mergeBlackholes = true --[[ Allow blackholes to merge blackholes? ]] ,
- gravityEngine = "bodyforce" --[[ Try "velocity". Note: Velocity is accurate but unstable, bodyforce is inaccurate but stable (accepts 1 or 2) ]] ,
- glint = script.Parent.VFX.Glint --[[ Just in case you move or change the name ]] ,
- glintProportion = 1.5 --[[ Factor for glint to grow in proportion ]] ,
- rocheLimitFactor = 3 --[[ Radius (in multiples) where joints are destroyed... for realism! ]] ,
- gravitySync = true --[[ Synchronize velocity and bodyforce gravities? Velocity is OP! ]]
- }
- -- Updates documented in `UPDATE_LOG` under `v5A_Documentation_READ`
- --/-/-/-/-/-/-/--
- -- This is how the blackhole works, which requires big brain coding.
- require(script.BHv5A_Core).Setup(config).Run()
Advertisement
Comments
-
- local BlackHoleCore = {}
- -- Hi, welcome to the main works of Blackhole v5 Alpha! I guess you know these stuff, so feel free to break it!
- -- Logger for one-time messages
- local logger = {
- bodyForce = false,
- velocity = false,
- sizeProp = false,
- zeroGrav = false,
- consuming = false,
- gravEngine = false
- }
- function BlackHoleCore.Setup(config)
- local self = {}
- -- Store configuration values
- self.hole = config.hole
- self.gravitationalConstant = config.gravitationalConstant
- self.updateInterval = config.updateInterval
- self.damping = config.damping
- self.rangeFactor = config.rangeFactor
- self.transparencySteps = config.transparencySteps
- self.dematerializeDuration = config.dematerializeDuration
- self.sizeProportion = config.sizeProportion
- self.rangeProportion = config.rangeProportion
- self.partColor = config.partColor
- self.partMaterialTransform = config.partMaterialTransform
- self.absorption = config.absorption
- self.growth = config.growth
- self.killPlayers = config.killPlayers
- self.collision = config.collision
- self.fixedPosition = config.fixedPosition
- self.toggleMicroGravity = config.toggleMicroGravity
- self.infinityHandler = config.infinityHandler
- self.paradoxHandler = config.paradoxHandler
- self.mergeBlackholes = config.mergeBlackholes
- self.gravityEngine = config.gravityEngine
- self.glint = config.glint
- self.glintProportion = config.glintProportion
- self.rocheLimitFactor = config.rocheLimitFactor
- self.gravitySync = config.gravitySync
- -- Internal variables
- self.lastUpdateTime = 0
- self.logger = logger
- self.CollectionService = game:GetService("CollectionService")
- self.previousSize = self.hole.Size.X
- self.glintProportions = self.previousSize * self.glintProportion
- ---------------------------------------------------------------------
- -- CORE FUNCTIONS
- ---------------------------------------------------------------------
- -- Destroy joints within the Roche limit
- function self.DestroyJointsWithinRocheLimit(object)
- local distance = (self.hole.Position - object.Position).Magnitude
- local rocheLimit = (self.hole.Size.Magnitude / 2) * self.rocheLimitFactor
- if distance <= rocheLimit then
- for _, descendant in pairs(object:GetDescendants()) do
- if descendant:IsA("JointInstance") then descendant:Destroy() end
- end
- end
- end
- -- Apply gravity to a given object
- function self.ApplyGravity(object)
- local currentTime = tick()
- if currentTime - self.lastUpdateTime < self.updateInterval then return end
- self.lastUpdateTime = currentTime
- local direction = self.hole.Position - object.Position
- local distance = direction.Magnitude
- local holeRadius = self.hole.Size.Magnitude / 2
- local distanceSquared = (distance / ((self.rangeFactor / 100) + ((self.rangeFactor / 100) * (1 / 64))))^2
- local magnitude = self.gravitationalConstant / distanceSquared
- -- Dampening for velocity-based gravity when gravitySync is enabled
- local engineType = string.lower(self.gravityEngine)
- if (engineType == "velocity" or engineType == "speed" or engineType == "2") and self.gravitySync then
- magnitude = magnitude / (self.gravitationalConstant * 0.1)
- end
- local force = direction.Unit * magnitude * object:GetMass()
- -- Infinity handler: neutralize force inside inner radius
- if self.infinityHandler and distance < holeRadius then
- force = Vector3.zero
- direction = Vector3.zero
- end
- -- Apply force/velocity based on gravity engine
- if engineType == "bodyforce" or engineType == "force" or engineType == "1" then
- local bodyForce = object:FindFirstChild("BlackHoleBodyForce") or Instance.new("BodyForce", object)
- bodyForce.Name = "BlackHoleBodyForce"
- bodyForce.Force = (bodyForce.Force + force) * self.damping
- if not self.logger.bodyForce then
- print("{BHv5A} Using FORCE-based gravity (+Stability, -Accuracy) MODEL SUPPORTED")
- self.logger.bodyForce = true
- end
- elseif engineType == "velocity" or engineType == "speed" or engineType == "2" then
- local blackHoleRadius = self.hole.Size.X / 2
- if distance < blackHoleRadius then return end
- object.Velocity = object.Velocity + force * self.damping
- if not self.logger.velocity then
- print("{BHv5A} Using VELOCITY-based gravity (-Stability, +Accuracy) DOES NOT SUPPORT MODELS!!!")
- self.logger.velocity = true
- end
- else
- print("{BHv5A} Invalid Gravity Engine request! Switching to default (Force-based Gravity)")
- self.logger.gravEngine = true
- self.gravityEngine = "1"
- end
- end
- -- Check and apply gravity to an object if appropriate
- function self.CheckAndApplyGravity(obj)
- if not obj:IsDescendantOf(game.Workspace) or not obj:IsA("BasePart") then return end
- if obj == self.hole or obj.Parent:IsA("Player") or obj.Anchored then return end
- self.DestroyJointsWithinRocheLimit(obj)
- self.ApplyGravity(obj)
- end
- -- Absorb smaller black holes
- function self.AbsorbSmallerBlackHole(otherBlackHole)
- local function AverageSize(part)
- return (part.Size.X + part.Size.Y + part.Size.Z) / 3
- end
- local thisSize = AverageSize(self.hole)
- local otherSize = AverageSize(otherBlackHole)
- local sizeDifference = math.floor((thisSize - otherSize) * 1000 + 0.5) / 1000
- local function resetForces(blackHole)
- local bf = blackHole:FindFirstChild("BlackHoleBodyForce")
- if bf then bf.Force = Vector3.new(0, 0, 0) end
- end
- local function applyNewForce(blackHole)
- local newBF = Instance.new("BodyForce", blackHole)
- newBF.Force = Vector3.new(0, blackHole.Size.Magnitude * 2, 0)
- end
- if sizeDifference > 0.001 then
- self.CollectionService:RemoveTag(otherBlackHole, "Blackholev5")
- task.wait(0.01)
- resetForces(otherBlackHole)
- self.hole.Size = otherBlackHole.Size * 0.5
- self.rangeFactor = (self.hole.Size.Magnitude * 0.5) * (self.rangeProportion / self.sizeProportion)
- otherBlackHole:Destroy()
- resetForces(self.hole)
- applyNewForce(self.hole)
- elseif sizeDifference < -0.001 then
- task.wait(0.1)
- resetForces(otherBlackHole)
- applyNewForce(otherBlackHole)
- self.hole:Destroy()
- else
- local unifiedSize = self.hole.Size * 2
- local newBlackHole = self.hole:Clone()
- newBlackHole.Size = unifiedSize
- newBlackHole.Position = self.hole.Position
- newBlackHole.Parent = self.hole.Parent
- self.CollectionService:AddTag(newBlackHole, "Blackholev5")
- local newGlintSize = self.glint.Size.Keypoints[1].Value * 2
- newBlackHole.VFX.Glint.Size = NumberSequence.new(newGlintSize)
- self.hole:Destroy()
- otherBlackHole:Destroy()
- resetForces(newBlackHole)
- applyNewForce(newBlackHole)
- self.hole = newBlackHole
- end
- end
- -- Damage players when they touch the black hole
- function self.onTouch(part)
- local humanoid = part.Parent:FindFirstChild("Humanoid")
- if humanoid then humanoid.Health = 0 end
- end
- -- Update Glint's size based on the black hole's size
- function self.updateGlintSize()
- local currentSize = self.hole.Size.X
- if currentSize ~= self.previousSize then
- local scaleFactor = currentSize / self.previousSize
- local newSize = self.glint.Size.Keypoints[1].Value * scaleFactor
- self.glint.Size = NumberSequence.new(newSize)
- self.previousSize = currentSize
- end
- end
- ---------------------------------------------------------------------
- -- RUN FUNCTION: SET UP LOOP & EVENT CONNECTIONS (INCLUDING ABSORPTION)
- ---------------------------------------------------------------------
- function self.Run()
- local RunService = game:GetService("RunService")
- -- Set up absorption events if enabled
- if self.absorption then
- self.hole.Touched:Connect(function(part)
- if self.CollectionService:HasTag(part, "Blackholev5") and self.mergeBlackholes then
- self.AbsorbSmallerBlackHole(part)
- return
- end
- if part.Anchored or (self.CollectionService:HasTag(part, "Blackholev5") and self.paradoxHandler) then
- return
- end
- local function CalculateAverageSize(part)
- return (part.Size.X + part.Size.Y + part.Size.Z) / 3
- end
- local objectAverageSize = CalculateAverageSize(part)
- local blackHoleSize = self.hole.Size.X
- local sizeIncrement = objectAverageSize / (blackHoleSize * self.sizeProportion)
- part.BrickColor = self.partColor
- part.Material = self.partMaterialTransform
- part.CanCollide = self.collision
- part.Anchored = self.fixedPosition
- for _, transparency in ipairs(self.transparencySteps) do
- part.Transparency = transparency
- wait(self.dematerializeDuration)
- end
- part:Destroy()
- if self.growth then
- self.hole.Size = self.hole.Size + Vector3.new(sizeIncrement, sizeIncrement, sizeIncrement)
- self.rangeFactor = self.rangeFactor + sizeIncrement * self.rangeProportion
- end
- end)
- print("{BHv5A} Absorption is ENABLED")
- else
- print("{BHv5A} Absorption is DISABLED")
- end
- -- Main gravitational loop
- RunService.Heartbeat:Connect(function()
- for _, obj in pairs(workspace:GetDescendants()) do
- self.CheckAndApplyGravity(obj)
- end
- self.updateGlintSize()
- end)
- -- Connect kill-player logic if enabled
- if self.killPlayers then
- self.hole.Touched:Connect(self.onTouch)
- end
- -- Toggle micro gravity
- workspace.Gravity = self.toggleMicroGravity and 0 or workspace.Gravity
- print("{BHv5A} Gravity is " .. (self.toggleMicroGravity and "DISABLED" or "ENABLED"))
- end
- return self
- end
- return BlackHoleCore
Add Comment
Please, Sign In to add comment
Advertisement