How do I make my 'entity' check "lockers"?

I have a problem, that is making my ‘entity’ checking “lockers”, like if there is a player inside the ‘locker’, then the ‘entity’ kills the player then the ‘entity’ closes the ‘locker’, if there is not, then the ‘entity’ closes the ‘locker’ and continues on until there are no lockers left for the ‘entity’ to check. so how can I do this?

The module script used to make the AI:

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local p100 = {}

function p100.FindPlayers(model)
	local players = Players:GetPlayers()
	local characters = {}
	for i, player in ipairs(players) do
		if player.Character then
			table.insert(characters, player.Character)
		end
	end
	
	local overlapParams = OverlapParams.new()
	overlapParams.FilterType = Enum.RaycastFilterType.Include
	overlapParams.FilterDescendantsInstances = characters
	local collisions = workspace:GetPartsInPart(model.Smoke, overlapParams)
	
	for index, obj in ipairs(collisions) do
		if obj.Name == "HumanoidRootPart" then
			local rayDirection = obj.Position - model.P100.Position
			local result = workspace:Raycast(model.P100.Position, rayDirection)
			if result and result.Instance then
				local hit = result.Instance
				if hit == obj or hit:FindFirstAncestor(obj.Parent.Name) then
					local FindPlayer = Players:GetPlayerFromCharacter(obj.Parent)
					if not FindPlayer.Hiding.Value then
						obj.Parent.Humanoid.Health = 0
					end
				end
			end
		end
	end
end

function p100.LerpTo(model, target)
	local alpha = 0
	local speed = 650
	local distance = (model.PrimaryPart.Position - target.Position).Magnitude
	local relativeSpeed = distance / speed
	local startCFrame = model.PrimaryPart.CFrame
	local loop = nil
	local reachedTarget = Instance.new("BindableEvent")
	
	loop = RunService.Heartbeat:Connect(function(delta)
		p100.FindPlayers(model)
		local goalCFrame = startCFrame:Lerp(target.CFrame, alpha)
		model:PivotTo(goalCFrame)
		alpha += delta / relativeSpeed
		if alpha >= 1 then
			loop:Disconnect()
			reachedTarget:Fire()
		end
	end)
	
	reachedTarget.Event:Wait()
end

function p100.Navigate(model, prevNum, maxNum, generatedRooms, loopAmount)
	local currentLoop = 0
	local p100State = "isGoing" or "isComing"
	repeat
		currentLoop +=1
		if p100State == "isGoing" then
			task.wait(2)
			for i = prevNum, maxNum do
				local room = generatedRooms[i]
				p100.LerpTo(model, room.Entrance)

				local waypoints = room:FindFirstChild("Waypoints")
				if waypoints then
					for i=1, #waypoints:GetChildren() do
						p100.LerpTo(model, waypoints[i])
					end
				end
				p100.LerpTo(model, room.Exit)
			end
			p100State = "isComing"
		else
			for i = maxNum, prevNum, -1 do
				local room = generatedRooms[i]
				p100.LerpTo(model, room.Exit)

				local waypoints = room:FindFirstChild("Waypoints")
				if waypoints then
					for i=#waypoints:GetChildren(), 1, -1 do
						p100.LerpTo(model, waypoints[i])
					end
				end
				p100.LerpTo(model, room.Entrance)		
			end
			p100State = "isGoing"
		end
	until currentLoop == loopAmount
end

function p100.New(number, generatedRooms)
	
	local enemyModel = game.ReplicatedStorage.Enemies.P100:Clone()
	
	local prevNum = number - 6
	local maxNum = number + 1
	local prevRoom = generatedRooms[prevNum]
	if not generatedRooms[maxNum] then
		maxNum = #generatedRooms
	end
	local maxRoom = generatedRooms[maxNum]
	local loopAmount = 4
	
	enemyModel:PivotTo(prevRoom.Entrance.CFrame)
	enemyModel.Parent = workspace
	enemyModel.P100.Ambience:Play()
	
	p100.Navigate(enemyModel, prevNum, maxNum, generatedRooms, loopAmount)
	
	enemyModel:Destroy()
end

return p100

And the module script used to make lockers interactive:

