mirror of
https://github.com/Melledy/LunarCore.git
synced 2026-03-29 03:12:21 +02:00
Merge remote-tracking branch 'origin/development' into development
# Conflicts: # README.md
This commit is contained in:
@@ -86,13 +86,15 @@ public class Config {
|
||||
@Getter
|
||||
public static class ServerOptions {
|
||||
public boolean autoCreateAccount = true;
|
||||
public int entitySceneLimit = 2000;
|
||||
public int sceneMaxEntites = 500;
|
||||
public boolean spendStamina = true;
|
||||
public boolean unlockAllChallenges = true;
|
||||
public int staminaRecoveryRate = 5 * 60;
|
||||
public int staminaReserveRecoveryRate = 18 * 60;
|
||||
public String language = "EN";
|
||||
public Set<String> defaultPermissions = Set.of("*");
|
||||
|
||||
public ServerProfile serverFriendInfo = new ServerProfile();
|
||||
public WelcomeMail welcomeMail = new WelcomeMail();
|
||||
|
||||
public int getStaminaRecoveryRate() {
|
||||
@@ -104,6 +106,17 @@ public class Config {
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class ServerProfile {
|
||||
public String name = "Server";
|
||||
public String signature = "Type /help for a list of commands";
|
||||
public int level = 1;
|
||||
public int headIcon = 201001;
|
||||
public int chatBubbleId = 0;
|
||||
public int displayAvatarId = 1001;
|
||||
public int displayAvatarLevel = 1;
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class WelcomeMail {
|
||||
public String title;
|
||||
@@ -130,6 +143,7 @@ public class Config {
|
||||
public boolean commands = true;
|
||||
public boolean connections = true;
|
||||
public boolean packets = false;
|
||||
public boolean filterLoopingPackets = false;
|
||||
}
|
||||
|
||||
@Getter
|
||||
|
||||
@@ -18,20 +18,33 @@ public class GameConstants {
|
||||
public static final int MAX_STAMINA = 240;
|
||||
public static final int MAX_STAMINA_RESERVE = 2400;
|
||||
public static final int MAX_AVATARS_IN_TEAM = 4;
|
||||
public static final int MAX_FRIENDSHIPS = 100;
|
||||
public static final int DEFAULT_TEAMS = 6;
|
||||
public static final int MAX_MP = 5; // Client doesnt like more than 5
|
||||
|
||||
// Chat/Social
|
||||
public static final int MAX_FRIENDSHIPS = 100;
|
||||
public static final int MAX_CHAT_HISTORY = 100; // Max chat messages per conversation
|
||||
|
||||
// Inventory
|
||||
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 TRAILBLAZER_EXP_ID = 22;
|
||||
|
||||
public static final int INVENTORY_MAX_EQUIPMENT = 1500;
|
||||
public static final int INVENTORY_MAX_RELIC = 1500;
|
||||
public static final int INVENTORY_MAX_MATERIAL = 2000;
|
||||
|
||||
// Start position
|
||||
public static final int START_PLANE_ID = 20001;
|
||||
public static final int START_FLOOR_ID = 20001001;
|
||||
public static final int START_ENTRY_ID = 2000101;
|
||||
public static final Position START_POS = new Position(99, 62, -4800);
|
||||
|
||||
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 TRAILBLAZER_EXP_ID = 22;
|
||||
// Battle
|
||||
public static final int BATTLE_AMBUSH_BUFF_ID = 1000102;
|
||||
|
||||
// Gacha
|
||||
public static final int GACHA_CEILING_MAX = 300; // Yes, I know this is in an excel
|
||||
|
||||
// Challenge
|
||||
public static final int CHALLENGE_ENTRANCE = 100000103;
|
||||
|
||||
@@ -255,4 +255,6 @@ public class LunarCore {
|
||||
return (this.flags & 0x2) == 0x2;
|
||||
}
|
||||
}
|
||||
|
||||
// Hiro was here
|
||||
}
|
||||
|
||||
@@ -12,4 +12,6 @@ public @interface Command {
|
||||
public String desc() default "";
|
||||
|
||||
public String permission() default "";
|
||||
|
||||
public boolean requireTarget() default false;
|
||||
}
|
||||
|
||||
@@ -6,13 +6,17 @@ import emu.lunarcore.LunarCore;
|
||||
import emu.lunarcore.data.GameData;
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.inventory.GameItem;
|
||||
import emu.lunarcore.game.inventory.GameItemSubAffix;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.util.Utils;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class CommandArgs {
|
||||
private List<String> list;
|
||||
private Player sender;
|
||||
private Player target;
|
||||
|
||||
private int targetUid;
|
||||
@@ -21,10 +25,12 @@ public class CommandArgs {
|
||||
private int rank = -1;
|
||||
private int promotion = -1;
|
||||
private int stage = -1;
|
||||
private Int2IntMap map;
|
||||
|
||||
private static String EMPTY_STRING = "";
|
||||
|
||||
public CommandArgs(Player sender, List<String> args) {
|
||||
this.sender = sender;
|
||||
this.list = args;
|
||||
|
||||
// Parse args. Maybe regex is better.
|
||||
@@ -35,23 +41,37 @@ public class CommandArgs {
|
||||
|
||||
try {
|
||||
if (arg.length() >= 2 && !Character.isDigit(arg.charAt(0)) && Character.isDigit(arg.charAt(arg.length() - 1))) {
|
||||
if (arg.startsWith("@")) {
|
||||
if (arg.startsWith("@")) { // Target UID
|
||||
this.targetUid = Utils.parseSafeInt(arg.substring(1));
|
||||
it.remove();
|
||||
} else if (arg.startsWith("x")) {
|
||||
} else if (arg.startsWith("x")) { // Amount
|
||||
this.amount = Utils.parseSafeInt(arg.substring(1));
|
||||
it.remove();
|
||||
} else if (arg.startsWith("lv")) {
|
||||
} else if (arg.startsWith("lv")) { // Level
|
||||
this.level = Utils.parseSafeInt(arg.substring(2));
|
||||
it.remove();
|
||||
} else if (arg.startsWith("r")) {
|
||||
} else if (arg.startsWith("r")) { // Rank
|
||||
this.rank = Utils.parseSafeInt(arg.substring(1));
|
||||
it.remove();
|
||||
} else if (arg.startsWith("p")) {
|
||||
} else if (arg.startsWith("e")) { // Eidolons
|
||||
this.rank = Utils.parseSafeInt(arg.substring(1));
|
||||
it.remove();
|
||||
} else if (arg.startsWith("p")) { // Promotion
|
||||
this.promotion = Utils.parseSafeInt(arg.substring(1));
|
||||
it.remove();
|
||||
} else if (arg.startsWith("s")) {
|
||||
} else if (arg.startsWith("s")) { // Stage or Superimposition
|
||||
this.stage = Utils.parseSafeInt(arg.substring(1));
|
||||
it.remove();
|
||||
}
|
||||
} else if (arg.contains(":")) {
|
||||
String[] split = arg.split(":");
|
||||
if (split.length >= 2) {
|
||||
int key = Integer.parseInt(split[0]);
|
||||
int value = Integer.parseInt(split[1]);
|
||||
|
||||
if (this.map == null) this.map = new Int2IntOpenHashMap();
|
||||
this.map.put(key, value);
|
||||
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
@@ -85,6 +105,18 @@ public class CommandArgs {
|
||||
return this.list.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to the command sender
|
||||
* @param message
|
||||
*/
|
||||
public void sendMessage(String message) {
|
||||
if (sender != null) {
|
||||
sender.sendMessage(message);
|
||||
} else {
|
||||
LunarCore.getLogger().info(message);
|
||||
}
|
||||
}
|
||||
|
||||
// Utility commands
|
||||
|
||||
/**
|
||||
@@ -144,22 +176,60 @@ public class CommandArgs {
|
||||
if (this.getLevel() > 0) {
|
||||
item.setLevel(Math.min(this.getLevel(), 80));
|
||||
item.setPromotion(Utils.getMinPromotionForLevel(item.getLevel()));
|
||||
hasChanged = true;
|
||||
}
|
||||
|
||||
// Try to set promotion
|
||||
if (this.getPromotion() >= 0) {
|
||||
item.setPromotion(Math.min(this.getPromotion(), item.getExcel().getEquipmentExcel().getMaxPromotion()));
|
||||
hasChanged = true;
|
||||
}
|
||||
|
||||
// Try to set rank (superimposition)
|
||||
if (this.getRank() >= 0) {
|
||||
item.setRank(Math.min(this.getRank(), item.getExcel().getEquipmentExcel().getMaxRank()));
|
||||
hasChanged = true;
|
||||
} else if (this.getStage() >= 0) {
|
||||
item.setRank(Math.min(this.getStage(), item.getExcel().getEquipmentExcel().getMaxRank()));
|
||||
hasChanged = true;
|
||||
}
|
||||
} else if (item.getExcel().isRelic()) {
|
||||
// Sub stats
|
||||
if (this.getMap() != null) {
|
||||
item.resetSubAffixes();
|
||||
hasChanged = true;
|
||||
|
||||
for (var entry : this.getMap().int2IntEntrySet()) {
|
||||
if (entry.getIntValue() <= 0) continue;
|
||||
|
||||
var subAffix = GameData.getRelicSubAffixExcel(item.getExcel().getRelicExcel().getSubAffixGroup(), entry.getIntKey());
|
||||
if (subAffix == null) continue;
|
||||
|
||||
item.getSubAffixes().add(new GameItemSubAffix(subAffix, entry.getIntValue()));
|
||||
}
|
||||
}
|
||||
|
||||
// Main stat
|
||||
if (this.getStage() > 0) {
|
||||
var mainAffix = GameData.getRelicMainAffixExcel(item.getExcel().getRelicExcel().getMainAffixGroup(), this.getStage());
|
||||
if (mainAffix != null) {
|
||||
item.setMainAffix(mainAffix.getAffixID());
|
||||
hasChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to set level
|
||||
if (this.getLevel() > 0) {
|
||||
item.setLevel(Math.min(this.getLevel(), 15));
|
||||
// TODO add substats
|
||||
// Set relic level
|
||||
item.setLevel(Math.min(this.getLevel(), 999));
|
||||
|
||||
// Apply sub stat upgrades to the relic
|
||||
int upgrades = item.getMaxNormalSubAffixCount() - item.getCurrentSubAffixCount();
|
||||
if (upgrades > 0) {
|
||||
item.addSubAffixes(upgrades);
|
||||
}
|
||||
|
||||
hasChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,22 +1,15 @@
|
||||
package emu.lunarcore.command;
|
||||
|
||||
import emu.lunarcore.LunarCore;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
|
||||
public interface CommandHandler {
|
||||
|
||||
public default Command getData() {
|
||||
return this.getClass().getAnnotation(Command.class);
|
||||
}
|
||||
|
||||
public default String getLabel() {
|
||||
return this.getClass().getAnnotation(Command.class).label();
|
||||
return getData().label();
|
||||
}
|
||||
|
||||
public default void sendMessage(Player player, String message) {
|
||||
if (player != null) {
|
||||
player.sendMessage(message);
|
||||
} else {
|
||||
LunarCore.getLogger().info(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void execute(Player sender, CommandArgs args);
|
||||
public void execute(CommandArgs args);
|
||||
|
||||
}
|
||||
|
||||
@@ -39,11 +39,12 @@ public class CommandManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a command that players and server console users can use. Command handlers must have the proper command annotation attached to them.
|
||||
*/
|
||||
public CommandManager registerCommand(CommandHandler handler) {
|
||||
Command command = handler.getClass().getAnnotation(Command.class);
|
||||
if (command == null) {
|
||||
return this;
|
||||
}
|
||||
if (command == null) return this;
|
||||
|
||||
this.getLabels().put(command.label(), handler);
|
||||
this.getCommands().put(command.label(), handler);
|
||||
@@ -55,11 +56,14 @@ public class CommandManager {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a command from use.
|
||||
* @param label The command name
|
||||
* @return
|
||||
*/
|
||||
public CommandManager unregisterCommand(String label) {
|
||||
CommandHandler handler = this.getLabels().get(label);
|
||||
if (handler == null) {
|
||||
return this;
|
||||
}
|
||||
if (handler == null) return this;
|
||||
|
||||
Command command = handler.getClass().getAnnotation(Command.class);
|
||||
if (command == null) {
|
||||
@@ -76,6 +80,12 @@ public class CommandManager {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the sender has permission to use this command. Will always return true if the sender is the server console.
|
||||
* @param sender The sender of the command.
|
||||
* @param command
|
||||
* @return true if the sender has permission to use this command
|
||||
*/
|
||||
private boolean checkPermission(Player sender, Command command) {
|
||||
if (sender == null || command.permission().isEmpty()) {
|
||||
return true;
|
||||
@@ -84,6 +94,12 @@ public class CommandManager {
|
||||
return sender.getAccount().hasPermission(command.permission());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the sender has permission to use this command on other players. Will always return true if the sender is the server console.
|
||||
* @param sender The sender of the command.
|
||||
* @param command
|
||||
* @return true if the sender has permission to use this command
|
||||
*/
|
||||
private boolean checkTargetPermission(Player sender, Command command) {
|
||||
if (sender == null || command.permission().isEmpty()) {
|
||||
return true;
|
||||
@@ -93,44 +109,59 @@ public class CommandManager {
|
||||
}
|
||||
|
||||
public void invoke(Player sender, String message) {
|
||||
// Parse message into arguments
|
||||
List<String> args = Arrays.stream(message.split(" ")).collect(Collectors.toCollection(ArrayList::new));
|
||||
|
||||
// Get command label
|
||||
String label = args.remove(0).toLowerCase();
|
||||
|
||||
// Filter out command prefixes
|
||||
if (label.startsWith("/") || label.startsWith("!")) {
|
||||
label = label.substring(1);
|
||||
}
|
||||
|
||||
// Get handler
|
||||
// Get command handler
|
||||
CommandHandler handler = this.commands.get(label);
|
||||
|
||||
// Execute
|
||||
// Execute command
|
||||
if (handler != null) {
|
||||
// Command annotation data
|
||||
Command command = handler.getClass().getAnnotation(Command.class);
|
||||
// Check permission
|
||||
if (this.checkPermission(sender, command)) {
|
||||
// Check targeted permission
|
||||
CommandArgs cmdArgs = new CommandArgs(sender, args);
|
||||
if (sender != cmdArgs.getTarget() && !this.checkTargetPermission(sender, command)) {
|
||||
handler.sendMessage(sender, "You do not have permission to use this command on another player.");
|
||||
return;
|
||||
}
|
||||
// Log
|
||||
if (sender != null && LunarCore.getConfig().getLogOptions().commands) {
|
||||
LunarCore.getLogger().info("[UID: " + sender.getUid() + "] " + sender.getName() + " used command: " + message);
|
||||
}
|
||||
// Run command
|
||||
handler.execute(sender, cmdArgs);
|
||||
} else {
|
||||
handler.sendMessage(sender, "You do not have permission to use this command.");
|
||||
// Get command annotation data
|
||||
Command command = handler.getData();
|
||||
|
||||
// Check if sender has permission to run the command.
|
||||
if (sender != null && !this.checkPermission(sender, command)) {
|
||||
// We have a double null check here just in case
|
||||
sender.sendMessage("You do not have permission to use this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Build command arguments
|
||||
CommandArgs cmdArgs = new CommandArgs(sender, args);
|
||||
|
||||
// Check targeted permission
|
||||
if (sender != cmdArgs.getTarget() && !this.checkTargetPermission(sender, command)) {
|
||||
cmdArgs.sendMessage("You do not have permission to use this command on another player.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure our command has a target
|
||||
if (command.requireTarget() && cmdArgs.getTarget() == null) {
|
||||
cmdArgs.sendMessage("Error: Targeted player not found or offline");
|
||||
return;
|
||||
}
|
||||
|
||||
// Log
|
||||
if (sender != null && LunarCore.getConfig().getLogOptions().commands) {
|
||||
LunarCore.getLogger().info("[UID: " + sender.getUid() + "] " + sender.getName() + " used command: " + message);
|
||||
}
|
||||
|
||||
// Run command
|
||||
handler.execute(cmdArgs);
|
||||
} else {
|
||||
if (sender != null) {
|
||||
sender.sendMessage("Inavlid Command!");
|
||||
sender.sendMessage("Invalid Command!");
|
||||
} else {
|
||||
LunarCore.getLogger().info("Inavlid Command!");
|
||||
LunarCore.getLogger().info("Invalid Command!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,16 +4,15 @@ import emu.lunarcore.command.Command;
|
||||
import emu.lunarcore.command.CommandArgs;
|
||||
import emu.lunarcore.command.CommandHandler;
|
||||
import emu.lunarcore.game.account.AccountHelper;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.util.Utils;
|
||||
|
||||
@Command(label = "account", permission = "admin.account", desc = "/account {create | delete} [username] (reserved player uid). Creates or deletes an account.")
|
||||
public class AccountCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, CommandArgs args) {
|
||||
public void execute(CommandArgs args) {
|
||||
if (args.size() < 2) {
|
||||
this.sendMessage(sender, "Invalid amount of args");
|
||||
args.sendMessage("Invalid amount of args");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -30,16 +29,16 @@ public class AccountCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
if (AccountHelper.createAccount(username, null, reservedUid) != null) {
|
||||
this.sendMessage(sender, "Account created");
|
||||
args.sendMessage("Account created");
|
||||
} else {
|
||||
this.sendMessage(sender, "Account already exists");
|
||||
args.sendMessage("Account already exists");
|
||||
}
|
||||
}
|
||||
case "delete" -> {
|
||||
if (AccountHelper.deleteAccount(username)) {
|
||||
this.sendMessage(sender, "Account deleted");
|
||||
args.sendMessage("Account deleted");
|
||||
} else {
|
||||
this.sendMessage(sender, "Account doesnt exist");
|
||||
args.sendMessage("Account doesnt exist");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,42 +1,59 @@
|
||||
package emu.lunarcore.command.commands;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import emu.lunarcore.command.Command;
|
||||
import emu.lunarcore.command.CommandArgs;
|
||||
import emu.lunarcore.command.CommandHandler;
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.server.packet.send.PacketPlayerSyncScNotify;
|
||||
|
||||
@Command(label = "avatar", aliases = {"a"}, permission = "player.avatar", desc = "/avatar lv(level) p(ascension) r(eidolon) s(skill levels). Sets the current avatar's properties")
|
||||
@Command(label = "avatar", aliases = {"a"}, requireTarget = true, permission = "player.avatar", desc = "/avatar {cur | all | lineup} lv(level) p(ascension) r(eidolon) s(skill levels). Sets the current avatar's properties")
|
||||
public class AvatarCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, CommandArgs args) {
|
||||
// Check target
|
||||
if (args.getTarget() == null) {
|
||||
this.sendMessage(sender, "Error: Targeted player not found or offline");
|
||||
return;
|
||||
public void execute(CommandArgs args) {
|
||||
// Temp avatar list
|
||||
List<GameAvatar> changeList = new ArrayList<>();
|
||||
|
||||
// Handle optional arguments
|
||||
switch (args.get(0).toLowerCase()) {
|
||||
case "all":
|
||||
args.getTarget().getAvatars().forEach(changeList::add);
|
||||
break;
|
||||
case "lineup":
|
||||
args.getTarget().getCurrentLineup().forEachAvatar(changeList::add);
|
||||
break;
|
||||
case "cur":
|
||||
default:
|
||||
changeList.add(args.getTarget().getCurrentLeaderAvatar());
|
||||
break;
|
||||
}
|
||||
|
||||
// Get current leader avatar
|
||||
GameAvatar avatar = args.getTarget().getCurrentLeaderAvatar();
|
||||
if (avatar == null) {
|
||||
// No leader!
|
||||
return;
|
||||
}
|
||||
|
||||
// Change properties
|
||||
if (args.setProperties(avatar)) {
|
||||
// Save avatar
|
||||
avatar.save();
|
||||
// Try to set properties of avatars
|
||||
Iterator<GameAvatar> it = changeList.iterator();
|
||||
while (it.hasNext()) {
|
||||
GameAvatar avatar = it.next();
|
||||
|
||||
if (args.setProperties(avatar)) {
|
||||
// Save avatar
|
||||
avatar.save();
|
||||
} else {
|
||||
// Remove from list if nothing was changed
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (changeList.size() > 0) {
|
||||
// Send packet
|
||||
args.getTarget().sendPacket(new PacketPlayerSyncScNotify(avatar));
|
||||
|
||||
args.getTarget().sendPacket(new PacketPlayerSyncScNotify(changeList.toArray(GameAvatar[]::new)));
|
||||
// Send message
|
||||
sender.sendMessage("Set avatar properties successfully");
|
||||
args.sendMessage("Set avatar(s) properties successfully");
|
||||
} else {
|
||||
sender.sendMessage("No avatar properties to change");
|
||||
args.sendMessage("No avatar properties to change");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,33 +8,28 @@ import emu.lunarcore.command.CommandArgs;
|
||||
import emu.lunarcore.command.CommandHandler;
|
||||
import emu.lunarcore.game.enums.ItemMainType;
|
||||
import emu.lunarcore.game.inventory.GameItem;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
|
||||
@Command(label = "clear", permission = "player.clear", desc = "/clear {relics | lightcones | materials | items}. Removes filtered items from the player inventory.")
|
||||
@Command(label = "clear", permission = "player.clear", requireTarget = true, desc = "/clear {relics | lightcones | materials | items} lv(filter level). Removes filter items from the targeted player's inventory.")
|
||||
public class ClearCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, CommandArgs args) {
|
||||
// Check target
|
||||
if (args.getTarget() == null) {
|
||||
this.sendMessage(sender, "Error: Targeted player not found or offline");
|
||||
return;
|
||||
}
|
||||
|
||||
public void execute(CommandArgs args) {
|
||||
List<GameItem> toRemove = new LinkedList<>();
|
||||
String type = args.get(0).toLowerCase();
|
||||
|
||||
int filterLevel = Math.max(args.getLevel(), 1);
|
||||
|
||||
switch (type) {
|
||||
case "relics", "r" -> {
|
||||
for (GameItem item : args.getTarget().getInventory().getItems().values()) {
|
||||
if (item.getItemMainType() == ItemMainType.Relic && item.getLevel() <= 1 && item.getExp() == 0 && !item.isLocked() && !item.isEquipped()) {
|
||||
if (item.getItemMainType() == ItemMainType.Relic && item.getLevel() <= filterLevel && !item.isLocked() && !item.isEquipped()) {
|
||||
toRemove.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
case "equipment", "lightcones", "lc" -> {
|
||||
for (GameItem item : args.getTarget().getInventory().getItems().values()) {
|
||||
if (item.getItemMainType() == ItemMainType.Equipment && item.getLevel() <= 1 && item.getExp() == 0 && !item.isLocked() && !item.isEquipped()) {
|
||||
if (item.getItemMainType() == ItemMainType.Equipment && item.getLevel() <= filterLevel && !item.isLocked() && !item.isEquipped()) {
|
||||
toRemove.add(item);
|
||||
}
|
||||
}
|
||||
@@ -56,7 +51,7 @@ public class ClearCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
args.getTarget().getInventory().removeItems(toRemove);
|
||||
this.sendMessage(sender, "Removed " + toRemove.size() + " items");
|
||||
args.sendMessage("Removed " + toRemove.size() + " items");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,17 +8,11 @@ import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.game.player.PlayerGender;
|
||||
import emu.lunarcore.server.packet.send.PacketGetHeroBasicTypeInfoScRsp;
|
||||
|
||||
@Command(label = "gender", permission = "player.gender", desc = "/gender {male | female}. Sets the player gender.")
|
||||
@Command(label = "gender", permission = "player.gender", requireTarget = true, desc = "/gender {male | female}. Sets the player gender.")
|
||||
public class GenderCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, CommandArgs args) {
|
||||
// Check target
|
||||
if (args.getTarget() == null) {
|
||||
this.sendMessage(sender, "Error: Targeted player not found or offline");
|
||||
return;
|
||||
}
|
||||
|
||||
public void execute(CommandArgs args) {
|
||||
// Set world level
|
||||
Player target = args.getTarget();
|
||||
PlayerGender playerGender = null;
|
||||
@@ -48,9 +42,9 @@ public class GenderCommand implements CommandHandler {
|
||||
|
||||
// Send packet and response message
|
||||
target.sendPacket(new PacketGetHeroBasicTypeInfoScRsp(target));
|
||||
this.sendMessage(sender, "Gender for " + target.getName() + " set successfully");
|
||||
args.sendMessage("Gender for " + target.getName() + " set successfully");
|
||||
} else {
|
||||
this.sendMessage(sender, "Error: Invalid input");
|
||||
args.sendMessage("Error: Invalid input");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,22 +15,22 @@ import emu.lunarcore.game.enums.ItemSubType;
|
||||
import emu.lunarcore.game.inventory.GameItem;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
|
||||
@Command(label = "giveall", aliases = {"ga"}, permission = "player.give", desc = "/giveall {materials | avatars | lightcones | relics}. Gives the targeted player items.")
|
||||
@Command(
|
||||
label = "giveall",
|
||||
aliases = {"ga"},
|
||||
permission = "player.give",
|
||||
requireTarget = true,
|
||||
desc = "/giveall {materials | avatars | lightcones | relics} lv(level). Gives the targeted player items."
|
||||
)
|
||||
public class GiveAllCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, CommandArgs args) {
|
||||
// Check target
|
||||
if (args.getTarget() == null) {
|
||||
this.sendMessage(sender, "Error: Targeted player not found or offline");
|
||||
return;
|
||||
}
|
||||
|
||||
public void execute(CommandArgs args) {
|
||||
Player target = args.getTarget();
|
||||
String type = args.get(0).toLowerCase();
|
||||
|
||||
switch (type) {
|
||||
default -> this.sendMessage(sender, "Error: Invalid type");
|
||||
default -> args.sendMessage("Error: Invalid type");
|
||||
case "m", "materials", "mats" -> {
|
||||
List<GameItem> items = new ArrayList<>();
|
||||
|
||||
@@ -49,9 +49,16 @@ public class GiveAllCommand implements CommandHandler {
|
||||
target.getInventory().addItems(items, true);
|
||||
|
||||
// Send message
|
||||
this.sendMessage(sender, "Giving " + target.getName() + " " + items.size() + " items");
|
||||
args.sendMessage("Giving " + target.getName() + " " + items.size() + " items");
|
||||
}
|
||||
case "lc", "lightcones" -> {
|
||||
// Make sure we dont go over the inventory limit
|
||||
var tab = args.getTarget().getInventory().getTabByItemType(ItemMainType.Equipment);
|
||||
if (tab.getSize() >= tab.getMaxCapacity()) {
|
||||
args.sendMessage(target.getName() + " has too many of this item type");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get lightcones
|
||||
List<GameItem> items = GameData.getItemExcelMap().values()
|
||||
.stream()
|
||||
@@ -67,9 +74,16 @@ public class GiveAllCommand implements CommandHandler {
|
||||
target.getInventory().addItems(items, true);
|
||||
|
||||
// Send message
|
||||
this.sendMessage(sender, "Giving " + target.getName() + " " + items.size() + " light cones");
|
||||
args.sendMessage("Giving " + target.getName() + " " + items.size() + " light cones");
|
||||
}
|
||||
case "r", "relics" -> {
|
||||
// Make sure we dont go over the inventory limit
|
||||
var tab = args.getTarget().getInventory().getTabByItemType(ItemMainType.Relic);
|
||||
if (tab.getSize() >= tab.getMaxCapacity()) {
|
||||
args.sendMessage(target.getName() + " has too many of this item type");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get relics
|
||||
List<GameItem> items = GameData.getItemExcelMap().values()
|
||||
.stream()
|
||||
@@ -80,12 +94,12 @@ public class GiveAllCommand implements CommandHandler {
|
||||
return item;
|
||||
})
|
||||
.toList();
|
||||
|
||||
|
||||
// Add to target's inventory
|
||||
target.getInventory().addItems(items, true);
|
||||
|
||||
// Send message
|
||||
this.sendMessage(sender, "Giving " + target.getName() + " " + items.size() + " relics");
|
||||
args.sendMessage("Giving " + target.getName() + " " + items.size() + " relics");
|
||||
}
|
||||
case "a", "characters", "avatars" -> {
|
||||
// All avatars and their eidolons
|
||||
@@ -111,7 +125,31 @@ public class GiveAllCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
// Send message
|
||||
this.sendMessage(sender, "Giving " + target.getName() + " all avatars");
|
||||
args.sendMessage("Giving " + target.getName() + " all avatars");
|
||||
}
|
||||
case "ic", "icons" -> {
|
||||
// Get UnlockedHeads
|
||||
for (var iconhead : GameData.getPlayerIconExcelMap().values()) {
|
||||
// This function will handle any duplicate head icons
|
||||
target.addHeadIcon(iconhead.getId());
|
||||
}
|
||||
|
||||
// Send message
|
||||
args.sendMessage("Added all icons to " + target.getName());
|
||||
}
|
||||
case "consumables", "food" -> {
|
||||
// Get consumables
|
||||
List<GameItem> items = GameData.getItemExcelMap().values()
|
||||
.stream()
|
||||
.filter(excel -> excel.getItemSubType() == ItemSubType.Food)
|
||||
.map(excel -> new GameItem(excel, 1000))
|
||||
.toList();
|
||||
|
||||
// Add to target's inventory
|
||||
target.getInventory().addItems(items, true);
|
||||
|
||||
// Send message
|
||||
args.sendMessage("Added all consumables to " + target.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,72 +11,63 @@ import emu.lunarcore.data.excel.ItemExcel;
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.enums.ItemMainType;
|
||||
import emu.lunarcore.game.inventory.GameItem;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.util.Utils;
|
||||
|
||||
@Command(label = "give", aliases = {"g"}, permission = "player.give", desc = "/give [item id] x[amount]. Gives the targetted player an item.")
|
||||
@Command(
|
||||
label = "give",
|
||||
aliases = {"g", "item"},
|
||||
permission = "player.give",
|
||||
requireTarget = true,
|
||||
desc = "/give [item id] x(amount) lv(level) r(rank) p(promotion). Gives the targeted player an item."
|
||||
)
|
||||
public class GiveCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, CommandArgs args) {
|
||||
// Check target
|
||||
if (args.getTarget() == null) {
|
||||
this.sendMessage(sender, "Error: Targeted player not found or offline");
|
||||
return;
|
||||
}
|
||||
|
||||
int itemId = Utils.parseSafeInt(args.get(0));
|
||||
int amount = Math.max(args.getAmount(), 1);
|
||||
|
||||
ItemExcel itemData = GameData.getItemExcelMap().get(itemId);
|
||||
|
||||
if (itemData == null) {
|
||||
this.sendMessage(sender, "Error: Item data not found");
|
||||
return;
|
||||
}
|
||||
|
||||
public void execute(CommandArgs args) {
|
||||
// Setup items
|
||||
List<GameItem> items = new LinkedList<>();
|
||||
|
||||
if (itemData.getItemMainType() == ItemMainType.AvatarCard) {
|
||||
// Add avatar
|
||||
GameAvatar avatar = new GameAvatar(itemData.getId());
|
||||
// Get amount to give
|
||||
int amount = Math.max(args.getAmount(), 1);
|
||||
|
||||
// Parse items
|
||||
for (String arg : args.getList()) {
|
||||
// Parse item id
|
||||
int itemId = Utils.parseSafeInt(arg);
|
||||
|
||||
if (args.getTarget().addAvatar(avatar)) {
|
||||
// Change avatar properties
|
||||
ItemExcel itemData = GameData.getItemExcelMap().get(itemId);
|
||||
if (itemData == null) {
|
||||
args.sendMessage("Item \"" + arg + "\" does not exist!");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add item
|
||||
if (itemData.getItemMainType() == ItemMainType.AvatarCard) {
|
||||
// Add avatar to target
|
||||
GameAvatar avatar = new GameAvatar(itemData.getId());
|
||||
args.setProperties(avatar);
|
||||
}
|
||||
} else if (itemData.isEquippable()) {
|
||||
for (int i = 0; i < amount; i++) {
|
||||
GameItem item = new GameItem(itemData);
|
||||
args.getTarget().addAvatar(avatar);
|
||||
} else if (itemData.isEquippable()) {
|
||||
// Make sure we dont go over the inventory limit
|
||||
var tab = args.getTarget().getInventory().getTabByItemType(itemData.getItemMainType());
|
||||
amount = Math.min(amount, tab.getAvailableCapacity());
|
||||
|
||||
if (item.getExcel().isEquipment()) {
|
||||
// Try to set level
|
||||
if (args.getLevel() > 0) {
|
||||
item.setLevel(Math.min(args.getLevel(), 80));
|
||||
item.setPromotion(Utils.getMinPromotionForLevel(item.getLevel()));
|
||||
}
|
||||
// Add items
|
||||
for (int i = 0; i < amount; i++) {
|
||||
GameItem item = new GameItem(itemData);
|
||||
args.setProperties(item);
|
||||
|
||||
// Try to set promotion
|
||||
if (args.getPromotion() >= 0) {
|
||||
item.setPromotion(Math.min(args.getPromotion(), item.getExcel().getEquipmentExcel().getMaxPromotion()));
|
||||
}
|
||||
|
||||
// Try to set rank (superimposition)
|
||||
if (args.getRank() >= 0) {
|
||||
item.setRank(Math.min(args.getRank(), item.getExcel().getEquipmentExcel().getMaxRank()));
|
||||
}
|
||||
items.add(item);
|
||||
}
|
||||
|
||||
items.add(item);
|
||||
} else {
|
||||
items.add(new GameItem(itemData, amount));
|
||||
}
|
||||
} else {
|
||||
items.add(new GameItem(itemData, amount));
|
||||
|
||||
// Send message
|
||||
args.sendMessage("Giving " + args.getTarget().getName() + " " + amount + " of " + itemId);
|
||||
}
|
||||
|
||||
// Add and send message to player
|
||||
// Add to player inventory
|
||||
args.getTarget().getInventory().addItems(items, true);
|
||||
args.getTarget().sendMessage("Giving " + args.getTarget().getName() + " " + amount + " of " + itemId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package emu.lunarcore.command.commands;
|
||||
|
||||
import emu.lunarcore.command.Command;
|
||||
import emu.lunarcore.command.CommandArgs;
|
||||
import emu.lunarcore.command.CommandHandler;
|
||||
import emu.lunarcore.game.player.lineup.PlayerLineup;
|
||||
|
||||
@Command(label = "heal", permission = "player.heal", requireTarget = true, desc = "/heal. Heals your avatars.")
|
||||
public class HealCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(CommandArgs args) {
|
||||
PlayerLineup lineup = args.getTarget().getCurrentLineup();
|
||||
lineup.forEachAvatar(avatar -> {
|
||||
avatar.setCurrentHp(lineup, 10000);
|
||||
avatar.save();
|
||||
});
|
||||
lineup.refreshLineup();
|
||||
|
||||
args.sendMessage("Healed all avatars for " + args.getTarget().getName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,21 +4,20 @@ import emu.lunarcore.LunarCore;
|
||||
import emu.lunarcore.command.Command;
|
||||
import emu.lunarcore.command.CommandArgs;
|
||||
import emu.lunarcore.command.CommandHandler;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
|
||||
@Command(label = "help", permission = "player.help", desc = "/help. Displays a list of available commands.")
|
||||
public class HelpCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, CommandArgs args) {
|
||||
this.sendMessage(sender, "Displaying list of commands:");
|
||||
public void execute(CommandArgs args) {
|
||||
args.sendMessage("Displaying list of commands:");
|
||||
|
||||
var labels = LunarCore.getCommandManager().getLabels().keySet().stream().sorted().toList();
|
||||
for (var label : labels) {
|
||||
Command command = LunarCore.getCommandManager().getLabels().get(label).getClass().getAnnotation(Command.class);
|
||||
if (command == null) continue;
|
||||
|
||||
this.sendMessage(sender, command.desc());
|
||||
args.sendMessage(command.desc());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,27 +3,21 @@ package emu.lunarcore.command.commands;
|
||||
import emu.lunarcore.command.Command;
|
||||
import emu.lunarcore.command.CommandArgs;
|
||||
import emu.lunarcore.command.CommandHandler;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
|
||||
@Command(
|
||||
label = "kick",
|
||||
desc = "/kick @[player id]. Kicks a player from the server.",
|
||||
requireTarget = true,
|
||||
permission = "player.kick"
|
||||
)
|
||||
public final class KickCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, CommandArgs args) {
|
||||
// Check target
|
||||
if (args.getTarget() == null) {
|
||||
this.sendMessage(sender, "Error: Targeted player not found or offline");
|
||||
return;
|
||||
}
|
||||
|
||||
public void execute(CommandArgs args) {
|
||||
// Kick player
|
||||
args.getTarget().getSession().close();
|
||||
|
||||
// Send message
|
||||
this.sendMessage(sender, "Player kicked successfully");
|
||||
args.sendMessage("Player kicked successfully");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package emu.lunarcore.command.commands;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import emu.lunarcore.GameConstants;
|
||||
import emu.lunarcore.command.Command;
|
||||
import emu.lunarcore.command.CommandArgs;
|
||||
import emu.lunarcore.command.CommandHandler;
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.game.player.lineup.PlayerLineup;
|
||||
import emu.lunarcore.util.Utils;
|
||||
|
||||
@Command(label = "lineup", permission = "player.lineup", requireTarget = true, desc = "/lineup [avatar ids]. USE AT YOUR OWN RISK. Sets your current lineup with the specified avatar ids.")
|
||||
public class LineupCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(CommandArgs args) {
|
||||
// Get target player
|
||||
Player target = args.getTarget();
|
||||
|
||||
// Do not set lineup while the target player is in a battle
|
||||
if (target.isInBattle()) {
|
||||
args.sendMessage("Error: The targeted player is in a battle");
|
||||
return;
|
||||
}
|
||||
|
||||
// Temp avatar list
|
||||
List<Integer> avatars = new ArrayList<>();
|
||||
|
||||
// Validate avatars in temp list
|
||||
for (String arg : args.getList()) {
|
||||
// Make sure the avatar actually exist
|
||||
GameAvatar avatar = target.getAvatarById(Utils.parseSafeInt(arg));
|
||||
if (avatar == null) continue;
|
||||
|
||||
avatars.add(avatar.getAvatarId());
|
||||
|
||||
// Soft cap check
|
||||
if (avatars.size() >= GameConstants.MAX_AVATARS_IN_TEAM) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Replace cleanly
|
||||
if (avatars.size() > 0) {
|
||||
// Only replace lineup if we have avatars to replace with
|
||||
// The client wont like it if we have a lineup with 0 avatars.
|
||||
PlayerLineup lineup = target.getCurrentLineup();
|
||||
lineup.getAvatars().clear();
|
||||
lineup.getAvatars().addAll(avatars);
|
||||
lineup.save();
|
||||
|
||||
// Send client packets to sync lineup
|
||||
lineup.refreshLineup();
|
||||
target.getScene().syncLineup();
|
||||
|
||||
args.sendMessage("Set the lineup of " + target.getName() + " successfully");
|
||||
} else {
|
||||
args.sendMessage("No avatars could be added");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,41 +6,27 @@ import java.util.List;
|
||||
import emu.lunarcore.command.Command;
|
||||
import emu.lunarcore.command.CommandArgs;
|
||||
import emu.lunarcore.command.CommandHandler;
|
||||
import emu.lunarcore.data.GameData;
|
||||
import emu.lunarcore.data.excel.ItemExcel;
|
||||
import emu.lunarcore.game.inventory.GameItem;
|
||||
import emu.lunarcore.game.mail.Mail;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
|
||||
@Command(label = "mail", aliases = {"m"}, permission = "player.mail", desc = "/mail [content]. Sends the targeted player a system mail.")
|
||||
@Command(label = "mail", aliases = {"m"}, permission = "player.mail", requireTarget = true, desc = "/mail [content]. Sends the targeted player a system mail.")
|
||||
public class MailCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, CommandArgs args) {
|
||||
// Check target
|
||||
if (args.getTarget() == null) {
|
||||
this.sendMessage(sender, "Error: Targeted player not found or offline");
|
||||
return;
|
||||
}
|
||||
|
||||
public void execute(CommandArgs args) {
|
||||
// Get attachments
|
||||
List<GameItem> attachments = new ArrayList<>();
|
||||
|
||||
var it = args.getList().iterator();
|
||||
while (it.hasNext()) {
|
||||
try {
|
||||
String str = it.next();
|
||||
|
||||
if (args.getMap() != null) {
|
||||
for (var entry : args.getMap().int2IntEntrySet()) {
|
||||
if (entry.getIntValue() <= 0) continue;
|
||||
|
||||
if (str.contains(":")) {
|
||||
String[] split = str.split(":");
|
||||
|
||||
int itemId = Integer.parseInt(split[0]);
|
||||
int count = Integer.parseInt(split[1]);
|
||||
|
||||
attachments.add(new GameItem(itemId, count));
|
||||
|
||||
it.remove();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
ItemExcel itemExcel = GameData.getItemExcelMap().get(entry.getIntKey());
|
||||
if (itemExcel == null) continue;
|
||||
|
||||
attachments.add(new GameItem(itemExcel, entry.getIntValue()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +41,7 @@ public class MailCommand implements CommandHandler {
|
||||
// Send to target
|
||||
args.getTarget().getMailbox().sendMail(mail);
|
||||
|
||||
this.sendMessage(sender, "Sending mail to " + args.getTarget().getName());
|
||||
args.sendMessage("Sending mail to " + args.getTarget().getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,19 +3,12 @@ package emu.lunarcore.command.commands;
|
||||
import emu.lunarcore.command.Command;
|
||||
import emu.lunarcore.command.CommandArgs;
|
||||
import emu.lunarcore.command.CommandHandler;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
|
||||
@Command(label = "permission", aliases = {"perm"}, permission = "admin.permission", desc = "/permission {add | remove | clear} [permission]. Gives/removes a permission from the targeted player.")
|
||||
@Command(label = "permission", aliases = {"perm"}, permission = "admin.permission", requireTarget = true, desc = "/permission {add | remove | clear} [permission]. Gives/removes a permission from the targeted player.")
|
||||
public class PermissionCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, CommandArgs args) {
|
||||
// Check target
|
||||
if (args.getTarget() == null) {
|
||||
this.sendMessage(sender, "Error: Targeted player not found or offline");
|
||||
return;
|
||||
}
|
||||
|
||||
public void execute(CommandArgs args) {
|
||||
String type = args.get(0).toLowerCase();
|
||||
String permission = args.get(1).toLowerCase();
|
||||
|
||||
@@ -26,7 +19,7 @@ public class PermissionCommand implements CommandHandler {
|
||||
args.getTarget().getAccount().addPermission(permission);
|
||||
}
|
||||
// Send message
|
||||
this.sendMessage(sender, "Added permission for " + args.getTarget().getName());
|
||||
args.sendMessage("Added permission for " + args.getTarget().getName());
|
||||
}
|
||||
case "remove" -> {
|
||||
// Remove permission
|
||||
@@ -34,16 +27,16 @@ public class PermissionCommand implements CommandHandler {
|
||||
args.getTarget().getAccount().removePermission(permission);
|
||||
}
|
||||
// Send message
|
||||
this.sendMessage(sender, "Removed permission for " + args.getTarget().getName());
|
||||
args.sendMessage("Removed permission for " + args.getTarget().getName());
|
||||
}
|
||||
case "clear" -> {
|
||||
// Clear permissions
|
||||
args.getTarget().getAccount().clearPermission();
|
||||
// Send message
|
||||
this.sendMessage(sender, "Cleared permissions for " + args.getTarget().getName());
|
||||
args.sendMessage("Cleared permissions for " + args.getTarget().getName());
|
||||
}
|
||||
default -> {
|
||||
this.sendMessage(sender, "Error: Invalid arguments");
|
||||
args.sendMessage("Error: Invalid arguments");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package emu.lunarcore.command.commands;
|
||||
|
||||
import emu.lunarcore.GameConstants;
|
||||
import emu.lunarcore.command.Command;
|
||||
import emu.lunarcore.command.CommandArgs;
|
||||
import emu.lunarcore.command.CommandHandler;
|
||||
|
||||
@Command(label = "refill", aliases = {"rf"}, permission = "player.refill", requireTarget = true, desc = "/refill - refill your skill points in open world.")
|
||||
public class RefillMPCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(CommandArgs args) {
|
||||
args.getTarget().getCurrentLineup().addMp(GameConstants.MAX_MP);
|
||||
args.sendMessage("Successfully refilled skill points for " + args.getTarget().getName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package emu.lunarcore.command.commands;
|
||||
|
||||
import emu.lunarcore.command.Command;
|
||||
import emu.lunarcore.game.player.lineup.PlayerLineup;
|
||||
import emu.lunarcore.command.CommandArgs;
|
||||
import emu.lunarcore.command.CommandHandler;
|
||||
|
||||
@Command(label = "energy", permission = "player.energy", requireTarget = true, desc = "/energy. Refills all characters energy in current lineup.")
|
||||
public class RefillSPCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(CommandArgs args) {
|
||||
PlayerLineup lineup = args.getTarget().getCurrentLineup();
|
||||
lineup.forEachAvatar(avatar -> {
|
||||
avatar.setCurrentSp(lineup, 10000);
|
||||
avatar.save();
|
||||
});
|
||||
lineup.refreshLineup();
|
||||
|
||||
args.sendMessage("Refilled SP for " + args.getTarget().getName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,15 +4,14 @@ import emu.lunarcore.LunarCore;
|
||||
import emu.lunarcore.command.Command;
|
||||
import emu.lunarcore.command.CommandArgs;
|
||||
import emu.lunarcore.command.CommandHandler;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
|
||||
@Command(label = "reload", permission = "admin.reload", desc = "/reload. Reloads the server config.")
|
||||
public class ReloadCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, CommandArgs args) {
|
||||
public void execute(CommandArgs args) {
|
||||
LunarCore.loadConfig();
|
||||
this.sendMessage(sender, "Reloaded the server config");
|
||||
args.sendMessage("Reloaded the server config");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,20 +7,13 @@ import emu.lunarcore.data.GameData;
|
||||
import emu.lunarcore.data.config.AnchorInfo;
|
||||
import emu.lunarcore.data.config.FloorInfo;
|
||||
import emu.lunarcore.data.excel.MazePlaneExcel;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.util.Utils;
|
||||
|
||||
@Command(label = "scene", aliases = {"sc"}, permission = "player.scene", desc = "/scene [scene id] [floor id]. Teleports the player to the specified scene.")
|
||||
@Command(label = "scene", aliases = {"sc"}, permission = "player.scene", requireTarget = true, desc = "/scene [scene id] [floor id]. Teleports the player to the specified scene.")
|
||||
public class SceneCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, CommandArgs args) {
|
||||
// Check target
|
||||
if (args.getTarget() == null) {
|
||||
this.sendMessage(sender, "Error: Targeted player not found or offline");
|
||||
return;
|
||||
}
|
||||
|
||||
public void execute(CommandArgs args) {
|
||||
// Get arguments
|
||||
int planeId = Utils.parseSafeInt(args.get(0));
|
||||
int floorId = Utils.parseSafeInt(args.get(1));
|
||||
@@ -28,7 +21,7 @@ public class SceneCommand implements CommandHandler {
|
||||
// Get maze plane
|
||||
MazePlaneExcel excel = GameData.getMazePlaneExcelMap().get(planeId);
|
||||
if (excel == null) {
|
||||
this.sendMessage(sender, "Error: Maze plane not found");
|
||||
args.sendMessage("Error: Maze plane not found");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -39,7 +32,7 @@ public class SceneCommand implements CommandHandler {
|
||||
// Get floor info
|
||||
FloorInfo floor = GameData.getFloorInfo(planeId, floorId);
|
||||
if (floor == null) {
|
||||
this.sendMessage(sender, "Error: Floor info not found");
|
||||
args.sendMessage("Error: Floor info not found");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -48,7 +41,7 @@ public class SceneCommand implements CommandHandler {
|
||||
|
||||
AnchorInfo anchor = floor.getAnchorInfo(startGroup, anchorId);
|
||||
if (anchor == null) {
|
||||
this.sendMessage(sender, "Error: Floor info not found");
|
||||
args.sendMessage("Error: Floor info not found");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -57,7 +50,7 @@ public class SceneCommand implements CommandHandler {
|
||||
|
||||
// Send packet
|
||||
if (success) {
|
||||
this.sendMessage(sender, "Teleported player to " + planeId);
|
||||
args.sendMessage("Teleported player to " + planeId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package emu.lunarcore.command.commands;
|
||||
|
||||
import emu.lunarcore.util.Utils;
|
||||
import emu.lunarcore.command.Command;
|
||||
import emu.lunarcore.command.CommandArgs;
|
||||
import emu.lunarcore.command.CommandHandler;
|
||||
|
||||
@Command(label = "setlevel", aliases = {"level"}, permission = "player.setlevel", requireTarget = true, desc = "/setlevel [level] - Sets the targeted player's trailblazer level.")
|
||||
public class SetLevelCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(CommandArgs args) {
|
||||
int targetLevel = Utils.parseSafeInt(args.get(0));
|
||||
args.getTarget().setLevel(targetLevel);
|
||||
|
||||
args.sendMessage("Set level to " + targetLevel);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package emu.lunarcore.command.commands;
|
||||
|
||||
import emu.lunarcore.LunarCore;
|
||||
import emu.lunarcore.command.Command;
|
||||
import emu.lunarcore.command.CommandArgs;
|
||||
import emu.lunarcore.command.CommandHandler;
|
||||
@@ -16,21 +17,15 @@ import emu.lunarcore.game.scene.entity.EntityProp;
|
||||
import emu.lunarcore.util.Position;
|
||||
import emu.lunarcore.util.Utils;
|
||||
|
||||
@Command(label = "spawn", permission = "player.spawn", desc = "/spawn [monster/prop id] x[amount] s[stage id]. Spawns a monster or prop near the targeted player.")
|
||||
@Command(label = "spawn", permission = "player.spawn", requireTarget = true, desc = "/spawn [monster/prop id] [stage id] x[amount] lv[level] r[radius]. Spawns a monster or prop near the targeted player.")
|
||||
public class SpawnCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, CommandArgs args) {
|
||||
// Check target
|
||||
if (args.getTarget() == null) {
|
||||
this.sendMessage(sender, "Error: Targeted player not found or offline");
|
||||
return;
|
||||
}
|
||||
|
||||
public void execute(CommandArgs args) {
|
||||
Player target = args.getTarget();
|
||||
|
||||
if (target.getScene() == null) {
|
||||
this.sendMessage(sender, "Error: Target is not in scene");
|
||||
args.sendMessage("Error: Target is not in scene");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -40,6 +35,12 @@ public class SpawnCommand implements CommandHandler {
|
||||
int amount = Math.max(args.getAmount(), 1);
|
||||
int radius = Math.max(args.getRank(), 5) * 1000;
|
||||
|
||||
// Enforce scene max entity limit
|
||||
if (target.getScene().getEntities().size() + amount >= LunarCore.getConfig().getServerOptions().getSceneMaxEntites()) {
|
||||
args.sendMessage("Error: Max entities in scene reached");
|
||||
return;
|
||||
}
|
||||
|
||||
// Spawn monster
|
||||
NpcMonsterExcel monsterExcel = GameData.getNpcMonsterExcelMap().get(id);
|
||||
if (monsterExcel != null) {
|
||||
@@ -62,7 +63,7 @@ public class SpawnCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
if (monsterInfo == null || groupInfo == null) {
|
||||
this.sendMessage(sender, "Error: No existing monster config found in this scene");
|
||||
args.sendMessage("Error: No existing monster config found in this scene");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -74,11 +75,15 @@ public class SpawnCommand implements CommandHandler {
|
||||
monster.setEventId(monsterInfo.getEventID());
|
||||
monster.setOverrideStageId(stage);
|
||||
|
||||
if (args.getLevel() > 0) {
|
||||
monster.setOverrideLevel(Math.min(args.getLevel(), 100));
|
||||
}
|
||||
|
||||
target.getScene().addEntity(monster, true);
|
||||
}
|
||||
|
||||
// Send message when done
|
||||
this.sendMessage(sender, "Spawning " + amount + " monsters");
|
||||
args.sendMessage("Spawning " + amount + " monsters");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -103,7 +108,7 @@ public class SpawnCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
if (propInfo == null || groupInfo == null) {
|
||||
this.sendMessage(sender, "Error: No existing prop config found in this scene");
|
||||
args.sendMessage("Error: No existing prop config found in this scene");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -119,11 +124,11 @@ public class SpawnCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
// Send message when done
|
||||
this.sendMessage(sender, "Spawning " + amount + " props");
|
||||
args.sendMessage("Spawning " + amount + " props");
|
||||
return;
|
||||
}
|
||||
|
||||
this.sendMessage(sender, "Error: Invalid id");
|
||||
args.sendMessage("Error: Invalid id");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,16 +10,16 @@ import emu.lunarcore.game.player.Player;
|
||||
public class UnstuckCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, CommandArgs args) {
|
||||
public void execute(CommandArgs args) {
|
||||
// Make sure were on the game server
|
||||
if (LunarCore.getGameDatabase() == null) {
|
||||
this.sendMessage(sender, "Error: Game database not connected");
|
||||
args.sendMessage("Error: Game database not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO add some logic to handle unstucking the target if theyre online
|
||||
if (args.getTarget() != null) {
|
||||
this.sendMessage(sender, "Error: Targeted player is online");
|
||||
args.sendMessage("Error: Targeted player is online");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -32,10 +32,10 @@ public class UnstuckCommand implements CommandHandler {
|
||||
player.save();
|
||||
|
||||
// Done
|
||||
this.sendMessage(sender, "Player unstuck successfully");
|
||||
args.sendMessage("Player unstuck successfully");
|
||||
} else {
|
||||
// Done
|
||||
this.sendMessage(sender, "Error: Player not found in database");
|
||||
args.sendMessage("Error: Player not found in database");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,20 +3,13 @@ package emu.lunarcore.command.commands;
|
||||
import emu.lunarcore.command.Command;
|
||||
import emu.lunarcore.command.CommandArgs;
|
||||
import emu.lunarcore.command.CommandHandler;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.util.Utils;
|
||||
|
||||
@Command(label = "worldlevel", aliases = {"wl"}, permission = "player.worldlevel", desc = "/worldlevel [world level]. Sets the targeted player's equilibrium level.")
|
||||
@Command(label = "worldlevel", aliases = {"wl"}, permission = "player.worldlevel", requireTarget = true, desc = "/worldlevel [world level]. Sets the targeted player's equilibrium level.")
|
||||
public class WorldLevelCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, CommandArgs args) {
|
||||
// Check target
|
||||
if (args.getTarget() == null) {
|
||||
this.sendMessage(sender, "Error: Targeted player not found or offline");
|
||||
return;
|
||||
}
|
||||
|
||||
public void execute(CommandArgs args) {
|
||||
// Set world level
|
||||
int level = Utils.parseSafeInt(args.get(0));
|
||||
level = Math.min(Math.max(level, 0), 6);
|
||||
@@ -24,7 +17,7 @@ public class WorldLevelCommand implements CommandHandler {
|
||||
args.getTarget().setWorldLevel(level);
|
||||
|
||||
// Done
|
||||
this.sendMessage(sender, "Set world level to " + level);
|
||||
args.sendMessage("Set world level to " + level);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,13 +2,14 @@ package emu.lunarcore.data;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import emu.lunarcore.data.config.FloorInfo;
|
||||
import emu.lunarcore.data.excel.*;
|
||||
import emu.lunarcore.game.battle.MazeBuff;
|
||||
import emu.lunarcore.util.Utils;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
@@ -18,10 +19,12 @@ public class GameData {
|
||||
// Excels
|
||||
@Getter private static Int2ObjectMap<AvatarExcel> avatarExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<ItemExcel> itemExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<ItemUseExcel> itemUseExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<EquipmentExcel> equipExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<RelicExcel> relicExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<PropExcel> propExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<NpcExcel> npcExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<MonsterExcel> monsterExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<NpcMonsterExcel> npcMonsterExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<StageExcel> stageExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<MazePlaneExcel> mazePlaneExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@@ -29,9 +32,15 @@ public class GameData {
|
||||
@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<PlayerIconExcel> playerIconExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<ItemComposeExcel> itemComposeExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<ActivityPanelExcel> activityPanelExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter private static Int2ObjectMap<BackGroundMusicExcel> backGroundMusicExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<QuestExcel> questExcelMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<TextJoinExcel> textJoinExcelMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<ChatBubbleExcel> chatBubbleExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<PhoneThemeExcel> phoneThemeExcelMap = 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<>();
|
||||
@@ -44,6 +53,7 @@ public class GameData {
|
||||
@Getter private static Int2ObjectMap<RogueRoomExcel> rogueRoomExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<RogueMapExcel> rogueMapExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<RogueMonsterExcel> rogueMonsterExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
private static Int2ObjectMap<RogueBuffExcel> rogueBuffExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
private static Int2ObjectMap<AvatarPromotionExcel> avatarPromotionExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
private static Int2ObjectMap<AvatarSkillTreeExcel> avatarSkillTreeExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
@@ -57,9 +67,10 @@ public class GameData {
|
||||
private static Int2ObjectMap<ExpTypeExcel> expTypeExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
private static Int2ObjectMap<EquipmentExpTypeExcel> equipmentExpTypeExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
private static Int2ObjectMap<RelicExpTypeExcel> relicExpTypeExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
|
||||
private static Int2ObjectMap<RelicMainAffixExcel> relicMainAffixExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
private static Int2ObjectMap<RelicSubAffixExcel> relicSubAffixExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
private static Int2ObjectMap<RelicSetExcel> relicSetExcelMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
// Configs (Bin)
|
||||
@Getter private static Object2ObjectMap<String, FloorInfo> floorInfos = new Object2ObjectOpenHashMap<>();
|
||||
@@ -81,6 +92,77 @@ public class GameData {
|
||||
return map;
|
||||
}
|
||||
|
||||
public static List<Integer> getAllRelicIds() {
|
||||
List<Integer> allIds = new ArrayList<>();
|
||||
|
||||
for (Int2ObjectMap.Entry<RelicExcel> entry : relicExcelMap.int2ObjectEntrySet()) {
|
||||
RelicExcel relicExcel = entry.getValue();
|
||||
allIds.add(relicExcel.getId());
|
||||
}
|
||||
|
||||
return allIds;
|
||||
}
|
||||
|
||||
public static int getRelicSetFromId(int relicId) {
|
||||
RelicExcel relicExcel = GameData.getRelicExcelMap().get(relicId);
|
||||
|
||||
if (relicExcel == null) {
|
||||
return 0;
|
||||
}
|
||||
return relicExcel.getSetId();
|
||||
}
|
||||
|
||||
public static List<Integer> getAllMusicIds() {
|
||||
List<Integer> allIds = new ArrayList<>();
|
||||
|
||||
for (Int2ObjectMap.Entry<BackGroundMusicExcel> entry : backGroundMusicExcelMap.int2ObjectEntrySet()) {
|
||||
BackGroundMusicExcel backGroundMusicExcel = entry.getValue();
|
||||
allIds.add(backGroundMusicExcel.getId());
|
||||
}
|
||||
|
||||
return allIds;
|
||||
}
|
||||
|
||||
public static int TextJoinItemFromId(int id) {
|
||||
for (Int2ObjectMap.Entry<TextJoinExcel> entry : textJoinExcelMap.int2ObjectEntrySet()) {
|
||||
TextJoinExcel textJoinExcel = entry.getValue();
|
||||
if (textJoinExcel.getId() == id) {
|
||||
IntArrayList textJoinItemList = textJoinExcel.getTextJoinItemList();
|
||||
if (textJoinItemList.size() > 0) {
|
||||
return textJoinItemList.getInt(textJoinItemList.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return id * 10; // or return a default value if needed
|
||||
}
|
||||
|
||||
public static List<Integer> getAllQuestIds() {
|
||||
List<Integer> allIds = new ArrayList<>();
|
||||
|
||||
for (Int2ObjectMap.Entry<QuestExcel> entry : questExcelMap.int2ObjectEntrySet()) {
|
||||
QuestExcel questExcel = entry.getValue();
|
||||
allIds.add(questExcel.getId());
|
||||
}
|
||||
|
||||
return allIds;
|
||||
}
|
||||
|
||||
public static List<Integer> getAllMonsterIds() {
|
||||
List<Integer> allIds = new ArrayList<>();
|
||||
|
||||
for (Int2ObjectMap.Entry<MonsterExcel> entry : monsterExcelMap.int2ObjectEntrySet()) {
|
||||
MonsterExcel monsterExcel = entry.getValue();
|
||||
allIds.add(monsterExcel.getId());
|
||||
}
|
||||
|
||||
return allIds;
|
||||
}
|
||||
|
||||
public static int getMusicGroupId(int musicId) {
|
||||
var excel = backGroundMusicExcelMap.get(musicId);
|
||||
return excel != null ? excel.getGroupId() : 0;
|
||||
}
|
||||
|
||||
public static AvatarPromotionExcel getAvatarPromotionExcel(int id, int promotion) {
|
||||
return avatarPromotionExcelMap.get((id << 8) + promotion);
|
||||
}
|
||||
@@ -148,4 +230,8 @@ public class GameData {
|
||||
public static RogueMapExcel getRogueMapExcel(int rogueMapId, int siteId) {
|
||||
return rogueMapExcelMap.get((rogueMapId << 8) + siteId);
|
||||
}
|
||||
|
||||
public static RogueBuffExcel getRogueBuffExcel(int rogueBuffId, int level) {
|
||||
return rogueBuffExcelMap.get((rogueBuffId << 4) + level);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ public class GameDepot {
|
||||
|
||||
// Rogue
|
||||
@Getter private static Int2ObjectMap<int[]> rogueMapGen = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<RogueBuffExcel> rogueAeonBuffs = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static Int2ObjectMap<List<RogueBuffExcel>> rogueAeonEnhanceBuffs = new Int2ObjectOpenHashMap<>();
|
||||
@Getter private static List<RogueBuffExcel> rogueRandomBuffList = new ArrayList<>();
|
||||
@Getter private static List<RogueMiracleExcel> rogueRandomMiracleList = new ArrayList<>();
|
||||
@Getter private static List<RogueNPCExcel> rogueRandomNpcList = new ArrayList<>();
|
||||
|
||||
@@ -2,7 +2,6 @@ package emu.lunarcore.data.excel;
|
||||
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@@ -12,7 +11,7 @@ public class ActivityPanelExcel extends GameResource {
|
||||
private int Type;
|
||||
private int ActivityModuleID;
|
||||
private boolean IsResidentPanel;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return PanelID;
|
||||
|
||||
@@ -40,10 +40,10 @@ public class AvatarExcel extends GameResource {
|
||||
private transient IntSet skillTreeIds;
|
||||
private transient String nameKey;
|
||||
private transient int maxSp;
|
||||
|
||||
|
||||
@Setter private transient MazeSkill mazeAttack;
|
||||
@Setter private transient MazeSkill mazeSkill;
|
||||
|
||||
|
||||
private static Pattern namePattern = Pattern.compile("(?<=Avatar_)(.*?)(?=_Config)");
|
||||
|
||||
public AvatarExcel() {
|
||||
@@ -75,14 +75,14 @@ public class AvatarExcel extends GameResource {
|
||||
|
||||
// Cache max sp
|
||||
this.maxSp = (int) this.SPNeed * 100;
|
||||
|
||||
|
||||
// Get name key
|
||||
Matcher matcher = namePattern.matcher(this.JsonPath);
|
||||
|
||||
|
||||
if (matcher.find()) {
|
||||
this.nameKey = matcher.group(0);
|
||||
}
|
||||
|
||||
|
||||
// Clear variable to save memory
|
||||
this.JsonPath = null;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import emu.lunarcore.data.GameDepot;
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
import emu.lunarcore.data.ResourceType.LoadPriority;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@@ -28,7 +27,7 @@ public class AvatarExpItemExcel extends GameResource {
|
||||
if (excel == null) return;
|
||||
|
||||
excel.setAvatarExp(Exp);
|
||||
|
||||
|
||||
// Add to game depot
|
||||
if (Exp > 0) {
|
||||
GameDepot.getAvatarExpExcels().add(this);
|
||||
|
||||
@@ -41,7 +41,7 @@ public class AvatarSkillTreeExcel extends GameResource {
|
||||
if (this.isDefaultUnlock()) {
|
||||
excel.getDefaultSkillTrees().add(this);
|
||||
}
|
||||
|
||||
|
||||
// Add point id to avatar excel
|
||||
excel.getSkillTreeIds().add(this.getPointID());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package emu.lunarcore.data.excel;
|
||||
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = {"BackGroundMusic.json"})
|
||||
public class BackGroundMusicExcel extends GameResource {
|
||||
private int ID;
|
||||
private int GroupID;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ID;
|
||||
}
|
||||
public int getGroupId() {
|
||||
return GroupID;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package emu.lunarcore.data.excel;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
import emu.lunarcore.game.rogue.RogueBuffType;
|
||||
import emu.lunarcore.util.Utils;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = {"BattleEventData.json"})
|
||||
public class BattleEventDataExcel extends GameResource {
|
||||
private int BattleEventID;
|
||||
private String Config;
|
||||
|
||||
private static final Pattern roguePattern = Pattern.compile("(?<=Avatar_RogueBattleevent)(.*?)(?=_Config.json)");
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return BattleEventID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
try {
|
||||
Matcher matcher = roguePattern.matcher(this.Config);
|
||||
|
||||
if (matcher.find()) {
|
||||
int rogueBuffType = Utils.parseSafeInt(matcher.group(0));
|
||||
var type = RogueBuffType.getById(rogueBuffType);
|
||||
|
||||
if (type != null) {
|
||||
type.setBattleEventSkill(this.BattleEventID);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,46 +15,46 @@ public class ChallengeExcel extends GameResource {
|
||||
private int StageNum;
|
||||
private int ChallengeCountDown;
|
||||
private int MazeBuffID;
|
||||
|
||||
|
||||
private int[] ChallengeTargetID;
|
||||
|
||||
|
||||
private int MazeGroupID1;
|
||||
private int[] ConfigList1;
|
||||
private int[] NpcMonsterIDList1;
|
||||
private int[] EventIDList1;
|
||||
|
||||
|
||||
private int MazeGroupID2;
|
||||
private int[] ConfigList2;
|
||||
private int[] NpcMonsterIDList2;
|
||||
private int[] EventIDList2;
|
||||
|
||||
|
||||
private transient Int2ObjectMap<ChallengeMonsterInfo> challengeMonsters1;
|
||||
private transient Int2ObjectMap<ChallengeMonsterInfo> challengeMonsters2;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
// Cache challenge monsters
|
||||
this.challengeMonsters1 = new Int2ObjectOpenHashMap<>();
|
||||
for (int i = 0; i < ConfigList1.length; i++) {
|
||||
if (ConfigList1[i] == 0) break;
|
||||
|
||||
|
||||
var monster = new ChallengeMonsterInfo(ConfigList1[i], NpcMonsterIDList1[i], EventIDList1[i]);
|
||||
this.challengeMonsters1.put(monster.getConfigId(), monster);
|
||||
}
|
||||
|
||||
|
||||
this.challengeMonsters2 = new Int2ObjectOpenHashMap<>();
|
||||
for (int i = 0; i < ConfigList2.length; i++) {
|
||||
if (ConfigList2[i] == 0) break;
|
||||
|
||||
|
||||
var monster = new ChallengeMonsterInfo(ConfigList2[i], NpcMonsterIDList2[i], EventIDList2[i]);
|
||||
this.challengeMonsters2.put(monster.getConfigId(), monster);
|
||||
}
|
||||
|
||||
|
||||
// Clear arrays to save memory
|
||||
this.ConfigList1 = null;
|
||||
this.NpcMonsterIDList1 = null;
|
||||
@@ -69,12 +69,12 @@ public class ChallengeExcel extends GameResource {
|
||||
private int configId;
|
||||
private int npcMonsterId;
|
||||
private int eventId;
|
||||
|
||||
|
||||
public ChallengeMonsterInfo(int configId, int npcMonsterId, int eventId) {
|
||||
this.configId = configId;
|
||||
this.npcMonsterId = npcMonsterId;
|
||||
this.eventId = eventId;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import lombok.Getter;
|
||||
public class ChallengeGroupExcel extends GameResource {
|
||||
private int GroupID;
|
||||
private int RewardLineGroupID;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return GroupID;
|
||||
|
||||
@@ -10,7 +10,7 @@ public class ChallengeRewardExcel extends GameResource {
|
||||
private int GroupID;
|
||||
private int StarCount;
|
||||
private int RewardID;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return (GroupID << 16) + StarCount;
|
||||
|
||||
@@ -11,7 +11,7 @@ public class ChallengeTargetExcel extends GameResource {
|
||||
private int ID;
|
||||
private ChallengeType ChallengeTargetType;
|
||||
private int ChallengeTargetParam1;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ID;
|
||||
|
||||
20
src/main/java/emu/lunarcore/data/excel/ChatBubbleExcel.java
Normal file
20
src/main/java/emu/lunarcore/data/excel/ChatBubbleExcel.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package emu.lunarcore.data.excel;
|
||||
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
import emu.lunarcore.data.ResourceType.LoadPriority;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = {"ChatBubbleConfig.json"}, loadPriority = LoadPriority.LOW)
|
||||
public class ChatBubbleExcel extends GameResource {
|
||||
private int ID;
|
||||
private String ShowType;
|
||||
private int ShowParam;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,7 +16,7 @@ public class CocoonExcel extends GameResource {
|
||||
private int MaxWave;
|
||||
private IntArrayList StageIDList;
|
||||
private IntArrayList DropList;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return (ID << 8) + WorldLevel;
|
||||
|
||||
@@ -7,7 +7,6 @@ import emu.lunarcore.data.GameDepot;
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
import emu.lunarcore.data.ResourceType.LoadPriority;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@@ -30,7 +29,7 @@ public class EquipmentExpItemExcel extends GameResource {
|
||||
|
||||
excel.setEquipmentExp(ExpProvide);
|
||||
excel.setExpCost(CoinCost);
|
||||
|
||||
|
||||
// Add to game depot
|
||||
if (ExpProvide > 0) {
|
||||
GameDepot.getEquipmentExpExcels().add(this);
|
||||
|
||||
@@ -10,7 +10,7 @@ import lombok.Getter;
|
||||
public class HeroExcel extends GameResource {
|
||||
private int HeroAvatarID;
|
||||
private PlayerGender Gender;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return HeroAvatarID;
|
||||
|
||||
@@ -15,11 +15,12 @@ public class ItemComposeExcel extends GameResource {
|
||||
private int ItemID;
|
||||
private FormulaType FormulaType;
|
||||
private List<ItemParam> MaterialCost;
|
||||
private int[] SpecialMaterialCost;
|
||||
private IntOpenHashSet SpecialMaterialCost;
|
||||
private int SpecialMaterialCostNumber;
|
||||
private int CoinCost;
|
||||
private int WorldLevelRequire;
|
||||
private IntOpenHashSet RelicList;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ID;
|
||||
|
||||
@@ -8,6 +8,7 @@ import emu.lunarcore.data.common.ItemParam;
|
||||
import emu.lunarcore.game.enums.ItemMainType;
|
||||
import emu.lunarcore.game.enums.ItemRarity;
|
||||
import emu.lunarcore.game.enums.ItemSubType;
|
||||
import emu.lunarcore.game.enums.ItemUseMethod;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@@ -18,11 +19,14 @@ public class ItemExcel extends GameResource {
|
||||
// General item data
|
||||
private int ID;
|
||||
private long ItemName;
|
||||
private ItemMainType ItemMainType;
|
||||
private ItemSubType ItemSubType;
|
||||
private ItemMainType ItemMainType = emu.lunarcore.game.enums.ItemMainType.Unknown;
|
||||
private ItemSubType ItemSubType = emu.lunarcore.game.enums.ItemSubType.Unknown;
|
||||
private ItemRarity Rarity;
|
||||
private int PileLimit;
|
||||
private int PurposeType;
|
||||
|
||||
private int UseDataID;
|
||||
private ItemUseMethod UseMethod;
|
||||
|
||||
private List<ItemParam> ReturnItemIDList;
|
||||
|
||||
@@ -44,6 +48,10 @@ public class ItemExcel extends GameResource {
|
||||
return ItemMainType == emu.lunarcore.game.enums.ItemMainType.Equipment && this.getEquipmentExcel() != null;
|
||||
}
|
||||
|
||||
public boolean isHeadIcon() {
|
||||
return ItemSubType == emu.lunarcore.game.enums.ItemSubType.HeadIcon;
|
||||
}
|
||||
|
||||
public boolean isRelic() {
|
||||
return ItemMainType == emu.lunarcore.game.enums.ItemMainType.Relic && this.getRelicExcel() != null;
|
||||
}
|
||||
@@ -51,6 +59,10 @@ public class ItemExcel extends GameResource {
|
||||
public boolean isEquippable() {
|
||||
return ItemMainType == emu.lunarcore.game.enums.ItemMainType.Relic || ItemMainType == emu.lunarcore.game.enums.ItemMainType.Equipment;
|
||||
}
|
||||
|
||||
public int getRarityNum() {
|
||||
return this.getRarity().getVal();
|
||||
}
|
||||
|
||||
public int getRelicExp() {
|
||||
if (this.relicExcel != null) {
|
||||
@@ -58,7 +70,7 @@ public class ItemExcel extends GameResource {
|
||||
}
|
||||
return this.relicExp;
|
||||
}
|
||||
|
||||
|
||||
public int getRelicExpCost() {
|
||||
if (this.relicExcel != null) {
|
||||
return this.relicExcel.getCoinCost();
|
||||
|
||||
29
src/main/java/emu/lunarcore/data/excel/ItemUseExcel.java
Normal file
29
src/main/java/emu/lunarcore/data/excel/ItemUseExcel.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package emu.lunarcore.data.excel;
|
||||
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
import emu.lunarcore.game.enums.ItemFoodTargetType;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = {"ItemUseData.json", "ItemUseBuffData.json"})
|
||||
public class ItemUseExcel extends GameResource {
|
||||
private int UseDataID;
|
||||
private int ConsumeType;
|
||||
private int MazeBuffID;
|
||||
|
||||
private double PreviewHPRecoveryPercent;
|
||||
private int PreviewHPRecoveryValue;
|
||||
private double PreviewPowerPercent;
|
||||
private int PreviewSkillPoint;
|
||||
|
||||
private ItemFoodTargetType UseTargetType;
|
||||
private IntArrayList UseParam;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return UseDataID;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,7 +12,7 @@ public class MapEntranceExcel extends GameResource {
|
||||
private int FloorID;
|
||||
private int StartGroupID;
|
||||
private int StartAnchorID;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ID;
|
||||
|
||||
@@ -9,7 +9,7 @@ import lombok.Getter;
|
||||
public class MazeBuffExcel extends GameResource {
|
||||
private int ID;
|
||||
private int Lv;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return (ID << 4) + Lv;
|
||||
|
||||
@@ -14,10 +14,10 @@ public class MazePlaneExcel extends GameResource {
|
||||
private int WorldID;
|
||||
private int StartFloorID;
|
||||
private long PlaneName;
|
||||
|
||||
|
||||
@SerializedName(value = "PlaneType")
|
||||
private PlaneType planeType = PlaneType.Unknown;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return PlaneID;
|
||||
|
||||
@@ -13,9 +13,9 @@ public class MonsterDropExcel extends GameResource {
|
||||
private int MonsterTemplateID;
|
||||
private int WorldLevel;
|
||||
private int AvatarExpReward;
|
||||
|
||||
|
||||
private List<ItemParam> DisplayItemList;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return (MonsterTemplateID << 4) + WorldLevel;
|
||||
|
||||
16
src/main/java/emu/lunarcore/data/excel/MonsterExcel.java
Normal file
16
src/main/java/emu/lunarcore/data/excel/MonsterExcel.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package emu.lunarcore.data.excel;
|
||||
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = {"MonsterConfig.json"})
|
||||
public class MonsterExcel extends GameResource {
|
||||
private int MonsterID;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return MonsterID;
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import lombok.Getter;
|
||||
@ResourceType(name = {"NPCData.json"})
|
||||
public class NpcExcel extends GameResource {
|
||||
private int ID;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ID;
|
||||
|
||||
18
src/main/java/emu/lunarcore/data/excel/PhoneThemeExcel.java
Normal file
18
src/main/java/emu/lunarcore/data/excel/PhoneThemeExcel.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package emu.lunarcore.data.excel;
|
||||
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
import emu.lunarcore.data.ResourceType.LoadPriority;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = {"PhoneThemeConfig.json"}, loadPriority = LoadPriority.LOW)
|
||||
public class PhoneThemeExcel extends GameResource {
|
||||
private int ID;
|
||||
private String ShowType;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ID;
|
||||
}
|
||||
}
|
||||
17
src/main/java/emu/lunarcore/data/excel/PlayerIconExcel.java
Normal file
17
src/main/java/emu/lunarcore/data/excel/PlayerIconExcel.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package emu.lunarcore.data.excel;
|
||||
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
import emu.lunarcore.data.ResourceType.LoadPriority;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = {"PlayerIcon.json"}, loadPriority = LoadPriority.NORMAL)
|
||||
public class PlayerIconExcel extends GameResource {
|
||||
private int ID;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ID;
|
||||
}
|
||||
}
|
||||
@@ -12,15 +12,15 @@ public class PropExcel extends GameResource {
|
||||
private long PropName;
|
||||
private String JsonPath;
|
||||
private PropType PropType;
|
||||
|
||||
|
||||
private transient boolean recoverHp;
|
||||
private transient boolean recoverMp;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
// Hacky way to determine if a prop will recover hp or mp
|
||||
@@ -31,7 +31,7 @@ public class PropExcel extends GameResource {
|
||||
this.recoverHp = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Clear for optimization
|
||||
this.JsonPath = null;
|
||||
}
|
||||
|
||||
17
src/main/java/emu/lunarcore/data/excel/QuestExcel.java
Normal file
17
src/main/java/emu/lunarcore/data/excel/QuestExcel.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package emu.lunarcore.data.excel;
|
||||
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
import emu.lunarcore.data.ResourceType.LoadPriority;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = {"QuestData.json"}, loadPriority = LoadPriority.NORMAL)
|
||||
public class QuestExcel extends GameResource {
|
||||
private int QuestID;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return QuestID;
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,9 @@ public class RelicExcel extends GameResource {
|
||||
public int getId() {
|
||||
return ID;
|
||||
}
|
||||
public int getSetId() {
|
||||
return SetID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
|
||||
@@ -30,7 +30,7 @@ public class RelicExpItemExcel extends GameResource {
|
||||
|
||||
excel.setRelicExp(ExpProvide);
|
||||
excel.setExpCost(CoinCost);
|
||||
|
||||
|
||||
// Add to game depot
|
||||
if (ExpProvide > 0 && excel.getRarity() != ItemRarity.SuperRare) {
|
||||
GameDepot.getRelicExpExcels().add(this);
|
||||
|
||||
17
src/main/java/emu/lunarcore/data/excel/RelicSetExcel.java
Normal file
17
src/main/java/emu/lunarcore/data/excel/RelicSetExcel.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package emu.lunarcore.data.excel;
|
||||
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
import emu.lunarcore.data.ResourceType.LoadPriority;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = {"RelicSetConfig.json"}, loadPriority = LoadPriority.NORMAL)
|
||||
public class RelicSetExcel extends GameResource {
|
||||
private int SetID;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return SetID;
|
||||
}
|
||||
}
|
||||
@@ -13,9 +13,9 @@ import lombok.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;
|
||||
@@ -26,9 +26,9 @@ public class RewardExcel extends GameResource {
|
||||
private int Count_4;
|
||||
private int ItemID_5;
|
||||
private int Count_5;
|
||||
|
||||
|
||||
private transient List<ItemParam> rewards;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return RewardID;
|
||||
@@ -37,11 +37,11 @@ public class RewardExcel extends GameResource {
|
||||
@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) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import lombok.Getter;
|
||||
public class RogueAeonExcel extends GameResource {
|
||||
private int AeonID;
|
||||
private int RogueBuffType;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return AeonID;
|
||||
|
||||
@@ -6,6 +6,7 @@ import emu.lunarcore.data.GameDepot;
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
import emu.lunarcore.data.ResourceType.LoadPriority;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@@ -14,10 +15,11 @@ public class RogueAreaExcel extends GameResource {
|
||||
private int RogueAreaID;
|
||||
private int AreaProgress;
|
||||
private int Difficulty;
|
||||
|
||||
private Int2IntOpenHashMap ScoreMap;
|
||||
|
||||
private transient int mapId;
|
||||
private transient List<RogueMapExcel> sites;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return RogueAreaID;
|
||||
|
||||
@@ -1,29 +1,45 @@
|
||||
package emu.lunarcore.data.excel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import emu.lunarcore.data.GameDepot;
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
|
||||
import emu.lunarcore.data.ResourceType.LoadPriority;
|
||||
import emu.lunarcore.game.enums.RogueBuffAeonType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = {"RogueBuff.json"})
|
||||
@ResourceType(name = {"RogueBuff.json"}, loadPriority = LoadPriority.LOW)
|
||||
public class RogueBuffExcel extends GameResource {
|
||||
private int MazeBuffID;
|
||||
private int MazeBuffLevel;
|
||||
private int RogueBuffType;
|
||||
private int RogueBuffRarity;
|
||||
private int AeonID;
|
||||
|
||||
private RogueBuffAeonType BattleEventBuffType = RogueBuffAeonType.Normal;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return MazeBuffID;
|
||||
return (MazeBuffID << 4) + MazeBuffLevel;
|
||||
}
|
||||
|
||||
public boolean isAeonBuff() {
|
||||
return this.BattleEventBuffType != RogueBuffAeonType.Normal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
// Add to random buff list
|
||||
if (RogueBuffType >= 120 && RogueBuffType <= 126 && RogueBuffRarity >= 1 && RogueBuffRarity <= 3 && MazeBuffLevel == 1 && AeonID == 0) {
|
||||
GameDepot.getRogueRandomBuffList().add(this);
|
||||
}
|
||||
|
||||
// Add to aeon buff list
|
||||
if (BattleEventBuffType == RogueBuffAeonType.BattleEventBuff) {
|
||||
GameDepot.getRogueAeonBuffs().put(this.getAeonID(), this);
|
||||
} else if (BattleEventBuffType == RogueBuffAeonType.BattleEventBuffEnhance) {
|
||||
GameDepot.getRogueAeonEnhanceBuffs().computeIfAbsent(this.getAeonID(), e -> new ArrayList<>()).add(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package emu.lunarcore.data.excel;
|
||||
|
||||
import java.time.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import emu.lunarcore.data.GameResource;
|
||||
@@ -12,20 +13,20 @@ import lombok.Getter;
|
||||
@ResourceType(name = {"RogueManager.json"})
|
||||
public class RogueManagerExcel extends GameResource {
|
||||
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
|
||||
private int ScheduleDataID;
|
||||
private int RogueSeason;
|
||||
|
||||
|
||||
@Getter(AccessLevel.NONE)
|
||||
private String BeginTime;
|
||||
@Getter(AccessLevel.NONE)
|
||||
private String EndTime;
|
||||
|
||||
|
||||
private int[] RogueAreaIDList;
|
||||
|
||||
|
||||
private transient long beginTime;
|
||||
private transient long endTime;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ScheduleDataID;
|
||||
@@ -38,13 +39,13 @@ public class RogueManagerExcel extends GameResource {
|
||||
.atOffset(ZoneOffset.UTC)
|
||||
.toInstant()
|
||||
.toEpochMilli();
|
||||
|
||||
|
||||
this.endTime = LocalDateTime.from(formatter.parse(this.EndTime))
|
||||
.atOffset(ZoneOffset.UTC)
|
||||
.toInstant()
|
||||
.toEpochMilli();
|
||||
} catch (Exception e) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,12 +14,12 @@ public class RogueMapExcel extends GameResource {
|
||||
private boolean IsStart;
|
||||
private int[] NextSiteIDList;
|
||||
private int[] LevelList;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return (RogueMapID << 8) + SiteID;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
GameDepot.getRogueMapsById(this.getRogueMapID()).add(this);
|
||||
|
||||
@@ -3,7 +3,6 @@ package emu.lunarcore.data.excel;
|
||||
import emu.lunarcore.data.GameDepot;
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@@ -12,7 +11,7 @@ public class RogueMiracleExcel extends GameResource {
|
||||
private int MiracleID;
|
||||
private boolean IsShow;
|
||||
private int MiracleReward;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return MiracleID;
|
||||
|
||||
@@ -2,7 +2,6 @@ package emu.lunarcore.data.excel;
|
||||
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@@ -11,7 +10,7 @@ public class RogueMonsterExcel extends GameResource {
|
||||
private int RogueMonsterID;
|
||||
private int NpcMonsterID;
|
||||
private int EventID;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return RogueMonsterID;
|
||||
|
||||
@@ -10,7 +10,7 @@ import lombok.Getter;
|
||||
public class RogueNPCExcel extends GameResource {
|
||||
private int RogueNPCID;
|
||||
private int NPCID;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return RogueNPCID;
|
||||
|
||||
@@ -13,7 +13,7 @@ public class RogueRoomExcel extends GameResource {
|
||||
private int MapEntrance;
|
||||
private int GroupID;
|
||||
private Int2IntOpenHashMap GroupWithContent;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return RogueRoomID;
|
||||
|
||||
@@ -12,7 +12,7 @@ import lombok.Getter;
|
||||
public class RogueTalentExcel extends GameResource {
|
||||
private int TalentID;
|
||||
private List<ItemParam> Cost;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return TalentID;
|
||||
|
||||
@@ -2,8 +2,8 @@ package emu.lunarcore.data.excel;
|
||||
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@@ -11,13 +11,13 @@ import lombok.Getter;
|
||||
public class ShopExcel extends GameResource {
|
||||
private int ShopID;
|
||||
private int ShopType;
|
||||
|
||||
|
||||
private transient Int2ObjectMap<ShopGoodsExcel> goods;
|
||||
|
||||
|
||||
public ShopExcel() {
|
||||
this.goods = new Int2ObjectOpenHashMap<>();
|
||||
this.goods = new Int2ObjectAVLTreeMap<>();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ShopID;
|
||||
|
||||
@@ -19,38 +19,41 @@ public class ShopGoodsExcel extends GameResource {
|
||||
private int ItemID;
|
||||
private int ItemCount;
|
||||
private int ShopID;
|
||||
|
||||
|
||||
@Getter(AccessLevel.NONE)
|
||||
private int[] CurrencyList;
|
||||
@Getter(AccessLevel.NONE)
|
||||
private int[] CurrencyCostList;
|
||||
|
||||
|
||||
private transient List<ItemParam> costList;
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return GoodsID;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
// Skip if we dont have an item id associated with this goods excel
|
||||
if (this.getItemID() == 0) return;
|
||||
|
||||
// Add to shop excel
|
||||
ShopExcel shop = GameData.getShopExcelMap().get(this.ShopID);
|
||||
if (shop == null) return;
|
||||
|
||||
|
||||
shop.getGoods().put(this.GoodsID, this);
|
||||
|
||||
|
||||
// Cache currency cost
|
||||
this.costList = new ArrayList<>(CurrencyList.length);
|
||||
|
||||
|
||||
for (int i = 0; i < CurrencyList.length; i++) {
|
||||
ItemParam param = new ItemParam(CurrencyList[i], CurrencyCostList[i]);
|
||||
this.costList.add(param);
|
||||
}
|
||||
|
||||
|
||||
// Done - Clear references to save memory
|
||||
this.CurrencyList = null;
|
||||
this.CurrencyCostList = null;
|
||||
this.CurrencyCostList = null;
|
||||
}
|
||||
|
||||
public Goods toProto() {
|
||||
@@ -58,7 +61,7 @@ public class ShopGoodsExcel extends GameResource {
|
||||
.setGoodsId(this.getGoodsID())
|
||||
.setItemId(this.getItemID())
|
||||
.setEndTime(Integer.MAX_VALUE);
|
||||
|
||||
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,10 @@ public class StageExcel extends GameResource {
|
||||
private long StageName;
|
||||
private StageType StageType;
|
||||
private int Level;
|
||||
|
||||
@Getter(AccessLevel.NONE)
|
||||
|
||||
@Getter(AccessLevel.NONE)
|
||||
private List<StageMonsterWave> MonsterList;
|
||||
|
||||
|
||||
// Cache
|
||||
private transient List<IntList> monsterWaves;
|
||||
|
||||
@@ -38,18 +38,18 @@ public class StageExcel extends GameResource {
|
||||
this.monsterWaves.add(wave.toList());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class StageMonsterWave {
|
||||
private int Monster0;
|
||||
private int Monster1;
|
||||
private int Monster2;
|
||||
private int Monster3;
|
||||
private int Monster4;
|
||||
|
||||
|
||||
// Sigh...
|
||||
public IntList toList() {
|
||||
IntList list = new IntArrayList(5);
|
||||
|
||||
|
||||
if (this.Monster0 != 0) {
|
||||
list.add(this.Monster0);
|
||||
} if (this.Monster1 != 0) {
|
||||
@@ -61,7 +61,7 @@ public class StageExcel extends GameResource {
|
||||
} if (this.Monster4 != 0) {
|
||||
list.add(this.Monster4);
|
||||
}
|
||||
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
23
src/main/java/emu/lunarcore/data/excel/TextJoinExcel.java
Normal file
23
src/main/java/emu/lunarcore/data/excel/TextJoinExcel.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package emu.lunarcore.data.excel;
|
||||
|
||||
import emu.lunarcore.data.GameResource;
|
||||
import emu.lunarcore.data.ResourceType;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = {"TextJoinConfig.json"})
|
||||
public class TextJoinExcel extends GameResource {
|
||||
private int TextJoinID;
|
||||
private int DefaultItem;
|
||||
private IntArrayList TextJoinItemList;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return TextJoinID;
|
||||
}
|
||||
|
||||
public IntArrayList getTextJoinItemList() {
|
||||
return TextJoinItemList;
|
||||
}
|
||||
}
|
||||
@@ -48,15 +48,15 @@ public final class DatabaseManager {
|
||||
// Local mongo server
|
||||
if (info.isUseInternal() && Utils.isPortOpen(internalConfig.getAddress(), internalConfig.getPort())) {
|
||||
connectionString = startInternalMongoServer(internalConfig);
|
||||
LunarCore.getLogger().info("Using local mongo server at " + server.getConnectionString());
|
||||
LunarCore.getLogger().info("Started local mongo server at " + server.getConnectionString());
|
||||
}
|
||||
|
||||
// Initialize
|
||||
MongoClient gameMongoClient = MongoClients.create(connectionString);
|
||||
|
||||
MongoClient mongoClient = MongoClients.create(connectionString);
|
||||
|
||||
// Add our custom fastutil codecs
|
||||
var codecProvider = CodecRegistries.fromCodecs(
|
||||
new IntSetCodec(), new Int2IntMapCodec()
|
||||
new IntSetCodec(), new IntListCodec(), new Int2IntMapCodec()
|
||||
);
|
||||
|
||||
// Set mapper options.
|
||||
@@ -67,7 +67,7 @@ public final class DatabaseManager {
|
||||
.build();
|
||||
|
||||
// Create data store.
|
||||
datastore = Morphia.createDatastore(gameMongoClient, info.getCollection(), mapperOptions);
|
||||
datastore = Morphia.createDatastore(mongoClient, info.getCollection(), mapperOptions);
|
||||
|
||||
// Map classes
|
||||
var entities = new Reflections(LunarCore.class.getPackageName())
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package emu.lunarcore.database.codecs;
|
||||
|
||||
import org.bson.BsonReader;
|
||||
import org.bson.BsonType;
|
||||
import org.bson.BsonWriter;
|
||||
import org.bson.codecs.Codec;
|
||||
import org.bson.codecs.DecoderContext;
|
||||
import org.bson.codecs.EncoderContext;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
|
||||
/**
|
||||
* Custom mongodb codec for encoding/decoding fastutil int sets.
|
||||
*/
|
||||
public class IntListCodec implements Codec<IntList> {
|
||||
|
||||
@Override
|
||||
public Class<IntList> getEncoderClass() {
|
||||
return IntList.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(BsonWriter writer, IntList collection, EncoderContext encoderContext) {
|
||||
writer.writeStartArray();
|
||||
for (int value : collection) {
|
||||
writer.writeInt32(value);
|
||||
}
|
||||
writer.writeEndArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntList decode(BsonReader reader, DecoderContext decoderContext) {
|
||||
IntList collection = new IntArrayList();
|
||||
reader.readStartArray();
|
||||
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
|
||||
collection.add(reader.readInt32());
|
||||
}
|
||||
reader.readEndArray();
|
||||
return collection;
|
||||
}
|
||||
}
|
||||
@@ -53,15 +53,20 @@ public class AvatarStorage extends BasePlayerManager implements Iterable<GameAva
|
||||
// Set owner first
|
||||
avatar.setOwner(getPlayer());
|
||||
|
||||
// Put into maps
|
||||
// Put into avatar map
|
||||
this.avatars.put(avatar.getAvatarId(), avatar);
|
||||
|
||||
// Save to database
|
||||
// Save to database and send packet
|
||||
avatar.save();
|
||||
|
||||
// Send packet
|
||||
getPlayer().sendPacket(new PacketPlayerSyncScNotify(avatar));
|
||||
|
||||
// Add head icon
|
||||
int headIconId = 200000 + avatar.getAvatarId();
|
||||
if (GameData.getItemExcelMap().containsKey(headIconId)) {
|
||||
getPlayer().addHeadIcon(headIconId);
|
||||
}
|
||||
|
||||
// Done
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ public class GameAvatar implements GameEntity {
|
||||
private transient Player owner;
|
||||
private transient AvatarExcel excel;
|
||||
|
||||
private int avatarId; // Id of avatar
|
||||
private int avatarId; // Id of avatar in the excels
|
||||
private AvatarData data;
|
||||
@Setter private int level;
|
||||
@Setter private int exp;
|
||||
|
||||
@@ -13,11 +13,12 @@ import emu.lunarcore.game.inventory.GameItem;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.game.player.lineup.PlayerLineup;
|
||||
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||
import emu.lunarcore.proto.ClientTurnSnapshotOuterClass.ClientTurnSnapshot;
|
||||
import emu.lunarcore.proto.SceneBattleInfoOuterClass.SceneBattleInfo;
|
||||
import emu.lunarcore.proto.SceneMonsterOuterClass.SceneMonster;
|
||||
import emu.lunarcore.proto.SceneMonsterWaveOuterClass.SceneMonsterWave;
|
||||
import emu.lunarcore.util.Utils;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@@ -33,6 +34,8 @@ public class Battle {
|
||||
private final List<GameItem> drops;
|
||||
private final long timestamp;
|
||||
|
||||
private IntList turnSnapshotList; // TODO maybe turn it into a map?
|
||||
|
||||
@Setter private int staminaCost;
|
||||
@Setter private int levelOverride;
|
||||
@Setter private int roundsLimit;
|
||||
@@ -58,6 +61,13 @@ public class Battle {
|
||||
this.stages.addAll(stages);
|
||||
}
|
||||
|
||||
public IntList getTurnSnapshotList() {
|
||||
if (this.turnSnapshotList == null) {
|
||||
this.turnSnapshotList = new IntArrayList();
|
||||
}
|
||||
return this.turnSnapshotList;
|
||||
}
|
||||
|
||||
public StageType getStageType() {
|
||||
StageExcel stage = this.getFirstStage();
|
||||
if (stage != null) {
|
||||
@@ -111,6 +121,10 @@ public class Battle {
|
||||
return buff;
|
||||
}
|
||||
|
||||
public boolean hasBuff(int buffId) {
|
||||
return this.buffs.stream().filter(buff -> buff.getId() == buffId).findFirst().isPresent();
|
||||
}
|
||||
|
||||
public void clearBuffs() {
|
||||
this.buffs.clear();
|
||||
}
|
||||
@@ -175,11 +189,33 @@ public class Battle {
|
||||
}
|
||||
}
|
||||
|
||||
// Apply food buffs to battle
|
||||
if (player.getFoodBuffs().size() > 0) {
|
||||
for (int buffId : player.getFoodBuffs().values()) {
|
||||
this.addBuff(buffId, -1);
|
||||
}
|
||||
}
|
||||
|
||||
// Buffs
|
||||
for (MazeBuff buff : this.getBuffs()) {
|
||||
proto.addBuffList(buff.toProto());
|
||||
}
|
||||
|
||||
// Client turn snapshots
|
||||
if (this.turnSnapshotList != null) {
|
||||
for (int id : this.turnSnapshotList) {
|
||||
var snapshot = ClientTurnSnapshot.newInstance()
|
||||
.setBattleEventId(id);
|
||||
|
||||
// Temp solution
|
||||
snapshot.getMutableStatus().getMutableSpBar()
|
||||
.setCurSp(10000)
|
||||
.setMaxSp(10000);
|
||||
|
||||
proto.addTurnSnapshotList(snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import emu.lunarcore.GameConstants;
|
||||
import emu.lunarcore.data.GameData;
|
||||
import emu.lunarcore.data.excel.CocoonExcel;
|
||||
import emu.lunarcore.data.excel.StageExcel;
|
||||
@@ -63,13 +64,13 @@ public class BattleService extends BaseGameService {
|
||||
}
|
||||
}
|
||||
|
||||
// Give the client an error if no attacked entities detected
|
||||
// Skip if no attacked entities detected
|
||||
if (targetEntities.size() == 0) {
|
||||
player.sendPacket(new PacketSceneCastSkillScRsp());
|
||||
player.sendPacket(new PacketSceneCastSkillScRsp(attackedGroupId));
|
||||
return;
|
||||
}
|
||||
|
||||
// Monster list
|
||||
// Separate entities into monster list
|
||||
List<EntityMonster> monsters = new ArrayList<>();
|
||||
|
||||
// Destroy props
|
||||
@@ -84,6 +85,15 @@ public class BattleService extends BaseGameService {
|
||||
player.getScene().removeEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we are using a skill that doesnt trigger a battle
|
||||
if (castedSkill != null && !castedSkill.isTriggerBattle()) {
|
||||
// Apply buffs to monsters
|
||||
castedSkill.onAttack(player.getCurrentLeaderAvatar(), monsters);
|
||||
// Skip battle if our technique does not trigger a battle
|
||||
player.sendPacket(new PacketSceneCastSkillScRsp(attackedGroupId));
|
||||
return;
|
||||
}
|
||||
|
||||
// Start battle
|
||||
if (monsters.size() > 0) {
|
||||
@@ -106,7 +116,20 @@ public class BattleService extends BaseGameService {
|
||||
|
||||
// Create battle and add npc monsters to it
|
||||
Battle battle = new Battle(player, player.getLineupManager().getCurrentLineup(), stages);
|
||||
battle.getNpcMonsters().addAll(monsters);
|
||||
|
||||
// Add npc monsters
|
||||
for (var monster : monsters) {
|
||||
battle.getNpcMonsters().add(monster);
|
||||
|
||||
// Handle monster buffs
|
||||
// TODO handle multiple waves properly
|
||||
monster.applyBuffs(battle);
|
||||
|
||||
// Override level
|
||||
if (monster.getOverrideLevel() > 0) {
|
||||
battle.setLevelOverride(monster.getOverrideLevel());
|
||||
}
|
||||
}
|
||||
|
||||
// Add buffs to battle
|
||||
if (isPlayerCaster) {
|
||||
@@ -122,6 +145,9 @@ public class BattleService extends BaseGameService {
|
||||
buff.addDynamicValue("SkillIndex", castedSkill.getIndex());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Ambush buff (for monsters)
|
||||
battle.addBuff(GameConstants.BATTLE_AMBUSH_BUFF_ID, -1, 1);
|
||||
}
|
||||
|
||||
// Challenge
|
||||
@@ -274,6 +300,11 @@ public class BattleService extends BaseGameService {
|
||||
}
|
||||
}
|
||||
|
||||
// Clear food buffs for player
|
||||
if (player.getFoodBuffs().size() > 0) {
|
||||
player.getFoodBuffs().clear();
|
||||
}
|
||||
|
||||
// Challenge
|
||||
if (player.getChallengeInstance() != null) {
|
||||
player.getChallengeInstance().onBattleFinish(battle, result, stats);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package emu.lunarcore.game.battle;
|
||||
|
||||
import emu.lunarcore.data.excel.MazeBuffExcel;
|
||||
import emu.lunarcore.game.scene.entity.GameEntity;
|
||||
import emu.lunarcore.proto.BattleBuffOuterClass.BattleBuff;
|
||||
import emu.lunarcore.proto.BattleBuffOuterClass.BattleBuff.DynamicValuesEntry;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
@@ -9,6 +10,7 @@ import it.unimi.dsi.fastutil.objects.Object2DoubleMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2DoubleOpenHashMap;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
public class MazeBuff {
|
||||
@@ -19,7 +21,10 @@ public class MazeBuff {
|
||||
private IntList targetIndex;
|
||||
|
||||
@Getter(AccessLevel.NONE)
|
||||
private Object2DoubleMap<String> dynamicValues;
|
||||
private Object2DoubleMap<String> dynamicValues;
|
||||
|
||||
@Setter
|
||||
private transient GameEntity owner;
|
||||
|
||||
public MazeBuff(MazeBuffExcel excel, int ownerIndex, int waveFlag) {
|
||||
this(excel.getBuffId(), excel.getLv(), ownerIndex, waveFlag);
|
||||
@@ -52,9 +57,12 @@ public class MazeBuff {
|
||||
var proto = BattleBuff.newInstance()
|
||||
.setId(this.getId())
|
||||
.setLevel(this.getLevel())
|
||||
.setOwnerId(this.getOwnerIndex())
|
||||
.setWaveFlag(this.getWaveFlag());
|
||||
|
||||
if (this.ownerIndex != 0) {
|
||||
proto.setOwnerId(this.getOwnerIndex());
|
||||
}
|
||||
|
||||
if (this.targetIndex != null) {
|
||||
for (int index : this.targetIndex) {
|
||||
proto.addTargetIndexList(index);
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.List;
|
||||
import emu.lunarcore.data.excel.AvatarExcel;
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.battle.Battle;
|
||||
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@@ -44,4 +45,13 @@ public class MazeSkill {
|
||||
action.onAttack(caster, battle);
|
||||
}
|
||||
}
|
||||
|
||||
// Triggered when player attacks an enemy
|
||||
public void onAttack(GameAvatar caster, List<EntityMonster> monsters) {
|
||||
if (this.getAttackActions().size() == 0) return;
|
||||
|
||||
for (var action : this.getAttackActions()) {
|
||||
action.onAttack(caster, monsters);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package emu.lunarcore.game.battle.skills;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.battle.Battle;
|
||||
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||
|
||||
public abstract class MazeSkillAction {
|
||||
@@ -10,4 +13,6 @@ public abstract class MazeSkillAction {
|
||||
|
||||
public abstract void onAttack(GameAvatar caster, Battle battle);
|
||||
|
||||
public abstract void onAttack(GameAvatar caster, List<EntityMonster> monsters);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package emu.lunarcore.game.battle.skills;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.battle.Battle;
|
||||
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||
import lombok.Getter;
|
||||
|
||||
@@ -29,5 +32,12 @@ public class MazeSkillAddBuff extends MazeSkillAction {
|
||||
battle.addBuff(buffId, battle.getLineup().getLeader(), 1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttack(GameAvatar caster, List<EntityMonster> monsters) {
|
||||
for (EntityMonster monster : monsters) {
|
||||
monster.addBuff(caster.getAvatarId(), buffId, duration);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package emu.lunarcore.game.battle.skills;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.battle.Battle;
|
||||
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||
|
||||
public class MazeSkillModifyHP extends MazeSkillAction {
|
||||
@@ -21,4 +24,9 @@ public class MazeSkillModifyHP extends MazeSkillAction {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttack(GameAvatar caster, List<EntityMonster> monsters) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package emu.lunarcore.game.battle.skills;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.battle.Battle;
|
||||
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||
|
||||
public class MazeSkillModifySP extends MazeSkillAction {
|
||||
@@ -24,4 +27,9 @@ public class MazeSkillModifySP extends MazeSkillAction {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttack(GameAvatar caster, List<EntityMonster> monsters) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package emu.lunarcore.game.battle.skills;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.battle.Battle;
|
||||
import emu.lunarcore.game.scene.entity.EntityMonster;
|
||||
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
|
||||
|
||||
public class MazeSkillSummonUnit extends MazeSkillAction {
|
||||
@@ -16,4 +19,9 @@ public class MazeSkillSummonUnit extends MazeSkillAction {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttack(GameAvatar caster, List<EntityMonster> monsters) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import emu.lunarcore.proto.ChallengeStatusOuterClass.ChallengeStatus;
|
||||
import emu.lunarcore.proto.ExtraLineupTypeOuterClass.ExtraLineupType;
|
||||
import emu.lunarcore.server.packet.send.PacketChallengeLineupNotify;
|
||||
import emu.lunarcore.server.packet.send.PacketChallengeSettleNotify;
|
||||
import emu.lunarcore.server.packet.send.PacketSyncLineupNotify;
|
||||
import emu.lunarcore.util.Position;
|
||||
|
||||
import lombok.Getter;
|
||||
@@ -32,6 +33,7 @@ public class ChallengeInstance {
|
||||
private int status;
|
||||
private boolean hasAvatarDied;
|
||||
|
||||
@Setter private int savedMp;
|
||||
@Setter private int roundsLeft;
|
||||
@Setter private int stars;
|
||||
|
||||
@@ -79,7 +81,8 @@ public class ChallengeInstance {
|
||||
}
|
||||
|
||||
public void onBattleFinish(Battle battle, BattleEndStatus result, BattleStatistics stats) {
|
||||
if (result == BattleEndStatus.BATTLE_END_WIN) {
|
||||
switch (result) {
|
||||
case BATTLE_END_WIN:
|
||||
// Check if any avatar in the lineup has died
|
||||
battle.getLineup().forEachAvatar(avatar -> {
|
||||
if (avatar.getCurrentHp(battle.getLineup()) <= 0) {
|
||||
@@ -109,6 +112,7 @@ public class ChallengeInstance {
|
||||
this.setCurrentExtraLineup(ExtraLineupType.LINEUP_CHALLENGE_2);
|
||||
player.getLineupManager().setCurrentExtraLineup(this.getCurrentExtraLineup(), true);
|
||||
player.sendPacket(new PacketChallengeLineupNotify(this.getCurrentExtraLineup()));
|
||||
this.savedMp = player.getCurrentLineup().getMp();
|
||||
// Move player
|
||||
player.moveTo(this.getStartPos(), this.getStartRot());
|
||||
}
|
||||
@@ -116,9 +120,21 @@ public class ChallengeInstance {
|
||||
|
||||
// Calculate rounds left
|
||||
this.roundsLeft = Math.min(Math.max(this.roundsLeft - stats.getRoundCnt(), 1), this.roundsLeft);
|
||||
} else {
|
||||
|
||||
// Set saved technique points (This will be restored if the player resets the challenge)
|
||||
this.savedMp = player.getCurrentLineup().getMp();
|
||||
break;
|
||||
case BATTLE_END_QUIT:
|
||||
// Reset technique points and move back to start position
|
||||
var lineup = player.getCurrentLineup();
|
||||
lineup.setMp(this.savedMp);
|
||||
player.moveTo(this.getStartPos(), this.getStartRot());
|
||||
player.sendPacket(new PacketSyncLineupNotify(lineup));
|
||||
break;
|
||||
default:
|
||||
// Fail challenge
|
||||
this.setStatus(ChallengeStatus.CHALLENGE_FAILED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ public class ChallengeManager extends BasePlayerManager {
|
||||
// Save start positions
|
||||
instance.getStartPos().set(getPlayer().getPos());
|
||||
instance.getStartRot().set(getPlayer().getRot());
|
||||
instance.setSavedMp(getPlayer().getCurrentLineup().getMp());
|
||||
|
||||
// Send packet
|
||||
getPlayer().sendPacket(new PacketStartChallengeScRsp(getPlayer(), challengeId));
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package emu.lunarcore.game.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum ItemFoodTargetType {
|
||||
All (0),
|
||||
Alive (101),
|
||||
Dead (102);
|
||||
|
||||
private int val;
|
||||
|
||||
private ItemFoodTargetType(int value) {
|
||||
this.val = value;
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,29 @@
|
||||
package emu.lunarcore.game.enums;
|
||||
|
||||
import emu.lunarcore.game.inventory.tabs.InventoryTabType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum ItemMainType {
|
||||
Unknown (0),
|
||||
Virtual (1),
|
||||
AvatarCard (2),
|
||||
Equipment (3),
|
||||
Relic (4),
|
||||
Usable (5),
|
||||
Material (6),
|
||||
Mission (7),
|
||||
Display (8);
|
||||
Unknown (0),
|
||||
Virtual (1),
|
||||
AvatarCard (2),
|
||||
Equipment (3, InventoryTabType.EQUIPMENT),
|
||||
Relic (4, InventoryTabType.RELIC),
|
||||
Usable (5, InventoryTabType.MATERIAL),
|
||||
Material (6, InventoryTabType.MATERIAL),
|
||||
Mission (7, InventoryTabType.MATERIAL),
|
||||
Display (8);
|
||||
|
||||
private int val;
|
||||
private InventoryTabType tabType;
|
||||
|
||||
private ItemMainType(int value) {
|
||||
this.val = value;
|
||||
}
|
||||
|
||||
private ItemMainType(int value, InventoryTabType tabType) {
|
||||
this.val = value;
|
||||
this.tabType = tabType;
|
||||
}
|
||||
}
|
||||
|
||||
29
src/main/java/emu/lunarcore/game/enums/ItemUseMethod.java
Normal file
29
src/main/java/emu/lunarcore/game/enums/ItemUseMethod.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package emu.lunarcore.game.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum ItemUseMethod {
|
||||
Unknown (0),
|
||||
FixedRewardGift (101),
|
||||
RandomRewardGift (102),
|
||||
PlayerSelectedReward (103),
|
||||
TeamFoodBenefit (201),
|
||||
TeamSpecificFoodBenefit (202),
|
||||
ExternalSystemFoodBenefit (203),
|
||||
PlayerSelectedDropGift (301),
|
||||
TreasureMap (401),
|
||||
Recipe (501),
|
||||
PerformanceProp (601),
|
||||
MonthlyCard (701),
|
||||
BPUnlock68 (702),
|
||||
BPUnlock128 (703),
|
||||
BPUpgradeFrom68To128 (704),
|
||||
AutoConversionItem (801);
|
||||
|
||||
private int val;
|
||||
|
||||
private ItemUseMethod(int value) {
|
||||
this.val = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package emu.lunarcore.game.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum RogueBuffAeonType {
|
||||
Normal (0),
|
||||
BattleEventBuff (1),
|
||||
BattleEventBuffEnhance (2),
|
||||
BattleEventBuffCross (3);
|
||||
|
||||
private final int val;
|
||||
|
||||
private RogueBuffAeonType(int value) {
|
||||
this.val = value;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package emu.lunarcore.game.gacha;
|
||||
|
||||
import emu.lunarcore.proto.GachaCeilingOuterClass.GachaCeiling;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.proto.GachaInfoOuterClass.GachaInfo;
|
||||
import lombok.Getter;
|
||||
|
||||
@@ -14,30 +14,34 @@ public class GachaBanner {
|
||||
private int[] rateUpItems4;
|
||||
private int eventChance = 50;
|
||||
|
||||
public GachaInfo toProto() {
|
||||
public GachaInfo toProto(GachaService service, Player player) {
|
||||
var info = GachaInfo.newInstance()
|
||||
.setGachaId(this.getId())
|
||||
.setDetailUrl("")
|
||||
.setHistoryUrl("");
|
||||
|
||||
if (this.gachaType == GachaType.Normal) {
|
||||
// Gacha ceiling
|
||||
info.setGachaCeiling(GachaCeiling.newInstance());
|
||||
} else {
|
||||
if (this.gachaType != GachaType.Normal) {
|
||||
info.setBeginTime(this.getBeginTime());
|
||||
info.setEndTime(this.getEndTime());
|
||||
}
|
||||
|
||||
if (this.getRateUpItems4().length > 0) {
|
||||
for (int id : getRateUpItems4()) {
|
||||
info.addUpInfo(id);
|
||||
|
||||
if (this.getId() == 1001) {
|
||||
info.setGachaCeiling(player.getGachaInfo().toGachaCeiling(player));
|
||||
|
||||
info.addAllUpInfo(service.getPurpleAvatars());
|
||||
info.addAllUpInfo(service.getYellowAvatars());
|
||||
info.addAllUpInfo(service.getPurpleWeapons());
|
||||
info.addAllUpInfo(service.getYellowWeapons());
|
||||
|
||||
info.addAllFeatured(service.getDefaultFeaturedIds());
|
||||
} else {
|
||||
if (this.getRateUpItems4().length > 0) {
|
||||
info.addAllUpInfo(getRateUpItems4());
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getRateUpItems5().length > 0) {
|
||||
for (int id : getRateUpItems5()) {
|
||||
info.addUpInfo(id);
|
||||
info.addFeatured(id);
|
||||
if (this.getRateUpItems5().length > 0) {
|
||||
info.addAllUpInfo(getRateUpItems5());
|
||||
info.addAllFeatured(getRateUpItems5());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import emu.lunarcore.GameConstants;
|
||||
import emu.lunarcore.LunarCore;
|
||||
import emu.lunarcore.data.GameData;
|
||||
import emu.lunarcore.data.excel.ItemExcel;
|
||||
@@ -21,21 +22,25 @@ import emu.lunarcore.server.game.BaseGameService;
|
||||
import emu.lunarcore.server.game.GameServer;
|
||||
import emu.lunarcore.server.packet.send.PacketDoGachaScRsp;
|
||||
import emu.lunarcore.util.JsonUtils;
|
||||
import emu.lunarcore.util.Utils;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class GachaService extends BaseGameService {
|
||||
private final Int2ObjectMap<GachaBanner> gachaBanners;
|
||||
private GetGachaInfoScRsp cachedProto;
|
||||
|
||||
private int[] yellowAvatars = new int[] {1003, 1004, 1101, 1107, 1104, 1209, 1211};
|
||||
private int[] yellowWeapons = new int[] {23000, 23002, 23003, 23004, 23005, 23012, 23013};
|
||||
private int[] purpleAvatars = new int[] {1001, 1002, 1008, 1009, 1013, 1103, 1105, 1106, 1108, 1109, 1111, 1201, 1202, 1206, 1207};
|
||||
private int[] purpleAvatars = new int[] {1001, 1002, 1008, 1009, 1013, 1103, 1105, 1106, 1108, 1109, 1110, 1111, 1201, 1202, 1206, 1207, 1210};
|
||||
private int[] purpleWeapons = new int[] {21000, 21001, 21002, 21003, 21004, 21005, 21006, 21007, 21008, 21009, 21010, 21011, 21012, 21013, 21014, 21015, 21016, 21017, 21018, 21019, 21020};
|
||||
private int[] blueWeapons = new int[] {20000, 20001, 20002, 20003, 20004, 20005, 20006, 20007, 20008, 20009, 20010, 20011, 20012, 20013, 20014, 20015, 20016, 20017, 20018, 20019, 20020};
|
||||
|
||||
private int[] defaultFeaturedIds = new int[] {23002, 1003, 1101, 1104, 23000, 23003};
|
||||
|
||||
private static int starglightId = 252;
|
||||
private static int embersId = 251;
|
||||
|
||||
@@ -45,10 +50,6 @@ public class GachaService extends BaseGameService {
|
||||
this.load();
|
||||
}
|
||||
|
||||
public Int2ObjectMap<GachaBanner> getGachaBanners() {
|
||||
return gachaBanners;
|
||||
}
|
||||
|
||||
public int randomRange(int min, int max) {
|
||||
return ThreadLocalRandom.current().nextInt(max - min + 1) + min;
|
||||
}
|
||||
@@ -69,11 +70,11 @@ public class GachaService extends BaseGameService {
|
||||
}
|
||||
|
||||
public synchronized void doPulls(Player player, int gachaId, int times) {
|
||||
// Sanity check
|
||||
if (times != 10 && times != 1) {
|
||||
return;
|
||||
}
|
||||
if (player.getInventory().getInventoryTab(ItemMainType.Equipment).getSize() + times > player.getInventory().getInventoryTab(ItemMainType.Equipment).getMaxCapacity()) {
|
||||
// Sanity checks
|
||||
if (times != 10 && times != 1) return;
|
||||
|
||||
// Prevent player from using gacha if they are at max light cones
|
||||
if (player.getInventory().getTabByItemType(ItemMainType.Equipment).getSize() >= player.getInventory().getTabByItemType(ItemMainType.Equipment).getMaxCapacity()) {
|
||||
player.sendPacket(new PacketDoGachaScRsp());
|
||||
return;
|
||||
}
|
||||
@@ -87,13 +88,19 @@ public class GachaService extends BaseGameService {
|
||||
|
||||
// Spend currency
|
||||
if (banner.getGachaType().getCostItem() > 0) {
|
||||
GameItem costItem = player.getInventory().getInventoryTab(ItemMainType.Material).getItemById(banner.getGachaType().getCostItem());
|
||||
GameItem costItem = player.getInventory().getMaterialByItemId(banner.getGachaType().getCostItem());
|
||||
if (costItem == null || costItem.getCount() < times) {
|
||||
return;
|
||||
}
|
||||
|
||||
player.getInventory().removeItem(costItem, times);
|
||||
}
|
||||
|
||||
// Add gacha ceiling
|
||||
if (banner.getGachaType() == GachaType.Normal || banner.getGachaType() == GachaType.Newbie) {
|
||||
player.getGachaInfo().addCeilingNum(times);
|
||||
player.save();
|
||||
}
|
||||
|
||||
// Roll
|
||||
PlayerGachaBannerInfo gachaInfo = player.getGachaInfo().getBannerInfo(banner.getGachaType());
|
||||
@@ -188,7 +195,7 @@ public class GachaService extends BaseGameService {
|
||||
if (avatar != null) {
|
||||
int dupeLevel = avatar.getRank();
|
||||
int dupeItemId = avatarId + 10000; // Hacky fix so we dont have to fetch data from an excel
|
||||
GameItem dupeItem = player.getInventory().getInventoryTab(ItemMainType.Material).getItemById(dupeItemId);
|
||||
GameItem dupeItem = player.getInventory().getTabByItemType(ItemMainType.Material).getItemById(dupeItemId);
|
||||
if (dupeItem != null) {
|
||||
dupeLevel += dupeItem.getCount();
|
||||
}
|
||||
@@ -255,24 +262,44 @@ public class GachaService extends BaseGameService {
|
||||
}
|
||||
|
||||
// Packets
|
||||
player.sendPacket(new PacketDoGachaScRsp(banner, times, list));
|
||||
player.sendPacket(new PacketDoGachaScRsp(player, banner, times, list));
|
||||
}
|
||||
|
||||
public List<GameItem> exchangeGachaCeiling(Player player, int avatarId) {
|
||||
// Sanity check
|
||||
if (player.getGachaInfo().getCeilingNum() < GameConstants.GACHA_CEILING_MAX || player.getGachaInfo().isCeilingClaimed()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Make sure the player is getting a valid avatar
|
||||
if (!Utils.arrayContains(this.getYellowAvatars(), avatarId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Add items
|
||||
List<GameItem> items = new ArrayList<>();
|
||||
|
||||
if (player.getAvatars().hasAvatar(avatarId)) {
|
||||
// Add eidolon if player already has the avatar
|
||||
items.add(new GameItem(avatarId + 10000));
|
||||
} else {
|
||||
items.add(new GameItem(avatarId));
|
||||
}
|
||||
|
||||
player.getInventory().addItems(items);
|
||||
player.getGachaInfo().setCeilingClaimed(true);
|
||||
player.save();
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
private synchronized GetGachaInfoScRsp createProto() {
|
||||
public synchronized GetGachaInfoScRsp toProto(Player player) {
|
||||
var proto = GetGachaInfoScRsp.newInstance();
|
||||
|
||||
for (GachaBanner banner : getGachaBanners().values()) {
|
||||
proto.addGachaInfoList(banner.toProto());
|
||||
proto.addGachaInfoList(banner.toProto(this, player));
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
||||
public GetGachaInfoScRsp toProto() {
|
||||
if (this.cachedProto == null) {
|
||||
this.cachedProto = createProto();
|
||||
}
|
||||
|
||||
return this.cachedProto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,16 +4,19 @@ import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum GachaType {
|
||||
Newbie (101, 1, 2),
|
||||
Normal (101, 1, 2),
|
||||
AvatarUp (102, 1, 1),
|
||||
WeaponUp (102, 2, 2);
|
||||
Unknown (0, 0, 0, 0),
|
||||
Newbie (1, 101, 1, 2),
|
||||
Normal (2, 101, 1, 2),
|
||||
AvatarUp (11, 102, 1, 1),
|
||||
WeaponUp (12, 102, 2, 2);
|
||||
|
||||
private int id;
|
||||
private int costItem;
|
||||
private int minItemType;
|
||||
private int maxItemType;
|
||||
|
||||
private GachaType(int costItem, int min, int max) {
|
||||
private GachaType(int id, int costItem, int min, int max) {
|
||||
this.id = id;
|
||||
this.costItem = costItem;
|
||||
this.minItemType = min;
|
||||
this.maxItemType = max;
|
||||
|
||||
@@ -1,29 +1,31 @@
|
||||
package emu.lunarcore.game.gacha;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import emu.lunarcore.GameConstants;
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.proto.GachaCeilingAvatarOuterClass.GachaCeilingAvatar;
|
||||
import emu.lunarcore.proto.GachaCeilingOuterClass.GachaCeiling;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Entity(useDiscriminator = false)
|
||||
@Getter @Entity(useDiscriminator = false)
|
||||
public class PlayerGachaInfo {
|
||||
private PlayerGachaBannerInfo standardBanner;
|
||||
private PlayerGachaBannerInfo eventCharacterBanner;
|
||||
private PlayerGachaBannerInfo eventWeaponBanner;
|
||||
|
||||
private int ceilingNum;
|
||||
@Setter private boolean ceilingClaimed;
|
||||
|
||||
public PlayerGachaInfo() {
|
||||
this.standardBanner = new PlayerGachaBannerInfo();
|
||||
this.eventCharacterBanner = new PlayerGachaBannerInfo();
|
||||
this.eventWeaponBanner = new PlayerGachaBannerInfo();
|
||||
}
|
||||
|
||||
public PlayerGachaBannerInfo getStandardBanner() {
|
||||
return standardBanner;
|
||||
}
|
||||
|
||||
public PlayerGachaBannerInfo getEventCharacterBanner() {
|
||||
return eventCharacterBanner;
|
||||
}
|
||||
|
||||
public PlayerGachaBannerInfo getEventWeaponBanner() {
|
||||
return eventWeaponBanner;
|
||||
|
||||
public void addCeilingNum(int amount) {
|
||||
this.ceilingNum = Math.min(ceilingNum + amount, GameConstants.GACHA_CEILING_MAX);
|
||||
}
|
||||
|
||||
public PlayerGachaBannerInfo getBannerInfo(GachaType type) {
|
||||
@@ -35,4 +37,30 @@ public class PlayerGachaInfo {
|
||||
|
||||
return this.standardBanner;
|
||||
}
|
||||
|
||||
public GachaCeiling toGachaCeiling(Player player) {
|
||||
var proto = GachaCeiling.newInstance()
|
||||
.setIsClaimed(this.isCeilingClaimed())
|
||||
.setCeilingNum(this.getCeilingNum());
|
||||
|
||||
// Gacha ceiling avatars are the avatars that we can pick
|
||||
var ceilingAvatars = player.getServer().getGachaService().getYellowAvatars();
|
||||
for (int i = 0; i < ceilingAvatars.length; i++) {
|
||||
int avatarId = ceilingAvatars[i];
|
||||
int repeatedCount = 0; // Eidolon count
|
||||
|
||||
GameAvatar avatar = player.getAvatarById(avatarId);
|
||||
if (avatar != null) {
|
||||
repeatedCount = avatar.getRank();
|
||||
}
|
||||
|
||||
var ceilingAvatar = GachaCeilingAvatar.newInstance()
|
||||
.setRepeatedCnt(repeatedCount)
|
||||
.setAvatarId(avatarId);
|
||||
|
||||
proto.addAvatarList(ceilingAvatar);
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class GameItem {
|
||||
@Setter private boolean locked;
|
||||
|
||||
@Setter private int mainAffix;
|
||||
private List<ItemSubAffix> subAffixes;
|
||||
private List<GameItemSubAffix> subAffixes;
|
||||
|
||||
private int equipAvatar;
|
||||
|
||||
@@ -148,6 +148,14 @@ public class GameItem {
|
||||
}
|
||||
|
||||
// Sub affixes
|
||||
|
||||
public void resetSubAffixes() {
|
||||
if (this.subAffixes != null) {
|
||||
this.subAffixes.clear();
|
||||
} else {
|
||||
this.subAffixes = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public void addSubAffixes(int quantity) {
|
||||
for (int i = 0; i < quantity; i++) {
|
||||
@@ -180,7 +188,7 @@ public class GameItem {
|
||||
}
|
||||
|
||||
IntSet blacklist = new IntOpenHashSet();
|
||||
for (ItemSubAffix subAffix : this.getSubAffixes()) {
|
||||
for (GameItemSubAffix subAffix : this.getSubAffixes()) {
|
||||
blacklist.add(subAffix.getId());
|
||||
}
|
||||
|
||||
@@ -199,12 +207,31 @@ public class GameItem {
|
||||
|
||||
// Add random stat
|
||||
RelicSubAffixExcel subAffix = randomList.next();
|
||||
this.subAffixes.add(new ItemSubAffix(subAffix));
|
||||
this.subAffixes.add(new GameItemSubAffix(subAffix));
|
||||
}
|
||||
|
||||
private void upgradeRandomSubAffix() {
|
||||
ItemSubAffix subAffix = Utils.randomElement(this.subAffixes);
|
||||
subAffix.incrementCount();
|
||||
GameItemSubAffix subAffix = Utils.randomElement(this.subAffixes);
|
||||
var subAffixExcel = GameData.getRelicSubAffixExcel(this.getExcel().getRelicExcel().getSubAffixGroup(), subAffix.getId());
|
||||
subAffix.incrementCount(subAffixExcel.getStepNum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current count of sub affixes this item has
|
||||
*/
|
||||
public int getCurrentSubAffixCount() {
|
||||
if (this.subAffixes == null) return 0;
|
||||
|
||||
return this.subAffixes
|
||||
.stream()
|
||||
.reduce(0, (subtotal, subAffix) -> subtotal + subAffix.getCount(), Integer::sum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum amount of sub affixes this item should normally have
|
||||
*/
|
||||
public int getMaxNormalSubAffixCount() {
|
||||
return (getExcel().getRarity().getVal() - 1) + (int) Math.floor(this.getLevel() / 3.0);
|
||||
}
|
||||
|
||||
// Database
|
||||
|
||||
@@ -8,24 +8,29 @@ import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Entity(useDiscriminator = false)
|
||||
public class ItemSubAffix {
|
||||
public class GameItemSubAffix {
|
||||
private int id; // Affix id
|
||||
private int count;
|
||||
private int step;
|
||||
|
||||
|
||||
@Deprecated
|
||||
public ItemSubAffix() {
|
||||
public GameItemSubAffix() {
|
||||
// Morphia only!
|
||||
}
|
||||
|
||||
public ItemSubAffix(RelicSubAffixExcel subAffix) {
|
||||
public GameItemSubAffix(RelicSubAffixExcel subAffix) {
|
||||
this(subAffix, 1);
|
||||
}
|
||||
|
||||
public GameItemSubAffix(RelicSubAffixExcel subAffix, int count) {
|
||||
this.id = subAffix.getAffixID();
|
||||
this.count = 1;
|
||||
this.step = Utils.randomRange(0, subAffix.getStepNum());
|
||||
this.count = count;
|
||||
this.step = Utils.randomRange(0, count * subAffix.getStepNum());
|
||||
}
|
||||
|
||||
public void incrementCount() {
|
||||
public void incrementCount(int stepNum) {
|
||||
this.count += 1;
|
||||
this.step += Utils.randomRange(0, stepNum);
|
||||
}
|
||||
|
||||
public RelicAffix toProto() {
|
||||
@@ -36,4 +41,4 @@ public class ItemSubAffix {
|
||||
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,63 +16,73 @@ import emu.lunarcore.game.avatar.AvatarStorage;
|
||||
import emu.lunarcore.game.avatar.GameAvatar;
|
||||
import emu.lunarcore.game.enums.ItemMainType;
|
||||
import emu.lunarcore.game.enums.ItemSubType;
|
||||
import emu.lunarcore.game.inventory.tabs.EquipInventoryTab;
|
||||
import emu.lunarcore.game.inventory.tabs.InventoryTab;
|
||||
import emu.lunarcore.game.inventory.tabs.InventoryTabType;
|
||||
import emu.lunarcore.game.inventory.tabs.MaterialInventoryTab;
|
||||
import emu.lunarcore.game.player.BasePlayerManager;
|
||||
import emu.lunarcore.game.player.Player;
|
||||
import emu.lunarcore.server.packet.send.PacketPlayerSyncScNotify;
|
||||
import emu.lunarcore.server.packet.send.PacketScenePlaneEventScNotify;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
|
||||
public class Inventory extends BasePlayerManager {
|
||||
private final Long2ObjectMap<GameItem> store;
|
||||
private final Int2ObjectMap<GameItem> store;
|
||||
private final Int2ObjectMap<InventoryTab> inventoryTypes;
|
||||
private int nextInternalUid;
|
||||
|
||||
public Inventory(Player player) {
|
||||
super(player);
|
||||
|
||||
this.store = new Long2ObjectOpenHashMap<>();
|
||||
this.store = new Int2ObjectOpenHashMap<>();
|
||||
this.inventoryTypes = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
this.createInventoryTab(ItemMainType.Equipment, new EquipInventoryTab(1500));
|
||||
this.createInventoryTab(ItemMainType.Relic, new EquipInventoryTab(1500));
|
||||
this.createInventoryTab(ItemMainType.Material, new MaterialInventoryTab(2000));
|
||||
this.createTab(InventoryTabType.EQUIPMENT, new EquipInventoryTab(GameConstants.INVENTORY_MAX_EQUIPMENT));
|
||||
this.createTab(InventoryTabType.RELIC, new EquipInventoryTab(GameConstants.INVENTORY_MAX_RELIC));
|
||||
this.createTab(InventoryTabType.MATERIAL, new MaterialInventoryTab(GameConstants.INVENTORY_MAX_MATERIAL));
|
||||
}
|
||||
|
||||
public AvatarStorage getAvatarStorage() {
|
||||
return this.getPlayer().getAvatars();
|
||||
}
|
||||
|
||||
public Long2ObjectMap<GameItem> getItems() {
|
||||
public Int2ObjectMap<GameItem> getItems() {
|
||||
return store;
|
||||
}
|
||||
|
||||
public Int2ObjectMap<InventoryTab> getInventoryTypes() {
|
||||
return inventoryTypes;
|
||||
}
|
||||
|
||||
public InventoryTab getInventoryTab(ItemMainType type) {
|
||||
return getInventoryTypes().get(type.getVal());
|
||||
}
|
||||
|
||||
public void createInventoryTab(ItemMainType type, InventoryTab tab) {
|
||||
this.getInventoryTypes().put(type.getVal(), tab);
|
||||
}
|
||||
|
||||
|
||||
public int getNextItemInternalUid() {
|
||||
return ++nextInternalUid;
|
||||
}
|
||||
|
||||
/* Returns an item using its internal uid
|
||||
* */
|
||||
// Inventory tabs
|
||||
|
||||
public InventoryTab getTabByItemType(ItemMainType type) {
|
||||
return getTab(type.getTabType());
|
||||
}
|
||||
|
||||
public InventoryTab getTab(InventoryTabType type) {
|
||||
if (type == null) return null;
|
||||
return this.inventoryTypes.get(type.getVal());
|
||||
}
|
||||
|
||||
public void createTab(InventoryTabType type, InventoryTab tab) {
|
||||
this.inventoryTypes.put(type.getVal(), tab);
|
||||
}
|
||||
|
||||
// Items
|
||||
|
||||
/**
|
||||
* Returns an item using its internal uid
|
||||
* @param uid
|
||||
* @return
|
||||
*/
|
||||
public synchronized GameItem getItemByUid(int uid) {
|
||||
return this.getItems().get(uid);
|
||||
}
|
||||
|
||||
public synchronized GameItem getMaterialByItemId(int id) {
|
||||
return this.getInventoryTab(ItemMainType.Material).getItemById(id);
|
||||
return this.getTab(InventoryTabType.MATERIAL).getItemById(id);
|
||||
}
|
||||
|
||||
public GameItem getItemByParam(ItemParam param) {
|
||||
@@ -146,8 +156,12 @@ public class Inventory extends BasePlayerManager {
|
||||
}
|
||||
|
||||
public List<GameItem> addItemParams(Collection<ItemParam> params) {
|
||||
return addItemParams(params, 1);
|
||||
}
|
||||
|
||||
public List<GameItem> addItemParams(Collection<ItemParam> params, int modifier) {
|
||||
// TODO handle params if they are equipment or relics
|
||||
List<GameItem> items = params.stream().map(param -> new GameItem(param.getId(), param.getCount())).toList();
|
||||
List<GameItem> items = params.stream().map(param -> new GameItem(param.getId(), param.getCount() * modifier)).toList();
|
||||
return addItems(items, false);
|
||||
}
|
||||
|
||||
@@ -160,7 +174,7 @@ public class Inventory extends BasePlayerManager {
|
||||
// Add item to inventory store
|
||||
ItemMainType type = item.getExcel().getItemMainType();
|
||||
ItemSubType subType = item.getExcel().getItemSubType();
|
||||
InventoryTab tab = getInventoryTab(type);
|
||||
InventoryTab tab = getTabByItemType(type);
|
||||
|
||||
// Add
|
||||
switch (type) {
|
||||
@@ -188,12 +202,17 @@ public class Inventory extends BasePlayerManager {
|
||||
}
|
||||
return null;
|
||||
case Usable:
|
||||
// Add head icon
|
||||
if (subType == ItemSubType.HeadIcon) {
|
||||
getPlayer().addHeadIcon(item.getItemId());
|
||||
return item;
|
||||
}
|
||||
return null;
|
||||
case Material:
|
||||
|
||||
// Skip if not food item
|
||||
if (subType != ItemSubType.Food) {
|
||||
return null;
|
||||
}
|
||||
default:
|
||||
if (tab == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -216,8 +235,6 @@ public class Inventory extends BasePlayerManager {
|
||||
existingItem.save();
|
||||
return existingItem;
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,7 +385,7 @@ public class Inventory extends BasePlayerManager {
|
||||
// Remove from inventory tab too
|
||||
InventoryTab tab = null;
|
||||
if (item.getExcel() != null) {
|
||||
tab = getInventoryTab(item.getExcel().getItemMainType());
|
||||
tab = getTabByItemType(item.getExcel().getItemMainType());
|
||||
|
||||
if (tab != null) {
|
||||
tab.onRemoveItem(item);
|
||||
@@ -428,20 +445,37 @@ public class Inventory extends BasePlayerManager {
|
||||
|
||||
// Use item
|
||||
|
||||
public List<GameItem> useItem(int itemId, int count, int baseAvatarId) {
|
||||
// Verify that the player actually has the item
|
||||
GameItem useItem = this.getMaterialByItemId(itemId);
|
||||
if (useItem == null || useItem.getCount() < count) {
|
||||
public List<GameItem> useItem(int itemId, int count, int avatarId) {
|
||||
// Sanity
|
||||
if (count <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Remove item from inventory
|
||||
this.removeItem(useItem, count);
|
||||
// Verify that the player actually has the item
|
||||
GameItem useItem = this.getMaterialByItemId(itemId);
|
||||
if (useItem == null || useItem.getCount() < count || useItem.getExcel().getUseMethod() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Use the item now
|
||||
// Get use excel
|
||||
var itemUseExcel = GameData.getItemUseExcelMap().get(useItem.getExcel().getUseDataID());
|
||||
if (itemUseExcel == null) return null;
|
||||
|
||||
// Setup variables
|
||||
boolean usedItem = false;
|
||||
|
||||
// Handle item useMethod
|
||||
// TODO write better handler for this later
|
||||
if (itemId == 201) {
|
||||
this.getPlayer().addStamina(60 * count);
|
||||
usedItem = switch (useItem.getExcel().getUseMethod()) {
|
||||
case FixedRewardGift -> ItemUseHandler.handleFixedRewardGift(getPlayer(), itemUseExcel, avatarId, count);
|
||||
case TeamSpecificFoodBenefit -> ItemUseHandler.handleTeamSpecificFoodBenefit(getPlayer(), itemUseExcel, avatarId, count);
|
||||
case ExternalSystemFoodBenefit -> ItemUseHandler.handleExternalSystemFoodBenefit(getPlayer(), itemUseExcel, avatarId, count);
|
||||
default -> false;
|
||||
};
|
||||
|
||||
// Remove item from inventory if we used it
|
||||
if (usedItem) {
|
||||
this.removeItem(useItem, count);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -498,7 +532,7 @@ public class Inventory extends BasePlayerManager {
|
||||
item.setExcel(excel);
|
||||
|
||||
// Put in inventory
|
||||
InventoryTab tab = getInventoryTab(item.getExcel().getItemMainType());
|
||||
InventoryTab tab = getTabByItemType(item.getExcel().getItemMainType());
|
||||
putItem(item, tab);
|
||||
|
||||
// Equip to a character if possible
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user