I’m trying to create a generic _set_attribute, because all the set functions I need are using the same code.
I have an issue here: Stack overflow (stack size: 1024). Check for infinite recursion in your script on the line set(attr_name, clampi(value, min_value, max_value))
Do you know a way to assign the value of a variable without calling the set function?
@warning_ignore("unused_signal")
signal strength_changed(old_value: int, new_value: int)
@warning_ignore("unused_signal")
signal dexterity_changed(old_value: int, new_value: int)
const MINIMUM_ATTRIBUTES_VALUE: int = 1
const MAXIMUM_ATTRIBUTES_VALUE: int = 1_000
var strength: int = base_strength:
set = set_strength
var dexterity: int = base_dexterity:
set = set_dexterity
func set_strength(value: int) -> void:
_set_attribute("strength", value, MINIMUM_ATTRIBUTES_VALUE, MAXIMUM_ATTRIBUTES_VALUE)
func set_dexterity(value: int) -> void:
_set_attribute("dexterity", value, MINIMUM_ATTRIBUTES_VALUE, MAXIMUM_ATTRIBUTES_VALUE)
func _set_attribute(attr_name: String, value: int, min_value: int, max_value: int) -> void:
var attr_previous: int = get(attr_name)
set(attr_name, clampi(value, min_value, max_value))
emit_signal(attr_name + "_changed", attr_previous, get(attr_name))
Setting it inside the individual setter function should be fine, so… The generic function could do the clamping, emit the signal and return the value (instead of setting it itself)? Would just be an additional e.g. strength = in each inidvidual setter function.
# as an aside there is no reason to pass the min/max constants since they are the same for both attributes
func set_strength(value: int) -> void:
strength = _set_attribute("strength", value, MINIMUM_ATTRIBUTES_VALUE, MAXIMUM_ATTRIBUTES_VALUE)
func set_dexterity(value: int) -> void:
dexterity = _set_attribute("dexterity", value, MINIMUM_ATTRIBUTES_VALUE, MAXIMUM_ATTRIBUTES_VALUE)
func _set_attribute(attr_name: String, value: int, min_value: int, max_value: int) -> int:
var attr_previous: int = get(attr_name)
#set(attr_name, clampi(value, min_value, max_value))
emit_signal(attr_name + "_changed", attr_previous, get(attr_name))
return clampi(value, min_value, max_value)
Yes that would be an option.
I hate sending signal before completing the function though. The signal is not asynchronous so the entire functionality of the emitted signal completes before returning to the function to then return a value.
This can be overcome by connecting the signal using the connect flag connect deferred.