Godot Version
v4.7.1.stable.mono
Question
Assume I have an enum like this:
enum StoryFlagsForest {
MetCoolNPC
FoundSecretWoods
SeenGluestick
WoodAmountCollected
}
If I have a value of this enum, how can I access where the enum is from? e.g. pseudocode:
print(StoryFlagsForest.MetCoolNPC.enum_type) # prints StoryFlagsForest
(I’m not sure what to call it. “Base type”? “Where it’s from”?)
I’m currently trying to make a story flags system that stores an organised dictionary of dictionaries with enums as the keys. It’s stored by the region, then its keys which have any value.
the underlying type is always int, MetCoolNPC is equal to zero, FoundSecretWoods equal to one, etc. That’s usually what people mean with base type of an enum, but you want to get a type from a value as an object of some sort, and that “type as an object” gets pretty funky quickly.
I don’t believe you can use a type itself as a key for dictionaries, you may need another enum for regions.
Surprisingly you can.
Let me rephrase then: can you get the base enum from a value of that enum value, or is it literally just an int like every other int in the engine?
You may be able to use some type-ish types like GDScript because it is also an object, but I wouldn’t rely on such things. If you could share an example of that working I’d love to see it, especially for an enum because Dictionary[enum, String] shouldn’t work but is kind of what you’re asking for.
To my knowledge Godot does not have great meta/type-programming, you can hardly figure out what the type of anything is at runtime other than those listed in Variant::Type, of which any enum does report as type int.
When you use an enum type as a dictionary key, the entire set of enum key/values is the actual key.
For example:
enum m {a,b,c,d}
func _ready() -> void:
var d:Dictionary
d[m] = 12
print(d.keys())
This prints:
[{ "a": 0, "b": 1, "c": 2, "d": 3 }]
I would suspect back tracing from a value is going to be difficult.
Because there may be more than one dictionary using the same key, GDScript would have to keep a record of where that integer came from and I don’t see that being efficient at all.
The situation you describe would likely better be filled with a custom class rather than enum type.
That’s true, now I’m thinking like
class_name StoryFlags
static var forest_flags := Forest.new()
class Forest:
static var wood_collected := 0
I was trying to use an enum for better IDE integration (e.g. print(StoryFlags.forest.wood_collected), but this works with inner classes too. I did a quick demo and this solution with inner classes seems to work.
For anyone else reading this: doesn’t seem like you can do what I was originally trying. Thanks for the help though!