local TweenService = game:GetService("TweenService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local events = ReplicatedStorage:WaitForChild("Events")
local moveCamEvent = events:WaitForChild("MoveCam")

local locker = {}

function locker.MoveHinge(hinge, direction)
	local openAngle = 100
	local goalCFrame = hinge.CFrame * CFrame.Angles(math.rad(openAngle * direction), 0, 0)
	local doorTween = TweenService:Create(hinge, TweenInfo.new(0.5), {CFrame = goalCFrame})
	doorTween:Play()
end

function locker.MoveDoor(model, direction)
	locker.MoveHinge(model.Hinge, -1 * direction)
	task.wait(0.5)
end

function locker.PlayerLeave(player, model)
	local character = player.Character
	if not character then return end
	
    model.Primary.Open:Play()
	locker.MoveDoor(model, 1)
	character:PivotTo(model.Outside.CFrame * CFrame.Angles(0, math.rad(180), 0))
	character.Humanoid.WalkSpeed = 16
	character.Humanoid.JumpPower = 50
	locker.MoveDoor(model, -1)
	model.hasPlayer.Value = nil
	player.Hiding.Value = false
end

function locker.PlayerEnter(player, model)
	local character = player.Character
	if not character then return end
	
	model.Primary.Open:Play()
	player.Hiding.Value = true
	model.hasPlayer.Value = player
	character.Humanoid.WalkSpeed = 0
	character.Humanoid.JumpPower = 0
	character:PivotTo(model.Outside.CFrame)
	moveCamEvent:FireClient(player, model.Outside.CFrame)
	locker.MoveDoor(model, 1)
	character:PivotTo(model.Inside.CFrame)
	moveCamEvent:FireClient(player, model.Inside.CFrame)
	locker.MoveDoor(model, -1)
end

function locker.New(template)
	
	local model = game.ReplicatedStorage.Furniture.Locker:Clone()
	model:PivotTo(template.CFrame)
	model.Parent = template.Parent
	
	local hasPlayer = Instance.new("ObjectValue")
	hasPlayer.Name = "hasPlayer"
	hasPlayer.Parent = model
	
	local outsidePrompt = Instance.new("ProximityPrompt")
	outsidePrompt.ActionText = ""
	outsidePrompt.MaxActivationDistance = 5
	outsidePrompt.Parent = model.Outside
	
	local insidePrompt = outsidePrompt:Clone()
	insidePrompt.MaxActivationDistance = 2
	insidePrompt.Parent = model.InsidePrompt
	
	outsidePrompt.Triggered:Connect(function(player)
		if hasPlayer.Value == nil then
			outsidePrompt.Enabled = false
			locker.PlayerEnter(player, model)
		end
	end)
	
	insidePrompt.Triggered:Connect(function(player)
		if hasPlayer.Value == player then
			insidePrompt.Enabled = false
			locker.PlayerLeave(player, model)
			insidePrompt.Enabled = true
			outsidePrompt.Enabled = true
		end
	end)
	
	template:Destroy()
end

return locker

Finally, the server script used for all of the rest:

local Players = game:GetService("Players")

local room = require(script.Room)
local door = require(script.Room.Door)
local p10 = require(script.P10)
local p20 = require(script.P20)
local p35 = require(script.P35)
local p40 = require(script.P40)
local p60 = require(script.P60)
local p70 = require(script.P70)
local p100 = require(script.P100)
local p404 = require(script.P404)

Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		if player and character then
			local hiding = player:FindFirstChild("Hiding")
			if hiding then
				hiding:Destroy()
			end
			
			local Hiding = Instance.new("BoolValue", player)
			Hiding.Name = "Hiding"
			Hiding.Value = false
		end
	end)
end)

local prevRoom = workspace.StarterRoom
local playerEnter = script.Room.PlayerEnter
local firstDoor = door.New(prevRoom, 1)

local generatedRooms = {prevRoom}

local Count = 1

if Count then
	Count += 1
	prevRoom = room.Generate(prevRoom, Count)
	generatedRooms[Count] = prevRoom
end

playerEnter.Event:Connect(function(number)
	if Count then
		Count += 1
		prevRoom = room.Generate(prevRoom, Count)
		generatedRooms[Count] = prevRoom
	end
	if number % 13 == 0 then
		workspace.Sounds.Flicker:Play()
		room.Blackout(generatedRooms[number])
		room.Blackout(generatedRooms[number+1])
		task.wait(4)
		p10.New(number, generatedRooms)
	end
	if number % 23 == 0 then
		workspace.Sounds.Flicker:Play()
		room.Blackout(generatedRooms[number])
		room.Blackout(generatedRooms[number+1])
		task.wait(3)
		p20.New(number, generatedRooms)
	end
	if number % 35 == 0 then
		workspace.Sounds.Flicker:Play()
		room.Blackout(generatedRooms[number])
		room.Blackout(generatedRooms[number+1])
		task.wait(2.5)
		p35.New(number, generatedRooms)
	end
	if number % 43 == 0 then
		task.wait(2)
		p40.New(number, generatedRooms)
	end
	if number % 63 == 0 then
		task.wait(1)
		p60.New(number, generatedRooms)
	end
	if number % 73 == 0 then
		workspace.Sounds.Flicker:Play()
		room.Blackout(generatedRooms[number])
		room.Blackout(generatedRooms[number+1])
		task.wait(3)
		p70.New(number, generatedRooms)
	end
	if number % 103 == 0 then
		workspace.Sounds.Flicker:Play()
		room.Blackout(generatedRooms[number])
		room.Blackout(generatedRooms[number+1])
		task.wait(2.1)
		p100.New(number, generatedRooms)
	end
	if number == 404 then
		room.Blackout(generatedRooms[number])
		room.Blackout(generatedRooms[number+1])
		p404.New(number, generatedRooms)
	end
end)

Any help is appreciated, thanks.

4 Likes

