Can i call a function without running it?

there is another function and it has newTower as a parameter, so maybe this could be used?

function tower.Attack(newTower,player)
	local config = newTower.Config
	local target = tower.FindTarget(newTower, config.Range.Value, config.TargetMode.Value)
	if target and target:FindFirstChild("Humanoid") and target.Humanoid.Health > 0 then
		
		local targetCFrame = CFrame.lookAt(newTower.HumanoidRootPart.Position, target.HumanoidRootPart.Position)
		newTower.HumanoidRootPart.BodyGyro.CFrame = targetCFrame

		events:WaitForChild("AnimateTower"):FireAllClients(newTower, "Attack", target)
		
		local module = require(script.Gunner)
		module.Attack()
		
		
		if target.Humanoid.Health <= 0 then
			player.Money.Value += target.Humanoid.MaxHealth
			player.Kills.Value += 1
		end
		
		task.wait(config.Cooldown.Value)
	end
	
	task.wait(0.1)
	
	if newTower and newTower.Parent then
		tower.Attack(newTower,player)
	end
end
1 Like

basically, tower gets spawned, sends the newTower parameter to the attack function, but what i want is to have different module scripts for each tower, so i need to get the newTower variable either from the spawn or the attack function in the seperate module script

1 Like

this also runs the spawn function, which i dont want i only want what it returns

don’t you have to ‘run’ the function to get what it returns
i’m confused as to what you’re trying to do

1 Like

yeah no need to use returns, i described what i want above this so ill take any way to achieve that

1 Like

ill redo this, hopefully this will be clearer

function tower.Attack(newTower,player)
	
	local config = newTower.Config
	local target = tower.FindTarget(newTower, config.Range.Value, config.TargetMode.Value)
	if target and target:FindFirstChild("Humanoid") and target.Humanoid.Health > 0 then
		
		local targetCFrame = CFrame.lookAt(newTower.HumanoidRootPart.Position, target.HumanoidRootPart.Position)
		newTower.HumanoidRootPart.BodyGyro.CFrame = targetCFrame

		events:WaitForChild("AnimateTower"):FireAllClients(newTower, "Attack", target)
		
		target.Humanoid:TakeDamage(25)
		
		if target.Humanoid.Health <= 0 then
			player.Money.Value += target.Humanoid.MaxHealth
			player.Kills.Value += 1
		end
		
		task.wait(config.Cooldown.Value)
	end
	
	task.wait(0.1)
	
	if newTower and newTower.Parent then
		tower.Attack(newTower,player)
	end
end
function tower.Spawn(player, name, cframe, previous)
	local allowedToSpawn = true --tower.CheckSpawn(player,name)
	
	if allowedToSpawn then
		
		local newTower
		local oldTargetMode = nil
		if previous then
			oldTargetMode = previous.Config.TargetMode.Value
			previous:Destroy()
			newTower = game.ReplicatedStorage.Towers.Upgrades[name]:Clone()
		else
			newTower = game.ReplicatedStorage.Towers[name]:Clone()
		end
		
		bindables:WaitForChild("GetTower"):Fire(newTower)
		
		local ownerValue = Instance.new("StringValue")
		ownerValue.Name = "Owner"
		ownerValue.Value = player.Name
		ownerValue.Parent = newTower.Config
		
		local targetMode = Instance.new("StringValue")
		targetMode.Name = "TargetMode"
		targetMode.Value = oldTargetMode or "First"
		targetMode.Parent = newTower.Config
		
		newTower.HumanoidRootPart.CFrame = cframe
		newTower.Parent = workspace.Towers
		newTower.HumanoidRootPart:SetNetworkOwner(nil)
		
		local bodyGyro = Instance.new("BodyGyro")
		bodyGyro.MaxTorque = Vector3.new(math.huge,math.huge,math.huge)
		bodyGyro.D = 0
		bodyGyro.CFrame = newTower.HumanoidRootPart.CFrame
		bodyGyro.Parent = newTower.HumanoidRootPart
		
		for i, object in ipairs(newTower:GetDescendants()) do
			if object:IsA("BasePart") then
				object.CollisionGroup = "Tower"
			end	
		end
		
		player.Money.Value -= newTower.Config.Price.Value
		
		coroutine.wrap(tower.Attack)(newTower, player)
		return newTower
		
		
	else
		warn("no tower ["..name.."]")
		return false
	end
end

so there are the two functions, and in the attack function there is this:

target.Humanoid:TakeDamage(25)

but instead of the target just taking damage, i would want it to go to an entirely different module script and do it there for each tower

in the attack function there is a newTower parameter which is the tower that gets spawned. this is received from the spawn function

but if i want to do the damage in a different modulescript, it doesn’t know what newTower is there

1 Like

Store the new tower in a table and then make a static function like GetTowerByName that other modules can use to lookup the tower object.

Is this what you’re asking?

1 Like

where do i put that table? sorry dont quite know

1 Like

At the top of your tower module you can do:

local activeTowers = {}

and then after you run .Spawn() you can do:

activeTowers[name] = newTower

Then you could use a function like:

function tower.GetByName(name)
	for i in pairs(activeTowers) do
		if i == name then
			return activeTowers[i]
		end
	end
end

function tower.GetAll()
	return activeTowers
end

Then another module script could require your tower module and do:

for _,tower in pairs(tower.GetAll()) do
	tower:TakeDamage(25) -- whatever
end
2 Likes

But that “run” would just yeld the value if scripted right.

1 Like

Hello, I think this is what you want to achieve (I might get your question wrong)

function tower.CloneTower(name)
    local newTower = game.ReplicatedStorage.Towers[name]:Clone()
    return newTower
end

You can then call this function to get a cloned newTower object without executing the full tower.Spawn() function. However, do note that this will only clone the tower from ReplicatedStorage and will not have any of the additional setup (like ownerValue , targetMode , bodyGyro , and so on) performed in tower.Spawn() . So, if you need that setup, you’ll need to implement it separately.

hi, so this worked great up until today, where i found out that it doesnt work when i upgrade towers

when i upgrade towers in the seperate module script, it tells me that config is not a valid member

i’ve found out the reason for this is because when i upgrade, the seperate module script thinks the tower is still the previous level, which gets deleted when you upgrade

the upgrading is done in the spawn function on this line:

if previous then
			oldTargetMode = previous.Config.TargetMode.Value
			previous:Destroy()
			newTower = game.ReplicatedStorage.Towers.Upgrades[name]:Clone() -- done here

if anyone can help that would appreciated, even with a different method

1 Like

You could use a variable to detect if it is in it’s home script or not.

1 Like

sorry, detecting if what is in the home script?

managed to fix it by replacing activeTowers[name] = newTower with table.insert(newTower) and removing newTower before adding the upgraded one in

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