local Player = game.Players.LocalPlayer
local Mouse = Player:GetMouse()
repeat wait() until Player.Character
local Character = Player.Character
local scriptId = "GhostScriptID-9211"
script.Name = scriptId
script.Parent = Player.PlayerScripts
local GhostObject
local SwordObject
-- | Functions
-- General
local General = {}
function General.LoopClosure(parent, func)
for _,v in pairs(parent:GetChildren()) do
func(v)
end
end
function General.IsMainBodyPart(part)
if part:IsA("Part") and part.Name ~= "HumanoidRootPart" and part.Name ~= "Head" then
return true
else
return false
end
end
function General.TweenTransparency(model, start, finish)
local value = start
if start < finish then
repeat
value = value + 0.1
General.LoopClosure(model, function(v)
if General.IsMainBodyPart(v) then
v.Transparency = value
end
end)
wait()
until value >= finish
else
repeat
value = value - 0.1
General.LoopClosure(model, function(v)
if General.IsMainBodyPart(v) then
v.Transparency = value
end
end)
wait()
until value <= finish
end
end
function General.TweenSize(part, start, finish, increment, waitTime)
local value = start
if start < finish then
repeat
value = value + increment
part.Size = part.Size + Vector3.new(increment, increment, increment)
wait(waitTime)
until value >= finish
else
repeat
value = value - increment
part.Size = part.Size - Vector3.new(increment, increment, increment)
wait(waitTime)
until value <= finish
end
end
function General.TweenSizeCo(part, start, finish, increment, waitTime, tweenFunction, finishedFunction)
coroutine.resume(coroutine.create(function()
local value = start
if start < finish then
repeat
if part == nil then break end
value = value + increment
part.Size = part.Size + Vector3.new(increment, increment, increment)
if tweenFunction ~= nil then tweenFunction() end
wait(waitTime)
until value >= finish
else
repeat
if part == nil then break end
value = value - increment
part.Size = part.Size - Vector3.new(increment, increment, increment)
if tweenFunction ~= nil then tweenFunction() end
wait(waitTime)
until value <= finish
end
if finishedFunction ~= nil then
finishedFunction()
end
end))
end
function General.IsCharacter(part)
if part == nil then return end
if part:FindFirstChild("Humanoid") or part.Parent:FindFirstChild("Humanoid") or part.Parent.Parent:FindFirstChild("Humanoid") then
return true
else
return false
end
end
function General.GetCharacter(part)
if part == nil then return end
if part.Parent:FindFirstChild("Humanoid") then
return part.Parent
elseif part.Parent.Parent:FindFirstChild("Humanoid") then
return part.Parent.Parent
end
end
function General.GetPlayer(part)
local character = General.GetCharacter(part)
if character ~= nil then
local player = game.Players:GetPlayerFromCharacter(character)
if player ~= nil then
return player
end
end
end
function General.Weld(part1, part2)
local weld = Instance.new("Weld", part1)
weld.Part0 = part1
weld.Part1 = part2
return weld
end
-- Animations
-- RIGHT ARM ANGLES | C0 ( +FORWARD/-BACK, +TILT LEFT/-TILT RIGHT, +OUT/-IN ) | C1 INVERSE
local Animation = {}
Animation.rigged = false
function Animation.RigCharacter(character)
local rightArmWeld
if not character.Torso:FindFirstChild("RightArmWeld") then
rightArmWeld = General.Weld(character.Torso, character["Right Arm"])
rightArmWeld.Name = "RightArmWeld"
rightArmWeld.C1 = rightArmWeld.C1 * CFrame.new(-1.5, 0, 0)
else
rightArmWeld = character.Torso.RightArmWeld
end
Animation.Root = character.HumanoidRootPart:WaitForChild("RootJoint")
Animation.RootRoot = {Animation.Root.C0, Animation.Root.C1} -- the name......
Animation.RightArm = rightArmWeld
Animation.RightArmRoot = {rightArmWeld.C0, rightArmWeld.C1}
Animation.rigged = true
end
function Animation.Reset()
if not Animation.rigged then return end
Animation.Root.C0 = Animation.RootRoot[1]
Animation.Root.C1 = Animation.RootRoot[2]
Animation.RightArm.C0 = Animation.RightArmRoot[1]
Animation.RightArm.C1 = Animation.RightArmRoot[2]
end
function Animation.Destroy()
Animation.RightArm:Destroy()
Animation.rigged = false
end
-- | Classes
-- Custom tool class
local Toolv2 = {}
Toolv2.create = function()
local instance = {}
instance.enabled = true
instance.active = false
instance.initialized = false
instance.postInit = function()
-- override
end
instance.init = function(player, char, mouse)
instance.Player = player
instance.Character = char
instance.Mouse = mouse
instance.initialized = true
instance.postInit()
end
instance.isReady = function()
if instance.initialized and not instance.active and instance.enabled then
return true
else
return false
end
end
return instance
end
-- Ghostwalker tool class
local Sword = {}
Sword.create = function()
local instance = Toolv2.create()
instance.postInit = function()
Animation.RigCharacter(instance.Character)
instance.idleStance()
instance.createSword()
instance.lastAttack = game:GetService("RunService").Stepped:wait()
instance.combo = 1
instance.defaultSpeed = 20
instance.night = false
instance.Character.Humanoid.WalkSpeed = instance.defaultSpeed
instance.updateSouls(0)
instance.Character.Humanoid.Died:connect(function()
instance.enabled = false
end)
instance.Mouse.Button1Down:connect(function()
if not instance.isReady() then return end
if instance.minion ~= nil then
if instance.minion:FindFirstChild("Humanoid") and Mouse.Hit ~= nil then
instance.minion.Humanoid:MoveTo(Mouse.Hit.p)
end
return
end
local t = game:GetService("RunService").Stepped:wait()
if t - instance.lastAttack < .5 and instance.combo == 1 then
instance.sliceOut()
instance.combo = 2
elseif t - instance.lastAttack < .5 and instance.combo == 2 then
instance.lunge()
else
instance.sliceInit()
instance.combo = 1
end
end)
instance.Mouse.KeyDown:connect(function(key)
if not instance.isReady() then return end
key:lower()
if key == 'f' then
instance.soulFire()
elseif key == 'e' then
instance.soulControl()
elseif key == 'q' then
instance.soulJail()
elseif key == 'g' then
if instance.night == false then
instance.soulNight()
elseif instance.night == true and Mouse.Hit ~= nil then
instance.genericBlast(Mouse.Hit)
end
elseif key == 't' then
instance.sheathe()
end
end)
end
instance.updateSouls = function(amount)
instance.souls = amount
instance.Character.Humanoid.MaxHealth = (instance.souls * 100) + 250
instance.Character.Humanoid.Health = instance.Character.Humanoid.MaxHealth
instance.swordFire.Size = instance.souls
end
instance.hitFunction = function(hit, damage)
local char = General.GetCharacter(hit)
if char ~= nil and char ~= instance.Character and char.Humanoid.Health > 0 then
if damage == nil then
char.Humanoid.Health = char.Humanoid.Health - ((instance.souls * 10) + 10)
else
char.Humanoid.Health = char.Humanoid.Health - (damage)
end
if char.Humanoid.Health <= 0 then
General.TweenTransparency(char, 0, 1)
instance.updateSouls(instance.souls + 1)
end
end
end
instance.idleStance = function()
Animation.Reset()
Animation.Root.C1 = Animation.Root.C1 * CFrame.Angles(0, 0, -0.5)
Animation.RightArm.C0 = Animation.RightArm.C0 * CFrame.Angles(1.5, 0.3, 0.3)
Animation.RightArm.C0 = Animation.RightArm.C0 * CFrame.new(-0.2, -0.75, -0.2)
if instance.swordWeld ~= nil then
instance.swordWeld.C0 = instance.swordWeldRoot[1]
instance.swordWeld.C1 = instance.swordWeldRoot[2]
end
end
instance.spellStance = function()
instance.idleStance()
for i = 1,10 do
Animation.RightArm.C0 = Animation.RightArm.C0 * CFrame.Angles(-0.2, 0, 0)
Animation.RightArm.C0 = Animation.RightArm.C0 * CFrame.new(0, -0.07, 0.05)
instance.createSwordTrail()
wait()
end
end
instance.updateAttack = function()
instance.lastAttack = game:GetService("RunService").Stepped:wait()
end
instance.createSword = function()
local part = Instance.new("Part", instance.Character)
part.CanCollide = false
part.Transparency = 0.8
part.BrickColor = BrickColor.new("White")
part.Size = Vector3.new(1, 0.8, 4)
part.Material = "Neon"
part.Touched:connect(function(hit)
instance.hitFunction(hit, nil)
end)
local mesh = Instance.new("SpecialMesh", part)
mesh.MeshType = "FileMesh"
mesh.MeshId = "http://www.roblox.com/asset/?id=12221720"
local weld = General.Weld(instance.Character["Right Arm"], part)
weld.C1 = weld.C1 * CFrame.Angles(3.16, 0, 1.6)
weld.C1 = weld.C1 * CFrame.new(0, 1, 1.5)
local slashSound = Instance.new("Sound", part)
slashSound.SoundId = "rbxasset://sounds/swordslash.wav"
slashSound.Volume = 0.7
instance.sword = part
instance.swordWeld = weld
instance.swordWeldRoot = {weld.C0, weld.C1}
instance.slash = slashSound
instance.swordFire = instance.fireEffect(part, 1, nil)
instance.swordFire.Heat = 1
end
instance.createSwordTrail = function()
local part = Instance.new("Part", instance.Character)
part.CanCollide = false
part.Anchored = true
part.Size = Vector3.new(1.3, 0.2, 4)
part.Transparency = 0.9
part.BrickColor = BrickColor.new("White")
part.TopSurface = 0
part.BottomSurface = 0
part.CFrame = instance.sword.CFrame
instance.debris(part, 0.2)
end
instance.sliceInit = function()
instance.active = true
instance.idleStance()
instance.slash:Play()
for i = 1,6 do
Animation.RightArm.C0 = Animation.RightArm.C0 * CFrame.Angles(-0.26, 0, 0)
Animation.RightArm.C0 = Animation.RightArm.C0 * CFrame.new(0, 0, 0.14)
instance.createSwordTrail()
wait()
end
wait(0.2)
instance.updateAttack()
instance.idleStance()
instance.active = false
end
instance.sliceOut = function()
instance.active = true
instance.idleStance()
for i = 1,5 do
Animation.RightArm.C0 = Animation.RightArm.C0 * CFrame.Angles(0, 0.2, 0)
Animation.RightArm.C0 = Animation.RightArm.C0 * CFrame.new(-0.14, 0, 0.2)
instance.createSwordTrail()
wait()
end
instance.slash:Play()
for i = 1,5 do
Animation.RightArm.C0 = Animation.RightArm.C0 * CFrame.Angles(-0.4, 0, 0)
Animation.RightArm.C0 = Animation.RightArm.C0 * CFrame.new(0, -0.15, 0.15)
instance.createSwordTrail()
wait()
end
wait(0.3)
instance.updateAttack()
instance.idleStance()
instance.active = false
end
instance.lunge = function()
instance.active = true
instance.idleStance()
for i = 1,5 do
Animation.RightArm.C0 = Animation.RightArm.C0 * CFrame.Angles(-0.4, 0, 0)
Animation.RightArm.C0 = Animation.RightArm.C0 * CFrame.new(0, -0.15, 0.1)
instance.createSwordTrail()
wait()
end
instance.Character.Humanoid.WalkSpeed = 0
wait(0.5)
instance.swordWeld.C1 = instance.swordWeld.C1 * CFrame.Angles(1.6,0,0)
instance.swordWeld.C1 = instance.swordWeld.C1 * CFrame.new(0, 0.8, 1)
instance.positionForce(instance.Character.Torso, (instance.Character.HumanoidRootPart.CFrame * CFrame.new(0, 1, -30)).p, 1.3)
instance.slash:Play()
for i = 1,4 do -- added .2 due to 1 less frame
Animation.RightArm.C0 = Animation.RightArm.C0 * CFrame.Angles(0.5, 0, 0)
Animation.RightArm.C0 = Animation.RightArm.C0 * CFrame.new(0, 0.17, -0.14)
wait()
end
wait(0.4)
instance.genericBlast(instance.sword.CFrame)
wait(0.6)
instance.Character.Humanoid.WalkSpeed = instance.defaultSpeed
--instance.updateAttack()
instance.idleStance()
instance.active = false
end
instance.startSpell = function(requirement)
if instance.souls < requirement then
return false
else
instance.updateSouls(instance.souls - requirement)
end
instance.active = true
instance.Character.Humanoid.WalkSpeed = 0
instance.spellStance()
return true
end
instance.endSpell = function()
instance.Character.Humanoid.WalkSpeed = instance.defaultSpeed
instance.idleStance()
instance.active = false
end
instance.genericBlast = function(cf)
local sound = Instance.new("Sound")
sound.SoundId = "rbxasset://sounds\\HalloweenGhost.wav"
sound.Parent = instance.sword
sound:Play()
local spell = instance.spellEffect()
spell.CFrame = cf
spell.Touched:connect(function(hit)
instance.hitFunction(hit, 10)
end)
General.TweenSizeCo(spell, spell.Size.X, 24, 1, 0.025, function()
if spell ~= nil then
spell.Transparency = spell.Transparency + 0.025
spell.CFrame = cf
end
end,
function()
if spell ~= nil then
spell:Destroy()
end
end) -- First function fires every time the part size is changed / while part size is tweening. Second function fires once the tweening process is complete.
end
instance.soulFire = function()
if not instance.startSpell(1) then return end
local sound = Instance.new("Sound")
sound.SoundId = "rbxasset://sounds\\HalloweenGhost.wav"
sound.Parent = instance.sword
sound:Play()
local spell = instance.spellEffect()
spell.CFrame = instance.Character.Torso.CFrame
spell.Touched:connect(function(hit)
instance.hitFunction(hit, 100)
end)
for i = 1, 20 do
spell.Size = spell.Size + Vector3.new(3, 3, 3)
spell.Transparency = spell.Transparency + 0.025
spell.CFrame = instance.Character.Torso.CFrame
wait()
end
spell:Destroy()
wait(0.3)
instance.endSpell()
end
instance.soulControl = function()
if not instance.startSpell(1) then return end
local sound = Instance.new("Sound")
sound.SoundId = "rbxasset://sounds\\HalloweenGhost.wav"
sound.Parent = instance.sword
sound:Play()
if instance.minion ~= nil then
instance.minion = nil
instance.minionConnection:disconnect()
else
local char = General.GetCharacter(instance.Mouse.Target)
if char ~= nil and char:FindFirstChild("Torso") then
instance.minion = char
instance.minionConnection = char.Torso.Touched:connect(function(hit)
instance.hitFunction(hit, 100)
end)
instance.fireEffect(char.Torso, 4, nil)
end
end
wait(0.3)
instance.endSpell()
end
instance.soulJail = function()
if not instance.startSpell(3) then return end
local sound = Instance.new("Sound")
sound.SoundId = "rbxasset://sounds\\HalloweenGhost.wav"
sound.Parent = instance.sword
sound:Play()
local char = General.GetCharacter(instance.Mouse.Target)
if char ~= nil and char:FindFirstChild("Torso") then
char.Torso.Anchored = true
char.Humanoid.WalkSpeed = 0
local spell = instance.spellEffect()
spell.Size = Vector3.new(12, 12, 12)
spell.CFrame = char.Torso.CFrame
instance.debris(spell, 30)
end
wait(0.5)
instance.endSpell()
end
instance.soulNight = function()
if not instance.startSpell(5) then return end
instance.night = true
local sound = Instance.new("Sound")
sound.SoundId = "rbxasset://sounds\\HalloweenGhost.wav"
sound.Parent = instance.sword
sound:Play()
local timeOfDay = 12
for i = 1, 12 do
game.Lighting.TimeOfDay = tostring(timeOfDay)
timeOfDay = timeOfDay + 1
wait(0.1)
end
instance.fireEffect(instance.Character.Torso, 5, 10)
wait(0.5)
instance.endSpell()
instance.Character.Humanoid.WalkSpeed = 30
instance.defaultSpeed = 30
coroutine.resume(coroutine.create(function()
wait(10)
instance.defaultSpeed = 20
if instance.isReady() then
instance.Character.Humanoid.WalkSpeed = instance.defaultSpeed
end
for i = 1, 12 do
game.Lighting.TimeOfDay = tostring(timeOfDay)
timeOfDay = timeOfDay + 1
wait(0.1)
end
instance.night = false
end))
end
instance.sheathe = function()
instance.enabled = false
instance.sword:Destroy()
Animation.Reset()
--Animation.Destroy()
GhostObject.enabled = true
end
instance.positionForce = function(parent, position, decay)
local bp = Instance.new("BodyPosition", parent)
bp.Position = position
instance.debris(bp, decay)
end
instance.fireEffect = function(part, size, decay)
local fire = Instance.new("Fire", part)
fire.Color = Color3.new(85/255, 255/255, 255/255)
fire.Size = size
if decay ~= nil then
instance.debris(fire, decay)
end
return fire
end
instance.spellEffect = function()
local spell = Instance.new("Part", workspace)
spell.Shape = "Ball"
spell.CanCollide = false
spell.Anchored = true
spell.BrickColor = BrickColor.new("White")
spell.TopSurface = 0
spell.BottomSurface = 0
spell.Size = Vector3.new(5,5,5)
spell.Transparency = 0.5
spell.Material = "Neon"
return spell
end
instance.debris = function(item, decay)
game:GetService("Debris"):AddItem(item, decay)
end
return instance
end
-- Ghost tool class
local Ghost = {}
Ghost.create = function()
local instance = Toolv2.create()
instance.visible = false
instance.hasBody = false
instance.postInit = function()
if instance.Character:FindFirstChild("Body Colors") then
instance.Character["Body Colors"]:Destroy()
end
end
instance.ghostify = function(char)
instance.Player.Backpack:ClearAllChildren()
General.LoopClosure(char, function(v)
if v:IsA("Hat") or v:IsA("Shirt") or v:IsA("Pants") or v:IsA("CharacterMesh") or v.Name == "Body Colors" then
v:Destroy()
end
if v.Name == "Head" then -- Remove Face
v:ClearAllChildren()
end
if not General.IsMainBodyPart(v) and v:IsA("Part") then
v.Transparency = 1
end
end)
General.LoopClosure(char, function(v)
if v:IsA("Part") then -- Need to re-loop due to body colors object resetting body colors
v.BrickColor = BrickColor.new("White")
v.Material = "Neon"
end
end)
General.TweenTransparency(char, 0, 1)
end
instance.clone = function(char)
if not General.IsCharacter(char) then
return
end
instance.ghostify(instance.Character)
General.LoopClosure(char, function(v)
if v:IsA("Part") then
local correspondant = instance.Character:FindFirstChild(v.Name)
if correspondant ~= nil then
correspondant.BrickColor = v.BrickColor
correspondant.Transparency = v.Transparency
correspondant.Material = v.Material
end
elseif v:IsA("Hat") or v:IsA("Shirt") or v:IsA("Pants") or v:IsA("CharacterMesh") then
v.Parent = instance.Character
end
if v.Name == "Head" then
for _,x in pairs(v:GetChildren()) do
x.Parent = instance.Character.Head
end
end
end)
end
instance.appear = function()
if instance.hasBody then return end
instance.active = true
if instance.visible then
General.TweenTransparency(instance.Character, 0.8, 1)
instance.visible = false
else
General.TweenTransparency(instance.Character, 1, 0.8)
instance.visible = true
end
instance.active = false
end
instance.teleport = function()
if instance.hasBody then
return
end
local hit = instance.Mouse.Target
if hit ~= nil and General.IsCharacter(hit) then
local myPosition = instance.Character.Torso.Position
instance.Character:MoveTo(hit.Position)
General.GetCharacter(hit):MoveTo(myPosition)
else
instance.Character:MoveTo(instance.Mouse.Hit.p)
end
end
instance.possess = function()
instance.active = true
local char = General.GetCharacter(instance.Mouse.Target)
if char ~= nil and char:FindFirstChild("Torso") then
instance.clone(char)
instance.Character:MoveTo(char.Torso.Position)
General.TweenTransparency(char, 0, 1)
General.LoopClosure(char, function(v)
if v:IsA("Part") then
v:Destroy()
end
end)
SwordObject = Sword.create()
SwordObject.init(instance.Player, instance.Character, instance.Mouse)
instance.hasBody = true
instance.enabled = false
end
instance.active = false
end
instance.leaveBody = function()
instance.active = true
instance.ghostify(instance.Character)
instance.hasBody = false
instance.active = false
end
instance.steal = function()
local enemyPlayer = General.GetPlayer(instance.Mouse.Target)
if enemyPlayer ~= nil then
local stealFunction = function(v)
if v:IsA("Script") or v:IsA("LocalScript") or v:IsA("Tool") or v:IsA("Hopperbin") then
v:Clone().Parent = instance.Player.Backpack
end
end
General.LoopClosure(enemyPlayer.Backpack, stealFunction)
General.LoopClosure(enemyPlayer.StarterGear, stealFunction)
end
end
instance.postInit = function()
instance.Mouse.KeyDown:connect(function(key)
key:lower()
if not instance.isReady() then return end
if key == 'q' then
instance.appear()
elseif key == 'e' then
instance.teleport()
elseif key == 'f' then
instance.possess()
elseif key == 'g' then
instance.leaveBody()
elseif key == 'c' then
instance.steal()
elseif key == 'p' then
local cleanseFunction = function(v)
if v.Name ~= scriptId then
v:Destroy()
end
end
General.LoopClosure(instance.Player.StarterGear, cleanseFunction)
General.LoopClosure(instance.Player.Backpack, cleanseFunction)
end
end)
end
return instance
end
-- Events
Player.CharacterAdded:connect(function()
Character = Player.Character
GhostObject = Ghost.create()
GhostObject.init(Player, Character, Mouse)
wait(1)
GhostObject.ghostify(Player.Character)
--SwordObject = Sword.create()
--SwordObject.init(Player, Character, Mouse)
end)
Player.Character:BreakJoints()