Sponge
Sponge copied to clipboard
Unable to retrieve leaf criterion from advancement
- Sponge version: version 1.12.2-7.1.9 - API 7
Hi, I'm currently working on per-world advancements management.
In doing so, I have to serialize and deserialize player's advancements every time a player is teleported from one world to another.
This issue is concerning the Sponge's advancement API because there is a lack of possibilities in advancement management.
Indeed, in Minecraft, advancements are divided in criterion. For some advancement, you have to achieve only one of the listed criteria (linked to Sponge's OR criterion). For others, you have to achieve every listed criterion (linked to Sponge's AND criterion).
However, in the API, we don't have access to this list of criterion.
Advancement#getCriterion returns only one criterion that represents all the "leaf" criterion, combined with "and()" or "or()" methods, and which have to be achieved to complete the advancement itself.
Plugin makers don't have access to any methods which could parse the combined criterion to retrieve all the leaf criterion.
There is a private method in SpongeCommon implementation that represents what I would like to have to build the per-world achievement in my plugin.
It's the SpongeOperatorCriterion#getLeafCriteria method :
https://github.com/SpongePowered/SpongeCommon/blob/stable-7/src/main/java/org/spongepowered/common/advancement/SpongeOperatorCriterion.java
Another problem I found is that the SpongeOperatorCriterionProgress#grant() method doesn't have the same behavior than the vanilla minecraft command :
/advancement grant
Indeed, this method seems to grant every leaf criterion as one instead of granting only the target criterion itself.
The problem also occurs for the SpongeOperatorCriterionProgress#revoke() method.
By the way, I know can be wrong, I don't know perfectly how the implementation works and what is the real role of SpongeOperatorCriterionProgress compared to Minecraft's criteria.
Currently, I'm able to perform per-world achievements correctly, but without considering achieved-criteria of the advancements.
What I mean is that I'm not able to detect partially achieved advancements.
For example for the Minecraft Adventuring Time advancement, which ask a player to visit all the biomes type of Minecraft (so, a Sponge "and()" builded criterion), the advancement can be partially realized :
"minecraft:adventure/adventuring_time": {
"criteria": {
"beaches": "2020-02-25 13:29:57 +0100",
"taiga": "2020-02-25 13:26:44 +0100",
"taiga_hills": "2020-02-25 13:29:06 +0100",
"ocean": "2020-02-25 13:29:59 +0100",
"river": "2020-02-25 13:29:39 +0100"
},
"done": false
}
And currently, I'm not able to detect the accomplishments of 'beaches', 'taiga', 'ocean', etc.. criteria.
It means that if a player moves out from a world without finishing the whole advancement, its progression would be erased when he comes back to this world.
This is why I'm reporting an issue today, and because this has been asked to me on the Sponge's discord. May this can lead to an improvement in api-7 or api-8 of Sponge.
Thank you for reading and sorry for grammar errors.
It's the SpongeOperatorCriterion#getLeafCriteria method
It is not private. It is the Impl of: OperatorCriterion#getLeafCriteria
.
You just need to cast to it.
SpongeOperatorCriterionProgress#grant() method doesn't have the same behavior than the vanilla minecraft command
Correct. Granting/revoking an OperatorCriterion
or ScoreAdvancementCriterion
applies to all its sub-criteria.
You can use the sub-criteria directly or for the score-criterion the set/add/remove score methods on ScoreCriterionProgress
.