Implement commissions

This commit is contained in:
Melledy
2025-11-12 03:25:23 -08:00
parent d4a7aa0320
commit be4a006c66
19 changed files with 526 additions and 40 deletions

View File

@@ -0,0 +1,48 @@
package emu.nebula.game.agent;
import dev.morphia.annotations.Entity;
import emu.nebula.Nebula;
import emu.nebula.data.resources.AgentDef;
import emu.nebula.proto.Public.AgentInfo;
import lombok.Getter;
@Getter
@Entity(useDiscriminator = false)
public class Agent {
private int id;
private int duration; // Minutes
private long start; // Seconds
private int[] charIds;
private long end; // Milliseconds
@Deprecated // Morphia only
public Agent() {
}
public Agent(AgentDef data, int duration, int[] charIds) {
this.id = data.getId();
this.start = Nebula.getCurrentTime();
this.duration = duration;
this.charIds = charIds;
this.end = (this.start + (duration * 60)) * 1000;
}
public boolean isCompleted() {
return System.currentTimeMillis() >= this.getEnd();
}
// Proto
public AgentInfo toProto() {
var proto = AgentInfo.newInstance()
.setId(this.getId())
.setProcessTime(this.getDuration())
.setStartTime(this.getStart())
.addAllCharIds(this.getCharIds());
return proto;
}
}

View File

@@ -0,0 +1,159 @@
package emu.nebula.game.agent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import emu.nebula.data.GameData;
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.game.quest.QuestCondType;
import lombok.Getter;
import us.hebi.quickbuf.RepeatedInt;
@Getter
@Entity(value = "agents", useDiscriminator = false)
public class AgentManager extends PlayerManager implements GameDatabaseObject {
@Id
private int uid;
private Map<Integer, Agent> agents;
@Deprecated // Morhpia only
public AgentManager() {
}
public AgentManager(Player player) {
super(player);
this.uid = player.getUid();
this.agents = new HashMap<>();
this.save();
}
public int getMax() {
return 4;
}
public Agent apply(int id, int processTime, RepeatedInt charIds) {
// Check if we already have the maximum amount of commissions
if (this.getAgents().size() >= this.getMax()) {
return null;
}
// Get agent data
var data = GameData.getAgentDataTable().get(id);
if (data == null) {
return null;
}
// Sanity check char ids
if (charIds.length() <= 0 || charIds.length() > data.getMemberLimit()) {
return null;
}
// Make sure we own the characters
for (int charId : charIds) {
if (!getPlayer().getCharacters().hasCharacter(charId)) {
return null;
}
}
// TODO verify char tags for rewards
// Create agent
var agent = new Agent(data, processTime, charIds.toArray());
// Add
this.getAgents().put(agent.getId(), agent);
// Quest
this.getPlayer().getQuestManager().triggerQuest(QuestCondType.AgentApplyTotal, 1);
// Success
return agent;
}
public Agent giveUp(int id) {
var agent = this.getAgents().remove(id);
if (agent != null) {
this.save();
}
return agent;
}
public PlayerChangeInfo claim(int id) {
// Create list of claimed agents
var list = new ArrayList<Agent>();
if (id > 0) {
var agent = this.getAgents().get(id);
if (agent != null && agent.isCompleted()) {
list.add(agent);
}
} else {
for (var agent : this.getAgents().values()) {
if (agent != null && agent.isCompleted()) {
list.add(agent);
}
}
}
// Sanity check
if (list.isEmpty()) {
return null;
}
// Create results
var change = new PlayerChangeInfo();
var results = new ArrayList<AgentResult>();
// Claim
for (var agent : list) {
// Remove agent
this.getAgents().remove(agent.getId());
// Get result
var result = new AgentResult(agent);
// Add to result list
results.add(result);
// Get agent data
var data = GameData.getAgentDataTable().get(agent.getId());
if (data == null) {
continue;
}
// Calculate rewards
var duration = data.getDurations().get(agent.getDuration());
if (duration == null) {
continue;
}
// Create rewards
var rewards = duration.getRewards().generateRewards();
result.setRewards(rewards);
// Add to inventory
this.getPlayer().getInventory().addItems(rewards, change);
}
// Set results in change info
change.setExtraData(results);
// Save to database
this.save();
// Success
return change.setSuccess(true);
}
}

View File

