Spill & Mop System Issue

Spill & Mop System Issue

  1. What do you want to achieve? I have a spill & mop system for a group of mine and it works almost flawlessly. While a staff member mops the spill, it slowly decreases in size and once it’s done, the staff member is awarded a point.

  2. What is the issue? The staff member can mop the spill and it decreases in size, but they are not awarded the point. The spill does not entirely go away and the ‘SPILL’ message above it means it’s still there.

  3. What solutions have you tried so far? I have tried changing the spill part size, changing the decrease rate of the spill when it’s being mopped, yet still no luck.

SampleSpill Part Size: 0.1, 5.7, 5.7

local DebriService = game:GetService("Debris")
local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")

local DSS = game:GetService("DataStoreService")
local DS = DSS:GetDataStore("PointsSaveSystem")

game.Players.PlayerAdded:Connect(function(Player)
	local Stats = Instance.new("Folder", Player)
	Stats.Name = "leaderstats"
	local Points = Instance.new("IntValue", Stats)
	Points.Name = "Points"

	Points.Value = DS:GetAsync(Player.UserId) or 0
	DS:SetAsync(Player.UserId, Points.Value)

	Points.Changed:Connect(function()
		DS:SetAsync(Player.UserId, Points.Value)
	end)
end)

local SPILL_PART = script.Parent -- AKA SampleSpill
local LOCK = false

SPILL_PART.Touched:Connect(function(Obj)
	if Obj.Parent.Name == "Mop" and Obj.Parent:IsA("Tool") then
			
		SPILL_PART.Size = SPILL_PART.Size - Vector3.new(0,0.05,0.05)
		wait(.02)
		
		if SPILL_PART.Size == Vector3.new(.1, .0, .0) then
			local PLAYER_OBJECT = Players:GetPlayerFromCharacter(Obj.Parent.Parent)
			if PLAYER_OBJECT and not LOCK then
				LOCK = true
				PLAYER_OBJECT.leaderstats.Points.Value = PLAYER_OBJECT.leaderstats.Points.Value + 1
				print("+1 to " .. PLAYER_OBJECT.Name)
				DebriService:AddItem(SPILL_PART,.001)
			end
		end
	end
end)

Before Mopping:
image

After Mopping:
image

I would like you to know that I am not experienced with programming whatsoever, so you’re gonna have to bear with me here. I thank you in advance.

This is likely happening because a part can’t be smaller than .001 on each axis, not to mention the floating point errors that might happen because Vector3’s are very rarely equal to each other. So instead of checking if the spill part’s size is equal to a certain value, check if it’s less than a certain value. Say we want to award a point to the player once the spill reaches 0.1 studs in diameter on the Y axis (which I think would be equal to the diameter bc spheres are rotated 90 deg)

So basically, change your if-statement condition to

if SPILL_PART.Size.X <= 0.1

Or if your axes can vary, you can check all 3 axes are smaller than 0.1,

local function checkVector3(vector)
    return (vector.X <= 0.1) and (vector.Y <= 0.1) and (vector.Z <= 0.1) -- if all 3 axes are smaller than 0.1, it would return true, otherwise returns false (all 3 axes are gt 0.1)
end

Then for the condition,

if checkVector3(SPILL_PART.Size) then
2 Likes

this is the solution, size cannot be completely zero on any axis for 3d object.

1 Like

So I’m assuming I would put that code here?

Please pardon my lack of knowledge in scripting.

I’d make it a function outside of the scope of your touched connections but it should work there too. It wouldn’t have much of a performance impact but I think it’s generally just better practice to have a single function accessible from any other code that might be calling it.

So when you say ‘make it a function outside of your touched connections,’ do you mean I should put the checkVector3 function before line 31?

Yeah, exactly. Basically a scope can be easily visualized by an indent, assuming your formatting is correct. Without going too in-depth, think of a scope like a field of view.

local function a()
	
end

if true then
	function c() -- global function, can be "seen" in all other scopes
		
	end
end

if something2 then
	local function b() -- local variable so it can't be "seen" in other scopes at the same level

	end
end

if something then
	-- this is a scope, it can see everything outside of this scope except for things in other scopes
	a() -- ok
	b() -- nope can't see the b function because it is within another scope
	c() -- can see the c function because it is a global variable, meaning it can be accessed in all other scopes
end

You should test it now, it should be working as intended.

Tried this just now but still no luck.

Before:
image

After:
image

Basically doing the same thing it did the first time.

what is the x-axis size of the part? i notice you dont change it so maybe the function returning false because

vector.X !<=.1

image

Should I try changing (vector.X <= 0.1) to a different number?

do
print(SPILL_PART.Size) right before the check condition

and tell us the final size when it should delete itself.

you can also add print statement within if condition to see if it is actually going through

(the prints will be printed in output bar)

Well.

I think it might be a floating point error (though I’m not 100% sure). You can get relatively precise by rounding to the thousandth (or more precise) by doing something like this:

local roundedYAxis = math.round(SPILL_PART.Size.Y * 1000) / 1000
if roundedYAxis <= 0.1 then
1 Like

So if I’m understanding you correctly, should I try this?

Yeah, exactly. (text limit thing, sorry to mods for bypassing the limit lol)

1 Like

Everything is now fully working! I’ll mark this as the solution, @Juicy_Fruit’s and your contributions are greatly appreciated. Thank you both!

2 Likes