mirror of
https://github.com/Melledy/LunarCore.git
synced 2025-12-23 10:44:36 +01:00
Implement challenge rewards
This commit is contained in:
@@ -15,6 +15,7 @@ public class GameConstants {
|
||||
public static final String DEFAULT_NAME = "Trailblazer";
|
||||
public static final int TRAILBLAZER_AVATAR_ID = 8001;
|
||||
public static final int MAX_TRAILBLAZER_LEVEL = 70;
|
||||
public static final int MATERIAL_HCOIN_ID = 1; // Material id for jades. DO NOT CHANGE
|
||||
public static final int MATERIAL_COIN_ID = 2; // Material id for credits. DO NOT CHANGE
|
||||
public static final int MAX_STAMINA = 240;
|
||||
public static final int MAX_AVATARS_IN_TEAM = 4;
|
||||
|
||||
@@ -28,10 +28,13 @@ public class GameData {
|
||||
@Getter private static Int2ObjectMap<MapEntranceExcel> mapEntranceExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<HeroExcel> heroExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<ShopExcel> shopExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<RewardExcel> rewardExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<ItemComposeExcel> itemComposeExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter private static Int2ObjectMap<ChallengeGroupExcel> challengeGroupExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<ChallengeExcel> challengeExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<ChallengeTargetExcel> challengeTargetExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
private static Int2ObjectMap<ChallengeRewardExcel> challengeRewardExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter private static Int2ObjectMap<RogueManagerExcel> rogueManagerExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<RogueTalentExcel> rogueTalentExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@@ -135,4 +138,8 @@ public class GameData {
|
||||
public static MonsterDropExcel getMonsterDropExcel(int monsterNpcId, int worldLevel) {
|
||||
return monsterDropExcelMap.get((monsterNpcId << 4) + worldLevel);
|
||||
}
|
||||
|
||||
public static ChallengeRewardExcel getChallengeRewardExcel(int groupId, int starCount) {
|
||||
return challengeRewardExcelMap.get((groupId << 16) + starCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import lombok.Getter;
|
||||
@ResourceType(name = {"ChallengeMazeConfig.json"})
|
||||
public class ChallengeExcel extends GameResource {
|
||||
private int ID;
|
||||
private int GroupID;
|
||||
private int MapEntranceID;
|
||||
private int StageNum;
|
||||
private int ChallengeCountDown;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package emu.lunarcore.data.excel;
|
||||
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = {"ChallengeGroupConfig.json"})
|
||||
public class ChallengeGroupExcel extends GameResource {
|
||||
private int GroupID;
|
||||
private int RewardLineGroupID;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return GroupID;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package emu.lunarcore.data.excel;
|
||||
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = {"ChallengeMazeRewardLine.json"})
|
||||
public class ChallengeRewardExcel extends GameResource {
|
||||
private int GroupID;
|
||||
private int StarCount;
|
||||
private int RewardID;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return (GroupID << 16) + StarCount;
|
||||
}
|
||||
}
|
||||
57
src/main/java/emu/lunarcore/data/excel/RewardExcel.java
Normal file
57
src/main/java/emu/lunarcore/data/excel/RewardExcel.java
Normal file
@@ -0,0 +1,57 @@
|
||||
package emu.lunarcore.data.excel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import emu.lunarcore.GameConstants;
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
import emu.lunarcore.data.common.ItemParam;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = {"RewardData.json"})
|
||||
public class RewardExcel extends GameResource {
|
||||
private int RewardID;
|
||||
|
||||
private int Hcoin;
|
||||
|
||||
private int ItemID_1;
|
||||
private int Count_1;
|
||||
private int ItemID_2;
|
||||
private int Count_2;
|
||||
private int ItemID_3;
|
||||
private int Count_3;
|
||||
private int ItemID_4;
|
||||
private int Count_4;
|
||||
private int ItemID_5;
|
||||
private int Count_5;
|
||||
|
||||
private transient List<ItemParam> rewards;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return RewardID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.rewards = new ArrayList<>();
|
||||
|
||||
if (Hcoin > 0) {
|
||||
this.rewards.add(new ItemParam(GameConstants.MATERIAL_HCOIN_ID, Hcoin));
|
||||
}
|
||||
|
||||
if (ItemID_1 > 0) {
|
||||
this.rewards.add(new ItemParam(ItemID_1, Count_1));
|
||||
} if (ItemID_2 > 0) {
|
||||
this.rewards.add(new ItemParam(ItemID_2, Count_2));
|
||||
} if (ItemID_3 > 0) {
|
||||
this.rewards.add(new ItemParam(ItemID_3, Count_3));
|
||||
} if (ItemID_4 > 0) {
|
||||
this.rewards.add(new ItemParam(ItemID_4, Count_4));
|
||||
} if (ItemID_5 > 0) {
|
||||
this.rewards.add(new ItemParam(ItemID_5, Count_5));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package emu.lunarcore.game.challenge;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Id;
|
||||
import dev.morphia.annotations.Indexed;
|
||||
import emu.lunarcore.LunarCore;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.proto.ChallengeRewardOuterClass.ChallengeReward;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Entity(value = "challengeReward", useDiscriminator = false)
|
||||
public class ChallengeGroupReward {
|
||||
@Id
|
||||
private ObjectId id;
|
||||
|
||||
@Indexed
|
||||
private int ownerUid;
|
||||
|
||||
private int groupId;
|
||||
private long takenStars;
|
||||
|
||||
@Deprecated // Morphia
|
||||
public ChallengeGroupReward() {}
|
||||
|
||||
public ChallengeGroupReward(Player player, int groupId) {
|
||||
this.ownerUid = player.getUid();
|
||||
this.groupId = groupId;
|
||||
}
|
||||
|
||||
public boolean hasTakenReward(int starCount) {
|
||||
return (takenStars & (1L << starCount)) != 0;
|
||||
}
|
||||
|
||||
public void setTakenReward(int starCount) {
|
||||
this.takenStars |= 1L << starCount;
|
||||
this.save();
|
||||
}
|
||||
|
||||
public ChallengeReward toProto() {
|
||||
var proto = ChallengeReward.newInstance()
|
||||
.setGroupId(this.getGroupId())
|
||||
.setTakenChallengeReward(this.getTakenStars());
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
LunarCore.getGameDatabase().delete(this);
|
||||
}
|
||||
|
||||
public void save() {
|
||||
LunarCore.getGameDatabase().save(this);
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ public class ChallengeHistory {
|
||||
private int ownerUid;
|
||||
|
||||
private int challengeId;
|
||||
private int groupId;
|
||||
private int takenReward;
|
||||
private int stars;
|
||||
|
||||
@@ -36,6 +37,14 @@ public class ChallengeHistory {
|
||||
this.stars = Math.max(this.stars, stars);
|
||||
}
|
||||
|
||||
public int getTotalStars() {
|
||||
int total = 0;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
total += (this.stars & (1 << i)) != 0 ? 1 : 0;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public Challenge toProto() {
|
||||
var proto = Challenge.newInstance()
|
||||
.setChallengeId(this.getChallengeId())
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package emu.lunarcore.game.challenge;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import emu.lunarcore.LunarCore;
|
||||
import emu.lunarcore.data.GameData;
|
||||
import emu.lunarcore.data.excel.ChallengeExcel;
|
||||
import emu.lunarcore.game.inventory.GameItem;
|
||||
import emu.lunarcore.game.player.BasePlayerManager;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.game.player.lineup.PlayerLineup;
|
||||
@@ -17,10 +19,12 @@ import lombok.Getter;
|
||||
@Getter
|
||||
public class ChallengeManager extends BasePlayerManager {
|
||||
private Int2ObjectMap<ChallengeHistory> history;
|
||||
private Int2ObjectMap<ChallengeGroupReward> takenRewards;
|
||||
|
||||
public ChallengeManager(Player player) {
|
||||
super(player);
|
||||
this.history = new Int2ObjectOpenHashMap<>();
|
||||
this.takenRewards = new Int2ObjectOpenHashMap<>();
|
||||
}
|
||||
|
||||
public void startChallenge(int challengeId) {
|
||||
@@ -84,7 +88,7 @@ public class ChallengeManager extends BasePlayerManager {
|
||||
getPlayer().sendPacket(new PacketStartChallengeScRsp(getPlayer(), challengeId));
|
||||
}
|
||||
|
||||
public void addHistory(int challengeId, int stars) {
|
||||
public synchronized void addHistory(int challengeId, int stars) {
|
||||
// Dont write challenge history if the player didnt get any stars
|
||||
if (stars <= 0) return;
|
||||
|
||||
@@ -96,11 +100,66 @@ public class ChallengeManager extends BasePlayerManager {
|
||||
info.save();
|
||||
}
|
||||
|
||||
public synchronized List<GameItem> takeRewards(int groupId, int starCount) {
|
||||
// Get excels
|
||||
var challengeGroup = GameData.getChallengeGroupExcelMap().get(groupId);
|
||||
if (challengeGroup == null) return null;
|
||||
|
||||
var challengeReward = GameData.getChallengeRewardExcel(challengeGroup.getRewardLineGroupID(), starCount);
|
||||
if (challengeReward == null) return null;
|
||||
|
||||
var rewardExcel = GameData.getRewardExcelMap().get(challengeReward.getRewardID());
|
||||
if (rewardExcel == null) return null;
|
||||
|
||||
// Validate
|
||||
int totalStars = 0;
|
||||
for (ChallengeHistory ch : this.getHistory().values()) {
|
||||
// Legacy compatibility
|
||||
if (ch.getGroupId() == 0) {
|
||||
var challengeExcel = GameData.getChallengeExcelMap().get(ch.getChallengeId());
|
||||
if (challengeExcel == null) continue;
|
||||
|
||||
ch.setGroupId(challengeExcel.getGroupID());
|
||||
ch.save();
|
||||
}
|
||||
|
||||
// Add total stars
|
||||
if (ch.getGroupId() == groupId) {
|
||||
totalStars += ch.getTotalStars();
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the player has enough stars
|
||||
if (totalStars < starCount) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get reward info
|
||||
var reward = this.getTakenRewards().computeIfAbsent(groupId, id -> new ChallengeGroupReward(getPlayer(), groupId));
|
||||
|
||||
if (reward.hasTakenReward(starCount)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
reward.setTakenReward(starCount);
|
||||
|
||||
// Add items to inventory
|
||||
return getPlayer().getInventory().addItemParams(rewardExcel.getRewards());
|
||||
}
|
||||
|
||||
public void loadFromDatabase() {
|
||||
Stream<ChallengeHistory> stream = LunarCore.getGameDatabase().getObjects(ChallengeHistory.class, "ownerUid", this.getPlayer().getUid());
|
||||
// Load challenge history
|
||||
Stream<ChallengeHistory> stream = LunarCore.getGameDatabase().getObjects(ChallengeHistory.class, "ownerUid", getPlayer().getUid());
|
||||
|
||||
stream.forEach(info -> {
|
||||
this.getHistory().put(info.getChallengeId(), info);
|
||||
});
|
||||
|
||||
// Load challenge rewards
|
||||
Stream<ChallengeGroupReward> stream2 = LunarCore.getGameDatabase().getObjects(ChallengeGroupReward.class, "ownerUid", getPlayer().getUid());
|
||||
|
||||
stream2.forEach(info -> {
|
||||
this.getTakenRewards().put(info.getGroupId(), info);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,6 +142,12 @@ public class Inventory extends BasePlayerManager {
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public List<GameItem> addItemParams(Collection<ItemParam> params) {
|
||||
// TODO handle params if they are equipment or relics
|
||||
List<GameItem> items = params.stream().map(param -> new GameItem(param.getId(), param.getCount())).toList();
|
||||
return addItems(items, false);
|
||||
}
|
||||
|
||||
private synchronized GameItem putItem(GameItem item) {
|
||||
// Dont add items that dont have a valid item definition.
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.lunarcore.server.packet.recv;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.lunarcore.game.inventory.GameItem;
|
||||
import emu.lunarcore.proto.TakeChallengeRewardCsReqOuterClass.TakeChallengeRewardCsReq;
|
||||
import emu.lunarcore.server.game.GameSession;
|
||||
import emu.lunarcore.server.packet.CmdId;
|
||||
import emu.lunarcore.server.packet.Opcodes;
|
||||
import emu.lunarcore.server.packet.PacketHandler;
|
||||
import emu.lunarcore.server.packet.send.PacketTakeChallengeRewardScRsp;
|
||||
|
||||
@Opcodes(CmdId.TakeChallengeRewardCsReq)
|
||||
public class HandlerTakeChallengeRewardCsReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] data) throws Exception {
|
||||
var req = TakeChallengeRewardCsReq.parseFrom(data);
|
||||
|
||||
List<GameItem> rewards = session.getPlayer().getChallengeManager().takeRewards(req.getGroupId(), req.getStarCount());
|
||||
session.send(new PacketTakeChallengeRewardScRsp(req.getGroupId(), req.getStarCount(), rewards));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,6 +16,10 @@ public class PacketGetChallengeScRsp extends BasePacket {
|
||||
data.addChallengeList(history.toProto());
|
||||
}
|
||||
|
||||
for (var reward : player.getChallengeManager().getTakenRewards().values()) {
|
||||
data.addChallengeRewardList(reward.toProto());
|
||||
}
|
||||
|
||||
this.setData(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package emu.lunarcore.server.packet.send;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import emu.lunarcore.game.inventory.GameItem;
|
||||
import emu.lunarcore.proto.TakeChallengeRewardScRspOuterClass.TakeChallengeRewardScRsp;
|
||||
import emu.lunarcore.server.packet.BasePacket;
|
||||
import emu.lunarcore.server.packet.CmdId;
|
||||
|
||||
public class PacketTakeChallengeRewardScRsp extends BasePacket {
|
||||
|
||||
public PacketTakeChallengeRewardScRsp(int groupId, int starCount, Collection<GameItem> rewards) {
|
||||
super(CmdId.TakeChallengeRewardScRsp);
|
||||
|
||||
var data = TakeChallengeRewardScRsp.newInstance();
|
||||
|
||||
if (rewards != null) {
|
||||
data.setGroupId(groupId)
|
||||
.setStarCount(starCount);
|
||||
|
||||
for (GameItem item : rewards) {
|
||||
data.getMutableReward().addItemList(item.toProto());
|
||||
}
|
||||
} else {
|
||||
data.setRetcode(1);
|
||||
}
|
||||
|
||||
this.setData(data);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user