Skip to content
Snippets Groups Projects
Commit b0d19e54 authored by GanyusLeftHorn's avatar GanyusLeftHorn Committed by Melledy
Browse files

Implement selection chests for BP rewards.

parent 8104378b
Branches
Tags
No related merge requests found
...@@ -22,6 +22,7 @@ public final class GameConstants { ...@@ -22,6 +22,7 @@ public final class GameConstants {
public static final int BATTLE_PASS_POINT_PER_LEVEL = 1000; public static final int BATTLE_PASS_POINT_PER_LEVEL = 1000;
public static final int BATTLE_PASS_POINT_PER_WEEK = 10000; public static final int BATTLE_PASS_POINT_PER_WEEK = 10000;
public static final int BATTLE_PASS_LEVEL_PRICE = 150; public static final int BATTLE_PASS_LEVEL_PRICE = 150;
public static final int BATTLE_PASS_CURRENT_INDEX = 2;
// Default entity ability hashes. // Default entity ability hashes.
public static final String[] DEFAULT_ABILITY_STRINGS = { public static final String[] DEFAULT_ABILITY_STRINGS = {
......
...@@ -17,11 +17,12 @@ public class BattlePassRewardData extends GameResource { ...@@ -17,11 +17,12 @@ public class BattlePassRewardData extends GameResource {
@Override @Override
public int getId() { public int getId() {
return this.level; // Reward ID is a combination of index and level.
// We do this to get a unique ID.
return this.indexId * 100 + this.level;
} }
@Override @Override
public void onLoad() { public void onLoad() {
} }
} }
package emu.grasscutter.game.battlepass; package emu.grasscutter.game.battlepass;
import java.time.DayOfWeek; import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters; import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
...@@ -23,23 +21,23 @@ import emu.grasscutter.Grasscutter; ...@@ -23,23 +21,23 @@ import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.common.ItemParamData; import emu.grasscutter.data.common.ItemParamData;
import emu.grasscutter.data.excels.BattlePassRewardData; import emu.grasscutter.data.excels.BattlePassRewardData;
import emu.grasscutter.data.excels.ItemData;
import emu.grasscutter.data.excels.RewardData; import emu.grasscutter.data.excels.RewardData;
import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.inventory.MaterialType;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.game.props.BattlePassMissionRefreshType; import emu.grasscutter.game.props.BattlePassMissionRefreshType;
import emu.grasscutter.game.props.BattlePassMissionStatus; import emu.grasscutter.game.props.BattlePassMissionStatus;
import emu.grasscutter.game.props.WatcherTriggerType; import emu.grasscutter.game.props.WatcherTriggerType;
import emu.grasscutter.net.proto.BattlePassCycleOuterClass.BattlePassCycle; import emu.grasscutter.net.proto.BattlePassCycleOuterClass.BattlePassCycle;
import emu.grasscutter.net.proto.BattlePassProductOuterClass.BattlePassProduct;
import emu.grasscutter.net.proto.BattlePassRewardTagOuterClass.BattlePassRewardTag;
import emu.grasscutter.net.proto.BattlePassUnlockStatusOuterClass.BattlePassUnlockStatus; import emu.grasscutter.net.proto.BattlePassUnlockStatusOuterClass.BattlePassUnlockStatus;
import emu.grasscutter.net.proto.BattlePassRewardTakeOptionOuterClass.BattlePassRewardTakeOption; import emu.grasscutter.net.proto.BattlePassRewardTakeOptionOuterClass.BattlePassRewardTakeOption;
import emu.grasscutter.net.proto.BattlePassScheduleOuterClass.BattlePassSchedule; import emu.grasscutter.net.proto.BattlePassScheduleOuterClass.BattlePassSchedule;
import emu.grasscutter.server.packet.send.PacketBattlePassCurScheduleUpdateNotify; import emu.grasscutter.server.packet.send.PacketBattlePassCurScheduleUpdateNotify;
import emu.grasscutter.server.packet.send.PacketBattlePassMissionUpdateNotify; import emu.grasscutter.server.packet.send.PacketBattlePassMissionUpdateNotify;
import emu.grasscutter.server.packet.send.PacketTakeBattlePassRewardRsp; import emu.grasscutter.server.packet.send.PacketTakeBattlePassRewardRsp;
import emu.grasscutter.utils.Utils;
import lombok.Getter; import lombok.Getter;
@Entity(value = "battlepass", useDiscriminator = false) @Entity(value = "battlepass", useDiscriminator = false)
...@@ -190,9 +188,45 @@ public class BattlePassManager { ...@@ -190,9 +188,45 @@ public class BattlePassManager {
getPlayer().sendPacket(new PacketBattlePassCurScheduleUpdateNotify(getPlayer())); getPlayer().sendPacket(new PacketBattlePassCurScheduleUpdateNotify(getPlayer()));
} }
} }
private void takeRewardsFromSelectChest(ItemData rewardItemData, int index, ItemParamData entry, List<GameItem> rewardItems) {
// Sanity checks.
if (rewardItemData.getItemUse().size() < 1) {
return;
}
// Get possible item choices.
String[] choices = rewardItemData.getItemUse().get(0).getUseParam().get(0).split(",");
if (choices.length < index) {
return;
}
// Get data for the selected item.
// This depends on the type of chest.
int chosenId = Integer.parseInt(choices[index - 1]);
// For ITEM_USE_ADD_SELECT_ITEM chests, we can directly add the item specified in the chest's data.
if (rewardItemData.getItemUse().get(0).getUseOp().equals("ITEM_USE_ADD_SELECT_ITEM")) {
GameItem rewardItem = new GameItem(GameData.getItemDataMap().get(chosenId), entry.getItemCount());
rewardItems.add(rewardItem);
}
// For ITEM_USE_GRANT_SELECT_REWARD chests, we have to again look up reward data.
else if (rewardItemData.getItemUse().get(0).getUseOp().equals("ITEM_USE_GRANT_SELECT_REWARD")) {
RewardData selectedReward = GameData.getRewardDataMap().get(chosenId);
for (var r : selectedReward.getRewardItemList()) {
GameItem rewardItem = new GameItem(GameData.getItemDataMap().get(r.getItemId()), r.getItemCount());
rewardItems.add(rewardItem);
}
}
else {
Grasscutter.getLogger().error("Invalid chest type for BP reward.");
}
}
public void takeReward(List<BattlePassRewardTakeOption> takeOptionList) { public void takeReward(List<BattlePassRewardTakeOption> takeOptionList) {
List<BattlePassRewardTag> rewardList = new ArrayList<>(); List<BattlePassRewardTakeOption> rewardList = new ArrayList<>();
// List<BattlePassRewardTag> rewardList = new ArrayList<>();
for (BattlePassRewardTakeOption option : takeOptionList) { for (BattlePassRewardTakeOption option : takeOptionList) {
// Duplicate check // Duplicate check
...@@ -205,38 +239,63 @@ public class BattlePassManager { ...@@ -205,38 +239,63 @@ public class BattlePassManager {
continue; continue;
} }
BattlePassRewardData rewardData = GameData.getBattlePassRewardDataMap().get(option.getTag().getLevel()); BattlePassRewardData rewardData = GameData.getBattlePassRewardDataMap().get(GameConstants.BATTLE_PASS_CURRENT_INDEX * 100 + option.getTag().getLevel());
// Sanity check with excel data // Sanity check with excel data
if (rewardData.getFreeRewardIdList().contains(option.getTag().getRewardId())) { if (rewardData.getFreeRewardIdList().contains(option.getTag().getRewardId())) {
rewardList.add(option.getTag()); rewardList.add(option);
} else if (this.isPaid() && rewardData.getPaidRewardIdList().contains(option.getTag().getRewardId())) { } else if (this.isPaid() && rewardData.getPaidRewardIdList().contains(option.getTag().getRewardId())) {
rewardList.add(option.getTag()); rewardList.add(option);
} }
else {
Grasscutter.getLogger().info("Not in rewards list: {}", option.getTag().getRewardId());
}
// rewardList.add(new Pair<>(option.getTag(), option.getOptionIdx()));
} }
// Get rewards // Get rewards
List<ItemParamData> rewardItems = null; List<GameItem> rewardItems = null;
if (rewardList.size() > 0) { if (rewardList.size() > 0) {
rewardItems = new ArrayList<>(); rewardItems = new ArrayList<>();
for (BattlePassRewardTag tag : rewardList) { for (var option : rewardList) {
var tag = option.getTag();
int index = option.getOptionIdx();
// Make sure we have reward data.
RewardData reward = GameData.getRewardDataMap().get(tag.getRewardId()); RewardData reward = GameData.getRewardDataMap().get(tag.getRewardId());
if (reward == null) {
continue;
}
if (reward == null) continue; // Add reward items.
for (var entry : reward.getRewardItemList()) {
ItemData rewardItemData = GameData.getItemDataMap().get(entry.getItemId());
// Some rewards are chests where the user can select the item they want.
if (rewardItemData.getMaterialType() == MaterialType.MATERIAL_SELECTABLE_CHEST) {
this.takeRewardsFromSelectChest(rewardItemData, index, entry, rewardItems);
}
// All other rewards directly give us the right item.
else {
GameItem rewardItem = new GameItem(rewardItemData, entry.getItemCount());
rewardItems.add(rewardItem);
}
}
// Construct the reward and set as taken.
BattlePassReward bpReward = new BattlePassReward(tag.getLevel(), tag.getRewardId(), tag.getUnlockStatus() == BattlePassUnlockStatus.BATTLE_PASS_UNLOCK_STATUS_PAID); BattlePassReward bpReward = new BattlePassReward(tag.getLevel(), tag.getRewardId(), tag.getUnlockStatus() == BattlePassUnlockStatus.BATTLE_PASS_UNLOCK_STATUS_PAID);
this.getTakenRewards().put(bpReward.getRewardId(), bpReward); this.getTakenRewards().put(bpReward.getRewardId(), bpReward);
rewardItems.addAll(reward.getRewardItemList());
} }
// Save to db // Save to db
this.save(); this.save();
// Add items and send battle pass schedule packet // Add items and send battle pass schedule packet
getPlayer().getInventory().addItemParamDatas(rewardItems); getPlayer().getInventory().addItems(rewardItems);
getPlayer().sendPacket(new PacketBattlePassCurScheduleUpdateNotify(getPlayer())); getPlayer().sendPacket(new PacketBattlePassCurScheduleUpdateNotify(getPlayer()));
} }
......
package emu.grasscutter.server.packet.send; package emu.grasscutter.server.packet.send;
import emu.grasscutter.data.common.ItemParamData; import emu.grasscutter.data.common.ItemParamData;
import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.net.packet.BasePacket; import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.BattlePassRewardTakeOptionOuterClass.BattlePassRewardTakeOption; import emu.grasscutter.net.proto.BattlePassRewardTakeOptionOuterClass.BattlePassRewardTakeOption;
...@@ -11,7 +12,7 @@ import emu.grasscutter.server.game.GameSession; ...@@ -11,7 +12,7 @@ import emu.grasscutter.server.game.GameSession;
import java.util.List; import java.util.List;
public class PacketTakeBattlePassRewardRsp extends BasePacket { public class PacketTakeBattlePassRewardRsp extends BasePacket {
public PacketTakeBattlePassRewardRsp(List<BattlePassRewardTakeOption> takeOptionList, List<ItemParamData> rewardItems) { /*public PacketTakeBattlePassRewardRsp(List<BattlePassRewardTakeOption> takeOptionList, List<ItemParamData> rewardItems) {
super(PacketOpcodes.TakeBattlePassRewardRsp); super(PacketOpcodes.TakeBattlePassRewardRsp);
var proto = TakeBattlePassRewardRsp.newBuilder() var proto = TakeBattlePassRewardRsp.newBuilder()
...@@ -23,6 +24,21 @@ public class PacketTakeBattlePassRewardRsp extends BasePacket { ...@@ -23,6 +24,21 @@ public class PacketTakeBattlePassRewardRsp extends BasePacket {
} }
} }
setData(proto);
}*/
public PacketTakeBattlePassRewardRsp(List<BattlePassRewardTakeOption> takeOptionList, List<GameItem> rewardItems) {
super(PacketOpcodes.TakeBattlePassRewardRsp);
var proto = TakeBattlePassRewardRsp.newBuilder()
.addAllTakeOptionList(takeOptionList);
if (rewardItems != null) {
for (var item : rewardItems) {
proto.addItemList(ItemParam.newBuilder().setItemId(item.getItemId()).setCount(item.getCount()));
}
}
setData(proto); setData(proto);
} }
} }
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment