Implement trekker affinity story

This commit is contained in:
Melledy
2025-11-24 03:07:47 -08:00
parent 139b1cf87e
commit c78c6a7492
4 changed files with 122 additions and 0 deletions

View File

@@ -30,6 +30,7 @@ public class GameData {
@Getter private static DataTable<AffinityLevelDef> AffinityLevelDataTable = new DataTable<>();
@Getter private static DataTable<AffinityGiftDef> AffinityGiftDataTable = new DataTable<>();
@Getter private static DataTable<PlotDef> PlotDataTable = new DataTable<>();
@Getter private static DataTable<CharGemDef> CharGemDataTable = new DataTable<>();
@Getter private static DataTable<CharGemSlotControlDef> CharGemSlotControlDataTable = new DataTable<>();

View File

@@ -0,0 +1,31 @@
package emu.nebula.data.resources;
import emu.nebula.data.BaseDef;
import emu.nebula.data.ResourceType;
import emu.nebula.game.inventory.ItemParamMap;
import lombok.Getter;
@Getter
@ResourceType(name = "Plot.json")
public class PlotDef extends BaseDef {
private int Id;
private int Char;
private int UnlockAffinityLevel;
private String Rewards;
private transient ItemParamMap rewards;
@Override
public int getId() {
return this.Id;
}
public ItemParamMap getRewards() {
return this.rewards;
}
@Override
public void onLoad() {
this.rewards = ItemParamMap.fromJsonString(this.Rewards);
}
}

View File

@@ -35,6 +35,7 @@ import emu.nebula.util.Bitset;
import emu.nebula.util.CustomIntArray;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import lombok.Getter;
import us.hebi.quickbuf.RepeatedInt;
@@ -58,6 +59,7 @@ public class GameCharacter implements GameDatabaseObject {
private int skin;
private int[] skills;
private Bitset talents;
private IntSet plots;
private long createTime;
private int gemPresetIndex;
@@ -461,6 +463,40 @@ public class GameCharacter implements GameDatabaseObject {
return change;
}
public PlayerChangeInfo recvPlotReward(int plotId) {
// Create change info
var change = new PlayerChangeInfo();
// Sanity check to prevent players from recving rewards over and over again from the same plot
if (this.getPlots() != null && this.getPlots().contains(plotId)) {
return change;
}
// Get data
var plot = GameData.getPlotDataTable().get(plotId);
// Sanity check to make sure we can complete this plot quest
if (plot == null || plot.getChar() != this.getCharId() || plot.getUnlockAffinityLevel() > this.getAffinityLevel()) {
return change;
}
// Complete plot
if (this.plots == null) {
this.plots = new IntOpenHashSet();
}
this.getPlots().add(plotId);
// Update to database
this.save();
// Add items
this.getPlayer().getInventory().addItems(plot.getRewards(), change);
// Success
return change;
}
// Gems
public boolean hasGemPreset(int index) {
@@ -782,6 +818,12 @@ public class GameCharacter implements GameDatabaseObject {
// Affinity quests
proto.getMutableAffinityQuests();
// Encode plots
if (this.getPlots() != null) {
this.getPlots().forEach(proto::addPlots);
}
// Finish
return proto;
}

View File

@@ -0,0 +1,48 @@
package emu.nebula.server.handlers;
import emu.nebula.net.NetHandler;
import emu.nebula.net.NetMsgId;
import emu.nebula.proto.Public.ChangeInfo;
import emu.nebula.proto.Public.UI32;
import emu.nebula.net.HandlerId;
import emu.nebula.data.GameData;
import emu.nebula.net.GameSession;
@HandlerId(NetMsgId.plot_reward_receive_req)
public class HandlerPlotRewardReceiveReq extends NetHandler {
@Override
public byte[] handle(GameSession session, byte[] message) throws Exception {
// Parse request
var req = UI32.parseFrom(message);
// Get plot data
var plot = GameData.getPlotDataTable().get(req.getValue());
if (plot == null) {
// Send empty packet to prevent the client from crashing
return session.encodeMsg(NetMsgId.plot_reward_receive_succeed_ack, ChangeInfo.newInstance());
}
// Get character
var character = session.getPlayer().getCharacters().getCharacterById(plot.getChar());
if (character == null) {
// Send empty packet to prevent the client from crashing
return session.encodeMsg(NetMsgId.plot_reward_receive_succeed_ack, ChangeInfo.newInstance());
}
// Complete plot
var change = character.recvPlotReward(plot.getId());
if (change == null) {
// Should never happen
// Send empty packet to prevent the client from crashing
return session.encodeMsg(NetMsgId.plot_reward_receive_succeed_ack, ChangeInfo.newInstance());
}
// Encode and send
return session.encodeMsg(NetMsgId.plot_reward_receive_succeed_ack, change.toProto());
}
}