Related to mobile app issue https://github.com/HabitRPG/habitica-android/issues/969 (fixed a couple months ago on the client side), the server apparently allows API consumers to allocate stat points while the avatar is under level 10. Now that it's corrected on the mobile clients, we can safely add logic to fix this on the server.
I can take a stab at this.
So the correct behavior would be to respond with some kind of error? Similar to when there are no points to allocate (but different message)?
@cvuorinen: Yes, exactly! And go right ahead, I'll update the issue labels.
So, is the thing that I should check user.flags.classSelected or !user.preferences.disableClasses or user.stats.lvl >= 10? Seems like the mobile app checks lvl >= 10 (at least the code that fixed the issue linked in description) but the website UI does not allow stats allocation even if level 10 but opted out of Class system. And what is the difference between user.preferences.disableClasses and user.flags.classSelected?
Also, if I add a new error message what is the convention regarding the translation files? Should I add the same English message to all of the language files or something else? Couldn't really find an existing message that would fit in this situation, I was thinking something like "You must select Class before you can assign Stat Points." or "You must be at least level 10 to assign Stat Points."
Found the README in locales directory, ignore the above question about translation files.
@cvuorinen This comment: https://github.com/HabitRPG/habitica/pull/10629#issuecomment-415933528 describes the case when anything related to the class system becomes visible/usable to the player. That specific PR is about mana notifications but the same conditions apply to being able to allocate Stat Points.
That PR uses the hasClass method:
https://github.com/HabitRPG/habitica/blob/2ce2100f89bb9eef616fb1ebd6bb10cda75009ad/website/client/store/getters/members.js#L8-L11
which would be a good thing to use here too.
It sounds like the mobile app just checks level which isn't the ideal fix.
And what is the difference between user.preferences.disableClasses and user.flags.classSelected?
When a new user creates an account, preferences.disableClasses is set to false and flags.classSelected is set to false (also stats.class is set to warrior).
When they reach level 10 for the first time, they're presented with the choose class dialog. If they select a class then preferences.disableClasses remains false and flags.classSelected is set to true (and stats.class is changed if they select anything other than Warrior).
If they choose to opt out of the class system (either from that dialog or from the Settings screen at any later time), then preferences.disableClasses is set to true and flags.classSelected is NOT changed.
Later if they opt back in and choose a class, preferences.disableClasses is set back to false and flags.classSelected still remains true.
So basically:
flags.classSelected becomes true as soon as a class is selected by the user and remains true thereafterpreferences.disableClasses becomes true only when the user opts out of the class system and becomes false when they opt back inIf they die and drop back to level 9, flags.classSelected and preferences.disableClasses and stats.class are NOT changed.
If they use the Orb of Rebirth, those settings are set back to the same as for a new account (flags.classSelected = false, preferences.disableClasses= false, stats.class = warrior).
Thanks @Alys for the comprehensive answer, everything clear now :smile:
I will use the hasClass function.
Ok, one more question. The hasClass method is defined in website/client/store/getters
https://github.com/HabitRPG/habitica/blob/2ce2100f89bb9eef616fb1ebd6bb10cda75009ad/website/client/store/getters/members.js#L8-L11
so I can't probably import it in the website/server/... or website/common/.... Should I add similar function somewhere there or define it only in one place under common and then import it from there in the store getters also?
@cvuorinen yep! moving the code in /common and importing it from the server and client is a good idea!