Implement achievements properly

This commit is contained in:
Melledy
2025-11-29 00:29:04 -08:00
parent 898e8dd43f
commit f53bdaba32
44 changed files with 818 additions and 115 deletions

View File

@@ -12,6 +12,8 @@ import emu.nebula.Nebula;
import emu.nebula.data.GameData;
import emu.nebula.database.GameDatabaseObject;
import emu.nebula.game.account.Account;
import emu.nebula.game.achievement.AchievementCondition;
import emu.nebula.game.achievement.AchievementManager;
import emu.nebula.game.agent.AgentManager;
import emu.nebula.game.battlepass.BattlePassManager;
import emu.nebula.game.character.CharacterStorage;
@@ -23,7 +25,7 @@ import emu.nebula.game.infinitytower.InfinityTowerManager;
import emu.nebula.game.instance.InstanceManager;
import emu.nebula.game.inventory.Inventory;
import emu.nebula.game.mail.Mailbox;
import emu.nebula.game.quest.QuestCondType;
import emu.nebula.game.quest.QuestCondition;
import emu.nebula.game.quest.QuestManager;
import emu.nebula.game.scoreboss.ScoreBossManager;
import emu.nebula.game.story.StoryManager;
@@ -104,6 +106,7 @@ public class Player implements GameDatabaseObject {
private transient PlayerProgress progress;
private transient StoryManager storyManager;
private transient QuestManager questManager;
private transient AchievementManager achievementManager;
private transient AgentManager agentManager;
// Extra
@@ -204,8 +207,14 @@ public class Player implements GameDatabaseObject {
}
public void setLevel(int level) {
// Set player world class (level)
this.level = level;
// Save to database
Nebula.getGameDatabase().update(this, this.getUid(), "level", this.level);
// Trigger achievement
this.triggerAchievement(AchievementCondition.WorldClassSpecific, this.getLevel());
}
public void setExp(int exp) {
@@ -481,16 +490,17 @@ public class Player implements GameDatabaseObject {
// Save to database
Nebula.getGameDatabase().update(
this,
this.getUid(),
"level",
this.getLevel(),
"exp",
this.getExp()
this,
this.getUid(),
"level",
this.getLevel(),
"exp",
this.getExp()
);
// Save level rewards if we changed it
if (oldLevel != this.getLevel()) {
// Update level rewards
this.getQuestManager().saveLevelRewards();
this.addNextPackage(
@@ -498,6 +508,9 @@ public class Player implements GameDatabaseObject {
WorldClassRewardState.newInstance()
.setFlag(getQuestManager().getLevelRewards().toBigEndianByteArray())
);
// Trigger achievement
this.triggerAchievement(AchievementCondition.WorldClassSpecific, this.getLevel());
}
// Calculate changes
@@ -550,7 +563,7 @@ public class Player implements GameDatabaseObject {
change = modifyEnergy(-amount, change);
// Trigger quest
this.triggerQuest(QuestCondType.EnergyDeplete, amount);
this.triggerQuest(QuestCondition.EnergyDeplete, amount);
// Complete
return change;
@@ -601,6 +614,10 @@ public class Player implements GameDatabaseObject {
// Reset dailies
this.resetDailies(hasWeekChanged);
// Trigger quest/achievement login
this.triggerQuest(QuestCondition.LoginTotal, 1);
this.triggerAchievement(AchievementCondition.LoginTotal, 1);
// Update last epoch day
this.lastEpochDay = Nebula.getGameContext().getEpochDays();
Nebula.getGameDatabase().update(this, this.getUid(), "lastEpochDay", this.lastEpochDay);
@@ -612,17 +629,25 @@ public class Player implements GameDatabaseObject {
this.getBattlePassManager().getBattlePass().resetDailyQuests(resetWeekly);
}
// Trigger quests
// Trigger quests + achievements
public void triggerQuest(QuestCondType condition, int progress) {
public void triggerQuest(QuestCondition condition, int progress) {
this.triggerQuest(condition, progress, 0);
}
public void triggerQuest(QuestCondType condition, int progress, int param) {
public void triggerQuest(QuestCondition condition, int progress, int param) {
this.getQuestManager().trigger(condition, progress, param);
this.getBattlePassManager().getBattlePass().trigger(condition, progress, param);
}
public void triggerAchievement(AchievementCondition condition, int progress) {
this.getAchievementManager().trigger(condition, progress, 0, 0);
}
public void triggerAchievement(AchievementCondition condition, int progress, int param1, int param2) {
this.getAchievementManager().trigger(condition, progress, param1, param2);
}
// Login
private <T extends PlayerManager> T loadManagerFromDatabase(Class<T> cls) {
@@ -664,6 +689,7 @@ public class Player implements GameDatabaseObject {
this.gachaManager = this.loadManagerFromDatabase(GachaManager.class);
this.storyManager = this.loadManagerFromDatabase(StoryManager.class);
this.questManager = this.loadManagerFromDatabase(QuestManager.class);
this.achievementManager = this.loadManagerFromDatabase(AchievementManager.class);
this.agentManager = this.loadManagerFromDatabase(AgentManager.class);
// Database fixes
@@ -680,9 +706,6 @@ public class Player implements GameDatabaseObject {
// See if we need to reset dailies
this.checkResetDailies();
// Trigger quest login
this.triggerQuest(QuestCondType.LoginTotal, 1);
// Update last login time
this.lastLogin = System.currentTimeMillis();
Nebula.getGameDatabase().update(this, this.getUid(), "lastLogin", this.getLastLogin());
@@ -698,6 +721,18 @@ public class Player implements GameDatabaseObject {
this.getNextPackages().add(new NetMsgPacket(msgId, proto));
}
// Misc
/**
* Called AFTER a response is sent to the client
*/
public void afterResponse() {
// Check if we need save achievements
if (this.getAchievementManager().isQueueSave()) {
this.getAchievementManager().save();
}
}
// Proto
public PlayerInfo toProto() {
@@ -784,10 +819,12 @@ public class Player implements GameDatabaseObject {
state.getMutableBattlePass()
.setState(1);
state.getMutableAchievement()
.setNew(this.getAchievementManager().hasNewAchievements());
state.getMutableFriendEnergy();
state.getMutableMallPackage();
state.getMutableAchievement();
state.getMutableTravelerDuelQuest()
.setType(QuestType.TravelerDuel);
state.getMutableTravelerDuelChallengeQuest()