Static typing of exported dictionary?

Godot Version

4.3.dev1

Question

I am creating an equipment system where certain armor items can only be equipped by certain classes / vocations using ressources.

For example, this is my helmet class.

class_name Helmet extends Resource

@export var name: String
@export_enum("Common", "Uncommon", "Rare", "Epic", "Legendary") var rarity: int

@export var eligible_vocations: Dictionary = {
	"gladiator": false,
	"mage": false,
	"martial_artist": false,
	"paladin": false,
	"priest": false,
	"warrior": false,
}

@export var resilience: int
@export var health: int

My first idea is to export a dictionary containing the classes / vocations and a boolean if they can equip this item. This leads to an issue where the values and the size of the dictionary can be changed in the editor.

Is there a way to statically type an exported dictionary so I can only change the boolean values? Or is there a better approach to solve this problem like an exported enum where you can select multiple values?

Statically typed Dictionaries are not supported in GDScript at the moment.

1 Like
class_name Helmet extends Resource

@export var name: String
@export_enum("Common", "Uncommon", "Rare", "Epic", "Legendary") var rarity: int
@export var resilience: int
@export var health: int

@export_group("Eligible Vocations")
@export_enum("false","true") var gladiator: String="false"
@export_enum("false","true") var mage:  String="false"
@export_enum("false","true") var martial_artist:  String="false"
@export_enum("false","true") var paladin:  String="false"
@export_enum("false","true") var priest:  String="false"
@export_enum("false","true") var warrior:  String="false"

const TRUE_FALSE:Dictionary={"false":0,"true":1}

var eligible_vocations:Dictionary={}

func set_dict():
	eligible_vocations["gladiator"]=bool(TRUE_FALSE[gladiator])
	eligible_vocations["mage"]=bool(TRUE_FALSE[mage])
	eligible_vocations["martial_artist"]=bool(TRUE_FALSE[martial_artist])
	eligible_vocations["paladin"]=bool(TRUE_FALSE[paladin])
	eligible_vocations["priest"]=bool(TRUE_FALSE[priest])
	eligible_vocations["warrior"]=bool(TRUE_FALSE[warrior])

how about this code? will it be what you want? call .set_dict() then .eligible_vocations to get the dictionary values from editor’s eligible_vocations values

1 Like

Create a custom resource, name it whatever, let’s say EligibleClasses. In it define a bool @export var for each class, and write an _init() that accepts bool for each class.

Then in Helmet just do:

@export var eligible_vocations: EligibleClasses = EligibleClasses.new(false, false, false, false, false, false)

Something like that, maybe?

2 Likes

Hey, thank you very much for the suggestion. Is there a quick way to loop through the export vars? If not, I heard typed dictionaries are coming in Godot 4.3, so maybe I’ll just wait for that…

Thanks for the suggestions! This seems like a good workaround for now, until typed dictionaries are added.

1 Like

try this

for idx in range(0, state.get_node_count() ):
	for propIdx in range(0, state.get_node_property_count(idx) ):
		var pname = state.get_node_property_name(idx, propIdx)
		var pvalue = state.get_node_property_value(idx, propIdx)

can skip the first loop if only 1 node maybe, not sure, haven’t tested it, just googled

I think the names come out as exportedStirng, etc. So check for exported in front and those are your exported ones?