mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-01-25 13:13:06 +08:00
Fix player fields not being set
line seps r weird
This commit is contained in:
parent
5e56b5e3a8
commit
06cbae31fa
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,135 +1,135 @@
|
||||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: UgcType.proto
|
||||
|
||||
package emu.grasscutter.net.proto;
|
||||
|
||||
public final class UgcTypeOuterClass {
|
||||
private UgcTypeOuterClass() {}
|
||||
|
||||
public static void registerAllExtensions(com.google.protobuf.ExtensionRegistryLite registry) {}
|
||||
|
||||
public static void registerAllExtensions(com.google.protobuf.ExtensionRegistry registry) {
|
||||
registerAllExtensions((com.google.protobuf.ExtensionRegistryLite) registry);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* 3.2
|
||||
* </pre>
|
||||
*
|
||||
* Protobuf enum {@code UgcType}
|
||||
*/
|
||||
public enum UgcType implements com.google.protobuf.ProtocolMessageEnum {
|
||||
/** <code>UGC_TYPE_NONE = 0;</code> */
|
||||
UGC_TYPE_NONE(0),
|
||||
/** <code>UGC_TYPE_MUSIC_GAME = 1;</code> */
|
||||
UGC_TYPE_MUSIC_GAME(1),
|
||||
UNRECOGNIZED(-1),
|
||||
;
|
||||
|
||||
/** <code>UGC_TYPE_NONE = 0;</code> */
|
||||
public static final int UGC_TYPE_NONE_VALUE = 0;
|
||||
/** <code>UGC_TYPE_MUSIC_GAME = 1;</code> */
|
||||
public static final int UGC_TYPE_MUSIC_GAME_VALUE = 1;
|
||||
|
||||
public final int getNumber() {
|
||||
if (this == UNRECOGNIZED) {
|
||||
throw new java.lang.IllegalArgumentException(
|
||||
"Can't get the number of an unknown enum value.");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value The numeric wire value of the corresponding enum entry.
|
||||
* @return The enum associated with the given numeric wire value.
|
||||
* @deprecated Use {@link #forNumber(int)} instead.
|
||||
*/
|
||||
@java.lang.Deprecated
|
||||
public static UgcType valueOf(int value) {
|
||||
return forNumber(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value The numeric wire value of the corresponding enum entry.
|
||||
* @return The enum associated with the given numeric wire value.
|
||||
*/
|
||||
public static UgcType forNumber(int value) {
|
||||
switch (value) {
|
||||
case 0:
|
||||
return UGC_TYPE_NONE;
|
||||
case 1:
|
||||
return UGC_TYPE_MUSIC_GAME;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static com.google.protobuf.Internal.EnumLiteMap<UgcType> internalGetValueMap() {
|
||||
return internalValueMap;
|
||||
}
|
||||
|
||||
private static final com.google.protobuf.Internal.EnumLiteMap<UgcType> internalValueMap =
|
||||
new com.google.protobuf.Internal.EnumLiteMap<UgcType>() {
|
||||
public UgcType findValueByNumber(int number) {
|
||||
return UgcType.forNumber(number);
|
||||
}
|
||||
};
|
||||
|
||||
public final com.google.protobuf.Descriptors.EnumValueDescriptor getValueDescriptor() {
|
||||
if (this == UNRECOGNIZED) {
|
||||
throw new java.lang.IllegalStateException(
|
||||
"Can't get the descriptor of an unrecognized enum value.");
|
||||
}
|
||||
return getDescriptor().getValues().get(ordinal());
|
||||
}
|
||||
|
||||
public final com.google.protobuf.Descriptors.EnumDescriptor getDescriptorForType() {
|
||||
return getDescriptor();
|
||||
}
|
||||
|
||||
public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() {
|
||||
return emu.grasscutter.net.proto.UgcTypeOuterClass.getDescriptor().getEnumTypes().get(0);
|
||||
}
|
||||
|
||||
private static final UgcType[] VALUES = values();
|
||||
|
||||
public static UgcType valueOf(com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
|
||||
if (desc.getType() != getDescriptor()) {
|
||||
throw new java.lang.IllegalArgumentException("EnumValueDescriptor is not for this type.");
|
||||
}
|
||||
if (desc.getIndex() == -1) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
return VALUES[desc.getIndex()];
|
||||
}
|
||||
|
||||
private final int value;
|
||||
|
||||
private UgcType(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(enum_scope:UgcType)
|
||||
}
|
||||
|
||||
public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
private static com.google.protobuf.Descriptors.FileDescriptor descriptor;
|
||||
|
||||
static {
|
||||
java.lang.String[] descriptorData = {
|
||||
"\n\rUgcType.proto*5\n\007UgcType\022\021\n\rUGC_TYPE_N"
|
||||
+ "ONE\020\000\022\027\n\023UGC_TYPE_MUSIC_GAME\020\001B\033\n\031emu.gr"
|
||||
+ "asscutter.net.protob\006proto3"
|
||||
};
|
||||
descriptor =
|
||||
com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom(
|
||||
descriptorData, new com.google.protobuf.Descriptors.FileDescriptor[] {});
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(outer_class_scope)
|
||||
}
|
||||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: UgcType.proto
|
||||
|
||||
package emu.grasscutter.net.proto;
|
||||
|
||||
public final class UgcTypeOuterClass {
|
||||
private UgcTypeOuterClass() {}
|
||||
|
||||
public static void registerAllExtensions(com.google.protobuf.ExtensionRegistryLite registry) {}
|
||||
|
||||
public static void registerAllExtensions(com.google.protobuf.ExtensionRegistry registry) {
|
||||
registerAllExtensions((com.google.protobuf.ExtensionRegistryLite) registry);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* 3.2
|
||||
* </pre>
|
||||
*
|
||||
* Protobuf enum {@code UgcType}
|
||||
*/
|
||||
public enum UgcType implements com.google.protobuf.ProtocolMessageEnum {
|
||||
/** <code>UGC_TYPE_NONE = 0;</code> */
|
||||
UGC_TYPE_NONE(0),
|
||||
/** <code>UGC_TYPE_MUSIC_GAME = 1;</code> */
|
||||
UGC_TYPE_MUSIC_GAME(1),
|
||||
UNRECOGNIZED(-1),
|
||||
;
|
||||
|
||||
/** <code>UGC_TYPE_NONE = 0;</code> */
|
||||
public static final int UGC_TYPE_NONE_VALUE = 0;
|
||||
/** <code>UGC_TYPE_MUSIC_GAME = 1;</code> */
|
||||
public static final int UGC_TYPE_MUSIC_GAME_VALUE = 1;
|
||||
|
||||
public final int getNumber() {
|
||||
if (this == UNRECOGNIZED) {
|
||||
throw new java.lang.IllegalArgumentException(
|
||||
"Can't get the number of an unknown enum value.");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value The numeric wire value of the corresponding enum entry.
|
||||
* @return The enum associated with the given numeric wire value.
|
||||
* @deprecated Use {@link #forNumber(int)} instead.
|
||||
*/
|
||||
@java.lang.Deprecated
|
||||
public static UgcType valueOf(int value) {
|
||||
return forNumber(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value The numeric wire value of the corresponding enum entry.
|
||||
* @return The enum associated with the given numeric wire value.
|
||||
*/
|
||||
public static UgcType forNumber(int value) {
|
||||
switch (value) {
|
||||
case 0:
|
||||
return UGC_TYPE_NONE;
|
||||
case 1:
|
||||
return UGC_TYPE_MUSIC_GAME;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static com.google.protobuf.Internal.EnumLiteMap<UgcType> internalGetValueMap() {
|
||||
return internalValueMap;
|
||||
}
|
||||
|
||||
private static final com.google.protobuf.Internal.EnumLiteMap<UgcType> internalValueMap =
|
||||
new com.google.protobuf.Internal.EnumLiteMap<UgcType>() {
|
||||
public UgcType findValueByNumber(int number) {
|
||||
return UgcType.forNumber(number);
|
||||
}
|
||||
};
|
||||
|
||||
public final com.google.protobuf.Descriptors.EnumValueDescriptor getValueDescriptor() {
|
||||
if (this == UNRECOGNIZED) {
|
||||
throw new java.lang.IllegalStateException(
|
||||
"Can't get the descriptor of an unrecognized enum value.");
|
||||
}
|
||||
return getDescriptor().getValues().get(ordinal());
|
||||
}
|
||||
|
||||
public final com.google.protobuf.Descriptors.EnumDescriptor getDescriptorForType() {
|
||||
return getDescriptor();
|
||||
}
|
||||
|
||||
public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() {
|
||||
return emu.grasscutter.net.proto.UgcTypeOuterClass.getDescriptor().getEnumTypes().get(0);
|
||||
}
|
||||
|
||||
private static final UgcType[] VALUES = values();
|
||||
|
||||
public static UgcType valueOf(com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
|
||||
if (desc.getType() != getDescriptor()) {
|
||||
throw new java.lang.IllegalArgumentException("EnumValueDescriptor is not for this type.");
|
||||
}
|
||||
if (desc.getIndex() == -1) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
return VALUES[desc.getIndex()];
|
||||
}
|
||||
|
||||
private final int value;
|
||||
|
||||
private UgcType(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(enum_scope:UgcType)
|
||||
}
|
||||
|
||||
public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
private static com.google.protobuf.Descriptors.FileDescriptor descriptor;
|
||||
|
||||
static {
|
||||
java.lang.String[] descriptorData = {
|
||||
"\n\rUgcType.proto*5\n\007UgcType\022\021\n\rUGC_TYPE_N"
|
||||
+ "ONE\020\000\022\027\n\023UGC_TYPE_MUSIC_GAME\020\001B\033\n\031emu.gr"
|
||||
+ "asscutter.net.protob\006proto3"
|
||||
};
|
||||
descriptor =
|
||||
com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom(
|
||||
descriptorData, new com.google.protobuf.Descriptors.FileDescriptor[] {});
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(outer_class_scope)
|
||||
}
|
||||
|
@ -1,35 +1,35 @@
|
||||
package emu.grasscutter;
|
||||
|
||||
import emu.grasscutter.utils.Position;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class GameConstants {
|
||||
public static final int DEFAULT_TEAMS = 4;
|
||||
public static final int MAX_TEAMS = 10;
|
||||
public static final int MAIN_CHARACTER_MALE = 10000005;
|
||||
public static final int MAIN_CHARACTER_FEMALE = 10000007;
|
||||
public static final Position START_POSITION = new Position(2747, 194, -1719);
|
||||
public static final int MAX_FRIENDS = 60;
|
||||
public static final int MAX_FRIEND_REQUESTS = 50;
|
||||
public static final int SERVER_CONSOLE_UID = 99; // The UID of the server console's "player".
|
||||
public static final int BATTLE_PASS_MAX_LEVEL = 50;
|
||||
public static final int BATTLE_PASS_POINT_PER_LEVEL = 1000;
|
||||
public static final int BATTLE_PASS_POINT_PER_WEEK = 10000;
|
||||
public static final int BATTLE_PASS_LEVEL_PRICE = 150;
|
||||
public static final int BATTLE_PASS_CURRENT_INDEX = 2;
|
||||
// Default entity ability hashes.
|
||||
public static final String[] DEFAULT_ABILITY_STRINGS = {
|
||||
"Avatar_DefaultAbility_VisionReplaceDieInvincible",
|
||||
"Avatar_DefaultAbility_AvartarInShaderChange",
|
||||
"Avatar_SprintBS_Invincible",
|
||||
"Avatar_Freeze_Duration_Reducer",
|
||||
"Avatar_Attack_ReviveEnergy",
|
||||
"Avatar_Component_Initializer",
|
||||
"Avatar_FallAnthem_Achievement_Listener"
|
||||
};
|
||||
public static final int[] DEFAULT_ABILITY_HASHES =
|
||||
Arrays.stream(DEFAULT_ABILITY_STRINGS).mapToInt(Utils::abilityHash).toArray();
|
||||
public static final int DEFAULT_ABILITY_NAME = Utils.abilityHash("Default");
|
||||
public static String VERSION = "3.5.0";
|
||||
}
|
||||
package emu.grasscutter;
|
||||
|
||||
import emu.grasscutter.utils.Position;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class GameConstants {
|
||||
public static final int DEFAULT_TEAMS = 4;
|
||||
public static final int MAX_TEAMS = 10;
|
||||
public static final int MAIN_CHARACTER_MALE = 10000005;
|
||||
public static final int MAIN_CHARACTER_FEMALE = 10000007;
|
||||
public static final Position START_POSITION = new Position(2747, 194, -1719);
|
||||
public static final int MAX_FRIENDS = 60;
|
||||
public static final int MAX_FRIEND_REQUESTS = 50;
|
||||
public static final int SERVER_CONSOLE_UID = 99; // The UID of the server console's "player".
|
||||
public static final int BATTLE_PASS_MAX_LEVEL = 50;
|
||||
public static final int BATTLE_PASS_POINT_PER_LEVEL = 1000;
|
||||
public static final int BATTLE_PASS_POINT_PER_WEEK = 10000;
|
||||
public static final int BATTLE_PASS_LEVEL_PRICE = 150;
|
||||
public static final int BATTLE_PASS_CURRENT_INDEX = 2;
|
||||
// Default entity ability hashes.
|
||||
public static final String[] DEFAULT_ABILITY_STRINGS = {
|
||||
"Avatar_DefaultAbility_VisionReplaceDieInvincible",
|
||||
"Avatar_DefaultAbility_AvartarInShaderChange",
|
||||
"Avatar_SprintBS_Invincible",
|
||||
"Avatar_Freeze_Duration_Reducer",
|
||||
"Avatar_Attack_ReviveEnergy",
|
||||
"Avatar_Component_Initializer",
|
||||
"Avatar_FallAnthem_Achievement_Listener"
|
||||
};
|
||||
public static final int[] DEFAULT_ABILITY_HASHES =
|
||||
Arrays.stream(DEFAULT_ABILITY_STRINGS).mapToInt(Utils::abilityHash).toArray();
|
||||
public static final int DEFAULT_ABILITY_NAME = Utils.abilityHash("Default");
|
||||
public static String VERSION = "3.5.0";
|
||||
}
|
||||
|
@ -1,322 +1,322 @@
|
||||
package emu.grasscutter;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.SERVER;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import emu.grasscutter.auth.AuthenticationSystem;
|
||||
import emu.grasscutter.auth.DefaultAuthentication;
|
||||
import emu.grasscutter.command.CommandMap;
|
||||
import emu.grasscutter.command.DefaultPermissionHandler;
|
||||
import emu.grasscutter.command.PermissionHandler;
|
||||
import emu.grasscutter.config.ConfigContainer;
|
||||
import emu.grasscutter.data.ResourceLoader;
|
||||
import emu.grasscutter.database.DatabaseManager;
|
||||
import emu.grasscutter.plugin.PluginManager;
|
||||
import emu.grasscutter.plugin.api.ServerHook;
|
||||
import emu.grasscutter.scripts.ScriptLoader;
|
||||
import emu.grasscutter.server.game.GameServer;
|
||||
import emu.grasscutter.server.http.HttpServer;
|
||||
import emu.grasscutter.server.http.dispatch.DispatchHandler;
|
||||
import emu.grasscutter.server.http.dispatch.RegionHandler;
|
||||
import emu.grasscutter.server.http.documentation.DocumentationServerHandler;
|
||||
import emu.grasscutter.server.http.handlers.AnnouncementsHandler;
|
||||
import emu.grasscutter.server.http.handlers.GachaHandler;
|
||||
import emu.grasscutter.server.http.handlers.GenericHandler;
|
||||
import emu.grasscutter.server.http.handlers.LogHandler;
|
||||
import emu.grasscutter.tools.Tools;
|
||||
import emu.grasscutter.utils.*;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOError;
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.jline.reader.EndOfFileException;
|
||||
import org.jline.reader.LineReader;
|
||||
import org.jline.reader.LineReaderBuilder;
|
||||
import org.jline.reader.UserInterruptException;
|
||||
import org.jline.terminal.Terminal;
|
||||
import org.jline.terminal.TerminalBuilder;
|
||||
import org.reflections.Reflections;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public final class Grasscutter {
|
||||
public static final File configFile = new File("./config.json");
|
||||
public static final Reflections reflector = new Reflections("emu.grasscutter");
|
||||
@Getter private static final Logger logger = (Logger) LoggerFactory.getLogger(Grasscutter.class);
|
||||
|
||||
@Getter public static ConfigContainer config;
|
||||
|
||||
@Getter @Setter private static Language language;
|
||||
@Getter @Setter private static String preferredLanguage;
|
||||
|
||||
@Getter private static int currentDayOfWeek;
|
||||
@Setter private static ServerRunMode runModeOverride = null; // Config override for run mode
|
||||
|
||||
@Getter private static HttpServer httpServer;
|
||||
@Getter private static GameServer gameServer;
|
||||
@Getter private static PluginManager pluginManager;
|
||||
@Getter private static CommandMap commandMap;
|
||||
|
||||
@Getter @Setter private static AuthenticationSystem authenticationSystem;
|
||||
@Getter @Setter private static PermissionHandler permissionHandler;
|
||||
|
||||
private static LineReader consoleLineReader = null;
|
||||
|
||||
static {
|
||||
// Declare logback configuration.
|
||||
System.setProperty("logback.configurationFile", "src/main/resources/logback.xml");
|
||||
|
||||
// Disable the MongoDB logger.
|
||||
var mongoLogger = (Logger) LoggerFactory.getLogger("org.mongodb.driver");
|
||||
mongoLogger.setLevel(Level.OFF);
|
||||
|
||||
// Load server configuration.
|
||||
Grasscutter.loadConfig();
|
||||
// Attempt to update configuration.
|
||||
ConfigContainer.updateConfig();
|
||||
|
||||
// Load translation files.
|
||||
Grasscutter.loadLanguage();
|
||||
|
||||
// Check server structure.
|
||||
Utils.startupCheck();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Crypto.loadKeys(); // Load keys from buffers.
|
||||
|
||||
// Parse start-up arguments.
|
||||
if (StartupArguments.parse(args)) {
|
||||
System.exit(0); // Exit early.
|
||||
}
|
||||
|
||||
// Create command map.
|
||||
commandMap = new CommandMap(true);
|
||||
|
||||
// Initialize server.
|
||||
logger.info(translate("messages.status.starting"));
|
||||
logger.info(translate("messages.status.game_version", GameConstants.VERSION));
|
||||
logger.info(translate("messages.status.version", BuildConfig.VERSION, BuildConfig.GIT_HASH));
|
||||
|
||||
// Load all resources.
|
||||
Grasscutter.updateDayOfWeek();
|
||||
ResourceLoader.loadAll();
|
||||
ScriptLoader.init();
|
||||
|
||||
// Generate handbooks.
|
||||
Tools.createGmHandbooks(false);
|
||||
|
||||
// Initialize database.
|
||||
DatabaseManager.initialize();
|
||||
|
||||
// Initialize the default systems.
|
||||
authenticationSystem = new DefaultAuthentication();
|
||||
permissionHandler = new DefaultPermissionHandler();
|
||||
|
||||
// Create server instances.
|
||||
httpServer = new HttpServer();
|
||||
gameServer = new GameServer();
|
||||
// Create a server hook instance with both servers.
|
||||
new ServerHook(gameServer, httpServer);
|
||||
|
||||
// Create plugin manager instance.
|
||||
pluginManager = new PluginManager();
|
||||
// Add HTTP routes after loading plugins.
|
||||
httpServer.addRouter(HttpServer.UnhandledRequestRouter.class);
|
||||
httpServer.addRouter(HttpServer.DefaultRequestRouter.class);
|
||||
httpServer.addRouter(RegionHandler.class);
|
||||
httpServer.addRouter(LogHandler.class);
|
||||
httpServer.addRouter(GenericHandler.class);
|
||||
httpServer.addRouter(AnnouncementsHandler.class);
|
||||
httpServer.addRouter(DispatchHandler.class);
|
||||
httpServer.addRouter(GachaHandler.class);
|
||||
httpServer.addRouter(DocumentationServerHandler.class);
|
||||
|
||||
// Start servers.
|
||||
var runMode = Grasscutter.getRunMode();
|
||||
if (runMode == ServerRunMode.HYBRID) {
|
||||
httpServer.start();
|
||||
gameServer.start();
|
||||
} else if (runMode == ServerRunMode.DISPATCH_ONLY) {
|
||||
httpServer.start();
|
||||
} else if (runMode == ServerRunMode.GAME_ONLY) {
|
||||
gameServer.start();
|
||||
} else {
|
||||
logger.error(translate("messages.status.run_mode_error", runMode));
|
||||
logger.error(translate("messages.status.run_mode_help"));
|
||||
logger.error(translate("messages.status.shutdown"));
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
// Enable all plugins.
|
||||
pluginManager.enablePlugins();
|
||||
|
||||
// Hook into shutdown event.
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(Grasscutter::onShutdown));
|
||||
|
||||
// Open console.
|
||||
Grasscutter.startConsole();
|
||||
}
|
||||
|
||||
/** Server shutdown event. */
|
||||
private static void onShutdown() {
|
||||
// Disable all plugins.
|
||||
if (pluginManager != null) pluginManager.disablePlugins();
|
||||
}
|
||||
|
||||
/*
|
||||
* Methods for the language system component.
|
||||
*/
|
||||
|
||||
public static void loadLanguage() {
|
||||
var locale = config.language.language;
|
||||
language = Language.getLanguage(Utils.getLanguageCode(locale));
|
||||
}
|
||||
|
||||
/*
|
||||
* Methods for the configuration system component.
|
||||
*/
|
||||
|
||||
/** Attempts to load the configuration from a file. */
|
||||
public static void loadConfig() {
|
||||
// Check if config.json exists. If not, we generate a new config.
|
||||
if (!configFile.exists()) {
|
||||
getLogger().info("config.json could not be found. Generating a default configuration ...");
|
||||
config = new ConfigContainer();
|
||||
Grasscutter.saveConfig(config);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the file already exists, we attempt to load it.
|
||||
try {
|
||||
config = JsonUtils.loadToClass(configFile.toPath(), ConfigContainer.class);
|
||||
} catch (Exception exception) {
|
||||
getLogger()
|
||||
.error(
|
||||
"There was an error while trying to load the configuration from config.json. Please make sure that there are no syntax errors. If you want to start with a default configuration, delete your existing config.json.");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the provided server configuration.
|
||||
*
|
||||
* @param config The configuration to save, or null for a new one.
|
||||
*/
|
||||
public static void saveConfig(@Nullable ConfigContainer config) {
|
||||
if (config == null) config = new ConfigContainer();
|
||||
|
||||
try (FileWriter file = new FileWriter(configFile)) {
|
||||
file.write(JsonUtils.encode(config));
|
||||
} catch (IOException ignored) {
|
||||
logger.error("Unable to write to config file.");
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to save config file.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters for the various server components.
|
||||
*/
|
||||
|
||||
public static Language getLanguage(String langCode) {
|
||||
return Language.getLanguage(langCode);
|
||||
}
|
||||
|
||||
public static ServerRunMode getRunMode() {
|
||||
return Grasscutter.runModeOverride != null ? Grasscutter.runModeOverride : SERVER.runMode;
|
||||
}
|
||||
|
||||
public static LineReader getConsole() {
|
||||
if (consoleLineReader == null) {
|
||||
Terminal terminal = null;
|
||||
try {
|
||||
terminal = TerminalBuilder.builder().jna(true).build();
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
// Fallback to a dumb jline terminal.
|
||||
terminal = TerminalBuilder.builder().dumb(true).build();
|
||||
} catch (Exception ignored) {
|
||||
// When dumb is true, build() never throws.
|
||||
}
|
||||
}
|
||||
|
||||
consoleLineReader = LineReaderBuilder.builder().terminal(terminal).build();
|
||||
}
|
||||
|
||||
return consoleLineReader;
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility methods.
|
||||
*/
|
||||
|
||||
public static void updateDayOfWeek() {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
Grasscutter.currentDayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
|
||||
logger.debug("Set day of week to " + currentDayOfWeek);
|
||||
}
|
||||
|
||||
public static void startConsole() {
|
||||
// Console should not start in dispatch only mode.
|
||||
if (SERVER.runMode == ServerRunMode.DISPATCH_ONLY) {
|
||||
logger.info(translate("messages.dispatch.no_commands_error"));
|
||||
return;
|
||||
} else {
|
||||
logger.info(translate("messages.status.done"));
|
||||
}
|
||||
|
||||
String input = null;
|
||||
var isLastInterrupted = false;
|
||||
while (config.server.game.enableConsole) {
|
||||
try {
|
||||
input = consoleLineReader.readLine("> ");
|
||||
} catch (UserInterruptException e) {
|
||||
if (!isLastInterrupted) {
|
||||
isLastInterrupted = true;
|
||||
logger.info("Press Ctrl-C again to shutdown.");
|
||||
continue;
|
||||
} else {
|
||||
Runtime.getRuntime().exit(0);
|
||||
}
|
||||
} catch (EndOfFileException e) {
|
||||
logger.info("EOF detected.");
|
||||
continue;
|
||||
} catch (IOError e) {
|
||||
logger.error("An IO error occurred while trying to read from console.", e);
|
||||
return;
|
||||
}
|
||||
|
||||
isLastInterrupted = false;
|
||||
|
||||
try {
|
||||
commandMap.invoke(null, null, input);
|
||||
} catch (Exception e) {
|
||||
logger.error(translate("messages.game.command_error"), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enums for the configuration.
|
||||
*/
|
||||
|
||||
public enum ServerRunMode {
|
||||
HYBRID,
|
||||
DISPATCH_ONLY,
|
||||
GAME_ONLY
|
||||
}
|
||||
|
||||
public enum ServerDebugMode {
|
||||
ALL,
|
||||
MISSING,
|
||||
WHITELIST,
|
||||
BLACKLIST,
|
||||
NONE
|
||||
}
|
||||
}
|
||||
package emu.grasscutter;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.SERVER;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import emu.grasscutter.auth.AuthenticationSystem;
|
||||
import emu.grasscutter.auth.DefaultAuthentication;
|
||||
import emu.grasscutter.command.CommandMap;
|
||||
import emu.grasscutter.command.DefaultPermissionHandler;
|
||||
import emu.grasscutter.command.PermissionHandler;
|
||||
import emu.grasscutter.config.ConfigContainer;
|
||||
import emu.grasscutter.data.ResourceLoader;
|
||||
import emu.grasscutter.database.DatabaseManager;
|
||||
import emu.grasscutter.plugin.PluginManager;
|
||||
import emu.grasscutter.plugin.api.ServerHook;
|
||||
import emu.grasscutter.scripts.ScriptLoader;
|
||||
import emu.grasscutter.server.game.GameServer;
|
||||
import emu.grasscutter.server.http.HttpServer;
|
||||
import emu.grasscutter.server.http.dispatch.DispatchHandler;
|
||||
import emu.grasscutter.server.http.dispatch.RegionHandler;
|
||||
import emu.grasscutter.server.http.documentation.DocumentationServerHandler;
|
||||
import emu.grasscutter.server.http.handlers.AnnouncementsHandler;
|
||||
import emu.grasscutter.server.http.handlers.GachaHandler;
|
||||
import emu.grasscutter.server.http.handlers.GenericHandler;
|
||||
import emu.grasscutter.server.http.handlers.LogHandler;
|
||||
import emu.grasscutter.tools.Tools;
|
||||
import emu.grasscutter.utils.*;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOError;
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.jline.reader.EndOfFileException;
|
||||
import org.jline.reader.LineReader;
|
||||
import org.jline.reader.LineReaderBuilder;
|
||||
import org.jline.reader.UserInterruptException;
|
||||
import org.jline.terminal.Terminal;
|
||||
import org.jline.terminal.TerminalBuilder;
|
||||
import org.reflections.Reflections;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public final class Grasscutter {
|
||||
public static final File configFile = new File("./config.json");
|
||||
public static final Reflections reflector = new Reflections("emu.grasscutter");
|
||||
@Getter private static final Logger logger = (Logger) LoggerFactory.getLogger(Grasscutter.class);
|
||||
|
||||
@Getter public static ConfigContainer config;
|
||||
|
||||
@Getter @Setter private static Language language;
|
||||
@Getter @Setter private static String preferredLanguage;
|
||||
|
||||
@Getter private static int currentDayOfWeek;
|
||||
@Setter private static ServerRunMode runModeOverride = null; // Config override for run mode
|
||||
|
||||
@Getter private static HttpServer httpServer;
|
||||
@Getter private static GameServer gameServer;
|
||||
@Getter private static PluginManager pluginManager;
|
||||
@Getter private static CommandMap commandMap;
|
||||
|
||||
@Getter @Setter private static AuthenticationSystem authenticationSystem;
|
||||
@Getter @Setter private static PermissionHandler permissionHandler;
|
||||
|
||||
private static LineReader consoleLineReader = null;
|
||||
|
||||
static {
|
||||
// Declare logback configuration.
|
||||
System.setProperty("logback.configurationFile", "src/main/resources/logback.xml");
|
||||
|
||||
// Disable the MongoDB logger.
|
||||
var mongoLogger = (Logger) LoggerFactory.getLogger("org.mongodb.driver");
|
||||
mongoLogger.setLevel(Level.OFF);
|
||||
|
||||
// Load server configuration.
|
||||
Grasscutter.loadConfig();
|
||||
// Attempt to update configuration.
|
||||
ConfigContainer.updateConfig();
|
||||
|
||||
// Load translation files.
|
||||
Grasscutter.loadLanguage();
|
||||
|
||||
// Check server structure.
|
||||
Utils.startupCheck();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Crypto.loadKeys(); // Load keys from buffers.
|
||||
|
||||
// Parse start-up arguments.
|
||||
if (StartupArguments.parse(args)) {
|
||||
System.exit(0); // Exit early.
|
||||
}
|
||||
|
||||
// Create command map.
|
||||
commandMap = new CommandMap(true);
|
||||
|
||||
// Initialize server.
|
||||
logger.info(translate("messages.status.starting"));
|
||||
logger.info(translate("messages.status.game_version", GameConstants.VERSION));
|
||||
logger.info(translate("messages.status.version", BuildConfig.VERSION, BuildConfig.GIT_HASH));
|
||||
|
||||
// Load all resources.
|
||||
Grasscutter.updateDayOfWeek();
|
||||
ResourceLoader.loadAll();
|
||||
ScriptLoader.init();
|
||||
|
||||
// Generate handbooks.
|
||||
Tools.createGmHandbooks(false);
|
||||
|
||||
// Initialize database.
|
||||
DatabaseManager.initialize();
|
||||
|
||||
// Initialize the default systems.
|
||||
authenticationSystem = new DefaultAuthentication();
|
||||
permissionHandler = new DefaultPermissionHandler();
|
||||
|
||||
// Create server instances.
|
||||
httpServer = new HttpServer();
|
||||
gameServer = new GameServer();
|
||||
// Create a server hook instance with both servers.
|
||||
new ServerHook(gameServer, httpServer);
|
||||
|
||||
// Create plugin manager instance.
|
||||
pluginManager = new PluginManager();
|
||||
// Add HTTP routes after loading plugins.
|
||||
httpServer.addRouter(HttpServer.UnhandledRequestRouter.class);
|
||||
httpServer.addRouter(HttpServer.DefaultRequestRouter.class);
|
||||
httpServer.addRouter(RegionHandler.class);
|
||||
httpServer.addRouter(LogHandler.class);
|
||||
httpServer.addRouter(GenericHandler.class);
|
||||
httpServer.addRouter(AnnouncementsHandler.class);
|
||||
httpServer.addRouter(DispatchHandler.class);
|
||||
httpServer.addRouter(GachaHandler.class);
|
||||
httpServer.addRouter(DocumentationServerHandler.class);
|
||||
|
||||
// Start servers.
|
||||
var runMode = Grasscutter.getRunMode();
|
||||
if (runMode == ServerRunMode.HYBRID) {
|
||||
httpServer.start();
|
||||
gameServer.start();
|
||||
} else if (runMode == ServerRunMode.DISPATCH_ONLY) {
|
||||
httpServer.start();
|
||||
} else if (runMode == ServerRunMode.GAME_ONLY) {
|
||||
gameServer.start();
|
||||
} else {
|
||||
logger.error(translate("messages.status.run_mode_error", runMode));
|
||||
logger.error(translate("messages.status.run_mode_help"));
|
||||
logger.error(translate("messages.status.shutdown"));
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
// Enable all plugins.
|
||||
pluginManager.enablePlugins();
|
||||
|
||||
// Hook into shutdown event.
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(Grasscutter::onShutdown));
|
||||
|
||||
// Open console.
|
||||
Grasscutter.startConsole();
|
||||
}
|
||||
|
||||
/** Server shutdown event. */
|
||||
private static void onShutdown() {
|
||||
// Disable all plugins.
|
||||
if (pluginManager != null) pluginManager.disablePlugins();
|
||||
}
|
||||
|
||||
/*
|
||||
* Methods for the language system component.
|
||||
*/
|
||||
|
||||
public static void loadLanguage() {
|
||||
var locale = config.language.language;
|
||||
language = Language.getLanguage(Utils.getLanguageCode(locale));
|
||||
}
|
||||
|
||||
/*
|
||||
* Methods for the configuration system component.
|
||||
*/
|
||||
|
||||
/** Attempts to load the configuration from a file. */
|
||||
public static void loadConfig() {
|
||||
// Check if config.json exists. If not, we generate a new config.
|
||||
if (!configFile.exists()) {
|
||||
getLogger().info("config.json could not be found. Generating a default configuration ...");
|
||||
config = new ConfigContainer();
|
||||
Grasscutter.saveConfig(config);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the file already exists, we attempt to load it.
|
||||
try {
|
||||
config = JsonUtils.loadToClass(configFile.toPath(), ConfigContainer.class);
|
||||
} catch (Exception exception) {
|
||||
getLogger()
|
||||
.error(
|
||||
"There was an error while trying to load the configuration from config.json. Please make sure that there are no syntax errors. If you want to start with a default configuration, delete your existing config.json.");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the provided server configuration.
|
||||
*
|
||||
* @param config The configuration to save, or null for a new one.
|
||||
*/
|
||||
public static void saveConfig(@Nullable ConfigContainer config) {
|
||||
if (config == null) config = new ConfigContainer();
|
||||
|
||||
try (FileWriter file = new FileWriter(configFile)) {
|
||||
file.write(JsonUtils.encode(config));
|
||||
} catch (IOException ignored) {
|
||||
logger.error("Unable to write to config file.");
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to save config file.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters for the various server components.
|
||||
*/
|
||||
|
||||
public static Language getLanguage(String langCode) {
|
||||
return Language.getLanguage(langCode);
|
||||
}
|
||||
|
||||
public static ServerRunMode getRunMode() {
|
||||
return Grasscutter.runModeOverride != null ? Grasscutter.runModeOverride : SERVER.runMode;
|
||||
}
|
||||
|
||||
public static LineReader getConsole() {
|
||||
if (consoleLineReader == null) {
|
||||
Terminal terminal = null;
|
||||
try {
|
||||
terminal = TerminalBuilder.builder().jna(true).build();
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
// Fallback to a dumb jline terminal.
|
||||
terminal = TerminalBuilder.builder().dumb(true).build();
|
||||
} catch (Exception ignored) {
|
||||
// When dumb is true, build() never throws.
|
||||
}
|
||||
}
|
||||
|
||||
consoleLineReader = LineReaderBuilder.builder().terminal(terminal).build();
|
||||
}
|
||||
|
||||
return consoleLineReader;
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility methods.
|
||||
*/
|
||||
|
||||
public static void updateDayOfWeek() {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
Grasscutter.currentDayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
|
||||
logger.debug("Set day of week to " + currentDayOfWeek);
|
||||
}
|
||||
|
||||
public static void startConsole() {
|
||||
// Console should not start in dispatch only mode.
|
||||
if (SERVER.runMode == ServerRunMode.DISPATCH_ONLY) {
|
||||
logger.info(translate("messages.dispatch.no_commands_error"));
|
||||
return;
|
||||
} else {
|
||||
logger.info(translate("messages.status.done"));
|
||||
}
|
||||
|
||||
String input = null;
|
||||
var isLastInterrupted = false;
|
||||
while (config.server.game.enableConsole) {
|
||||
try {
|
||||
input = consoleLineReader.readLine("> ");
|
||||
} catch (UserInterruptException e) {
|
||||
if (!isLastInterrupted) {
|
||||
isLastInterrupted = true;
|
||||
logger.info("Press Ctrl-C again to shutdown.");
|
||||
continue;
|
||||
} else {
|
||||
Runtime.getRuntime().exit(0);
|
||||
}
|
||||
} catch (EndOfFileException e) {
|
||||
logger.info("EOF detected.");
|
||||
continue;
|
||||
} catch (IOError e) {
|
||||
logger.error("An IO error occurred while trying to read from console.", e);
|
||||
return;
|
||||
}
|
||||
|
||||
isLastInterrupted = false;
|
||||
|
||||
try {
|
||||
commandMap.invoke(null, null, input);
|
||||
} catch (Exception e) {
|
||||
logger.error(translate("messages.game.command_error"), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enums for the configuration.
|
||||
*/
|
||||
|
||||
public enum ServerRunMode {
|
||||
HYBRID,
|
||||
DISPATCH_ONLY,
|
||||
GAME_ONLY
|
||||
}
|
||||
|
||||
public enum ServerDebugMode {
|
||||
ALL,
|
||||
MISSING,
|
||||
WHITELIST,
|
||||
BLACKLIST,
|
||||
NONE
|
||||
}
|
||||
}
|
||||
|
@ -1,158 +1,158 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.achievement.AchievementData;
|
||||
import emu.grasscutter.game.achievement.AchievementControlReturns;
|
||||
import emu.grasscutter.game.achievement.Achievements;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Command(
|
||||
label = "achievement",
|
||||
usage = {
|
||||
"(grant|revoke) <achievementId>",
|
||||
"progress <achievementId> <progress>",
|
||||
"grantall",
|
||||
"revokeall"
|
||||
},
|
||||
aliases = {"am"},
|
||||
permission = "player.achievement",
|
||||
permissionTargeted = "player.achievement.others",
|
||||
targetRequirement = Command.TargetRequirement.PLAYER,
|
||||
threading = true)
|
||||
public final class AchievementCommand implements CommandHandler {
|
||||
private static void sendSuccessMessage(Player sender, String cmd, Object... args) {
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, AchievementControlReturns.Return.SUCCESS.getKey() + cmd, args);
|
||||
}
|
||||
|
||||
private static Optional<Integer> parseInt(String s) {
|
||||
try {
|
||||
return Optional.of(Integer.parseInt(s));
|
||||
} catch (NumberFormatException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private static void grantAll(Player sender, Player targetPlayer, Achievements achievements) {
|
||||
var counter = new AtomicInteger();
|
||||
GameData.getAchievementDataMap().values().stream()
|
||||
.filter(AchievementData::isUsed)
|
||||
.filter(AchievementData::isParent)
|
||||
.forEach(
|
||||
data -> {
|
||||
var success = achievements.grant(data.getId());
|
||||
if (success.getRet() == AchievementControlReturns.Return.SUCCESS) {
|
||||
counter.addAndGet(success.getChangedAchievementStatusNum());
|
||||
}
|
||||
});
|
||||
|
||||
sendSuccessMessage(sender, "grantall", counter.intValue(), targetPlayer.getNickname());
|
||||
}
|
||||
|
||||
private static void revokeAll(Player sender, Player targetPlayer, Achievements achievements) {
|
||||
var counter = new AtomicInteger();
|
||||
GameData.getAchievementDataMap().values().stream()
|
||||
.filter(AchievementData::isUsed)
|
||||
.filter(AchievementData::isParent)
|
||||
.forEach(
|
||||
data -> {
|
||||
var success = achievements.revoke(data.getId());
|
||||
if (success.getRet() == AchievementControlReturns.Return.SUCCESS) {
|
||||
counter.addAndGet(success.getChangedAchievementStatusNum());
|
||||
}
|
||||
});
|
||||
|
||||
sendSuccessMessage(sender, "revokeall", counter.intValue(), targetPlayer.getNickname());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 1) {
|
||||
this.sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
var command = args.remove(0).toLowerCase();
|
||||
var achievements = Achievements.getByPlayer(targetPlayer);
|
||||
switch (command) {
|
||||
case "grant" -> this.grant(sender, targetPlayer, achievements, args);
|
||||
case "revoke" -> this.revoke(sender, targetPlayer, achievements, args);
|
||||
case "progress" -> this.progress(sender, targetPlayer, achievements, args);
|
||||
case "grantall" -> grantAll(sender, targetPlayer, achievements);
|
||||
case "revokeall" -> revokeAll(sender, targetPlayer, achievements);
|
||||
default -> this.sendUsageMessage(sender);
|
||||
}
|
||||
}
|
||||
|
||||
private void grant(
|
||||
Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
|
||||
if (args.size() < 1) {
|
||||
this.sendUsageMessage(sender);
|
||||
}
|
||||
|
||||
parseInt(args.remove(0))
|
||||
.ifPresentOrElse(
|
||||
integer -> {
|
||||
var ret = achievements.grant(integer);
|
||||
switch (ret.getRet()) {
|
||||
case SUCCESS -> sendSuccessMessage(sender, "grant", targetPlayer.getNickname());
|
||||
case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage(
|
||||
sender, ret.getRet().getKey());
|
||||
case ALREADY_ACHIEVED -> CommandHandler.sendTranslatedMessage(
|
||||
sender, ret.getRet().getKey(), targetPlayer.getNickname());
|
||||
}
|
||||
},
|
||||
() -> this.sendUsageMessage(sender));
|
||||
}
|
||||
|
||||
private void revoke(
|
||||
Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
|
||||
if (args.size() < 1) {
|
||||
this.sendUsageMessage(sender);
|
||||
}
|
||||
|
||||
parseInt(args.remove(0))
|
||||
.ifPresentOrElse(
|
||||
integer -> {
|
||||
var ret = achievements.revoke(integer);
|
||||
switch (ret.getRet()) {
|
||||
case SUCCESS -> sendSuccessMessage(sender, "revoke", targetPlayer.getNickname());
|
||||
case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage(
|
||||
sender, ret.getRet().getKey());
|
||||
case NOT_YET_ACHIEVED -> CommandHandler.sendTranslatedMessage(
|
||||
sender, ret.getRet().getKey(), targetPlayer.getNickname());
|
||||
}
|
||||
},
|
||||
() -> this.sendUsageMessage(sender));
|
||||
}
|
||||
|
||||
private void progress(
|
||||
Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
|
||||
if (args.size() < 2) {
|
||||
this.sendUsageMessage(sender);
|
||||
}
|
||||
|
||||
parseInt(args.remove(0))
|
||||
.ifPresentOrElse(
|
||||
integer -> {
|
||||
parseInt(args.remove(0))
|
||||
.ifPresentOrElse(
|
||||
progress -> {
|
||||
var ret = achievements.progress(integer, progress);
|
||||
switch (ret.getRet()) {
|
||||
case SUCCESS -> sendSuccessMessage(
|
||||
sender, "progress", targetPlayer.getNickname(), integer, progress);
|
||||
case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage(
|
||||
sender, ret.getRet().getKey());
|
||||
}
|
||||
},
|
||||
() -> this.sendUsageMessage(sender));
|
||||
},
|
||||
() -> this.sendUsageMessage(sender));
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.achievement.AchievementData;
|
||||
import emu.grasscutter.game.achievement.AchievementControlReturns;
|
||||
import emu.grasscutter.game.achievement.Achievements;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Command(
|
||||
label = "achievement",
|
||||
usage = {
|
||||
"(grant|revoke) <achievementId>",
|
||||
"progress <achievementId> <progress>",
|
||||
"grantall",
|
||||
"revokeall"
|
||||
},
|
||||
aliases = {"am"},
|
||||
permission = "player.achievement",
|
||||
permissionTargeted = "player.achievement.others",
|
||||
targetRequirement = Command.TargetRequirement.PLAYER,
|
||||
threading = true)
|
||||
public final class AchievementCommand implements CommandHandler {
|
||||
private static void sendSuccessMessage(Player sender, String cmd, Object... args) {
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, AchievementControlReturns.Return.SUCCESS.getKey() + cmd, args);
|
||||
}
|
||||
|
||||
private static Optional<Integer> parseInt(String s) {
|
||||
try {
|
||||
return Optional.of(Integer.parseInt(s));
|
||||
} catch (NumberFormatException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private static void grantAll(Player sender, Player targetPlayer, Achievements achievements) {
|
||||
var counter = new AtomicInteger();
|
||||
GameData.getAchievementDataMap().values().stream()
|
||||
.filter(AchievementData::isUsed)
|
||||
.filter(AchievementData::isParent)
|
||||
.forEach(
|
||||
data -> {
|
||||
var success = achievements.grant(data.getId());
|
||||
if (success.getRet() == AchievementControlReturns.Return.SUCCESS) {
|
||||
counter.addAndGet(success.getChangedAchievementStatusNum());
|
||||
}
|
||||
});
|
||||
|
||||
sendSuccessMessage(sender, "grantall", counter.intValue(), targetPlayer.getNickname());
|
||||
}
|
||||
|
||||
private static void revokeAll(Player sender, Player targetPlayer, Achievements achievements) {
|
||||
var counter = new AtomicInteger();
|
||||
GameData.getAchievementDataMap().values().stream()
|
||||
.filter(AchievementData::isUsed)
|
||||
.filter(AchievementData::isParent)
|
||||
.forEach(
|
||||
data -> {
|
||||
var success = achievements.revoke(data.getId());
|
||||
if (success.getRet() == AchievementControlReturns.Return.SUCCESS) {
|
||||
counter.addAndGet(success.getChangedAchievementStatusNum());
|
||||
}
|
||||
});
|
||||
|
||||
sendSuccessMessage(sender, "revokeall", counter.intValue(), targetPlayer.getNickname());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 1) {
|
||||
this.sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
var command = args.remove(0).toLowerCase();
|
||||
var achievements = Achievements.getByPlayer(targetPlayer);
|
||||
switch (command) {
|
||||
case "grant" -> this.grant(sender, targetPlayer, achievements, args);
|
||||
case "revoke" -> this.revoke(sender, targetPlayer, achievements, args);
|
||||
case "progress" -> this.progress(sender, targetPlayer, achievements, args);
|
||||
case "grantall" -> grantAll(sender, targetPlayer, achievements);
|
||||
case "revokeall" -> revokeAll(sender, targetPlayer, achievements);
|
||||
default -> this.sendUsageMessage(sender);
|
||||
}
|
||||
}
|
||||
|
||||
private void grant(
|
||||
Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
|
||||
if (args.size() < 1) {
|
||||
this.sendUsageMessage(sender);
|
||||
}
|
||||
|
||||
parseInt(args.remove(0))
|
||||
.ifPresentOrElse(
|
||||
integer -> {
|
||||
var ret = achievements.grant(integer);
|
||||
switch (ret.getRet()) {
|
||||
case SUCCESS -> sendSuccessMessage(sender, "grant", targetPlayer.getNickname());
|
||||
case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage(
|
||||
sender, ret.getRet().getKey());
|
||||
case ALREADY_ACHIEVED -> CommandHandler.sendTranslatedMessage(
|
||||
sender, ret.getRet().getKey(), targetPlayer.getNickname());
|
||||
}
|
||||
},
|
||||
() -> this.sendUsageMessage(sender));
|
||||
}
|
||||
|
||||
private void revoke(
|
||||
Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
|
||||
if (args.size() < 1) {
|
||||
this.sendUsageMessage(sender);
|
||||
}
|
||||
|
||||
parseInt(args.remove(0))
|
||||
.ifPresentOrElse(
|
||||
integer -> {
|
||||
var ret = achievements.revoke(integer);
|
||||
switch (ret.getRet()) {
|
||||
case SUCCESS -> sendSuccessMessage(sender, "revoke", targetPlayer.getNickname());
|
||||
case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage(
|
||||
sender, ret.getRet().getKey());
|
||||
case NOT_YET_ACHIEVED -> CommandHandler.sendTranslatedMessage(
|
||||
sender, ret.getRet().getKey(), targetPlayer.getNickname());
|
||||
}
|
||||
},
|
||||
() -> this.sendUsageMessage(sender));
|
||||
}
|
||||
|
||||
private void progress(
|
||||
Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
|
||||
if (args.size() < 2) {
|
||||
this.sendUsageMessage(sender);
|
||||
}
|
||||
|
||||
parseInt(args.remove(0))
|
||||
.ifPresentOrElse(
|
||||
integer -> {
|
||||
parseInt(args.remove(0))
|
||||
.ifPresentOrElse(
|
||||
progress -> {
|
||||
var ret = achievements.progress(integer, progress);
|
||||
switch (ret.getRet()) {
|
||||
case SUCCESS -> sendSuccessMessage(
|
||||
sender, "progress", targetPlayer.getNickname(), integer, progress);
|
||||
case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage(
|
||||
sender, ret.getRet().getKey());
|
||||
}
|
||||
},
|
||||
() -> this.sendUsageMessage(sender));
|
||||
},
|
||||
() -> this.sendUsageMessage(sender));
|
||||
}
|
||||
}
|
||||
|
@ -1,139 +1,139 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.command.CommandHelpers.*;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.entity.*;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ElementType;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.server.event.entity.EntityDamageEvent;
|
||||
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.Setter;
|
||||
|
||||
@Command(
|
||||
label = "entity",
|
||||
usage = {
|
||||
"<configId gadget> [state<state>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>]",
|
||||
"<configId monster> [ai<aiId>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>]"
|
||||
},
|
||||
permission = "server.entity")
|
||||
public final class EntityCommand implements CommandHandler {
|
||||
private static final Map<Pattern, BiConsumer<EntityParameters, Integer>> intCommandHandlers =
|
||||
Map.ofEntries(
|
||||
Map.entry(stateRegex, EntityParameters::setState),
|
||||
Map.entry(maxHPRegex, EntityParameters::setMaxHP),
|
||||
Map.entry(hpRegex, EntityParameters::setHp),
|
||||
Map.entry(defRegex, EntityParameters::setDef),
|
||||
Map.entry(atkRegex, EntityParameters::setAtk),
|
||||
Map.entry(aiRegex, EntityParameters::setAi));
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
EntityParameters param = new EntityParameters();
|
||||
|
||||
parseIntParameters(args, param, intCommandHandlers);
|
||||
|
||||
// At this point, first remaining argument MUST be the id and the rest the pos
|
||||
if (args.size() != 1) {
|
||||
sendUsageMessage(sender); // Reachable if someone does `/give lv90` or similar
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
try {
|
||||
param.configId = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.cfgId"));
|
||||
}
|
||||
|
||||
param.scene = targetPlayer.getScene();
|
||||
var entity = param.scene.getEntityByConfigId(param.configId);
|
||||
|
||||
if (entity == null) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.entity.not_found_error"));
|
||||
return;
|
||||
}
|
||||
applyFightProps(entity, param);
|
||||
applyGadgetParams(entity, param);
|
||||
applyMonsterParams(entity, param);
|
||||
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.status.success"));
|
||||
}
|
||||
|
||||
private void applyGadgetParams(GameEntity entity, EntityParameters param) {
|
||||
if (!(entity instanceof EntityGadget)) {
|
||||
return;
|
||||
}
|
||||
if (param.state != -1) {
|
||||
((EntityGadget) entity).updateState(param.state);
|
||||
}
|
||||
}
|
||||
|
||||
private void applyMonsterParams(GameEntity entity, EntityParameters param) {
|
||||
if (!(entity instanceof EntityMonster)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (param.ai != -1) {
|
||||
((EntityMonster) entity).setAiId(param.ai);
|
||||
// TODO notify
|
||||
}
|
||||
}
|
||||
|
||||
private void applyFightProps(GameEntity entity, EntityParameters param) {
|
||||
var changedFields = new ArrayList<FightProperty>();
|
||||
if (param.maxHP != -1) {
|
||||
setFightProperty(entity, FightProperty.FIGHT_PROP_MAX_HP, param.maxHP, changedFields);
|
||||
}
|
||||
if (param.hp != -1) {
|
||||
float targetHp = param.hp == 0 ? Float.MAX_VALUE : param.hp;
|
||||
float oldHp = entity.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP);
|
||||
setFightProperty(entity, FightProperty.FIGHT_PROP_CUR_HP, targetHp, changedFields);
|
||||
EntityDamageEvent event =
|
||||
new EntityDamageEvent(entity, oldHp - targetHp, ElementType.None, null);
|
||||
callHPEvents(entity, event);
|
||||
}
|
||||
if (param.atk != -1) {
|
||||
setFightProperty(entity, FightProperty.FIGHT_PROP_ATTACK, param.atk, changedFields);
|
||||
setFightProperty(entity, FightProperty.FIGHT_PROP_CUR_ATTACK, param.atk, changedFields);
|
||||
}
|
||||
if (param.def != -1) {
|
||||
setFightProperty(entity, FightProperty.FIGHT_PROP_DEFENSE, param.def, changedFields);
|
||||
setFightProperty(entity, FightProperty.FIGHT_PROP_CUR_DEFENSE, param.def, changedFields);
|
||||
}
|
||||
if (!changedFields.isEmpty()) {
|
||||
entity
|
||||
.getScene()
|
||||
.broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, changedFields));
|
||||
}
|
||||
}
|
||||
|
||||
private void callHPEvents(GameEntity entity, EntityDamageEvent event) {
|
||||
entity.runLuaCallbacks(event);
|
||||
}
|
||||
|
||||
private void setFightProperty(
|
||||
GameEntity entity, FightProperty property, float value, List<FightProperty> modifiedProps) {
|
||||
entity.setFightProperty(property, value);
|
||||
modifiedProps.add(property);
|
||||
}
|
||||
|
||||
private static class EntityParameters {
|
||||
@Setter public int configId = -1;
|
||||
@Setter public int state = -1;
|
||||
@Setter public int hp = -1;
|
||||
@Setter public int maxHP = -1;
|
||||
@Setter public int atk = -1;
|
||||
@Setter public int def = -1;
|
||||
@Setter public int ai = -1;
|
||||
public Scene scene = null;
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.command.CommandHelpers.*;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.entity.*;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ElementType;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.server.event.entity.EntityDamageEvent;
|
||||
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.Setter;
|
||||
|
||||
@Command(
|
||||
label = "entity",
|
||||
usage = {
|
||||
"<configId gadget> [state<state>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>]",
|
||||
"<configId monster> [ai<aiId>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>]"
|
||||
},
|
||||
permission = "server.entity")
|
||||
public final class EntityCommand implements CommandHandler {
|
||||
private static final Map<Pattern, BiConsumer<EntityParameters, Integer>> intCommandHandlers =
|
||||
Map.ofEntries(
|
||||
Map.entry(stateRegex, EntityParameters::setState),
|
||||
Map.entry(maxHPRegex, EntityParameters::setMaxHP),
|
||||
Map.entry(hpRegex, EntityParameters::setHp),
|
||||
Map.entry(defRegex, EntityParameters::setDef),
|
||||
Map.entry(atkRegex, EntityParameters::setAtk),
|
||||
Map.entry(aiRegex, EntityParameters::setAi));
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
EntityParameters param = new EntityParameters();
|
||||
|
||||
parseIntParameters(args, param, intCommandHandlers);
|
||||
|
||||
// At this point, first remaining argument MUST be the id and the rest the pos
|
||||
if (args.size() != 1) {
|
||||
sendUsageMessage(sender); // Reachable if someone does `/give lv90` or similar
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
try {
|
||||
param.configId = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.cfgId"));
|
||||
}
|
||||
|
||||
param.scene = targetPlayer.getScene();
|
||||
var entity = param.scene.getEntityByConfigId(param.configId);
|
||||
|
||||
if (entity == null) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.entity.not_found_error"));
|
||||
return;
|
||||
}
|
||||
applyFightProps(entity, param);
|
||||
applyGadgetParams(entity, param);
|
||||
applyMonsterParams(entity, param);
|
||||
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.status.success"));
|
||||
}
|
||||
|
||||
private void applyGadgetParams(GameEntity entity, EntityParameters param) {
|
||||
if (!(entity instanceof EntityGadget)) {
|
||||
return;
|
||||
}
|
||||
if (param.state != -1) {
|
||||
((EntityGadget) entity).updateState(param.state);
|
||||
}
|
||||
}
|
||||
|
||||
private void applyMonsterParams(GameEntity entity, EntityParameters param) {
|
||||
if (!(entity instanceof EntityMonster)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (param.ai != -1) {
|
||||
((EntityMonster) entity).setAiId(param.ai);
|
||||
// TODO notify
|
||||
}
|
||||
}
|
||||
|
||||
private void applyFightProps(GameEntity entity, EntityParameters param) {
|
||||
var changedFields = new ArrayList<FightProperty>();
|
||||
if (param.maxHP != -1) {
|
||||
setFightProperty(entity, FightProperty.FIGHT_PROP_MAX_HP, param.maxHP, changedFields);
|
||||
}
|
||||
if (param.hp != -1) {
|
||||
float targetHp = param.hp == 0 ? Float.MAX_VALUE : param.hp;
|
||||
float oldHp = entity.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP);
|
||||
setFightProperty(entity, FightProperty.FIGHT_PROP_CUR_HP, targetHp, changedFields);
|
||||
EntityDamageEvent event =
|
||||
new EntityDamageEvent(entity, oldHp - targetHp, ElementType.None, null);
|
||||
callHPEvents(entity, event);
|
||||
}
|
||||
if (param.atk != -1) {
|
||||
setFightProperty(entity, FightProperty.FIGHT_PROP_ATTACK, param.atk, changedFields);
|
||||
setFightProperty(entity, FightProperty.FIGHT_PROP_CUR_ATTACK, param.atk, changedFields);
|
||||
}
|
||||
if (param.def != -1) {
|
||||
setFightProperty(entity, FightProperty.FIGHT_PROP_DEFENSE, param.def, changedFields);
|
||||
setFightProperty(entity, FightProperty.FIGHT_PROP_CUR_DEFENSE, param.def, changedFields);
|
||||
}
|
||||
if (!changedFields.isEmpty()) {
|
||||
entity
|
||||
.getScene()
|
||||
.broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, changedFields));
|
||||
}
|
||||
}
|
||||
|
||||
private void callHPEvents(GameEntity entity, EntityDamageEvent event) {
|
||||
entity.runLuaCallbacks(event);
|
||||
}
|
||||
|
||||
private void setFightProperty(
|
||||
GameEntity entity, FightProperty property, float value, List<FightProperty> modifiedProps) {
|
||||
entity.setFightProperty(property, value);
|
||||
modifiedProps.add(property);
|
||||
}
|
||||
|
||||
private static class EntityParameters {
|
||||
@Setter public int configId = -1;
|
||||
@Setter public int state = -1;
|
||||
@Setter public int hp = -1;
|
||||
@Setter public int maxHP = -1;
|
||||
@Setter public int atk = -1;
|
||||
@Setter public int def = -1;
|
||||
@Setter public int ai = -1;
|
||||
public Scene scene = null;
|
||||
}
|
||||
}
|
||||
|
@ -1,72 +1,72 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.world.SceneGroupInstance;
|
||||
import java.util.List;
|
||||
|
||||
@Command(
|
||||
label = "group",
|
||||
aliases = {"g"},
|
||||
usage = {"(refresh) [<groupId>] [<suiteId>]"},
|
||||
permission = "player.group",
|
||||
permissionTargeted = "player.group.others")
|
||||
public final class GroupCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String cmd = args.remove(0).toLowerCase();
|
||||
|
||||
int groupId = 0;
|
||||
int suiteId = 0;
|
||||
switch (args.size()) {
|
||||
case 2:
|
||||
try {
|
||||
suiteId = Integer.parseInt(args.get(1));
|
||||
} catch (Exception e) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.group.invalid_suiteid"));
|
||||
return;
|
||||
} // Fallthrough
|
||||
case 1:
|
||||
try {
|
||||
groupId = Integer.parseInt(args.get(0));
|
||||
} catch (Exception e) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.group.invalid_groupid"));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case "refresh" -> {
|
||||
SceneGroupInstance groupInstance =
|
||||
targetPlayer.getScene().getScriptManager().getGroupInstanceById(groupId);
|
||||
if (groupInstance == null) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.group.group_not_found", groupId));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.size() >= 2) {
|
||||
targetPlayer.getScene().getScriptManager().refreshGroup(groupInstance, suiteId, false);
|
||||
} else {
|
||||
targetPlayer.getScene().getScriptManager().refreshGroup(groupInstance);
|
||||
}
|
||||
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.group.refreshed", groupId));
|
||||
}
|
||||
default -> {
|
||||
sendUsageMessage(sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.world.SceneGroupInstance;
|
||||
import java.util.List;
|
||||
|
||||
@Command(
|
||||
label = "group",
|
||||
aliases = {"g"},
|
||||
usage = {"(refresh) [<groupId>] [<suiteId>]"},
|
||||
permission = "player.group",
|
||||
permissionTargeted = "player.group.others")
|
||||
public final class GroupCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String cmd = args.remove(0).toLowerCase();
|
||||
|
||||
int groupId = 0;
|
||||
int suiteId = 0;
|
||||
switch (args.size()) {
|
||||
case 2:
|
||||
try {
|
||||
suiteId = Integer.parseInt(args.get(1));
|
||||
} catch (Exception e) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.group.invalid_suiteid"));
|
||||
return;
|
||||
} // Fallthrough
|
||||
case 1:
|
||||
try {
|
||||
groupId = Integer.parseInt(args.get(0));
|
||||
} catch (Exception e) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.group.invalid_groupid"));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case "refresh" -> {
|
||||
SceneGroupInstance groupInstance =
|
||||
targetPlayer.getScene().getScriptManager().getGroupInstanceById(groupId);
|
||||
if (groupInstance == null) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.group.group_not_found", groupId));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.size() >= 2) {
|
||||
targetPlayer.getScene().getScriptManager().refreshGroup(groupInstance, suiteId, false);
|
||||
} else {
|
||||
targetPlayer.getScene().getScriptManager().refreshGroup(groupInstance);
|
||||
}
|
||||
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.group.refreshed", groupId));
|
||||
}
|
||||
default -> {
|
||||
sendUsageMessage(sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,279 +1,279 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.PlayerProperty;
|
||||
import emu.grasscutter.game.tower.TowerLevelRecord;
|
||||
import emu.grasscutter.server.packet.send.PacketOpenStateChangeNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneAreaUnlockNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketScenePointUnlockNotify;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Command(
|
||||
label = "setProp",
|
||||
aliases = {"prop"},
|
||||
usage = {"<prop> <value>"},
|
||||
permission = "player.setprop",
|
||||
permissionTargeted = "player.setprop.others")
|
||||
public final class SetPropCommand implements CommandHandler {
|
||||
// List of map areas. Unfortunately, there is no readily available source for them in excels or
|
||||
// bins.
|
||||
private static final List<Integer> sceneAreas =
|
||||
List.of(
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
|
||||
28, 29, 32, 100, 101, 102, 103, 200, 210, 300, 400, 401, 402, 403);
|
||||
Map<String, Prop> props;
|
||||
|
||||
public SetPropCommand() {
|
||||
this.props = new HashMap<>();
|
||||
// Full PlayerProperty enum that won't be advertised but can be used by devs
|
||||
for (PlayerProperty prop : PlayerProperty.values()) {
|
||||
String name = prop.toString().substring(5); // PROP_EXP -> EXP
|
||||
String key = name.toLowerCase(); // EXP -> exp
|
||||
this.props.put(key, new Prop(name, prop));
|
||||
}
|
||||
// Add special props
|
||||
Prop worldlevel =
|
||||
new Prop("World Level", PlayerProperty.PROP_PLAYER_WORLD_LEVEL, PseudoProp.WORLD_LEVEL);
|
||||
this.props.put("worldlevel", worldlevel);
|
||||
this.props.put("wl", worldlevel);
|
||||
|
||||
Prop abyss = new Prop("Tower Level", PseudoProp.TOWER_LEVEL);
|
||||
this.props.put("abyss", abyss);
|
||||
this.props.put("abyssfloor", abyss);
|
||||
this.props.put("ut", abyss);
|
||||
this.props.put("tower", abyss);
|
||||
this.props.put("towerlevel", abyss);
|
||||
this.props.put("unlocktower", abyss);
|
||||
|
||||
Prop bplevel = new Prop("BP Level", PseudoProp.BP_LEVEL);
|
||||
this.props.put("bplevel", bplevel);
|
||||
this.props.put("bp", bplevel);
|
||||
this.props.put("battlepass", bplevel);
|
||||
|
||||
Prop godmode = new Prop("GodMode", PseudoProp.GOD_MODE);
|
||||
this.props.put("godmode", godmode);
|
||||
this.props.put("god", godmode);
|
||||
|
||||
Prop nostamina = new Prop("UnlimitedStamina", PseudoProp.UNLIMITED_STAMINA);
|
||||
this.props.put("unlimitedstamina", nostamina);
|
||||
this.props.put("us", nostamina);
|
||||
this.props.put("nostamina", nostamina);
|
||||
this.props.put("nostam", nostamina);
|
||||
this.props.put("ns", nostamina);
|
||||
|
||||
Prop unlimitedenergy = new Prop("UnlimitedEnergy", PseudoProp.UNLIMITED_ENERGY);
|
||||
this.props.put("unlimitedenergy", unlimitedenergy);
|
||||
this.props.put("ue", unlimitedenergy);
|
||||
|
||||
Prop setopenstate = new Prop("SetOpenstate", PseudoProp.SET_OPENSTATE);
|
||||
this.props.put("setopenstate", setopenstate);
|
||||
this.props.put("so", setopenstate);
|
||||
|
||||
Prop unsetopenstate = new Prop("UnsetOpenstate", PseudoProp.UNSET_OPENSTATE);
|
||||
this.props.put("unsetopenstate", unsetopenstate);
|
||||
this.props.put("uo", unsetopenstate);
|
||||
|
||||
Prop unlockmap = new Prop("UnlockMap", PseudoProp.UNLOCK_MAP);
|
||||
this.props.put("unlockmap", unlockmap);
|
||||
this.props.put("um", unlockmap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() != 2) {
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
String propStr = args.get(0).toLowerCase();
|
||||
String valueStr = args.get(1).toLowerCase();
|
||||
int value;
|
||||
|
||||
if (!props.containsKey(propStr)) {
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
value =
|
||||
switch (valueStr.toLowerCase()) {
|
||||
case "on", "true" -> 1;
|
||||
case "off", "false" -> 0;
|
||||
case "toggle" -> -1;
|
||||
default -> Integer.parseInt(valueStr);
|
||||
};
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.execution.argument_error");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean success = false;
|
||||
Prop prop = props.get(propStr);
|
||||
|
||||
success =
|
||||
switch (prop.pseudoProp) {
|
||||
case WORLD_LEVEL -> targetPlayer.setWorldLevel(value);
|
||||
case BP_LEVEL -> targetPlayer.getBattlePassManager().setLevel(value);
|
||||
case TOWER_LEVEL -> this.setTowerLevel(sender, targetPlayer, value);
|
||||
case GOD_MODE, UNLIMITED_STAMINA, UNLIMITED_ENERGY -> this.setBool(
|
||||
sender, targetPlayer, prop.pseudoProp, value);
|
||||
case SET_OPENSTATE -> this.setOpenState(targetPlayer, value, 1);
|
||||
case UNSET_OPENSTATE -> this.setOpenState(targetPlayer, value, 0);
|
||||
case UNLOCK_MAP -> unlockMap(targetPlayer);
|
||||
default -> targetPlayer.setProperty(prop.prop, value);
|
||||
};
|
||||
|
||||
if (success) {
|
||||
if (targetPlayer == sender) {
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.generic.set_to", prop.name, valueStr);
|
||||
} else {
|
||||
String uidStr = targetPlayer.getAccount().getId();
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.generic.set_for_to", prop.name, uidStr, valueStr);
|
||||
}
|
||||
} else {
|
||||
if (prop.prop
|
||||
!= PlayerProperty.PROP_NONE) { // PseudoProps need to do their own error messages
|
||||
int min = targetPlayer.getPropertyMin(prop.prop);
|
||||
int max = targetPlayer.getPropertyMax(prop.prop);
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.generic.invalid.value_between", prop.name, min, max);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean setTowerLevel(Player sender, Player targetPlayer, int topFloor) {
|
||||
List<Integer> floorIds = targetPlayer.getServer().getTowerSystem().getAllFloors();
|
||||
if (topFloor < 0 || topFloor > floorIds.size()) {
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.generic.invalid.value_between", "Tower Level", 0, floorIds.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
Map<Integer, TowerLevelRecord> recordMap = targetPlayer.getTowerManager().getRecordMap();
|
||||
// Add records for each unlocked floor
|
||||
for (int floor : floorIds.subList(0, topFloor)) {
|
||||
if (!recordMap.containsKey(floor)) {
|
||||
recordMap.put(floor, new TowerLevelRecord(floor));
|
||||
}
|
||||
}
|
||||
// Remove records for each floor past our target
|
||||
for (int floor : floorIds.subList(topFloor, floorIds.size())) {
|
||||
recordMap.remove(floor);
|
||||
}
|
||||
// Six stars required on Floor 8 to unlock Floor 9+
|
||||
if (topFloor > 8) {
|
||||
recordMap
|
||||
.get(floorIds.get(7))
|
||||
.setLevelStars(
|
||||
0,
|
||||
6); // levelIds seem to start at 1 for Floor 1 Chamber 1, so this doesn't get shown at
|
||||
// all
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean setBool(Player sender, Player targetPlayer, PseudoProp pseudoProp, int value) {
|
||||
boolean enabled =
|
||||
switch (pseudoProp) {
|
||||
case GOD_MODE -> targetPlayer.isInGodMode();
|
||||
case UNLIMITED_STAMINA -> targetPlayer.isUnlimitedStamina();
|
||||
case UNLIMITED_ENERGY -> !targetPlayer.getEnergyManager().isEnergyUsage();
|
||||
default -> false;
|
||||
};
|
||||
enabled =
|
||||
switch (value) {
|
||||
case -1 -> !enabled;
|
||||
case 0 -> false;
|
||||
default -> true;
|
||||
};
|
||||
|
||||
switch (pseudoProp) {
|
||||
case GOD_MODE:
|
||||
targetPlayer.setInGodMode(enabled);
|
||||
break;
|
||||
case UNLIMITED_STAMINA:
|
||||
targetPlayer.setUnlimitedStamina(enabled);
|
||||
break;
|
||||
case UNLIMITED_ENERGY:
|
||||
targetPlayer.getEnergyManager().setEnergyUsage(!enabled);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean setOpenState(Player targetPlayer, int state, int value) {
|
||||
targetPlayer.sendPacket(new PacketOpenStateChangeNotify(state, value));
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean unlockMap(Player targetPlayer) {
|
||||
// Unlock.
|
||||
GameData.getScenePointsPerScene()
|
||||
.forEach(
|
||||
(sceneId, scenePoints) -> {
|
||||
// Unlock trans points.
|
||||
targetPlayer.getUnlockedScenePoints(sceneId).addAll(scenePoints);
|
||||
|
||||
// Unlock map areas.
|
||||
targetPlayer.getUnlockedSceneAreas(sceneId).addAll(sceneAreas);
|
||||
});
|
||||
|
||||
// Send notify.
|
||||
int playerScene = targetPlayer.getSceneId();
|
||||
targetPlayer.sendPacket(
|
||||
new PacketScenePointUnlockNotify(
|
||||
playerScene, targetPlayer.getUnlockedScenePoints(playerScene)));
|
||||
targetPlayer.sendPacket(
|
||||
new PacketSceneAreaUnlockNotify(
|
||||
playerScene, targetPlayer.getUnlockedSceneAreas(playerScene)));
|
||||
return true;
|
||||
}
|
||||
|
||||
enum PseudoProp {
|
||||
NONE,
|
||||
WORLD_LEVEL,
|
||||
TOWER_LEVEL,
|
||||
BP_LEVEL,
|
||||
GOD_MODE,
|
||||
UNLIMITED_STAMINA,
|
||||
UNLIMITED_ENERGY,
|
||||
SET_OPENSTATE,
|
||||
UNSET_OPENSTATE,
|
||||
UNLOCK_MAP
|
||||
}
|
||||
|
||||
static class Prop {
|
||||
String name;
|
||||
PlayerProperty prop;
|
||||
PseudoProp pseudoProp;
|
||||
|
||||
public Prop(PlayerProperty prop) {
|
||||
this(prop.toString(), prop, PseudoProp.NONE);
|
||||
}
|
||||
|
||||
public Prop(String name) {
|
||||
this(name, PlayerProperty.PROP_NONE, PseudoProp.NONE);
|
||||
}
|
||||
|
||||
public Prop(String name, PseudoProp pseudoProp) {
|
||||
this(name, PlayerProperty.PROP_NONE, pseudoProp);
|
||||
}
|
||||
|
||||
public Prop(String name, PlayerProperty prop) {
|
||||
this(name, prop, PseudoProp.NONE);
|
||||
}
|
||||
|
||||
public Prop(String name, PlayerProperty prop, PseudoProp pseudoProp) {
|
||||
this.name = name;
|
||||
this.prop = prop;
|
||||
this.pseudoProp = pseudoProp;
|
||||
}
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.PlayerProperty;
|
||||
import emu.grasscutter.game.tower.TowerLevelRecord;
|
||||
import emu.grasscutter.server.packet.send.PacketOpenStateChangeNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneAreaUnlockNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketScenePointUnlockNotify;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Command(
|
||||
label = "setProp",
|
||||
aliases = {"prop"},
|
||||
usage = {"<prop> <value>"},
|
||||
permission = "player.setprop",
|
||||
permissionTargeted = "player.setprop.others")
|
||||
public final class SetPropCommand implements CommandHandler {
|
||||
// List of map areas. Unfortunately, there is no readily available source for them in excels or
|
||||
// bins.
|
||||
private static final List<Integer> sceneAreas =
|
||||
List.of(
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
|
||||
28, 29, 32, 100, 101, 102, 103, 200, 210, 300, 400, 401, 402, 403);
|
||||
Map<String, Prop> props;
|
||||
|
||||
public SetPropCommand() {
|
||||
this.props = new HashMap<>();
|
||||
// Full PlayerProperty enum that won't be advertised but can be used by devs
|
||||
for (PlayerProperty prop : PlayerProperty.values()) {
|
||||
String name = prop.toString().substring(5); // PROP_EXP -> EXP
|
||||
String key = name.toLowerCase(); // EXP -> exp
|
||||
this.props.put(key, new Prop(name, prop));
|
||||
}
|
||||
// Add special props
|
||||
Prop worldlevel =
|
||||
new Prop("World Level", PlayerProperty.PROP_PLAYER_WORLD_LEVEL, PseudoProp.WORLD_LEVEL);
|
||||
this.props.put("worldlevel", worldlevel);
|
||||
this.props.put("wl", worldlevel);
|
||||
|
||||
Prop abyss = new Prop("Tower Level", PseudoProp.TOWER_LEVEL);
|
||||
this.props.put("abyss", abyss);
|
||||
this.props.put("abyssfloor", abyss);
|
||||
this.props.put("ut", abyss);
|
||||
this.props.put("tower", abyss);
|
||||
this.props.put("towerlevel", abyss);
|
||||
this.props.put("unlocktower", abyss);
|
||||
|
||||
Prop bplevel = new Prop("BP Level", PseudoProp.BP_LEVEL);
|
||||
this.props.put("bplevel", bplevel);
|
||||
this.props.put("bp", bplevel);
|
||||
this.props.put("battlepass", bplevel);
|
||||
|
||||
Prop godmode = new Prop("GodMode", PseudoProp.GOD_MODE);
|
||||
this.props.put("godmode", godmode);
|
||||
this.props.put("god", godmode);
|
||||
|
||||
Prop nostamina = new Prop("UnlimitedStamina", PseudoProp.UNLIMITED_STAMINA);
|
||||
this.props.put("unlimitedstamina", nostamina);
|
||||
this.props.put("us", nostamina);
|
||||
this.props.put("nostamina", nostamina);
|
||||
this.props.put("nostam", nostamina);
|
||||
this.props.put("ns", nostamina);
|
||||
|
||||
Prop unlimitedenergy = new Prop("UnlimitedEnergy", PseudoProp.UNLIMITED_ENERGY);
|
||||
this.props.put("unlimitedenergy", unlimitedenergy);
|
||||
this.props.put("ue", unlimitedenergy);
|
||||
|
||||
Prop setopenstate = new Prop("SetOpenstate", PseudoProp.SET_OPENSTATE);
|
||||
this.props.put("setopenstate", setopenstate);
|
||||
this.props.put("so", setopenstate);
|
||||
|
||||
Prop unsetopenstate = new Prop("UnsetOpenstate", PseudoProp.UNSET_OPENSTATE);
|
||||
this.props.put("unsetopenstate", unsetopenstate);
|
||||
this.props.put("uo", unsetopenstate);
|
||||
|
||||
Prop unlockmap = new Prop("UnlockMap", PseudoProp.UNLOCK_MAP);
|
||||
this.props.put("unlockmap", unlockmap);
|
||||
this.props.put("um", unlockmap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() != 2) {
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
String propStr = args.get(0).toLowerCase();
|
||||
String valueStr = args.get(1).toLowerCase();
|
||||
int value;
|
||||
|
||||
if (!props.containsKey(propStr)) {
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
value =
|
||||
switch (valueStr.toLowerCase()) {
|
||||
case "on", "true" -> 1;
|
||||
case "off", "false" -> 0;
|
||||
case "toggle" -> -1;
|
||||
default -> Integer.parseInt(valueStr);
|
||||
};
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.execution.argument_error");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean success = false;
|
||||
Prop prop = props.get(propStr);
|
||||
|
||||
success =
|
||||
switch (prop.pseudoProp) {
|
||||
case WORLD_LEVEL -> targetPlayer.setWorldLevel(value);
|
||||
case BP_LEVEL -> targetPlayer.getBattlePassManager().setLevel(value);
|
||||
case TOWER_LEVEL -> this.setTowerLevel(sender, targetPlayer, value);
|
||||
case GOD_MODE, UNLIMITED_STAMINA, UNLIMITED_ENERGY -> this.setBool(
|
||||
sender, targetPlayer, prop.pseudoProp, value);
|
||||
case SET_OPENSTATE -> this.setOpenState(targetPlayer, value, 1);
|
||||
case UNSET_OPENSTATE -> this.setOpenState(targetPlayer, value, 0);
|
||||
case UNLOCK_MAP -> unlockMap(targetPlayer);
|
||||
default -> targetPlayer.setProperty(prop.prop, value);
|
||||
};
|
||||
|
||||
if (success) {
|
||||
if (targetPlayer == sender) {
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.generic.set_to", prop.name, valueStr);
|
||||
} else {
|
||||
String uidStr = targetPlayer.getAccount().getId();
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.generic.set_for_to", prop.name, uidStr, valueStr);
|
||||
}
|
||||
} else {
|
||||
if (prop.prop
|
||||
!= PlayerProperty.PROP_NONE) { // PseudoProps need to do their own error messages
|
||||
int min = targetPlayer.getPropertyMin(prop.prop);
|
||||
int max = targetPlayer.getPropertyMax(prop.prop);
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.generic.invalid.value_between", prop.name, min, max);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean setTowerLevel(Player sender, Player targetPlayer, int topFloor) {
|
||||
List<Integer> floorIds = targetPlayer.getServer().getTowerSystem().getAllFloors();
|
||||
if (topFloor < 0 || topFloor > floorIds.size()) {
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.generic.invalid.value_between", "Tower Level", 0, floorIds.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
Map<Integer, TowerLevelRecord> recordMap = targetPlayer.getTowerManager().getRecordMap();
|
||||
// Add records for each unlocked floor
|
||||
for (int floor : floorIds.subList(0, topFloor)) {
|
||||
if (!recordMap.containsKey(floor)) {
|
||||
recordMap.put(floor, new TowerLevelRecord(floor));
|
||||
}
|
||||
}
|
||||
// Remove records for each floor past our target
|
||||
for (int floor : floorIds.subList(topFloor, floorIds.size())) {
|
||||
recordMap.remove(floor);
|
||||
}
|
||||
// Six stars required on Floor 8 to unlock Floor 9+
|
||||
if (topFloor > 8) {
|
||||
recordMap
|
||||
.get(floorIds.get(7))
|
||||
.setLevelStars(
|
||||
0,
|
||||
6); // levelIds seem to start at 1 for Floor 1 Chamber 1, so this doesn't get shown at
|
||||
// all
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean setBool(Player sender, Player targetPlayer, PseudoProp pseudoProp, int value) {
|
||||
boolean enabled =
|
||||
switch (pseudoProp) {
|
||||
case GOD_MODE -> targetPlayer.isInGodMode();
|
||||
case UNLIMITED_STAMINA -> targetPlayer.isUnlimitedStamina();
|
||||
case UNLIMITED_ENERGY -> !targetPlayer.getEnergyManager().isEnergyUsage();
|
||||
default -> false;
|
||||
};
|
||||
enabled =
|
||||
switch (value) {
|
||||
case -1 -> !enabled;
|
||||
case 0 -> false;
|
||||
default -> true;
|
||||
};
|
||||
|
||||
switch (pseudoProp) {
|
||||
case GOD_MODE:
|
||||
targetPlayer.setInGodMode(enabled);
|
||||
break;
|
||||
case UNLIMITED_STAMINA:
|
||||
targetPlayer.setUnlimitedStamina(enabled);
|
||||
break;
|
||||
case UNLIMITED_ENERGY:
|
||||
targetPlayer.getEnergyManager().setEnergyUsage(!enabled);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean setOpenState(Player targetPlayer, int state, int value) {
|
||||
targetPlayer.sendPacket(new PacketOpenStateChangeNotify(state, value));
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean unlockMap(Player targetPlayer) {
|
||||
// Unlock.
|
||||
GameData.getScenePointsPerScene()
|
||||
.forEach(
|
||||
(sceneId, scenePoints) -> {
|
||||
// Unlock trans points.
|
||||
targetPlayer.getUnlockedScenePoints(sceneId).addAll(scenePoints);
|
||||
|
||||
// Unlock map areas.
|
||||
targetPlayer.getUnlockedSceneAreas(sceneId).addAll(sceneAreas);
|
||||
});
|
||||
|
||||
// Send notify.
|
||||
int playerScene = targetPlayer.getSceneId();
|
||||
targetPlayer.sendPacket(
|
||||
new PacketScenePointUnlockNotify(
|
||||
playerScene, targetPlayer.getUnlockedScenePoints(playerScene)));
|
||||
targetPlayer.sendPacket(
|
||||
new PacketSceneAreaUnlockNotify(
|
||||
playerScene, targetPlayer.getUnlockedSceneAreas(playerScene)));
|
||||
return true;
|
||||
}
|
||||
|
||||
enum PseudoProp {
|
||||
NONE,
|
||||
WORLD_LEVEL,
|
||||
TOWER_LEVEL,
|
||||
BP_LEVEL,
|
||||
GOD_MODE,
|
||||
UNLIMITED_STAMINA,
|
||||
UNLIMITED_ENERGY,
|
||||
SET_OPENSTATE,
|
||||
UNSET_OPENSTATE,
|
||||
UNLOCK_MAP
|
||||
}
|
||||
|
||||
static class Prop {
|
||||
String name;
|
||||
PlayerProperty prop;
|
||||
PseudoProp pseudoProp;
|
||||
|
||||
public Prop(PlayerProperty prop) {
|
||||
this(prop.toString(), prop, PseudoProp.NONE);
|
||||
}
|
||||
|
||||
public Prop(String name) {
|
||||
this(name, PlayerProperty.PROP_NONE, PseudoProp.NONE);
|
||||
}
|
||||
|
||||
public Prop(String name, PseudoProp pseudoProp) {
|
||||
this(name, PlayerProperty.PROP_NONE, pseudoProp);
|
||||
}
|
||||
|
||||
public Prop(String name, PlayerProperty prop) {
|
||||
this(name, prop, PseudoProp.NONE);
|
||||
}
|
||||
|
||||
public Prop(String name, PlayerProperty prop, PseudoProp pseudoProp) {
|
||||
this.name = name;
|
||||
this.prop = prop;
|
||||
this.pseudoProp = pseudoProp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,217 +1,217 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.command.CommandHelpers.*;
|
||||
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.GadgetData;
|
||||
import emu.grasscutter.data.excels.ItemData;
|
||||
import emu.grasscutter.data.excels.monster.MonsterData;
|
||||
import emu.grasscutter.game.entity.*;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.EntityType;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.Setter;
|
||||
|
||||
@Command(
|
||||
label = "spawn",
|
||||
aliases = {"drop", "s"},
|
||||
usage = {
|
||||
"<itemId> [x<amount>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>",
|
||||
"<gadgetId> [x<amount>] [state<state>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>",
|
||||
"<monsterId> [x<amount>] [lv<level>] [ai<aiId>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>"
|
||||
},
|
||||
permission = "server.spawn",
|
||||
permissionTargeted = "server.spawn.others")
|
||||
public final class SpawnCommand implements CommandHandler {
|
||||
private static final Map<Pattern, BiConsumer<SpawnParameters, Integer>> intCommandHandlers =
|
||||
Map.ofEntries(
|
||||
Map.entry(lvlRegex, SpawnParameters::setLvl),
|
||||
Map.entry(amountRegex, SpawnParameters::setAmount),
|
||||
Map.entry(stateRegex, SpawnParameters::setState),
|
||||
Map.entry(blockRegex, SpawnParameters::setBlockId),
|
||||
Map.entry(groupRegex, SpawnParameters::setGroupId),
|
||||
Map.entry(configRegex, SpawnParameters::setConfigId),
|
||||
Map.entry(maxHPRegex, SpawnParameters::setMaxHP),
|
||||
Map.entry(hpRegex, SpawnParameters::setHp),
|
||||
Map.entry(defRegex, SpawnParameters::setDef),
|
||||
Map.entry(atkRegex, SpawnParameters::setAtk),
|
||||
Map.entry(aiRegex, SpawnParameters::setAi));
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
SpawnParameters param = new SpawnParameters();
|
||||
|
||||
parseIntParameters(args, param, intCommandHandlers);
|
||||
|
||||
// At this point, first remaining argument MUST be the id and the rest the pos
|
||||
if (args.size() < 1) {
|
||||
sendUsageMessage(sender); // Reachable if someone does `/give lv90` or similar
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
switch (args.size()) {
|
||||
case 4:
|
||||
try {
|
||||
float x, y, z;
|
||||
x = Float.parseFloat(args.get(1));
|
||||
y = Float.parseFloat(args.get(2));
|
||||
z = Float.parseFloat(args.get(3));
|
||||
param.pos = new Position(x, y, z);
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.execution.argument_error"));
|
||||
} // Fallthrough
|
||||
case 1:
|
||||
try {
|
||||
param.id = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.generic.invalid.entityId"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
MonsterData monsterData = GameData.getMonsterDataMap().get(param.id);
|
||||
GadgetData gadgetData = GameData.getGadgetDataMap().get(param.id);
|
||||
ItemData itemData = GameData.getItemDataMap().get(param.id);
|
||||
if (monsterData == null && gadgetData == null && itemData == null) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.entityId"));
|
||||
return;
|
||||
}
|
||||
|
||||
param.scene = targetPlayer.getScene();
|
||||
|
||||
if (param.scene.getEntities().size() + param.amount > GAME_OPTIONS.sceneEntityLimit) {
|
||||
param.amount =
|
||||
Math.max(
|
||||
Math.min(
|
||||
GAME_OPTIONS.sceneEntityLimit - param.scene.getEntities().size(), param.amount),
|
||||
0);
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.spawn.limit_reached", param.amount));
|
||||
if (param.amount <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
double maxRadius = Math.sqrt(param.amount * 0.2 / Math.PI);
|
||||
if (param.pos == null) {
|
||||
param.pos = targetPlayer.getPosition();
|
||||
}
|
||||
|
||||
for (int i = 0; i < param.amount; i++) {
|
||||
Position pos = GetRandomPositionInCircle(param.pos, maxRadius).addY(3);
|
||||
GameEntity entity = null;
|
||||
if (itemData != null) {
|
||||
entity = createItem(itemData, param, pos);
|
||||
}
|
||||
if (gadgetData != null) {
|
||||
pos.addY(-3);
|
||||
entity = createGadget(gadgetData, param, pos, targetPlayer);
|
||||
}
|
||||
if (monsterData != null) {
|
||||
entity = createMonster(monsterData, param, pos);
|
||||
}
|
||||
applyCommonParameters(entity, param);
|
||||
|
||||
param.scene.addEntity(entity);
|
||||
}
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.spawn.success", param.amount, param.id));
|
||||
}
|
||||
|
||||
private EntityItem createItem(ItemData itemData, SpawnParameters param, Position pos) {
|
||||
return new EntityItem(param.scene, null, itemData, pos, 1, true);
|
||||
}
|
||||
|
||||
private EntityMonster createMonster(
|
||||
MonsterData monsterData, SpawnParameters param, Position pos) {
|
||||
var entity = new EntityMonster(param.scene, monsterData, pos, param.lvl);
|
||||
if (param.ai != -1) {
|
||||
entity.setAiId(param.ai);
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
private EntityBaseGadget createGadget(
|
||||
GadgetData gadgetData, SpawnParameters param, Position pos, Player targetPlayer) {
|
||||
EntityBaseGadget entity;
|
||||
if (gadgetData.getType() == EntityType.Vehicle) {
|
||||
entity =
|
||||
new EntityVehicle(
|
||||
param.scene, targetPlayer, param.id, 0, pos, targetPlayer.getRotation());
|
||||
} else {
|
||||
entity = new EntityGadget(param.scene, param.id, pos, targetPlayer.getRotation());
|
||||
if (param.state != -1) {
|
||||
((EntityGadget) entity).setState(param.state);
|
||||
}
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
private void applyCommonParameters(GameEntity entity, SpawnParameters param) {
|
||||
if (param.blockId != -1) {
|
||||
entity.setBlockId(param.blockId);
|
||||
}
|
||||
if (param.groupId != -1) {
|
||||
entity.setGroupId(param.groupId);
|
||||
}
|
||||
if (param.configId != -1) {
|
||||
entity.setConfigId(param.configId);
|
||||
}
|
||||
if (param.maxHP != -1) {
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_MAX_HP, param.maxHP);
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_BASE_HP, param.maxHP);
|
||||
}
|
||||
if (param.hp != -1) {
|
||||
entity.setFightProperty(
|
||||
FightProperty.FIGHT_PROP_CUR_HP, param.hp == 0 ? Float.MAX_VALUE : param.hp);
|
||||
}
|
||||
if (param.atk != -1) {
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_ATTACK, param.atk);
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_ATTACK, param.atk);
|
||||
}
|
||||
if (param.def != -1) {
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_DEFENSE, param.def);
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_DEFENSE, param.def);
|
||||
}
|
||||
}
|
||||
|
||||
private Position GetRandomPositionInCircle(Position origin, double radius) {
|
||||
Position target = origin.clone();
|
||||
double angle = Math.random() * 360;
|
||||
double r = Math.sqrt(Math.random() * radius * radius);
|
||||
target.addX((float) (r * Math.cos(angle))).addZ((float) (r * Math.sin(angle)));
|
||||
return target;
|
||||
}
|
||||
|
||||
private static class SpawnParameters {
|
||||
@Setter public int id;
|
||||
@Setter public int lvl = 1;
|
||||
@Setter public int amount = 1;
|
||||
@Setter public int blockId = -1;
|
||||
@Setter public int groupId = -1;
|
||||
@Setter public int configId = -1;
|
||||
@Setter public int state = -1;
|
||||
@Setter public int hp = -1;
|
||||
@Setter public int maxHP = -1;
|
||||
@Setter public int atk = -1;
|
||||
@Setter public int def = -1;
|
||||
@Setter public int ai = -1;
|
||||
@Setter public Position pos = null;
|
||||
public Scene scene = null;
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.command.CommandHelpers.*;
|
||||
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.GadgetData;
|
||||
import emu.grasscutter.data.excels.ItemData;
|
||||
import emu.grasscutter.data.excels.monster.MonsterData;
|
||||
import emu.grasscutter.game.entity.*;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.EntityType;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.Setter;
|
||||
|
||||
@Command(
|
||||
label = "spawn",
|
||||
aliases = {"drop", "s"},
|
||||
usage = {
|
||||
"<itemId> [x<amount>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>",
|
||||
"<gadgetId> [x<amount>] [state<state>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>",
|
||||
"<monsterId> [x<amount>] [lv<level>] [ai<aiId>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>"
|
||||
},
|
||||
permission = "server.spawn",
|
||||
permissionTargeted = "server.spawn.others")
|
||||
public final class SpawnCommand implements CommandHandler {
|
||||
private static final Map<Pattern, BiConsumer<SpawnParameters, Integer>> intCommandHandlers =
|
||||
Map.ofEntries(
|
||||
Map.entry(lvlRegex, SpawnParameters::setLvl),
|
||||
Map.entry(amountRegex, SpawnParameters::setAmount),
|
||||
Map.entry(stateRegex, SpawnParameters::setState),
|
||||
Map.entry(blockRegex, SpawnParameters::setBlockId),
|
||||
Map.entry(groupRegex, SpawnParameters::setGroupId),
|
||||
Map.entry(configRegex, SpawnParameters::setConfigId),
|
||||
Map.entry(maxHPRegex, SpawnParameters::setMaxHP),
|
||||
Map.entry(hpRegex, SpawnParameters::setHp),
|
||||
Map.entry(defRegex, SpawnParameters::setDef),
|
||||
Map.entry(atkRegex, SpawnParameters::setAtk),
|
||||
Map.entry(aiRegex, SpawnParameters::setAi));
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
SpawnParameters param = new SpawnParameters();
|
||||
|
||||
parseIntParameters(args, param, intCommandHandlers);
|
||||
|
||||
// At this point, first remaining argument MUST be the id and the rest the pos
|
||||
if (args.size() < 1) {
|
||||
sendUsageMessage(sender); // Reachable if someone does `/give lv90` or similar
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
switch (args.size()) {
|
||||
case 4:
|
||||
try {
|
||||
float x, y, z;
|
||||
x = Float.parseFloat(args.get(1));
|
||||
y = Float.parseFloat(args.get(2));
|
||||
z = Float.parseFloat(args.get(3));
|
||||
param.pos = new Position(x, y, z);
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.execution.argument_error"));
|
||||
} // Fallthrough
|
||||
case 1:
|
||||
try {
|
||||
param.id = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.generic.invalid.entityId"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
MonsterData monsterData = GameData.getMonsterDataMap().get(param.id);
|
||||
GadgetData gadgetData = GameData.getGadgetDataMap().get(param.id);
|
||||
ItemData itemData = GameData.getItemDataMap().get(param.id);
|
||||
if (monsterData == null && gadgetData == null && itemData == null) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.entityId"));
|
||||
return;
|
||||
}
|
||||
|
||||
param.scene = targetPlayer.getScene();
|
||||
|
||||
if (param.scene.getEntities().size() + param.amount > GAME_OPTIONS.sceneEntityLimit) {
|
||||
param.amount =
|
||||
Math.max(
|
||||
Math.min(
|
||||
GAME_OPTIONS.sceneEntityLimit - param.scene.getEntities().size(), param.amount),
|
||||
0);
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.spawn.limit_reached", param.amount));
|
||||
if (param.amount <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
double maxRadius = Math.sqrt(param.amount * 0.2 / Math.PI);
|
||||
if (param.pos == null) {
|
||||
param.pos = targetPlayer.getPosition();
|
||||
}
|
||||
|
||||
for (int i = 0; i < param.amount; i++) {
|
||||
Position pos = GetRandomPositionInCircle(param.pos, maxRadius).addY(3);
|
||||
GameEntity entity = null;
|
||||
if (itemData != null) {
|
||||
entity = createItem(itemData, param, pos);
|
||||
}
|
||||
if (gadgetData != null) {
|
||||
pos.addY(-3);
|
||||
entity = createGadget(gadgetData, param, pos, targetPlayer);
|
||||
}
|
||||
if (monsterData != null) {
|
||||
entity = createMonster(monsterData, param, pos);
|
||||
}
|
||||
applyCommonParameters(entity, param);
|
||||
|
||||
param.scene.addEntity(entity);
|
||||
}
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.spawn.success", param.amount, param.id));
|
||||
}
|
||||
|
||||
private EntityItem createItem(ItemData itemData, SpawnParameters param, Position pos) {
|
||||
return new EntityItem(param.scene, null, itemData, pos, 1, true);
|
||||
}
|
||||
|
||||
private EntityMonster createMonster(
|
||||
MonsterData monsterData, SpawnParameters param, Position pos) {
|
||||
var entity = new EntityMonster(param.scene, monsterData, pos, param.lvl);
|
||||
if (param.ai != -1) {
|
||||
entity.setAiId(param.ai);
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
private EntityBaseGadget createGadget(
|
||||
GadgetData gadgetData, SpawnParameters param, Position pos, Player targetPlayer) {
|
||||
EntityBaseGadget entity;
|
||||
if (gadgetData.getType() == EntityType.Vehicle) {
|
||||
entity =
|
||||
new EntityVehicle(
|
||||
param.scene, targetPlayer, param.id, 0, pos, targetPlayer.getRotation());
|
||||
} else {
|
||||
entity = new EntityGadget(param.scene, param.id, pos, targetPlayer.getRotation());
|
||||
if (param.state != -1) {
|
||||
((EntityGadget) entity).setState(param.state);
|
||||
}
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
private void applyCommonParameters(GameEntity entity, SpawnParameters param) {
|
||||
if (param.blockId != -1) {
|
||||
entity.setBlockId(param.blockId);
|
||||
}
|
||||
if (param.groupId != -1) {
|
||||
entity.setGroupId(param.groupId);
|
||||
}
|
||||
if (param.configId != -1) {
|
||||
entity.setConfigId(param.configId);
|
||||
}
|
||||
if (param.maxHP != -1) {
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_MAX_HP, param.maxHP);
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_BASE_HP, param.maxHP);
|
||||
}
|
||||
if (param.hp != -1) {
|
||||
entity.setFightProperty(
|
||||
FightProperty.FIGHT_PROP_CUR_HP, param.hp == 0 ? Float.MAX_VALUE : param.hp);
|
||||
}
|
||||
if (param.atk != -1) {
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_ATTACK, param.atk);
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_ATTACK, param.atk);
|
||||
}
|
||||
if (param.def != -1) {
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_DEFENSE, param.def);
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_DEFENSE, param.def);
|
||||
}
|
||||
}
|
||||
|
||||
private Position GetRandomPositionInCircle(Position origin, double radius) {
|
||||
Position target = origin.clone();
|
||||
double angle = Math.random() * 360;
|
||||
double r = Math.sqrt(Math.random() * radius * radius);
|
||||
target.addX((float) (r * Math.cos(angle))).addZ((float) (r * Math.sin(angle)));
|
||||
return target;
|
||||
}
|
||||
|
||||
private static class SpawnParameters {
|
||||
@Setter public int id;
|
||||
@Setter public int lvl = 1;
|
||||
@Setter public int amount = 1;
|
||||
@Setter public int blockId = -1;
|
||||
@Setter public int groupId = -1;
|
||||
@Setter public int configId = -1;
|
||||
@Setter public int state = -1;
|
||||
@Setter public int hp = -1;
|
||||
@Setter public int maxHP = -1;
|
||||
@Setter public int atk = -1;
|
||||
@Setter public int def = -1;
|
||||
@Setter public int ai = -1;
|
||||
@Setter public Position pos = null;
|
||||
public Scene scene = null;
|
||||
}
|
||||
}
|
||||
|
@ -1,129 +1,129 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.avatar.AvatarSkillDepotData;
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.utils.Language;
|
||||
import java.util.List;
|
||||
|
||||
@Command(
|
||||
label = "talent",
|
||||
usage = {"set <talentId> <level>", "(n|e|q|all) <level>", "getid"},
|
||||
permission = "player.settalent",
|
||||
permissionTargeted = "player.settalent.others")
|
||||
public final class TalentCommand implements CommandHandler {
|
||||
private void setTalentLevel(Player sender, Avatar avatar, int skillId, int newLevel) {
|
||||
if (avatar.setSkillLevel(skillId, newLevel)) {
|
||||
long nameHash = GameData.getAvatarSkillDataMap().get(skillId).getNameTextMapHash();
|
||||
var name = Language.getTextMapKey(nameHash);
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.talent.set_id", skillId, name, newLevel);
|
||||
} else {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.talent.out_of_range");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 1) {
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
Avatar avatar = targetPlayer.getTeamManager().getCurrentAvatarEntity().getAvatar();
|
||||
AvatarSkillDepotData skillDepot = avatar.getSkillDepot();
|
||||
if (skillDepot
|
||||
== null) { // Avatars without skill depots aren't a suitable target even with manual skillId
|
||||
// specified
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_skill_id");
|
||||
return;
|
||||
}
|
||||
int skillId = 0;
|
||||
int newLevel = -1;
|
||||
|
||||
String cmdSwitch = args.get(0).toLowerCase();
|
||||
switch (cmdSwitch) {
|
||||
default -> {
|
||||
sendUsageMessage(sender);
|
||||
}
|
||||
case "set" -> {
|
||||
if (args.size() < 3) {
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
skillId = Integer.parseInt(args.get(1));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_skill_id");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
newLevel = Integer.parseInt(args.get(2));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_level");
|
||||
return;
|
||||
}
|
||||
|
||||
setTalentLevel(sender, avatar, skillId, newLevel);
|
||||
}
|
||||
case "n", "e", "q" -> {
|
||||
if (args.size() < 2) {
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
newLevel = Integer.parseInt(args.get(1));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_level");
|
||||
return;
|
||||
}
|
||||
|
||||
skillId =
|
||||
switch (cmdSwitch) {
|
||||
default -> skillDepot.getSkills().get(0);
|
||||
case "e" -> skillDepot.getSkills().get(1);
|
||||
case "q" -> skillDepot.getEnergySkill();
|
||||
};
|
||||
setTalentLevel(sender, avatar, skillId, newLevel);
|
||||
}
|
||||
case "all" -> {
|
||||
if (args.size() < 2) {
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
newLevel = Integer.parseInt(args.get(1));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_level");
|
||||
return;
|
||||
}
|
||||
// This stops setTalentLevel from outputting 3 "levels out of range" messages
|
||||
if (newLevel < 1 || newLevel > 15) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.talent.out_of_range");
|
||||
return;
|
||||
}
|
||||
int finalNewLevel = newLevel;
|
||||
skillDepot
|
||||
.getSkillsAndEnergySkill()
|
||||
.forEach(id -> setTalentLevel(sender, avatar, id, finalNewLevel));
|
||||
}
|
||||
case "getid" -> {
|
||||
var map = GameData.getAvatarSkillDataMap();
|
||||
skillDepot
|
||||
.getSkillsAndEnergySkill()
|
||||
.forEach(
|
||||
id -> {
|
||||
var talent = map.get(id);
|
||||
if (talent == null) return;
|
||||
var talentName = Language.getTextMapKey(talent.getNameTextMapHash());
|
||||
var talentDesc = Language.getTextMapKey(talent.getDescTextMapHash());
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.talent.id_desc", id, talentName, talentDesc);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.avatar.AvatarSkillDepotData;
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.utils.Language;
|
||||
import java.util.List;
|
||||
|
||||
@Command(
|
||||
label = "talent",
|
||||
usage = {"set <talentId> <level>", "(n|e|q|all) <level>", "getid"},
|
||||
permission = "player.settalent",
|
||||
permissionTargeted = "player.settalent.others")
|
||||
public final class TalentCommand implements CommandHandler {
|
||||
private void setTalentLevel(Player sender, Avatar avatar, int skillId, int newLevel) {
|
||||
if (avatar.setSkillLevel(skillId, newLevel)) {
|
||||
long nameHash = GameData.getAvatarSkillDataMap().get(skillId).getNameTextMapHash();
|
||||
var name = Language.getTextMapKey(nameHash);
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.talent.set_id", skillId, name, newLevel);
|
||||
} else {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.talent.out_of_range");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 1) {
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
Avatar avatar = targetPlayer.getTeamManager().getCurrentAvatarEntity().getAvatar();
|
||||
AvatarSkillDepotData skillDepot = avatar.getSkillDepot();
|
||||
if (skillDepot
|
||||
== null) { // Avatars without skill depots aren't a suitable target even with manual skillId
|
||||
// specified
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_skill_id");
|
||||
return;
|
||||
}
|
||||
int skillId = 0;
|
||||
int newLevel = -1;
|
||||
|
||||
String cmdSwitch = args.get(0).toLowerCase();
|
||||
switch (cmdSwitch) {
|
||||
default -> {
|
||||
sendUsageMessage(sender);
|
||||
}
|
||||
case "set" -> {
|
||||
if (args.size() < 3) {
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
skillId = Integer.parseInt(args.get(1));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_skill_id");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
newLevel = Integer.parseInt(args.get(2));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_level");
|
||||
return;
|
||||
}
|
||||
|
||||
setTalentLevel(sender, avatar, skillId, newLevel);
|
||||
}
|
||||
case "n", "e", "q" -> {
|
||||
if (args.size() < 2) {
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
newLevel = Integer.parseInt(args.get(1));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_level");
|
||||
return;
|
||||
}
|
||||
|
||||
skillId =
|
||||
switch (cmdSwitch) {
|
||||
default -> skillDepot.getSkills().get(0);
|
||||
case "e" -> skillDepot.getSkills().get(1);
|
||||
case "q" -> skillDepot.getEnergySkill();
|
||||
};
|
||||
setTalentLevel(sender, avatar, skillId, newLevel);
|
||||
}
|
||||
case "all" -> {
|
||||
if (args.size() < 2) {
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
newLevel = Integer.parseInt(args.get(1));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_level");
|
||||
return;
|
||||
}
|
||||
// This stops setTalentLevel from outputting 3 "levels out of range" messages
|
||||
if (newLevel < 1 || newLevel > 15) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.talent.out_of_range");
|
||||
return;
|
||||
}
|
||||
int finalNewLevel = newLevel;
|
||||
skillDepot
|
||||
.getSkillsAndEnergySkill()
|
||||
.forEach(id -> setTalentLevel(sender, avatar, id, finalNewLevel));
|
||||
}
|
||||
case "getid" -> {
|
||||
var map = GameData.getAvatarSkillDataMap();
|
||||
skillDepot
|
||||
.getSkillsAndEnergySkill()
|
||||
.forEach(
|
||||
id -> {
|
||||
var talent = map.get(id);
|
||||
if (talent == null) return;
|
||||
var talentName = Language.getTextMapKey(talent.getNameTextMapHash());
|
||||
var talentDesc = Language.getTextMapKey(talent.getDescTextMapHash());
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.talent.id_desc", id, talentName, talentDesc);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,156 +1,156 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.activity.trialavatar.TrialAvatarActivityHandler;
|
||||
import emu.grasscutter.game.activity.trialavatar.TrialAvatarPlayerData;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActivityType;
|
||||
import emu.grasscutter.server.packet.send.PacketActivityInfoNotify;
|
||||
import emu.grasscutter.utils.JsonUtils;
|
||||
import java.util.List;
|
||||
|
||||
@Command(
|
||||
label = "trialAvatarActivity",
|
||||
aliases = {"taa"},
|
||||
usage = {
|
||||
"change <scheduleId>",
|
||||
"toggleDungeon <index(start from 1)|all>",
|
||||
"toggleReward <index(start from 1)|all>"
|
||||
},
|
||||
permission = "player.trialavataractivity",
|
||||
permissionTargeted = "player.trialavataractivity.others")
|
||||
public final class TrialAvatarActivityCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 2) {
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
var action = args.get(0).toLowerCase();
|
||||
var param = args.get(1);
|
||||
|
||||
var playerDataOption =
|
||||
targetPlayer
|
||||
.getActivityManager()
|
||||
.getPlayerActivityDataByActivityType(ActivityType.NEW_ACTIVITY_TRIAL_AVATAR);
|
||||
if (playerDataOption.isEmpty()) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.not_found"));
|
||||
return;
|
||||
}
|
||||
|
||||
var playerData = playerDataOption.get();
|
||||
var handler = (TrialAvatarActivityHandler) playerData.getActivityHandler();
|
||||
if (handler == null) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.not_found"));
|
||||
return;
|
||||
}
|
||||
|
||||
var trialAvatarPlayerData =
|
||||
JsonUtils.decode(playerData.getDetail(), TrialAvatarPlayerData.class);
|
||||
if (trialAvatarPlayerData == null) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.not_found"));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
default -> this.sendUsageMessage(sender);
|
||||
case "change" -> {
|
||||
if (!param.chars().allMatch(Character::isDigit)) { // if its not number
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.invalid_param"));
|
||||
return;
|
||||
}
|
||||
if (TrialAvatarPlayerData.getAvatarIdList(Integer.parseInt(param)).isEmpty()) {
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
translate(
|
||||
sender,
|
||||
"commands.trialAvatarActivity.schedule_not_found",
|
||||
Integer.parseInt(param)));
|
||||
return;
|
||||
}
|
||||
playerData.setDetail(TrialAvatarPlayerData.create(Integer.parseInt(param)));
|
||||
playerData.save();
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
translate(
|
||||
sender, "commands.trialAvatarActivity.success_schedule", Integer.parseInt(param)));
|
||||
}
|
||||
case "toggledungeon" -> {
|
||||
if (param.chars().allMatch(Character::isDigit)) { // if its number
|
||||
if (Integer.parseInt(param) - 1 >= trialAvatarPlayerData.getRewardInfoList().size()
|
||||
|| Integer.parseInt(param) - 1 <= 0) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.invalid_param"));
|
||||
return;
|
||||
}
|
||||
TrialAvatarPlayerData.RewardInfoItem rewardInfo =
|
||||
trialAvatarPlayerData.getRewardInfoList().get(Integer.parseInt(param) - 1);
|
||||
rewardInfo.setPassedDungeon(!rewardInfo.isPassedDungeon());
|
||||
playerData.setDetail(trialAvatarPlayerData);
|
||||
playerData.save();
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
translate(
|
||||
sender, "commands.trialAvatarActivity.success_dungeon", Integer.parseInt(param)));
|
||||
} else {
|
||||
if (!param.equals("all")) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.invalid_param"));
|
||||
return;
|
||||
}
|
||||
trialAvatarPlayerData
|
||||
.getRewardInfoList()
|
||||
.forEach(r -> r.setPassedDungeon(!r.isPassedDungeon()));
|
||||
playerData.setDetail(trialAvatarPlayerData);
|
||||
playerData.save();
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.success_dungeon_all"));
|
||||
}
|
||||
}
|
||||
case "togglereward" -> {
|
||||
if (param.chars().allMatch(Character::isDigit)) { // if its number
|
||||
if (Integer.parseInt(param) - 1 >= trialAvatarPlayerData.getRewardInfoList().size()
|
||||
|| Integer.parseInt(param) - 1 <= 0) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.invalid_param"));
|
||||
return;
|
||||
}
|
||||
TrialAvatarPlayerData.RewardInfoItem rewardInfo =
|
||||
trialAvatarPlayerData.getRewardInfoList().get(Integer.parseInt(param) - 1);
|
||||
rewardInfo.setReceivedReward(!rewardInfo.isReceivedReward());
|
||||
playerData.setDetail(trialAvatarPlayerData);
|
||||
playerData.save();
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
translate(
|
||||
sender, "commands.trialAvatarActivity.success_reward", Integer.parseInt(param)));
|
||||
} else {
|
||||
if (!param.toLowerCase().equals("all")) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.invalid_param"));
|
||||
return;
|
||||
}
|
||||
trialAvatarPlayerData
|
||||
.getRewardInfoList()
|
||||
.forEach(r -> r.setReceivedReward(!r.isReceivedReward()));
|
||||
playerData.setDetail(trialAvatarPlayerData);
|
||||
playerData.save();
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.success_reward_all"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
targetPlayer.sendPacket(
|
||||
new PacketActivityInfoNotify(
|
||||
handler.toProto(playerData, targetPlayer.getActivityManager().getConditionExecutor())));
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.activity.trialavatar.TrialAvatarActivityHandler;
|
||||
import emu.grasscutter.game.activity.trialavatar.TrialAvatarPlayerData;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ActivityType;
|
||||
import emu.grasscutter.server.packet.send.PacketActivityInfoNotify;
|
||||
import emu.grasscutter.utils.JsonUtils;
|
||||
import java.util.List;
|
||||
|
||||
@Command(
|
||||
label = "trialAvatarActivity",
|
||||
aliases = {"taa"},
|
||||
usage = {
|
||||
"change <scheduleId>",
|
||||
"toggleDungeon <index(start from 1)|all>",
|
||||
"toggleReward <index(start from 1)|all>"
|
||||
},
|
||||
permission = "player.trialavataractivity",
|
||||
permissionTargeted = "player.trialavataractivity.others")
|
||||
public final class TrialAvatarActivityCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 2) {
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
var action = args.get(0).toLowerCase();
|
||||
var param = args.get(1);
|
||||
|
||||
var playerDataOption =
|
||||
targetPlayer
|
||||
.getActivityManager()
|
||||
.getPlayerActivityDataByActivityType(ActivityType.NEW_ACTIVITY_TRIAL_AVATAR);
|
||||
if (playerDataOption.isEmpty()) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.not_found"));
|
||||
return;
|
||||
}
|
||||
|
||||
var playerData = playerDataOption.get();
|
||||
var handler = (TrialAvatarActivityHandler) playerData.getActivityHandler();
|
||||
if (handler == null) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.not_found"));
|
||||
return;
|
||||
}
|
||||
|
||||
var trialAvatarPlayerData =
|
||||
JsonUtils.decode(playerData.getDetail(), TrialAvatarPlayerData.class);
|
||||
if (trialAvatarPlayerData == null) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.not_found"));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
default -> this.sendUsageMessage(sender);
|
||||
case "change" -> {
|
||||
if (!param.chars().allMatch(Character::isDigit)) { // if its not number
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.invalid_param"));
|
||||
return;
|
||||
}
|
||||
if (TrialAvatarPlayerData.getAvatarIdList(Integer.parseInt(param)).isEmpty()) {
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
translate(
|
||||
sender,
|
||||
"commands.trialAvatarActivity.schedule_not_found",
|
||||
Integer.parseInt(param)));
|
||||
return;
|
||||
}
|
||||
playerData.setDetail(TrialAvatarPlayerData.create(Integer.parseInt(param)));
|
||||
playerData.save();
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
translate(
|
||||
sender, "commands.trialAvatarActivity.success_schedule", Integer.parseInt(param)));
|
||||
}
|
||||
case "toggledungeon" -> {
|
||||
if (param.chars().allMatch(Character::isDigit)) { // if its number
|
||||
if (Integer.parseInt(param) - 1 >= trialAvatarPlayerData.getRewardInfoList().size()
|
||||
|| Integer.parseInt(param) - 1 <= 0) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.invalid_param"));
|
||||
return;
|
||||
}
|
||||
TrialAvatarPlayerData.RewardInfoItem rewardInfo =
|
||||
trialAvatarPlayerData.getRewardInfoList().get(Integer.parseInt(param) - 1);
|
||||
rewardInfo.setPassedDungeon(!rewardInfo.isPassedDungeon());
|
||||
playerData.setDetail(trialAvatarPlayerData);
|
||||
playerData.save();
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
translate(
|
||||
sender, "commands.trialAvatarActivity.success_dungeon", Integer.parseInt(param)));
|
||||
} else {
|
||||
if (!param.equals("all")) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.invalid_param"));
|
||||
return;
|
||||
}
|
||||
trialAvatarPlayerData
|
||||
.getRewardInfoList()
|
||||
.forEach(r -> r.setPassedDungeon(!r.isPassedDungeon()));
|
||||
playerData.setDetail(trialAvatarPlayerData);
|
||||
playerData.save();
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.success_dungeon_all"));
|
||||
}
|
||||
}
|
||||
case "togglereward" -> {
|
||||
if (param.chars().allMatch(Character::isDigit)) { // if its number
|
||||
if (Integer.parseInt(param) - 1 >= trialAvatarPlayerData.getRewardInfoList().size()
|
||||
|| Integer.parseInt(param) - 1 <= 0) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.invalid_param"));
|
||||
return;
|
||||
}
|
||||
TrialAvatarPlayerData.RewardInfoItem rewardInfo =
|
||||
trialAvatarPlayerData.getRewardInfoList().get(Integer.parseInt(param) - 1);
|
||||
rewardInfo.setReceivedReward(!rewardInfo.isReceivedReward());
|
||||
playerData.setDetail(trialAvatarPlayerData);
|
||||
playerData.save();
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
translate(
|
||||
sender, "commands.trialAvatarActivity.success_reward", Integer.parseInt(param)));
|
||||
} else {
|
||||
if (!param.toLowerCase().equals("all")) {
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.invalid_param"));
|
||||
return;
|
||||
}
|
||||
trialAvatarPlayerData
|
||||
.getRewardInfoList()
|
||||
.forEach(r -> r.setReceivedReward(!r.isReceivedReward()));
|
||||
playerData.setDetail(trialAvatarPlayerData);
|
||||
playerData.save();
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.trialAvatarActivity.success_reward_all"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
targetPlayer.sendPacket(
|
||||
new PacketActivityInfoNotify(
|
||||
handler.toProto(playerData, targetPlayer.getActivityManager().getConditionExecutor())));
|
||||
}
|
||||
}
|
||||
|
@ -1,118 +1,118 @@
|
||||
package emu.grasscutter.config;
|
||||
|
||||
import static emu.grasscutter.Grasscutter.config;
|
||||
|
||||
import emu.grasscutter.utils.FileUtils;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* A data container for the server's configuration.
|
||||
*
|
||||
* <p>Use `import static emu.grasscutter.Configuration.*;` to import all configuration constants.
|
||||
*/
|
||||
public final class Configuration extends ConfigContainer {
|
||||
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
|
||||
// 'c' is short for 'config' and makes code look 'cleaner'.
|
||||
public static final ConfigContainer c = config;
|
||||
|
||||
public static final Locale LANGUAGE = config.language.language;
|
||||
public static final Locale FALLBACK_LANGUAGE = config.language.fallback;
|
||||
public static final String DOCUMENT_LANGUAGE = config.language.document;
|
||||
public static final Server SERVER = config.server;
|
||||
public static final Database DATABASE = config.databaseInfo;
|
||||
public static final Account ACCOUNT = config.account;
|
||||
public static final HTTP HTTP_INFO = config.server.http;
|
||||
public static final Game GAME_INFO = config.server.game;
|
||||
public static final Dispatch DISPATCH_INFO = config.server.dispatch;
|
||||
public static final DebugMode DEBUG_MODE_INFO = config.server.debugMode;
|
||||
public static final Encryption HTTP_ENCRYPTION = config.server.http.encryption;
|
||||
public static final Policies HTTP_POLICIES = config.server.http.policies;
|
||||
public static final Files HTTP_STATIC_FILES = config.server.http.files;
|
||||
public static final GameOptions GAME_OPTIONS = config.server.game.gameOptions;
|
||||
public static final GameOptions.InventoryLimits INVENTORY_LIMITS =
|
||||
config.server.game.gameOptions.inventoryLimits;
|
||||
private static final String DATA_FOLDER = config.folderStructure.data;
|
||||
private static final String PLUGINS_FOLDER = config.folderStructure.plugins;
|
||||
private static final String SCRIPTS_FOLDER = config.folderStructure.scripts;
|
||||
private static final String PACKETS_FOLDER = config.folderStructure.packets;
|
||||
|
||||
/*
|
||||
* Utilities
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static String DATA() {
|
||||
return DATA_FOLDER;
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static String DATA(String path) {
|
||||
return Path.of(DATA_FOLDER, path).toString();
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static Path getResourcePath(String path) {
|
||||
return FileUtils.getResourcePath(path);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static String RESOURCE(String path) {
|
||||
return FileUtils.getResourcePath(path).toString();
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static String PLUGIN() {
|
||||
return PLUGINS_FOLDER;
|
||||
}
|
||||
|
||||
public static String PLUGIN(String path) {
|
||||
return Path.of(PLUGINS_FOLDER, path).toString();
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static String SCRIPT(String path) {
|
||||
return Path.of(SCRIPTS_FOLDER, path).toString();
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static String PACKET(String path) {
|
||||
return Path.of(PACKETS_FOLDER, path).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback method.
|
||||
*
|
||||
* @param left Attempt to use.
|
||||
* @param right Use if left is undefined.
|
||||
* @return Left or right.
|
||||
*/
|
||||
public static <T> T lr(T left, T right) {
|
||||
return left == null ? right : left;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Configuration#lr(Object, Object)} for {@link String}s.
|
||||
*
|
||||
* @param left Attempt to use.
|
||||
* @param right Use if left is empty.
|
||||
* @return Left or right.
|
||||
*/
|
||||
public static String lr(String left, String right) {
|
||||
return left.isEmpty() ? right : left;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Configuration#lr(Object, Object)} for {@link Integer}s.
|
||||
*
|
||||
* @param left Attempt to use.
|
||||
* @param right Use if left is 0.
|
||||
* @return Left or right.
|
||||
*/
|
||||
public static int lr(int left, int right) {
|
||||
return left == 0 ? right : left;
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.config;
|
||||
|
||||
import static emu.grasscutter.Grasscutter.config;
|
||||
|
||||
import emu.grasscutter.utils.FileUtils;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* A data container for the server's configuration.
|
||||
*
|
||||
* <p>Use `import static emu.grasscutter.Configuration.*;` to import all configuration constants.
|
||||
*/
|
||||
public final class Configuration extends ConfigContainer {
|
||||
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
|
||||
// 'c' is short for 'config' and makes code look 'cleaner'.
|
||||
public static final ConfigContainer c = config;
|
||||
|
||||
public static final Locale LANGUAGE = config.language.language;
|
||||
public static final Locale FALLBACK_LANGUAGE = config.language.fallback;
|
||||
public static final String DOCUMENT_LANGUAGE = config.language.document;
|
||||
public static final Server SERVER = config.server;
|
||||
public static final Database DATABASE = config.databaseInfo;
|
||||
public static final Account ACCOUNT = config.account;
|
||||
public static final HTTP HTTP_INFO = config.server.http;
|
||||
public static final Game GAME_INFO = config.server.game;
|
||||
public static final Dispatch DISPATCH_INFO = config.server.dispatch;
|
||||
public static final DebugMode DEBUG_MODE_INFO = config.server.debugMode;
|
||||
public static final Encryption HTTP_ENCRYPTION = config.server.http.encryption;
|
||||
public static final Policies HTTP_POLICIES = config.server.http.policies;
|
||||
public static final Files HTTP_STATIC_FILES = config.server.http.files;
|
||||
public static final GameOptions GAME_OPTIONS = config.server.game.gameOptions;
|
||||
public static final GameOptions.InventoryLimits INVENTORY_LIMITS =
|
||||
config.server.game.gameOptions.inventoryLimits;
|
||||
private static final String DATA_FOLDER = config.folderStructure.data;
|
||||
private static final String PLUGINS_FOLDER = config.folderStructure.plugins;
|
||||
private static final String SCRIPTS_FOLDER = config.folderStructure.scripts;
|
||||
private static final String PACKETS_FOLDER = config.folderStructure.packets;
|
||||
|
||||
/*
|
||||
* Utilities
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static String DATA() {
|
||||
return DATA_FOLDER;
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static String DATA(String path) {
|
||||
return Path.of(DATA_FOLDER, path).toString();
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static Path getResourcePath(String path) {
|
||||
return FileUtils.getResourcePath(path);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static String RESOURCE(String path) {
|
||||
return FileUtils.getResourcePath(path).toString();
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static String PLUGIN() {
|
||||
return PLUGINS_FOLDER;
|
||||
}
|
||||
|
||||
public static String PLUGIN(String path) {
|
||||
return Path.of(PLUGINS_FOLDER, path).toString();
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static String SCRIPT(String path) {
|
||||
return Path.of(SCRIPTS_FOLDER, path).toString();
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static String PACKET(String path) {
|
||||
return Path.of(PACKETS_FOLDER, path).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback method.
|
||||
*
|
||||
* @param left Attempt to use.
|
||||
* @param right Use if left is undefined.
|
||||
* @return Left or right.
|
||||
*/
|
||||
public static <T> T lr(T left, T right) {
|
||||
return left == null ? right : left;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Configuration#lr(Object, Object)} for {@link String}s.
|
||||
*
|
||||
* @param left Attempt to use.
|
||||
* @param right Use if left is empty.
|
||||
* @return Left or right.
|
||||
*/
|
||||
public static String lr(String left, String right) {
|
||||
return left.isEmpty() ? right : left;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Configuration#lr(Object, Object)} for {@link Integer}s.
|
||||
*
|
||||
* @param left Attempt to use.
|
||||
* @param right Use if left is 0.
|
||||
* @return Left or right.
|
||||
*/
|
||||
public static int lr(int left, int right) {
|
||||
return left == 0 ? right : left;
|
||||
}
|
||||
}
|
||||
|
@ -1,86 +1,86 @@
|
||||
package emu.grasscutter.data;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.ResourceLoader.AvatarConfig;
|
||||
import emu.grasscutter.data.excels.reliquary.ReliquaryAffixData;
|
||||
import emu.grasscutter.data.excels.reliquary.ReliquaryMainPropData;
|
||||
import emu.grasscutter.game.managers.blossom.BlossomConfig;
|
||||
import emu.grasscutter.game.world.SpawnDataEntry;
|
||||
import emu.grasscutter.utils.WeightedList;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class GameDepot {
|
||||
public static final int[] BLOCK_SIZE = new int[] {50, 500}; // Scales
|
||||
|
||||
private static final Int2ObjectMap<WeightedList<ReliquaryMainPropData>> relicRandomMainPropDepot =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<List<ReliquaryMainPropData>> relicMainPropDepot =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<List<ReliquaryAffixData>> relicAffixDepot =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter @Setter private static Map<String, AvatarConfig> playerAbilities = new HashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final HashMap<SpawnDataEntry.GridBlockId, ArrayList<SpawnDataEntry>> spawnLists =
|
||||
new HashMap<>();
|
||||
|
||||
@Getter @Setter private static BlossomConfig blossomConfig;
|
||||
|
||||
public static void load() {
|
||||
for (ReliquaryMainPropData data : GameData.getReliquaryMainPropDataMap().values()) {
|
||||
if (data.getWeight() <= 0 || data.getPropDepotId() <= 0) {
|
||||
continue;
|
||||
}
|
||||
List<ReliquaryMainPropData> list =
|
||||
relicMainPropDepot.computeIfAbsent(data.getPropDepotId(), k -> new ArrayList<>());
|
||||
list.add(data);
|
||||
WeightedList<ReliquaryMainPropData> weightedList =
|
||||
relicRandomMainPropDepot.computeIfAbsent(
|
||||
data.getPropDepotId(), k -> new WeightedList<>());
|
||||
weightedList.add(data.getWeight(), data);
|
||||
}
|
||||
for (ReliquaryAffixData data : GameData.getReliquaryAffixDataMap().values()) {
|
||||
if (data.getWeight() <= 0 || data.getDepotId() <= 0) {
|
||||
continue;
|
||||
}
|
||||
List<ReliquaryAffixData> list =
|
||||
relicAffixDepot.computeIfAbsent(data.getDepotId(), k -> new ArrayList<>());
|
||||
list.add(data);
|
||||
}
|
||||
// Let the server owner know if theyre missing weights
|
||||
if (relicMainPropDepot.size() == 0 || relicAffixDepot.size() == 0) {
|
||||
Grasscutter.getLogger()
|
||||
.error(
|
||||
"Relic properties are missing weights! Please check your ReliquaryMainPropExcelConfigData or ReliquaryAffixExcelConfigData files in your ExcelBinOutput folder.");
|
||||
}
|
||||
}
|
||||
|
||||
public static ReliquaryMainPropData getRandomRelicMainProp(int depot) {
|
||||
WeightedList<ReliquaryMainPropData> depotList = relicRandomMainPropDepot.get(depot);
|
||||
if (depotList == null) {
|
||||
return null;
|
||||
}
|
||||
return depotList.next();
|
||||
}
|
||||
|
||||
public static List<ReliquaryMainPropData> getRelicMainPropList(int depot) {
|
||||
return relicMainPropDepot.get(depot);
|
||||
}
|
||||
|
||||
public static List<ReliquaryAffixData> getRelicAffixList(int depot) {
|
||||
return relicAffixDepot.get(depot);
|
||||
}
|
||||
|
||||
public static void addSpawnListById(
|
||||
HashMap<SpawnDataEntry.GridBlockId, ArrayList<SpawnDataEntry>> data) {
|
||||
spawnLists.putAll(data);
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.ResourceLoader.AvatarConfig;
|
||||
import emu.grasscutter.data.excels.reliquary.ReliquaryAffixData;
|
||||
import emu.grasscutter.data.excels.reliquary.ReliquaryMainPropData;
|
||||
import emu.grasscutter.game.managers.blossom.BlossomConfig;
|
||||
import emu.grasscutter.game.world.SpawnDataEntry;
|
||||
import emu.grasscutter.utils.WeightedList;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class GameDepot {
|
||||
public static final int[] BLOCK_SIZE = new int[] {50, 500}; // Scales
|
||||
|
||||
private static final Int2ObjectMap<WeightedList<ReliquaryMainPropData>> relicRandomMainPropDepot =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<List<ReliquaryMainPropData>> relicMainPropDepot =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<List<ReliquaryAffixData>> relicAffixDepot =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter @Setter private static Map<String, AvatarConfig> playerAbilities = new HashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final HashMap<SpawnDataEntry.GridBlockId, ArrayList<SpawnDataEntry>> spawnLists =
|
||||
new HashMap<>();
|
||||
|
||||
@Getter @Setter private static BlossomConfig blossomConfig;
|
||||
|
||||
public static void load() {
|
||||
for (ReliquaryMainPropData data : GameData.getReliquaryMainPropDataMap().values()) {
|
||||
if (data.getWeight() <= 0 || data.getPropDepotId() <= 0) {
|
||||
continue;
|
||||
}
|
||||
List<ReliquaryMainPropData> list =
|
||||
relicMainPropDepot.computeIfAbsent(data.getPropDepotId(), k -> new ArrayList<>());
|
||||
list.add(data);
|
||||
WeightedList<ReliquaryMainPropData> weightedList =
|
||||
relicRandomMainPropDepot.computeIfAbsent(
|
||||
data.getPropDepotId(), k -> new WeightedList<>());
|
||||
weightedList.add(data.getWeight(), data);
|
||||
}
|
||||
for (ReliquaryAffixData data : GameData.getReliquaryAffixDataMap().values()) {
|
||||
if (data.getWeight() <= 0 || data.getDepotId() <= 0) {
|
||||
continue;
|
||||
}
|
||||
List<ReliquaryAffixData> list =
|
||||
relicAffixDepot.computeIfAbsent(data.getDepotId(), k -> new ArrayList<>());
|
||||
list.add(data);
|
||||
}
|
||||
// Let the server owner know if theyre missing weights
|
||||
if (relicMainPropDepot.size() == 0 || relicAffixDepot.size() == 0) {
|
||||
Grasscutter.getLogger()
|
||||
.error(
|
||||
"Relic properties are missing weights! Please check your ReliquaryMainPropExcelConfigData or ReliquaryAffixExcelConfigData files in your ExcelBinOutput folder.");
|
||||
}
|
||||
}
|
||||
|
||||
public static ReliquaryMainPropData getRandomRelicMainProp(int depot) {
|
||||
WeightedList<ReliquaryMainPropData> depotList = relicRandomMainPropDepot.get(depot);
|
||||
if (depotList == null) {
|
||||
return null;
|
||||
}
|
||||
return depotList.next();
|
||||
}
|
||||
|
||||
public static List<ReliquaryMainPropData> getRelicMainPropList(int depot) {
|
||||
return relicMainPropDepot.get(depot);
|
||||
}
|
||||
|
||||
public static List<ReliquaryAffixData> getRelicAffixList(int depot) {
|
||||
return relicAffixDepot.get(depot);
|
||||
}
|
||||
|
||||
public static void addSpawnListById(
|
||||
HashMap<SpawnDataEntry.GridBlockId, ArrayList<SpawnDataEntry>> data) {
|
||||
spawnLists.putAll(data);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,3 @@
|
||||
package emu.grasscutter.data.binout.config;
|
||||
|
||||
public class ConfigEntityAvatar extends ConfigEntityBase {}
|
||||
package emu.grasscutter.data.binout.config;
|
||||
|
||||
public class ConfigEntityAvatar extends ConfigEntityBase {}
|
||||
|
@ -1,17 +1,17 @@
|
||||
package emu.grasscutter.data.binout.config;
|
||||
|
||||
import emu.grasscutter.data.binout.config.fields.ConfigAbilityData;
|
||||
import emu.grasscutter.data.binout.config.fields.ConfigCombat;
|
||||
import emu.grasscutter.data.binout.config.fields.ConfigCommon;
|
||||
import emu.grasscutter.data.binout.config.fields.ConfigGlobalValue;
|
||||
import java.util.Collection;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ConfigEntityBase {
|
||||
@Nullable ConfigCommon configCommon;
|
||||
@Nullable ConfigCombat combat;
|
||||
Collection<ConfigAbilityData> abilities;
|
||||
ConfigGlobalValue globalValue; // used for SGV in monsters and Gadgets
|
||||
}
|
||||
package emu.grasscutter.data.binout.config;
|
||||
|
||||
import emu.grasscutter.data.binout.config.fields.ConfigAbilityData;
|
||||
import emu.grasscutter.data.binout.config.fields.ConfigCombat;
|
||||
import emu.grasscutter.data.binout.config.fields.ConfigCommon;
|
||||
import emu.grasscutter.data.binout.config.fields.ConfigGlobalValue;
|
||||
import java.util.Collection;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ConfigEntityBase {
|
||||
@Nullable ConfigCommon configCommon;
|
||||
@Nullable ConfigCombat combat;
|
||||
Collection<ConfigAbilityData> abilities;
|
||||
ConfigGlobalValue globalValue; // used for SGV in monsters and Gadgets
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
package emu.grasscutter.data.binout.config;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ConfigEntityGadget extends ConfigEntityBase {
|
||||
// There are more values that can be added that might be useful in the json
|
||||
}
|
||||
package emu.grasscutter.data.binout.config;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ConfigEntityGadget extends ConfigEntityBase {
|
||||
// There are more values that can be added that might be useful in the json
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package emu.grasscutter.data.binout.config;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ConfigEntityMonster extends ConfigEntityBase {}
|
||||
package emu.grasscutter.data.binout.config;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ConfigEntityMonster extends ConfigEntityBase {}
|
||||
|
@ -1,13 +1,13 @@
|
||||
package emu.grasscutter.data.binout.config;
|
||||
|
||||
import emu.grasscutter.data.binout.config.fields.ConfigAbilityData;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
|
||||
public class ConfigLevelEntity {
|
||||
|
||||
@Getter private List<ConfigAbilityData> abilities; // monster abilities
|
||||
@Getter private List<ConfigAbilityData> avatarAbilities;
|
||||
@Getter private List<ConfigAbilityData> teamAbilities;
|
||||
@Getter private List<Integer> preloadMonsterEntityIDs;
|
||||
}
|
||||
package emu.grasscutter.data.binout.config;
|
||||
|
||||
import emu.grasscutter.data.binout.config.fields.ConfigAbilityData;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
|
||||
public class ConfigLevelEntity {
|
||||
|
||||
@Getter private List<ConfigAbilityData> abilities; // monster abilities
|
||||
@Getter private List<ConfigAbilityData> avatarAbilities;
|
||||
@Getter private List<ConfigAbilityData> teamAbilities;
|
||||
@Getter private List<Integer> preloadMonsterEntityIDs;
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
package emu.grasscutter.data.binout.config.fields;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ConfigAbilityData {
|
||||
public String abilityID;
|
||||
public String abilityName;
|
||||
public String abilityOverride;
|
||||
}
|
||||
package emu.grasscutter.data.binout.config.fields;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ConfigAbilityData {
|
||||
public String abilityID;
|
||||
public String abilityName;
|
||||
public String abilityOverride;
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package emu.grasscutter.data.binout.config.fields;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ConfigAiBeta {
|
||||
boolean enable;
|
||||
}
|
||||
package emu.grasscutter.data.binout.config.fields;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ConfigAiBeta {
|
||||
boolean enable;
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
package emu.grasscutter.data.binout.config.fields;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ConfigCombat {
|
||||
// There are more values that can be added that might be useful in the json
|
||||
ConfigCombatProperty property;
|
||||
}
|
||||
package emu.grasscutter.data.binout.config.fields;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ConfigCombat {
|
||||
// There are more values that can be added that might be useful in the json
|
||||
ConfigCombatProperty property;
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
package emu.grasscutter.data.binout.config.fields;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ConfigCombatDie {
|
||||
@SerializedName(
|
||||
value = "dieEndTime",
|
||||
alternate = {"HGGPMFGGBNC"})
|
||||
double dieEndTime;
|
||||
|
||||
double dieForceDisappearTime;
|
||||
boolean hasAnimatorDie;
|
||||
}
|
||||
package emu.grasscutter.data.binout.config.fields;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ConfigCombatDie {
|
||||
@SerializedName(
|
||||
value = "dieEndTime",
|
||||
alternate = {"HGGPMFGGBNC"})
|
||||
double dieEndTime;
|
||||
|
||||
double dieForceDisappearTime;
|
||||
boolean hasAnimatorDie;
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
package emu.grasscutter.data.binout.config.fields;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ConfigCombatProperty {
|
||||
float HP;
|
||||
boolean isLockHP;
|
||||
boolean isInvincible;
|
||||
boolean isGhostToAllied;
|
||||
float attack;
|
||||
float defence;
|
||||
float weight;
|
||||
boolean useCreatorProperty;
|
||||
}
|
||||
package emu.grasscutter.data.binout.config.fields;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ConfigCombatProperty {
|
||||
float HP;
|
||||
boolean isLockHP;
|
||||
boolean isInvincible;
|
||||
boolean isGhostToAllied;
|
||||
float attack;
|
||||
float defence;
|
||||
float weight;
|
||||
boolean useCreatorProperty;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package emu.grasscutter.data.binout.config.fields;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ConfigCommon {}
|
||||
package emu.grasscutter.data.binout.config.fields;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ConfigCommon {}
|
||||
|
@ -1,12 +1,12 @@
|
||||
package emu.grasscutter.data.binout.config.fields;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import lombok.Data;
|
||||
|
||||
/** Contains information about the entities SGVs */
|
||||
@Data
|
||||
public class ConfigGlobalValue {
|
||||
Set<String> serverGlobalValues;
|
||||
Map<String, Float> initServerGlobalValues;
|
||||
}
|
||||
package emu.grasscutter.data.binout.config.fields;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import lombok.Data;
|
||||
|
||||
/** Contains information about the entities SGVs */
|
||||
@Data
|
||||
public class ConfigGlobalValue {
|
||||
Set<String> serverGlobalValues;
|
||||
Map<String, Float> initServerGlobalValues;
|
||||
}
|
||||
|
@ -1,22 +1,22 @@
|
||||
package emu.grasscutter.data.binout.routes;
|
||||
|
||||
// import emu.grasscutter.scripts.constants.IntValueEnum;
|
||||
import lombok.Getter;
|
||||
|
||||
public enum RotAngleType /*implements IntValueEnum */ {
|
||||
ROT_NONE(-1),
|
||||
ROT_ANGLE_X(0),
|
||||
ROT_ANGLE_Y(1),
|
||||
ROT_ANGLE_Z(2);
|
||||
|
||||
@Getter private final int id;
|
||||
|
||||
RotAngleType(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
// @Override
|
||||
public int getValue() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.binout.routes;
|
||||
|
||||
// import emu.grasscutter.scripts.constants.IntValueEnum;
|
||||
import lombok.Getter;
|
||||
|
||||
public enum RotAngleType /*implements IntValueEnum */ {
|
||||
ROT_NONE(-1),
|
||||
ROT_ANGLE_X(0),
|
||||
ROT_ANGLE_Y(1),
|
||||
ROT_ANGLE_Z(2);
|
||||
|
||||
@Getter private final int id;
|
||||
|
||||
RotAngleType(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
// @Override
|
||||
public int getValue() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package emu.grasscutter.data.binout.routes;
|
||||
|
||||
public enum RotType {
|
||||
ROT_NONE,
|
||||
ROT_ANGLE,
|
||||
ROT_ROUND
|
||||
}
|
||||
package emu.grasscutter.data.binout.routes;
|
||||
|
||||
public enum RotType {
|
||||
ROT_NONE,
|
||||
ROT_ANGLE,
|
||||
ROT_ROUND
|
||||
}
|
||||
|
@ -1,29 +1,29 @@
|
||||
package emu.grasscutter.data.binout.routes;
|
||||
|
||||
import emu.grasscutter.net.proto.RouteOuterClass;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import lombok.val;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class Route {
|
||||
private int localId;
|
||||
private String name;
|
||||
private RouteType type = RouteType.Unknown;
|
||||
private RoutePoint[] points;
|
||||
private float arriveRange; // optional
|
||||
private RotType rotType; // optional
|
||||
private RotAngleType rotAngleType; // optional
|
||||
|
||||
public RouteOuterClass.Route toProto() {
|
||||
val builder = RouteOuterClass.Route.newBuilder().setRouteType(type.getValue());
|
||||
if (points != null) {
|
||||
for (var routePoint : points) {
|
||||
builder.addRoutePoints(routePoint.toProto().setArriveRange(arriveRange));
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.binout.routes;
|
||||
|
||||
import emu.grasscutter.net.proto.RouteOuterClass;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import lombok.val;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class Route {
|
||||
private int localId;
|
||||
private String name;
|
||||
private RouteType type = RouteType.Unknown;
|
||||
private RoutePoint[] points;
|
||||
private float arriveRange; // optional
|
||||
private RotType rotType; // optional
|
||||
private RotAngleType rotAngleType; // optional
|
||||
|
||||
public RouteOuterClass.Route toProto() {
|
||||
val builder = RouteOuterClass.Route.newBuilder().setRouteType(type.getValue());
|
||||
if (points != null) {
|
||||
for (var routePoint : points) {
|
||||
builder.addRoutePoints(routePoint.toProto().setArriveRange(arriveRange));
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +1,31 @@
|
||||
package emu.grasscutter.data.binout.routes;
|
||||
|
||||
import emu.grasscutter.net.proto.RoutePointOuterClass;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import lombok.val;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class RoutePoint {
|
||||
private Position pos;
|
||||
private int speedLevel; // optional
|
||||
private float waitTime; // optional
|
||||
private float targetVelocity; // optional
|
||||
private boolean hasReachEvent; // optional
|
||||
// rotRoundReachDir //optional Pos with optional values
|
||||
// rotRoundLeaveDir //optional Pos with optional values
|
||||
|
||||
public RoutePointOuterClass.RoutePoint.Builder toProto() {
|
||||
val builder = RoutePointOuterClass.RoutePoint.newBuilder().setPosition(pos.toProto());
|
||||
if (waitTime != 0) {
|
||||
builder.setTime(waitTime);
|
||||
} else if (targetVelocity != 0) {
|
||||
builder.setVelocity(targetVelocity);
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.binout.routes;
|
||||
|
||||
import emu.grasscutter.net.proto.RoutePointOuterClass;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import lombok.val;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class RoutePoint {
|
||||
private Position pos;
|
||||
private int speedLevel; // optional
|
||||
private float waitTime; // optional
|
||||
private float targetVelocity; // optional
|
||||
private boolean hasReachEvent; // optional
|
||||
// rotRoundReachDir //optional Pos with optional values
|
||||
// rotRoundLeaveDir //optional Pos with optional values
|
||||
|
||||
public RoutePointOuterClass.RoutePoint.Builder toProto() {
|
||||
val builder = RoutePointOuterClass.RoutePoint.newBuilder().setPosition(pos.toProto());
|
||||
if (waitTime != 0) {
|
||||
builder.setTime(waitTime);
|
||||
} else if (targetVelocity != 0) {
|
||||
builder.setVelocity(targetVelocity);
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,22 @@
|
||||
package emu.grasscutter.data.binout.routes;
|
||||
|
||||
// import emu.grasscutter.scripts.constants.IntValueEnum;
|
||||
import lombok.Getter;
|
||||
|
||||
public enum RouteType /*implements IntValueEnum*/ {
|
||||
Unknown(-1),
|
||||
OneWay(0),
|
||||
Reciprocate(1),
|
||||
Loop(2);
|
||||
|
||||
@Getter private final int id;
|
||||
|
||||
RouteType(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
// @Override
|
||||
public int getValue() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.binout.routes;
|
||||
|
||||
// import emu.grasscutter.scripts.constants.IntValueEnum;
|
||||
import lombok.Getter;
|
||||
|
||||
public enum RouteType /*implements IntValueEnum*/ {
|
||||
Unknown(-1),
|
||||
OneWay(0),
|
||||
Reciprocate(1),
|
||||
Loop(2);
|
||||
|
||||
@Getter private final int id;
|
||||
|
||||
RouteType(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
// @Override
|
||||
public int getValue() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
package emu.grasscutter.data.binout.routes;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class SceneRoutes {
|
||||
private int sceneId;
|
||||
@Nullable private Route[] routes;
|
||||
}
|
||||
package emu.grasscutter.data.binout.routes;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class SceneRoutes {
|
||||
private int sceneId;
|
||||
@Nullable private Route[] routes;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package emu.grasscutter.data.common;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface BaseTrialActivityData {
|
||||
List<Integer> getAvatarIndexIdList();
|
||||
|
||||
List<Integer> getRewardIdList();
|
||||
}
|
||||
package emu.grasscutter.data.common;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface BaseTrialActivityData {
|
||||
List<Integer> getAvatarIndexIdList();
|
||||
|
||||
List<Integer> getRewardIdList();
|
||||
}
|
||||
|
@ -1,70 +1,70 @@
|
||||
package emu.grasscutter.data.common;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.dungeon.DailyDungeonData;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public final class PointData {
|
||||
@Getter @Setter private int id;
|
||||
private String $type;
|
||||
@Getter private Position tranPos;
|
||||
@Getter private Position pos;
|
||||
@Getter private Position rot;
|
||||
@Getter private Position size;
|
||||
|
||||
@SerializedName(
|
||||
value = "dungeonIds",
|
||||
alternate = {"JHHFPGJNMIN"})
|
||||
@Getter
|
||||
private int[] dungeonIds;
|
||||
|
||||
@SerializedName(
|
||||
value = "dungeonRandomList",
|
||||
alternate = {"OIBKFJNBLHO"})
|
||||
@Getter
|
||||
private int[] dungeonRandomList;
|
||||
|
||||
@SerializedName(
|
||||
value = "groupIDs",
|
||||
alternate = {"HFOBOOHKBGF"})
|
||||
@Getter
|
||||
private int[] groupIDs;
|
||||
|
||||
@SerializedName(
|
||||
value = "tranSceneId",
|
||||
alternate = {"JHBICGBAPIH"})
|
||||
@Getter
|
||||
@Setter
|
||||
private int tranSceneId;
|
||||
|
||||
public String getType() {
|
||||
return $type;
|
||||
}
|
||||
|
||||
public void updateDailyDungeon() {
|
||||
if (this.dungeonRandomList == null || this.dungeonRandomList.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
IntList newDungeons = new IntArrayList();
|
||||
int day = Grasscutter.getCurrentDayOfWeek();
|
||||
|
||||
for (int randomId : this.dungeonRandomList) {
|
||||
DailyDungeonData data = GameData.getDailyDungeonDataMap().get(randomId);
|
||||
|
||||
if (data != null) {
|
||||
for (int d : data.getDungeonsByDay(day)) {
|
||||
newDungeons.add(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.dungeonIds = newDungeons.toIntArray();
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.common;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.dungeon.DailyDungeonData;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public final class PointData {
|
||||
@Getter @Setter private int id;
|
||||
private String $type;
|
||||
@Getter private Position tranPos;
|
||||
@Getter private Position pos;
|
||||
@Getter private Position rot;
|
||||
@Getter private Position size;
|
||||
|
||||
@SerializedName(
|
||||
value = "dungeonIds",
|
||||
alternate = {"JHHFPGJNMIN"})
|
||||
@Getter
|
||||
private int[] dungeonIds;
|
||||
|
||||
@SerializedName(
|
||||
value = "dungeonRandomList",
|
||||
alternate = {"OIBKFJNBLHO"})
|
||||
@Getter
|
||||
private int[] dungeonRandomList;
|
||||
|
||||
@SerializedName(
|
||||
value = "groupIDs",
|
||||
alternate = {"HFOBOOHKBGF"})
|
||||
@Getter
|
||||
private int[] groupIDs;
|
||||
|
||||
@SerializedName(
|
||||
value = "tranSceneId",
|
||||
alternate = {"JHBICGBAPIH"})
|
||||
@Getter
|
||||
@Setter
|
||||
private int tranSceneId;
|
||||
|
||||
public String getType() {
|
||||
return $type;
|
||||
}
|
||||
|
||||
public void updateDailyDungeon() {
|
||||
if (this.dungeonRandomList == null || this.dungeonRandomList.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
IntList newDungeons = new IntArrayList();
|
||||
int day = Grasscutter.getCurrentDayOfWeek();
|
||||
|
||||
for (int randomId : this.dungeonRandomList) {
|
||||
DailyDungeonData data = GameData.getDailyDungeonDataMap().get(randomId);
|
||||
|
||||
if (data != null) {
|
||||
for (int d : data.getDungeonsByDay(day)) {
|
||||
newDungeons.add(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.dungeonIds = newDungeons.toIntArray();
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,17 @@
|
||||
package emu.grasscutter.data.custom;
|
||||
|
||||
import emu.grasscutter.data.common.BaseTrialActivityData;
|
||||
import java.util.List;
|
||||
import lombok.*;
|
||||
|
||||
@Data
|
||||
public class TrialAvatarActivityCustomData implements BaseTrialActivityData {
|
||||
private int ScheduleId;
|
||||
private List<Integer> AvatarIndexIdList;
|
||||
private List<Integer> RewardIdList;
|
||||
|
||||
public void onLoad() {
|
||||
this.AvatarIndexIdList = AvatarIndexIdList.stream().filter(x -> x > 0).toList();
|
||||
this.RewardIdList = RewardIdList.stream().filter(x -> x > 0).toList();
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.custom;
|
||||
|
||||
import emu.grasscutter.data.common.BaseTrialActivityData;
|
||||
import java.util.List;
|
||||
import lombok.*;
|
||||
|
||||
@Data
|
||||
public class TrialAvatarActivityCustomData implements BaseTrialActivityData {
|
||||
private int ScheduleId;
|
||||
private List<Integer> AvatarIndexIdList;
|
||||
private List<Integer> RewardIdList;
|
||||
|
||||
public void onLoad() {
|
||||
this.AvatarIndexIdList = AvatarIndexIdList.stream().filter(x -> x > 0).toList();
|
||||
this.RewardIdList = RewardIdList.stream().filter(x -> x > 0).toList();
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
package emu.grasscutter.data.custom;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.*;
|
||||
|
||||
@Data
|
||||
public class TrialAvatarCustomData {
|
||||
private int trialAvatarId;
|
||||
private List<String> trialAvatarParamList;
|
||||
private int coreProudSkillLevel;
|
||||
private int skillDepotId;
|
||||
|
||||
public void onLoad() {
|
||||
this.trialAvatarParamList = trialAvatarParamList.stream().filter(x -> !x.isBlank()).toList();
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.custom;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.*;
|
||||
|
||||
@Data
|
||||
public class TrialAvatarCustomData {
|
||||
private int trialAvatarId;
|
||||
private List<String> trialAvatarParamList;
|
||||
private int coreProudSkillLevel;
|
||||
private int skillDepotId;
|
||||
|
||||
public void onLoad() {
|
||||
this.trialAvatarParamList = trialAvatarParamList.stream().filter(x -> !x.isBlank()).toList();
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,22 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.props.EntityType;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "GadgetExcelConfigData.json")
|
||||
@Getter
|
||||
public final class GadgetData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int id;
|
||||
|
||||
private EntityType type;
|
||||
private String jsonName;
|
||||
private boolean isInteractive;
|
||||
private String[] tags;
|
||||
private String itemJsonName;
|
||||
private long nameTextMapHash;
|
||||
private int campId;
|
||||
private String visionLevel;
|
||||
}
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.props.EntityType;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "GadgetExcelConfigData.json")
|
||||
@Getter
|
||||
public final class GadgetData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int id;
|
||||
|
||||
private EntityType type;
|
||||
private String jsonName;
|
||||
private boolean isInteractive;
|
||||
private String[] tags;
|
||||
private String itemJsonName;
|
||||
private long nameTextMapHash;
|
||||
private int campId;
|
||||
private String visionLevel;
|
||||
}
|
||||
|
@ -1,27 +1,27 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@ResourceType(name = "GuideTriggerExcelConfigData.json")
|
||||
public class GuideTriggerData extends GameResource {
|
||||
// more like open state guide than quest guide
|
||||
private int id; // dont use, just to prevent resource loader from not functioning
|
||||
private String guideName;
|
||||
private String type;
|
||||
private String openState;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void onLoad() {
|
||||
GameData.getGuideTriggerDataStringMap().put(getGuideName(), this);
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@ResourceType(name = "GuideTriggerExcelConfigData.json")
|
||||
public class GuideTriggerData extends GameResource {
|
||||
// more like open state guide than quest guide
|
||||
private int id; // dont use, just to prevent resource loader from not functioning
|
||||
private String guideName;
|
||||
private String type;
|
||||
private String openState;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void onLoad() {
|
||||
GameData.getGuideTriggerDataStringMap().put(getGuideName(), this);
|
||||
}
|
||||
}
|
||||
|
@ -1,154 +1,154 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.common.ItemUseData;
|
||||
import emu.grasscutter.game.inventory.EquipType;
|
||||
import emu.grasscutter.game.inventory.ItemType;
|
||||
import emu.grasscutter.game.inventory.MaterialType;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.game.props.ItemUseAction.ItemUseAction;
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
import emu.grasscutter.game.props.ItemUseTarget;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(
|
||||
name = {
|
||||
"MaterialExcelConfigData.json",
|
||||
"WeaponExcelConfigData.json",
|
||||
"ReliquaryExcelConfigData.json",
|
||||
"HomeWorldFurnitureExcelConfigData.json"
|
||||
})
|
||||
@Getter
|
||||
public class ItemData extends GameResource {
|
||||
// Main
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int id;
|
||||
|
||||
private final int stackLimit = 1;
|
||||
private int maxUseCount;
|
||||
private int rankLevel;
|
||||
private String effectName;
|
||||
private int rank;
|
||||
private int weight;
|
||||
private int gadgetId;
|
||||
|
||||
private int[] destroyReturnMaterial;
|
||||
private int[] destroyReturnMaterialCount;
|
||||
|
||||
// Enums
|
||||
private final ItemType itemType = ItemType.ITEM_NONE;
|
||||
private MaterialType materialType = MaterialType.MATERIAL_NONE;
|
||||
private EquipType equipType = EquipType.EQUIP_NONE;
|
||||
private String effectType;
|
||||
private String destroyRule;
|
||||
|
||||
// Food
|
||||
private String foodQuality;
|
||||
private int[] satiationParams;
|
||||
|
||||
// Usable item
|
||||
private final ItemUseTarget useTarget = ItemUseTarget.ITEM_USE_TARGET_NONE;
|
||||
private List<ItemUseData> itemUse;
|
||||
private List<ItemUseAction> itemUseActions;
|
||||
private final boolean useOnGain = false;
|
||||
|
||||
// Relic
|
||||
private int mainPropDepotId;
|
||||
private int appendPropDepotId;
|
||||
private int appendPropNum;
|
||||
private int setId;
|
||||
private int[] addPropLevels;
|
||||
private int baseConvExp;
|
||||
private int maxLevel;
|
||||
|
||||
// Weapon
|
||||
private int weaponPromoteId;
|
||||
private int weaponBaseExp;
|
||||
private int storyId;
|
||||
private int avatarPromoteId;
|
||||
private int awakenMaterial;
|
||||
private int[] awakenCosts;
|
||||
private int[] skillAffix;
|
||||
private WeaponProperty[] weaponProp;
|
||||
|
||||
// Hash
|
||||
private long nameTextMapHash;
|
||||
|
||||
// Furniture
|
||||
private int comfort;
|
||||
private List<Integer> furnType;
|
||||
private List<Integer> furnitureGadgetID;
|
||||
|
||||
@SerializedName(
|
||||
value = "roomSceneId",
|
||||
alternate = {"BMEPAMCNABE", "DANFGGLKLNO", "JFDLJGDFIGL", "OHIANNAEEAK", "MFGACDIOHGF"})
|
||||
private int roomSceneId;
|
||||
|
||||
// Custom
|
||||
private transient IntSet addPropLevelSet;
|
||||
|
||||
public WeaponProperty[] getWeaponProperties() {
|
||||
return this.weaponProp;
|
||||
}
|
||||
|
||||
public boolean canAddRelicProp(int level) {
|
||||
return this.addPropLevelSet != null && this.addPropLevelSet.contains(level);
|
||||
}
|
||||
|
||||
public boolean isEquip() {
|
||||
return this.itemType == ItemType.ITEM_RELIQUARY || this.itemType == ItemType.ITEM_WEAPON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
if (this.itemType == ItemType.ITEM_RELIQUARY) {
|
||||
if (this.addPropLevels != null && this.addPropLevels.length > 0) {
|
||||
this.addPropLevelSet = new IntOpenHashSet(this.addPropLevels);
|
||||
}
|
||||
} else if (this.itemType == ItemType.ITEM_WEAPON) {
|
||||
this.equipType = EquipType.EQUIP_WEAPON;
|
||||
} else {
|
||||
this.equipType = EquipType.EQUIP_NONE;
|
||||
}
|
||||
|
||||
if (this.weaponProp != null) {
|
||||
this.weaponProp =
|
||||
Arrays.stream(this.weaponProp)
|
||||
.filter(prop -> prop.getPropType() != null)
|
||||
.toArray(WeaponProperty[]::new);
|
||||
}
|
||||
|
||||
if (this.getFurnType() != null) {
|
||||
this.furnType = this.furnType.stream().filter(x -> x > 0).toList();
|
||||
}
|
||||
if (this.getFurnitureGadgetID() != null) {
|
||||
this.furnitureGadgetID = this.furnitureGadgetID.stream().filter(x -> x > 0).toList();
|
||||
}
|
||||
|
||||
// Prevent material type from being null
|
||||
this.materialType = this.materialType == null ? MaterialType.MATERIAL_NONE : this.materialType;
|
||||
|
||||
if (this.itemUse != null && !this.itemUse.isEmpty()) {
|
||||
this.itemUseActions =
|
||||
this.itemUse.stream()
|
||||
.filter(x -> x.getUseOp() != ItemUseOp.ITEM_USE_NONE)
|
||||
.map(ItemUseAction::fromItemUseData)
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class WeaponProperty {
|
||||
private FightProperty propType;
|
||||
private float initValue;
|
||||
private String type;
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.common.ItemUseData;
|
||||
import emu.grasscutter.game.inventory.EquipType;
|
||||
import emu.grasscutter.game.inventory.ItemType;
|
||||
import emu.grasscutter.game.inventory.MaterialType;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.game.props.ItemUseAction.ItemUseAction;
|
||||
import emu.grasscutter.game.props.ItemUseOp;
|
||||
import emu.grasscutter.game.props.ItemUseTarget;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(
|
||||
name = {
|
||||
"MaterialExcelConfigData.json",
|
||||
"WeaponExcelConfigData.json",
|
||||
"ReliquaryExcelConfigData.json",
|
||||
"HomeWorldFurnitureExcelConfigData.json"
|
||||
})
|
||||
@Getter
|
||||
public class ItemData extends GameResource {
|
||||
// Main
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int id;
|
||||
|
||||
private final int stackLimit = 1;
|
||||
private int maxUseCount;
|
||||
private int rankLevel;
|
||||
private String effectName;
|
||||
private int rank;
|
||||
private int weight;
|
||||
private int gadgetId;
|
||||
|
||||
private int[] destroyReturnMaterial;
|
||||
private int[] destroyReturnMaterialCount;
|
||||
|
||||
// Enums
|
||||
private final ItemType itemType = ItemType.ITEM_NONE;
|
||||
private MaterialType materialType = MaterialType.MATERIAL_NONE;
|
||||
private EquipType equipType = EquipType.EQUIP_NONE;
|
||||
private String effectType;
|
||||
private String destroyRule;
|
||||
|
||||
// Food
|
||||
private String foodQuality;
|
||||
private int[] satiationParams;
|
||||
|
||||
// Usable item
|
||||
private final ItemUseTarget useTarget = ItemUseTarget.ITEM_USE_TARGET_NONE;
|
||||
private List<ItemUseData> itemUse;
|
||||
private List<ItemUseAction> itemUseActions;
|
||||
private final boolean useOnGain = false;
|
||||
|
||||
// Relic
|
||||
private int mainPropDepotId;
|
||||
private int appendPropDepotId;
|
||||
private int appendPropNum;
|
||||
private int setId;
|
||||
private int[] addPropLevels;
|
||||
private int baseConvExp;
|
||||
private int maxLevel;
|
||||
|
||||
// Weapon
|
||||
private int weaponPromoteId;
|
||||
private int weaponBaseExp;
|
||||
private int storyId;
|
||||
private int avatarPromoteId;
|
||||
private int awakenMaterial;
|
||||
private int[] awakenCosts;
|
||||
private int[] skillAffix;
|
||||
private WeaponProperty[] weaponProp;
|
||||
|
||||
// Hash
|
||||
private long nameTextMapHash;
|
||||
|
||||
// Furniture
|
||||
private int comfort;
|
||||
private List<Integer> furnType;
|
||||
private List<Integer> furnitureGadgetID;
|
||||
|
||||
@SerializedName(
|
||||
value = "roomSceneId",
|
||||
alternate = {"BMEPAMCNABE", "DANFGGLKLNO", "JFDLJGDFIGL", "OHIANNAEEAK", "MFGACDIOHGF"})
|
||||
private int roomSceneId;
|
||||
|
||||
// Custom
|
||||
private transient IntSet addPropLevelSet;
|
||||
|
||||
public WeaponProperty[] getWeaponProperties() {
|
||||
return this.weaponProp;
|
||||
}
|
||||
|
||||
public boolean canAddRelicProp(int level) {
|
||||
return this.addPropLevelSet != null && this.addPropLevelSet.contains(level);
|
||||
}
|
||||
|
||||
public boolean isEquip() {
|
||||
return this.itemType == ItemType.ITEM_RELIQUARY || this.itemType == ItemType.ITEM_WEAPON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
if (this.itemType == ItemType.ITEM_RELIQUARY) {
|
||||
if (this.addPropLevels != null && this.addPropLevels.length > 0) {
|
||||
this.addPropLevelSet = new IntOpenHashSet(this.addPropLevels);
|
||||
}
|
||||
} else if (this.itemType == ItemType.ITEM_WEAPON) {
|
||||
this.equipType = EquipType.EQUIP_WEAPON;
|
||||
} else {
|
||||
this.equipType = EquipType.EQUIP_NONE;
|
||||
}
|
||||
|
||||
if (this.weaponProp != null) {
|
||||
this.weaponProp =
|
||||
Arrays.stream(this.weaponProp)
|
||||
.filter(prop -> prop.getPropType() != null)
|
||||
.toArray(WeaponProperty[]::new);
|
||||
}
|
||||
|
||||
if (this.getFurnType() != null) {
|
||||
this.furnType = this.furnType.stream().filter(x -> x > 0).toList();
|
||||
}
|
||||
if (this.getFurnitureGadgetID() != null) {
|
||||
this.furnitureGadgetID = this.furnitureGadgetID.stream().filter(x -> x > 0).toList();
|
||||
}
|
||||
|
||||
// Prevent material type from being null
|
||||
this.materialType = this.materialType == null ? MaterialType.MATERIAL_NONE : this.materialType;
|
||||
|
||||
if (this.itemUse != null && !this.itemUse.isEmpty()) {
|
||||
this.itemUseActions =
|
||||
this.itemUse.stream()
|
||||
.filter(x -> x.getUseOp() != ItemUseOp.ITEM_USE_NONE)
|
||||
.map(ItemUseAction::fromItemUseData)
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class WeaponProperty {
|
||||
private FightProperty propType;
|
||||
private float initValue;
|
||||
private String type;
|
||||
}
|
||||
}
|
||||
|
@ -1,140 +1,140 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.quest.enums.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.*;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@ResourceType(name = "QuestExcelConfigData.json")
|
||||
@Getter
|
||||
@ToString
|
||||
public class QuestData extends GameResource {
|
||||
@Getter private int subId;
|
||||
@Getter private int mainId;
|
||||
@Getter private int order;
|
||||
@Getter private long descTextMapHash;
|
||||
|
||||
@Getter private boolean finishParent;
|
||||
@Getter private boolean isRewind;
|
||||
|
||||
@Getter private LogicType acceptCondComb;
|
||||
@Getter private LogicType finishCondComb;
|
||||
@Getter private LogicType failCondComb;
|
||||
|
||||
@Getter private List<QuestAcceptCondition> acceptCond;
|
||||
@Getter private List<QuestContentCondition> finishCond;
|
||||
@Getter private List<QuestContentCondition> failCond;
|
||||
@Getter private List<QuestExecParam> beginExec;
|
||||
@Getter private List<QuestExecParam> finishExec;
|
||||
@Getter private List<QuestExecParam> failExec;
|
||||
@Getter private Guide guide;
|
||||
@Getter private List<Integer> trialAvatarList;
|
||||
|
||||
public static String questConditionKey(
|
||||
@Nonnull Enum<?> type, int firstParam, @Nullable String paramsStr) {
|
||||
return type.name() + firstParam + (paramsStr != null ? paramsStr : "");
|
||||
}
|
||||
|
||||
// ResourceLoader not happy if you remove getId() ~~
|
||||
public int getId() {
|
||||
return subId;
|
||||
}
|
||||
|
||||
public void onLoad() {
|
||||
this.acceptCond = acceptCond.stream().filter(p -> p.getType() != null).toList();
|
||||
this.finishCond = finishCond.stream().filter(p -> p.getType() != null).toList();
|
||||
this.failCond = failCond.stream().filter(p -> p.getType() != null).toList();
|
||||
|
||||
this.beginExec = beginExec.stream().filter(p -> p.type != null).toList();
|
||||
this.finishExec = finishExec.stream().filter(p -> p.type != null).toList();
|
||||
this.failExec = failExec.stream().filter(p -> p.type != null).toList();
|
||||
|
||||
if (this.acceptCondComb == null) this.acceptCondComb = LogicType.LOGIC_NONE;
|
||||
|
||||
if (this.finishCondComb == null) this.finishCondComb = LogicType.LOGIC_NONE;
|
||||
|
||||
if (this.failCondComb == null) this.failCondComb = LogicType.LOGIC_NONE;
|
||||
|
||||
addToCache();
|
||||
}
|
||||
|
||||
private void addToCache() {
|
||||
if (this.acceptCond == null) {
|
||||
Grasscutter.getLogger().warn("missing AcceptConditions for quest {}", getSubId());
|
||||
return;
|
||||
}
|
||||
|
||||
var cacheMap = GameData.getBeginCondQuestMap();
|
||||
if (getAcceptCond().isEmpty()) {
|
||||
var list =
|
||||
cacheMap.computeIfAbsent(
|
||||
QuestData.questConditionKey(QuestCond.QUEST_COND_NONE, 0, null),
|
||||
e -> new ArrayList<>());
|
||||
list.add(this);
|
||||
} else {
|
||||
this.getAcceptCond()
|
||||
.forEach(
|
||||
questCondition -> {
|
||||
if (questCondition.getType() == null) {
|
||||
Grasscutter.getLogger().warn("null accept type for quest {}", getSubId());
|
||||
return;
|
||||
}
|
||||
|
||||
var key = questCondition.asKey();
|
||||
var list = cacheMap.computeIfAbsent(key, e -> new ArrayList<>());
|
||||
list.add(this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public static class QuestExecParam {
|
||||
@SerializedName("_type")
|
||||
QuestExec type;
|
||||
|
||||
@SerializedName("_param")
|
||||
String[] param;
|
||||
|
||||
@SerializedName("_count")
|
||||
String count;
|
||||
}
|
||||
|
||||
public static class QuestAcceptCondition extends QuestCondition<QuestCond> {}
|
||||
|
||||
public static class QuestContentCondition extends QuestCondition<QuestContent> {}
|
||||
|
||||
@Data
|
||||
public static class QuestCondition<TYPE extends Enum<?> & QuestTrigger> {
|
||||
@SerializedName("_type")
|
||||
private TYPE type;
|
||||
|
||||
@SerializedName("_param")
|
||||
private int[] param;
|
||||
|
||||
@SerializedName("_param_str")
|
||||
private String paramStr;
|
||||
|
||||
@SerializedName("_count")
|
||||
private int count;
|
||||
|
||||
public String asKey() {
|
||||
return questConditionKey(getType(), getParam()[0], getParamStr());
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class Guide {
|
||||
private String type;
|
||||
private List<String> param;
|
||||
private int guideScene;
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.quest.enums.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.*;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@ResourceType(name = "QuestExcelConfigData.json")
|
||||
@Getter
|
||||
@ToString
|
||||
public class QuestData extends GameResource {
|
||||
@Getter private int subId;
|
||||
@Getter private int mainId;
|
||||
@Getter private int order;
|
||||
@Getter private long descTextMapHash;
|
||||
|
||||
@Getter private boolean finishParent;
|
||||
@Getter private boolean isRewind;
|
||||
|
||||
@Getter private LogicType acceptCondComb;
|
||||
@Getter private LogicType finishCondComb;
|
||||
@Getter private LogicType failCondComb;
|
||||
|
||||
@Getter private List<QuestAcceptCondition> acceptCond;
|
||||
@Getter private List<QuestContentCondition> finishCond;
|
||||
@Getter private List<QuestContentCondition> failCond;
|
||||
@Getter private List<QuestExecParam> beginExec;
|
||||
@Getter private List<QuestExecParam> finishExec;
|
||||
@Getter private List<QuestExecParam> failExec;
|
||||
@Getter private Guide guide;
|
||||
@Getter private List<Integer> trialAvatarList;
|
||||
|
||||
public static String questConditionKey(
|
||||
@Nonnull Enum<?> type, int firstParam, @Nullable String paramsStr) {
|
||||
return type.name() + firstParam + (paramsStr != null ? paramsStr : "");
|
||||
}
|
||||
|
||||
// ResourceLoader not happy if you remove getId() ~~
|
||||
public int getId() {
|
||||
return subId;
|
||||
}
|
||||
|
||||
public void onLoad() {
|
||||
this.acceptCond = acceptCond.stream().filter(p -> p.getType() != null).toList();
|
||||
this.finishCond = finishCond.stream().filter(p -> p.getType() != null).toList();
|
||||
this.failCond = failCond.stream().filter(p -> p.getType() != null).toList();
|
||||
|
||||
this.beginExec = beginExec.stream().filter(p -> p.type != null).toList();
|
||||
this.finishExec = finishExec.stream().filter(p -> p.type != null).toList();
|
||||
this.failExec = failExec.stream().filter(p -> p.type != null).toList();
|
||||
|
||||
if (this.acceptCondComb == null) this.acceptCondComb = LogicType.LOGIC_NONE;
|
||||
|
||||
if (this.finishCondComb == null) this.finishCondComb = LogicType.LOGIC_NONE;
|
||||
|
||||
if (this.failCondComb == null) this.failCondComb = LogicType.LOGIC_NONE;
|
||||
|
||||
addToCache();
|
||||
}
|
||||
|
||||
private void addToCache() {
|
||||
if (this.acceptCond == null) {
|
||||
Grasscutter.getLogger().warn("missing AcceptConditions for quest {}", getSubId());
|
||||
return;
|
||||
}
|
||||
|
||||
var cacheMap = GameData.getBeginCondQuestMap();
|
||||
if (getAcceptCond().isEmpty()) {
|
||||
var list =
|
||||
cacheMap.computeIfAbsent(
|
||||
QuestData.questConditionKey(QuestCond.QUEST_COND_NONE, 0, null),
|
||||
e -> new ArrayList<>());
|
||||
list.add(this);
|
||||
} else {
|
||||
this.getAcceptCond()
|
||||
.forEach(
|
||||
questCondition -> {
|
||||
if (questCondition.getType() == null) {
|
||||
Grasscutter.getLogger().warn("null accept type for quest {}", getSubId());
|
||||
return;
|
||||
}
|
||||
|
||||
var key = questCondition.asKey();
|
||||
var list = cacheMap.computeIfAbsent(key, e -> new ArrayList<>());
|
||||
list.add(this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public static class QuestExecParam {
|
||||
@SerializedName("_type")
|
||||
QuestExec type;
|
||||
|
||||
@SerializedName("_param")
|
||||
String[] param;
|
||||
|
||||
@SerializedName("_count")
|
||||
String count;
|
||||
}
|
||||
|
||||
public static class QuestAcceptCondition extends QuestCondition<QuestCond> {}
|
||||
|
||||
public static class QuestContentCondition extends QuestCondition<QuestContent> {}
|
||||
|
||||
@Data
|
||||
public static class QuestCondition<TYPE extends Enum<?> & QuestTrigger> {
|
||||
@SerializedName("_type")
|
||||
private TYPE type;
|
||||
|
||||
@SerializedName("_param")
|
||||
private int[] param;
|
||||
|
||||
@SerializedName("_param_str")
|
||||
private String paramStr;
|
||||
|
||||
@SerializedName("_count")
|
||||
private int count;
|
||||
|
||||
public String asKey() {
|
||||
return questConditionKey(getType(), getParam()[0], getParamStr());
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class Guide {
|
||||
private String type;
|
||||
private List<String> param;
|
||||
private int guideScene;
|
||||
}
|
||||
}
|
||||
|
@ -1,85 +1,85 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.props.RefreshType;
|
||||
import emu.grasscutter.game.world.World;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "RefreshPolicyExcelConfigData.json")
|
||||
public class RefreshPolicyExcelConfigData extends GameResource {
|
||||
@Getter private int id;
|
||||
@Getter private RefreshType type;
|
||||
@Getter private String time;
|
||||
|
||||
private static int upperBound(List<Integer> list, int low, int high, int value) {
|
||||
while (low < high) {
|
||||
int middle = (high + low) / 2;
|
||||
if (list.size() >= middle) return low; // Just in case
|
||||
if (list.get(middle) > value) {
|
||||
high = middle;
|
||||
} else {
|
||||
low = middle + 1;
|
||||
}
|
||||
}
|
||||
return low;
|
||||
}
|
||||
|
||||
public int getIntervalInSeconds(World world) {
|
||||
if (time.isEmpty()) return -1;
|
||||
|
||||
var currentTimestamp = world.getTotalGameTimeMinutes();
|
||||
|
||||
try {
|
||||
List<String> paramsStr = Arrays.asList(time.split(";"));
|
||||
List<Integer> params = paramsStr.stream().map(Integer::parseInt).toList();
|
||||
|
||||
switch (type) {
|
||||
case REFRESH_NONE:
|
||||
return -1;
|
||||
case REFRESH_INTERVAL:
|
||||
if (params.isEmpty()) return -1;
|
||||
return params.get(0);
|
||||
case REFRESH_DAILY:
|
||||
{
|
||||
var dayTime = (world.getTotalGameTimeMinutes() / (24 * 60)) * 24 * 60 * 60;
|
||||
var temp = currentTimestamp - dayTime;
|
||||
var upper_bound_idx =
|
||||
upperBound(
|
||||
params, (int) params.get(0), (int) params.get(params.size() - 1), (int) temp);
|
||||
var upper_bound = params.get(upper_bound_idx);
|
||||
if (params.get(params.size() - 1) == upper_bound) {
|
||||
return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7;
|
||||
} else if (params.get(0) == upper_bound) {
|
||||
return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7;
|
||||
}
|
||||
return (params.get(upper_bound_idx - 1) - params.get(0));
|
||||
}
|
||||
case REFRESH_WEEKlY:
|
||||
if (params.size() < 2) return -1;
|
||||
{
|
||||
var weekTime = (world.getTotalGameTimeDays() / 7) * 60 * 60 * 24 * 7;
|
||||
var temp = currentTimestamp - weekTime;
|
||||
var upper_bound_idx =
|
||||
upperBound(
|
||||
params, (int) params.get(0), (int) params.get(params.size() - 1), (int) temp);
|
||||
var upper_bound = params.get(upper_bound_idx);
|
||||
if (params.get(params.size() - 1) == upper_bound) {
|
||||
return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7;
|
||||
} else if (params.get(0) == upper_bound) {
|
||||
return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7;
|
||||
}
|
||||
return (params.get(upper_bound_idx - 1) - params.get(0));
|
||||
}
|
||||
case REFRESH_DAYBEGIN_INTERVAL:
|
||||
if (params.size() == 0) return -1;
|
||||
return params.get(0) * 60 * 60 * 24;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.props.RefreshType;
|
||||
import emu.grasscutter.game.world.World;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "RefreshPolicyExcelConfigData.json")
|
||||
public class RefreshPolicyExcelConfigData extends GameResource {
|
||||
@Getter private int id;
|
||||
@Getter private RefreshType type;
|
||||
@Getter private String time;
|
||||
|
||||
private static int upperBound(List<Integer> list, int low, int high, int value) {
|
||||
while (low < high) {
|
||||
int middle = (high + low) / 2;
|
||||
if (list.size() >= middle) return low; // Just in case
|
||||
if (list.get(middle) > value) {
|
||||
high = middle;
|
||||
} else {
|
||||
low = middle + 1;
|
||||
}
|
||||
}
|
||||
return low;
|
||||
}
|
||||
|
||||
public int getIntervalInSeconds(World world) {
|
||||
if (time.isEmpty()) return -1;
|
||||
|
||||
var currentTimestamp = world.getTotalGameTimeMinutes();
|
||||
|
||||
try {
|
||||
List<String> paramsStr = Arrays.asList(time.split(";"));
|
||||
List<Integer> params = paramsStr.stream().map(Integer::parseInt).toList();
|
||||
|
||||
switch (type) {
|
||||
case REFRESH_NONE:
|
||||
return -1;
|
||||
case REFRESH_INTERVAL:
|
||||
if (params.isEmpty()) return -1;
|
||||
return params.get(0);
|
||||
case REFRESH_DAILY:
|
||||
{
|
||||
var dayTime = (world.getTotalGameTimeMinutes() / (24 * 60)) * 24 * 60 * 60;
|
||||
var temp = currentTimestamp - dayTime;
|
||||
var upper_bound_idx =
|
||||
upperBound(
|
||||
params, (int) params.get(0), (int) params.get(params.size() - 1), (int) temp);
|
||||
var upper_bound = params.get(upper_bound_idx);
|
||||
if (params.get(params.size() - 1) == upper_bound) {
|
||||
return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7;
|
||||
} else if (params.get(0) == upper_bound) {
|
||||
return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7;
|
||||
}
|
||||
return (params.get(upper_bound_idx - 1) - params.get(0));
|
||||
}
|
||||
case REFRESH_WEEKlY:
|
||||
if (params.size() < 2) return -1;
|
||||
{
|
||||
var weekTime = (world.getTotalGameTimeDays() / 7) * 60 * 60 * 24 * 7;
|
||||
var temp = currentTimestamp - weekTime;
|
||||
var upper_bound_idx =
|
||||
upperBound(
|
||||
params, (int) params.get(0), (int) params.get(params.size() - 1), (int) temp);
|
||||
var upper_bound = params.get(upper_bound_idx);
|
||||
if (params.get(params.size() - 1) == upper_bound) {
|
||||
return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7;
|
||||
} else if (params.get(0) == upper_bound) {
|
||||
return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7;
|
||||
}
|
||||
return (params.get(upper_bound_idx - 1) - params.get(0));
|
||||
}
|
||||
case REFRESH_DAYBEGIN_INTERVAL:
|
||||
if (params.size() == 0) return -1;
|
||||
return params.get(0) * 60 * 60 * 24;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,22 @@
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.props.SceneType;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "SceneExcelConfigData.json")
|
||||
@Getter
|
||||
public class SceneData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int id;
|
||||
|
||||
@SerializedName("type")
|
||||
private SceneType sceneType;
|
||||
|
||||
private String scriptData;
|
||||
private String levelEntityConfig;
|
||||
private List<Integer> specifiedAvatarList;
|
||||
}
|
||||
package emu.grasscutter.data.excels;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.props.SceneType;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "SceneExcelConfigData.json")
|
||||
@Getter
|
||||
public class SceneData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int id;
|
||||
|
||||
@SerializedName("type")
|
||||
private SceneType sceneType;
|
||||
|
||||
private String scriptData;
|
||||
private String levelEntityConfig;
|
||||
private List<Integer> specifiedAvatarList;
|
||||
}
|
||||
|
@ -1,100 +1,100 @@
|
||||
package emu.grasscutter.data.excels.achievement;
|
||||
|
||||
import com.github.davidmoten.guavamini.Lists;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.excels.BattlePassMissionData;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "AchievementExcelConfigData.json")
|
||||
public class AchievementData extends GameResource {
|
||||
private static final AtomicBoolean isDivided = new AtomicBoolean();
|
||||
private int goalId;
|
||||
private int preStageAchievementId;
|
||||
private final Set<Integer> groupAchievementIdList = new HashSet<>();
|
||||
private boolean isParent;
|
||||
private long titleTextMapHash;
|
||||
private long descTextMapHash;
|
||||
private int finishRewardId;
|
||||
private boolean isDeleteWatcherAfterFinish;
|
||||
private int id;
|
||||
private BattlePassMissionData.TriggerConfig triggerConfig;
|
||||
private int progress;
|
||||
private boolean isDisuse;
|
||||
|
||||
public static void divideIntoGroups() {
|
||||
if (isDivided.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
isDivided.set(true);
|
||||
var map = GameData.getAchievementDataMap();
|
||||
var achievementDataList = map.values().stream().filter(AchievementData::isUsed).toList();
|
||||
for (var data : achievementDataList) {
|
||||
if (!data.hasPreStageAchievement() || data.hasGroupAchievements()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<Integer> ids = Lists.newArrayList();
|
||||
int parentId = data.getId();
|
||||
while (true) {
|
||||
var next = map.get(parentId + 1);
|
||||
if (next == null || parentId != next.getPreStageAchievementId()) {
|
||||
break;
|
||||
}
|
||||
|
||||
parentId++;
|
||||
}
|
||||
|
||||
map.get(parentId).isParent = true;
|
||||
|
||||
while (true) {
|
||||
ids.add(parentId);
|
||||
var previous = map.get(--parentId);
|
||||
if (previous == null) {
|
||||
break;
|
||||
} else if (!previous.hasPreStageAchievement()) {
|
||||
ids.add(parentId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i : ids) {
|
||||
map.get(i).groupAchievementIdList.addAll(ids);
|
||||
}
|
||||
}
|
||||
|
||||
map.values().stream()
|
||||
.filter(a -> !a.hasGroupAchievements() && a.isUsed())
|
||||
.forEach(a -> a.isParent = true);
|
||||
}
|
||||
|
||||
public boolean hasPreStageAchievement() {
|
||||
return this.preStageAchievementId != 0;
|
||||
}
|
||||
|
||||
public boolean hasGroupAchievements() {
|
||||
return !this.groupAchievementIdList.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isUsed() {
|
||||
return !this.isDisuse;
|
||||
}
|
||||
|
||||
public Set<Integer> getGroupAchievementIdList() {
|
||||
return this.groupAchievementIdList.stream().collect(Collectors.toUnmodifiableSet());
|
||||
}
|
||||
|
||||
public Set<Integer> getExcludedGroupAchievementIdList() {
|
||||
return this.groupAchievementIdList.stream()
|
||||
.filter(integer -> integer != this.getId())
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels.achievement;
|
||||
|
||||
import com.github.davidmoten.guavamini.Lists;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.excels.BattlePassMissionData;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "AchievementExcelConfigData.json")
|
||||
public class AchievementData extends GameResource {
|
||||
private static final AtomicBoolean isDivided = new AtomicBoolean();
|
||||
private int goalId;
|
||||
private int preStageAchievementId;
|
||||
private final Set<Integer> groupAchievementIdList = new HashSet<>();
|
||||
private boolean isParent;
|
||||
private long titleTextMapHash;
|
||||
private long descTextMapHash;
|
||||
private int finishRewardId;
|
||||
private boolean isDeleteWatcherAfterFinish;
|
||||
private int id;
|
||||
private BattlePassMissionData.TriggerConfig triggerConfig;
|
||||
private int progress;
|
||||
private boolean isDisuse;
|
||||
|
||||
public static void divideIntoGroups() {
|
||||
if (isDivided.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
isDivided.set(true);
|
||||
var map = GameData.getAchievementDataMap();
|
||||
var achievementDataList = map.values().stream().filter(AchievementData::isUsed).toList();
|
||||
for (var data : achievementDataList) {
|
||||
if (!data.hasPreStageAchievement() || data.hasGroupAchievements()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<Integer> ids = Lists.newArrayList();
|
||||
int parentId = data.getId();
|
||||
while (true) {
|
||||
var next = map.get(parentId + 1);
|
||||
if (next == null || parentId != next.getPreStageAchievementId()) {
|
||||
break;
|
||||
}
|
||||
|
||||
parentId++;
|
||||
}
|
||||
|
||||
map.get(parentId).isParent = true;
|
||||
|
||||
while (true) {
|
||||
ids.add(parentId);
|
||||
var previous = map.get(--parentId);
|
||||
if (previous == null) {
|
||||
break;
|
||||
} else if (!previous.hasPreStageAchievement()) {
|
||||
ids.add(parentId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i : ids) {
|
||||
map.get(i).groupAchievementIdList.addAll(ids);
|
||||
}
|
||||
}
|
||||
|
||||
map.values().stream()
|
||||
.filter(a -> !a.hasGroupAchievements() && a.isUsed())
|
||||
.forEach(a -> a.isParent = true);
|
||||
}
|
||||
|
||||
public boolean hasPreStageAchievement() {
|
||||
return this.preStageAchievementId != 0;
|
||||
}
|
||||
|
||||
public boolean hasGroupAchievements() {
|
||||
return !this.groupAchievementIdList.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isUsed() {
|
||||
return !this.isDisuse;
|
||||
}
|
||||
|
||||
public Set<Integer> getGroupAchievementIdList() {
|
||||
return this.groupAchievementIdList.stream().collect(Collectors.toUnmodifiableSet());
|
||||
}
|
||||
|
||||
public Set<Integer> getExcludedGroupAchievementIdList() {
|
||||
return this.groupAchievementIdList.stream()
|
||||
.filter(integer -> integer != this.getId())
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
package emu.grasscutter.data.excels.achievement;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "AchievementGoalExcelConfigData.json")
|
||||
public class AchievementGoalData extends GameResource {
|
||||
private int id;
|
||||
private long nameTextMapHash;
|
||||
private int finishRewardId;
|
||||
}
|
||||
package emu.grasscutter.data.excels.achievement;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "AchievementGoalExcelConfigData.json")
|
||||
public class AchievementGoalData extends GameResource {
|
||||
private int id;
|
||||
private long nameTextMapHash;
|
||||
private int finishRewardId;
|
||||
}
|
||||
|
@ -1,38 +1,38 @@
|
||||
package emu.grasscutter.data.excels.activity;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditions;
|
||||
import emu.grasscutter.game.quest.enums.LogicType;
|
||||
import java.util.List;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@ResourceType(name = "NewActivityCondExcelConfigData.json")
|
||||
@Getter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ActivityCondExcelConfigData extends GameResource {
|
||||
int condId;
|
||||
LogicType condComb;
|
||||
List<ActivityConfigCondition> cond;
|
||||
|
||||
public static class ActivityConfigCondition {
|
||||
@Getter private ActivityConditions type;
|
||||
@Getter private List<Integer> param;
|
||||
|
||||
public int[] paramArray() {
|
||||
return param.stream().mapToInt(Integer::intValue).toArray();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return condId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
cond.removeIf(c -> c.type == null);
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels.activity;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.activity.condition.ActivityConditions;
|
||||
import emu.grasscutter.game.quest.enums.LogicType;
|
||||
import java.util.List;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@ResourceType(name = "NewActivityCondExcelConfigData.json")
|
||||
@Getter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ActivityCondExcelConfigData extends GameResource {
|
||||
int condId;
|
||||
LogicType condComb;
|
||||
List<ActivityConfigCondition> cond;
|
||||
|
||||
public static class ActivityConfigCondition {
|
||||
@Getter private ActivityConditions type;
|
||||
@Getter private List<Integer> param;
|
||||
|
||||
public int[] paramArray() {
|
||||
return param.stream().mapToInt(Integer::intValue).toArray();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return condId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
cond.removeIf(c -> c.type == null);
|
||||
}
|
||||
}
|
||||
|
@ -1,37 +1,37 @@
|
||||
package emu.grasscutter.data.excels.activity;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@ResourceType(
|
||||
name = "NewActivityExcelConfigData.json",
|
||||
loadPriority = ResourceType.LoadPriority.LOW)
|
||||
@Getter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ActivityData extends GameResource {
|
||||
int activityId;
|
||||
String activityType;
|
||||
List<Integer> condGroupId;
|
||||
List<Integer> watcherId;
|
||||
List<ActivityWatcherData> watcherDataList;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.activityId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.watcherDataList =
|
||||
watcherId.stream()
|
||||
.map(item -> GameData.getActivityWatcherDataMap().get(item.intValue()))
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels.activity;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@ResourceType(
|
||||
name = "NewActivityExcelConfigData.json",
|
||||
loadPriority = ResourceType.LoadPriority.LOW)
|
||||
@Getter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ActivityData extends GameResource {
|
||||
int activityId;
|
||||
String activityType;
|
||||
List<Integer> condGroupId;
|
||||
List<Integer> watcherId;
|
||||
List<ActivityWatcherData> watcherDataList;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.activityId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.watcherDataList =
|
||||
watcherId.stream()
|
||||
.map(item -> GameData.getActivityWatcherDataMap().get(item.intValue()))
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,24 @@
|
||||
package emu.grasscutter.data.excels.activity;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.shop.ShopType;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "ActivityShopOverallExcelConfigData.json")
|
||||
public class ActivityShopData extends GameResource {
|
||||
@Getter private int scheduleId;
|
||||
@Getter private ShopType shopType;
|
||||
@Getter private List<Integer> sheetList;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return getShopTypeId();
|
||||
}
|
||||
|
||||
public int getShopTypeId() {
|
||||
if (this.shopType == null) this.shopType = ShopType.SHOP_TYPE_NONE;
|
||||
return shopType.shopTypeId;
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels.activity;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.shop.ShopType;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "ActivityShopOverallExcelConfigData.json")
|
||||
public class ActivityShopData extends GameResource {
|
||||
@Getter private int scheduleId;
|
||||
@Getter private ShopType shopType;
|
||||
@Getter private List<Integer> sheetList;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return getShopTypeId();
|
||||
}
|
||||
|
||||
public int getShopTypeId() {
|
||||
if (this.shopType == null) this.shopType = ShopType.SHOP_TYPE_NONE;
|
||||
return shopType.shopTypeId;
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +1,45 @@
|
||||
package emu.grasscutter.data.excels.activity;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import java.util.List;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@ResourceType(
|
||||
name = "NewActivityWatcherConfigData.json",
|
||||
loadPriority = ResourceType.LoadPriority.HIGH)
|
||||
@Getter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ActivityWatcherData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
int id;
|
||||
|
||||
int rewardID;
|
||||
int progress;
|
||||
WatcherTrigger triggerConfig;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.triggerConfig.paramList =
|
||||
this.triggerConfig.paramList.stream().filter(x -> (x != null) && !x.isBlank()).toList();
|
||||
this.triggerConfig.watcherTriggerType =
|
||||
WatcherTriggerType.getTypeByName(this.triggerConfig.triggerType);
|
||||
}
|
||||
|
||||
@Getter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public static class WatcherTrigger {
|
||||
String triggerType;
|
||||
List<String> paramList;
|
||||
|
||||
transient WatcherTriggerType watcherTriggerType;
|
||||
|
||||
public void onLoad() {
|
||||
this.paramList = this.paramList.stream().filter(x -> (x != null) && !x.isBlank()).toList();
|
||||
this.watcherTriggerType = WatcherTriggerType.getTypeByName(this.triggerType);
|
||||
}
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels.activity;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import java.util.List;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@ResourceType(
|
||||
name = "NewActivityWatcherConfigData.json",
|
||||
loadPriority = ResourceType.LoadPriority.HIGH)
|
||||
@Getter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ActivityWatcherData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
int id;
|
||||
|
||||
int rewardID;
|
||||
int progress;
|
||||
WatcherTrigger triggerConfig;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.triggerConfig.paramList =
|
||||
this.triggerConfig.paramList.stream().filter(x -> (x != null) && !x.isBlank()).toList();
|
||||
this.triggerConfig.watcherTriggerType =
|
||||
WatcherTriggerType.getTypeByName(this.triggerConfig.triggerType);
|
||||
}
|
||||
|
||||
@Getter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public static class WatcherTrigger {
|
||||
String triggerType;
|
||||
List<String> paramList;
|
||||
|
||||
transient WatcherTriggerType watcherTriggerType;
|
||||
|
||||
public void onLoad() {
|
||||
this.paramList = this.paramList.stream().filter(x -> (x != null) && !x.isBlank()).toList();
|
||||
this.watcherTriggerType = WatcherTriggerType.getTypeByName(this.triggerType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,38 +1,38 @@
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = "AvatarCostumeExcelConfigData.json")
|
||||
public class AvatarCostumeData extends GameResource {
|
||||
@SerializedName(value = "skinId", alternate = "costumeId")
|
||||
private int skinId;
|
||||
|
||||
private int itemId;
|
||||
private int characterId;
|
||||
private int quality;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.skinId;
|
||||
}
|
||||
|
||||
public int getItemId() {
|
||||
return this.itemId;
|
||||
}
|
||||
|
||||
public int getCharacterId() {
|
||||
return characterId;
|
||||
}
|
||||
|
||||
public int getQuality() {
|
||||
return quality;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
GameData.getAvatarCostumeDataItemIdMap().put(this.getItemId(), this);
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = "AvatarCostumeExcelConfigData.json")
|
||||
public class AvatarCostumeData extends GameResource {
|
||||
@SerializedName(value = "skinId", alternate = "costumeId")
|
||||
private int skinId;
|
||||
|
||||
private int itemId;
|
||||
private int characterId;
|
||||
private int quality;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.skinId;
|
||||
}
|
||||
|
||||
public int getItemId() {
|
||||
return this.itemId;
|
||||
}
|
||||
|
||||
public int getCharacterId() {
|
||||
return characterId;
|
||||
}
|
||||
|
||||
public int getQuality() {
|
||||
return quality;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
GameData.getAvatarCostumeDataItemIdMap().put(this.getItemId(), this);
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +1,36 @@
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.common.CurveInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@ResourceType(name = "AvatarCurveExcelConfigData.json")
|
||||
public class AvatarCurveData extends GameResource {
|
||||
private int level;
|
||||
private CurveInfo[] curveInfos;
|
||||
|
||||
private Map<String, Float> curveInfoMap;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.level;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public Map<String, Float> getCurveInfos() {
|
||||
return curveInfoMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.curveInfoMap = new HashMap<>();
|
||||
Stream.of(this.curveInfos)
|
||||
.forEach(info -> this.curveInfoMap.put(info.getType(), info.getValue()));
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.common.CurveInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@ResourceType(name = "AvatarCurveExcelConfigData.json")
|
||||
public class AvatarCurveData extends GameResource {
|
||||
private int level;
|
||||
private CurveInfo[] curveInfos;
|
||||
|
||||
private Map<String, Float> curveInfoMap;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.level;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public Map<String, Float> getCurveInfos() {
|
||||
return curveInfoMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.curveInfoMap = new HashMap<>();
|
||||
Stream.of(this.curveInfos)
|
||||
.forEach(info -> this.curveInfoMap.put(info.getType(), info.getValue()));
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,23 @@
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = "AvatarFettersLevelExcelConfigData.json")
|
||||
public class AvatarFetterLevelData extends GameResource {
|
||||
private int fetterLevel;
|
||||
private int needExp;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.fetterLevel;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return fetterLevel;
|
||||
}
|
||||
|
||||
public int getExp() {
|
||||
return needExp;
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = "AvatarFettersLevelExcelConfigData.json")
|
||||
public class AvatarFetterLevelData extends GameResource {
|
||||
private int fetterLevel;
|
||||
private int needExp;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.fetterLevel;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return fetterLevel;
|
||||
}
|
||||
|
||||
public int getExp() {
|
||||
return needExp;
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,22 @@
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = "AvatarFlycloakExcelConfigData.json")
|
||||
public class AvatarFlycloakData extends GameResource {
|
||||
private int flycloakId;
|
||||
private long nameTextMapHash;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.flycloakId;
|
||||
}
|
||||
|
||||
public long getNameTextMapHash() {
|
||||
return nameTextMapHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {}
|
||||
}
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = "AvatarFlycloakExcelConfigData.json")
|
||||
public class AvatarFlycloakData extends GameResource {
|
||||
private int flycloakId;
|
||||
private long nameTextMapHash;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.flycloakId;
|
||||
}
|
||||
|
||||
public long getNameTextMapHash() {
|
||||
return nameTextMapHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {}
|
||||
}
|
||||
|
@ -1,23 +1,23 @@
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = "AvatarLevelExcelConfigData.json")
|
||||
public class AvatarLevelData extends GameResource {
|
||||
private int level;
|
||||
private int exp;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.level;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public int getExp() {
|
||||
return exp;
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = "AvatarLevelExcelConfigData.json")
|
||||
public class AvatarLevelData extends GameResource {
|
||||
private int level;
|
||||
private int exp;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.level;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public int getExp() {
|
||||
return exp;
|
||||
}
|
||||
}
|
||||
|
@ -1,74 +1,74 @@
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.common.FightPropData;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ResourceType(name = "AvatarPromoteExcelConfigData.json")
|
||||
public class AvatarPromoteData extends GameResource {
|
||||
|
||||
private int avatarPromoteId;
|
||||
private int promoteLevel;
|
||||
private int scoinCost;
|
||||
private ItemParamData[] costItems;
|
||||
private int unlockMaxLevel;
|
||||
private FightPropData[] addProps;
|
||||
private int requiredPlayerLevel;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return (avatarPromoteId << 8) + promoteLevel;
|
||||
}
|
||||
|
||||
public int getAvatarPromoteId() {
|
||||
return avatarPromoteId;
|
||||
}
|
||||
|
||||
public int getPromoteLevel() {
|
||||
return promoteLevel;
|
||||
}
|
||||
|
||||
public ItemParamData[] getCostItems() {
|
||||
return costItems;
|
||||
}
|
||||
|
||||
public int getCoinCost() {
|
||||
return scoinCost;
|
||||
}
|
||||
|
||||
public FightPropData[] getAddProps() {
|
||||
return addProps;
|
||||
}
|
||||
|
||||
public int getUnlockMaxLevel() {
|
||||
return unlockMaxLevel;
|
||||
}
|
||||
|
||||
public int getRequiredPlayerLevel() {
|
||||
return requiredPlayerLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
// Trim item params
|
||||
ArrayList<ItemParamData> trim = new ArrayList<>(getAddProps().length);
|
||||
for (ItemParamData itemParam : getCostItems()) {
|
||||
if (itemParam.getId() == 0) {
|
||||
continue;
|
||||
}
|
||||
trim.add(itemParam);
|
||||
}
|
||||
this.costItems = trim.toArray(new ItemParamData[trim.size()]);
|
||||
// Trim fight prop data (just in case)
|
||||
ArrayList<FightPropData> parsed = new ArrayList<>(getAddProps().length);
|
||||
for (FightPropData prop : getAddProps()) {
|
||||
if (prop.getPropType() != null && prop.getValue() != 0f) {
|
||||
prop.onLoad();
|
||||
parsed.add(prop);
|
||||
}
|
||||
}
|
||||
this.addProps = parsed.toArray(new FightPropData[parsed.size()]);
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.common.FightPropData;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ResourceType(name = "AvatarPromoteExcelConfigData.json")
|
||||
public class AvatarPromoteData extends GameResource {
|
||||
|
||||
private int avatarPromoteId;
|
||||
private int promoteLevel;
|
||||
private int scoinCost;
|
||||
private ItemParamData[] costItems;
|
||||
private int unlockMaxLevel;
|
||||
private FightPropData[] addProps;
|
||||
private int requiredPlayerLevel;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return (avatarPromoteId << 8) + promoteLevel;
|
||||
}
|
||||
|
||||
public int getAvatarPromoteId() {
|
||||
return avatarPromoteId;
|
||||
}
|
||||
|
||||
public int getPromoteLevel() {
|
||||
return promoteLevel;
|
||||
}
|
||||
|
||||
public ItemParamData[] getCostItems() {
|
||||
return costItems;
|
||||
}
|
||||
|
||||
public int getCoinCost() {
|
||||
return scoinCost;
|
||||
}
|
||||
|
||||
public FightPropData[] getAddProps() {
|
||||
return addProps;
|
||||
}
|
||||
|
||||
public int getUnlockMaxLevel() {
|
||||
return unlockMaxLevel;
|
||||
}
|
||||
|
||||
public int getRequiredPlayerLevel() {
|
||||
return requiredPlayerLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
// Trim item params
|
||||
ArrayList<ItemParamData> trim = new ArrayList<>(getAddProps().length);
|
||||
for (ItemParamData itemParam : getCostItems()) {
|
||||
if (itemParam.getId() == 0) {
|
||||
continue;
|
||||
}
|
||||
trim.add(itemParam);
|
||||
}
|
||||
this.costItems = trim.toArray(new ItemParamData[trim.size()]);
|
||||
// Trim fight prop data (just in case)
|
||||
ArrayList<FightPropData> parsed = new ArrayList<>(getAddProps().length);
|
||||
for (FightPropData prop : getAddProps()) {
|
||||
if (prop.getPropType() != null && prop.getValue() != 0f) {
|
||||
prop.onLoad();
|
||||
parsed.add(prop);
|
||||
}
|
||||
}
|
||||
this.addProps = parsed.toArray(new FightPropData[parsed.size()]);
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,24 @@
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@ResourceType(name = "AvatarReplaceCostumeExcelConfigData.json")
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class AvatarReplaceCostumeData extends GameResource {
|
||||
private int avatarId;
|
||||
|
||||
@SerializedName(
|
||||
value = "costumeId",
|
||||
alternate = {"MGLCOPOIJIC", "BDBMOBGKIAP"})
|
||||
private int costumeId;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return costumeId;
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@ResourceType(name = "AvatarReplaceCostumeExcelConfigData.json")
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class AvatarReplaceCostumeData extends GameResource {
|
||||
private int avatarId;
|
||||
|
||||
@SerializedName(
|
||||
value = "costumeId",
|
||||
alternate = {"MGLCOPOIJIC", "BDBMOBGKIAP"})
|
||||
private int costumeId;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return costumeId;
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,25 @@
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.ResourceType.LoadPriority;
|
||||
import emu.grasscutter.game.props.ElementType;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "AvatarSkillExcelConfigData.json", loadPriority = LoadPriority.HIGHEST)
|
||||
@Getter
|
||||
public class AvatarSkillData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int id;
|
||||
|
||||
private float cdTime;
|
||||
private int costElemVal;
|
||||
private int maxChargeNum;
|
||||
private int triggerID;
|
||||
private boolean isAttackCameraLock;
|
||||
private int proudSkillGroupId;
|
||||
private ElementType costElemType;
|
||||
private long nameTextMapHash;
|
||||
private long descTextMapHash;
|
||||
private String abilityName;
|
||||
}
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.ResourceType.LoadPriority;
|
||||
import emu.grasscutter.game.props.ElementType;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "AvatarSkillExcelConfigData.json", loadPriority = LoadPriority.HIGHEST)
|
||||
@Getter
|
||||
public class AvatarSkillData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int id;
|
||||
|
||||
private float cdTime;
|
||||
private int costElemVal;
|
||||
private int maxChargeNum;
|
||||
private int triggerID;
|
||||
private boolean isAttackCameraLock;
|
||||
private int proudSkillGroupId;
|
||||
private ElementType costElemType;
|
||||
private long nameTextMapHash;
|
||||
private long descTextMapHash;
|
||||
private String abilityName;
|
||||
}
|
||||
|
@ -1,89 +1,89 @@
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameDepot;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceLoader.AvatarConfig;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.ResourceType.LoadPriority;
|
||||
import emu.grasscutter.data.binout.AbilityEmbryoEntry;
|
||||
import emu.grasscutter.game.props.ElementType;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.IntStream;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "AvatarSkillDepotExcelConfigData.json", loadPriority = LoadPriority.HIGH)
|
||||
@Getter
|
||||
public class AvatarSkillDepotData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int id;
|
||||
|
||||
private int energySkill;
|
||||
private int attackModeSkill;
|
||||
|
||||
private List<Integer> skills;
|
||||
private List<Integer> subSkills;
|
||||
private List<String> extraAbilities;
|
||||
private List<Integer> talents;
|
||||
private List<InherentProudSkillOpens> inherentProudSkillOpens;
|
||||
|
||||
private String talentStarName;
|
||||
private String skillDepotAbilityGroup;
|
||||
|
||||
// Transient
|
||||
private AvatarSkillData energySkillData;
|
||||
private ElementType elementType;
|
||||
private IntList abilities;
|
||||
private int talentCostItemId;
|
||||
|
||||
public void setAbilities(AbilityEmbryoEntry info) {
|
||||
this.abilities = new IntArrayList(info.getAbilities().length);
|
||||
for (String ability : info.getAbilities()) {
|
||||
this.abilities.add(Utils.abilityHash(ability));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
// Set energy skill data
|
||||
this.energySkillData = GameData.getAvatarSkillDataMap().get(this.energySkill);
|
||||
if (this.energySkillData != null) {
|
||||
this.elementType = this.energySkillData.getCostElemType();
|
||||
} else {
|
||||
this.elementType = ElementType.None;
|
||||
}
|
||||
// Set embryo abilities (if player skill depot)
|
||||
if (getSkillDepotAbilityGroup() != null && getSkillDepotAbilityGroup().length() > 0) {
|
||||
AvatarConfig config = GameDepot.getPlayerAbilities().get(getSkillDepotAbilityGroup());
|
||||
|
||||
if (config != null) {
|
||||
this.setAbilities(
|
||||
new AbilityEmbryoEntry(
|
||||
getSkillDepotAbilityGroup(),
|
||||
config.abilities.stream().map(Object::toString).toArray(String[]::new)));
|
||||
}
|
||||
}
|
||||
|
||||
// Get constellation item from GameData
|
||||
Optional.ofNullable(this.talents)
|
||||
.map(talents -> talents.get(0))
|
||||
.map(i -> GameData.getAvatarTalentDataMap().get((int) i))
|
||||
.map(talentData -> talentData.getMainCostItemId())
|
||||
.ifPresent(itemId -> this.talentCostItemId = itemId);
|
||||
}
|
||||
|
||||
public IntStream getSkillsAndEnergySkill() {
|
||||
return IntStream.concat(this.skills.stream().mapToInt(i -> i), IntStream.of(this.energySkill))
|
||||
.filter(skillId -> skillId > 0);
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class InherentProudSkillOpens {
|
||||
private int proudSkillGroupId;
|
||||
private int needAvatarPromoteLevel;
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameDepot;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceLoader.AvatarConfig;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.ResourceType.LoadPriority;
|
||||
import emu.grasscutter.data.binout.AbilityEmbryoEntry;
|
||||
import emu.grasscutter.game.props.ElementType;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.IntStream;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "AvatarSkillDepotExcelConfigData.json", loadPriority = LoadPriority.HIGH)
|
||||
@Getter
|
||||
public class AvatarSkillDepotData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int id;
|
||||
|
||||
private int energySkill;
|
||||
private int attackModeSkill;
|
||||
|
||||
private List<Integer> skills;
|
||||
private List<Integer> subSkills;
|
||||
private List<String> extraAbilities;
|
||||
private List<Integer> talents;
|
||||
private List<InherentProudSkillOpens> inherentProudSkillOpens;
|
||||
|
||||
private String talentStarName;
|
||||
private String skillDepotAbilityGroup;
|
||||
|
||||
// Transient
|
||||
private AvatarSkillData energySkillData;
|
||||
private ElementType elementType;
|
||||
private IntList abilities;
|
||||
private int talentCostItemId;
|
||||
|
||||
public void setAbilities(AbilityEmbryoEntry info) {
|
||||
this.abilities = new IntArrayList(info.getAbilities().length);
|
||||
for (String ability : info.getAbilities()) {
|
||||
this.abilities.add(Utils.abilityHash(ability));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
// Set energy skill data
|
||||
this.energySkillData = GameData.getAvatarSkillDataMap().get(this.energySkill);
|
||||
if (this.energySkillData != null) {
|
||||
this.elementType = this.energySkillData.getCostElemType();
|
||||
} else {
|
||||
this.elementType = ElementType.None;
|
||||
}
|
||||
// Set embryo abilities (if player skill depot)
|
||||
if (getSkillDepotAbilityGroup() != null && getSkillDepotAbilityGroup().length() > 0) {
|
||||
AvatarConfig config = GameDepot.getPlayerAbilities().get(getSkillDepotAbilityGroup());
|
||||
|
||||
if (config != null) {
|
||||
this.setAbilities(
|
||||
new AbilityEmbryoEntry(
|
||||
getSkillDepotAbilityGroup(),
|
||||
config.abilities.stream().map(Object::toString).toArray(String[]::new)));
|
||||
}
|
||||
}
|
||||
|
||||
// Get constellation item from GameData
|
||||
Optional.ofNullable(this.talents)
|
||||
.map(talents -> talents.get(0))
|
||||
.map(i -> GameData.getAvatarTalentDataMap().get((int) i))
|
||||
.map(talentData -> talentData.getMainCostItemId())
|
||||
.ifPresent(itemId -> this.talentCostItemId = itemId);
|
||||
}
|
||||
|
||||
public IntStream getSkillsAndEnergySkill() {
|
||||
return IntStream.concat(this.skills.stream().mapToInt(i -> i), IntStream.of(this.energySkill))
|
||||
.filter(skillId -> skillId > 0);
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class InherentProudSkillOpens {
|
||||
private int proudSkillGroupId;
|
||||
private int needAvatarPromoteLevel;
|
||||
}
|
||||
}
|
||||
|
@ -1,69 +1,69 @@
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.ResourceType.LoadPriority;
|
||||
import emu.grasscutter.data.common.FightPropData;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ResourceType(name = "AvatarTalentExcelConfigData.json", loadPriority = LoadPriority.HIGHEST)
|
||||
public class AvatarTalentData extends GameResource {
|
||||
private int talentId;
|
||||
private int prevTalent;
|
||||
private long nameTextMapHash;
|
||||
private String icon;
|
||||
private int mainCostItemId;
|
||||
private int mainCostItemCount;
|
||||
private String openConfig;
|
||||
private FightPropData[] addProps;
|
||||
private float[] paramList;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.talentId;
|
||||
}
|
||||
|
||||
public int PrevTalent() {
|
||||
return prevTalent;
|
||||
}
|
||||
|
||||
public long getNameTextMapHash() {
|
||||
return nameTextMapHash;
|
||||
}
|
||||
|
||||
public String getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public int getMainCostItemId() {
|
||||
return mainCostItemId;
|
||||
}
|
||||
|
||||
public int getMainCostItemCount() {
|
||||
return mainCostItemCount;
|
||||
}
|
||||
|
||||
public String getOpenConfig() {
|
||||
return openConfig;
|
||||
}
|
||||
|
||||
public FightPropData[] getAddProps() {
|
||||
return addProps;
|
||||
}
|
||||
|
||||
public float[] getParamList() {
|
||||
return paramList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
ArrayList<FightPropData> parsed = new ArrayList<FightPropData>(getAddProps().length);
|
||||
for (FightPropData prop : getAddProps()) {
|
||||
if (prop.getPropType() != null || prop.getValue() == 0f) {
|
||||
prop.onLoad();
|
||||
parsed.add(prop);
|
||||
}
|
||||
}
|
||||
this.addProps = parsed.toArray(new FightPropData[parsed.size()]);
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels.avatar;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.ResourceType.LoadPriority;
|
||||
import emu.grasscutter.data.common.FightPropData;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ResourceType(name = "AvatarTalentExcelConfigData.json", loadPriority = LoadPriority.HIGHEST)
|
||||
public class AvatarTalentData extends GameResource {
|
||||
private int talentId;
|
||||
private int prevTalent;
|
||||
private long nameTextMapHash;
|
||||
private String icon;
|
||||
private int mainCostItemId;
|
||||
private int mainCostItemCount;
|
||||
private String openConfig;
|
||||
private FightPropData[] addProps;
|
||||
private float[] paramList;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.talentId;
|
||||
}
|
||||
|
||||
public int PrevTalent() {
|
||||
return prevTalent;
|
||||
}
|
||||
|
||||
public long getNameTextMapHash() {
|
||||
return nameTextMapHash;
|
||||
}
|
||||
|
||||
public String getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public int getMainCostItemId() {
|
||||
return mainCostItemId;
|
||||
}
|
||||
|
||||
public int getMainCostItemCount() {
|
||||
return mainCostItemCount;
|
||||
}
|
||||
|
||||
public String getOpenConfig() {
|
||||
return openConfig;
|
||||
}
|
||||
|
||||
public FightPropData[] getAddProps() {
|
||||
return addProps;
|
||||
}
|
||||
|
||||
public float[] getParamList() {
|
||||
return paramList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
ArrayList<FightPropData> parsed = new ArrayList<FightPropData>(getAddProps().length);
|
||||
for (FightPropData prop : getAddProps()) {
|
||||
if (prop.getPropType() != null || prop.getValue() == 0f) {
|
||||
prop.onLoad();
|
||||
parsed.add(prop);
|
||||
}
|
||||
}
|
||||
this.addProps = parsed.toArray(new FightPropData[parsed.size()]);
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +1,27 @@
|
||||
package emu.grasscutter.data.excels.codex;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = {"AnimalCodexExcelConfigData.json"})
|
||||
@Getter
|
||||
public class CodexAnimalData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int Id;
|
||||
|
||||
private String type;
|
||||
private int describeId;
|
||||
private int sortOrder;
|
||||
|
||||
@SerializedName(
|
||||
value = "countType",
|
||||
alternate = {"OCCLHPBCDGL"})
|
||||
private CountType countType;
|
||||
|
||||
public enum CountType {
|
||||
CODEX_COUNT_TYPE_KILL,
|
||||
CODEX_COUNT_TYPE_CAPTURE
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels.codex;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = {"AnimalCodexExcelConfigData.json"})
|
||||
@Getter
|
||||
public class CodexAnimalData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int Id;
|
||||
|
||||
private String type;
|
||||
private int describeId;
|
||||
private int sortOrder;
|
||||
|
||||
@SerializedName(
|
||||
value = "countType",
|
||||
alternate = {"OCCLHPBCDGL"})
|
||||
private CountType countType;
|
||||
|
||||
public enum CountType {
|
||||
CODEX_COUNT_TYPE_KILL,
|
||||
CODEX_COUNT_TYPE_CAPTURE
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,29 @@
|
||||
package emu.grasscutter.data.excels.codex;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = {"MaterialCodexExcelConfigData.json"})
|
||||
public class CodexMaterialData extends GameResource {
|
||||
private int Id;
|
||||
private int materialId;
|
||||
private int sortOrder;
|
||||
|
||||
public int getSortOrder() {
|
||||
return sortOrder;
|
||||
}
|
||||
|
||||
public int getMaterialId() {
|
||||
return materialId;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
GameData.getCodexMaterialDataIdMap().put(this.getMaterialId(), this);
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels.codex;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = {"MaterialCodexExcelConfigData.json"})
|
||||
public class CodexMaterialData extends GameResource {
|
||||
private int Id;
|
||||
private int materialId;
|
||||
private int sortOrder;
|
||||
|
||||
public int getSortOrder() {
|
||||
return sortOrder;
|
||||
}
|
||||
|
||||
public int getMaterialId() {
|
||||
return materialId;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
GameData.getCodexMaterialDataIdMap().put(this.getMaterialId(), this);
|
||||
}
|
||||
}
|
||||
|
@ -1,41 +1,41 @@
|
||||
package emu.grasscutter.data.excels.codex;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = {"QuestCodexExcelConfigData.json"})
|
||||
public class CodexQuestData extends GameResource {
|
||||
private int Id;
|
||||
private int parentQuestId;
|
||||
private int chapterId;
|
||||
private int sortOrder;
|
||||
private boolean isDisuse;
|
||||
|
||||
public int getParentQuestId() {
|
||||
return parentQuestId;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
|
||||
public int getChapterId() {
|
||||
return chapterId;
|
||||
}
|
||||
|
||||
public int getSortOrder() {
|
||||
return sortOrder;
|
||||
}
|
||||
|
||||
public boolean getIsDisuse() {
|
||||
return isDisuse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
if (!this.getIsDisuse()) {
|
||||
GameData.getCodexQuestDataIdMap().put(this.getParentQuestId(), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels.codex;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
|
||||
@ResourceType(name = {"QuestCodexExcelConfigData.json"})
|
||||
public class CodexQuestData extends GameResource {
|
||||
private int Id;
|
||||
private int parentQuestId;
|
||||
private int chapterId;
|
||||
private int sortOrder;
|
||||
private boolean isDisuse;
|
||||
|
||||
public int getParentQuestId() {
|
||||
return parentQuestId;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
|
||||
public int getChapterId() {
|
||||
return chapterId;
|
||||
}
|
||||
|
||||
public int getSortOrder() {
|
||||
return sortOrder;
|
||||
}
|
||||
|
||||
public boolean getIsDisuse() {
|
||||
return isDisuse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
if (!this.getIsDisuse()) {
|
||||
GameData.getCodexQuestDataIdMap().put(this.getParentQuestId(), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,47 +1,47 @@
|
||||
package emu.grasscutter.data.excels.codex;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import it.unimi.dsi.fastutil.ints.IntCollection;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = {"ReliquaryCodexExcelConfigData.json"})
|
||||
public class CodexReliquaryData extends GameResource {
|
||||
@Getter private int Id;
|
||||
@Getter private int suitId;
|
||||
@Getter private int level;
|
||||
@Getter private int cupId;
|
||||
@Getter private int leatherId;
|
||||
@Getter private int capId;
|
||||
@Getter private int flowerId;
|
||||
@Getter private int sandId;
|
||||
@Getter private int sortOrder;
|
||||
private transient IntCollection ids;
|
||||
|
||||
public boolean containsId(int id) {
|
||||
return getIds().contains(id);
|
||||
}
|
||||
|
||||
public IntCollection getIds() {
|
||||
if (this.ids == null) {
|
||||
int[] idsArr = {cupId, leatherId, capId, flowerId, sandId};
|
||||
this.ids = IntList.of(idsArr);
|
||||
}
|
||||
return this.ids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
// Normalize all itemIds to the 0-substat form
|
||||
cupId = (cupId / 10) * 10;
|
||||
leatherId = (leatherId / 10) * 10;
|
||||
capId = (capId / 10) * 10;
|
||||
flowerId = (flowerId / 10) * 10;
|
||||
sandId = (sandId / 10) * 10;
|
||||
|
||||
GameData.getCodexReliquaryArrayList().add(this);
|
||||
GameData.getCodexReliquaryDataIdMap().put(getSuitId(), this);
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.data.excels.codex;
|
||||
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import it.unimi.dsi.fastutil.ints.IntCollection;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = {"ReliquaryCodexExcelConfigData.json"})
|
||||
public class CodexReliquaryData extends GameResource {
|
||||
@Getter private int Id;
|
||||
@Getter private int suitId;
|
||||
@Getter private int level;
|
||||
@Getter private int cupId;
|
||||
@Getter private int leatherId;
|
||||
@Getter private int capId;
|
||||
@Getter private int flowerId;
|
||||
@Getter private int sandId;
|
||||
@Getter private int sortOrder;
|
||||
private transient IntCollection ids;
|
||||
|
||||
public boolean containsId(int id) {
|
||||
return getIds().contains(id);
|
||||
}
|
||||
|
||||
public IntCollection getIds() {
|
||||
if (this.ids == null) {
|
||||
int[] idsArr = {cupId, leatherId, capId, flowerId, sandId};
|
||||
this.ids = IntList.of(idsArr);
|
||||
}
|
||||
return this.ids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
// Normalize all itemIds to the 0-substat form
|
||||
cupId = (cupId / 10) * 10;
|
||||
leatherId = (leatherId / 10) * 10;
|
||||
capId = (capId / 10) * 10;
|
||||
flowerId = (flowerId / 10) * 10;
|
||||
sandId = (sandId / 10) * 10;
|
||||
|
||||
GameData.getCodexReliquaryArrayList().add(this);
|
||||
GameData.getCodexReliquaryDataIdMap().put(getSuitId(), this);
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user