You want to make your AI entities check if there are players inside the lockers and, if so, kill the player and then close the locker. If no players are inside, the entity should simply close the locker and continue its actions from what I understand.

Modify the Locker Script: First, you should have a script that handles the locker’s functionality. The locker script should have a function that can be called by the AI entity to check if a player is inside and perform the necessary actions.
Here’s an example:

local Locker = {} -- Your locker module

function Locker.CheckForPlayerInside(locker)
    -- Check if there's a player inside the locker
    -- You can use your own logic here based on your game setup
    return true -- Return true if a player is inside, false otherwise
end

function Locker.CloseLocker(locker)
    -- Perform actions to close the locker
    -- You can add animations or other relevant logic here
end

return Locker

In your AI entity script, you need to import the Locker module and use it to check if there’s a player inside the locker. If a player is inside, kill the player and then close the locker. If no player is inside, simply close the locker.
Here’s an example:


local Locker = require(game.ServerScriptService.LockerModule) -- Adjust the path as needed

-- Function to handle the AI entity's interaction with the locker
function AIEntityInteractWithLocker(locker)
    if Locker.CheckForPlayerInside(locker) then
        -- Kill the player
        -- You can use your own logic to get the player and apply damage
        local playerInside = -- Get the player inside the locker
        playerInside:FindFirstChild("Humanoid").Health = 0 -- Kill the player
    end
    
    -- Close the locker regardless of whether there was a player inside
    Locker.CloseLocker(locker)
end

-- Call AIEntityInteractWithLocker with the appropriate locker object

This approach separates the functionality of checking the locker and closing it into distinct modules, making it easier to manage and debug. You can adapt the code snippets above to your specific game setup and logic. I’m not sure if this will help but you can try.

1 Like

If there’s no lockers in the room, then what will the entity do, the entity will continue to the previous room and check any lockers until there’s no more, and I have multiple lockers.

2 Likes

In your AI entity script, you should iterate through all the lockers in the current room and check if there are players inside. If there are players inside any locker, it should kill the player and close the locker. If there are no players inside any locker, it should move to the previous room and repeat the process until there are no more lockers.
Example:


local Locker = require(game.ServerScriptService.LockerModule) -- Adjust the path as needed

-- Function to handle the AI entity's interaction with lockers in the current room
function AIEntityInteractWithLockersInRoom(currentRoom)
    local lockersInRoom = currentRoom:GetChildren() -- Assuming lockers are children of the room

    local playersInsideLockers = false

    for _, locker in pairs(lockersInRoom) do
        if locker:IsA("Model") and locker.Name == "Locker" then
            if Locker.CheckForPlayerInside(locker) then
                -- Kill the player
                -- You can use your own logic to get the player and apply damage
                local playerInside = -- Get the player inside the locker
                playerInside:FindFirstChild("Humanoid").Health = 0 -- Kill the player
                
                -- Close the locker
                Locker.CloseLocker(locker)
                
                playersInsideLockers = true -- Set to true if a player was found inside any locker
            end
        end
    end

    if not playersInsideLockers then
        -- Move to the previous room (implement your own logic to find the previous room)
        local previousRoom = -- Find the previous room

        if previousRoom then
            -- Call the function recursively for the previous room
            AIEntityInteractWithLockersInRoom(previousRoom)
        end
    end
end

-- Call AIEntityInteractWithLockersInRoom with the current room object

In this script, the AI entity iterates through all the lockers in the current room. If it finds any players inside a locker, it kills the player and closes the locker. If there are no players inside any locker, it moves to the previous room and repeats the process recursively until there are no more lockers to check. I think this is what you’re looking for, but I’m not sure.

2 Likes

The prevNum is set to 6 and the entity will check the lockers one by one in each one previous room until it reaches the prevNum max value of the previous rooms it navigates through.

2 Likes

Locker Script:

local locker = script.Parent
local IsOccupied = Instance.new("BoolValue")
IsOccupied.Name = "IsOccupied"
IsOccupied.Value = false
IsOccupied.Parent = locker

locker.Touched:Connect(function(hit)
    local char = hit.Parent
    local humanoid = char:FindFirstChild("Humanoid")
    
    -- Ensure what touched the locker is a player
    if humanoid then
        IsOccupied.Value = not IsOccupied.Value -- toggle the value
    end
end)

Modify the Entity Script to Check Lockers:

function checkLocker(locker)
    if locker:IsA("Model") and locker:FindFirstChild("IsOccupied") then
        if locker.IsOccupied.Value == true then
            -- Kill the player logic here
            -- You may need additional logic to specifically find out which player is inside and kill them
        end
        
        -- Close the locker logic here
    end
end

2 Likes

My locker and the entity AI script type is a module script, not the server script, and the entity checks the lockers one by one until there’s no more to check and also the entity moves to the locker’s Outside CFrame using my LerpTo function and then opens the locker, then if there is a player inside, it will kill them and then closes the locker, if not, then closes the locker and checks another locker, until it reaches the max room and when it reaches the max room’s Exit’s position then the entity ‘despawns’.

1 Like