mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-11-22 13:15:39 +00:00
Implement battle pass triggers/rewards
This commit is contained in:
parent
34f7c6e780
commit
5eb1d34b14
@ -18,6 +18,10 @@ public final class GameConstants {
|
||||
|
||||
public static final int SERVER_CONSOLE_UID = 99; // The UID of the server console's "player".
|
||||
|
||||
public static final int BATTLE_PASS_MAX_LEVEL = 50;
|
||||
public static final int BATTLE_PASS_POINT_PER_LEVEL = 1000;
|
||||
public static final int BATTLE_PASS_LEVEL_PRICE = 150;
|
||||
|
||||
// Default entity ability hashes.
|
||||
public static final String[] DEFAULT_ABILITY_STRINGS = {
|
||||
"Avatar_DefaultAbility_VisionReplaceDieInvincible", "Avatar_DefaultAbility_AvartarInShaderChange", "Avatar_SprintBS_Invincible",
|
||||
|
@ -17,7 +17,6 @@ public final class SetBPLevelCommand implements CommandHandler {
|
||||
|
||||
int level = Integer.parseInt(args.get(0));
|
||||
|
||||
sender.getBattlePassManager().addPoint(level);
|
||||
sender.getBattlePassManager().updateAwardTakenLevel(0);
|
||||
sender.getBattlePassManager().addPoints(level);
|
||||
}
|
||||
}
|
||||
|
@ -95,8 +95,8 @@ public class GameData {
|
||||
private static final Int2ObjectMap<InvestigationMonsterData> investigationMonsterDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CityData> cityDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<WeatherData> weatherDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<BattlePassMissionExcelConfigData> battlePassMissionExcelConfigDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<BattlePassRewardExcelConfigData> battlePassRewardExcelConfigDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<BattlePassMissionData> battlePassMissionDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<BattlePassRewardData> battlePassRewardDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
// Cache
|
||||
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
|
||||
@ -424,11 +424,11 @@ public class GameData {
|
||||
return weatherDataMap;
|
||||
}
|
||||
|
||||
public static Int2ObjectMap<BattlePassMissionExcelConfigData> getBattlePassMissionExcelConfigDataMap() {
|
||||
return battlePassMissionExcelConfigDataMap;
|
||||
public static Int2ObjectMap<BattlePassMissionData> getBattlePassMissionDataMap() {
|
||||
return battlePassMissionDataMap;
|
||||
}
|
||||
|
||||
public static Int2ObjectMap<BattlePassRewardExcelConfigData> getBattlePassRewardExcelConfigDataMap() {
|
||||
return battlePassRewardExcelConfigDataMap;
|
||||
public static Int2ObjectMap<BattlePassRewardData> getBattlePassRewardDataMap() {
|
||||
return battlePassRewardDataMap;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,69 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.props.BattlePassMissionRefreshType;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import emu.grasscutter.net.proto.BattlePassMissionOuterClass.BattlePassMission.MissionStatus;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@ResourceType(name = {"BattlePassMissionExcelConfigData.json"})
|
||||
@Getter
|
||||
public class BattlePassMissionData extends GameResource {
|
||||
private int addPoint;
|
||||
private int id;
|
||||
private int scheduleId;
|
||||
private int progress;
|
||||
private TriggerConfig triggerConfig;
|
||||
private BattlePassMissionRefreshType refreshType;
|
||||
|
||||
private transient Set<Integer> mainParams;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public WatcherTriggerType getTriggerType() {
|
||||
return this.getTriggerConfig().getTriggerType();
|
||||
}
|
||||
|
||||
public boolean isValidRefreshType() {
|
||||
return getRefreshType() == null ||
|
||||
getRefreshType() == BattlePassMissionRefreshType.BATTLE_PASS_MISSION_REFRESH_CYCLE_CROSS_SCHEDULE ||
|
||||
getScheduleId() == 2701;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
if (this.getTriggerConfig() != null && getTriggerConfig().getParamList()[0].length() > 0) {
|
||||
this.mainParams = Arrays.stream(getTriggerConfig().getParamList()[0].split("[:;,]")).map(Integer::parseInt).collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class TriggerConfig {
|
||||
private WatcherTriggerType triggerType;
|
||||
private String[] paramList;
|
||||
}
|
||||
|
||||
public emu.grasscutter.net.proto.BattlePassMissionOuterClass.BattlePassMission toProto() {
|
||||
var protoBuilder = emu.grasscutter.net.proto.BattlePassMissionOuterClass.BattlePassMission.newBuilder();
|
||||
|
||||
protoBuilder
|
||||
.setMissionId(getId())
|
||||
.setTotalProgress(this.getProgress())
|
||||
.setRewardBattlePassPoint(this.getAddPoint())
|
||||
.setMissionStatus(MissionStatus.MISSION_STATUS_UNFINISHED)
|
||||
.setMissionType(this.getRefreshType() == null ? 0 : this.getRefreshType().getValue());
|
||||
|
||||
return protoBuilder.build();
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@ResourceType(name = {"BattlePassMissionExcelConfigData.json"})
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
@Getter
|
||||
@Setter
|
||||
public class BattlePassMissionExcelConfigData extends GameResource {
|
||||
|
||||
private int addPoint;
|
||||
private int id;
|
||||
private int progress;
|
||||
private String refreshType;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
}
|
@ -9,8 +9,7 @@ import java.util.List;
|
||||
|
||||
@ResourceType(name = "BattlePassRewardExcelConfigData.json")
|
||||
@Getter
|
||||
@Setter
|
||||
public class BattlePassRewardExcelConfigData extends GameResource {
|
||||
public class BattlePassRewardData extends GameResource {
|
||||
private int indexId;
|
||||
private int level;
|
||||
private List<Integer> freeRewardIdList;
|
||||
@ -23,5 +22,6 @@ public class BattlePassRewardExcelConfigData extends GameResource {
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
|
||||
}
|
||||
}
|
@ -131,6 +131,7 @@ public final class DatabaseHelper {
|
||||
DatabaseManager.getGameDatabase().getCollection("gachas").deleteMany(eq("ownerId", player.getUid()));
|
||||
DatabaseManager.getGameDatabase().getCollection("items").deleteMany(eq("ownerId", player.getUid()));
|
||||
DatabaseManager.getGameDatabase().getCollection("quests").deleteMany(eq("ownerUid", player.getUid()));
|
||||
DatabaseManager.getGameDatabase().getCollection("battlepass").deleteMany(eq("ownerUid", player.getUid()));
|
||||
|
||||
// Delete friendships.
|
||||
// Here, we need to make sure to not only delete the deleted account's friendships,
|
||||
|
@ -1,14 +1,34 @@
|
||||
package emu.grasscutter.game.battlepass;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Id;
|
||||
import dev.morphia.annotations.Indexed;
|
||||
import dev.morphia.annotations.Transient;
|
||||
import emu.grasscutter.GameConstants;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
import emu.grasscutter.data.excels.BattlePassRewardData;
|
||||
import emu.grasscutter.data.excels.RewardData;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.game.props.BattlePassMissionStatus;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import emu.grasscutter.net.proto.BattlePassCycleOuterClass.BattlePassCycle;
|
||||
import emu.grasscutter.net.proto.BattlePassRewardTagOuterClass.BattlePassRewardTag;
|
||||
import emu.grasscutter.net.proto.BattlePassUnlockStatusOuterClass.BattlePassUnlockStatus;
|
||||
import emu.grasscutter.net.proto.BattlePassRewardTakeOptionOuterClass.BattlePassRewardTakeOption;
|
||||
import emu.grasscutter.net.proto.BattlePassScheduleOuterClass.BattlePassSchedule;
|
||||
import emu.grasscutter.server.packet.send.PacketBattlePassCurScheduleUpdateNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketBattlePassMissionUpdateNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketTakeBattlePassRewardRsp;
|
||||
|
||||
@Entity(value = "battlepass", useDiscriminator = false)
|
||||
public class BattlePassManager {
|
||||
@ -17,7 +37,13 @@ public class BattlePassManager {
|
||||
|
||||
@Indexed private int ownerUid;
|
||||
private int point;
|
||||
private int awardTakenLevel;
|
||||
private int level;
|
||||
|
||||
private boolean viewed;
|
||||
private boolean paid;
|
||||
|
||||
private Map<Integer, BattlePassMission> missions;
|
||||
private Map<Integer, BattlePassReward> takenRewards;
|
||||
|
||||
@Deprecated // Morphia only
|
||||
public BattlePassManager() {}
|
||||
@ -40,25 +66,215 @@ public class BattlePassManager {
|
||||
}
|
||||
|
||||
public int getPoint() {
|
||||
return point;
|
||||
}
|
||||
|
||||
public int getAwardTakenLevel() {
|
||||
return awardTakenLevel;
|
||||
}
|
||||
|
||||
public void addPoint(int point){
|
||||
this.point += point;
|
||||
player.getSession().send(new PacketBattlePassCurScheduleUpdateNotify(player.getSession().getPlayer()));
|
||||
this.save();
|
||||
}
|
||||
|
||||
public void updateAwardTakenLevel(int level){
|
||||
this.awardTakenLevel = level;
|
||||
player.getSession().send(new PacketBattlePassCurScheduleUpdateNotify(player.getSession().getPlayer()));
|
||||
this.save();
|
||||
return this.point;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return this.level;
|
||||
}
|
||||
|
||||
public boolean isViewed() {
|
||||
return viewed;
|
||||
}
|
||||
|
||||
public void updateViewed() {
|
||||
this.viewed = true;
|
||||
}
|
||||
|
||||
public boolean isPaid() {
|
||||
return paid;
|
||||
}
|
||||
|
||||
public void addPoints(int point){
|
||||
this.addPointsDirectly(point);
|
||||
|
||||
player.getSession().send(new PacketBattlePassCurScheduleUpdateNotify(player.getSession().getPlayer()));
|
||||
this.save();
|
||||
}
|
||||
|
||||
public void addPointsDirectly(int point) {
|
||||
this.point += point;
|
||||
|
||||
if (this.point >= GameConstants.BATTLE_PASS_POINT_PER_LEVEL && this.getLevel() < GameConstants.BATTLE_PASS_MAX_LEVEL) {
|
||||
int levelups = (int) Math.floor((float) this.point / GameConstants.BATTLE_PASS_POINT_PER_LEVEL);
|
||||
|
||||
// Make sure player cant go above max BP level
|
||||
levelups = Math.min(levelups, GameConstants.BATTLE_PASS_MAX_LEVEL - levelups);
|
||||
|
||||
// Set new points after level up
|
||||
this.point = this.point - (levelups * GameConstants.BATTLE_PASS_POINT_PER_LEVEL);
|
||||
this.level += levelups;
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Integer, BattlePassMission> getMissions() {
|
||||
if (this.missions == null) this.missions = new HashMap<>();
|
||||
return this.missions;
|
||||
}
|
||||
|
||||
// Will return a new empty mission if the mission id is not found
|
||||
public BattlePassMission loadMissionById(int id) {
|
||||
return getMissions().computeIfAbsent(id, i -> new BattlePassMission(i));
|
||||
}
|
||||
|
||||
public boolean hasMission(int id) {
|
||||
return getMissions().containsKey(id);
|
||||
}
|
||||
|
||||
public Map<Integer, BattlePassReward> getTakenRewards() {
|
||||
if (this.takenRewards == null) this.takenRewards = new HashMap<>();
|
||||
return this.takenRewards;
|
||||
}
|
||||
|
||||
// Mission triggers
|
||||
public void triggerMission(WatcherTriggerType triggerType) {
|
||||
getPlayer().getServer().getBattlePassMissionManager().triggerMission(getPlayer(), triggerType);
|
||||
}
|
||||
|
||||
public void triggerMission(WatcherTriggerType triggerType, int param, int progress) {
|
||||
getPlayer().getServer().getBattlePassMissionManager().triggerMission(getPlayer(), triggerType, param, progress);
|
||||
}
|
||||
|
||||
// Handlers
|
||||
public void takeMissionPoint(List<Integer> missionIdList) {
|
||||
// Obvious exploit check
|
||||
if (missionIdList.size() > GameData.getBattlePassMissionDataMap().size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<BattlePassMission> updatedMissions = new ArrayList<>(missionIdList.size());
|
||||
|
||||
for (int id : missionIdList) {
|
||||
// Skip if we dont have this mission
|
||||
if (!this.hasMission(id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BattlePassMission mission = this.loadMissionById(id);
|
||||
|
||||
if (mission.getData() == null) {
|
||||
this.getMissions().remove(mission.getId());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Take reward
|
||||
if (mission.getStatus() == BattlePassMissionStatus.MISSION_STATUS_FINISHED) {
|
||||
this.addPointsDirectly(mission.getData().getAddPoint());
|
||||
mission.setStatus(BattlePassMissionStatus.MISSION_STATUS_POINT_TAKEN);
|
||||
|
||||
updatedMissions.add(mission);
|
||||
}
|
||||
}
|
||||
|
||||
if (updatedMissions.size() > 0) {
|
||||
// Save to db
|
||||
this.save();
|
||||
|
||||
// Packet
|
||||
getPlayer().sendPacket(new PacketBattlePassMissionUpdateNotify(updatedMissions));
|
||||
getPlayer().sendPacket(new PacketBattlePassCurScheduleUpdateNotify(getPlayer()));
|
||||
}
|
||||
}
|
||||
|
||||
public void takeReward(List<BattlePassRewardTakeOption> takeOptionList) {
|
||||
List<BattlePassRewardTag> rewardList = new ArrayList<>();
|
||||
|
||||
for (BattlePassRewardTakeOption option : takeOptionList) {
|
||||
// Duplicate check
|
||||
if (option.getTag().getRewardId() == 0 || getTakenRewards().containsKey(option.getTag().getRewardId())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Level check
|
||||
if (option.getTag().getLevel() > this.getLevel()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BattlePassRewardData rewardData = GameData.getBattlePassRewardDataMap().get(option.getTag().getLevel());
|
||||
|
||||
// Sanity check with excel data
|
||||
if (rewardData.getFreeRewardIdList().contains(option.getTag().getRewardId())) {
|
||||
rewardList.add(option.getTag());
|
||||
} else if (this.isPaid() && rewardData.getPaidRewardIdList().contains(option.getTag().getRewardId())) {
|
||||
rewardList.add(option.getTag());
|
||||
}
|
||||
}
|
||||
|
||||
// Get rewards
|
||||
List<ItemParamData> rewardItems = null;
|
||||
|
||||
if (rewardList.size() > 0) {
|
||||
rewardItems = new ArrayList<>();
|
||||
|
||||
for (BattlePassRewardTag tag : rewardList) {
|
||||
RewardData reward = GameData.getRewardDataMap().get(tag.getRewardId());
|
||||
|
||||
if (reward == null) continue;
|
||||
|
||||
BattlePassReward bpReward = new BattlePassReward(tag.getLevel(), tag.getRewardId(), tag.getUnlockStatus() == BattlePassUnlockStatus.BATTLE_PASS_UNLOCK_STATUS_PAID);
|
||||
this.getTakenRewards().put(bpReward.getRewardId(), bpReward);
|
||||
|
||||
rewardItems.addAll(reward.getRewardItemList());
|
||||
}
|
||||
|
||||
// Save to db
|
||||
this.save();
|
||||
|
||||
// Add items and send battle pass schedule packet
|
||||
getPlayer().getInventory().addItemParamDatas(rewardItems);
|
||||
getPlayer().sendPacket(new PacketBattlePassCurScheduleUpdateNotify(getPlayer()));
|
||||
}
|
||||
|
||||
getPlayer().sendPacket(new PacketTakeBattlePassRewardRsp(takeOptionList, rewardItems));
|
||||
}
|
||||
|
||||
public int buyLevels(int buyLevel) {
|
||||
int boughtLevels = Math.min(buyLevel, GameConstants.BATTLE_PASS_MAX_LEVEL - buyLevel);
|
||||
|
||||
if (boughtLevels > 0) {
|
||||
int price = GameConstants.BATTLE_PASS_LEVEL_PRICE * boughtLevels;
|
||||
|
||||
if (getPlayer().getPrimogems() < price) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
this.level += boughtLevels;
|
||||
this.save();
|
||||
|
||||
getPlayer().sendPacket(new PacketBattlePassCurScheduleUpdateNotify(getPlayer()));
|
||||
}
|
||||
|
||||
return boughtLevels;
|
||||
}
|
||||
|
||||
public void resetDailyMissions() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
public void resetWeeklyMissions() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
//
|
||||
public BattlePassSchedule getScheduleProto() {
|
||||
BattlePassSchedule.Builder schedule = BattlePassSchedule.newBuilder()
|
||||
.setScheduleId(2700)
|
||||
.setLevel(this.getLevel())
|
||||
.setPoint(this.getPoint())
|
||||
.setBeginTime(0)
|
||||
.setEndTime(2059483200)
|
||||
.setIsViewed(this.isViewed())
|
||||
.setUnlockStatus(this.isPaid() ? BattlePassUnlockStatus.BATTLE_PASS_UNLOCK_STATUS_PAID : BattlePassUnlockStatus.BATTLE_PASS_UNLOCK_STATUS_FREE)
|
||||
.setCurCyclePoints(0)
|
||||
.setCurCycle(BattlePassCycle.newBuilder().setBeginTime(0).setEndTime(2059483200).setCycleIdx(3));
|
||||
|
||||
for (BattlePassReward reward : getTakenRewards().values()) {
|
||||
schedule.addRewardTakenList(reward.toProto());
|
||||
}
|
||||
|
||||
return schedule.build();
|
||||
}
|
||||
|
||||
public void save() {
|
||||
DatabaseHelper.saveBattlePass(this);
|
||||
}
|
||||
|
@ -0,0 +1,70 @@
|
||||
package emu.grasscutter.game.battlepass;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Transient;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.BattlePassMissionData;
|
||||
import emu.grasscutter.game.props.BattlePassMissionStatus;
|
||||
|
||||
@Entity
|
||||
public class BattlePassMission {
|
||||
private int id;
|
||||
private int progress;
|
||||
private BattlePassMissionStatus status;
|
||||
|
||||
@Transient
|
||||
private BattlePassMissionData data;
|
||||
|
||||
@Deprecated // Morphia only
|
||||
public BattlePassMission() {}
|
||||
|
||||
public BattlePassMission(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public BattlePassMissionData getData() {
|
||||
if (this.data == null) {
|
||||
this.data = GameData.getBattlePassMissionDataMap().get(getId());
|
||||
}
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public int getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
public void addProgress(int addProgress, int maxProgress) {
|
||||
this.progress = Math.min(addProgress + this.progress, maxProgress);
|
||||
}
|
||||
|
||||
public BattlePassMissionStatus getStatus() {
|
||||
if (status == null) status = BattlePassMissionStatus.MISSION_STATUS_UNFINISHED;
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(BattlePassMissionStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public boolean isFinshed() {
|
||||
return getStatus().getValue() >= 2;
|
||||
}
|
||||
|
||||
public emu.grasscutter.net.proto.BattlePassMissionOuterClass.BattlePassMission toProto() {
|
||||
var protoBuilder = emu.grasscutter.net.proto.BattlePassMissionOuterClass.BattlePassMission.newBuilder();
|
||||
|
||||
protoBuilder
|
||||
.setMissionId(getId())
|
||||
.setCurProgress(getProgress())
|
||||
.setTotalProgress(getData().getProgress())
|
||||
.setRewardBattlePassPoint(getData().getAddPoint())
|
||||
.setMissionStatus(getStatus().getMissionStatus())
|
||||
.setMissionType(getData().getRefreshType() == null ? 0 : getData().getRefreshType().getValue());
|
||||
|
||||
return protoBuilder.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package emu.grasscutter.game.battlepass;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.BattlePassMissionData;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.BattlePassMissionRefreshType;
|
||||
import emu.grasscutter.game.props.BattlePassMissionStatus;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import emu.grasscutter.server.game.GameServer;
|
||||
import emu.grasscutter.server.packet.send.PacketBattlePassMissionUpdateNotify;
|
||||
|
||||
public class BattlePassMissionManager {
|
||||
private final GameServer server;
|
||||
private final Map<WatcherTriggerType, List<BattlePassMissionData>> cachedTriggers;
|
||||
|
||||
// BP Mission manager for the server, contains cached triggers so we dont have to load it for each player
|
||||
public BattlePassMissionManager(GameServer server) {
|
||||
this.server = server;
|
||||
this.cachedTriggers = new HashMap<>();
|
||||
|
||||
for (BattlePassMissionData missionData : GameData.getBattlePassMissionDataMap().values()) {
|
||||
if (missionData.isValidRefreshType()) {
|
||||
List<BattlePassMissionData> triggerList = getTriggers().computeIfAbsent(missionData.getTriggerType(), e -> new ArrayList<>());
|
||||
triggerList.add(missionData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public GameServer getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
private Map<WatcherTriggerType, List<BattlePassMissionData>> getTriggers() {
|
||||
return cachedTriggers;
|
||||
}
|
||||
|
||||
public void triggerMission(Player player, WatcherTriggerType triggerType) {
|
||||
triggerMission(player, triggerType, 0, 1);
|
||||
}
|
||||
|
||||
public void triggerMission(Player player, WatcherTriggerType triggerType, int param, int progress) {
|
||||
List<BattlePassMissionData> triggerList = getTriggers().get(triggerType);
|
||||
|
||||
if (triggerList == null || triggerList.isEmpty()) return;
|
||||
|
||||
for (BattlePassMissionData data : triggerList) {
|
||||
// Skip params check if param == 0
|
||||
if (param != 0) {
|
||||
if (!data.getMainParams().contains(param)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Get mission from player, if it doesnt exist, then we make one
|
||||
BattlePassMission mission = player.getBattlePassManager().loadMissionById(data.getId());
|
||||
|
||||
if (mission.isFinshed()) continue;
|
||||
|
||||
// Add progress
|
||||
mission.addProgress(progress, data.getProgress());
|
||||
|
||||
if (mission.getProgress() >= data.getProgress()) {
|
||||
mission.setStatus(BattlePassMissionStatus.MISSION_STATUS_FINISHED);
|
||||
}
|
||||
|
||||
// Save to db
|
||||
player.getBattlePassManager().save();
|
||||
|
||||
// Packet
|
||||
player.sendPacket(new PacketBattlePassMissionUpdateNotify(mission));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package emu.grasscutter.game.battlepass;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Transient;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.BattlePassMissionData;
|
||||
import emu.grasscutter.data.excels.BattlePassRewardData;
|
||||
import emu.grasscutter.game.props.BattlePassMissionStatus;
|
||||
import emu.grasscutter.net.proto.BattlePassRewardTagOuterClass.BattlePassRewardTag;
|
||||
import emu.grasscutter.net.proto.BattlePassUnlockStatusOuterClass.BattlePassUnlockStatus;
|
||||
|
||||
@Entity
|
||||
public class BattlePassReward {
|
||||
private int level;
|
||||
private int rewardId;
|
||||
private boolean paid;
|
||||
|
||||
@Transient
|
||||
private BattlePassMissionData data;
|
||||
|
||||
@Deprecated // Morphia only
|
||||
public BattlePassReward() {}
|
||||
|
||||
public BattlePassReward(int level, int rewardId, boolean paid) {
|
||||
this.level = level;
|
||||
this.rewardId = rewardId;
|
||||
this.paid = paid;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public int getRewardId() {
|
||||
return rewardId;
|
||||
}
|
||||
|
||||
public boolean isPaid() {
|
||||
return paid;
|
||||
}
|
||||
|
||||
public BattlePassRewardTag toProto() {
|
||||
var protoBuilder = BattlePassRewardTag.newBuilder();
|
||||
|
||||
protoBuilder
|
||||
.setLevel(this.getLevel())
|
||||
.setRewardId(this.getRewardId())
|
||||
.setUnlockStatus(this.isPaid() ? BattlePassUnlockStatus.BATTLE_PASS_UNLOCK_STATUS_PAID : BattlePassUnlockStatus.BATTLE_PASS_UNLOCK_STATUS_FREE);
|
||||
|
||||
return protoBuilder.build();
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.inventory.ItemType;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq;
|
||||
import emu.grasscutter.scripts.constants.EventType;
|
||||
@ -98,6 +99,8 @@ public class DungeonChallenge extends WorldChallenge {
|
||||
getScene().getDungeonSettleObservers().forEach(o -> o.onDungeonSettle(getScene()));
|
||||
getScene().getScriptManager().callEvent(EventType.EVENT_DUNGEON_SETTLE,
|
||||
new ScriptArgs(this.isSuccess() ? 1 : 0));
|
||||
// Battle pass trigger
|
||||
this.getScene().getPlayers().forEach(p -> p.getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_FINISH_DUNGEON));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.EntityIdType;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.game.props.PlayerProperty;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo;
|
||||
import emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair;
|
||||
@ -154,6 +155,8 @@ public class EntityMonster extends GameEntity {
|
||||
getScene().getScriptManager().callEvent(EventType.EVENT_ANY_MONSTER_DIE, new ScriptArgs().setParam1(this.getConfigId()));
|
||||
}
|
||||
}
|
||||
// Battle Pass trigger
|
||||
getScene().getPlayers().forEach(p -> p.getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_MONSTER_DIE, this.getMonsterId(), 1));
|
||||
}
|
||||
|
||||
public void recalcStats() {
|
||||
|
@ -27,6 +27,7 @@ import emu.grasscutter.game.inventory.Inventory;
|
||||
import emu.grasscutter.game.inventory.ItemType;
|
||||
import emu.grasscutter.game.inventory.MaterialType;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import emu.grasscutter.net.proto.GachaItemOuterClass.GachaItem;
|
||||
import emu.grasscutter.net.proto.GachaTransferItemOuterClass.GachaTransferItem;
|
||||
import emu.grasscutter.net.proto.GetGachaInfoRspOuterClass.GetGachaInfoRsp;
|
||||
@ -372,9 +373,12 @@ public class GachaManager {
|
||||
if (starglitter > 0) {
|
||||
inventory.addItem(starglitterId, starglitter);
|
||||
}
|
||||
|
||||
|
||||
// Packets
|
||||
player.sendPacket(new PacketDoGachaRsp(banner, list, gachaInfo));
|
||||
|
||||
// Battle Pass trigger
|
||||
player.getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_GACHA_NUM, 0, times);
|
||||
}
|
||||
|
||||
private synchronized void startWatcher(GameServer server) {
|
||||
|
@ -18,6 +18,7 @@ import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.game.props.PlayerProperty;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam;
|
||||
import emu.grasscutter.server.packet.send.PacketAvatarEquipChangeNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
|
||||
@ -95,6 +96,7 @@ public class Inventory implements Iterable<GameItem> {
|
||||
GameItem result = putItem(item);
|
||||
|
||||
if (result != null) {
|
||||
getPlayer().getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_OBTAIN_MATERIAL_NUM, result.getItemId(), result.getCount());
|
||||
getPlayer().sendPacket(new PacketStoreItemChangeNotify(result));
|
||||
return true;
|
||||
}
|
||||
@ -131,7 +133,9 @@ public class Inventory implements Iterable<GameItem> {
|
||||
|
||||
for (GameItem item : items) {
|
||||
GameItem result = putItem(item);
|
||||
|
||||
if (result != null) {
|
||||
getPlayer().getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_OBTAIN_MATERIAL_NUM, result.getItemId(), result.getCount());
|
||||
changedItems.add(result);
|
||||
}
|
||||
}
|
||||
@ -368,7 +372,7 @@ public class Inventory implements Iterable<GameItem> {
|
||||
if (count <= 0 || item == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (item.getItemData().isEquip()) {
|
||||
item.setCount(0);
|
||||
} else {
|
||||
@ -389,6 +393,10 @@ public class Inventory implements Iterable<GameItem> {
|
||||
getPlayer().sendPacket(new PacketStoreItemChangeNotify(item));
|
||||
}
|
||||
|
||||
// Battle pass trigger
|
||||
int removeCount = Math.min(count, item.getCount());
|
||||
getPlayer().getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_COST_MATERIAL, item.getItemId(), removeCount);
|
||||
|
||||
// Update in db
|
||||
item.save();
|
||||
|
||||
|
@ -2,6 +2,7 @@ package emu.grasscutter.game.managers;
|
||||
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.PlayerProperty;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import emu.grasscutter.server.packet.send.PacketPlayerPropNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketResinChangeNotify;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
@ -45,7 +46,10 @@ public class ResinManager {
|
||||
// Send packets.
|
||||
this.player.sendPacket(new PacketPlayerPropNotify(this.player, PlayerProperty.PROP_PLAYER_RESIN));
|
||||
this.player.sendPacket(new PacketResinChangeNotify(this.player));
|
||||
|
||||
|
||||
// Battle Pass trigger
|
||||
this.player.getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_COST_MATERIAL, 106, amount); // Resin item id = 106
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.inventory.ItemType;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import emu.grasscutter.net.proto.ForgeStartReqOuterClass;
|
||||
import emu.grasscutter.net.proto.ForgeQueueDataOuterClass.ForgeQueueData;
|
||||
import emu.grasscutter.net.proto.ForgeQueueManipulateReqOuterClass.ForgeQueueManipulateReq;
|
||||
@ -195,6 +196,9 @@ public class ForgingManager {
|
||||
|
||||
GameItem addItem = new GameItem(resultItemData, data.getResultItemCount() * finished);
|
||||
this.player.getInventory().addItem(addItem);
|
||||
|
||||
// Battle pass trigger handler
|
||||
this.player.getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_DO_FORGE, 0, finished);
|
||||
|
||||
// Replace active forge with a new one for the unfinished items, if there are any.
|
||||
if (unfinished > 0) {
|
||||
|
@ -42,6 +42,7 @@ import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.game.props.ClimateType;
|
||||
import emu.grasscutter.game.props.PlayerProperty;
|
||||
import emu.grasscutter.game.props.SceneType;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import emu.grasscutter.game.quest.QuestManager;
|
||||
import emu.grasscutter.game.shop.ShopLimit;
|
||||
import emu.grasscutter.game.tower.TowerData;
|
||||
@ -1268,6 +1269,7 @@ public class Player {
|
||||
public void loadBattlePassManager() {
|
||||
if (this.battlePassManager != null) return;
|
||||
this.battlePassManager = DatabaseHelper.loadBattlePass(this);
|
||||
this.battlePassManager.getMissions().values().removeIf(mission -> mission.getData() == null);
|
||||
}
|
||||
|
||||
public AbilityManager getAbilityManager() {
|
||||
@ -1425,6 +1427,9 @@ public class Player {
|
||||
|
||||
getTodayMoonCard(); // The timer works at 0:0, some users log in after that, use this method to check if they have received a reward today or not. If not, send the reward.
|
||||
|
||||
// Battle Pass trigger
|
||||
this.getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_LOGIN);
|
||||
|
||||
this.furnitureManager.onLogin();
|
||||
// Home
|
||||
home = GameHome.getByUid(getUid());
|
||||
|
@ -0,0 +1,18 @@
|
||||
package emu.grasscutter.game.props;
|
||||
|
||||
public enum BattlePassMissionRefreshType {
|
||||
BATTLE_PASS_MISSION_REFRESH_DAILY (0),
|
||||
BATTLE_PASS_MISSION_REFRESH_CYCLE_CROSS_SCHEDULE (1), // Weekly
|
||||
BATTLE_PASS_MISSION_REFRESH_SCHEDULE (2), // Per BP
|
||||
BATTLE_PASS_MISSION_REFRESH_CYCLE (1); // Event?
|
||||
|
||||
private final int value;
|
||||
|
||||
BattlePassMissionRefreshType(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package emu.grasscutter.game.props;
|
||||
|
||||
import emu.grasscutter.net.proto.BattlePassMissionOuterClass.BattlePassMission.MissionStatus;
|
||||
|
||||
public enum BattlePassMissionStatus {
|
||||
MISSION_STATUS_INVALID (0, MissionStatus.MISSION_STATUS_INVALID),
|
||||
MISSION_STATUS_UNFINISHED (1, MissionStatus.MISSION_STATUS_UNFINISHED),
|
||||
MISSION_STATUS_FINISHED (2, MissionStatus.MISSION_STATUS_FINISHED),
|
||||
MISSION_STATUS_POINT_TAKEN (3, MissionStatus.MISSION_STATUS_POINT_TAKEN);
|
||||
|
||||
private final int value;
|
||||
private final MissionStatus missionStatus;
|
||||
|
||||
BattlePassMissionStatus(int value, MissionStatus missionStatus) {
|
||||
this.value = value;
|
||||
this.missionStatus = missionStatus; // In case proto enum values change later
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public MissionStatus getMissionStatus() {
|
||||
return missionStatus;
|
||||
}
|
||||
}
|
337
src/main/java/emu/grasscutter/game/props/WatcherTriggerType.java
Normal file
337
src/main/java/emu/grasscutter/game/props/WatcherTriggerType.java
Normal file
@ -0,0 +1,337 @@
|
||||
package emu.grasscutter.game.props;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
public enum WatcherTriggerType {
|
||||
TRIGGER_NONE (0),
|
||||
TRIGGER_COMBAT_CONFIG_COMMON (1),
|
||||
TRIGGER_ELEMENT_VIEW (2),
|
||||
TRIGGER_ENTER_AIRFLOW (5),
|
||||
TRIGGER_NEW_MONSTER (6),
|
||||
TRIGGER_NEW_AFFIX (8),
|
||||
TRIGGER_CHANGE_INPUT_DEVICE_TYPE (9),
|
||||
TRIGGER_PAIMON_ANGRY_VOICE_EASTER_EGG (10),
|
||||
TRIGGER_WIND_CRYSTAL (11),
|
||||
TRIGGER_ELEMENT_BALL (101),
|
||||
TRIGGER_WORLD_LEVEL_UP (102),
|
||||
TRIGGER_DUNGEON_ENTRY_TO_BE_EXPLORED (103),
|
||||
TRIGGER_UNLOCK_GATE_TEMPLE (104),
|
||||
TRIGGER_UNLOCK_AREA (105),
|
||||
TRIGGER_UNLOCK_TRANS_POINT (106),
|
||||
TRIGGER_OPEN_CHEST_WITH_GADGET_ID (107),
|
||||
TRIGGER_CITY_LEVEL_UP (108),
|
||||
TRIGGER_MONSTER_DIE (109),
|
||||
TRIGGER_PLATFORM_START_MOVE (110),
|
||||
TRIGGER_GROUP_NOTIFY (111),
|
||||
TRIGGER_ELEMENT_TYPE_CHANGE (112),
|
||||
TRIGGER_GADGET_INTERACTABLE (113),
|
||||
TRIGGER_COLLECT_SET_OF_READINGS (114),
|
||||
TRIGGER_TELEPORT_WITH_CERTAIN_PORTAL (115),
|
||||
TRIGGER_WORLD_GATHER (116),
|
||||
TRIGGER_TAKE_GENERAL_REWARD (117),
|
||||
TRIGGER_BATTLE_FOR_MONSTER_DIE_OR (118),
|
||||
TRIGGER_BATTLE_FOR_MONSTER_DIE_AND (119),
|
||||
TRIGGER_OPEN_WORLD_CHEST (120),
|
||||
TRIGGER_ENTER_CLIMATE_AREA (121),
|
||||
TRIGGER_UNLOCK_SCENE_POINT (122),
|
||||
TRIGGER_INTERACT_GADGET_WITH_INTERACT_ID (123),
|
||||
TRIGGER_OBTAIN_AVATAR (201),
|
||||
TRIGGER_PLAYER_LEVEL (202),
|
||||
TRIGGER_AVATAR_UPGRADE (203),
|
||||
TRIGGER_AVATAR_PROMOTE (204),
|
||||
TRIGGER_WEAPON_UPGRADE (205),
|
||||
TRIGGER_WEAPON_PROMOTE (206),
|
||||
TRIGGER_RELIQUARY_UPGRADE (207),
|
||||
TRIGGER_WEAR_RELIQUARY (208),
|
||||
TRIGGER_UPGRADE_TALENT (209),
|
||||
TRIGGER_UNLOCK_RECIPE (210),
|
||||
TRIGGER_RELIQUARY_SET_NUM (211),
|
||||
TRIGGER_OBTAIN_MATERIAL_NUM (212),
|
||||
TRIGGER_OBTAIN_RELIQUARY_NUM (213),
|
||||
TRIGGER_GACHA_NUM (214),
|
||||
TRIGGER_ANY_RELIQUARY_UPGRADE (215),
|
||||
TRIGGER_FETTER_LEVEL_AVATAR_NUM (216),
|
||||
TRIGGER_SKILLED_AT_RECIPE (217),
|
||||
TRIGGER_RELIQUARY_UPGRADE_EQUAL_RANK_LEVEL (218),
|
||||
TRIGGER_SPECIFIED_WEAPON_UPGRADE (219),
|
||||
TRIGGER_SPECIFIED_WEAPON_AWAKEN (220),
|
||||
TRIGGER_UNLOCK_SPECIFIC_RECIPE_OR (221),
|
||||
TRIGGER_POSSESS_MATERIAL_NUM (222),
|
||||
TRIGGER_EXHIBITION_ACCUMULABLE_VALUE (223),
|
||||
TRIGGER_EXHIBITION_REPLACEABLE_VALUE_SETTLE_NUM (224),
|
||||
TRIGGER_ANY_WEAPON_UPGRADE_NUM (225),
|
||||
TRIGGER_ANY_RELIQUARY_UPGRADE_NUM (226),
|
||||
TRIGGER_ACTIVITY_SCORE_EXCEED_VALUE (227),
|
||||
TRIGGER_UNLOCK_SPECIFIC_FORGE_OR (228),
|
||||
TRIGGER_UNLOCK_SPECIFIC_ANIMAL_CODEX (229),
|
||||
TRIGGER_OBTAIN_ITEM_NUM (230),
|
||||
TRIGGER_CAPTURE_ANIMAL (231),
|
||||
TRIGGER_DAILY_TASK (301),
|
||||
TRIGGER_RAND_TASK (302),
|
||||
TRIGGER_AVATAR_EXPEDITION (303),
|
||||
TRIGGER_FINISH_TOWER_LEVEL (304),
|
||||
TRIGGER_WORLD_BOSS_REWARD (306),
|
||||
TRIGGER_FINISH_DUNGEON (307),
|
||||
TRIGGER_START_AVATAR_EXPEDITION (308),
|
||||
TRIGGER_OPEN_BLOSSOM_CHEST (309),
|
||||
TRIGGER_FINISH_BLOSSOM_PROGRESS (310),
|
||||
TRIGGER_DONE_TOWER_GADGET_UNHURT (311),
|
||||
TRIGGER_DONE_TOWER_STARS (312),
|
||||
TRIGGER_DONE_TOWER_UNHURT (313),
|
||||
TRIGGER_STEAL_FOOD_TIMES (314),
|
||||
TRIGGER_DONE_DUNGEON_WITH_SAME_ELEMENT_AVATARS (315),
|
||||
TRIGGER_GROUP_FLIGHT_CHALLENGE_REACH_POINTS (316),
|
||||
TRIGGER_FINISH_DAILY_DELIVERY_NUM (317),
|
||||
TRIGGER_TOWER_STARS_NUM (318),
|
||||
TRIGGER_FINISH_SPECIFED_TYPE_BLOSSOM_NUM (319),
|
||||
TRIGGER_FINISH_SPECIFED_TYPE_BLOSSOM_CLIMATE_METER (320),
|
||||
TRIGGER_FINISH_BLOSSOM_GROUP_VARIABLE_GT (321),
|
||||
TRIGGER_EFFIGY_CHALLENGE_SCORE (322),
|
||||
TRIGGER_FINISH_ROUTINE (323),
|
||||
TRIGGER_ACTIVITY_EXPEDITION_FINISH (324),
|
||||
TRIGGER_ACTIVITY_CHANNELLER_SLAB_FINISH_ALL_CAMP (325),
|
||||
TRIGGER_ACTIVITY_CHANNELLER_SLAB_FINISH_ALL_ONEOFF_DUNGEON (326),
|
||||
TRIGGER_ACTIVITY_CHANNELLER_SLAB_LOOP_DUNGEON_TOTAL_SCORE (327),
|
||||
TRIGGER_GROUP_SUMMER_TIME_SPRINT_BOAT_REACH_POINTS (328),
|
||||
TRIGGER_WEEKLY_BOSS_KILL (329),
|
||||
TRIGGER_BOUNCE_CONJURING_FINISH_COUNT (330),
|
||||
TRIGGER_BOUNCE_CONJURING_SCORE (331),
|
||||
TRIGGER_GROUP_VARIABLE_SET_VALUE_TO (332),
|
||||
TRIGGER_KILL_GADGETS_BY_SPECIFIC_SKILL (333),
|
||||
TRIGGER_KILL_MONSTERS_WITHOUT_VEHICLE (334),
|
||||
TRIGGER_KILL_MONSTER_IN_AREA (335),
|
||||
TRIGGER_ENTER_VEHICLE (336),
|
||||
TRIGGER_VEHICLE_DURATION (337),
|
||||
TRIGGER_VEHICLE_FRIENDS (338),
|
||||
TRIGGER_VEHICLE_KILLED_BY_MONSTER (339),
|
||||
TRIGGER_VEHICLE_DASH (340),
|
||||
TRIGGER_DO_COOK (401),
|
||||
TRIGGER_DO_FORGE (402),
|
||||
TRIGGER_DO_COMPOUND (403),
|
||||
TRIGGER_DO_COMBINE (404),
|
||||
TRIGGER_BUY_SHOP_GOODS (405),
|
||||
TRIGGER_FORGE_WEAPON (406),
|
||||
TRIGGER_MP_PLAY_BATTLE_WIN (421),
|
||||
TRIGGER_KILL_GROUP_MONSTER (422),
|
||||
TRIGGER_CRUCIBLE_ELEMENT_SCORE (423),
|
||||
TRIGGER_MP_DUNGEON_TIMES (424),
|
||||
TRIGGER_MP_KILL_MONSTER_NUM (425),
|
||||
TRIGGER_CRUCIBLE_MAX_BALL (426),
|
||||
TRIGGER_CRUCIBLE_MAX_SCORE (427),
|
||||
TRIGGER_CRUCIBLE_SUBMIT_BALL (428),
|
||||
TRIGGER_CRUCIBLE_WORLD_LEVEL_SCORE (429),
|
||||
TRIGGER_MP_PLAY_GROUP_STATISTIC (430),
|
||||
TRIGGER_KILL_GROUP_SPECIFIC_MONSTER (431),
|
||||
TRIGGER_REACH_MP_PLAY_SCORE (432),
|
||||
TRIGGER_REACH_MP_PLAY_RECORD (433),
|
||||
TRIGGER_TREASURE_MAP_DONE_REGION (434),
|
||||
TRIGGER_SEA_LAMP_MINI_QUEST (435),
|
||||
TRIGGER_FINISH_FIND_HILICHURL_LEVEL (436),
|
||||
TRIGGER_COMBINE_ITEM (437),
|
||||
TRIGGER_FINISH_CHALLENGE_IN_DURATION (438),
|
||||
TRIGGER_FINISH_CHALLENGE_LEFT_TIME (439),
|
||||
TRIGGER_MP_KILL_MONSTER_ID_NUM (440),
|
||||
TRIGGER_LOGIN (501),
|
||||
TRIGGER_COST_MATERIAL (502),
|
||||
TRIGGER_DELIVER_ITEM_TO_SALESMAN (503),
|
||||
TRIGGER_USE_ITEM (504),
|
||||
TRIGGER_ACCUMULATE_DAILY_LOGIN (505),
|
||||
TRIGGER_FINISH_CHALLENGE (601),
|
||||
TRIGGER_MECHANICUS_UNLOCK_GEAR (602),
|
||||
TRIGGER_MECHANICUS_LEVELUP_GEAR (603),
|
||||
TRIGGER_MECHANICUS_DIFFICULT (604),
|
||||
TRIGGER_MECHANICUS_DIFFICULT_SCORE (605),
|
||||
TRIGGER_MECHANICUS_KILL_MONSTER (606),
|
||||
TRIGGER_MECHANICUS_BUILDING_POINT (607),
|
||||
TRIGGER_MECHANICUS_DIFFICULT_EQ (608),
|
||||
TRIGGER_MECHANICUS_BATTLE_END (609),
|
||||
TRIGGER_MECHANICUS_BATTLE_END_EXCAPED_LESS_THAN (610),
|
||||
TRIGGER_MECHANICUS_BATTLE_END_POINTS_MORE_THAN (611),
|
||||
TRIGGER_MECHANICUS_BATTLE_END_GEAR_MORE_THAN (612),
|
||||
TRIGGER_MECHANICUS_BATTLE_END_PURE_GEAR_DAMAGE (613),
|
||||
TRIGGER_MECHANICUS_BATTLE_END_CARD_PICK_MORE_THAN (614),
|
||||
TRIGGER_MECHANICUS_BATTLE_END_CARD_TARGET_MORE_THAN (615),
|
||||
TRIGGER_MECHANICUS_BATTLE_END_BUILD_GEAR_MORE_THAN (616),
|
||||
TRIGGER_MECHANICUS_BATTLE_END_GEAR_KILL_MORE_THAN (617),
|
||||
TRIGGER_MECHANICUS_BATTLE_END_ROUND_MORE_THAN (618),
|
||||
TRIGGER_MECHANICUS_BATTLE_END_ROUND (619),
|
||||
TRIGGER_MECHANICUS_BATTLE_FIN_CHALLENGE_MORE_THAN (620),
|
||||
TRIGGER_MECHANICUS_BATTLE_WATCHER_FINISH_COUNT (621),
|
||||
TRIGGER_MECHANICUS_BATTLE_INTERACT_COUNT (622),
|
||||
TRIGGER_MECHANICUS_BATTLE_DIFFICULT_ESCAPE (623),
|
||||
TRIGGER_MECHANICUS_BATTLE_DIFFICULT_GEAR_NUM (624),
|
||||
TRIGGER_MECHANICUS_BATTLE_DIFFICULT_GEAR_ID_NUM (625),
|
||||
TRIGGER_FLEUR_FAIR_DUNGEON_FINISH_IN_LIMIT_TIME (626),
|
||||
TRIGGER_FLEUR_FAIR_DUNGEON_FINISH_KEEP_ENERGY (627),
|
||||
TRIGGER_FLEUR_FAIR_DUNGEON_FINISH_WITH_GROUP_VARIABLE (628),
|
||||
TRIGGER_FLEUR_FAIR_DUNGEON_FINISH_WITH_BUFF_NUM (629),
|
||||
TRIGGER_FLEUR_FAIR_DUNGEON_MISSION_FINISH (630),
|
||||
TRIGGER_FINISH_DUNGEON_AND_CHALLENGE_REMAIN_TIME_GREATER_THAN (631),
|
||||
TRIGGER_FINISH_DUNGEON_WITH_MIST_TRIAL_STAT (632),
|
||||
TRIGGER_DUNGEON_MIST_TRIAL_STAT (633),
|
||||
TRIGGER_DUNGEON_ELEMENT_REACTION_NUM (634),
|
||||
TRIGGER_LEVEL_AVATAR_FINISH_DUNGEON_COUNT (635),
|
||||
TRIGGER_CHESS_REACH_LEVEL (636),
|
||||
TRIGGER_CHESS_DUNGEON_ADD_SCORE (637),
|
||||
TRIGGER_CHESS_DUNGEON_SUCC_WITH_ESCAPED_MONSTERS_LESS_THAN (638),
|
||||
TRIGGER_CHESS_DUNGEON_SUCC_WITH_TOWER_COUNT_LESS_OR_EQUAL (639),
|
||||
TRIGGER_CHESS_DUNGEON_SUCC_WITH_CARD_COUNT_LESS_OR_EQUAL (640),
|
||||
TRIGGER_CHESS_DUNGEON_SUCC_WITH_CARD_COUNT_GREATER_THAN (641),
|
||||
TRIGGER_CHESS_KILL_MONSTERS (642),
|
||||
TRIGGER_CHESS_COST_BUILDING_POINTS (643),
|
||||
TRIGGER_SUMO_STAGE_SCORE_REACH (644),
|
||||
TRIGGER_SUMO_TOTAL_MAX_SCORE_REACH (645),
|
||||
TRIGGER_ROGUE_DESTROY_GADGET_NUM (646),
|
||||
TRIGGER_ROGUE_KILL_MONSTER_NUM (647),
|
||||
TRIGGER_ROGUE_FINISH_WITHOUT_USING_SPRING_CELL (649),
|
||||
TRIGGER_ROGUE_FINISH_ALL_CHALLENGE_CELL (650),
|
||||
TRIGGER_ROGUE_FINISH_WITH_AVATAR_ELEMENT_TYPE_NUM_LESS_THAN (651),
|
||||
TRIGGER_ROGUE_FINISH_WITH_AVATAR_NUM_LESS_THAN (652),
|
||||
TRIGGER_ROGUE_FINISH_NO_AVATAR_DEAD (653),
|
||||
TRIGGER_ROGUE_SHIKIGAMI_UPGRADE (654),
|
||||
TRIGGER_ROGUE_CURSE_NUM (655),
|
||||
TRIGGER_ROGUE_SELECT_CARD_NUM (656),
|
||||
TRIGGER_FINISH_QUEST_AND (700),
|
||||
TRIGGER_FINISH_QUEST_OR (701),
|
||||
TRIGGER_DAILY_TASK_VAR_EQUAL (702),
|
||||
TRIGGER_QUEST_GLOBAL_VAR_EQUAL (703),
|
||||
TRIGGER_TALK_NUM (704),
|
||||
TRIGGER_FINISH_PARENT_QUEST_AND (705),
|
||||
TRIGGER_FINISH_PARENT_QUEST_OR (706),
|
||||
TRIGGER_ELEMENT_REACTION_TIMELIMIT_NUM (800),
|
||||
TRIGGER_ELEMENT_REACTION_TIMELIMIT_KILL_NUM (801),
|
||||
TRIGGER_ELEMENT_REACTION_TIMELIMIT_DAMAGE_NUM (802),
|
||||
TRIGGER_ABILITY_STATE_PASS_TIME (803),
|
||||
TRIGGER_MAX_CRITICAL_DAMAGE (804),
|
||||
TRIGGER_FULL_SATIATION_TEAM_AVATAR_NUM (805),
|
||||
TRIGGER_KILLED_BY_CERTAIN_MONSTER (806),
|
||||
TRIGGER_CUR_AVATAR_HURT (807),
|
||||
TRIGGER_CUR_AVATAR_ABILITY_STATE (808),
|
||||
TRIGGER_USE_ENERGY_SKILL_NUM_TIMELIMIT (809),
|
||||
TRIGGER_SHIELD_SOURCE_NUM (810),
|
||||
TRIGGER_CUR_AVATAR_HURT_BY_SPECIFIC_ABILITY (811),
|
||||
TRIGGER_KILLED_BY_SPECIFIC_ABILITY (812),
|
||||
TRIGGER_MAX_DASH_TIME (900),
|
||||
TRIGGER_MAX_FLY_TIME (901),
|
||||
TRIGGER_MAX_FLY_MAP_DISTANCE (902),
|
||||
TRIGGER_SIT_DOWN_IN_POINT (903),
|
||||
TRIGGER_DASH (904),
|
||||
TRIGGER_CLIMB (905),
|
||||
TRIGGER_FLY (906),
|
||||
TRIGGER_CITY_REPUTATION_LEVEL (930),
|
||||
TRIGGER_CITY_REPUTATION_FINISH_REQUEST (931),
|
||||
TRIGGER_HUNTING_FINISH_NUM (932),
|
||||
TRIGGER_HUNTING_FAIL_NUM (933),
|
||||
TRIGGER_OFFERING_LEVEL (934),
|
||||
TRIGGER_MIRACLE_RING_DELIVER_ITEM (935),
|
||||
TRIGGER_MIRACLE_RING_TAKE_REWARD (936),
|
||||
TRIGGER_BLESSING_EXCHANGE_PIC_NUM (937),
|
||||
TRIGGER_BLESSING_REDEEM_REWARD_NUM (938),
|
||||
TRIGGER_GALLERY_BALLOON_REACH_SCORE (939),
|
||||
TRIGGER_GALLERY_FALL_REACH_SCORE (940),
|
||||
TRIGGER_FLEUR_FAIR_MUSIC_GAME_REACH_SCORE (941),
|
||||
TRIGGER_MAIN_COOP_SAVE_POINT_AND (942),
|
||||
TRIGGER_MAIN_COOP_SAVE_POINT_OR (943),
|
||||
TRIGGER_MAIN_COOP_VAR_EQUAL (944),
|
||||
TRIGGER_FINISH_ALL_ARENA_CHALLENGE_WATCHER_IN_SCHEDULE (945),
|
||||
TRIGGER_GALLERY_BUOYANT_COMBAT_REACH_SCORE (946),
|
||||
TRIGGER_BUOYANT_COMBAT_REACH_NEW_SCORE_LEVEL (947),
|
||||
TRIGGER_PLACE_MIRACLE_RING (948),
|
||||
TRIGGER_LUNA_RITE_SEARCH (949),
|
||||
TRIGGER_GALLERY_FISH_REACH_SCORE (950),
|
||||
TRIGGER_GALLERY_TRIATHLON_REACH_SCORE (951),
|
||||
TRIGGER_WINTER_CAMP_SNOWMAN_COMPLEIET (952),
|
||||
TRIGGER_CREATE_CUSTOM_DUNGEON (953),
|
||||
TRIGGER_PUBLISH_CUSTOM_DUNGEON (954),
|
||||
TRIGGER_PLAY_OTHER_CUSTOM_DUNGEON (955),
|
||||
TRIGGER_FINISH_CUSTOM_DUNGEON_OFFICIAL (956),
|
||||
TRIGGER_CUSTOM_DUNGEON_OFFICIAL_COIN (957),
|
||||
TRIGGER_OBTAIN_WOOD_TYPE (1000),
|
||||
TRIGGER_OBTAIN_WOOD_COUNT (1001),
|
||||
TRIGGER_UNLOCK_FURNITURE_COUNT (1002),
|
||||
TRIGGER_FURNITURE_MAKE (1003),
|
||||
TRIGGER_HOME_LEVEL (1004),
|
||||
TRIGGER_HOME_COIN (1005),
|
||||
TRIGGER_HOME_COMFORT_LEVEL (1006),
|
||||
TRIGGER_HOME_LIMITED_SHOP_BUY (1007),
|
||||
TRIGGER_FURNITURE_SUITE_TYPE (1008),
|
||||
TRIGGER_ARRANGEMENT_FURNITURE_COUNT (1009),
|
||||
TRIGGER_ENTER_SELF_HOME (1010),
|
||||
TRIGGER_HOME_MODULE_COMFORT_VALUE (1011),
|
||||
TRIGGER_HOME_ENTER_ROOM (1012),
|
||||
TRIGGER_HOME_AVATAR_IN (1013),
|
||||
TRIGGER_HOME_AVATAR_REWARD_EVENT_COUNT (1014),
|
||||
TRIGGER_HOME_AVATAR_TALK_FINISH_COUNT (1015),
|
||||
TRIGGER_HOME_AVATAR_REWARD_EVENT_ALL_COUNT (1016),
|
||||
TRIGGER_HOME_AVATAR_TALK_FINISH_ALL_COUNT (1017),
|
||||
TRIGGER_HOME_AVATAR_FETTER_GET (1018),
|
||||
TRIGGER_HOME_AVATAR_IN_COUNT (1019),
|
||||
TRIGGER_HOME_DO_PLANT (1020),
|
||||
TRIGGER_ARRANGEMENT_FURNITURE (1021),
|
||||
TRIGGER_HOME_GATHER_COUNT (1022),
|
||||
TRIGGER_HOME_FIELD_GATHER_COUNT (1023),
|
||||
TRIGGER_HOME_UNLOCK_BGM_COUNT (1024),
|
||||
TRIGGER_FISHING_SUCC_NUM (1100),
|
||||
TRIGGER_FISHING_KEEP_BONUS (1101),
|
||||
TRIGGER_EMPTY_FISH_POOL (1102),
|
||||
TRIGGER_FISHING_FAIL_NUM (1103),
|
||||
TRIGGER_SHOCK_FISH_NUM (1104),
|
||||
TRIGGER_PLANT_FLOWER_SET_WISH (1105),
|
||||
TRIGGER_PLANT_FLOWER_GIVE_FLOWER (1106),
|
||||
TRIGGER_PLANT_FLOWER_OBTAIN_FLOWER_TYPE (1107),
|
||||
TRIGGER_PLANT_FLOWER_COMMON_OBTAIN_FLOWER_TYPE (1108),
|
||||
TRIGGER_FINISH_LANV2_PROJECTION_LEVEL (1111),
|
||||
TRIGGER_GALLERY_SALVAGE_REACH_SCORE (1112),
|
||||
TRIGGER_LANV2_FIREWORKS_CHALLENGE_REACH_SCORE (1113),
|
||||
TRIGGER_POTION_STAGE_LEVEL_PASS_NUM (1115),
|
||||
TRIGGER_POTION_STAGE_OBTAIN_MEDAL_NUM (1116),
|
||||
TRIGGER_POTION_STAGE_REACH_TOTAL_SCORE (1117),
|
||||
TRIGGER_BARTENDER_FINISH_STORY_MODULE (1120),
|
||||
TRIGGER_BARTENDER_CHALLENGE_MODULE_LEVEL_SCORE (1121),
|
||||
TRIGGER_BARTENDER_UNLOCK_FORMULA (1122),
|
||||
TRIGGER_MICHIAE_MATSURI_UNLOCK_CRYSTAL_SKILL_REACH_NUM (1123),
|
||||
TRIGGER_MICHIAE_MATSURI_FINISH_DARK_CHALLENGE_REACH_NUM (1124),
|
||||
TRIGGER_CAPTURE_ENV_ANIMAL_REACH_NUM (1125),
|
||||
TRIGGER_SPICE_MAKE_FORMULA_TIMES (1126),
|
||||
TRIGGER_SPICE_GIVE_FOOD_TIMES (1127),
|
||||
TRIGGER_SPICE_MAKE_FORMULA_SUCCESSFUL_TIMES (1128),
|
||||
TRIGGER_IRODORI_FINISH_FLOWER_THEME (1131),
|
||||
TRIGGER_IRODORI_FINISH_MASTER_STAGE (1132),
|
||||
TRIGGER_IRODORI_CHESS_STAGE_REACH_SCORE (1133),
|
||||
TRIGGER_IRODORI_FINISH_POETRY_THEME (1134),
|
||||
TRIGGER_PHOTO_FINISH_POS_ID (1135),
|
||||
TRIGGER_CRYSTAL_LINK_LEVEL_SCORE_REACH (1138),
|
||||
TRIGGER_CRYSTAL_LINK_TOTAL_MAX_SCORE_REACH (1139);
|
||||
|
||||
private final int value;
|
||||
private static final Int2ObjectMap<WatcherTriggerType> map = new Int2ObjectOpenHashMap<>();
|
||||
private static final Map<String, WatcherTriggerType> stringMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
Stream.of(values()).forEach(e -> {
|
||||
map.put(e.getValue(), e);
|
||||
stringMap.put(e.name(), e);
|
||||
});
|
||||
}
|
||||
|
||||
private WatcherTriggerType(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static WatcherTriggerType getTypeByValue(int value) {
|
||||
return map.getOrDefault(value, TRIGGER_NONE);
|
||||
}
|
||||
|
||||
public static WatcherTriggerType getTypeByName(String name) {
|
||||
return stringMap.getOrDefault(name, TRIGGER_NONE);
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.CommandMap;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.game.battlepass.BattlePassMissionManager;
|
||||
import emu.grasscutter.game.combine.CombineManger;
|
||||
import emu.grasscutter.game.drop.DropManager;
|
||||
import emu.grasscutter.game.dungeons.DungeonManager;
|
||||
@ -61,6 +62,7 @@ public final class GameServer extends KcpServer {
|
||||
private final TaskMap taskMap;
|
||||
private final DropManager dropManager;
|
||||
private final WorldDataManager worldDataManager;
|
||||
private final BattlePassMissionManager battlePassMissionManager;
|
||||
|
||||
private final CombineManger combineManger;
|
||||
private final TowerScheduleManager towerScheduleManager;
|
||||
@ -101,6 +103,8 @@ public final class GameServer extends KcpServer {
|
||||
this.combineManger = new CombineManger(this);
|
||||
this.towerScheduleManager = new TowerScheduleManager(this);
|
||||
this.worldDataManager = new WorldDataManager(this);
|
||||
this.battlePassMissionManager = new BattlePassMissionManager(this);
|
||||
|
||||
// Hook into shutdown event.
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(this::onServerShutdown));
|
||||
}
|
||||
@ -173,6 +177,10 @@ public final class GameServer extends KcpServer {
|
||||
return worldDataManager;
|
||||
}
|
||||
|
||||
public BattlePassMissionManager getBattlePassMissionManager() {
|
||||
return battlePassMissionManager;
|
||||
}
|
||||
|
||||
public TaskMap getTaskMap() {
|
||||
return this.taskMap;
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.BuyBattlePassLevelReqOuterClass.BuyBattlePassLevelReq;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketBuyBattlePassLevelRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.BuyBattlePassLevelReq)
|
||||
public class HandlerBuyBattlePassLevelReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
BuyBattlePassLevelReq req = BuyBattlePassLevelReq.parseFrom(payload);
|
||||
|
||||
int buyLevel = session.getPlayer().getBattlePassManager().buyLevels(req.getBuyLevel());
|
||||
|
||||
session.send(new PacketBuyBattlePassLevelRsp(buyLevel));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.SetBattlePassViewedReqOuterClass.SetBattlePassViewedReq;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketSetBattlePassViewedRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.SetBattlePassViewedReq)
|
||||
public class HandlerSetBattlePassViewedReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
var req = SetBattlePassViewedReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().getBattlePassManager().updateViewed();
|
||||
session.send(new PacketSetBattlePassViewedRsp(req.getScheduleId()));
|
||||
}
|
||||
}
|
@ -1,13 +1,10 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.TakeBattlePassMissionPointReqOuterClass;
|
||||
import emu.grasscutter.net.proto.TakeBattlePassMissionPointReqOuterClass.TakeBattlePassMissionPointReq;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketBattlePassCurScheduleUpdateNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketBattlePassMissionUpdateNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketTakeBattlePassMissionPointRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.TakeBattlePassMissionPointReq)
|
||||
@ -15,11 +12,10 @@ public class HandlerTakeBattlePassMissionPointReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
var req
|
||||
= TakeBattlePassMissionPointReqOuterClass.TakeBattlePassMissionPointReq.parseFrom(payload);
|
||||
var req = TakeBattlePassMissionPointReq.parseFrom(payload);
|
||||
|
||||
session.getPlayer().getBattlePassManager().takeMissionPoint(req.getMissionIdListList());
|
||||
|
||||
session.send(new PacketBattlePassMissionUpdateNotify(req.getMissionIdListList() , session));
|
||||
session.send(new PacketBattlePassCurScheduleUpdateNotify(session.getPlayer()));
|
||||
session.send(new PacketTakeBattlePassMissionPointRsp());
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package emu.grasscutter.server.packet.recv;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.TakeBattlePassRewardReqOuterClass;
|
||||
import emu.grasscutter.net.proto.TakeBattlePassRewardReqOuterClass.TakeBattlePassRewardReq;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketTakeBattlePassRewardRsp;
|
||||
|
||||
@ -11,14 +11,8 @@ import emu.grasscutter.server.packet.send.PacketTakeBattlePassRewardRsp;
|
||||
public class HandlerTakeBattlePassRewardReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
var req
|
||||
= TakeBattlePassRewardReqOuterClass.TakeBattlePassRewardReq.parseFrom(payload);
|
||||
var req = TakeBattlePassRewardReq.parseFrom(payload);
|
||||
|
||||
//due to the list only have one element, so we can use get(0)
|
||||
session.send(new PacketTakeBattlePassRewardRsp(req.getTakeOptionListList() , session));
|
||||
|
||||
//update the awardTakenLevel
|
||||
req.getTakeOptionListList().forEach(battlePassRewardTakeOption ->
|
||||
session.getPlayer().getBattlePassManager().updateAwardTakenLevel(battlePassRewardTakeOption.getTag().getLevel()));
|
||||
session.getPlayer().getBattlePassManager().takeReward(req.getTakeOptionListList());
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.*;
|
||||
import emu.grasscutter.net.proto.BattlePassAllDataNotifyOuterClass.BattlePassAllDataNotify;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -13,50 +14,25 @@ public class PacketBattlePassAllDataNotify extends BasePacket {
|
||||
public PacketBattlePassAllDataNotify(Player player) {
|
||||
super(PacketOpcodes.BattlePassAllDataNotify);
|
||||
|
||||
var value = player.getBattlePassManager().getPoint();
|
||||
var proto = BattlePassAllDataNotify.newBuilder();
|
||||
|
||||
proto
|
||||
.setHaveCurSchedule(true)
|
||||
.setCurSchedule(player.getBattlePassManager().getScheduleProto());
|
||||
|
||||
int level = (int) Math.floor(value / 1000d);
|
||||
|
||||
var point = value - level * 1000;
|
||||
|
||||
List<BattlePassRewardTagOuterClass.BattlePassRewardTag> rewardTags = new ArrayList<>();
|
||||
|
||||
for (int id = 1; id <= player.getBattlePassManager().getAwardTakenLevel(); id++)
|
||||
rewardTags.add(BattlePassRewardTagOuterClass.BattlePassRewardTag.newBuilder()
|
||||
.setLevel(id)
|
||||
.setUnlockStatus(BattlePassUnlockStatusOuterClass.BattlePassUnlockStatus.BATTLE_PASS_UNLOCK_STATUS_FREE)
|
||||
.setRewardId(1001000 + id)
|
||||
.build());
|
||||
|
||||
|
||||
var proto
|
||||
= BattlePassAllDataNotifyOuterClass.BattlePassAllDataNotify.newBuilder();
|
||||
|
||||
var missions
|
||||
= GameData.getBattlePassMissionExcelConfigDataMap();
|
||||
|
||||
|
||||
var curSchedule
|
||||
= BattlePassScheduleOuterClass.BattlePassSchedule.newBuilder()
|
||||
.setScheduleId(2700).setLevel(level).setPoint(point).setBeginTime(1653940800).setEndTime(2059483200).addAllRewardTakenList(rewardTags)
|
||||
.setIsViewed(true).setUnlockStatus(BattlePassUnlockStatusOuterClass.BattlePassUnlockStatus.BATTLE_PASS_UNLOCK_STATUS_FREE).setCurCyclePoints(0)
|
||||
.setCurCycle(BattlePassCycleOuterClass.BattlePassCycle.newBuilder().setBeginTime(1653940800).setEndTime(2059483200).setCycleIdx(3).build());
|
||||
|
||||
proto.setHaveCurSchedule(true).setCurSchedule(curSchedule);
|
||||
|
||||
|
||||
//TODO: UNFINISHED YET / Need to add mission data --> Hard work
|
||||
|
||||
for (var mission : missions.values())
|
||||
proto.addMissionList(BattlePassMissionOuterClass.BattlePassMission.newBuilder()
|
||||
.setMissionId(mission.getId())
|
||||
.setMissionStatus(BattlePassMissionOuterClass.BattlePassMission.MissionStatus.MISSION_STATUS_UNFINISHED)
|
||||
.setTotalProgress(mission.getProgress())
|
||||
.setMissionType(
|
||||
mission.getRefreshType() == null ? 0 :
|
||||
mission.getRefreshType().equals("BATTLE_PASS_MISSION_REFRESH_SCHEDULE") ? 2 : mission.getRefreshType().contains("CYCLE") ? 1 : 0)
|
||||
.setRewardBattlePassPoint(mission.getAddPoint())
|
||||
.build());
|
||||
for (var missionData : GameData.getBattlePassMissionDataMap().values()) {
|
||||
// Dont send invalid refresh types
|
||||
if (!missionData.isValidRefreshType()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if player has mission in bp manager. If not, then add an empty proto from the mission data
|
||||
if (player.getBattlePassManager().hasMission(missionData.getId())) {
|
||||
proto.addMissionList(player.getBattlePassManager().loadMissionById(missionData.getId()).toProto());
|
||||
} else {
|
||||
proto.addMissionList(missionData.toProto());
|
||||
}
|
||||
}
|
||||
|
||||
setData(proto.build());
|
||||
}
|
||||
|
@ -4,36 +4,22 @@ import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.*;
|
||||
import emu.grasscutter.net.proto.BattlePassCurScheduleUpdateNotifyOuterClass.BattlePassCurScheduleUpdateNotify;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PacketBattlePassCurScheduleUpdateNotify extends BasePacket {
|
||||
|
||||
public PacketBattlePassCurScheduleUpdateNotify(Player player) {
|
||||
super(PacketOpcodes.BattlePassCurScheduleUpdateNotify);
|
||||
|
||||
var value = player.getBattlePassManager().getPoint();
|
||||
int level = (int) Math.floor(value / 1000d);
|
||||
var point = value - level * 1000;
|
||||
var proto = BattlePassCurScheduleUpdateNotify.newBuilder();
|
||||
|
||||
List<BattlePassRewardTagOuterClass.BattlePassRewardTag> rewardTags = new ArrayList<>();
|
||||
|
||||
for (int id = 1; id <= player.getBattlePassManager().getAwardTakenLevel(); id++)
|
||||
rewardTags.add(BattlePassRewardTagOuterClass.BattlePassRewardTag.newBuilder()
|
||||
.setLevel(id)
|
||||
.setUnlockStatus(BattlePassUnlockStatusOuterClass.BattlePassUnlockStatus.BATTLE_PASS_UNLOCK_STATUS_FREE)
|
||||
.setRewardId(1001000 + id)
|
||||
.build());
|
||||
|
||||
var curSchedule
|
||||
= BattlePassScheduleOuterClass.BattlePassSchedule.newBuilder()
|
||||
.setScheduleId(2700).setLevel(level).setPoint(point).setBeginTime(1653940800).setEndTime(2059483200).addAllRewardTakenList(rewardTags)
|
||||
.setIsViewed(true).setUnlockStatus(BattlePassUnlockStatusOuterClass.BattlePassUnlockStatus.BATTLE_PASS_UNLOCK_STATUS_FREE).setCurCyclePoints(0)
|
||||
.setCurCycle(BattlePassCycleOuterClass.BattlePassCycle.newBuilder().setBeginTime(1653940800).setEndTime(2059483200).setCycleIdx(3).build());
|
||||
|
||||
var proto = BattlePassCurScheduleUpdateNotifyOuterClass.BattlePassCurScheduleUpdateNotify.newBuilder();
|
||||
|
||||
proto.setHaveCurSchedule(true).setCurSchedule(curSchedule).build();
|
||||
proto
|
||||
.setHaveCurSchedule(true)
|
||||
.setCurSchedule(player.getBattlePassManager().getScheduleProto())
|
||||
.build();
|
||||
|
||||
setData(proto.build());
|
||||
|
||||
|
@ -1,39 +1,33 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.BattlePassMissionExcelConfigData;
|
||||
import java.util.Collection;
|
||||
|
||||
import emu.grasscutter.game.battlepass.BattlePassMission;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.BattlePassMissionOuterClass;
|
||||
import emu.grasscutter.net.proto.BattlePassMissionUpdateNotifyOuterClass;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import emu.grasscutter.net.proto.BattlePassMissionUpdateNotifyOuterClass.BattlePassMissionUpdateNotify;
|
||||
|
||||
public class PacketBattlePassMissionUpdateNotify extends BasePacket {
|
||||
|
||||
public PacketBattlePassMissionUpdateNotify(List<Integer> missionIdList , GameSession session) {
|
||||
public PacketBattlePassMissionUpdateNotify(BattlePassMission mission) {
|
||||
super(PacketOpcodes.BattlePassMissionUpdateNotify);
|
||||
|
||||
var proto
|
||||
= BattlePassMissionUpdateNotifyOuterClass.BattlePassMissionUpdateNotify.newBuilder();
|
||||
var proto = BattlePassMissionUpdateNotify.newBuilder()
|
||||
.addMissionList(mission.toProto())
|
||||
.build();
|
||||
|
||||
Map<Integer, BattlePassMissionExcelConfigData> missionMap
|
||||
= GameData.getBattlePassMissionExcelConfigDataMap();
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
public PacketBattlePassMissionUpdateNotify(Collection<BattlePassMission> missions) {
|
||||
super(PacketOpcodes.BattlePassMissionUpdateNotify);
|
||||
|
||||
missionIdList.forEach(missionId -> proto.addMissionList
|
||||
(BattlePassMissionOuterClass.BattlePassMission.newBuilder().setMissionId(missionId).setMissionStatus
|
||||
(BattlePassMissionOuterClass.BattlePassMission.MissionStatus.MISSION_STATUS_POINT_TAKEN)
|
||||
.setTotalProgress(missionMap.get(missionId).getProgress()).setRewardBattlePassPoint(missionMap.get(missionId).getAddPoint()).build()));
|
||||
|
||||
var point = session.getPlayer().getBattlePassManager().getPoint();
|
||||
missionIdList.forEach(missionId
|
||||
-> session.getPlayer().getBattlePassManager().addPoint(missionMap.get(missionId).getAddPoint()));
|
||||
Grasscutter.getLogger().info("[PacketBattlePassMissionUpdateNotify] addPoint: {}", session.getPlayer().getBattlePassManager().getPoint() - point);
|
||||
var proto = BattlePassMissionUpdateNotify.newBuilder();
|
||||
|
||||
missions.forEach(mission -> {
|
||||
proto.addMissionList(mission.toProto());
|
||||
});
|
||||
|
||||
this.setData(proto.build());
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,18 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.BuyBattlePassLevelRspOuterClass.BuyBattlePassLevelRsp;
|
||||
|
||||
public class PacketBuyBattlePassLevelRsp extends BasePacket {
|
||||
|
||||
public PacketBuyBattlePassLevelRsp(int buyLevel) {
|
||||
super(PacketOpcodes.BuyBattlePassLevelRsp);
|
||||
|
||||
BuyBattlePassLevelRsp proto = BuyBattlePassLevelRsp.newBuilder()
|
||||
.setBuyLevel(buyLevel)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.SetBattlePassViewedRspOuterClass.SetBattlePassViewedRsp;
|
||||
|
||||
public class PacketSetBattlePassViewedRsp extends BasePacket {
|
||||
|
||||
public PacketSetBattlePassViewedRsp(int scheduleId) {
|
||||
super(PacketOpcodes.SetBattlePassViewedRsp);
|
||||
|
||||
SetBattlePassViewedRsp proto = SetBattlePassViewedRsp.newBuilder()
|
||||
.setScheduleId(scheduleId)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
@ -1,49 +1,28 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.BattlePassRewardExcelConfigData;
|
||||
import emu.grasscutter.data.excels.RewardData;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.BattlePassRewardTakeOptionOuterClass;
|
||||
import emu.grasscutter.net.proto.ItemParamOuterClass;
|
||||
import emu.grasscutter.net.proto.TakeBattlePassRewardRspOuterClass;
|
||||
import emu.grasscutter.net.proto.BattlePassRewardTakeOptionOuterClass.BattlePassRewardTakeOption;
|
||||
import emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam;
|
||||
import emu.grasscutter.net.proto.TakeBattlePassRewardRspOuterClass.TakeBattlePassRewardRsp;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PacketTakeBattlePassRewardRsp extends BasePacket {
|
||||
public PacketTakeBattlePassRewardRsp(List<BattlePassRewardTakeOptionOuterClass.BattlePassRewardTakeOption> takeOptionList , GameSession session) {
|
||||
public PacketTakeBattlePassRewardRsp(List<BattlePassRewardTakeOption> takeOptionList, List<ItemParamData> rewardItems) {
|
||||
super(PacketOpcodes.TakeBattlePassRewardRsp);
|
||||
|
||||
var proto
|
||||
= TakeBattlePassRewardRspOuterClass.TakeBattlePassRewardRsp.newBuilder();
|
||||
|
||||
Map<Integer , BattlePassRewardExcelConfigData> excelConfigDataMap = GameData.getBattlePassRewardExcelConfigDataMap();
|
||||
Map<Integer , RewardData> rewardDataMap = GameData.getRewardDataMap();
|
||||
|
||||
List<Integer> rewardItemList = new ArrayList<>();
|
||||
|
||||
for (var takeOption : takeOptionList) {
|
||||
for (int level = session.getPlayer().getBattlePassManager().getAwardTakenLevel() + 1 ; level <= takeOption.getTag().getLevel() ; level++){
|
||||
rewardItemList.addAll(excelConfigDataMap.get(level).getFreeRewardIdList());
|
||||
rewardItemList.addAll(excelConfigDataMap.get(level).getPaidRewardIdList());
|
||||
var proto = TakeBattlePassRewardRsp.newBuilder()
|
||||
.addAllTakeOptionList(takeOptionList);
|
||||
|
||||
if (rewardItems != null) {
|
||||
for (ItemParamData param : rewardItems) {
|
||||
proto.addItemList(ItemParam.newBuilder().setItemId(param.getItemId()).setCount(param.getCount()));
|
||||
}
|
||||
|
||||
for (var rewardItemId : rewardItemList) {
|
||||
var rewardData = rewardDataMap.get(rewardItemId);
|
||||
if (rewardData == null) continue;
|
||||
rewardData.getRewardItemList().forEach(i ->
|
||||
proto.addItemList(ItemParamOuterClass.ItemParam.newBuilder().setItemId(i.getId()).setCount(i.getCount()).build()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
proto.addAllTakeOptionList(takeOptionList).build();
|
||||
|
||||
setData(proto);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user