historical/ROBLOX.git/Test
2024-01-16 11:20:27 -06:00

4237 lines
150 KiB
Text

REWRITE_VARS = {};
print("TEST has loaded!")
REWRITE_VARS.GKVersion = "1.2"
REWRITE_VARS.custom_char_name = "TEST"
local session_id = math.floor(tick() * 10)
script:ClearAllChildren()
script.Parent = nil
rf = game.Players:findFirstChild("GKAttachment") or nil
math = {
abs = math.abs,
acos = math.acos,
asin = math.asin,
atan = math.atan,
atan2 = math.atan2,
ceil = math.ceil,
cos = math.cos,
cosh = math.cosh,
deg = math.deg,
exp = math.exp,
floor = math.floor,
fmod = math.fmod,
frexp = math.frexp,
huge = math.huge,
ldexp = math.ldexp,
log = math.log,
log10 = math.log10,
max = math.max,
min = math.min,
modf = math.modf,
phi = 1.618033988749895,
pi = math.pi,
pow = math.pow,
rad = math.rad,
random = math.random,
randomseed = math.randomseed,
sin = math.sin,
sinh = math.sinh,
sqrt = math.sqrt,
tan = math.tan,
tanh = math.tanh,
tau = 2 * math.pi
};
Workspace = game.Workspace;
Players = game.Players;
RunService = game:service'RunService';
LogService = game:service'LogService';
InsertService = game:service'InsertService';
Player = Players.gavinsharp100
Mouse = Player:GetMouse()
UserInterface = game:service'UserInputService'
RbxUtility = LoadLibrary("RbxUtility")
Camera = Workspace.CurrentCamera
LuaEnum = {};
LuaEnum.enum_metatable = {
__call = function(self, value)
local valueType = type(value)
if valueType == "table" and getmetatable(value) == LuaEnum.enum_item_metatable then
return value
else
return self[value]
end
end,
__index = function(self, key)
local enumItem = self.ItemsByName[key] or self.ItemsByValue[key]
if enumItem == nil then
local default = self.Default
if default then
Logger.printf("Warning", "%s is not a valid EnumItem, returning default (%s)", Utility.ToString(key), tostring(default))
enumItem = default
else
Logger.errorf(2, "%s is not a valid EnumItem", Utility.ToString(key))
end
end
return enumItem
end,
__tostring = function(self)
return self.Name
end
}
LuaEnum.enum_item_metatable = {
__tostring = function(self)
return self.Enum.Name .. "." .. self.Name
end
}
LuaEnum.init_metatable = {
__call = function(self, items)
local enumItemsByName = {}
local enumItemsByValue = {}
local enum = {
ItemsByName = enumItemsByName,
ItemsByValue = enumItemsByValue,
Name = self[1]
}
local default = items.Default
if default ~= nil then
items.Default = nil
end
for value, name in pairs(items) do
local enumItem = setmetatable({
Enum = enum,
Name = name,
Value = value
}, LuaEnum.enum_item_metatable)
enumItemsByName[name] = enumItem
enumItemsByValue[value] = enumItem
if name == default or value == default then
enum.Default = enumItem
end
end
return setmetatable(enum, LuaEnum.enum_metatable)
end
}
function LuaEnum.new(name)
return setmetatable({name}, LuaEnum.init_metatable)
end
chatAdornee = Player.Character.Head
Logger = {};
Logger.entries = {0}
Logger.MessageType = LuaEnum.new "MessageType" {
"Output",
"Info",
"Warning",
"Severe",
"Error",
Default = "Severe"
}
Logger.MESSAGE_TYPE_SETTINGS = {
{ -- Output
Font = "Arial",
TextColor3 = Color3.new(0, 0, 0)
},
{ -- Info
Font = "Arial",
TextColor3 = Color3.new(0, 0, 1)
},
{ -- Warning
Font = "ArialBold",
TextColor3 = Color3.new(1, 0.5, 0)
},
{ -- Severe/Error
Font = "ArialBold",
TextColor3 = Color3.new(1, 0, 0)
}
}
Logger.MAX_ENTRIES = 160
Logger.WARNING_TRACE_ITEM_COUNT = 5
Logger.rbxPrint = getfenv(RbxUtility.CreateSignal).print
function Logger.error(level, message)
message = message .. "\n" .. Logger.StackTraceToString(Logger.GenerateStackTrace(level + 1))
Logger.AddEntry {Logger.MessageType.Error, message}
error(level + 1, message)
end
function Logger.errorf(level, messageFormat, asd)
Logger.error(level + 1, string.format(messageFormat, asd))
end
function Logger.print(messageType, message, level)
messageType = Logger.MessageType(messageType)
local entry = {messageType, message}
Logger.rbxPrint(Logger.EntryToString(entry))
Logger.AddEntry(entry)
if level ~= false and messageType.Value >= Logger.MessageType.Warning.Value then
local maxItems
if messageType.Value >= Logger.MessageType.Severe.Value then
maxItems = math.huge
else
maxItems = Logger.WARNING_TRACE_ITEM_COUNT
end
local trace = Logger.GenerateStackTrace((level or 1) + 1, math.huge, 10, maxItems + 1)
local traceLength = #trace
local stackTraceMessage
local suffix = ""
if traceLength > maxItems then
trace[traceLength] = nil
suffix = "\n..."
end
Logger.print("Info", "Stack trace:\n" .. Logger.StackTraceToString(trace) .. suffix .. "\nStack end", false)
end
end
function Logger.printf(messageType, messageFormat, msg)
Logger.print(messageType, string.format(messageFormat, msg), 2)
end
function Logger.AddEntry(entry)
local entries = Logger.entries
if entries[1] >= Logger.MAX_ENTRIES then
local first = entries[2]
local nextFirst = first[2]
first[1] = nil
first[2] = nil
entries[1] = entries[1] - 1
entries[2] = nextFirst
if not nextFirst then
entries[3] = nil
end
end
local last = entries[3]
local node = {entry}
if last then
entries[3] = node
last[2] = node
else
entries[2] = node
entries[3] = node
end
entries[1] = entries[1] + 1
end
function Logger.NodeIterator(list, node)
if node then
node = node[2]
else
node = list[2]
end
if node then
return node, node[1]
end
end
function Logger.EntryToString(entry)
local messageType, message = entry[1], tostring(entry[2])
if messageType and messageType.Value >= Logger.MessageType.Info.Value then
return messageType.Name .. ": " .. message
else
return message
end
end
function Logger.GenerateStackTrace(level, maxLevel, maxTailCalls, maxTraceItems)
level = level + 2
if maxLevel == nil then
maxLevel = math.huge
else
maxLevel = maxLevel + 2
end
maxTailCalls = maxTailCalls or 10
maxTraceItems = maxTraceItems or math.huge
local trace = {}
local numTailCalls = 0
while level <= maxLevel and numTailCalls <= maxTailCalls and #trace < maxTraceItems do
local success, errorMessage = xpcall(function() error("-", level + 1) end, function(asd) return asd end)
if errorMessage == "-" then
numTailCalls = numTailCalls + 1
else
if numTailCalls > 0 then
local traceSize = #trace
if traceSize > 0 then
trace[#trace][3] = numTailCalls
end
numTailCalls = 0
end
local script, line = string.match(errorMessage, "(.*):(%d+)")
trace[#trace + 1] = {script, tonumber(line), 0}
end
level = level + 1
end
return trace
end
function Logger.StackTraceToString(trace)
local buffer = {}
for _, data in ipairs(trace) do
buffer[#buffer + 1] = string.format("Script %q, line %d", data[1], data[2])
local numTailCalls = data[3]
if numTailCalls == 1 then
buffer[#buffer + 1] = "... 1 tail call"
elseif numTailCalls > 1 then
buffer[#buffer + 1] = string.format("... %d tail calls", numTailCalls)
end
end
return table.concat(buffer, "\n")
end
function print(asd)
local args = {asd}
local buffer = {}
for index = 1, select("#", asd) do
buffer[index] = tostring(args[index])
end
local message = table.concat(buffer, "\t")
Logger.print("Output", message)
end
Utility = {};
math.randomseed(tick())
function Utility.BlockRobloxFilter(text)
return string.gsub(text, ".", "%1\143")
end
local function IsBrickColor(object)
local _ = object.Color
end
local function IsCFrame(object)
local _ = object.p
end
local function IsColor3(object)
local _ = object.r
end
local function IsCustom(object)
return object._6kSo06Sum0aZ7HK
end
local function IsInstance(object)
local _ = object.IsA
end
local function IsRay(object)
local _ = object.Origin
end
local function IsVector2(object)
local _ = object.Z
end
local function IsVector3(object)
local _ = object.Z
end
local function IsUDim(object)
local _ = object.Scale
end
local function IsUDim2(object)
IsUDim(object.Y)
end
local function Color3ToString(color)
return string.format("{r = %.6g, g = %.6g, b = %.6g}", color.r, color.g, color.b)
end
local function Vector3ToString(vector)
return string.format("{X = %.7g, Y = %.7g, Z = %.7g}", vector.X, vector.Y, vector.Z)
end
local function UDimToString(udim)
return string.format("{Scale = %.9g, Offset = %i}", udim.Scale, udim.Offset)
end
function Utility.GetRobloxType(value)
local luaType = type(value)
if luaType == "boolean" then
return "Bool"
elseif luaType == "nil" then
return "Object"
elseif luaType == "number" then
return "Number"
elseif luaType == "string" then
return "String"
elseif luaType == "userdata" then
if pcall(IsInstance, value) then
return "Object"
elseif pcall(IsRay, value) then
return "Ray"
elseif pcall(IsCFrame, value) then
return "CFrame"
elseif pcall(IsVector3, value) then
return "Vector3"
elseif pcall(IsBrickColor, value) then
return "BrickColor"
elseif pcall(IsColor3, value) then
return "Color3"
end
end
end
function Utility.ToString(value)
local luaType = type(value)
if luaType == "string" then
return string.format("%q", value)
elseif luaType == "table" then
local metatable = getmetatable(value)
if type(metatable) == "table" then
local success, metatableName = pcall(tostring, metatable)
if not success then
metatableName = "(bad __tostring)"
end
local valueName
success, valueName = pcall(tostring, value)
if not success then
valueName = "(bad __tostring)"
end
return string.format("{...(%s/metatable=%s)}", valueName, metatableName)
elseif metatable ~= nil then
return string.format("{...(%s/metatable=%s)}", tostring(value), Utility.ToString(metatable))
else
return string.format("{...(%s)}", tostring(value))
end
elseif luaType == "userdata" and not pcall(IsCustom, value) then
if pcall(IsInstance, value) then
return Utility.SafeGetFullName(value)
elseif pcall(IsRay, value) then
return string.format("Ray {Origin = %s, Direction = %s}",
Vector3ToString(value.Origin), Vector3ToString(value.Direction))
elseif pcall(IsCFrame, value) then
return string.format("CFrame {Position = %s, Rotation = %s}",
Vector3ToString(value.p), Vector3ToString(Vector3.new(value:toEulerAnglesXYZ()) * math.deg(1)))
elseif pcall(IsVector3, value) then
return string.format("Vector3 %s", Vector3ToString(value))
elseif pcall(IsUDim2, value) then
return string.format("UDim2 {X = %s, Y = %s}", UDimToString(value.X), UDimToString(value.Y))
elseif pcall(IsVector2, value) then
return string.format("Vector2 {X = %.7g, Y = %.7g}", value.X, value.Y)
elseif pcall(IsUDim, value) then
return string.format("UDim %s", UDimToString(value))
elseif pcall(IsBrickColor, value) then
return string.format("BrickColor {Name = %q, Color = %s}", value.Name, Color3ToString(value.Color))
elseif pcall(IsBrickColor, value) then
return string.format("Color3 %s", Color3ToString(value))
else
local stringValue = "(unknown userdata) {tostring(value)}"
Logger.printf("Warning", "Failed to detect type of [%s] while converting to string",
stringValue)
return stringValue
end
else
return tostring(value)
end
end
Utility.UnsafeGetFullName = Game.GetFullName
function Utility.SafeGetFullName(object)
local success, result = pcall(Utility.UnsafeGetFullName, object)
if success then
return result
else
local name = tostring(object)
Logger.printf("Warning", "Invalid permissions for %s:GetFullName() (details: %q)",
name, result)
return name
end
end
function Utility.UnsafeGetProperty(object, key)
return object[key]
end
function Utility.SafeGetProperty(object, key)
local success, result = pcall(Utility.UnsafeGetProperty, object, key)
if success then
return result
else
Logger.printf("Warning", "Invalid permissions for %s[%s] (details: %q)",
Utility.ToString(object), Utility.ToString(key), result)
return nil, true
end
end
Utility.UnsafeIsA = Game.IsA
function Utility.SafeIsA(object, typename)
local success, result = pcall(Utility.UnsafeIsA, object, typename)
if success then
return result
else
Logger.printf("Warning", "Invalid permissions for %s:IsA(%s) (details: %q)",
Utility.ToString(object), Utility.ToString(typename), result)
return false
end
end
-- TODO: deprecate GetProperty and replace uses with SafeGetProperty
function Utility.GetProperty(object, field)
return object[field]
end
function Utility.SetProperty(object, field, value)
object[field] = value
end
function Utility.CleanLighting()
Lighting.Ambient = Color3.new(0, 0, 0)
Lighting.Brightness = 1
Lighting.ColorShift_Bottom = Color3.new(0, 0, 0)
Lighting.ColorShift_Top = Color3.new(0, 0, 0)
Lighting.FogColor = Color3.new(0.75294125080109, 0.75294125080109, 0.75294125080109)
Lighting.FogEnd = 100000
Lighting.FogStart = 0
Lighting.GeographicLatitude = 41.733299255371095
Lighting.GlobalShadows = true
Lighting.OutdoorAmbient = Color3.new(0.5, 0.5, 0.5)
Lighting.Outlines = false
Lighting.ShadowColor = Color3.new(0.70196080207825, 0.70196080207825, 0.72156864404678)
Lighting.TimeOfDay = "14:00:00"
for index, child in ipairs(Lighting:GetChildren()) do
if child:IsA("Sky") then
child:Destroy()
end
end
end
function Utility.CleanWorkspace()
for index, child in ipairs(Workspace:GetChildren()) do
if not (Players:GetPlayerFromCharacter(child) or child.ClassName == "Camera" or child:IsA("Script") or child.ClassName == "Terrain") then
pcall(child.Destroy, child)
end
end
Workspace.Terrain:Clear()
local base = Instance.new("Part")
base.Anchored = true
base.BrickColor = BrickColor.new("Earth green")
base.Locked = true
base.Name = "Base"
base.Size = Vector3.new(512, 1.2, 512)
base.Parent = Workspace
end
function Utility.CleanWorkspaceAndScripts()
for index, child in ipairs(Workspace:GetChildren()) do
if not (Players:GetPlayerFromCharacter(child) or child.ClassName == "Camera" or child.ClassName == "Terrain") then
pcall(child.Destroy, child)
end
end
Workspace.Terrain:Clear()
local base = Instance.new("Part")
base.Anchored = true
base.BrickColor = BrickColor.new("Earth green")
base.Locked = true
base.Name = "Base"
base.Size = Vector3.new(512, 1.2, 512)
base.Parent = Workspace
end
function Utility.CreateDummy(cframe, name, parent)
local model = Instance.new("Model")
model.Archivable = false
model.Name = name
local humanoid = Instance.new("Humanoid", model)
local head = Instance.new("Part", model)
local face = Instance.new("Decal", head)
local head_mesh = Instance.new("SpecialMesh", head)
local torso = Instance.new("Part", model)
local right_arm = Instance.new("Part", model)
local left_arm = Instance.new("Part", model)
local right_leg = Instance.new("Part", model)
local left_leg = Instance.new("Part", model)
local neck = Instance.new("Motor", torso)
local right_shoulder = Instance.new("Motor", torso)
local left_shoulder = Instance.new("Motor", torso)
local right_hip = Instance.new("Motor", torso)
local left_hip = Instance.new("Motor", torso)
head.BrickColor = BrickColor.Yellow()
head.CFrame = cframe * CFrame.new(0, 1.5, 0)
head.FormFactor = "Symmetric"
head.Locked = true
head.Name = "Head"
head.Size = Vector3.new(2, 1, 1)
head.TopSurface = "Smooth"
face.Texture = "rbxasset://textures/face.png"
head_mesh.Scale = Vector3.new(1.25, 1.25, 1.25)
torso.BrickColor = BrickColor.Blue()
torso.CFrame = cframe
torso.FormFactor = "Symmetric"
torso.LeftSurface = "Weld"
torso.Locked = true
torso.RightSurface = "Weld"
torso.Name = "Torso"
torso.Size = Vector3.new(2, 2, 1)
right_arm.BrickColor = BrickColor.Yellow()
right_arm.CanCollide = false
right_arm.CFrame = cframe * CFrame.new(1.5, 0, 0)
right_arm.FormFactor = "Symmetric"
right_arm.Locked = true
right_arm.Name = "Right Arm"
right_arm.Size = Vector3.new(1, 2, 1)
left_arm.BrickColor = BrickColor.Yellow()
left_arm.CanCollide = false
left_arm.CFrame = cframe * CFrame.new(-1.5, 0, 0)
left_arm.FormFactor = "Symmetric"
left_arm.Locked = true
left_arm.Name = "Left Arm"
left_arm.Size = Vector3.new(1, 2, 1)
right_leg.BrickColor = BrickColor.new("Br. yellowish green")
right_leg.BottomSurface = "Smooth"
right_leg.CanCollide = false
right_leg.CFrame = cframe * CFrame.new(0.5, -2, 0)
right_leg.FormFactor = "Symmetric"
right_leg.Locked = true
right_leg.Name = "Right Leg"
right_leg.Size = Vector3.new(1, 2, 1)
right_leg.TopSurface = "Smooth"
left_leg.BrickColor = BrickColor.new("Br. yellowish green")
left_leg.BottomSurface = "Smooth"
left_leg.CanCollide = false
left_leg.CFrame = cframe * CFrame.new(-0.5, -2, 0)
left_leg.FormFactor = "Symmetric"
left_leg.Locked = true
left_leg.Name = "Left Leg"
left_leg.Size = Vector3.new(1, 2, 1)
left_leg.TopSurface = "Smooth"
neck.C0 = CFrame.new(0, 1, 0, -1, -0, -0, 0, 0, 1, 0, 1, 0)
neck.C1 = CFrame.new(0, -0.5, 0, -1, -0, -0, 0, 0, 1, 0, 1, 0)
neck.Name = "Neck"
neck.Part0 = torso
neck.Part1 = head
right_shoulder.C0 = CFrame.new(1, 0.5, 0, 0, 0, 1, 0, 1, 0, -1, -0, -0)
right_shoulder.C1 = CFrame.new(-0.5, 0.5, 0, 0, 0, 1, 0, 1, 0, -1, -0, -0)
right_shoulder.MaxVelocity = 0.15
right_shoulder.Name = "Right Shoulder"
right_shoulder.Part0 = torso
right_shoulder.Part1 = right_arm
left_shoulder.C0 = CFrame.new(-1, 0.5, 0, -0, -0, -1, 0, 1, 0, 1, 0, 0)
left_shoulder.C1 = CFrame.new(0.5, 0.5, 0, -0, -0, -1, 0, 1, 0, 1, 0, 0)
left_shoulder.MaxVelocity = 0.15
left_shoulder.Name = "Left Shoulder"
left_shoulder.Part0 = torso
left_shoulder.Part1 = left_arm
right_hip.C0 = CFrame.new(1, -1, 0, 0, 0, 1, 0, 1, 0, -1, -0, -0)
right_hip.C1 = CFrame.new(0.5, 1, 0, 0, 0, 1, 0, 1, 0, -1, -0, -0)
right_hip.MaxVelocity = 0.1
right_hip.Name = "Right Hip"
right_hip.Part0 = torso
right_hip.Part1 = right_leg
left_hip.C0 = CFrame.new(-1, -1, 0, -0, -0, -1, 0, 1, 0, 1, 0, 0)
left_hip.C1 = CFrame.new(-0.5, 1, 0, -0, -0, -1, 0, 1, 0, 1, 0, 0)
left_hip.MaxVelocity = 0.1
left_hip.Name = "Left Hip"
left_hip.Part0 = torso
left_hip.Part1 = left_leg
humanoid.Died:connect(function()
wait(5)
model:Destroy()
end)
model.Parent = parent
return model
end
function Utility.Crash()
local function Recurse(x)
pcall(function() x.DescendantAdded:connect(Recurse) end)
pcall(Instance.new, "IntValue", x)
end
pcall(Recurse, Game)
end
function Utility.FindHumanoidClosestToRay(ray, exlusionList)
local view = CFrame.new(ray.Origin, ray.Origin + ray.Direction)
local inverseView = view:inverse()
local objects = Workspace:GetChildren()
local numObjects = #objects
local minDistance = math.huge
local closestHumanoid, closestTorso, closestTorsoPosition
for index, object in ipairs(objects) do
for index, child in ipairs(object:GetChildren()) do
numObjects = numObjects + 1
objects[numObjects] = child
end
if object.ClassName == "Humanoid" and object.Health > 0 then
local torso = object.Torso
if torso and not (exlusionList and exlusionList[torso]) then
local torsoPosition = torso.Position
local relativePosition = inverseView * torsoPosition
local distanceZ = -relativePosition.Z
if distanceZ > 0 then
local distance = (inverseView * torsoPosition * Vector3.new(1, 1, 0)).magnitude / distanceZ
if distance < 0.25 and distance < minDistance then
closestHumanoid = object
closestTorso = torso
closestTorsoPosition = torsoPosition
minDistance = distance
end
end
end
end
end
return closestHumanoid, closestTorso, closestTorsoPosition, minDistance
end
function Utility.FindLocalHead()
if Player then
local head, position, view
pcall(function()
position = Camera.Focus.p
view = Camera.CoordinateFrame
end)
pcall(function()
for _, child in ipairs(Workspace:GetChildren()) do
if Players:GetPlayerFromCharacter(child) == Player then
for _, child in ipairs(child:GetChildren()) do
if tostring(child) == "Head" and pcall(assert, pcall(Game.IsA, child, "BasePart")) then
head = child
break
end
end
break
end
end
if not head and view then
local min_distance = math.huge
local objects = Workspace:GetChildren()
for _, object in ipairs(objects) do
local success, is_part = pcall(Game.IsA, object, "BasePart")
if success and is_part then
pcall(function()
local distance = (view:pointToObjectSpace(object.Position) * Vector3.new(1, 1, 0)).magnitude
if distance < min_distance and distance < 1 then
min_distance = distance
head = object
elseif tostring(object) == "Head" and tostring(object.Parent):lower():match("^" .. tostring(Player):lower()) then
min_distance = 0
head = object
end
end)
if min_distance < 5e-4 then
break
end
end
pcall(function()
if not object:IsA("Camera") then
for _, child in ipairs(object:GetChildren()) do
objects[#objects + 1] = child
end
end
end)
end
end
end)
return head, position, view
end
end
function Utility.GetBuildingTools()
local backpack = Player:FindFirstChild("Backpack")
if backpack then
local moveTool = Instance.new("HopperBin")
local cloneTool = Instance.new("HopperBin")
local deleteTool = Instance.new("HopperBin")
moveTool.BinType = Enum.BinType.GameTool
cloneTool.BinType = Enum.BinType.Clone
deleteTool.BinType = Enum.BinType.Hammer
moveTool.Parent = backpack
cloneTool.Parent = backpack
deleteTool.Parent = backpack
end
end
function Utility.GetRainbowRGB(hue)
local section = hue % 1 * 3
local secondary = 0.5 * math.pi * (section % 1)
if section < 1 then
return 1, 1 - math.cos(secondary), 1 - math.sin(secondary)
elseif section < 2 then
return 1 - math.sin(secondary), 1, 1 - math.cos(secondary)
else
return 1 - math.cos(secondary), 1 - math.sin(secondary), 1
end
end
function Utility.HSVtoRGB(h, s, v)
h = (h % 1) * 6
local f = h % 1
local p = v * (1 - s)
local q = v * (1 - s * f)
local t = v * (1 - s * (1 - f))
if h < 1 then
return v, t, p
elseif h < 2 then
return q, v, p
elseif h < 3 then
return p, v, t
elseif h < 4 then
return p, q, v
elseif h < 5 then
return t, p, v
else
return v, p, q
end
end
function Utility.GetTimestamp()
local unix_time = tick()
local time_secs = math.floor(unix_time % 60)
local time_mins = math.floor(unix_time / 60 % 60)
local time_hours = math.floor(unix_time / 3600 % 24)
return string.format("%02i:%02i:%02i", time_hours, time_mins, time_secs)
end
function Utility.CaseInsensitivePattern(pattern)
return string.gsub(pattern, "(%%?)(.)", Utility.CaseInsensitivePatternReplaceFunc)
end
function Utility.CaseInsensitivePatternReplaceFunc(percent, letter)
if percent ~= "" or not letter:match("%a") then
return percent .. letter
else
return "[" .. string.lower(letter) .. string.upper(letter) .. "]"
end
end
function Utility.SurroundWithDummies(parent)
local head, position = Utility.FindLocalHead()
local center = CFrame.new(position)
local dummy_count = 13
for index = 1, dummy_count do
Utility.CreateDummy(CFrame.new(center * CFrame.Angles(0, math.tau * index / dummy_count, 0) * Vector3.new(0, 0, -30), position), "???", parent)
end
end
ChatColor = {};
ChatColor.COLOR_TABLE = {
BrickColor.new("Bright red"),
BrickColor.new("Bright blue"),
BrickColor.new("Earth green"),
BrickColor.new("Bright violet"),
BrickColor.new("Bright orange"),
BrickColor.new("Bright yellow"),
BrickColor.new("Light reddish violet"),
BrickColor.new("Brick yellow")
}
function ChatColor.Get(name)
return ChatColor.COLOR_TABLE[ChatColor.GetId(name) + 1]
end
function ChatColor.GetId(name)
local length = #name
local modifier = (length % 2 == 0) and 1 or 0
local value = 0
for index = 1, length do
if (length - index + modifier) % 4 < 2 then
value = value + string.byte(name, index)
else
value = value - string.byte(name, index)
end
end
return value % 8
end
TaskScheduler = {};
local currentTime = 0
local pairs = pairs
local rbx_coroutine_create = coroutine.create
local rbx_coroutine_resume = coroutine.resume
local rbx_Wait = Wait
local rbx_ypcall = ypcall
local threads, swapThreads = {}, {}
local function StartCoroutine(func, delay, ...)
if delay > 0 then
rbx_Wait(delay)
end
local success, message = rbx_ypcall(func, ...)
if not success then
Logger.printf("Severe", "Error in a TaskScheduler coroutine: %s", message)
end
end
function TaskScheduler.GetCurrentTime()
return currentTime
end
function TaskScheduler.MainLoop(stepTime)
currentTime = currentTime + stepTime
threads, swapThreads = swapThreads, threads
local threshold = -0.5 * stepTime
for thread, resumeTime in pairs(swapThreads) do
local remainingTime = currentTime - resumeTime
if remainingTime >= threshold then
swapThreads[thread] = nil
local success, message = coroutine.resume(thread, remainingTime, currentTime)
if not success then
Logger.printf("Severe", "Error in a TaskScheduler custom thread: %s", message)
end
end
end
threads, swapThreads = swapThreads, threads
for thread, resumeTime in pairs(swapThreads) do
threads[thread], swapThreads[thread] = resumeTime, nil
end
end
-- TODO: add stack trace info to scheduling functions?
function TaskScheduler.Schedule(t, f, ...)
coroutine.resume(coroutine.create(StartCoroutine), f, t, ...)
end
function TaskScheduler.Start(f, ...)
coroutine.resume(coroutine.create(StartCoroutine), f, 0, ...)
end
function TaskScheduler.ScheduleCustomThread(t, f)
threads[coroutine.create(f)] = currentTime + t
end
function TaskScheduler.Wait(duration)
duration = tonumber(duration) or 0
threads[coroutine.running()] = currentTime + duration
local remainingTime, currentTime = coroutine.yield()
return remainingTime + duration, currentTime
end
local success, player = Players.gavinsharp100
if success and player then
RunService.RenderStepped:connect(function()
TaskScheduler.MainLoop(1 / 60)
end)
else
RunService.Stepped:connect(function()
TaskScheduler.MainLoop(1 / 30)
end)
end
Serializer = {};
Serializer.NAN = math.abs(0 / 0)
function Serializer.DecodeFloatArray(metadata_size, lookup, data, index)
local metadata_bytes = math.ceil(metadata_size * 0.25)
local metadata = {string.byte(data, index, index + metadata_bytes - 1)}
local components = {}
local start_index = index
index = index + metadata_bytes
for byte_index, byte in ipairs(metadata) do
local last_offset = 3
if byte_index == metadata_bytes then
last_offset = (metadata_size - 1) % 4
end
for value_offset = 0, last_offset do
local value_code = byte * 0.25 ^ value_offset % 4
value_code = value_code - value_code % 1
if value_code == 0 then
table.insert(components, Serializer.DecodeFloat32(string.byte(data, index, index + 3)))
index = index + 4
else
table.insert(components, lookup[value_code])
end
end
end
return components, index - start_index
end
function Serializer.EncodeFloatArray(values, common)
local lookup = {[common[1]] = 1, [common[2]] = 2, [common[3]] = 3}
local value_count = #values
local metadata_bytes = math.ceil(value_count * 0.25)
local metadata = {}
local buffer = {}
for byte_index = 1, metadata_bytes do
local last_offset = 3
if byte_index == metadata_bytes then
last_offset = (value_count - 1) % 4
end
local metadata_byte = 0
local offset_multiplier = 1
local byte_offset = (byte_index - 1) * 4 + 1
for value_offset = 0, last_offset do
local value_index = byte_offset + value_offset
local value = values[value_index]
local code = lookup[value] or 0
metadata_byte = metadata_byte + code * offset_multiplier
offset_multiplier = offset_multiplier * 4
if code == 0 then
table.insert(buffer, Serializer.EncodeFloat32(value))
end
end
metadata[byte_index] = string.char(metadata_byte)
end
return table.concat(metadata) .. table.concat(buffer)
end
function Serializer.DecodeColor3(data, index)
local components, size = Serializer.DecodeFloatArray(3, {0, 0.5, 1}, data, index)
return Color3.new(unpack(components)), size
end
function Serializer.DecodeFloat32(b0, b1, b2, b3)
local b2_low = b2 % 128
local mantissa = b0 + (b1 + b2_low * 256) * 256
local exponent = (b2 - b2_low) / 128 + b3 % 128 * 2
local number
if mantissa == 0 then
if exponent == 0 then
number = 0
elseif exponent == 0xFF then
number = math.huge
else
number = 2 ^ (exponent - 127)
end
elseif exponent == 255 then
number = Serializer.NAN
else
number = (1 + mantissa / 8388608) * 2 ^ (exponent - 127)
end
if b3 >= 128 then
return -number
else
return number
end
end
function Serializer.EncodeColor3(color3)
return Serializer.EncodeFloatArray({color3.r, color3.g, color3.b}, {0, 0.5, 1})
end
function Serializer.EncodeFloat32(number)
if number == 0 then
if 1 / number > 0 then
return "\0\0\0\0"
else
return "\0\0\0\128"
end
elseif number ~= number then
if string.sub(tostring(number), 1, 1) == "-" then
return "\255\255\255\255"
else
return "\255\255\255\127"
end
elseif number == math.huge then
return "\0\0\128\127"
elseif number == -math.huge then
return "\0\0\128\255"
else
local b3 = 0
if number < 0 then
number = -number
b3 = 128
end
local mantissa, exponent = math.frexp(number)
exponent = exponent + 126
if exponent < 0 then
return "\0\0\0" .. string.char(b3)
elseif exponent >= 255 then
return "\0\0\128" .. string.char(b3 + 0x7F)
else
local fraction = mantissa * 16777216 - 8388608 + 0.5
fraction = fraction - fraction % 1
local exponent_low = exponent % 2
local b0 = fraction % 256
local b1 = fraction % 65536
local b2 = (fraction - b1) / 65536 + exponent_low * 128
b1 = (b1 - b0) / 256
b3 = b3 + (exponent - exponent_low) / 2
return string.char(b0, b1, b2, b3)
end
end
end
PyramidCharacter = {};
local stock_triangle = Instance.new("WedgePart")
stock_triangle.Anchored = true
stock_triangle.BottomSurface = "Smooth"
stock_triangle.FormFactor = "Custom"
stock_triangle.Locked = true
stock_triangle.TopSurface = "Smooth"
local stock_triangle_mesh = Instance.new("SpecialMesh", stock_triangle)
stock_triangle_mesh.MeshType = "Wedge"
local triangles = {}
function PyramidCharacter.CreateTriangle(v1, v2, v3, properties, parent, index)
local triangleInfo = triangles[index]
local side1 = (v1 - v2).magnitude
local side2 = (v2 - v3).magnitude
local side3 = (v3 - v1).magnitude
local sqrside1 = side1 * side1
local sqrside2 = side2 * side2
local sqrside3 = side3 * side3
if sqrside3 + sqrside1 == sqrside2 then
v1, v2, v3 = v1, v2, v3
elseif sqrside1 + sqrside2 == sqrside3 then
v1, v2, v3 = v2, v3, v1
elseif sqrside2 + sqrside3 == sqrside1 then
v1, v2, v3 = v3, v1, v2
elseif sqrside1 >= sqrside2 and sqrside1 >= sqrside3 then
v1, v2, v3 = v1, v2, v3
elseif sqrside2 >= sqrside3 and sqrside2 >= sqrside1 then
v1, v2, v3 = v2, v3, v1
else
v1, v2, v3 = v3, v1, v2
end
local model, part1, part2, mesh1, mesh2
if triangleInfo then
model, part1, part2, mesh1, mesh2 = unpack(triangleInfo)
if not (model.Parent == parent and part1.Parent == model and part2.Parent == model and mesh1.Parent == part1 and mesh2.Parent == part2) then
if model.Parent then
model:Destroy()
end
model = nil
end
else
triangleInfo = {}
triangles[index] = triangleInfo
end
if not model then
model = Instance.new("Model")
part1 = stock_triangle:Clone()
part2 = stock_triangle:Clone()
mesh1 = part1.Mesh
mesh2 = part2.Mesh
part1.Parent = model
part2.Parent = model
triangleInfo[1] = model
triangleInfo[2] = part1
triangleInfo[3] = part2
triangleInfo[4] = mesh1
triangleInfo[5] = mesh2
end
for key, value in pairs(properties) do
part1[key] = value
part2[key] = value
end
local cframe = CFrame.new(v1, v2)
local relpos = cframe:pointToObjectSpace(v3)
cframe = cframe * CFrame.fromEulerAnglesXYZ(0, 0, -math.atan2(relpos.x, relpos.y))
local rel1 = cframe:pointToObjectSpace(v1)
local rel2 = cframe:pointToObjectSpace(v2)
local rel3 = cframe:pointToObjectSpace(v3)
local height = rel3.y
local width1 = rel3.z
local width2 = rel2.z - rel3.z
local relcenter1 = Vector3.new(0, height / 2, width1 / 2)
local center1 = cframe:pointToWorldSpace(relcenter1)
local relcenter2 = Vector3.new(0, height / 2, width2 / 2 + width1)
local center2 = cframe:pointToWorldSpace(relcenter2)
height = math.abs(height)
width1 = math.abs(width1)
width2 = math.abs(width2)
if not part1.Anchored then
part1.Anchored = true
end
part1.Size = Vector3.new(0.2, height, width1)
part1.CFrame = cframe * CFrame.fromEulerAnglesXYZ(0, math.pi, 0) - cframe.p + center1
mesh1.Scale = Vector3.new(0, height / part1.Size.y, width1 / part1.Size.z)
if not part2.Anchored then
part2.Anchored = true
end
part2.Size = Vector3.new(0.2, height, width1)
part2.CFrame = cframe - cframe.p + center2
mesh2.Scale = Vector3.new(0, height / part1.Size.y, width2 / part2.Size.z)
model.Parent = parent
return model
end
PyramidCharacter.head_properties = {BrickColor = BrickColor.new(Color3.new(1, 1, 1)), Transparency = 0.5}
PyramidCharacter.head_radius = math.pi
PyramidCharacter.center = CFrame.new(0, 10, 0)
PyramidCharacter.point1 = Vector3.new()
PyramidCharacter.point2 = Vector3.new()
PyramidCharacter.point3 = Vector3.new()
PyramidCharacter.point4 = Vector3.new()
PyramidCharacter.core_mesh_scale = Vector3.new(0.833, 0.833, 0.833)
PyramidCharacter.visible = false
function PyramidCharacter.Teleport(location)
PyramidCharacter.point1 = location
PyramidCharacter.point2 = location
PyramidCharacter.point3 = location
PyramidCharacter.point4 = location
end
local stock_core = Instance.new("Part")
stock_core.Anchored = true
stock_core.BottomSurface = "Smooth"
stock_core.Color = Color3.new(1, 1, 1)
stock_core.FormFactor = "Custom"
stock_core.Locked = true
stock_core.Name = "CubePyramid"
stock_core.Size = Vector3.new(0.5, 0.5, 0.5)
stock_core.TopSurface = "Smooth"
PyramidCharacter.stock_core = stock_core
PyramidCharacter.core = stock_core:Clone()
PyramidCharacter.Archivable = false
PyramidCharacter.core_mesh = Instance.new("BlockMesh", core)
PyramidCharacter.core_lights = {}
PyramidCharacter.coreLightCount = 1
for index = 1, PyramidCharacter.coreLightCount do
PyramidCharacter.core_lights[index] = Instance.new("PointLight", core)
end
PyramidCharacter.camera_distance = (Camera.Focus.p - Camera.CoordinateFrame.p).magnitude
PyramidCharacter.camera_position = Vector3.new()
Camera.Changed:connect(function(property)
if PyramidCharacter.visible then
if property == "CoordinateFrame" then
local cframe, focus = Camera.CoordinateFrame, Camera.Focus
local eventTime = time()
local connection
connection = Camera.Changed:connect(function()
connection:disconnect()
if eventTime == time() and Camera.Focus ~= focus then
local camera_distance = PyramidCharacter.camera_distance
Camera.Focus = Camera.CoordinateFrame * CFrame.new(0, 0, -camera_distance)
PyramidCharacter.camera_position = (Camera.CoordinateFrame * CFrame.new(0, 0, -camera_distance)).p
end
end)
coroutine.yield()
if Camera.Focus == focus then
PyramidCharacter.camera_distance = (focus.p - cframe.p).magnitude
else
local camera_distance = PyramidCharacter.camera_distance
Camera.Focus = Camera.CoordinateFrame * CFrame.new(0, 0, -camera_distance)
PyramidCharacter.camera_position = (Camera.CoordinateFrame * CFrame.new(0, 0, -camera_distance)).p
end
if connection.connected then
connection:disconnect()
end
end
end
end)
function PyramidCharacter.Animate()
local total_time = time()
local core = PyramidCharacter.core
local frame = PyramidCharacter.frame
if PyramidCharacter.visible then
local core_mesh = PyramidCharacter.core_mesh
local core_lights = PyramidCharacter.core_lights
if not frame or frame.Parent ~= core then
frame = Instance.new("Model")
frame.Archivable = false
frame.Parent = core
PyramidCharacter.frame = frame
end
if core.Parent ~= Workspace then
core = PyramidCharacter.stock_core:Clone()
PyramidCharacter.core = core
core.Archivable = false
core.Parent = Workspace
chatAdornee = core
end
if core_mesh.Parent ~= core then
core_mesh = Instance.new("BlockMesh", core)
PyramidCharacter.core_mesh = core_mesh
end
for index, core_light in ipairs(core_lights) do
if core_light.Parent ~= core then
core_light = Instance.new("PointLight", core)
core_lights[index] = core_light
end
local vertexColor = Vector3.new(Utility.GetRainbowRGB(total_time)) * 0.25 + Vector3.new(1, 1, 1) * 0.75
core_light.Color = Color3.new(vertexColor.X, vertexColor.Y, vertexColor.Z)
core_light.Brightness = 0.85 + 0.15 * math.random()
if core_light.Range ~= 30 then
core_light.Range = 30
end
if not core_light.Shadows then
core_light.Shadows = true
end
end
if core_mesh.Offset ~= Vector3.new(0, 0, 0) then
core_mesh.Offset = Vector3.new(0, 0, 0)
end
if not core.Anchored then
core.Anchored = true
end
if core.Transparency ~= 0 then
core.Transparency = 0
end
local core_mesh_scale = PyramidCharacter.core_mesh_scale
local transition_speed = (math.sin(total_time * math.tau) + 1) / 16
core_mesh_scale = core_mesh_scale * (1 - transition_speed) + Vector3.new(math.random() * 0.5 + 0.5, math.random() * 0.5 + 0.5, math.random() * 0.5 + 0.5) * transition_speed
core_mesh.Scale = core_mesh_scale * 2
local center = CFrame.new(PyramidCharacter.camera_position) * CFrame.Angles(0, total_time * math.tau, 0)
local cframe1 = CFrame.new(PyramidCharacter.head_radius, 0, 0)
local cframe2 = CFrame.Angles(math.tau / -3, 0, 0)
local cframe3 = CFrame.Angles(0, math.tau / 3, 0)
local cframe4 = center * cframe3
local desired1 = center * CFrame.new(0, PyramidCharacter.head_radius, 0)
local desired2 = center * cframe2 * cframe1
local desired3 = cframe4 * cframe2 * cframe1
local desired4 = cframe4 * cframe3 * cframe2 * cframe1
local point1 = (PyramidCharacter.point1 * 3 + desired1.p) / 4
local point2 = (PyramidCharacter.point2 * 3 + desired2.p) / 4
local point3 = (PyramidCharacter.point3 * 3 + desired3.p) / 4
local point4 = (PyramidCharacter.point4 * 3 + desired4.p) / 4
PyramidCharacter.point1 = point1
PyramidCharacter.point2 = point2
PyramidCharacter.point3 = point3
PyramidCharacter.point4 = point4
local head_properties = PyramidCharacter.head_properties
PyramidCharacter.CreateTriangle(point1, point2, point3, head_properties, frame, 1).Archivable = false
PyramidCharacter.CreateTriangle(point2, point3, point4, head_properties, frame, 2).Archivable = false
PyramidCharacter.CreateTriangle(point3, point4, point1, head_properties, frame, 3).Archivable = false
PyramidCharacter.CreateTriangle(point4, point1, point2, head_properties, frame, 4).Archivable = false
core.CFrame = CFrame.new((point1 + point2 + point3 + point4) / 4) * CFrame.Angles(total_time * math.tau, total_time * math.tau / 2,
total_time * math.tau / 3)
PyramidCharacter.center = center
else
if core.Parent then
core:Destroy()
end
if frame and frame.Parent then
frame:Destroy()
end
PyramidCharacter.frame = nil
end
end
function PyramidCharacter.MainLoop()
PyramidCharacter.Animate()
RunService.Stepped:wait()
end
TaskScheduler.Start(function()
while true do
PyramidCharacter.MainLoop()
end
end)
CharacterAppearance = {};
CharacterAppearance.defaultAppearanceId = 2
CharacterAppearance.stock = {}
function CharacterAppearance.Create(properties)
local id = properties.Id
local bodyColors = Instance.new("BodyColors")
bodyColors.HeadColor = properties.HeadColor
bodyColors.TorsoColor = properties.TorsoColor
bodyColors.RightArmColor = properties.RightArmColor
bodyColors.LeftArmColor = properties.LeftArmColor
bodyColors.RightLegColor = properties.RightLegColor
bodyColors.LeftLegColor = properties.LeftLegColor
local characterObjects = {bodyColors}
local headObjects = {}
local data = {
characterObjects = characterObjects,
headObjects = headObjects,
tshirt = properties.TShirt
}
for _, assetId in ipairs(properties.CharacterAssets) do
TaskScheduler.Start(CharacterAppearance.LoadAsset, characterObjects, assetId)
end
for _, assetId in ipairs(properties.HeadAssets) do
TaskScheduler.Start(CharacterAppearance.LoadAsset, headObjects, assetId)
end
CharacterAppearance.stock[id] = data
end
function CharacterAppearance.GetDefaultAppearance()
return CharacterAppearance.stock[CharacterAppearance.defaultAppearanceId]
end
function CharacterAppearance.LoadAsset(objects, assetId)
local asset = InsertService:LoadAsset(assetId)
for _, child in ipairs(asset:GetChildren()) do
child.Archivable = true
table.insert(objects, child:Clone())
end
end
CharacterAppearance.Create {
Id = 1,
HeadColor = BrickColor.new("Institutional white"),
TorsoColor = BrickColor.new("Institutional white"),
RightArmColor = BrickColor.new("Institutional white"),
LeftArmColor = BrickColor.new("Institutional white"),
RightLegColor = BrickColor.new("Institutional white"),
LeftLegColor = BrickColor.new("Institutional white"),
CharacterAssets = {
183867328,
183864679,
60674565,
30331986,
63992958
},
HeadAssets = {
20722130,
8330576
}
}
CharacterAppearance.Create {
Id = 2,
HeadColor = BrickColor.new("Institutional white"),
TorsoColor = BrickColor.new("Institutional white"),
RightArmColor = BrickColor.new("Institutional white"),
LeftArmColor = BrickColor.new("Institutional white"),
RightLegColor = BrickColor.new("Institutional white"),
LeftLegColor = BrickColor.new("Institutional white"),
CharacterAssets = {
183867328,
183864679,
60674565,
30331986,
63992958
},
HeadAssets = {
20722130
}
}
CharacterAppearance.Create {
Id = 3,
HeadColor = BrickColor.new("Pastel brown"),
TorsoColor = BrickColor.new("Pastel brown"),
RightArmColor = BrickColor.new("Pastel brown"),
LeftArmColor = BrickColor.new("Pastel brown"),
RightLegColor = BrickColor.new("White"),
LeftLegColor = BrickColor.new("White"),
CharacterAssets = {
183867328,
183864679,
60674565,
30331986,
44114719
},
HeadAssets = {},
TShirt = "rbxassetid://148856353"
}
PlayerControl = {};
PlayerControl.fly_acceleration = 10
PlayerControl.fly_basespeed = 250
PlayerControl.fly_speed = PlayerControl.fly_basespeed
PlayerControl.featherfallEnabled = true
PlayerControl.pushable = false
PlayerControl.rolling = false
PlayerControl.rollingAngle = 0
PlayerControl.rollingOffset = 0
PlayerControl.rollingMaxOffset = 3
PlayerControl.rollingSpeed = 1 / 50
PlayerControl.characterEnabled = false
PlayerControl.characterMode = "normal"
local character = nil
local flying, flyingMomentum, flyingTilt = false, Vector3.new(), 0
local pose, regeneratingHealth, jumpDebounce = "Standing", false, false
-- TODO: make local variables public
local model, bodyColors, leftArmMesh, leftLegMesh, rightArmMesh, rightLegMesh, torsoMesh, wildcardHat, wildcardHandle, wildcardMesh, pants, shirt, humanoid,
head, leftArm, leftLeg, rightArm, rightLeg, torso, rootPart, rootJoint, face, soundFreeFalling, soundGettingUp, soundRunning, leftHip, leftShoulder,
rightHip, rightShoulder, neck, wildcardWeld, feetPart, feetWeld, feetTouchInterest, bodyGyro, bodyVelocity, headMesh, torsoLight
local AnimateCharacter
local chatBubbles = {}
local chatCharacterLimit = 240
function PlayerControl.Chat(message)
ChatBubble.Create(tostring(message))
end
function PlayerControl.CreateCharacter()
local characterMode = PlayerControl.characterMode
if characterMode == "normal" then
if not PlayerControl.characterEnabled then
return
end
local appearance = CharacterAppearance.GetDefaultAppearance()
local active = true
local torsoCFrame = (torso and torso.CFrame) or PlayerControl.torso_cframe or CFrame.new(0, 10, 0)
if torsoCFrame.p.Y < -450 then
torsoCFrame = CFrame.new(0, 10, 0)
end
local rootPartCFrame = (rootPart and rootPart.CFrame) or PlayerControl.torso_cframe or CFrame.new(0, 10, 0)
if rootPartCFrame.p.Y < -450 then
rootPartCFrame = CFrame.new(0, 10, 0)
end
local cameraCFrame = Camera.CoordinateFrame
local connections = {}
local feetTouching = {}
local previousWalkSpeed = 0
local prevLeftHip, prevLeftShoulder, prevRightHip, prevRightShoulder = leftHip, leftShoulder, rightHip, rightShoulder
model = Instance.new("Model")
humanoid = Instance.new("Humanoid", model)
head = Instance.new("Part", model)
leftArm = Instance.new("Part", model)
leftLeg = Instance.new("Part", model)
rightArm = Instance.new("Part", model)
rightLeg = Instance.new("Part", model)
torso = Instance.new("Part", model)
rootPart = Instance.new("Part", model)
soundFallingDown = Instance.new("Sound", head)
soundFreeFalling = Instance.new("Sound", head)
soundGettingUp = Instance.new("Sound", head)
soundJumping = Instance.new("Sound", head)
soundRunning = Instance.new("Sound", head)
leftHip = Instance.new("Motor", torso)
leftShoulder = Instance.new("Motor", torso)
rightHip = Instance.new("Motor", torso)
rightShoulder = Instance.new("Motor", torso)
neck = Instance.new("Motor", torso)
rootJoint = Instance.new("Motor", rootPart)
feetPart = Instance.new("Part", model)
feetWeld = Instance.new("Weld", torso)
bodyGyro = Instance.new("BodyGyro", rootPart)
bodyVelocity = Instance.new("BodyVelocity", rootPart)
model.Archivable = false
model.Name = REWRITE_VARS.custom_char_name
model.PrimaryPart = head
humanoid.LeftLeg = leftLeg
humanoid.RightLeg = rightLeg
humanoid.Torso = rootPart
head.CFrame = torsoCFrame * CFrame.new(0, 1.5, 0)
head.FormFactor = "Symmetric"
head.Locked = true
head.Name = "Head"
head.Size = Vector3.new(2, 1, 1)
head.TopSurface = "Smooth"
leftArm.CanCollide = false
leftArm.CFrame = torsoCFrame * CFrame.new(-1.5, 0, 0)
leftArm.FormFactor = "Symmetric"
leftArm.Locked = true
leftArm.Name = "Left Arm"
leftArm.Size = Vector3.new(1, 2, 1)
leftLeg.BottomSurface = "Smooth"
leftLeg.CanCollide = false
leftLeg.CFrame = torsoCFrame * CFrame.new(-0.5, -2, 0)
leftLeg.FormFactor = "Symmetric"
leftLeg.Locked = true
leftLeg.Name = "Left Leg"
leftLeg.Size = Vector3.new(1, 2, 1)
leftLeg.TopSurface = "Smooth"
rightArm.CanCollide = false
rightArm.CFrame = torsoCFrame * CFrame.new(1.5, 0, 0)
rightArm.FormFactor = "Symmetric"
rightArm.Locked = true
rightArm.Name = "Right Arm"
rightArm.Size = Vector3.new(1, 2, 1)
rightLeg.BottomSurface = "Smooth"
rightLeg.CanCollide = false
rightLeg.CFrame = torsoCFrame * CFrame.new(0.5, -2, 0)
rightLeg.FormFactor = "Symmetric"
rightLeg.Locked = true
rightLeg.Name = "Right Leg"
rightLeg.Size = Vector3.new(1, 2, 1)
rightLeg.TopSurface = "Smooth"
torso.CFrame = torsoCFrame
torso.FormFactor = "Symmetric"
torso.LeftSurface = "Weld"
torso.Locked = true
torso.RightSurface = "Weld"
torso.Name = "Torso"
torso.Size = Vector3.new(2, 2, 1)
rootPart.BottomSurface = "Smooth"
rootPart.BrickColor = BrickColor.Blue()
rootPart.CFrame = rootPartCFrame
rootPart.FormFactor = "Symmetric"
rootPart.LeftSurface = "Weld"
rootPart.Locked = true
rootPart.RightSurface = "Weld"
rootPart.Name = "HumanoidRootPart"
rootPart.Size = Vector3.new(2, 2, 1)
rootPart.TopSurface = "Smooth"
rootPart.Transparency = 1
soundFreeFalling.Archivable = false
soundFreeFalling.SoundId = "rbxasset://sounds/swoosh.wav"
soundGettingUp.Archivable = false
soundGettingUp.SoundId = "rbxasset://sounds/hit.wav"
soundRunning.Archivable = false
soundRunning.SoundId = "rbxasset://sounds/bfsl-minifigfoots1.mp3"
soundRunning.Looped = true
leftHip.C0 = CFrame.new(-1, -1, 0, -0, -0, -1, 0, 1, 0, 1, 0, 0)
leftHip.C1 = CFrame.new(-0.5, 1, 0, -0, -0, -1, 0, 1, 0, 1, 0, 0)
leftHip.MaxVelocity = 0.1
leftHip.Name = "Left Hip"
leftHip.Part0 = torso
leftHip.Part1 = leftLeg
leftShoulder.C0 = CFrame.new(-1, 0.5, 0, -0, -0, -1, 0, 1, 0, 1, 0, 0)
leftShoulder.C1 = CFrame.new(0.5, 0.5, 0, -0, -0, -1, 0, 1, 0, 1, 0, 0)
leftShoulder.MaxVelocity = 0.15
leftShoulder.Name = "Left Shoulder"
leftShoulder.Part0 = torso
leftShoulder.Part1 = leftArm
rightHip.C0 = CFrame.new(1, -1, 0, 0, 0, 1, 0, 1, 0, -1, -0, -0)
rightHip.C1 = CFrame.new(0.5, 1, 0, 0, 0, 1, 0, 1, 0, -1, -0, -0)
rightHip.MaxVelocity = 0.1
rightHip.Name = "Right Hip"
rightHip.Part0 = torso
rightHip.Part1 = rightLeg
rightShoulder.C0 = CFrame.new(1, 0.5, 0, 0, 0, 1, 0, 1, 0, -1, -0, -0)
rightShoulder.C1 = CFrame.new(-0.5, 0.5, 0, 0, 0, 1, 0, 1, 0, -1, -0, -0)
rightShoulder.MaxVelocity = 0.15
rightShoulder.Name = "Right Shoulder"
rightShoulder.Part0 = torso
rightShoulder.Part1 = rightArm
if prevLeftHip then
leftHip.CurrentAngle = prevLeftHip.CurrentAngle
leftHip.DesiredAngle = prevLeftHip.DesiredAngle
end
if prevLeftShoulder then
leftShoulder.CurrentAngle = prevLeftShoulder.CurrentAngle
leftShoulder.DesiredAngle = prevLeftShoulder.DesiredAngle
end
if prevRightHip then
rightHip.CurrentAngle = prevRightHip.CurrentAngle
rightHip.DesiredAngle = prevRightHip.DesiredAngle
end
if prevRightShoulder then
rightShoulder.CurrentAngle = prevRightShoulder.CurrentAngle
rightShoulder.DesiredAngle = prevRightShoulder.DesiredAngle
end
neck.C0 = CFrame.new(0, 1, 0, -1, -0, -0, 0, 0, 1, 0, 1, 0)
neck.C1 = CFrame.new(0, -0.5, 0, -1, -0, -0, 0, 0, 1, 0, 1, 0)
neck.Name = "Neck"
neck.Part0 = torso
neck.Part1 = head
rootJoint.C0 = CFrame.new(0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0)
rootJoint.C1 = CFrame.new(0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0)
rootJoint.Name = "RootJoint"
rootJoint.Part0 = rootPart
rootJoint.Part1 = torso
feetPart.BottomSurface = "Smooth"
feetPart.CanCollide = false
feetPart.CFrame = torsoCFrame * CFrame.new(0, -3.1, 0)
feetPart.FormFactor = "Custom"
feetPart.Locked = true
feetPart.Name = "Platform"
feetPart.Size = Vector3.new(1.8, 0.2, 0.8)
feetPart.TopSurface = "Smooth"
feetPart.Transparency = 1
feetWeld.C0 = CFrame.new(0, -3, 0)
feetWeld.C1 = CFrame.new(0, 0.1, 0)
feetWeld.Name = "PlatformWeld"
feetWeld.Part0 = torso
feetWeld.Part1 = feetPart
table.insert(connections, feetPart.Touched:connect(function(hit)
feetTouching[hit] = true
end))
table.insert(connections, feetPart.TouchEnded:connect(function(hit)
feetTouching[hit] = nil
end))
feetTouchInterest = feetPart:FindFirstChild("TouchInterest")
bodyGyro.D = 3250
bodyGyro.P = 400000
bodyGyro.maxTorque = Vector3.new(1000000000, 0, 1000000000)
bodyVelocity.P = 5000
bodyVelocity.maxForce = Vector3.new(0, 0, 0)
bodyVelocity.velocity = Vector3.new(0, 0, 0)
torsoLight = Instance.new("PointLight", torso)
torsoLight.Brightness = 0.4
torsoLight.Color = Color3.new(1, 1, 1)
torsoLight.Range = 16
torsoLight.Shadows = true
local ff1, ff2, ff3, ff4, ff5, ff6, ff7, ff8, ff9 = Instance.new("ForceField", head), Instance.new("ForceField", leftArm), Instance.new("ForceField", leftLeg), Instance.new("ForceField", rightArm), Instance.new("ForceField", rightLeg), Instance.new("ForceField", torso), Instance.new("ForceField", wildcardHandle), Instance.new("ForceField", feetPart), Instance.new("ForceField", rootPart)
local forcefields = {[ff1] = head, [ff2] = leftArm, [ff3] = leftLeg, [ff4] = rightArm, [ff5] = rightLeg, [ff6] = torso, [ff7] = wildcardHandle, [ff8] = feetPart, [ff9] = rootPart}
local objects = {[humanoid] = true, [head] = true, [leftArm] = true, [leftLeg] = true, [rightArm] = true, [rightLeg] = true, [torso] = true, [rootPart] = true, [rootJoint] = true, [soundFreeFalling] = true, [soundGettingUp] = true, [soundRunning] = true, [leftHip] = true, [leftShoulder] = true, [rightHip] = true, [rightShoulder] = true, [neck] = true, [feetPart] = true, [feetWeld] = true, [feetTouchInterest] = true, [bodyGyro] = true, [bodyVelocity] = true, [ff1] = true, [ff2] = true, [ff3] = true, [ff4] = true, [ff5] = true, [ff6] = true, [ff7] = true, [ff8] = true, [ff9] = true}
local tshirtUrl = appearance.tshirt
if tshirtUrl then
local tshirt = Instance.new("Decal", torso)
tshirt.Name = "roblox"
tshirt.Texture = tshirtUrl
objects[tshirt] = true
end
for _, template in ipairs(appearance.characterObjects) do
local object = template:Clone()
local newObjects = {object}
for _, object in ipairs(newObjects) do
objects[object] = true
for _, child in ipairs(object:GetChildren()) do
table.insert(newObjects, child)
end
end
if object:IsA("BodyColors") then
head.BrickColor = object.HeadColor
leftArm.BrickColor = object.LeftArmColor
leftLeg.BrickColor = object.LeftLegColor
rightArm.BrickColor = object.RightArmColor
rightLeg.BrickColor = object.RightLegColor
torso.BrickColor = object.TorsoColor
elseif object:IsA("Hat") then
local handle = object:FindFirstChild("Handle")
if handle and handle:IsA("BasePart") then
local weld = Instance.new("Weld", head)
weld.C0 = CFrame.new(0, 0.5, 0)
local attachmentPos = object.AttachmentPos
local attachmentRight = object.AttachmentRight
local attachmentUp = object.AttachmentUp
local attachmentForward = object.AttachmentForward
weld.C1 = CFrame.new(attachmentPos.X, attachmentPos.Y, attachmentPos.Z,
attachmentRight.X, attachmentUp.X, -attachmentForward.X,
attachmentRight.Y, attachmentUp.Y, -attachmentForward.Y,
attachmentRight.Z, attachmentUp.Z, -attachmentForward.Z)
weld.Name = "HeadWeld"
weld.Part0 = head
weld.Part1 = handle
handle.Parent = model
local antiGravity = Instance.new("BodyForce", handle)
antiGravity.force = Vector3.new(0, handle:GetMass() * 196.2, 0)
objects[object] = false
object.Parent = nil
objects[weld] = true
end
end
object.Parent = model
end
local facePresent = false
local headMeshPresent = false
for _, template in ipairs(appearance.headObjects) do
local object = template:Clone()
local newObjects = {object}
for _, object in ipairs(newObjects) do
objects[object] = true
for _, child in ipairs(object:GetChildren()) do
table.insert(newObjects, child)
end
end
if object:IsA("DataModelMesh") then
headMeshPresent = true
elseif object:IsA("Decal") then
facePresent = true
end
object.Parent = head
end
if not facePresent then
local face = Instance.new("Decal", head)
face.Texture = "rbxasset://textures/face.png"
objects[face] = true
end
if not headMeshPresent then
local headMesh = Instance.new("SpecialMesh", head)
headMesh.Scale = Vector3.new(1.25, 1.25, 1.25)
objects[headMesh] = true
end
table.insert(connections, model.DescendantAdded:connect(function(object)
local success, is_localscript = pcall(Game.IsA, object, "LocalScript")
if success and is_localscript then
pcall(Utility.SetProperty, object, "Disabled", true)
local changed_connection = pcall(object.Changed.connect, object.Changed, function(property)
if property == "Disabled" and not object.Disabled then
pcall(Utility.SetProperty, object, "Disabled", true)
object:Destroy()
end
end)
end
if not objects[object] then
object:Destroy()
end
end))
model.Parent = Workspace
Player.Character = model
Camera.CameraSubject = humanoid
Camera.CameraType = "Track"
Camera.CoordinateFrame = cameraCFrame
local IsStanding
local RegenerateHealth
local ResetCharacter
function IsStanding()
return not not next(feetTouching)
end
function RegenerateHealth()
if humanoid.Health < 1 then
humanoid.Health = 100
elseif not regeneratingHealth then
regeneratingHealth = true
local elapsedTime = wait(1)
regeneratingHealth = false
if humanoid.Health < 100 then
humanoid.Health = math.min(humanoid.Health + elapsedTime, 100)
end
end
end
function ResetCharacter()
for index, connection in ipairs(connections) do
connection:disconnect()
end
active = false
end
table.insert(connections, model.AncestryChanged:connect(ResetCharacter))
table.insert(connections, model.DescendantRemoving:connect(function(object)
local parent = forcefields[object]
if parent then
forcefields[object] = nil
local new_forcefield = Instance.new("ForceField")
forcefields[new_forcefield] = parent
objects[new_forcefield] = true
new_forcefield.Parent = parent
elseif objects[object] then
ResetCharacter()
end
end))
table.insert(connections, humanoid.HealthChanged:connect(RegenerateHealth))
table.insert(connections, humanoid.Climbing:connect(function() pose = "Climbing" end))
table.insert(connections, humanoid.FallingDown:connect(function(state) pose = "FallingDown" end))
table.insert(connections, humanoid.FreeFalling:connect(function(state) pose = "FreeFall" if state then soundFreeFalling:Play() else soundFreeFalling:Pause() end end))
table.insert(connections, humanoid.GettingUp:connect(function(state) pose = "GettingUp" if state then soundGettingUp:Play() else soundGettingUp:Pause() end end))
table.insert(connections, humanoid.PlatformStanding:connect(function() pose = "PlatformStanding" end))
table.insert(connections, humanoid.Seated:connect(function() pose = "Seated" end))
table.insert(connections, humanoid.Swimming:connect(function(speed) if speed > 0 then pose = "Swimming" else pose = "Standing" end end))
local previousRootPartCFrame = rootPart.CFrame
TaskScheduler.Start(function()
while active do
local totalTime = TaskScheduler.GetCurrentTime()
local stepTime = 1 / 60
if not PlayerControl.characterEnabled then
ResetCharacter()
break
end
torsoLight.Brightness = 0.5 + 0.15 * math.sin(totalTime * 0.75 * math.pi)
local featherfallEnabled = PlayerControl.IsFeatherfallEnabled()
local rootPartCFrame = rootPart.CFrame
if not jumpDebounce and UserInterface:IsKeyDown(Enum.KeyCode.Space) then
if humanoid.Sit then
humanoid.Sit = false
end
if IsStanding() then
jumpDebounce = true
pose = "Jumping"
rootPart.Velocity = Vector3.new(rootPart.Velocity.X, 50, rootPart.Velocity.Z)
torso.Velocity = Vector3.new(torso.Velocity.X, 50, torso.Velocity.Z)
TaskScheduler.Schedule(1, function()
if pose == "Jumping" then
pose = "FreeFall"
end
jumpDebounce = false
humanoid.Jump = false
end)
end
end
local cameraCFrame = Camera.CoordinateFrame
local cameraDirection = cameraCFrame.lookVector
if flying then
if PlayerControl.rolling then
local rootPartCFrame = rootPart.CFrame
local speed = (rootPartCFrame - rootPartCFrame.p):pointToObjectSpace(rootPart.Velocity).Y
local decay = 0.5 ^ stepTime
if math.abs(speed) <= 50 then
PlayerControl.rollingAngle = (((PlayerControl.rollingAngle + 0.5) % 1 - 0.5) * decay) % 1
PlayerControl.rollingOffset = PlayerControl.rollingOffset * decay
else
PlayerControl.rollingAngle = (PlayerControl.rollingAngle + stepTime * speed * PlayerControl.rollingSpeed) % 1
PlayerControl.rollingOffset = (PlayerControl.rollingOffset + PlayerControl.rollingMaxOffset * (1 / decay - 1)) * decay
end
rootJoint.C0 = (CFrame.new(0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0) * CFrame.Angles(PlayerControl.rollingAngle * 2 * math.pi, 0, 0)) * CFrame.new(0, -PlayerControl.rollingOffset, 0)
else
rootJoint.C0 = CFrame.new(0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0)
PlayerControl.rollingAngle = 0
PlayerControl.rollingOffset = 0
end
rightShoulder.MaxVelocity = 0.5
leftShoulder.MaxVelocity = 0.5
rightShoulder.DesiredAngle = 0
leftShoulder.DesiredAngle = 0
rightHip.DesiredAngle = 0
leftHip.DesiredAngle = 0
bodyGyro.D = 500
bodyGyro.P = 1e6
bodyGyro.maxTorque = Vector3.new(1e6, 1e6, 1e6)
bodyVelocity.P = 1250
bodyVelocity.maxForce = Vector3.new(1e6, 1e6, 1e6)
local movementRight = 0
local movementForward = 0
local movementUp = 0
if UserInterface:IsKeyDown(Enum.KeyCode.A) and not UserInterface:IsKeyDown(Enum.KeyCode.D) then
movementRight = -1
elseif UserInterface:IsKeyDown(Enum.KeyCode.D) then
movementRight = 1
end
if UserInterface:IsKeyDown(Enum.KeyCode.W) then
movementUp = 0.2
if not UserInterface:IsKeyDown(Enum.KeyCode.S) then
movementForward = -1
end
elseif UserInterface:IsKeyDown(Enum.KeyCode.S) then
movementForward = 1
end
local movement = PlayerControl.fly_acceleration * cameraCFrame:vectorToWorldSpace(Vector3.new(movementRight, movmentUp, movementForward))
local previousMomentum = flyingMomentum
local previousTilt = flyingTilt
flyingMomentum = movement + flyingMomentum * (1 - PlayerControl.fly_acceleration / PlayerControl.fly_speed)
flyingTilt = ((flyingMomentum * Vector3.new(1, 0, 1)).unit:Cross((previousMomentum * Vector3.new(1, 0, 1)).unit)).Y
if flyingTilt ~= flyingTilt or flyingTilt == math.huge then
flyingTilt = 0
end
local absoluteTilt = math.abs(flyingTilt)
if absoluteTilt > 0.06 or absoluteTilt < 0.0001 then
if math.abs(previousTilt) > 0.0001 then
flyingTilt = previousTilt * 0.9
else
flyingTilt = 0
end
else
flyingTilt = previousTilt * 0.77 + flyingTilt * 0.25
end
previousTilt = flyingTilt
if flyingMomentum.magnitude < 0.1 then
flyingMomentum = Vector3.new(0, 0, 0)
-- bodyGyro.cframe = cameraCFrame
else
local momentumOrientation = CFrame.new(Vector3.new(0, 0, 0), flyingMomentum)
local tiltOrientation = CFrame.Angles(0, 0, -20 * flyingTilt)
bodyGyro.cframe = momentumOrientation * tiltOrientation * CFrame.Angles(-0.5 * math.pi * math.min(flyingMomentum.magnitude / PlayerControl.fly_speed, 1), 0, 0)
end
bodyVelocity.velocity = flyingMomentum + Vector3.new(0, 0.15695775618683547, 0)
rootPart.Velocity = flyingMomentum
previousMomentum = flyingMomentum
else
rootJoint.C0 = CFrame.new(0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0)
PlayerControl.rollingAngle = 0
PlayerControl.rollingOffset = 0
bodyGyro.D = 3250
bodyGyro.P = 400000
bodyVelocity.P = 5000
local cameraDirection = cameraCFrame.lookVector
local walkDirection = Vector3.new(0, 0, 0)
local walkSpeed = 16
if UserInterface:IsKeyDown(Enum.KeyCode.W) then
if UserInterface:IsKeyDown(Enum.KeyCode.A) then
walkDirection = Vector3.new(cameraDirection.X + cameraDirection.Z, 0, cameraDirection.Z - cameraDirection.X).unit
elseif UserInterface:IsKeyDown(Enum.KeyCode.D) then
walkDirection = Vector3.new(cameraDirection.X - cameraDirection.Z, 0, cameraDirection.Z + cameraDirection.X).unit
else
walkDirection = Vector3.new(cameraDirection.X, 0, cameraDirection.Z).unit
end
elseif UserInterface:IsKeyDown(Enum.KeyCode.S) then
if UserInterface:IsKeyDown(Enum.KeyCode.A) then
walkDirection = Vector3.new(-cameraDirection.X + cameraDirection.Z, 0, -cameraDirection.Z - cameraDirection.X).unit
elseif UserInterface:IsKeyDown(Enum.KeyCode.D) then
walkDirection = Vector3.new(-cameraDirection.X - cameraDirection.Z, 0, -cameraDirection.Z + cameraDirection.X).unit
else
walkDirection = Vector3.new(-cameraDirection.X, 0, -cameraDirection.Z).unit
end
elseif UserInterface:IsKeyDown(Enum.KeyCode.A) then
walkDirection = Vector3.new(cameraDirection.Z, 0, -cameraDirection.X).unit
elseif UserInterface:IsKeyDown(Enum.KeyCode.D) then
walkDirection = Vector3.new(-cameraDirection.Z, 0, cameraDirection.X).unit
else
walkSpeed = 0
end
if walkSpeed ~= previousWalkSpeed then
if walkSpeed > 0 then
soundRunning:Play()
else
soundRunning:Pause()
end
end
if walkSpeed > 0 then
if pose ~= "Jumping" then
if IsStanding() then
pose = "Running"
else
pose = "FreeFall"
end
end
bodyGyro.cframe = CFrame.new(Vector3.new(), walkDirection)
bodyGyro.maxTorque = Vector3.new(1000000000, 1000000000, 1000000000)
bodyVelocity.maxForce = Vector3.new(1000000, maxForceY, 1000000)
else
if pose ~= "Jumping" then
if IsStanding() then
pose = "Standing"
else
pose = "FreeFall"
end
end
-- TODO: find and fix bug that causes torso to rotate back to some angle
bodyGyro.maxTorque = Vector3.new(1000000000, 1000000000, 1000000000) -- Vector3.new(1000000000, 0, 1000000000)
if PlayerControl.pushable then
bodyVelocity.maxForce = Vector3.new(0, 0, 0)
else
bodyVelocity.maxForce = Vector3.new(1000000, 0, 1000000)
end
end
if featherfallEnabled then
local velocity = rootPart.Velocity
if velocity.Y > 50 then
rootPart.Velocity = Vector3.new(velocity.X, 50, velocity.Z)
elseif velocity.Y < -50 then
rootPart.Velocity = Vector3.new(velocity.X, -50, velocity.Z)
end
local distanceVector = rootPartCFrame.p - previousRootPartCFrame.p
local offsetX, offsetY, offsetZ = distanceVector.X, distanceVector.Y, distanceVector.Z
local MAX_MOVEMENT = 50 * 0.03333333507180214
if offsetX > MAX_MOVEMENT then
offsetX = MAX_MOVEMENT
elseif offsetX < -MAX_MOVEMENT then
offsetX = -MAX_MOVEMENT
end
if offsetY > MAX_MOVEMENT then
offsetY = MAX_MOVEMENT
elseif offsetY < -MAX_MOVEMENT then
offsetY = -MAX_MOVEMENT
end
if offsetZ > MAX_MOVEMENT then
offsetZ = MAX_MOVEMENT
elseif offsetZ < -MAX_MOVEMENT then
offsetZ = -MAX_MOVEMENT
end
local offset = Vector3.new(offsetX, offsetY, offsetZ)
if offset ~= distanceVector then
rootPartCFrame = previousRootPartCFrame + offset
--rootPart.CFrame = rootPartCFrame
end
end
local walkingVelocity = walkDirection * walkSpeed
bodyVelocity.velocity = walkingVelocity
if not jumpDebounce and math.abs(rootPart.Velocity.Y) <= 0.1 then
rootPart.Velocity = Vector3.new(walkingVelocity.X, rootPart.Velocity.Y, walkingVelocity.Z)
end
previousWalkSpeed = walkSpeed
if pose == "Jumping" or jumpDebounce then
rightShoulder.MaxVelocity = 0.5
leftShoulder.MaxVelocity = 0.5
rightShoulder.DesiredAngle = 3.14
leftShoulder.DesiredAngle = -3.14
rightHip.DesiredAngle = 0
leftHip.DesiredAngle = 0
elseif pose == "FreeFall" then
rightShoulder.MaxVelocity = 0.5
leftShoulder.MaxVelocity = 0.5
rightShoulder.DesiredAngle = 3.14
leftShoulder.DesiredAngle = -3.14
rightHip.DesiredAngle = 0
leftHip.DesiredAngle = 0
elseif pose == "Seated" then
rightShoulder.MaxVelocity = 0.15
leftShoulder.MaxVelocity = 0.15
rightShoulder.DesiredAngle = 3.14 / 2
leftShoulder.DesiredAngle = -3.14 / 2
rightHip.DesiredAngle = 3.14 / 2
leftHip.DesiredAngle = -3.14 / 2
else
local climbFudge = 0
local amplitude
local frequency
if pose == "Running" then
rightShoulder.MaxVelocity = 0.15
leftShoulder.MaxVelocity = 0.15
amplitude = 1
frequency = 9
elseif (pose == "Climbing") then
rightShoulder.MaxVelocity = 0.5
leftShoulder.MaxVelocity = 0.5
amplitude = 1
frequency = 9
climbFudge = 3.14
else
amplitude = 0.1
frequency = 1
end
local desiredAngle = amplitude * math.sin(totalTime * frequency)
rightShoulder.DesiredAngle = desiredAngle + climbFudge
leftShoulder.DesiredAngle = desiredAngle - climbFudge
rightHip.DesiredAngle = -desiredAngle
leftHip.DesiredAngle = -desiredAngle
end
end
previousRootPartCFrame = rootPartCFrame
RunService.RenderStepped:wait()
end
if model.Parent ~= nil then
model.Parent = nil
end
PlayerControl.CreateCharacter()
end)
humanoid.Health = 100
character = model
chatAdornee = head
elseif characterMode == "pyramid" then
if PlayerControl.characterEnabled then
Camera.CameraType = "Fixed"
PyramidCharacter.camera_distance = (Camera.Focus.p - Camera.CoordinateFrame.p).magnitude
PyramidCharacter.camera_position = Camera.Focus.p
PyramidCharacter.Teleport(Camera.Focus.p)
PyramidCharacter.visible = true
Player.Character = nil
else
PyramidCharacter.visible = false
end
end
end
function PlayerControl.GetCharacter()
return character
end
function PlayerControl.GetHead()
local characterMode = PlayerControl.characterMode
if characterMode == "normal" then
return head
elseif characterMode == "pyramid" then
return PyramidCharacter.core
end
end
function PlayerControl.GetHumanoid()
return humanoid
end
function PlayerControl.GetRootPart()
return rootPart
end
function PlayerControl.GetTorso()
return torso
end
function PlayerControl.IsEnabled()
return PlayerControl.characterEnabled
end
function PlayerControl.IsFeatherfallEnabled()
return PlayerControl.featherfallEnabled
end
function PlayerControl.IsPushable()
return PlayerControl.pushable
end
function PlayerControl.IsRolling()
return PlayerControl.rolling
end
function PlayerControl.ResetCharacter()
if character and character.Parent then
character.Parent = nil
end
PyramidCharacter.visible = false
end
function PlayerControl.SetEnabled(state, no_animation)
state = not not state
if state ~= PlayerControl.characterEnabled then
PlayerControl.characterEnabled = state
local characterMode = PlayerControl.characterMode
if characterMode == "normal" then
local torso = PlayerControl.GetRootPart()
local rootPart = PlayerControl.GetRootPart()
if rootPart then
if PlayerControl.characterEnabled then
local torso_cframe = Camera.Focus:toWorldSpace(PlayerControl.hide_torso_object_cframe)
PlayerControl.torso_cframe = torso_cframe
torso.CFrame = torso_cframe
rootPart.CFrame = torso_cframe
else
PlayerControl.hide_torso_object_cframe = Camera.Focus:toObjectSpace(rootPart.CFrame)
end
else
PlayerControl.torso_cframe = Camera.Focus
end
if PlayerControl.characterEnabled then
PlayerControl.CreateCharacter()
RunService.Stepped:wait()
coroutine.yield()
if not no_animation then
GraphicalEffects.CrystalRing({base_part = PlayerControl.GetTorso(), crystal_color = BrickColor.new("Institutional white"), float_duration = 2})
end
else
Player.Character = nil
Camera.CameraType = "Fixed"
if not no_animation then
GraphicalEffects.CrystalRing({position = PlayerControl.GetTorso().Position, crystal_color = BrickColor.new("Institutional white"), float_duration = 2})
end
end
else
if state then
PlayerControl.CreateCharacter()
RunService.Stepped:wait()
coroutine.yield()
if not no_animation then
GraphicalEffects.CrystalRing({base_part = PyramidCharacter.core, crystal_color = BrickColor.new("Institutional white"), float_duration = 2})
end
else
PyramidCharacter.visible = false
if not no_animation then
GraphicalEffects.CrystalRing({position = PyramidCharacter.core.Position, crystal_color = BrickColor.new("Institutional white"), float_duration = 2})
end
end
end
end
end
function PlayerControl.SetFeatherfallEnabled(state)
state = not not state
if state ~= PlayerControl.featherfallEnabled then
PlayerControl.featherfallEnabled = state
if state then
Logger.print("Info", "Featherfall enabled in PlayerControl")
else
Logger.print("Info", "Featherfall disabled in PlayerControl")
end
end
end
function PlayerControl.SetPushable(state)
state = not not state
if state ~= PlayerControl.pushable then
PlayerControl.pushable = state
if state then
Logger.print("Info", "Pushing enabled in PlayerControl")
else
Logger.print("Info", "Pushing disabled in PlayerControl")
end
end
end
function PlayerControl.SetRolling(state)
state = not not state
if state ~= PlayerControl.rolling then
PlayerControl.rolling = state
if state then
Logger.print("Info", "Rolling fly mode enabled in PlayerControl")
else
Logger.print("Info", "Rolling fly mode disabled in PlayerControl")
end
end
end
function PlayerControl.StartFlying()
PlayerControl.fly_speed = PlayerControl.fly_basespeed
if torso then
flyingMomentum = torso.Velocity + torso.CFrame.lookVector * 3 + Vector3.new(0, 10, 0)
else
flyingMomentum = Vector3.new()
end
flyingTilt = 0
flying = true
end
function PlayerControl.StopFlying()
if bodyGyro.cframe then
local lookVector = bodyGyro.cframe.lookVector
if lookVector.X ~= 0 or lookVector.Z ~= 0 then
bodyGyro.cframe = CFrame.new(Vector3.new(), Vector3.new(lookVector.X, 0, lookVector.Z))
end
end
flying = false
end
local previousTime = 0
RBXInstance = {};
RBXInstance.init_metatable = {}
function RBXInstance.init_metatable:__call(data)
local instance = Instance.new(self[1])
for key, value in pairs(data) do
if type(key) == "number" then
value.Parent = instance
else
instance[key] = value
end
end
return instance
end
function RBXInstance.new(className)
return setmetatable({className}, RBXInstance.init_metatable)
end
GraphicalEffects = {};
local MESH_IDS = {"rbxassetid://15310891"}
local SOUND_IDS = {"rbxassetid://2248511", "rbxassetid://1369158"}
local TEXTURE_IDS = {"rbxassetid://36527089", "rbxassetid://122610943", "rbxassetid://126561317", "rbxassetid://127033719"}
local preloadConnections = {}
local reloadingPreloads = false
function GraphicalEffects.InitPreloads()
local preload_part = Instance.new("Part")
GraphicalEffects.preload_part = preload_part
preload_part.Anchored = true
preload_part.Archivable = false
preload_part.BottomSurface = "Smooth"
preload_part.CanCollide = false
preload_part.CFrame = CFrame.new(math.huge, math.huge, math.huge)
preload_part.FormFactor = "Custom"
preload_part.Locked = true
preload_part.Name = "Asset Preloader"
preload_part.Size = Vector3.new(0.2, 0.2, 0.2)
preload_part.TopSurface = "Smooth"
preload_part.Transparency = 1
preloadConnections[preload_part] = preload_part.AncestryChanged:connect(GraphicalEffects.PreloadsAncestryChanged)
for _, mesh_id in ipairs(MESH_IDS) do
local mesh = Instance.new("SpecialMesh")
mesh.MeshType = "FileMesh"
mesh.MeshId = mesh_id
preloadConnections[mesh] = mesh.AncestryChanged:connect(GraphicalEffects.PreloadsAncestryChanged)
mesh.Parent = preload_part
end
for _, sound_id in ipairs(SOUND_IDS) do
local sound = Instance.new("Sound")
sound.SoundId = sound_id
sound.Volume = 0
preloadConnections[sound] = sound.AncestryChanged:connect(GraphicalEffects.PreloadsAncestryChanged)
sound.Parent = preload_part
end
for _, texture_id in ipairs(TEXTURE_IDS) do
local decal = Instance.new("Decal")
decal.Texture = texture_id
preloadConnections[decal] = decal.AncestryChanged:connect(GraphicalEffects.PreloadsAncestryChanged)
decal.Parent = preload_part
end
preload_part.Parent = Workspace
end
function GraphicalEffects.PreloadsAncestryChanged(child, parent)
if not reloadingPreloads and parent ~= GraphicalEffects.preload_part and parent ~= Workspace then
reloadingPreloads = true
for _, connection in pairs(preloadConnections) do
connection:disconnect()
preloadConnections[_] = nil
end
wait(1)
reloadingPreloads = false
GraphicalEffects.InitPreloads()
end
end
GraphicalEffects.InitPreloads()
-- Hyper beam
function GraphicalEffects.FireSpaceHyperBeam(target, power, duration, radius, height, deviation)
local stepTime, gameTime = 1 / 30, TaskScheduler.GetCurrentTime()
local frames = duration * 30
local beamColorOffset = 0.75 * tick() -- math.random()
local blastPressure = power * 62500 + 250000
local beamPart = Instance.new("Part")
local beamMesh = Instance.new("SpecialMesh", beamPart)
local explosion = Instance.new("Explosion")
local sound = Instance.new("Sound", beamPart)
beamPart.Anchored = true
beamPart.CanCollide = false
beamPart.CFrame = CFrame.new(target, target + Vector3.new(deviation * (math.random() - 0.5), deviation * (math.random() - 0.5), height))
beamPart.FormFactor = "Custom"
beamPart.Locked = true
beamPart.Size = Vector3.new(0.2, 0.2, 0.2)
beamMesh.MeshId = "rbxassetid://15310891"
beamMesh.MeshType = "FileMesh"
beamMesh.TextureId = "rbxassetid://36527089"
local beamGlowPart1 = beamPart:Clone()
local beamGlowMesh1 = beamMesh:Clone()
local beamGlowPart2 = beamPart:Clone()
local beamGlowMesh2 = beamMesh:Clone()
local beamLight = Instance.new("PointLight", beamPart)
beamLight.Range = power * 2
beamLight.Shadows = true
explosion.BlastPressure = blastPressure
explosion.BlastRadius = power
explosion.Position = target
sound.SoundId = "rbxassetid://2248511"
sound.Volume = 1
local explosionHitConnection = explosion.Hit:connect(function(part, distance)
if not part.Anchored and part:GetMass() < power * power then
pcall(part.BreakJoints, part)
part.Color = Color3.new(Utility.GetRainbowRGB(1.5 * gameTime + beamColorOffset))
end
end)
beamPart.Transparency = 0.5
beamPart.Archivable = false
beamGlowPart1.Transparency = 0.75
beamGlowPart2.Transparency = 0.75
beamGlowMesh1.Parent = beamGlowPart1
beamGlowPart1.Parent = beamPart
beamGlowMesh2.Parent = beamGlowPart2
beamGlowPart2.Parent = beamPart
beamPart.Parent = workspace
explosion.Parent = workspace
for frame = 1, frames do
local progress = frame / frames
local alpha = 1 - math.sin(0.5 * math.pi * progress)
local scale = 0.4 * alpha
local glowScale1 = alpha * (0.5 + 0.5 * math.sin(math.tau * (8 * gameTime + beamColorOffset)))
local glowScale2 = alpha * (0.5 + 0.5 * math.cos(math.tau * (8 * gameTime + beamColorOffset)))
local vertexColor = Vector3.new(Utility.GetRainbowRGB(1.5 * gameTime + beamColorOffset))
beamLight.Brightness = 1 - progress
beamLight.Color = Color3.new(vertexColor.x, vertexColor.y, vertexColor.z)
beamMesh.Scale = Vector3.new(radius * scale, 9000, radius * scale)
beamMesh.VertexColor = vertexColor
beamGlowMesh1.Scale = Vector3.new(1.2 * radius * glowScale1, 9000, 1.2 * radius * glowScale1)
beamGlowMesh1.VertexColor = vertexColor
beamGlowMesh2.Scale = Vector3.new(1.2 * radius * glowScale2, 9000, 1.2 * radius * glowScale2)
beamGlowMesh2.VertexColor = vertexColor
RunService.Stepped:wait()
gameTime = TaskScheduler.GetCurrentTime()
if frame <= 2 then
local explosion = Instance.new("Explosion")
explosion.BlastPressure = (1 - progress) * blastPressure
explosion.BlastRadius = (1 - progress) * power
explosion.Position = target
explosion.Parent = Workspace
if frame == 2 then
sound:Play()
end
end
end
pcall(beamPart.Destroy, beamPart)
explosionHitConnection:disconnect()
end
function GraphicalEffects.SpaceHyperBeam(target, power, duration, radius, height, deviation)
TaskScheduler.Start(GraphicalEffects.FireSpaceHyperBeam, target, power or 12, duration or 1.5, radius or 6, height or 600, deviation or 20)
end
-- Magic Circle
GraphicalEffects.magicCircleData = {}
GraphicalEffects.MAGIC_CIRCLE_DEFAULT_OFFSET = 6.25
function GraphicalEffects.AnimateMagicCircle(data)
local frame, direction, magic_circle_model, magic_circle_part, magic_circle_light, magic_circle_decal_back, magic_circle_decal_front, duration,
stay, magic_circle_adornee_func, magic_circle_offset = unpack(data)
frame = frame + 1
data[1] = frame
local transparency = (frame / duration) ^ stay
local opacity = 1 - transparency
if frame == duration then
pcall(Game.Destroy, magic_circle_model)
GraphicalEffects.magicCircleData[data] = nil
else
if magic_circle_model.Parent ~= Workspace then
pcall(Utility.SetProperty, magic_circle_model, "Parent", Workspace)
end
local magic_circle_adornee = magic_circle_adornee_func()
magic_circle_position = magic_circle_adornee.Position + direction * magic_circle_offset
local magic_circle_cframe = CFrame.new(magic_circle_position, magic_circle_position + direction) * CFrame.Angles(0, 0, math.tau * frame /
25)
magic_circle_part.CFrame = magic_circle_cframe
magic_circle_light.Brightness = opacity
magic_circle_decal_back.Transparency = transparency
magic_circle_decal_front.Transparency = transparency
end
end
function GraphicalEffects.CreateMagicCircle(target, magic_circle_scale, magic_circle_image, light_color, duration, stay, magic_circle_adornee_func,
magic_circle_offset)
local magic_circle_adornee = magic_circle_adornee_func()
if magic_circle_adornee then
local origin = magic_circle_adornee.Position
local direction = (target - origin).unit
local magic_circle_position = origin + direction * magic_circle_offset
local magic_circle_cframe = CFrame.new(magic_circle_position, magic_circle_position + direction)
local magic_circle_model = Instance.new("Model")
local magic_circle_part = Instance.new("Part", magic_circle_model)
local magic_circle_mesh = Instance.new("BlockMesh", magic_circle_part)
local magic_circle_light = Instance.new("PointLight", magic_circle_part)
local magic_circle_decal_back = Instance.new("Decal", magic_circle_part)
local magic_circle_decal_front = Instance.new("Decal", magic_circle_part)
magic_circle_model.Archivable = false
magic_circle_part.Anchored = true
magic_circle_part.BottomSurface = "Smooth"
magic_circle_part.CanCollide = false
magic_circle_part.CFrame = magic_circle_cframe
magic_circle_part.FormFactor = "Custom"
magic_circle_part.Locked = true
magic_circle_part.Size = Vector3.new(0.2, 0.2, 0.2)
magic_circle_part.TopSurface = "Smooth"
magic_circle_part.Transparency = 1
magic_circle_mesh.Scale = Vector3.new(60, 60, 0) * magic_circle_scale
magic_circle_light.Color = light_color
magic_circle_light.Range = 16 * magic_circle_scale
magic_circle_light.Shadows = true
magic_circle_decal_back.Face = "Back"
magic_circle_decal_back.Texture = magic_circle_image
magic_circle_decal_front.Face = "Front"
magic_circle_decal_front.Texture = magic_circle_image
magic_circle_model.Parent = Workspace
local data = {0, direction, magic_circle_model, magic_circle_part, magic_circle_light, magic_circle_decal_back, magic_circle_decal_front,
duration, stay, magic_circle_adornee_func, magic_circle_offset}
GraphicalEffects.magicCircleData[data] = true
return data
end
end
-- Laser of Death
GraphicalEffects.LASER_WIDTH = 0.15
GraphicalEffects.LASER_MAGIC_CIRCLE_DISTANCE = 6.25
GraphicalEffects.laser_data = {}
--GraphicalEffects.fragmentation = {}
function GraphicalEffects.AnimateLaserOfDeath(data)
local frame, directionOrientation, direction, magic_circle_model, laser_part, laser_mesh, magic_circle_part, magic_circle_light,
magic_circle_decal_back, magic_circle_decal_front, sound, laser_scale, fragmentation_size, duration, laser_lights, laser_effects, stay, light_effects =
unpack(data)
local laser_color = laser_part.Color
frame = frame + 1
data[1] = frame
local transparency = (frame / duration) ^ stay
local opacity = 1 - transparency
if frame == 2 then
sound:Play()
end
if frame == duration then
pcall(Game.Destroy, magic_circle_model)
GraphicalEffects.laser_data[data] = nil
else
if magic_circle_model.Parent ~= Workspace then
pcall(Utility.SetProperty, magic_circle_model, "Parent", Workspace)
end
local laser_distance = 0
local origin = chatAdornee.CFrame
if not light_effects then
direction = (origin * directionOrientation - origin.p).unit
end
local magic_circle_position = origin.p + direction * GraphicalEffects.LASER_MAGIC_CIRCLE_DISTANCE
local magic_circle_cframe = CFrame.new(magic_circle_position, magic_circle_position + direction) * CFrame.Angles(0, 0, math.tau * frame /
25)
local loop_scale = (laser_scale - 1) / 10
for x_offset = -loop_scale, loop_scale, 2 do
for y_offset = -loop_scale, loop_scale, 2 do
local origin_position = magic_circle_cframe * Vector3.new(x_offset, y_offset, 0)
for index = 1, 8 do
local part, position
for ray_index = 1, 10 do
local ray = Ray.new(origin_position + direction * (999 * (ray_index - 1)), direction * 999)
part, position = Workspace:FindPartOnRay(ray, magic_circle_model)
if part then
break
end
end
if part then
laser_distance = (position - origin_position).magnitude
if frame % 8 == 1 and index == 1 then
Instance.new("Explosion", Workspace).Position = position
end
if not part:IsA("Terrain") then
pcall(part.BreakJoints, part)
local is_block = part:IsA("Part") and part.Shape == Enum.PartType.Block
local mass = part:GetMass()
local size = part.Size
if (is_block and ((size.X < fragmentation_size and size.Y < fragmentation_size and size.Z <
fragmentation_size) or (not part.Anchored and mass < 750))) or (not is_block and mass < 250000) then
local part_transparency = math.max(part.Transparency + 0.007 * fragmentation_size, 0.5)
if part_transparency >= 0.5 then -- temporarily to minimize debris
pcall(Game.Destroy, part)
else
local cframe = part.CFrame
part.Anchored = false
part.BrickColor = BrickColor.new("Medium stone grey")
part.CanCollide = true
if part:IsA("FormFactorPart") then
part.FormFactor = "Custom"
end
part.Size = size - Vector3.new(0.135, 0.135, 0.135) * fragmentation_size
part.Transparency = part_transparency
part.CFrame = cframe + direction * 5
part.Velocity = part.Velocity + direction * 40
end
elseif is_block then
local parts = {part}
local model = Instance.new("Model", part.Parent)
model.Name = "Fragments"
if size.X >= fragmentation_size then
size = Vector3.new(0.5, 1, 1) * size
local archivable = part.Archivable
local cframe = part.CFrame
part.FormFactor = "Custom"
part.Size = size
part.Archivable = true
local part_clone = part:Clone()
part.Archivable = archivable
part_clone.Archivable = archivable
part.CFrame = cframe * CFrame.new(-0.5 * size.X, 0, 0)
part_clone.CFrame = cframe * CFrame.new(0.5 * size.X, 0, 0)
part_clone.Parent = model
parts[2] = part_clone
end
if size.Y >= fragmentation_size then
size = Vector3.new(1, 0.5, 1) * size
for part_index = 1, #parts do
local part = parts[part_index]
local archivable = part.Archivable
local cframe = part.CFrame
part.FormFactor = "Custom"
part.Size = size
part.Archivable = true
local part_clone = part:Clone()
part.Archivable = archivable
part_clone.Archivable = archivable
part.CFrame = cframe * CFrame.new(0, -0.5 * size.Y, 0)
part_clone.CFrame = cframe * CFrame.new(0, 0.5 * size.Y, 0)
part_clone.Parent = model
table.insert(parts, part_clone)
end
end
if size.Z >= fragmentation_size then
size = Vector3.new(1, 1, 0.5) * size
for part_index = 1, #parts do
local part = parts[part_index]
local archivable = part.Archivable
local cframe = part.CFrame
part.FormFactor = "Custom"
part.Size = size
part.Archivable = true
local part_clone = part:Clone()
part.Archivable = archivable
part_clone.Archivable = archivable
part.CFrame = cframe * CFrame.new(0, 0, -0.5 * size.Z)
part_clone.CFrame = cframe * CFrame.new(0, 0, 0.5 * size.Z)
part_clone.Parent = model
table.insert(parts, part_clone)
end
end
for _, part in ipairs(parts) do
part:MakeJoints()
end
else
break
end
end
else
laser_distance = 9990
break
end
end
end
end
local laser_cframe = magic_circle_cframe * CFrame.Angles(-0.5 * math.pi, 0, 0)
local laser_width = GraphicalEffects.LASER_WIDTH * opacity * laser_scale
local laser_mesh_offset = Vector3.new(0, 0.5 * laser_distance, 0)
laser_part.CFrame = laser_cframe
if laser_effects then
local laser_effect_data_1, laser_effect_data_2 = laser_effects[1], laser_effects[2]
local laser_effect_1, laser_effect_mesh_1 = laser_effect_data_1[1], laser_effect_data_1[2]
local laser_effect_2, laser_effect_mesh_2 = laser_effect_data_2[1], laser_effect_data_2[2]
laser_effect_1.CFrame = laser_cframe
laser_effect_2.CFrame = laser_cframe
laser_effect_mesh_1.Offset = laser_mesh_offset
laser_effect_mesh_2.Offset = laser_mesh_offset
local game_time = time()
local effect_scale_1 = 0.5 + 0.5 * math.sin(16 * math.pi * game_time)
local effect_scale_2 = 0.5 + 0.5 * math.cos(16 * math.pi * game_time)
laser_effect_mesh_1.Scale = 5 * Vector3.new(laser_width * effect_scale_1, laser_distance, laser_width * effect_scale_1)
laser_effect_mesh_2.Scale = 5 * Vector3.new(laser_width * effect_scale_2, laser_distance, laser_width * effect_scale_2)
laser_width = laser_width * 0.25
end
laser_mesh.Offset = laser_mesh_offset
laser_mesh.Scale = 5 * Vector3.new(laser_width, laser_distance, laser_width)
magic_circle_part.CFrame = magic_circle_cframe
magic_circle_light.Brightness = opacity
magic_circle_decal_back.Transparency = transparency
magic_circle_decal_front.Transparency = transparency
if light_effects then
for index, data in ipairs(laser_lights) do
local laser_spotlight_part, laser_spotlight = data[1], data[2]
local laser_spotlight_offset = 30 * (index - 1)
if laser_spotlight_offset <= laser_distance then
laser_spotlight_part.CFrame = magic_circle_cframe * CFrame.new(0, 0, -laser_spotlight_offset)
laser_spotlight.Brightness = opacity
laser_spotlight.Enabled = true
else
laser_spotlight.Enabled = false
end
end
end
end
end
function GraphicalEffects.ShootLaserOfDeath(target, data)
if chatAdornee then
data = data or {}
local brickcolor = data.brickcolor or BrickColor.new("Really black")
local duration = data.duration or 40
local fragmentation_size = data.fragmentation_size or 3
local laser_scale = data.laser_scale or 1
local light_color = data.light_color or Color3.new(1, 0.5, 1)
local magic_circle_image = data.magic_circle_image or "rbxassetid://122610943"
local magic_circle_scale = data.magic_circle_scale or 1
local sound_volume = data.sound_volume or 1 / 3
local special_effects = data.special_effects
local stay = data.stay or 4
local origin = chatAdornee.CFrame
local directionOrientation = origin:pointToObjectSpace(target)
local direction = (target - origin.p).unit
local magic_circle_position = origin.p + direction * GraphicalEffects.LASER_MAGIC_CIRCLE_DISTANCE
local magic_circle_cframe = CFrame.new(magic_circle_position, magic_circle_position + direction)
local magic_circle_model = Instance.new("Model")
local laser_part = Instance.new("Part", magic_circle_model)
local laser_mesh = Instance.new("CylinderMesh", laser_part)
local magic_circle_part = Instance.new("Part", magic_circle_model)
local magic_circle_mesh = Instance.new("BlockMesh", magic_circle_part)
local magic_circle_light = Instance.new("PointLight", magic_circle_part)
local magic_circle_decal_back = Instance.new("Decal", magic_circle_part)
local magic_circle_decal_front = Instance.new("Decal", magic_circle_part)
local sound = Instance.new("Sound", magic_circle_part)
sound.Pitch = 1.25
sound.SoundId = "rbxassetid://2248511"
sound.Volume = sound_volume
magic_circle_model.Archivable = false
laser_part.Anchored = true
laser_part.BottomSurface = "Smooth"
laser_part.BrickColor = brickcolor
laser_part.CanCollide = false
laser_part.CFrame = magic_circle_cframe * CFrame.Angles(-0.5 * math.pi, 0, 0)
laser_part.FormFactor = "Custom"
laser_part.Locked = true
laser_part.Size = Vector3.new(0.2, 0.2, 0.2)
laser_part.TopSurface = "Smooth"
laser_mesh.Offset = Vector3.new(0, 0, 0)
laser_mesh.Name = "Mesh"
laser_mesh.Scale = 5 * laser_scale * Vector3.new(GraphicalEffects.LASER_WIDTH, 0, GraphicalEffects.LASER_WIDTH)
magic_circle_part.Anchored = true
magic_circle_part.BottomSurface = "Smooth"
magic_circle_part.CanCollide = false
magic_circle_part.CFrame = magic_circle_cframe
magic_circle_part.FormFactor = "Custom"
magic_circle_part.Locked = true
magic_circle_part.Size = Vector3.new(0.2, 0.2, 0.2)
magic_circle_part.TopSurface = "Smooth"
magic_circle_part.Transparency = 1
magic_circle_mesh.Scale = Vector3.new(60, 60, 0) * magic_circle_scale
magic_circle_light.Color = light_color
magic_circle_light.Range = 16 * magic_circle_scale
magic_circle_light.Shadows = true
magic_circle_decal_back.Face = "Back"
magic_circle_decal_back.Texture = magic_circle_image
magic_circle_decal_front.Face = "Front"
magic_circle_decal_front.Texture = magic_circle_image
magic_circle_model.Parent = Workspace
local laser_color = brickcolor.Color
local laser_lights = {}
local light_effects = laser_color.r + laser_color.g + laser_color.b > 0.25
if light_effects then
local laser_spotlight_part_template = Instance.new("Part")
local laser_spotlight_light_template = Instance.new("SpotLight", laser_spotlight_part_template)
laser_spotlight_part_template.Anchored = true
laser_spotlight_part_template.Anchored = true
laser_spotlight_part_template.BottomSurface = "Smooth"
laser_spotlight_part_template.CanCollide = false
laser_spotlight_part_template.FormFactor = "Custom"
laser_spotlight_part_template.Locked = true
laser_spotlight_part_template.Size = Vector3.new(0.2, 0.2, 0.2)
laser_spotlight_part_template.TopSurface = "Smooth"
laser_spotlight_part_template.Transparency = 1
laser_spotlight_light_template.Angle = 45
laser_spotlight_light_template.Color = laser_color
laser_spotlight_light_template.Enabled = true
laser_spotlight_light_template.Name = "Light"
laser_spotlight_light_template.Range = 60
for index = 1, 40 do
local laser_spotlight_part = laser_spotlight_part_template:Clone()
laser_spotlight_part.CFrame = magic_circle_cframe * CFrame.new(0, 0, -30 * (index - 1))
laser_spotlight_part.Parent = magic_circle_model
laser_lights[index] = {laser_spotlight_part, laser_spotlight_part.Light}
end
end
local laser_effects
if special_effects then
laser_effects = {}
local laser_effect_1 = laser_part:Clone()
laser_effect_1.BrickColor = special_effects
laser_effect_1.Transparency = 0.5
local laser_effect_2 = laser_effect_1:Clone()
laser_effects[1], laser_effects[2] = {laser_effect_1, laser_effect_1.Mesh}, {laser_effect_2, laser_effect_2.Mesh}
laser_effect_1.Parent = magic_circle_model
laser_effect_2.Parent = magic_circle_model
end
GraphicalEffects.laser_data[{0, directionOrientation, direction, magic_circle_model, laser_part, laser_mesh, magic_circle_part, magic_circle_light, magic_circle_decal_back, magic_circle_decal_front, sound, laser_scale, fragmentation_size, duration, laser_lights, laser_effects, stay, light_effects}] = true
end
end
-- Sapient Rock
function GraphicalEffects.SpawnSapientRock(position)
local part = Instance.new("Part", Workspace)
local size = 8 + math.random(0, 5)
part.BottomSurface = "Smooth"
part.TopSurface = "Smooth"
part.Material = "Slate"
part.Locked = true
part.Shape = "Ball"
part.FormFactor = "Custom"
part.Size = Vector3.new(size, size, size)
part.Position = position
local bodypos = Instance.new("BodyPosition", part)
bodypos.maxForce = Vector3.new(0, 0, 0)
local angry = false
local damage_ready = true
local torso_following
local torso_changed = -1000
local touched_conn = part.Touched:connect(function(hit)
local character = hit.Parent
if character then
local humanoid
for _, child in ipairs(character:GetChildren()) do
if child:IsA("Humanoid") then
humanoid = child
break
end
end
if humanoid then
if angry then
if damage_ready then
damage_ready = false
humanoid:TakeDamage(100)
wait(1)
damage_ready = true
angry = false
part.BrickColor = BrickColor.new("Medium stone grey")
end
else
local torso = humanoid.Torso
if torso then
torso_following = torso
torso_changed = tick()
end
end
end
end
end)
TaskScheduler.Start(function()
while part.Parent == Workspace do
if torso_following then
bodypos.position = torso_following.Position
if tick() - torso_changed > 60 or not torso_following.Parent then
torso_following = nil
bodypos.maxForce = Vector3.new(0, 0, 0)
angry = false
part.BrickColor = BrickColor.new("Medium stone grey")
else
local speed = angry and Vector3.new(16, 16, 16) or Vector3.new(6, 0, 6)
bodypos.maxForce = part:GetMass() * speed
if part.Position.Y < -250 then
part.Velocity = Vector3.new()
part.Position = torso_following.Position + Vector3.new(0, 80, 0)
part.BrickColor = BrickColor.new("Bright red")
angry = true
torso_changed = tick()
end
end
end
RunService.Stepped:wait()
end
touched_conn:disconnect()
end)
TaskScheduler.Start(function()
while part.Parent == Workspace do
wait(25 + math.random() * 10)
local next_size = 8 + math.random() * 5
if math.random(100) == 1 then
next_size = next_size * (2 + 6 * math.random())
end
next_size = math.floor(next_size + 0.5)
local start_time = tick()
local mesh = Instance.new("SpecialMesh", part)
mesh.MeshType = "Sphere"
repeat
local elapsed_time = tick() - start_time
local alpha = math.cos(elapsed_time * math.pi * 0.5)
local interpolated_size = size * alpha + next_size * (1 - alpha)
local size_vector = Vector3.new(interpolated_size, interpolated_size, interpolated_size)
local cframe = part.CFrame
part.Size = size_vector
part.CFrame = cframe
mesh.Scale = size_vector / part.Size
RunService.Stepped:wait()
until tick() - start_time >= 1
mesh:Destroy()
local cframe = part.CFrame
part.Size = Vector3.new(next_size, next_size, next_size)
part.CFrame = cframe
size = next_size
end
end)
end
-- Crystal ring
function GraphicalEffects.CrystalRing(data)
data = data or {}
local crystal_count = data.crystal_count or 10
local crystal_color = data.crystal_color or BrickColor.new("Bright red")
local crystal_scale = data.crystal_scale or Vector3.new(2 / 3, 2, 2 / 3)
local radius = radius or 1.25 * crystal_count / math.pi
local spawn_duration = data.spawn_duration or 0.065
local full_spawn_duration = spawn_duration * crystal_count
local float_duration = data.float_duration or 5
local wave_amplitude = data.wave_amplitude or 0.5
local wave_period = data.wave_period or 1
local appear_duration = data.appear_duration or 0.1
local disappear_duration = data.disappear_duration or 0.5
local base_part = data.base_part
local offset_cframe
if data.position then
offset_cframe = CFrame.new(data.position)
if base_part then
offset_cframe = base_part.CFrame:toObjectSpace(offset_cframe)
end
else
offset_cframe = CFrame.new()
end
local crystal_template = Instance.new("Part")
crystal_template.Anchored = true
crystal_template.Locked = true
crystal_template.CanCollide = false
crystal_template.BottomSurface = "Smooth"
crystal_template.TopSurface = "Smooth"
crystal_template.BrickColor = crystal_color
crystal_template.FormFactor = "Symmetric"
crystal_template.Size = Vector3.new(1, 1, 1)
local crystal_light = Instance.new("PointLight", crystal_template)
crystal_light.Brightness = 0.1 / crystal_count
crystal_light.Color = crystal_color.Color
crystal_light.Name = "Light"
crystal_light.Range = radius
crystal_light.Shadows = true
local crystal_mesh = Instance.new("SpecialMesh", crystal_template)
crystal_mesh.MeshId = "rbxassetid://9756362"
crystal_mesh.MeshType = "FileMesh"
crystal_mesh.Name = "Mesh"
crystal_mesh.Scale = crystal_scale
local crystal_model = Instance.new("Model")
crystal_model.Archivable = false
crystal_model.Name = "Crystal Model"
crystal_model.Parent = Workspace
local crystals = {}
local lights = {}
local meshes = {}
for index = 1, crystal_count do
local crystal = crystal_template:Clone()
crystal.Parent = crystal_model
crystals[index] = crystal
lights[index] = crystal.Light
meshes[index] = crystal.Mesh
end
local start_time = tick()
repeat
local base_cframe = offset_cframe
if base_part then
base_cframe = base_part.CFrame * base_cframe
end
local elapsed_time = tick() - start_time
for index, crystal in ipairs(crystals) do
local crystal_time = elapsed_time - index * spawn_duration
local disappear_time = crystal_time - float_duration
local offset
if crystal_time < 0 then
offset = 0
elseif crystal_time < appear_duration then
offset = radius * crystal_time / appear_duration
else
offset = radius
end
local wave_offset
if disappear_time >= 0 then
local disappear_progress = disappear_time / disappear_duration
if disappear_progress > 1 then
if crystal.Parent then
crystal:Destroy()
end
else
local inverse_progress = 1 - disappear_progress
local light = lights[index]
local mesh = meshes[index]
crystal.BrickColor = BrickColor.new("Really black")
light.Brightness = 2 * inverse_progress
light.Range = 2 * radius
mesh.Scale = crystal_scale * inverse_progress
end
wave_offset = 0
else
wave_offset = wave_amplitude * math.sin(math.tau * (elapsed_time - index / crystal_count * 3) / wave_period)
end
local rotation_angle = (tick() * 0.5 + (index - 1) / crystal_count) % 1 * math.tau
crystal.CFrame = base_cframe * CFrame.Angles(0, rotation_angle, 0) * CFrame.new(0, wave_offset, -offset)
end
RunService.Stepped:wait()
until elapsed_time >= float_duration + full_spawn_duration + disappear_duration
if crystal_model.Parent then
crystal_model:Destroy()
end
end
-- Missiles
GraphicalEffects.missileData = {}
GraphicalEffects.missileParts = {}
function GraphicalEffects.AnimateMissile(data)
local frame, missilePart, targetPart, timeCreated, direction, touchedConnection, explodeRequested, bodyGyro, swooshSound, magicCircleData, lifeTime,
pointOnPart, flipped = unpack(data)
frame = frame + 1
data[1] = frame
if flipped then
direction = -direction
end
if frame <= 10 then
if frame == 2 then
swooshSound:Play()
end
missilePart.Anchored = true
local progress = frame / 10
missilePart.Size = Vector3.new(1, 1, progress * 4)
local magicCirclePart = magicCircleData[4]
local magicCirclePosition = magicCirclePart.Position
local missileOffset = 2 * progress * direction
local missilePosition = magicCirclePosition + missileOffset
missilePart.CFrame = CFrame.new(missilePosition, missilePosition + direction)
--missilePart.Transparency = 0.5 * (1 - progress)
if frame == 10 then
touchedConnection = missilePart.Touched:connect(function(hit)
if hit.CanCollide and hit.Parent and not GraphicalEffects.missileParts[hit] then
touchedConnection:disconnect()
data[7] = true
end
end)
data[6] = touchedConnection
end
else
missilePart.Anchored = false
local missilePosition = missilePart.Position
local targetPosition = targetPart.CFrame * pointOnPart
local distanceVector = targetPosition - missilePosition
local elapsedTime = time() - timeCreated
local targetParent = targetPart.Parent
if explodeRequested or (targetParent and distanceVector.magnitude < 10) or elapsedTime > lifeTime then
GraphicalEffects.missileData[data] = nil
GraphicalEffects.missileParts[missilePart] = nil
touchedConnection:disconnect()
if missilePart.Parent then
missilePart:Destroy()
local explosion = Instance.new("Explosion")
explosion.BlastRadius = 12.5
explosion.Position = missilePosition
local explosionHitConnection = explosion.Hit:connect(function(hit, distance)
local missileData = GraphicalEffects.missileParts[hit]
if missileData and distance < 3 then
missileData[7] = true
else
pcall(hit.BreakJoints, hit)
end
end)
explosion.Parent = Workspace
TaskScheduler.Schedule(1, explosionHitConnection.disconnect, explosionHitConnection)
end
else
local targetInWorkspace = targetPart:IsDescendantOf(Workspace)
if targetInWorkspace then
direction = distanceVector.unit
data[5] = direction
end
local speed = 14 + elapsedTime * 10
local gyroD
if elapsedTime < 42.5 and targetInWorkspace then
gyroD = 1000 - elapsedTime * 15
else
gyroD = 100
bodyGyro.maxTorque = Vector3.new(0, 0, 0)
if elapsedTime + 7.5 < lifeTime then
data[11] = elapsedTime + 7.5
end
end
bodyGyro.D = gyroD
bodyGyro.cframe = CFrame.new(Vector3.new(), direction)
missilePart.Velocity = missilePart.CFrame.lookVector * speed
end
end
end
function GraphicalEffects.ShootMissile(targetPart, pointOnPart, direction, magic_circle_adornee_func, magic_circle_offset, flipped)
if not magic_circle_offset then
magic_circle_offset = GraphicalEffects.MAGIC_CIRCLE_DEFAULT_OFFSET
end
local targetPosition = targetPart.Position
local headPosition = chatAdornee.Position
local origin = CFrame.new(headPosition, headPosition + direction) + direction * magic_circle_offset
local missilePart = Instance.new("Part")
local antiGravityForce = Instance.new("BodyForce", missilePart)
local bodyGyro = Instance.new("BodyGyro", missilePart)
local explosionSound = Instance.new("Sound", missilePart)
local swooshSound = Instance.new("Sound", missilePart)
antiGravityForce.force = Vector3.new(0, 196.2 * 4, 0)
bodyGyro.D = 1000
bodyGyro.maxTorque = Vector3.new(1, 1, 1)
explosionSound.PlayOnRemove = true
explosionSound.SoundId = "rbxasset://sounds/collide.wav"
explosionSound.Volume = 1
missilePart.Anchored = true
missilePart.BackSurface = "Studs"
missilePart.BottomSurface = "Studs"
missilePart.BrickColor = BrickColor.Red()
missilePart.CFrame = origin
missilePart.FormFactor = "Custom"
missilePart.FrontSurface = "Studs"
missilePart.LeftSurface = "Studs"
missilePart.Locked = true
missilePart.RightSurface = "Studs"
missilePart.Size = Vector3.new(1, 1, 0.2)
missilePart.TopSurface = "Studs"
--missilePart.Transparency = 0.5
swooshSound.Looped = true
swooshSound.SoundId = "rbxasset://sounds/Rocket whoosh 01.wav"
swooshSound.Volume = 0.7
local magicCircleData = GraphicalEffects.CreateMagicCircle(headPosition + direction * 1000, 0.875, "rbxassetid://127033719", Color3.new(1, 1, 1),
40, 4, magic_circle_adornee_func or function() return chatAdornee end, magic_circle_offset)
local data = {0, missilePart, targetPart, time(), direction, false, false, bodyGyro, swooshSound, magicCircleData, 50, pointOnPart, flipped}
missilePart.Parent = Workspace
GraphicalEffects.missileData[data] = true
GraphicalEffects.missileParts[missilePart] = data
end
-- Joint crap
function GraphicalEffects.CubicInterpolate(y0, y1, y2, y3, mu)
local a0, a1, a2, a3, mu2
mu2 = mu * mu
a0 = y3 - y2 - y0 + y1
a1 = y0 - y1 - a0
a2 = y2 - y0
a3 = y1
return a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3
end
function GraphicalEffects.JointCrap(model, cycletime)
if model then
local cycletime = cycletime or (0.75 * (1 + math.random() * 4))
local offsetradius = 0.75
local rotationoffset = math.pi
local joints = {}
local stack = model:GetChildren()
while #stack ~= 0 do
local object = stack[#stack]
table.remove(stack)
for index, child in ipairs(object:GetChildren()) do
table.insert(stack, child)
end
if object:IsA("JointInstance") then
table.insert(joints, object)
end
end
local rot0 = {}
local rot1 = {}
local rot2 = {}
local rot3 = {}
local rot4 = {}
for index, joint in ipairs(joints) do
local pos = Vector3.new(math.random() - 0.5, math.random() - 0.5, math.random() - 0.5).unit * offsetradius
local rot = Vector3.new(math.random(), math.random(), math.random()) * rotationoffset
rot0[index] = {joint.C0, joint.C1}
rot = Vector3.new(rot.x % (math.tau), rot.y % (math.tau), rot.z % (math.tau))
rot2[index] = {pos, rot}
pos = Vector3.new(math.random() - 0.5, math.random() - 0.5, math.random() - 0.5).unit * offsetradius
rot = rot + Vector3.new(math.random(), math.random(), math.random()) * rotationoffset
rot = Vector3.new(rot.x % (math.tau), rot.y % (math.tau), rot.z % (math.tau))
rot3[index] = {pos, rot}
pos = Vector3.new(math.random() - 0.5, math.random() - 0.5, math.random() - 0.5).unit * offsetradius
rot = rot + Vector3.new(math.random(), math.random(), math.random()) * rotationoffset
rot = Vector3.new(rot.x % (math.tau), rot.y % (math.tau), rot.z % (math.tau))
rot4[index] = {pos, rot}
end
while model.Parent do
for i, j in ipairs(joints) do
local pos = Vector3.new(math.random() - 0.5, math.random() - 0.5, math.random() - 0.5).unit * offsetradius
local rot = rot4[i][2] + Vector3.new(math.random(), math.random(), math.random()) * rotationoffset
rot = Vector3.new(rot.x % (math.tau), rot.y % (math.tau), rot.z % (math.tau))
rot1[i], rot2[i], rot3[i], rot4[i] = rot2[i], rot3[i], rot4[i], {pos, rot}
end
local start = tick()
while true do
local ctime = tick()
local elapsed = ctime - start
if elapsed > cycletime then
break
end
local progress = elapsed / cycletime
for index, joint in ipairs(joints) do
local v0, v1, v2, v3, v4 = rot0[index], rot1[index], rot2[index], rot3[index], rot4[index]
local p1, p2, p3, p4, r1, r2, r3, r4 = v1[1], v2[1], v3[1], v4[1], v1[2], v2[2], v3[2], v4[2]
local px = GraphicalEffects.CubicInterpolate(p1.x, p2.x, p3.x, p4.x, progress)
local py = GraphicalEffects.CubicInterpolate(p1.y, p2.y, p3.y, p4.y, progress)
local pz = GraphicalEffects.CubicInterpolate(p1.z, p2.z, p3.z, p4.z, progress)
local rx = GraphicalEffects.CubicInterpolate(r1.x, r2.x, r3.x, r4.x, progress)
local ry = GraphicalEffects.CubicInterpolate(r1.y, r2.y, r3.y, r4.y, progress)
local rz = GraphicalEffects.CubicInterpolate(r1.z, r2.z, r3.z, r4.z, progress)
local cframe = CFrame.new(px, py, pz) * CFrame.Angles(rx, ry, rz)
joint.C0 = v0[1] * cframe
joint.C1 = v0[2] * cframe:inverse()
end
RunService.Stepped:wait()
end
end
end
end
-- Destruction spell
do
GraphicalEffects.destructionSpellSpeed = 5
GraphicalEffects.destructionSpellEffectSize = 2
GraphicalEffects.destructionSpellExplosionRate = 10
GraphicalEffects.destructionSpellFadeDuration = 120
local partProto = Instance.new("Part")
local partProtoDecal1 = Instance.new("Decal", partProto)
local partProtoDecal2 = Instance.new("Decal", partProto)
local partProtoGyro = Instance.new("BodyGyro", partProto)
local partProtoPosition = Instance.new("BodyPosition", partProto)
partProto.CanCollide = false
partProto.FormFactor = "Custom"
partProto.Transparency = 1
partProtoDecal1.Face = "Bottom"
partProtoDecal1.Texture = "rbxassetid://106508453"
partProtoDecal2.Face = "Top"
partProtoDecal2.Texture = "rbxassetid://106508453"
partProtoGyro.Name = "gyro"
partProtoGyro.P = 1e6
partProtoGyro.maxTorque = Vector3.new(1e9, 1e9, 1e9)
partProtoPosition.Name = "pos"
partProtoPosition.P = 1e4
partProtoPosition.maxForce = Vector3.new(1e9, 1e9, 1e9)
function GraphicalEffects.DestructionSpell(nodes)
local destroyTable = {}
local regionSizeX, regionSizeY, regionSizeZ
local function MagicalDestroyUnchecked(part)
local partSize = part.Size
if partSize.X < regionSizeX and partSize.Y < regionSizeY and partSize.Z < regionSizeZ then
destroyTable[part] = true
part.Material = "Plastic"
local beginTransparency = part.Transparency
local fadeDuration = GraphicalEffects.destructionSpellFadeDuration
for i = 1, fadeDuration do
RunService.Stepped:wait()
part.Transparency = beginTransparency + (1 - beginTransparency) * (i / fadeDuration)
end
pcall(Game.Destroy, part)
destroyTable[part] = nil
end
end
local function MagicalDestroy(part)
if not destroyTable[part] then
MagicalDestroyUnchecked(part)
end
end
local function MagicalNodeFinalize(part, gyro, pos, conn)
part.Anchored = true
pcall(gyro.Destroy, gyro)
pcall(pos.Destroy, pos)
conn:disconnect()
end
local model = Instance.new("Model")
model.Archivable = false
model.Name = "Nolix Wrath"
model.Parent = Workspace
local connections = {}
local parts = {}
local partsHit = {}
local cleanupList = {}
local explosionRate = GraphicalEffects.destructionSpellExplosionRate
local effectSize = GraphicalEffects.destructionSpellEffectSize
partProto.Size = Vector3.new(effectSize, 0.2, effectSize)
local speed = GraphicalEffects.destructionSpellSpeed
local rateTimer = 0
local partRotation = CFrame.Angles(0, 0.5 * math.pi, 0)
local minX, minY, minZ, maxX, maxY, maxZ = math.huge, math.huge, math.huge, -math.huge, -math.huge, -math.huge
for index = 4, #nodes do
local v0, v1, v2, v3 = nodes[index - 3], nodes[index - 2], nodes[index - 1], nodes[index]
local p1 = v1
local count = math.ceil((v2 - v1).magnitude / effectSize)
local linearStep = (v2 - v1) / count
for i = 1, count do
local alpha = i / count
local p2 = GraphicalEffects.CubicInterpolate(v0, v1, v2, v3, alpha)
local center = 0.5 * (p1 + p2)
local offset = p2 - p1
local partId = #parts + 1
local hitList = {}
partsHit[partId] = hitList
local part = partProto:Clone()
local gyro = part.gyro
local pos = part.pos
local cframe = CFrame.new(center, center + offset) * partRotation
part.CFrame = cframe
gyro.cframe = cframe
pos.position = center
local posX, posY, posZ = center.X, center.Y, center.Z
if posX < minX then minX = posX end
if posY < minY then minY = posY end
if posZ < minZ then minZ = posZ end
if posX > maxX then maxX = posX end
if posY > maxY then maxY = posY end
if posZ > maxZ then maxZ = posZ end
Instance.new("BlockMesh", part).Scale = Vector3.new(offset.magnitude, 0, effectSize)
parts[partId] = part
destroyTable[part] = true
local conn = part.Touched:connect(function(hit)
if not destroyTable[hit] then
hitList[hit] = true
end
end)
part.Parent = model
p1 = p2
TaskScheduler.Schedule(0.125, MagicalNodeFinalize, part, gyro, pos, conn)
rateTimer = rateTimer + 1
while rateTimer >= speed do
RunService.Stepped:wait()
rateTimer = rateTimer - speed
end
end
end
local center = Vector3.new(minX + maxX, minY + maxY, minZ + maxZ) * 0.5
regionSizeX, regionSizeY, regionSizeZ = maxX - minX, maxY - minY, maxZ - minZ
wait(0.5)
rateTimer = 0
for index, part in pairs(parts) do
if index % explosionRate == 1 then
local partSize = part.Size
if partSize.X < regionSizeX and partSize.Y < regionSizeY and partSize.Z < regionSizeZ then
local explosion = Instance.new("Explosion")
explosion.BlastPressure = 0
local position = part.Position
explosion.BlastRadius = (position - center).magnitude * 0.5
explosion.Position = (position + center) * 0.5
connections[#connections + 1] = explosion.Hit:connect(MagicalDestroy)
explosion.Parent = model
end
end
pcall(part.Destroy, part)
destroyTable[part] = nil
local hitList = partsHit[index]
for hit in pairs(hitList) do
local partSize = hit.Size
if partSize.X < regionSizeX and partSize.Y < regionSizeY and partSize.Z < regionSizeZ
and hit.Parent and not destroyTable[hit] then
TaskScheduler.Start(MagicalDestroyUnchecked, hit)
local explosion = Instance.new("Explosion")
explosion.BlastPressure = 0
explosion.BlastRadius = hit:GetMass() ^ (1 / 3) * 2
explosion.Position = hit.Position
connections[#connections + 1] = explosion.Hit:connect(MagicalDestroy)
explosion.Parent = model
end
end
rateTimer = rateTimer + 1
while rateTimer >= 4 * speed do
RunService.Stepped:wait()
rateTimer = rateTimer - 4 * speed
end
end
wait(0.25)
for _, connection in ipairs(connections) do
connection:disconnect()
end
end
end
-- MainLoop
function GraphicalEffects.MainLoop()
RunService.Stepped:wait()
for data in pairs(GraphicalEffects.magicCircleData) do
GraphicalEffects.AnimateMagicCircle(data)
end
for data in pairs(GraphicalEffects.laser_data) do
GraphicalEffects.AnimateLaserOfDeath(data)
end
for data in pairs(GraphicalEffects.missileData) do
GraphicalEffects.AnimateMissile(data)
end
end
TaskScheduler.Start(function()
while true do
GraphicalEffects.MainLoop()
end
end)
ChatBubble = {};
local FONT_CUSTOM_A_SRC, FONT_CUSTOM_A, TextAlignment, LoadFixedFont, LoadFont, DrawTextNetwork, DrawMultilineTextNetwork, ConfigureChatBubble,
CreateChatBubble, WrapText, chat_bubbles
FONT_CUSTOM_A_SRC = "03E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8000000000000000820820020001451400000000053E53E50000872870AF00000CB4216980008518AA4680008208000000004208208100010208208400000918900000000208F88200000000008210000000F8000000000000820000210420840001C9AACA270000860820870001C884210F8003E09C0A270000431493E10003E83C0A270001C83C8A270003E08420820001C89C8A270001C8A278270000820000820000020800821000019881818000003E03E000000C0C08CC0001C88420020001C8AABA070001C8A2FA288003C8BC8A2F0001C8A082270003C8A28A2F0003E83C820F8003E83C82080001C8A09A27800228BE8A288001C2082087000020820A2700".."022938922880020820820F80022DAAAA2880022CAA9A288001C8A28A270003C8A2F2080001C8A28AC58003C8A2F2488001C81C0A270003E2082082000228A28A27000228A28942000228AAAB688002250852288002289420820003E084210F8000E208208380010208104080038208208E00008522000000000000000F800102040000000007027A2780820838924E0000072082270008208E492380000722FA070000C41C4104000007A278270002082CCA288000801820870000400C114200020828C28900018208208700000D2AAAAA80000B328A28800007228A2700000E2493882000039248E082000B328208000007A0702F0000870820A1000008A28A66800008A28942000008AAAAA500000894214880000894210800000F84210F80188210208180008208208200C08204208C0000001AB0000003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F80".. "03E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F80".. "03E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F8003E8A28A2F80"
FONT_CUSTOM_A = {}
ChatBubble.THEME = {}
ChatBubble.THEME.AQUA = {
Name = "Aqua",
Background = Color3.new(0, 1 / 3, 0.5),
Foreground = Color3.new(2 / 3, 1, 1)
}
ChatBubble.THEME.CLASSIC = {
Name = "Classic",
Background = Color3.new(0, 0, 0),
Foreground = Color3.new(1, 1, 1)
}
ChatBubble.THEME.CRIMSON = {
Name = "Crimson",
Background = Color3.new(0, 0, 0),
Foreground = Color3.new(0.9, 0, 0)
}
ChatBubble.THEME.GRAPE = {
Name = "Grape",
Background = Color3.new(0.25, 0, 0.25),
Foreground = Color3.new(1, 2 / 3, 1)
}
ChatBubble.THEME.LIBERATION = {
Name = "Liberation",
Background = Color3.new(1 / 6, 3 / 7, 3 / 7),
Foreground = Color3.new(1, 1, 1)
}
ChatBubble.THEME.PASSION = {
Name = "Passion",
Background = Color3.new(0.5, 0, 0),
Foreground = Color3.new(1, 1, 1)
}
ChatBubble.THEME.PURPLE = {
Name = "Purple",
Background = Color3.new(0.25, 0, 0.25),
Foreground = Color3.new(1, 1, 1)
}
ChatBubble.THEME.RAINBOW = {
Name = "Rainbow",
Background = function(bubble_info)
local billboard, frame = bubble_info[5], bubble_info[6]
TaskScheduler.Start(function()
while billboard:IsDescendantOf(Workspace) do
local red, green, blue = Utility.GetRainbowRGB(tick())
frame.BackgroundColor3 = Color3.new(0.6 * red, 0.6 * green, 0.65 * blue)
RunService.Stepped:wait()
end
end)
end,
Foreground = Color3.new(1, 1, 1)
}
ChatBubble.THEME.TEAL = {
Name = "Teal",
Background = Color3.new(0, 1 / 3, 0.5),
Foreground = Color3.new(1, 1, 1)
}
function ChatBubble.GetTheme()
return ChatBubble.theme_info
end
function ChatBubble.SetTheme(theme_info)
if type(theme_info) == "string" then
theme_info = string.lower(theme_info)
for key, info in pairs(ChatBubble.THEME) do
if info.Name:lower():match(theme_info) then
ChatBubble.SetTheme(info)
break
end
end
return
end
ChatBubble.theme_info = theme_info
ChatBubble.background_color = theme_info.Background
ChatBubble.font = LoadFont(ChatBubble.FONT_DEFAULT, theme_info.Foreground)
Logger.printf("Info", "Theme has been set to %q in ChatBubble", theme_info.Name)
end
do
local floor = math.floor
local max = math.max
local asc = string.byte
local chr = string.char
local find = string.find
local gmatch = string.gmatch
local sub = string.sub
local insert = table.insert
local type = type
local unpack = unpack
local PopIntegerBit
TextAlignment = setmetatable({
[0] = 0,
[1] = 1,
[2] = 2,
Left = 0,
Center = 1,
Right = 2
}, {
__call = function(self, ...)
local argc = #{...}
if argc == 0 then
return 0
else
local arg = (...)
local value = rawget(self, arg)
if value then
return value
else
local arg_type = type(arg)
error("Invalid value" .. ((arg_type == "number") and (" " .. arg) or ((arg_type == "string") and (" \"" .. arg .. "\"") or
"")) .. " for enum TextAlignment")
end
end
end
})
function PopIntegerBit(value, bit)
if value >= bit then
return 1, value - bit
else
return 0, value
end
end
function LoadFixedFont(dest, src, height, width)
local n = #src / 64 - 1
local bit_index = 0
local symbol_bits = width * height
for i = 0, 255 do
local char_data = {}
for j = 1, height do
char_data[j] = {}
end
dest[i] = char_data
end
for i = 1, #src do
local buffer = tonumber(sub(src, i, i), 16)
for j = 1, 4 do
local code = floor(bit_index / symbol_bits)
local row = floor(bit_index / width) % height + 1
local column = bit_index % width + 1
dest[code][row][column], buffer = PopIntegerBit(buffer, 8)
buffer = buffer * 2
bit_index = bit_index + 1
end
end
end
function LoadFont(font_data, color)
local font_obj = {}
for character, char_data in pairs(font_data) do
local code = character
if type(code) ~= "number" then
code = asc(character)
end
local height = #char_data
local width = #char_data[1]
local pixel_h = 1 / height
local pixel_w = 1 / width
local pixel_size = UDim2.new(pixel_w, 0, pixel_h, 0)
local frame = Instance.new("Frame")
frame.BackgroundTransparency = 1
frame.Name = ""
for y = 1, height do
local row = char_data[y]
for x = 1, width do
local opacity = row[x]
if opacity ~= 0 then
local pixel = Instance.new("Frame", frame)
pixel.BackgroundColor3 = color
pixel.BorderSizePixel = 0
pixel.Name = ""
pixel.Position = UDim2.new(x * pixel_w, 0, y * pixel_h, 0) - pixel_size
pixel.Size = pixel_size -- + UDim2.new(0, 0, 0, 1) -- correction
-- ^ never mind that correction, fixed by changing font size to 12x16 instead of 13x17
if opacity then
pixel.BackgroundTransparency = 1 - opacity
end
end
end
end
font_obj[code] = {frame, height, width}
end
return font_obj
end
function DrawTextNetwork(text, font, size, delay_offset)
if #text == 0 then
text = " "
end
local frame = Instance.new("Frame")
frame.BackgroundTransparency = 1
frame.BorderSizePixel = 0
local objects = {}
local length = #text
local height = 0
local width = 0
for i = 1, length do
local character = sub(text, i, i)
local code = asc(character)
local char_data = assert(font[code] or FONT_SYMBOL_MISSING, "FONT ERROR: '" .. character .. "' (" .. code .. ") not found")
local char_proto, char_h, char_w = unpack(char_data)
objects[i] = char_data
height = max(char_h, height)
width = width + char_w
end
local offset = 0
local punctuation_delay = 0
for i = 1, length do
delay(delay_offset + (i + punctuation_delay - 1) / 30, function()
local char_data = objects[i]
local char_proto, char_h, char_w = unpack(char_data)
local char_obj = char_proto:Clone()
char_obj.Position = UDim2.new(offset / width, 0, 0, 0)
char_obj.Size = UDim2.new(char_w / width, 0, 1, 0)
char_obj.Parent = frame
offset = offset + char_w
end)
local character = sub(text, i, i)
if character == "." then
punctionation_delay = punctuation_delay + 3
elseif character == "?" or character == "!" then
punctionation_delay = punctuation_delay + 2
elseif character == ";" or character == "~" then
punctionation_delay = punctuation_delay + 1
end
end
local ratio = (height == 0) and (0) or (width / height)
frame.Size = UDim2.new(size.X.Scale * ratio, size.X.Offset * ratio, size.Y.Scale, size.Y.Offset)
return frame, height, width, (length + punctuation_delay) / 30
end
function DrawMultilineTextNetwork(text, font, size, delay_offset, ...)
local align = TextAlignment(...)
local frame = Instance.new("Frame")
frame.BackgroundTransparency = 1
frame.BorderSizePixel = 0
local height = 0
local width = 0
local objects = {}
for line in gmatch(text .. "\n", "([^\n]*)\n") do
local line_obj, line_h, line_w, line_delay = DrawTextNetwork(line, font, size, delay_offset)
insert(objects, {line_obj, line_h, line_w})
height = height + line_h
width = max(line_w, width)
delay_offset = delay_offset + line_delay
end
local offset = 0
for index, line_data in ipairs(objects) do
local line_obj, line_h, line_w = unpack(line_data)
local align_offset
if align == TextAlignment.Left then
align_offset = 0
elseif align == TextAlignment.Center then
align_offset = 0.5 - line_w / width / 2
elseif align == TextAlignment.Right then
align_offset = 1 - line_w / width
end
line_obj.Position = UDim2.new(align_offset, 0, offset / height, 0)
line_obj.Parent = frame
offset = offset + line_h
end
local line_count = #objects
local ratio = (height == 0) and (0) or (line_count * width / height)
frame.Size = UDim2.new(size.X.Scale * ratio, size.X.Offset * ratio, size.Y.Scale * line_count, size.Y.Offset * line_count)
return frame, height, width
end
end
LoadFixedFont(FONT_CUSTOM_A, FONT_CUSTOM_A_SRC, 8, 6)
ChatBubble.FONT_DEFAULT = FONT_CUSTOM_A
ChatBubble.SetTheme("Classic")
chat_bubbles = {}
function CreateChatBubble(bubble_info)
local creation_time, text, backup = bubble_info[1], bubble_info[2], bubble_info[8]
local billboard, frame, label
if backup and false then
billboard = backup:Clone()
frame = billboard.Frame
label = frame.Label
bubble_info[5] = billboard
bubble_info[6] = frame
bubble_info[7] = label
billboard.Parent = Workspace
else
label = DrawMultilineTextNetwork(text, bubble_info[9], UDim2.new(0, 12, 0, 16), creation_time - time(), "Center")
label.Name = "Label"
label.Position = UDim2.new(0, 16, 0, 16)
billboard = Instance.new("BillboardGui", Workspace)
billboard.Adornee = chatAdornee
billboard.AlwaysOnTop = true
billboard.Size = UDim2.new(label.Size.X.Scale, label.Size.X.Offset + 32, label.Size.Y.Scale, label.Size.Y.Offset + 32)
billboard.SizeOffset = Vector2.new(0, 0)
billboard.StudsOffset = Vector3.new(0, 1, 0)
frame = Instance.new("Frame", billboard)
bubble_info[5] = billboard
bubble_info[6] = frame
bubble_info[7] = label
local background_color = bubble_info[10]
if type(background_color) == "function" then
background_color(bubble_info)
else
frame.BackgroundColor3 = background_color
end
frame.BackgroundTransparency = 0.3
frame.BorderSizePixel = 0
frame.ClipsDescendants = true
frame.Name = "Frame"
frame.Size = UDim2.new(1, 0, 0, 0)
label.Parent = frame
-- bubble_info[8] = billboard:Clone()
end
end
local tween_time = 0.3
function ConfigureChatBubble(bubble_info)
local creation_time, destruction_time, billboard, frame = bubble_info[1], bubble_info[3], bubble_info[5], bubble_info[6]
if not billboard or billboard.Parent ~= workspace then
CreateChatBubble(bubble_info)
billboard, frame = bubble_info[5], bubble_info[6]
end
if billboard.Adornee ~= chatAdornee then
billboard.Adornee = chatAdornee
end
local current_time = time()
local elapsed_time = current_time - creation_time
local remaining_time = destruction_time - current_time
if remaining_time < 0 then
bubble_info[4] = false
billboard:Destroy()
return false
elseif remaining_time < tween_time then
local tween_progress = math.sin(remaining_time * math.pi / (tween_time * 2))
frame.Size = UDim2.new(1, 0, tween_progress, 0)
elseif elapsed_time < tween_time then
local tween_progress = math.sin(elapsed_time * math.pi / (tween_time * 2))
frame.Size = UDim2.new(1, 0, tween_progress, 0)
elseif frame.Size ~= UDim2.new(1, 0, 1, 0) then
frame.Size = UDim2.new(1, 0, 1, 0)
end
return true
end
function ChatBubble.MainLoop()
local offset = 0
local removing = {}
for index, bubble_info in ipairs(chat_bubbles) do
if not ConfigureChatBubble(bubble_info) then
removing[#removing + 1] = index - #removing
else
local billboard, frame = bubble_info[5], bubble_info[6]
local billboard_h = billboard.Size.Y.Offset
local bubble_h = frame.Size.Y.Scale * billboard_h
offset = 8 + offset + bubble_h
billboard.SizeOffset = Vector2.new(0, offset / billboard_h - 0.5)
end
end
for index, bubble_index in ipairs(removing) do
table.remove(chat_bubbles, bubble_index)
end
RunService.Stepped:wait()
end
function WrapText(text, character_limit, line_length_limit)
if #text > character_limit then
text = string.sub(text, 1, character_limit - 3) .. "..."
end
local text_length = #text
local line_length = 0
local i = 0
while i <= text_length do
i = i + 1
local character = string.sub(text, i, i)
if character == "\t" then
local tabulation_size = 4 - line_length % 4
line_length = line_length + tabulation_size
if line_length >= line_length_limit then
tabulation_size = line_length - line_length_limit
line_length = 0
text_length = text_length + tabulation_size
text = string.sub(text, 1, i - 1) .. string.rep(" ", tabulation_size) .. "\n" .. string.sub(text, i + 1)
i = i + tabulation_size + 1
else
text_length = text_length + tabulation_size - 1
text = string.sub(text, 1, i - 1) .. string.rep(" ", tabulation_size) .. string.sub(text, i + 1)
i = i + tabulation_size - 1
end
elseif character == "\n" then
line_length = 0
else
line_length = line_length + 1
if line_length >= line_length_limit then
local k = i - line_length + 1
local success = false
for j = i, k, -1 do
if string.match(string.sub(text, j, j), "[ \t]") then
text = string.sub(text, 1, j - 1) .. "\n" .. string.sub(text, j + 1)
text_length = text_length + 1
success = true
break
end
end
if not success then
text = string.sub(text, 1, i) .. "\n" .. string.sub(text, i + 1)
text_length = text_length + 1
end
i = i + 1
line_length = 0
end
end
end
if #text > character_limit then
text = string.sub(text, 1, character_limit - 3) .. "..."
end
return text
end
function ChatBubble.Create(text, theme)
local text = WrapText(text, 200, 30)
local creation_time = time()
local bubble_info = {creation_time, text, creation_time + 6 + #text / 15, true}
local previousTheme
if theme then
previousTheme = ChatBubble.GetTheme()
ChatBubble.SetTheme(theme)
end
bubble_info[9] = ChatBubble.font
bubble_info[10] = ChatBubble.background_color
if previousTheme then
ChatBubble.SetTheme(previousTheme)
end
table.insert(chat_bubbles, 1, bubble_info)
end
TaskScheduler.Start(function()
while true do
ChatBubble.MainLoop()
end
end)
ControllerCommands = {};
ControllerCommands.BALEFIRE_SPEED = 40
function ControllerCommands.BalefireAtMouse()
local head = chatAdornee
if head then
local target = Mouse.Hit.p
local origin = head.Position
local direction = (target - origin).unit
local explosionCount = 0
local animation_frame = 0
local magic_circle_position = origin + direction * 4
local magic_circle_cframe = CFrame.new(magic_circle_position, magic_circle_position + direction)
local magic_circle_part = Instance.new("Part")
local magic_circle_mesh = Instance.new("BlockMesh", magic_circle_part)
local magic_circle_light = Instance.new("PointLight", magic_circle_part)
local magic_circle_decal_back = Instance.new("Decal", magic_circle_part)
local magic_circle_decal_front = Instance.new("Decal", magic_circle_part)
magic_circle_part.Anchored = true
magic_circle_part.Archivable = false
magic_circle_part.BottomSurface = "Smooth"
magic_circle_part.CanCollide = false
magic_circle_part.CFrame = magic_circle_cframe
magic_circle_part.FormFactor = "Custom"
magic_circle_part.Locked = true
magic_circle_part.Size = Vector3.new(0.2, 0.2, 0.2)
magic_circle_part.TopSurface = "Smooth"
magic_circle_part.Transparency = 1
magic_circle_mesh.Scale = Vector3.new(60, 60, 0)
magic_circle_light.Color = Color3.new(1, 0.5, 1)
magic_circle_light.Range = 16
magic_circle_light.Shadows = true
magic_circle_decal_back.Face = "Back"
magic_circle_decal_back.Texture = "rbxassetid://122610943"
magic_circle_decal_front.Face = "Front"
magic_circle_decal_front.Texture = "rbxassetid://122610943"
local function NextExplosion()
explosionCount = explosionCount + 1
Instance.new("Explosion", Workspace).Position = origin + direction * (explosionCount * 8 + 4)
end
local function AnimateMagicCircle()
animation_frame = animation_frame + 1
local transparency = (animation_frame / 40) ^ 3
if animation_frame == 40 then
pcall(Game.Destroy, magic_circle_part)
else
if magic_circle_part.Parent ~= Workspace then
pcall(Utility.SetProperty, magic_circle_part, "Parent", Workspace)
end
head = PlayerControl.GetHead()
if head then
magic_circle_position = head.Position + direction * 4
end
magic_circle_part.CFrame = CFrame.new(magic_circle_position, magic_circle_position + direction) * CFrame.Angles(0, 0,
math.tau * animation_frame / 40 * 1.5)
magic_circle_light.Brightness = 1 - transparency
magic_circle_decal_back.Transparency = transparency
magic_circle_decal_front.Transparency = transparency
end
end
magic_circle_part.Parent = Workspace
for i = 1, 40 do
Delay((i - 1) / ControllerCommands.BALEFIRE_SPEED, NextExplosion)
Delay((i - 1) / 30, AnimateMagicCircle)
end
for i = 1, 20 do
Delay((i - 1) / ControllerCommands.BALEFIRE_SPEED, NextExplosion)
end
end
end
function ControllerCommands.ControlRandomDummy()
local dummies = {}
local numDummies = 0
for _, character in ipairs(Workspace:GetChildren()) do
local name = tostring(character)
if name == "???" or name == "Dummy" then
local head, humanoid
for _, child in ipairs(character:GetChildren()) do
local className = child.ClassName
if className == "Part" and tostring(child) == "Head" then
head = child
if humanoid then
break
end
elseif className == "Humanoid" then
if child.Health > 0 then
humanoid = child
if head then
break
end
else
break
end
end
end
if head and humanoid then
numDummies = numDummies + 1
dummies[numDummies] = {character, head, humanoid}
end
end
end
if numDummies > 0 then
local dummy = dummies[math.random(numDummies)]
Player.Character = dummy[1]
chatAdornee = dummy[2]
Camera.CameraSubject = dummy[3]
Camera.CameraType = "Track"
end
end
function ControllerCommands.Decalify(textures, exclusion)
local objects = Workspace:GetChildren()
for _, object in ipairs(objects) do
if not exclusion[object] then
for _, child in ipairs(object:GetChildren()) do
objects[#objects + 1] = child
end
if object:IsA("BasePart") then
local texture = textures[math.random(#textures)]
local face_left = Instance.new("Decal", object)
face_left.Face = Enum.NormalId.Left
face_left.Texture = texture
local face_right = Instance.new("Decal", object)
face_right.Face = Enum.NormalId.Right
face_right.Texture = texture
local face_bottom = Instance.new("Decal", object)
face_bottom.Face = Enum.NormalId.Bottom
face_bottom.Texture = texture
local face_top = Instance.new("Decal", object)
face_top.Face = Enum.NormalId.Top
face_top.Texture = texture
local face_front = Instance.new("Decal", object)
face_front.Face = Enum.NormalId.Front
face_front.Texture = texture
local face_back = Instance.new("Decal", object)
face_back.Face = Enum.NormalId.Back
face_back.Texture = texture
end
end
end
end
function ControllerCommands.ShootMissileAroundMouse(amount, offset, delayTime)
local exclusionList = {}
local playerHead = PlayerControl.GetHead()
local playerTorso = PlayerControl.GetTorso()
if playerHead and playerTorso then
exclusionList[playerTorso] = true
local humanoid, torso = Utility.FindHumanoidClosestToRay(Mouse.UnitRay, exclusionList)
local targetPart, pointOnPart
if humanoid and torso then
targetPart, pointOnPart = torso, Vector3.new()
else
local target = Mouse.Target
if target then
targetPart, pointOnPart = target, target.CFrame:pointToObjectSpace(Mouse.Hit.p)
else
return
end
end
if targetPart then
delayTime = delayTime or 0
local index = 1
local targetPoint = targetPart.CFrame * pointOnPart
local rotation_offset_angles = math.tau * Vector3.new(math.random() - 0.5, math.random() - 0.5, 0).unit
local rotation_offset = CFrame.Angles(rotation_offset_angles.x, rotation_offset_angles.y, 0)
local angle_x = 0
local angle_x_step = math.tau / math.phi
for i = 1, 8 * amount do
angle_x = angle_x + angle_x_step
local direction = rotation_offset * (CFrame.Angles(0, math.tau * index / amount, 0) * CFrame.Angles(angle_x, 0, 0).lookVector)
local blocked = Workspace:FindPartOnRay(Ray.new(targetPoint, direction * offset), targetPart.Parent)
if not blocked then
local p0 = targetPart
local p1 = pointOnPart
local p2 = direction
local p3 = offset
GraphicalEffects.ShootMissile(p0, p1, p2, function() return p0 end, p3, true)
index = index + 1
if index > amount then
break
end
end
end
end
end
end
function ControllerCommands.BigLaser(target)
GraphicalEffects.ShootLaserOfDeath(target, {brickcolor = BrickColor.new("New Yeller"), duration = 80, fragmentation_size = 6, laser_scale = 30, light_color = Color3.new(1, 0.5, 0), magic_circle_image = "rbxassetid://126561317", magic_circle_scale = 1.5, sound_volume = 1, special_effects = BrickColor.new("Deep orange"), stay = 2})
end
function ControllerCommands.BigLaserAtMouse()
ControllerCommands.BigLaser(Mouse.Hit.p)
end
function ControllerCommands.ShootMissile(targetPart, pointOnPart, direction)
GraphicalEffects.ShootMissile(targetPart, pointOnPart, direction)
end
function ControllerCommands.ShootMissileAtMouse(amount, spread, delayTime)
local exclusionList = {}
local playerHead = PlayerControl.GetHead()
local playerTorso = PlayerControl.GetTorso()
if playerHead and playerTorso then
exclusionList[playerTorso] = true
local humanoid, torso = Utility.FindHumanoidClosestToRay(Mouse.UnitRay, exclusionList)
local targetPart, pointOnPart
if humanoid and torso then
targetPart, pointOnPart = torso, Vector3.new()
else
local target = Mouse.Target
if target then
targetPart, pointOnPart = target, target.CFrame:pointToObjectSpace(Mouse.Hit.p)
else
return
end
end
if targetPart then
local direction = (Mouse.Hit.p - playerHead.Position).unit
delayTime = delayTime or 0
for index = 1, amount do
local angles = math.tau * (index - 0.5) * spread / amount * Vector3.new(math.random() - 0.5, math.random() - 0.5, math.random() - 0.5).unit
TaskScheduler.Schedule(delayTime * (index - 1), ControllerCommands.ShootMissile, targetPart, pointOnPart, CFrame.Angles(angles.X, angles.Y, angles.Z) * direction)
end
end
end
end
local _ = string.char
function ControllerCommands.HugeExplosionOfDoom(position)
local connections = {}
local parts = {}
local cframe = CFrame.new(position)
local function ExplosionHit(part)
if part:GetMass() < 10000 and part.Parent ~= Camera then
parts[part] = true
part.Anchored = true
part:BreakJoints()
part.BrickColor = BrickColor.new("Instituational white")
end
end
for i = 1, 4 do
local quantity = 0.5 * i * (1 + i)
local fraction = math.tau / quantity
for x = 1, quantity do
for y = 1, quantity do
local explosion = Instance.new("Explosion")
connections[#connections + 1] = explosion.Hit:connect(ExplosionHit)
explosion.BlastRadius = 5
explosion.Position = cframe * (CFrame.Angles(fraction * x, fraction * y, 0) * Vector3.new((i - 1) * 6, 0, 0))
explosion.Parent = Workspace
end
end
wait(0.075)
end
for part in pairs(parts) do
for _, child in ipairs(part:GetChildren()) do
if child:IsA("BodyMover") then
child:Destroy()
end
end
local mass = part:GetMass()
local velocity = CFrame.Angles(math.tau * math.random(), math.tau * math.random(), 0) * Vector3.new(25, 0, 0)
local bodythrust = Instance.new("BodyThrust")
bodythrust.force = mass * -velocity
bodythrust.Parent = part
local bodyforce = Instance.new("BodyForce")
bodyforce.force = mass * Vector3.new(0, 196.2, 0)
bodyforce.Parent = part
part.Anchored = false
part.Reflectance = 1
part.RotVelocity = math.tau * Vector3.new(math.random() - 0.5, math.random() - 0.5, math.random() - 0.5)
part.Transparency = 0.5
part.Velocity = (part.CFrame - part.Position) * velocity
end
for _, connection in ipairs(connections) do
connection:disconnect()
end
for i = 0, 99 do
Delay(i / 10, function()
for part in pairs(parts) do
local new_transparency = 0.5 * (1 + i / 50)
part.Reflectance = 0.98 * part.Reflectance
if new_transparency > part.Transparency then
part.Transparency = new_transparency
end
end
end)
end
Delay(10, function()
for part in pairs(parts) do
pcall(part.Destroy, part)
end
end)
end
function ControllerCommands.HugeExplosionOfDoomAtMouse()
ControllerCommands.HugeExplosionOfDoom(Mouse.Hit.p)
end
function ControllerCommands.SpaceHyperBeam(asd)
GraphicalEffects.SpaceHyperBeam(asd)
end
function ControllerCommands.SpaceHyperBeamAtMouse()
ControllerCommands.SpaceHyperBeam(Mouse.Hit.p)
end
function ControllerCommands.ConcentratedSpaceHyperBeamAtMouse()
local p = Mouse.Hit.p; for i = 1, 50 do GraphicalEffects.SpaceHyperBeam(p) end
end
ControllerCommands.MAX_SPACE_HYPER_BEAM_LENGTH = 20
ControllerCommands.SPACE_HYPER_BEAM_DELAY = 0.1
ControllerCommands.SPACE_HYPER_BEAM_SPACING = 20
ControllerCommands.SPACE_HYPER_BEAM_START_OFFSET = 20
function ControllerCommands.SpawnSapientRock(position)
GraphicalEffects.SpawnSapientRock(position)
end
function ControllerCommands.SpawnSapientRockAtMouse()
ControllerCommands.SpawnSapientRock(Mouse.Hit.p)
end
function ControllerCommands.TeleportCharacterToMouse()
if PlayerControl.IsEnabled() then
local torso = PlayerControl.GetTorso()
if torso then
local pos = Mouse.Hit.p + Vector3.new(0, 5, 0)
torso.CFrame = CFrame.new(pos, pos + torso.CFrame.lookVector)
end
else
local new_focus_position = Mouse.Hit.p
local direction_vector = Camera.CoordinateFrame.lookVector
local new_focus = CFrame.new(new_focus_position, new_focus_position + direction_vector)
Camera.CoordinateFrame = new_focus * CFrame.new(0, 0, 25)
Camera.Focus = new_focus
end
end
function ControllerCommands.FixLimbs(target)
local targetCaseInsensitive = Utility.CaseInsensitivePattern(target)
local character = PlayerControl.GetCharacter()
local user_torso = PlayerControl.GetTorso()
local objects = workspace:GetChildren()
for _, object in ipairs(objects) do
local humanoid
for _, child in ipairs(object:GetChildren()) do
objects[#objects + 1] = child
if child:IsA("Humanoid") then
humanoid = child
end
end
if humanoid and object.Name:lower():match(targetCaseInsensitive) then
local bc
for _, o in ipairs(object:GetChildren()) do
if o:IsA("BodyColors") then
bc = o
end
end
local fixing = false
local torso = object:FindFirstChild("Torso")
if torso and torso:IsA("Part") then
if not object:FindFirstChild("Left Arm") or not torso:FindFirstChild("Left Shoulder") then
fixing = true
local s = character["Left Arm"]:Clone()
local j = user_torso["Left Shoulder"]:Clone()
j.Part0 = torso
j.Part1 = s
j.CurrentAngle = 0
j.DesiredAngle = 0
j.MaxVelocity = 0
s.Anchored = true
s.BrickColor = bc and bc.LeftArmColor or BrickColor.Yellow()
local p1, r1 = s.Position, s.CFrame.lookVector
s.Parent = object
TaskScheduler.Start(function()
for i = 1, 30 do
RunService.Stepped:wait()
local a = i / 30
local c2 = torso.CFrame * j.C0 * j.C1:inverse()
local p = p1:Lerp(c2.p, a)
s.CFrame = CFrame.new(p, p + r1:Lerp(c2.lookVector, a))
end
s.Anchored = false
j.Parent = torso
end)
end
if not object:FindFirstChild("Right Arm") or not torso:FindFirstChild("Right Shoulder") then
fixing = true
local s = character["Right Arm"]:Clone()
local j = user_torso["Right Shoulder"]:Clone()
j.Part0 = torso
j.Part1 = s
j.CurrentAngle = 0
j.DesiredAngle = 0
j.MaxVelocity = 0
s.Anchored = true
s.BrickColor = bc and bc.RightArmColor or BrickColor.Yellow()
local p1, r1 = s.Position, s.CFrame.lookVector
s.Parent = object
TaskScheduler.Start(function()
for i = 1, 30 do
RunService.Stepped:wait()
local a = i / 30
local c2 = torso.CFrame * j.C0 * j.C1:inverse()
local p = p1:Lerp(c2.p, a)
s.CFrame = CFrame.new(p, p + r1:Lerp(c2.lookVector, a))
end
s.Anchored = false
j.Parent = torso
end)
end
if not object:FindFirstChild("Left Leg") or not torso:FindFirstChild("Left Hip") then
fixing = true
local s = character["Left Leg"]:Clone()
local j = user_torso["Left Hip"]:Clone()
j.Part0 = torso
j.Part1 = s
j.CurrentAngle = 0
j.DesiredAngle = 0
j.MaxVelocity = 0
s.Anchored = true
s.BrickColor = bc and bc.LeftLegColor or BrickColor.new("Br. yellowish green")
local p1, r1 = s.Position, s.CFrame.lookVector
s.Parent = object
TaskScheduler.Start(function()
for i = 1, 30 do
RunService.Stepped:wait()
local a = i / 30
local c2 = torso.CFrame * j.C0 * j.C1:inverse()
local p = p1:Lerp(c2.p, a)
s.CFrame = CFrame.new(p, p + r1:Lerp(c2.lookVector, a))
end
s.Anchored = false
j.Parent = torso
end)
end
if not object:FindFirstChild("Right Leg") or not torso:FindFirstChild("Right Hip") then
fixing = true
local s = character["Right Leg"]:Clone()
local j = user_torso["Right Hip"]:Clone()
j.Part0 = torso
j.Part1 = s
j.CurrentAngle = 0
j.DesiredAngle = 0
j.MaxVelocity = 0
s.Anchored = true
s.BrickColor = bc and bc.RightLegColor or BrickColor.new("Br. yellowish green")
local p1, r1 = s.Position, s.CFrame.lookVector
s.Parent = object
TaskScheduler.Start(function()
for i = 1, 30 do
RunService.Stepped:wait()
local a = i / 30
local c2 = torso.CFrame * j.C0 * j.C1:inverse()
local p = p1:Lerp(c2.p, a)
s.CFrame = CFrame.new(p, p + r1:Lerp(c2.lookVector, a))
end
s.Anchored = false
j.Parent = torso
end)
end
if fixing then
TaskScheduler.Schedule(1, function()
local anim = object:FindFirstChild("Animate")
if anim and anim.ClassName == "LocalScript" then
anim.Disabled = true
wait(0.5)
anim.Disabled = false
end
end)
end
end
end
end
end
REWRITE_VARS.Commands = {};
REWRITE_VARS.Keybindings = {};
GetPlayers=function(msg)
local found = {};
for _,plr in pairs(Players:children()) do
if string.match(plr.Name, msg) then
table.insert(found, plr)
end
end
return found
end
NewCommand=function(nme, usg, func)
table.insert(REWRITE_VARS.Commands, {['Name']=nme, ['Usage']=usg, ['Function']=func})
end
NewKey=function(nme, key, mainFunc, func)
table.insert(REWRITE_VARS.Keybindings, {['Name']=nme, ['Key']=key, ['Main']=mainFunc, ['Function']=func})
end
REWRITE_VARS.onChatted=function(msg)
if string.sub(msg,1,1) == ";" then
for _,cmd in pairs(REWRITE_VARS.Commands) do
local tosay = ";"..cmd['Usage']
if string.sub(msg,1,string.len(tosay)) == tosay then
cmd.Function(string.sub(msg,string.len(tosay)+2))
end
end
else
ChatBubble.Create(msg)
end
end
REWRITE_VARS.onButtonClick=function()
for _,key in pairs(REWRITE_VARS.Keybindings) do
if UserInterface:IsKeyDown(Enum.KeyCode.LeftControl) and UserInterface:IsKeyDown(Enum.KeyCode.LeftShift) and UserInterface:IsKeyDown(Enum.KeyCode[key.Key]) and key['Main'] == false then
key.Function()
elseif UserInterface:IsKeyDown(Enum.KeyCode.LeftControl) and UserInterface:IsKeyDown(Enum.KeyCode[key.Key]) and key['Main'] == true then
key.Function()
end
end
end
NewCommand("PyramidChar", "pyr", function(args) PlayerControl.characterMode = PlayerControl.characterMode == "pyramid" and "normal" or "pyramid" end)
NewKey("Dummy", "Z", true, function() Utility.CreateDummy(Mouse.Hit, "???", Workspace) end)
NewKey("Flying", "G", true, function() if flying then PlayerControl.StopFlying() else PlayerControl.StartFlying() end end)
NewCommand("Chat theme", "ctheme", function(msg) ChatBubble.SetTheme(msg) end)
NewCommand("Reset control", "resetc", function() if not game.Players:FindFirstChild(Player.Name) then chatAdornee = PlayerControl.GetHead() Camera.CameraSubject = PlayerControl.GetHead() Player.Humanoid = PlayerControl.GetHumanoid() else chatAdornee = game.Players[Player.Name].Character.Head end end)
NewCommand("Set char name", "setname", function(msg) REWRITE_VARS.custom_char_name = msg end)
NewCommand("Set char id", "setid", function(msg) if tonumber(msg) == 1 or tonumber(msg) == 2 or tonumber(msg) == 3 then CharacterAppearance.defaultAppearanceId = tonumber(msg) end end)
NewCommand("Get Building Tools", "btools", function(msg) Utility.GetBuildingTools() end)
NewCommand("FixLimbs", "flimbs", function(msg) local plrs = GetPlayers(msg) for _,plr in pairs(plrs) do ControllerCommands.FixLimbs(plr.Name) end end)
NewCommand("Kick", "kick", function(msg) local plrs = GetPlayers(msg) for _,plr in pairs(plrs) do GraphicalEffects.CrystalRing({base_part = plr.Character.Torso, crystal_color = BrickColor.new("Really black"), float_duration = 1}) plr:remove() end end)
NewCommand("Disc", "disc", function(msg) local plrs = GetPlayers(msg) for _,plr in pairs(plrs) do GraphicalEffects.CrystalRing({base_part = plr.Character.Torso, crystal_color = BrickColor.new("Royal purple"), float_duration = 1}) rf:InvokeServer("game."..plr:GetFullName()..":Kick('You were disconnected by TEST Secruity.')") end end)
NewKey("Laser", "X", true, function() GraphicalEffects.ShootLaserOfDeath(Mouse.Hit.p) end)
NewKey("Destroy", "Y", false, function() local targ = Mouse.Target GraphicalEffects.CrystalRing({base_part = targ, crystal_color = BrickColor.new("Really black"), float_duration = 1}) targ:remove() targ=nil; end)
NewKey("SLaser", "C", true, function() GraphicalEffects.SpaceHyperBeam(Mouse.Hit.p) end)
NewKey("Balefire", "B", true, function() ControllerCommands.BalefireAtMouse() end)
NewKey("Missiles", "Y", true, function() ControllerCommands.ShootMissileAroundMouse(19, 50, 1 / 19) end)
NewKey("BigLaser", "F", true, function() ControllerCommands.BigLaserAtMouse() end)
NewKey("Possess", "V", true, function() chatAdornee = Mouse.Target end)
NewKey("Rock", "R", true, function() ControllerCommands.SpawnSapientRockAtMouse() end)
NewKey("Teleport", "T", true, function() ControllerCommands.TeleportCharacterToMouse() end)
NewKey("ShowHide", "Q", true, function() for _,p in pairs(game.Workspace:children()) do if p.Name == REWRITE_VARS.custom_char_name then p:remove() end end PlayerControl.SetEnabled(not PlayerControl.IsEnabled()) end)
Mouse.Button1Down:connect(REWRITE_VARS.onButtonClick)
Player.Chatted:connect(REWRITE_VARS.onChatted)
ChatBubble.Create("Loaded TEST Nil, Verison "..REWRITE_VARS.GKVersion)
ChatBubble.Create("TEST is created and fixed by gavinsharp100.")
ChatBubble.Create("Thank you for using TEST")
--[[
--]]