--[[
Author: WelpNathan
Date: 31/05/2018
Script: This script will control how the SCP reacts to touching
and other interactions.
--]]
---------------------------
-- V A R I A B L E S --
---------------------------
-- ROBLOX Services
local players = game:GetService('Players')
local physicsService = game:GetService("PhysicsService")
local pathfindingService = game:GetService("PathfindingService")
-- Locate the physical SCP
local this = script.Parent.Parent:WaitForChild('PhysicalSCP')
-- Store the settings of the SCP
local settingsSCP = {
magnitudeMax = 500,
sound = {
damageSound = 1542642349,
standbySound = {}
}
}
-- Store the previous weld in memory
local previousWeld = nil
local scpBreached = false
---------------------------
-- M A I N S C R I P T --
---------------------------
script.Parent.BreachSCP.Changed:Connect(function(value)
scpBreached = value
end)
--[[
Function:
Usage:
- When called, it will loop through the parts in the model
and will generate a weld to weld them all together.
Arguments:
- model:
- This is the model which will be welded together. Only
supports singular for loop. Won't go into other models.
--]]
local weldModel = function(model)
local parts = model:GetChildren()
for _, part in pairs(parts) do
if part:IsA("Part") then
if previousWeld ~= nil then
local weld = Instance.new("Weld")
weld.Part0 = previousWeld
weld.Part1 = part
weld.C0 = previousWeld.CFrame:inverse()
weld.C1 = part.CFrame:inverse()
weld.Parent = previousWeld
part.Anchored = false
end
previousWeld = part
end
end
end
-- Weld the humanoid parts
weldModel(script.Parent.Parent.PhysicalSCP)
--[[
Make sure that the SCP cannot collide with doors.
--]]
local scpGroup = "GroupSCP"
local doorGroup = "GroupDoor"
physicsService:CreateCollisionGroup(scpGroup)
physicsService:CreateCollisionGroup(doorGroup)
function addPartToCollisionGroup(root, colissionGroup)
for _, child in pairs (root:GetChildren()) do
addPartToCollisionGroup(child, colissionGroup)
end
if root:IsA('Part') or root:IsA('UnionOperation') then
physicsService:SetPartCollisionGroup(root, colissionGroup)
end
end
addPartToCollisionGroup(workspace.SiteDoors, doorGroup)
addPartToCollisionGroup(this, scpGroup)
physicsService:CollisionGroupSetCollidable(doorGroup, scpGroup, false)
--[[
Function:
Usage:
- When called, it will attempt to locate the nearest player
model to attack. It will only attack players. SCPs are
allies.
Arguments:
- positionSCP:
- This is the current position of the SCP. This is usually
the Torso found in PhysicalSCP.
--]]
local findNearestAttack = function(positionSCP)
local currentPlayers = players:GetPlayers()
local pos = settingsSCP.magnitudeMax
local attackPart = nil
for _, player in pairs(currentPlayers) do
-- Check to see if there is a valid model of the player
if player.Character and player.Character:FindFirstChild('Humanoid') and player.Character:FindFirstChild('HumanoidRootPart') and player.Character.Humanoid.Health > 0 then
local distance = player:DistanceFromCharacter(positionSCP)
if distance < settingsSCP.magnitudeMax and distance ~= 0 and distance < pos then
pos = distance
attackPart = player.Character.HumanoidRootPart
end
end
end
return attackPart
end
--[[
Function:
Usage:
- When called, it will scroll through a table and see
if there is a matching value.
Arguments:
- tablePhysical: The table.
- tableValue: The table value we're trying to find.
--]]
local searchTable = function(tablePhysical, tableValue)
for i, v in pairs(tablePhysical) do
if v == tableValue then
return i
end
end
return nil
end
--[[
Touch Event:
- When this is fired, it will proceed to check if a
player has touched the SCP. If a player has, they will
take damage.
--]]
local damageDebounce = {}
this.BoundarySCP.Touched:Connect(function(hit)
if scpBreached == false then return end
local player = players:GetPlayerFromCharacter(hit.Parent)
if player and player.Character and player.Character:FindFirstChild('Humanoid') and player.Character.Humanoid.Health > 0 then
if searchTable(damageDebounce, player.UserId) == nil then
-- Take damage from the player
-- Add a debounce so they don't constantly take damage
-- Remove the debounce
player.Character.Humanoid:TakeDamage(20)
table.insert(damageDebounce, player.UserId)
-- If there is a damage sound, play it
if settingsSCP.sound.damageSound ~= nil then
local sound = Instance.new('Sound', this.Torso)
sound.SoundId = 'rbxassetid://' .. settingsSCP.sound.damageSound
sound.Volume = 1
sound:Play()
spawn(function()
repeat wait(3) until sound.Playing == false
sound:Destroy()
end)
end
wait(0.5)
local index = searchTable(damageDebounce, player.UserId)
table.remove(damageDebounce, index)
end
end
end)
-- Make the SCP into a production environment (remove red)
for _, part in pairs(this:GetChildren()) do
if part:IsA('Part') then
part.Transparency = 1
end
end
this.Torso.Transparency = 0
local destroyed = function(x)
if x.Parent then return false end
local _, result = pcall(function() x.Parent = x end)
return result:match("locked") and true or false
end
--[[
While Loop:
Every 3 seconds, it will compare all distances of players and
if the player is within the SCP's reach, it will attempt to move to it.
--]]
while true do
while scpBreached do
local targetPlayer = findNearestAttack(this:WaitForChild('Torso').Position)
if targetPlayer ~= nil then
-- Calculate the path and get the waypoints
local start = this:WaitForChild('Torso')
local path = pathfindingService:FindPathAsync(start.Position, targetPlayer.Character.HumanoidRootPart.Position)
local waypoints = path:GetWaypoints()
-- Loop through all of the waypoints in the path
for waypointIndex, waypoint in pairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
this.Humanoid.Jump = true
else
local waypointPosition = waypoint.Position
-- Make the humanoid move to the current waypoint
this.Humanoid:MoveTo(waypointPosition)
-- Wait until the humanoid has reached it's target
this.Humanoid.MoveToFinished:Wait()
if scpBreached == false then break end
if targetPlayer and targetPlayer.Character:FindFirstChild('HumanoidRootPart') and targetPlayer.Character:FindFirstChild('Humanoid') and targetPlayer.Character.Humanoid.Health > 0 and (targetPlayer.Character.HumanoidRootPart.Position - this.Torso.Position).magnitude < 20 then
break
end
end
end
if targetPlayer and targetPlayer.Character and targetPlayer.Character:FindFirstChild('Humanoid') and targetPlayer.Character.Humanoid.Health > 0 and targetPlayer.Character:FindFirstChild('HumanoidRootPart') then
if (targetPlayer.Character.HumanoidRootPart.Position - this.Torso.Position).magnitude < 20 then
while scpBreached == true and targetPlayer and targetPlayer.Character:FindFirstChild('HumanoidRootPart') and targetPlayer.Character:FindFirstChild('Humanoid') and targetPlayer.Character.Humanoid.Health > 0 and (targetPlayer.Character.HumanoidRootPart.Position - this.Torso.Position).magnitude < 20 do
this.Humanoid:MoveTo(targetPlayer.Character.HumanoidRootPart.Position, targetPlayer.Character.HumanoidRootPart)
wait(0.5)
end
end
end
end
wait(0.25)
end
wait(0.25)
end
COMMUNITY QUESTION
SiteDoors is not a valid member of Workspace "Workspace"?
1 answer
Read the error it says sitedoors is not in workspace check if it exist or is correctly named
This discussion is preserved as it was. New answers, comments, and votes are closed.
