How to make pokemon style encounters

I want to know how to make an encounter system where if you are walking in grass for like a random amount of time between 3 to 7 seconds, you find an encounter. If you stop walking or leave the grass, it resets the timer. This is part of my code. It only works once and if u stop in the grass you still get an encounter:

local parts = script.Parent:GetChildren()
local debounce = false

for _, part in pairs(parts) do
	if part:IsA("Part") then
		part.Touched:Connect(function(hit)
			if debounce == false then
				debounce = true
				if hit.Parent:FindFirstChild("Humanoid") then
					local iteration = 1
					while wait(0.05) do
						local touching = false
						if hit.Parent.Humanoid.MoveDirection.Magnitude == 0 then
							debounce = false
						end
						for i,v in part:GetTouchingParts() do
							if v.Parent == hit.Parent then
								touching = true
							end
						end
						if touching == false then
							debounce = false
						end
						coroutine.wrap(function()
							if iteration == 1 then
								local randTime = math.random(3,7)
								wait(randTime)
								hit.Parent:FindFirstChild("Humanoid").WalkSpeed = 0
								local encounter = chooseRandom(part:GetAttribute("locationNum"))
								event:FireClient(game.Players:GetPlayerFromCharacter(hit.Parent),encounter)
								event.OnServerEvent:Connect(function(plr)
									hit.Parent:FindFirstChild("Humanoid").WalkSpeed = 16
									debounce = false
								end)
							end
						end)()
						iteration += 1
						if debounce == false then
							break
						end
					end
				end
			end
		end)
	end
end
2 Likes

Hey There Pidge_y!

A reason why you can only encounter an enemy once is the fact your script only executes once. The for loop that cycles through your variable, parts will only fire once since you don’t have anyway of looping it or executing it again. All the code nested within the loop will not run as a result.

A solution could be putting all the code (besides the variables) inside a function and have a touched event that will fire this function to check if the player is touching a part within the part variable.

Hope this helps with your first issue :slight_smile:

1 Like

Nevermind, I think it was something else in a local script. a debounce I forgot to set to false. I just need ideas on why when I stop moving it encounters and for some reason I need to exit the grass to get another encounter

Glad you got somewhere!
I’ll see what I can do and look for some ways to fix the encounter issue :slight_smile:

1 Like

I would also like to know. haha

I redid the script a little and I used print debugging, I made a timer that counts down when you move in the grass and once it reaches below 0 it fires the encounter. I still need to test this a bit because I’ve had some bugs like when exiting the battle it immediately fires another one or it starts 2 timers at the same time. A lot of while loops is not that efficient but it kinda works. I added an invisible part over the grass that makes it much easier to detect if there is a humanoid there. Here’s the code:

local function GetTouchingParts(part)
   local connection = part.Touched:Connect(function() end)
   local results = part:GetTouchingParts()
   connection:Disconnect()
   return results
end

local debounce = false

local function encounter(hit,part)
   local randTime = math.random(3,7)
   while wait(0.1) do
   	local touching = false
   	
   	for i,v in pairs(workspace:GetPartsInPart(part.InvisiblePart)) do
   		if v.Parent == hit.Parent then
   			touching = true
   		end
   	end
   	if touching == true and hit.Parent.Humanoid.MoveDirection.Magnitude > 0 then
   		randTime -= 0.1
   		print(randTime)
   	end
   	if randTime < 0 then
   		hit.Parent:FindFirstChild("Humanoid").WalkSpeed = 0
   		local chosen = chooseRandom(part:GetAttribute("locationNum"))
   		event:FireClient(game.Players:GetPlayerFromCharacter(hit.Parent),chosen)
   		event.OnServerEvent:Connect(function(plr)
   			randTime = math.random(3,7)
   			hit.Parent:FindFirstChild("Humanoid").WalkSpeed = 16
   			debounce = false
   		end)
   	end
   end
end

local parts = script.Parent:GetChildren()

for _, part in pairs(parts) do
   if part:IsA("Part") then
   	while wait(0.99) do
   		coroutine.wrap(function()
   			for i,v in pairs(GetTouchingParts(part.InvisiblePart)) do
   				if v.Parent:FindFirstChild("Humanoid") then
   					if debounce == false then
   						debounce = true
   						encounter(v,part)
   					end
   				end
   			end
   		end)()
   	end
   end
end
2 Likes

I figured it out! I just had to remove the coroutine in the while loop that checks if a part in the parts folder is being touched, and add a wait before making the debounce false so that you can ensure the timer gets reset. Here is the new code:

local function GetTouchingParts(part)
   local connection = part.Touched:Connect(function() end)
   local results = part:GetTouchingParts()
   connection:Disconnect()
   return results
end

local debounce = false

local function encounter(hit,part)
   local randTime = math.random(3,7)
   while wait(0.1) do
   	local touching = false
   	
   	for i,v in pairs(workspace:GetPartsInPart(part.InvisiblePart)) do
   		if v.Parent == hit.Parent then
   			touching = true
   		end
   	end
   	if touching == true and hit.Parent.Humanoid.MoveDirection.Magnitude > 0 then
   		randTime -= 0.1
   		print(randTime)
   	end
   	if randTime < 0 then
   		hit.Parent:FindFirstChild("Humanoid").WalkSpeed = 0
   		local chosen = chooseRandom(part:GetAttribute("locationNum"))
   		event:FireClient(game.Players:GetPlayerFromCharacter(hit.Parent),chosen)
   		event.OnServerEvent:Connect(function(plr)
   			randTime = math.random(3,7)
   			hit.Parent:FindFirstChild("Humanoid").WalkSpeed = 16
            wait()
   			debounce = false
   		end)
   	end
   end
end

local parts = script.Parent:GetChildren()

for _, part in pairs(parts) do
   if part:IsA("Part") then
   	while wait(0.99) do
 		for i,v in pairs(GetTouchingParts(part.InvisiblePart)) do
 			if v.Parent:FindFirstChild("Humanoid") then
 				if debounce == false then
 					debounce = true
 					encounter(v,part)
 				end
 			end
 		end
   	end
   end
end
2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.