Calling a function in a tool script from a module script

I’m working on a weapon reload system where the player can run into ammo that’s placed on the map and it reloads the corresponding weapon. The problem that I’m running into is that there doesn’t seem to be a way to call a function in the tool script from the module script that’s handling the reload. I have tried several things and none of them seem to work. I get an error saying that the function is not a valid member of the script, and yet it is.

Here are the relevant functions in the tool script:

-- Allows an external caller to add ammo to the weapon.
function ReloadAmmo(player, amount)
	toolData.weapon.ammo += amount
	if toolData.weapon.ammo > toolData.weapon.ammoMax then
		toolData.weapon.ammo = toolData.weapon.ammoMax
	end
	script.Parent.Click:FireClient(player, 0)
end

-- Returns the weapon data to the caller.
function GetToolData()
	local data = recursiveCopy(toolData)
	return data	
end

And here is the code from the module script that is giving the error:

	local toolList = player.Backpack:GetChildren()
	for _, tool in pairs(toolList) do
		local toolData = tool.ServerScript.GetToolData()
		if toolData.toolType == enums.ToolType.Weapon then
			if ammoType == toolData.weapon.projectile.projType then
				tool.ServerScript.ReloadAmmo(player, ammoAmount)
				break;
			end
		end
	end

It stops on an error when I try to call GetToolData() which says that GetToolData is not a valid member of the tool script…yet it’s in there, and it does not have the local qualifier. The tool script is an actual script, not a module or local script. I do have a workaround where the tool registers itself with another module script that I can call, but that is far from ideal.

2 Likes

The function is private in the modulescript, which means the function will not be included when using require.
To do public functions, include it in the module table, like so:

function Module.ReloadAmmo(player, amount)
	toolData.weapon.ammo += amount
	if toolData.weapon.ammo > toolData.weapon.ammoMax then
		toolData.weapon.ammo = toolData.weapon.ammoMax
	end
	script.Parent.Click:FireClient(player, 0)
end

-- Returns the weapon data to the caller.
function Module.GetToolData()
	local data = recursiveCopy(toolData)
	return data	
end

Normally, I would agree with you. But the problem is that these functions are not defined in a module script, but a script that’s part of a tool instance. Besides, I tried that already and it did not work.

Well, I don’t see why you would make public functions in a script and call them in a modulescript. You should swap, use a modulescript instead of a script and use a script instead of a modulescript.

Maybe I’m missing something, but the main script in the tool (a weapon) is a script. In order to reload the weapon, I have to call reload weapon with the amount of ammo to reload. I have a workaround that I figured out. Basically, the weapon registers itself with the weapons module when it’s equipped (working on getting that to happen when it’s picked up). All weapon registrations go into a dictionary. Part of the registration is the address of the reload function in the weapon script. So now I can call the reload function through a table reference, which effectively solves the problem.

1 Like