mirror of
https://github.com/Melledy/Nebula.git
synced 2026-09-19 09:09:54 +02:00
Basic shadow siege implementation
This commit is contained in:
@@ -54,7 +54,14 @@ public class GameConstants {
|
|||||||
public static final int[] TOWER_EVENTS_IDS = new int[] {
|
public static final int[] TOWER_EVENTS_IDS = new int[] {
|
||||||
101, 102, 104, 105, 106, 107, 108, 114, 115, 116, 126, 127, 128
|
101, 102, 104, 105, 106, 107, 108, 114, 115, 116, 126, 127, 128
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static final int TRACE_HUNT_TOKEN_ID = 37;
|
||||||
|
public static final int TRACE_HUNT_REQUEST_ITEM_ID = 38;
|
||||||
|
public static final int TRACE_HUNT_PERMIT_ITEM_ID = 39;
|
||||||
|
public static final int[] TRACE_HUNT_TRACE_IDS = {21, 22, 23, 31, 41};
|
||||||
|
public static final int TRACE_HUNT_MAX_TRACE_PROGRESS = 10_000;
|
||||||
|
public static final int TRACE_HUNT_MAX_HUNT_PROGRESS = 10_000;
|
||||||
|
|
||||||
public static final int REFRESH_TYPE_DAILY = 1;
|
public static final int REFRESH_TYPE_DAILY = 1;
|
||||||
public static final int REFRESH_TYPE_WEEKLY = 2;
|
public static final int REFRESH_TYPE_WEEKLY = 2;
|
||||||
public static final int REFRESH_TYPE_MONTHLY = 3;
|
public static final int REFRESH_TYPE_MONTHLY = 3;
|
||||||
|
|||||||
@@ -139,6 +139,11 @@ public class GameData {
|
|||||||
@Getter private static DataTable<ScoreBossControlDef> ScoreBossControlDataTable = new DataTable<>();
|
@Getter private static DataTable<ScoreBossControlDef> ScoreBossControlDataTable = new DataTable<>();
|
||||||
@Getter private static DataTable<ScoreBossRewardDef> ScoreBossRewardDataTable = new DataTable<>();
|
@Getter private static DataTable<ScoreBossRewardDef> ScoreBossRewardDataTable = new DataTable<>();
|
||||||
|
|
||||||
|
// ===== Trace Hunt =====
|
||||||
|
@Getter private static DataTable<TraceHuntControlDef> TraceHuntControlDataTable = new DataTable<>();
|
||||||
|
@Getter private static DataTable<TraceHuntLevelDef> TraceHuntLevelDataTable = new DataTable<>();
|
||||||
|
@Getter private static DataTable<TraceHuntSelfHuntExtraCostDef> TraceHuntSelfHuntExtraCostDataTable = new DataTable<>();
|
||||||
|
|
||||||
// ===== Misc =====
|
// ===== Misc =====
|
||||||
@Getter private static DataTable<WorldClassDef> WorldClassDataTable = new DataTable<>();
|
@Getter private static DataTable<WorldClassDef> WorldClassDataTable = new DataTable<>();
|
||||||
@Getter private static DataTable<GuideGroupDef> GuideGroupDataTable = new DataTable<>();
|
@Getter private static DataTable<GuideGroupDef> GuideGroupDataTable = new DataTable<>();
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package emu.nebula.data.resources;
|
||||||
|
|
||||||
|
import emu.nebula.data.BaseDef;
|
||||||
|
import emu.nebula.data.ResourceType;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ResourceType(name = "TraceHuntControl.json")
|
||||||
|
public class TraceHuntControlDef extends BaseDef {
|
||||||
|
private int Id;
|
||||||
|
private int[] BossList;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package emu.nebula.data.resources;
|
||||||
|
|
||||||
|
import emu.nebula.data.BaseDef;
|
||||||
|
import emu.nebula.data.ResourceType;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ResourceType(name = "TraceHuntLevel.json")
|
||||||
|
public class TraceHuntLevelDef extends BaseDef {
|
||||||
|
private int Level;
|
||||||
|
private int Exp;
|
||||||
|
private int WorldClass;
|
||||||
|
private int MaxStar;
|
||||||
|
private int TokenRate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return Level;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package emu.nebula.data.resources;
|
||||||
|
|
||||||
|
import emu.nebula.data.BaseDef;
|
||||||
|
import emu.nebula.data.ResourceType;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ResourceType(name = "TraceHuntSelfHuntExtraCost.json")
|
||||||
|
public class TraceHuntSelfHuntExtraCostDef extends BaseDef {
|
||||||
|
private int Times;
|
||||||
|
private int ExtraCost1Tid;
|
||||||
|
private int ExtraCost1Qty;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return Times;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,6 +46,7 @@ public class Inventory extends PlayerManager implements GameDatabaseObject {
|
|||||||
private ItemParamMap shopBuyCount;
|
private ItemParamMap shopBuyCount;
|
||||||
private String2IntMap mallBuyCount;
|
private String2IntMap mallBuyCount;
|
||||||
private String2IntMap mallPackageBuyCount;
|
private String2IntMap mallPackageBuyCount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tracks whether a MallGem pack has already consumed its maiden bonus.
|
* Tracks whether a MallGem pack has already consumed its maiden bonus.
|
||||||
* This is the only persisted state MallGem recharge still needs now that
|
* This is the only persisted state MallGem recharge still needs now that
|
||||||
@@ -589,6 +590,34 @@ public class Inventory extends PlayerManager implements GameDatabaseObject {
|
|||||||
change.add(proto);
|
change.add(proto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case TraceRequest -> {
|
||||||
|
int oldAmount = this.getPlayer().getTraceHuntManager().getTraceRequests();
|
||||||
|
int newAmount = oldAmount;
|
||||||
|
int diff = 0;
|
||||||
|
|
||||||
|
newAmount = this.getPlayer().getTraceHuntManager().addTraceRequests(amount);
|
||||||
|
diff = newAmount - oldAmount;
|
||||||
|
|
||||||
|
var proto = TraceHuntItem.newInstance()
|
||||||
|
.setTid(id)
|
||||||
|
.setGrantQty(diff);
|
||||||
|
|
||||||
|
change.add(proto);
|
||||||
|
}
|
||||||
|
case HuntPermit -> {
|
||||||
|
int oldAmount = this.getPlayer().getTraceHuntManager().getHuntPermits();
|
||||||
|
int newAmount = oldAmount;
|
||||||
|
int diff = 0;
|
||||||
|
|
||||||
|
newAmount = this.getPlayer().getTraceHuntManager().addHuntPermits(amount);
|
||||||
|
diff = newAmount - oldAmount;
|
||||||
|
|
||||||
|
var proto = TraceHuntItem.newInstance()
|
||||||
|
.setTid(id)
|
||||||
|
.setGrantQty(diff);
|
||||||
|
|
||||||
|
change.add(proto);
|
||||||
|
}
|
||||||
default -> {
|
default -> {
|
||||||
// Not implemented
|
// Not implemented
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import emu.nebula.game.quest.QuestManager;
|
|||||||
import emu.nebula.game.scoreboss.ScoreBossManager;
|
import emu.nebula.game.scoreboss.ScoreBossManager;
|
||||||
import emu.nebula.game.story.StoryManager;
|
import emu.nebula.game.story.StoryManager;
|
||||||
import emu.nebula.game.tower.StarTowerManager;
|
import emu.nebula.game.tower.StarTowerManager;
|
||||||
|
import emu.nebula.game.tracehunt.TraceHuntManager;
|
||||||
import emu.nebula.game.vampire.VampireSurvivorManager;
|
import emu.nebula.game.vampire.VampireSurvivorManager;
|
||||||
import emu.nebula.net.GameSession;
|
import emu.nebula.net.GameSession;
|
||||||
import emu.nebula.net.NetMsgId;
|
import emu.nebula.net.NetMsgId;
|
||||||
@@ -110,6 +111,7 @@ public class Player implements GameDatabaseObject {
|
|||||||
private transient QuestManager questManager;
|
private transient QuestManager questManager;
|
||||||
private transient AchievementManager achievementManager;
|
private transient AchievementManager achievementManager;
|
||||||
private transient AgentManager agentManager;
|
private transient AgentManager agentManager;
|
||||||
|
private transient TraceHuntManager traceHuntManager;
|
||||||
private transient ActivityManager activityManager;
|
private transient ActivityManager activityManager;
|
||||||
|
|
||||||
// Extra
|
// Extra
|
||||||
@@ -814,6 +816,7 @@ public class Player implements GameDatabaseObject {
|
|||||||
this.questManager = this.loadManagerFromDatabase(QuestManager.class);
|
this.questManager = this.loadManagerFromDatabase(QuestManager.class);
|
||||||
this.achievementManager = this.loadManagerFromDatabase(AchievementManager.class);
|
this.achievementManager = this.loadManagerFromDatabase(AchievementManager.class);
|
||||||
this.agentManager = this.loadManagerFromDatabase(AgentManager.class);
|
this.agentManager = this.loadManagerFromDatabase(AgentManager.class);
|
||||||
|
this.traceHuntManager = this.loadManagerFromDatabase(TraceHuntManager.class);
|
||||||
this.activityManager = this.loadManagerFromDatabase(ActivityManager.class);
|
this.activityManager = this.loadManagerFromDatabase(ActivityManager.class);
|
||||||
|
|
||||||
// Database fixes
|
// Database fixes
|
||||||
@@ -1234,7 +1237,7 @@ public class Player implements GameDatabaseObject {
|
|||||||
state.getMutableStarTowerBook();
|
state.getMutableStarTowerBook();
|
||||||
state.getMutableScoreBoss();
|
state.getMutableScoreBoss();
|
||||||
state.getMutableCharAffinityRewards();
|
state.getMutableCharAffinityRewards();
|
||||||
state.getMutableTraceHunt();
|
state.getMutableTraceHunt().setBossRewardCanReceive(this.getTraceHuntManager().isHuntComplete());
|
||||||
|
|
||||||
// Force complete tutorials
|
// Force complete tutorials
|
||||||
for (var guide : GameData.getGuideGroupDataTable()) {
|
for (var guide : GameData.getGuideGroupDataTable()) {
|
||||||
@@ -1307,8 +1310,13 @@ public class Player implements GameDatabaseObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Trace hunt
|
// Trace hunt
|
||||||
proto.getMutableHuntPermit();
|
proto.getMutableHuntPermit()
|
||||||
proto.getMutableTraceRequest();
|
.setTid(GameConstants.TRACE_HUNT_PERMIT_ITEM_ID)
|
||||||
|
.setGrantedCount(this.getTraceHuntManager().getHuntPermits());
|
||||||
|
|
||||||
|
proto.getMutableTraceRequest()
|
||||||
|
.setTid(GameConstants.TRACE_HUNT_REQUEST_ITEM_ID)
|
||||||
|
.setGrantedCount(this.getTraceHuntManager().getTraceRequests());
|
||||||
|
|
||||||
// Complete
|
// Complete
|
||||||
return proto;
|
return proto;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import emu.nebula.game.quest.QuestManager;
|
|||||||
import emu.nebula.game.scoreboss.ScoreBossRankEntry;
|
import emu.nebula.game.scoreboss.ScoreBossRankEntry;
|
||||||
import emu.nebula.game.story.StoryManager;
|
import emu.nebula.game.story.StoryManager;
|
||||||
import emu.nebula.game.tower.StarTowerBuild;
|
import emu.nebula.game.tower.StarTowerBuild;
|
||||||
|
import emu.nebula.game.tracehunt.TraceHuntManager;
|
||||||
import emu.nebula.net.GameSession;
|
import emu.nebula.net.GameSession;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
@@ -183,6 +184,7 @@ public class PlayerModule extends GameContextModule {
|
|||||||
datastore.getCollection(StoryManager.class).deleteOne(idFilter);
|
datastore.getCollection(StoryManager.class).deleteOne(idFilter);
|
||||||
datastore.getCollection(QuestManager.class).deleteOne(idFilter);
|
datastore.getCollection(QuestManager.class).deleteOne(idFilter);
|
||||||
datastore.getCollection(AgentManager.class).deleteOne(idFilter);
|
datastore.getCollection(AgentManager.class).deleteOne(idFilter);
|
||||||
|
datastore.getCollection(TraceHuntManager.class).deleteOne(idFilter);
|
||||||
datastore.getCollection(AchievementManager.class).deleteOne(idFilter);
|
datastore.getCollection(AchievementManager.class).deleteOne(idFilter);
|
||||||
datastore.getCollection(ActivityManager.class).deleteOne(idFilter);
|
datastore.getCollection(ActivityManager.class).deleteOne(idFilter);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package emu.nebula.game.tracehunt;
|
||||||
|
|
||||||
|
import dev.morphia.annotations.Entity;
|
||||||
|
import emu.nebula.proto.Public.TraceHuntBossCollection;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Entity(useDiscriminator = false)
|
||||||
|
public class TraceHuntBoss {
|
||||||
|
private int id;
|
||||||
|
private int hunts;
|
||||||
|
private int assists;
|
||||||
|
|
||||||
|
@Deprecated // Morphia only
|
||||||
|
public TraceHuntBoss() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public TraceHuntBoss(int bossId, int hunts, int assists) {
|
||||||
|
this.id = bossId;
|
||||||
|
this.hunts = hunts;
|
||||||
|
this.assists = assists;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proto
|
||||||
|
|
||||||
|
public TraceHuntBossCollection toProto() {
|
||||||
|
var proto = TraceHuntBossCollection.newInstance()
|
||||||
|
.setId(this.getId())
|
||||||
|
.setHuntCount(this.hunts)
|
||||||
|
.setAssistHuntCount(this.assists);
|
||||||
|
|
||||||
|
return proto;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package emu.nebula.game.tracehunt;
|
||||||
|
|
||||||
|
import dev.morphia.annotations.Entity;
|
||||||
|
import emu.nebula.proto.Public.TraceHuntLogEntry;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Entity(useDiscriminator = false)
|
||||||
|
public class TraceHuntLog {
|
||||||
|
private int id;
|
||||||
|
private String[] args;
|
||||||
|
|
||||||
|
@Deprecated // Morphia only
|
||||||
|
public TraceHuntLog() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public TraceHuntLog(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TraceHuntLog(int id, String... args) {
|
||||||
|
this.id = id;
|
||||||
|
this.args = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proto
|
||||||
|
|
||||||
|
public TraceHuntLogEntry toProto() {
|
||||||
|
var proto = TraceHuntLogEntry.newInstance()
|
||||||
|
.setTid(this.getId());
|
||||||
|
|
||||||
|
if (this.getArgs() != null) {
|
||||||
|
proto.addAllArgs(this.getArgs());
|
||||||
|
}
|
||||||
|
|
||||||
|
return proto;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package emu.nebula.game.tracehunt;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
public enum TraceHuntLogType {
|
||||||
|
TraceStart (1),
|
||||||
|
Tracing (2),
|
||||||
|
TraceBeforeEnd (3),
|
||||||
|
TraceEnd (4),
|
||||||
|
TraceInterrupt (5),
|
||||||
|
TraceRestart (6),
|
||||||
|
HuntBeforeStart (7),
|
||||||
|
HuntStart (8),
|
||||||
|
HuntPlayer (9),
|
||||||
|
HuntNPC (10),
|
||||||
|
HuntPlayerFatal (11),
|
||||||
|
HuntNPCFatal (12),
|
||||||
|
HuntEnd (13),
|
||||||
|
Settlement (14),
|
||||||
|
HuntAfterStart (15),
|
||||||
|
HuntInterrupt (16);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final int value;
|
||||||
|
private final static Int2ObjectMap<TraceHuntLogType> map = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
for (TraceHuntLogType type : TraceHuntLogType.values()) {
|
||||||
|
map.put(type.getValue(), type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private TraceHuntLogType(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TraceHuntLogType getByValue(int value) {
|
||||||
|
return map.get(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,381 @@
|
|||||||
|
package emu.nebula.game.tracehunt;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import dev.morphia.annotations.Entity;
|
||||||
|
import dev.morphia.annotations.Id;
|
||||||
|
import emu.nebula.GameConstants;
|
||||||
|
import emu.nebula.Nebula;
|
||||||
|
import emu.nebula.data.GameData;
|
||||||
|
import emu.nebula.data.resources.TraceHuntControlDef;
|
||||||
|
import emu.nebula.data.resources.TraceHuntSelfHuntExtraCostDef;
|
||||||
|
import emu.nebula.database.GameDatabaseObject;
|
||||||
|
import emu.nebula.game.player.Player;
|
||||||
|
import emu.nebula.game.player.PlayerChangeInfo;
|
||||||
|
import emu.nebula.game.player.PlayerManager;
|
||||||
|
import emu.nebula.proto.TraceHuntInfoOuterClass.TraceHuntInfo;
|
||||||
|
import emu.nebula.util.Utils;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Entity(value = "trace_hunts", useDiscriminator = false)
|
||||||
|
public class TraceHuntManager extends PlayerManager implements GameDatabaseObject {
|
||||||
|
@Id
|
||||||
|
private int uid;
|
||||||
|
|
||||||
|
private int controlId;
|
||||||
|
private int level;
|
||||||
|
private int exp;
|
||||||
|
|
||||||
|
// Requests/Hunt items
|
||||||
|
private int traceRequests;
|
||||||
|
private int dailyRequests; // Max of 20 daily
|
||||||
|
|
||||||
|
private int huntPermits;
|
||||||
|
|
||||||
|
// Current boss
|
||||||
|
private int bossId;
|
||||||
|
private long bossCreateTime;
|
||||||
|
private int traceProgress;
|
||||||
|
private int huntProgress;
|
||||||
|
|
||||||
|
private int huntCount;
|
||||||
|
private int assistCount;
|
||||||
|
|
||||||
|
private List<TraceHuntLog> traceLogs;
|
||||||
|
private List<TraceHuntLog> huntLogs;
|
||||||
|
|
||||||
|
// Current hunt
|
||||||
|
private transient int huntPlayerUid;
|
||||||
|
private transient int huntBossId;
|
||||||
|
private long buildId;
|
||||||
|
|
||||||
|
// Collection
|
||||||
|
private Map<Integer, TraceHuntBoss> bosses;
|
||||||
|
|
||||||
|
@Deprecated // Morphia only
|
||||||
|
public TraceHuntManager() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public TraceHuntManager(Player player) {
|
||||||
|
this();
|
||||||
|
this.setPlayer(player);
|
||||||
|
this.uid = player.getUid();
|
||||||
|
|
||||||
|
this.controlId = 3;
|
||||||
|
this.level = 1;
|
||||||
|
|
||||||
|
this.bossId = this.getControlData().getBossList()[0];
|
||||||
|
this.bossCreateTime = Nebula.getCurrentServerTime();
|
||||||
|
this.traceLogs = new ArrayList<>();
|
||||||
|
this.huntLogs = new ArrayList<>();
|
||||||
|
|
||||||
|
this.bosses = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getControlId() {
|
||||||
|
return this.controlId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TraceHuntControlDef getControlData() {
|
||||||
|
return GameData.getTraceHuntControlDataTable().get(this.getControlId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int addTraceRequests(int amount) {
|
||||||
|
// Add/remove requests
|
||||||
|
this.traceRequests = Math.max(Math.min(this.traceRequests + amount, 60), 0);
|
||||||
|
|
||||||
|
// Save to database
|
||||||
|
this.save();
|
||||||
|
|
||||||
|
// Return amount
|
||||||
|
return this.traceRequests;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int addHuntPermits(int amount) {
|
||||||
|
// Add/remove permits
|
||||||
|
this.huntPermits = Math.max(this.huntPermits + amount, 0);
|
||||||
|
|
||||||
|
// Save to database
|
||||||
|
this.save();
|
||||||
|
|
||||||
|
// Return amount
|
||||||
|
return this.huntPermits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxGainableExp() {
|
||||||
|
if (this.getLevel() >= this.getMaxLevel()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int maxLevel = this.getMaxLevel();
|
||||||
|
int max = 0;
|
||||||
|
|
||||||
|
for (int i = this.getLevel() + 1; i <= maxLevel; i++) {
|
||||||
|
var data = GameData.getTraceHuntLevelDataTable().get(i);
|
||||||
|
|
||||||
|
if (data != null) {
|
||||||
|
max += data.getExp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.max(max - this.getExp(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxExp() {
|
||||||
|
if (this.getLevel() >= this.getMaxLevel()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = GameData.getTraceHuntLevelDataTable().get(this.level + 1);
|
||||||
|
return data != null ? data.getExp() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxLevel() {
|
||||||
|
return GameData.getTraceHuntLevelDataTable().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addExp(int amount) {
|
||||||
|
// Setup
|
||||||
|
int expRequired = this.getMaxExp();
|
||||||
|
|
||||||
|
// Add exp
|
||||||
|
this.exp += amount;
|
||||||
|
|
||||||
|
// Check for level ups
|
||||||
|
while (this.exp >= expRequired && expRequired > 0) {
|
||||||
|
this.level += 1;
|
||||||
|
this.exp -= expRequired;
|
||||||
|
|
||||||
|
expRequired = this.getMaxExp();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clamp exp
|
||||||
|
if (this.getLevel() >= this.getMaxLevel()) {
|
||||||
|
this.exp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save to database
|
||||||
|
this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHunting() {
|
||||||
|
return this.traceProgress >= GameConstants.TRACE_HUNT_MAX_TRACE_PROGRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHuntComplete() {
|
||||||
|
return this.huntProgress >= GameConstants.TRACE_HUNT_MAX_HUNT_PROGRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TraceHuntSelfHuntExtraCostDef getHuntCost() {
|
||||||
|
int times = Math.max(this.huntCount, GameData.getTraceHuntSelfHuntExtraCostDataTable().size());
|
||||||
|
return GameData.getTraceHuntSelfHuntExtraCostDataTable().get(times);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetBoss() {
|
||||||
|
this.bossId = 0;
|
||||||
|
this.bossCreateTime = 0;
|
||||||
|
this.traceProgress = 0;
|
||||||
|
this.huntProgress = 0;
|
||||||
|
|
||||||
|
this.huntCount = 0;
|
||||||
|
this.assistCount = 0;
|
||||||
|
|
||||||
|
this.traceLogs.clear();
|
||||||
|
this.huntLogs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Game logic
|
||||||
|
|
||||||
|
public PlayerChangeInfo trace(int count) {
|
||||||
|
// Sanity check to make sure we have enough requests
|
||||||
|
if (this.getTraceRequests() < count) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanity check to make sure we havent started hunting yet
|
||||||
|
if (this.isHunting()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used requests
|
||||||
|
int consumed = 0;
|
||||||
|
|
||||||
|
// Parse log
|
||||||
|
var logs = new ArrayList<TraceHuntLog>();
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
// Get random trace
|
||||||
|
int traceId = Utils.randomElement(GameConstants.TRACE_HUNT_TRACE_IDS);
|
||||||
|
int progress = 0;
|
||||||
|
|
||||||
|
if (traceId >= 40) {
|
||||||
|
progress = 2000;
|
||||||
|
} else if (traceId >= 30) {
|
||||||
|
progress = 1000;
|
||||||
|
} else {
|
||||||
|
progress = 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add trace log
|
||||||
|
logs.add(new TraceHuntLog(traceId, Integer.toString(progress)));
|
||||||
|
|
||||||
|
// Add progress
|
||||||
|
this.traceProgress += progress;
|
||||||
|
|
||||||
|
// Increment requests we used
|
||||||
|
consumed++;
|
||||||
|
|
||||||
|
// Complete
|
||||||
|
if (this.isHunting()) {
|
||||||
|
logs.add(new TraceHuntLog(5));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consume trace requests
|
||||||
|
var change = this.getPlayer().getInventory().removeItem(GameConstants.TRACE_HUNT_REQUEST_ITEM_ID, consumed);
|
||||||
|
|
||||||
|
// Add to logs
|
||||||
|
this.getTraceLogs().addAll(logs);
|
||||||
|
|
||||||
|
// Add logs to change info
|
||||||
|
change.setExtraData(logs);
|
||||||
|
|
||||||
|
// Save
|
||||||
|
this.save();
|
||||||
|
|
||||||
|
// Success
|
||||||
|
return change;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean apply(long ownerUid, int bossId, long buildId) {
|
||||||
|
// Sanity check
|
||||||
|
if (!this.isHunting() || this.isHuntComplete()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set build
|
||||||
|
this.huntPlayerUid = (int) ownerUid;
|
||||||
|
this.huntBossId = bossId;
|
||||||
|
this.buildId = buildId;
|
||||||
|
|
||||||
|
// Success
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayerChangeInfo settle(int score, int stars) {
|
||||||
|
// Sanity check
|
||||||
|
if (this.huntBossId == 0 || this.huntPlayerUid == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO verify stars
|
||||||
|
stars = Math.min(Math.max(stars, 0), 7);
|
||||||
|
|
||||||
|
// Build change info
|
||||||
|
var change = new PlayerChangeInfo();
|
||||||
|
var logs = new ArrayList<TraceHuntLog>();
|
||||||
|
|
||||||
|
// Add logs to change info
|
||||||
|
change.setExtraData(logs);
|
||||||
|
|
||||||
|
// Calculate result
|
||||||
|
if (this.huntPlayerUid == this.getPlayerUid()) {
|
||||||
|
// Check if we have enough cost items
|
||||||
|
var cost = this.getHuntCost();
|
||||||
|
|
||||||
|
if (cost != null) {
|
||||||
|
if (!getPlayer().getInventory().hasItem(cost.getExtraCost1Tid(), cost.getExtraCost1Qty())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
getPlayer().getInventory().removeItem(cost.getExtraCost1Tid(), cost.getExtraCost1Qty(), change);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Our own hunts
|
||||||
|
int progress = stars * 500;
|
||||||
|
|
||||||
|
logs.add(new TraceHuntLog(11, this.getPlayer().getName(), Integer.toString(progress)));
|
||||||
|
|
||||||
|
// Add to logs
|
||||||
|
this.huntProgress = Math.min(this.huntProgress + progress, GameConstants.TRACE_HUNT_MAX_HUNT_PROGRESS);
|
||||||
|
this.huntCount++;
|
||||||
|
this.getHuntLogs().addAll(logs);
|
||||||
|
|
||||||
|
// Save
|
||||||
|
this.save();
|
||||||
|
} else {
|
||||||
|
// Other player's hunts are not supported yet TODO
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Success
|
||||||
|
return change;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayerChangeInfo claimReward() {
|
||||||
|
if (!this.isHuntComplete()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add boss log
|
||||||
|
var bossLog = new TraceHuntBoss(this.getBossId(), this.getHuntCount(), this.getAssistCount());
|
||||||
|
this.getBosses().put(this.getBossId(), bossLog);
|
||||||
|
|
||||||
|
// Reset boss
|
||||||
|
this.resetBoss();
|
||||||
|
|
||||||
|
// Get next boss from control data
|
||||||
|
var control = this.getControlData();
|
||||||
|
|
||||||
|
for (int bossId : control.getBossList()) {
|
||||||
|
if (this.getBosses().containsKey(bossId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.bossId = bossId;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save
|
||||||
|
this.save();
|
||||||
|
|
||||||
|
// Success
|
||||||
|
// Test amount of items
|
||||||
|
return this.getPlayer().getInventory().addItem(37, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proto
|
||||||
|
|
||||||
|
public TraceHuntInfo toProto() {
|
||||||
|
var proto = TraceHuntInfo.newInstance()
|
||||||
|
.setControlID(this.getControlId())
|
||||||
|
.setLevel(this.getLevel())
|
||||||
|
.setExp(this.getExp())
|
||||||
|
.setBossID(this.getBossId())
|
||||||
|
.setBossCreateTime(this.getBossCreateTime())
|
||||||
|
.setBuildID(this.getBuildId())
|
||||||
|
.setTraceProgress(this.getTraceProgress())
|
||||||
|
.setHuntProgress(this.getHuntProgress())
|
||||||
|
.setSelfHuntTimes(this.getHuntCount());
|
||||||
|
|
||||||
|
for (var boss : this.getBosses().values()) {
|
||||||
|
proto.addBossCollections(boss.toProto());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var log : this.getTraceLogs()) {
|
||||||
|
proto.addTraceLog(log.toProto());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var log : this.getHuntLogs()) {
|
||||||
|
proto.addHuntLog(log.toProto());
|
||||||
|
}
|
||||||
|
|
||||||
|
return proto;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package emu.nebula.server.handlers;
|
||||||
|
|
||||||
|
import emu.nebula.net.NetHandler;
|
||||||
|
import emu.nebula.net.NetMsgId;
|
||||||
|
import emu.nebula.proto.TraceHuntApply.TraceHuntApplyReq;
|
||||||
|
import emu.nebula.net.HandlerId;
|
||||||
|
import emu.nebula.net.GameSession;
|
||||||
|
|
||||||
|
@HandlerId(NetMsgId.trace_hunt_apply_req)
|
||||||
|
public class HandlerTraceHuntApplyReq extends NetHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||||
|
// Parse Request
|
||||||
|
var req = TraceHuntApplyReq.parseFrom(message);
|
||||||
|
|
||||||
|
// Hunt
|
||||||
|
boolean success = session.getPlayer().getTraceHuntManager().apply(req.getOwnerUID(), req.getBossID(), req.getBuildID());
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
return session.encodeMsg(NetMsgId.trace_hunt_apply_failed_ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode and send
|
||||||
|
return session.encodeMsg(NetMsgId.trace_hunt_apply_succeed_ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package emu.nebula.server.handlers;
|
||||||
|
|
||||||
|
import emu.nebula.net.NetHandler;
|
||||||
|
import emu.nebula.net.NetMsgId;
|
||||||
|
import emu.nebula.proto.TraceHuntBossRewardReceive.TraceHuntBossRewardReceiveResp;
|
||||||
|
import emu.nebula.net.HandlerId;
|
||||||
|
import emu.nebula.net.GameSession;
|
||||||
|
|
||||||
|
@HandlerId(NetMsgId.trace_hunt_boss_reward_receive_req)
|
||||||
|
public class HandlerTraceHuntBossRewardReceiveReq extends NetHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||||
|
// Get manager
|
||||||
|
var manager = session.getPlayer().getTraceHuntManager();
|
||||||
|
|
||||||
|
// Claim reward
|
||||||
|
var change = manager.claimReward();
|
||||||
|
|
||||||
|
if (change == null) {
|
||||||
|
return session.encodeMsg(NetMsgId.trace_hunt_boss_reward_receive_failed_ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build response
|
||||||
|
var rsp = TraceHuntBossRewardReceiveResp.newInstance()
|
||||||
|
.setLevel(manager.getLevel())
|
||||||
|
.setExp(manager.getExp())
|
||||||
|
.setChangeInfo(change.toProto());
|
||||||
|
|
||||||
|
// Encode and send
|
||||||
|
return session.encodeMsg(NetMsgId.trace_hunt_boss_reward_receive_succeed_ack, rsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package emu.nebula.server.handlers;
|
||||||
|
|
||||||
|
import emu.nebula.net.NetHandler;
|
||||||
|
import emu.nebula.net.NetMsgId;
|
||||||
|
import emu.nebula.net.HandlerId;
|
||||||
|
import emu.nebula.net.GameSession;
|
||||||
|
|
||||||
|
@HandlerId(NetMsgId.trace_hunt_info_req)
|
||||||
|
public class HandlerTraceHuntInfoReq extends NetHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||||
|
// Encode and send
|
||||||
|
return session.encodeMsg(NetMsgId.trace_hunt_info_succeed_ack, session.getPlayer().getTraceHuntManager().toProto());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package emu.nebula.server.handlers;
|
||||||
|
|
||||||
|
import emu.nebula.net.NetHandler;
|
||||||
|
import emu.nebula.net.NetMsgId;
|
||||||
|
import emu.nebula.proto.TraceHuntRecommend.TraceHuntRecommendResp;
|
||||||
|
import emu.nebula.net.HandlerId;
|
||||||
|
import emu.nebula.net.GameSession;
|
||||||
|
|
||||||
|
@HandlerId(NetMsgId.trace_hunt_recommend_req)
|
||||||
|
public class HandlerTraceHuntRecommendReq extends NetHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||||
|
// Build response
|
||||||
|
var rsp = TraceHuntRecommendResp.newInstance();
|
||||||
|
|
||||||
|
// TODO add other players
|
||||||
|
|
||||||
|
// Encode and send
|
||||||
|
return session.encodeMsg(NetMsgId.trace_hunt_recommend_succeed_ack, rsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package emu.nebula.server.handlers;
|
||||||
|
|
||||||
|
import emu.nebula.net.NetHandler;
|
||||||
|
import emu.nebula.net.NetMsgId;
|
||||||
|
import emu.nebula.proto.TraceHuntSettle.TraceHuntSettleReq;
|
||||||
|
import emu.nebula.proto.TraceHuntSettle.TraceHuntSettleResp;
|
||||||
|
import emu.nebula.net.HandlerId;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import emu.nebula.game.tracehunt.TraceHuntLog;
|
||||||
|
import emu.nebula.net.GameSession;
|
||||||
|
|
||||||
|
@HandlerId(NetMsgId.trace_hunt_settle_req)
|
||||||
|
public class HandlerTraceHuntSettleReq extends NetHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||||
|
// Parse request
|
||||||
|
var req = TraceHuntSettleReq.parseFrom(message);
|
||||||
|
|
||||||
|
// Get manager
|
||||||
|
var manager = session.getPlayer().getTraceHuntManager();
|
||||||
|
|
||||||
|
// Hunt
|
||||||
|
var change = manager.settle(req.getScore(), req.getStar());
|
||||||
|
|
||||||
|
if (change == null) {
|
||||||
|
return session.encodeMsg(NetMsgId.trace_hunt_settle_failed_ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle client events for achievements
|
||||||
|
session.getPlayer().getAchievementManager().handleClientEvents(req.getEvents());
|
||||||
|
|
||||||
|
// Build response
|
||||||
|
var rsp = TraceHuntSettleResp.newInstance()
|
||||||
|
.setLevel(manager.getLevel())
|
||||||
|
.setExp(manager.getExp())
|
||||||
|
.setSelfHuntTimes(manager.getHuntCount())
|
||||||
|
.setBossCreateTime(manager.getBossCreateTime());
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
var logs = (List<TraceHuntLog>) change.getExtraData();
|
||||||
|
for (var log : logs) {
|
||||||
|
rsp.addHuntLog(log.toProto());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode and send
|
||||||
|
return session.encodeMsg(NetMsgId.trace_hunt_settle_succeed_ack, rsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package emu.nebula.server.handlers;
|
||||||
|
|
||||||
|
import emu.nebula.net.NetHandler;
|
||||||
|
import emu.nebula.net.NetMsgId;
|
||||||
|
import emu.nebula.proto.Public.I32;
|
||||||
|
import emu.nebula.proto.TraceHuntTrace.TraceHuntTraceResp;
|
||||||
|
import emu.nebula.net.HandlerId;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import emu.nebula.game.tracehunt.TraceHuntLog;
|
||||||
|
import emu.nebula.net.GameSession;
|
||||||
|
|
||||||
|
@HandlerId(NetMsgId.trace_hunt_trace_req)
|
||||||
|
public class HandlerTraceHuntTraceReq extends NetHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||||
|
// Parse request
|
||||||
|
var req = I32.parseFrom(message);
|
||||||
|
|
||||||
|
// Trace
|
||||||
|
var change = session.getPlayer().getTraceHuntManager().trace(req.getValue());
|
||||||
|
|
||||||
|
// Sanity check
|
||||||
|
if (change == null) {
|
||||||
|
return session.encodeMsg(NetMsgId.trace_hunt_apply_failed_ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build response
|
||||||
|
var rsp = TraceHuntTraceResp.newInstance()
|
||||||
|
.setBossID(session.getPlayer().getTraceHuntManager().getBossId())
|
||||||
|
.setChangeInfo(change.toProto());
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
var logs = (List<TraceHuntLog>) change.getExtraData();
|
||||||
|
for (var log : logs) {
|
||||||
|
rsp.addTraceLog(log.toProto());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode and send
|
||||||
|
return session.encodeMsg(NetMsgId.trace_hunt_apply_succeed_ack, rsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user