Fix more Monolith achievements

This commit is contained in:
Melledy
2025-12-08 01:12:01 -08:00
parent b92319b4c5
commit e5ce16d6ea
5 changed files with 173 additions and 68 deletions
@@ -53,11 +53,45 @@ public class AchievementHelper {
} }
private static void fixParams() { private static void fixParams() {
// Star Tower TODO // Clear "Misstep On One"
addParam(78, 0, 2); addParam(56, 401, 0); // Custom trigger
addParam(79, 0, 4);
// Clear "Currents and Shadows"
addParam(57, 102, 0);
addParam(58, 103, 0);
addParam(59, 104, 0);
addParam(60, 105, 0);
addParam(61, 106, 0);
addParam(62, 107, 0);
addParam(63, 108, 0);
// Clear "Dust and Flames"
addParam(64, 202, 0);
addParam(65, 203, 0);
addParam(66, 204, 0);
addParam(67, 205, 0);
addParam(68, 206, 0);
addParam(69, 207, 0);
addParam(70, 208, 0);
// Clear "Storm and Thunder"
addParam(71, 302, 0);
addParam(72, 303, 0);
addParam(73, 304, 0);
addParam(74, 305, 0);
addParam(75, 306, 0);
addParam(76, 307, 0);
addParam(77, 308, 0);
// First Ascension
addParam(498, 0, 1); addParam(498, 0, 1);
// Monolith Conqueror
addParam(78, 2, 0);
addParam(79, 4, 0);
addParam(80, 6, 0);
addParam(81, 7, 0);
// Money // Money
addParam(25, GameConstants.GOLD_ITEM_ID, 0); addParam(25, GameConstants.GOLD_ITEM_ID, 0);
addParam(26, GameConstants.GOLD_ITEM_ID, 0); addParam(26, GameConstants.GOLD_ITEM_ID, 0);
@@ -5,6 +5,7 @@ import java.util.Map;
import dev.morphia.annotations.Entity; import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id; import dev.morphia.annotations.Id;
import emu.nebula.Nebula; import emu.nebula.Nebula;
import emu.nebula.data.GameData; import emu.nebula.data.GameData;
import emu.nebula.data.resources.AchievementDef; import emu.nebula.data.resources.AchievementDef;
@@ -16,8 +17,8 @@ import emu.nebula.game.player.PlayerManager;
import emu.nebula.net.NetMsgId; import emu.nebula.net.NetMsgId;
import emu.nebula.proto.Public.Achievements; import emu.nebula.proto.Public.Achievements;
import emu.nebula.proto.Public.Events; import emu.nebula.proto.Public.Events;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import us.hebi.quickbuf.RepeatedInt; import us.hebi.quickbuf.RepeatedInt;
@Getter @Getter
@@ -29,8 +30,9 @@ public class AchievementManager extends PlayerManager implements GameDatabaseObj
// Achievement data // Achievement data
private Map<Integer, GameAchievement> achievements; private Map<Integer, GameAchievement> achievements;
@Setter // Flags
private transient boolean queueSave; private transient boolean queueSave;
private transient boolean hasCompleted;
@Deprecated // Morphia only @Deprecated // Morphia only
public AchievementManager() { public AchievementManager() {
@@ -79,9 +81,6 @@ public class AchievementManager extends PlayerManager implements GameDatabaseObj
} }
public synchronized void handleClientEvents(Events events) { public synchronized void handleClientEvents(Events events) {
//
boolean hasCompleted = false;
// Parse events // Parse events
for (var event : events.getList()) { for (var event : events.getList()) {
// Check id // Check id
@@ -117,23 +116,15 @@ public class AchievementManager extends PlayerManager implements GameDatabaseObj
// Update achievement // Update achievement
boolean changed = achievement.trigger(true, progress, 0, 0); boolean changed = achievement.trigger(true, progress, 0, 0);
// Only save/update on client if achievement was changed // Sync with client if achievement was changed
if (changed) { if (changed) {
// Sync
this.syncAchievement(achievement); this.syncAchievement(achievement);
// Set save flag
this.queueSave = true;
// Check if achievement was completed
if (achievement.isComplete()) {
hasCompleted = true;
}
} }
} }
// Trigger update // Update total achievements
if (hasCompleted) { if (this.hasCompleted) {
this.hasCompleted = false;
this.getPlayer().trigger(AchievementCondition.AchievementTotal, this.getCompletedAchievementsCount()); this.getPlayer().trigger(AchievementCondition.AchievementTotal, this.getCompletedAchievementsCount());
} }
} }
@@ -166,7 +157,6 @@ public class AchievementManager extends PlayerManager implements GameDatabaseObj
// Check what type of achievement condition this is // Check what type of achievement condition this is
boolean isTotal = AchievementHelper.isIncrementalAchievement(condition); boolean isTotal = AchievementHelper.isIncrementalAchievement(condition);
boolean hasCompleted = false;
// Parse achievements // Parse achievements
for (var data : triggerList) { for (var data : triggerList) {
@@ -176,23 +166,41 @@ public class AchievementManager extends PlayerManager implements GameDatabaseObj
// Update achievement // Update achievement
boolean changed = achievement.trigger(isTotal, progress, param1, param2); boolean changed = achievement.trigger(isTotal, progress, param1, param2);
// Only save/update on client if achievement was changed // Sync with client if achievement was changed
if (changed) { if (changed) {
// Sync
this.syncAchievement(achievement); this.syncAchievement(achievement);
// Set save flag
this.queueSave = true;
// Check if achievement was completed
if (achievement.isComplete()) {
hasCompleted = true;
}
} }
} }
// Trigger update // Update total achievements
if (hasCompleted) { if (this.hasCompleted) {
this.hasCompleted = false;
this.getPlayer().trigger(AchievementCondition.AchievementTotal, this.getCompletedAchievementsCount());
}
}
public synchronized void triggerOne(int id, int progress, int param1, int param2) {
// Get achievement data
var data = GameData.getAchievementDataTable().get(id);
if (data == null) return;
// Get achievement
var achievement = this.getAchievement(data);
// Check what type of achievement condition this is
boolean isTotal = AchievementHelper.isIncrementalAchievement(data.getCompleteCond());
// Update achievement
boolean changed = achievement.trigger(isTotal, progress, param1, param2);
// Sync with client if achievement was changed
if (changed) {
this.syncAchievement(achievement);
}
// Update total achievements
if (this.hasCompleted) {
this.hasCompleted = false;
this.getPlayer().trigger(AchievementCondition.AchievementTotal, this.getCompletedAchievementsCount()); this.getPlayer().trigger(AchievementCondition.AchievementTotal, this.getCompletedAchievementsCount());
} }
} }
@@ -205,6 +213,15 @@ public class AchievementManager extends PlayerManager implements GameDatabaseObj
return; return;
} }
// Set save flag
this.queueSave = true;
// Check if achievement was completed
if (achievement.isComplete()) {
this.hasCompleted = true;
}
// Send update to player
getPlayer().addNextPackage( getPlayer().addNextPackage(
NetMsgId.achievement_change_notify, NetMsgId.achievement_change_notify,
achievement.toProto() achievement.toProto()
@@ -769,32 +769,7 @@ public class StarTowerGame {
} }
// Refresh secondary skills // Refresh secondary skills
var newSecondarySkills = SecondarySkillDef.calculateSecondarySkills(this.getDiscIds(), this.getItems()); this.refreshSecondarySkills(data);
// Add any new secondary skills to the data proto
for (int id : newSecondarySkills) {
if (!this.getSecondarySkills().contains(id)) {
var info = ActiveSecondaryChange.newInstance()
.setSecondaryId(id)
.setActive(true);
data.addSecondaries(info);
}
}
// Inform the client that these skills are no longer active
for (int id : this.getSecondarySkills()) {
if (!newSecondarySkills.contains(id)) {
var info = ActiveSecondaryChange.newInstance()
.setSecondaryId(id)
.setActive(false);
data.addSecondaries(info);
}
}
// Set new secondary skills
this.secondarySkills = newSecondarySkills;
// Clear new infos // Clear new infos
this.getNewInfos().clear(); this.getNewInfos().clear();
@@ -826,6 +801,50 @@ public class StarTowerGame {
return rsp; return rsp;
} }
// Etc
private void refreshSecondarySkills(TowerChangeData data) {
// Init
var newSecondarySkills = SecondarySkillDef.calculateSecondarySkills(this.getDiscIds(), this.getItems());
int newSecondaryCount = 0;
// Add any new secondary skills to the data proto
for (int id : newSecondarySkills) {
if (!this.getSecondarySkills().contains(id)) {
var info = ActiveSecondaryChange.newInstance()
.setSecondaryId(id)
.setActive(true);
data.addSecondaries(info);
// Counter
newSecondaryCount++;
}
}
// Inform the client that these skills are no longer active
for (int id : this.getSecondarySkills()) {
if (!newSecondarySkills.contains(id)) {
var info = ActiveSecondaryChange.newInstance()
.setSecondaryId(id)
.setActive(false);
data.addSecondaries(info);
}
}
// Set new secondary skills
this.secondarySkills = newSecondarySkills;
// Achievement trigger
if (newSecondaryCount > 0) {
this.getAchievementManager().trigger(
AchievementCondition.TowerSpecificSecondarySkillActivateTotal,
newSecondaryCount
);
}
}
// Proto // Proto
public StarTowerInfo toProto() { public StarTowerInfo toProto() {
@@ -12,6 +12,7 @@ import emu.nebula.game.quest.QuestCondition;
import emu.nebula.proto.StarTowerApply.StarTowerApplyReq; import emu.nebula.proto.StarTowerApply.StarTowerApplyReq;
import emu.nebula.util.Utils; import emu.nebula.util.Utils;
import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
@@ -34,6 +35,10 @@ public class StarTowerManager extends PlayerManager {
return this.getPlayer().getProgress(); return this.getPlayer().getProgress();
} }
public IntSet getStarTowerLog() {
return this.getProgress().getStarTowerLog();
}
// Growth nodes (talents/research) // Growth nodes (talents/research)
public boolean hasGrowthNode(int id) { public boolean hasGrowthNode(int id) {
@@ -240,23 +245,20 @@ public class StarTowerManager extends PlayerManager {
var achievements = this.getPlayer().getAchievementManager(); var achievements = this.getPlayer().getAchievementManager();
achievements.trigger(AchievementCondition.TowerClearTotal, 1); achievements.trigger(AchievementCondition.TowerClearTotal, 1);
achievements.trigger(
AchievementCondition.TowerClearSpecificGroupIdAndDifficulty,
1,
game.getData().getGroupId(),
game.getData().getDifficulty()
);
achievements.trigger( achievements.trigger(
AchievementCondition.TowerClearSpecificLevelWithDifficultyAndTotal, AchievementCondition.TowerClearSpecificLevelWithDifficultyAndTotal,
1, 1,
game.getData().getId(), game.getData().getId(),
game.getData().getDifficulty() 0
); );
var elementType = game.getTeamElement(); var elementType = game.getTeamElement();
if (elementType != null) { if (elementType != null) {
achievements.trigger(AchievementCondition.TowerClearSpecificCharacterTypeWithTotal, 1, elementType.getValue(), 0); achievements.trigger(AchievementCondition.TowerClearSpecificCharacterTypeWithTotal, 1, elementType.getValue(), 0);
} }
// Update tower group achievements
this.updateTowerGroupAchievements(game);
} }
// Return game // Return game
@@ -290,6 +292,35 @@ public class StarTowerManager extends PlayerManager {
return change; return change;
} }
// Achievements
private void updateTowerGroupAchievements(StarTowerGame game) {
// Update "First Ascension" achievement
boolean firstAscension = this.getStarTowerLog().contains(401) && this.getStarTowerLog().size() >= 2;
if (firstAscension) {
this.getPlayer().getAchievementManager().triggerOne(498, 1, 0, 1);
}
// Get total clears on this difficulty
int diff = game.getDifficulty();
int totalDiffClears = 0;
for (int i = 1; i <= 3; i++) {
int towerId = (i * 100) + 1 + diff;
if (this.getStarTowerLog().contains(towerId)) {
totalDiffClears++;
}
}
// Update "Monolith Conqueror" achievements
this.getPlayer().getAchievementManager().trigger(
AchievementCondition.TowerClearSpecificGroupIdAndDifficulty,
totalDiffClears,
diff,
0
);
}
// Build // Build
private PlayerChangeInfo dismantleBuild(StarTowerBuild build, PlayerChangeInfo change) { private PlayerChangeInfo dismantleBuild(StarTowerBuild build, PlayerChangeInfo change) {
@@ -209,9 +209,13 @@ public class StarTowerHawkerCase extends StarTowerBaseCase {
// Remove coins // Remove coins
this.getGame().addItem(GameConstants.TOWER_COIN_ITEM_ID, -price, change); this.getGame().addItem(GameConstants.TOWER_COIN_ITEM_ID, -price, change);
// Achievement // Achievements
this.getGame().getAchievementManager().trigger(AchievementCondition.TowerSpecificDifficultyShopBuyTimes, 1); this.getGame().getAchievementManager().trigger(AchievementCondition.TowerSpecificDifficultyShopBuyTimes, 1);
if (goods.hasDiscount()) {
this.getGame().getAchievementManager().trigger(AchievementCondition.TowerSpecificShopBuyDiscountTotal, 1);
}
// Set change info // Set change info
rsp.setChange(change.toProto()); rsp.setChange(change.toProto());
} }