@@ -0,0 +1,41 @@
package emu.nebula.game.agent;
import emu.nebula.game.inventory.ItemParamMap;
public class AgentResult {
private Agent agent;
private ItemParamMap rewards;
private ItemParamMap bonus;
public AgentResult(Agent agent) {
this.agent = agent;
}
public Agent getAgent() {
return this.agent;
}
public ItemParamMap getRewards() {
if (this.rewards == null) {
return ItemParamMap.EMPTY;
}
return this.rewards;
}
public ItemParamMap getBonus() {
if (this.bonus == null) {
return ItemParamMap.EMPTY;
}
return this.bonus;
}
public void setRewards(ItemParamMap rewards) {
this.rewards = rewards;
}
public void setBonus(ItemParamMap bonus) {
this.bonus = bonus;
}
}

View File

@@ -3,6 +3,7 @@ package emu.nebula.game.instance;
import java.util.List;
import emu.nebula.game.inventory.ItemParamMap;
import emu.nebula.game.inventory.ItemRewardParam;
import emu.nebula.game.player.Player;
public interface InstanceData {
@@ -15,9 +16,9 @@ public interface InstanceData {
// Handle reward generation
public List<InstanceRewardParam> getFirstRewards();
public List<ItemRewardParam> getFirstRewards();
public default List<InstanceRewardParam> getFirstRewards(int rewardType) {
public default List<ItemRewardParam> getFirstRewards(int rewardType) {
return getFirstRewards();
}
@@ -25,9 +26,9 @@ public interface InstanceData {
return this.generateRewards(this.getFirstRewards());
}
public List<InstanceRewardParam> getRewards();
public List<ItemRewardParam> getRewards();
public default List<InstanceRewardParam> getRewards(int rewardType) {
public default List<ItemRewardParam> getRewards(int rewardType) {
return getRewards();
}
@@ -35,7 +36,7 @@ public interface InstanceData {
return this.generateRewards(this.getRewards());
}
public default ItemParamMap generateRewards(List<InstanceRewardParam> params) {
public default ItemParamMap generateRewards(List<ItemRewardParam> params) {
var map = new ItemParamMap();
for (var param : params) {

View File

@@ -0,0 +1,21 @@
package emu.nebula.game.inventory;
import java.util.ArrayList;
public class ItemRewardList extends ArrayList<ItemRewardParam> {
private static final long serialVersionUID = -4317949564663392685L;
public ItemRewardList() {
super();
}
public ItemParamMap generateRewards() {
var map = new ItemParamMap();
for (var param : this) {
map.add(param.getId(), param.getRandomCount());
}
return map;
}
}

View File

@@ -1,15 +1,15 @@
package emu.nebula.game.instance;
package emu.nebula.game.inventory;
import emu.nebula.util.Utils;
import lombok.Getter;
@Getter
public class InstanceRewardParam {
public class ItemRewardParam {
public int id;
public int min;
public int max;
public InstanceRewardParam(int id, int min, int max) {
public ItemRewardParam(int id, int min, int max) {
this.id = id;
this.min = min;
this.max = max;

View File

@@ -11,6 +11,7 @@ import emu.nebula.Nebula;
import emu.nebula.data.GameData;
import emu.nebula.database.GameDatabaseObject;
import emu.nebula.game.account.Account;
import emu.nebula.game.agent.AgentManager;
import emu.nebula.game.character.CharacterStorage;
import emu.nebula.game.formation.FormationManager;
import emu.nebula.game.gacha.GachaManager;
@@ -87,6 +88,7 @@ public class Player implements GameDatabaseObject {
private transient PlayerProgress progress;
private transient StoryManager storyManager;
private transient QuestManager questManager;
private transient AgentManager agentManager;
// Next packages
private transient Stack<NetMsgPacket> nextPackages;
@@ -532,6 +534,7 @@ public class Player implements GameDatabaseObject {
this.progress = this.loadManagerFromDatabase(PlayerProgress.class);
this.storyManager = this.loadManagerFromDatabase(StoryManager.class);
this.questManager = this.loadManagerFromDatabase(QuestManager.class);
this.agentManager = this.loadManagerFromDatabase(AgentManager.class);
// Database fixes
if (this.showChars == null) {
@@ -714,9 +717,14 @@ public class Player implements GameDatabaseObject {
var phone = proto.getMutablePhone();
phone.setNewMessage(this.getCharacters().getNewPhoneMessageCount());
// Extra
proto.getMutableAgent();
// Agent
var agentProto = proto.getMutableAgent();
for (var agent : getAgentManager().getAgents().values()) {
agentProto.addInfos(agent.toProto());
}
// Complete
return proto;
}