minecraft-src/net/minecraft/world/level/GameRules.java
2025-07-04 03:45:38 +03:00

653 lines
25 KiB
Java

package net.minecraft.world.level;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.BoolArgumentType;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.logging.LogUtils;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.DynamicLike;
import java.util.Comparator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.game.ClientboundEntityEventPacket;
import net.minecraft.network.protocol.game.ClientboundGameEventPacket;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.flag.FeatureFlagSet;
import net.minecraft.world.flag.FeatureFlags;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
public class GameRules {
public static final int DEFAULT_RANDOM_TICK_SPEED = 3;
static final Logger LOGGER = LogUtils.getLogger();
private static final Map<GameRules.Key<?>, GameRules.Type<?>> GAME_RULE_TYPES = Maps.newTreeMap(Comparator.comparing(key -> key.id));
public static final GameRules.Key<GameRules.BooleanValue> RULE_DOFIRETICK = register(
"doFireTick", GameRules.Category.UPDATES, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_ALLOWFIRETICKAWAYFROMPLAYERS = register(
"allowFireTicksAwayFromPlayer", GameRules.Category.UPDATES, GameRules.BooleanValue.create(false)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_MOBGRIEFING = register(
"mobGriefing", GameRules.Category.MOBS, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_KEEPINVENTORY = register(
"keepInventory", GameRules.Category.PLAYER, GameRules.BooleanValue.create(false)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_DOMOBSPAWNING = register(
"doMobSpawning", GameRules.Category.SPAWNING, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_DOMOBLOOT = register("doMobLoot", GameRules.Category.DROPS, GameRules.BooleanValue.create(true));
public static final GameRules.Key<GameRules.BooleanValue> RULE_PROJECTILESCANBREAKBLOCKS = register(
"projectilesCanBreakBlocks", GameRules.Category.DROPS, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_DOBLOCKDROPS = register(
"doTileDrops", GameRules.Category.DROPS, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_DOENTITYDROPS = register(
"doEntityDrops", GameRules.Category.DROPS, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_COMMANDBLOCKOUTPUT = register(
"commandBlockOutput", GameRules.Category.CHAT, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_NATURAL_REGENERATION = register(
"naturalRegeneration", GameRules.Category.PLAYER, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_DAYLIGHT = register(
"doDaylightCycle", GameRules.Category.UPDATES, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_LOGADMINCOMMANDS = register(
"logAdminCommands", GameRules.Category.CHAT, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_SHOWDEATHMESSAGES = register(
"showDeathMessages", GameRules.Category.CHAT, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.IntegerValue> RULE_RANDOMTICKING = register(
"randomTickSpeed", GameRules.Category.UPDATES, GameRules.IntegerValue.create(3)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_SENDCOMMANDFEEDBACK = register(
"sendCommandFeedback", GameRules.Category.CHAT, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_REDUCEDDEBUGINFO = register(
"reducedDebugInfo", GameRules.Category.MISC, GameRules.BooleanValue.create(false, (minecraftServer, booleanValue) -> {
byte b = (byte)(booleanValue.get() ? 22 : 23);
for (ServerPlayer serverPlayer : minecraftServer.getPlayerList().getPlayers()) {
serverPlayer.connection.send(new ClientboundEntityEventPacket(serverPlayer, b));
}
})
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_SPECTATORSGENERATECHUNKS = register(
"spectatorsGenerateChunks", GameRules.Category.PLAYER, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.IntegerValue> RULE_SPAWN_RADIUS = register(
"spawnRadius", GameRules.Category.PLAYER, GameRules.IntegerValue.create(10)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_DISABLE_PLAYER_MOVEMENT_CHECK = register(
"disablePlayerMovementCheck", GameRules.Category.PLAYER, GameRules.BooleanValue.create(false)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_DISABLE_ELYTRA_MOVEMENT_CHECK = register(
"disableElytraMovementCheck", GameRules.Category.PLAYER, GameRules.BooleanValue.create(false)
);
public static final GameRules.Key<GameRules.IntegerValue> RULE_MAX_ENTITY_CRAMMING = register(
"maxEntityCramming", GameRules.Category.MOBS, GameRules.IntegerValue.create(24)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_WEATHER_CYCLE = register(
"doWeatherCycle", GameRules.Category.UPDATES, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_LIMITED_CRAFTING = register(
"doLimitedCrafting", GameRules.Category.PLAYER, GameRules.BooleanValue.create(false, (minecraftServer, booleanValue) -> {
for (ServerPlayer serverPlayer : minecraftServer.getPlayerList().getPlayers()) {
serverPlayer.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LIMITED_CRAFTING, booleanValue.get() ? 1.0F : 0.0F));
}
})
);
public static final GameRules.Key<GameRules.IntegerValue> RULE_MAX_COMMAND_CHAIN_LENGTH = register(
"maxCommandChainLength", GameRules.Category.MISC, GameRules.IntegerValue.create(65536)
);
public static final GameRules.Key<GameRules.IntegerValue> RULE_MAX_COMMAND_FORK_COUNT = register(
"maxCommandForkCount", GameRules.Category.MISC, GameRules.IntegerValue.create(65536)
);
public static final GameRules.Key<GameRules.IntegerValue> RULE_COMMAND_MODIFICATION_BLOCK_LIMIT = register(
"commandModificationBlockLimit", GameRules.Category.MISC, GameRules.IntegerValue.create(32768)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_ANNOUNCE_ADVANCEMENTS = register(
"announceAdvancements", GameRules.Category.CHAT, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_DISABLE_RAIDS = register(
"disableRaids", GameRules.Category.MOBS, GameRules.BooleanValue.create(false)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_DOINSOMNIA = register(
"doInsomnia", GameRules.Category.SPAWNING, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_DO_IMMEDIATE_RESPAWN = register(
"doImmediateRespawn", GameRules.Category.PLAYER, GameRules.BooleanValue.create(false, (minecraftServer, booleanValue) -> {
for (ServerPlayer serverPlayer : minecraftServer.getPlayerList().getPlayers()) {
serverPlayer.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.IMMEDIATE_RESPAWN, booleanValue.get() ? 1.0F : 0.0F));
}
})
);
public static final GameRules.Key<GameRules.IntegerValue> RULE_PLAYERS_NETHER_PORTAL_DEFAULT_DELAY = register(
"playersNetherPortalDefaultDelay", GameRules.Category.PLAYER, GameRules.IntegerValue.create(80)
);
public static final GameRules.Key<GameRules.IntegerValue> RULE_PLAYERS_NETHER_PORTAL_CREATIVE_DELAY = register(
"playersNetherPortalCreativeDelay", GameRules.Category.PLAYER, GameRules.IntegerValue.create(0)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_DROWNING_DAMAGE = register(
"drowningDamage", GameRules.Category.PLAYER, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_FALL_DAMAGE = register(
"fallDamage", GameRules.Category.PLAYER, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_FIRE_DAMAGE = register(
"fireDamage", GameRules.Category.PLAYER, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_FREEZE_DAMAGE = register(
"freezeDamage", GameRules.Category.PLAYER, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_DO_PATROL_SPAWNING = register(
"doPatrolSpawning", GameRules.Category.SPAWNING, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_DO_TRADER_SPAWNING = register(
"doTraderSpawning", GameRules.Category.SPAWNING, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_DO_WARDEN_SPAWNING = register(
"doWardenSpawning", GameRules.Category.SPAWNING, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_FORGIVE_DEAD_PLAYERS = register(
"forgiveDeadPlayers", GameRules.Category.MOBS, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_UNIVERSAL_ANGER = register(
"universalAnger", GameRules.Category.MOBS, GameRules.BooleanValue.create(false)
);
public static final GameRules.Key<GameRules.IntegerValue> RULE_PLAYERS_SLEEPING_PERCENTAGE = register(
"playersSleepingPercentage", GameRules.Category.PLAYER, GameRules.IntegerValue.create(100)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_BLOCK_EXPLOSION_DROP_DECAY = register(
"blockExplosionDropDecay", GameRules.Category.DROPS, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_MOB_EXPLOSION_DROP_DECAY = register(
"mobExplosionDropDecay", GameRules.Category.DROPS, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_TNT_EXPLOSION_DROP_DECAY = register(
"tntExplosionDropDecay", GameRules.Category.DROPS, GameRules.BooleanValue.create(false)
);
public static final GameRules.Key<GameRules.IntegerValue> RULE_SNOW_ACCUMULATION_HEIGHT = register(
"snowAccumulationHeight", GameRules.Category.UPDATES, GameRules.IntegerValue.create(1)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_WATER_SOURCE_CONVERSION = register(
"waterSourceConversion", GameRules.Category.UPDATES, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_LAVA_SOURCE_CONVERSION = register(
"lavaSourceConversion", GameRules.Category.UPDATES, GameRules.BooleanValue.create(false)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_GLOBAL_SOUND_EVENTS = register(
"globalSoundEvents", GameRules.Category.MISC, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_DO_VINES_SPREAD = register(
"doVinesSpread", GameRules.Category.UPDATES, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_ENDER_PEARLS_VANISH_ON_DEATH = register(
"enderPearlsVanishOnDeath", GameRules.Category.PLAYER, GameRules.BooleanValue.create(true)
);
public static final GameRules.Key<GameRules.IntegerValue> RULE_MINECART_MAX_SPEED = register(
"minecartMaxSpeed",
GameRules.Category.MISC,
GameRules.IntegerValue.create(8, 1, 1000, FeatureFlagSet.of(FeatureFlags.MINECART_IMPROVEMENTS), (minecraftServer, integerValue) -> {})
);
public static final GameRules.Key<GameRules.IntegerValue> RULE_SPAWN_CHUNK_RADIUS = register(
"spawnChunkRadius", GameRules.Category.MISC, GameRules.IntegerValue.create(2, 0, 32, FeatureFlagSet.of(), (minecraftServer, integerValue) -> {
ServerLevel serverLevel = minecraftServer.overworld();
serverLevel.setDefaultSpawnPos(serverLevel.getSharedSpawnPos(), serverLevel.getSharedSpawnAngle());
})
);
public static final GameRules.Key<GameRules.BooleanValue> RULE_TNT_EXPLODES = register(
"tntExplodes", GameRules.Category.MISC, GameRules.BooleanValue.create(true)
);
private final Map<GameRules.Key<?>, GameRules.Value<?>> rules;
private final FeatureFlagSet enabledFeatures;
public static <T extends GameRules.Value<T>> GameRules.Type<T> getType(GameRules.Key<T> key) {
return (GameRules.Type<T>)GAME_RULE_TYPES.get(key);
}
public static <T extends GameRules.Value<T>> Codec<GameRules.Key<T>> keyCodec(Class<T> clazz) {
return Codec.STRING
.comapFlatMap(
string -> (DataResult)GAME_RULE_TYPES.entrySet()
.stream()
.filter(entry -> ((GameRules.Type)entry.getValue()).valueClass == clazz)
.map(Entry::getKey)
.filter(key -> key.getId().equals(string))
.map(key -> key)
.findFirst()
.map(DataResult::success)
.orElseGet(() -> DataResult.error(() -> "Invalid game rule ID for type: " + string)),
GameRules.Key::getId
);
}
private static <T extends GameRules.Value<T>> GameRules.Key<T> register(String name, GameRules.Category category, GameRules.Type<T> type) {
GameRules.Key<T> key = new GameRules.Key<>(name, category);
GameRules.Type<?> type2 = (GameRules.Type<?>)GAME_RULE_TYPES.put(key, type);
if (type2 != null) {
throw new IllegalStateException("Duplicate game rule registration for " + name);
} else {
return key;
}
}
public GameRules(FeatureFlagSet enabledFeatures, DynamicLike<?> tag) {
this(enabledFeatures);
this.loadFromTag(tag);
}
public GameRules(FeatureFlagSet enabledFeatures) {
this(
(Map<GameRules.Key<?>, GameRules.Value<?>>)availableRules(enabledFeatures)
.collect(ImmutableMap.toImmutableMap(Entry::getKey, entry -> ((GameRules.Type)entry.getValue()).createRule())),
enabledFeatures
);
}
private static Stream<Entry<GameRules.Key<?>, GameRules.Type<?>>> availableRules(FeatureFlagSet enabledFeatures) {
return GAME_RULE_TYPES.entrySet().stream().filter(entry -> ((GameRules.Type)entry.getValue()).requiredFeatures.isSubsetOf(enabledFeatures));
}
private GameRules(Map<GameRules.Key<?>, GameRules.Value<?>> rules, FeatureFlagSet enabledFeatures) {
this.rules = rules;
this.enabledFeatures = enabledFeatures;
}
public <T extends GameRules.Value<T>> T getRule(GameRules.Key<T> key) {
T value = (T)this.rules.get(key);
if (value == null) {
throw new IllegalArgumentException("Tried to access invalid game rule");
} else {
return value;
}
}
/**
* Return the defined game rules as NBT.
*/
public CompoundTag createTag() {
CompoundTag compoundTag = new CompoundTag();
this.rules.forEach((key, value) -> compoundTag.putString(key.id, value.serialize()));
return compoundTag;
}
private void loadFromTag(DynamicLike<?> dynamic) {
this.rules.forEach((key, value) -> dynamic.get(key.id).asString().ifSuccess(value::deserialize));
}
public GameRules copy(FeatureFlagSet enabledFeatures) {
return new GameRules(
(Map<GameRules.Key<?>, GameRules.Value<?>>)availableRules(enabledFeatures)
.collect(
ImmutableMap.toImmutableMap(
Entry::getKey,
entry -> this.rules.containsKey(entry.getKey()) ? (GameRules.Value)this.rules.get(entry.getKey()) : ((GameRules.Type)entry.getValue()).createRule()
)
),
enabledFeatures
);
}
public void visitGameRuleTypes(GameRules.GameRuleTypeVisitor visitor) {
GAME_RULE_TYPES.forEach((key, type) -> this.callVisitorCap(visitor, key, type));
}
private <T extends GameRules.Value<T>> void callVisitorCap(GameRules.GameRuleTypeVisitor visitor, GameRules.Key<?> key, GameRules.Type<?> type) {
if (type.requiredFeatures.isSubsetOf(this.enabledFeatures)) {
visitor.visit(key, type);
type.callVisitor(visitor, key);
}
}
public void assignFrom(GameRules rules, @Nullable MinecraftServer server) {
rules.rules.keySet().forEach(key -> this.assignCap(key, rules, server));
}
private <T extends GameRules.Value<T>> void assignCap(GameRules.Key<T> key, GameRules rules, @Nullable MinecraftServer server) {
T value = rules.getRule(key);
this.<T>getRule(key).setFrom(value, server);
}
public boolean getBoolean(GameRules.Key<GameRules.BooleanValue> key) {
return this.getRule(key).get();
}
public int getInt(GameRules.Key<GameRules.IntegerValue> key) {
return this.getRule(key).get();
}
public static class BooleanValue extends GameRules.Value<GameRules.BooleanValue> {
private boolean value;
static GameRules.Type<GameRules.BooleanValue> create(boolean defaultValue, BiConsumer<MinecraftServer, GameRules.BooleanValue> changeListener) {
return new GameRules.Type<>(
BoolArgumentType::bool,
type -> new GameRules.BooleanValue(type, defaultValue),
changeListener,
GameRules.GameRuleTypeVisitor::visitBoolean,
GameRules.BooleanValue.class,
FeatureFlagSet.of()
);
}
static GameRules.Type<GameRules.BooleanValue> create(boolean defaultValue) {
return create(defaultValue, (minecraftServer, booleanValue) -> {});
}
public BooleanValue(GameRules.Type<GameRules.BooleanValue> type, boolean value) {
super(type);
this.value = value;
}
@Override
protected void updateFromArgument(CommandContext<CommandSourceStack> context, String paramName) {
this.value = BoolArgumentType.getBool(context, paramName);
}
public boolean get() {
return this.value;
}
public void set(boolean value, @Nullable MinecraftServer server) {
this.value = value;
this.onChanged(server);
}
@Override
public String serialize() {
return Boolean.toString(this.value);
}
@Override
protected void deserialize(String value) {
this.value = Boolean.parseBoolean(value);
}
@Override
public int getCommandResult() {
return this.value ? 1 : 0;
}
protected GameRules.BooleanValue getSelf() {
return this;
}
protected GameRules.BooleanValue copy() {
return new GameRules.BooleanValue(this.type, this.value);
}
public void setFrom(GameRules.BooleanValue value, @Nullable MinecraftServer server) {
this.value = value.value;
this.onChanged(server);
}
}
public static enum Category {
PLAYER("gamerule.category.player"),
MOBS("gamerule.category.mobs"),
SPAWNING("gamerule.category.spawning"),
DROPS("gamerule.category.drops"),
UPDATES("gamerule.category.updates"),
CHAT("gamerule.category.chat"),
MISC("gamerule.category.misc");
private final String descriptionId;
private Category(final String descriptionId) {
this.descriptionId = descriptionId;
}
public String getDescriptionId() {
return this.descriptionId;
}
}
public interface GameRuleTypeVisitor {
default <T extends GameRules.Value<T>> void visit(GameRules.Key<T> key, GameRules.Type<T> type) {
}
default void visitBoolean(GameRules.Key<GameRules.BooleanValue> key, GameRules.Type<GameRules.BooleanValue> type) {
}
default void visitInteger(GameRules.Key<GameRules.IntegerValue> key, GameRules.Type<GameRules.IntegerValue> type) {
}
}
public static class IntegerValue extends GameRules.Value<GameRules.IntegerValue> {
private int value;
private static GameRules.Type<GameRules.IntegerValue> create(int defaultValue, BiConsumer<MinecraftServer, GameRules.IntegerValue> changeListener) {
return new GameRules.Type<>(
IntegerArgumentType::integer,
type -> new GameRules.IntegerValue(type, defaultValue),
changeListener,
GameRules.GameRuleTypeVisitor::visitInteger,
GameRules.IntegerValue.class,
FeatureFlagSet.of()
);
}
static GameRules.Type<GameRules.IntegerValue> create(
int defaultValue, int min, int max, FeatureFlagSet requiredFeatures, BiConsumer<MinecraftServer, GameRules.IntegerValue> changeListener
) {
return new GameRules.Type<>(
() -> IntegerArgumentType.integer(min, max),
type -> new GameRules.IntegerValue(type, defaultValue),
changeListener,
GameRules.GameRuleTypeVisitor::visitInteger,
GameRules.IntegerValue.class,
requiredFeatures
);
}
static GameRules.Type<GameRules.IntegerValue> create(int defaultValue) {
return create(defaultValue, (minecraftServer, integerValue) -> {});
}
public IntegerValue(GameRules.Type<GameRules.IntegerValue> type, int value) {
super(type);
this.value = value;
}
@Override
protected void updateFromArgument(CommandContext<CommandSourceStack> context, String paramName) {
this.value = IntegerArgumentType.getInteger(context, paramName);
}
public int get() {
return this.value;
}
public void set(int value, @Nullable MinecraftServer server) {
this.value = value;
this.onChanged(server);
}
@Override
public String serialize() {
return Integer.toString(this.value);
}
@Override
protected void deserialize(String value) {
this.value = safeParse(value);
}
public boolean tryDeserialize(String name) {
try {
StringReader stringReader = new StringReader(name);
this.value = (Integer)((ArgumentType)this.type.argument.get()).parse(stringReader);
return !stringReader.canRead();
} catch (CommandSyntaxException var3) {
return false;
}
}
private static int safeParse(String strValue) {
if (!strValue.isEmpty()) {
try {
return Integer.parseInt(strValue);
} catch (NumberFormatException var2) {
GameRules.LOGGER.warn("Failed to parse integer {}", strValue);
}
}
return 0;
}
@Override
public int getCommandResult() {
return this.value;
}
protected GameRules.IntegerValue getSelf() {
return this;
}
protected GameRules.IntegerValue copy() {
return new GameRules.IntegerValue(this.type, this.value);
}
public void setFrom(GameRules.IntegerValue value, @Nullable MinecraftServer server) {
this.value = value.value;
this.onChanged(server);
}
}
public static final class Key<T extends GameRules.Value<T>> {
final String id;
private final GameRules.Category category;
public Key(String id, GameRules.Category category) {
this.id = id;
this.category = category;
}
public String toString() {
return this.id;
}
public boolean equals(Object object) {
return this == object ? true : object instanceof GameRules.Key && ((GameRules.Key)object).id.equals(this.id);
}
public int hashCode() {
return this.id.hashCode();
}
public String getId() {
return this.id;
}
public String getDescriptionId() {
return "gamerule." + this.id;
}
public GameRules.Category getCategory() {
return this.category;
}
}
public static class Type<T extends GameRules.Value<T>> {
final Supplier<ArgumentType<?>> argument;
private final Function<GameRules.Type<T>, T> constructor;
final BiConsumer<MinecraftServer, T> callback;
private final GameRules.VisitorCaller<T> visitorCaller;
final Class<T> valueClass;
final FeatureFlagSet requiredFeatures;
Type(
Supplier<ArgumentType<?>> argument,
Function<GameRules.Type<T>, T> constructor,
BiConsumer<MinecraftServer, T> callback,
GameRules.VisitorCaller<T> visitorCaller,
Class<T> valueClass,
FeatureFlagSet requiredFeatures
) {
this.argument = argument;
this.constructor = constructor;
this.callback = callback;
this.visitorCaller = visitorCaller;
this.valueClass = valueClass;
this.requiredFeatures = requiredFeatures;
}
public RequiredArgumentBuilder<CommandSourceStack, ?> createArgument(String name) {
return Commands.argument(name, (ArgumentType<T>)this.argument.get());
}
public T createRule() {
return (T)this.constructor.apply(this);
}
public void callVisitor(GameRules.GameRuleTypeVisitor visitor, GameRules.Key<T> key) {
this.visitorCaller.call(visitor, key, this);
}
public FeatureFlagSet requiredFeatures() {
return this.requiredFeatures;
}
}
public abstract static class Value<T extends GameRules.Value<T>> {
protected final GameRules.Type<T> type;
public Value(GameRules.Type<T> type) {
this.type = type;
}
protected abstract void updateFromArgument(CommandContext<CommandSourceStack> context, String paramName);
public void setFromArgument(CommandContext<CommandSourceStack> context, String paramName) {
this.updateFromArgument(context, paramName);
this.onChanged(context.getSource().getServer());
}
protected void onChanged(@Nullable MinecraftServer server) {
if (server != null) {
this.type.callback.accept(server, this.getSelf());
}
}
protected abstract void deserialize(String value);
public abstract String serialize();
public String toString() {
return this.serialize();
}
public abstract int getCommandResult();
protected abstract T getSelf();
protected abstract T copy();
public abstract void setFrom(T value, @Nullable MinecraftServer server);
}
interface VisitorCaller<T extends GameRules.Value<T>> {
void call(GameRules.GameRuleTypeVisitor gameRuleTypeVisitor, GameRules.Key<T> key, GameRules.Type<T> type);
}
}