Activation
Many kit objects need to wait for the player to activate it. For example, the Damager only damages the player when the player touches it.
Implementation
Section titled “Implementation”A naive implementation would be:
Damager:onLoaded(function(trove, dmg) -- When the Damager is touched... trove:connect(dmg.Touched, function(toucher) -- Check if it is the player character... local player = Players:GetPlayerFromCharacter(toucher.Parent) if player == Players.LocalPlayer then -- Take damage! end end)end)Later on however, one might want to add more ways of activating this Mechanic, such as when a box touches it.
Again, a naive implementation would be:
Damager:onLoaded(function(trove, dmg) -- When the Damager is touched... trove:connect(dmg.Touched, function(toucher) -- Check if it is the player character OR a box... local player = Players:GetPlayerFromCharacter(toucher.Parent) if player == Players.LocalPlayer or toucher:HasTag("Box") and toucher:IsDescendantOf(kit.mechanics) then -- Take damage! end end)end)Then, again, one might only want the player or boxes to activate it, on a per case basis.
Another naive implementation would be:
local SupportsCharacter = utils.attribute("SupportsCharacter", utils.t.boolean)local SupportsBox = utils.attribute("SupportsBox", utils.t.boolean)
-- ...
Damager:onLoaded(function(trove, dmg) -- When the Damager is touched... trove:connect(dmg.Touched, function(toucher) -- Check if it is the player character OR a box... local player = Players:GetPlayerFromCharacter(toucher.Parent) if SupportsCharacter(dmg) and player == Players.LocalPlayer or SupportsBox(dmg) andtoucher:HasTag("Box") and toucher:IsDescendantOf(kit.mechanics) then -- Take damage! end end)end)One will realize this gets increasingly complex and hard to maintain, especially if more kinds of activation should be implemented.
connectActivation
Section titled “connectActivation”The standard library package exports a connectActivation function. This takes
in an instance that should be activated, and a callback to call when it is
activated:
function std.connectActivation<T: Instance>( trove: Trove, connectTo: T, onActivated: (trove: Trove, instance: T, activationTrove: Trove) -> ()): ()While connected, connectActivation implements the following attributes:
Activefor activationActivationMode, withTouch,Prompt,Click, andKeyCodeActivationKeyCode, ifActivationMode(connectedTo) == "KeyCode"ActivationsRequiredBoxRequiresIdandRequiredBoxId
Earlier, the Damager can be refactored as:
Damager:onLoaded(function(trove, dmg) utils.connectActivation(trove, dmg, function() -- Take damage! end)end)For ergonomics, the onActivated also receives the trove and the instance.
This let’s one abstract the onActivated callback into it’s own function:
local function takeDamage(trove, dmg, _) -- Take damage!end
Damager:onLoaded(function(trove, dmg) utils.connectActivation(trove, dmg, takeDamage)end)The 3rd argument will be elaborated in the next section.
One-time Activation
Section titled “One-time Activation”Some Mechanics can be activated once before a cooldown, such as Buttons.
The onActivated callback also receives the activationTrove as the 3rd
argument, which handles activation.
Simply clean the activationTrove to cease activation:
local function takeDamage(trove, dmg, activationTrove) activationTrove:clean() -- Take damage!end
Damager:onLoaded(function(trove, dmg) utils.connectActivation(trove, dmg, takeDamage)end)Later, usually after a cooldown, one might want to make it activatable again.
One can just reconnectActivation:
-- Define a cooldown...local Cooldown = utils.attribute("Cooldown", utils.t.numberPositive, 0)
local function takeDamage(trove, dmg, activationTrove) activationTrove:clean()
-- Take damage!
-- Once the cooldown finishes... task.delay(Cooldown(dmg), function(trove, dmg) -- Reconnect activation! utils.connectActivation(trove, dmg, takeDamage) end, trove, dmg)end
Damager:onLoaded(function(trove, dmg) utils.connectActivation(trove, dmg, takeDamage)end)onActivated
Section titled “onActivated”Using the onActivated tag lifecycle, the below code:
Damager:onLoaded(function(trove, dmg) utils.connectActivation(trove, dmg, takeDamage)end)Can be shortened as:
Damager:onActivated(takeDamage)Note that one will still need to reconnect activation if one needs to cease activation.