mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-12-17 01:15:52 +01:00
Simply implement achievement system and add achievement command (#2068)
* Implement achievement system * Update src/main/java/emu/grasscutter/command/commands/AchievementCommand.java Co-authored-by: Der Chien <b03902015@ntu.edu.tw> * fix: redundant codes * fix: redundant codes * Update language files --------- Co-authored-by: Der Chien <b03902015@ntu.edu.tw>
This commit is contained in:
@@ -41,6 +41,8 @@ public class GameData {
|
||||
|
||||
// ExcelConfigs
|
||||
@Getter private static final ArrayList<CodexReliquaryData> codexReliquaryArrayList = new ArrayList<>();
|
||||
private static final Int2ObjectMap<AchievementData> achievementDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<AchievementGoalData> achievementGoalDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<ActivityData> activityDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<ActivityShopData> activityShopDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static final Int2ObjectMap<ActivityWatcherData> activityWatcherDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@@ -233,4 +235,9 @@ public class GameData {
|
||||
|
||||
return shopGoods;
|
||||
}
|
||||
|
||||
public static Int2ObjectMap<AchievementData> getAchievementDataMap() {
|
||||
AchievementData.divideIntoGroups();
|
||||
return achievementDataMap;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import com.github.davidmoten.guavamini.Lists;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "AchievementExcelConfigData.json")
|
||||
public class AchievementData extends GameResource {
|
||||
private static final AtomicBoolean isDivided = new AtomicBoolean();
|
||||
private int goalId;
|
||||
private int preStageAchievementId;
|
||||
private Set<Integer> groupAchievementIdList = new HashSet<>();
|
||||
private boolean isParent;
|
||||
private long titleTextMapHash;
|
||||
private long descTextMapHash;
|
||||
private int finishRewardId;
|
||||
private boolean isDeleteWatcherAfterFinish;
|
||||
private int id;
|
||||
private BattlePassMissionData.TriggerConfig triggerConfig;
|
||||
private int progress;
|
||||
private boolean isDisuse;
|
||||
|
||||
public boolean hasPreStageAchievement() {
|
||||
return this.preStageAchievementId != 0;
|
||||
}
|
||||
|
||||
public boolean hasGroupAchievements() {
|
||||
return !this.groupAchievementIdList.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isUsed() {
|
||||
return !this.isDisuse;
|
||||
}
|
||||
|
||||
public Set<Integer> getGroupAchievementIdList() {
|
||||
return this.groupAchievementIdList.stream().collect(Collectors.toUnmodifiableSet());
|
||||
}
|
||||
|
||||
public Set<Integer> getExcludedGroupAchievementIdList() {
|
||||
return this.groupAchievementIdList.stream().filter(integer -> integer != this.getId()).collect(Collectors.toUnmodifiableSet());
|
||||
}
|
||||
|
||||
public static void divideIntoGroups() {
|
||||
if (isDivided.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
isDivided.set(true);
|
||||
var map = GameData.getAchievementDataMap();
|
||||
var achievementDataList = map.values().stream().filter(AchievementData::isUsed).toList();
|
||||
for (var data : achievementDataList) {
|
||||
if (!data.hasPreStageAchievement() || data.hasGroupAchievements()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<Integer> ids = Lists.newArrayList();
|
||||
int parentId = data.getId();
|
||||
while (true) {
|
||||
var next = map.get(parentId + 1);
|
||||
if (next == null || parentId != next.getPreStageAchievementId()) {
|
||||
break;
|
||||
}
|
||||
|
||||
parentId++;
|
||||
}
|
||||
|
||||
map.get(parentId).isParent = true;
|
||||
|
||||
while (true) {
|
||||
ids.add(parentId);
|
||||
var previous = map.get(--parentId);
|
||||
if (previous == null) {
|
||||
break;
|
||||
} else if (!previous.hasPreStageAchievement()) {
|
||||
ids.add(parentId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i : ids) {
|
||||
map.get(i).groupAchievementIdList.addAll(ids);
|
||||
}
|
||||
}
|
||||
|
||||
map.values().stream().filter(a -> !a.hasGroupAchievements() && a.isUsed()).forEach(a -> a.isParent = true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "AchievementGoalExcelConfigData.json")
|
||||
public class AchievementGoalData extends GameResource {
|
||||
private int id;
|
||||
private long nameTextMapHash;
|
||||
private int finishRewardId;
|
||||
}
|
||||
Reference in New Issue
Block a user